summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBo Xu <bo_xu@foxitsoftware.com>2014-10-28 23:03:33 -0700
committerBo Xu <bo_xu@foxitsoftware.com>2014-11-03 11:10:11 -0800
commitfdc00a7042d912aafaabddae4d9c84199921ef23 (patch)
tree32ab8ac91cc68d2cd15b9168782a71b3f3f5e7b9
parente9b38fa38de2c95d8260be31c57d9272c4d127ed (diff)
downloadpdfium-fdc00a7042d912aafaabddae4d9c84199921ef23.tar.xz
Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
-rw-r--r--core/include/fpdfdoc/fpdf_doc.h3
-rw-r--r--core/include/fxcodec/fx_codec.h184
-rw-r--r--core/include/fxcodec/fx_codec_def.h15
-rw-r--r--core/include/fxcodec/fx_codec_provider.h4
-rw-r--r--core/include/fxcrt/fx_arb.h48
-rw-r--r--core/include/fxcrt/fx_basic.h7
-rw-r--r--core/include/fxcrt/fx_ext.h18
-rw-r--r--core/include/fxcrt/fx_stream.h9
-rw-r--r--core/include/fxcrt/fx_ucd.h99
-rw-r--r--core/include/fxge/fx_font.h39
-rw-r--r--core/src/fpdfdoc/doc_formfield.cpp71
-rw-r--r--core/src/fxcodec/codec/codec_int.h89
-rw-r--r--core/src/fxcodec/codec/fx_codec.cpp341
-rw-r--r--core/src/fxcodec/codec/fx_codec_bmp.cpp124
-rw-r--r--core/src/fxcodec/codec/fx_codec_gif.cpp176
-rw-r--r--core/src/fxcodec/codec/fx_codec_jpeg.cpp78
-rw-r--r--core/src/fxcodec/codec/fx_codec_png.cpp245
-rw-r--r--core/src/fxcodec/codec/fx_codec_progress.cpp2263
-rw-r--r--core/src/fxcodec/codec/fx_codec_progress.h206
-rw-r--r--core/src/fxcodec/codec/fx_codec_tiff.cpp532
-rw-r--r--core/src/fxcodec/fx_lpng/include/fx_png.h7
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_png.c4299
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngerror.c933
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngget.c1178
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngmem.c291
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngpread.c1292
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngread.c4001
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrio.c119
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrtran.c5104
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrutil.c4473
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngset.c1598
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngtrans.c842
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwio.c165
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwrite.c2331
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwtran.c638
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwutil.c3024
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/png.h3563
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/pngconf.h617
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/pngdebug.h157
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/pnginfo.h260
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/pnglibconf.h211
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/pngpriv.h2006
-rw-r--r--core/src/fxcodec/fx_lpng/lpng_v163/pngstruct.h489
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_png.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngerror.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngget.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngmem.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngpread.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngread.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngrio.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngrtran.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngrutil.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngset.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngtrans.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngwio.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngwrite.c10
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngwtran.c7
-rw-r--r--core/src/fxcodec/fx_lpng/src/fx_pngwutil.c7
-rw-r--r--core/src/fxcodec/fx_tiff/include/fx_tiffiop.h7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_aux.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_close.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_codec.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_color.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_compress.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_dir.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_dirinfo.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_dirread.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_dirwrite.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_dumpmode.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_error.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_extension.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_fax3.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_fax3sm.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_flush.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_getimage.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_jpeg.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_luv.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_lzw.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_next.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_ojpeg.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_open.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_packbits.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_pixarlog.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_predict.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_print.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_read.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_strip.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_swab.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_thunder.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_tile.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_version.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_warning.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_write.c7
-rw-r--r--core/src/fxcodec/fx_tiff/src/fx_tif_zip.c7
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/t4.h292
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_aux.c360
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_close.c143
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_codec.c168
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_color.c289
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_compress.c307
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.c1662
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.h308
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_dirinfo.c978
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_dirread.c5616
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_dirwrite.c2912
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_dumpmode.c146
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_error.c85
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_extension.c120
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.c1625
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.h538
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3sm.c1263
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_flush.c121
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_getimage.c2991
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_jpeg.c2311
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_luv.c1687
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_lzw.c1169
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_next.c162
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_ojpeg.c2506
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_open.c728
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_packbits.c302
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_pixarlog.c1428
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.c813
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.h77
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_print.c719
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_read.c1116
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_strip.c386
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_swab.c313
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_thunder.c210
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_tile.c302
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_version.c43
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_warning.c87
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_write.c774
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tif_zip.c471
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tiff.h678
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tiffconf.h250
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tiffio.h559
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tiffiop.h367
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/tiffvers.h9
-rw-r--r--core/src/fxcodec/fx_tiff/tiff_v403/uvcode.h180
-rw-r--r--core/src/fxcodec/lbmp/fx_bmp.cpp917
-rw-r--r--core/src/fxcodec/lbmp/fx_bmp.h142
-rw-r--r--core/src/fxcodec/lgif/fx_gif.cpp1368
-rw-r--r--core/src/fxcodec/lgif/fx_gif.h307
-rw-r--r--core/src/fxcrt/extension.h38
-rw-r--r--core/src/fxcrt/fx_arabic.cpp1078
-rw-r--r--core/src/fxcrt/fx_arabic.h175
-rw-r--r--core/src/fxcrt/fx_extension.cpp49
-rw-r--r--core/src/fxcrt/fx_xml_parser.cpp4
-rw-r--r--core/src/fxge/ge/fx_ge_font.cpp231
-rw-r--r--core/src/fxge/ge/fx_ge_fontmap.cpp69
-rw-r--r--core/src/fxge/ge/text_int.h21
-rw-r--r--fpdfsdk/include/formfiller/FFL_ComboBox.h2
-rw-r--r--fpdfsdk/include/formfiller/FFL_FormFiller.h1
-rw-r--r--fpdfsdk/include/formfiller/FFL_IFormFiller.h6
-rw-r--r--fpdfsdk/include/formfiller/FFL_Notify.h1
-rw-r--r--fpdfsdk/include/formfiller/FFL_TextField.h2
-rw-r--r--fpdfsdk/include/fpdf_dataavail.h2
-rw-r--r--fpdfsdk/include/fpdf_flatten.h5
-rw-r--r--fpdfsdk/include/fpdf_progressive.h8
-rw-r--r--fpdfsdk/include/fpdf_transformpage.h7
-rw-r--r--fpdfsdk/include/fpdfdoc.h4
-rw-r--r--fpdfsdk/include/fpdfedit.h34
-rw-r--r--fpdfsdk/include/fpdfformfill.h412
-rw-r--r--fpdfsdk/include/fpdfppo.h3
-rw-r--r--fpdfsdk/include/fpdftext.h2
-rw-r--r--fpdfsdk/include/fpdfview.h127
-rw-r--r--fpdfsdk/include/fpdfxfa/fpdfxfa_app.h140
-rw-r--r--fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h148
-rw-r--r--fpdfsdk/include/fpdfxfa/fpdfxfa_page.h50
-rw-r--r--fpdfsdk/include/fpdfxfa/fpdfxfa_util.h50
-rw-r--r--fpdfsdk/include/fsdk_annothandler.h89
-rw-r--r--fpdfsdk/include/fsdk_baseannot.h69
-rw-r--r--fpdfsdk/include/fsdk_baseform.h85
-rw-r--r--fpdfsdk/include/fsdk_define.h38
-rw-r--r--fpdfsdk/include/fsdk_mgr.h412
-rw-r--r--fpdfsdk/include/javascript/IJavaScript.h2
-rw-r--r--fpdfsdk/include/javascript/JS_Context.h2
-rw-r--r--fpdfsdk/include/javascript/JS_Define.h56
-rw-r--r--fpdfsdk/include/javascript/JS_GlobalData.h1
-rw-r--r--fpdfsdk/include/javascript/JS_Object.h15
-rw-r--r--fpdfsdk/include/javascript/JS_Runtime.h16
-rw-r--r--fpdfsdk/include/javascript/JavaScript.h1
-rw-r--r--fpdfsdk/include/pdfwindow/PWL_Edit.h3
-rw-r--r--fpdfsdk/src/formfiller/FFL_ComboBox.cpp13
-rw-r--r--fpdfsdk/src/formfiller/FFL_FormFiller.cpp11
-rw-r--r--fpdfsdk/src/formfiller/FFL_IFormFiller.cpp202
-rw-r--r--fpdfsdk/src/formfiller/FFL_TextField.cpp12
-rw-r--r--fpdfsdk/src/fpdf_dataavail.cpp13
-rw-r--r--fpdfsdk/src/fpdf_ext.cpp3
-rw-r--r--fpdfsdk/src/fpdf_flatten.cpp7
-rw-r--r--fpdfsdk/src/fpdf_progressive.cpp13
-rw-r--r--fpdfsdk/src/fpdf_transformpage.cpp22
-rw-r--r--fpdfsdk/src/fpdfdoc.cpp22
-rw-r--r--fpdfsdk/src/fpdfeditimg.cpp15
-rw-r--r--fpdfsdk/src/fpdfeditpage.cpp44
-rw-r--r--fpdfsdk/src/fpdfformfill.cpp459
-rw-r--r--fpdfsdk/src/fpdfppo.cpp25
-rw-r--r--fpdfsdk/src/fpdfsave.cpp275
-rw-r--r--fpdfsdk/src/fpdftext.cpp10
-rw-r--r--fpdfsdk/src/fpdfview.cpp360
-rw-r--r--fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp640
-rw-r--r--fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp1476
-rw-r--r--fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp276
-rw-r--r--fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp96
-rw-r--r--fpdfsdk/src/fsdk_actionhandler.cpp5
-rw-r--r--fpdfsdk/src/fsdk_annothandler.cpp494
-rw-r--r--fpdfsdk/src/fsdk_baseannot.cpp130
-rw-r--r--fpdfsdk/src/fsdk_baseform.cpp843
-rw-r--r--fpdfsdk/src/fsdk_mgr.cpp337
-rw-r--r--fpdfsdk/src/javascript/Document.cpp26
-rw-r--r--fpdfsdk/src/javascript/Field.cpp2
-rw-r--r--fpdfsdk/src/javascript/JS_Context.cpp1
-rw-r--r--fpdfsdk/src/javascript/JS_GlobalData.cpp2
-rw-r--r--fpdfsdk/src/javascript/JS_Object.cpp4
-rw-r--r--fpdfsdk/src/javascript/JS_Runtime.cpp74
-rw-r--r--fpdfsdk/src/javascript/app.cpp25
-rw-r--r--fpdfsdk/src/javascript/global.cpp5
-rw-r--r--fpdfsdk/src/jsapi/fxjs_v8.cpp51
-rw-r--r--fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp36
-rw-r--r--pdfium.gyp81
-rw-r--r--samples/pdfium_test.cc1
-rw-r--r--xfa.gyp715
-rw-r--r--xfa/include/foxitxfa.h20
-rw-r--r--xfa/include/fwl/adapter/fwl_adapterclipboardmgr.h36
-rw-r--r--xfa/include/fwl/adapter/fwl_adaptercursormgr.h37
-rw-r--r--xfa/include/fwl/adapter/fwl_adaptermonitormgr.h23
-rw-r--r--xfa/include/fwl/adapter/fwl_adapternative.h29
-rw-r--r--xfa/include/fwl/adapter/fwl_adapterthreadmgr.h33
-rw-r--r--xfa/include/fwl/adapter/fwl_adaptertimermgr.h17
-rw-r--r--xfa/include/fwl/adapter/fwl_adapterwidgetmgr.h55
-rw-r--r--xfa/include/fwl/adapter/fwl_sdadapterimp.h72
-rw-r--r--xfa/include/fwl/basewidget/fwl_barcode.h63
-rw-r--r--xfa/include/fwl/basewidget/fwl_caret.h32
-rw-r--r--xfa/include/fwl/basewidget/fwl_checkbox.h95
-rw-r--r--xfa/include/fwl/basewidget/fwl_combobox.h139
-rw-r--r--xfa/include/fwl/basewidget/fwl_datetimepicker.h101
-rw-r--r--xfa/include/fwl/basewidget/fwl_edit.h165
-rw-r--r--xfa/include/fwl/basewidget/fwl_listbox.h110
-rw-r--r--xfa/include/fwl/basewidget/fwl_menu.h15
-rw-r--r--xfa/include/fwl/basewidget/fwl_monthcalendar.h130
-rw-r--r--xfa/include/fwl/basewidget/fwl_picturebox.h55
-rw-r--r--xfa/include/fwl/basewidget/fwl_pushbutton.h57
-rw-r--r--xfa/include/fwl/basewidget/fwl_scrollbar.h73
-rw-r--r--xfa/include/fwl/basewidget/fwl_spinbutton.h43
-rw-r--r--xfa/include/fwl/basewidget/fwl_tooltipctrl.h45
-rw-r--r--xfa/include/fwl/basewidget/fxmath_barcode.h41
-rw-r--r--xfa/include/fwl/core/fwl_app.h35
-rw-r--r--xfa/include/fwl/core/fwl_content.h27
-rw-r--r--xfa/include/fwl/core/fwl_error.h49
-rw-r--r--xfa/include/fwl/core/fwl_form.h83
-rw-r--r--xfa/include/fwl/core/fwl_grid.h76
-rw-r--r--xfa/include/fwl/core/fwl_note.h389
-rw-r--r--xfa/include/fwl/core/fwl_panel.h40
-rw-r--r--xfa/include/fwl/core/fwl_target.h25
-rw-r--r--xfa/include/fwl/core/fwl_theme.h91
-rw-r--r--xfa/include/fwl/core/fwl_thread.h56
-rw-r--r--xfa/include/fwl/core/fwl_timer.h20
-rw-r--r--xfa/include/fwl/core/fwl_widget.h122
-rw-r--r--xfa/include/fwl/core/fwl_widgetdef.h247
-rw-r--r--xfa/include/fwl/core/fwl_widgetmgr.h47
-rw-r--r--xfa/include/fwl/fwl.h76
-rw-r--r--xfa/include/fwl/lightwidget/app.h25
-rw-r--r--xfa/include/fwl/lightwidget/barcode.h177
-rw-r--r--xfa/include/fwl/lightwidget/caret.h25
-rw-r--r--xfa/include/fwl/lightwidget/checkbox.h39
-rw-r--r--xfa/include/fwl/lightwidget/combobox.h115
-rw-r--r--xfa/include/fwl/lightwidget/datetimepicker.h58
-rw-r--r--xfa/include/fwl/lightwidget/edit.h57
-rw-r--r--xfa/include/fwl/lightwidget/listbox.h98
-rw-r--r--xfa/include/fwl/lightwidget/picturebox.h65
-rw-r--r--xfa/include/fwl/lightwidget/pushbutton.h37
-rw-r--r--xfa/include/fwl/lightwidget/scrollbar.h32
-rw-r--r--xfa/include/fwl/lightwidget/theme.h39
-rw-r--r--xfa/include/fwl/lightwidget/tooltipctrl.h54
-rw-r--r--xfa/include/fwl/lightwidget/widget.h101
-rw-r--r--xfa/include/fwl/theme/barcodetp.h19
-rw-r--r--xfa/include/fwl/theme/carettp.h21
-rw-r--r--xfa/include/fwl/theme/checkboxtp.h48
-rw-r--r--xfa/include/fwl/theme/comboboxtp.h23
-rw-r--r--xfa/include/fwl/theme/datetimepickertp.h26
-rw-r--r--xfa/include/fwl/theme/edittp.h21
-rw-r--r--xfa/include/fwl/theme/formtp.h74
-rw-r--r--xfa/include/fwl/theme/listboxtp.h24
-rw-r--r--xfa/include/fwl/theme/monthcalendartp.h48
-rw-r--r--xfa/include/fwl/theme/pictureboxtp.h19
-rw-r--r--xfa/include/fwl/theme/pushbuttontp.h41
-rw-r--r--xfa/include/fwl/theme/scrollbartp.h36
-rw-r--r--xfa/include/fwl/theme/utils.h87
-rw-r--r--xfa/include/fwl/theme/widgettp.h126
-rw-r--r--xfa/include/fxbarcode/BC_BarCode.h249
-rw-r--r--xfa/include/fxfa/fxfa.h622
-rw-r--r--xfa/include/fxfa/fxfa_basic.h1073
-rw-r--r--xfa/include/fxfa/fxfa_objectacc.h931
-rw-r--r--xfa/include/fxfa/fxfa_widget.h101
-rw-r--r--xfa/include/fxgraphics/fx_graphics.h511
-rw-r--r--xfa/include/fxjse/fxjse.h125
-rw-r--r--xfa/src/fdp/include/fde.h20
-rw-r--r--xfa/src/fdp/include/fde_brs.h143
-rw-r--r--xfa/src/fdp/include/fde_css.h1082
-rw-r--r--xfa/src/fdp/include/fde_img.h76
-rw-r--r--xfa/src/fdp/include/fde_mem.h23
-rw-r--r--xfa/src/fdp/include/fde_pen.h61
-rw-r--r--xfa/src/fdp/include/fde_psr.h94
-rw-r--r--xfa/src/fdp/include/fde_pth.h29
-rw-r--r--xfa/src/fdp/include/fde_rdr.h32
-rw-r--r--xfa/src/fdp/include/fde_rdv.h53
-rw-r--r--xfa/src/fdp/include/fde_tto.h69
-rw-r--r--xfa/src/fdp/include/fde_xml.h188
-rw-r--r--xfa/src/fdp/src/css/fde_csscache.cpp163
-rw-r--r--xfa/src/fdp/src/css/fde_csscache.h97
-rw-r--r--xfa/src/fdp/src/css/fde_cssdatatable.cpp729
-rw-r--r--xfa/src/fdp/src/css/fde_cssdatatable.h195
-rw-r--r--xfa/src/fdp/src/css/fde_cssdeclaration.cpp1193
-rw-r--r--xfa/src/fdp/src/css/fde_cssdeclaration.h70
-rw-r--r--xfa/src/fdp/src/css/fde_cssstyleselector.cpp1715
-rw-r--r--xfa/src/fdp/src/css/fde_cssstyleselector.h1000
-rw-r--r--xfa/src/fdp/src/css/fde_cssstylesheet.cpp481
-rw-r--r--xfa/src/fdp/src/css/fde_cssstylesheet.h163
-rw-r--r--xfa/src/fdp/src/css/fde_csssyntax.cpp495
-rw-r--r--xfa/src/fdp/src/css/fde_csssyntax.h135
-rw-r--r--xfa/src/fdp/src/fde/fde_devbasic.cpp70
-rw-r--r--xfa/src/fdp/src/fde/fde_devbasic.h16
-rw-r--r--xfa/src/fdp/src/fde/fde_gdidevice.cpp555
-rw-r--r--xfa/src/fdp/src/fde/fde_gdidevice.h76
-rw-r--r--xfa/src/fdp/src/fde/fde_gedevice.cpp532
-rw-r--r--xfa/src/fdp/src/fde/fde_gedevice.h63
-rw-r--r--xfa/src/fdp/src/fde/fde_geobject.cpp270
-rw-r--r--xfa/src/fdp/src/fde/fde_geobject.h53
-rw-r--r--xfa/src/fdp/src/fde/fde_iterator.cpp101
-rw-r--r--xfa/src/fdp/src/fde/fde_iterator.h33
-rw-r--r--xfa/src/fdp/src/fde/fde_object.cpp27
-rw-r--r--xfa/src/fdp/src/fde/fde_object.h427
-rw-r--r--xfa/src/fdp/src/fde/fde_render.cpp253
-rw-r--r--xfa/src/fdp/src/fde/fde_render.h42
-rw-r--r--xfa/src/fdp/src/tto/fde_textout.cpp952
-rw-r--r--xfa/src/fdp/src/tto/fde_textout.h132
-rw-r--r--xfa/src/fdp/src/xml/fde_xml.cpp2712
-rw-r--r--xfa/src/fdp/src/xml/fde_xml.h443
-rw-r--r--xfa/src/fee/include/fx_wordbreak.h24
-rw-r--r--xfa/src/fee/include/ifde_txtedtbuf.h31
-rw-r--r--xfa/src/fee/include/ifde_txtedtengine.h233
-rw-r--r--xfa/src/fee/include/ifde_txtedtpage.h32
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtblock.cpp674
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtblock.h227
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtbuf.cpp446
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtbuf.h90
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtengine.cpp2871
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtengine.h341
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtkmpmatch.cpp8
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtkmpmatch.h9
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtpage.cpp647
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtpage.h130
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtparag.cpp149
-rw-r--r--xfa/src/fee/src/fee/fde_txtedtparag.h39
-rw-r--r--xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.cpp263
-rw-r--r--xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.h64
-rw-r--r--xfa/src/fee/src/fx_wordbreak/fx_wordbreakdata.cpp2062
-rw-r--r--xfa/src/fgas/include/fgas.h24
-rw-r--r--xfa/src/fgas/include/fx_alg.h46
-rw-r--r--xfa/src/fgas/include/fx_cpg.h233
-rw-r--r--xfa/src/fgas/include/fx_datetime.h470
-rw-r--r--xfa/src/fgas/include/fx_fnt.h170
-rw-r--r--xfa/src/fgas/include/fx_lbk.h27
-rw-r--r--xfa/src/fgas/include/fx_lgg.h267
-rw-r--r--xfa/src/fgas/include/fx_locale.h160
-rw-r--r--xfa/src/fgas/include/fx_mem.h58
-rw-r--r--xfa/src/fgas/include/fx_rbk.h235
-rw-r--r--xfa/src/fgas/include/fx_sax.h48
-rw-r--r--xfa/src/fgas/include/fx_stm.h60
-rw-r--r--xfa/src/fgas/include/fx_sys.h63
-rw-r--r--xfa/src/fgas/include/fx_tbk.h211
-rw-r--r--xfa/src/fgas/include/fx_ucd.h23
-rw-r--r--xfa/src/fgas/include/fx_utl.h797
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1250.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1251.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1252.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1253.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1254.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1255.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1256.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1257.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu1258.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu874.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu932.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu936.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu949.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpcu950.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1250.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1251.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1252.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1253.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1254.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1255.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1256.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1257.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi1258.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi874.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi932.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi936.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi949.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cphi950.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1250.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1251.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1252.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1253.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1254.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1255.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1256.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1257.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc1258.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc874.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc932.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc936.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc949.cpp6
-rw-r--r--xfa/src/fgas/src/crt/codepage/cpuc950.cpp6
-rw-r--r--xfa/src/fgas/src/crt/fx_algorithm.cpp315
-rw-r--r--xfa/src/fgas/src/crt/fx_codepage.cpp373
-rw-r--r--xfa/src/fgas/src/crt/fx_codepage.h9
-rw-r--r--xfa/src/fgas/src/crt/fx_cpmgr.cpp65
-rw-r--r--xfa/src/fgas/src/crt/fx_encode.cpp189
-rw-r--r--xfa/src/fgas/src/crt/fx_memory.cpp334
-rw-r--r--xfa/src/fgas/src/crt/fx_memory.h199
-rw-r--r--xfa/src/fgas/src/crt/fx_stream.cpp1613
-rw-r--r--xfa/src/fgas/src/crt/fx_stream.h405
-rw-r--r--xfa/src/fgas/src/crt/fx_system.cpp236
-rw-r--r--xfa/src/fgas/src/crt/fx_utils.cpp456
-rw-r--r--xfa/src/fgas/src/crt/fx_utils.h32
-rw-r--r--xfa/src/fgas/src/fgas_base.h12
-rw-r--r--xfa/src/fgas/src/font/fx_fontutils.cpp236
-rw-r--r--xfa/src/fgas/src/font/fx_fontutils.h19
-rw-r--r--xfa/src/fgas/src/font/fx_gdifont.cpp532
-rw-r--r--xfa/src/fgas/src/font/fx_gdifont.h89
-rw-r--r--xfa/src/fgas/src/font/fx_gefont.cpp595
-rw-r--r--xfa/src/fgas/src/font/fx_gefont.h81
-rw-r--r--xfa/src/fgas/src/font/fx_stdfontmgr.cpp1490
-rw-r--r--xfa/src/fgas/src/font/fx_stdfontmgr.h175
-rw-r--r--xfa/src/fgas/src/layout/fx_linebreak.cpp121
-rw-r--r--xfa/src/fgas/src/layout/fx_rtfbreak.cpp1522
-rw-r--r--xfa/src/fgas/src/layout/fx_rtfbreak.h180
-rw-r--r--xfa/src/fgas/src/layout/fx_textbreak.cpp1653
-rw-r--r--xfa/src/fgas/src/layout/fx_textbreak.h171
-rw-r--r--xfa/src/fgas/src/layout/fx_unicode.cpp146
-rw-r--r--xfa/src/fgas/src/layout/fx_unicode.h15
-rw-r--r--xfa/src/fgas/src/localization/fx_datetime.cpp548
-rw-r--r--xfa/src/fgas/src/localization/fx_locale.cpp4954
-rw-r--r--xfa/src/fgas/src/localization/fx_localeimp.h74
-rw-r--r--xfa/src/fgas/src/localization/fx_localemgr.cpp100
-rw-r--r--xfa/src/fgas/src/localization/fx_localemgr.h27
-rw-r--r--xfa/src/fgas/src/xml/fx_sax_imp.cpp720
-rw-r--r--xfa/src/fgas/src/xml/fx_sax_imp.h140
-rw-r--r--xfa/src/foxitlib.h15
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_barcodeimp.cpp247
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_caretimp.cpp192
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_checkboximp.cpp606
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_comboboximp.cpp1991
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_datetimepickerimp.cpp1202
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_editimp.cpp2244
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_formproxyimp.cpp71
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_listboximp.cpp1255
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_monthcalendarimp.cpp1113
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_pictureboximp.cpp172
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_pushbuttonimp.cpp542
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_scrollbarimp.cpp852
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_spinbuttonimp.cpp450
-rw-r--r--xfa/src/fwl/src/basewidget/fwl_tooltipctrlimp.cpp338
-rw-r--r--xfa/src/fwl/src/basewidget/fxmath_barcodeimp.cpp400
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_barcodeimp.h51
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_caretimp.h63
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_checkboximp.h60
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h227
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_datetimepickerimp.h206
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_editimp.h169
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h39
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_listboximp.h98
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_monthcalendarimp.h203
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_pictureboximp.h47
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_pushbuttonimp.h57
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h113
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_spinbuttonimp.h62
-rw-r--r--xfa/src/fwl/src/basewidget/include/fwl_tooltipctrlimp.h78
-rw-r--r--xfa/src/fwl/src/basewidget/include/fxmath_barcodeimp.h45
-rw-r--r--xfa/src/fwl/src/core/fwl_appimp.cpp110
-rw-r--r--xfa/src/fwl/src/core/fwl_contentimp.cpp131
-rw-r--r--xfa/src/fwl/src/core/fwl_formimp.cpp1434
-rw-r--r--xfa/src/fwl/src/core/fwl_gridimp.cpp1359
-rw-r--r--xfa/src/fwl/src/core/fwl_noteimp.cpp1116
-rw-r--r--xfa/src/fwl/src/core/fwl_panelimp.cpp208
-rw-r--r--xfa/src/fwl/src/core/fwl_sdadapterimp.cpp187
-rw-r--r--xfa/src/fwl/src/core/fwl_targetimp.cpp101
-rw-r--r--xfa/src/fwl/src/core/fwl_threadimp.cpp158
-rw-r--r--xfa/src/fwl/src/core/fwl_timerimp.cpp28
-rw-r--r--xfa/src/fwl/src/core/fwl_widgetimp.cpp1217
-rw-r--r--xfa/src/fwl/src/core/fwl_widgetmgrimp.cpp1054
-rw-r--r--xfa/src/fwl/src/core/include/fwl_appimp.h34
-rw-r--r--xfa/src/fwl/src/core/include/fwl_contentimp.h31
-rw-r--r--xfa/src/fwl/src/core/include/fwl_formimp.h187
-rw-r--r--xfa/src/fwl/src/core/include/fwl_gridimp.h161
-rw-r--r--xfa/src/fwl/src/core/include/fwl_noteimp.h152
-rw-r--r--xfa/src/fwl/src/core/include/fwl_panelimp.h29
-rw-r--r--xfa/src/fwl/src/core/include/fwl_targetimp.h33
-rw-r--r--xfa/src/fwl/src/core/include/fwl_threadimp.h53
-rw-r--r--xfa/src/fwl/src/core/include/fwl_widgetimp.h128
-rw-r--r--xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h142
-rw-r--r--xfa/src/fwl/src/lightwidget/app.cpp42
-rw-r--r--xfa/src/fwl/src/lightwidget/barcode.cpp57
-rw-r--r--xfa/src/fwl/src/lightwidget/caret.cpp58
-rw-r--r--xfa/src/fwl/src/lightwidget/checkbox.cpp75
-rw-r--r--xfa/src/fwl/src/lightwidget/combobox.cpp361
-rw-r--r--xfa/src/fwl/src/lightwidget/datetimepicker.cpp156
-rw-r--r--xfa/src/fwl/src/lightwidget/edit.cpp226
-rw-r--r--xfa/src/fwl/src/lightwidget/listbox.cpp327
-rw-r--r--xfa/src/fwl/src/lightwidget/picturebox.cpp144
-rw-r--r--xfa/src/fwl/src/lightwidget/pushbutton.cpp71
-rw-r--r--xfa/src/fwl/src/lightwidget/scrollbar.cpp102
-rw-r--r--xfa/src/fwl/src/lightwidget/theme.cpp155
-rw-r--r--xfa/src/fwl/src/lightwidget/tooltipctrl.cpp141
-rw-r--r--xfa/src/fwl/src/lightwidget/widget.cpp344
-rw-r--r--xfa/src/fwl/src/theme/barcodetp.cpp39
-rw-r--r--xfa/src/fwl/src/theme/carettp.cpp43
-rw-r--r--xfa/src/fwl/src/theme/checkboxtp.cpp500
-rw-r--r--xfa/src/fwl/src/theme/comboboxtp.cpp147
-rw-r--r--xfa/src/fwl/src/theme/datetimepickertp.cpp120
-rw-r--r--xfa/src/fwl/src/theme/edittp.cpp84
-rw-r--r--xfa/src/fwl/src/theme/formtp.cpp796
-rw-r--r--xfa/src/fwl/src/theme/listboxtp.cpp92
-rw-r--r--xfa/src/fwl/src/theme/monthcalendartp.cpp554
-rw-r--r--xfa/src/fwl/src/theme/pictureboxtp.cpp35
-rw-r--r--xfa/src/fwl/src/theme/pushbuttontp.cpp165
-rw-r--r--xfa/src/fwl/src/theme/scrollbartp.cpp362
-rw-r--r--xfa/src/fwl/src/theme/widgettp.cpp827
-rw-r--r--xfa/src/fxbarcode/src/BC_ASCIIEncoder.cpp83
-rw-r--r--xfa/src/fxbarcode/src/BC_BarCode.cpp856
-rw-r--r--xfa/src/fxbarcode/src/BC_Base256Encoder.cpp79
-rw-r--r--xfa/src/fxbarcode/src/BC_Binarizer.cpp22
-rw-r--r--xfa/src/fxbarcode/src/BC_BinaryBitmap.cpp60
-rw-r--r--xfa/src/fxbarcode/src/BC_BufferedImageLuminanceSource.cpp188
-rw-r--r--xfa/src/fxbarcode/src/BC_C40Encoder.cpp182
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonBitArray.cpp108
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonBitMatrix.cpp145
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonBitSource.cpp60
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonByteArray.cpp98
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonByteMatrix.cpp60
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonCharacterSetECI.cpp34
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonDecoderResult.cpp63
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonECI.cpp30
-rw-r--r--xfa/src/fxbarcode/src/BC_CommonPerspectiveTransform.cpp109
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixBitMatrixParser.cpp350
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixDataBlock.cpp83
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixDecodedBitStreamParser.cpp456
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixDecoder.cpp94
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixDetector.cpp352
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixReader.cpp51
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixSymbolInfo144.cpp27
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixVersion.cpp131
-rw-r--r--xfa/src/fxbarcode/src/BC_DataMatrixWriter.cpp122
-rw-r--r--xfa/src/fxbarcode/src/BC_DefaultPlacement.cpp158
-rw-r--r--xfa/src/fxbarcode/src/BC_Dimension.cpp39
-rw-r--r--xfa/src/fxbarcode/src/BC_EdifactEncoder.cpp137
-rw-r--r--xfa/src/fxbarcode/src/BC_Encoder.cpp14
-rw-r--r--xfa/src/fxbarcode/src/BC_EncoderContext.cpp111
-rw-r--r--xfa/src/fxbarcode/src/BC_ErrorCorrection.cpp178
-rw-r--r--xfa/src/fxbarcode/src/BC_FinderPatternInfo.cpp31
-rw-r--r--xfa/src/fxbarcode/src/BC_GlobalHistogramBinarizer.cpp153
-rw-r--r--xfa/src/fxbarcode/src/BC_HighLevelEncoder.cpp352
-rw-r--r--xfa/src/fxbarcode/src/BC_Library.cpp122
-rw-r--r--xfa/src/fxbarcode/src/BC_LuminanceSource.cpp22
-rw-r--r--xfa/src/fxbarcode/src/BC_OneDReader.cpp163
-rw-r--r--xfa/src/fxbarcode/src/BC_OneDimReader.cpp219
-rw-r--r--xfa/src/fxbarcode/src/BC_OneDimWriter.cpp399
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedCodaBarReader.cpp190
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedCodaBarWriter.cpp206
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedCode128Reader.cpp414
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedCode128Writer.cpp214
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedCode39Reader.cpp277
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedCode39Writer.cpp335
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedEAN13Reader.cpp78
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedEAN13Writer.cpp278
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedEAN8Reader.cpp65
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedEAN8Writer.cpp245
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedUPCAReader.cpp76
-rw-r--r--xfa/src/fxbarcode/src/BC_OnedUPCAWriter.cpp269
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417.cpp676
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417BarcodeMatrix.cpp82
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417BarcodeMetadata.cpp39
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417BarcodeRow.cpp44
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417BarcodeValue.cpp52
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417BoundingBox.cpp178
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417Codeword.cpp64
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417CodewordDecoder.cpp102
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417Common.cpp434
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417Compaction.cpp14
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417DecodedBitStreamParser.cpp474
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417DetectionResult.cpp267
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417DetectionResultColumn.cpp91
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417DetectionResultRowIndicatorColumn.cpp225
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417Detector.cpp295
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417DetectorResult.cpp37
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417Dimensions.cpp34
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417ECErrorCorrection.cpp353
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417ECModulusGF.cpp110
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417ECModulusPoly.cpp300
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417ErrorCorrection.cpp177
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417HighLevelEncoder.cpp420
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417Reader.cpp103
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417ResultMetadata.cpp46
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417ScanningDecoder.cpp580
-rw-r--r--xfa/src/fxbarcode/src/BC_PDF417Writer.cpp110
-rw-r--r--xfa/src/fxbarcode/src/BC_QRAlignmentPattern.cpp36
-rw-r--r--xfa/src/fxbarcode/src/BC_QRAlignmentPatternFinder.cpp171
-rw-r--r--xfa/src/fxbarcode/src/BC_QRBitMatrixParser.cpp169
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCodeReader.cpp95
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCodeWriter.cpp87
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoder.cpp152
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderBitVector.cpp125
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderBlockPair.cpp33
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderDecoder.cpp112
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderECB.cpp24
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderECBlocks.cpp49
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderEncoder.cpp860
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderErrorCorrectionLevel.cpp81
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderFormatInformation.cpp103
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderMaskUtil.cpp192
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderMatrixUtil.cpp474
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderMode.cpp162
-rw-r--r--xfa/src/fxbarcode/src/BC_QRCoderVersion.cpp761
-rw-r--r--xfa/src/fxbarcode/src/BC_QRDataBlock.cpp88
-rw-r--r--xfa/src/fxbarcode/src/BC_QRDataMask.cpp133
-rw-r--r--xfa/src/fxbarcode/src/BC_QRDecodedBitStreamParser.cpp238
-rw-r--r--xfa/src/fxbarcode/src/BC_QRDetector.cpp248
-rw-r--r--xfa/src/fxbarcode/src/BC_QRDetectorResult.cpp35
-rw-r--r--xfa/src/fxbarcode/src/BC_QRFinderPattern.cpp55
-rw-r--r--xfa/src/fxbarcode/src/BC_QRFinderPatternFinder.cpp435
-rw-r--r--xfa/src/fxbarcode/src/BC_QRGridSampler.cpp112
-rw-r--r--xfa/src/fxbarcode/src/BC_Reader.cpp14
-rw-r--r--xfa/src/fxbarcode/src/BC_ReedSolomon.cpp84
-rw-r--r--xfa/src/fxbarcode/src/BC_ReedSolomonDecoder.cpp208
-rw-r--r--xfa/src/fxbarcode/src/BC_ReedSolomonGF256.cpp124
-rw-r--r--xfa/src/fxbarcode/src/BC_ReedSolomonGF256Poly.cpp241
-rw-r--r--xfa/src/fxbarcode/src/BC_ResultPoint.cpp19
-rw-r--r--xfa/src/fxbarcode/src/BC_SymbolInfo.cpp226
-rw-r--r--xfa/src/fxbarcode/src/BC_SymbolShapeHint.cpp14
-rw-r--r--xfa/src/fxbarcode/src/BC_TextEncoder.cpp86
-rw-r--r--xfa/src/fxbarcode/src/BC_TwoDimWriter.cpp137
-rw-r--r--xfa/src/fxbarcode/src/BC_UtilCodingConvert.cpp49
-rw-r--r--xfa/src/fxbarcode/src/BC_UtilRSS.cpp148
-rw-r--r--xfa/src/fxbarcode/src/BC_Utils.cpp46
-rw-r--r--xfa/src/fxbarcode/src/BC_WhiteRectangleDetector.cpp228
-rw-r--r--xfa/src/fxbarcode/src/BC_Writer.cpp70
-rw-r--r--xfa/src/fxbarcode/src/BC_X12Encoder.cpp88
-rw-r--r--xfa/src/fxbarcode/src/barcode.h8
-rw-r--r--xfa/src/fxbarcode/src/include/BC_ASCIIEncoder.h22
-rw-r--r--xfa/src/fxbarcode/src/include/BC_Base256Encoder.h21
-rw-r--r--xfa/src/fxbarcode/src/include/BC_Binarizer.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_BinaryBitmap.h29
-rw-r--r--xfa/src/fxbarcode/src/include/BC_BufferedImageLuminanceSource.h33
-rw-r--r--xfa/src/fxbarcode/src/include/BC_C40Encoder.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonBitArray.h32
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonBitMatrix.h38
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonBitSource.h23
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonByteArray.h30
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonByteMatrix.h29
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonCharacterSetECI.h25
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonDecoderResult.h33
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonECI.h21
-rw-r--r--xfa/src/fxbarcode/src/include/BC_CommonPerspectiveTransform.h39
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixBitMatrixParser.h33
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixDataBlock.h26
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixDecodedBitStreamParser.h43
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixDecoder.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixDetector.h78
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixReader.h25
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixSymbolInfo144.h19
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixVersion.h101
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DataMatrixWriter.h30
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DecoderResult.h32
-rw-r--r--xfa/src/fxbarcode/src/include/BC_DefaultPlacement.h35
-rw-r--r--xfa/src/fxbarcode/src/include/BC_Dimension.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_EdifactEncoder.h23
-rw-r--r--xfa/src/fxbarcode/src/include/BC_Encoder.h19
-rw-r--r--xfa/src/fxbarcode/src/include/BC_EncoderContext.h48
-rw-r--r--xfa/src/fxbarcode/src/include/BC_ErrorCorrection.h29
-rw-r--r--xfa/src/fxbarcode/src/include/BC_FinderPatternInfo.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_GlobalHistogramBinarizer.h28
-rw-r--r--xfa/src/fxbarcode/src/include/BC_HighLevelEncoder.h60
-rw-r--r--xfa/src/fxbarcode/src/include/BC_LuminanceSource.h34
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OneDReader.h34
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OneDimReader.h39
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OneDimWriter.h70
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedCodaBarReader.h30
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedCodaBarWriter.h38
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedCode128Reader.h40
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedCode128Writer.h37
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedCode39Reader.h32
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedCode39Writer.h37
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedEAN13Reader.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedEAN13Writer.h31
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedEAN8Reader.h20
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedEAN8Writer.h32
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedUPCAReader.h30
-rw-r--r--xfa/src/fxbarcode/src/include/BC_OnedUPCAWriter.h31
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417.h45
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMatrix.h35
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMetadata.h27
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417BarcodeRow.h25
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417BarcodeValue.h22
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417BoundingBox.h43
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417Codeword.h34
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417CodewordDecoder.h27
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417Common.h31
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417Compaction.h22
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417DecodedBitStreamParser.h49
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417DetectionResult.h48
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultColumn.h31
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultRowIndicatorColumn.h28
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417Detector.h43
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417DetectorResult.h22
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417Dimensions.h25
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417ECErrorCorrection.h26
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417ECModulusGF.h37
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417ECModulusPoly.h34
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417ErrorCorrection.h21
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417HighLevelEncoder.h48
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417Reader.h26
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417ResultMetadata.h29
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417ScanningDecoder.h61
-rw-r--r--xfa/src/fxbarcode/src/include/BC_PDF417Writer.h26
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRAlignmentPattern.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRAlignmentPatternFinder.h32
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRBitMatrixParser.h31
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCodeReader.h35
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCodeWriter.h28
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoder.h55
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderBitVector.h32
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderBlockPair.h23
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderDecoder.h29
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderECB.h21
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderECBlocks.h25
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderEncoder.h60
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderErrorCorrectionLevel.h32
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderFormatInformation.h29
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderMaskUtil.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderMatrixUtil.h50
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderMode.h40
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRCoderVersion.h42
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRDataBlock.h27
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRDataMask.h25
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRDecodedBitStreamParser.h35
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRDetector.h41
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRDetectorResult.h23
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRFinderPattern.h29
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRFinderPatternFinder.h45
-rw-r--r--xfa/src/fxbarcode/src/include/BC_QRGridSampler.h33
-rw-r--r--xfa/src/fxbarcode/src/include/BC_Reader.h19
-rw-r--r--xfa/src/fxbarcode/src/include/BC_ReedSolomon.h25
-rw-r--r--xfa/src/fxbarcode/src/include/BC_ReedSolomonDecoder.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256.h35
-rw-r--r--xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256Poly.h33
-rw-r--r--xfa/src/fxbarcode/src/include/BC_ResultPoint.h24
-rw-r--r--xfa/src/fxbarcode/src/include/BC_SymbolInfo.h53
-rw-r--r--xfa/src/fxbarcode/src/include/BC_SymbolShapeHint.h21
-rw-r--r--xfa/src/fxbarcode/src/include/BC_TextEncoder.h18
-rw-r--r--xfa/src/fxbarcode/src/include/BC_TwoDimWriter.h44
-rw-r--r--xfa/src/fxbarcode/src/include/BC_UtilCodingConvert.h22
-rw-r--r--xfa/src/fxbarcode/src/include/BC_UtilRSS.h23
-rw-r--r--xfa/src/fxbarcode/src/include/BC_WhiteRectangleDetector.h38
-rw-r--r--xfa/src/fxbarcode/src/include/BC_Writer.h35
-rw-r--r--xfa/src/fxbarcode/src/include/BC_X12Encoder.h21
-rw-r--r--xfa/src/fxbarcode/src/include/utils.h219
-rw-r--r--xfa/src/fxfa/src/app/xfa_checksum.cpp203
-rw-r--r--xfa/src/fxfa/src/app/xfa_checksum.h58
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffConfigAcc.cpp65
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffConfigAcc.h21
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffapp.cpp301
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffapp.h92
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffbarcode.cpp223
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffbarcode.h93
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffcheckbutton.cpp341
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffcheckbutton.h36
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffchoicelist.cpp571
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffchoicelist.h82
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdoc.cpp453
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdoc.h63
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdochandler.cpp113
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdochandler.h34
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdocview.cpp960
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdocview.h164
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdraw.cpp20
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffdraw.h16
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffexclgroup.cpp32
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffexclgroup.h18
-rw-r--r--xfa/src/fxfa/src/app/xfa_fffield.cpp874
-rw-r--r--xfa/src/fxfa/src/app/xfa_fffield.h77
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffimage.cpp70
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffimage.h19
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffimageedit.cpp188
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffimageedit.h28
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffnotify.cpp611
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffnotify.h52
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffpageview.cpp428
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffpageview.h99
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffpath.cpp162
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffpath.h32
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffpushbutton.cpp252
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffpushbutton.h39
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffsignature.cpp129
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffsignature.h37
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffsubform.cpp20
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffsubform.h17
-rw-r--r--xfa/src/fxfa/src/app/xfa_fftext.cpp188
-rw-r--r--xfa/src/fxfa/src/app/xfa_fftext.h26
-rw-r--r--xfa/src/fxfa/src/app/xfa_fftextedit.cpp830
-rw-r--r--xfa/src/fxfa/src/app/xfa_fftextedit.h116
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffwidget.cpp1876
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffwidget.h201
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffwidgetacc.cpp1713
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffwidgetacc.h40
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffwidgethandler.cpp591
-rw-r--r--xfa/src/fxfa/src/app/xfa_ffwidgethandler.h104
-rw-r--r--xfa/src/fxfa/src/app/xfa_fontmgr.cpp1379
-rw-r--r--xfa/src/fxfa/src/app/xfa_fontmgr.h62
-rw-r--r--xfa/src/fxfa/src/app/xfa_fwladapter.cpp80
-rw-r--r--xfa/src/fxfa/src/app/xfa_fwladapter.h48
-rw-r--r--xfa/src/fxfa/src/app/xfa_fwltheme.cpp412
-rw-r--r--xfa/src/fxfa/src/app/xfa_fwltheme.h94
-rw-r--r--xfa/src/fxfa/src/app/xfa_rendercontext.cpp74
-rw-r--r--xfa/src/fxfa/src/app/xfa_rendercontext.h31
-rw-r--r--xfa/src/fxfa/src/app/xfa_textlayout.cpp1927
-rw-r--r--xfa/src/fxfa/src/app/xfa_textlayout.h391
-rw-r--r--xfa/src/fxfa/src/common/fxfa_localevalue.h81
-rw-r--r--xfa/src/fxfa/src/common/xfa_common.h19
-rw-r--r--xfa/src/fxfa/src/common/xfa_debug.h9
-rw-r--r--xfa/src/fxfa/src/common/xfa_docdata.h27
-rw-r--r--xfa/src/fxfa/src/common/xfa_doclayout.h107
-rw-r--r--xfa/src/fxfa/src/common/xfa_document.h177
-rw-r--r--xfa/src/fxfa/src/common/xfa_fm2jsapi.h25
-rw-r--r--xfa/src/fxfa/src/common/xfa_localemgr.h69
-rw-r--r--xfa/src/fxfa/src/common/xfa_object.h588
-rw-r--r--xfa/src/fxfa/src/common/xfa_parser.h37
-rw-r--r--xfa/src/fxfa/src/common/xfa_script.h107
-rw-r--r--xfa/src/fxfa/src/common/xfa_utils.h237
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_error.cpp25
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_error.h29
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_expression.cpp715
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_expression.h172
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_fm2js.cpp7
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_fm2js.h30
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_fm2jsapi.cpp57
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.cpp7185
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.h174
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp1146
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_fmparse.h49
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_lexer.cpp589
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_lexer.h82
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_program.cpp50
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_program.h26
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_simpleexpression.cpp758
-rw-r--r--xfa/src/fxfa/src/fm2js/xfa_simpleexpression.h239
-rw-r--r--xfa/src/fxfa/src/parser/xfa_basic_data.cpp1429
-rw-r--r--xfa/src/fxfa/src/parser/xfa_basic_imp.cpp634
-rw-r--r--xfa/src/fxfa/src/parser/xfa_basic_imp.h73
-rw-r--r--xfa/src/fxfa/src/parser/xfa_debug_parser.cpp18
-rw-r--r--xfa/src/fxfa/src/parser/xfa_debug_parser.h9
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.cpp116
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.h11
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.cpp1267
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.h12
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_imp.cpp418
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_imp.h9
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_layout_imp.cpp201
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_layout_imp.h52
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_serialize.cpp543
-rw-r--r--xfa/src/fxfa/src/parser/xfa_document_serialize.h35
-rw-r--r--xfa/src/fxfa/src/parser/xfa_layout_appadapter.cpp180
-rw-r--r--xfa/src/fxfa/src/parser/xfa_layout_appadapter.h74
-rw-r--r--xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp2391
-rw-r--r--xfa/src/fxfa/src/parser/xfa_layout_itemlayout.h132
-rw-r--r--xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.cpp1680
-rw-r--r--xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.h102
-rw-r--r--xfa/src/fxfa/src/parser/xfa_locale.cpp373
-rw-r--r--xfa/src/fxfa/src/parser/xfa_locale.h61
-rw-r--r--xfa/src/fxfa/src/parser/xfa_localemgr.cpp934
-rw-r--r--xfa/src/fxfa/src/parser/xfa_localevalue.cpp976
-rw-r--r--xfa/src/fxfa/src/parser/xfa_object_imp.cpp5125
-rw-r--r--xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp4161
-rw-r--r--xfa/src/fxfa/src/parser/xfa_parser_imp.cpp1421
-rw-r--r--xfa/src/fxfa/src/parser/xfa_parser_imp.h137
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_datawindow.cpp51
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_datawindow.h23
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.cpp218
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.h56
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.cpp754
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.h50
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_imp.cpp750
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_imp.h113
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.cpp524
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.h48
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.cpp42
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.h21
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_nodehelper.cpp393
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_nodehelper.h41
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.cpp784
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.h72
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.cpp122
-rw-r--r--xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.h19
-rw-r--r--xfa/src/fxfa/src/parser/xfa_utils_imp.cpp382
-rw-r--r--xfa/src/fxgraphics/src/fx_graphics.cpp1670
-rw-r--r--xfa/src/fxgraphics/src/fx_metafile_interpreter.cpp281
-rw-r--r--xfa/src/fxgraphics/src/fx_metafile_interpreter.h54
-rw-r--r--xfa/src/fxgraphics/src/fx_path_generator.cpp222
-rw-r--r--xfa/src/fxgraphics/src/fx_path_generator.h42
-rw-r--r--xfa/src/fxgraphics/src/pre.h115
-rw-r--r--xfa/src/fxjse/src/class.cpp268
-rw-r--r--xfa/src/fxjse/src/class.h40
-rw-r--r--xfa/src/fxjse/src/context.cpp224
-rw-r--r--xfa/src/fxjse/src/context.h37
-rw-r--r--xfa/src/fxjse/src/dynprop.cpp284
-rw-r--r--xfa/src/fxjse/src/fxv8.h11
-rw-r--r--xfa/src/fxjse/src/runtime.cpp118
-rw-r--r--xfa/src/fxjse/src/runtime.h39
-rw-r--r--xfa/src/fxjse/src/scope_inline.h86
-rw-r--r--xfa/src/fxjse/src/util_inline.h44
-rw-r--r--xfa/src/fxjse/src/value.cpp524
-rw-r--r--xfa/src/fxjse/src/value.h236
-rw-r--r--xfa_test/FormFiller_Test/BookMarkView.cpp197
-rw-r--r--xfa_test/FormFiller_Test/BookMarkView.h67
-rw-r--r--xfa_test/FormFiller_Test/ChildFrm.cpp112
-rw-r--r--xfa_test/FormFiller_Test/ChildFrm.h64
-rw-r--r--xfa_test/FormFiller_Test/ConvertDlg.cpp65
-rw-r--r--xfa_test/FormFiller_Test/ConvertDlg.h47
-rw-r--r--xfa_test/FormFiller_Test/ExportPage.cpp189
-rw-r--r--xfa_test/FormFiller_Test/ExportPage.h59
-rw-r--r--xfa_test/FormFiller_Test/FX_SplitterWnd.cpp373
-rw-r--r--xfa_test/FormFiller_Test/FX_SplitterWnd.h44
-rw-r--r--xfa_test/FormFiller_Test/FindDlg.cpp73
-rw-r--r--xfa_test/FormFiller_Test/FindDlg.h50
-rw-r--r--xfa_test/FormFiller_Test/GotoPageDlg.cpp65
-rw-r--r--xfa_test/FormFiller_Test/GotoPageDlg.h48
-rw-r--r--xfa_test/FormFiller_Test/JS_ResponseDlg.cpp152
-rw-r--r--xfa_test/FormFiller_Test/JS_ResponseDlg.h64
-rw-r--r--xfa_test/FormFiller_Test/MainFrm.cpp238
-rw-r--r--xfa_test/FormFiller_Test/MainFrm.h56
-rw-r--r--xfa_test/FormFiller_Test/ReaderVC.cpp195
-rw-r--r--xfa_test/FormFiller_Test/ReaderVC.dsp460
-rw-r--r--xfa_test/FormFiller_Test/ReaderVC.h54
-rw-r--r--xfa_test/FormFiller_Test/ReaderVC.rc741
-rw-r--r--xfa_test/FormFiller_Test/ReaderVCDoc.cpp113
-rw-r--r--xfa_test/FormFiller_Test/ReaderVCDoc.h59
-rw-r--r--xfa_test/FormFiller_Test/ReaderVCView.cpp3750
-rw-r--r--xfa_test/FormFiller_Test/ReaderVCView.h375
-rw-r--r--xfa_test/FormFiller_Test/StdAfx.cpp8
-rw-r--r--xfa_test/FormFiller_Test/StdAfx.h99
-rw-r--r--xfa_test/FormFiller_Test/TestJsDlg.cpp58
-rw-r--r--xfa_test/FormFiller_Test/TestJsDlg.h46
-rw-r--r--xfa_test/FormFiller_Test/ZoomDlg.cpp104
-rw-r--r--xfa_test/FormFiller_Test/ZoomDlg.h48
-rw-r--r--xfa_test/FormFiller_Test/res/BigHandCursor.curbin0 -> 326 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/Rd_SelText_Icon.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/Rd_SelText_Icon_Dis.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/ReaderVC.icobin0 -> 1078 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/ReaderVC.rc213
-rw-r--r--xfa_test/FormFiller_Test/res/ReaderVCDoc.icobin0 -> 1078 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/SmallHandCursor.curbin0 -> 326 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/Toolbar.bmpbin0 -> 5590 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/bookmark.bmpbin0 -> 2358 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/bound.curbin0 -> 326 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/point.curbin0 -> 326 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_actual_size.bmpbin0 -> 406 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_bookmark1.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_clockwise.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_counterclockwise.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_first.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_fit_page.bmpbin0 -> 406 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_fit_width.bmpbin0 -> 406 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hand1.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_about2.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_actual_size.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_bookmark1.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_clockwise.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_counterclockwise.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_first.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_first.xpm109
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_fit_page.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_fit_width.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_hand1.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_last.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_next.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_open1.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_prev.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_print.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_search.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_snap_shot.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_zoomin.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_hot_zoomout.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_last.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_next.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_prev.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_print.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_search.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_snap_shot.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_zoomin.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/res/tool_zoomout.bmpbin0 -> 1654 bytes
-rw-r--r--xfa_test/FormFiller_Test/resource.h113
-rw-r--r--xfa_test/pdf/BUILD.gn99
-rw-r--r--xfa_test/pdf/DEPS9
-rw-r--r--xfa_test/pdf/Info.plist44
-rw-r--r--xfa_test/pdf/OWNERS4
-rw-r--r--xfa_test/pdf/button.cc179
-rw-r--r--xfa_test/pdf/button.h71
-rw-r--r--xfa_test/pdf/chunk_stream.cc172
-rw-r--r--xfa_test/pdf/chunk_stream.h48
-rw-r--r--xfa_test/pdf/control.cc117
-rw-r--r--xfa_test/pdf/control.h77
-rw-r--r--xfa_test/pdf/document_loader.cc513
-rw-r--r--xfa_test/pdf/document_loader.h124
-rw-r--r--xfa_test/pdf/draw_utils.cc343
-rw-r--r--xfa_test/pdf/draw_utils.h94
-rw-r--r--xfa_test/pdf/fading_control.cc75
-rw-r--r--xfa_test/pdf/fading_control.h32
-rw-r--r--xfa_test/pdf/fading_controls.cc316
-rw-r--r--xfa_test/pdf/fading_controls.h84
-rw-r--r--xfa_test/pdf/instance.cc2778
-rw-r--r--xfa_test/pdf/instance.h531
-rw-r--r--xfa_test/pdf/number_image_generator.cc81
-rw-r--r--xfa_test/pdf/number_image_generator.h37
-rw-r--r--xfa_test/pdf/out_of_process_instance.cc1369
-rw-r--r--xfa_test/pdf/out_of_process_instance.h345
-rw-r--r--xfa_test/pdf/page_indicator.cc127
-rw-r--r--xfa_test/pdf/page_indicator.h72
-rw-r--r--xfa_test/pdf/paint_aggregator.cc263
-rw-r--r--xfa_test/pdf/paint_aggregator.h130
-rw-r--r--xfa_test/pdf/paint_manager.cc302
-rw-r--r--xfa_test/pdf/paint_manager.h205
-rw-r--r--xfa_test/pdf/pdf.cc275
-rw-r--r--xfa_test/pdf/pdf.def7
-rw-r--r--xfa_test/pdf/pdf.gyp200
-rw-r--r--xfa_test/pdf/pdf.h24
-rw-r--r--xfa_test/pdf/pdf.rc104
-rw-r--r--xfa_test/pdf/pdf_engine.h321
-rw-r--r--xfa_test/pdf/pdfium/pdfium_assert_matching_enums.cc207
-rw-r--r--xfa_test/pdf/pdfium/pdfium_engine.cc3884
-rw-r--r--xfa_test/pdf/pdfium/pdfium_engine.h687
-rw-r--r--xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.cc34
-rw-r--r--xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.h30
-rw-r--r--xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.cc33
-rw-r--r--xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.h34
-rw-r--r--xfa_test/pdf/pdfium/pdfium_page.cc477
-rw-r--r--xfa_test/pdf/pdfium/pdfium_page.h136
-rw-r--r--xfa_test/pdf/pdfium/pdfium_range.cc79
-rw-r--r--xfa_test/pdf/pdfium/pdfium_range.h54
-rw-r--r--xfa_test/pdf/preview_mode_client.cc162
-rw-r--r--xfa_test/pdf/preview_mode_client.h77
-rw-r--r--xfa_test/pdf/progress_control.cc283
-rw-r--r--xfa_test/pdf/progress_control.h72
-rw-r--r--xfa_test/pdf/resource.h14
-rw-r--r--xfa_test/pdf/resource_consts.h49
-rw-r--r--xfa_test/pdf/thumbnail_control.cc301
-rw-r--r--xfa_test/pdf/thumbnail_control.h67
-rw-r--r--xfa_test/process/process.cc712
-rw-r--r--xfa_test/process/script.txt21
1059 files changed, 283674 insertions, 601 deletions
diff --git a/core/include/fpdfdoc/fpdf_doc.h b/core/include/fpdfdoc/fpdf_doc.h
index e4cf777c1f..960e943e4a 100644
--- a/core/include/fpdfdoc/fpdf_doc.h
+++ b/core/include/fpdfdoc/fpdf_doc.h
@@ -1230,8 +1230,9 @@ public:
FX_BOOL ClearSelectedOptions(FX_BOOL bNotify = FALSE);
+ FX_BOOL ClearOptions(FX_BOOL bNotify = FALSE);
-
+ int InsertOption(CFX_WideString csOptLabel, int index = -1, FX_BOOL bNotify = FALSE);
FX_FLOAT GetFontSize()
{
diff --git a/core/include/fxcodec/fx_codec.h b/core/include/fxcodec/fx_codec.h
index da8b309dd6..b0eecc3e52 100644
--- a/core/include/fxcodec/fx_codec.h
+++ b/core/include/fxcodec/fx_codec.h
@@ -13,6 +13,7 @@
#include "fx_codec_provider.h"
class CFX_DIBSource;
class ICodec_ScanlineDecoder;
+class ICodec_ProgressiveDecoder;
class ICodec_BasicModule;
class ICodec_FaxModule;
class ICodec_JpegModule;
@@ -21,6 +22,11 @@ class ICodec_Jbig2Module;
class ICodec_IccModule;
class ICodec_FlateModule;
class ICodec_Jbig2Encoder;
+class ICodec_PngModule;
+class ICodec_GifModule;
+class ICodec_BmpModule;
+class ICodec_TiffModule;
+class CFX_DIBAttribute;
class ICodec_ScanlineDecoder;
class CCodec_ModuleMgr : public CFX_Object
{
@@ -37,6 +43,9 @@ public:
void InitIccDecoder();
+
+ ICodec_ProgressiveDecoder* CreateProgressiveDecoder();
+
ICodec_Jbig2Encoder* CreateJbig2Encoder();
protected:
CCodec_ModuleMgr();
@@ -70,6 +79,22 @@ public:
{
return m_pFlateModule;
}
+ ICodec_PngModule* GetPngModule()
+ {
+ return m_pPngModule;
+ }
+ ICodec_GifModule* GetGifModule()
+ {
+ return m_pGifModule;
+ }
+ ICodec_BmpModule* GetBmpModule()
+ {
+ return m_pBmpModule;
+ }
+ ICodec_TiffModule* GetTiffModule()
+ {
+ return m_pTiffModule;
+ }
protected:
ICodec_BasicModule* m_pBasicModule;
ICodec_FaxModule* m_pFaxModule;
@@ -78,6 +103,10 @@ protected:
ICodec_Jbig2Module* m_pJbig2Module;
ICodec_IccModule* m_pIccModule;
ICodec_FlateModule* m_pFlateModule;
+ ICodec_PngModule* m_pPngModule;
+ ICodec_GifModule* m_pGifModule;
+ ICodec_BmpModule* m_pBmpModule;
+ ICodec_TiffModule* m_pTiffModule;
};
class ICodec_BasicModule : public CFX_Object
@@ -170,7 +199,7 @@ public:
virtual void Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;
- virtual int ReadHeader(void* pContext, int* width, int* height, int* nComps) = 0;
+ virtual int ReadHeader(void* pContext, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute = NULL) = 0;
virtual int StartScanline(void* pContext, int down_scale) = 0;
@@ -197,6 +226,97 @@ public:
virtual void DestroyDecoder(FX_LPVOID ctx) = 0;
};
+class ICodec_PngModule : public CFX_Object
+{
+public:
+
+ virtual ~ICodec_PngModule() {}
+
+ virtual void* Start(void* pModule) = 0;
+
+ virtual void Finish(void* pContext) = 0;
+
+ virtual FX_BOOL Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_DIBAttribute* pAttribute = NULL) = 0;
+
+ FX_BOOL (*ReadHeaderCallback)(void* pModule, int width, int height, int bpc, int pass, int* color_type, double* gamma);
+
+ FX_BOOL (*AskScanlineBufCallback)(void* pModule, int line, FX_LPBYTE& src_buf);
+
+ void (*FillScanlineBufCompletedCallback)(void* pModule, int pass, int line);
+};
+class ICodec_GifModule : public CFX_Object
+{
+public:
+
+ virtual ~ICodec_GifModule() {}
+
+ virtual void* Start(void* pModule) = 0;
+
+ virtual void Finish(void* pContext) = 0;
+
+ virtual FX_DWORD GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr = NULL) = 0;
+
+ virtual void Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;
+
+ virtual FX_INT32 ReadHeader(void* pContext, int* width, int* height,
+ int* pal_num, void** pal_pp, int* bg_index, CFX_DIBAttribute* pAttribute = NULL) = 0;
+
+ virtual FX_INT32 LoadFrameInfo(void* pContext, int* frame_num) = 0;
+
+ void (*RecordCurrentPositionCallback)(void* pModule, FX_DWORD& cur_pos);
+
+ FX_LPBYTE (*AskLocalPaletteBufCallback)(void* pModule, FX_INT32 frame_num, FX_INT32 pal_size);
+
+ virtual FX_INT32 LoadFrame(void* pContext, int frame_num, CFX_DIBAttribute* pAttribute = NULL) = 0;
+
+ FX_BOOL (*InputRecordPositionBufCallback)(void* pModule, FX_DWORD rcd_pos, const FX_RECT& img_rc,
+ FX_INT32 pal_num, void* pal_ptr,
+ FX_INT32 delay_time, FX_BOOL user_input,
+ FX_INT32 trans_index, FX_INT32 disposal_method, FX_BOOL interlace);
+
+ void (*ReadScanlineCallback)(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf);
+};
+class ICodec_BmpModule : public CFX_Object
+{
+public:
+
+ virtual ~ICodec_BmpModule() {}
+
+ virtual void* Start(void* pModule) = 0;
+
+ virtual void Finish(void* pContext) = 0;
+
+ virtual FX_DWORD GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr = NULL) = 0;
+
+ virtual void Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;
+
+ virtual FX_INT32 ReadHeader(void* pContext, FX_INT32* width, FX_INT32* height, FX_BOOL* tb_flag, FX_INT32* components,
+ int* pal_num, FX_DWORD** pal_pp, CFX_DIBAttribute* pAttribute = NULL) = 0;
+
+ virtual FX_INT32 LoadImage(void* pContext) = 0;
+
+ FX_BOOL (*InputImagePositionBufCallback)(void* pModule, FX_DWORD rcd_pos);
+
+ void (*ReadScanlineCallback)(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf);
+};
+class ICodec_TiffModule : public CFX_Object
+{
+public:
+
+ virtual ~ICodec_TiffModule() {}
+
+ virtual FX_LPVOID CreateDecoder(IFX_FileRead* file_ptr) = 0;
+
+
+ virtual void GetFrames(FX_LPVOID ctx, FX_INT32& frames) = 0;
+
+ virtual FX_BOOL LoadFrameInfo(FX_LPVOID ctx, FX_INT32 frame, FX_DWORD& width, FX_DWORD& height, FX_DWORD& comps, FX_DWORD& bpc, CFX_DIBAttribute* pAttribute = NULL) = 0;
+
+
+ virtual FX_BOOL Decode(FX_LPVOID ctx, class CFX_DIBitmap* pDIBitmap) = 0;
+
+ virtual void DestroyDecoder(FX_LPVOID ctx) = 0;
+};
class ICodec_Jbig2Module : public CFX_Object
{
public:
@@ -218,6 +338,34 @@ public:
virtual FXCODEC_STATUS ContinueDecode(void* pJbig2Content, IFX_Pause* pPause) = 0;
virtual void DestroyJbig2Context(void* pJbig2Content) = 0;
};
+class ICodec_ProgressiveDecoder : public CFX_Object
+{
+public:
+
+ virtual ~ICodec_ProgressiveDecoder() {}
+
+ virtual FXCODEC_STATUS LoadImageInfo(IFX_FileRead* pFile, FXCODEC_IMAGE_TYPE imageType = FXCODEC_IMAGE_UNKNOWN, CFX_DIBAttribute* pAttribute = NULL) = 0;
+
+ virtual FXCODEC_IMAGE_TYPE GetType() = 0;
+
+ virtual FX_INT32 GetWidth() = 0;
+
+ virtual FX_INT32 GetHeight() = 0;
+
+ virtual FX_INT32 GetNumComponents() = 0;
+
+ virtual FX_INT32 GetBPC() = 0;
+
+ virtual void SetClipBox(FX_RECT* clip) = 0;
+
+ virtual FXCODEC_STATUS GetFrames(FX_INT32& frames, IFX_Pause* pPause = NULL) = 0;
+
+ virtual FXCODEC_STATUS StartDecode(class CFX_DIBitmap* pDIBitmap,
+ FX_INT32 start_x, FX_INT32 start_y, FX_INT32 size_x, FX_INT32 size_y,
+ FX_INT32 frames = 0, FX_BOOL bInterpol = TRUE) = 0;
+
+ virtual FXCODEC_STATUS ContinueDecode(IFX_Pause* pPause = NULL) = 0;
+};
class ICodec_Jbig2Encoder : public CFX_Object
{
public:
@@ -286,4 +434,38 @@ public:
void AdobeCMYK_to_sRGB(FX_FLOAT c, FX_FLOAT m, FX_FLOAT y, FX_FLOAT k, FX_FLOAT& R, FX_FLOAT& G, FX_FLOAT& B);
void AdobeCMYK_to_sRGB1(FX_BYTE c, FX_BYTE m, FX_BYTE y, FX_BYTE k, FX_BYTE& R, FX_BYTE& G, FX_BYTE& B);
FX_BOOL MD5ComputeID(FX_LPCVOID buf, FX_DWORD dwSize, FX_BYTE ID[16]);
+class CFX_DIBAttribute : public CFX_Object
+{
+public:
+ CFX_DIBAttribute();
+ ~CFX_DIBAttribute();
+
+ FX_INT32 m_nXDPI;
+
+ FX_INT32 m_nYDPI;
+
+ FX_FLOAT m_fAspectRatio;
+
+ FX_WORD m_wDPIUnit;
+
+ CFX_ByteString m_strAuthor;
+
+ FX_BYTE m_strTime[20];
+
+ FX_INT32 m_nGifLeft;
+ FX_INT32 m_nGifTop;
+
+ FX_DWORD* m_pGifLocalPalette;
+
+ FX_DWORD m_nGifLocalPalNum;
+
+ FX_INT32 m_nBmpCompressType;
+ class IFX_DIBAttributeExif* m_pExif;
+};
+class IFX_DIBAttributeExif : public CFX_Object
+{
+public:
+ virtual ~IFX_DIBAttributeExif() {};
+ virtual FX_BOOL GetInfo(FX_WORD tag, FX_LPVOID val) = 0;
+};
#endif
diff --git a/core/include/fxcodec/fx_codec_def.h b/core/include/fxcodec/fx_codec_def.h
index 0d08da699b..7a18f5be09 100644
--- a/core/include/fxcodec/fx_codec_def.h
+++ b/core/include/fxcodec/fx_codec_def.h
@@ -6,6 +6,15 @@
#ifndef _FX_CODEC_DEF_H_
#define _FX_CODEC_DEF_H_
+enum FXCODEC_IMAGE_TYPE {
+ FXCODEC_IMAGE_UNKNOWN = 0,
+ FXCODEC_IMAGE_BMP,
+ FXCODEC_IMAGE_JPG,
+ FXCODEC_IMAGE_PNG,
+ FXCODEC_IMAGE_GIF,
+ FXCODEC_IMAGE_TIF,
+ FXCODEC_IMAGE_MAX
+};
enum FXCODEC_STATUS {
FXCODEC_STATUS_ERROR = -1,
FXCODEC_STATUS_FRAME_READY,
@@ -58,6 +67,12 @@ enum FXCODEC_STATUS {
#define Icc_PARAMTYPE_NONE 0
#define Icc_PARAMTYPE_BUFFER 1
#define Icc_PARAMTYPE_PARAM 2
+enum FXCODEC_RESUNIT {
+ FXCODEC_RESUNIT_NONE = 0,
+ FXCODEC_RESUNIT_INCH,
+ FXCODEC_RESUNIT_CENTIMETER,
+ FXCODEC_RESUNIT_METER
+};
#define EXIFTAG_USHORT_RESUNIT 296
#define EXIFTAG_FLOAT_DPIX 282
#define EXIFTAG_FLOAT_DPIY 283
diff --git a/core/include/fxcodec/fx_codec_provider.h b/core/include/fxcodec/fx_codec_provider.h
index a3ef396a27..f26194a14e 100644
--- a/core/include/fxcodec/fx_codec_provider.h
+++ b/core/include/fxcodec/fx_codec_provider.h
@@ -6,6 +6,7 @@
#ifndef _FX_CODEC_PROVIDER_H_
#define _FX_CODEC_PROVIDER_H_
+class CFX_DIBAttribute;
class IFX_JpegProvider
{
public:
@@ -39,8 +40,7 @@ public:
virtual void Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size) = 0;
- virtual int ReadHeader(void* pContext, int* width, int* height, int* nComps) = 0;
-
+ virtual int ReadHeader(void* pContext, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute = NULL) = 0;
virtual int StartScanline(void* pContext, int down_scale) = 0;
diff --git a/core/include/fxcrt/fx_arb.h b/core/include/fxcrt/fx_arb.h
index 4950f81716..ed0370ff74 100644
--- a/core/include/fxcrt/fx_arb.h
+++ b/core/include/fxcrt/fx_arb.h
@@ -6,6 +6,54 @@
#ifndef _FX_ARABIC_
#define _FX_ARABIC_
+class IFX_ArabicChar;
+class IFX_BidiChar;
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+typedef struct _FX_ARBFORMTABLE {
+ FX_WCHAR wIsolated;
+ FX_WCHAR wFinal;
+ FX_WCHAR wInitial;
+ FX_WCHAR wMedial;
+} FX_ARBFORMTABLE, * FX_LPARBFORMTABLE;
+typedef FX_ARBFORMTABLE const * FX_LPCARBFORMTABLE;
+typedef struct _FX_ARAALEF {
+ FX_WCHAR wAlef;
+ FX_WCHAR wIsolated;
+} FX_ARAALEF, * FX_LPARAALEF;
+typedef FX_ARAALEF const * FX_LPCARAALEF;
+typedef struct _FX_ARASHADDA {
+ FX_WCHAR wShadda;
+ FX_WCHAR wIsolated;
+} FX_ARASHADDA, * FX_LPARASHADDA;
+typedef FX_ARASHADDA const * FX_LPCARASHADDA;
+FX_LPCARBFORMTABLE FX_GetArabicFormTable(FX_WCHAR unicode);
+FX_WCHAR FX_GetArabicFromAlefTable(FX_WCHAR alef);
+FX_WCHAR FX_GetArabicFromShaddaTable(FX_WCHAR shadda);
+#ifdef __cplusplus
+};
+#endif
+enum FX_ARBPOSITION {
+ FX_ARBPOSITION_Isolated = 0,
+ FX_ARBPOSITION_Final,
+ FX_ARBPOSITION_Initial,
+ FX_ARBPOSITION_Medial,
+};
+class IFX_ArabicChar
+{
+public:
+ static IFX_ArabicChar* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL IsArabicChar(FX_WCHAR wch) const = 0;
+ virtual FX_BOOL IsArabicFormChar(FX_WCHAR wch) const = 0;
+ virtual FX_WCHAR GetFormChar(FX_WCHAR wch, FX_WCHAR prev = 0, FX_WCHAR next = 0) const = 0;
+ virtual FX_WCHAR GetFormChar(const CFX_Char *cur, const CFX_Char *prev, const CFX_Char *next) const = 0;
+};
+void FX_BidiLine(CFX_WideString &wsText, FX_INT32 iBaseLevel = 0);
+void FX_BidiLine(CFX_TxtCharArray &chars, FX_INT32 iCount, FX_INT32 iBaseLevel = 0);
+void FX_BidiLine(CFX_RTFCharArray &chars, FX_INT32 iCount, FX_INT32 iBaseLevel = 0);
class IFX_BidiChar
{
public:
diff --git a/core/include/fxcrt/fx_basic.h b/core/include/fxcrt/fx_basic.h
index 22ba611a77..0c84f540e9 100644
--- a/core/include/fxcrt/fx_basic.h
+++ b/core/include/fxcrt/fx_basic.h
@@ -1578,6 +1578,13 @@ typedef enum {
} FX_ProgressiveStatus;
#define ProgressiveStatus FX_ProgressiveStatus
#define FX_NAMESPACE_DECLARE(namespace, type) namespace::type
+class IFX_Unknown
+{
+public:
+ virtual FX_DWORD Release() = 0;
+ virtual FX_DWORD AddRef() = 0;
+};
+#define FX_IsOdd(a) ((a) & 1)
class CFX_Vector_3by1 : public CFX_Object
{
diff --git a/core/include/fxcrt/fx_ext.h b/core/include/fxcrt/fx_ext.h
index 03ec488135..ceba015b59 100644
--- a/core/include/fxcrt/fx_ext.h
+++ b/core/include/fxcrt/fx_ext.h
@@ -76,6 +76,24 @@ void FX_Random_GenerateCrypto(FX_LPDWORD pBuffer, FX_INT32 iCount);
#ifdef __cplusplus
}
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct FX_GUID {
+ FX_DWORD data1;
+ FX_WORD data2;
+ FX_WORD data3;
+ FX_BYTE data4[8];
+} FX_GUID, * FX_LPGUID;
+typedef FX_GUID const * FX_LPCGUID;
+
+void FX_GUID_CreateV4(FX_LPGUID pGUID);
+
+void FX_GUID_ToString(FX_LPCGUID pGUID, CFX_ByteString &bsStr, FX_BOOL bSeparator = TRUE);
+#ifdef __cplusplus
+}
+#endif
template<class baseType>
class CFX_SSortTemplate
{
diff --git a/core/include/fxcrt/fx_stream.h b/core/include/fxcrt/fx_stream.h
index 8e298f7727..0a3d1c4609 100644
--- a/core/include/fxcrt/fx_stream.h
+++ b/core/include/fxcrt/fx_stream.h
@@ -162,6 +162,15 @@ public:
};
IFX_FileStream* FX_CreateFileStream(FX_LPCSTR filename, FX_DWORD dwModes);
IFX_FileStream* FX_CreateFileStream(FX_LPCWSTR filename, FX_DWORD dwModes);
+class IFX_FileAccess
+{
+public:
+ virtual void Release() = 0;
+ virtual IFX_FileAccess* Retain() = 0;
+ virtual void GetPath(CFX_WideString& wsPath) = 0;
+ virtual IFX_FileStream* CreateFileStream(FX_DWORD dwModes) = 0;
+};
+IFX_FileAccess* FX_CreateDefaultFileAccess(FX_WSTR wsPath);
class IFX_MemoryStream : public IFX_FileStream
{
public:
diff --git a/core/include/fxcrt/fx_ucd.h b/core/include/fxcrt/fx_ucd.h
index 9e1862aa80..c87e459aa5 100644
--- a/core/include/fxcrt/fx_ucd.h
+++ b/core/include/fxcrt/fx_ucd.h
@@ -88,6 +88,20 @@ enum FX_CHARTYPE {
FX_CHARTYPE_ArabicForm = (11 << FX_CHARTYPEBITS),
FX_CHARTYPE_Arabic = (12 << FX_CHARTYPEBITS),
};
+typedef struct _FX_CHARPROPERTIES {
+ union FX_CHARPROPERTIES_UNION{
+ struct FX_CHARPROPERTIES_BIT{
+ FX_DWORD dwBreakType : 6;
+ FX_DWORD dwBidiClass : 5;
+ FX_DWORD dwCharType : 4;
+ FX_DWORD dwRotation : 1;
+ FX_DWORD dwCJKSpecial : 1;
+ FX_DWORD dwVertIndex : 6;
+ FX_DWORD dwBidiIndex : 9;
+ };
+ FX_DWORD dwCharProps;
+ };
+} FX_CHARPROPERTIES;
FX_DWORD FX_GetUnicodeProperties(FX_WCHAR wch);
FX_BOOL FX_IsCtrlCode(FX_WCHAR ch);
FX_BOOL FX_IsRotationCode(FX_WCHAR ch);
@@ -95,4 +109,89 @@ FX_BOOL FX_IsCombinationChar(FX_WCHAR wch);
FX_BOOL FX_IsBidiChar(FX_WCHAR wch);
FX_WCHAR FX_GetMirrorChar(FX_WCHAR wch, FX_BOOL bRTL, FX_BOOL bVertical);
FX_WCHAR FX_GetMirrorChar(FX_WCHAR wch, FX_DWORD dwProps, FX_BOOL bRTL, FX_BOOL bVertical);
+class CFX_Char : public CFX_Object
+{
+public:
+ CFX_Char() : m_wCharCode(0)
+ , m_nBreakType(0)
+ , m_nRotation(0)
+ , m_dwCharProps(0)
+ , m_dwCharStyles(0)
+ , m_iCharWidth(0)
+ , m_iHorizontalScale(100)
+ , m_iVertialScale(100)
+ {
+ }
+ CFX_Char(FX_WORD wCharCode, FX_DWORD dwCharProps)
+ : m_wCharCode(wCharCode)
+ , m_nBreakType(0)
+ , m_nRotation(0)
+ , m_dwCharProps(dwCharProps)
+ , m_dwCharStyles(0)
+ , m_iCharWidth(0)
+ , m_iHorizontalScale(100)
+ , m_iVertialScale(100)
+ {
+ }
+ FX_DWORD GetCharType() const
+ {
+ return m_dwCharProps & FX_CHARTYPEBITSMASK;
+ }
+ FX_WORD m_wCharCode;
+ FX_BYTE m_nBreakType;
+ FX_INT8 m_nRotation;
+ FX_DWORD m_dwCharProps;
+ FX_DWORD m_dwCharStyles;
+ FX_INT32 m_iCharWidth;
+ FX_INT32 m_iHorizontalScale;
+ FX_INT32 m_iVertialScale;
+};
+typedef CFX_ArrayTemplate<CFX_Char> CFX_CharArray;
+class CFX_TxtChar : public CFX_Char
+{
+public:
+ CFX_TxtChar() : CFX_Char()
+ , m_dwStatus(0)
+ , m_iBidiClass(0)
+ , m_iBidiLevel(0)
+ , m_iBidiPos(0)
+ , m_iBidiOrder(0)
+ , m_pUserData(NULL)
+ {
+ }
+ FX_DWORD m_dwStatus;
+ FX_INT16 m_iBidiClass;
+ FX_INT16 m_iBidiLevel;
+ FX_INT16 m_iBidiPos;
+ FX_INT16 m_iBidiOrder;
+ FX_LPVOID m_pUserData;
+};
+typedef CFX_ArrayTemplate<CFX_TxtChar> CFX_TxtCharArray;
+class CFX_RTFChar : public CFX_Char
+{
+public:
+ CFX_RTFChar() : CFX_Char()
+ , m_dwStatus(0)
+ , m_iFontSize(0)
+ , m_iFontHeight(0)
+ , m_iBidiClass(0)
+ , m_iBidiLevel(0)
+ , m_iBidiPos(0)
+ , m_dwLayoutStyles(0)
+ , m_dwIdentity(0)
+ , m_pUserData(NULL)
+ {
+ }
+ FX_DWORD m_dwStatus;
+ FX_INT32 m_iFontSize;
+ FX_INT32 m_iFontHeight;
+ FX_INT16 m_iBidiClass;
+ FX_INT16 m_iBidiLevel;
+ FX_INT16 m_iBidiPos;
+ FX_INT16 m_iBidiOrder;
+ FX_DWORD m_dwLayoutStyles;
+ FX_DWORD m_dwIdentity;
+ IFX_Unknown *m_pUserData;
+};
+typedef CFX_ArrayTemplate<CFX_RTFChar> CFX_RTFCharArray;
#endif
diff --git a/core/include/fxge/fx_font.h b/core/include/fxge/fx_font.h
index 52f8f30d8d..8744919cf8 100644
--- a/core/include/fxge/fx_font.h
+++ b/core/include/fxge/fx_font.h
@@ -29,6 +29,7 @@ class CFontFileFaceInfo;
#define FXFONT_ITALIC 0x40
#define FXFONT_BOLD 0x40000
#define FXFONT_USEEXTERNATTR 0x80000
+#define FXFONT_EXACTMATCH 0x80000000
#define FXFONT_CIDFONT 0x100000
#define FXFONT_ANSI_CHARSET 0
#define FXFONT_DEFAULT_CHARSET 1
@@ -61,7 +62,10 @@ public:
FX_BOOL LoadEmbedded(FX_LPCBYTE data, FX_DWORD size);
- FX_BOOL LoadFile(IFX_FileRead* pFile);
+ FX_BOOL LoadFile(IFX_FileRead* pFile, int nFaceIndex = 0, int* pFaceCount = NULL);
+
+ FX_BOOL LoadClone(const CFX_Font* pFont);
+
FXFT_Face GetFace() const
{
@@ -141,6 +145,7 @@ protected:
FX_BOOL m_bEmbedded;
FX_BOOL m_bVertical;
+ FX_BOOL m_bLogic;
void* m_pOwnedStream;
};
#define ENCODING_INTERNAL 0
@@ -157,6 +162,32 @@ public:
virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const = 0;
};
IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont);
+#define FXFM_ENC_TAG(a, b, c, d) (((FX_DWORD)(a) << 24) | ((FX_DWORD)(b) << 16) | ((FX_DWORD)(c) << 8) | (FX_DWORD)(d))
+#define FXFM_ENCODING_NONE FXFM_ENC_TAG(0, 0, 0, 0)
+#define FXFM_ENCODING_MS_SYMBOL FXFM_ENC_TAG('s', 'y', 'm', 'b')
+#define FXFM_ENCODING_UNICODE FXFM_ENC_TAG('u', 'n', 'i', 'c')
+#define FXFM_ENCODING_MS_SJIS FXFM_ENC_TAG('s', 'j', 'i', 's')
+#define FXFM_ENCODING_MS_GB2312 FXFM_ENC_TAG('g', 'b', ' ', ' ')
+#define FXFM_ENCODING_MS_BIG5 FXFM_ENC_TAG('b', 'i', 'g', '5')
+#define FXFM_ENCODING_MS_WANSUNG FXFM_ENC_TAG('w', 'a', 'n', 's')
+#define FXFM_ENCODING_MS_JOHAB FXFM_ENC_TAG('j', 'o', 'h', 'a')
+#define FXFM_ENCODING_ADOBE_STANDARD FXFM_ENC_TAG('A', 'D', 'O', 'B')
+#define FXFM_ENCODING_ADOBE_EXPERT FXFM_ENC_TAG('A', 'D', 'B', 'E')
+#define FXFM_ENCODING_ADOBE_CUSTOM FXFM_ENC_TAG('A', 'D', 'B', 'C')
+#define FXFM_ENCODING_ADOBE_LATIN_1 FXFM_ENC_TAG('l', 'a', 't', '1')
+#define FXFM_ENCODING_OLD_LATIN_2 FXFM_ENC_TAG('l', 'a', 't', '2')
+#define FXFM_ENCODING_APPLE_ROMAN FXFM_ENC_TAG('a', 'r', 'm', 'n')
+class IFX_FontEncodingEx : public IFX_FontEncoding
+{
+public:
+
+ virtual FX_DWORD GlyphIndexFromName(FX_LPCSTR pStrName) = 0;
+
+ virtual CFX_ByteString NameFromGlyphIndex(FX_DWORD dwGlyphIndex) = 0;
+
+ virtual FX_DWORD CharCodeFromGlyphIndex(FX_DWORD dwGlyphIndex) = 0;
+};
+IFX_FontEncodingEx* FX_CreateFontEncodingEx(CFX_Font* pFont, FX_DWORD nEncodingID = FXFM_ENCODING_NONE);
#define FXFONT_SUBST_MM 0x01
#define FXFONT_SUBST_GLYPHPATH 0x04
#define FXFONT_SUBST_CLEARTYPE 0x08
@@ -277,6 +308,7 @@ public:
}
virtual FXFT_Face FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont);
+ FXFT_Face FindSubstFontByUnicode(FX_DWORD dwUnicode, FX_DWORD flags, int weight, int italic_angle);
private:
CFX_ByteString GetPSNameFromTT(void* hFont);
CFX_ByteString MatchInstalledFonts(const CFX_ByteString& norm_name);
@@ -298,6 +330,10 @@ public:
virtual void Release() = 0;
virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper) = 0;
virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact) = 0;
+ virtual void* MapFontByUnicode(FX_DWORD dwUnicode, int weight, FX_BOOL bItalic, int pitch_family)
+ {
+ return NULL;
+ }
virtual void* GetFont(FX_LPCSTR face) = 0;
virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size) = 0;
virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name) = 0;
@@ -321,6 +357,7 @@ public:
virtual void Release();
virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper);
virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact);
+ virtual void* MapFontByUnicode(FX_DWORD dwUnicode, int weight, FX_BOOL bItalic, int pitch_family);
virtual void* GetFont(FX_LPCSTR face);
virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size);
virtual void DeleteFont(void* hFont);
diff --git a/core/src/fpdfdoc/doc_formfield.cpp b/core/src/fpdfdoc/doc_formfield.cpp
index a2f0fbd297..64e9c287cc 100644
--- a/core/src/fpdfdoc/doc_formfield.cpp
+++ b/core/src/fpdfdoc/doc_formfield.cpp
@@ -797,6 +797,77 @@ int CPDF_FormField::FindOptionValue(FX_LPCWSTR csOptValue, int iStartIndex)
}
return -1;
}
+int CPDF_FormField::InsertOption(CFX_WideString csOptLabel, int index, FX_BOOL bNotify)
+{
+ if (csOptLabel.IsEmpty()) return -1;
+
+ if (bNotify && m_pForm->m_pFormNotify != NULL)
+ {
+ int iRet = 0;
+ if (GetType() == ListBox) iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csOptLabel);
+ if (GetType() == ComboBox) iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csOptLabel);
+ if (iRet < 0) return -1;
+ }
+
+ CFX_ByteString csStr = PDF_EncodeText(csOptLabel, csOptLabel.GetLength());
+ CPDF_Array* pOpt = NULL;
+ CPDF_Object* pValue = FPDF_GetFieldAttr(m_pDict, "Opt");
+ if (pValue == NULL || pValue->GetType() != PDFOBJ_ARRAY)
+ {
+ pOpt = CPDF_Array::Create();
+ if (pOpt == NULL) return -1;
+ m_pDict->SetAt("Opt", pOpt);
+ }
+ else
+ pOpt = (CPDF_Array*)pValue;
+ int iCount = (int)pOpt->GetCount();
+ if (index < 0 || index >= iCount)
+ {
+ pOpt->AddString(csStr);
+ index = iCount;
+ }
+ else {
+ CPDF_String* pString = CPDF_String::Create(csStr);
+ if (pString == NULL) return -1;
+ pOpt->InsertAt(index, pString);
+ }
+
+ if (bNotify && m_pForm->m_pFormNotify != NULL)
+ {
+ if (GetType() == ListBox) m_pForm->m_pFormNotify->AfterSelectionChange(this);
+ if (GetType() == ComboBox) m_pForm->m_pFormNotify->AfterValueChange(this);
+ }
+ m_pForm->m_bUpdated = TRUE;
+ return index;
+}
+FX_BOOL CPDF_FormField::ClearOptions(FX_BOOL bNotify)
+{
+ if (bNotify && m_pForm->m_pFormNotify != NULL)
+ {
+ int iRet = 0;
+ CFX_WideString csValue;
+ int iIndex = GetSelectedIndex(0);
+ if (iIndex >= 0) csValue = GetOptionLabel(iIndex);
+ if (GetType() == ListBox) iRet = m_pForm->m_pFormNotify->BeforeSelectionChange(this, csValue);
+ if (GetType() == ComboBox) iRet = m_pForm->m_pFormNotify->BeforeValueChange(this, csValue);
+ if (iRet < 0) return FALSE;
+ }
+
+ m_pDict->RemoveAt("Opt");
+ m_pDict->RemoveAt("V");
+ m_pDict->RemoveAt("DV");
+ m_pDict->RemoveAt("I");
+ m_pDict->RemoveAt("TI");
+
+ if (bNotify && m_pForm->m_pFormNotify != NULL)
+ {
+ if (GetType() == ListBox) m_pForm->m_pFormNotify->AfterSelectionChange(this);
+ if (GetType() == ComboBox) m_pForm->m_pFormNotify->AfterValueChange(this);
+ }
+
+ m_pForm->m_bUpdated = TRUE;
+ return TRUE;
+}
FX_BOOL CPDF_FormField::CheckControl(int iControlIndex, FX_BOOL bChecked, FX_BOOL bNotify)
{
ASSERT(GetType() == CheckBox || GetType() == RadioButton);
diff --git a/core/src/fxcodec/codec/codec_int.h b/core/src/fxcodec/codec/codec_int.h
index 78672e62ee..3cbdce9265 100644
--- a/core/src/fxcodec/codec/codec_int.h
+++ b/core/src/fxcodec/codec/codec_int.h
@@ -142,13 +142,67 @@ public:
virtual void* Start();
virtual void Finish(void* pContext);
virtual void Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size);
- virtual int ReadHeader(void* pContext, int* width, int* height, int* nComps);
+ virtual int ReadHeader(void* pContext, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute = NULL);
virtual FX_BOOL StartScanline(void* pContext, int down_scale);
virtual FX_BOOL ReadScanline(void* pContext, FX_LPBYTE dest_buf);
virtual FX_DWORD GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr);
protected:
IFX_JpegProvider* m_pExtProvider;
};
+#define PNG_ERROR_SIZE 256
+class CCodec_PngModule : public ICodec_PngModule
+{
+public:
+ CCodec_PngModule()
+ {
+ FXSYS_memset8(m_szLastError, '\0', PNG_ERROR_SIZE);
+ }
+
+ virtual void* Start(void* pModule);
+ virtual void Finish(void* pContext);
+ virtual FX_BOOL Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_DIBAttribute* pAttribute);
+protected:
+ FX_CHAR m_szLastError[PNG_ERROR_SIZE];
+};
+class CCodec_GifModule : public ICodec_GifModule
+{
+public:
+ CCodec_GifModule()
+ {
+ FXSYS_memset8(m_szLastError, '\0', 256);
+ }
+ virtual void* Start(void* pModule);
+ virtual void Finish(void* pContext);
+ virtual FX_DWORD GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr);
+ virtual void Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size);
+
+ virtual FX_INT32 ReadHeader(void* pContext, int* width, int* height,
+ int* pal_num, void** pal_pp, int* bg_index, CFX_DIBAttribute* pAttribute);
+
+ virtual FX_INT32 LoadFrameInfo(void* pContext, int* frame_num);
+
+ virtual FX_INT32 LoadFrame(void* pContext, int frame_num, CFX_DIBAttribute* pAttribute);
+
+protected:
+ FX_CHAR m_szLastError[256];
+};
+class CCodec_BmpModule : public ICodec_BmpModule
+{
+public:
+ CCodec_BmpModule()
+ {
+ FXSYS_memset8(m_szLastError, '\0', 256);
+ }
+ virtual void* Start(void* pModule);
+ virtual void Finish(void* pContext);
+ virtual FX_DWORD GetAvailInput(void* pContext, FX_LPBYTE* avail_buf_ptr);
+ virtual void Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size);
+ virtual FX_INT32 ReadHeader(void* pContext, FX_INT32* width, FX_INT32* height, FX_BOOL* tb_flag, FX_INT32* components, FX_INT32* pal_num, FX_DWORD** pal_pp, CFX_DIBAttribute* pAttribute);
+ virtual FX_INT32 LoadImage(void* pContext);
+
+protected:
+ FX_CHAR m_szLastError[256];
+};
class CCodec_IccModule : public ICodec_IccModule
{
public:
@@ -196,6 +250,15 @@ public:
FX_BOOL Decode(void* ctx, FX_LPBYTE dest_data, int pitch, FX_BOOL bTranslateColor, FX_LPBYTE offsets);
void DestroyDecoder(void* ctx);
};
+class CCodec_TiffModule : public ICodec_TiffModule
+{
+public:
+ virtual FX_LPVOID CreateDecoder(IFX_FileRead* file_ptr);
+ virtual void GetFrames(FX_LPVOID ctx, FX_INT32& frames);
+ virtual FX_BOOL LoadFrameInfo(FX_LPVOID ctx, FX_INT32 frame, FX_DWORD& width, FX_DWORD& height, FX_DWORD& comps, FX_DWORD& bpc, CFX_DIBAttribute* pAttribute = NULL);
+ virtual FX_BOOL Decode(FX_LPVOID ctx, class CFX_DIBitmap* pDIBitmap);
+ virtual void DestroyDecoder(FX_LPVOID ctx);
+};
#include "../jbig2/JBig2_Context.h"
class CPDF_Jbig2Interface : public CFX_Object, public CJBig2_Module
{
@@ -270,3 +333,27 @@ public:
CPDF_Jbig2Interface m_Module;
private:
};
+class CFX_DIBAttributeExif : public IFX_DIBAttributeExif
+{
+public:
+ CFX_DIBAttributeExif();
+ ~CFX_DIBAttributeExif();
+ virtual FX_BOOL GetInfo(FX_WORD tag, FX_LPVOID val);
+
+ FX_BOOL ParseExif(CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE>* pHead, FX_LPBYTE data, FX_DWORD len, CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE>* pVal);
+
+ typedef FX_WORD (*_Read2Bytes)(FX_LPBYTE data);
+ typedef FX_DWORD (*_Read4Bytes)(FX_LPBYTE data);
+ FX_LPBYTE ParseExifIFH(FX_LPBYTE data, FX_DWORD len, _Read2Bytes* pReadWord, _Read4Bytes* pReadDword);
+ FX_BOOL ParseExifIFD(CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE>* pMap, FX_LPBYTE data, FX_DWORD len);
+
+ FX_LPBYTE m_pExifData;
+
+ FX_DWORD m_dwExifDataLen;
+
+ void clear();
+ _Read2Bytes m_readWord;
+ _Read4Bytes m_readDword;
+ CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE> m_TagHead;
+ CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE> m_TagVal;
+};
diff --git a/core/src/fxcodec/codec/fx_codec.cpp b/core/src/fxcodec/codec/fx_codec.cpp
index 456ec40fea..b2f70c73d1 100644
--- a/core/src/fxcodec/codec/fx_codec.cpp
+++ b/core/src/fxcodec/codec/fx_codec.cpp
@@ -14,6 +14,10 @@ CCodec_ModuleMgr::CCodec_ModuleMgr()
m_pJpxModule = FX_NEW CCodec_JpxModule;
m_pJbig2Module = FX_NEW CCodec_Jbig2Module;
m_pIccModule = FX_NEW CCodec_IccModule;
+ m_pPngModule = FX_NEW CCodec_PngModule;
+ m_pGifModule = FX_NEW CCodec_GifModule;
+ m_pBmpModule = FX_NEW CCodec_BmpModule;
+ m_pTiffModule = FX_NEW CCodec_TiffModule;
m_pFlateModule = FX_NEW CCodec_FlateModule;
}
CCodec_ModuleMgr::~CCodec_ModuleMgr()
@@ -249,6 +253,343 @@ void CCodec_ModuleMgr::Destroy()
{
delete this;
}
+CFX_DIBAttribute::CFX_DIBAttribute()
+{
+ FXSYS_memset32(this, 0, sizeof(CFX_DIBAttribute));
+ m_nXDPI = -1;
+ m_nYDPI = -1;
+ m_fAspectRatio = -1.0f;
+ m_pExif = FX_NEW CFX_DIBAttributeExif;
+}
+CFX_DIBAttribute::~CFX_DIBAttribute()
+{
+ if (m_pExif) {
+ delete m_pExif;
+ }
+}
+CFX_DIBAttributeExif::CFX_DIBAttributeExif()
+{
+ m_pExifData = NULL;
+ m_dwExifDataLen = 0;
+}
+CFX_DIBAttributeExif::~CFX_DIBAttributeExif()
+{
+ clear();
+}
+void CFX_DIBAttributeExif::clear()
+{
+ if (m_pExifData) {
+ FX_Free(m_pExifData);
+ }
+ m_pExifData = NULL;
+ FX_DWORD key = 0;
+ FX_LPBYTE buf = NULL;
+ FX_POSITION pos = NULL;
+ pos = m_TagHead.GetStartPosition();
+ while (pos) {
+ m_TagHead.GetNextAssoc(pos, key, buf);
+ if (buf) {
+ FX_Free(buf);
+ }
+ }
+ m_TagHead.RemoveAll();
+ pos = m_TagVal.GetStartPosition();
+ while (pos) {
+ m_TagVal.GetNextAssoc(pos, key, buf);
+ if (buf) {
+ FX_Free(buf);
+ }
+ }
+ m_TagVal.RemoveAll();
+}
+static FX_WORD _Read2BytesL(FX_LPBYTE data)
+{
+ ASSERT(data);
+ return data[0] | (data[1] << 8);
+}
+static FX_WORD _Read2BytesB(FX_LPBYTE data)
+{
+ ASSERT(data);
+ return data[1] | (data[0] << 8);
+}
+static FX_DWORD _Read4BytesL(FX_LPBYTE data)
+{
+ return _Read2BytesL(data) | (_Read2BytesL(data + 2) << 16);
+}
+static FX_DWORD _Read4BytesB(FX_LPBYTE data)
+{
+ return _Read2BytesB(data + 2) | (_Read2BytesB(data) << 16);
+}
+typedef FX_WORD (*_Read2Bytes) (FX_LPBYTE data);
+typedef FX_DWORD (*_Read4Bytes) (FX_LPBYTE data);
+typedef void (*_Write2Bytes) (FX_LPBYTE data, FX_WORD val);
+typedef void (*_Write4Bytes) (FX_LPBYTE data, FX_DWORD val);
+FX_LPBYTE CFX_DIBAttributeExif::ParseExifIFH(FX_LPBYTE data, FX_DWORD len, _Read2Bytes* pReadWord, _Read4Bytes* pReadDword)
+{
+ if (len > 8) {
+ FX_BOOL tag = FALSE;
+ if (FXSYS_memcmp32(data, "\x49\x49\x2a\x00", 4) == 0) {
+ if (pReadWord) {
+ *pReadWord = _Read2BytesL;
+ }
+ if (pReadDword) {
+ *pReadDword = _Read4BytesL;
+ }
+ tag = TRUE;
+ } else if (FXSYS_memcmp32(data, "\x4d\x4d\x00\x2a", 4) == 0) {
+ if (pReadWord) {
+ *pReadWord = _Read2BytesB;
+ }
+ if (pReadDword) {
+ *pReadDword = _Read4BytesB;
+ }
+ tag = TRUE;
+ }
+ if (tag) {
+ data += 4;
+ if (pReadDword) {
+ data += (*pReadDword)(data) - 4;
+ } else {
+ data += 4;
+ }
+ }
+ }
+ return data;
+}
+FX_BOOL CFX_DIBAttributeExif::ParseExifIFD(CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE>* pMap, FX_LPBYTE data, FX_DWORD len)
+{
+ if (pMap && data) {
+ if (len > 8) {
+ FX_WORD wTagNum = m_readWord(data);
+ data += 2;
+ FX_DWORD wTag;
+ FX_LPBYTE buf;
+ while (wTagNum--) {
+ wTag = m_readWord(data);
+ data += 2;
+ if (!pMap->Lookup(wTag, buf)) {
+ buf = FX_Alloc(FX_BYTE, 10);
+ if (buf == NULL) {
+ return FALSE;
+ }
+ FXSYS_memcpy32(buf, data, 10);
+ pMap->SetAt(wTag, buf);
+ }
+ data += 10;
+ }
+ FX_DWORD dwIFDOffset;
+ dwIFDOffset = m_readDword(data);
+ while (dwIFDOffset && dwIFDOffset < len) {
+ data = m_pExifData + dwIFDOffset;
+ wTagNum = m_readWord(data);
+ data += 2;
+ while (wTagNum--) {
+ wTag = m_readWord(data);
+ data += 2;
+ if (!pMap->Lookup(wTag, buf)) {
+ buf = FX_Alloc(FX_BYTE, 10);
+ if (buf == NULL) {
+ return FALSE;
+ }
+ FXSYS_memcpy32(buf, data, 10);
+ pMap->SetAt(wTag, buf);
+ }
+ data += 10;
+ }
+ dwIFDOffset = m_readDword(data);
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+enum FX_ExifDataType {
+ FX_UnsignedByte = 1,
+ FX_AscString,
+ FX_UnsignedShort,
+ FX_UnsignedLong,
+ FX_UnsignedRation,
+ FX_SignedByte,
+ FX_Undefined,
+ FX_SignedShort,
+ FX_SignedLong,
+ FX_SignedRation,
+ FX_SignedFloat,
+ FX_DoubleFloat
+};
+FX_BOOL CFX_DIBAttributeExif::ParseExif(CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE>* pHead, FX_LPBYTE data, FX_DWORD len, CFX_MapPtrTemplate<FX_DWORD, FX_LPBYTE>* pVal)
+{
+ if (pHead && data && pVal) {
+ if (len > 8) {
+ FX_LPBYTE old_data = data;
+ data = ParseExifIFH(data, len, &m_readWord, &m_readDword);
+ if (data == old_data) {
+ return FALSE;
+ }
+ if (pHead->GetCount() == 0) {
+ if (!ParseExifIFD(pHead, data, len)) {
+ return FALSE;
+ }
+ }
+ FX_DWORD dwModuleNum;
+ FX_WORD type;
+ FX_DWORD dwSize;
+ FX_DWORD tag;
+ FX_LPBYTE head;
+ FX_POSITION pos = pHead->GetStartPosition();
+ while (pos) {
+ pHead->GetNextAssoc(pos, tag, head);
+ FX_LPBYTE val = NULL, buf = NULL, temp = NULL;
+ int i;
+ if (head) {
+ type = m_readWord(head);
+ head += 2;
+ dwModuleNum = m_readDword(head);
+ head += 4;
+ switch (type) {
+ case FX_UnsignedByte:
+ case FX_AscString:
+ case FX_SignedByte:
+ case FX_Undefined:
+ dwSize = dwModuleNum;
+ val = FX_Alloc(FX_BYTE, dwSize);
+ if (val == NULL) {
+ return FALSE;
+ }
+ if (dwSize > 4) {
+ FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize);
+ } else {
+ FXSYS_memcpy32(val, head, dwSize);
+ }
+ break;
+ case FX_UnsignedShort:
+ case FX_SignedShort:
+ dwSize = dwModuleNum << 1;
+ val = FX_Alloc(FX_BYTE, dwSize);
+ if (val == NULL) {
+ return FALSE;
+ }
+ if (dwSize > 4) {
+ FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize);
+ } else {
+ FXSYS_memcpy32(val, head, dwSize);
+ }
+ buf = val;
+ for(i = 0; i < (int)dwModuleNum; i ++) {
+ *(FX_WORD*)buf = m_readWord(buf);
+ buf += 2;
+ }
+ break;
+ case FX_UnsignedLong:
+ case FX_SignedLong:
+ case FX_SignedFloat:
+ dwSize = dwModuleNum << 2;
+ val = FX_Alloc(FX_BYTE, dwSize);
+ if (val == NULL) {
+ return FALSE;
+ }
+ if (dwSize > 4) {
+ FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize);
+ } else {
+ FXSYS_memcpy32(val, head, dwSize);
+ }
+ buf = val;
+ for(i = 0; i < (int)dwModuleNum; i ++) {
+ *(FX_DWORD*)buf = m_readDword(buf);
+ buf += 4;
+ }
+ break;
+ case FX_UnsignedRation:
+ case FX_SignedRation: {
+ dwSize = dwModuleNum << 3;
+ buf = FX_Alloc(FX_BYTE, dwSize);
+ if (buf == NULL) {
+ return FALSE;
+ }
+ if (dwSize > 4) {
+ FXSYS_memcpy32(buf, old_data + m_readDword(head), dwSize);
+ } else {
+ FXSYS_memcpy32(buf, head, dwSize);
+ }
+ temp = buf;
+ val = FX_Alloc(FX_BYTE, dwSize / 2);
+ if (val == NULL) {
+ FX_Free(buf);
+ return FALSE;
+ }
+ for(i = 0; i < (int)dwModuleNum; i ++) {
+ *(FX_DWORD*)temp = m_readDword(temp);
+ *(FX_DWORD*)(temp + 4) = m_readDword(temp + 4);
+ FX_DWORD* lNumerator = (FX_DWORD*)temp;
+ FX_DWORD* lNenominator = (FX_DWORD*)(temp + 4);
+ *(FX_FLOAT*)(val + i * 4) = (FX_FLOAT)(*lNumerator) / (FX_FLOAT)(*lNenominator);
+ temp += 8;
+ }
+ FX_Free(buf);
+ }
+ break;
+ case FX_DoubleFloat:
+ dwSize = dwModuleNum << 3;
+ val = FX_Alloc(FX_BYTE, dwSize);
+ if (val == NULL) {
+ return FALSE;
+ }
+ if (dwSize > 4) {
+ FXSYS_memcpy32(val, old_data + m_readDword(head), dwSize);
+ } else {
+ FXSYS_memcpy32(val, head, dwSize);
+ }
+ buf = val;
+ for(i = 0; i < (int)dwModuleNum; i ++) {
+ *(FX_DWORD*)buf = m_readDword(buf);
+ *(FX_DWORD*)(buf + 4) = m_readDword(buf + 4);
+ buf += 8;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ pVal->SetAt(tag, val);
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+#define FXEXIF_INFOCONVERT(T) {T* src = (T*)ptr; T* dst = (T*)val; *dst = *src;}
+FX_BOOL CFX_DIBAttributeExif::GetInfo( FX_WORD tag, FX_LPVOID val )
+{
+ if (m_TagVal.GetCount() == 0) {
+ if (!ParseExif(&m_TagHead, m_pExifData, m_dwExifDataLen, &m_TagVal)) {
+ return FALSE;
+ }
+ }
+ FX_LPBYTE ptr = NULL;
+ if (m_TagVal.Lookup(tag, ptr)) {
+ switch (tag) {
+ case EXIFTAG_USHORT_RESUNIT:
+ FXEXIF_INFOCONVERT(FX_WORD);
+ {
+ FX_WORD* ptr = (FX_WORD*)val;
+ *ptr -= 1;
+ }
+ break;
+ case EXIFTAG_FLOAT_DPIX:
+ case EXIFTAG_FLOAT_DPIY:
+ FXEXIF_INFOCONVERT(FX_FLOAT);
+ break;
+ case EXIFTAG_USHORT_ORIENTATION:
+ FXEXIF_INFOCONVERT(FX_WORD);
+ break;
+ default: {
+ FX_LPBYTE* dst = (FX_LPBYTE*)val;
+ *dst = ptr;
+ }
+ }
+ }
+ return TRUE;
+}
class CCodec_RLScanlineDecoder : public CCodec_ScanlineDecoder
{
public:
diff --git a/core/src/fxcodec/codec/fx_codec_bmp.cpp b/core/src/fxcodec/codec/fx_codec_bmp.cpp
new file mode 100644
index 0000000000..4e974e2124
--- /dev/null
+++ b/core/src/fxcodec/codec/fx_codec_bmp.cpp
@@ -0,0 +1,124 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxcodec/fx_codec.h"
+#include "../../../include/fxge/fx_dib.h"
+#include "codec_int.h"
+#include "../lbmp/fx_bmp.h"
+struct FXBMP_Context {
+ bmp_decompress_struct_p bmp_ptr;
+ void* parent_ptr;
+ void* child_ptr;
+
+ void* (*m_AllocFunc)(unsigned int);
+ void (*m_FreeFunc)(void*);
+};
+extern "C" {
+ static void* _bmp_alloc_func(unsigned int size)
+ {
+ return FX_Alloc(char, size);
+ }
+ static void _bmp_free_func(void* p)
+ {
+ if(p != NULL) {
+ FX_Free(p);
+ }
+ }
+};
+static void _bmp_error_data(bmp_decompress_struct_p bmp_ptr, FX_LPCSTR err_msg)
+{
+ FXSYS_strncpy((char*)bmp_ptr->err_ptr, err_msg, BMP_MAX_ERROR_SIZE - 1);
+ longjmp(bmp_ptr->jmpbuf, 1);
+}
+static void _bmp_read_scanline(bmp_decompress_struct_p bmp_ptr, FX_INT32 row_num, FX_LPBYTE row_buf)
+{
+ FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr;
+ CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr;
+ pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf);
+}
+static FX_BOOL _bmp_get_data_position(bmp_decompress_struct_p bmp_ptr, FX_DWORD rcd_pos)
+{
+ FXBMP_Context* p = (FXBMP_Context*)bmp_ptr->context_ptr;
+ CCodec_BmpModule* pModule = (CCodec_BmpModule*)p->parent_ptr;
+ return pModule->InputImagePositionBufCallback(p->child_ptr, rcd_pos);
+}
+void* CCodec_BmpModule::Start(void* pModule)
+{
+ FXBMP_Context* p = (FXBMP_Context*)FX_Alloc(FX_BYTE, sizeof(FXBMP_Context));
+ if (p == NULL) {
+ return NULL;
+ }
+ FXSYS_memset32(p, 0, sizeof(FXBMP_Context));
+ if(p == NULL) {
+ return NULL;
+ }
+ p->m_AllocFunc = _bmp_alloc_func;
+ p->m_FreeFunc = _bmp_free_func;
+ p->bmp_ptr = NULL;
+ p->parent_ptr = (void*)this;
+ p->child_ptr = pModule;
+ p->bmp_ptr = _bmp_create_decompress();
+ if (p->bmp_ptr == NULL) {
+ FX_Free(p);
+ return NULL;
+ }
+ p->bmp_ptr->context_ptr = (void*)p;
+ p->bmp_ptr->err_ptr = m_szLastError;
+ p->bmp_ptr->_bmp_error_fn = _bmp_error_data;
+ p->bmp_ptr->_bmp_get_row_fn = _bmp_read_scanline;
+ p->bmp_ptr->_bmp_get_data_position_fn = _bmp_get_data_position;
+ return p;
+}
+void CCodec_BmpModule::Finish(void* pContext)
+{
+ FXBMP_Context* p = (FXBMP_Context*)pContext;
+ if(p != NULL) {
+ _bmp_destroy_decompress(&p->bmp_ptr);
+ p->m_FreeFunc(p);
+ }
+}
+FX_INT32 CCodec_BmpModule::ReadHeader(void* pContext, FX_INT32* width, FX_INT32* height, FX_BOOL* tb_flag, FX_INT32* components, FX_INT32* pal_num, FX_DWORD** pal_pp, CFX_DIBAttribute* pAttribute)
+{
+ FXBMP_Context* p = (FXBMP_Context*)pContext;
+ if(setjmp(p->bmp_ptr->jmpbuf)) {
+ return 0;
+ }
+ FX_INT32 ret = _bmp_read_header(p->bmp_ptr);
+ if (ret != 1) {
+ return ret;
+ }
+ *width = p->bmp_ptr->width;
+ *height = p->bmp_ptr->height;
+ *tb_flag = p->bmp_ptr->imgTB_flag;
+ *components = p->bmp_ptr->components;
+ *pal_num = p->bmp_ptr->pal_num;
+ *pal_pp = p->bmp_ptr->pal_ptr;
+ if (pAttribute) {
+ pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER;
+ pAttribute->m_nXDPI = p->bmp_ptr->dpi_x;
+ pAttribute->m_nYDPI = p->bmp_ptr->dpi_y;
+ pAttribute->m_nBmpCompressType = p->bmp_ptr->compress_flag;
+ }
+ return 1;
+}
+FX_INT32 CCodec_BmpModule::LoadImage(void* pContext)
+{
+ FXBMP_Context* p = (FXBMP_Context*)pContext;
+ if(setjmp(p->bmp_ptr->jmpbuf)) {
+ return 0;
+ }
+ return _bmp_decode_image(p->bmp_ptr);
+}
+FX_DWORD CCodec_BmpModule::GetAvailInput(void* pContext, FX_LPBYTE* avial_buf_ptr)
+{
+ FXBMP_Context* p = (FXBMP_Context*)pContext;
+ return _bmp_get_avail_input(p->bmp_ptr, avial_buf_ptr);
+}
+void CCodec_BmpModule::Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size)
+{
+ FXBMP_Context* p = (FXBMP_Context*)pContext;
+ _bmp_input_buffer(p->bmp_ptr, (FX_LPBYTE)src_buf, src_size);
+}
diff --git a/core/src/fxcodec/codec/fx_codec_gif.cpp b/core/src/fxcodec/codec/fx_codec_gif.cpp
new file mode 100644
index 0000000000..1fc708db5c
--- /dev/null
+++ b/core/src/fxcodec/codec/fx_codec_gif.cpp
@@ -0,0 +1,176 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxcodec/fx_codec.h"
+#include "../../../include/fxge/fx_dib.h"
+#include "codec_int.h"
+#include "../lgif/fx_gif.h"
+struct FXGIF_Context {
+ gif_decompress_struct_p gif_ptr;
+ void* parent_ptr;
+ void* child_ptr;
+
+ void* (*m_AllocFunc)(unsigned int);
+ void (*m_FreeFunc)(void*);
+};
+extern "C" {
+ static void* _gif_alloc_func(unsigned int size)
+ {
+ return FX_Alloc(char, size);
+ }
+ static void _gif_free_func(void* p)
+ {
+ if(p != NULL) {
+ FX_Free(p);
+ }
+ }
+};
+static void _gif_error_data(gif_decompress_struct_p gif_ptr, FX_LPCSTR err_msg)
+{
+ FXSYS_strncpy((char*)gif_ptr->err_ptr, err_msg, GIF_MAX_ERROR_SIZE - 1);
+ longjmp(gif_ptr->jmpbuf, 1);
+}
+static FX_LPBYTE _gif_ask_buf_for_pal(gif_decompress_struct_p gif_ptr, FX_INT32 pal_size)
+{
+ FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
+ CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
+ return pModule->AskLocalPaletteBufCallback(p->child_ptr,
+ _gif_get_frame_num(gif_ptr),
+ pal_size);
+}
+static void _gif_record_current_position(gif_decompress_struct_p gif_ptr, FX_DWORD* cur_pos_ptr)
+{
+ FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
+ CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
+ pModule->RecordCurrentPositionCallback(p->child_ptr, *cur_pos_ptr);
+}
+static void _gif_read_scanline(gif_decompress_struct_p gif_ptr, FX_INT32 row_num, FX_LPBYTE row_buf)
+{
+ FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
+ CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
+ pModule->ReadScanlineCallback(p->child_ptr, row_num, row_buf);
+}
+static FX_BOOL _gif_get_record_position(gif_decompress_struct_p gif_ptr, FX_DWORD cur_pos,
+ FX_INT32 left, FX_INT32 top, FX_INT32 width, FX_INT32 height,
+ FX_INT32 pal_num, void* pal_ptr,
+ FX_INT32 delay_time, FX_BOOL user_input,
+ FX_INT32 trans_index, FX_INT32 disposal_method, FX_BOOL interlace)
+{
+ FXGIF_Context* p = (FXGIF_Context*)gif_ptr->context_ptr;
+ CCodec_GifModule* pModule = (CCodec_GifModule*)p->parent_ptr;
+ return pModule->InputRecordPositionBufCallback(p->child_ptr, cur_pos, FX_RECT(left, top, left + width, top + height),
+ pal_num, pal_ptr, delay_time, user_input, trans_index, disposal_method, interlace);
+}
+void* CCodec_GifModule::Start(void* pModule)
+{
+ FXGIF_Context* p = (FXGIF_Context*)FX_Alloc(FX_BYTE, sizeof(FXGIF_Context));
+ if (p == NULL) {
+ return NULL;
+ }
+ FXSYS_memset32(p, 0, sizeof(FXGIF_Context));
+ p->m_AllocFunc = _gif_alloc_func;
+ p->m_FreeFunc = _gif_free_func;
+ p->gif_ptr = NULL;
+ p->parent_ptr = (void*)this;
+ p->child_ptr = pModule;
+ p->gif_ptr = _gif_create_decompress();
+ if (p->gif_ptr == NULL) {
+ FX_Free(p);
+ return NULL;
+ }
+ p->gif_ptr->context_ptr = (void*)p;
+ p->gif_ptr->err_ptr = m_szLastError;
+ p->gif_ptr->_gif_error_fn = _gif_error_data;
+ p->gif_ptr->_gif_ask_buf_for_pal_fn = _gif_ask_buf_for_pal;
+ p->gif_ptr->_gif_record_current_position_fn = _gif_record_current_position;
+ p->gif_ptr->_gif_get_row_fn = _gif_read_scanline;
+ p->gif_ptr->_gif_get_record_position_fn = _gif_get_record_position;
+ return p;
+}
+void CCodec_GifModule::Finish(void* pContext)
+{
+ FXGIF_Context* p = (FXGIF_Context*)pContext;
+ if(p != NULL) {
+ _gif_destroy_decompress(&p->gif_ptr);
+ p->m_FreeFunc(p);
+ }
+}
+FX_INT32 CCodec_GifModule::ReadHeader(void* pContext, int* width, int* height,
+ int* pal_num, void** pal_pp, int* bg_index, CFX_DIBAttribute* pAttribute)
+{
+ FXGIF_Context* p = (FXGIF_Context*)pContext;
+ if(setjmp(p->gif_ptr->jmpbuf)) {
+ return 0;
+ }
+ FX_INT32 ret = _gif_read_header(p->gif_ptr);
+ if (ret != 1) {
+ return ret;
+ }
+ if (pAttribute) {
+ }
+ *width = p->gif_ptr->width;
+ *height = p->gif_ptr->height;
+ *pal_num = p->gif_ptr->global_pal_num;
+ *pal_pp = p->gif_ptr->global_pal_ptr;
+ *bg_index = p->gif_ptr->bc_index;
+ return 1;
+}
+FX_INT32 CCodec_GifModule::LoadFrameInfo(void* pContext, int* frame_num)
+{
+ FXGIF_Context* p = (FXGIF_Context*)pContext;
+ if(setjmp(p->gif_ptr->jmpbuf)) {
+ return 0;
+ }
+ FX_INT32 ret = _gif_get_frame(p->gif_ptr);
+ if (ret != 1) {
+ return ret;
+ }
+ *frame_num = _gif_get_frame_num(p->gif_ptr);
+ return 1;
+}
+FX_INT32 CCodec_GifModule::LoadFrame(void* pContext, int frame_num, CFX_DIBAttribute* pAttribute)
+{
+ FXGIF_Context* p = (FXGIF_Context*)pContext;
+ if(setjmp(p->gif_ptr->jmpbuf)) {
+ return 0;
+ }
+ FX_INT32 ret = _gif_load_frame(p->gif_ptr, frame_num);
+ if (ret == 1) {
+ if (pAttribute) {
+ pAttribute->m_nGifLeft = p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->left;
+ pAttribute->m_nGifTop = p->gif_ptr->img_ptr_arr_ptr->GetAt(frame_num)->image_info_ptr->top;
+ pAttribute->m_fAspectRatio = p->gif_ptr->pixel_aspect;
+ if (p->gif_ptr->cmt_data_ptr) {
+ FX_LPCBYTE buf = (FX_LPCBYTE)p->gif_ptr->cmt_data_ptr->GetBuffer(0);
+ FX_DWORD len = p->gif_ptr->cmt_data_ptr->GetLength();
+ if (len > 21) {
+ FX_BYTE size = *buf++;
+ if (size) {
+ pAttribute->m_strAuthor = CFX_ByteString(buf, size);
+ } else {
+ pAttribute->m_strAuthor.Empty();
+ }
+ buf += size;
+ size = *buf++;
+ if (size == 20) {
+ FXSYS_memcpy32(pAttribute->m_strTime, buf, size);
+ }
+ }
+ }
+ }
+ }
+ return ret;
+}
+FX_DWORD CCodec_GifModule::GetAvailInput(void* pContext, FX_LPBYTE* avial_buf_ptr)
+{
+ FXGIF_Context* p = (FXGIF_Context*)pContext;
+ return _gif_get_avail_input(p->gif_ptr, avial_buf_ptr);
+}
+void CCodec_GifModule::Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size)
+{
+ FXGIF_Context* p = (FXGIF_Context*)pContext;
+ _gif_input_buffer(p->gif_ptr, (FX_LPBYTE)src_buf, src_size);
+}
diff --git a/core/src/fxcodec/codec/fx_codec_jpeg.cpp b/core/src/fxcodec/codec/fx_codec_jpeg.cpp
index 489f099bf8..95770ea26e 100644
--- a/core/src/fxcodec/codec/fx_codec_jpeg.cpp
+++ b/core/src/fxcodec/codec/fx_codec_jpeg.cpp
@@ -73,6 +73,68 @@ extern "C" {
#define JPEG_MARKER_AUTHORTIME (JPEG_APP0 + 3)
#define JPEG_MARKER_MAXSIZE 0xFFFF
#define JPEG_OVERHEAD_LEN 14
+static FX_BOOL _JpegIsIccMarker(jpeg_saved_marker_ptr marker)
+{
+ if (marker->marker == JPEG_MARKER_ICC &&
+ marker->data_length >= JPEG_OVERHEAD_LEN &&
+ (FXSYS_memcmp32(marker->data, "\x49\x43\x43\x5f\x50\x52\x4f\x46\x49\x4c\x45\x00", 12) == 0)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+static FX_BOOL _JpegLoadIccProfile(j_decompress_ptr cinfo, FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length)
+{
+ if(icc_buf_ptr == NULL || icc_length == NULL) {
+ return FALSE;
+ }
+ *icc_buf_ptr = NULL;
+ *icc_length = 0;
+ FX_LPBYTE icc_data_ptr = NULL;
+ FX_DWORD icc_data_len = 0;
+ FX_BYTE count_icc_marker = 0;
+ FX_BYTE num_icc_marker = 0;
+ jpeg_saved_marker_ptr marker_list[256] = {NULL};
+ for (jpeg_saved_marker_ptr cur_marker = cinfo->marker_list;
+ cur_marker != NULL;
+ cur_marker = cur_marker->next) {
+ if(_JpegIsIccMarker(cur_marker)) {
+ if(count_icc_marker == 0) {
+ num_icc_marker = cur_marker->data[13];
+ } else if(num_icc_marker != cur_marker->data[13]) {
+ return FALSE;
+ }
+ int sn = cur_marker->data[12] - 1;
+ if(sn < 0 || sn >= num_icc_marker) {
+ return FALSE;
+ }
+ if(marker_list[sn] == NULL) {
+ marker_list[sn] = cur_marker;
+ } else {
+ return FALSE;
+ }
+ count_icc_marker ++;
+ icc_data_len += (cur_marker->data_length - JPEG_OVERHEAD_LEN);
+ }
+ }
+ if(count_icc_marker != num_icc_marker) {
+ return FALSE;
+ }
+ if(num_icc_marker == 0) {
+ return TRUE;
+ }
+ icc_data_ptr = FX_Alloc(FX_BYTE, icc_data_len);
+ if(icc_buf_ptr == NULL) {
+ return FALSE;
+ }
+ *icc_buf_ptr = icc_data_ptr;
+ *icc_length = icc_data_len;
+ for (int idx = 0; idx < num_icc_marker; idx++) {
+ icc_data_len = marker_list[idx]->data_length - JPEG_OVERHEAD_LEN;
+ FXSYS_memcpy32(icc_data_ptr, marker_list[idx]->data + JPEG_OVERHEAD_LEN, icc_data_len);
+ icc_data_ptr += icc_data_len;
+ }
+ return TRUE;
+}
static FX_BOOL _JpegEmbedIccProfile(j_compress_ptr cinfo, FX_LPCBYTE icc_buf_ptr, FX_DWORD icc_length)
{
if(icc_buf_ptr == NULL || icc_length == 0) {
@@ -207,6 +269,17 @@ static void _JpegEncode(const CFX_DIBSource* pSource, FX_LPBYTE& dest_buf, FX_ST
}
dest_size = dest_buf_length - (FX_STRSIZE)dest.free_in_buffer;
}
+static void _JpegLoadAttribute(struct jpeg_decompress_struct* pInfo, CFX_DIBAttribute* pAttribute)
+{
+ if (pInfo == NULL || pAttribute == NULL) {
+ return;
+ }
+ if (pAttribute) {
+ pAttribute->m_nXDPI = pInfo->X_density;
+ pAttribute->m_nYDPI = pInfo->Y_density;
+ pAttribute->m_wDPIUnit = pInfo->density_unit;
+ }
+}
static FX_BOOL _JpegLoadInfo(FX_LPCBYTE src_buf, FX_DWORD src_size, int& width, int& height,
int& num_components, int& bits_per_components, FX_BOOL& color_transform,
FX_LPBYTE* icc_buf_ptr, FX_DWORD* icc_length)
@@ -613,10 +686,10 @@ void CCodec_JpegModule::Input(void* pContext, const unsigned char* src_buf, FX_D
p->m_SrcMgr.next_input_byte = src_buf;
p->m_SrcMgr.bytes_in_buffer = src_size;
}
-int CCodec_JpegModule::ReadHeader(void* pContext, int* width, int* height, int* nComps)
+int CCodec_JpegModule::ReadHeader(void* pContext, int* width, int* height, int* nComps, CFX_DIBAttribute* pAttribute)
{
if (m_pExtProvider) {
- return m_pExtProvider->ReadHeader(pContext, width, height, nComps);
+ return m_pExtProvider->ReadHeader(pContext, width, height, nComps, pAttribute);
}
FXJPEG_Context* p = (FXJPEG_Context*)pContext;
if (setjmp(p->m_JumpMark) == -1) {
@@ -632,6 +705,7 @@ int CCodec_JpegModule::ReadHeader(void* pContext, int* width, int* height, int*
*width = p->m_Info.image_width;
*height = p->m_Info.image_height;
*nComps = p->m_Info.num_components;
+ _JpegLoadAttribute(&p->m_Info, pAttribute);
return 0;
}
FX_BOOL CCodec_JpegModule::StartScanline(void* pContext, int down_scale)
diff --git a/core/src/fxcodec/codec/fx_codec_png.cpp b/core/src/fxcodec/codec/fx_codec_png.cpp
new file mode 100644
index 0000000000..0ddae7a7cd
--- /dev/null
+++ b/core/src/fxcodec/codec/fx_codec_png.cpp
@@ -0,0 +1,245 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxcodec/fx_codec.h"
+#include "../../../include/fxge/fx_dib.h"
+#include "codec_int.h"
+extern "C" {
+#undef FAR
+#include "../fx_lpng/include/fx_png.h"
+}
+static void _png_error_data(png_structp png_ptr, png_const_charp error_msg)
+{
+ if(png_get_error_ptr(png_ptr)) {
+ FXSYS_strncpy((char*)png_get_error_ptr(png_ptr), error_msg, PNG_ERROR_SIZE - 1);
+ }
+ longjmp(png_jmpbuf(png_ptr), 1);
+}
+static void _png_warning_data(png_structp png_ptr, png_const_charp error_msg)
+{
+}
+static void _png_load_bmp_attribute(png_structp png_ptr, png_infop info_ptr, CFX_DIBAttribute* pAttribute)
+{
+ if (pAttribute) {
+#if defined(PNG_pHYs_SUPPORTED)
+ pAttribute->m_nXDPI = png_get_x_pixels_per_meter(png_ptr, info_ptr);
+ pAttribute->m_nYDPI = png_get_y_pixels_per_meter(png_ptr, info_ptr);
+ png_uint_32 res_x, res_y;
+ int unit_type;
+ png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type);
+ switch (unit_type) {
+ case PNG_RESOLUTION_METER:
+ pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_METER;
+ break;
+ default:
+ pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_NONE;
+ }
+#endif
+#if defined(PNG_iCCP_SUPPORTED)
+ png_charp icc_name;
+ png_bytep icc_profile;
+ png_uint_32 icc_proflen;
+ int compress_type;
+ png_get_iCCP(png_ptr, info_ptr, &icc_name, &compress_type, &icc_profile, &icc_proflen);
+#endif
+ int bTime = 0;
+#if defined(PNG_tIME_SUPPORTED)
+ png_timep t = NULL;
+ png_get_tIME(png_ptr, info_ptr, &t);
+ if (t) {
+ FXSYS_memset32(pAttribute->m_strTime, 0, 20);
+ FXSYS_sprintf((FX_LPSTR)pAttribute->m_strTime, "%4d:%2d:%2d %2d:%2d:%2d", t->year, t->month, t->day, t->hour, t->minute, t->second);
+ bTime = 1;
+ }
+#endif
+#if defined(PNG_TEXT_SUPPORTED)
+ int i;
+ FX_DWORD len;
+ FX_LPCSTR buf;
+ int num_text;
+ png_textp text = NULL;
+ png_get_text(png_ptr, info_ptr, &text, &num_text);
+ for (i = 0; i < num_text; i++) {
+ len = (FX_DWORD)FXSYS_strlen(text[i].key);
+ buf = "Time";
+ if (!FXSYS_memcmp32(buf, text[i].key, FX_MIN(len, FXSYS_strlen(buf)))) {
+ if (!bTime) {
+ FXSYS_memset32(pAttribute->m_strTime, 0, 20);
+ FXSYS_memcpy32(pAttribute->m_strTime, text[i].text, text[i].text_length);
+ }
+ } else {
+ buf = "Author";
+ if (!FXSYS_memcmp32(buf, text[i].key, FX_MIN(len, FXSYS_strlen(buf)))) {
+ pAttribute->m_strAuthor.Empty();
+ pAttribute->m_strAuthor.Load((FX_LPBYTE)text[i].text, (FX_STRSIZE)text[i].text_length);
+ }
+ }
+ }
+#endif
+ }
+}
+struct FXPNG_Context {
+ png_structp png_ptr;
+ png_infop info_ptr;
+ void* parent_ptr;
+ void* child_ptr;
+
+ void* (*m_AllocFunc)(unsigned int);
+ void (*m_FreeFunc)(void*);
+};
+extern "C" {
+ static void* _png_alloc_func(unsigned int size)
+ {
+ return FX_Alloc(char, size);
+ }
+ static void _png_free_func(void* p)
+ {
+ if(p != NULL) {
+ FX_Free(p);
+ }
+ }
+};
+static void _png_get_header_func(png_structp png_ptr, png_infop info_ptr)
+{
+ FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr);
+ if(p == NULL) {
+ return;
+ }
+ CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr;
+ if(pModule == NULL) {
+ return;
+ }
+ png_uint_32 width = 0, height = 0;
+ int bpc = 0, color_type = 0 , color_type1 = 0, pass = 0;
+ double gamma = 1.0;
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bpc, &color_type, NULL, NULL, NULL);
+ color_type1 = color_type;
+ if(bpc > 8) {
+ png_set_strip_16(png_ptr);
+ } else if(bpc < 8) {
+ png_set_expand_gray_1_2_4_to_8(png_ptr);
+ }
+ bpc = 8;
+ if(color_type == PNG_COLOR_TYPE_PALETTE) {
+ png_set_palette_to_rgb(png_ptr);
+ }
+ pass = png_set_interlace_handling(png_ptr);
+ if(!pModule->ReadHeaderCallback(p->child_ptr, width, height, bpc, pass, &color_type, &gamma)) {
+ png_error(p->png_ptr, "Read Header Callback Error");
+ }
+ int intent;
+ if (png_get_sRGB(png_ptr, info_ptr, &intent)) {
+ png_set_gamma(png_ptr, gamma, 0.45455);
+ } else {
+ double image_gamma;
+ if(png_get_gAMA(png_ptr, info_ptr, &image_gamma)) {
+ png_set_gamma(png_ptr, gamma, image_gamma);
+ } else {
+ png_set_gamma(png_ptr, gamma, 0.45455);
+ }
+ }
+ switch(color_type) {
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_GRAY_ALPHA: {
+ if(color_type1 & PNG_COLOR_MASK_COLOR) {
+ png_set_rgb_to_gray(png_ptr, 1, 0.299, 0.587);
+ }
+ }
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ if(color_type1 != PNG_COLOR_TYPE_PALETTE) {
+ png_error(p->png_ptr, "Not Support Output Palette Now");
+ }
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ if(!(color_type1 & PNG_COLOR_MASK_COLOR)) {
+ png_set_gray_to_rgb(png_ptr);
+ }
+ png_set_bgr(png_ptr);
+ break;
+ }
+ if(!(color_type & PNG_COLOR_MASK_ALPHA)) {
+ png_set_strip_alpha(png_ptr);
+ }
+ if(color_type & PNG_COLOR_MASK_ALPHA && !(color_type1 & PNG_COLOR_MASK_ALPHA)) {
+ png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+ }
+ png_read_update_info(png_ptr, info_ptr);
+}
+static void _png_get_end_func(png_structp png_ptr, png_infop info_ptr) {}
+static void _png_get_row_func(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num, int pass)
+{
+ FXPNG_Context* p = (FXPNG_Context*)png_get_progressive_ptr(png_ptr);
+ if(p == NULL) {
+ return;
+ }
+ CCodec_PngModule* pModule = (CCodec_PngModule*)p->parent_ptr;
+ FX_LPBYTE src_buf = NULL;
+ if(!pModule->AskScanlineBufCallback(p->child_ptr, row_num, src_buf)) {
+ png_error(png_ptr, "Ask Scanline buffer Callback Error");
+ }
+ if(src_buf != NULL) {
+ png_progressive_combine_row(png_ptr, src_buf, new_row);
+ }
+ pModule->FillScanlineBufCompletedCallback(p->child_ptr, pass, row_num);
+}
+void* CCodec_PngModule::Start(void* pModule)
+{
+ FXPNG_Context* p = (FXPNG_Context*)FX_Alloc(FX_BYTE, sizeof(FXPNG_Context));
+ if(p == NULL) {
+ return NULL;
+ }
+ p->m_AllocFunc = _png_alloc_func;
+ p->m_FreeFunc = _png_free_func;
+ p->png_ptr = NULL;
+ p->info_ptr = NULL;
+ p->parent_ptr = (void*)this;
+ p->child_ptr = pModule;
+ p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (p->png_ptr == NULL) {
+ FX_Free(p);
+ return NULL;
+ }
+ p->info_ptr = png_create_info_struct(p->png_ptr);
+ if (p->info_ptr == NULL) {
+ png_destroy_read_struct(&(p->png_ptr), (png_infopp)NULL, (png_infopp)NULL);
+ FX_Free(p);
+ return NULL;
+ }
+ if (setjmp(png_jmpbuf(p->png_ptr))) {
+ if(p != NULL) {
+ png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL);
+ FX_Free(p);
+ }
+ return NULL;
+ }
+ png_set_progressive_read_fn(p->png_ptr, p,
+ _png_get_header_func,
+ _png_get_row_func,
+ _png_get_end_func);
+ png_set_error_fn(p->png_ptr, m_szLastError, (png_error_ptr)_png_error_data, (png_error_ptr)_png_warning_data);
+ return p;
+}
+void CCodec_PngModule::Finish(void* pContext)
+{
+ FXPNG_Context* p = (FXPNG_Context*)pContext;
+ if(p != NULL) {
+ png_destroy_read_struct(&(p->png_ptr), &(p->info_ptr), (png_infopp)NULL);
+ p->m_FreeFunc(p);
+ }
+}
+FX_BOOL CCodec_PngModule::Input(void* pContext, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_DIBAttribute* pAttribute)
+{
+ FXPNG_Context* p = (FXPNG_Context*)pContext;
+ if(setjmp(png_jmpbuf(p->png_ptr))) {
+ if (pAttribute && 0 == FXSYS_strcmp(m_szLastError, "Read Header Callback Error")) {
+ _png_load_bmp_attribute(p->png_ptr, p->info_ptr, pAttribute);
+ }
+ return FALSE;
+ }
+ png_process_data(p->png_ptr, p->info_ptr, (FX_LPBYTE)src_buf, src_size);
+ return TRUE;
+}
diff --git a/core/src/fxcodec/codec/fx_codec_progress.cpp b/core/src/fxcodec/codec/fx_codec_progress.cpp
new file mode 100644
index 0000000000..542ac681e6
--- /dev/null
+++ b/core/src/fxcodec/codec/fx_codec_progress.cpp
@@ -0,0 +1,2263 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxge/fx_dib.h"
+#include "../../../include/fxcodec/fx_codec.h"
+#include "fx_codec_progress.h"
+void CFXCODEC_WeightTable::Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, FX_BOOL bInterpol)
+{
+ if (m_pWeightTables) {
+ FX_Free(m_pWeightTables);
+ }
+ double scale, base;
+ scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len));
+ if (dest_len < 0) {
+ base = (FX_FLOAT)(src_len);
+ } else {
+ base = 0.0f;
+ }
+ m_ItemSize = (int)(sizeof(int) * 2 + sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + 1));
+ m_DestMin = dest_min;
+ m_pWeightTables = FX_Alloc(FX_BYTE, (dest_max - dest_min) * m_ItemSize + 4);
+ if(m_pWeightTables == NULL) {
+ return;
+ }
+ if (FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {
+ for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
+ PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
+ double src_pos = dest_pixel * scale + scale / 2 + base;
+ if (bInterpol) {
+ pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
+ pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
+ if (pixel_weights.m_SrcStart < src_min) {
+ pixel_weights.m_SrcStart = src_min;
+ }
+ if (pixel_weights.m_SrcEnd >= src_max) {
+ pixel_weights.m_SrcEnd = src_max - 1;
+ }
+ if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
+ pixel_weights.m_Weights[0] = 65536;
+ } else {
+ pixel_weights.m_Weights[1] = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536);
+ pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
+ }
+ } else {
+ pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos);
+ pixel_weights.m_Weights[0] = 65536;
+ }
+ }
+ return;
+ }
+ for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
+ PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
+ double src_start = dest_pixel * scale + base;
+ double src_end = src_start + scale;
+ int start_i, end_i;
+ if (src_start < src_end) {
+ start_i = (int)FXSYS_floor((FX_FLOAT)src_start);
+ end_i = (int)FXSYS_ceil((FX_FLOAT)src_end);
+ } else {
+ start_i = (int)FXSYS_floor((FX_FLOAT)src_end);
+ end_i = (int)FXSYS_ceil((FX_FLOAT)src_start);
+ }
+ if (start_i < src_min) {
+ start_i = src_min;
+ }
+ if (end_i >= src_max) {
+ end_i = src_max - 1;
+ }
+ if (start_i > end_i) {
+ pixel_weights.m_SrcStart = start_i;
+ pixel_weights.m_SrcEnd = start_i;
+ continue;
+ }
+ pixel_weights.m_SrcStart = start_i;
+ pixel_weights.m_SrcEnd = end_i;
+ for (int j = start_i; j <= end_i; j ++) {
+ double dest_start = FXSYS_Div((FX_FLOAT)(j) - base, scale);
+ double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale);
+ if (dest_start > dest_end) {
+ double temp = dest_start;
+ dest_start = dest_end;
+ dest_end = temp;
+ }
+ double area_start = dest_start > (FX_FLOAT)(dest_pixel) ? dest_start : (FX_FLOAT)(dest_pixel);
+ double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) ? (FX_FLOAT)(dest_pixel + 1) : dest_end;
+ double weight = area_start >= area_end ? 0.0f : area_end - area_start;
+ if (weight == 0 && j == end_i) {
+ pixel_weights.m_SrcEnd --;
+ break;
+ }
+ pixel_weights.m_Weights[j - start_i] = FXSYS_round((FX_FLOAT)(weight * 65536));
+ }
+ }
+}
+void CFXCODEC_HorzTable::Calc(int dest_len, int src_len, FX_BOOL bInterpol)
+{
+ if (m_pWeightTables) {
+ FX_Free(m_pWeightTables);
+ }
+ double scale = (double)dest_len / (double)src_len;
+ m_ItemSize = sizeof(int) * 4;
+ int size = dest_len * m_ItemSize + 4;
+ m_pWeightTables = FX_Alloc(FX_BYTE, size);
+ if(m_pWeightTables == NULL) {
+ return;
+ }
+ FXSYS_memset32(m_pWeightTables, 0, size);
+ if(scale > 1) {
+ int pre_des_col = 0;
+ for (int src_col = 0; src_col < src_len; src_col++) {
+ double des_col_f = src_col * scale;
+ int des_col = FXSYS_round((FX_FLOAT)des_col_f);
+ PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize);
+ pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
+ pWeight->m_Weights[0] = 65536;
+ pWeight->m_Weights[1] = 0;
+ if(src_col == src_len - 1 && des_col < dest_len - 1) {
+ for (int des_col_index = pre_des_col + 1; des_col_index < dest_len; des_col_index++) {
+ pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize);
+ pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
+ pWeight->m_Weights[0] = 65536;
+ pWeight->m_Weights[1] = 0;
+ }
+ return;
+ }
+ int des_col_len = des_col - pre_des_col;
+ for (int des_col_index = pre_des_col + 1; des_col_index < des_col; des_col_index++) {
+ pWeight = (PixelWeight*)(m_pWeightTables + des_col_index * m_ItemSize);
+ pWeight->m_SrcStart = src_col - 1;
+ pWeight->m_SrcEnd = src_col;
+ pWeight->m_Weights[0] = bInterpol ? FXSYS_round((FX_FLOAT)
+ (
+ ((FX_FLOAT)des_col - (FX_FLOAT)des_col_index)
+ / (FX_FLOAT)des_col_len * 65536
+ )
+ ) : 65536;
+ pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
+ }
+ pre_des_col = des_col;
+ }
+ return;
+ }
+ for (int des_col = 0; des_col < dest_len; des_col++) {
+ double src_col_f = des_col / scale;
+ int src_col = FXSYS_round((FX_FLOAT)src_col_f);
+ PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_col * m_ItemSize);
+ pWeight->m_SrcStart = pWeight->m_SrcEnd = src_col;
+ pWeight->m_Weights[0] = 65536;
+ pWeight->m_Weights[1] = 0;
+ }
+}
+void CFXCODEC_VertTable::Calc(int dest_len, int src_len)
+{
+ if (m_pWeightTables) {
+ FX_Free(m_pWeightTables);
+ }
+ double scale = (double)dest_len / (double)src_len;
+ m_ItemSize = sizeof(int) * 4;
+ int size = dest_len * m_ItemSize + 4;
+ m_pWeightTables = FX_Alloc(FX_BYTE, size);
+ if(m_pWeightTables == NULL) {
+ return;
+ }
+ FXSYS_memset32(m_pWeightTables, 0, size);
+ if(scale > 1) {
+ double step = 0.0;
+ int src_row = 0;
+ while ( step < (double)dest_len ) {
+ int start_step = (int)step;
+ step = scale * (++src_row);
+ int end_step = (int)step;
+ if(end_step >= dest_len) {
+ end_step = dest_len;
+ for (int des_row = start_step; des_row < end_step; des_row++) {
+ PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);
+ pWeight->m_SrcStart = start_step;
+ pWeight->m_SrcEnd = start_step;
+ pWeight->m_Weights[0] = 65536;
+ pWeight->m_Weights[1] = 0;
+ }
+ return;
+ }
+ int length = end_step - start_step;
+ {
+ PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + start_step * m_ItemSize);
+ pWeight->m_SrcStart = start_step;
+ pWeight->m_SrcEnd = start_step;
+ pWeight->m_Weights[0] = 65536;
+ pWeight->m_Weights[1] = 0;
+ }
+ for (int des_row = start_step + 1; des_row < end_step; des_row++) {
+ PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);
+ pWeight->m_SrcStart = start_step;
+ pWeight->m_SrcEnd = end_step;
+ pWeight->m_Weights[0] = FXSYS_round((FX_FLOAT)(end_step - des_row) / (FX_FLOAT)length * 65536);
+ pWeight->m_Weights[1] = 65536 - pWeight->m_Weights[0];
+ }
+ }
+ } else {
+ for (int des_row = 0; des_row < dest_len; des_row++) {
+ PixelWeight* pWeight = (PixelWeight*)(m_pWeightTables + des_row * m_ItemSize);
+ pWeight->m_SrcStart = des_row;
+ pWeight->m_SrcEnd = des_row;
+ pWeight->m_Weights[0] = 65536;
+ pWeight->m_Weights[1] = 0;
+ }
+ }
+}
+CCodec_ProgressiveDecoder::CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr)
+{
+ m_pFile = NULL;
+ m_pJpegContext = NULL;
+ m_pPngContext = NULL;
+ m_pGifContext = NULL;
+ m_pBmpContext = NULL;
+ m_pTiffContext = NULL;
+ m_pCodecMgr = NULL;
+ m_pSrcBuf = NULL;
+ m_pDecodeBuf = NULL;
+ m_pDeviceBitmap = NULL;
+ m_pSrcPalette = NULL;
+ m_pCodecMgr = pCodecMgr;
+ m_offSet = 0;
+ m_SrcSize = 0;
+ m_ScanlineSize = 0;
+ m_SrcWidth = m_SrcHeight = 0;
+ m_SrcComponents = 0;
+ m_SrcBPC = 0;
+ m_SrcPassNumber = 0;
+ m_clipBox = FX_RECT(0, 0, 0, 0);
+ m_imagType = FXCODEC_IMAGE_UNKNOWN;
+ m_status = FXCODEC_STATUS_DECODE_FINISH;
+ m_TransMethod = -1;
+ m_SrcRow = 0;
+ m_SrcFormat = FXCodec_Invalid;
+ m_bInterpol = TRUE;
+ m_FrameNumber = 0;
+ m_FrameCur = 0;
+ m_SrcPaletteNumber = 0;
+ m_GifPltNumber = 0;
+ m_GifBgIndex = 0;
+ m_pGifPalette = NULL;
+ m_GifTransIndex = -1;
+ m_GifFrameRect = FX_RECT(0, 0, 0, 0);
+ m_BmpIsTopBottom = FALSE;
+}
+CCodec_ProgressiveDecoder::~CCodec_ProgressiveDecoder()
+{
+ m_pFile = NULL;
+ if(m_pJpegContext != NULL) {
+ m_pCodecMgr->GetJpegModule()->Finish(m_pJpegContext);
+ }
+ if(m_pPngContext != NULL) {
+ m_pCodecMgr->GetPngModule()->Finish(m_pPngContext);
+ }
+ if(m_pGifContext != NULL) {
+ m_pCodecMgr->GetGifModule()->Finish(m_pGifContext);
+ }
+ if(m_pBmpContext != NULL) {
+ m_pCodecMgr->GetBmpModule()->Finish(m_pBmpContext);
+ }
+ if(m_pTiffContext != NULL) {
+ m_pCodecMgr->GetTiffModule()->DestroyDecoder(m_pTiffContext);
+ }
+ if(m_pSrcBuf != NULL) {
+ FX_Free(m_pSrcBuf);
+ }
+ if(m_pDecodeBuf != NULL) {
+ FX_Free(m_pDecodeBuf);
+ }
+ if(m_pSrcPalette != NULL) {
+ FX_Free(m_pSrcPalette);
+ }
+}
+FX_BOOL CCodec_ProgressiveDecoder::JpegReadMoreData(ICodec_JpegModule* pJpegModule, FXCODEC_STATUS& err_status)
+{
+ FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize();
+ if (dwSize <= m_offSet) {
+ return FALSE;
+ }
+ dwSize = dwSize - m_offSet;
+ FX_DWORD dwAvail = pJpegModule->GetAvailInput(m_pJpegContext, NULL);
+ if (dwAvail == m_SrcSize) {
+ if (dwSize > FXCODEC_BLOCK_SIZE) {
+ dwSize = FXCODEC_BLOCK_SIZE;
+ }
+ m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;
+ m_pSrcBuf = FX_Realloc(FX_BYTE, m_pSrcBuf, m_SrcSize);
+ if (!m_pSrcBuf) {
+ err_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ } else {
+ FX_DWORD dwConsume = m_SrcSize - dwAvail;
+ if (dwAvail) {
+ FXSYS_memcpy32(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);
+ }
+ if (dwSize > dwConsume) {
+ dwSize = dwConsume;
+ }
+ }
+ if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {
+ err_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += dwSize;
+ pJpegModule->Input(m_pJpegContext, m_pSrcBuf, dwSize + dwAvail);
+ return TRUE;
+}
+FX_BOOL CCodec_ProgressiveDecoder::PngReadHeaderFunc(void* pModule, int width, int height, int bpc, int pass, int* color_type, double* gamma)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ if(pCodec->m_pDeviceBitmap == NULL) {
+ pCodec->m_SrcWidth = width;
+ pCodec->m_SrcHeight = height;
+ pCodec->m_SrcBPC = bpc;
+ pCodec->m_SrcPassNumber = pass;
+ pCodec->m_SrcComponents = *color_type == 0 ? 1 :
+ *color_type == 2 ? 3 :
+ *color_type == 3 ? 4 :
+ *color_type == 4 ? 2 :
+ *color_type == 6 ? 4 : 0;
+ pCodec->m_clipBox = FX_RECT(0, 0, width, height);
+ return FALSE;
+ }
+ FXDIB_Format format = pCodec->m_pDeviceBitmap->GetFormat();
+ switch(format) {
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ ASSERT(FALSE);
+ return FALSE;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb:
+ *color_type = 0;
+ break;
+ case FXDIB_Rgb:
+ *color_type = 2;
+ break;
+ case FXDIB_Rgb32:
+ case FXDIB_Argb:
+ *color_type = 6;
+ break;
+ default:
+ ASSERT(FALSE);
+ return FALSE;
+ }
+ *gamma = FXCODEC_PNG_GAMMA;
+ return TRUE;
+}
+FX_BOOL CCodec_ProgressiveDecoder::PngAskScanlineBufFunc(void* pModule, int line, FX_LPBYTE& src_buf)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;
+ ASSERT(pDIBitmap != NULL);
+ if(pDIBitmap == NULL) {
+ return FALSE;
+ }
+ if(line >= pCodec->m_clipBox.top && line < pCodec->m_clipBox.bottom) {
+ double scale_y = (double)pCodec->m_sizeY / (double)pCodec->m_clipBox.Height();
+ FX_INT32 row = (FX_INT32)((line - pCodec->m_clipBox.top) * scale_y) + pCodec->m_startY;
+ FX_LPBYTE src_scan = (FX_LPBYTE)pDIBitmap->GetScanline(row);
+ FX_LPBYTE des_scan = pCodec->m_pDecodeBuf;
+ src_buf = pCodec->m_pDecodeBuf;
+ FX_INT32 src_Bpp = pDIBitmap->GetBPP() >> 3;
+ FX_INT32 des_Bpp = (pCodec->m_SrcFormat & 0xff) >> 3;
+ FX_INT32 src_left = pCodec->m_startX;
+ FX_INT32 des_left = pCodec->m_clipBox.left;
+ src_scan += src_left * src_Bpp;
+ des_scan += des_left * des_Bpp;
+ for (FX_INT32 src_col = 0; src_col < pCodec->m_sizeX; src_col++) {
+ PixelWeight* pPixelWeights = pCodec->m_WeightHorzOO.GetPixelWeight(src_col);
+ if(pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) {
+ continue;
+ }
+ switch(pDIBitmap->GetFormat()) {
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ ASSERT(FALSE);
+ return FALSE;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ if(pDIBitmap->GetPalette() != NULL) {
+ return FALSE;
+ }
+ FX_DWORD des_g = 0;
+ des_g += pPixelWeights->m_Weights[0] * src_scan[src_col];
+ des_scan[pPixelWeights->m_SrcStart] = (FX_BYTE)(des_g >> 16);
+ }
+ break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ FX_LPCBYTE p = src_scan + src_col * src_Bpp;
+ des_b += pPixelWeights->m_Weights[0] * (*p++);
+ des_g += pPixelWeights->m_Weights[0] * (*p++);
+ des_r += pPixelWeights->m_Weights[0] * (*p);
+ FX_LPBYTE pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp];
+ *pDes++ = (FX_BYTE)((des_b) >> 16);
+ *pDes++ = (FX_BYTE)((des_g) >> 16);
+ *pDes = (FX_BYTE)((des_r) >> 16);
+ }
+ break;
+ case FXDIB_Argb: {
+ FX_DWORD des_r = 0, des_g = 0, des_b = 0;
+ FX_LPCBYTE p = src_scan + src_col * src_Bpp;
+ des_b += pPixelWeights->m_Weights[0] * (*p++);
+ des_g += pPixelWeights->m_Weights[0] * (*p++);
+ des_r += pPixelWeights->m_Weights[0] * (*p++);
+ FX_LPBYTE pDes = &des_scan[pPixelWeights->m_SrcStart * des_Bpp];
+ *pDes++ = (FX_BYTE)((des_b) >> 16);
+ *pDes++ = (FX_BYTE)((des_g) >> 16);
+ *pDes++ = (FX_BYTE)((des_r) >> 16);
+ *pDes = *p;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+void CCodec_ProgressiveDecoder::PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, FX_INT32 des_line, FX_LPBYTE src_scan, FXCodec_Format src_format)
+{
+ FX_LPBYTE des_scan = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_line);
+ FX_INT32 src_Bpp = (m_SrcFormat & 0xff) >> 3;
+ FX_INT32 des_Bpp = pDeviceBitmap->GetBPP() >> 3;
+ FX_INT32 src_left = m_clipBox.left;
+ FX_INT32 des_left = m_startX;
+ src_scan += src_left * src_Bpp;
+ des_scan += des_left * des_Bpp;
+ for (FX_INT32 des_col = 0; des_col < m_sizeX; des_col++) {
+ PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(des_col);
+ switch(pDeviceBitmap->GetFormat()) {
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ ASSERT(FALSE);
+ return;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ if(pDeviceBitmap->GetPalette() != NULL) {
+ return;
+ }
+ FX_DWORD des_g = 0;
+ des_g += pPixelWeights->m_Weights[0] * src_scan[pPixelWeights->m_SrcStart];
+ des_g += pPixelWeights->m_Weights[1] * src_scan[pPixelWeights->m_SrcEnd];
+ *des_scan++ = (FX_BYTE)(des_g >> 16);
+ }
+ break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ FX_LPCBYTE p = src_scan;
+ p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
+ des_b += pPixelWeights->m_Weights[0] * (*p++);
+ des_g += pPixelWeights->m_Weights[0] * (*p++);
+ des_r += pPixelWeights->m_Weights[0] * (*p);
+ p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
+ des_b += pPixelWeights->m_Weights[1] * (*p++);
+ des_g += pPixelWeights->m_Weights[1] * (*p++);
+ des_r += pPixelWeights->m_Weights[1] * (*p);
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ des_scan += des_Bpp - 3;
+ }
+ break;
+ case FXDIB_Argb: {
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;
+ FX_LPCBYTE p = src_scan;
+ p = src_scan + pPixelWeights->m_SrcStart * src_Bpp;
+ des_b += pPixelWeights->m_Weights[0] * (*p++);
+ des_g += pPixelWeights->m_Weights[0] * (*p++);
+ des_r += pPixelWeights->m_Weights[0] * (*p++);
+ des_a += pPixelWeights->m_Weights[0] * (*p);
+ p = src_scan + pPixelWeights->m_SrcEnd * src_Bpp;
+ des_b += pPixelWeights->m_Weights[1] * (*p++);
+ des_g += pPixelWeights->m_Weights[1] * (*p++);
+ des_r += pPixelWeights->m_Weights[1] * (*p++);
+ des_a += pPixelWeights->m_Weights[1] * (*p);
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ *des_scan++ = (FX_BYTE)((des_a) >> 16);
+ }
+ break;
+ default:
+ return;
+ }
+ }
+}
+void CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc(void* pModule, int pass, int line)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;
+ ASSERT(pDIBitmap != NULL);
+ int src_top = pCodec->m_clipBox.top;
+ int src_bottom = pCodec->m_clipBox.bottom;
+ int des_top = pCodec->m_startY;
+ int src_hei = pCodec->m_clipBox.Height();
+ int des_hei = pCodec->m_sizeY;
+ if(line >= src_top && line < src_bottom) {
+ double scale_y = (double)des_hei / (double)src_hei;
+ int src_row = line - src_top;
+ int des_row = (int)(src_row * scale_y) + des_top;
+ if(des_row >= des_top + des_hei) {
+ return;
+ }
+ pCodec->PngOneOneMapResampleHorz(pDIBitmap, des_row, pCodec->m_pDecodeBuf, pCodec->m_SrcFormat);
+ if(pCodec->m_SrcPassNumber == 1 && scale_y > 1.0) {
+ pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
+ return;
+ }
+ if(pass == 6 && scale_y > 1.0) {
+ pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
+ }
+ }
+}
+FX_BOOL CCodec_ProgressiveDecoder::GifReadMoreData(ICodec_GifModule* pGifModule, FXCODEC_STATUS& err_status)
+{
+ FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize();
+ if (dwSize <= m_offSet) {
+ return FALSE;
+ }
+ dwSize = dwSize - m_offSet;
+ FX_DWORD dwAvail = pGifModule->GetAvailInput(m_pGifContext, NULL);
+ if (dwAvail == m_SrcSize) {
+ if (dwSize > FXCODEC_BLOCK_SIZE) {
+ dwSize = FXCODEC_BLOCK_SIZE;
+ }
+ m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;
+ m_pSrcBuf = FX_Realloc(FX_BYTE, m_pSrcBuf, m_SrcSize);
+ if (!m_pSrcBuf) {
+ err_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ } else {
+ FX_DWORD dwConsume = m_SrcSize - dwAvail;
+ if (dwAvail) {
+ FXSYS_memcpy32(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);
+ }
+ if (dwSize > dwConsume) {
+ dwSize = dwConsume;
+ }
+ }
+ if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {
+ err_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += dwSize;
+ pGifModule->Input(m_pGifContext, m_pSrcBuf, dwSize + dwAvail);
+ return TRUE;
+}
+void CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback(void* pModule, FX_DWORD& cur_pos)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ FX_DWORD remain_size = pCodec->m_pCodecMgr->GetGifModule()->GetAvailInput(pCodec->m_pGifContext);
+ cur_pos = pCodec->m_offSet - remain_size;
+}
+FX_LPBYTE CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback(void* pModule, FX_INT32 frame_num, FX_INT32 pal_size)
+{
+ return FX_Alloc(FX_BYTE, pal_size);
+}
+FX_BOOL CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback(void* pModule, FX_DWORD rcd_pos, const FX_RECT& img_rc,
+ FX_INT32 pal_num, void* pal_ptr,
+ FX_INT32 delay_time, FX_BOOL user_input,
+ FX_INT32 trans_index, FX_INT32 disposal_method, FX_BOOL interlace)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ pCodec->m_offSet = rcd_pos;
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
+ if(!pCodec->GifReadMoreData(pCodec->m_pCodecMgr->GetGifModule(), error_status)) {
+ return FALSE;
+ }
+ FX_LPBYTE pPalette = NULL;
+ if(pal_num != 0 && pal_ptr) {
+ pPalette = (FX_LPBYTE)pal_ptr;
+ } else {
+ pal_num = pCodec->m_GifPltNumber;
+ pPalette = pCodec->m_pGifPalette;
+ }
+ if(pCodec->m_pSrcPalette == NULL) {
+ pCodec->m_pSrcPalette = FX_Alloc(FX_ARGB, pal_num);
+ } else if(pal_num > pCodec->m_SrcPaletteNumber) {
+ pCodec->m_pSrcPalette = FX_Realloc(FX_ARGB, pCodec->m_pSrcPalette, pal_num);
+ }
+ if(pCodec->m_pSrcPalette == NULL) {
+ return FALSE;
+ }
+ pCodec->m_SrcPaletteNumber = pal_num;
+ for (int i = 0; i < pal_num; i++) {
+ register FX_DWORD j = i * 3;
+ pCodec->m_pSrcPalette[i] =
+ ArgbEncode(0xff, pPalette[j], pPalette[j + 1], pPalette[j + 2]);
+ }
+ pCodec->m_GifTransIndex = trans_index;
+ pCodec->m_GifFrameRect = img_rc;
+ pCodec->m_SrcPassNumber = interlace ? 4 : 1;
+ FX_INT32 pal_index = pCodec->m_GifBgIndex;
+ CFX_DIBitmap* pDevice = pCodec->m_pDeviceBitmap;
+ if (trans_index >= pal_num) {
+ trans_index = -1;
+ }
+ if (trans_index != -1) {
+ pCodec->m_pSrcPalette[trans_index] &= 0x00ffffff;
+ if (pDevice->HasAlpha()) {
+ pal_index = trans_index;
+ }
+ }
+ int startX = pCodec->m_startX;
+ int startY = pCodec->m_startY;
+ int sizeX = pCodec->m_sizeX;
+ int sizeY = pCodec->m_sizeY;
+ int Bpp = pDevice->GetBPP() / 8;
+ FX_ARGB argb = pCodec->m_pSrcPalette[pal_index];
+ for (int row = 0; row < sizeY; row ++) {
+ FX_LPBYTE pScanline = (FX_LPBYTE)pDevice->GetScanline(row + startY) + startX * Bpp;
+ switch(pCodec->m_TransMethod) {
+ case 3: {
+ FX_BYTE gray = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
+ FXSYS_memset8(pScanline, gray, sizeX);
+ break;
+ }
+ case 8: {
+ for (int col = 0; col < sizeX; col ++) {
+ *pScanline++ = FXARGB_B(argb);
+ *pScanline++ = FXARGB_G(argb);
+ *pScanline++ = FXARGB_R(argb);
+ pScanline += Bpp - 3;
+ }
+ break;
+ }
+ case 12: {
+ for (int col = 0; col < sizeX; col ++) {
+ FXARGB_SETDIB(pScanline, argb);
+ pScanline += 4;
+ }
+ break;
+ }
+ }
+ }
+ return TRUE;
+}
+void CCodec_ProgressiveDecoder::GifReadScanlineCallback(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;
+ ASSERT(pDIBitmap != NULL);
+ FX_INT32 img_width = pCodec->m_GifFrameRect.Width();
+ if (!pDIBitmap->HasAlpha()) {
+ FX_LPBYTE byte_ptr = row_buf;
+ for (int i = 0; i < img_width; i++ ) {
+ if(*byte_ptr == pCodec->m_GifTransIndex) {
+ *byte_ptr = pCodec->m_GifBgIndex;
+ }
+ byte_ptr++;
+ }
+ }
+ FX_INT32 pal_index = pCodec->m_GifBgIndex;
+ if (pCodec->m_GifTransIndex != -1 && pCodec->m_pDeviceBitmap->HasAlpha()) {
+ pal_index = pCodec->m_GifTransIndex;
+ }
+ FXSYS_memset8(pCodec->m_pDecodeBuf, pal_index, pCodec->m_SrcWidth);
+ FX_BOOL bLastPass = ((row_num % 2) == 1) ? TRUE : FALSE;
+ FX_INT32 line = row_num + pCodec->m_GifFrameRect.top;
+ FX_INT32 left = pCodec->m_GifFrameRect.left;
+ FXSYS_memcpy32(pCodec->m_pDecodeBuf + left, row_buf, img_width);
+ int src_top = pCodec->m_clipBox.top;
+ int src_bottom = pCodec->m_clipBox.bottom;
+ int des_top = pCodec->m_startY;
+ int src_hei = pCodec->m_clipBox.Height();
+ int des_hei = pCodec->m_sizeY;
+ if(line >= src_top && line < src_bottom) {
+ double scale_y = (double)des_hei / (double)src_hei;
+ int src_row = line - src_top;
+ int des_row = (int)(src_row * scale_y) + des_top;
+ if(des_row >= des_top + des_hei) {
+ return;
+ }
+ pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, pCodec->m_SrcFormat);
+ if(scale_y > 1.0 && (!pCodec->m_bInterpol || pCodec->m_SrcPassNumber == 1)) {
+ pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
+ return;
+ }
+ if(scale_y > 1.0) {
+ int des_bottom = des_top + pCodec->m_sizeY;
+ int des_Bpp = pDIBitmap->GetBPP() >> 3;
+ FX_DWORD des_ScanOffet = pCodec->m_startX * des_Bpp;
+ if(des_row + (int)scale_y >= des_bottom - 1) {
+ FX_LPBYTE scan_src = (FX_LPBYTE)pDIBitmap->GetScanline(des_row) + des_ScanOffet;
+ int cur_row = des_row;
+ while (++cur_row < des_bottom) {
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDIBitmap->GetScanline(cur_row) + des_ScanOffet;
+ FX_DWORD size = pCodec->m_sizeX * des_Bpp;
+ FXSYS_memcpy32(scan_des, scan_src, size);
+ }
+ }
+ if(bLastPass) {
+ pCodec->GifDoubleLineResampleVert(pDIBitmap, scale_y, des_row);
+ }
+ }
+ }
+}
+void CCodec_ProgressiveDecoder::GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row)
+{
+ int des_Bpp = pDeviceBitmap->GetBPP() >> 3;
+ FX_DWORD des_ScanOffet = m_startX * des_Bpp;
+ int des_top = m_startY;
+ int des_row_1 = des_row - int(2 * scale_y);
+ if(des_row_1 < des_top) {
+ des_row_1 = des_top;
+ }
+ for (; des_row_1 < des_row; des_row_1++) {
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;
+ PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);
+ FX_LPCBYTE scan_src1 = pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + des_ScanOffet;
+ FX_LPCBYTE scan_src2 = pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;
+ for (int des_col = 0; des_col < m_sizeX; des_col++) {
+ switch(pDeviceBitmap->GetFormat()) {
+ case FXDIB_Invalid:
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ return;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ if(pDeviceBitmap->GetPalette() != NULL) {
+ return;
+ }
+ int des_g = 0;
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (FX_BYTE)(des_g >> 16);
+ }
+ break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ des_b += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_r += pWeight->m_Weights[0] * (*scan_src1++);
+ scan_src1 += des_Bpp - 3;
+ des_b += pWeight->m_Weights[1] * (*scan_src2++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ des_r += pWeight->m_Weights[1] * (*scan_src2++);
+ scan_src2 += des_Bpp - 3;
+ *scan_des++ = (FX_BYTE)((des_b) >> 16);
+ *scan_des++ = (FX_BYTE)((des_g) >> 16);
+ *scan_des++ = (FX_BYTE)((des_r) >> 16);
+ scan_des += des_Bpp - 3;
+ }
+ break;
+ case FXDIB_Argb: {
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;
+ des_b += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_r += pWeight->m_Weights[0] * (*scan_src1++);
+ des_a += pWeight->m_Weights[0] * (*scan_src1++);
+ des_b += pWeight->m_Weights[1] * (*scan_src2++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ des_r += pWeight->m_Weights[1] * (*scan_src2++);
+ des_a += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (FX_BYTE)((des_b) >> 16);
+ *scan_des++ = (FX_BYTE)((des_g) >> 16);
+ *scan_des++ = (FX_BYTE)((des_r) >> 16);
+ *scan_des++ = (FX_BYTE)((des_a) >> 16);
+ }
+ break;
+ default:
+ return;
+ }
+ }
+ }
+ int des_bottom = des_top + m_sizeY - 1;
+ if(des_row + (int)(2 * scale_y) >= des_bottom && des_row + (int)scale_y < des_bottom) {
+ GifDoubleLineResampleVert(pDeviceBitmap, scale_y, des_row + (int)scale_y);
+ }
+}
+FX_BOOL CCodec_ProgressiveDecoder::BmpReadMoreData(ICodec_BmpModule* pBmpModule, FXCODEC_STATUS& err_status)
+{
+ FX_DWORD dwSize = (FX_DWORD)m_pFile->GetSize();
+ if (dwSize <= m_offSet) {
+ return FALSE;
+ }
+ dwSize = dwSize - m_offSet;
+ FX_DWORD dwAvail = pBmpModule->GetAvailInput(m_pBmpContext, NULL);
+ if (dwAvail == m_SrcSize) {
+ if (dwSize > FXCODEC_BLOCK_SIZE) {
+ dwSize = FXCODEC_BLOCK_SIZE;
+ }
+ m_SrcSize = (dwSize + dwAvail + FXCODEC_BLOCK_SIZE - 1) / FXCODEC_BLOCK_SIZE * FXCODEC_BLOCK_SIZE;
+ m_pSrcBuf = FX_Realloc(FX_BYTE, m_pSrcBuf, m_SrcSize);
+ if (!m_pSrcBuf) {
+ err_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ } else {
+ FX_DWORD dwConsume = m_SrcSize - dwAvail;
+ if (dwAvail) {
+ FXSYS_memcpy32(m_pSrcBuf, m_pSrcBuf + dwConsume, dwAvail);
+ }
+ if (dwSize > dwConsume) {
+ dwSize = dwConsume;
+ }
+ }
+ if (!m_pFile->ReadBlock(m_pSrcBuf + dwAvail, m_offSet, dwSize)) {
+ err_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += dwSize;
+ pBmpModule->Input(m_pBmpContext, m_pSrcBuf, dwSize + dwAvail);
+ return TRUE;
+}
+FX_BOOL CCodec_ProgressiveDecoder::BmpInputImagePositionBufCallback(void* pModule, FX_DWORD rcd_pos)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ pCodec->m_offSet = rcd_pos;
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
+ if(!pCodec->BmpReadMoreData(pCodec->m_pCodecMgr->GetBmpModule(), error_status)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+void CCodec_ProgressiveDecoder::BmpReadScanlineCallback(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf)
+{
+ CCodec_ProgressiveDecoder* pCodec = (CCodec_ProgressiveDecoder*)pModule;
+ CFX_DIBitmap* pDIBitmap = pCodec->m_pDeviceBitmap;
+ ASSERT(pDIBitmap != NULL);
+ FXSYS_memcpy32(pCodec->m_pDecodeBuf, row_buf, pCodec->m_ScanlineSize);
+ int src_top = pCodec->m_clipBox.top;
+ int src_bottom = pCodec->m_clipBox.bottom;
+ int des_top = pCodec->m_startY;
+ int src_hei = pCodec->m_clipBox.Height();
+ int des_hei = pCodec->m_sizeY;
+ if(row_num >= src_top && row_num < src_bottom) {
+ double scale_y = (double)des_hei / (double)src_hei;
+ int src_row = row_num - src_top;
+ int des_row = (int)(src_row * scale_y) + des_top;
+ if(des_row >= des_top + des_hei) {
+ return;
+ }
+ pCodec->ReSampleScanline(pDIBitmap, des_row, pCodec->m_pDecodeBuf, pCodec->m_SrcFormat);
+ if(scale_y > 1.0) {
+ if(pCodec->m_BmpIsTopBottom || !pCodec->m_bInterpol) {
+ pCodec->ResampleVert(pDIBitmap, scale_y, des_row);
+ return;
+ } else {
+ pCodec->ResampleVertBT(pDIBitmap, scale_y, des_row);
+ }
+ }
+ }
+}
+void CCodec_ProgressiveDecoder::ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row)
+{
+ int des_Bpp = pDeviceBitmap->GetBPP() >> 3;
+ FX_DWORD des_ScanOffet = m_startX * des_Bpp;
+ int des_top = m_startY;
+ int des_bottom = m_startY + m_sizeY;
+ int des_row_1 = des_row + int(scale_y);
+ if(des_row_1 >= des_bottom - 1) {
+ FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
+ while (++des_row < des_bottom) {
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
+ FX_DWORD size = m_sizeX * des_Bpp;
+ FXSYS_memcpy32(scan_des, scan_src, size);
+ }
+ return;
+ }
+ for (; des_row_1 > des_row; des_row_1--) {
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;
+ PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);
+ FX_LPCBYTE scan_src1 = pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + des_ScanOffet;
+ FX_LPCBYTE scan_src2 = pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;
+ for (int des_col = 0; des_col < m_sizeX; des_col++) {
+ switch(pDeviceBitmap->GetFormat()) {
+ case FXDIB_Invalid:
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ return;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ if(pDeviceBitmap->GetPalette() != NULL) {
+ return;
+ }
+ int des_g = 0;
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (FX_BYTE)(des_g >> 16);
+ }
+ break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ des_b += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_r += pWeight->m_Weights[0] * (*scan_src1++);
+ scan_src1 += des_Bpp - 3;
+ des_b += pWeight->m_Weights[1] * (*scan_src2++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ des_r += pWeight->m_Weights[1] * (*scan_src2++);
+ scan_src2 += des_Bpp - 3;
+ *scan_des++ = (FX_BYTE)((des_b) >> 16);
+ *scan_des++ = (FX_BYTE)((des_g) >> 16);
+ *scan_des++ = (FX_BYTE)((des_r) >> 16);
+ scan_des += des_Bpp - 3;
+ }
+ break;
+ case FXDIB_Argb: {
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;
+ des_b += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_r += pWeight->m_Weights[0] * (*scan_src1++);
+ des_a += pWeight->m_Weights[0] * (*scan_src1++);
+ des_b += pWeight->m_Weights[1] * (*scan_src2++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ des_r += pWeight->m_Weights[1] * (*scan_src2++);
+ des_a += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (FX_BYTE)((des_b) >> 16);
+ *scan_des++ = (FX_BYTE)((des_g) >> 16);
+ *scan_des++ = (FX_BYTE)((des_r) >> 16);
+ *scan_des++ = (FX_BYTE)((des_a) >> 16);
+ }
+ break;
+ default:
+ return;
+ }
+ }
+ }
+}
+FX_BOOL CCodec_ProgressiveDecoder::DetectImageType(FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute)
+{
+ m_offSet = 0;
+ FX_DWORD size = (FX_DWORD)m_pFile->GetSize();
+ if(size > FXCODEC_BLOCK_SIZE) {
+ size = FXCODEC_BLOCK_SIZE;
+ }
+ if(m_pSrcBuf != NULL) {
+ FX_Free(m_pSrcBuf);
+ m_pSrcBuf = NULL;
+ }
+ m_pSrcBuf = FX_Alloc(FX_BYTE, size);
+ if(m_pSrcBuf == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ FXSYS_memset32(m_pSrcBuf, 0, size);
+ m_SrcSize = size;
+ switch(imageType) {
+ case FXCODEC_IMAGE_BMP: {
+ ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
+ if(pBmpModule == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ pBmpModule->InputImagePositionBufCallback = BmpInputImagePositionBufCallback;
+ pBmpModule->ReadScanlineCallback = BmpReadScanlineCallback;
+ m_pBmpContext = pBmpModule->Start((void*)this);
+ if(m_pBmpContext == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
+ if(!bResult) {
+ m_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += size;
+ pBmpModule->Input(m_pBmpContext, m_pSrcBuf, size);
+ FX_DWORD* pPalette = NULL;
+ FX_INT32 readResult = pBmpModule->ReadHeader(m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,
+ &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute);
+ while(readResult == 2) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
+ if(!BmpReadMoreData(pBmpModule, error_status)) {
+ m_status = error_status;
+ return FALSE;
+ }
+ readResult = pBmpModule->ReadHeader(m_pBmpContext, &m_SrcWidth, &m_SrcHeight, &m_BmpIsTopBottom,
+ &m_SrcComponents, &m_SrcPaletteNumber, &pPalette, pAttribute);
+ }
+ if(readResult == 1) {
+ m_SrcBPC = 8;
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
+ if(m_pSrcPalette != NULL) {
+ FX_Free(m_pSrcPalette);
+ m_pSrcPalette = NULL;
+ }
+ if (m_SrcPaletteNumber) {
+ m_pSrcPalette = FX_Alloc(FX_ARGB, m_SrcPaletteNumber);
+ if(m_pSrcPalette == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ FXSYS_memcpy32(m_pSrcPalette, pPalette, m_SrcPaletteNumber * sizeof(FX_DWORD));
+ }
+ return TRUE;
+ }
+ if(m_pBmpContext != NULL) {
+ pBmpModule->Finish(m_pBmpContext);
+ m_pBmpContext = NULL;
+ }
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ break;
+ case FXCODEC_IMAGE_JPG: {
+ ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
+ if(pJpegModule == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ m_pJpegContext = pJpegModule->Start();
+ if(m_pJpegContext == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
+ if(!bResult) {
+ m_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += size;
+ pJpegModule->Input(m_pJpegContext, m_pSrcBuf, size);
+ FX_INT32 readResult = pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, &m_SrcComponents, pAttribute);
+ while(readResult == 2) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
+ if(!JpegReadMoreData(pJpegModule, error_status)) {
+ m_status = error_status;
+ return FALSE;
+ }
+ readResult = pJpegModule->ReadHeader(m_pJpegContext, &m_SrcWidth, &m_SrcHeight, &m_SrcComponents, pAttribute);
+ }
+ if(!readResult) {
+ m_SrcBPC = 8;
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
+ return TRUE;
+ }
+ if(m_pJpegContext != NULL) {
+ pJpegModule->Finish(m_pJpegContext);
+ m_pJpegContext = NULL;
+ }
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ break;
+ case FXCODEC_IMAGE_PNG: {
+ ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
+ if(pPngModule == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ pPngModule->ReadHeaderCallback = CCodec_ProgressiveDecoder::PngReadHeaderFunc;
+ pPngModule->AskScanlineBufCallback = CCodec_ProgressiveDecoder::PngAskScanlineBufFunc;
+ pPngModule->FillScanlineBufCompletedCallback = CCodec_ProgressiveDecoder::PngFillScanlineBufCompletedFunc;
+ m_pPngContext = pPngModule->Start((void*)this);
+ if(m_pPngContext == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
+ if(!bResult) {
+ m_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += size;
+ bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, size, pAttribute);
+ while(bResult) {
+ FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet;
+ FX_DWORD input_size = remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
+ if(input_size == 0) {
+ if(m_pPngContext != NULL) {
+ pPngModule->Finish(m_pPngContext);
+ }
+ m_pPngContext = NULL;
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ if(m_pSrcBuf != NULL && input_size > m_SrcSize) {
+ FX_Free(m_pSrcBuf);
+ m_pSrcBuf = FX_Alloc(FX_BYTE, input_size);
+ if(m_pSrcBuf == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ FXSYS_memset32(m_pSrcBuf, 0, input_size);
+ m_SrcSize = input_size;
+ }
+ bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);
+ if(!bResult) {
+ m_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += input_size;
+ bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size, pAttribute);
+ }
+ ASSERT(!bResult);
+ if(m_pPngContext != NULL) {
+ pPngModule->Finish(m_pPngContext);
+ m_pPngContext = NULL;
+ }
+ if(m_SrcPassNumber == 0) {
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ }
+ break;
+ case FXCODEC_IMAGE_GIF: {
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
+ if(pGifModule == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ pGifModule->RecordCurrentPositionCallback = CCodec_ProgressiveDecoder::GifRecordCurrentPositionCallback;
+ pGifModule->AskLocalPaletteBufCallback = CCodec_ProgressiveDecoder::GifAskLocalPaletteBufCallback;
+ pGifModule->InputRecordPositionBufCallback = CCodec_ProgressiveDecoder::GifInputRecordPositionBufCallback;
+ pGifModule->ReadScanlineCallback = CCodec_ProgressiveDecoder::GifReadScanlineCallback;
+ m_pGifContext = pGifModule->Start((void*)this);
+ if(m_pGifContext == NULL) {
+ m_status = FXCODEC_STATUS_ERR_MEMORY;
+ return FALSE;
+ }
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, 0, size);
+ if(!bResult) {
+ m_status = FXCODEC_STATUS_ERR_READ;
+ return FALSE;
+ }
+ m_offSet += size;
+ pGifModule->Input(m_pGifContext, m_pSrcBuf, size);
+ m_SrcComponents = 1;
+ FX_INT32 readResult = pGifModule->ReadHeader(m_pGifContext, &m_SrcWidth, &m_SrcHeight,
+ &m_GifPltNumber, (void**)&m_pGifPalette, &m_GifBgIndex);
+ while(readResult == 2) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_FORMAT;
+ if(!GifReadMoreData(pGifModule, error_status)) {
+ m_status = error_status;
+ return FALSE;
+ }
+ readResult = pGifModule->ReadHeader(m_pGifContext, &m_SrcWidth, &m_SrcHeight,
+ &m_GifPltNumber, (void**)&m_pGifPalette, &m_GifBgIndex);
+ }
+ if(readResult == 1) {
+ m_SrcBPC = 8;
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
+ return TRUE;
+ }
+ if(m_pGifContext != NULL) {
+ pGifModule->Finish(m_pGifContext);
+ m_pGifContext = NULL;
+ }
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ break;
+ case FXCODEC_IMAGE_TIF: {
+ ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
+ if(pTiffModule == NULL) {
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ m_pTiffContext = pTiffModule->CreateDecoder(m_pFile);
+ if(m_pTiffContext == NULL) {
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ FX_INT32 frames = 0;
+ pTiffModule->GetFrames(m_pTiffContext, frames);
+ FX_DWORD bpc;
+ FX_BOOL ret = pTiffModule->LoadFrameInfo(m_pTiffContext, 0, (FX_DWORD&)m_SrcWidth, (FX_DWORD&)m_SrcHeight, (FX_DWORD&)m_SrcComponents, bpc, pAttribute);
+ m_SrcComponents = 4;
+ m_clipBox = FX_RECT(0, 0, m_SrcWidth, m_SrcHeight);
+ if(!ret) {
+ pTiffModule->DestroyDecoder(m_pTiffContext);
+ (m_pTiffContext = NULL);
+ (m_status = FXCODEC_STATUS_ERR_FORMAT);
+ return FALSE;
+ }
+ }
+ break;
+ default:
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ return FALSE;
+ }
+ return TRUE;
+}
+FXCODEC_STATUS CCodec_ProgressiveDecoder::LoadImageInfo(IFX_FileRead* pFile, FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute)
+{
+ switch(m_status) {
+ case FXCODEC_STATUS_FRAME_READY:
+ case FXCODEC_STATUS_FRAME_TOBECONTINUE:
+ case FXCODEC_STATUS_DECODE_READY:
+ case FXCODEC_STATUS_DECODE_TOBECONTINUE:
+ return FXCODEC_STATUS_ERROR;
+ default:
+ ;
+ }
+ if(pFile == NULL) {
+ m_status = FXCODEC_STATUS_ERR_PARAMS;
+ m_pFile = NULL;
+ return m_status;
+ }
+ m_pFile = pFile;
+ m_offSet = 0;
+ m_SrcWidth = m_SrcHeight = 0;
+ m_SrcComponents = m_SrcBPC = 0;
+ m_clipBox = FX_RECT(0, 0, 0, 0);
+ m_startX = m_startY = 0;
+ m_sizeX = m_sizeY = 0;
+ m_SrcPassNumber = 0;
+ if(imageType != FXCODEC_IMAGE_UNKNOWN &&
+ DetectImageType(imageType, pAttribute)) {
+ m_imagType = imageType;
+ m_status = FXCODEC_STATUS_FRAME_READY;
+ return m_status;
+ }
+ for (int type = FXCODEC_IMAGE_BMP; type < FXCODEC_IMAGE_MAX; type++) {
+ if(DetectImageType((FXCODEC_IMAGE_TYPE)type, pAttribute)) {
+ m_imagType = (FXCODEC_IMAGE_TYPE)type;
+ m_status = FXCODEC_STATUS_FRAME_READY;
+ return m_status;
+ }
+ }
+ m_status = FXCODEC_STATUS_ERR_FORMAT;
+ m_pFile = NULL;
+ return m_status;
+}
+void CCodec_ProgressiveDecoder::SetClipBox(FX_RECT* clip)
+{
+ if(m_status != FXCODEC_STATUS_FRAME_READY) {
+ return;
+ }
+ if(clip->IsEmpty()) {
+ m_clipBox = FX_RECT(0, 0, 0, 0);
+ return;
+ }
+ if(clip->left < 0) {
+ clip->left = 0;
+ }
+ if(clip->right > m_SrcWidth) {
+ clip->right = m_SrcWidth;
+ }
+ if(clip->top < 0) {
+ clip->top = 0;
+ }
+ if(clip->bottom > m_SrcHeight) {
+ clip->bottom = m_SrcHeight;
+ }
+ if(clip->IsEmpty()) {
+ m_clipBox = FX_RECT(0, 0, 0, 0);
+ return;
+ }
+ m_clipBox = *clip;
+}
+void CCodec_ProgressiveDecoder::GetDownScale(int& down_scale)
+{
+ down_scale = 1;
+ int ratio_w = m_clipBox.Width() / m_sizeX;
+ int ratio_h = m_clipBox.Height() / m_sizeY;
+ int ratio = (ratio_w > ratio_h) ? ratio_h : ratio_w;
+ if (ratio >= 8) {
+ down_scale = 8;
+ } else if (ratio >= 4) {
+ down_scale = 4;
+ } else if (ratio >= 2) {
+ down_scale = 2;
+ }
+ m_clipBox.left /= down_scale;
+ m_clipBox.right /= down_scale;
+ m_clipBox.top /= down_scale;
+ m_clipBox.bottom /= down_scale;
+ if(m_clipBox.right == m_clipBox.left) {
+ m_clipBox.right = m_clipBox.left + 1;
+ }
+ if(m_clipBox.bottom == m_clipBox.top) {
+ m_clipBox.bottom = m_clipBox.top + 1;
+ }
+}
+void CCodec_ProgressiveDecoder::GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format)
+{
+ switch(des_format) {
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb: {
+ switch(src_format) {
+ case FXCodec_1bppGray:
+ m_TransMethod = 0;
+ break;
+ default:
+ m_TransMethod = -1;
+ }
+ }
+ break;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ switch(src_format) {
+ case FXCodec_1bppGray:
+ m_TransMethod = 1;
+ break;
+ case FXCodec_8bppGray:
+ m_TransMethod = 2;
+ break;
+ case FXCodec_1bppRgb:
+ case FXCodec_8bppRgb:
+ m_TransMethod = 3;
+ break;
+ case FXCodec_Rgb:
+ case FXCodec_Rgb32:
+ case FXCodec_Argb:
+ m_TransMethod = 4;
+ break;
+ case FXCodec_Cmyk:
+ m_TransMethod = 5;
+ break;
+ default:
+ m_TransMethod = -1;
+ }
+ }
+ break;
+ case FXDIB_Rgb: {
+ switch(src_format) {
+ case FXCodec_1bppGray:
+ m_TransMethod = 6;
+ break;
+ case FXCodec_8bppGray:
+ m_TransMethod = 7;
+ break;
+ case FXCodec_1bppRgb:
+ case FXCodec_8bppRgb:
+ m_TransMethod = 8;
+ break;
+ case FXCodec_Rgb:
+ case FXCodec_Rgb32:
+ case FXCodec_Argb:
+ m_TransMethod = 9;
+ break;
+ case FXCodec_Cmyk:
+ m_TransMethod = 10;
+ break;
+ default:
+ m_TransMethod = -1;
+ }
+ }
+ break;
+ case FXDIB_Rgb32:
+ case FXDIB_Argb: {
+ switch(src_format) {
+ case FXCodec_1bppGray:
+ m_TransMethod = 6;
+ break;
+ case FXCodec_8bppGray:
+ m_TransMethod = 7;
+ break;
+ case FXCodec_1bppRgb:
+ case FXCodec_8bppRgb:
+ if(des_format == FXDIB_Argb) {
+ m_TransMethod = 12;
+ } else {
+ m_TransMethod = 8;
+ }
+ break;
+ case FXCodec_Rgb:
+ case FXCodec_Rgb32:
+ m_TransMethod = 9;
+ break;
+ case FXCodec_Cmyk:
+ m_TransMethod = 10;
+ break;
+ case FXCodec_Argb:
+ m_TransMethod = 11;
+ break;
+ default:
+ m_TransMethod = -1;
+ }
+ }
+ break;
+ default:
+ m_TransMethod = -1;
+ }
+}
+void _RGB2BGR(FX_LPBYTE buffer, int width = 1)
+{
+ if (buffer && width > 0) {
+ FX_BYTE temp;
+ int i = 0;
+ int j = 0;
+ for (; i < width; i++, j += 3) {
+ temp = buffer[j];
+ buffer[j] = buffer[j + 2];
+ buffer[j + 2] = temp;
+ }
+ }
+}
+void CCodec_ProgressiveDecoder::ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, int des_line, FX_LPBYTE src_scan, FXCodec_Format src_format)
+{
+ int src_left = m_clipBox.left;
+ int des_left = m_startX;
+ FX_LPBYTE des_scan = pDeviceBitmap->GetBuffer() + des_line * pDeviceBitmap->GetPitch();
+ int src_bpp = src_format & 0xff;
+ int des_bpp = pDeviceBitmap->GetBPP();
+ int src_Bpp = src_bpp >> 3;
+ int des_Bpp = des_bpp >> 3;
+ src_scan += src_left * src_Bpp;
+ des_scan += des_left * des_Bpp;
+ for (int des_col = 0; des_col < m_sizeX; des_col++) {
+ PixelWeight* pPixelWeights = m_WeightHorz.GetPixelWeight(des_col);
+ switch(m_TransMethod) {
+ case -1:
+ return;
+ case 0:
+ return;
+ case 1:
+ return;
+ case 2: {
+ FX_DWORD des_g = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ des_g += pixel_weight * src_scan[j];
+ }
+ *des_scan++ = (FX_BYTE)(des_g >> 16);
+ }
+ break;
+ case 3: {
+ int des_r = 0, des_g = 0, des_b = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ unsigned long argb = m_pSrcPalette[src_scan[j]];
+ des_r += pixel_weight * (FX_BYTE)(argb >> 16);
+ des_g += pixel_weight * (FX_BYTE)(argb >> 8);
+ des_b += pixel_weight * (FX_BYTE)argb;
+ }
+ *des_scan++ = (FX_BYTE)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));
+ }
+ break;
+ case 4: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;
+ des_b += pixel_weight * (*src_pixel++);
+ des_g += pixel_weight * (*src_pixel++);
+ des_r += pixel_weight * (*src_pixel);
+ }
+ *des_scan++ = (FX_BYTE)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));
+ }
+ break;
+ case 5: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;
+ FX_BYTE src_b = 0, src_g = 0, src_r = 0;
+ AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], 255 - src_pixel[2], 255 - src_pixel[3],
+ src_r, src_g, src_b);
+ des_b += pixel_weight * src_b;
+ des_g += pixel_weight * src_g;
+ des_r += pixel_weight * src_r;
+ }
+ *des_scan++ = (FX_BYTE)FXRGB2GRAY((des_r >> 16), (des_g >> 16), (des_b >> 16));
+ }
+ break;
+ case 6:
+ return;
+ case 7: {
+ FX_DWORD des_g = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ des_g += pixel_weight * src_scan[j];
+ }
+ FXSYS_memset8(des_scan, (FX_BYTE)(des_g >> 16), 3);
+ des_scan += des_Bpp;
+ }
+ break;
+ case 8: {
+ int des_r = 0, des_g = 0, des_b = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ unsigned long argb = m_pSrcPalette[src_scan[j]];
+ des_r += pixel_weight * (FX_BYTE)(argb >> 16);
+ des_g += pixel_weight * (FX_BYTE)(argb >> 8);
+ des_b += pixel_weight * (FX_BYTE)argb;
+ }
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ des_scan += des_Bpp - 3;
+ }
+ break;
+ case 12: {
+ if (m_pBmpContext) {
+ int des_r = 0, des_g = 0, des_b = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ unsigned long argb = m_pSrcPalette[src_scan[j]];
+ des_r += pixel_weight * (FX_BYTE)(argb >> 16);
+ des_g += pixel_weight * (FX_BYTE)(argb >> 8);
+ des_b += pixel_weight * (FX_BYTE)argb;
+ }
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ *des_scan++ = 0xFF;
+ } else {
+ int des_a = 0, des_r = 0, des_g = 0, des_b = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ unsigned long argb = m_pSrcPalette[src_scan[j]];
+ des_a += pixel_weight * (FX_BYTE)(argb >> 24);
+ des_r += pixel_weight * (FX_BYTE)(argb >> 16);
+ des_g += pixel_weight * (FX_BYTE)(argb >> 8);
+ des_b += pixel_weight * (FX_BYTE)argb;
+ }
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ *des_scan++ = (FX_BYTE)((des_a) >> 16);
+ }
+ }
+ break;
+ case 9: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;
+ des_b += pixel_weight * (*src_pixel++);
+ des_g += pixel_weight * (*src_pixel++);
+ des_r += pixel_weight * (*src_pixel);
+ }
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ des_scan += des_Bpp - 3;
+ }
+ break;
+ case 10: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;
+ FX_BYTE src_b = 0, src_g = 0, src_r = 0;
+ AdobeCMYK_to_sRGB1(255 - src_pixel[0], 255 - src_pixel[1], 255 - src_pixel[2], 255 - src_pixel[3],
+ src_r, src_g, src_b);
+ des_b += pixel_weight * src_b;
+ des_g += pixel_weight * src_g;
+ des_r += pixel_weight * src_r;
+ }
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ des_scan += des_Bpp - 3;
+ }
+ break;
+ case 11: {
+ FX_DWORD des_alpha = 0, des_r = 0, des_g = 0, des_b = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + j * src_Bpp;
+ pixel_weight = pixel_weight * src_pixel[3] / 255;
+ des_b += pixel_weight * (*src_pixel++);
+ des_g += pixel_weight * (*src_pixel++);
+ des_r += pixel_weight * (*src_pixel);
+ des_alpha += pixel_weight;
+ }
+ *des_scan++ = (FX_BYTE)((des_b) >> 16);
+ *des_scan++ = (FX_BYTE)((des_g) >> 16);
+ *des_scan++ = (FX_BYTE)((des_r) >> 16);
+ *des_scan++ = (FX_BYTE)((des_alpha * 255) >> 16);
+ }
+ break;
+ default:
+ return;
+ }
+ }
+}
+void CCodec_ProgressiveDecoder::ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row)
+{
+ int des_Bpp = pDeviceBitmap->GetBPP() >> 3;
+ FX_DWORD des_ScanOffet = m_startX * des_Bpp;
+ if(m_bInterpol) {
+ int des_top = m_startY;
+ int des_row_1 = des_row - int(scale_y);
+ if(des_row_1 < des_top) {
+ int des_bottom = des_top + m_sizeY;
+ if(des_row + (int)scale_y >= des_bottom - 1) {
+ FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
+ while (++des_row < des_bottom) {
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
+ FX_DWORD size = m_sizeX * des_Bpp;
+ FXSYS_memcpy32(scan_des, scan_src, size);
+ }
+ }
+ return;
+ }
+ for (; des_row_1 < des_row; des_row_1++) {
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row_1) + des_ScanOffet;
+ PixelWeight* pWeight = m_WeightVert.GetPixelWeight(des_row_1 - des_top);
+ FX_LPCBYTE scan_src1 = pDeviceBitmap->GetScanline(pWeight->m_SrcStart + des_top) + des_ScanOffet;
+ FX_LPCBYTE scan_src2 = pDeviceBitmap->GetScanline(pWeight->m_SrcEnd + des_top) + des_ScanOffet;
+ for (int des_col = 0; des_col < m_sizeX; des_col++) {
+ switch(pDeviceBitmap->GetFormat()) {
+ case FXDIB_Invalid:
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ return;
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb: {
+ if(pDeviceBitmap->GetPalette() != NULL) {
+ return;
+ }
+ int des_g = 0;
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (FX_BYTE)(des_g >> 16);
+ }
+ break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ FX_DWORD des_b = 0, des_g = 0, des_r = 0;
+ des_b += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_r += pWeight->m_Weights[0] * (*scan_src1++);
+ scan_src1 += des_Bpp - 3;
+ des_b += pWeight->m_Weights[1] * (*scan_src2++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ des_r += pWeight->m_Weights[1] * (*scan_src2++);
+ scan_src2 += des_Bpp - 3;
+ *scan_des++ = (FX_BYTE)((des_b) >> 16);
+ *scan_des++ = (FX_BYTE)((des_g) >> 16);
+ *scan_des++ = (FX_BYTE)((des_r) >> 16);
+ scan_des += des_Bpp - 3;
+ }
+ break;
+ case FXDIB_Argb: {
+ FX_DWORD des_a = 0, des_b = 0, des_g = 0, des_r = 0;
+ des_b += pWeight->m_Weights[0] * (*scan_src1++);
+ des_g += pWeight->m_Weights[0] * (*scan_src1++);
+ des_r += pWeight->m_Weights[0] * (*scan_src1++);
+ des_a += pWeight->m_Weights[0] * (*scan_src1++);
+ des_b += pWeight->m_Weights[1] * (*scan_src2++);
+ des_g += pWeight->m_Weights[1] * (*scan_src2++);
+ des_r += pWeight->m_Weights[1] * (*scan_src2++);
+ des_a += pWeight->m_Weights[1] * (*scan_src2++);
+ *scan_des++ = (FX_BYTE)((des_b) >> 16);
+ *scan_des++ = (FX_BYTE)((des_g) >> 16);
+ *scan_des++ = (FX_BYTE)((des_r) >> 16);
+ *scan_des++ = (FX_BYTE)((des_a) >> 16);
+ }
+ break;
+ default:
+ return;
+ }
+ }
+ }
+ int des_bottom = des_top + m_sizeY;
+ if(des_row + (int)scale_y >= des_bottom - 1) {
+ FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
+ while (++des_row < des_bottom) {
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
+ FX_DWORD size = m_sizeX * des_Bpp;
+ FXSYS_memcpy32(scan_des, scan_src, size);
+ }
+ }
+ return;
+ }
+ int multiple = (int)FXSYS_ceil((FX_FLOAT)scale_y - 1);
+ if(multiple > 0) {
+ FX_LPBYTE scan_src = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row) + des_ScanOffet;
+ for (int i = 1; i <= multiple; i++) {
+ if(des_row + i >= m_startY + m_sizeY) {
+ return;
+ }
+ FX_LPBYTE scan_des = (FX_LPBYTE)pDeviceBitmap->GetScanline(des_row + i) + des_ScanOffet;
+ FX_DWORD size = m_sizeX * des_Bpp;
+ FXSYS_memcpy32(scan_des, scan_src, size);
+ }
+ }
+}
+void CCodec_ProgressiveDecoder::Resample(CFX_DIBitmap* pDeviceBitmap, FX_INT32 src_line, FX_LPBYTE src_scan, FXCodec_Format src_format)
+{
+ int src_top = m_clipBox.top;
+ int des_top = m_startY;
+ int src_hei = m_clipBox.Height();
+ int des_hei = m_sizeY;
+ if(src_line >= src_top) {
+ double scale_y = (double)des_hei / (double)src_hei;
+ int src_row = src_line - src_top;
+ int des_row = (int)(src_row * scale_y) + des_top;
+ if(des_row >= des_top + des_hei) {
+ return;
+ }
+ ReSampleScanline(pDeviceBitmap, des_row, m_pDecodeBuf, src_format);
+ if(scale_y > 1.0) {
+ ResampleVert(pDeviceBitmap, scale_y, des_row);
+ }
+ }
+}
+FXCODEC_STATUS CCodec_ProgressiveDecoder::GetFrames(FX_INT32& frames, IFX_Pause* pPause)
+{
+ if(!(m_status == FXCODEC_STATUS_FRAME_READY || m_status == FXCODEC_STATUS_FRAME_TOBECONTINUE)) {
+ return FXCODEC_STATUS_ERROR;
+ }
+ switch(m_imagType) {
+ case FXCODEC_IMAGE_BMP:
+ case FXCODEC_IMAGE_JPG:
+ case FXCODEC_IMAGE_PNG:
+ case FXCODEC_IMAGE_TIF:
+ frames = m_FrameNumber = 1;
+ return m_status = FXCODEC_STATUS_DECODE_READY;
+ case FXCODEC_IMAGE_GIF: {
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
+ while (TRUE) {
+ FX_INT32 readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);
+ while(readResult == 2) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERR_READ;
+ if(!GifReadMoreData(pGifModule, error_status)) {
+ return error_status;
+ }
+ if(pPause && pPause->NeedToPauseNow()) {
+ return m_status = FXCODEC_STATUS_FRAME_TOBECONTINUE;
+ }
+ readResult = pGifModule->LoadFrameInfo(m_pGifContext, &m_FrameNumber);
+ }
+ if(readResult == 1) {
+ frames = m_FrameNumber;
+ return m_status = FXCODEC_STATUS_DECODE_READY;
+ }
+ if(m_pGifContext != NULL) {
+ pGifModule->Finish(m_pGifContext);
+ m_pGifContext = NULL;
+ }
+ return m_status = FXCODEC_STATUS_ERROR;
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ return FXCODEC_STATUS_ERROR;
+}
+FXCODEC_STATUS CCodec_ProgressiveDecoder::StartDecode(CFX_DIBitmap* pDIBitmap,
+ int start_x, int start_y, int size_x, int size_y,
+ FX_INT32 frames, FX_BOOL bInterpol)
+{
+ if(m_status != FXCODEC_STATUS_DECODE_READY) {
+ return FXCODEC_STATUS_ERROR;
+ }
+ if(pDIBitmap == NULL || pDIBitmap->GetBPP() < 8 ||
+ frames < 0 || frames >= m_FrameNumber) {
+ return FXCODEC_STATUS_ERR_PARAMS;
+ }
+ m_pDeviceBitmap = pDIBitmap;
+ if(m_clipBox.IsEmpty()) {
+ return FXCODEC_STATUS_ERR_PARAMS;
+ }
+ if(size_x <= 0 || size_x > 65535 || size_y <= 0 || size_y > 65535) {
+ return FXCODEC_STATUS_ERR_PARAMS;
+ }
+ FX_RECT device_rc = FX_RECT(start_x, start_y, start_x + size_x, start_y + size_y);
+ FX_INT32 out_range_x = device_rc.right - pDIBitmap->GetWidth();
+ FX_INT32 out_range_y = device_rc.bottom - pDIBitmap->GetHeight();
+ device_rc.Intersect(FX_RECT(0, 0, pDIBitmap->GetWidth(), pDIBitmap->GetHeight()));
+ if(device_rc.IsEmpty()) {
+ return FXCODEC_STATUS_ERR_PARAMS;
+ }
+ m_startX = device_rc.left;
+ m_startY = device_rc.top;
+ m_sizeX = device_rc.Width();
+ m_sizeY = device_rc.Height();
+ m_bInterpol = bInterpol;
+ m_FrameCur = 0;
+ if(start_x < 0 || out_range_x > 0) {
+ FX_FLOAT scaleX = (FX_FLOAT)m_clipBox.Width() / (FX_FLOAT)size_x;
+ if(start_x < 0) {
+ m_clipBox.left -= (FX_INT32)FXSYS_ceil((FX_FLOAT)start_x * scaleX);
+ }
+ if(out_range_x > 0) {
+ m_clipBox.right -= (FX_INT32)FXSYS_floor((FX_FLOAT)out_range_x * scaleX);
+ }
+ }
+ if(start_y < 0 || out_range_y > 0) {
+ FX_FLOAT scaleY = (FX_FLOAT)m_clipBox.Height() / (FX_FLOAT)size_y;
+ if(start_y < 0) {
+ m_clipBox.top -= (FX_INT32)FXSYS_ceil((FX_FLOAT)start_y * scaleY);
+ }
+ if(out_range_y > 0) {
+ m_clipBox.bottom -= (FX_INT32)FXSYS_floor((FX_FLOAT)out_range_y * scaleY);
+ }
+ }
+ if(m_clipBox.IsEmpty()) {
+ return FXCODEC_STATUS_ERR_PARAMS;
+ }
+ switch(m_imagType) {
+ case FXCODEC_IMAGE_JPG: {
+ ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
+ int down_scale = 1;
+ GetDownScale(down_scale);
+ FX_BOOL bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale);
+ while(!bStart) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_ERROR;
+ if(!JpegReadMoreData(pJpegModule, error_status)) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = error_status;
+ }
+ bStart = pJpegModule->StartScanline(m_pJpegContext, down_scale);
+ }
+ int scanline_size = ( m_SrcWidth + down_scale - 1) / down_scale;
+ scanline_size = (scanline_size * m_SrcComponents + 3) / 4 * 4;
+ if(m_pDecodeBuf != NULL) {
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = NULL;
+ }
+ m_pDecodeBuf = FX_Alloc(FX_BYTE, scanline_size);
+ if(m_pDecodeBuf == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ FXSYS_memset32(m_pDecodeBuf, 0, scanline_size);
+ m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, m_clipBox.Width(), m_bInterpol);
+ m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
+ switch(m_SrcComponents) {
+ case 1:
+ m_SrcFormat = FXCodec_8bppGray;
+ break;
+ case 3:
+ m_SrcFormat = FXCodec_Rgb;
+ break;
+ case 4:
+ m_SrcFormat = FXCodec_Cmyk;
+ break;
+ }
+ GetTransMethod(pDIBitmap->GetFormat(), m_SrcFormat);
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ break;
+ case FXCODEC_IMAGE_PNG: {
+ ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
+ if(pPngModule == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ if(m_pPngContext != NULL) {
+ pPngModule->Finish(m_pPngContext);
+ m_pPngContext = NULL;
+ }
+ m_pPngContext = pPngModule->Start((void*)this);
+ if(m_pPngContext == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ m_offSet = 0;
+ switch(m_pDeviceBitmap->GetFormat()) {
+ case FXDIB_8bppMask:
+ case FXDIB_8bppRgb:
+ m_SrcComponents = 1;
+ m_SrcFormat = FXCodec_8bppGray;
+ break;
+ case FXDIB_Rgb:
+ m_SrcComponents = 3;
+ m_SrcFormat = FXCodec_Rgb;
+ break;
+ case FXDIB_Rgb32:
+ case FXDIB_Argb:
+ m_SrcComponents = 4;
+ m_SrcFormat = FXCodec_Argb;
+ break;
+ default: {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_PARAMS;
+ }
+ }
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
+ int scanline_size = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
+ if(m_pDecodeBuf != NULL) {
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = NULL;
+ }
+ m_pDecodeBuf = FX_Alloc(FX_BYTE, scanline_size);
+ if(m_pDecodeBuf == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ FXSYS_memset32(m_pDecodeBuf, 0, scanline_size);
+ m_WeightHorzOO.Calc(m_sizeX, m_clipBox.Width(), m_bInterpol);
+ m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ break;
+ case FXCODEC_IMAGE_GIF: {
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
+ if(pGifModule == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ m_SrcFormat = FXCodec_8bppRgb;
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
+ int scanline_size = (m_SrcWidth + 3) / 4 * 4;
+ if(m_pDecodeBuf != NULL) {
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = NULL;
+ }
+ m_pDecodeBuf = FX_Alloc(FX_BYTE, scanline_size);
+ if(m_pDecodeBuf == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ FXSYS_memset32(m_pDecodeBuf, 0, scanline_size);
+ m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, m_clipBox.Width(), m_bInterpol);
+ m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
+ m_FrameCur = frames;
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ break;
+ case FXCODEC_IMAGE_BMP: {
+ ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
+ if(pBmpModule == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ switch(m_SrcComponents) {
+ case 1:
+ m_SrcFormat = FXCodec_8bppRgb;
+ break;
+ case 3:
+ m_SrcFormat = FXCodec_Rgb;
+ break;
+ case 4:
+ m_SrcFormat = FXCodec_Rgb32;
+ break;
+ }
+ GetTransMethod(m_pDeviceBitmap->GetFormat(), m_SrcFormat);
+ m_ScanlineSize = (m_SrcWidth * m_SrcComponents + 3) / 4 * 4;
+ if(m_pDecodeBuf != NULL) {
+ FX_Free(m_pDecodeBuf);
+ m_pDecodeBuf = NULL;
+ }
+ m_pDecodeBuf = FX_Alloc(FX_BYTE, m_ScanlineSize);
+ if(m_pDecodeBuf == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ FXSYS_memset32(m_pDecodeBuf, 0, m_ScanlineSize);
+ m_WeightHorz.Calc(m_sizeX, 0, m_sizeX, m_clipBox.Width(), 0, m_clipBox.Width(), m_bInterpol);
+ m_WeightVert.Calc(m_sizeY, m_clipBox.Height());
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ break;
+ case FXCODEC_IMAGE_TIF:
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ default:
+ break;
+ }
+ return FXCODEC_STATUS_ERROR;
+}
+FXCODEC_STATUS CCodec_ProgressiveDecoder::ContinueDecode(IFX_Pause* pPause)
+{
+ if(m_status != FXCODEC_STATUS_DECODE_TOBECONTINUE) {
+ return FXCODEC_STATUS_ERROR;
+ }
+ switch(m_imagType) {
+ case FXCODEC_IMAGE_JPG: {
+ ICodec_JpegModule* pJpegModule = m_pCodecMgr->GetJpegModule();
+ while(TRUE) {
+ FX_BOOL readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);
+ while(!readRes) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
+ if(!JpegReadMoreData(pJpegModule, error_status)) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = error_status;
+ }
+ readRes = pJpegModule->ReadScanline(m_pJpegContext, m_pDecodeBuf);
+ }
+ if(m_SrcFormat == FXCodec_Rgb) {
+ int src_Bpp = (m_SrcFormat & 0xff) >> 3;
+ _RGB2BGR(m_pDecodeBuf + m_clipBox.left * src_Bpp, m_clipBox.Width());
+ }
+ if(m_SrcRow >= m_clipBox.bottom) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_DECODE_FINISH;
+ }
+ Resample(m_pDeviceBitmap, m_SrcRow, m_pDecodeBuf, m_SrcFormat);
+ m_SrcRow++;
+ if(pPause && pPause->NeedToPauseNow()) {
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ }
+ }
+ break;
+ case FXCODEC_IMAGE_PNG: {
+ ICodec_PngModule* pPngModule = m_pCodecMgr->GetPngModule();
+ while (TRUE) {
+ FX_DWORD remain_size = (FX_DWORD)m_pFile->GetSize() - m_offSet;
+ FX_DWORD input_size = remain_size > FXCODEC_BLOCK_SIZE ? FXCODEC_BLOCK_SIZE : remain_size;
+ if(input_size == 0) {
+ if(m_pPngContext != NULL) {
+ pPngModule->Finish(m_pPngContext);
+ }
+ m_pPngContext = NULL;
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_DECODE_FINISH;
+ }
+ if(m_pSrcBuf != NULL && input_size > m_SrcSize) {
+ FX_Free(m_pSrcBuf);
+ m_pSrcBuf = FX_Alloc(FX_BYTE, input_size);
+ if(m_pSrcBuf == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ FXSYS_memset32(m_pSrcBuf, 0, input_size);
+ m_SrcSize = input_size;
+ }
+ FX_BOOL bResult = m_pFile->ReadBlock(m_pSrcBuf, m_offSet, input_size);
+ if(!bResult) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_READ;
+ }
+ m_offSet += input_size;
+ bResult = pPngModule->Input(m_pPngContext, m_pSrcBuf, input_size);
+ if(!bResult) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERROR;
+ }
+ if(pPause && pPause->NeedToPauseNow()) {
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ }
+ }
+ break;
+ case FXCODEC_IMAGE_GIF: {
+ ICodec_GifModule* pGifModule = m_pCodecMgr->GetGifModule();
+ while(TRUE) {
+ FX_INT32 readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur);
+ while(readRes == 2) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
+ if(!GifReadMoreData(pGifModule, error_status)) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = error_status;
+ }
+ if(pPause && pPause->NeedToPauseNow()) {
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ readRes = pGifModule->LoadFrame(m_pGifContext, m_FrameCur);
+ }
+ if(readRes == 1) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_DECODE_FINISH;
+ }
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERROR;
+ }
+ }
+ break;
+ case FXCODEC_IMAGE_BMP: {
+ ICodec_BmpModule* pBmpModule = m_pCodecMgr->GetBmpModule();
+ while(TRUE) {
+ FX_INT32 readRes = pBmpModule->LoadImage(m_pBmpContext);
+ while(readRes == 2) {
+ FXCODEC_STATUS error_status = FXCODEC_STATUS_DECODE_FINISH;
+ if(!BmpReadMoreData(pBmpModule, error_status)) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = error_status;
+ }
+ if(pPause && pPause->NeedToPauseNow()) {
+ return m_status = FXCODEC_STATUS_DECODE_TOBECONTINUE;
+ }
+ readRes = pBmpModule->LoadImage(m_pBmpContext);
+ }
+ if(readRes == 1) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_DECODE_FINISH;
+ }
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERROR;
+ }
+ }
+ break;
+ case FXCODEC_IMAGE_TIF: {
+ ICodec_TiffModule* pTiffModule = m_pCodecMgr->GetTiffModule();
+ FX_BOOL ret = FALSE;
+ if(m_pDeviceBitmap->GetBPP() == 32 &&
+ m_pDeviceBitmap->GetWidth() == m_SrcWidth && m_SrcWidth == m_sizeX &&
+ m_pDeviceBitmap->GetHeight() == m_SrcHeight && m_SrcHeight == m_sizeY &&
+ m_startX == 0 && m_startY == 0 && m_clipBox.left == 0 && m_clipBox.top == 0
+ && m_clipBox.right == m_SrcWidth && m_clipBox.bottom == m_SrcHeight) {
+ ret = pTiffModule->Decode(m_pTiffContext, m_pDeviceBitmap);
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ if(!ret) {
+ return m_status = FXCODEC_STATUS_ERROR;
+ }
+ return m_status = FXCODEC_STATUS_DECODE_FINISH;
+ } else {
+ CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
+ if(pDIBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ pDIBitmap->Create(m_SrcWidth, m_SrcHeight, FXDIB_Argb);
+ if(pDIBitmap->GetBuffer() == NULL) {
+ delete pDIBitmap;
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ ret = pTiffModule->Decode(m_pTiffContext, pDIBitmap);
+ if(!ret) {
+ delete pDIBitmap;
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERROR;
+ }
+ CFX_DIBitmap* pClipBitmap =
+ (m_clipBox.left == 0 &&
+ m_clipBox.top == 0 &&
+ m_clipBox.right == m_SrcWidth &&
+ m_clipBox.bottom == m_SrcHeight) ? pDIBitmap : pDIBitmap->Clone(&m_clipBox);
+ if(pDIBitmap != pClipBitmap) {
+ delete pDIBitmap;
+ }
+ if(pClipBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ CFX_DIBitmap* pFormatBitmap = NULL;
+ switch(m_pDeviceBitmap->GetFormat()) {
+ case FXDIB_8bppRgb:
+ pFormatBitmap = FX_NEW CFX_DIBitmap;
+ if(pFormatBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_8bppRgb);
+ break;
+ case FXDIB_8bppMask:
+ pFormatBitmap = FX_NEW CFX_DIBitmap;
+ if(pFormatBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_8bppMask);
+ break;
+ case FXDIB_Rgb:
+ pFormatBitmap = FX_NEW CFX_DIBitmap;
+ if(pFormatBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_Rgb);
+ break;
+ case FXDIB_Rgb32:
+ pFormatBitmap = FX_NEW CFX_DIBitmap;
+ if(pFormatBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ pFormatBitmap->Create(pClipBitmap->GetWidth(), pClipBitmap->GetHeight(), FXDIB_Rgb32);
+ break;
+ case FXDIB_Argb:
+ pFormatBitmap = pClipBitmap;
+ break;
+ default:
+ ;
+ }
+ switch(m_pDeviceBitmap->GetFormat()) {
+ case FXDIB_8bppRgb:
+ case FXDIB_8bppMask: {
+ for (FX_INT32 row = 0; row < pClipBitmap->GetHeight(); row++) {
+ FX_LPBYTE src_line = (FX_LPBYTE)pClipBitmap->GetScanline(row);
+ FX_LPBYTE des_line = (FX_LPBYTE)pFormatBitmap->GetScanline(row);
+ for (FX_INT32 col = 0; col < pClipBitmap->GetWidth(); col++) {
+ FX_BYTE _a = 255 - src_line[3];
+ FX_BYTE b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
+ FX_BYTE g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
+ FX_BYTE r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
+ *des_line++ = FXRGB2GRAY(r, g, b);
+ src_line += 4;
+ }
+ }
+ }
+ break;
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ FX_INT32 desBpp = (m_pDeviceBitmap->GetFormat() == FXDIB_Rgb) ? 3 : 4;
+ for (FX_INT32 row = 0; row < pClipBitmap->GetHeight(); row++) {
+ FX_LPBYTE src_line = (FX_LPBYTE)pClipBitmap->GetScanline(row);
+ FX_LPBYTE des_line = (FX_LPBYTE)pFormatBitmap->GetScanline(row);
+ for (FX_INT32 col = 0; col < pClipBitmap->GetWidth(); col++) {
+ FX_BYTE _a = 255 - src_line[3];
+ FX_BYTE b = (src_line[0] * src_line[3] + 0xFF * _a) / 255;
+ FX_BYTE g = (src_line[1] * src_line[3] + 0xFF * _a) / 255;
+ FX_BYTE r = (src_line[2] * src_line[3] + 0xFF * _a) / 255;
+ *des_line++ = b;
+ *des_line++ = g;
+ *des_line++ = r;
+ des_line += desBpp - 3;
+ src_line += 4;
+ }
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ if(pClipBitmap != pFormatBitmap) {
+ delete pClipBitmap;
+ }
+ if(pFormatBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ CFX_DIBitmap* pStrechBitmap = pFormatBitmap->StretchTo(m_sizeX, m_sizeY, m_bInterpol ? FXDIB_INTERPOL : FXDIB_DOWNSAMPLE);
+ delete pFormatBitmap;
+ pFormatBitmap = NULL;
+ if(pStrechBitmap == NULL) {
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_ERR_MEMORY;
+ }
+ m_pDeviceBitmap->TransferBitmap(m_startX, m_startY, m_sizeX, m_sizeY, pStrechBitmap, 0, 0);
+ delete pStrechBitmap;
+ pStrechBitmap = NULL;
+ m_pDeviceBitmap = NULL;
+ m_pFile = NULL;
+ return m_status = FXCODEC_STATUS_DECODE_FINISH;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return FXCODEC_STATUS_ERROR;
+}
+ICodec_ProgressiveDecoder* CCodec_ModuleMgr::CreateProgressiveDecoder()
+{
+ return FX_NEW CCodec_ProgressiveDecoder(this);
+}
diff --git a/core/src/fxcodec/codec/fx_codec_progress.h b/core/src/fxcodec/codec/fx_codec_progress.h
new file mode 100644
index 0000000000..6a618e2f51
--- /dev/null
+++ b/core/src/fxcodec/codec/fx_codec_progress.h
@@ -0,0 +1,206 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_CODEC_PROGRESS_H_
+#define _FX_CODEC_PROGRESS_H_
+#define FXCODEC_BLOCK_SIZE 4096
+#define FXCODEC_PNG_GAMMA 2.2
+#if _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
+# undef FXCODEC_PNG_GAMMA
+# define FXCODEC_PNG_GAMMA 1.7
+#endif
+struct PixelWeight {
+ int m_SrcStart;
+ int m_SrcEnd;
+ int m_Weights[1];
+};
+class CFXCODEC_WeightTable : public CFX_Object
+{
+public:
+ CFXCODEC_WeightTable()
+ {
+ m_pWeightTables = NULL;
+ }
+ ~CFXCODEC_WeightTable()
+ {
+ if(m_pWeightTables != NULL) {
+ FX_Free(m_pWeightTables);
+ }
+ }
+
+ void Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, FX_BOOL bInterpol);
+ PixelWeight* GetPixelWeight(int pixel)
+ {
+ return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize);
+ }
+
+ int m_DestMin, m_ItemSize;
+ FX_LPBYTE m_pWeightTables;
+};
+class CFXCODEC_HorzTable : public CFX_Object
+{
+public:
+ CFXCODEC_HorzTable()
+ {
+ m_pWeightTables = NULL;
+ }
+ ~CFXCODEC_HorzTable()
+ {
+ if(m_pWeightTables != NULL) {
+ FX_Free(m_pWeightTables);
+ }
+ }
+
+ void Calc(int dest_len, int src_len, FX_BOOL bInterpol);
+ PixelWeight* GetPixelWeight(int pixel)
+ {
+ return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize);
+ }
+
+ int m_ItemSize;
+ FX_LPBYTE m_pWeightTables;
+};
+class CFXCODEC_VertTable : public CFX_Object
+{
+public:
+ CFXCODEC_VertTable()
+ {
+ m_pWeightTables = NULL;
+ }
+ ~CFXCODEC_VertTable()
+ {
+ if(m_pWeightTables != NULL) {
+ FX_Free(m_pWeightTables);
+ }
+ }
+ void Calc(int dest_len, int src_len);
+ PixelWeight* GetPixelWeight(int pixel)
+ {
+ return (PixelWeight*)(m_pWeightTables + pixel * m_ItemSize);
+ }
+ int m_ItemSize;
+ FX_LPBYTE m_pWeightTables;
+};
+enum FXCodec_Format {
+ FXCodec_Invalid = 0,
+ FXCodec_1bppGray = 0x101,
+ FXCodec_1bppRgb = 0x001,
+ FXCodec_8bppGray = 0x108,
+ FXCodec_8bppRgb = 0x008,
+ FXCodec_Rgb = 0x018,
+ FXCodec_Rgb32 = 0x020,
+ FXCodec_Argb = 0x220,
+ FXCodec_Cmyk = 0x120
+};
+class CCodec_ProgressiveDecoder : public ICodec_ProgressiveDecoder
+{
+public:
+ CCodec_ProgressiveDecoder(CCodec_ModuleMgr* pCodecMgr);
+ virtual ~CCodec_ProgressiveDecoder();
+
+public:
+ virtual FXCODEC_STATUS LoadImageInfo(IFX_FileRead* pFile, FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute);
+
+ virtual FXCODEC_IMAGE_TYPE GetType()
+ {
+ return m_imagType;
+ }
+ virtual FX_INT32 GetWidth()
+ {
+ return m_SrcWidth;
+ }
+ virtual FX_INT32 GetHeight()
+ {
+ return m_SrcHeight;
+ }
+ virtual FX_INT32 GetNumComponents()
+ {
+ return m_SrcComponents;
+ }
+ virtual FX_INT32 GetBPC()
+ {
+ return m_SrcBPC;
+ }
+ virtual void SetClipBox(FX_RECT* clip);
+ virtual FXCODEC_STATUS GetFrames(FX_INT32& frames, IFX_Pause* pPause);
+
+ virtual FXCODEC_STATUS StartDecode(CFX_DIBitmap* pDIBitmap,
+ int start_x, int start_y, int size_x, int size_y,
+ FX_INT32 frames, FX_BOOL bInterpol);
+
+ virtual FXCODEC_STATUS ContinueDecode(IFX_Pause* pPause);
+
+protected:
+ FX_BOOL DetectImageType(FXCODEC_IMAGE_TYPE imageType, CFX_DIBAttribute* pAttribute = NULL);
+ void GetDownScale(int& down_scale);
+ void GetTransMethod(FXDIB_Format des_format, FXCodec_Format src_format);
+ void ReSampleScanline(CFX_DIBitmap* pDeviceBitmap, FX_INT32 des_line, FX_LPBYTE src_scan, FXCodec_Format src_format);
+ void Resample(CFX_DIBitmap* pDeviceBitmap, FX_INT32 src_line, FX_LPBYTE src_scan, FXCodec_Format src_format);
+ void ResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row);
+ FX_BOOL JpegReadMoreData(ICodec_JpegModule* pJpegModule, FXCODEC_STATUS& err_status);
+ static FX_BOOL PngReadHeaderFunc(void* pModule, int width, int height, int bpc, int pass, int* color_type, double* gamma);
+ static FX_BOOL PngAskScanlineBufFunc(void* pModule, int line, FX_LPBYTE& src_buf);
+ static void PngFillScanlineBufCompletedFunc(void* pModule, int pass, int line);
+ void PngOneOneMapResampleHorz(CFX_DIBitmap* pDeviceBitmap, FX_INT32 des_line, FX_LPBYTE src_scan, FXCodec_Format src_format);
+
+ FX_BOOL GifReadMoreData(ICodec_GifModule* pGifModule, FXCODEC_STATUS& err_status);
+ static void GifRecordCurrentPositionCallback(void* pModule, FX_DWORD& cur_pos);
+ static FX_LPBYTE GifAskLocalPaletteBufCallback(void* pModule, FX_INT32 frame_num, FX_INT32 pal_size);
+ static FX_BOOL GifInputRecordPositionBufCallback(void* pModule, FX_DWORD rcd_pos, const FX_RECT& img_rc,
+ FX_INT32 pal_num, void* pal_ptr,
+ FX_INT32 delay_time, FX_BOOL user_input,
+ FX_INT32 trans_index, FX_INT32 disposal_method, FX_BOOL interlace);
+ static void GifReadScanlineCallback(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf);
+ void GifDoubleLineResampleVert(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row);
+ FX_BOOL BmpReadMoreData(ICodec_BmpModule* pBmpModule, FXCODEC_STATUS& err_status);
+ static FX_BOOL BmpInputImagePositionBufCallback(void* pModule, FX_DWORD rcd_pos);
+ static void BmpReadScanlineCallback(void* pModule, FX_INT32 row_num, FX_LPBYTE row_buf);
+ void ResampleVertBT(CFX_DIBitmap* pDeviceBitmap, double scale_y, int des_row);
+public:
+ IFX_FileRead* m_pFile;
+ CCodec_ModuleMgr* m_pCodecMgr;
+ FX_LPVOID m_pJpegContext;
+ FX_LPVOID m_pPngContext;
+ FX_LPVOID m_pGifContext;
+ FX_LPVOID m_pBmpContext;
+ FX_LPVOID m_pTiffContext;
+ FXCODEC_IMAGE_TYPE m_imagType;
+ FX_DWORD m_offSet;
+ FX_LPBYTE m_pSrcBuf;
+ FX_DWORD m_SrcSize;
+ FX_LPBYTE m_pDecodeBuf;
+ int m_ScanlineSize;
+ CFX_DIBitmap* m_pDeviceBitmap;
+ FX_BOOL m_bInterpol;
+ CFXCODEC_WeightTable m_WeightHorz;
+ CFXCODEC_VertTable m_WeightVert;
+ CFXCODEC_HorzTable m_WeightHorzOO;
+ int m_SrcWidth;
+ int m_SrcHeight;
+ int m_SrcComponents;
+ int m_SrcBPC;
+ FX_RECT m_clipBox;
+ int m_startX;
+ int m_startY;
+ int m_sizeX;
+ int m_sizeY;
+ int m_TransMethod;
+ FX_ARGB* m_pSrcPalette;
+ int m_SrcPaletteNumber;
+ int m_SrcRow;
+ FXCodec_Format m_SrcFormat;
+ int m_SrcPassNumber;
+ int m_FrameNumber;
+ int m_FrameCur;
+ int m_GifBgIndex;
+ FX_LPBYTE m_pGifPalette;
+ FX_INT32 m_GifPltNumber;
+ int m_GifTransIndex;
+ FX_RECT m_GifFrameRect;
+ FX_BOOL m_BmpIsTopBottom;
+ FXCODEC_STATUS m_status;
+};
+#endif
diff --git a/core/src/fxcodec/codec/fx_codec_tiff.cpp b/core/src/fxcodec/codec/fx_codec_tiff.cpp
new file mode 100644
index 0000000000..c90de7a74f
--- /dev/null
+++ b/core/src/fxcodec/codec/fx_codec_tiff.cpp
@@ -0,0 +1,532 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../include/fxcodec/fx_codec.h"
+#include "../../../include/fxge/fx_dib.h"
+#include "codec_int.h"
+extern "C" {
+#include "../fx_tiff/include/fx_tiffiop.h"
+}
+#if !defined(_FPDFAPI_MINI_)
+void* IccLib_CreateTransform_sRGB(const unsigned char* pProfileData, unsigned int dwProfileSize, int nComponents, int intent, FX_DWORD dwSrcFormat = Icc_FORMAT_DEFAULT);
+void IccLib_TranslateImage(void* pTransform, unsigned char* pDest, const unsigned char* pSrc, int pixels);
+void IccLib_DestroyTransform(void* pTransform);
+#endif
+class CCodec_TiffContext : public CFX_Object
+{
+public:
+ CCodec_TiffContext();
+ ~CCodec_TiffContext();
+
+ FX_BOOL InitDecoder(IFX_FileRead* file_ptr);
+ void GetFrames(FX_INT32& frames);
+ FX_BOOL LoadFrameInfo(FX_INT32 frame, FX_DWORD& width, FX_DWORD& height, FX_DWORD& comps, FX_DWORD& bpc, CFX_DIBAttribute* pAttribute);
+ FX_BOOL Decode(CFX_DIBitmap* pDIBitmap);
+
+ union {
+ IFX_FileRead* in;
+ IFX_FileStream* out;
+ } io;
+
+ FX_DWORD offset;
+
+ TIFF* tif_ctx;
+ void* icc_ctx;
+ FX_INT32 frame_num;
+ FX_INT32 frame_cur;
+ FX_BOOL isDecoder;
+private:
+ FX_BOOL isSupport(CFX_DIBitmap* pDIBitmap);
+ void SetPalette(CFX_DIBitmap* pDIBitmap, FX_UINT16 bps);
+ FX_BOOL Decode1bppRGB(CFX_DIBitmap* pDIBitmap, FX_INT32 height, FX_INT32 width, FX_UINT16 bps, FX_UINT16 spp);
+ FX_BOOL Decode8bppRGB(CFX_DIBitmap* pDIBitmap, FX_INT32 height, FX_INT32 width, FX_UINT16 bps, FX_UINT16 spp);
+ FX_BOOL Decode24bppRGB(CFX_DIBitmap* pDIBitmap, FX_INT32 height, FX_INT32 width, FX_UINT16 bps, FX_UINT16 spp);
+};
+CCodec_TiffContext::CCodec_TiffContext()
+{
+ offset = 0;
+ frame_num = 0;
+ frame_cur = 0;
+ io.in = NULL;
+ tif_ctx = NULL;
+ icc_ctx = NULL;
+ isDecoder = TRUE;
+}
+CCodec_TiffContext::~CCodec_TiffContext()
+{
+#if !defined(_FPDFAPI_MINI_)
+ if(icc_ctx) {
+ IccLib_DestroyTransform(icc_ctx);
+ icc_ctx = NULL;
+ }
+#endif
+ if(tif_ctx) {
+ TIFFClose(tif_ctx);
+ }
+}
+static tsize_t _tiff_read(thandle_t context, tdata_t buf, tsize_t length)
+{
+ CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
+ FX_BOOL ret = FALSE;
+ if(pTiffContext->isDecoder) {
+ ret = pTiffContext->io.in->ReadBlock(buf, pTiffContext->offset, length);
+ } else {
+ ret = pTiffContext->io.out->ReadBlock(buf, pTiffContext->offset, length);
+ }
+ if(!ret) {
+ return 0;
+ }
+ pTiffContext->offset += (FX_DWORD)length;
+ return length;
+}
+static tsize_t _tiff_write(thandle_t context, tdata_t buf, tsize_t length)
+{
+ CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
+ ASSERT(!pTiffContext->isDecoder);
+ if(!pTiffContext->io.out->WriteBlock(buf, pTiffContext->offset, length)) {
+ return 0;
+ }
+ pTiffContext->offset += (FX_DWORD)length;
+ return length;
+}
+static toff_t _tiff_seek(thandle_t context, toff_t offset, int whence)
+{
+ CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
+ switch(whence) {
+ case 0:
+ pTiffContext->offset = (FX_DWORD)offset;
+ break;
+ case 1:
+ pTiffContext->offset += (FX_DWORD)offset;
+ break;
+ case 2:
+ if(pTiffContext->isDecoder) {
+ if(pTiffContext->io.in->GetSize() < (FX_FILESIZE)offset) {
+ return -1;
+ }
+ pTiffContext->offset = (FX_DWORD)(pTiffContext->io.in->GetSize() - offset);
+ } else {
+ if(pTiffContext->io.out->GetSize() < (FX_FILESIZE)offset) {
+ return -1;
+ }
+ pTiffContext->offset = (FX_DWORD)(pTiffContext->io.out->GetSize() - offset);
+ }
+ break;
+ default:
+ return -1;
+ }
+ ASSERT(pTiffContext->isDecoder ?
+ (pTiffContext->offset <= (FX_DWORD)pTiffContext->io.in->GetSize()) :
+ TRUE);
+ return pTiffContext->offset;
+}
+static int _tiff_close(thandle_t context)
+{
+ return 0;
+}
+static toff_t _tiff_get_size(thandle_t context)
+{
+ CCodec_TiffContext* pTiffContext = (CCodec_TiffContext*)context;
+ return pTiffContext->isDecoder ?
+ (toff_t)pTiffContext->io.in->GetSize() :
+ (toff_t)pTiffContext->io.out->GetSize();
+}
+static int _tiff_map(thandle_t context, tdata_t*, toff_t*)
+{
+ return 0;
+}
+static void _tiff_unmap(thandle_t context, tdata_t, toff_t) {}
+TIFF* _tiff_open(void* context, const char* mode)
+{
+ TIFF* tif = TIFFClientOpen("Tiff Image", mode,
+ (thandle_t)context,
+ _tiff_read, _tiff_write, _tiff_seek, _tiff_close,
+ _tiff_get_size, _tiff_map, _tiff_unmap);
+ if(tif) {
+ tif->tif_fd = (int)(FX_INTPTR)context;
+ }
+ return tif;
+}
+void* _TIFFmalloc(tmsize_t size)
+{
+ return FXMEM_DefaultAlloc(size, 0);
+}
+void _TIFFfree(void* ptr)
+{
+ FXMEM_DefaultFree(ptr, 0);
+}
+void* _TIFFrealloc(void* ptr, tmsize_t size)
+{
+ return FXMEM_DefaultRealloc(ptr, size, 0);
+}
+void _TIFFmemset(void* ptr, int val, tmsize_t size)
+{
+ FXSYS_memset8(ptr, val, (size_t)size);
+}
+void _TIFFmemcpy(void* des, const void* src, tmsize_t size)
+{
+ FXSYS_memcpy32(des, src, (size_t)size);
+}
+int _TIFFmemcmp(const void* ptr1, const void* ptr2, tmsize_t size)
+{
+ return FXSYS_memcmp32(ptr1, ptr2, (size_t)size);
+}
+static void _tiff_warning_ext(thandle_t context, const char* module, const char* fmt, va_list ap)
+{
+ if(module != NULL) {
+ }
+}
+TIFFErrorHandlerExt _TIFFwarningHandlerExt = _tiff_warning_ext;
+static void _tiff_error_ext(thandle_t context, const char* module, const char* fmt, va_list ap)
+{
+ if(module != NULL) {
+ }
+}
+TIFFErrorHandlerExt _TIFFerrorHandlerExt = _tiff_error_ext;
+int TIFFCmyk2Rgb(thandle_t context, uint8 c, uint8 m, uint8 y, uint8 k, uint8* r, uint8* g, uint8* b)
+{
+ if(context == NULL) {
+ return 0;
+ }
+ CCodec_TiffContext* p = (CCodec_TiffContext*)context;
+#if !defined(_FPDFAPI_MINI_)
+ if(p->icc_ctx) {
+ unsigned char cmyk[4], bgr[3];
+ cmyk[0] = c, cmyk[1] = m, cmyk[2] = y, cmyk[3] = k;
+ IccLib_TranslateImage(p->icc_ctx, bgr, cmyk, 1);
+ *r = bgr[2], *g = bgr[1], *b = bgr[0];
+ } else {
+#endif
+ AdobeCMYK_to_sRGB1(c, m, y, k, *r, *g, *b);
+#if !defined(_FPDFAPI_MINI_)
+ }
+#endif
+ return 1;
+}
+FX_BOOL CCodec_TiffContext::InitDecoder(IFX_FileRead* file_ptr)
+{
+ io.in = file_ptr;
+ tif_ctx = _tiff_open(this, "r");
+ if(tif_ctx == NULL) {
+ return FALSE;
+ }
+ return TRUE;
+}
+void CCodec_TiffContext::GetFrames(FX_INT32& frames)
+{
+ frames = frame_num = TIFFNumberOfDirectories(tif_ctx);
+}
+#define TIFF_EXIF_GETINFO(key, T, tag) {\
+ T val = (T)0;\
+ TIFFGetField(tif_ctx,tag,&val);\
+ if (val) {\
+ (key) = FX_Alloc(FX_BYTE,sizeof(T));\
+ if ((key)) {\
+ T* ptr = (T*)(key);\
+ *ptr = val;\
+ pExif->m_TagVal.SetAt(tag,(key));}}}\
+ (key) = NULL;
+#define TIFF_EXIF_GETSTRINGINFO(key, tag) {\
+ FX_DWORD size = 0;\
+ FX_LPBYTE buf = NULL;\
+ TIFFGetField(tif_ctx,tag,&size, &buf);\
+ if (size && buf) {\
+ (key) = FX_Alloc(FX_BYTE,size);\
+ if ((key)) {\
+ FXSYS_memcpy32((key),buf,size);\
+ pExif->m_TagVal.SetAt(tag,(key));}}}\
+ (key) = NULL;
+template <class T>
+static FX_BOOL Tiff_Exif_GetInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttributeExif* pExif)
+{
+ FX_LPBYTE key = NULL;
+ T val = (T)0;
+ TIFFGetField(tif_ctx, tag, &val);
+ if (val) {
+ (key) = FX_Alloc(FX_BYTE, sizeof(T));
+ if ((key) == NULL) {
+ return FALSE;
+ }
+ T* ptr = (T*)(key);
+ *ptr = val;
+ pExif->m_TagVal.SetAt(tag, (key));
+ return TRUE;
+ }
+ return FALSE;
+}
+static void Tiff_Exif_GetStringInfo(TIFF* tif_ctx, ttag_t tag, CFX_DIBAttributeExif* pExif)
+{
+ FX_LPSTR buf = NULL;
+ FX_LPBYTE key = NULL;
+ TIFFGetField(tif_ctx, tag, &buf);
+ if (buf) {
+ FX_INT32 size = (FX_INT32)FXSYS_strlen(buf);
+ (key) = FX_Alloc(FX_BYTE, size + 1);
+ if ((key) == NULL) {
+ return;
+ }
+ FXSYS_memcpy32((key), buf, size);
+ key[size] = 0;
+ pExif->m_TagVal.SetAt(tag, (key));
+ }
+}
+FX_BOOL CCodec_TiffContext::LoadFrameInfo(FX_INT32 frame, FX_DWORD& width, FX_DWORD& height, FX_DWORD& comps, FX_DWORD& bpc, CFX_DIBAttribute* pAttribute)
+{
+ if (!TIFFSetDirectory(tif_ctx, (uint16)frame)) {
+ return FALSE;
+ }
+ FX_WORD tif_cs;
+ FX_DWORD tif_icc_size = 0;
+ FX_LPBYTE tif_icc_buf = NULL;
+ FX_WORD tif_bpc = 0;
+ FX_WORD tif_cps;
+ FX_DWORD tif_rps;
+ width = height = comps = 0;
+ TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width);
+ TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height);
+ TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &comps);
+ TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &tif_bpc);
+ TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &tif_cs);
+ TIFFGetField(tif_ctx, TIFFTAG_COMPRESSION, &tif_cps);
+ TIFFGetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, &tif_rps);
+ TIFFGetField(tif_ctx, TIFFTAG_ICCPROFILE, &tif_icc_size, &tif_icc_buf);
+ if (pAttribute) {
+ pAttribute->m_wDPIUnit = FXCODEC_RESUNIT_INCH;
+ if (TIFFGetField(tif_ctx, TIFFTAG_RESOLUTIONUNIT, &pAttribute->m_wDPIUnit)) {
+ pAttribute->m_wDPIUnit -= 1;
+ }
+ CFX_DIBAttributeExif* pExif = (CFX_DIBAttributeExif*)pAttribute->m_pExif;
+ pExif->clear();
+ Tiff_Exif_GetInfo<FX_WORD>(tif_ctx, TIFFTAG_ORIENTATION, pExif);
+ if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_XRESOLUTION, pExif)) {
+ FX_FLOAT fDpi = 0;
+ pExif->GetInfo(TIFFTAG_XRESOLUTION, &fDpi);
+ pAttribute->m_nXDPI = (FX_INT32)(fDpi + 0.5f);
+ }
+ if (Tiff_Exif_GetInfo<FX_FLOAT>(tif_ctx, TIFFTAG_YRESOLUTION, pExif)) {
+ FX_FLOAT fDpi = 0;
+ pExif->GetInfo(TIFFTAG_YRESOLUTION, &fDpi);
+ pAttribute->m_nYDPI = (FX_INT32)(fDpi + 0.5f);
+ }
+ Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_IMAGEDESCRIPTION, pExif);
+ Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MAKE, pExif);
+ Tiff_Exif_GetStringInfo(tif_ctx, TIFFTAG_MODEL, pExif);
+ }
+ bpc = tif_bpc;
+ if(tif_rps > height) {
+ TIFFSetField(tif_ctx, TIFFTAG_ROWSPERSTRIP, tif_rps = height);
+ }
+ return TRUE;
+}
+void _TiffBGRA2RGBA(FX_LPBYTE pBuf, FX_INT32 pixel, FX_INT32 spp)
+{
+ register FX_BYTE tmp;
+ for (FX_INT32 n = 0; n < pixel; n++) {
+ tmp = pBuf[0];
+ pBuf[0] = pBuf[2];
+ pBuf[2] = tmp;
+ pBuf += spp;
+ }
+}
+FX_BOOL CCodec_TiffContext::isSupport(CFX_DIBitmap* pDIBitmap)
+{
+ if (TIFFIsTiled(tif_ctx)) {
+ return FALSE;
+ }
+ FX_UINT16 photometric;
+ if (!TIFFGetField(tif_ctx, TIFFTAG_PHOTOMETRIC, &photometric)) {
+ return FALSE;
+ }
+ switch (pDIBitmap->GetBPP()) {
+ case 1:
+ case 8:
+ if (photometric != PHOTOMETRIC_PALETTE) {
+ return FALSE;
+ }
+ break;
+ case 24:
+ if (photometric != PHOTOMETRIC_RGB) {
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+ FX_UINT16 planarconfig;
+ if (!TIFFGetFieldDefaulted(tif_ctx, TIFFTAG_PLANARCONFIG, &planarconfig)) {
+ return FALSE;
+ }
+ if (planarconfig == PLANARCONFIG_SEPARATE) {
+ return FALSE;
+ }
+ return TRUE;
+}
+void CCodec_TiffContext::SetPalette(CFX_DIBitmap* pDIBitmap, FX_UINT16 bps)
+{
+ FX_UINT16 *red_orig, *green_orig, *blue_orig;
+ TIFFGetField(tif_ctx, TIFFTAG_COLORMAP, &red_orig, &green_orig, &blue_orig);
+ for (FX_INT32 i = (1L << bps) - 1; i >= 0; i--) {
+#define CVT(x) ((FX_UINT16)((x)>>8))
+ red_orig[i] = CVT(red_orig[i]);
+ green_orig[i] = CVT(green_orig[i]);
+ blue_orig[i] = CVT(blue_orig[i]);
+#undef CVT
+ }
+ FX_INT32 len = 1 << bps;
+ for(FX_INT32 index = 0; index < len; index++) {
+ FX_DWORD r = red_orig[index] & 0xFF;
+ FX_DWORD g = green_orig[index] & 0xFF;
+ FX_DWORD b = blue_orig[index] & 0xFF;
+ FX_DWORD color = (FX_UINT32)b | ((FX_UINT32)g << 8) | ((FX_UINT32)r << 16) | (((uint32)0xffL) << 24);
+ pDIBitmap->SetPaletteEntry(index, color);
+ }
+}
+FX_BOOL CCodec_TiffContext::Decode1bppRGB(CFX_DIBitmap* pDIBitmap, FX_INT32 height, FX_INT32 width, FX_UINT16 bps, FX_UINT16 spp)
+{
+ if (pDIBitmap->GetBPP() != 1 || spp != 1 || bps != 1 || !isSupport(pDIBitmap)) {
+ return FALSE;
+ }
+ SetPalette(pDIBitmap, bps);
+ FX_INT32 size = (FX_INT32)TIFFScanlineSize(tif_ctx);
+ FX_LPBYTE buf = (FX_LPBYTE)_TIFFmalloc(size);
+ if (buf == NULL) {
+ TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer");
+ return FALSE;
+ }
+ FX_LPBYTE bitMapbuffer = (FX_LPBYTE)pDIBitmap->GetBuffer();
+ FX_DWORD pitch = pDIBitmap->GetPitch();
+ for(FX_INT32 row = 0; row < height; row++) {
+ TIFFReadScanline(tif_ctx, buf, row, 0);
+ for(FX_INT32 j = 0; j < size; j++) {
+ bitMapbuffer[row * pitch + j] = buf[j];
+ }
+ }
+ _TIFFfree(buf);
+ return TRUE;
+}
+FX_BOOL CCodec_TiffContext::Decode8bppRGB(CFX_DIBitmap* pDIBitmap, FX_INT32 height, FX_INT32 width, FX_UINT16 bps, FX_UINT16 spp)
+{
+ if (pDIBitmap->GetBPP() != 8 || spp != 1 || (bps != 4 && bps != 8) || !isSupport(pDIBitmap)) {
+ return FALSE;
+ }
+ SetPalette(pDIBitmap, bps);
+ FX_INT32 size = (FX_INT32)TIFFScanlineSize(tif_ctx);
+ FX_LPBYTE buf = (FX_LPBYTE)_TIFFmalloc(size);
+ if (buf == NULL) {
+ TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer");
+ return FALSE;
+ }
+ FX_LPBYTE bitMapbuffer = (FX_LPBYTE)pDIBitmap->GetBuffer();
+ FX_DWORD pitch = pDIBitmap->GetPitch();
+ for(FX_INT32 row = 0; row < height; row++) {
+ TIFFReadScanline(tif_ctx, buf, row, 0);
+ for(FX_INT32 j = 0; j < size; j++) {
+ switch(bps) {
+ case 4:
+ bitMapbuffer[row * pitch + 2 * j + 0] = (buf[j] & 0xF0) >> 4;
+ bitMapbuffer[row * pitch + 2 * j + 1] = (buf[j] & 0x0F) >> 0;
+ break;
+ case 8:
+ bitMapbuffer[row * pitch + j] = buf[j];
+ break;
+ }
+ }
+ }
+ _TIFFfree(buf);
+ return TRUE;
+}
+FX_BOOL CCodec_TiffContext::Decode24bppRGB(CFX_DIBitmap* pDIBitmap, FX_INT32 height, FX_INT32 width, FX_UINT16 bps, FX_UINT16 spp)
+{
+ if (pDIBitmap->GetBPP() != 24 || !isSupport(pDIBitmap)) {
+ return FALSE;
+ }
+ FX_INT32 size = (FX_INT32)TIFFScanlineSize(tif_ctx);
+ FX_LPBYTE buf = (FX_LPBYTE)_TIFFmalloc(size);
+ if (buf == NULL) {
+ TIFFError(TIFFFileName(tif_ctx), "No space for scanline buffer");
+ return FALSE;
+ }
+ FX_LPBYTE bitMapbuffer = (FX_LPBYTE)pDIBitmap->GetBuffer();
+ FX_DWORD pitch = pDIBitmap->GetPitch();
+ for(FX_INT32 row = 0; row < height; row++) {
+ TIFFReadScanline(tif_ctx, buf, row, 0);
+ for(FX_INT32 j = 0; j < size - 2; j += 3) {
+ bitMapbuffer[row * pitch + j + 0] = buf[j + 2];
+ bitMapbuffer[row * pitch + j + 1] = buf[j + 1];
+ bitMapbuffer[row * pitch + j + 2] = buf[j + 0];
+ }
+ }
+ _TIFFfree(buf);
+ return TRUE;
+}
+FX_BOOL CCodec_TiffContext::Decode(CFX_DIBitmap* pDIBitmap)
+{
+ FX_DWORD img_wid = pDIBitmap->GetWidth();
+ FX_DWORD img_hei = pDIBitmap->GetHeight();
+ FX_DWORD width = 0;
+ FX_DWORD height = 0;
+ TIFFGetField(tif_ctx, TIFFTAG_IMAGEWIDTH, &width);
+ TIFFGetField(tif_ctx, TIFFTAG_IMAGELENGTH, &height);
+ if (img_wid != width || img_hei != height) {
+ return FALSE;
+ }
+ if (pDIBitmap->GetBPP() == 32) {
+ FX_WORD rotation = ORIENTATION_TOPLEFT;
+ TIFFGetField(tif_ctx, TIFFTAG_ORIENTATION, &rotation);
+ if(TIFFReadRGBAImageOriented(tif_ctx, img_wid, img_hei,
+ (uint32*)pDIBitmap->GetBuffer(), rotation, 1)) {
+ for (FX_DWORD row = 0; row < img_hei; row++) {
+ FX_LPBYTE row_buf = (FX_LPBYTE)pDIBitmap->GetScanline(row);
+ _TiffBGRA2RGBA(row_buf, img_wid, 4);
+ }
+ return TRUE;
+ }
+ }
+ FX_UINT16 spp, bps;
+ TIFFGetField(tif_ctx, TIFFTAG_SAMPLESPERPIXEL, &spp);
+ TIFFGetField(tif_ctx, TIFFTAG_BITSPERSAMPLE, &bps);
+ FX_DWORD bpp = bps * spp;
+ if (bpp == 1) {
+ return Decode1bppRGB(pDIBitmap, height, width, bps, spp);
+ } else if (bpp <= 8) {
+ return Decode8bppRGB(pDIBitmap, height, width, bps, spp);
+ } else if (bpp <= 24) {
+ return Decode24bppRGB(pDIBitmap, height, width, bps, spp);
+ }
+ return FALSE;
+}
+FX_LPVOID CCodec_TiffModule::CreateDecoder(IFX_FileRead* file_ptr)
+{
+ CCodec_TiffContext* pDecoder = FX_NEW CCodec_TiffContext;
+ if (pDecoder == NULL) {
+ return NULL;
+ }
+ if (!pDecoder->InitDecoder(file_ptr)) {
+ delete pDecoder;
+ return NULL;
+ }
+ return pDecoder;
+}
+void CCodec_TiffModule::GetFrames(FX_LPVOID ctx, FX_INT32& frames)
+{
+ CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx;
+ pDecoder->GetFrames(frames);
+}
+FX_BOOL CCodec_TiffModule::LoadFrameInfo(FX_LPVOID ctx, FX_INT32 frame, FX_DWORD& width, FX_DWORD& height, FX_DWORD& comps, FX_DWORD& bpc, CFX_DIBAttribute* pAttribute)
+{
+ CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx;
+ return pDecoder->LoadFrameInfo(frame, width, height, comps, bpc, pAttribute);
+}
+FX_BOOL CCodec_TiffModule::Decode(void* ctx, class CFX_DIBitmap* pDIBitmap)
+{
+ CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx;
+ return pDecoder->Decode(pDIBitmap);
+}
+void CCodec_TiffModule::DestroyDecoder(void* ctx)
+{
+ CCodec_TiffContext* pDecoder = (CCodec_TiffContext*)ctx;
+ delete pDecoder;
+}
diff --git a/core/src/fxcodec/fx_lpng/include/fx_png.h b/core/src/fxcodec/fx_lpng/include/fx_png.h
new file mode 100644
index 0000000000..4ef53d0298
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/include/fx_png.h
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/png.h"
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_png.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_png.c
new file mode 100644
index 0000000000..5329a6409d
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_png.c
@@ -0,0 +1,4299 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* png.c - location for general purpose libpng functions
+ *
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef png_libpng_version_1_6_3 Your_png_h_is_not_version_1_6_3;
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature. If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+#ifdef PNG_READ_SUPPORTED
+void PNGAPI
+png_set_sig_bytes(png_structrp png_ptr, int num_bytes)
+{
+ png_debug(1, "in png_set_sig_bytes");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (num_bytes > 8)
+ png_error(png_ptr, "Too many bytes for PNG signature");
+
+ png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+}
+
+/* Checks whether the supplied bytes match the PNG signature. We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance. Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behavior as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+ if (num_to_check > 8)
+ num_to_check = 8;
+
+ else if (num_to_check < 1)
+ return (-1);
+
+ if (start > 7)
+ return (-1);
+
+ if (start + num_to_check > 8)
+ num_to_check = 8 - start;
+
+ return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+#endif /* PNG_READ_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Function to allocate memory for zlib */
+PNG_FUNCTION(voidpf /* PRIVATE */,
+png_zalloc,(voidpf png_ptr, uInt items, uInt size),PNG_ALLOCATED)
+{
+ png_alloc_size_t num_bytes = size;
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ if (items >= (~(png_alloc_size_t)0)/size)
+ {
+ png_warning (png_voidcast(png_structrp, png_ptr),
+ "Potential overflow in png_zalloc()");
+ return NULL;
+ }
+
+ num_bytes *= items;
+ return png_malloc_warn(png_voidcast(png_structrp, png_ptr), num_bytes);
+}
+
+/* Function to free memory for zlib */
+void /* PRIVATE */
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+ png_free(png_voidcast(png_const_structrp,png_ptr), ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's. Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structrp png_ptr)
+{
+ /* The cast is safe because the crc is a 32 bit value. */
+ png_ptr->crc = (png_uint_32)crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data. We can only pass as
+ * much data to this routine as the largest single buffer size. We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structrp png_ptr, png_const_bytep ptr, png_size_t length)
+{
+ int need_crc = 1;
+
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+ /* 'uLong' is defined in zlib.h as unsigned long; this means that on some
+ * systems it is a 64 bit value. crc32, however, returns 32 bits so the
+ * following cast is safe. 'uInt' may be no more than 16 bits, so it is
+ * necessary to perform a loop here.
+ */
+ if (need_crc && length > 0)
+ {
+ uLong crc = png_ptr->crc; /* Should never issue a warning */
+
+ do
+ {
+ uInt safe_length = (uInt)length;
+ if (safe_length == 0)
+ safe_length = (uInt)-1; /* evil, but safe */
+
+ crc = crc32(crc, ptr, safe_length);
+
+ /* The following should never issue compiler warnings; if they do the
+ * target system has characteristics that will probably violate other
+ * assumptions within the libpng code.
+ */
+ ptr += safe_length;
+ length -= safe_length;
+ }
+ while (length > 0);
+
+ /* And the following is always safe because the crc is only 32 bits. */
+ png_ptr->crc = (png_uint_32)crc;
+ }
+}
+
+/* Check a user supplied version number, called from both read and write
+ * functions that create a png_struct.
+ */
+int
+png_user_version_check(png_structrp png_ptr, png_const_charp user_png_ver)
+{
+ if (user_png_ver)
+ {
+ int i = 0;
+
+ do
+ {
+ if (user_png_ver[i] != png_libpng_ver[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ } while (png_libpng_ver[i++]);
+ }
+
+ else
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+ {
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first and third digits (note that when we reach version
+ * 1.10 we will need to check the fourth symbol, namely user_png_ver[3]).
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && (user_png_ver[2] != png_libpng_ver[2] ||
+ user_png_ver[3] != png_libpng_ver[3])) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
+#ifdef PNG_WARNINGS_SUPPORTED
+ size_t pos = 0;
+ char m[128];
+
+ pos = png_safecat(m, (sizeof m), pos,
+ "Application built with libpng-");
+ pos = png_safecat(m, (sizeof m), pos, user_png_ver);
+ pos = png_safecat(m, (sizeof m), pos, " but running with ");
+ pos = png_safecat(m, (sizeof m), pos, png_libpng_ver);
+
+ png_warning(png_ptr, m);
+#endif
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags = 0;
+#endif
+
+ return 0;
+ }
+ }
+
+ /* Success return. */
+ return 1;
+}
+
+/* Generic function to create a png_struct for either read or write - this
+ * contains the common initialization.
+ */
+PNG_FUNCTION(png_structp /* PRIVATE */,
+png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+ png_struct create_struct;
+# ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf create_jmp_buf;
+# endif
+
+ /* This temporary stack-allocated structure is used to provide a place to
+ * build enough context to allow the user provided memory allocator (if any)
+ * to be called.
+ */
+ memset(&create_struct, 0, (sizeof create_struct));
+
+ /* Added at libpng-1.2.6 */
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ create_struct.user_width_max = PNG_USER_WIDTH_MAX;
+ create_struct.user_height_max = PNG_USER_HEIGHT_MAX;
+
+# ifdef PNG_USER_CHUNK_CACHE_MAX
+ /* Added at libpng-1.2.43 and 1.4.0 */
+ create_struct.user_chunk_cache_max = PNG_USER_CHUNK_CACHE_MAX;
+# endif
+
+# ifdef PNG_USER_CHUNK_MALLOC_MAX
+ /* Added at libpng-1.2.43 and 1.4.1, required only for read but exists
+ * in png_struct regardless.
+ */
+ create_struct.user_chunk_malloc_max = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+# endif
+
+ /* The following two API calls simply set fields in png_struct, so it is safe
+ * to do them now even though error handling is not yet set up.
+ */
+# ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(&create_struct, mem_ptr, malloc_fn, free_fn);
+# endif
+
+ /* (*error_fn) can return control to the caller after the error_ptr is set,
+ * this will result in a memory leak unless the error_fn does something
+ * extremely sophisticated. The design lacks merit but is implicit in the
+ * API.
+ */
+ png_set_error_fn(&create_struct, error_ptr, error_fn, warn_fn);
+
+# ifdef PNG_SETJMP_SUPPORTED
+ if (!setjmp(create_jmp_buf))
+ {
+ /* Temporarily fake out the longjmp information until we have
+ * successfully completed this function. This only works if we have
+ * setjmp() support compiled in, but it is safe - this stuff should
+ * never happen.
+ */
+ create_struct.jmp_buf_ptr = &create_jmp_buf;
+ create_struct.jmp_buf_size = 0; /*stack allocation*/
+ create_struct.longjmp_fn = longjmp;
+# else
+ {
+# endif
+ /* Call the general version checker (shared with read and write code):
+ */
+ if (png_user_version_check(&create_struct, user_png_ver))
+ {
+ png_structrp png_ptr = png_voidcast(png_structrp,
+ png_malloc_warn(&create_struct, (sizeof *png_ptr)));
+
+ if (png_ptr != NULL)
+ {
+ /* png_ptr->zstream holds a back-pointer to the png_struct, so
+ * this can only be done now:
+ */
+ create_struct.zstream.zalloc = png_zalloc;
+ create_struct.zstream.zfree = png_zfree;
+ create_struct.zstream.opaque = png_ptr;
+
+# ifdef PNG_SETJMP_SUPPORTED
+ /* Eliminate the local error handling: */
+ create_struct.jmp_buf_ptr = NULL;
+ create_struct.jmp_buf_size = 0;
+ create_struct.longjmp_fn = 0;
+# endif
+
+ *png_ptr = create_struct;
+
+ /* This is the successful return point */
+ return png_ptr;
+ }
+ }
+ }
+
+ /* A longjmp because of a bug in the application storage allocator or a
+ * simple failure to allocate the png_struct.
+ */
+ return NULL;
+}
+
+/* Allocate the memory for an info_struct for the application. */
+PNG_FUNCTION(png_infop,PNGAPI
+png_create_info_struct,(png_const_structrp png_ptr),PNG_ALLOCATED)
+{
+ png_inforp info_ptr;
+
+ png_debug(1, "in png_create_info_struct");
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ /* Use the internal API that does not (or at least should not) error out, so
+ * that this call always returns ok. The application typically sets up the
+ * error handling *after* creating the info_struct because this is the way it
+ * has always been done in 'example.c'.
+ */
+ info_ptr = png_voidcast(png_inforp, png_malloc_base(png_ptr,
+ (sizeof *info_ptr)));
+
+ if (info_ptr != NULL)
+ memset(info_ptr, 0, (sizeof *info_ptr));
+
+ return info_ptr;
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications. From libpng 1.6.0 this function is also used
+ * internally to implement the png_info release part of the 'struct' destroy
+ * APIs. This ensures that all possible approaches free the same data (all of
+ * it).
+ */
+void PNGAPI
+png_destroy_info_struct(png_const_structrp png_ptr, png_infopp info_ptr_ptr)
+{
+ png_inforp info_ptr = NULL;
+
+ png_debug(1, "in png_destroy_info_struct");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ /* Do this first in case of an error below; if the app implements its own
+ * memory management this can lead to png_free calling png_error, which
+ * will abort this routine and return control to the app error handler.
+ * An infinite loop may result if it then tries to free the same info
+ * ptr.
+ */
+ *info_ptr_ptr = NULL;
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+ memset(info_ptr, 0, (sizeof *info_ptr));
+ png_free(png_ptr, info_ptr);
+ }
+}
+
+/* Initialize the info structure. This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead. Use deprecated in 1.6.0, internal use removed (used internally it
+ * is just a memset).
+ *
+ * NOTE: it is almost inconceivable that this API is used because it bypasses
+ * the user-memory mechanism and the user error handling/warning mechanisms in
+ * those cases where it does anything other than a memset.
+ */
+PNG_FUNCTION(void,PNGAPI
+png_info_init_3,(png_infopp ptr_ptr, png_size_t png_info_struct_size),
+ PNG_DEPRECATED)
+{
+ png_inforp info_ptr = *ptr_ptr;
+
+ png_debug(1, "in png_info_init_3");
+
+ if (info_ptr == NULL)
+ return;
+
+ if ((sizeof (png_info)) > png_info_struct_size)
+ {
+ *ptr_ptr = NULL;
+ /* The following line is why this API should not be used: */
+ free(info_ptr);
+ info_ptr = png_voidcast(png_inforp, png_malloc_base(NULL,
+ (sizeof *info_ptr)));
+ *ptr_ptr = info_ptr;
+ }
+
+ /* Set everything to 0 */
+ memset(info_ptr, 0, (sizeof *info_ptr));
+}
+
+/* The following API is not called internally */
+void PNGAPI
+png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr,
+ int freer, png_uint_32 mask)
+{
+ png_debug(1, "in png_data_freer");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (freer == PNG_DESTROY_WILL_FREE_DATA)
+ info_ptr->free_me |= mask;
+
+ else if (freer == PNG_USER_WILL_FREE_DATA)
+ info_ptr->free_me &= ~mask;
+
+ else
+ png_error(png_ptr, "Unknown freer parameter in png_data_freer");
+}
+
+void PNGAPI
+png_free_data(png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 mask,
+ int num)
+{
+ png_debug(1, "in png_free_data");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+#ifdef PNG_TEXT_SUPPORTED
+ /* Free text item num or (if num == -1) all text items */
+ if ((mask & PNG_FREE_TEXT) & info_ptr->free_me)
+ {
+ if (num != -1)
+ {
+ if (info_ptr->text && info_ptr->text[num].key)
+ {
+ png_free(png_ptr, info_ptr->text[num].key);
+ info_ptr->text[num].key = NULL;
+ }
+ }
+
+ else
+ {
+ int i;
+ for (i = 0; i < info_ptr->num_text; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
+ png_free(png_ptr, info_ptr->text);
+ info_ptr->text = NULL;
+ info_ptr->num_text=0;
+ }
+ }
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+ /* Free any tRNS entry */
+ if ((mask & PNG_FREE_TRNS) & info_ptr->free_me)
+ {
+ png_free(png_ptr, info_ptr->trans_alpha);
+ info_ptr->trans_alpha = NULL;
+ info_ptr->valid &= ~PNG_INFO_tRNS;
+ }
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+ /* Free any sCAL entry */
+ if ((mask & PNG_FREE_SCAL) & info_ptr->free_me)
+ {
+ png_free(png_ptr, info_ptr->scal_s_width);
+ png_free(png_ptr, info_ptr->scal_s_height);
+ info_ptr->scal_s_width = NULL;
+ info_ptr->scal_s_height = NULL;
+ info_ptr->valid &= ~PNG_INFO_sCAL;
+ }
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+ /* Free any pCAL entry */
+ if ((mask & PNG_FREE_PCAL) & info_ptr->free_me)
+ {
+ png_free(png_ptr, info_ptr->pcal_purpose);
+ png_free(png_ptr, info_ptr->pcal_units);
+ info_ptr->pcal_purpose = NULL;
+ info_ptr->pcal_units = NULL;
+ if (info_ptr->pcal_params != NULL)
+ {
+ unsigned int i;
+ for (i = 0; i < info_ptr->pcal_nparams; i++)
+ {
+ png_free(png_ptr, info_ptr->pcal_params[i]);
+ info_ptr->pcal_params[i] = NULL;
+ }
+ png_free(png_ptr, info_ptr->pcal_params);
+ info_ptr->pcal_params = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_pCAL;
+ }
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+ /* Free any profile entry */
+ if ((mask & PNG_FREE_ICCP) & info_ptr->free_me)
+ {
+ png_free(png_ptr, info_ptr->iccp_name);
+ png_free(png_ptr, info_ptr->iccp_profile);
+ info_ptr->iccp_name = NULL;
+ info_ptr->iccp_profile = NULL;
+ info_ptr->valid &= ~PNG_INFO_iCCP;
+ }
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+ /* Free a given sPLT entry, or (if num == -1) all sPLT entries */
+ if ((mask & PNG_FREE_SPLT) & info_ptr->free_me)
+ {
+ if (num != -1)
+ {
+ if (info_ptr->splt_palettes)
+ {
+ png_free(png_ptr, info_ptr->splt_palettes[num].name);
+ png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+ info_ptr->splt_palettes[num].name = NULL;
+ info_ptr->splt_palettes[num].entries = NULL;
+ }
+ }
+
+ else
+ {
+ if (info_ptr->splt_palettes_num)
+ {
+ int i;
+ for (i = 0; i < info_ptr->splt_palettes_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, (int)i);
+
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = NULL;
+ info_ptr->splt_palettes_num = 0;
+ }
+ info_ptr->valid &= ~PNG_INFO_sPLT;
+ }
+ }
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+ if ((mask & PNG_FREE_UNKN) & info_ptr->free_me)
+ {
+ if (num != -1)
+ {
+ if (info_ptr->unknown_chunks)
+ {
+ png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+ info_ptr->unknown_chunks[num].data = NULL;
+ }
+ }
+
+ else
+ {
+ int i;
+
+ if (info_ptr->unknown_chunks_num)
+ {
+ for (i = 0; i < info_ptr->unknown_chunks_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, (int)i);
+
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = NULL;
+ info_ptr->unknown_chunks_num = 0;
+ }
+ }
+ }
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+ /* Free any hIST entry */
+ if ((mask & PNG_FREE_HIST) & info_ptr->free_me)
+ {
+ png_free(png_ptr, info_ptr->hist);
+ info_ptr->hist = NULL;
+ info_ptr->valid &= ~PNG_INFO_hIST;
+ }
+#endif
+
+ /* Free any PLTE entry that was internally allocated */
+ if ((mask & PNG_FREE_PLTE) & info_ptr->free_me)
+ {
+ png_free(png_ptr, info_ptr->palette);
+ info_ptr->palette = NULL;
+ info_ptr->valid &= ~PNG_INFO_PLTE;
+ info_ptr->num_palette = 0;
+ }
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* Free any image bits attached to the info structure */
+ if ((mask & PNG_FREE_ROWS) & info_ptr->free_me)
+ {
+ if (info_ptr->row_pointers)
+ {
+ png_uint_32 row;
+ for (row = 0; row < info_ptr->height; row++)
+ {
+ png_free(png_ptr, info_ptr->row_pointers[row]);
+ info_ptr->row_pointers[row] = NULL;
+ }
+ png_free(png_ptr, info_ptr->row_pointers);
+ info_ptr->row_pointers = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_IDAT;
+ }
+#endif
+
+ if (num != -1)
+ mask &= ~PNG_FREE_MUL;
+
+ info_ptr->free_me &= ~mask;
+}
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+
+ return (png_ptr->io_ptr);
+}
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+# ifdef PNG_STDIO_SUPPORTED
+/* Initialize the default input/output functions for the PNG file. If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io(). If you have defined
+ * PNG_NO_STDIO or otherwise disabled PNG_STDIO_SUPPORTED, you must use a
+ * function of your own because "FILE *" isn't necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structrp png_ptr, png_FILE_p fp)
+{
+ png_debug(1, "in png_init_io");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = (png_voidp)fp;
+}
+# endif
+
+#ifdef PNG_SAVE_INT_32_SUPPORTED
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format. If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format. Note that,
+ * the following works correctly even if png_int_32 has more than 32 bits
+ * (compare the more complex code required on read for sign extension.)
+ */
+void PNGAPI
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+#endif
+
+# ifdef PNG_TIME_RFC1123_SUPPORTED
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+int PNGAPI
+png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime)
+{
+ static PNG_CONST char short_months[12][4] =
+ {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ if (out == NULL)
+ return 0;
+
+ if (ptime->year > 9999 /* RFC1123 limitation */ ||
+ ptime->month == 0 || ptime->month > 12 ||
+ ptime->day == 0 || ptime->day > 31 ||
+ ptime->hour > 23 || ptime->minute > 59 ||
+ ptime->second > 60)
+ return 0;
+
+ {
+ size_t pos = 0;
+ char number_buf[5]; /* enough for a four-digit year */
+
+# define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string))
+# define APPEND_NUMBER(format, value)\
+ APPEND_STRING(PNG_FORMAT_NUMBER(number_buf, format, (value)))
+# define APPEND(ch) if (pos < 28) out[pos++] = (ch)
+
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_u, (unsigned)ptime->day);
+ APPEND(' ');
+ APPEND_STRING(short_months[(ptime->month - 1)]);
+ APPEND(' ');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_u, ptime->year);
+ APPEND(' ');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->hour);
+ APPEND(':');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->minute);
+ APPEND(':');
+ APPEND_NUMBER(PNG_NUMBER_FORMAT_02u, (unsigned)ptime->second);
+ APPEND_STRING(" +0000"); /* This reliably terminates the buffer */
+
+# undef APPEND
+# undef APPEND_NUMBER
+# undef APPEND_STRING
+ }
+
+ return 1;
+}
+
+# if PNG_LIBPNG_VER < 10700
+/* To do: remove the following from libpng-1.7 */
+/* Original API that uses a private buffer in png_struct.
+ * Deprecated because it causes png_struct to carry a spurious temporary
+ * buffer (png_struct::time_buffer), better to have the caller pass this in.
+ */
+png_const_charp PNGAPI
+png_convert_to_rfc1123(png_structrp png_ptr, png_const_timep ptime)
+{
+ if (png_ptr != NULL)
+ {
+ /* The only failure above if png_ptr != NULL is from an invalid ptime */
+ if (!png_convert_to_rfc1123_buffer(png_ptr->time_buffer, ptime))
+ png_warning(png_ptr, "Ignoring invalid time value");
+
+ else
+ return png_ptr->time_buffer;
+ }
+
+ return NULL;
+}
+# endif
+# endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+
+png_const_charp PNGAPI
+png_get_copyright(png_const_structrp png_ptr)
+{
+ PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
+#ifdef PNG_STRING_COPYRIGHT
+ return PNG_STRING_COPYRIGHT
+#else
+# ifdef __STDC__
+ return PNG_STRING_NEWLINE \
+ "libpng version 1.6.3 - July 18, 2013" PNG_STRING_NEWLINE \
+ "Copyright (c) 1998-2013 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
+ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
+ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
+ PNG_STRING_NEWLINE;
+# else
+ return "libpng version 1.6.3 - July 18, 2013\
+ Copyright (c) 1998-2013 Glenn Randers-Pehrson\
+ Copyright (c) 1996-1997 Andreas Dilger\
+ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
+# endif
+#endif
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz. To get the version of *.h files
+ * used with your application, print out PNG_LIBPNG_VER_STRING, which
+ * is defined in png.h.
+ * Note: now there is no difference between png_get_libpng_ver() and
+ * png_get_header_ver(). Due to the version_nn_nn_nn typedef guard,
+ * it is guaranteed that png.c uses the correct version of png.h.
+ */
+png_const_charp PNGAPI
+png_get_libpng_ver(png_const_structrp png_ptr)
+{
+ /* Version of *.c files used when building libpng */
+ return png_get_header_ver(png_ptr);
+}
+
+png_const_charp PNGAPI
+png_get_header_ver(png_const_structrp png_ptr)
+{
+ /* Version of *.h files used when building libpng */
+ PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
+ return PNG_LIBPNG_VER_STRING;
+}
+
+png_const_charp PNGAPI
+png_get_header_version(png_const_structrp png_ptr)
+{
+ /* Returns longer string containing both version and date */
+ PNG_UNUSED(png_ptr) /* Silence compiler warning about unused png_ptr */
+#ifdef __STDC__
+ return PNG_HEADER_VERSION_STRING
+# ifndef PNG_READ_SUPPORTED
+ " (NO READ SUPPORT)"
+# endif
+ PNG_STRING_NEWLINE;
+#else
+ return PNG_HEADER_VERSION_STRING;
+#endif
+}
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_const_structrp png_ptr, png_const_bytep chunk_name)
+{
+ /* Check chunk_name and return "keep" value if it's on the list, else 0 */
+ png_const_bytep p, p_end;
+
+ if (png_ptr == NULL || chunk_name == NULL || png_ptr->num_chunk_list == 0)
+ return PNG_HANDLE_CHUNK_AS_DEFAULT;
+
+ p_end = png_ptr->chunk_list;
+ p = p_end + png_ptr->num_chunk_list*5; /* beyond end */
+
+ /* The code is the fifth byte after each four byte string. Historically this
+ * code was always searched from the end of the list, this is no longer
+ * necessary because the 'set' routine handles duplicate entries correcty.
+ */
+ do /* num_chunk_list > 0, so at least one */
+ {
+ p -= 5;
+
+ if (!memcmp(chunk_name, p, 4))
+ return p[4];
+ }
+ while (p > p_end);
+
+ /* This means that known chunks should be processed and unknown chunks should
+ * be handled according to the value of png_ptr->unknown_default; this can be
+ * confusing because, as a result, there are two levels of defaulting for
+ * unknown chunks.
+ */
+ return PNG_HANDLE_CHUNK_AS_DEFAULT;
+}
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+int /* PRIVATE */
+png_chunk_unknown_handling(png_const_structrp png_ptr, png_uint_32 chunk_name)
+{
+ png_byte chunk_string[5];
+
+ PNG_CSTRING_FROM_CHUNK(chunk_string, chunk_name);
+ return png_handle_as_unknown(png_ptr, chunk_string);
+}
+#endif /* READ_UNKNOWN_CHUNKS */
+#endif /* SET_UNKNOWN_CHUNKS */
+
+#ifdef PNG_READ_SUPPORTED
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return Z_STREAM_ERROR;
+
+ /* WARNING: this resets the window bits to the maximum! */
+ return (inflateReset(&png_ptr->zstream));
+}
+#endif /* PNG_READ_SUPPORTED */
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+ /* Version of *.c files used when building libpng */
+ return((png_uint_32)PNG_LIBPNG_VER);
+}
+
+
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
+ * If it doesn't 'ret' is used to set it to something appropriate, even in cases
+ * like Z_OK or Z_STREAM_END where the error code is apparently a success code.
+ */
+void /* PRIVATE */
+png_zstream_error(png_structrp png_ptr, int ret)
+{
+ /* Translate 'ret' into an appropriate error string, priority is given to the
+ * one in zstream if set. This always returns a string, even in cases like
+ * Z_OK or Z_STREAM_END where the error code is a success code.
+ */
+ if (png_ptr->zstream.msg == NULL) switch (ret)
+ {
+ default:
+ case Z_OK:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
+ break;
+
+ case Z_STREAM_END:
+ /* Normal exit */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
+ break;
+
+ case Z_NEED_DICT:
+ /* This means the deflate stream did not have a dictionary; this
+ * indicates a bogus PNG.
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
+ break;
+
+ case Z_ERRNO:
+ /* gz APIs only: should not happen */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
+ break;
+
+ case Z_STREAM_ERROR:
+ /* internal libpng error */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
+ break;
+
+ case Z_DATA_ERROR:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
+ break;
+
+ case Z_MEM_ERROR:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
+ break;
+
+ case Z_BUF_ERROR:
+ /* End of input or output; not a problem if the caller is doing
+ * incremental read or write.
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
+ break;
+
+ case Z_VERSION_ERROR:
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
+ break;
+
+ case PNG_UNEXPECTED_ZLIB_RETURN:
+ /* Compile errors here mean that zlib now uses the value co-opted in
+ * pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
+ * and change pngpriv.h. Note that this message is "... return",
+ * whereas the default/Z_OK one is "... return code".
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
+ break;
+ }
+}
+
+/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
+ * at libpng 1.5.5!
+ */
+
+/* Added at libpng version 1.2.34 and 1.4.0 (moved from pngset.c) */
+#ifdef PNG_GAMMA_SUPPORTED /* always set if COLORSPACE */
+static int
+png_colorspace_check_gamma(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA, int from)
+ /* This is called to check a new gamma value against an existing one. The
+ * routine returns false if the new gamma value should not be written.
+ *
+ * 'from' says where the new gamma value comes from:
+ *
+ * 0: the new gamma value is the libpng estimate for an ICC profile
+ * 1: the new gamma value comes from a gAMA chunk
+ * 2: the new gamma value comes from an sRGB chunk
+ */
+{
+ png_fixed_point gtest;
+
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_GAMMA) != 0 &&
+ (!png_muldiv(&gtest, colorspace->gamma, PNG_FP_1, gAMA) ||
+ png_gamma_significant(gtest)))
+ {
+ /* Either this is an sRGB image, in which case the calculated gamma
+ * approximation should match, or this is an image with a profile and the
+ * value libpng calculates for the gamma of the profile does not match the
+ * value recorded in the file. The former, sRGB, case is an error, the
+ * latter is just a warning.
+ */
+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0 || from == 2)
+ {
+ png_chunk_report(png_ptr, "gamma value does not match sRGB",
+ PNG_CHUNK_ERROR);
+ /* Do not overwrite an sRGB value */
+ return from == 2;
+ }
+
+ else /* sRGB tag not involved */
+ {
+ png_chunk_report(png_ptr, "gamma value does not match libpng estimate",
+ PNG_CHUNK_WARNING);
+ return from == 1;
+ }
+ }
+
+ return 1;
+}
+
+void /* PRIVATE */
+png_colorspace_set_gamma(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA)
+{
+ /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't
+ * occur. Since the fixed point representation is assymetrical it is
+ * possible for 1/gamma to overflow the limit of 21474 and this means the
+ * gamma value must be at least 5/100000 and hence at most 20000.0. For
+ * safety the limits here are a little narrower. The values are 0.00016 to
+ * 6250.0, which are truly ridiculous gamma values (and will produce
+ * displays that are all black or all white.)
+ *
+ * In 1.6.0 this test replaces the ones in pngrutil.c, in the gAMA chunk
+ * handling code, which only required the value to be >0.
+ */
+ png_const_charp errmsg;
+
+ if (gAMA < 16 || gAMA > 625000000)
+ errmsg = "gamma value out of range";
+
+# ifdef PNG_READ_gAMA_SUPPORTED
+ /* Allow the application to set the gamma value more than once */
+ else if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ (colorspace->flags & PNG_COLORSPACE_FROM_gAMA) != 0)
+ errmsg = "duplicate";
+# endif
+
+ /* Do nothing if the colorspace is already invalid */
+ else if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return;
+
+ else
+ {
+ if (png_colorspace_check_gamma(png_ptr, colorspace, gAMA, 1/*from gAMA*/))
+ {
+ /* Store this gamma value. */
+ colorspace->gamma = gAMA;
+ colorspace->flags |=
+ (PNG_COLORSPACE_HAVE_GAMMA | PNG_COLORSPACE_FROM_gAMA);
+ }
+
+ /* At present if the check_gamma test fails the gamma of the colorspace is
+ * not updated however the colorspace is not invalidated. This
+ * corresponds to the case where the existing gamma comes from an sRGB
+ * chunk or profile. An error message has already been output.
+ */
+ return;
+ }
+
+ /* Error exit - errmsg has been set. */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_chunk_report(png_ptr, errmsg, PNG_CHUNK_WRITE_ERROR);
+}
+
+void /* PRIVATE */
+png_colorspace_sync_info(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ {
+ /* Everything is invalid */
+ info_ptr->valid &= ~(PNG_INFO_gAMA|PNG_INFO_cHRM|PNG_INFO_sRGB|
+ PNG_INFO_iCCP);
+
+# ifdef PNG_COLORSPACE_SUPPORTED
+ /* Clean up the iCCP profile now if it won't be used. */
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, -1/*not used*/);
+# else
+ PNG_UNUSED(png_ptr)
+# endif
+ }
+
+ else
+ {
+# ifdef PNG_COLORSPACE_SUPPORTED
+ /* Leave the INFO_iCCP flag set if the pngset.c code has already set
+ * it; this allows a PNG to contain a profile which matches sRGB and
+ * yet still have that profile retrievable by the application.
+ */
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_MATCHES_sRGB)
+ info_ptr->valid |= PNG_INFO_sRGB;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_sRGB;
+
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS)
+ info_ptr->valid |= PNG_INFO_cHRM;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_cHRM;
+# endif
+
+ if (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA)
+ info_ptr->valid |= PNG_INFO_gAMA;
+
+ else
+ info_ptr->valid &= ~PNG_INFO_gAMA;
+ }
+}
+
+#ifdef PNG_READ_SUPPORTED
+void /* PRIVATE */
+png_colorspace_sync(png_const_structrp png_ptr, png_inforp info_ptr)
+{
+ if (info_ptr == NULL) /* reduce code size; check here not in the caller */
+ return;
+
+ info_ptr->colorspace = png_ptr->colorspace;
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+#endif
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* Added at libpng-1.5.5 to support read and write of true CIEXYZ values for
+ * cHRM, as opposed to using chromaticities. These internal APIs return
+ * non-zero on a parameter error. The X, Y and Z values are required to be
+ * positive and less than 1.0.
+ */
+static int
+png_xy_from_XYZ(png_xy *xy, const png_XYZ *XYZ)
+{
+ png_int_32 d, dwhite, whiteX, whiteY;
+
+ d = XYZ->red_X + XYZ->red_Y + XYZ->red_Z;
+ if (!png_muldiv(&xy->redx, XYZ->red_X, PNG_FP_1, d)) return 1;
+ if (!png_muldiv(&xy->redy, XYZ->red_Y, PNG_FP_1, d)) return 1;
+ dwhite = d;
+ whiteX = XYZ->red_X;
+ whiteY = XYZ->red_Y;
+
+ d = XYZ->green_X + XYZ->green_Y + XYZ->green_Z;
+ if (!png_muldiv(&xy->greenx, XYZ->green_X, PNG_FP_1, d)) return 1;
+ if (!png_muldiv(&xy->greeny, XYZ->green_Y, PNG_FP_1, d)) return 1;
+ dwhite += d;
+ whiteX += XYZ->green_X;
+ whiteY += XYZ->green_Y;
+
+ d = XYZ->blue_X + XYZ->blue_Y + XYZ->blue_Z;
+ if (!png_muldiv(&xy->bluex, XYZ->blue_X, PNG_FP_1, d)) return 1;
+ if (!png_muldiv(&xy->bluey, XYZ->blue_Y, PNG_FP_1, d)) return 1;
+ dwhite += d;
+ whiteX += XYZ->blue_X;
+ whiteY += XYZ->blue_Y;
+
+ /* The reference white is simply the sum of the end-point (X,Y,Z) vectors,
+ * thus:
+ */
+ if (!png_muldiv(&xy->whitex, whiteX, PNG_FP_1, dwhite)) return 1;
+ if (!png_muldiv(&xy->whitey, whiteY, PNG_FP_1, dwhite)) return 1;
+
+ return 0;
+}
+
+static int
+png_XYZ_from_xy(png_XYZ *XYZ, const png_xy *xy)
+{
+ png_fixed_point red_inverse, green_inverse, blue_scale;
+ png_fixed_point left, right, denominator;
+
+ /* Check xy and, implicitly, z. Note that wide gamut color spaces typically
+ * have end points with 0 tristimulus values (these are impossible end
+ * points, but they are used to cover the possible colors.)
+ */
+ if (xy->redx < 0 || xy->redx > PNG_FP_1) return 1;
+ if (xy->redy < 0 || xy->redy > PNG_FP_1-xy->redx) return 1;
+ if (xy->greenx < 0 || xy->greenx > PNG_FP_1) return 1;
+ if (xy->greeny < 0 || xy->greeny > PNG_FP_1-xy->greenx) return 1;
+ if (xy->bluex < 0 || xy->bluex > PNG_FP_1) return 1;
+ if (xy->bluey < 0 || xy->bluey > PNG_FP_1-xy->bluex) return 1;
+ if (xy->whitex < 0 || xy->whitex > PNG_FP_1) return 1;
+ if (xy->whitey < 0 || xy->whitey > PNG_FP_1-xy->whitex) return 1;
+
+ /* The reverse calculation is more difficult because the original tristimulus
+ * value had 9 independent values (red,green,blue)x(X,Y,Z) however only 8
+ * derived values were recorded in the cHRM chunk;
+ * (red,green,blue,white)x(x,y). This loses one degree of freedom and
+ * therefore an arbitrary ninth value has to be introduced to undo the
+ * original transformations.
+ *
+ * Think of the original end-points as points in (X,Y,Z) space. The
+ * chromaticity values (c) have the property:
+ *
+ * C
+ * c = ---------
+ * X + Y + Z
+ *
+ * For each c (x,y,z) from the corresponding original C (X,Y,Z). Thus the
+ * three chromaticity values (x,y,z) for each end-point obey the
+ * relationship:
+ *
+ * x + y + z = 1
+ *
+ * This describes the plane in (X,Y,Z) space that intersects each axis at the
+ * value 1.0; call this the chromaticity plane. Thus the chromaticity
+ * calculation has scaled each end-point so that it is on the x+y+z=1 plane
+ * and chromaticity is the intersection of the vector from the origin to the
+ * (X,Y,Z) value with the chromaticity plane.
+ *
+ * To fully invert the chromaticity calculation we would need the three
+ * end-point scale factors, (red-scale, green-scale, blue-scale), but these
+ * were not recorded. Instead we calculated the reference white (X,Y,Z) and
+ * recorded the chromaticity of this. The reference white (X,Y,Z) would have
+ * given all three of the scale factors since:
+ *
+ * color-C = color-c * color-scale
+ * white-C = red-C + green-C + blue-C
+ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
+ *
+ * But cHRM records only white-x and white-y, so we have lost the white scale
+ * factor:
+ *
+ * white-C = white-c*white-scale
+ *
+ * To handle this the inverse transformation makes an arbitrary assumption
+ * about white-scale:
+ *
+ * Assume: white-Y = 1.0
+ * Hence: white-scale = 1/white-y
+ * Or: red-Y + green-Y + blue-Y = 1.0
+ *
+ * Notice the last statement of the assumption gives an equation in three of
+ * the nine values we want to calculate. 8 more equations come from the
+ * above routine as summarised at the top above (the chromaticity
+ * calculation):
+ *
+ * Given: color-x = color-X / (color-X + color-Y + color-Z)
+ * Hence: (color-x - 1)*color-X + color.x*color-Y + color.x*color-Z = 0
+ *
+ * This is 9 simultaneous equations in the 9 variables "color-C" and can be
+ * solved by Cramer's rule. Cramer's rule requires calculating 10 9x9 matrix
+ * determinants, however this is not as bad as it seems because only 28 of
+ * the total of 90 terms in the various matrices are non-zero. Nevertheless
+ * Cramer's rule is notoriously numerically unstable because the determinant
+ * calculation involves the difference of large, but similar, numbers. It is
+ * difficult to be sure that the calculation is stable for real world values
+ * and it is certain that it becomes unstable where the end points are close
+ * together.
+ *
+ * So this code uses the perhaps slightly less optimal but more
+ * understandable and totally obvious approach of calculating color-scale.
+ *
+ * This algorithm depends on the precision in white-scale and that is
+ * (1/white-y), so we can immediately see that as white-y approaches 0 the
+ * accuracy inherent in the cHRM chunk drops off substantially.
+ *
+ * libpng arithmetic: a simple invertion of the above equations
+ * ------------------------------------------------------------
+ *
+ * white_scale = 1/white-y
+ * white-X = white-x * white-scale
+ * white-Y = 1.0
+ * white-Z = (1 - white-x - white-y) * white_scale
+ *
+ * white-C = red-C + green-C + blue-C
+ * = red-c*red-scale + green-c*green-scale + blue-c*blue-scale
+ *
+ * This gives us three equations in (red-scale,green-scale,blue-scale) where
+ * all the coefficients are now known:
+ *
+ * red-x*red-scale + green-x*green-scale + blue-x*blue-scale
+ * = white-x/white-y
+ * red-y*red-scale + green-y*green-scale + blue-y*blue-scale = 1
+ * red-z*red-scale + green-z*green-scale + blue-z*blue-scale
+ * = (1 - white-x - white-y)/white-y
+ *
+ * In the last equation color-z is (1 - color-x - color-y) so we can add all
+ * three equations together to get an alternative third:
+ *
+ * red-scale + green-scale + blue-scale = 1/white-y = white-scale
+ *
+ * So now we have a Cramer's rule solution where the determinants are just
+ * 3x3 - far more tractible. Unfortunately 3x3 determinants still involve
+ * multiplication of three coefficients so we can't guarantee to avoid
+ * overflow in the libpng fixed point representation. Using Cramer's rule in
+ * floating point is probably a good choice here, but it's not an option for
+ * fixed point. Instead proceed to simplify the first two equations by
+ * eliminating what is likely to be the largest value, blue-scale:
+ *
+ * blue-scale = white-scale - red-scale - green-scale
+ *
+ * Hence:
+ *
+ * (red-x - blue-x)*red-scale + (green-x - blue-x)*green-scale =
+ * (white-x - blue-x)*white-scale
+ *
+ * (red-y - blue-y)*red-scale + (green-y - blue-y)*green-scale =
+ * 1 - blue-y*white-scale
+ *
+ * And now we can trivially solve for (red-scale,green-scale):
+ *
+ * green-scale =
+ * (white-x - blue-x)*white-scale - (red-x - blue-x)*red-scale
+ * -----------------------------------------------------------
+ * green-x - blue-x
+ *
+ * red-scale =
+ * 1 - blue-y*white-scale - (green-y - blue-y) * green-scale
+ * ---------------------------------------------------------
+ * red-y - blue-y
+ *
+ * Hence:
+ *
+ * red-scale =
+ * ( (green-x - blue-x) * (white-y - blue-y) -
+ * (green-y - blue-y) * (white-x - blue-x) ) / white-y
+ * -------------------------------------------------------------------------
+ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
+ *
+ * green-scale =
+ * ( (red-y - blue-y) * (white-x - blue-x) -
+ * (red-x - blue-x) * (white-y - blue-y) ) / white-y
+ * -------------------------------------------------------------------------
+ * (green-x - blue-x)*(red-y - blue-y)-(green-y - blue-y)*(red-x - blue-x)
+ *
+ * Accuracy:
+ * The input values have 5 decimal digits of accuracy. The values are all in
+ * the range 0 < value < 1, so simple products are in the same range but may
+ * need up to 10 decimal digits to preserve the original precision and avoid
+ * underflow. Because we are using a 32-bit signed representation we cannot
+ * match this; the best is a little over 9 decimal digits, less than 10.
+ *
+ * The approach used here is to preserve the maximum precision within the
+ * signed representation. Because the red-scale calculation above uses the
+ * difference between two products of values that must be in the range -1..+1
+ * it is sufficient to divide the product by 7; ceil(100,000/32767*2). The
+ * factor is irrelevant in the calculation because it is applied to both
+ * numerator and denominator.
+ *
+ * Note that the values of the differences of the products of the
+ * chromaticities in the above equations tend to be small, for example for
+ * the sRGB chromaticities they are:
+ *
+ * red numerator: -0.04751
+ * green numerator: -0.08788
+ * denominator: -0.2241 (without white-y multiplication)
+ *
+ * The resultant Y coefficients from the chromaticities of some widely used
+ * color space definitions are (to 15 decimal places):
+ *
+ * sRGB
+ * 0.212639005871510 0.715168678767756 0.072192315360734
+ * Kodak ProPhoto
+ * 0.288071128229293 0.711843217810102 0.000085653960605
+ * Adobe RGB
+ * 0.297344975250536 0.627363566255466 0.075291458493998
+ * Adobe Wide Gamut RGB
+ * 0.258728243040113 0.724682314948566 0.016589442011321
+ */
+ /* By the argument, above overflow should be impossible here. The return
+ * value of 2 indicates an internal error to the caller.
+ */
+ if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->redy - xy->bluey, 7))
+ return 2;
+ if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->redx - xy->bluex, 7))
+ return 2;
+ denominator = left - right;
+
+ /* Now find the red numerator. */
+ if (!png_muldiv(&left, xy->greenx-xy->bluex, xy->whitey-xy->bluey, 7))
+ return 2;
+ if (!png_muldiv(&right, xy->greeny-xy->bluey, xy->whitex-xy->bluex, 7))
+ return 2;
+
+ /* Overflow is possible here and it indicates an extreme set of PNG cHRM
+ * chunk values. This calculation actually returns the reciprocal of the
+ * scale value because this allows us to delay the multiplication of white-y
+ * into the denominator, which tends to produce a small number.
+ */
+ if (!png_muldiv(&red_inverse, xy->whitey, denominator, left-right) ||
+ red_inverse <= xy->whitey /* r+g+b scales = white scale */)
+ return 1;
+
+ /* Similarly for green_inverse: */
+ if (!png_muldiv(&left, xy->redy-xy->bluey, xy->whitex-xy->bluex, 7))
+ return 2;
+ if (!png_muldiv(&right, xy->redx-xy->bluex, xy->whitey-xy->bluey, 7))
+ return 2;
+ if (!png_muldiv(&green_inverse, xy->whitey, denominator, left-right) ||
+ green_inverse <= xy->whitey)
+ return 1;
+
+ /* And the blue scale, the checks above guarantee this can't overflow but it
+ * can still produce 0 for extreme cHRM values.
+ */
+ blue_scale = png_reciprocal(xy->whitey) - png_reciprocal(red_inverse) -
+ png_reciprocal(green_inverse);
+ if (blue_scale <= 0) return 1;
+
+
+ /* And fill in the png_XYZ: */
+ if (!png_muldiv(&XYZ->red_X, xy->redx, PNG_FP_1, red_inverse)) return 1;
+ if (!png_muldiv(&XYZ->red_Y, xy->redy, PNG_FP_1, red_inverse)) return 1;
+ if (!png_muldiv(&XYZ->red_Z, PNG_FP_1 - xy->redx - xy->redy, PNG_FP_1,
+ red_inverse))
+ return 1;
+
+ if (!png_muldiv(&XYZ->green_X, xy->greenx, PNG_FP_1, green_inverse))
+ return 1;
+ if (!png_muldiv(&XYZ->green_Y, xy->greeny, PNG_FP_1, green_inverse))
+ return 1;
+ if (!png_muldiv(&XYZ->green_Z, PNG_FP_1 - xy->greenx - xy->greeny, PNG_FP_1,
+ green_inverse))
+ return 1;
+
+ if (!png_muldiv(&XYZ->blue_X, xy->bluex, blue_scale, PNG_FP_1)) return 1;
+ if (!png_muldiv(&XYZ->blue_Y, xy->bluey, blue_scale, PNG_FP_1)) return 1;
+ if (!png_muldiv(&XYZ->blue_Z, PNG_FP_1 - xy->bluex - xy->bluey, blue_scale,
+ PNG_FP_1))
+ return 1;
+
+ return 0; /*success*/
+}
+
+static int
+png_XYZ_normalize(png_XYZ *XYZ)
+{
+ png_int_32 Y;
+
+ if (XYZ->red_Y < 0 || XYZ->green_Y < 0 || XYZ->blue_Y < 0 ||
+ XYZ->red_X < 0 || XYZ->green_X < 0 || XYZ->blue_X < 0 ||
+ XYZ->red_Z < 0 || XYZ->green_Z < 0 || XYZ->blue_Z < 0)
+ return 1;
+
+ /* Normalize by scaling so the sum of the end-point Y values is PNG_FP_1.
+ * IMPLEMENTATION NOTE: ANSI requires signed overflow not to occur, therefore
+ * relying on addition of two positive values producing a negative one is not
+ * safe.
+ */
+ Y = XYZ->red_Y;
+ if (0x7fffffff - Y < XYZ->green_X) return 1;
+ Y += XYZ->green_Y;
+ if (0x7fffffff - Y < XYZ->blue_X) return 1;
+ Y += XYZ->blue_Y;
+
+ if (Y != PNG_FP_1)
+ {
+ if (!png_muldiv(&XYZ->red_X, XYZ->red_X, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->red_Y, XYZ->red_Y, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->red_Z, XYZ->red_Z, PNG_FP_1, Y)) return 1;
+
+ if (!png_muldiv(&XYZ->green_X, XYZ->green_X, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->green_Y, XYZ->green_Y, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->green_Z, XYZ->green_Z, PNG_FP_1, Y)) return 1;
+
+ if (!png_muldiv(&XYZ->blue_X, XYZ->blue_X, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->blue_Y, XYZ->blue_Y, PNG_FP_1, Y)) return 1;
+ if (!png_muldiv(&XYZ->blue_Z, XYZ->blue_Z, PNG_FP_1, Y)) return 1;
+ }
+
+ return 0;
+}
+
+static int
+png_colorspace_endpoints_match(const png_xy *xy1, const png_xy *xy2, int delta)
+{
+ /* Allow an error of +/-0.01 (absolute value) on each chromaticity */
+ return !(PNG_OUT_OF_RANGE(xy1->whitex, xy2->whitex,delta) ||
+ PNG_OUT_OF_RANGE(xy1->whitey, xy2->whitey,delta) ||
+ PNG_OUT_OF_RANGE(xy1->redx, xy2->redx, delta) ||
+ PNG_OUT_OF_RANGE(xy1->redy, xy2->redy, delta) ||
+ PNG_OUT_OF_RANGE(xy1->greenx, xy2->greenx,delta) ||
+ PNG_OUT_OF_RANGE(xy1->greeny, xy2->greeny,delta) ||
+ PNG_OUT_OF_RANGE(xy1->bluex, xy2->bluex, delta) ||
+ PNG_OUT_OF_RANGE(xy1->bluey, xy2->bluey, delta));
+}
+
+/* Added in libpng-1.6.0, a different check for the validity of a set of cHRM
+ * chunk chromaticities. Earlier checks used to simply look for the overflow
+ * condition (where the determinant of the matrix to solve for XYZ ends up zero
+ * because the chromaticity values are not all distinct.) Despite this it is
+ * theoretically possible to produce chromaticities that are apparently valid
+ * but that rapidly degrade to invalid, potentially crashing, sets because of
+ * arithmetic inaccuracies when calculations are performed on them. The new
+ * check is to round-trip xy -> XYZ -> xy and then check that the result is
+ * within a small percentage of the original.
+ */
+static int
+png_colorspace_check_xy(png_XYZ *XYZ, const png_xy *xy)
+{
+ int result;
+ png_xy xy_test;
+
+ /* As a side-effect this routine also returns the XYZ endpoints. */
+ result = png_XYZ_from_xy(XYZ, xy);
+ if (result) return result;
+
+ result = png_xy_from_XYZ(&xy_test, XYZ);
+ if (result) return result;
+
+ if (png_colorspace_endpoints_match(xy, &xy_test,
+ 5/*actually, the math is pretty accurate*/))
+ return 0;
+
+ /* Too much slip */
+ return 1;
+}
+
+/* This is the check going the other way. The XYZ is modified to normalize it
+ * (another side-effect) and the xy chromaticities are returned.
+ */
+static int
+png_colorspace_check_XYZ(png_xy *xy, png_XYZ *XYZ)
+{
+ int result;
+ png_XYZ XYZtemp;
+
+ result = png_XYZ_normalize(XYZ);
+ if (result) return result;
+
+ result = png_xy_from_XYZ(xy, XYZ);
+ if (result) return result;
+
+ XYZtemp = *XYZ;
+ return png_colorspace_check_xy(&XYZtemp, xy);
+}
+
+/* Used to check for an endpoint match against sRGB */
+static const png_xy sRGB_xy = /* From ITU-R BT.709-3 */
+{
+ /* color x y */
+ /* red */ 64000, 33000,
+ /* green */ 30000, 60000,
+ /* blue */ 15000, 6000,
+ /* white */ 31270, 32900
+};
+
+static int
+png_colorspace_set_xy_and_XYZ(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_xy *xy, const png_XYZ *XYZ,
+ int preferred)
+{
+ if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return 0;
+
+ /* The consistency check is performed on the chromaticities; this factors out
+ * variations because of the normalization (or not) of the end point Y
+ * values.
+ */
+ if (preferred < 2 && (colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
+ {
+ /* The end points must be reasonably close to any we already have. The
+ * following allows an error of up to +/-.001
+ */
+ if (!png_colorspace_endpoints_match(xy, &colorspace->end_points_xy, 100))
+ {
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "inconsistent chromaticities");
+ return 0; /* failed */
+ }
+
+ /* Only overwrite with preferred values */
+ if (!preferred)
+ return 1; /* ok, but no change */
+ }
+
+ colorspace->end_points_xy = *xy;
+ colorspace->end_points_XYZ = *XYZ;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_ENDPOINTS;
+
+ /* The end points are normally quoted to two decimal digits, so allow +/-0.01
+ * on this test.
+ */
+ if (png_colorspace_endpoints_match(xy, &sRGB_xy, 1000))
+ colorspace->flags |= PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB;
+
+ else
+ colorspace->flags &= PNG_COLORSPACE_CANCEL(
+ PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+ return 2; /* ok and changed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_chromaticities(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_xy *xy, int preferred)
+{
+ /* We must check the end points to ensure they are reasonable - in the past
+ * color management systems have crashed as a result of getting bogus
+ * colorant values, while this isn't the fault of libpng it is the
+ * responsibility of libpng because PNG carries the bomb and libpng is in a
+ * position to protect against it.
+ */
+ png_XYZ XYZ;
+
+ switch (png_colorspace_check_xy(&XYZ, xy))
+ {
+ case 0: /* success */
+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, xy, &XYZ,
+ preferred);
+
+ case 1:
+ /* We can't invert the chromaticities so we can't produce value XYZ
+ * values. Likely as not a color management system will fail too.
+ */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "invalid chromaticities");
+ break;
+
+ default:
+ /* libpng is broken; this should be a warning but if it happens we
+ * want error reports so for the moment it is an error.
+ */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_error(png_ptr, "internal error checking chromaticities");
+ break;
+ }
+
+ return 0; /* failed */
+}
+
+int /* PRIVATE */
+png_colorspace_set_endpoints(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, const png_XYZ *XYZ_in, int preferred)
+{
+ png_XYZ XYZ = *XYZ_in;
+ png_xy xy;
+
+ switch (png_colorspace_check_XYZ(&xy, &XYZ))
+ {
+ case 0:
+ return png_colorspace_set_xy_and_XYZ(png_ptr, colorspace, &xy, &XYZ,
+ preferred);
+
+ case 1:
+ /* End points are invalid. */
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_benign_error(png_ptr, "invalid end points");
+ break;
+
+ default:
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+ png_error(png_ptr, "internal error checking chromaticities");
+ break;
+ }
+
+ return 0; /* failed */
+}
+
+#if defined(PNG_sRGB_SUPPORTED) || defined(PNG_iCCP_SUPPORTED)
+/* Error message generation */
+static char
+png_icc_tag_char(png_uint_32 byte)
+{
+ byte &= 0xff;
+ if (byte >= 32 && byte <= 126)
+ return (char)byte;
+ else
+ return '?';
+}
+
+static void
+png_icc_tag_name(char *name, png_uint_32 tag)
+{
+ name[0] = '\'';
+ name[1] = png_icc_tag_char(tag >> 24);
+ name[2] = png_icc_tag_char(tag >> 16);
+ name[3] = png_icc_tag_char(tag >> 8);
+ name[4] = png_icc_tag_char(tag );
+ name[5] = '\'';
+}
+
+static int
+is_ICC_signature_char(png_alloc_size_t it)
+{
+ return it == 32 || (it >= 48 && it <= 57) || (it >= 65 && it <= 90) ||
+ (it >= 97 && it <= 122);
+}
+
+static int is_ICC_signature(png_alloc_size_t it)
+{
+ return is_ICC_signature_char(it >> 24) /* checks all the top bits */ &&
+ is_ICC_signature_char((it >> 16) & 0xff) &&
+ is_ICC_signature_char((it >> 8) & 0xff) &&
+ is_ICC_signature_char(it & 0xff);
+}
+
+static int
+png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_alloc_size_t value, png_const_charp reason)
+{
+ size_t pos;
+ char message[196]; /* see below for calculation */
+
+ if (colorspace != NULL)
+ colorspace->flags |= PNG_COLORSPACE_INVALID;
+
+ pos = png_safecat(message, (sizeof message), 0, "profile '"); /* 9 chars */
+ pos = png_safecat(message, pos+79, pos, name); /* Truncate to 79 chars */
+ pos = png_safecat(message, (sizeof message), pos, "': "); /* +2 = 90 */
+ if (is_ICC_signature(value))
+ {
+ /* So 'value' is at most 4 bytes and the following cast is safe */
+ png_icc_tag_name(message+pos, (png_uint_32)value);
+ pos += 6; /* total +8; less than the else clause */
+ message[pos++] = ':';
+ message[pos++] = ' ';
+ }
+# ifdef PNG_WARNINGS_SUPPORTED
+ else
+ {
+ char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114*/
+
+ pos = png_safecat(message, (sizeof message), pos,
+ png_format_number(number, number+(sizeof number),
+ PNG_NUMBER_FORMAT_x, value));
+ pos = png_safecat(message, (sizeof message), pos, "h: "); /*+2 = 116*/
+ }
+# endif
+ /* The 'reason' is an arbitrary message, allow +79 maximum 195 */
+ pos = png_safecat(message, (sizeof message), pos, reason);
+
+ /* This is recoverable, but make it unconditionally an app_error on write to
+ * avoid writing invalid ICC profiles into PNG files. (I.e. we handle them
+ * on read, with a warning, but on write unless the app turns off
+ * application errors the PNG won't be written.)
+ */
+ png_chunk_report(png_ptr, message,
+ (colorspace != NULL) ? PNG_CHUNK_ERROR : PNG_CHUNK_WRITE_ERROR);
+
+ return 0;
+}
+#endif /* sRGB || iCCP */
+
+#ifdef PNG_sRGB_SUPPORTED
+int /* PRIVATE */
+png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ int intent)
+{
+ /* sRGB sets known gamma, end points and (from the chunk) intent. */
+ /* IMPORTANT: these are not necessarily the values found in an ICC profile
+ * because ICC profiles store values adapted to a D50 environment; it is
+ * expected that the ICC profile mediaWhitePointTag will be D50, see the
+ * checks and code elsewhere to understand this better.
+ *
+ * These XYZ values, which are accurate to 5dp, produce rgb to gray
+ * coefficients of (6968,23435,2366), which are reduced (because they add up
+ * to 32769 not 32768) to (6968,23434,2366). These are the values that
+ * libpng has traditionally used (and are the best values given the 15bit
+ * algorithm used by the rgb to gray code.)
+ */
+ static const png_XYZ sRGB_XYZ = /* D65 XYZ (*not* the D50 adapted values!) */
+ {
+ /* color X Y Z */
+ /* red */ 41239, 21264, 1933,
+ /* green */ 35758, 71517, 11919,
+ /* blue */ 18048, 7219, 95053
+ };
+
+ /* Do nothing if the colorspace is already invalidated. */
+ if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return 0;
+
+ /* Check the intent, then check for existing settings. It is valid for the
+ * PNG file to have cHRM or gAMA chunks along with sRGB, but the values must
+ * be consistent with the correct values. If, however, this function is
+ * called below because an iCCP chunk matches sRGB then it is quite
+ * conceivable that an older app recorded incorrect gAMA and cHRM because of
+ * an incorrect calculation based on the values in the profile - this does
+ * *not* invalidate the profile (though it still produces an error, which can
+ * be ignored.)
+ */
+ if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
+ return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+ (unsigned)intent, "invalid sRGB rendering intent");
+
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
+ colorspace->rendering_intent != intent)
+ return png_icc_profile_error(png_ptr, colorspace, "sRGB",
+ (unsigned)intent, "inconsistent rendering intents");
+
+ if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
+ {
+ png_benign_error(png_ptr, "duplicate sRGB information ignored");
+ return 0;
+ }
+
+ /* If the standard sRGB cHRM chunk does not match the one from the PNG file
+ * warn but overwrite the value with the correct one.
+ */
+ if ((colorspace->flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0 &&
+ !png_colorspace_endpoints_match(&sRGB_xy, &colorspace->end_points_xy,
+ 100))
+ png_chunk_report(png_ptr, "cHRM chunk does not match sRGB",
+ PNG_CHUNK_ERROR);
+
+ /* This check is just done for the error reporting - the routine always
+ * returns true when the 'from' argument corresponds to sRGB (2).
+ */
+ (void)png_colorspace_check_gamma(png_ptr, colorspace, PNG_GAMMA_sRGB_INVERSE,
+ 2/*from sRGB*/);
+
+ /* intent: bugs in GCC force 'int' to be used as the parameter type. */
+ colorspace->rendering_intent = (png_uint_16)intent;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_INTENT;
+
+ /* endpoints */
+ colorspace->end_points_xy = sRGB_xy;
+ colorspace->end_points_XYZ = sRGB_XYZ;
+ colorspace->flags |=
+ (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB);
+
+ /* gamma */
+ colorspace->gamma = PNG_GAMMA_sRGB_INVERSE;
+ colorspace->flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+ /* Finally record that we have an sRGB profile */
+ colorspace->flags |=
+ (PNG_COLORSPACE_MATCHES_sRGB|PNG_COLORSPACE_FROM_sRGB);
+
+ return 1; /* set */
+}
+#endif /* sRGB */
+
+#ifdef PNG_iCCP_SUPPORTED
+/* Encoded value of D50 as an ICC XYZNumber. From the ICC 2010 spec the value
+ * is XYZ(0.9642,1.0,0.8249), which scales to:
+ *
+ * (63189.8112, 65536, 54060.6464)
+ */
+static const png_byte D50_nCIEXYZ[12] =
+ { 0x00, 0x00, 0xf6, 0xd6, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x2d };
+
+int /* PRIVATE */
+png_icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length)
+{
+ if (profile_length < 132)
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "too short");
+
+ if (profile_length & 3)
+ return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
+ "invalid length");
+
+ return 1;
+}
+
+int /* PRIVATE */
+png_icc_check_header(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length,
+ png_const_bytep profile/* first 132 bytes only */, int color_type)
+{
+ png_uint_32 temp;
+
+ /* Length check; this cannot be ignored in this code because profile_length
+ * is used later to check the tag table, so even if the profile seems over
+ * long profile_length from the caller must be correct. The caller can fix
+ * this up on read or write by just passing in the profile header length.
+ */
+ temp = png_get_uint_32(profile);
+ if (temp != profile_length)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "length does not match profile");
+
+ temp = png_get_uint_32(profile+128); /* tag count: 12 bytes/tag */
+ if (temp > 357913930 || /* (2^32-4-132)/12: maximum possible tag count */
+ profile_length < 132+12*temp) /* truncated tag table */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "tag count too large");
+
+ /* The 'intent' must be valid or we can't store it, ICC limits the intent to
+ * 16 bits.
+ */
+ temp = png_get_uint_32(profile+64);
+ if (temp >= 0xffff) /* The ICC limit */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid rendering intent");
+
+ /* This is just a warning because the profile may be valid in future
+ * versions.
+ */
+ if (temp >= PNG_sRGB_INTENT_LAST)
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "intent outside defined range");
+
+ /* At this point the tag table can't be checked because it hasn't necessarily
+ * been loaded; however, various header fields can be checked. These checks
+ * are for values permitted by the PNG spec in an ICC profile; the PNG spec
+ * restricts the profiles that can be passed in an iCCP chunk (they must be
+ * appropriate to processing PNG data!)
+ */
+
+ /* Data checks (could be skipped). These checks must be independent of the
+ * version number; however, the version number doesn't accomodate changes in
+ * the header fields (just the known tags and the interpretation of the
+ * data.)
+ */
+ temp = png_get_uint_32(profile+36); /* signature 'ascp' */
+ if (temp != 0x61637370)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid signature");
+
+ /* Currently the PCS illuminant/adopted white point (the computational
+ * white point) are required to be D50,
+ * however the profile contains a record of the illuminant so perhaps ICC
+ * expects to be able to change this in the future (despite the rationale in
+ * the introduction for using a fixed PCS adopted white.) Consequently the
+ * following is just a warning.
+ */
+ if (memcmp(profile+68, D50_nCIEXYZ, 12) != 0)
+ (void)png_icc_profile_error(png_ptr, NULL, name, 0/*no tag value*/,
+ "PCS illuminant is not D50");
+
+ /* The PNG spec requires this:
+ * "If the iCCP chunk is present, the image samples conform to the colour
+ * space represented by the embedded ICC profile as defined by the
+ * International Color Consortium [ICC]. The colour space of the ICC profile
+ * shall be an RGB colour space for colour images (PNG colour types 2, 3, and
+ * 6), or a greyscale colour space for greyscale images (PNG colour types 0
+ * and 4)."
+ *
+ * This checking code ensures the embedded profile (on either read or write)
+ * conforms to the specification requirements. Notice that an ICC 'gray'
+ * color-space profile contains the information to transform the monochrome
+ * data to XYZ or L*a*b (according to which PCS the profile uses) and this
+ * should be used in preference to the standard libpng K channel replication
+ * into R, G and B channels.
+ *
+ * Previously it was suggested that an RGB profile on grayscale data could be
+ * handled. However it it is clear that using an RGB profile in this context
+ * must be an error - there is no specification of what it means. Thus it is
+ * almost certainly more correct to ignore the profile.
+ */
+ temp = png_get_uint_32(profile+16); /* data colour space field */
+ switch (temp)
+ {
+ case 0x52474220: /* 'RGB ' */
+ if (!(color_type & PNG_COLOR_MASK_COLOR))
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "RGB color space not permitted on grayscale PNG");
+ break;
+
+ case 0x47524159: /* 'GRAY' */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "Gray color space not permitted on RGB PNG");
+ break;
+
+ default:
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid ICC profile color space");
+ }
+
+ /* It is up to the application to check that the profile class matches the
+ * application requirements; the spec provides no guidance, but it's pretty
+ * weird if the profile is not scanner ('scnr'), monitor ('mntr'), printer
+ * ('prtr') or 'spac' (for generic color spaces). Issue a warning in these
+ * cases. Issue an error for device link or abstract profiles - these don't
+ * contain the records necessary to transform the color-space to anything
+ * other than the target device (and not even that for an abstract profile).
+ * Profiles of these classes may not be embedded in images.
+ */
+ temp = png_get_uint_32(profile+12); /* profile/device class */
+ switch (temp)
+ {
+ case 0x73636E72: /* 'scnr' */
+ case 0x6D6E7472: /* 'mntr' */
+ case 0x70727472: /* 'prtr' */
+ case 0x73706163: /* 'spac' */
+ /* All supported */
+ break;
+
+ case 0x61627374: /* 'abst' */
+ /* May not be embedded in an image */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "invalid embedded Abstract ICC profile");
+
+ case 0x6C696E6B: /* 'link' */
+ /* DeviceLink profiles cannnot be interpreted in a non-device specific
+ * fashion, if an app uses the AToB0Tag in the profile the results are
+ * undefined unless the result is sent to the intended device,
+ * therefore a DeviceLink profile should not be found embedded in a
+ * PNG.
+ */
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "unexpected DeviceLink ICC profile class");
+
+ case 0x6E6D636C: /* 'nmcl' */
+ /* A NamedColor profile is also device specific, however it doesn't
+ * contain an AToB0 tag that is open to misintrepretation. Almost
+ * certainly it will fail the tests below.
+ */
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "unexpected NamedColor ICC profile class");
+ break;
+
+ default:
+ /* To allow for future enhancements to the profile accept unrecognized
+ * profile classes with a warning, these then hit the test below on the
+ * tag content to ensure they are backward compatible with one of the
+ * understood profiles.
+ */
+ (void)png_icc_profile_error(png_ptr, NULL, name, temp,
+ "unrecognized ICC profile class");
+ break;
+ }
+
+ /* For any profile other than a device link one the PCS must be encoded
+ * either in XYZ or Lab.
+ */
+ temp = png_get_uint_32(profile+20);
+ switch (temp)
+ {
+ case 0x58595A20: /* 'XYZ ' */
+ case 0x4C616220: /* 'Lab ' */
+ break;
+
+ default:
+ return png_icc_profile_error(png_ptr, colorspace, name, temp,
+ "unexpected ICC PCS encoding");
+ }
+
+ return 1;
+}
+
+int /* PRIVATE */
+png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length,
+ png_const_bytep profile /* header plus whole tag table */)
+{
+ png_uint_32 tag_count = png_get_uint_32(profile+128);
+ png_uint_32 itag;
+ png_const_bytep tag = profile+132; /* The first tag */
+
+ /* First scan all the tags in the table and add bits to the icc_info value
+ * (temporarily in 'tags').
+ */
+ for (itag=0; itag < tag_count; ++itag, tag += 12)
+ {
+ png_uint_32 tag_id = png_get_uint_32(tag+0);
+ png_uint_32 tag_start = png_get_uint_32(tag+4); /* must be aligned */
+ png_uint_32 tag_length = png_get_uint_32(tag+8);/* not padded */
+
+ /* The ICC specification does not exclude zero length tags, therefore the
+ * start might actually be anywhere if there is no data, but this would be
+ * a clear abuse of the intent of the standard so the start is checked for
+ * being in range. All defined tag types have an 8 byte header - a 4 byte
+ * type signature then 0.
+ */
+ if ((tag_start & 3) != 0)
+ {
+ /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
+ * only a warning here because libpng does not care about the
+ * alignment.
+ */
+ (void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
+ "ICC profile tag start not a multiple of 4");
+ }
+
+ /* This is a hard error; potentially it can cause read outside the
+ * profile.
+ */
+ if (tag_start > profile_length || tag_length > profile_length - tag_start)
+ return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
+ "ICC profile tag outside profile");
+ }
+
+ return 1; /* success, maybe with warnings */
+}
+
+#ifdef PNG_sRGB_SUPPORTED
+/* Information about the known ICC sRGB profiles */
+static const struct
+{
+ png_uint_32 adler, crc, length;
+ png_uint_32 md5[4];
+ png_byte have_md5;
+ png_byte is_broken;
+ png_uint_16 intent;
+
+# define PNG_MD5(a,b,c,d) { a, b, c, d }, (a!=0)||(b!=0)||(c!=0)||(d!=0)
+# define PNG_ICC_CHECKSUM(adler, crc, md5, intent, broke, date, length, fname)\
+ { adler, crc, length, md5, broke, intent },
+
+} png_sRGB_checks[] =
+{
+ /* This data comes from contrib/tools/checksum-icc run on downloads of
+ * all four ICC sRGB profiles from www.color.org.
+ */
+ /* adler32, crc32, MD5[4], intent, date, length, file-name */
+ PNG_ICC_CHECKSUM(0x0a3fd9f6, 0x3b8772b9,
+ PNG_MD5(0x29f83dde, 0xaff255ae, 0x7842fae4, 0xca83390d), 0, 0,
+ "2009/03/27 21:36:31", 3048, "sRGB_IEC61966-2-1_black_scaled.icc")
+
+ /* ICC sRGB v2 perceptual no black-compensation: */
+ PNG_ICC_CHECKSUM(0x4909e5e1, 0x427ebb21,
+ PNG_MD5(0xc95bd637, 0xe95d8a3b, 0x0df38f99, 0xc1320389), 1, 0,
+ "2009/03/27 21:37:45", 3052, "sRGB_IEC61966-2-1_no_black_scaling.icc")
+
+ PNG_ICC_CHECKSUM(0xfd2144a1, 0x306fd8ae,
+ PNG_MD5(0xfc663378, 0x37e2886b, 0xfd72e983, 0x8228f1b8), 0, 0,
+ "2009/08/10 17:28:01", 60988, "sRGB_v4_ICC_preference_displayclass.icc")
+
+ /* ICC sRGB v4 perceptual */
+ PNG_ICC_CHECKSUM(0x209c35d2, 0xbbef7812,
+ PNG_MD5(0x34562abf, 0x994ccd06, 0x6d2c5721, 0xd0d68c5d), 0, 0,
+ "2007/07/25 00:05:37", 60960, "sRGB_v4_ICC_preference.icc")
+
+ /* The following profiles have no known MD5 checksum. If there is a match
+ * on the (empty) MD5 the other fields are used to attempt a match and
+ * a warning is produced. The first two of these profiles have a 'cprt' tag
+ * which suggests that they were also made by Hewlett Packard.
+ */
+ PNG_ICC_CHECKSUM(0xa054d762, 0x5d5129ce,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 0,
+ "2004/07/21 18:57:42", 3024, "sRGB_IEC61966-2-1_noBPC.icc")
+
+ /* This is a 'mntr' (display) profile with a mediaWhitePointTag that does not
+ * match the D50 PCS illuminant in the header (it is in fact the D65 values,
+ * so the white point is recorded as the un-adapted value.) The profiles
+ * below only differ in one byte - the intent - and are basically the same as
+ * the previous profile except for the mediaWhitePointTag error and a missing
+ * chromaticAdaptationTag.
+ */
+ PNG_ICC_CHECKSUM(0xf784f3fb, 0x182ea552,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 0, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 perceptual")
+
+ PNG_ICC_CHECKSUM(0x0398f3fc, 0xf29e526d,
+ PNG_MD5(0x00000000, 0x00000000, 0x00000000, 0x00000000), 1, 1/*broken*/,
+ "1998/02/09 06:49:00", 3144, "HP-Microsoft sRGB v2 media-relative")
+};
+
+static int
+png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
+ png_const_bytep profile, uLong adler)
+{
+ /* The quick check is to verify just the MD5 signature and trust the
+ * rest of the data. Because the profile has already been verified for
+ * correctness this is safe. png_colorspace_set_sRGB will check the 'intent'
+ * field too, so if the profile has been edited with an intent not defined
+ * by sRGB (but maybe defined by a later ICC specification) the read of
+ * the profile will fail at that point.
+ */
+ png_uint_32 length = 0;
+ png_uint_32 intent = 0x10000; /* invalid */
+#if PNG_sRGB_PROFILE_CHECKS > 1
+ uLong crc = 0; /* the value for 0 length data */
+#endif
+ unsigned int i;
+
+ for (i=0; i < (sizeof png_sRGB_checks) / (sizeof png_sRGB_checks[0]); ++i)
+ {
+ if (png_get_uint_32(profile+84) == png_sRGB_checks[i].md5[0] &&
+ png_get_uint_32(profile+88) == png_sRGB_checks[i].md5[1] &&
+ png_get_uint_32(profile+92) == png_sRGB_checks[i].md5[2] &&
+ png_get_uint_32(profile+96) == png_sRGB_checks[i].md5[3])
+ {
+ /* This may be one of the old HP profiles without an MD5, in that
+ * case we can only use the length and Adler32 (note that these
+ * are not used by default if there is an MD5!)
+ */
+# if PNG_sRGB_PROFILE_CHECKS == 0
+ if (png_sRGB_checks[i].have_md5)
+ return 1+png_sRGB_checks[i].is_broken;
+# endif
+
+ /* Profile is unsigned or more checks have been configured in. */
+ if (length == 0)
+ {
+ length = png_get_uint_32(profile);
+ intent = png_get_uint_32(profile+64);
+ }
+
+ /* Length *and* intent must match */
+ if (length == png_sRGB_checks[i].length &&
+ intent == png_sRGB_checks[i].intent)
+ {
+ /* Now calculate the adler32 if not done already. */
+ if (adler == 0)
+ {
+ adler = adler32(0, NULL, 0);
+ adler = adler32(adler, profile, length);
+ }
+
+ if (adler == png_sRGB_checks[i].adler)
+ {
+ /* These basic checks suggest that the data has not been
+ * modified, but if the check level is more than 1 perform
+ * our own crc32 checksum on the data.
+ */
+# if PNG_sRGB_PROFILE_CHECKS > 1
+ if (crc == 0)
+ {
+ crc = crc32(0, NULL, 0);
+ crc = crc32(crc, profile, length);
+ }
+
+ /* So this check must pass for the 'return' below to happen.
+ */
+ if (crc == png_sRGB_checks[i].crc)
+# endif
+ {
+ if (png_sRGB_checks[i].is_broken)
+ {
+ /* These profiles are known to have bad data that may cause
+ * problems if they are used, therefore attempt to
+ * discourage their use, skip the 'have_md5' warning below,
+ * which is made irrelevant by this error.
+ */
+ png_chunk_report(png_ptr, "known incorrect sRGB profile",
+ PNG_CHUNK_ERROR);
+ }
+
+ /* Warn that this being done; this isn't even an error since
+ * the profile is perfectly valid, but it would be nice if
+ * people used the up-to-date ones.
+ */
+ else if (!png_sRGB_checks[i].have_md5)
+ {
+ png_chunk_report(png_ptr,
+ "out-of-date sRGB profile with no signature",
+ PNG_CHUNK_WARNING);
+ }
+
+ return 1+png_sRGB_checks[i].is_broken;
+ }
+ }
+ }
+
+# if PNG_sRGB_PROFILE_CHECKS > 0
+ /* The signature matched, but the profile had been changed in some
+ * way. This is an apparent violation of the ICC terms of use and,
+ * anyway, probably indicates a data error or uninformed hacking.
+ */
+ if (png_sRGB_checks[i].have_md5)
+ png_benign_error(png_ptr,
+ "copyright violation: edited ICC profile ignored");
+# endif
+ }
+ }
+
+ return 0; /* no match */
+}
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void /* PRIVATE */
+png_icc_set_sRGB(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_bytep profile, uLong adler)
+{
+ /* Is this profile one of the known ICC sRGB profiles? If it is, just set
+ * the sRGB information.
+ */
+ if (png_compare_ICC_profile_with_sRGB(png_ptr, profile, adler))
+ (void)png_colorspace_set_sRGB(png_ptr, colorspace,
+ (int)/*already checked*/png_get_uint_32(profile+64));
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+int /* PRIVATE */
+png_colorspace_set_ICC(png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_charp name, png_uint_32 profile_length, png_const_bytep profile,
+ int color_type)
+{
+ if (colorspace->flags & PNG_COLORSPACE_INVALID)
+ return 0;
+
+ if (png_icc_check_length(png_ptr, colorspace, name, profile_length) &&
+ png_icc_check_header(png_ptr, colorspace, name, profile_length, profile,
+ color_type) &&
+ png_icc_check_tag_table(png_ptr, colorspace, name, profile_length,
+ profile))
+ {
+# ifdef PNG_sRGB_SUPPORTED
+ /* If no sRGB support, don't try storing sRGB information */
+ png_icc_set_sRGB(png_ptr, colorspace, profile, 0);
+# endif
+ return 1;
+ }
+
+ /* Failure case */
+ return 0;
+}
+#endif /* iCCP */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+void /* PRIVATE */
+png_colorspace_set_rgb_coefficients(png_structrp png_ptr)
+{
+ /* Set the rgb_to_gray coefficients from the colorspace. */
+ if (!png_ptr->rgb_to_gray_coefficients_set &&
+ (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0)
+ {
+ /* png_set_background has not been called, get the coefficients from the Y
+ * values of the colorspace colorants.
+ */
+ png_fixed_point r = png_ptr->colorspace.end_points_XYZ.red_Y;
+ png_fixed_point g = png_ptr->colorspace.end_points_XYZ.green_Y;
+ png_fixed_point b = png_ptr->colorspace.end_points_XYZ.blue_Y;
+ png_fixed_point total = r+g+b;
+
+ if (total > 0 &&
+ r >= 0 && png_muldiv(&r, r, 32768, total) && r >= 0 && r <= 32768 &&
+ g >= 0 && png_muldiv(&g, g, 32768, total) && g >= 0 && g <= 32768 &&
+ b >= 0 && png_muldiv(&b, b, 32768, total) && b >= 0 && b <= 32768 &&
+ r+g+b <= 32769)
+ {
+ /* We allow 0 coefficients here. r+g+b may be 32769 if two or
+ * all of the coefficients were rounded up. Handle this by
+ * reducing the *largest* coefficient by 1; this matches the
+ * approach used for the default coefficients in pngrtran.c
+ */
+ int add = 0;
+
+ if (r+g+b > 32768)
+ add = -1;
+ else if (r+g+b < 32768)
+ add = 1;
+
+ if (add != 0)
+ {
+ if (g >= r && g >= b)
+ g += add;
+ else if (r >= g && r >= b)
+ r += add;
+ else
+ b += add;
+ }
+
+ /* Check for an internal error. */
+ if (r+g+b != 32768)
+ png_error(png_ptr,
+ "internal error handling cHRM coefficients");
+
+ else
+ {
+ png_ptr->rgb_to_gray_red_coeff = (png_uint_16)r;
+ png_ptr->rgb_to_gray_green_coeff = (png_uint_16)g;
+ }
+ }
+
+ /* This is a png_error at present even though it could be ignored -
+ * it should never happen, but it is important that if it does, the
+ * bug is fixed.
+ */
+ else
+ png_error(png_ptr, "internal error handling cHRM->XYZ");
+ }
+}
+#endif
+
+#endif /* COLORSPACE */
+
+void /* PRIVATE */
+png_check_IHDR(png_const_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ int error = 0;
+
+ /* Check for width and height valid values */
+ if (width == 0)
+ {
+ png_warning(png_ptr, "Image width is zero in IHDR");
+ error = 1;
+ }
+
+ if (height == 0)
+ {
+ png_warning(png_ptr, "Image height is zero in IHDR");
+ error = 1;
+ }
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (width > png_ptr->user_width_max)
+
+# else
+ if (width > PNG_USER_WIDTH_MAX)
+# endif
+ {
+ png_warning(png_ptr, "Image width exceeds user limit in IHDR");
+ error = 1;
+ }
+
+# ifdef PNG_SET_USER_LIMITS_SUPPORTED
+ if (height > png_ptr->user_height_max)
+# else
+ if (height > PNG_USER_HEIGHT_MAX)
+# endif
+ {
+ png_warning(png_ptr, "Image height exceeds user limit in IHDR");
+ error = 1;
+ }
+
+ if (width > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Invalid image width in IHDR");
+ error = 1;
+ }
+
+ if (height > PNG_UINT_31_MAX)
+ {
+ png_warning(png_ptr, "Invalid image height in IHDR");
+ error = 1;
+ }
+
+ if (width > (PNG_UINT_32_MAX
+ >> 3) /* 8-byte RGBA pixels */
+ - 48 /* bigrowbuf hack */
+ - 1 /* filter byte */
+ - 7*8 /* rounding of width to multiple of 8 pixels */
+ - 8) /* extra max_pixel_depth pad */
+ png_warning(png_ptr, "Width is too large for libpng to process pixels");
+
+ /* Check other values */
+ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+ bit_depth != 8 && bit_depth != 16)
+ {
+ png_warning(png_ptr, "Invalid bit depth in IHDR");
+ error = 1;
+ }
+
+ if (color_type < 0 || color_type == 1 ||
+ color_type == 5 || color_type > 6)
+ {
+ png_warning(png_ptr, "Invalid color type in IHDR");
+ error = 1;
+ }
+
+ if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+ ((color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+ {
+ png_warning(png_ptr, "Invalid color type/bit depth combination in IHDR");
+ error = 1;
+ }
+
+ if (interlace_type >= PNG_INTERLACE_LAST)
+ {
+ png_warning(png_ptr, "Unknown interlace method in IHDR");
+ error = 1;
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Unknown compression method in IHDR");
+ error = 1;
+ }
+
+# ifdef PNG_MNG_FEATURES_SUPPORTED
+ /* Accept filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not read a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) &&
+ png_ptr->mng_features_permitted)
+ png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+
+ if (filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ if (!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+ ((png_ptr->mode & PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+ {
+ png_warning(png_ptr, "Unknown filter method in IHDR");
+ error = 1;
+ }
+
+ if (png_ptr->mode & PNG_HAVE_PNG_SIGNATURE)
+ {
+ png_warning(png_ptr, "Invalid filter method in IHDR");
+ error = 1;
+ }
+ }
+
+# else
+ if (filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Unknown filter method in IHDR");
+ error = 1;
+ }
+# endif
+
+ if (error == 1)
+ png_error(png_ptr, "Invalid IHDR data");
+}
+
+#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
+/* ASCII to fp functions */
+/* Check an ASCII formated floating point value, see the more detailed
+ * comments in pngpriv.h
+ */
+/* The following is used internally to preserve the sticky flags */
+#define png_fp_add(state, flags) ((state) |= (flags))
+#define png_fp_set(state, value) ((state) = (value) | ((state) & PNG_FP_STICKY))
+
+int /* PRIVATE */
+png_check_fp_number(png_const_charp string, png_size_t size, int *statep,
+ png_size_tp whereami)
+{
+ int state = *statep;
+ png_size_t i = *whereami;
+
+ while (i < size)
+ {
+ int type;
+ /* First find the type of the next character */
+ switch (string[i])
+ {
+ case 43: type = PNG_FP_SAW_SIGN; break;
+ case 45: type = PNG_FP_SAW_SIGN + PNG_FP_NEGATIVE; break;
+ case 46: type = PNG_FP_SAW_DOT; break;
+ case 48: type = PNG_FP_SAW_DIGIT; break;
+ case 49: case 50: case 51: case 52:
+ case 53: case 54: case 55: case 56:
+ case 57: type = PNG_FP_SAW_DIGIT + PNG_FP_NONZERO; break;
+ case 69:
+ case 101: type = PNG_FP_SAW_E; break;
+ default: goto PNG_FP_End;
+ }
+
+ /* Now deal with this type according to the current
+ * state, the type is arranged to not overlap the
+ * bits of the PNG_FP_STATE.
+ */
+ switch ((state & PNG_FP_STATE) + (type & PNG_FP_SAW_ANY))
+ {
+ case PNG_FP_INTEGER + PNG_FP_SAW_SIGN:
+ if (state & PNG_FP_SAW_ANY)
+ goto PNG_FP_End; /* not a part of the number */
+
+ png_fp_add(state, type);
+ break;
+
+ case PNG_FP_INTEGER + PNG_FP_SAW_DOT:
+ /* Ok as trailer, ok as lead of fraction. */
+ if (state & PNG_FP_SAW_DOT) /* two dots */
+ goto PNG_FP_End;
+
+ else if (state & PNG_FP_SAW_DIGIT) /* trailing dot? */
+ png_fp_add(state, type);
+
+ else
+ png_fp_set(state, PNG_FP_FRACTION | type);
+
+ break;
+
+ case PNG_FP_INTEGER + PNG_FP_SAW_DIGIT:
+ if (state & PNG_FP_SAW_DOT) /* delayed fraction */
+ png_fp_set(state, PNG_FP_FRACTION | PNG_FP_SAW_DOT);
+
+ png_fp_add(state, type | PNG_FP_WAS_VALID);
+
+ break;
+
+ case PNG_FP_INTEGER + PNG_FP_SAW_E:
+ if ((state & PNG_FP_SAW_DIGIT) == 0)
+ goto PNG_FP_End;
+
+ png_fp_set(state, PNG_FP_EXPONENT);
+
+ break;
+
+ /* case PNG_FP_FRACTION + PNG_FP_SAW_SIGN:
+ goto PNG_FP_End; ** no sign in fraction */
+
+ /* case PNG_FP_FRACTION + PNG_FP_SAW_DOT:
+ goto PNG_FP_End; ** Because SAW_DOT is always set */
+
+ case PNG_FP_FRACTION + PNG_FP_SAW_DIGIT:
+ png_fp_add(state, type | PNG_FP_WAS_VALID);
+ break;
+
+ case PNG_FP_FRACTION + PNG_FP_SAW_E:
+ /* This is correct because the trailing '.' on an
+ * integer is handled above - so we can only get here
+ * with the sequence ".E" (with no preceding digits).
+ */
+ if ((state & PNG_FP_SAW_DIGIT) == 0)
+ goto PNG_FP_End;
+
+ png_fp_set(state, PNG_FP_EXPONENT);
+
+ break;
+
+ case PNG_FP_EXPONENT + PNG_FP_SAW_SIGN:
+ if (state & PNG_FP_SAW_ANY)
+ goto PNG_FP_End; /* not a part of the number */
+
+ png_fp_add(state, PNG_FP_SAW_SIGN);
+
+ break;
+
+ /* case PNG_FP_EXPONENT + PNG_FP_SAW_DOT:
+ goto PNG_FP_End; */
+
+ case PNG_FP_EXPONENT + PNG_FP_SAW_DIGIT:
+ png_fp_add(state, PNG_FP_SAW_DIGIT | PNG_FP_WAS_VALID);
+
+ break;
+
+ /* case PNG_FP_EXPONEXT + PNG_FP_SAW_E:
+ goto PNG_FP_End; */
+
+ default: goto PNG_FP_End; /* I.e. break 2 */
+ }
+
+ /* The character seems ok, continue. */
+ ++i;
+ }
+
+PNG_FP_End:
+ /* Here at the end, update the state and return the correct
+ * return code.
+ */
+ *statep = state;
+ *whereami = i;
+
+ return (state & PNG_FP_SAW_DIGIT) != 0;
+}
+
+
+/* The same but for a complete string. */
+int
+png_check_fp_string(png_const_charp string, png_size_t size)
+{
+ int state=0;
+ png_size_t char_index=0;
+
+ if (png_check_fp_number(string, size, &state, &char_index) &&
+ (char_index == size || string[char_index] == 0))
+ return state /* must be non-zero - see above */;
+
+ return 0; /* i.e. fail */
+}
+#endif /* pCAL or sCAL */
+
+#ifdef PNG_sCAL_SUPPORTED
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Utility used below - a simple accurate power of ten from an integral
+ * exponent.
+ */
+static double
+png_pow10(int power)
+{
+ int recip = 0;
+ double d = 1;
+
+ /* Handle negative exponent with a reciprocal at the end because
+ * 10 is exact whereas .1 is inexact in base 2
+ */
+ if (power < 0)
+ {
+ if (power < DBL_MIN_10_EXP) return 0;
+ recip = 1, power = -power;
+ }
+
+ if (power > 0)
+ {
+ /* Decompose power bitwise. */
+ double mult = 10;
+ do
+ {
+ if (power & 1) d *= mult;
+ mult *= mult;
+ power >>= 1;
+ }
+ while (power > 0);
+
+ if (recip) d = 1/d;
+ }
+ /* else power is 0 and d is 1 */
+
+ return d;
+}
+
+/* Function to format a floating point value in ASCII with a given
+ * precision.
+ */
+void /* PRIVATE */
+png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
+ double fp, unsigned int precision)
+{
+ /* We use standard functions from math.h, but not printf because
+ * that would require stdio. The caller must supply a buffer of
+ * sufficient size or we will png_error. The tests on size and
+ * the space in ascii[] consumed are indicated below.
+ */
+ if (precision < 1)
+ precision = DBL_DIG;
+
+ /* Enforce the limit of the implementation precision too. */
+ if (precision > DBL_DIG+1)
+ precision = DBL_DIG+1;
+
+ /* Basic sanity checks */
+ if (size >= precision+5) /* See the requirements below. */
+ {
+ if (fp < 0)
+ {
+ fp = -fp;
+ *ascii++ = 45; /* '-' PLUS 1 TOTAL 1 */
+ --size;
+ }
+
+ if (fp >= DBL_MIN && fp <= DBL_MAX)
+ {
+ int exp_b10; /* A base 10 exponent */
+ double base; /* 10^exp_b10 */
+
+ /* First extract a base 10 exponent of the number,
+ * the calculation below rounds down when converting
+ * from base 2 to base 10 (multiply by log10(2) -
+ * 0.3010, but 77/256 is 0.3008, so exp_b10 needs to
+ * be increased. Note that the arithmetic shift
+ * performs a floor() unlike C arithmetic - using a
+ * C multiply would break the following for negative
+ * exponents.
+ */
+ (void)frexp(fp, &exp_b10); /* exponent to base 2 */
+
+ exp_b10 = (exp_b10 * 77) >> 8; /* <= exponent to base 10 */
+
+ /* Avoid underflow here. */
+ base = png_pow10(exp_b10); /* May underflow */
+
+ while (base < DBL_MIN || base < fp)
+ {
+ /* And this may overflow. */
+ double test = png_pow10(exp_b10+1);
+
+ if (test <= DBL_MAX)
+ ++exp_b10, base = test;
+
+ else
+ break;
+ }
+
+ /* Normalize fp and correct exp_b10, after this fp is in the
+ * range [.1,1) and exp_b10 is both the exponent and the digit
+ * *before* which the decimal point should be inserted
+ * (starting with 0 for the first digit). Note that this
+ * works even if 10^exp_b10 is out of range because of the
+ * test on DBL_MAX above.
+ */
+ fp /= base;
+ while (fp >= 1) fp /= 10, ++exp_b10;
+
+ /* Because of the code above fp may, at this point, be
+ * less than .1, this is ok because the code below can
+ * handle the leading zeros this generates, so no attempt
+ * is made to correct that here.
+ */
+
+ {
+ int czero, clead, cdigits;
+ char exponent[10];
+
+ /* Allow up to two leading zeros - this will not lengthen
+ * the number compared to using E-n.
+ */
+ if (exp_b10 < 0 && exp_b10 > -3) /* PLUS 3 TOTAL 4 */
+ {
+ czero = -exp_b10; /* PLUS 2 digits: TOTAL 3 */
+ exp_b10 = 0; /* Dot added below before first output. */
+ }
+ else
+ czero = 0; /* No zeros to add */
+
+ /* Generate the digit list, stripping trailing zeros and
+ * inserting a '.' before a digit if the exponent is 0.
+ */
+ clead = czero; /* Count of leading zeros */
+ cdigits = 0; /* Count of digits in list. */
+
+ do
+ {
+ double d;
+
+ fp *= 10;
+ /* Use modf here, not floor and subtract, so that
+ * the separation is done in one step. At the end
+ * of the loop don't break the number into parts so
+ * that the final digit is rounded.
+ */
+ if (cdigits+czero-clead+1 < (int)precision)
+ fp = modf(fp, &d);
+
+ else
+ {
+ d = floor(fp + .5);
+
+ if (d > 9)
+ {
+ /* Rounding up to 10, handle that here. */
+ if (czero > 0)
+ {
+ --czero, d = 1;
+ if (cdigits == 0) --clead;
+ }
+ else
+ {
+ while (cdigits > 0 && d > 9)
+ {
+ int ch = *--ascii;
+
+ if (exp_b10 != (-1))
+ ++exp_b10;
+
+ else if (ch == 46)
+ {
+ ch = *--ascii, ++size;
+ /* Advance exp_b10 to '1', so that the
+ * decimal point happens after the
+ * previous digit.
+ */
+ exp_b10 = 1;
+ }
+
+ --cdigits;
+ d = ch - 47; /* I.e. 1+(ch-48) */
+ }
+
+ /* Did we reach the beginning? If so adjust the
+ * exponent but take into account the leading
+ * decimal point.
+ */
+ if (d > 9) /* cdigits == 0 */
+ {
+ if (exp_b10 == (-1))
+ {
+ /* Leading decimal point (plus zeros?), if
+ * we lose the decimal point here it must
+ * be reentered below.
+ */
+ int ch = *--ascii;
+
+ if (ch == 46)
+ ++size, exp_b10 = 1;
+
+ /* Else lost a leading zero, so 'exp_b10' is
+ * still ok at (-1)
+ */
+ }
+ else
+ ++exp_b10;
+
+ /* In all cases we output a '1' */
+ d = 1;
+ }
+ }
+ }
+ fp = 0; /* Guarantees termination below. */
+ }
+
+ if (d == 0)
+ {
+ ++czero;
+ if (cdigits == 0) ++clead;
+ }
+ else
+ {
+ /* Included embedded zeros in the digit count. */
+ cdigits += czero - clead;
+ clead = 0;
+
+ while (czero > 0)
+ {
+ /* exp_b10 == (-1) means we just output the decimal
+ * place - after the DP don't adjust 'exp_b10' any
+ * more!
+ */
+ if (exp_b10 != (-1))
+ {
+ if (exp_b10 == 0) *ascii++ = 46, --size;
+ /* PLUS 1: TOTAL 4 */
+ --exp_b10;
+ }
+ *ascii++ = 48, --czero;
+ }
+
+ if (exp_b10 != (-1))
+ {
+ if (exp_b10 == 0) *ascii++ = 46, --size; /* counted
+ above */
+ --exp_b10;
+ }
+ *ascii++ = (char)(48 + (int)d), ++cdigits;
+ }
+ }
+ while (cdigits+czero-clead < (int)precision && fp > DBL_MIN);
+
+ /* The total output count (max) is now 4+precision */
+
+ /* Check for an exponent, if we don't need one we are
+ * done and just need to terminate the string. At
+ * this point exp_b10==(-1) is effectively if flag - it got
+ * to '-1' because of the decrement after outputing
+ * the decimal point above (the exponent required is
+ * *not* -1!)
+ */
+ if (exp_b10 >= (-1) && exp_b10 <= 2)
+ {
+ /* The following only happens if we didn't output the
+ * leading zeros above for negative exponent, so this
+ * doest add to the digit requirement. Note that the
+ * two zeros here can only be output if the two leading
+ * zeros were *not* output, so this doesn't increase
+ * the output count.
+ */
+ while (--exp_b10 >= 0) *ascii++ = 48;
+
+ *ascii = 0;
+
+ /* Total buffer requirement (including the '\0') is
+ * 5+precision - see check at the start.
+ */
+ return;
+ }
+
+ /* Here if an exponent is required, adjust size for
+ * the digits we output but did not count. The total
+ * digit output here so far is at most 1+precision - no
+ * decimal point and no leading or trailing zeros have
+ * been output.
+ */
+ size -= cdigits;
+
+ *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */
+
+ /* The following use of an unsigned temporary avoids ambiguities in
+ * the signed arithmetic on exp_b10 and permits GCC at least to do
+ * better optimization.
+ */
+ {
+ unsigned int uexp_b10;
+
+ if (exp_b10 < 0)
+ {
+ *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
+ uexp_b10 = -exp_b10;
+ }
+
+ else
+ uexp_b10 = exp_b10;
+
+ cdigits = 0;
+
+ while (uexp_b10 > 0)
+ {
+ exponent[cdigits++] = (char)(48 + uexp_b10 % 10);
+ uexp_b10 /= 10;
+ }
+ }
+
+ /* Need another size check here for the exponent digits, so
+ * this need not be considered above.
+ */
+ if ((int)size > cdigits)
+ {
+ while (cdigits > 0) *ascii++ = exponent[--cdigits];
+
+ *ascii = 0;
+
+ return;
+ }
+ }
+ }
+ else if (!(fp >= DBL_MIN))
+ {
+ *ascii++ = 48; /* '0' */
+ *ascii = 0;
+ return;
+ }
+ else
+ {
+ *ascii++ = 105; /* 'i' */
+ *ascii++ = 110; /* 'n' */
+ *ascii++ = 102; /* 'f' */
+ *ascii = 0;
+ return;
+ }
+ }
+
+ /* Here on buffer too small. */
+ png_error(png_ptr, "ASCII conversion buffer too small");
+}
+
+# endif /* FLOATING_POINT */
+
+# ifdef PNG_FIXED_POINT_SUPPORTED
+/* Function to format a fixed point value in ASCII.
+ */
+void /* PRIVATE */
+png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
+ png_size_t size, png_fixed_point fp)
+{
+ /* Require space for 10 decimal digits, a decimal point, a minus sign and a
+ * trailing \0, 13 characters:
+ */
+ if (size > 12)
+ {
+ png_uint_32 num;
+
+ /* Avoid overflow here on the minimum integer. */
+ if (fp < 0)
+ *ascii++ = 45, --size, num = -fp;
+ else
+ num = fp;
+
+ if (num <= 0x80000000) /* else overflowed */
+ {
+ unsigned int ndigits = 0, first = 16 /* flag value */;
+ char digits[10];
+
+ while (num)
+ {
+ /* Split the low digit off num: */
+ unsigned int tmp = num/10;
+ num -= tmp*10;
+ digits[ndigits++] = (char)(48 + num);
+ /* Record the first non-zero digit, note that this is a number
+ * starting at 1, it's not actually the array index.
+ */
+ if (first == 16 && num > 0)
+ first = ndigits;
+ num = tmp;
+ }
+
+ if (ndigits > 0)
+ {
+ while (ndigits > 5) *ascii++ = digits[--ndigits];
+ /* The remaining digits are fractional digits, ndigits is '5' or
+ * smaller at this point. It is certainly not zero. Check for a
+ * non-zero fractional digit:
+ */
+ if (first <= 5)
+ {
+ unsigned int i;
+ *ascii++ = 46; /* decimal point */
+ /* ndigits may be <5 for small numbers, output leading zeros
+ * then ndigits digits to first:
+ */
+ i = 5;
+ while (ndigits < i) *ascii++ = 48, --i;
+ while (ndigits >= first) *ascii++ = digits[--ndigits];
+ /* Don't output the trailing zeros! */
+ }
+ }
+ else
+ *ascii++ = 48;
+
+ /* And null terminate the string: */
+ *ascii = 0;
+ return;
+ }
+ }
+
+ /* Here on buffer too small. */
+ png_error(png_ptr, "ASCII conversion buffer too small");
+}
+# endif /* FIXED_POINT */
+#endif /* READ_SCAL */
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
+ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
+ (defined(PNG_sCAL_SUPPORTED) && \
+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
+png_fixed_point
+png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text)
+{
+ double r = floor(100000 * fp + .5);
+
+ if (r > 2147483647. || r < -2147483648.)
+ png_fixed_error(png_ptr, text);
+
+ return (png_fixed_point)r;
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || \
+ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
+/* muldiv functions */
+/* This API takes signed arguments and rounds the result to the nearest
+ * integer (or, for a fixed point number - the standard argument - to
+ * the nearest .00001). Overflow and divide by zero are signalled in
+ * the result, a boolean - true on success, false on overflow.
+ */
+int
+png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times,
+ png_int_32 divisor)
+{
+ /* Return a * times / divisor, rounded. */
+ if (divisor != 0)
+ {
+ if (a == 0 || times == 0)
+ {
+ *res = 0;
+ return 1;
+ }
+ else
+ {
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = a;
+ r *= times;
+ r /= divisor;
+ r = floor(r+.5);
+
+ /* A png_fixed_point is a 32-bit integer. */
+ if (r <= 2147483647. && r >= -2147483648.)
+ {
+ *res = (png_fixed_point)r;
+ return 1;
+ }
+#else
+ int negative = 0;
+ png_uint_32 A, T, D;
+ png_uint_32 s16, s32, s00;
+
+ if (a < 0)
+ negative = 1, A = -a;
+ else
+ A = a;
+
+ if (times < 0)
+ negative = !negative, T = -times;
+ else
+ T = times;
+
+ if (divisor < 0)
+ negative = !negative, D = -divisor;
+ else
+ D = divisor;
+
+ /* Following can't overflow because the arguments only
+ * have 31 bits each, however the result may be 32 bits.
+ */
+ s16 = (A >> 16) * (T & 0xffff) +
+ (A & 0xffff) * (T >> 16);
+ /* Can't overflow because the a*times bit is only 30
+ * bits at most.
+ */
+ s32 = (A >> 16) * (T >> 16) + (s16 >> 16);
+ s00 = (A & 0xffff) * (T & 0xffff);
+
+ s16 = (s16 & 0xffff) << 16;
+ s00 += s16;
+
+ if (s00 < s16)
+ ++s32; /* carry */
+
+ if (s32 < D) /* else overflow */
+ {
+ /* s32.s00 is now the 64-bit product, do a standard
+ * division, we know that s32 < D, so the maximum
+ * required shift is 31.
+ */
+ int bitshift = 32;
+ png_fixed_point result = 0; /* NOTE: signed */
+
+ while (--bitshift >= 0)
+ {
+ png_uint_32 d32, d00;
+
+ if (bitshift > 0)
+ d32 = D >> (32-bitshift), d00 = D << bitshift;
+
+ else
+ d32 = 0, d00 = D;
+
+ if (s32 > d32)
+ {
+ if (s00 < d00) --s32; /* carry */
+ s32 -= d32, s00 -= d00, result += 1<<bitshift;
+ }
+
+ else
+ if (s32 == d32 && s00 >= d00)
+ s32 = 0, s00 -= d00, result += 1<<bitshift;
+ }
+
+ /* Handle the rounding. */
+ if (s00 >= (D >> 1))
+ ++result;
+
+ if (negative)
+ result = -result;
+
+ /* Check for overflow. */
+ if ((negative && result <= 0) || (!negative && result >= 0))
+ {
+ *res = result;
+ return 1;
+ }
+ }
+#endif
+ }
+ }
+
+ return 0;
+}
+#endif /* READ_GAMMA || INCH_CONVERSIONS */
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* The following is for when the caller doesn't much care about the
+ * result.
+ */
+png_fixed_point
+png_muldiv_warn(png_const_structrp png_ptr, png_fixed_point a, png_int_32 times,
+ png_int_32 divisor)
+{
+ png_fixed_point result;
+
+ if (png_muldiv(&result, a, times, divisor))
+ return result;
+
+ png_warning(png_ptr, "fixed point overflow ignored");
+ return 0;
+}
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED /* more fixed point functions for gamma */
+/* Calculate a reciprocal, return 0 on div-by-zero or overflow. */
+png_fixed_point
+png_reciprocal(png_fixed_point a)
+{
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = floor(1E10/a+.5);
+
+ if (r <= 2147483647. && r >= -2147483648.)
+ return (png_fixed_point)r;
+#else
+ png_fixed_point res;
+
+ if (png_muldiv(&res, 100000, 100000, a))
+ return res;
+#endif
+
+ return 0; /* error/overflow */
+}
+
+/* This is the shared test on whether a gamma value is 'significant' - whether
+ * it is worth doing gamma correction.
+ */
+int /* PRIVATE */
+png_gamma_significant(png_fixed_point gamma_val)
+{
+ return gamma_val < PNG_FP_1 - PNG_GAMMA_THRESHOLD_FIXED ||
+ gamma_val > PNG_FP_1 + PNG_GAMMA_THRESHOLD_FIXED;
+}
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* A local convenience routine. */
+static png_fixed_point
+png_product2(png_fixed_point a, png_fixed_point b)
+{
+ /* The required result is 1/a * 1/b; the following preserves accuracy. */
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = a * 1E-5;
+ r *= b;
+ r = floor(r+.5);
+
+ if (r <= 2147483647. && r >= -2147483648.)
+ return (png_fixed_point)r;
+#else
+ png_fixed_point res;
+
+ if (png_muldiv(&res, a, b, 100000))
+ return res;
+#endif
+
+ return 0; /* overflow */
+}
+
+/* The inverse of the above. */
+png_fixed_point
+png_reciprocal2(png_fixed_point a, png_fixed_point b)
+{
+ /* The required result is 1/a * 1/b; the following preserves accuracy. */
+#ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = 1E15/a;
+ r /= b;
+ r = floor(r+.5);
+
+ if (r <= 2147483647. && r >= -2147483648.)
+ return (png_fixed_point)r;
+#else
+ /* This may overflow because the range of png_fixed_point isn't symmetric,
+ * but this API is only used for the product of file and screen gamma so it
+ * doesn't matter that the smallest number it can produce is 1/21474, not
+ * 1/100000
+ */
+ png_fixed_point res = png_product2(a, b);
+
+ if (res != 0)
+ return png_reciprocal(res);
+#endif
+
+ return 0; /* overflow */
+}
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED /* gamma table code */
+#ifndef PNG_FLOATING_ARITHMETIC_SUPPORTED
+/* Fixed point gamma.
+ *
+ * The code to calculate the tables used below can be found in the shell script
+ * contrib/tools/intgamma.sh
+ *
+ * To calculate gamma this code implements fast log() and exp() calls using only
+ * fixed point arithmetic. This code has sufficient precision for either 8-bit
+ * or 16-bit sample values.
+ *
+ * The tables used here were calculated using simple 'bc' programs, but C double
+ * precision floating point arithmetic would work fine.
+ *
+ * 8-bit log table
+ * This is a table of -log(value/255)/log(2) for 'value' in the range 128 to
+ * 255, so it's the base 2 logarithm of a normalized 8-bit floating point
+ * mantissa. The numbers are 32-bit fractions.
+ */
+static const png_uint_32
+png_8bit_l2[128] =
+{
+ 4270715492U, 4222494797U, 4174646467U, 4127164793U, 4080044201U, 4033279239U,
+ 3986864580U, 3940795015U, 3895065449U, 3849670902U, 3804606499U, 3759867474U,
+ 3715449162U, 3671346997U, 3627556511U, 3584073329U, 3540893168U, 3498011834U,
+ 3455425220U, 3413129301U, 3371120137U, 3329393864U, 3287946700U, 3246774933U,
+ 3205874930U, 3165243125U, 3124876025U, 3084770202U, 3044922296U, 3005329011U,
+ 2965987113U, 2926893432U, 2888044853U, 2849438323U, 2811070844U, 2772939474U,
+ 2735041326U, 2697373562U, 2659933400U, 2622718104U, 2585724991U, 2548951424U,
+ 2512394810U, 2476052606U, 2439922311U, 2404001468U, 2368287663U, 2332778523U,
+ 2297471715U, 2262364947U, 2227455964U, 2192742551U, 2158222529U, 2123893754U,
+ 2089754119U, 2055801552U, 2022034013U, 1988449497U, 1955046031U, 1921821672U,
+ 1888774511U, 1855902668U, 1823204291U, 1790677560U, 1758320682U, 1726131893U,
+ 1694109454U, 1662251657U, 1630556815U, 1599023271U, 1567649391U, 1536433567U,
+ 1505374214U, 1474469770U, 1443718700U, 1413119487U, 1382670639U, 1352370686U,
+ 1322218179U, 1292211689U, 1262349810U, 1232631153U, 1203054352U, 1173618059U,
+ 1144320946U, 1115161701U, 1086139034U, 1057251672U, 1028498358U, 999877854U,
+ 971388940U, 943030410U, 914801076U, 886699767U, 858725327U, 830876614U,
+ 803152505U, 775551890U, 748073672U, 720716771U, 693480120U, 666362667U,
+ 639363374U, 612481215U, 585715177U, 559064263U, 532527486U, 506103872U,
+ 479792461U, 453592303U, 427502463U, 401522014U, 375650043U, 349885648U,
+ 324227938U, 298676034U, 273229066U, 247886176U, 222646516U, 197509248U,
+ 172473545U, 147538590U, 122703574U, 97967701U, 73330182U, 48790236U,
+ 24347096U, 0U
+
+#if 0
+ /* The following are the values for 16-bit tables - these work fine for the
+ * 8-bit conversions but produce very slightly larger errors in the 16-bit
+ * log (about 1.2 as opposed to 0.7 absolute error in the final value). To
+ * use these all the shifts below must be adjusted appropriately.
+ */
+ 65166, 64430, 63700, 62976, 62257, 61543, 60835, 60132, 59434, 58741, 58054,
+ 57371, 56693, 56020, 55352, 54689, 54030, 53375, 52726, 52080, 51439, 50803,
+ 50170, 49542, 48918, 48298, 47682, 47070, 46462, 45858, 45257, 44661, 44068,
+ 43479, 42894, 42312, 41733, 41159, 40587, 40020, 39455, 38894, 38336, 37782,
+ 37230, 36682, 36137, 35595, 35057, 34521, 33988, 33459, 32932, 32408, 31887,
+ 31369, 30854, 30341, 29832, 29325, 28820, 28319, 27820, 27324, 26830, 26339,
+ 25850, 25364, 24880, 24399, 23920, 23444, 22970, 22499, 22029, 21562, 21098,
+ 20636, 20175, 19718, 19262, 18808, 18357, 17908, 17461, 17016, 16573, 16132,
+ 15694, 15257, 14822, 14390, 13959, 13530, 13103, 12678, 12255, 11834, 11415,
+ 10997, 10582, 10168, 9756, 9346, 8937, 8531, 8126, 7723, 7321, 6921, 6523,
+ 6127, 5732, 5339, 4947, 4557, 4169, 3782, 3397, 3014, 2632, 2251, 1872, 1495,
+ 1119, 744, 372
+#endif
+};
+
+static png_int_32
+png_log8bit(unsigned int x)
+{
+ unsigned int lg2 = 0;
+ /* Each time 'x' is multiplied by 2, 1 must be subtracted off the final log,
+ * because the log is actually negate that means adding 1. The final
+ * returned value thus has the range 0 (for 255 input) to 7.994 (for 1
+ * input), return -1 for the overflow (log 0) case, - so the result is
+ * always at most 19 bits.
+ */
+ if ((x &= 0xff) == 0)
+ return -1;
+
+ if ((x & 0xf0) == 0)
+ lg2 = 4, x <<= 4;
+
+ if ((x & 0xc0) == 0)
+ lg2 += 2, x <<= 2;
+
+ if ((x & 0x80) == 0)
+ lg2 += 1, x <<= 1;
+
+ /* result is at most 19 bits, so this cast is safe: */
+ return (png_int_32)((lg2 << 16) + ((png_8bit_l2[x-128]+32768)>>16));
+}
+
+/* The above gives exact (to 16 binary places) log2 values for 8-bit images,
+ * for 16-bit images we use the most significant 8 bits of the 16-bit value to
+ * get an approximation then multiply the approximation by a correction factor
+ * determined by the remaining up to 8 bits. This requires an additional step
+ * in the 16-bit case.
+ *
+ * We want log2(value/65535), we have log2(v'/255), where:
+ *
+ * value = v' * 256 + v''
+ * = v' * f
+ *
+ * So f is value/v', which is equal to (256+v''/v') since v' is in the range 128
+ * to 255 and v'' is in the range 0 to 255 f will be in the range 256 to less
+ * than 258. The final factor also needs to correct for the fact that our 8-bit
+ * value is scaled by 255, whereas the 16-bit values must be scaled by 65535.
+ *
+ * This gives a final formula using a calculated value 'x' which is value/v' and
+ * scaling by 65536 to match the above table:
+ *
+ * log2(x/257) * 65536
+ *
+ * Since these numbers are so close to '1' we can use simple linear
+ * interpolation between the two end values 256/257 (result -368.61) and 258/257
+ * (result 367.179). The values used below are scaled by a further 64 to give
+ * 16-bit precision in the interpolation:
+ *
+ * Start (256): -23591
+ * Zero (257): 0
+ * End (258): 23499
+ */
+static png_int_32
+png_log16bit(png_uint_32 x)
+{
+ unsigned int lg2 = 0;
+
+ /* As above, but now the input has 16 bits. */
+ if ((x &= 0xffff) == 0)
+ return -1;
+
+ if ((x & 0xff00) == 0)
+ lg2 = 8, x <<= 8;
+
+ if ((x & 0xf000) == 0)
+ lg2 += 4, x <<= 4;
+
+ if ((x & 0xc000) == 0)
+ lg2 += 2, x <<= 2;
+
+ if ((x & 0x8000) == 0)
+ lg2 += 1, x <<= 1;
+
+ /* Calculate the base logarithm from the top 8 bits as a 28-bit fractional
+ * value.
+ */
+ lg2 <<= 28;
+ lg2 += (png_8bit_l2[(x>>8)-128]+8) >> 4;
+
+ /* Now we need to interpolate the factor, this requires a division by the top
+ * 8 bits. Do this with maximum precision.
+ */
+ x = ((x << 16) + (x >> 9)) / (x >> 8);
+
+ /* Since we divided by the top 8 bits of 'x' there will be a '1' at 1<<24,
+ * the value at 1<<16 (ignoring this) will be 0 or 1; this gives us exactly
+ * 16 bits to interpolate to get the low bits of the result. Round the
+ * answer. Note that the end point values are scaled by 64 to retain overall
+ * precision and that 'lg2' is current scaled by an extra 12 bits, so adjust
+ * the overall scaling by 6-12. Round at every step.
+ */
+ x -= 1U << 24;
+
+ if (x <= 65536U) /* <= '257' */
+ lg2 += ((23591U * (65536U-x)) + (1U << (16+6-12-1))) >> (16+6-12);
+
+ else
+ lg2 -= ((23499U * (x-65536U)) + (1U << (16+6-12-1))) >> (16+6-12);
+
+ /* Safe, because the result can't have more than 20 bits: */
+ return (png_int_32)((lg2 + 2048) >> 12);
+}
+
+/* The 'exp()' case must invert the above, taking a 20-bit fixed point
+ * logarithmic value and returning a 16 or 8-bit number as appropriate. In
+ * each case only the low 16 bits are relevant - the fraction - since the
+ * integer bits (the top 4) simply determine a shift.
+ *
+ * The worst case is the 16-bit distinction between 65535 and 65534, this
+ * requires perhaps spurious accuracty in the decoding of the logarithm to
+ * distinguish log2(65535/65534.5) - 10^-5 or 17 bits. There is little chance
+ * of getting this accuracy in practice.
+ *
+ * To deal with this the following exp() function works out the exponent of the
+ * frational part of the logarithm by using an accurate 32-bit value from the
+ * top four fractional bits then multiplying in the remaining bits.
+ */
+static const png_uint_32
+png_32bit_exp[16] =
+{
+ /* NOTE: the first entry is deliberately set to the maximum 32-bit value. */
+ 4294967295U, 4112874773U, 3938502376U, 3771522796U, 3611622603U, 3458501653U,
+ 3311872529U, 3171459999U, 3037000500U, 2908241642U, 2784941738U, 2666869345U,
+ 2553802834U, 2445529972U, 2341847524U, 2242560872U
+};
+
+/* Adjustment table; provided to explain the numbers in the code below. */
+#if 0
+for (i=11;i>=0;--i){ print i, " ", (1 - e(-(2^i)/65536*l(2))) * 2^(32-i), "\n"}
+ 11 44937.64284865548751208448
+ 10 45180.98734845585101160448
+ 9 45303.31936980687359311872
+ 8 45364.65110595323018870784
+ 7 45395.35850361789624614912
+ 6 45410.72259715102037508096
+ 5 45418.40724413220722311168
+ 4 45422.25021786898173001728
+ 3 45424.17186732298419044352
+ 2 45425.13273269940811464704
+ 1 45425.61317555035558641664
+ 0 45425.85339951654943850496
+#endif
+
+static png_uint_32
+png_exp(png_fixed_point x)
+{
+ if (x > 0 && x <= 0xfffff) /* Else overflow or zero (underflow) */
+ {
+ /* Obtain a 4-bit approximation */
+ png_uint_32 e = png_32bit_exp[(x >> 12) & 0xf];
+
+ /* Incorporate the low 12 bits - these decrease the returned value by
+ * multiplying by a number less than 1 if the bit is set. The multiplier
+ * is determined by the above table and the shift. Notice that the values
+ * converge on 45426 and this is used to allow linear interpolation of the
+ * low bits.
+ */
+ if (x & 0x800)
+ e -= (((e >> 16) * 44938U) + 16U) >> 5;
+
+ if (x & 0x400)
+ e -= (((e >> 16) * 45181U) + 32U) >> 6;
+
+ if (x & 0x200)
+ e -= (((e >> 16) * 45303U) + 64U) >> 7;
+
+ if (x & 0x100)
+ e -= (((e >> 16) * 45365U) + 128U) >> 8;
+
+ if (x & 0x080)
+ e -= (((e >> 16) * 45395U) + 256U) >> 9;
+
+ if (x & 0x040)
+ e -= (((e >> 16) * 45410U) + 512U) >> 10;
+
+ /* And handle the low 6 bits in a single block. */
+ e -= (((e >> 16) * 355U * (x & 0x3fU)) + 256U) >> 9;
+
+ /* Handle the upper bits of x. */
+ e >>= x >> 16;
+ return e;
+ }
+
+ /* Check for overflow */
+ if (x <= 0)
+ return png_32bit_exp[0];
+
+ /* Else underflow */
+ return 0;
+}
+
+static png_byte
+png_exp8bit(png_fixed_point lg2)
+{
+ /* Get a 32-bit value: */
+ png_uint_32 x = png_exp(lg2);
+
+ /* Convert the 32-bit value to 0..255 by multiplying by 256-1, note that the
+ * second, rounding, step can't overflow because of the first, subtraction,
+ * step.
+ */
+ x -= x >> 8;
+ return (png_byte)((x + 0x7fffffU) >> 24);
+}
+
+static png_uint_16
+png_exp16bit(png_fixed_point lg2)
+{
+ /* Get a 32-bit value: */
+ png_uint_32 x = png_exp(lg2);
+
+ /* Convert the 32-bit value to 0..65535 by multiplying by 65536-1: */
+ x -= x >> 16;
+ return (png_uint_16)((x + 32767U) >> 16);
+}
+#endif /* FLOATING_ARITHMETIC */
+
+png_byte
+png_gamma_8bit_correct(unsigned int value, png_fixed_point gamma_val)
+{
+ if (value > 0 && value < 255)
+ {
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = floor(255*pow(value/255.,gamma_val*.00001)+.5);
+ return (png_byte)r;
+# else
+ png_int_32 lg2 = png_log8bit(value);
+ png_fixed_point res;
+
+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
+ return png_exp8bit(res);
+
+ /* Overflow. */
+ value = 0;
+# endif
+ }
+
+ return (png_byte)value;
+}
+
+png_uint_16
+png_gamma_16bit_correct(unsigned int value, png_fixed_point gamma_val)
+{
+ if (value > 0 && value < 65535)
+ {
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ double r = floor(65535*pow(value/65535.,gamma_val*.00001)+.5);
+ return (png_uint_16)r;
+# else
+ png_int_32 lg2 = png_log16bit(value);
+ png_fixed_point res;
+
+ if (png_muldiv(&res, gamma_val, lg2, PNG_FP_1))
+ return png_exp16bit(res);
+
+ /* Overflow. */
+ value = 0;
+# endif
+ }
+
+ return (png_uint_16)value;
+}
+
+/* This does the right thing based on the bit_depth field of the
+ * png_struct, interpreting values as 8-bit or 16-bit. While the result
+ * is nominally a 16-bit value if bit depth is 8 then the result is
+ * 8-bit (as are the arguments.)
+ */
+png_uint_16 /* PRIVATE */
+png_gamma_correct(png_structrp png_ptr, unsigned int value,
+ png_fixed_point gamma_val)
+{
+ if (png_ptr->bit_depth == 8)
+ return png_gamma_8bit_correct(value, gamma_val);
+
+ else
+ return png_gamma_16bit_correct(value, gamma_val);
+}
+
+/* Internal function to build a single 16-bit table - the table consists of
+ * 'num' 256 entry subtables, where 'num' is determined by 'shift' - the amount
+ * to shift the input values right (or 16-number_of_signifiant_bits).
+ *
+ * The caller is responsible for ensuring that the table gets cleaned up on
+ * png_error (i.e. if one of the mallocs below fails) - i.e. the *table argument
+ * should be somewhere that will be cleaned.
+ */
+static void
+png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable,
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+{
+ /* Various values derived from 'shift': */
+ PNG_CONST unsigned int num = 1U << (8U - shift);
+ PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+ PNG_CONST unsigned int max_by_2 = 1U << (15U-shift);
+ unsigned int i;
+
+ png_uint_16pp table = *ptable =
+ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
+
+ for (i = 0; i < num; i++)
+ {
+ png_uint_16p sub_table = table[i] =
+ (png_uint_16p)png_malloc(png_ptr, 256 * (sizeof (png_uint_16)));
+
+ /* The 'threshold' test is repeated here because it can arise for one of
+ * the 16-bit tables even if the others don't hit it.
+ */
+ if (png_gamma_significant(gamma_val))
+ {
+ /* The old code would overflow at the end and this would cause the
+ * 'pow' function to return a result >1, resulting in an
+ * arithmetic error. This code follows the spec exactly; ig is
+ * the recovered input sample, it always has 8-16 bits.
+ *
+ * We want input * 65535/max, rounded, the arithmetic fits in 32
+ * bits (unsigned) so long as max <= 32767.
+ */
+ unsigned int j;
+ for (j = 0; j < 256; j++)
+ {
+ png_uint_32 ig = (j << (8-shift)) + i;
+# ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED
+ /* Inline the 'max' scaling operation: */
+ double d = floor(65535*pow(ig/(double)max, gamma_val*.00001)+.5);
+ sub_table[j] = (png_uint_16)d;
+# else
+ if (shift)
+ ig = (ig * 65535U + max_by_2)/max;
+
+ sub_table[j] = png_gamma_16bit_correct(ig, gamma_val);
+# endif
+ }
+ }
+ else
+ {
+ /* We must still build a table, but do it the fast way. */
+ unsigned int j;
+
+ for (j = 0; j < 256; j++)
+ {
+ png_uint_32 ig = (j << (8-shift)) + i;
+
+ if (shift)
+ ig = (ig * 65535U + max_by_2)/max;
+
+ sub_table[j] = (png_uint_16)ig;
+ }
+ }
+ }
+}
+
+/* NOTE: this function expects the *inverse* of the overall gamma transformation
+ * required.
+ */
+static void
+png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable,
+ PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val)
+{
+ PNG_CONST unsigned int num = 1U << (8U - shift);
+ PNG_CONST unsigned int max = (1U << (16U - shift))-1U;
+ unsigned int i;
+ png_uint_32 last;
+
+ png_uint_16pp table = *ptable =
+ (png_uint_16pp)png_calloc(png_ptr, num * (sizeof (png_uint_16p)));
+
+ /* 'num' is the number of tables and also the number of low bits of low
+ * bits of the input 16-bit value used to select a table. Each table is
+ * itself index by the high 8 bits of the value.
+ */
+ for (i = 0; i < num; i++)
+ table[i] = (png_uint_16p)png_malloc(png_ptr,
+ 256 * (sizeof (png_uint_16)));
+
+ /* 'gamma_val' is set to the reciprocal of the value calculated above, so
+ * pow(out,g) is an *input* value. 'last' is the last input value set.
+ *
+ * In the loop 'i' is used to find output values. Since the output is
+ * 8-bit there are only 256 possible values. The tables are set up to
+ * select the closest possible output value for each input by finding
+ * the input value at the boundary between each pair of output values
+ * and filling the table up to that boundary with the lower output
+ * value.
+ *
+ * The boundary values are 0.5,1.5..253.5,254.5. Since these are 9-bit
+ * values the code below uses a 16-bit value in i; the values start at
+ * 128.5 (for 0.5) and step by 257, for a total of 254 values (the last
+ * entries are filled with 255). Start i at 128 and fill all 'last'
+ * table entries <= 'max'
+ */
+ last = 0;
+ for (i = 0; i < 255; ++i) /* 8-bit output value */
+ {
+ /* Find the corresponding maximum input value */
+ png_uint_16 out = (png_uint_16)(i * 257U); /* 16-bit output value */
+
+ /* Find the boundary value in 16 bits: */
+ png_uint_32 bound = png_gamma_16bit_correct(out+128U, gamma_val);
+
+ /* Adjust (round) to (16-shift) bits: */
+ bound = (bound * max + 32768U)/65535U + 1U;
+
+ while (last < bound)
+ {
+ table[last & (0xffU >> shift)][last >> (8U - shift)] = out;
+ last++;
+ }
+ }
+
+ /* And fill in the final entries. */
+ while (last < (num << 8))
+ {
+ table[last & (0xff >> shift)][last >> (8U - shift)] = 65535U;
+ last++;
+ }
+}
+
+/* Build a single 8-bit table: same as the 16-bit case but much simpler (and
+ * typically much faster). Note that libpng currently does no sBIT processing
+ * (apparently contrary to the spec) so a 256 entry table is always generated.
+ */
+static void
+png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable,
+ PNG_CONST png_fixed_point gamma_val)
+{
+ unsigned int i;
+ png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256);
+
+ if (png_gamma_significant(gamma_val)) for (i=0; i<256; i++)
+ table[i] = png_gamma_8bit_correct(i, gamma_val);
+
+ else for (i=0; i<256; ++i)
+ table[i] = (png_byte)i;
+}
+
+/* Used from png_read_destroy and below to release the memory used by the gamma
+ * tables.
+ */
+void /* PRIVATE */
+png_destroy_gamma_table(png_structrp png_ptr)
+{
+ png_free(png_ptr, png_ptr->gamma_table);
+ png_ptr->gamma_table = NULL;
+
+ if (png_ptr->gamma_16_table != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_table[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_table);
+ png_ptr->gamma_16_table = NULL;
+ }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ png_free(png_ptr, png_ptr->gamma_from_1);
+ png_ptr->gamma_from_1 = NULL;
+ png_free(png_ptr, png_ptr->gamma_to_1);
+ png_ptr->gamma_to_1 = NULL;
+
+ if (png_ptr->gamma_16_from_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_from_1);
+ png_ptr->gamma_16_from_1 = NULL;
+ }
+ if (png_ptr->gamma_16_to_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_to_1);
+ png_ptr->gamma_16_to_1 = NULL;
+ }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+}
+
+/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future. Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ */
+void /* PRIVATE */
+png_build_gamma_table(png_structrp png_ptr, int bit_depth)
+{
+ png_debug(1, "in png_build_gamma_table");
+
+ /* Remove any existing table; this copes with multiple calls to
+ * png_read_update_info. The warning is because building the gamma tables
+ * multiple times is a performance hit - it's harmless but the ability to call
+ * png_read_update_info() multiple times is new in 1.5.6 so it seems sensible
+ * to warn if the app introduces such a hit.
+ */
+ if (png_ptr->gamma_table != NULL || png_ptr->gamma_16_table != NULL)
+ {
+ png_warning(png_ptr, "gamma table being rebuilt");
+ png_destroy_gamma_table(png_ptr);
+ }
+
+ if (bit_depth <= 8)
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_table,
+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
+ {
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_to_1,
+ png_reciprocal(png_ptr->colorspace.gamma));
+
+ png_build_8bit_table(png_ptr, &png_ptr->gamma_from_1,
+ png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+ }
+ else
+ {
+ png_byte shift, sig_bit;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ sig_bit = png_ptr->sig_bit.red;
+
+ if (png_ptr->sig_bit.green > sig_bit)
+ sig_bit = png_ptr->sig_bit.green;
+
+ if (png_ptr->sig_bit.blue > sig_bit)
+ sig_bit = png_ptr->sig_bit.blue;
+ }
+ else
+ sig_bit = png_ptr->sig_bit.gray;
+
+ /* 16-bit gamma code uses this equation:
+ *
+ * ov = table[(iv & 0xff) >> gamma_shift][iv >> 8]
+ *
+ * Where 'iv' is the input color value and 'ov' is the output value -
+ * pow(iv, gamma).
+ *
+ * Thus the gamma table consists of up to 256 256 entry tables. The table
+ * is selected by the (8-gamma_shift) most significant of the low 8 bits of
+ * the color value then indexed by the upper 8 bits:
+ *
+ * table[low bits][high 8 bits]
+ *
+ * So the table 'n' corresponds to all those 'iv' of:
+ *
+ * <all high 8-bit values><n << gamma_shift>..<(n+1 << gamma_shift)-1>
+ *
+ */
+ if (sig_bit > 0 && sig_bit < 16U)
+ shift = (png_byte)(16U - sig_bit); /* shift == insignificant bits */
+
+ else
+ shift = 0; /* keep all 16 bits */
+
+ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
+ {
+ /* PNG_MAX_GAMMA_8 is the number of bits to keep - effectively
+ * the significant bits in the *input* when the output will
+ * eventually be 8 bits. By default it is 11.
+ */
+ if (shift < (16U - PNG_MAX_GAMMA_8))
+ shift = (16U - PNG_MAX_GAMMA_8);
+ }
+
+ if (shift > 8U)
+ shift = 8U; /* Guarantees at least one table! */
+
+ png_ptr->gamma_shift = shift;
+
+#ifdef PNG_16BIT_SUPPORTED
+ /* NOTE: prior to 1.5.4 this test used to include PNG_BACKGROUND (now
+ * PNG_COMPOSE). This effectively smashed the background calculation for
+ * 16-bit output because the 8-bit table assumes the result will be reduced
+ * to 8 bits.
+ */
+ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_SCALE_16_TO_8))
+#endif
+ png_build_16to8_table(png_ptr, &png_ptr->gamma_16_table, shift,
+ png_ptr->screen_gamma > 0 ? png_product2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+
+#ifdef PNG_16BIT_SUPPORTED
+ else
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_table, shift,
+ png_ptr->screen_gamma > 0 ? png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma) : PNG_FP_1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & (PNG_COMPOSE | PNG_RGB_TO_GRAY))
+ {
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_to_1, shift,
+ png_reciprocal(png_ptr->colorspace.gamma));
+
+ /* Notice that the '16 from 1' table should be full precision, however
+ * the lookup on this table still uses gamma_shift, so it can't be.
+ * TODO: fix this.
+ */
+ png_build_16bit_table(png_ptr, &png_ptr->gamma_16_from_1, shift,
+ png_ptr->screen_gamma > 0 ? png_reciprocal(png_ptr->screen_gamma) :
+ png_ptr->colorspace.gamma/* Probably doing rgb_to_gray */);
+ }
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+ }
+}
+#endif /* READ_GAMMA */
+
+/* HARDWARE OPTION SUPPORT */
+#ifdef PNG_SET_OPTION_SUPPORTED
+int PNGAPI
+png_set_option(png_structrp png_ptr, int option, int onoff)
+{
+ if (png_ptr != NULL && option >= 0 && option < PNG_OPTION_NEXT &&
+ (option & 1) == 0)
+ {
+ int mask = 3 << option;
+ int setting = (2 + (onoff != 0)) << option;
+ int current = png_ptr->options;
+
+ png_ptr->options = (png_byte)((current & ~mask) | setting);
+
+ return (current & mask) >> option;
+ }
+
+ return PNG_OPTION_INVALID;
+}
+#endif
+
+/* sRGB support */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+/* sRGB conversion tables; these are machine generated with the code in
+ * contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the
+ * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
+ * is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
+ * The sRGB to linear table is exact (to the nearest 16 bit linear fraction).
+ * The inverse (linear to sRGB) table has accuracies as follows:
+ *
+ * For all possible (255*65535+1) input values:
+ *
+ * error: -0.515566 - 0.625971, 79441 (0.475369%) of readings inexact
+ *
+ * For the input values corresponding to the 65536 16-bit values:
+ *
+ * error: -0.513727 - 0.607759, 308 (0.469978%) of readings inexact
+ *
+ * In all cases the inexact readings are off by one.
+ */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* The convert-to-sRGB table is only currently required for read. */
+const png_uint_16 png_sRGB_table[256] =
+{
+ 0,20,40,60,80,99,119,139,
+ 159,179,199,219,241,264,288,313,
+ 340,367,396,427,458,491,526,562,
+ 599,637,677,718,761,805,851,898,
+ 947,997,1048,1101,1156,1212,1270,1330,
+ 1391,1453,1517,1583,1651,1720,1790,1863,
+ 1937,2013,2090,2170,2250,2333,2418,2504,
+ 2592,2681,2773,2866,2961,3058,3157,3258,
+ 3360,3464,3570,3678,3788,3900,4014,4129,
+ 4247,4366,4488,4611,4736,4864,4993,5124,
+ 5257,5392,5530,5669,5810,5953,6099,6246,
+ 6395,6547,6700,6856,7014,7174,7335,7500,
+ 7666,7834,8004,8177,8352,8528,8708,8889,
+ 9072,9258,9445,9635,9828,10022,10219,10417,
+ 10619,10822,11028,11235,11446,11658,11873,12090,
+ 12309,12530,12754,12980,13209,13440,13673,13909,
+ 14146,14387,14629,14874,15122,15371,15623,15878,
+ 16135,16394,16656,16920,17187,17456,17727,18001,
+ 18277,18556,18837,19121,19407,19696,19987,20281,
+ 20577,20876,21177,21481,21787,22096,22407,22721,
+ 23038,23357,23678,24002,24329,24658,24990,25325,
+ 25662,26001,26344,26688,27036,27386,27739,28094,
+ 28452,28813,29176,29542,29911,30282,30656,31033,
+ 31412,31794,32179,32567,32957,33350,33745,34143,
+ 34544,34948,35355,35764,36176,36591,37008,37429,
+ 37852,38278,38706,39138,39572,40009,40449,40891,
+ 41337,41785,42236,42690,43147,43606,44069,44534,
+ 45002,45473,45947,46423,46903,47385,47871,48359,
+ 48850,49344,49841,50341,50844,51349,51858,52369,
+ 52884,53401,53921,54445,54971,55500,56032,56567,
+ 57105,57646,58190,58737,59287,59840,60396,60955,
+ 61517,62082,62650,63221,63795,64372,64952,65535
+};
+
+#endif /* simplified read only */
+
+/* The base/delta tables are required for both read and write (but currently
+ * only the simplified versions.)
+ */
+const png_uint_16 png_sRGB_base[512] =
+{
+ 128,1782,3383,4644,5675,6564,7357,8074,
+ 8732,9346,9921,10463,10977,11466,11935,12384,
+ 12816,13233,13634,14024,14402,14769,15125,15473,
+ 15812,16142,16466,16781,17090,17393,17690,17981,
+ 18266,18546,18822,19093,19359,19621,19879,20133,
+ 20383,20630,20873,21113,21349,21583,21813,22041,
+ 22265,22487,22707,22923,23138,23350,23559,23767,
+ 23972,24175,24376,24575,24772,24967,25160,25352,
+ 25542,25730,25916,26101,26284,26465,26645,26823,
+ 27000,27176,27350,27523,27695,27865,28034,28201,
+ 28368,28533,28697,28860,29021,29182,29341,29500,
+ 29657,29813,29969,30123,30276,30429,30580,30730,
+ 30880,31028,31176,31323,31469,31614,31758,31902,
+ 32045,32186,32327,32468,32607,32746,32884,33021,
+ 33158,33294,33429,33564,33697,33831,33963,34095,
+ 34226,34357,34486,34616,34744,34873,35000,35127,
+ 35253,35379,35504,35629,35753,35876,35999,36122,
+ 36244,36365,36486,36606,36726,36845,36964,37083,
+ 37201,37318,37435,37551,37668,37783,37898,38013,
+ 38127,38241,38354,38467,38580,38692,38803,38915,
+ 39026,39136,39246,39356,39465,39574,39682,39790,
+ 39898,40005,40112,40219,40325,40431,40537,40642,
+ 40747,40851,40955,41059,41163,41266,41369,41471,
+ 41573,41675,41777,41878,41979,42079,42179,42279,
+ 42379,42478,42577,42676,42775,42873,42971,43068,
+ 43165,43262,43359,43456,43552,43648,43743,43839,
+ 43934,44028,44123,44217,44311,44405,44499,44592,
+ 44685,44778,44870,44962,45054,45146,45238,45329,
+ 45420,45511,45601,45692,45782,45872,45961,46051,
+ 46140,46229,46318,46406,46494,46583,46670,46758,
+ 46846,46933,47020,47107,47193,47280,47366,47452,
+ 47538,47623,47709,47794,47879,47964,48048,48133,
+ 48217,48301,48385,48468,48552,48635,48718,48801,
+ 48884,48966,49048,49131,49213,49294,49376,49458,
+ 49539,49620,49701,49782,49862,49943,50023,50103,
+ 50183,50263,50342,50422,50501,50580,50659,50738,
+ 50816,50895,50973,51051,51129,51207,51285,51362,
+ 51439,51517,51594,51671,51747,51824,51900,51977,
+ 52053,52129,52205,52280,52356,52432,52507,52582,
+ 52657,52732,52807,52881,52956,53030,53104,53178,
+ 53252,53326,53400,53473,53546,53620,53693,53766,
+ 53839,53911,53984,54056,54129,54201,54273,54345,
+ 54417,54489,54560,54632,54703,54774,54845,54916,
+ 54987,55058,55129,55199,55269,55340,55410,55480,
+ 55550,55620,55689,55759,55828,55898,55967,56036,
+ 56105,56174,56243,56311,56380,56448,56517,56585,
+ 56653,56721,56789,56857,56924,56992,57059,57127,
+ 57194,57261,57328,57395,57462,57529,57595,57662,
+ 57728,57795,57861,57927,57993,58059,58125,58191,
+ 58256,58322,58387,58453,58518,58583,58648,58713,
+ 58778,58843,58908,58972,59037,59101,59165,59230,
+ 59294,59358,59422,59486,59549,59613,59677,59740,
+ 59804,59867,59930,59993,60056,60119,60182,60245,
+ 60308,60370,60433,60495,60558,60620,60682,60744,
+ 60806,60868,60930,60992,61054,61115,61177,61238,
+ 61300,61361,61422,61483,61544,61605,61666,61727,
+ 61788,61848,61909,61969,62030,62090,62150,62211,
+ 62271,62331,62391,62450,62510,62570,62630,62689,
+ 62749,62808,62867,62927,62986,63045,63104,63163,
+ 63222,63281,63340,63398,63457,63515,63574,63632,
+ 63691,63749,63807,63865,63923,63981,64039,64097,
+ 64155,64212,64270,64328,64385,64443,64500,64557,
+ 64614,64672,64729,64786,64843,64900,64956,65013,
+ 65070,65126,65183,65239,65296,65352,65409,65465
+};
+
+const png_byte png_sRGB_delta[512] =
+{
+ 207,201,158,129,113,100,90,82,77,72,68,64,61,59,56,54,
+ 52,50,49,47,46,45,43,42,41,40,39,39,38,37,36,36,
+ 35,34,34,33,33,32,32,31,31,30,30,30,29,29,28,28,
+ 28,27,27,27,27,26,26,26,25,25,25,25,24,24,24,24,
+ 23,23,23,23,23,22,22,22,22,22,22,21,21,21,21,21,
+ 21,20,20,20,20,20,20,20,20,19,19,19,19,19,19,19,
+ 19,18,18,18,18,18,18,18,18,18,18,17,17,17,17,17,
+ 17,17,17,17,17,17,16,16,16,16,16,16,16,16,16,16,
+ 16,16,16,16,15,15,15,15,15,15,15,15,15,15,15,15,
+ 15,15,15,15,14,14,14,14,14,14,14,14,14,14,14,14,
+ 14,14,14,14,14,14,14,13,13,13,13,13,13,13,13,13,
+ 13,13,13,13,13,13,13,13,13,13,13,13,13,13,12,12,
+ 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
+ 12,12,12,12,12,12,12,12,12,12,12,12,11,11,11,11,
+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+ 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+ 11,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+ 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
+ 10,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+ 9,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+};
+#endif /* SIMPLIFIED READ/WRITE sRGB support */
+
+/* SIMPLIFIED READ/WRITE SUPPORT */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+static int
+png_image_free_function(png_voidp argument)
+{
+ png_imagep image = png_voidcast(png_imagep, argument);
+ png_controlp cp = image->opaque;
+ png_control c;
+
+ /* Double check that we have a png_ptr - it should be impossible to get here
+ * without one.
+ */
+ if (cp->png_ptr == NULL)
+ return 0;
+
+ /* First free any data held in the control structure. */
+# ifdef PNG_STDIO_SUPPORTED
+ if (cp->owned_file)
+ {
+ FILE *fp = png_voidcast(FILE*, cp->png_ptr->io_ptr);
+ cp->owned_file = 0;
+
+ /* Ignore errors here. */
+ if (fp != NULL)
+ {
+ cp->png_ptr->io_ptr = NULL;
+ (void)fclose(fp);
+ }
+ }
+# endif
+
+ /* Copy the control structure so that the original, allocated, version can be
+ * safely freed. Notice that a png_error here stops the remainder of the
+ * cleanup, but this is probably fine because that would indicate bad memory
+ * problems anyway.
+ */
+ c = *cp;
+ image->opaque = &c;
+ png_free(c.png_ptr, cp);
+
+ /* Then the structures, calling the correct API. */
+ if (c.for_write)
+ {
+# ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+ png_destroy_write_struct(&c.png_ptr, &c.info_ptr);
+# else
+ png_error(c.png_ptr, "simplified write not supported");
+# endif
+ }
+ else
+ {
+# ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+ png_destroy_read_struct(&c.png_ptr, &c.info_ptr, NULL);
+# else
+ png_error(c.png_ptr, "simplified read not supported");
+# endif
+ }
+
+ /* Success. */
+ return 1;
+}
+
+void PNGAPI
+png_image_free(png_imagep image)
+{
+ /* Safely call the real function, but only if doing so is safe at this point
+ * (if not inside an error handling context). Otherwise assume
+ * png_safe_execute will call this API after the return.
+ */
+ if (image != NULL && image->opaque != NULL &&
+ image->opaque->error_buf == NULL)
+ {
+ /* Ignore errors here: */
+ (void)png_safe_execute(image, png_image_free_function, image);
+ image->opaque = NULL;
+ }
+}
+
+int /* PRIVATE */
+png_image_error(png_imagep image, png_const_charp error_message)
+{
+ /* Utility to log an error. */
+ png_safecat(image->message, (sizeof image->message), 0, error_message);
+ image->warning_or_error |= PNG_IMAGE_ERROR;
+ png_image_free(image);
+ return 0;
+}
+
+#endif /* SIMPLIFIED READ/WRITE */
+#endif /* defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngerror.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngerror.c
new file mode 100644
index 0000000000..e53c932542
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngerror.c
@@ -0,0 +1,933 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all error handling. Users who
+ * need special error handling are expected to write replacement functions
+ * and use png_set_error_fn() to use those functions. See the instructions
+ * at each function.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+static PNG_FUNCTION(void, png_default_error,PNGARG((png_const_structrp png_ptr,
+ png_const_charp error_message)),PNG_NORETURN);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+static void /* PRIVATE */
+png_default_warning PNGARG((png_const_structrp png_ptr,
+ png_const_charp warning_message));
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+/* This function is called whenever there is a fatal error. This function
+ * should not be changed. If there is a need to handle errors differently,
+ * you should supply a replacement error function and use png_set_error_fn()
+ * to replace the error function at run-time.
+ */
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+PNG_FUNCTION(void,PNGAPI
+png_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ char msg[16];
+ if (png_ptr != NULL)
+ {
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+ {
+ if (*error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ for (offset = 1; offset<15; offset++)
+ if (error_message[offset] == ' ')
+ break;
+
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ int i;
+ for (i = 0; i < offset - 1; i++)
+ msg[i] = error_message[i + 1];
+ msg[i - 1] = '\0';
+ error_message = msg;
+ }
+
+ else
+ error_message += offset;
+ }
+
+ else
+ {
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ msg[0] = '0';
+ msg[1] = '\0';
+ error_message = msg;
+ }
+ }
+ }
+ }
+#endif
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr),
+ error_message);
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, error_message);
+}
+#else
+PNG_FUNCTION(void,PNGAPI
+png_err,(png_const_structrp png_ptr),PNG_NORETURN)
+{
+ /* Prior to 1.5.2 the error_fn received a NULL pointer, expressed
+ * erroneously as '\0', instead of the empty string "". This was
+ * apparently an error, introduced in libpng-1.2.20, and png_default_error
+ * will crash in this case.
+ */
+ if (png_ptr != NULL && png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_constcast(png_structrp,png_ptr), "");
+
+ /* If the custom handler doesn't exist, or if it returns,
+ use the default handler, which will not return. */
+ png_default_error(png_ptr, "");
+}
+#endif /* PNG_ERROR_TEXT_SUPPORTED */
+
+/* Utility to safely appends strings to a buffer. This never errors out so
+ * error checking is not required in the caller.
+ */
+size_t
+png_safecat(png_charp buffer, size_t bufsize, size_t pos,
+ png_const_charp string)
+{
+ if (buffer != NULL && pos < bufsize)
+ {
+ if (string != NULL)
+ while (*string != '\0' && pos < bufsize-1)
+ buffer[pos++] = *string++;
+
+ buffer[pos] = '\0';
+ }
+
+ return pos;
+}
+
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Utility to dump an unsigned value into a buffer, given a start pointer and
+ * and end pointer (which should point just *beyond* the end of the buffer!)
+ * Returns the pointer to the start of the formatted string.
+ */
+png_charp
+png_format_number(png_const_charp start, png_charp end, int format,
+ png_alloc_size_t number)
+{
+ int count = 0; /* number of digits output */
+ int mincount = 1; /* minimum number required */
+ int output = 0; /* digit output (for the fixed point format) */
+
+ *--end = '\0';
+
+ /* This is written so that the loop always runs at least once, even with
+ * number zero.
+ */
+ while (end > start && (number != 0 || count < mincount))
+ {
+
+ static const char digits[] = "0123456789ABCDEF";
+
+ switch (format)
+ {
+ case PNG_NUMBER_FORMAT_fixed:
+ /* Needs five digits (the fraction) */
+ mincount = 5;
+ if (output || number % 10 != 0)
+ {
+ *--end = digits[number % 10];
+ output = 1;
+ }
+ number /= 10;
+ break;
+
+ case PNG_NUMBER_FORMAT_02u:
+ /* Expects at least 2 digits. */
+ mincount = 2;
+ /* FALL THROUGH */
+
+ case PNG_NUMBER_FORMAT_u:
+ *--end = digits[number % 10];
+ number /= 10;
+ break;
+
+ case PNG_NUMBER_FORMAT_02x:
+ /* This format expects at least two digits */
+ mincount = 2;
+ /* FALL THROUGH */
+
+ case PNG_NUMBER_FORMAT_x:
+ *--end = digits[number & 0xf];
+ number >>= 4;
+ break;
+
+ default: /* an error */
+ number = 0;
+ break;
+ }
+
+ /* Keep track of the number of digits added */
+ ++count;
+
+ /* Float a fixed number here: */
+ if (format == PNG_NUMBER_FORMAT_fixed) if (count == 5) if (end > start)
+ {
+ /* End of the fraction, but maybe nothing was output? In that case
+ * drop the decimal point. If the number is a true zero handle that
+ * here.
+ */
+ if (output)
+ *--end = '.';
+ else if (number == 0) /* and !output */
+ *--end = '0';
+ }
+ }
+
+ return end;
+}
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called whenever there is a non-fatal error. This function
+ * should not be changed. If there is a need to handle warnings differently,
+ * you should supply a replacement warning function and use
+ * png_set_error_fn() to replace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+ int offset = 0;
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (png_ptr->flags&
+ (PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+#endif
+ {
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ for (offset = 1; offset < 15; offset++)
+ if (warning_message[offset] == ' ')
+ break;
+ }
+ }
+ }
+ if (png_ptr != NULL && png_ptr->warning_fn != NULL)
+ (*(png_ptr->warning_fn))(png_constcast(png_structrp,png_ptr),
+ warning_message + offset);
+ else
+ png_default_warning(png_ptr, warning_message + offset);
+}
+
+/* These functions support 'formatted' warning messages with up to
+ * PNG_WARNING_PARAMETER_COUNT parameters. In the format string the parameter
+ * is introduced by @<number>, where 'number' starts at 1. This follows the
+ * standard established by X/Open for internationalizable error messages.
+ */
+void
+png_warning_parameter(png_warning_parameters p, int number,
+ png_const_charp string)
+{
+ if (number > 0 && number <= PNG_WARNING_PARAMETER_COUNT)
+ (void)png_safecat(p[number-1], (sizeof p[number-1]), 0, string);
+}
+
+void
+png_warning_parameter_unsigned(png_warning_parameters p, int number, int format,
+ png_alloc_size_t value)
+{
+ char buffer[PNG_NUMBER_BUFFER_SIZE];
+ png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value));
+}
+
+void
+png_warning_parameter_signed(png_warning_parameters p, int number, int format,
+ png_int_32 value)
+{
+ png_alloc_size_t u;
+ png_charp str;
+ char buffer[PNG_NUMBER_BUFFER_SIZE];
+
+ /* Avoid overflow by doing the negate in a png_alloc_size_t: */
+ u = (png_alloc_size_t)value;
+ if (value < 0)
+ u = ~u + 1;
+
+ str = PNG_FORMAT_NUMBER(buffer, format, u);
+
+ if (value < 0 && str > buffer)
+ *--str = '-';
+
+ png_warning_parameter(p, number, str);
+}
+
+void
+png_formatted_warning(png_const_structrp png_ptr, png_warning_parameters p,
+ png_const_charp message)
+{
+ /* The internal buffer is just 192 bytes - enough for all our messages,
+ * overflow doesn't happen because this code checks! If someone figures
+ * out how to send us a message longer than 192 bytes, all that will
+ * happen is that the message will be truncated appropriately.
+ */
+ size_t i = 0; /* Index in the msg[] buffer: */
+ char msg[192];
+
+ /* Each iteration through the following loop writes at most one character
+ * to msg[i++] then returns here to validate that there is still space for
+ * the trailing '\0'. It may (in the case of a parameter) read more than
+ * one character from message[]; it must check for '\0' and continue to the
+ * test if it finds the end of string.
+ */
+ while (i<(sizeof msg)-1 && *message != '\0')
+ {
+ /* '@' at end of string is now just printed (previously it was skipped);
+ * it is an error in the calling code to terminate the string with @.
+ */
+ if (p != NULL && *message == '@' && message[1] != '\0')
+ {
+ int parameter_char = *++message; /* Consume the '@' */
+ static const char valid_parameters[] = "123456789";
+ int parameter = 0;
+
+ /* Search for the parameter digit, the index in the string is the
+ * parameter to use.
+ */
+ while (valid_parameters[parameter] != parameter_char &&
+ valid_parameters[parameter] != '\0')
+ ++parameter;
+
+ /* If the parameter digit is out of range it will just get printed. */
+ if (parameter < PNG_WARNING_PARAMETER_COUNT)
+ {
+ /* Append this parameter */
+ png_const_charp parm = p[parameter];
+ png_const_charp pend = p[parameter] + (sizeof p[parameter]);
+
+ /* No need to copy the trailing '\0' here, but there is no guarantee
+ * that parm[] has been initialized, so there is no guarantee of a
+ * trailing '\0':
+ */
+ while (i<(sizeof msg)-1 && *parm != '\0' && parm < pend)
+ msg[i++] = *parm++;
+
+ /* Consume the parameter digit too: */
+ ++message;
+ continue;
+ }
+
+ /* else not a parameter and there is a character after the @ sign; just
+ * copy that. This is known not to be '\0' because of the test above.
+ */
+ }
+
+ /* At this point *message can't be '\0', even in the bad parameter case
+ * above where there is a lone '@' at the end of the message string.
+ */
+ msg[i++] = *message++;
+ }
+
+ /* i is always less than (sizeof msg), so: */
+ msg[i] = '\0';
+
+ /* And this is the formatted message. It may be larger than
+ * PNG_MAX_ERROR_TEXT, but that is only used for 'chunk' errors and these
+ * are not (currently) formatted.
+ */
+ png_warning(png_ptr, msg);
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_benign_error(png_const_structrp png_ptr, png_const_charp error_message)
+{
+ if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+ {
+# ifdef PNG_READ_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ png_ptr->chunk_name != 0)
+ png_chunk_warning(png_ptr, error_message);
+ else
+# endif
+ png_warning(png_ptr, error_message);
+ }
+
+ else
+ {
+# ifdef PNG_READ_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ png_ptr->chunk_name != 0)
+ png_chunk_error(png_ptr, error_message);
+ else
+# endif
+ png_error(png_ptr, error_message);
+ }
+}
+
+void /* PRIVATE */
+png_app_warning(png_const_structrp png_ptr, png_const_charp error_message)
+{
+ if (png_ptr->flags & PNG_FLAG_APP_WARNINGS_WARN)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
+}
+
+void /* PRIVATE */
+png_app_error(png_const_structrp png_ptr, png_const_charp error_message)
+{
+ if (png_ptr->flags & PNG_FLAG_APP_ERRORS_WARN)
+ png_warning(png_ptr, error_message);
+ else
+ png_error(png_ptr, error_message);
+}
+#endif /* BENIGN_ERRORS */
+
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk. The chunk name comes from png_ptr->chunk_name,
+ * this is used to prefix the message. The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F'
+};
+
+#define PNG_MAX_ERROR_TEXT 196 /* Currently limited be profile_error in png.c */
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_ERROR_TEXT_SUPPORTED)
+static void /* PRIVATE */
+png_format_buffer(png_const_structrp png_ptr, png_charp buffer, png_const_charp
+ error_message)
+{
+ png_uint_32 chunk_name = png_ptr->chunk_name;
+ int iout = 0, ishift = 24;
+
+ while (ishift >= 0)
+ {
+ int c = (int)(chunk_name >> ishift) & 0xff;
+
+ ishift -= 8;
+ if (isnonalpha(c))
+ {
+ buffer[iout++] = PNG_LITERAL_LEFT_SQUARE_BRACKET;
+ buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+ buffer[iout++] = png_digit[c & 0x0f];
+ buffer[iout++] = PNG_LITERAL_RIGHT_SQUARE_BRACKET;
+ }
+
+ else
+ {
+ buffer[iout++] = (char)c;
+ }
+ }
+
+ if (error_message == NULL)
+ buffer[iout] = '\0';
+
+ else
+ {
+ int iin = 0;
+
+ buffer[iout++] = ':';
+ buffer[iout++] = ' ';
+
+ while (iin < PNG_MAX_ERROR_TEXT-1 && error_message[iin] != '\0')
+ buffer[iout++] = error_message[iin++];
+
+ /* iin < PNG_MAX_ERROR_TEXT, so the following is safe: */
+ buffer[iout] = '\0';
+ }
+}
+#endif /* PNG_WARNINGS_SUPPORTED || PNG_ERROR_TEXT_SUPPORTED */
+
+#if defined(PNG_READ_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
+PNG_FUNCTION(void,PNGAPI
+png_chunk_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+ char msg[18+PNG_MAX_ERROR_TEXT];
+ if (png_ptr == NULL)
+ png_error(png_ptr, error_message);
+
+ else
+ {
+ png_format_buffer(png_ptr, msg, error_message);
+ png_error(png_ptr, msg);
+ }
+}
+#endif /* PNG_READ_SUPPORTED && PNG_ERROR_TEXT_SUPPORTED */
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void PNGAPI
+png_chunk_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+ char msg[18+PNG_MAX_ERROR_TEXT];
+ if (png_ptr == NULL)
+ png_warning(png_ptr, warning_message);
+
+ else
+ {
+ png_format_buffer(png_ptr, msg, warning_message);
+ png_warning(png_ptr, msg);
+ }
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+#ifdef PNG_READ_SUPPORTED
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_chunk_benign_error(png_const_structrp png_ptr, png_const_charp
+ error_message)
+{
+ if (png_ptr->flags & PNG_FLAG_BENIGN_ERRORS_WARN)
+ png_chunk_warning(png_ptr, error_message);
+
+ else
+ png_chunk_error(png_ptr, error_message);
+}
+#endif
+#endif /* PNG_READ_SUPPORTED */
+
+void /* PRIVATE */
+png_chunk_report(png_const_structrp png_ptr, png_const_charp message, int error)
+{
+ /* This is always supported, but for just read or just write it
+ * unconditionally does the right thing.
+ */
+# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
+# endif
+
+# ifdef PNG_READ_SUPPORTED
+ {
+ if (error < PNG_CHUNK_ERROR)
+ png_chunk_warning(png_ptr, message);
+
+ else
+ png_chunk_benign_error(png_ptr, message);
+ }
+# endif
+
+# if defined(PNG_READ_SUPPORTED) && defined(PNG_WRITE_SUPPORTED)
+ else if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
+# endif
+
+# ifdef PNG_WRITE_SUPPORTED
+ {
+ if (error < PNG_CHUNK_WRITE_ERROR)
+ png_app_warning(png_ptr, message);
+
+ else
+ png_app_error(png_ptr, message);
+ }
+# endif
+}
+
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_FUNCTION(void,
+png_fixed_error,(png_const_structrp png_ptr, png_const_charp name),PNG_NORETURN)
+{
+# define fixed_message "fixed point overflow in "
+# define fixed_message_ln ((sizeof fixed_message)-1)
+ int iin;
+ char msg[fixed_message_ln+PNG_MAX_ERROR_TEXT];
+ memcpy(msg, fixed_message, fixed_message_ln);
+ iin = 0;
+ if (name != NULL) while (iin < (PNG_MAX_ERROR_TEXT-1) && name[iin] != 0)
+ {
+ msg[fixed_message_ln + iin] = name[iin];
+ ++iin;
+ }
+ msg[fixed_message_ln + iin] = 0;
+ png_error(png_ptr, msg);
+}
+#endif
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This API only exists if ANSI-C style error handling is used,
+ * otherwise it is necessary for png_default_error to be overridden.
+ */
+jmp_buf* PNGAPI
+png_set_longjmp_fn(png_structrp png_ptr, png_longjmp_ptr longjmp_fn,
+ size_t jmp_buf_size)
+{
+ /* From libpng 1.6.0 the app gets one chance to set a 'jmpbuf_size' value
+ * and it must not change after that. Libpng doesn't care how big the
+ * buffer is, just that it doesn't change.
+ *
+ * If the buffer size is no *larger* than the size of jmp_buf when libpng is
+ * compiled a built in jmp_buf is returned; this preserves the pre-1.6.0
+ * semantics that this call will not fail. If the size is larger, however,
+ * the buffer is allocated and this may fail, causing the function to return
+ * NULL.
+ */
+ if (png_ptr == NULL)
+ return NULL;
+
+ if (png_ptr->jmp_buf_ptr == NULL)
+ {
+ png_ptr->jmp_buf_size = 0; /* not allocated */
+
+ if (jmp_buf_size <= (sizeof png_ptr->jmp_buf_local))
+ png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local;
+
+ else
+ {
+ png_ptr->jmp_buf_ptr = png_voidcast(jmp_buf *,
+ png_malloc_warn(png_ptr, jmp_buf_size));
+
+ if (png_ptr->jmp_buf_ptr == NULL)
+ return NULL; /* new NULL return on OOM */
+
+ png_ptr->jmp_buf_size = jmp_buf_size;
+ }
+ }
+
+ else /* Already allocated: check the size */
+ {
+ size_t size = png_ptr->jmp_buf_size;
+
+ if (size == 0)
+ {
+ size = (sizeof png_ptr->jmp_buf_local);
+ if (png_ptr->jmp_buf_ptr != &png_ptr->jmp_buf_local)
+ {
+ /* This is an internal error in libpng: somehow we have been left
+ * with a stack allocated jmp_buf when the application regained
+ * control. It's always possible to fix this up, but for the moment
+ * this is a png_error because that makes it easy to detect.
+ */
+ png_error(png_ptr, "Libpng jmp_buf still allocated");
+ /* png_ptr->jmp_buf_ptr = &png_ptr->jmp_buf_local; */
+ }
+ }
+
+ if (size != jmp_buf_size)
+ {
+ png_warning(png_ptr, "Application jmp_buf size changed");
+ return NULL; /* caller will probably crash: no choice here */
+ }
+ }
+
+ /* Finally fill in the function, now we have a satisfactory buffer. It is
+ * valid to change the function on every call.
+ */
+ png_ptr->longjmp_fn = longjmp_fn;
+ return png_ptr->jmp_buf_ptr;
+}
+
+void /* PRIVATE */
+png_free_jmpbuf(png_structrp png_ptr)
+{
+ if (png_ptr != NULL)
+ {
+ jmp_buf *jb = png_ptr->jmp_buf_ptr;
+
+ /* A size of 0 is used to indicate a local, stack, allocation of the
+ * pointer; used here and in png.c
+ */
+ if (jb != NULL && png_ptr->jmp_buf_size > 0)
+ {
+
+ /* This stuff is so that a failure to free the error control structure
+ * does not leave libpng in a state with no valid error handling: the
+ * free always succeeds, if there is an error it gets ignored.
+ */
+ if (jb != &png_ptr->jmp_buf_local)
+ {
+ /* Make an internal, libpng, jmp_buf to return here */
+ jmp_buf free_jmp_buf;
+
+ if (!setjmp(free_jmp_buf))
+ {
+ png_ptr->jmp_buf_ptr = &free_jmp_buf; /* come back here */
+ png_ptr->jmp_buf_size = 0; /* stack allocation */
+ png_ptr->longjmp_fn = longjmp;
+ png_free(png_ptr, jb); /* Return to setjmp on error */
+ }
+ }
+ }
+
+ /* *Always* cancel everything out: */
+ png_ptr->jmp_buf_size = 0;
+ png_ptr->jmp_buf_ptr = NULL;
+ png_ptr->longjmp_fn = 0;
+ }
+}
+#endif
+
+/* This is the default error handling function. Note that replacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static PNG_FUNCTION(void /* PRIVATE */,
+png_default_error,(png_const_structrp png_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ /* Check on NULL only added in 1.5.4 */
+ if (error_message != NULL && *error_message == PNG_LITERAL_SHARP)
+ {
+ /* Strip "#nnnn " from beginning of error message. */
+ int offset;
+ char error_number[16];
+ for (offset = 0; offset<15; offset++)
+ {
+ error_number[offset] = error_message[offset + 1];
+ if (error_message[offset] == ' ')
+ break;
+ }
+
+ if ((offset > 1) && (offset < 15))
+ {
+ error_number[offset - 1] = '\0';
+ fprintf(stderr, "libpng error no. %s: %s",
+ error_number, error_message + offset + 1);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+
+ else
+ {
+ fprintf(stderr, "libpng error: %s, offset=%d",
+ error_message, offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+#endif
+ {
+ fprintf(stderr, "libpng error: %s", error_message ? error_message :
+ "undefined");
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+#else
+ PNG_UNUSED(error_message) /* Make compiler happy */
+#endif
+ png_longjmp(png_ptr, 1);
+}
+
+PNG_FUNCTION(void,PNGAPI
+png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ if (png_ptr && png_ptr->longjmp_fn && png_ptr->jmp_buf_ptr)
+ png_ptr->longjmp_fn(*png_ptr->jmp_buf_ptr, val);
+#endif
+
+ /* Here if not setjmp support or if png_ptr is null. */
+ PNG_ABORT();
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want them to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_const_structrp png_ptr, png_const_charp warning_message)
+{
+#ifdef PNG_CONSOLE_IO_SUPPORTED
+# ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*warning_message == PNG_LITERAL_SHARP)
+ {
+ int offset;
+ char warning_number[16];
+ for (offset = 0; offset < 15; offset++)
+ {
+ warning_number[offset] = warning_message[offset + 1];
+ if (warning_message[offset] == ' ')
+ break;
+ }
+
+ if ((offset > 1) && (offset < 15))
+ {
+ warning_number[offset + 1] = '\0';
+ fprintf(stderr, "libpng warning no. %s: %s",
+ warning_number, warning_message + offset);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+
+ else
+ {
+ fprintf(stderr, "libpng warning: %s",
+ warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+ }
+ else
+# endif
+
+ {
+ fprintf(stderr, "libpng warning: %s", warning_message);
+ fprintf(stderr, PNG_STRING_NEWLINE);
+ }
+#else
+ PNG_UNUSED(warning_message) /* Make compiler happy */
+#endif
+ PNG_UNUSED(png_ptr) /* Make compiler happy */
+}
+#endif /* PNG_WARNINGS_SUPPORTED */
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings. Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur. The return
+ * method used in the default routine calls longjmp(png_ptr->jmp_buf_ptr, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structrp png_ptr, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->error_ptr = error_ptr;
+ png_ptr->error_fn = error_fn;
+#ifdef PNG_WARNINGS_SUPPORTED
+ png_ptr->warning_fn = warning_fn;
+#else
+ PNG_UNUSED(warning_fn)
+#endif
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return NULL;
+
+ return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structrp png_ptr, png_uint_32 strip_mode)
+{
+ if (png_ptr != NULL)
+ {
+ png_ptr->flags &=
+ ((~(PNG_FLAG_STRIP_ERROR_NUMBERS |
+ PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+ }
+}
+#endif
+
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+ /* Currently the above both depend on SETJMP_SUPPORTED, however it would be
+ * possible to implement without setjmp support just so long as there is some
+ * way to handle the error return here:
+ */
+PNG_FUNCTION(void /* PRIVATE */,
+png_safe_error,(png_structp png_nonconst_ptr, png_const_charp error_message),
+ PNG_NORETURN)
+{
+ const png_const_structrp png_ptr = png_nonconst_ptr;
+ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+ /* An error is always logged here, overwriting anything (typically a warning)
+ * that is already there:
+ */
+ if (image != NULL)
+ {
+ png_safecat(image->message, (sizeof image->message), 0, error_message);
+ image->warning_or_error |= PNG_IMAGE_ERROR;
+
+ /* Retrieve the jmp_buf from within the png_control, making this work for
+ * C++ compilation too is pretty tricky: C++ wants a pointer to the first
+ * element of a jmp_buf, but C doesn't tell us the type of that.
+ */
+ if (image->opaque != NULL && image->opaque->error_buf != NULL)
+ longjmp(png_control_jmp_buf(image->opaque), 1);
+
+ /* Missing longjmp buffer, the following is to help debugging: */
+ {
+ size_t pos = png_safecat(image->message, (sizeof image->message), 0,
+ "bad longjmp: ");
+ png_safecat(image->message, (sizeof image->message), pos,
+ error_message);
+ }
+ }
+
+ /* Here on an internal programming error. */
+ abort();
+}
+
+#ifdef PNG_WARNINGS_SUPPORTED
+void /* PRIVATE */
+png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message)
+{
+ const png_const_structrp png_ptr = png_nonconst_ptr;
+ png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr);
+
+ /* A warning is only logged if there is no prior warning or error. */
+ if (image->warning_or_error == 0)
+ {
+ png_safecat(image->message, (sizeof image->message), 0, warning_message);
+ image->warning_or_error |= PNG_IMAGE_WARNING;
+ }
+}
+#endif
+
+int /* PRIVATE */
+png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg)
+{
+ volatile png_imagep image = image_in;
+ volatile int result;
+ volatile png_voidp saved_error_buf;
+ jmp_buf safe_jmpbuf;
+
+ /* Safely execute function(arg) with png_error returning to this function. */
+ saved_error_buf = image->opaque->error_buf;
+ result = setjmp(safe_jmpbuf) == 0;
+
+ if (result)
+ {
+
+ image->opaque->error_buf = safe_jmpbuf;
+ result = function(arg);
+ }
+
+ image->opaque->error_buf = saved_error_buf;
+
+ /* And do the cleanup prior to any failure return. */
+ if (!result)
+ png_image_free(image);
+
+ return result;
+}
+#endif /* SIMPLIFIED READ/WRITE */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngget.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngget.c
new file mode 100644
index 0000000000..56ba97090e
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngget.c
@@ -0,0 +1,1178 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngget.c - retrieval of values from info struct
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+png_uint_32 PNGAPI
+png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 flag)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->valid & flag);
+
+ return(0);
+}
+
+png_size_t PNGAPI
+png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->rowbytes);
+
+ return(0);
+}
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+png_bytepp PNGAPI
+png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->row_pointers);
+
+ return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->width;
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->height;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->bit_depth;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->color_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->filter_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->interlace_type;
+
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return info_ptr->compression_type;
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function",
+ "png_get_x_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+ return (info_ptr->x_pixels_per_unit);
+ }
+#endif
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function",
+ "png_get_y_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER)
+ return (info_ptr->y_pixels_per_unit);
+ }
+#endif
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter");
+
+ if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER &&
+ info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit)
+ return (info_ptr->x_pixels_per_unit);
+ }
+#endif
+
+ return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp
+ info_ptr)
+{
+#ifdef PNG_READ_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio");
+
+ if (info_ptr->x_pixels_per_unit != 0)
+ return ((float)((float)info_ptr->y_pixels_per_unit
+ /(float)info_ptr->x_pixels_per_unit));
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return ((float)0.0);
+}
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_fixed_point PNGAPI
+png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr,
+ png_const_inforp info_ptr)
+{
+#ifdef PNG_READ_pHYs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)
+ && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0
+ && info_ptr->x_pixels_per_unit <= PNG_UINT_31_MAX
+ && info_ptr->y_pixels_per_unit <= PNG_UINT_31_MAX)
+ {
+ png_fixed_point res;
+
+ png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed");
+
+ /* The following casts work because a PNG 4 byte integer only has a valid
+ * range of 0..2^31-1; otherwise the cast might overflow.
+ */
+ if (png_muldiv(&res, (png_int_32)info_ptr->y_pixels_per_unit, PNG_FP_1,
+ (png_int_32)info_ptr->x_pixels_per_unit))
+ return res;
+ }
+#else
+ PNG_UNUSED(png_ptr)
+ PNG_UNUSED(info_ptr)
+#endif
+
+ return 0;
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
+ return (info_ptr->x_offset);
+ }
+#endif
+
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER)
+ return (info_ptr->y_offset);
+ }
+#endif
+
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
+ return (info_ptr->x_offset);
+ }
+#endif
+
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+#ifdef PNG_oFFs_SUPPORTED
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels");
+
+ if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL)
+ return (info_ptr->y_offset);
+ }
+#endif
+
+ return (0);
+}
+
+#ifdef PNG_INCH_CONVERSIONS_SUPPORTED
+static png_uint_32
+ppi_from_ppm(png_uint_32 ppm)
+{
+#if 0
+ /* The conversion is *(2.54/100), in binary (32 digits):
+ * .00000110100000001001110101001001
+ */
+ png_uint_32 t1001, t1101;
+ ppm >>= 1; /* .1 */
+ t1001 = ppm + (ppm >> 3); /* .1001 */
+ t1101 = t1001 + (ppm >> 1); /* .1101 */
+ ppm >>= 20; /* .000000000000000000001 */
+ t1101 += t1101 >> 15; /* .1101000000000001101 */
+ t1001 >>= 11; /* .000000000001001 */
+ t1001 += t1001 >> 12; /* .000000000001001000000001001 */
+ ppm += t1001; /* .000000000001001000001001001 */
+ ppm += t1101; /* .110100000001001110101001001 */
+ return (ppm + 16) >> 5;/* .00000110100000001001110101001001 */
+#else
+ /* The argument is a PNG unsigned integer, so it is not permitted
+ * to be bigger than 2^31.
+ */
+ png_fixed_point result;
+ if (ppm <= PNG_UINT_31_MAX && png_muldiv(&result, (png_int_32)ppm, 127,
+ 5000))
+ return result;
+
+ /* Overflow. */
+ return 0;
+#endif
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ return ppi_from_ppm(png_get_pixels_per_meter(png_ptr, info_ptr));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ return ppi_from_ppm(png_get_x_pixels_per_meter(png_ptr, info_ptr));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ return ppi_from_ppm(png_get_y_pixels_per_meter(png_ptr, info_ptr));
+}
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+static png_fixed_point
+png_fixed_inches_from_microns(png_const_structrp png_ptr, png_int_32 microns)
+{
+ /* Convert from metres * 1,000,000 to inches * 100,000, meters to
+ * inches is simply *(100/2.54), so we want *(10/2.54) == 500/127.
+ * Notice that this can overflow - a warning is output and 0 is
+ * returned.
+ */
+ return png_muldiv_warn(png_ptr, microns, 500, 127);
+}
+
+png_fixed_point PNGAPI
+png_get_x_offset_inches_fixed(png_const_structrp png_ptr,
+ png_const_inforp info_ptr)
+{
+ return png_fixed_inches_from_microns(png_ptr,
+ png_get_x_offset_microns(png_ptr, info_ptr));
+}
+#endif
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_fixed_point PNGAPI
+png_get_y_offset_inches_fixed(png_const_structrp png_ptr,
+ png_const_inforp info_ptr)
+{
+ return png_fixed_inches_from_microns(png_ptr,
+ png_get_y_offset_microns(png_ptr, info_ptr));
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_x_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ /* To avoid the overflow do the conversion directly in floating
+ * point.
+ */
+ return (float)(png_get_x_offset_microns(png_ptr, info_ptr) * .00003937);
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_y_offset_inches(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ /* To avoid the overflow do the conversion directly in floating
+ * point.
+ */
+ return (float)(png_get_y_offset_microns(png_ptr, info_ptr) * .00003937);
+}
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+
+ if (*unit_type == 1)
+ {
+ if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+ if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+ }
+ }
+ }
+
+ return (retval);
+}
+#endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+
+png_byte PNGAPI
+png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->channels);
+
+ return (0);
+}
+
+#ifdef PNG_READ_SUPPORTED
+png_const_bytep PNGAPI
+png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->signature);
+
+ return (NULL);
+}
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+png_uint_32 PNGAPI
+png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_color_16p *background)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+ && background != NULL)
+ {
+ png_debug1(1, "in %s retrieval function", "bKGD");
+
+ *background = &(info_ptr->background);
+ return (PNG_INFO_bKGD);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+/* The XYZ APIs were added in 1.5.5 to take advantage of the code added at the
+ * same time to correct the rgb grayscale coefficient defaults obtained from the
+ * cHRM chunk in 1.5.4
+ */
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ double *white_x, double *white_y, double *red_x, double *red_y,
+ double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+ /* Quiet API change: this code used to only return the end points if a cHRM
+ * chunk was present, but the end points can also come from iCCP or sRGB
+ * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and
+ * the png_set_ APIs merely check that set end points are mutually
+ * consistent.
+ */
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
+ {
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
+ if (white_x != NULL)
+ *white_x = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.whitex, "cHRM white X");
+ if (white_y != NULL)
+ *white_y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.whitey, "cHRM white Y");
+ if (red_x != NULL)
+ *red_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redx,
+ "cHRM red X");
+ if (red_y != NULL)
+ *red_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.redy,
+ "cHRM red Y");
+ if (green_x != NULL)
+ *green_x = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.greenx, "cHRM green X");
+ if (green_y != NULL)
+ *green_y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_xy.greeny, "cHRM green Y");
+ if (blue_x != NULL)
+ *blue_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluex,
+ "cHRM blue X");
+ if (blue_y != NULL)
+ *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey,
+ "cHRM blue Y");
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ double *red_X, double *red_Y, double *red_Z, double *green_X,
+ double *green_Y, double *green_Z, double *blue_X, double *blue_Y,
+ double *blue_Z)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
+ {
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)");
+
+ if (red_X != NULL)
+ *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X,
+ "cHRM red X");
+ if (red_Y != NULL)
+ *red_Y = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Y,
+ "cHRM red Y");
+ if (red_Z != NULL)
+ *red_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_Z,
+ "cHRM red Z");
+ if (green_X != NULL)
+ *green_X = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_X, "cHRM green X");
+ if (green_Y != NULL)
+ *green_Y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_Y, "cHRM green Y");
+ if (green_Z != NULL)
+ *green_Z = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.green_Z, "cHRM green Z");
+ if (blue_X != NULL)
+ *blue_X = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_X, "cHRM blue X");
+ if (blue_Y != NULL)
+ *blue_Y = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_Y, "cHRM blue Y");
+ if (blue_Z != NULL)
+ *blue_Z = png_float(png_ptr,
+ info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z");
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+# endif
+
+# ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
+ png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
+ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
+ png_fixed_point *int_blue_Z)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
+ {
+ png_debug1(1, "in %s retrieval function", "cHRM_XYZ");
+
+ if (int_red_X != NULL)
+ *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X;
+ if (int_red_Y != NULL)
+ *int_red_Y = info_ptr->colorspace.end_points_XYZ.red_Y;
+ if (int_red_Z != NULL)
+ *int_red_Z = info_ptr->colorspace.end_points_XYZ.red_Z;
+ if (int_green_X != NULL)
+ *int_green_X = info_ptr->colorspace.end_points_XYZ.green_X;
+ if (int_green_Y != NULL)
+ *int_green_Y = info_ptr->colorspace.end_points_XYZ.green_Y;
+ if (int_green_Z != NULL)
+ *int_green_Z = info_ptr->colorspace.end_points_XYZ.green_Z;
+ if (int_blue_X != NULL)
+ *int_blue_X = info_ptr->colorspace.end_points_XYZ.blue_X;
+ if (int_blue_Y != NULL)
+ *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y;
+ if (int_blue_Z != NULL)
+ *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z;
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+ png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+ png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+ png_debug1(1, "in %s retrieval function", "cHRM");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS))
+ {
+ if (white_x != NULL)
+ *white_x = info_ptr->colorspace.end_points_xy.whitex;
+ if (white_y != NULL)
+ *white_y = info_ptr->colorspace.end_points_xy.whitey;
+ if (red_x != NULL)
+ *red_x = info_ptr->colorspace.end_points_xy.redx;
+ if (red_y != NULL)
+ *red_y = info_ptr->colorspace.end_points_xy.redy;
+ if (green_x != NULL)
+ *green_x = info_ptr->colorspace.end_points_xy.greenx;
+ if (green_y != NULL)
+ *green_y = info_ptr->colorspace.end_points_xy.greeny;
+ if (blue_x != NULL)
+ *blue_x = info_ptr->colorspace.end_points_xy.bluex;
+ if (blue_y != NULL)
+ *blue_y = info_ptr->colorspace.end_points_xy.bluey;
+ return (PNG_INFO_cHRM);
+ }
+
+ return (0);
+}
+# endif
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+# ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *file_gamma)
+{
+ png_debug1(1, "in %s retrieval function", "gAMA");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) &&
+ file_gamma != NULL)
+ {
+ *file_gamma = info_ptr->colorspace.gamma;
+ return (PNG_INFO_gAMA);
+ }
+
+ return (0);
+}
+# endif
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ double *file_gamma)
+{
+ png_debug1(1, "in %s retrieval function", "gAMA(float)");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) &&
+ file_gamma != NULL)
+ {
+ *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma,
+ "png_get_gAMA");
+ return (PNG_INFO_gAMA);
+ }
+
+ return (0);
+}
+# endif
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *file_srgb_intent)
+{
+ png_debug1(1, "in %s retrieval function", "sRGB");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+ && file_srgb_intent != NULL)
+ {
+ *file_srgb_intent = info_ptr->colorspace.rendering_intent;
+ return (PNG_INFO_sRGB);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+png_uint_32 PNGAPI
+png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_charpp name, int *compression_type,
+ png_bytepp profile, png_uint_32 *proflen)
+{
+ png_debug1(1, "in %s retrieval function", "iCCP");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+ && name != NULL && compression_type != NULL && profile != NULL &&
+ proflen != NULL)
+ {
+ *name = info_ptr->iccp_name;
+ *profile = info_ptr->iccp_profile;
+ *proflen = png_get_uint_32(info_ptr->iccp_profile);
+ /* This is somewhat irrelevant since the profile data returned has
+ * actually been uncompressed.
+ */
+ *compression_type = PNG_COMPRESSION_TYPE_BASE;
+ return (PNG_INFO_iCCP);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+int PNGAPI
+png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_sPLT_tpp spalettes)
+{
+ if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+ {
+ *spalettes = info_ptr->splt_palettes;
+ return info_ptr->splt_palettes_num;
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+png_uint_32 PNGAPI
+png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_uint_16p *hist)
+{
+ png_debug1(1, "in %s retrieval function", "hIST");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+ && hist != NULL)
+ {
+ *hist = info_ptr->hist;
+ return (PNG_INFO_hIST);
+ }
+
+ return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+ int *color_type, int *interlace_type, int *compression_type,
+ int *filter_type)
+{
+ png_debug1(1, "in %s retrieval function", "IHDR");
+
+ if (png_ptr == NULL || info_ptr == NULL || width == NULL ||
+ height == NULL || bit_depth == NULL || color_type == NULL)
+ return (0);
+
+ *width = info_ptr->width;
+ *height = info_ptr->height;
+ *bit_depth = info_ptr->bit_depth;
+ *color_type = info_ptr->color_type;
+
+ if (compression_type != NULL)
+ *compression_type = info_ptr->compression_type;
+
+ if (filter_type != NULL)
+ *filter_type = info_ptr->filter_type;
+
+ if (interlace_type != NULL)
+ *interlace_type = info_ptr->interlace_type;
+
+ /* This is redundant if we can be sure that the info_ptr values were all
+ * assigned in png_set_IHDR(). We do the check anyhow in case an
+ * application has ignored our advice not to mess with the members
+ * of info_ptr directly.
+ */
+ png_check_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+ info_ptr->compression_type, info_ptr->filter_type);
+
+ return (1);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+ png_debug1(1, "in %s retrieval function", "oFFs");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+ && offset_x != NULL && offset_y != NULL && unit_type != NULL)
+ {
+ *offset_x = info_ptr->x_offset;
+ *offset_y = info_ptr->y_offset;
+ *unit_type = (int)info_ptr->offset_unit_type;
+ return (PNG_INFO_oFFs);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+ png_charp *units, png_charpp *params)
+{
+ png_debug1(1, "in %s retrieval function", "pCAL");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+ && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+ nparams != NULL && units != NULL && params != NULL)
+ {
+ *purpose = info_ptr->pcal_purpose;
+ *X0 = info_ptr->pcal_X0;
+ *X1 = info_ptr->pcal_X1;
+ *type = (int)info_ptr->pcal_type;
+ *nparams = (int)info_ptr->pcal_nparams;
+ *units = info_ptr->pcal_units;
+ *params = info_ptr->pcal_params;
+ return (PNG_INFO_pCAL);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+# ifdef PNG_FIXED_POINT_SUPPORTED
+# if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *unit, png_fixed_point *width, png_fixed_point *height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ /*TODO: make this work without FP support; the API is currently eliminated
+ * if neither floating point APIs nor internal floating point arithmetic
+ * are enabled.
+ */
+ *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width");
+ *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height),
+ "sCAL height");
+ return (PNG_INFO_sCAL);
+ }
+
+ return(0);
+}
+# endif /* FLOATING_ARITHMETIC */
+# endif /* FIXED_POINT */
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *unit, double *width, double *height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = atof(info_ptr->scal_s_width);
+ *height = atof(info_ptr->scal_s_height);
+ return (PNG_INFO_sCAL);
+ }
+
+ return(0);
+}
+# endif /* FLOATING POINT */
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ int *unit, png_charpp width, png_charpp height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_s_width;
+ *height = info_ptr->scal_s_height;
+ return (PNG_INFO_sCAL);
+ }
+
+ return(0);
+}
+#endif /* sCAL */
+
+#ifdef PNG_pHYs_SUPPORTED
+png_uint_32 PNGAPI
+png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ png_debug1(1, "in %s retrieval function", "pHYs");
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ }
+ }
+
+ return (retval);
+}
+#endif /* pHYs */
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_colorp *palette, int *num_palette)
+{
+ png_debug1(1, "in %s retrieval function", "PLTE");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+ && palette != NULL)
+ {
+ *palette = info_ptr->palette;
+ *num_palette = info_ptr->num_palette;
+ png_debug1(3, "num_palette = %d", *num_palette);
+ return (PNG_INFO_PLTE);
+ }
+
+ return (0);
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_color_8p *sig_bit)
+{
+ png_debug1(1, "in %s retrieval function", "sBIT");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+ && sig_bit != NULL)
+ {
+ *sig_bit = &(info_ptr->sig_bit);
+ return (PNG_INFO_sBIT);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+int PNGAPI
+png_get_text(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_textp *text_ptr, int *num_text)
+{
+ if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+ {
+ png_debug1(1, "in 0x%lx retrieval function",
+ (unsigned long)png_ptr->chunk_name);
+
+ if (text_ptr != NULL)
+ *text_ptr = info_ptr->text;
+
+ if (num_text != NULL)
+ *num_text = info_ptr->num_text;
+
+ return info_ptr->num_text;
+ }
+
+ if (num_text != NULL)
+ *num_text = 0;
+
+ return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_timep *mod_time)
+{
+ png_debug1(1, "in %s retrieval function", "tIME");
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+ && mod_time != NULL)
+ {
+ *mod_time = &(info_ptr->mod_time);
+ return (PNG_INFO_tIME);
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+png_uint_32 PNGAPI
+png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color)
+{
+ png_uint_32 retval = 0;
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_debug1(1, "in %s retrieval function", "tRNS");
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (trans_alpha != NULL)
+ {
+ *trans_alpha = info_ptr->trans_alpha;
+ retval |= PNG_INFO_tRNS;
+ }
+
+ if (trans_color != NULL)
+ *trans_color = &(info_ptr->trans_color);
+ }
+
+ else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+ {
+ if (trans_color != NULL)
+ {
+ *trans_color = &(info_ptr->trans_color);
+ retval |= PNG_INFO_tRNS;
+ }
+
+ if (trans_alpha != NULL)
+ *trans_alpha = NULL;
+ }
+
+ if (num_trans != NULL)
+ {
+ *num_trans = info_ptr->num_trans;
+ retval |= PNG_INFO_tRNS;
+ }
+ }
+
+ return (retval);
+}
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+int PNGAPI
+png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_unknown_chunkpp unknowns)
+{
+ if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+ {
+ *unknowns = info_ptr->unknown_chunks;
+ return info_ptr->unknown_chunks_num;
+ }
+
+ return (0);
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_const_structrp png_ptr)
+{
+ return (png_byte)(png_ptr ? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+png_size_t PNGAPI
+png_get_compression_buffer_size(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return 0;
+
+# ifdef PNG_WRITE_SUPPORTED
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
+# endif
+ {
+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ return png_ptr->IDAT_read_size;
+# else
+ return PNG_IDAT_READ_SIZE;
+# endif
+ }
+
+# ifdef PNG_WRITE_SUPPORTED
+ else
+ return png_ptr->zbuffer_size;
+# endif
+}
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* These functions were added to libpng 1.2.6 and were enabled
+ * by default in libpng-1.4.0 */
+png_uint_32 PNGAPI
+png_get_user_width_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_width_max : 0);
+}
+
+png_uint_32 PNGAPI
+png_get_user_height_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_height_max : 0);
+}
+
+/* This function was added to libpng 1.4.0 */
+png_uint_32 PNGAPI
+png_get_chunk_cache_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_chunk_cache_max : 0);
+}
+
+/* This function was added to libpng 1.4.1 */
+png_alloc_size_t PNGAPI
+png_get_chunk_malloc_max (png_const_structrp png_ptr)
+{
+ return (png_ptr ? png_ptr->user_chunk_malloc_max : 0);
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+/* These functions were added to libpng 1.4.0 */
+#ifdef PNG_IO_STATE_SUPPORTED
+png_uint_32 PNGAPI
+png_get_io_state (png_const_structrp png_ptr)
+{
+ return png_ptr->io_state;
+}
+
+png_uint_32 PNGAPI
+png_get_io_chunk_type (png_const_structrp png_ptr)
+{
+ return png_ptr->chunk_name;
+}
+#endif /* ?PNG_IO_STATE_SUPPORTED */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+int PNGAPI
+png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return png_ptr->num_palette_max;
+
+ return (-1);
+}
+# endif
+#endif
+
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngmem.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngmem.c
new file mode 100644
index 0000000000..446bc6879a
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngmem.c
@@ -0,0 +1,291 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngmem.c - stub functions for memory allocation
+ *
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all memory allocation. Users who
+ * need special memory handling are expected to supply replacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the replacement functions.
+ */
+
+#include "pngpriv.h"
+
+#if defined(_FX_MANAGED_CODE_) && defined(__cplusplus)
+extern "C" {
+#endif
+
+void* FXMEM_DefaultAlloc(int byte_size, int);
+void FXMEM_DefaultFree(void* pointer, int);
+
+#if defined(_FX_MANAGED_CODE_) && defined(__cplusplus)
+}
+#endif
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+/* Free a png_struct */
+void /* PRIVATE */
+png_destroy_png_struct(png_structrp png_ptr)
+{
+ if (png_ptr != NULL)
+ {
+ /* png_free might call png_error and may certainly call
+ * png_get_mem_ptr, so fake a temporary png_struct to support this.
+ */
+ png_struct dummy_struct = *png_ptr;
+ memset(png_ptr, 0, (sizeof *png_ptr));
+ png_free(&dummy_struct, png_ptr);
+
+# ifdef PNG_SETJMP_SUPPORTED
+ /* We may have a jmp_buf left to deallocate. */
+ png_free_jmpbuf(&dummy_struct);
+# endif
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ * 64K. However, zlib may allocate more then 64K if you don't tell
+ * it not to. See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+{
+ png_voidp ret;
+
+ ret = png_malloc(png_ptr, size);
+
+ if (ret != NULL)
+ memset(ret, 0, size);
+
+ return ret;
+}
+
+/* png_malloc_base, an internal function added at libpng 1.6.0, does the work of
+ * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.
+ * Checking and error handling must happen outside this routine; it returns NULL
+ * if the allocation cannot be done (for any reason.)
+ */
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),
+ PNG_ALLOCATED)
+{
+ /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS
+ * allocators have also been removed in 1.6.0, so any 16-bit system now has
+ * to implement a user memory handler. This checks to be sure it isn't
+ * called with big numbers.
+ */
+#ifdef PNG_USER_MEM_SUPPORTED
+ PNG_UNUSED(png_ptr)
+#endif
+ if (size > 0 && size <= PNG_SIZE_MAX
+# ifdef PNG_MAX_MALLOC_64K
+ && size <= 65536U
+# endif
+ )
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr != NULL && png_ptr->malloc_fn != NULL)
+ return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);
+
+ else
+#endif
+ return FXMEM_DefaultAlloc((int)size, 0);
+ //return malloc((size_t)size); /* checked for truncation above */
+ }
+
+ else
+ return NULL;
+}
+
+/* This is really here only to work round a spurious warning in GCC 4.6 and 4.7
+ * that arises because of the checks in png_realloc_array that are repeated in
+ * png_malloc_array.
+ */
+static png_voidp
+png_malloc_array_checked(png_const_structrp png_ptr, int nelements,
+ size_t element_size)
+{
+ png_alloc_size_t req = nelements; /* known to be > 0 */
+
+ if (req <= PNG_SIZE_MAX/element_size)
+ return png_malloc_base(png_ptr, req * element_size);
+
+ /* The failure case when the request is too large */
+ return NULL;
+}
+
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_malloc_array,(png_const_structrp png_ptr, int nelements,
+ size_t element_size),PNG_ALLOCATED)
+{
+ if (nelements <= 0 || element_size == 0)
+ png_error(png_ptr, "internal error: array alloc");
+
+ return png_malloc_array_checked(png_ptr, nelements, element_size);
+}
+
+PNG_FUNCTION(png_voidp /* PRIVATE */,
+png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,
+ int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)
+{
+ /* These are internal errors: */
+ if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||
+ (old_array == NULL && old_elements > 0))
+ png_error(png_ptr, "internal error: array realloc");
+
+ /* Check for overflow on the elements count (so the caller does not have to
+ * check.)
+ */
+ if (add_elements <= INT_MAX - old_elements)
+ {
+ png_voidp new_array = png_malloc_array_checked(png_ptr,
+ old_elements+add_elements, element_size);
+
+ if (new_array != NULL)
+ {
+ /* Because png_malloc_array worked the size calculations below cannot
+ * overflow.
+ */
+ if (old_elements > 0)
+ memcpy(new_array, old_array, element_size*(unsigned)old_elements);
+
+ memset((char*)new_array + element_size*(unsigned)old_elements, 0,
+ element_size*(unsigned)add_elements);
+
+ return new_array;
+ }
+ }
+
+ return NULL; /* error */
+}
+
+/* Various functions that have different error handling are derived from this.
+ * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate
+ * function png_malloc_default is also provided.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ ret = png_malloc_base(png_ptr, size);
+
+ if (ret == NULL)
+ png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */
+
+ return ret;
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),
+ PNG_ALLOCATED PNG_DEPRECATED)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL)
+ return NULL;
+
+ /* Passing 'NULL' here bypasses the application provided memory handler. */
+ ret = png_malloc_base(NULL/*use malloc*/, size);
+
+ if (ret == NULL)
+ png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */
+
+ return ret;
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+/* This function was added at libpng version 1.2.3. The png_malloc_warn()
+ * function will issue a png_warning and return NULL instead of issuing a
+ * png_error, if it fails to allocate the requested memory.
+ */
+PNG_FUNCTION(png_voidp,PNGAPI
+png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),
+ PNG_ALLOCATED)
+{
+ if (png_ptr != NULL)
+ {
+ png_voidp ret = png_malloc_base(png_ptr, size);
+
+ if (ret != NULL)
+ return ret;
+
+ png_warning(png_ptr, "Out of memory");
+ }
+
+ return NULL;
+}
+
+/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
+ * without taking any action.
+ */
+void PNGAPI
+png_free(png_const_structrp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);
+
+ else
+ png_free_default(png_ptr, ptr);
+}
+
+PNG_FUNCTION(void,PNGAPI
+png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ FXMEM_DefaultFree(ptr, 0);
+ //free(ptr);
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+ malloc_fn, png_free_ptr free_fn)
+{
+ if (png_ptr != NULL)
+ {
+ png_ptr->mem_ptr = mem_ptr;
+ png_ptr->malloc_fn = malloc_fn;
+ png_ptr->free_fn = free_fn;
+ }
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return NULL;
+
+ return png_ptr->mem_ptr;
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngpread.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngpread.c
new file mode 100644
index 0000000000..6d5053f849
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngpread.c
@@ -0,0 +1,1292 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngpread.c - read a png file in push mode
+ *
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* Push model modes */
+#define PNG_READ_SIG_MODE 0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE 2
+#define PNG_SKIP_MODE 3
+#define PNG_READ_tEXt_MODE 4
+#define PNG_READ_zTXt_MODE 5
+#define PNG_READ_DONE_MODE 6
+#define PNG_READ_iTXt_MODE 7
+#define PNG_ERROR_MODE 8
+
+void PNGAPI
+png_process_data(png_structrp png_ptr, png_inforp info_ptr,
+ png_bytep buffer, png_size_t buffer_size)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+ while (png_ptr->buffer_size)
+ {
+ png_process_some_data(png_ptr, info_ptr);
+ }
+}
+
+png_size_t PNGAPI
+png_process_data_pause(png_structrp png_ptr, int save)
+{
+ if (png_ptr != NULL)
+ {
+ /* It's easiest for the caller if we do the save, then the caller doesn't
+ * have to supply the same data again:
+ */
+ if (save)
+ png_push_save_buffer(png_ptr);
+ else
+ {
+ /* This includes any pending saved bytes: */
+ png_size_t remaining = png_ptr->buffer_size;
+ png_ptr->buffer_size = 0;
+
+ /* So subtract the saved buffer size, unless all the data
+ * is actually 'saved', in which case we just return 0
+ */
+ if (png_ptr->save_buffer_size < remaining)
+ return remaining - png_ptr->save_buffer_size;
+ }
+ }
+
+ return 0;
+}
+
+png_uint_32 PNGAPI
+png_process_data_skip(png_structrp png_ptr)
+{
+ png_uint_32 remaining = 0;
+
+ if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE &&
+ png_ptr->skip_length > 0)
+ {
+ /* At the end of png_process_data the buffer size must be 0 (see the loop
+ * above) so we can detect a broken call here:
+ */
+ if (png_ptr->buffer_size != 0)
+ png_error(png_ptr,
+ "png_process_data_skip called inside png_process_data");
+
+ /* If is impossible for there to be a saved buffer at this point -
+ * otherwise we could not be in SKIP mode. This will also happen if
+ * png_process_skip is called inside png_process_data (but only very
+ * rarely.)
+ */
+ if (png_ptr->save_buffer_size != 0)
+ png_error(png_ptr, "png_process_data_skip called with saved data");
+
+ remaining = png_ptr->skip_length;
+ png_ptr->skip_length = 0;
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+
+ return remaining;
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
+{
+ if (png_ptr == NULL)
+ return;
+
+ switch (png_ptr->process_mode)
+ {
+ case PNG_READ_SIG_MODE:
+ {
+ png_push_read_sig(png_ptr, info_ptr);
+ break;
+ }
+
+ case PNG_READ_CHUNK_MODE:
+ {
+ png_push_read_chunk(png_ptr, info_ptr);
+ break;
+ }
+
+ case PNG_READ_IDAT_MODE:
+ {
+ png_push_read_IDAT(png_ptr);
+ break;
+ }
+
+ case PNG_SKIP_MODE:
+ {
+ png_push_crc_finish(png_ptr);
+ break;
+ }
+
+ default:
+ {
+ png_ptr->buffer_size = 0;
+ break;
+ }
+ }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature. It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
+ num_to_check = 8 - num_checked;
+
+ if (png_ptr->buffer_size < num_to_check)
+ {
+ num_to_check = png_ptr->buffer_size;
+ }
+
+ png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+ num_to_check);
+ png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check);
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ else
+ {
+ if (png_ptr->sig_bytes >= 8)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+ }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_uint_32 chunk_name;
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ int keep; /* unknown handling method */
+#endif
+
+ /* First we make sure we have enough data for the 4 byte chunk name
+ * and the 4 byte chunk length before proceeding with decoding the
+ * chunk data. To fully decode each of these chunks, we also make
+ * sure we have enough data in the buffer for the 4 byte CRC at the
+ * end of every chunk (except IDAT, which is handled separately).
+ */
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+ png_byte chunk_tag[4];
+
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, chunk_tag, 4);
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+ }
+
+ chunk_name = png_ptr->chunk_name;
+
+ if (chunk_name == png_IDAT)
+ {
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT;
+
+ /* If we reach an IDAT chunk, this means we have read all of the
+ * header chunks, and we can start reading the image (or if this
+ * is called after the image has been read - we have an error).
+ */
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+ png_ptr->mode |= PNG_HAVE_IDAT;
+
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ if (png_ptr->push_length == 0)
+ return;
+
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_benign_error(png_ptr, "Too many IDATs found");
+ }
+
+ if (chunk_name == png_IHDR)
+ {
+ if (png_ptr->push_length != 13)
+ png_error(png_ptr, "Invalid IHDR length");
+
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ else if (chunk_name == png_IEND)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+ png_ptr->process_mode = PNG_READ_DONE_MODE;
+ png_push_have_end(png_ptr, info_ptr);
+ }
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep);
+
+ if (chunk_name == png_PLTE)
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ }
+
+#endif
+ else if (chunk_name == png_PLTE)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ else if (chunk_name == png_IDAT)
+ {
+ png_ptr->idat_size = png_ptr->push_length;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+ png_push_have_info(png_ptr, info_ptr);
+ png_ptr->zstream.avail_out =
+ (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ return;
+ }
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (png_ptr->chunk_name == png_gAMA)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (png_ptr->chunk_name == png_sBIT)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (png_ptr->chunk_name == png_cHRM)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (png_ptr->chunk_name == png_iCCP)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+#endif
+ else
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+ }
+
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void /* PRIVATE */
+png_push_crc_skip(png_structrp png_ptr, png_uint_32 skip)
+{
+ png_ptr->process_mode = PNG_SKIP_MODE;
+ png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structrp png_ptr)
+{
+ if (png_ptr->skip_length && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size = png_ptr->save_buffer_size;
+ png_uint_32 skip_length = png_ptr->skip_length;
+
+ /* We want the smaller of 'skip_length' and 'save_buffer_size', but
+ * they are of different types and we don't know which variable has the
+ * fewest bits. Carefully select the smaller and cast it to the type of
+ * the larger - this cannot overflow. Do not cast in the following test
+ * - it will break on either 16 or 64 bit platforms.
+ */
+ if (skip_length < save_size)
+ save_size = (png_size_t)skip_length;
+
+ else
+ skip_length = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= skip_length;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->skip_length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size = png_ptr->current_buffer_size;
+ png_uint_32 skip_length = png_ptr->skip_length;
+
+ /* We want the smaller of 'skip_length' and 'current_buffer_size', here,
+ * the same problem exists as above and the same solution.
+ */
+ if (skip_length < save_size)
+ save_size = (png_size_t)skip_length;
+
+ else
+ skip_length = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= skip_length;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->skip_length)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+}
+
+void PNGCBAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+ png_bytep ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ ptr = buffer;
+ if (png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->save_buffer_size)
+ save_size = length;
+
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+ length -= save_size;
+ ptr += save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->current_buffer_size)
+ save_size = length;
+
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structrp png_ptr)
+{
+ if (png_ptr->save_buffer_size)
+ {
+ if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+ {
+ png_size_t i, istop;
+ png_bytep sp;
+ png_bytep dp;
+
+ istop = png_ptr->save_buffer_size;
+ for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+ i < istop; i++, sp++, dp++)
+ {
+ *dp = *sp;
+ }
+ }
+ }
+ if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+ png_ptr->save_buffer_max)
+ {
+ png_size_t new_max;
+ png_bytep old_buffer;
+
+ if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
+ (png_ptr->current_buffer_size + 256))
+ {
+ png_error(png_ptr, "Potential overflow of save_buffer");
+ }
+
+ new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+ old_buffer = png_ptr->save_buffer;
+ png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr,
+ (png_size_t)new_max);
+
+ if (png_ptr->save_buffer == NULL)
+ {
+ png_free(png_ptr, old_buffer);
+ png_error(png_ptr, "Insufficient memory for save_buffer");
+ }
+
+ memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+ png_free(png_ptr, old_buffer);
+ png_ptr->save_buffer_max = new_max;
+ }
+ if (png_ptr->current_buffer_size)
+ {
+ memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+ png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+ png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+ png_ptr->current_buffer_size = 0;
+ }
+ png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+ png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structrp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ png_ptr->current_buffer = buffer;
+ png_ptr->current_buffer_size = buffer_length;
+ png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+ png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structrp png_ptr)
+{
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+ png_byte chunk_tag[4];
+
+ /* TODO: this code can be commoned up with the same code in push_read */
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, chunk_tag, 4);
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+ if (png_ptr->chunk_name != png_IDAT)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+
+ if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ png_error(png_ptr, "Not enough compressed data");
+
+ return;
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
+ }
+
+ if (png_ptr->idat_size && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size = png_ptr->save_buffer_size;
+ png_uint_32 idat_size = png_ptr->idat_size;
+
+ /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+ * are of different types and we don't know which variable has the fewest
+ * bits. Carefully select the smaller and cast it to the type of the
+ * larger - this cannot overflow. Do not cast in the following test - it
+ * will break on either 16 or 64 bit platforms.
+ */
+ if (idat_size < save_size)
+ save_size = (png_size_t)idat_size;
+
+ else
+ idat_size = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= idat_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+
+ if (png_ptr->idat_size && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size = png_ptr->current_buffer_size;
+ png_uint_32 idat_size = png_ptr->idat_size;
+
+ /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+ * are of different types and we don't know which variable has the fewest
+ * bits. Carefully select the smaller and cast it to the type of the
+ * larger - this cannot overflow.
+ */
+ if (idat_size < save_size)
+ save_size = (png_size_t)idat_size;
+
+ else
+ idat_size = (png_uint_32)save_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= idat_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->idat_size)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->zowner = 0;
+ }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ /* The caller checks for a non-zero buffer length. */
+ if (!(buffer_length > 0) || buffer == NULL)
+ png_error(png_ptr, "No IDAT data (internal error)");
+
+ /* This routine must process all the data it has been given
+ * before returning, calling the row callback as required to
+ * handle the uncompressed results.
+ */
+ png_ptr->zstream.next_in = buffer;
+ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
+ png_ptr->zstream.avail_in = (uInt)buffer_length;
+
+ /* Keep going until the decompressed data is all processed
+ * or the stream marked as finished.
+ */
+ while (png_ptr->zstream.avail_in > 0 &&
+ !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ {
+ int ret;
+
+ /* We have data for zlib, but we must check that zlib
+ * has someplace to put the results. It doesn't matter
+ * if we don't expect any results -- it may be the input
+ * data is just the LZ end code.
+ */
+ if (!(png_ptr->zstream.avail_out > 0))
+ {
+ /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */
+ png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
+ png_ptr->iwidth) + 1);
+
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ }
+
+ /* Using Z_SYNC_FLUSH here means that an unterminated
+ * LZ stream (a stream with a missing end code) can still
+ * be handled, otherwise (Z_NO_FLUSH) a future zlib
+ * implementation might defer output and therefore
+ * change the current behavior (see comments in inflate.c
+ * for why this doesn't happen at present with zlib 1.2.5).
+ */
+ ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+
+ /* Check for any failure before proceeding. */
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ /* Terminate the decompression. */
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ png_ptr->zowner = 0;
+
+ /* This may be a truncated stream (missing or
+ * damaged end code). Treat that as a warning.
+ */
+ if (png_ptr->row_number >= png_ptr->num_rows ||
+ png_ptr->pass > 6)
+ png_warning(png_ptr, "Truncated compressed data in IDAT");
+
+ else
+ png_error(png_ptr, "Decompression error in IDAT");
+
+ /* Skip the check on unprocessed input */
+ return;
+ }
+
+ /* Did inflate output any data? */
+ if (png_ptr->zstream.next_out != png_ptr->row_buf)
+ {
+ /* Is this unexpected data after the last row?
+ * If it is, artificially terminate the LZ output
+ * here.
+ */
+ if (png_ptr->row_number >= png_ptr->num_rows ||
+ png_ptr->pass > 6)
+ {
+ /* Extra data. */
+ png_warning(png_ptr, "Extra compressed data in IDAT");
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ png_ptr->zowner = 0;
+
+ /* Do no more processing; skip the unprocessed
+ * input check below.
+ */
+ return;
+ }
+
+ /* Do we have a complete row? */
+ if (png_ptr->zstream.avail_out == 0)
+ png_push_process_row(png_ptr);
+ }
+
+ /* And check for the end of the stream. */
+ if (ret == Z_STREAM_END)
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ }
+
+ /* All the data should have been processed, if anything
+ * is left at this point we have bytes of IDAT data
+ * after the zlib end code.
+ */
+ if (png_ptr->zstream.avail_in > 0)
+ png_warning(png_ptr, "Extra compression data in IDAT");
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structrp png_ptr)
+{
+ /* 1.5.6: row_info moved out of png_struct to a local here. */
+ png_row_info row_info;
+
+ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
+ row_info.color_type = png_ptr->color_type;
+ row_info.bit_depth = png_ptr->bit_depth;
+ row_info.channels = png_ptr->channels;
+ row_info.pixel_depth = png_ptr->pixel_depth;
+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
+ {
+ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
+ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
+ png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+ else
+ png_error(png_ptr, "bad adaptive filter value");
+ }
+
+ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
+ * 1.5.6, while the buffer really is this big in current versions of libpng
+ * it may not be in the future, so this was changed just to copy the
+ * interlaced row count:
+ */
+ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ if (png_ptr->transformations)
+ png_do_read_transformations(png_ptr, &row_info);
+#endif
+
+ /* The transformed pixel depth should match the depth now in row_info. */
+ if (png_ptr->transformed_pixel_depth == 0)
+ {
+ png_ptr->transformed_pixel_depth = row_info.pixel_depth;
+ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
+ png_error(png_ptr, "progressive row overflow");
+ }
+
+ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
+ png_error(png_ptr, "internal progressive row size calculation error");
+
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Blow up interlaced rows to full size */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
+ png_ptr->transformations);
+
+ switch (png_ptr->pass)
+ {
+ case 0:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */
+ }
+
+ if (png_ptr->pass == 2) /* Pass 1 might be empty */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ if (png_ptr->pass == 4 && png_ptr->height <= 4)
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ if (png_ptr->pass == 6 && png_ptr->height <= 4)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ case 1:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 2) /* Skip top 4 generated rows */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 2:
+ {
+ int i;
+
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 4) /* Pass 3 might be empty */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ int i;
+
+ for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 4) /* Skip top two generated rows */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+
+ break;
+ }
+
+ case 4:
+ {
+ int i;
+
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 6) /* Pass 5 might be empty */
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ case 5:
+ {
+ int i;
+
+ for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ if (png_ptr->pass == 6) /* Skip top generated row */
+ {
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+
+ break;
+ }
+
+ default:
+ case 6:
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+
+ if (png_ptr->pass != 6)
+ break;
+
+ png_push_have_row(png_ptr, NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ }
+ else
+#endif
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structrp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+ /* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+ static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+ */
+#endif
+
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ do
+ {
+ png_ptr->pass++;
+ if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+ (png_ptr->pass == 3 && png_ptr->width < 3) ||
+ (png_ptr->pass == 5 && png_ptr->width < 2))
+ png_ptr->pass++;
+
+ if (png_ptr->pass > 7)
+ png_ptr->pass--;
+
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+
+ } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+ }
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+ if (png_ptr->info_fn != NULL)
+ (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+ if (png_ptr->end_fn != NULL)
+ (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structrp png_ptr, png_bytep row)
+{
+ if (png_ptr->row_fn != NULL)
+ (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+ (int)png_ptr->pass);
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+void PNGAPI
+png_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row,
+ png_const_bytep new_row)
+{
+ if (png_ptr == NULL)
+ return;
+
+ /* new_row is a flag here - if it is NULL then the app callback was called
+ * from an empty row (see the calls to png_struct::row_fn below), otherwise
+ * it must be png_ptr->row_buf+1
+ */
+ if (new_row != NULL)
+ png_combine_row(png_ptr, old_row, 1/*display*/);
+}
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+void PNGAPI
+png_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->info_fn = info_fn;
+ png_ptr->row_fn = row_fn;
+ png_ptr->end_fn = end_fn;
+
+ png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+
+ return png_ptr->io_ptr;
+}
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngread.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngread.c
new file mode 100644
index 0000000000..3918e8396f
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngread.c
@@ -0,0 +1,4001 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngread.c - read a PNG file
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#include "pngpriv.h"
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+# include <errno.h>
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_read_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
+{
+#ifndef PNG_USER_MEM_SUPPORTED
+ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, NULL, NULL, NULL);
+#else
+ return png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, NULL, NULL, NULL);
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory
+ * needed.
+ */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+ png_structp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if (png_ptr != NULL)
+ {
+ png_ptr->mode = PNG_IS_READ_STRUCT;
+
+ /* Added in libpng-1.6.0; this can be used to detect a read structure if
+ * required (it will be zero in a write structure.)
+ */
+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;
+# endif
+
+# ifdef PNG_BENIGN_READ_ERRORS_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+
+ /* In stable builds only warn if an application error can be completely
+ * handled.
+ */
+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
+# endif
+# endif
+
+ /* TODO: delay this, it can be done in png_init_io (if the app doesn't
+ * do it itself) avoiding setting the default function if it is not
+ * required.
+ */
+ png_set_read_fn(png_ptr, NULL, NULL);
+ }
+
+ return png_ptr;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream. You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here. The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ int keep;
+#endif
+
+ png_debug(1, "in png_read_info");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Read and check the PNG file signature. */
+ png_read_sig(png_ptr, info_ptr);
+
+ for (;;)
+ {
+ png_uint_32 length = png_read_chunk_header(png_ptr);
+ png_uint_32 chunk_name = png_ptr->chunk_name;
+
+ /* IDAT logic needs to happen here to simplify getting the two flags
+ * right.
+ */
+ if (chunk_name == png_IDAT)
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "Missing IHDR before IDAT");
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_chunk_error(png_ptr, "Missing PLTE before IDAT");
+
+ else if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_chunk_benign_error(png_ptr, "Too many IDATs found");
+
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ }
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ /* This should be a binary subdivision search or a hash for
+ * matching the chunk name rather than a linear search.
+ */
+ if (chunk_name == png_IHDR)
+ png_handle_IHDR(png_ptr, info_ptr, length);
+
+ else if (chunk_name == png_IEND)
+ png_handle_IEND(png_ptr, info_ptr, length);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+ {
+ png_handle_unknown(png_ptr, info_ptr, length, keep);
+
+ if (chunk_name == png_PLTE)
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ else if (chunk_name == png_IDAT)
+ {
+ png_ptr->idat_size = 0; /* It has been consumed */
+ break;
+ }
+ }
+#endif
+ else if (chunk_name == png_PLTE)
+ png_handle_PLTE(png_ptr, info_ptr, length);
+
+ else if (chunk_name == png_IDAT)
+ {
+ png_ptr->idat_size = length;
+ break;
+ }
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (chunk_name == png_cHRM)
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (chunk_name == png_gAMA)
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (chunk_name == png_sBIT)
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (chunk_name == png_iCCP)
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+
+ else
+ png_handle_unknown(png_ptr, info_ptr, length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+ }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+/* Optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_debug(1, "in png_read_update_info");
+
+ if (png_ptr != NULL)
+ {
+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ {
+ png_read_start_row(png_ptr);
+
+# ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ png_read_transform_info(png_ptr, info_ptr);
+# else
+ PNG_UNUSED(info_ptr)
+# endif
+ }
+
+ /* New in 1.6.0 this avoids the bug of doing the initializations twice */
+ else
+ png_app_error(png_ptr,
+ "png_read_update_info/png_start_read_image: duplicate call");
+ }
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place. This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structrp png_ptr)
+{
+ png_debug(1, "in png_start_read_image");
+
+ if (png_ptr != NULL)
+ {
+ if ((png_ptr->flags & PNG_FLAG_ROW_INIT) == 0)
+ png_read_start_row(png_ptr);
+
+ /* New in 1.6.0 this avoids the bug of doing the initializations twice */
+ else
+ png_app_error(png_ptr,
+ "png_start_read_image/png_read_update_info: duplicate call");
+ }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void PNGAPI
+png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+ png_row_info row_info;
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug2(1, "in png_read_row (row %lu, pass %d)",
+ (unsigned long)png_ptr->row_number, png_ptr->pass);
+
+ /* png_read_start_row sets the information (in particular iwidth) for this
+ * interlace pass.
+ */
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+
+ /* 1.5.6: row_info moved out of png_struct to a local here. */
+ row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */
+ row_info.color_type = png_ptr->color_type;
+ row_info.bit_depth = png_ptr->bit_depth;
+ row_info.channels = png_ptr->channels;
+ row_info.pixel_depth = png_ptr->pixel_depth;
+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* Check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+ !defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined");
+#endif
+
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined");
+#endif
+ }
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* If interlaced and we do not need a new row, combine row and return.
+ * Notice that the pixels we have from previous rows have been transformed
+ * already; we can only combine like with like (transformed or
+ * untransformed) and, because of the libpng API for interlaced images, this
+ * means we must transform before de-interlacing.
+ */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 4))
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 3:
+ if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 4:
+ if ((png_ptr->row_number & 3) != 2)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 2))
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 5:
+ if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ default:
+ case 6:
+ if (!(png_ptr->row_number & 1))
+ {
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "Invalid attempt to read row data");
+
+ /* Fill the row with IDAT data: */
+ png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
+
+ if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
+ {
+ if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST)
+ png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1,
+ png_ptr->prev_row + 1, png_ptr->row_buf[0]);
+ else
+ png_error(png_ptr, "bad adaptive filter value");
+ }
+
+ /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before
+ * 1.5.6, while the buffer really is this big in current versions of libpng
+ * it may not be in the future, so this was changed just to copy the
+ * interlaced count:
+ */
+ memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_read_intrapixel(&row_info, png_ptr->row_buf + 1);
+ }
+#endif
+
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ if (png_ptr->transformations)
+ png_do_read_transformations(png_ptr, &row_info);
+#endif
+
+ /* The transformed pixel depth should match the depth now in row_info. */
+ if (png_ptr->transformed_pixel_depth == 0)
+ {
+ png_ptr->transformed_pixel_depth = row_info.pixel_depth;
+ if (row_info.pixel_depth > png_ptr->maximum_pixel_depth)
+ png_error(png_ptr, "sequential row overflow");
+ }
+
+ else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth)
+ png_error(png_ptr, "internal sequential row size calculation error");
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Blow up interlaced rows to full size */
+ if (png_ptr->interlaced &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+ png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass,
+ png_ptr->transformations);
+
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 1/*display*/);
+
+ if (row != NULL)
+ png_combine_row(png_ptr, row, 0/*row*/);
+ }
+
+ else
+#endif
+ {
+ if (row != NULL)
+ png_combine_row(png_ptr, row, -1/*ignored*/);
+
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, -1/*ignored*/);
+ }
+ png_read_finish_row(png_ptr);
+
+ if (png_ptr->read_row_fn != NULL)
+ (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass. If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive. If the image is displayed after each pass, it will
+ * appear to "sparkle" in. "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available. If you do not want this "chunky" display, you may pass
+ * NULL for display_row. If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows. In this case, you do not have to provide a display_row buffer
+ * also, but you may. If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+
+void PNGAPI
+png_read_rows(png_structrp png_ptr, png_bytepp row,
+ png_bytepp display_row, png_uint_32 num_rows)
+{
+ png_uint_32 i;
+ png_bytepp rp;
+ png_bytepp dp;
+
+ png_debug(1, "in png_read_rows");
+
+ if (png_ptr == NULL)
+ return;
+
+ rp = row;
+ dp = display_row;
+ if (rp != NULL && dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp++;
+ png_bytep dptr = *dp++;
+
+ png_read_row(png_ptr, rptr, dptr);
+ }
+
+ else if (rp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp;
+ png_read_row(png_ptr, rptr, NULL);
+ rp++;
+ }
+
+ else if (dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep dptr = *dp;
+ png_read_row(png_ptr, NULL, dptr);
+ dp++;
+ }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the entire image. If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been. You can
+ * only call this function once. If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of this version of libpng
+ */
+void PNGAPI
+png_read_image(png_structrp png_ptr, png_bytepp image)
+{
+ png_uint_32 i, image_height;
+ int pass, j;
+ png_bytepp rp;
+
+ png_debug(1, "in png_read_image");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ {
+ pass = png_set_interlace_handling(png_ptr);
+ /* And make sure transforms are initialized. */
+ png_start_read_image(png_ptr);
+ }
+ else
+ {
+ if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
+ {
+ /* Caller called png_start_read_image or png_read_update_info without
+ * first turning on the PNG_INTERLACE transform. We can fix this here,
+ * but the caller should do it!
+ */
+ png_warning(png_ptr, "Interlace handling should be turned on when "
+ "using png_read_image");
+ /* Make sure this is set correctly */
+ png_ptr->num_rows = png_ptr->height;
+ }
+
+ /* Obtain the pass number, which also turns on the PNG_INTERLACE flag in
+ * the above error case.
+ */
+ pass = png_set_interlace_handling(png_ptr);
+ }
+#else
+ if (png_ptr->interlaced)
+ png_error(png_ptr,
+ "Cannot read interlaced image -- interlace handler disabled");
+
+ pass = 1;
+#endif
+
+ image_height=png_ptr->height;
+
+ for (j = 0; j < pass; j++)
+ {
+ rp = image;
+ for (i = 0; i < image_height; i++)
+ {
+ png_read_row(png_ptr, *rp, NULL);
+ rp++;
+ }
+ }
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ int keep;
+#endif
+
+ png_debug(1, "in png_read_end");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* If png_read_end is called in the middle of reading the rows there may
+ * still be pending IDAT data and an owned zstream. Deal with this here.
+ */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ if (!png_chunk_unknown_handling(png_ptr, png_IDAT))
+#endif
+ png_read_finish_IDAT(png_ptr);
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Report invalid palette index; added at libng-1.5.10 */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ png_ptr->num_palette_max > png_ptr->num_palette)
+ png_benign_error(png_ptr, "Read palette index exceeding num_palette");
+#endif
+
+ do
+ {
+ png_uint_32 length = png_read_chunk_header(png_ptr);
+ png_uint_32 chunk_name = png_ptr->chunk_name;
+
+ if (chunk_name == png_IHDR)
+ png_handle_IHDR(png_ptr, info_ptr, length);
+
+ else if (chunk_name == png_IEND)
+ png_handle_IEND(png_ptr, info_ptr, length);
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0)
+ {
+ if (chunk_name == png_IDAT)
+ {
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_benign_error(png_ptr, "Too many IDATs found");
+ }
+ png_handle_unknown(png_ptr, info_ptr, length, keep);
+ if (chunk_name == png_PLTE)
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ }
+#endif
+
+ else if (chunk_name == png_IDAT)
+ {
+ /* Zero length IDATs are legal after the last IDAT has been
+ * read, but not after other chunks have been read.
+ */
+ if ((length > 0) || (png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT))
+ png_benign_error(png_ptr, "Too many IDATs found");
+
+ png_crc_finish(png_ptr, length);
+ }
+ else if (chunk_name == png_PLTE)
+ png_handle_PLTE(png_ptr, info_ptr, length);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ else if (chunk_name == png_bKGD)
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+ else if (chunk_name == png_cHRM)
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+ else if (chunk_name == png_gAMA)
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ else if (chunk_name == png_hIST)
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+ else if (chunk_name == png_oFFs)
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+ else if (chunk_name == png_pCAL)
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+ else if (chunk_name == png_sCAL)
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+ else if (chunk_name == png_pHYs)
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+ else if (chunk_name == png_sBIT)
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+ else if (chunk_name == png_sRGB)
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+ else if (chunk_name == png_iCCP)
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+ else if (chunk_name == png_sPLT)
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+ else if (chunk_name == png_tEXt)
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+ else if (chunk_name == png_tIME)
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+ else if (chunk_name == png_tRNS)
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+ else if (chunk_name == png_zTXt)
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+ else if (chunk_name == png_iTXt)
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+
+ else
+ png_handle_unknown(png_ptr, info_ptr, length,
+ PNG_HANDLE_CHUNK_AS_DEFAULT);
+ } while (!(png_ptr->mode & PNG_HAVE_IEND));
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+/* Free all memory used in the read struct */
+static void
+png_read_destroy(png_structrp png_ptr)
+{
+ png_debug(1, "in png_read_destroy");
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_destroy_gamma_table(png_ptr);
+#endif
+
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->big_prev_row);
+ png_free(png_ptr, png_ptr->read_buffer);
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ png_free(png_ptr, png_ptr->palette_lookup);
+ png_free(png_ptr, png_ptr->quantize_index);
+#endif
+
+ if (png_ptr->free_me & PNG_FREE_PLTE)
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->free_me &= ~PNG_FREE_PLTE;
+
+#if defined(PNG_tRNS_SUPPORTED) || \
+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->free_me & PNG_FREE_TRNS)
+ png_free(png_ptr, png_ptr->trans_alpha);
+ png_ptr->free_me &= ~PNG_FREE_TRNS;
+#endif
+
+ inflateEnd(&png_ptr->zstream);
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_free(png_ptr, png_ptr->save_buffer);
+#endif
+
+#if defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED) &&\
+ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ png_free(png_ptr, png_ptr->chunk_list);
+#endif
+
+ /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error
+ * callbacks are still set at this point. They are required to complete the
+ * destruction of the png_struct itself.
+ */
+}
+
+/* Free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+ png_infopp end_info_ptr_ptr)
+{
+ png_structrp png_ptr = NULL;
+
+ png_debug(1, "in png_destroy_read_struct");
+
+ if (png_ptr_ptr != NULL)
+ png_ptr = *png_ptr_ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ /* libpng 1.6.0: use the API to destroy info structs to ensure consistent
+ * behavior. Prior to 1.6.0 libpng did extra 'info' destruction in this API.
+ * The extra was, apparently, unnecessary yet this hides memory leak bugs.
+ */
+ png_destroy_info_struct(png_ptr, end_info_ptr_ptr);
+ png_destroy_info_struct(png_ptr, info_ptr_ptr);
+
+ *png_ptr_ptr = NULL;
+ png_read_destroy(png_ptr);
+ png_destroy_png_struct(png_ptr);
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structrp png_ptr, png_read_status_ptr read_row_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->read_row_fn = read_row_fn;
+}
+
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_read_png(png_structrp png_ptr, png_inforp info_ptr,
+ int transforms,
+ voidp params)
+{
+ int row;
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* png_read_info() gives us all of the information from the
+ * PNG file before the first IDAT (image data chunk).
+ */
+ png_read_info(png_ptr, info_ptr);
+ if (info_ptr->height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
+ png_error(png_ptr, "Image is too high to process with png_read_png()");
+
+ /* -------------- image transformations start here ------------------- */
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ /* Tell libpng to strip 16-bit/color files down to 8 bits per color.
+ */
+ if (transforms & PNG_TRANSFORM_SCALE_16)
+ {
+ /* Added at libpng-1.5.4. "strip_16" produces the same result that it
+ * did in earlier versions, while "scale_16" is now more accurate.
+ */
+ png_set_scale_16(png_ptr);
+ }
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ /* If both SCALE and STRIP are required pngrtran will effectively cancel the
+ * latter by doing SCALE first. This is ok and allows apps not to check for
+ * which is supported to get the right answer.
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_16)
+ png_set_strip_16(png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ /* Strip alpha bytes from the input data without combining with
+ * the background (not recommended).
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+ png_set_strip_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
+ /* Extract multiple pixels with bit depths of 1, 2, or 4 from a single
+ * byte into separate bytes (useful for paletted and grayscale images).
+ */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ /* Change the order of packed pixels to least significant bit first
+ * (not useful if you are using png_set_packing).
+ */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ /* Expand paletted colors into true RGB triplets
+ * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+ * Expand paletted or RGB images with transparency to full alpha
+ * channels so the data will be available as RGBA quartets.
+ */
+ if (transforms & PNG_TRANSFORM_EXPAND)
+ if ((png_ptr->bit_depth < 8) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+ (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+ png_set_expand(png_ptr);
+#endif
+
+ /* We don't handle background color or gamma transformation or quantizing.
+ */
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+ /* Invert monochrome files to have 0 as white and 1 as black
+ */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ /* If you want to shift the pixel values from the range [0,255] or
+ * [0,65535] to the original [0,7] or [0,31], or whatever range the
+ * colors were originally in:
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+ {
+ png_color_8p sig_bit;
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ png_set_shift(png_ptr, sig_bit);
+ }
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+ /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#ifdef PNG_READ_SWAP_SUPPORTED
+ /* Swap bytes of 16-bit files to least significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+/* Added at libpng-1.2.41 */
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+/* Added at libpng-1.2.41 */
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* Expand grayscale image to RGB */
+ if (transforms & PNG_TRANSFORM_GRAY_TO_RGB)
+ png_set_gray_to_rgb(png_ptr);
+#endif
+
+/* Added at libpng-1.5.4 */
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ if (transforms & PNG_TRANSFORM_EXPAND_16)
+ png_set_expand_16(png_ptr);
+#endif
+
+ /* We don't handle adding filler bytes */
+
+ /* We use png_read_image and rely on that for interlace handling, but we also
+ * call png_read_update_info therefore must turn on interlace handling now:
+ */
+ (void)png_set_interlace_handling(png_ptr);
+
+ /* Optional call to gamma correct and add the background to the palette
+ * and update info structure. REQUIRED if you are expecting libpng to
+ * update the palette for you (i.e., you selected such a transform above).
+ */
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* -------------- image transformations end here ------------------- */
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+ if (info_ptr->row_pointers == NULL)
+ {
+ png_uint_32 iptr;
+
+ info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+ info_ptr->height * (sizeof (png_bytep)));
+ for (iptr=0; iptr<info_ptr->height; iptr++)
+ info_ptr->row_pointers[iptr] = NULL;
+
+ info_ptr->free_me |= PNG_FREE_ROWS;
+
+ for (row = 0; row < (int)info_ptr->height; row++)
+ info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
+ png_get_rowbytes(png_ptr, info_ptr));
+ }
+
+ png_read_image(png_ptr, info_ptr->row_pointers);
+ info_ptr->valid |= PNG_INFO_IDAT;
+
+ /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
+ png_read_end(png_ptr, info_ptr);
+
+ PNG_UNUSED(transforms) /* Quiet compiler warnings */
+ PNG_UNUSED(params)
+
+}
+#endif /* PNG_INFO_IMAGE_SUPPORTED */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* SIMPLIFIED READ
+ *
+ * This code currently relies on the sequential reader, though it could easily
+ * be made to work with the progressive one.
+ */
+/* Arguments to png_image_finish_read: */
+
+/* Encoding of PNG data (used by the color-map code) */
+/* TODO: change these, dang, ANSI-C reserves the 'E' namespace. */
+# define E_NOTSET 0 /* File encoding not yet known */
+# define E_sRGB 1 /* 8-bit encoded to sRGB gamma */
+# define E_LINEAR 2 /* 16-bit linear: not encoded, NOT pre-multiplied! */
+# define E_FILE 3 /* 8-bit encoded to file gamma, not sRGB or linear */
+# define E_LINEAR8 4 /* 8-bit linear: only from a file value */
+
+/* Color-map processing: after libpng has run on the PNG image further
+ * processing may be needed to conver the data to color-map indicies.
+ */
+#define PNG_CMAP_NONE 0
+#define PNG_CMAP_GA 1 /* Process GA data to a color-map with alpha */
+#define PNG_CMAP_TRANS 2 /* Process GA data to a background index */
+#define PNG_CMAP_RGB 3 /* Process RGB data */
+#define PNG_CMAP_RGB_ALPHA 4 /* Process RGBA data */
+
+/* The following document where the background is for each processing case. */
+#define PNG_CMAP_NONE_BACKGROUND 256
+#define PNG_CMAP_GA_BACKGROUND 231
+#define PNG_CMAP_TRANS_BACKGROUND 254
+#define PNG_CMAP_RGB_BACKGROUND 256
+#define PNG_CMAP_RGB_ALPHA_BACKGROUND 216
+
+typedef struct
+{
+ /* Arguments: */
+ png_imagep image;
+ png_voidp buffer;
+ png_int_32 row_stride;
+ png_voidp colormap;
+ png_const_colorp background;
+ /* Local variables: */
+ png_voidp local_row;
+ png_voidp first_row;
+ ptrdiff_t row_bytes; /* step between rows */
+ int file_encoding; /* E_ values above */
+ png_fixed_point gamma_to_linear; /* For E_FILE, reciprocal of gamma */
+ int colormap_processing; /* PNG_CMAP_ values above */
+} png_image_read_control;
+
+/* Do all the *safe* initialization - 'safe' means that png_error won't be
+ * called, so setting up the jmp_buf is not required. This means that anything
+ * called from here must *not* call png_malloc - it has to call png_malloc_warn
+ * instead so that control is returned safely back to this routine.
+ */
+static int
+png_image_read_init(png_imagep image)
+{
+ if (image->opaque == NULL)
+ {
+ png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, image,
+ png_safe_error, png_safe_warning);
+
+ /* And set the rest of the structure to NULL to ensure that the various
+ * fields are consistent.
+ */
+ memset(image, 0, (sizeof *image));
+ image->version = PNG_IMAGE_VERSION;
+
+ if (png_ptr != NULL)
+ {
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+
+ if (info_ptr != NULL)
+ {
+ png_controlp control = png_voidcast(png_controlp,
+ png_malloc_warn(png_ptr, (sizeof *control)));
+
+ if (control != NULL)
+ {
+ memset(control, 0, (sizeof *control));
+
+ control->png_ptr = png_ptr;
+ control->info_ptr = info_ptr;
+ control->for_write = 0;
+
+ image->opaque = control;
+ return 1;
+ }
+
+ /* Error clean up */
+ png_destroy_info_struct(png_ptr, &info_ptr);
+ }
+
+ png_destroy_read_struct(&png_ptr, NULL, NULL);
+ }
+
+ return png_image_error(image, "png_image_read: out of memory");
+ }
+
+ return png_image_error(image, "png_image_read: opaque pointer not NULL");
+}
+
+/* Utility to find the base format of a PNG file from a png_struct. */
+static png_uint_32
+png_image_format(png_structrp png_ptr)
+{
+ png_uint_32 format = 0;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ format |= PNG_FORMAT_FLAG_COLOR;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ format |= PNG_FORMAT_FLAG_ALPHA;
+
+ /* Use png_ptr here, not info_ptr, because by examination png_handle_tRNS
+ * sets the png_struct fields; that's all we are interested in here. The
+ * precise interaction with an app call to png_set_tRNS and PNG file reading
+ * is unclear.
+ */
+ else if (png_ptr->num_trans > 0)
+ format |= PNG_FORMAT_FLAG_ALPHA;
+
+ if (png_ptr->bit_depth == 16)
+ format |= PNG_FORMAT_FLAG_LINEAR;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_PALETTE)
+ format |= PNG_FORMAT_FLAG_COLORMAP;
+
+ return format;
+}
+
+/* Is the given gamma significantly different from sRGB? The test is the same
+ * one used in pngrtran.c when deciding whether to do gamma correction. The
+ * arithmetic optimizes the division by using the fact that the inverse of the
+ * file sRGB gamma is 2.2
+ */
+static int
+png_gamma_not_sRGB(png_fixed_point g)
+{
+ if (g < PNG_FP_1)
+ {
+ /* An uninitialized gamma is assumed to be sRGB for the simplified API. */
+ if (g == 0)
+ return 0;
+
+ return png_gamma_significant((g * 11 + 2)/5 /* i.e. *2.2, rounded */);
+ }
+
+ return 1;
+}
+
+/* Do the main body of a 'png_image_begin_read' function; read the PNG file
+ * header and fill in all the information. This is executed in a safe context,
+ * unlike the init routine above.
+ */
+static int
+png_image_read_header(png_voidp argument)
+{
+ png_imagep image = png_voidcast(png_imagep, argument);
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+
+ png_set_benign_errors(png_ptr, 1/*warn*/);
+ png_read_info(png_ptr, info_ptr);
+
+ /* Do this the fast way; just read directly out of png_struct. */
+ image->width = png_ptr->width;
+ image->height = png_ptr->height;
+
+ {
+ png_uint_32 format = png_image_format(png_ptr);
+
+ image->format = format;
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+ /* Does the colorspace match sRGB? If there is no color endpoint
+ * (colorant) information assume yes, otherwise require the
+ * 'ENDPOINTS_MATCHE_sRGB' colorspace flag to have been set. If the
+ * colorspace has been determined to be invalid ignore it.
+ */
+ if ((format & PNG_FORMAT_FLAG_COLOR) != 0 && ((png_ptr->colorspace.flags
+ & (PNG_COLORSPACE_HAVE_ENDPOINTS|PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB|
+ PNG_COLORSPACE_INVALID)) == PNG_COLORSPACE_HAVE_ENDPOINTS))
+ image->flags |= PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB;
+#endif
+ }
+
+ /* We need the maximum number of entries regardless of the format the
+ * application sets here.
+ */
+ {
+ png_uint_32 cmap_entries;
+
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ cmap_entries = 1U << png_ptr->bit_depth;
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ cmap_entries = png_ptr->num_palette;
+ break;
+
+ default:
+ cmap_entries = 256;
+ break;
+ }
+
+ if (cmap_entries > 256)
+ cmap_entries = 256;
+
+ image->colormap_entries = cmap_entries;
+ }
+
+ return 1;
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+int PNGAPI
+png_image_begin_read_from_stdio(png_imagep image, FILE* file)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file != NULL)
+ {
+ if (png_image_read_init(image))
+ {
+ /* This is slightly evil, but png_init_io doesn't do anything other
+ * than this and we haven't changed the standard IO functions so
+ * this saves a 'safe' function.
+ */
+ image->opaque->png_ptr->io_ptr = file;
+ return png_safe_execute(image, png_image_read_header, image);
+ }
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_begin_read_from_stdio: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_begin_read_from_stdio: incorrect PNG_IMAGE_VERSION");
+
+ return 0;
+}
+
+int PNGAPI
+png_image_begin_read_from_file(png_imagep image, const char *file_name)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file_name != NULL)
+ {
+ FILE *fp = fopen(file_name, "rb");
+
+ if (fp != NULL)
+ {
+ if (png_image_read_init(image))
+ {
+ image->opaque->png_ptr->io_ptr = fp;
+ image->opaque->owned_file = 1;
+ return png_safe_execute(image, png_image_read_header, image);
+ }
+
+ /* Clean up: just the opened file. */
+ (void)fclose(fp);
+ }
+
+ else
+ return png_image_error(image, strerror(errno));
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_begin_read_from_file: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_begin_read_from_file: incorrect PNG_IMAGE_VERSION");
+
+ return 0;
+}
+#endif /* PNG_STDIO_SUPPORTED */
+
+static void PNGCBAPI
+png_image_memory_read(png_structp png_ptr, png_bytep out, png_size_t need)
+{
+ if (png_ptr != NULL)
+ {
+ png_imagep image = png_voidcast(png_imagep, png_ptr->io_ptr);
+ if (image != NULL)
+ {
+ png_controlp cp = image->opaque;
+ if (cp != NULL)
+ {
+ png_const_bytep memory = cp->memory;
+ png_size_t size = cp->size;
+
+ if (memory != NULL && size >= need)
+ {
+ memcpy(out, memory, need);
+ cp->memory = memory + need;
+ cp->size = size - need;
+ return;
+ }
+
+ png_error(png_ptr, "read beyond end of data");
+ }
+ }
+
+ png_error(png_ptr, "invalid memory read");
+ }
+}
+
+int PNGAPI png_image_begin_read_from_memory(png_imagep image,
+ png_const_voidp memory, png_size_t size)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (memory != NULL && size > 0)
+ {
+ if (png_image_read_init(image))
+ {
+ /* Now set the IO functions to read from the memory buffer and
+ * store it into io_ptr. Again do this in-place to avoid calling a
+ * libpng function that requires error handling.
+ */
+ image->opaque->memory = png_voidcast(png_const_bytep, memory);
+ image->opaque->size = size;
+ image->opaque->png_ptr->io_ptr = image;
+ image->opaque->png_ptr->read_data_fn = png_image_memory_read;
+
+ return png_safe_execute(image, png_image_read_header, image);
+ }
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_begin_read_from_memory: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_begin_read_from_memory: incorrect PNG_IMAGE_VERSION");
+
+ return 0;
+}
+
+/* Utility function to skip chunks that are not used by the simplified image
+ * read functions and an appropriate macro to call it.
+ */
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+static void
+png_image_skip_unused_chunks(png_structrp png_ptr)
+{
+ /* Prepare the reader to ignore all recognized chunks whose data will not
+ * be used, i.e., all chunks recognized by libpng except for those
+ * involved in basic image reading:
+ *
+ * IHDR, PLTE, IDAT, IEND
+ *
+ * Or image data handling:
+ *
+ * tRNS, bKGD, gAMA, cHRM, sRGB, iCCP and sBIT.
+ *
+ * This provides a small performance improvement and eliminates any
+ * potential vulnerability to security problems in the unused chunks.
+ */
+ {
+ static PNG_CONST png_byte chunks_to_process[] = {
+ 98, 75, 71, 68, '\0', /* bKGD */
+ 99, 72, 82, 77, '\0', /* cHRM */
+ 103, 65, 77, 65, '\0', /* gAMA */
+ 105, 67, 67, 80, '\0', /* iCCP */
+ 115, 66, 73, 84, '\0', /* sBIT */
+ 115, 82, 71, 66, '\0', /* sRGB */
+ };
+
+ /* Ignore unknown chunks and all other chunks except for the
+ * IHDR, PLTE, tRNS, IDAT, and IEND chunks.
+ */
+ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_NEVER,
+ NULL, -1);
+
+ /* But do not ignore image data handling chunks */
+ png_set_keep_unknown_chunks(png_ptr, PNG_HANDLE_CHUNK_AS_DEFAULT,
+ chunks_to_process, (sizeof chunks_to_process)/5);
+ }
+}
+
+# define PNG_SKIP_CHUNKS(p) png_image_skip_unused_chunks(p)
+#else
+# define PNG_SKIP_CHUNKS(p) ((void)0)
+#endif /* PNG_HANDLE_AS_UNKNOWN_SUPPORTED */
+
+/* The following macro gives the exact rounded answer for all values in the
+ * range 0..255 (it actually divides by 51.2, but the rounding still generates
+ * the correct numbers 0..5
+ */
+#define PNG_DIV51(v8) (((v8) * 5 + 130) >> 8)
+
+/* Utility functions to make particular color-maps */
+static void
+set_file_encoding(png_image_read_control *display)
+{
+ png_fixed_point g = display->image->opaque->png_ptr->colorspace.gamma;
+ if (png_gamma_significant(g))
+ {
+ if (png_gamma_not_sRGB(g))
+ {
+ display->file_encoding = E_FILE;
+ display->gamma_to_linear = png_reciprocal(g);
+ }
+
+ else
+ display->file_encoding = E_sRGB;
+ }
+
+ else
+ display->file_encoding = E_LINEAR8;
+}
+
+static unsigned int
+decode_gamma(png_image_read_control *display, png_uint_32 value, int encoding)
+{
+ if (encoding == E_FILE) /* double check */
+ encoding = display->file_encoding;
+
+ if (encoding == E_NOTSET) /* must be the file encoding */
+ {
+ set_file_encoding(display);
+ encoding = display->file_encoding;
+ }
+
+ switch (encoding)
+ {
+ case E_FILE:
+ value = png_gamma_16bit_correct(value*257, display->gamma_to_linear);
+ break;
+
+ case E_sRGB:
+ value = png_sRGB_table[value];
+ break;
+
+ case E_LINEAR:
+ break;
+
+ case E_LINEAR8:
+ value *= 257;
+ break;
+
+ default:
+ png_error(display->image->opaque->png_ptr,
+ "unexpected encoding (internal error)");
+ break;
+ }
+
+ return value;
+}
+
+static png_uint_32
+png_colormap_compose(png_image_read_control *display,
+ png_uint_32 foreground, int foreground_encoding, png_uint_32 alpha,
+ png_uint_32 background, int encoding)
+{
+ /* The file value is composed on the background, the background has the given
+ * encoding and so does the result, the file is encoded with E_FILE and the
+ * file and alpha are 8-bit values. The (output) encoding will always be
+ * E_LINEAR or E_sRGB.
+ */
+ png_uint_32 f = decode_gamma(display, foreground, foreground_encoding);
+ png_uint_32 b = decode_gamma(display, background, encoding);
+
+ /* The alpha is always an 8-bit value (it comes from the palette), the value
+ * scaled by 255 is what PNG_sRGB_FROM_LINEAR requires.
+ */
+ f = f * alpha + b * (255-alpha);
+
+ if (encoding == E_LINEAR)
+ {
+ /* Scale to 65535; divide by 255, approximately (in fact this is extremely
+ * accurate, it divides by 255.00000005937181414556, with no overflow.)
+ */
+ f *= 257; /* Now scaled by 65535 */
+ f += f >> 16;
+ f = (f+32768) >> 16;
+ }
+
+ else /* E_sRGB */
+ f = PNG_sRGB_FROM_LINEAR(f);
+
+ return f;
+}
+
+/* NOTE: E_LINEAR values to this routine must be 16-bit, but E_FILE values must
+ * be 8-bit.
+ */
+static void
+png_create_colormap_entry(png_image_read_control *display,
+ png_uint_32 ip, png_uint_32 red, png_uint_32 green, png_uint_32 blue,
+ png_uint_32 alpha, int encoding)
+{
+ png_imagep image = display->image;
+ const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) ?
+ E_LINEAR : E_sRGB;
+ const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 &&
+ (red != green || green != blue);
+
+ if (ip > 255)
+ png_error(image->opaque->png_ptr, "color-map index out of range");
+
+ /* Update the cache with whether the file gamma is significantly different
+ * from sRGB.
+ */
+ if (encoding == E_FILE)
+ {
+ if (display->file_encoding == E_NOTSET)
+ set_file_encoding(display);
+
+ /* Note that the cached value may be E_FILE too, but if it is then the
+ * gamma_to_linear member has been set.
+ */
+ encoding = display->file_encoding;
+ }
+
+ if (encoding == E_FILE)
+ {
+ png_fixed_point g = display->gamma_to_linear;
+
+ red = png_gamma_16bit_correct(red*257, g);
+ green = png_gamma_16bit_correct(green*257, g);
+ blue = png_gamma_16bit_correct(blue*257, g);
+
+ if (convert_to_Y || output_encoding == E_LINEAR)
+ {
+ alpha *= 257;
+ encoding = E_LINEAR;
+ }
+
+ else
+ {
+ red = PNG_sRGB_FROM_LINEAR(red * 255);
+ green = PNG_sRGB_FROM_LINEAR(green * 255);
+ blue = PNG_sRGB_FROM_LINEAR(blue * 255);
+ encoding = E_sRGB;
+ }
+ }
+
+ else if (encoding == E_LINEAR8)
+ {
+ /* This encoding occurs quite frequently in test cases because PngSuite
+ * includes a gAMA 1.0 chunk with most images.
+ */
+ red *= 257;
+ green *= 257;
+ blue *= 257;
+ alpha *= 257;
+ encoding = E_LINEAR;
+ }
+
+ else if (encoding == E_sRGB && (convert_to_Y || output_encoding == E_LINEAR))
+ {
+ /* The values are 8-bit sRGB values, but must be converted to 16-bit
+ * linear.
+ */
+ red = png_sRGB_table[red];
+ green = png_sRGB_table[green];
+ blue = png_sRGB_table[blue];
+ alpha *= 257;
+ encoding = E_LINEAR;
+ }
+
+ /* This is set if the color isn't gray but the output is. */
+ if (encoding == E_LINEAR)
+ {
+ if (convert_to_Y)
+ {
+ /* NOTE: these values are copied from png_do_rgb_to_gray */
+ png_uint_32 y = (png_uint_32)6968 * red + (png_uint_32)23434 * green +
+ (png_uint_32)2366 * blue;
+
+ if (output_encoding == E_LINEAR)
+ y = (y + 16384) >> 15;
+
+ else
+ {
+ /* y is scaled by 32768, we need it scaled by 255: */
+ y = (y + 128) >> 8;
+ y *= 255;
+ y = PNG_sRGB_FROM_LINEAR((y + 64) >> 7);
+ encoding = E_sRGB;
+ }
+
+ blue = red = green = y;
+ }
+
+ else if (output_encoding == E_sRGB)
+ {
+ red = PNG_sRGB_FROM_LINEAR(red * 255);
+ green = PNG_sRGB_FROM_LINEAR(green * 255);
+ blue = PNG_sRGB_FROM_LINEAR(blue * 255);
+ alpha = PNG_DIV257(alpha);
+ encoding = E_sRGB;
+ }
+ }
+
+ if (encoding != output_encoding)
+ png_error(image->opaque->png_ptr, "bad encoding (internal error)");
+
+ /* Store the value. */
+ {
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
+# else
+# define afirst 0
+# endif
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
+# else
+# define bgr 0
+# endif
+
+ if (output_encoding == E_LINEAR)
+ {
+ png_uint_16p entry = png_voidcast(png_uint_16p, display->colormap);
+
+ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
+
+ /* The linear 16-bit values must be pre-multiplied by the alpha channel
+ * value, if less than 65535 (this is, effectively, composite on black
+ * if the alpha channel is removed.)
+ */
+ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
+ {
+ case 4:
+ entry[afirst ? 0 : 3] = (png_uint_16)alpha;
+ /* FALL THROUGH */
+
+ case 3:
+ if (alpha < 65535)
+ {
+ if (alpha > 0)
+ {
+ blue = (blue * alpha + 32767U)/65535U;
+ green = (green * alpha + 32767U)/65535U;
+ red = (red * alpha + 32767U)/65535U;
+ }
+
+ else
+ red = green = blue = 0;
+ }
+ entry[afirst + (2 ^ bgr)] = (png_uint_16)blue;
+ entry[afirst + 1] = (png_uint_16)green;
+ entry[afirst + bgr] = (png_uint_16)red;
+ break;
+
+ case 2:
+ entry[1 ^ afirst] = (png_uint_16)alpha;
+ /* FALL THROUGH */
+
+ case 1:
+ if (alpha < 65535)
+ {
+ if (alpha > 0)
+ green = (green * alpha + 32767U)/65535U;
+
+ else
+ green = 0;
+ }
+ entry[afirst] = (png_uint_16)green;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ else /* output encoding is E_sRGB */
+ {
+ png_bytep entry = png_voidcast(png_bytep, display->colormap);
+
+ entry += ip * PNG_IMAGE_SAMPLE_CHANNELS(image->format);
+
+ switch (PNG_IMAGE_SAMPLE_CHANNELS(image->format))
+ {
+ case 4:
+ entry[afirst ? 0 : 3] = (png_byte)alpha;
+ case 3:
+ entry[afirst + (2 ^ bgr)] = (png_byte)blue;
+ entry[afirst + 1] = (png_byte)green;
+ entry[afirst + bgr] = (png_byte)red;
+ break;
+
+ case 2:
+ entry[1 ^ afirst] = (png_byte)alpha;
+ case 1:
+ entry[afirst] = (png_byte)green;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+# ifdef afirst
+# undef afirst
+# endif
+# ifdef bgr
+# undef bgr
+# endif
+ }
+}
+
+static int
+make_gray_file_colormap(png_image_read_control *display)
+{
+ unsigned int i;
+
+ for (i=0; i<256; ++i)
+ png_create_colormap_entry(display, i, i, i, i, 255, E_FILE);
+
+ return i;
+}
+
+static int
+make_gray_colormap(png_image_read_control *display)
+{
+ unsigned int i;
+
+ for (i=0; i<256; ++i)
+ png_create_colormap_entry(display, i, i, i, i, 255, E_sRGB);
+
+ return i;
+}
+#define PNG_GRAY_COLORMAP_ENTRIES 256
+
+static int
+make_ga_colormap(png_image_read_control *display)
+{
+ unsigned int i, a;
+
+ /* Alpha is retained, the output will be a color-map with entries
+ * selected by six levels of alpha. One transparent entry, 6 gray
+ * levels for all the intermediate alpha values, leaving 230 entries
+ * for the opaque grays. The color-map entries are the six values
+ * [0..5]*51, the GA processing uses PNG_DIV51(value) to find the
+ * relevant entry.
+ *
+ * if (alpha > 229) // opaque
+ * {
+ * // The 231 entries are selected to make the math below work:
+ * base = 0;
+ * entry = (231 * gray + 128) >> 8;
+ * }
+ * else if (alpha < 26) // transparent
+ * {
+ * base = 231;
+ * entry = 0;
+ * }
+ * else // partially opaque
+ * {
+ * base = 226 + 6 * PNG_DIV51(alpha);
+ * entry = PNG_DIV51(gray);
+ * }
+ */
+ i = 0;
+ while (i < 231)
+ {
+ unsigned int gray = (i * 256 + 115) / 231;
+ png_create_colormap_entry(display, i++, gray, gray, gray, 255, E_sRGB);
+ }
+
+ /* 255 is used here for the component values for consistency with the code
+ * that undoes premultiplication in pngwrite.c.
+ */
+ png_create_colormap_entry(display, i++, 255, 255, 255, 0, E_sRGB);
+
+ for (a=1; a<5; ++a)
+ {
+ unsigned int g;
+
+ for (g=0; g<6; ++g)
+ png_create_colormap_entry(display, i++, g*51, g*51, g*51, a*51,
+ E_sRGB);
+ }
+
+ return i;
+}
+
+#define PNG_GA_COLORMAP_ENTRIES 256
+
+static int
+make_rgb_colormap(png_image_read_control *display)
+{
+ unsigned int i, r;
+
+ /* Build a 6x6x6 opaque RGB cube */
+ for (i=r=0; r<6; ++r)
+ {
+ unsigned int g;
+
+ for (g=0; g<6; ++g)
+ {
+ unsigned int b;
+
+ for (b=0; b<6; ++b)
+ png_create_colormap_entry(display, i++, r*51, g*51, b*51, 255,
+ E_sRGB);
+ }
+ }
+
+ return i;
+}
+
+#define PNG_RGB_COLORMAP_ENTRIES 216
+
+/* Return a palette index to the above palette given three 8-bit sRGB values. */
+#define PNG_RGB_INDEX(r,g,b) \
+ ((png_byte)(6 * (6 * PNG_DIV51(r) + PNG_DIV51(g)) + PNG_DIV51(b)))
+
+static int
+png_image_read_colormap(png_voidp argument)
+{
+ png_image_read_control *display =
+ png_voidcast(png_image_read_control*, argument);
+ const png_imagep image = display->image;
+
+ const png_structrp png_ptr = image->opaque->png_ptr;
+ const png_uint_32 output_format = image->format;
+ const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) ?
+ E_LINEAR : E_sRGB;
+
+ unsigned int cmap_entries;
+ unsigned int output_processing; /* Output processing option */
+ unsigned int data_encoding = E_NOTSET; /* Encoding libpng must produce */
+
+ /* Background information; the background color and the index of this color
+ * in the color-map if it exists (else 256).
+ */
+ unsigned int background_index = 256;
+ png_uint_32 back_r, back_g, back_b;
+
+ /* Flags to accumulate things that need to be done to the input. */
+ int expand_tRNS = 0;
+
+ /* Exclude the NYI feature of compositing onto a color-mapped buffer; it is
+ * very difficult to do, the results look awful, and it is difficult to see
+ * what possible use it is because the application can't control the
+ * color-map.
+ */
+ if (((png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0 ||
+ png_ptr->num_trans > 0) /* alpha in input */ &&
+ ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0) /* no alpha in output */)
+ {
+ if (output_encoding == E_LINEAR) /* compose on black */
+ back_b = back_g = back_r = 0;
+
+ else if (display->background == NULL /* no way to remove it */)
+ png_error(png_ptr,
+ "a background color must be supplied to remove alpha/transparency");
+
+ /* Get a copy of the background color (this avoids repeating the checks
+ * below.) The encoding is 8-bit sRGB or 16-bit linear, depending on the
+ * output format.
+ */
+ else
+ {
+ back_g = display->background->green;
+ if (output_format & PNG_FORMAT_FLAG_COLOR)
+ {
+ back_r = display->background->red;
+ back_b = display->background->blue;
+ }
+ else
+ back_b = back_r = back_g;
+ }
+ }
+
+ else if (output_encoding == E_LINEAR)
+ back_b = back_r = back_g = 65535;
+
+ else
+ back_b = back_r = back_g = 255;
+
+ /* Default the input file gamma if required - this is necessary because
+ * libpng assumes that if no gamma information is present the data is in the
+ * output format, but the simplified API deduces the gamma from the input
+ * format.
+ */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_GAMMA) == 0)
+ {
+ /* Do this directly, not using the png_colorspace functions, to ensure
+ * that it happens even if the colorspace is invalid (though probably if
+ * it is the setting will be ignored) Note that the same thing can be
+ * achieved at the application interface with png_set_gAMA.
+ */
+ if (png_ptr->bit_depth == 16 &&
+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+ png_ptr->colorspace.gamma = PNG_GAMMA_LINEAR;
+
+ else
+ png_ptr->colorspace.gamma = PNG_GAMMA_sRGB_INVERSE;
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ }
+
+ /* Decide what to do based on the PNG color type of the input data. The
+ * utility function png_create_colormap_entry deals with most aspects of the
+ * output transformations; this code works out how to produce bytes of
+ * color-map entries from the original format.
+ */
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ if (png_ptr->bit_depth <= 8)
+ {
+ /* There at most 256 colors in the output, regardless of
+ * transparency.
+ */
+ unsigned int step, i, val, trans = 256/*ignore*/, back_alpha = 0;
+
+ cmap_entries = 1U << png_ptr->bit_depth;
+ if (cmap_entries > image->colormap_entries)
+ png_error(png_ptr, "gray[8] color-map: too few entries");
+
+ step = 255 / (cmap_entries - 1);
+ output_processing = PNG_CMAP_NONE;
+
+ /* If there is a tRNS chunk then this either selects a transparent
+ * value or, if the output has no alpha, the background color.
+ */
+ if (png_ptr->num_trans > 0)
+ {
+ trans = png_ptr->trans_color.gray;
+
+ if ((output_format & PNG_FORMAT_FLAG_ALPHA) == 0)
+ back_alpha = output_encoding == E_LINEAR ? 65535 : 255;
+ }
+
+ /* png_create_colormap_entry just takes an RGBA and writes the
+ * corresponding color-map entry using the format from 'image',
+ * including the required conversion to sRGB or linear as
+ * appropriate. The input values are always either sRGB (if the
+ * gamma correction flag is 0) or 0..255 scaled file encoded values
+ * (if the function must gamma correct them).
+ */
+ for (i=val=0; i<cmap_entries; ++i, val += step)
+ {
+ /* 'i' is a file value. While this will result in duplicated
+ * entries for 8-bit non-sRGB encoded files it is necessary to
+ * have non-gamma corrected values to do tRNS handling.
+ */
+ if (i != trans)
+ png_create_colormap_entry(display, i, val, val, val, 255,
+ E_FILE/*8-bit with file gamma*/);
+
+ /* Else this entry is transparent. The colors don't matter if
+ * there is an alpha channel (back_alpha == 0), but it does no
+ * harm to pass them in; the values are not set above so this
+ * passes in white.
+ *
+ * NOTE: this preserves the full precision of the application
+ * supplied background color when it is used.
+ */
+ else
+ png_create_colormap_entry(display, i, back_r, back_g, back_b,
+ back_alpha, output_encoding);
+ }
+
+ /* We need libpng to preserve the original encoding. */
+ data_encoding = E_FILE;
+
+ /* The rows from libpng, while technically gray values, are now also
+ * color-map indicies; however, they may need to be expanded to 1
+ * byte per pixel. This is what png_set_packing does (i.e., it
+ * unpacks the bit values into bytes.)
+ */
+ if (png_ptr->bit_depth < 8)
+ png_set_packing(png_ptr);
+ }
+
+ else /* bit depth is 16 */
+ {
+ /* The 16-bit input values can be converted directly to 8-bit gamma
+ * encoded values; however, if a tRNS chunk is present 257 color-map
+ * entries are required. This means that the extra entry requires
+ * special processing; add an alpha channel, sacrifice gray level
+ * 254 and convert transparent (alpha==0) entries to that.
+ *
+ * Use libpng to chop the data to 8 bits. Convert it to sRGB at the
+ * same time to minimize quality loss. If a tRNS chunk is present
+ * this means libpng must handle it too; otherwise it is impossible
+ * to do the exact match on the 16-bit value.
+ *
+ * If the output has no alpha channel *and* the background color is
+ * gray then it is possible to let libpng handle the substitution by
+ * ensuring that the corresponding gray level matches the background
+ * color exactly.
+ */
+ data_encoding = E_sRGB;
+
+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "gray[16] color-map: too few entries");
+
+ cmap_entries = make_gray_colormap(display);
+
+ if (png_ptr->num_trans > 0)
+ {
+ unsigned int back_alpha;
+
+ if (output_format & PNG_FORMAT_FLAG_ALPHA)
+ back_alpha = 0;
+
+ else
+ {
+ if (back_r == back_g && back_g == back_b)
+ {
+ /* Background is gray; no special processing will be
+ * required.
+ */
+ png_color_16 c;
+ png_uint_32 gray = back_g;
+
+ if (output_encoding == E_LINEAR)
+ {
+ gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+ /* And make sure the corresponding palette entry
+ * matches.
+ */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 65535, E_LINEAR);
+ }
+
+ /* The background passed to libpng, however, must be the
+ * sRGB value.
+ */
+ c.index = 0; /*unused*/
+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+ /* NOTE: does this work without expanding tRNS to alpha?
+ * It should be the color->gray case below apparently
+ * doesn't.
+ */
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+
+ output_processing = PNG_CMAP_NONE;
+ break;
+ }
+
+ back_alpha = output_encoding == E_LINEAR ? 65535 : 255;
+ }
+
+ /* output_processing means that the libpng-processed row will be
+ * 8-bit GA and it has to be processing to single byte color-map
+ * values. Entry 254 is replaced by either a completely
+ * transparent entry or by the background color at full
+ * precision (and the background color is not a simple gray leve
+ * in this case.)
+ */
+ expand_tRNS = 1;
+ output_processing = PNG_CMAP_TRANS;
+ background_index = 254;
+
+ /* And set (overwrite) color-map entry 254 to the actual
+ * background color at full precision.
+ */
+ png_create_colormap_entry(display, 254, back_r, back_g, back_b,
+ back_alpha, output_encoding);
+ }
+
+ else
+ output_processing = PNG_CMAP_NONE;
+ }
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ /* 8-bit or 16-bit PNG with two channels - gray and alpha. A minimum
+ * of 65536 combinations. If, however, the alpha channel is to be
+ * removed there are only 256 possibilities if the background is gray.
+ * (Otherwise there is a subset of the 65536 possibilities defined by
+ * the triangle between black, white and the background color.)
+ *
+ * Reduce 16-bit files to 8-bit and sRGB encode the result. No need to
+ * worry about tRNS matching - tRNS is ignored if there is an alpha
+ * channel.
+ */
+ data_encoding = E_sRGB;
+
+ if (output_format & PNG_FORMAT_FLAG_ALPHA)
+ {
+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "gray+alpha color-map: too few entries");
+
+ cmap_entries = make_ga_colormap(display);
+
+ background_index = PNG_CMAP_GA_BACKGROUND;
+ output_processing = PNG_CMAP_GA;
+ }
+
+ else /* alpha is removed */
+ {
+ /* Alpha must be removed as the PNG data is processed when the
+ * background is a color because the G and A channels are
+ * independent and the vector addition (non-parallel vectors) is a
+ * 2-D problem.
+ *
+ * This can be reduced to the same algorithm as above by making a
+ * colormap containing gray levels (for the opaque grays), a
+ * background entry (for a transparent pixel) and a set of four six
+ * level color values, one set for each intermediate alpha value.
+ * See the comments in make_ga_colormap for how this works in the
+ * per-pixel processing.
+ *
+ * If the background is gray, however, we only need a 256 entry gray
+ * level color map. It is sufficient to make the entry generated
+ * for the background color be exactly the color specified.
+ */
+ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0 ||
+ (back_r == back_g && back_g == back_b))
+ {
+ /* Background is gray; no special processing will be required. */
+ png_color_16 c;
+ png_uint_32 gray = back_g;
+
+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "gray-alpha color-map: too few entries");
+
+ cmap_entries = make_gray_colormap(display);
+
+ if (output_encoding == E_LINEAR)
+ {
+ gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+ /* And make sure the corresponding palette entry matches. */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 65535, E_LINEAR);
+ }
+
+ /* The background passed to libpng, however, must be the sRGB
+ * value.
+ */
+ c.index = 0; /*unused*/
+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+
+ output_processing = PNG_CMAP_NONE;
+ }
+
+ else
+ {
+ png_uint_32 i, a;
+
+ /* This is the same as png_make_ga_colormap, above, except that
+ * the entries are all opaque.
+ */
+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "ga-alpha color-map: too few entries");
+
+ i = 0;
+ while (i < 231)
+ {
+ png_uint_32 gray = (i * 256 + 115) / 231;
+ png_create_colormap_entry(display, i++, gray, gray, gray,
+ 255, E_sRGB);
+ }
+
+ /* NOTE: this preserves the full precision of the application
+ * background color.
+ */
+ background_index = i;
+ png_create_colormap_entry(display, i++, back_r, back_g, back_b,
+ output_encoding == E_LINEAR ? 65535U : 255U, output_encoding);
+
+ /* For non-opaque input composite on the sRGB background - this
+ * requires inverting the encoding for each component. The input
+ * is still converted to the sRGB encoding because this is a
+ * reasonable approximate to the logarithmic curve of human
+ * visual sensitivity, at least over the narrow range which PNG
+ * represents. Consequently 'G' is always sRGB encoded, while
+ * 'A' is linear. We need the linear background colors.
+ */
+ if (output_encoding == E_sRGB) /* else already linear */
+ {
+ /* This may produce a value not exactly matching the
+ * background, but that's ok because these numbers are only
+ * used when alpha != 0
+ */
+ back_r = png_sRGB_table[back_r];
+ back_g = png_sRGB_table[back_g];
+ back_b = png_sRGB_table[back_b];
+ }
+
+ for (a=1; a<5; ++a)
+ {
+ unsigned int g;
+
+ /* PNG_sRGB_FROM_LINEAR expects a 16-bit linear value scaled
+ * by an 8-bit alpha value (0..255).
+ */
+ png_uint_32 alpha = 51 * a;
+ png_uint_32 back_rx = (255-alpha) * back_r;
+ png_uint_32 back_gx = (255-alpha) * back_g;
+ png_uint_32 back_bx = (255-alpha) * back_b;
+
+ for (g=0; g<6; ++g)
+ {
+ png_uint_32 gray = png_sRGB_table[g*51] * alpha;
+
+ png_create_colormap_entry(display, i++,
+ PNG_sRGB_FROM_LINEAR(gray + back_rx),
+ PNG_sRGB_FROM_LINEAR(gray + back_gx),
+ PNG_sRGB_FROM_LINEAR(gray + back_bx), 255, E_sRGB);
+ }
+ }
+
+ cmap_entries = i;
+ output_processing = PNG_CMAP_GA;
+ }
+ }
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ /* Exclude the case where the output is gray; we can always handle this
+ * with the cases above.
+ */
+ if ((output_format & PNG_FORMAT_FLAG_COLOR) == 0)
+ {
+ /* The color-map will be grayscale, so we may as well convert the
+ * input RGB values to a simple grayscale and use the grayscale
+ * code above.
+ *
+ * NOTE: calling this apparently damages the recognition of the
+ * transparent color in background color handling; call
+ * png_set_tRNS_to_alpha before png_set_background_fixed.
+ */
+ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE, -1,
+ -1);
+ data_encoding = E_sRGB;
+
+ /* The output will now be one or two 8-bit gray or gray+alpha
+ * channels. The more complex case arises when the input has alpha.
+ */
+ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0) &&
+ (output_format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ {
+ /* Both input and output have an alpha channel, so no background
+ * processing is required; just map the GA bytes to the right
+ * color-map entry.
+ */
+ expand_tRNS = 1;
+
+ if (PNG_GA_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "rgb[ga] color-map: too few entries");
+
+ cmap_entries = make_ga_colormap(display);
+ background_index = PNG_CMAP_GA_BACKGROUND;
+ output_processing = PNG_CMAP_GA;
+ }
+
+ else
+ {
+ /* Either the input or the output has no alpha channel, so there
+ * will be no non-opaque pixels in the color-map; it will just be
+ * grayscale.
+ */
+ if (PNG_GRAY_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "rgb[gray] color-map: too few entries");
+
+ /* Ideally this code would use libpng to do the gamma correction,
+ * but if an input alpha channel is to be removed we will hit the
+ * libpng bug in gamma+compose+rgb-to-gray (the double gamma
+ * correction bug). Fix this by dropping the gamma correction in
+ * this case and doing it in the palette; this will result in
+ * duplicate palette entries, but that's better than the
+ * alternative of double gamma correction.
+ */
+ if ((png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0) &&
+ png_gamma_not_sRGB(png_ptr->colorspace.gamma))
+ {
+ cmap_entries = make_gray_file_colormap(display);
+ data_encoding = E_FILE;
+ }
+
+ else
+ cmap_entries = make_gray_colormap(display);
+
+ /* But if the input has alpha or transparency it must be removed
+ */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0)
+ {
+ png_color_16 c;
+ png_uint_32 gray = back_g;
+
+ /* We need to ensure that the application background exists in
+ * the colormap and that completely transparent pixels map to
+ * it. Achieve this simply by ensuring that the entry
+ * selected for the background really is the background color.
+ */
+ if (data_encoding == E_FILE) /* from the fixup above */
+ {
+ /* The app supplied a gray which is in output_encoding, we
+ * need to convert it to a value of the input (E_FILE)
+ * encoding then set this palette entry to the required
+ * output encoding.
+ */
+ if (output_encoding == E_sRGB)
+ gray = png_sRGB_table[gray]; /* now E_LINEAR */
+
+ gray = PNG_DIV257(png_gamma_16bit_correct(gray,
+ png_ptr->colorspace.gamma)); /* now E_FILE */
+
+ /* And make sure the corresponding palette entry contains
+ * exactly the required sRGB value.
+ */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 0/*unused*/, output_encoding);
+ }
+
+ else if (output_encoding == E_LINEAR)
+ {
+ gray = PNG_sRGB_FROM_LINEAR(gray * 255);
+
+ /* And make sure the corresponding palette entry matches.
+ */
+ png_create_colormap_entry(display, gray, back_g, back_g,
+ back_g, 0/*unused*/, E_LINEAR);
+ }
+
+ /* The background passed to libpng, however, must be the
+ * output (normally sRGB) value.
+ */
+ c.index = 0; /*unused*/
+ c.gray = c.red = c.green = c.blue = (png_uint_16)gray;
+
+ /* NOTE: the following is apparently a bug in libpng. Without
+ * it the transparent color recognition in
+ * png_set_background_fixed seems to go wrong.
+ */
+ expand_tRNS = 1;
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+ }
+
+ output_processing = PNG_CMAP_NONE;
+ }
+ }
+
+ else /* output is color */
+ {
+ /* We could use png_quantize here so long as there is no transparent
+ * color or alpha; png_quantize ignores alpha. Easier overall just
+ * to do it once and using PNG_DIV51 on the 6x6x6 reduced RGB cube.
+ * Consequently we always want libpng to produce sRGB data.
+ */
+ data_encoding = E_sRGB;
+
+ /* Is there any transparency or alpha? */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ png_ptr->num_trans > 0)
+ {
+ /* Is there alpha in the output too? If so all four channels are
+ * processed into a special RGB cube with alpha support.
+ */
+ if (output_format & PNG_FORMAT_FLAG_ALPHA)
+ {
+ png_uint_32 r;
+
+ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
+ png_error(png_ptr, "rgb+alpha color-map: too few entries");
+
+ cmap_entries = make_rgb_colormap(display);
+
+ /* Add a transparent entry. */
+ png_create_colormap_entry(display, cmap_entries, 255, 255,
+ 255, 0, E_sRGB);
+
+ /* This is stored as the background index for the processing
+ * algorithm.
+ */
+ background_index = cmap_entries++;
+
+ /* Add 27 r,g,b entries each with alpha 0.5. */
+ for (r=0; r<256; r = (r << 1) | 0x7f)
+ {
+ png_uint_32 g;
+
+ for (g=0; g<256; g = (g << 1) | 0x7f)
+ {
+ png_uint_32 b;
+
+ /* This generates components with the values 0, 127 and
+ * 255
+ */
+ for (b=0; b<256; b = (b << 1) | 0x7f)
+ png_create_colormap_entry(display, cmap_entries++,
+ r, g, b, 128, E_sRGB);
+ }
+ }
+
+ expand_tRNS = 1;
+ output_processing = PNG_CMAP_RGB_ALPHA;
+ }
+
+ else
+ {
+ /* Alpha/transparency must be removed. The background must
+ * exist in the color map (achieved by setting adding it after
+ * the 666 color-map). If the standard processing code will
+ * pick up this entry automatically that's all that is
+ * required; libpng can be called to do the background
+ * processing.
+ */
+ unsigned int sample_size =
+ PNG_IMAGE_SAMPLE_SIZE(output_format);
+ png_uint_32 r, g, b; /* sRGB background */
+
+ if (PNG_RGB_COLORMAP_ENTRIES+1+27 > image->colormap_entries)
+ png_error(png_ptr, "rgb-alpha color-map: too few entries");
+
+ cmap_entries = make_rgb_colormap(display);
+
+ png_create_colormap_entry(display, cmap_entries, back_r,
+ back_g, back_b, 0/*unused*/, output_encoding);
+
+ if (output_encoding == E_LINEAR)
+ {
+ r = PNG_sRGB_FROM_LINEAR(back_r * 255);
+ g = PNG_sRGB_FROM_LINEAR(back_g * 255);
+ b = PNG_sRGB_FROM_LINEAR(back_b * 255);
+ }
+
+ else
+ {
+ r = back_r;
+ g = back_g;
+ b = back_g;
+ }
+
+ /* Compare the newly-created color-map entry with the one the
+ * PNG_CMAP_RGB algorithm will use. If the two entries don't
+ * match, add the new one and set this as the background
+ * index.
+ */
+ if (memcmp((png_const_bytep)display->colormap +
+ sample_size * cmap_entries,
+ (png_const_bytep)display->colormap +
+ sample_size * PNG_RGB_INDEX(r,g,b),
+ sample_size) != 0)
+ {
+ /* The background color must be added. */
+ background_index = cmap_entries++;
+
+ /* Add 27 r,g,b entries each with created by composing with
+ * the background at alpha 0.5.
+ */
+ for (r=0; r<256; r = (r << 1) | 0x7f)
+ {
+ for (g=0; g<256; g = (g << 1) | 0x7f)
+ {
+ /* This generates components with the values 0, 127
+ * and 255
+ */
+ for (b=0; b<256; b = (b << 1) | 0x7f)
+ png_create_colormap_entry(display, cmap_entries++,
+ png_colormap_compose(display, r, E_sRGB, 128,
+ back_r, output_encoding),
+ png_colormap_compose(display, g, E_sRGB, 128,
+ back_g, output_encoding),
+ png_colormap_compose(display, b, E_sRGB, 128,
+ back_b, output_encoding),
+ 0/*unused*/, output_encoding);
+ }
+ }
+
+ expand_tRNS = 1;
+ output_processing = PNG_CMAP_RGB_ALPHA;
+ }
+
+ else /* background color is in the standard color-map */
+ {
+ png_color_16 c;
+
+ c.index = 0; /*unused*/
+ c.red = (png_uint_16)back_r;
+ c.gray = c.green = (png_uint_16)back_g;
+ c.blue = (png_uint_16)back_b;
+
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+
+ output_processing = PNG_CMAP_RGB;
+ }
+ }
+ }
+
+ else /* no alpha or transparency in the input */
+ {
+ /* Alpha in the output is irrelevant, simply map the opaque input
+ * pixels to the 6x6x6 color-map.
+ */
+ if (PNG_RGB_COLORMAP_ENTRIES > image->colormap_entries)
+ png_error(png_ptr, "rgb color-map: too few entries");
+
+ cmap_entries = make_rgb_colormap(display);
+ output_processing = PNG_CMAP_RGB;
+ }
+ }
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ /* It's already got a color-map. It may be necessary to eliminate the
+ * tRNS entries though.
+ */
+ {
+ unsigned int num_trans = png_ptr->num_trans;
+ png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL;
+ png_const_colorp colormap = png_ptr->palette;
+ const int do_background = trans != NULL &&
+ (output_format & PNG_FORMAT_FLAG_ALPHA) == 0;
+ unsigned int i;
+
+ /* Just in case: */
+ if (trans == NULL)
+ num_trans = 0;
+
+ output_processing = PNG_CMAP_NONE;
+ data_encoding = E_FILE; /* Don't change from color-map indicies */
+ cmap_entries = png_ptr->num_palette;
+ if (cmap_entries > 256)
+ cmap_entries = 256;
+
+ if (cmap_entries > image->colormap_entries)
+ png_error(png_ptr, "palette color-map: too few entries");
+
+ for (i=0; i < cmap_entries; ++i)
+ {
+ if (do_background && i < num_trans && trans[i] < 255)
+ {
+ if (trans[i] == 0)
+ png_create_colormap_entry(display, i, back_r, back_g,
+ back_b, 0, output_encoding);
+
+ else
+ {
+ /* Must compose the PNG file color in the color-map entry
+ * on the sRGB color in 'back'.
+ */
+ png_create_colormap_entry(display, i,
+ png_colormap_compose(display, colormap[i].red, E_FILE,
+ trans[i], back_r, output_encoding),
+ png_colormap_compose(display, colormap[i].green, E_FILE,
+ trans[i], back_g, output_encoding),
+ png_colormap_compose(display, colormap[i].blue, E_FILE,
+ trans[i], back_b, output_encoding),
+ output_encoding == E_LINEAR ? trans[i] * 257U :
+ trans[i],
+ output_encoding);
+ }
+ }
+
+ else
+ png_create_colormap_entry(display, i, colormap[i].red,
+ colormap[i].green, colormap[i].blue,
+ i < num_trans ? trans[i] : 255U, E_FILE/*8-bit*/);
+ }
+
+ /* The PNG data may have indicies packed in fewer than 8 bits, it
+ * must be expanded if so.
+ */
+ if (png_ptr->bit_depth < 8)
+ png_set_packing(png_ptr);
+ }
+ break;
+
+ default:
+ png_error(png_ptr, "invalid PNG color type");
+ /*NOT REACHED*/
+ break;
+ }
+
+ /* Now deal with the output processing */
+ if (expand_tRNS && png_ptr->num_trans > 0 &&
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) == 0)
+ png_set_tRNS_to_alpha(png_ptr);
+
+ switch (data_encoding)
+ {
+ default:
+ png_error(png_ptr, "bad data option (internal error)");
+ break;
+
+ case E_sRGB:
+ /* Change to 8-bit sRGB */
+ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB);
+ /* FALL THROUGH */
+
+ case E_FILE:
+ if (png_ptr->bit_depth > 8)
+ png_set_scale_16(png_ptr);
+ break;
+ }
+
+ if (cmap_entries > 256 || cmap_entries > image->colormap_entries)
+ png_error(png_ptr, "color map overflow (BAD internal error)");
+
+ image->colormap_entries = cmap_entries;
+
+ /* Double check using the recorded background index */
+ switch (output_processing)
+ {
+ case PNG_CMAP_NONE:
+ if (background_index != PNG_CMAP_NONE_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_GA:
+ if (background_index != PNG_CMAP_GA_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_TRANS:
+ if (background_index >= cmap_entries ||
+ background_index != PNG_CMAP_TRANS_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_RGB:
+ if (background_index != PNG_CMAP_RGB_BACKGROUND)
+ goto bad_background;
+ break;
+
+ case PNG_CMAP_RGB_ALPHA:
+ if (background_index != PNG_CMAP_RGB_ALPHA_BACKGROUND)
+ goto bad_background;
+ break;
+
+ default:
+ png_error(png_ptr, "bad processing option (internal error)");
+
+ bad_background:
+ png_error(png_ptr, "bad background index (internal error)");
+ }
+
+ display->colormap_processing = output_processing;
+
+ return 1/*ok*/;
+}
+
+/* The final part of the color-map read called from png_image_finish_read. */
+static int
+png_image_read_and_map(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ int passes;
+
+ /* Called when the libpng data must be transformed into the color-mapped
+ * form. There is a local row buffer in display->local and this routine must
+ * do the interlace handling.
+ */
+ switch (png_ptr->interlaced)
+ {
+ case PNG_INTERLACE_NONE:
+ passes = 1;
+ break;
+
+ case PNG_INTERLACE_ADAM7:
+ passes = PNG_INTERLACE_ADAM7_PASSES;
+ break;
+
+ default:
+ passes = 0;
+ png_error(png_ptr, "unknown interlace type");
+ }
+
+ {
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ int proc = display->colormap_processing;
+ png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+ ptrdiff_t step_row = display->row_bytes;
+ int pass;
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass);
+ stepx = PNG_PASS_COL_OFFSET(pass);
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = stepy = 1;
+ }
+
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep, display->local_row);
+ png_bytep outrow = first_row + y * step_row;
+ png_const_bytep end_row = outrow + width;
+
+ /* Read read the libpng data into the temporary buffer. */
+ png_read_row(png_ptr, inrow, NULL);
+
+ /* Now process the row according to the processing option, note
+ * that the caller verifies that the format of the libpng output
+ * data is as required.
+ */
+ outrow += startx;
+ switch (proc)
+ {
+ case PNG_CMAP_GA:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ /* The data is always in the PNG order */
+ unsigned int gray = *inrow++;
+ unsigned int alpha = *inrow++;
+ unsigned int entry;
+
+ /* NOTE: this code is copied as a comment in
+ * make_ga_colormap above. Please update the
+ * comment if you change this code!
+ */
+ if (alpha > 229) /* opaque */
+ {
+ entry = (231 * gray + 128) >> 8;
+ }
+ else if (alpha < 26) /* transparent */
+ {
+ entry = 231;
+ }
+ else /* partially opaque */
+ {
+ entry = 226 + 6 * PNG_DIV51(alpha) + PNG_DIV51(gray);
+ }
+
+ *outrow = (png_byte)entry;
+ }
+ break;
+
+ case PNG_CMAP_TRANS:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte gray = *inrow++;
+ png_byte alpha = *inrow++;
+
+ if (alpha == 0)
+ *outrow = PNG_CMAP_TRANS_BACKGROUND;
+
+ else if (gray != PNG_CMAP_TRANS_BACKGROUND)
+ *outrow = gray;
+
+ else
+ *outrow = (png_byte)(PNG_CMAP_TRANS_BACKGROUND+1);
+ }
+ break;
+
+ case PNG_CMAP_RGB:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1], inrow[2]);
+ inrow += 3;
+ }
+ break;
+
+ case PNG_CMAP_RGB_ALPHA:
+ for (; outrow < end_row; outrow += stepx)
+ {
+ unsigned int alpha = inrow[3];
+
+ /* Because the alpha entries only hold alpha==0.5 values
+ * split the processing at alpha==0.25 (64) and 0.75
+ * (196).
+ */
+
+ if (alpha >= 196)
+ *outrow = PNG_RGB_INDEX(inrow[0], inrow[1],
+ inrow[2]);
+
+ else if (alpha < 64)
+ *outrow = PNG_CMAP_RGB_ALPHA_BACKGROUND;
+
+ else
+ {
+ /* Likewise there are three entries for each of r, g
+ * and b. We could select the entry by popcount on
+ * the top two bits on those architectures that
+ * support it, this is what the code below does,
+ * crudely.
+ */
+ unsigned int back_i = PNG_CMAP_RGB_ALPHA_BACKGROUND+1;
+
+ /* Here are how the values map:
+ *
+ * 0x00 .. 0x3f -> 0
+ * 0x40 .. 0xbf -> 1
+ * 0xc0 .. 0xff -> 2
+ *
+ * So, as above with the explicit alpha checks, the
+ * breakpoints are at 64 and 196.
+ */
+ if (inrow[0] & 0x80) back_i += 9; /* red */
+ if (inrow[0] & 0x40) back_i += 9;
+ if (inrow[0] & 0x80) back_i += 3; /* green */
+ if (inrow[0] & 0x40) back_i += 3;
+ if (inrow[0] & 0x80) back_i += 1; /* blue */
+ if (inrow[0] & 0x40) back_i += 1;
+
+ *outrow = (png_byte)back_i;
+ }
+
+ inrow += 4;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+static int
+png_image_read_colormapped(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_controlp control = image->opaque;
+ png_structrp png_ptr = control->png_ptr;
+ png_inforp info_ptr = control->info_ptr;
+
+ int passes = 0; /* As a flag */
+
+ PNG_SKIP_CHUNKS(png_ptr);
+
+ /* Update the 'info' structure and make sure the result is as required; first
+ * make sure to turn on the interlace handling if it will be required
+ * (because it can't be turned on *after* the call to png_read_update_info!)
+ */
+ if (display->colormap_processing == PNG_CMAP_NONE)
+ passes = png_set_interlace_handling(png_ptr);
+
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* The expected output can be deduced from the colormap_processing option. */
+ switch (display->colormap_processing)
+ {
+ case PNG_CMAP_NONE:
+ /* Output must be one channel and one byte per pixel, the output
+ * encoding can be anything.
+ */
+ if ((info_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+ info_ptr->color_type == PNG_COLOR_TYPE_GRAY) &&
+ info_ptr->bit_depth == 8)
+ break;
+
+ goto bad_output;
+
+ case PNG_CMAP_TRANS:
+ case PNG_CMAP_GA:
+ /* Output must be two channels and the 'G' one must be sRGB, the latter
+ * can be checked with an exact number because it should have been set
+ * to this number above!
+ */
+ if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ info_ptr->bit_depth == 8 &&
+ png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+ image->colormap_entries == 256)
+ break;
+
+ goto bad_output;
+
+ case PNG_CMAP_RGB:
+ /* Output must be 8-bit sRGB encoded RGB */
+ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+ info_ptr->bit_depth == 8 &&
+ png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+ image->colormap_entries == 216)
+ break;
+
+ goto bad_output;
+
+ case PNG_CMAP_RGB_ALPHA:
+ /* Output must be 8-bit sRGB encoded RGBA */
+ if (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ info_ptr->bit_depth == 8 &&
+ png_ptr->screen_gamma == PNG_GAMMA_sRGB &&
+ image->colormap_entries == 244 /* 216 + 1 + 27 */)
+ break;
+
+ /* goto bad_output; */
+ /* FALL THROUGH */
+
+ default:
+ bad_output:
+ png_error(png_ptr, "bad color-map processing (internal error)");
+ }
+
+ /* Now read the rows. Do this here if it is possible to read directly into
+ * the output buffer, otherwise allocate a local row buffer of the maximum
+ * size libpng requires and call the relevant processing routine safely.
+ */
+ {
+ png_voidp first_row = display->buffer;
+ ptrdiff_t row_bytes = display->row_stride;
+
+ /* The following expression is designed to work correctly whether it gives
+ * a signed or an unsigned result.
+ */
+ if (row_bytes < 0)
+ {
+ char *ptr = png_voidcast(char*, first_row);
+ ptr += (image->height-1) * (-row_bytes);
+ first_row = png_voidcast(png_voidp, ptr);
+ }
+
+ display->first_row = first_row;
+ display->row_bytes = row_bytes;
+ }
+
+ if (passes == 0)
+ {
+ int result;
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+ display->local_row = row;
+ result = png_safe_execute(image, png_image_read_and_map, display);
+ display->local_row = NULL;
+ png_free(png_ptr, row);
+
+ return result;
+ }
+
+ else
+ {
+ png_alloc_size_t row_bytes = display->row_bytes;
+
+ while (--passes >= 0)
+ {
+ png_uint_32 y = image->height;
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
+
+ while (y-- > 0)
+ {
+ png_read_row(png_ptr, row, NULL);
+ row += row_bytes;
+ }
+ }
+
+ return 1;
+ }
+}
+
+/* Just the row reading part of png_image_read. */
+static int
+png_image_read_composite(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ int passes;
+
+ switch (png_ptr->interlaced)
+ {
+ case PNG_INTERLACE_NONE:
+ passes = 1;
+ break;
+
+ case PNG_INTERLACE_ADAM7:
+ passes = PNG_INTERLACE_ADAM7_PASSES;
+ break;
+
+ default:
+ passes = 0;
+ png_error(png_ptr, "unknown interlace type");
+ }
+
+ {
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ ptrdiff_t step_row = display->row_bytes;
+ unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
+ int pass;
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass) * channels;
+ stepx = PNG_PASS_COL_OFFSET(pass) * channels;
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = channels;
+ stepy = 1;
+ }
+
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep, display->local_row);
+ png_bytep outrow;
+ png_const_bytep end_row;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, inrow, NULL);
+
+ outrow = png_voidcast(png_bytep, display->first_row);
+ outrow += y * step_row;
+ end_row = outrow + width * channels;
+
+ /* Now do the composition on each pixel in this row. */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte alpha = inrow[channels];
+
+ if (alpha > 0) /* else no change to the output */
+ {
+ unsigned int c;
+
+ for (c=0; c<channels; ++c)
+ {
+ png_uint_32 component = inrow[c];
+
+ if (alpha < 255) /* else just use component */
+ {
+ /* This is PNG_OPTIMIZED_ALPHA, the component value
+ * is a linear 8-bit value. Combine this with the
+ * current outrow[c] value which is sRGB encoded.
+ * Arithmetic here is 16-bits to preserve the output
+ * values correctly.
+ */
+ component *= 257*255; /* =65535 */
+ component += (255-alpha)*png_sRGB_table[outrow[c]];
+
+ /* So 'component' is scaled by 255*65535 and is
+ * therefore appropriate for the sRGB to linear
+ * conversion table.
+ */
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ outrow[c] = (png_byte)component;
+ }
+ }
+
+ inrow += channels+1; /* components and alpha channel */
+ }
+ }
+ }
+ }
+
+ return 1;
+}
+
+/* The do_local_background case; called when all the following transforms are to
+ * be done:
+ *
+ * PNG_RGB_TO_GRAY
+ * PNG_COMPOSITE
+ * PNG_GAMMA
+ *
+ * This is a work-round for the fact that both the PNG_RGB_TO_GRAY and
+ * PNG_COMPOSITE code performs gamma correction, so we get double gamma
+ * correction. The fix-up is to prevent the PNG_COMPOSITE operation happening
+ * inside libpng, so this routine sees an 8 or 16-bit gray+alpha row and handles
+ * the removal or pre-multiplication of the alpha channel.
+ */
+static int
+png_image_read_background(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+ png_uint_32 height = image->height;
+ png_uint_32 width = image->width;
+ int pass, passes;
+
+ /* Double check the convoluted logic below. We expect to get here with
+ * libpng doing rgb to gray and gamma correction but background processing
+ * left to the png_image_read_background function. The rows libpng produce
+ * might be 8 or 16-bit but should always have two channels; gray plus alpha.
+ */
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
+ png_error(png_ptr, "lost rgb to gray");
+
+ if ((png_ptr->transformations & PNG_COMPOSE) != 0)
+ png_error(png_ptr, "unexpected compose");
+
+ if (png_get_channels(png_ptr, info_ptr) != 2)
+ png_error(png_ptr, "lost/gained channels");
+
+ /* Expect the 8-bit case to always remove the alpha channel */
+ if ((image->format & PNG_FORMAT_FLAG_LINEAR) == 0 &&
+ (image->format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ png_error(png_ptr, "unexpected 8-bit transformation");
+
+ switch (png_ptr->interlaced)
+ {
+ case PNG_INTERLACE_NONE:
+ passes = 1;
+ break;
+
+ case PNG_INTERLACE_ADAM7:
+ passes = PNG_INTERLACE_ADAM7_PASSES;
+ break;
+
+ default:
+ passes = 0;
+ png_error(png_ptr, "unknown interlace type");
+ }
+
+ switch (png_get_bit_depth(png_ptr, info_ptr))
+ {
+ default:
+ png_error(png_ptr, "unexpected bit depth");
+ break;
+
+ case 8:
+ /* 8-bit sRGB gray values with an alpha channel; the alpha channel is
+ * to be removed by composing on a backgroundi: either the row if
+ * display->background is NULL or display->background->green if not.
+ * Unlike the code above ALPHA_OPTIMIZED has *not* been done.
+ */
+ {
+ png_bytep first_row = png_voidcast(png_bytep, display->first_row);
+ ptrdiff_t step_row = display->row_bytes;
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ png_bytep row = png_voidcast(png_bytep,
+ display->first_row);
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass);
+ stepx = PNG_PASS_COL_OFFSET(pass);
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = stepy = 1;
+ }
+
+ if (display->background == NULL)
+ {
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep,
+ display->local_row);
+ png_bytep outrow = first_row + y * step_row;
+ png_const_bytep end_row = outrow + width;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, inrow, NULL);
+
+ /* Now do the composition on each pixel in this row. */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte alpha = inrow[1];
+
+ if (alpha > 0) /* else no change to the output */
+ {
+ png_uint_32 component = inrow[0];
+
+ if (alpha < 255) /* else just use component */
+ {
+ /* Since PNG_OPTIMIZED_ALPHA was not set it is
+ * necessary to invert the sRGB transfer
+ * function and multiply the alpha out.
+ */
+ component = png_sRGB_table[component] * alpha;
+ component += png_sRGB_table[outrow[0]] *
+ (255-alpha);
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ outrow[0] = (png_byte)component;
+ }
+
+ inrow += 2; /* gray and alpha channel */
+ }
+ }
+ }
+
+ else /* constant background value */
+ {
+ png_byte background8 = display->background->green;
+ png_uint_16 background = png_sRGB_table[background8];
+
+ for (; y<height; y += stepy)
+ {
+ png_bytep inrow = png_voidcast(png_bytep,
+ display->local_row);
+ png_bytep outrow = first_row + y * step_row;
+ png_const_bytep end_row = outrow + width;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, inrow, NULL);
+
+ /* Now do the composition on each pixel in this row. */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_byte alpha = inrow[1];
+
+ if (alpha > 0) /* else use background */
+ {
+ png_uint_32 component = inrow[0];
+
+ if (alpha < 255) /* else just use component */
+ {
+ component = png_sRGB_table[component] * alpha;
+ component += background * (255-alpha);
+ component = PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ outrow[0] = (png_byte)component;
+ }
+
+ else
+ outrow[0] = background8;
+
+ inrow += 2; /* gray and alpha channel */
+ }
+
+ row += display->row_bytes;
+ }
+ }
+ }
+ }
+ break;
+
+ case 16:
+ /* 16-bit linear with pre-multiplied alpha; the pre-multiplication must
+ * still be done and, maybe, the alpha channel removed. This code also
+ * handles the alpha-first option.
+ */
+ {
+ png_uint_16p first_row = png_voidcast(png_uint_16p,
+ display->first_row);
+ /* The division by two is safe because the caller passed in a
+ * stride which was multiplied by 2 (below) to get row_bytes.
+ */
+ ptrdiff_t step_row = display->row_bytes / 2;
+ int preserve_alpha = (image->format & PNG_FORMAT_FLAG_ALPHA) != 0;
+ unsigned int outchannels = 1+preserve_alpha;
+ int swap_alpha = 0;
+
+ if (preserve_alpha && (image->format & PNG_FORMAT_FLAG_AFIRST))
+ swap_alpha = 1;
+
+ for (pass = 0; pass < passes; ++pass)
+ {
+ unsigned int startx, stepx, stepy;
+ png_uint_32 y;
+
+ /* The 'x' start and step are adjusted to output components here.
+ */
+ if (png_ptr->interlaced == PNG_INTERLACE_ADAM7)
+ {
+ /* The row may be empty for a short image: */
+ if (PNG_PASS_COLS(width, pass) == 0)
+ continue;
+
+ startx = PNG_PASS_START_COL(pass) * outchannels;
+ stepx = PNG_PASS_COL_OFFSET(pass) * outchannels;
+ y = PNG_PASS_START_ROW(pass);
+ stepy = PNG_PASS_ROW_OFFSET(pass);
+ }
+
+ else
+ {
+ y = 0;
+ startx = 0;
+ stepx = outchannels;
+ stepy = 1;
+ }
+
+ for (; y<height; y += stepy)
+ {
+ png_const_uint_16p inrow;
+ png_uint_16p outrow = first_row + y*step_row;
+ png_uint_16p end_row = outrow + width * outchannels;
+
+ /* Read the row, which is packed: */
+ png_read_row(png_ptr, png_voidcast(png_bytep,
+ display->local_row), NULL);
+ inrow = png_voidcast(png_const_uint_16p, display->local_row);
+
+ /* Now do the pre-multiplication on each pixel in this row.
+ */
+ outrow += startx;
+ for (; outrow < end_row; outrow += stepx)
+ {
+ png_uint_32 component = inrow[0];
+ png_uint_16 alpha = inrow[1];
+
+ if (alpha > 0) /* else 0 */
+ {
+ if (alpha < 65535) /* else just use component */
+ {
+ component *= alpha;
+ component += 32767;
+ component /= 65535;
+ }
+ }
+
+ else
+ component = 0;
+
+ outrow[swap_alpha] = (png_uint_16)component;
+ if (preserve_alpha)
+ outrow[1 ^ swap_alpha] = alpha;
+
+ inrow += 2; /* components and alpha channel */
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ return 1;
+}
+
+/* The guts of png_image_finish_read as a png_safe_execute callback. */
+static int
+png_image_read_direct(png_voidp argument)
+{
+ png_image_read_control *display = png_voidcast(png_image_read_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+
+ png_uint_32 format = image->format;
+ int linear = (format & PNG_FORMAT_FLAG_LINEAR) != 0;
+ int do_local_compose = 0;
+ int do_local_background = 0; /* to avoid double gamma correction bug */
+ int passes = 0;
+
+ /* Add transforms to ensure the correct output format is produced then check
+ * that the required implementation support is there. Always expand; always
+ * need 8 bits minimum, no palette and expanded tRNS.
+ */
+ png_set_expand(png_ptr);
+
+ /* Now check the format to see if it was modified. */
+ {
+ png_uint_32 base_format = png_image_format(png_ptr) &
+ ~PNG_FORMAT_FLAG_COLORMAP /* removed by png_set_expand */;
+ png_uint_32 change = format ^ base_format;
+ png_fixed_point output_gamma;
+ int mode; /* alpha mode */
+
+ /* Do this first so that we have a record if rgb to gray is happening. */
+ if (change & PNG_FORMAT_FLAG_COLOR)
+ {
+ /* gray<->color transformation required. */
+ if (format & PNG_FORMAT_FLAG_COLOR)
+ png_set_gray_to_rgb(png_ptr);
+
+ else
+ {
+ /* libpng can't do both rgb to gray and
+ * background/pre-multiplication if there is also significant gamma
+ * correction, because both operations require linear colors and
+ * the code only supports one transform doing the gamma correction.
+ * Handle this by doing the pre-multiplication or background
+ * operation in this code, if necessary.
+ *
+ * TODO: fix this by rewriting pngrtran.c (!)
+ *
+ * For the moment (given that fixing this in pngrtran.c is an
+ * enormous change) 'do_local_background' is used to indicate that
+ * the problem exists.
+ */
+ if (base_format & PNG_FORMAT_FLAG_ALPHA)
+ do_local_background = 1/*maybe*/;
+
+ png_set_rgb_to_gray_fixed(png_ptr, PNG_ERROR_ACTION_NONE,
+ PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT);
+ }
+
+ change &= ~PNG_FORMAT_FLAG_COLOR;
+ }
+
+ /* Set the gamma appropriately, linear for 16-bit input, sRGB otherwise.
+ */
+ {
+ png_fixed_point input_gamma_default;
+
+ if ((base_format & PNG_FORMAT_FLAG_LINEAR) &&
+ (image->flags & PNG_IMAGE_FLAG_16BIT_sRGB) == 0)
+ input_gamma_default = PNG_GAMMA_LINEAR;
+ else
+ input_gamma_default = PNG_DEFAULT_sRGB;
+
+ /* Call png_set_alpha_mode to set the default for the input gamma; the
+ * output gamma is set by a second call below.
+ */
+ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, input_gamma_default);
+ }
+
+ if (linear)
+ {
+ /* If there *is* an alpha channel in the input it must be multiplied
+ * out; use PNG_ALPHA_STANDARD, otherwise just use PNG_ALPHA_PNG.
+ */
+ if (base_format & PNG_FORMAT_FLAG_ALPHA)
+ mode = PNG_ALPHA_STANDARD; /* associated alpha */
+
+ else
+ mode = PNG_ALPHA_PNG;
+
+ output_gamma = PNG_GAMMA_LINEAR;
+ }
+
+ else
+ {
+ mode = PNG_ALPHA_PNG;
+ output_gamma = PNG_DEFAULT_sRGB;
+ }
+
+ /* If 'do_local_background' is set check for the presence of gamma
+ * correction; this is part of the work-round for the libpng bug
+ * described above.
+ *
+ * TODO: fix libpng and remove this.
+ */
+ if (do_local_background)
+ {
+ png_fixed_point gtest;
+
+ /* This is 'png_gamma_threshold' from pngrtran.c; the test used for
+ * gamma correction, the screen gamma hasn't been set on png_struct
+ * yet; it's set below. png_struct::gamma, however, is set to the
+ * final value.
+ */
+ if (png_muldiv(&gtest, output_gamma, png_ptr->colorspace.gamma,
+ PNG_FP_1) && !png_gamma_significant(gtest))
+ do_local_background = 0;
+
+ else if (mode == PNG_ALPHA_STANDARD)
+ {
+ do_local_background = 2/*required*/;
+ mode = PNG_ALPHA_PNG; /* prevent libpng doing it */
+ }
+
+ /* else leave as 1 for the checks below */
+ }
+
+ /* If the bit-depth changes then handle that here. */
+ if (change & PNG_FORMAT_FLAG_LINEAR)
+ {
+ if (linear /*16-bit output*/)
+ png_set_expand_16(png_ptr);
+
+ else /* 8-bit output */
+ png_set_scale_16(png_ptr);
+
+ change &= ~PNG_FORMAT_FLAG_LINEAR;
+ }
+
+ /* Now the background/alpha channel changes. */
+ if (change & PNG_FORMAT_FLAG_ALPHA)
+ {
+ /* Removing an alpha channel requires composition for the 8-bit
+ * formats; for the 16-bit it is already done, above, by the
+ * pre-multiplication and the channel just needs to be stripped.
+ */
+ if (base_format & PNG_FORMAT_FLAG_ALPHA)
+ {
+ /* If RGB->gray is happening the alpha channel must be left and the
+ * operation completed locally.
+ *
+ * TODO: fix libpng and remove this.
+ */
+ if (do_local_background)
+ do_local_background = 2/*required*/;
+
+ /* 16-bit output: just remove the channel */
+ else if (linear) /* compose on black (well, pre-multiply) */
+ png_set_strip_alpha(png_ptr);
+
+ /* 8-bit output: do an appropriate compose */
+ else if (display->background != NULL)
+ {
+ png_color_16 c;
+
+ c.index = 0; /*unused*/
+ c.red = display->background->red;
+ c.green = display->background->green;
+ c.blue = display->background->blue;
+ c.gray = display->background->green;
+
+ /* This is always an 8-bit sRGB value, using the 'green' channel
+ * for gray is much better than calculating the luminance here;
+ * we can get off-by-one errors in that calculation relative to
+ * the app expectations and that will show up in transparent
+ * pixels.
+ */
+ png_set_background_fixed(png_ptr, &c,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0/*need_expand*/,
+ 0/*gamma: not used*/);
+ }
+
+ else /* compose on row: implemented below. */
+ {
+ do_local_compose = 1;
+ /* This leaves the alpha channel in the output, so it has to be
+ * removed by the code below. Set the encoding to the 'OPTIMIZE'
+ * one so the code only has to hack on the pixels that require
+ * composition.
+ */
+ mode = PNG_ALPHA_OPTIMIZED;
+ }
+ }
+
+ else /* output needs an alpha channel */
+ {
+ /* This is tricky because it happens before the swap operation has
+ * been accomplished; however, the swap does *not* swap the added
+ * alpha channel (weird API), so it must be added in the correct
+ * place.
+ */
+ png_uint_32 filler; /* opaque filler */
+ int where;
+
+ if (linear)
+ filler = 65535;
+
+ else
+ filler = 255;
+
+# ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if (format & PNG_FORMAT_FLAG_AFIRST)
+ {
+ where = PNG_FILLER_BEFORE;
+ change &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
+
+ else
+# endif
+ where = PNG_FILLER_AFTER;
+
+ png_set_add_alpha(png_ptr, filler, where);
+ }
+
+ /* This stops the (irrelevant) call to swap_alpha below. */
+ change &= ~PNG_FORMAT_FLAG_ALPHA;
+ }
+
+ /* Now set the alpha mode correctly; this is always done, even if there is
+ * no alpha channel in either the input or the output because it correctly
+ * sets the output gamma.
+ */
+ png_set_alpha_mode_fixed(png_ptr, mode, output_gamma);
+
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ if (change & PNG_FORMAT_FLAG_BGR)
+ {
+ /* Check only the output format; PNG is never BGR; don't do this if
+ * the output is gray, but fix up the 'format' value in that case.
+ */
+ if (format & PNG_FORMAT_FLAG_COLOR)
+ png_set_bgr(png_ptr);
+
+ else
+ format &= ~PNG_FORMAT_FLAG_BGR;
+
+ change &= ~PNG_FORMAT_FLAG_BGR;
+ }
+# endif
+
+# ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if (change & PNG_FORMAT_FLAG_AFIRST)
+ {
+ /* Only relevant if there is an alpha channel - it's particularly
+ * important to handle this correctly because do_local_compose may
+ * be set above and then libpng will keep the alpha channel for this
+ * code to remove.
+ */
+ if (format & PNG_FORMAT_FLAG_ALPHA)
+ {
+ /* Disable this if doing a local background,
+ * TODO: remove this when local background is no longer required.
+ */
+ if (do_local_background != 2)
+ png_set_swap_alpha(png_ptr);
+ }
+
+ else
+ format &= ~PNG_FORMAT_FLAG_AFIRST;
+
+ change &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
+# endif
+
+ /* If the *output* is 16-bit then we need to check for a byte-swap on this
+ * architecture.
+ */
+ if (linear)
+ {
+ PNG_CONST png_uint_16 le = 0x0001;
+
+ if (*(png_const_bytep)&le)
+ png_set_swap(png_ptr);
+ }
+
+ /* If change is not now 0 some transformation is missing - error out. */
+ if (change)
+ png_error(png_ptr, "png_read_image: unsupported transformation");
+ }
+
+ PNG_SKIP_CHUNKS(png_ptr);
+
+ /* Update the 'info' structure and make sure the result is as required; first
+ * make sure to turn on the interlace handling if it will be required
+ * (because it can't be turned on *after* the call to png_read_update_info!)
+ *
+ * TODO: remove the do_local_background fixup below.
+ */
+ if (!do_local_compose && do_local_background != 2)
+ passes = png_set_interlace_handling(png_ptr);
+
+ png_read_update_info(png_ptr, info_ptr);
+
+ {
+ png_uint_32 info_format = 0;
+
+ if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_format |= PNG_FORMAT_FLAG_COLOR;
+
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ /* do_local_compose removes this channel below. */
+ if (!do_local_compose)
+ {
+ /* do_local_background does the same if required. */
+ if (do_local_background != 2 ||
+ (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ info_format |= PNG_FORMAT_FLAG_ALPHA;
+ }
+ }
+
+ else if (do_local_compose) /* internal error */
+ png_error(png_ptr, "png_image_read: alpha channel lost");
+
+ if (info_ptr->bit_depth == 16)
+ info_format |= PNG_FORMAT_FLAG_LINEAR;
+
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ info_format |= PNG_FORMAT_FLAG_BGR;
+# endif
+
+# ifdef PNG_FORMAT_AFIRST_SUPPORTED
+ if (do_local_background == 2)
+ {
+ if (format & PNG_FORMAT_FLAG_AFIRST)
+ info_format |= PNG_FORMAT_FLAG_AFIRST;
+ }
+
+ if ((png_ptr->transformations & PNG_SWAP_ALPHA) != 0 ||
+ ((png_ptr->transformations & PNG_ADD_ALPHA) != 0 &&
+ (png_ptr->flags & PNG_FLAG_FILLER_AFTER) == 0))
+ {
+ if (do_local_background == 2)
+ png_error(png_ptr, "unexpected alpha swap transformation");
+
+ info_format |= PNG_FORMAT_FLAG_AFIRST;
+ }
+# endif
+
+ /* This is actually an internal error. */
+ if (info_format != format)
+ png_error(png_ptr, "png_read_image: invalid transformations");
+ }
+
+ /* Now read the rows. If do_local_compose is set then it is necessary to use
+ * a local row buffer. The output will be GA, RGBA or BGRA and must be
+ * converted to G, RGB or BGR as appropriate. The 'local_row' member of the
+ * display acts as a flag.
+ */
+ {
+ png_voidp first_row = display->buffer;
+ ptrdiff_t row_bytes = display->row_stride;
+
+ if (linear)
+ row_bytes *= 2;
+
+ /* The following expression is designed to work correctly whether it gives
+ * a signed or an unsigned result.
+ */
+ if (row_bytes < 0)
+ {
+ char *ptr = png_voidcast(char*, first_row);
+ ptr += (image->height-1) * (-row_bytes);
+ first_row = png_voidcast(png_voidp, ptr);
+ }
+
+ display->first_row = first_row;
+ display->row_bytes = row_bytes;
+ }
+
+ if (do_local_compose)
+ {
+ int result;
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+ display->local_row = row;
+ result = png_safe_execute(image, png_image_read_composite, display);
+ display->local_row = NULL;
+ png_free(png_ptr, row);
+
+ return result;
+ }
+
+ else if (do_local_background == 2)
+ {
+ int result;
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+
+ display->local_row = row;
+ result = png_safe_execute(image, png_image_read_background, display);
+ display->local_row = NULL;
+ png_free(png_ptr, row);
+
+ return result;
+ }
+
+ else
+ {
+ png_alloc_size_t row_bytes = display->row_bytes;
+
+ while (--passes >= 0)
+ {
+ png_uint_32 y = image->height;
+ png_bytep row = png_voidcast(png_bytep, display->first_row);
+
+ while (y-- > 0)
+ {
+ png_read_row(png_ptr, row, NULL);
+ row += row_bytes;
+ }
+ }
+
+ return 1;
+ }
+}
+
+int PNGAPI
+png_image_finish_read(png_imagep image, png_const_colorp background,
+ void *buffer, png_int_32 row_stride, void *colormap)
+{
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ png_uint_32 check;
+
+ if (row_stride == 0)
+ row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+
+ if (row_stride < 0)
+ check = -row_stride;
+
+ else
+ check = row_stride;
+
+ if (image->opaque != NULL && buffer != NULL &&
+ check >= PNG_IMAGE_ROW_STRIDE(*image))
+ {
+ if ((image->format & PNG_FORMAT_FLAG_COLORMAP) == 0 ||
+ (image->colormap_entries > 0 && colormap != NULL))
+ {
+ int result;
+ png_image_read_control display;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.background = background;
+ display.local_row = NULL;
+
+ /* Choose the correct 'end' routine; for the color-map case all the
+ * setup has already been done.
+ */
+ if (image->format & PNG_FORMAT_FLAG_COLORMAP)
+ result =
+ png_safe_execute(image, png_image_read_colormap, &display) &&
+ png_safe_execute(image, png_image_read_colormapped, &display);
+
+ else
+ result =
+ png_safe_execute(image, png_image_read_direct, &display);
+
+ png_image_free(image);
+ return result;
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_finish_read[color-map]: no color-map");
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_finish_read: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_finish_read: damaged PNG_IMAGE_VERSION");
+
+ return 0;
+}
+
+#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrio.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrio.c
new file mode 100644
index 0000000000..5f927d127b
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrio.c
@@ -0,0 +1,119 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngrio.c - functions for data input
+ *
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all input. Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method. Note that you shouldn't change this
+ * function, but rather write a replacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Read the data from whatever input you are using. The default routine
+ * reads from a file pointer. Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered reads. This should never be asked
+ * to read more then 64K on a 16 bit machine.
+ */
+void /* PRIVATE */
+png_read_data(png_structrp png_ptr, png_bytep data, png_size_t length)
+{
+ png_debug1(4, "reading %d bytes", (int)length);
+
+ if (png_ptr->read_data_fn != NULL)
+ (*(png_ptr->read_data_fn))(png_ptr, data, length);
+
+ else
+ png_error(png_ptr, "Call to NULL read function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual reading of data. If you are
+ * not reading from a standard C stream, you should create a replacement
+ * read_data function and use it at run time with png_set_read_fn(), rather
+ * than changing the library.
+ */
+void PNGCBAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ if (png_ptr == NULL)
+ return;
+
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+ check = fread(data, 1, length, png_voidcast(png_FILE_p, png_ptr->io_ptr));
+
+ if (check != length)
+ png_error(png_ptr, "Read Error");
+}
+#endif
+
+/* This function allows the application to supply a new input function
+ * for libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ *
+ * png_ptr - pointer to a png input data structure
+ *
+ * io_ptr - pointer to user supplied structure containing info about
+ * the input functions. May be NULL.
+ *
+ * read_data_fn - pointer to a new input function that takes as its
+ * arguments a pointer to a png_struct, a pointer to
+ * a location where input data can be stored, and a 32-bit
+ * unsigned int that is the number of bytes to be read.
+ * To exit and output any fatal error messages the new write
+ * function should call png_error(png_ptr, "Error msg").
+ * May be NULL, in which case libpng's default function will
+ * be used.
+ */
+void PNGAPI
+png_set_read_fn(png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+ if (read_data_fn != NULL)
+ png_ptr->read_data_fn = read_data_fn;
+
+ else
+ png_ptr->read_data_fn = png_default_read_data;
+#else
+ png_ptr->read_data_fn = read_data_fn;
+#endif
+
+ /* It is an error to write to a read device */
+ if (png_ptr->write_data_fn != NULL)
+ {
+ png_ptr->write_data_fn = NULL;
+ png_warning(png_ptr,
+ "Can't set both read_data_fn and write_data_fn in the"
+ " same structure");
+ }
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_ptr->output_flush_fn = NULL;
+#endif
+}
+#endif /* PNG_READ_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrtran.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrtran.c
new file mode 100644
index 0000000000..4a279be3ff
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrtran.c
@@ -0,0 +1,5104 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action)
+{
+ png_debug(1, "in png_set_crc_action");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* Tell libpng how we react to CRC errors in critical chunks */
+ switch (crit_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* Leave setting as is */
+ break;
+
+ case PNG_CRC_WARN_USE: /* Warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+ break;
+
+ case PNG_CRC_QUIET_USE: /* Quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+ PNG_FLAG_CRC_CRITICAL_IGNORE;
+ break;
+
+ case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */
+ png_warning(png_ptr,
+ "Can't discard critical data on CRC error");
+ case PNG_CRC_ERROR_QUIT: /* Error/quit */
+
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ break;
+ }
+
+ /* Tell libpng how we react to CRC errors in ancillary chunks */
+ switch (ancil_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* Leave setting as is */
+ break;
+
+ case PNG_CRC_WARN_USE: /* Warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+ break;
+
+ case PNG_CRC_QUIET_USE: /* Quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+ PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+
+ case PNG_CRC_ERROR_QUIT: /* Error/quit */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+
+ case PNG_CRC_WARN_DISCARD: /* Warn/discard data */
+
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ break;
+ }
+}
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+/* Is it OK to set a transformation now? Only if png_start_read_image or
+ * png_read_update_info have not been called. It is not necessary for the IHDR
+ * to have been read in all cases, the parameter allows for this check too.
+ */
+static int
+png_rtran_ok(png_structrp png_ptr, int need_IHDR)
+{
+ if (png_ptr != NULL)
+ {
+ if (png_ptr->flags & PNG_FLAG_ROW_INIT)
+ png_app_error(png_ptr,
+ "invalid after png_start_read_image or png_read_update_info");
+
+ else if (need_IHDR && (png_ptr->mode & PNG_HAVE_IHDR) == 0)
+ png_app_error(png_ptr, "invalid before the PNG header has been read");
+
+ else
+ {
+ /* Turn on failure to initialize correctly for all transforms. */
+ png_ptr->flags |= PNG_FLAG_DETECT_UNINITIALIZED;
+
+ return 1; /* Ok */
+ }
+ }
+
+ return 0; /* no png_error possible! */
+}
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS via a background color */
+void PNGFAPI
+png_set_background_fixed(png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, png_fixed_point background_gamma)
+{
+ png_debug(1, "in png_set_background_fixed");
+
+ if (!png_rtran_ok(png_ptr, 0) || background_color == NULL)
+ return;
+
+ if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+ {
+ png_warning(png_ptr, "Application must supply a known background gamma");
+ return;
+ }
+
+ png_ptr->transformations |= PNG_COMPOSE | PNG_STRIP_ALPHA;
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+ png_ptr->background = *background_color;
+ png_ptr->background_gamma = background_gamma;
+ png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+ if (need_expand)
+ png_ptr->transformations |= PNG_BACKGROUND_EXPAND;
+ else
+ png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_background(png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma)
+{
+ png_set_background_fixed(png_ptr, background_color, background_gamma_code,
+ need_expand, png_fixed(png_ptr, background_gamma, "png_set_background"));
+}
+# endif /* FLOATING_POINT */
+#endif /* READ_BACKGROUND */
+
+/* Scale 16-bit depth files to 8-bit depth. If both of these are set then the
+ * one that pngrtran does first (scale) happens. This is necessary to allow the
+ * TRANSFORM and API behavior to be somewhat consistent, and it's simpler.
+ */
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+void PNGAPI
+png_set_scale_16(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_scale_16");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= PNG_SCALE_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+/* Chop 16-bit depth files to 8-bit depth */
+void PNGAPI
+png_set_strip_16(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_strip_16");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+void PNGAPI
+png_set_strip_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_strip_alpha");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= PNG_STRIP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_ALPHA_MODE_SUPPORTED) || defined(PNG_READ_GAMMA_SUPPORTED)
+static png_fixed_point
+translate_gamma_flags(png_structrp png_ptr, png_fixed_point output_gamma,
+ int is_screen)
+{
+ /* Check for flag values. The main reason for having the old Mac value as a
+ * flag is that it is pretty near impossible to work out what the correct
+ * value is from Apple documentation - a working Mac system is needed to
+ * discover the value!
+ */
+ if (output_gamma == PNG_DEFAULT_sRGB ||
+ output_gamma == PNG_FP_1 / PNG_DEFAULT_sRGB)
+ {
+ /* If there is no sRGB support this just sets the gamma to the standard
+ * sRGB value. (This is a side effect of using this function!)
+ */
+# ifdef PNG_READ_sRGB_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_ASSUME_sRGB;
+# else
+ PNG_UNUSED(png_ptr)
+# endif
+ if (is_screen)
+ output_gamma = PNG_GAMMA_sRGB;
+ else
+ output_gamma = PNG_GAMMA_sRGB_INVERSE;
+ }
+
+ else if (output_gamma == PNG_GAMMA_MAC_18 ||
+ output_gamma == PNG_FP_1 / PNG_GAMMA_MAC_18)
+ {
+ if (is_screen)
+ output_gamma = PNG_GAMMA_MAC_OLD;
+ else
+ output_gamma = PNG_GAMMA_MAC_INVERSE;
+ }
+
+ return output_gamma;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+static png_fixed_point
+convert_gamma_value(png_structrp png_ptr, double output_gamma)
+{
+ /* The following silently ignores cases where fixed point (times 100,000)
+ * gamma values are passed to the floating point API. This is safe and it
+ * means the fixed point constants work just fine with the floating point
+ * API. The alternative would just lead to undetected errors and spurious
+ * bug reports. Negative values fail inside the _fixed API unless they
+ * correspond to the flag values.
+ */
+ if (output_gamma > 0 && output_gamma < 128)
+ output_gamma *= PNG_FP_1;
+
+ /* This preserves -1 and -2 exactly: */
+ output_gamma = floor(output_gamma + .5);
+
+ if (output_gamma > PNG_FP_MAX || output_gamma < PNG_FP_MIN)
+ png_fixed_error(png_ptr, "gamma value");
+
+ return (png_fixed_point)output_gamma;
+}
+# endif
+#endif /* READ_ALPHA_MODE || READ_GAMMA */
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+void PNGFAPI
+png_set_alpha_mode_fixed(png_structrp png_ptr, int mode,
+ png_fixed_point output_gamma)
+{
+ int compose = 0;
+ png_fixed_point file_gamma;
+
+ png_debug(1, "in png_set_alpha_mode");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/);
+
+ /* Validate the value to ensure it is in a reasonable range. The value
+ * is expected to be 1 or greater, but this range test allows for some
+ * viewing correction values. The intent is to weed out users of this API
+ * who use the inverse of the gamma value accidentally! Since some of these
+ * values are reasonable this may have to be changed.
+ */
+ if (output_gamma < 70000 || output_gamma > 300000)
+ png_error(png_ptr, "output gamma out of expected range");
+
+ /* The default file gamma is the inverse of the output gamma; the output
+ * gamma may be changed below so get the file value first:
+ */
+ file_gamma = png_reciprocal(output_gamma);
+
+ /* There are really 8 possibilities here, composed of any combination
+ * of:
+ *
+ * premultiply the color channels
+ * do not encode non-opaque pixels
+ * encode the alpha as well as the color channels
+ *
+ * The differences disappear if the input/output ('screen') gamma is 1.0,
+ * because then the encoding is a no-op and there is only the choice of
+ * premultiplying the color channels or not.
+ *
+ * png_set_alpha_mode and png_set_background interact because both use
+ * png_compose to do the work. Calling both is only useful when
+ * png_set_alpha_mode is used to set the default mode - PNG_ALPHA_PNG - along
+ * with a default gamma value. Otherwise PNG_COMPOSE must not be set.
+ */
+ switch (mode)
+ {
+ case PNG_ALPHA_PNG: /* default: png standard */
+ /* No compose, but it may be set by png_set_background! */
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ break;
+
+ case PNG_ALPHA_ASSOCIATED: /* color channels premultiplied */
+ compose = 1;
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ /* The output is linear: */
+ output_gamma = PNG_FP_1;
+ break;
+
+ case PNG_ALPHA_OPTIMIZED: /* associated, non-opaque pixels linear */
+ compose = 1;
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags |= PNG_FLAG_OPTIMIZE_ALPHA;
+ /* output_gamma records the encoding of opaque pixels! */
+ break;
+
+ case PNG_ALPHA_BROKEN: /* associated, non-linear, alpha encoded */
+ compose = 1;
+ png_ptr->transformations |= PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ break;
+
+ default:
+ png_error(png_ptr, "invalid alpha mode");
+ }
+
+ /* Only set the default gamma if the file gamma has not been set (this has
+ * the side effect that the gamma in a second call to png_set_alpha_mode will
+ * be ignored.)
+ */
+ if (png_ptr->colorspace.gamma == 0)
+ {
+ png_ptr->colorspace.gamma = file_gamma;
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ }
+
+ /* But always set the output gamma: */
+ png_ptr->screen_gamma = output_gamma;
+
+ /* Finally, if pre-multiplying, set the background fields to achieve the
+ * desired result.
+ */
+ if (compose)
+ {
+ /* And obtain alpha pre-multiplication by composing on black: */
+ memset(&png_ptr->background, 0, (sizeof png_ptr->background));
+ png_ptr->background_gamma = png_ptr->colorspace.gamma; /* just in case */
+ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_FILE;
+ png_ptr->transformations &= ~PNG_BACKGROUND_EXPAND;
+
+ if (png_ptr->transformations & PNG_COMPOSE)
+ png_error(png_ptr,
+ "conflicting calls to set alpha mode and background");
+
+ png_ptr->transformations |= PNG_COMPOSE;
+ }
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_alpha_mode(png_structrp png_ptr, int mode, double output_gamma)
+{
+ png_set_alpha_mode_fixed(png_ptr, mode, convert_gamma_value(png_ptr,
+ output_gamma));
+}
+# endif
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* Dither file to 8-bit. Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible. If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number. "full_quantize" indicates
+ * whether we need a quantizing cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+ struct png_dsort_struct * next;
+ png_byte left;
+ png_byte right;
+} png_dsort;
+typedef png_dsort * png_dsortp;
+typedef png_dsort * * png_dsortpp;
+
+void PNGAPI
+png_set_quantize(png_structrp png_ptr, png_colorp palette,
+ int num_palette, int maximum_colors, png_const_uint_16p histogram,
+ int full_quantize)
+{
+ png_debug(1, "in png_set_quantize");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= PNG_QUANTIZE;
+
+ if (!full_quantize)
+ {
+ int i;
+
+ png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
+ for (i = 0; i < num_palette; i++)
+ png_ptr->quantize_index[i] = (png_byte)i;
+ }
+
+ if (num_palette > maximum_colors)
+ {
+ if (histogram != NULL)
+ {
+ /* This is easy enough, just throw out the least used colors.
+ * Perhaps not the best solution, but good enough.
+ */
+
+ int i;
+
+ /* Initialize an array to sort colors */
+ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
+
+ /* Initialize the quantize_sort array */
+ for (i = 0; i < num_palette; i++)
+ png_ptr->quantize_sort[i] = (png_byte)i;
+
+ /* Find the least used palette entries by starting a
+ * bubble sort, and running it until we have sorted
+ * out enough colors. Note that we don't care about
+ * sorting all the colors, just finding which are
+ * least used.
+ */
+
+ for (i = num_palette - 1; i >= maximum_colors; i--)
+ {
+ int done; /* To stop early if the list is pre-sorted */
+ int j;
+
+ done = 1;
+ for (j = 0; j < i; j++)
+ {
+ if (histogram[png_ptr->quantize_sort[j]]
+ < histogram[png_ptr->quantize_sort[j + 1]])
+ {
+ png_byte t;
+
+ t = png_ptr->quantize_sort[j];
+ png_ptr->quantize_sort[j] = png_ptr->quantize_sort[j + 1];
+ png_ptr->quantize_sort[j + 1] = t;
+ done = 0;
+ }
+ }
+
+ if (done)
+ break;
+ }
+
+ /* Swap the palette around, and set up a table, if necessary */
+ if (full_quantize)
+ {
+ int j = num_palette;
+
+ /* Put all the useful colors within the max, but don't
+ * move the others.
+ */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
+ {
+ do
+ j--;
+ while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
+
+ palette[i] = palette[j];
+ }
+ }
+ }
+ else
+ {
+ int j = num_palette;
+
+ /* Move all the used colors inside the max limit, and
+ * develop a translation table.
+ */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ /* Only move the colors we need to */
+ if ((int)png_ptr->quantize_sort[i] >= maximum_colors)
+ {
+ png_color tmp_color;
+
+ do
+ j--;
+ while ((int)png_ptr->quantize_sort[j] >= maximum_colors);
+
+ tmp_color = palette[j];
+ palette[j] = palette[i];
+ palette[i] = tmp_color;
+ /* Indicate where the color went */
+ png_ptr->quantize_index[j] = (png_byte)i;
+ png_ptr->quantize_index[i] = (png_byte)j;
+ }
+ }
+
+ /* Find closest color for those colors we are not using */
+ for (i = 0; i < num_palette; i++)
+ {
+ if ((int)png_ptr->quantize_index[i] >= maximum_colors)
+ {
+ int min_d, k, min_k, d_index;
+
+ /* Find the closest color to one we threw out */
+ d_index = png_ptr->quantize_index[i];
+ min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+ for (k = 1, min_k = 0; k < maximum_colors; k++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+ if (d < min_d)
+ {
+ min_d = d;
+ min_k = k;
+ }
+ }
+ /* Point to closest color */
+ png_ptr->quantize_index[i] = (png_byte)min_k;
+ }
+ }
+ }
+ png_free(png_ptr, png_ptr->quantize_sort);
+ png_ptr->quantize_sort = NULL;
+ }
+ else
+ {
+ /* This is much harder to do simply (and quickly). Perhaps
+ * we need to go through a median cut routine, but those
+ * don't always behave themselves with only a few colors
+ * as input. So we will just find the closest two colors,
+ * and throw out one of them (chosen somewhat randomly).
+ * [We don't understand this at all, so if someone wants to
+ * work on improving it, be our guest - AED, GRP]
+ */
+ int i;
+ int max_d;
+ int num_new_palette;
+ png_dsortp t;
+ png_dsortpp hash;
+
+ t = NULL;
+
+ /* Initialize palette index arrays */
+ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
+ png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * (sizeof (png_byte))));
+
+ /* Initialize the sort array */
+ for (i = 0; i < num_palette; i++)
+ {
+ png_ptr->index_to_palette[i] = (png_byte)i;
+ png_ptr->palette_to_index[i] = (png_byte)i;
+ }
+
+ hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
+ (sizeof (png_dsortp))));
+
+ num_new_palette = num_palette;
+
+ /* Initial wild guess at how far apart the farthest pixel
+ * pair we will be eliminating will be. Larger
+ * numbers mean more areas will be allocated, Smaller
+ * numbers run the risk of not saving enough data, and
+ * having to do this all over again.
+ *
+ * I have not done extensive checking on this number.
+ */
+ max_d = 96;
+
+ while (num_new_palette > maximum_colors)
+ {
+ for (i = 0; i < num_new_palette - 1; i++)
+ {
+ int j;
+
+ for (j = i + 1; j < num_new_palette; j++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+ if (d <= max_d)
+ {
+
+ t = (png_dsortp)png_malloc_warn(png_ptr,
+ (png_uint_32)(sizeof (png_dsort)));
+
+ if (t == NULL)
+ break;
+
+ t->next = hash[d];
+ t->left = (png_byte)i;
+ t->right = (png_byte)j;
+ hash[d] = t;
+ }
+ }
+ if (t == NULL)
+ break;
+ }
+
+ if (t != NULL)
+ for (i = 0; i <= max_d; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p;
+
+ for (p = hash[i]; p; p = p->next)
+ {
+ if ((int)png_ptr->index_to_palette[p->left]
+ < num_new_palette &&
+ (int)png_ptr->index_to_palette[p->right]
+ < num_new_palette)
+ {
+ int j, next_j;
+
+ if (num_new_palette & 0x01)
+ {
+ j = p->left;
+ next_j = p->right;
+ }
+ else
+ {
+ j = p->right;
+ next_j = p->left;
+ }
+
+ num_new_palette--;
+ palette[png_ptr->index_to_palette[j]]
+ = palette[num_new_palette];
+ if (!full_quantize)
+ {
+ int k;
+
+ for (k = 0; k < num_palette; k++)
+ {
+ if (png_ptr->quantize_index[k] ==
+ png_ptr->index_to_palette[j])
+ png_ptr->quantize_index[k] =
+ png_ptr->index_to_palette[next_j];
+
+ if ((int)png_ptr->quantize_index[k] ==
+ num_new_palette)
+ png_ptr->quantize_index[k] =
+ png_ptr->index_to_palette[j];
+ }
+ }
+
+ png_ptr->index_to_palette[png_ptr->palette_to_index
+ [num_new_palette]] = png_ptr->index_to_palette[j];
+
+ png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+ = png_ptr->palette_to_index[num_new_palette];
+
+ png_ptr->index_to_palette[j] =
+ (png_byte)num_new_palette;
+
+ png_ptr->palette_to_index[num_new_palette] =
+ (png_byte)j;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ }
+
+ for (i = 0; i < 769; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p = hash[i];
+ while (p)
+ {
+ t = p->next;
+ png_free(png_ptr, p);
+ p = t;
+ }
+ }
+ hash[i] = 0;
+ }
+ max_d += 96;
+ }
+ png_free(png_ptr, hash);
+ png_free(png_ptr, png_ptr->palette_to_index);
+ png_free(png_ptr, png_ptr->index_to_palette);
+ png_ptr->palette_to_index = NULL;
+ png_ptr->index_to_palette = NULL;
+ }
+ num_palette = maximum_colors;
+ }
+ if (png_ptr->palette == NULL)
+ {
+ png_ptr->palette = palette;
+ }
+ png_ptr->num_palette = (png_uint_16)num_palette;
+
+ if (full_quantize)
+ {
+ int i;
+ png_bytep distance;
+ int total_bits = PNG_QUANTIZE_RED_BITS + PNG_QUANTIZE_GREEN_BITS +
+ PNG_QUANTIZE_BLUE_BITS;
+ int num_red = (1 << PNG_QUANTIZE_RED_BITS);
+ int num_green = (1 << PNG_QUANTIZE_GREEN_BITS);
+ int num_blue = (1 << PNG_QUANTIZE_BLUE_BITS);
+ png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+ png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
+ (png_uint_32)(num_entries * (sizeof (png_byte))));
+
+ distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+ (sizeof (png_byte))));
+
+ memset(distance, 0xff, num_entries * (sizeof (png_byte)));
+
+ for (i = 0; i < num_palette; i++)
+ {
+ int ir, ig, ib;
+ int r = (palette[i].red >> (8 - PNG_QUANTIZE_RED_BITS));
+ int g = (palette[i].green >> (8 - PNG_QUANTIZE_GREEN_BITS));
+ int b = (palette[i].blue >> (8 - PNG_QUANTIZE_BLUE_BITS));
+
+ for (ir = 0; ir < num_red; ir++)
+ {
+ /* int dr = abs(ir - r); */
+ int dr = ((ir > r) ? ir - r : r - ir);
+ int index_r = (ir << (PNG_QUANTIZE_BLUE_BITS +
+ PNG_QUANTIZE_GREEN_BITS));
+
+ for (ig = 0; ig < num_green; ig++)
+ {
+ /* int dg = abs(ig - g); */
+ int dg = ((ig > g) ? ig - g : g - ig);
+ int dt = dr + dg;
+ int dm = ((dr > dg) ? dr : dg);
+ int index_g = index_r | (ig << PNG_QUANTIZE_BLUE_BITS);
+
+ for (ib = 0; ib < num_blue; ib++)
+ {
+ int d_index = index_g | ib;
+ /* int db = abs(ib - b); */
+ int db = ((ib > b) ? ib - b : b - ib);
+ int dmax = ((dm > db) ? dm : db);
+ int d = dmax + dt + db;
+
+ if (d < (int)distance[d_index])
+ {
+ distance[d_index] = (png_byte)d;
+ png_ptr->palette_lookup[d_index] = (png_byte)i;
+ }
+ }
+ }
+ }
+ }
+
+ png_free(png_ptr, distance);
+ }
+}
+#endif /* PNG_READ_QUANTIZE_SUPPORTED */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+void PNGFAPI
+png_set_gamma_fixed(png_structrp png_ptr, png_fixed_point scrn_gamma,
+ png_fixed_point file_gamma)
+{
+ png_debug(1, "in png_set_gamma_fixed");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ /* New in libpng-1.5.4 - reserve particular negative values as flags. */
+ scrn_gamma = translate_gamma_flags(png_ptr, scrn_gamma, 1/*screen*/);
+ file_gamma = translate_gamma_flags(png_ptr, file_gamma, 0/*file*/);
+
+ /* Checking the gamma values for being >0 was added in 1.5.4 along with the
+ * premultiplied alpha support; this actually hides an undocumented feature
+ * of the previous implementation which allowed gamma processing to be
+ * disabled in background handling. There is no evidence (so far) that this
+ * was being used; however, png_set_background itself accepted and must still
+ * accept '0' for the gamma value it takes, because it isn't always used.
+ *
+ * Since this is an API change (albeit a very minor one that removes an
+ * undocumented API feature) the following checks were only enabled in
+ * libpng-1.6.0.
+ */
+ if (file_gamma <= 0)
+ png_error(png_ptr, "invalid file gamma in png_set_gamma");
+
+ if (scrn_gamma <= 0)
+ png_error(png_ptr, "invalid screen gamma in png_set_gamma");
+
+ /* Set the gamma values unconditionally - this overrides the value in the PNG
+ * file if a gAMA chunk was present. png_set_alpha_mode provides a
+ * different, easier, way to default the file gamma.
+ */
+ png_ptr->colorspace.gamma = file_gamma;
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+ png_ptr->screen_gamma = scrn_gamma;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gamma(png_structrp png_ptr, double scrn_gamma, double file_gamma)
+{
+ png_set_gamma_fixed(png_ptr, convert_gamma_value(png_ptr, scrn_gamma),
+ convert_gamma_value(png_ptr, file_gamma));
+}
+# endif /* FLOATING_POINT_SUPPORTED */
+#endif /* READ_GAMMA */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_expand");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+
+/* GRR 19990627: the following three functions currently are identical
+ * to png_set_expand(). However, it is entirely reasonable that someone
+ * might wish to expand an indexed image to RGB but *not* expand a single,
+ * fully transparent palette entry to a full alpha channel--perhaps instead
+ * convert tRNS to the grayscale/RGB format (16-bit RGB value), or replace
+ * the transparent color with a particular RGB value, or drop tRNS entirely.
+ * IOW, a future version of the library may make the transformations flag
+ * a bit more fine-grained, with separate bits for each of these three
+ * functions.
+ *
+ * More to the point, these functions make it obvious what libpng will be
+ * doing, whereas "expand" can (and does) mean any number of things.
+ *
+ * GRP 20060307: In libpng-1.2.9, png_set_gray_1_2_4_to_8() was modified
+ * to expand only the sample depth but not to expand the tRNS to alpha
+ * and its name was changed to png_set_expand_gray_1_2_4_to_8().
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_palette_to_rgb");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_expand_gray_1_2_4_to_8(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_expand_gray_1_2_4_to_8");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_tRNS_to_alpha");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* Expand to 16-bit channels, expand the tRNS chunk too (because otherwise
+ * it may not work correctly.)
+ */
+void PNGAPI
+png_set_expand_16(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_expand_16");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ png_ptr->transformations |= (PNG_EXPAND_16 | PNG_EXPAND | PNG_EXPAND_tRNS);
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+void PNGAPI
+png_set_gray_to_rgb(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_gray_to_rgb");
+
+ if (!png_rtran_ok(png_ptr, 0))
+ return;
+
+ /* Because rgb must be 8 bits or more: */
+ png_set_expand_gray_1_2_4_to_8(png_ptr);
+ png_ptr->transformations |= PNG_GRAY_TO_RGB;
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+void PNGFAPI
+png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action,
+ png_fixed_point red, png_fixed_point green)
+{
+ png_debug(1, "in png_set_rgb_to_gray");
+
+ /* Need the IHDR here because of the check on color_type below. */
+ /* TODO: fix this */
+ if (!png_rtran_ok(png_ptr, 1))
+ return;
+
+ switch(error_action)
+ {
+ case PNG_ERROR_ACTION_NONE:
+ png_ptr->transformations |= PNG_RGB_TO_GRAY;
+ break;
+
+ case PNG_ERROR_ACTION_WARN:
+ png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+ break;
+
+ case PNG_ERROR_ACTION_ERROR:
+ png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+ break;
+
+ default:
+ png_error(png_ptr, "invalid error action to rgb_to_gray");
+ break;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ png_ptr->transformations |= PNG_EXPAND;
+#else
+ {
+ /* Make this an error in 1.6 because otherwise the application may assume
+ * that it just worked and get a memory overwrite.
+ */
+ png_error(png_ptr,
+ "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED");
+
+ /* png_ptr->transformations &= ~PNG_RGB_TO_GRAY; */
+ }
+#endif
+ {
+ if (red >= 0 && green >= 0 && red + green <= PNG_FP_1)
+ {
+ png_uint_16 red_int, green_int;
+
+ /* NOTE: this calculation does not round, but this behavior is retained
+ * for consistency, the inaccuracy is very small. The code here always
+ * overwrites the coefficients, regardless of whether they have been
+ * defaulted or set already.
+ */
+ red_int = (png_uint_16)(((png_uint_32)red*32768)/100000);
+ green_int = (png_uint_16)(((png_uint_32)green*32768)/100000);
+
+ png_ptr->rgb_to_gray_red_coeff = red_int;
+ png_ptr->rgb_to_gray_green_coeff = green_int;
+ png_ptr->rgb_to_gray_coefficients_set = 1;
+ }
+
+ else
+ {
+ if (red >= 0 && green >= 0)
+ png_app_warning(png_ptr,
+ "ignoring out of range rgb_to_gray coefficients");
+
+ /* Use the defaults, from the cHRM chunk if set, else the historical
+ * values which are close to the sRGB/HDTV/ITU-Rec 709 values. See
+ * png_do_rgb_to_gray for more discussion of the values. In this case
+ * the coefficients are not marked as 'set' and are not overwritten if
+ * something has already provided a default.
+ */
+ if (png_ptr->rgb_to_gray_red_coeff == 0 &&
+ png_ptr->rgb_to_gray_green_coeff == 0)
+ {
+ png_ptr->rgb_to_gray_red_coeff = 6968;
+ png_ptr->rgb_to_gray_green_coeff = 23434;
+ /* png_ptr->rgb_to_gray_blue_coeff = 2366; */
+ }
+ }
+ }
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* Convert a RGB image to a grayscale of the same width. This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structrp png_ptr, int error_action, double red,
+ double green)
+{
+ png_set_rgb_to_gray_fixed(png_ptr, error_action,
+ png_fixed(png_ptr, red, "rgb to gray red coefficient"),
+ png_fixed(png_ptr, green, "rgb to gray green coefficient"));
+}
+#endif /* FLOATING POINT */
+
+#endif /* RGB_TO_GRAY */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+ read_user_transform_fn)
+{
+ png_debug(1, "in png_set_read_user_transform_fn");
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+}
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* In the case of gamma transformations only do transformations on images where
+ * the [file] gamma and screen_gamma are not close reciprocals, otherwise it
+ * slows things down slightly, and also needlessly introduces small errors.
+ */
+static int /* PRIVATE */
+png_gamma_threshold(png_fixed_point screen_gamma, png_fixed_point file_gamma)
+{
+ /* PNG_GAMMA_THRESHOLD is the threshold for performing gamma
+ * correction as a difference of the overall transform from 1.0
+ *
+ * We want to compare the threshold with s*f - 1, if we get
+ * overflow here it is because of wacky gamma values so we
+ * turn on processing anyway.
+ */
+ png_fixed_point gtest;
+ return !png_muldiv(&gtest, screen_gamma, file_gamma, PNG_FP_1) ||
+ png_gamma_significant(gtest);
+}
+#endif
+
+/* Initialize everything needed for the read. This includes modifying
+ * the palette.
+ */
+
+/*For the moment 'png_init_palette_transformations' and
+ * 'png_init_rgb_transformations' only do some flag canceling optimizations.
+ * The intent is that these two routines should have palette or rgb operations
+ * extracted from 'png_init_read_transformations'.
+ */
+static void /* PRIVATE */
+png_init_palette_transformations(png_structrp png_ptr)
+{
+ /* Called to handle the (input) palette case. In png_do_read_transformations
+ * the first step is to expand the palette if requested, so this code must
+ * take care to only make changes that are invariant with respect to the
+ * palette expansion, or only do them if there is no expansion.
+ *
+ * STRIP_ALPHA has already been handled in the caller (by setting num_trans
+ * to 0.)
+ */
+ int input_has_alpha = 0;
+ int input_has_transparency = 0;
+
+ if (png_ptr->num_trans > 0)
+ {
+ int i;
+
+ /* Ignore if all the entries are opaque (unlikely!) */
+ for (i=0; i<png_ptr->num_trans; ++i)
+ if (png_ptr->trans_alpha[i] == 255)
+ continue;
+ else if (png_ptr->trans_alpha[i] == 0)
+ input_has_transparency = 1;
+ else
+ input_has_alpha = 1;
+ }
+
+ /* If no alpha we can optimize. */
+ if (!input_has_alpha)
+ {
+ /* Any alpha means background and associative alpha processing is
+ * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
+ * and ENCODE_ALPHA are irrelevant.
+ */
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+ if (!input_has_transparency)
+ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
+ }
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* png_set_background handling - deals with the complexity of whether the
+ * background color is in the file format or the screen format in the case
+ * where an 'expand' will happen.
+ */
+
+ /* The following code cannot be entered in the alpha pre-multiplication case
+ * because PNG_BACKGROUND_EXPAND is cancelled below.
+ */
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_EXPAND))
+ {
+ {
+ png_ptr->background.red =
+ png_ptr->palette[png_ptr->background.index].red;
+ png_ptr->background.green =
+ png_ptr->palette[png_ptr->background.index].green;
+ png_ptr->background.blue =
+ png_ptr->palette[png_ptr->background.index].blue;
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ {
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ /* Invert the alpha channel (in tRNS) unless the pixels are
+ * going to be expanded, in which case leave it for later
+ */
+ int i, istop = png_ptr->num_trans;
+
+ for (i=0; i<istop; i++)
+ png_ptr->trans_alpha[i] = (png_byte)(255 -
+ png_ptr->trans_alpha[i]);
+ }
+ }
+#endif /* PNG_READ_INVERT_ALPHA_SUPPORTED */
+ }
+ } /* background expand and (therefore) no alpha association. */
+#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
+}
+
+static void /* PRIVATE */
+png_init_rgb_transformations(png_structrp png_ptr)
+{
+ /* Added to libpng-1.5.4: check the color type to determine whether there
+ * is any alpha or transparency in the image and simply cancel the
+ * background and alpha mode stuff if there isn't.
+ */
+ int input_has_alpha = (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+ int input_has_transparency = png_ptr->num_trans > 0;
+
+ /* If no alpha we can optimize. */
+ if (!input_has_alpha)
+ {
+ /* Any alpha means background and associative alpha processing is
+ * required, however if the alpha is 0 or 1 throughout OPTIIMIZE_ALPHA
+ * and ENCODE_ALPHA are irrelevant.
+ */
+# ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+# endif
+
+ if (!input_has_transparency)
+ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_BACKGROUND_EXPAND);
+ }
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* png_set_background handling - deals with the complexity of whether the
+ * background color is in the file format or the screen format in the case
+ * where an 'expand' will happen.
+ */
+
+ /* The following code cannot be entered in the alpha pre-multiplication case
+ * because PNG_BACKGROUND_EXPAND is cancelled below.
+ */
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_EXPAND) &&
+ !(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
+ /* i.e., GRAY or GRAY_ALPHA */
+ {
+ {
+ /* Expand background and tRNS chunks */
+ int gray = png_ptr->background.gray;
+ int trans_gray = png_ptr->trans_color.gray;
+
+ switch (png_ptr->bit_depth)
+ {
+ case 1:
+ gray *= 0xff;
+ trans_gray *= 0xff;
+ break;
+
+ case 2:
+ gray *= 0x55;
+ trans_gray *= 0x55;
+ break;
+
+ case 4:
+ gray *= 0x11;
+ trans_gray *= 0x11;
+ break;
+
+ default:
+
+ case 8:
+ /* FALL THROUGH (Already 8 bits) */
+
+ case 16:
+ /* Already a full 16 bits */
+ break;
+ }
+
+ png_ptr->background.red = png_ptr->background.green =
+ png_ptr->background.blue = (png_uint_16)gray;
+
+ if (!(png_ptr->transformations & PNG_EXPAND_tRNS))
+ {
+ png_ptr->trans_color.red = png_ptr->trans_color.green =
+ png_ptr->trans_color.blue = (png_uint_16)trans_gray;
+ }
+ }
+ } /* background expand and (therefore) no alpha association. */
+#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
+}
+
+void /* PRIVATE */
+png_init_read_transformations(png_structrp png_ptr)
+{
+ png_debug(1, "in png_init_read_transformations");
+
+ /* This internal function is called from png_read_start_row in pngrutil.c
+ * and it is called before the 'rowbytes' calculation is done, so the code
+ * in here can change or update the transformations flags.
+ *
+ * First do updates that do not depend on the details of the PNG image data
+ * being processed.
+ */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ /* Prior to 1.5.4 these tests were performed from png_set_gamma, 1.5.4 adds
+ * png_set_alpha_mode and this is another source for a default file gamma so
+ * the test needs to be performed later - here. In addition prior to 1.5.4
+ * the tests were repeated for the PALETTE color type here - this is no
+ * longer necessary (and doesn't seem to have been necessary before.)
+ */
+ {
+ /* The following temporary indicates if overall gamma correction is
+ * required.
+ */
+ int gamma_correction = 0;
+
+ if (png_ptr->colorspace.gamma != 0) /* has been set */
+ {
+ if (png_ptr->screen_gamma != 0) /* screen set too */
+ gamma_correction = png_gamma_threshold(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
+
+ else
+ /* Assume the output matches the input; a long time default behavior
+ * of libpng, although the standard has nothing to say about this.
+ */
+ png_ptr->screen_gamma = png_reciprocal(png_ptr->colorspace.gamma);
+ }
+
+ else if (png_ptr->screen_gamma != 0)
+ /* The converse - assume the file matches the screen, note that this
+ * perhaps undesireable default can (from 1.5.4) be changed by calling
+ * png_set_alpha_mode (even if the alpha handling mode isn't required
+ * or isn't changed from the default.)
+ */
+ png_ptr->colorspace.gamma = png_reciprocal(png_ptr->screen_gamma);
+
+ else /* neither are set */
+ /* Just in case the following prevents any processing - file and screen
+ * are both assumed to be linear and there is no way to introduce a
+ * third gamma value other than png_set_background with 'UNIQUE', and,
+ * prior to 1.5.4
+ */
+ png_ptr->screen_gamma = png_ptr->colorspace.gamma = PNG_FP_1;
+
+ /* We have a gamma value now. */
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_HAVE_GAMMA;
+
+ /* Now turn the gamma transformation on or off as appropriate. Notice
+ * that PNG_GAMMA just refers to the file->screen correction. Alpha
+ * composition may independently cause gamma correction because it needs
+ * linear data (e.g. if the file has a gAMA chunk but the screen gamma
+ * hasn't been specified.) In any case this flag may get turned off in
+ * the code immediately below if the transform can be handled outside the
+ * row loop.
+ */
+ if (gamma_correction)
+ png_ptr->transformations |= PNG_GAMMA;
+
+ else
+ png_ptr->transformations &= ~PNG_GAMMA;
+ }
+#endif
+
+ /* Certain transformations have the effect of preventing other
+ * transformations that happen afterward in png_do_read_transformations,
+ * resolve the interdependencies here. From the code of
+ * png_do_read_transformations the order is:
+ *
+ * 1) PNG_EXPAND (including PNG_EXPAND_tRNS)
+ * 2) PNG_STRIP_ALPHA (if no compose)
+ * 3) PNG_RGB_TO_GRAY
+ * 4) PNG_GRAY_TO_RGB iff !PNG_BACKGROUND_IS_GRAY
+ * 5) PNG_COMPOSE
+ * 6) PNG_GAMMA
+ * 7) PNG_STRIP_ALPHA (if compose)
+ * 8) PNG_ENCODE_ALPHA
+ * 9) PNG_SCALE_16_TO_8
+ * 10) PNG_16_TO_8
+ * 11) PNG_QUANTIZE (converts to palette)
+ * 12) PNG_EXPAND_16
+ * 13) PNG_GRAY_TO_RGB iff PNG_BACKGROUND_IS_GRAY
+ * 14) PNG_INVERT_MONO
+ * 15) PNG_SHIFT
+ * 16) PNG_PACK
+ * 17) PNG_BGR
+ * 18) PNG_PACKSWAP
+ * 19) PNG_FILLER (includes PNG_ADD_ALPHA)
+ * 20) PNG_INVERT_ALPHA
+ * 21) PNG_SWAP_ALPHA
+ * 22) PNG_SWAP_BYTES
+ * 23) PNG_USER_TRANSFORM [must be last]
+ */
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+ !(png_ptr->transformations & PNG_COMPOSE))
+ {
+ /* Stripping the alpha channel happens immediately after the 'expand'
+ * transformations, before all other transformation, so it cancels out
+ * the alpha handling. It has the side effect negating the effect of
+ * PNG_EXPAND_tRNS too:
+ */
+ png_ptr->transformations &= ~(PNG_BACKGROUND_EXPAND | PNG_ENCODE_ALPHA |
+ PNG_EXPAND_tRNS);
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+
+ /* Kill the tRNS chunk itself too. Prior to 1.5.4 this did not happen
+ * so transparency information would remain just so long as it wasn't
+ * expanded. This produces unexpected API changes if the set of things
+ * that do PNG_EXPAND_tRNS changes (perfectly possible given the
+ * documentation - which says ask for what you want, accept what you
+ * get.) This makes the behavior consistent from 1.5.4:
+ */
+ png_ptr->num_trans = 0;
+ }
+#endif /* STRIP_ALPHA supported, no COMPOSE */
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+ /* If the screen gamma is about 1.0 then the OPTIMIZE_ALPHA and ENCODE_ALPHA
+ * settings will have no effect.
+ */
+ if (!png_gamma_significant(png_ptr->screen_gamma))
+ {
+ png_ptr->transformations &= ~PNG_ENCODE_ALPHA;
+ png_ptr->flags &= ~PNG_FLAG_OPTIMIZE_ALPHA;
+ }
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* Make sure the coefficients for the rgb to gray conversion are set
+ * appropriately.
+ */
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ png_colorspace_set_rgb_coefficients(png_ptr);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* Detect gray background and attempt to enable optimization for
+ * gray --> RGB case.
+ *
+ * Note: if PNG_BACKGROUND_EXPAND is set and color_type is either RGB or
+ * RGB_ALPHA (in which case need_expand is superfluous anyway), the
+ * background color might actually be gray yet not be flagged as such.
+ * This is not a problem for the current code, which uses
+ * PNG_BACKGROUND_IS_GRAY only to decide when to do the
+ * png_do_gray_to_rgb() transformation.
+ *
+ * TODO: this code needs to be revised to avoid the complexity and
+ * interdependencies. The color type of the background should be recorded in
+ * png_set_background, along with the bit depth, then the code has a record
+ * of exactly what color space the background is currently in.
+ */
+ if (png_ptr->transformations & PNG_BACKGROUND_EXPAND)
+ {
+ /* PNG_BACKGROUND_EXPAND: the background is in the file color space, so if
+ * the file was grayscale the background value is gray.
+ */
+ if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ }
+
+ else if (png_ptr->transformations & PNG_COMPOSE)
+ {
+ /* PNG_COMPOSE: png_set_background was called with need_expand false,
+ * so the color is in the color space of the output or png_set_alpha_mode
+ * was called and the color is black. Ignore RGB_TO_GRAY because that
+ * happens before GRAY_TO_RGB.
+ */
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ {
+ if (png_ptr->background.red == png_ptr->background.green &&
+ png_ptr->background.red == png_ptr->background.blue)
+ {
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+ png_ptr->background.gray = png_ptr->background.red;
+ }
+ }
+ }
+#endif /* PNG_READ_EXPAND_SUPPORTED && PNG_READ_BACKGROUND_SUPPORTED */
+#endif /* PNG_READ_GRAY_TO_RGB_SUPPORTED */
+
+ /* For indexed PNG data (PNG_COLOR_TYPE_PALETTE) many of the transformations
+ * can be performed directly on the palette, and some (such as rgb to gray)
+ * can be optimized inside the palette. This is particularly true of the
+ * composite (background and alpha) stuff, which can be pretty much all done
+ * in the palette even if the result is expanded to RGB or gray afterward.
+ *
+ * NOTE: this is Not Yet Implemented, the code behaves as in 1.5.1 and
+ * earlier and the palette stuff is actually handled on the first row. This
+ * leads to the reported bug that the palette returned by png_get_PLTE is not
+ * updated.
+ */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_init_palette_transformations(png_ptr);
+
+ else
+ png_init_rgb_transformations(png_ptr);
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_READ_EXPAND_16_SUPPORTED)
+ if ((png_ptr->transformations & PNG_EXPAND_16) &&
+ (png_ptr->transformations & PNG_COMPOSE) &&
+ !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ png_ptr->bit_depth != 16)
+ {
+ /* TODO: fix this. Because the expand_16 operation is after the compose
+ * handling the background color must be 8, not 16, bits deep, but the
+ * application will supply a 16-bit value so reduce it here.
+ *
+ * The PNG_BACKGROUND_EXPAND code above does not expand to 16 bits at
+ * present, so that case is ok (until do_expand_16 is moved.)
+ *
+ * NOTE: this discards the low 16 bits of the user supplied background
+ * color, but until expand_16 works properly there is no choice!
+ */
+# define CHOP(x) (x)=((png_uint_16)PNG_DIV257(x))
+ CHOP(png_ptr->background.red);
+ CHOP(png_ptr->background.green);
+ CHOP(png_ptr->background.blue);
+ CHOP(png_ptr->background.gray);
+# undef CHOP
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED && PNG_READ_EXPAND_16_SUPPORTED */
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ (defined(PNG_READ_SCALE_16_TO_8_SUPPORTED) || \
+ defined(PNG_READ_STRIP_16_TO_8_SUPPORTED))
+ if ((png_ptr->transformations & (PNG_16_TO_8|PNG_SCALE_16_TO_8)) &&
+ (png_ptr->transformations & PNG_COMPOSE) &&
+ !(png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ png_ptr->bit_depth == 16)
+ {
+ /* On the other hand, if a 16-bit file is to be reduced to 8-bits per
+ * component this will also happen after PNG_COMPOSE and so the background
+ * color must be pre-expanded here.
+ *
+ * TODO: fix this too.
+ */
+ png_ptr->background.red = (png_uint_16)(png_ptr->background.red * 257);
+ png_ptr->background.green =
+ (png_uint_16)(png_ptr->background.green * 257);
+ png_ptr->background.blue = (png_uint_16)(png_ptr->background.blue * 257);
+ png_ptr->background.gray = (png_uint_16)(png_ptr->background.gray * 257);
+ }
+#endif
+
+ /* NOTE: below 'PNG_READ_ALPHA_MODE_SUPPORTED' is presumed to also enable the
+ * background support (see the comments in scripts/pnglibconf.dfa), this
+ * allows pre-multiplication of the alpha channel to be implemented as
+ * compositing on black. This is probably sub-optimal and has been done in
+ * 1.5.4 betas simply to enable external critique and testing (i.e. to
+ * implement the new API quickly, without lots of internal changes.)
+ */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+# ifdef PNG_READ_BACKGROUND_SUPPORTED
+ /* Includes ALPHA_MODE */
+ png_ptr->background_1 = png_ptr->background;
+# endif
+
+ /* This needs to change - in the palette image case a whole set of tables are
+ * built when it would be quicker to just calculate the correct value for
+ * each palette entry directly. Also, the test is too tricky - why check
+ * PNG_RGB_TO_GRAY if PNG_GAMMA is not set? The answer seems to be that
+ * PNG_GAMMA is cancelled even if the gamma is known? The test excludes the
+ * PNG_COMPOSE case, so apparently if there is no *overall* gamma correction
+ * the gamma tables will not be built even if composition is required on a
+ * gamma encoded value.
+ *
+ * In 1.5.4 this is addressed below by an additional check on the individual
+ * file gamma - if it is not 1.0 both RGB_TO_GRAY and COMPOSE need the
+ * tables.
+ */
+ if ((png_ptr->transformations & PNG_GAMMA)
+ || ((png_ptr->transformations & PNG_RGB_TO_GRAY)
+ && (png_gamma_significant(png_ptr->colorspace.gamma) ||
+ png_gamma_significant(png_ptr->screen_gamma)))
+ || ((png_ptr->transformations & PNG_COMPOSE)
+ && (png_gamma_significant(png_ptr->colorspace.gamma)
+ || png_gamma_significant(png_ptr->screen_gamma)
+# ifdef PNG_READ_BACKGROUND_SUPPORTED
+ || (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_UNIQUE
+ && png_gamma_significant(png_ptr->background_gamma))
+# endif
+ )) || ((png_ptr->transformations & PNG_ENCODE_ALPHA)
+ && png_gamma_significant(png_ptr->screen_gamma))
+ )
+ {
+ png_build_gamma_table(png_ptr, png_ptr->bit_depth);
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ if (png_ptr->transformations & PNG_COMPOSE)
+ {
+ /* Issue a warning about this combination: because RGB_TO_GRAY is
+ * optimized to do the gamma transform if present yet do_background has
+ * to do the same thing if both options are set a
+ * double-gamma-correction happens. This is true in all versions of
+ * libpng to date.
+ */
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ png_warning(png_ptr,
+ "libpng does not support gamma+background+rgb_to_gray");
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ /* We don't get to here unless there is a tRNS chunk with non-opaque
+ * entries - see the checking code at the start of this function.
+ */
+ png_color back, back_1;
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ png_fixed_point g, gs;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = PNG_FP_1;
+ break;
+
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = png_reciprocal(png_ptr->colorspace.gamma);
+ gs = png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
+ break;
+
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = png_reciprocal(png_ptr->background_gamma);
+ gs = png_reciprocal2(png_ptr->background_gamma,
+ png_ptr->screen_gamma);
+ break;
+ default:
+ g = PNG_FP_1; /* back_1 */
+ gs = PNG_FP_1; /* back */
+ break;
+ }
+
+ if (png_gamma_significant(gs))
+ {
+ back.red = png_gamma_8bit_correct(png_ptr->background.red,
+ gs);
+ back.green = png_gamma_8bit_correct(png_ptr->background.green,
+ gs);
+ back.blue = png_gamma_8bit_correct(png_ptr->background.blue,
+ gs);
+ }
+
+ else
+ {
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+ }
+
+ if (png_gamma_significant(g))
+ {
+ back_1.red = png_gamma_8bit_correct(png_ptr->background.red,
+ g);
+ back_1.green = png_gamma_8bit_correct(
+ png_ptr->background.green, g);
+ back_1.blue = png_gamma_8bit_correct(png_ptr->background.blue,
+ g);
+ }
+
+ else
+ {
+ back_1.red = (png_byte)png_ptr->background.red;
+ back_1.green = (png_byte)png_ptr->background.green;
+ back_1.blue = (png_byte)png_ptr->background.blue;
+ }
+ }
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i < (int)png_ptr->num_trans &&
+ png_ptr->trans_alpha[i] != 0xff)
+ {
+ if (png_ptr->trans_alpha[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else /* if (png_ptr->trans_alpha[i] != 0xff) */
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[palette[i].red];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].green];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].blue];
+ png_composite(w, v, png_ptr->trans_alpha[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+
+ /* Prevent the transformations being done again.
+ *
+ * NOTE: this is highly dubious; it removes the transformations in
+ * place. This seems inconsistent with the general treatment of the
+ * transformations elsewhere.
+ */
+ png_ptr->transformations &= ~(PNG_COMPOSE | PNG_GAMMA);
+ } /* color_type == PNG_COLOR_TYPE_PALETTE */
+
+ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+ else /* color_type != PNG_COLOR_TYPE_PALETTE */
+ {
+ int gs_sig, g_sig;
+ png_fixed_point g = PNG_FP_1; /* Correction to linear */
+ png_fixed_point gs = PNG_FP_1; /* Correction to screen */
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = png_ptr->screen_gamma;
+ /* gs = PNG_FP_1; */
+ break;
+
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = png_reciprocal(png_ptr->colorspace.gamma);
+ gs = png_reciprocal2(png_ptr->colorspace.gamma,
+ png_ptr->screen_gamma);
+ break;
+
+ case PNG_BACKGROUND_GAMMA_UNIQUE:
+ g = png_reciprocal(png_ptr->background_gamma);
+ gs = png_reciprocal2(png_ptr->background_gamma,
+ png_ptr->screen_gamma);
+ break;
+
+ default:
+ png_error(png_ptr, "invalid background gamma type");
+ }
+
+ g_sig = png_gamma_significant(g);
+ gs_sig = png_gamma_significant(gs);
+
+ if (g_sig)
+ png_ptr->background_1.gray = png_gamma_correct(png_ptr,
+ png_ptr->background.gray, g);
+
+ if (gs_sig)
+ png_ptr->background.gray = png_gamma_correct(png_ptr,
+ png_ptr->background.gray, gs);
+
+ if ((png_ptr->background.red != png_ptr->background.green) ||
+ (png_ptr->background.red != png_ptr->background.blue) ||
+ (png_ptr->background.red != png_ptr->background.gray))
+ {
+ /* RGB or RGBA with color background */
+ if (g_sig)
+ {
+ png_ptr->background_1.red = png_gamma_correct(png_ptr,
+ png_ptr->background.red, g);
+
+ png_ptr->background_1.green = png_gamma_correct(png_ptr,
+ png_ptr->background.green, g);
+
+ png_ptr->background_1.blue = png_gamma_correct(png_ptr,
+ png_ptr->background.blue, g);
+ }
+
+ if (gs_sig)
+ {
+ png_ptr->background.red = png_gamma_correct(png_ptr,
+ png_ptr->background.red, gs);
+
+ png_ptr->background.green = png_gamma_correct(png_ptr,
+ png_ptr->background.green, gs);
+
+ png_ptr->background.blue = png_gamma_correct(png_ptr,
+ png_ptr->background.blue, gs);
+ }
+ }
+
+ else
+ {
+ /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+ png_ptr->background_1.red = png_ptr->background_1.green
+ = png_ptr->background_1.blue = png_ptr->background_1.gray;
+
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ }
+
+ /* The background is now in screen gamma: */
+ png_ptr->background_gamma_type = PNG_BACKGROUND_GAMMA_SCREEN;
+ } /* color_type != PNG_COLOR_TYPE_PALETTE */
+ }/* png_ptr->transformations & PNG_BACKGROUND */
+
+ else
+ /* Transformation does not include PNG_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* RGB_TO_GRAY needs to have non-gamma-corrected values! */
+ && ((png_ptr->transformations & PNG_EXPAND) == 0 ||
+ (png_ptr->transformations & PNG_RGB_TO_GRAY) == 0)
+#endif
+ )
+ {
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+
+ /* NOTE: there are other transformations that should probably be in
+ * here too.
+ */
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+
+ /* Done the gamma correction. */
+ png_ptr->transformations &= ~PNG_GAMMA;
+ } /* color_type == PALETTE && !PNG_BACKGROUND transformation */
+ }
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ else
+#endif
+#endif /* PNG_READ_GAMMA_SUPPORTED */
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+ /* No GAMMA transformation (see the hanging else 4 lines above) */
+ if ((png_ptr->transformations & PNG_COMPOSE) &&
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ int i;
+ int istop = (int)png_ptr->num_trans;
+ png_color back;
+ png_colorp palette = png_ptr->palette;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < istop; i++)
+ {
+ if (png_ptr->trans_alpha[i] == 0)
+ {
+ palette[i] = back;
+ }
+
+ else if (png_ptr->trans_alpha[i] != 0xff)
+ {
+ /* The png_composite() macro is defined in png.h */
+ png_composite(palette[i].red, palette[i].red,
+ png_ptr->trans_alpha[i], back.red);
+
+ png_composite(palette[i].green, palette[i].green,
+ png_ptr->trans_alpha[i], back.green);
+
+ png_composite(palette[i].blue, palette[i].blue,
+ png_ptr->trans_alpha[i], back.blue);
+ }
+ }
+
+ png_ptr->transformations &= ~PNG_COMPOSE;
+
+ //png_ptr->flags |= PNG_FLAG_STRIP_ALPHA; /* Add by Sunliang.Liu */
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if ((png_ptr->transformations & PNG_SHIFT) &&
+ !(png_ptr->transformations & PNG_EXPAND) &&
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ int i;
+ int istop = png_ptr->num_palette;
+ int shift = 8 - png_ptr->sig_bit.red;
+
+ png_ptr->transformations &= ~PNG_SHIFT;
+
+ /* significant bits can be in the range 1 to 7 for a meaninful result, if
+ * the number of significant bits is 0 then no shift is done (this is an
+ * error condition which is silently ignored.)
+ */
+ if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
+ {
+ int component = png_ptr->palette[i].red;
+
+ component >>= shift;
+ png_ptr->palette[i].red = (png_byte)component;
+ }
+
+ shift = 8 - png_ptr->sig_bit.green;
+ if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
+ {
+ int component = png_ptr->palette[i].green;
+
+ component >>= shift;
+ png_ptr->palette[i].green = (png_byte)component;
+ }
+
+ shift = 8 - png_ptr->sig_bit.blue;
+ if (shift > 0 && shift < 8) for (i=0; i<istop; ++i)
+ {
+ int component = png_ptr->palette[i].blue;
+
+ component >>= shift;
+ png_ptr->palette[i].blue = (png_byte)component;
+ }
+ }
+#endif /* PNG_READ_SHIFT_SUPPORTED */
+}
+
+/* Modify the info structure to reflect the transformations. The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_debug(1, "in png_read_transform_info");
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ /* This check must match what actually happens in
+ * png_do_expand_palette; if it ever checks the tRNS chunk to see if
+ * it is all opaque we must do the same (at present it does not.)
+ */
+ if (png_ptr->num_trans > 0)
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+
+ else
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+ }
+ else
+ {
+ if (png_ptr->num_trans)
+ {
+ if (png_ptr->transformations & PNG_EXPAND_tRNS)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ }
+ if (info_ptr->bit_depth < 8)
+ info_ptr->bit_depth = 8;
+
+ info_ptr->num_trans = 0;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ /* The following is almost certainly wrong unless the background value is in
+ * the screen space!
+ */
+ if (png_ptr->transformations & PNG_COMPOSE)
+ info_ptr->background = png_ptr->background;
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ /* The following used to be conditional on PNG_GAMMA (prior to 1.5.4),
+ * however it seems that the code in png_init_read_transformations, which has
+ * been called before this from png_read_update_info->png_read_start_row
+ * sometimes does the gamma transform and cancels the flag.
+ *
+ * TODO: this looks wrong; the info_ptr should end up with a gamma equal to
+ * the screen_gamma value. The following probably results in weirdness if
+ * the info_ptr is used by the app after the rows have been read.
+ */
+ info_ptr->colorspace.gamma = png_ptr->colorspace.gamma;
+#endif
+
+ if (info_ptr->bit_depth == 16)
+ {
+# ifdef PNG_READ_16BIT_SUPPORTED
+# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ if (png_ptr->transformations & PNG_SCALE_16_TO_8)
+ info_ptr->bit_depth = 8;
+# endif
+
+# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ if (png_ptr->transformations & PNG_16_TO_8)
+ info_ptr->bit_depth = 8;
+# endif
+
+# else
+ /* No 16 bit support: force chopping 16-bit input down to 8, in this case
+ * the app program can chose if both APIs are available by setting the
+ * correct scaling to use.
+ */
+# ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ /* For compatibility with previous versions use the strip method by
+ * default. This code works because if PNG_SCALE_16_TO_8 is already
+ * set the code below will do that in preference to the chop.
+ */
+ png_ptr->transformations |= PNG_16_TO_8;
+ info_ptr->bit_depth = 8;
+# else
+
+# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ png_ptr->transformations |= PNG_SCALE_16_TO_8;
+ info_ptr->bit_depth = 8;
+# else
+
+ CONFIGURATION ERROR: you must enable at least one 16 to 8 method
+# endif
+# endif
+#endif /* !READ_16BIT_SUPPORTED */
+ }
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ info_ptr->color_type = (png_byte)(info_ptr->color_type |
+ PNG_COLOR_MASK_COLOR);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ info_ptr->color_type = (png_byte)(info_ptr->color_type &
+ ~PNG_COLOR_MASK_COLOR);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ if (png_ptr->transformations & PNG_QUANTIZE)
+ {
+ if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+ png_ptr->palette_lookup && info_ptr->bit_depth == 8)
+ {
+ info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+ }
+ }
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND_16 && info_ptr->bit_depth == 8 &&
+ info_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ info_ptr->bit_depth = 16;
+ }
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
+ info_ptr->bit_depth = 8;
+#endif
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+
+ else
+ info_ptr->channels = 1;
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_STRIP_ALPHA)
+ {
+ info_ptr->color_type = (png_byte)(info_ptr->color_type &
+ ~PNG_COLOR_MASK_ALPHA);
+ info_ptr->num_trans = 0;
+ }
+#endif
+
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
+ if ((png_ptr->transformations & PNG_FILLER) &&
+ ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
+ {
+ info_ptr->channels++;
+ /* If adding a true alpha channel not just filler */
+ if (png_ptr->transformations & PNG_ADD_ALPHA)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if (info_ptr->bit_depth < png_ptr->user_transform_depth)
+ info_ptr->bit_depth = png_ptr->user_transform_depth;
+
+ if (info_ptr->channels < png_ptr->user_transform_channels)
+ info_ptr->channels = png_ptr->user_transform_channels;
+ }
+#endif
+
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+ info_ptr->bit_depth);
+
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, info_ptr->width);
+
+ /* Adding in 1.5.4: cache the above value in png_struct so that we can later
+ * check in png_rowbytes that the user buffer won't get overwritten. Note
+ * that the field is not always set - if png_read_update_info isn't called
+ * the application has to either not do any transforms or get the calculation
+ * right itself.
+ */
+ png_ptr->info_rowbytes = info_ptr->rowbytes;
+
+#ifndef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr)
+ return;
+#endif
+}
+
+/* Transform the row. The order of transformations is significant,
+ * and is very touchy. If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+ png_debug(1, "in png_do_read_transformations");
+
+ if (png_ptr->row_buf == NULL)
+ {
+ /* Prior to 1.5.4 this output row/pass where the NULL pointer is, but this
+ * error is incredibly rare and incredibly easy to debug without this
+ * information.
+ */
+ png_error(png_ptr, "NULL row buffer");
+ }
+
+ /* The following is debugging; prior to 1.5.4 the code was never compiled in;
+ * in 1.5.4 PNG_FLAG_DETECT_UNINITIALIZED was added and the macro
+ * PNG_WARN_UNINITIALIZED_ROW removed. In 1.6 the new flag is set only for
+ * all transformations, however in practice the ROW_INIT always gets done on
+ * demand, if necessary.
+ */
+ if ((png_ptr->flags & PNG_FLAG_DETECT_UNINITIALIZED) != 0 &&
+ !(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ {
+ /* Application has failed to call either png_read_start_image() or
+ * png_read_update_info() after setting transforms that expand pixels.
+ * This check added to libpng-1.2.19 (but not enabled until 1.5.4).
+ */
+ png_error(png_ptr, "Uninitialized row");
+ }
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_do_expand_palette(row_info, png_ptr->row_buf + 1,
+ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans);
+ }
+
+ else
+ {
+ if (png_ptr->num_trans &&
+ (png_ptr->transformations & PNG_EXPAND_tRNS))
+ png_do_expand(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->trans_color));
+
+ else
+ png_do_expand(row_info, png_ptr->row_buf + 1,
+ NULL);
+ }
+ }
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+ !(png_ptr->transformations & PNG_COMPOSE) &&
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ 0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ {
+ int rgb_error =
+ png_do_rgb_to_gray(png_ptr, row_info,
+ png_ptr->row_buf + 1);
+
+ if (rgb_error)
+ {
+ png_ptr->rgb_to_gray_status=1;
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_WARN)
+ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+
+ if ((png_ptr->transformations & PNG_RGB_TO_GRAY) ==
+ PNG_RGB_TO_GRAY_ERR)
+ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ }
+ }
+#endif
+
+/* From Andreas Dilger e-mail to png-implement, 26 March 1998:
+ *
+ * In most cases, the "simple transparency" should be done prior to doing
+ * gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ * pixel is transparent. You would also need to make sure that the
+ * transparency information is upgraded to RGB.
+ *
+ * To summarize, the current flow is:
+ * - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ * with background "in place" if transparent,
+ * convert to RGB if necessary
+ * - Gray + alpha -> composite with gray background and remove alpha bytes,
+ * convert to RGB if necessary
+ *
+ * To support RGB backgrounds for gray images we need:
+ * - Gray + simple transparency -> convert to RGB + simple transparency,
+ * compare 3 or 6 bytes and composite with
+ * background "in place" if transparent
+ * (3x compare/pixel compared to doing
+ * composite with gray bkgrnd)
+ * - Gray + alpha -> convert to RGB + alpha, composite with background and
+ * remove alpha bytes (3x float
+ * operations/pixel compared with composite
+ * on gray background)
+ *
+ * Greg's change will do this. The reason it wasn't done before is for
+ * performance, as this increases the per-pixel operations. If we would check
+ * in advance if the background was gray or RGB, and position the gray-to-RGB
+ * transform appropriately, then it would save a lot of work/time.
+ */
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* If gray -> RGB, do so now only if background is non-gray; else do later
+ * for performance reasons
+ */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ if (png_ptr->transformations & PNG_COMPOSE)
+ png_do_compose(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if ((png_ptr->transformations & PNG_GAMMA) &&
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ /* Because RGB_TO_GRAY does the gamma transform. */
+ !(png_ptr->transformations & PNG_RGB_TO_GRAY) &&
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ /* Because PNG_COMPOSE does the gamma transform if there is something to
+ * do (if there is an alpha channel or transparency.)
+ */
+ !((png_ptr->transformations & PNG_COMPOSE) &&
+ ((png_ptr->num_trans != 0) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+ /* Because png_init_read_transformations transforms the palette, unless
+ * RGB_TO_GRAY will do the transform.
+ */
+ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+ png_do_gamma(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+ if ((png_ptr->transformations & PNG_STRIP_ALPHA) &&
+ (png_ptr->transformations & PNG_COMPOSE) &&
+ (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ 0 /* at_start == false, because SWAP_ALPHA happens later */);
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+ if ((png_ptr->transformations & PNG_ENCODE_ALPHA) &&
+ (row_info->color_type & PNG_COLOR_MASK_ALPHA))
+ png_do_encode_alpha(row_info, png_ptr->row_buf + 1, png_ptr);
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+ if (png_ptr->transformations & PNG_SCALE_16_TO_8)
+ png_do_scale_16_to_8(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+ /* There is no harm in doing both of these because only one has any effect,
+ * by putting the 'scale' option first if the app asks for scale (either by
+ * calling the API or in a TRANSFORM flag) this is what happens.
+ */
+ if (png_ptr->transformations & PNG_16_TO_8)
+ png_do_chop(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ if (png_ptr->transformations & PNG_QUANTIZE)
+ {
+ png_do_quantize(row_info, png_ptr->row_buf + 1,
+ png_ptr->palette_lookup, png_ptr->quantize_index);
+
+ if (row_info->rowbytes == 0)
+ png_error(png_ptr, "png_do_quantize returned rowbytes=0");
+ }
+#endif /* PNG_READ_QUANTIZE_SUPPORTED */
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ /* Do the expansion now, after all the arithmetic has been done. Notice
+ * that previous transformations can handle the PNG_EXPAND_16 flag if this
+ * is efficient (particularly true in the case of gamma correction, where
+ * better accuracy results faster!)
+ */
+ if (png_ptr->transformations & PNG_EXPAND_16)
+ png_do_expand_16(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ /* NOTE: moved here in 1.5.4 (from much later in this list.) */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_INVERT_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_unshift(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_unpack(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Added at libpng-1.5.10 */
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ png_ptr->num_palette_max >= 0)
+ png_do_check_palette_indexes(png_ptr, row_info);
+#endif
+
+#ifdef PNG_READ_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_read_filler(row_info, png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_read_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_read_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+#ifdef PNG_READ_SWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if (png_ptr->read_user_transform_fn != NULL)
+ (*(png_ptr->read_user_transform_fn)) /* User read transform function */
+ (png_ptr, /* png_ptr */
+ row_info, /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_size_t rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+ if (png_ptr->user_transform_depth)
+ row_info->bit_depth = png_ptr->user_transform_depth;
+
+ if (png_ptr->user_transform_channels)
+ row_info->channels = png_ptr->user_transform_channels;
+#endif
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth *
+ row_info->channels);
+
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_info->width);
+ }
+#endif
+}
+
+#ifdef PNG_READ_PACK_SUPPORTED
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values. Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1. If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+void /* PRIVATE */
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_unpack");
+
+ if (row_info->bit_depth < 8)
+ {
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x01);
+
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x03);
+
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x0f);
+
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+/* Reverse the effects of png_do_shift. This routine merely shifts the
+ * pixels back to their significant bits values. Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+void /* PRIVATE */
+png_do_unshift(png_row_infop row_info, png_bytep row,
+ png_const_color_8p sig_bits)
+{
+ int color_type;
+
+ png_debug(1, "in png_do_unshift");
+
+ /* The palette case has already been handled in the _init routine. */
+ color_type = row_info->color_type;
+
+ if (color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift[4];
+ int channels = 0;
+ int bit_depth = row_info->bit_depth;
+
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift[channels++] = bit_depth - sig_bits->red;
+ shift[channels++] = bit_depth - sig_bits->green;
+ shift[channels++] = bit_depth - sig_bits->blue;
+ }
+
+ else
+ {
+ shift[channels++] = bit_depth - sig_bits->gray;
+ }
+
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift[channels++] = bit_depth - sig_bits->alpha;
+ }
+
+ {
+ int c, have_shift;
+
+ for (c = have_shift = 0; c < channels; ++c)
+ {
+ /* A shift of more than the bit depth is an error condition but it
+ * gets ignored here.
+ */
+ if (shift[c] <= 0 || shift[c] >= bit_depth)
+ shift[c] = 0;
+
+ else
+ have_shift = 1;
+ }
+
+ if (!have_shift)
+ return;
+ }
+
+ switch (bit_depth)
+ {
+ default:
+ /* Must be 1bpp gray: should not be here! */
+ /* NOTREACHED */
+ break;
+
+ case 2:
+ /* Must be 2bpp gray */
+ /* assert(channels == 1 && shift[0] == 1) */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+
+ while (bp < bp_end)
+ {
+ int b = (*bp >> 1) & 0x55;
+ *bp++ = (png_byte)b;
+ }
+ break;
+ }
+
+ case 4:
+ /* Must be 4bpp gray */
+ /* assert(channels == 1) */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+ int gray_shift = shift[0];
+ int mask = 0xf >> gray_shift;
+
+ mask |= mask << 4;
+
+ while (bp < bp_end)
+ {
+ int b = (*bp >> gray_shift) & mask;
+ *bp++ = (png_byte)b;
+ }
+ break;
+ }
+
+ case 8:
+ /* Single byte components, G, GA, RGB, RGBA */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+ int channel = 0;
+
+ while (bp < bp_end)
+ {
+ int b = *bp >> shift[channel];
+ if (++channel >= channels)
+ channel = 0;
+ *bp++ = (png_byte)b;
+ }
+ break;
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ case 16:
+ /* Double byte components, G, GA, RGB, RGBA */
+ {
+ png_bytep bp = row;
+ png_bytep bp_end = bp + row_info->rowbytes;
+ int channel = 0;
+
+ while (bp < bp_end)
+ {
+ int value = (bp[0] << 8) + bp[1];
+
+ value >>= shift[channel];
+ if (++channel >= channels)
+ channel = 0;
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ break;
+ }
+#endif
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+/* Scale rows of bit depth 16 down to 8 accurately */
+void /* PRIVATE */
+png_do_scale_16_to_8(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_scale_16_to_8");
+
+ if (row_info->bit_depth == 16)
+ {
+ png_bytep sp = row; /* source */
+ png_bytep dp = row; /* destination */
+ png_bytep ep = sp + row_info->rowbytes; /* end+1 */
+
+ while (sp < ep)
+ {
+ /* The input is an array of 16 bit components, these must be scaled to
+ * 8 bits each. For a 16 bit value V the required value (from the PNG
+ * specification) is:
+ *
+ * (V * 255) / 65535
+ *
+ * This reduces to round(V / 257), or floor((V + 128.5)/257)
+ *
+ * Represent V as the two byte value vhi.vlo. Make a guess that the
+ * result is the top byte of V, vhi, then the correction to this value
+ * is:
+ *
+ * error = floor(((V-vhi.vhi) + 128.5) / 257)
+ * = floor(((vlo-vhi) + 128.5) / 257)
+ *
+ * This can be approximated using integer arithmetic (and a signed
+ * shift):
+ *
+ * error = (vlo-vhi+128) >> 8;
+ *
+ * The approximate differs from the exact answer only when (vlo-vhi) is
+ * 128; it then gives a correction of +1 when the exact correction is
+ * 0. This gives 128 errors. The exact answer (correct for all 16 bit
+ * input values) is:
+ *
+ * error = (vlo-vhi+128)*65535 >> 24;
+ *
+ * An alternative arithmetic calculation which also gives no errors is:
+ *
+ * (V * 255 + 32895) >> 16
+ */
+
+ png_int_32 tmp = *sp++; /* must be signed! */
+ tmp += (((int)*sp++ - tmp + 128) * 65535) >> 24;
+ *dp++ = (png_byte)tmp;
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_info->width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+void /* PRIVATE */
+/* Simply discard the low byte. This was the default behavior prior
+ * to libpng-1.5.4.
+ */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_chop");
+
+ if (row_info->bit_depth == 16)
+ {
+ png_bytep sp = row; /* source */
+ png_bytep dp = row; /* destination */
+ png_bytep ep = sp + row_info->rowbytes; /* end+1 */
+
+ while (sp < ep)
+ {
+ *dp++ = *sp;
+ sp += 2; /* skip low byte */
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_info->width * row_info->channels;
+ }
+}
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_swap_alpha");
+
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from RGBA to ARGB */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ /* This converts from RRGGBBAA to AARRGGBB */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+#endif
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from GA to AG */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ /* This converts from GGAA to AAGG */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+#endif
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_uint_32 row_width;
+ png_debug(1, "in png_do_read_invert_alpha");
+
+ row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in RGBA */
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=3;
+ dp=sp;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can replace it with:
+*/
+ sp-=6;
+ dp=sp;
+ }
+ }
+#endif
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in GA */
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = *(--sp);
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ else
+ {
+ /* This inverts the alpha channel in GGAA */
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+/*
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+*/
+ sp-=2;
+ dp=sp;
+ }
+ }
+#endif
+ }
+}
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+/* Add filler channel if we have RGB color */
+void /* PRIVATE */
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+ png_uint_32 filler, png_uint_32 flags)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+#endif
+ png_byte lo_filler = (png_byte)(filler & 0xff);
+
+ png_debug(1, "in png_do_read_filler");
+
+ if (
+ row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This changes the data from G to GX */
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+
+ else
+ {
+ /* This changes the data from G to XG */
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This changes the data from GG to GGXX */
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+
+ else
+ {
+ /* This changes the data from GG to XXGG */
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+#endif
+ } /* COLOR_TYPE == GRAY */
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This changes the data from RGB to RGBX */
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+
+ else
+ {
+ /* This changes the data from RGB to XRGB */
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+
+#ifdef PNG_READ_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This changes the data from RRGGBB to RRGGBBXX */
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+
+ else
+ {
+ /* This changes the data from RRGGBB to XXRRGGBB */
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ }
+#endif
+ } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand grayscale files to RGB, with or without alpha */
+void /* PRIVATE */
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_debug(1, "in png_do_gray_to_rgb");
+
+ if (row_info->bit_depth >= 8 &&
+ !(row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This changes G to RGB */
+ png_bytep sp = row + (png_size_t)row_width - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+
+ else
+ {
+ /* This changes GG to RRGGBB */
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This changes GA to RGBA */
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+
+ else
+ {
+ /* This changes GGAA to RRGGBBAA */
+ png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ row_info->channels = (png_byte)(row_info->channels + 2);
+ row_info->color_type |= PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+}
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ of 1998-01-04 at
+ * <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but
+ * versions dated 1998 through November 2002 have been archived at
+ * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
+ * ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
+ * Charles Poynton poynton at poynton.com
+ *
+ * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ * which can be expressed with integers as
+ *
+ * Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ * Poynton's current link (as of January 2003 through July 2011):
+ * <http://www.poynton.com/notes/colour_and_gamma/>
+ * has changed the numbers slightly:
+ *
+ * Y = 0.2126*R + 0.7152*G + 0.0722*B
+ *
+ * which can be expressed with integers as
+ *
+ * Y = (6966 * R + 23436 * G + 2366 * B)/32768
+ *
+ * Historically, however, libpng uses numbers derived from the ITU-R Rec 709
+ * end point chromaticities and the D65 white point. Depending on the
+ * precision used for the D65 white point this produces a variety of different
+ * numbers, however if the four decimal place value used in ITU-R Rec 709 is
+ * used (0.3127,0.3290) the Y calculation would be:
+ *
+ * Y = (6968 * R + 23435 * G + 2366 * B)/32768
+ *
+ * While this is correct the rounding results in an overflow for white, because
+ * the sum of the rounded coefficients is 32769, not 32768. Consequently
+ * libpng uses, instead, the closest non-overflowing approximation:
+ *
+ * Y = (6968 * R + 23434 * G + 2366 * B)/32768
+ *
+ * Starting with libpng-1.5.5, if the image being converted has a cHRM chunk
+ * (including an sRGB chunk) then the chromaticities are used to calculate the
+ * coefficients. See the chunk handling in pngrutil.c for more information.
+ *
+ * In all cases the calculation is to be done in a linear colorspace. If no
+ * gamma information is available to correct the encoding of the original RGB
+ * values this results in an implicit assumption that the original PNG RGB
+ * values were linear.
+ *
+ * Other integer coefficents can be used via png_set_rgb_to_gray(). Because
+ * the API takes just red and green coefficients the blue coefficient is
+ * calculated to make the sum 32768. This will result in different rounding
+ * to that used above.
+ */
+int /* PRIVATE */
+png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+ int rgb_error = 0;
+
+ png_debug(1, "in png_do_rgb_to_gray");
+
+ if (!(row_info->color_type & PNG_COLOR_MASK_PALETTE) &&
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+ PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+ PNG_CONST png_uint_32 bc = 32768 - rc - gc;
+ PNG_CONST png_uint_32 row_width = row_info->width;
+ PNG_CONST int have_alpha =
+ (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0;
+
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ /* Notice that gamma to/from 1 are not necessarily inverses (if
+ * there is an overall gamma correction). Prior to 1.5.5 this code
+ * checked the linearized values for equality; this doesn't match
+ * the documentation, the original values must be checked.
+ */
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+
+ if (red != green || red != blue)
+ {
+ red = png_ptr->gamma_to_1[red];
+ green = png_ptr->gamma_to_1[green];
+ blue = png_ptr->gamma_to_1[blue];
+
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1[
+ (rc*red + gc*green + bc*blue + 16384)>>15];
+ }
+
+ else
+ {
+ /* If there is no overall correction the table will not be
+ * set.
+ */
+ if (png_ptr->gamma_table != NULL)
+ red = png_ptr->gamma_table[red];
+
+ *(dp++) = red;
+ }
+
+ if (have_alpha)
+ *(dp++) = *(sp++);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+
+ if (red != green || red != blue)
+ {
+ rgb_error |= 1;
+ /* NOTE: this is the historical approach which simply
+ * truncates the results.
+ */
+ *(dp++) = (png_byte)((rc*red + gc*green + bc*blue)>>15);
+ }
+
+ else
+ *(dp++) = red;
+
+ if (have_alpha)
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+
+ else /* RGB bit_depth == 16 */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (png_ptr->gamma_16_to_1 != NULL && png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+
+ if (red == green && red == blue)
+ {
+ if (png_ptr->gamma_16_table != NULL)
+ w = png_ptr->gamma_16_table[(red&0xff)
+ >> png_ptr->gamma_shift][red>>8];
+
+ else
+ w = red;
+ }
+
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff)
+ >> png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 =
+ png_ptr->gamma_16_to_1[(green&0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff)
+ >> png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ + bc*blue_1 + 16384)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+
+ if (have_alpha)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp + 1)); sp += 2;
+
+ if (red != green || red != blue)
+ rgb_error |= 1;
+
+ /* From 1.5.5 in the 16 bit case do the accurate conversion even
+ * in the 'fast' case - this is because this is where the code
+ * ends up when handling linear 16 bit data.
+ */
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue + 16384) >>
+ 15);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+
+ if (have_alpha)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+ }
+
+ row_info->channels = (png_byte)(row_info->channels - 2);
+ row_info->color_type = (png_byte)(row_info->color_type &
+ ~PNG_COLOR_MASK_COLOR);
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ return rgb_error;
+}
+#endif
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
+ * large of png_color. This lets grayscale images be treated as
+ * paletted. Most useful for gamma correction and simplification
+ * of code. This API is not used internally.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+ int num_palette;
+ int color_inc;
+ int i;
+ int v;
+
+ png_debug(1, "in png_do_build_grayscale_palette");
+
+ if (palette == NULL)
+ return;
+
+ switch (bit_depth)
+ {
+ case 1:
+ num_palette = 2;
+ color_inc = 0xff;
+ break;
+
+ case 2:
+ num_palette = 4;
+ color_inc = 0x55;
+ break;
+
+ case 4:
+ num_palette = 16;
+ color_inc = 0x11;
+ break;
+
+ case 8:
+ num_palette = 256;
+ color_inc = 1;
+ break;
+
+ default:
+ num_palette = 0;
+ color_inc = 0;
+ break;
+ }
+
+ for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+ {
+ palette[i].red = (png_byte)v;
+ palette[i].green = (png_byte)v;
+ palette[i].blue = (png_byte)v;
+ }
+}
+#endif
+
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0. Paletted files have already been taken care of.
+ */
+void /* PRIVATE */
+png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_const_bytep gamma_table = png_ptr->gamma_table;
+ png_const_bytep gamma_from_1 = png_ptr->gamma_from_1;
+ png_const_bytep gamma_to_1 = png_ptr->gamma_to_1;
+ png_const_uint_16pp gamma_16 = png_ptr->gamma_16_table;
+ png_const_uint_16pp gamma_16_from_1 = png_ptr->gamma_16_from_1;
+ png_const_uint_16pp gamma_16_to_1 = png_ptr->gamma_16_to_1;
+ int gamma_shift = png_ptr->gamma_shift;
+ int optimize = (png_ptr->flags & PNG_FLAG_OPTIMIZE_ALPHA) != 0;
+#endif
+
+ png_bytep sp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ int shift;
+
+ png_debug(1, "in png_do_compose");
+
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row;
+ shift = 7;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x01)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x7f7f >> (7 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (!shift)
+ {
+ shift = 7;
+ sp++;
+ }
+
+ else
+ shift--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ else
+ {
+ unsigned int p = (*sp >> shift) & 0x03;
+ unsigned int g = (gamma_table [p | (p << 2) |
+ (p << 4) | (p << 6)] >> 6) & 0x03;
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |= g << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+
+ else
+ shift -= 2;
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0x3f3f >> (6 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+
+ else
+ shift -= 2;
+ }
+ }
+ break;
+ }
+
+ case 4:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ else
+ {
+ unsigned int p = (*sp >> shift) & 0x0f;
+ unsigned int g = (gamma_table[p | (p << 4)] >> 4) &
+ 0x0f;
+ unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+ tmp |= g << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+
+ else
+ shift -= 4;
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == png_ptr->trans_color.gray)
+ {
+ unsigned int tmp = *sp & (0xf0f >> (4 - shift));
+ tmp |= png_ptr->background.gray << shift;
+ *sp = (png_byte)(tmp & 0xff);
+ }
+
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+
+ else
+ shift -= 4;
+ }
+ }
+ break;
+ }
+
+ case 8:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == png_ptr->trans_color.gray)
+ *sp = (png_byte)png_ptr->background.gray;
+
+ else
+ *sp = gamma_table[*sp];
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == png_ptr->trans_color.gray)
+ *sp = (png_byte)png_ptr->background.gray;
+ }
+ }
+ break;
+ }
+
+ case 16:
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ if (v == png_ptr->trans_color.gray)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray
+ & 0xff);
+ }
+
+ else
+ {
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ if (v == png_ptr->trans_color.gray)
+ {
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray
+ & 0xff);
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == png_ptr->trans_color.red &&
+ *(sp + 1) == png_ptr->trans_color.green &&
+ *(sp + 2) == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == png_ptr->trans_color.red &&
+ *(sp + 1) == png_ptr->trans_color.green &&
+ *(sp + 2) == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ if (r == png_ptr->trans_color.red &&
+ g == png_ptr->trans_color.green &&
+ b == png_ptr->trans_color.blue)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ if (r == png_ptr->trans_color.red &&
+ g == png_ptr->trans_color.green &&
+ b == png_ptr->trans_color.blue)
+ {
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 a = *(sp + 1);
+
+ if (a == 0xff)
+ *sp = gamma_table[*sp];
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)png_ptr->background.gray;
+ }
+
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, png_ptr->background_1.gray);
+ if (!optimize)
+ w = gamma_from_1[w];
+ *sp = w;
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_byte a = *(sp + 1);
+
+ if (a == 0)
+ *sp = (png_byte)png_ptr->background.gray;
+
+ else if (a < 0xff)
+ png_composite(*sp, *sp, a, png_ptr->background.gray);
+ }
+ }
+ }
+ else /* if (png_ptr->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 g, v, w;
+
+ g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(v, g, a, png_ptr->background_1.gray);
+ if (optimize)
+ w = v;
+ else
+ w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+ *sp = (png_byte)((w >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(w & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+
+ if (a == 0)
+ {
+ *sp = (png_byte)((png_ptr->background.gray >> 8)
+ & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.gray & 0xff);
+ }
+
+ else if (a < 0xffff)
+ {
+ png_uint_16 g, v;
+
+ g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_composite_16(v, g, a, png_ptr->background.gray);
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, png_ptr->background_1.red);
+ if (!optimize) w = gamma_from_1[w];
+ *sp = w;
+
+ v = gamma_to_1[*(sp + 1)];
+ png_composite(w, v, a, png_ptr->background_1.green);
+ if (!optimize) w = gamma_from_1[w];
+ *(sp + 1) = w;
+
+ v = gamma_to_1[*(sp + 2)];
+ png_composite(w, v, a, png_ptr->background_1.blue);
+ if (!optimize) w = gamma_from_1[w];
+ *(sp + 2) = w;
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 4)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0)
+ {
+ *sp = (png_byte)png_ptr->background.red;
+ *(sp + 1) = (png_byte)png_ptr->background.green;
+ *(sp + 2) = (png_byte)png_ptr->background.blue;
+ }
+
+ else if (a < 0xff)
+ {
+ png_composite(*sp, *sp, a, png_ptr->background.red);
+
+ png_composite(*(sp + 1), *(sp + 1), a,
+ png_ptr->background.green);
+
+ png_composite(*(sp + 2), *(sp + 2), a,
+ png_ptr->background.blue);
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 8)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+
+ else if (a == 0)
+ {
+ /* Background is already in screen gamma */
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else
+ {
+ png_uint_16 v, w;
+
+ v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(w, v, a, png_ptr->background_1.red);
+ if (!optimize)
+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+ 8];
+ *sp = (png_byte)((w >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(w & 0xff);
+
+ v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ png_composite_16(w, v, a, png_ptr->background_1.green);
+ if (!optimize)
+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+ 8];
+
+ *(sp + 2) = (png_byte)((w >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(w & 0xff);
+
+ v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ png_composite_16(w, v, a, png_ptr->background_1.blue);
+ if (!optimize)
+ w = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >>
+ 8];
+
+ *(sp + 4) = (png_byte)((w >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(w & 0xff);
+ }
+ }
+ }
+
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 8)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+
+ if (a == 0)
+ {
+ *sp = (png_byte)((png_ptr->background.red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(png_ptr->background.red & 0xff);
+ *(sp + 2) = (png_byte)((png_ptr->background.green >> 8)
+ & 0xff);
+ *(sp + 3) = (png_byte)(png_ptr->background.green
+ & 0xff);
+ *(sp + 4) = (png_byte)((png_ptr->background.blue >> 8)
+ & 0xff);
+ *(sp + 5) = (png_byte)(png_ptr->background.blue & 0xff);
+ }
+
+ else if (a < 0xffff)
+ {
+ png_uint_16 v;
+
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ png_composite_16(v, r, a, png_ptr->background.red);
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+
+ png_composite_16(v, g, a, png_ptr->background.green);
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+
+ png_composite_16(v, b, a, png_ptr->background.blue);
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_READ_ALPHA_MODE_SUPPORTED */
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Gamma correct the image, avoiding the alpha channel. Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift. Build these with
+ * build_gamma_table().
+ */
+void /* PRIVATE */
+png_do_gamma(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+ png_const_bytep gamma_table = png_ptr->gamma_table;
+ png_const_uint_16pp gamma_16_table = png_ptr->gamma_16_table;
+ int gamma_shift = png_ptr->gamma_shift;
+
+ png_bytep sp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_gamma");
+
+ if (((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+ (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+
+ *sp = gamma_table[*sp];
+ sp++;
+
+ *sp = gamma_table[*sp];
+ sp++;
+
+ sp++;
+ }
+ }
+
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp += 2;
+ }
+ }
+
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ if (row_info->bit_depth == 2)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 4)
+ {
+ int a = *sp & 0xc0;
+ int b = *sp & 0x30;
+ int c = *sp & 0x0c;
+ int d = *sp & 0x03;
+
+ *sp = (png_byte)(
+ ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
+ ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+ ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+ ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+ sp++;
+ }
+ }
+
+ if (row_info->bit_depth == 4)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 2)
+ {
+ int msb = *sp & 0xf0;
+ int lsb = *sp & 0x0f;
+
+ *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+ | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+ sp++;
+ }
+ }
+
+ else if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+/* Encode the alpha channel to the output gamma (the input channel is always
+ * linear.) Called only with color types that have an alpha channel. Needs the
+ * from_1 tables.
+ */
+void /* PRIVATE */
+png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
+{
+ png_uint_32 row_width = row_info->width;
+
+ png_debug(1, "in png_do_encode_alpha");
+
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ PNG_CONST png_bytep table = png_ptr->gamma_from_1;
+
+ if (table != NULL)
+ {
+ PNG_CONST int step =
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2;
+
+ /* The alpha channel is the last component: */
+ row += step - 1;
+
+ for (; row_width > 0; --row_width, row += step)
+ *row = table[*row];
+
+ return;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1;
+ PNG_CONST int gamma_shift = png_ptr->gamma_shift;
+
+ if (table != NULL)
+ {
+ PNG_CONST int step =
+ (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4;
+
+ /* The alpha channel is the last component: */
+ row += step - 2;
+
+ for (; row_width > 0; --row_width, row += step)
+ {
+ png_uint_16 v;
+
+ v = table[*(row + 1) >> gamma_shift][*row];
+ *row = (png_byte)((v >> 8) & 0xff);
+ *(row + 1) = (png_byte)(v & 0xff);
+ }
+
+ return;
+ }
+ }
+ }
+
+ /* Only get to here if called with a weird row_info; no harm has been done,
+ * so just issue a warning.
+ */
+ png_warning(png_ptr, "png_do_encode_alpha: unexpected call");
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+void /* PRIVATE */
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+ png_const_colorp palette, png_const_bytep trans_alpha, int num_trans)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand_palette");
+
+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 1;
+
+ else
+ *dp = 0;
+
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)value;
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((row_width & 0x01) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)value;
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 4;
+
+ dp--;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+
+ if (row_info->bit_depth == 8)
+ {
+ {
+ if (num_trans > 0)
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if ((int)(*sp) >= num_trans)
+ *dp-- = 0xff;
+
+ else
+ *dp-- = trans_alpha[*sp];
+
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ row_info->color_type = 6;
+ row_info->channels = 4;
+ }
+
+ else
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width * 3) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ row_info->color_type = 2;
+ row_info->channels = 3;
+ }
+ }
+ }
+ }
+}
+
+/* If the bit depth < 8, it is expanded to 8. Also, if the already
+ * expanded transparency value is supplied, an alpha channel is built.
+ */
+void /* PRIVATE */
+png_do_expand(png_row_infop row_info, png_bytep row,
+ png_const_color_16p trans_color)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand");
+
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ unsigned int gray = trans_color ? trans_color->gray : 0;
+
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ gray = (gray & 0x01) * 0xff;
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 0xff;
+
+ else
+ *dp = 0;
+
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ gray = (gray & 0x03) * 0x55;
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)(value | (value << 2) | (value << 4) |
+ (value << 6));
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ gray = (gray & 0x0f) * 0x11;
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)(value | (value << 4));
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+
+ if (trans_color != NULL)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ gray = gray & 0xff;
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 1) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp == gray)
+ *dp-- = 0;
+
+ else
+ *dp-- = 0xff;
+
+ *dp-- = *sp--;
+ }
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ unsigned int gray_high = (gray >> 8) & 0xff;
+ unsigned int gray_low = gray & 0xff;
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (row_info->rowbytes << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 1) == gray_high && *(sp) == gray_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ row_info->channels = 2;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_width);
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_color)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_byte red = (png_byte)(trans_color->red & 0xff);
+ png_byte green = (png_byte)(trans_color->green & 0xff);
+ png_byte blue = (png_byte)(trans_color->blue & 0xff);
+ sp = row + (png_size_t)row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 2) == red && *(sp - 1) == green && *(sp) == blue)
+ *dp-- = 0;
+
+ else
+ *dp-- = 0xff;
+
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_byte red_high = (png_byte)((trans_color->red >> 8) & 0xff);
+ png_byte green_high = (png_byte)((trans_color->green >> 8) & 0xff);
+ png_byte blue_high = (png_byte)((trans_color->blue >> 8) & 0xff);
+ png_byte red_low = (png_byte)(trans_color->red & 0xff);
+ png_byte green_low = (png_byte)(trans_color->green & 0xff);
+ png_byte blue_low = (png_byte)(trans_color->blue & 0xff);
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 3) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 5) == red_high &&
+ *(sp - 4) == red_low &&
+ *(sp - 3) == green_high &&
+ *(sp - 2) == green_low &&
+ *(sp - 1) == blue_high &&
+ *(sp ) == blue_low)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ row_info->channels = 4;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+ }
+}
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* If the bit depth is 8 and the color type is not a palette type expand the
+ * whole row to 16 bits. Has no effect otherwise.
+ */
+void /* PRIVATE */
+png_do_expand_16(png_row_infop row_info, png_bytep row)
+{
+ if (row_info->bit_depth == 8 &&
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ /* The row have a sequence of bytes containing [0..255] and we need
+ * to turn it into another row containing [0..65535], to do this we
+ * calculate:
+ *
+ * (input / 255) * 65535
+ *
+ * Which happens to be exactly input * 257 and this can be achieved
+ * simply by byte replication in place (copying backwards).
+ */
+ png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
+ png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */
+ while (dp > sp)
+ dp[-2] = dp[-1] = *--sp, dp -= 2;
+
+ row_info->rowbytes *= 2;
+ row_info->bit_depth = 16;
+ row_info->pixel_depth = (png_byte)(row_info->channels * 16);
+ }
+}
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+void /* PRIVATE */
+png_do_quantize(png_row_infop row_info, png_bytep row,
+ png_const_bytep palette_lookup, png_const_bytep quantize_lookup)
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_quantize");
+
+ if (row_info->bit_depth == 8)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB && palette_lookup)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+
+ /* This looks real messy, but the compiler will reduce
+ * it down to a reasonable formula. For example, with
+ * 5 bits per color, we get:
+ * p = (((r >> 3) & 0x1f) << 10) |
+ * (((g >> 3) & 0x1f) << 5) |
+ * ((b >> 3) & 0x1f);
+ */
+ p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
+ ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
+ (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
+ (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
+ ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
+ (PNG_QUANTIZE_BLUE_BITS)) |
+ ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
+ ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ palette_lookup != NULL)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+ sp++;
+
+ p = (((r >> (8 - PNG_QUANTIZE_RED_BITS)) &
+ ((1 << PNG_QUANTIZE_RED_BITS) - 1)) <<
+ (PNG_QUANTIZE_GREEN_BITS + PNG_QUANTIZE_BLUE_BITS)) |
+ (((g >> (8 - PNG_QUANTIZE_GREEN_BITS)) &
+ ((1 << PNG_QUANTIZE_GREEN_BITS) - 1)) <<
+ (PNG_QUANTIZE_BLUE_BITS)) |
+ ((b >> (8 - PNG_QUANTIZE_BLUE_BITS)) &
+ ((1 << PNG_QUANTIZE_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, row_width);
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ quantize_lookup)
+ {
+ sp = row;
+
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ *sp = quantize_lookup[*sp];
+ }
+ }
+ }
+}
+#endif /* PNG_READ_QUANTIZE_SUPPORTED */
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_intrapixel");
+
+ if (
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((256 + *rp + *(rp + 1)) & 0xff);
+ *(rp+2) = (png_byte)((256 + *(rp + 2) + *(rp + 1)) & 0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
+ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
+ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
+ png_uint_32 red = (s0 + s1 + 65536) & 0xffff;
+ png_uint_32 blue = (s2 + s1 + 65536) & 0xffff;
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp + 1) = (png_byte)(red & 0xff);
+ *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp + 5) = (png_byte)(blue & 0xff);
+ }
+ }
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrutil.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrutil.c
new file mode 100644
index 0000000000..d12395a18d
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngrutil.c
@@ -0,0 +1,4473 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * Last changed in libpng 1.6.3 [July 18, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file contains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#include "pngpriv.h"
+
+#ifdef PNG_READ_SUPPORTED
+
+png_uint_32 PNGAPI
+png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
+{
+ png_uint_32 uval = png_get_uint_32(buf);
+
+ if (uval > PNG_UINT_31_MAX)
+ png_error(png_ptr, "PNG unsigned integer out of range");
+
+ return (uval);
+}
+
+#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED)
+/* The following is a variation on the above for use with the fixed
+ * point values used for gAMA and cHRM. Instead of png_error it
+ * issues a warning and returns (-1) - an invalid value because both
+ * gAMA and cHRM use *unsigned* integers for fixed point values.
+ */
+#define PNG_FIXED_ERROR (-1)
+
+static png_fixed_point /* PRIVATE */
+png_get_fixed_point(png_structrp png_ptr, png_const_bytep buf)
+{
+ png_uint_32 uval = png_get_uint_32(buf);
+
+ if (uval <= PNG_UINT_31_MAX)
+ return (png_fixed_point)uval; /* known to be in range */
+
+ /* The caller can turn off the warning by passing NULL. */
+ if (png_ptr != NULL)
+ png_warning(png_ptr, "PNG fixed point integer out of range");
+
+ return PNG_FIXED_ERROR;
+}
+#endif
+
+#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
+/* NOTE: the read macros will obscure these definitions, so that if
+ * PNG_USE_READ_MACROS is set the library will not use them internally,
+ * but the APIs will still be available externally.
+ *
+ * The parentheses around "PNGAPI function_name" in the following three
+ * functions are necessary because they allow the macros to co-exist with
+ * these (unused but exported) functions.
+ */
+
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 (PNGAPI
+png_get_uint_32)(png_const_bytep buf)
+{
+ png_uint_32 uval =
+ ((png_uint_32)(*(buf )) << 24) +
+ ((png_uint_32)(*(buf + 1)) << 16) +
+ ((png_uint_32)(*(buf + 2)) << 8) +
+ ((png_uint_32)(*(buf + 3)) ) ;
+
+ return uval;
+}
+
+/* Grab a signed 32-bit integer from a buffer in big-endian format. The
+ * data is stored in the PNG file in two's complement format and there
+ * is no guarantee that a 'png_int_32' is exactly 32 bits, therefore
+ * the following code does a two's complement to native conversion.
+ */
+png_int_32 (PNGAPI
+png_get_int_32)(png_const_bytep buf)
+{
+ png_uint_32 uval = png_get_uint_32(buf);
+ if ((uval & 0x80000000) == 0) /* non-negative */
+ return uval;
+
+ uval = (uval ^ 0xffffffff) + 1; /* 2's complement: -x = ~x+1 */
+ return -(png_int_32)uval;
+}
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 (PNGAPI
+png_get_uint_16)(png_const_bytep buf)
+{
+ /* ANSI-C requires an int value to accomodate at least 16 bits so this
+ * works and allows the compiler not to worry about possible narrowing
+ * on 32 bit systems. (Pre-ANSI systems did not make integers smaller
+ * than 16 bits either.)
+ */
+ unsigned int val =
+ ((unsigned int)(*buf) << 8) +
+ ((unsigned int)(*(buf + 1)));
+
+ return (png_uint_16)val;
+}
+
+#endif /* PNG_READ_INT_FUNCTIONS_SUPPORTED */
+
+/* Read and check the PNG file signature */
+void /* PRIVATE */
+png_read_sig(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_size_t num_checked, num_to_check;
+
+ /* Exit if the user application does not expect a signature. */
+ if (png_ptr->sig_bytes >= 8)
+ return;
+
+ num_checked = png_ptr->sig_bytes;
+ num_to_check = 8 - num_checked;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_SIGNATURE;
+#endif
+
+ /* The signature must be serialized in a single I/O call. */
+ png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+ png_ptr->sig_bytes = 8;
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ if (num_checked < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Read the chunk header (length + type name).
+ * Put the type name into png_ptr->chunk_name, and return the length.
+ */
+png_uint_32 /* PRIVATE */
+png_read_chunk_header(png_structrp png_ptr)
+{
+ png_byte buf[8];
+ png_uint_32 length;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
+#endif
+
+ /* Read the length and the chunk name.
+ * This must be performed in a single I/O call.
+ */
+ png_read_data(png_ptr, buf, 8);
+ length = png_get_uint_31(png_ptr, buf);
+
+ /* Put the chunk name into png_ptr->chunk_name. */
+ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4);
+
+ png_debug2(0, "Reading %lx chunk, length = %lu",
+ (unsigned long)png_ptr->chunk_name, (unsigned long)length);
+
+ /* Reset the crc and run it over the chunk name. */
+ png_reset_crc(png_ptr);
+ png_calculate_crc(png_ptr, buf + 4, 4);
+
+ /* Check to see if chunk name is valid. */
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
+#endif
+
+ return length;
+}
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structrp png_ptr, png_bytep buf, png_uint_32 length)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_read_data(png_ptr, buf, length);
+ png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC. Depending on whether we
+ * are reading an ancillary or critical chunk, and how the program has set
+ * things up, we may calculate the CRC on the data and print a message.
+ * Returns '1' if there was a CRC error, '0' otherwise.
+ */
+int /* PRIVATE */
+png_crc_finish(png_structrp png_ptr, png_uint_32 skip)
+{
+ /* The size of the local buffer for inflate is a good guess as to a
+ * reasonable size to use for buffering reads from the application.
+ */
+ while (skip > 0)
+ {
+ png_uint_32 len;
+ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
+
+ len = (sizeof tmpbuf);
+ if (len > skip)
+ len = skip;
+ skip -= len;
+
+ png_crc_read(png_ptr, tmpbuf, len);
+ }
+
+ if (png_crc_error(png_ptr))
+ {
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name) ?
+ !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) :
+ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+
+ else
+ {
+ png_chunk_benign_error(png_ptr, "CRC error");
+ return (0);
+ }
+
+ return (1);
+ }
+
+ return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ * the data it has read thus far.
+ */
+int /* PRIVATE */
+png_crc_error(png_structrp png_ptr)
+{
+ png_byte crc_bytes[4];
+ png_uint_32 crc;
+ int need_crc = 1;
+
+ if (PNG_CHUNK_ANCILLARY(png_ptr->chunk_name))
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
+#endif
+
+ /* The chunk CRC must be serialized in a single I/O call. */
+ png_read_data(png_ptr, crc_bytes, 4);
+
+ if (need_crc)
+ {
+ crc = png_get_uint_32(crc_bytes);
+ return ((int)(crc != png_ptr->crc));
+ }
+
+ else
+ return (0);
+}
+
+/* Manage the read buffer; this simply reallocates the buffer if it is not small
+ * enough (or if it is not allocated). The routine returns a pointer to the
+ * buffer; if an error occurs and 'warn' is set the routine returns NULL, else
+ * it will call png_error (via png_malloc) on failure. (warn == 2 means
+ * 'silent').
+ */
+static png_bytep
+png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
+{
+ png_bytep buffer = png_ptr->read_buffer;
+
+ if (buffer != NULL && new_size > png_ptr->read_buffer_size)
+ {
+ png_ptr->read_buffer = NULL;
+ png_ptr->read_buffer = NULL;
+ png_ptr->read_buffer_size = 0;
+ png_free(png_ptr, buffer);
+ buffer = NULL;
+ }
+
+ if (buffer == NULL)
+ {
+ buffer = png_voidcast(png_bytep, png_malloc_base(png_ptr, new_size));
+
+ if (buffer != NULL)
+ {
+ png_ptr->read_buffer = buffer;
+ png_ptr->read_buffer_size = new_size;
+ }
+
+ else if (warn < 2) /* else silent */
+ {
+#ifdef PNG_WARNINGS_SUPPORTED
+ if (warn)
+ png_chunk_warning(png_ptr, "insufficient memory to read chunk");
+ else
+#endif
+ {
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+ png_chunk_error(png_ptr, "insufficient memory to read chunk");
+#endif
+ }
+ }
+ }
+
+ return buffer;
+}
+
+/* png_inflate_claim: claim the zstream for some nefarious purpose that involves
+ * decompression. Returns Z_OK on success, else a zlib error code. It checks
+ * the owner but, in final release builds, just issues a warning if some other
+ * chunk apparently owns the stream. Prior to release it does a png_error.
+ */
+static int
+png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
+{
+ if (png_ptr->zowner != 0)
+ {
+ char msg[64];
+
+ PNG_STRING_FROM_CHUNK(msg, png_ptr->zowner);
+ /* So the message that results is "<chunk> using zstream"; this is an
+ * internal error, but is very useful for debugging. i18n requirements
+ * are minimal.
+ */
+ (void)png_safecat(msg, (sizeof msg), 4, " using zstream");
+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+ png_chunk_warning(png_ptr, msg);
+ png_ptr->zowner = 0;
+# else
+ png_chunk_error(png_ptr, msg);
+# endif
+ }
+
+ /* Implementation note: unlike 'png_deflate_claim' this internal function
+ * does not take the size of the data as an argument. Some efficiency could
+ * be gained by using this when it is known *if* the zlib stream itself does
+ * not record the number; however, this is an illusion: the original writer
+ * of the PNG may have selected a lower window size, and we really must
+ * follow that because, for systems with with limited capabilities, we
+ * would otherwise reject the application's attempts to use a smaller window
+ * size (zlib doesn't have an interface to say "this or lower"!).
+ *
+ * inflateReset2 was added to zlib 1.2.4; before this the window could not be
+ * reset, therefore it is necessary to always allocate the maximum window
+ * size with earlier zlibs just in case later compressed chunks need it.
+ */
+ {
+ int ret; /* zlib return code */
+# if PNG_ZLIB_VERNUM >= 0x1240
+
+# if defined(PNG_SET_OPTION_SUPPORTED) && \
+ defined(PNG_MAXIMUM_INFLATE_WINDOW)
+ int window_bits;
+
+ if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
+ PNG_OPTION_ON)
+ window_bits = 15;
+
+ else
+ window_bits = 0;
+# else
+# define window_bits 0
+# endif
+# endif
+
+ /* Set this for safety, just in case the previous owner left pointers to
+ * memory allocations.
+ */
+ png_ptr->zstream.next_in = NULL;
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->zstream.next_out = NULL;
+ png_ptr->zstream.avail_out = 0;
+
+ if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
+ {
+# if PNG_ZLIB_VERNUM < 0x1240
+ ret = inflateReset(&png_ptr->zstream);
+# else
+ ret = inflateReset2(&png_ptr->zstream, window_bits);
+# endif
+ }
+
+ else
+ {
+# if PNG_ZLIB_VERNUM < 0x1240
+ ret = inflateInit(&png_ptr->zstream);
+# else
+ ret = inflateInit2(&png_ptr->zstream, window_bits);
+# endif
+
+ if (ret == Z_OK)
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
+ }
+
+ if (ret == Z_OK)
+ png_ptr->zowner = owner;
+
+ else
+ png_zstream_error(png_ptr, ret);
+
+ return ret;
+ }
+
+# ifdef window_bits
+# undef window_bits
+# endif
+}
+
+#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
+/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
+ * allow the caller to do multiple calls if required. If the 'finish' flag is
+ * set Z_FINISH will be passed to the final inflate() call and Z_STREAM_END must
+ * be returned or there has been a problem, otherwise Z_SYNC_FLUSH is used and
+ * Z_OK or Z_STREAM_END will be returned on success.
+ *
+ * The input and output sizes are updated to the actual amounts of data consumed
+ * or written, not the amount available (as in a z_stream). The data pointers
+ * are not changed, so the next input is (data+input_size) and the next
+ * available output is (output+output_size).
+ */
+static int
+png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
+ /* INPUT: */ png_const_bytep input, png_uint_32p input_size_ptr,
+ /* OUTPUT: */ png_bytep output, png_alloc_size_t *output_size_ptr)
+{
+ if (png_ptr->zowner == owner) /* Else not claimed */
+ {
+ int ret;
+ png_alloc_size_t avail_out = *output_size_ptr;
+ png_uint_32 avail_in = *input_size_ptr;
+
+ /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it
+ * can't even necessarily handle 65536 bytes) because the type uInt is
+ * "16 bits or more". Consequently it is necessary to chunk the input to
+ * zlib. This code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the
+ * maximum value that can be stored in a uInt.) It is possible to set
+ * ZLIB_IO_MAX to a lower value in pngpriv.h and this may sometimes have
+ * a performance advantage, because it reduces the amount of data accessed
+ * at each step and that may give the OS more time to page it in.
+ */
+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
+ /* avail_in and avail_out are set below from 'size' */
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->zstream.avail_out = 0;
+
+ /* Read directly into the output if it is available (this is set to
+ * a local buffer below if output is NULL).
+ */
+ if (output != NULL)
+ png_ptr->zstream.next_out = output;
+
+ do
+ {
+ uInt avail;
+ Byte local_buffer[PNG_INFLATE_BUF_SIZE];
+
+ /* zlib INPUT BUFFER */
+ /* The setting of 'avail_in' used to be outside the loop; by setting it
+ * inside it is possible to chunk the input to zlib and simply rely on
+ * zlib to advance the 'next_in' pointer. This allows arbitrary
+ * amounts of data to be passed through zlib at the unavoidable cost of
+ * requiring a window save (memcpy of up to 32768 output bytes)
+ * every ZLIB_IO_MAX input bytes.
+ */
+ avail_in += png_ptr->zstream.avail_in; /* not consumed last time */
+
+ avail = ZLIB_IO_MAX;
+
+ if (avail_in < avail)
+ avail = (uInt)avail_in; /* safe: < than ZLIB_IO_MAX */
+
+ avail_in -= avail;
+ png_ptr->zstream.avail_in = avail;
+
+ /* zlib OUTPUT BUFFER */
+ avail_out += png_ptr->zstream.avail_out; /* not written last time */
+
+ avail = ZLIB_IO_MAX; /* maximum zlib can process */
+
+ if (output == NULL)
+ {
+ /* Reset the output buffer each time round if output is NULL and
+ * make available the full buffer, up to 'remaining_space'
+ */
+ png_ptr->zstream.next_out = local_buffer;
+ if ((sizeof local_buffer) < avail)
+ avail = (sizeof local_buffer);
+ }
+
+ if (avail_out < avail)
+ avail = (uInt)avail_out; /* safe: < ZLIB_IO_MAX */
+
+ png_ptr->zstream.avail_out = avail;
+ avail_out -= avail;
+
+ /* zlib inflate call */
+ /* In fact 'avail_out' may be 0 at this point, that happens at the end
+ * of the read when the final LZ end code was not passed at the end of
+ * the previous chunk of input data. Tell zlib if we have reached the
+ * end of the output buffer.
+ */
+ ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH :
+ (finish ? Z_FINISH : Z_SYNC_FLUSH));
+ } while (ret == Z_OK);
+
+ /* For safety kill the local buffer pointer now */
+ if (output == NULL)
+ png_ptr->zstream.next_out = NULL;
+
+ /* Claw back the 'size' and 'remaining_space' byte counts. */
+ avail_in += png_ptr->zstream.avail_in;
+ avail_out += png_ptr->zstream.avail_out;
+
+ /* Update the input and output sizes; the updated values are the amount
+ * consumed or written, effectively the inverse of what zlib uses.
+ */
+ if (avail_out > 0)
+ *output_size_ptr -= avail_out;
+
+ if (avail_in > 0)
+ *input_size_ptr -= avail_in;
+
+ /* Ensure png_ptr->zstream.msg is set (even in the success case!) */
+ png_zstream_error(png_ptr, ret);
+ return ret;
+ }
+
+ else
+ {
+ /* This is a bad internal error. The recovery assigns to the zstream msg
+ * pointer, which is not owned by the caller, but this is safe; it's only
+ * used on errors!
+ */
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
+ return Z_STREAM_ERROR;
+ }
+}
+
+/*
+ * Decompress trailing data in a chunk. The assumption is that read_buffer
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part. What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+static int
+png_decompress_chunk(png_structrp png_ptr,
+ png_uint_32 chunklength, png_uint_32 prefix_size,
+ png_alloc_size_t *newlength /* must be initialized to the maximum! */,
+ int terminate /*add a '\0' to the end of the uncompressed data*/)
+{
+ /* TODO: implement different limits for different types of chunk.
+ *
+ * The caller supplies *newlength set to the maximum length of the
+ * uncompressed data, but this routine allocates space for the prefix and
+ * maybe a '\0' terminator too. We have to assume that 'prefix_size' is
+ * limited only by the maximum chunk size.
+ */
+ png_alloc_size_t limit = PNG_SIZE_MAX;
+
+# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+
+ if (limit >= prefix_size + (terminate != 0))
+ {
+ int ret;
+
+ limit -= prefix_size + (terminate != 0);
+
+ if (limit < *newlength)
+ *newlength = limit;
+
+ /* Now try to claim the stream. */
+ ret = png_inflate_claim(png_ptr, png_ptr->chunk_name);
+
+ if (ret == Z_OK)
+ {
+ png_uint_32 lzsize = chunklength - prefix_size;
+
+ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
+ /* input: */ png_ptr->read_buffer + prefix_size, &lzsize,
+ /* output: */ NULL, newlength);
+
+ if (ret == Z_STREAM_END)
+ {
+ /* Use 'inflateReset' here, not 'inflateReset2' because this
+ * preserves the previously decided window size (otherwise it would
+ * be necessary to store the previous window size.) In practice
+ * this doesn't matter anyway, because png_inflate will call inflate
+ * with Z_FINISH in almost all cases, so the window will not be
+ * maintained.
+ */
+ if (inflateReset(&png_ptr->zstream) == Z_OK)
+ {
+ /* Because of the limit checks above we know that the new,
+ * expanded, size will fit in a size_t (let alone an
+ * png_alloc_size_t). Use png_malloc_base here to avoid an
+ * extra OOM message.
+ */
+ png_alloc_size_t new_size = *newlength;
+ png_alloc_size_t buffer_size = prefix_size + new_size +
+ (terminate != 0);
+ png_bytep text = png_voidcast(png_bytep, png_malloc_base(png_ptr,
+ buffer_size));
+
+ if (text != NULL)
+ {
+ ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
+ png_ptr->read_buffer + prefix_size, &lzsize,
+ text + prefix_size, newlength);
+
+ if (ret == Z_STREAM_END)
+ {
+ if (new_size == *newlength)
+ {
+ if (terminate)
+ text[prefix_size + *newlength] = 0;
+
+ if (prefix_size > 0)
+ memcpy(text, png_ptr->read_buffer, prefix_size);
+
+ {
+ png_bytep old_ptr = png_ptr->read_buffer;
+
+ png_ptr->read_buffer = text;
+ png_ptr->read_buffer_size = buffer_size;
+ text = old_ptr; /* freed below */
+ }
+ }
+
+ else
+ {
+ /* The size changed on the second read, there can be no
+ * guarantee that anything is correct at this point.
+ * The 'msg' pointer has been set to "unexpected end of
+ * LZ stream", which is fine, but return an error code
+ * that the caller won't accept.
+ */
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+ }
+ }
+
+ else if (ret == Z_OK)
+ ret = PNG_UNEXPECTED_ZLIB_RETURN; /* for safety */
+
+ /* Free the text pointer (this is the old read_buffer on
+ * success)
+ */
+ png_free(png_ptr, text);
+
+ /* This really is very benign, but it's still an error because
+ * the extra space may otherwise be used as a Trojan Horse.
+ */
+ if (ret == Z_STREAM_END &&
+ chunklength - prefix_size != lzsize)
+ png_chunk_benign_error(png_ptr, "extra compressed data");
+ }
+
+ else
+ {
+ /* Out of memory allocating the buffer */
+ ret = Z_MEM_ERROR;
+ png_zstream_error(png_ptr, Z_MEM_ERROR);
+ }
+ }
+
+ else
+ {
+ /* inflateReset failed, store the error message */
+ png_zstream_error(png_ptr, ret);
+
+ if (ret == Z_STREAM_END)
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+ }
+ }
+
+ else if (ret == Z_OK)
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+ /* Release the claimed stream */
+ png_ptr->zowner = 0;
+ }
+
+ else /* the claim failed */ if (ret == Z_STREAM_END) /* impossible! */
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
+
+ return ret;
+ }
+
+ else
+ {
+ /* Application/configuration limits exceeded */
+ png_zstream_error(png_ptr, Z_MEM_ERROR);
+ return Z_MEM_ERROR;
+ }
+}
+#endif /* PNG_READ_COMPRESSED_TEXT_SUPPORTED */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+/* Perform a partial read and decompress, producing 'avail_out' bytes and
+ * reading from the current chunk as required.
+ */
+static int
+png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
+ png_uint_32p chunk_bytes, png_bytep next_out, png_alloc_size_t *out_size,
+ int finish)
+{
+ if (png_ptr->zowner == png_ptr->chunk_name)
+ {
+ int ret;
+
+ /* next_in and avail_in must have been initialized by the caller. */
+ png_ptr->zstream.next_out = next_out;
+ png_ptr->zstream.avail_out = 0; /* set in the loop */
+
+ do
+ {
+ if (png_ptr->zstream.avail_in == 0)
+ {
+ if (read_size > *chunk_bytes)
+ read_size = (uInt)*chunk_bytes;
+ *chunk_bytes -= read_size;
+
+ if (read_size > 0)
+ png_crc_read(png_ptr, read_buffer, read_size);
+
+ png_ptr->zstream.next_in = read_buffer;
+ png_ptr->zstream.avail_in = read_size;
+ }
+
+ if (png_ptr->zstream.avail_out == 0)
+ {
+ uInt avail = ZLIB_IO_MAX;
+ if (avail > *out_size)
+ avail = (uInt)*out_size;
+ *out_size -= avail;
+
+ png_ptr->zstream.avail_out = avail;
+ }
+
+ /* Use Z_SYNC_FLUSH when there is no more chunk data to ensure that all
+ * the available output is produced; this allows reading of truncated
+ * streams.
+ */
+ ret = inflate(&png_ptr->zstream,
+ *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
+ }
+ while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
+
+ *out_size += png_ptr->zstream.avail_out;
+ png_ptr->zstream.avail_out = 0; /* Should not be required, but is safe */
+
+ /* Ensure the error message pointer is always set: */
+ png_zstream_error(png_ptr, ret);
+ return ret;
+ }
+
+ else
+ {
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("zstream unclaimed");
+ return Z_STREAM_ERROR;
+ }
+}
+#endif
+
+/* Read and check the IDHR chunk */
+void /* PRIVATE */
+png_handle_IHDR(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[13];
+ png_uint_32 width, height;
+ int bit_depth, color_type, compression_type, filter_type;
+ int interlace_type;
+
+ png_debug(1, "in png_handle_IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IHDR)
+ png_chunk_error(png_ptr, "out of place");
+
+ /* Check the length */
+ if (length != 13)
+ png_chunk_error(png_ptr, "invalid");
+
+ png_ptr->mode |= PNG_HAVE_IHDR;
+
+ png_crc_read(png_ptr, buf, 13);
+ png_crc_finish(png_ptr, 0);
+
+ width = png_get_uint_31(png_ptr, buf);
+ height = png_get_uint_31(png_ptr, buf + 4);
+ bit_depth = buf[8];
+ color_type = buf[9];
+ compression_type = buf[10];
+ filter_type = buf[11];
+ interlace_type = buf[12];
+
+ /* Set internal variables */
+ png_ptr->width = width;
+ png_ptr->height = height;
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->interlaced = (png_byte)interlace_type;
+ png_ptr->color_type = (png_byte)color_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+
+ /* Find number of channels */
+ switch (png_ptr->color_type)
+ {
+ default: /* invalid, png_set_IHDR calls png_error */
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_PALETTE:
+ png_ptr->channels = 1;
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ png_ptr->channels = 3;
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_ptr->channels = 2;
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_ptr->channels = 4;
+ break;
+ }
+
+ /* Set up other useful info */
+ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+ png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
+ png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
+ png_debug1(3, "channels = %d", png_ptr->channels);
+ png_debug1(3, "rowbytes = %lu", (unsigned long)png_ptr->rowbytes);
+ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+ color_type, interlace_type, compression_type, filter_type);
+}
+
+/* Read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_color palette[PNG_MAX_PALETTE_LENGTH];
+ int num, i;
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ png_colorp pal_ptr;
+#endif
+
+ png_debug(1, "in png_handle_PLTE");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ /* Moved to before the 'after IDAT' check below because otherwise duplicate
+ * PLTE chunks are potentially ignored (the spec says there shall not be more
+ * than one PLTE, the error is not treated as benign, so this check trumps
+ * the requirement that PLTE appears before IDAT.)
+ */
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ png_chunk_error(png_ptr, "duplicate");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ /* This is benign because the non-benign error happened before, when an
+ * IDAT was encountered in a color-mapped image with no PLTE.
+ */
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "ignored in grayscale PNG");
+ return;
+ }
+
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+ {
+ png_crc_finish(png_ptr, length);
+
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ png_chunk_benign_error(png_ptr, "invalid");
+
+ else
+ png_chunk_error(png_ptr, "invalid");
+
+ return;
+ }
+
+ /* The cast is safe because 'length' is less than 3*PNG_MAX_PALETTE_LENGTH */
+ num = (int)length / 3;
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ pal_ptr->red = buf[0];
+ pal_ptr->green = buf[1];
+ pal_ptr->blue = buf[2];
+ }
+#else
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ /* Don't depend upon png_color being any order */
+ palette[i].red = buf[0];
+ palette[i].green = buf[1];
+ palette[i].blue = buf[2];
+ }
+#endif
+
+ /* If we actually need the PLTE chunk (ie for a paletted image), we do
+ * whatever the normal CRC configuration tells us. However, if we
+ * have an RGB image, the PLTE can be considered ancillary, so
+ * we will act as though it is.
+ */
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+ {
+ png_crc_finish(png_ptr, 0);
+ }
+
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
+ else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
+ {
+ /* If we don't want to use the data from an ancillary chunk,
+ * we have two options: an error abort, or a warning and we
+ * ignore the data in this chunk (which should be OK, since
+ * it's considered ancillary for a RGB or RGBA image).
+ *
+ * IMPLEMENTATION NOTE: this is only here because png_crc_finish uses the
+ * chunk type to determine whether to check the ancillary or the critical
+ * flags.
+ */
+ if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+ {
+ png_chunk_benign_error(png_ptr, "CRC error");
+ }
+
+ else
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ return;
+ }
+ }
+
+ /* Otherwise, we (optionally) emit a warning and use the chunk. */
+ else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ }
+#endif
+
+ /* TODO: png_set_PLTE has the side effect of setting png_ptr->palette to its
+ * own copy of the palette. This has the side effect that when png_start_row
+ * is called (this happens after any call to png_read_update_info) the
+ * info_ptr palette gets changed. This is extremely unexpected and
+ * confusing.
+ *
+ * Fix this by not sharing the palette in this way.
+ */
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+ /* The three chunks, bKGD, hIST and tRNS *must* appear after PLTE and before
+ * IDAT. Prior to 1.6.0 this was not checked; instead the code merely
+ * checked the apparent validity of a tRNS chunk inserted before PLTE on a
+ * palette PNG. 1.6.0 attempts to rigorously follow the standard and
+ * therefore does a benign error if the erroneous condition is detected *and*
+ * cancels the tRNS if the benign error returns. The alternative is to
+ * amend the standard since it would be rather hypocritical of the standards
+ * maintainers to ignore it.
+ */
+#ifdef PNG_READ_tRNS_SUPPORTED
+ if (png_ptr->num_trans > 0 ||
+ (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0))
+ {
+ /* Cancel this because otherwise it would be used if the transforms
+ * require it. Don't cancel the 'valid' flag because this would prevent
+ * detection of duplicate chunks.
+ */
+ png_ptr->num_trans = 0;
+
+ if (info_ptr != NULL)
+ info_ptr->num_trans = 0;
+
+ png_chunk_benign_error(png_ptr, "tRNS must be after");
+ }
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST) != 0)
+ png_chunk_benign_error(png_ptr, "hIST must be after");
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0)
+ png_chunk_benign_error(png_ptr, "bKGD must be after");
+#endif
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_debug(1, "in png_handle_IEND");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+ png_chunk_error(png_ptr, "out of place");
+
+ png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+ png_crc_finish(png_ptr, length);
+
+ if (length != 0)
+ png_chunk_benign_error(png_ptr, "invalid");
+
+ PNG_UNUSED(info_ptr)
+}
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+void /* PRIVATE */
+png_handle_gAMA(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_fixed_point igamma;
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_gAMA");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length != 4)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 4);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ igamma = png_get_fixed_point(NULL, buf);
+
+ png_colorspace_set_gamma(png_ptr, &png_ptr->colorspace, igamma);
+ png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+void /* PRIVATE */
+png_handle_sBIT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ unsigned int truelen;
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_sBIT");
+
+ buf[0] = buf[1] = buf[2] = buf[3] = 0;
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 3;
+
+ else
+ truelen = png_ptr->channels;
+
+ if (length != truelen || length > 4)
+ {
+ png_chunk_benign_error(png_ptr, "invalid");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[1];
+ png_ptr->sig_bit.blue = buf[2];
+ png_ptr->sig_bit.alpha = buf[3];
+ }
+
+ else
+ {
+ png_ptr->sig_bit.gray = buf[0];
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[0];
+ png_ptr->sig_bit.blue = buf[0];
+ png_ptr->sig_bit.alpha = buf[1];
+ }
+
+ png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+void /* PRIVATE */
+png_handle_cHRM(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[32];
+ png_xy xy;
+
+ png_debug(1, "in png_handle_cHRM");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length != 32)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 32);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ xy.whitex = png_get_fixed_point(NULL, buf);
+ xy.whitey = png_get_fixed_point(NULL, buf + 4);
+ xy.redx = png_get_fixed_point(NULL, buf + 8);
+ xy.redy = png_get_fixed_point(NULL, buf + 12);
+ xy.greenx = png_get_fixed_point(NULL, buf + 16);
+ xy.greeny = png_get_fixed_point(NULL, buf + 20);
+ xy.bluex = png_get_fixed_point(NULL, buf + 24);
+ xy.bluey = png_get_fixed_point(NULL, buf + 28);
+
+ if (xy.whitex == PNG_FIXED_ERROR ||
+ xy.whitey == PNG_FIXED_ERROR ||
+ xy.redx == PNG_FIXED_ERROR ||
+ xy.redy == PNG_FIXED_ERROR ||
+ xy.greenx == PNG_FIXED_ERROR ||
+ xy.greeny == PNG_FIXED_ERROR ||
+ xy.bluex == PNG_FIXED_ERROR ||
+ xy.bluey == PNG_FIXED_ERROR)
+ {
+ png_chunk_benign_error(png_ptr, "invalid values");
+ return;
+ }
+
+ /* If a colorspace error has already been output skip this chunk */
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ return;
+
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM)
+ {
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+ (void)png_colorspace_set_chromaticities(png_ptr, &png_ptr->colorspace, &xy,
+ 1/*prefer cHRM values*/);
+ png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+void /* PRIVATE */
+png_handle_sRGB(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte intent;
+
+ png_debug(1, "in png_handle_sRGB");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length != 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, &intent, 1);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* If a colorspace error has already been output skip this chunk */
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ return;
+
+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+ * this.
+ */
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT)
+ {
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ png_chunk_benign_error(png_ptr, "too many profiles");
+ return;
+ }
+
+ (void)png_colorspace_set_sRGB(png_ptr, &png_ptr->colorspace, intent);
+ png_colorspace_sync(png_ptr, info_ptr);
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+void /* PRIVATE */
+png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+/* Note: this does not properly handle profiles that are > 64K under DOS */
+{
+ png_const_charp errmsg = NULL; /* error message output, or no error */
+ int finished = 0; /* crc checked */
+
+ png_debug(1, "in png_handle_iCCP");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & (PNG_HAVE_IDAT|PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ /* Consistent with all the above colorspace handling an obviously *invalid*
+ * chunk is just ignored, so does not invalidate the color space. An
+ * alternative is to set the 'invalid' flags at the start of this routine
+ * and only clear them in they were not set before and all the tests pass.
+ * The minimum 'deflate' stream is assumed to be just the 2 byte header and 4
+ * byte checksum. The keyword must be one character and there is a
+ * terminator (0) byte and the compression method.
+ */
+ if (length < 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too short");
+ return;
+ }
+
+ /* If a colorspace error has already been output skip this chunk */
+ if (png_ptr->colorspace.flags & PNG_COLORSPACE_INVALID)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ /* Only one sRGB or iCCP chunk is allowed, use the HAVE_INTENT flag to detect
+ * this.
+ */
+ if ((png_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_INTENT) == 0)
+ {
+ uInt read_length, keyword_length;
+ char keyword[81];
+
+ /* Find the keyword; the keyword plus separator and compression method
+ * bytes can be at most 81 characters long.
+ */
+ read_length = 81; /* maximum */
+ if (read_length > length)
+ read_length = (uInt)length;
+
+ png_crc_read(png_ptr, (png_bytep)keyword, read_length);
+ length -= read_length;
+
+ keyword_length = 0;
+ while (keyword_length < 80 && keyword_length < read_length &&
+ keyword[keyword_length] != 0)
+ ++keyword_length;
+
+ /* TODO: make the keyword checking common */
+ if (keyword_length >= 1 && keyword_length <= 79)
+ {
+ /* We only understand '0' compression - deflate - so if we get a
+ * different value we can't safely decode the chunk.
+ */
+ if (keyword_length+1 < read_length &&
+ keyword[keyword_length+1] == PNG_COMPRESSION_TYPE_BASE)
+ {
+ read_length -= keyword_length+2;
+
+ if (png_inflate_claim(png_ptr, png_iCCP) == Z_OK)
+ {
+ Byte profile_header[132];
+ Byte local_buffer[PNG_INFLATE_BUF_SIZE];
+ png_alloc_size_t size = (sizeof profile_header);
+
+ png_ptr->zstream.next_in = (Bytef*)keyword + (keyword_length+2);
+ png_ptr->zstream.avail_in = read_length;
+ (void)png_inflate_read(png_ptr, local_buffer,
+ (sizeof local_buffer), &length, profile_header, &size,
+ 0/*finish: don't, because the output is too small*/);
+
+ if (size == 0)
+ {
+ /* We have the ICC profile header; do the basic header checks.
+ */
+ const png_uint_32 profile_length =
+ png_get_uint_32(profile_header);
+
+ if (png_icc_check_length(png_ptr, &png_ptr->colorspace,
+ keyword, profile_length))
+ {
+ /* The length is apparently ok, so we can check the 132
+ * byte header.
+ */
+ if (png_icc_check_header(png_ptr, &png_ptr->colorspace,
+ keyword, profile_length, profile_header,
+ png_ptr->color_type))
+ {
+ /* Now read the tag table; a variable size buffer is
+ * needed at this point, allocate one for the whole
+ * profile. The header check has already validated
+ * that none of these stuff will overflow.
+ */
+ const png_uint_32 tag_count = png_get_uint_32(
+ profile_header+128);
+ png_bytep profile = png_read_buffer(png_ptr,
+ profile_length, 2/*silent*/);
+
+ if (profile != NULL)
+ {
+ memcpy(profile, profile_header,
+ (sizeof profile_header));
+
+ size = 12 * tag_count;
+
+ (void)png_inflate_read(png_ptr, local_buffer,
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header), &size, 0);
+
+ /* Still expect a a buffer error because we expect
+ * there to be some tag data!
+ */
+ if (size == 0)
+ {
+ if (png_icc_check_tag_table(png_ptr,
+ &png_ptr->colorspace, keyword, profile_length,
+ profile))
+ {
+ /* The profile has been validated for basic
+ * security issues, so read the whole thing in.
+ */
+ size = profile_length - (sizeof profile_header)
+ - 12 * tag_count;
+
+ (void)png_inflate_read(png_ptr, local_buffer,
+ (sizeof local_buffer), &length,
+ profile + (sizeof profile_header) +
+ 12 * tag_count, &size, 1/*finish*/);
+
+ if (length > 0 && !(png_ptr->flags &
+ PNG_FLAG_BENIGN_ERRORS_WARN))
+ errmsg = "extra compressed data";
+
+ /* But otherwise allow extra data: */
+ else if (size == 0)
+ {
+ if (length > 0)
+ {
+ /* This can be handled completely, so
+ * keep going.
+ */
+ png_chunk_warning(png_ptr,
+ "extra compressed data");
+ }
+
+ png_crc_finish(png_ptr, length);
+ finished = 1;
+
+# ifdef PNG_sRGB_SUPPORTED
+ /* Check for a match against sRGB */
+ png_icc_set_sRGB(png_ptr,
+ &png_ptr->colorspace, profile,
+ png_ptr->zstream.adler);
+# endif
+
+ /* Steal the profile for info_ptr. */
+ if (info_ptr != NULL)
+ {
+ png_free_data(png_ptr, info_ptr,
+ PNG_FREE_ICCP, 0);
+
+ info_ptr->iccp_name = png_voidcast(char*,
+ png_malloc_base(png_ptr,
+ keyword_length+1));
+ if (info_ptr->iccp_name != NULL)
+ {
+ memcpy(info_ptr->iccp_name, keyword,
+ keyword_length+1);
+ info_ptr->iccp_proflen =
+ profile_length;
+ info_ptr->iccp_profile = profile;
+ png_ptr->read_buffer = NULL; /*steal*/
+ info_ptr->free_me |= PNG_FREE_ICCP;
+ info_ptr->valid |= PNG_INFO_iCCP;
+ }
+
+ else
+ {
+ png_ptr->colorspace.flags |=
+ PNG_COLORSPACE_INVALID;
+ errmsg = "out of memory";
+ }
+ }
+
+ /* else the profile remains in the read
+ * buffer which gets reused for subsequent
+ * chunks.
+ */
+
+ if (info_ptr != NULL)
+ png_colorspace_sync(png_ptr, info_ptr);
+
+ if (errmsg == NULL)
+ {
+ png_ptr->zowner = 0;
+ return;
+ }
+ }
+
+ else if (size > 0)
+ errmsg = "truncated";
+
+ else
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ /* else png_icc_check_tag_table output an error */
+ }
+
+ else /* profile truncated */
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ else
+ errmsg = "out of memory";
+ }
+
+ /* else png_icc_check_header output an error */
+ }
+
+ /* else png_icc_check_length output an error */
+ }
+
+ else /* profile truncated */
+ errmsg = png_ptr->zstream.msg;
+
+ /* Release the stream */
+ png_ptr->zowner = 0;
+ }
+
+ else /* png_inflate_claim failed */
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ else
+ errmsg = "bad compression method"; /* or missing */
+ }
+
+ else
+ errmsg = "bad keyword";
+ }
+
+ else
+ errmsg = "too many profiles";
+
+ /* Failure: the reason is in 'errmsg' */
+ if (!finished)
+ png_crc_finish(png_ptr, length);
+
+ png_ptr->colorspace.flags |= PNG_COLORSPACE_INVALID;
+ png_colorspace_sync(png_ptr, info_ptr);
+ if (errmsg != NULL) /* else already output */
+ png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+void /* PRIVATE */
+png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_bytep entry_start, buffer;
+ png_sPLT_t new_palette;
+ png_sPLT_entryp pp;
+ png_uint_32 data_length;
+ int entry_size, i;
+ png_uint_32 skip = 0;
+ png_uint_32 dl;
+ png_size_t max_dl;
+
+ png_debug(1, "in png_handle_sPLT");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_warning(png_ptr, "No space in chunk cache for sPLT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > 65535U)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too large to fit in memory");
+ return;
+ }
+#endif
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+
+ /* WARNING: this may break if size_t is less than 32 bits; it is assumed
+ * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
+ * potential breakage point if the types in pngconf.h aren't exactly right.
+ */
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, skip))
+ return;
+
+ buffer[length] = 0;
+
+ for (entry_start = buffer; *entry_start; entry_start++)
+ /* Empty loop to find end of name */ ;
+
+ ++entry_start;
+
+ /* A sample depth should follow the separator, and we should be on it */
+ if (entry_start > buffer + length - 2)
+ {
+ png_warning(png_ptr, "malformed sPLT chunk");
+ return;
+ }
+
+ new_palette.depth = *entry_start++;
+ entry_size = (new_palette.depth == 8 ? 6 : 10);
+ /* This must fit in a png_uint_32 because it is derived from the original
+ * chunk data length.
+ */
+ data_length = length - (png_uint_32)(entry_start - buffer);
+
+ /* Integrity-check the data length */
+ if (data_length % entry_size)
+ {
+ png_warning(png_ptr, "sPLT chunk has bad length");
+ return;
+ }
+
+ dl = (png_int_32)(data_length / entry_size);
+ max_dl = PNG_SIZE_MAX / (sizeof (png_sPLT_entry));
+
+ if (dl > max_dl)
+ {
+ png_warning(png_ptr, "sPLT chunk too long");
+ return;
+ }
+
+ new_palette.nentries = (png_int_32)(data_length / entry_size);
+
+ new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+ png_ptr, new_palette.nentries * (sizeof (png_sPLT_entry)));
+
+ if (new_palette.entries == NULL)
+ {
+ png_warning(png_ptr, "sPLT chunk requires too much memory");
+ return;
+ }
+
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+ pp = new_palette.entries + i;
+
+ if (new_palette.depth == 8)
+ {
+ pp->red = *entry_start++;
+ pp->green = *entry_start++;
+ pp->blue = *entry_start++;
+ pp->alpha = *entry_start++;
+ }
+
+ else
+ {
+ pp->red = png_get_uint_16(entry_start); entry_start += 2;
+ pp->green = png_get_uint_16(entry_start); entry_start += 2;
+ pp->blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#else
+ pp = new_palette.entries;
+
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+
+ if (new_palette.depth == 8)
+ {
+ pp[i].red = *entry_start++;
+ pp[i].green = *entry_start++;
+ pp[i].blue = *entry_start++;
+ pp[i].alpha = *entry_start++;
+ }
+
+ else
+ {
+ pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+
+ pp[i].frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#endif
+
+ /* Discard all chunk data except the name and stash that */
+ new_palette.name = (png_charp)buffer;
+
+ png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+ png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+void /* PRIVATE */
+png_handle_tRNS(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_tRNS");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_byte buf[2];
+
+ if (length != 2)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 2);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_color.gray = png_get_uint_16(buf);
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_byte buf[6];
+
+ if (length != 6)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, length);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_color.red = png_get_uint_16(buf);
+ png_ptr->trans_color.green = png_get_uint_16(buf + 2);
+ png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (!(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ /* TODO: is this actually an error in the ISO spec? */
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ if (length > png_ptr->num_palette || length > PNG_MAX_PALETTE_LENGTH ||
+ length == 0)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, readbuf, length);
+ png_ptr->num_trans = (png_uint_16)length;
+ }
+
+ else
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid with alpha channel");
+ return;
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_ptr->num_trans = 0;
+ return;
+ }
+
+ /* TODO: this is a horrible side effect in the palette case because the
+ * png_struct ends up with a pointer to the tRNS buffer owned by the
+ * png_info. Fix this.
+ */
+ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+ &(png_ptr->trans_color));
+}
+#endif
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+void /* PRIVATE */
+png_handle_bKGD(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ unsigned int truelen;
+ png_byte buf[6];
+ png_color_16 background;
+
+ png_debug(1, "in png_handle_bKGD");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE)))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 1;
+
+ else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ truelen = 6;
+
+ else
+ truelen = 2;
+
+ if (length != truelen)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* We convert the index value into RGB components so that we can allow
+ * arbitrary RGB values for background when we have transparency, and
+ * so it is easy to determine the RGB values of the background color
+ * from the info_ptr struct.
+ */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ background.index = buf[0];
+
+ if (info_ptr && info_ptr->num_palette)
+ {
+ if (buf[0] >= info_ptr->num_palette)
+ {
+ png_chunk_benign_error(png_ptr, "invalid index");
+ return;
+ }
+
+ background.red = (png_uint_16)png_ptr->palette[buf[0]].red;
+ background.green = (png_uint_16)png_ptr->palette[buf[0]].green;
+ background.blue = (png_uint_16)png_ptr->palette[buf[0]].blue;
+ }
+
+ else
+ background.red = background.green = background.blue = 0;
+
+ background.gray = 0;
+ }
+
+ else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
+ {
+ background.index = 0;
+ background.red =
+ background.green =
+ background.blue =
+ background.gray = png_get_uint_16(buf);
+ }
+
+ else
+ {
+ background.index = 0;
+ background.red = png_get_uint_16(buf);
+ background.green = png_get_uint_16(buf + 2);
+ background.blue = png_get_uint_16(buf + 4);
+ background.gray = 0;
+ }
+
+ png_set_bKGD(png_ptr, info_ptr, &background);
+}
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+void /* PRIVATE */
+png_handle_hIST(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ unsigned int num, i;
+ png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_hIST");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if ((png_ptr->mode & PNG_HAVE_IDAT) || !(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ num = length / 2 ;
+
+ if (num != png_ptr->num_palette || num > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[2];
+
+ png_crc_read(png_ptr, buf, 2);
+ readbuf[i] = png_get_uint_16(buf);
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+void /* PRIVATE */
+png_handle_pHYs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_pHYs");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ res_x = png_get_uint_32(buf);
+ res_y = png_get_uint_32(buf + 4);
+ unit_type = buf[8];
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+void /* PRIVATE */
+png_handle_oFFs(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_oFFs");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ offset_x = png_get_int_32(buf);
+ offset_y = png_get_int_32(buf + 4);
+ unit_type = buf[8];
+ png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+/* Read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_int_32 X0, X1;
+ png_byte type, nparams;
+ png_bytep buffer, buf, units, endptr;
+ png_charpp params;
+ int i;
+
+ png_debug(1, "in png_handle_pCAL");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading pCAL chunk data (%u bytes)",
+ length + 1);
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ buffer[length] = 0; /* Null terminate the last string */
+
+ png_debug(3, "Finding end of pCAL purpose string");
+ for (buf = buffer; *buf; buf++)
+ /* Empty loop */ ;
+
+ endptr = buffer + length;
+
+ /* We need to have at least 12 bytes after the purpose string
+ * in order to get the parameter information.
+ */
+ if (endptr <= buf + 12)
+ {
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
+ X0 = png_get_int_32((png_bytep)buf+1);
+ X1 = png_get_int_32((png_bytep)buf+5);
+ type = buf[9];
+ nparams = buf[10];
+ units = buf + 11;
+
+ png_debug(3, "Checking pCAL equation type and number of parameters");
+ /* Check that we have the right number of parameters for known
+ * equation types.
+ */
+ if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
+ (type == PNG_EQUATION_BASE_E && nparams != 3) ||
+ (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
+ (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
+ {
+ png_chunk_benign_error(png_ptr, "invalid parameter count");
+ return;
+ }
+
+ else if (type >= PNG_EQUATION_LAST)
+ {
+ png_chunk_benign_error(png_ptr, "unrecognized equation type");
+ }
+
+ for (buf = units; *buf; buf++)
+ /* Empty loop to move past the units string. */ ;
+
+ png_debug(3, "Allocating pCAL parameters array");
+
+ params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
+ nparams * (sizeof (png_charp))));
+
+ if (params == NULL)
+ {
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ /* Get pointers to the start of each parameter string. */
+ for (i = 0; i < nparams; i++)
+ {
+ buf++; /* Skip the null string terminator from previous parameter. */
+
+ png_debug1(3, "Reading pCAL parameter %d", i);
+
+ for (params[i] = (png_charp)buf; buf <= endptr && *buf != 0; buf++)
+ /* Empty loop to move past each parameter string */ ;
+
+ /* Make sure we haven't run out of data yet */
+ if (buf > endptr)
+ {
+ png_free(png_ptr, params);
+ png_chunk_benign_error(png_ptr, "invalid data");
+ return;
+ }
+ }
+
+ png_set_pCAL(png_ptr, info_ptr, (png_charp)buffer, X0, X1, type, nparams,
+ (png_charp)units, params);
+
+ png_free(png_ptr, params);
+}
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+/* Read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_bytep buffer;
+ png_size_t i;
+ int state;
+
+ png_debug(1, "in png_handle_sCAL");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of place");
+ return;
+ }
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ /* Need unit type, width, \0, height: minimum 4 bytes */
+ else if (length < 4)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading sCAL chunk data (%u bytes)",
+ length + 1);
+
+ buffer = png_read_buffer(png_ptr, length+1, 2/*silent*/);
+
+ if (buffer == NULL)
+ {
+ png_chunk_benign_error(png_ptr, "out of memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+ buffer[length] = 0; /* Null terminate the last string */
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* Validate the unit. */
+ if (buffer[0] != 1 && buffer[0] != 2)
+ {
+ png_chunk_benign_error(png_ptr, "invalid unit");
+ return;
+ }
+
+ /* Validate the ASCII numbers, need two ASCII numbers separated by
+ * a '\0' and they need to fit exactly in the chunk data.
+ */
+ i = 1;
+ state = 0;
+
+ if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) ||
+ i >= length || buffer[i++] != 0)
+ png_chunk_benign_error(png_ptr, "bad width format");
+
+ else if (!PNG_FP_IS_POSITIVE(state))
+ png_chunk_benign_error(png_ptr, "non-positive width");
+
+ else
+ {
+ png_size_t heighti = i;
+
+ state = 0;
+ if (!png_check_fp_number((png_const_charp)buffer, length, &state, &i) ||
+ i != length)
+ png_chunk_benign_error(png_ptr, "bad height format");
+
+ else if (!PNG_FP_IS_POSITIVE(state))
+ png_chunk_benign_error(png_ptr, "non-positive height");
+
+ else
+ /* This is the (only) success case. */
+ png_set_sCAL_s(png_ptr, info_ptr, buffer[0],
+ (png_charp)buffer+1, (png_charp)buffer+heighti);
+ }
+}
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+void /* PRIVATE */
+png_handle_tIME(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_byte buf[7];
+ png_time mod_time;
+
+ png_debug(1, "in png_handle_tIME");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "duplicate");
+ return;
+ }
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ if (length != 7)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "invalid");
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 7);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ mod_time.second = buf[6];
+ mod_time.minute = buf[5];
+ mod_time.hour = buf[4];
+ mod_time.day = buf[3];
+ mod_time.month = buf[2];
+ mod_time.year = png_get_uint_16(buf);
+
+ png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_text text_info;
+ png_bytep buffer;
+ png_charp key;
+ png_charp text;
+ png_uint_32 skip = 0;
+
+ png_debug(1, "in png_handle_tEXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > 65535U)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "too large to fit in memory");
+ return;
+ }
+#endif
+
+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+
+ if (buffer == NULL)
+ {
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, skip))
+ return;
+
+ key = (png_charp)buffer;
+ key[length] = 0;
+
+ for (text = key; *text; text++)
+ /* Empty loop to find end of key */ ;
+
+ if (text != key + length)
+ text++;
+
+ text_info.compression = PNG_TEXT_COMPRESSION_NONE;
+ text_info.key = key;
+ text_info.lang = NULL;
+ text_info.lang_key = NULL;
+ text_info.itxt_length = 0;
+ text_info.text = text;
+ text_info.text_length = strlen(text);
+
+ if (png_set_text_2(png_ptr, info_ptr, &text_info, 1))
+ png_warning(png_ptr, "Insufficient memory to process text chunk");
+}
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_const_charp errmsg = NULL;
+ png_bytep buffer;
+ png_uint_32 keyword_length;
+
+ png_debug(1, "in png_handle_zTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
+
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* TODO: also check that the keyword contents match the spec! */
+ for (keyword_length = 0;
+ keyword_length < length && buffer[keyword_length] != 0;
+ ++keyword_length)
+ /* Empty loop to find end of name */ ;
+
+ if (keyword_length > 79 || keyword_length < 1)
+ errmsg = "bad keyword";
+
+ /* zTXt must have some LZ data after the keyword, although it may expand to
+ * zero bytes; we need a '\0' at the end of the keyword, the compression type
+ * then the LZ data:
+ */
+ else if (keyword_length + 3 > length)
+ errmsg = "truncated";
+
+ else if (buffer[keyword_length+1] != PNG_COMPRESSION_TYPE_BASE)
+ errmsg = "unknown compression type";
+
+ else
+ {
+ png_alloc_size_t uncompressed_length = PNG_SIZE_MAX;
+
+ /* TODO: at present png_decompress_chunk imposes a single application
+ * level memory limit, this should be split to different values for iCCP
+ * and text chunks.
+ */
+ if (png_decompress_chunk(png_ptr, length, keyword_length+2,
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ {
+ png_text text;
+
+ /* It worked; png_ptr->read_buffer now looks like a tEXt chunk except
+ * for the extra compression type byte and the fact that it isn't
+ * necessarily '\0' terminated.
+ */
+ buffer = png_ptr->read_buffer;
+ buffer[uncompressed_length+(keyword_length+2)] = 0;
+
+ text.compression = PNG_TEXT_COMPRESSION_zTXt;
+ text.key = (png_charp)buffer;
+ text.text = (png_charp)(buffer + keyword_length+2);
+ text.text_length = uncompressed_length;
+ text.itxt_length = 0;
+ text.lang = NULL;
+ text.lang_key = NULL;
+
+ if (png_set_text_2(png_ptr, info_ptr, &text, 1))
+ errmsg = "insufficient memory";
+ }
+
+ else
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ if (errmsg != NULL)
+ png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+/* Note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
+{
+ png_const_charp errmsg = NULL;
+ png_bytep buffer;
+ png_uint_32 prefix_length;
+
+ png_debug(1, "in png_handle_iTXt");
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ if (png_ptr->user_chunk_cache_max != 0)
+ {
+ if (png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (--png_ptr->user_chunk_cache_max == 1)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ return;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_chunk_error(png_ptr, "missing IHDR");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ buffer = png_read_buffer(png_ptr, length+1, 1/*warn*/);
+
+ if (buffer == NULL)
+ {
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "out of memory");
+ return;
+ }
+
+ png_crc_read(png_ptr, buffer, length);
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* First the keyword. */
+ for (prefix_length=0;
+ prefix_length < length && buffer[prefix_length] != 0;
+ ++prefix_length)
+ /* Empty loop */ ;
+
+ /* Perform a basic check on the keyword length here. */
+ if (prefix_length > 79 || prefix_length < 1)
+ errmsg = "bad keyword";
+
+ /* Expect keyword, compression flag, compression type, language, translated
+ * keyword (both may be empty but are 0 terminated) then the text, which may
+ * be empty.
+ */
+ else if (prefix_length + 5 > length)
+ errmsg = "truncated";
+
+ else if (buffer[prefix_length+1] == 0 ||
+ (buffer[prefix_length+1] == 1 &&
+ buffer[prefix_length+2] == PNG_COMPRESSION_TYPE_BASE))
+ {
+ int compressed = buffer[prefix_length+1] != 0;
+ png_uint_32 language_offset, translated_keyword_offset;
+ png_alloc_size_t uncompressed_length = 0;
+
+ /* Now the language tag */
+ prefix_length += 3;
+ language_offset = prefix_length;
+
+ for (; prefix_length < length && buffer[prefix_length] != 0;
+ ++prefix_length)
+ /* Empty loop */ ;
+
+ /* WARNING: the length may be invalid here, this is checked below. */
+ translated_keyword_offset = ++prefix_length;
+
+ for (; prefix_length < length && buffer[prefix_length] != 0;
+ ++prefix_length)
+ /* Empty loop */ ;
+
+ /* prefix_length should now be at the trailing '\0' of the translated
+ * keyword, but it may already be over the end. None of this arithmetic
+ * can overflow because chunks are at most 2^31 bytes long, but on 16-bit
+ * systems the available allocaton may overflow.
+ */
+ ++prefix_length;
+
+ if (!compressed && prefix_length <= length)
+ uncompressed_length = length - prefix_length;
+
+ else if (compressed && prefix_length < length)
+ {
+ uncompressed_length = PNG_SIZE_MAX;
+
+ /* TODO: at present png_decompress_chunk imposes a single application
+ * level memory limit, this should be split to different values for
+ * iCCP and text chunks.
+ */
+ if (png_decompress_chunk(png_ptr, length, prefix_length,
+ &uncompressed_length, 1/*terminate*/) == Z_STREAM_END)
+ buffer = png_ptr->read_buffer;
+
+ else
+ errmsg = png_ptr->zstream.msg;
+ }
+
+ else
+ errmsg = "truncated";
+
+ if (errmsg == NULL)
+ {
+ png_text text;
+
+ buffer[uncompressed_length+prefix_length] = 0;
+
+ if (compressed)
+ text.compression = PNG_ITXT_COMPRESSION_NONE;
+
+ else
+ text.compression = PNG_ITXT_COMPRESSION_zTXt;
+
+ text.key = (png_charp)buffer;
+ text.lang = (png_charp)buffer + language_offset;
+ text.lang_key = (png_charp)buffer + translated_keyword_offset;
+ text.text = (png_charp)buffer + prefix_length;
+ text.text_length = 0;
+ text.itxt_length = uncompressed_length;
+
+ if (png_set_text_2(png_ptr, info_ptr, &text, 1))
+ errmsg = "insufficient memory";
+ }
+ }
+
+ else
+ errmsg = "bad compression info";
+
+ if (errmsg != NULL)
+ png_chunk_benign_error(png_ptr, errmsg);
+}
+#endif
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+/* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
+static int
+png_cache_unknown_chunk(png_structrp png_ptr, png_uint_32 length)
+{
+ png_alloc_size_t limit = PNG_SIZE_MAX;
+
+ if (png_ptr->unknown_chunk.data != NULL)
+ {
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+ }
+
+# ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
+
+# elif PNG_USER_CHUNK_MALLOC_MAX > 0
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
+# endif
+
+ if (length <= limit)
+ {
+ PNG_CSTRING_FROM_CHUNK(png_ptr->unknown_chunk.name, png_ptr->chunk_name);
+ /* The following is safe because of the PNG_SIZE_MAX init above */
+ png_ptr->unknown_chunk.size = (png_size_t)length/*SAFE*/;
+ /* 'mode' is a flag array, only the bottom four bits matter here */
+ png_ptr->unknown_chunk.location = (png_byte)png_ptr->mode/*SAFE*/;
+
+ if (length == 0)
+ png_ptr->unknown_chunk.data = NULL;
+
+ else
+ {
+ /* Do a 'warn' here - it is handled below. */
+ png_ptr->unknown_chunk.data = png_voidcast(png_bytep,
+ png_malloc_warn(png_ptr, length));
+ }
+ }
+
+ if (png_ptr->unknown_chunk.data == NULL && length > 0)
+ {
+ /* This is benign because we clean up correctly */
+ png_crc_finish(png_ptr, length);
+ png_chunk_benign_error(png_ptr, "unknown chunk exceeds memory limits");
+ return 0;
+ }
+
+ else
+ {
+ if (length > 0)
+ png_crc_read(png_ptr, png_ptr->unknown_chunk.data, length);
+ png_crc_finish(png_ptr, 0);
+ return 1;
+ }
+}
+#endif /* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
+
+/* Handle an unknown, or known but disabled, chunk */
+void /* PRIVATE */
+png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr,
+ png_uint_32 length, int keep)
+{
+ int handled = 0; /* the chunk was handled */
+
+ png_debug(1, "in png_handle_unknown");
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ /* NOTE: this code is based on the code in libpng-1.4.12 except for fixing
+ * the bug which meant that setting a non-default behavior for a specific
+ * chunk would be ignored (the default was always used unless a user
+ * callback was installed).
+ *
+ * 'keep' is the value from the png_chunk_unknown_handling, the setting for
+ * this specific chunk_name, if PNG_HANDLE_AS_UNKNOWN_SUPPORTED, if not it
+ * will always be PNG_HANDLE_CHUNK_AS_DEFAULT and it needs to be set here.
+ * This is just an optimization to avoid multiple calls to the lookup
+ * function.
+ */
+# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ keep = png_chunk_unknown_handling(png_ptr, png_ptr->chunk_name);
+# endif
+# endif
+
+ /* One of the following methods will read the chunk or skip it (at least one
+ * of these is always defined because this is the only way to switch on
+ * PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ */
+# ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ /* The user callback takes precedence over the chunk keep value, but the
+ * keep value is still required to validate a save of a critical chunk.
+ */
+ if (png_ptr->read_user_chunk_fn != NULL)
+ {
+ if (png_cache_unknown_chunk(png_ptr, length))
+ {
+ /* Callback to user unknown chunk handler */
+ int ret = (*(png_ptr->read_user_chunk_fn))(png_ptr,
+ &png_ptr->unknown_chunk);
+
+ /* ret is:
+ * negative: An error occured, png_chunk_error will be called.
+ * zero: The chunk was not handled, the chunk will be discarded
+ * unless png_set_keep_unknown_chunks has been used to set
+ * a 'keep' behavior for this particular chunk, in which
+ * case that will be used. A critical chunk will cause an
+ * error at this point unless it is to be saved.
+ * positive: The chunk was handled, libpng will ignore/discard it.
+ */
+ if (ret < 0)
+ png_chunk_error(png_ptr, "error in user chunk");
+
+ else if (ret == 0)
+ {
+ /* If the keep value is 'default' or 'never' override it, but
+ * still error out on critical chunks unless the keep value is
+ * 'always' While this is weird it is the behavior in 1.4.12.
+ * A possible improvement would be to obey the value set for the
+ * chunk, but this would be an API change that would probably
+ * damage some applications.
+ *
+ * The png_app_warning below catches the case that matters, where
+ * the application has not set specific save or ignore for this
+ * chunk or global save or ignore.
+ */
+ if (keep < PNG_HANDLE_CHUNK_IF_SAFE)
+ {
+# ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ if (png_ptr->unknown_default < PNG_HANDLE_CHUNK_IF_SAFE)
+ {
+ png_chunk_warning(png_ptr, "Saving unknown chunk:");
+ png_app_warning(png_ptr,
+ "forcing save of an unhandled chunk;"
+ " please call png_set_keep_unknown_chunks");
+ /* with keep = PNG_HANDLE_CHUNK_IF_SAFE */
+ }
+# endif
+ keep = PNG_HANDLE_CHUNK_IF_SAFE;
+ }
+ }
+
+ else /* chunk was handled */
+ {
+ handled = 1;
+ /* Critical chunks can be safely discarded at this point. */
+ keep = PNG_HANDLE_CHUNK_NEVER;
+ }
+ }
+
+ else
+ keep = PNG_HANDLE_CHUNK_NEVER; /* insufficient memory */
+ }
+
+ else
+ /* Use the SAVE_UNKNOWN_CHUNKS code or skip the chunk */
+# endif /* PNG_READ_USER_CHUNKS_SUPPORTED */
+
+# ifdef PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
+ {
+ /* keep is currently just the per-chunk setting, if there was no
+ * setting change it to the global default now (not that this may
+ * still be AS_DEFAULT) then obtain the cache of the chunk if required,
+ * if not simply skip the chunk.
+ */
+ if (keep == PNG_HANDLE_CHUNK_AS_DEFAULT)
+ keep = png_ptr->unknown_default;
+
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
+ {
+ if (!png_cache_unknown_chunk(png_ptr, length))
+ keep = PNG_HANDLE_CHUNK_NEVER;
+ }
+
+ else
+ png_crc_finish(png_ptr, length);
+ }
+# else
+# ifndef PNG_READ_USER_CHUNKS_SUPPORTED
+# error no method to support READ_UNKNOWN_CHUNKS
+# endif
+
+ {
+ /* If here there is no read callback pointer set and no support is
+ * compiled in to just save the unknown chunks, so simply skip this
+ * chunk. If 'keep' is something other than AS_DEFAULT or NEVER then
+ * the app has erroneously asked for unknown chunk saving when there
+ * is no support.
+ */
+ if (keep > PNG_HANDLE_CHUNK_NEVER)
+ png_app_error(png_ptr, "no unknown chunk support available");
+
+ png_crc_finish(png_ptr, length);
+ }
+# endif
+
+# ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+ /* Now store the chunk in the chunk list if appropriate, and if the limits
+ * permit it.
+ */
+ if (keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_IF_SAFE &&
+ PNG_CHUNK_ANCILLARY(png_ptr->chunk_name)))
+ {
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ switch (png_ptr->user_chunk_cache_max)
+ {
+ case 2:
+ png_ptr->user_chunk_cache_max = 1;
+ png_chunk_benign_error(png_ptr, "no space in chunk cache");
+ /* FALL THROUGH */
+ case 1:
+ /* NOTE: prior to 1.6.0 this case resulted in an unknown critical
+ * chunk being skipped, now there will be a hard error below.
+ */
+ break;
+
+ default: /* not at limit */
+ --(png_ptr->user_chunk_cache_max);
+ /* FALL THROUGH */
+ case 0: /* no limit */
+# endif /* PNG_USER_LIMITS_SUPPORTED */
+ /* Here when the limit isn't reached or when limits are compiled
+ * out; store the chunk.
+ */
+ png_set_unknown_chunks(png_ptr, info_ptr,
+ &png_ptr->unknown_chunk, 1);
+ handled = 1;
+# ifdef PNG_USER_LIMITS_SUPPORTED
+ break;
+ }
+# endif
+ }
+# else /* no store support! */
+ PNG_UNUSED(info_ptr)
+# error untested code (reading unknown chunks with no store support)
+# endif
+
+ /* Regardless of the error handling below the cached data (if any) can be
+ * freed now. Notice that the data is not freed if there is a png_error, but
+ * it will be freed by destroy_read_struct.
+ */
+ if (png_ptr->unknown_chunk.data != NULL)
+ png_free(png_ptr, png_ptr->unknown_chunk.data);
+ png_ptr->unknown_chunk.data = NULL;
+
+#else /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
+ /* There is no support to read an unknown chunk, so just skip it. */
+ png_crc_finish(png_ptr, length);
+ PNG_UNUSED(info_ptr)
+ PNG_UNUSED(keep)
+#endif /* !PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
+
+ /* Check for unhandled critical chunks */
+ if (!handled && PNG_CHUNK_CRITICAL(png_ptr->chunk_name))
+ png_chunk_error(png_ptr, "unhandled critical chunk");
+}
+
+/* This function is called to verify that a chunk name is valid.
+ * This function can't have the "critical chunk check" incorporated
+ * into it, since in the future we will need to be able to call user
+ * functions to handle unknown critical chunks after we check that
+ * the chunk name itself is valid.
+ */
+
+/* Bit hacking: the test for an invalid byte in the 4 byte chunk name is:
+ *
+ * ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
+ */
+
+void /* PRIVATE */
+png_check_chunk_name(png_structrp png_ptr, png_uint_32 chunk_name)
+{
+ int i;
+
+ png_debug(1, "in png_check_chunk_name");
+
+ for (i=1; i<=4; ++i)
+ {
+ int c = chunk_name & 0xff;
+
+ if (c < 65 || c > 122 || (c > 90 && c < 97))
+ png_chunk_error(png_ptr, "invalid chunk type");
+
+ chunk_name >>= 8;
+ }
+}
+
+/* Combines the row recently read in with the existing pixels in the row. This
+ * routine takes care of alpha and transparency if requested. This routine also
+ * handles the two methods of progressive display of interlaced images,
+ * depending on the 'display' value; if 'display' is true then the whole row
+ * (dp) is filled from the start by replicating the available pixels. If
+ * 'display' is false only those pixels present in the pass are filled in.
+ */
+void /* PRIVATE */
+png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
+{
+ unsigned int pixel_depth = png_ptr->transformed_pixel_depth;
+ png_const_bytep sp = png_ptr->row_buf + 1;
+ png_uint_32 row_width = png_ptr->width;
+ unsigned int pass = png_ptr->pass;
+ png_bytep end_ptr = 0;
+ png_byte end_byte = 0;
+ unsigned int end_mask;
+
+ png_debug(1, "in png_combine_row");
+
+ /* Added in 1.5.6: it should not be possible to enter this routine until at
+ * least one row has been read from the PNG data and transformed.
+ */
+ if (pixel_depth == 0)
+ png_error(png_ptr, "internal row logic error");
+
+ /* Added in 1.5.4: the pixel depth should match the information returned by
+ * any call to png_read_update_info at this point. Do not continue if we got
+ * this wrong.
+ */
+ if (png_ptr->info_rowbytes != 0 && png_ptr->info_rowbytes !=
+ PNG_ROWBYTES(pixel_depth, row_width))
+ png_error(png_ptr, "internal row size calculation error");
+
+ /* Don't expect this to ever happen: */
+ if (row_width == 0)
+ png_error(png_ptr, "internal row width error");
+
+ /* Preserve the last byte in cases where only part of it will be overwritten,
+ * the multiply below may overflow, we don't care because ANSI-C guarantees
+ * we get the low bits.
+ */
+ end_mask = (pixel_depth * row_width) & 7;
+ if (end_mask != 0)
+ {
+ /* end_ptr == NULL is a flag to say do nothing */
+ end_ptr = dp + PNG_ROWBYTES(pixel_depth, row_width) - 1;
+ end_byte = *end_ptr;
+# ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP) /* little-endian byte */
+ end_mask = 0xff << end_mask;
+
+ else /* big-endian byte */
+# endif
+ end_mask = 0xff >> end_mask;
+ /* end_mask is now the bits to *keep* from the destination row */
+ }
+
+ /* For non-interlaced images this reduces to a memcpy(). A memcpy()
+ * will also happen if interlacing isn't supported or if the application
+ * does not call png_set_interlace_handling(). In the latter cases the
+ * caller just gets a sequence of the unexpanded rows from each interlace
+ * pass.
+ */
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE) &&
+ pass < 6 && (display == 0 ||
+ /* The following copies everything for 'display' on passes 0, 2 and 4. */
+ (display == 1 && (pass & 1) != 0)))
+ {
+ /* Narrow images may have no bits in a pass; the caller should handle
+ * this, but this test is cheap:
+ */
+ if (row_width <= PNG_PASS_START_COL(pass))
+ return;
+
+ if (pixel_depth < 8)
+ {
+ /* For pixel depths up to 4 bpp the 8-pixel mask can be expanded to fit
+ * into 32 bits, then a single loop over the bytes using the four byte
+ * values in the 32-bit mask can be used. For the 'display' option the
+ * expanded mask may also not require any masking within a byte. To
+ * make this work the PACKSWAP option must be taken into account - it
+ * simply requires the pixels to be reversed in each byte.
+ *
+ * The 'regular' case requires a mask for each of the first 6 passes,
+ * the 'display' case does a copy for the even passes in the range
+ * 0..6. This has already been handled in the test above.
+ *
+ * The masks are arranged as four bytes with the first byte to use in
+ * the lowest bits (little-endian) regardless of the order (PACKSWAP or
+ * not) of the pixels in each byte.
+ *
+ * NOTE: the whole of this logic depends on the caller of this function
+ * only calling it on rows appropriate to the pass. This function only
+ * understands the 'x' logic; the 'y' logic is handled by the caller.
+ *
+ * The following defines allow generation of compile time constant bit
+ * masks for each pixel depth and each possibility of swapped or not
+ * swapped bytes. Pass 'p' is in the range 0..6; 'x', a pixel index,
+ * is in the range 0..7; and the result is 1 if the pixel is to be
+ * copied in the pass, 0 if not. 'S' is for the sparkle method, 'B'
+ * for the block method.
+ *
+ * With some compilers a compile time expression of the general form:
+ *
+ * (shift >= 32) ? (a >> (shift-32)) : (b >> shift)
+ *
+ * Produces warnings with values of 'shift' in the range 33 to 63
+ * because the right hand side of the ?: expression is evaluated by
+ * the compiler even though it isn't used. Microsoft Visual C (various
+ * versions) and the Intel C compiler are known to do this. To avoid
+ * this the following macros are used in 1.5.6. This is a temporary
+ * solution to avoid destabilizing the code during the release process.
+ */
+# if PNG_USE_COMPILE_TIME_MASKS
+# define PNG_LSR(x,s) ((x)>>((s) & 0x1f))
+# define PNG_LSL(x,s) ((x)<<((s) & 0x1f))
+# else
+# define PNG_LSR(x,s) ((x)>>(s))
+# define PNG_LSL(x,s) ((x)<<(s))
+# endif
+# define S_COPY(p,x) (((p)<4 ? PNG_LSR(0x80088822,(3-(p))*8+(7-(x))) :\
+ PNG_LSR(0xaa55ff00,(7-(p))*8+(7-(x)))) & 1)
+# define B_COPY(p,x) (((p)<4 ? PNG_LSR(0xff0fff33,(3-(p))*8+(7-(x))) :\
+ PNG_LSR(0xff55ff00,(7-(p))*8+(7-(x)))) & 1)
+
+ /* Return a mask for pass 'p' pixel 'x' at depth 'd'. The mask is
+ * little endian - the first pixel is at bit 0 - however the extra
+ * parameter 's' can be set to cause the mask position to be swapped
+ * within each byte, to match the PNG format. This is done by XOR of
+ * the shift with 7, 6 or 4 for bit depths 1, 2 and 4.
+ */
+# define PIXEL_MASK(p,x,d,s) \
+ (PNG_LSL(((PNG_LSL(1U,(d)))-1),(((x)*(d))^((s)?8-(d):0))))
+
+ /* Hence generate the appropriate 'block' or 'sparkle' pixel copy mask.
+ */
+# define S_MASKx(p,x,d,s) (S_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
+# define B_MASKx(p,x,d,s) (B_COPY(p,x)?PIXEL_MASK(p,x,d,s):0)
+
+ /* Combine 8 of these to get the full mask. For the 1-bpp and 2-bpp
+ * cases the result needs replicating, for the 4-bpp case the above
+ * generates a full 32 bits.
+ */
+# define MASK_EXPAND(m,d) ((m)*((d)==1?0x01010101:((d)==2?0x00010001:1)))
+
+# define S_MASK(p,d,s) MASK_EXPAND(S_MASKx(p,0,d,s) + S_MASKx(p,1,d,s) +\
+ S_MASKx(p,2,d,s) + S_MASKx(p,3,d,s) + S_MASKx(p,4,d,s) +\
+ S_MASKx(p,5,d,s) + S_MASKx(p,6,d,s) + S_MASKx(p,7,d,s), d)
+
+# define B_MASK(p,d,s) MASK_EXPAND(B_MASKx(p,0,d,s) + B_MASKx(p,1,d,s) +\
+ B_MASKx(p,2,d,s) + B_MASKx(p,3,d,s) + B_MASKx(p,4,d,s) +\
+ B_MASKx(p,5,d,s) + B_MASKx(p,6,d,s) + B_MASKx(p,7,d,s), d)
+
+#if PNG_USE_COMPILE_TIME_MASKS
+ /* Utility macros to construct all the masks for a depth/swap
+ * combination. The 's' parameter says whether the format is PNG
+ * (big endian bytes) or not. Only the three odd-numbered passes are
+ * required for the display/block algorithm.
+ */
+# define S_MASKS(d,s) { S_MASK(0,d,s), S_MASK(1,d,s), S_MASK(2,d,s),\
+ S_MASK(3,d,s), S_MASK(4,d,s), S_MASK(5,d,s) }
+
+# define B_MASKS(d,s) { B_MASK(1,d,s), S_MASK(3,d,s), S_MASK(5,d,s) }
+
+# define DEPTH_INDEX(d) ((d)==1?0:((d)==2?1:2))
+
+ /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and
+ * then pass:
+ */
+ static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] =
+ {
+ /* Little-endian byte masks for PACKSWAP */
+ { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) },
+ /* Normal (big-endian byte) masks - PNG format */
+ { S_MASKS(1,1), S_MASKS(2,1), S_MASKS(4,1) }
+ };
+
+ /* display_mask has only three entries for the odd passes, so index by
+ * pass>>1.
+ */
+ static PNG_CONST png_uint_32 display_mask[2][3][3] =
+ {
+ /* Little-endian byte masks for PACKSWAP */
+ { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) },
+ /* Normal (big-endian byte) masks - PNG format */
+ { B_MASKS(1,1), B_MASKS(2,1), B_MASKS(4,1) }
+ };
+
+# define MASK(pass,depth,display,png)\
+ ((display)?display_mask[png][DEPTH_INDEX(depth)][pass>>1]:\
+ row_mask[png][DEPTH_INDEX(depth)][pass])
+
+#else /* !PNG_USE_COMPILE_TIME_MASKS */
+ /* This is the runtime alternative: it seems unlikely that this will
+ * ever be either smaller or faster than the compile time approach.
+ */
+# define MASK(pass,depth,display,png)\
+ ((display)?B_MASK(pass,depth,png):S_MASK(pass,depth,png))
+#endif /* !PNG_USE_COMPILE_TIME_MASKS */
+
+ /* Use the appropriate mask to copy the required bits. In some cases
+ * the byte mask will be 0 or 0xff, optimize these cases. row_width is
+ * the number of pixels, but the code copies bytes, so it is necessary
+ * to special case the end.
+ */
+ png_uint_32 pixels_per_byte = 8 / pixel_depth;
+ png_uint_32 mask;
+
+# ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ mask = MASK(pass, pixel_depth, display, 0);
+
+ else
+# endif
+ mask = MASK(pass, pixel_depth, display, 1);
+
+ for (;;)
+ {
+ png_uint_32 m;
+
+ /* It doesn't matter in the following if png_uint_32 has more than
+ * 32 bits because the high bits always match those in m<<24; it is,
+ * however, essential to use OR here, not +, because of this.
+ */
+ m = mask;
+ mask = (m >> 8) | (m << 24); /* rotate right to good compilers */
+ m &= 0xff;
+
+ if (m != 0) /* something to copy */
+ {
+ if (m != 0xff)
+ *dp = (png_byte)((*dp & ~m) | (*sp & m));
+ else
+ *dp = *sp;
+ }
+
+ /* NOTE: this may overwrite the last byte with garbage if the image
+ * is not an exact number of bytes wide; libpng has always done
+ * this.
+ */
+ if (row_width <= pixels_per_byte)
+ break; /* May need to restore part of the last byte */
+
+ row_width -= pixels_per_byte;
+ ++dp;
+ ++sp;
+ }
+ }
+
+ else /* pixel_depth >= 8 */
+ {
+ unsigned int bytes_to_copy, bytes_to_jump;
+
+ /* Validate the depth - it must be a multiple of 8 */
+ if (pixel_depth & 7)
+ png_error(png_ptr, "invalid user transform pixel depth");
+
+ pixel_depth >>= 3; /* now in bytes */
+ row_width *= pixel_depth;
+
+ /* Regardless of pass number the Adam 7 interlace always results in a
+ * fixed number of pixels to copy then to skip. There may be a
+ * different number of pixels to skip at the start though.
+ */
+ {
+ unsigned int offset = PNG_PASS_START_COL(pass) * pixel_depth;
+
+ row_width -= offset;
+ dp += offset;
+ sp += offset;
+ }
+
+ /* Work out the bytes to copy. */
+ if (display)
+ {
+ /* When doing the 'block' algorithm the pixel in the pass gets
+ * replicated to adjacent pixels. This is why the even (0,2,4,6)
+ * passes are skipped above - the entire expanded row is copied.
+ */
+ bytes_to_copy = (1<<((6-pass)>>1)) * pixel_depth;
+
+ /* But don't allow this number to exceed the actual row width. */
+ if (bytes_to_copy > row_width)
+ bytes_to_copy = row_width;
+ }
+
+ else /* normal row; Adam7 only ever gives us one pixel to copy. */
+ bytes_to_copy = pixel_depth;
+
+ /* In Adam7 there is a constant offset between where the pixels go. */
+ bytes_to_jump = PNG_PASS_COL_OFFSET(pass) * pixel_depth;
+
+ /* And simply copy these bytes. Some optimization is possible here,
+ * depending on the value of 'bytes_to_copy'. Special case the low
+ * byte counts, which we know to be frequent.
+ *
+ * Notice that these cases all 'return' rather than 'break' - this
+ * avoids an unnecessary test on whether to restore the last byte
+ * below.
+ */
+ switch (bytes_to_copy)
+ {
+ case 1:
+ for (;;)
+ {
+ *dp = *sp;
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ dp += bytes_to_jump;
+ sp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ }
+
+ case 2:
+ /* There is a possibility of a partial copy at the end here; this
+ * slows the code down somewhat.
+ */
+ do
+ {
+ dp[0] = sp[0], dp[1] = sp[1];
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ sp += bytes_to_jump;
+ dp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ }
+ while (row_width > 1);
+
+ /* And there can only be one byte left at this point: */
+ *dp = *sp;
+ return;
+
+ case 3:
+ /* This can only be the RGB case, so each copy is exactly one
+ * pixel and it is not necessary to check for a partial copy.
+ */
+ for(;;)
+ {
+ dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ sp += bytes_to_jump;
+ dp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ }
+
+ default:
+#if PNG_ALIGN_TYPE != PNG_ALIGN_NONE
+ /* Check for double byte alignment and, if possible, use a
+ * 16-bit copy. Don't attempt this for narrow images - ones that
+ * are less than an interlace panel wide. Don't attempt it for
+ * wide bytes_to_copy either - use the memcpy there.
+ */
+ if (bytes_to_copy < 16 /*else use memcpy*/ &&
+ png_isaligned(dp, png_uint_16) &&
+ png_isaligned(sp, png_uint_16) &&
+ bytes_to_copy % (sizeof (png_uint_16)) == 0 &&
+ bytes_to_jump % (sizeof (png_uint_16)) == 0)
+ {
+ /* Everything is aligned for png_uint_16 copies, but try for
+ * png_uint_32 first.
+ */
+ if (png_isaligned(dp, png_uint_32) &&
+ png_isaligned(sp, png_uint_32) &&
+ bytes_to_copy % (sizeof (png_uint_32)) == 0 &&
+ bytes_to_jump % (sizeof (png_uint_32)) == 0)
+ {
+ png_uint_32p dp32 = png_aligncast(png_uint_32p,dp);
+ png_const_uint_32p sp32 = png_aligncastconst(
+ png_const_uint_32p, sp);
+ size_t skip = (bytes_to_jump-bytes_to_copy) /
+ (sizeof (png_uint_32));
+
+ do
+ {
+ size_t c = bytes_to_copy;
+ do
+ {
+ *dp32++ = *sp32++;
+ c -= (sizeof (png_uint_32));
+ }
+ while (c > 0);
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ dp32 += skip;
+ sp32 += skip;
+ row_width -= bytes_to_jump;
+ }
+ while (bytes_to_copy <= row_width);
+
+ /* Get to here when the row_width truncates the final copy.
+ * There will be 1-3 bytes left to copy, so don't try the
+ * 16-bit loop below.
+ */
+ dp = (png_bytep)dp32;
+ sp = (png_const_bytep)sp32;
+ do
+ *dp++ = *sp++;
+ while (--row_width > 0);
+ return;
+ }
+
+ /* Else do it in 16-bit quantities, but only if the size is
+ * not too large.
+ */
+ else
+ {
+ png_uint_16p dp16 = png_aligncast(png_uint_16p, dp);
+ png_const_uint_16p sp16 = png_aligncastconst(
+ png_const_uint_16p, sp);
+ size_t skip = (bytes_to_jump-bytes_to_copy) /
+ (sizeof (png_uint_16));
+
+ do
+ {
+ size_t c = bytes_to_copy;
+ do
+ {
+ *dp16++ = *sp16++;
+ c -= (sizeof (png_uint_16));
+ }
+ while (c > 0);
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ dp16 += skip;
+ sp16 += skip;
+ row_width -= bytes_to_jump;
+ }
+ while (bytes_to_copy <= row_width);
+
+ /* End of row - 1 byte left, bytes_to_copy > row_width: */
+ dp = (png_bytep)dp16;
+ sp = (png_const_bytep)sp16;
+ do
+ *dp++ = *sp++;
+ while (--row_width > 0);
+ return;
+ }
+ }
+#endif /* PNG_ALIGN_ code */
+
+ /* The true default - use a memcpy: */
+ for (;;)
+ {
+ memcpy(dp, sp, bytes_to_copy);
+
+ if (row_width <= bytes_to_jump)
+ return;
+
+ sp += bytes_to_jump;
+ dp += bytes_to_jump;
+ row_width -= bytes_to_jump;
+ if (bytes_to_copy > row_width)
+ bytes_to_copy = row_width;
+ }
+ }
+
+ /* NOT REACHED*/
+ } /* pixel_depth >= 8 */
+
+ /* Here if pixel_depth < 8 to check 'end_ptr' below. */
+ }
+ else
+#endif
+
+ /* If here then the switch above wasn't used so just memcpy the whole row
+ * from the temporary row buffer (notice that this overwrites the end of the
+ * destination row if it is a partial byte.)
+ */
+ memcpy(dp, sp, PNG_ROWBYTES(pixel_depth, row_width));
+
+ /* Restore the overwritten bits from the last byte if necessary. */
+ if (end_ptr != NULL)
+ *end_ptr = (png_byte)((end_byte & end_mask) | (*end_ptr & ~end_mask));
+}
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+void /* PRIVATE */
+png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+ png_uint_32 transformations /* Because these may affect the byte layout */)
+{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+ /* Offset to next interlace block */
+ static PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ png_debug(1, "in png_do_read_interlace");
+ if (row != NULL && row_info != NULL)
+ {
+ png_uint_32 final_width;
+
+ final_width = row_info->width * png_pass_inc[pass];
+
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_byte v;
+ png_uint_32 i;
+ int j;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)((row_info->width + 7) & 0x07);
+ dshift = (int)((final_width + 7) & 0x07);
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+
+ else
+#endif
+ {
+ sshift = 7 - (int)((row_info->width + 7) & 0x07);
+ dshift = 7 - (int)((final_width + 7) & 0x07);
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ v = (png_byte)((*sp >> sshift) & 0x01);
+ for (j = 0; j < jstop; j++)
+ {
+ unsigned int tmp = *dp & (0x7f7f >> (7 - dshift));
+ tmp |= v << dshift;
+ *dp = (png_byte)(tmp & 0xff);
+
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+
+ else
+ dshift += s_inc;
+ }
+
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+ png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+ dshift = (int)(((final_width + 3) & 0x03) << 1);
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+
+ else
+#endif
+ {
+ sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+ dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0x03);
+ for (j = 0; j < jstop; j++)
+ {
+ unsigned int tmp = *dp & (0x3f3f >> (6 - dshift));
+ tmp |= v << dshift;
+ *dp = (png_byte)(tmp & 0xff);
+
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+
+ else
+ dshift += s_inc;
+ }
+
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+ int jstop = png_pass_inc[pass];
+
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+ dshift = (int)(((final_width + 1) & 0x01) << 2);
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+
+ else
+#endif
+ {
+ sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+ dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v = (png_byte)((*sp >> sshift) & 0x0f);
+ int j;
+
+ for (j = 0; j < jstop; j++)
+ {
+ unsigned int tmp = *dp & (0xf0f >> (4 - dshift));
+ tmp |= v << dshift;
+ *dp = (png_byte)(tmp & 0xff);
+
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+
+ else
+ dshift += s_inc;
+ }
+
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ default:
+ {
+ png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+
+ png_bytep sp = row + (png_size_t)(row_info->width - 1)
+ * pixel_bytes;
+
+ png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v[8]; /* SAFE; pixel_depth does not exceed 64 */
+ int j;
+
+ memcpy(v, sp, pixel_bytes);
+
+ for (j = 0; j < jstop; j++)
+ {
+ memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+
+ sp -= pixel_bytes;
+ }
+ break;
+ }
+ }
+
+ row_info->width = final_width;
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
+ }
+#ifndef PNG_READ_PACKSWAP_SUPPORTED
+ PNG_UNUSED(transformations) /* Silence compiler warning */
+#endif
+}
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+static void
+png_read_filter_row_sub(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+ unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp = row + bpp;
+
+ PNG_UNUSED(prev_row)
+
+ for (i = bpp; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*(rp-bpp))) & 0xff);
+ rp++;
+ }
+}
+
+static void
+png_read_filter_row_up(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_const_bytep pp = prev_row;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+}
+
+static void
+png_read_filter_row_avg(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_size_t i;
+ png_bytep rp = row;
+ png_const_bytep pp = prev_row;
+ unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+ png_size_t istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) / 2 )) & 0xff);
+
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *(rp-bpp)) / 2 ) & 0xff);
+
+ rp++;
+ }
+}
+
+static void
+png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ png_bytep rp_end = row + row_info->rowbytes;
+ int a, c;
+
+ /* First pixel/byte */
+ c = *prev_row++;
+ a = *row + c;
+ *row++ = (png_byte)a;
+
+ /* Remainder */
+ while (row < rp_end)
+ {
+ int b, pa, pb, pc, p;
+
+ a &= 0xff; /* From previous iteration or start */
+ b = *prev_row++;
+
+ p = b - c;
+ pc = a - c;
+
+# ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+# else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+# endif
+
+ /* Find the best predictor, the least of pa, pb, pc favoring the earlier
+ * ones in the case of a tie.
+ */
+ if (pb < pa) pa = pb, a = b;
+ if (pc < pa) a = c;
+
+ /* Calculate the current pixel in a, and move the previous row pixel to c
+ * for the next time round the loop
+ */
+ c = b;
+ a += *row;
+ *row++ = (png_byte)a;
+ }
+}
+
+static void
+png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row)
+{
+ int bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp_end = row + bpp;
+
+ /* Process the first pixel in the row completely (this is the same as 'up'
+ * because there is only one candidate predictor for the first row).
+ */
+ while (row < rp_end)
+ {
+ int a = *row + *prev_row++;
+ *row++ = (png_byte)a;
+ }
+
+ /* Remainder */
+ rp_end += row_info->rowbytes - bpp;
+
+ while (row < rp_end)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ c = *(prev_row - bpp);
+ a = *(row - bpp);
+ b = *prev_row++;
+
+ p = b - c;
+ pc = a - c;
+
+# ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+# else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+# endif
+
+ if (pb < pa) pa = pb, a = b;
+ if (pc < pa) a = c;
+
+ c = b;
+ a += *row;
+ *row++ = (png_byte)a;
+ }
+}
+
+static void
+png_init_filter_functions(png_structrp pp)
+ /* This function is called once for every PNG image to set the
+ * implementations required to reverse the filtering of PNG rows. Reversing
+ * the filter is the first transformation performed on the row data. It is
+ * performed in place, therefore an implementation can be selected based on
+ * the image pixel format. If the implementation depends on image width then
+ * take care to ensure that it works correctly if the image is interlaced -
+ * interlacing causes the actual row width to vary.
+ */
+{
+ unsigned int bpp = (pp->pixel_depth + 7) >> 3;
+
+ pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub;
+ pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up;
+ pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg;
+ if (bpp == 1)
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth_1byte_pixel;
+ else
+ pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
+ png_read_filter_row_paeth_multibyte_pixel;
+
+#ifdef PNG_FILTER_OPTIMIZATIONS
+ /* To use this define PNG_FILTER_OPTIMIZATIONS as the name of a function to
+ * call to install hardware optimizations for the above functions; simply
+ * replace whatever elements of the pp->read_filter[] array with a hardware
+ * specific (or, for that matter, generic) optimization.
+ *
+ * To see an example of this examine what configure.ac does when
+ * --enable-arm-neon is specified on the command line.
+ */
+ PNG_FILTER_OPTIMIZATIONS(pp, bpp);
+#endif
+}
+
+void /* PRIVATE */
+png_read_filter_row(png_structrp pp, png_row_infop row_info, png_bytep row,
+ png_const_bytep prev_row, int filter)
+{
+ /* OPTIMIZATION: DO NOT MODIFY THIS FUNCTION, instead #define
+ * PNG_FILTER_OPTIMIZATIONS to a function that overrides the generic
+ * implementations. See png_init_filter_functions above.
+ */
+ if (pp->read_filter[0] == NULL)
+ png_init_filter_functions(pp);
+ if (filter > PNG_FILTER_VALUE_NONE && filter < PNG_FILTER_VALUE_LAST)
+ pp->read_filter[filter-1](row_info, row, prev_row);
+}
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+void /* PRIVATE */
+png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
+ png_alloc_size_t avail_out)
+{
+ /* Loop reading IDATs and decompressing the result into output[avail_out] */
+ png_ptr->zstream.next_out = output;
+ png_ptr->zstream.avail_out = 0; /* safety: set below */
+
+ if (output == NULL)
+ avail_out = 0;
+
+ do
+ {
+ int ret;
+ png_byte tmpbuf[PNG_INFLATE_BUF_SIZE];
+
+ if (png_ptr->zstream.avail_in == 0)
+ {
+ uInt avail_in;
+ png_bytep buffer;
+
+ while (png_ptr->idat_size == 0)
+ {
+ png_crc_finish(png_ptr, 0);
+
+ png_ptr->idat_size = png_read_chunk_header(png_ptr);
+ /* This is an error even in the 'check' case because the code just
+ * consumed a non-IDAT header.
+ */
+ if (png_ptr->chunk_name != png_IDAT)
+ png_error(png_ptr, "Not enough image data");
+ }
+
+ avail_in = png_ptr->IDAT_read_size;
+
+ if (avail_in > png_ptr->idat_size)
+ avail_in = (uInt)png_ptr->idat_size;
+
+ /* A PNG with a gradually increasing IDAT size will defeat this attempt
+ * to minimize memory usage by causing lots of re-allocs, but
+ * realistically doing IDAT_read_size re-allocs is not likely to be a
+ * big problem.
+ */
+ buffer = png_read_buffer(png_ptr, avail_in, 0/*error*/);
+
+ png_crc_read(png_ptr, buffer, avail_in);
+ png_ptr->idat_size -= avail_in;
+
+ png_ptr->zstream.next_in = buffer;
+ png_ptr->zstream.avail_in = avail_in;
+ }
+
+ /* And set up the output side. */
+ if (output != NULL) /* standard read */
+ {
+ uInt out = ZLIB_IO_MAX;
+
+ if (out > avail_out)
+ out = (uInt)avail_out;
+
+ avail_out -= out;
+ png_ptr->zstream.avail_out = out;
+ }
+
+ else /* after last row, checking for end */
+ {
+ png_ptr->zstream.next_out = tmpbuf;
+ png_ptr->zstream.avail_out = (sizeof tmpbuf);
+ }
+
+ /* Use NO_FLUSH; this gives zlib the maximum opportunity to optimize the
+ * process. If the LZ stream is truncated the sequential reader will
+ * terminally damage the stream, above, by reading the chunk header of the
+ * following chunk (it then exits with png_error).
+ *
+ * TODO: deal more elegantly with truncated IDAT lists.
+ */
+ ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
+
+ /* Take the unconsumed output back. */
+ if (output != NULL)
+ avail_out += png_ptr->zstream.avail_out;
+
+ else /* avail_out counts the extra bytes */
+ avail_out += (sizeof tmpbuf) - png_ptr->zstream.avail_out;
+
+ png_ptr->zstream.avail_out = 0;
+
+ if (ret == Z_STREAM_END)
+ {
+ /* Do this for safety; we won't read any more into this row. */
+ png_ptr->zstream.next_out = NULL;
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+
+ if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0)
+ png_chunk_benign_error(png_ptr, "Extra compressed data");
+ break;
+ }
+
+ if (ret != Z_OK)
+ {
+ png_zstream_error(png_ptr, ret);
+
+ if (output != NULL)
+ png_chunk_error(png_ptr, png_ptr->zstream.msg);
+
+ else /* checking */
+ {
+ png_chunk_benign_error(png_ptr, png_ptr->zstream.msg);
+ return;
+ }
+ }
+ } while (avail_out > 0);
+
+ if (avail_out > 0)
+ {
+ /* The stream ended before the image; this is the same as too few IDATs so
+ * should be handled the same way.
+ */
+ if (output != NULL)
+ png_error(png_ptr, "Not enough image data");
+
+ else /* the deflate stream contained extra data */
+ png_chunk_benign_error(png_ptr, "Too much image data");
+ }
+}
+
+void /* PRIVATE */
+png_read_finish_IDAT(png_structrp png_ptr)
+{
+ /* We don't need any more data and the stream should have ended, however the
+ * LZ end code may actually not have been processed. In this case we must
+ * read it otherwise stray unread IDAT data or, more likely, an IDAT chunk
+ * may still remain to be consumed.
+ */
+ if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ {
+ /* The NULL causes png_read_IDAT_data to swallow any remaining bytes in
+ * the compressed stream, but the stream may be damaged too, so even after
+ * this call we may need to terminate the zstream ownership.
+ */
+ png_read_IDAT_data(png_ptr, NULL, 0);
+ png_ptr->zstream.next_out = NULL; /* safety */
+
+ /* Now clear everything out for safety; the following may not have been
+ * done.
+ */
+ if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED))
+ {
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
+ }
+ }
+
+ /* If the zstream has not been released do it now *and* terminate the reading
+ * of the final IDAT chunk.
+ */
+ if (png_ptr->zowner == png_IDAT)
+ {
+ /* Always do this; the pointers otherwise point into the read buffer. */
+ png_ptr->zstream.next_in = NULL;
+ png_ptr->zstream.avail_in = 0;
+
+ /* Now we no longer own the zstream. */
+ png_ptr->zowner = 0;
+
+ /* The slightly weird semantics of the sequential IDAT reading is that we
+ * are always in or at the end of an IDAT chunk, so we always need to do a
+ * crc_finish here. If idat_size is non-zero we also need to read the
+ * spurious bytes at the end of the chunk now.
+ */
+ (void)png_crc_finish(png_ptr, png_ptr->idat_size);
+ }
+}
+
+void /* PRIVATE */
+png_read_finish_row(png_structrp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+ png_debug(1, "in png_read_finish_row");
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+
+ /* TO DO: don't do this if prev_row isn't needed (requires
+ * read-ahead of the next row's filter byte.
+ */
+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ do
+ {
+ png_ptr->pass++;
+
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ }
+
+ else /* if (png_ptr->transformations & PNG_INTERLACE) */
+ break; /* libpng deinterlacing sees every row */
+
+ } while (png_ptr->num_rows == 0 || png_ptr->iwidth == 0);
+
+ if (png_ptr->pass < 7)
+ return;
+ }
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+ /* Here after at the end of the last row of the last pass. */
+ png_read_finish_IDAT(png_ptr);
+}
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
+
+void /* PRIVATE */
+png_read_start_row(png_structrp png_ptr)
+{
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ int max_pixel_depth;
+ png_size_t row_bytes;
+
+ png_debug(1, "in png_read_start_row");
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+ png_init_read_transformations(png_ptr);
+#endif
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+
+ else
+ png_ptr->num_rows = png_ptr->height;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+ }
+
+ else
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->iwidth = png_ptr->width;
+ }
+
+ max_pixel_depth = png_ptr->pixel_depth;
+
+ /* WARNING: * png_read_transform_info (pngrtran.c) performs a simpliar set of
+ * calculations to calculate the final pixel depth, then
+ * png_do_read_transforms actually does the transforms. This means that the
+ * code which effectively calculates this value is actually repeated in three
+ * separate places. They must all match. Innocent changes to the order of
+ * transformations can and will break libpng in a way that causes memory
+ * overwrites.
+ *
+ * TODO: fix this.
+ */
+#ifdef PNG_READ_PACK_SUPPORTED
+ if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
+ max_pixel_depth = 8;
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 24;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth < 8)
+ max_pixel_depth = 8;
+
+ if (png_ptr->num_trans)
+ max_pixel_depth *= 2;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (png_ptr->num_trans)
+ {
+ max_pixel_depth *= 4;
+ max_pixel_depth /= 3;
+ }
+ }
+ }
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+ if (png_ptr->transformations & PNG_EXPAND_16)
+ {
+# ifdef PNG_READ_EXPAND_SUPPORTED
+ /* In fact it is an error if it isn't supported, but checking is
+ * the safe way.
+ */
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->bit_depth < 16)
+ max_pixel_depth *= 2;
+ }
+ else
+# endif
+ png_ptr->transformations &= ~PNG_EXPAND_16;
+ }
+#endif
+
+#ifdef PNG_READ_FILLER_SUPPORTED
+ if (png_ptr->transformations & (PNG_FILLER))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth <= 8)
+ max_pixel_depth = 16;
+
+ else
+ max_pixel_depth = 32;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB ||
+ png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (max_pixel_depth <= 32)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 64;
+ }
+ }
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ {
+ if (
+#ifdef PNG_READ_EXPAND_SUPPORTED
+ (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
+#endif
+#ifdef PNG_READ_FILLER_SUPPORTED
+ (png_ptr->transformations & (PNG_FILLER)) ||
+#endif
+ png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (max_pixel_depth <= 16)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 64;
+ }
+
+ else
+ {
+ if (max_pixel_depth <= 8)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 32;
+
+ else
+ max_pixel_depth = 24;
+ }
+
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 64;
+
+ else
+ max_pixel_depth = 48;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ int user_pixel_depth = png_ptr->user_transform_depth *
+ png_ptr->user_transform_channels;
+
+ if (user_pixel_depth > max_pixel_depth)
+ max_pixel_depth = user_pixel_depth;
+ }
+#endif
+
+ /* This value is stored in png_struct and double checked in the row read
+ * code.
+ */
+ png_ptr->maximum_pixel_depth = (png_byte)max_pixel_depth;
+ png_ptr->transformed_pixel_depth = 0; /* calculated on demand */
+
+ /* Align the width on the next larger 8 pixels. Mainly used
+ * for interlacing
+ */
+ row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+ /* Calculate the maximum bytes needed, adding a byte and a pixel
+ * for safety's sake
+ */
+ row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
+ 1 + ((max_pixel_depth + 7) >> 3);
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (row_bytes > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+
+ if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
+ {
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->big_prev_row);
+
+ if (png_ptr->interlaced)
+ png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+ row_bytes + 48);
+
+ else
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+
+ png_ptr->big_prev_row = (png_bytep)png_malloc(png_ptr, row_bytes + 48);
+
+#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
+ /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+ * of padding before and after row_buf; treat prev_row similarly.
+ * NOTE: the alignment is to the start of the pixels, one beyond the start
+ * of the buffer, because of the filter byte. Prior to libpng 1.5.6 this
+ * was incorrect; the filter byte was aligned, which had the exact
+ * opposite effect of that intended.
+ */
+ {
+ png_bytep temp = png_ptr->big_row_buf + 32;
+ int extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->row_buf = temp - extra - 1/*filter byte*/;
+
+ temp = png_ptr->big_prev_row + 32;
+ extra = (int)((temp - (png_bytep)0) & 0x0f);
+ png_ptr->prev_row = temp - extra - 1/*filter byte*/;
+ }
+
+#else
+ /* Use 31 bytes of padding before and 17 bytes after row_buf. */
+ png_ptr->row_buf = png_ptr->big_row_buf + 31;
+ png_ptr->prev_row = png_ptr->big_prev_row + 31;
+#endif
+ png_ptr->old_big_row_buf_size = row_bytes + 48;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (png_ptr->rowbytes > 65535)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+
+#endif
+ if (png_ptr->rowbytes > (PNG_SIZE_MAX - 1))
+ png_error(png_ptr, "Row has too many bytes to allocate in memory");
+
+ memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ png_debug1(3, "width = %u,", png_ptr->width);
+ png_debug1(3, "height = %u,", png_ptr->height);
+ png_debug1(3, "iwidth = %u,", png_ptr->iwidth);
+ png_debug1(3, "num_rows = %u,", png_ptr->num_rows);
+ png_debug1(3, "rowbytes = %lu,", (unsigned long)png_ptr->rowbytes);
+ png_debug1(3, "irowbytes = %lu",
+ (unsigned long)PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
+
+ /* The sequential reader needs a buffer for IDAT, but the progressive reader
+ * does not, so free the read buffer now regardless; the sequential reader
+ * reallocates it on demand.
+ */
+ if (png_ptr->read_buffer)
+ {
+ png_bytep buffer = png_ptr->read_buffer;
+
+ png_ptr->read_buffer_size = 0;
+ png_ptr->read_buffer = NULL;
+ png_free(png_ptr, buffer);
+ }
+
+ /* Finally claim the zstream for the inflate of the IDAT data, use the bits
+ * value from the stream (note that this will result in a fatal error if the
+ * IDAT stream has a bogus deflate header window_bits value, but this should
+ * not be happening any longer!)
+ */
+ if (png_inflate_claim(png_ptr, png_IDAT) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
+#endif /* PNG_READ_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngset.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngset.c
new file mode 100644
index 0000000000..8fd7445f2f
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngset.c
@@ -0,0 +1,1598 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngset.c - storage of image information into info struct
+ *
+ * Last changed in libpng 1.6.3 [July 18, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file. This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#ifdef PNG_bKGD_SUPPORTED
+void PNGAPI
+png_set_bKGD(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_color_16p background)
+{
+ png_debug1(1, "in %s storage function", "bKGD");
+
+ if (png_ptr == NULL || info_ptr == NULL || background == NULL)
+ return;
+
+ info_ptr->background = *background;
+ info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+void PNGFAPI
+png_set_cHRM_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+ png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+ png_fixed_point blue_x, png_fixed_point blue_y)
+{
+ png_xy xy;
+
+ png_debug1(1, "in %s storage function", "cHRM fixed");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ xy.redx = red_x;
+ xy.redy = red_y;
+ xy.greenx = green_x;
+ xy.greeny = green_y;
+ xy.bluex = blue_x;
+ xy.bluey = blue_y;
+ xy.whitex = white_x;
+ xy.whitey = white_y;
+
+ if (png_colorspace_set_chromaticities(png_ptr, &info_ptr->colorspace, &xy,
+ 2/* override with app values*/))
+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+void PNGFAPI
+png_set_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_fixed_point int_red_X, png_fixed_point int_red_Y,
+ png_fixed_point int_red_Z, png_fixed_point int_green_X,
+ png_fixed_point int_green_Y, png_fixed_point int_green_Z,
+ png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
+ png_fixed_point int_blue_Z)
+{
+ png_XYZ XYZ;
+
+ png_debug1(1, "in %s storage function", "cHRM XYZ fixed");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ XYZ.red_X = int_red_X;
+ XYZ.red_Y = int_red_Y;
+ XYZ.red_Z = int_red_Z;
+ XYZ.green_X = int_green_X;
+ XYZ.green_Y = int_green_Y;
+ XYZ.green_Z = int_green_Z;
+ XYZ.blue_X = int_blue_X;
+ XYZ.blue_Y = int_blue_Y;
+ XYZ.blue_Z = int_blue_Z;
+
+ if (png_colorspace_set_endpoints(png_ptr, &info_ptr->colorspace, &XYZ, 2))
+ info_ptr->colorspace.flags |= PNG_COLORSPACE_FROM_cHRM;
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
+ double white_x, double white_y, double red_x, double red_y,
+ double green_x, double green_y, double blue_x, double blue_y)
+{
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ png_fixed(png_ptr, white_x, "cHRM White X"),
+ png_fixed(png_ptr, white_y, "cHRM White Y"),
+ png_fixed(png_ptr, red_x, "cHRM Red X"),
+ png_fixed(png_ptr, red_y, "cHRM Red Y"),
+ png_fixed(png_ptr, green_x, "cHRM Green X"),
+ png_fixed(png_ptr, green_y, "cHRM Green Y"),
+ png_fixed(png_ptr, blue_x, "cHRM Blue X"),
+ png_fixed(png_ptr, blue_y, "cHRM Blue Y"));
+}
+
+void PNGAPI
+png_set_cHRM_XYZ(png_const_structrp png_ptr, png_inforp info_ptr, double red_X,
+ double red_Y, double red_Z, double green_X, double green_Y, double green_Z,
+ double blue_X, double blue_Y, double blue_Z)
+{
+ png_set_cHRM_XYZ_fixed(png_ptr, info_ptr,
+ png_fixed(png_ptr, red_X, "cHRM Red X"),
+ png_fixed(png_ptr, red_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, red_Z, "cHRM Red Z"),
+ png_fixed(png_ptr, green_X, "cHRM Red X"),
+ png_fixed(png_ptr, green_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, green_Z, "cHRM Red Z"),
+ png_fixed(png_ptr, blue_X, "cHRM Red X"),
+ png_fixed(png_ptr, blue_Y, "cHRM Red Y"),
+ png_fixed(png_ptr, blue_Z, "cHRM Red Z"));
+}
+# endif /* PNG_FLOATING_POINT_SUPPORTED */
+
+#endif /* PNG_cHRM_SUPPORTED */
+
+#ifdef PNG_gAMA_SUPPORTED
+void PNGFAPI
+png_set_gAMA_fixed(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_fixed_point file_gamma)
+{
+ png_debug1(1, "in %s storage function", "gAMA");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_colorspace_set_gamma(png_ptr, &info_ptr->colorspace, file_gamma);
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_const_structrp png_ptr, png_inforp info_ptr, double file_gamma)
+{
+ png_set_gAMA_fixed(png_ptr, info_ptr, png_fixed(png_ptr, file_gamma,
+ "png_set_gAMA"));
+}
+# endif
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+void PNGAPI
+png_set_hIST(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_uint_16p hist)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function", "hIST");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (info_ptr->num_palette == 0 || info_ptr->num_palette
+ > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr,
+ "Invalid palette size, hIST allocation skipped");
+
+ return;
+ }
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+
+ /* Changed from info->num_palette to PNG_MAX_PALETTE_LENGTH in
+ * version 1.2.1
+ */
+ info_ptr->hist = png_voidcast(png_uint_16p, png_malloc_warn(png_ptr,
+ PNG_MAX_PALETTE_LENGTH * (sizeof (png_uint_16))));
+
+ if (info_ptr->hist == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for hIST chunk data");
+ return;
+ }
+
+ info_ptr->free_me |= PNG_FREE_HIST;
+
+ for (i = 0; i < info_ptr->num_palette; i++)
+ info_ptr->hist[i] = hist[i];
+
+ info_ptr->valid |= PNG_INFO_hIST;
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ png_debug1(1, "in %s storage function", "IHDR");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->width = width;
+ info_ptr->height = height;
+ info_ptr->bit_depth = (png_byte)bit_depth;
+ info_ptr->color_type = (png_byte)color_type;
+ info_ptr->compression_type = (png_byte)compression_type;
+ info_ptr->filter_type = (png_byte)filter_type;
+ info_ptr->interlace_type = (png_byte)interlace_type;
+
+ png_check_IHDR (png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type,
+ info_ptr->compression_type, info_ptr->filter_type);
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+
+ else
+ info_ptr->channels = 1;
+
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+ info_ptr->rowbytes = PNG_ROWBYTES(info_ptr->pixel_depth, width);
+}
+
+#ifdef PNG_oFFs_SUPPORTED
+void PNGAPI
+png_set_oFFs(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function", "oFFs");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_offset = offset_x;
+ info_ptr->y_offset = offset_y;
+ info_ptr->offset_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+void PNGAPI
+png_set_pCAL(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_charp purpose, png_int_32 X0, png_int_32 X1, int type,
+ int nparams, png_const_charp units, png_charpp params)
+{
+ png_size_t length;
+ int i;
+
+ png_debug1(1, "in %s storage function", "pCAL");
+
+ if (png_ptr == NULL || info_ptr == NULL || purpose == NULL || units == NULL
+ || (nparams > 0 && params == NULL))
+ return;
+
+ length = strlen(purpose) + 1;
+ png_debug1(3, "allocating purpose for info (%lu bytes)",
+ (unsigned long)length);
+
+ /* TODO: validate format of calibration name and unit name */
+
+ /* Check that the type matches the specification. */
+ if (type < 0 || type > 3)
+ png_error(png_ptr, "Invalid pCAL equation type");
+
+ if (nparams < 0 || nparams > 255)
+ png_error(png_ptr, "Invalid pCAL parameter count");
+
+ /* Validate params[nparams] */
+ for (i=0; i<nparams; ++i)
+ if (params[i] == NULL ||
+ !png_check_fp_string(params[i], strlen(params[i])))
+ png_error(png_ptr, "Invalid format for pCAL parameter");
+
+ info_ptr->pcal_purpose = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, length));
+
+ if (info_ptr->pcal_purpose == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL purpose");
+ return;
+ }
+
+ memcpy(info_ptr->pcal_purpose, purpose, length);
+
+ png_debug(3, "storing X0, X1, type, and nparams in info");
+ info_ptr->pcal_X0 = X0;
+ info_ptr->pcal_X1 = X1;
+ info_ptr->pcal_type = (png_byte)type;
+ info_ptr->pcal_nparams = (png_byte)nparams;
+
+ length = strlen(units) + 1;
+ png_debug1(3, "allocating units for info (%lu bytes)",
+ (unsigned long)length);
+
+ info_ptr->pcal_units = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, length));
+
+ if (info_ptr->pcal_units == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL units");
+ return;
+ }
+
+ memcpy(info_ptr->pcal_units, units, length);
+
+ info_ptr->pcal_params = png_voidcast(png_charpp, png_malloc_warn(png_ptr,
+ (png_size_t)((nparams + 1) * (sizeof (png_charp)))));
+
+ if (info_ptr->pcal_params == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL params");
+ return;
+ }
+
+ memset(info_ptr->pcal_params, 0, (nparams + 1) * (sizeof (png_charp)));
+
+ for (i = 0; i < nparams; i++)
+ {
+ length = strlen(params[i]) + 1;
+ png_debug2(3, "allocating parameter %d for info (%lu bytes)", i,
+ (unsigned long)length);
+
+ info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+
+ if (info_ptr->pcal_params[i] == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL parameter");
+ return;
+ }
+
+ memcpy(info_ptr->pcal_params[i], params[i], length);
+ }
+
+ info_ptr->valid |= PNG_INFO_pCAL;
+ info_ptr->free_me |= PNG_FREE_PCAL;
+}
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_const_structrp png_ptr, png_inforp info_ptr,
+ int unit, png_const_charp swidth, png_const_charp sheight)
+{
+ png_size_t lengthw = 0, lengthh = 0;
+
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Double check the unit (should never get here with an invalid
+ * unit unless this is an API call.)
+ */
+ if (unit != 1 && unit != 2)
+ png_error(png_ptr, "Invalid sCAL unit");
+
+ if (swidth == NULL || (lengthw = strlen(swidth)) == 0 ||
+ swidth[0] == 45 /* '-' */ || !png_check_fp_string(swidth, lengthw))
+ png_error(png_ptr, "Invalid sCAL width");
+
+ if (sheight == NULL || (lengthh = strlen(sheight)) == 0 ||
+ sheight[0] == 45 /* '-' */ || !png_check_fp_string(sheight, lengthh))
+ png_error(png_ptr, "Invalid sCAL height");
+
+ info_ptr->scal_unit = (png_byte)unit;
+
+ ++lengthw;
+
+ png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthw);
+
+ info_ptr->scal_s_width = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, lengthw));
+
+ if (info_ptr->scal_s_width == NULL)
+ {
+ png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+ return;
+ }
+
+ memcpy(info_ptr->scal_s_width, swidth, lengthw);
+
+ ++lengthh;
+
+ png_debug1(3, "allocating unit for info (%u bytes)", (unsigned int)lengthh);
+
+ info_ptr->scal_s_height = png_voidcast(png_charp,
+ png_malloc_warn(png_ptr, lengthh));
+
+ if (info_ptr->scal_s_height == NULL)
+ {
+ png_free (png_ptr, info_ptr->scal_s_width);
+ info_ptr->scal_s_width = NULL;
+
+ png_warning(png_ptr, "Memory allocation failed while processing sCAL");
+ return;
+ }
+
+ memcpy(info_ptr->scal_s_height, sheight, lengthh);
+
+ info_ptr->valid |= PNG_INFO_sCAL;
+ info_ptr->free_me |= PNG_FREE_SCAL;
+}
+
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
+ double width, double height)
+{
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ /* Check the arguments. */
+ if (width <= 0)
+ png_warning(png_ptr, "Invalid sCAL width ignored");
+
+ else if (height <= 0)
+ png_warning(png_ptr, "Invalid sCAL height ignored");
+
+ else
+ {
+ /* Convert 'width' and 'height' to ASCII. */
+ char swidth[PNG_sCAL_MAX_DIGITS+1];
+ char sheight[PNG_sCAL_MAX_DIGITS+1];
+
+ png_ascii_from_fp(png_ptr, swidth, (sizeof swidth), width,
+ PNG_sCAL_PRECISION);
+ png_ascii_from_fp(png_ptr, sheight, (sizeof sheight), height,
+ PNG_sCAL_PRECISION);
+
+ png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
+ }
+}
+# endif
+
+# ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_fixed(png_const_structrp png_ptr, png_inforp info_ptr, int unit,
+ png_fixed_point width, png_fixed_point height)
+{
+ png_debug1(1, "in %s storage function", "sCAL");
+
+ /* Check the arguments. */
+ if (width <= 0)
+ png_warning(png_ptr, "Invalid sCAL width ignored");
+
+ else if (height <= 0)
+ png_warning(png_ptr, "Invalid sCAL height ignored");
+
+ else
+ {
+ /* Convert 'width' and 'height' to ASCII. */
+ char swidth[PNG_sCAL_MAX_DIGITS+1];
+ char sheight[PNG_sCAL_MAX_DIGITS+1];
+
+ png_ascii_from_fixed(png_ptr, swidth, (sizeof swidth), width);
+ png_ascii_from_fixed(png_ptr, sheight, (sizeof sheight), height);
+
+ png_set_sCAL_s(png_ptr, info_ptr, unit, swidth, sheight);
+ }
+}
+# endif
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+void PNGAPI
+png_set_pHYs(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function", "pHYs");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_pixels_per_unit = res_x;
+ info_ptr->y_pixels_per_unit = res_y;
+ info_ptr->phys_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
+ png_const_colorp palette, int num_palette)
+{
+
+ png_debug1(1, "in %s storage function", "PLTE");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (num_palette < 0 || num_palette > PNG_MAX_PALETTE_LENGTH)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Invalid palette length");
+
+ else
+ {
+ png_warning(png_ptr, "Invalid palette length");
+ return;
+ }
+ }
+
+ if ((num_palette > 0 && palette == NULL) ||
+ (num_palette == 0
+# ifdef PNG_MNG_FEATURES_SUPPORTED
+ && (png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) == 0
+# endif
+ ))
+ {
+ png_chunk_report(png_ptr, "Invalid palette", PNG_CHUNK_ERROR);
+ return;
+ }
+
+ /* It may not actually be necessary to set png_ptr->palette here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ *
+ * 1.6.0: the above statement appears to be incorrect; something has to set
+ * the palette inside png_struct on read.
+ */
+ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+
+ /* Changed in libpng-1.2.1 to allocate PNG_MAX_PALETTE_LENGTH instead
+ * of num_palette entries, in case of an invalid PNG file that has
+ * too-large sample values.
+ */
+ png_ptr->palette = png_voidcast(png_colorp, png_calloc(png_ptr,
+ PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))));
+
+ if (num_palette > 0)
+ memcpy(png_ptr->palette, palette, num_palette * (sizeof (png_color)));
+ info_ptr->palette = png_ptr->palette;
+ info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+ info_ptr->free_me |= PNG_FREE_PLTE;
+
+ info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#ifdef PNG_sBIT_SUPPORTED
+void PNGAPI
+png_set_sBIT(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_color_8p sig_bit)
+{
+ png_debug1(1, "in %s storage function", "sBIT");
+
+ if (png_ptr == NULL || info_ptr == NULL || sig_bit == NULL)
+ return;
+
+ info_ptr->sig_bit = *sig_bit;
+ info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+void PNGAPI
+png_set_sRGB(png_const_structrp png_ptr, png_inforp info_ptr, int srgb_intent)
+{
+ png_debug1(1, "in %s storage function", "sRGB");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ (void)png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent);
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_const_structrp png_ptr, png_inforp info_ptr,
+ int srgb_intent)
+{
+ png_debug1(1, "in %s storage function", "sRGB_gAMA_and_cHRM");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (png_colorspace_set_sRGB(png_ptr, &info_ptr->colorspace, srgb_intent))
+ {
+ /* This causes the gAMA and cHRM to be written too */
+ info_ptr->colorspace.flags |=
+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+ }
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+}
+#endif /* sRGB */
+
+
+#ifdef PNG_iCCP_SUPPORTED
+void PNGAPI
+png_set_iCCP(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_charp name, int compression_type,
+ png_const_bytep profile, png_uint_32 proflen)
+{
+ png_charp new_iccp_name;
+ png_bytep new_iccp_profile;
+ png_size_t length;
+
+ png_debug1(1, "in %s storage function", "iCCP");
+
+ if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+ return;
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ png_app_error(png_ptr, "Invalid iCCP compression method");
+
+ /* Set the colorspace first because this validates the profile; do not
+ * override previously set app cHRM or gAMA here (because likely as not the
+ * application knows better than libpng what the correct values are.) Pass
+ * the info_ptr color_type field to png_colorspace_set_ICC because in the
+ * write case it has not yet been stored in png_ptr.
+ */
+ {
+ int result = png_colorspace_set_ICC(png_ptr, &info_ptr->colorspace, name,
+ proflen, profile, info_ptr->color_type);
+
+ png_colorspace_sync_info(png_ptr, info_ptr);
+
+ /* Don't do any of the copying if the profile was bad, or inconsistent. */
+ if (!result)
+ return;
+
+ /* But do write the gAMA and cHRM chunks from the profile. */
+ info_ptr->colorspace.flags |=
+ PNG_COLORSPACE_FROM_gAMA|PNG_COLORSPACE_FROM_cHRM;
+ }
+
+ length = strlen(name)+1;
+ new_iccp_name = png_voidcast(png_charp, png_malloc_warn(png_ptr, length));
+
+ if (new_iccp_name == NULL)
+ {
+ png_benign_error(png_ptr, "Insufficient memory to process iCCP chunk");
+ return;
+ }
+
+ memcpy(new_iccp_name, name, length);
+ new_iccp_profile = png_voidcast(png_bytep,
+ png_malloc_warn(png_ptr, proflen));
+
+ if (new_iccp_profile == NULL)
+ {
+ png_free(png_ptr, new_iccp_name);
+ png_benign_error(png_ptr,
+ "Insufficient memory to process iCCP profile");
+ return;
+ }
+
+ memcpy(new_iccp_profile, profile, proflen);
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+ info_ptr->iccp_proflen = proflen;
+ info_ptr->iccp_name = new_iccp_name;
+ info_ptr->iccp_profile = new_iccp_profile;
+ info_ptr->free_me |= PNG_FREE_ICCP;
+ info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+void PNGAPI
+png_set_text(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_textp text_ptr, int num_text)
+{
+ int ret;
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_textp text_ptr, int num_text)
+{
+ int i;
+
+ png_debug1(1, "in %lx storage function", png_ptr == NULL ? "unexpected" :
+ (unsigned long)png_ptr->chunk_name);
+
+ if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL)
+ return(0);
+
+ /* Make sure we have enough space in the "text" array in info_struct
+ * to hold all of the incoming text_ptr objects. This compare can't overflow
+ * because max_text >= num_text (anyway, subtract of two positive integers
+ * can't overflow in any case.)
+ */
+ if (num_text > info_ptr->max_text - info_ptr->num_text)
+ {
+ int old_num_text = info_ptr->num_text;
+ int max_text;
+ png_textp new_text = NULL;
+
+ /* Calculate an appropriate max_text, checking for overflow. */
+ max_text = old_num_text;
+ if (num_text <= INT_MAX - max_text)
+ {
+ max_text += num_text;
+
+ /* Round up to a multiple of 8 */
+ if (max_text < INT_MAX-8)
+ max_text = (max_text + 8) & ~0x7;
+
+ else
+ max_text = INT_MAX;
+
+ /* Now allocate a new array and copy the old members in, this does all
+ * the overflow checks.
+ */
+ new_text = png_voidcast(png_textp,png_realloc_array(png_ptr,
+ info_ptr->text, old_num_text, max_text-old_num_text,
+ sizeof *new_text));
+ }
+
+ if (new_text == NULL)
+ {
+ png_chunk_report(png_ptr, "too many text chunks",
+ PNG_CHUNK_WRITE_ERROR);
+ return 1;
+ }
+
+ png_free(png_ptr, info_ptr->text);
+
+ info_ptr->text = new_text;
+ info_ptr->free_me |= PNG_FREE_TEXT;
+ info_ptr->max_text = max_text;
+ /* num_text is adjusted below as the entries are copied in */
+
+ png_debug1(3, "allocated %d entries for info_ptr->text", max_text);
+ }
+
+ for (i = 0; i < num_text; i++)
+ {
+ size_t text_length, key_len;
+ size_t lang_len, lang_key_len;
+ png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+ if (text_ptr[i].key == NULL)
+ continue;
+
+ if (text_ptr[i].compression < PNG_TEXT_COMPRESSION_NONE ||
+ text_ptr[i].compression >= PNG_TEXT_COMPRESSION_LAST)
+ {
+ png_chunk_report(png_ptr, "text compression mode is out of range",
+ PNG_CHUNK_WRITE_ERROR);
+ continue;
+ }
+
+ key_len = strlen(text_ptr[i].key);
+
+ if (text_ptr[i].compression <= 0)
+ {
+ lang_len = 0;
+ lang_key_len = 0;
+ }
+
+ else
+# ifdef PNG_iTXt_SUPPORTED
+ {
+ /* Set iTXt data */
+
+ if (text_ptr[i].lang != NULL)
+ lang_len = strlen(text_ptr[i].lang);
+
+ else
+ lang_len = 0;
+
+ if (text_ptr[i].lang_key != NULL)
+ lang_key_len = strlen(text_ptr[i].lang_key);
+
+ else
+ lang_key_len = 0;
+ }
+# else /* PNG_iTXt_SUPPORTED */
+ {
+ png_chunk_report(png_ptr, "iTXt chunk not supported",
+ PNG_CHUNK_WRITE_ERROR);
+ continue;
+ }
+# endif
+
+ if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+ {
+ text_length = 0;
+# ifdef PNG_iTXt_SUPPORTED
+ if (text_ptr[i].compression > 0)
+ textp->compression = PNG_ITXT_COMPRESSION_NONE;
+
+ else
+# endif
+ textp->compression = PNG_TEXT_COMPRESSION_NONE;
+ }
+
+ else
+ {
+ text_length = strlen(text_ptr[i].text);
+ textp->compression = text_ptr[i].compression;
+ }
+
+ textp->key = png_voidcast(png_charp,png_malloc_base(png_ptr,
+ key_len + text_length + lang_len + lang_key_len + 4));
+
+ if (textp->key == NULL)
+ {
+ png_chunk_report(png_ptr, "text chunk: out of memory",
+ PNG_CHUNK_WRITE_ERROR);
+ return 1;
+ }
+
+ png_debug2(2, "Allocated %lu bytes at %p in png_set_text",
+ (unsigned long)(png_uint_32)
+ (key_len + lang_len + lang_key_len + text_length + 4),
+ textp->key);
+
+ memcpy(textp->key, text_ptr[i].key, key_len);
+ *(textp->key + key_len) = '\0';
+
+ if (text_ptr[i].compression > 0)
+ {
+ textp->lang = textp->key + key_len + 1;
+ memcpy(textp->lang, text_ptr[i].lang, lang_len);
+ *(textp->lang + lang_len) = '\0';
+ textp->lang_key = textp->lang + lang_len + 1;
+ memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+ *(textp->lang_key + lang_key_len) = '\0';
+ textp->text = textp->lang_key + lang_key_len + 1;
+ }
+
+ else
+ {
+ textp->lang=NULL;
+ textp->lang_key=NULL;
+ textp->text = textp->key + key_len + 1;
+ }
+
+ if (text_length)
+ memcpy(textp->text, text_ptr[i].text, text_length);
+
+ *(textp->text + text_length) = '\0';
+
+# ifdef PNG_iTXt_SUPPORTED
+ if (textp->compression > 0)
+ {
+ textp->text_length = 0;
+ textp->itxt_length = text_length;
+ }
+
+ else
+# endif
+ {
+ textp->text_length = text_length;
+ textp->itxt_length = 0;
+ }
+
+ info_ptr->num_text++;
+ png_debug1(3, "transferred text chunk %d", info_ptr->num_text);
+ }
+
+ return(0);
+}
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+void PNGAPI
+png_set_tIME(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_const_timep mod_time)
+{
+ png_debug1(1, "in %s storage function", "tIME");
+
+ if (png_ptr == NULL || info_ptr == NULL || mod_time == NULL ||
+ (png_ptr->mode & PNG_WROTE_tIME))
+ return;
+
+ if (mod_time->month == 0 || mod_time->month > 12 ||
+ mod_time->day == 0 || mod_time->day > 31 ||
+ mod_time->hour > 23 || mod_time->minute > 59 ||
+ mod_time->second > 60)
+ {
+ png_warning(png_ptr, "Ignoring invalid time value");
+ return;
+ }
+
+ info_ptr->mod_time = *mod_time;
+ info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+void PNGAPI
+png_set_tRNS(png_structrp png_ptr, png_inforp info_ptr,
+ png_const_bytep trans_alpha, int num_trans, png_const_color_16p trans_color)
+{
+ png_debug1(1, "in %s storage function", "tRNS");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (trans_alpha != NULL)
+ {
+ /* It may not actually be necessary to set png_ptr->trans_alpha here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ *
+ * 1.6.0: The above statement is incorrect; png_handle_tRNS effectively
+ * relies on png_set_tRNS storing the information in png_struct
+ * (otherwise it won't be there for the code in pngrtran.c).
+ */
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+
+ /* Changed from num_trans to PNG_MAX_PALETTE_LENGTH in version 1.2.1 */
+ png_ptr->trans_alpha = info_ptr->trans_alpha = png_voidcast(png_bytep,
+ png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
+
+ if (num_trans > 0 && num_trans <= PNG_MAX_PALETTE_LENGTH)
+ memcpy(info_ptr->trans_alpha, trans_alpha, (png_size_t)num_trans);
+ }
+
+ if (trans_color != NULL)
+ {
+ int sample_max = (1 << info_ptr->bit_depth);
+
+ if ((info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
+ trans_color->gray > sample_max) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB &&
+ (trans_color->red > sample_max ||
+ trans_color->green > sample_max ||
+ trans_color->blue > sample_max)))
+ png_warning(png_ptr,
+ "tRNS chunk has out-of-range samples for bit_depth");
+
+ info_ptr->trans_color = *trans_color;
+
+ if (num_trans == 0)
+ num_trans = 1;
+ }
+
+ info_ptr->num_trans = (png_uint_16)num_trans;
+
+ if (num_trans != 0)
+ {
+ info_ptr->valid |= PNG_INFO_tRNS;
+ info_ptr->free_me |= PNG_FREE_TRNS;
+ }
+}
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+void PNGAPI
+png_set_sPLT(png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries)
+/*
+ * entries - array of png_sPLT_t structures
+ * to be added to the list of palettes
+ * in the info structure.
+ *
+ * nentries - number of palette structures to be
+ * added.
+ */
+{
+ png_sPLT_tp np;
+
+ if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL)
+ return;
+
+ /* Use the internal realloc function, which checks for all the possible
+ * overflows. Notice that the parameters are (int) and (size_t)
+ */
+ np = png_voidcast(png_sPLT_tp,png_realloc_array(png_ptr,
+ info_ptr->splt_palettes, info_ptr->splt_palettes_num, nentries,
+ sizeof *np));
+
+ if (np == NULL)
+ {
+ /* Out of memory or too many chunks */
+ png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
+ return;
+ }
+
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = np;
+ info_ptr->free_me |= PNG_FREE_SPLT;
+
+ np += info_ptr->splt_palettes_num;
+
+ do
+ {
+ png_size_t length;
+
+ /* Skip invalid input entries */
+ if (entries->name == NULL || entries->entries == NULL)
+ {
+ /* png_handle_sPLT doesn't do this, so this is an app error */
+ png_app_error(png_ptr, "png_set_sPLT: invalid sPLT");
+ /* Just skip the invalid entry */
+ continue;
+ }
+
+ np->depth = entries->depth;
+
+ /* In the even of out-of-memory just return - there's no point keeping on
+ * trying to add sPLT chunks.
+ */
+ length = strlen(entries->name) + 1;
+ np->name = png_voidcast(png_charp, png_malloc_base(png_ptr, length));
+
+ if (np->name == NULL)
+ break;
+
+ memcpy(np->name, entries->name, length);
+
+ /* IMPORTANT: we have memory now that won't get freed if something else
+ * goes wrong, this code must free it. png_malloc_array produces no
+ * warnings, use a png_chunk_report (below) if there is an error.
+ */
+ np->entries = png_voidcast(png_sPLT_entryp, png_malloc_array(png_ptr,
+ entries->nentries, sizeof (png_sPLT_entry)));
+
+ if (np->entries == NULL)
+ {
+ png_free(png_ptr, np->name);
+ break;
+ }
+
+ np->nentries = entries->nentries;
+ /* This multiply can't overflow because png_malloc_array has already
+ * checked it when doing the allocation.
+ */
+ memcpy(np->entries, entries->entries,
+ entries->nentries * sizeof (png_sPLT_entry));
+
+ /* Note that 'continue' skips the advance of the out pointer and out
+ * count, so an invalid entry is not added.
+ */
+ info_ptr->valid |= PNG_INFO_sPLT;
+ ++(info_ptr->splt_palettes_num);
+ ++np;
+ }
+ while (++entries, --nentries);
+
+ if (nentries > 0)
+ png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+static png_byte
+check_location(png_const_structrp png_ptr, int location)
+{
+ location &= (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT);
+
+ /* New in 1.6.0; copy the location and check it. This is an API
+ * change, previously the app had to use the
+ * png_set_unknown_chunk_location API below for each chunk.
+ */
+ if (location == 0 && !(png_ptr->mode & PNG_IS_READ_STRUCT))
+ {
+ /* Write struct, so unknown chunks come from the app */
+ png_app_warning(png_ptr,
+ "png_set_unknown_chunks now expects a valid location");
+ /* Use the old behavior */
+ location = (png_byte)(png_ptr->mode &
+ (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT));
+ }
+
+ /* This need not be an internal error - if the app calls
+ * png_set_unknown_chunks on a read pointer it must get the location right.
+ */
+ if (location == 0)
+ png_error(png_ptr, "invalid location in png_set_unknown_chunks");
+
+ /* Now reduce the location to the top-most set bit by removing each least
+ * significant bit in turn.
+ */
+ while (location != (location & -location))
+ location &= ~(location & -location);
+
+ /* The cast is safe because 'location' is a bit mask and only the low four
+ * bits are significant.
+ */
+ return (png_byte)location;
+}
+
+void PNGAPI
+png_set_unknown_chunks(png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns, int num_unknowns)
+{
+ png_unknown_chunkp np;
+
+ if (png_ptr == NULL || info_ptr == NULL || num_unknowns <= 0 ||
+ unknowns == NULL)
+ return;
+
+ /* Check for the failure cases where support has been disabled at compile
+ * time. This code is hardly ever compiled - it's here because
+ * STORE_UNKNOWN_CHUNKS is set by both read and write code (compiling in this
+ * code) but may be meaningless if the read or write handling of unknown
+ * chunks is not compiled in.
+ */
+# if !defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) && \
+ defined(PNG_READ_SUPPORTED)
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
+ {
+ png_app_error(png_ptr, "no unknown chunk support on read");
+ return;
+ }
+# endif
+# if !defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED) && \
+ defined(PNG_WRITE_SUPPORTED)
+ if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
+ {
+ png_app_error(png_ptr, "no unknown chunk support on write");
+ return;
+ }
+# endif
+
+ /* Prior to 1.6.0 this code used png_malloc_warn; however, this meant that
+ * unknown critical chunks could be lost with just a warning resulting in
+ * undefined behavior. Now png_chunk_report is used to provide behavior
+ * appropriate to read or write.
+ */
+ np = png_voidcast(png_unknown_chunkp, png_realloc_array(png_ptr,
+ info_ptr->unknown_chunks, info_ptr->unknown_chunks_num, num_unknowns,
+ sizeof *np));
+
+ if (np == NULL)
+ {
+ png_chunk_report(png_ptr, "too many unknown chunks",
+ PNG_CHUNK_WRITE_ERROR);
+ return;
+ }
+
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = np; /* safe because it is initialized */
+ info_ptr->free_me |= PNG_FREE_UNKN;
+
+ np += info_ptr->unknown_chunks_num;
+
+ /* Increment unknown_chunks_num each time round the loop to protect the
+ * just-allocated chunk data.
+ */
+ for (; num_unknowns > 0; --num_unknowns, ++unknowns)
+ {
+ memcpy(np->name, unknowns->name, (sizeof np->name));
+ np->name[(sizeof np->name)-1] = '\0';
+ np->location = check_location(png_ptr, unknowns->location);
+
+ if (unknowns->size == 0)
+ {
+ np->data = NULL;
+ np->size = 0;
+ }
+
+ else
+ {
+ np->data = png_voidcast(png_bytep,
+ png_malloc_base(png_ptr, unknowns->size));
+
+ if (np->data == NULL)
+ {
+ png_chunk_report(png_ptr, "unknown chunk: out of memory",
+ PNG_CHUNK_WRITE_ERROR);
+ /* But just skip storing the unknown chunk */
+ continue;
+ }
+
+ memcpy(np->data, unknowns->data, unknowns->size);
+ np->size = unknowns->size;
+ }
+
+ /* These increments are skipped on out-of-memory for the data - the
+ * unknown chunk entry gets overwritten if the png_chunk_report returns.
+ * This is correct in the read case (the chunk is just dropped.)
+ */
+ ++np;
+ ++(info_ptr->unknown_chunks_num);
+ }
+}
+
+void PNGAPI
+png_set_unknown_chunk_location(png_const_structrp png_ptr, png_inforp info_ptr,
+ int chunk, int location)
+{
+ /* This API is pretty pointless in 1.6.0 because the location can be set
+ * before the call to png_set_unknown_chunks.
+ *
+ * TODO: add a png_app_warning in 1.7
+ */
+ if (png_ptr != NULL && info_ptr != NULL && chunk >= 0 &&
+ chunk < info_ptr->unknown_chunks_num)
+ {
+ if ((location & (PNG_HAVE_IHDR|PNG_HAVE_PLTE|PNG_AFTER_IDAT)) == 0)
+ {
+ png_app_error(png_ptr, "invalid unknown chunk location");
+ /* Fake out the pre 1.6.0 behavior: */
+ if ((location & PNG_HAVE_IDAT)) /* undocumented! */
+ location = PNG_AFTER_IDAT;
+
+ else
+ location = PNG_HAVE_IHDR; /* also undocumented */
+ }
+
+ info_ptr->unknown_chunks[chunk].location =
+ check_location(png_ptr, location);
+ }
+}
+#endif
+
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structrp png_ptr, png_uint_32 mng_features)
+{
+ png_debug(1, "in png_permit_mng_features");
+
+ if (png_ptr == NULL)
+ return 0;
+
+ png_ptr->mng_features_permitted = mng_features & PNG_ALL_MNG_FEATURES;
+
+ return png_ptr->mng_features_permitted;
+}
+#endif
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+static unsigned int
+add_one_chunk(png_bytep list, unsigned int count, png_const_bytep add, int keep)
+{
+ unsigned int i;
+
+ /* Utility function: update the 'keep' state of a chunk if it is already in
+ * the list, otherwise add it to the list.
+ */
+ for (i=0; i<count; ++i, list += 5) if (memcmp(list, add, 4) == 0)
+ {
+ list[4] = (png_byte)keep;
+ return count;
+ }
+
+ if (keep != PNG_HANDLE_CHUNK_AS_DEFAULT)
+ {
+ ++count;
+ memcpy(list, add, 4);
+ list[4] = (png_byte)keep;
+ }
+
+ return count;
+}
+
+void PNGAPI
+png_set_keep_unknown_chunks(png_structrp png_ptr, int keep,
+ png_const_bytep chunk_list, int num_chunks_in)
+{
+ png_bytep new_list;
+ unsigned int num_chunks, old_num_chunks;
+
+ if (png_ptr == NULL)
+ return;
+
+ if (keep < 0 || keep >= PNG_HANDLE_CHUNK_LAST)
+ {
+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: invalid keep");
+ return;
+ }
+
+ if (num_chunks_in <= 0)
+ {
+ png_ptr->unknown_default = keep;
+
+ /* '0' means just set the flags, so stop here */
+ if (num_chunks_in == 0)
+ return;
+ }
+
+ if (num_chunks_in < 0)
+ {
+ /* Ignore all unknown chunks and all chunks recognized by
+ * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND
+ */
+ static PNG_CONST png_byte chunks_to_ignore[] = {
+ 98, 75, 71, 68, '\0', /* bKGD */
+ 99, 72, 82, 77, '\0', /* cHRM */
+ 103, 65, 77, 65, '\0', /* gAMA */
+ 104, 73, 83, 84, '\0', /* hIST */
+ 105, 67, 67, 80, '\0', /* iCCP */
+ 105, 84, 88, 116, '\0', /* iTXt */
+ 111, 70, 70, 115, '\0', /* oFFs */
+ 112, 67, 65, 76, '\0', /* pCAL */
+ 112, 72, 89, 115, '\0', /* pHYs */
+ 115, 66, 73, 84, '\0', /* sBIT */
+ 115, 67, 65, 76, '\0', /* sCAL */
+ 115, 80, 76, 84, '\0', /* sPLT */
+ 115, 84, 69, 82, '\0', /* sTER */
+ 115, 82, 71, 66, '\0', /* sRGB */
+ 116, 69, 88, 116, '\0', /* tEXt */
+ 116, 73, 77, 69, '\0', /* tIME */
+ 122, 84, 88, 116, '\0' /* zTXt */
+ };
+
+ chunk_list = chunks_to_ignore;
+ num_chunks = (sizeof chunks_to_ignore)/5;
+ }
+
+ else /* num_chunks_in > 0 */
+ {
+ if (chunk_list == NULL)
+ {
+ /* Prior to 1.6.0 this was silently ignored, now it is an app_error
+ * which can be switched off.
+ */
+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: no chunk list");
+ return;
+ }
+
+ num_chunks = num_chunks_in;
+ }
+
+ old_num_chunks = png_ptr->num_chunk_list;
+ if (png_ptr->chunk_list == NULL)
+ old_num_chunks = 0;
+
+ /* Since num_chunks is always restricted to UINT_MAX/5 this can't overflow.
+ */
+ if (num_chunks + old_num_chunks > UINT_MAX/5)
+ {
+ png_app_error(png_ptr, "png_set_keep_unknown_chunks: too many chunks");
+ return;
+ }
+
+ /* If these chunks are being reset to the default then no more memory is
+ * required because add_one_chunk above doesn't extend the list if the 'keep'
+ * parameter is the default.
+ */
+ if (keep)
+ {
+ new_list = png_voidcast(png_bytep, png_malloc(png_ptr,
+ 5 * (num_chunks + old_num_chunks)));
+
+ if (old_num_chunks > 0)
+ memcpy(new_list, png_ptr->chunk_list, 5*old_num_chunks);
+ }
+
+ else if (old_num_chunks > 0)
+ new_list = png_ptr->chunk_list;
+
+ else
+ new_list = NULL;
+
+ /* Add the new chunks together with each one's handling code. If the chunk
+ * already exists the code is updated, otherwise the chunk is added to the
+ * end. (In libpng 1.6.0 order no longer matters because this code enforces
+ * the earlier convention that the last setting is the one that is used.)
+ */
+ if (new_list != NULL)
+ {
+ png_const_bytep inlist;
+ png_bytep outlist;
+ unsigned int i;
+
+ for (i=0; i<num_chunks; ++i)
+ old_num_chunks = add_one_chunk(new_list, old_num_chunks,
+ chunk_list+5*i, keep);
+
+ /* Now remove any spurious 'default' entries. */
+ num_chunks = 0;
+ for (i=0, inlist=outlist=new_list; i<old_num_chunks; ++i, inlist += 5)
+ if (inlist[4])
+ {
+ if (outlist != inlist)
+ memcpy(outlist, inlist, 5);
+ outlist += 5;
+ ++num_chunks;
+ }
+
+ /* This means the application has removed all the specialized handling. */
+ if (num_chunks == 0)
+ {
+ if (png_ptr->chunk_list != new_list)
+ png_free(png_ptr, new_list);
+
+ new_list = NULL;
+ }
+ }
+
+ else
+ num_chunks = 0;
+
+ png_ptr->num_chunk_list = num_chunks;
+
+ if (png_ptr->chunk_list != new_list)
+ {
+ if (png_ptr->chunk_list != NULL)
+ png_free(png_ptr, png_ptr->chunk_list);
+
+ png_ptr->chunk_list = new_list;
+ }
+}
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+void PNGAPI
+png_set_read_user_chunk_fn(png_structrp png_ptr, png_voidp user_chunk_ptr,
+ png_user_chunk_ptr read_user_chunk_fn)
+{
+ png_debug(1, "in png_set_read_user_chunk_fn");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+ png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr,
+ png_bytepp row_pointers)
+{
+ png_debug1(1, "in %s storage function", "rows");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+
+ info_ptr->row_pointers = row_pointers;
+
+ if (row_pointers)
+ info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+void PNGAPI
+png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
+{
+ if (png_ptr == NULL)
+ return;
+
+ if (size == 0 || size > PNG_UINT_31_MAX)
+ png_error(png_ptr, "invalid compression buffer size");
+
+# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
+ {
+ png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
+ return;
+ }
+# endif
+
+# ifdef PNG_WRITE_SUPPORTED
+ if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
+ {
+ if (png_ptr->zowner != 0)
+ {
+ png_warning(png_ptr,
+ "Compression buffer size cannot be changed because it is in use");
+ return;
+ }
+
+ if (size > ZLIB_IO_MAX)
+ {
+ png_warning(png_ptr,
+ "Compression buffer size limited to system maximum");
+ size = ZLIB_IO_MAX; /* must fit */
+ }
+
+ else if (size < 6)
+ {
+ /* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
+ * if this is permitted.
+ */
+ png_warning(png_ptr,
+ "Compression buffer size cannot be reduced below 6");
+ return;
+ }
+
+ if (png_ptr->zbuffer_size != size)
+ {
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+ png_ptr->zbuffer_size = (uInt)size;
+ }
+ }
+# endif
+}
+
+void PNGAPI
+png_set_invalid(png_const_structrp png_ptr, png_inforp info_ptr, int mask)
+{
+ if (png_ptr && info_ptr)
+ info_ptr->valid &= ~mask;
+}
+
+
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+/* This function was added to libpng 1.2.6 */
+void PNGAPI
+png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
+ png_uint_32 user_height_max)
+{
+ /* Images with dimensions larger than these limits will be
+ * rejected by png_set_IHDR(). To accept any PNG datastream
+ * regardless of dimensions, set both limits to 0x7ffffffL.
+ */
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->user_width_max = user_width_max;
+ png_ptr->user_height_max = user_height_max;
+}
+
+/* This function was added to libpng 1.4.0 */
+void PNGAPI
+png_set_chunk_cache_max (png_structrp png_ptr, png_uint_32 user_chunk_cache_max)
+{
+ if (png_ptr)
+ png_ptr->user_chunk_cache_max = user_chunk_cache_max;
+}
+
+/* This function was added to libpng 1.4.1 */
+void PNGAPI
+png_set_chunk_malloc_max (png_structrp png_ptr,
+ png_alloc_size_t user_chunk_malloc_max)
+{
+ if (png_ptr)
+ png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
+}
+#endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
+
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+void PNGAPI
+png_set_benign_errors(png_structrp png_ptr, int allowed)
+{
+ png_debug(1, "in png_set_benign_errors");
+
+ /* If allowed is 1, png_benign_error() is treated as a warning.
+ *
+ * If allowed is 0, png_benign_error() is treated as an error (which
+ * is the default behavior if png_set_benign_errors() is not called).
+ */
+
+ if (allowed)
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN |
+ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN;
+
+ else
+ png_ptr->flags &= ~(PNG_FLAG_BENIGN_ERRORS_WARN |
+ PNG_FLAG_APP_WARNINGS_WARN | PNG_FLAG_APP_ERRORS_WARN);
+}
+#endif /* PNG_BENIGN_ERRORS_SUPPORTED */
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Whether to report invalid palette index; added at libng-1.5.10.
+ * It is possible for an indexed (color-type==3) PNG file to contain
+ * pixels with invalid (out-of-range) indexes if the PLTE chunk has
+ * fewer entries than the image's bit-depth would allow. We recover
+ * from this gracefully by filling any incomplete palette with zeroes
+ * (opaque black). By default, when this occurs libpng will issue
+ * a benign error. This API can be used to override that behavior.
+ */
+void PNGAPI
+png_set_check_for_invalid_index(png_structrp png_ptr, int allowed)
+{
+ png_debug(1, "in png_set_check_for_invalid_index");
+
+ if (allowed > 0)
+ png_ptr->num_palette_max = 0;
+
+ else
+ png_ptr->num_palette_max = -1;
+}
+#endif
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngtrans.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngtrans.c
new file mode 100644
index 0000000000..a46b0fc331
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngtrans.c
@@ -0,0 +1,842 @@
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+#include "pngpriv.h"
+
+#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_bgr");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Turn on 16 bit byte swapping */
+void PNGAPI
+png_set_swap(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_swap");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (png_ptr->bit_depth == 16)
+ png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_packing");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (png_ptr->bit_depth < 8)
+ {
+ png_ptr->transformations |= PNG_PACK;
+ png_ptr->usr_bit_depth = 8;
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_packswap");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (png_ptr->bit_depth < 8)
+ png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structrp png_ptr, png_const_color_8p true_bits)
+{
+ png_debug(1, "in png_set_shift");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_SHIFT;
+ png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_interlace handling");
+
+ if (png_ptr && png_ptr->interlaced)
+ {
+ png_ptr->transformations |= PNG_INTERLACE;
+ return (7);
+ }
+
+ return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_filler");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* In libpng 1.6 it is possible to determine whether this is a read or write
+ * operation and therefore to do more checking here for a valid call.
+ */
+ if (png_ptr->mode & PNG_IS_READ_STRUCT)
+ {
+# ifdef PNG_READ_FILLER_SUPPORTED
+ /* On read png_set_filler is always valid, regardless of the base PNG
+ * format, because other transformations can give a format where the
+ * filler code can execute (basically an 8 or 16-bit component RGB or G
+ * format.)
+ *
+ * NOTE: usr_channels is not used by the read code! (This has led to
+ * confusion in the past.) The filler is only used in the read code.
+ */
+ png_ptr->filler = (png_uint_16)filler;
+# else
+ png_app_error(png_ptr, "png_set_filler not supported on read");
+ PNG_UNUSED(filler) /* not used in the write case */
+ return;
+# endif
+ }
+
+ else /* write */
+ {
+# ifdef PNG_WRITE_FILLER_SUPPORTED
+ /* On write the usr_channels parameter must be set correctly at the
+ * start to record the number of channels in the app-supplied data.
+ */
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ png_ptr->usr_channels = 4;
+ break;
+
+ case PNG_COLOR_TYPE_GRAY:
+ if (png_ptr->bit_depth >= 8)
+ {
+ png_ptr->usr_channels = 2;
+ break;
+ }
+
+ else
+ {
+ /* There simply isn't any code in libpng to strip out bits
+ * from bytes when the components are less than a byte in
+ * size!
+ */
+ png_app_error(png_ptr,
+ "png_set_filler is invalid for low bit depth gray output");
+ return;
+ }
+
+ default:
+ png_app_error(png_ptr,
+ "png_set_filler: inappropriate color type");
+ return;
+ }
+# else
+ png_app_error(png_ptr, "png_set_filler not supported on write");
+ return;
+# endif
+ }
+
+ /* Here on success - libpng supports the operation, set the transformation
+ * and the flag to say where the filler channel is.
+ */
+ png_ptr->transformations |= PNG_FILLER;
+
+ if (filler_loc == PNG_FILLER_AFTER)
+ png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+
+ else
+ png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+}
+
+/* Added to libpng-1.2.7 */
+void PNGAPI
+png_set_add_alpha(png_structrp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_add_alpha");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_set_filler(png_ptr, filler, filler_loc);
+ /* The above may fail to do anything. */
+ if (png_ptr->transformations & PNG_FILLER)
+ png_ptr->transformations |= PNG_ADD_ALPHA;
+}
+
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_swap_alpha");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_invert_alpha");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structrp png_ptr)
+{
+ png_debug(1, "in png_set_invert_mono");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* Invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_invert");
+
+ /* This test removed from libpng version 1.0.13 and 1.2.0:
+ * if (row_info->bit_depth == 1 &&
+ */
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_bytep rp = row;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp++;
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 8)
+ {
+ png_bytep rp = row;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i += 2)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp += 2;
+ }
+ }
+
+#ifdef PNG_16BIT_SUPPORTED
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_size_t i;
+ png_size_t istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i += 4)
+ {
+ *rp = (png_byte)(~(*rp));
+ *(rp + 1) = (png_byte)(~(*(rp + 1)));
+ rp += 4;
+ }
+ }
+#endif
+}
+#endif
+
+#ifdef PNG_16BIT_SUPPORTED
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swaps byte order on 16 bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_swap");
+
+ if (row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop= row_info->width * row_info->channels;
+
+ for (i = 0; i < istop; i++, rp += 2)
+ {
+ png_byte t = *rp;
+ *rp = *(rp + 1);
+ *(rp + 1) = t;
+ }
+ }
+}
+#endif
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static PNG_CONST png_byte onebppswaptable[256] = {
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static PNG_CONST png_byte twobppswaptable[256] = {
+ 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+ 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+ 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+ 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+ 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+ 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+ 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+ 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+ 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+ 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+ 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+ 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+ 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+ 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+ 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+ 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+ 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+ 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+ 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+ 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+ 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+ 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+ 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+ 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+ 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+ 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+ 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+ 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+ 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+ 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+ 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+ 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static PNG_CONST png_byte fourbppswaptable[256] = {
+ 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+ 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+ 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+ 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+ 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+ 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+ 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+ 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+ 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+ 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+ 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+ 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+ 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+ 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+ 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+ 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+ 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+ 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+ 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+ 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+ 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+ 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+ 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+ 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+ 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+ 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+ 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+ 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+ 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+ 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+ 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* Swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_packswap");
+
+ if (row_info->bit_depth < 8)
+ {
+ png_bytep rp;
+ png_const_bytep end, table;
+
+ end = row + row_info->rowbytes;
+
+ if (row_info->bit_depth == 1)
+ table = onebppswaptable;
+
+ else if (row_info->bit_depth == 2)
+ table = twobppswaptable;
+
+ else if (row_info->bit_depth == 4)
+ table = fourbppswaptable;
+
+ else
+ return;
+
+ for (rp = row; rp < end; rp++)
+ *rp = table[*rp];
+ }
+}
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* Remove a channel - this used to be 'png_do_strip_filler' but it used a
+ * somewhat weird combination of flags to determine what to do. All the calls
+ * to png_do_strip_filler are changed in 1.5.2 to call this instead with the
+ * correct arguments.
+ *
+ * The routine isn't general - the channel must be the channel at the start or
+ * end (not in the middle) of each pixel.
+ */
+void /* PRIVATE */
+png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
+{
+ png_bytep sp = row; /* source pointer */
+ png_bytep dp = row; /* destination pointer */
+ png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */
+
+ /* At the start sp will point to the first byte to copy and dp to where
+ * it is copied to. ep always points just beyond the end of the row, so
+ * the loop simply copies (channels-1) channels until sp reaches ep.
+ *
+ * at_start: 0 -- convert AG, XG, ARGB, XRGB, AAGG, XXGG, etc.
+ * nonzero -- convert GA, GX, RGBA, RGBX, GGAA, RRGGBBXX, etc.
+ */
+
+ /* GA, GX, XG cases */
+ if (row_info->channels == 2)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if (at_start) /* Skip initial filler */
+ ++sp;
+ else /* Skip initial channel and, for sp, the filler */
+ sp += 2, ++dp;
+
+ /* For a 1 pixel wide image there is nothing to do */
+ while (sp < ep)
+ *dp++ = *sp, sp += 2;
+
+ row_info->pixel_depth = 8;
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ if (at_start) /* Skip initial filler */
+ sp += 2;
+ else /* Skip initial channel and, for sp, the filler */
+ sp += 4, dp += 2;
+
+ while (sp < ep)
+ *dp++ = *sp++, *dp++ = *sp, sp += 3;
+
+ row_info->pixel_depth = 16;
+ }
+
+ else
+ return; /* bad bit depth */
+
+ row_info->channels = 1;
+
+ /* Finally fix the color type if it records an alpha channel */
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ row_info->color_type = PNG_COLOR_TYPE_GRAY;
+ }
+
+ /* RGBA, RGBX, XRGB cases */
+ else if (row_info->channels == 4)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ if (at_start) /* Skip initial filler */
+ ++sp;
+ else /* Skip initial channels and, for sp, the filler */
+ sp += 4, dp += 3;
+
+ /* Note that the loop adds 3 to dp and 4 to sp each time. */
+ while (sp < ep)
+ *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
+
+ row_info->pixel_depth = 24;
+ }
+
+ else if (row_info->bit_depth == 16)
+ {
+ if (at_start) /* Skip initial filler */
+ sp += 2;
+ else /* Skip initial channels and, for sp, the filler */
+ sp += 8, dp += 6;
+
+ while (sp < ep)
+ {
+ /* Copy 6 bytes, skip 2 */
+ *dp++ = *sp++, *dp++ = *sp++;
+ *dp++ = *sp++, *dp++ = *sp++;
+ *dp++ = *sp++, *dp++ = *sp, sp += 3;
+ }
+
+ row_info->pixel_depth = 48;
+ }
+
+ else
+ return; /* bad bit depth */
+
+ row_info->channels = 3;
+
+ /* Finally fix the color type if it records an alpha channel */
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ row_info->color_type = PNG_COLOR_TYPE_RGB;
+ }
+
+ else
+ return; /* The filler channel has gone already */
+
+ /* Fix the rowbytes value. */
+ row_info->rowbytes = dp-row;
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_bgr");
+
+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 3)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 4)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ }
+
+#ifdef PNG_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 6)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 8)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ }
+#endif
+ }
+}
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+
+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
+ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
+/* Added at libpng-1.5.10 */
+void /* PRIVATE */
+png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
+{
+ if (png_ptr->num_palette < (1 << row_info->bit_depth) &&
+ png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */
+ {
+ /* Calculations moved outside switch in an attempt to stop different
+ * compiler warnings. 'padding' is in *bits* within the last byte, it is
+ * an 'int' because pixel_depth becomes an 'int' in the expression below,
+ * and this calculation is used because it avoids warnings that other
+ * forms produced on either GCC or MSVC.
+ */
+ int padding = (-row_info->pixel_depth * row_info->width) & 7;
+ png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
+
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ /* in this case, all bytes must be 0 so we don't need
+ * to unpack the pixels except for the rightmost one.
+ */
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ if (*rp >> padding != 0)
+ png_ptr->num_palette_max = 1;
+ padding = 0;
+ }
+
+ break;
+ }
+
+ case 2:
+ {
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ int i = ((*rp >> padding) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 2) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 4) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 6) & 0x03);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ padding = 0;
+ }
+
+ break;
+ }
+
+ case 4:
+ {
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ int i = ((*rp >> padding) & 0x0f);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ i = (((*rp >> padding) >> 4) & 0x0f);
+
+ if (i > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = i;
+
+ padding = 0;
+ }
+
+ break;
+ }
+
+ case 8:
+ {
+ for (; rp > png_ptr->row_buf; rp--)
+ {
+ if (*rp > png_ptr->num_palette_max)
+ png_ptr->num_palette_max = (int) *rp;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+#endif /* PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+void PNGAPI
+png_set_user_transform_info(png_structrp png_ptr, png_voidp
+ user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+ png_debug(1, "in png_set_user_transform_info");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ if ((png_ptr->mode & PNG_IS_READ_STRUCT) != 0 &&
+ (png_ptr->flags & PNG_FLAG_ROW_INIT) != 0)
+ {
+ png_app_error(png_ptr,
+ "info change after png_start_read_image or png_read_update_info");
+ return;
+ }
+#endif
+
+ png_ptr->user_transform_ptr = user_transform_ptr;
+ png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+ png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions. The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_const_structrp png_ptr)
+{
+ if (png_ptr == NULL)
+ return (NULL);
+
+ return png_ptr->user_transform_ptr;
+}
+#endif
+
+#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
+png_uint_32 PNGAPI
+png_get_current_row_number(png_const_structrp png_ptr)
+{
+ /* See the comments in png.h - this is the sub-image row when reading and
+ * interlaced image.
+ */
+ if (png_ptr != NULL)
+ return png_ptr->row_number;
+
+ return PNG_UINT_32_MAX; /* help the app not to fail silently */
+}
+
+png_byte PNGAPI
+png_get_current_pass_number(png_const_structrp png_ptr)
+{
+ if (png_ptr != NULL)
+ return png_ptr->pass;
+ return 8; /* invalid */
+}
+#endif /* PNG_USER_TRANSFORM_INFO_SUPPORTED */
+#endif /* PNG_READ_USER_TRANSFORM_SUPPORTED ||
+ PNG_WRITE_USER_TRANSFORM_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */
+#endif
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwio.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwio.c
new file mode 100644
index 0000000000..5f3133e5d5
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwio.c
@@ -0,0 +1,165 @@
+
+/* pngwio.c - functions for data output
+ *
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ * This file provides a location for all output. Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods. Note that you shouldn't change these
+ * functions, but rather write replacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using. The default routine
+ * writes to a file pointer. Note that this routine sometimes gets called
+ * with very small lengths, so you should implement some kind of simple
+ * buffering if you are using unbuffered writes. This should never be asked
+ * to write more than 64K on a 16 bit machine.
+ */
+
+void /* PRIVATE */
+png_write_data(png_structrp png_ptr, png_const_bytep data, png_size_t length)
+{
+ /* NOTE: write_data_fn must not change the buffer! */
+ if (png_ptr->write_data_fn != NULL )
+ (*(png_ptr->write_data_fn))(png_ptr, png_constcast(png_bytep,data),
+ length);
+
+ else
+ png_error(png_ptr, "Call to NULL write function");
+}
+
+#ifdef PNG_STDIO_SUPPORTED
+/* This is the function that does the actual writing of data. If you are
+ * not writing to a standard C stream, you should create a replacement
+ * write_data function and use it at run time with png_set_write_fn(), rather
+ * than changing the library.
+ */
+void PNGCBAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ if (png_ptr == NULL)
+ return;
+
+ check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+#endif
+
+/* This function is called to output any data pending writing (normally
+ * to disk). After png_flush is called, there should be no data pending
+ * writing in any buffers.
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+void /* PRIVATE */
+png_flush(png_structrp png_ptr)
+{
+ if (png_ptr->output_flush_fn != NULL)
+ (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+# ifdef PNG_STDIO_SUPPORTED
+void PNGCBAPI
+png_default_flush(png_structp png_ptr)
+{
+ png_FILE_p io_ptr;
+
+ if (png_ptr == NULL)
+ return;
+
+ io_ptr = png_voidcast(png_FILE_p, (png_ptr->io_ptr));
+ fflush(io_ptr);
+}
+# endif
+#endif
+
+/* This function allows the application to supply new output functions for
+ * libpng if standard C streams aren't being used.
+ *
+ * This function takes as its arguments:
+ * png_ptr - pointer to a png output data structure
+ * io_ptr - pointer to user supplied structure containing info about
+ * the output functions. May be NULL.
+ * write_data_fn - pointer to a new output function that takes as its
+ * arguments a pointer to a png_struct, a pointer to
+ * data to be written, and a 32-bit unsigned int that is
+ * the number of bytes to be written. The new write
+ * function should call png_error(png_ptr, "Error msg")
+ * to exit and output any fatal error messages. May be
+ * NULL, in which case libpng's default function will
+ * be used.
+ * flush_data_fn - pointer to a new flush function that takes as its
+ * arguments a pointer to a png_struct. After a call to
+ * the flush function, there should be no data in any buffers
+ * or pending transmission. If the output method doesn't do
+ * any buffering of output, a function prototype must still be
+ * supplied although it doesn't have to do anything. If
+ * PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+ * time, output_flush_fn will be ignored, although it must be
+ * supplied for compatibility. May be NULL, in which case
+ * libpng's default function will be used, if
+ * PNG_WRITE_FLUSH_SUPPORTED is defined. This is not
+ * a good idea if io_ptr does not point to a standard
+ * *FILE structure.
+ */
+void PNGAPI
+png_set_write_fn(png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->io_ptr = io_ptr;
+
+#ifdef PNG_STDIO_SUPPORTED
+ if (write_data_fn != NULL)
+ png_ptr->write_data_fn = write_data_fn;
+
+ else
+ png_ptr->write_data_fn = png_default_write_data;
+#else
+ png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+# ifdef PNG_STDIO_SUPPORTED
+
+ if (output_flush_fn != NULL)
+ png_ptr->output_flush_fn = output_flush_fn;
+
+ else
+ png_ptr->output_flush_fn = png_default_flush;
+
+# else
+ png_ptr->output_flush_fn = output_flush_fn;
+# endif
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+ /* It is an error to read while writing a png file */
+ if (png_ptr->read_data_fn != NULL)
+ {
+ png_ptr->read_data_fn = NULL;
+
+ png_warning(png_ptr,
+ "Can't set both read_data_fn and write_data_fn in the"
+ " same structure");
+ }
+}
+#endif /* PNG_WRITE_SUPPORTED */
+#endif//_FPDFAPI_MINI_
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwrite.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwrite.c
new file mode 100644
index 0000000000..7efcfc3a26
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwrite.c
@@ -0,0 +1,2331 @@
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "pngpriv.h"
+#if defined(PNG_SIMPLIFIED_WRITE_SUPPORTED) && defined(PNG_STDIO_SUPPORTED)
+# include <errno.h>
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+/* Write out all the unknown chunks for the current given location */
+static void
+write_unknown_chunks(png_structrp png_ptr, png_const_inforp info_ptr,
+ unsigned int where)
+{
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_const_unknown_chunkp up;
+
+ png_debug(5, "writing extra chunks");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ ++up)
+ if (up->location & where)
+ {
+ /* If per-chunk unknown chunk handling is enabled use it, otherwise
+ * just write the chunks the application has set.
+ */
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ int keep = png_handle_as_unknown(png_ptr, up->name);
+
+ /* NOTE: this code is radically different from the read side in the
+ * matter of handling an ancillary unknown chunk. In the read side
+ * the default behavior is to discard it, in the code below the default
+ * behavior is to write it. Critical chunks are, however, only
+ * written if explicitly listed or if the default is set to write all
+ * unknown chunks.
+ *
+ * The default handling is also slightly weird - it is not possible to
+ * stop the writing of all unsafe-to-copy chunks!
+ *
+ * TODO: REVIEW: this would seem to be a bug.
+ */
+ if (keep != PNG_HANDLE_CHUNK_NEVER &&
+ ((up->name[3] & 0x20) /* safe-to-copy overrides everything */ ||
+ keep == PNG_HANDLE_CHUNK_ALWAYS ||
+ (keep == PNG_HANDLE_CHUNK_AS_DEFAULT &&
+ png_ptr->unknown_default == PNG_HANDLE_CHUNK_ALWAYS)))
+#endif
+ {
+ /* TODO: review, what is wrong with a zero length unknown chunk? */
+ if (up->size == 0)
+ png_warning(png_ptr, "Writing zero-length unknown chunk");
+
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+}
+#endif /* PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED */
+
+/* Writes all the PNG information. This is the suggested way to use the
+ * library. If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here. If you want the chunk written
+ * after the image data, put it in png_write_end(). I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file. If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structrp png_ptr, png_const_inforp info_ptr)
+{
+ png_debug(1, "in png_write_info_before_PLTE");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ {
+ /* Write PNG signature */
+ png_write_sig(png_ptr);
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) && \
+ (png_ptr->mng_features_permitted))
+ {
+ png_warning(png_ptr, "MNG features are not allowed in a PNG datastream");
+ png_ptr->mng_features_permitted = 0;
+ }
+#endif
+
+ /* Write IHDR information. */
+ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+ info_ptr->filter_type,
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ info_ptr->interlace_type
+#else
+ 0
+#endif
+ );
+
+ /* The rest of these check to see if the valid field has the appropriate
+ * flag set, and if it does, writes the chunk.
+ *
+ * 1.6.0: COLORSPACE support controls the writing of these chunks too, and
+ * the chunks will be written if the WRITE routine is there and information
+ * is available in the COLORSPACE. (See png_colorspace_sync_info in png.c
+ * for where the valid flags get set.)
+ *
+ * Under certain circumstances the colorspace can be invalidated without
+ * syncing the info_struct 'valid' flags; this happens if libpng detects and
+ * error and calls png_error while the color space is being set, yet the
+ * application continues writing the PNG. So check the 'invalid' flag here
+ * too.
+ */
+#ifdef PNG_GAMMA_SUPPORTED
+# ifdef PNG_WRITE_gAMA_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_gAMA) &&
+ (info_ptr->valid & PNG_INFO_gAMA))
+ png_write_gAMA_fixed(png_ptr, info_ptr->colorspace.gamma);
+# endif
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+ /* Write only one of sRGB or an ICC profile. If a profile was supplied
+ * and it matches one of the known sRGB ones issue a warning.
+ */
+# ifdef PNG_WRITE_iCCP_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->valid & PNG_INFO_iCCP))
+ {
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sRGB)
+ png_app_warning(png_ptr,
+ "profile matches sRGB but writing iCCP instead");
+# endif
+
+ png_write_iCCP(png_ptr, info_ptr->iccp_name,
+ info_ptr->iccp_profile);
+ }
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ else
+# endif
+# endif
+
+# ifdef PNG_WRITE_sRGB_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->valid & PNG_INFO_sRGB))
+ png_write_sRGB(png_ptr, info_ptr->colorspace.rendering_intent);
+# endif /* WRITE_sRGB */
+#endif /* COLORSPACE */
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sBIT)
+ png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+# ifdef PNG_WRITE_cHRM_SUPPORTED
+ if (!(info_ptr->colorspace.flags & PNG_COLORSPACE_INVALID) &&
+ (info_ptr->colorspace.flags & PNG_COLORSPACE_FROM_cHRM) &&
+ (info_ptr->valid & PNG_INFO_cHRM))
+ png_write_cHRM_fixed(png_ptr, &info_ptr->colorspace.end_points_xy);
+# endif
+#endif
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_IHDR);
+#endif
+
+ png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+ }
+}
+
+void PNGAPI
+png_write_info(png_structrp png_ptr, png_const_inforp info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+ int i;
+#endif
+
+ png_debug(1, "in png_write_info");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+
+ if (info_ptr->valid & PNG_INFO_PLTE)
+ png_write_PLTE(png_ptr, info_ptr->palette,
+ (png_uint_32)info_ptr->num_palette);
+
+ else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Valid palette required for paletted images");
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_tRNS)
+ {
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel (in tRNS) */
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
+ info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ int j;
+ for (j = 0; j<(int)info_ptr->num_trans; j++)
+ info_ptr->trans_alpha[j] =
+ (png_byte)(255 - info_ptr->trans_alpha[j]);
+ }
+#endif
+ png_write_tRNS(png_ptr, info_ptr->trans_alpha, &(info_ptr->trans_color),
+ info_ptr->num_trans, info_ptr->color_type);
+ }
+#endif
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_bKGD)
+ png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_hIST)
+ png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+ info_ptr->offset_unit_type);
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_pCAL)
+ png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+ info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+ info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sCAL)
+ png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_s_width, info_ptr->scal_s_height);
+#endif /* sCAL */
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+ info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif /* pHYs */
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_tIME)
+ {
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+ png_ptr->mode |= PNG_WROTE_tIME;
+ }
+#endif /* tIME */
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_sPLT)
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif /* sPLT */
+
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ /* Check to see if we need to write text chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing header text chunk %d, type %d", i,
+ info_ptr->text[i].compression);
+ /* An internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+ /* Write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+
+ /* If we want a compressed text chunk */
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+ {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+ /* Write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+ /* Write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text,
+ 0);
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+#else
+ /* Can't get here */
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+ }
+ }
+#endif /* tEXt */
+
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ write_unknown_chunks(png_ptr, info_ptr, PNG_HAVE_PLTE);
+#endif
+}
+
+/* Writes the end of the PNG file. If you don't want to write comments or
+ * time information, you can pass NULL for info. If you already wrote these
+ * in png_write_info(), do not write them again here. If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structrp png_ptr, png_inforp info_ptr)
+{
+ png_debug(1, "in png_write_end");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "No IDATs written into file");
+
+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ if (png_ptr->num_palette_max > png_ptr->num_palette)
+ png_benign_error(png_ptr, "Wrote palette index exceeding num_palette");
+#endif
+
+ /* See if user wants us to write information chunks */
+ if (info_ptr != NULL)
+ {
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ int i; /* local index variable */
+#endif
+#ifdef PNG_WRITE_tIME_SUPPORTED
+ /* Check to see if user has supplied a time chunk */
+ if ((info_ptr->valid & PNG_INFO_tIME) &&
+ !(png_ptr->mode & PNG_WROTE_tIME))
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+
+#endif
+#ifdef PNG_WRITE_TEXT_SUPPORTED
+ /* Loop through comment chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing trailer text chunk %d, type %d", i,
+ info_ptr->text[i].compression);
+ /* An internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+ /* Write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+
+ else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+ {
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+ /* Write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+ /* Write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0);
+#else
+ png_warning(png_ptr, "Unable to write uncompressed text");
+#endif
+
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ }
+#endif
+#ifdef PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+ write_unknown_chunks(png_ptr, info_ptr, PNG_AFTER_IDAT);
+#endif
+ }
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ /* Write end of PNG file */
+ png_write_IEND(png_ptr);
+ /* This flush, added in libpng-1.0.8, removed from libpng-1.0.9beta03,
+ * and restored again in libpng-1.2.30, may cause some applications that
+ * do not set png_ptr->output_flush_fn to crash. If your application
+ * experiences a problem, please try building libpng with
+ * PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED defined, and report the event to
+ * png-mng-implement at lists.sf.net .
+ */
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+# ifdef PNG_WRITE_FLUSH_AFTER_IEND_SUPPORTED
+ png_flush(png_ptr);
+# endif
+#endif
+}
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime)
+{
+ png_debug(1, "in png_convert_from_struct_tm");
+
+ ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+ ptime->month = (png_byte)(ttime->tm_mon + 1);
+ ptime->day = (png_byte)ttime->tm_mday;
+ ptime->hour = (png_byte)ttime->tm_hour;
+ ptime->minute = (png_byte)ttime->tm_min;
+ ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+ struct tm *tbuf;
+
+ png_debug(1, "in png_convert_from_time_t");
+
+ tbuf = gmtime(&ttime);
+ png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_write_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn),PNG_ALLOCATED)
+{
+#ifndef PNG_USER_MEM_SUPPORTED
+ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, NULL, NULL, NULL);
+#else
+ return png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, NULL, NULL, NULL);
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+PNG_FUNCTION(png_structp,PNGAPI
+png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn),PNG_ALLOCATED)
+{
+ png_structrp png_ptr = png_create_png_struct(user_png_ver, error_ptr,
+ error_fn, warn_fn, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+ if (png_ptr != NULL)
+ {
+ /* Set the zlib control values to defaults; they can be overridden by the
+ * application after the struct has been created.
+ */
+ png_ptr->zbuffer_size = PNG_ZBUF_SIZE;
+
+ /* The 'zlib_strategy' setting is irrelevant because png_default_claim in
+ * pngwutil.c defaults it according to whether or not filters will be
+ * used, and ignores this setting.
+ */
+ png_ptr->zlib_strategy = PNG_Z_DEFAULT_STRATEGY;
+ png_ptr->zlib_level = PNG_Z_DEFAULT_COMPRESSION;
+ png_ptr->zlib_mem_level = 8;
+ png_ptr->zlib_window_bits = 15;
+ png_ptr->zlib_method = 8;
+
+#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+ png_ptr->zlib_text_strategy = PNG_TEXT_Z_DEFAULT_STRATEGY;
+ png_ptr->zlib_text_level = PNG_TEXT_Z_DEFAULT_COMPRESSION;
+ png_ptr->zlib_text_mem_level = 8;
+ png_ptr->zlib_text_window_bits = 15;
+ png_ptr->zlib_text_method = 8;
+#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
+
+ /* This is a highly dubious configuration option; by default it is off,
+ * but it may be appropriate for private builds that are testing
+ * extensions not conformant to the current specification, or of
+ * applications that must not fail to write at all costs!
+ */
+#ifdef PNG_BENIGN_WRITE_ERRORS_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_BENIGN_ERRORS_WARN;
+ /* In stable builds only warn if an application error can be completely
+ * handled.
+ */
+#endif
+
+ /* App warnings are warnings in release (or release candidate) builds but
+ * are errors during development.
+ */
+#if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+ png_ptr->flags |= PNG_FLAG_APP_WARNINGS_WARN;
+#endif
+
+ /* TODO: delay this, it can be done in png_init_io() (if the app doesn't
+ * do it itself) avoiding setting the default function if it is not
+ * required.
+ */
+ png_set_write_fn(png_ptr, NULL, NULL, NULL);
+ }
+
+ return png_ptr;
+}
+
+
+/* Write a few rows of image data. If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structrp png_ptr, png_bytepp row,
+ png_uint_32 num_rows)
+{
+ png_uint_32 i; /* row counter */
+ png_bytepp rp; /* row pointer */
+
+ png_debug(1, "in png_write_rows");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* Loop through the rows */
+ for (i = 0, rp = row; i < num_rows; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+}
+
+/* Write the image. You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structrp png_ptr, png_bytepp image)
+{
+ png_uint_32 i; /* row index */
+ int pass, num_pass; /* pass variables */
+ png_bytepp rp; /* points to current row */
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug(1, "in png_write_image");
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Initialize interlace handling. If image is not interlaced,
+ * this will set pass to 1
+ */
+ num_pass = png_set_interlace_handling(png_ptr);
+#else
+ num_pass = 1;
+#endif
+ /* Loop through passes */
+ for (pass = 0; pass < num_pass; pass++)
+ {
+ /* Loop through image */
+ for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+ }
+}
+
+/* Called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structrp png_ptr, png_const_bytep row)
+{
+ /* 1.5.6: moved from png_struct to be a local structure: */
+ png_row_info row_info;
+
+ if (png_ptr == NULL)
+ return;
+
+ png_debug2(1, "in png_write_row (row %u, pass %d)",
+ png_ptr->row_number, png_ptr->pass);
+
+ /* Initialize transformations and other stuff if first time */
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* Make sure we wrote the header info */
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ png_error(png_ptr,
+ "png_write_info was never called before png_write_row");
+
+ /* Check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && \
+ defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr,
+ "PNG_WRITE_PACKSWAP_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined");
+#endif
+
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined");
+#endif
+
+ png_write_start_row(png_ptr);
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced and not interested in row, return */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 3:
+ if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 4:
+ if ((png_ptr->row_number & 0x03) != 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 5:
+ if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ case 6:
+ if (!(png_ptr->row_number & 0x01))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+
+ default: /* error: ignore it */
+ break;
+ }
+ }
+#endif
+
+ /* Set up row info for transformations */
+ row_info.color_type = png_ptr->color_type;
+ row_info.width = png_ptr->usr_width;
+ row_info.channels = png_ptr->usr_channels;
+ row_info.bit_depth = png_ptr->usr_bit_depth;
+ row_info.pixel_depth = (png_byte)(row_info.bit_depth * row_info.channels);
+ row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width);
+
+ png_debug1(3, "row_info->color_type = %d", row_info.color_type);
+ png_debug1(3, "row_info->width = %u", row_info.width);
+ png_debug1(3, "row_info->channels = %d", row_info.channels);
+ png_debug1(3, "row_info->bit_depth = %d", row_info.bit_depth);
+ png_debug1(3, "row_info->pixel_depth = %d", row_info.pixel_depth);
+ png_debug1(3, "row_info->rowbytes = %lu", (unsigned long)row_info.rowbytes);
+
+ /* Copy user's row into buffer, leaving room for filter byte. */
+ memcpy(png_ptr->row_buf + 1, row, row_info.rowbytes);
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Handle interlacing */
+ if (png_ptr->interlaced && png_ptr->pass < 6 &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_do_write_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass);
+ /* This should always get caught above, but still ... */
+ if (!(row_info.width))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ }
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+ /* Handle other transformations */
+ if (png_ptr->transformations)
+ png_do_write_transformations(png_ptr, &row_info);
+#endif
+
+ /* At this point the row_info pixel depth must match the 'transformed' depth,
+ * which is also the output depth.
+ */
+ if (row_info.pixel_depth != png_ptr->pixel_depth ||
+ row_info.pixel_depth != png_ptr->transformed_pixel_depth)
+ png_error(png_ptr, "internal write transform logic error");
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_write_intrapixel(&row_info, png_ptr->row_buf + 1);
+ }
+#endif
+
+/* Added at libpng-1.5.10 */
+#ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ /* Check for out-of-range palette index */
+ if (row_info.color_type == PNG_COLOR_TYPE_PALETTE &&
+ png_ptr->num_palette_max >= 0)
+ png_do_check_palette_indexes(png_ptr, &row_info);
+#endif
+
+ /* Find a filter if necessary, filter the row and write it out. */
+ png_write_find_filter(png_ptr, &row_info);
+
+ if (png_ptr->write_row_fn != NULL)
+ (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structrp png_ptr, int nrows)
+{
+ png_debug(1, "in png_set_flush");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* Flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structrp png_ptr)
+{
+ png_debug(1, "in png_write_flush");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* We have already written out all of the data */
+ if (png_ptr->row_number >= png_ptr->num_rows)
+ return;
+
+ png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH);
+ png_ptr->flush_rows = 0;
+ png_flush(png_ptr);
+}
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+static void png_reset_filter_heuristics(png_structrp png_ptr);/* forward decl */
+#endif
+
+/* Free any memory used in png_ptr struct without freeing the struct itself. */
+static void
+png_write_destroy(png_structrp png_ptr)
+{
+ png_debug(1, "in png_write_destroy");
+
+ /* Free any memory zlib uses */
+ if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
+ deflateEnd(&png_ptr->zstream);
+
+ /* Free our memory. png_free checks NULL for us. */
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
+ png_free(png_ptr, png_ptr->row_buf);
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_free(png_ptr, png_ptr->prev_row);
+ png_free(png_ptr, png_ptr->sub_row);
+ png_free(png_ptr, png_ptr->up_row);
+ png_free(png_ptr, png_ptr->avg_row);
+ png_free(png_ptr, png_ptr->paeth_row);
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* Use this to save a little code space, it doesn't free the filter_costs */
+ png_reset_filter_heuristics(png_ptr);
+ png_free(png_ptr, png_ptr->filter_costs);
+ png_free(png_ptr, png_ptr->inv_filter_costs);
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ png_free(png_ptr, png_ptr->chunk_list);
+#endif
+
+ /* The error handling and memory handling information is left intact at this
+ * point: the jmp_buf may still have to be freed. See png_destroy_png_struct
+ * for how this happens.
+ */
+}
+
+/* Free all memory used by the write.
+ * In libpng 1.6.0 this API changed quietly to no longer accept a NULL value for
+ * *png_ptr_ptr. Prior to 1.6.0 it would accept such a value and it would free
+ * the passed in info_structs but it would quietly fail to free any of the data
+ * inside them. In 1.6.0 it quietly does nothing (it has to be quiet because it
+ * has no png_ptr.)
+ */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+ png_debug(1, "in png_destroy_write_struct");
+
+ if (png_ptr_ptr != NULL)
+ {
+ png_structrp png_ptr = *png_ptr_ptr;
+
+ if (png_ptr != NULL) /* added in libpng 1.6.0 */
+ {
+ png_destroy_info_struct(png_ptr, info_ptr_ptr);
+
+ *png_ptr_ptr = NULL;
+ png_write_destroy(png_ptr);
+ png_destroy_png_struct(png_ptr);
+ }
+ }
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structrp png_ptr, int method, int filters)
+{
+ png_debug(1, "in png_set_filter");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ if ((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (method == PNG_INTRAPIXEL_DIFFERENCING))
+ method = PNG_FILTER_TYPE_BASE;
+
+#endif
+ if (method == PNG_FILTER_TYPE_BASE)
+ {
+ switch (filters & (PNG_ALL_FILTERS | 0x07))
+ {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ case 5:
+ case 6:
+ case 7: png_app_error(png_ptr, "Unknown row filter for method 0");
+ /* FALL THROUGH */
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ case PNG_FILTER_VALUE_NONE:
+ png_ptr->do_filter = PNG_FILTER_NONE; break;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ case PNG_FILTER_VALUE_SUB:
+ png_ptr->do_filter = PNG_FILTER_SUB; break;
+
+ case PNG_FILTER_VALUE_UP:
+ png_ptr->do_filter = PNG_FILTER_UP; break;
+
+ case PNG_FILTER_VALUE_AVG:
+ png_ptr->do_filter = PNG_FILTER_AVG; break;
+
+ case PNG_FILTER_VALUE_PAETH:
+ png_ptr->do_filter = PNG_FILTER_PAETH; break;
+
+ default:
+ png_ptr->do_filter = (png_byte)filters; break;
+#else
+ default:
+ png_app_error(png_ptr, "Unknown row filter for method 0");
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ }
+
+ /* If we have allocated the row_buf, this means we have already started
+ * with the image and we should have allocated all of the filter buffers
+ * that have been selected. If prev_row isn't already allocated, then
+ * it is too late to start using the filters that need it, since we
+ * will be missing the data in the previous row. If an application
+ * wants to start and stop using particular filters during compression,
+ * it should start out with all of the filters, and then add and
+ * remove them after the start of compression.
+ */
+ if (png_ptr->row_buf != NULL)
+ {
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Up filter after starting");
+ png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+ ~PNG_FILTER_UP);
+ }
+
+ else
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Average filter after starting");
+ png_ptr->do_filter = (png_byte)(png_ptr->do_filter &
+ ~PNG_FILTER_AVG);
+ }
+
+ else
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
+ png_ptr->paeth_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Paeth filter after starting");
+ png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+ }
+
+ else
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+
+ if (png_ptr->do_filter == PNG_NO_FILTERS)
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+ png_ptr->do_filter = PNG_FILTER_NONE;
+ }
+ }
+ else
+ png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline. While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* GRR 970116 */
+/* Convenience reset API. */
+static void
+png_reset_filter_heuristics(png_structrp png_ptr)
+{
+ /* Clear out any old values in the 'weights' - this must be done because if
+ * the app calls set_filter_heuristics multiple times with different
+ * 'num_weights' values we would otherwise potentially have wrong sized
+ * arrays.
+ */
+ png_ptr->num_prev_filters = 0;
+ png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+ if (png_ptr->prev_filters != NULL)
+ {
+ png_bytep old = png_ptr->prev_filters;
+ png_ptr->prev_filters = NULL;
+ png_free(png_ptr, old);
+ }
+ if (png_ptr->filter_weights != NULL)
+ {
+ png_uint_16p old = png_ptr->filter_weights;
+ png_ptr->filter_weights = NULL;
+ png_free(png_ptr, old);
+ }
+
+ if (png_ptr->inv_filter_weights != NULL)
+ {
+ png_uint_16p old = png_ptr->inv_filter_weights;
+ png_ptr->inv_filter_weights = NULL;
+ png_free(png_ptr, old);
+ }
+
+ /* Leave the filter_costs - this array is fixed size. */
+}
+
+static int
+png_init_filter_heuristics(png_structrp png_ptr, int heuristic_method,
+ int num_weights)
+{
+ if (png_ptr == NULL)
+ return 0;
+
+ /* Clear out the arrays */
+ png_reset_filter_heuristics(png_ptr);
+
+ /* Check arguments; the 'reset' function makes the correct settings for the
+ * unweighted case, but we must handle the weight case by initializing the
+ * arrays for the caller.
+ */
+ if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int i;
+
+ if (num_weights > 0)
+ {
+ png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_byte)) * num_weights));
+
+ /* To make sure that the weighting starts out fairly */
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->prev_filters[i] = 255;
+ }
+
+ png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+
+ png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * num_weights));
+
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+
+ /* Safe to set this now */
+ png_ptr->num_prev_filters = (png_byte)num_weights;
+ }
+
+ /* If, in the future, there are other filter methods, this would
+ * need to be based on png_ptr->filter.
+ */
+ if (png_ptr->filter_costs == NULL)
+ {
+ png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
+
+ png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)((sizeof (png_uint_16)) * PNG_FILTER_VALUE_LAST));
+ }
+
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+
+ /* All the arrays are inited, safe to set this: */
+ png_ptr->heuristic_method = PNG_FILTER_HEURISTIC_WEIGHTED;
+
+ /* Return the 'ok' code. */
+ return 1;
+ }
+ else if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT ||
+ heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+ {
+ return 1;
+ }
+ else
+ {
+ png_warning(png_ptr, "Unknown filter heuristic method");
+ return 0;
+ }
+}
+
+/* Provide floating and fixed point APIs */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_filter_heuristics(png_structrp png_ptr, int heuristic_method,
+ int num_weights, png_const_doublep filter_weights,
+ png_const_doublep filter_costs)
+{
+ png_debug(1, "in png_set_filter_heuristics");
+
+ /* The internal API allocates all the arrays and ensures that the elements of
+ * those arrays are set to the default value.
+ */
+ if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
+ return;
+
+ /* If using the weighted method copy in the weights. */
+ if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int i;
+ for (i = 0; i < num_weights; i++)
+ {
+ if (filter_weights[i] <= 0.0)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+
+ else
+ {
+ png_ptr->inv_filter_weights[i] =
+ (png_uint_16)(PNG_WEIGHT_FACTOR*filter_weights[i]+.5);
+
+ png_ptr->filter_weights[i] =
+ (png_uint_16)(PNG_WEIGHT_FACTOR/filter_weights[i]+.5);
+ }
+ }
+
+ /* Here is where we set the relative costs of the different filters. We
+ * should take the desired compression level into account when setting
+ * the costs, so that Paeth, for instance, has a high relative cost at low
+ * compression levels, while it has a lower relative cost at higher
+ * compression settings. The filter types are in order of increasing
+ * relative cost, so it would be possible to do this with an algorithm.
+ */
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++) if (filter_costs[i] >= 1.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ (png_uint_16)(PNG_COST_FACTOR / filter_costs[i] + .5);
+
+ png_ptr->filter_costs[i] =
+ (png_uint_16)(PNG_COST_FACTOR * filter_costs[i] + .5);
+ }
+ }
+}
+#endif /* FLOATING_POINT */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_filter_heuristics_fixed(png_structrp png_ptr, int heuristic_method,
+ int num_weights, png_const_fixed_point_p filter_weights,
+ png_const_fixed_point_p filter_costs)
+{
+ png_debug(1, "in png_set_filter_heuristics_fixed");
+
+ /* The internal API allocates all the arrays and ensures that the elements of
+ * those arrays are set to the default value.
+ */
+ if (!png_init_filter_heuristics(png_ptr, heuristic_method, num_weights))
+ return;
+
+ /* If using the weighted method copy in the weights. */
+ if (heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int i;
+ for (i = 0; i < num_weights; i++)
+ {
+ if (filter_weights[i] <= 0)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+
+ else
+ {
+ png_ptr->inv_filter_weights[i] = (png_uint_16)
+ ((PNG_WEIGHT_FACTOR*filter_weights[i]+PNG_FP_HALF)/PNG_FP_1);
+
+ png_ptr->filter_weights[i] = (png_uint_16)((PNG_WEIGHT_FACTOR*
+ PNG_FP_1+(filter_weights[i]/2))/filter_weights[i]);
+ }
+ }
+
+ /* Here is where we set the relative costs of the different filters. We
+ * should take the desired compression level into account when setting
+ * the costs, so that Paeth, for instance, has a high relative cost at low
+ * compression levels, while it has a lower relative cost at higher
+ * compression settings. The filter types are in order of increasing
+ * relative cost, so it would be possible to do this with an algorithm.
+ */
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ if (filter_costs[i] >= PNG_FP_1)
+ {
+ png_uint_32 tmp;
+
+ /* Use a 32 bit unsigned temporary here because otherwise the
+ * intermediate value will be a 32 bit *signed* integer (ANSI rules)
+ * and this will get the wrong answer on division.
+ */
+ tmp = PNG_COST_FACTOR*PNG_FP_1 + (filter_costs[i]/2);
+ tmp /= filter_costs[i];
+
+ png_ptr->inv_filter_costs[i] = (png_uint_16)tmp;
+
+ tmp = PNG_COST_FACTOR * filter_costs[i] + PNG_FP_HALF;
+ tmp /= PNG_FP_1;
+
+ png_ptr->filter_costs[i] = (png_uint_16)tmp;
+ }
+ }
+}
+#endif /* FIXED_POINT */
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+void PNGAPI
+png_set_compression_level(png_structrp png_ptr, int level)
+{
+ png_debug(1, "in png_set_compression_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structrp png_ptr, int mem_level)
+{
+ png_debug(1, "in png_set_compression_mem_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structrp png_ptr, int strategy)
+{
+ png_debug(1, "in png_set_compression_strategy");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* The flag setting here prevents the libpng dynamic selection of strategy.
+ */
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+ png_ptr->zlib_strategy = strategy;
+}
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+void PNGAPI
+png_set_compression_window_bits(png_structrp png_ptr, int window_bits)
+{
+ if (png_ptr == NULL)
+ return;
+
+ /* Prior to 1.6.0 this would warn but then set the window_bits value, this
+ * meant that negative window bits values could be selected which would cause
+ * libpng to write a non-standard PNG file with raw deflate or gzip
+ * compressed IDAT or ancillary chunks. Such files can be read and there is
+ * no warning on read, so this seems like a very bad idea.
+ */
+ if (window_bits > 15)
+ {
+ png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+ window_bits = 15;
+ }
+
+ else if (window_bits < 8)
+ {
+ png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+ window_bits = 8;
+ }
+
+ png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structrp png_ptr, int method)
+{
+ png_debug(1, "in png_set_compression_method");
+
+ if (png_ptr == NULL)
+ return;
+
+ /* This would produce an invalid PNG file if it worked, but it doesn't and
+ * deflate will fault it, so it is harmless to just warn here.
+ */
+ if (method != 8)
+ png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+
+ png_ptr->zlib_method = method;
+}
+
+/* The following were added to libpng-1.5.4 */
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+void PNGAPI
+png_set_text_compression_level(png_structrp png_ptr, int level)
+{
+ png_debug(1, "in png_set_text_compression_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_text_level = level;
+}
+
+void PNGAPI
+png_set_text_compression_mem_level(png_structrp png_ptr, int mem_level)
+{
+ png_debug(1, "in png_set_text_compression_mem_level");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_text_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_text_compression_strategy(png_structrp png_ptr, int strategy)
+{
+ png_debug(1, "in png_set_text_compression_strategy");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->zlib_text_strategy = strategy;
+}
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+void PNGAPI
+png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits)
+{
+ if (png_ptr == NULL)
+ return;
+
+ if (window_bits > 15)
+ {
+ png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+ window_bits = 15;
+ }
+
+ else if (window_bits < 8)
+ {
+ png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+ window_bits = 8;
+ }
+
+ png_ptr->zlib_text_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_text_compression_method(png_structrp png_ptr, int method)
+{
+ png_debug(1, "in png_set_text_compression_method");
+
+ if (png_ptr == NULL)
+ return;
+
+ if (method != 8)
+ png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+
+ png_ptr->zlib_text_method = method;
+}
+#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
+/* end of API added to libpng-1.5.4 */
+
+void PNGAPI
+png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn)
+{
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->write_row_fn = write_row_fn;
+}
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+void PNGAPI
+png_set_write_user_transform_fn(png_structrp png_ptr, png_user_transform_ptr
+ write_user_transform_fn)
+{
+ png_debug(1, "in png_set_write_user_transform_fn");
+
+ if (png_ptr == NULL)
+ return;
+
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+void PNGAPI
+png_write_png(png_structrp png_ptr, png_inforp info_ptr,
+ int transforms, voidp params)
+{
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Write the file header information. */
+ png_write_info(png_ptr, info_ptr);
+
+ /* ------ these transformations don't touch the info structure ------- */
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+ /* Invert monochrome pixels */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ /* Shift the pixels up to a legal bit depth and fill in
+ * as appropriate to correctly scale the image.
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && (info_ptr->valid & PNG_INFO_sBIT))
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ /* Pack pixels into bytes */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ /* Swap location of alpha bytes from ARGB to RGBA */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ /* Pack XRGB/RGBX/ARGB/RGBA into RGB (4 channels -> 3 channels) */
+ if (transforms & PNG_TRANSFORM_STRIP_FILLER_AFTER)
+ png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
+
+ else if (transforms & PNG_TRANSFORM_STRIP_FILLER_BEFORE)
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+ /* Flip BGR pixels to RGB */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+ /* Swap bytes of 16-bit files to most significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ /* Swap bits of 1, 2, 4 bit packed pixel formats */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ /* Invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+ /* ----------------------- end of transformations ------------------- */
+
+ /* Write the bits */
+ if (info_ptr->valid & PNG_INFO_IDAT)
+ png_write_image(png_ptr, info_ptr->row_pointers);
+
+ /* It is REQUIRED to call this to finish writing the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+
+ PNG_UNUSED(transforms) /* Quiet compiler warnings */
+ PNG_UNUSED(params)
+}
+#endif
+
+
+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED /* currently required for png_image_write_* */
+/* Initialize the write structure - general purpose utility. */
+static int
+png_image_write_init(png_imagep image)
+{
+ png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, image,
+ png_safe_error, png_safe_warning);
+
+ if (png_ptr != NULL)
+ {
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+
+ if (info_ptr != NULL)
+ {
+ png_controlp control = png_voidcast(png_controlp,
+ png_malloc_warn(png_ptr, (sizeof *control)));
+
+ if (control != NULL)
+ {
+ memset(control, 0, (sizeof *control));
+
+ control->png_ptr = png_ptr;
+ control->info_ptr = info_ptr;
+ control->for_write = 1;
+
+ image->opaque = control;
+ return 1;
+ }
+
+ /* Error clean up */
+ png_destroy_info_struct(png_ptr, &info_ptr);
+ }
+
+ png_destroy_write_struct(&png_ptr, NULL);
+ }
+
+ return png_image_error(image, "png_image_write_: out of memory");
+}
+
+/* Arguments to png_image_write_main: */
+typedef struct
+{
+ /* Arguments: */
+ png_imagep image;
+ png_const_voidp buffer;
+ png_int_32 row_stride;
+ png_const_voidp colormap;
+ int convert_to_8bit;
+ /* Local variables: */
+ png_const_voidp first_row;
+ ptrdiff_t row_bytes;
+ png_voidp local_row;
+} png_image_write_control;
+
+/* Write png_uint_16 input to a 16-bit PNG; the png_ptr has already been set to
+ * do any necessary byte swapping. The component order is defined by the
+ * png_image format value.
+ */
+static int
+png_write_image_16bit(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+
+ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
+ display->first_row);
+ png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row);
+ png_uint_16p row_end;
+ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
+ int aindex = 0;
+ png_uint_32 y = image->height;
+
+ if (image->format & PNG_FORMAT_FLAG_ALPHA)
+ {
+ if (image->format & PNG_FORMAT_FLAG_AFIRST)
+ {
+ aindex = -1;
+ ++input_row; /* To point to the first component */
+ ++output_row;
+ }
+
+ else
+ aindex = channels;
+ }
+
+ else
+ png_error(png_ptr, "png_write_image: internal call error");
+
+ /* Work out the output row end and count over this, note that the increment
+ * above to 'row' means that row_end can actually be beyond the end of the
+ * row; this is correct.
+ */
+ row_end = output_row + image->width * (channels+1);
+
+ while (y-- > 0)
+ {
+ png_const_uint_16p in_ptr = input_row;
+ png_uint_16p out_ptr = output_row;
+
+ while (out_ptr < row_end)
+ {
+ const png_uint_16 alpha = in_ptr[aindex];
+ png_uint_32 reciprocal = 0;
+ int c;
+
+ out_ptr[aindex] = alpha;
+
+ /* Calculate a reciprocal. The correct calculation is simply
+ * component/alpha*65535 << 15. (I.e. 15 bits of precision); this
+ * allows correct rounding by adding .5 before the shift. 'reciprocal'
+ * is only initialized when required.
+ */
+ if (alpha > 0 && alpha < 65535)
+ reciprocal = ((0xffff<<15)+(alpha>>1))/alpha;
+
+ c = channels;
+ do /* always at least one channel */
+ {
+ png_uint_16 component = *in_ptr++;
+
+ /* The following gives 65535 for an alpha of 0, which is fine,
+ * otherwise if 0/0 is represented as some other value there is more
+ * likely to be a discontinuity which will probably damage
+ * compression when moving from a fully transparent area to a
+ * nearly transparent one. (The assumption here is that opaque
+ * areas tend not to be 0 intensity.)
+ */
+ if (component >= alpha)
+ component = 65535;
+
+ /* component<alpha, so component/alpha is less than one and
+ * component*reciprocal is less than 2^31.
+ */
+ else if (component > 0 && alpha < 65535)
+ {
+ png_uint_32 calc = component * reciprocal;
+ calc += 16384; /* round to nearest */
+ component = (png_uint_16)(calc >> 15);
+ }
+
+ *out_ptr++ = component;
+ }
+ while (--c > 0);
+
+ /* Skip to next component (skip the intervening alpha channel) */
+ ++in_ptr;
+ ++out_ptr;
+ }
+
+ png_write_row(png_ptr, png_voidcast(png_const_bytep, display->local_row));
+ input_row += display->row_bytes/(sizeof (png_uint_16));
+ }
+
+ return 1;
+}
+
+/* Given 16-bit input (1 to 4 channels) write 8-bit output. If an alpha channel
+ * is present it must be removed from the components, the components are then
+ * written in sRGB encoding. No components are added or removed.
+ *
+ * Calculate an alpha reciprocal to reverse pre-multiplication. As above the
+ * calculation can be done to 15 bits of accuracy; however, the output needs to
+ * be scaled in the range 0..255*65535, so include that scaling here.
+ */
+#define UNP_RECIPROCAL(alpha) ((((0xffff*0xff)<<7)+(alpha>>1))/alpha)
+
+static png_byte
+png_unpremultiply(png_uint_32 component, png_uint_32 alpha,
+ png_uint_32 reciprocal/*from the above macro*/)
+{
+ /* The following gives 1.0 for an alpha of 0, which is fine, otherwise if 0/0
+ * is represented as some other value there is more likely to be a
+ * discontinuity which will probably damage compression when moving from a
+ * fully transparent area to a nearly transparent one. (The assumption here
+ * is that opaque areas tend not to be 0 intensity.)
+ *
+ * There is a rounding problem here; if alpha is less than 128 it will end up
+ * as 0 when scaled to 8 bits. To avoid introducing spurious colors into the
+ * output change for this too.
+ */
+ if (component >= alpha || alpha < 128)
+ return 255;
+
+ /* component<alpha, so component/alpha is less than one and
+ * component*reciprocal is less than 2^31.
+ */
+ else if (component > 0)
+ {
+ /* The test is that alpha/257 (rounded) is less than 255, the first value
+ * that becomes 255 is 65407.
+ * NOTE: this must agree with the PNG_DIV257 macro (which must, therefore,
+ * be exact!) [Could also test reciprocal != 0]
+ */
+ if (alpha < 65407)
+ {
+ component *= reciprocal;
+ component += 64; /* round to nearest */
+ component >>= 7;
+ }
+
+ else
+ component *= 255;
+
+ /* Convert the component to sRGB. */
+ return (png_byte)PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ else
+ return 0;
+}
+
+static int
+png_write_image_8bit(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+
+ png_const_uint_16p input_row = png_voidcast(png_const_uint_16p,
+ display->first_row);
+ png_bytep output_row = png_voidcast(png_bytep, display->local_row);
+ png_uint_32 y = image->height;
+ const int channels = (image->format & PNG_FORMAT_FLAG_COLOR) ? 3 : 1;
+
+ if (image->format & PNG_FORMAT_FLAG_ALPHA)
+ {
+ png_bytep row_end;
+ int aindex;
+
+ if (image->format & PNG_FORMAT_FLAG_AFIRST)
+ {
+ aindex = -1;
+ ++input_row; /* To point to the first component */
+ ++output_row;
+ }
+
+ else
+ aindex = channels;
+
+ /* Use row_end in place of a loop counter: */
+ row_end = output_row + image->width * (channels+1);
+
+ while (y-- > 0)
+ {
+ png_const_uint_16p in_ptr = input_row;
+ png_bytep out_ptr = output_row;
+
+ while (out_ptr < row_end)
+ {
+ png_uint_16 alpha = in_ptr[aindex];
+ png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
+ png_uint_32 reciprocal = 0;
+ int c;
+
+ /* Scale and write the alpha channel. */
+ out_ptr[aindex] = alphabyte;
+
+ if (alphabyte > 0 && alphabyte < 255)
+ reciprocal = UNP_RECIPROCAL(alpha);
+
+ c = channels;
+ do /* always at least one channel */
+ *out_ptr++ = png_unpremultiply(*in_ptr++, alpha, reciprocal);
+ while (--c > 0);
+
+ /* Skip to next component (skip the intervening alpha channel) */
+ ++in_ptr;
+ ++out_ptr;
+ } /* while out_ptr < row_end */
+
+ png_write_row(png_ptr, png_voidcast(png_const_bytep,
+ display->local_row));
+ input_row += display->row_bytes/(sizeof (png_uint_16));
+ } /* while y */
+ }
+
+ else
+ {
+ /* No alpha channel, so the row_end really is the end of the row and it
+ * is sufficient to loop over the components one by one.
+ */
+ png_bytep row_end = output_row + image->width * channels;
+
+ while (y-- > 0)
+ {
+ png_const_uint_16p in_ptr = input_row;
+ png_bytep out_ptr = output_row;
+
+ while (out_ptr < row_end)
+ {
+ png_uint_32 component = *in_ptr++;
+
+ component *= 255;
+ *out_ptr++ = (png_byte)PNG_sRGB_FROM_LINEAR(component);
+ }
+
+ png_write_row(png_ptr, output_row);
+ input_row += display->row_bytes/(sizeof (png_uint_16));
+ }
+ }
+
+ return 1;
+}
+
+static void
+png_image_set_PLTE(png_image_write_control *display)
+{
+ const png_imagep image = display->image;
+ const void *cmap = display->colormap;
+ const int entries = image->colormap_entries > 256 ? 256 :
+ (int)image->colormap_entries;
+
+ /* NOTE: the caller must check for cmap != NULL and entries != 0 */
+ const png_uint_32 format = image->format;
+ const int channels = PNG_IMAGE_SAMPLE_CHANNELS(format);
+
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 &&
+ (format & PNG_FORMAT_FLAG_ALPHA) != 0;
+# else
+# define afirst 0
+# endif
+
+# ifdef PNG_FORMAT_BGR_SUPPORTED
+ const int bgr = (format & PNG_FORMAT_FLAG_BGR) ? 2 : 0;
+# else
+# define bgr 0
+# endif
+
+ int i, num_trans;
+ png_color palette[256];
+ png_byte tRNS[256];
+
+ memset(tRNS, 255, (sizeof tRNS));
+ memset(palette, 0, (sizeof palette));
+
+ for (i=num_trans=0; i<entries; ++i)
+ {
+ /* This gets automatically converted to sRGB with reversal of the
+ * pre-multiplication if the color-map has an alpha channel.
+ */
+ if (format & PNG_FORMAT_FLAG_LINEAR)
+ {
+ png_const_uint_16p entry = png_voidcast(png_const_uint_16p, cmap);
+
+ entry += i * channels;
+
+ if (channels & 1) /* no alpha */
+ {
+ if (channels >= 3) /* RGB */
+ {
+ palette[i].blue = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+ entry[(2 ^ bgr)]);
+ palette[i].green = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+ entry[1]);
+ palette[i].red = (png_byte)PNG_sRGB_FROM_LINEAR(255 *
+ entry[bgr]);
+ }
+
+ else /* Gray */
+ palette[i].blue = palette[i].red = palette[i].green =
+ (png_byte)PNG_sRGB_FROM_LINEAR(255 * *entry);
+ }
+
+ else /* alpha */
+ {
+ png_uint_16 alpha = entry[afirst ? 0 : channels-1];
+ png_byte alphabyte = (png_byte)PNG_DIV257(alpha);
+ png_uint_32 reciprocal = 0;
+
+ /* Calculate a reciprocal, as in the png_write_image_8bit code above
+ * this is designed to produce a value scaled to 255*65535 when
+ * divided by 128 (i.e. asr 7).
+ */
+ if (alphabyte > 0 && alphabyte < 255)
+ reciprocal = (((0xffff*0xff)<<7)+(alpha>>1))/alpha;
+
+ tRNS[i] = alphabyte;
+ if (alphabyte < 255)
+ num_trans = i+1;
+
+ if (channels >= 3) /* RGB */
+ {
+ palette[i].blue = png_unpremultiply(entry[afirst + (2 ^ bgr)],
+ alpha, reciprocal);
+ palette[i].green = png_unpremultiply(entry[afirst + 1], alpha,
+ reciprocal);
+ palette[i].red = png_unpremultiply(entry[afirst + bgr], alpha,
+ reciprocal);
+ }
+
+ else /* gray */
+ palette[i].blue = palette[i].red = palette[i].green =
+ png_unpremultiply(entry[afirst], alpha, reciprocal);
+ }
+ }
+
+ else /* Color-map has sRGB values */
+ {
+ png_const_bytep entry = png_voidcast(png_const_bytep, cmap);
+
+ entry += i * channels;
+
+ switch (channels)
+ {
+ case 4:
+ tRNS[i] = entry[afirst ? 0 : 3];
+ if (tRNS[i] < 255)
+ num_trans = i+1;
+ /* FALL THROUGH */
+ case 3:
+ palette[i].blue = entry[afirst + (2 ^ bgr)];
+ palette[i].green = entry[afirst + 1];
+ palette[i].red = entry[afirst + bgr];
+ break;
+
+ case 2:
+ tRNS[i] = entry[1 ^ afirst];
+ if (tRNS[i] < 255)
+ num_trans = i+1;
+ /* FALL THROUGH */
+ case 1:
+ palette[i].blue = palette[i].red = palette[i].green =
+ entry[afirst];
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+# ifdef afirst
+# undef afirst
+# endif
+# ifdef bgr
+# undef bgr
+# endif
+
+ png_set_PLTE(image->opaque->png_ptr, image->opaque->info_ptr, palette,
+ entries);
+
+ if (num_trans > 0)
+ png_set_tRNS(image->opaque->png_ptr, image->opaque->info_ptr, tRNS,
+ num_trans, NULL);
+
+ image->colormap_entries = entries;
+}
+
+static int
+png_image_write_main(png_voidp argument)
+{
+ png_image_write_control *display = png_voidcast(png_image_write_control*,
+ argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_inforp info_ptr = image->opaque->info_ptr;
+ png_uint_32 format = image->format;
+
+ int colormap = (format & PNG_FORMAT_FLAG_COLORMAP) != 0;
+ int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR) != 0; /* input */
+ int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0;
+ int write_16bit = linear && !colormap && !display->convert_to_8bit;
+
+# ifdef PNG_BENIGN_ERRORS_SUPPORTED
+ /* Make sure we error out on any bad situation */
+ png_set_benign_errors(png_ptr, 0/*error*/);
+# endif
+
+ /* Default the 'row_stride' parameter if required. */
+ if (display->row_stride == 0)
+ display->row_stride = PNG_IMAGE_ROW_STRIDE(*image);
+
+ /* Set the required transforms then write the rows in the correct order. */
+ if (format & PNG_FORMAT_FLAG_COLORMAP)
+ {
+ if (display->colormap != NULL && image->colormap_entries > 0)
+ {
+ png_uint_32 entries = image->colormap_entries;
+
+ png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
+ entries > 16 ? 8 : (entries > 4 ? 4 : (entries > 2 ? 2 : 1)),
+ PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ png_image_set_PLTE(display);
+ }
+
+ else
+ png_error(image->opaque->png_ptr,
+ "no color-map for color-mapped image");
+ }
+
+ else
+ png_set_IHDR(png_ptr, info_ptr, image->width, image->height,
+ write_16bit ? 16 : 8,
+ ((format & PNG_FORMAT_FLAG_COLOR) ? PNG_COLOR_MASK_COLOR : 0) +
+ ((format & PNG_FORMAT_FLAG_ALPHA) ? PNG_COLOR_MASK_ALPHA : 0),
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ /* Counter-intuitively the data transformations must be called *after*
+ * png_write_info, not before as in the read code, but the 'set' functions
+ * must still be called before. Just set the color space information, never
+ * write an interlaced image.
+ */
+
+ if (write_16bit)
+ {
+ /* The gamma here is 1.0 (linear) and the cHRM chunk matches sRGB. */
+ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_LINEAR);
+
+ if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ /* color x y */
+ /* white */ 31270, 32900,
+ /* red */ 64000, 33000,
+ /* green */ 30000, 60000,
+ /* blue */ 15000, 6000
+ );
+ }
+
+ else if (!(image->flags & PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB))
+ png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_PERCEPTUAL);
+
+ /* Else writing an 8-bit file and the *colors* aren't sRGB, but the 8-bit
+ * space must still be gamma encoded.
+ */
+ else
+ png_set_gAMA_fixed(png_ptr, info_ptr, PNG_GAMMA_sRGB_INVERSE);
+
+ /* Write the file header. */
+ png_write_info(png_ptr, info_ptr);
+
+ /* Now set up the data transformations (*after* the header is written),
+ * remove the handled transformations from the 'format' flags for checking.
+ *
+ * First check for a little endian system if writing 16 bit files.
+ */
+ if (write_16bit)
+ {
+ PNG_CONST png_uint_16 le = 0x0001;
+
+ if (*(png_const_bytep)&le)
+ png_set_swap(png_ptr);
+ }
+
+# ifdef PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+ if (format & PNG_FORMAT_FLAG_BGR)
+ {
+ if (!colormap && (format & PNG_FORMAT_FLAG_COLOR) != 0)
+ png_set_bgr(png_ptr);
+ format &= ~PNG_FORMAT_FLAG_BGR;
+ }
+# endif
+
+# ifdef PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+ if (format & PNG_FORMAT_FLAG_AFIRST)
+ {
+ if (!colormap && (format & PNG_FORMAT_FLAG_ALPHA) != 0)
+ png_set_swap_alpha(png_ptr);
+ format &= ~PNG_FORMAT_FLAG_AFIRST;
+ }
+# endif
+
+ /* If there are 16 or fewer color-map entries we wrote a lower bit depth
+ * above, but the application data is still byte packed.
+ */
+ if (colormap && image->colormap_entries <= 16)
+ png_set_packing(png_ptr);
+
+ /* That should have handled all (both) the transforms. */
+ if ((format & ~(png_uint_32)(PNG_FORMAT_FLAG_COLOR | PNG_FORMAT_FLAG_LINEAR |
+ PNG_FORMAT_FLAG_ALPHA | PNG_FORMAT_FLAG_COLORMAP)) != 0)
+ png_error(png_ptr, "png_write_image: unsupported transformation");
+
+ {
+ png_const_bytep row = png_voidcast(png_const_bytep, display->buffer);
+ ptrdiff_t row_bytes = display->row_stride;
+
+ if (linear)
+ row_bytes *= (sizeof (png_uint_16));
+
+ if (row_bytes < 0)
+ row += (image->height-1) * (-row_bytes);
+
+ display->first_row = row;
+ display->row_bytes = row_bytes;
+ }
+
+ /* Apply 'fast' options if the flag is set. */
+ if ((image->flags & PNG_IMAGE_FLAG_FAST) != 0)
+ {
+ png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, PNG_NO_FILTERS);
+ /* NOTE: determined by experiment using pngstest, this reflects some
+ * balance between the time to write the image once and the time to read
+ * it about 50 times. The speed-up in pngstest was about 10-20% of the
+ * total (user) time on a heavily loaded system.
+ */
+ png_set_compression_level(png_ptr, 3);
+ }
+
+ /* Check for the cases that currently require a pre-transform on the row
+ * before it is written. This only applies when the input is 16-bit and
+ * either there is an alpha channel or it is converted to 8-bit.
+ */
+ if ((linear && alpha) || (!colormap && display->convert_to_8bit))
+ {
+ png_bytep row = png_voidcast(png_bytep, png_malloc(png_ptr,
+ png_get_rowbytes(png_ptr, info_ptr)));
+ int result;
+
+ display->local_row = row;
+ if (write_16bit)
+ result = png_safe_execute(image, png_write_image_16bit, display);
+ else
+ result = png_safe_execute(image, png_write_image_8bit, display);
+ display->local_row = NULL;
+
+ png_free(png_ptr, row);
+
+ /* Skip the 'write_end' on error: */
+ if (!result)
+ return 0;
+ }
+
+ /* Otherwise this is the case where the input is in a format currently
+ * supported by the rest of the libpng write code; call it directly.
+ */
+ else
+ {
+ png_const_bytep row = png_voidcast(png_const_bytep, display->first_row);
+ ptrdiff_t row_bytes = display->row_bytes;
+ png_uint_32 y = image->height;
+
+ while (y-- > 0)
+ {
+ png_write_row(png_ptr, row);
+ row += row_bytes;
+ }
+ }
+
+ png_write_end(png_ptr, info_ptr);
+ return 1;
+}
+
+int PNGAPI
+png_image_write_to_stdio(png_imagep image, FILE *file, int convert_to_8bit,
+ const void *buffer, png_int_32 row_stride, const void *colormap)
+{
+ /* Write the image to the given (FILE*). */
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file != NULL)
+ {
+ if (png_image_write_init(image))
+ {
+ png_image_write_control display;
+ int result;
+
+ /* This is slightly evil, but png_init_io doesn't do anything other
+ * than this and we haven't changed the standard IO functions so
+ * this saves a 'safe' function.
+ */
+ image->opaque->png_ptr->io_ptr = file;
+
+ memset(&display, 0, (sizeof display));
+ display.image = image;
+ display.buffer = buffer;
+ display.row_stride = row_stride;
+ display.colormap = colormap;
+ display.convert_to_8bit = convert_to_8bit;
+
+ result = png_safe_execute(image, png_image_write_main, &display);
+ png_image_free(image);
+ return result;
+ }
+
+ else
+ return 0;
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_write_to_stdio: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_write_to_stdio: incorrect PNG_IMAGE_VERSION");
+
+ else
+ return 0;
+}
+
+int PNGAPI
+png_image_write_to_file(png_imagep image, const char *file_name,
+ int convert_to_8bit, const void *buffer, png_int_32 row_stride,
+ const void *colormap)
+{
+ /* Write the image to the named file. */
+ if (image != NULL && image->version == PNG_IMAGE_VERSION)
+ {
+ if (file_name != NULL)
+ {
+ FILE *fp = fopen(file_name, "wb");
+
+ if (fp != NULL)
+ {
+ if (png_image_write_to_stdio(image, fp, convert_to_8bit, buffer,
+ row_stride, colormap))
+ {
+ int error; /* from fflush/fclose */
+
+ /* Make sure the file is flushed correctly. */
+ if (fflush(fp) == 0 && ferror(fp) == 0)
+ {
+ if (fclose(fp) == 0)
+ return 1;
+
+ error = errno; /* from fclose */
+ }
+
+ else
+ {
+ error = errno; /* from fflush or ferror */
+ (void)fclose(fp);
+ }
+
+ (void)remove(file_name);
+ /* The image has already been cleaned up; this is just used to
+ * set the error (because the original write succeeded).
+ */
+ return png_image_error(image, strerror(error));
+ }
+
+ else
+ {
+ /* Clean up: just the opened file. */
+ (void)fclose(fp);
+ (void)remove(file_name);
+ return 0;
+ }
+ }
+
+ else
+ return png_image_error(image, strerror(errno));
+ }
+
+ else
+ return png_image_error(image,
+ "png_image_write_to_file: invalid argument");
+ }
+
+ else if (image != NULL)
+ return png_image_error(image,
+ "png_image_write_to_file: incorrect PNG_IMAGE_VERSION");
+
+ else
+ return 0;
+}
+#endif /* PNG_STDIO_SUPPORTED */
+#endif /* SIMPLIFIED_WRITE */
+#endif /* PNG_WRITE_SUPPORTED */
+#endif//_FPDFAPI_MINI_
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwtran.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwtran.c
new file mode 100644
index 0000000000..8f2811099a
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwtran.c
@@ -0,0 +1,638 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * Last changed in libpng 1.6.0 [February 14, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+/* Transform the data according to the user's wishes. The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structrp png_ptr, png_row_infop row_info)
+{
+ png_debug(1, "in png_do_write_transformations");
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ if (png_ptr->write_user_transform_fn != NULL)
+ (*(png_ptr->write_user_transform_fn)) /* User write transform
+ function */
+ (png_ptr, /* png_ptr */
+ row_info, /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_size_t rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#endif
+
+#ifdef PNG_WRITE_FILLER_SUPPORTED
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_strip_channel(row_info, png_ptr->row_buf + 1,
+ !(png_ptr->flags & PNG_FLAG_FILLER_AFTER));
+#endif
+
+#ifdef PNG_WRITE_PACKSWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_pack(row_info, png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->bit_depth);
+#endif
+
+#ifdef PNG_WRITE_SWAP_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_shift(row_info, png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_write_swap_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_write_invert_alpha(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_BGR_SUPPORTED
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(row_info, png_ptr->row_buf + 1);
+#endif
+
+#ifdef PNG_WRITE_INVERT_SUPPORTED
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(row_info, png_ptr->row_buf + 1);
+#endif
+}
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
+ * row_info bit depth should be 8 (one pixel per byte). The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+void /* PRIVATE */
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+ png_debug(1, "in png_do_pack");
+
+ if (row_info->bit_depth == 8 &&
+ row_info->channels == 1)
+ {
+ switch ((int)bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp, dp;
+ int mask, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ mask = 0x80;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp != 0)
+ v |= mask;
+
+ sp++;
+
+ if (mask > 1)
+ mask >>= 1;
+
+ else
+ {
+ mask = 0x80;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ }
+
+ if (mask != 0x80)
+ *dp = (png_byte)v;
+
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 6;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x03);
+ v |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+
+ else
+ shift -= 2;
+
+ sp++;
+ }
+
+ if (shift != 6)
+ *dp = (png_byte)v;
+
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 4;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x0f);
+ v |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+
+ else
+ shift -= 4;
+
+ sp++;
+ }
+
+ if (shift != 4)
+ *dp = (png_byte)v;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ row_info->bit_depth = (png_byte)bit_depth;
+ row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+/* Shift pixel values to take advantage of whole range. Pass the
+ * true number of bits in bit_depth. The row should be packed
+ * according to row_info->bit_depth. Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+void /* PRIVATE */
+png_do_shift(png_row_infop row_info, png_bytep row,
+ png_const_color_8p bit_depth)
+{
+ png_debug(1, "in png_do_shift");
+
+ if (row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift_start[4], shift_dec[4];
+ int channels = 0;
+
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->red;
+ shift_dec[channels] = bit_depth->red;
+ channels++;
+
+ shift_start[channels] = row_info->bit_depth - bit_depth->green;
+ shift_dec[channels] = bit_depth->green;
+ channels++;
+
+ shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+ shift_dec[channels] = bit_depth->blue;
+ channels++;
+ }
+
+ else
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+ shift_dec[channels] = bit_depth->gray;
+ channels++;
+ }
+
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+ shift_dec[channels] = bit_depth->alpha;
+ channels++;
+ }
+
+ /* With low row depths, could only be grayscale, so one channel */
+ if (row_info->bit_depth < 8)
+ {
+ png_bytep bp = row;
+ png_size_t i;
+ unsigned int mask;
+ png_size_t row_bytes = row_info->rowbytes;
+
+ if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+ mask = 0x55;
+
+ else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+ mask = 0x11;
+
+ else
+ mask = 0xff;
+
+ for (i = 0; i < row_bytes; i++, bp++)
+ {
+ int j;
+ unsigned int v, out;
+
+ v = *bp;
+ out = 0;
+
+ for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+ {
+ if (j > 0)
+ out |= v << j;
+
+ else
+ out |= (v >> (-j)) & mask;
+ }
+
+ *bp = (png_byte)(out & 0xff);
+ }
+ }
+
+ else if (row_info->bit_depth == 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (i = 0; i < istop; i++, bp++)
+ {
+
+ const unsigned int c = i%channels;
+ int j;
+ unsigned int v, out;
+
+ v = *bp;
+ out = 0;
+
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ out |= v << j;
+
+ else
+ out |= v >> (-j);
+ }
+
+ *bp = (png_byte)(out & 0xff);
+ }
+ }
+
+ else
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ const unsigned int c = i%channels;
+ int j;
+ unsigned int value, v;
+
+ v = png_get_uint_16(bp);
+ value = 0;
+
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ value |= v << j;
+
+ else
+ value |= v >> (-j);
+ }
+ *bp++ = (png_byte)((value >> 8) & 0xff);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_swap_alpha");
+
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from ARGB to RGBA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This converts from AARRGGBB to RRGGBBAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from AG to GA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This converts from AAGG to GGAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
+ }
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+void /* PRIVATE */
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_invert_alpha");
+
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in RGBA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=3; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This inverts the alpha channel in RRGGBBAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=6; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
+ }
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This inverts the alpha channel in GA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else
+ {
+ /* This inverts the alpha channel in GGAA */
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ /* Does nothing
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ */
+ sp+=2; dp = sp;
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
+ }
+ }
+}
+#endif
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+/* Undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_intrapixel");
+
+ if ((row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((*rp - *(rp + 1)) & 0xff);
+ *(rp + 2) = (png_byte)((*(rp + 2) - *(rp + 1)) & 0xff);
+ }
+ }
+
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0 = (*(rp ) << 8) | *(rp + 1);
+ png_uint_32 s1 = (*(rp + 2) << 8) | *(rp + 3);
+ png_uint_32 s2 = (*(rp + 4) << 8) | *(rp + 5);
+ png_uint_32 red = (png_uint_32)((s0 - s1) & 0xffffL);
+ png_uint_32 blue = (png_uint_32)((s2 - s1) & 0xffffL);
+ *(rp ) = (png_byte)((red >> 8) & 0xff);
+ *(rp + 1) = (png_byte)(red & 0xff);
+ *(rp + 4) = (png_byte)((blue >> 8) & 0xff);
+ *(rp + 5) = (png_byte)(blue & 0xff);
+ }
+ }
+#endif /* PNG_WRITE_16BIT_SUPPORTED */
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_SUPPORTED */
+#endif//_FPDFAPI_MINI_
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwutil.c b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwutil.c
new file mode 100644
index 0000000000..40955b9381
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/fx_pngwutil.c
@@ -0,0 +1,3024 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * Last changed in libpng 1.6.2 [April 25, 2013]
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "pngpriv.h"
+
+#ifdef PNG_WRITE_SUPPORTED
+
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+/* Place a 32-bit number into a buffer in PNG byte order. We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void PNGAPI
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void PNGAPI
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+ buf[0] = (png_byte)((i >> 8) & 0xff);
+ buf[1] = (png_byte)(i & 0xff);
+}
+#endif
+
+/* Simple function to write the signature. If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void PNGAPI
+png_write_sig(png_structrp png_ptr)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that the signature is being written */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_SIGNATURE;
+#endif
+
+ /* Write the rest of the 8 byte signature */
+ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+ (png_size_t)(8 - png_ptr->sig_bytes));
+
+ if (png_ptr->sig_bytes < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+/* Write the start of a PNG chunk. The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+static void
+png_write_chunk_header(png_structrp png_ptr, png_uint_32 chunk_name,
+ png_uint_32 length)
+{
+ png_byte buf[8];
+
+#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
+ PNG_CSTRING_FROM_CHUNK(buf, chunk_name);
+ png_debug2(0, "Writing %s chunk, length = %lu", buf, (unsigned long)length);
+#endif
+
+ if (png_ptr == NULL)
+ return;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that the chunk header is being written.
+ * PNG_IO_CHUNK_HDR requires a single I/O call.
+ */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_HDR;
+#endif
+
+ /* Write the length and the chunk name */
+ png_save_uint_32(buf, length);
+ png_save_uint_32(buf + 4, chunk_name);
+ png_write_data(png_ptr, buf, 8);
+
+ /* Put the chunk name into png_ptr->chunk_name */
+ png_ptr->chunk_name = chunk_name;
+
+ /* Reset the crc and run it over the chunk name */
+ png_reset_crc(png_ptr);
+
+ png_calculate_crc(png_ptr, buf + 4, 4);
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that chunk data will (possibly) be written.
+ * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
+ */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_DATA;
+#endif
+}
+
+void PNGAPI
+png_write_chunk_start(png_structrp png_ptr, png_const_bytep chunk_string,
+ png_uint_32 length)
+{
+ png_write_chunk_header(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), length);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_header().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_header().
+ */
+void PNGAPI
+png_write_chunk_data(png_structrp png_ptr, png_const_bytep data,
+ png_size_t length)
+{
+ /* Write the data, and run the CRC over it */
+ if (png_ptr == NULL)
+ return;
+
+ if (data != NULL && length > 0)
+ {
+ png_write_data(png_ptr, data, length);
+
+ /* Update the CRC after writing the data,
+ * in case that the user I/O routine alters it.
+ */
+ png_calculate_crc(png_ptr, data, length);
+ }
+}
+
+/* Finish a chunk started with png_write_chunk_header(). */
+void PNGAPI
+png_write_chunk_end(png_structrp png_ptr)
+{
+ png_byte buf[4];
+
+ if (png_ptr == NULL) return;
+
+#ifdef PNG_IO_STATE_SUPPORTED
+ /* Inform the I/O callback that the chunk CRC is being written.
+ * PNG_IO_CHUNK_CRC requires a single I/O function call.
+ */
+ png_ptr->io_state = PNG_IO_WRITING | PNG_IO_CHUNK_CRC;
+#endif
+
+ /* Write the crc in a single operation */
+ png_save_uint_32(buf, png_ptr->crc);
+
+ png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+/* Write a PNG chunk all at once. The type is an array of ASCII characters
+ * representing the chunk name. The array must be at least 4 bytes in
+ * length, and does not need to be null terminated. To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined. The length is the length of the data.
+ * All the data must be present. If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+static void
+png_write_complete_chunk(png_structrp png_ptr, png_uint_32 chunk_name,
+ png_const_bytep data, png_size_t length)
+{
+ if (png_ptr == NULL)
+ return;
+
+ /* On 64 bit architectures 'length' may not fit in a png_uint_32. */
+ if (length > PNG_UINT_31_MAX)
+ png_error(png_ptr, "length exceeds PNG maxima");
+
+ png_write_chunk_header(png_ptr, chunk_name, (png_uint_32)length);
+ png_write_chunk_data(png_ptr, data, length);
+ png_write_chunk_end(png_ptr);
+}
+
+/* This is the API that calls the internal function above. */
+void PNGAPI
+png_write_chunk(png_structrp png_ptr, png_const_bytep chunk_string,
+ png_const_bytep data, png_size_t length)
+{
+ png_write_complete_chunk(png_ptr, PNG_CHUNK_FROM_STRING(chunk_string), data,
+ length);
+}
+
+/* This is used below to find the size of an image to pass to png_deflate_claim,
+ * so it only needs to be accurate if the size is less than 16384 bytes (the
+ * point at which a lower LZ window size can be used.)
+ */
+static png_alloc_size_t
+png_image_size(png_structrp png_ptr)
+{
+ /* Only return sizes up to the maximum of a png_uint_32, do this by limiting
+ * the width and height used to 15 bits.
+ */
+ png_uint_32 h = png_ptr->height;
+
+ if (png_ptr->rowbytes < 32768 && h < 32768)
+ {
+ if (png_ptr->interlaced)
+ {
+ /* Interlacing makes the image larger because of the replication of
+ * both the filter byte and the padding to a byte boundary.
+ */
+ png_uint_32 w = png_ptr->width;
+ unsigned int pd = png_ptr->pixel_depth;
+ png_alloc_size_t cb_base;
+ int pass;
+
+ for (cb_base=0, pass=0; pass<=6; ++pass)
+ {
+ png_uint_32 pw = PNG_PASS_COLS(w, pass);
+
+ if (pw > 0)
+ cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
+ }
+
+ return cb_base;
+ }
+
+ else
+ return (png_ptr->rowbytes+1) * h;
+ }
+
+ else
+ return 0xffffffffU;
+}
+
+#ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ /* This is the code to hack the first two bytes of the deflate stream (the
+ * deflate header) to correct the windowBits value to match the actual data
+ * size. Note that the second argument is the *uncompressed* size but the
+ * first argument is the *compressed* data (and it must be deflate
+ * compressed.)
+ */
+static void
+optimize_cmf(png_bytep data, png_alloc_size_t data_size)
+{
+ /* Optimize the CMF field in the zlib stream. The resultant zlib stream is
+ * still compliant to the stream specification.
+ */
+ if (data_size <= 16384) /* else windowBits must be 15 */
+ {
+ unsigned int z_cmf = data[0]; /* zlib compression method and flags */
+
+ if ((z_cmf & 0x0f) == 8 && (z_cmf & 0xf0) <= 0x70)
+ {
+ unsigned int z_cinfo;
+ unsigned int half_z_window_size;
+
+ z_cinfo = z_cmf >> 4;
+ half_z_window_size = 1U << (z_cinfo + 7);
+
+ if (data_size <= half_z_window_size) /* else no change */
+ {
+ unsigned int tmp;
+
+ do
+ {
+ half_z_window_size >>= 1;
+ --z_cinfo;
+ }
+ while (z_cinfo > 0 && data_size <= half_z_window_size);
+
+ z_cmf = (z_cmf & 0x0f) | (z_cinfo << 4);
+
+ data[0] = (png_byte)z_cmf;
+ tmp = data[1] & 0xe0;
+ tmp += 0x1f - ((z_cmf << 8) + tmp) % 0x1f;
+ data[1] = (png_byte)tmp;
+ }
+ }
+ }
+}
+#else
+# define optimize_cmf(dp,dl) ((void)0)
+#endif /* PNG_WRITE_OPTIMIZE_CMF_SUPPORTED */
+
+/* Initialize the compressor for the appropriate type of compression. */
+static int
+png_deflate_claim(png_structrp png_ptr, png_uint_32 owner,
+ png_alloc_size_t data_size)
+{
+ if (png_ptr->zowner != 0)
+ {
+ char msg[64];
+
+ PNG_STRING_FROM_CHUNK(msg, owner);
+ msg[4] = ':';
+ msg[5] = ' ';
+ PNG_STRING_FROM_CHUNK(msg+6, png_ptr->zowner);
+ /* So the message that results is "<chunk> using zstream"; this is an
+ * internal error, but is very useful for debugging. i18n requirements
+ * are minimal.
+ */
+ (void)png_safecat(msg, (sizeof msg), 10, " using zstream");
+# if PNG_LIBPNG_BUILD_BASE_TYPE >= PNG_LIBPNG_BUILD_RC
+ png_warning(png_ptr, msg);
+
+ /* Attempt sane error recovery */
+ if (png_ptr->zowner == png_IDAT) /* don't steal from IDAT */
+ {
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("in use by IDAT");
+ return Z_STREAM_ERROR;
+ }
+
+ png_ptr->zowner = 0;
+# else
+ png_error(png_ptr, msg);
+# endif
+ }
+
+ {
+ int level = png_ptr->zlib_level;
+ int method = png_ptr->zlib_method;
+ int windowBits = png_ptr->zlib_window_bits;
+ int memLevel = png_ptr->zlib_mem_level;
+ int strategy; /* set below */
+ int ret; /* zlib return code */
+
+ if (owner == png_IDAT)
+ {
+ if (png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY)
+ strategy = png_ptr->zlib_strategy;
+
+ else if (png_ptr->do_filter != PNG_FILTER_NONE)
+ strategy = PNG_Z_DEFAULT_STRATEGY;
+
+ else
+ strategy = PNG_Z_DEFAULT_NOFILTER_STRATEGY;
+ }
+
+ else
+ {
+# ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+ level = png_ptr->zlib_text_level;
+ method = png_ptr->zlib_text_method;
+ windowBits = png_ptr->zlib_text_window_bits;
+ memLevel = png_ptr->zlib_text_mem_level;
+ strategy = png_ptr->zlib_text_strategy;
+# else
+ /* If customization is not supported the values all come from the
+ * IDAT values except for the strategy, which is fixed to the
+ * default. (This is the pre-1.6.0 behavior too, although it was
+ * implemented in a very different way.)
+ */
+ strategy = Z_DEFAULT_STRATEGY;
+# endif
+ }
+
+ /* Adjust 'windowBits' down if larger than 'data_size'; to stop this
+ * happening just pass 32768 as the data_size parameter. Notice that zlib
+ * requires an extra 262 bytes in the window in addition to the data to be
+ * able to see the whole of the data, so if data_size+262 takes us to the
+ * next windowBits size we need to fix up the value later. (Because even
+ * though deflate needs the extra window, inflate does not!)
+ */
+ if (data_size <= 16384)
+ {
+ /* IMPLEMENTATION NOTE: this 'half_window_size' stuff is only here to
+ * work round a Microsoft Visual C misbehavior which, contrary to C-90,
+ * widens the result of the following shift to 64-bits if (and,
+ * apparently, only if) it is used in a test.
+ */
+ unsigned int half_window_size = 1U << (windowBits-1);
+
+ while (data_size + 262 <= half_window_size)
+ {
+ half_window_size >>= 1;
+ --windowBits;
+ }
+ }
+
+ /* Check against the previous initialized values, if any. */
+ if ((png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED) &&
+ (png_ptr->zlib_set_level != level ||
+ png_ptr->zlib_set_method != method ||
+ png_ptr->zlib_set_window_bits != windowBits ||
+ png_ptr->zlib_set_mem_level != memLevel ||
+ png_ptr->zlib_set_strategy != strategy))
+ {
+ if (deflateEnd(&png_ptr->zstream) != Z_OK)
+ png_warning(png_ptr, "deflateEnd failed (ignored)");
+
+ png_ptr->flags &= ~PNG_FLAG_ZSTREAM_INITIALIZED;
+ }
+
+ /* For safety clear out the input and output pointers (currently zlib
+ * doesn't use them on Init, but it might in the future).
+ */
+ png_ptr->zstream.next_in = NULL;
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->zstream.next_out = NULL;
+ png_ptr->zstream.avail_out = 0;
+
+ /* Now initialize if required, setting the new parameters, otherwise just
+ * to a simple reset to the previous parameters.
+ */
+ if (png_ptr->flags & PNG_FLAG_ZSTREAM_INITIALIZED)
+ ret = deflateReset(&png_ptr->zstream);
+
+ else
+ {
+ ret = deflateInit2(&png_ptr->zstream, level, method, windowBits,
+ memLevel, strategy);
+
+ if (ret == Z_OK)
+ png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED;
+ }
+
+ /* The return code is from either deflateReset or deflateInit2; they have
+ * pretty much the same set of error codes.
+ */
+ if (ret == Z_OK)
+ png_ptr->zowner = owner;
+
+ else
+ png_zstream_error(png_ptr, ret);
+
+ return ret;
+ }
+}
+
+/* Clean up (or trim) a linked list of compression buffers. */
+void /* PRIVATE */
+png_free_buffer_list(png_structrp png_ptr, png_compression_bufferp *listp)
+{
+ png_compression_bufferp list = *listp;
+
+ if (list != NULL)
+ {
+ *listp = NULL;
+
+ do
+ {
+ png_compression_bufferp next = list->next;
+
+ png_free(png_ptr, list);
+ list = next;
+ }
+ while (list != NULL);
+ }
+}
+
+#ifdef PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+/* This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller to allow access to the relevant local variables.
+ *
+ * compression_buffer (new in 1.6.0) is just a linked list of zbuffer_size
+ * temporary buffers. From 1.6.0 it is retained in png_struct so that it will
+ * be correctly freed in the event of a write error (previous implementations
+ * just leaked memory.)
+ */
+typedef struct
+{
+ png_const_bytep input; /* The uncompressed input data */
+ png_alloc_size_t input_len; /* Its length */
+ png_uint_32 output_len; /* Final compressed length */
+ png_byte output[1024]; /* First block of output */
+} compression_state;
+
+static void
+png_text_compress_init(compression_state *comp, png_const_bytep input,
+ png_alloc_size_t input_len)
+{
+ comp->input = input;
+ comp->input_len = input_len;
+ comp->output_len = 0;
+}
+
+/* Compress the data in the compression state input */
+static int
+png_text_compress(png_structrp png_ptr, png_uint_32 chunk_name,
+ compression_state *comp, png_uint_32 prefix_len)
+{
+ int ret;
+
+ /* To find the length of the output it is necessary to first compress the
+ * input, the result is buffered rather than using the two-pass algorithm
+ * that is used on the inflate side; deflate is assumed to be slower and a
+ * PNG writer is assumed to have more memory available than a PNG reader.
+ *
+ * IMPLEMENTATION NOTE: the zlib API deflateBound() can be used to find an
+ * upper limit on the output size, but it is always bigger than the input
+ * size so it is likely to be more efficient to use this linked-list
+ * approach.
+ */
+ ret = png_deflate_claim(png_ptr, chunk_name, comp->input_len);
+
+ if (ret != Z_OK)
+ return ret;
+
+ /* Set up the compression buffers, we need a loop here to avoid overflowing a
+ * uInt. Use ZLIB_IO_MAX to limit the input. The output is always limited
+ * by the output buffer size, so there is no need to check that. Since this
+ * is ANSI-C we know that an 'int', hence a uInt, is always at least 16 bits
+ * in size.
+ */
+ {
+ png_compression_bufferp *end = &png_ptr->zbuffer_list;
+ png_alloc_size_t input_len = comp->input_len; /* may be zero! */
+ png_uint_32 output_len;
+
+ /* zlib updates these for us: */
+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(comp->input);
+ png_ptr->zstream.avail_in = 0; /* Set below */
+ png_ptr->zstream.next_out = comp->output;
+ png_ptr->zstream.avail_out = (sizeof comp->output);
+
+ output_len = png_ptr->zstream.avail_out;
+
+ do
+ {
+ uInt avail_in = ZLIB_IO_MAX;
+
+ if (avail_in > input_len)
+ avail_in = (uInt)input_len;
+
+ input_len -= avail_in;
+
+ png_ptr->zstream.avail_in = avail_in;
+
+ if (png_ptr->zstream.avail_out == 0)
+ {
+ png_compression_buffer *next;
+
+ /* Chunk data is limited to 2^31 bytes in length, so the prefix
+ * length must be counted here.
+ */
+ if (output_len + prefix_len > PNG_UINT_31_MAX)
+ {
+ ret = Z_MEM_ERROR;
+ break;
+ }
+
+ /* Need a new (malloc'ed) buffer, but there may be one present
+ * already.
+ */
+ next = *end;
+ if (next == NULL)
+ {
+ next = png_voidcast(png_compression_bufferp, png_malloc_base
+ (png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+
+ if (next == NULL)
+ {
+ ret = Z_MEM_ERROR;
+ break;
+ }
+
+ /* Link in this buffer (so that it will be freed later) */
+ next->next = NULL;
+ *end = next;
+ }
+
+ png_ptr->zstream.next_out = next->output;
+ png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
+ output_len += png_ptr->zstream.avail_out;
+
+ /* Move 'end' to the next buffer pointer. */
+ end = &next->next;
+ }
+
+ /* Compress the data */
+ ret = deflate(&png_ptr->zstream,
+ input_len > 0 ? Z_NO_FLUSH : Z_FINISH);
+
+ /* Claw back input data that was not consumed (because avail_in is
+ * reset above every time round the loop).
+ */
+ input_len += png_ptr->zstream.avail_in;
+ png_ptr->zstream.avail_in = 0; /* safety */
+ }
+ while (ret == Z_OK);
+
+ /* There may be some space left in the last output buffer, this needs to
+ * be subtracted from output_len.
+ */
+ output_len -= png_ptr->zstream.avail_out;
+ png_ptr->zstream.avail_out = 0; /* safety */
+ comp->output_len = output_len;
+
+ /* Now double check the output length, put in a custom message if it is
+ * too long. Otherwise ensure the z_stream::msg pointer is set to
+ * something.
+ */
+ if (output_len + prefix_len >= PNG_UINT_31_MAX)
+ {
+ png_ptr->zstream.msg = PNGZ_MSG_CAST("compressed data too long");
+ ret = Z_MEM_ERROR;
+ }
+
+ else
+ png_zstream_error(png_ptr, ret);
+
+ /* Reset zlib for another zTXt/iTXt or image data */
+ png_ptr->zowner = 0;
+
+ /* The only success case is Z_STREAM_END, input_len must be 0, if not this
+ * is an internal error.
+ */
+ if (ret == Z_STREAM_END && input_len == 0)
+ {
+ /* Fix up the deflate header, if required */
+ optimize_cmf(comp->output, comp->input_len);
+
+ /* But Z_OK is returned, not Z_STREAM_END; this allows the claim
+ * function above to return Z_STREAM_END on an error (though it never
+ * does in the current versions of zlib.)
+ */
+ return Z_OK;
+ }
+
+ else
+ return ret;
+ }
+}
+
+/* Ship the compressed text out via chunk writes */
+static void
+png_write_compressed_data_out(png_structrp png_ptr, compression_state *comp)
+{
+ png_uint_32 output_len = comp->output_len;
+ png_const_bytep output = comp->output;
+ png_uint_32 avail = (sizeof comp->output);
+ png_compression_buffer *next = png_ptr->zbuffer_list;
+
+ for (;;)
+ {
+ if (avail > output_len)
+ avail = output_len;
+
+ png_write_chunk_data(png_ptr, output, avail);
+
+ output_len -= avail;
+
+ if (output_len == 0 || next == NULL)
+ break;
+
+ avail = png_ptr->zbuffer_size;
+ output = next->output;
+ next = next->next;
+ }
+
+ /* This is an internal error; 'next' must have been NULL! */
+ if (output_len > 0)
+ png_error(png_ptr, "error writing ancillary chunked compressed data");
+}
+#endif /* PNG_WRITE_COMPRESSED_TEXT_SUPPORTED */
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
+ *
+ * The 'new_key' buffer must be 80 characters in size (for the keyword plus a
+ * trailing '\0'). If this routine returns 0 then there was no keyword, or a
+ * valid one could not be generated, and the caller must png_error.
+ */
+static png_uint_32
+png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
+{
+ png_const_charp orig_key = key;
+ png_uint_32 key_len = 0;
+ int bad_character = 0;
+ int space = 1;
+
+ png_debug(1, "in png_check_keyword");
+
+ if (key == NULL)
+ {
+ *new_key = 0;
+ return 0;
+ }
+
+ while (*key && key_len < 79)
+ {
+ png_byte ch = (png_byte)(0xff & *key++);
+
+ if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
+ *new_key++ = ch, ++key_len, space = 0;
+
+ else if (!space)
+ {
+ /* A space or an invalid character when one wasn't seen immediately
+ * before; output just a space.
+ */
+ *new_key++ = 32, ++key_len, space = 1;
+
+ /* If the character was not a space then it is invalid. */
+ if (ch != 32)
+ bad_character = ch;
+ }
+
+ else if (!bad_character)
+ bad_character = ch; /* just skip it, record the first error */
+ }
+
+ if (key_len > 0 && space) /* trailing space */
+ {
+ --key_len, --new_key;
+ if (!bad_character)
+ bad_character = 32;
+ }
+
+ /* Terminate the keyword */
+ *new_key = 0;
+
+ if (key_len == 0)
+ return 0;
+
+ /* Try to only output one warning per keyword: */
+ if (*key) /* keyword too long */
+ png_warning(png_ptr, "keyword truncated");
+
+ else if (bad_character)
+ {
+ PNG_WARNING_PARAMETERS(p)
+
+ png_warning_parameter(p, 1, orig_key);
+ png_warning_parameter_signed(p, 2, PNG_NUMBER_FORMAT_02x, bad_character);
+
+ png_formatted_warning(png_ptr, p, "keyword \"@1\": bad character '0x@2'");
+ }
+
+ return key_len;
+}
+#endif
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information. Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structrp png_ptr, png_uint_32 width, png_uint_32 height,
+ int bit_depth, int color_type, int compression_type, int filter_type,
+ int interlace_type)
+{
+ png_byte buf[13]; /* Buffer to store the IHDR info */
+
+ png_debug(1, "in png_write_IHDR");
+
+ /* Check that we have valid input data from the application info */
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ case 16:
+#endif
+ png_ptr->channels = 1; break;
+
+ default:
+ png_error(png_ptr,
+ "Invalid bit depth for grayscale image");
+ }
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ if (bit_depth != 8 && bit_depth != 16)
+#else
+ if (bit_depth != 8)
+#endif
+ png_error(png_ptr, "Invalid bit depth for RGB image");
+
+ png_ptr->channels = 3;
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ png_ptr->channels = 1;
+ break;
+
+ default:
+ png_error(png_ptr, "Invalid bit depth for paletted image");
+ }
+ break;
+
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+
+ png_ptr->channels = 2;
+ break;
+
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ if (bit_depth != 8 && bit_depth != 16)
+#else
+ if (bit_depth != 8)
+#endif
+ png_error(png_ptr, "Invalid bit depth for RGBA image");
+
+ png_ptr->channels = 4;
+ break;
+
+ default:
+ png_error(png_ptr, "Invalid image color type specified");
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid compression type specified");
+ compression_type = PNG_COMPRESSION_TYPE_BASE;
+ }
+
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a mask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+ filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid filter type specified");
+ filter_type = PNG_FILTER_TYPE_BASE;
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ if (interlace_type != PNG_INTERLACE_NONE &&
+ interlace_type != PNG_INTERLACE_ADAM7)
+ {
+ png_warning(png_ptr, "Invalid interlace type specified");
+ interlace_type = PNG_INTERLACE_ADAM7;
+ }
+#else
+ interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+ /* Save the relevent information */
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->color_type = (png_byte)color_type;
+ png_ptr->interlaced = (png_byte)interlace_type;
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->compression_type = (png_byte)compression_type;
+ png_ptr->width = width;
+ png_ptr->height = height;
+
+ png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+ png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, width);
+ /* Set the usr info, so any transformations can modify it */
+ png_ptr->usr_width = png_ptr->width;
+ png_ptr->usr_bit_depth = png_ptr->bit_depth;
+ png_ptr->usr_channels = png_ptr->channels;
+
+ /* Pack the header information into the buffer */
+ png_save_uint_32(buf, width);
+ png_save_uint_32(buf + 4, height);
+ buf[8] = (png_byte)bit_depth;
+ buf[9] = (png_byte)color_type;
+ buf[10] = (png_byte)compression_type;
+ buf[11] = (png_byte)filter_type;
+ buf[12] = (png_byte)interlace_type;
+
+ /* Write the chunk */
+ png_write_complete_chunk(png_ptr, png_IHDR, buf, (png_size_t)13);
+
+ if (!(png_ptr->do_filter))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+ png_ptr->bit_depth < 8)
+ png_ptr->do_filter = PNG_FILTER_NONE;
+
+ else
+ png_ptr->do_filter = PNG_ALL_FILTERS;
+ }
+
+ png_ptr->mode = PNG_HAVE_IHDR; /* not READY_FOR_ZTXT */
+}
+
+/* Write the palette. We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structrp png_ptr, png_const_colorp palette,
+ png_uint_32 num_pal)
+{
+ png_uint_32 i;
+ png_const_colorp pal_ptr;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_PLTE");
+
+ if ((
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
+#endif
+ num_pal == 0) || num_pal > 256)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_error(png_ptr, "Invalid number of colors in palette");
+ }
+
+ else
+ {
+ png_warning(png_ptr, "Invalid number of colors in palette");
+ return;
+ }
+ }
+
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+ {
+ png_warning(png_ptr,
+ "Ignoring request to write a PLTE chunk in grayscale PNG");
+
+ return;
+ }
+
+ png_ptr->num_palette = (png_uint_16)num_pal;
+ png_debug1(3, "num_palette = %d", png_ptr->num_palette);
+
+ png_write_chunk_header(png_ptr, png_PLTE, (png_uint_32)(num_pal * 3));
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+
+ for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+ {
+ buf[0] = pal_ptr->red;
+ buf[1] = pal_ptr->green;
+ buf[2] = pal_ptr->blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+
+#else
+ /* This is a little slower but some buggy compilers need to do this
+ * instead
+ */
+ pal_ptr=palette;
+
+ for (i = 0; i < num_pal; i++)
+ {
+ buf[0] = pal_ptr[i].red;
+ buf[1] = pal_ptr[i].green;
+ buf[2] = pal_ptr[i].blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+
+#endif
+ png_write_chunk_end(png_ptr);
+ png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* This is similar to png_text_compress, above, except that it does not require
+ * all of the data at once and, instead of buffering the compressed result,
+ * writes it as IDAT chunks. Unlike png_text_compress it *can* png_error out
+ * because it calls the write interface. As a result it does its own error
+ * reporting and does not return an error code. In the event of error it will
+ * just call png_error. The input data length may exceed 32-bits. The 'flush'
+ * parameter is exactly the same as that to deflate, with the following
+ * meanings:
+ *
+ * Z_NO_FLUSH: normal incremental output of compressed data
+ * Z_SYNC_FLUSH: do a SYNC_FLUSH, used by png_write_flush
+ * Z_FINISH: this is the end of the input, do a Z_FINISH and clean up
+ *
+ * The routine manages the acquire and release of the png_ptr->zstream by
+ * checking and (at the end) clearing png_ptr->zowner, it does some sanity
+ * checks on the 'mode' flags while doing this.
+ */
+void /* PRIVATE */
+png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
+ png_alloc_size_t input_len, int flush)
+{
+ if (png_ptr->zowner != png_IDAT)
+ {
+ /* First time. Ensure we have a temporary buffer for compression and
+ * trim the buffer list if it has more than one entry to free memory.
+ * If 'WRITE_COMPRESSED_TEXT' is not set the list will never have been
+ * created at this point, but the check here is quick and safe.
+ */
+ if (png_ptr->zbuffer_list == NULL)
+ {
+ png_ptr->zbuffer_list = png_voidcast(png_compression_bufferp,
+ png_malloc(png_ptr, PNG_COMPRESSION_BUFFER_SIZE(png_ptr)));
+ png_ptr->zbuffer_list->next = NULL;
+ }
+
+ else
+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list->next);
+
+ /* It is a terminal error if we can't claim the zstream. */
+ if (png_deflate_claim(png_ptr, png_IDAT, png_image_size(png_ptr)) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ /* The output state is maintained in png_ptr->zstream, so it must be
+ * initialized here after the claim.
+ */
+ png_ptr->zstream.next_out = png_ptr->zbuffer_list->output;
+ png_ptr->zstream.avail_out = png_ptr->zbuffer_size;
+ }
+
+ /* Now loop reading and writing until all the input is consumed or an error
+ * terminates the operation. The _out values are maintained across calls to
+ * this function, but the input must be reset each time.
+ */
+ png_ptr->zstream.next_in = PNGZ_INPUT_CAST(input);
+ png_ptr->zstream.avail_in = 0; /* set below */
+ for (;;)
+ {
+ int ret;
+
+ /* INPUT: from the row data */
+ uInt avail = ZLIB_IO_MAX;
+
+ if (avail > input_len)
+ avail = (uInt)input_len; /* safe because of the check */
+
+ png_ptr->zstream.avail_in = avail;
+ input_len -= avail;
+
+ ret = deflate(&png_ptr->zstream, input_len > 0 ? Z_NO_FLUSH : flush);
+
+ /* Include as-yet unconsumed input */
+ input_len += png_ptr->zstream.avail_in;
+ png_ptr->zstream.avail_in = 0;
+
+ /* OUTPUT: write complete IDAT chunks when avail_out drops to zero, note
+ * that these two zstream fields are preserved across the calls, therefore
+ * there is no need to set these up on entry to the loop.
+ */
+ if (png_ptr->zstream.avail_out == 0)
+ {
+ png_bytep data = png_ptr->zbuffer_list->output;
+ uInt size = png_ptr->zbuffer_size;
+
+ /* Write an IDAT containing the data then reset the buffer. The
+ * first IDAT may need deflate header optimization.
+ */
+# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+ optimize_cmf(data, png_image_size(png_ptr));
+# endif
+
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ png_ptr->mode |= PNG_HAVE_IDAT;
+
+ png_ptr->zstream.next_out = data;
+ png_ptr->zstream.avail_out = size;
+
+ /* For SYNC_FLUSH or FINISH it is essential to keep calling zlib with
+ * the same flush parameter until it has finished output, for NO_FLUSH
+ * it doesn't matter.
+ */
+ if (ret == Z_OK && flush != Z_NO_FLUSH)
+ continue;
+ }
+
+ /* The order of these checks doesn't matter much; it just effect which
+ * possible error might be detected if multiple things go wrong at once.
+ */
+ if (ret == Z_OK) /* most likely return code! */
+ {
+ /* If all the input has been consumed then just return. If Z_FINISH
+ * was used as the flush parameter something has gone wrong if we get
+ * here.
+ */
+ if (input_len == 0)
+ {
+ if (flush == Z_FINISH)
+ png_error(png_ptr, "Z_OK on Z_FINISH with output space");
+
+ return;
+ }
+ }
+
+ else if (ret == Z_STREAM_END && flush == Z_FINISH)
+ {
+ /* This is the end of the IDAT data; any pending output must be
+ * flushed. For small PNG files we may still be at the beginning.
+ */
+ png_bytep data = png_ptr->zbuffer_list->output;
+ uInt size = png_ptr->zbuffer_size - png_ptr->zstream.avail_out;
+
+# ifdef PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+ if (!(png_ptr->mode & PNG_HAVE_IDAT) &&
+ png_ptr->compression_type == PNG_COMPRESSION_TYPE_BASE)
+ optimize_cmf(data, png_image_size(png_ptr));
+# endif
+
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ png_ptr->zstream.avail_out = 0;
+ png_ptr->zstream.next_out = NULL;
+ png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
+
+ png_ptr->zowner = 0; /* Release the stream */
+ return;
+ }
+
+ else
+ {
+ /* This is an error condition. */
+ png_zstream_error(png_ptr, ret);
+ png_error(png_ptr, png_ptr->zstream.msg);
+ }
+ }
+}
+
+/* Write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structrp png_ptr)
+{
+ png_debug(1, "in png_write_IEND");
+
+ png_write_complete_chunk(png_ptr, png_IEND, NULL, (png_size_t)0);
+ png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+/* Write a gAMA chunk */
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structrp png_ptr, png_fixed_point file_gamma)
+{
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA");
+
+ /* file_gamma is saved in 1/100,000ths */
+ png_save_uint_32(buf, (png_uint_32)file_gamma);
+ png_write_complete_chunk(png_ptr, png_gAMA, buf, (png_size_t)4);
+}
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+/* Write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structrp png_ptr, int srgb_intent)
+{
+ png_byte buf[1];
+
+ png_debug(1, "in png_write_sRGB");
+
+ if (srgb_intent >= PNG_sRGB_INTENT_LAST)
+ png_warning(png_ptr,
+ "Invalid sRGB rendering intent specified");
+
+ buf[0]=(png_byte)srgb_intent;
+ png_write_complete_chunk(png_ptr, png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+/* Write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structrp png_ptr, png_const_charp name,
+ png_const_bytep profile)
+{
+ png_uint_32 name_len;
+ png_uint_32 profile_len;
+ png_byte new_name[81]; /* 1 byte for the compression byte */
+ compression_state comp;
+
+ png_debug(1, "in png_write_iCCP");
+
+ /* These are all internal problems: the profile should have been checked
+ * before when it was stored.
+ */
+ if (profile == NULL)
+ png_error(png_ptr, "No profile for iCCP chunk"); /* internal error */
+
+ profile_len = png_get_uint_32(profile);
+
+ if (profile_len < 132)
+ png_error(png_ptr, "ICC profile too short");
+
+ if (profile_len & 0x03)
+ png_error(png_ptr, "ICC profile length invalid (not a multiple of 4)");
+
+ {
+ png_uint_32 embedded_profile_len = png_get_uint_32(profile);
+
+ if (profile_len != embedded_profile_len)
+ png_error(png_ptr, "Profile length does not match profile");
+ }
+
+ name_len = png_check_keyword(png_ptr, name, new_name);
+
+ if (name_len == 0)
+ png_error(png_ptr, "iCCP: invalid keyword");
+
+ new_name[++name_len] = PNG_COMPRESSION_TYPE_BASE;
+
+ /* Make sure we include the NULL after the name and the compression type */
+ ++name_len;
+
+ png_text_compress_init(&comp, profile, profile_len);
+
+ /* Allow for keyword terminator and compression byte */
+ if (png_text_compress(png_ptr, png_iCCP, &comp, name_len) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ png_write_chunk_header(png_ptr, png_iCCP, name_len + comp.output_len);
+
+ png_write_chunk_data(png_ptr, new_name, name_len);
+
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+/* Write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structrp png_ptr, png_const_sPLT_tp spalette)
+{
+ png_uint_32 name_len;
+ png_byte new_name[80];
+ png_byte entrybuf[10];
+ png_size_t entry_size = (spalette->depth == 8 ? 6 : 10);
+ png_size_t palette_size = entry_size * spalette->nentries;
+ png_sPLT_entryp ep;
+#ifndef PNG_POINTER_INDEXING_SUPPORTED
+ int i;
+#endif
+
+ png_debug(1, "in png_write_sPLT");
+
+ name_len = png_check_keyword(png_ptr, spalette->name, new_name);
+
+ if (name_len == 0)
+ png_error(png_ptr, "sPLT: invalid keyword");
+
+ /* Make sure we include the NULL after the name */
+ png_write_chunk_header(png_ptr, png_sPLT,
+ (png_uint_32)(name_len + 2 + palette_size));
+
+ png_write_chunk_data(png_ptr, (png_bytep)new_name,
+ (png_size_t)(name_len + 1));
+
+ png_write_chunk_data(png_ptr, &spalette->depth, (png_size_t)1);
+
+ /* Loop through each palette entry, writing appropriately */
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
+ for (ep = spalette->entries; ep<spalette->entries + spalette->nentries; ep++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep->red;
+ entrybuf[1] = (png_byte)ep->green;
+ entrybuf[2] = (png_byte)ep->blue;
+ entrybuf[3] = (png_byte)ep->alpha;
+ png_save_uint_16(entrybuf + 4, ep->frequency);
+ }
+
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep->red);
+ png_save_uint_16(entrybuf + 2, ep->green);
+ png_save_uint_16(entrybuf + 4, ep->blue);
+ png_save_uint_16(entrybuf + 6, ep->alpha);
+ png_save_uint_16(entrybuf + 8, ep->frequency);
+ }
+
+ png_write_chunk_data(png_ptr, entrybuf, entry_size);
+ }
+#else
+ ep=spalette->entries;
+ for (i = 0; i>spalette->nentries; i++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep[i].red;
+ entrybuf[1] = (png_byte)ep[i].green;
+ entrybuf[2] = (png_byte)ep[i].blue;
+ entrybuf[3] = (png_byte)ep[i].alpha;
+ png_save_uint_16(entrybuf + 4, ep[i].frequency);
+ }
+
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep[i].red);
+ png_save_uint_16(entrybuf + 2, ep[i].green);
+ png_save_uint_16(entrybuf + 4, ep[i].blue);
+ png_save_uint_16(entrybuf + 6, ep[i].alpha);
+ png_save_uint_16(entrybuf + 8, ep[i].frequency);
+ }
+
+ png_write_chunk_data(png_ptr, entrybuf, entry_size);
+ }
+#endif
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+/* Write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structrp png_ptr, png_const_color_8p sbit, int color_type)
+{
+ png_byte buf[4];
+ png_size_t size;
+
+ png_debug(1, "in png_write_sBIT");
+
+ /* Make sure we don't depend upon the order of PNG_COLOR_8 */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_byte maxbits;
+
+ maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+ png_ptr->usr_bit_depth);
+
+ if (sbit->red == 0 || sbit->red > maxbits ||
+ sbit->green == 0 || sbit->green > maxbits ||
+ sbit->blue == 0 || sbit->blue > maxbits)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+
+ buf[0] = sbit->red;
+ buf[1] = sbit->green;
+ buf[2] = sbit->blue;
+ size = 3;
+ }
+
+ else
+ {
+ if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+
+ buf[0] = sbit->gray;
+ size = 1;
+ }
+
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+
+ buf[size++] = sbit->alpha;
+ }
+
+ png_write_complete_chunk(png_ptr, png_sBIT, buf, size);
+}
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+/* Write the cHRM chunk */
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structrp png_ptr, const png_xy *xy)
+{
+ png_byte buf[32];
+
+ png_debug(1, "in png_write_cHRM");
+
+ /* Each value is saved in 1/100,000ths */
+ png_save_int_32(buf, xy->whitex);
+ png_save_int_32(buf + 4, xy->whitey);
+
+ png_save_int_32(buf + 8, xy->redx);
+ png_save_int_32(buf + 12, xy->redy);
+
+ png_save_int_32(buf + 16, xy->greenx);
+ png_save_int_32(buf + 20, xy->greeny);
+
+ png_save_int_32(buf + 24, xy->bluex);
+ png_save_int_32(buf + 28, xy->bluey);
+
+ png_write_complete_chunk(png_ptr, png_cHRM, buf, 32);
+}
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+/* Write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structrp png_ptr, png_const_bytep trans_alpha,
+ png_const_color_16p tran, int num_trans, int color_type)
+{
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_tRNS");
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+ {
+ png_app_warning(png_ptr,
+ "Invalid number of transparent colors specified");
+ return;
+ }
+
+ /* Write the chunk out as it is */
+ png_write_complete_chunk(png_ptr, png_tRNS, trans_alpha,
+ (png_size_t)num_trans);
+ }
+
+ else if (color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ /* One 16 bit value */
+ if (tran->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_app_warning(png_ptr,
+ "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+
+ return;
+ }
+
+ png_save_uint_16(buf, tran->gray);
+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)2);
+ }
+
+ else if (color_type == PNG_COLOR_TYPE_RGB)
+ {
+ /* Three 16 bit values */
+ png_save_uint_16(buf, tran->red);
+ png_save_uint_16(buf + 2, tran->green);
+ png_save_uint_16(buf + 4, tran->blue);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+#else
+ if (buf[0] | buf[2] | buf[4])
+#endif
+ {
+ png_app_warning(png_ptr,
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+ return;
+ }
+
+ png_write_complete_chunk(png_ptr, png_tRNS, buf, (png_size_t)6);
+ }
+
+ else
+ {
+ png_app_warning(png_ptr, "Can't write tRNS with an alpha channel");
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+/* Write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structrp png_ptr, png_const_color_16p back, int color_type)
+{
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_bKGD");
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ (png_ptr->num_palette ||
+ (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
+#endif
+ back->index >= png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Invalid background palette index");
+ return;
+ }
+
+ buf[0] = back->index;
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)1);
+ }
+
+ else if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_save_uint_16(buf, back->red);
+ png_save_uint_16(buf + 2, back->green);
+ png_save_uint_16(buf + 4, back->blue);
+#ifdef PNG_WRITE_16BIT_SUPPORTED
+ if (png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+#else
+ if (buf[0] | buf[2] | buf[4])
+#endif
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+
+ return;
+ }
+
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)6);
+ }
+
+ else
+ {
+ if (back->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+
+ return;
+ }
+
+ png_save_uint_16(buf, back->gray);
+ png_write_complete_chunk(png_ptr, png_bKGD, buf, (png_size_t)2);
+ }
+}
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+/* Write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structrp png_ptr, png_const_uint_16p hist, int num_hist)
+{
+ int i;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_hIST");
+
+ if (num_hist > (int)png_ptr->num_palette)
+ {
+ png_debug2(3, "num_hist = %d, num_palette = %d", num_hist,
+ png_ptr->num_palette);
+
+ png_warning(png_ptr, "Invalid number of histogram entries specified");
+ return;
+ }
+
+ png_write_chunk_header(png_ptr, png_hIST, (png_uint_32)(num_hist * 2));
+
+ for (i = 0; i < num_hist; i++)
+ {
+ png_save_uint_16(buf, hist[i]);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+ }
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+/* Write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
+ png_size_t text_len)
+{
+ png_uint_32 key_len;
+ png_byte new_key[80];
+
+ png_debug(1, "in png_write_tEXt");
+
+ key_len = png_check_keyword(png_ptr, key, new_key);
+
+ if (key_len == 0)
+ png_error(png_ptr, "tEXt: invalid keyword");
+
+ if (text == NULL || *text == '\0')
+ text_len = 0;
+
+ else
+ text_len = strlen(text);
+
+ if (text_len > PNG_UINT_31_MAX - (key_len+1))
+ png_error(png_ptr, "tEXt: text too long");
+
+ /* Make sure we include the 0 after the key */
+ png_write_chunk_header(png_ptr, png_tEXt,
+ (png_uint_32)/*checked above*/(key_len + text_len + 1));
+ /*
+ * We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, new_key, key_len + 1);
+
+ if (text_len)
+ png_write_chunk_data(png_ptr, (png_const_bytep)text, text_len);
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+/* Write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structrp png_ptr, png_const_charp key, png_const_charp text,
+ png_size_t text_len, int compression)
+{
+ png_uint_32 key_len;
+ png_byte new_key[81];
+ compression_state comp;
+
+ png_debug(1, "in png_write_zTXt");
+ PNG_UNUSED(text_len) /* Always use strlen */
+
+ if (compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+ png_write_tEXt(png_ptr, key, text, 0);
+ return;
+ }
+
+ if (compression != PNG_TEXT_COMPRESSION_zTXt)
+ png_error(png_ptr, "zTXt: invalid compression type");
+
+ key_len = png_check_keyword(png_ptr, key, new_key);
+
+ if (key_len == 0)
+ png_error(png_ptr, "zTXt: invalid keyword");
+
+ /* Add the compression method and 1 for the keyword separator. */
+ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
+ ++key_len;
+
+ /* Compute the compressed data; do it now for the length */
+ png_text_compress_init(&comp, (png_const_bytep)text,
+ text == NULL ? 0 : strlen(text));
+
+ if (png_text_compress(png_ptr, png_zTXt, &comp, key_len) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+
+ /* Write start of chunk */
+ png_write_chunk_header(png_ptr, png_zTXt, key_len + comp.output_len);
+
+ /* Write key */
+ png_write_chunk_data(png_ptr, new_key, key_len);
+
+ /* Write the compressed data */
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ /* Close the chunk */
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+/* Write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structrp png_ptr, int compression, png_const_charp key,
+ png_const_charp lang, png_const_charp lang_key, png_const_charp text)
+{
+ png_uint_32 key_len, prefix_len;
+ png_size_t lang_len, lang_key_len;
+ png_byte new_key[82];
+ compression_state comp;
+
+ png_debug(1, "in png_write_iTXt");
+
+ key_len = png_check_keyword(png_ptr, key, new_key);
+
+ if (key_len == 0)
+ png_error(png_ptr, "iTXt: invalid keyword");
+
+ /* Set the compression flag */
+ switch (compression)
+ {
+ case PNG_ITXT_COMPRESSION_NONE:
+ case PNG_TEXT_COMPRESSION_NONE:
+ compression = new_key[++key_len] = 0; /* no compression */
+ break;
+
+ case PNG_TEXT_COMPRESSION_zTXt:
+ case PNG_ITXT_COMPRESSION_zTXt:
+ compression = new_key[++key_len] = 1; /* compressed */
+ break;
+
+ default:
+ png_error(png_ptr, "iTXt: invalid compression");
+ }
+
+ new_key[++key_len] = PNG_COMPRESSION_TYPE_BASE;
+ ++key_len; /* for the keywod separator */
+
+ /* We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG, however,
+ * specifies that the text is UTF-8 and this really doesn't require any
+ * checking.
+ *
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ *
+ * TODO: validate the language tag correctly (see the spec.)
+ */
+ if (lang == NULL) lang = ""; /* empty language is valid */
+ lang_len = strlen(lang)+1;
+ if (lang_key == NULL) lang_key = ""; /* may be empty */
+ lang_key_len = strlen(lang_key)+1;
+ if (text == NULL) text = ""; /* may be empty */
+
+ prefix_len = key_len;
+ if (lang_len > PNG_UINT_31_MAX-prefix_len)
+ prefix_len = PNG_UINT_31_MAX;
+ else
+ prefix_len = (png_uint_32)(prefix_len + lang_len);
+
+ if (lang_key_len > PNG_UINT_31_MAX-prefix_len)
+ prefix_len = PNG_UINT_31_MAX;
+ else
+ prefix_len = (png_uint_32)(prefix_len + lang_key_len);
+
+ png_text_compress_init(&comp, (png_const_bytep)text, strlen(text));
+
+ if (compression)
+ {
+ if (png_text_compress(png_ptr, png_iTXt, &comp, prefix_len) != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ }
+
+ else
+ {
+ if (comp.input_len > PNG_UINT_31_MAX-prefix_len)
+ png_error(png_ptr, "iTXt: uncompressed text too long");
+
+ /* So the string will fit in a chunk: */
+ comp.output_len = (png_uint_32)/*SAFE*/comp.input_len;
+ }
+
+ png_write_chunk_header(png_ptr, png_iTXt, comp.output_len + prefix_len);
+
+ png_write_chunk_data(png_ptr, new_key, key_len);
+
+ png_write_chunk_data(png_ptr, (png_const_bytep)lang, lang_len);
+
+ png_write_chunk_data(png_ptr, (png_const_bytep)lang_key, lang_key_len);
+
+ if (compression)
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ else
+ png_write_chunk_data(png_ptr, (png_const_bytep)text, comp.input_len);
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+/* Write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structrp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+ int unit_type)
+{
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_oFFs");
+
+ if (unit_type >= PNG_OFFSET_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+ png_save_int_32(buf, x_offset);
+ png_save_int_32(buf + 4, y_offset);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_complete_chunk(png_ptr, png_oFFs, buf, (png_size_t)9);
+}
+#endif
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+/* Write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structrp png_ptr, png_charp purpose, png_int_32 X0,
+ png_int_32 X1, int type, int nparams, png_const_charp units,
+ png_charpp params)
+{
+ png_uint_32 purpose_len;
+ png_size_t units_len, total_len;
+ png_size_tp params_len;
+ png_byte buf[10];
+ png_byte new_purpose[80];
+ int i;
+
+ png_debug1(1, "in png_write_pCAL (%d parameters)", nparams);
+
+ if (type >= PNG_EQUATION_LAST)
+ png_error(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+ purpose_len = png_check_keyword(png_ptr, purpose, new_purpose);
+
+ if (purpose_len == 0)
+ png_error(png_ptr, "pCAL: invalid keyword");
+
+ ++purpose_len; /* terminator */
+
+ png_debug1(3, "pCAL purpose length = %d", (int)purpose_len);
+ units_len = strlen(units) + (nparams == 0 ? 0 : 1);
+ png_debug1(3, "pCAL units length = %d", (int)units_len);
+ total_len = purpose_len + units_len + 10;
+
+ params_len = (png_size_tp)png_malloc(png_ptr,
+ (png_alloc_size_t)(nparams * (sizeof (png_size_t))));
+
+ /* Find the length of each parameter, making sure we don't count the
+ * null terminator for the last parameter.
+ */
+ for (i = 0; i < nparams; i++)
+ {
+ params_len[i] = strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+ png_debug2(3, "pCAL parameter %d length = %lu", i,
+ (unsigned long)params_len[i]);
+ total_len += params_len[i];
+ }
+
+ png_debug1(3, "pCAL total length = %d", (int)total_len);
+ png_write_chunk_header(png_ptr, png_pCAL, (png_uint_32)total_len);
+ png_write_chunk_data(png_ptr, new_purpose, purpose_len);
+ png_save_int_32(buf, X0);
+ png_save_int_32(buf + 4, X1);
+ buf[8] = (png_byte)type;
+ buf[9] = (png_byte)nparams;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+ png_write_chunk_data(png_ptr, (png_const_bytep)units, (png_size_t)units_len);
+
+ for (i = 0; i < nparams; i++)
+ {
+ png_write_chunk_data(png_ptr, (png_const_bytep)params[i], params_len[i]);
+ }
+
+ png_free(png_ptr, params_len);
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+/* Write the sCAL chunk */
+void /* PRIVATE */
+png_write_sCAL_s(png_structrp png_ptr, int unit, png_const_charp width,
+ png_const_charp height)
+{
+ png_byte buf[64];
+ png_size_t wlen, hlen, total_len;
+
+ png_debug(1, "in png_write_sCAL_s");
+
+ wlen = strlen(width);
+ hlen = strlen(height);
+ total_len = wlen + hlen + 2;
+
+ if (total_len > 64)
+ {
+ png_warning(png_ptr, "Can't write sCAL (buffer too small)");
+ return;
+ }
+
+ buf[0] = (png_byte)unit;
+ memcpy(buf + 1, width, wlen + 1); /* Append the '\0' here */
+ memcpy(buf + wlen + 2, height, hlen); /* Do NOT append the '\0' here */
+
+ png_debug1(3, "sCAL total length = %u", (unsigned int)total_len);
+ png_write_complete_chunk(png_ptr, png_sCAL, buf, total_len);
+}
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+/* Write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structrp png_ptr, png_uint_32 x_pixels_per_unit,
+ png_uint_32 y_pixels_per_unit,
+ int unit_type)
+{
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_pHYs");
+
+ if (unit_type >= PNG_RESOLUTION_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+ png_save_uint_32(buf, x_pixels_per_unit);
+ png_save_uint_32(buf + 4, y_pixels_per_unit);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_complete_chunk(png_ptr, png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+/* Write the tIME chunk. Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structrp png_ptr, png_const_timep mod_time)
+{
+ png_byte buf[7];
+
+ png_debug(1, "in png_write_tIME");
+
+ if (mod_time->month > 12 || mod_time->month < 1 ||
+ mod_time->day > 31 || mod_time->day < 1 ||
+ mod_time->hour > 23 || mod_time->second > 60)
+ {
+ png_warning(png_ptr, "Invalid time specified for tIME chunk");
+ return;
+ }
+
+ png_save_uint_16(buf, mod_time->year);
+ buf[2] = mod_time->month;
+ buf[3] = mod_time->day;
+ buf[4] = mod_time->hour;
+ buf[5] = mod_time->minute;
+ buf[6] = mod_time->second;
+
+ png_write_complete_chunk(png_ptr, png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* Initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structrp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_alloc_size_t buf_size;
+ int usr_pixel_depth;
+
+ png_debug(1, "in png_write_start_row");
+
+ usr_pixel_depth = png_ptr->usr_channels * png_ptr->usr_bit_depth;
+ buf_size = PNG_ROWBYTES(usr_pixel_depth, png_ptr->width) + 1;
+
+ /* 1.5.6: added to allow checking in the row write code. */
+ png_ptr->transformed_pixel_depth = png_ptr->pixel_depth;
+ png_ptr->maximum_pixel_depth = (png_byte)usr_pixel_depth;
+
+ /* Set up row buffer */
+ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, buf_size);
+
+ png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ /* Set up filtering buffer, if using this filter */
+ if (png_ptr->do_filter & PNG_FILTER_SUB)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
+
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ /* We only need to keep the previous row if we are using one of these. */
+ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+ {
+ /* Set up previous row buffer */
+ png_ptr->prev_row = (png_bytep)png_calloc(png_ptr, buf_size);
+
+ if (png_ptr->do_filter & PNG_FILTER_UP)
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ png_ptr->rowbytes + 1);
+
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_AVG)
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ png_ptr->rowbytes + 1);
+
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_PAETH)
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ png_ptr->rowbytes + 1);
+
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced, we need to set up width and height of pass */
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+
+ png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+ png_pass_start[0]) / png_pass_inc[0];
+ }
+
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ }
+
+ else
+#endif
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+}
+
+/* Internal use only. Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structrp png_ptr)
+{
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* Start of interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* Offset to next interlace block in the y direction */
+ static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_debug(1, "in png_write_finish_row");
+
+ /* Next row */
+ png_ptr->row_number++;
+
+ /* See if we are done */
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* If interlaced, go to next pass */
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ if (png_ptr->transformations & PNG_INTERLACE)
+ {
+ png_ptr->pass++;
+ }
+
+ else
+ {
+ /* Loop until we find a non-zero width or height pass */
+ do
+ {
+ png_ptr->pass++;
+
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->usr_width = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+
+ } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+ }
+
+ /* Reset the row above the image for the next pass */
+ if (png_ptr->pass < 7)
+ {
+ if (png_ptr->prev_row != NULL)
+ memset(png_ptr->prev_row, 0,
+ (png_size_t)(PNG_ROWBYTES(png_ptr->usr_channels*
+ png_ptr->usr_bit_depth, png_ptr->width)) + 1);
+
+ return;
+ }
+ }
+#endif
+
+ /* If we get here, we've just written the last row, so we need
+ to flush the compressor */
+ png_compress_IDAT(png_ptr, NULL, 0, Z_FINISH);
+}
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass. As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* Start of interlace block */
+ static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* Offset to next interlace block */
+ static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ png_debug(1, "in png_do_write_interlace");
+
+ /* We don't have to do anything on the last pass (6) */
+ if (pass < 6)
+ {
+ /* Each pixel depth is handled separately */
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ d = 0;
+ shift = 7;
+
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 3);
+ value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 7;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+
+ else
+ shift--;
+
+ }
+ if (shift != 7)
+ *dp = (png_byte)d;
+
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 6;
+ d = 0;
+
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 2);
+ value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+
+ else
+ shift -= 2;
+ }
+ if (shift != 6)
+ *dp = (png_byte)d;
+
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 4;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 1);
+ value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+
+ else
+ shift -= 4;
+ }
+ if (shift != 4)
+ *dp = (png_byte)d;
+
+ break;
+ }
+
+ default:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ png_size_t pixel_bytes;
+
+ /* Start at the beginning */
+ dp = row;
+
+ /* Find out how many bytes each pixel takes up */
+ pixel_bytes = (row_info->pixel_depth >> 3);
+
+ /* Loop through the row, only looking at the pixels that matter */
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ /* Find out where the original pixel is */
+ sp = row + (png_size_t)i * pixel_bytes;
+
+ /* Move the pixel */
+ if (dp != sp)
+ memcpy(dp, sp, pixel_bytes);
+
+ /* Next pixel */
+ dp += pixel_bytes;
+ }
+ break;
+ }
+ }
+ /* Set new row width */
+ row_info->width = (row_info->width +
+ png_pass_inc[pass] - 1 -
+ png_pass_start[pass]) /
+ png_pass_inc[pass];
+
+ row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,
+ row_info->width);
+ }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+static void png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+ png_size_t row_bytes);
+
+#define PNG_MAXSUM (((png_uint_32)(-1)) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void /* PRIVATE */
+png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
+{
+ png_bytep best_row;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ png_bytep prev_row, row_buf;
+ png_uint_32 mins, bpp;
+ png_byte filter_to_do = png_ptr->do_filter;
+ png_size_t row_bytes = row_info->rowbytes;
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ int num_p_filters = png_ptr->num_prev_filters;
+#endif
+
+ png_debug(1, "in png_write_find_filter");
+
+#ifndef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->row_number == 0 && filter_to_do == PNG_ALL_FILTERS)
+ {
+ /* These will never be selected so we need not test them. */
+ filter_to_do &= ~(PNG_FILTER_UP | PNG_FILTER_PAETH);
+ }
+#endif
+
+ /* Find out how many bytes offset each pixel is */
+ bpp = (row_info->pixel_depth + 7) >> 3;
+
+ prev_row = png_ptr->prev_row;
+#endif
+ best_row = png_ptr->row_buf;
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+ row_buf = best_row;
+ mins = PNG_MAXSUM;
+
+ /* The prediction method we use is to find which method provides the
+ * smallest value when summing the absolute values of the distances
+ * from zero, using anything >= 128 as negative numbers. This is known
+ * as the "minimum sum of absolute differences" heuristic. Other
+ * heuristics are the "weighted minimum sum of absolute differences"
+ * (experimental and can in theory improve compression), and the "zlib
+ * predictive" method (not implemented yet), which does test compressions
+ * of lines using different filter methods, and then chooses the
+ * (series of) filter(s) that give minimum compressed data size (VERY
+ * computationally expensive).
+ *
+ * GRR 980525: consider also
+ *
+ * (1) minimum sum of absolute differences from running average (i.e.,
+ * keep running sum of non-absolute differences & count of bytes)
+ * [track dispersion, too? restart average if dispersion too large?]
+ *
+ * (1b) minimum sum of absolute differences from sliding average, probably
+ * with window size <= deflate window (usually 32K)
+ *
+ * (2) minimum sum of squared differences from zero or running average
+ * (i.e., ~ root-mean-square approach)
+ */
+
+
+ /* We don't need to test the 'no filter' case if this is the only filter
+ * that has been chosen, as it doesn't actually do anything to the data.
+ */
+ if ((filter_to_do & PNG_FILTER_NONE) && filter_to_do != PNG_FILTER_NONE)
+ {
+ png_bytep rp;
+ png_uint_32 sum = 0;
+ png_size_t i;
+ int v;
+
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+ {
+ v = *rp;
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ png_uint_32 sumhi, sumlo;
+ int j;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+ /* Reduce the sum if we match any of the previous rows */
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ /* Factor in the cost of this filter (this is here for completeness,
+ * but it makes no sense to have a "cost" for the NONE filter, as
+ * it has the minimum possible computational cost - none).
+ */
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+ mins = sum;
+ }
+
+ /* Sub filter */
+ if (filter_to_do == PNG_FILTER_SUB)
+ /* It's the only filter so no testing is needed */
+ {
+ png_bytep rp, lp, dp;
+ png_size_t i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ *dp = *rp;
+ }
+
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ }
+
+ best_row = png_ptr->sub_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_SUB)
+ {
+ png_bytep rp, dp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* We temporarily increase the "minimum sum" by the factor we
+ * would reduce the sum of this filter, so that we can do the
+ * early exit comparison without scaling the sum each time.
+ */
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ v = *dp = *rp;
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->sub_row;
+ }
+ }
+
+ /* Up filter */
+ if (filter_to_do == PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_size_t i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ }
+
+ best_row = png_ptr->up_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
+
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->up_row;
+ }
+ }
+
+ /* Avg filter */
+ if (filter_to_do == PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+ }
+
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+ }
+ best_row = png_ptr->avg_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ v = *dp++ =
+ (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->avg_row;
+ }
+ }
+
+ /* Paeth filter */
+ if (filter_to_do == PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_size_t i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+ }
+ best_row = png_ptr->paeth_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_size_t i;
+ int v;
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+ p = b - c;
+ pc = a - c;
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* PNG_SLOW_PAETH */
+ p = a + b - c;
+ pa = abs(p - a);
+ pb = abs(p - b);
+ pc = abs(p - c);
+
+ if (pa <= pb && pa <= pc)
+ p = a;
+
+ else if (pb <= pc)
+ p = b;
+
+ else
+ p = c;
+#endif /* PNG_SLOW_PAETH */
+
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ best_row = png_ptr->paeth_row;
+ }
+ }
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+
+ /* Do the actual writing of the filtered row data from the chosen filter. */
+ png_write_filtered_row(png_ptr, best_row, row_info->rowbytes+1);
+
+#ifdef PNG_WRITE_FILTER_SUPPORTED
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ /* Save the type of filter we picked this time for future calculations */
+ if (png_ptr->num_prev_filters > 0)
+ {
+ int j;
+
+ for (j = 1; j < num_p_filters; j++)
+ {
+ png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+ }
+
+ png_ptr->prev_filters[j] = best_row[0];
+ }
+#endif
+#endif /* PNG_WRITE_FILTER_SUPPORTED */
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+static void
+png_write_filtered_row(png_structrp png_ptr, png_bytep filtered_row,
+ png_size_t full_row_length/*includes filter byte*/)
+{
+ png_debug(1, "in png_write_filtered_row");
+
+ png_debug1(2, "filter = %d", filtered_row[0]);
+
+ png_compress_IDAT(png_ptr, filtered_row, full_row_length, Z_NO_FLUSH);
+
+ /* Swap the current and previous rows */
+ if (png_ptr->prev_row != NULL)
+ {
+ png_bytep tptr;
+
+ tptr = png_ptr->prev_row;
+ png_ptr->prev_row = png_ptr->row_buf;
+ png_ptr->row_buf = tptr;
+ }
+
+ /* Finish row - updates counters and flushes zlib if last row */
+ png_write_finish_row(png_ptr);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_ptr->flush_rows++;
+
+ if (png_ptr->flush_dist > 0 &&
+ png_ptr->flush_rows >= png_ptr->flush_dist)
+ {
+ png_write_flush(png_ptr);
+ }
+#endif
+}
+#endif /* PNG_WRITE_SUPPORTED */
+#endif//_FPDFAPI_MINI_
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/png.h b/core/src/fxcodec/fx_lpng/lpng_v163/png.h
new file mode 100644
index 0000000000..c3fb52d11a
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/png.h
@@ -0,0 +1,3563 @@
+
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.6.3 - July 18, 2013
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license (See LICENSE, below)
+ *
+ * Authors and maintainers:
+ * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ * libpng versions 0.97, January 1998, through 1.6.3 - July 18, 2013: Glenn
+ * See also "Contributing Authors", below.
+ *
+ * Note about libpng version numbers:
+ *
+ * Due to various miscommunications, unforeseen code incompatibilities
+ * and occasional factors outside the authors' control, version numbering
+ * on the library has not always been consistent and straightforward.
+ * The following table summarizes matters since version 0.89c, which was
+ * the first widely used release:
+ *
+ * source png.h png.h shared-lib
+ * version string int version
+ * ------- ------ ----- ----------
+ * 0.89c "1.0 beta 3" 0.89 89 1.0.89
+ * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90]
+ * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95]
+ * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96]
+ * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97]
+ * 0.97c 0.97 97 2.0.97
+ * 0.98 0.98 98 2.0.98
+ * 0.99 0.99 98 2.0.99
+ * 0.99a-m 0.99 99 2.0.99
+ * 1.00 1.00 100 2.1.0 [100 should be 10000]
+ * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000]
+ * 1.0.1 png.h string is 10001 2.1.0
+ * 1.0.1a-e identical to the 10002 from here on, the shared library
+ * 1.0.2 source version) 10002 is 2.V where V is the source code
+ * 1.0.2a-b 10003 version, except as noted.
+ * 1.0.3 10003
+ * 1.0.3a-d 10004
+ * 1.0.4 10004
+ * 1.0.4a-f 10005
+ * 1.0.5 (+ 2 patches) 10005
+ * 1.0.5a-d 10006
+ * 1.0.5e-r 10100 (not source compatible)
+ * 1.0.5s-v 10006 (not binary compatible)
+ * 1.0.6 (+ 3 patches) 10006 (still binary incompatible)
+ * 1.0.6d-f 10007 (still binary incompatible)
+ * 1.0.6g 10007
+ * 1.0.6h 10007 10.6h (testing xy.z so-numbering)
+ * 1.0.6i 10007 10.6i
+ * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0)
+ * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible)
+ * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
+ * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
+ * 1.0.7 1 10007 (still compatible)
+ * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
+ * 1.0.8rc1 1 10008 2.1.0.8rc1
+ * 1.0.8 1 10008 2.1.0.8
+ * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
+ * 1.0.9rc1 1 10009 2.1.0.9rc1
+ * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
+ * 1.0.9rc2 1 10009 2.1.0.9rc2
+ * 1.0.9 1 10009 2.1.0.9
+ * 1.0.10beta1 1 10010 2.1.0.10beta1
+ * 1.0.10rc1 1 10010 2.1.0.10rc1
+ * 1.0.10 1 10010 2.1.0.10
+ * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
+ * 1.0.11rc1 1 10011 2.1.0.11rc1
+ * 1.0.11 1 10011 2.1.0.11
+ * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
+ * 1.0.12rc1 2 10012 2.1.0.12rc1
+ * 1.0.12 2 10012 2.1.0.12
+ * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned)
+ * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
+ * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
+ * 1.2.0rc1 3 10200 3.1.2.0rc1
+ * 1.2.0 3 10200 3.1.2.0
+ * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4
+ * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
+ * 1.2.1 3 10201 3.1.2.1
+ * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
+ * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
+ * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
+ * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
+ * 1.0.13 10 10013 10.so.0.1.0.13
+ * 1.2.2 12 10202 12.so.0.1.2.2
+ * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
+ * 1.2.3 12 10203 12.so.0.1.2.3
+ * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
+ * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1
+ * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
+ * 1.0.14 10 10014 10.so.0.1.0.14
+ * 1.2.4 13 10204 12.so.0.1.2.4
+ * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
+ * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
+ * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
+ * 1.0.15 10 10015 10.so.0.1.0.15
+ * 1.2.5 13 10205 12.so.0.1.2.5
+ * 1.2.6beta1-4 13 10206 12.so.0.1.2.6beta1-4
+ * 1.0.16 10 10016 10.so.0.1.0.16
+ * 1.2.6 13 10206 12.so.0.1.2.6
+ * 1.2.7beta1-2 13 10207 12.so.0.1.2.7beta1-2
+ * 1.0.17rc1 10 10017 12.so.0.1.0.17rc1
+ * 1.2.7rc1 13 10207 12.so.0.1.2.7rc1
+ * 1.0.17 10 10017 12.so.0.1.0.17
+ * 1.2.7 13 10207 12.so.0.1.2.7
+ * 1.2.8beta1-5 13 10208 12.so.0.1.2.8beta1-5
+ * 1.0.18rc1-5 10 10018 12.so.0.1.0.18rc1-5
+ * 1.2.8rc1-5 13 10208 12.so.0.1.2.8rc1-5
+ * 1.0.18 10 10018 12.so.0.1.0.18
+ * 1.2.8 13 10208 12.so.0.1.2.8
+ * 1.2.9beta1-3 13 10209 12.so.0.1.2.9beta1-3
+ * 1.2.9beta4-11 13 10209 12.so.0.9[.0]
+ * 1.2.9rc1 13 10209 12.so.0.9[.0]
+ * 1.2.9 13 10209 12.so.0.9[.0]
+ * 1.2.10beta1-7 13 10210 12.so.0.10[.0]
+ * 1.2.10rc1-2 13 10210 12.so.0.10[.0]
+ * 1.2.10 13 10210 12.so.0.10[.0]
+ * 1.4.0beta1-5 14 10400 14.so.0.0[.0]
+ * 1.2.11beta1-4 13 10211 12.so.0.11[.0]
+ * 1.4.0beta7-8 14 10400 14.so.0.0[.0]
+ * 1.2.11 13 10211 12.so.0.11[.0]
+ * 1.2.12 13 10212 12.so.0.12[.0]
+ * 1.4.0beta9-14 14 10400 14.so.0.0[.0]
+ * 1.2.13 13 10213 12.so.0.13[.0]
+ * 1.4.0beta15-36 14 10400 14.so.0.0[.0]
+ * 1.4.0beta37-87 14 10400 14.so.14.0[.0]
+ * 1.4.0rc01 14 10400 14.so.14.0[.0]
+ * 1.4.0beta88-109 14 10400 14.so.14.0[.0]
+ * 1.4.0rc02-08 14 10400 14.so.14.0[.0]
+ * 1.4.0 14 10400 14.so.14.0[.0]
+ * 1.4.1beta01-03 14 10401 14.so.14.1[.0]
+ * 1.4.1rc01 14 10401 14.so.14.1[.0]
+ * 1.4.1beta04-12 14 10401 14.so.14.1[.0]
+ * 1.4.1 14 10401 14.so.14.1[.0]
+ * 1.4.2 14 10402 14.so.14.2[.0]
+ * 1.4.3 14 10403 14.so.14.3[.0]
+ * 1.4.4 14 10404 14.so.14.4[.0]
+ * 1.5.0beta01-58 15 10500 15.so.15.0[.0]
+ * 1.5.0rc01-07 15 10500 15.so.15.0[.0]
+ * 1.5.0 15 10500 15.so.15.0[.0]
+ * 1.5.1beta01-11 15 10501 15.so.15.1[.0]
+ * 1.5.1rc01-02 15 10501 15.so.15.1[.0]
+ * 1.5.1 15 10501 15.so.15.1[.0]
+ * 1.5.2beta01-03 15 10502 15.so.15.2[.0]
+ * 1.5.2rc01-03 15 10502 15.so.15.2[.0]
+ * 1.5.2 15 10502 15.so.15.2[.0]
+ * 1.5.3beta01-10 15 10503 15.so.15.3[.0]
+ * 1.5.3rc01-02 15 10503 15.so.15.3[.0]
+ * 1.5.3beta11 15 10503 15.so.15.3[.0]
+ * 1.5.3 [omitted]
+ * 1.5.4beta01-08 15 10504 15.so.15.4[.0]
+ * 1.5.4rc01 15 10504 15.so.15.4[.0]
+ * 1.5.4 15 10504 15.so.15.4[.0]
+ * 1.5.5beta01-08 15 10505 15.so.15.5[.0]
+ * 1.5.5rc01 15 10505 15.so.15.5[.0]
+ * 1.5.5 15 10505 15.so.15.5[.0]
+ * 1.5.6beta01-07 15 10506 15.so.15.6[.0]
+ * 1.5.6rc01-03 15 10506 15.so.15.6[.0]
+ * 1.5.6 15 10506 15.so.15.6[.0]
+ * 1.5.7beta01-05 15 10507 15.so.15.7[.0]
+ * 1.5.7rc01-03 15 10507 15.so.15.7[.0]
+ * 1.5.7 15 10507 15.so.15.7[.0]
+ * 1.6.0beta01-40 16 10600 16.so.16.0[.0]
+ * 1.6.0rc01-08 16 10600 16.so.16.0[.0]
+ * 1.6.0 16 10600 16.so.16.0[.0]
+ * 1.6.1beta01-09 16 10601 16.so.16.1[.0]
+ * 1.6.1rc01 16 10601 16.so.16.1[.0]
+ * 1.6.1 16 10601 16.so.16.1[.0]
+ * 1.6.2beta01 16 10602 16.so.16.2[.0]
+ * 1.6.2rc01-06 16 10602 16.so.16.2[.0]
+ * 1.6.2 16 10602 16.so.16.2[.0]
+ * 1.6.3beta01-11 16 10603 16.so.16.3[.0]
+ * 1.6.3rc01 16 10603 16.so.16.3[.0]
+ * 1.6.3 16 10603 16.so.16.3[.0]
+ *
+ * Henceforth the source version will match the shared-library major
+ * and minor numbers; the shared-library major version number will be
+ * used for changes in backward compatibility, as it is intended. The
+ * PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ * for applications, is an unsigned integer of the form xyyzz corresponding
+ * to the source version x.y.z (leading zeros in y and z). Beta versions
+ * were given the previous public release number plus a letter, until
+ * version 1.0.6j; from then on they were given the upcoming public
+ * release number plus "betaNN" or "rcNN".
+ *
+ * Binary incompatibility exists only when applications make direct access
+ * to the info_ptr or png_ptr members through png.h, and the compiled
+ * application is loaded with a different version of the library.
+ *
+ * DLLNUM will change each time there are forward or backward changes
+ * in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng-manual.txt or libpng.3 for more information. The PNG
+ * specification is available as a W3C Recommendation and as an ISO
+ * Specification, <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * This code is released under the libpng license.
+ *
+ * libpng versions 1.2.6, August 15, 2004, through 1.6.3, July 18, 2013, are
+ * Copyright (c) 2004, 2006-2013 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.2.5
+ * with the following individual added to the list of Contributing Authors:
+ *
+ * Cosmin Truta
+ *
+ * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+ * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * Simon-Pierre Cadieux
+ * Eric S. Raymond
+ * Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ * There is no warranty against interference with your enjoyment of the
+ * library or against infringement. There is no warranty that our
+ * efforts or the library will fulfill any of your particular purposes
+ * or needs. This library is provided with all faults, and the entire
+ * risk of satisfactory quality, performance, accuracy, and effort is with
+ * the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * Tom Lane
+ * Glenn Randers-Pehrson
+ * Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * John Bowler
+ * Kevin Bracey
+ * Sam Bushell
+ * Magnus Holmgren
+ * Greg Roelofs
+ * Tom Tanner
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ * Andreas Dilger
+ * Dave Martindale
+ * Guy Eric Schalnat
+ * Paul Schmidt
+ * Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS". The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose. The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ * 1. The origin of this source code must not be misrepresented.
+ *
+ * 2. Altered versions must be plainly marked as such and must not
+ * be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from
+ * any source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products. If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s", png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * Libpng is OSI Certified Open Source Software. OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience. This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ * July 18, 2013
+ *
+ * Since the PNG Development group is an ad-hoc body, we can't make
+ * an official declaration.
+ *
+ * This is your unofficial assurance that libpng from version 0.71 and
+ * upward through 1.6.3 are Y2K compliant. It is my belief that
+ * earlier versions were also Y2K compliant.
+ *
+ * Libpng only has two year fields. One is a 2-byte unsigned integer
+ * that will hold years up to 65535. The other, which is deprecated,
+ * holds the date in text format, and will hold years up to 9999.
+ *
+ * The integer is
+ * "png_uint_16 year" in png_time_struct.
+ *
+ * The string is
+ * "char time_buffer[29]" in png_struct. This is no longer used
+ * in libpng-1.6.x and will be removed from libpng-1.7.0.
+ *
+ * There are seven time-related functions:
+ * png.c: png_convert_to_rfc_1123_buffer() in png.c
+ * (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and
+ * png_convert_to_rfc_1152() in error prior to libpng-0.98)
+ * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ * png_convert_from_time_t() in pngwrite.c
+ * png_get_tIME() in pngget.c
+ * png_handle_tIME() in pngrutil.c, called in pngread.c
+ * png_set_tIME() in pngset.c
+ * png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ * All handle dates properly in a Y2K environment. The
+ * png_convert_from_time_t() function calls gmtime() to convert from system
+ * clock time, which returns (year - 1900), which we properly convert to
+ * the full 4-digit year. There is a possibility that libpng applications
+ * are not passing 4-digit years into the png_convert_to_rfc_1123_buffer()
+ * function, or that they are incorrectly passing only a 2-digit year
+ * instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ * but this is not under our control. The libpng documentation has always
+ * stated that it works with 4-digit years, and the APIs have been
+ * documented as such.
+ *
+ * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+ * integer to hold the year, and can hold years as large as 65535.
+ *
+ * zlib, upon which libpng depends, is also Y2K compliant. It contains
+ * no date-related code.
+ *
+ * Glenn Randers-Pehrson
+ * libpng maintainer
+ * PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+/* This is not the place to learn how to use libpng. The file libpng-manual.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build. This file is useful for looking
+ * at the actual function definitions and structure components.
+ *
+ * If you just need to read a PNG file and don't want to read the documentation
+ * skip to the end of this file and read the section entitled 'simplified API'.
+ */
+
+/* Sunliang.liu add 20100319 for avoid name conflict. */
+#define png_set_sig_bytes FOXIT_png_set_sig_bytes
+#define png_sig_cmp FOXIT_png_sig_cmp
+#define png_create_info_struct FOXIT_png_create_info_struct
+#define png_destroy_info_struct FOXIT_png_destroy_info_struct
+#define png_info_init_3 FOXIT_png_info_init_3
+#define png_data_freer FOXIT_png_data_freer
+#define png_free_data FOXIT_png_free_data
+#define png_info_destroy FOXIT_png_info_destroy
+#define png_get_io_ptr FOXIT_png_get_io_ptr
+#define png_init_io FOXIT_png_init_io
+#define png_convert_to_rfc1123 FOXIT_png_convert_to_rfc1123
+#define png_get_copyright FOXIT_png_get_copyright
+#define png_get_libpng_ver FOXIT_png_get_libpng_ver
+#define png_get_header_ver FOXIT_png_get_header_ver
+#define png_get_header_version FOXIT_png_get_header_version
+#define png_handle_as_unknown FOXIT_png_handle_as_unknown
+#define png_reset_zstream FOXIT_png_reset_zstream
+#define png_access_version_number FOXIT_png_access_version_number
+#define png_mmx_support FOXIT_png_mmx_support
+#define png_create_read_struct FOXIT_png_create_read_struct
+#define png_create_read_struct_2 FOXIT_png_create_read_struct_2
+#define png_create_write_struct FOXIT_png_create_write_struct
+#define png_create_write_struct_2 FOXIT_png_create_write_struct_2
+#define png_get_compression_buffer_size FOXIT_png_get_compression_buffer_size
+#define png_set_compression_buffer_size FOXIT_png_set_compression_buffer_size
+#define png_set_longjmp_fn FOXIT_png_set_longjmp_fn
+#define png_longjmp FOXIT_png_longjmp
+#define png_write_sig FOXIT_png_write_sig
+#define png_write_chunk FOXIT_png_write_chunk
+#define png_write_chunk_start FOXIT_png_write_chunk_start
+#define png_write_chunk_data FOXIT_png_write_chunk_data
+#define png_write_chunk_end FOXIT_png_write_chunk_end
+#define png_write_info_before_PLTE FOXIT_png_write_info_before_PLTE
+#define png_write_info FOXIT_png_write_info
+#define png_read_info FOXIT_png_read_info
+#define png_convert_to_rfc1123_buffer FOXIT_png_convert_to_rfc1123_buffer
+#define png_convert_from_struct_tm FOXIT_png_convert_from_struct_tm
+#define png_convert_from_time_t FOXIT_png_convert_from_time_t
+#define png_set_expand FOXIT_png_set_expand
+#define png_set_expand_gray_1_2_4_to_8 FOXIT_png_set_expand_gray_1_2_4_to_8
+#define png_set_palette_to_rgb FOXIT_png_set_palette_to_rgb
+#define png_set_tRNS_to_alpha FOXIT_png_set_tRNS_to_alpha
+#define png_set_expand_16 FOXIT_png_set_expand_16
+#define png_set_bgr FOXIT_png_set_bgr
+#define png_set_gray_to_rgb FOXIT_png_set_gray_to_rgb
+#define png_set_rgb_to_gray FOXIT_png_set_rgb_to_gray
+#define png_set_rgb_to_gray_fixed FOXIT_png_set_rgb_to_gray_fixed
+#define png_get_rgb_to_gray_status FOXIT_png_get_rgb_to_gray_status
+#define png_build_grayscale_palette FOXIT_png_build_grayscale_palette
+#define png_set_alpha_mode FOXIT_png_set_alpha_mode
+#define png_set_alpha_mode_fixed FOXIT_png_set_alpha_mode_fixed
+#define png_set_strip_alpha FOXIT_png_set_strip_alpha
+#define png_set_swap_alpha FOXIT_png_set_swap_alpha
+#define png_set_invert_alpha FOXIT_png_set_invert_alpha
+#define png_set_filler FOXIT_png_set_filler
+#define png_set_add_alpha FOXIT_png_set_add_alpha
+#define png_set_swap FOXIT_png_set_swap
+#define png_set_packing FOXIT_png_set_packing
+#define png_set_packswap FOXIT_png_set_packswap
+#define png_set_shift FOXIT_png_set_shift
+#define png_set_interlace_handling FOXIT_png_set_interlace_handling
+#define png_set_invert_mono FOXIT_png_set_invert_mono
+#define png_set_background FOXIT_png_set_background
+#define png_set_background_fixed FOXIT_png_set_background_fixed
+#define png_set_scale_16 FOXIT_png_set_scale_16
+#define png_set_quantize FOXIT_png_set_quantize
+#define png_set_gamma FOXIT_png_set_gamma
+#define png_set_gamma_fixed FOXIT_png_set_gamma_fixed
+#define png_set_flush FOXIT_png_set_flush
+#define png_write_flush FOXIT_png_write_flush
+#define png_start_read_image FOXIT_png_start_read_image
+#define png_read_update_info FOXIT_png_read_update_info
+#define png_read_rows FOXIT_png_read_rows
+#define png_read_row FOXIT_png_read_row
+#define png_read_image FOXIT_png_read_image
+#define png_write_row FOXIT_png_write_row
+#define png_write_rows FOXIT_png_write_rows
+#define png_write_image FOXIT_png_write_image
+#define png_write_end FOXIT_png_write_end
+#define png_read_end FOXIT_png_read_end
+#define png_destroy_read_struct FOXIT_png_destroy_read_struct
+#define png_destroy_write_struct FOXIT_png_destroy_write_struct
+#define png_set_crc_action FOXIT_png_set_crc_action
+#define png_set_filter FOXIT_png_set_filter
+#define png_set_filter_heuristics FOXIT_png_set_filter_heuristics
+#define png_set_filter_heuristics_fixed FOXIT_png_set_filter_heuristics_fixed
+#define png_set_compression_level FOXIT_png_set_compression_level
+#define png_set_compression_mem_level FOXIT_png_set_compression_mem_level
+#define png_set_compression_strategy FOXIT_png_set_compression_strategy
+#define png_set_compression_window_bits FOXIT_png_set_compression_window_bits
+#define png_set_compression_method FOXIT_png_set_compression_method
+#define png_set_text_compression_level FOXIT_png_set_text_compression_level
+#define png_set_text_compression_mem_level FOXIT_png_set_text_compression_mem_level
+#define png_set_text_compression_strategy FOXIT_png_set_text_compression_strategy
+#define png_set_text_compression_window_bits FOXIT_png_set_text_compression_window_bits
+#define png_set_text_compression_method FOXIT_png_set_text_compression_method
+#define png_set_error_fn FOXIT_png_set_error_fn
+#define png_get_error_ptr FOXIT_png_get_error_ptr
+#define png_set_write_fn FOXIT_png_set_write_fn
+#define png_set_read_fn FOXIT_png_set_read_fn
+#define png_set_read_status_fn FOXIT_png_set_read_status_fn
+#define png_set_write_status_fn FOXIT_png_set_write_status_fn
+#define png_set_read_user_transform_fn FOXIT_png_set_read_user_transform_fn
+#define png_set_write_user_transform_fn FOXIT_png_set_write_user_transform_fn
+#define png_set_user_transform_info FOXIT_png_set_user_transform_info
+#define png_get_user_transform_ptr FOXIT_png_get_user_transform_ptr
+#define png_get_current_row_number FOXIT_png_get_current_row_number
+#define png_get_current_pass_number FOXIT_png_get_current_pass_number
+#define png_set_read_user_chunk_fn FOXIT_png_set_read_user_chunk_fn
+#define png_get_user_chunk_ptr FOXIT_png_get_user_chunk_ptr
+#define png_set_progressive_read_fn FOXIT_png_set_progressive_read_fn
+#define png_get_progressive_ptr FOXIT_png_get_progressive_ptr
+#define png_process_data FOXIT_png_process_data
+#define png_process_data_pause FOXIT_png_process_data_pause
+#define png_process_data_skip FOXIT_png_process_data_skip
+#define png_progressive_combine_row FOXIT_png_progressive_combine_row
+#define png_calloc FOXIT_png_calloc
+#define png_error FOXIT_png_error
+#define png_chunk_error FOXIT_png_chunk_error
+#define png_err FOXIT_png_err
+#define png_warning FOXIT_png_warning
+#define png_chunk_warning FOXIT_png_chunk_warning
+#define png_benign_error FOXIT_png_benign_error
+#define png_chunk_benign_error FOXIT_png_chunk_benign_error
+#define png_set_benign_errors FOXIT_png_set_benign_errors
+#define png_get_valid FOXIT_png_get_valid
+#define png_get_rowbytes FOXIT_png_get_rowbytes
+#define png_get_rows FOXIT_png_get_rows
+#define png_set_rows FOXIT_png_set_rows
+#define png_get_channels FOXIT_png_get_channels
+#define png_get_image_width FOXIT_png_get_image_width
+#define png_get_image_height FOXIT_png_get_image_height
+#define png_get_bit_depth FOXIT_png_get_bit_depth
+#define png_get_color_type FOXIT_png_get_color_type
+#define png_get_filter_type FOXIT_png_get_filter_type
+#define png_get_interlace_type FOXIT_png_get_interlace_type
+#define png_get_compression_type FOXIT_png_get_compression_type
+#define png_get_pixels_per_meter FOXIT_png_get_pixels_per_meter
+#define png_get_x_pixels_per_meter FOXIT_png_get_x_pixels_per_meter
+#define png_get_y_pixels_per_meter FOXIT_png_get_y_pixels_per_meter
+#define png_get_pixel_aspect_ratio FOXIT_png_get_pixel_aspect_ratio
+#define png_get_pixel_aspect_ratio_fixed FOXIT_png_get_pixel_aspect_ratio_fixed
+#define png_get_x_offset_pixels FOXIT_png_get_x_offset_pixels
+#define png_get_y_offset_pixels FOXIT_png_get_y_offset_pixels
+#define png_get_x_offset_microns FOXIT_png_get_x_offset_microns
+#define png_get_y_offset_microns FOXIT_png_get_y_offset_microns
+#define png_get_signature FOXIT_png_get_signature
+#define png_get_bKGD FOXIT_png_get_bKGD
+#define png_set_bKGD FOXIT_png_set_bKGD
+#define png_get_cHRM FOXIT_png_get_cHRM
+#define png_get_cHRM_XYZ FOXIT_png_get_cHRM_XYZ
+#define png_get_cHRM_fixed FOXIT_png_get_cHRM_fixed
+#define png_get_cHRM_XYZ_fixed FOXIT_png_get_cHRM_XYZ_fixed
+#define png_set_cHRM FOXIT_png_set_cHRM
+#define png_set_cHRM_XYZ FOXIT_png_set_cHRM_XYZ
+#define png_set_cHRM_fixed FOXIT_png_set_cHRM_fixed
+#define png_set_cHRM_XYZ_fixed FOXIT_png_set_cHRM_XYZ_fixed
+#define png_get_gAMA FOXIT_png_get_gAMA
+#define png_set_gAMA FOXIT_png_set_gAMA
+#define png_set_gAMA_fixed FOXIT_png_set_gAMA_fixed
+#define png_get_hIST FOXIT_png_get_hIST
+#define png_set_hIST FOXIT_png_set_hIST
+#define png_get_IHDR FOXIT_png_get_IHDR
+#define png_set_IHDR FOXIT_png_set_IHDR
+#define png_get_oFFs FOXIT_png_get_oFFs
+#define png_set_oFFs FOXIT_png_set_oFFs
+#define png_get_pCAL FOXIT_png_get_pCAL
+#define png_set_pCAL FOXIT_png_set_pCAL
+#define png_set_pHYs FOXIT_png_set_pHYs
+#define png_get_PLTE FOXIT_png_get_PLTE
+#define png_set_PLTE FOXIT_png_set_PLTE
+#define png_get_sBIT FOXIT_png_get_sBIT
+#define png_set_sBIT FOXIT_png_set_sBIT
+#define png_get_sRGB FOXIT_png_get_sRGB
+#define png_set_sRGB FOXIT_png_set_sRGB
+#define png_set_sRGB_gAMA_and_cHRM FOXIT_png_set_sRGB_gAMA_and_cHRM
+#define png_get_iCCP FOXIT_png_get_iCCP
+#define png_set_iCCP FOXIT_png_set_iCCP
+#define png_get_sPLT FOXIT_png_get_sPLT
+#define png_set_sPLT FOXIT_png_set_sPLT
+#define png_get_text FOXIT_png_get_text
+#define png_set_text FOXIT_png_set_text
+#define png_get_tIME FOXIT_png_get_tIME
+#define png_set_tIME FOXIT_png_set_tIME
+#define png_get_tRNS FOXIT_png_get_tRNS
+#define png_set_tRNS FOXIT_png_set_tRNS
+#define png_get_sCAL FOXIT_png_get_sCAL
+#define png_get_sCAL_fixed FOXIT_png_get_sCAL_fixed
+#define png_get_sCAL_s FOXIT_png_get_sCAL_s
+#define png_set_sCAL FOXIT_png_set_sCAL
+#define png_set_sCAL_s FOXIT_png_set_sCAL_s
+#define png_set_keep_unknown_chunks FOXIT_png_set_keep_unknown_chunks
+#define png_set_unknown_chunks FOXIT_png_set_unknown_chunks
+#define png_set_unknown_chunk_location FOXIT_png_set_unknown_chunk_location
+#define png_get_unknown_chunks FOXIT_png_get_unknown_chunks
+#define png_set_invalid FOXIT_png_set_invalid
+#define png_read_png FOXIT_png_read_png
+#define png_write_png FOXIT_png_write_png
+#define png_permit_mng_features FOXIT_png_permit_mng_features
+#define png_set_strip_error_numbers FOXIT_png_set_strip_error_numbers
+#define png_set_user_limits FOXIT_png_set_user_limits
+#define png_get_user_width_max FOXIT_png_get_user_width_max
+#define png_get_user_height_max FOXIT_png_get_user_height_max
+#define png_set_chunk_cache_max FOXIT_png_set_chunk_cache_max
+#define png_get_chunk_cache_max FOXIT_png_get_chunk_cache_max
+#define png_set_chunk_malloc_max FOXIT_png_set_chunk_malloc_max
+#define png_get_chunk_malloc_max FOXIT_png_get_chunk_malloc_max
+#define png_get_pixels_per_inch FOXIT_png_get_pixels_per_inch
+#define png_get_x_pixels_per_inch FOXIT_png_get_x_pixels_per_inch
+#define png_get_y_pixels_per_inch FOXIT_png_get_y_pixels_per_inch
+#define png_get_x_offset_inches FOXIT_png_get_x_offset_inches
+#define png_get_x_offset_inches_fixed FOXIT_png_get_x_offset_inches_fixed
+#define png_get_y_offset_inches FOXIT_png_get_y_offset_inches
+#define png_get_y_offset_inches_fixed FOXIT_png_get_y_offset_inches_fixed
+#define png_get_pHYs_dpi FOXIT_png_get_pHYs_dpi
+#define png_get_io_state FOXIT_png_get_io_state
+#define png_get_io_chunk_name FOXIT_png_get_io_chunk_name
+#define png_get_io_chunk_type FOXIT_png_get_io_chunk_type
+#define png_get_uint_31 FOXIT_png_get_uint_31
+#define png_save_uint_32 FOXIT_png_save_uint_32
+#define png_save_int_32 FOXIT_png_save_int_32
+#define png_save_uint_16 FOXIT_png_save_uint_16
+#define png_image_begin_read_from_file FOXIT_png_image_begin_read_from_file
+#define png_image_begin_read_from_stdio FOXIT_png_image_begin_read_from_stdio
+#define png_image_begin_read_from_memory FOXIT_png_image_begin_read_from_memory
+#define png_image_finish_read FOXIT_png_image_finish_read
+#define png_image_free FOXIT_png_image_free
+#define png_image_write_to_file FOXIT_png_image_write_to_file
+#define png_image_write_to_stdio FOXIT_png_image_write_to_stdio
+#define png_set_check_for_invalid_index FOXIT_png_set_check_for_invalid_index
+#define png_get_palette_max FOXIT_png_get_palette_max
+#define png_set_option FOXIT_png_set_option
+
+#define png_set_strip_16 FOXIT_png_set_strip_16
+#define png_64bit_product FOXIT_png_64bit_product
+#define png_check_cHRM_fixed FOXIT_png_check_cHRM_fixed
+#define png_free FOXIT_png_free
+#define png_free_default FOXIT_png_free_default
+#define png_get_mem_ptr FOXIT_png_get_mem_ptr
+#define png_malloc FOXIT_png_malloc
+#define png_malloc_default FOXIT_png_malloc_default
+#define png_malloc_warn FOXIT_png_malloc_warn
+#define png_memcpy_check FOXIT_png_memcpy_check
+#define png_memset_check FOXIT_png_memset_check
+#define png_pass_dsp_mask FOXIT_png_pass_dsp_mask
+#define png_pass_inc FOXIT_png_pass_inc
+#define png_pass_mask FOXIT_png_pass_mask
+#define png_pass_start FOXIT_png_pass_start
+#define png_pass_yinc FOXIT_png_pass_yinc
+#define png_pass_ystart FOXIT_png_pass_ystart
+#define png_set_mem_fn FOXIT_png_set_mem_fn
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.6.3"
+#define PNG_HEADER_VERSION_STRING \
+ " libpng version 1.6.3 - July 18, 2013\n"
+
+#define PNG_LIBPNG_VER_SONUM 16
+#define PNG_LIBPNG_VER_DLLNUM 16
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR 1
+#define PNG_LIBPNG_VER_MINOR 6
+#define PNG_LIBPNG_VER_RELEASE 3
+
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero:
+ */
+
+#define PNG_LIBPNG_VER_BUILD 0
+
+/* Release Status */
+#define PNG_LIBPNG_BUILD_ALPHA 1
+#define PNG_LIBPNG_BUILD_BETA 2
+#define PNG_LIBPNG_BUILD_RC 3
+#define PNG_LIBPNG_BUILD_STABLE 4
+#define PNG_LIBPNG_BUILD_RELEASE_STATUS_MASK 7
+
+/* Release-Specific Flags */
+#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with
+ PNG_LIBPNG_BUILD_STABLE only */
+#define PNG_LIBPNG_BUILD_PRIVATE 16 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_SPECIAL */
+#define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with
+ PNG_LIBPNG_BUILD_PRIVATE */
+
+#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE
+
+/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000). From
+ * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
+ */
+#define PNG_LIBPNG_VER 10603 /* 1.6.3 */
+
+/* Library configuration: these options cannot be changed after
+ * the library has been built.
+ */
+#ifndef PNGLCONF_H
+ /* If pnglibconf.h is missing, you can
+ * copy scripts/pnglibconf.h.prebuilt to pnglibconf.h
+ */
+# include "pnglibconf.h"
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+ /* Machine specific configuration. */
+# include "pngconf.h"
+#endif
+
+/*
+ * Added at libpng-1.2.8
+ *
+ * Ref MSDN: Private as priority over Special
+ * VS_FF_PRIVATEBUILD File *was not* built using standard release
+ * procedures. If this value is given, the StringFileInfo block must
+ * contain a PrivateBuild string.
+ *
+ * VS_FF_SPECIALBUILD File *was* built by the original company using
+ * standard release procedures but is a variation of the standard
+ * file of the same version number. If this value is given, the
+ * StringFileInfo block must contain a SpecialBuild string.
+ */
+
+#ifdef PNG_USER_PRIVATEBUILD /* From pnglibconf.h */
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_PRIVATE)
+#else
+# ifdef PNG_LIBPNG_SPECIALBUILD
+# define PNG_LIBPNG_BUILD_TYPE \
+ (PNG_LIBPNG_BUILD_BASE_TYPE | PNG_LIBPNG_BUILD_SPECIAL)
+# else
+# define PNG_LIBPNG_BUILD_TYPE (PNG_LIBPNG_BUILD_BASE_TYPE)
+# endif
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Version information for C files, stored in png.c. This had better match
+ * the version above.
+ */
+#define png_libpng_ver png_get_header_ver(NULL)
+
+/* This file is arranged in several sections:
+ *
+ * 1. Any configuration options that can be specified by for the application
+ * code when it is built. (Build time configuration is in pnglibconf.h)
+ * 2. Type definitions (base types are defined in pngconf.h), structure
+ * definitions.
+ * 3. Exported library functions.
+ * 4. Simplified API.
+ *
+ * The library source code has additional files (principally pngpriv.h) that
+ * allow configuration of the library.
+ */
+/* Section 1: run time configuration
+ * See pnglibconf.h for build time configuration
+ *
+ * Run time configuration allows the application to choose between
+ * implementations of certain arithmetic APIs. The default is set
+ * at build time and recorded in pnglibconf.h, but it is safe to
+ * override these (and only these) settings. Note that this won't
+ * change what the library does, only application code, and the
+ * settings can (and probably should) be made on a per-file basis
+ * by setting the #defines before including png.h
+ *
+ * Use macros to read integers from PNG data or use the exported
+ * functions?
+ * PNG_USE_READ_MACROS: use the macros (see below) Note that
+ * the macros evaluate their argument multiple times.
+ * PNG_NO_USE_READ_MACROS: call the relevant library function.
+ *
+ * Use the alternative algorithm for compositing alpha samples that
+ * does not use division?
+ * PNG_READ_COMPOSITE_NODIV_SUPPORTED: use the 'no division'
+ * algorithm.
+ * PNG_NO_READ_COMPOSITE_NODIV: use the 'division' algorithm.
+ *
+ * How to handle benign errors if PNG_ALLOW_BENIGN_ERRORS is
+ * false?
+ * PNG_ALLOW_BENIGN_ERRORS: map calls to the benign error
+ * APIs to png_warning.
+ * Otherwise the calls are mapped to png_error.
+ */
+
+/* Section 2: type definitions, including structures and compile time
+ * constants.
+ * See pngconf.h for base types that vary by machine/system
+ */
+
+/* This triggers a compiler error in png.c, if png.c and png.h
+ * do not agree upon the version number.
+ */
+typedef char* png_libpng_version_1_6_3;
+
+/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
+ *
+ * png_struct is the cache of information used while reading or writing a single
+ * PNG file. One of these is always required, although the simplified API
+ * (below) hides the creation and destruction of it.
+ */
+typedef struct png_struct_def png_struct;
+typedef const png_struct * png_const_structp;
+typedef png_struct * png_structp;
+typedef png_struct * * png_structpp;
+
+/* png_info contains information read from or to be written to a PNG file. One
+ * or more of these must exist while reading or creating a PNG file. The
+ * information is not used by libpng during read but is used to control what
+ * gets written when a PNG file is created. "png_get_" function calls read
+ * information during read and "png_set_" functions calls write information
+ * when creating a PNG.
+ * been moved into a separate header file that is not accessible to
+ * applications. Read libpng-manual.txt or libpng.3 for more info.
+ */
+typedef struct png_info_def png_info;
+typedef png_info * png_infop;
+typedef const png_info * png_const_infop;
+typedef png_info * * png_infopp;
+
+/* Types with names ending 'p' are pointer types. The corresponding types with
+ * names ending 'rp' are identical pointer types except that the pointer is
+ * marked 'restrict', which means that it is the only pointer to the object
+ * passed to the function. Applications should not use the 'restrict' types;
+ * it is always valid to pass 'p' to a pointer with a function argument of the
+ * corresponding 'rp' type. Different compilers have different rules with
+ * regard to type matching in the presence of 'restrict'. For backward
+ * compatibility libpng callbacks never have 'restrict' in their parameters and,
+ * consequentially, writing portable application code is extremely difficult if
+ * an attempt is made to use 'restrict'.
+ */
+typedef png_struct * PNG_RESTRICT png_structrp;
+typedef const png_struct * PNG_RESTRICT png_const_structrp;
+typedef png_info * PNG_RESTRICT png_inforp;
+typedef const png_info * PNG_RESTRICT png_const_inforp;
+
+/* Three color definitions. The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+ png_byte red;
+ png_byte green;
+ png_byte blue;
+} png_color;
+typedef png_color * png_colorp;
+typedef const png_color * png_const_colorp;
+typedef png_color * * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+ png_byte index; /* used for palette files */
+ png_uint_16 red; /* for use in red green blue files */
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 gray; /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 * png_color_16p;
+typedef const png_color_16 * png_const_color_16p;
+typedef png_color_16 * * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+ png_byte red; /* for use in red green blue files */
+ png_byte green;
+ png_byte blue;
+ png_byte gray; /* for use in grayscale files */
+ png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 * png_color_8p;
+typedef const png_color_8 * png_const_color_8p;
+typedef png_color_8 * * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+ png_uint_16 red;
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 alpha;
+ png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry * png_sPLT_entryp;
+typedef const png_sPLT_entry * png_const_sPLT_entryp;
+typedef png_sPLT_entry * * png_sPLT_entrypp;
+
+/* When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ * occupy the LSB of their respective members, and the MSB of each member
+ * is zero-filled. The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+ png_charp name; /* palette name */
+ png_byte depth; /* depth of palette samples */
+ png_sPLT_entryp entries; /* palette entries */
+ png_int_32 nentries; /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t * png_sPLT_tp;
+typedef const png_sPLT_t * png_const_sPLT_tp;
+typedef png_sPLT_t * * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not. The "key" field
+ * points to a regular zero-terminated C string. The "text" fields can be a
+ * regular C string, an empty string, or a NULL pointer.
+ * However, the structure returned by png_get_text() will always contain
+ * the "text" field as a regular zero-terminated C string (possibly
+ * empty), never a NULL pointer, so it can be safely used in printf() and
+ * other string-handling functions. Note that the "itxt_length", "lang", and
+ * "lang_key" members of the structure only exist when the library is built
+ * with iTXt chunk support. Prior to libpng-1.4.0 the library was built by
+ * default without iTXt support. Also note that when iTXt *is* supported,
+ * the "lang" and "lang_key" fields contain NULL pointers when the
+ * "compression" field contains * PNG_TEXT_COMPRESSION_NONE or
+ * PNG_TEXT_COMPRESSION_zTXt. Note that the "compression value" is not the
+ * same as what appears in the PNG tEXt/zTXt/iTXt chunk's "compression flag"
+ * which is always 0 or 1, or its "compression method" which is always 0.
+ */
+typedef struct png_text_struct
+{
+ int compression; /* compression value:
+ -1: tEXt, none
+ 0: zTXt, deflate
+ 1: iTXt, none
+ 2: iTXt, deflate */
+ png_charp key; /* keyword, 1-79 character description of "text" */
+ png_charp text; /* comment, may be an empty string (ie "")
+ or a NULL pointer */
+ png_size_t text_length; /* length of the text string */
+ png_size_t itxt_length; /* length of the itxt string */
+ png_charp lang; /* language code, 0-79 characters
+ or a NULL pointer */
+ png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
+ chars or a NULL pointer */
+} png_text;
+typedef png_text * png_textp;
+typedef const png_text * png_const_textp;
+typedef png_text * * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE -1
+#define PNG_TEXT_COMPRESSION_zTXt 0
+#define PNG_ITXT_COMPRESSION_NONE 1
+#define PNG_ITXT_COMPRESSION_zTXt 2
+#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm. There
+ * is no portable way to convert to either of these structures, as far
+ * as I know. If you know of a portable way, send it to me. As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+ png_uint_16 year; /* full year, as in, 1995 */
+ png_byte month; /* month of year, 1 - 12 */
+ png_byte day; /* day of month, 1 - 31 */
+ png_byte hour; /* hour of day, 0 - 23 */
+ png_byte minute; /* minute of hour, 0 - 59 */
+ png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time * png_timep;
+typedef const png_time * png_const_timep;
+typedef png_time * * png_timepp;
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support. The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ *
+ * The data in the structure is set by libpng on read and used on write.
+ */
+typedef struct png_unknown_chunk_t
+{
+ png_byte name[5]; /* Textual chunk name with '\0' terminator */
+ png_byte *data; /* Data, should not be modified on read! */
+ png_size_t size;
+
+ /* On write 'location' must be set using the flag values listed below.
+ * Notice that on read it is set by libpng however the values stored have
+ * more bits set than are listed below. Always treat the value as a
+ * bitmask. On write set only one bit - setting multiple bits may cause the
+ * chunk to be written in multiple places.
+ */
+ png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+
+typedef png_unknown_chunk * png_unknown_chunkp;
+typedef const png_unknown_chunk * png_const_unknown_chunkp;
+typedef png_unknown_chunk * * png_unknown_chunkpp;
+#endif
+
+/* Flag values for the unknown chunk location byte. */
+#define PNG_HAVE_IHDR 0x01
+#define PNG_HAVE_PLTE 0x02
+#define PNG_AFTER_IDAT 0x08
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX ((png_uint_32)(-1))
+#define PNG_SIZE_MAX ((png_size_t)(-1))
+
+/* These are constants for fixed point values encoded in the
+ * PNG specification manner (x100000)
+ */
+#define PNG_FP_1 100000
+#define PNG_FP_HALF 50000
+#define PNG_FP_MAX ((png_fixed_point)0x7fffffffL)
+#define PNG_FP_MIN (-PNG_FP_MAX)
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE 1
+#define PNG_COLOR_MASK_COLOR 2
+#define PNG_COLOR_MASK_ALPHA 4
+
+/* color types. Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type. These values should NOT be changed. */
+#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST 2 /* Not a valid value */
+
+/* These are for the oFFs chunk. These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST 2 /* Not a valid value */
+
+/* These are for the pCAL chunk. These values should NOT be changed. */
+#define PNG_EQUATION_LINEAR 0 /* Linear transformation */
+#define PNG_EQUATION_BASE_E 1 /* Exponential base e transform */
+#define PNG_EQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
+#define PNG_EQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
+#define PNG_EQUATION_LAST 4 /* Not a valid value */
+
+/* These are for the sCAL chunk. These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER 1 /* meters per pixel */
+#define PNG_SCALE_RADIAN 2 /* radians per pixel */
+#define PNG_SCALE_LAST 3 /* Not a valid value */
+
+/* These are for the pHYs chunk. These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER 1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST 2 /* Not a valid value */
+
+/* These are for the sRGB chunk. These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE 1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE 3
+#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH 79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH 256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file. The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000 /* ESR, 1.0.6 */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row. It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+ png_uint_32 width; /* width of row */
+ png_size_t rowbytes; /* number of bytes in row */
+ png_byte color_type; /* color type of row */
+ png_byte bit_depth; /* bit depth of row */
+ png_byte channels; /* number of channels (1, 2, 3, or 4) */
+ png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info * png_row_infop;
+typedef png_row_info * * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own. The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions. Note that the 'write' function must not
+ * modify the buffer it is passed. The 'read' function, on the other hand, is
+ * expected to return the read data in the buffer.
+ */
+typedef PNG_CALLBACK(void, *png_error_ptr, (png_structp, png_const_charp));
+typedef PNG_CALLBACK(void, *png_rw_ptr, (png_structp, png_bytep, png_size_t));
+typedef PNG_CALLBACK(void, *png_flush_ptr, (png_structp));
+typedef PNG_CALLBACK(void, *png_read_status_ptr, (png_structp, png_uint_32,
+ int));
+typedef PNG_CALLBACK(void, *png_write_status_ptr, (png_structp, png_uint_32,
+ int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef PNG_CALLBACK(void, *png_progressive_info_ptr, (png_structp, png_infop));
+typedef PNG_CALLBACK(void, *png_progressive_end_ptr, (png_structp, png_infop));
+
+/* The following callback receives png_uint_32 row_number, int pass for the
+ * png_bytep data of the row. When transforming an interlaced image the
+ * row number is the row number within the sub-image of the interlace pass, so
+ * the value will increase to the height of the sub-image (not the full image)
+ * then reset to 0 for the next pass.
+ *
+ * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
+ * find the output pixel (x,y) given an interlaced sub-image pixel
+ * (row,col,pass). (See below for these macros.)
+ */
+typedef PNG_CALLBACK(void, *png_progressive_row_ptr, (png_structp, png_bytep,
+ png_uint_32, int));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+typedef PNG_CALLBACK(void, *png_user_transform_ptr, (png_structp, png_row_infop,
+ png_bytep));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+typedef PNG_CALLBACK(int, *png_user_chunk_ptr, (png_structp,
+ png_unknown_chunkp));
+#endif
+#ifdef PNG_UNKNOWN_CHUNKS_SUPPORTED
+/* not used anywhere */
+/* typedef PNG_CALLBACK(void, *png_unknown_chunk_ptr, (png_structp)); */
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This must match the function definition in <setjmp.h>, and the application
+ * must include this before png.h to obtain the definition of jmp_buf. The
+ * function is required to be PNG_NORETURN, but this is not checked. If the
+ * function does return the application will crash via an abort() or similar
+ * system level call.
+ *
+ * If you get a warning here while building the library you may need to make
+ * changes to ensure that pnglibconf.h records the calling convention used by
+ * your compiler. This may be very difficult - try using a different compiler
+ * to build the library!
+ */
+PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef);
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */
+#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */
+#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */
+#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */
+#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */
+#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */
+#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */
+#define PNG_TRANSFORM_BGR 0x0080 /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* write only */
+/* Added to libpng-1.2.34 */
+#define PNG_TRANSFORM_STRIP_FILLER_BEFORE PNG_TRANSFORM_STRIP_FILLER
+#define PNG_TRANSFORM_STRIP_FILLER_AFTER 0x1000 /* write only */
+/* Added to libpng-1.4.0 */
+#define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */
+/* Added to libpng-1.5.4 */
+#define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */
+#define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE 0x01
+#define PNG_FLAG_MNG_FILTER_64 0x04
+#define PNG_ALL_MNG_FEATURES 0x05
+
+/* NOTE: prior to 1.5 these functions had no 'API' style declaration,
+ * this allowed the zlib default functions to be used on Windows
+ * platforms. In 1.5 the zlib default malloc (which just calls malloc and
+ * ignores the first argument) should be completely compatible with the
+ * following.
+ */
+typedef PNG_CALLBACK(png_voidp, *png_malloc_ptr, (png_structp,
+ png_alloc_size_t));
+typedef PNG_CALLBACK(void, *png_free_ptr, (png_structp, png_voidp));
+
+/* Section 3: exported functions
+ * Here are the function definitions most commonly used. This is not
+ * the place to find out how to use libpng. See libpng-manual.txt for the
+ * full explanation, see example.c for the summary. This just provides
+ * a simple one line description of the use of each function.
+ *
+ * The PNG_EXPORT() and PNG_EXPORTA() macros used below are defined in
+ * pngconf.h and in the *.dfn files in the scripts directory.
+ *
+ * PNG_EXPORT(ordinal, type, name, (args));
+ *
+ * ordinal: ordinal that is used while building
+ * *.def files. The ordinal value is only
+ * relevant when preprocessing png.h with
+ * the *.dfn files for building symbol table
+ * entries, and are removed by pngconf.h.
+ * type: return type of the function
+ * name: function name
+ * args: function arguments, with types
+ *
+ * When we wish to append attributes to a function prototype we use
+ * the PNG_EXPORTA() macro instead.
+ *
+ * PNG_EXPORTA(ordinal, type, name, (args), attributes);
+ *
+ * ordinal, type, name, and args: same as in PNG_EXPORT().
+ * attributes: function attributes
+ */
+
+/* Returns the version number of the library */
+PNG_EXPORT(1, png_uint_32, png_access_version_number, (void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise. Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, png_size_t start,
+ png_size_t num_to_check));
+
+/* Simple signature checking function. This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n))
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+PNG_EXPORTA(4, png_structp, png_create_read_struct,
+ (png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn),
+ PNG_ALLOCATED);
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+PNG_EXPORTA(5, png_structp, png_create_write_struct,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn),
+ PNG_ALLOCATED);
+
+PNG_EXPORT(6, png_size_t, png_get_compression_buffer_size,
+ (png_const_structrp png_ptr));
+
+PNG_EXPORT(7, void, png_set_compression_buffer_size, (png_structrp png_ptr,
+ png_size_t size));
+
+/* Moved from pngconf.h in 1.4.0 and modified to ensure setjmp/longjmp
+ * match up.
+ */
+#ifdef PNG_SETJMP_SUPPORTED
+/* This function returns the jmp_buf built in to *png_ptr. It must be
+ * supplied with an appropriate 'longjmp' function to use on that jmp_buf
+ * unless the default error function is overridden in which case NULL is
+ * acceptable. The size of the jmp_buf is checked against the actual size
+ * allocated by the library - the call will return NULL on a mismatch
+ * indicating an ABI mismatch.
+ */
+PNG_EXPORT(8, jmp_buf*, png_set_longjmp_fn, (png_structrp png_ptr,
+ png_longjmp_ptr longjmp_fn, size_t jmp_buf_size));
+# define png_jmpbuf(png_ptr) \
+ (*png_set_longjmp_fn((png_ptr), longjmp, (sizeof (jmp_buf))))
+#else
+# define png_jmpbuf(png_ptr) \
+ (LIBPNG_WAS_COMPILED_WITH__PNG_NO_SETJMP)
+#endif
+/* This function should be used by libpng applications in place of
+ * longjmp(png_ptr->jmpbuf, val). If longjmp_fn() has been set, it
+ * will use it; otherwise it will call PNG_ABORT(). This function was
+ * added in libpng-1.5.0.
+ */
+PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),
+ PNG_NORETURN);
+
+#ifdef PNG_READ_SUPPORTED
+/* Reset the compression stream */
+PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);
+#endif
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_EXPORTA(11, png_structp, png_create_read_struct_2,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn,
+ png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+ PNG_ALLOCATED);
+PNG_EXPORTA(12, png_structp, png_create_write_struct_2,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn,
+ png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn),
+ PNG_ALLOCATED);
+#endif
+
+/* Write the PNG file signature. */
+PNG_EXPORT(13, void, png_write_sig, (png_structrp png_ptr));
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+PNG_EXPORT(14, void, png_write_chunk, (png_structrp png_ptr, png_const_bytep
+ chunk_name, png_const_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+PNG_EXPORT(15, void, png_write_chunk_start, (png_structrp png_ptr,
+ png_const_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+PNG_EXPORT(16, void, png_write_chunk_data, (png_structrp png_ptr,
+ png_const_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+PNG_EXPORT(17, void, png_write_chunk_end, (png_structrp png_ptr));
+
+/* Allocate and initialize the info structure */
+PNG_EXPORTA(18, png_infop, png_create_info_struct, (png_const_structrp png_ptr),
+ PNG_ALLOCATED);
+
+/* DEPRECATED: this function allowed init structures to be created using the
+ * default allocation method (typically malloc). Use is deprecated in 1.6.0 and
+ * the API will be removed in the future.
+ */
+PNG_EXPORTA(19, void, png_info_init_3, (png_infopp info_ptr,
+ png_size_t png_info_struct_size), PNG_DEPRECATED);
+
+/* Writes all the PNG information before the image. */
+PNG_EXPORT(20, void, png_write_info_before_PLTE,
+ (png_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(21, void, png_write_info,
+ (png_structrp png_ptr, png_const_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the information before the actual image data. */
+PNG_EXPORT(22, void, png_read_info,
+ (png_structrp png_ptr, png_inforp info_ptr));
+#endif
+
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ /* Convert to a US string format: there is no localization support in this
+ * routine. The original implementation used a 29 character buffer in
+ * png_struct, this will be removed in future versions.
+ */
+#if PNG_LIBPNG_VER < 10700
+/* To do: remove this from libpng17 (and from libpng17/png.c and pngstruct.h) */
+PNG_EXPORTA(23, png_const_charp, png_convert_to_rfc1123, (png_structrp png_ptr,
+ png_const_timep ptime),PNG_DEPRECATED);
+#endif
+PNG_EXPORT(241, int, png_convert_to_rfc1123_buffer, (char out[29],
+ png_const_timep ptime));
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+/* Convert from a struct tm to png_time */
+PNG_EXPORT(24, void, png_convert_from_struct_tm, (png_timep ptime,
+ const struct tm * ttime));
+
+/* Convert from time_t to png_time. Uses gmtime() */
+PNG_EXPORT(25, void, png_convert_from_time_t, (png_timep ptime, time_t ttime));
+#endif /* PNG_CONVERT_tIME_SUPPORTED */
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+PNG_EXPORT(26, void, png_set_expand, (png_structrp png_ptr));
+PNG_EXPORT(27, void, png_set_expand_gray_1_2_4_to_8, (png_structrp png_ptr));
+PNG_EXPORT(28, void, png_set_palette_to_rgb, (png_structrp png_ptr));
+PNG_EXPORT(29, void, png_set_tRNS_to_alpha, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+/* Expand to 16-bit channels, forces conversion of palette to RGB and expansion
+ * of a tRNS chunk if present.
+ */
+PNG_EXPORT(221, void, png_set_expand_16, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+PNG_EXPORT(30, void, png_set_bgr, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+/* Expand the grayscale to 24-bit RGB if necessary. */
+PNG_EXPORT(31, void, png_set_gray_to_rgb, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+/* Reduce RGB to grayscale. */
+#define PNG_ERROR_ACTION_NONE 1
+#define PNG_ERROR_ACTION_WARN 2
+#define PNG_ERROR_ACTION_ERROR 3
+#define PNG_RGB_TO_GRAY_DEFAULT (-1)/*for red/green coefficients*/
+
+PNG_FP_EXPORT(32, void, png_set_rgb_to_gray, (png_structrp png_ptr,
+ int error_action, double red, double green))
+PNG_FIXED_EXPORT(33, void, png_set_rgb_to_gray_fixed, (png_structrp png_ptr,
+ int error_action, png_fixed_point red, png_fixed_point green))
+
+PNG_EXPORT(34, png_byte, png_get_rgb_to_gray_status, (png_const_structrp
+ png_ptr));
+#endif
+
+#ifdef PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+PNG_EXPORT(35, void, png_build_grayscale_palette, (int bit_depth,
+ png_colorp palette));
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+/* How the alpha channel is interpreted - this affects how the color channels of
+ * a PNG file are returned when an alpha channel, or tRNS chunk in a palette
+ * file, is present.
+ *
+ * This has no effect on the way pixels are written into a PNG output
+ * datastream. The color samples in a PNG datastream are never premultiplied
+ * with the alpha samples.
+ *
+ * The default is to return data according to the PNG specification: the alpha
+ * channel is a linear measure of the contribution of the pixel to the
+ * corresponding composited pixel. The gamma encoded color channels must be
+ * scaled according to the contribution and to do this it is necessary to undo
+ * the encoding, scale the color values, perform the composition and reencode
+ * the values. This is the 'PNG' mode.
+ *
+ * The alternative is to 'associate' the alpha with the color information by
+ * storing color channel values that have been scaled by the alpha. The
+ * advantage is that the color channels can be resampled (the image can be
+ * scaled) in this form. The disadvantage is that normal practice is to store
+ * linear, not (gamma) encoded, values and this requires 16-bit channels for
+ * still images rather than the 8-bit channels that are just about sufficient if
+ * gamma encoding is used. In addition all non-transparent pixel values,
+ * including completely opaque ones, must be gamma encoded to produce the final
+ * image. This is the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' mode (the
+ * latter being the two common names for associated alpha color channels.)
+ *
+ * Since it is not necessary to perform arithmetic on opaque color values so
+ * long as they are not to be resampled and are in the final color space it is
+ * possible to optimize the handling of alpha by storing the opaque pixels in
+ * the PNG format (adjusted for the output color space) while storing partially
+ * opaque pixels in the standard, linear, format. The accuracy required for
+ * standard alpha composition is relatively low, because the pixels are
+ * isolated, therefore typically the accuracy loss in storing 8-bit linear
+ * values is acceptable. (This is not true if the alpha channel is used to
+ * simulate transparency over large areas - use 16 bits or the PNG mode in
+ * this case!) This is the 'OPTIMIZED' mode. For this mode a pixel is
+ * treated as opaque only if the alpha value is equal to the maximum value.
+ *
+ * The final choice is to gamma encode the alpha channel as well. This is
+ * broken because, in practice, no implementation that uses this choice
+ * correctly undoes the encoding before handling alpha composition. Use this
+ * choice only if other serious errors in the software or hardware you use
+ * mandate it; the typical serious error is for dark halos to appear around
+ * opaque areas of the composited PNG image because of arithmetic overflow.
+ *
+ * The API function png_set_alpha_mode specifies which of these choices to use
+ * with an enumerated 'mode' value and the gamma of the required output:
+ */
+#define PNG_ALPHA_PNG 0 /* according to the PNG standard */
+#define PNG_ALPHA_STANDARD 1 /* according to Porter/Duff */
+#define PNG_ALPHA_ASSOCIATED 1 /* as above; this is the normal practice */
+#define PNG_ALPHA_PREMULTIPLIED 1 /* as above */
+#define PNG_ALPHA_OPTIMIZED 2 /* 'PNG' for opaque pixels, else 'STANDARD' */
+#define PNG_ALPHA_BROKEN 3 /* the alpha channel is gamma encoded */
+
+PNG_FP_EXPORT(227, void, png_set_alpha_mode, (png_structrp png_ptr, int mode,
+ double output_gamma))
+PNG_FIXED_EXPORT(228, void, png_set_alpha_mode_fixed, (png_structrp png_ptr,
+ int mode, png_fixed_point output_gamma))
+#endif
+
+#if defined(PNG_GAMMA_SUPPORTED) || defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+/* The output_gamma value is a screen gamma in libpng terminology: it expresses
+ * how to decode the output values, not how they are encoded. The values used
+ * correspond to the normal numbers used to describe the overall gamma of a
+ * computer display system; for example 2.2 for an sRGB conformant system. The
+ * values are scaled by 100000 in the _fixed version of the API (so 220000 for
+ * sRGB.)
+ *
+ * The inverse of the value is always used to provide a default for the PNG file
+ * encoding if it has no gAMA chunk and if png_set_gamma() has not been called
+ * to override the PNG gamma information.
+ *
+ * When the ALPHA_OPTIMIZED mode is selected the output gamma is used to encode
+ * opaque pixels however pixels with lower alpha values are not encoded,
+ * regardless of the output gamma setting.
+ *
+ * When the standard Porter Duff handling is requested with mode 1 the output
+ * encoding is set to be linear and the output_gamma value is only relevant
+ * as a default for input data that has no gamma information. The linear output
+ * encoding will be overridden if png_set_gamma() is called - the results may be
+ * highly unexpected!
+ *
+ * The following numbers are derived from the sRGB standard and the research
+ * behind it. sRGB is defined to be approximated by a PNG gAMA chunk value of
+ * 0.45455 (1/2.2) for PNG. The value implicitly includes any viewing
+ * correction required to take account of any differences in the color
+ * environment of the original scene and the intended display environment; the
+ * value expresses how to *decode* the image for display, not how the original
+ * data was *encoded*.
+ *
+ * sRGB provides a peg for the PNG standard by defining a viewing environment.
+ * sRGB itself, and earlier TV standards, actually use a more complex transform
+ * (a linear portion then a gamma 2.4 power law) than PNG can express. (PNG is
+ * limited to simple power laws.) By saying that an image for direct display on
+ * an sRGB conformant system should be stored with a gAMA chunk value of 45455
+ * (11.3.3.2 and 11.3.3.5 of the ISO PNG specification) the PNG specification
+ * makes it possible to derive values for other display systems and
+ * environments.
+ *
+ * The Mac value is deduced from the sRGB based on an assumption that the actual
+ * extra viewing correction used in early Mac display systems was implemented as
+ * a power 1.45 lookup table.
+ *
+ * Any system where a programmable lookup table is used or where the behavior of
+ * the final display device characteristics can be changed requires system
+ * specific code to obtain the current characteristic. However this can be
+ * difficult and most PNG gamma correction only requires an approximate value.
+ *
+ * By default, if png_set_alpha_mode() is not called, libpng assumes that all
+ * values are unencoded, linear, values and that the output device also has a
+ * linear characteristic. This is only very rarely correct - it is invariably
+ * better to call png_set_alpha_mode() with PNG_DEFAULT_sRGB than rely on the
+ * default if you don't know what the right answer is!
+ *
+ * The special value PNG_GAMMA_MAC_18 indicates an older Mac system (pre Mac OS
+ * 10.6) which used a correction table to implement a somewhat lower gamma on an
+ * otherwise sRGB system.
+ *
+ * Both these values are reserved (not simple gamma values) in order to allow
+ * more precise correction internally in the future.
+ *
+ * NOTE: the following values can be passed to either the fixed or floating
+ * point APIs, but the floating point API will also accept floating point
+ * values.
+ */
+#define PNG_DEFAULT_sRGB -1 /* sRGB gamma and color space */
+#define PNG_GAMMA_MAC_18 -2 /* Old Mac '1.8' gamma and color space */
+#define PNG_GAMMA_sRGB 220000 /* Television standards--matches sRGB gamma */
+#define PNG_GAMMA_LINEAR PNG_FP_1 /* Linear */
+#endif
+
+/* The following are examples of calls to png_set_alpha_mode to achieve the
+ * required overall gamma correction and, where necessary, alpha
+ * premultiplication.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ * This is the default libpng handling of the alpha channel - it is not
+ * pre-multiplied into the color components. In addition the call states
+ * that the output is for a sRGB system and causes all PNG files without gAMA
+ * chunks to be assumed to be encoded using sRGB.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+ * In this case the output is assumed to be something like an sRGB conformant
+ * display preceeded by a power-law lookup table of power 1.45. This is how
+ * early Mac systems behaved.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);
+ * This is the classic Jim Blinn approach and will work in academic
+ * environments where everything is done by the book. It has the shortcoming
+ * of assuming that input PNG data with no gamma information is linear - this
+ * is unlikely to be correct unless the PNG files where generated locally.
+ * Most of the time the output precision will be so low as to show
+ * significant banding in dark areas of the image.
+ *
+ * png_set_expand_16(pp);
+ * png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);
+ * This is a somewhat more realistic Jim Blinn inspired approach. PNG files
+ * are assumed to have the sRGB encoding if not marked with a gamma value and
+ * the output is always 16 bits per component. This permits accurate scaling
+ * and processing of the data. If you know that your input PNG files were
+ * generated locally you might need to replace PNG_DEFAULT_sRGB with the
+ * correct value for your system.
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);
+ * If you just need to composite the PNG image onto an existing background
+ * and if you control the code that does this you can use the optimization
+ * setting. In this case you just copy completely opaque pixels to the
+ * output. For pixels that are not completely transparent (you just skip
+ * those) you do the composition math using png_composite or png_composite_16
+ * below then encode the resultant 8-bit or 16-bit values to match the output
+ * encoding.
+ *
+ * Other cases
+ * If neither the PNG nor the standard linear encoding work for you because
+ * of the software or hardware you use then you have a big problem. The PNG
+ * case will probably result in halos around the image. The linear encoding
+ * will probably result in a washed out, too bright, image (it's actually too
+ * contrasty.) Try the ALPHA_OPTIMIZED mode above - this will probably
+ * substantially reduce the halos. Alternatively try:
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);
+ * This option will also reduce the halos, but there will be slight dark
+ * halos round the opaque parts of the image where the background is light.
+ * In the OPTIMIZED mode the halos will be light halos where the background
+ * is dark. Take your pick - the halos are unavoidable unless you can get
+ * your hardware/software fixed! (The OPTIMIZED approach is slightly
+ * faster.)
+ *
+ * When the default gamma of PNG files doesn't match the output gamma.
+ * If you have PNG files with no gamma information png_set_alpha_mode allows
+ * you to provide a default gamma, but it also sets the ouput gamma to the
+ * matching value. If you know your PNG files have a gamma that doesn't
+ * match the output you can take advantage of the fact that
+ * png_set_alpha_mode always sets the output gamma but only sets the PNG
+ * default if it is not already set:
+ *
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
+ * png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);
+ * The first call sets both the default and the output gamma values, the
+ * second call overrides the output gamma without changing the default. This
+ * is easier than achieving the same effect with png_set_gamma. You must use
+ * PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
+ * fire if more than one call to png_set_alpha_mode and png_set_background is
+ * made in the same read operation, however multiple calls with PNG_ALPHA_PNG
+ * are ignored.
+ */
+
+#ifdef PNG_READ_STRIP_ALPHA_SUPPORTED
+PNG_EXPORT(36, void, png_set_strip_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+PNG_EXPORT(37, void, png_set_swap_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+PNG_EXPORT(38, void, png_set_invert_alpha, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 8-bit Gray or 24-bit RGB images. */
+PNG_EXPORT(39, void, png_set_filler, (png_structrp png_ptr, png_uint_32 filler,
+ int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+# define PNG_FILLER_BEFORE 0
+# define PNG_FILLER_AFTER 1
+/* Add an alpha byte to 8-bit Gray or 24-bit RGB images. */
+PNG_EXPORT(40, void, png_set_add_alpha, (png_structrp png_ptr,
+ png_uint_32 filler, int flags));
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+PNG_EXPORT(41, void, png_set_swap, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+PNG_EXPORT(42, void, png_set_packing, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+ defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+PNG_EXPORT(43, void, png_set_packswap, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+PNG_EXPORT(44, void, png_set_shift, (png_structrp png_ptr, png_const_color_8p
+ true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing. Returns the number of passes.
+ * MUST be called before png_read_update_info or png_start_read_image,
+ * otherwise it will not have the desired effect. Note that it is still
+ * necessary to call png_read_row or png_read_rows png_get_image_height
+ * times for each pass.
+*/
+PNG_EXPORT(45, int, png_set_interlace_handling, (png_structrp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+PNG_EXPORT(46, void, png_set_invert_mono, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+/* Handle alpha and tRNS by replacing with a background color. Prior to
+ * libpng-1.5.4 this API must not be called before the PNG file header has been
+ * read. Doing so will result in unexpected behavior and possible warnings or
+ * errors if the PNG file contains a bKGD chunk.
+ */
+PNG_FP_EXPORT(47, void, png_set_background, (png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma))
+PNG_FIXED_EXPORT(215, void, png_set_background_fixed, (png_structrp png_ptr,
+ png_const_color_16p background_color, int background_gamma_code,
+ int need_expand, png_fixed_point background_gamma))
+#endif
+#ifdef PNG_READ_BACKGROUND_SUPPORTED
+# define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+# define PNG_BACKGROUND_GAMMA_SCREEN 1
+# define PNG_BACKGROUND_GAMMA_FILE 2
+# define PNG_BACKGROUND_GAMMA_UNIQUE 3
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+/* Scale a 16-bit depth file down to 8-bit, accurately. */
+PNG_EXPORT(229, void, png_set_scale_16, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+#define PNG_READ_16_TO_8 SUPPORTED /* Name prior to 1.5.4 */
+/* Strip the second byte of information from a 16-bit depth file. */
+PNG_EXPORT(48, void, png_set_strip_16, (png_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* Turn on quantizing, and reduce the palette to the number of colors
+ * available.
+ */
+PNG_EXPORT(49, void, png_set_quantize, (png_structrp png_ptr,
+ png_colorp palette, int num_palette, int maximum_colors,
+ png_const_uint_16p histogram, int full_quantize));
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* The threshold on gamma processing is configurable but hard-wired into the
+ * library. The following is the floating point variant.
+ */
+#define PNG_GAMMA_THRESHOLD (PNG_GAMMA_THRESHOLD_FIXED*.00001)
+
+/* Handle gamma correction. Screen_gamma=(display_exponent).
+ * NOTE: this API simply sets the screen and file gamma values. It will
+ * therefore override the value for gamma in a PNG file if it is called after
+ * the file header has been read - use with care - call before reading the PNG
+ * file for best results!
+ *
+ * These routines accept the same gamma values as png_set_alpha_mode (described
+ * above). The PNG_GAMMA_ defines and PNG_DEFAULT_sRGB can be passed to either
+ * API (floating point or fixed.) Notice, however, that the 'file_gamma' value
+ * is the inverse of a 'screen gamma' value.
+ */
+PNG_FP_EXPORT(50, void, png_set_gamma, (png_structrp png_ptr,
+ double screen_gamma, double override_file_gamma))
+PNG_FIXED_EXPORT(208, void, png_set_gamma_fixed, (png_structrp png_ptr,
+ png_fixed_point screen_gamma, png_fixed_point override_file_gamma))
+#endif
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+/* Set how many lines between output flushes - 0 for no flushing */
+PNG_EXPORT(51, void, png_set_flush, (png_structrp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+PNG_EXPORT(52, void, png_write_flush, (png_structrp png_ptr));
+#endif
+
+/* Optional update palette with requested transformations */
+PNG_EXPORT(53, void, png_start_read_image, (png_structrp png_ptr));
+
+/* Optional call to update the users info structure */
+PNG_EXPORT(54, void, png_read_update_info, (png_structrp png_ptr,
+ png_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read one or more rows of image data. */
+PNG_EXPORT(55, void, png_read_rows, (png_structrp png_ptr, png_bytepp row,
+ png_bytepp display_row, png_uint_32 num_rows));
+#endif
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read a row of data. */
+PNG_EXPORT(56, void, png_read_row, (png_structrp png_ptr, png_bytep row,
+ png_bytep display_row));
+#endif
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the whole image into memory at once. */
+PNG_EXPORT(57, void, png_read_image, (png_structrp png_ptr, png_bytepp image));
+#endif
+
+/* Write a row of image data */
+PNG_EXPORT(58, void, png_write_row, (png_structrp png_ptr,
+ png_const_bytep row));
+
+/* Write a few rows of image data: (*row) is not written; however, the type
+ * is declared as writeable to maintain compatibility with previous versions
+ * of libpng and to allow the 'display_row' array from read_rows to be passed
+ * unchanged to write_rows.
+ */
+PNG_EXPORT(59, void, png_write_rows, (png_structrp png_ptr, png_bytepp row,
+ png_uint_32 num_rows));
+
+/* Write the image data */
+PNG_EXPORT(60, void, png_write_image, (png_structrp png_ptr, png_bytepp image));
+
+/* Write the end of the PNG file. */
+PNG_EXPORT(61, void, png_write_end, (png_structrp png_ptr,
+ png_inforp info_ptr));
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+/* Read the end of the PNG file. */
+PNG_EXPORT(62, void, png_read_end, (png_structrp png_ptr, png_inforp info_ptr));
+#endif
+
+/* Free any memory associated with the png_info_struct */
+PNG_EXPORT(63, void, png_destroy_info_struct, (png_const_structrp png_ptr,
+ png_infopp info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+PNG_EXPORT(64, void, png_destroy_read_struct, (png_structpp png_ptr_ptr,
+ png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* Free any memory associated with the png_struct and the png_info_structs */
+PNG_EXPORT(65, void, png_destroy_write_struct, (png_structpp png_ptr_ptr,
+ png_infopp info_ptr_ptr));
+
+/* Set the libpng method of handling chunk CRC errors */
+PNG_EXPORT(66, void, png_set_crc_action, (png_structrp png_ptr, int crit_action,
+ int ancil_action));
+
+/* Values for png_set_crc_action() say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein. Note that it is impossible to "discard" data in a critical
+ * chunk. For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard. These values should NOT be changed.
+ *
+ * value action:critical action:ancillary
+ */
+#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
+#define PNG_CRC_ERROR_QUIT 1 /* error/quit error/quit */
+#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
+#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
+#define PNG_CRC_QUIET_USE 4 /* quiet/use data quiet/use data */
+#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib. These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them. See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* Set the filtering method(s) used by libpng. Currently, the only valid
+ * value for "method" is 0.
+ */
+PNG_EXPORT(67, void, png_set_filter, (png_structrp png_ptr, int method,
+ int filters));
+
+/* Flags for png_set_filter() to say which filters to use. The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS 0x00
+#define PNG_FILTER_NONE 0x08
+#define PNG_FILTER_SUB 0x10
+#define PNG_FILTER_UP 0x20
+#define PNG_FILTER_AVG 0x40
+#define PNG_FILTER_PAETH 0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+ PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE 0
+#define PNG_FILTER_VALUE_SUB 1
+#define PNG_FILTER_VALUE_UP 2
+#define PNG_FILTER_VALUE_AVG 3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST 5
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows. Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters. This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified. Weights have no influence on
+ * the selection of the first row filter. Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type. Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs. There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs. Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found. If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+PNG_FP_EXPORT(68, void, png_set_filter_heuristics, (png_structrp png_ptr,
+ int heuristic_method, int num_weights, png_const_doublep filter_weights,
+ png_const_doublep filter_costs))
+PNG_FIXED_EXPORT(209, void, png_set_filter_heuristics_fixed,
+ (png_structrp png_ptr, int heuristic_method, int num_weights,
+ png_const_fixed_point_p filter_weights,
+ png_const_fixed_point_p filter_costs))
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+/* Heuristic used for row filter selection. These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
+
+#ifdef PNG_WRITE_SUPPORTED
+/* Set the library compression level. Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression). Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations. In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+PNG_EXPORT(69, void, png_set_compression_level, (png_structrp png_ptr,
+ int level));
+
+PNG_EXPORT(70, void, png_set_compression_mem_level, (png_structrp png_ptr,
+ int mem_level));
+
+PNG_EXPORT(71, void, png_set_compression_strategy, (png_structrp png_ptr,
+ int strategy));
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+PNG_EXPORT(72, void, png_set_compression_window_bits, (png_structrp png_ptr,
+ int window_bits));
+
+PNG_EXPORT(73, void, png_set_compression_method, (png_structrp png_ptr,
+ int method));
+#endif
+
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+/* Also set zlib parameters for compressing non-IDAT chunks */
+PNG_EXPORT(222, void, png_set_text_compression_level, (png_structrp png_ptr,
+ int level));
+
+PNG_EXPORT(223, void, png_set_text_compression_mem_level, (png_structrp png_ptr,
+ int mem_level));
+
+PNG_EXPORT(224, void, png_set_text_compression_strategy, (png_structrp png_ptr,
+ int strategy));
+
+/* If PNG_WRITE_OPTIMIZE_CMF_SUPPORTED is defined, libpng will use a
+ * smaller value of window_bits if it can do so safely.
+ */
+PNG_EXPORT(225, void, png_set_text_compression_window_bits,
+ (png_structrp png_ptr, int window_bits));
+
+PNG_EXPORT(226, void, png_set_text_compression_method, (png_structrp png_ptr,
+ int method));
+#endif /* PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED */
+
+/* These next functions are called for input/output, memory, and error
+ * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf(). These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn(). See libpng-manual.txt for
+ * more information.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+/* Initialize the input/output for the PNG file to the default functions. */
+PNG_EXPORT(74, void, png_init_io, (png_structrp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions. If no messages are to be printed you must still
+ * write and use replacement functions. The replacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling. If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+PNG_EXPORT(75, void, png_set_error_fn, (png_structrp png_ptr,
+ png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+PNG_EXPORT(76, png_voidp, png_get_error_ptr, (png_const_structrp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ * It is probably a mistake to use NULL for output_flush_fn if
+ * write_data_fn is not also NULL unless you have built libpng with
+ * PNG_WRITE_FLUSH_SUPPORTED undefined, because in this case libpng's
+ * default flush function, which uses the standard *FILE structure, will
+ * be used.
+ */
+PNG_EXPORT(77, void, png_set_write_fn, (png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+PNG_EXPORT(78, void, png_set_read_fn, (png_structrp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+PNG_EXPORT(79, png_voidp, png_get_io_ptr, (png_const_structrp png_ptr));
+
+PNG_EXPORT(80, void, png_set_read_status_fn, (png_structrp png_ptr,
+ png_read_status_ptr read_row_fn));
+
+PNG_EXPORT(81, void, png_set_write_status_fn, (png_structrp png_ptr,
+ png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+PNG_EXPORT(82, void, png_set_mem_fn, (png_structrp png_ptr, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+PNG_EXPORT(83, png_voidp, png_get_mem_ptr, (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+PNG_EXPORT(84, void, png_set_read_user_transform_fn, (png_structrp png_ptr,
+ png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+PNG_EXPORT(85, void, png_set_write_user_transform_fn, (png_structrp png_ptr,
+ png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+PNG_EXPORT(86, void, png_set_user_transform_info, (png_structrp png_ptr,
+ png_voidp user_transform_ptr, int user_transform_depth,
+ int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+PNG_EXPORT(87, png_voidp, png_get_user_transform_ptr,
+ (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_USER_TRANSFORM_INFO_SUPPORTED
+/* Return information about the row currently being processed. Note that these
+ * APIs do not fail but will return unexpected results if called outside a user
+ * transform callback. Also note that when transforming an interlaced image the
+ * row number is the row number within the sub-image of the interlace pass, so
+ * the value will increase to the height of the sub-image (not the full image)
+ * then reset to 0 for the next pass.
+ *
+ * Use PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
+ * find the output pixel (x,y) given an interlaced sub-image pixel
+ * (row,col,pass). (See below for these macros.)
+ */
+PNG_EXPORT(217, png_uint_32, png_get_current_row_number, (png_const_structrp));
+PNG_EXPORT(218, png_byte, png_get_current_pass_number, (png_const_structrp));
+#endif
+
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+/* This callback is called only for *unknown* chunks. If
+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED is set then it is possible to set known
+ * chunks to be treated as unknown, however in this case the callback must do
+ * any processing required by the chunk (e.g. by calling the appropriate
+ * png_set_ APIs.)
+ *
+ * There is no write support - on write, by default, all the chunks in the
+ * 'unknown' list are written in the specified position.
+ *
+ * The integer return from the callback function is interpreted thus:
+ *
+ * negative: An error occured, png_chunk_error will be called.
+ * zero: The chunk was not handled, the chunk will be saved. A critical
+ * chunk will cause an error at this point unless it is to be saved.
+ * positive: The chunk was handled, libpng will ignore/discard it.
+ *
+ * See "INTERACTION WTIH USER CHUNK CALLBACKS" below for important notes about
+ * how this behavior will change in libpng 1.7
+ */
+PNG_EXPORT(88, void, png_set_read_user_chunk_fn, (png_structrp png_ptr,
+ png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+PNG_EXPORT(89, png_voidp, png_get_user_chunk_ptr, (png_const_structrp png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+PNG_EXPORT(90, void, png_set_progressive_read_fn, (png_structrp png_ptr,
+ png_voidp progressive_ptr, png_progressive_info_ptr info_fn,
+ png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn));
+
+/* Returns the user pointer associated with the push read functions */
+PNG_EXPORT(91, png_voidp, png_get_progressive_ptr,
+ (png_const_structrp png_ptr));
+
+/* Function to be called when data becomes available */
+PNG_EXPORT(92, void, png_process_data, (png_structrp png_ptr,
+ png_inforp info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* A function which may be called *only* within png_process_data to stop the
+ * processing of any more data. The function returns the number of bytes
+ * remaining, excluding any that libpng has cached internally. A subsequent
+ * call to png_process_data must supply these bytes again. If the argument
+ * 'save' is set to true the routine will first save all the pending data and
+ * will always return 0.
+ */
+PNG_EXPORT(219, png_size_t, png_process_data_pause, (png_structrp, int save));
+
+/* A function which may be called *only* outside (after) a call to
+ * png_process_data. It returns the number of bytes of data to skip in the
+ * input. Normally it will return 0, but if it returns a non-zero value the
+ * application must skip than number of bytes of input data and pass the
+ * following data to the next call to png_process_data.
+ */
+PNG_EXPORT(220, png_uint_32, png_process_data_skip, (png_structrp));
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Function that combines rows. 'new_row' is a flag that should come from
+ * the callback and be non-NULL if anything needs to be done; the library
+ * stores its own version of the new data internally and ignores the passed
+ * in value.
+ */
+PNG_EXPORT(93, void, png_progressive_combine_row, (png_const_structrp png_ptr,
+ png_bytep old_row, png_const_bytep new_row));
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+PNG_EXPORTA(94, png_voidp, png_malloc, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
+/* Added at libpng version 1.4.0 */
+PNG_EXPORTA(95, png_voidp, png_calloc, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
+
+/* Added at libpng version 1.2.4 */
+PNG_EXPORTA(96, png_voidp, png_malloc_warn, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED);
+
+/* Frees a pointer allocated by png_malloc() */
+PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr));
+
+/* Free data that was allocated internally */
+PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 free_me, int num));
+
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application; this works on the png_info structure passed
+ * in, it does not change the state for other png_info structures.
+ *
+ * It is unlikely that this function works correctly as of 1.6.0 and using it
+ * may result either in memory leaks or double free of allocated data.
+ */
+PNG_EXPORTA(99, void, png_data_freer, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int freer, png_uint_32 mask), PNG_DEPRECATED);
+
+/* Assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_FREE_UNKN 0x0200
+#endif
+/* PNG_FREE_LIST 0x0400 removed in 1.6.0 because it is ignored */
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL 0x7fff
+#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+PNG_EXPORTA(100, png_voidp, png_malloc_default, (png_const_structrp png_ptr,
+ png_alloc_size_t size), PNG_ALLOCATED PNG_DEPRECATED);
+PNG_EXPORTA(101, void, png_free_default, (png_const_structrp png_ptr,
+ png_voidp ptr), PNG_DEPRECATED);
+#endif
+
+#ifdef PNG_ERROR_TEXT_SUPPORTED
+/* Fatal error in PNG image of libpng - can't continue */
+PNG_EXPORTA(102, void, png_error, (png_const_structrp png_ptr,
+ png_const_charp error_message), PNG_NORETURN);
+
+/* The same, but the chunk name is prepended to the error string. */
+PNG_EXPORTA(103, void, png_chunk_error, (png_const_structrp png_ptr,
+ png_const_charp error_message), PNG_NORETURN);
+
+#else
+/* Fatal error in PNG image of libpng - can't continue */
+PNG_EXPORTA(104, void, png_err, (png_const_structrp png_ptr), PNG_NORETURN);
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* Non-fatal error in libpng. Can continue, but may have a problem. */
+PNG_EXPORT(105, void, png_warning, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+PNG_EXPORT(106, void, png_chunk_warning, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+#endif
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+/* Benign error in libpng. Can continue, but may have a problem.
+ * User can choose whether to handle as a fatal error or as a warning. */
+PNG_EXPORT(107, void, png_benign_error, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+
+#ifdef PNG_READ_SUPPORTED
+/* Same, chunk name is prepended to message (only during read) */
+PNG_EXPORT(108, void, png_chunk_benign_error, (png_const_structrp png_ptr,
+ png_const_charp warning_message));
+#endif
+
+PNG_EXPORT(109, void, png_set_benign_errors,
+ (png_structrp png_ptr, int allowed));
+#else
+# ifdef PNG_ALLOW_BENIGN_ERRORS
+# define png_benign_error png_warning
+# define png_chunk_benign_error png_chunk_warning
+# else
+# define png_benign_error png_error
+# define png_chunk_benign_error png_chunk_error
+# endif
+#endif
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored. The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal layout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+PNG_EXPORT(110, png_uint_32, png_get_valid, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+PNG_EXPORT(111, png_size_t, png_get_rowbytes, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+ * returned from png_read_png().
+ */
+PNG_EXPORT(112, png_bytepp, png_get_rows, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Set row_pointers, which is an array of pointers to scanlines for use
+ * by png_write_png().
+ */
+PNG_EXPORT(113, void, png_set_rows, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+PNG_EXPORT(114, png_byte, png_get_channels, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+PNG_EXPORT(115, png_uint_32, png_get_image_width, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image height in pixels. */
+PNG_EXPORT(116, png_uint_32, png_get_image_height, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image bit_depth. */
+PNG_EXPORT(117, png_byte, png_get_bit_depth, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image color_type. */
+PNG_EXPORT(118, png_byte, png_get_color_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image filter_type. */
+PNG_EXPORT(119, png_byte, png_get_filter_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image interlace_type. */
+PNG_EXPORT(120, png_byte, png_get_interlace_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image compression_type. */
+PNG_EXPORT(121, png_byte, png_get_compression_type, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+PNG_EXPORT(122, png_uint_32, png_get_pixels_per_meter,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(123, png_uint_32, png_get_x_pixels_per_meter,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(124, png_uint_32, png_get_y_pixels_per_meter,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data. */
+PNG_FP_EXPORT(125, float, png_get_pixel_aspect_ratio,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+PNG_FIXED_EXPORT(210, png_fixed_point, png_get_pixel_aspect_ratio_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+PNG_EXPORT(126, png_int_32, png_get_x_offset_pixels,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(127, png_int_32, png_get_y_offset_pixels,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(128, png_int_32, png_get_x_offset_microns,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+PNG_EXPORT(129, png_int_32, png_get_y_offset_microns,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+#ifdef PNG_READ_SUPPORTED
+/* Returns pointer to signature string read from PNG header */
+PNG_EXPORT(130, png_const_bytep, png_get_signature, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+PNG_EXPORT(131, png_uint_32, png_get_bKGD, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_color_16p *background));
+#endif
+
+#ifdef PNG_bKGD_SUPPORTED
+PNG_EXPORT(132, void, png_set_bKGD, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_color_16p background));
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+PNG_FP_EXPORT(133, png_uint_32, png_get_cHRM, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x,
+ double *red_y, double *green_x, double *green_y, double *blue_x,
+ double *blue_y))
+PNG_FP_EXPORT(230, png_uint_32, png_get_cHRM_XYZ, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *red_X, double *red_Y, double *red_Z,
+ double *green_X, double *green_Y, double *green_Z, double *blue_X,
+ double *blue_Y, double *blue_Z))
+PNG_FIXED_EXPORT(134, png_uint_32, png_get_cHRM_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_white_x, png_fixed_point *int_white_y,
+ png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+ png_fixed_point *int_green_x, png_fixed_point *int_green_y,
+ png_fixed_point *int_blue_x, png_fixed_point *int_blue_y))
+PNG_FIXED_EXPORT(231, png_uint_32, png_get_cHRM_XYZ_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_red_X, png_fixed_point *int_red_Y,
+ png_fixed_point *int_red_Z, png_fixed_point *int_green_X,
+ png_fixed_point *int_green_Y, png_fixed_point *int_green_Z,
+ png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y,
+ png_fixed_point *int_blue_Z))
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+PNG_FP_EXPORT(135, void, png_set_cHRM, (png_const_structrp png_ptr,
+ png_inforp info_ptr,
+ double white_x, double white_y, double red_x, double red_y, double green_x,
+ double green_y, double blue_x, double blue_y))
+PNG_FP_EXPORT(232, void, png_set_cHRM_XYZ, (png_const_structrp png_ptr,
+ png_inforp info_ptr, double red_X, double red_Y, double red_Z,
+ double green_X, double green_Y, double green_Z, double blue_X,
+ double blue_Y, double blue_Z))
+PNG_FIXED_EXPORT(136, void, png_set_cHRM_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_white_x,
+ png_fixed_point int_white_y, png_fixed_point int_red_x,
+ png_fixed_point int_red_y, png_fixed_point int_green_x,
+ png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y))
+PNG_FIXED_EXPORT(233, void, png_set_cHRM_XYZ_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_red_X, png_fixed_point int_red_Y,
+ png_fixed_point int_red_Z, png_fixed_point int_green_X,
+ png_fixed_point int_green_Y, png_fixed_point int_green_Z,
+ png_fixed_point int_blue_X, png_fixed_point int_blue_Y,
+ png_fixed_point int_blue_Z))
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+PNG_FP_EXPORT(137, png_uint_32, png_get_gAMA, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, double *file_gamma))
+PNG_FIXED_EXPORT(138, png_uint_32, png_get_gAMA_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr,
+ png_fixed_point *int_file_gamma))
+#endif
+
+#ifdef PNG_gAMA_SUPPORTED
+PNG_FP_EXPORT(139, void, png_set_gAMA, (png_const_structrp png_ptr,
+ png_inforp info_ptr, double file_gamma))
+PNG_FIXED_EXPORT(140, void, png_set_gAMA_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_fixed_point int_file_gamma))
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+PNG_EXPORT(141, png_uint_32, png_get_hIST, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_16p *hist));
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+PNG_EXPORT(142, void, png_set_hIST, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_uint_16p hist));
+#endif
+
+PNG_EXPORT(143, png_uint_32, png_get_IHDR, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *width, png_uint_32 *height,
+ int *bit_depth, int *color_type, int *interlace_method,
+ int *compression_method, int *filter_method));
+
+PNG_EXPORT(144, void, png_set_IHDR, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_method, int compression_method,
+ int filter_method));
+
+#ifdef PNG_oFFs_SUPPORTED
+PNG_EXPORT(145, png_uint_32, png_get_oFFs, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+ int *unit_type));
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+PNG_EXPORT(146, void, png_set_oFFs, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+ int unit_type));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+PNG_EXPORT(147, png_uint_32, png_get_pCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_charp *purpose, png_int_32 *X0,
+ png_int_32 *X1, int *type, int *nparams, png_charp *units,
+ png_charpp *params));
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+PNG_EXPORT(148, void, png_set_pCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_charp purpose, png_int_32 X0, png_int_32 X1,
+ int type, int nparams, png_const_charp units, png_charpp params));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(149, png_uint_32, png_get_pHYs, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+ int *unit_type));
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(150, void, png_set_pHYs, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+PNG_EXPORT(151, png_uint_32, png_get_PLTE, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_colorp *palette, int *num_palette));
+
+PNG_EXPORT(152, void, png_set_PLTE, (png_structrp png_ptr,
+ png_inforp info_ptr, png_const_colorp palette, int num_palette));
+
+#ifdef PNG_sBIT_SUPPORTED
+PNG_EXPORT(153, png_uint_32, png_get_sBIT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_color_8p *sig_bit));
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+PNG_EXPORT(154, void, png_set_sBIT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_color_8p sig_bit));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_EXPORT(155, png_uint_32, png_get_sRGB, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, int *file_srgb_intent));
+#endif
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_EXPORT(156, void, png_set_sRGB, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int srgb_intent));
+PNG_EXPORT(157, void, png_set_sRGB_gAMA_and_cHRM, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int srgb_intent));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_EXPORT(158, png_uint_32, png_get_iCCP, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_charpp name, int *compression_type,
+ png_bytepp profile, png_uint_32 *proflen));
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_EXPORT(159, void, png_set_iCCP, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_charp name, int compression_type,
+ png_const_bytep profile, png_uint_32 proflen));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+PNG_EXPORT(160, int, png_get_sPLT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_sPLT_tpp entries));
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+PNG_EXPORT(161, void, png_set_sPLT, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_sPLT_tp entries, int nentries));
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_get_text also returns the number of text chunks in *num_text */
+PNG_EXPORT(162, int, png_get_text, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/* Note while png_set_text() will accept a structure whose text,
+ * language, and translated keywords are NULL pointers, the structure
+ * returned by png_get_text will always contain regular
+ * zero-terminated C strings. They might be empty strings but
+ * they will never be NULL pointers.
+ */
+
+#ifdef PNG_TEXT_SUPPORTED
+PNG_EXPORT(163, void, png_set_text, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_textp text_ptr, int num_text));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+PNG_EXPORT(164, png_uint_32, png_get_tIME, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_timep *mod_time));
+#endif
+
+#ifdef PNG_tIME_SUPPORTED
+PNG_EXPORT(165, void, png_set_tIME, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_timep mod_time));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+PNG_EXPORT(166, png_uint_32, png_get_tRNS, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans,
+ png_color_16p *trans_color));
+#endif
+
+#ifdef PNG_tRNS_SUPPORTED
+PNG_EXPORT(167, void, png_set_tRNS, (png_structrp png_ptr,
+ png_inforp info_ptr, png_const_bytep trans_alpha, int num_trans,
+ png_const_color_16p trans_color));
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+PNG_FP_EXPORT(168, png_uint_32, png_get_sCAL, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, int *unit, double *width, double *height))
+#if defined(PNG_FLOATING_ARITHMETIC_SUPPORTED) || \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+/* NOTE: this API is currently implemented using floating point arithmetic,
+ * consequently it can only be used on systems with floating point support.
+ * In any case the range of values supported by png_fixed_point is small and it
+ * is highly recommended that png_get_sCAL_s be used instead.
+ */
+PNG_FIXED_EXPORT(214, png_uint_32, png_get_sCAL_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+ png_fixed_point *width, png_fixed_point *height))
+#endif
+PNG_EXPORT(169, png_uint_32, png_get_sCAL_s,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit,
+ png_charpp swidth, png_charpp sheight));
+
+PNG_FP_EXPORT(170, void, png_set_sCAL, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit, double width, double height))
+PNG_FIXED_EXPORT(213, void, png_set_sCAL_fixed, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit, png_fixed_point width,
+ png_fixed_point height))
+PNG_EXPORT(171, void, png_set_sCAL_s, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int unit,
+ png_const_charp swidth, png_const_charp sheight));
+#endif /* PNG_sCAL_SUPPORTED */
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+/* Provide the default handling for all unknown chunks or, optionally, for
+ * specific unknown chunks.
+ *
+ * NOTE: prior to 1.6.0 the handling specified for particular chunks on read was
+ * ignored and the default was used, the per-chunk setting only had an effect on
+ * write. If you wish to have chunk-specific handling on read in code that must
+ * work on earlier versions you must use a user chunk callback to specify the
+ * desired handling (keep or discard.)
+ *
+ * The 'keep' parameter is a PNG_HANDLE_CHUNK_ value as listed below. The
+ * parameter is interpreted as follows:
+ *
+ * READ:
+ * PNG_HANDLE_CHUNK_AS_DEFAULT:
+ * Known chunks: do normal libpng processing, do not keep the chunk (but
+ * see the comments below about PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+ * Unknown chunks: for a specific chunk use the global default, when used
+ * as the default discard the chunk data.
+ * PNG_HANDLE_CHUNK_NEVER:
+ * Discard the chunk data.
+ * PNG_HANDLE_CHUNK_IF_SAFE:
+ * Keep the chunk data if the chunk is not critical else raise a chunk
+ * error.
+ * PNG_HANDLE_CHUNK_ALWAYS:
+ * Keep the chunk data.
+ *
+ * If the chunk data is saved it can be retrieved using png_get_unknown_chunks,
+ * below. Notice that specifying "AS_DEFAULT" as a global default is equivalent
+ * to specifying "NEVER", however when "AS_DEFAULT" is used for specific chunks
+ * it simply resets the behavior to the libpng default.
+ *
+ * INTERACTION WTIH USER CHUNK CALLBACKS:
+ * The per-chunk handling is always used when there is a png_user_chunk_ptr
+ * callback and the callback returns 0; the chunk is then always stored *unless*
+ * it is critical and the per-chunk setting is other than ALWAYS. Notice that
+ * the global default is *not* used in this case. (In effect the per-chunk
+ * value is incremented to at least IF_SAFE.)
+ *
+ * IMPORTANT NOTE: this behavior will change in libpng 1.7 - the global and
+ * per-chunk defaults will be honored. If you want to preserve the current
+ * behavior when your callback returns 0 you must set PNG_HANDLE_CHUNK_IF_SAFE
+ * as the default - if you don't do this libpng 1.6 will issue a warning.
+ *
+ * If you want unhandled unknown chunks to be discarded in libpng 1.6 and
+ * earlier simply return '1' (handled).
+ *
+ * PNG_HANDLE_AS_UNKNOWN_SUPPORTED:
+ * If this is *not* set known chunks will always be handled by libpng and
+ * will never be stored in the unknown chunk list. Known chunks listed to
+ * png_set_keep_unknown_chunks will have no effect. If it is set then known
+ * chunks listed with a keep other than AS_DEFAULT will *never* be processed
+ * by libpng, in addition critical chunks must either be processed by the
+ * callback or saved.
+ *
+ * The IHDR and IEND chunks must not be listed. Because this turns off the
+ * default handling for chunks that would otherwise be recognized the
+ * behavior of libpng transformations may well become incorrect!
+ *
+ * WRITE:
+ * When writing chunks the options only apply to the chunks specified by
+ * png_set_unknown_chunks (below), libpng will *always* write known chunks
+ * required by png_set_ calls and will always write the core critical chunks
+ * (as required for PLTE).
+ *
+ * Each chunk in the png_set_unknown_chunks list is looked up in the
+ * png_set_keep_unknown_chunks list to find the keep setting, this is then
+ * interpreted as follows:
+ *
+ * PNG_HANDLE_CHUNK_AS_DEFAULT:
+ * Write safe-to-copy chunks and write other chunks if the global
+ * default is set to _ALWAYS, otherwise don't write this chunk.
+ * PNG_HANDLE_CHUNK_NEVER:
+ * Do not write the chunk.
+ * PNG_HANDLE_CHUNK_IF_SAFE:
+ * Write the chunk if it is safe-to-copy, otherwise do not write it.
+ * PNG_HANDLE_CHUNK_ALWAYS:
+ * Write the chunk.
+ *
+ * Note that the default behavior is effectively the opposite of the read case -
+ * in read unknown chunks are not stored by default, in write they are written
+ * by default. Also the behavior of PNG_HANDLE_CHUNK_IF_SAFE is very different
+ * - on write the safe-to-copy bit is checked, on read the critical bit is
+ * checked and on read if the chunk is critical an error will be raised.
+ *
+ * num_chunks:
+ * ===========
+ * If num_chunks is positive, then the "keep" parameter specifies the manner
+ * for handling only those chunks appearing in the chunk_list array,
+ * otherwise the chunk list array is ignored.
+ *
+ * If num_chunks is 0 the "keep" parameter specifies the default behavior for
+ * unknown chunks, as described above.
+ *
+ * If num_chunks is negative, then the "keep" parameter specifies the manner
+ * for handling all unknown chunks plus all chunks recognized by libpng
+ * except for the IHDR, PLTE, tRNS, IDAT, and IEND chunks (which continue to
+ * be processed by libpng.
+ */
+PNG_EXPORT(172, void, png_set_keep_unknown_chunks, (png_structrp png_ptr,
+ int keep, png_const_bytep chunk_list, int num_chunks));
+
+/* The "keep" PNG_HANDLE_CHUNK_ parameter for the specified chunk is returned;
+ * the result is therefore true (non-zero) if special handling is required,
+ * false for the default handling.
+ */
+PNG_EXPORT(173, int, png_handle_as_unknown, (png_const_structrp png_ptr,
+ png_const_bytep chunk_name));
+#endif
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+PNG_EXPORT(174, void, png_set_unknown_chunks, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_unknown_chunkp unknowns,
+ int num_unknowns));
+ /* NOTE: prior to 1.6.0 this routine set the 'location' field of the added
+ * unknowns to the location currently stored in the png_struct. This is
+ * invariably the wrong value on write. To fix this call the following API
+ * for each chunk in the list with the correct location. If you know your
+ * code won't be compiled on earlier versions you can rely on
+ * png_set_unknown_chunks(write-ptr, png_get_unknown_chunks(read-ptr)) doing
+ * the correct thing.
+ */
+
+PNG_EXPORT(175, void, png_set_unknown_chunk_location,
+ (png_const_structrp png_ptr, png_inforp info_ptr, int chunk, int location));
+
+PNG_EXPORT(176, int, png_get_unknown_chunks, (png_const_structrp png_ptr,
+ png_inforp info_ptr, png_unknown_chunkpp entries));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+ * If you need to turn it off for a chunk that your application has freed,
+ * you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK);
+ */
+PNG_EXPORT(177, void, png_set_invalid, (png_const_structrp png_ptr,
+ png_inforp info_ptr, int mask));
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+/* The "params" pointer is currently not used and is for future expansion. */
+PNG_EXPORT(178, void, png_read_png, (png_structrp png_ptr, png_inforp info_ptr,
+ int transforms, png_voidp params));
+PNG_EXPORT(179, void, png_write_png, (png_structrp png_ptr, png_inforp info_ptr,
+ int transforms, png_voidp params));
+#endif
+
+PNG_EXPORT(180, png_const_charp, png_get_copyright,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(181, png_const_charp, png_get_header_ver,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(182, png_const_charp, png_get_header_version,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(183, png_const_charp, png_get_libpng_ver,
+ (png_const_structrp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXPORT(184, png_uint_32, png_permit_mng_features, (png_structrp png_ptr,
+ png_uint_32 mng_features_permitted));
+#endif
+
+/* For use in png_set_keep_unknown, added to version 1.2.6 */
+#define PNG_HANDLE_CHUNK_AS_DEFAULT 0
+#define PNG_HANDLE_CHUNK_NEVER 1
+#define PNG_HANDLE_CHUNK_IF_SAFE 2
+#define PNG_HANDLE_CHUNK_ALWAYS 3
+#define PNG_HANDLE_CHUNK_LAST 4
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler.
+ */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+PNG_EXPORT(185, void, png_set_strip_error_numbers, (png_structrp png_ptr,
+ png_uint_32 strip_mode));
+#endif
+
+/* Added in libpng-1.2.6 */
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+PNG_EXPORT(186, void, png_set_user_limits, (png_structrp png_ptr,
+ png_uint_32 user_width_max, png_uint_32 user_height_max));
+PNG_EXPORT(187, png_uint_32, png_get_user_width_max,
+ (png_const_structrp png_ptr));
+PNG_EXPORT(188, png_uint_32, png_get_user_height_max,
+ (png_const_structrp png_ptr));
+/* Added in libpng-1.4.0 */
+PNG_EXPORT(189, void, png_set_chunk_cache_max, (png_structrp png_ptr,
+ png_uint_32 user_chunk_cache_max));
+PNG_EXPORT(190, png_uint_32, png_get_chunk_cache_max,
+ (png_const_structrp png_ptr));
+/* Added in libpng-1.4.1 */
+PNG_EXPORT(191, void, png_set_chunk_malloc_max, (png_structrp png_ptr,
+ png_alloc_size_t user_chunk_cache_max));
+PNG_EXPORT(192, png_alloc_size_t, png_get_chunk_malloc_max,
+ (png_const_structrp png_ptr));
+#endif
+
+#if defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+PNG_EXPORT(193, png_uint_32, png_get_pixels_per_inch,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_EXPORT(194, png_uint_32, png_get_x_pixels_per_inch,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_EXPORT(195, png_uint_32, png_get_y_pixels_per_inch,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr));
+
+PNG_FP_EXPORT(196, float, png_get_x_offset_inches,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+PNG_FIXED_EXPORT(211, png_fixed_point, png_get_x_offset_inches_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#endif
+
+PNG_FP_EXPORT(197, float, png_get_y_offset_inches, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr))
+#ifdef PNG_FIXED_POINT_SUPPORTED /* otherwise not implemented. */
+PNG_FIXED_EXPORT(212, png_fixed_point, png_get_y_offset_inches_fixed,
+ (png_const_structrp png_ptr, png_const_inforp info_ptr))
+#endif
+
+# ifdef PNG_pHYs_SUPPORTED
+PNG_EXPORT(198, png_uint_32, png_get_pHYs_dpi, (png_const_structrp png_ptr,
+ png_const_inforp info_ptr, png_uint_32 *res_x, png_uint_32 *res_y,
+ int *unit_type));
+# endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS_SUPPORTED */
+
+/* Added in libpng-1.4.0 */
+#ifdef PNG_IO_STATE_SUPPORTED
+PNG_EXPORT(199, png_uint_32, png_get_io_state, (png_const_structrp png_ptr));
+
+/* Removed from libpng 1.6; use png_get_io_chunk_type. */
+PNG_REMOVED(200, png_const_bytep, png_get_io_chunk_name, (png_structrp png_ptr),
+ PNG_DEPRECATED)
+
+PNG_EXPORT(216, png_uint_32, png_get_io_chunk_type,
+ (png_const_structrp png_ptr));
+
+/* The flags returned by png_get_io_state() are the following: */
+# define PNG_IO_NONE 0x0000 /* no I/O at this moment */
+# define PNG_IO_READING 0x0001 /* currently reading */
+# define PNG_IO_WRITING 0x0002 /* currently writing */
+# define PNG_IO_SIGNATURE 0x0010 /* currently at the file signature */
+# define PNG_IO_CHUNK_HDR 0x0020 /* currently at the chunk header */
+# define PNG_IO_CHUNK_DATA 0x0040 /* currently at the chunk data */
+# define PNG_IO_CHUNK_CRC 0x0080 /* currently at the chunk crc */
+# define PNG_IO_MASK_OP 0x000f /* current operation: reading/writing */
+# define PNG_IO_MASK_LOC 0x00f0 /* current location: sig/hdr/data/crc */
+#endif /* ?PNG_IO_STATE_SUPPORTED */
+
+/* Interlace support. The following macros are always defined so that if
+ * libpng interlace handling is turned off the macros may be used to handle
+ * interlaced images within the application.
+ */
+#define PNG_INTERLACE_ADAM7_PASSES 7
+
+/* Two macros to return the first row and first column of the original,
+ * full, image which appears in a given pass. 'pass' is in the range 0
+ * to 6 and the result is in the range 0 to 7.
+ */
+#define PNG_PASS_START_ROW(pass) (((1&~(pass))<<(3-((pass)>>1)))&7)
+#define PNG_PASS_START_COL(pass) (((1& (pass))<<(3-(((pass)+1)>>1)))&7)
+
+/* A macro to return the offset between pixels in the output row for a pair of
+ * pixels in the input - effectively the inverse of the 'COL_SHIFT' macro that
+ * follows. Note that ROW_OFFSET is the offset from one row to the next whereas
+ * COL_OFFSET is from one column to the next, within a row.
+ */
+#define PNG_PASS_ROW_OFFSET(pass) ((pass)>2?(8>>(((pass)-1)>>1)):8)
+#define PNG_PASS_COL_OFFSET(pass) (1<<((7-(pass))>>1))
+
+/* Two macros to help evaluate the number of rows or columns in each
+ * pass. This is expressed as a shift - effectively log2 of the number or
+ * rows or columns in each 8x8 tile of the original image.
+ */
+#define PNG_PASS_ROW_SHIFT(pass) ((pass)>2?(8-(pass))>>1:3)
+#define PNG_PASS_COL_SHIFT(pass) ((pass)>1?(7-(pass))>>1:3)
+
+/* Hence two macros to determine the number of rows or columns in a given
+ * pass of an image given its height or width. In fact these macros may
+ * return non-zero even though the sub-image is empty, because the other
+ * dimension may be empty for a small image.
+ */
+#define PNG_PASS_ROWS(height, pass) (((height)+(((1<<PNG_PASS_ROW_SHIFT(pass))\
+ -1)-PNG_PASS_START_ROW(pass)))>>PNG_PASS_ROW_SHIFT(pass))
+#define PNG_PASS_COLS(width, pass) (((width)+(((1<<PNG_PASS_COL_SHIFT(pass))\
+ -1)-PNG_PASS_START_COL(pass)))>>PNG_PASS_COL_SHIFT(pass))
+
+/* For the reader row callbacks (both progressive and sequential) it is
+ * necessary to find the row in the output image given a row in an interlaced
+ * image, so two more macros:
+ */
+#define PNG_ROW_FROM_PASS_ROW(y_in, pass) \
+ (((y_in)<<PNG_PASS_ROW_SHIFT(pass))+PNG_PASS_START_ROW(pass))
+#define PNG_COL_FROM_PASS_COL(x_in, pass) \
+ (((x_in)<<PNG_PASS_COL_SHIFT(pass))+PNG_PASS_START_COL(pass))
+
+/* Two macros which return a boolean (0 or 1) saying whether the given row
+ * or column is in a particular pass. These use a common utility macro that
+ * returns a mask for a given pass - the offset 'off' selects the row or
+ * column version. The mask has the appropriate bit set for each column in
+ * the tile.
+ */
+#define PNG_PASS_MASK(pass,off) ( \
+ ((0x110145AF>>(((7-(off))-(pass))<<2)) & 0xF) | \
+ ((0x01145AF0>>(((7-(off))-(pass))<<2)) & 0xF0))
+
+#define PNG_ROW_IN_INTERLACE_PASS(y, pass) \
+ ((PNG_PASS_MASK(pass,0) >> ((y)&7)) & 1)
+#define PNG_COL_IN_INTERLACE_PASS(x, pass) \
+ ((PNG_PASS_MASK(pass,1) >> ((x)&7)) & 1)
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines. However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems. There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same! 128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+
+# define png_composite(composite, fg, alpha, bg) \
+ { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) \
+ * (png_uint_16)(alpha) \
+ + (png_uint_16)(bg)*(png_uint_16)(255 \
+ - (png_uint_16)(alpha)) + 128); \
+ (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) \
+ * (png_uint_32)(alpha) \
+ + (png_uint_32)(bg)*(65535 \
+ - (png_uint_32)(alpha)) + 32768); \
+ (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else /* Standard method using integer division */
+
+# define png_composite(composite, fg, alpha, bg) \
+ (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+ 127) / 255)
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+ (png_uint_32)(bg)*(png_uint_32)(65535 - (png_uint_32)(alpha)) + \
+ 32767) / 65535)
+#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
+
+#ifdef PNG_READ_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(201, png_uint_32, png_get_uint_32, (png_const_bytep buf));
+PNG_EXPORT(202, png_uint_16, png_get_uint_16, (png_const_bytep buf));
+PNG_EXPORT(203, png_int_32, png_get_int_32, (png_const_bytep buf));
+#endif
+
+PNG_EXPORT(204, png_uint_32, png_get_uint_31, (png_const_structrp png_ptr,
+ png_const_bytep buf));
+/* No png_get_int_16 -- may be added if there's a real need for it. */
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian). */
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(205, void, png_save_uint_32, (png_bytep buf, png_uint_32 i));
+#endif
+#ifdef PNG_SAVE_INT_32_SUPPORTED
+PNG_EXPORT(206, void, png_save_int_32, (png_bytep buf, png_int_32 i));
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+#ifdef PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+PNG_EXPORT(207, void, png_save_uint_16, (png_bytep buf, unsigned int i));
+/* No png_save_int_16 -- may be added if there's a real need for it. */
+#endif
+
+#ifdef PNG_USE_READ_MACROS
+/* Inline macros to do direct reads of bytes from the input buffer.
+ * The png_get_int_32() routine assumes we are using two's complement
+ * format for negative values, which is almost certainly true.
+ */
+# define PNG_get_uint_32(buf) \
+ (((png_uint_32)(*(buf)) << 24) + \
+ ((png_uint_32)(*((buf) + 1)) << 16) + \
+ ((png_uint_32)(*((buf) + 2)) << 8) + \
+ ((png_uint_32)(*((buf) + 3))))
+
+ /* From libpng-1.4.0 until 1.4.4, the png_get_uint_16 macro (but not the
+ * function) incorrectly returned a value of type png_uint_32.
+ */
+# define PNG_get_uint_16(buf) \
+ ((png_uint_16) \
+ (((unsigned int)(*(buf)) << 8) + \
+ ((unsigned int)(*((buf) + 1)))))
+
+# define PNG_get_int_32(buf) \
+ ((png_int_32)((*(buf) & 0x80) \
+ ? -((png_int_32)((png_get_uint_32(buf) ^ 0xffffffffL) + 1)) \
+ : (png_int_32)png_get_uint_32(buf)))
+
+ /* If PNG_PREFIX is defined the same thing as below happens in pnglibconf.h,
+ * but defining a macro name prefixed with PNG_PREFIX.
+ */
+# ifndef PNG_PREFIX
+# define png_get_uint_32(buf) PNG_get_uint_32(buf)
+# define png_get_uint_16(buf) PNG_get_uint_16(buf)
+# define png_get_int_32(buf) PNG_get_int_32(buf)
+# endif
+#else
+# ifdef PNG_PREFIX
+ /* No macros; revert to the (redefined) function */
+# define PNG_get_uint_32 (png_get_uint_32)
+# define PNG_get_uint_16 (png_get_uint_16)
+# define PNG_get_int_32 (png_get_int_32)
+# endif
+#endif
+
+/*******************************************************************************
+ * SIMPLIFIED API
+ *******************************************************************************
+ *
+ * Please read the documentation in libpng-manual.txt (TODO: write said
+ * documentation) if you don't understand what follows.
+ *
+ * The simplified API hides the details of both libpng and the PNG file format
+ * itself. It allows PNG files to be read into a very limited number of
+ * in-memory bitmap formats or to be written from the same formats. If these
+ * formats do not accomodate your needs then you can, and should, use the more
+ * sophisticated APIs above - these support a wide variety of in-memory formats
+ * and a wide variety of sophisticated transformations to those formats as well
+ * as a wide variety of APIs to manipulate ancillary information.
+ *
+ * To read a PNG file using the simplified API:
+ *
+ * 1) Declare a 'png_image' structure (see below) on the stack and set the
+ * version field to PNG_IMAGE_VERSION.
+ * 2) Call the appropriate png_image_begin_read... function.
+ * 3) Set the png_image 'format' member to the required sample format.
+ * 4) Allocate a buffer for the image and, if required, the color-map.
+ * 5) Call png_image_finish_read to read the image and, if required, the
+ * color-map into your buffers.
+ *
+ * There are no restrictions on the format of the PNG input itself; all valid
+ * color types, bit depths, and interlace methods are acceptable, and the
+ * input image is transformed as necessary to the requested in-memory format
+ * during the png_image_finish_read() step. The only caveat is that if you
+ * request a color-mapped image from a PNG that is full-color or makes
+ * complex use of an alpha channel the transformation is extremely lossy and the
+ * result may look terrible.
+ *
+ * To write a PNG file using the simplified API:
+ *
+ * 1) Declare a 'png_image' structure on the stack and memset() it to all zero.
+ * 2) Initialize the members of the structure that describe the image, setting
+ * the 'format' member to the format of the image samples.
+ * 3) Call the appropriate png_image_write... function with a pointer to the
+ * image and, if necessary, the color-map to write the PNG data.
+ *
+ * png_image is a structure that describes the in-memory format of an image
+ * when it is being read or defines the in-memory format of an image that you
+ * need to write:
+ */
+#define PNG_IMAGE_VERSION 1
+
+typedef struct png_control *png_controlp;
+typedef struct
+{
+ png_controlp opaque; /* Initialize to NULL, free with png_image_free */
+ png_uint_32 version; /* Set to PNG_IMAGE_VERSION */
+ png_uint_32 width; /* Image width in pixels (columns) */
+ png_uint_32 height; /* Image height in pixels (rows) */
+ png_uint_32 format; /* Image format as defined below */
+ png_uint_32 flags; /* A bit mask containing informational flags */
+ png_uint_32 colormap_entries;
+ /* Number of entries in the color-map */
+
+ /* In the event of an error or warning the following field will be set to a
+ * non-zero value and the 'message' field will contain a '\0' terminated
+ * string with the libpng error or warning message. If both warnings and
+ * an error were encountered, only the error is recorded. If there
+ * are multiple warnings, only the first one is recorded.
+ *
+ * The upper 30 bits of this value are reserved, the low two bits contain
+ * a value as follows:
+ */
+# define PNG_IMAGE_WARNING 1
+# define PNG_IMAGE_ERROR 2
+ /*
+ * The result is a two bit code such that a value more than 1 indicates
+ * a failure in the API just called:
+ *
+ * 0 - no warning or error
+ * 1 - warning
+ * 2 - error
+ * 3 - error preceded by warning
+ */
+# define PNG_IMAGE_FAILED(png_cntrl) ((((png_cntrl).warning_or_error)&0x03)>1)
+
+ png_uint_32 warning_or_error;
+
+ char message[64];
+} png_image, *png_imagep;
+
+/* The samples of the image have one to four channels whose components have
+ * original values in the range 0 to 1.0:
+ *
+ * 1: A single gray or luminance channel (G).
+ * 2: A gray/luminance channel and an alpha channel (GA).
+ * 3: Three red, green, blue color channels (RGB).
+ * 4: Three color channels and an alpha channel (RGBA).
+ *
+ * The components are encoded in one of two ways:
+ *
+ * a) As a small integer, value 0..255, contained in a single byte. For the
+ * alpha channel the original value is simply value/255. For the color or
+ * luminance channels the value is encoded according to the sRGB specification
+ * and matches the 8-bit format expected by typical display devices.
+ *
+ * The color/gray channels are not scaled (pre-multiplied) by the alpha
+ * channel and are suitable for passing to color management software.
+ *
+ * b) As a value in the range 0..65535, contained in a 2-byte integer. All
+ * channels can be converted to the original value by dividing by 65535; all
+ * channels are linear. Color channels use the RGB encoding (RGB end-points) of
+ * the sRGB specification. This encoding is identified by the
+ * PNG_FORMAT_FLAG_LINEAR flag below.
+ *
+ * When the simplified API needs to convert between sRGB and linear colorspaces,
+ * the actual sRGB transfer curve defined in the sRGB specification (see the
+ * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+ * approximation used elsewhere in libpng.
+ *
+ * When an alpha channel is present it is expected to denote pixel coverage
+ * of the color or luminance channels and is returned as an associated alpha
+ * channel: the color/gray channels are scaled (pre-multiplied) by the alpha
+ * value.
+ *
+ * The samples are either contained directly in the image data, between 1 and 8
+ * bytes per pixel according to the encoding, or are held in a color-map indexed
+ * by bytes in the image data. In the case of a color-map the color-map entries
+ * are individual samples, encoded as above, and the image data has one byte per
+ * pixel to select the relevant sample from the color-map.
+ */
+
+/* PNG_FORMAT_*
+ *
+ * #defines to be used in png_image::format. Each #define identifies a
+ * particular layout of sample data and, if present, alpha values. There are
+ * separate defines for each of the two component encodings.
+ *
+ * A format is built up using single bit flag values. All combinations are
+ * valid. Formats can be built up from the flag values or you can use one of
+ * the predefined values below. When testing formats always use the FORMAT_FLAG
+ * macros to test for individual features - future versions of the library may
+ * add new flags.
+ *
+ * When reading or writing color-mapped images the format should be set to the
+ * format of the entries in the color-map then png_image_{read,write}_colormap
+ * called to read or write the color-map and set the format correctly for the
+ * image data. Do not set the PNG_FORMAT_FLAG_COLORMAP bit directly!
+ *
+ * NOTE: libpng can be built with particular features disabled, if you see
+ * compiler errors because the definition of one of the following flags has been
+ * compiled out it is because libpng does not have the required support. It is
+ * possible, however, for the libpng configuration to enable the format on just
+ * read or just write; in that case you may see an error at run time. You can
+ * guard against this by checking for the definition of the appropriate
+ * "_SUPPORTED" macro, one of:
+ *
+ * PNG_SIMPLIFIED_{READ,WRITE}_{BGR,AFIRST}_SUPPORTED
+ */
+#define PNG_FORMAT_FLAG_ALPHA 0x01U /* format with an alpha channel */
+#define PNG_FORMAT_FLAG_COLOR 0x02U /* color format: otherwise grayscale */
+#define PNG_FORMAT_FLAG_LINEAR 0x04U /* 2 byte channels else 1 byte */
+#define PNG_FORMAT_FLAG_COLORMAP 0x08U /* image data is color-mapped */
+
+#ifdef PNG_FORMAT_BGR_SUPPORTED
+# define PNG_FORMAT_FLAG_BGR 0x10U /* BGR colors, else order is RGB */
+#endif
+
+#ifdef PNG_FORMAT_AFIRST_SUPPORTED
+# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
+#endif
+
+/* Commonly used formats have predefined macros.
+ *
+ * First the single byte (sRGB) formats:
+ */
+#define PNG_FORMAT_GRAY 0
+#define PNG_FORMAT_GA PNG_FORMAT_FLAG_ALPHA
+#define PNG_FORMAT_AG (PNG_FORMAT_GA|PNG_FORMAT_FLAG_AFIRST)
+#define PNG_FORMAT_RGB PNG_FORMAT_FLAG_COLOR
+#define PNG_FORMAT_BGR (PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_BGR)
+#define PNG_FORMAT_RGBA (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_ARGB (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_AFIRST)
+#define PNG_FORMAT_BGRA (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_ABGR (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_AFIRST)
+
+/* Then the linear 2-byte formats. When naming these "Y" is used to
+ * indicate a luminance (gray) channel.
+ */
+#define PNG_FORMAT_LINEAR_Y PNG_FORMAT_FLAG_LINEAR
+#define PNG_FORMAT_LINEAR_Y_ALPHA (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_ALPHA)
+#define PNG_FORMAT_LINEAR_RGB (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR)
+#define PNG_FORMAT_LINEAR_RGB_ALPHA \
+ (PNG_FORMAT_FLAG_LINEAR|PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA)
+
+/* With color-mapped formats the image data is one byte for each pixel, the byte
+ * is an index into the color-map which is formatted as above. To obtain a
+ * color-mapped format it is sufficient just to add the PNG_FOMAT_FLAG_COLORMAP
+ * to one of the above definitions, or you can use one of the definitions below.
+ */
+#define PNG_FORMAT_RGB_COLORMAP (PNG_FORMAT_RGB|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_BGR_COLORMAP (PNG_FORMAT_BGR|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_RGBA_COLORMAP (PNG_FORMAT_RGBA|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_ARGB_COLORMAP (PNG_FORMAT_ARGB|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_BGRA_COLORMAP (PNG_FORMAT_BGRA|PNG_FORMAT_FLAG_COLORMAP)
+#define PNG_FORMAT_ABGR_COLORMAP (PNG_FORMAT_ABGR|PNG_FORMAT_FLAG_COLORMAP)
+
+/* PNG_IMAGE macros
+ *
+ * These are convenience macros to derive information from a png_image
+ * structure. The PNG_IMAGE_SAMPLE_ macros return values appropriate to the
+ * actual image sample values - either the entries in the color-map or the
+ * pixels in the image. The PNG_IMAGE_PIXEL_ macros return corresponding values
+ * for the pixels and will always return 1 for color-mapped formats. The
+ * remaining macros return information about the rows in the image and the
+ * complete image.
+ *
+ * NOTE: All the macros that take a png_image::format parameter are compile time
+ * constants if the format parameter is, itself, a constant. Therefore these
+ * macros can be used in array declarations and case labels where required.
+ * Similarly the macros are also pre-processor constants (sizeof is not used) so
+ * they can be used in #if tests.
+ *
+ * First the information about the samples.
+ */
+#define PNG_IMAGE_SAMPLE_CHANNELS(fmt)\
+ (((fmt)&(PNG_FORMAT_FLAG_COLOR|PNG_FORMAT_FLAG_ALPHA))+1)
+ /* Return the total number of channels in a given format: 1..4 */
+
+#define PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt)\
+ ((((fmt) & PNG_FORMAT_FLAG_LINEAR) >> 2)+1)
+ /* Return the size in bytes of a single component of a pixel or color-map
+ * entry (as appropriate) in the image: 1 or 2.
+ */
+
+#define PNG_IMAGE_SAMPLE_SIZE(fmt)\
+ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * PNG_IMAGE_SAMPLE_COMPONENT_SIZE(fmt))
+ /* This is the size of the sample data for one sample. If the image is
+ * color-mapped it is the size of one color-map entry (and image pixels are
+ * one byte in size), otherwise it is the size of one image pixel.
+ */
+
+#define PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(fmt)\
+ (PNG_IMAGE_SAMPLE_CHANNELS(fmt) * 256)
+ /* The maximum size of the color-map required by the format expressed in a
+ * count of components. This can be used to compile-time allocate a
+ * color-map:
+ *
+ * png_uint_16 colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(linear_fmt)];
+ *
+ * png_byte colormap[PNG_IMAGE_MAXIMUM_COLORMAP_COMPONENTS(sRGB_fmt)];
+ *
+ * Alternatively use the PNG_IMAGE_COLORMAP_SIZE macro below to use the
+ * information from one of the png_image_begin_read_ APIs and dynamically
+ * allocate the required memory.
+ */
+
+/* Corresponding information about the pixels */
+#define PNG_IMAGE_PIXEL_(test,fmt)\
+ (((fmt)&PNG_FORMAT_FLAG_COLORMAP)?1:test(fmt))
+
+#define PNG_IMAGE_PIXEL_CHANNELS(fmt)\
+ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_CHANNELS,fmt)
+ /* The number of separate channels (components) in a pixel; 1 for a
+ * color-mapped image.
+ */
+
+#define PNG_IMAGE_PIXEL_COMPONENT_SIZE(fmt)\
+ PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_COMPONENT_SIZE,fmt)
+ /* The size, in bytes, of each component in a pixel; 1 for a color-mapped
+ * image.
+ */
+
+#define PNG_IMAGE_PIXEL_SIZE(fmt) PNG_IMAGE_PIXEL_(PNG_IMAGE_SAMPLE_SIZE,fmt)
+ /* The size, in bytes, of a complete pixel; 1 for a color-mapped image. */
+
+/* Information about the whole row, or whole image */
+#define PNG_IMAGE_ROW_STRIDE(image)\
+ (PNG_IMAGE_PIXEL_CHANNELS((image).format) * (image).width)
+ /* Return the total number of components in a single row of the image; this
+ * is the minimum 'row stride', the minimum count of components between each
+ * row. For a color-mapped image this is the minimum number of bytes in a
+ * row.
+ */
+
+#define PNG_IMAGE_BUFFER_SIZE(image, row_stride)\
+ (PNG_IMAGE_PIXEL_COMPONENT_SIZE((image).format)*(image).height*(row_stride))
+ /* Return the size, in bytes, of an image buffer given a png_image and a row
+ * stride - the number of components to leave space for in each row.
+ */
+
+#define PNG_IMAGE_SIZE(image)\
+ PNG_IMAGE_BUFFER_SIZE(image, PNG_IMAGE_ROW_STRIDE(image))
+ /* Return the size, in bytes, of the image in memory given just a png_image;
+ * the row stride is the minimum stride required for the image.
+ */
+
+#define PNG_IMAGE_COLORMAP_SIZE(image)\
+ (PNG_IMAGE_SAMPLE_SIZE((image).format) * (image).colormap_entries)
+ /* Return the size, in bytes, of the color-map of this image. If the image
+ * format is not a color-map format this will return a size sufficient for
+ * 256 entries in the given format; check PNG_FORMAT_FLAG_COLORMAP if
+ * you don't want to allocate a color-map in this case.
+ */
+
+/* PNG_IMAGE_FLAG_*
+ *
+ * Flags containing additional information about the image are held in the
+ * 'flags' field of png_image.
+ */
+#define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01
+ /* This indicates the the RGB values of the in-memory bitmap do not
+ * correspond to the red, green and blue end-points defined by sRGB.
+ */
+
+#define PNG_IMAGE_FLAG_FAST 0x02
+ /* On write emphasise speed over compression; the resultant PNG file will be
+ * larger but will be produced significantly faster, particular for large
+ * images. Do not use this option for images which will be distributed, only
+ * used it when producing intermediate files that will be read back in
+ * repeatedly. For a typical 24-bit image the option will double the read
+ * speed at the cost of increasing the image size by 25%, however for many
+ * more compressible images the PNG file can be 10 times larger with only a
+ * slight speed gain.
+ */
+
+#define PNG_IMAGE_FLAG_16BIT_sRGB 0x04
+ /* On read if the image is a 16-bit per component image and there is no gAMA
+ * or sRGB chunk assume that the components are sRGB encoded. Notice that
+ * images output by the simplified API always have gamma information; setting
+ * this flag only affects the interpretation of 16-bit images from an
+ * external source. It is recommended that the application expose this flag
+ * to the user; the user can normally easily recognize the difference between
+ * linear and sRGB encoding. This flag has no effect on write - the data
+ * passed to the write APIs must have the correct encoding (as defined
+ * above.)
+ *
+ * If the flag is not set (the default) input 16-bit per component data is
+ * assumed to be linear.
+ *
+ * NOTE: the flag can only be set after the png_image_begin_read_ call,
+ * because that call initializes the 'flags' field.
+ */
+
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+/* READ APIs
+ * ---------
+ *
+ * The png_image passed to the read APIs must have been initialized by setting
+ * the png_controlp field 'opaque' to NULL (or, safer, memset the whole thing.)
+ */
+#ifdef PNG_STDIO_SUPPORTED
+PNG_EXPORT(234, int, png_image_begin_read_from_file, (png_imagep image,
+ const char *file_name));
+ /* The named file is opened for read and the image header is filled in
+ * from the PNG header in the file.
+ */
+
+PNG_EXPORT(235, int, png_image_begin_read_from_stdio, (png_imagep image,
+ FILE* file));
+ /* The PNG header is read from the stdio FILE object. */
+#endif /* PNG_STDIO_SUPPORTED */
+
+PNG_EXPORT(236, int, png_image_begin_read_from_memory, (png_imagep image,
+ png_const_voidp memory, png_size_t size));
+ /* The PNG header is read from the given memory buffer. */
+
+PNG_EXPORT(237, int, png_image_finish_read, (png_imagep image,
+ png_const_colorp background, void *buffer, png_int_32 row_stride,
+ void *colormap));
+ /* Finish reading the image into the supplied buffer and clean up the
+ * png_image structure.
+ *
+ * row_stride is the step, in byte or 2-byte units as appropriate,
+ * between adjacent rows. A positive stride indicates that the top-most row
+ * is first in the buffer - the normal top-down arrangement. A negative
+ * stride indicates that the bottom-most row is first in the buffer.
+ *
+ * background need only be supplied if an alpha channel must be removed from
+ * a png_byte format and the removal is to be done by compositing on a solid
+ * color; otherwise it may be NULL and any composition will be done directly
+ * onto the buffer. The value is an sRGB color to use for the background,
+ * for grayscale output the green channel is used.
+ *
+ * background must be supplied when an alpha channel must be removed from a
+ * single byte color-mapped output format, in other words if:
+ *
+ * 1) The original format from png_image_begin_read_from_* had
+ * PNG_FORMAT_FLAG_ALPHA set.
+ * 2) The format set by the application does not.
+ * 3) The format set by the application has PNG_FORMAT_FLAG_COLORMAP set and
+ * PNG_FORMAT_FLAG_LINEAR *not* set.
+ *
+ * For linear output removing the alpha channel is always done by compositing
+ * on black and background is ignored.
+ *
+ * colormap must be supplied when PNG_FORMAT_FLAG_COLORMAP is set. It must
+ * be at least the size (in bytes) returned by PNG_IMAGE_COLORMAP_SIZE.
+ * image->colormap_entries will be updated to the actual number of entries
+ * written to the colormap; this may be less than the original value.
+ */
+
+PNG_EXPORT(238, void, png_image_free, (png_imagep image));
+ /* Free any data allocated by libpng in image->opaque, setting the pointer to
+ * NULL. May be called at any time after the structure is initialized.
+ */
+#endif /* PNG_SIMPLIFIED_READ_SUPPORTED */
+
+#ifdef PNG_SIMPLIFIED_WRITE_SUPPORTED
+#ifdef PNG_STDIO_SUPPORTED
+/* WRITE APIS
+ * ----------
+ * For write you must initialize a png_image structure to describe the image to
+ * be written. To do this use memset to set the whole structure to 0 then
+ * initialize fields describing your image.
+ *
+ * version: must be set to PNG_IMAGE_VERSION
+ * opaque: must be initialized to NULL
+ * width: image width in pixels
+ * height: image height in rows
+ * format: the format of the data (image and color-map) you wish to write
+ * flags: set to 0 unless one of the defined flags applies; set
+ * PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB for color format images where the RGB
+ * values do not correspond to the colors in sRGB.
+ * colormap_entries: set to the number of entries in the color-map (0 to 256)
+ */
+PNG_EXPORT(239, int, png_image_write_to_file, (png_imagep image,
+ const char *file, int convert_to_8bit, const void *buffer,
+ png_int_32 row_stride, const void *colormap));
+ /* Write the image to the named file. */
+
+PNG_EXPORT(240, int, png_image_write_to_stdio, (png_imagep image, FILE *file,
+ int convert_to_8_bit, const void *buffer, png_int_32 row_stride,
+ const void *colormap));
+ /* Write the image to the given (FILE*). */
+
+/* With both write APIs if image is in one of the linear formats with 16-bit
+ * data then setting convert_to_8_bit will cause the output to be an 8-bit PNG
+ * gamma encoded according to the sRGB specification, otherwise a 16-bit linear
+ * encoded PNG file is written.
+ *
+ * With color-mapped data formats the colormap parameter point to a color-map
+ * with at least image->colormap_entries encoded in the specified format. If
+ * the format is linear the written PNG color-map will be converted to sRGB
+ * regardless of the convert_to_8_bit flag.
+ *
+ * With all APIs row_stride is handled as in the read APIs - it is the spacing
+ * from one row to the next in component sized units (1 or 2 bytes) and if
+ * negative indicates a bottom-up row layout in the buffer.
+ *
+ * Note that the write API does not support interlacing or sub-8-bit pixels.
+ */
+#endif /* PNG_STDIO_SUPPORTED */
+#endif /* PNG_SIMPLIFIED_WRITE_SUPPORTED */
+/*******************************************************************************
+ * END OF SIMPLIFIED API
+ ******************************************************************************/
+
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+PNG_EXPORT(242, void, png_set_check_for_invalid_index,
+ (png_structrp png_ptr, int allowed));
+# ifdef PNG_GET_PALETTE_MAX_SUPPORTED
+PNG_EXPORT(243, int, png_get_palette_max, (png_const_structp png_ptr,
+ png_const_infop info_ptr));
+# endif
+#endif /* CHECK_FOR_INVALID_INDEX */
+
+/*******************************************************************************
+ * IMPLEMENTATION OPTIONS
+ *******************************************************************************
+ *
+ * Support for arbitrary implementation-specific optimizations. The API allows
+ * particular options to be turned on or off. 'Option' is the number of the
+ * option and 'onoff' is 0 (off) or non-0 (on). The value returned is given
+ * by the PNG_OPTION_ defines below.
+ *
+ * HARDWARE: normally hardware capabilites, such as the Intel SSE instructions,
+ * are detected at run time, however sometimes it may be impossible
+ * to do this in user mode, in which case it is necessary to discover
+ * the capabilities in an OS specific way. Such capabilities are
+ * listed here when libpng has support for them and must be turned
+ * ON by the application if present.
+ *
+ * SOFTWARE: sometimes software optimizations actually result in performance
+ * decrease on some architectures or systems, or with some sets of
+ * PNG images. 'Software' options allow such optimizations to be
+ * selected at run time.
+ */
+#ifdef PNG_SET_OPTION_SUPPORTED
+#ifdef PNG_ARM_NEON_API_SUPPORTED
+# define PNG_ARM_NEON 0 /* HARDWARE: ARM Neon SIMD instructions supported */
+#endif
+#define PNG_MAXIMUM_INFLATE_WINDOW 2 /* SOFTWARE: force maximum window */
+#define PNG_OPTION_NEXT 4 /* Next option - numbers must be even */
+
+/* Return values: NOTE: there are four values and 'off' is *not* zero */
+#define PNG_OPTION_UNSET 0 /* Unset - defaults to off */
+#define PNG_OPTION_INVALID 1 /* Option number out of range */
+#define PNG_OPTION_OFF 2
+#define PNG_OPTION_ON 3
+
+PNG_EXPORT(244, int, png_set_option, (png_structrp png_ptr, int option,
+ int onoff));
+#endif
+
+/*******************************************************************************
+ * END OF HARDWARE OPTIONS
+ ******************************************************************************/
+
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and project
+ * defs, scripts/pnglibconf.h, and scripts/pnglibconf.h.prebuilt
+ */
+
+/* The last ordinal number (this is the *last* one already used; the next
+ * one to use is one more than this.) Maintainer, remember to add an entry to
+ * scripts/symbols.def as well.
+ */
+#ifdef PNG_EXPORT_LAST_ORDINAL
+ PNG_EXPORT_LAST_ORDINAL(244);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* Do not put anything past this line */
+#endif /* PNG_H */
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/pngconf.h b/core/src/fxcodec/fx_lpng/lpng_v163/pngconf.h
new file mode 100644
index 0000000000..02f74e2639
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/pngconf.h
@@ -0,0 +1,617 @@
+
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng version 1.6.3 - July 18, 2013
+ *
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ *
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+/* To do: Do all of this in scripts/pnglibconf.dfa */
+#ifdef PNG_SAFE_LIMITS_SUPPORTED
+# ifdef PNG_USER_WIDTH_MAX
+# undef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 1000000L
+# endif
+# ifdef PNG_USER_HEIGHT_MAX
+# undef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 1000000L
+# endif
+# ifdef PNG_USER_CHUNK_MALLOC_MAX
+# undef PNG_USER_CHUNK_MALLOC_MAX
+# define PNG_USER_CHUNK_MALLOC_MAX 4000000L
+# endif
+# ifdef PNG_USER_CHUNK_CACHE_MAX
+# undef PNG_USER_CHUNK_CACHE_MAX
+# define PNG_USER_CHUNK_CACHE_MAX 128
+# endif
+#endif
+
+#ifndef PNG_BUILDING_SYMBOL_TABLE /* else includes may cause problems */
+
+/* From libpng 1.6.0 libpng requires an ANSI X3.159-1989 ("ISOC90") compliant C
+ * compiler for correct compilation. The following header files are required by
+ * the standard. If your compiler doesn't provide these header files, or they
+ * do not match the standard, you will need to provide/improve them.
+ */
+#include <limits.h>
+#include <stddef.h>
+
+/* Library header files. These header files are all defined by ISOC90; libpng
+ * expects conformant implementations, however, an ISOC90 conformant system need
+ * not provide these header files if the functionality cannot be implemented.
+ * In this case it will be necessary to disable the relevant parts of libpng in
+ * the build of pnglibconf.h.
+ *
+ * Prior to 1.6.0 string.h was included here; the API changes in 1.6.0 to not
+ * include this unnecessary header file.
+ */
+
+#ifdef PNG_STDIO_SUPPORTED
+ /* Required for the definition of FILE: */
+# include <stdio.h>
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* Required for the definition of jmp_buf and the declaration of longjmp: */
+# include <setjmp.h>
+#endif
+
+#ifdef PNG_CONVERT_tIME_SUPPORTED
+ /* Required for struct tm: */
+# include <time.h>
+#endif
+
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
+
+/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using
+ * PNG_NO_CONST; this is no longer supported except for data declarations which
+ * apparently still cause problems in 2011 on some compilers.
+ */
+#define PNG_CONST const /* backward compatibility only */
+
+/* This controls optimization of the reading of 16 and 32 bit values
+ * from PNG files. It can be set on a per-app-file basis - it
+ * just changes whether a macro is used when the function is called.
+ * The library builder sets the default; if read functions are not
+ * built into the library the macro implementation is forced on.
+ */
+#ifndef PNG_READ_INT_FUNCTIONS_SUPPORTED
+# define PNG_USE_READ_MACROS
+#endif
+#if !defined(PNG_NO_USE_READ_MACROS) && !defined(PNG_USE_READ_MACROS)
+# if PNG_DEFAULT_READ_MACROS
+# define PNG_USE_READ_MACROS
+# endif
+#endif
+
+/* COMPILER SPECIFIC OPTIONS.
+ *
+ * These options are provided so that a variety of difficult compilers
+ * can be used. Some are fixed at build time (e.g. PNG_API_RULE
+ * below) but still have compiler specific implementations, others
+ * may be changed on a per-file basis when compiling against libpng.
+ */
+
+/* The PNGARG macro was used in versions of libpng prior to 1.6.0 to protect
+ * against legacy (pre ISOC90) compilers that did not understand function
+ * prototypes. It is not required for modern C compilers.
+ */
+#ifndef PNGARG
+# define PNGARG(arglist) arglist
+#endif
+
+/* Function calling conventions.
+ * =============================
+ * Normally it is not necessary to specify to the compiler how to call
+ * a function - it just does it - however on x86 systems derived from
+ * Microsoft and Borland C compilers ('IBM PC', 'DOS', 'Windows' systems
+ * and some others) there are multiple ways to call a function and the
+ * default can be changed on the compiler command line. For this reason
+ * libpng specifies the calling convention of every exported function and
+ * every function called via a user supplied function pointer. This is
+ * done in this file by defining the following macros:
+ *
+ * PNGAPI Calling convention for exported functions.
+ * PNGCBAPI Calling convention for user provided (callback) functions.
+ * PNGCAPI Calling convention used by the ANSI-C library (required
+ * for longjmp callbacks and sometimes used internally to
+ * specify the calling convention for zlib).
+ *
+ * These macros should never be overridden. If it is necessary to
+ * change calling convention in a private build this can be done
+ * by setting PNG_API_RULE (which defaults to 0) to one of the values
+ * below to select the correct 'API' variants.
+ *
+ * PNG_API_RULE=0 Use PNGCAPI - the 'C' calling convention - throughout.
+ * This is correct in every known environment.
+ * PNG_API_RULE=1 Use the operating system convention for PNGAPI and
+ * the 'C' calling convention (from PNGCAPI) for
+ * callbacks (PNGCBAPI). This is no longer required
+ * in any known environment - if it has to be used
+ * please post an explanation of the problem to the
+ * libpng mailing list.
+ *
+ * These cases only differ if the operating system does not use the C
+ * calling convention, at present this just means the above cases
+ * (x86 DOS/Windows sytems) and, even then, this does not apply to
+ * Cygwin running on those systems.
+ *
+ * Note that the value must be defined in pnglibconf.h so that what
+ * the application uses to call the library matches the conventions
+ * set when building the library.
+ */
+
+/* Symbol export
+ * =============
+ * When building a shared library it is almost always necessary to tell
+ * the compiler which symbols to export. The png.h macro 'PNG_EXPORT'
+ * is used to mark the symbols. On some systems these symbols can be
+ * extracted at link time and need no special processing by the compiler,
+ * on other systems the symbols are flagged by the compiler and just
+ * the declaration requires a special tag applied (unfortunately) in a
+ * compiler dependent way. Some systems can do either.
+ *
+ * A small number of older systems also require a symbol from a DLL to
+ * be flagged to the program that calls it. This is a problem because
+ * we do not know in the header file included by application code that
+ * the symbol will come from a shared library, as opposed to a statically
+ * linked one. For this reason the application must tell us by setting
+ * the magic flag PNG_USE_DLL to turn on the special processing before
+ * it includes png.h.
+ *
+ * Four additional macros are used to make this happen:
+ *
+ * PNG_IMPEXP The magic (if any) to cause a symbol to be exported from
+ * the build or imported if PNG_USE_DLL is set - compiler
+ * and system specific.
+ *
+ * PNG_EXPORT_TYPE(type) A macro that pre or appends PNG_IMPEXP to
+ * 'type', compiler specific.
+ *
+ * PNG_DLL_EXPORT Set to the magic to use during a libpng build to
+ * make a symbol exported from the DLL. Not used in the
+ * public header files; see pngpriv.h for how it is used
+ * in the libpng build.
+ *
+ * PNG_DLL_IMPORT Set to the magic to force the libpng symbols to come
+ * from a DLL - used to define PNG_IMPEXP when
+ * PNG_USE_DLL is set.
+ */
+
+/* System specific discovery.
+ * ==========================
+ * This code is used at build time to find PNG_IMPEXP, the API settings
+ * and PNG_EXPORT_TYPE(), it may also set a macro to indicate the DLL
+ * import processing is possible. On Windows systems it also sets
+ * compiler-specific macros to the values required to change the calling
+ * conventions of the various functions.
+ */
+#if defined(_Windows) || defined(_WINDOWS) || defined(WIN32) ||\
+ defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+ /* Windows system (DOS doesn't support DLLs). Includes builds under Cygwin or
+ * MinGW on any architecture currently supported by Windows. Also includes
+ * Watcom builds but these need special treatment because they are not
+ * compatible with GCC or Visual C because of different calling conventions.
+ */
+# if PNG_API_RULE == 2
+ /* If this line results in an error, either because __watcall is not
+ * understood or because of a redefine just below you cannot use *this*
+ * build of the library with the compiler you are using. *This* build was
+ * build using Watcom and applications must also be built using Watcom!
+ */
+# define PNGCAPI __watcall
+# endif
+
+# if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 800))
+# define PNGCAPI __cdecl
+# if PNG_API_RULE == 1
+ /* If this line results in an error __stdcall is not understood and
+ * PNG_API_RULE should not have been set to '1'.
+ */
+# define PNGAPI __stdcall
+# endif
+# else
+ /* An older compiler, or one not detected (erroneously) above,
+ * if necessary override on the command line to get the correct
+ * variants for the compiler.
+ */
+# ifndef PNGCAPI
+# define PNGCAPI _cdecl
+# endif
+# if PNG_API_RULE == 1 && !defined(PNGAPI)
+# define PNGAPI _stdcall
+# endif
+# endif /* compiler/api */
+
+ /* NOTE: PNGCBAPI always defaults to PNGCAPI. */
+
+# if defined(PNGAPI) && !defined(PNG_USER_PRIVATEBUILD)
+# error "PNG_USER_PRIVATEBUILD must be defined if PNGAPI is changed"
+# endif
+
+# if (defined(_MSC_VER) && _MSC_VER < 800) ||\
+ (defined(__BORLANDC__) && __BORLANDC__ < 0x500)
+ /* older Borland and MSC
+ * compilers used '__export' and required this to be after
+ * the type.
+ */
+# ifndef PNG_EXPORT_TYPE
+# define PNG_EXPORT_TYPE(type) type PNG_IMPEXP
+# endif
+# define PNG_DLL_EXPORT __export
+# else /* newer compiler */
+# define PNG_DLL_EXPORT __declspec(dllexport)
+# ifndef PNG_DLL_IMPORT
+# define PNG_DLL_IMPORT __declspec(dllimport)
+# endif
+# endif /* compiler */
+
+#else /* !Windows */
+# if (defined(__IBMC__) || defined(__IBMCPP__)) && defined(__OS2__)
+# define PNGAPI _System
+# else /* !Windows/x86 && !OS/2 */
+ /* Use the defaults, or define PNG*API on the command line (but
+ * this will have to be done for every compile!)
+ */
+# endif /* other system, !OS/2 */
+#endif /* !Windows/x86 */
+
+/* Now do all the defaulting . */
+#ifndef PNGCAPI
+# define PNGCAPI
+#endif
+#ifndef PNGCBAPI
+# define PNGCBAPI PNGCAPI
+#endif
+#ifndef PNGAPI
+# define PNGAPI PNGCAPI
+#endif
+
+/* PNG_IMPEXP may be set on the compilation system command line or (if not set)
+ * then in an internal header file when building the library, otherwise (when
+ * using the library) it is set here.
+ */
+#ifndef PNG_IMPEXP
+# if defined(PNG_USE_DLL) && defined(PNG_DLL_IMPORT)
+ /* This forces use of a DLL, disallowing static linking */
+# define PNG_IMPEXP PNG_DLL_IMPORT
+# endif
+
+# ifndef PNG_IMPEXP
+# define PNG_IMPEXP
+# endif
+#endif
+
+/* In 1.5.2 the definition of PNG_FUNCTION has been changed to always treat
+ * 'attributes' as a storage class - the attributes go at the start of the
+ * function definition, and attributes are always appended regardless of the
+ * compiler. This considerably simplifies these macros but may cause problems
+ * if any compilers both need function attributes and fail to handle them as
+ * a storage class (this is unlikely.)
+ */
+#ifndef PNG_FUNCTION
+# define PNG_FUNCTION(type, name, args, attributes) attributes type name args
+#endif
+
+#ifndef PNG_EXPORT_TYPE
+# define PNG_EXPORT_TYPE(type) PNG_IMPEXP type
+#endif
+
+ /* The ordinal value is only relevant when preprocessing png.h for symbol
+ * table entries, so we discard it here. See the .dfn files in the
+ * scripts directory.
+ */
+#ifndef PNG_EXPORTA
+
+# define PNG_EXPORTA(ordinal, type, name, args, attributes)\
+ PNG_FUNCTION(PNG_EXPORT_TYPE(type),(PNGAPI name),PNGARG(args), \
+ extern attributes)
+#endif
+
+/* ANSI-C (C90) does not permit a macro to be invoked with an empty argument,
+ * so make something non-empty to satisfy the requirement:
+ */
+#define PNG_EMPTY /*empty list*/
+
+#define PNG_EXPORT(ordinal, type, name, args)\
+ PNG_EXPORTA(ordinal, type, name, args, PNG_EMPTY)
+
+/* Use PNG_REMOVED to comment out a removed interface. */
+#ifndef PNG_REMOVED
+# define PNG_REMOVED(ordinal, type, name, args, attributes)
+#endif
+
+#ifndef PNG_CALLBACK
+# define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) PNGARG(args)
+#endif
+
+/* Support for compiler specific function attributes. These are used
+ * so that where compiler support is available incorrect use of API
+ * functions in png.h will generate compiler warnings.
+ *
+ * Added at libpng-1.2.41.
+ */
+
+#ifndef PNG_NO_PEDANTIC_WARNINGS
+# ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED
+# define PNG_PEDANTIC_WARNINGS_SUPPORTED
+# endif
+#endif
+
+#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED
+ /* Support for compiler specific function attributes. These are used
+ * so that where compiler support is available, incorrect use of API
+ * functions in png.h will generate compiler warnings. Added at libpng
+ * version 1.2.41. Disabling these removes the warnings but may also produce
+ * less efficient code.
+ */
+# if defined(__GNUC__)
+# ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT __attribute__((__warn_unused_result__))
+# endif
+# ifndef PNG_NORETURN
+# define PNG_NORETURN __attribute__((__noreturn__))
+# endif
+# if __GNUC__ >= 3
+# ifndef PNG_ALLOCATED
+# define PNG_ALLOCATED __attribute__((__malloc__))
+# endif
+# ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED __attribute__((__deprecated__))
+# endif
+# ifndef PNG_PRIVATE
+# if 0 /* Doesn't work so we use deprecated instead*/
+# define PNG_PRIVATE \
+ __attribute__((warning("This function is not exported by libpng.")))
+# else
+# define PNG_PRIVATE \
+ __attribute__((__deprecated__))
+# endif
+# endif
+# if ((__GNUC__ != 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1))
+# ifndef PNG_RESTRICT
+# define PNG_RESTRICT __restrict
+# endif
+# endif /* __GNUC__ == 3.0 */
+# endif /* __GNUC__ >= 3 */
+
+# elif defined(_MSC_VER) && (_MSC_VER >= 1300)
+# ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT /* not supported */
+# endif
+# ifndef PNG_NORETURN
+# define PNG_NORETURN __declspec(noreturn)
+# endif
+# ifndef PNG_ALLOCATED
+# if (_MSC_VER >= 1400)
+# define PNG_ALLOCATED __declspec(restrict)
+# endif
+# endif
+# ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED __declspec(deprecated)
+# endif
+# ifndef PNG_PRIVATE
+# define PNG_PRIVATE __declspec(deprecated)
+# endif
+# ifndef PNG_RESTRICT
+# if (_MSC_VER >= 1400)
+# define PNG_RESTRICT __restrict
+# endif
+# endif
+
+# elif defined(__WATCOMC__)
+# ifndef PNG_RESTRICT
+# define PNG_RESTRICT __restrict
+# endif
+# endif /* _MSC_VER */
+#endif /* PNG_PEDANTIC_WARNINGS */
+
+#ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED /* Use of this function is deprecated */
+#endif
+#ifndef PNG_USE_RESULT
+# define PNG_USE_RESULT /* The result of this function must be checked */
+#endif
+#ifndef PNG_NORETURN
+# define PNG_NORETURN /* This function does not return */
+#endif
+#ifndef PNG_ALLOCATED
+# define PNG_ALLOCATED /* The result of the function is new memory */
+#endif
+#ifndef PNG_PRIVATE
+# define PNG_PRIVATE /* This is a private libpng function */
+#endif
+#ifndef PNG_RESTRICT
+# define PNG_RESTRICT /* The C99 "restrict" feature */
+#endif
+#ifndef PNG_FP_EXPORT /* A floating point API. */
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+# define PNG_FP_EXPORT(ordinal, type, name, args)\
+ PNG_EXPORT(ordinal, type, name, args);
+# else /* No floating point APIs */
+# define PNG_FP_EXPORT(ordinal, type, name, args)
+# endif
+#endif
+#ifndef PNG_FIXED_EXPORT /* A fixed point API. */
+# ifdef PNG_FIXED_POINT_SUPPORTED
+# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
+ PNG_EXPORT(ordinal, type, name, args);
+# else /* No fixed point APIs */
+# define PNG_FIXED_EXPORT(ordinal, type, name, args)
+# endif
+#endif
+
+#ifndef PNG_BUILDING_SYMBOL_TABLE
+/* Some typedefs to get us started. These should be safe on most of the common
+ * platforms.
+ *
+ * png_uint_32 and png_int_32 may, currently, be larger than required to hold a
+ * 32-bit value however this is not normally advisable.
+ *
+ * png_uint_16 and png_int_16 should always be two bytes in size - this is
+ * verified at library build time.
+ *
+ * png_byte must always be one byte in size.
+ *
+ * The checks below use constants from limits.h, as defined by the ISOC90
+ * standard.
+ */
+#if CHAR_BIT == 8 && UCHAR_MAX == 255
+ typedef unsigned char png_byte;
+#else
+# error "libpng requires 8 bit bytes"
+#endif
+
+#if INT_MIN == -32768 && INT_MAX == 32767
+ typedef int png_int_16;
+#elif SHRT_MIN == -32768 && SHRT_MAX == 32767
+ typedef short png_int_16;
+#else
+# error "libpng requires a signed 16 bit type"
+#endif
+
+#if UINT_MAX == 65535
+ typedef unsigned int png_uint_16;
+#elif USHRT_MAX == 65535
+ typedef unsigned short png_uint_16;
+#else
+# error "libpng requires an unsigned 16 bit type"
+#endif
+
+#if INT_MIN < -2147483646 && INT_MAX > 2147483646
+ typedef int png_int_32;
+#elif LONG_MIN < -2147483646 && LONG_MAX > 2147483646
+ typedef long int png_int_32;
+#else
+# error "libpng requires a signed 32 bit (or more) type"
+#endif
+
+#if UINT_MAX > 4294967294
+ typedef unsigned int png_uint_32;
+#elif ULONG_MAX > 4294967294
+ typedef unsigned long int png_uint_32;
+#else
+# error "libpng requires an unsigned 32 bit (or more) type"
+#endif
+
+/* Prior to 1.6.0 it was possible to disable the use of size_t, 1.6.0, however,
+ * requires an ISOC90 compiler and relies on consistent behavior of sizeof.
+ */
+typedef size_t png_size_t;
+typedef ptrdiff_t png_ptrdiff_t;
+
+/* libpng needs to know the maximum value of 'size_t' and this controls the
+ * definition of png_alloc_size_t, below. This maximum value of size_t limits
+ * but does not control the maximum allocations the library makes - there is
+ * direct application control of this through png_set_user_limits().
+ */
+#ifndef PNG_SMALL_SIZE_T
+ /* Compiler specific tests for systems where size_t is known to be less than
+ * 32 bits (some of these systems may no longer work because of the lack of
+ * 'far' support; see above.)
+ */
+# if (defined(__TURBOC__) && !defined(__FLAT__)) ||\
+ (defined(_MSC_VER) && defined(MAXSEG_64K))
+# define PNG_SMALL_SIZE_T
+# endif
+#endif
+
+/* png_alloc_size_t is guaranteed to be no smaller than png_size_t, and no
+ * smaller than png_uint_32. Casts from png_size_t or png_uint_32 to
+ * png_alloc_size_t are not necessary; in fact, it is recommended not to use
+ * them at all so that the compiler can complain when something turns out to be
+ * problematic.
+ *
+ * Casts in the other direction (from png_alloc_size_t to png_size_t or
+ * png_uint_32) should be explicitly applied; however, we do not expect to
+ * encounter practical situations that require such conversions.
+ *
+ * PNG_SMALL_SIZE_T must be defined if the maximum value of size_t is less than
+ * 4294967295 - i.e. less than the maximum value of png_uint_32.
+ */
+#ifdef PNG_SMALL_SIZE_T
+ typedef png_uint_32 png_alloc_size_t;
+#else
+ typedef png_size_t png_alloc_size_t;
+#endif
+
+/* Prior to 1.6.0 libpng offered limited support for Microsoft C compiler
+ * implementations of Intel CPU specific support of user-mode segmented address
+ * spaces, where 16-bit pointers address more than 65536 bytes of memory using
+ * separate 'segment' registers. The implementation requires two different
+ * types of pointer (only one of which includes the segment value.)
+ *
+ * If required this support is available in version 1.2 of libpng and may be
+ * available in versions through 1.5, although the correctness of the code has
+ * not been verified recently.
+ */
+
+/* Typedef for floating-point numbers that are converted to fixed-point with a
+ * multiple of 100,000, e.g., gamma
+ */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void * png_voidp;
+typedef const void * png_const_voidp;
+typedef png_byte * png_bytep;
+typedef const png_byte * png_const_bytep;
+typedef png_uint_32 * png_uint_32p;
+typedef const png_uint_32 * png_const_uint_32p;
+typedef png_int_32 * png_int_32p;
+typedef const png_int_32 * png_const_int_32p;
+typedef png_uint_16 * png_uint_16p;
+typedef const png_uint_16 * png_const_uint_16p;
+typedef png_int_16 * png_int_16p;
+typedef const png_int_16 * png_const_int_16p;
+typedef char * png_charp;
+typedef const char * png_const_charp;
+typedef png_fixed_point * png_fixed_point_p;
+typedef const png_fixed_point * png_const_fixed_point_p;
+typedef png_size_t * png_size_tp;
+typedef const png_size_t * png_const_size_tp;
+
+#ifdef PNG_STDIO_SUPPORTED
+typedef FILE * png_FILE_p;
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double * png_doublep;
+typedef const double * png_const_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte * * png_bytepp;
+typedef png_uint_32 * * png_uint_32pp;
+typedef png_int_32 * * png_int_32pp;
+typedef png_uint_16 * * png_uint_16pp;
+typedef png_int_16 * * png_int_16pp;
+typedef const char * * png_const_charpp;
+typedef char * * png_charpp;
+typedef png_fixed_point * * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double * * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char * * * png_charppp;
+
+#endif /* PNG_BUILDING_SYMBOL_TABLE */
+
+#endif /* PNGCONF_H */
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/pngdebug.h b/core/src/fxcodec/fx_lpng/lpng_v163/pngdebug.h
new file mode 100644
index 0000000000..96c1ea42b3
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/pngdebug.h
@@ -0,0 +1,157 @@
+
+/* pngdebug.h - Debugging macros for libpng, also used in pngtest.c
+ *
+ * Copyright (c) 1998-2011 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.5.0 [January 6, 2011]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* Define PNG_DEBUG at compile time for debugging information. Higher
+ * numbers for PNG_DEBUG mean more debugging information. This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ *
+ * png_debug[1-2]?(level, message ,arg{0-2})
+ * Expands to a statement (either a simple expression or a compound
+ * do..while(0) statement) that outputs a message with parameter
+ * substitution if PNG_DEBUG is defined to 2 or more. If PNG_DEBUG
+ * is undefined, 0 or 1 every png_debug expands to a simple expression
+ * (actually ((void)0)).
+ *
+ * level: level of detail of message, starting at 0. A level 'n'
+ * message is preceded by 'n' tab characters (not implemented
+ * on Microsoft compilers unless PNG_DEBUG_FILE is also
+ * defined, to allow debug DLL compilation with no standard IO).
+ * message: a printf(3) style text string. A trailing '\n' is added
+ * to the message.
+ * arg: 0 to 2 arguments for printf(3) style substitution in message.
+ */
+#ifndef PNGDEBUG_H
+#define PNGDEBUG_H
+/* These settings control the formatting of messages in png.c and pngerror.c */
+/* Moved to pngdebug.h at 1.5.0 */
+# ifndef PNG_LITERAL_SHARP
+# define PNG_LITERAL_SHARP 0x23
+# endif
+# ifndef PNG_LITERAL_LEFT_SQUARE_BRACKET
+# define PNG_LITERAL_LEFT_SQUARE_BRACKET 0x5b
+# endif
+# ifndef PNG_LITERAL_RIGHT_SQUARE_BRACKET
+# define PNG_LITERAL_RIGHT_SQUARE_BRACKET 0x5d
+# endif
+# ifndef PNG_STRING_NEWLINE
+# define PNG_STRING_NEWLINE "\n"
+# endif
+
+#ifdef PNG_DEBUG
+# if (PNG_DEBUG > 0)
+# if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+# include <crtdbg.h>
+# if (PNG_DEBUG > 1)
+# ifndef _DEBUG
+# define _DEBUG
+# endif
+# ifndef png_debug
+# define png_debug(l,m) _RPT0(_CRT_WARN,m PNG_STRING_NEWLINE)
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m PNG_STRING_NEWLINE,p1)
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ _RPT2(_CRT_WARN,m PNG_STRING_NEWLINE,p1,p2)
+# endif
+# endif
+# else /* PNG_DEBUG_FILE || !_MSC_VER */
+# ifndef PNG_STDIO_SUPPORTED
+# include <stdio.h> /* not included yet */
+# endif
+# ifndef PNG_DEBUG_FILE
+# define PNG_DEBUG_FILE stderr
+# endif /* PNG_DEBUG_FILE */
+
+# if (PNG_DEBUG > 1)
+/* Note: ["%s"m PNG_STRING_NEWLINE] probably does not work on
+ * non-ISO compilers
+ */
+# ifdef __STDC__
+# ifndef png_debug
+# define png_debug(l,m) \
+ do { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+ } while (0)
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) \
+ do { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+ } while (0)
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ do { \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m PNG_STRING_NEWLINE,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+ } while (0)
+# endif
+# else /* __STDC __ */
+# ifndef png_debug
+# define png_debug(l,m) \
+ do { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format); \
+ } while (0)
+# endif
+# ifndef png_debug1
+# define png_debug1(l,m,p1) \
+ do { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format,p1); \
+ } while (0)
+# endif
+# ifndef png_debug2
+# define png_debug2(l,m,p1,p2) \
+ do { \
+ int num_tabs=l; \
+ char format[256]; \
+ snprintf(format,256,"%s%s%s",(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))), \
+ m,PNG_STRING_NEWLINE); \
+ fprintf(PNG_DEBUG_FILE,format,p1,p2); \
+ } while (0)
+# endif
+# endif /* __STDC __ */
+# endif /* (PNG_DEBUG > 1) */
+
+# endif /* _MSC_VER */
+# endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+# define png_debug(l, m) ((void)0)
+#endif
+#ifndef png_debug1
+# define png_debug1(l, m, p1) ((void)0)
+#endif
+#ifndef png_debug2
+# define png_debug2(l, m, p1, p2) ((void)0)
+#endif
+#endif /* PNGDEBUG_H */
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/pnginfo.h b/core/src/fxcodec/fx_lpng/lpng_v163/pnginfo.h
new file mode 100644
index 0000000000..683b7ea177
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/pnginfo.h
@@ -0,0 +1,260 @@
+
+/* pnginfo.h - header file for PNG reference library
+ *
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+ /* png_info is a structure that holds the information in a PNG file so
+ * that the application can find out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file. If you are writing the file, fill in the information
+ * you want to put into the PNG file, using png_set_*() functions, then
+ * call png_write_info().
+ *
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed. With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality. In libpng-1.5.0 this was moved into a separate private
+ * file that is not visible to applications.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng. This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions. A function to clear these members is available: see
+ * png_free_data(). The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+#ifndef PNGINFO_H
+#define PNGINFO_H
+
+struct png_info_def
+{
+ /* The following are necessary for every PNG file */
+ png_uint_32 width; /* width of image in pixels (from IHDR) */
+ png_uint_32 height; /* height of image in pixels (from IHDR) */
+ png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
+ png_size_t rowbytes; /* bytes needed to hold an untransformed row */
+ png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
+ png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
+ png_uint_16 num_trans; /* number of transparent palette color (tRNS) */
+ png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+ png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
+ /* The following three should have been named *_method not *_type */
+ png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+ png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+ png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+ /* The following are set by png_set_IHDR, called from the application on
+ * write, but the are never actually used by the write code.
+ */
+ png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte spare_byte; /* to align the data, and for future use */
+
+#ifdef PNG_READ_SUPPORTED
+ /* This is never set during write */
+ png_byte signature[8]; /* magic bytes read by libpng from start of file */
+#endif
+
+ /* The rest of the data is optional. If you are reading, check the
+ * valid field to see if the information in these are valid. If you
+ * are writing, set the valid field to those chunks you want written,
+ * and initialize the appropriate fields below.
+ */
+
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+ /* png_colorspace only contains 'flags' if neither GAMMA or COLORSPACE are
+ * defined. When COLORSPACE is switched on all the colorspace-defining
+ * chunks should be enabled, when GAMMA is switched on all the gamma-defining
+ * chunks should be enabled. If this is not done it becomes possible to read
+ * inconsistent PNG files and assign a probably incorrect interpretation to
+ * the information. (In other words, by carefully choosing which chunks to
+ * recognize the system configuration can select an interpretation for PNG
+ * files containing ambiguous data and this will result in inconsistent
+ * behavior between different libpng builds!)
+ */
+ png_colorspace colorspace;
+#endif
+
+#ifdef PNG_iCCP_SUPPORTED
+ /* iCCP chunk data. */
+ png_charp iccp_name; /* profile name */
+ png_bytep iccp_profile; /* International Color Consortium profile data */
+ png_uint_32 iccp_proflen; /* ICC profile data length */
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED
+ /* The tEXt, and zTXt chunks contain human-readable textual data in
+ * uncompressed, compressed, and optionally compressed forms, respectively.
+ * The data in "text" is an array of pointers to uncompressed,
+ * null-terminated C strings. Each chunk has a keyword that describes the
+ * textual data contained in that chunk. Keywords are not required to be
+ * unique, and the text string may be empty. Any number of text chunks may
+ * be in an image.
+ */
+ int num_text; /* number of comments read or comments to write */
+ int max_text; /* current size of text array */
+ png_textp text; /* array of comments read or comments to write */
+#endif /* PNG_TEXT_SUPPORTED */
+
+#ifdef PNG_tIME_SUPPORTED
+ /* The tIME chunk holds the last time the displayed image data was
+ * modified. See the png_time struct for the contents of this struct.
+ */
+ png_time mod_time;
+#endif
+
+#ifdef PNG_sBIT_SUPPORTED
+ /* The sBIT chunk specifies the number of significant high-order bits
+ * in the pixel data. Values are in the range [1, bit_depth], and are
+ * only specified for the channels in the pixel data. The contents of
+ * the low-order bits is not specified. Data is valid if
+ * (valid & PNG_INFO_sBIT) is non-zero.
+ */
+ png_color_8 sig_bit; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The tRNS chunk supplies transparency data for paletted images and
+ * other image types that don't need a full alpha channel. There are
+ * "num_trans" transparency values for a paletted image, stored in the
+ * same order as the palette colors, starting from index 0. Values
+ * for the data are in the range [0, 255], ranging from fully transparent
+ * to fully opaque, respectively. For non-paletted images, there is a
+ * single color specified that should be treated as fully transparent.
+ * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+ */
+ png_bytep trans_alpha; /* alpha values for paletted image */
+ png_color_16 trans_color; /* transparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The bKGD chunk gives the suggested image background color if the
+ * display program does not have its own background color and the image
+ * is needs to composited onto a background before display. The colors
+ * in "background" are normally in the same color space/depth as the
+ * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+ */
+ png_color_16 background;
+#endif
+
+#ifdef PNG_oFFs_SUPPORTED
+ /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+ * and downwards from the top-left corner of the display, page, or other
+ * application-specific co-ordinate space. See the PNG_OFFSET_ defines
+ * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
+ */
+ png_int_32 x_offset; /* x offset on page */
+ png_int_32 y_offset; /* y offset on page */
+ png_byte offset_unit_type; /* offset units type */
+#endif
+
+#ifdef PNG_pHYs_SUPPORTED
+ /* The pHYs chunk gives the physical pixel density of the image for
+ * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+ * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+ */
+ png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
+ png_uint_32 y_pixels_per_unit; /* vertical pixel density */
+ png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#ifdef PNG_hIST_SUPPORTED
+ /* The hIST chunk contains the relative frequency or importance of the
+ * various palette entries, so that a viewer can intelligently select a
+ * reduced-color palette, if required. Data is an array of "num_palette"
+ * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+ * is non-zero.
+ */
+ png_uint_16p hist;
+#endif
+
+#ifdef PNG_pCAL_SUPPORTED
+ /* The pCAL chunk describes a transformation between the stored pixel
+ * values and original physical data values used to create the image.
+ * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+ * range given by [pcal_X0, pcal_X1], and are further transformed by a
+ * (possibly non-linear) transformation function given by "pcal_type"
+ * and "pcal_params" into "pcal_units". Please see the PNG_EQUATION_
+ * defines below, and the PNG-Group's PNG extensions document for a
+ * complete description of the transformations and how they should be
+ * implemented, and for a description of the ASCII parameter strings.
+ * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+ */
+ png_charp pcal_purpose; /* pCAL chunk description string */
+ png_int_32 pcal_X0; /* minimum value */
+ png_int_32 pcal_X1; /* maximum value */
+ png_charp pcal_units; /* Latin-1 string giving physical units */
+ png_charpp pcal_params; /* ASCII strings containing parameter values */
+ png_byte pcal_type; /* equation type (see PNG_EQUATION_ below) */
+ png_byte pcal_nparams; /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+
+#ifdef PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+ /* Storage for unknown chunks that the library doesn't recognize. */
+ png_unknown_chunkp unknown_chunks;
+
+ /* The type of this field is limited by the type of
+ * png_struct::user_chunk_cache_max, else overflow can occur.
+ */
+ int unknown_chunks_num;
+#endif
+
+#ifdef PNG_sPLT_SUPPORTED
+ /* Data on sPLT chunks (there may be more than one). */
+ png_sPLT_tp splt_palettes;
+ int splt_palettes_num; /* Match type returned by png_get API */
+#endif
+
+#ifdef PNG_sCAL_SUPPORTED
+ /* The sCAL chunk describes the actual physical dimensions of the
+ * subject matter of the graphic. The chunk contains a unit specification
+ * a byte value, and two ASCII strings representing floating-point
+ * values. The values are width and height corresponsing to one pixel
+ * in the image. Data values are valid if (valid & PNG_INFO_sCAL) is
+ * non-zero.
+ */
+ png_byte scal_unit; /* unit of physical scale */
+ png_charp scal_s_width; /* string containing height */
+ png_charp scal_s_height; /* string containing width */
+#endif
+
+#ifdef PNG_INFO_IMAGE_SUPPORTED
+ /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS)
+ non-zero */
+ /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+ png_bytepp row_pointers; /* the image bits */
+#endif
+
+};
+#endif /* PNGINFO_H */
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/pnglibconf.h b/core/src/fxcodec/fx_lpng/lpng_v163/pnglibconf.h
new file mode 100644
index 0000000000..ececc38fc2
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/pnglibconf.h
@@ -0,0 +1,211 @@
+/* libpng 1.6.3 STANDARD API DEFINITION */
+
+/* pnglibconf.h - library build configuration */
+
+/* Libpng version 1.6.3 - July 18, 2013 */
+
+/* Copyright (c) 1998-2013 Glenn Randers-Pehrson */
+
+/* This code is released under the libpng license. */
+/* For conditions of distribution and use, see the disclaimer */
+/* and license in png.h */
+
+/* pnglibconf.h */
+/* Machine generated file: DO NOT EDIT */
+/* Derived from: scripts/pnglibconf.dfa */
+#ifndef PNGLCONF_H
+#define PNGLCONF_H
+/* options */
+#define PNG_16BIT_SUPPORTED
+#define PNG_ALIGNED_MEMORY_SUPPORTED
+/*#undef PNG_ARM_NEON_API_SUPPORTED*/
+/*#undef PNG_ARM_NEON_CHECK_SUPPORTED*/
+#define PNG_BENIGN_ERRORS_SUPPORTED
+#define PNG_BENIGN_READ_ERRORS_SUPPORTED
+/*#undef PNG_BENIGN_WRITE_ERRORS_SUPPORTED*/
+#define PNG_BUILD_GRAYSCALE_PALETTE_SUPPORTED
+#define PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_COLORSPACE_SUPPORTED
+#define PNG_CONSOLE_IO_SUPPORTED
+#define PNG_CONVERT_tIME_SUPPORTED
+#define PNG_EASY_ACCESS_SUPPORTED
+/*#undef PNG_ERROR_NUMBERS_SUPPORTED*/
+#define PNG_ERROR_TEXT_SUPPORTED
+#define PNG_FIXED_POINT_SUPPORTED
+#define PNG_FLOATING_ARITHMETIC_SUPPORTED
+#define PNG_FLOATING_POINT_SUPPORTED
+#define PNG_FORMAT_AFIRST_SUPPORTED
+#define PNG_FORMAT_BGR_SUPPORTED
+#define PNG_GAMMA_SUPPORTED
+#define PNG_GET_PALETTE_MAX_SUPPORTED
+#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+#define PNG_INCH_CONVERSIONS_SUPPORTED
+#define PNG_INFO_IMAGE_SUPPORTED
+#define PNG_IO_STATE_SUPPORTED
+#define PNG_MNG_FEATURES_SUPPORTED
+#define PNG_POINTER_INDEXING_SUPPORTED
+#define PNG_PROGRESSIVE_READ_SUPPORTED
+#define PNG_READ_16BIT_SUPPORTED
+#define PNG_READ_ALPHA_MODE_SUPPORTED
+#define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_READ_BACKGROUND_SUPPORTED
+#define PNG_READ_BGR_SUPPORTED
+#define PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_READ_COMPOSITE_NODIV_SUPPORTED
+#define PNG_READ_COMPRESSED_TEXT_SUPPORTED
+#define PNG_READ_EXPAND_16_SUPPORTED
+#define PNG_READ_EXPAND_SUPPORTED
+#define PNG_READ_FILLER_SUPPORTED
+#define PNG_READ_GAMMA_SUPPORTED
+#define PNG_READ_GET_PALETTE_MAX_SUPPORTED
+#define PNG_READ_GRAY_TO_RGB_SUPPORTED
+#define PNG_READ_INTERLACING_SUPPORTED
+#define PNG_READ_INT_FUNCTIONS_SUPPORTED
+#define PNG_READ_INVERT_ALPHA_SUPPORTED
+#define PNG_READ_INVERT_SUPPORTED
+#define PNG_READ_OPT_PLTE_SUPPORTED
+#define PNG_READ_PACKSWAP_SUPPORTED
+#define PNG_READ_PACK_SUPPORTED
+#define PNG_READ_QUANTIZE_SUPPORTED
+#define PNG_READ_RGB_TO_GRAY_SUPPORTED
+#define PNG_READ_SCALE_16_TO_8_SUPPORTED
+#define PNG_READ_SHIFT_SUPPORTED
+#define PNG_READ_STRIP_16_TO_8_SUPPORTED
+#define PNG_READ_STRIP_ALPHA_SUPPORTED
+#define PNG_READ_SUPPORTED
+#define PNG_READ_SWAP_ALPHA_SUPPORTED
+#define PNG_READ_SWAP_SUPPORTED
+#define PNG_READ_TEXT_SUPPORTED
+#define PNG_READ_TRANSFORMS_SUPPORTED
+#define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_READ_USER_CHUNKS_SUPPORTED
+#define PNG_READ_USER_TRANSFORM_SUPPORTED
+#define PNG_READ_bKGD_SUPPORTED
+#define PNG_READ_cHRM_SUPPORTED
+#define PNG_READ_gAMA_SUPPORTED
+#define PNG_READ_hIST_SUPPORTED
+#define PNG_READ_iCCP_SUPPORTED
+#define PNG_READ_iTXt_SUPPORTED
+#define PNG_READ_oFFs_SUPPORTED
+#define PNG_READ_pCAL_SUPPORTED
+#define PNG_READ_pHYs_SUPPORTED
+#define PNG_READ_sBIT_SUPPORTED
+#define PNG_READ_sCAL_SUPPORTED
+#define PNG_READ_sPLT_SUPPORTED
+#define PNG_READ_sRGB_SUPPORTED
+#define PNG_READ_tEXt_SUPPORTED
+#define PNG_READ_tIME_SUPPORTED
+#define PNG_READ_tRNS_SUPPORTED
+#define PNG_READ_zTXt_SUPPORTED
+/*#undef PNG_SAFE_LIMITS_SUPPORTED*/
+#define PNG_SAVE_INT_32_SUPPORTED
+#define PNG_SAVE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_SEQUENTIAL_READ_SUPPORTED
+#define PNG_SETJMP_SUPPORTED
+#define PNG_SET_CHUNK_CACHE_LIMIT_SUPPORTED
+#define PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
+#define PNG_SET_OPTION_SUPPORTED
+#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_SET_USER_LIMITS_SUPPORTED
+#define PNG_SIMPLIFIED_READ_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_READ_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_READ_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_BGR_SUPPORTED
+#define PNG_SIMPLIFIED_WRITE_SUPPORTED
+#define PNG_STDIO_SUPPORTED
+#define PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_TEXT_SUPPORTED
+#define PNG_TIME_RFC1123_SUPPORTED
+#define PNG_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_USER_CHUNKS_SUPPORTED
+#define PNG_USER_LIMITS_SUPPORTED
+#define PNG_USER_MEM_SUPPORTED
+#define PNG_USER_TRANSFORM_INFO_SUPPORTED
+#define PNG_USER_TRANSFORM_PTR_SUPPORTED
+#define PNG_WARNINGS_SUPPORTED
+#define PNG_WRITE_16BIT_SUPPORTED
+#define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#define PNG_WRITE_BGR_SUPPORTED
+#define PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED
+#define PNG_WRITE_COMPRESSED_TEXT_SUPPORTED
+#define PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+#define PNG_WRITE_FILLER_SUPPORTED
+#define PNG_WRITE_FILTER_SUPPORTED
+#define PNG_WRITE_FLUSH_SUPPORTED
+#define PNG_WRITE_GET_PALETTE_MAX_SUPPORTED
+#define PNG_WRITE_INTERLACING_SUPPORTED
+#define PNG_WRITE_INT_FUNCTIONS_SUPPORTED
+#define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+#define PNG_WRITE_INVERT_SUPPORTED
+#define PNG_WRITE_OPTIMIZE_CMF_SUPPORTED
+#define PNG_WRITE_PACKSWAP_SUPPORTED
+#define PNG_WRITE_PACK_SUPPORTED
+#define PNG_WRITE_SHIFT_SUPPORTED
+#define PNG_WRITE_SUPPORTED
+#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+#define PNG_WRITE_SWAP_SUPPORTED
+#define PNG_WRITE_TEXT_SUPPORTED
+#define PNG_WRITE_TRANSFORMS_SUPPORTED
+#define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+#define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#define PNG_WRITE_bKGD_SUPPORTED
+#define PNG_WRITE_cHRM_SUPPORTED
+#define PNG_WRITE_gAMA_SUPPORTED
+#define PNG_WRITE_hIST_SUPPORTED
+#define PNG_WRITE_iCCP_SUPPORTED
+#define PNG_WRITE_iTXt_SUPPORTED
+#define PNG_WRITE_oFFs_SUPPORTED
+#define PNG_WRITE_pCAL_SUPPORTED
+#define PNG_WRITE_pHYs_SUPPORTED
+#define PNG_WRITE_sBIT_SUPPORTED
+#define PNG_WRITE_sCAL_SUPPORTED
+#define PNG_WRITE_sPLT_SUPPORTED
+#define PNG_WRITE_sRGB_SUPPORTED
+#define PNG_WRITE_tEXt_SUPPORTED
+#define PNG_WRITE_tIME_SUPPORTED
+#define PNG_WRITE_tRNS_SUPPORTED
+#define PNG_WRITE_zTXt_SUPPORTED
+#define PNG_bKGD_SUPPORTED
+#define PNG_cHRM_SUPPORTED
+#define PNG_gAMA_SUPPORTED
+#define PNG_hIST_SUPPORTED
+#define PNG_iCCP_SUPPORTED
+#define PNG_iTXt_SUPPORTED
+#define PNG_oFFs_SUPPORTED
+#define PNG_pCAL_SUPPORTED
+#define PNG_pHYs_SUPPORTED
+#define PNG_sBIT_SUPPORTED
+#define PNG_sCAL_SUPPORTED
+#define PNG_sPLT_SUPPORTED
+#define PNG_sRGB_SUPPORTED
+#define PNG_tEXt_SUPPORTED
+#define PNG_tIME_SUPPORTED
+#define PNG_tRNS_SUPPORTED
+#define PNG_zTXt_SUPPORTED
+/* end of options */
+/* settings */
+#define PNG_API_RULE 0
+#define PNG_CALLOC_SUPPORTED
+#define PNG_COST_SHIFT 3
+#define PNG_DEFAULT_READ_MACROS 1
+#define PNG_GAMMA_THRESHOLD_FIXED 5000
+#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
+#define PNG_INFLATE_BUF_SIZE 1024
+#define PNG_MAX_GAMMA_8 11
+#define PNG_QUANTIZE_BLUE_BITS 5
+#define PNG_QUANTIZE_GREEN_BITS 5
+#define PNG_QUANTIZE_RED_BITS 5
+#define PNG_TEXT_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_TEXT_Z_DEFAULT_STRATEGY 0
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_ZBUF_SIZE 8192
+#define PNG_ZLIB_VERNUM 0 /* unknown */
+#define PNG_Z_DEFAULT_COMPRESSION (-1)
+#define PNG_Z_DEFAULT_NOFILTER_STRATEGY 0
+#define PNG_Z_DEFAULT_STRATEGY 1
+#define PNG_sCAL_PRECISION 5
+#define PNG_sRGB_PROFILE_CHECKS 2
+/* end of settings */
+#endif /* PNGLCONF_H */
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/pngpriv.h b/core/src/fxcodec/fx_lpng/lpng_v163/pngpriv.h
new file mode 100644
index 0000000000..7fa3d6059c
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/pngpriv.h
@@ -0,0 +1,2006 @@
+
+/* pngpriv.h - private declarations for use inside libpng
+ *
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.3 [July 18, 2013]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* The symbols declared in this file (including the functions declared
+ * as extern) are PRIVATE. They are not part of the libpng public
+ * interface, and are not recommended for use by regular applications.
+ * Some of them may become public in the future; others may stay private,
+ * change in an incompatible way, or even disappear.
+ * Although the libpng users are not forbidden to include this header,
+ * they should be well aware of the issues that may arise from doing so.
+ */
+
+#ifndef PNGPRIV_H
+#define PNGPRIV_H
+
+/* Feature Test Macros. The following are defined here to ensure that correctly
+ * implemented libraries reveal the APIs libpng needs to build and hide those
+ * that are not needed and potentially damaging to the compilation.
+ *
+ * Feature Test Macros must be defined before any system header is included (see
+ * POSIX 1003.1 2.8.2 "POSIX Symbols."
+ *
+ * These macros only have an effect if the operating system supports either
+ * POSIX 1003.1 or C99, or both. On other operating systems (particularly
+ * Windows/Visual Studio) there is no effect; the OS specific tests below are
+ * still required (as of 2011-05-02.)
+ */
+#define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Standard library headers not required by png.h: */
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#define PNGLIB_BUILD /*libpng is being built, not used*/
+
+/* If HAVE_CONFIG_H is defined during the build then the build system must
+ * provide an appropriate "config.h" file on the include path. The header file
+ * must provide definitions as required below (search for "HAVE_CONFIG_H");
+ * see configure.ac for more details of the requirements. The macro
+ * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on
+ * 'configure'; define this macro to prevent the configure build including the
+ * configure generated config.h. Libpng is expected to compile without *any*
+ * special build system support on a reasonably ANSI-C compliant system.
+ */
+#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H)
+# include <config.h>
+
+ /* Pick up the definition of 'restrict' from config.h if it was read: */
+# define PNG_RESTRICT restrict
+#endif
+
+/* To support symbol prefixing it is necessary to know *before* including png.h
+ * whether the fixed point (and maybe other) APIs are exported, because if they
+ * are not internal definitions may be required. This is handled below just
+ * before png.h is included, but load the configuration now if it is available.
+ */
+#ifndef PNGLCONF_H
+# include "pnglibconf.h"
+#endif
+
+/* Local renames may change non-exported API functions from png.h */
+#if defined(PNG_PREFIX) && !defined(PNGPREFIX_H)
+# include "pngprefix.h"
+#endif
+
+#ifdef PNG_USER_CONFIG
+# include "pngusr.h"
+ /* These should have been defined in pngusr.h */
+# ifndef PNG_USER_PRIVATEBUILD
+# define PNG_USER_PRIVATEBUILD "Custom libpng build"
+# endif
+# ifndef PNG_USER_DLLFNAME_POSTFIX
+# define PNG_USER_DLLFNAME_POSTFIX "Cb"
+# endif
+#endif
+
+/* Compile time options.
+ * =====================
+ * In a multi-arch build the compiler may compile the code several times for the
+ * same object module, producing different binaries for different architectures.
+ * When this happens configure-time setting of the target host options cannot be
+ * done and this interferes with the handling of the ARM NEON optimizations, and
+ * possibly other similar optimizations. Put additional tests here; in general
+ * this is needed when the same option can be changed at both compile time and
+ * run time depending on the target OS (i.e. iOS vs Android.)
+ *
+ * NOTE: symbol prefixing does not pass $(CFLAGS) to the preprocessor, because
+ * this is not possible with certain compilers (Oracle SUN OS CC), as a result
+ * it is necessary to ensure that all extern functions that *might* be used
+ * regardless of $(CFLAGS) get declared in this file. The test on __ARM_NEON__
+ * below is one example of this behavior because it is controlled by the
+ * presence or not of -mfpu=neon on the GCC command line, it is possible to do
+ * this in $(CC), e.g. "CC=gcc -mfpu=neon", but people who build libpng rarely
+ * do this.
+ */
+#ifndef PNG_ARM_NEON_OPT
+ /* ARM NEON optimizations are being controlled by the compiler settings,
+ * typically the target FPU. If the FPU has been set to NEON (-mfpu=neon
+ * with GCC) then the compiler will define __ARM_NEON__ and we can rely
+ * unconditionally on NEON instructions not crashing, otherwise we must
+ * disable use of NEON instructions:
+ */
+# ifdef __ARM_NEON__
+# define PNG_ARM_NEON_OPT 2
+# else
+# define PNG_ARM_NEON_OPT 0
+# endif
+#endif
+
+#if PNG_ARM_NEON_OPT > 0
+ /* NEON optimizations are to be at least considered by libpng, so enable the
+ * callbacks to do this.
+ */
+# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_neon
+#endif
+
+/* Is this a build of a DLL where compilation of the object modules requires
+ * different preprocessor settings to those required for a simple library? If
+ * so PNG_BUILD_DLL must be set.
+ *
+ * If libpng is used inside a DLL but that DLL does not export the libpng APIs
+ * PNG_BUILD_DLL must not be set. To avoid the code below kicking in build a
+ * static library of libpng then link the DLL against that.
+ */
+#ifndef PNG_BUILD_DLL
+# ifdef DLL_EXPORT
+ /* This is set by libtool when files are compiled for a DLL; libtool
+ * always compiles twice, even on systems where it isn't necessary. Set
+ * PNG_BUILD_DLL in case it is necessary:
+ */
+# define PNG_BUILD_DLL
+# else
+# ifdef _WINDLL
+ /* This is set by the Microsoft Visual Studio IDE in projects that
+ * build a DLL. It can't easily be removed from those projects (it
+ * isn't visible in the Visual Studio UI) so it is a fairly reliable
+ * indication that PNG_IMPEXP needs to be set to the DLL export
+ * attributes.
+ */
+# define PNG_BUILD_DLL
+# else
+# ifdef __DLL__
+ /* This is set by the Borland C system when compiling for a DLL
+ * (as above.)
+ */
+# define PNG_BUILD_DLL
+# else
+ /* Add additional compiler cases here. */
+# endif
+# endif
+# endif
+#endif /* Setting PNG_BUILD_DLL if required */
+
+/* See pngconf.h for more details: the builder of the library may set this on
+ * the command line to the right thing for the specific compilation system or it
+ * may be automagically set above (at present we know of no system where it does
+ * need to be set on the command line.)
+ *
+ * PNG_IMPEXP must be set here when building the library to prevent pngconf.h
+ * setting it to the "import" setting for a DLL build.
+ */
+#ifndef PNG_IMPEXP
+# ifdef PNG_BUILD_DLL
+# define PNG_IMPEXP PNG_DLL_EXPORT
+# else
+ /* Not building a DLL, or the DLL doesn't require specific export
+ * definitions.
+ */
+# define PNG_IMPEXP
+# endif
+#endif
+
+/* No warnings for private or deprecated functions in the build: */
+#ifndef PNG_DEPRECATED
+# define PNG_DEPRECATED
+#endif
+#ifndef PNG_PRIVATE
+# define PNG_PRIVATE
+#endif
+
+/* Symbol preprocessing support.
+ *
+ * To enable listing global, but internal, symbols the following macros should
+ * always be used to declare an extern data or function object in this file.
+ */
+#ifndef PNG_INTERNAL_DATA
+# define PNG_INTERNAL_DATA(type, name, array) extern type name array
+#endif
+
+#ifndef PNG_INTERNAL_FUNCTION
+# define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\
+ extern PNG_FUNCTION(type, name, args, PNG_EMPTY attributes)
+#endif
+
+/* If floating or fixed point APIs are disabled they may still be compiled
+ * internally. To handle this make sure they are declared as the appropriate
+ * internal extern function (otherwise the symbol prefixing stuff won't work and
+ * the functions will be used without definitions.)
+ *
+ * NOTE: although all the API functions are declared here they are not all
+ * actually built! Because the declarations are still made it is necessary to
+ * fake out types that they depend on.
+ */
+#ifndef PNG_FP_EXPORT
+# ifndef PNG_FLOATING_POINT_SUPPORTED
+# define PNG_FP_EXPORT(ordinal, type, name, args)\
+ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
+# ifndef PNG_VERSION_INFO_ONLY
+ typedef struct png_incomplete png_double;
+ typedef png_double* png_doublep;
+ typedef const png_double* png_const_doublep;
+ typedef png_double** png_doublepp;
+# endif
+# endif
+#endif
+#ifndef PNG_FIXED_EXPORT
+# ifndef PNG_FIXED_POINT_SUPPORTED
+# define PNG_FIXED_EXPORT(ordinal, type, name, args)\
+ PNG_INTERNAL_FUNCTION(type, name, args, PNG_EMPTY);
+# endif
+#endif
+
+#include "png.h"
+
+/* pngconf.h does not set PNG_DLL_EXPORT unless it is required, so: */
+#ifndef PNG_DLL_EXPORT
+# define PNG_DLL_EXPORT
+#endif
+
+/* SECURITY and SAFETY:
+ *
+ * By default libpng is built without any internal limits on image size,
+ * individual heap (png_malloc) allocations or the total amount of memory used.
+ * If PNG_SAFE_LIMITS_SUPPORTED is defined, however, the limits below are used
+ * (unless individually overridden). These limits are believed to be fairly
+ * safe, but builders of secure systems should verify the values against the
+ * real system capabilities.
+ */
+#ifdef PNG_SAFE_LIMITS_SUPPORTED
+ /* 'safe' limits */
+# ifndef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 1000000
+# endif
+# ifndef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 1000000
+# endif
+# ifndef PNG_USER_CHUNK_CACHE_MAX
+# define PNG_USER_CHUNK_CACHE_MAX 128
+# endif
+# ifndef PNG_USER_CHUNK_MALLOC_MAX
+# define PNG_USER_CHUNK_MALLOC_MAX 8000000
+# endif
+#else
+ /* values for no limits */
+# ifndef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 0x7fffffff
+# endif
+# ifndef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 0x7fffffff
+# endif
+# ifndef PNG_USER_CHUNK_CACHE_MAX
+# define PNG_USER_CHUNK_CACHE_MAX 0
+# endif
+# ifndef PNG_USER_CHUNK_MALLOC_MAX
+# define PNG_USER_CHUNK_MALLOC_MAX 0
+# endif
+#endif
+
+/* Moved to pngpriv.h at libpng-1.5.0 */
+/* NOTE: some of these may have been used in external applications as
+ * these definitions were exposed in pngconf.h prior to 1.5.
+ */
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this. While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+ *
+ * zlib provides 'MAXSEG_64K' which, if defined, indicates the
+ * same limit and pngconf.h (already included) sets the limit
+ * if certain operating systems are detected.
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+# define PNG_MAX_MALLOC_64K
+#endif
+
+#ifndef PNG_UNUSED
+/* Unused formal parameter warnings are silenced using the following macro
+ * which is expected to have no bad effects on performance (optimizing
+ * compilers will probably remove it entirely). Note that if you replace
+ * it with something other than whitespace, you must include the terminating
+ * semicolon.
+ */
+# define PNG_UNUSED(param) (void)param;
+#endif
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536L) && defined(PNG_MAX_MALLOC_64K)
+# undef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 65536L
+#endif
+
+/* If warnings or errors are turned off the code is disabled or redirected here.
+ * From 1.5.4 functions have been added to allow very limited formatting of
+ * error and warning messages - this code will also be disabled here.
+ */
+#ifdef PNG_WARNINGS_SUPPORTED
+# define PNG_WARNING_PARAMETERS(p) png_warning_parameters p;
+#else
+# define png_warning(s1,s2) ((void)(s1))
+# define png_chunk_warning(s1,s2) ((void)(s1))
+# define png_warning_parameter(p,number,string) ((void)0)
+# define png_warning_parameter_unsigned(p,number,format,value) ((void)0)
+# define png_warning_parameter_signed(p,number,format,value) ((void)0)
+# define png_formatted_warning(pp,p,message) ((void)(pp))
+# define PNG_WARNING_PARAMETERS(p)
+#endif
+#ifndef PNG_ERROR_TEXT_SUPPORTED
+# define png_error(s1,s2) png_err(s1)
+# define png_chunk_error(s1,s2) png_err(s1)
+# define png_fixed_error(s1,s2) png_err(s1)
+#endif
+
+/* C allows up-casts from (void*) to any pointer and (const void*) to any
+ * pointer to a const object. C++ regards this as a type error and requires an
+ * explicit, static, cast and provides the static_cast<> rune to ensure that
+ * const is not cast away.
+ */
+#ifdef __cplusplus
+# define png_voidcast(type, value) static_cast<type>(value)
+# define png_constcast(type, value) const_cast<type>(value)
+# define png_aligncast(type, value) \
+ static_cast<type>(static_cast<void*>(value))
+# define png_aligncastconst(type, value) \
+ static_cast<type>(static_cast<const void*>(value))
+#else
+# define png_voidcast(type, value) (value)
+# define png_constcast(type, value) ((type)(value))
+# define png_aligncast(type, value) ((void*)(value))
+# define png_aligncastconst(type, value) ((const void*)(value))
+#endif /* __cplusplus */
+
+/* Some fixed point APIs are still required even if not exported because
+ * they get used by the corresponding floating point APIs. This magic
+ * deals with this:
+ */
+#ifdef PNG_FIXED_POINT_SUPPORTED
+# define PNGFAPI PNGAPI
+#else
+# define PNGFAPI /* PRIVATE */
+#endif
+
+#ifndef PNG_VERSION_INFO_ONLY
+/* Other defines specific to compilers can go here. Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) ||\
+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED)
+ /* png.c requires the following ANSI-C constants if the conversion of
+ * floating point to ASCII is implemented therein:
+ *
+ * DBL_DIG Maximum number of decimal digits (can be set to any constant)
+ * DBL_MIN Smallest normalized fp number (can be set to an arbitrary value)
+ * DBL_MAX Maximum floating point number (can be set to an arbitrary value)
+ */
+# include <float.h>
+
+# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+ /* We need to check that <math.h> hasn't already been included earlier
+ * as it seems it doesn't agree with <fp.h>, yet we should really use
+ * <fp.h> if possible.
+ */
+# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+# include <fp.h>
+# endif
+# else
+# include <math.h>
+# endif
+# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+ /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+ * MATH=68881
+ */
+# include <m68881.h>
+# endif
+#endif
+
+/* This provides the non-ANSI (far) memory allocation routines. */
+#if defined(__TURBOC__) && defined(__MSDOS__)
+# include <mem.h>
+# include <alloc.h>
+#endif
+
+#if defined(WIN32) || defined(_Windows) || defined(_WINDOWS) || \
+ defined(_WIN32) || defined(__WIN32__)
+# include <windows.h> /* defines _WINDOWS_ macro */
+#endif
+#endif /* PNG_VERSION_INFO_ONLY */
+
+/* Moved here around 1.5.0beta36 from pngconf.h */
+/* Users may want to use these so they are not private. Any library
+ * functions that are passed far data must be model-independent.
+ */
+
+/* Memory model/platform independent fns */
+#ifndef PNG_ABORT
+# ifdef _WINDOWS_
+# define PNG_ABORT() ExitProcess(0)
+# else
+# define PNG_ABORT() abort()
+# endif
+#endif
+
+/* These macros may need to be architecture dependent. */
+#define PNG_ALIGN_NONE 0 /* do not use data alignment */
+#define PNG_ALIGN_ALWAYS 1 /* assume unaligned accesses are OK */
+#ifdef offsetof
+# define PNG_ALIGN_OFFSET 2 /* use offsetof to determine alignment */
+#else
+# define PNG_ALIGN_OFFSET -1 /* prevent the use of this */
+#endif
+#define PNG_ALIGN_SIZE 3 /* use sizeof to determine alignment */
+
+#ifndef PNG_ALIGN_TYPE
+ /* Default to using aligned access optimizations and requiring alignment to a
+ * multiple of the data type size. Override in a compiler specific fashion
+ * if necessary by inserting tests here:
+ */
+# define PNG_ALIGN_TYPE PNG_ALIGN_SIZE
+#endif
+
+#if PNG_ALIGN_TYPE == PNG_ALIGN_SIZE
+ /* This is used because in some compiler implementations non-aligned
+ * structure members are supported, so the offsetof approach below fails.
+ * Set PNG_ALIGN_SIZE=0 for compiler combinations where unaligned access
+ * is good for performance. Do not do this unless you have tested the result
+ * and understand it.
+ */
+# define png_alignof(type) (sizeof (type))
+#else
+# if PNG_ALIGN_TYPE == PNG_ALIGN_OFFSET
+# define png_alignof(type) offsetof(struct{char c; type t;}, t)
+# else
+# if PNG_ALIGN_TYPE == PNG_ALIGN_ALWAYS
+# define png_alignof(type) (1)
+# endif
+ /* Else leave png_alignof undefined to prevent use thereof */
+# endif
+#endif
+
+/* This implicitly assumes alignment is always to a power of 2. */
+#ifdef png_alignof
+# define png_isaligned(ptr, type)\
+ ((((const char*)ptr-(const char*)0) & (png_alignof(type)-1)) == 0)
+#else
+# define png_isaligned(ptr, type) 0
+#endif
+
+/* End of memory model/platform independent support */
+/* End of 1.5.0beta36 move from pngconf.h */
+
+/* CONSTANTS and UTILITY MACROS
+ * These are used internally by libpng and not exposed in the API
+ */
+
+/* Various modes of operation. Note that after an init, mode is set to
+ * zero automatically when the structure is created. Three of these
+ * are defined in png.h because they need to be visible to applications
+ * that call png_set_unknown_chunk().
+ */
+/* #define PNG_HAVE_IHDR 0x01 (defined in png.h) */
+/* #define PNG_HAVE_PLTE 0x02 (defined in png.h) */
+#define PNG_HAVE_IDAT 0x04
+/* #define PNG_AFTER_IDAT 0x08 (defined in png.h) */
+#define PNG_HAVE_IEND 0x10
+ /* 0x20 (unused) */
+ /* 0x40 (unused) */
+ /* 0x80 (unused) */
+#define PNG_HAVE_CHUNK_HEADER 0x100
+#define PNG_WROTE_tIME 0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY 0x800
+#define PNG_HAVE_PNG_SIGNATURE 0x1000
+#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
+ /* 0x4000 (unused) */
+#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */
+
+/* Flags for the transformations the PNG library does on the image data */
+#define PNG_BGR 0x0001
+#define PNG_INTERLACE 0x0002
+#define PNG_PACK 0x0004
+#define PNG_SHIFT 0x0008
+#define PNG_SWAP_BYTES 0x0010
+#define PNG_INVERT_MONO 0x0020
+#define PNG_QUANTIZE 0x0040
+#define PNG_COMPOSE 0x0080 /* Was PNG_BACKGROUND */
+#define PNG_BACKGROUND_EXPAND 0x0100
+#define PNG_EXPAND_16 0x0200 /* Added to libpng 1.5.2 */
+#define PNG_16_TO_8 0x0400 /* Becomes 'chop' in 1.5.4 */
+#define PNG_RGBA 0x0800
+#define PNG_EXPAND 0x1000
+#define PNG_GAMMA 0x2000
+#define PNG_GRAY_TO_RGB 0x4000
+#define PNG_FILLER 0x8000
+#define PNG_PACKSWAP 0x10000
+#define PNG_SWAP_ALPHA 0x20000
+#define PNG_STRIP_ALPHA 0x40000
+#define PNG_INVERT_ALPHA 0x80000
+#define PNG_USER_TRANSFORM 0x100000
+#define PNG_RGB_TO_GRAY_ERR 0x200000
+#define PNG_RGB_TO_GRAY_WARN 0x400000
+#define PNG_RGB_TO_GRAY 0x600000 /* two bits, RGB_TO_GRAY_ERR|WARN */
+#define PNG_ENCODE_ALPHA 0x800000 /* Added to libpng-1.5.4 */
+#define PNG_ADD_ALPHA 0x1000000 /* Added to libpng-1.2.7 */
+#define PNG_EXPAND_tRNS 0x2000000 /* Added to libpng-1.2.9 */
+#define PNG_SCALE_16_TO_8 0x4000000 /* Added to libpng-1.5.4 */
+ /* 0x8000000 unused */
+ /* 0x10000000 unused */
+ /* 0x20000000 unused */
+ /* 0x40000000 unused */
+/* Flags for png_create_struct */
+#define PNG_STRUCT_PNG 0x0001
+#define PNG_STRUCT_INFO 0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* Flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
+#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */
+ /* 0x0004 unused */
+#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */
+ /* 0x0010 unused */
+ /* 0x0020 unused */
+#define PNG_FLAG_ROW_INIT 0x0040
+#define PNG_FLAG_FILLER_AFTER 0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
+#define PNG_FLAG_ASSUME_sRGB 0x1000 /* Added to libpng-1.5.4 */
+#define PNG_FLAG_OPTIMIZE_ALPHA 0x2000 /* Added to libpng-1.5.4 */
+#define PNG_FLAG_DETECT_UNINITIALIZED 0x4000 /* Added to libpng-1.5.4 */
+/* #define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000 */
+/* #define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000 */
+#define PNG_FLAG_LIBRARY_MISMATCH 0x20000
+#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000
+#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000
+#define PNG_FLAG_BENIGN_ERRORS_WARN 0x100000 /* Added to libpng-1.4.0 */
+#define PNG_FLAG_APP_WARNINGS_WARN 0x200000 /* Added to libpng-1.6.0 */
+#define PNG_FLAG_APP_ERRORS_WARN 0x400000 /* Added to libpng-1.6.0 */
+ /* 0x800000 unused */
+ /* 0x1000000 unused */
+ /* 0x2000000 unused */
+ /* 0x4000000 unused */
+ /* 0x8000000 unused */
+ /* 0x10000000 unused */
+ /* 0x20000000 unused */
+ /* 0x40000000 unused */
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+ PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
+ PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
+ PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* Save typing and make code easier to understand */
+
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+ abs((int)((c1).green) - (int)((c2).green)) + \
+ abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* Added to libpng-1.6.0: scale a 16-bit value in the range 0..65535 to 0..255
+ * by dividing by 257 *with rounding*. This macro is exact for the given range.
+ * See the discourse in pngrtran.c png_do_scale_16_to_8. The values in the
+ * macro were established by experiment (modifying the added value). The macro
+ * has a second variant that takes a value already scaled by 255 and divides by
+ * 65535 - this has a maximum error of .502. Over the range 0..65535*65535 it
+ * only gives off-by-one errors and only for 0.5% (1 in 200) of the values.
+ */
+#define PNG_DIV65535(v24) (((v24) + 32895) >> 16)
+#define PNG_DIV257(v16) PNG_DIV65535((png_uint_32)(v16) * 255)
+
+/* Added to libpng-1.2.6 JB */
+#define PNG_ROWBYTES(pixel_bits, width) \
+ ((pixel_bits) >= 8 ? \
+ ((png_size_t)(width) * (((png_size_t)(pixel_bits)) >> 3)) : \
+ (( ((png_size_t)(width) * ((png_size_t)(pixel_bits))) + 7) >> 3) )
+
+/* PNG_OUT_OF_RANGE returns true if value is outside the range
+ * ideal-delta..ideal+delta. Each argument is evaluated twice.
+ * "ideal" and "delta" should be constants, normally simple
+ * integers, "value" a variable. Added to libpng-1.2.6 JB
+ */
+#define PNG_OUT_OF_RANGE(value, ideal, delta) \
+ ( (value) < (ideal)-(delta) || (value) > (ideal)+(delta) )
+
+/* Conversions between fixed and floating point, only defined if
+ * required (to make sure the code doesn't accidentally use float
+ * when it is supposedly disabled.)
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+/* The floating point conversion can't overflow, though it can and
+ * does lose accuracy relative to the original fixed point value.
+ * In practice this doesn't matter because png_fixed_point only
+ * stores numbers with very low precision. The png_ptr and s
+ * arguments are unused by default but are there in case error
+ * checking becomes a requirement.
+ */
+#define png_float(png_ptr, fixed, s) (.00001 * (fixed))
+
+/* The fixed point conversion performs range checking and evaluates
+ * its argument multiple times, so must be used with care. The
+ * range checking uses the PNG specification values for a signed
+ * 32 bit fixed point value except that the values are deliberately
+ * rounded-to-zero to an integral value - 21474 (21474.83 is roughly
+ * (2^31-1) * 100000). 's' is a string that describes the value being
+ * converted.
+ *
+ * NOTE: this macro will raise a png_error if the range check fails,
+ * therefore it is normally only appropriate to use this on values
+ * that come from API calls or other sources where an out of range
+ * error indicates a programming error, not a data error!
+ *
+ * NOTE: by default this is off - the macro is not used - because the
+ * function call saves a lot of code.
+ */
+#ifdef PNG_FIXED_POINT_MACRO_SUPPORTED
+#define png_fixed(png_ptr, fp, s) ((fp) <= 21474 && (fp) >= -21474 ?\
+ ((png_fixed_point)(100000 * (fp))) : (png_fixed_error(png_ptr, s),0))
+#endif
+/* else the corresponding function is defined below, inside the scope of the
+ * cplusplus test.
+ */
+#endif
+
+/* Constants for known chunk types. If you need to add a chunk, define the name
+ * here. For historical reasons these constants have the form png_<name>; i.e.
+ * the prefix is lower case. Please use decimal values as the parameters to
+ * match the ISO PNG specification and to avoid relying on the C locale
+ * interpretation of character values.
+ *
+ * Prior to 1.5.6 these constants were strings, as of 1.5.6 png_uint_32 values
+ * are computed and a new macro (PNG_STRING_FROM_CHUNK) added to allow a string
+ * to be generated if required.
+ *
+ * PNG_32b correctly produces a value shifted by up to 24 bits, even on
+ * architectures where (int) is only 16 bits.
+ */
+#define PNG_32b(b,s) ((png_uint_32)(b) << (s))
+#define PNG_U32(b1,b2,b3,b4) \
+ (PNG_32b(b1,24) | PNG_32b(b2,16) | PNG_32b(b3,8) | PNG_32b(b4,0))
+
+/* Constants for known chunk types.
+ *
+ * MAINTAINERS: If you need to add a chunk, define the name here.
+ * For historical reasons these constants have the form png_<name>; i.e.
+ * the prefix is lower case. Please use decimal values as the parameters to
+ * match the ISO PNG specification and to avoid relying on the C locale
+ * interpretation of character values. Please keep the list sorted.
+ *
+ * Notice that PNG_U32 is used to define a 32-bit value for the 4 byte chunk
+ * type. In fact the specification does not express chunk types this way,
+ * however using a 32-bit value means that the chunk type can be read from the
+ * stream using exactly the same code as used for a 32-bit unsigned value and
+ * can be examined far more efficiently (using one arithmetic compare).
+ *
+ * Prior to 1.5.6 the chunk type constants were expressed as C strings. The
+ * libpng API still uses strings for 'unknown' chunks and a macro,
+ * PNG_STRING_FROM_CHUNK, allows a string to be generated if required. Notice
+ * that for portable code numeric values must still be used; the string "IHDR"
+ * is not portable and neither is PNG_U32('I', 'H', 'D', 'R').
+ *
+ * In 1.7.0 the definitions will be made public in png.h to avoid having to
+ * duplicate the same definitions in application code.
+ */
+#define png_IDAT PNG_U32( 73, 68, 65, 84)
+#define png_IEND PNG_U32( 73, 69, 78, 68)
+#define png_IHDR PNG_U32( 73, 72, 68, 82)
+#define png_PLTE PNG_U32( 80, 76, 84, 69)
+#define png_bKGD PNG_U32( 98, 75, 71, 68)
+#define png_cHRM PNG_U32( 99, 72, 82, 77)
+#define png_fRAc PNG_U32(102, 82, 65, 99) /* registered, not defined */
+#define png_gAMA PNG_U32(103, 65, 77, 65)
+#define png_gIFg PNG_U32(103, 73, 70, 103)
+#define png_gIFt PNG_U32(103, 73, 70, 116) /* deprecated */
+#define png_gIFx PNG_U32(103, 73, 70, 120)
+#define png_hIST PNG_U32(104, 73, 83, 84)
+#define png_iCCP PNG_U32(105, 67, 67, 80)
+#define png_iTXt PNG_U32(105, 84, 88, 116)
+#define png_oFFs PNG_U32(111, 70, 70, 115)
+#define png_pCAL PNG_U32(112, 67, 65, 76)
+#define png_pHYs PNG_U32(112, 72, 89, 115)
+#define png_sBIT PNG_U32(115, 66, 73, 84)
+#define png_sCAL PNG_U32(115, 67, 65, 76)
+#define png_sPLT PNG_U32(115, 80, 76, 84)
+#define png_sRGB PNG_U32(115, 82, 71, 66)
+#define png_sTER PNG_U32(115, 84, 69, 82)
+#define png_tEXt PNG_U32(116, 69, 88, 116)
+#define png_tIME PNG_U32(116, 73, 77, 69)
+#define png_tRNS PNG_U32(116, 82, 78, 83)
+#define png_zTXt PNG_U32(122, 84, 88, 116)
+
+/* The following will work on (signed char*) strings, whereas the get_uint_32
+ * macro will fail on top-bit-set values because of the sign extension.
+ */
+#define PNG_CHUNK_FROM_STRING(s)\
+ PNG_U32(0xff&(s)[0], 0xff&(s)[1], 0xff&(s)[2], 0xff&(s)[3])
+
+/* This uses (char), not (png_byte) to avoid warnings on systems where (char) is
+ * signed and the argument is a (char[]) This macro will fail miserably on
+ * systems where (char) is more than 8 bits.
+ */
+#define PNG_STRING_FROM_CHUNK(s,c)\
+ (void)(((char*)(s))[0]=(char)((c)>>24), ((char*)(s))[1]=(char)((c)>>16),\
+ ((char*)(s))[2]=(char)((c)>>8), ((char*)(s))[3]=(char)((c)))
+
+/* Do the same but terminate with a null character. */
+#define PNG_CSTRING_FROM_CHUNK(s,c)\
+ (void)(PNG_STRING_FROM_CHUNK(s,c), ((char*)(s))[4] = 0)
+
+/* Test on flag values as defined in the spec (section 5.4): */
+#define PNG_CHUNK_ANCILLARY(c) (1 & ((c) >> 29))
+#define PNG_CHUNK_CRITICAL(c) (!PNG_CHUNK_ANCILLARY(c))
+#define PNG_CHUNK_PRIVATE(c) (1 & ((c) >> 21))
+#define PNG_CHUNK_RESERVED(c) (1 & ((c) >> 13))
+#define PNG_CHUNK_SAFE_TO_COPY(c) (1 & ((c) >> 5))
+
+/* Gamma values (new at libpng-1.5.4): */
+#define PNG_GAMMA_MAC_OLD 151724 /* Assume '1.8' is really 2.2/1.45! */
+#define PNG_GAMMA_MAC_INVERSE 65909
+#define PNG_GAMMA_sRGB_INVERSE 45455
+
+/* Almost everything below is C specific; the #defines above can be used in
+ * non-C code (so long as it is C-preprocessed) the rest of this stuff cannot.
+ */
+#ifndef PNG_VERSION_INFO_ONLY
+
+#include "pngstruct.h"
+#include "pnginfo.h"
+
+/* Validate the include paths - the include path used to generate pnglibconf.h
+ * must match that used in the build, or we must be using pnglibconf.h.prebuilt:
+ */
+#if PNG_ZLIB_VERNUM != 0 && PNG_ZLIB_VERNUM != ZLIB_VERNUM
+# error ZLIB_VERNUM != PNG_ZLIB_VERNUM \
+ "-I (include path) error: see the notes in pngpriv.h"
+ /* This means that when pnglibconf.h was built the copy of zlib.h that it
+ * used is not the same as the one being used here. Because the build of
+ * libpng makes decisions to use inflateInit2 and inflateReset2 based on the
+ * zlib version number and because this affects handling of certain broken
+ * PNG files the -I directives must match.
+ *
+ * The most likely explanation is that you passed a -I in CFLAGS, this will
+ * not work; all the preprocessor directories and in particular all the -I
+ * directives must be in CPPFLAGS.
+ */
+#endif
+
+/* This is used for 16 bit gamma tables -- only the top level pointers are
+ * const; this could be changed:
+ */
+typedef const png_uint_16p * png_const_uint_16pp;
+
+/* Added to libpng-1.5.7: sRGB conversion tables */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+#ifdef PNG_SIMPLIFIED_READ_SUPPORTED
+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_table, [256]);
+ /* Convert from an sRGB encoded value 0..255 to a 16-bit linear value,
+ * 0..65535. This table gives the closest 16-bit answers (no errors).
+ */
+#endif
+
+PNG_INTERNAL_DATA(const png_uint_16, png_sRGB_base, [512]);
+PNG_INTERNAL_DATA(const png_byte, png_sRGB_delta, [512]);
+
+#define PNG_sRGB_FROM_LINEAR(linear) ((png_byte)((png_sRGB_base[(linear)>>15] +\
+ ((((linear)&0x7fff)*png_sRGB_delta[(linear)>>15])>>12)) >> 8))
+ /* Given a value 'linear' in the range 0..255*65535 calculate the 8-bit sRGB
+ * encoded value with maximum error 0.646365. Note that the input is not a
+ * 16-bit value; it has been multiplied by 255! */
+#endif /* PNG_SIMPLIFIED_READ/WRITE */
+
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Internal functions; these are not exported from a DLL however because they
+ * are used within several of the C source files they have to be C extern.
+ *
+ * All of these functions must be declared with PNG_INTERNAL_FUNCTION.
+ */
+
+/* Zlib support */
+#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
+PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
+ PNG_EMPTY);
+ /* Used by the zlib handling functions to ensure that z_stream::msg is always
+ * set before they return.
+ */
+
+#ifdef PNG_WRITE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
+ png_compression_bufferp *list),PNG_EMPTY);
+ /* Free the buffer list used by the compressed write code. */
+#endif
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && \
+ !defined(PNG_FIXED_POINT_MACRO_SUPPORTED) && \
+ (defined(PNG_gAMA_SUPPORTED) || defined(PNG_cHRM_SUPPORTED) || \
+ defined(PNG_sCAL_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)) || \
+ (defined(PNG_sCAL_SUPPORTED) && \
+ defined(PNG_FLOATING_ARITHMETIC_SUPPORTED))
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_fixed,(png_const_structrp png_ptr,
+ double fp, png_const_charp text),PNG_EMPTY);
+#endif
+
+/* Check the user version string for compatibility, returns false if the version
+ * numbers aren't compatible.
+ */
+PNG_INTERNAL_FUNCTION(int,png_user_version_check,(png_structrp png_ptr,
+ png_const_charp user_png_ver),PNG_EMPTY);
+
+/* Internal base allocator - no messages, NULL on failure to allocate. This
+ * does, however, call the application provided allocator and that could call
+ * png_error (although that would be a bug in the application implementation.)
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_base,(png_const_structrp png_ptr,
+ png_alloc_size_t size),PNG_ALLOCATED);
+
+#if defined(PNG_TEXT_SUPPORTED) || defined(PNG_sPLT_SUPPORTED) ||\
+ defined(PNG_STORE_UNKNOWN_CHUNKS_SUPPORTED)
+/* Internal array allocator, outputs no error or warning messages on failure,
+ * just returns NULL.
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_malloc_array,(png_const_structrp png_ptr,
+ int nelements, size_t element_size),PNG_ALLOCATED);
+
+/* The same but an existing array is extended by add_elements. This function
+ * also memsets the new elements to 0 and copies the old elements. The old
+ * array is not freed or altered.
+ */
+PNG_INTERNAL_FUNCTION(png_voidp,png_realloc_array,(png_const_structrp png_ptr,
+ png_const_voidp array, int old_elements, int add_elements,
+ size_t element_size),PNG_ALLOCATED);
+#endif /* text, sPLT or unknown chunks */
+
+/* Magic to create a struct when there is no struct to call the user supplied
+ * memory allocators. Because error handling has not been set up the memory
+ * handlers can't safely call png_error, but this is an obscure and undocumented
+ * restriction so libpng has to assume that the 'free' handler, at least, might
+ * call png_error.
+ */
+PNG_INTERNAL_FUNCTION(png_structp,png_create_png_struct,
+ (png_const_charp user_png_ver, png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warn_fn, png_voidp mem_ptr, png_malloc_ptr malloc_fn,
+ png_free_ptr free_fn),PNG_ALLOCATED);
+
+/* Free memory from internal libpng struct */
+PNG_INTERNAL_FUNCTION(void,png_destroy_png_struct,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Free an allocated jmp_buf (always succeeds) */
+PNG_INTERNAL_FUNCTION(void,png_free_jmpbuf,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Function to allocate memory for zlib. PNGAPI is disallowed. */
+PNG_INTERNAL_FUNCTION(voidpf,png_zalloc,(voidpf png_ptr, uInt items, uInt size),
+ PNG_ALLOCATED);
+
+/* Function to free memory for zlib. PNGAPI is disallowed. */
+PNG_INTERNAL_FUNCTION(void,png_zfree,(voidpf png_ptr, voidpf ptr),PNG_EMPTY);
+
+/* Next four functions are used internally as callbacks. PNGCBAPI is required
+ * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3, changed to
+ * PNGCBAPI at 1.5.0
+ */
+
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_read_data,(png_structp png_ptr,
+ png_bytep data, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_push_fill_buffer,(png_structp png_ptr,
+ png_bytep buffer, png_size_t length),PNG_EMPTY);
+#endif
+
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_write_data,(png_structp png_ptr,
+ png_bytep data, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+# ifdef PNG_STDIO_SUPPORTED
+PNG_INTERNAL_FUNCTION(void PNGCBAPI,png_default_flush,(png_structp png_ptr),
+ PNG_EMPTY);
+# endif
+#endif
+
+/* Reset the CRC variable */
+PNG_INTERNAL_FUNCTION(void,png_reset_crc,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Write the "data" buffer to whatever output you are using */
+PNG_INTERNAL_FUNCTION(void,png_write_data,(png_structrp png_ptr,
+ png_const_bytep data, png_size_t length),PNG_EMPTY);
+
+/* Read and check the PNG file signature */
+PNG_INTERNAL_FUNCTION(void,png_read_sig,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+
+/* Read the chunk header (length + type name) */
+PNG_INTERNAL_FUNCTION(png_uint_32,png_read_chunk_header,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_INTERNAL_FUNCTION(void,png_read_data,(png_structrp png_ptr, png_bytep data,
+ png_size_t length),PNG_EMPTY);
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_INTERNAL_FUNCTION(void,png_crc_read,(png_structrp png_ptr, png_bytep buf,
+ png_uint_32 length),PNG_EMPTY);
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_INTERNAL_FUNCTION(int,png_crc_finish,(png_structrp png_ptr,
+ png_uint_32 skip),PNG_EMPTY);
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_INTERNAL_FUNCTION(int,png_crc_error,(png_structrp png_ptr),PNG_EMPTY);
+
+/* Calculate the CRC over a section of data. Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_INTERNAL_FUNCTION(void,png_calculate_crc,(png_structrp png_ptr,
+ png_const_bytep ptr, png_size_t length),PNG_EMPTY);
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+/* Write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
+ int compression_method, int filter_method, int interlace_method),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
+ png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,
+ png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
+ PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
+
+#ifdef PNG_WRITE_gAMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_gAMA_fixed,(png_structrp png_ptr,
+ png_fixed_point file_gamma),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_sBIT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sBIT,(png_structrp png_ptr,
+ png_const_color_8p sbit, int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_cHRM_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_cHRM_fixed,(png_structrp png_ptr,
+ const png_xy *xy), PNG_EMPTY);
+ /* The xy value must have been previously validated */
+#endif
+
+#ifdef PNG_WRITE_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sRGB,(png_structrp png_ptr,
+ int intent),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_iCCP,(png_structrp png_ptr,
+ png_const_charp name, png_const_bytep profile), PNG_EMPTY);
+ /* The profile must have been previously validated for correctness, the
+ * length comes from the first four bytes. Only the base, deflate,
+ * compression is supported.
+ */
+#endif
+
+#ifdef PNG_WRITE_sPLT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sPLT,(png_structrp png_ptr,
+ png_const_sPLT_tp palette),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_tRNS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tRNS,(png_structrp png_ptr,
+ png_const_bytep trans, png_const_color_16p values, int number,
+ int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_bKGD_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_bKGD,(png_structrp png_ptr,
+ png_const_color_16p values, int color_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_hIST_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
+ png_const_uint_16p hist, int num_hist),PNG_EMPTY);
+#endif
+
+/* Chunks that have keywords */
+#ifdef PNG_WRITE_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
+ png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_zTXt,(png_structrp png_ptr, png_const_charp
+ key, png_const_charp text, png_size_t text_len, int compression),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_iTXt,(png_structrp png_ptr,
+ int compression, png_const_charp key, png_const_charp lang,
+ png_const_charp lang_key, png_const_charp text),PNG_EMPTY);
+#endif
+
+#ifdef PNG_TEXT_SUPPORTED /* Added at version 1.0.14 and 1.2.4 */
+PNG_INTERNAL_FUNCTION(int,png_set_text_2,(png_const_structrp png_ptr,
+ png_inforp info_ptr, png_const_textp text_ptr, int num_text),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_oFFs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_oFFs,(png_structrp png_ptr,
+ png_int_32 x_offset, png_int_32 y_offset, int unit_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_pCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_pCAL,(png_structrp png_ptr,
+ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_const_charp units, png_charpp params),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_pHYs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_pHYs,(png_structrp png_ptr,
+ png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+ int unit_type),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_tIME_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_tIME,(png_structrp png_ptr,
+ png_const_timep mod_time),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_sCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_write_sCAL_s,(png_structrp png_ptr,
+ int unit, png_const_charp width, png_const_charp height),PNG_EMPTY);
+#endif
+
+/* Called when finished processing a row of data */
+PNG_INTERNAL_FUNCTION(void,png_write_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Internal use only. Called before first row of data */
+PNG_INTERNAL_FUNCTION(void,png_write_start_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+
+/* Combine a row of data, dealing with alpha, etc. if requested. 'row' is an
+ * array of png_ptr->width pixels. If the image is not interlaced or this
+ * is the final pass this just does a memcpy, otherwise the "display" flag
+ * is used to determine whether to copy pixels that are not in the current pass.
+ *
+ * Because 'png_do_read_interlace' (below) replicates pixels this allows this
+ * function to achieve the documented 'blocky' appearance during interlaced read
+ * if display is 1 and the 'sparkle' appearance, where existing pixels in 'row'
+ * are not changed if they are not in the current pass, when display is 0.
+ *
+ * 'display' must be 0 or 1, otherwise the memcpy will be done regardless.
+ *
+ * The API always reads from the png_struct row buffer and always assumes that
+ * it is full width (png_do_read_interlace has already been called.)
+ *
+ * This function is only ever used to write to row buffers provided by the
+ * caller of the relevant libpng API and the row must have already been
+ * transformed by the read transformations.
+ *
+ * The PNG_USE_COMPILE_TIME_MASKS option causes generation of pre-computed
+ * bitmasks for use within the code, otherwise runtime generated masks are used.
+ * The default is compile time masks.
+ */
+#ifndef PNG_USE_COMPILE_TIME_MASKS
+# define PNG_USE_COMPILE_TIME_MASKS 1
+#endif
+PNG_INTERNAL_FUNCTION(void,png_combine_row,(png_const_structrp png_ptr,
+ png_bytep row, int display),PNG_EMPTY);
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+/* Expand an interlaced row: the 'row_info' describes the pass data that has
+ * been read in and must correspond to the pixels in 'row', the pixels are
+ * expanded (moved apart) in 'row' to match the final layout, when doing this
+ * the pixels are *replicated* to the intervening space. This is essential for
+ * the correct operation of png_combine_row, above.
+ */
+PNG_INTERNAL_FUNCTION(void,png_do_read_interlace,(png_row_infop row_info,
+ png_bytep row, int pass, png_uint_32 transformations),PNG_EMPTY);
+#endif
+
+/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+/* Grab pixels out of a row for an interlaced pass */
+PNG_INTERNAL_FUNCTION(void,png_do_write_interlace,(png_row_infop row_info,
+ png_bytep row, int pass),PNG_EMPTY);
+#endif
+
+/* Unfilter a row: check the filter value before calling this, there is no point
+ * calling it for PNG_FILTER_VALUE_NONE.
+ */
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row,(png_structrp pp, png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row, int filter),PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_neon,(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop
+ row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY);
+
+/* Choose the best filter to use and filter the row data */
+PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
+
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
+ png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
+ /* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer
+ * is NULL the function checks, instead, for the end of the stream. In this
+ * case a benign error will be issued if the stream end is not found or if
+ * extra data has to be consumed.
+ */
+PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),
+ PNG_EMPTY);
+ /* This cleans up when the IDAT LZ stream does not end when the last image
+ * byte is read; there is still some pending input.
+ */
+
+PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+ /* Finish a row while reading, dealing with interlacing passes, etc. */
+#endif
+
+/* Initialize the row buffers, etc. */
+PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+/* Optional call to update the users info structure */
+PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+#endif
+
+/* These are the functions that do the transformations */
+#ifdef PNG_READ_FILLER_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_filler,(png_row_infop row_info,
+ png_bytep row, png_uint_32 filler, png_uint_32 flags),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_SWAP_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_swap_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_SWAP_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_write_swap_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_INVERT_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_invert_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_INVERT_ALPHA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_write_invert_alpha,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_strip_channel,(png_row_infop row_info,
+ png_bytep row, int at_start),PNG_EMPTY);
+#endif
+
+#ifdef PNG_16BIT_SUPPORTED
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_swap,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || \
+ defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_packswap,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_do_rgb_to_gray,(png_structrp png_ptr,
+ png_row_infop row_info, png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_gray_to_rgb,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_PACK_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_unpack,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_SHIFT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_unshift,(png_row_infop row_info,
+ png_bytep row, png_const_color_8p sig_bits),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_invert,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_scale_16_to_8,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_STRIP_16_TO_8_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_chop,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_quantize,(png_row_infop row_info,
+ png_bytep row, png_const_bytep palette_lookup,
+ png_const_bytep quantize_lookup),PNG_EMPTY);
+
+# ifdef PNG_CORRECT_PALETTE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_correct_palette,(png_structrp png_ptr,
+ png_colorp palette, int num_palette),PNG_EMPTY);
+# endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_bgr,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_PACK_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_pack,(png_row_infop row_info,
+ png_bytep row, png_uint_32 bit_depth),PNG_EMPTY);
+#endif
+
+#ifdef PNG_WRITE_SHIFT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_shift,(png_row_infop row_info,
+ png_bytep row, png_const_color_8p bit_depth),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_compose,(png_row_infop row_info,
+ png_bytep row, png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_gamma,(png_row_infop row_info,
+ png_bytep row, png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_ALPHA_MODE_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_encode_alpha,(png_row_infop row_info,
+ png_bytep row, png_structrp png_ptr),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_EXPAND_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_expand_palette,(png_row_infop row_info,
+ png_bytep row, png_const_colorp palette, png_const_bytep trans,
+ int num_trans),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_expand,(png_row_infop row_info,
+ png_bytep row, png_const_color_16p trans_color),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_EXPAND_16_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_expand_16,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* Decode the IHDR chunk */
+PNG_INTERNAL_FUNCTION(void,png_handle_IHDR,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_PLTE,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_handle_IEND,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+
+#ifdef PNG_READ_bKGD_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_bKGD,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_cHRM,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_gAMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_gAMA,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_hIST_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_hIST,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iCCP,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_oFFs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_oFFs,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pCAL,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_pHYs_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_pHYs,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sBIT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sBIT,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sCAL_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sCAL,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_sPLT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sPLT,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#ifdef PNG_READ_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_sRGB,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tIME_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tIME,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_tRNS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_tRNS,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+#endif
+
+PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_structrp png_ptr,
+ png_uint_32 chunk_name),PNG_EMPTY);
+
+#ifdef PNG_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY);
+ /* This is the function that gets called for unknown chunks. The 'keep'
+ * argument is either non-zero for a known chunk that has been set to be
+ * handled as unknown or zero for an unknown chunk. By default the function
+ * just skips the chunk or errors out if it is critical.
+ */
+
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_chunk_unknown_handling,
+ (png_const_structrp png_ptr, png_uint_32 chunk_name),PNG_EMPTY);
+ /* Exactly as the API png_handle_as_unknown() except that the argument is a
+ * 32-bit chunk name, not a string.
+ */
+#endif
+#endif /* PNG_READ_UNKNOWN_CHUNKS_SUPPORTED */
+#endif /* PNG_READ_SUPPORTED */
+
+/* Handle the transformations for reading and writing */
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_transformations,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
+#endif
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_write_transformations,(png_structrp png_ptr,
+ png_row_infop row_info),PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_init_read_transformations,(png_structrp png_ptr),
+ PNG_EMPTY);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_read_chunk,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_sig,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_check_crc,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_crc_skip,(png_structrp png_ptr,
+ png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_crc_finish,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_save_buffer,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_restore_buffer,(png_structrp png_ptr,
+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_IDAT,(png_structrp png_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_IDAT_data,(png_structrp png_ptr,
+ png_bytep buffer, png_size_t buffer_length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_process_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_handle_unknown,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_info,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_end,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_have_row,(png_structrp png_ptr,
+ png_bytep row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_end,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_process_some_data,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_read_push_finish_row,(png_structrp png_ptr),
+ PNG_EMPTY);
+# ifdef PNG_READ_tEXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_tEXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+# ifdef PNG_READ_zTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_zTXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+# ifdef PNG_READ_iTXt_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_push_handle_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr, png_uint_32 length),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_push_read_iTXt,(png_structrp png_ptr,
+ png_inforp info_ptr),PNG_EMPTY);
+# endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_do_read_intrapixel,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_do_write_intrapixel,(png_row_infop row_info,
+ png_bytep row),PNG_EMPTY);
+#endif
+
+/* Added at libpng version 1.6.0 */
+#ifdef PNG_GAMMA_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_gamma,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_fixed_point gAMA), PNG_EMPTY);
+ /* Set the colorspace gamma with a value provided by the application or by
+ * the gAMA chunk on read. The value will override anything set by an ICC
+ * profile.
+ */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync_info,(png_const_structrp png_ptr,
+ png_inforp info_ptr), PNG_EMPTY);
+ /* Synchronize the info 'valid' flags with the colorspace */
+
+PNG_INTERNAL_FUNCTION(void,png_colorspace_sync,(png_const_structrp png_ptr,
+ png_inforp info_ptr), PNG_EMPTY);
+ /* Copy the png_struct colorspace to the info_struct and call the above to
+ * synchronize the flags. Checks for NULL info_ptr and does nothing.
+ */
+#endif
+
+/* Added at libpng version 1.4.0 */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* These internal functions are for maintaining the colorspace structure within
+ * a png_info or png_struct (or, indeed, both).
+ */
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_chromaticities,
+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_xy *xy,
+ int preferred), PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_endpoints,
+ (png_const_structrp png_ptr, png_colorspacerp colorspace, const png_XYZ *XYZ,
+ int preferred), PNG_EMPTY);
+
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_sRGB,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, int intent), PNG_EMPTY);
+ /* This does set the colorspace gAMA and cHRM values too, but doesn't set the
+ * flags to write them, if it returns false there was a problem and an error
+ * message has already been output (but the colorspace may still need to be
+ * synced to record the invalid flag).
+ */
+#endif /* sRGB */
+
+#ifdef PNG_iCCP_SUPPORTED
+PNG_INTERNAL_FUNCTION(int,png_colorspace_set_ICC,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length, png_const_bytep profile, int color_type),
+ PNG_EMPTY);
+ /* The 'name' is used for information only */
+
+/* Routines for checking parts of an ICC profile. */
+PNG_INTERNAL_FUNCTION(int,png_icc_check_length,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length), PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_icc_check_header,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length,
+ png_const_bytep profile /* first 132 bytes only */, int color_type),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(int,png_icc_check_tag_table,(png_const_structrp png_ptr,
+ png_colorspacerp colorspace, png_const_charp name,
+ png_uint_32 profile_length,
+ png_const_bytep profile /* header plus whole tag table */), PNG_EMPTY);
+#ifdef PNG_sRGB_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_icc_set_sRGB,(
+ png_const_structrp png_ptr, png_colorspacerp colorspace,
+ png_const_bytep profile, uLong adler), PNG_EMPTY);
+ /* 'adler' is the Adler32 checksum of the uncompressed profile data. It may
+ * be zero to indicate that it is not available. It is used, if provided,
+ * as a fast check on the profile when checking to see if it is sRGB.
+ */
+#endif
+#endif /* iCCP */
+
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_colorspace_set_rgb_coefficients,
+ (png_structrp png_ptr), PNG_EMPTY);
+ /* Set the rgb_to_gray coefficients from the colorspace Y values */
+#endif /* READ_RGB_TO_GRAY */
+#endif /* COLORSPACE */
+
+/* Added at libpng version 1.4.0 */
+PNG_INTERNAL_FUNCTION(void,png_check_IHDR,(png_const_structrp png_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type),PNG_EMPTY);
+
+/* Added at libpng version 1.5.10 */
+#if defined(PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED) || \
+ defined(PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_do_check_palette_indexes,
+ (png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY);
+#endif
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && defined(PNG_ERROR_TEXT_SUPPORTED)
+PNG_INTERNAL_FUNCTION(void,png_fixed_error,(png_const_structrp png_ptr,
+ png_const_charp name),PNG_NORETURN);
+#endif
+
+/* Puts 'string' into 'buffer' at buffer[pos], taking care never to overwrite
+ * the end. Always leaves the buffer nul terminated. Never errors out (and
+ * there is no error code.)
+ */
+PNG_INTERNAL_FUNCTION(size_t,png_safecat,(png_charp buffer, size_t bufsize,
+ size_t pos, png_const_charp string),PNG_EMPTY);
+
+/* Various internal functions to handle formatted warning messages, currently
+ * only implemented for warnings.
+ */
+#if defined(PNG_WARNINGS_SUPPORTED) || defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Utility to dump an unsigned value into a buffer, given a start pointer and
+ * and end pointer (which should point just *beyond* the end of the buffer!)
+ * Returns the pointer to the start of the formatted string. This utility only
+ * does unsigned values.
+ */
+PNG_INTERNAL_FUNCTION(png_charp,png_format_number,(png_const_charp start,
+ png_charp end, int format, png_alloc_size_t number),PNG_EMPTY);
+
+/* Convenience macro that takes an array: */
+#define PNG_FORMAT_NUMBER(buffer,format,number) \
+ png_format_number(buffer, buffer + (sizeof buffer), format, number)
+
+/* Suggested size for a number buffer (enough for 64 bits and a sign!) */
+#define PNG_NUMBER_BUFFER_SIZE 24
+
+/* These are the integer formats currently supported, the name is formed from
+ * the standard printf(3) format string.
+ */
+#define PNG_NUMBER_FORMAT_u 1 /* chose unsigned API! */
+#define PNG_NUMBER_FORMAT_02u 2
+#define PNG_NUMBER_FORMAT_d 1 /* chose signed API! */
+#define PNG_NUMBER_FORMAT_02d 2
+#define PNG_NUMBER_FORMAT_x 3
+#define PNG_NUMBER_FORMAT_02x 4
+#define PNG_NUMBER_FORMAT_fixed 5 /* choose the signed API */
+#endif
+
+#ifdef PNG_WARNINGS_SUPPORTED
+/* New defines and members adding in libpng-1.5.4 */
+# define PNG_WARNING_PARAMETER_SIZE 32
+# define PNG_WARNING_PARAMETER_COUNT 8 /* Maximum 9; see pngerror.c */
+
+/* An l-value of this type has to be passed to the APIs below to cache the
+ * values of the parameters to a formatted warning message.
+ */
+typedef char png_warning_parameters[PNG_WARNING_PARAMETER_COUNT][
+ PNG_WARNING_PARAMETER_SIZE];
+
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter,(png_warning_parameters p,
+ int number, png_const_charp string),PNG_EMPTY);
+ /* Parameters are limited in size to PNG_WARNING_PARAMETER_SIZE characters,
+ * including the trailing '\0'.
+ */
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_unsigned,
+ (png_warning_parameters p, int number, int format, png_alloc_size_t value),
+ PNG_EMPTY);
+ /* Use png_alloc_size_t because it is an unsigned type as big as any we
+ * need to output. Use the following for a signed value.
+ */
+PNG_INTERNAL_FUNCTION(void,png_warning_parameter_signed,
+ (png_warning_parameters p, int number, int format, png_int_32 value),
+ PNG_EMPTY);
+
+PNG_INTERNAL_FUNCTION(void,png_formatted_warning,(png_const_structrp png_ptr,
+ png_warning_parameters p, png_const_charp message),PNG_EMPTY);
+ /* 'message' follows the X/Open approach of using @1, @2 to insert
+ * parameters previously supplied using the above functions. Errors in
+ * specifying the parameters will simply result in garbage substitutions.
+ */
+#endif
+
+#ifdef PNG_BENIGN_ERRORS_SUPPORTED
+/* Application errors (new in 1.6); use these functions (declared below) for
+ * errors in the parameters or order of API function calls on read. The
+ * 'warning' should be used for an error that can be handled completely; the
+ * 'error' for one which can be handled safely but which may lose application
+ * information or settings.
+ *
+ * By default these both result in a png_error call prior to release, while in a
+ * released version the 'warning' is just a warning. However if the application
+ * explicitly disables benign errors (explicitly permitting the code to lose
+ * information) they both turn into warnings.
+ *
+ * If benign errors aren't supported they end up as the corresponding base call
+ * (png_warning or png_error.)
+ */
+PNG_INTERNAL_FUNCTION(void,png_app_warning,(png_const_structrp png_ptr,
+ png_const_charp message),PNG_EMPTY);
+ /* The application provided invalid parameters to an API function or called
+ * an API function at the wrong time, libpng can completely recover.
+ */
+
+PNG_INTERNAL_FUNCTION(void,png_app_error,(png_const_structrp png_ptr,
+ png_const_charp message),PNG_EMPTY);
+ /* As above but libpng will ignore the call, or attempt some other partial
+ * recovery from the error.
+ */
+#else
+# define png_app_warning(pp,s) png_warning(pp,s)
+# define png_app_error(pp,s) png_error(pp,s)
+#endif
+
+PNG_INTERNAL_FUNCTION(void,png_chunk_report,(png_const_structrp png_ptr,
+ png_const_charp message, int error),PNG_EMPTY);
+ /* Report a recoverable issue in chunk data. On read this is used to report
+ * a problem found while reading a particular chunk and the
+ * png_chunk_benign_error or png_chunk_warning function is used as
+ * appropriate. On write this is used to report an error that comes from
+ * data set via an application call to a png_set_ API and png_app_error or
+ * png_app_warning is used as appropriate.
+ *
+ * The 'error' parameter must have one of the following values:
+ */
+#define PNG_CHUNK_WARNING 0 /* never an error */
+#define PNG_CHUNK_WRITE_ERROR 1 /* an error only on write */
+#define PNG_CHUNK_ERROR 2 /* always an error */
+
+/* ASCII to FP interfaces, currently only implemented if sCAL
+ * support is required.
+ */
+#if defined(PNG_sCAL_SUPPORTED)
+/* MAX_DIGITS is actually the maximum number of characters in an sCAL
+ * width or height, derived from the precision (number of significant
+ * digits - a build time settable option) and assumptions about the
+ * maximum ridiculous exponent.
+ */
+#define PNG_sCAL_MAX_DIGITS (PNG_sCAL_PRECISION+1/*.*/+1/*E*/+10/*exponent*/)
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fp,(png_const_structrp png_ptr,
+ png_charp ascii, png_size_t size, double fp, unsigned int precision),
+ PNG_EMPTY);
+#endif /* FLOATING_POINT */
+
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_ascii_from_fixed,(png_const_structrp png_ptr,
+ png_charp ascii, png_size_t size, png_fixed_point fp),PNG_EMPTY);
+#endif /* FIXED_POINT */
+#endif /* sCAL */
+
+#if defined(PNG_sCAL_SUPPORTED) || defined(PNG_pCAL_SUPPORTED)
+/* An internal API to validate the format of a floating point number.
+ * The result is the index of the next character. If the number is
+ * not valid it will be the index of a character in the supposed number.
+ *
+ * The format of a number is defined in the PNG extensions specification
+ * and this API is strictly conformant to that spec, not anyone elses!
+ *
+ * The format as a regular expression is:
+ *
+ * [+-]?[0-9]+.?([Ee][+-]?[0-9]+)?
+ *
+ * or:
+ *
+ * [+-]?.[0-9]+(.[0-9]+)?([Ee][+-]?[0-9]+)?
+ *
+ * The complexity is that either integer or fraction must be present and the
+ * fraction is permitted to have no digits only if the integer is present.
+ *
+ * NOTE: The dangling E problem.
+ * There is a PNG valid floating point number in the following:
+ *
+ * PNG floating point numbers are not greedy.
+ *
+ * Working this out requires *TWO* character lookahead (because of the
+ * sign), the parser does not do this - it will fail at the 'r' - this
+ * doesn't matter for PNG sCAL chunk values, but it requires more care
+ * if the value were ever to be embedded in something more complex. Use
+ * ANSI-C strtod if you need the lookahead.
+ */
+/* State table for the parser. */
+#define PNG_FP_INTEGER 0 /* before or in integer */
+#define PNG_FP_FRACTION 1 /* before or in fraction */
+#define PNG_FP_EXPONENT 2 /* before or in exponent */
+#define PNG_FP_STATE 3 /* mask for the above */
+#define PNG_FP_SAW_SIGN 4 /* Saw +/- in current state */
+#define PNG_FP_SAW_DIGIT 8 /* Saw a digit in current state */
+#define PNG_FP_SAW_DOT 16 /* Saw a dot in current state */
+#define PNG_FP_SAW_E 32 /* Saw an E (or e) in current state */
+#define PNG_FP_SAW_ANY 60 /* Saw any of the above 4 */
+
+/* These three values don't affect the parser. They are set but not used.
+ */
+#define PNG_FP_WAS_VALID 64 /* Preceding substring is a valid fp number */
+#define PNG_FP_NEGATIVE 128 /* A negative number, including "-0" */
+#define PNG_FP_NONZERO 256 /* A non-zero value */
+#define PNG_FP_STICKY 448 /* The above three flags */
+
+/* This is available for the caller to store in 'state' if required. Do not
+ * call the parser after setting it (the parser sometimes clears it.)
+ */
+#define PNG_FP_INVALID 512 /* Available for callers as a distinct value */
+
+/* Result codes for the parser (boolean - true meants ok, false means
+ * not ok yet.)
+ */
+#define PNG_FP_MAYBE 0 /* The number may be valid in the future */
+#define PNG_FP_OK 1 /* The number is valid */
+
+/* Tests on the sticky non-zero and negative flags. To pass these checks
+ * the state must also indicate that the whole number is valid - this is
+ * achieved by testing PNG_FP_SAW_DIGIT (see the implementation for why this
+ * is equivalent to PNG_FP_OK above.)
+ */
+#define PNG_FP_NZ_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NEGATIVE | PNG_FP_NONZERO)
+ /* NZ_MASK: the string is valid and a non-zero negative value */
+#define PNG_FP_Z_MASK (PNG_FP_SAW_DIGIT | PNG_FP_NONZERO)
+ /* Z MASK: the string is valid and a non-zero value. */
+ /* PNG_FP_SAW_DIGIT: the string is valid. */
+#define PNG_FP_IS_ZERO(state) (((state) & PNG_FP_Z_MASK) == PNG_FP_SAW_DIGIT)
+#define PNG_FP_IS_POSITIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_Z_MASK)
+#define PNG_FP_IS_NEGATIVE(state) (((state) & PNG_FP_NZ_MASK) == PNG_FP_NZ_MASK)
+
+/* The actual parser. This can be called repeatedly. It updates
+ * the index into the string and the state variable (which must
+ * be initialized to 0). It returns a result code, as above. There
+ * is no point calling the parser any more if it fails to advance to
+ * the end of the string - it is stuck on an invalid character (or
+ * terminated by '\0').
+ *
+ * Note that the pointer will consume an E or even an E+ and then leave
+ * a 'maybe' state even though a preceding integer.fraction is valid.
+ * The PNG_FP_WAS_VALID flag indicates that a preceding substring was
+ * a valid number. It's possible to recover from this by calling
+ * the parser again (from the start, with state 0) but with a string
+ * that omits the last character (i.e. set the size to the index of
+ * the problem character.) This has not been tested within libpng.
+ */
+PNG_INTERNAL_FUNCTION(int,png_check_fp_number,(png_const_charp string,
+ png_size_t size, int *statep, png_size_tp whereami),PNG_EMPTY);
+
+/* This is the same but it checks a complete string and returns true
+ * only if it just contains a floating point number. As of 1.5.4 this
+ * function also returns the state at the end of parsing the number if
+ * it was valid (otherwise it returns 0.) This can be used for testing
+ * for negative or zero values using the sticky flag.
+ */
+PNG_INTERNAL_FUNCTION(int,png_check_fp_string,(png_const_charp string,
+ png_size_t size),PNG_EMPTY);
+#endif /* pCAL || sCAL */
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) ||\
+ defined(PNG_INCH_CONVERSIONS_SUPPORTED) || defined(PNG_READ_pHYs_SUPPORTED)
+/* Added at libpng version 1.5.0 */
+/* This is a utility to provide a*times/div (rounded) and indicate
+ * if there is an overflow. The result is a boolean - false (0)
+ * for overflow, true (1) if no overflow, in which case *res
+ * holds the result.
+ */
+PNG_INTERNAL_FUNCTION(int,png_muldiv,(png_fixed_point_p res, png_fixed_point a,
+ png_int_32 multiplied_by, png_int_32 divided_by),PNG_EMPTY);
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED)
+/* Same deal, but issue a warning on overflow and return 0. */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_muldiv_warn,
+ (png_const_structrp png_ptr, png_fixed_point a, png_int_32 multiplied_by,
+ png_int_32 divided_by),PNG_EMPTY);
+#endif
+
+#ifdef PNG_GAMMA_SUPPORTED
+/* Calculate a reciprocal - used for gamma values. This returns
+ * 0 if the argument is 0 in order to maintain an undefined value;
+ * there are no warnings.
+ */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal,(png_fixed_point a),
+ PNG_EMPTY);
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* The same but gives a reciprocal of the product of two fixed point
+ * values. Accuracy is suitable for gamma calculations but this is
+ * not exact - use png_muldiv for that. Only required at present on read.
+ */
+PNG_INTERNAL_FUNCTION(png_fixed_point,png_reciprocal2,(png_fixed_point a,
+ png_fixed_point b),PNG_EMPTY);
+#endif
+
+/* Return true if the gamma value is significantly different from 1.0 */
+PNG_INTERNAL_FUNCTION(int,png_gamma_significant,(png_fixed_point gamma_value),
+ PNG_EMPTY);
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+/* Internal fixed point gamma correction. These APIs are called as
+ * required to convert single values - they don't need to be fast,
+ * they are not used when processing image pixel values.
+ *
+ * While the input is an 'unsigned' value it must actually be the
+ * correct bit value - 0..255 or 0..65535 as required.
+ */
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_correct,(png_structrp png_ptr,
+ unsigned int value, png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_uint_16,png_gamma_16bit_correct,(unsigned int value,
+ png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(png_byte,png_gamma_8bit_correct,(unsigned int value,
+ png_fixed_point gamma_value),PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_destroy_gamma_table,(png_structrp png_ptr),
+ PNG_EMPTY);
+PNG_INTERNAL_FUNCTION(void,png_build_gamma_table,(png_structrp png_ptr,
+ int bit_depth),PNG_EMPTY);
+#endif
+
+/* SIMPLIFIED READ/WRITE SUPPORT */
+#if defined(PNG_SIMPLIFIED_READ_SUPPORTED) ||\
+ defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
+/* The internal structure that png_image::opaque points to. */
+typedef struct png_control
+{
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_voidp error_buf; /* Always a jmp_buf at present. */
+
+ png_const_bytep memory; /* Memory buffer. */
+ png_size_t size; /* Size of the memory buffer. */
+
+ unsigned int for_write :1; /* Otherwise it is a read structure */
+ unsigned int owned_file :1; /* We own the file in io_ptr */
+} png_control;
+
+/* Return the pointer to the jmp_buf from a png_control: necessary because C
+ * does not reveal the type of the elements of jmp_buf.
+ */
+#ifdef __cplusplus
+# define png_control_jmp_buf(pc) (((jmp_buf*)((pc)->error_buf))[0])
+#else
+# define png_control_jmp_buf(pc) ((pc)->error_buf)
+#endif
+
+/* Utility to safely execute a piece of libpng code catching and logging any
+ * errors that might occur. Returns true on success, false on failure (either
+ * of the function or as a result of a png_error.)
+ */
+PNG_INTERNAL_FUNCTION(void,png_safe_error,(png_structp png_ptr,
+ png_const_charp error_message),PNG_NORETURN);
+
+#ifdef PNG_WARNINGS_SUPPORTED
+PNG_INTERNAL_FUNCTION(void,png_safe_warning,(png_structp png_ptr,
+ png_const_charp warning_message),PNG_EMPTY);
+#else
+# define png_safe_warning 0/*dummy argument*/
+#endif
+
+PNG_INTERNAL_FUNCTION(int,png_safe_execute,(png_imagep image,
+ int (*function)(png_voidp), png_voidp arg),PNG_EMPTY);
+
+/* Utility to log an error; this also cleans up the png_image; the function
+ * always returns 0 (false).
+ */
+PNG_INTERNAL_FUNCTION(int,png_image_error,(png_imagep image,
+ png_const_charp error_message),PNG_EMPTY);
+
+#ifndef PNG_SIMPLIFIED_READ_SUPPORTED
+/* png_image_free is used by the write code but not exported */
+PNG_INTERNAL_FUNCTION(void, png_image_free, (png_imagep image), PNG_EMPTY);
+#endif /* !SIMPLIFIED_READ */
+
+#endif /* SIMPLIFIED READ/WRITE */
+
+/* These are initialization functions for hardware specific PNG filter
+ * optimizations; list these here then select the appropriate one at compile
+ * time using the macro PNG_FILTER_OPTIMIZATIONS. If the macro is not defined
+ * the generic code is used.
+ */
+#ifdef PNG_FILTER_OPTIMIZATIONS
+PNG_INTERNAL_FUNCTION(void, PNG_FILTER_OPTIMIZATIONS, (png_structp png_ptr,
+ unsigned int bpp), PNG_EMPTY);
+ /* Just declare the optimization that will be used */
+#else
+ /* List *all* the possible optimizations here - this branch is required if
+ * the builder of libpng passes the definition of PNG_FILTER_OPTIMIZATIONS in
+ * CFLAGS in place of CPPFLAGS *and* uses symbol prefixing.
+ */
+PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon,
+ (png_structp png_ptr, unsigned int bpp), PNG_EMPTY);
+#endif
+
+/* Maintainer: Put new private prototypes here ^ */
+
+#include "pngdebug.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+#endif /* PNGPRIV_H */
diff --git a/core/src/fxcodec/fx_lpng/lpng_v163/pngstruct.h b/core/src/fxcodec/fx_lpng/lpng_v163/pngstruct.h
new file mode 100644
index 0000000000..269470531e
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/lpng_v163/pngstruct.h
@@ -0,0 +1,489 @@
+
+/* pngstruct.h - header file for PNG reference library
+ *
+ * Copyright (c) 1998-2013 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Last changed in libpng 1.6.1 [March 28, 2013]
+ *
+ * This code is released under the libpng license.
+ * For conditions of distribution and use, see the disclaimer
+ * and license in png.h
+ */
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application.
+ */
+
+#ifndef PNGSTRUCT_H
+#define PNGSTRUCT_H
+/* zlib.h defines the structure z_stream, an instance of which is included
+ * in this structure and is required for decompressing the LZ compressed
+ * data in PNG files.
+ */
+#ifndef ZLIB_CONST
+ /* We must ensure that zlib uses 'const' in declarations. */
+# define ZLIB_CONST
+#endif
+#include "../../fx_zlib/include/fx_zlib.h"
+#ifdef const
+ /* zlib.h sometimes #defines const to nothing, undo this. */
+# undef const
+#endif
+
+/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
+ * with older builds.
+ */
+#if ZLIB_VERNUM < 0x1260
+# define PNGZ_MSG_CAST(s) png_constcast(char*,s)
+# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
+#else
+# define PNGZ_MSG_CAST(s) (s)
+# define PNGZ_INPUT_CAST(b) (b)
+#endif
+
+/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
+ * can handle at once. This type need be no larger than 16 bits (so maximum of
+ * 65535), this define allows us to discover how big it is, but limited by the
+ * maximuum for png_size_t. The value can be overriden in a library build
+ * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
+ * lower value (e.g. 255 works). A lower value may help memory usage (slightly)
+ * and may even improve performance on some systems (and degrade it on others.)
+ */
+#ifndef ZLIB_IO_MAX
+# define ZLIB_IO_MAX ((uInt)-1)
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+/* The type of a compression buffer list used by the write code. */
+typedef struct png_compression_buffer
+{
+ struct png_compression_buffer *next;
+ png_byte output[1]; /* actually zbuf_size */
+} png_compression_buffer, *png_compression_bufferp;
+
+#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
+ (offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
+#endif
+
+/* Colorspace support; structures used in png_struct, png_info and in internal
+ * functions to hold and communicate information about the color space.
+ *
+ * PNG_COLORSPACE_SUPPORTED is only required if the application will perform
+ * colorspace corrections, otherwise all the colorspace information can be
+ * skipped and the size of libpng can be reduced (significantly) by compiling
+ * out the colorspace support.
+ */
+#ifdef PNG_COLORSPACE_SUPPORTED
+/* The chromaticities of the red, green and blue colorants and the chromaticity
+ * of the corresponding white point (i.e. of rgb(1.0,1.0,1.0)).
+ */
+typedef struct png_xy
+{
+ png_fixed_point redx, redy;
+ png_fixed_point greenx, greeny;
+ png_fixed_point bluex, bluey;
+ png_fixed_point whitex, whitey;
+} png_xy;
+
+/* The same data as above but encoded as CIE XYZ values. When this data comes
+ * from chromaticities the sum of the Y values is assumed to be 1.0
+ */
+typedef struct png_XYZ
+{
+ png_fixed_point red_X, red_Y, red_Z;
+ png_fixed_point green_X, green_Y, green_Z;
+ png_fixed_point blue_X, blue_Y, blue_Z;
+} png_XYZ;
+#endif /* COLORSPACE */
+
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+/* A colorspace is all the above plus, potentially, profile information,
+ * however at present libpng does not use the profile internally so it is only
+ * stored in the png_info struct (if iCCP is supported.) The rendering intent
+ * is retained here and is checked.
+ *
+ * The file gamma encoding information is also stored here and gamma correction
+ * is done by libpng, whereas color correction must currently be done by the
+ * application.
+ */
+typedef struct png_colorspace
+{
+#ifdef PNG_GAMMA_SUPPORTED
+ png_fixed_point gamma; /* File gamma */
+#endif
+
+#ifdef PNG_COLORSPACE_SUPPORTED
+ png_xy end_points_xy; /* End points as chromaticities */
+ png_XYZ end_points_XYZ; /* End points as CIE XYZ colorant values */
+ png_uint_16 rendering_intent; /* Rendering intent of a profile */
+#endif
+
+ /* Flags are always defined to simplify the code. */
+ png_uint_16 flags; /* As defined below */
+} png_colorspace, * PNG_RESTRICT png_colorspacerp;
+
+typedef const png_colorspace * PNG_RESTRICT png_const_colorspacerp;
+
+/* General flags for the 'flags' field */
+#define PNG_COLORSPACE_HAVE_GAMMA 0x0001
+#define PNG_COLORSPACE_HAVE_ENDPOINTS 0x0002
+#define PNG_COLORSPACE_HAVE_INTENT 0x0004
+#define PNG_COLORSPACE_FROM_gAMA 0x0008
+#define PNG_COLORSPACE_FROM_cHRM 0x0010
+#define PNG_COLORSPACE_FROM_sRGB 0x0020
+#define PNG_COLORSPACE_ENDPOINTS_MATCH_sRGB 0x0040
+#define PNG_COLORSPACE_MATCHES_sRGB 0x0080 /* exact match on profile */
+#define PNG_COLORSPACE_INVALID 0x8000
+#define PNG_COLORSPACE_CANCEL(flags) (0xffff ^ (flags))
+#endif /* COLORSPACE || GAMMA */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf jmp_buf_local; /* New name in 1.6.0 for jmp_buf in png_struct */
+ png_longjmp_ptr longjmp_fn;/* setjmp non-local goto function. */
+ jmp_buf *jmp_buf_ptr; /* passed to longjmp_fn */
+ size_t jmp_buf_size; /* size of the above, if allocated */
+#endif
+ png_error_ptr error_fn; /* function for printing errors and aborting */
+#ifdef PNG_WARNINGS_SUPPORTED
+ png_error_ptr warning_fn; /* function for printing warnings */
+#endif
+ png_voidp error_ptr; /* user supplied struct for error functions */
+ png_rw_ptr write_data_fn; /* function for writing output data */
+ png_rw_ptr read_data_fn; /* function for reading input data */
+ png_voidp io_ptr; /* ptr to application struct for I/O functions */
+
+#ifdef PNG_READ_USER_TRANSFORM_SUPPORTED
+ png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+
+#ifdef PNG_WRITE_USER_TRANSFORM_SUPPORTED
+ png_user_transform_ptr write_user_transform_fn; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#ifdef PNG_USER_TRANSFORM_PTR_SUPPORTED
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ png_voidp user_transform_ptr; /* user supplied struct for user transform */
+ png_byte user_transform_depth; /* bit depth of user transformed pixels */
+ png_byte user_transform_channels; /* channels in user transformed pixels */
+#endif
+#endif
+
+ png_uint_32 mode; /* tells us where we are in the PNG file */
+ png_uint_32 flags; /* flags indicating various things to libpng */
+ png_uint_32 transformations; /* which transformations to perform */
+
+ png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
+ z_stream zstream; /* decompression structure */
+
+#ifdef PNG_WRITE_SUPPORTED
+ png_compression_bufferp zbuffer_list; /* Created on demand during write */
+ uInt zbuffer_size; /* size of the actual buffer */
+
+ int zlib_level; /* holds zlib compression level */
+ int zlib_method; /* holds zlib compression method */
+ int zlib_window_bits; /* holds zlib compression window bits */
+ int zlib_mem_level; /* holds zlib compression memory level */
+ int zlib_strategy; /* holds zlib compression strategy */
+#endif
+/* Added at libpng 1.5.4 */
+#ifdef PNG_WRITE_CUSTOMIZE_ZTXT_COMPRESSION_SUPPORTED
+ int zlib_text_level; /* holds zlib compression level */
+ int zlib_text_method; /* holds zlib compression method */
+ int zlib_text_window_bits; /* holds zlib compression window bits */
+ int zlib_text_mem_level; /* holds zlib compression memory level */
+ int zlib_text_strategy; /* holds zlib compression strategy */
+#endif
+/* End of material added at libpng 1.5.4 */
+/* Added at libpng 1.6.0 */
+#ifdef PNG_WRITE_SUPPORTED
+ int zlib_set_level; /* Actual values set into the zstream on write */
+ int zlib_set_method;
+ int zlib_set_window_bits;
+ int zlib_set_mem_level;
+ int zlib_set_strategy;
+#endif
+
+ png_uint_32 width; /* width of image in pixels */
+ png_uint_32 height; /* height of image in pixels */
+ png_uint_32 num_rows; /* number of rows in current pass */
+ png_uint_32 usr_width; /* width of row at start of write */
+ png_size_t rowbytes; /* size of row in bytes */
+ png_uint_32 iwidth; /* width of current interlaced row in pixels */
+ png_uint_32 row_number; /* current row in interlace pass */
+ png_uint_32 chunk_name; /* PNG_CHUNK() id of current chunk */
+ png_bytep prev_row; /* buffer to save previous (unfiltered) row.
+ * This is a pointer into big_prev_row
+ */
+ png_bytep row_buf; /* buffer to save current (unfiltered) row.
+ * This is a pointer into big_row_buf
+ */
+#ifdef PNG_WRITE_SUPPORTED
+ png_bytep sub_row; /* buffer to save "sub" row when filtering */
+ png_bytep up_row; /* buffer to save "up" row when filtering */
+ png_bytep avg_row; /* buffer to save "avg" row when filtering */
+ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
+#endif
+ png_size_t info_rowbytes; /* Added in 1.5.4: cache of updated row bytes */
+
+ png_uint_32 idat_size; /* current IDAT size for read */
+ png_uint_32 crc; /* current chunk CRC value */
+ png_colorp palette; /* palette from the input file */
+ png_uint_16 num_palette; /* number of color entries in palette */
+
+/* Added at libpng-1.5.10 */
+#ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED
+ int num_palette_max; /* maximum palette index found in IDAT */
+#endif
+
+ png_uint_16 num_trans; /* number of transparency values */
+ png_byte compression; /* file compression type (always 0) */
+ png_byte filter; /* file filter type (always 0) */
+ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+ png_byte pass; /* current interlace pass (0 - 6) */
+ png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
+ png_byte color_type; /* color type of file */
+ png_byte bit_depth; /* bit depth of file */
+ png_byte usr_bit_depth; /* bit depth of users row: write only */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte channels; /* number of channels in file */
+#ifdef PNG_WRITE_SUPPORTED
+ png_byte usr_channels; /* channels at start of write: write only */
+#endif
+ png_byte sig_bytes; /* magic bytes read/written from start of file */
+ png_byte maximum_pixel_depth;
+ /* pixel depth used for the row buffers */
+ png_byte transformed_pixel_depth;
+ /* pixel depth after read/write transforms */
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+ png_uint_16 filler; /* filler bytes for pixel expansion */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) ||\
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED)
+ png_byte background_gamma_type;
+ png_fixed_point background_gamma;
+ png_color_16 background; /* background color in screen gamma space */
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ png_color_16 background_1; /* background normalized to gamma 1.0 */
+#endif
+#endif /* PNG_bKGD_SUPPORTED */
+
+#ifdef PNG_WRITE_FLUSH_SUPPORTED
+ png_flush_ptr output_flush_fn; /* Function for flushing output */
+ png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
+ png_uint_32 flush_rows; /* number of rows written since last flush */
+#endif
+
+#ifdef PNG_READ_GAMMA_SUPPORTED
+ int gamma_shift; /* number of "insignificant" bits in 16-bit gamma */
+ png_fixed_point screen_gamma; /* screen gamma value (display_exponent) */
+
+ png_bytep gamma_table; /* gamma table for 8-bit depth files */
+ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_ALPHA_MODE_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ png_bytep gamma_from_1; /* converts from 1.0 to screen */
+ png_bytep gamma_to_1; /* converts from file to 1.0 */
+ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
+ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
+#endif /* READ_BACKGROUND || READ_ALPHA_MODE || RGB_TO_GRAY */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+ png_color_8 sig_bit; /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+ png_color_8 shift; /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep trans_alpha; /* alpha values for paletted files */
+ png_color_16 trans_color; /* transparent color for non-paletted files */
+#endif
+
+ png_read_status_ptr read_row_fn; /* called after each row is decoded */
+ png_write_status_ptr write_row_fn; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_progressive_info_ptr info_fn; /* called after header data fully read */
+ png_progressive_row_ptr row_fn; /* called after a prog. row is decoded */
+ png_progressive_end_ptr end_fn; /* called after image is complete */
+ png_bytep save_buffer_ptr; /* current location in save_buffer */
+ png_bytep save_buffer; /* buffer for previously read data */
+ png_bytep current_buffer_ptr; /* current location in current_buffer */
+ png_bytep current_buffer; /* buffer for recently used data */
+ png_uint_32 push_length; /* size of current input chunk */
+ png_uint_32 skip_length; /* bytes to skip in input data */
+ png_size_t save_buffer_size; /* amount of data now in save_buffer */
+ png_size_t save_buffer_max; /* total size of save_buffer */
+ png_size_t buffer_size; /* total amount of available input data */
+ png_size_t current_buffer_size; /* amount of data now in current_buffer */
+ int process_mode; /* what push library is currently doing */
+ int cur_palette; /* current push library palette index */
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* For the Borland special 64K segment handler */
+ png_bytepp offset_table_ptr;
+ png_bytep offset_table;
+ png_uint_16 offset_table_number;
+ png_uint_16 offset_table_count;
+ png_uint_16 offset_table_count_free;
+#endif
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+ png_bytep palette_lookup; /* lookup table for quantizing */
+ png_bytep quantize_index; /* index translation for palette files */
+#endif
+
+#ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+ png_byte heuristic_method; /* heuristic for row filter selection */
+ png_byte num_prev_filters; /* number of weights for previous rows */
+ png_bytep prev_filters; /* filter type(s) of previous row(s) */
+ png_uint_16p filter_weights; /* weight(s) for previous line(s) */
+ png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
+ png_uint_16p filter_costs; /* relative filter calculation cost */
+ png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
+#endif
+
+ /* Options */
+#ifdef PNG_SET_OPTION_SUPPORTED
+ png_byte options; /* On/off state (up to 4 options) */
+#endif
+
+#if PNG_LIBPNG_VER < 10700
+/* To do: remove this from libpng-1.7 */
+#ifdef PNG_TIME_RFC1123_SUPPORTED
+ char time_buffer[29]; /* String to hold RFC 1123 time text */
+#endif
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+ png_voidp user_chunk_ptr;
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
+ png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
+#endif
+#endif
+
+#ifdef PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
+ int unknown_default; /* As PNG_HANDLE_* */
+ unsigned int num_chunk_list; /* Number of entries in the list */
+ png_bytep chunk_list; /* List of png_byte[5]; the textual chunk name
+ * followed by a PNG_HANDLE_* byte */
+#endif
+
+/* New members added in libpng-1.0.3 */
+#ifdef PNG_READ_RGB_TO_GRAY_SUPPORTED
+ png_byte rgb_to_gray_status;
+ /* Added in libpng 1.5.5 to record setting of coefficients: */
+ png_byte rgb_to_gray_coefficients_set;
+ /* These were changed from png_byte in libpng-1.0.6 */
+ png_uint_16 rgb_to_gray_red_coeff;
+ png_uint_16 rgb_to_gray_green_coeff;
+ /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* Changed from png_byte to png_uint_32 at version 1.2.0 */
+ png_uint_32 mng_features_permitted;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+ png_byte filter_type;
+#endif
+
+/* New members added in libpng-1.2.0 */
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_voidp mem_ptr; /* user supplied struct for mem functions */
+ png_malloc_ptr malloc_fn; /* function for allocating memory */
+ png_free_ptr free_fn; /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+ png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
+
+#ifdef PNG_READ_QUANTIZE_SUPPORTED
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+ png_bytep quantize_sort; /* working sort array */
+ png_bytep index_to_palette; /* where the original index currently is
+ in the palette */
+ png_bytep palette_to_index; /* which original index points to this
+ palette color */
+#endif
+
+/* New members added in libpng-1.0.16 and 1.2.6 */
+ png_byte compression_type;
+
+#ifdef PNG_USER_LIMITS_SUPPORTED
+ png_uint_32 user_width_max;
+ png_uint_32 user_height_max;
+
+ /* Added in libpng-1.4.0: Total number of sPLT, text, and unknown
+ * chunks that can be stored (0 means unlimited).
+ */
+ png_uint_32 user_chunk_cache_max;
+
+ /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
+ * can occupy when decompressed. 0 means unlimited.
+ */
+ png_alloc_size_t user_chunk_malloc_max;
+#endif
+
+/* New member added in libpng-1.0.25 and 1.2.17 */
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+ /* Temporary storage for unknown chunk that the library doesn't recognize,
+ * used while reading the chunk.
+ */
+ png_unknown_chunk unknown_chunk;
+#endif
+
+/* New member added in libpng-1.2.26 */
+ png_size_t old_big_row_buf_size;
+
+#ifdef PNG_READ_SUPPORTED
+/* New member added in libpng-1.2.30 */
+ png_bytep read_buffer; /* buffer for reading chunk data */
+ png_alloc_size_t read_buffer_size; /* current size of the buffer */
+#endif
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
+ uInt IDAT_read_size; /* limit on read buffer size for IDAT */
+#endif
+
+#ifdef PNG_IO_STATE_SUPPORTED
+/* New member added in libpng-1.4.0 */
+ png_uint_32 io_state;
+#endif
+
+/* New member added in libpng-1.5.6 */
+ png_bytep big_prev_row;
+
+/* New member added in libpng-1.5.7 */
+ void (*read_filter[PNG_FILTER_VALUE_LAST-1])(png_row_infop row_info,
+ png_bytep row, png_const_bytep prev_row);
+
+#ifdef PNG_READ_SUPPORTED
+#if defined(PNG_COLORSPACE_SUPPORTED) || defined(PNG_GAMMA_SUPPORTED)
+ png_colorspace colorspace;
+#endif
+#endif
+};
+#endif /* PNGSTRUCT_H */
diff --git a/core/src/fxcodec/fx_lpng/src/fx_png.c b/core/src/fxcodec/fx_lpng/src/fx_png.c
new file mode 100644
index 0000000000..7b6582666f
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_png.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_png.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngerror.c b/core/src/fxcodec/fx_lpng/src/fx_pngerror.c
new file mode 100644
index 0000000000..7581b99130
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngerror.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngerror.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngget.c b/core/src/fxcodec/fx_lpng/src/fx_pngget.c
new file mode 100644
index 0000000000..cc8dc4e6b7
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngget.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngget.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngmem.c b/core/src/fxcodec/fx_lpng/src/fx_pngmem.c
new file mode 100644
index 0000000000..9892408d70
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngmem.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngmem.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngpread.c b/core/src/fxcodec/fx_lpng/src/fx_pngpread.c
new file mode 100644
index 0000000000..8d53be20a6
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngpread.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngpread.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngread.c b/core/src/fxcodec/fx_lpng/src/fx_pngread.c
new file mode 100644
index 0000000000..c612bd533e
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngread.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngread.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngrio.c b/core/src/fxcodec/fx_lpng/src/fx_pngrio.c
new file mode 100644
index 0000000000..d324a8e6e5
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngrio.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngrio.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngrtran.c b/core/src/fxcodec/fx_lpng/src/fx_pngrtran.c
new file mode 100644
index 0000000000..bec380dc3c
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngrtran.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngrtran.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngrutil.c b/core/src/fxcodec/fx_lpng/src/fx_pngrutil.c
new file mode 100644
index 0000000000..a3da3555e3
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngrutil.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngrutil.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngset.c b/core/src/fxcodec/fx_lpng/src/fx_pngset.c
new file mode 100644
index 0000000000..76a72223f2
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngset.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngset.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngtrans.c b/core/src/fxcodec/fx_lpng/src/fx_pngtrans.c
new file mode 100644
index 0000000000..eac49bf227
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngtrans.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngtrans.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngwio.c b/core/src/fxcodec/fx_lpng/src/fx_pngwio.c
new file mode 100644
index 0000000000..3fb21e5b0b
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngwio.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngwio.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngwrite.c b/core/src/fxcodec/fx_lpng/src/fx_pngwrite.c
new file mode 100644
index 0000000000..4434fd0cb4
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngwrite.c
@@ -0,0 +1,10 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+#include "../lpng_v163/fx_pngwrite.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngwtran.c b/core/src/fxcodec/fx_lpng/src/fx_pngwtran.c
new file mode 100644
index 0000000000..8a095d3565
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngwtran.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngwtran.c"
diff --git a/core/src/fxcodec/fx_lpng/src/fx_pngwutil.c b/core/src/fxcodec/fx_lpng/src/fx_pngwutil.c
new file mode 100644
index 0000000000..b07fb40500
--- /dev/null
+++ b/core/src/fxcodec/fx_lpng/src/fx_pngwutil.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../lpng_v163/fx_pngwutil.c"
diff --git a/core/src/fxcodec/fx_tiff/include/fx_tiffiop.h b/core/src/fxcodec/fx_tiff/include/fx_tiffiop.h
new file mode 100644
index 0000000000..8c78903025
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/include/fx_tiffiop.h
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tiffiop.h"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_aux.c b/core/src/fxcodec/fx_tiff/src/fx_tif_aux.c
new file mode 100644
index 0000000000..55d4f650cf
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_aux.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_aux.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_close.c b/core/src/fxcodec/fx_tiff/src/fx_tif_close.c
new file mode 100644
index 0000000000..3645bd29bd
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_close.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_close.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_codec.c b/core/src/fxcodec/fx_tiff/src/fx_tif_codec.c
new file mode 100644
index 0000000000..183622f659
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_codec.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_codec.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_color.c b/core/src/fxcodec/fx_tiff/src/fx_tif_color.c
new file mode 100644
index 0000000000..ce0f6fb252
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_color.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_color.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_compress.c b/core/src/fxcodec/fx_tiff/src/fx_tif_compress.c
new file mode 100644
index 0000000000..cdbf26c71e
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_compress.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_compress.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_dir.c b/core/src/fxcodec/fx_tiff/src/fx_tif_dir.c
new file mode 100644
index 0000000000..2dc94bb60f
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_dir.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_dir.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_dirinfo.c b/core/src/fxcodec/fx_tiff/src/fx_tif_dirinfo.c
new file mode 100644
index 0000000000..5481733e46
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_dirinfo.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_dirinfo.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_dirread.c b/core/src/fxcodec/fx_tiff/src/fx_tif_dirread.c
new file mode 100644
index 0000000000..ef57dfde21
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_dirread.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_dirread.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_dirwrite.c b/core/src/fxcodec/fx_tiff/src/fx_tif_dirwrite.c
new file mode 100644
index 0000000000..daee77ba0e
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_dirwrite.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_dirwrite.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_dumpmode.c b/core/src/fxcodec/fx_tiff/src/fx_tif_dumpmode.c
new file mode 100644
index 0000000000..1ece3b8322
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_dumpmode.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_dumpmode.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_error.c b/core/src/fxcodec/fx_tiff/src/fx_tif_error.c
new file mode 100644
index 0000000000..8693e9d359
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_error.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_error.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_extension.c b/core/src/fxcodec/fx_tiff/src/fx_tif_extension.c
new file mode 100644
index 0000000000..3b92492098
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_extension.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_extension.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_fax3.c b/core/src/fxcodec/fx_tiff/src/fx_tif_fax3.c
new file mode 100644
index 0000000000..68d26de22d
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_fax3.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_fax3.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_fax3sm.c b/core/src/fxcodec/fx_tiff/src/fx_tif_fax3sm.c
new file mode 100644
index 0000000000..aa633e7b7e
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_fax3sm.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_fax3sm.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_flush.c b/core/src/fxcodec/fx_tiff/src/fx_tif_flush.c
new file mode 100644
index 0000000000..40884c8c37
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_flush.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_flush.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_getimage.c b/core/src/fxcodec/fx_tiff/src/fx_tif_getimage.c
new file mode 100644
index 0000000000..15c8ee46fb
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_getimage.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_getimage.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_jpeg.c b/core/src/fxcodec/fx_tiff/src/fx_tif_jpeg.c
new file mode 100644
index 0000000000..03ee51fc78
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_jpeg.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_jpeg.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_luv.c b/core/src/fxcodec/fx_tiff/src/fx_tif_luv.c
new file mode 100644
index 0000000000..08768e795a
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_luv.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_luv.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_lzw.c b/core/src/fxcodec/fx_tiff/src/fx_tif_lzw.c
new file mode 100644
index 0000000000..832311330b
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_lzw.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_lzw.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_next.c b/core/src/fxcodec/fx_tiff/src/fx_tif_next.c
new file mode 100644
index 0000000000..a13df45480
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_next.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_next.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_ojpeg.c b/core/src/fxcodec/fx_tiff/src/fx_tif_ojpeg.c
new file mode 100644
index 0000000000..fed1911053
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_ojpeg.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_ojpeg.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_open.c b/core/src/fxcodec/fx_tiff/src/fx_tif_open.c
new file mode 100644
index 0000000000..682ffe614b
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_open.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_open.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_packbits.c b/core/src/fxcodec/fx_tiff/src/fx_tif_packbits.c
new file mode 100644
index 0000000000..349930f7c5
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_packbits.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_packbits.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_pixarlog.c b/core/src/fxcodec/fx_tiff/src/fx_tif_pixarlog.c
new file mode 100644
index 0000000000..2812901c84
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_pixarlog.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_pixarlog.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_predict.c b/core/src/fxcodec/fx_tiff/src/fx_tif_predict.c
new file mode 100644
index 0000000000..eab405a93b
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_predict.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_predict.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_print.c b/core/src/fxcodec/fx_tiff/src/fx_tif_print.c
new file mode 100644
index 0000000000..9a16a921fd
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_print.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_print.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_read.c b/core/src/fxcodec/fx_tiff/src/fx_tif_read.c
new file mode 100644
index 0000000000..64289bbddf
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_read.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_read.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_strip.c b/core/src/fxcodec/fx_tiff/src/fx_tif_strip.c
new file mode 100644
index 0000000000..e642a4e56f
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_strip.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_strip.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_swab.c b/core/src/fxcodec/fx_tiff/src/fx_tif_swab.c
new file mode 100644
index 0000000000..e9c6b10793
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_swab.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_swab.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_thunder.c b/core/src/fxcodec/fx_tiff/src/fx_tif_thunder.c
new file mode 100644
index 0000000000..80f523cd2b
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_thunder.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_thunder.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_tile.c b/core/src/fxcodec/fx_tiff/src/fx_tif_tile.c
new file mode 100644
index 0000000000..49cd4048a4
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_tile.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_tile.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_version.c b/core/src/fxcodec/fx_tiff/src/fx_tif_version.c
new file mode 100644
index 0000000000..6d62e3cd79
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_version.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_version.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_warning.c b/core/src/fxcodec/fx_tiff/src/fx_tif_warning.c
new file mode 100644
index 0000000000..cb1921db8d
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_warning.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_warning.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_write.c b/core/src/fxcodec/fx_tiff/src/fx_tif_write.c
new file mode 100644
index 0000000000..9ab43fa882
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_write.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_write.c"
diff --git a/core/src/fxcodec/fx_tiff/src/fx_tif_zip.c b/core/src/fxcodec/fx_tiff/src/fx_tif_zip.c
new file mode 100644
index 0000000000..8460a3fd5b
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/src/fx_tif_zip.c
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../tiff_v403/tif_zip.c"
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/t4.h b/core/src/fxcodec/fx_tiff/tiff_v403/t4.h
new file mode 100644
index 0000000000..b908f54f09
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/t4.h
@@ -0,0 +1,292 @@
+/* $Id: t4.h,v 1.3 2010-03-10 18:56:48 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _T4_
+#define _T4_
+/*
+ * CCITT T.4 1D Huffman runlength codes and
+ * related definitions. Given the small sizes
+ * of these tables it does not seem
+ * worthwhile to make code & length 8 bits.
+ */
+typedef struct tableentry {
+ unsigned short length; /* bit length of g3 code */
+ unsigned short code; /* g3 code */
+ short runlen; /* run length in bits */
+} tableentry;
+
+#define EOL 0x001 /* EOL code value - 0000 0000 0000 1 */
+
+/* status values returned instead of a run length */
+#define G3CODE_EOL -1 /* NB: ACT_EOL - ACT_WRUNT */
+#define G3CODE_INVALID -2 /* NB: ACT_INVALID - ACT_WRUNT */
+#define G3CODE_EOF -3 /* end of input data */
+#define G3CODE_INCOMP -4 /* incomplete run code */
+
+/*
+ * Note that these tables are ordered such that the
+ * index into the table is known to be either the
+ * run length, or (run length / 64) + a fixed offset.
+ *
+ * NB: The G3CODE_INVALID entries are only used
+ * during state generation (see mkg3states.c).
+ */
+#ifdef G3CODES
+const tableentry TIFFFaxWhiteCodes[] = {
+ { 8, 0x35, 0 }, /* 0011 0101 */
+ { 6, 0x7, 1 }, /* 0001 11 */
+ { 4, 0x7, 2 }, /* 0111 */
+ { 4, 0x8, 3 }, /* 1000 */
+ { 4, 0xB, 4 }, /* 1011 */
+ { 4, 0xC, 5 }, /* 1100 */
+ { 4, 0xE, 6 }, /* 1110 */
+ { 4, 0xF, 7 }, /* 1111 */
+ { 5, 0x13, 8 }, /* 1001 1 */
+ { 5, 0x14, 9 }, /* 1010 0 */
+ { 5, 0x7, 10 }, /* 0011 1 */
+ { 5, 0x8, 11 }, /* 0100 0 */
+ { 6, 0x8, 12 }, /* 0010 00 */
+ { 6, 0x3, 13 }, /* 0000 11 */
+ { 6, 0x34, 14 }, /* 1101 00 */
+ { 6, 0x35, 15 }, /* 1101 01 */
+ { 6, 0x2A, 16 }, /* 1010 10 */
+ { 6, 0x2B, 17 }, /* 1010 11 */
+ { 7, 0x27, 18 }, /* 0100 111 */
+ { 7, 0xC, 19 }, /* 0001 100 */
+ { 7, 0x8, 20 }, /* 0001 000 */
+ { 7, 0x17, 21 }, /* 0010 111 */
+ { 7, 0x3, 22 }, /* 0000 011 */
+ { 7, 0x4, 23 }, /* 0000 100 */
+ { 7, 0x28, 24 }, /* 0101 000 */
+ { 7, 0x2B, 25 }, /* 0101 011 */
+ { 7, 0x13, 26 }, /* 0010 011 */
+ { 7, 0x24, 27 }, /* 0100 100 */
+ { 7, 0x18, 28 }, /* 0011 000 */
+ { 8, 0x2, 29 }, /* 0000 0010 */
+ { 8, 0x3, 30 }, /* 0000 0011 */
+ { 8, 0x1A, 31 }, /* 0001 1010 */
+ { 8, 0x1B, 32 }, /* 0001 1011 */
+ { 8, 0x12, 33 }, /* 0001 0010 */
+ { 8, 0x13, 34 }, /* 0001 0011 */
+ { 8, 0x14, 35 }, /* 0001 0100 */
+ { 8, 0x15, 36 }, /* 0001 0101 */
+ { 8, 0x16, 37 }, /* 0001 0110 */
+ { 8, 0x17, 38 }, /* 0001 0111 */
+ { 8, 0x28, 39 }, /* 0010 1000 */
+ { 8, 0x29, 40 }, /* 0010 1001 */
+ { 8, 0x2A, 41 }, /* 0010 1010 */
+ { 8, 0x2B, 42 }, /* 0010 1011 */
+ { 8, 0x2C, 43 }, /* 0010 1100 */
+ { 8, 0x2D, 44 }, /* 0010 1101 */
+ { 8, 0x4, 45 }, /* 0000 0100 */
+ { 8, 0x5, 46 }, /* 0000 0101 */
+ { 8, 0xA, 47 }, /* 0000 1010 */
+ { 8, 0xB, 48 }, /* 0000 1011 */
+ { 8, 0x52, 49 }, /* 0101 0010 */
+ { 8, 0x53, 50 }, /* 0101 0011 */
+ { 8, 0x54, 51 }, /* 0101 0100 */
+ { 8, 0x55, 52 }, /* 0101 0101 */
+ { 8, 0x24, 53 }, /* 0010 0100 */
+ { 8, 0x25, 54 }, /* 0010 0101 */
+ { 8, 0x58, 55 }, /* 0101 1000 */
+ { 8, 0x59, 56 }, /* 0101 1001 */
+ { 8, 0x5A, 57 }, /* 0101 1010 */
+ { 8, 0x5B, 58 }, /* 0101 1011 */
+ { 8, 0x4A, 59 }, /* 0100 1010 */
+ { 8, 0x4B, 60 }, /* 0100 1011 */
+ { 8, 0x32, 61 }, /* 0011 0010 */
+ { 8, 0x33, 62 }, /* 0011 0011 */
+ { 8, 0x34, 63 }, /* 0011 0100 */
+ { 5, 0x1B, 64 }, /* 1101 1 */
+ { 5, 0x12, 128 }, /* 1001 0 */
+ { 6, 0x17, 192 }, /* 0101 11 */
+ { 7, 0x37, 256 }, /* 0110 111 */
+ { 8, 0x36, 320 }, /* 0011 0110 */
+ { 8, 0x37, 384 }, /* 0011 0111 */
+ { 8, 0x64, 448 }, /* 0110 0100 */
+ { 8, 0x65, 512 }, /* 0110 0101 */
+ { 8, 0x68, 576 }, /* 0110 1000 */
+ { 8, 0x67, 640 }, /* 0110 0111 */
+ { 9, 0xCC, 704 }, /* 0110 0110 0 */
+ { 9, 0xCD, 768 }, /* 0110 0110 1 */
+ { 9, 0xD2, 832 }, /* 0110 1001 0 */
+ { 9, 0xD3, 896 }, /* 0110 1001 1 */
+ { 9, 0xD4, 960 }, /* 0110 1010 0 */
+ { 9, 0xD5, 1024 }, /* 0110 1010 1 */
+ { 9, 0xD6, 1088 }, /* 0110 1011 0 */
+ { 9, 0xD7, 1152 }, /* 0110 1011 1 */
+ { 9, 0xD8, 1216 }, /* 0110 1100 0 */
+ { 9, 0xD9, 1280 }, /* 0110 1100 1 */
+ { 9, 0xDA, 1344 }, /* 0110 1101 0 */
+ { 9, 0xDB, 1408 }, /* 0110 1101 1 */
+ { 9, 0x98, 1472 }, /* 0100 1100 0 */
+ { 9, 0x99, 1536 }, /* 0100 1100 1 */
+ { 9, 0x9A, 1600 }, /* 0100 1101 0 */
+ { 6, 0x18, 1664 }, /* 0110 00 */
+ { 9, 0x9B, 1728 }, /* 0100 1101 1 */
+ { 11, 0x8, 1792 }, /* 0000 0001 000 */
+ { 11, 0xC, 1856 }, /* 0000 0001 100 */
+ { 11, 0xD, 1920 }, /* 0000 0001 101 */
+ { 12, 0x12, 1984 }, /* 0000 0001 0010 */
+ { 12, 0x13, 2048 }, /* 0000 0001 0011 */
+ { 12, 0x14, 2112 }, /* 0000 0001 0100 */
+ { 12, 0x15, 2176 }, /* 0000 0001 0101 */
+ { 12, 0x16, 2240 }, /* 0000 0001 0110 */
+ { 12, 0x17, 2304 }, /* 0000 0001 0111 */
+ { 12, 0x1C, 2368 }, /* 0000 0001 1100 */
+ { 12, 0x1D, 2432 }, /* 0000 0001 1101 */
+ { 12, 0x1E, 2496 }, /* 0000 0001 1110 */
+ { 12, 0x1F, 2560 }, /* 0000 0001 1111 */
+ { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */
+ { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */
+ { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */
+ { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */
+ { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */
+};
+
+const tableentry TIFFFaxBlackCodes[] = {
+ { 10, 0x37, 0 }, /* 0000 1101 11 */
+ { 3, 0x2, 1 }, /* 010 */
+ { 2, 0x3, 2 }, /* 11 */
+ { 2, 0x2, 3 }, /* 10 */
+ { 3, 0x3, 4 }, /* 011 */
+ { 4, 0x3, 5 }, /* 0011 */
+ { 4, 0x2, 6 }, /* 0010 */
+ { 5, 0x3, 7 }, /* 0001 1 */
+ { 6, 0x5, 8 }, /* 0001 01 */
+ { 6, 0x4, 9 }, /* 0001 00 */
+ { 7, 0x4, 10 }, /* 0000 100 */
+ { 7, 0x5, 11 }, /* 0000 101 */
+ { 7, 0x7, 12 }, /* 0000 111 */
+ { 8, 0x4, 13 }, /* 0000 0100 */
+ { 8, 0x7, 14 }, /* 0000 0111 */
+ { 9, 0x18, 15 }, /* 0000 1100 0 */
+ { 10, 0x17, 16 }, /* 0000 0101 11 */
+ { 10, 0x18, 17 }, /* 0000 0110 00 */
+ { 10, 0x8, 18 }, /* 0000 0010 00 */
+ { 11, 0x67, 19 }, /* 0000 1100 111 */
+ { 11, 0x68, 20 }, /* 0000 1101 000 */
+ { 11, 0x6C, 21 }, /* 0000 1101 100 */
+ { 11, 0x37, 22 }, /* 0000 0110 111 */
+ { 11, 0x28, 23 }, /* 0000 0101 000 */
+ { 11, 0x17, 24 }, /* 0000 0010 111 */
+ { 11, 0x18, 25 }, /* 0000 0011 000 */
+ { 12, 0xCA, 26 }, /* 0000 1100 1010 */
+ { 12, 0xCB, 27 }, /* 0000 1100 1011 */
+ { 12, 0xCC, 28 }, /* 0000 1100 1100 */
+ { 12, 0xCD, 29 }, /* 0000 1100 1101 */
+ { 12, 0x68, 30 }, /* 0000 0110 1000 */
+ { 12, 0x69, 31 }, /* 0000 0110 1001 */
+ { 12, 0x6A, 32 }, /* 0000 0110 1010 */
+ { 12, 0x6B, 33 }, /* 0000 0110 1011 */
+ { 12, 0xD2, 34 }, /* 0000 1101 0010 */
+ { 12, 0xD3, 35 }, /* 0000 1101 0011 */
+ { 12, 0xD4, 36 }, /* 0000 1101 0100 */
+ { 12, 0xD5, 37 }, /* 0000 1101 0101 */
+ { 12, 0xD6, 38 }, /* 0000 1101 0110 */
+ { 12, 0xD7, 39 }, /* 0000 1101 0111 */
+ { 12, 0x6C, 40 }, /* 0000 0110 1100 */
+ { 12, 0x6D, 41 }, /* 0000 0110 1101 */
+ { 12, 0xDA, 42 }, /* 0000 1101 1010 */
+ { 12, 0xDB, 43 }, /* 0000 1101 1011 */
+ { 12, 0x54, 44 }, /* 0000 0101 0100 */
+ { 12, 0x55, 45 }, /* 0000 0101 0101 */
+ { 12, 0x56, 46 }, /* 0000 0101 0110 */
+ { 12, 0x57, 47 }, /* 0000 0101 0111 */
+ { 12, 0x64, 48 }, /* 0000 0110 0100 */
+ { 12, 0x65, 49 }, /* 0000 0110 0101 */
+ { 12, 0x52, 50 }, /* 0000 0101 0010 */
+ { 12, 0x53, 51 }, /* 0000 0101 0011 */
+ { 12, 0x24, 52 }, /* 0000 0010 0100 */
+ { 12, 0x37, 53 }, /* 0000 0011 0111 */
+ { 12, 0x38, 54 }, /* 0000 0011 1000 */
+ { 12, 0x27, 55 }, /* 0000 0010 0111 */
+ { 12, 0x28, 56 }, /* 0000 0010 1000 */
+ { 12, 0x58, 57 }, /* 0000 0101 1000 */
+ { 12, 0x59, 58 }, /* 0000 0101 1001 */
+ { 12, 0x2B, 59 }, /* 0000 0010 1011 */
+ { 12, 0x2C, 60 }, /* 0000 0010 1100 */
+ { 12, 0x5A, 61 }, /* 0000 0101 1010 */
+ { 12, 0x66, 62 }, /* 0000 0110 0110 */
+ { 12, 0x67, 63 }, /* 0000 0110 0111 */
+ { 10, 0xF, 64 }, /* 0000 0011 11 */
+ { 12, 0xC8, 128 }, /* 0000 1100 1000 */
+ { 12, 0xC9, 192 }, /* 0000 1100 1001 */
+ { 12, 0x5B, 256 }, /* 0000 0101 1011 */
+ { 12, 0x33, 320 }, /* 0000 0011 0011 */
+ { 12, 0x34, 384 }, /* 0000 0011 0100 */
+ { 12, 0x35, 448 }, /* 0000 0011 0101 */
+ { 13, 0x6C, 512 }, /* 0000 0011 0110 0 */
+ { 13, 0x6D, 576 }, /* 0000 0011 0110 1 */
+ { 13, 0x4A, 640 }, /* 0000 0010 0101 0 */
+ { 13, 0x4B, 704 }, /* 0000 0010 0101 1 */
+ { 13, 0x4C, 768 }, /* 0000 0010 0110 0 */
+ { 13, 0x4D, 832 }, /* 0000 0010 0110 1 */
+ { 13, 0x72, 896 }, /* 0000 0011 1001 0 */
+ { 13, 0x73, 960 }, /* 0000 0011 1001 1 */
+ { 13, 0x74, 1024 }, /* 0000 0011 1010 0 */
+ { 13, 0x75, 1088 }, /* 0000 0011 1010 1 */
+ { 13, 0x76, 1152 }, /* 0000 0011 1011 0 */
+ { 13, 0x77, 1216 }, /* 0000 0011 1011 1 */
+ { 13, 0x52, 1280 }, /* 0000 0010 1001 0 */
+ { 13, 0x53, 1344 }, /* 0000 0010 1001 1 */
+ { 13, 0x54, 1408 }, /* 0000 0010 1010 0 */
+ { 13, 0x55, 1472 }, /* 0000 0010 1010 1 */
+ { 13, 0x5A, 1536 }, /* 0000 0010 1101 0 */
+ { 13, 0x5B, 1600 }, /* 0000 0010 1101 1 */
+ { 13, 0x64, 1664 }, /* 0000 0011 0010 0 */
+ { 13, 0x65, 1728 }, /* 0000 0011 0010 1 */
+ { 11, 0x8, 1792 }, /* 0000 0001 000 */
+ { 11, 0xC, 1856 }, /* 0000 0001 100 */
+ { 11, 0xD, 1920 }, /* 0000 0001 101 */
+ { 12, 0x12, 1984 }, /* 0000 0001 0010 */
+ { 12, 0x13, 2048 }, /* 0000 0001 0011 */
+ { 12, 0x14, 2112 }, /* 0000 0001 0100 */
+ { 12, 0x15, 2176 }, /* 0000 0001 0101 */
+ { 12, 0x16, 2240 }, /* 0000 0001 0110 */
+ { 12, 0x17, 2304 }, /* 0000 0001 0111 */
+ { 12, 0x1C, 2368 }, /* 0000 0001 1100 */
+ { 12, 0x1D, 2432 }, /* 0000 0001 1101 */
+ { 12, 0x1E, 2496 }, /* 0000 0001 1110 */
+ { 12, 0x1F, 2560 }, /* 0000 0001 1111 */
+ { 12, 0x1, G3CODE_EOL }, /* 0000 0000 0001 */
+ { 9, 0x1, G3CODE_INVALID }, /* 0000 0000 1 */
+ { 10, 0x1, G3CODE_INVALID }, /* 0000 0000 01 */
+ { 11, 0x1, G3CODE_INVALID }, /* 0000 0000 001 */
+ { 12, 0x0, G3CODE_INVALID }, /* 0000 0000 0000 */
+};
+#else
+extern const tableentry TIFFFaxWhiteCodes[];
+extern const tableentry TIFFFaxBlackCodes[];
+#endif
+#endif /* _T4_ */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_aux.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_aux.c
new file mode 100644
index 0000000000..752e8d6ef4
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_aux.c
@@ -0,0 +1,360 @@
+/* $Id: tif_aux.c,v 1.26 2010-07-01 15:33:28 dron Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Auxiliary Support Routines.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include "tif_predict.h"
+#include <math.h>
+
+uint32
+_TIFFMultiply32(TIFF* tif, uint32 first, uint32 second, const char* where)
+{
+ uint32 bytes = first * second;
+
+ if (second && bytes / second != first) {
+ TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
+ bytes = 0;
+ }
+
+ return bytes;
+}
+
+uint64
+_TIFFMultiply64(TIFF* tif, uint64 first, uint64 second, const char* where)
+{
+ uint64 bytes = first * second;
+
+ if (second && bytes / second != first) {
+ TIFFErrorExt(tif->tif_clientdata, where, "Integer overflow in %s", where);
+ bytes = 0;
+ }
+
+ return bytes;
+}
+
+void*
+_TIFFCheckRealloc(TIFF* tif, void* buffer,
+ tmsize_t nmemb, tmsize_t elem_size, const char* what)
+{
+ void* cp = NULL;
+ tmsize_t bytes = nmemb * elem_size;
+
+ /*
+ * XXX: Check for integer overflow.
+ */
+ if (nmemb && elem_size && bytes / elem_size == nmemb)
+ cp = _TIFFrealloc(buffer, bytes);
+
+ if (cp == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Failed to allocate memory for %s "
+ "(%ld elements of %ld bytes each)",
+ what,(long) nmemb, (long) elem_size);
+ }
+
+ return cp;
+}
+
+void*
+_TIFFCheckMalloc(TIFF* tif, tmsize_t nmemb, tmsize_t elem_size, const char* what)
+{
+ return _TIFFCheckRealloc(tif, NULL, nmemb, elem_size, what);
+}
+
+static int
+TIFFDefaultTransferFunction(TIFFDirectory* td)
+{
+ uint16 **tf = td->td_transferfunction;
+ tmsize_t i, n, nbytes;
+
+ tf[0] = tf[1] = tf[2] = 0;
+ if (td->td_bitspersample >= sizeof(tmsize_t) * 8 - 2)
+ return 0;
+
+ n = ((tmsize_t)1)<<td->td_bitspersample;
+ nbytes = n * sizeof (uint16);
+ if (!(tf[0] = (uint16 *)_TIFFmalloc(nbytes)))
+ return 0;
+ tf[0][0] = 0;
+ for (i = 1; i < n; i++) {
+ double t = (double)i/((double) n-1.);
+ tf[0][i] = (uint16)floor(65535.*pow(t, 2.2) + .5);
+ }
+
+ if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+ if (!(tf[1] = (uint16 *)_TIFFmalloc(nbytes)))
+ goto bad;
+ _TIFFmemcpy(tf[1], tf[0], nbytes);
+ if (!(tf[2] = (uint16 *)_TIFFmalloc(nbytes)))
+ goto bad;
+ _TIFFmemcpy(tf[2], tf[0], nbytes);
+ }
+ return 1;
+
+bad:
+ if (tf[0])
+ _TIFFfree(tf[0]);
+ if (tf[1])
+ _TIFFfree(tf[1]);
+ if (tf[2])
+ _TIFFfree(tf[2]);
+ tf[0] = tf[1] = tf[2] = 0;
+ return 0;
+}
+
+static int
+TIFFDefaultRefBlackWhite(TIFFDirectory* td)
+{
+ int i;
+
+ if (!(td->td_refblackwhite = (float *)_TIFFmalloc(6*sizeof (float))))
+ return 0;
+ if (td->td_photometric == PHOTOMETRIC_YCBCR) {
+ /*
+ * YCbCr (Class Y) images must have the ReferenceBlackWhite
+ * tag set. Fix the broken images, which lacks that tag.
+ */
+ td->td_refblackwhite[0] = 0.0F;
+ td->td_refblackwhite[1] = td->td_refblackwhite[3] =
+ td->td_refblackwhite[5] = 255.0F;
+ td->td_refblackwhite[2] = td->td_refblackwhite[4] = 128.0F;
+ } else {
+ /*
+ * Assume RGB (Class R)
+ */
+ for (i = 0; i < 3; i++) {
+ td->td_refblackwhite[2*i+0] = 0;
+ td->td_refblackwhite[2*i+1] =
+ (float)((1L<<td->td_bitspersample)-1L);
+ }
+ }
+ return 1;
+}
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ *
+ * NB: We use the value in the directory, rather than
+ * explcit values so that defaults exist only one
+ * place in the library -- in TIFFDefaultDirectory.
+ */
+int
+TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (TIFFVGetField(tif, tag, ap))
+ return (1);
+ switch (tag) {
+ case TIFFTAG_SUBFILETYPE:
+ *va_arg(ap, uint32 *) = td->td_subfiletype;
+ return (1);
+ case TIFFTAG_BITSPERSAMPLE:
+ *va_arg(ap, uint16 *) = td->td_bitspersample;
+ return (1);
+ case TIFFTAG_THRESHHOLDING:
+ *va_arg(ap, uint16 *) = td->td_threshholding;
+ return (1);
+ case TIFFTAG_FILLORDER:
+ *va_arg(ap, uint16 *) = td->td_fillorder;
+ return (1);
+ case TIFFTAG_ORIENTATION:
+ *va_arg(ap, uint16 *) = td->td_orientation;
+ return (1);
+ case TIFFTAG_SAMPLESPERPIXEL:
+ *va_arg(ap, uint16 *) = td->td_samplesperpixel;
+ return (1);
+ case TIFFTAG_ROWSPERSTRIP:
+ *va_arg(ap, uint32 *) = td->td_rowsperstrip;
+ return (1);
+ case TIFFTAG_MINSAMPLEVALUE:
+ *va_arg(ap, uint16 *) = td->td_minsamplevalue;
+ return (1);
+ case TIFFTAG_MAXSAMPLEVALUE:
+ *va_arg(ap, uint16 *) = td->td_maxsamplevalue;
+ return (1);
+ case TIFFTAG_PLANARCONFIG:
+ *va_arg(ap, uint16 *) = td->td_planarconfig;
+ return (1);
+ case TIFFTAG_RESOLUTIONUNIT:
+ *va_arg(ap, uint16 *) = td->td_resolutionunit;
+ return (1);
+ case TIFFTAG_PREDICTOR:
+ {
+ TIFFPredictorState* sp = (TIFFPredictorState*) tif->tif_data;
+ *va_arg(ap, uint16*) = (uint16) sp->predictor;
+ return 1;
+ }
+ case TIFFTAG_DOTRANGE:
+ *va_arg(ap, uint16 *) = 0;
+ *va_arg(ap, uint16 *) = (1<<td->td_bitspersample)-1;
+ return (1);
+ case TIFFTAG_INKSET:
+ *va_arg(ap, uint16 *) = INKSET_CMYK;
+ return 1;
+ case TIFFTAG_NUMBEROFINKS:
+ *va_arg(ap, uint16 *) = 4;
+ return (1);
+ case TIFFTAG_EXTRASAMPLES:
+ *va_arg(ap, uint16 *) = td->td_extrasamples;
+ *va_arg(ap, uint16 **) = td->td_sampleinfo;
+ return (1);
+ case TIFFTAG_MATTEING:
+ *va_arg(ap, uint16 *) =
+ (td->td_extrasamples == 1 &&
+ td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+ return (1);
+ case TIFFTAG_TILEDEPTH:
+ *va_arg(ap, uint32 *) = td->td_tiledepth;
+ return (1);
+ case TIFFTAG_DATATYPE:
+ *va_arg(ap, uint16 *) = td->td_sampleformat-1;
+ return (1);
+ case TIFFTAG_SAMPLEFORMAT:
+ *va_arg(ap, uint16 *) = td->td_sampleformat;
+ return(1);
+ case TIFFTAG_IMAGEDEPTH:
+ *va_arg(ap, uint32 *) = td->td_imagedepth;
+ return (1);
+ case TIFFTAG_YCBCRCOEFFICIENTS:
+ {
+ /* defaults are from CCIR Recommendation 601-1 */
+ static float ycbcrcoeffs[] = { 0.299f, 0.587f, 0.114f };
+ *va_arg(ap, float **) = ycbcrcoeffs;
+ return 1;
+ }
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[0];
+ *va_arg(ap, uint16 *) = td->td_ycbcrsubsampling[1];
+ return (1);
+ case TIFFTAG_YCBCRPOSITIONING:
+ *va_arg(ap, uint16 *) = td->td_ycbcrpositioning;
+ return (1);
+ case TIFFTAG_WHITEPOINT:
+ {
+ static float whitepoint[2];
+
+ /* TIFF 6.0 specification tells that it is no default
+ value for the WhitePoint, but AdobePhotoshop TIFF
+ Technical Note tells that it should be CIE D50. */
+ whitepoint[0] = D50_X0 / (D50_X0 + D50_Y0 + D50_Z0);
+ whitepoint[1] = D50_Y0 / (D50_X0 + D50_Y0 + D50_Z0);
+ *va_arg(ap, float **) = whitepoint;
+ return 1;
+ }
+ case TIFFTAG_TRANSFERFUNCTION:
+ if (!td->td_transferfunction[0] &&
+ !TIFFDefaultTransferFunction(td)) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "No space for \"TransferFunction\" tag");
+ return (0);
+ }
+ *va_arg(ap, uint16 **) = td->td_transferfunction[0];
+ if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+ *va_arg(ap, uint16 **) = td->td_transferfunction[1];
+ *va_arg(ap, uint16 **) = td->td_transferfunction[2];
+ }
+ return (1);
+ case TIFFTAG_REFERENCEBLACKWHITE:
+ if (!td->td_refblackwhite && !TIFFDefaultRefBlackWhite(td))
+ return (0);
+ *va_arg(ap, float **) = td->td_refblackwhite;
+ return (1);
+ }
+ return 0;
+}
+
+/*
+ * Like TIFFGetField, but return any default
+ * value if the tag is not present in the directory.
+ */
+int
+TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...)
+{
+ int ok;
+ va_list ap;
+
+ va_start(ap, tag);
+ ok = TIFFVGetFieldDefaulted(tif, tag, ap);
+ va_end(ap);
+ return (ok);
+}
+
+struct _Int64Parts {
+ int32 low, high;
+};
+
+typedef union {
+ struct _Int64Parts part;
+ int64 value;
+} _Int64;
+
+float
+_TIFFUInt64ToFloat(uint64 ui64)
+{
+ _Int64 i;
+
+ i.value = ui64;
+ if (i.part.high >= 0) {
+ return (float)i.value;
+ } else {
+ long double df;
+ df = (long double)i.value;
+ df += 18446744073709551616.0; /* adding 2**64 */
+ return (float)df;
+ }
+}
+
+double
+_TIFFUInt64ToDouble(uint64 ui64)
+{
+ _Int64 i;
+
+ i.value = ui64;
+ if (i.part.high >= 0) {
+ return (double)i.value;
+ } else {
+ long double df;
+ df = (long double)i.value;
+ df += 18446744073709551616.0; /* adding 2**64 */
+ return (double)df;
+ }
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+ #endif
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_close.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_close.c
new file mode 100644
index 0000000000..eebb30a41c
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_close.c
@@ -0,0 +1,143 @@
+/* $Id: tif_close.c,v 1.19 2010-03-10 18:56:48 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <string.h>
+
+/************************************************************************/
+/* TIFFCleanup() */
+/************************************************************************/
+
+/**
+ * Auxiliary function to free the TIFF structure. Given structure will be
+ * completetly freed, so you should save opened file handle and pointer
+ * to the close procedure in external variables before calling
+ * _TIFFCleanup(), if you will need these ones to close the file.
+ *
+ * @param tif A TIFF pointer.
+ */
+
+void
+TIFFCleanup(TIFF* tif)
+{
+ /*
+ * Flush buffered data and directory (if dirty).
+ */
+ if (tif->tif_mode != O_RDONLY)
+ TIFFFlush(tif);
+ (*tif->tif_cleanup)(tif);
+ TIFFFreeDirectory(tif);
+
+ if (tif->tif_dirlist)
+ _TIFFfree(tif->tif_dirlist);
+
+ /*
+ * Clean up client info links.
+ */
+ while( tif->tif_clientinfo )
+ {
+ TIFFClientInfoLink *link = tif->tif_clientinfo;
+
+ tif->tif_clientinfo = link->next;
+ _TIFFfree( link->name );
+ _TIFFfree( link );
+ }
+
+ if (tif->tif_rawdata && (tif->tif_flags&TIFF_MYBUFFER))
+ _TIFFfree(tif->tif_rawdata);
+ if (isMapped(tif))
+ TIFFUnmapFileContents(tif, tif->tif_base, (toff_t)tif->tif_size);
+
+ /*
+ * Clean up custom fields.
+ */
+ if (tif->tif_fields && tif->tif_nfields > 0) {
+ uint32 i;
+
+ for (i = 0; i < tif->tif_nfields; i++) {
+ TIFFField *fld = tif->tif_fields[i];
+ if (fld->field_bit == FIELD_CUSTOM &&
+ strncmp("Tag ", fld->field_name, 4) == 0) {
+ _TIFFfree(fld->field_name);
+ _TIFFfree(fld);
+ }
+ }
+
+ _TIFFfree(tif->tif_fields);
+ }
+
+ if (tif->tif_nfieldscompat > 0) {
+ uint32 i;
+
+ for (i = 0; i < tif->tif_nfieldscompat; i++) {
+ if (tif->tif_fieldscompat[i].allocated_size)
+ _TIFFfree(tif->tif_fieldscompat[i].fields);
+ }
+ _TIFFfree(tif->tif_fieldscompat);
+ }
+
+ _TIFFfree(tif);
+}
+
+/************************************************************************/
+/* TIFFClose() */
+/************************************************************************/
+
+/**
+ * Close a previously opened TIFF file.
+ *
+ * TIFFClose closes a file that was previously opened with TIFFOpen().
+ * Any buffered data are flushed to the file, including the contents of
+ * the current directory (if modified); and all resources are reclaimed.
+ *
+ * @param tif A TIFF pointer.
+ */
+
+void
+TIFFClose(TIFF* tif)
+{
+ TIFFCloseProc closeproc = tif->tif_closeproc;
+ thandle_t fd = tif->tif_clientdata;
+
+ TIFFCleanup(tif);
+ (void) (*closeproc)(fd);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_codec.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_codec.c
new file mode 100644
index 0000000000..16d237f79a
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_codec.c
@@ -0,0 +1,168 @@
+/* $Id: tif_codec.c,v 1.15 2010-12-14 12:53:00 dron Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Builtin Compression Scheme Configuration Support.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+static int NotConfigured(TIFF*, int);
+
+#ifndef LZW_SUPPORT
+#define TIFFInitLZW NotConfigured
+#endif
+#ifndef PACKBITS_SUPPORT
+#define TIFFInitPackBits NotConfigured
+#endif
+#ifndef THUNDER_SUPPORT
+#define TIFFInitThunderScan NotConfigured
+#endif
+#ifndef NEXT_SUPPORT
+#define TIFFInitNeXT NotConfigured
+#endif
+#ifndef JPEG_SUPPORT
+#define TIFFInitJPEG NotConfigured
+#endif
+#ifndef OJPEG_SUPPORT
+#define TIFFInitOJPEG NotConfigured
+#endif
+#ifndef CCITT_SUPPORT
+#define TIFFInitCCITTRLE NotConfigured
+#define TIFFInitCCITTRLEW NotConfigured
+#define TIFFInitCCITTFax3 NotConfigured
+#define TIFFInitCCITTFax4 NotConfigured
+#endif
+#ifndef JBIG_SUPPORT
+#define TIFFInitJBIG NotConfigured
+#endif
+#ifndef ZIP_SUPPORT
+#define TIFFInitZIP NotConfigured
+#endif
+#ifndef PIXARLOG_SUPPORT
+#define TIFFInitPixarLog NotConfigured
+#endif
+#ifndef LOGLUV_SUPPORT
+#define TIFFInitSGILog NotConfigured
+#endif
+#ifndef LZMA_SUPPORT
+#define TIFFInitLZMA NotConfigured
+#endif
+
+/*
+ * Compression schemes statically built into the library.
+ */
+#ifdef VMS
+const TIFFCodec _TIFFBuiltinCODECS[] = {
+#else
+TIFFCodec _TIFFBuiltinCODECS[] = {
+#endif
+ { "None", COMPRESSION_NONE, TIFFInitDumpMode },
+ { "LZW", COMPRESSION_LZW, TIFFInitLZW },
+ { "PackBits", COMPRESSION_PACKBITS, TIFFInitPackBits },
+ { "ThunderScan", COMPRESSION_THUNDERSCAN,TIFFInitThunderScan },
+ { "NeXT", COMPRESSION_NEXT, TIFFInitNeXT },
+ { "JPEG", COMPRESSION_JPEG, TIFFInitJPEG },
+ { "Old-style JPEG", COMPRESSION_OJPEG, TIFFInitOJPEG },
+ { "CCITT RLE", COMPRESSION_CCITTRLE, TIFFInitCCITTRLE },
+ { "CCITT RLE/W", COMPRESSION_CCITTRLEW, TIFFInitCCITTRLEW },
+ { "CCITT Group 3", COMPRESSION_CCITTFAX3, TIFFInitCCITTFax3 },
+ { "CCITT Group 4", COMPRESSION_CCITTFAX4, TIFFInitCCITTFax4 },
+ { "ISO JBIG", COMPRESSION_JBIG, TIFFInitJBIG },
+ { "Deflate", COMPRESSION_DEFLATE, TIFFInitZIP },
+ { "AdobeDeflate", COMPRESSION_ADOBE_DEFLATE , TIFFInitZIP },
+ { "PixarLog", COMPRESSION_PIXARLOG, TIFFInitPixarLog },
+ { "SGILog", COMPRESSION_SGILOG, TIFFInitSGILog },
+ { "SGILog24", COMPRESSION_SGILOG24, TIFFInitSGILog },
+ { "LZMA", COMPRESSION_LZMA, TIFFInitLZMA },
+ { NULL, 0, NULL }
+};
+
+static int
+_notConfigured(TIFF* tif)
+{
+ const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
+ char compression_code[20];
+
+ sprintf( compression_code, "%d", tif->tif_dir.td_compression );
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%s compression support is not configured",
+ c ? c->name : compression_code );
+ return (0);
+}
+
+static int
+NotConfigured(TIFF* tif, int scheme)
+{
+ (void) scheme;
+
+ tif->tif_fixuptags = _notConfigured;
+ tif->tif_decodestatus = FALSE;
+ tif->tif_setupdecode = _notConfigured;
+ tif->tif_encodestatus = FALSE;
+ tif->tif_setupencode = _notConfigured;
+ return (1);
+}
+
+/************************************************************************/
+/* TIFFIsCODECConfigured() */
+/************************************************************************/
+
+/**
+ * Check whether we have working codec for the specific coding scheme.
+ *
+ * @return returns 1 if the codec is configured and working. Otherwise
+ * 0 will be returned.
+ */
+
+int
+TIFFIsCODECConfigured(uint16 scheme)
+{
+ const TIFFCodec* codec = TIFFFindCODEC(scheme);
+
+ if(codec == NULL) {
+ return 0;
+ }
+ if(codec->init == NULL) {
+ return 0;
+ }
+ if(codec->init != NotConfigured){
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_color.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_color.c
new file mode 100644
index 0000000000..71effbce92
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_color.c
@@ -0,0 +1,289 @@
+/* $Id: tif_color.c,v 1.19 2010-12-14 02:22:42 faxguy Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * CIE L*a*b* to CIE XYZ and CIE XYZ to RGB conversion routines are taken
+ * from the VIPS library (http://www.vips.ecs.soton.ac.uk) with
+ * the permission of John Cupitt, the VIPS author.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Color space conversion routines.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <math.h>
+
+/*
+ * Convert color value from the CIE L*a*b* 1976 space to CIE XYZ.
+ */
+void
+TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b,
+ float *X, float *Y, float *Z)
+{
+ float L = (float)l * 100.0F / 255.0F;
+ float cby, tmp;
+
+ if( L < 8.856F ) {
+ *Y = (L * cielab->Y0) / 903.292F;
+ cby = 7.787F * (*Y / cielab->Y0) + 16.0F / 116.0F;
+ } else {
+ cby = (L + 16.0F) / 116.0F;
+ *Y = cielab->Y0 * cby * cby * cby;
+ }
+
+ tmp = (float)a / 500.0F + cby;
+ if( tmp < 0.2069F )
+ *X = cielab->X0 * (tmp - 0.13793F) / 7.787F;
+ else
+ *X = cielab->X0 * tmp * tmp * tmp;
+
+ tmp = cby - (float)b / 200.0F;
+ if( tmp < 0.2069F )
+ *Z = cielab->Z0 * (tmp - 0.13793F) / 7.787F;
+ else
+ *Z = cielab->Z0 * tmp * tmp * tmp;
+}
+
+#define RINT(R) ((uint32)((R)>0?((R)+0.5):((R)-0.5)))
+/*
+ * Convert color value from the XYZ space to RGB.
+ */
+void
+TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z,
+ uint32 *r, uint32 *g, uint32 *b)
+{
+ int i;
+ float Yr, Yg, Yb;
+ float *matrix = &cielab->display.d_mat[0][0];
+
+ /* Multiply through the matrix to get luminosity values. */
+ Yr = matrix[0] * X + matrix[1] * Y + matrix[2] * Z;
+ Yg = matrix[3] * X + matrix[4] * Y + matrix[5] * Z;
+ Yb = matrix[6] * X + matrix[7] * Y + matrix[8] * Z;
+
+ /* Clip input */
+ Yr = TIFFmax(Yr, cielab->display.d_Y0R);
+ Yg = TIFFmax(Yg, cielab->display.d_Y0G);
+ Yb = TIFFmax(Yb, cielab->display.d_Y0B);
+
+ /* Avoid overflow in case of wrong input values */
+ Yr = TIFFmin(Yr, cielab->display.d_YCR);
+ Yg = TIFFmin(Yg, cielab->display.d_YCG);
+ Yb = TIFFmin(Yb, cielab->display.d_YCB);
+
+ /* Turn luminosity to colour value. */
+ i = (int)((Yr - cielab->display.d_Y0R) / cielab->rstep);
+ i = TIFFmin(cielab->range, i);
+ *r = RINT(cielab->Yr2r[i]);
+
+ i = (int)((Yg - cielab->display.d_Y0G) / cielab->gstep);
+ i = TIFFmin(cielab->range, i);
+ *g = RINT(cielab->Yg2g[i]);
+
+ i = (int)((Yb - cielab->display.d_Y0B) / cielab->bstep);
+ i = TIFFmin(cielab->range, i);
+ *b = RINT(cielab->Yb2b[i]);
+
+ /* Clip output. */
+ *r = TIFFmin(*r, cielab->display.d_Vrwr);
+ *g = TIFFmin(*g, cielab->display.d_Vrwg);
+ *b = TIFFmin(*b, cielab->display.d_Vrwb);
+}
+#undef RINT
+
+/*
+ * Allocate conversion state structures and make look_up tables for
+ * the Yr,Yb,Yg <=> r,g,b conversions.
+ */
+int
+TIFFCIELabToRGBInit(TIFFCIELabToRGB* cielab,
+ const TIFFDisplay *display, float *refWhite)
+{
+ int i;
+ double gamma;
+
+ cielab->range = CIELABTORGB_TABLE_RANGE;
+
+ _TIFFmemcpy(&cielab->display, display, sizeof(TIFFDisplay));
+
+ /* Red */
+ gamma = 1.0 / cielab->display.d_gammaR ;
+ cielab->rstep =
+ (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+ for(i = 0; i <= cielab->range; i++) {
+ cielab->Yr2r[i] = cielab->display.d_Vrwr
+ * ((float)pow((double)i / cielab->range, gamma));
+ }
+
+ /* Green */
+ gamma = 1.0 / cielab->display.d_gammaG ;
+ cielab->gstep =
+ (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+ for(i = 0; i <= cielab->range; i++) {
+ cielab->Yg2g[i] = cielab->display.d_Vrwg
+ * ((float)pow((double)i / cielab->range, gamma));
+ }
+
+ /* Blue */
+ gamma = 1.0 / cielab->display.d_gammaB ;
+ cielab->bstep =
+ (cielab->display.d_YCR - cielab->display.d_Y0R) / cielab->range;
+ for(i = 0; i <= cielab->range; i++) {
+ cielab->Yb2b[i] = cielab->display.d_Vrwb
+ * ((float)pow((double)i / cielab->range, gamma));
+ }
+
+ /* Init reference white point */
+ cielab->X0 = refWhite[0];
+ cielab->Y0 = refWhite[1];
+ cielab->Z0 = refWhite[2];
+
+ return 0;
+}
+
+/*
+ * Convert color value from the YCbCr space to CIE XYZ.
+ * The colorspace conversion algorithm comes from the IJG v5a code;
+ * see below for more information on how it works.
+ */
+#define SHIFT 16
+#define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
+#define ONE_HALF ((int32)(1<<(SHIFT-1)))
+#define Code2V(c, RB, RW, CR) ((((c)-(int32)(RB))*(float)(CR))/(float)(((RW)-(RB)) ? ((RW)-(RB)) : 1))
+#define CLAMP(f,min,max) ((f)<(min)?(min):(f)>(max)?(max):(f))
+#define HICLAMP(f,max) ((f)>(max)?(max):(f))
+
+void
+TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr,
+ uint32 *r, uint32 *g, uint32 *b)
+{
+ int32 i;
+
+ /* XXX: Only 8-bit YCbCr input supported for now */
+ Y = HICLAMP(Y, 255), Cb = CLAMP(Cb, 0, 255), Cr = CLAMP(Cr, 0, 255);
+
+ i = ycbcr->Y_tab[Y] + ycbcr->Cr_r_tab[Cr];
+ *r = CLAMP(i, 0, 255);
+ i = ycbcr->Y_tab[Y]
+ + (int)((ycbcr->Cb_g_tab[Cb] + ycbcr->Cr_g_tab[Cr]) >> SHIFT);
+ *g = CLAMP(i, 0, 255);
+ i = ycbcr->Y_tab[Y] + ycbcr->Cb_b_tab[Cb];
+ *b = CLAMP(i, 0, 255);
+}
+
+/*
+ * Initialize the YCbCr->RGB conversion tables. The conversion
+ * is done according to the 6.0 spec:
+ *
+ * R = Y + Cr*(2 - 2*LumaRed)
+ * B = Y + Cb*(2 - 2*LumaBlue)
+ * G = Y
+ * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
+ * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
+ *
+ * To avoid floating point arithmetic the fractional constants that
+ * come out of the equations are represented as fixed point values
+ * in the range 0...2^16. We also eliminate multiplications by
+ * pre-calculating possible values indexed by Cb and Cr (this code
+ * assumes conversion is being done for 8-bit samples).
+ */
+int
+TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, float *luma, float *refBlackWhite)
+{
+ TIFFRGBValue* clamptab;
+ int i;
+
+#define LumaRed luma[0]
+#define LumaGreen luma[1]
+#define LumaBlue luma[2]
+
+ clamptab = (TIFFRGBValue*)(
+ (uint8*) ycbcr+TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long)));
+ _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
+ ycbcr->clamptab = (clamptab += 256);
+ for (i = 0; i < 256; i++)
+ clamptab[i] = (TIFFRGBValue) i;
+ _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */
+ ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
+ ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
+ ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
+ ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
+ ycbcr->Y_tab = ycbcr->Cb_g_tab + 256;
+
+ { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1);
+ float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2);
+ float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3);
+ float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4);
+ int x;
+
+#undef LumaBlue
+#undef LumaGreen
+#undef LumaRed
+
+ /*
+ * i is the actual input pixel value in the range 0..255
+ * Cb and Cr values are in the range -128..127 (actually
+ * they are in a range defined by the ReferenceBlackWhite
+ * tag) so there is some range shifting to do here when
+ * constructing tables indexed by the raw pixel data.
+ */
+ for (i = 0, x = -128; i < 256; i++, x++) {
+ int32 Cr = (int32)Code2V(x, refBlackWhite[4] - 128.0F,
+ refBlackWhite[5] - 128.0F, 127);
+ int32 Cb = (int32)Code2V(x, refBlackWhite[2] - 128.0F,
+ refBlackWhite[3] - 128.0F, 127);
+
+ ycbcr->Cr_r_tab[i] = (int32)((D1*Cr + ONE_HALF)>>SHIFT);
+ ycbcr->Cb_b_tab[i] = (int32)((D3*Cb + ONE_HALF)>>SHIFT);
+ ycbcr->Cr_g_tab[i] = D2*Cr;
+ ycbcr->Cb_g_tab[i] = D4*Cb + ONE_HALF;
+ ycbcr->Y_tab[i] =
+ (int32)Code2V(x + 128, refBlackWhite[0], refBlackWhite[1], 255);
+ }
+ }
+
+ return 0;
+}
+#undef HICLAMP
+#undef CLAMP
+#undef Code2V
+#undef SHIFT
+#undef ONE_HALF
+#undef FIX
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_compress.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_compress.c
new file mode 100644
index 0000000000..5b2b4d5948
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_compress.c
@@ -0,0 +1,307 @@
+/* $Id: tif_compress.c,v 1.22 2010-03-10 18:56:48 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Compression Scheme Configuration Support.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+static int
+TIFFNoEncode(TIFF* tif, const char* method)
+{
+ const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
+
+ if (c) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%s %s encoding is not implemented",
+ c->name, method);
+ } else {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Compression scheme %u %s encoding is not implemented",
+ tif->tif_dir.td_compression, method);
+ }
+ return (-1);
+}
+
+int
+_TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+ (void) pp; (void) cc; (void) s;
+ return (TIFFNoEncode(tif, "scanline"));
+}
+
+int
+_TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+ (void) pp; (void) cc; (void) s;
+ return (TIFFNoEncode(tif, "strip"));
+}
+
+int
+_TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+ (void) pp; (void) cc; (void) s;
+ return (TIFFNoEncode(tif, "tile"));
+}
+
+static int
+TIFFNoDecode(TIFF* tif, const char* method)
+{
+ const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression);
+
+ if (c)
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%s %s decoding is not implemented",
+ c->name, method);
+ else
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Compression scheme %u %s decoding is not implemented",
+ tif->tif_dir.td_compression, method);
+ return (-1);
+}
+
+int
+_TIFFNoFixupTags(TIFF* tif)
+{
+ (void) tif;
+ return (1);
+}
+
+int
+_TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+ (void) pp; (void) cc; (void) s;
+ return (TIFFNoDecode(tif, "scanline"));
+}
+
+int
+_TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+ (void) pp; (void) cc; (void) s;
+ return (TIFFNoDecode(tif, "strip"));
+}
+
+int
+_TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+ (void) pp; (void) cc; (void) s;
+ return (TIFFNoDecode(tif, "tile"));
+}
+
+int
+_TIFFNoSeek(TIFF* tif, uint32 off)
+{
+ (void) off;
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Compression algorithm does not support random access");
+ return (0);
+}
+
+int
+_TIFFNoPreCode(TIFF* tif, uint16 s)
+{
+ (void) tif; (void) s;
+ return (1);
+}
+
+static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); }
+static void _TIFFvoid(TIFF* tif) { (void) tif; }
+
+void
+_TIFFSetDefaultCompressionState(TIFF* tif)
+{
+ tif->tif_fixuptags = _TIFFNoFixupTags;
+ tif->tif_decodestatus = TRUE;
+ tif->tif_setupdecode = _TIFFtrue;
+ tif->tif_predecode = _TIFFNoPreCode;
+ tif->tif_decoderow = _TIFFNoRowDecode;
+ tif->tif_decodestrip = _TIFFNoStripDecode;
+ tif->tif_decodetile = _TIFFNoTileDecode;
+ tif->tif_encodestatus = TRUE;
+ tif->tif_setupencode = _TIFFtrue;
+ tif->tif_preencode = _TIFFNoPreCode;
+ tif->tif_postencode = _TIFFtrue;
+ tif->tif_encoderow = _TIFFNoRowEncode;
+ tif->tif_encodestrip = _TIFFNoStripEncode;
+ tif->tif_encodetile = _TIFFNoTileEncode;
+ tif->tif_close = _TIFFvoid;
+ tif->tif_seek = _TIFFNoSeek;
+ tif->tif_cleanup = _TIFFvoid;
+ tif->tif_defstripsize = _TIFFDefaultStripSize;
+ tif->tif_deftilesize = _TIFFDefaultTileSize;
+ tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW);
+}
+
+int
+TIFFSetCompressionScheme(TIFF* tif, int scheme)
+{
+ const TIFFCodec *c = TIFFFindCODEC((uint16) scheme);
+
+ _TIFFSetDefaultCompressionState(tif);
+ /*
+ * Don't treat an unknown compression scheme as an error.
+ * This permits applications to open files with data that
+ * the library does not have builtin support for, but which
+ * may still be meaningful.
+ */
+ return (c ? (*c->init)(tif, scheme) : 1);
+}
+
+/*
+ * Other compression schemes may be registered. Registered
+ * schemes can also override the builtin versions provided
+ * by this library.
+ */
+typedef struct _codec {
+ struct _codec* next;
+ TIFFCodec* info;
+} codec_t;
+static codec_t* registeredCODECS = NULL;
+
+const TIFFCodec*
+TIFFFindCODEC(uint16 scheme)
+{
+ const TIFFCodec* c;
+ codec_t* cd;
+
+ for (cd = registeredCODECS; cd; cd = cd->next)
+ if (cd->info->scheme == scheme)
+ return ((const TIFFCodec*) cd->info);
+ for (c = _TIFFBuiltinCODECS; c->name; c++)
+ if (c->scheme == scheme)
+ return (c);
+ return ((const TIFFCodec*) 0);
+}
+
+TIFFCodec*
+TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init)
+{
+ codec_t* cd = (codec_t*)
+ _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1));
+
+ if (cd != NULL) {
+ cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t));
+ cd->info->name = (char*)
+ ((uint8*) cd->info + sizeof (TIFFCodec));
+ strcpy(cd->info->name, name);
+ cd->info->scheme = scheme;
+ cd->info->init = init;
+ cd->next = registeredCODECS;
+ registeredCODECS = cd;
+ } else {
+ TIFFErrorExt(0, "TIFFRegisterCODEC",
+ "No space to register compression scheme %s", name);
+ return NULL;
+ }
+ return (cd->info);
+}
+
+void
+TIFFUnRegisterCODEC(TIFFCodec* c)
+{
+ codec_t* cd;
+ codec_t** pcd;
+
+ for (pcd = &registeredCODECS; (cd = *pcd); pcd = &cd->next)
+ if (cd->info == c) {
+ *pcd = cd->next;
+ _TIFFfree(cd);
+ return;
+ }
+ TIFFErrorExt(0, "TIFFUnRegisterCODEC",
+ "Cannot remove compression scheme %s; not registered", c->name);
+}
+
+/************************************************************************/
+/* TIFFGetConfisuredCODECs() */
+/************************************************************************/
+
+/**
+ * Get list of configured codecs, both built-in and registered by user.
+ * Caller is responsible to free this structure.
+ *
+ * @return returns array of TIFFCodec records (the last record should be NULL)
+ * or NULL if function failed.
+ */
+
+TIFFCodec*
+TIFFGetConfiguredCODECs()
+{
+ int i = 1;
+ codec_t *cd;
+ const TIFFCodec* c;
+ TIFFCodec* codecs = NULL;
+ TIFFCodec* new_codecs;
+
+ for (cd = registeredCODECS; cd; cd = cd->next) {
+ new_codecs = (TIFFCodec *)
+ _TIFFrealloc(codecs, i * sizeof(TIFFCodec));
+ if (!new_codecs) {
+ _TIFFfree (codecs);
+ return NULL;
+ }
+ codecs = new_codecs;
+ _TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec));
+ i++;
+ }
+ for (c = _TIFFBuiltinCODECS; c->name; c++) {
+ if (TIFFIsCODECConfigured(c->scheme)) {
+ new_codecs = (TIFFCodec *)
+ _TIFFrealloc(codecs, i * sizeof(TIFFCodec));
+ if (!new_codecs) {
+ _TIFFfree (codecs);
+ return NULL;
+ }
+ codecs = new_codecs;
+ _TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec));
+ i++;
+ }
+ }
+
+ new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec));
+ if (!new_codecs) {
+ _TIFFfree (codecs);
+ return NULL;
+ }
+ codecs = new_codecs;
+ _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
+
+ return codecs;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.c
new file mode 100644
index 0000000000..076d9b4ea0
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.c
@@ -0,0 +1,1662 @@
+/* $Id: tif_dir.c,v 1.113 2012-06-14 20:32:53 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Tag Get & Set Routines.
+ * (and also some miscellaneous stuff)
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+/*
+ * These are used in the backwards compatibility code...
+ */
+#define DATATYPE_VOID 0 /* !untyped data */
+#define DATATYPE_INT 1 /* !signed integer data */
+#define DATATYPE_UINT 2 /* !unsigned integer data */
+#define DATATYPE_IEEEFP 3 /* !IEEE floating point data */
+
+static void
+setByteArray(void** vpp, void* vp, size_t nmemb, size_t elem_size)
+{
+ if (*vpp)
+ _TIFFfree(*vpp), *vpp = 0;
+ if (vp) {
+ tmsize_t bytes = (tmsize_t)(nmemb * elem_size);
+ if (elem_size && bytes / elem_size == nmemb)
+ *vpp = (void*) _TIFFmalloc(bytes);
+ if (*vpp)
+ _TIFFmemcpy(*vpp, vp, bytes);
+ }
+}
+void _TIFFsetByteArray(void** vpp, void* vp, uint32 n)
+ { setByteArray(vpp, vp, n, 1); }
+void _TIFFsetString(char** cpp, char* cp)
+ { setByteArray((void**) cpp, (void*) cp, strlen(cp)+1, 1); }
+void _TIFFsetNString(char** cpp, char* cp, uint32 n)
+ { setByteArray((void**) cpp, (void*) cp, n, 1); }
+void _TIFFsetShortArray(uint16** wpp, uint16* wp, uint32 n)
+ { setByteArray((void**) wpp, (void*) wp, n, sizeof (uint16)); }
+void _TIFFsetLongArray(uint32** lpp, uint32* lp, uint32 n)
+ { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint32)); }
+void _TIFFsetLong8Array(uint64** lpp, uint64* lp, uint32 n)
+ { setByteArray((void**) lpp, (void*) lp, n, sizeof (uint64)); }
+void _TIFFsetFloatArray(float** fpp, float* fp, uint32 n)
+ { setByteArray((void**) fpp, (void*) fp, n, sizeof (float)); }
+void _TIFFsetDoubleArray(double** dpp, double* dp, uint32 n)
+ { setByteArray((void**) dpp, (void*) dp, n, sizeof (double)); }
+
+static void
+setDoubleArrayOneValue(double** vpp, double value, size_t nmemb)
+{
+ if (*vpp)
+ _TIFFfree(*vpp);
+ *vpp = _TIFFmalloc(nmemb*sizeof(double));
+ if (*vpp)
+ {
+ while (nmemb--)
+ ((double*)*vpp)[nmemb] = value;
+ }
+}
+
+/*
+ * Install extra samples information.
+ */
+static int
+setExtraSamples(TIFFDirectory* td, va_list ap, uint32* v)
+{
+/* XXX: Unassociated alpha data == 999 is a known Corel Draw bug, see below */
+#define EXTRASAMPLE_COREL_UNASSALPHA 999
+
+ uint16* va;
+ uint32 i;
+
+ *v = (uint16) va_arg(ap, uint16_vap);
+ if ((uint16) *v > td->td_samplesperpixel)
+ return 0;
+ va = va_arg(ap, uint16*);
+ if (*v > 0 && va == NULL) /* typically missing param */
+ return 0;
+ for (i = 0; i < *v; i++) {
+ if (va[i] > EXTRASAMPLE_UNASSALPHA) {
+ /*
+ * XXX: Corel Draw is known to produce incorrect
+ * ExtraSamples tags which must be patched here if we
+ * want to be able to open some of the damaged TIFF
+ * files:
+ */
+ if (va[i] == EXTRASAMPLE_COREL_UNASSALPHA)
+ va[i] = EXTRASAMPLE_UNASSALPHA;
+ else
+ return 0;
+ }
+ }
+ td->td_extrasamples = (uint16) *v;
+ _TIFFsetShortArray(&td->td_sampleinfo, va, td->td_extrasamples);
+ return 1;
+
+#undef EXTRASAMPLE_COREL_UNASSALPHA
+}
+
+/*
+ * Confirm we have "samplesperpixel" ink names separated by \0. Returns
+ * zero if the ink names are not as expected.
+ */
+static uint32
+checkInkNamesString(TIFF* tif, uint32 slen, const char* s)
+{
+ TIFFDirectory* td = &tif->tif_dir;
+ uint16 i = td->td_samplesperpixel;
+
+ if (slen > 0) {
+ const char* ep = s+slen;
+ const char* cp = s;
+ for (; i > 0; i--) {
+ for (; cp < ep && *cp != '\0'; cp++) {}
+ if (cp >= ep)
+ goto bad;
+ cp++; /* skip \0 */
+ }
+ return ((uint32)(cp-s));
+ }
+bad:
+ TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
+ "%s: Invalid InkNames value; expecting %d names, found %d",
+ tif->tif_name,
+ td->td_samplesperpixel,
+ td->td_samplesperpixel-i);
+ return (0);
+}
+
+static int
+_TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ static const char module[] = "_TIFFVSetField";
+
+ TIFFDirectory* td = &tif->tif_dir;
+ int status = 1;
+ uint32 v32, i, v;
+ char* s;
+ const TIFFField *fip = TIFFFindField(tif, tag, TIFF_ANY);
+ uint32 standard_tag = tag;
+
+ /*
+ * We want to force the custom code to be used for custom
+ * fields even if the tag happens to match a well known
+ * one - important for reinterpreted handling of standard
+ * tag values in custom directories (ie. EXIF)
+ */
+ if (fip->field_bit == FIELD_CUSTOM) {
+ standard_tag = 0;
+ }
+
+ switch (standard_tag) {
+ case TIFFTAG_SUBFILETYPE:
+ td->td_subfiletype = (uint32) va_arg(ap, uint32);
+ break;
+ case TIFFTAG_IMAGEWIDTH:
+ td->td_imagewidth = (uint32) va_arg(ap, uint32);
+ break;
+ case TIFFTAG_IMAGELENGTH:
+ td->td_imagelength = (uint32) va_arg(ap, uint32);
+ break;
+ case TIFFTAG_BITSPERSAMPLE:
+ td->td_bitspersample = (uint16) va_arg(ap, uint16_vap);
+ /*
+ * If the data require post-decoding processing to byte-swap
+ * samples, set it up here. Note that since tags are required
+ * to be ordered, compression code can override this behaviour
+ * in the setup method if it wants to roll the post decoding
+ * work in with its normal work.
+ */
+ if (tif->tif_flags & TIFF_SWAB) {
+ if (td->td_bitspersample == 8)
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ else if (td->td_bitspersample == 16)
+ tif->tif_postdecode = _TIFFSwab16BitData;
+ else if (td->td_bitspersample == 24)
+ tif->tif_postdecode = _TIFFSwab24BitData;
+ else if (td->td_bitspersample == 32)
+ tif->tif_postdecode = _TIFFSwab32BitData;
+ else if (td->td_bitspersample == 64)
+ tif->tif_postdecode = _TIFFSwab64BitData;
+ else if (td->td_bitspersample == 128) /* two 64's */
+ tif->tif_postdecode = _TIFFSwab64BitData;
+ }
+ break;
+ case TIFFTAG_COMPRESSION:
+ v = (uint16) va_arg(ap, uint16_vap);
+ /*
+ * If we're changing the compression scheme, the notify the
+ * previous module so that it can cleanup any state it's
+ * setup.
+ */
+ if (TIFFFieldSet(tif, FIELD_COMPRESSION)) {
+ if ((uint32)td->td_compression == v)
+ break;
+ (*tif->tif_cleanup)(tif);
+ tif->tif_flags &= ~TIFF_CODERSETUP;
+ }
+ /*
+ * Setup new compression routine state.
+ */
+ if( (status = TIFFSetCompressionScheme(tif, v)) != 0 )
+ td->td_compression = (uint16) v;
+ else
+ status = 0;
+ break;
+ case TIFFTAG_PHOTOMETRIC:
+ td->td_photometric = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_THRESHHOLDING:
+ td->td_threshholding = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_FILLORDER:
+ v = (uint16) va_arg(ap, uint16_vap);
+ if (v != FILLORDER_LSB2MSB && v != FILLORDER_MSB2LSB)
+ goto badvalue;
+ td->td_fillorder = (uint16) v;
+ break;
+ case TIFFTAG_ORIENTATION:
+ v = (uint16) va_arg(ap, uint16_vap);
+ if (v < ORIENTATION_TOPLEFT || ORIENTATION_LEFTBOT < v)
+ goto badvalue;
+ else
+ td->td_orientation = (uint16) v;
+ break;
+ case TIFFTAG_SAMPLESPERPIXEL:
+ v = (uint16) va_arg(ap, uint16_vap);
+ if (v == 0)
+ goto badvalue;
+ td->td_samplesperpixel = (uint16) v;
+ break;
+ case TIFFTAG_ROWSPERSTRIP:
+ v32 = (uint32) va_arg(ap, uint32);
+ if (v32 == 0)
+ goto badvalue32;
+ td->td_rowsperstrip = v32;
+ if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
+ td->td_tilelength = v32;
+ td->td_tilewidth = td->td_imagewidth;
+ }
+ break;
+ case TIFFTAG_MINSAMPLEVALUE:
+ td->td_minsamplevalue = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_MAXSAMPLEVALUE:
+ td->td_maxsamplevalue = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ _TIFFsetDoubleArray(&td->td_sminsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
+ else
+ setDoubleArrayOneValue(&td->td_sminsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
+ break;
+ case TIFFTAG_SMAXSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ _TIFFsetDoubleArray(&td->td_smaxsamplevalue, va_arg(ap, double*), td->td_samplesperpixel);
+ else
+ setDoubleArrayOneValue(&td->td_smaxsamplevalue, va_arg(ap, double), td->td_samplesperpixel);
+ break;
+ case TIFFTAG_XRESOLUTION:
+ td->td_xresolution = (float) va_arg(ap, double);
+ break;
+ case TIFFTAG_YRESOLUTION:
+ td->td_yresolution = (float) va_arg(ap, double);
+ break;
+ case TIFFTAG_PLANARCONFIG:
+ v = (uint16) va_arg(ap, uint16_vap);
+ if (v != PLANARCONFIG_CONTIG && v != PLANARCONFIG_SEPARATE)
+ goto badvalue;
+ td->td_planarconfig = (uint16) v;
+ break;
+ case TIFFTAG_XPOSITION:
+ td->td_xposition = (float) va_arg(ap, double);
+ break;
+ case TIFFTAG_YPOSITION:
+ td->td_yposition = (float) va_arg(ap, double);
+ break;
+ case TIFFTAG_RESOLUTIONUNIT:
+ v = (uint16) va_arg(ap, uint16_vap);
+ if (v < RESUNIT_NONE || RESUNIT_CENTIMETER < v)
+ goto badvalue;
+ td->td_resolutionunit = (uint16) v;
+ break;
+ case TIFFTAG_PAGENUMBER:
+ td->td_pagenumber[0] = (uint16) va_arg(ap, uint16_vap);
+ td->td_pagenumber[1] = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_HALFTONEHINTS:
+ td->td_halftonehints[0] = (uint16) va_arg(ap, uint16_vap);
+ td->td_halftonehints[1] = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_COLORMAP:
+ v32 = (uint32)(1L<<td->td_bitspersample);
+ _TIFFsetShortArray(&td->td_colormap[0], va_arg(ap, uint16*), v32);
+ _TIFFsetShortArray(&td->td_colormap[1], va_arg(ap, uint16*), v32);
+ _TIFFsetShortArray(&td->td_colormap[2], va_arg(ap, uint16*), v32);
+ break;
+ case TIFFTAG_EXTRASAMPLES:
+ if (!setExtraSamples(td, ap, &v))
+ goto badvalue;
+ break;
+ case TIFFTAG_MATTEING:
+ td->td_extrasamples = (((uint16) va_arg(ap, uint16_vap)) != 0);
+ if (td->td_extrasamples) {
+ uint16 sv = EXTRASAMPLE_ASSOCALPHA;
+ _TIFFsetShortArray(&td->td_sampleinfo, &sv, 1);
+ }
+ break;
+ case TIFFTAG_TILEWIDTH:
+ v32 = (uint32) va_arg(ap, uint32);
+ if (v32 % 16) {
+ if (tif->tif_mode != O_RDONLY)
+ goto badvalue32;
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+ "Nonstandard tile width %d, convert file", v32);
+ }
+ td->td_tilewidth = v32;
+ tif->tif_flags |= TIFF_ISTILED;
+ break;
+ case TIFFTAG_TILELENGTH:
+ v32 = (uint32) va_arg(ap, uint32);
+ if (v32 % 16) {
+ if (tif->tif_mode != O_RDONLY)
+ goto badvalue32;
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+ "Nonstandard tile length %d, convert file", v32);
+ }
+ td->td_tilelength = v32;
+ tif->tif_flags |= TIFF_ISTILED;
+ break;
+ case TIFFTAG_TILEDEPTH:
+ v32 = (uint32) va_arg(ap, uint32);
+ if (v32 == 0)
+ goto badvalue32;
+ td->td_tiledepth = v32;
+ break;
+ case TIFFTAG_DATATYPE:
+ v = (uint16) va_arg(ap, uint16_vap);
+ switch (v) {
+ case DATATYPE_VOID: v = SAMPLEFORMAT_VOID; break;
+ case DATATYPE_INT: v = SAMPLEFORMAT_INT; break;
+ case DATATYPE_UINT: v = SAMPLEFORMAT_UINT; break;
+ case DATATYPE_IEEEFP: v = SAMPLEFORMAT_IEEEFP;break;
+ default: goto badvalue;
+ }
+ td->td_sampleformat = (uint16) v;
+ break;
+ case TIFFTAG_SAMPLEFORMAT:
+ v = (uint16) va_arg(ap, uint16_vap);
+ if (v < SAMPLEFORMAT_UINT || SAMPLEFORMAT_COMPLEXIEEEFP < v)
+ goto badvalue;
+ td->td_sampleformat = (uint16) v;
+
+ /* Try to fix up the SWAB function for complex data. */
+ if( td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
+ && td->td_bitspersample == 32
+ && tif->tif_postdecode == _TIFFSwab32BitData )
+ tif->tif_postdecode = _TIFFSwab16BitData;
+ else if( (td->td_sampleformat == SAMPLEFORMAT_COMPLEXINT
+ || td->td_sampleformat == SAMPLEFORMAT_COMPLEXIEEEFP)
+ && td->td_bitspersample == 64
+ && tif->tif_postdecode == _TIFFSwab64BitData )
+ tif->tif_postdecode = _TIFFSwab32BitData;
+ break;
+ case TIFFTAG_IMAGEDEPTH:
+ td->td_imagedepth = (uint32) va_arg(ap, uint32);
+ break;
+ case TIFFTAG_SUBIFD:
+ if ((tif->tif_flags & TIFF_INSUBIFD) == 0) {
+ td->td_nsubifd = (uint16) va_arg(ap, uint16_vap);
+ _TIFFsetLong8Array(&td->td_subifd, (uint64*) va_arg(ap, uint64*),
+ (long) td->td_nsubifd);
+ } else {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Sorry, cannot nest SubIFDs",
+ tif->tif_name);
+ status = 0;
+ }
+ break;
+ case TIFFTAG_YCBCRPOSITIONING:
+ td->td_ycbcrpositioning = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ td->td_ycbcrsubsampling[0] = (uint16) va_arg(ap, uint16_vap);
+ td->td_ycbcrsubsampling[1] = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_TRANSFERFUNCTION:
+ v = (td->td_samplesperpixel - td->td_extrasamples) > 1 ? 3 : 1;
+ for (i = 0; i < v; i++)
+ _TIFFsetShortArray(&td->td_transferfunction[i],
+ va_arg(ap, uint16*), 1L<<td->td_bitspersample);
+ break;
+ case TIFFTAG_REFERENCEBLACKWHITE:
+ /* XXX should check for null range */
+ _TIFFsetFloatArray(&td->td_refblackwhite, va_arg(ap, float*), 6);
+ break;
+ case TIFFTAG_INKNAMES:
+ v = (uint16) va_arg(ap, uint16_vap);
+ s = va_arg(ap, char*);
+ v = checkInkNamesString(tif, v, s);
+ status = v > 0;
+ if( v > 0 ) {
+ _TIFFsetNString(&td->td_inknames, s, v);
+ td->td_inknameslen = v;
+ }
+ break;
+ case TIFFTAG_PERSAMPLE:
+ v = (uint16) va_arg(ap, uint16_vap);
+ if( v == PERSAMPLE_MULTI )
+ tif->tif_flags |= TIFF_PERSAMPLE;
+ else
+ tif->tif_flags &= ~TIFF_PERSAMPLE;
+ break;
+ default: {
+ TIFFTagValue *tv;
+ int tv_size, iCustom;
+
+ /*
+ * This can happen if multiple images are open with different
+ * codecs which have private tags. The global tag information
+ * table may then have tags that are valid for one file but not
+ * the other. If the client tries to set a tag that is not valid
+ * for the image's codec then we'll arrive here. This
+ * happens, for example, when tiffcp is used to convert between
+ * compression schemes and codec-specific tags are blindly copied.
+ */
+ if(fip == NULL || fip->field_bit != FIELD_CUSTOM) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Invalid %stag \"%s\" (not supported by codec)",
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "",
+ fip ? fip->field_name : "Unknown");
+ status = 0;
+ break;
+ }
+
+ /*
+ * Find the existing entry for this custom value.
+ */
+ tv = NULL;
+ for (iCustom = 0; iCustom < td->td_customValueCount; iCustom++) {
+ if (td->td_customValues[iCustom].info->field_tag == tag) {
+ tv = td->td_customValues + iCustom;
+ if (tv->value != NULL) {
+ _TIFFfree(tv->value);
+ tv->value = NULL;
+ }
+ break;
+ }
+ }
+
+ /*
+ * Grow the custom list if the entry was not found.
+ */
+ if(tv == NULL) {
+ TIFFTagValue *new_customValues;
+
+ td->td_customValueCount++;
+ new_customValues = (TIFFTagValue *)
+ _TIFFrealloc(td->td_customValues,
+ sizeof(TIFFTagValue) * td->td_customValueCount);
+ if (!new_customValues) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Failed to allocate space for list of custom values",
+ tif->tif_name);
+ status = 0;
+ goto end;
+ }
+
+ td->td_customValues = new_customValues;
+
+ tv = td->td_customValues + (td->td_customValueCount - 1);
+ tv->info = fip;
+ tv->value = NULL;
+ tv->count = 0;
+ }
+
+ /*
+ * Set custom value ... save a copy of the custom tag value.
+ */
+ tv_size = _TIFFDataSize(fip->field_type);
+ if (tv_size == 0) {
+ status = 0;
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Bad field type %d for \"%s\"",
+ tif->tif_name, fip->field_type,
+ fip->field_name);
+ goto end;
+ }
+
+ if (fip->field_type == TIFF_ASCII)
+ {
+ uint32 ma;
+ char* mb;
+ if (fip->field_passcount)
+ {
+ assert(fip->field_writecount==TIFF_VARIABLE2);
+ ma=(uint32)va_arg(ap,uint32);
+ mb=(char*)va_arg(ap,char*);
+ }
+ else
+ {
+ mb=(char*)va_arg(ap,char*);
+ ma=(uint32)(strlen(mb)+1);
+ }
+ tv->count=ma;
+ setByteArray(&tv->value,mb,ma,1);
+ }
+ else
+ {
+ if (fip->field_passcount) {
+ if (fip->field_writecount == TIFF_VARIABLE2)
+ tv->count = (uint32) va_arg(ap, uint32);
+ else
+ tv->count = (int) va_arg(ap, int);
+ } else if (fip->field_writecount == TIFF_VARIABLE
+ || fip->field_writecount == TIFF_VARIABLE2)
+ tv->count = 1;
+ else if (fip->field_writecount == TIFF_SPP)
+ tv->count = td->td_samplesperpixel;
+ else
+ tv->count = fip->field_writecount;
+
+ if (tv->count == 0) {
+ status = 0;
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Null count for \"%s\" (type "
+ "%d, writecount %d, passcount %d)",
+ tif->tif_name,
+ fip->field_name,
+ fip->field_type,
+ fip->field_writecount,
+ fip->field_passcount);
+ goto end;
+ }
+
+ tv->value = _TIFFCheckMalloc(tif, tv->count, tv_size,
+ "custom tag binary object");
+ if (!tv->value) {
+ status = 0;
+ goto end;
+ }
+
+ if (fip->field_tag == TIFFTAG_DOTRANGE
+ && strcmp(fip->field_name,"DotRange") == 0) {
+ /* TODO: This is an evil exception and should not have been
+ handled this way ... likely best if we move it into
+ the directory structure with an explicit field in
+ libtiff 4.1 and assign it a FIELD_ value */
+ uint16 v[2];
+ v[0] = (uint16)va_arg(ap, int);
+ v[1] = (uint16)va_arg(ap, int);
+ _TIFFmemcpy(tv->value, &v, 4);
+ }
+
+ else if (fip->field_passcount
+ || fip->field_writecount == TIFF_VARIABLE
+ || fip->field_writecount == TIFF_VARIABLE2
+ || fip->field_writecount == TIFF_SPP
+ || tv->count > 1) {
+ _TIFFmemcpy(tv->value, va_arg(ap, void *),
+ tv->count * tv_size);
+ } else {
+ char *val = (char *)tv->value;
+ assert( tv->count == 1 );
+
+ switch (fip->field_type) {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ {
+ uint8 v = (uint8)va_arg(ap, int);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8 v = (int8)va_arg(ap, int);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16 v = (uint16)va_arg(ap, int);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16 v = (int16)va_arg(ap, int);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_LONG:
+ case TIFF_IFD:
+ {
+ uint32 v = va_arg(ap, uint32);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32 v = va_arg(ap, int32);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ {
+ uint64 v = va_arg(ap, uint64);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64 v = va_arg(ap, int64);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ {
+ float v = (float)va_arg(ap, double);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ case TIFF_DOUBLE:
+ {
+ double v = va_arg(ap, double);
+ _TIFFmemcpy(val, &v, tv_size);
+ }
+ break;
+ default:
+ _TIFFmemset(val, 0, tv_size);
+ status = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (status) {
+ const TIFFField* fip=TIFFFieldWithTag(tif,tag);
+ if (fip)
+ TIFFSetFieldBit(tif, fip->field_bit);
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ }
+
+end:
+ va_end(ap);
+ return (status);
+badvalue:
+ {
+ const TIFFField* fip=TIFFFieldWithTag(tif,tag);
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Bad value %u for \"%s\" tag",
+ tif->tif_name, v,
+ fip ? fip->field_name : "Unknown");
+ va_end(ap);
+ }
+ return (0);
+badvalue32:
+ {
+ const TIFFField* fip=TIFFFieldWithTag(tif,tag);
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Bad value %u for \"%s\" tag",
+ tif->tif_name, v32,
+ fip ? fip->field_name : "Unknown");
+ va_end(ap);
+ }
+ return (0);
+}
+
+/*
+ * Return 1/0 according to whether or not
+ * it is permissible to set the tag's value.
+ * Note that we allow ImageLength to be changed
+ * so that we can append and extend to images.
+ * Any other tag may not be altered once writing
+ * has commenced, unless its value has no effect
+ * on the format of the data that is written.
+ */
+static int
+OkToChangeTag(TIFF* tif, uint32 tag)
+{
+ const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+ if (!fip) { /* unknown tag */
+ TIFFErrorExt(tif->tif_clientdata, "TIFFSetField", "%s: Unknown %stag %u",
+ tif->tif_name, isPseudoTag(tag) ? "pseudo-" : "", tag);
+ return (0);
+ }
+ if (tag != TIFFTAG_IMAGELENGTH && (tif->tif_flags & TIFF_BEENWRITING) &&
+ !fip->field_oktochange) {
+ /*
+ * Consult info table to see if tag can be changed
+ * after we've started writing. We only allow changes
+ * to those tags that don't/shouldn't affect the
+ * compression and/or format of the data.
+ */
+ TIFFErrorExt(tif->tif_clientdata, "TIFFSetField",
+ "%s: Cannot modify tag \"%s\" while writing",
+ tif->tif_name, fip->field_name);
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Record the value of a field in the
+ * internal directory structure. The
+ * field will be written to the file
+ * when/if the directory structure is
+ * updated.
+ */
+int
+TIFFSetField(TIFF* tif, uint32 tag, ...)
+{
+ va_list ap;
+ int status;
+
+ va_start(ap, tag);
+ status = TIFFVSetField(tif, tag, ap);
+ va_end(ap);
+ return (status);
+}
+
+/*
+ * Clear the contents of the field in the internal structure.
+ */
+int
+TIFFUnsetField(TIFF* tif, uint32 tag)
+{
+ const TIFFField *fip = TIFFFieldWithTag(tif, tag);
+ TIFFDirectory* td = &tif->tif_dir;
+
+ if( !fip )
+ return 0;
+
+ if( fip->field_bit != FIELD_CUSTOM )
+ TIFFClrFieldBit(tif, fip->field_bit);
+ else
+ {
+ TIFFTagValue *tv = NULL;
+ int i;
+
+ for (i = 0; i < td->td_customValueCount; i++) {
+
+ tv = td->td_customValues + i;
+ if( tv->info->field_tag == tag )
+ break;
+ }
+
+ if( i < td->td_customValueCount )
+ {
+ _TIFFfree(tv->value);
+ for( ; i < td->td_customValueCount-1; i++) {
+ td->td_customValues[i] = td->td_customValues[i+1];
+ }
+ td->td_customValueCount--;
+ }
+ }
+
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+
+ return (1);
+}
+
+/*
+ * Like TIFFSetField, but taking a varargs
+ * parameter list. This routine is useful
+ * for building higher-level interfaces on
+ * top of the library.
+ */
+int
+TIFFVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ return OkToChangeTag(tif, tag) ?
+ (*tif->tif_tagmethods.vsetfield)(tif, tag, ap) : 0;
+}
+
+static int
+_TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ TIFFDirectory* td = &tif->tif_dir;
+ int ret_val = 1;
+ uint32 standard_tag = tag;
+ const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+
+ /*
+ * We want to force the custom code to be used for custom
+ * fields even if the tag happens to match a well known
+ * one - important for reinterpreted handling of standard
+ * tag values in custom directories (ie. EXIF)
+ */
+ if (fip->field_bit == FIELD_CUSTOM) {
+ standard_tag = 0;
+ }
+
+ switch (standard_tag) {
+ case TIFFTAG_SUBFILETYPE:
+ *va_arg(ap, uint32*) = td->td_subfiletype;
+ break;
+ case TIFFTAG_IMAGEWIDTH:
+ *va_arg(ap, uint32*) = td->td_imagewidth;
+ break;
+ case TIFFTAG_IMAGELENGTH:
+ *va_arg(ap, uint32*) = td->td_imagelength;
+ break;
+ case TIFFTAG_BITSPERSAMPLE:
+ *va_arg(ap, uint16*) = td->td_bitspersample;
+ break;
+ case TIFFTAG_COMPRESSION:
+ *va_arg(ap, uint16*) = td->td_compression;
+ break;
+ case TIFFTAG_PHOTOMETRIC:
+ *va_arg(ap, uint16*) = td->td_photometric;
+ break;
+ case TIFFTAG_THRESHHOLDING:
+ *va_arg(ap, uint16*) = td->td_threshholding;
+ break;
+ case TIFFTAG_FILLORDER:
+ *va_arg(ap, uint16*) = td->td_fillorder;
+ break;
+ case TIFFTAG_ORIENTATION:
+ *va_arg(ap, uint16*) = td->td_orientation;
+ break;
+ case TIFFTAG_SAMPLESPERPIXEL:
+ *va_arg(ap, uint16*) = td->td_samplesperpixel;
+ break;
+ case TIFFTAG_ROWSPERSTRIP:
+ *va_arg(ap, uint32*) = td->td_rowsperstrip;
+ break;
+ case TIFFTAG_MINSAMPLEVALUE:
+ *va_arg(ap, uint16*) = td->td_minsamplevalue;
+ break;
+ case TIFFTAG_MAXSAMPLEVALUE:
+ *va_arg(ap, uint16*) = td->td_maxsamplevalue;
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ *va_arg(ap, double**) = td->td_sminsamplevalue;
+ else
+ {
+ /* libtiff historially treats this as a single value. */
+ uint16 i;
+ double v = td->td_sminsamplevalue[0];
+ for (i=1; i < td->td_samplesperpixel; ++i)
+ if( td->td_sminsamplevalue[i] < v )
+ v = td->td_sminsamplevalue[i];
+ *va_arg(ap, double*) = v;
+ }
+ break;
+ case TIFFTAG_SMAXSAMPLEVALUE:
+ if (tif->tif_flags & TIFF_PERSAMPLE)
+ *va_arg(ap, double**) = td->td_smaxsamplevalue;
+ else
+ {
+ /* libtiff historially treats this as a single value. */
+ uint16 i;
+ double v = td->td_smaxsamplevalue[0];
+ for (i=1; i < td->td_samplesperpixel; ++i)
+ if( td->td_smaxsamplevalue[i] > v )
+ v = td->td_smaxsamplevalue[i];
+ *va_arg(ap, double*) = v;
+ }
+ break;
+ case TIFFTAG_XRESOLUTION:
+ *va_arg(ap, float*) = td->td_xresolution;
+ break;
+ case TIFFTAG_YRESOLUTION:
+ *va_arg(ap, float*) = td->td_yresolution;
+ break;
+ case TIFFTAG_PLANARCONFIG:
+ *va_arg(ap, uint16*) = td->td_planarconfig;
+ break;
+ case TIFFTAG_XPOSITION:
+ *va_arg(ap, float*) = td->td_xposition;
+ break;
+ case TIFFTAG_YPOSITION:
+ *va_arg(ap, float*) = td->td_yposition;
+ break;
+ case TIFFTAG_RESOLUTIONUNIT:
+ *va_arg(ap, uint16*) = td->td_resolutionunit;
+ break;
+ case TIFFTAG_PAGENUMBER:
+ *va_arg(ap, uint16*) = td->td_pagenumber[0];
+ *va_arg(ap, uint16*) = td->td_pagenumber[1];
+ break;
+ case TIFFTAG_HALFTONEHINTS:
+ *va_arg(ap, uint16*) = td->td_halftonehints[0];
+ *va_arg(ap, uint16*) = td->td_halftonehints[1];
+ break;
+ case TIFFTAG_COLORMAP:
+ *va_arg(ap, uint16**) = td->td_colormap[0];
+ *va_arg(ap, uint16**) = td->td_colormap[1];
+ *va_arg(ap, uint16**) = td->td_colormap[2];
+ break;
+ case TIFFTAG_STRIPOFFSETS:
+ case TIFFTAG_TILEOFFSETS:
+ _TIFFFillStriles( tif );
+ *va_arg(ap, uint64**) = td->td_stripoffset;
+ break;
+ case TIFFTAG_STRIPBYTECOUNTS:
+ case TIFFTAG_TILEBYTECOUNTS:
+ _TIFFFillStriles( tif );
+ *va_arg(ap, uint64**) = td->td_stripbytecount;
+ break;
+ case TIFFTAG_MATTEING:
+ *va_arg(ap, uint16*) =
+ (td->td_extrasamples == 1 &&
+ td->td_sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
+ break;
+ case TIFFTAG_EXTRASAMPLES:
+ *va_arg(ap, uint16*) = td->td_extrasamples;
+ *va_arg(ap, uint16**) = td->td_sampleinfo;
+ break;
+ case TIFFTAG_TILEWIDTH:
+ *va_arg(ap, uint32*) = td->td_tilewidth;
+ break;
+ case TIFFTAG_TILELENGTH:
+ *va_arg(ap, uint32*) = td->td_tilelength;
+ break;
+ case TIFFTAG_TILEDEPTH:
+ *va_arg(ap, uint32*) = td->td_tiledepth;
+ break;
+ case TIFFTAG_DATATYPE:
+ switch (td->td_sampleformat) {
+ case SAMPLEFORMAT_UINT:
+ *va_arg(ap, uint16*) = DATATYPE_UINT;
+ break;
+ case SAMPLEFORMAT_INT:
+ *va_arg(ap, uint16*) = DATATYPE_INT;
+ break;
+ case SAMPLEFORMAT_IEEEFP:
+ *va_arg(ap, uint16*) = DATATYPE_IEEEFP;
+ break;
+ case SAMPLEFORMAT_VOID:
+ *va_arg(ap, uint16*) = DATATYPE_VOID;
+ break;
+ }
+ break;
+ case TIFFTAG_SAMPLEFORMAT:
+ *va_arg(ap, uint16*) = td->td_sampleformat;
+ break;
+ case TIFFTAG_IMAGEDEPTH:
+ *va_arg(ap, uint32*) = td->td_imagedepth;
+ break;
+ case TIFFTAG_SUBIFD:
+ *va_arg(ap, uint16*) = td->td_nsubifd;
+ *va_arg(ap, uint64**) = td->td_subifd;
+ break;
+ case TIFFTAG_YCBCRPOSITIONING:
+ *va_arg(ap, uint16*) = td->td_ycbcrpositioning;
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[0];
+ *va_arg(ap, uint16*) = td->td_ycbcrsubsampling[1];
+ break;
+ case TIFFTAG_TRANSFERFUNCTION:
+ *va_arg(ap, uint16**) = td->td_transferfunction[0];
+ if (td->td_samplesperpixel - td->td_extrasamples > 1) {
+ *va_arg(ap, uint16**) = td->td_transferfunction[1];
+ *va_arg(ap, uint16**) = td->td_transferfunction[2];
+ }
+ break;
+ case TIFFTAG_REFERENCEBLACKWHITE:
+ *va_arg(ap, float**) = td->td_refblackwhite;
+ break;
+ case TIFFTAG_INKNAMES:
+ *va_arg(ap, char**) = td->td_inknames;
+ break;
+ default:
+ {
+ int i;
+
+ /*
+ * This can happen if multiple images are open
+ * with different codecs which have private
+ * tags. The global tag information table may
+ * then have tags that are valid for one file
+ * but not the other. If the client tries to
+ * get a tag that is not valid for the image's
+ * codec then we'll arrive here.
+ */
+ if( fip == NULL || fip->field_bit != FIELD_CUSTOM )
+ {
+ TIFFErrorExt(tif->tif_clientdata, "_TIFFVGetField",
+ "%s: Invalid %stag \"%s\" "
+ "(not supported by codec)",
+ tif->tif_name,
+ isPseudoTag(tag) ? "pseudo-" : "",
+ fip ? fip->field_name : "Unknown");
+ ret_val = 0;
+ break;
+ }
+
+ /*
+ * Do we have a custom value?
+ */
+ ret_val = 0;
+ for (i = 0; i < td->td_customValueCount; i++) {
+ TIFFTagValue *tv = td->td_customValues + i;
+
+ if (tv->info->field_tag != tag)
+ continue;
+
+ if (fip->field_passcount) {
+ if (fip->field_readcount == TIFF_VARIABLE2)
+ *va_arg(ap, uint32*) = (uint32)tv->count;
+ else /* Assume TIFF_VARIABLE */
+ *va_arg(ap, uint16*) = (uint16)tv->count;
+ *va_arg(ap, void **) = tv->value;
+ ret_val = 1;
+ } else if (fip->field_tag == TIFFTAG_DOTRANGE
+ && strcmp(fip->field_name,"DotRange") == 0) {
+ /* TODO: This is an evil exception and should not have been
+ handled this way ... likely best if we move it into
+ the directory structure with an explicit field in
+ libtiff 4.1 and assign it a FIELD_ value */
+ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[0];
+ *va_arg(ap, uint16*) = ((uint16 *)tv->value)[1];
+ ret_val = 1;
+ } else {
+ if (fip->field_type == TIFF_ASCII
+ || fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2
+ || fip->field_readcount == TIFF_SPP
+ || tv->count > 1) {
+ *va_arg(ap, void **) = tv->value;
+ ret_val = 1;
+ } else {
+ char *val = (char *)tv->value;
+ assert( tv->count == 1 );
+ switch (fip->field_type) {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ *va_arg(ap, uint8*) =
+ *(uint8 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SBYTE:
+ *va_arg(ap, int8*) =
+ *(int8 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SHORT:
+ *va_arg(ap, uint16*) =
+ *(uint16 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SSHORT:
+ *va_arg(ap, int16*) =
+ *(int16 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_LONG:
+ case TIFF_IFD:
+ *va_arg(ap, uint32*) =
+ *(uint32 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SLONG:
+ *va_arg(ap, int32*) =
+ *(int32 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ *va_arg(ap, uint64*) =
+ *(uint64 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_SLONG8:
+ *va_arg(ap, int64*) =
+ *(int64 *)val;
+ ret_val = 1;
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ *va_arg(ap, float*) =
+ *(float *)val;
+ ret_val = 1;
+ break;
+ case TIFF_DOUBLE:
+ *va_arg(ap, double*) =
+ *(double *)val;
+ ret_val = 1;
+ break;
+ default:
+ ret_val = 0;
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ return(ret_val);
+}
+
+/*
+ * Return the value of a field in the
+ * internal directory structure.
+ */
+int
+TIFFGetField(TIFF* tif, uint32 tag, ...)
+{
+ int status;
+ va_list ap;
+
+ va_start(ap, tag);
+ status = TIFFVGetField(tif, tag, ap);
+ va_end(ap);
+ return (status);
+}
+
+/*
+ * Like TIFFGetField, but taking a varargs
+ * parameter list. This routine is useful
+ * for building higher-level interfaces on
+ * top of the library.
+ */
+int
+TIFFVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+ return (fip && (isPseudoTag(tag) || TIFFFieldSet(tif, fip->field_bit)) ?
+ (*tif->tif_tagmethods.vgetfield)(tif, tag, ap) : 0);
+}
+
+#define CleanupField(member) { \
+ if (td->member) { \
+ _TIFFfree(td->member); \
+ td->member = 0; \
+ } \
+}
+
+/*
+ * Release storage associated with a directory.
+ */
+void
+TIFFFreeDirectory(TIFF* tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ int i;
+
+ _TIFFmemset(td->td_fieldsset, 0, FIELD_SETLONGS);
+ CleanupField(td_sminsamplevalue);
+ CleanupField(td_smaxsamplevalue);
+ CleanupField(td_colormap[0]);
+ CleanupField(td_colormap[1]);
+ CleanupField(td_colormap[2]);
+ CleanupField(td_sampleinfo);
+ CleanupField(td_subifd);
+ CleanupField(td_inknames);
+ CleanupField(td_refblackwhite);
+ CleanupField(td_transferfunction[0]);
+ CleanupField(td_transferfunction[1]);
+ CleanupField(td_transferfunction[2]);
+ CleanupField(td_stripoffset);
+ CleanupField(td_stripbytecount);
+ TIFFClrFieldBit(tif, FIELD_YCBCRSUBSAMPLING);
+ TIFFClrFieldBit(tif, FIELD_YCBCRPOSITIONING);
+
+ /* Cleanup custom tag values */
+ for( i = 0; i < td->td_customValueCount; i++ ) {
+ if (td->td_customValues[i].value)
+ _TIFFfree(td->td_customValues[i].value);
+ }
+
+ td->td_customValueCount = 0;
+ CleanupField(td_customValues);
+
+#if defined(DEFER_STRILE_LOAD)
+ _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+#endif
+}
+#undef CleanupField
+
+/*
+ * Client Tag extension support (from Niles Ritter).
+ */
+static TIFFExtendProc _TIFFextender = (TIFFExtendProc) NULL;
+
+TIFFExtendProc
+TIFFSetTagExtender(TIFFExtendProc extender)
+{
+ TIFFExtendProc prev = _TIFFextender;
+ _TIFFextender = extender;
+ return (prev);
+}
+
+/*
+ * Setup for a new directory. Should we automatically call
+ * TIFFWriteDirectory() if the current one is dirty?
+ *
+ * The newly created directory will not exist on the file till
+ * TIFFWriteDirectory(), TIFFFlush() or TIFFClose() is called.
+ */
+int
+TIFFCreateDirectory(TIFF* tif)
+{
+ TIFFDefaultDirectory(tif);
+ tif->tif_diroff = 0;
+ tif->tif_nextdiroff = 0;
+ tif->tif_curoff = 0;
+ tif->tif_row = (uint32) -1;
+ tif->tif_curstrip = (uint32) -1;
+
+ return 0;
+}
+
+int
+TIFFCreateCustomDirectory(TIFF* tif, const TIFFFieldArray* infoarray)
+{
+ TIFFDefaultDirectory(tif);
+
+ /*
+ * Reset the field definitions to match the application provided list.
+ * Hopefully TIFFDefaultDirectory() won't have done anything irreversable
+ * based on it's assumption this is an image directory.
+ */
+ _TIFFSetupFields(tif, infoarray);
+
+ tif->tif_diroff = 0;
+ tif->tif_nextdiroff = 0;
+ tif->tif_curoff = 0;
+ tif->tif_row = (uint32) -1;
+ tif->tif_curstrip = (uint32) -1;
+
+ return 0;
+}
+
+int
+TIFFCreateEXIFDirectory(TIFF* tif)
+{
+ const TIFFFieldArray* exifFieldArray;
+ exifFieldArray = _TIFFGetExifFields();
+ return TIFFCreateCustomDirectory(tif, exifFieldArray);
+}
+
+/*
+ * Setup a default directory structure.
+ */
+int
+TIFFDefaultDirectory(TIFF* tif)
+{
+ register TIFFDirectory* td = &tif->tif_dir;
+ const TIFFFieldArray* tiffFieldArray;
+
+ tiffFieldArray = _TIFFGetFields();
+ _TIFFSetupFields(tif, tiffFieldArray);
+
+ _TIFFmemset(td, 0, sizeof (*td));
+ td->td_fillorder = FILLORDER_MSB2LSB;
+ td->td_bitspersample = 1;
+ td->td_threshholding = THRESHHOLD_BILEVEL;
+ td->td_orientation = ORIENTATION_TOPLEFT;
+ td->td_samplesperpixel = 1;
+ td->td_rowsperstrip = (uint32) -1;
+ td->td_tilewidth = 0;
+ td->td_tilelength = 0;
+ td->td_tiledepth = 1;
+ td->td_stripbytecountsorted = 1; /* Our own arrays always sorted. */
+ td->td_resolutionunit = RESUNIT_INCH;
+ td->td_sampleformat = SAMPLEFORMAT_UINT;
+ td->td_imagedepth = 1;
+ td->td_ycbcrsubsampling[0] = 2;
+ td->td_ycbcrsubsampling[1] = 2;
+ td->td_ycbcrpositioning = YCBCRPOSITION_CENTERED;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ tif->tif_foundfield = NULL;
+ tif->tif_tagmethods.vsetfield = _TIFFVSetField;
+ tif->tif_tagmethods.vgetfield = _TIFFVGetField;
+ tif->tif_tagmethods.printdir = NULL;
+ /*
+ * Give client code a chance to install their own
+ * tag extensions & methods, prior to compression overloads.
+ */
+ if (_TIFFextender)
+ (*_TIFFextender)(tif);
+ (void) TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
+ /*
+ * NB: The directory is marked dirty as a result of setting
+ * up the default compression scheme. However, this really
+ * isn't correct -- we want TIFF_DIRTYDIRECT to be set only
+ * if the user does something. We could just do the setup
+ * by hand, but it seems better to use the normal mechanism
+ * (i.e. TIFFSetField).
+ */
+ tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+
+ /*
+ * As per http://bugzilla.remotesensing.org/show_bug.cgi?id=19
+ * we clear the ISTILED flag when setting up a new directory.
+ * Should we also be clearing stuff like INSUBIFD?
+ */
+ tif->tif_flags &= ~TIFF_ISTILED;
+
+ return (1);
+}
+
+static int
+TIFFAdvanceDirectory(TIFF* tif, uint64* nextdir, uint64* off)
+{
+ static const char module[] = "TIFFAdvanceDirectory";
+ if (isMapped(tif))
+ {
+ uint64 poff=*nextdir;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ tmsize_t poffa,poffb,poffc,poffd;
+ uint16 dircount;
+ uint32 nextdir32;
+ poffa=(tmsize_t)poff;
+ poffb=poffa+sizeof(uint16);
+ if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint16))||(poffb>tif->tif_size))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
+ return(0);
+ }
+ _TIFFmemcpy(&dircount,tif->tif_base+poffa,sizeof(uint16));
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ poffc=poffb+dircount*12;
+ poffd=poffc+sizeof(uint32);
+ if ((poffc<poffb)||(poffc<dircount*12)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint32))||(poffd>tif->tif_size))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
+ return(0);
+ }
+ if (off!=NULL)
+ *off=(uint64)poffc;
+ _TIFFmemcpy(&nextdir32,tif->tif_base+poffc,sizeof(uint32));
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+ *nextdir=nextdir32;
+ }
+ else
+ {
+ tmsize_t poffa,poffb,poffc,poffd;
+ uint64 dircount64;
+ uint16 dircount16;
+ poffa=(tmsize_t)poff;
+ poffb=poffa+sizeof(uint64);
+ if (((uint64)poffa!=poff)||(poffb<poffa)||(poffb<(tmsize_t)sizeof(uint64))||(poffb>tif->tif_size))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory count");
+ return(0);
+ }
+ _TIFFmemcpy(&dircount64,tif->tif_base+poffa,sizeof(uint64));
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64>0xFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Sanity check on directory count failed");
+ return(0);
+ }
+ dircount16=(uint16)dircount64;
+ poffc=poffb+dircount16*20;
+ poffd=poffc+sizeof(uint64);
+ if ((poffc<poffb)||(poffc<dircount16*20)||(poffd<poffc)||(poffd<(tmsize_t)sizeof(uint64))||(poffd>tif->tif_size))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Error fetching directory link");
+ return(0);
+ }
+ if (off!=NULL)
+ *off=(uint64)poffc;
+ _TIFFmemcpy(nextdir,tif->tif_base+poffc,sizeof(uint64));
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(nextdir);
+ }
+ return(1);
+ }
+ else
+ {
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint16 dircount;
+ uint32 nextdir32;
+ if (!SeekOK(tif, *nextdir) ||
+ !ReadOK(tif, &dircount, sizeof (uint16))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ if (off != NULL)
+ *off = TIFFSeekFile(tif,
+ dircount*12, SEEK_CUR);
+ else
+ (void) TIFFSeekFile(tif,
+ dircount*12, SEEK_CUR);
+ if (!ReadOK(tif, &nextdir32, sizeof (uint32))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+ *nextdir=nextdir32;
+ }
+ else
+ {
+ uint64 dircount64;
+ uint16 dircount16;
+ if (!SeekOK(tif, *nextdir) ||
+ !ReadOK(tif, &dircount64, sizeof (uint64))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory count",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64>0xFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Error fetching directory count");
+ return(0);
+ }
+ dircount16 = (uint16)dircount64;
+ if (off != NULL)
+ *off = TIFFSeekFile(tif,
+ dircount16*20, SEEK_CUR);
+ else
+ (void) TIFFSeekFile(tif,
+ dircount16*20, SEEK_CUR);
+ if (!ReadOK(tif, nextdir, sizeof (uint64))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s: Error fetching directory link",
+ tif->tif_name);
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(nextdir);
+ }
+ return (1);
+ }
+}
+
+/*
+ * Count the number of directories in a file.
+ */
+uint16
+TIFFNumberOfDirectories(TIFF* tif)
+{
+ uint64 nextdir;
+ uint16 n;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ nextdir = tif->tif_header.classic.tiff_diroff;
+ else
+ nextdir = tif->tif_header.big.tiff_diroff;
+ n = 0;
+ while (nextdir != 0 && TIFFAdvanceDirectory(tif, &nextdir, NULL))
+ n++;
+ return (n);
+}
+
+/*
+ * Set the n-th directory as the current directory.
+ * NB: Directories are numbered starting at 0.
+ */
+int
+TIFFSetDirectory(TIFF* tif, uint16 dirn)
+{
+ uint64 nextdir;
+ uint16 n;
+
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ nextdir = tif->tif_header.classic.tiff_diroff;
+ else
+ nextdir = tif->tif_header.big.tiff_diroff;
+ for (n = dirn; n > 0 && nextdir != 0; n--)
+ if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
+ return (0);
+ tif->tif_nextdiroff = nextdir;
+ /*
+ * Set curdir to the actual directory index. The
+ * -1 is because TIFFReadDirectory will increment
+ * tif_curdir after successfully reading the directory.
+ */
+ tif->tif_curdir = (dirn - n) - 1;
+ /*
+ * Reset tif_dirnumber counter and start new list of seen directories.
+ * We need this to prevent IFD loops.
+ */
+ tif->tif_dirnumber = 0;
+ return (TIFFReadDirectory(tif));
+}
+
+/*
+ * Set the current directory to be the directory
+ * located at the specified file offset. This interface
+ * is used mainly to access directories linked with
+ * the SubIFD tag (e.g. thumbnail images).
+ */
+int
+TIFFSetSubDirectory(TIFF* tif, uint64 diroff)
+{
+ tif->tif_nextdiroff = diroff;
+ /*
+ * Reset tif_dirnumber counter and start new list of seen directories.
+ * We need this to prevent IFD loops.
+ */
+ tif->tif_dirnumber = 0;
+ return (TIFFReadDirectory(tif));
+}
+
+/*
+ * Return file offset of the current directory.
+ */
+uint64
+TIFFCurrentDirOffset(TIFF* tif)
+{
+ return (tif->tif_diroff);
+}
+
+/*
+ * Return an indication of whether or not we are
+ * at the last directory in the file.
+ */
+int
+TIFFLastDirectory(TIFF* tif)
+{
+ return (tif->tif_nextdiroff == 0);
+}
+
+/*
+ * Unlink the specified directory from the directory chain.
+ */
+int
+TIFFUnlinkDirectory(TIFF* tif, uint16 dirn)
+{
+ static const char module[] = "TIFFUnlinkDirectory";
+ uint64 nextdir;
+ uint64 off;
+ uint16 n;
+
+ if (tif->tif_mode == O_RDONLY) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Can not unlink directory in read-only file");
+ return (0);
+ }
+ /*
+ * Go to the directory before the one we want
+ * to unlink and nab the offset of the link
+ * field we'll need to patch.
+ */
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ nextdir = tif->tif_header.classic.tiff_diroff;
+ off = 4;
+ }
+ else
+ {
+ nextdir = tif->tif_header.big.tiff_diroff;
+ off = 8;
+ }
+ for (n = dirn-1; n > 0; n--) {
+ if (nextdir == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Directory %d does not exist", dirn);
+ return (0);
+ }
+ if (!TIFFAdvanceDirectory(tif, &nextdir, &off))
+ return (0);
+ }
+ /*
+ * Advance to the directory to be unlinked and fetch
+ * the offset of the directory that follows.
+ */
+ if (!TIFFAdvanceDirectory(tif, &nextdir, NULL))
+ return (0);
+ /*
+ * Go back and patch the link field of the preceding
+ * directory to point to the offset of the directory
+ * that follows.
+ */
+ (void) TIFFSeekFile(tif, off, SEEK_SET);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 nextdir32;
+ nextdir32=(uint32)nextdir;
+ assert((uint64)nextdir32==nextdir);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextdir32);
+ if (!WriteOK(tif, &nextdir32, sizeof (uint32))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
+ return (0);
+ }
+ }
+ else
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&nextdir);
+ if (!WriteOK(tif, &nextdir, sizeof (uint64))) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Error writing directory link");
+ return (0);
+ }
+ }
+ /*
+ * Leave directory state setup safely. We don't have
+ * facilities for doing inserting and removing directories,
+ * so it's safest to just invalidate everything. This
+ * means that the caller can only append to the directory
+ * chain.
+ */
+ (*tif->tif_cleanup)(tif);
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawcc = 0;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+ }
+ tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP|TIFF_POSTENCODE|TIFF_BUF4WRITE);
+ TIFFFreeDirectory(tif);
+ TIFFDefaultDirectory(tif);
+ tif->tif_diroff = 0; /* force link on next write */
+ tif->tif_nextdiroff = 0; /* next write must be at end */
+ tif->tif_curoff = 0;
+ tif->tif_row = (uint32) -1;
+ tif->tif_curstrip = (uint32) -1;
+ return (1);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.h b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.h
new file mode 100644
index 0000000000..6af5f3dc37
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dir.h
@@ -0,0 +1,308 @@
+/* $Id: tif_dir.h,v 1.54 2011-02-18 20:53:05 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFDIR_
+#define _TIFFDIR_
+/*
+ * ``Library-private'' Directory-related Definitions.
+ */
+
+typedef struct {
+ const TIFFField *info;
+ int count;
+ void *value;
+} TIFFTagValue;
+
+/*
+ * TIFF Image File Directories are comprised of a table of field
+ * descriptors of the form shown below. The table is sorted in
+ * ascending order by tag. The values associated with each entry are
+ * disjoint and may appear anywhere in the file (so long as they are
+ * placed on a word boundary).
+ *
+ * If the value is 4 bytes or less, in ClassicTIFF, or 8 bytes or less in
+ * BigTIFF, then it is placed in the offset field to save space. If so,
+ * it is left-justified in the offset field.
+ */
+typedef struct {
+ uint16 tdir_tag; /* see below */
+ uint16 tdir_type; /* data type; see below */
+ uint64 tdir_count; /* number of items; length in spec */
+ union {
+ uint16 toff_short;
+ uint32 toff_long;
+ uint64 toff_long8;
+ } tdir_offset; /* either offset or the data itself if fits */
+} TIFFDirEntry;
+
+/*
+ * Internal format of a TIFF directory entry.
+ */
+typedef struct {
+#define FIELD_SETLONGS 4
+ /* bit vector of fields that are set */
+ unsigned long td_fieldsset[FIELD_SETLONGS];
+
+ uint32 td_imagewidth, td_imagelength, td_imagedepth;
+ uint32 td_tilewidth, td_tilelength, td_tiledepth;
+ uint32 td_subfiletype;
+ uint16 td_bitspersample;
+ uint16 td_sampleformat;
+ uint16 td_compression;
+ uint16 td_photometric;
+ uint16 td_threshholding;
+ uint16 td_fillorder;
+ uint16 td_orientation;
+ uint16 td_samplesperpixel;
+ uint32 td_rowsperstrip;
+ uint16 td_minsamplevalue, td_maxsamplevalue;
+ double* td_sminsamplevalue;
+ double* td_smaxsamplevalue;
+ float td_xresolution, td_yresolution;
+ uint16 td_resolutionunit;
+ uint16 td_planarconfig;
+ float td_xposition, td_yposition;
+ uint16 td_pagenumber[2];
+ uint16* td_colormap[3];
+ uint16 td_halftonehints[2];
+ uint16 td_extrasamples;
+ uint16* td_sampleinfo;
+ /* even though the name is misleading, td_stripsperimage is the number
+ * of striles (=strips or tiles) per plane, and td_nstrips the total
+ * number of striles */
+ uint32 td_stripsperimage;
+ uint32 td_nstrips; /* size of offset & bytecount arrays */
+ uint64* td_stripoffset;
+ uint64* td_stripbytecount;
+ int td_stripbytecountsorted; /* is the bytecount array sorted ascending? */
+#if defined(DEFER_STRILE_LOAD)
+ TIFFDirEntry td_stripoffset_entry; /* for deferred loading */
+ TIFFDirEntry td_stripbytecount_entry; /* for deferred loading */
+#endif
+ uint16 td_nsubifd;
+ uint64* td_subifd;
+ /* YCbCr parameters */
+ uint16 td_ycbcrsubsampling[2];
+ uint16 td_ycbcrpositioning;
+ /* Colorimetry parameters */
+ uint16* td_transferfunction[3];
+ float* td_refblackwhite;
+ /* CMYK parameters */
+ int td_inknameslen;
+ char* td_inknames;
+
+ int td_customValueCount;
+ TIFFTagValue *td_customValues;
+} TIFFDirectory;
+
+/*
+ * Field flags used to indicate fields that have been set in a directory, and
+ * to reference fields when manipulating a directory.
+ */
+
+/*
+ * FIELD_IGNORE is used to signify tags that are to be processed but otherwise
+ * ignored. This permits antiquated tags to be quietly read and discarded.
+ * Note that a bit *is* allocated for ignored tags; this is understood by the
+ * directory reading logic which uses this fact to avoid special-case handling
+ */
+#define FIELD_IGNORE 0
+
+/* multi-item fields */
+#define FIELD_IMAGEDIMENSIONS 1
+#define FIELD_TILEDIMENSIONS 2
+#define FIELD_RESOLUTION 3
+#define FIELD_POSITION 4
+
+/* single-item fields */
+#define FIELD_SUBFILETYPE 5
+#define FIELD_BITSPERSAMPLE 6
+#define FIELD_COMPRESSION 7
+#define FIELD_PHOTOMETRIC 8
+#define FIELD_THRESHHOLDING 9
+#define FIELD_FILLORDER 10
+#define FIELD_ORIENTATION 15
+#define FIELD_SAMPLESPERPIXEL 16
+#define FIELD_ROWSPERSTRIP 17
+#define FIELD_MINSAMPLEVALUE 18
+#define FIELD_MAXSAMPLEVALUE 19
+#define FIELD_PLANARCONFIG 20
+#define FIELD_RESOLUTIONUNIT 22
+#define FIELD_PAGENUMBER 23
+#define FIELD_STRIPBYTECOUNTS 24
+#define FIELD_STRIPOFFSETS 25
+#define FIELD_COLORMAP 26
+#define FIELD_EXTRASAMPLES 31
+#define FIELD_SAMPLEFORMAT 32
+#define FIELD_SMINSAMPLEVALUE 33
+#define FIELD_SMAXSAMPLEVALUE 34
+#define FIELD_IMAGEDEPTH 35
+#define FIELD_TILEDEPTH 36
+#define FIELD_HALFTONEHINTS 37
+#define FIELD_YCBCRSUBSAMPLING 39
+#define FIELD_YCBCRPOSITIONING 40
+#define FIELD_REFBLACKWHITE 41
+#define FIELD_TRANSFERFUNCTION 44
+#define FIELD_INKNAMES 46
+#define FIELD_SUBIFD 49
+/* FIELD_CUSTOM (see tiffio.h) 65 */
+/* end of support for well-known tags; codec-private tags follow */
+#define FIELD_CODEC 66 /* base of codec-private tags */
+
+
+/*
+ * Pseudo-tags don't normally need field bits since they are not written to an
+ * output file (by definition). The library also has express logic to always
+ * query a codec for a pseudo-tag so allocating a field bit for one is a
+ * waste. If codec wants to promote the notion of a pseudo-tag being ``set''
+ * or ``unset'' then it can do using internal state flags without polluting
+ * the field bit space defined for real tags.
+ */
+#define FIELD_PSEUDO 0
+
+#define FIELD_LAST (32*FIELD_SETLONGS-1)
+
+#define BITn(n) (((unsigned long)1L)<<((n)&0x1f))
+#define BITFIELDn(tif, n) ((tif)->tif_dir.td_fieldsset[(n)/32])
+#define TIFFFieldSet(tif, field) (BITFIELDn(tif, field) & BITn(field))
+#define TIFFSetFieldBit(tif, field) (BITFIELDn(tif, field) |= BITn(field))
+#define TIFFClrFieldBit(tif, field) (BITFIELDn(tif, field) &= ~BITn(field))
+
+#define FieldSet(fields, f) (fields[(f)/32] & BITn(f))
+#define ResetFieldBit(fields, f) (fields[(f)/32] &= ~BITn(f))
+
+typedef enum {
+ TIFF_SETGET_UNDEFINED = 0,
+ TIFF_SETGET_ASCII = 1,
+ TIFF_SETGET_UINT8 = 2,
+ TIFF_SETGET_SINT8 = 3,
+ TIFF_SETGET_UINT16 = 4,
+ TIFF_SETGET_SINT16 = 5,
+ TIFF_SETGET_UINT32 = 6,
+ TIFF_SETGET_SINT32 = 7,
+ TIFF_SETGET_UINT64 = 8,
+ TIFF_SETGET_SINT64 = 9,
+ TIFF_SETGET_FLOAT = 10,
+ TIFF_SETGET_DOUBLE = 11,
+ TIFF_SETGET_IFD8 = 12,
+ TIFF_SETGET_INT = 13,
+ TIFF_SETGET_UINT16_PAIR = 14,
+ TIFF_SETGET_C0_ASCII = 15,
+ TIFF_SETGET_C0_UINT8 = 16,
+ TIFF_SETGET_C0_SINT8 = 17,
+ TIFF_SETGET_C0_UINT16 = 18,
+ TIFF_SETGET_C0_SINT16 = 19,
+ TIFF_SETGET_C0_UINT32 = 20,
+ TIFF_SETGET_C0_SINT32 = 21,
+ TIFF_SETGET_C0_UINT64 = 22,
+ TIFF_SETGET_C0_SINT64 = 23,
+ TIFF_SETGET_C0_FLOAT = 24,
+ TIFF_SETGET_C0_DOUBLE = 25,
+ TIFF_SETGET_C0_IFD8 = 26,
+ TIFF_SETGET_C16_ASCII = 27,
+ TIFF_SETGET_C16_UINT8 = 28,
+ TIFF_SETGET_C16_SINT8 = 29,
+ TIFF_SETGET_C16_UINT16 = 30,
+ TIFF_SETGET_C16_SINT16 = 31,
+ TIFF_SETGET_C16_UINT32 = 32,
+ TIFF_SETGET_C16_SINT32 = 33,
+ TIFF_SETGET_C16_UINT64 = 34,
+ TIFF_SETGET_C16_SINT64 = 35,
+ TIFF_SETGET_C16_FLOAT = 36,
+ TIFF_SETGET_C16_DOUBLE = 37,
+ TIFF_SETGET_C16_IFD8 = 38,
+ TIFF_SETGET_C32_ASCII = 39,
+ TIFF_SETGET_C32_UINT8 = 40,
+ TIFF_SETGET_C32_SINT8 = 41,
+ TIFF_SETGET_C32_UINT16 = 42,
+ TIFF_SETGET_C32_SINT16 = 43,
+ TIFF_SETGET_C32_UINT32 = 44,
+ TIFF_SETGET_C32_SINT32 = 45,
+ TIFF_SETGET_C32_UINT64 = 46,
+ TIFF_SETGET_C32_SINT64 = 47,
+ TIFF_SETGET_C32_FLOAT = 48,
+ TIFF_SETGET_C32_DOUBLE = 49,
+ TIFF_SETGET_C32_IFD8 = 50,
+ TIFF_SETGET_OTHER = 51
+} TIFFSetGetFieldType;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+extern const TIFFFieldArray* _TIFFGetFields(void);
+extern const TIFFFieldArray* _TIFFGetExifFields(void);
+extern void _TIFFSetupFields(TIFF* tif, const TIFFFieldArray* infoarray);
+extern void _TIFFPrintFieldInfo(TIFF*, FILE*);
+
+extern int _TIFFFillStriles(TIFF*);
+
+typedef enum {
+ tfiatImage,
+ tfiatExif,
+ tfiatOther
+} TIFFFieldArrayType;
+
+struct _TIFFFieldArray {
+ TIFFFieldArrayType type; /* array type, will be used to determine if IFD is image and such */
+ uint32 allocated_size; /* 0 if array is constant, other if modified by future definition extension support */
+ uint32 count; /* number of elements in fields array */
+ TIFFField* fields; /* actual field info */
+};
+
+struct _TIFFField {
+ uint32 field_tag; /* field's tag */
+ short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
+ short field_writecount; /* write count/TIFF_VARIABLE */
+ TIFFDataType field_type; /* type of associated data */
+ uint32 reserved; /* reserved for future extension */
+ TIFFSetGetFieldType set_field_type; /* type to be passed to TIFFSetField */
+ TIFFSetGetFieldType get_field_type; /* type to be passed to TIFFGetField */
+ unsigned short field_bit; /* bit in fieldsset bit vector */
+ unsigned char field_oktochange; /* if true, can change while writing */
+ unsigned char field_passcount; /* if true, pass dir count on set */
+ char* field_name; /* ASCII name */
+ TIFFFieldArray* field_subfields; /* if field points to child ifds, child ifd field definition array */
+};
+
+extern int _TIFFMergeFields(TIFF*, const TIFFField[], uint32);
+extern const TIFFField* _TIFFFindOrRegisterField(TIFF *, uint32, TIFFDataType);
+extern TIFFField* _TIFFCreateAnonField(TIFF *, uint32, TIFFDataType);
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFDIR_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirinfo.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirinfo.c
new file mode 100644
index 0000000000..5f28d23602
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirinfo.c
@@ -0,0 +1,978 @@
+/* $Id: tif_dirinfo.c,v 1.117 2012-08-19 16:56:34 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Core Directory Tag Support.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <stdlib.h>
+
+/*
+ * NOTE: THIS ARRAY IS ASSUMED TO BE SORTED BY TAG.
+ *
+ * NOTE: The second field (field_readcount) and third field (field_writecount)
+ * sometimes use the values TIFF_VARIABLE (-1), TIFF_VARIABLE2 (-3)
+ * and TIFF_SPP (-2). The macros should be used but would throw off
+ * the formatting of the code, so please interprete the -1, -2 and -3
+ * values accordingly.
+ */
+
+static TIFFFieldArray tiffFieldArray;
+static TIFFFieldArray exifFieldArray;
+
+static TIFFField
+tiffFields[] = {
+ { TIFFTAG_SUBFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "SubfileType", NULL },
+ { TIFFTAG_OSUBFILETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_SUBFILETYPE, 1, 0, "OldSubfileType", NULL },
+ { TIFFTAG_IMAGEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 0, 0, "ImageWidth", NULL },
+ { TIFFTAG_IMAGELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDIMENSIONS, 1, 0, "ImageLength", NULL },
+ { TIFFTAG_BITSPERSAMPLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_BITSPERSAMPLE, 0, 0, "BitsPerSample", NULL },
+ { TIFFTAG_COMPRESSION, -1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_COMPRESSION, 0, 0, "Compression", NULL },
+ { TIFFTAG_PHOTOMETRIC, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PHOTOMETRIC, 0, 0, "PhotometricInterpretation", NULL },
+ { TIFFTAG_THRESHHOLDING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_THRESHHOLDING, 1, 0, "Threshholding", NULL },
+ { TIFFTAG_CELLWIDTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellWidth", NULL },
+ { TIFFTAG_CELLLENGTH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "CellLength", NULL },
+ { TIFFTAG_FILLORDER, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_FILLORDER, 0, 0, "FillOrder", NULL },
+ { TIFFTAG_DOCUMENTNAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DocumentName", NULL },
+ { TIFFTAG_IMAGEDESCRIPTION, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageDescription", NULL },
+ { TIFFTAG_MAKE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Make", NULL },
+ { TIFFTAG_MODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Model", NULL },
+ { TIFFTAG_STRIPOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "StripOffsets", NULL },
+ { TIFFTAG_ORIENTATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_ORIENTATION, 0, 0, "Orientation", NULL },
+ { TIFFTAG_SAMPLESPERPIXEL, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLESPERPIXEL, 0, 0, "SamplesPerPixel", NULL },
+ { TIFFTAG_ROWSPERSTRIP, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_ROWSPERSTRIP, 0, 0, "RowsPerStrip", NULL },
+ { TIFFTAG_STRIPBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "StripByteCounts", NULL },
+ { TIFFTAG_MINSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MINSAMPLEVALUE, 1, 0, "MinSampleValue", NULL },
+ { TIFFTAG_MAXSAMPLEVALUE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_MAXSAMPLEVALUE, 1, 0, "MaxSampleValue", NULL },
+ { TIFFTAG_XRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "XResolution", NULL },
+ { TIFFTAG_YRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTION, 1, 0, "YResolution", NULL },
+ { TIFFTAG_PLANARCONFIG, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_PLANARCONFIG, 0, 0, "PlanarConfiguration", NULL },
+ { TIFFTAG_PAGENAME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PageName", NULL },
+ { TIFFTAG_XPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "XPosition", NULL },
+ { TIFFTAG_YPOSITION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_POSITION, 1, 0, "YPosition", NULL },
+ { TIFFTAG_FREEOFFSETS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeOffsets", NULL },
+ { TIFFTAG_FREEBYTECOUNTS, -1, -1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 0, 0, "FreeByteCounts", NULL },
+ { TIFFTAG_GRAYRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseUnit", NULL },
+ { TIFFTAG_GRAYRESPONSECURVE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "GrayResponseCurve", NULL },
+ { TIFFTAG_RESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_RESOLUTIONUNIT, 1, 0, "ResolutionUnit", NULL },
+ { TIFFTAG_PAGENUMBER, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_PAGENUMBER, 1, 0, "PageNumber", NULL },
+ { TIFFTAG_COLORRESPONSEUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_IGNORE, 1, 0, "ColorResponseUnit", NULL },
+ { TIFFTAG_TRANSFERFUNCTION, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_TRANSFERFUNCTION, 1, 0, "TransferFunction", NULL },
+ { TIFFTAG_SOFTWARE, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Software", NULL },
+ { TIFFTAG_DATETIME, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTime", NULL },
+ { TIFFTAG_ARTIST, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Artist", NULL },
+ { TIFFTAG_HOSTCOMPUTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "HostComputer", NULL },
+ { TIFFTAG_WHITEPOINT, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhitePoint", NULL },
+ { TIFFTAG_PRIMARYCHROMATICITIES, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PrimaryChromaticities", NULL },
+ { TIFFTAG_COLORMAP, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_COLORMAP, 1, 0, "ColorMap", NULL },
+ { TIFFTAG_HALFTONEHINTS, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_HALFTONEHINTS, 1, 0, "HalftoneHints", NULL },
+ { TIFFTAG_TILEWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileWidth", NULL },
+ { TIFFTAG_TILELENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDIMENSIONS, 0, 0, "TileLength", NULL },
+ { TIFFTAG_TILEOFFSETS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPOFFSETS, 0, 0, "TileOffsets", NULL },
+ { TIFFTAG_TILEBYTECOUNTS, -1, 1, TIFF_LONG8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_STRIPBYTECOUNTS, 0, 0, "TileByteCounts", NULL },
+ { TIFFTAG_SUBIFD, -1, -1, TIFF_IFD8, 0, TIFF_SETGET_C16_IFD8, TIFF_SETGET_UNDEFINED, FIELD_SUBIFD, 1, 1, "SubIFD", &tiffFieldArray },
+ { TIFFTAG_INKSET, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InkSet", NULL },
+ { TIFFTAG_INKNAMES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_C16_ASCII, TIFF_SETGET_UNDEFINED, FIELD_INKNAMES, 1, 1, "InkNames", NULL },
+ { TIFFTAG_NUMBEROFINKS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "NumberOfInks", NULL },
+ { TIFFTAG_DOTRANGE, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DotRange", NULL },
+ { TIFFTAG_TARGETPRINTER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TargetPrinter", NULL },
+ { TIFFTAG_EXTRASAMPLES, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 1, "ExtraSamples", NULL },
+ { TIFFTAG_SAMPLEFORMAT, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "SampleFormat", NULL },
+ { TIFFTAG_SMINSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMINSAMPLEVALUE, 1, 0, "SMinSampleValue", NULL },
+ { TIFFTAG_SMAXSAMPLEVALUE, -2, -1, TIFF_ANY, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_SMAXSAMPLEVALUE, 1, 0, "SMaxSampleValue", NULL },
+ { TIFFTAG_CLIPPATH, -1, -3, TIFF_BYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ClipPath", NULL },
+ { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
+ { TIFFTAG_XCLIPPATHUNITS, 1, 1, TIFF_SBYTE, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "XClipPathUnits", NULL },
+ { TIFFTAG_YCLIPPATHUNITS, 1, 1, TIFF_SLONG, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YClipPathUnits", NULL },
+ { TIFFTAG_YCBCRCOEFFICIENTS, 3, 3, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "YCbCrCoefficients", NULL },
+ { TIFFTAG_YCBCRSUBSAMPLING, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_UINT16_PAIR, TIFF_SETGET_UNDEFINED, FIELD_YCBCRSUBSAMPLING, 0, 0, "YCbCrSubsampling", NULL },
+ { TIFFTAG_YCBCRPOSITIONING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_YCBCRPOSITIONING, 0, 0, "YCbCrPositioning", NULL },
+ { TIFFTAG_REFERENCEBLACKWHITE, 6, 6, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_REFBLACKWHITE, 1, 0, "ReferenceBlackWhite", NULL },
+ { TIFFTAG_XMLPACKET, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "XMLPacket", NULL },
+ /* begin SGI tags */
+ { TIFFTAG_MATTEING, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_EXTRASAMPLES, 0, 0, "Matteing", NULL },
+ { TIFFTAG_DATATYPE, -2, -1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_SAMPLEFORMAT, 0, 0, "DataType", NULL },
+ { TIFFTAG_IMAGEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_IMAGEDEPTH, 0, 0, "ImageDepth", NULL },
+ { TIFFTAG_TILEDEPTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_TILEDEPTH, 0, 0, "TileDepth", NULL },
+ /* end SGI tags */
+ /* begin Pixar tags */
+ { TIFFTAG_PIXAR_IMAGEFULLWIDTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullWidth", NULL },
+ { TIFFTAG_PIXAR_IMAGEFULLLENGTH, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageFullLength", NULL },
+ { TIFFTAG_PIXAR_TEXTUREFORMAT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureFormat", NULL },
+ { TIFFTAG_PIXAR_WRAPMODES, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "TextureWrapModes", NULL },
+ { TIFFTAG_PIXAR_FOVCOT, 1, 1, TIFF_FLOAT, 0, TIFF_SETGET_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FieldOfViewCotangent", NULL },
+ { TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToScreen", NULL },
+ { TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA, 16, 16, TIFF_FLOAT, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MatrixWorldToCamera", NULL },
+ { TIFFTAG_COPYRIGHT, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Copyright", NULL },
+ /* end Pixar tags */
+ { TIFFTAG_RICHTIFFIPTC, -3, -3, TIFF_LONG, 0, TIFF_SETGET_C32_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "RichTIFFIPTC", NULL },
+ { TIFFTAG_PHOTOSHOP, -3, -3, TIFF_BYTE, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Photoshop", NULL },
+ { TIFFTAG_EXIFIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "EXIFIFDOffset", &exifFieldArray },
+ { TIFFTAG_ICCPROFILE, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ICC Profile", NULL },
+ { TIFFTAG_GPSIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_IFD8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GPSIFDOffset", NULL },
+ { TIFFTAG_FAXRECVPARAMS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvParams", NULL },
+ { TIFFTAG_FAXSUBADDRESS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxSubAddress", NULL },
+ { TIFFTAG_FAXRECVTIME, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_CUSTOM, TRUE, FALSE, "FaxRecvTime", NULL },
+ { TIFFTAG_FAXDCS, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_ASCII, FIELD_CUSTOM, TRUE, FALSE, "FaxDcs", NULL },
+ { TIFFTAG_STONITS, 1, 1, TIFF_DOUBLE, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "StoNits", NULL },
+ { TIFFTAG_INTEROPERABILITYIFD, 1, 1, TIFF_IFD8, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "InteroperabilityIFDOffset", NULL },
+ /* begin DNG tags */
+ { TIFFTAG_DNGVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGVersion", NULL },
+ { TIFFTAG_DNGBACKWARDVERSION, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DNGBackwardVersion", NULL },
+ { TIFFTAG_UNIQUECAMERAMODEL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "UniqueCameraModel", NULL },
+ { TIFFTAG_LOCALIZEDCAMERAMODEL, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "LocalizedCameraModel", NULL },
+ { TIFFTAG_CFAPLANECOLOR, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CFAPlaneColor", NULL },
+ { TIFFTAG_CFALAYOUT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CFALayout", NULL },
+ { TIFFTAG_LINEARIZATIONTABLE, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "LinearizationTable", NULL },
+ { TIFFTAG_BLACKLEVELREPEATDIM, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BlackLevelRepeatDim", NULL },
+ { TIFFTAG_BLACKLEVEL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevel", NULL },
+ { TIFFTAG_BLACKLEVELDELTAH, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaH", NULL },
+ { TIFFTAG_BLACKLEVELDELTAV, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "BlackLevelDeltaV", NULL },
+ { TIFFTAG_WHITELEVEL, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "WhiteLevel", NULL },
+ { TIFFTAG_DEFAULTSCALE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultScale", NULL },
+ { TIFFTAG_BESTQUALITYSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BestQualityScale", NULL },
+ { TIFFTAG_DEFAULTCROPORIGIN, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropOrigin", NULL },
+ { TIFFTAG_DEFAULTCROPSIZE, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "DefaultCropSize", NULL },
+ { TIFFTAG_COLORMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix1", NULL },
+ { TIFFTAG_COLORMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ColorMatrix2", NULL },
+ { TIFFTAG_CAMERACALIBRATION1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration1", NULL },
+ { TIFFTAG_CAMERACALIBRATION2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CameraCalibration2", NULL },
+ { TIFFTAG_REDUCTIONMATRIX1, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix1", NULL },
+ { TIFFTAG_REDUCTIONMATRIX2, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ReductionMatrix2", NULL },
+ { TIFFTAG_ANALOGBALANCE, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AnalogBalance", NULL },
+ { TIFFTAG_ASSHOTNEUTRAL, -1, -1, TIFF_RATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotNeutral", NULL },
+ { TIFFTAG_ASSHOTWHITEXY, 2, 2, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AsShotWhiteXY", NULL },
+ { TIFFTAG_BASELINEEXPOSURE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineExposure", NULL },
+ { TIFFTAG_BASELINENOISE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineNoise", NULL },
+ { TIFFTAG_BASELINESHARPNESS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BaselineSharpness", NULL },
+ { TIFFTAG_BAYERGREENSPLIT, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "BayerGreenSplit", NULL },
+ { TIFFTAG_LINEARRESPONSELIMIT, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LinearResponseLimit", NULL },
+ { TIFFTAG_CAMERASERIALNUMBER, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CameraSerialNumber", NULL },
+ { TIFFTAG_LENSINFO, 4, 4, TIFF_RATIONAL, 0, TIFF_SETGET_C0_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "LensInfo", NULL },
+ { TIFFTAG_CHROMABLURRADIUS, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ChromaBlurRadius", NULL },
+ { TIFFTAG_ANTIALIASSTRENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "AntiAliasStrength", NULL },
+ { TIFFTAG_SHADOWSCALE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ShadowScale", NULL },
+ { TIFFTAG_DNGPRIVATEDATA, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "DNGPrivateData", NULL },
+ { TIFFTAG_MAKERNOTESAFETY, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "MakerNoteSafety", NULL },
+ { TIFFTAG_CALIBRATIONILLUMINANT1, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant1", NULL },
+ { TIFFTAG_CALIBRATIONILLUMINANT2, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CalibrationIlluminant2", NULL },
+ { TIFFTAG_RAWDATAUNIQUEID, 16, 16, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "RawDataUniqueID", NULL },
+ { TIFFTAG_ORIGINALRAWFILENAME, -1, -1, TIFF_BYTE, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OriginalRawFileName", NULL },
+ { TIFFTAG_ORIGINALRAWFILEDATA, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "OriginalRawFileData", NULL },
+ { TIFFTAG_ACTIVEAREA, 4, 4, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ActiveArea", NULL },
+ { TIFFTAG_MASKEDAREAS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "MaskedAreas", NULL },
+ { TIFFTAG_ASSHOTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotICCProfile", NULL },
+ { TIFFTAG_ASSHOTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "AsShotPreProfileMatrix", NULL },
+ { TIFFTAG_CURRENTICCPROFILE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentICCProfile", NULL },
+ { TIFFTAG_CURRENTPREPROFILEMATRIX, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "CurrentPreProfileMatrix", NULL },
+ { TIFFTAG_PERSAMPLE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_UNDEFINED, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "PerSample", NULL},
+ /* end DNG tags */
+ /* begin TIFF/FX tags */
+ { TIFFTAG_INDEXED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "Indexed" },
+ { TIFFTAG_GLOBALPARAMETERSIFD, 1, 1, TIFF_IFD, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "GlobalParametersIFD", NULL },
+ { TIFFTAG_PROFILETYPE, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ProfileType", NULL },
+ { TIFFTAG_FAXPROFILE, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "FaxProfile", NULL },
+ { TIFFTAG_CODINGMETHODS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "CodingMethods", NULL },
+ { TIFFTAG_VERSIONYEAR, 4, 4, TIFF_BYTE, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "VersionYear", NULL },
+ { TIFFTAG_MODENUMBER, 1, 1, TIFF_BYTE, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ModeNumber", NULL },
+ { TIFFTAG_DECODE, -1, -1, TIFF_SRATIONAL, 0, TIFF_SETGET_C16_FLOAT, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "Decode", NULL },
+ { TIFFTAG_IMAGEBASECOLOR, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "ImageBaseColor", NULL },
+ { TIFFTAG_T82OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "T82Options", NULL },
+ { TIFFTAG_STRIPROWCOUNTS, -1, -1, TIFF_LONG, 0, TIFF_SETGET_C16_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 1, "StripRowCounts", NULL },
+ { TIFFTAG_IMAGELAYER, 2, 2, TIFF_LONG, 0, TIFF_SETGET_C0_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 0, 0, "ImageLayer", NULL },
+ /* end DNG tags */
+ /* begin pseudo tags */
+};
+
+static TIFFField
+exifFields[] = {
+ { EXIFTAG_EXPOSURETIME, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureTime", NULL },
+ { EXIFTAG_FNUMBER, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FNumber", NULL },
+ { EXIFTAG_EXPOSUREPROGRAM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureProgram", NULL },
+ { EXIFTAG_SPECTRALSENSITIVITY, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SpectralSensitivity", NULL },
+ { EXIFTAG_ISOSPEEDRATINGS, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "ISOSpeedRatings", NULL },
+ { EXIFTAG_OECF, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "OptoelectricConversionFactor", NULL },
+ { EXIFTAG_EXIFVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExifVersion", NULL },
+ { EXIFTAG_DATETIMEORIGINAL, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeOriginal", NULL },
+ { EXIFTAG_DATETIMEDIGITIZED, 20, 20, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DateTimeDigitized", NULL },
+ { EXIFTAG_COMPONENTSCONFIGURATION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ComponentsConfiguration", NULL },
+ { EXIFTAG_COMPRESSEDBITSPERPIXEL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CompressedBitsPerPixel", NULL },
+ { EXIFTAG_SHUTTERSPEEDVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ShutterSpeedValue", NULL },
+ { EXIFTAG_APERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ApertureValue", NULL },
+ { EXIFTAG_BRIGHTNESSVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "BrightnessValue", NULL },
+ { EXIFTAG_EXPOSUREBIASVALUE, 1, 1, TIFF_SRATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureBiasValue", NULL },
+ { EXIFTAG_MAXAPERTUREVALUE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MaxApertureValue", NULL },
+ { EXIFTAG_SUBJECTDISTANCE, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistance", NULL },
+ { EXIFTAG_METERINGMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "MeteringMode", NULL },
+ { EXIFTAG_LIGHTSOURCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "LightSource", NULL },
+ { EXIFTAG_FLASH, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Flash", NULL },
+ { EXIFTAG_FOCALLENGTH, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLength", NULL },
+ { EXIFTAG_SUBJECTAREA, -1, -1, TIFF_SHORT, 0, TIFF_SETGET_C16_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SubjectArea", NULL },
+ { EXIFTAG_MAKERNOTE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "MakerNote", NULL },
+ { EXIFTAG_USERCOMMENT, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "UserComment", NULL },
+ { EXIFTAG_SUBSECTIME, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTime", NULL },
+ { EXIFTAG_SUBSECTIMEORIGINAL, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeOriginal", NULL },
+ { EXIFTAG_SUBSECTIMEDIGITIZED, -1, -1, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubSecTimeDigitized", NULL },
+ { EXIFTAG_FLASHPIXVERSION, 4, 4, TIFF_UNDEFINED, 0, TIFF_SETGET_C0_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashpixVersion", NULL },
+ { EXIFTAG_COLORSPACE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ColorSpace", NULL },
+ { EXIFTAG_PIXELXDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelXDimension", NULL },
+ { EXIFTAG_PIXELYDIMENSION, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "PixelYDimension", NULL },
+ { EXIFTAG_RELATEDSOUNDFILE, 13, 13, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "RelatedSoundFile", NULL },
+ { EXIFTAG_FLASHENERGY, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FlashEnergy", NULL },
+ { EXIFTAG_SPATIALFREQUENCYRESPONSE, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "SpatialFrequencyResponse", NULL },
+ { EXIFTAG_FOCALPLANEXRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneXResolution", NULL },
+ { EXIFTAG_FOCALPLANEYRESOLUTION, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneYResolution", NULL },
+ { EXIFTAG_FOCALPLANERESOLUTIONUNIT, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalPlaneResolutionUnit", NULL },
+ { EXIFTAG_SUBJECTLOCATION, 2, 2, TIFF_SHORT, 0, TIFF_SETGET_C0_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectLocation", NULL },
+ { EXIFTAG_EXPOSUREINDEX, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureIndex", NULL },
+ { EXIFTAG_SENSINGMETHOD, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SensingMethod", NULL },
+ { EXIFTAG_FILESOURCE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FileSource", NULL },
+ { EXIFTAG_SCENETYPE, 1, 1, TIFF_UNDEFINED, 0, TIFF_SETGET_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneType", NULL },
+ { EXIFTAG_CFAPATTERN, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "CFAPattern", NULL },
+ { EXIFTAG_CUSTOMRENDERED, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "CustomRendered", NULL },
+ { EXIFTAG_EXPOSUREMODE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ExposureMode", NULL },
+ { EXIFTAG_WHITEBALANCE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "WhiteBalance", NULL },
+ { EXIFTAG_DIGITALZOOMRATIO, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "DigitalZoomRatio", NULL },
+ { EXIFTAG_FOCALLENGTHIN35MMFILM, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "FocalLengthIn35mmFilm", NULL },
+ { EXIFTAG_SCENECAPTURETYPE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SceneCaptureType", NULL },
+ { EXIFTAG_GAINCONTROL, 1, 1, TIFF_RATIONAL, 0, TIFF_SETGET_DOUBLE, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "GainControl", NULL },
+ { EXIFTAG_CONTRAST, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Contrast", NULL },
+ { EXIFTAG_SATURATION, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Saturation", NULL },
+ { EXIFTAG_SHARPNESS, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "Sharpness", NULL },
+ { EXIFTAG_DEVICESETTINGDESCRIPTION, -1, -1, TIFF_UNDEFINED, 0, TIFF_SETGET_C16_UINT8, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 1, "DeviceSettingDescription", NULL },
+ { EXIFTAG_SUBJECTDISTANCERANGE, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "SubjectDistanceRange", NULL },
+ { EXIFTAG_IMAGEUNIQUEID, 33, 33, TIFF_ASCII, 0, TIFF_SETGET_ASCII, TIFF_SETGET_UNDEFINED, FIELD_CUSTOM, 1, 0, "ImageUniqueID", NULL }
+};
+
+static TIFFFieldArray
+tiffFieldArray = { tfiatImage, 0, TIFFArrayCount(tiffFields), tiffFields };
+static TIFFFieldArray
+exifFieldArray = { tfiatExif, 0, TIFFArrayCount(exifFields), exifFields };
+
+/*
+ * We have our own local lfind() equivelent to avoid subtle differences
+ * in types passed to lfind() on different systems.
+ */
+
+static void *
+td_lfind(const void *key, const void *base, size_t *nmemb, size_t size,
+ int(*compar)(const void *, const void *))
+{
+ char *element, *end;
+
+ end = (char *)base + *nmemb * size;
+ for (element = (char *)base; element < end; element += size)
+ if (!compar(key, element)) /* key found */
+ return element;
+
+ return NULL;
+}
+
+const TIFFFieldArray*
+_TIFFGetFields(void)
+{
+ return(&tiffFieldArray);
+}
+
+const TIFFFieldArray*
+_TIFFGetExifFields(void)
+{
+ return(&exifFieldArray);
+}
+
+void
+_TIFFSetupFields(TIFF* tif, const TIFFFieldArray* fieldarray)
+{
+ if (tif->tif_fields && tif->tif_nfields > 0) {
+ uint32 i;
+
+ for (i = 0; i < tif->tif_nfields; i++) {
+ TIFFField *fld = tif->tif_fields[i];
+ if (fld->field_bit == FIELD_CUSTOM &&
+ strncmp("Tag ", fld->field_name, 4) == 0) {
+ _TIFFfree(fld->field_name);
+ _TIFFfree(fld);
+ }
+ }
+
+ _TIFFfree(tif->tif_fields);
+ tif->tif_fields = NULL;
+ tif->tif_nfields = 0;
+ }
+ if (!_TIFFMergeFields(tif, fieldarray->fields, fieldarray->count)) {
+ TIFFErrorExt(tif->tif_clientdata, "_TIFFSetupFields",
+ "Setting up field info failed");
+ }
+}
+
+static int
+tagCompare(const void* a, const void* b)
+{
+ const TIFFField* ta = *(const TIFFField**) a;
+ const TIFFField* tb = *(const TIFFField**) b;
+ /* NB: be careful of return values for 16-bit platforms */
+ if (ta->field_tag != tb->field_tag)
+ return (int)ta->field_tag - (int)tb->field_tag;
+ else
+ return (ta->field_type == TIFF_ANY) ?
+ 0 : ((int)tb->field_type - (int)ta->field_type);
+}
+
+static int
+tagNameCompare(const void* a, const void* b)
+{
+ const TIFFField* ta = *(const TIFFField**) a;
+ const TIFFField* tb = *(const TIFFField**) b;
+ int ret = strcmp(ta->field_name, tb->field_name);
+
+ if (ret)
+ return ret;
+ else
+ return (ta->field_type == TIFF_ANY) ?
+ 0 : ((int)tb->field_type - (int)ta->field_type);
+}
+
+int
+_TIFFMergeFields(TIFF* tif, const TIFFField info[], uint32 n)
+{
+ static const char module[] = "_TIFFMergeFields";
+ static const char reason[] = "for fields array";
+ /* TIFFField** tp; */
+ uint32 i;
+
+ tif->tif_foundfield = NULL;
+
+ if (tif->tif_fields && tif->tif_nfields > 0) {
+ tif->tif_fields = (TIFFField**)
+ _TIFFCheckRealloc(tif, tif->tif_fields,
+ (tif->tif_nfields + n),
+ sizeof(TIFFField *), reason);
+ } else {
+ tif->tif_fields = (TIFFField **)
+ _TIFFCheckMalloc(tif, n, sizeof(TIFFField *),
+ reason);
+ }
+ if (!tif->tif_fields) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Failed to allocate fields array");
+ return 0;
+ }
+
+ /* tp = tif->tif_fields + tif->tif_nfields; */
+ for (i = 0; i < n; i++) {
+ const TIFFField *fip =
+ TIFFFindField(tif, info[i].field_tag, TIFF_ANY);
+
+ /* only add definitions that aren't already present */
+ if (!fip) {
+ tif->tif_fields[tif->tif_nfields] = (TIFFField *) (info+i);
+ tif->tif_nfields++;
+ }
+ }
+
+ /* Sort the field info by tag number */
+ qsort(tif->tif_fields, tif->tif_nfields,
+ sizeof(TIFFField *), tagCompare);
+
+ return n;
+}
+
+void
+_TIFFPrintFieldInfo(TIFF* tif, FILE* fd)
+{
+ uint32 i;
+
+ fprintf(fd, "%s: \n", tif->tif_name);
+ for (i = 0; i < tif->tif_nfields; i++) {
+ const TIFFField* fip = tif->tif_fields[i];
+ fprintf(fd, "field[%2d] %5lu, %2d, %2d, %d, %2d, %5s, %5s, %s\n"
+ , (int)i
+ , (unsigned long) fip->field_tag
+ , fip->field_readcount, fip->field_writecount
+ , fip->field_type
+ , fip->field_bit
+ , fip->field_oktochange ? "TRUE" : "FALSE"
+ , fip->field_passcount ? "TRUE" : "FALSE"
+ , fip->field_name
+ );
+ }
+}
+
+/*
+ * Return size of TIFFDataType in bytes
+ */
+int
+TIFFDataWidth(TIFFDataType type)
+{
+ switch(type)
+ {
+ case 0: /* nothing */
+ case TIFF_BYTE:
+ case TIFF_ASCII:
+ case TIFF_SBYTE:
+ case TIFF_UNDEFINED:
+ return 1;
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ return 2;
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_FLOAT:
+ case TIFF_IFD:
+ return 4;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_DOUBLE:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_IFD8:
+ return 8;
+ default:
+ return 0; /* will return 0 for unknown types */
+ }
+}
+
+/*
+ * Return size of TIFFDataType in bytes.
+ *
+ * XXX: We need a separate function to determine the space needed
+ * to store the value. For TIFF_RATIONAL values TIFFDataWidth() returns 8,
+ * but we use 4-byte float to represent rationals.
+ */
+int
+_TIFFDataSize(TIFFDataType type)
+{
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_ASCII:
+ case TIFF_UNDEFINED:
+ return 1;
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ return 2;
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_FLOAT:
+ case TIFF_IFD:
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ return 4;
+ case TIFF_DOUBLE:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_IFD8:
+ return 8;
+ default:
+ return 0;
+ }
+}
+
+/* Sync from 3.8.2's modified*/
+#ifdef _WIN32_WCE
+void* wceex_bsearch(const void *key, const void *base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *));
+#define bsearch wceex_bsearch
+#endif
+
+const TIFFField*
+TIFFFindField(TIFF* tif, uint32 tag, TIFFDataType dt)
+{
+ TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
+ TIFFField* pkey = &key;
+ const TIFFField **ret;
+ if (tif->tif_foundfield && tif->tif_foundfield->field_tag == tag &&
+ (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
+ return tif->tif_foundfield;
+
+ /* If we are invoked with no field information, then just return. */
+ if (!tif->tif_fields)
+ return NULL;
+
+ /* NB: use sorted search (e.g. binary search) */
+
+ key.field_tag = tag;
+ key.field_type = dt;
+
+ ret = (const TIFFField **) bsearch(&pkey, tif->tif_fields,
+ tif->tif_nfields,
+ sizeof(TIFFField *), tagCompare);
+ return tif->tif_foundfield = (ret ? *ret : NULL);
+}
+
+const TIFFField*
+_TIFFFindFieldByName(TIFF* tif, const char *field_name, TIFFDataType dt)
+{
+ TIFFField key = {0, 0, 0, TIFF_NOTYPE, 0, 0, 0, 0, 0, 0, NULL, NULL};
+ TIFFField* pkey = &key;
+ const TIFFField **ret;
+ if (tif->tif_foundfield
+ && streq(tif->tif_foundfield->field_name, field_name)
+ && (dt == TIFF_ANY || dt == tif->tif_foundfield->field_type))
+ return (tif->tif_foundfield);
+
+ /* If we are invoked with no field information, then just return. */
+ if (!tif->tif_fields)
+ return NULL;
+
+ /* NB: use linear search since list is sorted by key#, not name */
+
+ key.field_name = (char *)field_name;
+ key.field_type = dt;
+
+#if 1
+ ret = (const TIFFField **)
+ td_lfind(&pkey, tif->tif_fields, &tif->tif_nfields,
+ sizeof(TIFFField *), tagNameCompare);
+#else
+ // from old svn version
+ /*ret = (const TIFFFieldInfo **) lfind(&pkey,
+ tif->tif_fieldinfo,
+ &tif->tif_nfields,
+ sizeof(TIFFFieldInfo *),
+ tagNameCompare);
+ */
+ /*modify by Sunliang.Liu 20090827 for some platform not support lfind*/
+ ret = NULL;
+#endif
+ return tif->tif_foundfield = (ret ? *ret : NULL);
+}
+
+const TIFFField*
+TIFFFieldWithTag(TIFF* tif, uint32 tag)
+{
+ const TIFFField* fip = TIFFFindField(tif, tag, TIFF_ANY);
+ if (!fip) {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithTag",
+ "Internal error, unknown tag 0x%x",
+ (unsigned int) tag);
+ }
+ return (fip);
+}
+
+const TIFFField*
+TIFFFieldWithName(TIFF* tif, const char *field_name)
+{
+ const TIFFField* fip =
+ _TIFFFindFieldByName(tif, field_name, TIFF_ANY);
+ if (!fip) {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFFieldWithName",
+ "Internal error, unknown tag %s", field_name);
+ }
+ return (fip);
+}
+
+uint32
+TIFFFieldTag(const TIFFField* fip)
+{
+ return fip->field_tag;
+}
+
+const char *
+TIFFFieldName(const TIFFField* fip)
+{
+ return fip->field_name;
+}
+
+TIFFDataType
+TIFFFieldDataType(const TIFFField* fip)
+{
+ return fip->field_type;
+}
+
+int
+TIFFFieldPassCount(const TIFFField* fip)
+{
+ return fip->field_passcount;
+}
+
+int
+TIFFFieldReadCount(const TIFFField* fip)
+{
+ return fip->field_readcount;
+}
+
+int
+TIFFFieldWriteCount(const TIFFField* fip)
+{
+ return fip->field_writecount;
+}
+
+const TIFFField*
+_TIFFFindOrRegisterField(TIFF *tif, uint32 tag, TIFFDataType dt)
+
+{
+ const TIFFField *fld;
+
+ fld = TIFFFindField(tif, tag, dt);
+ if (fld == NULL) {
+ fld = _TIFFCreateAnonField(tif, tag, dt);
+ if (!_TIFFMergeFields(tif, fld, 1))
+ return NULL;
+ }
+
+ return fld;
+}
+
+TIFFField*
+_TIFFCreateAnonField(TIFF *tif, uint32 tag, TIFFDataType field_type)
+{
+ TIFFField *fld;
+ (void) tif;
+
+ fld = (TIFFField *) _TIFFmalloc(sizeof (TIFFField));
+ if (fld == NULL)
+ return NULL;
+ _TIFFmemset(fld, 0, sizeof(TIFFField));
+
+ fld->field_tag = tag;
+ fld->field_readcount = TIFF_VARIABLE2;
+ fld->field_writecount = TIFF_VARIABLE2;
+ fld->field_type = field_type;
+ fld->reserved = 0;
+ switch (field_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ fld->set_field_type = TIFF_SETGET_C32_UINT8;
+ fld->get_field_type = TIFF_SETGET_C32_UINT8;
+ break;
+ case TIFF_ASCII:
+ fld->set_field_type = TIFF_SETGET_C32_ASCII;
+ fld->get_field_type = TIFF_SETGET_C32_ASCII;
+ break;
+ case TIFF_SHORT:
+ fld->set_field_type = TIFF_SETGET_C32_UINT16;
+ fld->get_field_type = TIFF_SETGET_C32_UINT16;
+ break;
+ case TIFF_LONG:
+ fld->set_field_type = TIFF_SETGET_C32_UINT32;
+ fld->get_field_type = TIFF_SETGET_C32_UINT32;
+ break;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ fld->set_field_type = TIFF_SETGET_C32_FLOAT;
+ fld->get_field_type = TIFF_SETGET_C32_FLOAT;
+ break;
+ case TIFF_SBYTE:
+ fld->set_field_type = TIFF_SETGET_C32_SINT8;
+ fld->get_field_type = TIFF_SETGET_C32_SINT8;
+ break;
+ case TIFF_SSHORT:
+ fld->set_field_type = TIFF_SETGET_C32_SINT16;
+ fld->get_field_type = TIFF_SETGET_C32_SINT16;
+ break;
+ case TIFF_SLONG:
+ fld->set_field_type = TIFF_SETGET_C32_SINT32;
+ fld->get_field_type = TIFF_SETGET_C32_SINT32;
+ break;
+ case TIFF_DOUBLE:
+ fld->set_field_type = TIFF_SETGET_C32_DOUBLE;
+ fld->get_field_type = TIFF_SETGET_C32_DOUBLE;
+ break;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ fld->set_field_type = TIFF_SETGET_C32_IFD8;
+ fld->get_field_type = TIFF_SETGET_C32_IFD8;
+ break;
+ case TIFF_LONG8:
+ fld->set_field_type = TIFF_SETGET_C32_UINT64;
+ fld->get_field_type = TIFF_SETGET_C32_UINT64;
+ break;
+ case TIFF_SLONG8:
+ fld->set_field_type = TIFF_SETGET_C32_SINT64;
+ fld->get_field_type = TIFF_SETGET_C32_SINT64;
+ break;
+ default:
+ fld->set_field_type = TIFF_SETGET_UNDEFINED;
+ fld->get_field_type = TIFF_SETGET_UNDEFINED;
+ break;
+ }
+ fld->field_bit = FIELD_CUSTOM;
+ fld->field_oktochange = TRUE;
+ fld->field_passcount = TRUE;
+ fld->field_name = (char *) _TIFFmalloc(32);
+ if (fld->field_name == NULL) {
+ _TIFFfree(fld);
+ return NULL;
+ }
+ fld->field_subfields = NULL;
+
+ /*
+ * note that this name is a special sign to TIFFClose() and
+ * _TIFFSetupFields() to free the field
+ */
+ sprintf(fld->field_name, "Tag %d", (int) tag);
+
+ return fld;
+}
+
+/****************************************************************************
+ * O B S O L E T E D I N T E R F A C E S
+ *
+ * Don't use this stuff in your applications, it may be removed in the future
+ * libtiff versions.
+ ****************************************************************************/
+
+static TIFFSetGetFieldType
+_TIFFSetGetType(TIFFDataType type, short count, unsigned char passcount)
+{
+ if (type == TIFF_ASCII && count == TIFF_VARIABLE && passcount == 0)
+ return TIFF_SETGET_ASCII;
+
+ else if (count == 1 && passcount == 0) {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ else if (count >= 1 && passcount == 0) {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_C0_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_C0_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_C0_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_C0_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_C0_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_C0_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_C0_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_C0_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_C0_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_C0_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_C0_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_C0_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ else if (count == TIFF_VARIABLE && passcount == 1) {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_C16_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_C16_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_C16_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_C16_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_C16_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_C16_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_C16_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_C16_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_C16_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_C16_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_C16_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_C16_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ else if (count == TIFF_VARIABLE2 && passcount == 1) {
+ switch (type)
+ {
+ case TIFF_BYTE:
+ case TIFF_UNDEFINED:
+ return TIFF_SETGET_C32_UINT8;
+ case TIFF_ASCII:
+ return TIFF_SETGET_C32_ASCII;
+ case TIFF_SHORT:
+ return TIFF_SETGET_C32_UINT16;
+ case TIFF_LONG:
+ return TIFF_SETGET_C32_UINT32;
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ return TIFF_SETGET_C32_FLOAT;
+ case TIFF_SBYTE:
+ return TIFF_SETGET_C32_SINT8;
+ case TIFF_SSHORT:
+ return TIFF_SETGET_C32_SINT16;
+ case TIFF_SLONG:
+ return TIFF_SETGET_C32_SINT32;
+ case TIFF_DOUBLE:
+ return TIFF_SETGET_C32_DOUBLE;
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ return TIFF_SETGET_C32_IFD8;
+ case TIFF_LONG8:
+ return TIFF_SETGET_C32_UINT64;
+ case TIFF_SLONG8:
+ return TIFF_SETGET_C32_SINT64;
+ default:
+ return TIFF_SETGET_UNDEFINED;
+ }
+ }
+
+ return TIFF_SETGET_UNDEFINED;
+}
+
+int
+TIFFMergeFieldInfo(TIFF* tif, const TIFFFieldInfo info[], uint32 n)
+{
+ static const char module[] = "TIFFMergeFieldInfo";
+ static const char reason[] = "for fields array";
+ TIFFField *tp;
+ size_t nfields;
+ uint32 i;
+
+ if (tif->tif_nfieldscompat > 0) {
+ tif->tif_fieldscompat = (TIFFFieldArray *)
+ _TIFFCheckRealloc(tif, tif->tif_fieldscompat,
+ tif->tif_nfieldscompat + 1,
+ sizeof(TIFFFieldArray), reason);
+ } else {
+ tif->tif_fieldscompat = (TIFFFieldArray *)
+ _TIFFCheckMalloc(tif, 1, sizeof(TIFFFieldArray),
+ reason);
+ }
+ if (!tif->tif_fieldscompat) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Failed to allocate fields array");
+ return -1;
+ }
+ nfields = tif->tif_nfieldscompat++;
+
+ tif->tif_fieldscompat[nfields].type = tfiatOther;
+ tif->tif_fieldscompat[nfields].allocated_size = n;
+ tif->tif_fieldscompat[nfields].count = n;
+ tif->tif_fieldscompat[nfields].fields =
+ (TIFFField *)_TIFFCheckMalloc(tif, n, sizeof(TIFFField),
+ reason);
+ if (!tif->tif_fieldscompat[nfields].fields) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Failed to allocate fields array");
+ return -1;
+ }
+
+ tp = tif->tif_fieldscompat[nfields].fields;
+ for (i = 0; i < n; i++) {
+ tp->field_tag = info[i].field_tag;
+ tp->field_readcount = info[i].field_readcount;
+ tp->field_writecount = info[i].field_writecount;
+ tp->field_type = info[i].field_type;
+ tp->reserved = 0;
+ tp->set_field_type =
+ _TIFFSetGetType(info[i].field_type,
+ info[i].field_readcount,
+ info[i].field_passcount);
+ tp->get_field_type =
+ _TIFFSetGetType(info[i].field_type,
+ info[i].field_readcount,
+ info[i].field_passcount);
+ tp->field_bit = info[i].field_bit;
+ tp->field_oktochange = info[i].field_oktochange;
+ tp->field_passcount = info[i].field_passcount;
+ tp->field_name = info[i].field_name;
+ tp->field_subfields = NULL;
+ tp++;
+ }
+
+ if (!_TIFFMergeFields(tif, tif->tif_fieldscompat[nfields].fields, n)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Setting up field info failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirread.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirread.c
new file mode 100644
index 0000000000..bd28d6926d
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirread.c
@@ -0,0 +1,5616 @@
+/* $Id: tif_dirread.c,v 1.178 2012-08-19 16:56:34 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Read Support Routines.
+ */
+
+/* Suggested pending improvements:
+ * - add a field 'ignore' to the TIFFDirEntry structure, to flag status,
+ * eliminating current use of the IGNORE value, and therefore eliminating
+ * current irrational behaviour on tags with tag id code 0
+ * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
+ * the pointer to the appropriate TIFFField structure early on in
+ * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
+ */
+
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+#define IGNORE 0 /* tag placeholder used below */
+#define FAILED_FII ((uint32) -1)
+
+#ifdef HAVE_IEEEFP
+# define TIFFCvtIEEEFloatToNative(tif, n, fp)
+# define TIFFCvtIEEEDoubleToNative(tif, n, dp)
+#else
+extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
+extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
+#endif
+
+enum TIFFReadDirEntryErr {
+ TIFFReadDirEntryErrOk = 0,
+ TIFFReadDirEntryErrCount = 1,
+ TIFFReadDirEntryErrType = 2,
+ TIFFReadDirEntryErrIo = 3,
+ TIFFReadDirEntryErrRange = 4,
+ TIFFReadDirEntryErrPsdif = 5,
+ TIFFReadDirEntryErrSizesan = 6,
+ TIFFReadDirEntryErrAlloc = 7,
+};
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
+#if 0
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
+#endif
+
+static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
+static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value);
+static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
+static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value);
+static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
+static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value);
+static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value);
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value);
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest);
+static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover);
+
+static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
+static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid);
+static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii);
+
+static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
+static void MissingRequired(TIFF*, const char*);
+static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
+static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
+static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff);
+static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
+static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp);
+static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
+static void ChopUpSingleUncompressedStrip(TIFF*);
+static uint64 TIFFReadUInt64(const uint8 *value);
+
+typedef union _UInt64Aligned_t
+{
+ double d;
+ uint64 l;
+ uint32 i[2];
+ uint16 s[4];
+ uint8 c[8];
+} UInt64Aligned_t;
+
+/*
+ Unaligned safe copy of a uint64 value from an octet array.
+*/
+static uint64 TIFFReadUInt64(const uint8 *value)
+{
+ UInt64Aligned_t result;
+
+ result.c[0]=value[0];
+ result.c[1]=value[1];
+ result.c[2]=value[2];
+ result.c[3]=value[3];
+ result.c[4]=value[4];
+ result.c[5]=value[5];
+ result.c[6]=value[6];
+ result.c[7]=value[7];
+
+ return result.l;
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count!=1)
+ return(TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ TIFFReadDirEntryCheckedByte(tif,direntry,value);
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_SBYTE:
+ {
+ int8 m;
+ TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeByteSbyte(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint8)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16 m;
+ TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeByteShort(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint8)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16 m;
+ TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeByteSshort(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint8)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32 m;
+ TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeByteLong(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint8)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32 m;
+ TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeByteSlong(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint8)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64 m;
+ err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ err=TIFFReadDirEntryCheckRangeByteLong8(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint8)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64 m;
+ err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ err=TIFFReadDirEntryCheckRangeByteSlong8(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint8)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count!=1)
+ return(TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8 m;
+ TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+ *value=(uint16)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8 m;
+ TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeShortSbyte(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint16)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ TIFFReadDirEntryCheckedShort(tif,direntry,value);
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_SSHORT:
+ {
+ int16 m;
+ TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeShortSshort(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint16)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32 m;
+ TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeShortLong(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint16)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32 m;
+ TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeShortSlong(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint16)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64 m;
+ err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ err=TIFFReadDirEntryCheckRangeShortLong8(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint16)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64 m;
+ err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ err=TIFFReadDirEntryCheckRangeShortSlong8(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint16)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count!=1)
+ return(TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8 m;
+ TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+ *value=(uint32)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8 m;
+ TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeLongSbyte(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint32)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16 m;
+ TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+ *value=(uint32)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16 m;
+ TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeLongSshort(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint32)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ TIFFReadDirEntryCheckedLong(tif,direntry,value);
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_SLONG:
+ {
+ int32 m;
+ TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeLongSlong(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint32)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64 m;
+ err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ err=TIFFReadDirEntryCheckRangeLongLong8(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint32)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64 m;
+ err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ err=TIFFReadDirEntryCheckRangeLongSlong8(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint32)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count!=1)
+ return(TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8 m;
+ TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8 m;
+ TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeLong8Sbyte(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16 m;
+ TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16 m;
+ TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeLong8Sshort(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32 m;
+ TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32 m;
+ TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+ err=TIFFReadDirEntryCheckRangeLong8Slong(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
+ return(err);
+ case TIFF_SLONG8:
+ {
+ int64 m;
+ err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ err=TIFFReadDirEntryCheckRangeLong8Slong8(m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count!=1)
+ return(TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8 m;
+ TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8 m;
+ TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16 m;
+ TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16 m;
+ TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32 m;
+ TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32 m;
+ TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64 m;
+ err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support conversion
+ * of 64-bit integers into floating point
+ * values.
+ */
+ *value = _TIFFUInt64ToFloat(m);
+#else
+ *value=(float)m;
+#endif
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64 m;
+ err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_RATIONAL:
+ {
+ double m;
+ err=TIFFReadDirEntryCheckedRational(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SRATIONAL:
+ {
+ double m;
+ err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_FLOAT:
+ TIFFReadDirEntryCheckedFloat(tif,direntry,value);
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_DOUBLE:
+ {
+ double m;
+ err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(float)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count!=1)
+ return(TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8 m;
+ TIFFReadDirEntryCheckedByte(tif,direntry,&m);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ {
+ int8 m;
+ TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SHORT:
+ {
+ uint16 m;
+ TIFFReadDirEntryCheckedShort(tif,direntry,&m);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ {
+ int16 m;
+ TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG:
+ {
+ uint32 m;
+ TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ {
+ int32 m;
+ TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ {
+ uint64 m;
+ err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support conversion
+ * of 64-bit integers into floating point
+ * values.
+ */
+ *value = _TIFFUInt64ToDouble(m);
+#else
+ *value = (double)m;
+#endif
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ {
+ int64 m;
+ err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_RATIONAL:
+ err=TIFFReadDirEntryCheckedRational(tif,direntry,value);
+ return(err);
+ case TIFF_SRATIONAL:
+ err=TIFFReadDirEntryCheckedSrational(tif,direntry,value);
+ return(err);
+ case TIFF_FLOAT:
+ {
+ float m;
+ TIFFReadDirEntryCheckedFloat(tif,direntry,&m);
+ *value=(double)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_DOUBLE:
+ err=TIFFReadDirEntryCheckedDouble(tif,direntry,value);
+ return(err);
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
+{
+ enum TIFFReadDirEntryErr err;
+ if (direntry->tdir_count!=1)
+ return(TIFFReadDirEntryErrCount);
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ case TIFF_IFD:
+ {
+ uint32 m;
+ TIFFReadDirEntryCheckedLong(tif,direntry,&m);
+ *value=(uint64)m;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
+ return(err);
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
+{
+ int typesize;
+ uint32 datasize;
+ void* data;
+ typesize=TIFFDataWidth(direntry->tdir_type);
+ if ((direntry->tdir_count==0)||(typesize==0))
+ {
+ *value=0;
+ return(TIFFReadDirEntryErrOk);
+ }
+ (void) desttypesize;
+
+ /*
+ * As a sanity check, make sure we have no more than a 2GB tag array
+ * in either the current data type or the dest data type. This also
+ * avoids problems with overflow of tmsize_t on 32bit systems.
+ */
+ if ((uint64)(2147483647/typesize)<direntry->tdir_count)
+ return(TIFFReadDirEntryErrSizesan);
+ if ((uint64)(2147483647/desttypesize)<direntry->tdir_count)
+ return(TIFFReadDirEntryErrSizesan);
+
+ *count=(uint32)direntry->tdir_count;
+ datasize=(*count)*typesize;
+ assert((tmsize_t)datasize>0);
+ data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
+ if (data==0)
+ return(TIFFReadDirEntryErrAlloc);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ if (datasize<=4)
+ _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
+ else
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32 offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ }
+ }
+ else
+ {
+ if (datasize<=8)
+ _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
+ else
+ {
+ enum TIFFReadDirEntryErr err;
+ uint64 offset = direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(&offset);
+ err=TIFFReadDirEntryData(tif,offset,(tmsize_t)datasize,data);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ }
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ uint8* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_ASCII:
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_ASCII:
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ *value=(uint8*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_SBYTE:
+ {
+ int8* m;
+ uint32 n;
+ m=(int8*)origdata;
+ for (n=0; n<count; n++)
+ {
+ err=TIFFReadDirEntryCheckRangeByteSbyte(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(uint8*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ }
+ data=(uint8*)_TIFFmalloc(count);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ uint8* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ err=TIFFReadDirEntryCheckRangeByteShort(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ uint8* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ err=TIFFReadDirEntryCheckRangeByteSshort(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ uint8* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err=TIFFReadDirEntryCheckRangeByteLong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ uint8* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ err=TIFFReadDirEntryCheckRangeByteSlong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ uint8* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err=TIFFReadDirEntryCheckRangeByteLong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ uint8* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ err=TIFFReadDirEntryCheckRangeByteSlong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint8)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ int8* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_UNDEFINED:
+ case TIFF_BYTE:
+ {
+ uint8* m;
+ uint32 n;
+ m=(uint8*)origdata;
+ for (n=0; n<count; n++)
+ {
+ err=TIFFReadDirEntryCheckRangeSbyteByte(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(int8*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SBYTE:
+ *value=(int8*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ data=(int8*)_TIFFmalloc(count);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ int8* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ err=TIFFReadDirEntryCheckRangeSbyteShort(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ int8* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ int8* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err=TIFFReadDirEntryCheckRangeSbyteLong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ int8* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ int8* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int8)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ int8* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int8)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ uint16* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ *value=(uint16*)origdata;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfShort(*value,count);
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_SSHORT:
+ {
+ int16* m;
+ uint32 n;
+ m=(int16*)origdata;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)m);
+ err=TIFFReadDirEntryCheckRangeShortSshort(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(uint16*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ }
+ data=(uint16*)_TIFFmalloc(count*2);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ uint16* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(uint16)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ uint16* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ err=TIFFReadDirEntryCheckRangeShortSbyte(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint16)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ uint16* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err=TIFFReadDirEntryCheckRangeShortLong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint16)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ uint16* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ err=TIFFReadDirEntryCheckRangeShortSlong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint16)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ uint16* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err=TIFFReadDirEntryCheckRangeShortLong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint16)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ uint16* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ err=TIFFReadDirEntryCheckRangeShortSlong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint16)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ int16* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_SHORT:
+ {
+ uint16* m;
+ uint32 n;
+ m=(uint16*)origdata;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(m);
+ err=TIFFReadDirEntryCheckRangeSshortShort(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(int16*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SSHORT:
+ *value=(int16*)origdata;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfShort((uint16*)(*value),count);
+ return(TIFFReadDirEntryErrOk);
+ }
+ data=(int16*)_TIFFmalloc(count*2);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ int16* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(int16)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ int16* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(int16)(*ma++);
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ int16* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ err=TIFFReadDirEntryCheckRangeSshortLong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int16)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ int16* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ err=TIFFReadDirEntryCheckRangeSshortSlong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int16)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ int16* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err=TIFFReadDirEntryCheckRangeSshortLong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int16)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ int16* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int16)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ uint32* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ *value=(uint32*)origdata;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(*value,count);
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_SLONG:
+ {
+ int32* m;
+ uint32 n;
+ m=(int32*)origdata;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)m);
+ err=TIFFReadDirEntryCheckRangeLongSlong(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(uint32*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ }
+ data=(uint32*)_TIFFmalloc(count*4);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ uint32* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(uint32)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ uint32* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ err=TIFFReadDirEntryCheckRangeLongSbyte(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint32)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ uint32* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++=(uint32)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ uint32* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ err=TIFFReadDirEntryCheckRangeLongSshort(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint32)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ uint32* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err=TIFFReadDirEntryCheckRangeLongLong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint32)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ uint32* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ err=TIFFReadDirEntryCheckRangeLongSlong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint32)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ int32* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ {
+ uint32* m;
+ uint32 n;
+ m=(uint32*)origdata;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)m);
+ err=TIFFReadDirEntryCheckRangeSlongLong(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(int32*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG:
+ *value=(int32*)origdata;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32*)(*value),count);
+ return(TIFFReadDirEntryErrOk);
+ }
+ data=(int32*)_TIFFmalloc(count*4);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ int32* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(int32)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ int32* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(int32)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ int32* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++=(int32)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ int32* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ *mb++=(int32)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ int32* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+ err=TIFFReadDirEntryCheckRangeSlongLong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int32)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ int32* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(int32)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ uint64* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG8:
+ *value=(uint64*)origdata;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8(*value,count);
+ return(TIFFReadDirEntryErrOk);
+ case TIFF_SLONG8:
+ {
+ int64* m;
+ uint32 n;
+ m=(int64*)origdata;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)m);
+ err=TIFFReadDirEntryCheckRangeLong8Slong8(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(uint64*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ }
+ data=(uint64*)_TIFFmalloc(count*8);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ uint64* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(uint64)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ uint64* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ err=TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint64)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ uint64* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++=(uint64)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ uint64* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint64)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ uint64* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++=(uint64)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ uint64* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ err=TIFFReadDirEntryCheckRangeLong8Slong(*ma);
+ if (err!=TIFFReadDirEntryErrOk)
+ break;
+ *mb++=(uint64)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ int64* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG8:
+ {
+ uint64* m;
+ uint32 n;
+ m=(uint64*)origdata;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(m);
+ err=TIFFReadDirEntryCheckRangeSlong8Long8(*m);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(origdata);
+ return(err);
+ }
+ m++;
+ }
+ *value=(int64*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ case TIFF_SLONG8:
+ *value=(int64*)origdata;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64*)(*value),count);
+ return(TIFFReadDirEntryErrOk);
+ }
+ data=(int64*)_TIFFmalloc(count*8);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ int64* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(int64)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ int64* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(int64)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ int64* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++=(int64)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ int64* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ *mb++=(int64)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ int64* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++=(int64)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ int64* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ *mb++=(int64)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ float* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ case TIFF_DOUBLE:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_FLOAT:
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32*)origdata,count);
+ TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata);
+ *value=(float*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ data=(float*)_TIFFmalloc(count*sizeof(float));
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ float* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(float)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ float* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(float)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ float* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++=(float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ float* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ *mb++=(float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ float* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++=(float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ float* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ *mb++=(float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ float* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support
+ * conversion of 64-bit integers into
+ * floating point values.
+ */
+ *mb++ = _TIFFUInt64ToFloat(*ma++);
+#else
+ *mb++ = (float)(*ma++);
+#endif
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ float* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ *mb++=(float)(*ma++);
+ }
+ }
+ break;
+ case TIFF_RATIONAL:
+ {
+ uint32* ma;
+ uint32 maa;
+ uint32 mab;
+ float* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa=*ma++;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab=*ma++;
+ if (mab==0)
+ *mb++=0.0;
+ else
+ *mb++=(float)maa/(float)mab;
+ }
+ }
+ break;
+ case TIFF_SRATIONAL:
+ {
+ uint32* ma;
+ int32 maa;
+ uint32 mab;
+ float* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa=*(int32*)ma;
+ ma++;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab=*ma++;
+ if (mab==0)
+ *mb++=0.0;
+ else
+ *mb++=(float)maa/(float)mab;
+ }
+ }
+ break;
+ case TIFF_DOUBLE:
+ {
+ double* ma;
+ float* mb;
+ uint32 n;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64*)origdata,count);
+ TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
+ ma=(double*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(float)(*ma++);
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ double* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ case TIFF_SBYTE:
+ case TIFF_SHORT:
+ case TIFF_SSHORT:
+ case TIFF_LONG:
+ case TIFF_SLONG:
+ case TIFF_LONG8:
+ case TIFF_SLONG8:
+ case TIFF_RATIONAL:
+ case TIFF_SRATIONAL:
+ case TIFF_FLOAT:
+ case TIFF_DOUBLE:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_DOUBLE:
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64*)origdata,count);
+ TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
+ *value=(double*)origdata;
+ return(TIFFReadDirEntryErrOk);
+ }
+ data=(double*)_TIFFmalloc(count*sizeof(double));
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_BYTE:
+ {
+ uint8* ma;
+ double* mb;
+ uint32 n;
+ ma=(uint8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(double)(*ma++);
+ }
+ break;
+ case TIFF_SBYTE:
+ {
+ int8* ma;
+ double* mb;
+ uint32 n;
+ ma=(int8*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(double)(*ma++);
+ }
+ break;
+ case TIFF_SHORT:
+ {
+ uint16* ma;
+ double* mb;
+ uint32 n;
+ ma=(uint16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(ma);
+ *mb++=(double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SSHORT:
+ {
+ int16* ma;
+ double* mb;
+ uint32 n;
+ ma=(int16*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ *mb++=(double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG:
+ {
+ uint32* ma;
+ double* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++=(double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_SLONG:
+ {
+ int32* ma;
+ double* mb;
+ uint32 n;
+ ma=(int32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ *mb++=(double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_LONG8:
+ {
+ uint64* ma;
+ double* mb;
+ uint32 n;
+ ma=(uint64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(ma);
+#if defined(__WIN32__) && (_MSC_VER < 1500)
+ /*
+ * XXX: MSVC 6.0 does not support
+ * conversion of 64-bit integers into
+ * floating point values.
+ */
+ *mb++ = _TIFFUInt64ToDouble(*ma++);
+#else
+ *mb++ = (double)(*ma++);
+#endif
+ }
+ }
+ break;
+ case TIFF_SLONG8:
+ {
+ int64* ma;
+ double* mb;
+ uint32 n;
+ ma=(int64*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ *mb++=(double)(*ma++);
+ }
+ }
+ break;
+ case TIFF_RATIONAL:
+ {
+ uint32* ma;
+ uint32 maa;
+ uint32 mab;
+ double* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa=*ma++;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab=*ma++;
+ if (mab==0)
+ *mb++=0.0;
+ else
+ *mb++=(double)maa/(double)mab;
+ }
+ }
+ break;
+ case TIFF_SRATIONAL:
+ {
+ uint32* ma;
+ int32 maa;
+ uint32 mab;
+ double* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ maa=*(int32*)ma;
+ ma++;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ mab=*ma++;
+ if (mab==0)
+ *mb++=0.0;
+ else
+ *mb++=(double)maa/(double)mab;
+ }
+ }
+ break;
+ case TIFF_FLOAT:
+ {
+ float* ma;
+ double* mb;
+ uint32 n;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32*)origdata,count);
+ TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata);
+ ma=(float*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ *mb++=(double)(*ma++);
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint32 count;
+ void* origdata;
+ uint64* data;
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ case TIFF_LONG8:
+ case TIFF_IFD:
+ case TIFF_IFD8:
+ break;
+ default:
+ return(TIFFReadDirEntryErrType);
+ }
+ err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
+ if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
+ {
+ *value=0;
+ return(err);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG8:
+ case TIFF_IFD8:
+ *value=(uint64*)origdata;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8(*value,count);
+ return(TIFFReadDirEntryErrOk);
+ }
+ data=(uint64*)_TIFFmalloc(count*8);
+ if (data==0)
+ {
+ _TIFFfree(origdata);
+ return(TIFFReadDirEntryErrAlloc);
+ }
+ switch (direntry->tdir_type)
+ {
+ case TIFF_LONG:
+ case TIFF_IFD:
+ {
+ uint32* ma;
+ uint64* mb;
+ uint32 n;
+ ma=(uint32*)origdata;
+ mb=data;
+ for (n=0; n<count; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(ma);
+ *mb++=(uint64)(*ma++);
+ }
+ }
+ break;
+ }
+ _TIFFfree(origdata);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ _TIFFfree(data);
+ return(err);
+ }
+ *value=data;
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
+{
+ enum TIFFReadDirEntryErr err;
+ uint16* m;
+ uint16* na;
+ uint16 nb;
+ if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
+ return(TIFFReadDirEntryErrCount);
+ err=TIFFReadDirEntryShortArray(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ na=m;
+ nb=tif->tif_dir.td_samplesperpixel;
+ *value=*na++;
+ nb--;
+ while (nb>0)
+ {
+ if (*na++!=*value)
+ {
+ err=TIFFReadDirEntryErrPsdif;
+ break;
+ }
+ nb--;
+ }
+ _TIFFfree(m);
+ return(err);
+}
+
+#if 0
+static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+ enum TIFFReadDirEntryErr err;
+ double* m;
+ double* na;
+ uint16 nb;
+ if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
+ return(TIFFReadDirEntryErrCount);
+ err=TIFFReadDirEntryDoubleArray(tif,direntry,&m);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ na=m;
+ nb=tif->tif_dir.td_samplesperpixel;
+ *value=*na++;
+ nb--;
+ while (nb>0)
+ {
+ if (*na++!=*value)
+ {
+ err=TIFFReadDirEntryErrPsdif;
+ break;
+ }
+ nb--;
+ }
+ _TIFFfree(m);
+ return(err);
+}
+#endif
+
+static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
+{
+ (void) tif;
+ *value=*(uint8*)(&direntry->tdir_offset);
+}
+
+static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value)
+{
+ (void) tif;
+ *value=*(int8*)(&direntry->tdir_offset);
+}
+
+static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
+{
+ *value = direntry->tdir_offset.toff_short;
+ /* *value=*(uint16*)(&direntry->tdir_offset); */
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(value);
+}
+
+static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value)
+{
+ *value=*(int16*)(&direntry->tdir_offset);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)value);
+}
+
+static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
+{
+ *value=*(uint32*)(&direntry->tdir_offset);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(value);
+}
+
+static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value)
+{
+ *value=*(int32*)(&direntry->tdir_offset);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)value);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
+{
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32 offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err=TIFFReadDirEntryData(tif,offset,8,value);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ }
+ else
+ *value = direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(value);
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value)
+{
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32 offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err=TIFFReadDirEntryData(tif,offset,8,value);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ }
+ else
+ *value=*(int64*)(&direntry->tdir_offset);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)value);
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+ UInt64Aligned_t m;
+
+ assert(sizeof(double)==8);
+ assert(sizeof(uint64)==8);
+ assert(sizeof(uint32)==4);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32 offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err=TIFFReadDirEntryData(tif,offset,8,m.i);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ }
+ else
+ m.l = direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(m.i,2);
+ if (m.i[0]==0)
+ *value=0.0;
+ else
+ *value=(double)m.i[0]/(double)m.i[1];
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+ UInt64Aligned_t m;
+ assert(sizeof(double)==8);
+ assert(sizeof(uint64)==8);
+ assert(sizeof(int32)==4);
+ assert(sizeof(uint32)==4);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32 offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err=TIFFReadDirEntryData(tif,offset,8,m.i);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ }
+ else
+ m.l=direntry->tdir_offset.toff_long8;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(m.i,2);
+ if ((int32)m.i[0]==0)
+ *value=0.0;
+ else
+ *value=(double)((int32)m.i[0])/(double)m.i[1];
+ return(TIFFReadDirEntryErrOk);
+}
+
+static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
+{
+ union
+ {
+ float f;
+ uint32 i;
+ } float_union;
+ assert(sizeof(float)==4);
+ assert(sizeof(uint32)==4);
+ assert(sizeof(float_union)==4);
+ float_union.i=*(uint32*)(&direntry->tdir_offset);
+ *value=float_union.f;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)value);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
+{
+ assert(sizeof(double)==8);
+ assert(sizeof(uint64)==8);
+ assert(sizeof(UInt64Aligned_t)==8);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32 offset = direntry->tdir_offset.toff_long;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err=TIFFReadDirEntryData(tif,offset,8,value);
+ if (err!=TIFFReadDirEntryErrOk)
+ return(err);
+ }
+ else
+ {
+ UInt64Aligned_t uint64_union;
+ uint64_union.l=direntry->tdir_offset.toff_long8;
+ *value=uint64_union.d;
+ }
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)value);
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value)
+{
+ if (value<0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value)
+{
+ if (value>0xFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value)
+{
+ if ((value<0)||(value>0xFF))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value)
+{
+ if (value>0xFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value)
+{
+ if ((value<0)||(value>0xFF))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value)
+{
+ if (value>0xFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value)
+{
+ if ((value<0)||(value>0xFF))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value)
+{
+ if (value>0x7F)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value)
+{
+ if (value>0x7F)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value)
+{
+ if ((value<-0x80)||(value>0x7F))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value)
+{
+ if (value>0x7F)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value)
+{
+ if ((value<-0x80)||(value>0x7F))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value)
+{
+ if (value>0x7F)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value)
+{
+ if ((value<-0x80)||(value>0x7F))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value)
+{
+ if (value<0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value)
+{
+ if (value<0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value)
+{
+ if (value>0xFFFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value)
+{
+ if ((value<0)||(value>0xFFFF))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value)
+{
+ if (value>0xFFFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value)
+{
+ if ((value<0)||(value>0xFFFF))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value)
+{
+ if (value>0x7FFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value)
+{
+ if (value>0x7FFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value)
+{
+ if ((value<-0x8000)||(value>0x7FFF))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value)
+{
+ if (value>0x7FFF)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value)
+{
+ if ((value<-0x8000)||(value>0x7FFF))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value)
+{
+ if (value<0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value)
+{
+ if (value<0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value)
+{
+ if (value<0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+/*
+ * Largest 32-bit unsigned integer value.
+ */
+#if defined(__WIN32__) && defined(_MSC_VER)
+# define TIFF_UINT32_MAX 0xFFFFFFFFI64
+#else
+# define TIFF_UINT32_MAX 0xFFFFFFFFLL
+#endif
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
+{
+ if (value > TIFF_UINT32_MAX)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
+{
+ if ((value<0) || (value > TIFF_UINT32_MAX))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+#undef TIFF_UINT32_MAX
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
+{
+ if (value > 0x7FFFFFFFUL)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongLong8(uint64 value)
+{
+ if (value > 0x7FFFFFFFUL)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlongSlong8(int64 value)
+{
+ if ((value < 0L-0x80000000L) || (value > 0x7FFFFFFFL))
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value)
+{
+ if (value < 0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Sshort(int16 value)
+{
+ if (value < 0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong(int32 value)
+{
+ if (value < 0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
+{
+ if (value < 0)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+/*
+ * Largest 64-bit signed integer value.
+ */
+#if defined(__WIN32__) && defined(_MSC_VER)
+# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFI64
+#else
+# define TIFF_INT64_MAX 0x7FFFFFFFFFFFFFFFLL
+#endif
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
+{
+ if (value > TIFF_INT64_MAX)
+ return(TIFFReadDirEntryErrRange);
+ else
+ return(TIFFReadDirEntryErrOk);
+}
+
+#undef TIFF_INT64_MAX
+
+static enum TIFFReadDirEntryErr
+TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
+{
+ assert(size>0);
+ if (!isMapped(tif)) {
+ if (!SeekOK(tif,offset))
+ return(TIFFReadDirEntryErrIo);
+ if (!ReadOK(tif,dest,size))
+ return(TIFFReadDirEntryErrIo);
+ } else {
+ size_t ma,mb;
+ ma=(size_t)offset;
+ mb=ma+size;
+ if (((uint64)ma!=offset)
+ || (mb < ma)
+ || (mb - ma != (size_t) size)
+ || (mb < (size_t)size)
+ || (mb > (size_t)tif->tif_size)
+ )
+ return(TIFFReadDirEntryErrIo);
+ _TIFFmemcpy(dest,tif->tif_base+ma,size);
+ }
+ return(TIFFReadDirEntryErrOk);
+}
+
+static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover)
+{
+ if (!recover) {
+ switch (err) {
+ case TIFFReadDirEntryErrCount:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Incorrect count for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrType:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Incompatible type for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrIo:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "IO error during reading of \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrRange:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Incorrect value for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrPsdif:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot handle different values per sample for \"%s\"",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrSizesan:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on size of \"%s\" value failed",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrAlloc:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Out of memory reading of \"%s\"",
+ tagname);
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ } else {
+ switch (err) {
+ case TIFFReadDirEntryErrCount:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Incorrect count for \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrType:
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Incompatible type for \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrIo:
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "IO error during reading of \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrRange:
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Incorrect value for \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrPsdif:
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Cannot handle different values per sample for \"%s\"; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrSizesan:
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Sanity check on size of \"%s\" value failed; tag ignored",
+ tagname);
+ break;
+ case TIFFReadDirEntryErrAlloc:
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Out of memory reading of \"%s\"; tag ignored",
+ tagname);
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ }
+}
+
+/*
+ * Read the next TIFF directory from a file and convert it to the internal
+ * format. We read directories sequentially.
+ */
+int
+TIFFReadDirectory(TIFF* tif)
+{
+ static const char module[] = "TIFFReadDirectory";
+ TIFFDirEntry* dir;
+ uint16 dircount;
+ TIFFDirEntry* dp;
+ uint16 di;
+ const TIFFField* fip;
+ uint32 fii=FAILED_FII;
+ toff_t nextdiroff;
+ tif->tif_diroff=tif->tif_nextdiroff;
+ if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
+ return 0; /* last offset or bad offset (IFD looping) */
+ (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
+ tif->tif_curdir++;
+ nextdiroff = tif->tif_nextdiroff;
+ dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff);
+ if (!dircount)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff);
+ return 0;
+ }
+ TIFFReadDirectoryCheckOrder(tif,dir,dircount);
+
+ /*
+ * Mark duplicates of any tag to be ignored (bugzilla 1994)
+ * to avoid certain pathological problems.
+ */
+ {
+ TIFFDirEntry* ma;
+ uint16 mb;
+ for (ma=dir, mb=0; mb<dircount; ma++, mb++)
+ {
+ TIFFDirEntry* na;
+ uint16 nb;
+ for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
+ {
+ if (ma->tdir_tag==na->tdir_tag)
+ na->tdir_tag=IGNORE;
+ }
+ }
+ }
+
+ tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
+ tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
+ /* free any old stuff and reinit */
+ TIFFFreeDirectory(tif);
+ TIFFDefaultDirectory(tif);
+ /*
+ * Electronic Arts writes gray-scale TIFF files
+ * without a PlanarConfiguration directory entry.
+ * Thus we setup a default value here, even though
+ * the TIFF spec says there is no default value.
+ */
+ TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
+ /*
+ * Setup default value and then make a pass over
+ * the fields to check type and tag information,
+ * and to extract info required to size data
+ * structures. A second pass is made afterwards
+ * to read in everthing not taken in the first pass.
+ * But we must process the Compression tag first
+ * in order to merge in codec-private tag definitions (otherwise
+ * we may get complaints about unknown tags). However, the
+ * Compression tag may be dependent on the SamplesPerPixel
+ * tag value because older TIFF specs permited Compression
+ * to be written as a SamplesPerPixel-count tag entry.
+ * Thus if we don't first figure out the correct SamplesPerPixel
+ * tag value then we may end up ignoring the Compression tag
+ * value because it has an incorrect count value (if the
+ * true value of SamplesPerPixel is not 1).
+ */
+ dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL);
+ if (dp)
+ {
+ if (!TIFFFetchNormalTag(tif,dp,0))
+ goto bad;
+ dp->tdir_tag=IGNORE;
+ }
+ dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
+ if (dp)
+ {
+ /*
+ * The 5.0 spec says the Compression tag has one value, while
+ * earlier specs say it has one value per sample. Because of
+ * this, we accept the tag if one value is supplied with either
+ * count.
+ */
+ uint16 value;
+ enum TIFFReadDirEntryErr err;
+ err=TIFFReadDirEntryShort(tif,dp,&value);
+ if (err==TIFFReadDirEntryErrCount)
+ err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0);
+ goto bad;
+ }
+ if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value))
+ goto bad;
+ dp->tdir_tag=IGNORE;
+ }
+ else
+ {
+ if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE))
+ goto bad;
+ }
+ /*
+ * First real pass over the directory.
+ */
+ for (di=0, dp=dir; di<dircount; di++, dp++)
+ {
+ if (dp->tdir_tag!=IGNORE)
+ {
+ TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+ if (fii == FAILED_FII)
+ {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Unknown field with tag %d (0x%x) encountered",
+ dp->tdir_tag,dp->tdir_tag);
+ /* the following knowingly leaks the
+ anonymous field structure */
+ if (!_TIFFMergeFields(tif,
+ _TIFFCreateAnonField(tif,
+ dp->tdir_tag,
+ (TIFFDataType) dp->tdir_type),
+ 1)) {
+ TIFFWarningExt(tif->tif_clientdata,
+ module,
+ "Registering anonymous field with tag %d (0x%x) failed",
+ dp->tdir_tag,
+ dp->tdir_tag);
+ dp->tdir_tag=IGNORE;
+ } else {
+ TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+ assert(fii != FAILED_FII);
+ }
+ }
+ }
+ if (dp->tdir_tag!=IGNORE)
+ {
+ fip=tif->tif_fields[fii];
+ if (fip->field_bit==FIELD_IGNORE)
+ dp->tdir_tag=IGNORE;
+ else
+ {
+ switch (dp->tdir_tag)
+ {
+ case TIFFTAG_STRIPOFFSETS:
+ case TIFFTAG_STRIPBYTECOUNTS:
+ case TIFFTAG_TILEOFFSETS:
+ case TIFFTAG_TILEBYTECOUNTS:
+ TIFFSetFieldBit(tif,fip->field_bit);
+ break;
+ case TIFFTAG_IMAGEWIDTH:
+ case TIFFTAG_IMAGELENGTH:
+ case TIFFTAG_IMAGEDEPTH:
+ case TIFFTAG_TILELENGTH:
+ case TIFFTAG_TILEWIDTH:
+ case TIFFTAG_TILEDEPTH:
+ case TIFFTAG_PLANARCONFIG:
+ case TIFFTAG_ROWSPERSTRIP:
+ case TIFFTAG_EXTRASAMPLES:
+ if (!TIFFFetchNormalTag(tif,dp,0))
+ goto bad;
+ dp->tdir_tag=IGNORE;
+ break;
+ }
+ }
+ }
+ }
+ /*
+ * XXX: OJPEG hack.
+ * If a) compression is OJPEG, b) planarconfig tag says it's separate,
+ * c) strip offsets/bytecounts tag are both present and
+ * d) both contain exactly one value, then we consistently find
+ * that the buggy implementation of the buggy compression scheme
+ * matches contig planarconfig best. So we 'fix-up' the tag here
+ */
+ if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
+ (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
+ {
+ if (!_TIFFFillStriles(tif))
+ goto bad;
+ dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
+ if ((dp!=0)&&(dp->tdir_count==1))
+ {
+ dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,
+ TIFFTAG_STRIPBYTECOUNTS);
+ if ((dp!=0)&&(dp->tdir_count==1))
+ {
+ tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG;
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Planarconfig tag value assumed incorrect, "
+ "assuming data is contig instead of chunky");
+ }
+ }
+ }
+ /*
+ * Allocate directory structure and setup defaults.
+ */
+ if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
+ {
+ MissingRequired(tif,"ImageLength");
+ goto bad;
+ }
+ /*
+ * Setup appropriate structures (by strip or by tile)
+ */
+ if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
+ tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
+ tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
+ tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
+ tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
+ tif->tif_flags &= ~TIFF_ISTILED;
+ } else {
+ tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
+ tif->tif_flags |= TIFF_ISTILED;
+ }
+ if (!tif->tif_dir.td_nstrips) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot handle zero number of %s",
+ isTiled(tif) ? "tiles" : "strips");
+ goto bad;
+ }
+ tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
+ if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
+ tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
+ if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
+ if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
+ (isTiled(tif)==0) &&
+ (tif->tif_dir.td_nstrips==1)) {
+ /*
+ * XXX: OJPEG hack.
+ * If a) compression is OJPEG, b) it's not a tiled TIFF,
+ * and c) the number of strips is 1,
+ * then we tolerate the absence of stripoffsets tag,
+ * because, presumably, all required data is in the
+ * JpegInterchangeFormat stream.
+ */
+ TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
+ } else {
+ MissingRequired(tif,
+ isTiled(tif) ? "TileOffsets" : "StripOffsets");
+ goto bad;
+ }
+ }
+ /*
+ * Second pass: extract other information.
+ */
+ for (di=0, dp=dir; di<dircount; di++, dp++)
+ {
+ switch (dp->tdir_tag)
+ {
+ case IGNORE:
+ break;
+ case TIFFTAG_MINSAMPLEVALUE:
+ case TIFFTAG_MAXSAMPLEVALUE:
+ case TIFFTAG_BITSPERSAMPLE:
+ case TIFFTAG_DATATYPE:
+ case TIFFTAG_SAMPLEFORMAT:
+ /*
+ * The MinSampleValue, MaxSampleValue, BitsPerSample
+ * DataType and SampleFormat tags are supposed to be
+ * written as one value/sample, but some vendors
+ * incorrectly write one value only -- so we accept
+ * that as well (yech). Other vendors write correct
+ * value for NumberOfSamples, but incorrect one for
+ * BitsPerSample and friends, and we will read this
+ * too.
+ */
+ {
+ uint16 value;
+ enum TIFFReadDirEntryErr err;
+ err=TIFFReadDirEntryShort(tif,dp,&value);
+ if (err==TIFFReadDirEntryErrCount)
+ err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+ goto bad;
+ }
+ if (!TIFFSetField(tif,dp->tdir_tag,value))
+ goto bad;
+ }
+ break;
+ case TIFFTAG_SMINSAMPLEVALUE:
+ case TIFFTAG_SMAXSAMPLEVALUE:
+ {
+
+ double *data;
+ enum TIFFReadDirEntryErr err;
+ uint32 saved_flags;
+ int m;
+ if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
+ err = TIFFReadDirEntryErrCount;
+ else
+ err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+ goto bad;
+ }
+ saved_flags = tif->tif_flags;
+ tif->tif_flags |= TIFF_PERSAMPLE;
+ m = TIFFSetField(tif,dp->tdir_tag,data);
+ tif->tif_flags = saved_flags;
+ _TIFFfree(data);
+ if (!m)
+ goto bad;
+ }
+ break;
+ case TIFFTAG_STRIPOFFSETS:
+ case TIFFTAG_TILEOFFSETS:
+#if defined(DEFER_STRILE_LOAD)
+ _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
+ dp, sizeof(TIFFDirEntry) );
+#else
+ if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripoffset))
+ goto bad;
+#endif
+ break;
+ case TIFFTAG_STRIPBYTECOUNTS:
+ case TIFFTAG_TILEBYTECOUNTS:
+#if defined(DEFER_STRILE_LOAD)
+ _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
+ dp, sizeof(TIFFDirEntry) );
+#else
+ if (!TIFFFetchStripThing(tif,dp,tif->tif_dir.td_nstrips,&tif->tif_dir.td_stripbytecount))
+ goto bad;
+#endif
+ break;
+ case TIFFTAG_COLORMAP:
+ case TIFFTAG_TRANSFERFUNCTION:
+ {
+ enum TIFFReadDirEntryErr err;
+ uint32 countpersample;
+ uint32 countrequired;
+ uint32 incrementpersample;
+ uint16* value=NULL;
+ countpersample=(1L<<tif->tif_dir.td_bitspersample);
+ if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
+ {
+ countrequired=countpersample;
+ incrementpersample=0;
+ }
+ else
+ {
+ countrequired=3*countpersample;
+ incrementpersample=countpersample;
+ }
+ if (dp->tdir_count!=(uint64)countrequired)
+ err=TIFFReadDirEntryErrCount;
+ else
+ err=TIFFReadDirEntryShortArray(tif,dp,&value);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ fip = TIFFFieldWithTag(tif,dp->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
+ }
+ else
+ {
+ TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
+ _TIFFfree(value);
+ }
+ }
+ break;
+/* BEGIN REV 4.0 COMPATIBILITY */
+ case TIFFTAG_OSUBFILETYPE:
+ {
+ uint16 valueo;
+ uint32 value;
+ if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
+ {
+ switch (valueo)
+ {
+ case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
+ case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
+ default: value=0; break;
+ }
+ if (value!=0)
+ TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
+ }
+ }
+ break;
+/* END REV 4.0 COMPATIBILITY */
+ default:
+ (void) TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ }
+ }
+ /*
+ * OJPEG hack:
+ * - If a) compression is OJPEG, and b) photometric tag is missing,
+ * then we consistently find that photometric should be YCbCr
+ * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
+ * then we consistently find that the buggy implementation of the
+ * buggy compression scheme matches photometric YCbCr instead.
+ * - If a) compression is OJPEG, and b) bitspersample tag is missing,
+ * then we consistently find bitspersample should be 8.
+ * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
+ * and c) photometric is RGB or YCbCr, then we consistently find
+ * samplesperpixel should be 3
+ * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
+ * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
+ * find samplesperpixel should be 3
+ */
+ if (tif->tif_dir.td_compression==COMPRESSION_OJPEG)
+ {
+ if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
+ {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Photometric tag is missing, assuming data is YCbCr");
+ if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
+ goto bad;
+ }
+ else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
+ {
+ tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR;
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Photometric tag value assumed incorrect, "
+ "assuming data is YCbCr instead of RGB");
+ }
+ if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "BitsPerSample tag is missing, assuming 8 bits per sample");
+ if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
+ goto bad;
+ }
+ if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
+ {
+ if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "SamplesPerPixel tag is missing, "
+ "assuming correct SamplesPerPixel value is 3");
+ if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
+ goto bad;
+ }
+ if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "SamplesPerPixel tag is missing, "
+ "applying correct SamplesPerPixel value of 3");
+ if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
+ goto bad;
+ }
+ else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE)
+ || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK))
+ {
+ /*
+ * SamplesPerPixel tag is missing, but is not required
+ * by spec. Assume correct SamplesPerPixel value of 1.
+ */
+ if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
+ goto bad;
+ }
+ }
+ }
+ /*
+ * Verify Palette image has a Colormap.
+ */
+ if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
+ !TIFFFieldSet(tif, FIELD_COLORMAP)) {
+ if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3)
+ tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
+ else if (tif->tif_dir.td_bitspersample>=8)
+ tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
+ else {
+ MissingRequired(tif, "Colormap");
+ goto bad;
+ }
+ }
+ /*
+ * OJPEG hack:
+ * We do no further messing with strip/tile offsets/bytecounts in OJPEG
+ * TIFFs
+ */
+ if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG)
+ {
+ /*
+ * Attempt to deal with a missing StripByteCounts tag.
+ */
+ if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
+ /*
+ * Some manufacturers violate the spec by not giving
+ * the size of the strips. In this case, assume there
+ * is one uncompressed strip of data.
+ */
+ if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
+ tif->tif_dir.td_nstrips > 1) ||
+ (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
+ tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) {
+ MissingRequired(tif, "StripByteCounts");
+ goto bad;
+ }
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "TIFF directory is missing required "
+ "\"StripByteCounts\" field, calculating from imagelength");
+ if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+ /*
+ * Assume we have wrong StripByteCount value (in case
+ * of single strip) in following cases:
+ * - it is equal to zero along with StripOffset;
+ * - it is larger than file itself (in case of uncompressed
+ * image);
+ * - it is smaller than the size of the bytes per row
+ * multiplied on the number of rows. The last case should
+ * not be checked in the case of writing new image,
+ * because we may do not know the exact strip size
+ * until the whole image will be written and directory
+ * dumped out.
+ */
+ #define BYTECOUNTLOOKSBAD \
+ ( (tif->tif_dir.td_stripbytecount[0] == 0 && tif->tif_dir.td_stripoffset[0] != 0) || \
+ (tif->tif_dir.td_compression == COMPRESSION_NONE && \
+ tif->tif_dir.td_stripbytecount[0] > TIFFGetFileSize(tif) - tif->tif_dir.td_stripoffset[0]) || \
+ (tif->tif_mode == O_RDONLY && \
+ tif->tif_dir.td_compression == COMPRESSION_NONE && \
+ tif->tif_dir.td_stripbytecount[0] < TIFFScanlineSize64(tif) * tif->tif_dir.td_imagelength) )
+
+ } else if (tif->tif_dir.td_nstrips == 1
+ && _TIFFFillStriles(tif)
+ && tif->tif_dir.td_stripoffset[0] != 0
+ && BYTECOUNTLOOKSBAD) {
+ /*
+ * XXX: Plexus (and others) sometimes give a value of
+ * zero for a tag when they don't know what the
+ * correct value is! Try and handle the simple case
+ * of estimating the size of a one strip image.
+ */
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength");
+ if(EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+
+#if !defined(DEFER_STRILE_LOAD)
+ } else if (tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
+ && tif->tif_dir.td_nstrips > 2
+ && tif->tif_dir.td_compression == COMPRESSION_NONE
+ && tif->tif_dir.td_stripbytecount[0] != tif->tif_dir.td_stripbytecount[1]
+ && tif->tif_dir.td_stripbytecount[0] != 0
+ && tif->tif_dir.td_stripbytecount[1] != 0 ) {
+ /*
+ * XXX: Some vendors fill StripByteCount array with
+ * absolutely wrong values (it can be equal to
+ * StripOffset array, for example). Catch this case
+ * here.
+ *
+ * We avoid this check if deferring strile loading
+ * as it would always force us to load the strip/tile
+ * information.
+ */
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
+ if (EstimateStripByteCounts(tif, dir, dircount) < 0)
+ goto bad;
+#endif /* !defined(DEFER_STRILE_LOAD) */
+ }
+ }
+ if (dir)
+ {
+ _TIFFfree(dir);
+ dir=NULL;
+ }
+ if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
+ {
+ if (tif->tif_dir.td_bitspersample>=16)
+ tif->tif_dir.td_maxsamplevalue=0xFFFF;
+ else
+ tif->tif_dir.td_maxsamplevalue = (uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
+ }
+ /*
+ * XXX: We can optimize checking for the strip bounds using the sorted
+ * bytecounts array. See also comments for TIFFAppendToStrip()
+ * function in tif_write.c.
+ */
+#if !defined(DEFER_STRILE_LOAD)
+ if (tif->tif_dir.td_nstrips > 1) {
+ uint32 strip;
+
+ tif->tif_dir.td_stripbytecountsorted = 1;
+ for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+ if (tif->tif_dir.td_stripoffset[strip - 1] >
+ tif->tif_dir.td_stripoffset[strip]) {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+#endif /* !defined(DEFER_STRILE_LOAD) */
+
+ /*
+ * An opportunity for compression mode dependent tag fixup
+ */
+ (*tif->tif_fixuptags)(tif);
+
+ /*
+ * Some manufacturers make life difficult by writing
+ * large amounts of uncompressed data as a single strip.
+ * This is contrary to the recommendations of the spec.
+ * The following makes an attempt at breaking such images
+ * into strips closer to the recommended 8k bytes. A
+ * side effect, however, is that the RowsPerStrip tag
+ * value may be changed.
+ */
+ if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
+ (tif->tif_dir.td_nstrips==1)&&
+ (tif->tif_dir.td_compression==COMPRESSION_NONE)&&
+ ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
+ {
+ if ( !_TIFFFillStriles(tif) || !tif->tif_dir.td_stripbytecount )
+ return 0;
+ ChopUpSingleUncompressedStrip(tif);
+ }
+
+ /*
+ * Clear the dirty directory flag.
+ */
+ tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+
+ /*
+ * Reinitialize i/o since we are starting on a new directory.
+ */
+ tif->tif_row = (uint32) -1;
+ tif->tif_curstrip = (uint32) -1;
+ tif->tif_col = (uint32) -1;
+ tif->tif_curtile = (uint32) -1;
+ tif->tif_tilesize = (tmsize_t) -1;
+
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ if (!tif->tif_scanlinesize) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot handle zero scanline size");
+ return (0);
+ }
+
+ if (isTiled(tif)) {
+ tif->tif_tilesize = TIFFTileSize(tif);
+ if (!tif->tif_tilesize) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot handle zero tile size");
+ return (0);
+ }
+ } else {
+ if (!TIFFStripSize(tif)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot handle zero strip size");
+ return (0);
+ }
+ }
+ return (1);
+bad:
+ if (dir)
+ _TIFFfree(dir);
+ return (0);
+}
+
+static void
+TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
+{
+ static const char module[] = "TIFFReadDirectoryCheckOrder";
+ uint16 m;
+ uint16 n;
+ TIFFDirEntry* o;
+ m=0;
+ for (n=0, o=dir; n<dircount; n++, o++)
+ {
+ if (o->tdir_tag<m)
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Invalid TIFF directory; tags are not sorted in ascending order");
+ break;
+ }
+ m=o->tdir_tag+1;
+ }
+}
+
+static TIFFDirEntry*
+TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
+{
+ TIFFDirEntry* m;
+ uint16 n;
+ (void) tif;
+ for (m=dir, n=0; n<dircount; m++, n++)
+ {
+ if (m->tdir_tag==tagid)
+ return(m);
+ }
+ return(0);
+}
+
+static void
+TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii)
+{
+ int32 ma,mb,mc;
+ ma=-1;
+ mc=(int32)tif->tif_nfields;
+ while (1)
+ {
+ if (ma+1==mc)
+ {
+ *fii = FAILED_FII;
+ return;
+ }
+ mb=(ma+mc)/2;
+ if (tif->tif_fields[mb]->field_tag==(uint32)tagid)
+ break;
+ if (tif->tif_fields[mb]->field_tag<(uint32)tagid)
+ ma=mb;
+ else
+ mc=mb;
+ }
+ while (1)
+ {
+ if (mb==0)
+ break;
+ if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid)
+ break;
+ mb--;
+ }
+ *fii=mb;
+}
+
+/*
+ * Read custom directory from the arbitarry offset.
+ * The code is very similar to TIFFReadDirectory().
+ */
+int
+TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
+ const TIFFFieldArray* infoarray)
+{
+ static const char module[] = "TIFFReadCustomDirectory";
+ TIFFDirEntry* dir;
+ uint16 dircount;
+ TIFFDirEntry* dp;
+ uint16 di;
+ const TIFFField* fip;
+ uint32 fii;
+ _TIFFSetupFields(tif, infoarray);
+ dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL);
+ if (!dircount)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff);
+ return 0;
+ }
+ TIFFFreeDirectory(tif);
+ _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
+ TIFFReadDirectoryCheckOrder(tif,dir,dircount);
+ for (di=0, dp=dir; di<dircount; di++, dp++)
+ {
+ TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+ if (fii == FAILED_FII)
+ {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Unknown field with tag %d (0x%x) encountered",
+ dp->tdir_tag, dp->tdir_tag);
+ if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif,
+ dp->tdir_tag,
+ (TIFFDataType) dp->tdir_type),
+ 1)) {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Registering anonymous field with tag %d (0x%x) failed",
+ dp->tdir_tag, dp->tdir_tag);
+ dp->tdir_tag=IGNORE;
+ } else {
+ TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+ assert( fii != FAILED_FII );
+ }
+ }
+ if (dp->tdir_tag!=IGNORE)
+ {
+ fip=tif->tif_fields[fii];
+ if (fip->field_bit==FIELD_IGNORE)
+ dp->tdir_tag=IGNORE;
+ else
+ {
+ /* check data type */
+ while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type))
+ {
+ fii++;
+ if ((fii==tif->tif_nfields)||
+ (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag))
+ {
+ fii=0xFFFF;
+ break;
+ }
+ fip=tif->tif_fields[fii];
+ }
+ if (fii==0xFFFF)
+ {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Wrong data type %d for \"%s\"; tag ignored",
+ dp->tdir_type,fip->field_name);
+ dp->tdir_tag=IGNORE;
+ }
+ else
+ {
+ /* check count if known in advance */
+ if ((fip->field_readcount!=TIFF_VARIABLE)&&
+ (fip->field_readcount!=TIFF_VARIABLE2))
+ {
+ uint32 expected;
+ if (fip->field_readcount==TIFF_SPP)
+ expected=(uint32)tif->tif_dir.td_samplesperpixel;
+ else
+ expected=(uint32)fip->field_readcount;
+ if (!CheckDirCount(tif,dp,expected))
+ dp->tdir_tag=IGNORE;
+ }
+ }
+ }
+ switch (dp->tdir_tag)
+ {
+ case IGNORE:
+ break;
+ case EXIFTAG_SUBJECTDISTANCE:
+ (void) TIFFFetchSubjectDistance(tif,dp);
+ break;
+ default:
+ (void) TIFFFetchNormalTag(tif, dp, TRUE);
+ break;
+ }
+ }
+ }
+ if (dir)
+ _TIFFfree(dir);
+ return 1;
+}
+
+/*
+ * EXIF is important special case of custom IFD, so we have a special
+ * function to read it.
+ */
+int
+TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
+{
+ const TIFFFieldArray* exifFieldArray;
+ exifFieldArray = _TIFFGetExifFields();
+ return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);
+}
+
+static int
+EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
+{
+ static const char module[] = "EstimateStripByteCounts";
+
+ TIFFDirEntry *dp;
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 strip;
+
+ _TIFFFillStriles( tif );
+
+ if (td->td_stripbytecount)
+ _TIFFfree(td->td_stripbytecount);
+ td->td_stripbytecount = (uint64*)
+ _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
+ "for \"StripByteCounts\" array");
+ if( td->td_stripbytecount == NULL )
+ return -1;
+
+ if (td->td_compression != COMPRESSION_NONE) {
+ uint64 space;
+ uint64 filesize;
+ uint16 n;
+ filesize = TIFFGetFileSize(tif);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ space=sizeof(TIFFHeaderClassic)+2+dircount*12+4;
+ else
+ space=sizeof(TIFFHeaderBig)+8+dircount*20+8;
+ /* calculate amount of space used by indirect values */
+ for (dp = dir, n = dircount; n > 0; n--, dp++)
+ {
+ uint32 typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
+ uint64 datasize;
+ typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
+ if (typewidth == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Cannot determine size of unknown tag type %d",
+ dp->tdir_type);
+ return -1;
+ }
+ datasize=(uint64)typewidth*dp->tdir_count;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ if (datasize<=4)
+ datasize=0;
+ }
+ else
+ {
+ if (datasize<=8)
+ datasize=0;
+ }
+ space+=datasize;
+ }
+ space = filesize - space;
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ space /= td->td_samplesperpixel;
+ for (strip = 0; strip < td->td_nstrips; strip++)
+ td->td_stripbytecount[strip] = space;
+ /*
+ * This gross hack handles the case were the offset to
+ * the last strip is past the place where we think the strip
+ * should begin. Since a strip of data must be contiguous,
+ * it's safe to assume that we've overestimated the amount
+ * of data in the strip and trim this number back accordingly.
+ */
+ strip--;
+ if (td->td_stripoffset[strip]+td->td_stripbytecount[strip] > filesize)
+ td->td_stripbytecount[strip] = filesize - td->td_stripoffset[strip];
+ } else if (isTiled(tif)) {
+ uint64 bytespertile = TIFFTileSize64(tif);
+
+ for (strip = 0; strip < td->td_nstrips; strip++)
+ td->td_stripbytecount[strip] = bytespertile;
+ } else {
+ uint64 rowbytes = TIFFScanlineSize64(tif);
+ uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
+ for (strip = 0; strip < td->td_nstrips; strip++)
+ td->td_stripbytecount[strip] = rowbytes * rowsperstrip;
+ }
+ TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
+ if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
+ td->td_rowsperstrip = td->td_imagelength;
+ return 1;
+}
+
+static void
+MissingRequired(TIFF* tif, const char* tagname)
+{
+ static const char module[] = "MissingRequired";
+
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "TIFF directory is missing required \"%s\" field",
+ tagname);
+}
+
+/*
+ * Check the directory offset against the list of already seen directory
+ * offsets. This is a trick to prevent IFD looping. The one can create TIFF
+ * file with looped directory pointers. We will maintain a list of already
+ * seen directories and check every IFD offset against that list.
+ */
+static int
+TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
+{
+ uint16 n;
+
+ if (diroff == 0) /* no more directories */
+ return 0;
+
+ for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
+ if (tif->tif_dirlist[n] == diroff)
+ return 0;
+ }
+
+ tif->tif_dirnumber++;
+
+ if (tif->tif_dirnumber > tif->tif_dirlistsize) {
+ uint64* new_dirlist;
+
+ /*
+ * XXX: Reduce memory allocation granularity of the dirlist
+ * array.
+ */
+ new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist,
+ tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
+ if (!new_dirlist)
+ return 0;
+ tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
+ tif->tif_dirlist = new_dirlist;
+ }
+
+ tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
+
+ return 1;
+}
+
+/*
+ * Check the count field of a directory entry against a known value. The
+ * caller is expected to skip/ignore the tag if there is a mismatch.
+ */
+static int
+CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
+{
+ if ((uint64)count > dir->tdir_count) {
+ const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+ "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored",
+ fip ? fip->field_name : "unknown tagname",
+ dir->tdir_count, count);
+ return (0);
+ } else if ((uint64)count < dir->tdir_count) {
+ const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+ "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed",
+ fip ? fip->field_name : "unknown tagname",
+ dir->tdir_count, count);
+ dir->tdir_count = count;
+ return (1);
+ }
+ return (1);
+}
+
+/*
+ * Read IFD structure from the specified offset. If the pointer to
+ * nextdiroff variable has been specified, read it too. Function returns a
+ * number of fields in the directory or 0 if failed.
+ */
+static uint16
+TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
+ uint64 *nextdiroff)
+{
+ static const char module[] = "TIFFFetchDirectory";
+
+ void* origdir;
+ uint16 dircount16;
+ uint32 dirsize;
+ TIFFDirEntry* dir;
+ uint8* ma;
+ TIFFDirEntry* mb;
+ uint16 n;
+
+ assert(pdir);
+
+ tif->tif_diroff = diroff;
+ if (nextdiroff)
+ *nextdiroff = 0;
+ if (!isMapped(tif)) {
+ if (!SeekOK(tif, tif->tif_diroff)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ if (!ReadOK(tif, &dircount16, sizeof (uint16))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount16);
+ if (dircount16>4096)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on directory count failed, this is probably not a valid IFD offset");
+ return 0;
+ }
+ dirsize = 12;
+ } else {
+ uint64 dircount64;
+ if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64>4096)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on directory count failed, this is probably not a valid IFD offset");
+ return 0;
+ }
+ dircount16 = (uint16)dircount64;
+ dirsize = 20;
+ }
+ origdir = _TIFFCheckMalloc(tif, dircount16,
+ dirsize, "to read TIFF directory");
+ if (origdir == NULL)
+ return 0;
+ if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%.100s: Can not read TIFF directory",
+ tif->tif_name);
+ _TIFFfree(origdir);
+ return 0;
+ }
+ /*
+ * Read offset to next directory for sequential scans if
+ * needed.
+ */
+ if (nextdiroff)
+ {
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 nextdiroff32;
+ if (!ReadOK(tif, &nextdiroff32, sizeof(uint32)))
+ nextdiroff32 = 0;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&nextdiroff32);
+ *nextdiroff=nextdiroff32;
+ } else {
+ if (!ReadOK(tif, nextdiroff, sizeof(uint64)))
+ *nextdiroff = 0;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(nextdiroff);
+ }
+ }
+ } else {
+ tmsize_t m;
+ tmsize_t off = (tmsize_t) tif->tif_diroff;
+ if ((uint64)off!=tif->tif_diroff)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count");
+ return(0);
+ }
+
+ /*
+ * Check for integer overflow when validating the dir_off,
+ * otherwise a very high offset may cause an OOB read and
+ * crash the client. Make two comparisons instead of
+ *
+ * off + sizeof(uint16) > tif->tif_size
+ *
+ * to avoid overflow.
+ */
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ m=off+sizeof(uint16);
+ if ((m<off)||(m<(tmsize_t)sizeof(uint16))||(m>tif->tif_size)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Can not read TIFF directory count");
+ return 0;
+ } else {
+ _TIFFmemcpy(&dircount16, tif->tif_base + off,
+ sizeof(uint16));
+ }
+ off += sizeof (uint16);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount16);
+ if (dircount16>4096)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on directory count failed, this is probably not a valid IFD offset");
+ return 0;
+ }
+ dirsize = 12;
+ }
+ else
+ {
+ tmsize_t m;
+ uint64 dircount64;
+ m=off+sizeof(uint64);
+ if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Can not read TIFF directory count");
+ return 0;
+ } else {
+ _TIFFmemcpy(&dircount64, tif->tif_base + off,
+ sizeof(uint64));
+ }
+ off += sizeof (uint64);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64>4096)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on directory count failed, this is probably not a valid IFD offset");
+ return 0;
+ }
+ dircount16 = (uint16)dircount64;
+ dirsize = 20;
+ }
+ if (dircount16 == 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on directory count failed, zero tag directories not supported");
+ return 0;
+ }
+ origdir = _TIFFCheckMalloc(tif, dircount16,
+ dirsize,
+ "to read TIFF directory");
+ if (origdir == NULL)
+ return 0;
+ m=off+dircount16*dirsize;
+ if ((m<off)||(m<(tmsize_t)(dircount16*dirsize))||(m>tif->tif_size)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Can not read TIFF directory");
+ _TIFFfree(origdir);
+ return 0;
+ } else {
+ _TIFFmemcpy(origdir, tif->tif_base + off,
+ dircount16 * dirsize);
+ }
+ if (nextdiroff) {
+ off += dircount16 * dirsize;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 nextdiroff32;
+ m=off+sizeof(uint32);
+ if ((m<off)||(m<(tmsize_t)sizeof(uint32))||(m>tif->tif_size))
+ nextdiroff32 = 0;
+ else
+ _TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
+ sizeof (uint32));
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&nextdiroff32);
+ *nextdiroff = nextdiroff32;
+ }
+ else
+ {
+ m=off+sizeof(uint64);
+ if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size))
+ *nextdiroff = 0;
+ else
+ _TIFFmemcpy(nextdiroff, tif->tif_base + off,
+ sizeof (uint64));
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(nextdiroff);
+ }
+ }
+ }
+ dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16,
+ sizeof(TIFFDirEntry),
+ "to read TIFF directory");
+ if (dir==0)
+ {
+ _TIFFfree(origdir);
+ return 0;
+ }
+ ma=(uint8*)origdir;
+ mb=dir;
+ for (n=0; n<dircount16; n++)
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ mb->tdir_tag=*(uint16*)ma;
+ ma+=sizeof(uint16);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)ma);
+ mb->tdir_type=*(uint16*)ma;
+ ma+=sizeof(uint16);
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)ma);
+ mb->tdir_count=(uint64)(*(uint32*)ma);
+ ma+=sizeof(uint32);
+ *(uint32*)(&mb->tdir_offset)=*(uint32*)ma;
+ ma+=sizeof(uint32);
+ }
+ else
+ {
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)ma);
+ mb->tdir_count=TIFFReadUInt64(ma);
+ ma+=sizeof(uint64);
+ mb->tdir_offset.toff_long8=TIFFReadUInt64(ma);
+ ma+=sizeof(uint64);
+ }
+ mb++;
+ }
+ _TIFFfree(origdir);
+ *pdir = dir;
+ return dircount16;
+}
+
+/*
+ * Fetch a tag that is not handled by special case code.
+ */
+static int
+TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
+{
+ static const char module[] = "TIFFFetchNormalTag";
+ enum TIFFReadDirEntryErr err;
+ uint32 fii;
+ const TIFFField* fip = NULL;
+ TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
+ if( fii == FAILED_FII )
+ {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag",
+ "No definition found for tag %d",
+ dp->tdir_tag);
+ return 0;
+ }
+ fip=tif->tif_fields[fii];
+ assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */
+ assert(fip->set_field_type!=TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */
+ err=TIFFReadDirEntryErrOk;
+ switch (fip->set_field_type)
+ {
+ case TIFF_SETGET_UNDEFINED:
+ break;
+ case TIFF_SETGET_ASCII:
+ {
+ uint8* data;
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryByteArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ uint8* ma;
+ uint32 mb;
+ int n;
+ ma=data;
+ mb=0;
+ while (mb<(uint32)dp->tdir_count)
+ {
+ if (*ma==0)
+ break;
+ ma++;
+ mb++;
+ }
+ if (mb+1<(uint32)dp->tdir_count)
+ TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name);
+ else if (mb+1>(uint32)dp->tdir_count)
+ {
+ uint8* o;
+ TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name);
+ if ((uint32)dp->tdir_count+1!=dp->tdir_count+1)
+ o=NULL;
+ else
+ o=_TIFFmalloc((uint32)dp->tdir_count+1);
+ if (o==NULL)
+ {
+ if (data!=NULL)
+ _TIFFfree(data);
+ return(0);
+ }
+ _TIFFmemcpy(o,data,(uint32)dp->tdir_count);
+ o[(uint32)dp->tdir_count]=0;
+ if (data!=0)
+ _TIFFfree(data);
+ data=o;
+ }
+ n=TIFFSetField(tif,dp->tdir_tag,data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!n)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_UINT8:
+ {
+ uint8 data=0;
+ assert(fip->field_readcount==1);
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryByte(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif,dp->tdir_tag,data))
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_UINT16:
+ {
+ uint16 data;
+ assert(fip->field_readcount==1);
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryShort(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif,dp->tdir_tag,data))
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_UINT32:
+ {
+ uint32 data;
+ assert(fip->field_readcount==1);
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryLong(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif,dp->tdir_tag,data))
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_UINT64:
+ {
+ uint64 data;
+ assert(fip->field_readcount==1);
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryLong8(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif,dp->tdir_tag,data))
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_FLOAT:
+ {
+ float data;
+ assert(fip->field_readcount==1);
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryFloat(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif,dp->tdir_tag,data))
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_DOUBLE:
+ {
+ double data;
+ assert(fip->field_readcount==1);
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryDouble(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif,dp->tdir_tag,data))
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_IFD8:
+ {
+ uint64 data;
+ assert(fip->field_readcount==1);
+ assert(fip->field_passcount==0);
+ err=TIFFReadDirEntryIfd8(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ if (!TIFFSetField(tif,dp->tdir_tag,data))
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_UINT16_PAIR:
+ {
+ uint16* data;
+ assert(fip->field_readcount==2);
+ assert(fip->field_passcount==0);
+ if (dp->tdir_count!=2) {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "incorrect count for field \"%s\", expected 2, got %d",
+ fip->field_name,(int)dp->tdir_count);
+ return(0);
+ }
+ err=TIFFReadDirEntryShortArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]);
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C0_UINT8:
+ {
+ uint8* data;
+ assert(fip->field_readcount>=1);
+ assert(fip->field_passcount==0);
+ if (dp->tdir_count!=(uint64)fip->field_readcount) {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "incorrect count for field \"%s\", expected %d, got %d",
+ fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count);
+ return 0;
+ }
+ else
+ {
+ err=TIFFReadDirEntryByteArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C0_UINT16:
+ {
+ uint16* data;
+ assert(fip->field_readcount>=1);
+ assert(fip->field_passcount==0);
+ if (dp->tdir_count!=(uint64)fip->field_readcount)
+ /* corrupt file */;
+ else
+ {
+ err=TIFFReadDirEntryShortArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C0_UINT32:
+ {
+ uint32* data;
+ assert(fip->field_readcount>=1);
+ assert(fip->field_passcount==0);
+ if (dp->tdir_count!=(uint64)fip->field_readcount)
+ /* corrupt file */;
+ else
+ {
+ err=TIFFReadDirEntryLongArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C0_FLOAT:
+ {
+ float* data;
+ assert(fip->field_readcount>=1);
+ assert(fip->field_passcount==0);
+ if (dp->tdir_count!=(uint64)fip->field_readcount)
+ /* corrupt file */;
+ else
+ {
+ err=TIFFReadDirEntryFloatArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_ASCII:
+ {
+ uint8* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryByteArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT8:
+ {
+ uint8* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryByteArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT16:
+ {
+ uint16* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryShortArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT32:
+ {
+ uint32* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryLongArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_UINT64:
+ {
+ uint64* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryLong8Array(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_FLOAT:
+ {
+ float* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryFloatArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_DOUBLE:
+ {
+ double* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C16_IFD8:
+ {
+ uint64* data;
+ assert(fip->field_readcount==TIFF_VARIABLE);
+ assert(fip->field_passcount==1);
+ if (dp->tdir_count>0xFFFF)
+ err=TIFFReadDirEntryErrCount;
+ else
+ {
+ err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_ASCII:
+ {
+ uint8* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryByteArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT8:
+ {
+ uint8* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryByteArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT8:
+ {
+ int8* data = NULL;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntrySbyteArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT16:
+ {
+ uint16* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryShortArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT16:
+ {
+ int16* data = NULL;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntrySshortArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT32:
+ {
+ uint32* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryLongArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT32:
+ {
+ int32* data = NULL;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntrySlongArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_UINT64:
+ {
+ uint64* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryLong8Array(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_SINT64:
+ {
+ int64* data = NULL;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntrySlong8Array(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_FLOAT:
+ {
+ float* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryFloatArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_DOUBLE:
+ {
+ double* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ case TIFF_SETGET_C32_IFD8:
+ {
+ uint64* data;
+ assert(fip->field_readcount==TIFF_VARIABLE2);
+ assert(fip->field_passcount==1);
+ err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ int m;
+ m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
+ if (data!=0)
+ _TIFFfree(data);
+ if (!m)
+ return(0);
+ }
+ }
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",recover);
+ return(0);
+ }
+ return(1);
+}
+
+/*
+ * Fetch a set of offsets or lengths.
+ * While this routine says "strips", in fact it's also used for tiles.
+ */
+static int
+TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
+{
+ static const char module[] = "TIFFFetchStripThing";
+ enum TIFFReadDirEntryErr err;
+ uint64* data;
+ err=TIFFReadDirEntryLong8Array(tif,dir,&data);
+ if (err!=TIFFReadDirEntryErrOk)
+ {
+ const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag);
+ TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
+ return(0);
+ }
+ if (dir->tdir_count!=(uint64)nstrips)
+ {
+ uint64* resizeddata;
+ resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
+ if (resizeddata==0) {
+ _TIFFfree(data);
+ return(0);
+ }
+ if (dir->tdir_count<(uint64)nstrips)
+ {
+ _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
+ _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
+ }
+ else
+ _TIFFmemcpy(resizeddata,data,nstrips*sizeof(uint64));
+ _TIFFfree(data);
+ data=resizeddata;
+ }
+ *lpp=data;
+ return(1);
+}
+
+/*
+ * Fetch and set the SubjectDistance EXIF tag.
+ */
+static int
+TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
+{
+ static const char module[] = "TIFFFetchSubjectDistance";
+ enum TIFFReadDirEntryErr err;
+ UInt64Aligned_t m;
+ m.l=0;
+ assert(sizeof(double)==8);
+ assert(sizeof(uint64)==8);
+ assert(sizeof(uint32)==4);
+ if (dir->tdir_count!=1)
+ err=TIFFReadDirEntryErrCount;
+ else if (dir->tdir_type!=TIFF_RATIONAL)
+ err=TIFFReadDirEntryErrType;
+ else
+ {
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 offset;
+ offset=*(uint32*)(&dir->tdir_offset);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&offset);
+ err=TIFFReadDirEntryData(tif,offset,8,m.i);
+ }
+ else
+ {
+ m.l=dir->tdir_offset.toff_long8;
+ err=TIFFReadDirEntryErrOk;
+ }
+ }
+ if (err==TIFFReadDirEntryErrOk)
+ {
+ double n;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(m.i,2);
+ if (m.i[0]==0)
+ n=0.0;
+ else if (m.i[0]==0xFFFFFFFF)
+ /*
+ * XXX: Numerator 0xFFFFFFFF means that we have infinite
+ * distance. Indicate that with a negative floating point
+ * SubjectDistance value.
+ */
+ n=-1.0;
+ else
+ n=(double)m.i[0]/(double)m.i[1];
+ return(TIFFSetField(tif,dir->tdir_tag,n));
+ }
+ else
+ {
+ TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE);
+ return(0);
+ }
+}
+
+/*
+ * Replace a single strip (tile) of uncompressed data by multiple strips
+ * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
+ * dealing with large images or for dealing with machines with a limited
+ * amount memory.
+ */
+static void
+ChopUpSingleUncompressedStrip(TIFF* tif)
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ uint64 bytecount;
+ uint64 offset;
+ uint32 rowblock;
+ uint64 rowblockbytes;
+ uint64 stripbytes;
+ uint32 strip;
+ uint64 nstrips64;
+ uint32 nstrips32;
+ uint32 rowsperstrip;
+ uint64* newcounts;
+ uint64* newoffsets;
+
+ bytecount = td->td_stripbytecount[0];
+ offset = td->td_stripoffset[0];
+ assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
+ if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
+ (!isUpSampled(tif)))
+ rowblock = td->td_ycbcrsubsampling[1];
+ else
+ rowblock = 1;
+ rowblockbytes = TIFFVTileSize64(tif, rowblock);
+ /*
+ * Make the rows hold at least one scanline, but fill specified amount
+ * of data if possible.
+ */
+ if (rowblockbytes > STRIP_SIZE_DEFAULT) {
+ stripbytes = rowblockbytes;
+ rowsperstrip = rowblock;
+ } else if (rowblockbytes > 0 ) {
+ uint32 rowblocksperstrip;
+ rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes);
+ rowsperstrip = rowblocksperstrip * rowblock;
+ stripbytes = rowblocksperstrip * rowblockbytes;
+ }
+ else
+ return;
+
+ /*
+ * never increase the number of strips in an image
+ */
+ if (rowsperstrip >= td->td_rowsperstrip)
+ return;
+ nstrips64 = TIFFhowmany_64(bytecount, stripbytes);
+ if ((nstrips64==0)||(nstrips64>0xFFFFFFFF)) /* something is wonky, do nothing. */
+ return;
+ nstrips32 = (uint32)nstrips64;
+
+ newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+ "for chopped \"StripByteCounts\" array");
+ newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips32, sizeof (uint64),
+ "for chopped \"StripOffsets\" array");
+ if (newcounts == NULL || newoffsets == NULL) {
+ /*
+ * Unable to allocate new strip information, give up and use
+ * the original one strip information.
+ */
+ if (newcounts != NULL)
+ _TIFFfree(newcounts);
+ if (newoffsets != NULL)
+ _TIFFfree(newoffsets);
+ return;
+ }
+ /*
+ * Fill the strip information arrays with new bytecounts and offsets
+ * that reflect the broken-up format.
+ */
+ for (strip = 0; strip < nstrips32; strip++) {
+ if (stripbytes > bytecount)
+ stripbytes = bytecount;
+ newcounts[strip] = stripbytes;
+ newoffsets[strip] = offset;
+ offset += stripbytes;
+ bytecount -= stripbytes;
+ }
+ /*
+ * Replace old single strip info with multi-strip info.
+ */
+ td->td_stripsperimage = td->td_nstrips = nstrips32;
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
+
+ _TIFFfree(td->td_stripbytecount);
+ _TIFFfree(td->td_stripoffset);
+ td->td_stripbytecount = newcounts;
+ td->td_stripoffset = newoffsets;
+ td->td_stripbytecountsorted = 1;
+}
+
+int _TIFFFillStriles( TIFF *tif )
+{
+#if defined(DEFER_STRILE_LOAD)
+ register TIFFDirectory *td = &tif->tif_dir;
+ int return_value = 1;
+
+ if( td->td_stripoffset != NULL )
+ return 1;
+
+ if( td->td_stripoffset_entry.tdir_count == 0 )
+ return 0;
+
+ if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
+ td->td_nstrips,&td->td_stripoffset))
+ {
+ return_value = 0;
+ }
+
+ if (!TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
+ td->td_nstrips,&td->td_stripbytecount))
+ {
+ return_value = 0;
+ }
+
+ _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
+ _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
+
+ if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
+ uint32 strip;
+
+ tif->tif_dir.td_stripbytecountsorted = 1;
+ for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
+ if (tif->tif_dir.td_stripoffset[strip - 1] >
+ tif->tif_dir.td_stripoffset[strip]) {
+ tif->tif_dir.td_stripbytecountsorted = 0;
+ break;
+ }
+ }
+ }
+
+ return return_value;
+#else /* !defined(DEFER_STRILE_LOAD) */
+ (void) tif;
+ return 1;
+#endif
+}
+
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+ #endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirwrite.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirwrite.c
new file mode 100644
index 0000000000..ac13cd4916
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dirwrite.c
@@ -0,0 +1,2912 @@
+/* $Id: tif_dirwrite.c,v 1.77 2012-07-06 19:18:31 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Write Support Routines.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+#ifdef HAVE_IEEEFP
+#define TIFFCvtNativeToIEEEFloat(tif, n, fp)
+#define TIFFCvtNativeToIEEEDouble(tif, n, dp)
+#else
+extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32 n, float* fp);
+extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32 n, double* dp);
+#endif
+
+static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff);
+
+static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+#if 0
+static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+
+static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
+static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#if 0
+static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
+#if 0
+static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
+static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
+#if 0
+static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#if 0
+static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
+#if 0
+static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
+#endif
+static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
+#endif
+static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
+static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#if 0
+static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+#ifdef notdef
+static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+#if 0
+static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#endif
+static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#endif
+static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir);
+
+static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value);
+static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value);
+static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value);
+static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value);
+static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value);
+static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value);
+#endif
+static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value);
+static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value);
+#endif
+static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value);
+#ifdef notdef
+static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value);
+#endif
+static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value);
+static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value);
+static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value);
+
+static int TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data);
+
+static int TIFFLinkDirectory(TIFF*);
+
+/*
+ * Write the contents of the current directory
+ * to the specified file. This routine doesn't
+ * handle overwriting a directory with auxiliary
+ * storage that's been changed.
+ */
+int
+TIFFWriteDirectory(TIFF* tif)
+{
+ return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), writes the directory out
+ * but leaves all data structures in memory so that it can be
+ * written again. This will make a partially written TIFF file
+ * readable before it is successfully completed/closed.
+ */
+int
+TIFFCheckpointDirectory(TIFF* tif)
+{
+ int rc;
+ /* Setup the strips arrays, if they haven't already been. */
+ if (tif->tif_dir.td_stripoffset == NULL)
+ (void) TIFFSetupStrips(tif);
+ rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
+ (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
+ return rc;
+}
+
+int
+TIFFWriteCustomDirectory(TIFF* tif, uint64* pdiroff)
+{
+ return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
+}
+
+/*
+ * Similar to TIFFWriteDirectory(), but if the directory has already
+ * been written once, it is relocated to the end of the file, in case it
+ * has changed in size. Note that this will result in the loss of the
+ * previously used directory space.
+ */
+int
+TIFFRewriteDirectory( TIFF *tif )
+{
+ static const char module[] = "TIFFRewriteDirectory";
+
+ /* We don't need to do anything special if it hasn't been written. */
+ if( tif->tif_diroff == 0 )
+ return TIFFWriteDirectory( tif );
+
+ /*
+ * Find and zero the pointer to this directory, so that TIFFLinkDirectory
+ * will cause it to be added after this directories current pre-link.
+ */
+
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
+ {
+ tif->tif_header.classic.tiff_diroff = 0;
+ tif->tif_diroff = 0;
+
+ TIFFSeekFile(tif,4,SEEK_SET);
+ if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4))
+ {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Error updating TIFF header");
+ return (0);
+ }
+ }
+ else
+ {
+ uint32 nextdir;
+ nextdir = tif->tif_header.classic.tiff_diroff;
+ while(1) {
+ uint16 dircount;
+ uint32 nextnextdir;
+
+ if (!SeekOK(tif, nextdir) ||
+ !ReadOK(tif, &dircount, 2)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ (void) TIFFSeekFile(tif,
+ nextdir+2+dircount*12, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 4)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextnextdir);
+ if (nextnextdir==tif->tif_diroff)
+ {
+ uint32 m;
+ m=0;
+ (void) TIFFSeekFile(tif,
+ nextdir+2+dircount*12, SEEK_SET);
+ if (!WriteOK(tif, &m, 4)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing directory link");
+ return (0);
+ }
+ tif->tif_diroff=0;
+ break;
+ }
+ nextdir=nextnextdir;
+ }
+ }
+ }
+ else
+ {
+ if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
+ {
+ tif->tif_header.big.tiff_diroff = 0;
+ tif->tif_diroff = 0;
+
+ TIFFSeekFile(tif,8,SEEK_SET);
+ if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8))
+ {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Error updating TIFF header");
+ return (0);
+ }
+ }
+ else
+ {
+ uint64 nextdir;
+ nextdir = tif->tif_header.big.tiff_diroff;
+ while(1) {
+ uint64 dircount64;
+ uint16 dircount;
+ uint64 nextnextdir;
+
+ if (!SeekOK(tif, nextdir) ||
+ !ReadOK(tif, &dircount64, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64>0xFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on tag count failed, likely corrupt TIFF");
+ return (0);
+ }
+ dircount=(uint16)dircount64;
+ (void) TIFFSeekFile(tif,
+ nextdir+8+dircount*20, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&nextnextdir);
+ if (nextnextdir==tif->tif_diroff)
+ {
+ uint64 m;
+ m=0;
+ (void) TIFFSeekFile(tif,
+ nextdir+8+dircount*20, SEEK_SET);
+ if (!WriteOK(tif, &m, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing directory link");
+ return (0);
+ }
+ tif->tif_diroff=0;
+ break;
+ }
+ nextdir=nextnextdir;
+ }
+ }
+ }
+
+ /*
+ * Now use TIFFWriteDirectory() normally.
+ */
+
+ return TIFFWriteDirectory( tif );
+}
+
+static int
+TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64* pdiroff)
+{
+ static const char module[] = "TIFFWriteDirectorySec";
+ uint32 ndir;
+ TIFFDirEntry* dir;
+ uint32 dirsize;
+ void* dirmem;
+ uint32 m;
+ if (tif->tif_mode == O_RDONLY)
+ return (1);
+
+ _TIFFFillStriles( tif );
+
+ /*
+ * Clear write state so that subsequent images with
+ * different characteristics get the right buffers
+ * setup for them.
+ */
+ if (imagedone)
+ {
+ if (tif->tif_flags & TIFF_POSTENCODE)
+ {
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+ if (!(*tif->tif_postencode)(tif))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Error post-encoding before directory write");
+ return (0);
+ }
+ }
+ (*tif->tif_close)(tif); /* shutdown encoder */
+ /*
+ * Flush any data that might have been written
+ * by the compression close+cleanup routines. But
+ * be careful not to write stuff if we didn't add data
+ * in the previous steps as the "rawcc" data may well be
+ * a previously read tile/strip in mixed read/write mode.
+ */
+ if (tif->tif_rawcc > 0
+ && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
+ {
+ if( !TIFFFlushData1(tif) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error flushing data before directory write");
+ return (0);
+ }
+ }
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
+ {
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawcc = 0;
+ tif->tif_rawdatasize = 0;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+ }
+ tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
+ }
+ dir=NULL;
+ dirmem=NULL;
+ dirsize=0;
+ while (1)
+ {
+ ndir=0;
+ if (isimage)
+ {
+ if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
+ {
+ if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth))
+ goto bad;
+ if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS))
+ {
+ if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth))
+ goto bad;
+ if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_RESOLUTION))
+ {
+ if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution))
+ goto bad;
+ if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_POSITION))
+ {
+ if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition))
+ goto bad;
+ if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_SUBFILETYPE))
+ {
+ if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_COMPRESSION))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_THRESHHOLDING))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_FILLORDER))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_ORIENTATION))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP))
+ {
+ if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_PLANARCONFIG))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
+ {
+ if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0]))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS))
+ {
+ if (!isTiled(tif))
+ {
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ goto bad;
+ }
+ else
+ {
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount))
+ goto bad;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS))
+ {
+ if (!isTiled(tif))
+ {
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ goto bad;
+ }
+ else
+ {
+ if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset))
+ goto bad;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_COLORMAP))
+ {
+ if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
+ {
+ if (tif->tif_dir.td_extrasamples)
+ {
+ uint16 na;
+ uint16* nb;
+ TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
+ if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
+ goto bad;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
+ {
+ if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
+ {
+ if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
+ {
+ if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
+ {
+ if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
+ {
+ if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
+ {
+ if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
+ {
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
+ {
+ if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
+ {
+ if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_INKNAMES))
+ {
+ if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
+ goto bad;
+ }
+ if (TIFFFieldSet(tif,FIELD_SUBIFD))
+ {
+ if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
+ goto bad;
+ }
+ {
+ uint32 n;
+ for (n=0; n<tif->tif_nfields; n++) {
+ const TIFFField* o;
+ o = tif->tif_fields[n];
+ if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
+ {
+ switch (o->get_field_type)
+ {
+ case TIFF_SETGET_ASCII:
+ {
+ uint32 pa;
+ char* pb;
+ assert(o->field_type==TIFF_ASCII);
+ assert(o->field_readcount==TIFF_VARIABLE);
+ assert(o->field_passcount==0);
+ TIFFGetField(tif,o->field_tag,&pb);
+ pa=(uint32)(strlen(pb));
+ if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,o->field_tag,pa,pb))
+ goto bad;
+ }
+ break;
+ case TIFF_SETGET_UINT16:
+ {
+ uint16 p;
+ assert(o->field_type==TIFF_SHORT);
+ assert(o->field_readcount==1);
+ assert(o->field_passcount==0);
+ TIFFGetField(tif,o->field_tag,&p);
+ if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,o->field_tag,p))
+ goto bad;
+ }
+ break;
+ case TIFF_SETGET_UINT32:
+ {
+ uint32 p;
+ assert(o->field_type==TIFF_LONG);
+ assert(o->field_readcount==1);
+ assert(o->field_passcount==0);
+ TIFFGetField(tif,o->field_tag,&p);
+ if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,o->field_tag,p))
+ goto bad;
+ }
+ break;
+ case TIFF_SETGET_C32_UINT8:
+ {
+ uint32 pa;
+ void* pb;
+ assert(o->field_type==TIFF_UNDEFINED);
+ assert(o->field_readcount==TIFF_VARIABLE2);
+ assert(o->field_passcount==1);
+ TIFFGetField(tif,o->field_tag,&pa,&pb);
+ if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,o->field_tag,pa,pb))
+ goto bad;
+ }
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ }
+ }
+ }
+ }
+ for (m=0; m<(uint32)(tif->tif_dir.td_customValueCount); m++)
+ {
+ switch (tif->tif_dir.td_customValues[m].info->field_type)
+ {
+ case TIFF_ASCII:
+ if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_UNDEFINED:
+ if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_BYTE:
+ if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SBYTE:
+ if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SHORT:
+ if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SSHORT:
+ if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_LONG:
+ if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SLONG:
+ if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_LONG8:
+ if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SLONG8:
+ if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_RATIONAL:
+ if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_SRATIONAL:
+ if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_FLOAT:
+ if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_DOUBLE:
+ if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_IFD:
+ if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ case TIFF_IFD8:
+ if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tif->tif_dir.td_customValues[m].info->field_tag,tif->tif_dir.td_customValues[m].count,tif->tif_dir.td_customValues[m].value))
+ goto bad;
+ break;
+ default:
+ assert(0); /* we should never get here */
+ break;
+ }
+ }
+ if (dir!=NULL)
+ break;
+ dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
+ if (dir==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ goto bad;
+ }
+ if (isimage)
+ {
+ if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
+ goto bad;
+ }
+ else
+ tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~1);
+ if (pdiroff!=NULL)
+ *pdiroff=tif->tif_diroff;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ dirsize=2+ndir*12+4;
+ else
+ dirsize=8+ndir*20+8;
+ tif->tif_dataoff=tif->tif_diroff+dirsize;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ tif->tif_dataoff=(uint32)tif->tif_dataoff;
+ if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64)dirsize))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
+ goto bad;
+ }
+ if (tif->tif_dataoff&1)
+ tif->tif_dataoff++;
+ if (isimage)
+ tif->tif_curdir++;
+ }
+ if (isimage)
+ {
+ if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
+ {
+ uint32 na;
+ TIFFDirEntry* nb;
+ for (na=0, nb=dir; ; na++, nb++)
+ {
+ assert(na<ndir);
+ if (nb->tdir_tag==TIFFTAG_SUBIFD)
+ break;
+ }
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
+ else
+ tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
+ }
+ }
+ dirmem=_TIFFmalloc(dirsize);
+ if (dirmem==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ goto bad;
+ }
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint8* n;
+ uint32 nTmp;
+ TIFFDirEntry* o;
+ n=dirmem;
+ *(uint16*)n=ndir;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)n);
+ n+=2;
+ o=dir;
+ for (m=0; m<ndir; m++)
+ {
+ *(uint16*)n=o->tdir_tag;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)n);
+ n+=2;
+ *(uint16*)n=o->tdir_type;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)n);
+ n+=2;
+ nTmp = (uint32)o->tdir_count;
+ _TIFFmemcpy(n,&nTmp,4);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)n);
+ n+=4;
+ /* This is correct. The data has been */
+ /* swabbed previously in TIFFWriteDirectoryTagData */
+ _TIFFmemcpy(n,&o->tdir_offset,4);
+ n+=4;
+ o++;
+ }
+ nTmp = (uint32)tif->tif_nextdiroff;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&nTmp);
+ _TIFFmemcpy(n,&nTmp,4);
+ }
+ else
+ {
+ uint8* n;
+ TIFFDirEntry* o;
+ n=dirmem;
+ *(uint64*)n=ndir;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)n);
+ n+=8;
+ o=dir;
+ for (m=0; m<ndir; m++)
+ {
+ *(uint16*)n=o->tdir_tag;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)n);
+ n+=2;
+ *(uint16*)n=o->tdir_type;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)n);
+ n+=2;
+ _TIFFmemcpy(n,&o->tdir_count,8);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)n);
+ n+=8;
+ _TIFFmemcpy(n,&o->tdir_offset,8);
+ n+=8;
+ o++;
+ }
+ _TIFFmemcpy(n,&tif->tif_nextdiroff,8);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)n);
+ }
+ _TIFFfree(dir);
+ dir=NULL;
+ if (!SeekOK(tif,tif->tif_diroff))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
+ goto bad;
+ }
+ if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
+ goto bad;
+ }
+ _TIFFfree(dirmem);
+ if (imagedone)
+ {
+ TIFFFreeDirectory(tif);
+ tif->tif_flags &= ~TIFF_DIRTYDIRECT;
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+ (*tif->tif_cleanup)(tif);
+ /*
+ * Reset directory-related state for subsequent
+ * directories.
+ */
+ TIFFCreateDirectory(tif);
+ }
+ return(1);
+bad:
+ if (dir!=NULL)
+ _TIFFfree(dir);
+ if (dirmem!=NULL)
+ _TIFFfree(dirmem);
+ return(0);
+}
+
+static int
+TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
+ void* conv;
+ uint32 i;
+ int ok;
+ conv = _TIFFmalloc(count*sizeof(double));
+ if (conv == NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
+ return (0);
+ }
+
+ switch (tif->tif_dir.td_sampleformat)
+ {
+ case SAMPLEFORMAT_IEEEFP:
+ if (tif->tif_dir.td_bitspersample<=32)
+ {
+ for (i = 0; i < count; ++i)
+ ((float*)conv)[i] = (float)value[i];
+ ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
+ }
+ else
+ {
+ ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value);
+ }
+ break;
+ case SAMPLEFORMAT_INT:
+ if (tif->tif_dir.td_bitspersample<=8)
+ {
+ for (i = 0; i < count; ++i)
+ ((int8*)conv)[i] = (int8)value[i];
+ ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8*)conv);
+ }
+ else if (tif->tif_dir.td_bitspersample<=16)
+ {
+ for (i = 0; i < count; ++i)
+ ((int16*)conv)[i] = (int16)value[i];
+ ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16*)conv);
+ }
+ else
+ {
+ for (i = 0; i < count; ++i)
+ ((int32*)conv)[i] = (int32)value[i];
+ ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32*)conv);
+ }
+ break;
+ case SAMPLEFORMAT_UINT:
+ if (tif->tif_dir.td_bitspersample<=8)
+ {
+ for (i = 0; i < count; ++i)
+ ((uint8*)conv)[i] = (uint8)value[i];
+ ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8*)conv);
+ }
+ else if (tif->tif_dir.td_bitspersample<=16)
+ {
+ for (i = 0; i < count; ++i)
+ ((uint16*)conv)[i] = (uint16)value[i];
+ ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16*)conv);
+ }
+ else
+ {
+ for (i = 0; i < count; ++i)
+ ((uint32*)conv)[i] = (uint32)value[i];
+ ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32*)conv);
+ }
+ break;
+ default:
+ ok = 0;
+ }
+
+ _TIFFfree(conv);
+ return (ok);
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+ switch (tif->tif_dir.td_sampleformat)
+ {
+ case SAMPLEFORMAT_IEEEFP:
+ if (tif->tif_dir.td_bitspersample<=32)
+ return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
+ else
+ return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
+ case SAMPLEFORMAT_INT:
+ if (tif->tif_dir.td_bitspersample<=8)
+ return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8)value));
+ else if (tif->tif_dir.td_bitspersample<=16)
+ return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16)value));
+ else
+ return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32)value));
+ case SAMPLEFORMAT_UINT:
+ if (tif->tif_dir.td_bitspersample<=8)
+ return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8)value));
+ else if (tif->tif_dir.td_bitspersample<=16)
+ return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16)value));
+ else
+ return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32)value));
+ default:
+ return(1);
+ }
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
+ uint8* m;
+ uint8* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
+ int8* m;
+ int8* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
+ uint16* m;
+ uint16* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
+ int16* m;
+ int16* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
+ uint32* m;
+ uint32* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int
+TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
+ int32* m;
+ int32* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+#endif
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
+}
+
+static int
+TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
+ float* m;
+ float* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+#endif
+
+#ifdef notdef
+static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
+}
+#endif
+
+static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
+}
+
+#if 0
+static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
+ double* m;
+ double* na;
+ uint16 nb;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
+ *na=value;
+ o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
+ _TIFFfree(m);
+ return(o);
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ if (value<=0xFFFF)
+ return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16)value));
+ else
+ return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
+}
+
+/************************************************************************/
+/* TIFFWriteDirectoryTagLongLong8Array() */
+/* */
+/* Write out LONG8 array as LONG8 for BigTIFF or LONG for */
+/* Classic TIFF with some checking. */
+/************************************************************************/
+
+static int
+TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
+ uint64* ma;
+ uint32 mb;
+ uint32* p;
+ uint32* q;
+ int o;
+
+ /* is this just a counting pass? */
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+
+ /* We always write LONG8 for BigTIFF, no checking needed. */
+ if( tif->tif_flags&TIFF_BIGTIFF )
+ return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
+ tag,count,value);
+
+ /*
+ ** For classic tiff we want to verify everything is in range for LONG
+ ** and convert to long format.
+ */
+
+ p = _TIFFmalloc(count*sizeof(uint32));
+ if (p==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+
+ for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ {
+ if (*ma>0xFFFFFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
+ _TIFFfree(p);
+ return(0);
+ }
+ *q= (uint32)(*ma);
+ }
+
+ o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
+
+ return(o);
+}
+
+/************************************************************************/
+/* TIFFWriteDirectoryTagIfdIfd8Array() */
+/* */
+/* Write either IFD8 or IFD array depending on file type. */
+/************************************************************************/
+
+static int
+TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
+ uint64* ma;
+ uint32 mb;
+ uint32* p;
+ uint32* q;
+ int o;
+
+ /* is this just a counting pass? */
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+
+ /* We always write IFD8 for BigTIFF, no checking needed. */
+ if( tif->tif_flags&TIFF_BIGTIFF )
+ return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
+ tag,count,value);
+
+ /*
+ ** For classic tiff we want to verify everything is in range for IFD
+ ** and convert to long format.
+ */
+
+ p = _TIFFmalloc(count*sizeof(uint32));
+ if (p==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+
+ for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
+ {
+ if (*ma>0xFFFFFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
+ _TIFFfree(p);
+ return(0);
+ }
+ *q= (uint32)(*ma);
+ }
+
+ o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
+
+ return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
+ uint64* ma;
+ uint32 mb;
+ uint8 n;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ n=0;
+ for (ma=value, mb=0; mb<count; ma++, mb++)
+ {
+ if ((n==0)&&(*ma>0xFFFF))
+ n=1;
+ if ((n==1)&&(*ma>0xFFFFFFFF))
+ {
+ n=2;
+ break;
+ }
+ }
+ if (n==0)
+ {
+ uint16* p;
+ uint16* q;
+ p=_TIFFmalloc(count*sizeof(uint16));
+ if (p==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
+ *q=(uint16)(*ma);
+ o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
+ }
+ else if (n==1)
+ {
+ uint32* p;
+ uint32* q;
+ p=_TIFFmalloc(count*sizeof(uint32));
+ if (p==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
+ *q=(uint32)(*ma);
+ o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
+ _TIFFfree(p);
+ }
+ else
+ {
+ assert(n==2);
+ o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
+ }
+ return(o);
+}
+#endif
+static int
+TIFFWriteDirectoryTagColormap(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+ static const char module[] = "TIFFWriteDirectoryTagColormap";
+ uint32 m;
+ uint16* n;
+ int o;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=(1<<tif->tif_dir.td_bitspersample);
+ n=_TIFFmalloc(3*m*sizeof(uint16));
+ if (n==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16));
+ _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16));
+ _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16));
+ o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
+ _TIFFfree(n);
+ return(o);
+}
+
+static int
+TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+ static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
+ uint32 m;
+ uint16 n;
+ uint16* o;
+ int p;
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=(1<<tif->tif_dir.td_bitspersample);
+ n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
+ /*
+ * Check if the table can be written as a single column,
+ * or if it must be written as 3 columns. Note that we
+ * write a 3-column tag if there are 2 samples/pixel and
+ * a single column of data won't suffice--hmm.
+ */
+ if (n>3)
+ n=3;
+ if (n==3)
+ {
+ if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16)))
+ n=2;
+ }
+ if (n==2)
+ {
+ if (!_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16)))
+ n=1;
+ }
+ if (n==0)
+ n=1;
+ o=_TIFFmalloc(n*m*sizeof(uint16));
+ if (o==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16));
+ if (n>1)
+ _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16));
+ if (n>2)
+ _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16));
+ p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
+ _TIFFfree(o);
+ return(p);
+}
+
+static int
+TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32* ndir, TIFFDirEntry* dir)
+{
+ static const char module[] = "TIFFWriteDirectoryTagSubifd";
+ uint64 m;
+ int n;
+ if (tif->tif_dir.td_nsubifd==0)
+ return(1);
+ if (dir==NULL)
+ {
+ (*ndir)++;
+ return(1);
+ }
+ m=tif->tif_dataoff;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32* o;
+ uint64* pa;
+ uint32* pb;
+ uint16 p;
+ o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32));
+ if (o==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ pa=tif->tif_dir.td_subifd;
+ pb=o;
+ for (p=0; p < tif->tif_dir.td_nsubifd; p++)
+ {
+ assert(pa != 0);
+ assert(*pa <= 0xFFFFFFFFUL);
+ *pb++=(uint32)(*pa++);
+ }
+ n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
+ _TIFFfree(o);
+ }
+ else
+ n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
+ if (!n)
+ return(0);
+ /*
+ * Total hack: if this directory includes a SubIFD
+ * tag then force the next <n> directories to be
+ * written as ``sub directories'' of this one. This
+ * is used to write things like thumbnails and
+ * image masks that one wants to keep out of the
+ * normal directory linkage access mechanism.
+ */
+ tif->tif_flags|=TIFF_INSUBIFD;
+ tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
+ if (tif->tif_dir.td_nsubifd==1)
+ tif->tif_subifdoff=0;
+ else
+ tif->tif_subifdoff=m;
+ return(1);
+}
+
+static int
+TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, char* value)
+{
+ assert(sizeof(char)==1);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+ assert(sizeof(uint8)==1);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint8 value)
+{
+ assert(sizeof(uint8)==1);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint8* value)
+{
+ assert(sizeof(uint8)==1);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int8 value)
+{
+ assert(sizeof(int8)==1);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int8* value)
+{
+ assert(sizeof(int8)==1);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 value)
+{
+ uint16 m;
+ assert(sizeof(uint16)==2);
+ m=value;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort(&m);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint16* value)
+{
+ assert(count<0x80000000);
+ assert(sizeof(uint16)==2);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfShort(value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int16 value)
+{
+ int16 m;
+ assert(sizeof(int16)==2);
+ m=value;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort((uint16*)(&m));
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int16* value)
+{
+ assert(count<0x80000000);
+ assert(sizeof(int16)==2);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfShort((uint16*)value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 value)
+{
+ uint32 m;
+ assert(sizeof(uint32)==4);
+ m=value;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&m);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+ assert(count<0x40000000);
+ assert(sizeof(uint32)==4);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int32 value)
+{
+ int32 m;
+ assert(sizeof(int32)==4);
+ m=value;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong((uint32*)(&m));
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int32* value)
+{
+ assert(count<0x40000000);
+ assert(sizeof(int32)==4);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32*)value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint64 value)
+{
+ uint64 m;
+ assert(sizeof(uint64)==8);
+ assert(tif->tif_flags&TIFF_BIGTIFF);
+ m=value;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(&m);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+ assert(count<0x20000000);
+ assert(sizeof(uint64)==8);
+ assert(tif->tif_flags&TIFF_BIGTIFF);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8(value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, int64 value)
+{
+ int64 m;
+ assert(sizeof(int64)==8);
+ assert(tif->tif_flags&TIFF_BIGTIFF);
+ m=value;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8((uint64*)(&m));
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, int64* value)
+{
+ assert(count<0x20000000);
+ assert(sizeof(int64)==8);
+ assert(tif->tif_flags&TIFF_BIGTIFF);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8((uint64*)value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+ uint32 m[2];
+ assert(value>=0.0);
+ assert(sizeof(uint32)==4);
+ if (value<=0.0)
+ {
+ m[0]=0;
+ m[1]=1;
+ }
+ else if (value==(double)(uint32)value)
+ {
+ m[0]=(uint32)value;
+ m[1]=1;
+ }
+ else if (value<1.0)
+ {
+ m[0]=(uint32)(value*0xFFFFFFFF);
+ m[1]=0xFFFFFFFF;
+ }
+ else
+ {
+ m[0]=0xFFFFFFFF;
+ m[1]=(uint32)(0xFFFFFFFF/value);
+ }
+ if (tif->tif_flags&TIFF_SWAB)
+ {
+ TIFFSwabLong(&m[0]);
+ TIFFSwabLong(&m[1]);
+ }
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
+ uint32* m;
+ float* na;
+ uint32* nb;
+ uint32 nc;
+ int o;
+ assert(sizeof(uint32)==4);
+ m=_TIFFmalloc(count*2*sizeof(uint32));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+ {
+ if (*na<=0.0)
+ {
+ nb[0]=0;
+ nb[1]=1;
+ }
+ else if (*na==(float)(uint32)(*na))
+ {
+ nb[0]=(uint32)(*na);
+ nb[1]=1;
+ }
+ else if (*na<1.0)
+ {
+ nb[0]=(uint32)((*na)*0xFFFFFFFF);
+ nb[1]=0xFFFFFFFF;
+ }
+ else
+ {
+ nb[0]=0xFFFFFFFF;
+ nb[1]=(uint32)(0xFFFFFFFF/(*na));
+ }
+ }
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(m,count*2);
+ o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
+ _TIFFfree(m);
+ return(o);
+}
+
+static int
+TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+ static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
+ int32* m;
+ float* na;
+ int32* nb;
+ uint32 nc;
+ int o;
+ assert(sizeof(int32)==4);
+ m=_TIFFmalloc(count*2*sizeof(int32));
+ if (m==NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
+ {
+ if (*na<0.0)
+ {
+ if (*na==(int32)(*na))
+ {
+ nb[0]=(int32)(*na);
+ nb[1]=1;
+ }
+ else if (*na>-1.0)
+ {
+ nb[0]=-(int32)((-*na)*0x7FFFFFFF);
+ nb[1]=0x7FFFFFFF;
+ }
+ else
+ {
+ nb[0]=-0x7FFFFFFF;
+ nb[1]=(int32)(0x7FFFFFFF/(-*na));
+ }
+ }
+ else
+ {
+ if (*na==(int32)(*na))
+ {
+ nb[0]=(int32)(*na);
+ nb[1]=1;
+ }
+ else if (*na<1.0)
+ {
+ nb[0]=(int32)((*na)*0x7FFFFFFF);
+ nb[1]=0x7FFFFFFF;
+ }
+ else
+ {
+ nb[0]=0x7FFFFFFF;
+ nb[1]=(int32)(0x7FFFFFFF/(*na));
+ }
+ }
+ }
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong((uint32*)m,count*2);
+ o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
+ _TIFFfree(m);
+ return(o);
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, float value)
+{
+ float m;
+ assert(sizeof(float)==4);
+ m=value;
+ TIFFCvtNativeToIEEEFloat(tif,1,&m);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabFloat(&m);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
+{
+ assert(count<0x40000000);
+ assert(sizeof(float)==4);
+ TIFFCvtNativeToIEEEFloat(tif,count,&value);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfFloat(value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
+}
+
+#ifdef notdef
+static int
+TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, double value)
+{
+ double m;
+ assert(sizeof(double)==8);
+ m=value;
+ TIFFCvtNativeToIEEEDouble(tif,1,&m);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabDouble(&m);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
+}
+#endif
+
+static int
+TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, double* value)
+{
+ assert(count<0x20000000);
+ assert(sizeof(double)==8);
+ TIFFCvtNativeToIEEEDouble(tif,count,&value);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfDouble(value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint32* value)
+{
+ assert(count<0x40000000);
+ assert(sizeof(uint32)==4);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong(value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
+}
+
+static int
+TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, uint64* value)
+{
+ assert(count<0x20000000);
+ assert(sizeof(uint64)==8);
+ assert(tif->tif_flags&TIFF_BIGTIFF);
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabArrayOfLong8(value,count);
+ return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
+}
+
+static int
+TIFFWriteDirectoryTagData(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint16 datatype, uint32 count, uint32 datalength, void* data)
+{
+ static const char module[] = "TIFFWriteDirectoryTagData";
+ uint32 m;
+ m=0;
+ while (m<(*ndir))
+ {
+ assert(dir[m].tdir_tag!=tag);
+ if (dir[m].tdir_tag>tag)
+ break;
+ m++;
+ }
+ if (m<(*ndir))
+ {
+ uint32 n;
+ for (n=*ndir; n>m; n--)
+ dir[n]=dir[n-1];
+ }
+ dir[m].tdir_tag=tag;
+ dir[m].tdir_type=datatype;
+ dir[m].tdir_count=count;
+ dir[m].tdir_offset.toff_long8 = 0;
+ if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
+ _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
+ else
+ {
+ uint64 na,nb;
+ na=tif->tif_dataoff;
+ nb=na+datalength;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ nb=(uint32)nb;
+ if ((nb<na)||(nb<datalength))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
+ return(0);
+ }
+ if (!SeekOK(tif,na))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+ return(0);
+ }
+ assert(datalength<0x80000000UL);
+ if (!WriteOK(tif,data,(tmsize_t)datalength))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
+ return(0);
+ }
+ tif->tif_dataoff=nb;
+ if (tif->tif_dataoff&1)
+ tif->tif_dataoff++;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 o;
+ o=(uint32)na;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong(&o);
+ _TIFFmemcpy(&dir[m].tdir_offset,&o,4);
+ }
+ else
+ {
+ dir[m].tdir_offset.toff_long8 = na;
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
+ }
+ }
+ (*ndir)++;
+ return(1);
+}
+
+/*
+ * Link the current directory into the directory chain for the file.
+ */
+static int
+TIFFLinkDirectory(TIFF* tif)
+{
+ static const char module[] = "TIFFLinkDirectory";
+
+ tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) &~ 1;
+
+ /*
+ * Handle SubIFDs
+ */
+ if (tif->tif_flags & TIFF_INSUBIFD)
+ {
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 m;
+ m = (uint32)tif->tif_diroff;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&m);
+ (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+ if (!WriteOK(tif, &m, 4)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing SubIFD directory link");
+ return (0);
+ }
+ /*
+ * Advance to the next SubIFD or, if this is
+ * the last one configured, revert back to the
+ * normal directory linkage.
+ */
+ if (--tif->tif_nsubifd)
+ tif->tif_subifdoff += 4;
+ else
+ tif->tif_flags &= ~TIFF_INSUBIFD;
+ return (1);
+ }
+ else
+ {
+ uint64 m;
+ m = tif->tif_diroff;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&m);
+ (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
+ if (!WriteOK(tif, &m, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing SubIFD directory link");
+ return (0);
+ }
+ /*
+ * Advance to the next SubIFD or, if this is
+ * the last one configured, revert back to the
+ * normal directory linkage.
+ */
+ if (--tif->tif_nsubifd)
+ tif->tif_subifdoff += 8;
+ else
+ tif->tif_flags &= ~TIFF_INSUBIFD;
+ return (1);
+ }
+ }
+
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 m;
+ uint32 nextdir;
+ m = (uint32)(tif->tif_diroff);
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&m);
+ if (tif->tif_header.classic.tiff_diroff == 0) {
+ /*
+ * First directory, overwrite offset in header.
+ */
+ tif->tif_header.classic.tiff_diroff = (uint32) tif->tif_diroff;
+ (void) TIFFSeekFile(tif,4, SEEK_SET);
+ if (!WriteOK(tif, &m, 4)) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Error writing TIFF header");
+ return (0);
+ }
+ return (1);
+ }
+ /*
+ * Not the first directory, search to the last and append.
+ */
+ nextdir = tif->tif_header.classic.tiff_diroff;
+ while(1) {
+ uint16 dircount;
+ uint32 nextnextdir;
+
+ if (!SeekOK(tif, nextdir) ||
+ !ReadOK(tif, &dircount, 2)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ (void) TIFFSeekFile(tif,
+ nextdir+2+dircount*12, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 4)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&nextnextdir);
+ if (nextnextdir==0)
+ {
+ (void) TIFFSeekFile(tif,
+ nextdir+2+dircount*12, SEEK_SET);
+ if (!WriteOK(tif, &m, 4)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing directory link");
+ return (0);
+ }
+ break;
+ }
+ nextdir=nextnextdir;
+ }
+ }
+ else
+ {
+ uint64 m;
+ uint64 nextdir;
+ m = tif->tif_diroff;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&m);
+ if (tif->tif_header.big.tiff_diroff == 0) {
+ /*
+ * First directory, overwrite offset in header.
+ */
+ tif->tif_header.big.tiff_diroff = tif->tif_diroff;
+ (void) TIFFSeekFile(tif,8, SEEK_SET);
+ if (!WriteOK(tif, &m, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Error writing TIFF header");
+ return (0);
+ }
+ return (1);
+ }
+ /*
+ * Not the first directory, search to the last and append.
+ */
+ nextdir = tif->tif_header.big.tiff_diroff;
+ while(1) {
+ uint64 dircount64;
+ uint16 dircount;
+ uint64 nextnextdir;
+
+ if (!SeekOK(tif, nextdir) ||
+ !ReadOK(tif, &dircount64, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory count");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ if (dircount64>0xFFFF)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Sanity check on tag count failed, likely corrupt TIFF");
+ return (0);
+ }
+ dircount=(uint16)dircount64;
+ (void) TIFFSeekFile(tif,
+ nextdir+8+dircount*20, SEEK_SET);
+ if (!ReadOK(tif, &nextnextdir, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error fetching directory link");
+ return (0);
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&nextnextdir);
+ if (nextnextdir==0)
+ {
+ (void) TIFFSeekFile(tif,
+ nextdir+8+dircount*20, SEEK_SET);
+ if (!WriteOK(tif, &m, 8)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing directory link");
+ return (0);
+ }
+ break;
+ }
+ nextdir=nextnextdir;
+ }
+ }
+ return (1);
+}
+
+/************************************************************************/
+/* TIFFRewriteField() */
+/* */
+/* Rewrite a field in the directory on disk without regard to */
+/* updating the TIFF directory structure in memory. Currently */
+/* only supported for field that already exist in the on-disk */
+/* directory. Mainly used for updating stripoffset / */
+/* stripbytecount values after the directory is already on */
+/* disk. */
+/* */
+/* Returns zero on failure, and one on success. */
+/************************************************************************/
+
+int
+_TIFFRewriteField(TIFF* tif, uint16 tag, TIFFDataType in_datatype,
+ tmsize_t count, void* data)
+{
+ static const char module[] = "TIFFResetField";
+ /* const TIFFField* fip = NULL; */
+ uint16 dircount;
+ tmsize_t dirsize;
+ uint8 direntry_raw[20];
+ uint16 entry_tag = 0;
+ uint16 entry_type = 0;
+ uint64 entry_count = 0;
+ uint64 entry_offset = 0;
+ int value_in_entry = 0;
+ uint64 read_offset;
+ uint8 *buf_to_write = NULL;
+ TIFFDataType datatype;
+
+/* -------------------------------------------------------------------- */
+/* Find field definition. */
+/* -------------------------------------------------------------------- */
+ /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
+
+/* -------------------------------------------------------------------- */
+/* Do some checking this is a straight forward case. */
+/* -------------------------------------------------------------------- */
+ if( isMapped(tif) )
+ {
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Memory mapped files not currently supported for this operation." );
+ return 0;
+ }
+
+ if( tif->tif_diroff == 0 )
+ {
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Attempt to reset field on directory not already on disk." );
+ return 0;
+ }
+
+/* -------------------------------------------------------------------- */
+/* Read the directory entry count. */
+/* -------------------------------------------------------------------- */
+ if (!SeekOK(tif, tif->tif_diroff)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+
+ read_offset = tif->tif_diroff;
+
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ if (!ReadOK(tif, &dircount, sizeof (uint16))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&dircount);
+ dirsize = 12;
+ read_offset += 2;
+ } else {
+ uint64 dircount64;
+ if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Can not read TIFF directory count",
+ tif->tif_name);
+ return 0;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong8(&dircount64);
+ dircount = (uint16)dircount64;
+ dirsize = 20;
+ read_offset += 8;
+ }
+
+/* -------------------------------------------------------------------- */
+/* Read through directory to find target tag. */
+/* -------------------------------------------------------------------- */
+ while( dircount > 0 )
+ {
+ if (!ReadOK(tif, direntry_raw, dirsize)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Can not read TIFF directory entry.",
+ tif->tif_name);
+ return 0;
+ }
+
+ memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort( &entry_tag );
+
+ if( entry_tag == tag )
+ break;
+
+ read_offset += dirsize;
+ }
+
+ if( entry_tag != tag )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Could not find tag %d.",
+ tif->tif_name, tag );
+ return 0;
+ }
+
+/* -------------------------------------------------------------------- */
+/* Extract the type, count and offset for this entry. */
+/* -------------------------------------------------------------------- */
+ memcpy( &entry_type, direntry_raw + 2, sizeof(uint16) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort( &entry_type );
+
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 value;
+
+ memcpy( &value, direntry_raw + 4, sizeof(uint32) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong( &value );
+ entry_count = value;
+
+ memcpy( &value, direntry_raw + 8, sizeof(uint32) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong( &value );
+ entry_offset = value;
+ }
+ else
+ {
+ memcpy( &entry_count, direntry_raw + 4, sizeof(uint64) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8( &entry_count );
+
+ memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8( &entry_offset );
+ }
+
+/* -------------------------------------------------------------------- */
+/* What data type do we want to write this as? */
+/* -------------------------------------------------------------------- */
+ if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
+ {
+ if( in_datatype == TIFF_LONG8 )
+ datatype = TIFF_LONG;
+ else if( in_datatype == TIFF_SLONG8 )
+ datatype = TIFF_SLONG;
+ else if( in_datatype == TIFF_IFD8 )
+ datatype = TIFF_IFD;
+ else
+ datatype = in_datatype;
+ }
+ else
+ datatype = in_datatype;
+
+/* -------------------------------------------------------------------- */
+/* Prepare buffer of actual data to write. This includes */
+/* swabbing as needed. */
+/* -------------------------------------------------------------------- */
+ buf_to_write =
+ (uint8 *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
+ "for field buffer.");
+ if (!buf_to_write)
+ return 0;
+
+ if( datatype == in_datatype )
+ memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
+ else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
+ {
+ tmsize_t i;
+
+ for( i = 0; i < count; i++ )
+ {
+ ((int32 *) buf_to_write)[i] =
+ (int32) ((int64 *) data)[i];
+ if( (int64) ((int32 *) buf_to_write)[i] != ((int64 *) data)[i] )
+ {
+ _TIFFfree( buf_to_write );
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Value exceeds 32bit range of output type." );
+ return 0;
+ }
+ }
+ }
+ else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
+ || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
+ {
+ tmsize_t i;
+
+ for( i = 0; i < count; i++ )
+ {
+ ((uint32 *) buf_to_write)[i] =
+ (uint32) ((uint64 *) data)[i];
+ if( (uint64) ((uint32 *) buf_to_write)[i] != ((uint64 *) data)[i] )
+ {
+ _TIFFfree( buf_to_write );
+ TIFFErrorExt( tif->tif_clientdata, module,
+ "Value exceeds 32bit range of output type." );
+ return 0;
+ }
+ }
+ }
+
+ if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
+ {
+ if( TIFFDataWidth(datatype) == 2 )
+ TIFFSwabArrayOfShort( (uint16 *) buf_to_write, count );
+ else if( TIFFDataWidth(datatype) == 4 )
+ TIFFSwabArrayOfLong( (uint32 *) buf_to_write, count );
+ else if( TIFFDataWidth(datatype) == 8 )
+ TIFFSwabArrayOfLong8( (uint64 *) buf_to_write, count );
+ }
+
+/* -------------------------------------------------------------------- */
+/* Is this a value that fits into the directory entry? */
+/* -------------------------------------------------------------------- */
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ if( TIFFDataWidth(datatype) * count <= 4 )
+ {
+ entry_offset = read_offset + 8;
+ value_in_entry = 1;
+ }
+ }
+ else
+ {
+ if( TIFFDataWidth(datatype) * count <= 8 )
+ {
+ entry_offset = read_offset + 12;
+ value_in_entry = 1;
+ }
+ }
+
+/* -------------------------------------------------------------------- */
+/* If the tag type, and count match, then we just write it out */
+/* over the old values without altering the directory entry at */
+/* all. */
+/* -------------------------------------------------------------------- */
+ if( entry_count == (uint64)count && entry_type == (uint16) datatype )
+ {
+ if (!SeekOK(tif, entry_offset)) {
+ _TIFFfree( buf_to_write );
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+ if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
+ _TIFFfree( buf_to_write );
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing directory link");
+ return (0);
+ }
+
+ _TIFFfree( buf_to_write );
+ return 1;
+ }
+
+/* -------------------------------------------------------------------- */
+/* Otherwise, we write the new tag data at the end of the file. */
+/* -------------------------------------------------------------------- */
+ if( !value_in_entry )
+ {
+ entry_offset = TIFFSeekFile(tif,0,SEEK_END);
+
+ if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
+ _TIFFfree( buf_to_write );
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Error writing directory link");
+ return (0);
+ }
+
+ _TIFFfree( buf_to_write );
+ }
+ else
+ {
+ memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
+ }
+
+/* -------------------------------------------------------------------- */
+/* Adjust the directory entry. */
+/* -------------------------------------------------------------------- */
+ entry_type = datatype;
+ memcpy( direntry_raw + 2, &entry_type, sizeof(uint16) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabShort( (uint16 *) (direntry_raw + 2) );
+
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ uint32 value;
+
+ value = (uint32) entry_count;
+ memcpy( direntry_raw + 4, &value, sizeof(uint32) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong( (uint32 *) (direntry_raw + 4) );
+
+ value = (uint32) entry_offset;
+ memcpy( direntry_raw + 8, &value, sizeof(uint32) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong( (uint32 *) (direntry_raw + 8) );
+ }
+ else
+ {
+ memcpy( direntry_raw + 4, &entry_count, sizeof(uint64) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8( (uint64 *) (direntry_raw + 4) );
+
+ memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64) );
+ if (tif->tif_flags&TIFF_SWAB)
+ TIFFSwabLong8( (uint64 *) (direntry_raw + 12) );
+ }
+
+/* -------------------------------------------------------------------- */
+/* Write the directory entry out to disk. */
+/* -------------------------------------------------------------------- */
+ if (!SeekOK(tif, read_offset )) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Seek error accessing TIFF directory",
+ tif->tif_name);
+ return 0;
+ }
+
+ if (!WriteOK(tif, direntry_raw,dirsize))
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: Can not write TIFF directory entry.",
+ tif->tif_name);
+ return 0;
+ }
+
+ return 1;
+}
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_dumpmode.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dumpmode.c
new file mode 100644
index 0000000000..78ab03f608
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_dumpmode.c
@@ -0,0 +1,146 @@
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_dumpmode.c,v 1.14 2011-04-02 20:54:09 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * "Null" Compression Algorithm Support.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+static int
+DumpFixupTags(TIFF* tif)
+{
+ (void) tif;
+ return (1);
+}
+
+/*
+ * Encode a hunk of pixels.
+ */
+static int
+DumpModeEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s)
+{
+ (void) s;
+ while (cc > 0) {
+ tmsize_t n;
+
+ n = cc;
+ if (tif->tif_rawcc + n > tif->tif_rawdatasize)
+ n = tif->tif_rawdatasize - tif->tif_rawcc;
+
+ assert( n > 0 );
+
+ /*
+ * Avoid copy if client has setup raw
+ * data buffer to avoid extra copy.
+ */
+ if (tif->tif_rawcp != pp)
+ _TIFFmemcpy(tif->tif_rawcp, pp, n);
+ tif->tif_rawcp += n;
+ tif->tif_rawcc += n;
+ pp += n;
+ cc -= n;
+ if (tif->tif_rawcc >= tif->tif_rawdatasize &&
+ !TIFFFlushData1(tif))
+ return (-1);
+ }
+ return (1);
+}
+
+/*
+ * Decode a hunk of pixels.
+ */
+static int
+DumpModeDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ static const char module[] = "DumpModeDecode";
+ (void) s;
+ if (tif->tif_rawcc < cc) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+"Not enough data for scanline %lu, expected a request for at most %I64d bytes, got a request for %I64d bytes",
+ (unsigned long) tif->tif_row,
+ (signed __int64) tif->tif_rawcc,
+ (signed __int64) cc);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+"Not enough data for scanline %lu, expected a request for at most %lld bytes, got a request for %lld bytes",
+ (unsigned long) tif->tif_row,
+ (signed long long) tif->tif_rawcc,
+ (signed long long) cc);
+#endif
+ return (0);
+ }
+ /*
+ * Avoid copy if client has setup raw
+ * data buffer to avoid extra copy.
+ */
+ if (tif->tif_rawcp != buf)
+ _TIFFmemcpy(buf, tif->tif_rawcp, cc);
+ tif->tif_rawcp += cc;
+ tif->tif_rawcc -= cc;
+ return (1);
+}
+
+/*
+ * Seek forwards nrows in the current strip.
+ */
+static int
+DumpModeSeek(TIFF* tif, uint32 nrows)
+{
+ tif->tif_rawcp += nrows * tif->tif_scanlinesize;
+ tif->tif_rawcc -= nrows * tif->tif_scanlinesize;
+ return (1);
+}
+
+/*
+ * Initialize dump mode.
+ */
+int
+TIFFInitDumpMode(TIFF* tif, int scheme)
+{
+ (void) scheme;
+ tif->tif_fixuptags = DumpFixupTags;
+ tif->tif_decoderow = DumpModeDecode;
+ tif->tif_decodestrip = DumpModeDecode;
+ tif->tif_decodetile = DumpModeDecode;
+ tif->tif_encoderow = DumpModeEncode;
+ tif->tif_encodestrip = DumpModeEncode;
+ tif->tif_encodetile = DumpModeEncode;
+ tif->tif_seek = DumpModeSeek;
+ return (1);
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_error.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_error.c
new file mode 100644
index 0000000000..3a478c328e
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_error.c
@@ -0,0 +1,85 @@
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_error.c,v 1.5 2010-03-10 18:56:48 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+/*TIFFErrorHandlerExt _TIFFerrorHandlerExt = NULL;*/
+/* Modify here for use _TIFFerrorHandlerExt by Sunliang.Liu 20090715 */
+TIFFErrorHandler _TIFFerrorHandler = NULL;
+
+TIFFErrorHandler
+TIFFSetErrorHandler(TIFFErrorHandler handler)
+{
+ TIFFErrorHandler prev = _TIFFerrorHandler;
+ _TIFFerrorHandler = handler;
+ return (prev);
+}
+
+TIFFErrorHandlerExt
+TIFFSetErrorHandlerExt(TIFFErrorHandlerExt handler)
+{
+ TIFFErrorHandlerExt prev = _TIFFerrorHandlerExt;
+ _TIFFerrorHandlerExt = handler;
+ return (prev);
+}
+
+void
+TIFFError(const char* module, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ if (_TIFFerrorHandler)
+ (*_TIFFerrorHandler)(module, fmt, ap);
+ if (_TIFFerrorHandlerExt)
+ (*_TIFFerrorHandlerExt)(0, module, fmt, ap);
+ va_end(ap);
+}
+
+void
+TIFFErrorExt(thandle_t fd, const char* module, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ if (_TIFFerrorHandler)
+ (*_TIFFerrorHandler)(module, fmt, ap);
+ if (_TIFFerrorHandlerExt)
+ (*_TIFFerrorHandlerExt)(fd, module, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_extension.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_extension.c
new file mode 100644
index 0000000000..474cd790cd
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_extension.c
@@ -0,0 +1,120 @@
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_extension.c,v 1.7 2010-03-10 18:56:48 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Various routines support external extension of the tag set, and other
+ * application extension capabilities.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+int TIFFGetTagListCount( TIFF *tif )
+
+{
+ TIFFDirectory* td = &tif->tif_dir;
+
+ return td->td_customValueCount;
+}
+
+uint32 TIFFGetTagListEntry( TIFF *tif, int tag_index )
+
+{
+ TIFFDirectory* td = &tif->tif_dir;
+
+ if( tag_index < 0 || tag_index >= td->td_customValueCount )
+ return (uint32)(-1);
+ else
+ return td->td_customValues[tag_index].info->field_tag;
+}
+
+/*
+** This provides read/write access to the TIFFTagMethods within the TIFF
+** structure to application code without giving access to the private
+** TIFF structure.
+*/
+TIFFTagMethods *TIFFAccessTagMethods( TIFF *tif )
+
+{
+ return &(tif->tif_tagmethods);
+}
+
+void *TIFFGetClientInfo( TIFF *tif, const char *name )
+
+{
+ TIFFClientInfoLink *link = tif->tif_clientinfo;
+
+ while( link != NULL && strcmp(link->name,name) != 0 )
+ link = link->next;
+
+ if( link != NULL )
+ return link->data;
+ else
+ return NULL;
+}
+
+void TIFFSetClientInfo( TIFF *tif, void *data, const char *name )
+
+{
+ TIFFClientInfoLink *link = tif->tif_clientinfo;
+
+ /*
+ ** Do we have an existing link with this name? If so, just
+ ** set it.
+ */
+ while( link != NULL && strcmp(link->name,name) != 0 )
+ link = link->next;
+
+ if( link != NULL )
+ {
+ link->data = data;
+ return;
+ }
+
+ /*
+ ** Create a new link.
+ */
+
+ link = (TIFFClientInfoLink *) _TIFFmalloc(sizeof(TIFFClientInfoLink));
+ assert (link != NULL);
+ link->next = tif->tif_clientinfo;
+ link->name = (char *) _TIFFmalloc((tmsize_t)(strlen(name)+1));
+ assert (link->name != NULL);
+ strcpy(link->name, name);
+ link->data = data;
+
+ tif->tif_clientinfo = link;
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.c
new file mode 100644
index 0000000000..986a3f48b9
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.c
@@ -0,0 +1,1625 @@
+/* $Id: tif_fax3.c,v 1.74 2012-06-21 02:01:31 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1990-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#ifdef CCITT_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * CCITT Group 3 (T.4) and Group 4 (T.6) Compression Support.
+ *
+ * This file contains support for decoding and encoding TIFF
+ * compression algorithms 2, 3, 4, and 32771.
+ *
+ * Decoder support is derived, with permission, from the code
+ * in Frank Cringle's viewfax program;
+ * Copyright (C) 1990, 1995 Frank D. Cringle.
+ */
+#include "tif_fax3.h"
+#define G3CODES
+#include "t4.h"
+#include <stdio.h>
+
+/*
+ * Compression+decompression state blocks are
+ * derived from this ``base state'' block.
+ */
+typedef struct {
+ int rw_mode; /* O_RDONLY for decode, else encode */
+ int mode; /* operating mode */
+ tmsize_t rowbytes; /* bytes in a decoded scanline */
+ uint32 rowpixels; /* pixels in a scanline */
+
+ uint16 cleanfaxdata; /* CleanFaxData tag */
+ uint32 badfaxrun; /* BadFaxRun tag */
+ uint32 badfaxlines; /* BadFaxLines tag */
+ uint32 groupoptions; /* Group 3/4 options tag */
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+ TIFFPrintMethod printdir; /* super-class method */
+} Fax3BaseState;
+#define Fax3State(tif) ((Fax3BaseState*) (tif)->tif_data)
+
+typedef enum { G3_1D, G3_2D } Ttag;
+typedef struct {
+ Fax3BaseState b;
+
+ /* Decoder state info */
+ const unsigned char* bitmap; /* bit reversal table */
+ uint32 data; /* current i/o byte/word */
+ int bit; /* current i/o bit in byte */
+ int EOLcnt; /* count of EOL codes recognized */
+ TIFFFaxFillFunc fill; /* fill routine */
+ uint32* runs; /* b&w runs for current/previous row */
+ uint32* refruns; /* runs for reference line */
+ uint32* curruns; /* runs for current line */
+
+ /* Encoder state info */
+ Ttag tag; /* encoding state */
+ unsigned char* refline; /* reference line for 2d decoding */
+ int k; /* #rows left that can be 2d encoded */
+ int maxk; /* max #rows that can be 2d encoded */
+
+ int line;
+} Fax3CodecState;
+#define DecoderState(tif) ((Fax3CodecState*) Fax3State(tif))
+#define EncoderState(tif) ((Fax3CodecState*) Fax3State(tif))
+
+#define is2DEncoding(sp) (sp->b.groupoptions & GROUP3OPT_2DENCODING)
+#define isAligned(p,t) ((((size_t)(p)) & (sizeof (t)-1)) == 0)
+
+/*
+ * Group 3 and Group 4 Decoding.
+ */
+
+/*
+ * These macros glue the TIFF library state to
+ * the state expected by Frank's decoder.
+ */
+#define DECLARE_STATE(tif, sp, mod) \
+ static const char module[] = mod; \
+ Fax3CodecState* sp = DecoderState(tif); \
+ int a0; /* reference element */ \
+ int lastx = sp->b.rowpixels; /* last element in row */ \
+ uint32 BitAcc; /* bit accumulator */ \
+ int BitsAvail; /* # valid bits in BitAcc */ \
+ int RunLength; /* length of current run */ \
+ unsigned char* cp; /* next byte of input data */ \
+ unsigned char* ep; /* end of input data */ \
+ uint32* pa; /* place to stuff next run */ \
+ uint32* thisrun; /* current row's run array */ \
+ int EOLcnt; /* # EOL codes recognized */ \
+ const unsigned char* bitmap = sp->bitmap; /* input data bit reverser */ \
+ const TIFFFaxTabEnt* TabEnt
+#define DECLARE_STATE_2D(tif, sp, mod) \
+ DECLARE_STATE(tif, sp, mod); \
+ int b1; /* next change on prev line */ \
+ uint32* pb /* next run in reference line */\
+/*
+ * Load any state that may be changed during decoding.
+ */
+#define CACHE_STATE(tif, sp) do { \
+ BitAcc = sp->data; \
+ BitsAvail = sp->bit; \
+ EOLcnt = sp->EOLcnt; \
+ cp = (unsigned char*) tif->tif_rawcp; \
+ ep = cp + tif->tif_rawcc; \
+} while (0)
+/*
+ * Save state possibly changed during decoding.
+ */
+#define UNCACHE_STATE(tif, sp) do { \
+ sp->bit = BitsAvail; \
+ sp->data = BitAcc; \
+ sp->EOLcnt = EOLcnt; \
+ tif->tif_rawcc -= (tmsize_t)((uint8*) cp - tif->tif_rawcp); \
+ tif->tif_rawcp = (uint8*) cp; \
+} while (0)
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+Fax3PreDecode(TIFF* tif, uint16 s)
+{
+ Fax3CodecState* sp = DecoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+ sp->bit = 0; /* force initial read */
+ sp->data = 0;
+ sp->EOLcnt = 0; /* force initial scan for EOL */
+ /*
+ * Decoder assumes lsb-to-msb bit order. Note that we select
+ * this here rather than in Fax3SetupState so that viewers can
+ * hold the image open, fiddle with the FillOrder tag value,
+ * and then re-decode the image. Otherwise they'd need to close
+ * and open the image to get the state reset.
+ */
+ sp->bitmap =
+ TIFFGetBitRevTable(tif->tif_dir.td_fillorder != FILLORDER_LSB2MSB);
+ if (sp->refruns) { /* init reference line to white */
+ sp->refruns[0] = (uint32) sp->b.rowpixels;
+ sp->refruns[1] = 0;
+ }
+ sp->line = 0;
+ return (1);
+}
+
+/*
+ * Routine for handling various errors/conditions.
+ * Note how they are "glued into the decoder" by
+ * overriding the definitions used by the decoder.
+ */
+
+static void
+Fax3Unexpected(const char* module, TIFF* tif, uint32 line, uint32 a0)
+{
+ TIFFErrorExt(tif->tif_clientdata, module, "Bad code word at line %u of %s %u (x %u)",
+ line, isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+ a0);
+}
+#define unexpected(table, a0) Fax3Unexpected(module, tif, sp->line, a0)
+
+static void
+Fax3Extension(const char* module, TIFF* tif, uint32 line, uint32 a0)
+{
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Uncompressed data (not supported) at line %u of %s %u (x %u)",
+ line, isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+ a0);
+}
+#define extension(a0) Fax3Extension(module, tif, sp->line, a0)
+
+static void
+Fax3BadLength(const char* module, TIFF* tif, uint32 line, uint32 a0, uint32 lastx)
+{
+ TIFFWarningExt(tif->tif_clientdata, module, "%s at line %u of %s %u (got %u, expected %u)",
+ a0 < lastx ? "Premature EOL" : "Line length mismatch",
+ line, isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+ a0, lastx);
+}
+#define badlength(a0,lastx) Fax3BadLength(module, tif, sp->line, a0, lastx)
+
+static void
+Fax3PrematureEOF(const char* module, TIFF* tif, uint32 line, uint32 a0)
+{
+ TIFFWarningExt(tif->tif_clientdata, module, "Premature EOF at line %u of %s %u (x %u)",
+ line, isTiled(tif) ? "tile" : "strip",
+ (isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip),
+ a0);
+}
+#define prematureEOF(a0) Fax3PrematureEOF(module, tif, sp->line, a0)
+
+#define Nop
+
+/*
+ * Decode the requested amount of G3 1D-encoded data.
+ */
+static int
+Fax3Decode1D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+ DECLARE_STATE(tif, sp, "Fax3Decode1D");
+ (void) s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ thisrun = sp->curruns;
+ while (occ > 0) {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
+ printf("-------------------- %d\n", tif->tif_row);
+ fflush(stdout);
+#endif
+ SYNC_EOL(EOF1D);
+ EXPAND1D(EOF1Da);
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOF1D: /* premature EOF */
+ CLEANUP_RUNS();
+ EOF1Da: /* premature EOF */
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ UNCACHE_STATE(tif, sp);
+ return (-1);
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+
+#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; }
+/*
+ * Decode the requested amount of G3 2D-encoded data.
+ */
+static int
+Fax3Decode2D(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+ DECLARE_STATE_2D(tif, sp, "Fax3Decode2D");
+ int is1D; /* current line is 1d/2d-encoded */
+ (void) s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ while (occ > 0) {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun = sp->curruns;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08X, BitsAvail = %d EOLcnt = %d",
+ BitAcc, BitsAvail, EOLcnt);
+#endif
+ SYNC_EOL(EOF2D);
+ NeedBits8(1, EOF2D);
+ is1D = GetBits(1); /* 1D/2D-encoding tag bit */
+ ClrBits(1);
+#ifdef FAX3_DEBUG
+ printf(" %s\n-------------------- %d\n",
+ is1D ? "1D" : "2D", tif->tif_row);
+ fflush(stdout);
+#endif
+ pb = sp->refruns;
+ b1 = *pb++;
+ if (is1D)
+ EXPAND1D(EOF2Da);
+ else
+ EXPAND2D(EOF2Da);
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ SETVALUE(0); /* imaginary change for reference */
+ SWAP(uint32*, sp->curruns, sp->refruns);
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOF2D: /* premature EOF */
+ CLEANUP_RUNS();
+ EOF2Da: /* premature EOF */
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ UNCACHE_STATE(tif, sp);
+ return (-1);
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+#undef SWAP
+
+/*
+ * The ZERO & FILL macros must handle spans < 2*sizeof(long) bytes.
+ * For machines with 64-bit longs this is <16 bytes; otherwise
+ * this is <8 bytes. We optimize the code here to reflect the
+ * machine characteristics.
+ */
+#if SIZEOF_UNSIGNED_LONG == 8
+# define FILL(n, cp) \
+ switch (n) { \
+ case 15:(cp)[14] = 0xff; case 14:(cp)[13] = 0xff; case 13: (cp)[12] = 0xff;\
+ case 12:(cp)[11] = 0xff; case 11:(cp)[10] = 0xff; case 10: (cp)[9] = 0xff;\
+ case 9: (cp)[8] = 0xff; case 8: (cp)[7] = 0xff; case 7: (cp)[6] = 0xff;\
+ case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; case 4: (cp)[3] = 0xff;\
+ case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
+ case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \
+ }
+# define ZERO(n, cp) \
+ switch (n) { \
+ case 15:(cp)[14] = 0; case 14:(cp)[13] = 0; case 13: (cp)[12] = 0; \
+ case 12:(cp)[11] = 0; case 11:(cp)[10] = 0; case 10: (cp)[9] = 0; \
+ case 9: (cp)[8] = 0; case 8: (cp)[7] = 0; case 7: (cp)[6] = 0; \
+ case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; case 4: (cp)[3] = 0; \
+ case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \
+ case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \
+ }
+#else
+# define FILL(n, cp) \
+ switch (n) { \
+ case 7: (cp)[6] = 0xff; case 6: (cp)[5] = 0xff; case 5: (cp)[4] = 0xff; \
+ case 4: (cp)[3] = 0xff; case 3: (cp)[2] = 0xff; case 2: (cp)[1] = 0xff; \
+ case 1: (cp)[0] = 0xff; (cp) += (n); case 0: ; \
+ }
+# define ZERO(n, cp) \
+ switch (n) { \
+ case 7: (cp)[6] = 0; case 6: (cp)[5] = 0; case 5: (cp)[4] = 0; \
+ case 4: (cp)[3] = 0; case 3: (cp)[2] = 0; case 2: (cp)[1] = 0; \
+ case 1: (cp)[0] = 0; (cp) += (n); case 0: ; \
+ }
+#endif
+
+/*
+ * Bit-fill a row according to the white/black
+ * runs generated during G3/G4 decoding.
+ */
+void
+_TIFFFax3fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
+{
+ static const unsigned char _fillmasks[] =
+ { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
+ unsigned char* cp;
+ uint32 x, bx, run,bx_;/* add bx_ = 8-bx for avoid ms evc compiler bug*/
+ int32 n, nw;
+ long* lp;
+
+ if ((erun-runs)&1)
+ *erun++ = 0;
+ x = 0;
+ for (; runs < erun; runs += 2) {
+ run = runs[0];
+ if (x+run > lastx || run > lastx )
+ run = runs[0] = (uint32) (lastx - x);
+ if (run) {
+ cp = buf + (x>>3);
+ bx = x&7;
+// if (run > 8-bx) {
+// if (bx) { /* align to byte boundary */
+// *cp++ &= 0xff << (8-bx);
+// run -= 8-bx;
+// }
+//Modify by Sunliang.Liu 20090804
+//Detail: For avoid ms evc compiler bug in WCE ARMV4(I) Release
+ bx_ = 8-bx;
+ if (run > bx_) {
+ if (bx) { /* align to byte boundary */
+ *cp++ &= 0xff << bx_;
+ run -= bx_;
+ }
+ if( (n = run >> 3) != 0 ) { /* multiple bytes to fill */
+ if ((n/sizeof (long)) > 1) {
+ /*
+ * Align to longword boundary and fill.
+ */
+ for (; n && !isAligned(cp, long); n--)
+ *cp++ = 0x00;
+ lp = (long*) cp;
+ nw = (int32)(n / sizeof (long));
+ n -= nw * sizeof (long);
+ do {
+ *lp++ = 0L;
+ } while (--nw);
+ cp = (unsigned char*) lp;
+ }
+#ifdef FAX3_DEBUG
+ printf("_TIFFFax3fillruns ZERO: %d\n",n);
+#endif
+ ZERO(n, cp);
+ run &= 7;
+ }
+ if (run)
+ cp[0] &= 0xff >> run;
+ } else
+ cp[0] &= ~(_fillmasks[run]>>bx);
+ x += runs[0];
+ }
+ run = runs[1];
+ if (x+run > lastx || run > lastx )
+ run = runs[1] = lastx - x;
+ if (run) {
+ cp = buf + (x>>3);
+ bx = x&7;
+ if (run > 8-bx) {
+ if (bx) { /* align to byte boundary */
+ *cp++ |= 0xff >> bx;
+ run -= 8-bx;
+ }
+ if( (n = run>>3) != 0 ) { /* multiple bytes to fill */
+ if ((n/sizeof (long)) > 1) {
+ /*
+ * Align to longword boundary and fill.
+ */
+ for (; n && !isAligned(cp, long); n--)
+ *cp++ = 0xff;
+ lp = (long*) cp;
+ nw = (int32)(n / sizeof (long));
+ n -= nw * sizeof (long);
+ do {
+ *lp++ = -1L;
+ } while (--nw);
+ cp = (unsigned char*) lp;
+ }
+#ifdef FAX3_DEBUG
+ printf("_TIFFFax3fillruns FILL: %d\n",n);
+#endif
+ FILL(n, cp);
+ run &= 7;
+ }
+ if (run)
+ cp[0] |= 0xff00 >> run;
+ } else
+ cp[0] |= _fillmasks[run]>>bx;
+ x += runs[1];
+ }
+ }
+ assert(x == lastx);
+}
+#undef ZERO
+#undef FILL
+
+static int
+Fax3FixupTags(TIFF* tif)
+{
+ (void) tif;
+ return (1);
+}
+
+/*
+ * Setup G3/G4-related compression/decompression state
+ * before data is processed. This routine is called once
+ * per image -- it sets up different state based on whether
+ * or not decoding or encoding is being done and whether
+ * 1D- or 2D-encoded data is involved.
+ */
+static int
+Fax3SetupState(TIFF* tif)
+{
+ static const char module[] = "Fax3SetupState";
+ TIFFDirectory* td = &tif->tif_dir;
+ Fax3BaseState* sp = Fax3State(tif);
+ int needsRefLine;
+ Fax3CodecState* dsp = (Fax3CodecState*) Fax3State(tif);
+ tmsize_t rowbytes;
+ uint32 rowpixels, nruns;
+
+ if (td->td_bitspersample != 1) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Bits/sample must be 1 for Group 3/4 encoding/decoding");
+ return (0);
+ }
+ /*
+ * Calculate the scanline/tile widths.
+ */
+ if (isTiled(tif)) {
+ rowbytes = TIFFTileRowSize(tif);
+ rowpixels = td->td_tilewidth;
+ } else {
+ rowbytes = TIFFScanlineSize(tif);
+ rowpixels = td->td_imagewidth;
+ }
+ sp->rowbytes = rowbytes;
+ sp->rowpixels = rowpixels;
+ /*
+ * Allocate any additional space required for decoding/encoding.
+ */
+ needsRefLine = (
+ (sp->groupoptions & GROUP3OPT_2DENCODING) ||
+ td->td_compression == COMPRESSION_CCITTFAX4
+ );
+
+ /*
+ Assure that allocation computations do not overflow.
+
+ TIFFroundup and TIFFSafeMultiply return zero on integer overflow
+ */
+ dsp->runs=(uint32*) NULL;
+ nruns = TIFFroundup_32(rowpixels,32);
+ if (needsRefLine) {
+ nruns = TIFFSafeMultiply(uint32,nruns,2);
+ }
+ if ((nruns == 0) || (TIFFSafeMultiply(uint32,nruns,2) == 0)) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Row pixels integer overflow (rowpixels %u)",
+ rowpixels);
+ return (0);
+ }
+ dsp->runs = (uint32*) _TIFFCheckMalloc(tif,
+ TIFFSafeMultiply(uint32,nruns,2),
+ sizeof (uint32),
+ "for Group 3/4 run arrays");
+ if (dsp->runs == NULL)
+ return (0);
+ memset( dsp->runs, 0, TIFFSafeMultiply(uint32,nruns,2)*sizeof(uint32));
+ dsp->curruns = dsp->runs;
+ if (needsRefLine)
+ dsp->refruns = dsp->runs + nruns;
+ else
+ dsp->refruns = NULL;
+ if (td->td_compression == COMPRESSION_CCITTFAX3
+ && is2DEncoding(dsp)) { /* NB: default is 1D routine */
+ tif->tif_decoderow = Fax3Decode2D;
+ tif->tif_decodestrip = Fax3Decode2D;
+ tif->tif_decodetile = Fax3Decode2D;
+ }
+
+ if (needsRefLine) { /* 2d encoding */
+ Fax3CodecState* esp = EncoderState(tif);
+ /*
+ * 2d encoding requires a scanline
+ * buffer for the ``reference line''; the
+ * scanline against which delta encoding
+ * is referenced. The reference line must
+ * be initialized to be ``white'' (done elsewhere).
+ */
+ esp->refline = (unsigned char*) _TIFFmalloc(rowbytes);
+ if (esp->refline == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for Group 3/4 reference line");
+ return (0);
+ }
+ } else /* 1d encoding */
+ EncoderState(tif)->refline = NULL;
+
+ return (1);
+}
+
+/*
+ * CCITT Group 3 FAX Encoding.
+ */
+
+#define Fax3FlushBits(tif, sp) { \
+ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
+ (void) TIFFFlushData1(tif); \
+ *(tif)->tif_rawcp++ = (uint8) (sp)->data; \
+ (tif)->tif_rawcc++; \
+ (sp)->data = 0, (sp)->bit = 8; \
+}
+#define _FlushBits(tif) { \
+ if ((tif)->tif_rawcc >= (tif)->tif_rawdatasize) \
+ (void) TIFFFlushData1(tif); \
+ *(tif)->tif_rawcp++ = (uint8) data; \
+ (tif)->tif_rawcc++; \
+ data = 0, bit = 8; \
+}
+static const int _msbmask[9] =
+ { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
+#define _PutBits(tif, bits, length) { \
+ while (length > bit) { \
+ data |= bits >> (length - bit); \
+ length -= bit; \
+ _FlushBits(tif); \
+ } \
+ assert( length < 9 ); \
+ data |= (bits & _msbmask[length]) << (bit - length); \
+ bit -= length; \
+ if (bit == 0) \
+ _FlushBits(tif); \
+}
+
+/*
+ * Write a variable-length bit-value to
+ * the output stream. Values are
+ * assumed to be at most 16 bits.
+ */
+static void
+Fax3PutBits(TIFF* tif, unsigned int bits, unsigned int length)
+{
+ Fax3CodecState* sp = EncoderState(tif);
+ unsigned int bit = sp->bit;
+ int data = sp->data;
+
+ _PutBits(tif, bits, length);
+
+ sp->data = data;
+ sp->bit = bit;
+}
+
+/*
+ * Write a code to the output stream.
+ */
+#define putcode(tif, te) Fax3PutBits(tif, (te)->code, (te)->length)
+
+#ifdef FAX3_DEBUG
+#define DEBUG_COLOR(w) (tab == TIFFFaxWhiteCodes ? w "W" : w "B")
+#define DEBUG_PRINT(what,len) { \
+ int t; \
+ printf("%08X/%-2d: %s%5d\t", data, bit, DEBUG_COLOR(what), len); \
+ for (t = length-1; t >= 0; t--) \
+ putchar(code & (1<<t) ? '1' : '0'); \
+ putchar('\n'); \
+}
+#endif
+
+/*
+ * Write the sequence of codes that describes
+ * the specified span of zero's or one's. The
+ * appropriate table that holds the make-up and
+ * terminating codes is supplied.
+ */
+static void
+putspan(TIFF* tif, int32 span, const tableentry* tab)
+{
+ Fax3CodecState* sp = EncoderState(tif);
+ unsigned int bit = sp->bit;
+ int data = sp->data;
+ unsigned int code, length;
+
+ while (span >= 2624) {
+ const tableentry* te = &tab[63 + (2560>>6)];
+ code = te->code, length = te->length;
+#ifdef FAX3_DEBUG
+ DEBUG_PRINT("MakeUp", te->runlen);
+#endif
+ _PutBits(tif, code, length);
+ span -= te->runlen;
+ }
+ if (span >= 64) {
+ const tableentry* te = &tab[63 + (span>>6)];
+ assert(te->runlen == 64*(span>>6));
+ code = te->code, length = te->length;
+#ifdef FAX3_DEBUG
+ DEBUG_PRINT("MakeUp", te->runlen);
+#endif
+ _PutBits(tif, code, length);
+ span -= te->runlen;
+ }
+ code = tab[span].code, length = tab[span].length;
+#ifdef FAX3_DEBUG
+ DEBUG_PRINT(" Term", tab[span].runlen);
+#endif
+ _PutBits(tif, code, length);
+
+ sp->data = data;
+ sp->bit = bit;
+}
+
+/*
+ * Write an EOL code to the output stream. The zero-fill
+ * logic for byte-aligning encoded scanlines is handled
+ * here. We also handle writing the tag bit for the next
+ * scanline when doing 2d encoding.
+ */
+static void
+Fax3PutEOL(TIFF* tif)
+{
+ Fax3CodecState* sp = EncoderState(tif);
+ unsigned int bit = sp->bit;
+ int data = sp->data;
+ unsigned int code, length, tparm;
+
+ if (sp->b.groupoptions & GROUP3OPT_FILLBITS) {
+ /*
+ * Force bit alignment so EOL will terminate on
+ * a byte boundary. That is, force the bit alignment
+ * to 16-12 = 4 before putting out the EOL code.
+ */
+ int align = 8 - 4;
+ if (align != sp->bit) {
+ if (align > sp->bit)
+ align = sp->bit + (8 - align);
+ else
+ align = sp->bit - align;
+ code = 0;
+ tparm=align;
+ _PutBits(tif, 0, tparm);
+ }
+ }
+ code = EOL, length = 12;
+ if (is2DEncoding(sp))
+ code = (code<<1) | (sp->tag == G3_1D), length++;
+ _PutBits(tif, code, length);
+
+ sp->data = data;
+ sp->bit = bit;
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+Fax3PreEncode(TIFF* tif, uint16 s)
+{
+ Fax3CodecState* sp = EncoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+ sp->bit = 8;
+ sp->data = 0;
+ sp->tag = G3_1D;
+ /*
+ * This is necessary for Group 4; otherwise it isn't
+ * needed because the first scanline of each strip ends
+ * up being copied into the refline.
+ */
+ if (sp->refline)
+ _TIFFmemset(sp->refline, 0x00, sp->b.rowbytes);
+ if (is2DEncoding(sp)) {
+ float res = tif->tif_dir.td_yresolution;
+ /*
+ * The CCITT spec says that when doing 2d encoding, you
+ * should only do it on K consecutive scanlines, where K
+ * depends on the resolution of the image being encoded
+ * (2 for <= 200 lpi, 4 for > 200 lpi). Since the directory
+ * code initializes td_yresolution to 0, this code will
+ * select a K of 2 unless the YResolution tag is set
+ * appropriately. (Note also that we fudge a little here
+ * and use 150 lpi to avoid problems with units conversion.)
+ */
+ if (tif->tif_dir.td_resolutionunit == RESUNIT_CENTIMETER)
+ res *= 2.54f; /* convert to inches */
+ sp->maxk = (res > 150 ? 4 : 2);
+ sp->k = sp->maxk-1;
+ } else
+ sp->k = sp->maxk = 0;
+ sp->line = 0;
+ return (1);
+}
+
+static const unsigned char zeroruns[256] = {
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, /* 0x00 - 0x0f */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0x10 - 0x1f */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x20 - 0x2f */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0x30 - 0x3f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x50 - 0x5f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x70 - 0x7f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xf0 - 0xff */
+};
+static const unsigned char oneruns[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 - 0x0f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x6f */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x80 - 0x8f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x90 - 0x9f */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xa0 - 0xaf */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0xb0 - 0xbf */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xc0 - 0xcf */
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 0xd0 - 0xdf */
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* 0xe0 - 0xef */
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, /* 0xf0 - 0xff */
+};
+
+/*
+ * On certain systems it pays to inline
+ * the routines that find pixel spans.
+ */
+#ifdef VAXC
+static int32 find0span(unsigned char*, int32, int32);
+static int32 find1span(unsigned char*, int32, int32);
+#pragma inline(find0span,find1span)
+#endif
+
+/*
+ * Find a span of ones or zeros using the supplied
+ * table. The ``base'' of the bit string is supplied
+ * along with the start+end bit indices.
+ */
+inline static int32
+find0span(unsigned char* bp, int32 bs, int32 be)
+{
+ int32 bits = be - bs;
+ int32 n, span;
+
+ bp += bs>>3;
+ /*
+ * Check partial byte on lhs.
+ */
+ if (bits > 0 && (n = (bs & 7))) {
+ span = zeroruns[(*bp << n) & 0xff];
+ if (span > 8-n) /* table value too generous */
+ span = 8-n;
+ if (span > bits) /* constrain span to bit range */
+ span = bits;
+ if (n+span < 8) /* doesn't extend to edge of byte */
+ return (span);
+ bits -= span;
+ bp++;
+ } else
+ span = 0;
+ if (bits >= (int32)(2 * 8 * sizeof(long))) {
+ long* lp;
+ /*
+ * Align to longword boundary and check longwords.
+ */
+ while (!isAligned(bp, long)) {
+ if (*bp != 0x00)
+ return (span + zeroruns[*bp]);
+ span += 8, bits -= 8;
+ bp++;
+ }
+ lp = (long*) bp;
+ while ((bits >= (int32)(8 * sizeof(long))) && (0 == *lp)) {
+ span += 8*sizeof (long), bits -= 8*sizeof (long);
+ lp++;
+ }
+ bp = (unsigned char*) lp;
+ }
+ /*
+ * Scan full bytes for all 0's.
+ */
+ while (bits >= 8) {
+ if (*bp != 0x00) /* end of run */
+ return (span + zeroruns[*bp]);
+ span += 8, bits -= 8;
+ bp++;
+ }
+ /*
+ * Check partial byte on rhs.
+ */
+ if (bits > 0) {
+ n = zeroruns[*bp];
+ span += (n > bits ? bits : n);
+ }
+ return (span);
+}
+
+inline static int32
+find1span(unsigned char* bp, int32 bs, int32 be)
+{
+ int32 bits = be - bs;
+ int32 n, span;
+
+ bp += bs>>3;
+ /*
+ * Check partial byte on lhs.
+ */
+ if (bits > 0 && (n = (bs & 7))) {
+ span = oneruns[(*bp << n) & 0xff];
+ if (span > 8-n) /* table value too generous */
+ span = 8-n;
+ if (span > bits) /* constrain span to bit range */
+ span = bits;
+ if (n+span < 8) /* doesn't extend to edge of byte */
+ return (span);
+ bits -= span;
+ bp++;
+ } else
+ span = 0;
+ if (bits >= (int32)(2 * 8 * sizeof(long))) {
+ long* lp;
+ /*
+ * Align to longword boundary and check longwords.
+ */
+ while (!isAligned(bp, long)) {
+ if (*bp != 0xff)
+ return (span + oneruns[*bp]);
+ span += 8, bits -= 8;
+ bp++;
+ }
+ lp = (long*) bp;
+ while ((bits >= (int32)(8 * sizeof(long))) && (~0 == *lp)) {
+ span += 8*sizeof (long), bits -= 8*sizeof (long);
+ lp++;
+ }
+ bp = (unsigned char*) lp;
+ }
+ /*
+ * Scan full bytes for all 1's.
+ */
+ while (bits >= 8) {
+ if (*bp != 0xff) /* end of run */
+ return (span + oneruns[*bp]);
+ span += 8, bits -= 8;
+ bp++;
+ }
+ /*
+ * Check partial byte on rhs.
+ */
+ if (bits > 0) {
+ n = oneruns[*bp];
+ span += (n > bits ? bits : n);
+ }
+ return (span);
+}
+
+/*
+ * Return the offset of the next bit in the range
+ * [bs..be] that is different from the specified
+ * color. The end, be, is returned if no such bit
+ * exists.
+ */
+#define finddiff(_cp, _bs, _be, _color) \
+ (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
+/*
+ * Like finddiff, but also check the starting bit
+ * against the end in case start > end.
+ */
+#define finddiff2(_cp, _bs, _be, _color) \
+ (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
+
+/*
+ * 1d-encode a row of pixels. The encoding is
+ * a sequence of all-white or all-black spans
+ * of pixels encoded with Huffman codes.
+ */
+static int
+Fax3Encode1DRow(TIFF* tif, unsigned char* bp, uint32 bits)
+{
+ Fax3CodecState* sp = EncoderState(tif);
+ int32 span;
+ uint32 bs = 0;
+
+ for (;;) {
+ span = find0span(bp, bs, bits); /* white span */
+ putspan(tif, span, TIFFFaxWhiteCodes);
+ bs += span;
+ if (bs >= bits)
+ break;
+ span = find1span(bp, bs, bits); /* black span */
+ putspan(tif, span, TIFFFaxBlackCodes);
+ bs += span;
+ if (bs >= bits)
+ break;
+ }
+ if (sp->b.mode & (FAXMODE_BYTEALIGN|FAXMODE_WORDALIGN)) {
+ if (sp->bit != 8) /* byte-align */
+ Fax3FlushBits(tif, sp);
+ if ((sp->b.mode&FAXMODE_WORDALIGN) &&
+ !isAligned(tif->tif_rawcp, uint16))
+ Fax3FlushBits(tif, sp);
+ }
+ return (1);
+}
+
+static const tableentry horizcode =
+ { 3, 0x1, 0 }; /* 001 */
+static const tableentry passcode =
+ { 4, 0x1, 0 }; /* 0001 */
+static const tableentry vcodes[7] = {
+ { 7, 0x03, 0 }, /* 0000 011 */
+ { 6, 0x03, 0 }, /* 0000 11 */
+ { 3, 0x03, 0 }, /* 011 */
+ { 1, 0x1, 0 }, /* 1 */
+ { 3, 0x2, 0 }, /* 010 */
+ { 6, 0x02, 0 }, /* 0000 10 */
+ { 7, 0x02, 0 } /* 0000 010 */
+};
+
+/*
+ * 2d-encode a row of pixels. Consult the CCITT
+ * documentation for the algorithm.
+ */
+static int
+Fax3Encode2DRow(TIFF* tif, unsigned char* bp, unsigned char* rp, uint32 bits)
+{
+#define PIXEL(buf,ix) ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
+ uint32 a0 = 0;
+ uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, bits, 0));
+ uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, bits, 0));
+ uint32 a2, b2;
+
+ for (;;) {
+ b2 = finddiff2(rp, b1, bits, PIXEL(rp,b1));
+ if (b2 >= a1) {
+ int32 d = b1 - a1;
+ if (!(-3 <= d && d <= 3)) { /* horizontal mode */
+ a2 = finddiff2(bp, a1, bits, PIXEL(bp,a1));
+ putcode(tif, &horizcode);
+ if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
+ putspan(tif, a1-a0, TIFFFaxWhiteCodes);
+ putspan(tif, a2-a1, TIFFFaxBlackCodes);
+ } else {
+ putspan(tif, a1-a0, TIFFFaxBlackCodes);
+ putspan(tif, a2-a1, TIFFFaxWhiteCodes);
+ }
+ a0 = a2;
+ } else { /* vertical mode */
+ putcode(tif, &vcodes[d+3]);
+ a0 = a1;
+ }
+ } else { /* pass mode */
+ putcode(tif, &passcode);
+ a0 = b2;
+ }
+ if (a0 >= bits)
+ break;
+ a1 = finddiff(bp, a0, bits, PIXEL(bp,a0));
+ b1 = finddiff(rp, a0, bits, !PIXEL(bp,a0));
+ b1 = finddiff(rp, b1, bits, PIXEL(bp,a0));
+ }
+ return (1);
+#undef PIXEL
+}
+
+/*
+ * Encode a buffer of pixels.
+ */
+static int
+Fax3Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ static const char module[] = "Fax3Encode";
+ Fax3CodecState* sp = EncoderState(tif);
+ (void) s;
+ if (cc % sp->b.rowbytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
+ return (0);
+ }
+ while (cc > 0) {
+ if ((sp->b.mode & FAXMODE_NOEOL) == 0)
+ Fax3PutEOL(tif);
+ if (is2DEncoding(sp)) {
+ if (sp->tag == G3_1D) {
+ if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
+ return (0);
+ sp->tag = G3_2D;
+ } else {
+ if (!Fax3Encode2DRow(tif, bp, sp->refline,
+ sp->b.rowpixels))
+ return (0);
+ sp->k--;
+ }
+ if (sp->k == 0) {
+ sp->tag = G3_1D;
+ sp->k = sp->maxk-1;
+ } else
+ _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
+ } else {
+ if (!Fax3Encode1DRow(tif, bp, sp->b.rowpixels))
+ return (0);
+ }
+ bp += sp->b.rowbytes;
+ cc -= sp->b.rowbytes;
+ }
+ return (1);
+}
+
+static int
+Fax3PostEncode(TIFF* tif)
+{
+ Fax3CodecState* sp = EncoderState(tif);
+
+ if (sp->bit != 8)
+ Fax3FlushBits(tif, sp);
+ return (1);
+}
+
+static void
+Fax3Close(TIFF* tif)
+{
+ if ((Fax3State(tif)->mode & FAXMODE_NORTC) == 0) {
+ Fax3CodecState* sp = EncoderState(tif);
+ unsigned int code = EOL;
+ unsigned int length = 12;
+ int i;
+
+ if (is2DEncoding(sp))
+ code = (code<<1) | (sp->tag == G3_1D), length++;
+ for (i = 0; i < 6; i++)
+ Fax3PutBits(tif, code, length);
+ Fax3FlushBits(tif, sp);
+ }
+}
+
+static void
+Fax3Cleanup(TIFF* tif)
+{
+ Fax3CodecState* sp = DecoderState(tif);
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->b.vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->b.vsetparent;
+ tif->tif_tagmethods.printdir = sp->b.printdir;
+
+ if (sp->runs)
+ _TIFFfree(sp->runs);
+ if (sp->refline)
+ _TIFFfree(sp->refline);
+
+ _TIFFfree(tif->tif_data);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+#define FIELD_BADFAXLINES (FIELD_CODEC+0)
+#define FIELD_CLEANFAXDATA (FIELD_CODEC+1)
+#define FIELD_BADFAXRUN (FIELD_CODEC+2)
+
+#define FIELD_OPTIONS (FIELD_CODEC+7)
+
+static const TIFFField faxFields[] = {
+ { TIFFTAG_FAXMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxMode", NULL },
+ { TIFFTAG_FAXFILLFUNC, 0, 0, TIFF_ANY, 0, TIFF_SETGET_OTHER, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "FaxFillFunc", NULL },
+ { TIFFTAG_BADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXLINES, TRUE, FALSE, "BadFaxLines", NULL },
+ { TIFFTAG_CLEANFAXDATA, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_CLEANFAXDATA, TRUE, FALSE, "CleanFaxData", NULL },
+ { TIFFTAG_CONSECUTIVEBADFAXLINES, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_BADFAXRUN, TRUE, FALSE, "ConsecutiveBadFaxLines", NULL }};
+static const TIFFField fax3Fields[] = {
+ { TIFFTAG_GROUP3OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group3Options", NULL },
+};
+static const TIFFField fax4Fields[] = {
+ { TIFFTAG_GROUP4OPTIONS, 1, 1, TIFF_LONG, 0, TIFF_SETGET_UINT32, TIFF_SETGET_UINT32, FIELD_OPTIONS, FALSE, FALSE, "Group4Options", NULL },
+};
+
+static int
+Fax3VSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ Fax3BaseState* sp = Fax3State(tif);
+ const TIFFField* fip;
+
+ assert(sp != 0);
+ assert(sp->vsetparent != 0);
+
+ switch (tag) {
+ case TIFFTAG_FAXMODE:
+ sp->mode = (int) va_arg(ap, int);
+ return 1; /* NB: pseudo tag */
+ case TIFFTAG_FAXFILLFUNC:
+ DecoderState(tif)->fill = va_arg(ap, TIFFFaxFillFunc);
+ return 1; /* NB: pseudo tag */
+ case TIFFTAG_GROUP3OPTIONS:
+ /* XXX: avoid reading options if compression mismatches. */
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX3)
+ sp->groupoptions = (uint32) va_arg(ap, uint32);
+ break;
+ case TIFFTAG_GROUP4OPTIONS:
+ /* XXX: avoid reading options if compression mismatches. */
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4)
+ sp->groupoptions = (uint32) va_arg(ap, uint32);
+ break;
+ case TIFFTAG_BADFAXLINES:
+ sp->badfaxlines = (uint32) va_arg(ap, uint32);
+ break;
+ case TIFFTAG_CLEANFAXDATA:
+ sp->cleanfaxdata = (uint16) va_arg(ap, uint16_vap);
+ break;
+ case TIFFTAG_CONSECUTIVEBADFAXLINES:
+ sp->badfaxrun = (uint32) va_arg(ap, uint32);
+ break;
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+
+ if ((fip = TIFFFieldWithTag(tif, tag)))
+ TIFFSetFieldBit(tif, fip->field_bit);
+ else
+ return 0;
+
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ return 1;
+}
+
+static int
+Fax3VGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ Fax3BaseState* sp = Fax3State(tif);
+
+ assert(sp != 0);
+
+ switch (tag) {
+ case TIFFTAG_FAXMODE:
+ *va_arg(ap, int*) = sp->mode;
+ break;
+ case TIFFTAG_FAXFILLFUNC:
+ *va_arg(ap, TIFFFaxFillFunc*) = DecoderState(tif)->fill;
+ break;
+ case TIFFTAG_GROUP3OPTIONS:
+ case TIFFTAG_GROUP4OPTIONS:
+ *va_arg(ap, uint32*) = sp->groupoptions;
+ break;
+ case TIFFTAG_BADFAXLINES:
+ *va_arg(ap, uint32*) = sp->badfaxlines;
+ break;
+ case TIFFTAG_CLEANFAXDATA:
+ *va_arg(ap, uint16*) = sp->cleanfaxdata;
+ break;
+ case TIFFTAG_CONSECUTIVEBADFAXLINES:
+ *va_arg(ap, uint32*) = sp->badfaxrun;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static void
+Fax3PrintDir(TIFF* tif, FILE* fd, long flags)
+{
+ Fax3BaseState* sp = Fax3State(tif);
+
+ assert(sp != 0);
+
+ (void) flags;
+ if (TIFFFieldSet(tif,FIELD_OPTIONS)) {
+ const char* sep = " ";
+ if (tif->tif_dir.td_compression == COMPRESSION_CCITTFAX4) {
+ fprintf(fd, " Group 4 Options:");
+ if (sp->groupoptions & GROUP4OPT_UNCOMPRESSED)
+ fprintf(fd, "%suncompressed data", sep);
+ } else {
+
+ fprintf(fd, " Group 3 Options:");
+ if (sp->groupoptions & GROUP3OPT_2DENCODING)
+ fprintf(fd, "%s2-d encoding", sep), sep = "+";
+ if (sp->groupoptions & GROUP3OPT_FILLBITS)
+ fprintf(fd, "%sEOL padding", sep), sep = "+";
+ if (sp->groupoptions & GROUP3OPT_UNCOMPRESSED)
+ fprintf(fd, "%suncompressed data", sep);
+ }
+ fprintf(fd, " (%lu = 0x%lx)\n",
+ (unsigned long) sp->groupoptions,
+ (unsigned long) sp->groupoptions);
+ }
+ if (TIFFFieldSet(tif,FIELD_CLEANFAXDATA)) {
+ fprintf(fd, " Fax Data:");
+ switch (sp->cleanfaxdata) {
+ case CLEANFAXDATA_CLEAN:
+ fprintf(fd, " clean");
+ break;
+ case CLEANFAXDATA_REGENERATED:
+ fprintf(fd, " receiver regenerated");
+ break;
+ case CLEANFAXDATA_UNCLEAN:
+ fprintf(fd, " uncorrected errors");
+ break;
+ }
+ fprintf(fd, " (%u = 0x%x)\n",
+ sp->cleanfaxdata, sp->cleanfaxdata);
+ }
+ if (TIFFFieldSet(tif,FIELD_BADFAXLINES))
+ fprintf(fd, " Bad Fax Lines: %lu\n",
+ (unsigned long) sp->badfaxlines);
+ if (TIFFFieldSet(tif,FIELD_BADFAXRUN))
+ fprintf(fd, " Consecutive Bad Fax Lines: %lu\n",
+ (unsigned long) sp->badfaxrun);
+ if (sp->printdir)
+ (*sp->printdir)(tif, fd, flags);
+}
+
+static int
+InitCCITTFax3(TIFF* tif)
+{
+ static const char module[] = "InitCCITTFax3";
+ Fax3BaseState* sp;
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, faxFields, TIFFArrayCount(faxFields))) {
+ TIFFErrorExt(tif->tif_clientdata, "InitCCITTFax3",
+ "Merging common CCITT Fax codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8*)
+ _TIFFmalloc(sizeof (Fax3CodecState));
+
+ if (tif->tif_data == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for state block");
+ return (0);
+ }
+
+ sp = Fax3State(tif);
+ sp->rw_mode = tif->tif_mode;
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = Fax3VGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = Fax3VSetField; /* hook for codec tags */
+ sp->printdir = tif->tif_tagmethods.printdir;
+ tif->tif_tagmethods.printdir = Fax3PrintDir; /* hook for codec tags */
+ sp->groupoptions = 0;
+
+ if (sp->rw_mode == O_RDONLY) /* FIXME: improve for in place update */
+ tif->tif_flags |= TIFF_NOBITREV; /* decoder does bit reversal */
+ DecoderState(tif)->runs = NULL;
+ TIFFSetField(tif, TIFFTAG_FAXFILLFUNC, _TIFFFax3fillruns);
+ EncoderState(tif)->refline = NULL;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = Fax3FixupTags;
+ tif->tif_setupdecode = Fax3SetupState;
+ tif->tif_predecode = Fax3PreDecode;
+ tif->tif_decoderow = Fax3Decode1D;
+ tif->tif_decodestrip = Fax3Decode1D;
+ tif->tif_decodetile = Fax3Decode1D;
+ tif->tif_setupencode = Fax3SetupState;
+ tif->tif_preencode = Fax3PreEncode;
+ tif->tif_postencode = Fax3PostEncode;
+ tif->tif_encoderow = Fax3Encode;
+ tif->tif_encodestrip = Fax3Encode;
+ tif->tif_encodetile = Fax3Encode;
+ tif->tif_close = Fax3Close;
+ tif->tif_cleanup = Fax3Cleanup;
+
+ return (1);
+}
+
+int
+TIFFInitCCITTFax3(TIFF* tif, int scheme)
+{
+ (void) scheme;
+ if (InitCCITTFax3(tif)) {
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, fax3Fields,
+ TIFFArrayCount(fax3Fields))) {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax3",
+ "Merging CCITT Fax 3 codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * The default format is Class/F-style w/o RTC.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_CLASSF);
+ } else
+ return 01;
+}
+
+/*
+ * CCITT Group 4 (T.6) Facsimile-compatible
+ * Compression Scheme Support.
+ */
+
+#define SWAP(t,a,b) { t x; x = (a); (a) = (b); (b) = x; }
+/*
+ * Decode the requested amount of G4-encoded data.
+ */
+static int
+Fax4Decode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+#ifdef FAX3_DEBUG
+ FILE* file;
+#endif
+ DECLARE_STATE_2D(tif, sp, "Fax4Decode");
+
+ (void) s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ while (occ > 0) {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun = sp->curruns;
+ pb = sp->refruns;
+ b1 = *pb++;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
+ printf("-------------------- %d\n", tif->tif_row);
+ fflush(stdout);
+#endif
+ EXPAND2D(EOFG4);
+ if (EOLcnt)
+ goto EOFG4;
+ (*sp->fill)(buf, thisrun, pa, lastx);
+#ifdef FAX3_DEBUG
+ file = fopen("fillbuf.txt", "a");
+ fwrite(buf, sp->b.rowbytes, 1, file);
+ fclose(file);
+#endif
+ SETVALUE(0); /* imaginary change for reference */
+ SWAP(uint32*, sp->curruns, sp->refruns);
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOFG4:
+ NeedBits16( 13, BADG4 );
+ BADG4:
+#ifdef FAX3_DEBUG
+ if( GetBits(13) != 0x1001 )
+ fputs( "Bad EOFB\n", stderr );
+#endif
+ ClrBits( 13 );
+ (*sp->fill)(buf, thisrun, pa, lastx);
+#ifdef FAX3_DEBUG
+ file = fopen("fillbuf.txt", "a");
+ fwrite(buf, sp->b.rowbytes, 1, file);
+ fclose(file);
+#endif
+ UNCACHE_STATE(tif, sp);
+ return ( sp->line ? 1 : -1); /* don't error on badly-terminated strips */
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+#undef SWAP
+
+/*
+ * Encode the requested amount of data.
+ */
+static int
+Fax4Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ static const char module[] = "Fax4Encode";
+ Fax3CodecState *sp = EncoderState(tif);
+ (void) s;
+ if (cc % sp->b.rowbytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be written");
+ return (0);
+ }
+ while (cc > 0) {
+ if (!Fax3Encode2DRow(tif, bp, sp->refline, sp->b.rowpixels))
+ return (0);
+ _TIFFmemcpy(sp->refline, bp, sp->b.rowbytes);
+ bp += sp->b.rowbytes;
+ cc -= sp->b.rowbytes;
+ }
+ return (1);
+}
+
+static int
+Fax4PostEncode(TIFF* tif)
+{
+ Fax3CodecState *sp = EncoderState(tif);
+
+ /* terminate strip w/ EOFB */
+ Fax3PutBits(tif, EOL, 12);
+ Fax3PutBits(tif, EOL, 12);
+ if (sp->bit != 8)
+ Fax3FlushBits(tif, sp);
+ return (1);
+}
+
+int
+TIFFInitCCITTFax4(TIFF* tif, int scheme)
+{
+ (void) scheme;
+ if (InitCCITTFax3(tif)) { /* reuse G3 support */
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, fax4Fields,
+ TIFFArrayCount(fax4Fields))) {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFInitCCITTFax4",
+ "Merging CCITT Fax 4 codec-specific tags failed");
+ return 0;
+ }
+
+ tif->tif_decoderow = Fax4Decode;
+ tif->tif_decodestrip = Fax4Decode;
+ tif->tif_decodetile = Fax4Decode;
+ tif->tif_encoderow = Fax4Encode;
+ tif->tif_encodestrip = Fax4Encode;
+ tif->tif_encodetile = Fax4Encode;
+ tif->tif_postencode = Fax4PostEncode;
+ /*
+ * Suppress RTC at the end of each strip.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE, FAXMODE_NORTC);
+ } else
+ return (0);
+}
+
+/*
+ * CCITT Group 3 1-D Modified Huffman RLE Compression Support.
+ * (Compression algorithms 2 and 32771)
+ */
+
+/*
+ * Decode the requested amount of RLE-encoded data.
+ */
+static int
+Fax3DecodeRLE(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+ DECLARE_STATE(tif, sp, "Fax3DecodeRLE");
+ int mode = sp->b.mode;
+ (void) s;
+ if (occ % sp->b.rowbytes)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+ return (-1);
+ }
+ CACHE_STATE(tif, sp);
+ thisrun = sp->curruns;
+ while (occ > 0) {
+ a0 = 0;
+ RunLength = 0;
+ pa = thisrun;
+#ifdef FAX3_DEBUG
+ printf("\nBitAcc=%08X, BitsAvail = %d\n", BitAcc, BitsAvail);
+ printf("-------------------- %d\n", tif->tif_row);
+ fflush(stdout);
+#endif
+ EXPAND1D(EOFRLE);
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ /*
+ * Cleanup at the end of the row.
+ */
+ if (mode & FAXMODE_BYTEALIGN) {
+ int n = BitsAvail - (BitsAvail &~ 7);
+ ClrBits(n);
+ } else if (mode & FAXMODE_WORDALIGN) {
+ int n = BitsAvail - (BitsAvail &~ 15);
+ ClrBits(n);
+ if (BitsAvail == 0 && !isAligned(cp, uint16))
+ cp++;
+ }
+ buf += sp->b.rowbytes;
+ occ -= sp->b.rowbytes;
+ sp->line++;
+ continue;
+ EOFRLE: /* premature EOF */
+ (*sp->fill)(buf, thisrun, pa, lastx);
+ UNCACHE_STATE(tif, sp);
+ return (-1);
+ }
+ UNCACHE_STATE(tif, sp);
+ return (1);
+}
+
+int
+TIFFInitCCITTRLE(TIFF* tif, int scheme)
+{
+ (void) scheme;
+ if (InitCCITTFax3(tif)) { /* reuse G3 support */
+ tif->tif_decoderow = Fax3DecodeRLE;
+ tif->tif_decodestrip = Fax3DecodeRLE;
+ tif->tif_decodetile = Fax3DecodeRLE;
+ /*
+ * Suppress RTC+EOLs when encoding and byte-align data.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE,
+ FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_BYTEALIGN);
+ } else
+ return (0);
+}
+
+int
+TIFFInitCCITTRLEW(TIFF* tif, int scheme)
+{
+ (void) scheme;
+ if (InitCCITTFax3(tif)) { /* reuse G3 support */
+ tif->tif_decoderow = Fax3DecodeRLE;
+ tif->tif_decodestrip = Fax3DecodeRLE;
+ tif->tif_decodetile = Fax3DecodeRLE;
+ /*
+ * Suppress RTC+EOLs when encoding and word-align data.
+ */
+ return TIFFSetField(tif, TIFFTAG_FAXMODE,
+ FAXMODE_NORTC|FAXMODE_NOEOL|FAXMODE_WORDALIGN);
+ } else
+ return (0);
+}
+#endif /* CCITT_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.h b/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.h
new file mode 100644
index 0000000000..b0f46c9a43
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3.h
@@ -0,0 +1,538 @@
+/* $Id: tif_fax3.h,v 1.9 2011-03-10 20:23:07 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1990-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _FAX3_
+#define _FAX3_
+/*
+ * TIFF Library.
+ *
+ * CCITT Group 3 (T.4) and Group 4 (T.6) Decompression Support.
+ *
+ * Decoder support is derived, with permission, from the code
+ * in Frank Cringle's viewfax program;
+ * Copyright (C) 1990, 1995 Frank D. Cringle.
+ */
+#include "tiff.h"
+
+/*
+ * To override the default routine used to image decoded
+ * spans one can use the pseduo tag TIFFTAG_FAXFILLFUNC.
+ * The routine must have the type signature given below;
+ * for example:
+ *
+ * fillruns(unsigned char* buf, uint32* runs, uint32* erun, uint32 lastx)
+ *
+ * where buf is place to set the bits, runs is the array of b&w run
+ * lengths (white then black), erun is the last run in the array, and
+ * lastx is the width of the row in pixels. Fill routines can assume
+ * the run array has room for at least lastx runs and can overwrite
+ * data in the run array as needed (e.g. to append zero runs to bring
+ * the count up to a nice multiple).
+ */
+typedef void (*TIFFFaxFillFunc)(unsigned char*, uint32*, uint32*, uint32);
+
+/*
+ * The default run filler; made external for other decoders.
+ */
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern void _TIFFFax3fillruns(unsigned char*, uint32*, uint32*, uint32);
+#if defined(__cplusplus)
+}
+#endif
+
+
+/* finite state machine codes */
+#define S_Null 0
+#define S_Pass 1
+#define S_Horiz 2
+#define S_V0 3
+#define S_VR 4
+#define S_VL 5
+#define S_Ext 6
+#define S_TermW 7
+#define S_TermB 8
+#define S_MakeUpW 9
+#define S_MakeUpB 10
+#define S_MakeUp 11
+#define S_EOL 12
+
+typedef struct { /* state table entry */
+ unsigned char State; /* see above */
+ unsigned char Width; /* width of code in bits */
+ uint32 Param; /* unsigned 32-bit run length in bits */
+} TIFFFaxTabEnt;
+
+extern const TIFFFaxTabEnt TIFFFaxMainTable[];
+extern const TIFFFaxTabEnt TIFFFaxWhiteTable[];
+extern const TIFFFaxTabEnt TIFFFaxBlackTable[];
+
+/*
+ * The following macros define the majority of the G3/G4 decoder
+ * algorithm using the state tables defined elsewhere. To build
+ * a decoder you need some setup code and some glue code. Note
+ * that you may also need/want to change the way the NeedBits*
+ * macros get input data if, for example, you know the data to be
+ * decoded is properly aligned and oriented (doing so before running
+ * the decoder can be a big performance win).
+ *
+ * Consult the decoder in the TIFF library for an idea of what you
+ * need to define and setup to make use of these definitions.
+ *
+ * NB: to enable a debugging version of these macros define FAX3_DEBUG
+ * before including this file. Trace output goes to stdout.
+ */
+
+#ifndef EndOfData
+#define EndOfData() (cp >= ep)
+#endif
+/*
+ * Need <=8 or <=16 bits of input data. Unlike viewfax we
+ * cannot use/assume a word-aligned, properly bit swizzled
+ * input data set because data may come from an arbitrarily
+ * aligned, read-only source such as a memory-mapped file.
+ * Note also that the viewfax decoder does not check for
+ * running off the end of the input data buffer. This is
+ * possible for G3-encoded data because it prescans the input
+ * data to count EOL markers, but can cause problems for G4
+ * data. In any event, we don't prescan and must watch for
+ * running out of data since we can't permit the library to
+ * scan past the end of the input data buffer.
+ *
+ * Finally, note that we must handle remaindered data at the end
+ * of a strip specially. The coder asks for a fixed number of
+ * bits when scanning for the next code. This may be more bits
+ * than are actually present in the data stream. If we appear
+ * to run out of data but still have some number of valid bits
+ * remaining then we makeup the requested amount with zeros and
+ * return successfully. If the returned data is incorrect then
+ * we should be called again and get a premature EOF error;
+ * otherwise we should get the right answer.
+ */
+#ifndef NeedBits8
+#define NeedBits8(n,eoflab) do { \
+ if (BitsAvail < (n)) { \
+ if (EndOfData()) { \
+ if (BitsAvail == 0) /* no valid bits */ \
+ goto eoflab; \
+ BitsAvail = (n); /* pad with zeros */ \
+ } else { \
+ BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
+ BitsAvail += 8; \
+ } \
+ } \
+} while (0)
+#endif
+#ifndef NeedBits16
+#define NeedBits16(n,eoflab) do { \
+ if (BitsAvail < (n)) { \
+ if (EndOfData()) { \
+ if (BitsAvail == 0) /* no valid bits */ \
+ goto eoflab; \
+ BitsAvail = (n); /* pad with zeros */ \
+ } else { \
+ BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
+ if ((BitsAvail += 8) < (n)) { \
+ if (EndOfData()) { \
+ /* NB: we know BitsAvail is non-zero here */ \
+ BitsAvail = (n); /* pad with zeros */ \
+ } else { \
+ BitAcc |= ((uint32) bitmap[*cp++])<<BitsAvail; \
+ BitsAvail += 8; \
+ } \
+ } \
+ } \
+ } \
+} while (0)
+#endif
+#define GetBits(n) (BitAcc & ((1<<(n))-1))
+#define ClrBits(n) do { \
+ BitsAvail -= (n); \
+ BitAcc >>= (n); \
+} while (0)
+
+#ifdef FAX3_DEBUG
+static const char* StateNames[] = {
+ "Null ",
+ "Pass ",
+ "Horiz ",
+ "V0 ",
+ "VR ",
+ "VL ",
+ "Ext ",
+ "TermW ",
+ "TermB ",
+ "MakeUpW",
+ "MakeUpB",
+ "MakeUp ",
+ "EOL ",
+};
+#define DEBUG_SHOW putchar(BitAcc & (1 << t) ? '1' : '0')
+#define LOOKUP8(wid,tab,eoflab) do { \
+ int t; \
+ NeedBits8(wid,eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \
+ StateNames[TabEnt->State], TabEnt->Param); \
+ for (t = 0; t < TabEnt->Width; t++) \
+ DEBUG_SHOW; \
+ putchar('\n'); \
+ fflush(stdout); \
+ ClrBits(TabEnt->Width); \
+} while (0)
+#define LOOKUP16(wid,tab,eoflab) do { \
+ int t; \
+ NeedBits16(wid,eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ printf("%08lX/%d: %s%5d\t", (long) BitAcc, BitsAvail, \
+ StateNames[TabEnt->State], TabEnt->Param); \
+ for (t = 0; t < TabEnt->Width; t++) \
+ DEBUG_SHOW; \
+ putchar('\n'); \
+ fflush(stdout); \
+ ClrBits(TabEnt->Width); \
+} while (0)
+
+#define SETVALUE(x) do { \
+ *pa++ = RunLength + (x); \
+ printf("SETVALUE: %d\t%d\n", RunLength + (x), a0); \
+ a0 += x; \
+ RunLength = 0; \
+} while (0)
+#else
+#define LOOKUP8(wid,tab,eoflab) do { \
+ NeedBits8(wid,eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ ClrBits(TabEnt->Width); \
+} while (0)
+#define LOOKUP16(wid,tab,eoflab) do { \
+ NeedBits16(wid,eoflab); \
+ TabEnt = tab + GetBits(wid); \
+ ClrBits(TabEnt->Width); \
+} while (0)
+
+/*
+ * Append a run to the run length array for the
+ * current row and reset decoding state.
+ */
+#define SETVALUE(x) do { \
+ *pa++ = RunLength + (x); \
+ a0 += (x); \
+ RunLength = 0; \
+} while (0)
+#endif
+
+/*
+ * Synchronize input decoding at the start of each
+ * row by scanning for an EOL (if appropriate) and
+ * skipping any trash data that might be present
+ * after a decoding error. Note that the decoding
+ * done elsewhere that recognizes an EOL only consumes
+ * 11 consecutive zero bits. This means that if EOLcnt
+ * is non-zero then we still need to scan for the final flag
+ * bit that is part of the EOL code.
+ */
+#define SYNC_EOL(eoflab) do { \
+ if (EOLcnt == 0) { \
+ for (;;) { \
+ NeedBits16(11,eoflab); \
+ if (GetBits(11) == 0) \
+ break; \
+ ClrBits(1); \
+ } \
+ } \
+ for (;;) { \
+ NeedBits8(8,eoflab); \
+ if (GetBits(8)) \
+ break; \
+ ClrBits(8); \
+ } \
+ while (GetBits(1) == 0) \
+ ClrBits(1); \
+ ClrBits(1); /* EOL bit */ \
+ EOLcnt = 0; /* reset EOL counter/flag */ \
+} while (0)
+
+/*
+ * Cleanup the array of runs after decoding a row.
+ * We adjust final runs to insure the user buffer is not
+ * overwritten and/or undecoded area is white filled.
+ */
+#define CLEANUP_RUNS() do { \
+ if (RunLength) \
+ SETVALUE(0); \
+ if (a0 != lastx) { \
+ badlength(a0, lastx); \
+ while (a0 > lastx && pa > thisrun) \
+ a0 -= *--pa; \
+ if (a0 < lastx) { \
+ if (a0 < 0) \
+ a0 = 0; \
+ if ((pa-thisrun)&1) \
+ SETVALUE(0); \
+ SETVALUE(lastx - a0); \
+ } else if (a0 > lastx) { \
+ SETVALUE(lastx); \
+ SETVALUE(0); \
+ } \
+ } \
+} while (0)
+
+/*
+ * Decode a line of 1D-encoded data.
+ *
+ * The line expanders are written as macros so that they can be reused
+ * but still have direct access to the local variables of the "calling"
+ * function.
+ *
+ * Note that unlike the original version we have to explicitly test for
+ * a0 >= lastx after each black/white run is decoded. This is because
+ * the original code depended on the input data being zero-padded to
+ * insure the decoder recognized an EOL before running out of data.
+ */
+#define EXPAND1D(eoflab) do { \
+ for (;;) { \
+ for (;;) { \
+ LOOKUP16(12, TIFFFaxWhiteTable, eof1d); \
+ switch (TabEnt->State) { \
+ case S_EOL: \
+ EOLcnt = 1; \
+ goto done1d; \
+ case S_TermW: \
+ SETVALUE(TabEnt->Param); \
+ goto doneWhite1d; \
+ case S_MakeUpW: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ unexpected("WhiteTable", a0); \
+ goto done1d; \
+ } \
+ } \
+ doneWhite1d: \
+ if (a0 >= lastx) \
+ goto done1d; \
+ for (;;) { \
+ LOOKUP16(13, TIFFFaxBlackTable, eof1d); \
+ switch (TabEnt->State) { \
+ case S_EOL: \
+ EOLcnt = 1; \
+ goto done1d; \
+ case S_TermB: \
+ SETVALUE(TabEnt->Param); \
+ goto doneBlack1d; \
+ case S_MakeUpB: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ unexpected("BlackTable", a0); \
+ goto done1d; \
+ } \
+ } \
+ doneBlack1d: \
+ if (a0 >= lastx) \
+ goto done1d; \
+ if( *(pa-1) == 0 && *(pa-2) == 0 ) \
+ pa -= 2; \
+ } \
+eof1d: \
+ prematureEOF(a0); \
+ CLEANUP_RUNS(); \
+ goto eoflab; \
+done1d: \
+ CLEANUP_RUNS(); \
+} while (0)
+
+/*
+ * Update the value of b1 using the array
+ * of runs for the reference line.
+ */
+#define CHECK_b1 do { \
+ if (pa != thisrun) while (b1 <= a0 && b1 < lastx) { \
+ b1 += pb[0] + pb[1]; \
+ pb += 2; \
+ } \
+} while (0)
+
+/*
+ * Expand a row of 2D-encoded data.
+ */
+#define EXPAND2D(eoflab) do { \
+ while (a0 < lastx) { \
+ LOOKUP8(7, TIFFFaxMainTable, eof2d); \
+ switch (TabEnt->State) { \
+ case S_Pass: \
+ CHECK_b1; \
+ b1 += *pb++; \
+ RunLength += b1 - a0; \
+ a0 = b1; \
+ b1 += *pb++; \
+ break; \
+ case S_Horiz: \
+ if ((pa-thisrun)&1) { \
+ for (;;) { /* black first */ \
+ LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
+ switch (TabEnt->State) { \
+ case S_TermB: \
+ SETVALUE(TabEnt->Param); \
+ goto doneWhite2da; \
+ case S_MakeUpB: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badBlack2d; \
+ } \
+ } \
+ doneWhite2da:; \
+ for (;;) { /* then white */ \
+ LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
+ switch (TabEnt->State) { \
+ case S_TermW: \
+ SETVALUE(TabEnt->Param); \
+ goto doneBlack2da; \
+ case S_MakeUpW: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badWhite2d; \
+ } \
+ } \
+ doneBlack2da:; \
+ } else { \
+ for (;;) { /* white first */ \
+ LOOKUP16(12, TIFFFaxWhiteTable, eof2d); \
+ switch (TabEnt->State) { \
+ case S_TermW: \
+ SETVALUE(TabEnt->Param); \
+ goto doneWhite2db; \
+ case S_MakeUpW: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badWhite2d; \
+ } \
+ } \
+ doneWhite2db:; \
+ for (;;) { /* then black */ \
+ LOOKUP16(13, TIFFFaxBlackTable, eof2d); \
+ switch (TabEnt->State) { \
+ case S_TermB: \
+ SETVALUE(TabEnt->Param); \
+ goto doneBlack2db; \
+ case S_MakeUpB: \
+ case S_MakeUp: \
+ a0 += TabEnt->Param; \
+ RunLength += TabEnt->Param; \
+ break; \
+ default: \
+ goto badBlack2d; \
+ } \
+ } \
+ doneBlack2db:; \
+ } \
+ CHECK_b1; \
+ break; \
+ case S_V0: \
+ CHECK_b1; \
+ SETVALUE(b1 - a0); \
+ b1 += *pb++; \
+ break; \
+ case S_VR: \
+ CHECK_b1; \
+ SETVALUE(b1 - a0 + TabEnt->Param); \
+ b1 += *pb++; \
+ break; \
+ case S_VL: \
+ CHECK_b1; \
+ if (b1 <= (int) (a0 + TabEnt->Param)) { \
+ if (b1 < (int) (a0 + TabEnt->Param) || pa != thisrun) { \
+ unexpected("VL", a0); \
+ goto eol2d; \
+ } \
+ } \
+ SETVALUE(b1 - a0 - TabEnt->Param); \
+ b1 -= *--pb; \
+ break; \
+ case S_Ext: \
+ *pa++ = lastx - a0; \
+ extension(a0); \
+ goto eol2d; \
+ case S_EOL: \
+ *pa++ = lastx - a0; \
+ NeedBits8(4,eof2d); \
+ if (GetBits(4)) \
+ unexpected("EOL", a0); \
+ ClrBits(4); \
+ EOLcnt = 1; \
+ goto eol2d; \
+ default: \
+ badMain2d: \
+ unexpected("MainTable", a0); \
+ goto eol2d; \
+ badBlack2d: \
+ unexpected("BlackTable", a0); \
+ goto eol2d; \
+ badWhite2d: \
+ unexpected("WhiteTable", a0); \
+ goto eol2d; \
+ eof2d: \
+ prematureEOF(a0); \
+ CLEANUP_RUNS(); \
+ goto eoflab; \
+ } \
+ } \
+ if (RunLength) { \
+ if (RunLength + a0 < lastx) { \
+ /* expect a final V0 */ \
+ NeedBits8(1,eof2d); \
+ if (!GetBits(1)) \
+ goto badMain2d; \
+ ClrBits(1); \
+ } \
+ SETVALUE(0); \
+ } \
+eol2d: \
+ CLEANUP_RUNS(); \
+} while (0)
+#endif /* _FAX3_ */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3sm.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3sm.c
new file mode 100644
index 0000000000..47a532cbd6
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_fax3sm.c
@@ -0,0 +1,1263 @@
+/* WARNING, this file was automatically generated by the
+ mkg3states program */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiff.h"
+#include "tif_fax3.h"
+ const TIFFFaxTabEnt TIFFFaxMainTable[128] = {
+{12,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{5,6,2},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{5,7,3},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,6,2},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{6,7,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{5,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},
+{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},{4,7,3},{3,1,0},{5,3,1},{3,1,0},
+{2,3,0},{3,1,0},{4,3,1},{3,1,0},{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},
+{4,3,1},{3,1,0},{4,6,2},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0},
+{1,4,0},{3,1,0},{5,3,1},{3,1,0},{2,3,0},{3,1,0},{4,3,1},{3,1,0}
+};
+ const TIFFFaxTabEnt TIFFFaxWhiteTable[4096] = {
+{12,11,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2112},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2368},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,12,1984},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2240},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2496},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{12,11,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1792},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,11,1856},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2176},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1600},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},
+{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},
+{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},
+{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},{7,8,43},{7,6,17},
+{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},
+{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},
+{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,768},{7,4,6},
+{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2432},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},{7,7,19},{7,5,8},
+{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},
+{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},{9,9,1408},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},
+{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},
+{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},
+{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},
+{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},
+{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,960},{7,4,6},
+{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},
+{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{11,12,2048},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},
+{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},
+{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},{7,8,32},{7,5,8},
+{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},
+{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},
+{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1536},{7,4,5},
+{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},
+{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,11,1920},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},
+{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,896},{7,4,6},
+{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},
+{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},
+{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},{7,8,44},{7,6,17},
+{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},
+{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},
+{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},
+{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},
+{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},
+{7,8,55},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},
+{7,8,53},{7,5,9},{9,8,448},{7,4,6},{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1472},{7,4,5},{7,8,43},{7,6,17},{9,9,1216},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},
+{7,8,61},{7,4,4},{7,4,2},{7,4,7},{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},
+{9,9,960},{7,4,6},{7,8,31},{7,5,8},{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,9,704},{7,4,6},{7,8,37},{9,5,128},
+{7,7,25},{7,6,15},{9,8,320},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},
+{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{11,12,2304},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,7,20},{9,5,128},{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},
+{7,7,27},{7,4,5},{7,8,40},{7,6,16},{9,9,832},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},
+{9,8,512},{7,4,6},{7,8,36},{9,5,128},{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{9,9,1600},{7,4,5},{7,8,44},{7,6,17},{9,9,1344},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},
+{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},
+{7,4,2},{7,4,7},{7,8,48},{7,4,3},{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1088},{7,4,6},
+{7,8,32},{7,5,8},{7,8,58},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},
+{7,5,11},{7,4,5},{7,7,26},{7,5,9},{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},
+{9,8,384},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},
+{9,7,256},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{0,0,0},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},
+{7,7,24},{7,6,14},{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},
+{7,8,39},{7,6,16},{9,8,576},{7,4,6},{7,7,19},{7,5,8},{7,8,55},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,45},{7,4,3},{7,5,11},{7,4,5},{7,8,53},{7,5,9},{9,8,448},{7,4,6},
+{7,8,35},{9,5,128},{7,8,51},{7,6,15},{7,8,63},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},
+{9,9,1536},{7,4,5},{7,8,43},{7,6,17},{9,9,1280},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,8,29},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},
+{9,6,1664},{7,4,6},{7,8,33},{9,5,128},{7,8,49},{7,6,14},{7,8,61},{7,4,4},{7,4,2},{7,4,7},
+{7,8,47},{7,4,3},{7,8,59},{7,4,5},{7,8,41},{7,6,16},{9,9,1024},{7,4,6},{7,8,31},{7,5,8},
+{7,8,57},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},
+{7,7,26},{7,5,9},{9,9,768},{7,4,6},{7,8,37},{9,5,128},{7,7,25},{7,6,15},{9,8,320},{7,4,4},
+{7,4,2},{7,4,7},{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},
+{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},{11,12,2560},{7,4,3},
+{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},{7,7,20},{9,5,128},{7,7,24},{7,6,14},
+{7,7,28},{7,4,4},{7,4,2},{7,4,7},{7,7,23},{7,4,3},{7,7,27},{7,4,5},{7,8,40},{7,6,16},
+{9,9,896},{7,4,6},{7,7,19},{7,5,8},{7,8,56},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7},
+{7,8,46},{7,4,3},{7,5,11},{7,4,5},{7,8,54},{7,5,9},{9,8,512},{7,4,6},{7,8,36},{9,5,128},
+{7,8,52},{7,6,15},{7,8,0},{7,4,4},{7,4,2},{7,4,7},{7,6,13},{7,4,3},{9,9,1728},{7,4,5},
+{7,8,44},{7,6,17},{9,9,1408},{7,4,6},{7,6,1},{7,5,8},{9,6,192},{9,5,64},{7,5,10},{7,4,4},
+{7,4,2},{7,4,7},{7,8,30},{7,4,3},{7,5,11},{7,4,5},{7,6,12},{7,5,9},{9,6,1664},{7,4,6},
+{7,8,34},{9,5,128},{7,8,50},{7,6,14},{7,8,62},{7,4,4},{7,4,2},{7,4,7},{7,8,48},{7,4,3},
+{7,8,60},{7,4,5},{7,8,42},{7,6,16},{9,9,1152},{7,4,6},{7,8,32},{7,5,8},{7,8,58},{9,5,64},
+{7,5,10},{7,4,4},{7,4,2},{7,4,7},{7,7,22},{7,4,3},{7,5,11},{7,4,5},{7,7,26},{7,5,9},
+{9,8,640},{7,4,6},{7,8,38},{9,5,128},{7,7,25},{7,6,15},{9,8,384},{7,4,4},{7,4,2},{7,4,7},
+{7,6,13},{7,4,3},{7,7,18},{7,4,5},{7,7,21},{7,6,17},{9,7,256},{7,4,6},{7,6,1},{7,5,8},
+{9,6,192},{9,5,64},{7,5,10},{7,4,4},{7,4,2},{7,4,7}
+};
+ const TIFFFaxTabEnt TIFFFaxBlackTable[8192] = {
+{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,56},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,30},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2112},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,44},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,60},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,1984},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,34},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1664},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1408},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,61},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,1024},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,768},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,62},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,38},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,512},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2496},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,25},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,12,192},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1280},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,31},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,21},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,896},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,640},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,45},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,12,448},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1536},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,41},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2048},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,51},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,59},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1152},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,63},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,2304},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,39},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,128},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,56},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,30},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,11,1856},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,57},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,54},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,52},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,48},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2112},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,44},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,36},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,384},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,28},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,60},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,40},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,12,2368},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,1984},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,50},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,34},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,1728},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,26},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,1472},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,32},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,61},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,42},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1088},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,832},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,62},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2240},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,46},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,38},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,576},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2496},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{12,11,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,18},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1792},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,23},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,20},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,25},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,192},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1344},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,31},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,11,1856},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,58},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,21},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{10,13,960},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,13,704},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,49},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2176},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,45},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,37},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,448},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,29},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1600},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,41},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{11,12,2432},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,18},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,17},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2048},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,51},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,35},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{10,12,320},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,27},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,59},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,33},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{11,11,1920},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,12,256},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,43},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,13,1216},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{0,0,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,8,13},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,9,15},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,55},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,63},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2304},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,12,47},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,12,39},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,12,53},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,12},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{0,0,0},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,8,13},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,11,19},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,11,24},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,11,22},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{11,12,2560},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,7,10},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,10,16},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2},{8,10,0},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},
+{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{10,10,64},{8,2,3},
+{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,9},{8,2,3},{8,3,1},{8,2,2},
+{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,11},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},
+{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},
+{8,8,14},{8,2,3},{8,3,1},{8,2,2},{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,6,8},{8,2,3},
+{8,3,1},{8,2,2},{8,4,5},{8,2,3},{8,3,4},{8,2,2},{8,7,12},{8,2,3},{8,3,1},{8,2,2},
+{8,4,6},{8,2,3},{8,3,4},{8,2,2},{8,5,7},{8,2,3},{8,3,1},{8,2,2},{8,4,5},{8,2,3},
+{8,3,4},{8,2,2}
+};
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_flush.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_flush.c
new file mode 100644
index 0000000000..075b3bcf33
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_flush.c
@@ -0,0 +1,121 @@
+/* $Id: tif_flush.c,v 1.9 2010-03-31 06:40:10 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+int
+TIFFFlush(TIFF* tif)
+{
+ if( tif->tif_mode == O_RDONLY )
+ return 1;
+
+ if (!TIFFFlushData(tif))
+ return (0);
+
+ /* In update (r+) mode we try to detect the case where
+ only the strip/tile map has been altered, and we try to
+ rewrite only that portion of the directory without
+ making any other changes */
+
+ if( (tif->tif_flags & TIFF_DIRTYSTRIP)
+ && !(tif->tif_flags & TIFF_DIRTYDIRECT)
+ && tif->tif_mode == O_RDWR )
+ {
+ uint64 *offsets=NULL, *sizes=NULL;
+
+ if( TIFFIsTiled(tif) )
+ {
+ if( TIFFGetField( tif, TIFFTAG_TILEOFFSETS, &offsets )
+ && TIFFGetField( tif, TIFFTAG_TILEBYTECOUNTS, &sizes )
+ && _TIFFRewriteField( tif, TIFFTAG_TILEOFFSETS, TIFF_LONG8,
+ tif->tif_dir.td_nstrips, offsets )
+ && _TIFFRewriteField( tif, TIFFTAG_TILEBYTECOUNTS, TIFF_LONG8,
+ tif->tif_dir.td_nstrips, sizes ) )
+ {
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+ tif->tif_flags &= ~TIFF_BEENWRITING;
+ return 1;
+ }
+ }
+ else
+ {
+ if( TIFFGetField( tif, TIFFTAG_STRIPOFFSETS, &offsets )
+ && TIFFGetField( tif, TIFFTAG_STRIPBYTECOUNTS, &sizes )
+ && _TIFFRewriteField( tif, TIFFTAG_STRIPOFFSETS, TIFF_LONG8,
+ tif->tif_dir.td_nstrips, offsets )
+ && _TIFFRewriteField( tif, TIFFTAG_STRIPBYTECOUNTS, TIFF_LONG8,
+ tif->tif_dir.td_nstrips, sizes ) )
+ {
+ tif->tif_flags &= ~TIFF_DIRTYSTRIP;
+ tif->tif_flags &= ~TIFF_BEENWRITING;
+ return 1;
+ }
+ }
+ }
+
+ if ((tif->tif_flags & (TIFF_DIRTYDIRECT|TIFF_DIRTYSTRIP))
+ && !TIFFRewriteDirectory(tif))
+ return (0);
+
+ return (1);
+}
+
+/*
+ * Flush buffered data to the file.
+ *
+ * Frank Warmerdam'2000: I modified this to return 1 if TIFF_BEENWRITING
+ * is not set, so that TIFFFlush() will proceed to write out the directory.
+ * The documentation says returning 1 is an error indicator, but not having
+ * been writing isn't exactly a an error. Hopefully this doesn't cause
+ * problems for other people.
+ */
+int
+TIFFFlushData(TIFF* tif)
+{
+ if ((tif->tif_flags & TIFF_BEENWRITING) == 0)
+ return (1);
+ if (tif->tif_flags & TIFF_POSTENCODE) {
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+ if (!(*tif->tif_postencode)(tif))
+ return (0);
+ }
+ return (TIFFFlushData1(tif));
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_getimage.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_getimage.c
new file mode 100644
index 0000000000..a5d7a44e19
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_getimage.c
@@ -0,0 +1,2991 @@
+/* $Id: tif_getimage.c,v 1.82 2012-06-06 00:17:49 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library
+ *
+ * Read and return a packed RGBA image.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <stdio.h>
+
+static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
+static int PickContigCase(TIFFRGBAImage*);
+static int PickSeparateCase(TIFFRGBAImage*);
+
+static int BuildMapUaToAa(TIFFRGBAImage* img);
+static int BuildMapBitdepth16To8(TIFFRGBAImage* img);
+
+static const char photoTag[] = "PhotometricInterpretation";
+
+/*
+ * Helper constants used in Orientation tag handling
+ */
+#define FLIP_VERTICALLY 0x01
+#define FLIP_HORIZONTALLY 0x02
+
+/*
+ * Color conversion constants. We will define display types here.
+ */
+
+static const TIFFDisplay display_sRGB = {
+ { /* XYZ -> luminance matrix */
+ { 3.2410F, -1.5374F, -0.4986F },
+ { -0.9692F, 1.8760F, 0.0416F },
+ { 0.0556F, -0.2040F, 1.0570F }
+ },
+ 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
+ 255, 255, 255, /* Pixel values for ref. white */
+ 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */
+ 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */
+};
+
+/*
+ * Check the image to see if TIFFReadRGBAImage can deal with it.
+ * 1/0 is returned according to whether or not the image can
+ * be handled. If 0 is returned, emsg contains the reason
+ * why it is being rejected.
+ */
+int
+TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
+{
+ TIFFDirectory* td = &tif->tif_dir;
+ uint16 photometric;
+ int colorchannels;
+
+ if (!tif->tif_decodestatus) {
+ sprintf(emsg, "Sorry, requested compression method is not configured");
+ return (0);
+ }
+ switch (td->td_bitspersample) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ break;
+ default:
+ sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
+ td->td_bitspersample);
+ return (0);
+ }
+ colorchannels = td->td_samplesperpixel - td->td_extrasamples;
+ if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
+ switch (colorchannels) {
+ case 1:
+ photometric = PHOTOMETRIC_MINISBLACK;
+ break;
+ case 3:
+ photometric = PHOTOMETRIC_RGB;
+ break;
+ default:
+ sprintf(emsg, "Missing needed %s tag", photoTag);
+ return (0);
+ }
+ }
+ switch (photometric) {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_PALETTE:
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG
+ && td->td_samplesperpixel != 1
+ && td->td_bitspersample < 8 ) {
+ sprintf(emsg,
+ "Sorry, can not handle contiguous data with %s=%d, "
+ "and %s=%d and Bits/Sample=%d",
+ photoTag, photometric,
+ "Samples/pixel", td->td_samplesperpixel,
+ td->td_bitspersample);
+ return (0);
+ }
+ /*
+ * We should likely validate that any extra samples are either
+ * to be ignored, or are alpha, and if alpha we should try to use
+ * them. But for now we won't bother with this.
+ */
+ break;
+ case PHOTOMETRIC_YCBCR:
+ /*
+ * TODO: if at all meaningful and useful, make more complete
+ * support check here, or better still, refactor to let supporting
+ * code decide whether there is support and what meaningfull
+ * error to return
+ */
+ break;
+ case PHOTOMETRIC_RGB:
+ if (colorchannels < 3) {
+ sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
+ "Color channels", colorchannels);
+ return (0);
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ {
+ uint16 inkset;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
+ if (inkset != INKSET_CMYK) {
+ sprintf(emsg,
+ "Sorry, can not handle separated image with %s=%d",
+ "InkSet", inkset);
+ return 0;
+ }
+ if (td->td_samplesperpixel < 4) {
+ sprintf(emsg,
+ "Sorry, can not handle separated image with %s=%d",
+ "Samples/pixel", td->td_samplesperpixel);
+ return 0;
+ }
+ break;
+ }
+ case PHOTOMETRIC_LOGL:
+ if (td->td_compression != COMPRESSION_SGILOG) {
+ sprintf(emsg, "Sorry, LogL data must have %s=%d",
+ "Compression", COMPRESSION_SGILOG);
+ return (0);
+ }
+ break;
+ case PHOTOMETRIC_LOGLUV:
+ if (td->td_compression != COMPRESSION_SGILOG &&
+ td->td_compression != COMPRESSION_SGILOG24) {
+ sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
+ "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
+ return (0);
+ }
+ if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
+ sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
+ "Planarconfiguration", td->td_planarconfig);
+ return (0);
+ }
+ break;
+ case PHOTOMETRIC_CIELAB:
+ break;
+ default:
+ sprintf(emsg, "Sorry, can not handle image with %s=%d",
+ photoTag, photometric);
+ return (0);
+ }
+ return (1);
+}
+
+void
+TIFFRGBAImageEnd(TIFFRGBAImage* img)
+{
+ if (img->Map)
+ _TIFFfree(img->Map), img->Map = NULL;
+ if (img->BWmap)
+ _TIFFfree(img->BWmap), img->BWmap = NULL;
+ if (img->PALmap)
+ _TIFFfree(img->PALmap), img->PALmap = NULL;
+ if (img->ycbcr)
+ _TIFFfree(img->ycbcr), img->ycbcr = NULL;
+ if (img->cielab)
+ _TIFFfree(img->cielab), img->cielab = NULL;
+ if (img->UaToAa)
+ _TIFFfree(img->UaToAa), img->UaToAa = NULL;
+ if (img->Bitdepth16To8)
+ _TIFFfree(img->Bitdepth16To8), img->Bitdepth16To8 = NULL;
+
+ if( img->redcmap ) {
+ _TIFFfree( img->redcmap );
+ _TIFFfree( img->greencmap );
+ _TIFFfree( img->bluecmap );
+ img->redcmap = img->greencmap = img->bluecmap = NULL;
+ }
+}
+
+static int
+isCCITTCompression(TIFF* tif)
+{
+ uint16 compress;
+ TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
+ return (compress == COMPRESSION_CCITTFAX3 ||
+ compress == COMPRESSION_CCITTFAX4 ||
+ compress == COMPRESSION_CCITTRLE ||
+ compress == COMPRESSION_CCITTRLEW);
+}
+
+int
+TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
+{
+ uint16* sampleinfo;
+ uint16 extrasamples;
+ uint16 planarconfig;
+ uint16 compress;
+ int colorchannels;
+ uint16 *red_orig, *green_orig, *blue_orig;
+ int n_color;
+
+ /* Initialize to normal values */
+ img->row_offset = 0;
+ img->col_offset = 0;
+ img->redcmap = NULL;
+ img->greencmap = NULL;
+ img->bluecmap = NULL;
+ img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
+
+ img->tif = tif;
+ img->stoponerr = stop;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
+ switch (img->bitspersample) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ break;
+ default:
+ sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
+ img->bitspersample);
+ goto fail_return;
+ }
+ img->alpha = 0;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
+ &extrasamples, &sampleinfo);
+ if (extrasamples >= 1)
+ {
+ switch (sampleinfo[0]) {
+ case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */
+ if (img->samplesperpixel > 3) /* correct info about alpha channel */
+ img->alpha = EXTRASAMPLE_ASSOCALPHA;
+ break;
+ case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
+ case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
+ img->alpha = sampleinfo[0];
+ break;
+ }
+ }
+
+#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
+ if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
+ img->photometric = PHOTOMETRIC_MINISWHITE;
+
+ if( extrasamples == 0
+ && img->samplesperpixel == 4
+ && img->photometric == PHOTOMETRIC_RGB )
+ {
+ img->alpha = EXTRASAMPLE_ASSOCALPHA;
+ extrasamples = 1;
+ }
+#endif
+
+ colorchannels = img->samplesperpixel - extrasamples;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
+ if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
+ switch (colorchannels) {
+ case 1:
+ if (isCCITTCompression(tif))
+ img->photometric = PHOTOMETRIC_MINISWHITE;
+ else
+ img->photometric = PHOTOMETRIC_MINISBLACK;
+ break;
+ case 3:
+ img->photometric = PHOTOMETRIC_RGB;
+ break;
+ default:
+ sprintf(emsg, "Missing needed %s tag", photoTag);
+ goto fail_return;
+ }
+ }
+ switch (img->photometric) {
+ case PHOTOMETRIC_PALETTE:
+ if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
+ &red_orig, &green_orig, &blue_orig)) {
+ sprintf(emsg, "Missing required \"Colormap\" tag");
+ goto fail_return;
+ }
+
+ /* copy the colormaps so we can modify them */
+ n_color = (1L << img->bitspersample);
+ img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
+ img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
+ img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
+ if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
+ sprintf(emsg, "Out of memory for colormap copy");
+ goto fail_return;
+ }
+
+ _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
+ _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
+ _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
+
+ /* fall thru... */
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ if (planarconfig == PLANARCONFIG_CONTIG
+ && img->samplesperpixel != 1
+ && img->bitspersample < 8 ) {
+ sprintf(emsg,
+ "Sorry, can not handle contiguous data with %s=%d, "
+ "and %s=%d and Bits/Sample=%d",
+ photoTag, img->photometric,
+ "Samples/pixel", img->samplesperpixel,
+ img->bitspersample);
+ goto fail_return;
+ }
+ break;
+ case PHOTOMETRIC_YCBCR:
+ /* It would probably be nice to have a reality check here. */
+ if (planarconfig == PLANARCONFIG_CONTIG)
+ /* can rely on libjpeg to convert to RGB */
+ /* XXX should restore current state on exit */
+ switch (compress) {
+ case COMPRESSION_JPEG:
+ /*
+ * TODO: when complete tests verify complete desubsampling
+ * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
+ * favor of tif_getimage.c native handling
+ */
+ TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
+ img->photometric = PHOTOMETRIC_RGB;
+ break;
+ default:
+ /* do nothing */;
+ break;
+ }
+ /*
+ * TODO: if at all meaningful and useful, make more complete
+ * support check here, or better still, refactor to let supporting
+ * code decide whether there is support and what meaningfull
+ * error to return
+ */
+ break;
+ case PHOTOMETRIC_RGB:
+ if (colorchannels < 3) {
+ sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
+ "Color channels", colorchannels);
+ goto fail_return;
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ {
+ uint16 inkset;
+ TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
+ if (inkset != INKSET_CMYK) {
+ sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
+ "InkSet", inkset);
+ goto fail_return;
+ }
+ if (img->samplesperpixel < 4) {
+ sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
+ "Samples/pixel", img->samplesperpixel);
+ goto fail_return;
+ }
+ }
+ break;
+ case PHOTOMETRIC_LOGL:
+ if (compress != COMPRESSION_SGILOG) {
+ sprintf(emsg, "Sorry, LogL data must have %s=%d",
+ "Compression", COMPRESSION_SGILOG);
+ goto fail_return;
+ }
+ TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
+ img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
+ img->bitspersample = 8;
+ break;
+ case PHOTOMETRIC_LOGLUV:
+ if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
+ sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
+ "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
+ goto fail_return;
+ }
+ if (planarconfig != PLANARCONFIG_CONTIG) {
+ sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
+ "Planarconfiguration", planarconfig);
+ return (0);
+ }
+ TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
+ img->photometric = PHOTOMETRIC_RGB; /* little white lie */
+ img->bitspersample = 8;
+ break;
+ case PHOTOMETRIC_CIELAB:
+ break;
+ default:
+ sprintf(emsg, "Sorry, can not handle image with %s=%d",
+ photoTag, img->photometric);
+ goto fail_return;
+ }
+ img->Map = NULL;
+ img->BWmap = NULL;
+ img->PALmap = NULL;
+ img->ycbcr = NULL;
+ img->cielab = NULL;
+ img->UaToAa = NULL;
+ img->Bitdepth16To8 = NULL;
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
+ img->isContig =
+ !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
+ if (img->isContig) {
+ if (!PickContigCase(img)) {
+ sprintf(emsg, "Sorry, can not handle image");
+ goto fail_return;
+ }
+ } else {
+ if (!PickSeparateCase(img)) {
+ sprintf(emsg, "Sorry, can not handle image");
+ goto fail_return;
+ }
+ }
+ return 1;
+
+ fail_return:
+ _TIFFfree( img->redcmap );
+ _TIFFfree( img->greencmap );
+ _TIFFfree( img->bluecmap );
+ img->redcmap = img->greencmap = img->bluecmap = NULL;
+ return 0;
+}
+
+int
+TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+ if (img->get == NULL) {
+ TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
+ return (0);
+ }
+ if (img->put.any == NULL) {
+ TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
+ "No \"put\" routine setupl; probably can not handle image format");
+ return (0);
+ }
+ return (*img->get)(img, raster, w, h);
+}
+
+/*
+ * Read the specified image into an ABGR-format rastertaking in account
+ * specified orientation.
+ */
+int
+TIFFReadRGBAImageOriented(TIFF* tif,
+ uint32 rwidth, uint32 rheight, uint32* raster,
+ int orientation, int stop)
+{
+ char emsg[1024] = "";
+ TIFFRGBAImage img;
+ int ok;
+
+ if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
+ img.req_orientation = orientation;
+ /* XXX verify rwidth and rheight against width and height */
+ ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
+ rwidth, img.height);
+ TIFFRGBAImageEnd(&img);
+ } else {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
+ ok = 0;
+ }
+ return (ok);
+}
+
+/*
+ * Read the specified image into an ABGR-format raster. Use bottom left
+ * origin for raster by default.
+ */
+int
+TIFFReadRGBAImage(TIFF* tif,
+ uint32 rwidth, uint32 rheight, uint32* raster, int stop)
+{
+ return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
+ ORIENTATION_BOTLEFT, stop);
+}
+
+static int
+setorientation(TIFFRGBAImage* img)
+{
+ switch (img->orientation) {
+ case ORIENTATION_TOPLEFT:
+ case ORIENTATION_LEFTTOP:
+ if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTTOP)
+ return FLIP_HORIZONTALLY;
+ else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTBOT)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+ img->req_orientation == ORIENTATION_LEFTBOT)
+ return FLIP_VERTICALLY;
+ else
+ return 0;
+ case ORIENTATION_TOPRIGHT:
+ case ORIENTATION_RIGHTTOP:
+ if (img->req_orientation == ORIENTATION_TOPLEFT ||
+ img->req_orientation == ORIENTATION_LEFTTOP)
+ return FLIP_HORIZONTALLY;
+ else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTBOT)
+ return FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+ img->req_orientation == ORIENTATION_LEFTBOT)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else
+ return 0;
+ case ORIENTATION_BOTRIGHT:
+ case ORIENTATION_RIGHTBOT:
+ if (img->req_orientation == ORIENTATION_TOPLEFT ||
+ img->req_orientation == ORIENTATION_LEFTTOP)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTTOP)
+ return FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTLEFT ||
+ img->req_orientation == ORIENTATION_LEFTBOT)
+ return FLIP_HORIZONTALLY;
+ else
+ return 0;
+ case ORIENTATION_BOTLEFT:
+ case ORIENTATION_LEFTBOT:
+ if (img->req_orientation == ORIENTATION_TOPLEFT ||
+ img->req_orientation == ORIENTATION_LEFTTOP)
+ return FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTTOP)
+ return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
+ else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
+ img->req_orientation == ORIENTATION_RIGHTBOT)
+ return FLIP_HORIZONTALLY;
+ else
+ return 0;
+ default: /* NOTREACHED */
+ return 0;
+ }
+}
+
+/*
+ * Get an tile-organized image that has
+ * PlanarConfiguration contiguous if SamplesPerPixel > 1
+ * or
+ * SamplesPerPixel == 1
+ */
+static int
+gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+ TIFF* tif = img->tif;
+ tileContigRoutine put = img->put.contig;
+ uint32 col, row, y, rowstoread;
+ tmsize_t pos;
+ uint32 tw, th;
+ unsigned char* buf;
+ int32 fromskew, toskew;
+ uint32 nrow;
+ int ret = 1, flip;
+
+ buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
+ if (buf == 0) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
+ return (0);
+ }
+ _TIFFmemset(buf, 0, TIFFTileSize(tif));
+ TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
+ TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY) {
+ y = h - 1;
+ toskew = -(int32)(tw + w);
+ }
+ else {
+ y = 0;
+ toskew = -(int32)(tw - w);
+ }
+
+ for (row = 0; row < h; row += nrow)
+ {
+ rowstoread = th - (row + img->row_offset) % th;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ for (col = 0; col < w; col += tw)
+ {
+ if (TIFFReadTile(tif, buf, col+img->col_offset,
+ row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+
+ pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
+
+ if (col + tw > w)
+ {
+ /*
+ * Tile is clipped horizontally. Calculate
+ * visible portion and skewing factors.
+ */
+ uint32 npix = w - col;
+ fromskew = tw - npix;
+ (*put)(img, raster+y*w+col, col, y,
+ npix, nrow, fromskew, toskew + fromskew, buf + pos);
+ }
+ else
+ {
+ (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
+ }
+ }
+
+ y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+ }
+ _TIFFfree(buf);
+
+ if (flip & FLIP_HORIZONTALLY) {
+ uint32 line;
+
+ for (line = 0; line < h; line++) {
+ uint32 *left = raster + (line * w);
+ uint32 *right = left + w - 1;
+
+ while ( left < right ) {
+ uint32 temp = *left;
+ *left = *right;
+ *right = temp;
+ left++, right--;
+ }
+ }
+ }
+
+ return (ret);
+}
+
+/*
+ * Get an tile-organized image that has
+ * SamplesPerPixel > 1
+ * PlanarConfiguration separated
+ * We assume that all such images are RGB.
+ */
+static int
+gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+ TIFF* tif = img->tif;
+ tileSeparateRoutine put = img->put.separate;
+ uint32 col, row, y, rowstoread;
+ tmsize_t pos;
+ uint32 tw, th;
+ unsigned char* buf;
+ unsigned char* p0;
+ unsigned char* p1;
+ unsigned char* p2;
+ unsigned char* pa;
+ tmsize_t tilesize;
+ tmsize_t bufsize;
+ int32 fromskew, toskew;
+ int alpha = img->alpha;
+ uint32 nrow;
+ int ret = 1, flip;
+ int colorchannels;
+
+ tilesize = TIFFTileSize(tif);
+ bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
+ if (bufsize == 0) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
+ return (0);
+ }
+ buf = (unsigned char*) _TIFFmalloc(bufsize);
+ if (buf == 0) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
+ return (0);
+ }
+ _TIFFmemset(buf, 0, bufsize);
+ p0 = buf;
+ p1 = p0 + tilesize;
+ p2 = p1 + tilesize;
+ pa = (alpha?(p2+tilesize):NULL);
+ TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
+ TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY) {
+ y = h - 1;
+ toskew = -(int32)(tw + w);
+ }
+ else {
+ y = 0;
+ toskew = -(int32)(tw - w);
+ }
+
+ switch( img->photometric )
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_PALETTE:
+ colorchannels = 1;
+ p2 = p1 = p0;
+ break;
+
+ default:
+ colorchannels = 3;
+ break;
+ }
+
+ for (row = 0; row < h; row += nrow)
+ {
+ rowstoread = th - (row + img->row_offset) % th;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ for (col = 0; col < w; col += tw)
+ {
+ if (TIFFReadTile(tif, p0, col+img->col_offset,
+ row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1
+ && TIFFReadTile(tif, p1, col+img->col_offset,
+ row+img->row_offset,0,1) == (tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1
+ && TIFFReadTile(tif, p2, col+img->col_offset,
+ row+img->row_offset,0,2) == (tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (alpha
+ && TIFFReadTile(tif,pa,col+img->col_offset,
+ row+img->row_offset,0,colorchannels) == (tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+
+ pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
+
+ if (col + tw > w)
+ {
+ /*
+ * Tile is clipped horizontally. Calculate
+ * visible portion and skewing factors.
+ */
+ uint32 npix = w - col;
+ fromskew = tw - npix;
+ (*put)(img, raster+y*w+col, col, y,
+ npix, nrow, fromskew, toskew + fromskew,
+ p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
+ } else {
+ (*put)(img, raster+y*w+col, col, y,
+ tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
+ }
+ }
+
+ y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
+ }
+
+ if (flip & FLIP_HORIZONTALLY) {
+ uint32 line;
+
+ for (line = 0; line < h; line++) {
+ uint32 *left = raster + (line * w);
+ uint32 *right = left + w - 1;
+
+ while ( left < right ) {
+ uint32 temp = *left;
+ *left = *right;
+ *right = temp;
+ left++, right--;
+ }
+ }
+ }
+
+ _TIFFfree(buf);
+ return (ret);
+}
+
+/*
+ * Get a strip-organized image that has
+ * PlanarConfiguration contiguous if SamplesPerPixel > 1
+ * or
+ * SamplesPerPixel == 1
+ */
+static int
+gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+ TIFF* tif = img->tif;
+ tileContigRoutine put = img->put.contig;
+ uint32 row, y, nrow, nrowsub, rowstoread;
+ tmsize_t pos;
+ unsigned char* buf;
+ uint32 rowsperstrip;
+ uint16 subsamplinghor,subsamplingver;
+ uint32 imagewidth = img->width;
+ tmsize_t scanline;
+ int32 fromskew, toskew;
+ int ret = 1, flip;
+
+ buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
+ if (buf == 0) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
+ return (0);
+ }
+ _TIFFmemset(buf, 0, TIFFStripSize(tif));
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY) {
+ y = h - 1;
+ toskew = -(int32)(w + w);
+ } else {
+ y = 0;
+ toskew = -(int32)(w - w);
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
+ scanline = TIFFScanlineSize(tif);
+ fromskew = (w < imagewidth ? imagewidth - w : 0);
+ for (row = 0; row < h; row += nrow)
+ {
+ rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ nrowsub = nrow;
+ if ((nrowsub%subsamplingver)!=0)
+ nrowsub+=subsamplingver-nrowsub%subsamplingver;
+ if (TIFFReadEncodedStrip(tif,
+ TIFFComputeStrip(tif,row+img->row_offset, 0),
+ buf,
+ ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+
+ pos = ((row + img->row_offset) % rowsperstrip) * scanline;
+ (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
+ y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+ }
+
+ if (flip & FLIP_HORIZONTALLY) {
+ uint32 line;
+
+ for (line = 0; line < h; line++) {
+ uint32 *left = raster + (line * w);
+ uint32 *right = left + w - 1;
+
+ while ( left < right ) {
+ uint32 temp = *left;
+ *left = *right;
+ *right = temp;
+ left++, right--;
+ }
+ }
+ }
+
+ _TIFFfree(buf);
+ return (ret);
+}
+
+/*
+ * Get a strip-organized image with
+ * SamplesPerPixel > 1
+ * PlanarConfiguration separated
+ * We assume that all such images are RGB.
+ */
+static int
+gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
+{
+ TIFF* tif = img->tif;
+ tileSeparateRoutine put = img->put.separate;
+ unsigned char *buf;
+ unsigned char *p0, *p1, *p2, *pa;
+ uint32 row, y, nrow, rowstoread;
+ tmsize_t pos;
+ tmsize_t scanline;
+ uint32 rowsperstrip, offset_row;
+ uint32 imagewidth = img->width;
+ tmsize_t stripsize;
+ tmsize_t bufsize;
+ int32 fromskew, toskew;
+ int alpha = img->alpha;
+ int ret = 1, flip, colorchannels;
+
+ stripsize = TIFFStripSize(tif);
+ bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
+ if (bufsize == 0) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
+ return (0);
+ }
+ p0 = buf = (unsigned char *)_TIFFmalloc(bufsize);
+ if (buf == 0) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
+ return (0);
+ }
+ _TIFFmemset(buf, 0, bufsize);
+ p1 = p0 + stripsize;
+ p2 = p1 + stripsize;
+ pa = (alpha?(p2+stripsize):NULL);
+
+ flip = setorientation(img);
+ if (flip & FLIP_VERTICALLY) {
+ y = h - 1;
+ toskew = -(int32)(w + w);
+ }
+ else {
+ y = 0;
+ toskew = -(int32)(w - w);
+ }
+
+ switch( img->photometric )
+ {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_PALETTE:
+ colorchannels = 1;
+ p2 = p1 = p0;
+ break;
+
+ default:
+ colorchannels = 3;
+ break;
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+ scanline = TIFFScanlineSize(tif);
+ fromskew = (w < imagewidth ? imagewidth - w : 0);
+ for (row = 0; row < h; row += nrow)
+ {
+ rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
+ nrow = (row + rowstoread > h ? h - row : rowstoread);
+ offset_row = row + img->row_offset;
+ if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
+ p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1
+ && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
+ p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (colorchannels > 1
+ && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
+ p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ if (alpha)
+ {
+ if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
+ pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
+ && img->stoponerr)
+ {
+ ret = 0;
+ break;
+ }
+ }
+
+ pos = ((row + img->row_offset) % rowsperstrip) * scanline;
+ (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
+ p2 + pos, (alpha?(pa+pos):NULL));
+ y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
+ }
+
+ if (flip & FLIP_HORIZONTALLY) {
+ uint32 line;
+
+ for (line = 0; line < h; line++) {
+ uint32 *left = raster + (line * w);
+ uint32 *right = left + w - 1;
+
+ while ( left < right ) {
+ uint32 temp = *left;
+ *left = *right;
+ *right = temp;
+ left++, right--;
+ }
+ }
+ }
+
+ _TIFFfree(buf);
+ return (ret);
+}
+
+/*
+ * The following routines move decoded data returned
+ * from the TIFF library into rasters filled with packed
+ * ABGR pixels (i.e. suitable for passing to lrecwrite.)
+ *
+ * The routines have been created according to the most
+ * important cases and optimized. PickContigCase and
+ * PickSeparateCase analyze the parameters and select
+ * the appropriate "get" and "put" routine to use.
+ */
+#define REPEAT8(op) REPEAT4(op); REPEAT4(op)
+#define REPEAT4(op) REPEAT2(op); REPEAT2(op)
+#define REPEAT2(op) op; op
+#define CASE8(x,op) \
+ switch (x) { \
+ case 7: op; case 6: op; case 5: op; \
+ case 4: op; case 3: op; case 2: op; \
+ case 1: op; \
+ }
+#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
+#define NOP
+
+#define UNROLL8(w, op1, op2) { \
+ uint32 _x; \
+ for (_x = w; _x >= 8; _x -= 8) { \
+ op1; \
+ REPEAT8(op2); \
+ } \
+ if (_x > 0) { \
+ op1; \
+ CASE8(_x,op2); \
+ } \
+}
+#define UNROLL4(w, op1, op2) { \
+ uint32 _x; \
+ for (_x = w; _x >= 4; _x -= 4) { \
+ op1; \
+ REPEAT4(op2); \
+ } \
+ if (_x > 0) { \
+ op1; \
+ CASE4(_x,op2); \
+ } \
+}
+#define UNROLL2(w, op1, op2) { \
+ uint32 _x; \
+ for (_x = w; _x >= 2; _x -= 2) { \
+ op1; \
+ REPEAT2(op2); \
+ } \
+ if (_x) { \
+ op1; \
+ op2; \
+ } \
+}
+
+#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
+#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
+
+#define A1 (((uint32)0xffL)<<24)
+#define PACK(r,g,b) \
+ ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
+#define PACK4(r,g,b,a) \
+ ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
+#define W2B(v) (((v)>>8)&0xff)
+/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
+#define PACKW(r,g,b) \
+ ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
+#define PACKW4(r,g,b,a) \
+ ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
+
+#define DECLAREContigPutFunc(name) \
+static void name(\
+ TIFFRGBAImage* img, \
+ uint32* cp, \
+ uint32 x, uint32 y, \
+ uint32 w, uint32 h, \
+ int32 fromskew, int32 toskew, \
+ unsigned char* pp \
+)
+
+/*
+ * 8-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put8bitcmaptile)
+{
+ uint32** PALmap = img->PALmap;
+ int samplesperpixel = img->samplesperpixel;
+
+ (void) y;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;)
+ {
+ *cp++ = PALmap[*pp][0];
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 4-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put4bitcmaptile)
+{
+ uint32** PALmap = img->PALmap;
+
+ (void) x; (void) y;
+ fromskew /= 2;
+ while (h-- > 0) {
+ uint32* bw;
+ UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 2-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put2bitcmaptile)
+{
+ uint32** PALmap = img->PALmap;
+
+ (void) x; (void) y;
+ fromskew /= 4;
+ while (h-- > 0) {
+ uint32* bw;
+ UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 1-bit palette => colormap/RGB
+ */
+DECLAREContigPutFunc(put1bitcmaptile)
+{
+ uint32** PALmap = img->PALmap;
+
+ (void) x; (void) y;
+ fromskew /= 8;
+ while (h-- > 0) {
+ uint32* bw;
+ UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(putgreytile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint32** BWmap = img->BWmap;
+
+ (void) y;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;)
+ {
+ *cp++ = BWmap[*pp][0];
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit greyscale with associated alpha => colormap/RGBA
+ */
+DECLAREContigPutFunc(putagreytile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint32** BWmap = img->BWmap;
+
+ (void) y;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;)
+ {
+ *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1);
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 16-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put16bitbwtile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint32** BWmap = img->BWmap;
+
+ (void) y;
+ while (h-- > 0) {
+ uint16 *wp = (uint16 *) pp;
+
+ for (x = w; x-- > 0;)
+ {
+ /* use high order byte of 16bit value */
+
+ *cp++ = BWmap[*wp >> 8][0];
+ pp += 2 * samplesperpixel;
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 1-bit bilevel => colormap/RGB
+ */
+DECLAREContigPutFunc(put1bitbwtile)
+{
+ uint32** BWmap = img->BWmap;
+
+ (void) x; (void) y;
+ fromskew /= 8;
+ while (h-- > 0) {
+ uint32* bw;
+ UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 2-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put2bitbwtile)
+{
+ uint32** BWmap = img->BWmap;
+
+ (void) x; (void) y;
+ fromskew /= 4;
+ while (h-- > 0) {
+ uint32* bw;
+ UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 4-bit greyscale => colormap/RGB
+ */
+DECLAREContigPutFunc(put4bitbwtile)
+{
+ uint32** BWmap = img->BWmap;
+
+ (void) x; (void) y;
+ fromskew /= 2;
+ while (h-- > 0) {
+ uint32* bw;
+ UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed samples, no Map => RGB
+ */
+DECLAREContigPutFunc(putRGBcontig8bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+
+ (void) x; (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ UNROLL8(w, NOP,
+ *cp++ = PACK(pp[0], pp[1], pp[2]);
+ pp += samplesperpixel);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed samples => RGBA w/ associated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBAAcontig8bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+
+ (void) x; (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ UNROLL8(w, NOP,
+ *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
+ pp += samplesperpixel);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed samples => RGBA w/ unassociated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBUAcontig8bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ uint32 r, g, b, a;
+ uint8* m;
+ for (x = w; x-- > 0;) {
+ a = pp[3];
+ m = img->UaToAa+(a<<8);
+ r = m[pp[0]];
+ g = m[pp[1]];
+ b = m[pp[2]];
+ *cp++ = PACK4(r,g,b,a);
+ pp += samplesperpixel;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed samples => RGB
+ */
+DECLAREContigPutFunc(putRGBcontig16bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16 *wp = (uint16 *)pp;
+ (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;) {
+ *cp++ = PACK(img->Bitdepth16To8[wp[0]],
+ img->Bitdepth16To8[wp[1]],
+ img->Bitdepth16To8[wp[2]]);
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed samples => RGBA w/ associated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBAAcontig16bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16 *wp = (uint16 *)pp;
+ (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;) {
+ *cp++ = PACK4(img->Bitdepth16To8[wp[0]],
+ img->Bitdepth16To8[wp[1]],
+ img->Bitdepth16To8[wp[2]],
+ img->Bitdepth16To8[wp[3]]);
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed samples => RGBA w/ unassociated alpha
+ * (known to have Map == NULL)
+ */
+DECLAREContigPutFunc(putRGBUAcontig16bittile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16 *wp = (uint16 *)pp;
+ (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ uint32 r,g,b,a;
+ uint8* m;
+ for (x = w; x-- > 0;) {
+ a = img->Bitdepth16To8[wp[3]];
+ m = img->UaToAa+(a<<8);
+ r = m[img->Bitdepth16To8[wp[0]]];
+ g = m[img->Bitdepth16To8[wp[1]]];
+ b = m[img->Bitdepth16To8[wp[2]]];
+ *cp++ = PACK4(r,g,b,a);
+ wp += samplesperpixel;
+ }
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed CMYK samples w/o Map => RGB
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+/*DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16 r, g, b, k;
+
+ (void) x; (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ UNROLL8(w, NOP,
+ k = 255 - pp[3];
+ r = (k*(255-pp[0]))/255;
+ g = (k*(255-pp[1]))/255;
+ b = (k*(255-pp[2]))/255;
+ *cp++ = PACK(r, g, b);
+ pp += samplesperpixel);
+ cp += toskew;
+ pp += fromskew;
+}*/
+/* Modify in 20090723 by Sunliang.Liu */
+DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint8 r, g, b, k;
+
+ (void) x; (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ UNROLL8(w, NOP,
+ if(!TIFFCmyk2Rgb(img->tif->tif_clientdata,pp[0],pp[1],pp[2],pp[3],
+ &r,&g,&b)){
+ k = 255 - pp[3];
+ r = (k*(255-pp[0]))/255;
+ g = (k*(255-pp[1]))/255;
+ b = (k*(255-pp[2]))/255;
+ }
+
+ *cp++ = PACK(r, g, b);
+ pp += samplesperpixel);
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * 16-bit packed CMYK samples w/o Map => RGB(8-bit)
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+DECLAREContigPutFunc(putRGBcontig16bitCMYKtile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ uint16* wp = (uint16*)pp;
+ uint8 C, M, Y, K;
+ uint8 r, g, b;
+
+ (void) x; (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ UNROLL8(w, NOP,
+ C = wp[0]>>8;M = wp[1]>>8;Y = wp[2]>>8;K = wp[3]>>8;
+ if(!TIFFCmyk2Rgb(img->tif->tif_clientdata,C,M,Y,K,
+ &r,&g,&b)){
+ K = 255 - K;
+ r = (K*(255-C))/255;
+ g = (K*(255-M))/255;
+ b = (K*(255-Y))/255;
+ }
+
+ *cp++ = PACK(r, g, b);
+ wp += samplesperpixel);
+ cp += toskew;
+ wp += fromskew;
+ }
+}
+
+/*
+ * 8-bit packed CMYK samples w/Map => RGB
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+/*
+DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ TIFFRGBValue* Map = img->Map;
+ uint16 r, g, b, k;
+
+ (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;) {
+ k = 255 - pp[3];
+ r = (k*(255-pp[0]))/255;
+ g = (k*(255-pp[1]))/255;
+ b = (k*(255-pp[2]))/255;
+ *cp++ = PACK(Map[r], Map[g], Map[b]);
+ pp += samplesperpixel;
+ }
+ pp += fromskew;
+ cp += toskew;
+ }
+}*/
+/* Modify in 20090723 by Sunliang.Liu */
+DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ TIFFRGBValue* Map = img->Map;
+ uint8 r, g, b, k;
+
+ (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;) {
+ if(!TIFFCmyk2Rgb(img->tif->tif_clientdata,pp[0],pp[1],pp[2],pp[3],
+ &r,&g,&b)){
+ k = 255 - pp[3];
+ r = (k*(255-pp[0]))/255;
+ g = (k*(255-pp[1]))/255;
+ b = (k*(255-pp[2]))/255;
+ }
+ *cp++ = PACK(Map[r], Map[g], Map[b]);
+ pp += samplesperpixel;
+ }
+ pp += fromskew;
+ cp += toskew;
+ }
+}
+
+/*
+ * 16-bit packed CMYK samples w/Map => RGB(8-bit)
+ *
+ * NB: The conversion of CMYK->RGB is *very* crude.
+ */
+DECLAREContigPutFunc(putRGBcontig16bitCMYKMaptile)
+{
+ int samplesperpixel = img->samplesperpixel;
+ TIFFRGBValue* Map = img->Map;
+ uint16* wp = (uint16*)pp;
+ uint8 C, M, Y, K;
+ uint8 r, g, b;
+
+ (void) y;
+ fromskew *= samplesperpixel;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;) {
+ C = wp[0]>>8;M = wp[1]>>8;Y = wp[2]>>8;K = wp[3]>>8;
+ if(!TIFFCmyk2Rgb(img->tif->tif_clientdata,C,M,Y,K,
+ &r,&g,&b)){
+ K = 255 - K;
+ r = (K*(255-C))/255;
+ g = (K*(255-M))/255;
+ b = (K*(255-Y))/255;
+ }
+ *cp++ = PACK(Map[r], Map[g], Map[b]);
+ wp += samplesperpixel;
+ }
+ wp += fromskew;
+ cp += toskew;
+ }
+}
+
+#define DECLARESepPutFunc(name) \
+static void name(\
+ TIFFRGBAImage* img,\
+ uint32* cp,\
+ uint32 x, uint32 y, \
+ uint32 w, uint32 h,\
+ int32 fromskew, int32 toskew,\
+ unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
+)
+
+/*
+ * 8-bit unpacked samples => RGB
+ */
+DECLARESepPutFunc(putRGBseparate8bittile)
+{
+ (void) img; (void) x; (void) y; (void) a;
+ while (h-- > 0) {
+ UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
+ SKEW(r, g, b, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit unpacked samples => RGBA w/ associated alpha
+ */
+DECLARESepPutFunc(putRGBAAseparate8bittile)
+{
+ (void) img; (void) x; (void) y;
+ while (h-- > 0) {
+ UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
+ SKEW4(r, g, b, a, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit unpacked CMYK samples => RGBA
+ */
+DECLARESepPutFunc(putCMYKseparate8bittile)
+{
+ (void) img; (void) y;
+ while (h-- > 0) {
+ uint32 rv, gv, bv, kv;
+ for (x = w; x-- > 0;) {
+ kv = 255 - *a++;
+ rv = (kv*(255-*r++))/255;
+ gv = (kv*(255-*g++))/255;
+ bv = (kv*(255-*b++))/255;
+ *cp++ = PACK4(rv,gv,bv,255);
+ }
+ SKEW4(r, g, b, a, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit unpacked samples => RGBA w/ unassociated alpha
+ */
+DECLARESepPutFunc(putRGBUAseparate8bittile)
+{
+ (void) img; (void) y;
+ while (h-- > 0) {
+ uint32 rv, gv, bv, av;
+ uint8* m;
+ for (x = w; x-- > 0;) {
+ av = *a++;
+ m = img->UaToAa+(av<<8);
+ rv = m[*r++];
+ gv = m[*g++];
+ bv = m[*b++];
+ *cp++ = PACK4(rv,gv,bv,av);
+ }
+ SKEW4(r, g, b, a, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 16-bit unpacked samples => RGB
+ */
+DECLARESepPutFunc(putRGBseparate16bittile)
+{
+ uint16 *wr = (uint16*) r;
+ uint16 *wg = (uint16*) g;
+ uint16 *wb = (uint16*) b;
+ (void) img; (void) y; (void) a;
+ while (h-- > 0) {
+ for (x = 0; x < w; x++)
+ *cp++ = PACK(img->Bitdepth16To8[*wr++],
+ img->Bitdepth16To8[*wg++],
+ img->Bitdepth16To8[*wb++]);
+ SKEW(wr, wg, wb, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 16-bit unpacked samples => RGBA w/ associated alpha
+ */
+DECLARESepPutFunc(putRGBAAseparate16bittile)
+{
+ uint16 *wr = (uint16*) r;
+ uint16 *wg = (uint16*) g;
+ uint16 *wb = (uint16*) b;
+ uint16 *wa = (uint16*) a;
+ (void) img; (void) y;
+ while (h-- > 0) {
+ for (x = 0; x < w; x++)
+ *cp++ = PACK4(img->Bitdepth16To8[*wr++],
+ img->Bitdepth16To8[*wg++],
+ img->Bitdepth16To8[*wb++],
+ img->Bitdepth16To8[*wa++]);
+ SKEW4(wr, wg, wb, wa, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 16-bit unpacked samples => RGBA w/ unassociated alpha
+ */
+DECLARESepPutFunc(putRGBUAseparate16bittile)
+{
+ uint16 *wr = (uint16*) r;
+ uint16 *wg = (uint16*) g;
+ uint16 *wb = (uint16*) b;
+ uint16 *wa = (uint16*) a;
+ (void) img; (void) y;
+ while (h-- > 0) {
+ uint32 r,g,b,a;
+ uint8* m;
+ for (x = w; x-- > 0;) {
+ a = img->Bitdepth16To8[*wa++];
+ m = img->UaToAa+(a<<8);
+ r = m[img->Bitdepth16To8[*wr++]];
+ g = m[img->Bitdepth16To8[*wg++]];
+ b = m[img->Bitdepth16To8[*wb++]];
+ *cp++ = PACK4(r,g,b,a);
+ }
+ SKEW4(wr, wg, wb, wa, fromskew);
+ cp += toskew;
+ }
+}
+
+/*
+ * 8-bit packed CIE L*a*b 1976 samples => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitCIELab)
+{
+ float X, Y, Z;
+ uint32 r, g, b;
+ (void) y;
+ fromskew *= 3;
+ while (h-- > 0) {
+ for (x = w; x-- > 0;) {
+ TIFFCIELabToXYZ(img->cielab,
+ (unsigned char)pp[0],
+ (signed char)pp[1],
+ (signed char)pp[2],
+ &X, &Y, &Z);
+ TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
+ *cp++ = PACK(r, g, b);
+ pp += 3;
+ }
+ cp += toskew;
+ pp += fromskew;
+ }
+}
+
+/*
+ * YCbCr -> RGB conversion and packing routines.
+ */
+
+#define YCbCrtoRGB(dst, Y) { \
+ uint32 r, g, b; \
+ TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
+ dst = PACK(r, g, b); \
+}
+
+/*
+ * 8-bit packed YCbCr samples => RGB
+ * This function is generic for different sampling sizes,
+ * and can handle blocks sizes that aren't multiples of the
+ * sampling size. However, it is substantially less optimized
+ * than the specific sampling cases. It is used as a fallback
+ * for difficult blocks.
+ */
+#ifdef notdef
+static void putcontig8bitYCbCrGenericTile(
+ TIFFRGBAImage* img,
+ uint32* cp,
+ uint32 x, uint32 y,
+ uint32 w, uint32 h,
+ int32 fromskew, int32 toskew,
+ unsigned char* pp,
+ int h_group,
+ int v_group )
+
+{
+ uint32* cp1 = cp+w+toskew;
+ uint32* cp2 = cp1+w+toskew;
+ uint32* cp3 = cp2+w+toskew;
+ int32 incr = 3*w+4*toskew;
+ int32 Cb, Cr;
+ int group_size = v_group * h_group + 2;
+
+ (void) y;
+ fromskew = (fromskew * group_size) / h_group;
+
+ for( yy = 0; yy < h; yy++ )
+ {
+ unsigned char *pp_line;
+ int y_line_group = yy / v_group;
+ int y_remainder = yy - y_line_group * v_group;
+
+ pp_line = pp + v_line_group *
+
+
+ for( xx = 0; xx < w; xx++ )
+ {
+ Cb = pp
+ }
+ }
+ for (; h >= 4; h -= 4) {
+ x = w>>2;
+ do {
+ Cb = pp[16];
+ Cr = pp[17];
+
+ YCbCrtoRGB(cp [0], pp[ 0]);
+ YCbCrtoRGB(cp [1], pp[ 1]);
+ YCbCrtoRGB(cp [2], pp[ 2]);
+ YCbCrtoRGB(cp [3], pp[ 3]);
+ YCbCrtoRGB(cp1[0], pp[ 4]);
+ YCbCrtoRGB(cp1[1], pp[ 5]);
+ YCbCrtoRGB(cp1[2], pp[ 6]);
+ YCbCrtoRGB(cp1[3], pp[ 7]);
+ YCbCrtoRGB(cp2[0], pp[ 8]);
+ YCbCrtoRGB(cp2[1], pp[ 9]);
+ YCbCrtoRGB(cp2[2], pp[10]);
+ YCbCrtoRGB(cp2[3], pp[11]);
+ YCbCrtoRGB(cp3[0], pp[12]);
+ YCbCrtoRGB(cp3[1], pp[13]);
+ YCbCrtoRGB(cp3[2], pp[14]);
+ YCbCrtoRGB(cp3[3], pp[15]);
+
+ cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
+ pp += 18;
+ } while (--x);
+ cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
+ pp += fromskew;
+ }
+}
+#endif
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
+{
+ uint32* cp1 = cp+w+toskew;
+ uint32* cp2 = cp1+w+toskew;
+ uint32* cp3 = cp2+w+toskew;
+ int32 incr = 3*w+4*toskew;
+
+ (void) y;
+ /* adjust fromskew */
+ fromskew = (fromskew * 18) / 4;
+ if ((h & 3) == 0 && (w & 3) == 0) {
+ for (; h >= 4; h -= 4) {
+ x = w>>2;
+ do {
+ int32 Cb = pp[16];
+ int32 Cr = pp[17];
+
+ YCbCrtoRGB(cp [0], pp[ 0]);
+ YCbCrtoRGB(cp [1], pp[ 1]);
+ YCbCrtoRGB(cp [2], pp[ 2]);
+ YCbCrtoRGB(cp [3], pp[ 3]);
+ YCbCrtoRGB(cp1[0], pp[ 4]);
+ YCbCrtoRGB(cp1[1], pp[ 5]);
+ YCbCrtoRGB(cp1[2], pp[ 6]);
+ YCbCrtoRGB(cp1[3], pp[ 7]);
+ YCbCrtoRGB(cp2[0], pp[ 8]);
+ YCbCrtoRGB(cp2[1], pp[ 9]);
+ YCbCrtoRGB(cp2[2], pp[10]);
+ YCbCrtoRGB(cp2[3], pp[11]);
+ YCbCrtoRGB(cp3[0], pp[12]);
+ YCbCrtoRGB(cp3[1], pp[13]);
+ YCbCrtoRGB(cp3[2], pp[14]);
+ YCbCrtoRGB(cp3[3], pp[15]);
+
+ cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
+ pp += 18;
+ } while (--x);
+ cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
+ pp += fromskew;
+ }
+ } else {
+ while (h > 0) {
+ for (x = w; x > 0;) {
+ int32 Cb = pp[16];
+ int32 Cr = pp[17];
+ switch (x) {
+ default:
+ switch (h) {
+ default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
+ case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
+ case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 3:
+ switch (h) {
+ default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
+ case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
+ case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 2:
+ switch (h) {
+ default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
+ case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
+ case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 1:
+ switch (h) {
+ default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
+ case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
+ case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ }
+ if (x < 4) {
+ cp += x; cp1 += x; cp2 += x; cp3 += x;
+ x = 0;
+ }
+ else {
+ cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
+ x -= 4;
+ }
+ pp += 18;
+ }
+ if (h <= 4)
+ break;
+ h -= 4;
+ cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
+ pp += fromskew;
+ }
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
+{
+ uint32* cp1 = cp+w+toskew;
+ int32 incr = 2*toskew+w;
+
+ (void) y;
+ fromskew = (fromskew * 10) / 4;
+ if ((h & 3) == 0 && (w & 1) == 0) {
+ for (; h >= 2; h -= 2) {
+ x = w>>2;
+ do {
+ int32 Cb = pp[8];
+ int32 Cr = pp[9];
+
+ YCbCrtoRGB(cp [0], pp[0]);
+ YCbCrtoRGB(cp [1], pp[1]);
+ YCbCrtoRGB(cp [2], pp[2]);
+ YCbCrtoRGB(cp [3], pp[3]);
+ YCbCrtoRGB(cp1[0], pp[4]);
+ YCbCrtoRGB(cp1[1], pp[5]);
+ YCbCrtoRGB(cp1[2], pp[6]);
+ YCbCrtoRGB(cp1[3], pp[7]);
+
+ cp += 4, cp1 += 4;
+ pp += 10;
+ } while (--x);
+ cp += incr, cp1 += incr;
+ pp += fromskew;
+ }
+ } else {
+ while (h > 0) {
+ for (x = w; x > 0;) {
+ int32 Cb = pp[8];
+ int32 Cr = pp[9];
+ switch (x) {
+ default:
+ switch (h) {
+ default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 3:
+ switch (h) {
+ default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 2:
+ switch (h) {
+ default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ case 1:
+ switch (h) {
+ default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
+ case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
+ } /* FALLTHROUGH */
+ }
+ if (x < 4) {
+ cp += x; cp1 += x;
+ x = 0;
+ }
+ else {
+ cp += 4; cp1 += 4;
+ x -= 4;
+ }
+ pp += 10;
+ }
+ if (h <= 2)
+ break;
+ h -= 2;
+ cp += incr, cp1 += incr;
+ pp += fromskew;
+ }
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
+{
+ (void) y;
+ /* XXX adjust fromskew */
+ do {
+ x = w>>2;
+ do {
+ int32 Cb = pp[4];
+ int32 Cr = pp[5];
+
+ YCbCrtoRGB(cp [0], pp[0]);
+ YCbCrtoRGB(cp [1], pp[1]);
+ YCbCrtoRGB(cp [2], pp[2]);
+ YCbCrtoRGB(cp [3], pp[3]);
+
+ cp += 4;
+ pp += 6;
+ } while (--x);
+
+ if( (w&3) != 0 )
+ {
+ int32 Cb = pp[4];
+ int32 Cr = pp[5];
+
+ switch( (w&3) ) {
+ case 3: YCbCrtoRGB(cp [2], pp[2]);
+ case 2: YCbCrtoRGB(cp [1], pp[1]);
+ case 1: YCbCrtoRGB(cp [0], pp[0]);
+ case 0: break;
+ }
+
+ cp += (w&3);
+ pp += 6;
+ }
+
+ cp += toskew;
+ pp += fromskew;
+ } while (--h);
+
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
+{
+ uint32* cp2;
+ int32 incr = 2*toskew+w;
+ (void) y;
+ fromskew = (fromskew / 2) * 6;
+ cp2 = cp+w+toskew;
+ while (h>=2) {
+ x = w;
+ while (x>=2) {
+ uint32 Cb = pp[4];
+ uint32 Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+ YCbCrtoRGB(cp2[0], pp[2]);
+ YCbCrtoRGB(cp2[1], pp[3]);
+ cp += 2;
+ cp2 += 2;
+ pp += 6;
+ x -= 2;
+ }
+ if (x==1) {
+ uint32 Cb = pp[4];
+ uint32 Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp2[0], pp[2]);
+ cp ++ ;
+ cp2 ++ ;
+ pp += 6;
+ }
+ cp += incr;
+ cp2 += incr;
+ pp += fromskew;
+ h-=2;
+ }
+ if (h==1) {
+ x = w;
+ while (x>=2) {
+ uint32 Cb = pp[4];
+ uint32 Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+ cp += 2;
+ cp2 += 2;
+ pp += 6;
+ x -= 2;
+ }
+ if (x==1) {
+ uint32 Cb = pp[4];
+ uint32 Cr = pp[5];
+ YCbCrtoRGB(cp[0], pp[0]);
+ }
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
+{
+ (void) y;
+ fromskew = (fromskew * 4) / 2;
+ do {
+ x = w>>1;
+ do {
+ int32 Cb = pp[2];
+ int32 Cr = pp[3];
+
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp[1], pp[1]);
+
+ cp += 2;
+ pp += 4;
+ } while (--x);
+
+ if( (w&1) != 0 )
+ {
+ int32 Cb = pp[2];
+ int32 Cr = pp[3];
+
+ YCbCrtoRGB(cp[0], pp[0]);
+
+ cp += 1;
+ pp += 4;
+ }
+
+ cp += toskew;
+ pp += fromskew;
+ } while (--h);
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
+{
+ uint32* cp2;
+ int32 incr = 2*toskew+w;
+ (void) y;
+ fromskew = (fromskew / 2) * 4;
+ cp2 = cp+w+toskew;
+ while (h>=2) {
+ x = w;
+ do {
+ uint32 Cb = pp[2];
+ uint32 Cr = pp[3];
+ YCbCrtoRGB(cp[0], pp[0]);
+ YCbCrtoRGB(cp2[0], pp[1]);
+ cp ++;
+ cp2 ++;
+ pp += 4;
+ } while (--x);
+ cp += incr;
+ cp2 += incr;
+ pp += fromskew;
+ h-=2;
+ }
+ if (h==1) {
+ x = w;
+ do {
+ uint32 Cb = pp[2];
+ uint32 Cr = pp[3];
+ YCbCrtoRGB(cp[0], pp[0]);
+ cp ++;
+ pp += 4;
+ } while (--x);
+ }
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ no subsampling => RGB
+ */
+DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
+{
+ (void) y;
+ fromskew *= 3;
+ do {
+ x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
+ do {
+ int32 Cb = pp[1];
+ int32 Cr = pp[2];
+
+ YCbCrtoRGB(*cp++, pp[0]);
+
+ pp += 3;
+ } while (--x);
+ cp += toskew;
+ pp += fromskew;
+ } while (--h);
+}
+
+/*
+ * 8-bit packed YCbCr samples w/ no subsampling => RGB
+ */
+DECLARESepPutFunc(putseparate8bitYCbCr11tile)
+{
+ (void) y;
+ (void) a;
+ /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
+ while (h-- > 0) {
+ x = w;
+ do {
+ uint32 dr, dg, db;
+ TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
+ *cp++ = PACK(dr,dg,db);
+ } while (--x);
+ SKEW(r, g, b, fromskew);
+ cp += toskew;
+ }
+}
+#undef YCbCrtoRGB
+
+static int
+initYCbCrConversion(TIFFRGBAImage* img)
+{
+ static const char module[] = "initYCbCrConversion";
+
+ float *luma, *refBlackWhite;
+
+ if (img->ycbcr == NULL) {
+ img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
+ TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))
+ + 4*256*sizeof (TIFFRGBValue)
+ + 2*256*sizeof (int)
+ + 3*256*sizeof (int32)
+ );
+ if (img->ycbcr == NULL) {
+ TIFFErrorExt(img->tif->tif_clientdata, module,
+ "No space for YCbCr->RGB conversion state");
+ return (0);
+ }
+ }
+
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
+ &refBlackWhite);
+ if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
+ return(0);
+ return (1);
+}
+
+static tileContigRoutine
+initCIELabConversion(TIFFRGBAImage* img)
+{
+ static const char module[] = "initCIELabConversion";
+
+ float *whitePoint;
+ float refWhite[3];
+
+ if (!img->cielab) {
+ img->cielab = (TIFFCIELabToRGB *)
+ _TIFFmalloc(sizeof(TIFFCIELabToRGB));
+ if (!img->cielab) {
+ TIFFErrorExt(img->tif->tif_clientdata, module,
+ "No space for CIE L*a*b*->RGB conversion state.");
+ return NULL;
+ }
+ }
+
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
+ refWhite[1] = 100.0F;
+ refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
+ refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
+ / whitePoint[1] * refWhite[1];
+ if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
+ TIFFErrorExt(img->tif->tif_clientdata, module,
+ "Failed to initialize CIE L*a*b*->RGB conversion state.");
+ _TIFFfree(img->cielab);
+ return NULL;
+ }
+
+ return (tileContigRoutine)putcontig8bitCIELab;
+}
+
+/*
+ * Greyscale images with less than 8 bits/sample are handled
+ * with a table to avoid lots of shifts and masks. The table
+ * is setup so that put*bwtile (below) can retrieve 8/bitspersample
+ * pixel values simply by indexing into the table with one
+ * number.
+ */
+static int
+makebwmap(TIFFRGBAImage* img)
+{
+ TIFFRGBValue* Map = img->Map;
+ int bitspersample = img->bitspersample;
+ int nsamples = 8 / bitspersample;
+ int i;
+ uint32* p;
+
+ if( nsamples == 0 )
+ nsamples = 1;
+
+ img->BWmap = (uint32**) _TIFFmalloc(
+ 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
+ if (img->BWmap == NULL) {
+ TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
+ return (0);
+ }
+ p = (uint32*)(img->BWmap + 256);
+ for (i = 0; i < 256; i++) {
+ TIFFRGBValue c;
+ img->BWmap[i] = p;
+ switch (bitspersample) {
+#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
+ case 1:
+ GREY(i>>7);
+ GREY((i>>6)&1);
+ GREY((i>>5)&1);
+ GREY((i>>4)&1);
+ GREY((i>>3)&1);
+ GREY((i>>2)&1);
+ GREY((i>>1)&1);
+ GREY(i&1);
+ break;
+ case 2:
+ GREY(i>>6);
+ GREY((i>>4)&3);
+ GREY((i>>2)&3);
+ GREY(i&3);
+ break;
+ case 4:
+ GREY(i>>4);
+ GREY(i&0xf);
+ break;
+ case 8:
+ case 16:
+ GREY(i);
+ break;
+ }
+#undef GREY
+ }
+ return (1);
+}
+
+/*
+ * Construct a mapping table to convert from the range
+ * of the data samples to [0,255] --for display. This
+ * process also handles inverting B&W images when needed.
+ */
+static int
+setupMap(TIFFRGBAImage* img)
+{
+ int32 x, range;
+
+ range = (int32)((1L<<img->bitspersample)-1);
+
+ /* treat 16 bit the same as eight bit */
+ if( img->bitspersample == 16 )
+ range = (int32) 255;
+
+ img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
+ if (img->Map == NULL) {
+ TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
+ "No space for photometric conversion table");
+ return (0);
+ }
+ if (img->photometric == PHOTOMETRIC_MINISWHITE) {
+ for (x = 0; x <= range; x++)
+ img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
+ } else {
+ for (x = 0; x <= range; x++)
+ img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
+ }
+ if (img->bitspersample <= 16 &&
+ (img->photometric == PHOTOMETRIC_MINISBLACK ||
+ img->photometric == PHOTOMETRIC_MINISWHITE)) {
+ /*
+ * Use photometric mapping table to construct
+ * unpacking tables for samples <= 8 bits.
+ */
+ if (!makebwmap(img))
+ return (0);
+ /* no longer need Map, free it */
+ _TIFFfree(img->Map), img->Map = NULL;
+ }
+ return (1);
+}
+
+static int
+checkcmap(TIFFRGBAImage* img)
+{
+ uint16* r = img->redcmap;
+ uint16* g = img->greencmap;
+ uint16* b = img->bluecmap;
+ long n = 1L<<img->bitspersample;
+
+ while (n-- > 0)
+ if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
+ return (16);
+ return (8);
+}
+
+static void
+cvtcmap(TIFFRGBAImage* img)
+{
+ uint16* r = img->redcmap;
+ uint16* g = img->greencmap;
+ uint16* b = img->bluecmap;
+ long i;
+
+ for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
+#define CVT(x) ((uint16)((x)>>8))
+ r[i] = CVT(r[i]);
+ g[i] = CVT(g[i]);
+ b[i] = CVT(b[i]);
+#undef CVT
+ }
+}
+
+/*
+ * Palette images with <= 8 bits/sample are handled
+ * with a table to avoid lots of shifts and masks. The table
+ * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
+ * pixel values simply by indexing into the table with one
+ * number.
+ */
+static int
+makecmap(TIFFRGBAImage* img)
+{
+ int bitspersample = img->bitspersample;
+ int nsamples = 8 / bitspersample;
+ uint16* r = img->redcmap;
+ uint16* g = img->greencmap;
+ uint16* b = img->bluecmap;
+ uint32 *p;
+ int i;
+
+ img->PALmap = (uint32**) _TIFFmalloc(
+ 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
+ if (img->PALmap == NULL) {
+ TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
+ return (0);
+ }
+ p = (uint32*)(img->PALmap + 256);
+ for (i = 0; i < 256; i++) {
+ TIFFRGBValue c;
+ img->PALmap[i] = p;
+#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
+ switch (bitspersample) {
+ case 1:
+ CMAP(i>>7);
+ CMAP((i>>6)&1);
+ CMAP((i>>5)&1);
+ CMAP((i>>4)&1);
+ CMAP((i>>3)&1);
+ CMAP((i>>2)&1);
+ CMAP((i>>1)&1);
+ CMAP(i&1);
+ break;
+ case 2:
+ CMAP(i>>6);
+ CMAP((i>>4)&3);
+ CMAP((i>>2)&3);
+ CMAP(i&3);
+ break;
+ case 4:
+ CMAP(i>>4);
+ CMAP(i&0xf);
+ break;
+ case 8:
+ CMAP(i);
+ break;
+ }
+#undef CMAP
+ }
+ return (1);
+}
+
+/*
+ * Construct any mapping table used
+ * by the associated put routine.
+ */
+static int
+buildMap(TIFFRGBAImage* img)
+{
+ switch (img->photometric) {
+ case PHOTOMETRIC_RGB:
+ case PHOTOMETRIC_YCBCR:
+ case PHOTOMETRIC_SEPARATED:
+ if (img->bitspersample == 8)
+ break;
+ /* fall thru... */
+ case PHOTOMETRIC_MINISBLACK:
+ case PHOTOMETRIC_MINISWHITE:
+ if (!setupMap(img))
+ return (0);
+ break;
+ case PHOTOMETRIC_PALETTE:
+ /*
+ * Convert 16-bit colormap to 8-bit (unless it looks
+ * like an old-style 8-bit colormap).
+ */
+ if (checkcmap(img) == 16)
+ cvtcmap(img);
+ else
+ TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
+ /*
+ * Use mapping table and colormap to construct
+ * unpacking tables for samples < 8 bits.
+ */
+ if (img->bitspersample <= 8 && !makecmap(img))
+ return (0);
+ break;
+ }
+ return (1);
+}
+
+/*
+ * Select the appropriate conversion routine for packed data.
+ */
+static int
+PickContigCase(TIFFRGBAImage* img)
+{
+ img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
+ img->put.contig = NULL;
+ switch (img->photometric) {
+ case PHOTOMETRIC_RGB:
+ switch (img->bitspersample) {
+ case 8:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+ img->put.contig = putRGBAAcontig8bittile;
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+ {
+ if (BuildMapUaToAa(img))
+ img->put.contig = putRGBUAcontig8bittile;
+ }
+ else
+ img->put.contig = putRGBcontig8bittile;
+ break;
+ case 16:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.contig = putRGBAAcontig16bittile;
+ }
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+ {
+ if (BuildMapBitdepth16To8(img) &&
+ BuildMapUaToAa(img))
+ img->put.contig = putRGBUAcontig16bittile;
+ }
+ else
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.contig = putRGBcontig16bittile;
+ }
+ break;
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ if (buildMap(img)) {
+ if (img->bitspersample == 8) {
+ if (!img->Map)
+ img->put.contig = putRGBcontig8bitCMYKtile;
+ else
+ img->put.contig = putRGBcontig8bitCMYKMaptile;
+ }
+ else if(img->bitspersample == 16) /*LiuSunliang added 16bpp CMYK support.*/
+ {
+ if (!img->Map)
+ img->put.contig = putRGBcontig16bitCMYKtile;
+ else
+ img->put.contig = putRGBcontig16bitCMYKMaptile;
+ }
+ }
+ break;
+ case PHOTOMETRIC_PALETTE:
+ if (buildMap(img)) {
+ switch (img->bitspersample) {
+ case 8:
+ img->put.contig = put8bitcmaptile;
+ break;
+ case 4:
+ img->put.contig = put4bitcmaptile;
+ break;
+ case 2:
+ img->put.contig = put2bitcmaptile;
+ break;
+ case 1:
+ img->put.contig = put1bitcmaptile;
+ break;
+ }
+ }
+ break;
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ if (buildMap(img)) {
+ switch (img->bitspersample) {
+ case 16:
+ img->put.contig = put16bitbwtile;
+ break;
+ case 8:
+ if (img->alpha && img->samplesperpixel == 2)
+ img->put.contig = putagreytile;
+ else
+ img->put.contig = putgreytile;
+ break;
+ case 4:
+ img->put.contig = put4bitbwtile;
+ break;
+ case 2:
+ img->put.contig = put2bitbwtile;
+ break;
+ case 1:
+ img->put.contig = put1bitbwtile;
+ break;
+ }
+ }
+ break;
+ case PHOTOMETRIC_YCBCR:
+ if ((img->bitspersample==8) && (img->samplesperpixel==3))
+ {
+ if (initYCbCrConversion(img)!=0)
+ {
+ /*
+ * The 6.0 spec says that subsampling must be
+ * one of 1, 2, or 4, and that vertical subsampling
+ * must always be <= horizontal subsampling; so
+ * there are only a few possibilities and we just
+ * enumerate the cases.
+ * Joris: added support for the [1,2] case, nonetheless, to accomodate
+ * some OJPEG files
+ */
+ uint16 SubsamplingHor;
+ uint16 SubsamplingVer;
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
+ switch ((SubsamplingHor<<4)|SubsamplingVer) {
+ case 0x44:
+ img->put.contig = putcontig8bitYCbCr44tile;
+ break;
+ case 0x42:
+ img->put.contig = putcontig8bitYCbCr42tile;
+ break;
+ case 0x41:
+ img->put.contig = putcontig8bitYCbCr41tile;
+ break;
+ case 0x22:
+ img->put.contig = putcontig8bitYCbCr22tile;
+ break;
+ case 0x21:
+ img->put.contig = putcontig8bitYCbCr21tile;
+ break;
+ case 0x12:
+ img->put.contig = putcontig8bitYCbCr12tile;
+ break;
+ case 0x11:
+ img->put.contig = putcontig8bitYCbCr11tile;
+ break;
+ }
+ }
+ }
+ break;
+ case PHOTOMETRIC_CIELAB:
+ if (buildMap(img)) {
+ if (img->bitspersample == 8)
+ img->put.contig = initCIELabConversion(img);
+ break;
+ }
+ }
+ return ((img->get!=NULL) && (img->put.contig!=NULL));
+}
+
+/*
+ * Select the appropriate conversion routine for unpacked data.
+ *
+ * NB: we assume that unpacked single channel data is directed
+ * to the "packed routines.
+ */
+static int
+PickSeparateCase(TIFFRGBAImage* img)
+{
+ img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
+ img->put.separate = NULL;
+ switch (img->photometric) {
+ case PHOTOMETRIC_MINISWHITE:
+ case PHOTOMETRIC_MINISBLACK:
+ /* greyscale images processed pretty much as RGB by gtTileSeparate */
+ case PHOTOMETRIC_RGB:
+ switch (img->bitspersample) {
+ case 8:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+ img->put.separate = putRGBAAseparate8bittile;
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+ {
+ if (BuildMapUaToAa(img))
+ img->put.separate = putRGBUAseparate8bittile;
+ }
+ else
+ img->put.separate = putRGBseparate8bittile;
+ break;
+ case 16:
+ if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.separate = putRGBAAseparate16bittile;
+ }
+ else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
+ {
+ if (BuildMapBitdepth16To8(img) &&
+ BuildMapUaToAa(img))
+ img->put.separate = putRGBUAseparate16bittile;
+ }
+ else
+ {
+ if (BuildMapBitdepth16To8(img))
+ img->put.separate = putRGBseparate16bittile;
+ }
+ break;
+ }
+ break;
+ case PHOTOMETRIC_SEPARATED:
+ if (img->bitspersample == 8 && img->samplesperpixel == 4)
+ {
+ img->alpha = 1; // Not alpha, but seems like the only way to get 4th band
+ img->put.separate = putCMYKseparate8bittile;
+ }
+ break;
+ case PHOTOMETRIC_YCBCR:
+ if ((img->bitspersample==8) && (img->samplesperpixel==3))
+ {
+ if (initYCbCrConversion(img)!=0)
+ {
+ uint16 hs, vs;
+ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
+ switch ((hs<<4)|vs) {
+ case 0x11:
+ img->put.separate = putseparate8bitYCbCr11tile;
+ break;
+ /* TODO: add other cases here */
+ }
+ }
+ }
+ break;
+ }
+ return ((img->get!=NULL) && (img->put.separate!=NULL));
+}
+
+static int
+BuildMapUaToAa(TIFFRGBAImage* img)
+{
+ static const char module[]="BuildMapUaToAa";
+ uint8* m;
+ uint16 na,nv;
+ assert(img->UaToAa==NULL);
+ img->UaToAa=_TIFFmalloc(65536);
+ if (img->UaToAa==NULL)
+ {
+ TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ m=img->UaToAa;
+ for (na=0; na<256; na++)
+ {
+ for (nv=0; nv<256; nv++)
+ *m++=(nv*na+127)/255;
+ }
+ return(1);
+}
+
+static int
+BuildMapBitdepth16To8(TIFFRGBAImage* img)
+{
+ static const char module[]="BuildMapBitdepth16To8";
+ uint8* m;
+ uint32 n;
+ assert(img->Bitdepth16To8==NULL);
+ img->Bitdepth16To8=_TIFFmalloc(65536);
+ if (img->Bitdepth16To8==NULL)
+ {
+ TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ m=img->Bitdepth16To8;
+ for (n=0; n<65536; n++)
+ *m++=(n+128)/257;
+ return(1);
+}
+
+
+/*
+ * Read a whole strip off data from the file, and convert to RGBA form.
+ * If this is the last strip, then it will only contain the portion of
+ * the strip that is actually within the image space. The result is
+ * organized in bottom to top form.
+ */
+
+
+int
+TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
+
+{
+ char emsg[1024] = "";
+ TIFFRGBAImage img;
+ int ok;
+ uint32 rowsperstrip, rows_to_read;
+
+ if( TIFFIsTiled( tif ) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+ "Can't use TIFFReadRGBAStrip() with tiled file.");
+ return (0);
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
+ if( (row % rowsperstrip) != 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+ "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
+ return (0);
+ }
+
+ if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
+
+ img.row_offset = row;
+ img.col_offset = 0;
+
+ if( row + rowsperstrip > img.height )
+ rows_to_read = img.height - row;
+ else
+ rows_to_read = rowsperstrip;
+
+ ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
+
+ TIFFRGBAImageEnd(&img);
+ } else {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
+ ok = 0;
+ }
+
+ return (ok);
+}
+
+/*
+ * Read a whole tile off data from the file, and convert to RGBA form.
+ * The returned RGBA data is organized from bottom to top of tile,
+ * and may include zeroed areas if the tile extends off the image.
+ */
+
+int
+TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
+
+{
+ char emsg[1024] = "";
+ TIFFRGBAImage img;
+ int ok;
+ uint32 tile_xsize, tile_ysize;
+ uint32 read_xsize, read_ysize;
+ uint32 i_row;
+
+ /*
+ * Verify that our request is legal - on a tile file, and on a
+ * tile boundary.
+ */
+
+ if( !TIFFIsTiled( tif ) )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+ "Can't use TIFFReadRGBATile() with stripped file.");
+ return (0);
+ }
+
+ TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
+ TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
+ if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
+ "Row/col passed to TIFFReadRGBATile() must be top"
+ "left corner of a tile.");
+ return (0);
+ }
+
+ /*
+ * Setup the RGBA reader.
+ */
+
+ if (!TIFFRGBAImageOK(tif, emsg)
+ || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
+ TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
+ return( 0 );
+ }
+
+ /*
+ * The TIFFRGBAImageGet() function doesn't allow us to get off the
+ * edge of the image, even to fill an otherwise valid tile. So we
+ * figure out how much we can read, and fix up the tile buffer to
+ * a full tile configuration afterwards.
+ */
+
+ if( row + tile_ysize > img.height )
+ read_ysize = img.height - row;
+ else
+ read_ysize = tile_ysize;
+
+ if( col + tile_xsize > img.width )
+ read_xsize = img.width - col;
+ else
+ read_xsize = tile_xsize;
+
+ /*
+ * Read the chunk of imagery.
+ */
+
+ img.row_offset = row;
+ img.col_offset = col;
+
+ ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
+
+ TIFFRGBAImageEnd(&img);
+
+ /*
+ * If our read was incomplete we will need to fix up the tile by
+ * shifting the data around as if a full tile of data is being returned.
+ *
+ * This is all the more complicated because the image is organized in
+ * bottom to top format.
+ */
+
+ if( read_xsize == tile_xsize && read_ysize == tile_ysize )
+ return( ok );
+
+ for( i_row = 0; i_row < read_ysize; i_row++ ) {
+ memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
+ raster + (read_ysize - i_row - 1) * read_xsize,
+ read_xsize * sizeof(uint32) );
+ _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
+ 0, sizeof(uint32) * (tile_xsize - read_xsize) );
+ }
+
+ for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
+ _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
+ 0, sizeof(uint32) * tile_xsize );
+ }
+
+ return (ok);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_jpeg.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_jpeg.c
new file mode 100644
index 0000000000..84f0f9e66d
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_jpeg.c
@@ -0,0 +1,2311 @@
+/* $Id: tif_jpeg.c,v 1.111 2012-07-06 18:48:04 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1994-1997 Sam Leffler
+ * Copyright (c) 1994-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+
+#include "tiffiop.h"
+#ifdef JPEG_SUPPORT
+
+/*
+ * TIFF Library
+ *
+ * JPEG Compression support per TIFF Technical Note #2
+ * (*not* per the original TIFF 6.0 spec).
+ *
+ * This file is simply an interface to the libjpeg library written by
+ * the Independent JPEG Group. You need release 5 or later of the IJG
+ * code, which you can find on the Internet at ftp.uu.net:/graphics/jpeg/.
+ *
+ * Contributed by Tom Lane <tgl@sss.pgh.pa.us>.
+ */
+#include <setjmp.h>
+
+int TIFFFillStrip(TIFF* tif, uint32 strip);
+int TIFFFillTile(TIFF* tif, uint32 tile);
+int TIFFReInitJPEG_12( TIFF *tif, int scheme, int is_encode );
+
+/* We undefine FAR to avoid conflict with JPEG definition */
+
+#ifdef FAR
+#undef FAR
+#endif
+
+/*
+ Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
+ not defined. Unfortunately, the MinGW and Borland compilers include
+ a typedef for INT32, which causes a conflict. MSVC does not include
+ a conficting typedef given the headers which are included.
+*/
+#if defined(__BORLANDC__) || defined(__MINGW32__)
+# define XMD_H 1
+#endif
+
+/*
+ The windows RPCNDR.H file defines boolean, but defines it with the
+ unsigned char size. You should compile JPEG library using appropriate
+ definitions in jconfig.h header, but many users compile library in wrong
+ way. That causes errors of the following type:
+
+ "JPEGLib: JPEG parameter struct mismatch: library thinks size is 432,
+ caller expects 464"
+
+ For such users we wil fix the problem here. See install.doc file from
+ the JPEG library distribution for details.
+*/
+
+/* Define "boolean" as unsigned char, not int, per Windows custom. */
+#if defined(WIN32) && !defined(__MINGW32__)
+# ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+ typedef unsigned char boolean;
+# endif
+# define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+#endif
+
+#ifndef _FX_JPEG_TURBO_
+ #include "../../libjpeg/jpeglib.h"
+ #include "../../libjpeg/jerror.h"
+#else
+ #include "../../libjpeg-turbo/jpeglib.h"
+ #include "../../libjpeg-turbo/jerror.h"
+#endif//_FX_JPEG_TURBO_
+
+/*
+ * Do we want to do special processing suitable for when JSAMPLE is a
+ * 16bit value?
+ */
+
+#if defined(JPEG_LIB_MK1)
+# define JPEG_LIB_MK1_OR_12BIT 1
+#elif BITS_IN_JSAMPLE == 12
+# define JPEG_LIB_MK1_OR_12BIT 1
+#endif
+
+/*
+ * We are using width_in_blocks which is supposed to be private to
+ * libjpeg. Unfortunately, the libjpeg delivered with Cygwin has
+ * renamed this member to width_in_data_units. Since the header has
+ * also renamed a define, use that unique define name in order to
+ * detect the problem header and adjust to suit.
+ */
+#if defined(D_MAX_DATA_UNITS_IN_MCU)
+#define width_in_blocks width_in_data_units
+#endif
+
+/*
+ * On some machines it may be worthwhile to use _setjmp or sigsetjmp
+ * in place of plain setjmp. These macros will make it easier.
+ */
+#define SETJMP(jbuf) setjmp(jbuf)
+#define LONGJMP(jbuf,code) longjmp(jbuf,code)
+#define JMP_BUF jmp_buf
+
+typedef struct jpeg_destination_mgr jpeg_destination_mgr;
+typedef struct jpeg_source_mgr jpeg_source_mgr;
+typedef struct jpeg_error_mgr jpeg_error_mgr;
+
+/*
+ * State block for each open TIFF file using
+ * libjpeg to do JPEG compression/decompression.
+ *
+ * libjpeg's visible state is either a jpeg_compress_struct
+ * or jpeg_decompress_struct depending on which way we
+ * are going. comm can be used to refer to the fields
+ * which are common to both.
+ *
+ * NB: cinfo is required to be the first member of JPEGState,
+ * so we can safely cast JPEGState* -> jpeg_xxx_struct*
+ * and vice versa!
+ */
+typedef struct {
+ union {
+ struct jpeg_compress_struct c;
+ struct jpeg_decompress_struct d;
+ struct jpeg_common_struct comm;
+ } cinfo; /* NB: must be first */
+ int cinfo_initialized;
+
+ jpeg_error_mgr err; /* libjpeg error manager */
+ JMP_BUF exit_jmpbuf; /* for catching libjpeg failures */
+ /*
+ * The following two members could be a union, but
+ * they're small enough that it's not worth the effort.
+ */
+ jpeg_destination_mgr dest; /* data dest for compression */
+ jpeg_source_mgr src; /* data source for decompression */
+ /* private state */
+ TIFF* tif; /* back link needed by some code */
+ uint16 photometric; /* copy of PhotometricInterpretation */
+ uint16 h_sampling; /* luminance sampling factors */
+ uint16 v_sampling;
+ tmsize_t bytesperline; /* decompressed bytes per scanline */
+ /* pointers to intermediate buffers when processing downsampled data */
+ JSAMPARRAY ds_buffer[MAX_COMPONENTS];
+ int scancount; /* number of "scanlines" accumulated */
+ int samplesperclump;
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+ TIFFPrintMethod printdir; /* super-class method */
+ TIFFStripMethod defsparent; /* super-class method */
+ TIFFTileMethod deftparent; /* super-class method */
+ /* pseudo-tag fields */
+ void* jpegtables; /* JPEGTables tag value, or NULL */
+ uint32 jpegtables_length; /* number of bytes in same */
+ int jpegquality; /* Compression quality level */
+ int jpegcolormode; /* Auto RGB<=>YCbCr convert? */
+ int jpegtablesmode; /* What to put in JPEGTables */
+
+ int ycbcrsampling_fetched;
+} JPEGState;
+
+#define JState(tif) ((JPEGState*)(tif)->tif_data)
+
+static int JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int JPEGInitializeLibJPEG(TIFF * tif, int decode );
+static int DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+
+#define FIELD_JPEGTABLES (FIELD_CODEC+0)
+
+static const TIFFField jpegFields[] = {
+ { TIFFTAG_JPEGTABLES, -3, -3, TIFF_UNDEFINED, 0, TIFF_SETGET_C32_UINT8, TIFF_SETGET_C32_UINT8, FIELD_JPEGTABLES, FALSE, TRUE, "JPEGTables", NULL },
+ { TIFFTAG_JPEGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
+ { TIFFTAG_JPEGCOLORMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL },
+ { TIFFTAG_JPEGTABLESMODE, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL }
+};
+
+/*
+ * libjpeg interface layer.
+ *
+ * We use setjmp/longjmp to return control to libtiff
+ * when a fatal error is encountered within the JPEG
+ * library. We also direct libjpeg error and warning
+ * messages through the appropriate libtiff handlers.
+ */
+
+/*
+ * Error handling routines (these replace corresponding
+ * IJG routines from jerror.c). These are used for both
+ * compression and decompression.
+ */
+static void
+TIFFjpeg_error_exit(j_common_ptr cinfo)
+{
+ JPEGState *sp = (JPEGState *) cinfo; /* NB: cinfo assumed first */
+ char buffer[JMSG_LENGTH_MAX];
+
+ (*cinfo->err->format_message) (cinfo, buffer);
+ TIFFErrorExt(sp->tif->tif_clientdata, "JPEGLib", "%s", buffer); /* display the error message */
+ jpeg_abort(cinfo); /* clean up libjpeg state */
+ LONGJMP(sp->exit_jmpbuf, 1); /* return to libtiff caller */
+}
+
+/*
+ * This routine is invoked only for warning messages,
+ * since error_exit does its own thing and trace_level
+ * is never set > 0.
+ */
+static void
+TIFFjpeg_output_message(j_common_ptr cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+
+ (*cinfo->err->format_message) (cinfo, buffer);
+ TIFFWarningExt(((JPEGState *) cinfo)->tif->tif_clientdata, "JPEGLib", "%s", buffer);
+}
+
+/*
+ * Interface routines. This layer of routines exists
+ * primarily to limit side-effects from using setjmp.
+ * Also, normal/error returns are converted into return
+ * values per libtiff practice.
+ */
+#define CALLJPEG(sp, fail, op) (SETJMP((sp)->exit_jmpbuf) ? (fail) : (op))
+#define CALLVJPEG(sp, op) CALLJPEG(sp, 0, ((op),1))
+
+static int
+TIFFjpeg_create_compress(JPEGState* sp)
+{
+ /* initialize JPEG error handling */
+ sp->cinfo.c.err = jpeg_std_error(&sp->err);
+ sp->err.error_exit = TIFFjpeg_error_exit;
+ sp->err.output_message = TIFFjpeg_output_message;
+
+ return CALLVJPEG(sp, jpeg_create_compress(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_create_decompress(JPEGState* sp)
+{
+ /* initialize JPEG error handling */
+ sp->cinfo.d.err = jpeg_std_error(&sp->err);
+ sp->err.error_exit = TIFFjpeg_error_exit;
+ sp->err.output_message = TIFFjpeg_output_message;
+
+ return CALLVJPEG(sp, jpeg_create_decompress(&sp->cinfo.d));
+}
+
+static int
+TIFFjpeg_set_defaults(JPEGState* sp)
+{
+ return CALLVJPEG(sp, jpeg_set_defaults(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_set_colorspace(JPEGState* sp, J_COLOR_SPACE colorspace)
+{
+ return CALLVJPEG(sp, jpeg_set_colorspace(&sp->cinfo.c, colorspace));
+}
+
+static int
+TIFFjpeg_set_quality(JPEGState* sp, int quality, boolean force_baseline)
+{
+ return CALLVJPEG(sp,
+ jpeg_set_quality(&sp->cinfo.c, quality, force_baseline));
+}
+
+static int
+TIFFjpeg_suppress_tables(JPEGState* sp, boolean suppress)
+{
+ return CALLVJPEG(sp, jpeg_suppress_tables(&sp->cinfo.c, suppress));
+}
+
+static int
+TIFFjpeg_start_compress(JPEGState* sp, boolean write_all_tables)
+{
+ return CALLVJPEG(sp,
+ jpeg_start_compress(&sp->cinfo.c, write_all_tables));
+}
+
+static int
+TIFFjpeg_write_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int num_lines)
+{
+ return CALLJPEG(sp, -1, (int) jpeg_write_scanlines(&sp->cinfo.c,
+ scanlines, (JDIMENSION) num_lines));
+}
+
+static int
+TIFFjpeg_write_raw_data(JPEGState* sp, JSAMPIMAGE data, int num_lines)
+{
+ return CALLJPEG(sp, -1, (int) jpeg_write_raw_data(&sp->cinfo.c,
+ data, (JDIMENSION) num_lines));
+}
+
+static int
+TIFFjpeg_finish_compress(JPEGState* sp)
+{
+ return CALLVJPEG(sp, jpeg_finish_compress(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_write_tables(JPEGState* sp)
+{
+ return CALLVJPEG(sp, jpeg_write_tables(&sp->cinfo.c));
+}
+
+static int
+TIFFjpeg_read_header(JPEGState* sp, boolean require_image)
+{
+ return CALLJPEG(sp, -1, jpeg_read_header(&sp->cinfo.d, require_image));
+}
+
+static int
+TIFFjpeg_start_decompress(JPEGState* sp)
+{
+ return CALLVJPEG(sp, jpeg_start_decompress(&sp->cinfo.d));
+}
+
+static int
+TIFFjpeg_read_scanlines(JPEGState* sp, JSAMPARRAY scanlines, int max_lines)
+{
+ return CALLJPEG(sp, -1, (int) jpeg_read_scanlines(&sp->cinfo.d,
+ scanlines, (JDIMENSION) max_lines));
+}
+
+static int
+TIFFjpeg_read_raw_data(JPEGState* sp, JSAMPIMAGE data, int max_lines)
+{
+ return CALLJPEG(sp, -1, (int) jpeg_read_raw_data(&sp->cinfo.d,
+ data, (JDIMENSION) max_lines));
+}
+
+static int
+TIFFjpeg_finish_decompress(JPEGState* sp)
+{
+ return CALLJPEG(sp, -1, (int) jpeg_finish_decompress(&sp->cinfo.d));
+}
+
+static int
+TIFFjpeg_abort(JPEGState* sp)
+{
+ return CALLVJPEG(sp, jpeg_abort(&sp->cinfo.comm));
+}
+
+static int
+TIFFjpeg_destroy(JPEGState* sp)
+{
+ return CALLVJPEG(sp, jpeg_destroy(&sp->cinfo.comm));
+}
+
+static JSAMPARRAY
+TIFFjpeg_alloc_sarray(JPEGState* sp, int pool_id,
+ JDIMENSION samplesperrow, JDIMENSION numrows)
+{
+ return CALLJPEG(sp, (JSAMPARRAY) NULL,
+ (*sp->cinfo.comm.mem->alloc_sarray)
+ (&sp->cinfo.comm, pool_id, samplesperrow, numrows));
+}
+
+/*
+ * JPEG library destination data manager.
+ * These routines direct compressed data from libjpeg into the
+ * libtiff output buffer.
+ */
+
+static void
+std_init_destination(j_compress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+ TIFF* tif = sp->tif;
+
+ sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
+ sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
+}
+
+static boolean
+std_empty_output_buffer(j_compress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+ TIFF* tif = sp->tif;
+
+ /* the entire buffer has been filled */
+ tif->tif_rawcc = tif->tif_rawdatasize;
+
+#ifdef IPPJ_HUFF
+ /*
+ * The Intel IPP performance library does not necessarily fill up
+ * the whole output buffer on each pass, so only dump out the parts
+ * that have been filled.
+ * http://trac.osgeo.org/gdal/wiki/JpegIPP
+ */
+ if ( sp->dest.free_in_buffer >= 0 ) {
+ tif->tif_rawcc = tif->tif_rawdatasize - sp->dest.free_in_buffer;
+ }
+#endif
+
+ TIFFFlushData1(tif);
+ sp->dest.next_output_byte = (JOCTET*) tif->tif_rawdata;
+ sp->dest.free_in_buffer = (size_t) tif->tif_rawdatasize;
+
+ return (TRUE);
+}
+
+static void
+std_term_destination(j_compress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+ TIFF* tif = sp->tif;
+
+ tif->tif_rawcp = (uint8*) sp->dest.next_output_byte;
+ tif->tif_rawcc =
+ tif->tif_rawdatasize - (tmsize_t) sp->dest.free_in_buffer;
+ /* NB: libtiff does the final buffer flush */
+}
+
+static void
+TIFFjpeg_data_dest(JPEGState* sp, TIFF* tif)
+{
+ (void) tif;
+ sp->cinfo.c.dest = &sp->dest;
+ sp->dest.init_destination = std_init_destination;
+ sp->dest.empty_output_buffer = std_empty_output_buffer;
+ sp->dest.term_destination = std_term_destination;
+}
+
+/*
+ * Alternate destination manager for outputting to JPEGTables field.
+ */
+
+static void
+tables_init_destination(j_compress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+
+ /* while building, jpegtables_length is allocated buffer size */
+ sp->dest.next_output_byte = (JOCTET*) sp->jpegtables;
+ sp->dest.free_in_buffer = (size_t) sp->jpegtables_length;
+}
+
+static boolean
+tables_empty_output_buffer(j_compress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+ void* newbuf;
+
+ /* the entire buffer has been filled; enlarge it by 1000 bytes */
+ newbuf = _TIFFrealloc((void*) sp->jpegtables,
+ (tmsize_t) (sp->jpegtables_length + 1000));
+ if (newbuf == NULL)
+ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 100);
+ sp->dest.next_output_byte = (JOCTET*) newbuf + sp->jpegtables_length;
+ sp->dest.free_in_buffer = (size_t) 1000;
+ sp->jpegtables = newbuf;
+ sp->jpegtables_length += 1000;
+ return (TRUE);
+}
+
+static void
+tables_term_destination(j_compress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+
+ /* set tables length to number of bytes actually emitted */
+ sp->jpegtables_length -= (uint32) sp->dest.free_in_buffer;
+}
+
+static int
+TIFFjpeg_tables_dest(JPEGState* sp, TIFF* tif)
+{
+ (void) tif;
+ /*
+ * Allocate a working buffer for building tables.
+ * Initial size is 1000 bytes, which is usually adequate.
+ */
+ if (sp->jpegtables)
+ _TIFFfree(sp->jpegtables);
+ sp->jpegtables_length = 1000;
+ sp->jpegtables = (void*) _TIFFmalloc((tmsize_t) sp->jpegtables_length);
+ if (sp->jpegtables == NULL) {
+ sp->jpegtables_length = 0;
+ TIFFErrorExt(sp->tif->tif_clientdata, "TIFFjpeg_tables_dest", "No space for JPEGTables");
+ return (0);
+ }
+ sp->cinfo.c.dest = &sp->dest;
+ sp->dest.init_destination = tables_init_destination;
+ sp->dest.empty_output_buffer = tables_empty_output_buffer;
+ sp->dest.term_destination = tables_term_destination;
+ return (1);
+}
+
+/*
+ * JPEG library source data manager.
+ * These routines supply compressed data to libjpeg.
+ */
+
+static void
+std_init_source(j_decompress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+ TIFF* tif = sp->tif;
+
+ sp->src.next_input_byte = (const JOCTET*) tif->tif_rawdata;
+ sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
+}
+
+static boolean
+std_fill_input_buffer(j_decompress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState* ) cinfo;
+ static const JOCTET dummy_EOI[2] = { 0xFF, JPEG_EOI };
+
+#ifdef IPPJ_HUFF
+ /*
+ * The Intel IPP performance library does not necessarily read the whole
+ * input buffer in one pass, so it is possible to get here with data
+ * yet to read.
+ *
+ * We just return without doing anything, until the entire buffer has
+ * been read.
+ * http://trac.osgeo.org/gdal/wiki/JpegIPP
+ */
+ if( sp->src.bytes_in_buffer > 0 ) {
+ return (TRUE);
+ }
+#endif
+
+ /*
+ * Normally the whole strip/tile is read and so we don't need to do
+ * a fill. In the case of CHUNKY_STRIP_READ_SUPPORT we might not have
+ * all the data, but the rawdata is refreshed between scanlines and
+ * we push this into the io machinery in JPEGDecode().
+ * http://trac.osgeo.org/gdal/ticket/3894
+ */
+
+ WARNMS(cinfo, JWRN_JPEG_EOF);
+ /* insert a fake EOI marker */
+ sp->src.next_input_byte = dummy_EOI;
+ sp->src.bytes_in_buffer = 2;
+ return (TRUE);
+}
+
+static void
+std_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+
+ if (num_bytes > 0) {
+ if ((size_t)num_bytes > sp->src.bytes_in_buffer) {
+ /* oops, buffer overrun */
+ (void) std_fill_input_buffer(cinfo);
+ } else {
+ sp->src.next_input_byte += (size_t) num_bytes;
+ sp->src.bytes_in_buffer -= (size_t) num_bytes;
+ }
+ }
+}
+
+static void
+std_term_source(j_decompress_ptr cinfo)
+{
+ /* No work necessary here */
+ (void) cinfo;
+}
+
+static void
+TIFFjpeg_data_src(JPEGState* sp, TIFF* tif)
+{
+ (void) tif;
+ sp->cinfo.d.src = &sp->src;
+ sp->src.init_source = std_init_source;
+ sp->src.fill_input_buffer = std_fill_input_buffer;
+ sp->src.skip_input_data = std_skip_input_data;
+ sp->src.resync_to_restart = jpeg_resync_to_restart;
+ sp->src.term_source = std_term_source;
+ sp->src.bytes_in_buffer = 0; /* for safety */
+ sp->src.next_input_byte = NULL;
+}
+
+/*
+ * Alternate source manager for reading from JPEGTables.
+ * We can share all the code except for the init routine.
+ */
+
+static void
+tables_init_source(j_decompress_ptr cinfo)
+{
+ JPEGState* sp = (JPEGState*) cinfo;
+
+ sp->src.next_input_byte = (const JOCTET*) sp->jpegtables;
+ sp->src.bytes_in_buffer = (size_t) sp->jpegtables_length;
+}
+
+static void
+TIFFjpeg_tables_src(JPEGState* sp, TIFF* tif)
+{
+ TIFFjpeg_data_src(sp, tif);
+ sp->src.init_source = tables_init_source;
+}
+
+/*
+ * Allocate downsampled-data buffers needed for downsampled I/O.
+ * We use values computed in jpeg_start_compress or jpeg_start_decompress.
+ * We use libjpeg's allocator so that buffers will be released automatically
+ * when done with strip/tile.
+ * This is also a handy place to compute samplesperclump, bytesperline.
+ */
+static int
+alloc_downsampled_buffers(TIFF* tif, jpeg_component_info* comp_info,
+ int num_components)
+{
+ JPEGState* sp = JState(tif);
+ int ci;
+ jpeg_component_info* compptr;
+ JSAMPARRAY buf;
+ int samples_per_clump = 0;
+
+ for (ci = 0, compptr = comp_info; ci < num_components;
+ ci++, compptr++) {
+ samples_per_clump += compptr->h_samp_factor *
+ compptr->v_samp_factor;
+ buf = TIFFjpeg_alloc_sarray(sp, JPOOL_IMAGE,
+ compptr->width_in_blocks * DCTSIZE,
+ (JDIMENSION) (compptr->v_samp_factor*DCTSIZE));
+ if (buf == NULL)
+ return (0);
+ sp->ds_buffer[ci] = buf;
+ }
+ sp->samplesperclump = samples_per_clump;
+ return (1);
+}
+
+
+/*
+ * JPEG Decoding.
+ */
+
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+
+#define JPEG_MARKER_SOF0 0xC0
+#define JPEG_MARKER_SOF1 0xC1
+#define JPEG_MARKER_SOF3 0xC3
+#define JPEG_MARKER_DHT 0xC4
+#define JPEG_MARKER_SOI 0xD8
+#define JPEG_MARKER_SOS 0xDA
+#define JPEG_MARKER_DQT 0xDB
+#define JPEG_MARKER_DRI 0xDD
+#define JPEG_MARKER_APP0 0xE0
+#define JPEG_MARKER_COM 0xFE
+struct JPEGFixupTagsSubsamplingData
+{
+ TIFF* tif;
+ void* buffer;
+ uint32 buffersize;
+ uint8* buffercurrentbyte;
+ uint32 bufferbytesleft;
+ uint64 fileoffset;
+ uint64 filebytesleft;
+ uint8 filepositioned;
+};
+static void JPEGFixupTagsSubsampling(TIFF* tif);
+static int JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data);
+static int JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result);
+static int JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result);
+static void JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength);
+
+#endif
+
+static int
+JPEGFixupTags(TIFF* tif)
+{
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+ if ((tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)&&
+ (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
+ (tif->tif_dir.td_samplesperpixel==3))
+ JPEGFixupTagsSubsampling(tif);
+#endif
+
+ return(1);
+}
+
+#ifdef CHECK_JPEG_YCBCR_SUBSAMPLING
+
+static void
+JPEGFixupTagsSubsampling(TIFF* tif)
+{
+ /*
+ * Some JPEG-in-TIFF produces do not emit the YCBCRSUBSAMPLING values in
+ * the TIFF tags, but still use non-default (2,2) values within the jpeg
+ * data stream itself. In order for TIFF applications to work properly
+ * - for instance to get the strip buffer size right - it is imperative
+ * that the subsampling be available before we start reading the image
+ * data normally. This function will attempt to analyze the first strip in
+ * order to get the sampling values from the jpeg data stream.
+ *
+ * Note that JPEGPreDeocode() will produce a fairly loud warning when the
+ * discovered sampling does not match the default sampling (2,2) or whatever
+ * was actually in the tiff tags.
+ *
+ * See the bug in bugzilla for details:
+ *
+ * http://bugzilla.remotesensing.org/show_bug.cgi?id=168
+ *
+ * Frank Warmerdam, July 2002
+ * Joris Van Damme, May 2007
+ */
+ static const char module[] = "JPEGFixupTagsSubsampling";
+ struct JPEGFixupTagsSubsamplingData m;
+
+ _TIFFFillStriles( tif );
+
+ if( tif->tif_dir.td_stripbytecount == NULL
+ || tif->tif_dir.td_stripbytecount[0] == 0 )
+ {
+ /* Do not even try to check if the first strip/tile does not
+ yet exist, as occurs when GDAL has created a new NULL file
+ for instance. */
+ return;
+ }
+
+ m.tif=tif;
+ m.buffersize=2048;
+ m.buffer=_TIFFmalloc(m.buffersize);
+ if (m.buffer==NULL)
+ {
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Unable to allocate memory for auto-correcting of subsampling values; auto-correcting skipped");
+ return;
+ }
+ m.buffercurrentbyte=NULL;
+ m.bufferbytesleft=0;
+ m.fileoffset=tif->tif_dir.td_stripoffset[0];
+ m.filepositioned=0;
+ m.filebytesleft=tif->tif_dir.td_stripbytecount[0];
+ if (!JPEGFixupTagsSubsamplingSec(&m))
+ TIFFWarningExt(tif->tif_clientdata,module,
+ "Unable to auto-correct subsampling values, likely corrupt JPEG compressed data in first strip/tile; auto-correcting skipped");
+ _TIFFfree(m.buffer);
+}
+
+static int
+JPEGFixupTagsSubsamplingSec(struct JPEGFixupTagsSubsamplingData* data)
+{
+ static const char module[] = "JPEGFixupTagsSubsamplingSec";
+ uint8 m;
+ while (1)
+ {
+ while (1)
+ {
+ if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
+ return(0);
+ if (m==255)
+ break;
+ }
+ while (1)
+ {
+ if (!JPEGFixupTagsSubsamplingReadByte(data,&m))
+ return(0);
+ if (m!=255)
+ break;
+ }
+ switch (m)
+ {
+ case JPEG_MARKER_SOI:
+ /* this type of marker has no data and should be skipped */
+ break;
+ case JPEG_MARKER_COM:
+ case JPEG_MARKER_APP0:
+ case JPEG_MARKER_APP0+1:
+ case JPEG_MARKER_APP0+2:
+ case JPEG_MARKER_APP0+3:
+ case JPEG_MARKER_APP0+4:
+ case JPEG_MARKER_APP0+5:
+ case JPEG_MARKER_APP0+6:
+ case JPEG_MARKER_APP0+7:
+ case JPEG_MARKER_APP0+8:
+ case JPEG_MARKER_APP0+9:
+ case JPEG_MARKER_APP0+10:
+ case JPEG_MARKER_APP0+11:
+ case JPEG_MARKER_APP0+12:
+ case JPEG_MARKER_APP0+13:
+ case JPEG_MARKER_APP0+14:
+ case JPEG_MARKER_APP0+15:
+ case JPEG_MARKER_DQT:
+ case JPEG_MARKER_SOS:
+ case JPEG_MARKER_DHT:
+ case JPEG_MARKER_DRI:
+ /* this type of marker has data, but it has no use to us and should be skipped */
+ {
+ uint16 n;
+ if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
+ return(0);
+ if (n<2)
+ return(0);
+ n-=2;
+ if (n>0)
+ JPEGFixupTagsSubsamplingSkip(data,n);
+ }
+ break;
+ case JPEG_MARKER_SOF0:
+ case JPEG_MARKER_SOF1:
+ /* this marker contains the subsampling factors we're scanning for */
+ {
+ uint16 n;
+ uint16 o;
+ uint8 p;
+ uint8 ph,pv;
+ if (!JPEGFixupTagsSubsamplingReadWord(data,&n))
+ return(0);
+ if (n!=8+data->tif->tif_dir.td_samplesperpixel*3)
+ return(0);
+ JPEGFixupTagsSubsamplingSkip(data,7);
+ if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
+ return(0);
+ ph=(p>>4);
+ pv=(p&15);
+ JPEGFixupTagsSubsamplingSkip(data,1);
+ for (o=1; o<data->tif->tif_dir.td_samplesperpixel; o++)
+ {
+ JPEGFixupTagsSubsamplingSkip(data,1);
+ if (!JPEGFixupTagsSubsamplingReadByte(data,&p))
+ return(0);
+ if (p!=0x11)
+ {
+ TIFFWarningExt(data->tif->tif_clientdata,module,
+ "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
+ return(1);
+ }
+ JPEGFixupTagsSubsamplingSkip(data,1);
+ }
+ if (((ph!=1)&&(ph!=2)&&(ph!=4))||((pv!=1)&&(pv!=2)&&(pv!=4)))
+ {
+ TIFFWarningExt(data->tif->tif_clientdata,module,
+ "Subsampling values inside JPEG compressed data have no TIFF equivalent, auto-correction of TIFF subsampling values failed");
+ return(1);
+ }
+ if ((ph!=data->tif->tif_dir.td_ycbcrsubsampling[0])||(pv!=data->tif->tif_dir.td_ycbcrsubsampling[1]))
+ {
+ TIFFWarningExt(data->tif->tif_clientdata,module,
+ "Auto-corrected former TIFF subsampling values [%d,%d] to match subsampling values inside JPEG compressed data [%d,%d]",
+ (int)data->tif->tif_dir.td_ycbcrsubsampling[0],
+ (int)data->tif->tif_dir.td_ycbcrsubsampling[1],
+ (int)ph,(int)pv);
+ data->tif->tif_dir.td_ycbcrsubsampling[0]=ph;
+ data->tif->tif_dir.td_ycbcrsubsampling[1]=pv;
+ }
+ }
+ return(1);
+ default:
+ return(0);
+ }
+ }
+}
+
+static int
+JPEGFixupTagsSubsamplingReadByte(struct JPEGFixupTagsSubsamplingData* data, uint8* result)
+{
+ if (data->bufferbytesleft==0)
+ {
+ uint32 m;
+ if (data->filebytesleft==0)
+ return(0);
+ if (!data->filepositioned)
+ {
+ TIFFSeekFile(data->tif,data->fileoffset,SEEK_SET);
+ data->filepositioned=1;
+ }
+ m=data->buffersize;
+ if ((uint64)m>data->filebytesleft)
+ m=(uint32)data->filebytesleft;
+ assert(m<0x80000000UL);
+ if (TIFFReadFile(data->tif,data->buffer,(tmsize_t)m)!=(tmsize_t)m)
+ return(0);
+ data->buffercurrentbyte=data->buffer;
+ data->bufferbytesleft=m;
+ data->fileoffset+=m;
+ data->filebytesleft-=m;
+ }
+ *result=*data->buffercurrentbyte;
+ data->buffercurrentbyte++;
+ data->bufferbytesleft--;
+ return(1);
+}
+
+static int
+JPEGFixupTagsSubsamplingReadWord(struct JPEGFixupTagsSubsamplingData* data, uint16* result)
+{
+ uint8 ma;
+ uint8 mb;
+ if (!JPEGFixupTagsSubsamplingReadByte(data,&ma))
+ return(0);
+ if (!JPEGFixupTagsSubsamplingReadByte(data,&mb))
+ return(0);
+ *result=(ma<<8)|mb;
+ return(1);
+}
+
+static void
+JPEGFixupTagsSubsamplingSkip(struct JPEGFixupTagsSubsamplingData* data, uint16 skiplength)
+{
+ if ((uint32)skiplength<=data->bufferbytesleft)
+ {
+ data->buffercurrentbyte+=skiplength;
+ data->bufferbytesleft-=skiplength;
+ }
+ else
+ {
+ uint16 m;
+ m=skiplength-data->bufferbytesleft;
+ if (m<=data->filebytesleft)
+ {
+ data->bufferbytesleft=0;
+ data->fileoffset+=m;
+ data->filebytesleft-=m;
+ data->filepositioned=0;
+ }
+ else
+ {
+ data->bufferbytesleft=0;
+ data->filebytesleft=0;
+ }
+ }
+}
+
+#endif
+
+
+static int
+JPEGSetupDecode(TIFF* tif)
+{
+ JPEGState* sp = JState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
+ if( tif->tif_dir.td_bitspersample == 12 )
+ return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 0 );
+#endif
+
+ JPEGInitializeLibJPEG( tif, TRUE );
+
+ assert(sp != NULL);
+ assert(sp->cinfo.comm.is_decompressor);
+
+ /* Read JPEGTables if it is present */
+ if (TIFFFieldSet(tif,FIELD_JPEGTABLES)) {
+ TIFFjpeg_tables_src(sp, tif);
+ if(TIFFjpeg_read_header(sp,FALSE) != JPEG_HEADER_TABLES_ONLY) {
+ TIFFErrorExt(tif->tif_clientdata, "JPEGSetupDecode", "Bogus JPEGTables field");
+ return (0);
+ }
+ }
+
+ /* Grab parameters that are same for all strips/tiles */
+ sp->photometric = td->td_photometric;
+ switch (sp->photometric) {
+ case PHOTOMETRIC_YCBCR:
+ sp->h_sampling = td->td_ycbcrsubsampling[0];
+ sp->v_sampling = td->td_ycbcrsubsampling[1];
+ break;
+ default:
+ /* TIFF 6.0 forbids subsampling of all other color spaces */
+ sp->h_sampling = 1;
+ sp->v_sampling = 1;
+ break;
+ }
+
+ /* Set up for reading normal data */
+ TIFFjpeg_data_src(sp, tif);
+ tif->tif_postdecode = _TIFFNoPostDecode; /* override byte swapping */
+ return (1);
+}
+
+/*
+ * Set up for decoding a strip or tile.
+ */
+static int
+JPEGPreDecode(TIFF* tif, uint16 s)
+{
+ JPEGState *sp = JState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+ static const char module[] = "JPEGPreDecode";
+ uint32 segment_width, segment_height;
+ int downsampled_output;
+ int ci;
+
+ assert(sp != NULL);
+
+ if (sp->cinfo.comm.is_decompressor == 0)
+ {
+ tif->tif_setupdecode( tif );
+ }
+
+ assert(sp->cinfo.comm.is_decompressor);
+ /*
+ * Reset decoder state from any previous strip/tile,
+ * in case application didn't read the whole strip.
+ */
+ if (!TIFFjpeg_abort(sp))
+ return (0);
+ /*
+ * Read the header for this strip/tile.
+ */
+
+ if (TIFFjpeg_read_header(sp, TRUE) != JPEG_HEADER_OK)
+ return (0);
+
+ tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
+ tif->tif_rawcc = sp->src.bytes_in_buffer;
+
+ /*
+ * Check image parameters and set decompression parameters.
+ */
+ segment_width = td->td_imagewidth;
+ segment_height = td->td_imagelength - tif->tif_row;
+ if (isTiled(tif)) {
+ segment_width = td->td_tilewidth;
+ segment_height = td->td_tilelength;
+ sp->bytesperline = TIFFTileRowSize(tif);
+ } else {
+ if (segment_height > td->td_rowsperstrip)
+ segment_height = td->td_rowsperstrip;
+ sp->bytesperline = TIFFScanlineSize(tif);
+ }
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
+ /*
+ * For PC 2, scale down the expected strip/tile size
+ * to match a downsampled component
+ */
+ segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
+ segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
+ }
+ if (sp->cinfo.d.image_width < segment_width ||
+ sp->cinfo.d.image_height < segment_height) {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Improper JPEG strip/tile size, "
+ "expected %dx%d, got %dx%d",
+ segment_width, segment_height,
+ sp->cinfo.d.image_width,
+ sp->cinfo.d.image_height);
+ }
+ if (sp->cinfo.d.image_width > segment_width ||
+ sp->cinfo.d.image_height > segment_height) {
+ /*
+ * This case could be dangerous, if the strip or tile size has
+ * been reported as less than the amount of data jpeg will
+ * return, some potential security issues arise. Catch this
+ * case and error out.
+ */
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "JPEG strip/tile size exceeds expected dimensions,"
+ " expected %dx%d, got %dx%d",
+ segment_width, segment_height,
+ sp->cinfo.d.image_width, sp->cinfo.d.image_height);
+ return (0);
+ }
+ if (sp->cinfo.d.num_components !=
+ (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+ td->td_samplesperpixel : 1)) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG component count");
+ return (0);
+ }
+#ifdef JPEG_LIB_MK1
+ if (12 != td->td_bitspersample && 8 != td->td_bitspersample) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
+ return (0);
+ }
+ sp->cinfo.d.data_precision = td->td_bitspersample;
+ sp->cinfo.d.bits_in_jsample = td->td_bitspersample;
+#else
+ if (sp->cinfo.d.data_precision != td->td_bitspersample) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG data precision");
+ return (0);
+ }
+#endif
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+ /* Component 0 should have expected sampling factors */
+ if (sp->cinfo.d.comp_info[0].h_samp_factor != sp->h_sampling ||
+ sp->cinfo.d.comp_info[0].v_samp_factor != sp->v_sampling) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Improper JPEG sampling factors %d,%d\n"
+ "Apparently should be %d,%d.",
+ sp->cinfo.d.comp_info[0].h_samp_factor,
+ sp->cinfo.d.comp_info[0].v_samp_factor,
+ sp->h_sampling, sp->v_sampling);
+ return (0);
+ }
+ /* Rest should have sampling factors 1,1 */
+ for (ci = 1; ci < sp->cinfo.d.num_components; ci++) {
+ if (sp->cinfo.d.comp_info[ci].h_samp_factor != 1 ||
+ sp->cinfo.d.comp_info[ci].v_samp_factor != 1) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
+ return (0);
+ }
+ }
+ } else {
+ /* PC 2's single component should have sampling factors 1,1 */
+ if (sp->cinfo.d.comp_info[0].h_samp_factor != 1 ||
+ sp->cinfo.d.comp_info[0].v_samp_factor != 1) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Improper JPEG sampling factors");
+ return (0);
+ }
+ }
+ downsampled_output = FALSE;
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
+ sp->photometric == PHOTOMETRIC_YCBCR &&
+ sp->jpegcolormode == JPEGCOLORMODE_RGB) {
+ /* Convert YCbCr to RGB */
+ sp->cinfo.d.jpeg_color_space = JCS_YCbCr;
+ sp->cinfo.d.out_color_space = JCS_RGB;
+ } else {
+ /* Suppress colorspace handling */
+ sp->cinfo.d.jpeg_color_space = JCS_UNKNOWN;
+ sp->cinfo.d.out_color_space = JCS_UNKNOWN;
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
+ (sp->h_sampling != 1 || sp->v_sampling != 1))
+ downsampled_output = TRUE;
+ /* XXX what about up-sampling? */
+ }
+ if (downsampled_output) {
+ /* Need to use raw-data interface to libjpeg */
+ sp->cinfo.d.raw_data_out = TRUE;
+#if JPEG_LIB_VERSION >= 70
+ sp->cinfo.d.do_fancy_upsampling = FALSE;
+#endif /* JPEG_LIB_VERSION >= 70 */
+ tif->tif_decoderow = DecodeRowError;
+ tif->tif_decodestrip = JPEGDecodeRaw;
+ tif->tif_decodetile = JPEGDecodeRaw;
+ } else {
+ /* Use normal interface to libjpeg */
+ sp->cinfo.d.raw_data_out = FALSE;
+ tif->tif_decoderow = JPEGDecode;
+ tif->tif_decodestrip = JPEGDecode;
+ tif->tif_decodetile = JPEGDecode;
+ }
+ /* Start JPEG decompressor */
+ if (!TIFFjpeg_start_decompress(sp))
+ return (0);
+ /* Allocate downsampled-data buffers if needed */
+ if (downsampled_output) {
+ if (!alloc_downsampled_buffers(tif, sp->cinfo.d.comp_info,
+ sp->cinfo.d.num_components))
+ return (0);
+ sp->scancount = DCTSIZE; /* mark buffer empty */
+ }
+ return (1);
+}
+
+/*
+ * Decode a chunk of pixels.
+ * "Standard" case: returned data is not downsampled.
+ */
+/*ARGSUSED*/ static int
+JPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ JPEGState *sp = JState(tif);
+ tmsize_t nrows;
+ (void) s;
+
+ /*
+ ** Update available information, buffer may have been refilled
+ ** between decode requests
+ */
+ sp->src.next_input_byte = (const JOCTET*) tif->tif_rawcp;
+ sp->src.bytes_in_buffer = (size_t) tif->tif_rawcc;
+
+ if( sp->bytesperline == 0 )
+ return 0;
+
+ nrows = cc / sp->bytesperline;
+ if (cc % sp->bytesperline)
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline not read");
+
+ if( nrows > (tmsize_t) sp->cinfo.d.image_height )
+ nrows = sp->cinfo.d.image_height;
+
+ /* data is expected to be read in multiples of a scanline */
+ if (nrows)
+ {
+ JSAMPROW line_work_buf = NULL;
+
+ /*
+ * For 6B, only use temporary buffer for 12 bit imagery.
+ * For Mk1 always use it.
+ */
+#if !defined(JPEG_LIB_MK1)
+ if( sp->cinfo.d.data_precision == 12 )
+#endif
+ {
+ line_work_buf = (JSAMPROW)
+ _TIFFmalloc(sizeof(short) * sp->cinfo.d.output_width
+ * sp->cinfo.d.num_components );
+ }
+
+ do {
+ if( line_work_buf != NULL )
+ {
+ /*
+ * In the MK1 case, we aways read into a 16bit buffer, and then
+ * pack down to 12bit or 8bit. In 6B case we only read into 16
+ * bit buffer for 12bit data, which we need to repack.
+ */
+ if (TIFFjpeg_read_scanlines(sp, &line_work_buf, 1) != 1)
+ return (0);
+
+ if( sp->cinfo.d.data_precision == 12 )
+ {
+ int value_pairs = (sp->cinfo.d.output_width
+ * sp->cinfo.d.num_components) / 2;
+ int iPair;
+
+ for( iPair = 0; iPair < value_pairs; iPair++ )
+ {
+ unsigned char *out_ptr =
+ ((unsigned char *) buf) + iPair * 3;
+ JSAMPLE *in_ptr = line_work_buf + iPair * 2;
+
+ out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
+ out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
+ | ((in_ptr[1] & 0xf00) >> 8);
+ out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
+ }
+ }
+ else if( sp->cinfo.d.data_precision == 8 )
+ {
+ int value_count = (sp->cinfo.d.output_width
+ * sp->cinfo.d.num_components);
+ int iValue;
+
+ for( iValue = 0; iValue < value_count; iValue++ )
+ {
+ ((unsigned char *) buf)[iValue] =
+ line_work_buf[iValue] & 0xff;
+ }
+ }
+ }
+ else
+ {
+ /*
+ * In the libjpeg6b 8bit case. We read directly into the
+ * TIFF buffer.
+ */
+ JSAMPROW bufptr = (JSAMPROW)buf;
+
+ if (TIFFjpeg_read_scanlines(sp, &bufptr, 1) != 1)
+ return (0);
+ }
+
+ ++tif->tif_row;
+ buf += sp->bytesperline;
+ cc -= sp->bytesperline;
+ } while (--nrows > 0);
+
+ if( line_work_buf != NULL )
+ _TIFFfree( line_work_buf );
+ }
+
+ /* Update information on consumed data */
+ tif->tif_rawcp = (uint8*) sp->src.next_input_byte;
+ tif->tif_rawcc = sp->src.bytes_in_buffer;
+
+ /* Close down the decompressor if we've finished the strip or tile. */
+ return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
+ || TIFFjpeg_finish_decompress(sp);
+}
+
+/*ARGSUSED*/ static int
+DecodeRowError(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+
+{
+ (void) buf;
+ (void) cc;
+ (void) s;
+
+ TIFFErrorExt(tif->tif_clientdata, "TIFFReadScanline",
+ "scanline oriented access is not supported for downsampled JPEG compressed images, consider enabling TIFF_JPEGCOLORMODE as JPEGCOLORMODE_RGB." );
+ return 0;
+}
+
+/*
+ * Decode a chunk of pixels.
+ * Returned data is downsampled per sampling factors.
+ */
+/*ARGSUSED*/ static int
+JPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ JPEGState *sp = JState(tif);
+ tmsize_t nrows;
+ (void) s;
+
+ /* data is expected to be read in multiples of a scanline */
+ if ( (nrows = sp->cinfo.d.image_height) ) {
+
+ /* Cb,Cr both have sampling factors 1, so this is correct */
+ JDIMENSION clumps_per_line = sp->cinfo.d.comp_info[1].downsampled_width;
+ int samples_per_clump = sp->samplesperclump;
+
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+ unsigned short* tmpbuf = _TIFFmalloc(sizeof(unsigned short) *
+ sp->cinfo.d.output_width *
+ sp->cinfo.d.num_components);
+ if(tmpbuf==NULL) {
+ TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
+ "Out of memory");
+ return 0;
+ }
+#endif
+
+ do {
+ jpeg_component_info *compptr;
+ int ci, clumpoffset;
+
+ if( cc < sp->bytesperline ) {
+ TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
+ "application buffer not large enough for all data.");
+ return 0;
+ }
+
+ /* Reload downsampled-data buffer if needed */
+ if (sp->scancount >= DCTSIZE) {
+ int n = sp->cinfo.d.max_v_samp_factor * DCTSIZE;
+ if (TIFFjpeg_read_raw_data(sp, sp->ds_buffer, n) != n)
+ return (0);
+ sp->scancount = 0;
+ }
+ /*
+ * Fastest way to unseparate data is to make one pass
+ * over the scanline for each row of each component.
+ */
+ clumpoffset = 0; /* first sample in clump */
+ for (ci = 0, compptr = sp->cinfo.d.comp_info;
+ ci < sp->cinfo.d.num_components;
+ ci++, compptr++) {
+ int hsamp = compptr->h_samp_factor;
+ int vsamp = compptr->v_samp_factor;
+ int ypos;
+
+ for (ypos = 0; ypos < vsamp; ypos++) {
+ JSAMPLE *inptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
+ JDIMENSION nclump;
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+ JSAMPLE *outptr = (JSAMPLE*)tmpbuf + clumpoffset;
+#else
+ JSAMPLE *outptr = (JSAMPLE*)buf + clumpoffset;
+ if (cc < (tmsize_t) (clumpoffset + samples_per_clump*(clumps_per_line-1) + hsamp)) {
+ TIFFErrorExt(tif->tif_clientdata, "JPEGDecodeRaw",
+ "application buffer not large enough for all data, possible subsampling issue");
+ return 0;
+ }
+#endif
+
+ if (hsamp == 1) {
+ /* fast path for at least Cb and Cr */
+ for (nclump = clumps_per_line; nclump-- > 0; ) {
+ outptr[0] = *inptr++;
+ outptr += samples_per_clump;
+ }
+ } else {
+ int xpos;
+
+ /* general case */
+ for (nclump = clumps_per_line; nclump-- > 0; ) {
+ for (xpos = 0; xpos < hsamp; xpos++)
+ outptr[xpos] = *inptr++;
+ outptr += samples_per_clump;
+ }
+ }
+ clumpoffset += hsamp;
+ }
+ }
+
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+ {
+ if (sp->cinfo.d.data_precision == 8)
+ {
+ int i=0;
+ int len = sp->cinfo.d.output_width * sp->cinfo.d.num_components;
+ for (i=0; i<len; i++)
+ {
+ ((unsigned char*)buf)[i] = tmpbuf[i] & 0xff;
+ }
+ }
+ else
+ { /* 12-bit */
+ int value_pairs = (sp->cinfo.d.output_width
+ * sp->cinfo.d.num_components) / 2;
+ int iPair;
+ for( iPair = 0; iPair < value_pairs; iPair++ )
+ {
+ unsigned char *out_ptr = ((unsigned char *) buf) + iPair * 3;
+ JSAMPLE *in_ptr = (JSAMPLE *) (tmpbuf + iPair * 2);
+ out_ptr[0] = (in_ptr[0] & 0xff0) >> 4;
+ out_ptr[1] = ((in_ptr[0] & 0xf) << 4)
+ | ((in_ptr[1] & 0xf00) >> 8);
+ out_ptr[2] = ((in_ptr[1] & 0xff) >> 0);
+ }
+ }
+ }
+#endif
+
+ sp->scancount ++;
+ tif->tif_row += sp->v_sampling;
+
+ buf += sp->bytesperline;
+ cc -= sp->bytesperline;
+
+ nrows -= sp->v_sampling;
+ } while (nrows > 0);
+
+#if defined(JPEG_LIB_MK1_OR_12BIT)
+ _TIFFfree(tmpbuf);
+#endif
+
+ }
+
+ /* Close down the decompressor if done. */
+ return sp->cinfo.d.output_scanline < sp->cinfo.d.output_height
+ || TIFFjpeg_finish_decompress(sp);
+}
+
+
+/*
+ * JPEG Encoding.
+ */
+
+static void
+unsuppress_quant_table (JPEGState* sp, int tblno)
+{
+ JQUANT_TBL* qtbl;
+
+ if ((qtbl = sp->cinfo.c.quant_tbl_ptrs[tblno]) != NULL)
+ qtbl->sent_table = FALSE;
+}
+
+static void
+unsuppress_huff_table (JPEGState* sp, int tblno)
+{
+ JHUFF_TBL* htbl;
+
+ if ((htbl = sp->cinfo.c.dc_huff_tbl_ptrs[tblno]) != NULL)
+ htbl->sent_table = FALSE;
+ if ((htbl = sp->cinfo.c.ac_huff_tbl_ptrs[tblno]) != NULL)
+ htbl->sent_table = FALSE;
+}
+
+static int
+prepare_JPEGTables(TIFF* tif)
+{
+ JPEGState* sp = JState(tif);
+
+ /* Initialize quant tables for current quality setting */
+ if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
+ return (0);
+ /* Mark only the tables we want for output */
+ /* NB: chrominance tables are currently used only with YCbCr */
+ if (!TIFFjpeg_suppress_tables(sp, TRUE))
+ return (0);
+ if (sp->jpegtablesmode & JPEGTABLESMODE_QUANT) {
+ unsuppress_quant_table(sp, 0);
+ if (sp->photometric == PHOTOMETRIC_YCBCR)
+ unsuppress_quant_table(sp, 1);
+ }
+ if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF) {
+ unsuppress_huff_table(sp, 0);
+ if (sp->photometric == PHOTOMETRIC_YCBCR)
+ unsuppress_huff_table(sp, 1);
+ }
+ /* Direct libjpeg output into jpegtables */
+ if (!TIFFjpeg_tables_dest(sp, tif))
+ return (0);
+ /* Emit tables-only datastream */
+ if (!TIFFjpeg_write_tables(sp))
+ return (0);
+
+ return (1);
+}
+
+static int
+JPEGSetupEncode(TIFF* tif)
+{
+ JPEGState* sp = JState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+ static const char module[] = "JPEGSetupEncode";
+
+#if defined(JPEG_DUAL_MODE_8_12) && !defined(TIFFInitJPEG)
+ if( tif->tif_dir.td_bitspersample == 12 )
+ return TIFFReInitJPEG_12( tif, COMPRESSION_JPEG, 1 );
+#endif
+
+ JPEGInitializeLibJPEG( tif, FALSE );
+
+ assert(sp != NULL);
+ assert(!sp->cinfo.comm.is_decompressor);
+
+ /*
+ * Initialize all JPEG parameters to default values.
+ * Note that jpeg_set_defaults needs legal values for
+ * in_color_space and input_components.
+ */
+ sp->cinfo.c.in_color_space = JCS_UNKNOWN;
+ sp->cinfo.c.input_components = 1;
+ if (!TIFFjpeg_set_defaults(sp))
+ return (0);
+ /* Set per-file parameters */
+ sp->photometric = td->td_photometric;
+ switch (sp->photometric) {
+ case PHOTOMETRIC_YCBCR:
+ sp->h_sampling = td->td_ycbcrsubsampling[0];
+ sp->v_sampling = td->td_ycbcrsubsampling[1];
+ /*
+ * A ReferenceBlackWhite field *must* be present since the
+ * default value is inappropriate for YCbCr. Fill in the
+ * proper value if application didn't set it.
+ */
+ {
+ float *ref;
+ if (!TIFFGetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
+ &ref)) {
+ float refbw[6];
+ long top = 1L << td->td_bitspersample;
+ refbw[0] = 0;
+ refbw[1] = (float)(top-1L);
+ refbw[2] = (float)(top>>1);
+ refbw[3] = refbw[1];
+ refbw[4] = refbw[2];
+ refbw[5] = refbw[1];
+ TIFFSetField(tif, TIFFTAG_REFERENCEBLACKWHITE,
+ refbw);
+ }
+ }
+ break;
+ case PHOTOMETRIC_PALETTE: /* disallowed by Tech Note */
+ case PHOTOMETRIC_MASK:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "PhotometricInterpretation %d not allowed for JPEG",
+ (int) sp->photometric);
+ return (0);
+ default:
+ /* TIFF 6.0 forbids subsampling of all other color spaces */
+ sp->h_sampling = 1;
+ sp->v_sampling = 1;
+ break;
+ }
+
+ /* Verify miscellaneous parameters */
+
+ /*
+ * This would need work if libtiff ever supports different
+ * depths for different components, or if libjpeg ever supports
+ * run-time selection of depth. Neither is imminent.
+ */
+#ifdef JPEG_LIB_MK1
+ /* BITS_IN_JSAMPLE now permits 8 and 12 --- dgilbert */
+ if (td->td_bitspersample != 8 && td->td_bitspersample != 12)
+#else
+ if (td->td_bitspersample != BITS_IN_JSAMPLE )
+#endif
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "BitsPerSample %d not allowed for JPEG",
+ (int) td->td_bitspersample);
+ return (0);
+ }
+ sp->cinfo.c.data_precision = td->td_bitspersample;
+#ifdef JPEG_LIB_MK1
+ sp->cinfo.c.bits_in_jsample = td->td_bitspersample;
+#endif
+ if (isTiled(tif)) {
+ if ((td->td_tilelength % (sp->v_sampling * DCTSIZE)) != 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "JPEG tile height must be multiple of %d",
+ sp->v_sampling * DCTSIZE);
+ return (0);
+ }
+ if ((td->td_tilewidth % (sp->h_sampling * DCTSIZE)) != 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "JPEG tile width must be multiple of %d",
+ sp->h_sampling * DCTSIZE);
+ return (0);
+ }
+ } else {
+ if (td->td_rowsperstrip < td->td_imagelength &&
+ (td->td_rowsperstrip % (sp->v_sampling * DCTSIZE)) != 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "RowsPerStrip must be multiple of %d for JPEG",
+ sp->v_sampling * DCTSIZE);
+ return (0);
+ }
+ }
+
+ /* Create a JPEGTables field if appropriate */
+ if (sp->jpegtablesmode & (JPEGTABLESMODE_QUANT|JPEGTABLESMODE_HUFF)) {
+ if( sp->jpegtables == NULL
+ || memcmp(sp->jpegtables,"\0\0\0\0\0\0\0\0\0",8) == 0 )
+ {
+ if (!prepare_JPEGTables(tif))
+ return (0);
+ /* Mark the field present */
+ /* Can't use TIFFSetField since BEENWRITING is already set! */
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
+ }
+ } else {
+ /* We do not support application-supplied JPEGTables, */
+ /* so mark the field not present */
+ TIFFClrFieldBit(tif, FIELD_JPEGTABLES);
+ }
+
+ /* Direct libjpeg output to libtiff's output buffer */
+ TIFFjpeg_data_dest(sp, tif);
+
+ return (1);
+}
+
+/*
+ * Set encoding state at the start of a strip or tile.
+ */
+static int
+JPEGPreEncode(TIFF* tif, uint16 s)
+{
+ JPEGState *sp = JState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+ static const char module[] = "JPEGPreEncode";
+ uint32 segment_width, segment_height;
+ int downsampled_input;
+
+ assert(sp != NULL);
+
+ if (sp->cinfo.comm.is_decompressor == 1)
+ {
+ tif->tif_setupencode( tif );
+ }
+
+ assert(!sp->cinfo.comm.is_decompressor);
+ /*
+ * Set encoding parameters for this strip/tile.
+ */
+ if (isTiled(tif)) {
+ segment_width = td->td_tilewidth;
+ segment_height = td->td_tilelength;
+ sp->bytesperline = TIFFTileRowSize(tif);
+ } else {
+ segment_width = td->td_imagewidth;
+ segment_height = td->td_imagelength - tif->tif_row;
+ if (segment_height > td->td_rowsperstrip)
+ segment_height = td->td_rowsperstrip;
+ sp->bytesperline = TIFFScanlineSize(tif);
+ }
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE && s > 0) {
+ /* for PC 2, scale down the strip/tile size
+ * to match a downsampled component
+ */
+ segment_width = TIFFhowmany_32(segment_width, sp->h_sampling);
+ segment_height = TIFFhowmany_32(segment_height, sp->v_sampling);
+ }
+ if (segment_width > 65535 || segment_height > 65535) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Strip/tile too large for JPEG");
+ return (0);
+ }
+ sp->cinfo.c.image_width = segment_width;
+ sp->cinfo.c.image_height = segment_height;
+ downsampled_input = FALSE;
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+ sp->cinfo.c.input_components = td->td_samplesperpixel;
+ if (sp->photometric == PHOTOMETRIC_YCBCR) {
+ if (sp->jpegcolormode == JPEGCOLORMODE_RGB) {
+ sp->cinfo.c.in_color_space = JCS_RGB;
+ } else {
+ sp->cinfo.c.in_color_space = JCS_YCbCr;
+ if (sp->h_sampling != 1 || sp->v_sampling != 1)
+ downsampled_input = TRUE;
+ }
+ if (!TIFFjpeg_set_colorspace(sp, JCS_YCbCr))
+ return (0);
+ /*
+ * Set Y sampling factors;
+ * we assume jpeg_set_colorspace() set the rest to 1
+ */
+ sp->cinfo.c.comp_info[0].h_samp_factor = sp->h_sampling;
+ sp->cinfo.c.comp_info[0].v_samp_factor = sp->v_sampling;
+ } else {
+ if ((td->td_photometric == PHOTOMETRIC_MINISWHITE || td->td_photometric == PHOTOMETRIC_MINISBLACK) && td->td_samplesperpixel == 1)
+ sp->cinfo.c.in_color_space = JCS_GRAYSCALE;
+ else if (td->td_photometric == PHOTOMETRIC_RGB && td->td_samplesperpixel == 3)
+ sp->cinfo.c.in_color_space = JCS_RGB;
+ else if (td->td_photometric == PHOTOMETRIC_SEPARATED && td->td_samplesperpixel == 4)
+ sp->cinfo.c.in_color_space = JCS_CMYK;
+ else
+ sp->cinfo.c.in_color_space = JCS_UNKNOWN;
+ if (!TIFFjpeg_set_colorspace(sp, sp->cinfo.c.in_color_space))
+ return (0);
+ /* jpeg_set_colorspace set all sampling factors to 1 */
+ }
+ } else {
+ sp->cinfo.c.input_components = 1;
+ sp->cinfo.c.in_color_space = JCS_UNKNOWN;
+ if (!TIFFjpeg_set_colorspace(sp, JCS_UNKNOWN))
+ return (0);
+ sp->cinfo.c.comp_info[0].component_id = s;
+ /* jpeg_set_colorspace() set sampling factors to 1 */
+ if (sp->photometric == PHOTOMETRIC_YCBCR && s > 0) {
+ sp->cinfo.c.comp_info[0].quant_tbl_no = 1;
+ sp->cinfo.c.comp_info[0].dc_tbl_no = 1;
+ sp->cinfo.c.comp_info[0].ac_tbl_no = 1;
+ }
+ }
+ /* ensure libjpeg won't write any extraneous markers */
+ sp->cinfo.c.write_JFIF_header = FALSE;
+ sp->cinfo.c.write_Adobe_marker = FALSE;
+ /* set up table handling correctly */
+ if (!TIFFjpeg_set_quality(sp, sp->jpegquality, FALSE))
+ return (0);
+ if (! (sp->jpegtablesmode & JPEGTABLESMODE_QUANT)) {
+ unsuppress_quant_table(sp, 0);
+ unsuppress_quant_table(sp, 1);
+ }
+ if (sp->jpegtablesmode & JPEGTABLESMODE_HUFF)
+ sp->cinfo.c.optimize_coding = FALSE;
+ else
+ sp->cinfo.c.optimize_coding = TRUE;
+ if (downsampled_input) {
+ /* Need to use raw-data interface to libjpeg */
+ sp->cinfo.c.raw_data_in = TRUE;
+ tif->tif_encoderow = JPEGEncodeRaw;
+ tif->tif_encodestrip = JPEGEncodeRaw;
+ tif->tif_encodetile = JPEGEncodeRaw;
+ } else {
+ /* Use normal interface to libjpeg */
+ sp->cinfo.c.raw_data_in = FALSE;
+ tif->tif_encoderow = JPEGEncode;
+ tif->tif_encodestrip = JPEGEncode;
+ tif->tif_encodetile = JPEGEncode;
+ }
+ /* Start JPEG compressor */
+ if (!TIFFjpeg_start_compress(sp, FALSE))
+ return (0);
+ /* Allocate downsampled-data buffers if needed */
+ if (downsampled_input) {
+ if (!alloc_downsampled_buffers(tif, sp->cinfo.c.comp_info,
+ sp->cinfo.c.num_components))
+ return (0);
+ }
+ sp->scancount = 0;
+
+ return (1);
+}
+
+/*
+ * Encode a chunk of pixels.
+ * "Standard" case: incoming data is not downsampled.
+ */
+static int
+JPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ JPEGState *sp = JState(tif);
+ tmsize_t nrows;
+ JSAMPROW bufptr[1];
+ short *line16 = NULL;
+ int line16_count = 0;
+
+ (void) s;
+ assert(sp != NULL);
+ /* data is expected to be supplied in multiples of a scanline */
+ nrows = cc / sp->bytesperline;
+ if (cc % sp->bytesperline)
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
+ "fractional scanline discarded");
+
+ /* The last strip will be limited to image size */
+ if( !isTiled(tif) && tif->tif_row+nrows > tif->tif_dir.td_imagelength )
+ nrows = tif->tif_dir.td_imagelength - tif->tif_row;
+
+ if( sp->cinfo.c.data_precision == 12 )
+ {
+ line16_count = (int)((sp->bytesperline * 2) / 3);
+ line16 = (short *) _TIFFmalloc(sizeof(short) * line16_count);
+ // FIXME: undiagnosed malloc failure
+ }
+
+ while (nrows-- > 0) {
+
+ if( sp->cinfo.c.data_precision == 12 )
+ {
+
+ int value_pairs = line16_count / 2;
+ int iPair;
+
+ bufptr[0] = (JSAMPROW) line16;
+
+ for( iPair = 0; iPair < value_pairs; iPair++ )
+ {
+ unsigned char *in_ptr =
+ ((unsigned char *) buf) + iPair * 3;
+ JSAMPLE *out_ptr = (JSAMPLE *) (line16 + iPair * 2);
+
+ out_ptr[0] = (in_ptr[0] << 4) | ((in_ptr[1] & 0xf0) >> 4);
+ out_ptr[1] = ((in_ptr[1] & 0x0f) << 8) | in_ptr[2];
+ }
+ }
+ else
+ {
+ bufptr[0] = (JSAMPROW) buf;
+ }
+ if (TIFFjpeg_write_scanlines(sp, bufptr, 1) != 1)
+ return (0);
+ if (nrows > 0)
+ tif->tif_row++;
+ buf += sp->bytesperline;
+ }
+
+ if( sp->cinfo.c.data_precision == 12 )
+ {
+ _TIFFfree( line16 );
+ }
+
+ return (1);
+}
+
+/*
+ * Encode a chunk of pixels.
+ * Incoming data is expected to be downsampled per sampling factors.
+ */
+static int
+JPEGEncodeRaw(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ JPEGState *sp = JState(tif);
+ JSAMPLE* inptr;
+ JSAMPLE* outptr;
+ tmsize_t nrows;
+ JDIMENSION clumps_per_line, nclump;
+ int clumpoffset, ci, xpos, ypos;
+ jpeg_component_info* compptr;
+ int samples_per_clump = sp->samplesperclump;
+ tmsize_t bytesperclumpline;
+
+ (void) s;
+ assert(sp != NULL);
+ /* data is expected to be supplied in multiples of a clumpline */
+ /* a clumpline is equivalent to v_sampling desubsampled scanlines */
+ /* TODO: the following calculation of bytesperclumpline, should substitute calculation of sp->bytesperline, except that it is per v_sampling lines */
+ bytesperclumpline = (((sp->cinfo.c.image_width+sp->h_sampling-1)/sp->h_sampling)
+ *(sp->h_sampling*sp->v_sampling+2)*sp->cinfo.c.data_precision+7)
+ /8;
+
+ nrows = ( cc / bytesperclumpline ) * sp->v_sampling;
+ if (cc % bytesperclumpline)
+ TIFFWarningExt(tif->tif_clientdata, tif->tif_name, "fractional scanline discarded");
+
+ /* Cb,Cr both have sampling factors 1, so this is correct */
+ clumps_per_line = sp->cinfo.c.comp_info[1].downsampled_width;
+
+ while (nrows > 0) {
+ /*
+ * Fastest way to separate the data is to make one pass
+ * over the scanline for each row of each component.
+ */
+ clumpoffset = 0; /* first sample in clump */
+ for (ci = 0, compptr = sp->cinfo.c.comp_info;
+ ci < sp->cinfo.c.num_components;
+ ci++, compptr++) {
+ int hsamp = compptr->h_samp_factor;
+ int vsamp = compptr->v_samp_factor;
+ int padding = (int) (compptr->width_in_blocks * DCTSIZE -
+ clumps_per_line * hsamp);
+ for (ypos = 0; ypos < vsamp; ypos++) {
+ inptr = ((JSAMPLE*) buf) + clumpoffset;
+ outptr = sp->ds_buffer[ci][sp->scancount*vsamp + ypos];
+ if (hsamp == 1) {
+ /* fast path for at least Cb and Cr */
+ for (nclump = clumps_per_line; nclump-- > 0; ) {
+ *outptr++ = inptr[0];
+ inptr += samples_per_clump;
+ }
+ } else {
+ /* general case */
+ for (nclump = clumps_per_line; nclump-- > 0; ) {
+ for (xpos = 0; xpos < hsamp; xpos++)
+ *outptr++ = inptr[xpos];
+ inptr += samples_per_clump;
+ }
+ }
+ /* pad each scanline as needed */
+ for (xpos = 0; xpos < padding; xpos++) {
+ *outptr = outptr[-1];
+ outptr++;
+ }
+ clumpoffset += hsamp;
+ }
+ }
+ sp->scancount++;
+ if (sp->scancount >= DCTSIZE) {
+ int n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
+ if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
+ return (0);
+ sp->scancount = 0;
+ }
+ tif->tif_row += sp->v_sampling;
+ buf += bytesperclumpline;
+ nrows -= sp->v_sampling;
+ }
+ return (1);
+}
+
+/*
+ * Finish up at the end of a strip or tile.
+ */
+static int
+JPEGPostEncode(TIFF* tif)
+{
+ JPEGState *sp = JState(tif);
+
+ if (sp->scancount > 0) {
+ /*
+ * Need to emit a partial bufferload of downsampled data.
+ * Pad the data vertically.
+ */
+ int ci, ypos, n;
+ jpeg_component_info* compptr;
+
+ for (ci = 0, compptr = sp->cinfo.c.comp_info;
+ ci < sp->cinfo.c.num_components;
+ ci++, compptr++) {
+ int vsamp = compptr->v_samp_factor;
+ tmsize_t row_width = compptr->width_in_blocks * DCTSIZE
+ * sizeof(JSAMPLE);
+ for (ypos = sp->scancount * vsamp;
+ ypos < DCTSIZE * vsamp; ypos++) {
+ _TIFFmemcpy((void*)sp->ds_buffer[ci][ypos],
+ (void*)sp->ds_buffer[ci][ypos-1],
+ row_width);
+
+ }
+ }
+ n = sp->cinfo.c.max_v_samp_factor * DCTSIZE;
+ if (TIFFjpeg_write_raw_data(sp, sp->ds_buffer, n) != n)
+ return (0);
+ }
+
+ return (TIFFjpeg_finish_compress(JState(tif)));
+}
+
+static void
+JPEGCleanup(TIFF* tif)
+{
+ JPEGState *sp = JState(tif);
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+ tif->tif_tagmethods.printdir = sp->printdir;
+
+ if( sp != NULL ) {
+ if( sp->cinfo_initialized )
+ TIFFjpeg_destroy(sp); /* release libjpeg resources */
+ if (sp->jpegtables) /* tag value */
+ _TIFFfree(sp->jpegtables);
+ }
+ _TIFFfree(tif->tif_data); /* release local state */
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static void
+JPEGResetUpsampled( TIFF* tif )
+{
+ JPEGState* sp = JState(tif);
+ TIFFDirectory* td = &tif->tif_dir;
+
+ /*
+ * Mark whether returned data is up-sampled or not so TIFFStripSize
+ * and TIFFTileSize return values that reflect the true amount of
+ * data.
+ */
+ tif->tif_flags &= ~TIFF_UPSAMPLED;
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+ if (td->td_photometric == PHOTOMETRIC_YCBCR &&
+ sp->jpegcolormode == JPEGCOLORMODE_RGB) {
+ tif->tif_flags |= TIFF_UPSAMPLED;
+ } else {
+#ifdef notdef
+ if (td->td_ycbcrsubsampling[0] != 1 ||
+ td->td_ycbcrsubsampling[1] != 1)
+ ; /* XXX what about up-sampling? */
+#endif
+ }
+ }
+
+ /*
+ * Must recalculate cached tile size in case sampling state changed.
+ * Should we really be doing this now if image size isn't set?
+ */
+ if( tif->tif_tilesize > 0 )
+ tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
+ if( tif->tif_scanlinesize > 0 )
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+}
+
+static int
+JPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ JPEGState* sp = JState(tif);
+ const TIFFField* fip;
+ uint32 v32;
+
+ assert(sp != NULL);
+
+ switch (tag) {
+ case TIFFTAG_JPEGTABLES:
+ v32 = (uint32) va_arg(ap, uint32);
+ if (v32 == 0) {
+ /* XXX */
+ return (0);
+ }
+ _TIFFsetByteArray(&sp->jpegtables, va_arg(ap, void*),
+ (long) v32);
+ sp->jpegtables_length = v32;
+ TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
+ break;
+ case TIFFTAG_JPEGQUALITY:
+ sp->jpegquality = (int) va_arg(ap, int);
+ return (1); /* pseudo tag */
+ case TIFFTAG_JPEGCOLORMODE:
+ sp->jpegcolormode = (int) va_arg(ap, int);
+ JPEGResetUpsampled( tif );
+ return (1); /* pseudo tag */
+ case TIFFTAG_PHOTOMETRIC:
+ {
+ int ret_value = (*sp->vsetparent)(tif, tag, ap);
+ JPEGResetUpsampled( tif );
+ return ret_value;
+ }
+ case TIFFTAG_JPEGTABLESMODE:
+ sp->jpegtablesmode = (int) va_arg(ap, int);
+ return (1); /* pseudo tag */
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ /* mark the fact that we have a real ycbcrsubsampling! */
+ sp->ycbcrsampling_fetched = 1;
+ /* should we be recomputing upsampling info here? */
+ return (*sp->vsetparent)(tif, tag, ap);
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+
+ if ((fip = TIFFFieldWithTag(tif, tag))) {
+ TIFFSetFieldBit(tif, fip->field_bit);
+ } else {
+ return (0);
+ }
+
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ return (1);
+}
+
+static int
+JPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ JPEGState* sp = JState(tif);
+
+ assert(sp != NULL);
+
+ switch (tag) {
+ case TIFFTAG_JPEGTABLES:
+ *va_arg(ap, uint32*) = sp->jpegtables_length;
+ *va_arg(ap, void**) = sp->jpegtables;
+ break;
+ case TIFFTAG_JPEGQUALITY:
+ *va_arg(ap, int*) = sp->jpegquality;
+ break;
+ case TIFFTAG_JPEGCOLORMODE:
+ *va_arg(ap, int*) = sp->jpegcolormode;
+ break;
+ case TIFFTAG_JPEGTABLESMODE:
+ *va_arg(ap, int*) = sp->jpegtablesmode;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static void
+JPEGPrintDir(TIFF* tif, FILE* fd, long flags)
+{
+ JPEGState* sp = JState(tif);
+
+ assert(sp != NULL);
+ (void) flags;
+
+ if( sp != NULL ) {
+ if (TIFFFieldSet(tif,FIELD_JPEGTABLES))
+ fprintf(fd, " JPEG Tables: (%lu bytes)\n",
+ (unsigned long) sp->jpegtables_length);
+ if (sp->printdir)
+ (*sp->printdir)(tif, fd, flags);
+ }
+}
+
+static uint32
+JPEGDefaultStripSize(TIFF* tif, uint32 s)
+{
+ JPEGState* sp = JState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ s = (*sp->defsparent)(tif, s);
+ if (s < td->td_imagelength)
+ s = TIFFroundup_32(s, td->td_ycbcrsubsampling[1] * DCTSIZE);
+ return (s);
+}
+
+static void
+JPEGDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
+{
+ JPEGState* sp = JState(tif);
+ TIFFDirectory *td = &tif->tif_dir;
+
+ (*sp->deftparent)(tif, tw, th);
+ *tw = TIFFroundup_32(*tw, td->td_ycbcrsubsampling[0] * DCTSIZE);
+ *th = TIFFroundup_32(*th, td->td_ycbcrsubsampling[1] * DCTSIZE);
+}
+
+/*
+ * The JPEG library initialized used to be done in TIFFInitJPEG(), but
+ * now that we allow a TIFF file to be opened in update mode it is necessary
+ * to have some way of deciding whether compression or decompression is
+ * desired other than looking at tif->tif_mode. We accomplish this by
+ * examining {TILE/STRIP}BYTECOUNTS to see if there is a non-zero entry.
+ * If so, we assume decompression is desired.
+ *
+ * This is tricky, because TIFFInitJPEG() is called while the directory is
+ * being read, and generally speaking the BYTECOUNTS tag won't have been read
+ * at that point. So we try to defer jpeg library initialization till we
+ * do have that tag ... basically any access that might require the compressor
+ * or decompressor that occurs after the reading of the directory.
+ *
+ * In an ideal world compressors or decompressors would be setup
+ * at the point where a single tile or strip was accessed (for read or write)
+ * so that stuff like update of missing tiles, or replacement of tiles could
+ * be done. However, we aren't trying to crack that nut just yet ...
+ *
+ * NFW, Feb 3rd, 2003.
+ */
+
+static int JPEGInitializeLibJPEG( TIFF * tif, int decompress )
+{
+ JPEGState* sp = JState(tif);
+
+ if(sp->cinfo_initialized)
+ {
+ if( !decompress && sp->cinfo.comm.is_decompressor )
+ TIFFjpeg_destroy( sp );
+ else if( decompress && !sp->cinfo.comm.is_decompressor )
+ TIFFjpeg_destroy( sp );
+ else
+ return 1;
+
+ sp->cinfo_initialized = 0;
+ }
+
+ /*
+ * Initialize libjpeg.
+ */
+ if ( decompress ) {
+ if (!TIFFjpeg_create_decompress(sp))
+ return (0);
+ } else {
+ if (!TIFFjpeg_create_compress(sp))
+ return (0);
+ }
+
+ sp->cinfo_initialized = TRUE;
+
+ return 1;
+}
+
+int
+TIFFInitJPEG(TIFF* tif, int scheme)
+{
+ JPEGState* sp;
+
+ assert(scheme == COMPRESSION_JPEG);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, jpegFields, TIFFArrayCount(jpegFields))) {
+ TIFFErrorExt(tif->tif_clientdata,
+ "TIFFInitJPEG",
+ "Merging JPEG codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8*) _TIFFmalloc(sizeof (JPEGState));
+
+ if (tif->tif_data == NULL) {
+ TIFFErrorExt(tif->tif_clientdata,
+ "TIFFInitJPEG", "No space for JPEG state block");
+ return 0;
+ }
+ _TIFFmemset(tif->tif_data, 0, sizeof(JPEGState));
+
+ sp = JState(tif);
+ sp->tif = tif; /* back link */
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = JPEGVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = JPEGVSetField; /* hook for codec tags */
+ sp->printdir = tif->tif_tagmethods.printdir;
+ tif->tif_tagmethods.printdir = JPEGPrintDir; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->jpegtables = NULL;
+ sp->jpegtables_length = 0;
+ sp->jpegquality = 75; /* Default IJG quality */
+ sp->jpegcolormode = JPEGCOLORMODE_RAW;
+ sp->jpegtablesmode = JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF;
+ sp->ycbcrsampling_fetched = 0;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = JPEGFixupTags;
+ tif->tif_setupdecode = JPEGSetupDecode;
+ tif->tif_predecode = JPEGPreDecode;
+ tif->tif_decoderow = JPEGDecode;
+ tif->tif_decodestrip = JPEGDecode;
+ tif->tif_decodetile = JPEGDecode;
+ tif->tif_setupencode = JPEGSetupEncode;
+ tif->tif_preencode = JPEGPreEncode;
+ tif->tif_postencode = JPEGPostEncode;
+ tif->tif_encoderow = JPEGEncode;
+ tif->tif_encodestrip = JPEGEncode;
+ tif->tif_encodetile = JPEGEncode;
+ tif->tif_cleanup = JPEGCleanup;
+ sp->defsparent = tif->tif_defstripsize;
+ tif->tif_defstripsize = JPEGDefaultStripSize;
+ sp->deftparent = tif->tif_deftilesize;
+ tif->tif_deftilesize = JPEGDefaultTileSize;
+ tif->tif_flags |= TIFF_NOBITREV; /* no bit reversal, please */
+
+ sp->cinfo_initialized = FALSE;
+
+ /*
+ ** Create a JPEGTables field if no directory has yet been created.
+ ** We do this just to ensure that sufficient space is reserved for
+ ** the JPEGTables field. It will be properly created the right
+ ** size later.
+ */
+ if( tif->tif_diroff == 0 )
+ {
+#define SIZE_OF_JPEGTABLES 2000
+/*
+The following line assumes incorrectly that all JPEG-in-TIFF files will have
+a JPEGTABLES tag generated and causes null-filled JPEGTABLES tags to be written
+when the JPEG data is placed with TIFFWriteRawStrip. The field bit should be
+set, anyway, later when actual JPEGTABLES header is generated, so removing it
+here hopefully is harmless.
+ TIFFSetFieldBit(tif, FIELD_JPEGTABLES);
+*/
+ sp->jpegtables_length = SIZE_OF_JPEGTABLES;
+ sp->jpegtables = (void *) _TIFFmalloc(sp->jpegtables_length);
+ // FIXME: NULL-deref after malloc failure
+ _TIFFmemset(sp->jpegtables, 0, SIZE_OF_JPEGTABLES);
+#undef SIZE_OF_JPEGTABLES
+ }
+
+ return 1;
+}
+#endif /* JPEG_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_luv.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_luv.c
new file mode 100644
index 0000000000..0c2298989b
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_luv.c
@@ -0,0 +1,1687 @@
+/* $Id: tif_luv.c,v 1.35 2011-04-02 20:54:09 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1997 Greg Ward Larson
+ * Copyright (c) 1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler, Greg Larson and Silicon Graphics may not be used in any
+ * advertising or publicity relating to the software without the specific,
+ * prior written permission of Sam Leffler, Greg Larson and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER, GREG LARSON OR SILICON GRAPHICS BE LIABLE
+ * FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#ifdef LOGLUV_SUPPORT
+
+/*
+ * TIFF Library.
+ * LogLuv compression support for high dynamic range images.
+ *
+ * Contributed by Greg Larson.
+ *
+ * LogLuv image support uses the TIFF library to store 16 or 10-bit
+ * log luminance values with 8 bits each of u and v or a 14-bit index.
+ *
+ * The codec can take as input and produce as output 32-bit IEEE float values
+ * as well as 16-bit integer values. A 16-bit luminance is interpreted
+ * as a sign bit followed by a 15-bit integer that is converted
+ * to and from a linear magnitude using the transformation:
+ *
+ * L = 2^( (Le+.5)/256 - 64 ) # real from 15-bit
+ *
+ * Le = floor( 256*(log2(L) + 64) ) # 15-bit from real
+ *
+ * The actual conversion to world luminance units in candelas per sq. meter
+ * requires an additional multiplier, which is stored in the TIFFTAG_STONITS.
+ * This value is usually set such that a reasonable exposure comes from
+ * clamping decoded luminances above 1 to 1 in the displayed image.
+ *
+ * The 16-bit values for u and v may be converted to real values by dividing
+ * each by 32768. (This allows for negative values, which aren't useful as
+ * far as we know, but are left in case of future improvements in human
+ * color vision.)
+ *
+ * Conversion from (u,v), which is actually the CIE (u',v') system for
+ * you color scientists, is accomplished by the following transformation:
+ *
+ * u = 4*x / (-2*x + 12*y + 3)
+ * v = 9*y / (-2*x + 12*y + 3)
+ *
+ * x = 9*u / (6*u - 16*v + 12)
+ * y = 4*v / (6*u - 16*v + 12)
+ *
+ * This process is greatly simplified by passing 32-bit IEEE floats
+ * for each of three CIE XYZ coordinates. The codec then takes care
+ * of conversion to and from LogLuv, though the application is still
+ * responsible for interpreting the TIFFTAG_STONITS calibration factor.
+ *
+ * By definition, a CIE XYZ vector of [1 1 1] corresponds to a neutral white
+ * point of (x,y)=(1/3,1/3). However, most color systems assume some other
+ * white point, such as D65, and an absolute color conversion to XYZ then
+ * to another color space with a different white point may introduce an
+ * unwanted color cast to the image. It is often desirable, therefore, to
+ * perform a white point conversion that maps the input white to [1 1 1]
+ * in XYZ, then record the original white point using the TIFFTAG_WHITEPOINT
+ * tag value. A decoder that demands absolute color calibration may use
+ * this white point tag to get back the original colors, but usually it
+ * will be ignored and the new white point will be used instead that
+ * matches the output color space.
+ *
+ * Pixel information is compressed into one of two basic encodings, depending
+ * on the setting of the compression tag, which is one of COMPRESSION_SGILOG
+ * or COMPRESSION_SGILOG24. For COMPRESSION_SGILOG, greyscale data is
+ * stored as:
+ *
+ * 1 15
+ * |-+---------------|
+ *
+ * COMPRESSION_SGILOG color data is stored as:
+ *
+ * 1 15 8 8
+ * |-+---------------|--------+--------|
+ * S Le ue ve
+ *
+ * For the 24-bit COMPRESSION_SGILOG24 color format, the data is stored as:
+ *
+ * 10 14
+ * |----------|--------------|
+ * Le' Ce
+ *
+ * There is no sign bit in the 24-bit case, and the (u,v) chromaticity is
+ * encoded as an index for optimal color resolution. The 10 log bits are
+ * defined by the following conversions:
+ *
+ * L = 2^((Le'+.5)/64 - 12) # real from 10-bit
+ *
+ * Le' = floor( 64*(log2(L) + 12) ) # 10-bit from real
+ *
+ * The 10 bits of the smaller format may be converted into the 15 bits of
+ * the larger format by multiplying by 4 and adding 13314. Obviously,
+ * a smaller range of magnitudes is covered (about 5 orders of magnitude
+ * instead of 38), and the lack of a sign bit means that negative luminances
+ * are not allowed. (Well, they aren't allowed in the real world, either,
+ * but they are useful for certain types of image processing.)
+ *
+ * The desired user format is controlled by the setting the internal
+ * pseudo tag TIFFTAG_SGILOGDATAFMT to one of:
+ * SGILOGDATAFMT_FLOAT = IEEE 32-bit float XYZ values
+ * SGILOGDATAFMT_16BIT = 16-bit integer encodings of logL, u and v
+ * Raw data i/o is also possible using:
+ * SGILOGDATAFMT_RAW = 32-bit unsigned integer with encoded pixel
+ * In addition, the following decoding is provided for ease of display:
+ * SGILOGDATAFMT_8BIT = 8-bit default RGB gamma-corrected values
+ *
+ * For grayscale images, we provide the following data formats:
+ * SGILOGDATAFMT_FLOAT = IEEE 32-bit float Y values
+ * SGILOGDATAFMT_16BIT = 16-bit integer w/ encoded luminance
+ * SGILOGDATAFMT_8BIT = 8-bit gray monitor values
+ *
+ * Note that the COMPRESSION_SGILOG applies a simple run-length encoding
+ * scheme by separating the logL, u and v bytes for each row and applying
+ * a PackBits type of compression. Since the 24-bit encoding is not
+ * adaptive, the 32-bit color format takes less space in many cases.
+ *
+ * Further control is provided over the conversion from higher-resolution
+ * formats to final encoded values through the pseudo tag
+ * TIFFTAG_SGILOGENCODE:
+ * SGILOGENCODE_NODITHER = do not dither encoded values
+ * SGILOGENCODE_RANDITHER = apply random dithering during encoding
+ *
+ * The default value of this tag is SGILOGENCODE_NODITHER for
+ * COMPRESSION_SGILOG to maximize run-length encoding and
+ * SGILOGENCODE_RANDITHER for COMPRESSION_SGILOG24 to turn
+ * quantization errors into noise.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/*
+ * State block for each open TIFF
+ * file using LogLuv compression/decompression.
+ */
+typedef struct logLuvState LogLuvState;
+
+struct logLuvState {
+ int user_datafmt; /* user data format */
+ int encode_meth; /* encoding method */
+ int pixel_size; /* bytes per pixel */
+
+ uint8* tbuf; /* translation buffer */
+ tmsize_t tbuflen; /* buffer length */
+ void (*tfunc)(LogLuvState*, uint8*, tmsize_t);
+
+ TIFFVSetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+};
+
+#define DecoderState(tif) ((LogLuvState*) (tif)->tif_data)
+#define EncoderState(tif) ((LogLuvState*) (tif)->tif_data)
+
+#define SGILOGDATAFMT_UNKNOWN -1
+
+#define MINRUN 4 /* minimum run length */
+
+/*
+ * Decode a string of 16-bit gray pixels.
+ */
+static int
+LogL16Decode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "LogL16Decode";
+ LogLuvState* sp = DecoderState(tif);
+ int shft;
+ tmsize_t i;
+ tmsize_t npixels;
+ unsigned char* bp;
+ int16* tp;
+ int16 b;
+ tmsize_t cc;
+ int rc;
+
+ assert(s == 0);
+ assert(sp != NULL);
+
+ npixels = occ / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
+ tp = (int16*) op;
+ else {
+ assert(sp->tbuflen >= npixels);
+ tp = (int16*) sp->tbuf;
+ }
+ _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
+
+ bp = (unsigned char*) tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ /* get each byte string */
+ for (shft = 2*8; (shft -= 8) >= 0; ) {
+ for (i = 0; i < npixels && cc > 0; )
+ if (*bp >= 128) { /* run */
+ rc = *bp++ + (2-128); /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
+ b = (int16)(*bp++ << shft);
+ cc -= 2;
+ while (rc-- && i < npixels)
+ tp[i++] |= b;
+ } else { /* non-run */
+ rc = *bp++; /* nul is noop */
+ while (--cc && rc-- && i < npixels)
+ tp[i++] |= (int16)*bp++ << shft;
+ }
+ if (i != npixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at row %lu (short %I64d pixels)",
+ (unsigned long) tif->tif_row,
+ (unsigned __int64) (npixels - i));
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at row %lu (short %llu pixels)",
+ (unsigned long) tif->tif_row,
+ (unsigned long long) (npixels - i));
+#endif
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ return (0);
+ }
+ }
+ (*sp->tfunc)(sp, op, npixels);
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ return (1);
+}
+
+/*
+ * Decode a string of 24-bit pixels.
+ */
+static int
+LogLuvDecode24(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "LogLuvDecode24";
+ LogLuvState* sp = DecoderState(tif);
+ tmsize_t cc;
+ tmsize_t i;
+ tmsize_t npixels;
+ unsigned char* bp;
+ uint32* tp;
+
+ assert(s == 0);
+ assert(sp != NULL);
+
+ npixels = occ / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32 *)op;
+ else {
+ assert(sp->tbuflen >= npixels);
+ tp = (uint32 *) sp->tbuf;
+ }
+ /* copy to array of uint32 */
+ bp = (unsigned char*) tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ for (i = 0; i < npixels && cc > 0; i++) {
+ tp[i] = bp[0] << 16 | bp[1] << 8 | bp[2];
+ bp += 3;
+ cc -= 3;
+ }
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ if (i != npixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at row %lu (short %I64d pixels)",
+ (unsigned long) tif->tif_row,
+ (unsigned __int64) (npixels - i));
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at row %lu (short %llu pixels)",
+ (unsigned long) tif->tif_row,
+ (unsigned long long) (npixels - i));
+#endif
+ return (0);
+ }
+ (*sp->tfunc)(sp, op, npixels);
+ return (1);
+}
+
+/*
+ * Decode a string of 32-bit pixels.
+ */
+static int
+LogLuvDecode32(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "LogLuvDecode32";
+ LogLuvState* sp;
+ int shft;
+ tmsize_t i;
+ tmsize_t npixels;
+ unsigned char* bp;
+ uint32* tp;
+ uint32 b;
+ tmsize_t cc;
+ int rc;
+
+ assert(s == 0);
+ sp = DecoderState(tif);
+ assert(sp != NULL);
+
+ npixels = occ / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32*) op;
+ else {
+ assert(sp->tbuflen >= npixels);
+ tp = (uint32*) sp->tbuf;
+ }
+ _TIFFmemset((void*) tp, 0, npixels*sizeof (tp[0]));
+
+ bp = (unsigned char*) tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ /* get each byte string */
+ for (shft = 4*8; (shft -= 8) >= 0; ) {
+ for (i = 0; i < npixels && cc > 0; )
+ if (*bp >= 128) { /* run */
+ rc = *bp++ + (2-128);
+ b = (uint32)*bp++ << shft;
+ cc -= 2; /* TODO: potential input buffer overrun when decoding corrupt or truncated data */
+ while (rc-- && i < npixels)
+ tp[i++] |= b;
+ } else { /* non-run */
+ rc = *bp++; /* nul is noop */
+ while (--cc && rc-- && i < npixels)
+ tp[i++] |= (uint32)*bp++ << shft;
+ }
+ if (i != npixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at row %lu (short %I64d pixels)",
+ (unsigned long) tif->tif_row,
+ (unsigned __int64) (npixels - i));
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at row %lu (short %llu pixels)",
+ (unsigned long) tif->tif_row,
+ (unsigned long long) (npixels - i));
+#endif
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ return (0);
+ }
+ }
+ (*sp->tfunc)(sp, op, npixels);
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ return (1);
+}
+
+/*
+ * Decode a strip of pixels. We break it into rows to
+ * maintain synchrony with the encode algorithm, which
+ * is row by row.
+ */
+static int
+LogLuvDecodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ tmsize_t rowlen = TIFFScanlineSize(tif);
+
+ assert(cc%rowlen == 0);
+ while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
+ bp += rowlen, cc -= rowlen;
+ return (cc == 0);
+}
+
+/*
+ * Decode a tile of pixels. We break it into rows to
+ * maintain synchrony with the encode algorithm, which
+ * is row by row.
+ */
+static int
+LogLuvDecodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ tmsize_t rowlen = TIFFTileRowSize(tif);
+
+ assert(cc%rowlen == 0);
+ while (cc && (*tif->tif_decoderow)(tif, bp, rowlen, s))
+ bp += rowlen, cc -= rowlen;
+ return (cc == 0);
+}
+
+/*
+ * Encode a row of 16-bit pixels.
+ */
+static int
+LogL16Encode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ LogLuvState* sp = EncoderState(tif);
+ int shft;
+ tmsize_t i;
+ tmsize_t j;
+ tmsize_t npixels;
+ uint8* op;
+ int16* tp;
+ int16 b;
+ tmsize_t occ;
+ int rc=0, mask;
+ tmsize_t beg;
+
+ assert(s == 0);
+ assert(sp != NULL);
+ npixels = cc / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_16BIT)
+ tp = (int16*) bp;
+ else {
+ tp = (int16*) sp->tbuf;
+ assert(sp->tbuflen >= npixels);
+ (*sp->tfunc)(sp, bp, npixels);
+ }
+ /* compress each byte string */
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ for (shft = 2*8; (shft -= 8) >= 0; )
+ for (i = 0; i < npixels; i += rc) {
+ if (occ < 4) {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (-1);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ mask = 0xff << shft; /* find next run */
+ for (beg = i; beg < npixels; beg += rc) {
+ b = (int16) (tp[beg] & mask);
+ rc = 1;
+ while (rc < 127+2 && beg+rc < npixels &&
+ (tp[beg+rc] & mask) == b)
+ rc++;
+ if (rc >= MINRUN)
+ break; /* long enough */
+ }
+ if (beg-i > 1 && beg-i < MINRUN) {
+ b = (int16) (tp[i] & mask);/*check short run */
+ j = i+1;
+ while ((tp[j++] & mask) == b)
+ if (j == beg) {
+ *op++ = (uint8)(128-2+j-i);
+ *op++ = (uint8)(b >> shft);
+ occ -= 2;
+ i = beg;
+ break;
+ }
+ }
+ while (i < beg) { /* write out non-run */
+ if ((j = beg-i) > 127) j = 127;
+ if (occ < j+3) {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (-1);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ *op++ = (uint8) j; occ--;
+ while (j--) {
+ *op++ = (uint8) (tp[i++] >> shft & 0xff);
+ occ--;
+ }
+ }
+ if (rc >= MINRUN) { /* write out run */
+ *op++ = (uint8) (128-2+rc);
+ *op++ = (uint8) (tp[beg] >> shft & 0xff);
+ occ -= 2;
+ } else
+ rc = 0;
+ }
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+ return (1);
+}
+
+/*
+ * Encode a row of 24-bit pixels.
+ */
+static int
+LogLuvEncode24(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ LogLuvState* sp = EncoderState(tif);
+ tmsize_t i;
+ tmsize_t npixels;
+ tmsize_t occ;
+ uint8* op;
+ uint32* tp;
+
+ assert(s == 0);
+ assert(sp != NULL);
+ npixels = cc / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32*) bp;
+ else {
+ tp = (uint32*) sp->tbuf;
+ assert(sp->tbuflen >= npixels);
+ (*sp->tfunc)(sp, bp, npixels);
+ }
+ /* write out encoded pixels */
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ for (i = npixels; i--; ) {
+ if (occ < 3) {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (-1);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ *op++ = (uint8)(*tp >> 16);
+ *op++ = (uint8)(*tp >> 8 & 0xff);
+ *op++ = (uint8)(*tp++ & 0xff);
+ occ -= 3;
+ }
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+ return (1);
+}
+
+/*
+ * Encode a row of 32-bit pixels.
+ */
+static int
+LogLuvEncode32(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ LogLuvState* sp = EncoderState(tif);
+ int shft;
+ tmsize_t i;
+ tmsize_t j;
+ tmsize_t npixels;
+ uint8* op;
+ uint32* tp;
+ uint32 b;
+ tmsize_t occ;
+ int rc=0, mask;
+ tmsize_t beg;
+
+ assert(s == 0);
+ assert(sp != NULL);
+
+ npixels = cc / sp->pixel_size;
+
+ if (sp->user_datafmt == SGILOGDATAFMT_RAW)
+ tp = (uint32*) bp;
+ else {
+ tp = (uint32*) sp->tbuf;
+ assert(sp->tbuflen >= npixels);
+ (*sp->tfunc)(sp, bp, npixels);
+ }
+ /* compress each byte string */
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ for (shft = 4*8; (shft -= 8) >= 0; )
+ for (i = 0; i < npixels; i += rc) {
+ if (occ < 4) {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (-1);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ mask = 0xff << shft; /* find next run */
+ for (beg = i; beg < npixels; beg += rc) {
+ b = tp[beg] & mask;
+ rc = 1;
+ while (rc < 127+2 && beg+rc < npixels &&
+ (tp[beg+rc] & mask) == b)
+ rc++;
+ if (rc >= MINRUN)
+ break; /* long enough */
+ }
+ if (beg-i > 1 && beg-i < MINRUN) {
+ b = tp[i] & mask; /* check short run */
+ j = i+1;
+ while ((tp[j++] & mask) == b)
+ if (j == beg) {
+ *op++ = (uint8)(128-2+j-i);
+ *op++ = (uint8)(b >> shft);
+ occ -= 2;
+ i = beg;
+ break;
+ }
+ }
+ while (i < beg) { /* write out non-run */
+ if ((j = beg-i) > 127) j = 127;
+ if (occ < j+3) {
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+ if (!TIFFFlushData1(tif))
+ return (-1);
+ op = tif->tif_rawcp;
+ occ = tif->tif_rawdatasize - tif->tif_rawcc;
+ }
+ *op++ = (uint8) j; occ--;
+ while (j--) {
+ *op++ = (uint8)(tp[i++] >> shft & 0xff);
+ occ--;
+ }
+ }
+ if (rc >= MINRUN) { /* write out run */
+ *op++ = (uint8) (128-2+rc);
+ *op++ = (uint8)(tp[beg] >> shft & 0xff);
+ occ -= 2;
+ } else
+ rc = 0;
+ }
+ tif->tif_rawcp = op;
+ tif->tif_rawcc = tif->tif_rawdatasize - occ;
+
+ return (1);
+}
+
+/*
+ * Encode a strip of pixels. We break it into rows to
+ * avoid encoding runs across row boundaries.
+ */
+static int
+LogLuvEncodeStrip(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ tmsize_t rowlen = TIFFScanlineSize(tif);
+
+ assert(cc%rowlen == 0);
+ while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
+ bp += rowlen, cc -= rowlen;
+ return (cc == 0);
+}
+
+/*
+ * Encode a tile of pixels. We break it into rows to
+ * avoid encoding runs across row boundaries.
+ */
+static int
+LogLuvEncodeTile(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ tmsize_t rowlen = TIFFTileRowSize(tif);
+
+ assert(cc%rowlen == 0);
+ while (cc && (*tif->tif_encoderow)(tif, bp, rowlen, s) == 1)
+ bp += rowlen, cc -= rowlen;
+ return (cc == 0);
+}
+
+/*
+ * Encode/Decode functions for converting to and from user formats.
+ */
+
+#include "uvcode.h"
+
+#ifndef UVSCALE
+#define U_NEU 0.210526316
+#define V_NEU 0.473684211
+#define UVSCALE 410.
+#endif
+
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+#ifndef log2
+#define log2(x) ((1./M_LN2)*log(x))
+#endif
+#define exp2(x) exp(M_LN2*(x))
+
+#define itrunc(x,m) ((m)==SGILOGENCODE_NODITHER ? \
+ (int)(x) : \
+ (int)((x) + rand()*(1./RAND_MAX) - .5))
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+double
+LogL16toY(int p16) /* compute luminance from 16-bit LogL */
+{
+ int Le = p16 & 0x7fff;
+ double Y;
+
+ if (!Le)
+ return (0.);
+ Y = exp(M_LN2/256.*(Le+.5) - M_LN2*64.);
+ return (!(p16 & 0x8000) ? Y : -Y);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+LogL16fromY(double Y, int em) /* get 16-bit LogL from Y */
+{
+ if (Y >= 1.8371976e19)
+ return (0x7fff);
+ if (Y <= -1.8371976e19)
+ return (0xffff);
+ if (Y > 5.4136769e-20)
+ return itrunc(256.*(log2(Y) + 64.), em);
+ if (Y < -5.4136769e-20)
+ return (~0x7fff | itrunc(256.*(log2(-Y) + 64.), em));
+ return (0);
+}
+
+static void
+L16toY(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ int16* l16 = (int16*) sp->tbuf;
+ float* yp = (float*) op;
+
+ while (n-- > 0)
+ *yp++ = (float)LogL16toY(*l16++);
+}
+
+static void
+L16toGry(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ int16* l16 = (int16*) sp->tbuf;
+ uint8* gp = (uint8*) op;
+
+ while (n-- > 0) {
+ double Y = LogL16toY(*l16++);
+ *gp++ = (uint8) ((Y <= 0.) ? 0 : (Y >= 1.) ? 255 : (int)(256.*sqrt(Y)));
+ }
+}
+
+static void
+L16fromY(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ int16* l16 = (int16*) sp->tbuf;
+ float* yp = (float*) op;
+
+ while (n-- > 0)
+ *l16++ = (int16) (LogL16fromY(*yp++, sp->encode_meth));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+void
+XYZtoRGB24(float xyz[3], uint8 rgb[3])
+{
+ double r, g, b;
+ /* assume CCIR-709 primaries */
+ r = 2.690*xyz[0] + -1.276*xyz[1] + -0.414*xyz[2];
+ g = -1.022*xyz[0] + 1.978*xyz[1] + 0.044*xyz[2];
+ b = 0.061*xyz[0] + -0.224*xyz[1] + 1.163*xyz[2];
+ /* assume 2.0 gamma for speed */
+ /* could use integer sqrt approx., but this is probably faster */
+ rgb[0] = (uint8)((r<=0.) ? 0 : (r >= 1.) ? 255 : (int)(256.*sqrt(r)));
+ rgb[1] = (uint8)((g<=0.) ? 0 : (g >= 1.) ? 255 : (int)(256.*sqrt(g)));
+ rgb[2] = (uint8)((b<=0.) ? 0 : (b >= 1.) ? 255 : (int)(256.*sqrt(b)));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+double
+LogL10toY(int p10) /* compute luminance from 10-bit LogL */
+{
+ if (p10 == 0)
+ return (0.);
+ return (exp(M_LN2/64.*(p10+.5) - M_LN2*12.));
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+LogL10fromY(double Y, int em) /* get 10-bit LogL from Y */
+{
+ if (Y >= 15.742)
+ return (0x3ff);
+ else if (Y <= .00024283)
+ return (0);
+ else
+ return itrunc(64.*(log2(Y) + 12.), em);
+}
+
+#define NANGLES 100
+#define uv2ang(u, v) ( (NANGLES*.499999999/M_PI) \
+ * atan2((v)-V_NEU,(u)-U_NEU) + .5*NANGLES )
+
+static int
+oog_encode(double u, double v) /* encode out-of-gamut chroma */
+{
+ static int oog_table[NANGLES];
+ static int initialized = 0;
+ register int i;
+
+ if (!initialized) { /* set up perimeter table */
+ double eps[NANGLES], ua, va, ang, epsa;
+ int ui, vi, ustep;
+ for (i = NANGLES; i--; )
+ eps[i] = 2.;
+ for (vi = UV_NVS; vi--; ) {
+ va = UV_VSTART + (vi+.5)*UV_SQSIZ;
+ ustep = uv_row[vi].nus-1;
+ if (vi == UV_NVS-1 || vi == 0 || ustep <= 0)
+ ustep = 1;
+ for (ui = uv_row[vi].nus-1; ui >= 0; ui -= ustep) {
+ ua = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
+ ang = uv2ang(ua, va);
+ i = (int) ang;
+ epsa = fabs(ang - (i+.5));
+ if (epsa < eps[i]) {
+ oog_table[i] = uv_row[vi].ncum + ui;
+ eps[i] = epsa;
+ }
+ }
+ }
+ for (i = NANGLES; i--; ) /* fill any holes */
+ if (eps[i] > 1.5) {
+ int i1, i2;
+ for (i1 = 1; i1 < NANGLES/2; i1++)
+ if (eps[(i+i1)%NANGLES] < 1.5)
+ break;
+ for (i2 = 1; i2 < NANGLES/2; i2++)
+ if (eps[(i+NANGLES-i2)%NANGLES] < 1.5)
+ break;
+ if (i1 < i2)
+ oog_table[i] =
+ oog_table[(i+i1)%NANGLES];
+ else
+ oog_table[i] =
+ oog_table[(i+NANGLES-i2)%NANGLES];
+ }
+ initialized = 1;
+ }
+ i = (int) uv2ang(u, v); /* look up hue angle */
+ return (oog_table[i]);
+}
+
+#undef uv2ang
+#undef NANGLES
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+uv_encode(double u, double v, int em) /* encode (u',v') coordinates */
+{
+ register int vi, ui;
+
+ if (v < UV_VSTART)
+ return oog_encode(u, v);
+ vi = itrunc((v - UV_VSTART)*(1./UV_SQSIZ), em);
+ if (vi >= UV_NVS)
+ return oog_encode(u, v);
+ if (u < uv_row[vi].ustart)
+ return oog_encode(u, v);
+ ui = itrunc((u - uv_row[vi].ustart)*(1./UV_SQSIZ), em);
+ if (ui >= uv_row[vi].nus)
+ return oog_encode(u, v);
+
+ return (uv_row[vi].ncum + ui);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+int
+uv_decode(double *up, double *vp, int c) /* decode (u',v') index */
+{
+ int upper, lower;
+ register int ui, vi;
+
+ if (c < 0 || c >= UV_NDIVS)
+ return (-1);
+ lower = 0; /* binary search */
+ upper = UV_NVS;
+ while (upper - lower > 1) {
+ vi = (lower + upper) >> 1;
+ ui = c - uv_row[vi].ncum;
+ if (ui > 0)
+ lower = vi;
+ else if (ui < 0)
+ upper = vi;
+ else {
+ lower = vi;
+ break;
+ }
+ }
+ vi = lower;
+ ui = c - uv_row[vi].ncum;
+ *up = uv_row[vi].ustart + (ui+.5)*UV_SQSIZ;
+ *vp = UV_VSTART + (vi+.5)*UV_SQSIZ;
+ return (0);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+void
+LogLuv24toXYZ(uint32 p, float XYZ[3])
+{
+ int Ce;
+ double L, u, v, s, x, y;
+ /* decode luminance */
+ L = LogL10toY(p>>14 & 0x3ff);
+ if (L <= 0.) {
+ XYZ[0] = XYZ[1] = XYZ[2] = 0.;
+ return;
+ }
+ /* decode color */
+ Ce = p & 0x3fff;
+ if (uv_decode(&u, &v, Ce) < 0) {
+ u = U_NEU; v = V_NEU;
+ }
+ s = 1./(6.*u - 16.*v + 12.);
+ x = 9.*u * s;
+ y = 4.*v * s;
+ /* convert to XYZ */
+ XYZ[0] = (float)(x/y * L);
+ XYZ[1] = (float)L;
+ XYZ[2] = (float)((1.-x-y)/y * L);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+uint32
+LogLuv24fromXYZ(float XYZ[3], int em)
+{
+ int Le, Ce;
+ double u, v, s;
+ /* encode luminance */
+ Le = LogL10fromY(XYZ[1], em);
+ /* encode color */
+ s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
+ if (!Le || s <= 0.) {
+ u = U_NEU;
+ v = V_NEU;
+ } else {
+ u = 4.*XYZ[0] / s;
+ v = 9.*XYZ[1] / s;
+ }
+ Ce = uv_encode(u, v, em);
+ if (Ce < 0) /* never happens */
+ Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
+ /* combine encodings */
+ return (Le << 14 | Ce);
+}
+
+static void
+Luv24toXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ float* xyz = (float*) op;
+
+ while (n-- > 0) {
+ LogLuv24toXYZ(*luv, xyz);
+ xyz += 3;
+ luv++;
+ }
+}
+
+static void
+Luv24toLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ int16* luv3 = (int16*) op;
+
+ while (n-- > 0) {
+ double u, v;
+
+ *luv3++ = (int16)((*luv >> 12 & 0xffd) + 13314);
+ if (uv_decode(&u, &v, *luv&0x3fff) < 0) {
+ u = U_NEU;
+ v = V_NEU;
+ }
+ *luv3++ = (int16)(u * (1L<<15));
+ *luv3++ = (int16)(v * (1L<<15));
+ luv++;
+ }
+}
+
+static void
+Luv24toRGB(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ uint8* rgb = (uint8*) op;
+
+ while (n-- > 0) {
+ float xyz[3];
+
+ LogLuv24toXYZ(*luv++, xyz);
+ XYZtoRGB24(xyz, rgb);
+ rgb += 3;
+ }
+}
+
+static void
+Luv24fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ float* xyz = (float*) op;
+
+ while (n-- > 0) {
+ *luv++ = LogLuv24fromXYZ(xyz, sp->encode_meth);
+ xyz += 3;
+ }
+}
+
+static void
+Luv24fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ int16* luv3 = (int16*) op;
+
+ while (n-- > 0) {
+ int Le, Ce;
+
+ if (luv3[0] <= 0)
+ Le = 0;
+ else if (luv3[0] >= (1<<12)+3314)
+ Le = (1<<10) - 1;
+ else if (sp->encode_meth == SGILOGENCODE_NODITHER)
+ Le = (luv3[0]-3314) >> 2;
+ else
+ Le = itrunc(.25*(luv3[0]-3314.), sp->encode_meth);
+
+ Ce = uv_encode((luv3[1]+.5)/(1<<15), (luv3[2]+.5)/(1<<15),
+ sp->encode_meth);
+ if (Ce < 0) /* never happens */
+ Ce = uv_encode(U_NEU, V_NEU, SGILOGENCODE_NODITHER);
+ *luv++ = (uint32)Le << 14 | Ce;
+ luv3 += 3;
+ }
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+void
+LogLuv32toXYZ(uint32 p, float XYZ[3])
+{
+ double L, u, v, s, x, y;
+ /* decode luminance */
+ L = LogL16toY((int)p >> 16);
+ if (L <= 0.) {
+ XYZ[0] = XYZ[1] = XYZ[2] = 0.;
+ return;
+ }
+ /* decode color */
+ u = 1./UVSCALE * ((p>>8 & 0xff) + .5);
+ v = 1./UVSCALE * ((p & 0xff) + .5);
+ s = 1./(6.*u - 16.*v + 12.);
+ x = 9.*u * s;
+ y = 4.*v * s;
+ /* convert to XYZ */
+ XYZ[0] = (float)(x/y * L);
+ XYZ[1] = (float)L;
+ XYZ[2] = (float)((1.-x-y)/y * L);
+}
+
+#if !LOGLUV_PUBLIC
+static
+#endif
+uint32
+LogLuv32fromXYZ(float XYZ[3], int em)
+{
+ unsigned int Le, ue, ve;
+ double u, v, s;
+ /* encode luminance */
+ Le = (unsigned int)LogL16fromY(XYZ[1], em);
+ /* encode color */
+ s = XYZ[0] + 15.*XYZ[1] + 3.*XYZ[2];
+ if (!Le || s <= 0.) {
+ u = U_NEU;
+ v = V_NEU;
+ } else {
+ u = 4.*XYZ[0] / s;
+ v = 9.*XYZ[1] / s;
+ }
+ if (u <= 0.) ue = 0;
+ else ue = itrunc(UVSCALE*u, em);
+ if (ue > 255) ue = 255;
+ if (v <= 0.) ve = 0;
+ else ve = itrunc(UVSCALE*v, em);
+ if (ve > 255) ve = 255;
+ /* combine encodings */
+ return (Le << 16 | ue << 8 | ve);
+}
+
+static void
+Luv32toXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ float* xyz = (float*) op;
+
+ while (n-- > 0) {
+ LogLuv32toXYZ(*luv++, xyz);
+ xyz += 3;
+ }
+}
+
+static void
+Luv32toLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ int16* luv3 = (int16*) op;
+
+ while (n-- > 0) {
+ double u, v;
+
+ *luv3++ = (int16)(*luv >> 16);
+ u = 1./UVSCALE * ((*luv>>8 & 0xff) + .5);
+ v = 1./UVSCALE * ((*luv & 0xff) + .5);
+ *luv3++ = (int16)(u * (1L<<15));
+ *luv3++ = (int16)(v * (1L<<15));
+ luv++;
+ }
+}
+
+static void
+Luv32toRGB(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ uint8* rgb = (uint8*) op;
+
+ while (n-- > 0) {
+ float xyz[3];
+
+ LogLuv32toXYZ(*luv++, xyz);
+ XYZtoRGB24(xyz, rgb);
+ rgb += 3;
+ }
+}
+
+static void
+Luv32fromXYZ(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ float* xyz = (float*) op;
+
+ while (n-- > 0) {
+ *luv++ = LogLuv32fromXYZ(xyz, sp->encode_meth);
+ xyz += 3;
+ }
+}
+
+static void
+Luv32fromLuv48(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ uint32* luv = (uint32*) sp->tbuf;
+ int16* luv3 = (int16*) op;
+
+ if (sp->encode_meth == SGILOGENCODE_NODITHER) {
+ while (n-- > 0) {
+ *luv++ = (uint32)luv3[0] << 16 |
+ (luv3[1]*(uint32)(UVSCALE+.5) >> 7 & 0xff00) |
+ (luv3[2]*(uint32)(UVSCALE+.5) >> 15 & 0xff);
+ luv3 += 3;
+ }
+ return;
+ }
+ while (n-- > 0) {
+ *luv++ = (uint32)luv3[0] << 16 |
+ (itrunc(luv3[1]*(UVSCALE/(1<<15)), sp->encode_meth) << 8 & 0xff00) |
+ (itrunc(luv3[2]*(UVSCALE/(1<<15)), sp->encode_meth) & 0xff);
+ luv3 += 3;
+ }
+}
+
+static void
+_logLuvNop(LogLuvState* sp, uint8* op, tmsize_t n)
+{
+ (void) sp; (void) op; (void) n;
+}
+
+static int
+LogL16GuessDataFmt(TIFFDirectory *td)
+{
+#define PACK(s,b,f) (((b)<<6)|((s)<<3)|(f))
+ switch (PACK(td->td_samplesperpixel, td->td_bitspersample, td->td_sampleformat)) {
+ case PACK(1, 32, SAMPLEFORMAT_IEEEFP):
+ return (SGILOGDATAFMT_FLOAT);
+ case PACK(1, 16, SAMPLEFORMAT_VOID):
+ case PACK(1, 16, SAMPLEFORMAT_INT):
+ case PACK(1, 16, SAMPLEFORMAT_UINT):
+ return (SGILOGDATAFMT_16BIT);
+ case PACK(1, 8, SAMPLEFORMAT_VOID):
+ case PACK(1, 8, SAMPLEFORMAT_UINT):
+ return (SGILOGDATAFMT_8BIT);
+ }
+#undef PACK
+ return (SGILOGDATAFMT_UNKNOWN);
+}
+
+static tmsize_t
+multiply_ms(tmsize_t m1, tmsize_t m2)
+{
+ tmsize_t bytes = m1 * m2;
+
+ if (m1 && bytes / m1 != m2)
+ bytes = 0;
+
+ return bytes;
+}
+
+static int
+LogL16InitState(TIFF* tif)
+{
+ static const char module[] = "LogL16InitState";
+ TIFFDirectory *td = &tif->tif_dir;
+ LogLuvState* sp = DecoderState(tif);
+
+ assert(sp != NULL);
+ assert(td->td_photometric == PHOTOMETRIC_LOGL);
+
+ /* for some reason, we can't do this in TIFFInitLogL16 */
+ if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = LogL16GuessDataFmt(td);
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->pixel_size = sizeof (float);
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->pixel_size = sizeof (int16);
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->pixel_size = sizeof (uint8);
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No support for converting user data format to LogL");
+ return (0);
+ }
+ if( isTiled(tif) )
+ sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
+ else
+ sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+ if (multiply_ms(sp->tbuflen, sizeof (int16)) == 0 ||
+ (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (int16))) == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
+ return (0);
+ }
+ return (1);
+}
+
+static int
+LogLuvGuessDataFmt(TIFFDirectory *td)
+{
+ int guess;
+
+ /*
+ * If the user didn't tell us their datafmt,
+ * take our best guess from the bitspersample.
+ */
+#define PACK(a,b) (((a)<<3)|(b))
+ switch (PACK(td->td_bitspersample, td->td_sampleformat)) {
+ case PACK(32, SAMPLEFORMAT_IEEEFP):
+ guess = SGILOGDATAFMT_FLOAT;
+ break;
+ case PACK(32, SAMPLEFORMAT_VOID):
+ case PACK(32, SAMPLEFORMAT_UINT):
+ case PACK(32, SAMPLEFORMAT_INT):
+ guess = SGILOGDATAFMT_RAW;
+ break;
+ case PACK(16, SAMPLEFORMAT_VOID):
+ case PACK(16, SAMPLEFORMAT_INT):
+ case PACK(16, SAMPLEFORMAT_UINT):
+ guess = SGILOGDATAFMT_16BIT;
+ break;
+ case PACK( 8, SAMPLEFORMAT_VOID):
+ case PACK( 8, SAMPLEFORMAT_UINT):
+ guess = SGILOGDATAFMT_8BIT;
+ break;
+ default:
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+#undef PACK
+ }
+ /*
+ * Double-check samples per pixel.
+ */
+ switch (td->td_samplesperpixel) {
+ case 1:
+ if (guess != SGILOGDATAFMT_RAW)
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+ case 3:
+ if (guess == SGILOGDATAFMT_RAW)
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+ default:
+ guess = SGILOGDATAFMT_UNKNOWN;
+ break;
+ }
+ return (guess);
+}
+
+static int
+LogLuvInitState(TIFF* tif)
+{
+ static const char module[] = "LogLuvInitState";
+ TIFFDirectory* td = &tif->tif_dir;
+ LogLuvState* sp = DecoderState(tif);
+
+ assert(sp != NULL);
+ assert(td->td_photometric == PHOTOMETRIC_LOGLUV);
+
+ /* for some reason, we can't do this in TIFFInitLogLuv */
+ if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "SGILog compression cannot handle non-contiguous data");
+ return (0);
+ }
+ if (sp->user_datafmt == SGILOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = LogLuvGuessDataFmt(td);
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->pixel_size = 3*sizeof (float);
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->pixel_size = 3*sizeof (int16);
+ break;
+ case SGILOGDATAFMT_RAW:
+ sp->pixel_size = sizeof (uint32);
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->pixel_size = 3*sizeof (uint8);
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No support for converting user data format to LogLuv");
+ return (0);
+ }
+ if( isTiled(tif) )
+ sp->tbuflen = multiply_ms(td->td_tilewidth, td->td_tilelength);
+ else
+ sp->tbuflen = multiply_ms(td->td_imagewidth, td->td_rowsperstrip);
+ if (multiply_ms(sp->tbuflen, sizeof (uint32)) == 0 ||
+ (sp->tbuf = (uint8*) _TIFFmalloc(sp->tbuflen * sizeof (uint32))) == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module, "No space for SGILog translation buffer");
+ return (0);
+ }
+ return (1);
+}
+
+static int
+LogLuvFixupTags(TIFF* tif)
+{
+ (void) tif;
+ return (1);
+}
+
+static int
+LogLuvSetupDecode(TIFF* tif)
+{
+ static const char module[] = "LogLuvSetupDecode";
+ LogLuvState* sp = DecoderState(tif);
+ TIFFDirectory* td = &tif->tif_dir;
+
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ switch (td->td_photometric) {
+ case PHOTOMETRIC_LOGLUV:
+ if (!LogLuvInitState(tif))
+ break;
+ if (td->td_compression == COMPRESSION_SGILOG24) {
+ tif->tif_decoderow = LogLuvDecode24;
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv24toXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv24toLuv48;
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->tfunc = Luv24toRGB;
+ break;
+ }
+ } else {
+ tif->tif_decoderow = LogLuvDecode32;
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv32toXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv32toLuv48;
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->tfunc = Luv32toRGB;
+ break;
+ }
+ }
+ return (1);
+ case PHOTOMETRIC_LOGL:
+ if (!LogL16InitState(tif))
+ break;
+ tif->tif_decoderow = LogL16Decode;
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = L16toY;
+ break;
+ case SGILOGDATAFMT_8BIT:
+ sp->tfunc = L16toGry;
+ break;
+ }
+ return (1);
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Inappropriate photometric interpretation %d for SGILog compression; %s",
+ td->td_photometric, "must be either LogLUV or LogL");
+ break;
+ }
+ return (0);
+}
+
+static int
+LogLuvSetupEncode(TIFF* tif)
+{
+ static const char module[] = "LogLuvSetupEncode";
+ LogLuvState* sp = EncoderState(tif);
+ TIFFDirectory* td = &tif->tif_dir;
+
+ switch (td->td_photometric) {
+ case PHOTOMETRIC_LOGLUV:
+ if (!LogLuvInitState(tif))
+ break;
+ if (td->td_compression == COMPRESSION_SGILOG24) {
+ tif->tif_encoderow = LogLuvEncode24;
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv24fromXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv24fromLuv48;
+ break;
+ case SGILOGDATAFMT_RAW:
+ break;
+ default:
+ goto notsupported;
+ }
+ } else {
+ tif->tif_encoderow = LogLuvEncode32;
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = Luv32fromXYZ;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ sp->tfunc = Luv32fromLuv48;
+ break;
+ case SGILOGDATAFMT_RAW:
+ break;
+ default:
+ goto notsupported;
+ }
+ }
+ break;
+ case PHOTOMETRIC_LOGL:
+ if (!LogL16InitState(tif))
+ break;
+ tif->tif_encoderow = LogL16Encode;
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ sp->tfunc = L16fromY;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ break;
+ default:
+ goto notsupported;
+ }
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Inappropriate photometric interpretation %d for SGILog compression; %s",
+ td->td_photometric, "must be either LogLUV or LogL");
+ break;
+ }
+ return (1);
+notsupported:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "SGILog compression supported only for %s, or raw data",
+ td->td_photometric == PHOTOMETRIC_LOGL ? "Y, L" : "XYZ, Luv");
+ return (0);
+}
+
+static void
+LogLuvClose(TIFF* tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ /*
+ * For consistency, we always want to write out the same
+ * bitspersample and sampleformat for our TIFF file,
+ * regardless of the data format being used by the application.
+ * Since this routine is called after tags have been set but
+ * before they have been recorded in the file, we reset them here.
+ */
+ td->td_samplesperpixel =
+ (td->td_photometric == PHOTOMETRIC_LOGL) ? 1 : 3;
+ td->td_bitspersample = 16;
+ td->td_sampleformat = SAMPLEFORMAT_INT;
+}
+
+static void
+LogLuvCleanup(TIFF* tif)
+{
+ LogLuvState* sp = (LogLuvState *)tif->tif_data;
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->tbuf)
+ _TIFFfree(sp->tbuf);
+ _TIFFfree(sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int
+LogLuvVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ static const char module[] = "LogLuvVSetField";
+ LogLuvState* sp = DecoderState(tif);
+ int bps, fmt;
+
+ switch (tag) {
+ case TIFFTAG_SGILOGDATAFMT:
+ sp->user_datafmt = (int) va_arg(ap, int);
+ /*
+ * Tweak the TIFF header so that the rest of libtiff knows what
+ * size of data will be passed between app and library, and
+ * assume that the app knows what it is doing and is not
+ * confused by these header manipulations...
+ */
+ switch (sp->user_datafmt) {
+ case SGILOGDATAFMT_FLOAT:
+ bps = 32, fmt = SAMPLEFORMAT_IEEEFP;
+ break;
+ case SGILOGDATAFMT_16BIT:
+ bps = 16, fmt = SAMPLEFORMAT_INT;
+ break;
+ case SGILOGDATAFMT_RAW:
+ bps = 32, fmt = SAMPLEFORMAT_UINT;
+ TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
+ break;
+ case SGILOGDATAFMT_8BIT:
+ bps = 8, fmt = SAMPLEFORMAT_UINT;
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "Unknown data format %d for LogLuv compression",
+ sp->user_datafmt);
+ return (0);
+ }
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, fmt);
+ /*
+ * Must recalculate sizes should bits/sample change.
+ */
+ tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t) -1;
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ return (1);
+ case TIFFTAG_SGILOGENCODE:
+ sp->encode_meth = (int) va_arg(ap, int);
+ if (sp->encode_meth != SGILOGENCODE_NODITHER &&
+ sp->encode_meth != SGILOGENCODE_RANDITHER) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Unknown encoding %d for LogLuv compression",
+ sp->encode_meth);
+ return (0);
+ }
+ return (1);
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+}
+
+static int
+LogLuvVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ LogLuvState *sp = (LogLuvState *)tif->tif_data;
+
+ switch (tag) {
+ case TIFFTAG_SGILOGDATAFMT:
+ *va_arg(ap, int*) = sp->user_datafmt;
+ return (1);
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+}
+
+static const TIFFField LogLuvFields[] = {
+ { TIFFTAG_SGILOGDATAFMT, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogDataFmt", NULL},
+ { TIFFTAG_SGILOGENCODE, 0, 0, TIFF_SHORT, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "SGILogEncode", NULL}
+};
+
+int
+TIFFInitSGILog(TIFF* tif, int scheme)
+{
+ static const char module[] = "TIFFInitSGILog";
+ LogLuvState* sp;
+
+ assert(scheme == COMPRESSION_SGILOG24 || scheme == COMPRESSION_SGILOG);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, LogLuvFields,
+ TIFFArrayCount(LogLuvFields))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Merging SGILog codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LogLuvState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = (LogLuvState*) tif->tif_data;
+ _TIFFmemset((void*)sp, 0, sizeof (*sp));
+ sp->user_datafmt = SGILOGDATAFMT_UNKNOWN;
+ sp->encode_meth = (scheme == COMPRESSION_SGILOG24) ?
+ SGILOGENCODE_RANDITHER : SGILOGENCODE_NODITHER;
+ sp->tfunc = _logLuvNop;
+
+ /*
+ * Install codec methods.
+ * NB: tif_decoderow & tif_encoderow are filled
+ * in at setup time.
+ */
+ tif->tif_fixuptags = LogLuvFixupTags;
+ tif->tif_setupdecode = LogLuvSetupDecode;
+ tif->tif_decodestrip = LogLuvDecodeStrip;
+ tif->tif_decodetile = LogLuvDecodeTile;
+ tif->tif_setupencode = LogLuvSetupEncode;
+ tif->tif_encodestrip = LogLuvEncodeStrip;
+ tif->tif_encodetile = LogLuvEncodeTile;
+ tif->tif_close = LogLuvClose;
+ tif->tif_cleanup = LogLuvCleanup;
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = LogLuvVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = LogLuvVSetField; /* hook for codec tags */
+
+ return (1);
+bad:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s: No space for LogLuv state block", tif->tif_name);
+ return (0);
+}
+#endif /* LOGLUV_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_lzw.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_lzw.c
new file mode 100644
index 0000000000..5c9ab0bf74
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_lzw.c
@@ -0,0 +1,1169 @@
+/* $Id: tif_lzw.c,v 1.45 2011-04-02 20:54:09 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#ifdef LZW_SUPPORT
+/*
+ * TIFF Library.
+ * Rev 5.0 Lempel-Ziv & Welch Compression Support
+ *
+ * This code is derived from the compress program whose code is
+ * derived from software contributed to Berkeley by James A. Woods,
+ * derived from original work by Spencer Thomas and Joseph Orost.
+ *
+ * The original Berkeley copyright notice appears below in its entirety.
+ */
+#include "tif_predict.h"
+
+#include <stdio.h>
+
+/*
+ * NB: The 5.0 spec describes a different algorithm than Aldus
+ * implements. Specifically, Aldus does code length transitions
+ * one code earlier than should be done (for real LZW).
+ * Earlier versions of this library implemented the correct
+ * LZW algorithm, but emitted codes in a bit order opposite
+ * to the TIFF spec. Thus, to maintain compatibility w/ Aldus
+ * we interpret MSB-LSB ordered codes to be images written w/
+ * old versions of this library, but otherwise adhere to the
+ * Aldus "off by one" algorithm.
+ *
+ * Future revisions to the TIFF spec are expected to "clarify this issue".
+ */
+#define LZW_COMPAT /* include backwards compatibility code */
+/*
+ * Each strip of data is supposed to be terminated by a CODE_EOI.
+ * If the following #define is included, the decoder will also
+ * check for end-of-strip w/o seeing this code. This makes the
+ * library more robust, but also slower.
+ */
+#define LZW_CHECKEOS /* include checks for strips w/o EOI code */
+
+#define MAXCODE(n) ((1L<<(n))-1)
+/*
+ * The TIFF spec specifies that encoded bit
+ * strings range from 9 to 12 bits.
+ */
+#define BITS_MIN 9 /* start with 9 bits */
+#define BITS_MAX 12 /* max of 12 bit strings */
+/* predefined codes */
+#define CODE_CLEAR 256 /* code to clear string table */
+#define CODE_EOI 257 /* end-of-information code */
+#define CODE_FIRST 258 /* first free code entry */
+#define CODE_MAX MAXCODE(BITS_MAX)
+#define HSIZE 9001L /* 91% occupancy */
+#define HSHIFT (13-8)
+#ifdef LZW_COMPAT
+/* NB: +1024 is for compatibility with old files */
+#define CSIZE (MAXCODE(BITS_MAX)+1024L)
+#else
+#define CSIZE (MAXCODE(BITS_MAX)+1L)
+#endif
+
+/*
+ * State block for each open TIFF file using LZW
+ * compression/decompression. Note that the predictor
+ * state block must be first in this data structure.
+ */
+typedef struct {
+ TIFFPredictorState predict; /* predictor super class */
+
+ unsigned short nbits; /* # of bits/code */
+ unsigned short maxcode; /* maximum code for lzw_nbits */
+ unsigned short free_ent; /* next free entry in hash table */
+ long nextdata; /* next bits of i/o */
+ long nextbits; /* # of valid bits in lzw_nextdata */
+
+ int rw_mode; /* preserve rw_mode from init */
+} LZWBaseState;
+
+#define lzw_nbits base.nbits
+#define lzw_maxcode base.maxcode
+#define lzw_free_ent base.free_ent
+#define lzw_nextdata base.nextdata
+#define lzw_nextbits base.nextbits
+
+/*
+ * Encoding-specific state.
+ */
+typedef uint16 hcode_t; /* codes fit in 16 bits */
+typedef struct {
+ long hash;
+ hcode_t code;
+} hash_t;
+
+/*
+ * Decoding-specific state.
+ */
+typedef struct code_ent {
+ struct code_ent *next;
+ unsigned short length; /* string len, including this token */
+ unsigned char value; /* data value */
+ unsigned char firstchar; /* first token of string */
+} code_t;
+
+typedef int (*decodeFunc)(TIFF*, uint8*, tmsize_t, uint16);
+
+typedef struct {
+ LZWBaseState base;
+
+ /* Decoding specific data */
+ long dec_nbitsmask; /* lzw_nbits 1 bits, right adjusted */
+ long dec_restart; /* restart count */
+#ifdef LZW_CHECKEOS
+ uint64 dec_bitsleft; /* available bits in raw data */
+#endif
+ decodeFunc dec_decode; /* regular or backwards compatible */
+ code_t* dec_codep; /* current recognized code */
+ code_t* dec_oldcodep; /* previously recognized code */
+ code_t* dec_free_entp; /* next free entry */
+ code_t* dec_maxcodep; /* max available entry */
+ code_t* dec_codetab; /* kept separate for small machines */
+
+ /* Encoding specific data */
+ int enc_oldcode; /* last code encountered */
+ long enc_checkpoint; /* point at which to clear table */
+#define CHECK_GAP 10000 /* enc_ratio check interval */
+ long enc_ratio; /* current compression ratio */
+ long enc_incount; /* (input) data bytes encoded */
+ long enc_outcount; /* encoded (output) bytes */
+ uint8* enc_rawlimit; /* bound on tif_rawdata buffer */
+ hash_t* enc_hashtab; /* kept separate for small machines */
+} LZWCodecState;
+
+#define LZWState(tif) ((LZWBaseState*) (tif)->tif_data)
+#define DecoderState(tif) ((LZWCodecState*) LZWState(tif))
+#define EncoderState(tif) ((LZWCodecState*) LZWState(tif))
+
+static int LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+#ifdef LZW_COMPAT
+static int LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+#endif
+static void cl_hash(LZWCodecState*);
+
+/*
+ * LZW Decoder.
+ */
+
+#ifdef LZW_CHECKEOS
+/*
+ * This check shouldn't be necessary because each
+ * strip is suppose to be terminated with CODE_EOI.
+ */
+#define NextCode(_tif, _sp, _bp, _code, _get) { \
+ if ((_sp)->dec_bitsleft < (uint64)nbits) { \
+ TIFFWarningExt(_tif->tif_clientdata, module, \
+ "LZWDecode: Strip %d not terminated with EOI code", \
+ _tif->tif_curstrip); \
+ _code = CODE_EOI; \
+ } else { \
+ _get(_sp,_bp,_code); \
+ (_sp)->dec_bitsleft -= nbits; \
+ } \
+}
+#else
+#define NextCode(tif, sp, bp, code, get) get(sp, bp, code)
+#endif
+
+static int
+LZWFixupTags(TIFF* tif)
+{
+ (void) tif;
+ return (1);
+}
+
+static int
+LZWSetupDecode(TIFF* tif)
+{
+ static const char module[] = "LZWSetupDecode";
+ LZWCodecState* sp = DecoderState(tif);
+ int code;
+
+ if( sp == NULL )
+ {
+ /*
+ * Allocate state block so tag methods have storage to record
+ * values.
+ */
+ tif->tif_data = (uint8*) _TIFFmalloc(sizeof(LZWCodecState));
+ if (tif->tif_data == NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "No space for LZW state block");
+ return (0);
+ }
+
+ DecoderState(tif)->dec_codetab = NULL;
+ DecoderState(tif)->dec_decode = NULL;
+
+ /*
+ * Setup predictor setup.
+ */
+ (void) TIFFPredictorInit(tif);
+
+ sp = DecoderState(tif);
+ }
+
+ assert(sp != NULL);
+
+ if (sp->dec_codetab == NULL) {
+ sp->dec_codetab = (code_t*)_TIFFmalloc(CSIZE*sizeof (code_t));
+ if (sp->dec_codetab == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for LZW code table");
+ return (0);
+ }
+ /*
+ * Pre-load the table.
+ */
+ code = 255;
+ do {
+ sp->dec_codetab[code].value = code;
+ sp->dec_codetab[code].firstchar = code;
+ sp->dec_codetab[code].length = 1;
+ sp->dec_codetab[code].next = NULL;
+ } while (code--);
+ /*
+ * Zero-out the unused entries
+ */
+ _TIFFmemset(&sp->dec_codetab[CODE_CLEAR], 0,
+ (CODE_FIRST - CODE_CLEAR) * sizeof (code_t));
+ }
+ return (1);
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+LZWPreDecode(TIFF* tif, uint16 s)
+{
+ static const char module[] = "LZWPreDecode";
+ LZWCodecState *sp = DecoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+ if( sp->dec_codetab == NULL )
+ {
+ tif->tif_setupdecode( tif );
+ }
+
+ /*
+ * Check for old bit-reversed codes.
+ */
+ if (tif->tif_rawdata[0] == 0 && (tif->tif_rawdata[1] & 0x1)) {
+#ifdef LZW_COMPAT
+ if (!sp->dec_decode) {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Old-style LZW codes, convert file");
+ /*
+ * Override default decoding methods with
+ * ones that deal with the old coding.
+ * Otherwise the predictor versions set
+ * above will call the compatibility routines
+ * through the dec_decode method.
+ */
+ tif->tif_decoderow = LZWDecodeCompat;
+ tif->tif_decodestrip = LZWDecodeCompat;
+ tif->tif_decodetile = LZWDecodeCompat;
+ /*
+ * If doing horizontal differencing, must
+ * re-setup the predictor logic since we
+ * switched the basic decoder methods...
+ */
+ (*tif->tif_setupdecode)(tif);
+ sp->dec_decode = LZWDecodeCompat;
+ }
+ sp->lzw_maxcode = MAXCODE(BITS_MIN);
+#else /* !LZW_COMPAT */
+ if (!sp->dec_decode) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Old-style LZW codes not supported");
+ sp->dec_decode = LZWDecode;
+ }
+ return (0);
+#endif/* !LZW_COMPAT */
+ } else {
+ sp->lzw_maxcode = MAXCODE(BITS_MIN)-1;
+ sp->dec_decode = LZWDecode;
+ }
+ sp->lzw_nbits = BITS_MIN;
+ sp->lzw_nextbits = 0;
+ sp->lzw_nextdata = 0;
+
+ sp->dec_restart = 0;
+ sp->dec_nbitsmask = MAXCODE(BITS_MIN);
+#ifdef LZW_CHECKEOS
+ sp->dec_bitsleft = ((uint64)tif->tif_rawcc) << 3;
+#endif
+ sp->dec_free_entp = sp->dec_codetab + CODE_FIRST;
+ /*
+ * Zero entries that are not yet filled in. We do
+ * this to guard against bogus input data that causes
+ * us to index into undefined entries. If you can
+ * come up with a way to safely bounds-check input codes
+ * while decoding then you can remove this operation.
+ */
+ _TIFFmemset(sp->dec_free_entp, 0, (CSIZE-CODE_FIRST)*sizeof (code_t));
+ sp->dec_oldcodep = &sp->dec_codetab[-1];
+ sp->dec_maxcodep = &sp->dec_codetab[sp->dec_nbitsmask-1];
+ return (1);
+}
+
+/*
+ * Decode a "hunk of data".
+ */
+#define GetNextCode(sp, bp, code) { \
+ nextdata = (nextdata<<8) | *(bp)++; \
+ nextbits += 8; \
+ if (nextbits < nbits) { \
+ nextdata = (nextdata<<8) | *(bp)++; \
+ nextbits += 8; \
+ } \
+ code = (hcode_t)((nextdata >> (nextbits-nbits)) & nbitsmask); \
+ nextbits -= nbits; \
+}
+
+static void
+codeLoop(TIFF* tif, const char* module)
+{
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Bogus encoding, loop in the code table; scanline %d",
+ tif->tif_row);
+}
+
+static int
+LZWDecode(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+ static const char module[] = "LZWDecode";
+ LZWCodecState *sp = DecoderState(tif);
+ char *op = (char*) op0;
+ long occ = (long) occ0;
+ char *tp;
+ unsigned char *bp;
+ hcode_t code;
+ int len;
+ long nbits, nextbits, nextdata, nbitsmask;
+ code_t *codep, *free_entp, *maxcodep, *oldcodep;
+
+ (void) s;
+ assert(sp != NULL);
+ assert(sp->dec_codetab != NULL);
+
+ /*
+ Fail if value does not fit in long.
+ */
+ if ((tmsize_t) occ != occ0)
+ return (0);
+ /*
+ * Restart interrupted output operation.
+ */
+ if (sp->dec_restart) {
+ long residue;
+
+ codep = sp->dec_codep;
+ residue = codep->length - sp->dec_restart;
+ if (residue > occ) {
+ /*
+ * Residue from previous decode is sufficient
+ * to satisfy decode request. Skip to the
+ * start of the decoded string, place decoded
+ * values in the output buffer, and return.
+ */
+ sp->dec_restart += occ;
+ do {
+ codep = codep->next;
+ } while (--residue > occ && codep);
+ if (codep) {
+ tp = op + occ;
+ do {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--occ && codep);
+ }
+ return (1);
+ }
+ /*
+ * Residue satisfies only part of the decode request.
+ */
+ op += residue, occ -= residue;
+ tp = op;
+ do {
+ int t;
+ --tp;
+ t = codep->value;
+ codep = codep->next;
+ *tp = t;
+ } while (--residue && codep);
+ sp->dec_restart = 0;
+ }
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ nbits = sp->lzw_nbits;
+ nextdata = sp->lzw_nextdata;
+ nextbits = sp->lzw_nextbits;
+ nbitsmask = sp->dec_nbitsmask;
+ oldcodep = sp->dec_oldcodep;
+ free_entp = sp->dec_free_entp;
+ maxcodep = sp->dec_maxcodep;
+
+ while (occ > 0) {
+ NextCode(tif, sp, bp, code, GetNextCode);
+ if (code == CODE_EOI)
+ break;
+ if (code == CODE_CLEAR) {
+ free_entp = sp->dec_codetab + CODE_FIRST;
+ _TIFFmemset(free_entp, 0,
+ (CSIZE - CODE_FIRST) * sizeof (code_t));
+ nbits = BITS_MIN;
+ nbitsmask = MAXCODE(BITS_MIN);
+ maxcodep = sp->dec_codetab + nbitsmask-1;
+ NextCode(tif, sp, bp, code, GetNextCode);
+ if (code == CODE_EOI)
+ break;
+ if (code >= CODE_CLEAR) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "LZWDecode: Corrupted LZW table at scanline %d",
+ tif->tif_row);
+ return (0);
+ }
+ *op++ = (char)code, occ--;
+ oldcodep = sp->dec_codetab + code;
+ continue;
+ }
+ codep = sp->dec_codetab + code;
+
+ /*
+ * Add the new entry to the code table.
+ */
+ if (free_entp < &sp->dec_codetab[0] ||
+ free_entp >= &sp->dec_codetab[CSIZE]) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Corrupted LZW table at scanline %d",
+ tif->tif_row);
+ return (0);
+ }
+
+ free_entp->next = oldcodep;
+ if (free_entp->next < &sp->dec_codetab[0] ||
+ free_entp->next >= &sp->dec_codetab[CSIZE]) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Corrupted LZW table at scanline %d",
+ tif->tif_row);
+ return (0);
+ }
+ free_entp->firstchar = free_entp->next->firstchar;
+ free_entp->length = free_entp->next->length+1;
+ free_entp->value = (codep < free_entp) ?
+ codep->firstchar : free_entp->firstchar;
+ if (++free_entp > maxcodep) {
+ if (++nbits > BITS_MAX) /* should not happen */
+ nbits = BITS_MAX;
+ nbitsmask = MAXCODE(nbits);
+ maxcodep = sp->dec_codetab + nbitsmask-1;
+ }
+ oldcodep = codep;
+ if (code >= 256) {
+ /*
+ * Code maps to a string, copy string
+ * value to output (written in reverse).
+ */
+ if(codep->length == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Wrong length of decoded string: "
+ "data probably corrupted at scanline %d",
+ tif->tif_row);
+ return (0);
+ }
+ if (codep->length > occ) {
+ /*
+ * String is too long for decode buffer,
+ * locate portion that will fit, copy to
+ * the decode buffer, and setup restart
+ * logic for the next decoding call.
+ */
+ sp->dec_codep = codep;
+ do {
+ codep = codep->next;
+ } while (codep && codep->length > occ);
+ if (codep) {
+ sp->dec_restart = (long)occ;
+ tp = op + occ;
+ do {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--occ && codep);
+ if (codep)
+ codeLoop(tif, module);
+ }
+ break;
+ }
+ len = codep->length;
+ tp = op + len;
+ do {
+ int t;
+ --tp;
+ t = codep->value;
+ codep = codep->next;
+ *tp = t;
+ } while (codep && tp > op);
+ if (codep) {
+ codeLoop(tif, module);
+ break;
+ }
+ assert(occ >= len);
+ op += len, occ -= len;
+ } else
+ *op++ = (char)code, occ--;
+ }
+
+ tif->tif_rawcp = (uint8*) bp;
+ sp->lzw_nbits = (unsigned short) nbits;
+ sp->lzw_nextdata = nextdata;
+ sp->lzw_nextbits = nextbits;
+ sp->dec_nbitsmask = nbitsmask;
+ sp->dec_oldcodep = oldcodep;
+ sp->dec_free_entp = free_entp;
+ sp->dec_maxcodep = maxcodep;
+
+ if (occ > 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at scanline %d (short %I64d bytes)",
+ tif->tif_row, (unsigned __int64) occ);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at scanline %d (short %llu bytes)",
+ tif->tif_row, (unsigned long long) occ);
+#endif
+ return (0);
+ }
+ return (1);
+}
+
+#ifdef LZW_COMPAT
+/*
+ * Decode a "hunk of data" for old images.
+ */
+#define GetNextCodeCompat(sp, bp, code) { \
+ nextdata |= (unsigned long) *(bp)++ << nextbits; \
+ nextbits += 8; \
+ if (nextbits < nbits) { \
+ nextdata |= (unsigned long) *(bp)++ << nextbits;\
+ nextbits += 8; \
+ } \
+ code = (hcode_t)(nextdata & nbitsmask); \
+ nextdata >>= nbits; \
+ nextbits -= nbits; \
+}
+
+static int
+LZWDecodeCompat(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+ static const char module[] = "LZWDecodeCompat";
+ LZWCodecState *sp = DecoderState(tif);
+ char *op = (char*) op0;
+ long occ = (long) occ0;
+ char *tp;
+ unsigned char *bp;
+ int code, nbits;
+ long nextbits, nextdata, nbitsmask;
+ code_t *codep, *free_entp, *maxcodep, *oldcodep;
+
+ (void) s;
+ assert(sp != NULL);
+
+ /*
+ Fail if value does not fit in long.
+ */
+ if ((tmsize_t) occ != occ0)
+ return (0);
+
+ /*
+ * Restart interrupted output operation.
+ */
+ if (sp->dec_restart) {
+ long residue;
+
+ codep = sp->dec_codep;
+ residue = codep->length - sp->dec_restart;
+ if (residue > occ) {
+ /*
+ * Residue from previous decode is sufficient
+ * to satisfy decode request. Skip to the
+ * start of the decoded string, place decoded
+ * values in the output buffer, and return.
+ */
+ sp->dec_restart += occ;
+ do {
+ codep = codep->next;
+ } while (--residue > occ);
+ tp = op + occ;
+ do {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--occ);
+ return (1);
+ }
+ /*
+ * Residue satisfies only part of the decode request.
+ */
+ op += residue, occ -= residue;
+ tp = op;
+ do {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--residue);
+ sp->dec_restart = 0;
+ }
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ nbits = sp->lzw_nbits;
+ nextdata = sp->lzw_nextdata;
+ nextbits = sp->lzw_nextbits;
+ nbitsmask = sp->dec_nbitsmask;
+ oldcodep = sp->dec_oldcodep;
+ free_entp = sp->dec_free_entp;
+ maxcodep = sp->dec_maxcodep;
+
+ while (occ > 0) {
+ NextCode(tif, sp, bp, code, GetNextCodeCompat);
+ if (code == CODE_EOI)
+ break;
+ if (code == CODE_CLEAR) {
+ free_entp = sp->dec_codetab + CODE_FIRST;
+ _TIFFmemset(free_entp, 0,
+ (CSIZE - CODE_FIRST) * sizeof (code_t));
+ nbits = BITS_MIN;
+ nbitsmask = MAXCODE(BITS_MIN);
+ maxcodep = sp->dec_codetab + nbitsmask;
+ NextCode(tif, sp, bp, code, GetNextCodeCompat);
+ if (code == CODE_EOI)
+ break;
+ if (code >= CODE_CLEAR) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "LZWDecode: Corrupted LZW table at scanline %d",
+ tif->tif_row);
+ return (0);
+ }
+ *op++ = code, occ--;
+ oldcodep = sp->dec_codetab + code;
+ continue;
+ }
+ codep = sp->dec_codetab + code;
+
+ /*
+ * Add the new entry to the code table.
+ */
+ if (free_entp < &sp->dec_codetab[0] ||
+ free_entp >= &sp->dec_codetab[CSIZE]) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Corrupted LZW table at scanline %d", tif->tif_row);
+ return (0);
+ }
+
+ free_entp->next = oldcodep;
+ if (free_entp->next < &sp->dec_codetab[0] ||
+ free_entp->next >= &sp->dec_codetab[CSIZE]) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Corrupted LZW table at scanline %d", tif->tif_row);
+ return (0);
+ }
+ free_entp->firstchar = free_entp->next->firstchar;
+ free_entp->length = free_entp->next->length+1;
+ free_entp->value = (codep < free_entp) ?
+ codep->firstchar : free_entp->firstchar;
+ if (++free_entp > maxcodep) {
+ if (++nbits > BITS_MAX) /* should not happen */
+ nbits = BITS_MAX;
+ nbitsmask = MAXCODE(nbits);
+ maxcodep = sp->dec_codetab + nbitsmask;
+ }
+ oldcodep = codep;
+ if (code >= 256) {
+ /*
+ * Code maps to a string, copy string
+ * value to output (written in reverse).
+ */
+ if(codep->length == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Wrong length of decoded "
+ "string: data probably corrupted at scanline %d",
+ tif->tif_row);
+ return (0);
+ }
+ if (codep->length > occ) {
+ /*
+ * String is too long for decode buffer,
+ * locate portion that will fit, copy to
+ * the decode buffer, and setup restart
+ * logic for the next decoding call.
+ */
+ sp->dec_codep = codep;
+ do {
+ codep = codep->next;
+ } while (codep->length > occ);
+ sp->dec_restart = occ;
+ tp = op + occ;
+ do {
+ *--tp = codep->value;
+ codep = codep->next;
+ } while (--occ);
+ break;
+ }
+ assert(occ >= codep->length);
+ op += codep->length, occ -= codep->length;
+ tp = op;
+ do {
+ *--tp = codep->value;
+ } while( (codep = codep->next) != NULL );
+ } else
+ *op++ = code, occ--;
+ }
+
+ tif->tif_rawcp = (uint8*) bp;
+ sp->lzw_nbits = nbits;
+ sp->lzw_nextdata = nextdata;
+ sp->lzw_nextbits = nextbits;
+ sp->dec_nbitsmask = nbitsmask;
+ sp->dec_oldcodep = oldcodep;
+ sp->dec_free_entp = free_entp;
+ sp->dec_maxcodep = maxcodep;
+
+ if (occ > 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at scanline %d (short %I64d bytes)",
+ tif->tif_row, (unsigned __int64) occ);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at scanline %d (short %llu bytes)",
+ tif->tif_row, (unsigned long long) occ);
+#endif
+ return (0);
+ }
+ return (1);
+}
+#endif /* LZW_COMPAT */
+
+/*
+ * LZW Encoding.
+ */
+
+static int
+LZWSetupEncode(TIFF* tif)
+{
+ static const char module[] = "LZWSetupEncode";
+ LZWCodecState* sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ sp->enc_hashtab = (hash_t*) _TIFFmalloc(HSIZE*sizeof (hash_t));
+ if (sp->enc_hashtab == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for LZW hash table");
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+LZWPreEncode(TIFF* tif, uint16 s)
+{
+ LZWCodecState *sp = EncoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+
+ if( sp->enc_hashtab == NULL )
+ {
+ tif->tif_setupencode( tif );
+ }
+
+ sp->lzw_nbits = BITS_MIN;
+ sp->lzw_maxcode = MAXCODE(BITS_MIN);
+ sp->lzw_free_ent = CODE_FIRST;
+ sp->lzw_nextbits = 0;
+ sp->lzw_nextdata = 0;
+ sp->enc_checkpoint = CHECK_GAP;
+ sp->enc_ratio = 0;
+ sp->enc_incount = 0;
+ sp->enc_outcount = 0;
+ /*
+ * The 4 here insures there is space for 2 max-sized
+ * codes in LZWEncode and LZWPostDecode.
+ */
+ sp->enc_rawlimit = tif->tif_rawdata + tif->tif_rawdatasize-1 - 4;
+ cl_hash(sp); /* clear hash table */
+ sp->enc_oldcode = (hcode_t) -1; /* generates CODE_CLEAR in LZWEncode */
+ return (1);
+}
+
+#define CALCRATIO(sp, rat) { \
+ if (incount > 0x007fffff) { /* NB: shift will overflow */\
+ rat = outcount >> 8; \
+ rat = (rat == 0 ? 0x7fffffff : incount/rat); \
+ } else \
+ rat = (incount<<8) / outcount; \
+}
+#define PutNextCode(op, c) { \
+ nextdata = (nextdata << nbits) | c; \
+ nextbits += nbits; \
+ *op++ = (unsigned char)(nextdata >> (nextbits-8)); \
+ nextbits -= 8; \
+ if (nextbits >= 8) { \
+ *op++ = (unsigned char)(nextdata >> (nextbits-8)); \
+ nextbits -= 8; \
+ } \
+ outcount += nbits; \
+}
+
+/*
+ * Encode a chunk of pixels.
+ *
+ * Uses an open addressing double hashing (no chaining) on the
+ * prefix code/next character combination. We do a variant of
+ * Knuth's algorithm D (vol. 3, sec. 6.4) along with G. Knott's
+ * relatively-prime secondary probe. Here, the modular division
+ * first probe is gives way to a faster exclusive-or manipulation.
+ * Also do block compression with an adaptive reset, whereby the
+ * code table is cleared when the compression ratio decreases,
+ * but after the table fills. The variable-length output codes
+ * are re-sized at this point, and a CODE_CLEAR is generated
+ * for the decoder.
+ */
+static int
+LZWEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ register LZWCodecState *sp = EncoderState(tif);
+ register long fcode;
+ register hash_t *hp;
+ register int h, c;
+ hcode_t ent;
+ long disp;
+ long incount, outcount, checkpoint;
+ long nextdata, nextbits;
+ int free_ent, maxcode, nbits;
+ uint8* op;
+ uint8* limit;
+
+ (void) s;
+ if (sp == NULL)
+ return (0);
+
+ assert(sp->enc_hashtab != NULL);
+
+ /*
+ * Load local state.
+ */
+ incount = sp->enc_incount;
+ outcount = sp->enc_outcount;
+ checkpoint = sp->enc_checkpoint;
+ nextdata = sp->lzw_nextdata;
+ nextbits = sp->lzw_nextbits;
+ free_ent = sp->lzw_free_ent;
+ maxcode = sp->lzw_maxcode;
+ nbits = sp->lzw_nbits;
+ op = tif->tif_rawcp;
+ limit = sp->enc_rawlimit;
+ ent = sp->enc_oldcode;
+
+ if (ent == (hcode_t) -1 && cc > 0) {
+ /*
+ * NB: This is safe because it can only happen
+ * at the start of a strip where we know there
+ * is space in the data buffer.
+ */
+ PutNextCode(op, CODE_CLEAR);
+ ent = *bp++; cc--; incount++;
+ }
+ while (cc > 0) {
+ c = *bp++; cc--; incount++;
+ fcode = ((long)c << BITS_MAX) + ent;
+ h = (c << HSHIFT) ^ ent; /* xor hashing */
+#ifdef _WINDOWS
+ /*
+ * Check hash index for an overflow.
+ */
+ if (h >= HSIZE)
+ h -= HSIZE;
+#endif
+ hp = &sp->enc_hashtab[h];
+ if (hp->hash == fcode) {
+ ent = hp->code;
+ continue;
+ }
+ if (hp->hash >= 0) {
+ /*
+ * Primary hash failed, check secondary hash.
+ */
+ disp = HSIZE - h;
+ if (h == 0)
+ disp = 1;
+ do {
+ /*
+ * Avoid pointer arithmetic 'cuz of
+ * wraparound problems with segments.
+ */
+ if ((h -= disp) < 0)
+ h += HSIZE;
+ hp = &sp->enc_hashtab[h];
+ if (hp->hash == fcode) {
+ ent = hp->code;
+ goto hit;
+ }
+ } while (hp->hash >= 0);
+ }
+ /*
+ * New entry, emit code and add to table.
+ */
+ /*
+ * Verify there is space in the buffer for the code
+ * and any potential Clear code that might be emitted
+ * below. The value of limit is setup so that there
+ * are at least 4 bytes free--room for 2 codes.
+ */
+ if (op > limit) {
+ tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+ TIFFFlushData1(tif);
+ op = tif->tif_rawdata;
+ }
+ PutNextCode(op, ent);
+ ent = c;
+ hp->code = free_ent++;
+ hp->hash = fcode;
+ if (free_ent == CODE_MAX-1) {
+ /* table is full, emit clear code and reset */
+ cl_hash(sp);
+ sp->enc_ratio = 0;
+ incount = 0;
+ outcount = 0;
+ free_ent = CODE_FIRST;
+ PutNextCode(op, CODE_CLEAR);
+ nbits = BITS_MIN;
+ maxcode = MAXCODE(BITS_MIN);
+ } else {
+ /*
+ * If the next entry is going to be too big for
+ * the code size, then increase it, if possible.
+ */
+ if (free_ent > maxcode) {
+ nbits++;
+ assert(nbits <= BITS_MAX);
+ maxcode = (int) MAXCODE(nbits);
+ } else if (incount >= checkpoint) {
+ long rat;
+ /*
+ * Check compression ratio and, if things seem
+ * to be slipping, clear the hash table and
+ * reset state. The compression ratio is a
+ * 24+8-bit fractional number.
+ */
+ checkpoint = incount+CHECK_GAP;
+ CALCRATIO(sp, rat);
+ if (rat <= sp->enc_ratio) {
+ cl_hash(sp);
+ sp->enc_ratio = 0;
+ incount = 0;
+ outcount = 0;
+ free_ent = CODE_FIRST;
+ PutNextCode(op, CODE_CLEAR);
+ nbits = BITS_MIN;
+ maxcode = MAXCODE(BITS_MIN);
+ } else
+ sp->enc_ratio = rat;
+ }
+ }
+ hit:
+ ;
+ }
+
+ /*
+ * Restore global state.
+ */
+ sp->enc_incount = incount;
+ sp->enc_outcount = outcount;
+ sp->enc_checkpoint = checkpoint;
+ sp->enc_oldcode = ent;
+ sp->lzw_nextdata = nextdata;
+ sp->lzw_nextbits = nextbits;
+ sp->lzw_free_ent = free_ent;
+ sp->lzw_maxcode = maxcode;
+ sp->lzw_nbits = nbits;
+ tif->tif_rawcp = op;
+ return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int
+LZWPostEncode(TIFF* tif)
+{
+ register LZWCodecState *sp = EncoderState(tif);
+ uint8* op = tif->tif_rawcp;
+ long nextbits = sp->lzw_nextbits;
+ long nextdata = sp->lzw_nextdata;
+ long outcount = sp->enc_outcount;
+ int nbits = sp->lzw_nbits;
+
+ if (op > sp->enc_rawlimit) {
+ tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+ TIFFFlushData1(tif);
+ op = tif->tif_rawdata;
+ }
+ if (sp->enc_oldcode != (hcode_t) -1) {
+ PutNextCode(op, sp->enc_oldcode);
+ sp->enc_oldcode = (hcode_t) -1;
+ }
+ PutNextCode(op, CODE_EOI);
+ if (nextbits > 0)
+ *op++ = (unsigned char)(nextdata << (8-nextbits));
+ tif->tif_rawcc = (tmsize_t)(op - tif->tif_rawdata);
+ return (1);
+}
+
+/*
+ * Reset encoding hash table.
+ */
+static void
+cl_hash(LZWCodecState* sp)
+{
+ register hash_t *hp = &sp->enc_hashtab[HSIZE-1];
+ register long i = HSIZE-8;
+
+ do {
+ i -= 8;
+ hp[-7].hash = -1;
+ hp[-6].hash = -1;
+ hp[-5].hash = -1;
+ hp[-4].hash = -1;
+ hp[-3].hash = -1;
+ hp[-2].hash = -1;
+ hp[-1].hash = -1;
+ hp[ 0].hash = -1;
+ hp -= 8;
+ } while (i >= 0);
+ for (i += 8; i > 0; i--, hp--)
+ hp->hash = -1;
+}
+
+static void
+LZWCleanup(TIFF* tif)
+{
+ (void)TIFFPredictorCleanup(tif);
+
+ assert(tif->tif_data != 0);
+
+ if (DecoderState(tif)->dec_codetab)
+ _TIFFfree(DecoderState(tif)->dec_codetab);
+
+ if (EncoderState(tif)->enc_hashtab)
+ _TIFFfree(EncoderState(tif)->enc_hashtab);
+
+ _TIFFfree(tif->tif_data);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+int
+TIFFInitLZW(TIFF* tif, int scheme)
+{
+ static const char module[] = "TIFFInitLZW";
+ assert(scheme == COMPRESSION_LZW);
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8*) _TIFFmalloc(sizeof (LZWCodecState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ DecoderState(tif)->dec_codetab = NULL;
+ DecoderState(tif)->dec_decode = NULL;
+ EncoderState(tif)->enc_hashtab = NULL;
+ LZWState(tif)->rw_mode = tif->tif_mode;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = LZWFixupTags;
+ tif->tif_setupdecode = LZWSetupDecode;
+ tif->tif_predecode = LZWPreDecode;
+ tif->tif_decoderow = LZWDecode;
+ tif->tif_decodestrip = LZWDecode;
+ tif->tif_decodetile = LZWDecode;
+ tif->tif_setupencode = LZWSetupEncode;
+ tif->tif_preencode = LZWPreEncode;
+ tif->tif_postencode = LZWPostEncode;
+ tif->tif_encoderow = LZWEncode;
+ tif->tif_encodestrip = LZWEncode;
+ tif->tif_encodetile = LZWEncode;
+ tif->tif_cleanup = LZWCleanup;
+ /*
+ * Setup predictor setup.
+ */
+ (void) TIFFPredictorInit(tif);
+ return (1);
+bad:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for LZW state block");
+ return (0);
+}
+
+/*
+ * Copyright (c) 1985, 1986 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * James A. Woods, derived from original work by Spencer Thomas
+ * and Joseph Orost.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#endif /* LZW_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_next.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_next.c
new file mode 100644
index 0000000000..8c4fec456f
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_next.c
@@ -0,0 +1,162 @@
+/* $Id: tif_next.c,v 1.13 2010-03-10 18:56:48 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#ifdef NEXT_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * NeXT 2-bit Grey Scale Compression Algorithm Support
+ */
+
+#define SETPIXEL(op, v) { \
+ switch (npixels++ & 3) { \
+ case 0: op[0] = (unsigned char) ((v) << 6); break; \
+ case 1: op[0] |= (v) << 4; break; \
+ case 2: op[0] |= (v) << 2; break; \
+ case 3: *op++ |= (v); break; \
+ } \
+}
+
+#define LITERALROW 0x00
+#define LITERALSPAN 0x40
+#define WHITE ((1<<2)-1)
+
+static int
+NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "NeXTDecode";
+ unsigned char *bp, *op;
+ tmsize_t cc;
+ uint8* row;
+ tmsize_t scanline, n;
+
+ (void) s;
+ /*
+ * Each scanline is assumed to start off as all
+ * white (we assume a PhotometricInterpretation
+ * of ``min-is-black'').
+ */
+ for (op = (unsigned char*) buf, cc = occ; cc-- > 0;)
+ *op++ = 0xff;
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ scanline = tif->tif_scanlinesize;
+ if (occ % scanline)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+ return (0);
+ }
+ for (row = buf; occ > 0; occ -= scanline, row += scanline) {
+ n = *bp++, cc--;
+ switch (n) {
+ case LITERALROW:
+ /*
+ * The entire scanline is given as literal values.
+ */
+ if (cc < scanline)
+ goto bad;
+ _TIFFmemcpy(row, bp, scanline);
+ bp += scanline;
+ cc -= scanline;
+ break;
+ case LITERALSPAN: {
+ tmsize_t off;
+ /*
+ * The scanline has a literal span that begins at some
+ * offset.
+ */
+ off = (bp[0] * 256) + bp[1];
+ n = (bp[2] * 256) + bp[3];
+ if (cc < 4+n || off+n > scanline)
+ goto bad;
+ _TIFFmemcpy(row+off, bp+4, n);
+ bp += 4+n;
+ cc -= 4+n;
+ break;
+ }
+ default: {
+ uint32 npixels = 0, grey;
+ uint32 imagewidth = tif->tif_dir.td_imagewidth;
+
+ /*
+ * The scanline is composed of a sequence of constant
+ * color ``runs''. We shift into ``run mode'' and
+ * interpret bytes as codes of the form
+ * <color><npixels> until we've filled the scanline.
+ */
+ op = row;
+ for (;;) {
+ grey = (uint32)((n>>6) & 0x3);
+ n &= 0x3f;
+ /*
+ * Ensure the run does not exceed the scanline
+ * bounds, potentially resulting in a security
+ * issue.
+ */
+ while (n-- > 0 && npixels < imagewidth)
+ SETPIXEL(op, grey);
+ if (npixels >= imagewidth)
+ break;
+ if (cc == 0)
+ goto bad;
+ n = *bp++, cc--;
+ }
+ break;
+ }
+ }
+ }
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ return (1);
+bad:
+ TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld",
+ (long) tif->tif_row);
+ return (0);
+}
+
+int
+TIFFInitNeXT(TIFF* tif, int scheme)
+{
+ (void) scheme;
+ tif->tif_decoderow = NeXTDecode;
+ tif->tif_decodestrip = NeXTDecode;
+ tif->tif_decodetile = NeXTDecode;
+ return (1);
+}
+#endif /* NEXT_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_ojpeg.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_ojpeg.c
new file mode 100644
index 0000000000..bed4f9be7e
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_ojpeg.c
@@ -0,0 +1,2506 @@
+/* $Id: tif_ojpeg.c,v 1.56 2012-05-24 03:15:18 fwarmerdam Exp $ */
+
+/* WARNING: The type of JPEG encapsulation defined by the TIFF Version 6.0
+ specification is now totally obsolete and deprecated for new applications and
+ images. This file was was created solely in order to read unconverted images
+ still present on some users' computer systems. It will never be extended
+ to write such files. Writing new-style JPEG compressed TIFFs is implemented
+ in tif_jpeg.c.
+
+ The code is carefully crafted to robustly read all gathered JPEG-in-TIFF
+ testfiles, and anticipate as much as possible all other... But still, it may
+ fail on some. If you encounter problems, please report them on the TIFF
+ mailing list and/or to Joris Van Damme <info@awaresystems.be>.
+
+ Please read the file called "TIFF Technical Note #2" if you need to be
+ convinced this compression scheme is bad and breaks TIFF. That document
+ is linked to from the LibTiff site <http://www.remotesensing.org/libtiff/>
+ and from AWare Systems' TIFF section
+ <http://www.awaresystems.be/imaging/tiff.html>. It is also absorbed
+ in Adobe's specification supplements, marked "draft" up to this day, but
+ supported by the TIFF community.
+
+ This file interfaces with Release 6B of the JPEG Library written by the
+ Independent JPEG Group. Previous versions of this file required a hack inside
+ the LibJpeg library. This version no longer requires that. Remember to
+ remove the hack if you update from the old version.
+
+ Copyright (c) Joris Van Damme <info@awaresystems.be>
+ Copyright (c) AWare Systems <http://www.awaresystems.be/>
+
+ The licence agreement for this file is the same as the rest of the LibTiff
+ library.
+
+ IN NO EVENT SHALL JORIS VAN DAMME OR AWARE SYSTEMS BE LIABLE FOR
+ ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ OF THIS SOFTWARE.
+
+ Joris Van Damme and/or AWare Systems may be available for custom
+ developement. If you like what you see, and need anything similar or related,
+ contact <info@awaresystems.be>.
+*/
+
+/* What is what, and what is not?
+
+ This decoder starts with an input stream, that is essentially the JpegInterchangeFormat
+ stream, if any, followed by the strile data, if any. This stream is read in
+ OJPEGReadByte and related functions.
+
+ It analyzes the start of this stream, until it encounters non-marker data, i.e.
+ compressed image data. Some of the header markers it sees have no actual content,
+ like the SOI marker, and APP/COM markers that really shouldn't even be there. Some
+ other markers do have content, and the valuable bits and pieces of information
+ in these markers are saved, checking all to verify that the stream is more or
+ less within expected bounds. This happens inside the OJPEGReadHeaderInfoSecStreamXxx
+ functions.
+
+ Some OJPEG imagery contains no valid JPEG header markers. This situation is picked
+ up on if we've seen no SOF marker when we're at the start of the compressed image
+ data. In this case, the tables are read from JpegXxxTables tags, and the other
+ bits and pieces of information is initialized to its most basic value. This is
+ implemented in the OJPEGReadHeaderInfoSecTablesXxx functions.
+
+ When this is complete, a good and valid JPEG header can be assembled, and this is
+ passed through to LibJpeg. When that's done, the remainder of the input stream, i.e.
+ the compressed image data, can be passed through unchanged. This is done in
+ OJPEGWriteStream functions.
+
+ LibTiff rightly expects to know the subsampling values before decompression. Just like
+ in new-style JPEG-in-TIFF, though, or even more so, actually, the YCbCrsubsampling
+ tag is notoriously unreliable. To correct these tag values with the ones inside
+ the JPEG stream, the first part of the input stream is pre-scanned in
+ OJPEGSubsamplingCorrect, making no note of any other data, reporting no warnings
+ or errors, up to the point where either these values are read, or it's clear they
+ aren't there. This means that some of the data is read twice, but we feel speed
+ in correcting these values is important enough to warrant this sacrifice. Allthough
+ there is currently no define or other configuration mechanism to disable this behaviour,
+ the actual header scanning is build to robustly respond with error report if it
+ should encounter an uncorrected mismatch of subsampling values. See
+ OJPEGReadHeaderInfoSecStreamSof.
+
+ The restart interval and restart markers are the most tricky part... The restart
+ interval can be specified in a tag. It can also be set inside the input JPEG stream.
+ It can be used inside the input JPEG stream. If reading from strile data, we've
+ consistenly discovered the need to insert restart markers in between the different
+ striles, as is also probably the most likely interpretation of the original TIFF 6.0
+ specification. With all this setting of interval, and actual use of markers that is not
+ predictable at the time of valid JPEG header assembly, the restart thing may turn
+ out the Achilles heel of this implementation. Fortunately, most OJPEG writer vendors
+ succeed in reading back what they write, which may be the reason why we've been able
+ to discover ways that seem to work.
+
+ Some special provision is made for planarconfig separate OJPEG files. These seem
+ to consistently contain header info, a SOS marker, a plane, SOS marker, plane, SOS,
+ and plane. This may or may not be a valid JPEG configuration, we don't know and don't
+ care. We want LibTiff to be able to access the planes individually, without huge
+ buffering inside LibJpeg, anyway. So we compose headers to feed to LibJpeg, in this
+ case, that allow us to pass a single plane such that LibJpeg sees a valid
+ single-channel JPEG stream. Locating subsequent SOS markers, and thus subsequent
+ planes, is done inside OJPEGReadSecondarySos.
+
+ The benefit of the scheme is... that it works, basically. We know of no other that
+ does. It works without checking software tag, or otherwise going about things in an
+ OJPEG flavor specific manner. Instead, it is a single scheme, that covers the cases
+ with and without JpegInterchangeFormat, with and without striles, with part of
+ the header in JpegInterchangeFormat and remainder in first strile, etc. It is forgiving
+ and robust, may likely work with OJPEG flavors we've not seen yet, and makes most out
+ of the data.
+
+ Another nice side-effect is that a complete JPEG single valid stream is build if
+ planarconfig is not separate (vast majority). We may one day use that to build
+ converters to JPEG, and/or to new-style JPEG compression inside TIFF.
+
+ A dissadvantage is the lack of random access to the individual striles. This is the
+ reason for much of the complicated restart-and-position stuff inside OJPEGPreDecode.
+ Applications would do well accessing all striles in order, as this will result in
+ a single sequential scan of the input stream, and no restarting of LibJpeg decoding
+ session.
+*/
+
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+
+#define WIN32_LEAN_AND_MEAN
+#define VC_EXTRALEAN
+
+#include "tiffiop.h"
+#ifdef OJPEG_SUPPORT
+
+/* Configuration defines here are:
+ * JPEG_ENCAP_EXTERNAL: The normal way to call libjpeg, uses longjump. In some environments,
+ * like eg LibTiffDelphi, this is not possible. For this reason, the actual calls to
+ * libjpeg, with longjump stuff, are encapsulated in dedicated functions. When
+ * JPEG_ENCAP_EXTERNAL is defined, these encapsulating functions are declared external
+ * to this unit, and can be defined elsewhere to use stuff other then longjump.
+ * The default mode, without JPEG_ENCAP_EXTERNAL, implements the call encapsulators
+ * here, internally, with normal longjump.
+ * SETJMP, LONGJMP, JMP_BUF: On some machines/environments a longjump equivalent is
+ * conviniently available, but still it may be worthwhile to use _setjmp or sigsetjmp
+ * in place of plain setjmp. These macros will make it easier. It is useless
+ * to fiddle with these if you define JPEG_ENCAP_EXTERNAL.
+ * OJPEG_BUFFER: Define the size of the desired buffer here. Should be small enough so as to guarantee
+ * instant processing, optimal streaming and optimal use of processor cache, but also big
+ * enough so as to not result in significant call overhead. It should be at least a few
+ * bytes to accomodate some structures (this is verified in asserts), but it would not be
+ * sensible to make it this small anyway, and it should be at most 64K since it is indexed
+ * with uint16. We recommend 2K.
+ * EGYPTIANWALK: You could also define EGYPTIANWALK here, but it is not used anywhere and has
+ * absolutely no effect. That is why most people insist the EGYPTIANWALK is a bit silly.
+ */
+
+/* define LIBJPEG_ENCAP_EXTERNAL */
+#define SETJMP(jbuf) setjmp(jbuf)
+#define LONGJMP(jbuf,code) longjmp(jbuf,code)
+#define JMP_BUF jmp_buf
+#define OJPEG_BUFFER 2048
+/* define EGYPTIANWALK */
+
+#define JPEG_MARKER_SOF0 0xC0
+#define JPEG_MARKER_SOF1 0xC1
+#define JPEG_MARKER_SOF3 0xC3
+#define JPEG_MARKER_DHT 0xC4
+#define JPEG_MARKER_RST0 0XD0
+#define JPEG_MARKER_SOI 0xD8
+#define JPEG_MARKER_EOI 0xD9
+#define JPEG_MARKER_SOS 0xDA
+#define JPEG_MARKER_DQT 0xDB
+#define JPEG_MARKER_DRI 0xDD
+#define JPEG_MARKER_APP0 0xE0
+#define JPEG_MARKER_COM 0xFE
+
+#define FIELD_OJPEG_JPEGINTERCHANGEFORMAT (FIELD_CODEC+0)
+#define FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH (FIELD_CODEC+1)
+#define FIELD_OJPEG_JPEGQTABLES (FIELD_CODEC+2)
+#define FIELD_OJPEG_JPEGDCTABLES (FIELD_CODEC+3)
+#define FIELD_OJPEG_JPEGACTABLES (FIELD_CODEC+4)
+#define FIELD_OJPEG_JPEGPROC (FIELD_CODEC+5)
+#define FIELD_OJPEG_JPEGRESTARTINTERVAL (FIELD_CODEC+6)
+
+static const TIFFField ojpegFields[] = {
+ {TIFFTAG_JPEGIFOFFSET,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMAT,TRUE,FALSE,"JpegInterchangeFormat",NULL},
+ {TIFFTAG_JPEGIFBYTECOUNT,1,1,TIFF_LONG8,0,TIFF_SETGET_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH,TRUE,FALSE,"JpegInterchangeFormatLength",NULL},
+ {TIFFTAG_JPEGQTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGQTABLES,FALSE,TRUE,"JpegQTables",NULL},
+ {TIFFTAG_JPEGDCTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGDCTABLES,FALSE,TRUE,"JpegDcTables",NULL},
+ {TIFFTAG_JPEGACTABLES,TIFF_VARIABLE2,TIFF_VARIABLE2,TIFF_LONG8,0,TIFF_SETGET_C32_UINT64,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGACTABLES,FALSE,TRUE,"JpegAcTables",NULL},
+ {TIFFTAG_JPEGPROC,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGPROC,FALSE,FALSE,"JpegProc",NULL},
+ {TIFFTAG_JPEGRESTARTINTERVAL,1,1,TIFF_SHORT,0,TIFF_SETGET_UINT16,TIFF_SETGET_UNDEFINED,FIELD_OJPEG_JPEGRESTARTINTERVAL,FALSE,FALSE,"JpegRestartInterval",NULL},
+};
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+#include <setjmp.h>
+#endif
+
+/* We undefine FAR to avoid conflict with JPEG definition */
+
+#ifdef FAR
+#undef FAR
+#endif
+
+/*
+ Libjpeg's jmorecfg.h defines INT16 and INT32, but only if XMD_H is
+ not defined. Unfortunately, the MinGW and Borland compilers include
+ a typedef for INT32, which causes a conflict. MSVC does not include
+ a conficting typedef given the headers which are included.
+*/
+#if defined(__BORLANDC__) || defined(__MINGW32__)
+# define XMD_H 1
+#endif
+
+/* Define "boolean" as unsigned char, not int, per Windows custom. */
+#if defined(__WIN32__) && !defined(__MINGW32__)
+# ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+ typedef unsigned char boolean;
+# endif
+# define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+#endif
+
+#ifndef _FX_JPEG_TURBO_
+ #include "../../libjpeg/jpeglib.h"
+ #include "../../libjpeg/jerror.h"
+#else
+ #include "../../libjpeg-turbo/jpeglib.h"
+ #include "../../libjpeg-turbo/jerror.h"
+#endif//_FX_JPEG_TURBO_
+
+typedef struct jpeg_error_mgr jpeg_error_mgr;
+typedef struct jpeg_common_struct jpeg_common_struct;
+typedef struct jpeg_decompress_struct jpeg_decompress_struct;
+typedef struct jpeg_source_mgr jpeg_source_mgr;
+
+typedef enum {
+ osibsNotSetYet,
+ osibsJpegInterchangeFormat,
+ osibsStrile,
+ osibsEof
+} OJPEGStateInBufferSource;
+
+typedef enum {
+ ososSoi,
+ ososQTable0,ososQTable1,ososQTable2,ososQTable3,
+ ososDcTable0,ososDcTable1,ososDcTable2,ososDcTable3,
+ ososAcTable0,ososAcTable1,ososAcTable2,ososAcTable3,
+ ososDri,
+ ososSof,
+ ososSos,
+ ososCompressed,
+ ososRst,
+ ososEoi
+} OJPEGStateOutState;
+
+typedef struct {
+ TIFF* tif;
+ #ifndef LIBJPEG_ENCAP_EXTERNAL
+ JMP_BUF exit_jmpbuf;
+ #endif
+ TIFFVGetMethod vgetparent;
+ TIFFVSetMethod vsetparent;
+ TIFFPrintMethod printdir;
+ uint64 file_size;
+ uint32 image_width;
+ uint32 image_length;
+ uint32 strile_width;
+ uint32 strile_length;
+ uint32 strile_length_total;
+ uint8 samples_per_pixel;
+ uint8 plane_sample_offset;
+ uint8 samples_per_pixel_per_plane;
+ uint64 jpeg_interchange_format;
+ uint64 jpeg_interchange_format_length;
+ uint8 jpeg_proc;
+ uint8 subsamplingcorrect;
+ uint8 subsamplingcorrect_done;
+ uint8 subsampling_tag;
+ uint8 subsampling_hor;
+ uint8 subsampling_ver;
+ uint8 subsampling_force_desubsampling_inside_decompression;
+ uint8 qtable_offset_count;
+ uint8 dctable_offset_count;
+ uint8 actable_offset_count;
+ uint64 qtable_offset[3];
+ uint64 dctable_offset[3];
+ uint64 actable_offset[3];
+ uint8* qtable[4];
+ uint8* dctable[4];
+ uint8* actable[4];
+ uint16 restart_interval;
+ uint8 restart_index;
+ uint8 sof_log;
+ uint8 sof_marker_id;
+ uint32 sof_x;
+ uint32 sof_y;
+ uint8 sof_c[3];
+ uint8 sof_hv[3];
+ uint8 sof_tq[3];
+ uint8 sos_cs[3];
+ uint8 sos_tda[3];
+ struct {
+ uint8 log;
+ OJPEGStateInBufferSource in_buffer_source;
+ uint32 in_buffer_next_strile;
+ uint64 in_buffer_file_pos;
+ uint64 in_buffer_file_togo;
+ } sos_end[3];
+ uint8 readheader_done;
+ uint8 writeheader_done;
+ uint16 write_cursample;
+ uint32 write_curstrile;
+ uint8 libjpeg_session_active;
+ uint8 libjpeg_jpeg_query_style;
+ jpeg_error_mgr libjpeg_jpeg_error_mgr;
+ jpeg_decompress_struct libjpeg_jpeg_decompress_struct;
+ jpeg_source_mgr libjpeg_jpeg_source_mgr;
+ uint8 subsampling_convert_log;
+ uint32 subsampling_convert_ylinelen;
+ uint32 subsampling_convert_ylines;
+ uint32 subsampling_convert_clinelen;
+ uint32 subsampling_convert_clines;
+ uint32 subsampling_convert_ybuflen;
+ uint32 subsampling_convert_cbuflen;
+ uint32 subsampling_convert_ycbcrbuflen;
+ uint8* subsampling_convert_ycbcrbuf;
+ uint8* subsampling_convert_ybuf;
+ uint8* subsampling_convert_cbbuf;
+ uint8* subsampling_convert_crbuf;
+ uint32 subsampling_convert_ycbcrimagelen;
+ uint8** subsampling_convert_ycbcrimage;
+ uint32 subsampling_convert_clinelenout;
+ uint32 subsampling_convert_state;
+ uint32 bytes_per_line; /* if the codec outputs subsampled data, a 'line' in bytes_per_line */
+ uint32 lines_per_strile; /* and lines_per_strile means subsampling_ver desubsampled rows */
+ OJPEGStateInBufferSource in_buffer_source;
+ uint32 in_buffer_next_strile;
+ uint32 in_buffer_strile_count;
+ uint64 in_buffer_file_pos;
+ uint8 in_buffer_file_pos_log;
+ uint64 in_buffer_file_togo;
+ uint16 in_buffer_togo;
+ uint8* in_buffer_cur;
+ uint8 in_buffer[OJPEG_BUFFER];
+ OJPEGStateOutState out_state;
+ uint8 out_buffer[OJPEG_BUFFER];
+ uint8* skip_buffer;
+} OJPEGState;
+
+static int OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap);
+static int OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap);
+static void OJPEGPrintDir(TIFF* tif, FILE* fd, long flags);
+
+static int OJPEGFixupTags(TIFF* tif);
+static int OJPEGSetupDecode(TIFF* tif);
+static int OJPEGPreDecode(TIFF* tif, uint16 s);
+static int OJPEGPreDecodeSkipRaw(TIFF* tif);
+static int OJPEGPreDecodeSkipScanlines(TIFF* tif);
+static int OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc);
+static int OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc);
+static void OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc);
+static int OJPEGSetupEncode(TIFF* tif);
+static int OJPEGPreEncode(TIFF* tif, uint16 s);
+static int OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s);
+static int OJPEGPostEncode(TIFF* tif);
+static void OJPEGCleanup(TIFF* tif);
+
+static void OJPEGSubsamplingCorrect(TIFF* tif);
+static int OJPEGReadHeaderInfo(TIFF* tif);
+static int OJPEGReadSecondarySos(TIFF* tif, uint16 s);
+static int OJPEGWriteHeaderInfo(TIFF* tif);
+static void OJPEGLibjpegSessionAbort(TIFF* tif);
+
+static int OJPEGReadHeaderInfoSec(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamDri(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamDht(TIFF* tif);
+static int OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id);
+static int OJPEGReadHeaderInfoSecStreamSos(TIFF* tif);
+static int OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif);
+static int OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif);
+static int OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif);
+
+static int OJPEGReadBufferFill(OJPEGState* sp);
+static int OJPEGReadByte(OJPEGState* sp, uint8* byte);
+static int OJPEGReadBytePeek(OJPEGState* sp, uint8* byte);
+static void OJPEGReadByteAdvance(OJPEGState* sp);
+static int OJPEGReadWord(OJPEGState* sp, uint16* word);
+static int OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem);
+static void OJPEGReadSkip(OJPEGState* sp, uint16 len);
+
+static int OJPEGWriteStream(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
+static void OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
+static void OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len);
+static void OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len);
+static int OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len);
+static void OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len);
+
+#ifdef LIBJPEG_ENCAP_EXTERNAL
+extern int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
+extern int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
+extern int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
+extern int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
+extern int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
+extern void jpeg_encap_unwind(TIFF* tif);
+#else
+static int jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* j);
+static int jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image);
+static int jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo);
+static int jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines);
+static int jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines);
+static void jpeg_encap_unwind(TIFF* tif);
+#endif
+
+static void OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo);
+static void OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo);
+static void OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo);
+static boolean OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo);
+static void OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes);
+static boolean OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired);
+static void OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo);
+
+int
+TIFFInitOJPEG(TIFF* tif, int scheme)
+{
+ static const char module[]="TIFFInitOJPEG";
+ OJPEGState* sp;
+
+ assert(scheme==COMPRESSION_OJPEG);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, ojpegFields, TIFFArrayCount(ojpegFields))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Merging Old JPEG codec-specific tags failed");
+ return 0;
+ }
+
+ /* state block */
+ sp = (OJPEGState*)_TIFFmalloc(sizeof(OJPEGState)); // // add (OJPEGState*) cast
+ if (sp == NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"No space for OJPEG state block");
+ return(0);
+ }
+ _TIFFmemset(sp,0,sizeof(OJPEGState));
+ sp->tif=tif;
+ sp->jpeg_proc=1;
+ sp->subsampling_hor=2;
+ sp->subsampling_ver=2;
+ TIFFSetField(tif,TIFFTAG_YCBCRSUBSAMPLING,2,2);
+ /* tif codec methods */
+ tif->tif_fixuptags=OJPEGFixupTags;
+ tif->tif_setupdecode=OJPEGSetupDecode;
+ tif->tif_predecode=OJPEGPreDecode;
+ tif->tif_postdecode=OJPEGPostDecode;
+ tif->tif_decoderow=OJPEGDecode;
+ tif->tif_decodestrip=OJPEGDecode;
+ tif->tif_decodetile=OJPEGDecode;
+ tif->tif_setupencode=OJPEGSetupEncode;
+ tif->tif_preencode=OJPEGPreEncode;
+ tif->tif_postencode=OJPEGPostEncode;
+ tif->tif_encoderow=OJPEGEncode;
+ tif->tif_encodestrip=OJPEGEncode;
+ tif->tif_encodetile=OJPEGEncode;
+ tif->tif_cleanup=OJPEGCleanup;
+ tif->tif_data=(uint8*)sp;
+ /* tif tag methods */
+ sp->vgetparent=tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield=OJPEGVGetField;
+ sp->vsetparent=tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield=OJPEGVSetField;
+ sp->printdir=tif->tif_tagmethods.printdir;
+ tif->tif_tagmethods.printdir=OJPEGPrintDir;
+ /* Some OJPEG files don't have strip or tile offsets or bytecounts tags.
+ Some others do, but have totally meaningless or corrupt values
+ in these tags. In these cases, the JpegInterchangeFormat stream is
+ reliable. In any case, this decoder reads the compressed data itself,
+ from the most reliable locations, and we need to notify encapsulating
+ LibTiff not to read raw strips or tiles for us. */
+ tif->tif_flags|=TIFF_NOREADRAW;
+ return(1);
+}
+
+static int
+OJPEGVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ switch(tag)
+ {
+ case TIFFTAG_JPEGIFOFFSET:
+ *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format;
+ break;
+ case TIFFTAG_JPEGIFBYTECOUNT:
+ *va_arg(ap,uint64*)=(uint64)sp->jpeg_interchange_format_length;
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ if (sp->subsamplingcorrect_done==0)
+ OJPEGSubsamplingCorrect(tif);
+ *va_arg(ap,uint16*)=(uint16)sp->subsampling_hor;
+ *va_arg(ap,uint16*)=(uint16)sp->subsampling_ver;
+ break;
+ case TIFFTAG_JPEGQTABLES:
+ *va_arg(ap,uint32*)=(uint32)sp->qtable_offset_count;
+ *va_arg(ap,void**)=(void*)sp->qtable_offset;
+ break;
+ case TIFFTAG_JPEGDCTABLES:
+ *va_arg(ap,uint32*)=(uint32)sp->dctable_offset_count;
+ *va_arg(ap,void**)=(void*)sp->dctable_offset;
+ break;
+ case TIFFTAG_JPEGACTABLES:
+ *va_arg(ap,uint32*)=(uint32)sp->actable_offset_count;
+ *va_arg(ap,void**)=(void*)sp->actable_offset;
+ break;
+ case TIFFTAG_JPEGPROC:
+ *va_arg(ap,uint16*)=(uint16)sp->jpeg_proc;
+ break;
+ case TIFFTAG_JPEGRESTARTINTERVAL:
+ *va_arg(ap,uint16*)=sp->restart_interval;
+ break;
+ default:
+ return (*sp->vgetparent)(tif,tag,ap);
+ }
+ return (1);
+}
+
+static int
+OJPEGVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ static const char module[]="OJPEGVSetField";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint32 ma;
+ uint64* mb;
+ uint32 n;
+ switch(tag)
+ {
+ case TIFFTAG_JPEGIFOFFSET:
+ sp->jpeg_interchange_format=(uint64)va_arg(ap,uint64);
+ break;
+ case TIFFTAG_JPEGIFBYTECOUNT:
+ sp->jpeg_interchange_format_length=(uint64)va_arg(ap,uint64);
+ break;
+ case TIFFTAG_YCBCRSUBSAMPLING:
+ sp->subsampling_tag=1;
+ sp->subsampling_hor=(uint8)va_arg(ap,uint16_vap);
+ sp->subsampling_ver=(uint8)va_arg(ap,uint16_vap);
+ tif->tif_dir.td_ycbcrsubsampling[0]=sp->subsampling_hor;
+ tif->tif_dir.td_ycbcrsubsampling[1]=sp->subsampling_ver;
+ break;
+ case TIFFTAG_JPEGQTABLES:
+ ma=(uint32)va_arg(ap,uint32);
+ if (ma!=0)
+ {
+ if (ma>3)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JpegQTables tag has incorrect count");
+ return(0);
+ }
+ sp->qtable_offset_count=(uint8)ma;
+ mb=(uint64*)va_arg(ap,uint64*);
+ for (n=0; n<ma; n++)
+ sp->qtable_offset[n]=mb[n];
+ }
+ break;
+ case TIFFTAG_JPEGDCTABLES:
+ ma=(uint32)va_arg(ap,uint32);
+ if (ma!=0)
+ {
+ if (ma>3)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JpegDcTables tag has incorrect count");
+ return(0);
+ }
+ sp->dctable_offset_count=(uint8)ma;
+ mb=(uint64*)va_arg(ap,uint64*);
+ for (n=0; n<ma; n++)
+ sp->dctable_offset[n]=mb[n];
+ }
+ break;
+ case TIFFTAG_JPEGACTABLES:
+ ma=(uint32)va_arg(ap,uint32);
+ if (ma!=0)
+ {
+ if (ma>3)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JpegAcTables tag has incorrect count");
+ return(0);
+ }
+ sp->actable_offset_count=(uint8)ma;
+ mb=(uint64*)va_arg(ap,uint64*);
+ for (n=0; n<ma; n++)
+ sp->actable_offset[n]=mb[n];
+ }
+ break;
+ case TIFFTAG_JPEGPROC:
+ sp->jpeg_proc=(uint8)va_arg(ap,uint16_vap);
+ break;
+ case TIFFTAG_JPEGRESTARTINTERVAL:
+ sp->restart_interval=(uint16)va_arg(ap,uint16_vap);
+ break;
+ default:
+ return (*sp->vsetparent)(tif,tag,ap);
+ }
+ TIFFSetFieldBit(tif,TIFFFieldWithTag(tif,tag)->field_bit);
+ tif->tif_flags|=TIFF_DIRTYDIRECT;
+ return(1);
+}
+
+static void
+OJPEGPrintDir(TIFF* tif, FILE* fd, long flags)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ (void)flags;
+ assert(sp!=NULL);
+ if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMAT))
+ fprintf(fd," JpegInterchangeFormat: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format);
+ if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGINTERCHANGEFORMATLENGTH))
+ fprintf(fd," JpegInterchangeFormatLength: " TIFF_UINT64_FORMAT "\n",(TIFF_UINT64_T)sp->jpeg_interchange_format_length);
+ if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGQTABLES))
+ {
+ fprintf(fd," JpegQTables:");
+ for (m=0; m<sp->qtable_offset_count; m++)
+ fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->qtable_offset[m]);
+ fprintf(fd,"\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGDCTABLES))
+ {
+ fprintf(fd," JpegDcTables:");
+ for (m=0; m<sp->dctable_offset_count; m++)
+ fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->dctable_offset[m]);
+ fprintf(fd,"\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGACTABLES))
+ {
+ fprintf(fd," JpegAcTables:");
+ for (m=0; m<sp->actable_offset_count; m++)
+ fprintf(fd," " TIFF_UINT64_FORMAT,(TIFF_UINT64_T)sp->actable_offset[m]);
+ fprintf(fd,"\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGPROC))
+ fprintf(fd," JpegProc: %u\n",(unsigned int)sp->jpeg_proc);
+ if (TIFFFieldSet(tif,FIELD_OJPEG_JPEGRESTARTINTERVAL))
+ fprintf(fd," JpegRestartInterval: %u\n",(unsigned int)sp->restart_interval);
+ if (sp->printdir)
+ (*sp->printdir)(tif, fd, flags);
+}
+
+static int
+OJPEGFixupTags(TIFF* tif)
+{
+ (void) tif;
+ return(1);
+}
+
+static int
+OJPEGSetupDecode(TIFF* tif)
+{
+ static const char module[]="OJPEGSetupDecode";
+ TIFFWarningExt(tif->tif_clientdata,module,"Depreciated and troublesome old-style JPEG compression mode, please convert to new-style JPEG compression and notify vendor of writing software");
+ return(1);
+}
+
+static int
+OJPEGPreDecode(TIFF* tif, uint16 s)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint32 m;
+ if (sp->subsamplingcorrect_done==0)
+ OJPEGSubsamplingCorrect(tif);
+ if (sp->readheader_done==0)
+ {
+ if (OJPEGReadHeaderInfo(tif)==0)
+ return(0);
+ }
+ if (sp->sos_end[s].log==0)
+ {
+ if (OJPEGReadSecondarySos(tif,s)==0)
+ return(0);
+ }
+ if isTiled(tif)
+ m=tif->tif_curtile;
+ else
+ m=tif->tif_curstrip;
+ if ((sp->writeheader_done!=0) && ((sp->write_cursample!=s) || (sp->write_curstrile>m)))
+ {
+ if (sp->libjpeg_session_active!=0)
+ OJPEGLibjpegSessionAbort(tif);
+ sp->writeheader_done=0;
+ }
+ if (sp->writeheader_done==0)
+ {
+ sp->plane_sample_offset=(uint8)s;
+ sp->write_cursample=s;
+ sp->write_curstrile=s*tif->tif_dir.td_stripsperimage;
+ if ((sp->in_buffer_file_pos_log==0) ||
+ (sp->in_buffer_file_pos-sp->in_buffer_togo!=sp->sos_end[s].in_buffer_file_pos))
+ {
+ sp->in_buffer_source=sp->sos_end[s].in_buffer_source;
+ sp->in_buffer_next_strile=sp->sos_end[s].in_buffer_next_strile;
+ sp->in_buffer_file_pos=sp->sos_end[s].in_buffer_file_pos;
+ sp->in_buffer_file_pos_log=0;
+ sp->in_buffer_file_togo=sp->sos_end[s].in_buffer_file_togo;
+ sp->in_buffer_togo=0;
+ sp->in_buffer_cur=0;
+ }
+ if (OJPEGWriteHeaderInfo(tif)==0)
+ return(0);
+ }
+ while (sp->write_curstrile<m)
+ {
+ if (sp->libjpeg_jpeg_query_style==0)
+ {
+ if (OJPEGPreDecodeSkipRaw(tif)==0)
+ return(0);
+ }
+ else
+ {
+ if (OJPEGPreDecodeSkipScanlines(tif)==0)
+ return(0);
+ }
+ sp->write_curstrile++;
+ }
+ return(1);
+}
+
+static int
+OJPEGPreDecodeSkipRaw(TIFF* tif)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint32 m;
+ m=sp->lines_per_strile;
+ if (sp->subsampling_convert_state!=0)
+ {
+ if (sp->subsampling_convert_clines-sp->subsampling_convert_state>=m)
+ {
+ sp->subsampling_convert_state+=m;
+ if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
+ sp->subsampling_convert_state=0;
+ return(1);
+ }
+ m-=sp->subsampling_convert_clines-sp->subsampling_convert_state;
+ sp->subsampling_convert_state=0;
+ }
+ while (m>=sp->subsampling_convert_clines)
+ {
+ if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+ return(0);
+ m-=sp->subsampling_convert_clines;
+ }
+ if (m>0)
+ {
+ if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+ return(0);
+ sp->subsampling_convert_state=m;
+ }
+ return(1);
+}
+
+static int
+OJPEGPreDecodeSkipScanlines(TIFF* tif)
+{
+ static const char module[]="OJPEGPreDecodeSkipScanlines";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint32 m;
+ if (sp->skip_buffer==NULL)
+ {
+ // add (uint8*) cast
+ sp->skip_buffer = (uint8*)_TIFFmalloc(sp->bytes_per_line);
+ if (sp->skip_buffer == NULL)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ }
+ for (m=0; m<sp->lines_per_strile; m++)
+ {
+ if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&sp->skip_buffer,1)==0)
+ return(0);
+ }
+ return(1);
+}
+
+static int
+OJPEGDecode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ (void)s;
+ if (sp->libjpeg_jpeg_query_style==0)
+ {
+ if (OJPEGDecodeRaw(tif,buf,cc)==0)
+ return(0);
+ }
+ else
+ {
+ if (OJPEGDecodeScanlines(tif,buf,cc)==0)
+ return(0);
+ }
+ return(1);
+}
+
+static int
+OJPEGDecodeRaw(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ static const char module[]="OJPEGDecodeRaw";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8* m;
+ tmsize_t n;
+ uint8* oy;
+ uint8* ocb;
+ uint8* ocr;
+ uint8* p;
+ uint32 q;
+ uint8* r;
+ uint8 sx,sy;
+ if (cc%sp->bytes_per_line!=0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
+ return(0);
+ }
+ assert(cc>0);
+ m=buf;
+ n=cc;
+ do
+ {
+ if (sp->subsampling_convert_state==0)
+ {
+ if (jpeg_read_raw_data_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),sp->subsampling_convert_ycbcrimage,sp->subsampling_ver*8)==0)
+ return(0);
+ }
+ oy=sp->subsampling_convert_ybuf+sp->subsampling_convert_state*sp->subsampling_ver*sp->subsampling_convert_ylinelen;
+ ocb=sp->subsampling_convert_cbbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
+ ocr=sp->subsampling_convert_crbuf+sp->subsampling_convert_state*sp->subsampling_convert_clinelen;
+ p=m;
+ for (q=0; q<sp->subsampling_convert_clinelenout; q++)
+ {
+ r=oy;
+ for (sy=0; sy<sp->subsampling_ver; sy++)
+ {
+ for (sx=0; sx<sp->subsampling_hor; sx++)
+ *p++=*r++;
+ r+=sp->subsampling_convert_ylinelen-sp->subsampling_hor;
+ }
+ oy+=sp->subsampling_hor;
+ *p++=*ocb++;
+ *p++=*ocr++;
+ }
+ sp->subsampling_convert_state++;
+ if (sp->subsampling_convert_state==sp->subsampling_convert_clines)
+ sp->subsampling_convert_state=0;
+ m+=sp->bytes_per_line;
+ n-=sp->bytes_per_line;
+ } while(n>0);
+ return(1);
+}
+
+static int
+OJPEGDecodeScanlines(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ static const char module[]="OJPEGDecodeScanlines";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8* m;
+ tmsize_t n;
+ if (cc%sp->bytes_per_line!=0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Fractional scanline not read");
+ return(0);
+ }
+ assert(cc>0);
+ m=buf;
+ n=cc;
+ do
+ {
+ if (jpeg_read_scanlines_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),&m,1)==0)
+ return(0);
+ m+=sp->bytes_per_line;
+ n-=sp->bytes_per_line;
+ } while(n>0);
+ return(1);
+}
+
+static void
+OJPEGPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ (void)buf;
+ (void)cc;
+ sp->write_curstrile++;
+ if (sp->write_curstrile%tif->tif_dir.td_stripsperimage==0)
+ {
+ assert(sp->libjpeg_session_active!=0);
+ OJPEGLibjpegSessionAbort(tif);
+ sp->writeheader_done=0;
+ }
+}
+
+static int
+OJPEGSetupEncode(TIFF* tif)
+{
+ static const char module[]="OJPEGSetupEncode";
+ TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+ return(0);
+}
+
+static int
+OJPEGPreEncode(TIFF* tif, uint16 s)
+{
+ static const char module[]="OJPEGPreEncode";
+ (void)s;
+ TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+ return(0);
+}
+
+static int
+OJPEGEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ static const char module[]="OJPEGEncode";
+ (void)buf;
+ (void)cc;
+ (void)s;
+ TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+ return(0);
+}
+
+static int
+OJPEGPostEncode(TIFF* tif)
+{
+ static const char module[]="OJPEGPostEncode";
+ TIFFErrorExt(tif->tif_clientdata,module,"OJPEG encoding not supported; use new-style JPEG compression instead");
+ return(0);
+}
+
+static void
+OJPEGCleanup(TIFF* tif)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ if (sp!=0)
+ {
+ tif->tif_tagmethods.vgetfield=sp->vgetparent;
+ tif->tif_tagmethods.vsetfield=sp->vsetparent;
+ tif->tif_tagmethods.printdir=sp->printdir;
+ if (sp->qtable[0]!=0)
+ _TIFFfree(sp->qtable[0]);
+ if (sp->qtable[1]!=0)
+ _TIFFfree(sp->qtable[1]);
+ if (sp->qtable[2]!=0)
+ _TIFFfree(sp->qtable[2]);
+ if (sp->qtable[3]!=0)
+ _TIFFfree(sp->qtable[3]);
+ if (sp->dctable[0]!=0)
+ _TIFFfree(sp->dctable[0]);
+ if (sp->dctable[1]!=0)
+ _TIFFfree(sp->dctable[1]);
+ if (sp->dctable[2]!=0)
+ _TIFFfree(sp->dctable[2]);
+ if (sp->dctable[3]!=0)
+ _TIFFfree(sp->dctable[3]);
+ if (sp->actable[0]!=0)
+ _TIFFfree(sp->actable[0]);
+ if (sp->actable[1]!=0)
+ _TIFFfree(sp->actable[1]);
+ if (sp->actable[2]!=0)
+ _TIFFfree(sp->actable[2]);
+ if (sp->actable[3]!=0)
+ _TIFFfree(sp->actable[3]);
+ if (sp->libjpeg_session_active!=0)
+ OJPEGLibjpegSessionAbort(tif);
+ if (sp->subsampling_convert_ycbcrbuf!=0)
+ _TIFFfree(sp->subsampling_convert_ycbcrbuf);
+ if (sp->subsampling_convert_ycbcrimage!=0)
+ _TIFFfree(sp->subsampling_convert_ycbcrimage);
+ if (sp->skip_buffer!=0)
+ _TIFFfree(sp->skip_buffer);
+ _TIFFfree(sp);
+ tif->tif_data=NULL;
+ _TIFFSetDefaultCompressionState(tif);
+ }
+}
+
+static void
+OJPEGSubsamplingCorrect(TIFF* tif)
+{
+ static const char module[]="OJPEGSubsamplingCorrect";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 mh;
+ uint8 mv;
+ _TIFFFillStriles( tif );
+
+ assert(sp->subsamplingcorrect_done==0);
+ if ((tif->tif_dir.td_samplesperpixel!=3) || ((tif->tif_dir.td_photometric!=PHOTOMETRIC_YCBCR) &&
+ (tif->tif_dir.td_photometric!=PHOTOMETRIC_ITULAB)))
+ {
+ if (sp->subsampling_tag!=0)
+ TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag not appropriate for this Photometric and/or SamplesPerPixel");
+ sp->subsampling_hor=1;
+ sp->subsampling_ver=1;
+ sp->subsampling_force_desubsampling_inside_decompression=0;
+ }
+ else
+ {
+ sp->subsamplingcorrect_done=1;
+ mh=sp->subsampling_hor;
+ mv=sp->subsampling_ver;
+ sp->subsamplingcorrect=1;
+ OJPEGReadHeaderInfoSec(tif);
+ if (sp->subsampling_force_desubsampling_inside_decompression!=0)
+ {
+ sp->subsampling_hor=1;
+ sp->subsampling_ver=1;
+ }
+ sp->subsamplingcorrect=0;
+ if (((sp->subsampling_hor!=mh) || (sp->subsampling_ver!=mv)) && (sp->subsampling_force_desubsampling_inside_decompression==0))
+ {
+ if (sp->subsampling_tag==0)
+ TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data [%d,%d] does not match default values [2,2]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver);
+ else
+ TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data [%d,%d] does not match subsampling tag values [%d,%d]; assuming subsampling inside JPEG data is correct",sp->subsampling_hor,sp->subsampling_ver,mh,mv);
+ }
+ if (sp->subsampling_force_desubsampling_inside_decompression!=0)
+ {
+ if (sp->subsampling_tag==0)
+ TIFFWarningExt(tif->tif_clientdata,module,"Subsampling tag is not set, yet subsampling inside JPEG data does not match default values [2,2] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression");
+ else
+ TIFFWarningExt(tif->tif_clientdata,module,"Subsampling inside JPEG data does not match subsampling tag values [%d,%d] (nor any other values allowed in TIFF); assuming subsampling inside JPEG data is correct and desubsampling inside JPEG decompression",mh,mv);
+ }
+ if (sp->subsampling_force_desubsampling_inside_decompression==0)
+ {
+ if (sp->subsampling_hor<sp->subsampling_ver)
+ TIFFWarningExt(tif->tif_clientdata,module,"Subsampling values [%d,%d] are not allowed in TIFF",sp->subsampling_hor,sp->subsampling_ver);
+ }
+ }
+ sp->subsamplingcorrect_done=1;
+}
+
+static int
+OJPEGReadHeaderInfo(TIFF* tif)
+{
+ static const char module[]="OJPEGReadHeaderInfo";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ assert(sp->readheader_done==0);
+ sp->image_width=tif->tif_dir.td_imagewidth;
+ sp->image_length=tif->tif_dir.td_imagelength;
+ if isTiled(tif)
+ {
+ sp->strile_width=tif->tif_dir.td_tilewidth;
+ sp->strile_length=tif->tif_dir.td_tilelength;
+ sp->strile_length_total=((sp->image_length+sp->strile_length-1)/sp->strile_length)*sp->strile_length;
+ }
+ else
+ {
+ sp->strile_width=sp->image_width;
+ sp->strile_length=tif->tif_dir.td_rowsperstrip;
+ sp->strile_length_total=sp->image_length;
+ }
+ if (tif->tif_dir.td_samplesperpixel==1)
+ {
+ sp->samples_per_pixel=1;
+ sp->plane_sample_offset=0;
+ sp->samples_per_pixel_per_plane=sp->samples_per_pixel;
+ sp->subsampling_hor=1;
+ sp->subsampling_ver=1;
+ }
+ else
+ {
+ if (tif->tif_dir.td_samplesperpixel!=3)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"SamplesPerPixel %d not supported for this compression scheme",sp->samples_per_pixel);
+ return(0);
+ }
+ sp->samples_per_pixel=3;
+ sp->plane_sample_offset=0;
+ if (tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)
+ sp->samples_per_pixel_per_plane=3;
+ else
+ sp->samples_per_pixel_per_plane=1;
+ }
+ if (sp->strile_length<sp->image_length)
+ {
+ if (sp->strile_length%(sp->subsampling_ver*8)!=0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Incompatible vertical subsampling and image strip/tile length");
+ return(0);
+ }
+ sp->restart_interval=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8))*(sp->strile_length/(sp->subsampling_ver*8));
+ }
+ if (OJPEGReadHeaderInfoSec(tif)==0)
+ return(0);
+ sp->sos_end[0].log=1;
+ sp->sos_end[0].in_buffer_source=sp->in_buffer_source;
+ sp->sos_end[0].in_buffer_next_strile=sp->in_buffer_next_strile;
+ sp->sos_end[0].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
+ sp->sos_end[0].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
+ sp->readheader_done=1;
+ return(1);
+}
+
+static int
+OJPEGReadSecondarySos(TIFF* tif, uint16 s)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ assert(s>0);
+ assert(s<3);
+ assert(sp->sos_end[0].log!=0);
+ assert(sp->sos_end[s].log==0);
+ sp->plane_sample_offset=s-1;
+ while(sp->sos_end[sp->plane_sample_offset].log==0)
+ sp->plane_sample_offset--;
+ sp->in_buffer_source=sp->sos_end[sp->plane_sample_offset].in_buffer_source;
+ sp->in_buffer_next_strile=sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile;
+ sp->in_buffer_file_pos=sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos;
+ sp->in_buffer_file_pos_log=0;
+ sp->in_buffer_file_togo=sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo;
+ sp->in_buffer_togo=0;
+ sp->in_buffer_cur=0;
+ while(sp->plane_sample_offset<s)
+ {
+ do
+ {
+ if (OJPEGReadByte(sp,&m)==0)
+ return(0);
+ if (m==255)
+ {
+ do
+ {
+ if (OJPEGReadByte(sp,&m)==0)
+ return(0);
+ if (m!=255)
+ break;
+ } while(1);
+ if (m==JPEG_MARKER_SOS)
+ break;
+ }
+ } while(1);
+ sp->plane_sample_offset++;
+ if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
+ return(0);
+ sp->sos_end[sp->plane_sample_offset].log=1;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_source=sp->in_buffer_source;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_next_strile=sp->in_buffer_next_strile;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_file_pos=sp->in_buffer_file_pos-sp->in_buffer_togo;
+ sp->sos_end[sp->plane_sample_offset].in_buffer_file_togo=sp->in_buffer_file_togo+sp->in_buffer_togo;
+ }
+ return(1);
+}
+
+static int
+OJPEGWriteHeaderInfo(TIFF* tif)
+{
+ static const char module[]="OJPEGWriteHeaderInfo";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8** m;
+ uint32 n;
+ /* if a previous attempt failed, don't try again */
+ if (sp->libjpeg_session_active != 0)
+ return 0;
+ sp->out_state=ososSoi;
+ sp->restart_index=0;
+ jpeg_std_error(&(sp->libjpeg_jpeg_error_mgr));
+ sp->libjpeg_jpeg_error_mgr.output_message=OJPEGLibjpegJpegErrorMgrOutputMessage;
+ sp->libjpeg_jpeg_error_mgr.error_exit=OJPEGLibjpegJpegErrorMgrErrorExit;
+ sp->libjpeg_jpeg_decompress_struct.err=&(sp->libjpeg_jpeg_error_mgr);
+ sp->libjpeg_jpeg_decompress_struct.client_data=(void*)tif;
+ if (jpeg_create_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
+ return(0);
+ sp->libjpeg_session_active=1;
+ sp->libjpeg_jpeg_source_mgr.bytes_in_buffer=0;
+ sp->libjpeg_jpeg_source_mgr.init_source=OJPEGLibjpegJpegSourceMgrInitSource;
+ sp->libjpeg_jpeg_source_mgr.fill_input_buffer=OJPEGLibjpegJpegSourceMgrFillInputBuffer;
+ sp->libjpeg_jpeg_source_mgr.skip_input_data=OJPEGLibjpegJpegSourceMgrSkipInputData;
+ sp->libjpeg_jpeg_source_mgr.resync_to_restart=OJPEGLibjpegJpegSourceMgrResyncToRestart;
+ sp->libjpeg_jpeg_source_mgr.term_source=OJPEGLibjpegJpegSourceMgrTermSource;
+ sp->libjpeg_jpeg_decompress_struct.src=&(sp->libjpeg_jpeg_source_mgr);
+ if (jpeg_read_header_encap(sp,&(sp->libjpeg_jpeg_decompress_struct),1)==0)
+ return(0);
+ if ((sp->subsampling_force_desubsampling_inside_decompression==0) && (sp->samples_per_pixel_per_plane>1))
+ {
+ sp->libjpeg_jpeg_decompress_struct.raw_data_out=1;
+#if JPEG_LIB_VERSION >= 70
+ sp->libjpeg_jpeg_decompress_struct.do_fancy_upsampling=FALSE;
+#endif
+ sp->libjpeg_jpeg_query_style=0;
+ if (sp->subsampling_convert_log==0)
+ {
+ assert(sp->subsampling_convert_ycbcrbuf==0);
+ assert(sp->subsampling_convert_ycbcrimage==0);
+ sp->subsampling_convert_ylinelen=((sp->strile_width+sp->subsampling_hor*8-1)/(sp->subsampling_hor*8)*sp->subsampling_hor*8);
+ sp->subsampling_convert_ylines=sp->subsampling_ver*8;
+ sp->subsampling_convert_clinelen=sp->subsampling_convert_ylinelen/sp->subsampling_hor;
+ sp->subsampling_convert_clines=8;
+ sp->subsampling_convert_ybuflen=sp->subsampling_convert_ylinelen*sp->subsampling_convert_ylines;
+ sp->subsampling_convert_cbuflen=sp->subsampling_convert_clinelen*sp->subsampling_convert_clines;
+ sp->subsampling_convert_ycbcrbuflen=sp->subsampling_convert_ybuflen+2*sp->subsampling_convert_cbuflen;
+ sp->subsampling_convert_ycbcrbuf = (uint8*)_TIFFmalloc(sp->subsampling_convert_ycbcrbuflen); // add (uint8*) cast
+ if (sp->subsampling_convert_ycbcrbuf==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ sp->subsampling_convert_ybuf=sp->subsampling_convert_ycbcrbuf;
+ sp->subsampling_convert_cbbuf=sp->subsampling_convert_ybuf+sp->subsampling_convert_ybuflen;
+ sp->subsampling_convert_crbuf=sp->subsampling_convert_cbbuf+sp->subsampling_convert_cbuflen;
+ sp->subsampling_convert_ycbcrimagelen=3+sp->subsampling_convert_ylines+2*sp->subsampling_convert_clines;
+ sp->subsampling_convert_ycbcrimage = (uint8**)_TIFFmalloc(sp->subsampling_convert_ycbcrimagelen * sizeof(uint8*));// add (uint8**) cast
+ if (sp->subsampling_convert_ycbcrimage==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ m=sp->subsampling_convert_ycbcrimage;
+ *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3);
+ *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines);
+ *m++=(uint8*)(sp->subsampling_convert_ycbcrimage+3+sp->subsampling_convert_ylines+sp->subsampling_convert_clines);
+ for (n=0; n<sp->subsampling_convert_ylines; n++)
+ *m++=sp->subsampling_convert_ybuf+n*sp->subsampling_convert_ylinelen;
+ for (n=0; n<sp->subsampling_convert_clines; n++)
+ *m++=sp->subsampling_convert_cbbuf+n*sp->subsampling_convert_clinelen;
+ for (n=0; n<sp->subsampling_convert_clines; n++)
+ *m++=sp->subsampling_convert_crbuf+n*sp->subsampling_convert_clinelen;
+ sp->subsampling_convert_clinelenout=((sp->strile_width+sp->subsampling_hor-1)/sp->subsampling_hor);
+ sp->subsampling_convert_state=0;
+ sp->bytes_per_line=sp->subsampling_convert_clinelenout*(sp->subsampling_ver*sp->subsampling_hor+2);
+ sp->lines_per_strile=((sp->strile_length+sp->subsampling_ver-1)/sp->subsampling_ver);
+ sp->subsampling_convert_log=1;
+ }
+ }
+ else
+ {
+ sp->libjpeg_jpeg_decompress_struct.jpeg_color_space=JCS_UNKNOWN;
+ sp->libjpeg_jpeg_decompress_struct.out_color_space=JCS_UNKNOWN;
+ sp->libjpeg_jpeg_query_style=1;
+ sp->bytes_per_line=sp->samples_per_pixel_per_plane*sp->strile_width;
+ sp->lines_per_strile=sp->strile_length;
+ }
+ if (jpeg_start_decompress_encap(sp,&(sp->libjpeg_jpeg_decompress_struct))==0)
+ return(0);
+ sp->writeheader_done=1;
+ return(1);
+}
+
+static void
+OJPEGLibjpegSessionAbort(TIFF* tif)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ assert(sp->libjpeg_session_active!=0);
+ jpeg_destroy((jpeg_common_struct*)(&(sp->libjpeg_jpeg_decompress_struct)));
+ sp->libjpeg_session_active=0;
+}
+
+static int
+OJPEGReadHeaderInfoSec(TIFF* tif)
+{
+ static const char module[]="OJPEGReadHeaderInfoSec";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ uint16 n;
+ uint8 o;
+ if (sp->file_size==0)
+ sp->file_size=TIFFGetFileSize(tif);
+ if (sp->jpeg_interchange_format!=0)
+ {
+ if (sp->jpeg_interchange_format>=sp->file_size)
+ {
+ sp->jpeg_interchange_format=0;
+ sp->jpeg_interchange_format_length=0;
+ }
+ else
+ {
+ if ((sp->jpeg_interchange_format_length==0) || (sp->jpeg_interchange_format+sp->jpeg_interchange_format_length>sp->file_size))
+ sp->jpeg_interchange_format_length=sp->file_size-sp->jpeg_interchange_format;
+ }
+ }
+ sp->in_buffer_source=osibsNotSetYet;
+ sp->in_buffer_next_strile=0;
+ sp->in_buffer_strile_count=tif->tif_dir.td_nstrips;
+ sp->in_buffer_file_togo=0;
+ sp->in_buffer_togo=0;
+ do
+ {
+ if (OJPEGReadBytePeek(sp,&m)==0)
+ return(0);
+ if (m!=255)
+ break;
+ OJPEGReadByteAdvance(sp);
+ do
+ {
+ if (OJPEGReadByte(sp,&m)==0)
+ return(0);
+ } while(m==255);
+ switch(m)
+ {
+ case JPEG_MARKER_SOI:
+ /* this type of marker has no data, and should be skipped */
+ break;
+ case JPEG_MARKER_COM:
+ case JPEG_MARKER_APP0:
+ case JPEG_MARKER_APP0+1:
+ case JPEG_MARKER_APP0+2:
+ case JPEG_MARKER_APP0+3:
+ case JPEG_MARKER_APP0+4:
+ case JPEG_MARKER_APP0+5:
+ case JPEG_MARKER_APP0+6:
+ case JPEG_MARKER_APP0+7:
+ case JPEG_MARKER_APP0+8:
+ case JPEG_MARKER_APP0+9:
+ case JPEG_MARKER_APP0+10:
+ case JPEG_MARKER_APP0+11:
+ case JPEG_MARKER_APP0+12:
+ case JPEG_MARKER_APP0+13:
+ case JPEG_MARKER_APP0+14:
+ case JPEG_MARKER_APP0+15:
+ /* this type of marker has data, but it has no use to us (and no place here) and should be skipped */
+ if (OJPEGReadWord(sp,&n)==0)
+ return(0);
+ if (n<2)
+ {
+ if (sp->subsamplingcorrect==0)
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
+ return(0);
+ }
+ if (n>2)
+ OJPEGReadSkip(sp,n-2);
+ break;
+ case JPEG_MARKER_DRI:
+ if (OJPEGReadHeaderInfoSecStreamDri(tif)==0)
+ return(0);
+ break;
+ case JPEG_MARKER_DQT:
+ if (OJPEGReadHeaderInfoSecStreamDqt(tif)==0)
+ return(0);
+ break;
+ case JPEG_MARKER_DHT:
+ if (OJPEGReadHeaderInfoSecStreamDht(tif)==0)
+ return(0);
+ break;
+ case JPEG_MARKER_SOF0:
+ case JPEG_MARKER_SOF1:
+ case JPEG_MARKER_SOF3:
+ if (OJPEGReadHeaderInfoSecStreamSof(tif,m)==0)
+ return(0);
+ if (sp->subsamplingcorrect!=0)
+ return(1);
+ break;
+ case JPEG_MARKER_SOS:
+ if (sp->subsamplingcorrect!=0)
+ return(1);
+ assert(sp->plane_sample_offset==0);
+ if (OJPEGReadHeaderInfoSecStreamSos(tif)==0)
+ return(0);
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata,module,"Unknown marker type %d in JPEG data",m);
+ return(0);
+ }
+ } while(m!=JPEG_MARKER_SOS);
+ if (sp->subsamplingcorrect)
+ return(1);
+ if (sp->sof_log==0)
+ {
+ if (OJPEGReadHeaderInfoSecTablesQTable(tif)==0)
+ return(0);
+ sp->sof_marker_id=JPEG_MARKER_SOF0;
+ for (o=0; o<sp->samples_per_pixel; o++)
+ sp->sof_c[o]=o;
+ sp->sof_hv[0]=((sp->subsampling_hor<<4)|sp->subsampling_ver);
+ for (o=1; o<sp->samples_per_pixel; o++)
+ sp->sof_hv[o]=17;
+ sp->sof_x=sp->strile_width;
+ sp->sof_y=sp->strile_length_total;
+ sp->sof_log=1;
+ if (OJPEGReadHeaderInfoSecTablesDcTable(tif)==0)
+ return(0);
+ if (OJPEGReadHeaderInfoSecTablesAcTable(tif)==0)
+ return(0);
+ for (o=1; o<sp->samples_per_pixel; o++)
+ sp->sos_cs[o]=o;
+ }
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamDri(TIFF* tif)
+{
+ /* this could easilly cause trouble in some cases... but no such cases have occured sofar */
+ static const char module[]="OJPEGReadHeaderInfoSecStreamDri";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint16 m;
+ if (OJPEGReadWord(sp,&m)==0)
+ return(0);
+ if (m!=4)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DRI marker in JPEG data");
+ return(0);
+ }
+ if (OJPEGReadWord(sp,&m)==0)
+ return(0);
+ sp->restart_interval=m;
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamDqt(TIFF* tif)
+{
+ /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
+ static const char module[]="OJPEGReadHeaderInfoSecStreamDqt";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint16 m;
+ uint32 na;
+ uint8* nb;
+ uint8 o;
+ if (OJPEGReadWord(sp,&m)==0)
+ return(0);
+ if (m<=2)
+ {
+ if (sp->subsamplingcorrect==0)
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
+ return(0);
+ }
+ if (sp->subsamplingcorrect!=0)
+ OJPEGReadSkip(sp,m-2);
+ else
+ {
+ m-=2;
+ do
+ {
+ if (m<65)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
+ return(0);
+ }
+ na = sizeof(uint32) + 69;
+ nb = (uint8*)_TIFFmalloc(na); // add (uint8*) cast
+ if (nb == 0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ *(uint32*)nb=na;
+ nb[sizeof(uint32)]=255;
+ nb[sizeof(uint32)+1]=JPEG_MARKER_DQT;
+ nb[sizeof(uint32)+2]=0;
+ nb[sizeof(uint32)+3]=67;
+ if (OJPEGReadBlock(sp,65,&nb[sizeof(uint32)+4])==0) {
+ _TIFFfree(nb);
+ return(0);
+ }
+ o=nb[sizeof(uint32)+4]&15;
+ if (3<o)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DQT marker in JPEG data");
+ _TIFFfree(nb);
+ return(0);
+ }
+ if (sp->qtable[o]!=0)
+ _TIFFfree(sp->qtable[o]);
+ sp->qtable[o]=nb;
+ m-=65;
+ } while(m>0);
+ }
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamDht(TIFF* tif)
+{
+ /* this is a table marker, and it is to be saved as a whole for exact pushing on the jpeg stream later on */
+ /* TODO: the following assumes there is only one table in this marker... but i'm not quite sure that assumption is guaranteed correct */
+ static const char module[]="OJPEGReadHeaderInfoSecStreamDht";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint16 m;
+ uint32 na;
+ uint8* nb;
+ uint8 o;
+ if (OJPEGReadWord(sp,&m)==0)
+ return(0);
+ if (m<=2)
+ {
+ if (sp->subsamplingcorrect==0)
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+ return(0);
+ }
+ if (sp->subsamplingcorrect!=0)
+ {
+ OJPEGReadSkip(sp,m-2);
+ }
+ else
+ {
+ na = sizeof(uint32) + 2 + m;
+ nb = (uint8*)_TIFFmalloc(na); // add (uint8*) cast
+ if (nb == 0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ *(uint32*)nb=na;
+ nb[sizeof(uint32)]=255;
+ nb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
+ nb[sizeof(uint32)+2]=(m>>8);
+ nb[sizeof(uint32)+3]=(m&255);
+ if (OJPEGReadBlock(sp,m-2,&nb[sizeof(uint32)+4])==0)
+ return(0);
+ o=nb[sizeof(uint32)+4];
+ if ((o&240)==0)
+ {
+ if (3<o)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+ return(0);
+ }
+ if (sp->dctable[o]!=0)
+ _TIFFfree(sp->dctable[o]);
+ sp->dctable[o]=nb;
+ }
+ else
+ {
+ if ((o&240)!=16)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+ return(0);
+ }
+ o&=15;
+ if (3<o)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt DHT marker in JPEG data");
+ return(0);
+ }
+ if (sp->actable[o]!=0)
+ _TIFFfree(sp->actable[o]);
+ sp->actable[o]=nb;
+ }
+ }
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamSof(TIFF* tif, uint8 marker_id)
+{
+ /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
+ static const char module[]="OJPEGReadHeaderInfoSecStreamSof";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint16 m;
+ uint16 n;
+ uint8 o;
+ uint16 p;
+ uint16 q;
+ if (sp->sof_log!=0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JPEG data");
+ return(0);
+ }
+ if (sp->subsamplingcorrect==0)
+ sp->sof_marker_id=marker_id;
+ /* Lf: data length */
+ if (OJPEGReadWord(sp,&m)==0)
+ return(0);
+ if (m<11)
+ {
+ if (sp->subsamplingcorrect==0)
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
+ return(0);
+ }
+ m-=8;
+ if (m%3!=0)
+ {
+ if (sp->subsamplingcorrect==0)
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
+ return(0);
+ }
+ n=m/3;
+ if (sp->subsamplingcorrect==0)
+ {
+ if (n!=sp->samples_per_pixel)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of samples");
+ return(0);
+ }
+ }
+ /* P: Sample precision */
+ if (OJPEGReadByte(sp,&o)==0)
+ return(0);
+ if (o!=8)
+ {
+ if (sp->subsamplingcorrect==0)
+ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected number of bits per sample");
+ return(0);
+ }
+ /* Y: Number of lines, X: Number of samples per line */
+ if (sp->subsamplingcorrect)
+ OJPEGReadSkip(sp,4);
+ else
+ {
+ /* Y: Number of lines */
+ if (OJPEGReadWord(sp,&p)==0)
+ return(0);
+ if (((uint32)p<sp->image_length) && ((uint32)p<sp->strile_length_total))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected height");
+ return(0);
+ }
+ sp->sof_y=p;
+ /* X: Number of samples per line */
+ if (OJPEGReadWord(sp,&p)==0)
+ return(0);
+ if (((uint32)p<sp->image_width) && ((uint32)p<sp->strile_width))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected width");
+ return(0);
+ }
+ if ((uint32)p>sp->strile_width)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data image width exceeds expected image width");
+ return(0);
+ }
+ sp->sof_x=p;
+ }
+ /* Nf: Number of image components in frame */
+ if (OJPEGReadByte(sp,&o)==0)
+ return(0);
+ if (o!=n)
+ {
+ if (sp->subsamplingcorrect==0)
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOF marker in JPEG data");
+ return(0);
+ }
+ /* per component stuff */
+ /* TODO: double-check that flow implies that n cannot be as big as to make us overflow sof_c, sof_hv and sof_tq arrays */
+ for (q=0; q<n; q++)
+ {
+ /* C: Component identifier */
+ if (OJPEGReadByte(sp,&o)==0)
+ return(0);
+ if (sp->subsamplingcorrect==0)
+ sp->sof_c[q]=o;
+ /* H: Horizontal sampling factor, and V: Vertical sampling factor */
+ if (OJPEGReadByte(sp,&o)==0)
+ return(0);
+ if (sp->subsamplingcorrect!=0)
+ {
+ if (q==0)
+ {
+ sp->subsampling_hor=(o>>4);
+ sp->subsampling_ver=(o&15);
+ if (((sp->subsampling_hor!=1) && (sp->subsampling_hor!=2) && (sp->subsampling_hor!=4)) ||
+ ((sp->subsampling_ver!=1) && (sp->subsampling_ver!=2) && (sp->subsampling_ver!=4)))
+ sp->subsampling_force_desubsampling_inside_decompression=1;
+ }
+ else
+ {
+ if (o!=17)
+ sp->subsampling_force_desubsampling_inside_decompression=1;
+ }
+ }
+ else
+ {
+ sp->sof_hv[q]=o;
+ if (sp->subsampling_force_desubsampling_inside_decompression==0)
+ {
+ if (q==0)
+ {
+ if (o!=((sp->subsampling_hor<<4)|sp->subsampling_ver))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
+ return(0);
+ }
+ }
+ else
+ {
+ if (o!=17)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"JPEG compressed data indicates unexpected subsampling values");
+ return(0);
+ }
+ }
+ }
+ }
+ /* Tq: Quantization table destination selector */
+ if (OJPEGReadByte(sp,&o)==0)
+ return(0);
+ if (sp->subsamplingcorrect==0)
+ sp->sof_tq[q]=o;
+ }
+ if (sp->subsamplingcorrect==0)
+ sp->sof_log=1;
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecStreamSos(TIFF* tif)
+{
+ /* this marker needs to be checked, and part of its data needs to be saved for regeneration later on */
+ static const char module[]="OJPEGReadHeaderInfoSecStreamSos";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint16 m;
+ uint8 n;
+ uint8 o;
+ assert(sp->subsamplingcorrect==0);
+ if (sp->sof_log==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
+ return(0);
+ }
+ /* Ls */
+ if (OJPEGReadWord(sp,&m)==0)
+ return(0);
+ if (m!=6+sp->samples_per_pixel_per_plane*2)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
+ return(0);
+ }
+ /* Ns */
+ if (OJPEGReadByte(sp,&n)==0)
+ return(0);
+ if (n!=sp->samples_per_pixel_per_plane)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt SOS marker in JPEG data");
+ return(0);
+ }
+ /* Cs, Td, and Ta */
+ for (o=0; o<sp->samples_per_pixel_per_plane; o++)
+ {
+ /* Cs */
+ if (OJPEGReadByte(sp,&n)==0)
+ return(0);
+ sp->sos_cs[sp->plane_sample_offset+o]=n;
+ /* Td and Ta */
+ if (OJPEGReadByte(sp,&n)==0)
+ return(0);
+ sp->sos_tda[sp->plane_sample_offset+o]=n;
+ }
+ /* skip Ss, Se, Ah, en Al -> no check, as per Tom Lane recommendation, as per LibJpeg source */
+ OJPEGReadSkip(sp,3);
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecTablesQTable(TIFF* tif)
+{
+ static const char module[]="OJPEGReadHeaderInfoSecTablesQTable";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ uint8 n;
+ uint32 oa;
+ uint8* ob;
+ uint32 p;
+ if (sp->qtable_offset[0]==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
+ return(0);
+ }
+ sp->in_buffer_file_pos_log=0;
+ for (m=0; m<sp->samples_per_pixel; m++)
+ {
+ if ((sp->qtable_offset[m]!=0) && ((m==0) || (sp->qtable_offset[m]!=sp->qtable_offset[m-1])))
+ {
+ for (n=0; n<m-1; n++)
+ {
+ if (sp->qtable_offset[m]==sp->qtable_offset[n])
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegQTables tag value");
+ return(0);
+ }
+ }
+ oa=sizeof(uint32)+69;
+ ob = (uint8*)_TIFFmalloc(oa); // add (uint8*) cast
+ if (ob==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ *(uint32*)ob=oa;
+ ob[sizeof(uint32)]=255;
+ ob[sizeof(uint32)+1]=JPEG_MARKER_DQT;
+ ob[sizeof(uint32)+2]=0;
+ ob[sizeof(uint32)+3]=67;
+ ob[sizeof(uint32)+4]=m;
+ TIFFSeekFile(tif,sp->qtable_offset[m],SEEK_SET);
+ p=(uint32)TIFFReadFile(tif,&ob[sizeof(uint32)+5],64);
+ if (p!=64)
+ return(0);
+ sp->qtable[m]=ob;
+ sp->sof_tq[m]=m;
+ }
+ else
+ sp->sof_tq[m]=sp->sof_tq[m-1];
+ }
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecTablesDcTable(TIFF* tif)
+{
+ static const char module[]="OJPEGReadHeaderInfoSecTablesDcTable";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ uint8 n;
+ uint8 o[16];
+ uint32 p;
+ uint32 q;
+ uint32 ra;
+ uint8* rb;
+ if (sp->dctable_offset[0]==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
+ return(0);
+ }
+ sp->in_buffer_file_pos_log=0;
+ for (m=0; m<sp->samples_per_pixel; m++)
+ {
+ if ((sp->dctable_offset[m]!=0) && ((m==0) || (sp->dctable_offset[m]!=sp->dctable_offset[m-1])))
+ {
+ for (n=0; n<m-1; n++)
+ {
+ if (sp->dctable_offset[m]==sp->dctable_offset[n])
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegDcTables tag value");
+ return(0);
+ }
+ }
+ TIFFSeekFile(tif,sp->dctable_offset[m],SEEK_SET);
+ p=(uint32)TIFFReadFile(tif,o,16);
+ if (p!=16)
+ return(0);
+ q=0;
+ for (n=0; n<16; n++)
+ q+=o[n];
+ ra=sizeof(uint32)+21+q;
+ rb = (uint8*)_TIFFmalloc(ra); // add (uint8*) cast
+ if (rb==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ *(uint32*)rb=ra;
+ rb[sizeof(uint32)]=255;
+ rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
+ rb[sizeof(uint32)+2]=((19+q)>>8);
+ rb[sizeof(uint32)+3]=((19+q)&255);
+ rb[sizeof(uint32)+4]=m;
+ for (n=0; n<16; n++)
+ rb[sizeof(uint32)+5+n]=o[n];
+ p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
+ if (p!=q)
+ return(0);
+ sp->dctable[m]=rb;
+ sp->sos_tda[m]=(m<<4);
+ }
+ else
+ sp->sos_tda[m]=sp->sos_tda[m-1];
+ }
+ return(1);
+}
+
+static int
+OJPEGReadHeaderInfoSecTablesAcTable(TIFF* tif)
+{
+ static const char module[]="OJPEGReadHeaderInfoSecTablesAcTable";
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ uint8 n;
+ uint8 o[16];
+ uint32 p;
+ uint32 q;
+ uint32 ra;
+ uint8* rb;
+ if (sp->actable_offset[0]==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Missing JPEG tables");
+ return(0);
+ }
+ sp->in_buffer_file_pos_log=0;
+ for (m=0; m<sp->samples_per_pixel; m++)
+ {
+ if ((sp->actable_offset[m]!=0) && ((m==0) || (sp->actable_offset[m]!=sp->actable_offset[m-1])))
+ {
+ for (n=0; n<m-1; n++)
+ {
+ if (sp->actable_offset[m]==sp->actable_offset[n])
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Corrupt JpegAcTables tag value");
+ return(0);
+ }
+ }
+ TIFFSeekFile(tif,sp->actable_offset[m],SEEK_SET);
+ p=(uint32)TIFFReadFile(tif,o,16);
+ if (p!=16)
+ return(0);
+ q=0;
+ for (n=0; n<16; n++)
+ q+=o[n];
+ ra=sizeof(uint32)+21+q;
+ rb = (uint8*)_TIFFmalloc(ra); // add (uint8*) cast
+ if (rb==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
+ return(0);
+ }
+ *(uint32*)rb=ra;
+ rb[sizeof(uint32)]=255;
+ rb[sizeof(uint32)+1]=JPEG_MARKER_DHT;
+ rb[sizeof(uint32)+2]=((19+q)>>8);
+ rb[sizeof(uint32)+3]=((19+q)&255);
+ rb[sizeof(uint32)+4]=(16|m);
+ for (n=0; n<16; n++)
+ rb[sizeof(uint32)+5+n]=o[n];
+ p=(uint32)TIFFReadFile(tif,&(rb[sizeof(uint32)+21]),q);
+ if (p!=q)
+ return(0);
+ sp->actable[m]=rb;
+ sp->sos_tda[m]=(sp->sos_tda[m]|m);
+ }
+ else
+ sp->sos_tda[m]=(sp->sos_tda[m]|(sp->sos_tda[m-1]&15));
+ }
+ return(1);
+}
+
+static int
+OJPEGReadBufferFill(OJPEGState* sp)
+{
+ uint16 m;
+ tmsize_t n;
+ /* TODO: double-check: when subsamplingcorrect is set, no call to TIFFErrorExt or TIFFWarningExt should be made
+ * in any other case, seek or read errors should be passed through */
+ do
+ {
+ if (sp->in_buffer_file_togo!=0)
+ {
+ if (sp->in_buffer_file_pos_log==0)
+ {
+ TIFFSeekFile(sp->tif,sp->in_buffer_file_pos,SEEK_SET);
+ sp->in_buffer_file_pos_log=1;
+ }
+ m=OJPEG_BUFFER;
+ if ((uint64)m>sp->in_buffer_file_togo)
+ m=(uint16)sp->in_buffer_file_togo;
+ n=TIFFReadFile(sp->tif,sp->in_buffer,(tmsize_t)m);
+ if (n==0)
+ return(0);
+ assert(n>0);
+ assert(n<=OJPEG_BUFFER);
+ assert(n<65536);
+ assert((uint64)n<=sp->in_buffer_file_togo);
+ m=(uint16)n;
+ sp->in_buffer_togo=m;
+ sp->in_buffer_cur=sp->in_buffer;
+ sp->in_buffer_file_togo-=m;
+ sp->in_buffer_file_pos+=m;
+ break;
+ }
+ sp->in_buffer_file_pos_log=0;
+ switch(sp->in_buffer_source)
+ {
+ case osibsNotSetYet:
+ if (sp->jpeg_interchange_format!=0)
+ {
+ sp->in_buffer_file_pos=sp->jpeg_interchange_format;
+ sp->in_buffer_file_togo=sp->jpeg_interchange_format_length;
+ }
+ sp->in_buffer_source=osibsJpegInterchangeFormat;
+ break;
+ case osibsJpegInterchangeFormat:
+ sp->in_buffer_source=osibsStrile;
+ case osibsStrile:
+ if (!_TIFFFillStriles( sp->tif )
+ || sp->tif->tif_dir.td_stripoffset == NULL
+ || sp->tif->tif_dir.td_stripbytecount == NULL)
+ return 0;
+
+ if (sp->in_buffer_next_strile==sp->in_buffer_strile_count)
+ sp->in_buffer_source=osibsEof;
+ else
+ {
+ sp->in_buffer_file_pos=sp->tif->tif_dir.td_stripoffset[sp->in_buffer_next_strile];
+ if (sp->in_buffer_file_pos!=0)
+ {
+ if (sp->in_buffer_file_pos>=sp->file_size)
+ sp->in_buffer_file_pos=0;
+ else if (sp->tif->tif_dir.td_stripbytecount==NULL)
+ sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
+ else
+ {
+ if (sp->tif->tif_dir.td_stripbytecount == 0) {
+ TIFFErrorExt(sp->tif->tif_clientdata,sp->tif->tif_name,"Strip byte counts are missing");
+ return(0);
+ }
+ sp->in_buffer_file_togo=sp->tif->tif_dir.td_stripbytecount[sp->in_buffer_next_strile];
+ if (sp->in_buffer_file_togo==0)
+ sp->in_buffer_file_pos=0;
+ else if (sp->in_buffer_file_pos+sp->in_buffer_file_togo>sp->file_size)
+ sp->in_buffer_file_togo=sp->file_size-sp->in_buffer_file_pos;
+ }
+ }
+ sp->in_buffer_next_strile++;
+ }
+ break;
+ default:
+ return(0);
+ }
+ } while (1);
+ return(1);
+}
+
+static int
+OJPEGReadByte(OJPEGState* sp, uint8* byte)
+{
+ if (sp->in_buffer_togo==0)
+ {
+ if (OJPEGReadBufferFill(sp)==0)
+ return(0);
+ assert(sp->in_buffer_togo>0);
+ }
+ *byte=*(sp->in_buffer_cur);
+ sp->in_buffer_cur++;
+ sp->in_buffer_togo--;
+ return(1);
+}
+
+static int
+OJPEGReadBytePeek(OJPEGState* sp, uint8* byte)
+{
+ if (sp->in_buffer_togo==0)
+ {
+ if (OJPEGReadBufferFill(sp)==0)
+ return(0);
+ assert(sp->in_buffer_togo>0);
+ }
+ *byte=*(sp->in_buffer_cur);
+ return(1);
+}
+
+static void
+OJPEGReadByteAdvance(OJPEGState* sp)
+{
+ assert(sp->in_buffer_togo>0);
+ sp->in_buffer_cur++;
+ sp->in_buffer_togo--;
+}
+
+static int
+OJPEGReadWord(OJPEGState* sp, uint16* word)
+{
+ uint8 m;
+ if (OJPEGReadByte(sp,&m)==0)
+ return(0);
+ *word=(m<<8);
+ if (OJPEGReadByte(sp,&m)==0)
+ return(0);
+ *word|=m;
+ return(1);
+}
+
+static int
+OJPEGReadBlock(OJPEGState* sp, uint16 len, void* mem)
+{
+ uint16 mlen;
+ uint8* mmem;
+ uint16 n;
+ assert(len>0);
+ mlen=len;
+ mmem = (uint8*)mem; // add (uint8*) cast
+ do
+ {
+ if (sp->in_buffer_togo==0)
+ {
+ if (OJPEGReadBufferFill(sp)==0)
+ return(0);
+ assert(sp->in_buffer_togo>0);
+ }
+ n=mlen;
+ if (n>sp->in_buffer_togo)
+ n=sp->in_buffer_togo;
+ _TIFFmemcpy(mmem,sp->in_buffer_cur,n);
+ sp->in_buffer_cur+=n;
+ sp->in_buffer_togo-=n;
+ mlen-=n;
+ mmem+=n;
+ } while(mlen>0);
+ return(1);
+}
+
+static void
+OJPEGReadSkip(OJPEGState* sp, uint16 len)
+{
+ uint16 m;
+ uint16 n;
+ m=len;
+ n=m;
+ if (n>sp->in_buffer_togo)
+ n=sp->in_buffer_togo;
+ sp->in_buffer_cur+=n;
+ sp->in_buffer_togo-=n;
+ m-=n;
+ if (m>0)
+ {
+ assert(sp->in_buffer_togo==0);
+ n=m;
+ if ((uint64)n>sp->in_buffer_file_togo)
+ n=(uint16)sp->in_buffer_file_togo;
+ sp->in_buffer_file_pos+=n;
+ sp->in_buffer_file_togo-=n;
+ sp->in_buffer_file_pos_log=0;
+ /* we don't skip past jpeginterchangeformat/strile block...
+ * if that is asked from us, we're dealing with totally bazurk
+ * data anyway, and we've not seen this happening on any
+ * testfile, so we might as well likely cause some other
+ * meaningless error to be passed at some later time
+ */
+ }
+}
+
+static int
+OJPEGWriteStream(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ *len=0;
+ do
+ {
+ assert(sp->out_state<=ososEoi);
+ switch(sp->out_state)
+ {
+ case ososSoi:
+ OJPEGWriteStreamSoi(tif,mem,len);
+ break;
+ case ososQTable0:
+ OJPEGWriteStreamQTable(tif,0,mem,len);
+ break;
+ case ososQTable1:
+ OJPEGWriteStreamQTable(tif,1,mem,len);
+ break;
+ case ososQTable2:
+ OJPEGWriteStreamQTable(tif,2,mem,len);
+ break;
+ case ososQTable3:
+ OJPEGWriteStreamQTable(tif,3,mem,len);
+ break;
+ case ososDcTable0:
+ OJPEGWriteStreamDcTable(tif,0,mem,len);
+ break;
+ case ososDcTable1:
+ OJPEGWriteStreamDcTable(tif,1,mem,len);
+ break;
+ case ososDcTable2:
+ OJPEGWriteStreamDcTable(tif,2,mem,len);
+ break;
+ case ososDcTable3:
+ OJPEGWriteStreamDcTable(tif,3,mem,len);
+ break;
+ case ososAcTable0:
+ OJPEGWriteStreamAcTable(tif,0,mem,len);
+ break;
+ case ososAcTable1:
+ OJPEGWriteStreamAcTable(tif,1,mem,len);
+ break;
+ case ososAcTable2:
+ OJPEGWriteStreamAcTable(tif,2,mem,len);
+ break;
+ case ososAcTable3:
+ OJPEGWriteStreamAcTable(tif,3,mem,len);
+ break;
+ case ososDri:
+ OJPEGWriteStreamDri(tif,mem,len);
+ break;
+ case ososSof:
+ OJPEGWriteStreamSof(tif,mem,len);
+ break;
+ case ososSos:
+ OJPEGWriteStreamSos(tif,mem,len);
+ break;
+ case ososCompressed:
+ if (OJPEGWriteStreamCompressed(tif,mem,len)==0)
+ return(0);
+ break;
+ case ososRst:
+ OJPEGWriteStreamRst(tif,mem,len);
+ break;
+ case ososEoi:
+ OJPEGWriteStreamEoi(tif,mem,len);
+ break;
+ }
+ } while (*len==0);
+ return(1);
+}
+
+static void
+OJPEGWriteStreamSoi(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ assert(OJPEG_BUFFER>=2);
+ sp->out_buffer[0]=255;
+ sp->out_buffer[1]=JPEG_MARKER_SOI;
+ *len=2;
+ *mem=(void*)sp->out_buffer;
+ sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamQTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ if (sp->qtable[table_index]!=0)
+ {
+ *mem=(void*)(sp->qtable[table_index]+sizeof(uint32));
+ *len=*((uint32*)sp->qtable[table_index])-sizeof(uint32);
+ }
+ sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamDcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ if (sp->dctable[table_index]!=0)
+ {
+ *mem=(void*)(sp->dctable[table_index]+sizeof(uint32));
+ *len=*((uint32*)sp->dctable[table_index])-sizeof(uint32);
+ }
+ sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamAcTable(TIFF* tif, uint8 table_index, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ if (sp->actable[table_index]!=0)
+ {
+ *mem=(void*)(sp->actable[table_index]+sizeof(uint32));
+ *len=*((uint32*)sp->actable[table_index])-sizeof(uint32);
+ }
+ sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamDri(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ assert(OJPEG_BUFFER>=6);
+ if (sp->restart_interval!=0)
+ {
+ sp->out_buffer[0]=255;
+ sp->out_buffer[1]=JPEG_MARKER_DRI;
+ sp->out_buffer[2]=0;
+ sp->out_buffer[3]=4;
+ sp->out_buffer[4]=(sp->restart_interval>>8);
+ sp->out_buffer[5]=(sp->restart_interval&255);
+ *len=6;
+ *mem=(void*)sp->out_buffer;
+ }
+ sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamSof(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ assert(OJPEG_BUFFER>=2+8+sp->samples_per_pixel_per_plane*3);
+ assert(255>=8+sp->samples_per_pixel_per_plane*3);
+ sp->out_buffer[0]=255;
+ sp->out_buffer[1]=sp->sof_marker_id;
+ /* Lf */
+ sp->out_buffer[2]=0;
+ sp->out_buffer[3]=8+sp->samples_per_pixel_per_plane*3;
+ /* P */
+ sp->out_buffer[4]=8;
+ /* Y */
+ sp->out_buffer[5]=(sp->sof_y>>8);
+ sp->out_buffer[6]=(sp->sof_y&255);
+ /* X */
+ sp->out_buffer[7]=(sp->sof_x>>8);
+ sp->out_buffer[8]=(sp->sof_x&255);
+ /* Nf */
+ sp->out_buffer[9]=sp->samples_per_pixel_per_plane;
+ for (m=0; m<sp->samples_per_pixel_per_plane; m++)
+ {
+ /* C */
+ sp->out_buffer[10+m*3]=sp->sof_c[sp->plane_sample_offset+m];
+ /* H and V */
+ sp->out_buffer[10+m*3+1]=sp->sof_hv[sp->plane_sample_offset+m];
+ /* Tq */
+ sp->out_buffer[10+m*3+2]=sp->sof_tq[sp->plane_sample_offset+m];
+ }
+ *len=10+sp->samples_per_pixel_per_plane*3;
+ *mem=(void*)sp->out_buffer;
+ sp->out_state++;
+}
+
+static void
+OJPEGWriteStreamSos(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ uint8 m;
+ assert(OJPEG_BUFFER>=2+6+sp->samples_per_pixel_per_plane*2);
+ assert(255>=6+sp->samples_per_pixel_per_plane*2);
+ sp->out_buffer[0]=255;
+ sp->out_buffer[1]=JPEG_MARKER_SOS;
+ /* Ls */
+ sp->out_buffer[2]=0;
+ sp->out_buffer[3]=6+sp->samples_per_pixel_per_plane*2;
+ /* Ns */
+ sp->out_buffer[4]=sp->samples_per_pixel_per_plane;
+ for (m=0; m<sp->samples_per_pixel_per_plane; m++)
+ {
+ /* Cs */
+ sp->out_buffer[5+m*2]=sp->sos_cs[sp->plane_sample_offset+m];
+ /* Td and Ta */
+ sp->out_buffer[5+m*2+1]=sp->sos_tda[sp->plane_sample_offset+m];
+ }
+ /* Ss */
+ sp->out_buffer[5+sp->samples_per_pixel_per_plane*2]=0;
+ /* Se */
+ sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+1]=63;
+ /* Ah and Al */
+ sp->out_buffer[5+sp->samples_per_pixel_per_plane*2+2]=0;
+ *len=8+sp->samples_per_pixel_per_plane*2;
+ *mem=(void*)sp->out_buffer;
+ sp->out_state++;
+}
+
+static int
+OJPEGWriteStreamCompressed(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ if (sp->in_buffer_togo==0)
+ {
+ if (OJPEGReadBufferFill(sp)==0)
+ return(0);
+ assert(sp->in_buffer_togo>0);
+ }
+ *len=sp->in_buffer_togo;
+ *mem=(void*)sp->in_buffer_cur;
+ sp->in_buffer_togo=0;
+ if (sp->in_buffer_file_togo==0)
+ {
+ switch(sp->in_buffer_source)
+ {
+ case osibsStrile:
+ if (sp->in_buffer_next_strile<sp->in_buffer_strile_count)
+ sp->out_state=ososRst;
+ else
+ sp->out_state=ososEoi;
+ break;
+ case osibsEof:
+ sp->out_state=ososEoi;
+ break;
+ default:
+ break;
+ }
+ }
+ return(1);
+}
+
+static void
+OJPEGWriteStreamRst(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ assert(OJPEG_BUFFER>=2);
+ sp->out_buffer[0]=255;
+ sp->out_buffer[1]=JPEG_MARKER_RST0+sp->restart_index;
+ sp->restart_index++;
+ if (sp->restart_index==8)
+ sp->restart_index=0;
+ *len=2;
+ *mem=(void*)sp->out_buffer;
+ sp->out_state=ososCompressed;
+}
+
+static void
+OJPEGWriteStreamEoi(TIFF* tif, void** mem, uint32* len)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ assert(OJPEG_BUFFER>=2);
+ sp->out_buffer[0]=255;
+ sp->out_buffer[1]=JPEG_MARKER_EOI;
+ *len=2;
+ *mem=(void*)sp->out_buffer;
+}
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_create_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
+{
+ return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_create_decompress(cinfo),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_read_header_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, uint8 require_image)
+{
+ return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_header(cinfo,require_image),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_start_decompress_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo)
+{
+ return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_start_decompress(cinfo),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_read_scanlines_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* scanlines, uint32 max_lines)
+{
+ return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_scanlines(cinfo,scanlines,max_lines),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static int
+jpeg_read_raw_data_encap(OJPEGState* sp, jpeg_decompress_struct* cinfo, void* data, uint32 max_lines)
+{
+ return(SETJMP(sp->exit_jmpbuf)?0:(jpeg_read_raw_data(cinfo,data,max_lines),1));
+}
+#endif
+
+#ifndef LIBJPEG_ENCAP_EXTERNAL
+static void
+jpeg_encap_unwind(TIFF* tif)
+{
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ LONGJMP(sp->exit_jmpbuf,1);
+}
+#endif
+
+static void
+OJPEGLibjpegJpegErrorMgrOutputMessage(jpeg_common_struct* cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+ (*cinfo->err->format_message)(cinfo,buffer);
+ TIFFWarningExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
+}
+
+static void
+OJPEGLibjpegJpegErrorMgrErrorExit(jpeg_common_struct* cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+ (*cinfo->err->format_message)(cinfo,buffer);
+ TIFFErrorExt(((TIFF*)(cinfo->client_data))->tif_clientdata,"LibJpeg","%s",buffer);
+ jpeg_encap_unwind((TIFF*)(cinfo->client_data));
+}
+
+static void
+OJPEGLibjpegJpegSourceMgrInitSource(jpeg_decompress_struct* cinfo)
+{
+ (void)cinfo;
+}
+
+static boolean
+OJPEGLibjpegJpegSourceMgrFillInputBuffer(jpeg_decompress_struct* cinfo)
+{
+ TIFF* tif=(TIFF*)cinfo->client_data;
+ OJPEGState* sp=(OJPEGState*)tif->tif_data;
+ void* mem=0;
+ uint32 len=0U;
+ if (OJPEGWriteStream(tif,&mem,&len)==0)
+ {
+ TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Premature end of JPEG data");
+ jpeg_encap_unwind(tif);
+ }
+ sp->libjpeg_jpeg_source_mgr.bytes_in_buffer = len;
+ sp->libjpeg_jpeg_source_mgr.next_input_byte = (const JOCTET * )mem; // add (const JOCTET * ) cast
+ return(1);
+}
+
+static void
+OJPEGLibjpegJpegSourceMgrSkipInputData(jpeg_decompress_struct* cinfo, long num_bytes)
+{
+ TIFF* tif=(TIFF*)cinfo->client_data;
+ (void)num_bytes;
+ TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
+ jpeg_encap_unwind(tif);
+}
+
+static boolean
+OJPEGLibjpegJpegSourceMgrResyncToRestart(jpeg_decompress_struct* cinfo, int desired)
+{
+ TIFF* tif=(TIFF*)cinfo->client_data;
+ (void)desired;
+ TIFFErrorExt(tif->tif_clientdata,"LibJpeg","Unexpected error");
+ jpeg_encap_unwind(tif);
+ return(0);
+}
+
+static void
+OJPEGLibjpegJpegSourceMgrTermSource(jpeg_decompress_struct* cinfo)
+{
+ (void)cinfo;
+}
+
+#endif
+
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif//#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_open.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_open.c
new file mode 100644
index 0000000000..95e8d1f8b9
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_open.c
@@ -0,0 +1,728 @@
+/* $Id: tif_open.c,v 1.46 2010-12-06 16:54:54 faxguy Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+/*
+ * Dummy functions to fill the omitted client procedures.
+ */
+static int
+_tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize)
+{
+ (void) fd; (void) pbase; (void) psize;
+ return (0);
+}
+
+static void
+_tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size)
+{
+ (void) fd; (void) base; (void) size;
+}
+
+int
+_TIFFgetMode(const char* mode, const char* module)
+{
+ int m = -1;
+
+ switch (mode[0]) {
+ case 'r':
+ m = O_RDONLY;
+ if (mode[1] == '+')
+ m = O_RDWR;
+ break;
+ case 'w':
+ case 'a':
+ m = O_RDWR|O_CREAT;
+ if (mode[0] == 'w')
+ m |= O_TRUNC;
+ break;
+ default:
+ TIFFErrorExt(0, module, "\"%s\": Bad mode", mode);
+ break;
+ }
+ return (m);
+}
+
+TIFF*
+TIFFClientOpen(
+ const char* name, const char* mode,
+ thandle_t clientdata,
+ TIFFReadWriteProc readproc,
+ TIFFReadWriteProc writeproc,
+ TIFFSeekProc seekproc,
+ TIFFCloseProc closeproc,
+ TIFFSizeProc sizeproc,
+ TIFFMapFileProc mapproc,
+ TIFFUnmapFileProc unmapproc
+)
+{
+ static const char module[] = "TIFFClientOpen";
+ TIFF *tif;
+ int m;
+ const char* cp;
+
+ /* The following are configuration checks. They should be redundant, but should not
+ * compile to any actual code in an optimised release build anyway. If any of them
+ * fail, (makefile-based or other) configuration is not correct */
+ assert(sizeof(uint8)==1);
+ assert(sizeof(int8)==1);
+ assert(sizeof(uint16)==2);
+ assert(sizeof(int16)==2);
+ assert(sizeof(uint32)==4);
+ assert(sizeof(int32)==4);
+ assert(sizeof(uint64)==8);
+ assert(sizeof(int64)==8);
+ assert(sizeof(tmsize_t)==sizeof(void*));
+ {
+ union{
+ uint8 a8[2];
+ uint16 a16;
+ } n;
+ n.a8[0]=1;
+ n.a8[1]=0;
+ #ifdef WORDS_BIGENDIAN
+ assert(n.a16==256);
+ #else
+ assert(n.a16==1);
+ #endif
+ }
+
+ m = _TIFFgetMode(mode, module);
+ if (m == -1)
+ goto bad2;
+ tif = (TIFF *)_TIFFmalloc((tmsize_t)(sizeof (TIFF) + strlen(name) + 1));
+ if (tif == NULL) {
+ TIFFErrorExt(clientdata, module, "%s: Out of memory (TIFF structure)", name);
+ goto bad2;
+ }
+ _TIFFmemset(tif, 0, sizeof (*tif));
+ tif->tif_name = (char *)tif + sizeof (TIFF);
+ strcpy(tif->tif_name, name);
+ tif->tif_mode = m &~ (O_CREAT|O_TRUNC);
+ tif->tif_curdir = (uint16) -1; /* non-existent directory */
+ tif->tif_curoff = 0;
+ tif->tif_curstrip = (uint32) -1; /* invalid strip */
+ tif->tif_row = (uint32) -1; /* read/write pre-increment */
+ tif->tif_clientdata = clientdata;
+ if (!readproc || !writeproc || !seekproc || !closeproc || !sizeproc) {
+ TIFFErrorExt(clientdata, module,
+ "One of the client procedures is NULL pointer.");
+ goto bad2;
+ }
+ tif->tif_readproc = readproc;
+ tif->tif_writeproc = writeproc;
+ tif->tif_seekproc = seekproc;
+ tif->tif_closeproc = closeproc;
+ tif->tif_sizeproc = sizeproc;
+ if (mapproc)
+ tif->tif_mapproc = mapproc;
+ else
+ tif->tif_mapproc = _tiffDummyMapProc;
+ if (unmapproc)
+ tif->tif_unmapproc = unmapproc;
+ else
+ tif->tif_unmapproc = _tiffDummyUnmapProc;
+ _TIFFSetDefaultCompressionState(tif); /* setup default state */
+ /*
+ * Default is to return data MSB2LSB and enable the
+ * use of memory-mapped files and strip chopping when
+ * a file is opened read-only.
+ */
+ tif->tif_flags = FILLORDER_MSB2LSB;
+ if (m == O_RDONLY )
+ tif->tif_flags |= TIFF_MAPPED;
+
+ #ifdef STRIPCHOP_DEFAULT
+ if (m == O_RDONLY || m == O_RDWR)
+ tif->tif_flags |= STRIPCHOP_DEFAULT;
+ #endif
+
+ /*
+ * Process library-specific flags in the open mode string.
+ * The following flags may be used to control intrinsic library
+ * behaviour that may or may not be desirable (usually for
+ * compatibility with some application that claims to support
+ * TIFF but only supports some braindead idea of what the
+ * vendor thinks TIFF is):
+ *
+ * 'l' use little-endian byte order for creating a file
+ * 'b' use big-endian byte order for creating a file
+ * 'L' read/write information using LSB2MSB bit order
+ * 'B' read/write information using MSB2LSB bit order
+ * 'H' read/write information using host bit order
+ * 'M' enable use of memory-mapped files when supported
+ * 'm' disable use of memory-mapped files
+ * 'C' enable strip chopping support when reading
+ * 'c' disable strip chopping support
+ * 'h' read TIFF header only, do not load the first IFD
+ * '4' ClassicTIFF for creating a file (default)
+ * '8' BigTIFF for creating a file
+ *
+ * The use of the 'l' and 'b' flags is strongly discouraged.
+ * These flags are provided solely because numerous vendors,
+ * typically on the PC, do not correctly support TIFF; they
+ * only support the Intel little-endian byte order. This
+ * support is not configured by default because it supports
+ * the violation of the TIFF spec that says that readers *MUST*
+ * support both byte orders. It is strongly recommended that
+ * you not use this feature except to deal with busted apps
+ * that write invalid TIFF. And even in those cases you should
+ * bang on the vendors to fix their software.
+ *
+ * The 'L', 'B', and 'H' flags are intended for applications
+ * that can optimize operations on data by using a particular
+ * bit order. By default the library returns data in MSB2LSB
+ * bit order for compatibiltiy with older versions of this
+ * library. Returning data in the bit order of the native cpu
+ * makes the most sense but also requires applications to check
+ * the value of the FillOrder tag; something they probably do
+ * not do right now.
+ *
+ * The 'M' and 'm' flags are provided because some virtual memory
+ * systems exhibit poor behaviour when large images are mapped.
+ * These options permit clients to control the use of memory-mapped
+ * files on a per-file basis.
+ *
+ * The 'C' and 'c' flags are provided because the library support
+ * for chopping up large strips into multiple smaller strips is not
+ * application-transparent and as such can cause problems. The 'c'
+ * option permits applications that only want to look at the tags,
+ * for example, to get the unadulterated TIFF tag information.
+ */
+ for (cp = mode; *cp; cp++)
+ switch (*cp) {
+ case 'b':
+ #ifndef WORDS_BIGENDIAN
+ if (m&O_CREAT)
+ tif->tif_flags |= TIFF_SWAB;
+ #endif
+ break;
+ case 'l':
+ #ifdef WORDS_BIGENDIAN
+ if ((m&O_CREAT))
+ tif->tif_flags |= TIFF_SWAB;
+ #endif
+ break;
+ case 'B':
+ tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
+ FILLORDER_MSB2LSB;
+ break;
+ case 'L':
+ tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
+ FILLORDER_LSB2MSB;
+ break;
+ case 'H':
+ tif->tif_flags = (tif->tif_flags &~ TIFF_FILLORDER) |
+ HOST_FILLORDER;
+ break;
+ case 'M':
+ if (m == O_RDONLY)
+ tif->tif_flags |= TIFF_MAPPED;
+ break;
+ case 'm':
+ if (m == O_RDONLY)
+ tif->tif_flags &= ~TIFF_MAPPED;
+ break;
+ case 'C':
+ if (m == O_RDONLY)
+ tif->tif_flags |= TIFF_STRIPCHOP;
+ break;
+ case 'c':
+ if (m == O_RDONLY)
+ tif->tif_flags &= ~TIFF_STRIPCHOP;
+ break;
+ case 'h':
+ tif->tif_flags |= TIFF_HEADERONLY;
+ break;
+ case '8':
+ if (m&O_CREAT)
+ tif->tif_flags |= TIFF_BIGTIFF;
+ break;
+ }
+ /*
+ * Read in TIFF header.
+ */
+ if ((m & O_TRUNC) ||
+ !ReadOK(tif, &tif->tif_header, sizeof (TIFFHeaderClassic))) {
+ if (tif->tif_mode == O_RDONLY) {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Cannot read TIFF header");
+ goto bad;
+ }
+ /*
+ * Setup header and write.
+ */
+ #ifdef WORDS_BIGENDIAN
+ tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
+ ? TIFF_LITTLEENDIAN : TIFF_BIGENDIAN;
+ #else
+ tif->tif_header.common.tiff_magic = tif->tif_flags & TIFF_SWAB
+ ? TIFF_BIGENDIAN : TIFF_LITTLEENDIAN;
+ #endif
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ {
+ tif->tif_header.common.tiff_version = TIFF_VERSION_CLASSIC;
+ tif->tif_header.classic.tiff_diroff = 0;
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&tif->tif_header.common.tiff_version);
+ tif->tif_header_size = sizeof(TIFFHeaderClassic);
+ }
+ else
+ {
+ tif->tif_header.common.tiff_version = TIFF_VERSION_BIG;
+ tif->tif_header.big.tiff_offsetsize = 8;
+ tif->tif_header.big.tiff_unused = 0;
+ tif->tif_header.big.tiff_diroff = 0;
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ TIFFSwabShort(&tif->tif_header.common.tiff_version);
+ TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
+ }
+ tif->tif_header_size = sizeof (TIFFHeaderBig);
+ }
+ /*
+ * The doc for "fopen" for some STD_C_LIBs says that if you
+ * open a file for modify ("+"), then you must fseek (or
+ * fflush?) between any freads and fwrites. This is not
+ * necessary on most systems, but has been shown to be needed
+ * on Solaris.
+ */
+ TIFFSeekFile( tif, 0, SEEK_SET );
+ if (!WriteOK(tif, &tif->tif_header, (tmsize_t)(tif->tif_header_size))) {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Error writing TIFF header");
+ goto bad;
+ }
+ /*
+ * Setup the byte order handling.
+ */
+ if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
+ #ifndef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+ #endif
+ } else {
+ #ifdef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+ #endif
+ }
+ /*
+ * Setup default directory.
+ */
+ if (!TIFFDefaultDirectory(tif))
+ goto bad;
+ tif->tif_diroff = 0;
+ tif->tif_dirlist = NULL;
+ tif->tif_dirlistsize = 0;
+ tif->tif_dirnumber = 0;
+ return (tif);
+ }
+ /*
+ * Setup the byte order handling.
+ */
+ if (tif->tif_header.common.tiff_magic != TIFF_BIGENDIAN &&
+ tif->tif_header.common.tiff_magic != TIFF_LITTLEENDIAN
+ #if MDI_SUPPORT
+ &&
+ #if HOST_BIGENDIAN
+ tif->tif_header.common.tiff_magic != MDI_BIGENDIAN
+ #else
+ tif->tif_header.common.tiff_magic != MDI_LITTLEENDIAN
+ #endif
+ ) {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Not a TIFF or MDI file, bad magic number %d (0x%x)",
+ #else
+ ) {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Not a TIFF file, bad magic number %d (0x%x)",
+ #endif
+ tif->tif_header.common.tiff_magic,
+ tif->tif_header.common.tiff_magic);
+ goto bad;
+ }
+ if (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN) {
+ #ifndef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+ #endif
+ } else {
+ #ifdef WORDS_BIGENDIAN
+ tif->tif_flags |= TIFF_SWAB;
+ #endif
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabShort(&tif->tif_header.common.tiff_version);
+ if ((tif->tif_header.common.tiff_version != TIFF_VERSION_CLASSIC)&&
+ (tif->tif_header.common.tiff_version != TIFF_VERSION_BIG)) {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Not a TIFF file, bad version number %d (0x%x)",
+ tif->tif_header.common.tiff_version,
+ tif->tif_header.common.tiff_version);
+ goto bad;
+ }
+ if (tif->tif_header.common.tiff_version == TIFF_VERSION_CLASSIC)
+ {
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabLong(&tif->tif_header.classic.tiff_diroff);
+ tif->tif_header_size = sizeof(TIFFHeaderClassic);
+ }
+ else
+ {
+ if (!ReadOK(tif, ((uint8*)(&tif->tif_header) + sizeof(TIFFHeaderClassic)), (sizeof(TIFFHeaderBig)-sizeof(TIFFHeaderClassic))))
+ {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Cannot read TIFF header");
+ goto bad;
+ }
+ if (tif->tif_flags & TIFF_SWAB)
+ {
+ TIFFSwabShort(&tif->tif_header.big.tiff_offsetsize);
+ TIFFSwabLong8(&tif->tif_header.big.tiff_diroff);
+ }
+ if (tif->tif_header.big.tiff_offsetsize != 8)
+ {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Not a TIFF file, bad BigTIFF offsetsize %d (0x%x)",
+ tif->tif_header.big.tiff_offsetsize,
+ tif->tif_header.big.tiff_offsetsize);
+ goto bad;
+ }
+ if (tif->tif_header.big.tiff_unused != 0)
+ {
+ TIFFErrorExt(tif->tif_clientdata, name,
+ "Not a TIFF file, bad BigTIFF unused %d (0x%x)",
+ tif->tif_header.big.tiff_unused,
+ tif->tif_header.big.tiff_unused);
+ goto bad;
+ }
+ tif->tif_header_size = sizeof(TIFFHeaderBig);
+ tif->tif_flags |= TIFF_BIGTIFF;
+ }
+ tif->tif_flags |= TIFF_MYBUFFER;
+ tif->tif_rawcp = tif->tif_rawdata = 0;
+ tif->tif_rawdatasize = 0;
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = 0;
+
+ switch (mode[0]) {
+ case 'r':
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ tif->tif_nextdiroff = tif->tif_header.classic.tiff_diroff;
+ else
+ tif->tif_nextdiroff = tif->tif_header.big.tiff_diroff;
+ /*
+ * Try to use a memory-mapped file if the client
+ * has not explicitly suppressed usage with the
+ * 'm' flag in the open mode (see above).
+ */
+ if (tif->tif_flags & TIFF_MAPPED)
+ {
+ toff_t n;
+ if (TIFFMapFileContents(tif,(void**)(&tif->tif_base),&n))
+ {
+ tif->tif_size=(tmsize_t)n;
+ assert((toff_t)tif->tif_size==n);
+ }
+ else
+ tif->tif_flags &= ~TIFF_MAPPED;
+ }
+ /*
+ * Sometimes we do not want to read the first directory (for example,
+ * it may be broken) and want to proceed to other directories. I this
+ * case we use the TIFF_HEADERONLY flag to open file and return
+ * immediately after reading TIFF header.
+ */
+ if (tif->tif_flags & TIFF_HEADERONLY)
+ return (tif);
+
+ /*
+ * Setup initial directory.
+ */
+ if (TIFFReadDirectory(tif)) {
+ tif->tif_rawcc = (tmsize_t)-1;
+ tif->tif_flags |= TIFF_BUFFERSETUP;
+ return (tif);
+ }
+ break;
+ case 'a':
+ /*
+ * New directories are automatically append
+ * to the end of the directory chain when they
+ * are written out (see TIFFWriteDirectory).
+ */
+ if (!TIFFDefaultDirectory(tif))
+ goto bad;
+ return (tif);
+ }
+bad:
+ tif->tif_mode = O_RDONLY; /* XXX avoid flush */
+ TIFFCleanup(tif);
+bad2:
+ return ((TIFF*)0);
+}
+
+/*
+ * Query functions to access private data.
+ */
+
+/*
+ * Return open file's name.
+ */
+const char *
+TIFFFileName(TIFF* tif)
+{
+ return (tif->tif_name);
+}
+
+/*
+ * Set the file name.
+ */
+const char *
+TIFFSetFileName(TIFF* tif, const char *name)
+{
+ const char* old_name = tif->tif_name;
+ tif->tif_name = (char *)name;
+ return (old_name);
+}
+
+/*
+ * Return open file's I/O descriptor.
+ */
+int
+TIFFFileno(TIFF* tif)
+{
+ return (tif->tif_fd);
+}
+
+/*
+ * Set open file's I/O descriptor, and return previous value.
+ */
+int
+TIFFSetFileno(TIFF* tif, int fd)
+{
+ int old_fd = tif->tif_fd;
+ tif->tif_fd = fd;
+ return old_fd;
+}
+
+/*
+ * Return open file's clientdata.
+ */
+thandle_t
+TIFFClientdata(TIFF* tif)
+{
+ return (tif->tif_clientdata);
+}
+
+/*
+ * Set open file's clientdata, and return previous value.
+ */
+thandle_t
+TIFFSetClientdata(TIFF* tif, thandle_t newvalue)
+{
+ thandle_t m = tif->tif_clientdata;
+ tif->tif_clientdata = newvalue;
+ return m;
+}
+
+/*
+ * Return read/write mode.
+ */
+int
+TIFFGetMode(TIFF* tif)
+{
+ return (tif->tif_mode);
+}
+
+/*
+ * Return read/write mode.
+ */
+int
+TIFFSetMode(TIFF* tif, int mode)
+{
+ int old_mode = tif->tif_mode;
+ tif->tif_mode = mode;
+ return (old_mode);
+}
+
+/*
+ * Return nonzero if file is organized in
+ * tiles; zero if organized as strips.
+ */
+int
+TIFFIsTiled(TIFF* tif)
+{
+ return (isTiled(tif));
+}
+
+/*
+ * Return current row being read/written.
+ */
+uint32
+TIFFCurrentRow(TIFF* tif)
+{
+ return (tif->tif_row);
+}
+
+/*
+ * Return index of the current directory.
+ */
+uint16
+TIFFCurrentDirectory(TIFF* tif)
+{
+ return (tif->tif_curdir);
+}
+
+/*
+ * Return current strip.
+ */
+uint32
+TIFFCurrentStrip(TIFF* tif)
+{
+ return (tif->tif_curstrip);
+}
+
+/*
+ * Return current tile.
+ */
+uint32
+TIFFCurrentTile(TIFF* tif)
+{
+ return (tif->tif_curtile);
+}
+
+/*
+ * Return nonzero if the file has byte-swapped data.
+ */
+int
+TIFFIsByteSwapped(TIFF* tif)
+{
+ return ((tif->tif_flags & TIFF_SWAB) != 0);
+}
+
+/*
+ * Return nonzero if the data is returned up-sampled.
+ */
+int
+TIFFIsUpSampled(TIFF* tif)
+{
+ return (isUpSampled(tif));
+}
+
+/*
+ * Return nonzero if the data is returned in MSB-to-LSB bit order.
+ */
+int
+TIFFIsMSB2LSB(TIFF* tif)
+{
+ return (isFillOrder(tif, FILLORDER_MSB2LSB));
+}
+
+/*
+ * Return nonzero if given file was written in big-endian order.
+ */
+int
+TIFFIsBigEndian(TIFF* tif)
+{
+ return (tif->tif_header.common.tiff_magic == TIFF_BIGENDIAN);
+}
+
+/*
+ * Return pointer to file read method.
+ */
+TIFFReadWriteProc
+TIFFGetReadProc(TIFF* tif)
+{
+ return (tif->tif_readproc);
+}
+
+/*
+ * Return pointer to file write method.
+ */
+TIFFReadWriteProc
+TIFFGetWriteProc(TIFF* tif)
+{
+ return (tif->tif_writeproc);
+}
+
+/*
+ * Return pointer to file seek method.
+ */
+TIFFSeekProc
+TIFFGetSeekProc(TIFF* tif)
+{
+ return (tif->tif_seekproc);
+}
+
+/*
+ * Return pointer to file close method.
+ */
+TIFFCloseProc
+TIFFGetCloseProc(TIFF* tif)
+{
+ return (tif->tif_closeproc);
+}
+
+/*
+ * Return pointer to file size requesting method.
+ */
+TIFFSizeProc
+TIFFGetSizeProc(TIFF* tif)
+{
+ return (tif->tif_sizeproc);
+}
+
+/*
+ * Return pointer to memory mapping method.
+ */
+TIFFMapFileProc
+TIFFGetMapFileProc(TIFF* tif)
+{
+ return (tif->tif_mapproc);
+}
+
+/*
+ * Return pointer to memory unmapping method.
+ */
+TIFFUnmapFileProc
+TIFFGetUnmapFileProc(TIFF* tif)
+{
+ return (tif->tif_unmapproc);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_packbits.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_packbits.c
new file mode 100644
index 0000000000..6fb517f7e5
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_packbits.c
@@ -0,0 +1,302 @@
+/* $Id: tif_packbits.c,v 1.22 2012-06-20 05:25:33 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#ifdef PACKBITS_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * PackBits Compression Algorithm Support
+ */
+#include <stdio.h>
+
+static int
+PackBitsPreEncode(TIFF* tif, uint16 s)
+{
+ (void) s;
+
+ if (!(tif->tif_data = (uint8*)_TIFFmalloc(sizeof(tmsize_t))))
+ return (0);
+ /*
+ * Calculate the scanline/tile-width size in bytes.
+ */
+ if (isTiled(tif))
+ *(tmsize_t*)tif->tif_data = TIFFTileRowSize(tif);
+ else
+ *(tmsize_t*)tif->tif_data = TIFFScanlineSize(tif);
+ return (1);
+}
+
+static int
+PackBitsPostEncode(TIFF* tif)
+{
+ if (tif->tif_data)
+ _TIFFfree(tif->tif_data);
+ return (1);
+}
+
+/*
+ * Encode a run of pixels.
+ */
+static int
+PackBitsEncode(TIFF* tif, uint8* buf, tmsize_t cc, uint16 s)
+{
+ unsigned char* bp = (unsigned char*) buf;
+ uint8* op;
+ uint8* ep;
+ uint8* lastliteral;
+ long n, slop;
+ int b;
+ enum { BASE, LITERAL, RUN, LITERAL_RUN } state;
+
+ (void) s;
+ op = tif->tif_rawcp;
+ ep = tif->tif_rawdata + tif->tif_rawdatasize;
+ state = BASE;
+ lastliteral = 0;
+ while (cc > 0) {
+ /*
+ * Find the longest string of identical bytes.
+ */
+ b = *bp++, cc--, n = 1;
+ for (; cc > 0 && b == *bp; cc--, bp++)
+ n++;
+ again:
+ if (op + 2 >= ep) { /* insure space for new data */
+ /*
+ * Be careful about writing the last
+ * literal. Must write up to that point
+ * and then copy the remainder to the
+ * front of the buffer.
+ */
+ if (state == LITERAL || state == LITERAL_RUN) {
+ slop = (long)(op - lastliteral);
+ tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
+ if (!TIFFFlushData1(tif))
+ return (-1);
+ op = tif->tif_rawcp;
+ while (slop-- > 0)
+ *op++ = *lastliteral++;
+ lastliteral = tif->tif_rawcp;
+ } else {
+ tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
+ if (!TIFFFlushData1(tif))
+ return (-1);
+ op = tif->tif_rawcp;
+ }
+ }
+ switch (state) {
+ case BASE: /* initial state, set run/literal */
+ if (n > 1) {
+ state = RUN;
+ if (n > 128) {
+ *op++ = (uint8) -127;
+ *op++ = (uint8) b;
+ n -= 128;
+ goto again;
+ }
+ *op++ = (uint8)(-(n-1));
+ *op++ = (uint8) b;
+ } else {
+ lastliteral = op;
+ *op++ = 0;
+ *op++ = (uint8) b;
+ state = LITERAL;
+ }
+ break;
+ case LITERAL: /* last object was literal string */
+ if (n > 1) {
+ state = LITERAL_RUN;
+ if (n > 128) {
+ *op++ = (uint8) -127;
+ *op++ = (uint8) b;
+ n -= 128;
+ goto again;
+ }
+ *op++ = (uint8)(-(n-1)); /* encode run */
+ *op++ = (uint8) b;
+ } else { /* extend literal */
+ if (++(*lastliteral) == 127)
+ state = BASE;
+ *op++ = (uint8) b;
+ }
+ break;
+ case RUN: /* last object was run */
+ if (n > 1) {
+ if (n > 128) {
+ *op++ = (uint8) -127;
+ *op++ = (uint8) b;
+ n -= 128;
+ goto again;
+ }
+ *op++ = (uint8)(-(n-1));
+ *op++ = (uint8) b;
+ } else {
+ lastliteral = op;
+ *op++ = 0;
+ *op++ = (uint8) b;
+ state = LITERAL;
+ }
+ break;
+ case LITERAL_RUN: /* literal followed by a run */
+ /*
+ * Check to see if previous run should
+ * be converted to a literal, in which
+ * case we convert literal-run-literal
+ * to a single literal.
+ */
+ if (n == 1 && op[-2] == (uint8) -1 &&
+ *lastliteral < 126) {
+ state = (((*lastliteral) += 2) == 127 ?
+ BASE : LITERAL);
+ op[-2] = op[-1]; /* replicate */
+ } else
+ state = RUN;
+ goto again;
+ }
+ }
+ tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
+ tif->tif_rawcp = op;
+ return (1);
+}
+
+/*
+ * Encode a rectangular chunk of pixels. We break it up
+ * into row-sized pieces to insure that encoded runs do
+ * not span rows. Otherwise, there can be problems with
+ * the decoder if data is read, for example, by scanlines
+ * when it was encoded by strips.
+ */
+static int
+PackBitsEncodeChunk(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ tmsize_t rowsize = *(tmsize_t*)tif->tif_data;
+
+ while (cc > 0) {
+ tmsize_t chunk = rowsize;
+
+ if( cc < chunk )
+ chunk = cc;
+
+ if (PackBitsEncode(tif, bp, chunk, s) < 0)
+ return (-1);
+ bp += chunk;
+ cc -= chunk;
+ }
+ return (1);
+}
+
+static int
+PackBitsDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "PackBitsDecode";
+ char *bp;
+ tmsize_t cc;
+ long n;
+ int b;
+
+ (void) s;
+ bp = (char*) tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ while (cc > 0 && occ > 0) {
+ n = (long) *bp++, cc--;
+ /*
+ * Watch out for compilers that
+ * don't sign extend chars...
+ */
+ if (n >= 128)
+ n -= 256;
+ if (n < 0) { /* replicate next byte -n+1 times */
+ if (n == -128) /* nop */
+ continue;
+ n = -n + 1;
+ if( occ < (tmsize_t)n )
+ {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Discarding %lu bytes to avoid buffer overrun",
+ (unsigned long) ((tmsize_t)n - occ));
+ n = (long)occ;
+ }
+ occ -= n;
+ b = *bp++, cc--;
+ while (n-- > 0)
+ *op++ = (uint8) b;
+ } else { /* copy next n+1 bytes literally */
+ if (occ < (tmsize_t)(n + 1))
+ {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Discarding %lu bytes to avoid buffer overrun",
+ (unsigned long) ((tmsize_t)n - occ + 1));
+ n = (long)occ - 1;
+ }
+ if (cc < (tmsize_t) (n+1))
+ {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "Terminating PackBitsDecode due to lack of data.");
+ break;
+ }
+ _TIFFmemcpy(op, bp, ++n);
+ op += n; occ -= n;
+ bp += n; cc -= n;
+ }
+ }
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ if (occ > 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data for scanline %lu",
+ (unsigned long) tif->tif_row);
+ return (0);
+ }
+ return (1);
+}
+
+int
+TIFFInitPackBits(TIFF* tif, int scheme)
+{
+ (void) scheme;
+ tif->tif_decoderow = PackBitsDecode;
+ tif->tif_decodestrip = PackBitsDecode;
+ tif->tif_decodetile = PackBitsDecode;
+ tif->tif_preencode = PackBitsPreEncode;
+ tif->tif_postencode = PackBitsPostEncode;
+ tif->tif_encoderow = PackBitsEncode;
+ tif->tif_encodestrip = PackBitsEncodeChunk;
+ tif->tif_encodetile = PackBitsEncodeChunk;
+ return (1);
+}
+#endif /* PACKBITS_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_pixarlog.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_pixarlog.c
new file mode 100644
index 0000000000..5aaf8be0d9
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_pixarlog.c
@@ -0,0 +1,1428 @@
+/* $Id: tif_pixarlog.c,v 1.38 2012-06-21 01:01:53 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1996-1997 Sam Leffler
+ * Copyright (c) 1996 Pixar
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Pixar, Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Pixar, Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL PIXAR, SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#ifdef PIXARLOG_SUPPORT
+
+/*
+ * TIFF Library.
+ * PixarLog Compression Support
+ *
+ * Contributed by Dan McCoy.
+ *
+ * PixarLog film support uses the TIFF library to store companded
+ * 11 bit values into a tiff file, which are compressed using the
+ * zip compressor.
+ *
+ * The codec can take as input and produce as output 32-bit IEEE float values
+ * as well as 16-bit or 8-bit unsigned integer values.
+ *
+ * On writing any of the above are converted into the internal
+ * 11-bit log format. In the case of 8 and 16 bit values, the
+ * input is assumed to be unsigned linear color values that represent
+ * the range 0-1. In the case of IEEE values, the 0-1 range is assumed to
+ * be the normal linear color range, in addition over 1 values are
+ * accepted up to a value of about 25.0 to encode "hot" hightlights and such.
+ * The encoding is lossless for 8-bit values, slightly lossy for the
+ * other bit depths. The actual color precision should be better
+ * than the human eye can perceive with extra room to allow for
+ * error introduced by further image computation. As with any quantized
+ * color format, it is possible to perform image calculations which
+ * expose the quantization error. This format should certainly be less
+ * susceptable to such errors than standard 8-bit encodings, but more
+ * susceptable than straight 16-bit or 32-bit encodings.
+ *
+ * On reading the internal format is converted to the desired output format.
+ * The program can request which format it desires by setting the internal
+ * pseudo tag TIFFTAG_PIXARLOGDATAFMT to one of these possible values:
+ * PIXARLOGDATAFMT_FLOAT = provide IEEE float values.
+ * PIXARLOGDATAFMT_16BIT = provide unsigned 16-bit integer values
+ * PIXARLOGDATAFMT_8BIT = provide unsigned 8-bit integer values
+ *
+ * alternately PIXARLOGDATAFMT_8BITABGR provides unsigned 8-bit integer
+ * values with the difference that if there are exactly three or four channels
+ * (rgb or rgba) it swaps the channel order (bgr or abgr).
+ *
+ * PIXARLOGDATAFMT_11BITLOG provides the internal encoding directly
+ * packed in 16-bit values. However no tools are supplied for interpreting
+ * these values.
+ *
+ * "hot" (over 1.0) areas written in floating point get clamped to
+ * 1.0 in the integer data types.
+ *
+ * When the file is closed after writing, the bit depth and sample format
+ * are set always to appear as if 8-bit data has been written into it.
+ * That way a naive program unaware of the particulars of the encoding
+ * gets the format it is most likely able to handle.
+ *
+ * The codec does it's own horizontal differencing step on the coded
+ * values so the libraries predictor stuff should be turned off.
+ * The codec also handle byte swapping the encoded values as necessary
+ * since the library does not have the information necessary
+ * to know the bit depth of the raw unencoded buffer.
+ *
+ * NOTE: This decoder does not appear to update tif_rawcp, and tif_rawcc.
+ * This can cause problems with the implementation of CHUNKY_STRIP_READ_SUPPORT
+ * as noted in http://trac.osgeo.org/gdal/ticket/3894. FrankW - Jan'11
+ */
+
+#include "tif_predict.h"
+#include "../../fx_zlib/include/fx_zlib.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+/* Tables for converting to/from 11 bit coded values */
+
+#define TSIZE 2048 /* decode table size (11-bit tokens) */
+#define TSIZEP1 2049 /* Plus one for slop */
+#define ONE 1250 /* token value of 1.0 exactly */
+#define RATIO 1.004 /* nominal ratio for log part */
+
+#define CODE_MASK 0x7ff /* 11 bits. */
+
+static float Fltsize;
+static float LogK1, LogK2;
+
+#define REPEAT(n, op) { int i; i=n; do { i--; op; } while (i>0); }
+
+static void
+horizontalAccumulateF(uint16 *wp, int n, int stride, float *op,
+ float *ToLinearF)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+ register float t0, t1, t2, t3;
+
+ if (n >= stride) {
+ mask = CODE_MASK;
+ if (stride == 3) {
+ t0 = ToLinearF[cr = (wp[0] & mask)];
+ t1 = ToLinearF[cg = (wp[1] & mask)];
+ t2 = ToLinearF[cb = (wp[2] & mask)];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ n -= 3;
+ while (n > 0) {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ t0 = ToLinearF[(cr += wp[0]) & mask];
+ t1 = ToLinearF[(cg += wp[1]) & mask];
+ t2 = ToLinearF[(cb += wp[2]) & mask];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ }
+ } else if (stride == 4) {
+ t0 = ToLinearF[cr = (wp[0] & mask)];
+ t1 = ToLinearF[cg = (wp[1] & mask)];
+ t2 = ToLinearF[cb = (wp[2] & mask)];
+ t3 = ToLinearF[ca = (wp[3] & mask)];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ n -= 4;
+ while (n > 0) {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ t0 = ToLinearF[(cr += wp[0]) & mask];
+ t1 = ToLinearF[(cg += wp[1]) & mask];
+ t2 = ToLinearF[(cb += wp[2]) & mask];
+ t3 = ToLinearF[(ca += wp[3]) & mask];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ }
+ } else {
+ REPEAT(stride, *op = ToLinearF[*wp&mask]; wp++; op++)
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride,
+ wp[stride] += *wp; *op = ToLinearF[*wp&mask]; wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void
+horizontalAccumulate12(uint16 *wp, int n, int stride, int16 *op,
+ float *ToLinearF)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+ register float t0, t1, t2, t3;
+
+#define SCALE12 2048.0F
+#define CLAMP12(t) (((t) < 3071) ? (uint16) (t) : 3071)
+
+ if (n >= stride) {
+ mask = CODE_MASK;
+ if (stride == 3) {
+ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
+ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
+ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ n -= 3;
+ while (n > 0) {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
+ t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
+ t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ }
+ } else if (stride == 4) {
+ t0 = ToLinearF[cr = (wp[0] & mask)] * SCALE12;
+ t1 = ToLinearF[cg = (wp[1] & mask)] * SCALE12;
+ t2 = ToLinearF[cb = (wp[2] & mask)] * SCALE12;
+ t3 = ToLinearF[ca = (wp[3] & mask)] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ op[3] = CLAMP12(t3);
+ n -= 4;
+ while (n > 0) {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ t0 = ToLinearF[(cr += wp[0]) & mask] * SCALE12;
+ t1 = ToLinearF[(cg += wp[1]) & mask] * SCALE12;
+ t2 = ToLinearF[(cb += wp[2]) & mask] * SCALE12;
+ t3 = ToLinearF[(ca += wp[3]) & mask] * SCALE12;
+ op[0] = CLAMP12(t0);
+ op[1] = CLAMP12(t1);
+ op[2] = CLAMP12(t2);
+ op[3] = CLAMP12(t3);
+ }
+ } else {
+ REPEAT(stride, t0 = ToLinearF[*wp&mask] * SCALE12;
+ *op = CLAMP12(t0); wp++; op++)
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride,
+ wp[stride] += *wp; t0 = ToLinearF[wp[stride]&mask]*SCALE12;
+ *op = CLAMP12(t0); wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void
+horizontalAccumulate16(uint16 *wp, int n, int stride, uint16 *op,
+ uint16 *ToLinear16)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+
+ if (n >= stride) {
+ mask = CODE_MASK;
+ if (stride == 3) {
+ op[0] = ToLinear16[cr = (wp[0] & mask)];
+ op[1] = ToLinear16[cg = (wp[1] & mask)];
+ op[2] = ToLinear16[cb = (wp[2] & mask)];
+ n -= 3;
+ while (n > 0) {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ op[0] = ToLinear16[(cr += wp[0]) & mask];
+ op[1] = ToLinear16[(cg += wp[1]) & mask];
+ op[2] = ToLinear16[(cb += wp[2]) & mask];
+ }
+ } else if (stride == 4) {
+ op[0] = ToLinear16[cr = (wp[0] & mask)];
+ op[1] = ToLinear16[cg = (wp[1] & mask)];
+ op[2] = ToLinear16[cb = (wp[2] & mask)];
+ op[3] = ToLinear16[ca = (wp[3] & mask)];
+ n -= 4;
+ while (n > 0) {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ op[0] = ToLinear16[(cr += wp[0]) & mask];
+ op[1] = ToLinear16[(cg += wp[1]) & mask];
+ op[2] = ToLinear16[(cb += wp[2]) & mask];
+ op[3] = ToLinear16[(ca += wp[3]) & mask];
+ }
+ } else {
+ REPEAT(stride, *op = ToLinear16[*wp&mask]; wp++; op++)
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride,
+ wp[stride] += *wp; *op = ToLinear16[*wp&mask]; wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+/*
+ * Returns the log encoded 11-bit values with the horizontal
+ * differencing undone.
+ */
+static void
+horizontalAccumulate11(uint16 *wp, int n, int stride, uint16 *op)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+
+ if (n >= stride) {
+ mask = CODE_MASK;
+ if (stride == 3) {
+ op[0] = cr = wp[0]; op[1] = cg = wp[1]; op[2] = cb = wp[2];
+ n -= 3;
+ while (n > 0) {
+ wp += 3;
+ op += 3;
+ n -= 3;
+ op[0] = (cr += wp[0]) & mask;
+ op[1] = (cg += wp[1]) & mask;
+ op[2] = (cb += wp[2]) & mask;
+ }
+ } else if (stride == 4) {
+ op[0] = cr = wp[0]; op[1] = cg = wp[1];
+ op[2] = cb = wp[2]; op[3] = ca = wp[3];
+ n -= 4;
+ while (n > 0) {
+ wp += 4;
+ op += 4;
+ n -= 4;
+ op[0] = (cr += wp[0]) & mask;
+ op[1] = (cg += wp[1]) & mask;
+ op[2] = (cb += wp[2]) & mask;
+ op[3] = (ca += wp[3]) & mask;
+ }
+ } else {
+ REPEAT(stride, *op = *wp&mask; wp++; op++)
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride,
+ wp[stride] += *wp; *op = *wp&mask; wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+static void
+horizontalAccumulate8(uint16 *wp, int n, int stride, unsigned char *op,
+ unsigned char *ToLinear8)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+
+ if (n >= stride) {
+ mask = CODE_MASK;
+ if (stride == 3) {
+ op[0] = ToLinear8[cr = (wp[0] & mask)];
+ op[1] = ToLinear8[cg = (wp[1] & mask)];
+ op[2] = ToLinear8[cb = (wp[2] & mask)];
+ n -= 3;
+ while (n > 0) {
+ n -= 3;
+ wp += 3;
+ op += 3;
+ op[0] = ToLinear8[(cr += wp[0]) & mask];
+ op[1] = ToLinear8[(cg += wp[1]) & mask];
+ op[2] = ToLinear8[(cb += wp[2]) & mask];
+ }
+ } else if (stride == 4) {
+ op[0] = ToLinear8[cr = (wp[0] & mask)];
+ op[1] = ToLinear8[cg = (wp[1] & mask)];
+ op[2] = ToLinear8[cb = (wp[2] & mask)];
+ op[3] = ToLinear8[ca = (wp[3] & mask)];
+ n -= 4;
+ while (n > 0) {
+ n -= 4;
+ wp += 4;
+ op += 4;
+ op[0] = ToLinear8[(cr += wp[0]) & mask];
+ op[1] = ToLinear8[(cg += wp[1]) & mask];
+ op[2] = ToLinear8[(cb += wp[2]) & mask];
+ op[3] = ToLinear8[(ca += wp[3]) & mask];
+ }
+ } else {
+ REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride,
+ wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+
+static void
+horizontalAccumulate8abgr(uint16 *wp, int n, int stride, unsigned char *op,
+ unsigned char *ToLinear8)
+{
+ register unsigned int cr, cg, cb, ca, mask;
+ register unsigned char t0, t1, t2, t3;
+
+ if (n >= stride) {
+ mask = CODE_MASK;
+ if (stride == 3) {
+ op[0] = 0;
+ t1 = ToLinear8[cb = (wp[2] & mask)];
+ t2 = ToLinear8[cg = (wp[1] & mask)];
+ t3 = ToLinear8[cr = (wp[0] & mask)];
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ n -= 3;
+ while (n > 0) {
+ n -= 3;
+ wp += 3;
+ op += 4;
+ op[0] = 0;
+ t1 = ToLinear8[(cb += wp[2]) & mask];
+ t2 = ToLinear8[(cg += wp[1]) & mask];
+ t3 = ToLinear8[(cr += wp[0]) & mask];
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ }
+ } else if (stride == 4) {
+ t0 = ToLinear8[ca = (wp[3] & mask)];
+ t1 = ToLinear8[cb = (wp[2] & mask)];
+ t2 = ToLinear8[cg = (wp[1] & mask)];
+ t3 = ToLinear8[cr = (wp[0] & mask)];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ n -= 4;
+ while (n > 0) {
+ n -= 4;
+ wp += 4;
+ op += 4;
+ t0 = ToLinear8[(ca += wp[3]) & mask];
+ t1 = ToLinear8[(cb += wp[2]) & mask];
+ t2 = ToLinear8[(cg += wp[1]) & mask];
+ t3 = ToLinear8[(cr += wp[0]) & mask];
+ op[0] = t0;
+ op[1] = t1;
+ op[2] = t2;
+ op[3] = t3;
+ }
+ } else {
+ REPEAT(stride, *op = ToLinear8[*wp&mask]; wp++; op++)
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride,
+ wp[stride] += *wp; *op = ToLinear8[*wp&mask]; wp++; op++)
+ n -= stride;
+ }
+ }
+ }
+}
+
+/*
+ * State block for each open TIFF
+ * file using PixarLog compression/decompression.
+ */
+typedef struct {
+ TIFFPredictorState predict;
+ z_stream stream;
+ uint16 *tbuf;
+ uint16 stride;
+ int state;
+ int user_datafmt;
+ int quality;
+#define PLSTATE_INIT 1
+
+ TIFFVSetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+
+ float *ToLinearF;
+ uint16 *ToLinear16;
+ unsigned char *ToLinear8;
+ uint16 *FromLT2;
+ uint16 *From14; /* Really for 16-bit data, but we shift down 2 */
+ uint16 *From8;
+
+} PixarLogState;
+
+static int
+PixarLogMakeTables(PixarLogState *sp)
+{
+
+/*
+ * We make several tables here to convert between various external
+ * representations (float, 16-bit, and 8-bit) and the internal
+ * 11-bit companded representation. The 11-bit representation has two
+ * distinct regions. A linear bottom end up through .018316 in steps
+ * of about .000073, and a region of constant ratio up to about 25.
+ * These floating point numbers are stored in the main table ToLinearF.
+ * All other tables are derived from this one. The tables (and the
+ * ratios) are continuous at the internal seam.
+ */
+
+ int nlin, lt2size;
+ int i, j;
+ double b, c, linstep, v;
+ float *ToLinearF;
+ uint16 *ToLinear16;
+ unsigned char *ToLinear8;
+ uint16 *FromLT2;
+ uint16 *From14; /* Really for 16-bit data, but we shift down 2 */
+ uint16 *From8;
+
+ c = log(RATIO);
+ nlin = (int)(1./c); /* nlin must be an integer */
+ c = 1./nlin;
+ b = exp(-c*ONE); /* multiplicative scale factor [b*exp(c*ONE) = 1] */
+ linstep = b*c*exp(1.);
+
+ LogK1 = (float)(1./c); /* if (v >= 2) token = k1*log(v*k2) */
+ LogK2 = (float)(1./b);
+ lt2size = (int)(2./linstep) + 1;
+ FromLT2 = (uint16 *)_TIFFmalloc(lt2size*sizeof(uint16));
+ From14 = (uint16 *)_TIFFmalloc(16384*sizeof(uint16));
+ From8 = (uint16 *)_TIFFmalloc(256*sizeof(uint16));
+ ToLinearF = (float *)_TIFFmalloc(TSIZEP1 * sizeof(float));
+ ToLinear16 = (uint16 *)_TIFFmalloc(TSIZEP1 * sizeof(uint16));
+ ToLinear8 = (unsigned char *)_TIFFmalloc(TSIZEP1 * sizeof(unsigned char));
+ if (FromLT2 == NULL || From14 == NULL || From8 == NULL ||
+ ToLinearF == NULL || ToLinear16 == NULL || ToLinear8 == NULL) {
+ if (FromLT2) _TIFFfree(FromLT2);
+ if (From14) _TIFFfree(From14);
+ if (From8) _TIFFfree(From8);
+ if (ToLinearF) _TIFFfree(ToLinearF);
+ if (ToLinear16) _TIFFfree(ToLinear16);
+ if (ToLinear8) _TIFFfree(ToLinear8);
+ sp->FromLT2 = NULL;
+ sp->From14 = NULL;
+ sp->From8 = NULL;
+ sp->ToLinearF = NULL;
+ sp->ToLinear16 = NULL;
+ sp->ToLinear8 = NULL;
+ return 0;
+ }
+
+ j = 0;
+
+ for (i = 0; i < nlin; i++) {
+ v = i * linstep;
+ ToLinearF[j++] = (float)v;
+ }
+
+ for (i = nlin; i < TSIZE; i++)
+ ToLinearF[j++] = (float)(b*exp(c*i));
+
+ ToLinearF[2048] = ToLinearF[2047];
+
+ for (i = 0; i < TSIZEP1; i++) {
+ v = ToLinearF[i]*65535.0 + 0.5;
+ ToLinear16[i] = (v > 65535.0) ? 65535 : (uint16)v;
+ v = ToLinearF[i]*255.0 + 0.5;
+ ToLinear8[i] = (v > 255.0) ? 255 : (unsigned char)v;
+ }
+
+ j = 0;
+ for (i = 0; i < lt2size; i++) {
+ if ((i*linstep)*(i*linstep) > ToLinearF[j]*ToLinearF[j+1])
+ j++;
+ FromLT2[i] = j;
+ }
+
+ /*
+ * Since we lose info anyway on 16-bit data, we set up a 14-bit
+ * table and shift 16-bit values down two bits on input.
+ * saves a little table space.
+ */
+ j = 0;
+ for (i = 0; i < 16384; i++) {
+ while ((i/16383.)*(i/16383.) > ToLinearF[j]*ToLinearF[j+1])
+ j++;
+ From14[i] = j;
+ }
+
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ while ((i/255.)*(i/255.) > ToLinearF[j]*ToLinearF[j+1])
+ j++;
+ From8[i] = j;
+ }
+
+ Fltsize = (float)(lt2size/2);
+
+ sp->ToLinearF = ToLinearF;
+ sp->ToLinear16 = ToLinear16;
+ sp->ToLinear8 = ToLinear8;
+ sp->FromLT2 = FromLT2;
+ sp->From14 = From14;
+ sp->From8 = From8;
+
+ return 1;
+}
+
+#define DecoderState(tif) ((PixarLogState*) (tif)->tif_data)
+#define EncoderState(tif) ((PixarLogState*) (tif)->tif_data)
+
+static int PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
+static int PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
+
+#define PIXARLOGDATAFMT_UNKNOWN -1
+
+static int
+PixarLogGuessDataFmt(TIFFDirectory *td)
+{
+ int guess = PIXARLOGDATAFMT_UNKNOWN;
+ int format = td->td_sampleformat;
+
+ /* If the user didn't tell us his datafmt,
+ * take our best guess from the bitspersample.
+ */
+ switch (td->td_bitspersample) {
+ case 32:
+ if (format == SAMPLEFORMAT_IEEEFP)
+ guess = PIXARLOGDATAFMT_FLOAT;
+ break;
+ case 16:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+ guess = PIXARLOGDATAFMT_16BIT;
+ break;
+ case 12:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_INT)
+ guess = PIXARLOGDATAFMT_12BITPICIO;
+ break;
+ case 11:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+ guess = PIXARLOGDATAFMT_11BITLOG;
+ break;
+ case 8:
+ if (format == SAMPLEFORMAT_VOID || format == SAMPLEFORMAT_UINT)
+ guess = PIXARLOGDATAFMT_8BIT;
+ break;
+ }
+
+ return guess;
+}
+
+static tmsize_t
+multiply_ms(tmsize_t m1, tmsize_t m2)
+{
+ tmsize_t bytes = m1 * m2;
+
+ if (m1 && bytes / m1 != m2)
+ bytes = 0;
+
+ return bytes;
+}
+
+static int
+PixarLogFixupTags(TIFF* tif)
+{
+ (void) tif;
+ return (1);
+}
+
+static int
+PixarLogSetupDecode(TIFF* tif)
+{
+ static const char module[] = "PixarLogSetupDecode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState* sp = DecoderState(tif);
+ tmsize_t tbuf_size;
+
+ assert(sp != NULL);
+
+ /* Make sure no byte swapping happens on the data
+ * after decompression. */
+ tif->tif_postdecode = _TIFFNoPostDecode;
+
+ /* for some reason, we can't do this in TIFFInitPixarLog */
+
+ sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+ td->td_samplesperpixel : 1);
+ tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
+ td->td_rowsperstrip), sizeof(uint16));
+ if (tbuf_size == 0)
+ return (0); /* TODO: this is an error return without error report through TIFFErrorExt */
+ sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size+sizeof(uint16)*sp->stride);
+ if (sp->tbuf == NULL)
+ return (0);
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = PixarLogGuessDataFmt(td);
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "PixarLog compression can't handle bits depth/data format combination (depth: %d)",
+ td->td_bitspersample);
+ return (0);
+ }
+
+ if (inflateInit(&sp->stream) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+ return (0);
+ } else {
+ sp->state |= PLSTATE_INIT;
+ return (1);
+ }
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+PixarLogPreDecode(TIFF* tif, uint16 s)
+{
+ static const char module[] = "PixarLogPreDecode";
+ PixarLogState* sp = DecoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+ sp->stream.next_in = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_in = (uInt) tif->tif_rawcc;
+ if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ return (inflateReset(&sp->stream) == Z_OK);
+}
+
+static int
+PixarLogDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "PixarLogDecode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState* sp = DecoderState(tif);
+ tmsize_t i;
+ tmsize_t nsamples;
+ int llen;
+ uint16 *up;
+
+ switch (sp->user_datafmt) {
+ case PIXARLOGDATAFMT_FLOAT:
+ nsamples = occ / sizeof(float); /* XXX float == 32 bits */
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ case PIXARLOGDATAFMT_12BITPICIO:
+ case PIXARLOGDATAFMT_11BITLOG:
+ nsamples = occ / sizeof(uint16); /* XXX uint16 == 16 bits */
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ case PIXARLOGDATAFMT_8BITABGR:
+ nsamples = occ;
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%d bit input not supported in PixarLog",
+ td->td_bitspersample);
+ return 0;
+ }
+
+ llen = sp->stride * td->td_imagewidth;
+
+ (void) s;
+ assert(sp != NULL);
+ sp->stream.next_out = (unsigned char *) sp->tbuf;
+ assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_out = (uInt) (nsamples * sizeof(uint16));
+ if (sp->stream.avail_out != nsamples * sizeof(uint16))
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ do {
+ int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ if (state == Z_STREAM_END) {
+ break; /* XXX */
+ }
+ if (state == Z_DATA_ERROR) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Decoding error at scanline %lu, %s",
+ (unsigned long) tif->tif_row, sp->stream.msg);
+ if (inflateSync(&sp->stream) != Z_OK)
+ return (0);
+ continue;
+ }
+ if (state != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ } while (sp->stream.avail_out > 0);
+
+ /* hopefully, we got all the bytes we needed */
+ if (sp->stream.avail_out != 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
+ (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
+ return (0);
+ }
+
+ up = sp->tbuf;
+ /* Swap bytes in the data if from a different endian machine. */
+ if (tif->tif_flags & TIFF_SWAB)
+ TIFFSwabArrayOfShort(up, nsamples);
+
+ /*
+ * if llen is not an exact multiple of nsamples, the decode operation
+ * may overflow the output buffer, so truncate it enough to prevent
+ * that but still salvage as much data as possible.
+ */
+ if (nsamples % llen) {
+ TIFFWarningExt(tif->tif_clientdata, module,
+ "stride %lu is not a multiple of sample count, "
+ "%lu, data truncated.", (unsigned long) llen, (unsigned long) nsamples);
+ nsamples -= nsamples % llen;
+ }
+
+ for (i = 0; i < nsamples; i += llen, up += llen) {
+ switch (sp->user_datafmt) {
+ case PIXARLOGDATAFMT_FLOAT:
+ horizontalAccumulateF(up, llen, sp->stride,
+ (float *)op, sp->ToLinearF);
+ op += llen * sizeof(float);
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ horizontalAccumulate16(up, llen, sp->stride,
+ (uint16 *)op, sp->ToLinear16);
+ op += llen * sizeof(uint16);
+ break;
+ case PIXARLOGDATAFMT_12BITPICIO:
+ horizontalAccumulate12(up, llen, sp->stride,
+ (int16 *)op, sp->ToLinearF);
+ op += llen * sizeof(int16);
+ break;
+ case PIXARLOGDATAFMT_11BITLOG:
+ horizontalAccumulate11(up, llen, sp->stride,
+ (uint16 *)op);
+ op += llen * sizeof(uint16);
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ horizontalAccumulate8(up, llen, sp->stride,
+ (unsigned char *)op, sp->ToLinear8);
+ op += llen * sizeof(unsigned char);
+ break;
+ case PIXARLOGDATAFMT_8BITABGR:
+ horizontalAccumulate8abgr(up, llen, sp->stride,
+ (unsigned char *)op, sp->ToLinear8);
+ op += llen * sizeof(unsigned char);
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Unsupported bits/sample: %d",
+ td->td_bitspersample);
+ return (0);
+ }
+ }
+
+ return (1);
+}
+
+static int
+PixarLogSetupEncode(TIFF* tif)
+{
+ static const char module[] = "PixarLogSetupEncode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState* sp = EncoderState(tif);
+ tmsize_t tbuf_size;
+
+ assert(sp != NULL);
+
+ /* for some reason, we can't do this in TIFFInitPixarLog */
+
+ sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+ td->td_samplesperpixel : 1);
+ tbuf_size = multiply_ms(multiply_ms(multiply_ms(sp->stride, td->td_imagewidth),
+ td->td_rowsperstrip), sizeof(uint16));
+ if (tbuf_size == 0)
+ return (0); /* TODO: this is an error return without error report through TIFFErrorExt */
+ sp->tbuf = (uint16 *) _TIFFmalloc(tbuf_size);
+ if (sp->tbuf == NULL)
+ return (0);
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN)
+ sp->user_datafmt = PixarLogGuessDataFmt(td);
+ if (sp->user_datafmt == PIXARLOGDATAFMT_UNKNOWN) {
+ TIFFErrorExt(tif->tif_clientdata, module, "PixarLog compression can't handle %d bit linear encodings", td->td_bitspersample);
+ return (0);
+ }
+
+ if (deflateInit(&sp->stream, sp->quality) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+ return (0);
+ } else {
+ sp->state |= PLSTATE_INIT;
+ return (1);
+ }
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+PixarLogPreEncode(TIFF* tif, uint16 s)
+{
+ static const char module[] = "PixarLogPreEncode";
+ PixarLogState *sp = EncoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+ sp->stream.next_out = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ return (deflateReset(&sp->stream) == Z_OK);
+}
+
+static void
+horizontalDifferenceF(float *ip, int n, int stride, uint16 *wp, uint16 *FromLT2)
+{
+ int32 r1, g1, b1, a1, r2, g2, b2, a2, mask;
+ float fltsize = Fltsize;
+
+#define CLAMP(v) ( (v<(float)0.) ? 0 \
+ : (v<(float)2.) ? FromLT2[(int)(v*fltsize)] \
+ : (v>(float)24.2) ? 2047 \
+ : LogK1*log(v*LogK2) + 0.5 )
+
+ mask = CODE_MASK;
+ if (n >= stride) {
+ if (stride == 3) {
+ r2 = wp[0] = (uint16) CLAMP(ip[0]);
+ g2 = wp[1] = (uint16) CLAMP(ip[1]);
+ b2 = wp[2] = (uint16) CLAMP(ip[2]);
+ n -= 3;
+ while (n > 0) {
+ n -= 3;
+ wp += 3;
+ ip += 3;
+ r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+ g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+ b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+ }
+ } else if (stride == 4) {
+ r2 = wp[0] = (uint16) CLAMP(ip[0]);
+ g2 = wp[1] = (uint16) CLAMP(ip[1]);
+ b2 = wp[2] = (uint16) CLAMP(ip[2]);
+ a2 = wp[3] = (uint16) CLAMP(ip[3]);
+ n -= 4;
+ while (n > 0) {
+ n -= 4;
+ wp += 4;
+ ip += 4;
+ r1 = (int32) CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+ g1 = (int32) CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+ b1 = (int32) CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+ a1 = (int32) CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
+ }
+ } else {
+ ip += n - 1; /* point to last one */
+ wp += n - 1; /* point to last one */
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]);
+ wp[stride] -= wp[0];
+ wp[stride] &= mask;
+ wp--; ip--)
+ n -= stride;
+ }
+ REPEAT(stride, wp[0] = (uint16) CLAMP(ip[0]); wp--; ip--)
+ }
+ }
+}
+
+static void
+horizontalDifference16(unsigned short *ip, int n, int stride,
+ unsigned short *wp, uint16 *From14)
+{
+ register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
+
+/* assumption is unsigned pixel values */
+#undef CLAMP
+#define CLAMP(v) From14[(v) >> 2]
+
+ mask = CODE_MASK;
+ if (n >= stride) {
+ if (stride == 3) {
+ r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]);
+ n -= 3;
+ while (n > 0) {
+ n -= 3;
+ wp += 3;
+ ip += 3;
+ r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+ g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+ b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+ }
+ } else if (stride == 4) {
+ r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]);
+ n -= 4;
+ while (n > 0) {
+ n -= 4;
+ wp += 4;
+ ip += 4;
+ r1 = CLAMP(ip[0]); wp[0] = (r1-r2) & mask; r2 = r1;
+ g1 = CLAMP(ip[1]); wp[1] = (g1-g2) & mask; g2 = g1;
+ b1 = CLAMP(ip[2]); wp[2] = (b1-b2) & mask; b2 = b1;
+ a1 = CLAMP(ip[3]); wp[3] = (a1-a2) & mask; a2 = a1;
+ }
+ } else {
+ ip += n - 1; /* point to last one */
+ wp += n - 1; /* point to last one */
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride, wp[0] = CLAMP(ip[0]);
+ wp[stride] -= wp[0];
+ wp[stride] &= mask;
+ wp--; ip--)
+ n -= stride;
+ }
+ REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
+ }
+ }
+}
+
+
+static void
+horizontalDifference8(unsigned char *ip, int n, int stride,
+ unsigned short *wp, uint16 *From8)
+{
+ register int r1, g1, b1, a1, r2, g2, b2, a2, mask;
+
+#undef CLAMP
+#define CLAMP(v) (From8[(v)])
+
+ mask = CODE_MASK;
+ if (n >= stride) {
+ if (stride == 3) {
+ r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]);
+ n -= 3;
+ while (n > 0) {
+ n -= 3;
+ r1 = CLAMP(ip[3]); wp[3] = (r1-r2) & mask; r2 = r1;
+ g1 = CLAMP(ip[4]); wp[4] = (g1-g2) & mask; g2 = g1;
+ b1 = CLAMP(ip[5]); wp[5] = (b1-b2) & mask; b2 = b1;
+ wp += 3;
+ ip += 3;
+ }
+ } else if (stride == 4) {
+ r2 = wp[0] = CLAMP(ip[0]); g2 = wp[1] = CLAMP(ip[1]);
+ b2 = wp[2] = CLAMP(ip[2]); a2 = wp[3] = CLAMP(ip[3]);
+ n -= 4;
+ while (n > 0) {
+ n -= 4;
+ r1 = CLAMP(ip[4]); wp[4] = (r1-r2) & mask; r2 = r1;
+ g1 = CLAMP(ip[5]); wp[5] = (g1-g2) & mask; g2 = g1;
+ b1 = CLAMP(ip[6]); wp[6] = (b1-b2) & mask; b2 = b1;
+ a1 = CLAMP(ip[7]); wp[7] = (a1-a2) & mask; a2 = a1;
+ wp += 4;
+ ip += 4;
+ }
+ } else {
+ wp += n + stride - 1; /* point to last one */
+ ip += n + stride - 1; /* point to last one */
+ n -= stride;
+ while (n > 0) {
+ REPEAT(stride, wp[0] = CLAMP(ip[0]);
+ wp[stride] -= wp[0];
+ wp[stride] &= mask;
+ wp--; ip--)
+ n -= stride;
+ }
+ REPEAT(stride, wp[0] = CLAMP(ip[0]); wp--; ip--)
+ }
+ }
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int
+PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ static const char module[] = "PixarLogEncode";
+ TIFFDirectory *td = &tif->tif_dir;
+ PixarLogState *sp = EncoderState(tif);
+ tmsize_t i;
+ tmsize_t n;
+ int llen;
+ unsigned short * up;
+
+ (void) s;
+
+ switch (sp->user_datafmt) {
+ case PIXARLOGDATAFMT_FLOAT:
+ n = cc / sizeof(float); /* XXX float == 32 bits */
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ case PIXARLOGDATAFMT_12BITPICIO:
+ case PIXARLOGDATAFMT_11BITLOG:
+ n = cc / sizeof(uint16); /* XXX uint16 == 16 bits */
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ case PIXARLOGDATAFMT_8BITABGR:
+ n = cc;
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%d bit input not supported in PixarLog",
+ td->td_bitspersample);
+ return 0;
+ }
+
+ llen = sp->stride * td->td_imagewidth;
+
+ for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
+ switch (sp->user_datafmt) {
+ case PIXARLOGDATAFMT_FLOAT:
+ horizontalDifferenceF((float *)bp, llen,
+ sp->stride, up, sp->FromLT2);
+ bp += llen * sizeof(float);
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ horizontalDifference16((uint16 *)bp, llen,
+ sp->stride, up, sp->From14);
+ bp += llen * sizeof(uint16);
+ break;
+ case PIXARLOGDATAFMT_8BIT:
+ horizontalDifference8((unsigned char *)bp, llen,
+ sp->stride, up, sp->From8);
+ bp += llen * sizeof(unsigned char);
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%d bit input not supported in PixarLog",
+ td->td_bitspersample);
+ return 0;
+ }
+ }
+
+ sp->stream.next_in = (unsigned char *) sp->tbuf;
+ assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_in = (uInt) (n * sizeof(uint16));
+ if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+
+ do {
+ if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ if (sp->stream.avail_out == 0) {
+ tif->tif_rawcc = tif->tif_rawdatasize;
+ TIFFFlushData1(tif);
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
+ }
+ } while (sp->stream.avail_in > 0);
+ return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+
+static int
+PixarLogPostEncode(TIFF* tif)
+{
+ static const char module[] = "PixarLogPostEncode";
+ PixarLogState *sp = EncoderState(tif);
+ int state;
+
+ sp->stream.avail_in = 0;
+
+ do {
+ state = deflate(&sp->stream, Z_FINISH);
+ switch (state) {
+ case Z_STREAM_END:
+ case Z_OK:
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize) {
+ tif->tif_rawcc =
+ tif->tif_rawdatasize - sp->stream.avail_out;
+ TIFFFlushData1(tif);
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in PixarLogPreEncode */
+ }
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ } while (state != Z_STREAM_END);
+ return (1);
+}
+
+static void
+PixarLogClose(TIFF* tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ /* In a really sneaky (and really incorrect, and untruthfull, and
+ * troublesome, and error-prone) maneuver that completely goes against
+ * the spirit of TIFF, and breaks TIFF, on close, we covertly
+ * modify both bitspersample and sampleformat in the directory to
+ * indicate 8-bit linear. This way, the decode "just works" even for
+ * readers that don't know about PixarLog, or how to set
+ * the PIXARLOGDATFMT pseudo-tag.
+ */
+ td->td_bitspersample = 8;
+ td->td_sampleformat = SAMPLEFORMAT_UINT;
+}
+
+static void
+PixarLogCleanup(TIFF* tif)
+{
+ PixarLogState* sp = (PixarLogState*) tif->tif_data;
+
+ assert(sp != 0);
+
+ (void)TIFFPredictorCleanup(tif);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->FromLT2) _TIFFfree(sp->FromLT2);
+ if (sp->From14) _TIFFfree(sp->From14);
+ if (sp->From8) _TIFFfree(sp->From8);
+ if (sp->ToLinearF) _TIFFfree(sp->ToLinearF);
+ if (sp->ToLinear16) _TIFFfree(sp->ToLinear16);
+ if (sp->ToLinear8) _TIFFfree(sp->ToLinear8);
+ if (sp->state&PLSTATE_INIT) {
+ if (tif->tif_mode == O_RDONLY)
+ inflateEnd(&sp->stream);
+ else
+ deflateEnd(&sp->stream);
+ }
+ if (sp->tbuf)
+ _TIFFfree(sp->tbuf);
+ _TIFFfree(sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int
+PixarLogVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ static const char module[] = "PixarLogVSetField";
+ PixarLogState *sp = (PixarLogState *)tif->tif_data;
+ int result;
+
+ switch (tag) {
+ case TIFFTAG_PIXARLOGQUALITY:
+ sp->quality = (int) va_arg(ap, int);
+ if (tif->tif_mode != O_RDONLY && (sp->state&PLSTATE_INIT)) {
+ if (deflateParams(&sp->stream,
+ sp->quality, Z_DEFAULT_STRATEGY) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ }
+ return (1);
+ case TIFFTAG_PIXARLOGDATAFMT:
+ sp->user_datafmt = (int) va_arg(ap, int);
+ /* Tweak the TIFF header so that the rest of libtiff knows what
+ * size of data will be passed between app and library, and
+ * assume that the app knows what it is doing and is not
+ * confused by these header manipulations...
+ */
+ switch (sp->user_datafmt) {
+ case PIXARLOGDATAFMT_8BIT:
+ case PIXARLOGDATAFMT_8BITABGR:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+ break;
+ case PIXARLOGDATAFMT_11BITLOG:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+ break;
+ case PIXARLOGDATAFMT_12BITPICIO:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
+ break;
+ case PIXARLOGDATAFMT_16BIT:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 16);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
+ break;
+ case PIXARLOGDATAFMT_FLOAT:
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 32);
+ TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
+ break;
+ }
+ /*
+ * Must recalculate sizes should bits/sample change.
+ */
+ tif->tif_tilesize = isTiled(tif) ? TIFFTileSize(tif) : (tmsize_t)(-1);
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ result = 1; /* NB: pseudo tag */
+ break;
+ default:
+ result = (*sp->vsetparent)(tif, tag, ap);
+ }
+ return (result);
+}
+
+static int
+PixarLogVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ PixarLogState *sp = (PixarLogState *)tif->tif_data;
+
+ switch (tag) {
+ case TIFFTAG_PIXARLOGQUALITY:
+ *va_arg(ap, int*) = sp->quality;
+ break;
+ case TIFFTAG_PIXARLOGDATAFMT:
+ *va_arg(ap, int*) = sp->user_datafmt;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static const TIFFField pixarlogFields[] = {
+ {TIFFTAG_PIXARLOGDATAFMT, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL},
+ {TIFFTAG_PIXARLOGQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, FALSE, FALSE, "", NULL}
+};
+
+int
+TIFFInitPixarLog(TIFF* tif, int scheme)
+{
+ static const char module[] = "TIFFInitPixarLog";
+
+ PixarLogState* sp;
+
+ assert(scheme == COMPRESSION_PIXARLOG);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, pixarlogFields,
+ TIFFArrayCount(pixarlogFields))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Merging PixarLog codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8*) _TIFFmalloc(sizeof (PixarLogState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = (PixarLogState*) tif->tif_data;
+ _TIFFmemset(sp, 0, sizeof (*sp));
+ sp->stream.data_type = Z_BINARY;
+ sp->user_datafmt = PIXARLOGDATAFMT_UNKNOWN;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = PixarLogFixupTags;
+ tif->tif_setupdecode = PixarLogSetupDecode;
+ tif->tif_predecode = PixarLogPreDecode;
+ tif->tif_decoderow = PixarLogDecode;
+ tif->tif_decodestrip = PixarLogDecode;
+ tif->tif_decodetile = PixarLogDecode;
+ tif->tif_setupencode = PixarLogSetupEncode;
+ tif->tif_preencode = PixarLogPreEncode;
+ tif->tif_postencode = PixarLogPostEncode;
+ tif->tif_encoderow = PixarLogEncode;
+ tif->tif_encodestrip = PixarLogEncode;
+ tif->tif_encodetile = PixarLogEncode;
+ tif->tif_close = PixarLogClose;
+ tif->tif_cleanup = PixarLogCleanup;
+
+ /* Override SetField so we can handle our private pseudo-tag */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = PixarLogVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = PixarLogVSetField; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->quality = Z_DEFAULT_COMPRESSION; /* default comp. level */
+ sp->state = 0;
+
+ /* we don't wish to use the predictor,
+ * the default is none, which predictor value 1
+ */
+ (void) TIFFPredictorInit(tif);
+
+ /*
+ * build the companding tables
+ */
+ PixarLogMakeTables(sp);
+
+ return (1);
+bad:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for PixarLog state block");
+ return (0);
+}
+#endif /* PIXARLOG_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.c
new file mode 100644
index 0000000000..190d01644a
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.c
@@ -0,0 +1,813 @@
+/* $Id: tif_predict.c,v 1.32 2010-03-10 18:56:49 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Predictor Tag Support (used by multiple codecs).
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include "tif_predict.h"
+
+#define PredictorState(tif) ((TIFFPredictorState*) (tif)->tif_data)
+
+static void horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc);
+static void fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc);
+static int PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+static int PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s);
+static int PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
+static int PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s);
+
+static int
+PredictorSetup(TIFF* tif)
+{
+ static const char module[] = "PredictorSetup";
+
+ TIFFPredictorState* sp = PredictorState(tif);
+ TIFFDirectory* td = &tif->tif_dir;
+
+ switch (sp->predictor) /* no differencing */
+ {
+ case PREDICTOR_NONE:
+ return 1;
+ case PREDICTOR_HORIZONTAL:
+ if (td->td_bitspersample != 8
+ && td->td_bitspersample != 16
+ && td->td_bitspersample != 32) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Horizontal differencing \"Predictor\" not supported with %d-bit samples",
+ td->td_bitspersample);
+ return 0;
+ }
+ break;
+ case PREDICTOR_FLOATINGPOINT:
+ if (td->td_sampleformat != SAMPLEFORMAT_IEEEFP) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Floating point \"Predictor\" not supported with %d data format",
+ td->td_sampleformat);
+ return 0;
+ }
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "\"Predictor\" value %d not supported",
+ sp->predictor);
+ return 0;
+ }
+ sp->stride = (td->td_planarconfig == PLANARCONFIG_CONTIG ?
+ td->td_samplesperpixel : 1);
+ /*
+ * Calculate the scanline/tile-width size in bytes.
+ */
+ if (isTiled(tif))
+ sp->rowsize = TIFFTileRowSize(tif);
+ else
+ sp->rowsize = TIFFScanlineSize(tif);
+ if (sp->rowsize == 0)
+ return 0;
+
+ return 1;
+}
+
+static int
+PredictorSetupDecode(TIFF* tif)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+ TIFFDirectory* td = &tif->tif_dir;
+
+ if (!(*sp->setupdecode)(tif) || !PredictorSetup(tif))
+ return 0;
+
+ if (sp->predictor == 2) {
+ switch (td->td_bitspersample) {
+ case 8: sp->decodepfunc = horAcc8; break;
+ case 16: sp->decodepfunc = horAcc16; break;
+ case 32: sp->decodepfunc = horAcc32; break;
+ }
+ /*
+ * Override default decoding method with one that does the
+ * predictor stuff.
+ */
+ if( tif->tif_decoderow != PredictorDecodeRow )
+ {
+ sp->decoderow = tif->tif_decoderow;
+ tif->tif_decoderow = PredictorDecodeRow;
+ sp->decodestrip = tif->tif_decodestrip;
+ tif->tif_decodestrip = PredictorDecodeTile;
+ sp->decodetile = tif->tif_decodetile;
+ tif->tif_decodetile = PredictorDecodeTile;
+ }
+
+ /*
+ * If the data is horizontally differenced 16-bit data that
+ * requires byte-swapping, then it must be byte swapped before
+ * the accumulation step. We do this with a special-purpose
+ * routine and override the normal post decoding logic that
+ * the library setup when the directory was read.
+ */
+ if (tif->tif_flags & TIFF_SWAB) {
+ if (sp->decodepfunc == horAcc16) {
+ sp->decodepfunc = swabHorAcc16;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ } else if (sp->decodepfunc == horAcc32) {
+ sp->decodepfunc = swabHorAcc32;
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ }
+ }
+
+ else if (sp->predictor == 3) {
+ sp->decodepfunc = fpAcc;
+ /*
+ * Override default decoding method with one that does the
+ * predictor stuff.
+ */
+ if( tif->tif_decoderow != PredictorDecodeRow )
+ {
+ sp->decoderow = tif->tif_decoderow;
+ tif->tif_decoderow = PredictorDecodeRow;
+ sp->decodestrip = tif->tif_decodestrip;
+ tif->tif_decodestrip = PredictorDecodeTile;
+ sp->decodetile = tif->tif_decodetile;
+ tif->tif_decodetile = PredictorDecodeTile;
+ }
+ /*
+ * The data should not be swapped outside of the floating
+ * point predictor, the accumulation routine should return
+ * byres in the native order.
+ */
+ if (tif->tif_flags & TIFF_SWAB) {
+ tif->tif_postdecode = _TIFFNoPostDecode;
+ }
+ /*
+ * Allocate buffer to keep the decoded bytes before
+ * rearranging in the ight order
+ */
+ }
+
+ return 1;
+}
+
+static int
+PredictorSetupEncode(TIFF* tif)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+ TIFFDirectory* td = &tif->tif_dir;
+
+ if (!(*sp->setupencode)(tif) || !PredictorSetup(tif))
+ return 0;
+
+ if (sp->predictor == 2) {
+ switch (td->td_bitspersample) {
+ case 8: sp->encodepfunc = horDiff8; break;
+ case 16: sp->encodepfunc = horDiff16; break;
+ case 32: sp->encodepfunc = horDiff32; break;
+ }
+ /*
+ * Override default encoding method with one that does the
+ * predictor stuff.
+ */
+ if( tif->tif_encoderow != PredictorEncodeRow )
+ {
+ sp->encoderow = tif->tif_encoderow;
+ tif->tif_encoderow = PredictorEncodeRow;
+ sp->encodestrip = tif->tif_encodestrip;
+ tif->tif_encodestrip = PredictorEncodeTile;
+ sp->encodetile = tif->tif_encodetile;
+ tif->tif_encodetile = PredictorEncodeTile;
+ }
+ }
+
+ else if (sp->predictor == 3) {
+ sp->encodepfunc = fpDiff;
+ /*
+ * Override default encoding method with one that does the
+ * predictor stuff.
+ */
+ if( tif->tif_encoderow != PredictorEncodeRow )
+ {
+ sp->encoderow = tif->tif_encoderow;
+ tif->tif_encoderow = PredictorEncodeRow;
+ sp->encodestrip = tif->tif_encodestrip;
+ tif->tif_encodestrip = PredictorEncodeTile;
+ sp->encodetile = tif->tif_encodetile;
+ tif->tif_encodetile = PredictorEncodeTile;
+ }
+ }
+
+ return 1;
+}
+
+#define REPEAT4(n, op) \
+ switch (n) { \
+ default: { tmsize_t i; for (i = n-4; i > 0; i--) { op; } } \
+ case 4: op; \
+ case 3: op; \
+ case 2: op; \
+ case 1: op; \
+ case 0: ; \
+ }
+
+static void
+horAcc8(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ /*
+ * compare v4.0.3 with v3.9.5,
+ * we find that horAcc8 uses while loop in the v4.0.3 and uses do while loop in the v3.9.5.
+ * times of do while loop are less than while loop, so we use v3.9.5 instead of v4.0.3.
+ */
+#if 0
+ tmsize_t stride = PredictorState(tif)->stride;
+
+ char* cp = (char*) cp0;
+ assert((cc%stride)==0);
+ if (cc > stride) {
+ /*
+ * Pipeline the most common cases.
+ */
+ if (stride == 3) {
+ unsigned int cr = cp[0];
+ unsigned int cg = cp[1];
+ unsigned int cb = cp[2];
+ cc -= 3;
+ cp += 3;
+ while (cc>0) {
+ cp[0] = (char) (cr += cp[0]);
+ cp[1] = (char) (cg += cp[1]);
+ cp[2] = (char) (cb += cp[2]);
+ cc -= 3;
+ cp += 3;
+ }
+ } else if (stride == 4) {
+ unsigned int cr = cp[0];
+ unsigned int cg = cp[1];
+ unsigned int cb = cp[2];
+ unsigned int ca = cp[3];
+ cc -= 4;
+ cp += 4;
+ while (cc>0) {
+ cp[0] = (char) (cr += cp[0]);
+ cp[1] = (char) (cg += cp[1]);
+ cp[2] = (char) (cb += cp[2]);
+ cp[3] = (char) (ca += cp[3]);
+ cc -= 4;
+ cp += 4;
+ }
+ } else {
+ cc -= stride;
+ do {
+ REPEAT4(stride, cp[stride] =
+ (char) (cp[stride] + *cp); cp++)
+ cc -= stride;
+ } while (cc>0);
+ }
+ }
+#else
+ tsize_t stride = PredictorState(tif)->stride;
+
+ char* cp = (char*) cp0;
+ if (cc > stride) {
+ cc -= stride;
+ /*
+ * Pipeline the most common cases.
+ */
+ if (stride == 3) {
+ unsigned int cr = cp[0];
+ unsigned int cg = cp[1];
+ unsigned int cb = cp[2];
+ do {
+ cc -= 3, cp += 3;
+ cp[0] = (char) (cr += cp[0]);
+ cp[1] = (char) (cg += cp[1]);
+ cp[2] = (char) (cb += cp[2]);
+ } while ((int32) cc > 0);
+ } else if (stride == 4) {
+ unsigned int cr = cp[0];
+ unsigned int cg = cp[1];
+ unsigned int cb = cp[2];
+ unsigned int ca = cp[3];
+ do {
+ cc -= 4, cp += 4;
+ cp[0] = (char) (cr += cp[0]);
+ cp[1] = (char) (cg += cp[1]);
+ cp[2] = (char) (cb += cp[2]);
+ cp[3] = (char) (ca += cp[3]);
+ } while ((int32) cc > 0);
+ } else {
+ do {
+ REPEAT4(stride, cp[stride] =
+ (char) (cp[stride] + *cp); cp++)
+ cc -= stride;
+ } while ((int32) cc > 0);
+ }
+ }
+#endif
+}
+
+static void
+swabHorAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint16* wp = (uint16*) cp0;
+ tmsize_t wc = cc / 2;
+
+ assert((cc%(2*stride))==0);
+
+ if (wc > stride) {
+ TIFFSwabArrayOfShort(wp, wc);
+ wc -= stride;
+ do {
+ REPEAT4(stride, wp[stride] += wp[0]; wp++)
+ wc -= stride;
+ } while (wc > 0);
+ }
+}
+
+static void
+horAcc16(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint16* wp = (uint16*) cp0;
+ tmsize_t wc = cc / 2;
+
+ assert((cc%(2*stride))==0);
+
+ if (wc > stride) {
+ wc -= stride;
+ do {
+ REPEAT4(stride, wp[stride] += wp[0]; wp++)
+ wc -= stride;
+ } while (wc > 0);
+ }
+}
+
+static void
+swabHorAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint32* wp = (uint32*) cp0;
+ tmsize_t wc = cc / 4;
+
+ assert((cc%(4*stride))==0);
+
+ if (wc > stride) {
+ TIFFSwabArrayOfLong(wp, wc);
+ wc -= stride;
+ do {
+ REPEAT4(stride, wp[stride] += wp[0]; wp++)
+ wc -= stride;
+ } while (wc > 0);
+ }
+}
+
+static void
+horAcc32(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint32* wp = (uint32*) cp0;
+ tmsize_t wc = cc / 4;
+
+ assert((cc%(4*stride))==0);
+
+ if (wc > stride) {
+ wc -= stride;
+ do {
+ REPEAT4(stride, wp[stride] += wp[0]; wp++)
+ wc -= stride;
+ } while (wc > 0);
+ }
+}
+
+/*
+ * Floating point predictor accumulation routine.
+ */
+static void
+fpAcc(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint32 bps = tif->tif_dir.td_bitspersample / 8;
+ tmsize_t wc = cc / bps;
+ tmsize_t count = cc;
+ uint8 *cp = (uint8 *) cp0;
+ uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
+
+ assert((cc%(bps*stride))==0);
+
+ if (!tmp)
+ return;
+
+ while (count > stride) {
+ REPEAT4(stride, cp[stride] += cp[0]; cp++)
+ count -= stride;
+ }
+
+ _TIFFmemcpy(tmp, cp0, cc);
+ cp = (uint8 *) cp0;
+ for (count = 0; count < wc; count++) {
+ uint32 byte;
+ for (byte = 0; byte < bps; byte++) {
+ #if WORDS_BIGENDIAN
+ cp[bps * count + byte] = tmp[byte * wc + count];
+ #else
+ cp[bps * count + byte] =
+ tmp[(bps - byte - 1) * wc + count];
+ #endif
+ }
+ }
+ _TIFFfree(tmp);
+}
+
+/*
+ * Decode a scanline and apply the predictor routine.
+ */
+static int
+PredictorDecodeRow(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->decoderow != NULL);
+ assert(sp->decodepfunc != NULL);
+
+ if ((*sp->decoderow)(tif, op0, occ0, s)) {
+ (*sp->decodepfunc)(tif, op0, occ0);
+ return 1;
+ } else
+ return 0;
+}
+
+/*
+ * Decode a tile/strip and apply the predictor routine.
+ * Note that horizontal differencing must be done on a
+ * row-by-row basis. The width of a "row" has already
+ * been calculated at pre-decode time according to the
+ * strip/tile dimensions.
+ */
+static int
+PredictorDecodeTile(TIFF* tif, uint8* op0, tmsize_t occ0, uint16 s)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->decodetile != NULL);
+
+ if ((*sp->decodetile)(tif, op0, occ0, s)) {
+ tmsize_t rowsize = sp->rowsize;
+ assert(rowsize > 0);
+ assert((occ0%rowsize)==0);
+ assert(sp->decodepfunc != NULL);
+ while (occ0 > 0) {
+ (*sp->decodepfunc)(tif, op0, rowsize);
+ occ0 -= rowsize;
+ op0 += rowsize;
+ }
+ return 1;
+ } else
+ return 0;
+}
+
+static void
+horDiff8(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+ tmsize_t stride = sp->stride;
+ char* cp = (char*) cp0;
+
+ assert((cc%stride)==0);
+
+ if (cc > stride) {
+ cc -= stride;
+ /*
+ * Pipeline the most common cases.
+ */
+ if (stride == 3) {
+ int r1, g1, b1;
+ int r2 = cp[0];
+ int g2 = cp[1];
+ int b2 = cp[2];
+ do {
+ r1 = cp[3]; cp[3] = r1-r2; r2 = r1;
+ g1 = cp[4]; cp[4] = g1-g2; g2 = g1;
+ b1 = cp[5]; cp[5] = b1-b2; b2 = b1;
+ cp += 3;
+ } while ((cc -= 3) > 0);
+ } else if (stride == 4) {
+ int r1, g1, b1, a1;
+ int r2 = cp[0];
+ int g2 = cp[1];
+ int b2 = cp[2];
+ int a2 = cp[3];
+ do {
+ r1 = cp[4]; cp[4] = r1-r2; r2 = r1;
+ g1 = cp[5]; cp[5] = g1-g2; g2 = g1;
+ b1 = cp[6]; cp[6] = b1-b2; b2 = b1;
+ a1 = cp[7]; cp[7] = a1-a2; a2 = a1;
+ cp += 4;
+ } while ((cc -= 4) > 0);
+ } else {
+ cp += cc - 1;
+ do {
+ REPEAT4(stride, cp[stride] -= cp[0]; cp--)
+ } while ((cc -= stride) > 0);
+ }
+ }
+}
+
+static void
+horDiff16(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+ tmsize_t stride = sp->stride;
+ int16 *wp = (int16*) cp0;
+ tmsize_t wc = cc/2;
+
+ assert((cc%(2*stride))==0);
+
+ if (wc > stride) {
+ wc -= stride;
+ wp += wc - 1;
+ do {
+ REPEAT4(stride, wp[stride] -= wp[0]; wp--)
+ wc -= stride;
+ } while (wc > 0);
+ }
+}
+
+static void
+horDiff32(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+ tmsize_t stride = sp->stride;
+ int32 *wp = (int32*) cp0;
+ tmsize_t wc = cc/4;
+
+ assert((cc%(4*stride))==0);
+
+ if (wc > stride) {
+ wc -= stride;
+ wp += wc - 1;
+ do {
+ REPEAT4(stride, wp[stride] -= wp[0]; wp--)
+ wc -= stride;
+ } while (wc > 0);
+ }
+}
+
+/*
+ * Floating point predictor differencing routine.
+ */
+static void
+fpDiff(TIFF* tif, uint8* cp0, tmsize_t cc)
+{
+ tmsize_t stride = PredictorState(tif)->stride;
+ uint32 bps = tif->tif_dir.td_bitspersample / 8;
+ tmsize_t wc = cc / bps;
+ tmsize_t count;
+ uint8 *cp = (uint8 *) cp0;
+ uint8 *tmp = (uint8 *)_TIFFmalloc(cc);
+
+ assert((cc%(bps*stride))==0);
+
+ if (!tmp)
+ return;
+
+ _TIFFmemcpy(tmp, cp0, cc);
+ for (count = 0; count < wc; count++) {
+ uint32 byte;
+ for (byte = 0; byte < bps; byte++) {
+ #if WORDS_BIGENDIAN
+ cp[byte * wc + count] = tmp[bps * count + byte];
+ #else
+ cp[(bps - byte - 1) * wc + count] =
+ tmp[bps * count + byte];
+ #endif
+ }
+ }
+ _TIFFfree(tmp);
+
+ cp = (uint8 *) cp0;
+ cp += cc - stride - 1;
+ for (count = cc; count > stride; count -= stride)
+ REPEAT4(stride, cp[stride] -= cp[0]; cp--)
+}
+
+static int
+PredictorEncodeRow(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->encodepfunc != NULL);
+ assert(sp->encoderow != NULL);
+
+ /* XXX horizontal differencing alters user's data XXX */
+ (*sp->encodepfunc)(tif, bp, cc);
+ return (*sp->encoderow)(tif, bp, cc, s);
+}
+
+static int
+PredictorEncodeTile(TIFF* tif, uint8* bp0, tmsize_t cc0, uint16 s)
+{
+ static const char module[] = "PredictorEncodeTile";
+ TIFFPredictorState *sp = PredictorState(tif);
+ uint8 *working_copy;
+ tmsize_t cc = cc0, rowsize;
+ unsigned char* bp;
+ int result_code;
+
+ assert(sp != NULL);
+ assert(sp->encodepfunc != NULL);
+ assert(sp->encodetile != NULL);
+
+ /*
+ * Do predictor manipulation in a working buffer to avoid altering
+ * the callers buffer. http://trac.osgeo.org/gdal/ticket/1965
+ */
+ working_copy = (uint8*) _TIFFmalloc(cc0);
+ if( working_copy == NULL )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Out of memory allocating " TIFF_SSIZE_FORMAT " byte temp buffer.",
+ cc0 );
+ return 0;
+ }
+ memcpy( working_copy, bp0, cc0 );
+ bp = working_copy;
+
+ rowsize = sp->rowsize;
+ assert(rowsize > 0);
+ assert((cc0%rowsize)==0);
+ while (cc > 0) {
+ (*sp->encodepfunc)(tif, bp, rowsize);
+ cc -= rowsize;
+ bp += rowsize;
+ }
+ result_code = (*sp->encodetile)(tif, working_copy, cc0, s);
+
+ _TIFFfree( working_copy );
+
+ return result_code;
+}
+
+#define FIELD_PREDICTOR (FIELD_CODEC+0) /* XXX */
+
+static const TIFFField predictFields[] = {
+ { TIFFTAG_PREDICTOR, 1, 1, TIFF_SHORT, 0, TIFF_SETGET_UINT16, TIFF_SETGET_UINT16, FIELD_PREDICTOR, FALSE, FALSE, "Predictor", NULL },
+};
+
+static int
+PredictorVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->vsetparent != NULL);
+
+ switch (tag) {
+ case TIFFTAG_PREDICTOR:
+ sp->predictor = (uint16) va_arg(ap, uint16_vap);
+ TIFFSetFieldBit(tif, FIELD_PREDICTOR);
+ break;
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+ return 1;
+}
+
+static int
+PredictorVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ TIFFPredictorState *sp = PredictorState(tif);
+
+ assert(sp != NULL);
+ assert(sp->vgetparent != NULL);
+
+ switch (tag) {
+ case TIFFTAG_PREDICTOR:
+ *va_arg(ap, uint16*) = sp->predictor;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return 1;
+}
+
+static void
+PredictorPrintDir(TIFF* tif, FILE* fd, long flags)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+
+ (void) flags;
+ if (TIFFFieldSet(tif,FIELD_PREDICTOR)) {
+ fprintf(fd, " Predictor: ");
+ switch (sp->predictor) {
+ case 1: fprintf(fd, "none "); break;
+ case 2: fprintf(fd, "horizontal differencing "); break;
+ case 3: fprintf(fd, "floating point predictor "); break;
+ }
+ fprintf(fd, "%u (0x%x)\n", sp->predictor, sp->predictor);
+ }
+ if (sp->printdir)
+ (*sp->printdir)(tif, fd, flags);
+}
+
+int
+TIFFPredictorInit(TIFF* tif)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+
+ assert(sp != 0);
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, predictFields,
+ TIFFArrayCount(predictFields))) {
+ TIFFErrorExt(tif->tif_clientdata, "TIFFPredictorInit",
+ "Merging Predictor codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield =
+ PredictorVGetField;/* hook for predictor tag */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield =
+ PredictorVSetField;/* hook for predictor tag */
+ sp->printdir = tif->tif_tagmethods.printdir;
+ tif->tif_tagmethods.printdir =
+ PredictorPrintDir; /* hook for predictor tag */
+
+ sp->setupdecode = tif->tif_setupdecode;
+ tif->tif_setupdecode = PredictorSetupDecode;
+ sp->setupencode = tif->tif_setupencode;
+ tif->tif_setupencode = PredictorSetupEncode;
+
+ sp->predictor = 1; /* default value */
+ sp->encodepfunc = NULL; /* no predictor routine */
+ sp->decodepfunc = NULL; /* no predictor routine */
+ return 1;
+}
+
+int
+TIFFPredictorCleanup(TIFF* tif)
+{
+ TIFFPredictorState* sp = PredictorState(tif);
+
+ assert(sp != 0);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+ tif->tif_tagmethods.printdir = sp->printdir;
+ tif->tif_setupdecode = sp->setupdecode;
+ tif->tif_setupencode = sp->setupencode;
+
+ return 1;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.h b/core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.h
new file mode 100644
index 0000000000..dc7144c69e
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_predict.h
@@ -0,0 +1,77 @@
+/* $Id: tif_predict.h,v 1.8 2010-03-10 18:56:49 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1995-1997 Sam Leffler
+ * Copyright (c) 1995-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFPREDICT_
+#define _TIFFPREDICT_
+/*
+ * ``Library-private'' Support for the Predictor Tag
+ */
+
+/*
+ * Codecs that want to support the Predictor tag must place
+ * this structure first in their private state block so that
+ * the predictor code can cast tif_data to find its state.
+ */
+typedef struct {
+ int predictor; /* predictor tag value */
+ tmsize_t stride; /* sample stride over data */
+ tmsize_t rowsize; /* tile/strip row size */
+
+ TIFFCodeMethod encoderow; /* parent codec encode/decode row */
+ TIFFCodeMethod encodestrip; /* parent codec encode/decode strip */
+ TIFFCodeMethod encodetile; /* parent codec encode/decode tile */
+ TIFFPostMethod encodepfunc; /* horizontal differencer */
+
+ TIFFCodeMethod decoderow; /* parent codec encode/decode row */
+ TIFFCodeMethod decodestrip; /* parent codec encode/decode strip */
+ TIFFCodeMethod decodetile; /* parent codec encode/decode tile */
+ TIFFPostMethod decodepfunc; /* horizontal accumulator */
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+ TIFFPrintMethod printdir; /* super-class method */
+ TIFFBoolMethod setupdecode; /* super-class method */
+ TIFFBoolMethod setupencode; /* super-class method */
+} TIFFPredictorState;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern int TIFFPredictorInit(TIFF*);
+extern int TIFFPredictorCleanup(TIFF*);
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFPREDICT_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_print.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_print.c
new file mode 100644
index 0000000000..3ee43fc79f
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_print.c
@@ -0,0 +1,719 @@
+/* $Id: tif_print.c,v 1.60 2012-08-19 16:56:35 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Directory Printing Support
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <stdio.h>
+
+#include <ctype.h>
+
+static void
+_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars);
+
+static const char *photoNames[] = {
+ "min-is-white", /* PHOTOMETRIC_MINISWHITE */
+ "min-is-black", /* PHOTOMETRIC_MINISBLACK */
+ "RGB color", /* PHOTOMETRIC_RGB */
+ "palette color (RGB from colormap)", /* PHOTOMETRIC_PALETTE */
+ "transparency mask", /* PHOTOMETRIC_MASK */
+ "separated", /* PHOTOMETRIC_SEPARATED */
+ "YCbCr", /* PHOTOMETRIC_YCBCR */
+ "7 (0x7)",
+ "CIE L*a*b*", /* PHOTOMETRIC_CIELAB */
+ "ICC L*a*b*", /* PHOTOMETRIC_ICCLAB */
+ "ITU L*a*b*" /* PHOTOMETRIC_ITULAB */
+};
+#define NPHOTONAMES (sizeof (photoNames) / sizeof (photoNames[0]))
+
+static const char *orientNames[] = {
+ "0 (0x0)",
+ "row 0 top, col 0 lhs", /* ORIENTATION_TOPLEFT */
+ "row 0 top, col 0 rhs", /* ORIENTATION_TOPRIGHT */
+ "row 0 bottom, col 0 rhs", /* ORIENTATION_BOTRIGHT */
+ "row 0 bottom, col 0 lhs", /* ORIENTATION_BOTLEFT */
+ "row 0 lhs, col 0 top", /* ORIENTATION_LEFTTOP */
+ "row 0 rhs, col 0 top", /* ORIENTATION_RIGHTTOP */
+ "row 0 rhs, col 0 bottom", /* ORIENTATION_RIGHTBOT */
+ "row 0 lhs, col 0 bottom", /* ORIENTATION_LEFTBOT */
+};
+#define NORIENTNAMES (sizeof (orientNames) / sizeof (orientNames[0]))
+
+static void
+_TIFFPrintField(FILE* fd, const TIFFField *fip,
+ uint32 value_count, void *raw_data)
+{
+ uint32 j;
+
+ fprintf(fd, " %s: ", fip->field_name);
+
+ for(j = 0; j < value_count; j++) {
+ if(fip->field_type == TIFF_BYTE)
+ fprintf(fd, "%u", ((uint8 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_UNDEFINED)
+ fprintf(fd, "0x%x",
+ (unsigned int) ((unsigned char *) raw_data)[j]);
+ else if(fip->field_type == TIFF_SBYTE)
+ fprintf(fd, "%d", ((int8 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_SHORT)
+ fprintf(fd, "%u", ((uint16 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_SSHORT)
+ fprintf(fd, "%d", ((int16 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_LONG)
+ fprintf(fd, "%lu",
+ (unsigned long)((uint32 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_SLONG)
+ fprintf(fd, "%ld", (long)((int32 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_IFD)
+ fprintf(fd, "0x%lx",
+ (unsigned long)((uint32 *) raw_data)[j]);
+ else if(fip->field_type == TIFF_RATIONAL
+ || fip->field_type == TIFF_SRATIONAL
+ || fip->field_type == TIFF_FLOAT)
+ fprintf(fd, "%f", ((float *) raw_data)[j]);
+ else if(fip->field_type == TIFF_LONG8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "%I64u",
+ (unsigned __int64)((uint64 *) raw_data)[j]);
+#else
+ fprintf(fd, "%llu",
+ (unsigned long long)((uint64 *) raw_data)[j]);
+#endif
+ else if(fip->field_type == TIFF_SLONG8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "%I64d", (__int64)((int64 *) raw_data)[j]);
+#else
+ fprintf(fd, "%lld", (long long)((int64 *) raw_data)[j]);
+#endif
+ else if(fip->field_type == TIFF_IFD8)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "0x%I64x",
+ (unsigned __int64)((uint64 *) raw_data)[j]);
+#else
+ fprintf(fd, "0x%llx",
+ (unsigned long long)((uint64 *) raw_data)[j]);
+#endif
+ else if(fip->field_type == TIFF_FLOAT)
+ fprintf(fd, "%f", ((float *)raw_data)[j]);
+ else if(fip->field_type == TIFF_DOUBLE)
+ fprintf(fd, "%f", ((double *) raw_data)[j]);
+ else if(fip->field_type == TIFF_ASCII) {
+ fprintf(fd, "%s", (char *) raw_data);
+ break;
+ }
+ else {
+ fprintf(fd, "<unsupported data type in TIFFPrint>");
+ break;
+ }
+
+ if(j < value_count - 1)
+ fprintf(fd, ",");
+ }
+
+ fprintf(fd, "\n");
+}
+
+static int
+_TIFFPrettyPrintField(TIFF* tif, const TIFFField *fip, FILE* fd, uint32 tag,
+ uint32 value_count, void *raw_data)
+{
+ (void) tif;
+
+ /* do not try to pretty print auto-defined fields */
+ if (strncmp(fip->field_name,"Tag ", 4) == 0) {
+ return 0;
+ }
+
+ switch (tag)
+ {
+ case TIFFTAG_INKSET:
+ if (value_count == 2 && fip->field_type == TIFF_SHORT) {
+ fprintf(fd, " Ink Set: ");
+ switch (*((uint16*)raw_data)) {
+ case INKSET_CMYK:
+ fprintf(fd, "CMYK\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ *((uint16*)raw_data),
+ *((uint16*)raw_data));
+ break;
+ }
+ return 1;
+ }
+ return 0;
+
+ case TIFFTAG_DOTRANGE:
+ if (value_count == 2 && fip->field_type == TIFF_SHORT) {
+ fprintf(fd, " Dot Range: %u-%u\n",
+ ((uint16*)raw_data)[0], ((uint16*)raw_data)[1]);
+ return 1;
+ }
+ return 0;
+
+ case TIFFTAG_WHITEPOINT:
+ if (value_count == 2 && fip->field_type == TIFF_RATIONAL) {
+ fprintf(fd, " White Point: %g-%g\n",
+ ((float *)raw_data)[0], ((float *)raw_data)[1]);
+ return 1;
+ }
+ return 0;
+
+ case TIFFTAG_XMLPACKET:
+ {
+ uint32 i;
+
+ fprintf(fd, " XMLPacket (XMP Metadata):\n" );
+ for(i = 0; i < value_count; i++)
+ fputc(((char *)raw_data)[i], fd);
+ fprintf( fd, "\n" );
+ return 1;
+ }
+ case TIFFTAG_RICHTIFFIPTC:
+ /*
+ * XXX: for some weird reason RichTIFFIPTC tag
+ * defined as array of LONG values.
+ */
+ fprintf(fd,
+ " RichTIFFIPTC Data: <present>, %lu bytes\n",
+ (unsigned long) value_count * 4);
+ return 1;
+
+ case TIFFTAG_PHOTOSHOP:
+ fprintf(fd, " Photoshop Data: <present>, %lu bytes\n",
+ (unsigned long) value_count);
+ return 1;
+
+ case TIFFTAG_ICCPROFILE:
+ fprintf(fd, " ICC Profile: <present>, %lu bytes\n",
+ (unsigned long) value_count);
+ return 1;
+
+ case TIFFTAG_STONITS:
+ if (value_count == 1 && fip->field_type == TIFF_DOUBLE) {
+ fprintf(fd,
+ " Sample to Nits conversion factor: %.4e\n",
+ *((double*)raw_data));
+ return 1;
+ }
+ return 0;
+ }
+
+ return 0;
+}
+
+/*
+ * Print the contents of the current directory
+ * to the specified stdio file stream.
+ */
+void
+TIFFPrintDirectory(TIFF* tif, FILE* fd, long flags)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ char *sep;
+ uint16 i;
+ long l, n;
+
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, "TIFF Directory at offset 0x%I64x (%I64u)\n",
+ (unsigned __int64) tif->tif_diroff,
+ (unsigned __int64) tif->tif_diroff);
+#else
+ fprintf(fd, "TIFF Directory at offset 0x%llx (%llu)\n",
+ (unsigned long long) tif->tif_diroff,
+ (unsigned long long) tif->tif_diroff);
+#endif
+ if (TIFFFieldSet(tif,FIELD_SUBFILETYPE)) {
+ fprintf(fd, " Subfile Type:");
+ sep = " ";
+ if (td->td_subfiletype & FILETYPE_REDUCEDIMAGE) {
+ fprintf(fd, "%sreduced-resolution image", sep);
+ sep = "/";
+ }
+ if (td->td_subfiletype & FILETYPE_PAGE) {
+ fprintf(fd, "%smulti-page document", sep);
+ sep = "/";
+ }
+ if (td->td_subfiletype & FILETYPE_MASK)
+ fprintf(fd, "%stransparency mask", sep);
+ fprintf(fd, " (%lu = 0x%lx)\n",
+ (long) td->td_subfiletype, (long) td->td_subfiletype);
+ }
+ if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS)) {
+ fprintf(fd, " Image Width: %lu Image Length: %lu",
+ (unsigned long) td->td_imagewidth, (unsigned long) td->td_imagelength);
+ if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
+ fprintf(fd, " Image Depth: %lu",
+ (unsigned long) td->td_imagedepth);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS)) {
+ fprintf(fd, " Tile Width: %lu Tile Length: %lu",
+ (unsigned long) td->td_tilewidth, (unsigned long) td->td_tilelength);
+ if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
+ fprintf(fd, " Tile Depth: %lu",
+ (unsigned long) td->td_tiledepth);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_RESOLUTION)) {
+ fprintf(fd, " Resolution: %g, %g",
+ td->td_xresolution, td->td_yresolution);
+ if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT)) {
+ switch (td->td_resolutionunit) {
+ case RESUNIT_NONE:
+ fprintf(fd, " (unitless)");
+ break;
+ case RESUNIT_INCH:
+ fprintf(fd, " pixels/inch");
+ break;
+ case RESUNIT_CENTIMETER:
+ fprintf(fd, " pixels/cm");
+ break;
+ default:
+ fprintf(fd, " (unit %u = 0x%x)",
+ td->td_resolutionunit,
+ td->td_resolutionunit);
+ break;
+ }
+ }
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_POSITION))
+ fprintf(fd, " Position: %g, %g\n",
+ td->td_xposition, td->td_yposition);
+ if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
+ fprintf(fd, " Bits/Sample: %u\n", td->td_bitspersample);
+ if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT)) {
+ fprintf(fd, " Sample Format: ");
+ switch (td->td_sampleformat) {
+ case SAMPLEFORMAT_VOID:
+ fprintf(fd, "void\n");
+ break;
+ case SAMPLEFORMAT_INT:
+ fprintf(fd, "signed integer\n");
+ break;
+ case SAMPLEFORMAT_UINT:
+ fprintf(fd, "unsigned integer\n");
+ break;
+ case SAMPLEFORMAT_IEEEFP:
+ fprintf(fd, "IEEE floating point\n");
+ break;
+ case SAMPLEFORMAT_COMPLEXINT:
+ fprintf(fd, "complex signed integer\n");
+ break;
+ case SAMPLEFORMAT_COMPLEXIEEEFP:
+ fprintf(fd, "complex IEEE floating point\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_sampleformat, td->td_sampleformat);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_COMPRESSION)) {
+ const TIFFCodec* c = TIFFFindCODEC(td->td_compression);
+ fprintf(fd, " Compression Scheme: ");
+ if (c)
+ fprintf(fd, "%s\n", c->name);
+ else
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_compression, td->td_compression);
+ }
+ if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC)) {
+ fprintf(fd, " Photometric Interpretation: ");
+ if (td->td_photometric < NPHOTONAMES)
+ fprintf(fd, "%s\n", photoNames[td->td_photometric]);
+ else {
+ switch (td->td_photometric) {
+ case PHOTOMETRIC_LOGL:
+ fprintf(fd, "CIE Log2(L)\n");
+ break;
+ case PHOTOMETRIC_LOGLUV:
+ fprintf(fd, "CIE Log2(L) (u',v')\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_photometric, td->td_photometric);
+ break;
+ }
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES) && td->td_extrasamples) {
+ fprintf(fd, " Extra Samples: %u<", td->td_extrasamples);
+ sep = "";
+ for (i = 0; i < td->td_extrasamples; i++) {
+ switch (td->td_sampleinfo[i]) {
+ case EXTRASAMPLE_UNSPECIFIED:
+ fprintf(fd, "%sunspecified", sep);
+ break;
+ case EXTRASAMPLE_ASSOCALPHA:
+ fprintf(fd, "%sassoc-alpha", sep);
+ break;
+ case EXTRASAMPLE_UNASSALPHA:
+ fprintf(fd, "%sunassoc-alpha", sep);
+ break;
+ default:
+ fprintf(fd, "%s%u (0x%x)", sep,
+ td->td_sampleinfo[i], td->td_sampleinfo[i]);
+ break;
+ }
+ sep = ", ";
+ }
+ fprintf(fd, ">\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_INKNAMES)) {
+ char* cp;
+ fprintf(fd, " Ink Names: ");
+ i = td->td_samplesperpixel;
+ sep = "";
+ for (cp = td->td_inknames;
+ i > 0 && cp < td->td_inknames + td->td_inknameslen;
+ cp = strchr(cp,'\0')+1, i--) {
+ int max_chars =
+ (int)(td->td_inknameslen - (cp - td->td_inknames));
+ fputs(sep, fd);
+ _TIFFprintAsciiBounded(fd, cp, max_chars);
+ sep = ", ";
+ }
+ fputs("\n", fd);
+ }
+ if (TIFFFieldSet(tif,FIELD_THRESHHOLDING)) {
+ fprintf(fd, " Thresholding: ");
+ switch (td->td_threshholding) {
+ case THRESHHOLD_BILEVEL:
+ fprintf(fd, "bilevel art scan\n");
+ break;
+ case THRESHHOLD_HALFTONE:
+ fprintf(fd, "halftone or dithered scan\n");
+ break;
+ case THRESHHOLD_ERRORDIFFUSE:
+ fprintf(fd, "error diffused\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_threshholding, td->td_threshholding);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_FILLORDER)) {
+ fprintf(fd, " FillOrder: ");
+ switch (td->td_fillorder) {
+ case FILLORDER_MSB2LSB:
+ fprintf(fd, "msb-to-lsb\n");
+ break;
+ case FILLORDER_LSB2MSB:
+ fprintf(fd, "lsb-to-msb\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_fillorder, td->td_fillorder);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
+ {
+ fprintf(fd, " YCbCr Subsampling: %u, %u\n",
+ td->td_ycbcrsubsampling[0], td->td_ycbcrsubsampling[1] );
+ }
+ if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING)) {
+ fprintf(fd, " YCbCr Positioning: ");
+ switch (td->td_ycbcrpositioning) {
+ case YCBCRPOSITION_CENTERED:
+ fprintf(fd, "centered\n");
+ break;
+ case YCBCRPOSITION_COSITED:
+ fprintf(fd, "cosited\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_ycbcrpositioning, td->td_ycbcrpositioning);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
+ fprintf(fd, " Halftone Hints: light %u dark %u\n",
+ td->td_halftonehints[0], td->td_halftonehints[1]);
+ if (TIFFFieldSet(tif,FIELD_ORIENTATION)) {
+ fprintf(fd, " Orientation: ");
+ if (td->td_orientation < NORIENTNAMES)
+ fprintf(fd, "%s\n", orientNames[td->td_orientation]);
+ else
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_orientation, td->td_orientation);
+ }
+ if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
+ fprintf(fd, " Samples/Pixel: %u\n", td->td_samplesperpixel);
+ if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP)) {
+ fprintf(fd, " Rows/Strip: ");
+ if (td->td_rowsperstrip == (uint32) -1)
+ fprintf(fd, "(infinite)\n");
+ else
+ fprintf(fd, "%lu\n", (unsigned long) td->td_rowsperstrip);
+ }
+ if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
+ fprintf(fd, " Min Sample Value: %u\n", td->td_minsamplevalue);
+ if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
+ fprintf(fd, " Max Sample Value: %u\n", td->td_maxsamplevalue);
+ if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE)) {
+ int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+ fprintf(fd, " SMin Sample Value:");
+ for (i = 0; i < count; ++i)
+ fprintf(fd, " %g", td->td_sminsamplevalue[i]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE)) {
+ int count = (tif->tif_flags & TIFF_PERSAMPLE) ? td->td_samplesperpixel : 1;
+ fprintf(fd, " SMax Sample Value:");
+ for (i = 0; i < count; ++i)
+ fprintf(fd, " %g", td->td_smaxsamplevalue[i]);
+ fprintf(fd, "\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_PLANARCONFIG)) {
+ fprintf(fd, " Planar Configuration: ");
+ switch (td->td_planarconfig) {
+ case PLANARCONFIG_CONTIG:
+ fprintf(fd, "single image plane\n");
+ break;
+ case PLANARCONFIG_SEPARATE:
+ fprintf(fd, "separate image planes\n");
+ break;
+ default:
+ fprintf(fd, "%u (0x%x)\n",
+ td->td_planarconfig, td->td_planarconfig);
+ break;
+ }
+ }
+ if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
+ fprintf(fd, " Page Number: %u-%u\n",
+ td->td_pagenumber[0], td->td_pagenumber[1]);
+ if (TIFFFieldSet(tif,FIELD_COLORMAP)) {
+ fprintf(fd, " Color Map: ");
+ if (flags & TIFFPRINT_COLORMAP) {
+ fprintf(fd, "\n");
+ n = 1L<<td->td_bitspersample;
+ for (l = 0; l < n; l++)
+ fprintf(fd, " %5lu: %5u %5u %5u\n",
+ l,
+ td->td_colormap[0][l],
+ td->td_colormap[1][l],
+ td->td_colormap[2][l]);
+ } else
+ fprintf(fd, "(present)\n");
+ }
+ if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE)) {
+ fprintf(fd, " Reference Black/White:\n");
+ for (i = 0; i < 3; i++)
+ fprintf(fd, " %2d: %5g %5g\n", i,
+ td->td_refblackwhite[2*i+0],
+ td->td_refblackwhite[2*i+1]);
+ }
+ if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION)) {
+ fprintf(fd, " Transfer Function: ");
+ if (flags & TIFFPRINT_CURVES) {
+ fprintf(fd, "\n");
+ n = 1L<<td->td_bitspersample;
+ for (l = 0; l < n; l++) {
+ fprintf(fd, " %2lu: %5u",
+ l, td->td_transferfunction[0][l]);
+ for (i = 1; i < td->td_samplesperpixel; i++)
+ fprintf(fd, " %5u",
+ td->td_transferfunction[i][l]);
+ fputc('\n', fd);
+ }
+ } else
+ fprintf(fd, "(present)\n");
+ }
+ if (TIFFFieldSet(tif, FIELD_SUBIFD) && (td->td_subifd)) {
+ fprintf(fd, " SubIFD Offsets:");
+ for (i = 0; i < td->td_nsubifd; i++)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, " %5I64u",
+ (unsigned __int64) td->td_subifd[i]);
+#else
+ fprintf(fd, " %5llu",
+ (unsigned long long) td->td_subifd[i]);
+#endif
+ fputc('\n', fd);
+ }
+
+ /*
+ ** Custom tag support.
+ */
+ {
+ int i;
+ short count;
+
+ count = (short) TIFFGetTagListCount(tif);
+ for(i = 0; i < count; i++) {
+ uint32 tag = TIFFGetTagListEntry(tif, i);
+ const TIFFField *fip;
+ uint32 value_count;
+ int mem_alloc = 0;
+ void *raw_data;
+
+ fip = TIFFFieldWithTag(tif, tag);
+ if(fip == NULL)
+ continue;
+
+ if(fip->field_passcount) {
+ if (fip->field_readcount == TIFF_VARIABLE ) {
+ if(TIFFGetField(tif, tag, &value_count, &raw_data) != 1)
+ continue;
+ } else if (fip->field_readcount == TIFF_VARIABLE2 ) {
+ uint16 small_value_count;
+ if(TIFFGetField(tif, tag, &small_value_count, &raw_data) != 1)
+ continue;
+ value_count = small_value_count;
+ } else {
+ assert (fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2);
+ continue;
+ }
+ } else {
+ if (fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2)
+ value_count = 1;
+ else if (fip->field_readcount == TIFF_SPP)
+ value_count = td->td_samplesperpixel;
+ else
+ value_count = fip->field_readcount;
+ if (fip->field_tag == TIFFTAG_DOTRANGE
+ && strcmp(fip->field_name,"DotRange") == 0) {
+ /* TODO: This is an evil exception and should not have been
+ handled this way ... likely best if we move it into
+ the directory structure with an explicit field in
+ libtiff 4.1 and assign it a FIELD_ value */
+ static uint16 dotrange[2];
+ raw_data = dotrange;
+ TIFFGetField(tif, tag, dotrange+0, dotrange+1);
+ } else if (fip->field_type == TIFF_ASCII
+ || fip->field_readcount == TIFF_VARIABLE
+ || fip->field_readcount == TIFF_VARIABLE2
+ || fip->field_readcount == TIFF_SPP
+ || value_count > 1) {
+ if(TIFFGetField(tif, tag, &raw_data) != 1)
+ continue;
+ } else {
+ raw_data = _TIFFmalloc(
+ _TIFFDataSize(fip->field_type)
+ * value_count);
+ mem_alloc = 1;
+ if(TIFFGetField(tif, tag, raw_data) != 1) {
+ _TIFFfree(raw_data);
+ continue;
+ }
+ }
+ }
+
+ /*
+ * Catch the tags which needs to be specially handled
+ * and pretty print them. If tag not handled in
+ * _TIFFPrettyPrintField() fall down and print it as
+ * any other tag.
+ */
+ if (!_TIFFPrettyPrintField(tif, fip, fd, tag, value_count, raw_data))
+ _TIFFPrintField(fd, fip, value_count, raw_data);
+
+ if(mem_alloc)
+ _TIFFfree(raw_data);
+ }
+ }
+
+ if (tif->tif_tagmethods.printdir)
+ (*tif->tif_tagmethods.printdir)(tif, fd, flags);
+
+ _TIFFFillStriles( tif );
+
+ if ((flags & TIFFPRINT_STRIPS) &&
+ TIFFFieldSet(tif,FIELD_STRIPOFFSETS)) {
+ uint32 s;
+
+ fprintf(fd, " %lu %s:\n",
+ (long) td->td_nstrips,
+ isTiled(tif) ? "Tiles" : "Strips");
+ for (s = 0; s < td->td_nstrips; s++)
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ fprintf(fd, " %3lu: [%8I64u, %8I64u]\n",
+ (unsigned long) s,
+ (unsigned __int64) td->td_stripoffset[s],
+ (unsigned __int64) td->td_stripbytecount[s]);
+#else
+ fprintf(fd, " %3lu: [%8llu, %8llu]\n",
+ (unsigned long) s,
+ (unsigned long long) td->td_stripoffset[s],
+ (unsigned long long) td->td_stripbytecount[s]);
+#endif
+ }
+}
+
+void
+_TIFFprintAscii(FILE* fd, const char* cp)
+{
+ _TIFFprintAsciiBounded( fd, cp, (int)strlen(cp));
+}
+
+static void
+_TIFFprintAsciiBounded(FILE* fd, const char* cp, int max_chars)
+{
+ for (; max_chars > 0 && *cp != '\0'; cp++, max_chars--) {
+ const char* tp;
+
+ if (isprint((int)*cp)) {
+ fputc(*cp, fd);
+ continue;
+ }
+ for (tp = "\tt\bb\rr\nn\vv"; *tp; tp++)
+ if (*tp++ == *cp)
+ break;
+ if (*tp)
+ fprintf(fd, "\\%c", *tp);
+ else
+ fprintf(fd, "\\%03o", *cp & 0xff);
+ }
+}
+
+void
+_TIFFprintAsciiTag(FILE* fd, const char* name, const char* value)
+{
+ fprintf(fd, " %s: \"", name);
+ _TIFFprintAscii(fd, value);
+ fprintf(fd, "\"\n");
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_read.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_read.c
new file mode 100644
index 0000000000..a25a5a6894
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_read.c
@@ -0,0 +1,1116 @@
+/* $Id: tif_read.c,v 1.41 2012-07-06 19:22:58 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ * Scanline-oriented Read Support
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <stdio.h>
+
+int TIFFFillStrip(TIFF* tif, uint32 strip);
+int TIFFFillTile(TIFF* tif, uint32 tile);
+static int TIFFStartStrip(TIFF* tif, uint32 strip);
+static int TIFFStartTile(TIFF* tif, uint32 tile);
+static int TIFFCheckRead(TIFF*, int);
+static tmsize_t
+TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,const char* module);
+
+#define NOSTRIP ((uint32)(-1)) /* undefined state */
+#define NOTILE ((uint32)(-1)) /* undefined state */
+
+static int
+TIFFFillStripPartial( TIFF *tif, int strip, tmsize_t read_ahead, int restart )
+{
+ static const char module[] = "TIFFFillStripPartial";
+ register TIFFDirectory *td = &tif->tif_dir;
+ uint64 unused_data;
+ uint64 read_offset;
+ tmsize_t cc, to_read;
+ /* tmsize_t bytecountm; */
+
+ if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+ return 0;
+
+ /*
+ * Expand raw data buffer, if needed, to hold data
+ * strip coming from file (perhaps should set upper
+ * bound on the size of a buffer we'll use?).
+ */
+
+ /* bytecountm=(tmsize_t) td->td_stripbytecount[strip]; */
+ if (read_ahead*2 > tif->tif_rawdatasize) {
+ assert( restart );
+
+ tif->tif_curstrip = NOSTRIP;
+ if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Data buffer too small to hold part of strip %lu",
+ (unsigned long) strip);
+ return (0);
+ }
+ if (!TIFFReadBufferSetup(tif, 0, read_ahead*2))
+ return (0);
+ }
+
+ if( restart )
+ {
+ tif->tif_rawdataloaded = 0;
+ tif->tif_rawdataoff = 0;
+ }
+
+ /*
+ ** If we are reading more data, move any unused data to the
+ ** start of the buffer.
+ */
+ if( tif->tif_rawdataloaded > 0 )
+ unused_data = tif->tif_rawdataloaded - (tif->tif_rawcp - tif->tif_rawdata);
+ else
+ unused_data = 0;
+
+ if( unused_data > 0 )
+ {
+ assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
+ memmove( tif->tif_rawdata, tif->tif_rawcp, (size_t)unused_data );
+ }
+
+ /*
+ ** Seek to the point in the file where more data should be read.
+ */
+ read_offset = td->td_stripoffset[strip]
+ + tif->tif_rawdataoff + tif->tif_rawdataloaded;
+
+ if (!SeekOK(tif, read_offset)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Seek error at scanline %lu, strip %lu",
+ (unsigned long) tif->tif_row, (unsigned long) strip);
+ return 0;
+ }
+
+ /*
+ ** How much do we want to read?
+ */
+ to_read = (tmsize_t)(tif->tif_rawdatasize - unused_data);
+ if( (uint64) to_read > td->td_stripbytecount[strip]
+ - tif->tif_rawdataoff - tif->tif_rawdataloaded )
+ {
+ to_read = (tmsize_t)(td->td_stripbytecount[strip]
+ - tif->tif_rawdataoff - tif->tif_rawdataloaded);
+ }
+
+ assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
+ cc = TIFFReadFile(tif, tif->tif_rawdata + unused_data, to_read);
+
+ if (cc != to_read) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at scanline %lu; got %I64u bytes, expected %I64u",
+ (unsigned long) tif->tif_row,
+ (unsigned __int64) cc,
+ (unsigned __int64) to_read);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at scanline %lu; got %llu bytes, expected %llu",
+ (unsigned long) tif->tif_row,
+ (unsigned long long) cc,
+ (unsigned long long) to_read);
+#endif
+ return 0;
+ }
+
+ tif->tif_rawdataoff = (tmsize_t)(tif->tif_rawdataoff + tif->tif_rawdataloaded - unused_data) ;
+ tif->tif_rawdataloaded = (tmsize_t)unused_data + to_read;
+
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0) {
+ assert((tif->tif_flags&TIFF_BUFFERMMAP)==0);
+ TIFFReverseBits(tif->tif_rawdata + unused_data, to_read );
+ }
+
+ /*
+ ** When starting a strip from the beginning we need to
+ ** restart the decoder.
+ */
+ if( restart )
+ return TIFFStartStrip(tif, strip);
+ else
+ return 1;
+}
+
+/*
+ * Seek to a random row+sample in a file.
+ *
+ * Only used by TIFFReadScanline, and is only used on
+ * strip organized files. We do some tricky stuff to try
+ * and avoid reading the whole compressed raw data for big
+ * strips.
+ */
+static int
+TIFFSeek(TIFF* tif, uint32 row, uint16 sample )
+{
+ register TIFFDirectory *td = &tif->tif_dir;
+ uint32 strip;
+ int whole_strip;
+ tmsize_t read_ahead = 0;
+
+ /*
+ ** Establish what strip we are working from.
+ */
+ if (row >= td->td_imagelength) { /* out of range */
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%lu: Row out of range, max %lu",
+ (unsigned long) row,
+ (unsigned long) td->td_imagelength);
+ return (0);
+ }
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+ if (sample >= td->td_samplesperpixel) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%lu: Sample out of range, max %lu",
+ (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
+ return (0);
+ }
+ strip = (uint32)sample*td->td_stripsperimage + row/td->td_rowsperstrip;
+ } else
+ strip = row / td->td_rowsperstrip;
+
+ /*
+ * Do we want to treat this strip as one whole chunk or
+ * read it a few lines at a time?
+ */
+#if defined(CHUNKY_STRIP_READ_SUPPORT)
+ if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+ return 0;
+ whole_strip = tif->tif_dir.td_stripbytecount[strip] < 10
+ || isMapped(tif);
+#else
+ whole_strip = 1;
+#endif
+
+ if( !whole_strip )
+ {
+ read_ahead = tif->tif_scanlinesize * 16 + 5000;
+ }
+
+ /*
+ * If we haven't loaded this strip, do so now, possibly
+ * only reading the first part.
+ */
+ if (strip != tif->tif_curstrip) { /* different strip, refill */
+
+ if( whole_strip )
+ {
+ if (!TIFFFillStrip(tif, strip))
+ return (0);
+ }
+ else
+ {
+ if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
+ return 0;
+ }
+ }
+
+ /*
+ ** If we already have some data loaded, do we need to read some more?
+ */
+ else if( !whole_strip )
+ {
+ if( ((tif->tif_rawdata + tif->tif_rawdataloaded) - tif->tif_rawcp) < read_ahead
+ && (uint64) tif->tif_rawdataoff+tif->tif_rawdataloaded < td->td_stripbytecount[strip] )
+ {
+ if( !TIFFFillStripPartial(tif,strip,read_ahead,0) )
+ return 0;
+ }
+ }
+
+ if (row < tif->tif_row) {
+ /*
+ * Moving backwards within the same strip: backup
+ * to the start and then decode forward (below).
+ *
+ * NB: If you're planning on lots of random access within a
+ * strip, it's better to just read and decode the entire
+ * strip, and then access the decoded data in a random fashion.
+ */
+
+ if( tif->tif_rawdataoff != 0 )
+ {
+ if( !TIFFFillStripPartial(tif,strip,read_ahead,1) )
+ return 0;
+ }
+ else
+ {
+ if (!TIFFStartStrip(tif, strip))
+ return (0);
+ }
+ }
+
+ if (row != tif->tif_row) {
+ /*
+ * Seek forward to the desired row.
+ */
+
+ /* TODO: Will this really work with partial buffers? */
+
+ if (!(*tif->tif_seek)(tif, row - tif->tif_row))
+ return (0);
+ tif->tif_row = row;
+ }
+
+ return (1);
+}
+
+int
+TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
+{
+ int e;
+
+ if (!TIFFCheckRead(tif, 0))
+ return (-1);
+ if( (e = TIFFSeek(tif, row, sample)) != 0) {
+ /*
+ * Decompress desired row into user buffer.
+ */
+ e = (*tif->tif_decoderow)
+ (tif, (uint8*) buf, tif->tif_scanlinesize, sample);
+
+ /* we are now poised at the beginning of the next row */
+ tif->tif_row = row + 1;
+
+ if (e)
+ (*tif->tif_postdecode)(tif, (uint8*) buf,
+ tif->tif_scanlinesize);
+ }
+ return (e > 0 ? 1 : -1);
+}
+
+/*
+ * Read a strip of data and decompress the specified
+ * amount into the user-supplied buffer.
+ */
+tmsize_t
+TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+{
+ static const char module[] = "TIFFReadEncodedStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 rowsperstrip;
+ uint32 stripsperplane;
+ uint32 stripinplane;
+ uint16 plane, comp;
+ uint32 rows;
+ tmsize_t stripsize;
+ if (!TIFFCheckRead(tif,0))
+ return((tmsize_t)(-1));
+ if (strip>=td->td_nstrips)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "%lu: Strip out of range, max %lu",(unsigned long)strip,
+ (unsigned long)td->td_nstrips);
+ return((tmsize_t)(-1));
+ }
+ /*
+ * Calculate the strip size according to the number of
+ * rows in the strip (check for truncated last strip on any
+ * of the separations).
+ */
+ rowsperstrip=td->td_rowsperstrip;
+ if (rowsperstrip>td->td_imagelength)
+ rowsperstrip=td->td_imagelength;
+ stripsperplane=((td->td_imagelength+rowsperstrip-1)/rowsperstrip);
+ stripinplane=(strip%stripsperplane);
+ plane=(strip/stripsperplane);
+ rows=td->td_imagelength-stripinplane*rowsperstrip;
+ if (rows>rowsperstrip)
+ rows=rowsperstrip;
+ stripsize=TIFFVStripSize(tif,rows);
+ if (stripsize==0)
+ return((tmsize_t)(-1));
+ if ((size!=(tmsize_t)(-1))&&(size<stripsize))
+ stripsize=size;
+
+ /*
+ * discard those.
+ * keep code modified by Changjin Gao.
+ * Xiaochuan Liu 20100828.
+ */
+ /*if (!TIFFFillStrip(tif,strip))
+ return((tmsize_t)(-1));
+ if ((*tif->tif_decodestrip)(tif,buf,stripsize,plane)<=0)
+ return((tmsize_t)(-1));
+ (*tif->tif_postdecode)(tif,buf,stripsize);
+ return(stripsize);*/
+
+ /*
+ * Changjin Gao 20110726 fixed decode error issue.
+ * Test file: mantis #27308 020511-1158450.tiff.
+ */
+ comp = COMPRESSION_NONE;
+StripDecode:
+ if (TIFFFillStrip(tif, strip) && (*tif->tif_decodestrip)(tif, buf, stripsize, plane) > 0)
+ {
+ (*tif->tif_postdecode)(tif, buf, stripsize);
+ return (stripsize);
+ }
+ else
+ {
+ if (comp < 9)
+ {
+ TIFFSetField(tif, TIFFTAG_COMPRESSION, comp);
+ TIFFSetField(tif, TIFFTAG_FAXMODE,FAXMODE_CLASSIC);
+ comp++;
+ goto StripDecode;
+ }
+
+ return ((tsize_t) -1);
+ }
+}
+
+static tmsize_t
+TIFFReadRawStrip1(TIFF* tif, uint32 strip, void* buf, tmsize_t size,
+ const char* module)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!_TIFFFillStriles( tif ))
+ return ((tmsize_t)(-1));
+
+ assert((tif->tif_flags&TIFF_NOREADRAW)==0);
+ if (!isMapped(tif)) {
+ tmsize_t cc;
+
+ if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Seek error at scanline %lu, strip %lu",
+ (unsigned long) tif->tif_row, (unsigned long) strip);
+ return ((tmsize_t)(-1));
+ }
+ cc = TIFFReadFile(tif, buf, size);
+ if (cc != size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at scanline %lu; got %I64u bytes, expected %I64u",
+ (unsigned long) tif->tif_row,
+ (unsigned __int64) cc,
+ (unsigned __int64) size);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at scanline %lu; got %llu bytes, expected %llu",
+ (unsigned long) tif->tif_row,
+ (unsigned long long) cc,
+ (unsigned long long) size);
+#endif
+ return ((tmsize_t)(-1));
+ }
+ } else {
+ tmsize_t ma,mb;
+ tmsize_t n;
+ ma=(tmsize_t)td->td_stripoffset[strip];
+ mb=ma+size;
+ if (((uint64)ma!=td->td_stripoffset[strip])||(ma>tif->tif_size))
+ n=0;
+ else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
+ n=tif->tif_size-ma;
+ else
+ n=size;
+ if (n!=size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at scanline %lu, strip %lu; got %I64u bytes, expected %I64u",
+ (unsigned long) tif->tif_row,
+ (unsigned long) strip,
+ (unsigned __int64) n,
+ (unsigned __int64) size);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at scanline %lu, strip %lu; got %llu bytes, expected %llu",
+ (unsigned long) tif->tif_row,
+ (unsigned long) strip,
+ (unsigned long long) n,
+ (unsigned long long) size);
+#endif
+ return ((tmsize_t)(-1));
+ }
+ _TIFFmemcpy(buf, tif->tif_base + ma,
+ size);
+ }
+ return (size);
+}
+
+/*
+ * Read a strip of data from the file.
+ */
+tmsize_t
+TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size)
+{
+ static const char module[] = "TIFFReadRawStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 bytecount;
+ tmsize_t bytecountm;
+
+ if (!TIFFCheckRead(tif, 0))
+ return ((tmsize_t)(-1));
+ if (strip >= td->td_nstrips) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%lu: Strip out of range, max %lu",
+ (unsigned long) strip,
+ (unsigned long) td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ if (tif->tif_flags&TIFF_NOREADRAW)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Compression scheme does not support access to raw uncompressed data");
+ return ((tmsize_t)(-1));
+ }
+ bytecount = td->td_stripbytecount[strip];
+ if (bytecount <= 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%I64u: Invalid strip byte count, strip %lu",
+ (unsigned __int64) bytecount,
+ (unsigned long) strip);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%llu: Invalid strip byte count, strip %lu",
+ (unsigned long long) bytecount,
+ (unsigned long) strip);
+#endif
+ return ((tmsize_t)(-1));
+ }
+ bytecountm = (tmsize_t)bytecount;
+ if ((uint64)bytecountm!=bytecount) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Integer overflow");
+ return ((tmsize_t)(-1));
+ }
+ if (size != (tmsize_t)(-1) && size < bytecountm)
+ bytecountm = size;
+ return (TIFFReadRawStrip1(tif, strip, buf, bytecountm, module));
+}
+
+/*
+ * Read the specified strip and setup for decoding. The data buffer is
+ * expanded, as necessary, to hold the strip's data.
+ */
+int
+TIFFFillStrip(TIFF* tif, uint32 strip)
+{
+ static const char module[] = "TIFFFillStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+ return 0;
+
+ if ((tif->tif_flags&TIFF_NOREADRAW)==0)
+ {
+ uint64 bytecount = td->td_stripbytecount[strip];
+ if (bytecount <= 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Invalid strip byte count %I64u, strip %lu",
+ (unsigned __int64) bytecount,
+ (unsigned long) strip);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Invalid strip byte count %llu, strip %lu",
+ (unsigned long long) bytecount,
+ (unsigned long) strip);
+#endif
+ return (0);
+ }
+ if (isMapped(tif) &&
+ (isFillOrder(tif, td->td_fillorder)
+ || (tif->tif_flags & TIFF_NOBITREV))) {
+ /*
+ * The image is mapped into memory and we either don't
+ * need to flip bits or the compression routine is
+ * going to handle this operation itself. In this
+ * case, avoid copying the raw data and instead just
+ * reference the data from the memory mapped file
+ * image. This assumes that the decompression
+ * routines do not modify the contents of the raw data
+ * buffer (if they try to, the application will get a
+ * fault since the file is mapped read-only).
+ */
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ }
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ /*
+ * We must check for overflow, potentially causing
+ * an OOB read. Instead of simple
+ *
+ * td->td_stripoffset[strip]+bytecount > tif->tif_size
+ *
+ * comparison (which can overflow) we do the following
+ * two comparisons:
+ */
+ if (bytecount > (uint64)tif->tif_size ||
+ td->td_stripoffset[strip] > (uint64)tif->tif_size - bytecount) {
+ /*
+ * This error message might seem strange, but
+ * it's what would happen if a read were done
+ * instead.
+ */
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+
+ "Read error on strip %lu; "
+ "got %I64u bytes, expected %I64u",
+ (unsigned long) strip,
+ (unsigned __int64) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned __int64) bytecount);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+
+ "Read error on strip %lu; "
+ "got %llu bytes, expected %llu",
+ (unsigned long) strip,
+ (unsigned long long) tif->tif_size - td->td_stripoffset[strip],
+ (unsigned long long) bytecount);
+#endif
+ tif->tif_curstrip = NOSTRIP;
+ return (0);
+ }
+ tif->tif_rawdatasize = (tmsize_t)bytecount;
+ tif->tif_rawdata = tif->tif_base + (tmsize_t)td->td_stripoffset[strip];
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = (tmsize_t) bytecount;
+
+ /*
+ * When we have tif_rawdata reference directly into the memory mapped file
+ * we need to be pretty careful about how we use the rawdata. It is not
+ * a general purpose working buffer as it normally otherwise is. So we
+ * keep track of this fact to avoid using it improperly.
+ */
+ tif->tif_flags |= TIFF_BUFFERMMAP;
+ } else {
+ /*
+ * Expand raw data buffer, if needed, to hold data
+ * strip coming from file (perhaps should set upper
+ * bound on the size of a buffer we'll use?).
+ */
+ tmsize_t bytecountm;
+ bytecountm=(tmsize_t)bytecount;
+ if ((uint64)bytecountm!=bytecount)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ return(0);
+ }
+ if (bytecountm > tif->tif_rawdatasize) {
+ tif->tif_curstrip = NOSTRIP;
+ if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Data buffer too small to hold strip %lu",
+ (unsigned long) strip);
+ return (0);
+ }
+ if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+ return (0);
+ }
+ if (tif->tif_flags&TIFF_BUFFERMMAP) {
+ tif->tif_curstrip = NOSTRIP;
+ if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+ return (0);
+ }
+ if (TIFFReadRawStrip1(tif, strip, tif->tif_rawdata,
+ bytecountm, module) != bytecountm)
+ return (0);
+
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = bytecountm;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(tif->tif_rawdata, bytecountm);
+ }
+ }
+ return (TIFFStartStrip(tif, strip));
+}
+
+/*
+ * Tile-oriented Read Support
+ * Contributed by Nancy Cam (Silicon Graphics).
+ */
+
+/*
+ * Read and decompress a tile of data. The
+ * tile is selected by the (x,y,z,s) coordinates.
+ */
+tmsize_t
+TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+ if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s))
+ return ((tmsize_t)(-1));
+ return (TIFFReadEncodedTile(tif,
+ TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
+}
+
+/*
+ * Read a tile of data and decompress the specified
+ * amount into the user-supplied buffer.
+ */
+tmsize_t
+TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
+{
+ static const char module[] = "TIFFReadEncodedTile";
+ TIFFDirectory *td = &tif->tif_dir;
+ tmsize_t tilesize = tif->tif_tilesize;
+
+ if (!TIFFCheckRead(tif, 1))
+ return ((tmsize_t)(-1));
+ if (tile >= td->td_nstrips) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%lu: Tile out of range, max %lu",
+ (unsigned long) tile, (unsigned long) td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ if (size == (tmsize_t)(-1))
+ size = tilesize;
+ else if (size > tilesize)
+ size = tilesize;
+ if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif,
+ (uint8*) buf, size, (uint16)(tile/td->td_stripsperimage))) {
+ (*tif->tif_postdecode)(tif, (uint8*) buf, size);
+ return (size);
+ } else
+ return ((tmsize_t)(-1));
+}
+
+static tmsize_t
+TIFFReadRawTile1(TIFF* tif, uint32 tile, void* buf, tmsize_t size, const char* module)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!_TIFFFillStriles( tif ))
+ return ((tmsize_t)(-1));
+
+ assert((tif->tif_flags&TIFF_NOREADRAW)==0);
+ if (!isMapped(tif)) {
+ tmsize_t cc;
+
+ if (!SeekOK(tif, td->td_stripoffset[tile])) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Seek error at row %lu, col %lu, tile %lu",
+ (unsigned long) tif->tif_row,
+ (unsigned long) tif->tif_col,
+ (unsigned long) tile);
+ return ((tmsize_t)(-1));
+ }
+ cc = TIFFReadFile(tif, buf, size);
+ if (cc != size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at row %lu, col %lu; got %I64u bytes, expected %I64u",
+ (unsigned long) tif->tif_row,
+ (unsigned long) tif->tif_col,
+ (unsigned __int64) cc,
+ (unsigned __int64) size);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Read error at row %lu, col %lu; got %llu bytes, expected %llu",
+ (unsigned long) tif->tif_row,
+ (unsigned long) tif->tif_col,
+ (unsigned long long) cc,
+ (unsigned long long) size);
+#endif
+ return ((tmsize_t)(-1));
+ }
+ } else {
+ tmsize_t ma,mb;
+ tmsize_t n;
+ ma=(tmsize_t)td->td_stripoffset[tile];
+ mb=ma+size;
+ if (((uint64)ma!=td->td_stripoffset[tile])||(ma>tif->tif_size))
+ n=0;
+ else if ((mb<ma)||(mb<size)||(mb>tif->tif_size))
+ n=tif->tif_size-ma;
+ else
+ n=size;
+ if (n!=size) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+"Read error at row %lu, col %lu, tile %lu; got %I64u bytes, expected %I64u",
+ (unsigned long) tif->tif_row,
+ (unsigned long) tif->tif_col,
+ (unsigned long) tile,
+ (unsigned __int64) n,
+ (unsigned __int64) size);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+"Read error at row %lu, col %lu, tile %lu; got %llu bytes, expected %llu",
+ (unsigned long) tif->tif_row,
+ (unsigned long) tif->tif_col,
+ (unsigned long) tile,
+ (unsigned long long) n,
+ (unsigned long long) size);
+#endif
+ return ((tmsize_t)(-1));
+ }
+ _TIFFmemcpy(buf, tif->tif_base + ma, size);
+ }
+ return (size);
+}
+
+/*
+ * Read a tile of data from the file.
+ */
+tmsize_t
+TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size)
+{
+ static const char module[] = "TIFFReadRawTile";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 bytecount64;
+ tmsize_t bytecountm;
+
+ if (!TIFFCheckRead(tif, 1))
+ return ((tmsize_t)(-1));
+ if (tile >= td->td_nstrips) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%lu: Tile out of range, max %lu",
+ (unsigned long) tile, (unsigned long) td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ if (tif->tif_flags&TIFF_NOREADRAW)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Compression scheme does not support access to raw uncompressed data");
+ return ((tmsize_t)(-1));
+ }
+ bytecount64 = td->td_stripbytecount[tile];
+ if (size != (tmsize_t)(-1) && (uint64)size < bytecount64)
+ bytecount64 = (uint64)size;
+ bytecountm = (tmsize_t)bytecount64;
+ if ((uint64)bytecountm!=bytecount64)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ return ((tmsize_t)(-1));
+ }
+ return (TIFFReadRawTile1(tif, tile, buf, bytecountm, module));
+}
+
+/*
+ * Read the specified tile and setup for decoding. The data buffer is
+ * expanded, as necessary, to hold the tile's data.
+ */
+int
+TIFFFillTile(TIFF* tif, uint32 tile)
+{
+ static const char module[] = "TIFFFillTile";
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+ return 0;
+
+ if ((tif->tif_flags&TIFF_NOREADRAW)==0)
+ {
+ uint64 bytecount = td->td_stripbytecount[tile];
+ if (bytecount <= 0) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%I64u: Invalid tile byte count, tile %lu",
+ (unsigned __int64) bytecount,
+ (unsigned long) tile);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%llu: Invalid tile byte count, tile %lu",
+ (unsigned long long) bytecount,
+ (unsigned long) tile);
+#endif
+ return (0);
+ }
+ if (isMapped(tif) &&
+ (isFillOrder(tif, td->td_fillorder)
+ || (tif->tif_flags & TIFF_NOBITREV))) {
+ /*
+ * The image is mapped into memory and we either don't
+ * need to flip bits or the compression routine is
+ * going to handle this operation itself. In this
+ * case, avoid copying the raw data and instead just
+ * reference the data from the memory mapped file
+ * image. This assumes that the decompression
+ * routines do not modify the contents of the raw data
+ * buffer (if they try to, the application will get a
+ * fault since the file is mapped read-only).
+ */
+ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) {
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ }
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ /*
+ * We must check for overflow, potentially causing
+ * an OOB read. Instead of simple
+ *
+ * td->td_stripoffset[tile]+bytecount > tif->tif_size
+ *
+ * comparison (which can overflow) we do the following
+ * two comparisons:
+ */
+ if (bytecount > (uint64)tif->tif_size ||
+ td->td_stripoffset[tile] > (uint64)tif->tif_size - bytecount) {
+ tif->tif_curtile = NOTILE;
+ return (0);
+ }
+ tif->tif_rawdatasize = (tmsize_t)bytecount;
+ tif->tif_rawdata =
+ tif->tif_base + (tmsize_t)td->td_stripoffset[tile];
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = (tmsize_t) bytecount;
+ tif->tif_flags |= TIFF_BUFFERMMAP;
+ } else {
+ /*
+ * Expand raw data buffer, if needed, to hold data
+ * tile coming from file (perhaps should set upper
+ * bound on the size of a buffer we'll use?).
+ */
+ tmsize_t bytecountm;
+ bytecountm=(tmsize_t)bytecount;
+ if ((uint64)bytecountm!=bytecount)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ return(0);
+ }
+ if (bytecountm > tif->tif_rawdatasize) {
+ tif->tif_curtile = NOTILE;
+ if ((tif->tif_flags & TIFF_MYBUFFER) == 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Data buffer too small to hold tile %lu",
+ (unsigned long) tile);
+ return (0);
+ }
+ if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+ return (0);
+ }
+ if (tif->tif_flags&TIFF_BUFFERMMAP) {
+ tif->tif_curtile = NOTILE;
+ if (!TIFFReadBufferSetup(tif, 0, bytecountm))
+ return (0);
+ }
+
+ if (TIFFReadRawTile1(tif, tile, tif->tif_rawdata,
+ bytecountm, module) != bytecountm)
+ return (0);
+
+ tif->tif_rawdataoff = 0;
+ tif->tif_rawdataloaded = bytecountm;
+
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(tif->tif_rawdata,
+ tif->tif_rawdataloaded);
+ }
+ }
+ return (TIFFStartTile(tif, tile));
+}
+
+/*
+ * Setup the raw data buffer in preparation for
+ * reading a strip of raw data. If the buffer
+ * is specified as zero, then a buffer of appropriate
+ * size is allocated by the library. Otherwise,
+ * the client must guarantee that the buffer is
+ * large enough to hold any individual strip of
+ * raw data.
+ */
+int
+TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size)
+{
+ static const char module[] = "TIFFReadBufferSetup";
+
+ assert((tif->tif_flags&TIFF_NOREADRAW)==0);
+ tif->tif_flags &= ~TIFF_BUFFERMMAP;
+
+ if (tif->tif_rawdata) {
+ if (tif->tif_flags & TIFF_MYBUFFER)
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_rawdata = NULL;
+ tif->tif_rawdatasize = 0;
+ }
+ if (bp) {
+ tif->tif_rawdatasize = size;
+ tif->tif_rawdata = (uint8*) bp;
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ } else {
+ tif->tif_rawdatasize = (tmsize_t)TIFFroundup_64((uint64)size, 1024);
+ if (tif->tif_rawdatasize==0)
+ tif->tif_rawdatasize=(tmsize_t)(-1);
+ tif->tif_rawdata = (uint8*) _TIFFmalloc(tif->tif_rawdatasize);
+ tif->tif_flags |= TIFF_MYBUFFER;
+ }
+ if (tif->tif_rawdata == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for data buffer at scanline %lu",
+ (unsigned long) tif->tif_row);
+ tif->tif_rawdatasize = 0;
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Set state to appear as if a
+ * strip has just been read in.
+ */
+static int
+TIFFStartStrip(TIFF* tif, uint32 strip)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+ return 0;
+
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+ if (!(*tif->tif_setupdecode)(tif))
+ return (0);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+ tif->tif_curstrip = strip;
+ tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ tif->tif_flags &= ~TIFF_BUF4WRITE;
+
+ if (tif->tif_flags&TIFF_NOREADRAW)
+ {
+ tif->tif_rawcp = NULL;
+ tif->tif_rawcc = 0;
+ }
+ else
+ {
+ tif->tif_rawcp = tif->tif_rawdata;
+ tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[strip];
+ }
+ return ((*tif->tif_predecode)(tif,
+ (uint16)(strip / td->td_stripsperimage)));
+}
+
+/*
+ * Set state to appear as if a
+ * tile has just been read in.
+ */
+static int
+TIFFStartTile(TIFF* tif, uint32 tile)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!_TIFFFillStriles( tif ) || !tif->tif_dir.td_stripbytecount)
+ return 0;
+
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+ if (!(*tif->tif_setupdecode)(tif))
+ return (0);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+ tif->tif_curtile = tile;
+ tif->tif_row =
+ (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth)) *
+ td->td_tilelength;
+ tif->tif_col =
+ (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength)) *
+ td->td_tilewidth;
+ tif->tif_flags &= ~TIFF_BUF4WRITE;
+ if (tif->tif_flags&TIFF_NOREADRAW)
+ {
+ tif->tif_rawcp = NULL;
+ tif->tif_rawcc = 0;
+ }
+ else
+ {
+ tif->tif_rawcp = tif->tif_rawdata;
+ tif->tif_rawcc = (tmsize_t)td->td_stripbytecount[tile];
+ }
+ return ((*tif->tif_predecode)(tif,
+ (uint16)(tile/td->td_stripsperimage)));
+}
+
+static int
+TIFFCheckRead(TIFF* tif, int tiles)
+{
+ if (tif->tif_mode == O_WRONLY) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading");
+ return (0);
+ }
+ if (tiles ^ isTiled(tif)) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ?
+ "Can not read tiles from a stripped image" :
+ "Can not read scanlines from a tiled image");
+ return (0);
+ }
+ return (1);
+}
+
+void
+_TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ (void) tif; (void) buf; (void) cc;
+}
+
+void
+_TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ (void) tif;
+ assert((cc & 1) == 0);
+ TIFFSwabArrayOfShort((uint16*) buf, cc/2);
+}
+
+void
+_TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ (void) tif;
+ assert((cc % 3) == 0);
+ TIFFSwabArrayOfTriples((uint8*) buf, cc/3);
+}
+
+void
+_TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ (void) tif;
+ assert((cc & 3) == 0);
+ TIFFSwabArrayOfLong((uint32*) buf, cc/4);
+}
+
+void
+_TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc)
+{
+ (void) tif;
+ assert((cc & 7) == 0);
+ TIFFSwabArrayOfDouble((double*) buf, cc/8);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_strip.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_strip.c
new file mode 100644
index 0000000000..047c59814c
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_strip.c
@@ -0,0 +1,386 @@
+/* $Id: tif_strip.c,v 1.35 2012-06-06 05:33:55 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Strip-organized Image Support Routines.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+/*
+ * Compute which strip a (row,sample) value is in.
+ */
+uint32
+TIFFComputeStrip(TIFF* tif, uint32 row, uint16 sample)
+{
+ static const char module[] = "TIFFComputeStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 strip;
+
+ strip = row / td->td_rowsperstrip;
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+ if (sample >= td->td_samplesperpixel) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%lu: Sample out of range, max %lu",
+ (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
+ return (0);
+ }
+ strip += (uint32)sample*td->td_stripsperimage;
+ }
+ return (strip);
+}
+
+/*
+ * Compute how many strips are in an image.
+ */
+uint32
+TIFFNumberOfStrips(TIFF* tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 nstrips;
+
+ nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
+ TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip));
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ nstrips = _TIFFMultiply32(tif, nstrips, (uint32)td->td_samplesperpixel,
+ "TIFFNumberOfStrips");
+ return (nstrips);
+}
+
+/*
+ * Compute the # bytes in a variable height, row-aligned strip.
+ */
+uint64
+TIFFVStripSize64(TIFF* tif, uint32 nrows)
+{
+ static const char module[] = "TIFFVStripSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ if (nrows==(uint32)(-1))
+ nrows=td->td_imagelength;
+ if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
+ (td->td_photometric == PHOTOMETRIC_YCBCR)&&
+ (!isUpSampled(tif)))
+ {
+ /*
+ * Packed YCbCr data contain one Cb+Cr for every
+ * HorizontalSampling*VerticalSampling Y values.
+ * Must also roundup width and height when calculating
+ * since images that are not a multiple of the
+ * horizontal/vertical subsampling area include
+ * YCbCr data for the extended image.
+ */
+ uint16 ycbcrsubsampling[2];
+ uint16 samplingblock_samples;
+ uint32 samplingblocks_hor;
+ uint32 samplingblocks_ver;
+ uint64 samplingrow_samples;
+ uint64 samplingrow_size;
+ if(td->td_samplesperpixel!=3)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Invalid td_samplesperpixel value");
+ return 0;
+ }
+ TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
+ ycbcrsubsampling+1);
+ if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
+ ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Invalid YCbCr subsampling (%dx%d)",
+ ycbcrsubsampling[0],
+ ycbcrsubsampling[1] );
+ return 0;
+ }
+ samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
+ samplingblocks_hor=TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
+ samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
+ samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
+ samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
+ return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
+ }
+ else
+ return(_TIFFMultiply64(tif,nrows,TIFFScanlineSize64(tif),module));
+}
+tmsize_t
+TIFFVStripSize(TIFF* tif, uint32 nrows)
+{
+ static const char module[] = "TIFFVStripSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFVStripSize64(tif,nrows);
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ n=0;
+ }
+ return(n);
+}
+
+/*
+ * Compute the # bytes in a raw strip.
+ */
+uint64
+TIFFRawStripSize64(TIFF* tif, uint32 strip)
+{
+ static const char module[] = "TIFFRawStripSize64";
+ TIFFDirectory* td = &tif->tif_dir;
+ uint64 bytecount = td->td_stripbytecount[strip];
+
+ if (bytecount == 0)
+ {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%I64u: Invalid strip byte count, strip %lu",
+ (unsigned __int64) bytecount,
+ (unsigned long) strip);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%llu: Invalid strip byte count, strip %lu",
+ (unsigned long long) bytecount,
+ (unsigned long) strip);
+#endif
+ bytecount = (uint64) -1;
+ }
+
+ return bytecount;
+}
+tmsize_t
+TIFFRawStripSize(TIFF* tif, uint32 strip)
+{
+ static const char module[] = "TIFFRawStripSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFRawStripSize64(tif,strip);
+ if (m==(uint64)(-1))
+ n=(tmsize_t)(-1);
+ else
+ {
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ n=0;
+ }
+ }
+ return(n);
+}
+
+/*
+ * Compute the # bytes in a (row-aligned) strip.
+ *
+ * Note that if RowsPerStrip is larger than the
+ * recorded ImageLength, then the strip size is
+ * truncated to reflect the actual space required
+ * to hold the strip.
+ */
+uint64
+TIFFStripSize64(TIFF* tif)
+{
+ TIFFDirectory* td = &tif->tif_dir;
+ uint32 rps = td->td_rowsperstrip;
+ if (rps > td->td_imagelength)
+ rps = td->td_imagelength;
+ return (TIFFVStripSize64(tif, rps));
+}
+tmsize_t
+TIFFStripSize(TIFF* tif)
+{
+ static const char module[] = "TIFFStripSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFStripSize64(tif);
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ n=0;
+ }
+ return(n);
+}
+
+/*
+ * Compute a default strip size based on the image
+ * characteristics and a requested value. If the
+ * request is <1 then we choose a strip size according
+ * to certain heuristics.
+ */
+uint32
+TIFFDefaultStripSize(TIFF* tif, uint32 request)
+{
+ return (*tif->tif_defstripsize)(tif, request);
+}
+
+uint32
+_TIFFDefaultStripSize(TIFF* tif, uint32 s)
+{
+ if ((int32) s < 1) {
+ /*
+ * If RowsPerStrip is unspecified, try to break the
+ * image up into strips that are approximately
+ * STRIP_SIZE_DEFAULT bytes long.
+ */
+ uint64 scanlinesize;
+ uint64 rows;
+ scanlinesize=TIFFScanlineSize64(tif);
+ if (scanlinesize==0)
+ scanlinesize=1;
+ rows=(uint64)STRIP_SIZE_DEFAULT/scanlinesize;
+ if (rows==0)
+ rows=1;
+ else if (rows>0xFFFFFFFF)
+ rows=0xFFFFFFFF;
+ s=(uint32)rows;
+ }
+ return (s);
+}
+
+/*
+ * Return the number of bytes to read/write in a call to
+ * one of the scanline-oriented i/o routines. Note that
+ * this number may be 1/samples-per-pixel if data is
+ * stored as separate planes.
+ * The ScanlineSize in case of YCbCrSubsampling is defined as the
+ * strip size divided by the strip height, i.e. the size of a pack of vertical
+ * subsampling lines divided by vertical subsampling. It should thus make
+ * sense when multiplied by a multiple of vertical subsampling.
+ */
+uint64
+TIFFScanlineSize64(TIFF* tif)
+{
+ static const char module[] = "TIFFScanlineSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 scanline_size;
+ if (td->td_planarconfig==PLANARCONFIG_CONTIG)
+ {
+ if ((td->td_photometric==PHOTOMETRIC_YCBCR)&&
+ (td->td_samplesperpixel==3)&&
+ (!isUpSampled(tif)))
+ {
+ uint16 ycbcrsubsampling[2];
+ uint16 samplingblock_samples;
+ uint32 samplingblocks_hor;
+ uint64 samplingrow_samples;
+ uint64 samplingrow_size;
+ if(td->td_samplesperpixel!=3)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Invalid td_samplesperpixel value");
+ return 0;
+ }
+ TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,
+ ycbcrsubsampling+0,
+ ycbcrsubsampling+1);
+ if (((ycbcrsubsampling[0]!=1)&&(ycbcrsubsampling[0]!=2)&&(ycbcrsubsampling[0]!=4)) ||
+ ((ycbcrsubsampling[1]!=1)&&(ycbcrsubsampling[1]!=2)&&(ycbcrsubsampling[1]!=4)))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Invalid YCbCr subsampling");
+ return 0;
+ }
+ samplingblock_samples = ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
+ samplingblocks_hor = TIFFhowmany_32(td->td_imagewidth,ycbcrsubsampling[0]);
+ samplingrow_samples = _TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
+ samplingrow_size = TIFFhowmany_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module),8);
+ scanline_size = (samplingrow_size/ycbcrsubsampling[1]);
+ }
+ else
+ {
+ uint64 scanline_samples;
+ scanline_samples=_TIFFMultiply64(tif,td->td_imagewidth,td->td_samplesperpixel,module);
+ scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,scanline_samples,td->td_bitspersample,module),8);
+ }
+ }
+ else
+ scanline_size=TIFFhowmany_64(_TIFFMultiply64(tif,td->td_imagewidth,td->td_bitspersample,module),8);
+ return(scanline_size);
+}
+tmsize_t
+TIFFScanlineSize(TIFF* tif)
+{
+ static const char module[] = "TIFFScanlineSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFScanlineSize64(tif);
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
+ n=0;
+ }
+ return(n);
+}
+
+/*
+ * Return the number of bytes required to store a complete
+ * decoded and packed raster scanline (as opposed to the
+ * I/O size returned by TIFFScanlineSize which may be less
+ * if data is store as separate planes).
+ */
+uint64
+TIFFRasterScanlineSize64(TIFF* tif)
+{
+ static const char module[] = "TIFFRasterScanlineSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 scanline;
+
+ scanline = _TIFFMultiply64(tif, td->td_bitspersample, td->td_imagewidth, module);
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
+ scanline = _TIFFMultiply64(tif, scanline, td->td_samplesperpixel, module);
+ return (TIFFhowmany8_64(scanline));
+ } else
+ return (_TIFFMultiply64(tif, TIFFhowmany8_64(scanline),
+ td->td_samplesperpixel, module));
+}
+tmsize_t
+TIFFRasterScanlineSize(TIFF* tif)
+{
+ static const char module[] = "TIFFRasterScanlineSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFRasterScanlineSize64(tif);
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer arithmetic overflow");
+ n=0;
+ }
+ return(n);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_swab.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_swab.c
new file mode 100644
index 0000000000..a60814bee2
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_swab.c
@@ -0,0 +1,313 @@
+/* $Id: tif_swab.c,v 1.13 2010-03-10 18:56:49 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library Bit & Byte Swapping Support.
+ *
+ * XXX We assume short = 16-bits and long = 32-bits XXX
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+#ifndef TIFFSwabShort
+void
+TIFFSwabShort(uint16* wp)
+{
+ register unsigned char* cp = (unsigned char*) wp;
+ unsigned char t;
+ assert(sizeof(uint16)==2);
+ t = cp[1]; cp[1] = cp[0]; cp[0] = t;
+}
+#endif
+
+#ifndef TIFFSwabLong
+void
+TIFFSwabLong(uint32* lp)
+{
+ register unsigned char* cp = (unsigned char*) lp;
+ unsigned char t;
+ assert(sizeof(uint32)==4);
+ t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+ t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+}
+#endif
+
+#ifndef TIFFSwabLong8
+void
+TIFFSwabLong8(uint64* lp)
+{
+ register unsigned char* cp = (unsigned char*) lp;
+ unsigned char t;
+ assert(sizeof(uint64)==8);
+ t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+ t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+ t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+ t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+}
+#endif
+
+#ifndef TIFFSwabArrayOfShort
+void
+TIFFSwabArrayOfShort(register uint16* wp, tmsize_t n)
+{
+ register unsigned char* cp;
+ register unsigned char t;
+ assert(sizeof(uint16)==2);
+ /* XXX unroll loop some */
+ while (n-- > 0) {
+ cp = (unsigned char*) wp;
+ t = cp[1]; cp[1] = cp[0]; cp[0] = t;
+ wp++;
+ }
+}
+#endif
+
+#ifndef TIFFSwabArrayOfTriples
+void
+TIFFSwabArrayOfTriples(register uint8* tp, tmsize_t n)
+{
+ unsigned char* cp;
+ unsigned char t;
+
+ /* XXX unroll loop some */
+ while (n-- > 0) {
+ cp = (unsigned char*) tp;
+ t = cp[2]; cp[2] = cp[0]; cp[0] = t;
+ tp += 3;
+ }
+}
+#endif
+
+#ifndef TIFFSwabArrayOfLong
+void
+TIFFSwabArrayOfLong(register uint32* lp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(uint32)==4);
+ /* XXX unroll loop some */
+ while (n-- > 0) {
+ cp = (unsigned char *)lp;
+ t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+ t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+ lp++;
+ }
+}
+#endif
+
+#ifndef TIFFSwabArrayOfLong8
+void
+TIFFSwabArrayOfLong8(register uint64* lp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(uint64)==8);
+ /* XXX unroll loop some */
+ while (n-- > 0) {
+ cp = (unsigned char *)lp;
+ t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+ t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+ t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+ t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+ lp++;
+ }
+}
+#endif
+
+#ifndef TIFFSwabFloat
+void
+TIFFSwabFloat(float* fp)
+{
+ register unsigned char* cp = (unsigned char*) fp;
+ unsigned char t;
+ assert(sizeof(float)==4);
+ t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+ t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+}
+#endif
+
+#ifndef TIFFSwabArrayOfFloat
+void
+TIFFSwabArrayOfFloat(register float* fp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(float)==4);
+ /* XXX unroll loop some */
+ while (n-- > 0) {
+ cp = (unsigned char *)fp;
+ t = cp[3]; cp[3] = cp[0]; cp[0] = t;
+ t = cp[2]; cp[2] = cp[1]; cp[1] = t;
+ fp++;
+ }
+}
+#endif
+
+#ifndef TIFFSwabDouble
+void
+TIFFSwabDouble(double *dp)
+{
+ register unsigned char* cp = (unsigned char*) dp;
+ unsigned char t;
+ assert(sizeof(double)==8);
+ t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+ t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+ t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+ t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+}
+#endif
+
+#ifndef TIFFSwabArrayOfDouble
+void
+TIFFSwabArrayOfDouble(double* dp, tmsize_t n)
+{
+ register unsigned char *cp;
+ register unsigned char t;
+ assert(sizeof(double)==8);
+ /* XXX unroll loop some */
+ while (n-- > 0) {
+ cp = (unsigned char *)dp;
+ t = cp[7]; cp[7] = cp[0]; cp[0] = t;
+ t = cp[6]; cp[6] = cp[1]; cp[1] = t;
+ t = cp[5]; cp[5] = cp[2]; cp[2] = t;
+ t = cp[4]; cp[4] = cp[3]; cp[3] = t;
+ dp++;
+ }
+}
+#endif
+
+/*
+ * Bit reversal tables. TIFFBitRevTable[<byte>] gives
+ * the bit reversed value of <byte>. Used in various
+ * places in the library when the FillOrder requires
+ * bit reversal of byte values (e.g. CCITT Fax 3
+ * encoding/decoding). TIFFNoBitRevTable is provided
+ * for algorithms that want an equivalent table that
+ * do not reverse bit values.
+ */
+static const unsigned char TIFFBitRevTable[256] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+static const unsigned char TIFFNoBitRevTable[256] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+
+const unsigned char*
+TIFFGetBitRevTable(int reversed)
+{
+ return (reversed ? TIFFBitRevTable : TIFFNoBitRevTable);
+}
+
+void
+TIFFReverseBits(uint8* cp, tmsize_t n)
+{
+ for (; n > 8; n -= 8) {
+ cp[0] = TIFFBitRevTable[cp[0]];
+ cp[1] = TIFFBitRevTable[cp[1]];
+ cp[2] = TIFFBitRevTable[cp[2]];
+ cp[3] = TIFFBitRevTable[cp[3]];
+ cp[4] = TIFFBitRevTable[cp[4]];
+ cp[5] = TIFFBitRevTable[cp[5]];
+ cp[6] = TIFFBitRevTable[cp[6]];
+ cp[7] = TIFFBitRevTable[cp[7]];
+ cp += 8;
+ }
+ while (n-- > 0)
+ *cp = TIFFBitRevTable[*cp], cp++;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_thunder.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_thunder.c
new file mode 100644
index 0000000000..e7cb0d4df5
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_thunder.c
@@ -0,0 +1,210 @@
+/* $Id: tif_thunder.c,v 1.12 2011-04-02 20:54:09 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <assert.h>
+#ifdef THUNDER_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ThunderScan 4-bit Compression Algorithm Support
+ */
+
+/*
+ * ThunderScan uses an encoding scheme designed for
+ * 4-bit pixel values. Data is encoded in bytes, with
+ * each byte split into a 2-bit code word and a 6-bit
+ * data value. The encoding gives raw data, runs of
+ * pixels, or pixel values encoded as a delta from the
+ * previous pixel value. For the latter, either 2-bit
+ * or 3-bit delta values are used, with the deltas packed
+ * into a single byte.
+ */
+#define THUNDER_DATA 0x3f /* mask for 6-bit data */
+#define THUNDER_CODE 0xc0 /* mask for 2-bit code word */
+/* code values */
+#define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */
+#define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */
+#define DELTA2_SKIP 2 /* skip code for 2-bit deltas */
+#define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */
+#define DELTA3_SKIP 4 /* skip code for 3-bit deltas */
+#define THUNDER_RAW 0xc0 /* raw data encoded */
+
+static const int twobitdeltas[4] = { 0, 1, 0, -1 };
+static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 };
+
+#define SETPIXEL(op, v) { \
+ lastpixel = (v) & 0xf; \
+ if ( npixels < maxpixels ) \
+ { \
+ if (npixels++ & 1) \
+ *op++ |= lastpixel; \
+ else \
+ op[0] = (uint8) (lastpixel << 4); \
+ } \
+}
+
+static int
+ThunderSetupDecode(TIFF* tif)
+{
+ static const char module[] = "ThunderSetupDecode";
+
+ if( tif->tif_dir.td_bitspersample != 4 )
+ {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Wrong bitspersample value (%d), Thunder decoder only supports 4bits per sample.",
+ (int) tif->tif_dir.td_bitspersample );
+ return 0;
+ }
+
+
+ return (1);
+}
+
+static int
+ThunderDecode(TIFF* tif, uint8* op, tmsize_t maxpixels)
+{
+ static const char module[] = "ThunderDecode";
+ register unsigned char *bp;
+ register tmsize_t cc;
+ unsigned int lastpixel;
+ tmsize_t npixels;
+
+ bp = (unsigned char *)tif->tif_rawcp;
+ cc = tif->tif_rawcc;
+ lastpixel = 0;
+ npixels = 0;
+ while (cc > 0 && npixels < maxpixels) {
+ int n, delta;
+
+ n = *bp++, cc--;
+ switch (n & THUNDER_CODE) {
+ case THUNDER_RUN: /* pixel run */
+ /*
+ * Replicate the last pixel n times,
+ * where n is the lower-order 6 bits.
+ */
+ if (npixels & 1) {
+ op[0] |= lastpixel;
+ lastpixel = *op++; npixels++; n--;
+ } else
+ lastpixel |= lastpixel << 4;
+ npixels += n;
+ if (npixels < maxpixels) {
+ for (; n > 0; n -= 2)
+ *op++ = (uint8) lastpixel;
+ }
+ if (n == -1)
+ *--op &= 0xf0;
+ lastpixel &= 0xf;
+ break;
+ case THUNDER_2BITDELTAS: /* 2-bit deltas */
+ if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
+ SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
+ SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ if ((delta = (n & 3)) != DELTA2_SKIP)
+ SETPIXEL(op, lastpixel + twobitdeltas[delta]);
+ break;
+ case THUNDER_3BITDELTAS: /* 3-bit deltas */
+ if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
+ SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+ if ((delta = (n & 7)) != DELTA3_SKIP)
+ SETPIXEL(op, lastpixel + threebitdeltas[delta]);
+ break;
+ case THUNDER_RAW: /* raw data */
+ SETPIXEL(op, n);
+ break;
+ }
+ }
+ tif->tif_rawcp = (uint8*) bp;
+ tif->tif_rawcc = cc;
+ if (npixels != maxpixels) {
+#if defined(__WIN32__) && (defined(_MSC_VER) || defined(__MINGW32__))
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s data at scanline %lu (%I64u != %I64u)",
+ npixels < maxpixels ? "Not enough" : "Too much",
+ (unsigned long) tif->tif_row,
+ (unsigned __int64) npixels,
+ (unsigned __int64) maxpixels);
+#else
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%s data at scanline %lu (%llu != %llu)",
+ npixels < maxpixels ? "Not enough" : "Too much",
+ (unsigned long) tif->tif_row,
+ (unsigned long long) npixels,
+ (unsigned long long) maxpixels);
+#endif
+ return (0);
+ }
+
+ return (1);
+}
+
+static int
+ThunderDecodeRow(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "ThunderDecodeRow";
+ uint8* row = buf;
+
+ (void) s;
+ if (occ % tif->tif_scanlinesize)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
+ return (0);
+ }
+ while (occ > 0) {
+ if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
+ return (0);
+ occ -= tif->tif_scanlinesize;
+ row += tif->tif_scanlinesize;
+ }
+ return (1);
+}
+
+int
+TIFFInitThunderScan(TIFF* tif, int scheme)
+{
+ (void) scheme;
+
+ tif->tif_setupdecode = ThunderSetupDecode;
+ tif->tif_decoderow = ThunderDecodeRow;
+ tif->tif_decodestrip = ThunderDecodeRow;
+ return (1);
+}
+#endif /* THUNDER_SUPPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_tile.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_tile.c
new file mode 100644
index 0000000000..24ba82c040
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_tile.c
@@ -0,0 +1,302 @@
+/* $Id: tif_tile.c,v 1.23 2012-06-06 05:33:55 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1991-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Tiled Image Support Routines.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+/*
+ * Compute which tile an (x,y,z,s) value is in.
+ */
+uint32
+TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 dx = td->td_tilewidth;
+ uint32 dy = td->td_tilelength;
+ uint32 dz = td->td_tiledepth;
+ uint32 tile = 1;
+
+ if (td->td_imagedepth == 1)
+ z = 0;
+ if (dx == (uint32) -1)
+ dx = td->td_imagewidth;
+ if (dy == (uint32) -1)
+ dy = td->td_imagelength;
+ if (dz == (uint32) -1)
+ dz = td->td_imagedepth;
+ if (dx != 0 && dy != 0 && dz != 0) {
+ uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx);
+ uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy);
+ uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz);
+
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ tile = (xpt*ypt*zpt)*s +
+ (xpt*ypt)*(z/dz) +
+ xpt*(y/dy) +
+ x/dx;
+ else
+ tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx;
+ }
+ return (tile);
+}
+
+/*
+ * Check an (x,y,z,s) coordinate
+ * against the image bounds.
+ */
+int
+TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (x >= td->td_imagewidth) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%lu: Col out of range, max %lu",
+ (unsigned long) x,
+ (unsigned long) (td->td_imagewidth - 1));
+ return (0);
+ }
+ if (y >= td->td_imagelength) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%lu: Row out of range, max %lu",
+ (unsigned long) y,
+ (unsigned long) (td->td_imagelength - 1));
+ return (0);
+ }
+ if (z >= td->td_imagedepth) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%lu: Depth out of range, max %lu",
+ (unsigned long) z,
+ (unsigned long) (td->td_imagedepth - 1));
+ return (0);
+ }
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
+ s >= td->td_samplesperpixel) {
+ TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
+ "%lu: Sample out of range, max %lu",
+ (unsigned long) s,
+ (unsigned long) (td->td_samplesperpixel - 1));
+ return (0);
+ }
+ return (1);
+}
+
+/*
+ * Compute how many tiles are in an image.
+ */
+uint32
+TIFFNumberOfTiles(TIFF* tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint32 dx = td->td_tilewidth;
+ uint32 dy = td->td_tilelength;
+ uint32 dz = td->td_tiledepth;
+ uint32 ntiles;
+
+ if (dx == (uint32) -1)
+ dx = td->td_imagewidth;
+ if (dy == (uint32) -1)
+ dy = td->td_imagelength;
+ if (dz == (uint32) -1)
+ dz = td->td_imagedepth;
+ ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 :
+ _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx),
+ TIFFhowmany_32(td->td_imagelength, dy),
+ "TIFFNumberOfTiles"),
+ TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles");
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel,
+ "TIFFNumberOfTiles");
+ return (ntiles);
+}
+
+/*
+ * Compute the # bytes in each row of a tile.
+ */
+uint64
+TIFFTileRowSize64(TIFF* tif)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 rowsize;
+
+ if (td->td_tilelength == 0 || td->td_tilewidth == 0)
+ return (0);
+ rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
+ "TIFFTileRowSize");
+ if (td->td_planarconfig == PLANARCONFIG_CONTIG)
+ rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
+ "TIFFTileRowSize");
+ return (TIFFhowmany8_64(rowsize));
+}
+tmsize_t
+TIFFTileRowSize(TIFF* tif)
+{
+ static const char module[] = "TIFFTileRowSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFTileRowSize64(tif);
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ n=0;
+ }
+ return(n);
+}
+
+/*
+ * Compute the # bytes in a variable length, row-aligned tile.
+ */
+uint64
+TIFFVTileSize64(TIFF* tif, uint32 nrows)
+{
+ static const char module[] = "TIFFVTileSize64";
+ TIFFDirectory *td = &tif->tif_dir;
+ if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
+ td->td_tiledepth == 0)
+ return (0);
+ if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
+ (td->td_photometric==PHOTOMETRIC_YCBCR)&&
+ (td->td_samplesperpixel==3)&&
+ (!isUpSampled(tif)))
+ {
+ /*
+ * Packed YCbCr data contain one Cb+Cr for every
+ * HorizontalSampling*VerticalSampling Y values.
+ * Must also roundup width and height when calculating
+ * since images that are not a multiple of the
+ * horizontal/vertical subsampling area include
+ * YCbCr data for the extended image.
+ */
+ uint16 ycbcrsubsampling[2];
+ uint16 samplingblock_samples;
+ uint32 samplingblocks_hor;
+ uint32 samplingblocks_ver;
+ uint64 samplingrow_samples;
+ uint64 samplingrow_size;
+ TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
+ ycbcrsubsampling+1);
+ if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
+ ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,
+ "Invalid YCbCr subsampling (%dx%d)",
+ ycbcrsubsampling[0],
+ ycbcrsubsampling[1] );
+ return 0;
+ }
+ samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
+ samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]);
+ samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
+ samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
+ samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
+ return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
+ }
+ else
+ return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module));
+}
+tmsize_t
+TIFFVTileSize(TIFF* tif, uint32 nrows)
+{
+ static const char module[] = "TIFFVTileSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFVTileSize64(tif,nrows);
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ n=0;
+ }
+ return(n);
+}
+
+/*
+ * Compute the # bytes in a row-aligned tile.
+ */
+uint64
+TIFFTileSize64(TIFF* tif)
+{
+ return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
+}
+tmsize_t
+TIFFTileSize(TIFF* tif)
+{
+ static const char module[] = "TIFFTileSize";
+ uint64 m;
+ tmsize_t n;
+ m=TIFFTileSize64(tif);
+ n=(tmsize_t)m;
+ if ((uint64)n!=m)
+ {
+ TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
+ n=0;
+ }
+ return(n);
+}
+
+/*
+ * Compute a default tile size based on the image
+ * characteristics and a requested value. If a
+ * request is <1 then we choose a size according
+ * to certain heuristics.
+ */
+void
+TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
+{
+ (*tif->tif_deftilesize)(tif, tw, th);
+}
+
+void
+_TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
+{
+ (void) tif;
+ if (*(int32*) tw < 1)
+ *tw = 256;
+ if (*(int32*) th < 1)
+ *th = 256;
+ /* roundup to a multiple of 16 per the spec */
+ if (*tw & 0xf)
+ *tw = TIFFroundup_32(*tw, 16);
+ if (*th & 0xf)
+ *th = TIFFroundup_32(*th, 16);
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_version.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_version.c
new file mode 100644
index 0000000000..41aa8b0dcd
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_version.c
@@ -0,0 +1,43 @@
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_version.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */
+/*
+ * Copyright (c) 1992-1997 Sam Leffler
+ * Copyright (c) 1992-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+static const char TIFFVersion[] = TIFFLIB_VERSION_STR;
+
+const char*
+TIFFGetVersion(void)
+{
+ return (TIFFVersion);
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_warning.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_warning.c
new file mode 100644
index 0000000000..ac6b3b938f
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_warning.c
@@ -0,0 +1,87 @@
+/* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/tif_warning.c,v 1.3 2010-03-10 18:56:49 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+
+/*TIFFErrorHandlerExt _TIFFwarningHandlerExt = NULL;*/
+/* Modify here for use _TIFFwarningHandlerExt by Sunliang.Liu 20090715 */
+TIFFErrorHandler _TIFFwarningHandler = NULL;
+
+TIFFErrorHandler
+TIFFSetWarningHandler(TIFFErrorHandler handler)
+{
+ TIFFErrorHandler prev = _TIFFwarningHandler;
+ _TIFFwarningHandler = handler;
+ return (prev);
+}
+
+TIFFErrorHandlerExt
+TIFFSetWarningHandlerExt(TIFFErrorHandlerExt handler)
+{
+ TIFFErrorHandlerExt prev = _TIFFwarningHandlerExt;
+ _TIFFwarningHandlerExt = handler;
+ return (prev);
+}
+
+void
+TIFFWarning(const char* module, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ if (_TIFFwarningHandler)
+ (*_TIFFwarningHandler)(module, fmt, ap);
+ if (_TIFFwarningHandlerExt)
+ (*_TIFFwarningHandlerExt)(0, module, fmt, ap);
+ va_end(ap);
+}
+
+void
+TIFFWarningExt(thandle_t fd, const char* module, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ if (_TIFFwarningHandler)
+ (*_TIFFwarningHandler)(module, fmt, ap);
+ if (_TIFFwarningHandlerExt)
+ (*_TIFFwarningHandlerExt)(fd, module, fmt, ap);
+ va_end(ap);
+}
+
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_write.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_write.c
new file mode 100644
index 0000000000..11a537c9d0
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_write.c
@@ -0,0 +1,774 @@
+/* $Id: tif_write.c,v 1.37 2012-08-13 22:10:17 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+/*
+ * TIFF Library.
+ *
+ * Scanline-oriented Write Support
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#include <stdio.h>
+
+#define STRIPINCR 20 /* expansion factor on strip array */
+
+#define WRITECHECKSTRIPS(tif, module) \
+ (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),0,module))
+#define WRITECHECKTILES(tif, module) \
+ (((tif)->tif_flags&TIFF_BEENWRITING) || TIFFWriteCheck((tif),1,module))
+#define BUFFERCHECK(tif) \
+ ((((tif)->tif_flags & TIFF_BUFFERSETUP) && tif->tif_rawdata) || \
+ TIFFWriteBufferSetup((tif), NULL, (tmsize_t) -1))
+
+static int TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module);
+static int TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc);
+
+int
+TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample)
+{
+ static const char module[] = "TIFFWriteScanline";
+ register TIFFDirectory *td;
+ int status, imagegrew = 0;
+ uint32 strip;
+
+ if (!WRITECHECKSTRIPS(tif, module))
+ return (-1);
+ /*
+ * Handle delayed allocation of data buffer. This
+ * permits it to be sized more intelligently (using
+ * directory information).
+ */
+ if (!BUFFERCHECK(tif))
+ return (-1);
+ tif->tif_flags |= TIFF_BUF4WRITE; /* not strictly sure this is right*/
+
+ td = &tif->tif_dir;
+ /*
+ * Extend image length if needed
+ * (but only for PlanarConfig=1).
+ */
+ if (row >= td->td_imagelength) { /* extend image */
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Can not change \"ImageLength\" when using separate planes");
+ return (-1);
+ }
+ td->td_imagelength = row+1;
+ imagegrew = 1;
+ }
+ /*
+ * Calculate strip and check for crossings.
+ */
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+ if (sample >= td->td_samplesperpixel) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "%lu: Sample out of range, max %lu",
+ (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
+ return (-1);
+ }
+ strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip;
+ } else
+ strip = row / td->td_rowsperstrip;
+ /*
+ * Check strip array to make sure there's space. We don't support
+ * dynamically growing files that have data organized in separate
+ * bitplanes because it's too painful. In that case we require that
+ * the imagelength be set properly before the first write (so that the
+ * strips array will be fully allocated above).
+ */
+ if (strip >= td->td_nstrips && !TIFFGrowStrips(tif, 1, module))
+ return (-1);
+ if (strip != tif->tif_curstrip) {
+ /*
+ * Changing strips -- flush any data present.
+ */
+ if (!TIFFFlushData(tif))
+ return (-1);
+ tif->tif_curstrip = strip;
+ /*
+ * Watch out for a growing image. The value of strips/image
+ * will initially be 1 (since it can't be deduced until the
+ * imagelength is known).
+ */
+ if (strip >= td->td_stripsperimage && imagegrew)
+ td->td_stripsperimage =
+ TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
+ tif->tif_row =
+ (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+ if (!(*tif->tif_setupencode)(tif))
+ return (-1);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ if( td->td_stripbytecount[strip] > 0 )
+ {
+ /* if we are writing over existing tiles, zero length */
+ td->td_stripbytecount[strip] = 0;
+
+ /* this forces TIFFAppendToStrip() to do a seek */
+ tif->tif_curoff = 0;
+ }
+
+ if (!(*tif->tif_preencode)(tif, sample))
+ return (-1);
+ tif->tif_flags |= TIFF_POSTENCODE;
+ }
+ /*
+ * Ensure the write is either sequential or at the
+ * beginning of a strip (or that we can randomly
+ * access the data -- i.e. no encoding).
+ */
+ if (row != tif->tif_row) {
+ if (row < tif->tif_row) {
+ /*
+ * Moving backwards within the same strip:
+ * backup to the start and then decode
+ * forward (below).
+ */
+ tif->tif_row = (strip % td->td_stripsperimage) *
+ td->td_rowsperstrip;
+ tif->tif_rawcp = tif->tif_rawdata;
+ }
+ /*
+ * Seek forward to the desired row.
+ */
+ if (!(*tif->tif_seek)(tif, row - tif->tif_row))
+ return (-1);
+ tif->tif_row = row;
+ }
+
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode( tif, (uint8*) buf, tif->tif_scanlinesize );
+
+ status = (*tif->tif_encoderow)(tif, (uint8*) buf,
+ tif->tif_scanlinesize, sample);
+
+ /* we are now poised at the beginning of the next row */
+ tif->tif_row = row + 1;
+ return (status);
+}
+
+/*
+ * Encode the supplied data and write it to the
+ * specified strip.
+ *
+ * NB: Image length must be setup before writing.
+ */
+tmsize_t
+TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteEncodedStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint16 sample;
+
+ if (!WRITECHECKSTRIPS(tif, module))
+ return ((tmsize_t) -1);
+ /*
+ * Check strip array to make sure there's space.
+ * We don't support dynamically growing files that
+ * have data organized in separate bitplanes because
+ * it's too painful. In that case we require that
+ * the imagelength be set properly before the first
+ * write (so that the strips array will be fully
+ * allocated above).
+ */
+ if (strip >= td->td_nstrips) {
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Can not grow image by strips when using separate planes");
+ return ((tmsize_t) -1);
+ }
+ if (!TIFFGrowStrips(tif, 1, module))
+ return ((tmsize_t) -1);
+ td->td_stripsperimage =
+ TIFFhowmany_32(td->td_imagelength, td->td_rowsperstrip);
+ }
+ /*
+ * Handle delayed allocation of data buffer. This
+ * permits it to be sized according to the directory
+ * info.
+ */
+ if (!BUFFERCHECK(tif))
+ return ((tmsize_t) -1);
+
+ tif->tif_flags |= TIFF_BUF4WRITE;
+ tif->tif_curstrip = strip;
+
+ tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+ if (!(*tif->tif_setupencode)(tif))
+ return ((tmsize_t) -1);
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+
+ if( td->td_stripbytecount[strip] > 0 )
+ {
+ /* Make sure that at the first attempt of rewriting the tile, we will have */
+ /* more bytes available in the output buffer than the previous byte count, */
+ /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
+ /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
+ if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[strip] )
+ {
+ if( !(TIFFWriteBufferSetup(tif, NULL,
+ (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[strip] + 1), 1024))) )
+ return ((tmsize_t)(-1));
+ }
+
+ /* Force TIFFAppendToStrip() to consider placing data at end
+ of file. */
+ tif->tif_curoff = 0;
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+ sample = (uint16)(strip / td->td_stripsperimage);
+ if (!(*tif->tif_preencode)(tif, sample))
+ return ((tmsize_t) -1);
+
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode( tif, (uint8*) data, cc );
+
+ if (!(*tif->tif_encodestrip)(tif, (uint8*) data, cc, sample))
+ return (0);
+ if (!(*tif->tif_postencode)(tif))
+ return ((tmsize_t) -1);
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits(tif->tif_rawdata, tif->tif_rawcc);
+ if (tif->tif_rawcc > 0 &&
+ !TIFFAppendToStrip(tif, strip, tif->tif_rawdata, tif->tif_rawcc))
+ return ((tmsize_t) -1);
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ return (cc);
+}
+
+/*
+ * Write the supplied data to the specified strip.
+ *
+ * NB: Image length must be setup before writing.
+ */
+tmsize_t
+TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteRawStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+
+ if (!WRITECHECKSTRIPS(tif, module))
+ return ((tmsize_t) -1);
+ /*
+ * Check strip array to make sure there's space.
+ * We don't support dynamically growing files that
+ * have data organized in separate bitplanes because
+ * it's too painful. In that case we require that
+ * the imagelength be set properly before the first
+ * write (so that the strips array will be fully
+ * allocated above).
+ */
+ if (strip >= td->td_nstrips) {
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Can not grow image by strips when using separate planes");
+ return ((tmsize_t) -1);
+ }
+ /*
+ * Watch out for a growing image. The value of
+ * strips/image will initially be 1 (since it
+ * can't be deduced until the imagelength is known).
+ */
+ if (strip >= td->td_stripsperimage)
+ td->td_stripsperimage =
+ TIFFhowmany_32(td->td_imagelength,td->td_rowsperstrip);
+ if (!TIFFGrowStrips(tif, 1, module))
+ return ((tmsize_t) -1);
+ }
+ tif->tif_curstrip = strip;
+ tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip;
+ return (TIFFAppendToStrip(tif, strip, (uint8*) data, cc) ?
+ cc : (tmsize_t) -1);
+}
+
+/*
+ * Write and compress a tile of data. The
+ * tile is selected by the (x,y,z,s) coordinates.
+ */
+tmsize_t
+TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s)
+{
+ if (!TIFFCheckTile(tif, x, y, z, s))
+ return ((tmsize_t)(-1));
+ /*
+ * NB: A tile size of -1 is used instead of tif_tilesize knowing
+ * that TIFFWriteEncodedTile will clamp this to the tile size.
+ * This is done because the tile size may not be defined until
+ * after the output buffer is setup in TIFFWriteBufferSetup.
+ */
+ return (TIFFWriteEncodedTile(tif,
+ TIFFComputeTile(tif, x, y, z, s), buf, (tmsize_t)(-1)));
+}
+
+/*
+ * Encode the supplied data and write it to the
+ * specified tile. There must be space for the
+ * data. The function clamps individual writes
+ * to a tile to the tile size, but does not (and
+ * can not) check that multiple writes to the same
+ * tile do not write more than tile size data.
+ *
+ * NB: Image length must be setup before writing; this
+ * interface does not support automatically growing
+ * the image on each write (as TIFFWriteScanline does).
+ */
+tmsize_t
+TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteEncodedTile";
+ TIFFDirectory *td;
+ uint16 sample;
+
+ if (!WRITECHECKTILES(tif, module))
+ return ((tmsize_t)(-1));
+ td = &tif->tif_dir;
+ if (tile >= td->td_nstrips) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
+ (unsigned long) tile, (unsigned long) td->td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ /*
+ * Handle delayed allocation of data buffer. This
+ * permits it to be sized more intelligently (using
+ * directory information).
+ */
+ if (!BUFFERCHECK(tif))
+ return ((tmsize_t)(-1));
+
+ tif->tif_flags |= TIFF_BUF4WRITE;
+ tif->tif_curtile = tile;
+
+ if( td->td_stripbytecount[tile] > 0 )
+ {
+ /* Make sure that at the first attempt of rewriting the tile, we will have */
+ /* more bytes available in the output buffer than the previous byte count, */
+ /* so that TIFFAppendToStrip() will detect the overflow when it is called the first */
+ /* time if the new compressed tile is bigger than the older one. (GDAL #4771) */
+ if( tif->tif_rawdatasize <= (tmsize_t)td->td_stripbytecount[tile] )
+ {
+ if( !(TIFFWriteBufferSetup(tif, NULL,
+ (tmsize_t)TIFFroundup_64((uint64)(td->td_stripbytecount[tile] + 1), 1024))) )
+ return ((tmsize_t)(-1));
+ }
+
+ /* Force TIFFAppendToStrip() to consider placing data at end
+ of file. */
+ tif->tif_curoff = 0;
+ }
+
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+
+ /*
+ * Compute tiles per row & per column to compute
+ * current row and column
+ */
+ tif->tif_row = (tile % TIFFhowmany_32(td->td_imagelength, td->td_tilelength))
+ * td->td_tilelength;
+ tif->tif_col = (tile % TIFFhowmany_32(td->td_imagewidth, td->td_tilewidth))
+ * td->td_tilewidth;
+
+ if ((tif->tif_flags & TIFF_CODERSETUP) == 0) {
+ if (!(*tif->tif_setupencode)(tif))
+ return ((tmsize_t)(-1));
+ tif->tif_flags |= TIFF_CODERSETUP;
+ }
+ tif->tif_flags &= ~TIFF_POSTENCODE;
+ sample = (uint16)(tile/td->td_stripsperimage);
+ if (!(*tif->tif_preencode)(tif, sample))
+ return ((tmsize_t)(-1));
+ /*
+ * Clamp write amount to the tile size. This is mostly
+ * done so that callers can pass in some large number
+ * (e.g. -1) and have the tile size used instead.
+ */
+ if ( cc < 1 || cc > tif->tif_tilesize)
+ cc = tif->tif_tilesize;
+
+ /* swab if needed - note that source buffer will be altered */
+ tif->tif_postdecode( tif, (uint8*) data, cc );
+
+ if (!(*tif->tif_encodetile)(tif, (uint8*) data, cc, sample))
+ return (0);
+ if (!(*tif->tif_postencode)(tif))
+ return ((tmsize_t)(-1));
+ if (!isFillOrder(tif, td->td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits((uint8*)tif->tif_rawdata, tif->tif_rawcc);
+ if (tif->tif_rawcc > 0 && !TIFFAppendToStrip(tif, tile,
+ tif->tif_rawdata, tif->tif_rawcc))
+ return ((tmsize_t)(-1));
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ return (cc);
+}
+
+/*
+ * Write the supplied data to the specified strip.
+ * There must be space for the data; we don't check
+ * if strips overlap!
+ *
+ * NB: Image length must be setup before writing; this
+ * interface does not support automatically growing
+ * the image on each write (as TIFFWriteScanline does).
+ */
+tmsize_t
+TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc)
+{
+ static const char module[] = "TIFFWriteRawTile";
+
+ if (!WRITECHECKTILES(tif, module))
+ return ((tmsize_t)(-1));
+ if (tile >= tif->tif_dir.td_nstrips) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Tile %lu out of range, max %lu",
+ (unsigned long) tile,
+ (unsigned long) tif->tif_dir.td_nstrips);
+ return ((tmsize_t)(-1));
+ }
+ return (TIFFAppendToStrip(tif, tile, (uint8*) data, cc) ?
+ cc : (tmsize_t)(-1));
+}
+
+#define isUnspecified(tif, f) \
+ (TIFFFieldSet(tif,f) && (tif)->tif_dir.td_imagelength == 0)
+
+int
+TIFFSetupStrips(TIFF* tif)
+{
+ TIFFDirectory* td = &tif->tif_dir;
+
+ if (isTiled(tif))
+ td->td_stripsperimage =
+ isUnspecified(tif, FIELD_TILEDIMENSIONS) ?
+ td->td_samplesperpixel : TIFFNumberOfTiles(tif);
+ else
+ td->td_stripsperimage =
+ isUnspecified(tif, FIELD_ROWSPERSTRIP) ?
+ td->td_samplesperpixel : TIFFNumberOfStrips(tif);
+ td->td_nstrips = td->td_stripsperimage;
+ if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
+ td->td_stripsperimage /= td->td_samplesperpixel;
+ td->td_stripoffset = (uint64 *)
+ _TIFFmalloc(td->td_nstrips * sizeof (uint64));
+ td->td_stripbytecount = (uint64 *)
+ _TIFFmalloc(td->td_nstrips * sizeof (uint64));
+ if (td->td_stripoffset == NULL || td->td_stripbytecount == NULL)
+ return (0);
+ /*
+ * Place data at the end-of-file
+ * (by setting offsets to zero).
+ */
+ _TIFFmemset(td->td_stripoffset, 0, td->td_nstrips*sizeof (uint64));
+ _TIFFmemset(td->td_stripbytecount, 0, td->td_nstrips*sizeof (uint64));
+ TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
+ TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
+ return (1);
+}
+#undef isUnspecified
+
+/*
+ * Verify file is writable and that the directory
+ * information is setup properly. In doing the latter
+ * we also "freeze" the state of the directory so
+ * that important information is not changed.
+ */
+int
+TIFFWriteCheck(TIFF* tif, int tiles, const char* module)
+{
+ if (tif->tif_mode == O_RDONLY) {
+ TIFFErrorExt(tif->tif_clientdata, module, "File not open for writing");
+ return (0);
+ }
+ if (tiles ^ isTiled(tif)) {
+ TIFFErrorExt(tif->tif_clientdata, module, tiles ?
+ "Can not write tiles to a stripped image" :
+ "Can not write scanlines to a tiled image");
+ return (0);
+ }
+
+ _TIFFFillStriles( tif );
+
+ /*
+ * On the first write verify all the required information
+ * has been setup and initialize any data structures that
+ * had to wait until directory information was set.
+ * Note that a lot of our work is assumed to remain valid
+ * because we disallow any of the important parameters
+ * from changing after we start writing (i.e. once
+ * TIFF_BEENWRITING is set, TIFFSetField will only allow
+ * the image's length to be changed).
+ */
+ if (!TIFFFieldSet(tif, FIELD_IMAGEDIMENSIONS)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Must set \"ImageWidth\" before writing data");
+ return (0);
+ }
+ if (tif->tif_dir.td_samplesperpixel == 1) {
+ /*
+ * Planarconfiguration is irrelevant in case of single band
+ * images and need not be included. We will set it anyway,
+ * because this field is used in other parts of library even
+ * in the single band case.
+ */
+ if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG))
+ tif->tif_dir.td_planarconfig = PLANARCONFIG_CONTIG;
+ } else {
+ if (!TIFFFieldSet(tif, FIELD_PLANARCONFIG)) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Must set \"PlanarConfiguration\" before writing data");
+ return (0);
+ }
+ }
+ if (tif->tif_dir.td_stripoffset == NULL && !TIFFSetupStrips(tif)) {
+ tif->tif_dir.td_nstrips = 0;
+ TIFFErrorExt(tif->tif_clientdata, module, "No space for %s arrays",
+ isTiled(tif) ? "tile" : "strip");
+ return (0);
+ }
+ if (isTiled(tif))
+ {
+ tif->tif_tilesize = TIFFTileSize(tif);
+ if (tif->tif_tilesize == 0)
+ return (0);
+ }
+ else
+ tif->tif_tilesize = (tmsize_t)(-1);
+ tif->tif_scanlinesize = TIFFScanlineSize(tif);
+ if (tif->tif_scanlinesize == 0)
+ return (0);
+ tif->tif_flags |= TIFF_BEENWRITING;
+ return (1);
+}
+
+/*
+ * Setup the raw data buffer used for encoding.
+ */
+int
+TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size)
+{
+ static const char module[] = "TIFFWriteBufferSetup";
+
+ if (tif->tif_rawdata) {
+ if (tif->tif_flags & TIFF_MYBUFFER) {
+ _TIFFfree(tif->tif_rawdata);
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ }
+ tif->tif_rawdata = NULL;
+ }
+ if (size == (tmsize_t)(-1)) {
+ size = (isTiled(tif) ?
+ tif->tif_tilesize : TIFFStripSize(tif));
+ /*
+ * Make raw data buffer at least 8K
+ */
+ if (size < 8*1024)
+ size = 8*1024;
+ bp = NULL; /* NB: force malloc */
+ }
+ if (bp == NULL) {
+ bp = _TIFFmalloc(size);
+ if (bp == NULL) {
+ TIFFErrorExt(tif->tif_clientdata, module, "No space for output buffer");
+ return (0);
+ }
+ tif->tif_flags |= TIFF_MYBUFFER;
+ } else
+ tif->tif_flags &= ~TIFF_MYBUFFER;
+ tif->tif_rawdata = (uint8*) bp;
+ tif->tif_rawdatasize = size;
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ tif->tif_flags |= TIFF_BUFFERSETUP;
+ return (1);
+}
+
+/*
+ * Grow the strip data structures by delta strips.
+ */
+static int
+TIFFGrowStrips(TIFF* tif, uint32 delta, const char* module)
+{
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64* new_stripoffset;
+ uint64* new_stripbytecount;
+
+ assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
+ new_stripoffset = (uint64*)_TIFFrealloc(td->td_stripoffset,
+ (td->td_nstrips + delta) * sizeof (uint64));
+ new_stripbytecount = (uint64*)_TIFFrealloc(td->td_stripbytecount,
+ (td->td_nstrips + delta) * sizeof (uint64));
+ if (new_stripoffset == NULL || new_stripbytecount == NULL) {
+ if (new_stripoffset)
+ _TIFFfree(new_stripoffset);
+ if (new_stripbytecount)
+ _TIFFfree(new_stripbytecount);
+ td->td_nstrips = 0;
+ TIFFErrorExt(tif->tif_clientdata, module, "No space to expand strip arrays");
+ return (0);
+ }
+ td->td_stripoffset = new_stripoffset;
+ td->td_stripbytecount = new_stripbytecount;
+ _TIFFmemset(td->td_stripoffset + td->td_nstrips,
+ 0, delta*sizeof (uint64));
+ _TIFFmemset(td->td_stripbytecount + td->td_nstrips,
+ 0, delta*sizeof (uint64));
+ td->td_nstrips += delta;
+ tif->tif_flags |= TIFF_DIRTYDIRECT;
+
+ return (1);
+}
+
+/*
+ * Append the data to the specified strip.
+ */
+static int
+TIFFAppendToStrip(TIFF* tif, uint32 strip, uint8* data, tmsize_t cc)
+{
+ static const char module[] = "TIFFAppendToStrip";
+ TIFFDirectory *td = &tif->tif_dir;
+ uint64 m;
+ int64 old_byte_count = -1;
+
+ if (td->td_stripoffset[strip] == 0 || tif->tif_curoff == 0) {
+ assert(td->td_nstrips > 0);
+
+ if( td->td_stripbytecount[strip] != 0
+ && td->td_stripoffset[strip] != 0
+ && td->td_stripbytecount[strip] >= (uint64) cc )
+ {
+ /*
+ * There is already tile data on disk, and the new tile
+ * data we have will fit in the same space. The only
+ * aspect of this that is risky is that there could be
+ * more data to append to this strip before we are done
+ * depending on how we are getting called.
+ */
+ if (!SeekOK(tif, td->td_stripoffset[strip])) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Seek error at scanline %lu",
+ (unsigned long)tif->tif_row);
+ return (0);
+ }
+ }
+ else
+ {
+ /*
+ * Seek to end of file, and set that as our location to
+ * write this strip.
+ */
+ td->td_stripoffset[strip] = TIFFSeekFile(tif, 0, SEEK_END);
+ tif->tif_flags |= TIFF_DIRTYSTRIP;
+ }
+
+ tif->tif_curoff = td->td_stripoffset[strip];
+
+ /*
+ * We are starting a fresh strip/tile, so set the size to zero.
+ */
+ old_byte_count = td->td_stripbytecount[strip];
+ td->td_stripbytecount[strip] = 0;
+ }
+
+ m = tif->tif_curoff+cc;
+ if (!(tif->tif_flags&TIFF_BIGTIFF))
+ m = (uint32)m;
+ if ((m<tif->tif_curoff)||(m<(uint64)cc))
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "Maximum TIFF file size exceeded");
+ return (0);
+ }
+ if (!WriteOK(tif, data, cc)) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Write error at scanline %lu",
+ (unsigned long) tif->tif_row);
+ return (0);
+ }
+ tif->tif_curoff = m;
+ td->td_stripbytecount[strip] += cc;
+
+ if( (int64) td->td_stripbytecount[strip] != old_byte_count )
+ tif->tif_flags |= TIFF_DIRTYSTRIP;
+
+ return (1);
+}
+
+/*
+ * Internal version of TIFFFlushData that can be
+ * called by ``encodestrip routines'' w/o concern
+ * for infinite recursion.
+ */
+int
+TIFFFlushData1(TIFF* tif)
+{
+ if (tif->tif_rawcc > 0 && tif->tif_flags & TIFF_BUF4WRITE ) {
+ if (!isFillOrder(tif, tif->tif_dir.td_fillorder) &&
+ (tif->tif_flags & TIFF_NOBITREV) == 0)
+ TIFFReverseBits((uint8*)tif->tif_rawdata,
+ tif->tif_rawcc);
+ if (!TIFFAppendToStrip(tif,
+ isTiled(tif) ? tif->tif_curtile : tif->tif_curstrip,
+ tif->tif_rawdata, tif->tif_rawcc))
+ return (0);
+ tif->tif_rawcc = 0;
+ tif->tif_rawcp = tif->tif_rawdata;
+ }
+ return (1);
+}
+
+/*
+ * Set the current write offset. This should only be
+ * used to set the offset to a known previous location
+ * (very carefully), or to 0 so that the next write gets
+ * appended to the end of the file.
+ */
+void
+TIFFSetWriteOffset(TIFF* tif, toff_t off)
+{
+ tif->tif_curoff = off;
+}
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tif_zip.c b/core/src/fxcodec/fx_tiff/tiff_v403/tif_zip.c
new file mode 100644
index 0000000000..0bb2a8cb29
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tif_zip.c
@@ -0,0 +1,471 @@
+/* $Id: tif_zip.c,v 1.31 2011-01-06 16:00:23 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1995-1997 Sam Leffler
+ * Copyright (c) 1995-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+#if (!defined(_FPDFAPI_MINI_) || defined(_TIFF_DECODER_)) && !defined(_USE_ADDIN_) && !defined _FX_NO_ANSIC_ && !defined(_FX_EMB_NOUSE_DECODER_)
+#include "tiffiop.h"
+#ifdef ZIP_SUPPORT
+/*
+ * TIFF Library.
+ *
+ * ZIP (aka Deflate) Compression Support
+ *
+ * This file is simply an interface to the zlib library written by
+ * Jean-loup Gailly and Mark Adler. You must use version 1.0 or later
+ * of the library: this code assumes the 1.0 API and also depends on
+ * the ability to write the zlib header multiple times (one per strip)
+ * which was not possible with versions prior to 0.95. Note also that
+ * older versions of this codec avoided this bug by supressing the header
+ * entirely. This means that files written with the old library cannot
+ * be read; they should be converted to a different compression scheme
+ * and then reconverted.
+ *
+ * The data format used by the zlib library is described in the files
+ * zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available in the
+ * directory ftp://ftp.uu.net/pub/archiving/zip/doc. The library was
+ * last found at ftp://ftp.uu.net/pub/archiving/zip/zlib/zlib-0.99.tar.gz.
+ */
+#include "tif_predict.h"
+#include "../../fx_zlib/include/fx_zlib.h"
+
+#include <stdio.h>
+
+/*
+ * Sigh, ZLIB_VERSION is defined as a string so there's no
+ * way to do a proper check here. Instead we guess based
+ * on the presence of #defines that were added between the
+ * 0.95 and 1.0 distributions.
+ */
+#if !defined(Z_NO_COMPRESSION) || !defined(Z_DEFLATED)
+#error "Antiquated ZLIB software; you must use version 1.0 or later"
+#endif
+
+/*
+ * State block for each open TIFF
+ * file using ZIP compression/decompression.
+ */
+typedef struct {
+ TIFFPredictorState predict;
+ z_stream stream;
+ int zipquality; /* compression level */
+ int state; /* state flags */
+#define ZSTATE_INIT_DECODE 0x01
+#define ZSTATE_INIT_ENCODE 0x02
+
+ TIFFVGetMethod vgetparent; /* super-class method */
+ TIFFVSetMethod vsetparent; /* super-class method */
+} ZIPState;
+
+#define ZState(tif) ((ZIPState*) (tif)->tif_data)
+#define DecoderState(tif) ZState(tif)
+#define EncoderState(tif) ZState(tif)
+
+static int ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s);
+static int ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s);
+
+static int
+ZIPFixupTags(TIFF* tif)
+{
+ (void) tif;
+ return (1);
+}
+
+static int
+ZIPSetupDecode(TIFF* tif)
+{
+ static const char module[] = "ZIPSetupDecode";
+ ZIPState* sp = DecoderState(tif);
+
+ assert(sp != NULL);
+
+ /* if we were last encoding, terminate this mode */
+ if (sp->state & ZSTATE_INIT_ENCODE) {
+ deflateEnd(&sp->stream);
+ sp->state = 0;
+ }
+
+ if (inflateInit(&sp->stream) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+ return (0);
+ } else {
+ sp->state |= ZSTATE_INIT_DECODE;
+ return (1);
+ }
+}
+
+/*
+ * Setup state for decoding a strip.
+ */
+static int
+ZIPPreDecode(TIFF* tif, uint16 s)
+{
+ static const char module[] = "ZIPPreDecode";
+ ZIPState* sp = DecoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+
+ if( (sp->state & ZSTATE_INIT_DECODE) == 0 )
+ tif->tif_setupdecode( tif );
+
+ sp->stream.next_in = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_in = (uInt) tif->tif_rawcc;
+ if ((tmsize_t)sp->stream.avail_in != tif->tif_rawcc)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ return (inflateReset(&sp->stream) == Z_OK);
+}
+
+static int
+ZIPDecode(TIFF* tif, uint8* op, tmsize_t occ, uint16 s)
+{
+ static const char module[] = "ZIPDecode";
+ ZIPState* sp = DecoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+ assert(sp->state == ZSTATE_INIT_DECODE);
+
+ sp->stream.next_in = tif->tif_rawcp;
+ sp->stream.avail_in = (uInt) tif->tif_rawcc;
+
+ sp->stream.next_out = op;
+ assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_out = (uInt) occ;
+ if ((tmsize_t)sp->stream.avail_out != occ)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ do {
+ int state = inflate(&sp->stream, Z_PARTIAL_FLUSH);
+ if (state == Z_STREAM_END)
+ break;
+ if (state == Z_DATA_ERROR) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Decoding error at scanline %lu, %s",
+ (unsigned long) tif->tif_row, sp->stream.msg);
+ if (inflateSync(&sp->stream) != Z_OK)
+ return (0);
+ continue;
+ }
+ if (state != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ } while (sp->stream.avail_out > 0);
+ if (sp->stream.avail_out != 0) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Not enough data at scanline %lu (short " TIFF_UINT64_FORMAT " bytes)",
+ (unsigned long) tif->tif_row, (TIFF_UINT64_T) sp->stream.avail_out);
+ return (0);
+ }
+
+ tif->tif_rawcp = sp->stream.next_in;
+ tif->tif_rawcc = sp->stream.avail_in;
+
+ return (1);
+}
+
+static int
+ZIPSetupEncode(TIFF* tif)
+{
+ static const char module[] = "ZIPSetupEncode";
+ ZIPState* sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ if (sp->state & ZSTATE_INIT_DECODE) {
+ inflateEnd(&sp->stream);
+ sp->state = 0;
+ }
+
+ if (deflateInit(&sp->stream, sp->zipquality) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "%s", sp->stream.msg);
+ return (0);
+ } else {
+ sp->state |= ZSTATE_INIT_ENCODE;
+ return (1);
+ }
+}
+
+/*
+ * Reset encoding state at the start of a strip.
+ */
+static int
+ZIPPreEncode(TIFF* tif, uint16 s)
+{
+ static const char module[] = "ZIPPreEncode";
+ ZIPState *sp = EncoderState(tif);
+
+ (void) s;
+ assert(sp != NULL);
+ if( sp->state != ZSTATE_INIT_ENCODE )
+ tif->tif_setupencode( tif );
+
+ sp->stream.next_out = tif->tif_rawdata;
+ assert(sizeof(sp->stream.avail_out)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_out = (uInt)tif->tif_rawdatasize;
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ return (deflateReset(&sp->stream) == Z_OK);
+}
+
+/*
+ * Encode a chunk of pixels.
+ */
+static int
+ZIPEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
+{
+ static const char module[] = "ZIPEncode";
+ ZIPState *sp = EncoderState(tif);
+
+ assert(sp != NULL);
+ assert(sp->state == ZSTATE_INIT_ENCODE);
+
+ (void) s;
+ sp->stream.next_in = bp;
+ assert(sizeof(sp->stream.avail_in)==4); /* if this assert gets raised,
+ we need to simplify this code to reflect a ZLib that is likely updated
+ to deal with 8byte memory sizes, though this code will respond
+ apropriately even before we simplify it */
+ sp->stream.avail_in = (uInt) cc;
+ if ((tmsize_t)sp->stream.avail_in != cc)
+ {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib cannot deal with buffers this size");
+ return (0);
+ }
+ do {
+ if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ if (sp->stream.avail_out == 0) {
+ tif->tif_rawcc = tif->tif_rawdatasize;
+ TIFFFlushData1(tif);
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
+ }
+ } while (sp->stream.avail_in > 0);
+ return (1);
+}
+
+/*
+ * Finish off an encoded strip by flushing the last
+ * string and tacking on an End Of Information code.
+ */
+static int
+ZIPPostEncode(TIFF* tif)
+{
+ static const char module[] = "ZIPPostEncode";
+ ZIPState *sp = EncoderState(tif);
+ int state;
+
+ sp->stream.avail_in = 0;
+ do {
+ state = deflate(&sp->stream, Z_FINISH);
+ switch (state) {
+ case Z_STREAM_END:
+ case Z_OK:
+ if ((tmsize_t)sp->stream.avail_out != tif->tif_rawdatasize)
+ {
+ tif->tif_rawcc = tif->tif_rawdatasize - sp->stream.avail_out;
+ TIFFFlushData1(tif);
+ sp->stream.next_out = tif->tif_rawdata;
+ sp->stream.avail_out = (uInt) tif->tif_rawdatasize; /* this is a safe typecast, as check is made already in ZIPPreEncode */
+ }
+ break;
+ default:
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ } while (state != Z_STREAM_END);
+ return (1);
+}
+
+static void
+ZIPCleanup(TIFF* tif)
+{
+ ZIPState* sp = ZState(tif);
+
+ assert(sp != 0);
+
+ (void)TIFFPredictorCleanup(tif);
+
+ tif->tif_tagmethods.vgetfield = sp->vgetparent;
+ tif->tif_tagmethods.vsetfield = sp->vsetparent;
+
+ if (sp->state & ZSTATE_INIT_ENCODE) {
+ deflateEnd(&sp->stream);
+ sp->state = 0;
+ } else if( sp->state & ZSTATE_INIT_DECODE) {
+ inflateEnd(&sp->stream);
+ sp->state = 0;
+ }
+ _TIFFfree(sp);
+ tif->tif_data = NULL;
+
+ _TIFFSetDefaultCompressionState(tif);
+}
+
+static int
+ZIPVSetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ static const char module[] = "ZIPVSetField";
+ ZIPState* sp = ZState(tif);
+
+ switch (tag) {
+ case TIFFTAG_ZIPQUALITY:
+ sp->zipquality = (int) va_arg(ap, int);
+ if ( sp->state&ZSTATE_INIT_ENCODE ) {
+ if (deflateParams(&sp->stream,
+ sp->zipquality, Z_DEFAULT_STRATEGY) != Z_OK) {
+ TIFFErrorExt(tif->tif_clientdata, module, "ZLib error: %s",
+ sp->stream.msg);
+ return (0);
+ }
+ }
+ return (1);
+ default:
+ return (*sp->vsetparent)(tif, tag, ap);
+ }
+ /*NOTREACHED*/
+}
+
+static int
+ZIPVGetField(TIFF* tif, uint32 tag, va_list ap)
+{
+ ZIPState* sp = ZState(tif);
+
+ switch (tag) {
+ case TIFFTAG_ZIPQUALITY:
+ *va_arg(ap, int*) = sp->zipquality;
+ break;
+ default:
+ return (*sp->vgetparent)(tif, tag, ap);
+ }
+ return (1);
+}
+
+static const TIFFField zipFields[] = {
+ { TIFFTAG_ZIPQUALITY, 0, 0, TIFF_ANY, 0, TIFF_SETGET_INT, TIFF_SETGET_UNDEFINED, FIELD_PSEUDO, TRUE, FALSE, "", NULL },
+};
+
+int
+TIFFInitZIP(TIFF* tif, int scheme)
+{
+ static const char module[] = "TIFFInitZIP";
+ ZIPState* sp;
+
+ assert( (scheme == COMPRESSION_DEFLATE)
+ || (scheme == COMPRESSION_ADOBE_DEFLATE));
+
+ /*
+ * Merge codec-specific tag information.
+ */
+ if (!_TIFFMergeFields(tif, zipFields, TIFFArrayCount(zipFields))) {
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "Merging Deflate codec-specific tags failed");
+ return 0;
+ }
+
+ /*
+ * Allocate state block so tag methods have storage to record values.
+ */
+ tif->tif_data = (uint8*) _TIFFmalloc(sizeof (ZIPState));
+ if (tif->tif_data == NULL)
+ goto bad;
+ sp = ZState(tif);
+ sp->stream.zalloc = NULL;
+ sp->stream.zfree = NULL;
+ sp->stream.opaque = NULL;
+ sp->stream.data_type = Z_BINARY;
+
+ /*
+ * Override parent get/set field methods.
+ */
+ sp->vgetparent = tif->tif_tagmethods.vgetfield;
+ tif->tif_tagmethods.vgetfield = ZIPVGetField; /* hook for codec tags */
+ sp->vsetparent = tif->tif_tagmethods.vsetfield;
+ tif->tif_tagmethods.vsetfield = ZIPVSetField; /* hook for codec tags */
+
+ /* Default values for codec-specific fields */
+ sp->zipquality = Z_DEFAULT_COMPRESSION; /* default comp. level */
+ sp->state = 0;
+
+ /*
+ * Install codec methods.
+ */
+ tif->tif_fixuptags = ZIPFixupTags;
+ tif->tif_setupdecode = ZIPSetupDecode;
+ tif->tif_predecode = ZIPPreDecode;
+ tif->tif_decoderow = ZIPDecode;
+ tif->tif_decodestrip = ZIPDecode;
+ tif->tif_decodetile = ZIPDecode;
+ tif->tif_setupencode = ZIPSetupEncode;
+ tif->tif_preencode = ZIPPreEncode;
+ tif->tif_postencode = ZIPPostEncode;
+ tif->tif_encoderow = ZIPEncode;
+ tif->tif_encodestrip = ZIPEncode;
+ tif->tif_encodetile = ZIPEncode;
+ tif->tif_cleanup = ZIPCleanup;
+ /*
+ * Setup predictor setup.
+ */
+ (void) TIFFPredictorInit(tif);
+ return (1);
+bad:
+ TIFFErrorExt(tif->tif_clientdata, module,
+ "No space for ZIP state block");
+ return (0);
+}
+#endif /* ZIP_SUPORT */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
+#endif
+
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tiff.h b/core/src/fxcodec/fx_tiff/tiff_v403/tiff.h
new file mode 100644
index 0000000000..19b4e7976d
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tiff.h
@@ -0,0 +1,678 @@
+/* $Id: tiff.h,v 1.68 2012-08-19 16:56:35 bfriesen Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFF_
+#define _TIFF_
+
+#include "tiffconf.h"
+
+/*
+ * Tag Image File Format (TIFF)
+ *
+ * Based on Rev 6.0 from:
+ * Developer's Desk
+ * Aldus Corporation
+ * 411 First Ave. South
+ * Suite 200
+ * Seattle, WA 98104
+ * 206-622-5500
+ *
+ * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf)
+ *
+ * For BigTIFF design notes see the following links
+ * http://www.remotesensing.org/libtiff/bigtiffdesign.html
+ * http://www.awaresystems.be/imaging/tiff/bigtiff.html
+ */
+
+#define TIFF_VERSION_CLASSIC 42
+#define TIFF_VERSION_BIG 43
+
+#define TIFF_BIGENDIAN 0x4d4d
+#define TIFF_LITTLEENDIAN 0x4949
+#define MDI_LITTLEENDIAN 0x5045
+#define MDI_BIGENDIAN 0x4550
+
+/*
+ * Intrinsic data types required by the file format:
+ *
+ * 8-bit quantities int8/uint8
+ * 16-bit quantities int16/uint16
+ * 32-bit quantities int32/uint32
+ * 64-bit quantities int64/uint64
+ * strings unsigned char*
+ */
+
+typedef TIFF_INT8_T int8;
+typedef TIFF_UINT8_T uint8;
+
+typedef TIFF_INT16_T int16;
+typedef TIFF_UINT16_T uint16;
+
+typedef TIFF_INT32_T int32;
+typedef TIFF_UINT32_T uint32;
+
+typedef TIFF_INT64_T int64;
+typedef TIFF_UINT64_T uint64;
+
+/*
+ * Some types as promoted in a variable argument list
+ * We use uint16_vap rather then directly using int, because this way
+ * we document the type we actually want to pass through, conceptually,
+ * rather then confusing the issue by merely stating the type it gets
+ * promoted to
+ */
+
+typedef int uint16_vap;
+
+/*
+ * TIFF header.
+ */
+typedef struct {
+ uint16 tiff_magic; /* magic number (defines byte order) */
+ uint16 tiff_version; /* TIFF version number */
+} TIFFHeaderCommon;
+typedef struct {
+ uint16 tiff_magic; /* magic number (defines byte order) */
+ uint16 tiff_version; /* TIFF version number */
+ uint32 tiff_diroff; /* byte offset to first directory */
+} TIFFHeaderClassic;
+typedef struct {
+ uint16 tiff_magic; /* magic number (defines byte order) */
+ uint16 tiff_version; /* TIFF version number */
+ uint16 tiff_offsetsize; /* size of offsets, should be 8 */
+ uint16 tiff_unused; /* unused word, should be 0 */
+ uint64 tiff_diroff; /* byte offset to first directory */
+} TIFFHeaderBig;
+
+
+/*
+ * NB: In the comments below,
+ * - items marked with a + are obsoleted by revision 5.0,
+ * - items marked with a ! are introduced in revision 6.0.
+ * - items marked with a % are introduced post revision 6.0.
+ * - items marked with a $ are obsoleted by revision 6.0.
+ * - items marked with a & are introduced by Adobe DNG specification.
+ */
+
+/*
+ * Tag data type information.
+ *
+ * Note: RATIONALs are the ratio of two 32-bit integer values.
+ */
+typedef enum {
+ TIFF_NOTYPE = 0, /* placeholder */
+ TIFF_BYTE = 1, /* 8-bit unsigned integer */
+ TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */
+ TIFF_SHORT = 3, /* 16-bit unsigned integer */
+ TIFF_LONG = 4, /* 32-bit unsigned integer */
+ TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */
+ TIFF_SBYTE = 6, /* !8-bit signed integer */
+ TIFF_UNDEFINED = 7, /* !8-bit untyped data */
+ TIFF_SSHORT = 8, /* !16-bit signed integer */
+ TIFF_SLONG = 9, /* !32-bit signed integer */
+ TIFF_SRATIONAL = 10, /* !64-bit signed fraction */
+ TIFF_FLOAT = 11, /* !32-bit IEEE floating point */
+ TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */
+ TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */
+ TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */
+ TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */
+ TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */
+} TIFFDataType;
+
+/*
+ * TIFF Tag Definitions.
+ */
+#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */
+#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */
+#define FILETYPE_PAGE 0x2 /* one page of many */
+#define FILETYPE_MASK 0x4 /* transparency mask */
+#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */
+#define OFILETYPE_IMAGE 1 /* full resolution image data */
+#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */
+#define OFILETYPE_PAGE 3 /* one page of many */
+#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */
+#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */
+#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */
+#define TIFFTAG_COMPRESSION 259 /* data compression technique */
+#define COMPRESSION_NONE 1 /* dump mode */
+#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */
+#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */
+#define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */
+#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */
+#define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */
+#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */
+#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */
+#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */
+#define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */
+#define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */
+#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */
+#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */
+#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */
+#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */
+/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
+#define COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */
+#define COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */
+#define COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */
+#define COMPRESSION_IT8BL 32898 /* IT8 Binary line art */
+/* compression codes 32908-32911 are reserved for Pixar */
+#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */
+#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */
+#define COMPRESSION_DEFLATE 32946 /* Deflate compression */
+#define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression,
+ as recognized by Adobe */
+/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */
+#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */
+#define COMPRESSION_JBIG 34661 /* ISO JBIG */
+#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */
+#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */
+#define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */
+#define COMPRESSION_LZMA 34925 /* LZMA2 */
+#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */
+#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */
+#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */
+#define PHOTOMETRIC_RGB 2 /* RGB color model */
+#define PHOTOMETRIC_PALETTE 3 /* color map indexed */
+#define PHOTOMETRIC_MASK 4 /* $holdout mask */
+#define PHOTOMETRIC_SEPARATED 5 /* !color separations */
+#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */
+#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */
+#define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */
+#define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */
+#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */
+#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */
+#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */
+#define THRESHHOLD_BILEVEL 1 /* b&w art scan */
+#define THRESHHOLD_HALFTONE 2 /* or dithered scan */
+#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */
+#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */
+#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */
+#define TIFFTAG_FILLORDER 266 /* data order within a byte */
+#define FILLORDER_MSB2LSB 1 /* most significant -> least */
+#define FILLORDER_LSB2MSB 2 /* least significant -> most */
+#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */
+#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */
+#define TIFFTAG_MAKE 271 /* scanner manufacturer name */
+#define TIFFTAG_MODEL 272 /* scanner model name/number */
+#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */
+#define TIFFTAG_ORIENTATION 274 /* +image orientation */
+#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */
+#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */
+#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */
+#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */
+#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */
+#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */
+#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */
+#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */
+#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */
+#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */
+#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */
+#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */
+#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */
+#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */
+#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */
+#define TIFFTAG_PLANARCONFIG 284 /* storage organization */
+#define PLANARCONFIG_CONTIG 1 /* single image plane */
+#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */
+#define TIFFTAG_PAGENAME 285 /* page name image is from */
+#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */
+#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */
+#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */
+#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */
+#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */
+#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */
+#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */
+#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */
+#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
+#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */
+#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */
+#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */
+#define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */
+#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */
+#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */
+#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */
+#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */
+#define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */
+#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */
+#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */
+#define RESUNIT_NONE 1 /* no meaningful units */
+#define RESUNIT_INCH 2 /* english */
+#define RESUNIT_CENTIMETER 3 /* metric */
+#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */
+#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */
+#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */
+#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */
+#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */
+#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */
+#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */
+#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */
+#define TIFFTAG_SOFTWARE 305 /* name & release */
+#define TIFFTAG_DATETIME 306 /* creation date and time */
+#define TIFFTAG_ARTIST 315 /* creator of image */
+#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */
+#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */
+#define PREDICTOR_NONE 1 /* no prediction scheme used */
+#define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */
+#define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */
+#define TIFFTAG_WHITEPOINT 318 /* image white point */
+#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */
+#define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */
+#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */
+#define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */
+#define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */
+#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */
+#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */
+#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */
+#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */
+#define CLEANFAXDATA_CLEAN 0 /* no errors detected */
+#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */
+#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */
+#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */
+#define TIFFTAG_SUBIFD 330 /* subimage descriptors */
+#define TIFFTAG_INKSET 332 /* !inks in separated image */
+#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */
+#define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */
+#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */
+#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */
+#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */
+#define TIFFTAG_TARGETPRINTER 337 /* !separation target */
+#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */
+#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */
+#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */
+#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */
+#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */
+#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */
+#define SAMPLEFORMAT_INT 2 /* !signed integer data */
+#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */
+#define SAMPLEFORMAT_VOID 4 /* !untyped data */
+#define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */
+#define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */
+#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */
+#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */
+#define TIFFTAG_CLIPPATH 343 /* %ClipPath
+ [Adobe TIFF technote 2] */
+#define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits
+ [Adobe TIFF technote 2] */
+#define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits
+ [Adobe TIFF technote 2] */
+#define TIFFTAG_INDEXED 346 /* %Indexed
+ [Adobe TIFF Technote 3] */
+#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */
+#define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */
+/* Tags 400-435 are from the TIFF/FX spec */
+#define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */
+#define TIFFTAG_PROFILETYPE 401 /* ! */
+#define PROFILETYPE_UNSPECIFIED 0 /* ! */
+#define PROFILETYPE_G3_FAX 1 /* ! */
+#define TIFFTAG_FAXPROFILE 402 /* ! */
+#define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */
+#define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */
+#define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */
+#define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */
+#define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */
+#define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */
+#define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */
+#define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */
+#define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */
+#define CODINGMETHODS_T6 (1 << 3) /* !T.6 */
+#define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */
+#define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */
+#define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */
+#define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */
+#define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */
+#define TIFFTAG_DECODE 433 /* !TIFF/FX decode */
+#define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */
+#define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */
+/*
+ * Tags 512-521 are obsoleted by Technical Note #2 which specifies a
+ * revised JPEG-in-TIFF scheme.
+ */
+#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */
+#define JPEGPROC_BASELINE 1 /* !baseline sequential */
+#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */
+#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */
+#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */
+#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */
+#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */
+#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */
+#define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */
+#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */
+#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */
+#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */
+#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */
+#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */
+#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */
+#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */
+#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */
+#define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */
+#define TIFFTAG_XMLPACKET 700 /* %XML packet
+ [Adobe XMP Specification,
+ January 2004 */
+#define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID
+ [Adobe TIFF technote] */
+/* tags 32952-32956 are private tags registered to Island Graphics */
+#define TIFFTAG_REFPTS 32953 /* image reference points */
+#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */
+#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */
+#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */
+/* tags 32995-32999 are private tags registered to SGI */
+#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */
+#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */
+#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */
+#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */
+/* tags 33300-33309 are private tags registered to Pixar */
+/*
+ * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH
+ * are set when an image has been cropped out of a larger image.
+ * They reflect the size of the original uncropped image.
+ * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used
+ * to determine the position of the smaller image in the larger one.
+ */
+#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */
+#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */
+ /* Tags 33302-33306 are used to identify special image modes and data
+ * used by Pixar's texture formats.
+ */
+#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */
+#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */
+#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */
+#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305
+#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306
+/* tag 33405 is a private tag registered to Eastman Kodak */
+#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */
+/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */
+#define TIFFTAG_COPYRIGHT 33432 /* copyright string */
+/* IPTC TAG from RichTIFF specifications */
+#define TIFFTAG_RICHTIFFIPTC 33723
+/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@apago.com) */
+#define TIFFTAG_IT8SITE 34016 /* site name */
+#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */
+#define TIFFTAG_IT8HEADER 34018 /* DDES Header */
+#define TIFFTAG_IT8RASTERPADDING 34019 /* raster scanline padding */
+#define TIFFTAG_IT8BITSPERRUNLENGTH 34020 /* # of bits in short run */
+#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021/* # of bits in long run */
+#define TIFFTAG_IT8COLORTABLE 34022 /* LW colortable */
+#define TIFFTAG_IT8IMAGECOLORINDICATOR 34023 /* BP/BL image color switch */
+#define TIFFTAG_IT8BKGCOLORINDICATOR 34024 /* BP/BL bg color switch */
+#define TIFFTAG_IT8IMAGECOLORVALUE 34025 /* BP/BL image color value */
+#define TIFFTAG_IT8BKGCOLORVALUE 34026 /* BP/BL bg color value */
+#define TIFFTAG_IT8PIXELINTENSITYRANGE 34027 /* MP pixel intensity value */
+#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028 /* HC transparency switch */
+#define TIFFTAG_IT8COLORCHARACTERIZATION 34029 /* color character. table */
+#define TIFFTAG_IT8HCUSAGE 34030 /* HC usage indicator */
+#define TIFFTAG_IT8TRAPINDICATOR 34031 /* Trapping indicator
+ (untrapped=0, trapped=1) */
+#define TIFFTAG_IT8CMYKEQUIVALENT 34032 /* CMYK color equivalents */
+/* tags 34232-34236 are private tags registered to Texas Instruments */
+#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */
+/* tag 34377 is private tag registered to Adobe for PhotoShop */
+#define TIFFTAG_PHOTOSHOP 34377
+/* tags 34665, 34853 and 40965 are documented in EXIF specification */
+#define TIFFTAG_EXIFIFD 34665 /* Pointer to EXIF private directory */
+/* tag 34750 is a private tag registered to Adobe? */
+#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */
+#define TIFFTAG_IMAGELAYER 34732 /* !TIFF/FX image layer information */
+/* tag 34750 is a private tag registered to Pixel Magic */
+#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */
+#define TIFFTAG_GPSIFD 34853 /* Pointer to GPS private directory */
+/* tags 34908-34914 are private tags registered to SGI */
+#define TIFFTAG_FAXRECVPARAMS 34908 /* encoded Class 2 ses. parms */
+#define TIFFTAG_FAXSUBADDRESS 34909 /* received SubAddr string */
+#define TIFFTAG_FAXRECVTIME 34910 /* receive time (secs) */
+#define TIFFTAG_FAXDCS 34911 /* encoded fax ses. params, Table 2/T.30 */
+/* tags 37439-37443 are registered to SGI <gregl@sgi.com> */
+#define TIFFTAG_STONITS 37439 /* Sample value to Nits */
+/* tag 34929 is a private tag registered to FedEx */
+#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */
+#define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */
+/* Adobe Digital Negative (DNG) format tags */
+#define TIFFTAG_DNGVERSION 50706 /* &DNG version number */
+#define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */
+#define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */
+#define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model
+ name */
+#define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space
+ mapping */
+#define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */
+#define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */
+#define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for
+ the BlackLevel tag */
+#define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */
+#define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level
+ differences (columns) */
+#define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level
+ differences (rows) */
+#define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding
+ level */
+#define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */
+#define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image
+ area */
+#define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image
+ area */
+#define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space
+ transformation matrix 1 */
+#define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space
+ transformation matrix 2 */
+#define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */
+#define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */
+#define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction
+ matrix 1 */
+#define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction
+ matrix 2 */
+#define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw
+ values*/
+#define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in
+ linear reference space */
+#define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in
+ x-y chromaticity
+ coordinates */
+#define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero
+ point */
+#define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */
+#define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of
+ sharpening */
+#define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of
+ the green pixels in the
+ blue/green rows track the
+ values of the green pixels
+ in the red/green rows */
+#define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */
+#define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */
+#define TIFFTAG_LENSINFO 50736 /* info about the lens */
+#define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */
+#define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the
+ camera's anti-alias filter */
+#define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */
+#define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */
+#define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote
+ tag is safe to preserve
+ along with the rest of the
+ EXIF data */
+#define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */
+#define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */
+#define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */
+#define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for
+ the raw image data */
+#define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original
+ raw file */
+#define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original
+ raw file */
+#define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels
+ of the sensor */
+#define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates
+ of fully masked pixels */
+#define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */
+#define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space
+ into ICC profile space */
+#define TIFFTAG_CURRENTICCPROFILE 50833 /* & */
+#define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */
+/* tag 65535 is an undefined tag used by Eastman Kodak */
+#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */
+
+/*
+ * The following are ``pseudo tags'' that can be used to control
+ * codec-specific functionality. These tags are not written to file.
+ * Note that these values start at 0xffff+1 so that they'll never
+ * collide with Aldus-assigned tags.
+ *
+ * If you want your private pseudo tags ``registered'' (i.e. added to
+ * this file), please post a bug report via the tracking system at
+ * http://www.remotesensing.org/libtiff/bugs.html with the appropriate
+ * C definitions to add.
+ */
+#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */
+#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */
+#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */
+#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */
+#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */
+#define FAXMODE_WORDALIGN 0x0008 /* word align row */
+#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */
+#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */
+/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */
+#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */
+#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */
+#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */
+#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */
+#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */
+#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */
+/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */
+#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */
+#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */
+#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */
+#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */
+#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */
+#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */
+#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */
+#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */
+/* 65550-65556 are allocated to Oceana Matrix <dev@oceana.com> */
+#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */
+#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */
+#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */
+#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */
+#define DCSIMAGERFILTER_IR 0 /* infrared filter */
+#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */
+#define DCSIMAGERFILTER_CFA 2 /* color filter array */
+#define DCSIMAGERFILTER_OTHER 3 /* other filter */
+#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */
+#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */
+#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */
+#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */
+#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */
+#define TIFFTAG_DCSGAMMA 65554 /* gamma value */
+#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */
+#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */
+/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */
+#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */
+#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */
+/* 65559 is allocated to Oceana Matrix <dev@oceana.com> */
+#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */
+#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */
+#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */
+#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */
+#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */
+#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */
+#define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/
+#define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/
+#define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */
+#define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */
+#define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */
+#define PERSAMPLE_MERGED 0 /* present as a single value */
+#define PERSAMPLE_MULTI 1 /* present as multiple values */
+
+/*
+ * EXIF tags
+ */
+#define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */
+#define EXIFTAG_FNUMBER 33437 /* F number */
+#define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */
+#define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */
+#define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */
+#define EXIFTAG_OECF 34856 /* Optoelectric conversion
+ factor */
+#define EXIFTAG_EXIFVERSION 36864 /* Exif version */
+#define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original
+ data generation */
+#define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital
+ data generation */
+#define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */
+#define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */
+#define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */
+#define EXIFTAG_APERTUREVALUE 37378 /* Aperture */
+#define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */
+#define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */
+#define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */
+#define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */
+#define EXIFTAG_METERINGMODE 37383 /* Metering mode */
+#define EXIFTAG_LIGHTSOURCE 37384 /* Light source */
+#define EXIFTAG_FLASH 37385 /* Flash */
+#define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */
+#define EXIFTAG_SUBJECTAREA 37396 /* Subject area */
+#define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */
+#define EXIFTAG_USERCOMMENT 37510 /* User comments */
+#define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */
+#define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */
+#define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */
+#define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */
+#define EXIFTAG_COLORSPACE 40961 /* Color space information */
+#define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */
+#define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */
+#define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */
+#define EXIFTAG_FLASHENERGY 41483 /* Flash energy */
+#define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */
+#define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */
+#define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */
+#define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */
+#define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */
+#define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */
+#define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */
+#define EXIFTAG_FILESOURCE 41728 /* File source */
+#define EXIFTAG_SCENETYPE 41729 /* Scene type */
+#define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */
+#define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */
+#define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */
+#define EXIFTAG_WHITEBALANCE 41987 /* White balance */
+#define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */
+#define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */
+#define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */
+#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
+#define EXIFTAG_CONTRAST 41992 /* Contrast */
+#define EXIFTAG_SATURATION 41993 /* Saturation */
+#define EXIFTAG_SHARPNESS 41994 /* Sharpness */
+#define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */
+#define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */
+#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
+#define EXIFTAG_GAINCONTROL 41991 /* Gain control */
+#define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */
+
+#endif /* _TIFF_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tiffconf.h b/core/src/fxcodec/fx_tiff/tiff_v403/tiffconf.h
new file mode 100644
index 0000000000..3ca425c712
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tiffconf.h
@@ -0,0 +1,250 @@
+/* libtiff/tiffconf.h. Generated by configure. */
+/*
+ Configuration defines for installed libtiff.
+ This file maintained for backward compatibility. Do not use definitions
+ from this file in your programs.
+*/
+#ifndef _TIFFCONF_
+#define _TIFFCONF_
+
+#ifndef _FX_SYSTEM_H_
+# include "../../../../include/fxcrt/fx_system.h"
+#endif
+
+//NOTE: The tiff codec requires an ANSI C compiler environment for building and
+// presumes an ANSI C environment for use.
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+/* Define to 1 if you have the <sys/types.h> header file. */
+#if _FX_OS_ == _FX_WIN32_MOBILE_
+# define O_RDONLY 0x0000 /* open for reading only */
+# define O_WRONLY 0x0001 /* open for writing only */
+# define O_RDWR 0x0002 /* open for reading and writing */
+# define O_CREAT 0x0100 /* create and open file */
+# define O_TRUNC 0x0200 /* open and truncate */
+#else
+# define HAVE_SYS_TYPES_H 1
+# define HAVE_FCNTL_H 1
+#endif
+
+/* Compatibility stuff. */
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define as 0 or 1 according to the floating point format suported by the
+ machine */
+#define HAVE_IEEEFP 1
+
+/* Define to 1 if you have the <string.h> header file. */
+//#define HAVE_STRING_H 1
+//fx_system.h already include the string.h in ANSIC
+
+/* Define to 1 if you have the <search.h> header file. */
+/*#define HAVE_SEARCH_H 1 */
+
+/* The size of a `int', as computed by sizeof. */
+/* According typedef int FX_INT32; in the fx_system.h*/
+#define SIZEOF_INT 4
+
+/* Sunliang.Liu 20110325. We should config the correct long size for tif
+ fax4decode optimize in tif_fax3.c -- Linux64 decode issue.
+ TESTDOC: Bug #23661 - z1.tif. */
+#if _FX_CPU_ == _FX_WIN64_ || _FX_CPU_ == _FX_X64_ || _FX_CPU_ == _FX_IA64_
+/* The size of `unsigned long', as computed by sizeof. */
+#define SIZEOF_UNSIGNED_LONG 8
+#else
+#define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+/* Signed 8-bit type */
+#define TIFF_INT8_T signed char
+
+/* Unsigned 8-bit type */
+#define TIFF_UINT8_T unsigned char
+
+/* Signed 16-bit type */
+#define TIFF_INT16_T signed short
+
+/* Unsigned 16-bit type */
+#define TIFF_UINT16_T unsigned short
+
+/* Signed 32-bit type */
+#define TIFF_INT32_T signed int
+
+/* Unsigned 32-bit type */
+#define TIFF_UINT32_T unsigned int
+
+/* Signed 32-bit type formatter */
+#define TIFF_INT32_FORMAT "%d"
+
+/* Unsigned 32-bit type formatter */
+#define TIFF_UINT32_FORMAT "%u"
+
+#ifdef _MSC_VER // windows
+
+/* Signed 64-bit type formatter */
+#define TIFF_INT64_FORMAT "%I64d"
+
+/* Unsigned 64-bit type formatter */
+#define TIFF_UINT64_FORMAT "%I64u"
+
+/* Signed 64-bit type */
+#define TIFF_INT64_T signed __int64
+
+/* Unsigned 64-bit type */
+#define TIFF_UINT64_T unsigned __int64
+
+#else // linux/unix
+
+#if 0 //_FX_CPU_ == _FX_X64_ // linux/unix 64
+
+/* Signed 64-bit type formatter */
+#define TIFF_INT64_FORMAT "%ld"
+
+/* Unsigned 64-bit type formatter */
+#define TIFF_UINT64_FORMAT "%lu"
+
+/* Signed 64-bit type */
+#define TIFF_INT64_T signed long
+
+#else // linux/unix 32
+
+/* Signed 64-bit type formatter */
+#define TIFF_INT64_FORMAT "%lld"
+
+/* Unsigned 64-bit type formatter */
+#define TIFF_UINT64_FORMAT "%llu"
+
+/* Signed 64-bit type */
+#define TIFF_INT64_T signed long long
+
+#endif // end _FX_CPU_
+
+/* Unsigned 64-bit type */
+#define TIFF_UINT64_T unsigned long long
+
+#endif
+
+
+/* Signed size type */
+#ifdef _MSC_VER
+
+#if defined(_WIN64)
+#define TIFF_SSIZE_T signed __int64
+#else
+#define TIFF_SSIZE_T signed int
+#endif
+
+#else
+
+#define TIFF_SSIZE_T signed long
+
+#endif
+
+/* Signed size type formatter */
+#if defined(_WIN64)
+#define TIFF_SSIZE_FORMAT "%I64d"
+#else
+#define TIFF_SSIZE_FORMAT "%ld"
+#endif
+
+/* Pointer difference type */
+#ifdef _MSC_VER
+#define TIFF_PTRDIFF_T long
+#else
+#define TIFF_PTRDIFF_T ptrdiff_t
+#endif
+
+/* Signed 64-bit type */
+/*#define TIFF_INT64_T signed __int64*/
+
+/* Unsigned 64-bit type */
+/*#define TIFF_UINT64_T unsigned __int64*/
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+# ifndef inline
+# define inline __inline
+# endif
+#endif
+
+#define lfind _lfind
+
+#define BSDTYPES
+
+/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
+#define HOST_FILLORDER FILLORDER_LSB2MSB
+
+/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
+ (Intel) */
+#if _FX_ENDIAN_ == _FX_BIG_ENDIAN_
+# define HOST_BIGENDIAN 1
+#else
+# define HOST_BIGENDIAN 0
+#endif
+
+/* Support CCITT Group 3 & 4 algorithms */
+#define CCITT_SUPPORT 1
+
+/* Support JPEG compression (requires IJG JPEG library) */
+#define JPEG_SUPPORT 1
+
+/* Support LogLuv high dynamic range encoding */
+#define LOGLUV_SUPPORT 1
+
+/* Support LZW algorithm */
+#define LZW_SUPPORT 1
+
+/* Support NeXT 2-bit RLE algorithm */
+#define NEXT_SUPPORT 1
+
+/* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation
+ fails with unpatched IJG JPEG library) */
+#define OJPEG_SUPPORT 1
+
+/* Support Macintosh PackBits algorithm */
+#define PACKBITS_SUPPORT 1
+
+/* Support Pixar log-format algorithm (requires Zlib) */
+#define PIXARLOG_SUPPORT 1
+
+/* Support ThunderScan 4-bit RLE algorithm */
+#define THUNDER_SUPPORT 1
+
+/* Support Deflate compression */
+#define ZIP_SUPPORT 1
+
+/* Support strip chopping (whether or not to convert single-strip uncompressed
+ images to mutiple strips of ~8Kb to reduce memory usage) */
+#define STRIPCHOP_DEFAULT TIFF_STRIPCHOP
+
+/* Enable SubIFD tag (330) support */
+#define SUBIFD_SUPPORT 1
+
+/* Treat extra sample as alpha (default enabled). The RGBA interface will
+ treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many
+ packages produce RGBA files but don't mark the alpha properly. */
+#define DEFAULT_EXTRASAMPLE_AS_ALPHA 1
+
+/* Pick up YCbCr subsampling info from the JPEG data stream to support files
+ lacking the tag (default enabled). */
+#define CHECK_JPEG_YCBCR_SUBSAMPLING 1
+
+/* Support MS MDI magic number files as TIFF */
+#define MDI_SUPPORT 1
+
+/*
+ * Feature support definitions.
+ * XXX: These macros are obsoleted. Don't use them in your apps!
+ * Macros stays here for backward compatibility and should be always defined.
+ */
+#define COLORIMETRY_SUPPORT
+#define YCBCR_SUPPORT
+#define CMYK_SUPPORT
+#define ICC_SUPPORT
+#define PHOTOSHOP_SUPPORT
+#define IPTC_SUPPORT
+
+#endif /* _TIFFCONF_ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tiffio.h b/core/src/fxcodec/fx_tiff/tiff_v403/tiffio.h
new file mode 100644
index 0000000000..4c749edc9e
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tiffio.h
@@ -0,0 +1,559 @@
+/* $Id: tiffio.h,v 1.91 2012-07-29 15:45:29 tgl Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFIO_
+#define _TIFFIO_
+
+/*
+ * TIFF I/O Library Definitions.
+ */
+#include "tiff.h"
+#include "tiffvers.h"
+
+/*
+ * TIFF is defined as an incomplete type to hide the
+ * library's internal data structures from clients.
+ */
+typedef struct tiff TIFF;
+
+/*
+ * The following typedefs define the intrinsic size of
+ * data types used in the *exported* interfaces. These
+ * definitions depend on the proper definition of types
+ * in tiff.h. Note also that the varargs interface used
+ * to pass tag types and values uses the types defined in
+ * tiff.h directly.
+ *
+ * NB: ttag_t is unsigned int and not unsigned short because
+ * ANSI C requires that the type before the ellipsis be a
+ * promoted type (i.e. one of int, unsigned int, pointer,
+ * or double) and because we defined pseudo-tags that are
+ * outside the range of legal Aldus-assigned tags.
+ * NB: tsize_t is int32 and not uint32 because some functions
+ * return -1.
+ * NB: toff_t is not off_t for many reasons; TIFFs max out at
+ * 32-bit file offsets, and BigTIFF maxes out at 64-bit
+ * offsets being the most important, and to ensure use of
+ * a consistently unsigned type across architectures.
+ * Prior to libtiff 4.0, this was an unsigned 32 bit type.
+ */
+/*
+ * this is the machine addressing size type, only it's signed, so make it
+ * int32 on 32bit machines, int64 on 64bit machines
+ */
+typedef TIFF_SSIZE_T tmsize_t;
+typedef uint64 toff_t; /* file offset */
+/* the following are deprecated and should be replaced by their defining
+ counterparts */
+typedef uint32 ttag_t; /* directory tag */
+typedef uint16 tdir_t; /* directory index */
+typedef uint16 tsample_t; /* sample number */
+typedef uint32 tstrile_t; /* strip or tile number */
+typedef tstrile_t tstrip_t; /* strip number */
+typedef tstrile_t ttile_t; /* tile number */
+typedef tmsize_t tsize_t; /* i/o size in bytes */
+typedef void* tdata_t; /* image data ref */
+
+#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32))
+#define __WIN32__
+#endif
+
+/*
+ * On windows you should define USE_WIN32_FILEIO if you are using tif_win32.c
+ * or AVOID_WIN32_FILEIO if you are using something else (like tif_unix.c).
+ *
+ * By default tif_unix.c is assumed.
+ */
+
+#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows)
+# if !defined(__CYGWIN) && !defined(AVOID_WIN32_FILEIO) && !defined(USE_WIN32_FILEIO)
+# define AVOID_WIN32_FILEIO
+# endif
+#endif
+
+#if defined(USE_WIN32_FILEIO)
+# define VC_EXTRALEAN
+# include <windows.h>
+# ifdef __WIN32__
+DECLARE_HANDLE(thandle_t); /* Win32 file handle */
+# else
+typedef HFILE thandle_t; /* client data handle */
+# endif /* __WIN32__ */
+#else
+typedef void* thandle_t; /* client data handle */
+#endif /* USE_WIN32_FILEIO */
+
+/*
+ * Flags to pass to TIFFPrintDirectory to control
+ * printing of data structures that are potentially
+ * very large. Bit-or these flags to enable printing
+ * multiple items.
+ */
+#define TIFFPRINT_NONE 0x0 /* no extra info */
+#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */
+#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */
+#define TIFFPRINT_COLORMAP 0x4 /* colormap */
+#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */
+#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */
+#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */
+
+/*
+ * Colour conversion stuff
+ */
+
+/* reference white */
+#define D65_X0 (95.0470F)
+#define D65_Y0 (100.0F)
+#define D65_Z0 (108.8827F)
+
+#define D50_X0 (96.4250F)
+#define D50_Y0 (100.0F)
+#define D50_Z0 (82.4680F)
+
+/* Structure for holding information about a display device. */
+
+typedef unsigned char TIFFRGBValue; /* 8-bit samples */
+
+typedef struct {
+ float d_mat[3][3]; /* XYZ -> luminance matrix */
+ float d_YCR; /* Light o/p for reference white */
+ float d_YCG;
+ float d_YCB;
+ uint32 d_Vrwr; /* Pixel values for ref. white */
+ uint32 d_Vrwg;
+ uint32 d_Vrwb;
+ float d_Y0R; /* Residual light for black pixel */
+ float d_Y0G;
+ float d_Y0B;
+ float d_gammaR; /* Gamma values for the three guns */
+ float d_gammaG;
+ float d_gammaB;
+} TIFFDisplay;
+
+typedef struct { /* YCbCr->RGB support */
+ TIFFRGBValue* clamptab; /* range clamping table */
+ int* Cr_r_tab;
+ int* Cb_b_tab;
+ int32* Cr_g_tab;
+ int32* Cb_g_tab;
+ int32* Y_tab;
+} TIFFYCbCrToRGB;
+
+typedef struct { /* CIE Lab 1976->RGB support */
+ int range; /* Size of conversion table */
+#define CIELABTORGB_TABLE_RANGE 1500
+ float rstep, gstep, bstep;
+ float X0, Y0, Z0; /* Reference white point */
+ TIFFDisplay display;
+ float Yr2r[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yr to r */
+ float Yg2g[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yg to g */
+ float Yb2b[CIELABTORGB_TABLE_RANGE + 1]; /* Conversion of Yb to b */
+} TIFFCIELabToRGB;
+
+/*
+ * RGBA-style image support.
+ */
+typedef struct _TIFFRGBAImage TIFFRGBAImage;
+/*
+ * The image reading and conversion routines invoke
+ * ``put routines'' to copy/image/whatever tiles of
+ * raw image data. A default set of routines are
+ * provided to convert/copy raw image data to 8-bit
+ * packed ABGR format rasters. Applications can supply
+ * alternate routines that unpack the data into a
+ * different format or, for example, unpack the data
+ * and draw the unpacked raster on the display.
+ */
+typedef void (*tileContigRoutine)
+ (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
+ unsigned char*);
+typedef void (*tileSeparateRoutine)
+ (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32,
+ unsigned char*, unsigned char*, unsigned char*, unsigned char*);
+/*
+ * RGBA-reader state.
+ */
+struct _TIFFRGBAImage {
+ TIFF* tif; /* image handle */
+ int stoponerr; /* stop on read error */
+ int isContig; /* data is packed/separate */
+ int alpha; /* type of alpha data present */
+ uint32 width; /* image width */
+ uint32 height; /* image height */
+ uint16 bitspersample; /* image bits/sample */
+ uint16 samplesperpixel; /* image samples/pixel */
+ uint16 orientation; /* image orientation */
+ uint16 req_orientation; /* requested orientation */
+ uint16 photometric; /* image photometric interp */
+ uint16* redcmap; /* colormap pallete */
+ uint16* greencmap;
+ uint16* bluecmap;
+ /* get image data routine */
+ int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32);
+ /* put decoded strip/tile */
+ union {
+ void (*any)(TIFFRGBAImage*);
+ tileContigRoutine contig;
+ tileSeparateRoutine separate;
+ } put;
+ TIFFRGBValue* Map; /* sample mapping array */
+ uint32** BWmap; /* black&white map */
+ uint32** PALmap; /* palette image map */
+ TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */
+ TIFFCIELabToRGB* cielab; /* CIE L*a*b conversion state */
+
+ uint8* UaToAa; /* Unassociated alpha to associated alpha convertion LUT */
+ uint8* Bitdepth16To8; /* LUT for conversion from 16bit to 8bit values */
+
+ int row_offset;
+ int col_offset;
+};
+
+/*
+ * Macros for extracting components from the
+ * packed ABGR form returned by TIFFReadRGBAImage.
+ */
+#define TIFFGetR(abgr) ((abgr) & 0xff)
+#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff)
+#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff)
+#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff)
+
+/*
+ * A CODEC is a software package that implements decoding,
+ * encoding, or decoding+encoding of a compression algorithm.
+ * The library provides a collection of builtin codecs.
+ * More codecs may be registered through calls to the library
+ * and/or the builtin implementations may be overridden.
+ */
+typedef int (*TIFFInitMethod)(TIFF*, int);
+typedef struct {
+ char* name;
+ uint16 scheme;
+ TIFFInitMethod init;
+} TIFFCodec;
+
+#include <stdio.h>
+#include <stdarg.h>
+
+/* share internal LogLuv conversion routines? */
+#ifndef LOGLUV_PUBLIC
+#define LOGLUV_PUBLIC 1
+#endif
+
+#if !defined(__GNUC__) && !defined(__attribute__)
+# define __attribute__(x) /*nothing*/
+#endif
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern "C" {
+#endif
+typedef void (*TIFFErrorHandler)(const char*, const char*, va_list);
+typedef void (*TIFFErrorHandlerExt)(thandle_t, const char*, const char*, va_list);
+typedef tmsize_t (*TIFFReadWriteProc)(thandle_t, void*, tmsize_t);
+typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int);
+typedef int (*TIFFCloseProc)(thandle_t);
+typedef toff_t (*TIFFSizeProc)(thandle_t);
+typedef int (*TIFFMapFileProc)(thandle_t, void** base, toff_t* size);
+typedef void (*TIFFUnmapFileProc)(thandle_t, void* base, toff_t size);
+typedef void (*TIFFExtendProc)(TIFF*);
+
+extern const char* TIFFGetVersion(void);
+
+extern const TIFFCodec* TIFFFindCODEC(uint16);
+extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod);
+extern void TIFFUnRegisterCODEC(TIFFCodec*);
+extern int TIFFIsCODECConfigured(uint16);
+extern TIFFCodec* TIFFGetConfiguredCODECs(void);
+
+/*
+ * Auxiliary functions.
+ */
+
+extern void* _TIFFmalloc(tmsize_t s);
+extern void* _TIFFrealloc(void* p, tmsize_t s);
+extern void _TIFFmemset(void* p, int v, tmsize_t c);
+extern void _TIFFmemcpy(void* d, const void* s, tmsize_t c);
+extern int _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c);
+extern void _TIFFfree(void* p);
+/* Do cmyk to rgb convert, add by Sunliang.Liu 20090723. */
+extern int TIFFCmyk2Rgb(thandle_t context, uint8 c, uint8 m, uint8 y, uint8 k, uint8* r, uint8* g, uint8* b);
+
+/*
+** Stuff, related to tag handling and creating custom tags.
+*/
+extern int TIFFGetTagListCount( TIFF * );
+extern uint32 TIFFGetTagListEntry( TIFF *, int tag_index );
+
+#define TIFF_ANY TIFF_NOTYPE /* for field descriptor searching */
+#define TIFF_VARIABLE -1 /* marker for variable length tags */
+#define TIFF_SPP -2 /* marker for SamplesPerPixel tags */
+#define TIFF_VARIABLE2 -3 /* marker for uint32 var-length tags */
+
+#define FIELD_CUSTOM 65
+
+typedef struct _TIFFField TIFFField;
+typedef struct _TIFFFieldArray TIFFFieldArray;
+
+extern const TIFFField* TIFFFindField(TIFF *, uint32, TIFFDataType);
+extern const TIFFField* TIFFFieldWithTag(TIFF*, uint32);
+extern const TIFFField* TIFFFieldWithName(TIFF*, const char *);
+
+extern uint32 TIFFFieldTag(const TIFFField*);
+extern const char* TIFFFieldName(const TIFFField*);
+extern TIFFDataType TIFFFieldDataType(const TIFFField*);
+extern int TIFFFieldPassCount(const TIFFField*);
+extern int TIFFFieldReadCount(const TIFFField*);
+extern int TIFFFieldWriteCount(const TIFFField*);
+
+typedef int (*TIFFVSetMethod)(TIFF*, uint32, va_list);
+typedef int (*TIFFVGetMethod)(TIFF*, uint32, va_list);
+typedef void (*TIFFPrintMethod)(TIFF*, FILE*, long);
+
+typedef struct {
+ TIFFVSetMethod vsetfield; /* tag set routine */
+ TIFFVGetMethod vgetfield; /* tag get routine */
+ TIFFPrintMethod printdir; /* directory print routine */
+} TIFFTagMethods;
+
+extern TIFFTagMethods *TIFFAccessTagMethods(TIFF *);
+extern void *TIFFGetClientInfo(TIFF *, const char *);
+extern void TIFFSetClientInfo(TIFF *, void *, const char *);
+
+extern void TIFFCleanup(TIFF* tif);
+extern void TIFFClose(TIFF* tif);
+extern int TIFFFlush(TIFF* tif);
+extern int TIFFFlushData(TIFF* tif);
+extern int TIFFGetField(TIFF* tif, uint32 tag, ...);
+extern int TIFFVGetField(TIFF* tif, uint32 tag, va_list ap);
+extern int TIFFGetFieldDefaulted(TIFF* tif, uint32 tag, ...);
+extern int TIFFVGetFieldDefaulted(TIFF* tif, uint32 tag, va_list ap);
+extern int TIFFReadDirectory(TIFF* tif);
+extern int TIFFReadCustomDirectory(TIFF* tif, toff_t diroff, const TIFFFieldArray* infoarray);
+extern int TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff);
+extern uint64 TIFFScanlineSize64(TIFF* tif);
+extern tmsize_t TIFFScanlineSize(TIFF* tif);
+extern uint64 TIFFRasterScanlineSize64(TIFF* tif);
+extern tmsize_t TIFFRasterScanlineSize(TIFF* tif);
+extern uint64 TIFFStripSize64(TIFF* tif);
+extern tmsize_t TIFFStripSize(TIFF* tif);
+extern uint64 TIFFRawStripSize64(TIFF* tif, uint32 strip);
+extern tmsize_t TIFFRawStripSize(TIFF* tif, uint32 strip);
+extern uint64 TIFFVStripSize64(TIFF* tif, uint32 nrows);
+extern tmsize_t TIFFVStripSize(TIFF* tif, uint32 nrows);
+extern uint64 TIFFTileRowSize64(TIFF* tif);
+extern tmsize_t TIFFTileRowSize(TIFF* tif);
+extern uint64 TIFFTileSize64(TIFF* tif);
+extern tmsize_t TIFFTileSize(TIFF* tif);
+extern uint64 TIFFVTileSize64(TIFF* tif, uint32 nrows);
+extern tmsize_t TIFFVTileSize(TIFF* tif, uint32 nrows);
+extern uint32 TIFFDefaultStripSize(TIFF* tif, uint32 request);
+extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*);
+extern int TIFFFileno(TIFF*);
+extern int TIFFSetFileno(TIFF*, int);
+extern thandle_t TIFFClientdata(TIFF*);
+extern thandle_t TIFFSetClientdata(TIFF*, thandle_t);
+extern int TIFFGetMode(TIFF*);
+extern int TIFFSetMode(TIFF*, int);
+extern int TIFFIsTiled(TIFF*);
+extern int TIFFIsByteSwapped(TIFF*);
+extern int TIFFIsUpSampled(TIFF*);
+extern int TIFFIsMSB2LSB(TIFF*);
+extern int TIFFIsBigEndian(TIFF*);
+extern TIFFReadWriteProc TIFFGetReadProc(TIFF*);
+extern TIFFReadWriteProc TIFFGetWriteProc(TIFF*);
+extern TIFFSeekProc TIFFGetSeekProc(TIFF*);
+extern TIFFCloseProc TIFFGetCloseProc(TIFF*);
+extern TIFFSizeProc TIFFGetSizeProc(TIFF*);
+extern TIFFMapFileProc TIFFGetMapFileProc(TIFF*);
+extern TIFFUnmapFileProc TIFFGetUnmapFileProc(TIFF*);
+extern uint32 TIFFCurrentRow(TIFF*);
+extern uint16 TIFFCurrentDirectory(TIFF*);
+extern uint16 TIFFNumberOfDirectories(TIFF*);
+extern uint64 TIFFCurrentDirOffset(TIFF*);
+extern uint32 TIFFCurrentStrip(TIFF*);
+extern uint32 TIFFCurrentTile(TIFF* tif);
+extern int TIFFReadBufferSetup(TIFF* tif, void* bp, tmsize_t size);
+extern int TIFFWriteBufferSetup(TIFF* tif, void* bp, tmsize_t size);
+extern int TIFFSetupStrips(TIFF *);
+extern int TIFFWriteCheck(TIFF*, int, const char *);
+extern void TIFFFreeDirectory(TIFF*);
+extern int TIFFCreateDirectory(TIFF*);
+extern int TIFFCreateCustomDirectory(TIFF*,const TIFFFieldArray*);
+extern int TIFFCreateEXIFDirectory(TIFF*);
+extern int TIFFLastDirectory(TIFF*);
+extern int TIFFSetDirectory(TIFF*, uint16);
+extern int TIFFSetSubDirectory(TIFF*, uint64);
+extern int TIFFUnlinkDirectory(TIFF*, uint16);
+extern int TIFFSetField(TIFF*, uint32, ...);
+extern int TIFFVSetField(TIFF*, uint32, va_list);
+extern int TIFFUnsetField(TIFF*, uint32);
+extern int TIFFWriteDirectory(TIFF *);
+extern int TIFFWriteCustomDirectory(TIFF *, uint64 *);
+extern int TIFFCheckpointDirectory(TIFF *);
+extern int TIFFRewriteDirectory(TIFF *);
+
+#if defined(c_plusplus) || defined(__cplusplus)
+extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0);
+extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
+extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample = 0);
+extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0);
+extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*,
+ int = ORIENTATION_BOTLEFT, int = 0);
+#else
+extern void TIFFPrintDirectory(TIFF*, FILE*, long);
+extern int TIFFReadScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
+extern int TIFFWriteScanline(TIFF* tif, void* buf, uint32 row, uint16 sample);
+extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int);
+extern int TIFFReadRGBAImageOriented(TIFF*, uint32, uint32, uint32*, int, int);
+#endif
+
+extern int TIFFReadRGBAStrip(TIFF*, uint32, uint32 * );
+extern int TIFFReadRGBATile(TIFF*, uint32, uint32, uint32 * );
+extern int TIFFRGBAImageOK(TIFF*, char [1024]);
+extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]);
+extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32);
+extern void TIFFRGBAImageEnd(TIFFRGBAImage*);
+extern TIFF* TIFFOpen(const char*, const char*);
+# ifdef __WIN32__
+extern TIFF* TIFFOpenW(const wchar_t*, const char*);
+# endif /* __WIN32__ */
+extern TIFF* TIFFFdOpen(int, const char*, const char*);
+extern TIFF* TIFFClientOpen(const char*, const char*,
+ thandle_t,
+ TIFFReadWriteProc, TIFFReadWriteProc,
+ TIFFSeekProc, TIFFCloseProc,
+ TIFFSizeProc,
+ TIFFMapFileProc, TIFFUnmapFileProc);
+extern const char* TIFFFileName(TIFF*);
+extern const char* TIFFSetFileName(TIFF*, const char *);
+extern void TIFFError(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
+extern void TIFFErrorExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
+extern void TIFFWarning(const char*, const char*, ...) __attribute__((__format__ (__printf__,2,3)));
+extern void TIFFWarningExt(thandle_t, const char*, const char*, ...) __attribute__((__format__ (__printf__,3,4)));
+extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler);
+extern TIFFErrorHandlerExt TIFFSetErrorHandlerExt(TIFFErrorHandlerExt);
+extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler);
+extern TIFFErrorHandlerExt TIFFSetWarningHandlerExt(TIFFErrorHandlerExt);
+extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc);
+extern uint32 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
+extern int TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s);
+extern uint32 TIFFNumberOfTiles(TIFF*);
+extern tmsize_t TIFFReadTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
+extern tmsize_t TIFFWriteTile(TIFF* tif, void* buf, uint32 x, uint32 y, uint32 z, uint16 s);
+extern uint32 TIFFComputeStrip(TIFF*, uint32, uint16);
+extern uint32 TIFFNumberOfStrips(TIFF*);
+extern tmsize_t TIFFReadEncodedStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
+extern tmsize_t TIFFReadRawStrip(TIFF* tif, uint32 strip, void* buf, tmsize_t size);
+extern tmsize_t TIFFReadEncodedTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
+extern tmsize_t TIFFReadRawTile(TIFF* tif, uint32 tile, void* buf, tmsize_t size);
+extern tmsize_t TIFFWriteEncodedStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
+extern tmsize_t TIFFWriteRawStrip(TIFF* tif, uint32 strip, void* data, tmsize_t cc);
+extern tmsize_t TIFFWriteEncodedTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
+extern tmsize_t TIFFWriteRawTile(TIFF* tif, uint32 tile, void* data, tmsize_t cc);
+extern int TIFFDataWidth(TIFFDataType); /* table of tag datatype widths */
+extern void TIFFSetWriteOffset(TIFF* tif, toff_t off);
+extern void TIFFSwabShort(uint16*);
+extern void TIFFSwabLong(uint32*);
+extern void TIFFSwabLong8(uint64*);
+extern void TIFFSwabFloat(float*);
+extern void TIFFSwabDouble(double*);
+extern void TIFFSwabArrayOfShort(uint16* wp, tmsize_t n);
+extern void TIFFSwabArrayOfTriples(uint8* tp, tmsize_t n);
+extern void TIFFSwabArrayOfLong(uint32* lp, tmsize_t n);
+extern void TIFFSwabArrayOfLong8(uint64* lp, tmsize_t n);
+extern void TIFFSwabArrayOfFloat(float* fp, tmsize_t n);
+extern void TIFFSwabArrayOfDouble(double* dp, tmsize_t n);
+extern void TIFFReverseBits(uint8* cp, tmsize_t n);
+extern const unsigned char* TIFFGetBitRevTable(int);
+
+#ifdef LOGLUV_PUBLIC
+#define U_NEU 0.210526316
+#define V_NEU 0.473684211
+#define UVSCALE 410.
+extern double LogL16toY(int);
+extern double LogL10toY(int);
+extern void XYZtoRGB24(float*, uint8*);
+extern int uv_decode(double*, double*, int);
+extern void LogLuv24toXYZ(uint32, float*);
+extern void LogLuv32toXYZ(uint32, float*);
+#if defined(c_plusplus) || defined(__cplusplus)
+extern int LogL16fromY(double, int = SGILOGENCODE_NODITHER);
+extern int LogL10fromY(double, int = SGILOGENCODE_NODITHER);
+extern int uv_encode(double, double, int = SGILOGENCODE_NODITHER);
+extern uint32 LogLuv24fromXYZ(float*, int = SGILOGENCODE_NODITHER);
+extern uint32 LogLuv32fromXYZ(float*, int = SGILOGENCODE_NODITHER);
+#else
+extern int LogL16fromY(double, int);
+extern int LogL10fromY(double, int);
+extern int uv_encode(double, double, int);
+extern uint32 LogLuv24fromXYZ(float*, int);
+extern uint32 LogLuv32fromXYZ(float*, int);
+#endif
+#endif /* LOGLUV_PUBLIC */
+
+extern int TIFFCIELabToRGBInit(TIFFCIELabToRGB*, const TIFFDisplay *, float*);
+extern void TIFFCIELabToXYZ(TIFFCIELabToRGB *, uint32, int32, int32,
+ float *, float *, float *);
+extern void TIFFXYZToRGB(TIFFCIELabToRGB *, float, float, float,
+ uint32 *, uint32 *, uint32 *);
+
+extern int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB*, float*, float*);
+extern void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *, uint32, int32, int32,
+ uint32 *, uint32 *, uint32 *);
+
+/****************************************************************************
+ * O B S O L E T E D I N T E R F A C E S
+ *
+ * Don't use this stuff in your applications, it may be removed in the future
+ * libtiff versions.
+ ****************************************************************************/
+typedef struct {
+ ttag_t field_tag; /* field's tag */
+ short field_readcount; /* read count/TIFF_VARIABLE/TIFF_SPP */
+ short field_writecount; /* write count/TIFF_VARIABLE */
+ TIFFDataType field_type; /* type of associated data */
+ unsigned short field_bit; /* bit in fieldsset bit vector */
+ unsigned char field_oktochange; /* if true, can change while writing */
+ unsigned char field_passcount; /* if true, pass dir count on set */
+ char *field_name; /* ASCII name */
+} TIFFFieldInfo;
+
+extern int TIFFMergeFieldInfo(TIFF*, const TIFFFieldInfo[], uint32);
+
+#if defined(c_plusplus) || defined(__cplusplus)
+}
+#endif
+
+#endif /* _TIFFIO_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tiffiop.h b/core/src/fxcodec/fx_tiff/tiff_v403/tiffiop.h
new file mode 100644
index 0000000000..c5ddc3c173
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tiffiop.h
@@ -0,0 +1,367 @@
+/* $Id: tiffiop.h,v 1.84 2012-05-30 01:50:17 fwarmerdam Exp $ */
+
+/*
+ * Copyright (c) 1988-1997 Sam Leffler
+ * Copyright (c) 1991-1997 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the names of
+ * Sam Leffler and Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Sam Leffler and Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _TIFFIOP_
+#define _TIFFIOP_
+/*
+ * ``Library-private'' definitions.
+ */
+
+#include "tiffconf.h"
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+
+#ifdef HAVE_ASSERT_H
+# include <assert.h>
+#else
+# define assert(x)
+#endif
+
+#ifdef HAVE_SEARCH_H
+# include <search.h>
+#else
+extern void *lfind(const void *, const void *, size_t *, size_t,
+ int (*)(const void *, const void *));
+#endif
+
+#include "tiffio.h"
+
+#include "tif_dir.h"
+
+#ifndef STRIP_SIZE_DEFAULT
+# define STRIP_SIZE_DEFAULT 8192
+#endif
+
+#define streq(a,b) (strcmp(a,b) == 0)
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+typedef struct client_info {
+ struct client_info *next;
+ void *data;
+ char *name;
+} TIFFClientInfoLink;
+
+/*
+ * Typedefs for ``method pointers'' used internally.
+ * these are depriciated and provided only for backwards compatibility
+ */
+typedef unsigned char tidataval_t; /* internal image data value type */
+typedef tidataval_t* tidata_t; /* reference to internal image data */
+
+typedef void (*TIFFVoidMethod)(TIFF*);
+typedef int (*TIFFBoolMethod)(TIFF*);
+typedef int (*TIFFPreMethod)(TIFF*, uint16);
+typedef int (*TIFFCodeMethod)(TIFF* tif, uint8* buf, tmsize_t size, uint16 sample);
+typedef int (*TIFFSeekMethod)(TIFF*, uint32);
+typedef void (*TIFFPostMethod)(TIFF* tif, uint8* buf, tmsize_t size);
+typedef uint32 (*TIFFStripMethod)(TIFF*, uint32);
+typedef void (*TIFFTileMethod)(TIFF*, uint32*, uint32*);
+
+struct tiff {
+ char* tif_name; /* name of open file */
+ int tif_fd; /* open file descriptor */
+ int tif_mode; /* open mode (O_*) */
+ uint32 tif_flags;
+ #define TIFF_FILLORDER 0x00003 /* natural bit fill order for machine */
+ #define TIFF_DIRTYHEADER 0x00004 /* header must be written on close */
+ #define TIFF_DIRTYDIRECT 0x00008 /* current directory must be written */
+ #define TIFF_BUFFERSETUP 0x00010 /* data buffers setup */
+ #define TIFF_CODERSETUP 0x00020 /* encoder/decoder setup done */
+ #define TIFF_BEENWRITING 0x00040 /* written 1+ scanlines to file */
+ #define TIFF_SWAB 0x00080 /* byte swap file information */
+ #define TIFF_NOBITREV 0x00100 /* inhibit bit reversal logic */
+ #define TIFF_MYBUFFER 0x00200 /* my raw data buffer; free on close */
+ #define TIFF_ISTILED 0x00400 /* file is tile, not strip- based */
+ #define TIFF_MAPPED 0x00800 /* file is mapped into memory */
+ #define TIFF_POSTENCODE 0x01000 /* need call to postencode routine */
+ #define TIFF_INSUBIFD 0x02000 /* currently writing a subifd */
+ #define TIFF_UPSAMPLED 0x04000 /* library is doing data up-sampling */
+ #define TIFF_STRIPCHOP 0x08000 /* enable strip chopping support */
+ #define TIFF_HEADERONLY 0x10000 /* read header only, do not process the first directory */
+ #define TIFF_NOREADRAW 0x20000 /* skip reading of raw uncompressed image data */
+ #define TIFF_INCUSTOMIFD 0x40000 /* currently writing a custom IFD */
+ #define TIFF_BIGTIFF 0x80000 /* read/write bigtiff */
+ #define TIFF_BUF4WRITE 0x100000 /* rawcc bytes are for writing */
+ #define TIFF_DIRTYSTRIP 0x200000 /* stripoffsets/stripbytecount dirty*/
+ #define TIFF_PERSAMPLE 0x400000 /* get/set per sample tags as arrays */
+ #define TIFF_BUFFERMMAP 0x800000 /* read buffer (tif_rawdata) points into mmap() memory */
+ uint64 tif_diroff; /* file offset of current directory */
+ uint64 tif_nextdiroff; /* file offset of following directory */
+ uint64* tif_dirlist; /* list of offsets to already seen directories to prevent IFD looping */
+ uint16 tif_dirlistsize; /* number of entires in offset list */
+ uint16 tif_dirnumber; /* number of already seen directories */
+ TIFFDirectory tif_dir; /* internal rep of current directory */
+ TIFFDirectory tif_customdir; /* custom IFDs are separated from the main ones */
+ union {
+ TIFFHeaderCommon common;
+ TIFFHeaderClassic classic;
+ TIFFHeaderBig big;
+ } tif_header;
+ uint16 tif_header_size; /* file's header block and its length */
+ uint32 tif_row; /* current scanline */
+ uint16 tif_curdir; /* current directory (index) */
+ uint32 tif_curstrip; /* current strip for read/write */
+ uint64 tif_curoff; /* current offset for read/write */
+ uint64 tif_dataoff; /* current offset for writing dir */
+ /* SubIFD support */
+ uint16 tif_nsubifd; /* remaining subifds to write */
+ uint64 tif_subifdoff; /* offset for patching SubIFD link */
+ /* tiling support */
+ uint32 tif_col; /* current column (offset by row too) */
+ uint32 tif_curtile; /* current tile for read/write */
+ tmsize_t tif_tilesize; /* # of bytes in a tile */
+ /* compression scheme hooks */
+ int tif_decodestatus;
+ TIFFBoolMethod tif_fixuptags; /* called in TIFFReadDirectory */
+ TIFFBoolMethod tif_setupdecode; /* called once before predecode */
+ TIFFPreMethod tif_predecode; /* pre- row/strip/tile decoding */
+ TIFFBoolMethod tif_setupencode; /* called once before preencode */
+ int tif_encodestatus;
+ TIFFPreMethod tif_preencode; /* pre- row/strip/tile encoding */
+ TIFFBoolMethod tif_postencode; /* post- row/strip/tile encoding */
+ TIFFCodeMethod tif_decoderow; /* scanline decoding routine */
+ TIFFCodeMethod tif_encoderow; /* scanline encoding routine */
+ TIFFCodeMethod tif_decodestrip; /* strip decoding routine */
+ TIFFCodeMethod tif_encodestrip; /* strip encoding routine */
+ TIFFCodeMethod tif_decodetile; /* tile decoding routine */
+ TIFFCodeMethod tif_encodetile; /* tile encoding routine */
+ TIFFVoidMethod tif_close; /* cleanup-on-close routine */
+ TIFFSeekMethod tif_seek; /* position within a strip routine */
+ TIFFVoidMethod tif_cleanup; /* cleanup state routine */
+ TIFFStripMethod tif_defstripsize; /* calculate/constrain strip size */
+ TIFFTileMethod tif_deftilesize; /* calculate/constrain tile size */
+ uint8* tif_data; /* compression scheme private data */
+ /* input/output buffering */
+ tmsize_t tif_scanlinesize; /* # of bytes in a scanline */
+ tmsize_t tif_scanlineskew; /* scanline skew for reading strips */
+ uint8* tif_rawdata; /* raw data buffer */
+ tmsize_t tif_rawdatasize; /* # of bytes in raw data buffer */
+ tmsize_t tif_rawdataoff; /* rawdata offset within strip */
+ tmsize_t tif_rawdataloaded;/* amount of data in rawdata */
+ uint8* tif_rawcp; /* current spot in raw buffer */
+ tmsize_t tif_rawcc; /* bytes unread from raw buffer */
+ /* memory-mapped file support */
+ uint8* tif_base; /* base of mapped file */
+ tmsize_t tif_size; /* size of mapped file region (bytes, thus tmsize_t) */
+ TIFFMapFileProc tif_mapproc; /* map file method */
+ TIFFUnmapFileProc tif_unmapproc; /* unmap file method */
+ /* input/output callback methods */
+ thandle_t tif_clientdata; /* callback parameter */
+ TIFFReadWriteProc tif_readproc; /* read method */
+ TIFFReadWriteProc tif_writeproc; /* write method */
+ TIFFSeekProc tif_seekproc; /* lseek method */
+ TIFFCloseProc tif_closeproc; /* close method */
+ TIFFSizeProc tif_sizeproc; /* filesize method */
+ /* post-decoding support */
+ TIFFPostMethod tif_postdecode; /* post decoding routine */
+ /* tag support */
+ TIFFField** tif_fields; /* sorted table of registered tags */
+ size_t tif_nfields; /* # entries in registered tag table */
+ const TIFFField* tif_foundfield; /* cached pointer to already found tag */
+ TIFFTagMethods tif_tagmethods; /* tag get/set/print routines */
+ TIFFClientInfoLink* tif_clientinfo; /* extra client information. */
+ /* Backward compatibility stuff. We need these two fields for
+ * setting up an old tag extension scheme. */
+ TIFFFieldArray* tif_fieldscompat;
+ size_t tif_nfieldscompat;
+};
+
+#define isPseudoTag(t) (t > 0xffff) /* is tag value normal or pseudo */
+
+#define isTiled(tif) (((tif)->tif_flags & TIFF_ISTILED) != 0)
+#define isMapped(tif) (((tif)->tif_flags & TIFF_MAPPED) != 0)
+#define isFillOrder(tif, o) (((tif)->tif_flags & (o)) != 0)
+#define isUpSampled(tif) (((tif)->tif_flags & TIFF_UPSAMPLED) != 0)
+#define TIFFReadFile(tif, buf, size) \
+ ((*(tif)->tif_readproc)((tif)->tif_clientdata,(buf),(size)))
+#define TIFFWriteFile(tif, buf, size) \
+ ((*(tif)->tif_writeproc)((tif)->tif_clientdata,(buf),(size)))
+#define TIFFSeekFile(tif, off, whence) \
+ ((*(tif)->tif_seekproc)((tif)->tif_clientdata,(off),(whence)))
+#define TIFFCloseFile(tif) \
+ ((*(tif)->tif_closeproc)((tif)->tif_clientdata))
+#define TIFFGetFileSize(tif) \
+ ((*(tif)->tif_sizeproc)((tif)->tif_clientdata))
+#define TIFFMapFileContents(tif, paddr, psize) \
+ ((*(tif)->tif_mapproc)((tif)->tif_clientdata,(paddr),(psize)))
+#define TIFFUnmapFileContents(tif, addr, size) \
+ ((*(tif)->tif_unmapproc)((tif)->tif_clientdata,(addr),(size)))
+
+/*
+ * Default Read/Seek/Write definitions.
+ */
+#ifndef ReadOK
+#define ReadOK(tif, buf, size) \
+ (TIFFReadFile((tif),(buf),(size))==(size))
+#endif
+#ifndef SeekOK
+#define SeekOK(tif, off) \
+ (TIFFSeekFile((tif),(off),SEEK_SET)==(off))
+#endif
+#ifndef WriteOK
+#define WriteOK(tif, buf, size) \
+ (TIFFWriteFile((tif),(buf),(size))==(size))
+#endif
+
+/* NB: the uint32 casts are to silence certain ANSI-C compilers */
+#define TIFFhowmany_32(x, y) (((uint32)x < (0xffffffff - (uint32)(y-1))) ? \
+ ((((uint32)(x))+(((uint32)(y))-1))/((uint32)(y))) : \
+ 0U)
+#define TIFFhowmany8_32(x) (((x)&0x07)?((uint32)(x)>>3)+1:(uint32)(x)>>3)
+#define TIFFroundup_32(x, y) (TIFFhowmany_32(x,y)*(y))
+#define TIFFhowmany_64(x, y) ((((uint64)(x))+(((uint64)(y))-1))/((uint64)(y)))
+#define TIFFhowmany8_64(x) (((x)&0x07)?((uint64)(x)>>3)+1:(uint64)(x)>>3)
+#define TIFFroundup_64(x, y) (TIFFhowmany_64(x,y)*(y))
+
+/* Safe multiply which returns zero if there is an integer overflow */
+#define TIFFSafeMultiply(t,v,m) ((((t)(m) != (t)0) && (((t)(((v)*(m))/(m))) == (t)(v))) ? (t)((v)*(m)) : (t)0)
+
+#define TIFFmax(A,B) ((A)>(B)?(A):(B))
+#define TIFFmin(A,B) ((A)<(B)?(A):(B))
+
+#define TIFFArrayCount(a) (sizeof (a) / sizeof ((a)[0]))
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+extern int _TIFFgetMode(const char* mode, const char* module);
+extern int _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoTileEncode(TIFF*, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s);
+extern int _TIFFNoTileDecode(TIFF*, uint8* pp, tmsize_t cc, uint16 s);
+extern void _TIFFNoPostDecode(TIFF* tif, uint8* buf, tmsize_t cc);
+extern int _TIFFNoPreCode(TIFF* tif, uint16 s);
+extern int _TIFFNoSeek(TIFF* tif, uint32 off);
+extern void _TIFFSwab16BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern void _TIFFSwab24BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern void _TIFFSwab32BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern void _TIFFSwab64BitData(TIFF* tif, uint8* buf, tmsize_t cc);
+extern int TIFFFlushData1(TIFF* tif);
+extern int TIFFDefaultDirectory(TIFF* tif);
+extern void _TIFFSetDefaultCompressionState(TIFF* tif);
+extern int _TIFFRewriteField(TIFF *, uint16, TIFFDataType, tmsize_t, void *);
+extern int TIFFSetCompressionScheme(TIFF* tif, int scheme);
+extern int TIFFSetDefaultCompressionState(TIFF* tif);
+extern uint32 _TIFFDefaultStripSize(TIFF* tif, uint32 s);
+extern void _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th);
+extern int _TIFFDataSize(TIFFDataType type);
+
+extern void _TIFFsetByteArray(void**, void*, uint32);
+extern void _TIFFsetString(char**, char*);
+extern void _TIFFsetShortArray(uint16**, uint16*, uint32);
+extern void _TIFFsetLongArray(uint32**, uint32*, uint32);
+extern void _TIFFsetFloatArray(float**, float*, uint32);
+extern void _TIFFsetDoubleArray(double**, double*, uint32);
+
+extern void _TIFFprintAscii(FILE*, const char*);
+extern void _TIFFprintAsciiTag(FILE*, const char*, const char*);
+
+extern TIFFErrorHandler _TIFFwarningHandler;
+extern TIFFErrorHandler _TIFFerrorHandler;
+extern TIFFErrorHandlerExt _TIFFwarningHandlerExt;
+extern TIFFErrorHandlerExt _TIFFerrorHandlerExt;
+
+extern uint32 _TIFFMultiply32(TIFF*, uint32, uint32, const char*);
+extern uint64 _TIFFMultiply64(TIFF*, uint64, uint64, const char*);
+extern void* _TIFFCheckMalloc(TIFF*, tmsize_t, tmsize_t, const char*);
+extern void* _TIFFCheckRealloc(TIFF*, void*, tmsize_t, tmsize_t, const char*);
+
+extern double _TIFFUInt64ToDouble(uint64);
+extern float _TIFFUInt64ToFloat(uint64);
+
+extern int TIFFInitDumpMode(TIFF*, int);
+#ifdef PACKBITS_SUPPORT
+extern int TIFFInitPackBits(TIFF*, int);
+#endif
+#ifdef CCITT_SUPPORT
+extern int TIFFInitCCITTRLE(TIFF*, int), TIFFInitCCITTRLEW(TIFF*, int);
+extern int TIFFInitCCITTFax3(TIFF*, int), TIFFInitCCITTFax4(TIFF*, int);
+#endif
+#ifdef THUNDER_SUPPORT
+extern int TIFFInitThunderScan(TIFF*, int);
+#endif
+#ifdef NEXT_SUPPORT
+extern int TIFFInitNeXT(TIFF*, int);
+#endif
+#ifdef LZW_SUPPORT
+extern int TIFFInitLZW(TIFF*, int);
+#endif
+#ifdef OJPEG_SUPPORT
+extern int TIFFInitOJPEG(TIFF*, int);
+#endif
+#ifdef JPEG_SUPPORT
+extern int TIFFInitJPEG(TIFF*, int);
+#endif
+#ifdef JBIG_SUPPORT
+extern int TIFFInitJBIG(TIFF*, int);
+#endif
+#ifdef ZIP_SUPPORT
+extern int TIFFInitZIP(TIFF*, int);
+#endif
+#ifdef PIXARLOG_SUPPORT
+extern int TIFFInitPixarLog(TIFF*, int);
+#endif
+#ifdef LOGLUV_SUPPORT
+extern int TIFFInitSGILog(TIFF*, int);
+#endif
+#ifdef LZMA_SUPPORT
+extern int TIFFInitLZMA(TIFF*, int);
+#endif
+#ifdef VMS
+extern const TIFFCodec _TIFFBuiltinCODECS[];
+#else
+extern TIFFCodec _TIFFBuiltinCODECS[];
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+#endif /* _TIFFIOP_ */
+
+/* vim: set ts=8 sts=8 sw=8 noet: */
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/tiffvers.h b/core/src/fxcodec/fx_tiff/tiff_v403/tiffvers.h
new file mode 100644
index 0000000000..40edc813d5
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/tiffvers.h
@@ -0,0 +1,9 @@
+#define TIFFLIB_VERSION_STR "LIBTIFF, Version 4.0.3\nCopyright (c) 1988-1996 Sam Leffler\nCopyright (c) 1991-1996 Silicon Graphics, Inc."
+/*
+ * This define can be used in code that requires
+ * compilation-related definitions specific to a
+ * version or versions of the library. Runtime
+ * version checking should be done based on the
+ * string returned by TIFFGetVersion.
+ */
+#define TIFFLIB_VERSION 20120922
diff --git a/core/src/fxcodec/fx_tiff/tiff_v403/uvcode.h b/core/src/fxcodec/fx_tiff/tiff_v403/uvcode.h
new file mode 100644
index 0000000000..50f11d7e0a
--- /dev/null
+++ b/core/src/fxcodec/fx_tiff/tiff_v403/uvcode.h
@@ -0,0 +1,180 @@
+/* Version 1.0 generated April 7, 1997 by Greg Ward Larson, SGI */
+#define UV_SQSIZ (float)0.003500
+#define UV_NDIVS 16289
+#define UV_VSTART (float)0.016940
+#define UV_NVS 163
+static struct {
+ float ustart;
+ short nus, ncum;
+} uv_row[UV_NVS] = {
+ { (float)0.247663, 4, 0 },
+ { (float)0.243779, 6, 4 },
+ { (float)0.241684, 7, 10 },
+ { (float)0.237874, 9, 17 },
+ { (float)0.235906, 10, 26 },
+ { (float)0.232153, 12, 36 },
+ { (float)0.228352, 14, 48 },
+ { (float)0.226259, 15, 62 },
+ { (float)0.222371, 17, 77 },
+ { (float)0.220410, 18, 94 },
+ { (float)0.214710, 21, 112 },
+ { (float)0.212714, 22, 133 },
+ { (float)0.210721, 23, 155 },
+ { (float)0.204976, 26, 178 },
+ { (float)0.202986, 27, 204 },
+ { (float)0.199245, 29, 231 },
+ { (float)0.195525, 31, 260 },
+ { (float)0.193560, 32, 291 },
+ { (float)0.189878, 34, 323 },
+ { (float)0.186216, 36, 357 },
+ { (float)0.186216, 36, 393 },
+ { (float)0.182592, 38, 429 },
+ { (float)0.179003, 40, 467 },
+ { (float)0.175466, 42, 507 },
+ { (float)0.172001, 44, 549 },
+ { (float)0.172001, 44, 593 },
+ { (float)0.168612, 46, 637 },
+ { (float)0.168612, 46, 683 },
+ { (float)0.163575, 49, 729 },
+ { (float)0.158642, 52, 778 },
+ { (float)0.158642, 52, 830 },
+ { (float)0.158642, 52, 882 },
+ { (float)0.153815, 55, 934 },
+ { (float)0.153815, 55, 989 },
+ { (float)0.149097, 58, 1044 },
+ { (float)0.149097, 58, 1102 },
+ { (float)0.142746, 62, 1160 },
+ { (float)0.142746, 62, 1222 },
+ { (float)0.142746, 62, 1284 },
+ { (float)0.138270, 65, 1346 },
+ { (float)0.138270, 65, 1411 },
+ { (float)0.138270, 65, 1476 },
+ { (float)0.132166, 69, 1541 },
+ { (float)0.132166, 69, 1610 },
+ { (float)0.126204, 73, 1679 },
+ { (float)0.126204, 73, 1752 },
+ { (float)0.126204, 73, 1825 },
+ { (float)0.120381, 77, 1898 },
+ { (float)0.120381, 77, 1975 },
+ { (float)0.120381, 77, 2052 },
+ { (float)0.120381, 77, 2129 },
+ { (float)0.112962, 82, 2206 },
+ { (float)0.112962, 82, 2288 },
+ { (float)0.112962, 82, 2370 },
+ { (float)0.107450, 86, 2452 },
+ { (float)0.107450, 86, 2538 },
+ { (float)0.107450, 86, 2624 },
+ { (float)0.107450, 86, 2710 },
+ { (float)0.100343, 91, 2796 },
+ { (float)0.100343, 91, 2887 },
+ { (float)0.100343, 91, 2978 },
+ { (float)0.095126, 95, 3069 },
+ { (float)0.095126, 95, 3164 },
+ { (float)0.095126, 95, 3259 },
+ { (float)0.095126, 95, 3354 },
+ { (float)0.088276, 100, 3449 },
+ { (float)0.088276, 100, 3549 },
+ { (float)0.088276, 100, 3649 },
+ { (float)0.088276, 100, 3749 },
+ { (float)0.081523, 105, 3849 },
+ { (float)0.081523, 105, 3954 },
+ { (float)0.081523, 105, 4059 },
+ { (float)0.081523, 105, 4164 },
+ { (float)0.074861, 110, 4269 },
+ { (float)0.074861, 110, 4379 },
+ { (float)0.074861, 110, 4489 },
+ { (float)0.074861, 110, 4599 },
+ { (float)0.068290, 115, 4709 },
+ { (float)0.068290, 115, 4824 },
+ { (float)0.068290, 115, 4939 },
+ { (float)0.068290, 115, 5054 },
+ { (float)0.063573, 119, 5169 },
+ { (float)0.063573, 119, 5288 },
+ { (float)0.063573, 119, 5407 },
+ { (float)0.063573, 119, 5526 },
+ { (float)0.057219, 124, 5645 },
+ { (float)0.057219, 124, 5769 },
+ { (float)0.057219, 124, 5893 },
+ { (float)0.057219, 124, 6017 },
+ { (float)0.050985, 129, 6141 },
+ { (float)0.050985, 129, 6270 },
+ { (float)0.050985, 129, 6399 },
+ { (float)0.050985, 129, 6528 },
+ { (float)0.050985, 129, 6657 },
+ { (float)0.044859, 134, 6786 },
+ { (float)0.044859, 134, 6920 },
+ { (float)0.044859, 134, 7054 },
+ { (float)0.044859, 134, 7188 },
+ { (float)0.040571, 138, 7322 },
+ { (float)0.040571, 138, 7460 },
+ { (float)0.040571, 138, 7598 },
+ { (float)0.040571, 138, 7736 },
+ { (float)0.036339, 142, 7874 },
+ { (float)0.036339, 142, 8016 },
+ { (float)0.036339, 142, 8158 },
+ { (float)0.036339, 142, 8300 },
+ { (float)0.032139, 146, 8442 },
+ { (float)0.032139, 146, 8588 },
+ { (float)0.032139, 146, 8734 },
+ { (float)0.032139, 146, 8880 },
+ { (float)0.027947, 150, 9026 },
+ { (float)0.027947, 150, 9176 },
+ { (float)0.027947, 150, 9326 },
+ { (float)0.023739, 154, 9476 },
+ { (float)0.023739, 154, 9630 },
+ { (float)0.023739, 154, 9784 },
+ { (float)0.023739, 154, 9938 },
+ { (float)0.019504, 158, 10092 },
+ { (float)0.019504, 158, 10250 },
+ { (float)0.019504, 158, 10408 },
+ { (float)0.016976, 161, 10566 },
+ { (float)0.016976, 161, 10727 },
+ { (float)0.016976, 161, 10888 },
+ { (float)0.016976, 161, 11049 },
+ { (float)0.012639, 165, 11210 },
+ { (float)0.012639, 165, 11375 },
+ { (float)0.012639, 165, 11540 },
+ { (float)0.009991, 168, 11705 },
+ { (float)0.009991, 168, 11873 },
+ { (float)0.009991, 168, 12041 },
+ { (float)0.009016, 170, 12209 },
+ { (float)0.009016, 170, 12379 },
+ { (float)0.009016, 170, 12549 },
+ { (float)0.006217, 173, 12719 },
+ { (float)0.006217, 173, 12892 },
+ { (float)0.005097, 175, 13065 },
+ { (float)0.005097, 175, 13240 },
+ { (float)0.005097, 175, 13415 },
+ { (float)0.003909, 177, 13590 },
+ { (float)0.003909, 177, 13767 },
+ { (float)0.002340, 177, 13944 },
+ { (float)0.002389, 170, 14121 },
+ { (float)0.001068, 164, 14291 },
+ { (float)0.001653, 157, 14455 },
+ { (float)0.000717, 150, 14612 },
+ { (float)0.001614, 143, 14762 },
+ { (float)0.000270, 136, 14905 },
+ { (float)0.000484, 129, 15041 },
+ { (float)0.001103, 123, 15170 },
+ { (float)0.001242, 115, 15293 },
+ { (float)0.001188, 109, 15408 },
+ { (float)0.001011, 103, 15517 },
+ { (float)0.000709, 97, 15620 },
+ { (float)0.000301, 89, 15717 },
+ { (float)0.002416, 82, 15806 },
+ { (float)0.003251, 76, 15888 },
+ { (float)0.003246, 69, 15964 },
+ { (float)0.004141, 62, 16033 },
+ { (float)0.005963, 55, 16095 },
+ { (float)0.008839, 47, 16150 },
+ { (float)0.010490, 40, 16197 },
+ { (float)0.016994, 31, 16237 },
+ { (float)0.023659, 21, 16268 },
+};
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 8
+ * fill-column: 78
+ * End:
+ */
diff --git a/core/src/fxcodec/lbmp/fx_bmp.cpp b/core/src/fxcodec/lbmp/fx_bmp.cpp
new file mode 100644
index 0000000000..4c6eb61757
--- /dev/null
+++ b/core/src/fxcodec/lbmp/fx_bmp.cpp
@@ -0,0 +1,917 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fx_bmp.h"
+FX_DWORD _GetDWord_LSBFirst(FX_LPBYTE p)
+{
+ return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+FX_WORD _GetWord_LSBFirst(FX_LPBYTE p)
+{
+ return p[0] | (p[1] << 8);
+}
+void _SetDWord_LSBFirst(FX_LPBYTE p, FX_DWORD v)
+{
+ p[0] = (FX_BYTE)v;
+ p[1] = (FX_BYTE)(v >> 8);
+ p[2] = (FX_BYTE)(v >> 16);
+ p[3] = (FX_BYTE)(v >> 24);
+}
+void _SetWord_LSBFirst(FX_LPBYTE p, FX_WORD v)
+{
+ p[0] = (FX_BYTE)v;
+ p[1] = (FX_BYTE)(v >> 8);
+}
+void _bmp_error(bmp_decompress_struct_p bmp_ptr, FX_LPCSTR err_msg)
+{
+ if(bmp_ptr != NULL && bmp_ptr->_bmp_error_fn != NULL) {
+ bmp_ptr->_bmp_error_fn(bmp_ptr, err_msg);
+ }
+}
+bmp_decompress_struct_p _bmp_create_decompress()
+{
+ bmp_decompress_struct_p bmp_ptr = FX_Alloc(bmp_decompress_struct, 1);
+ if(bmp_ptr == NULL) {
+ return NULL;
+ }
+ FXSYS_memset32(bmp_ptr, 0, sizeof(bmp_decompress_struct));
+ bmp_ptr->decode_status = BMP_D_STATUS_HEADER;
+ bmp_ptr->bmp_header_ptr = FX_Alloc(BmpFileHeader, 1);
+ return bmp_ptr;
+}
+void _bmp_destroy_decompress(bmp_decompress_struct_pp bmp_ptr_ptr)
+{
+ if(bmp_ptr_ptr == NULL || *bmp_ptr_ptr == NULL) {
+ return;
+ }
+ bmp_decompress_struct_p bmp_ptr = *bmp_ptr_ptr;
+ *bmp_ptr_ptr = NULL;
+ if(bmp_ptr->out_row_buffer != NULL) {
+ FX_Free(bmp_ptr->out_row_buffer);
+ }
+ if(bmp_ptr->pal_ptr != NULL) {
+ FX_Free(bmp_ptr->pal_ptr);
+ }
+ if(bmp_ptr->bmp_header_ptr != NULL) {
+ FX_Free(bmp_ptr->bmp_header_ptr);
+ }
+ FX_Free(bmp_ptr);
+}
+FX_INT32 _bmp_read_header(bmp_decompress_struct_p bmp_ptr)
+{
+ if(bmp_ptr == NULL) {
+ return 0;
+ }
+ FX_DWORD skip_size_org = bmp_ptr->skip_size;
+ if(bmp_ptr->decode_status == BMP_D_STATUS_HEADER) {
+ ASSERT(sizeof(BmpFileHeader) == 14);
+ BmpFileHeader* bmp_header_ptr = NULL;
+ if(_bmp_read_data(bmp_ptr, (FX_LPBYTE*)&bmp_header_ptr, 14) == NULL) {
+ return 2;
+ }
+ bmp_ptr->bmp_header_ptr->bfType = _GetWord_LSBFirst((FX_LPBYTE)&bmp_header_ptr->bfType);
+ bmp_ptr->bmp_header_ptr->bfOffBits = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_header_ptr->bfOffBits);
+ bmp_ptr->data_size = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_header_ptr->bfSize);
+ if(bmp_ptr->bmp_header_ptr->bfType != BMP_SIGNATURE) {
+ _bmp_error(bmp_ptr, "Not A Bmp Image");
+ return 0;
+ }
+ if(bmp_ptr->avail_in < sizeof(FX_DWORD)) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ bmp_ptr->img_ifh_size = _GetDWord_LSBFirst(bmp_ptr->next_in + bmp_ptr->skip_size);
+ bmp_ptr->pal_type = 0;
+ ASSERT(sizeof(BmpCoreHeader) == 12);
+ ASSERT(sizeof(BmpInfoHeader) == 40);
+ switch(bmp_ptr->img_ifh_size) {
+ case FX_MIN(12, sizeof(BmpCoreHeader)): {
+ bmp_ptr->pal_type = 1;
+ BmpCoreHeaderPtr bmp_core_header_ptr = NULL;
+ if(_bmp_read_data(bmp_ptr, (FX_LPBYTE*)&bmp_core_header_ptr, bmp_ptr->img_ifh_size) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ bmp_ptr->width = (FX_DWORD)_GetWord_LSBFirst((FX_LPBYTE)&bmp_core_header_ptr->bcWidth);
+ bmp_ptr->height = (FX_DWORD)_GetWord_LSBFirst((FX_LPBYTE)&bmp_core_header_ptr->bcHeight);
+ bmp_ptr->bitCounts = _GetWord_LSBFirst((FX_LPBYTE)&bmp_core_header_ptr->bcBitCount);
+ bmp_ptr->compress_flag = BMP_RGB;
+ bmp_ptr->imgTB_flag = FALSE;
+ }
+ break;
+ case FX_MIN(40, sizeof(BmpInfoHeader)): {
+ BmpInfoHeaderPtr bmp_info_header_ptr = NULL;
+ if(_bmp_read_data(bmp_ptr, (FX_LPBYTE*)&bmp_info_header_ptr, bmp_ptr->img_ifh_size) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ bmp_ptr->width = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biWidth);
+ bmp_ptr->height = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biHeight);
+ bmp_ptr->bitCounts = _GetWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biBitCount);
+ bmp_ptr->compress_flag = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biCompression);
+ bmp_ptr->color_used = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biClrUsed);
+ bmp_ptr->dpi_x = (FX_INT32)_GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biXPelsPerMeter);
+ bmp_ptr->dpi_y = (FX_INT32)_GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biYPelsPerMeter);
+ if(bmp_ptr->height < 0) {
+ bmp_ptr->height = -bmp_ptr->height;
+ bmp_ptr->imgTB_flag = TRUE;
+ }
+ }
+ break;
+ default: {
+ if(bmp_ptr->img_ifh_size > FX_MIN(40, sizeof(BmpInfoHeader))) {
+ BmpInfoHeaderPtr bmp_info_header_ptr = NULL;
+ if(_bmp_read_data(bmp_ptr, (FX_LPBYTE*)&bmp_info_header_ptr, bmp_ptr->img_ifh_size) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ FX_WORD biPlanes;
+ bmp_ptr->width = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biWidth);
+ bmp_ptr->height = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biHeight);
+ bmp_ptr->bitCounts = _GetWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biBitCount);
+ bmp_ptr->compress_flag = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biCompression);
+ bmp_ptr->color_used = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biClrUsed);
+ biPlanes = _GetWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biPlanes);
+ bmp_ptr->dpi_x = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biXPelsPerMeter);
+ bmp_ptr->dpi_y = _GetDWord_LSBFirst((FX_LPBYTE)&bmp_info_header_ptr->biYPelsPerMeter);
+ if(bmp_ptr->height < 0) {
+ bmp_ptr->height = -bmp_ptr->height;
+ bmp_ptr->imgTB_flag = TRUE;
+ }
+ if(bmp_ptr->compress_flag == BMP_RGB &&
+ biPlanes == 1 &&
+ bmp_ptr->color_used == 0) {
+ break;
+ }
+ }
+ _bmp_error(bmp_ptr, "Unsupported Bmp File");
+ return 0;
+ }
+ }
+ ASSERT(bmp_ptr->width > 0);
+ ASSERT(bmp_ptr->compress_flag <= BMP_BITFIELDS);
+ switch(bmp_ptr->bitCounts) {
+ case 1:
+ case 4:
+ case 8:
+ case 16:
+ case 24: {
+ if(bmp_ptr->color_used > ((FX_DWORD)1) << bmp_ptr->bitCounts) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ }
+ case 32: {
+ if(bmp_ptr->width <= 0 || bmp_ptr->compress_flag > BMP_BITFIELDS) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ }
+ break;
+ default:
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ bmp_ptr->src_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, bmp_ptr->bitCounts);
+ switch(bmp_ptr->bitCounts) {
+ case 1:
+ case 4:
+ case 8:
+ bmp_ptr->out_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, 8);
+ bmp_ptr->components = 1;
+ break;
+ case 16:
+ case 24:
+ bmp_ptr->out_row_bytes = BMP_WIDTHBYTES(bmp_ptr->width, 24);
+ bmp_ptr->components = 3;
+ break;
+ case 32:
+ bmp_ptr->out_row_bytes = bmp_ptr->src_row_bytes;
+ bmp_ptr->components = 4;
+ break;
+ }
+ if(bmp_ptr->out_row_buffer != NULL) {
+ FX_Free(bmp_ptr->out_row_buffer);
+ bmp_ptr->out_row_buffer = NULL;
+ }
+ bmp_ptr->out_row_buffer = FX_Alloc(FX_BYTE, bmp_ptr->out_row_bytes);
+ BMP_PTR_NOT_NULL(bmp_ptr->out_row_buffer, bmp_ptr);
+ FXSYS_memset32(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes);
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_PAL);
+ }
+ if (bmp_ptr->decode_status == BMP_D_STATUS_PAL) {
+ skip_size_org = bmp_ptr->skip_size;
+#ifdef BMP_SUPPORT_BITFIELD
+ if(bmp_ptr->compress_flag == BMP_BITFIELDS) {
+ if(bmp_ptr->bitCounts != 16 && bmp_ptr->bitCounts != 32) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ FX_DWORD* mask;
+ if(_bmp_read_data(bmp_ptr, (FX_LPBYTE*)&mask, 3 * sizeof(FX_DWORD)) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ bmp_ptr->mask_red = _GetDWord_LSBFirst((FX_LPBYTE)&mask[0]);
+ bmp_ptr->mask_green = _GetDWord_LSBFirst((FX_LPBYTE)&mask[1]);
+ bmp_ptr->mask_blue = _GetDWord_LSBFirst((FX_LPBYTE)&mask[2]);
+ if(bmp_ptr->mask_red & bmp_ptr->mask_green ||
+ bmp_ptr->mask_red & bmp_ptr->mask_blue ||
+ bmp_ptr->mask_green & bmp_ptr->mask_blue) {
+ _bmp_error(bmp_ptr, "The Bitfield Bmp File Is Corrupt");
+ return 0;
+ }
+ if(bmp_ptr->bmp_header_ptr->bfOffBits < 26 + bmp_ptr->img_ifh_size) {
+ bmp_ptr->bmp_header_ptr->bfOffBits = 26 + bmp_ptr->img_ifh_size;
+ }
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA_PRE);
+ return 1;
+ } else if(bmp_ptr->bitCounts == 16) {
+ bmp_ptr->mask_red = 0x7C00;
+ bmp_ptr->mask_green = 0x03E0;
+ bmp_ptr->mask_blue = 0x001F;
+ }
+#else
+ if(bmp_ptr->compress_flag == BMP_BITFIELDS || bmp_ptr->bitCounts == 16) {
+ _bmp_error(bmp_ptr, "Unsupported Bitfield Bmp File");
+ return 0;
+ }
+#endif
+ bmp_ptr->pal_num = 0;
+ if(bmp_ptr->bitCounts < 16) {
+ bmp_ptr->pal_num = 1 << bmp_ptr->bitCounts;
+ if(bmp_ptr->color_used != 0) {
+ bmp_ptr->pal_num = bmp_ptr->color_used;
+ }
+ FX_LPBYTE src_pal_ptr = NULL;
+ FX_DWORD src_pal_size = bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4);
+ if(_bmp_read_data(bmp_ptr, (FX_LPBYTE*)&src_pal_ptr, src_pal_size) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ if(bmp_ptr->pal_ptr != NULL) {
+ FX_Free(bmp_ptr->pal_ptr);
+ bmp_ptr->pal_ptr = NULL;
+ }
+ bmp_ptr->pal_ptr = FX_Alloc(FX_DWORD, bmp_ptr->pal_num);
+ BMP_PTR_NOT_NULL(bmp_ptr->pal_ptr, bmp_ptr);
+ FX_INT32 src_pal_index = 0;
+ if(bmp_ptr->pal_type == BMP_PAL_OLD) {
+ while(src_pal_index < bmp_ptr->pal_num) {
+ bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE(0x00, src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]);
+ src_pal_ptr += 3;
+ }
+ } else {
+ while(src_pal_index < bmp_ptr->pal_num) {
+ bmp_ptr->pal_ptr[src_pal_index++] = BMP_PAL_ENCODE(src_pal_ptr[3], src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]);
+ src_pal_ptr += 4;
+ }
+ }
+ }
+ if(bmp_ptr->bmp_header_ptr->bfOffBits < 14 + bmp_ptr->img_ifh_size + bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4)) {
+ bmp_ptr->bmp_header_ptr->bfOffBits = 14 + bmp_ptr->img_ifh_size + bmp_ptr->pal_num * (bmp_ptr->pal_type ? 3 : 4);
+ }
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA_PRE);
+ }
+ return 1;
+}
+FX_INT32 _bmp_decode_image(bmp_decompress_struct_p bmp_ptr)
+{
+ if(bmp_ptr->decode_status == BMP_D_STATUS_DATA_PRE) {
+ bmp_ptr->avail_in = 0;
+ if(!bmp_ptr->_bmp_get_data_position_fn(bmp_ptr, bmp_ptr->bmp_header_ptr->bfOffBits)) {
+ bmp_ptr->decode_status = BMP_D_STATUS_TAIL;
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt, Unexpected Stream Offset");
+ return 0;
+ }
+ bmp_ptr->row_num = 0;
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA);
+ }
+ if(bmp_ptr->decode_status == BMP_D_STATUS_DATA) {
+ switch(bmp_ptr->compress_flag) {
+ case BMP_RGB:
+ case BMP_BITFIELDS:
+ return _bmp_decode_rgb(bmp_ptr);
+ case BMP_RLE8:
+ return _bmp_decode_rle8(bmp_ptr);
+ case BMP_RLE4:
+ return _bmp_decode_rle4(bmp_ptr);
+ }
+ }
+ _bmp_error(bmp_ptr, "Any Uncontrol Error");
+ return 0;
+}
+FX_INT32 _bmp_decode_rgb(bmp_decompress_struct_p bmp_ptr)
+{
+ FX_LPBYTE row_buf = bmp_ptr->out_row_buffer;
+ FX_LPBYTE des_buf = NULL;
+ while (bmp_ptr->row_num < bmp_ptr->height) {
+ if(_bmp_read_data(bmp_ptr, &des_buf, bmp_ptr->src_row_bytes) == NULL) {
+ return 2;
+ }
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA);
+ switch(bmp_ptr->bitCounts) {
+ case 1: {
+ for (FX_INT32 col = 0; col < bmp_ptr->width; col++) {
+ *row_buf++ = des_buf[col >> 3] & (0x80 >> (col % 8)) ? 0x01 : 0x00;
+ }
+ }
+ break;
+ case 4: {
+ for (FX_INT32 col = 0; col < bmp_ptr->width; col++) {
+ *row_buf++ = (col & 0x01) ?
+ (des_buf[col >> 1] & 0x0F) :
+ ((des_buf[col >> 1] & 0xF0) >> 4);
+ }
+ }
+ break;
+#ifdef BMP_SUPPORT_BITFIELD
+ case 16: {
+ FX_WORD* buf = (FX_WORD*)des_buf;
+ FX_BYTE blue_bits = 0;
+ FX_BYTE green_bits = 0;
+ FX_BYTE red_bits = 0;
+ for(FX_INT32 i = 0; i < 16; i++) {
+ if((bmp_ptr->mask_blue >> i) & 0x01) {
+ blue_bits++;
+ }
+ if((bmp_ptr->mask_green >> i) & 0x01) {
+ green_bits++;
+ }
+ if((bmp_ptr->mask_red >> i) & 0x01) {
+ red_bits++;
+ }
+ }
+ green_bits += blue_bits;
+ red_bits += green_bits;
+ blue_bits = 8 - blue_bits;
+ green_bits -= 8;
+ red_bits -= 8;
+ for (FX_INT32 col = 0; col < bmp_ptr->width; col++) {
+ *buf = _GetWord_LSBFirst((FX_LPBYTE)buf);
+ *row_buf++ = (FX_BYTE)((*buf & bmp_ptr->mask_blue) << blue_bits);
+ *row_buf++ = (FX_BYTE)((*buf & bmp_ptr->mask_green) >> green_bits);
+ *row_buf++ = (FX_BYTE)((*buf++ & bmp_ptr->mask_red) >> red_bits);
+ }
+ }
+ break;
+#endif
+ case 8:
+ case 24:
+ case 32:
+ FXSYS_memcpy32(bmp_ptr->out_row_buffer, des_buf, bmp_ptr->src_row_bytes);
+ break;
+ }
+ row_buf = bmp_ptr->out_row_buffer;
+ bmp_ptr->_bmp_get_row_fn(bmp_ptr,
+ bmp_ptr->imgTB_flag ? bmp_ptr->row_num++ : (bmp_ptr->height - 1 - bmp_ptr->row_num++),
+ bmp_ptr->out_row_buffer);
+ }
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL);
+ return 1;
+}
+FX_INT32 _bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr)
+{
+ FX_LPBYTE first_byte_ptr = NULL;
+ FX_LPBYTE second_byte_ptr = NULL;
+ bmp_ptr->col_num = 0;
+ while(TRUE) {
+ FX_DWORD skip_size_org = bmp_ptr->skip_size;
+ if(_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) {
+ return 2;
+ }
+ switch(*first_byte_ptr) {
+ case RLE_MARKER: {
+ if(_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ switch(*first_byte_ptr) {
+ case RLE_EOL: {
+ if(bmp_ptr->row_num >= bmp_ptr->height) {
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL);
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ bmp_ptr->_bmp_get_row_fn(bmp_ptr,
+ bmp_ptr->imgTB_flag ? bmp_ptr->row_num++ : (bmp_ptr->height - 1 - bmp_ptr->row_num++),
+ bmp_ptr->out_row_buffer);
+ bmp_ptr->col_num = 0;
+ FXSYS_memset32(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes);
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA);
+ continue;
+ }
+ case RLE_EOI: {
+ if(bmp_ptr->row_num < bmp_ptr->height) {
+ bmp_ptr->_bmp_get_row_fn(bmp_ptr,
+ bmp_ptr->imgTB_flag ? bmp_ptr->row_num++ : (bmp_ptr->height - 1 - bmp_ptr->row_num++),
+ bmp_ptr->out_row_buffer);
+ }
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL);
+ return 1;
+ }
+ case RLE_DELTA: {
+ FX_LPBYTE delta_ptr;
+ if(_bmp_read_data(bmp_ptr, &delta_ptr, 2) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ bmp_ptr->col_num += (FX_INT32)delta_ptr[0];
+ FX_INT32 bmp_row_num_next = bmp_ptr->row_num + (FX_INT32)delta_ptr[1];
+ if(bmp_ptr->col_num >= bmp_ptr->out_row_bytes || bmp_row_num_next >= bmp_ptr->height) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt Or Not Supported");
+ return 0;
+ }
+ while(bmp_ptr->row_num < bmp_row_num_next) {
+ FXSYS_memset32(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes);
+ bmp_ptr->_bmp_get_row_fn(bmp_ptr,
+ bmp_ptr->imgTB_flag ? bmp_ptr->row_num++ : (bmp_ptr->height - 1 - bmp_ptr->row_num++),
+ bmp_ptr->out_row_buffer);
+ }
+ }
+ break;
+ default: {
+ if((FX_INT32)(*first_byte_ptr) > bmp_ptr->src_row_bytes - bmp_ptr->col_num) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ if(_bmp_read_data(bmp_ptr, &second_byte_ptr,
+ *first_byte_ptr & 1 ? *first_byte_ptr + 1 : *first_byte_ptr) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ FXSYS_memcpy32(bmp_ptr->out_row_buffer + bmp_ptr->col_num, second_byte_ptr, *first_byte_ptr);
+ bmp_ptr->col_num += (FX_INT32)(*first_byte_ptr);
+ }
+ }
+ }
+ break;
+ default: {
+ if(_bmp_read_data(bmp_ptr, &second_byte_ptr, 1) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ if((FX_INT32)(*first_byte_ptr) > bmp_ptr->src_row_bytes - bmp_ptr->col_num) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ FXSYS_memset8(bmp_ptr->out_row_buffer + bmp_ptr->col_num, *second_byte_ptr, *first_byte_ptr);
+ bmp_ptr->col_num += (FX_INT32)(*first_byte_ptr);
+ }
+ }
+ }
+ _bmp_error(bmp_ptr, "Any Uncontrol Error");
+ return 0;
+}
+FX_INT32 _bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr)
+{
+ FX_LPBYTE first_byte_ptr = NULL;
+ FX_LPBYTE second_byte_ptr = NULL;
+ bmp_ptr->col_num = 0;
+ while (TRUE) {
+ FX_DWORD skip_size_org = bmp_ptr->skip_size;
+ if(_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) {
+ return 2;
+ }
+ switch(*first_byte_ptr) {
+ case RLE_MARKER: {
+ if(_bmp_read_data(bmp_ptr, &first_byte_ptr, 1) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ switch(*first_byte_ptr) {
+ case RLE_EOL: {
+ if(bmp_ptr->row_num >= bmp_ptr->height) {
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL);
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ bmp_ptr->_bmp_get_row_fn(bmp_ptr,
+ bmp_ptr->imgTB_flag ? bmp_ptr->row_num++ : (bmp_ptr->height - 1 - bmp_ptr->row_num++),
+ bmp_ptr->out_row_buffer);
+ bmp_ptr->col_num = 0;
+ FXSYS_memset32(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes);
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_DATA);
+ continue;
+ }
+ case RLE_EOI: {
+ if(bmp_ptr->row_num < bmp_ptr->height) {
+ bmp_ptr->_bmp_get_row_fn(bmp_ptr,
+ bmp_ptr->imgTB_flag ? bmp_ptr->row_num++ : (bmp_ptr->height - 1 - bmp_ptr->row_num++),
+ bmp_ptr->out_row_buffer);
+ }
+ _bmp_save_decoding_status(bmp_ptr, BMP_D_STATUS_TAIL);
+ return 1;
+ }
+ case RLE_DELTA: {
+ FX_LPBYTE delta_ptr;
+ if(_bmp_read_data(bmp_ptr, &delta_ptr, 2) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ bmp_ptr->col_num += (FX_INT32)delta_ptr[0];
+ FX_INT32 bmp_row_num_next = bmp_ptr->row_num + (FX_INT32)delta_ptr[1];
+ if(bmp_ptr->col_num >= bmp_ptr->out_row_bytes || bmp_row_num_next >= bmp_ptr->height) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt Or Not Supported");
+ return 0;
+ }
+ while(bmp_ptr->row_num < bmp_row_num_next) {
+ FXSYS_memset32(bmp_ptr->out_row_buffer, 0, bmp_ptr->out_row_bytes);
+ bmp_ptr->_bmp_get_row_fn(bmp_ptr,
+ bmp_ptr->imgTB_flag ? bmp_ptr->row_num++ : (bmp_ptr->height - 1 - bmp_ptr->row_num++),
+ bmp_ptr->out_row_buffer);
+ }
+ }
+ break;
+ default: {
+ FX_BYTE size = (FX_BYTE)(((FX_WORD)(*first_byte_ptr) + 1) >> 1);
+ if((FX_INT32)*first_byte_ptr >= bmp_ptr->out_row_bytes - bmp_ptr->col_num) {
+ if(size + (bmp_ptr->col_num >> 1) > bmp_ptr->src_row_bytes) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ *first_byte_ptr = bmp_ptr->out_row_bytes - bmp_ptr->col_num - 1;
+ }
+ if(_bmp_read_data(bmp_ptr, &second_byte_ptr, size & 1 ? size + 1 : size) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ for (FX_BYTE i = 0; i < *first_byte_ptr; i++) {
+ if(i & 0x01) {
+ *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = (*second_byte_ptr++ & 0x0F);
+ } else {
+ *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = ((*second_byte_ptr & 0xF0) >> 4);
+ }
+ }
+ }
+ }
+ }
+ break;
+ default: {
+ if(_bmp_read_data(bmp_ptr, &second_byte_ptr, 1) == NULL) {
+ bmp_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ if((FX_INT32)*first_byte_ptr > bmp_ptr->out_row_bytes - bmp_ptr->col_num) {
+ FX_BYTE size = (FX_BYTE)(((FX_WORD)(*first_byte_ptr) + 1) >> 1);
+ if(size + (bmp_ptr->col_num >> 1) > bmp_ptr->src_row_bytes) {
+ _bmp_error(bmp_ptr, "The Bmp File Is Corrupt");
+ return 0;
+ }
+ *first_byte_ptr = bmp_ptr->out_row_bytes - bmp_ptr->col_num - 1;
+ }
+ for (FX_BYTE i = 0; i < *first_byte_ptr; i++) {
+ if(i & 0x01) {
+ *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = (*second_byte_ptr & 0x0F);
+ } else {
+ *(bmp_ptr->out_row_buffer + bmp_ptr->col_num++) = ((*second_byte_ptr & 0xF0) >> 4);
+ }
+ }
+ }
+ }
+ }
+ _bmp_error(bmp_ptr, "Any Uncontrol Error");
+ return 0;
+}
+FX_LPBYTE _bmp_read_data(bmp_decompress_struct_p bmp_ptr, FX_LPBYTE* des_buf_pp, FX_DWORD data_size)
+{
+ if(bmp_ptr == NULL ||
+ bmp_ptr->avail_in < bmp_ptr->skip_size + data_size) {
+ return NULL;
+ }
+ *des_buf_pp = bmp_ptr->next_in + bmp_ptr->skip_size;
+ bmp_ptr->skip_size += data_size;
+ return *des_buf_pp;
+}
+void _bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, FX_INT32 status)
+{
+ bmp_ptr->decode_status = status;
+ bmp_ptr->next_in += bmp_ptr->skip_size;
+ bmp_ptr->avail_in -= bmp_ptr->skip_size;
+ bmp_ptr->skip_size = 0;
+}
+void _bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, FX_LPBYTE src_buf, FX_DWORD src_size)
+{
+ bmp_ptr->next_in = src_buf;
+ bmp_ptr->avail_in = src_size;
+ bmp_ptr->skip_size = 0;
+}
+FX_DWORD _bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, FX_LPBYTE* avial_buf_ptr)
+{
+ if(avial_buf_ptr != NULL) {
+ *avial_buf_ptr = NULL;
+ if(bmp_ptr->avail_in > 0) {
+ *avial_buf_ptr = bmp_ptr->next_in;
+ }
+ }
+ return bmp_ptr->avail_in;
+}
+bmp_compress_struct_p _bmp_create_compress()
+{
+ bmp_compress_struct_p bmp_ptr;
+ bmp_ptr = FX_Alloc(bmp_compress_struct, 1);
+ if (bmp_ptr) {
+ FXSYS_memset32(bmp_ptr, 0, sizeof(bmp_compress_struct));
+ }
+ return bmp_ptr;
+}
+void _bmp_destroy_compress(bmp_compress_struct_p bmp_ptr)
+{
+ if (bmp_ptr) {
+ if (bmp_ptr->src_free && bmp_ptr->src_buf) {
+ FX_Free(bmp_ptr->src_buf);
+ }
+ FX_Free(bmp_ptr);
+ }
+}
+static void WriteFileHeader(BmpFileHeaderPtr head_ptr, FX_LPBYTE dst_buf)
+{
+ FX_DWORD offset;
+ offset = 0;
+ _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfType);
+ offset += 2;
+ _SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfSize);
+ offset += 4;
+ _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved1);
+ offset += 2;
+ _SetWord_LSBFirst(&dst_buf[offset], head_ptr->bfReserved2);
+ offset += 2;
+ _SetDWord_LSBFirst(&dst_buf[offset], head_ptr->bfOffBits);
+ offset += 4;
+}
+static void WriteInfoHeader(BmpInfoHeaderPtr info_head_ptr, FX_LPBYTE dst_buf)
+{
+ FX_DWORD offset;
+ offset = sizeof(BmpFileHeader);
+ _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSize);
+ offset += 4;
+ _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biWidth);
+ offset += 4;
+ _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biHeight);
+ offset += 4;
+ _SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biPlanes);
+ offset += 2;
+ _SetWord_LSBFirst(&dst_buf[offset], info_head_ptr->biBitCount);
+ offset += 2;
+ _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biCompression);
+ offset += 4;
+ _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biSizeImage);
+ offset += 4;
+ _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biXPelsPerMeter);
+ offset += 4;
+ _SetDWord_LSBFirst(&dst_buf[offset], (FX_DWORD)info_head_ptr->biYPelsPerMeter);
+ offset += 4;
+ _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrUsed);
+ offset += 4;
+ _SetDWord_LSBFirst(&dst_buf[offset], info_head_ptr->biClrImportant);
+ offset += 4;
+}
+#ifdef BMP_SUPPORT_BITFIELD
+static void _bmp_encode_bitfields(bmp_compress_struct_p bmp_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_size)
+{
+ if (bmp_ptr->info_header.biBitCount != 16 && bmp_ptr->info_header.biBitCount != 32) {
+ return;
+ }
+ FX_DWORD size, dst_pos, i;
+ size = bmp_ptr->src_pitch * bmp_ptr->src_row * bmp_ptr->info_header.biBitCount / 16;
+ dst_pos = bmp_ptr->file_header.bfOffBits;
+ dst_size += size;
+ dst_buf = FX_Realloc(FX_BYTE, dst_buf, dst_size);
+ if (dst_buf == NULL) {
+ return;
+ }
+ FXSYS_memset32(&dst_buf[dst_pos], 0, size);
+ FX_DWORD mask_red;
+ FX_DWORD mask_green;
+ FX_DWORD mask_blue;
+ mask_red = 0x7C00;
+ mask_green = 0x03E0;
+ mask_blue = 0x001F;
+ if (bmp_ptr->info_header.biCompression == BMP_BITFIELDS) {
+ if (bmp_ptr->bit_type == BMP_BIT_565) {
+ mask_red = 0xF800;
+ mask_green = 0x07E0;
+ mask_blue = 0x001F;
+ }
+ if (bmp_ptr->info_header.biBitCount == 32) {
+ mask_red = 0xFF0000;
+ mask_green = 0x00FF00;
+ mask_blue = 0x0000FF;
+ }
+ _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_red);
+ dst_pos += 4;
+ _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_green);
+ dst_pos += 4;
+ _SetDWord_LSBFirst(&dst_buf[dst_pos], mask_blue);
+ dst_pos += 4;
+ bmp_ptr->file_header.bfOffBits = dst_pos;
+ }
+ FX_BYTE blue_bits = 0;
+ FX_BYTE green_bits = 0;
+ FX_BYTE red_bits = 0;
+ for(i = 0; i < bmp_ptr->info_header.biBitCount; i++) {
+ if((mask_blue >> i) & 0x01) {
+ blue_bits++;
+ }
+ if((mask_green >> i) & 0x01) {
+ green_bits++;
+ }
+ if((mask_red >> i) & 0x01) {
+ red_bits++;
+ }
+ }
+ green_bits += blue_bits;
+ red_bits += green_bits;
+ blue_bits = 8 - blue_bits;
+ green_bits -= 8;
+ red_bits -= 8;
+ i = 0;
+ for (FX_INT32 row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--, i = 0) {
+ while (i < bmp_ptr->src_width * bmp_ptr->src_bpp / 8) {
+ FX_BYTE b = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++];
+ FX_BYTE g = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++];
+ FX_BYTE r = bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch + i++];
+ if (bmp_ptr->src_bpp == 32) {
+ i++;
+ }
+ FX_DWORD pix_val = 0;
+ pix_val |= (b >> blue_bits) & mask_blue;
+ pix_val |= (g << green_bits) & mask_green;
+ pix_val |= (r << red_bits) & mask_red;
+ if (bmp_ptr->info_header.biBitCount == 16) {
+ _SetWord_LSBFirst(&dst_buf[dst_pos], (FX_WORD)pix_val);
+ dst_pos += 2;
+ } else {
+ _SetDWord_LSBFirst(&dst_buf[dst_pos], pix_val);
+ dst_pos += 4;
+ }
+ }
+ }
+ dst_size = dst_pos;
+}
+#endif
+static void _bmp_encode_rgb(bmp_compress_struct_p bmp_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_size)
+{
+ if (bmp_ptr->info_header.biBitCount == 16) {
+#ifdef BMP_SUPPORT_BITFIELD
+ _bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size);
+#endif
+ return;
+ }
+ FX_DWORD size, dst_pos;
+ FX_DWORD dst_pitch = (bmp_ptr->src_width * bmp_ptr->info_header.biBitCount + 31) / 32 * 4;
+ size = dst_pitch * bmp_ptr->src_row;
+ dst_pos = bmp_ptr->file_header.bfOffBits;
+ dst_size += size;
+ dst_buf = FX_Realloc(FX_BYTE, dst_buf, dst_size);
+ if (dst_buf == NULL) {
+ return;
+ }
+ FXSYS_memset32(&dst_buf[dst_pos], 0, size);
+ for (FX_INT32 row_num = bmp_ptr->src_row - 1; row_num > -1; row_num--) {
+ FXSYS_memcpy32(&dst_buf[dst_pos], &bmp_ptr->src_buf[row_num * bmp_ptr->src_pitch], bmp_ptr->src_pitch);
+ dst_pos += dst_pitch;
+ }
+ dst_size = dst_pos;
+}
+static FX_BYTE _bmp_rle8_search(FX_LPCBYTE buf, FX_INT32 len)
+{
+ FX_BYTE num;
+ num = 1;
+ while (num < len) {
+ if (buf[num - 1] != buf[num] || num == 0xFF) {
+ break;
+ }
+ num++;
+ }
+ return num;
+}
+static void _bmp_encode_rle8(bmp_compress_struct_p bmp_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_size)
+{
+ FX_DWORD size, dst_pos, index;
+ FX_BYTE rle[2] = {0};
+ size = bmp_ptr->src_pitch * bmp_ptr->src_row * 2;
+ dst_pos = bmp_ptr->file_header.bfOffBits;
+ dst_size += size;
+ dst_buf = FX_Realloc(FX_BYTE, dst_buf, dst_size);
+ if (dst_buf == NULL) {
+ return;
+ }
+ FXSYS_memset32(&dst_buf[dst_pos], 0, size);
+ for (FX_INT32 row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1; ) {
+ index = row_num * bmp_ptr->src_pitch;
+ rle[0] = _bmp_rle8_search(&bmp_ptr->src_buf[index + i], size - index - i);
+ rle[1] = bmp_ptr->src_buf[index + i];
+ if (i + rle[0] >= (FX_INT32)bmp_ptr->src_pitch) {
+ rle[0] = FX_BYTE(bmp_ptr->src_pitch - i);
+ if (rle[0]) {
+ dst_buf[dst_pos++] = rle[0];
+ dst_buf[dst_pos++] = rle[1];
+ }
+ dst_buf[dst_pos++] = RLE_MARKER;
+ dst_buf[dst_pos++] = RLE_EOL;
+ i = 0;
+ row_num--;
+ } else {
+ i += rle[0];
+ dst_buf[dst_pos++] = rle[0];
+ dst_buf[dst_pos++] = rle[1];
+ }
+ }
+ dst_buf[dst_pos++] = RLE_MARKER;
+ dst_buf[dst_pos++] = RLE_EOI;
+ dst_size = dst_pos;
+}
+static FX_BYTE _bmp_rle4_search(FX_LPCBYTE buf, FX_INT32 len)
+{
+ FX_BYTE num;
+ num = 2;
+ while (num < len) {
+ if (buf[num - 2] != buf[num] || num == 0xFF) {
+ break;
+ }
+ num++;
+ }
+ return num;
+}
+static void _bmp_encode_rle4(bmp_compress_struct_p bmp_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_size)
+{
+ FX_DWORD size, dst_pos, index;
+ FX_BYTE rle[2] = {0};
+ size = bmp_ptr->src_pitch * bmp_ptr->src_row;
+ dst_pos = bmp_ptr->file_header.bfOffBits;
+ dst_size += size;
+ dst_buf = FX_Realloc(FX_BYTE, dst_buf, dst_size);
+ if (dst_buf == NULL) {
+ return;
+ }
+ FXSYS_memset32(&dst_buf[dst_pos], 0, size);
+ for (FX_INT32 row_num = bmp_ptr->src_row - 1, i = 0; row_num > -1; rle[1] = 0) {
+ index = row_num * bmp_ptr->src_pitch;
+ rle[0] = _bmp_rle4_search(&bmp_ptr->src_buf[index + i], size - index - i);
+ rle[1] |= (bmp_ptr->src_buf[index + i] & 0x0f) << 4;
+ rle[1] |= bmp_ptr->src_buf[index + i + 1] & 0x0f;
+ if (i + rle[0] >= (FX_INT32)bmp_ptr->src_pitch) {
+ rle[0] = FX_BYTE(bmp_ptr->src_pitch - i);
+ if (rle[0]) {
+ dst_buf[dst_pos++] = rle[0];
+ dst_buf[dst_pos++] = rle[1];
+ }
+ dst_buf[dst_pos++] = RLE_MARKER;
+ dst_buf[dst_pos++] = RLE_EOL;
+ i = 0;
+ row_num--;
+ } else {
+ i += rle[0];
+ dst_buf[dst_pos++] = rle[0];
+ dst_buf[dst_pos++] = rle[1];
+ }
+ }
+ dst_buf[dst_pos++] = RLE_MARKER;
+ dst_buf[dst_pos++] = RLE_EOI;
+ dst_size = dst_pos;
+}
+FX_BOOL _bmp_encode_image( bmp_compress_struct_p bmp_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_size )
+{
+ FX_DWORD head_size = sizeof(BmpFileHeader) + sizeof(BmpInfoHeader);
+ FX_DWORD pal_size = sizeof(FX_DWORD) * bmp_ptr->pal_num;
+ if (bmp_ptr->info_header.biClrUsed > 0 && bmp_ptr->info_header.biClrUsed < bmp_ptr->pal_num) {
+ pal_size = sizeof(FX_DWORD) * bmp_ptr->info_header.biClrUsed;
+ }
+ dst_size = head_size + sizeof(FX_DWORD) * bmp_ptr->pal_num;
+ dst_buf = FX_AllocNL(FX_BYTE, dst_size);
+ if (dst_buf == NULL) {
+ return FALSE;
+ }
+ FXSYS_memset32(dst_buf, 0, dst_size);
+ bmp_ptr->file_header.bfOffBits = head_size;
+ if (bmp_ptr->pal_ptr && pal_size) {
+ FXSYS_memcpy32(&dst_buf[head_size], bmp_ptr->pal_ptr, pal_size);
+ bmp_ptr->file_header.bfOffBits += pal_size;
+ }
+ WriteInfoHeader(&bmp_ptr->info_header, dst_buf);
+ switch(bmp_ptr->info_header.biCompression) {
+ case BMP_RGB:
+ _bmp_encode_rgb(bmp_ptr, dst_buf, dst_size);
+ break;
+ case BMP_BITFIELDS:
+#ifdef BMP_SUPPORT_BITFIELD
+ _bmp_encode_bitfields(bmp_ptr, dst_buf, dst_size);
+#endif
+ break;
+ case BMP_RLE8:
+ _bmp_encode_rle8(bmp_ptr, dst_buf, dst_size);
+ break;
+ case BMP_RLE4:
+ _bmp_encode_rle4(bmp_ptr, dst_buf, dst_size);
+ break;
+ default:
+ ;
+ }
+ bmp_ptr->file_header.bfSize = dst_size;
+ WriteFileHeader(&bmp_ptr->file_header, dst_buf);
+ return TRUE;
+}
diff --git a/core/src/fxcodec/lbmp/fx_bmp.h b/core/src/fxcodec/lbmp/fx_bmp.h
new file mode 100644
index 0000000000..1603770eb4
--- /dev/null
+++ b/core/src/fxcodec/lbmp/fx_bmp.h
@@ -0,0 +1,142 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_BASIC_H_
+#include "../../../include/fxcrt/fx_basic.h"
+#endif
+#define BMP_SUPPORT_BITFIELD
+#define BMP_WIDTHBYTES(width,bitCount) ((width*bitCount) + 31)/32*4
+#define BMP_PAL_ENCODE(a,r,g,b) (((FX_DWORD)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+#define BMP_D_STATUS_HEADER 0x01
+#define BMP_D_STATUS_PAL 0x02
+#define BMP_D_STATUS_DATA_PRE 0x03
+#define BMP_D_STATUS_DATA 0x04
+#define BMP_D_STATUS_TAIL 0x00
+#define BMP_SIGNATURE 0x4D42
+#define BMP_PAL_NEW 0
+#define BMP_PAL_OLD 1
+#define RLE_MARKER 0
+#define RLE_EOL 0
+#define RLE_EOI 1
+#define RLE_DELTA 2
+#define BMP_RGB 0L
+#define BMP_RLE8 1L
+#define BMP_RLE4 2L
+#define BMP_BITFIELDS 3L
+#define BMP_BIT_555 0
+#define BMP_BIT_565 1
+#define BMP_MAX_ERROR_SIZE 256
+#pragma pack(1)
+typedef struct tagBmpFileHeader {
+ FX_WORD bfType;
+ FX_DWORD bfSize;
+ FX_WORD bfReserved1;
+ FX_WORD bfReserved2;
+ FX_DWORD bfOffBits;
+} BmpFileHeader, *BmpFileHeaderPtr;
+typedef struct tagBmpCoreHeader {
+ FX_DWORD bcSize;
+ FX_WORD bcWidth;
+ FX_WORD bcHeight;
+ FX_WORD bcPlanes;
+ FX_WORD bcBitCount;
+} BmpCoreHeader, *BmpCoreHeaderPtr;
+typedef struct tagBmpInfoHeader {
+ FX_DWORD biSize;
+ FX_INT32 biWidth;
+ FX_INT32 biHeight;
+ FX_WORD biPlanes;
+ FX_WORD biBitCount;
+ FX_DWORD biCompression;
+ FX_DWORD biSizeImage;
+ FX_INT32 biXPelsPerMeter;
+ FX_INT32 biYPelsPerMeter;
+ FX_DWORD biClrUsed;
+ FX_DWORD biClrImportant;
+} BmpInfoHeader, *BmpInfoHeaderPtr;
+#pragma pack()
+typedef struct tag_bmp_decompress_struct bmp_decompress_struct;
+typedef bmp_decompress_struct *bmp_decompress_struct_p;
+typedef bmp_decompress_struct_p *bmp_decompress_struct_pp;
+struct tag_bmp_decompress_struct {
+ jmp_buf jmpbuf;
+ FX_LPSTR err_ptr;
+ void (*_bmp_error_fn)(bmp_decompress_struct_p gif_ptr, FX_LPCSTR err_msg);
+
+ void* context_ptr;
+
+ BmpFileHeaderPtr bmp_header_ptr;
+ BmpInfoHeaderPtr bmp_infoheader_ptr;
+ FX_INT32 width;
+ FX_INT32 height;
+ FX_DWORD compress_flag;
+ FX_INT32 components;
+ FX_INT32 src_row_bytes;
+ FX_INT32 out_row_bytes;
+ FX_LPBYTE out_row_buffer;
+ FX_WORD bitCounts;
+ FX_DWORD color_used;
+ FX_BOOL imgTB_flag;
+ FX_INT32 pal_num;
+ FX_INT32 pal_type;
+ FX_DWORD* pal_ptr;
+ FX_DWORD data_size;
+ FX_DWORD img_data_offset;
+ FX_DWORD img_ifh_size;
+ FX_INT32 row_num;
+ FX_INT32 col_num;
+ FX_INT32 dpi_x;
+ FX_INT32 dpi_y;
+#ifdef BMP_SUPPORT_BITFIELD
+ FX_DWORD mask_red;
+ FX_DWORD mask_green;
+ FX_DWORD mask_blue;
+#endif
+
+ FX_BOOL (*_bmp_get_data_position_fn)(bmp_decompress_struct_p bmp_ptr, FX_DWORD cur_pos);
+ void (*_bmp_get_row_fn)(bmp_decompress_struct_p bmp_ptr, FX_INT32 row_num, FX_LPBYTE row_buf);
+ FX_LPBYTE next_in;
+ FX_DWORD avail_in;
+ FX_DWORD skip_size;
+ FX_INT32 decode_status;
+};
+void _bmp_error(bmp_decompress_struct_p bmp_ptr, FX_LPCSTR err_msg);
+bmp_decompress_struct_p _bmp_create_decompress();
+void _bmp_destroy_decompress(bmp_decompress_struct_pp bmp_ptr_ptr);
+FX_INT32 _bmp_read_header(bmp_decompress_struct_p bmp_ptr);
+FX_INT32 _bmp_decode_image(bmp_decompress_struct_p bmp_ptr);
+FX_INT32 _bmp_decode_rgb(bmp_decompress_struct_p bmp_ptr);
+FX_INT32 _bmp_decode_rle8(bmp_decompress_struct_p bmp_ptr);
+FX_INT32 _bmp_decode_rle4(bmp_decompress_struct_p bmp_ptr);
+FX_LPBYTE _bmp_read_data(bmp_decompress_struct_p bmp_ptr, FX_LPBYTE* des_buf_pp, FX_DWORD data_size);
+void _bmp_save_decoding_status(bmp_decompress_struct_p bmp_ptr, FX_INT32 status);
+void _bmp_input_buffer(bmp_decompress_struct_p bmp_ptr, FX_LPBYTE src_buf, FX_DWORD src_size);
+FX_DWORD _bmp_get_avail_input(bmp_decompress_struct_p bmp_ptr, FX_LPBYTE* avial_buf_ptr);
+#define BMP_PTR_NOT_NULL(ptr,bmp_ptr) if(ptr == NULL){ \
+ _bmp_error(bmp_ptr,"Out Of Memory");\
+ return 0; \
+ }
+typedef struct tag_bmp_compress_struct bmp_compress_struct;
+typedef bmp_compress_struct *bmp_compress_struct_p;
+typedef bmp_compress_struct_p *bmp_compress_struct_pp;
+struct tag_bmp_compress_struct {
+ BmpFileHeader file_header;
+ BmpInfoHeader info_header;
+ FX_LPBYTE src_buf;
+ FX_DWORD src_pitch;
+ FX_DWORD src_row;
+ FX_BYTE src_bpp;
+ FX_DWORD src_width;
+ FX_BOOL src_free;
+ FX_DWORD* pal_ptr;
+ FX_WORD pal_num;
+#ifdef BMP_SUPPORT_BITFIELD
+ FX_BYTE bit_type;
+#endif
+};
+bmp_compress_struct_p _bmp_create_compress();
+void _bmp_destroy_compress(bmp_compress_struct_p bmp_ptr);
+FX_BOOL _bmp_encode_image(bmp_compress_struct_p bmp_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_size);
diff --git a/core/src/fxcodec/lgif/fx_gif.cpp b/core/src/fxcodec/lgif/fx_gif.cpp
new file mode 100644
index 0000000000..8f5794e786
--- /dev/null
+++ b/core/src/fxcodec/lgif/fx_gif.cpp
@@ -0,0 +1,1368 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "fx_gif.h"
+void CGifLZWDecoder::Input(FX_LPBYTE src_buf, FX_DWORD src_size)
+{
+ next_in = src_buf;
+ avail_in = src_size;
+}
+FX_DWORD CGifLZWDecoder::GetAvailInput()
+{
+ return avail_in;
+}
+void CGifLZWDecoder::InitTable(FX_BYTE code_len)
+{
+ code_size = code_len;
+ code_clear = 1 << code_size;
+ code_end = code_clear + 1;
+ bits_left = 0;
+ code_store = 0;
+ next_in = NULL;
+ avail_in = 0;
+ stack_size = 0;
+ code_first = 0;
+ ClearTable();
+}
+void CGifLZWDecoder::ClearTable()
+{
+ code_size_cur = code_size + 1;
+ code_next = code_end + 1;
+ code_old = (FX_WORD) - 1;
+ FXSYS_memset32(code_table, 0, sizeof(tag_Table)*GIF_MAX_LZW_CODE);
+ FXSYS_memset32(stack, 0, GIF_MAX_LZW_CODE);
+ for (FX_WORD i = 0; i < code_clear; i++) {
+ code_table[i].suffix = (FX_BYTE)i;
+ }
+}
+void CGifLZWDecoder::DecodeString(FX_WORD code)
+{
+ stack_size = 0;
+ while (TRUE) {
+ ASSERT(code <= code_next);
+ if(code < code_clear || code > code_next) {
+ break;
+ }
+ stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = code_table[code].suffix;
+ code = code_table[code].prefix;
+ }
+ stack[GIF_MAX_LZW_CODE - 1 - stack_size++] = (FX_BYTE)code;
+ code_first = (FX_BYTE)code;
+}
+void CGifLZWDecoder::AddCode(FX_WORD prefix_code, FX_BYTE append_char)
+{
+ if(code_next == GIF_MAX_LZW_CODE) {
+ return;
+ }
+ code_table[code_next].prefix = prefix_code;
+ code_table[code_next].suffix = append_char;
+ if(++code_next < GIF_MAX_LZW_CODE) {
+ if(code_next >> code_size_cur) {
+ code_size_cur++;
+ }
+ }
+}
+FX_INT32 CGifLZWDecoder::Decode(FX_LPBYTE des_buf, FX_DWORD& des_size)
+{
+ if(des_size == 0) {
+ return 3;
+ }
+ FX_DWORD i = 0;
+ if(stack_size != 0) {
+ if(des_size < stack_size) {
+ FXSYS_memcpy32(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], des_size);
+ stack_size -= (FX_WORD)des_size;
+ return 3;
+ }
+ FXSYS_memcpy32(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size);
+ des_buf += stack_size;
+ i += stack_size;
+ stack_size = 0;
+ }
+ FX_WORD code = 0;
+ while(i <= des_size && (avail_in > 0 || bits_left >= code_size_cur)) {
+ if(code_size_cur > 12) {
+ if(err_msg_ptr) {
+ FXSYS_strncpy(err_msg_ptr, "Code Length Out Of Range", GIF_MAX_ERROR_SIZE - 1);
+ }
+ return 0;
+ }
+ if (avail_in > 0) {
+ code_store |= (*next_in++) << bits_left;
+ avail_in--;
+ bits_left += 8;
+ }
+ while (bits_left >= code_size_cur) {
+ code = (FX_WORD)code_store & ((1 << code_size_cur) - 1);
+ code_store >>= code_size_cur;
+ bits_left -= code_size_cur;
+ if(code == code_clear) {
+ ClearTable();
+ continue;
+ } else if (code == code_end) {
+ des_size = i;
+ return 1;
+ } else {
+ if(code_old != (FX_WORD) - 1) {
+ if(code_next < GIF_MAX_LZW_CODE) {
+ if(code == code_next) {
+ AddCode(code_old, code_first);
+ DecodeString(code);
+ } else if(code > code_next) {
+ if(err_msg_ptr) {
+ FXSYS_strncpy(err_msg_ptr, "Decode Error, Out Of Range", GIF_MAX_ERROR_SIZE - 1);
+ }
+ return 0;
+ } else {
+ DecodeString(code);
+ FX_BYTE append_char = stack[GIF_MAX_LZW_CODE - stack_size];
+ AddCode(code_old, append_char);
+ }
+ }
+ } else {
+ DecodeString(code);
+ }
+ code_old = code;
+ if(i + stack_size > des_size) {
+ FXSYS_memcpy32(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], des_size - i);
+ stack_size -= (FX_WORD)(des_size - i);
+ return 3;
+ }
+ FXSYS_memcpy32(des_buf, &stack[GIF_MAX_LZW_CODE - stack_size], stack_size);
+ des_buf += stack_size;
+ i += stack_size;
+ stack_size = 0;
+ }
+ }
+ }
+ if(avail_in == 0) {
+ des_size = i;
+ return 2;
+ }
+ return 0;
+}
+static FX_BOOL _gif_grow_buf(FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD size)
+{
+ if (dst_len < size) {
+ FX_DWORD len_org = dst_len;
+ while (dst_buf && dst_len < size) {
+ dst_len <<= 1;
+ dst_buf = FX_Realloc(FX_BYTE, dst_buf, dst_len);
+ }
+ if (dst_buf == NULL) {
+ dst_len = size;
+ dst_buf = FX_Realloc(FX_BYTE, dst_buf, dst_len);
+ if (dst_buf == NULL) {
+ return FALSE;
+ }
+ }
+ FXSYS_memset32(dst_buf + len_org, 0, dst_len - len_org);
+ return dst_buf != NULL;
+ }
+ return TRUE;
+}
+static inline void _gif_cut_index(FX_BYTE& val, FX_DWORD index, FX_BYTE index_bit, FX_BYTE index_bit_use, FX_BYTE bit_use)
+{
+ FX_DWORD cut = ((1 << (index_bit - index_bit_use)) - 1) << index_bit_use;
+ val |= ((index & cut) >> index_bit_use) << bit_use;
+}
+static inline FX_BYTE _gif_cut_buf(FX_LPCBYTE buf, FX_DWORD& offset, FX_BYTE bit_cut, FX_BYTE& bit_offset, FX_DWORD& bit_num)
+{
+ if (bit_cut != 8) {
+ FX_WORD index = 0;
+ index |= ((1 << bit_cut) - 1) << (7 - bit_offset);
+ FX_BYTE ret = ((index & buf[offset]) >> (7 - bit_offset));
+ bit_offset += bit_cut;
+ if (bit_offset >= 8) {
+ if (bit_offset > 8) {
+ ret |= ((index & (buf[offset + 1] << 8)) >> 8);
+ }
+ bit_offset -= 8;
+ offset ++;
+ }
+ bit_num += bit_cut;
+ return ret;
+ }
+ bit_num += bit_cut;
+ return buf[offset++];
+}
+CGifLZWEncoder::CGifLZWEncoder()
+{
+ FXSYS_memset32(this, 0, sizeof(CGifLZWEncoder));
+}
+CGifLZWEncoder::~CGifLZWEncoder()
+{
+}
+void CGifLZWEncoder::ClearTable()
+{
+ index_bit_cur = code_size + 1;
+ index_num = code_end + 1;
+ table_cur = code_end + 1;
+ for (FX_WORD i = 0; i < GIF_MAX_LZW_CODE; i++) {
+ code_table[i].prefix = 0;
+ code_table[i].suffix = 0;
+ }
+}
+void CGifLZWEncoder::Start( FX_BYTE code_len, FX_LPCBYTE src_buf, FX_LPBYTE& dst_buf, FX_DWORD& offset)
+{
+ code_size = code_len + 1;
+ src_bit_cut = code_size;
+ if (code_len == 0) {
+ src_bit_cut = 1;
+ code_size = 2;
+ }
+ code_clear = 1 << code_size;
+ code_end = code_clear + 1;
+ dst_buf[offset++] = code_size;
+ bit_offset = 0;
+ ClearTable();
+ src_offset = 0;
+ src_bit_offset = 0;
+ src_bit_num = 0;
+ code_table[index_num].prefix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num);
+ code_table[index_num].suffix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num);
+}
+void CGifLZWEncoder::WriteBlock(FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset)
+{
+ if (!_gif_grow_buf(dst_buf, dst_len, offset + GIF_DATA_BLOCK + 1)) {
+ longjmp(jmp, 1);
+ }
+ dst_buf[offset++] = index_buf_len;
+ FXSYS_memcpy32(&dst_buf[offset], index_buf, index_buf_len);
+ offset += index_buf_len;
+ FXSYS_memset32(index_buf, 0, GIF_DATA_BLOCK);
+ index_buf_len = 0;
+}
+void CGifLZWEncoder::EncodeString( FX_DWORD index, FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset )
+{
+ FX_BYTE index_bit_use;
+ index_bit_use = 0;
+ if (index_buf_len == GIF_DATA_BLOCK) {
+ WriteBlock(dst_buf, dst_len, offset);
+ }
+ _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use, bit_offset);
+ if (index_bit_cur <= (8 - bit_offset)) {
+ bit_offset += index_bit_cur;
+ } else if (index_bit_cur <= (16 - bit_offset)) {
+ index_bit_use += (8 - bit_offset);
+ bit_offset = 0;
+ index_buf_len++;
+ if (index_buf_len == GIF_DATA_BLOCK) {
+ WriteBlock(dst_buf, dst_len, offset);
+ }
+ _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use, bit_offset);
+ bit_offset = index_bit_cur - index_bit_use;
+ } else {
+ index_bit_use += (8 - bit_offset);
+ bit_offset = 0;
+ index_buf_len++;
+ if (index_buf_len == GIF_DATA_BLOCK) {
+ WriteBlock(dst_buf, dst_len, offset);
+ }
+ _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use, bit_offset);
+ index_bit_use += 8;
+ bit_offset = 0;
+ index_buf_len++;
+ if (index_buf_len == GIF_DATA_BLOCK) {
+ WriteBlock(dst_buf, dst_len, offset);
+ }
+ _gif_cut_index(index_buf[index_buf_len], index, index_bit_cur, index_bit_use, bit_offset);
+ bit_offset = index_bit_cur - index_bit_use;
+ }
+ if (bit_offset == 8) {
+ bit_offset = 0;
+ index_buf_len++;
+ if (index_buf_len == GIF_DATA_BLOCK) {
+ WriteBlock(dst_buf, dst_len, offset);
+ }
+ }
+ if (index == code_end) {
+ index_buf_len++;
+ WriteBlock(dst_buf, dst_len, offset);
+ }
+ if (index_num++ >> index_bit_cur) {
+ index_bit_cur++;
+ }
+}
+FX_BOOL CGifLZWEncoder::Encode( FX_LPCBYTE src_buf, FX_DWORD src_len, FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset )
+{
+ FX_BYTE suffix;
+ if (setjmp(jmp)) {
+ return FALSE;
+ }
+ while(src_bit_num < src_len) {
+ if (!LookUpInTable(src_buf, src_offset, src_bit_offset)) {
+ EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset);
+ if (index_num == GIF_MAX_LZW_CODE) {
+ suffix = code_table[index_num - 1].suffix;
+ EncodeString(code_clear, dst_buf, dst_len, offset);
+ ClearTable();
+ code_table[index_num].prefix = suffix;
+ code_table[index_num].suffix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num);
+ } else {
+ code_table[index_num].prefix = code_table[index_num - 1].suffix;
+ code_table[index_num].suffix = _gif_cut_buf(src_buf, src_offset, src_bit_cut, src_bit_offset, src_bit_num);
+ }
+ }
+ }
+ src_offset = 0;
+ src_bit_offset = 0;
+ src_bit_num = 0;
+ return TRUE;
+}
+FX_BOOL CGifLZWEncoder::LookUpInTable( FX_LPCBYTE buf, FX_DWORD& offset, FX_BYTE& bit_offset )
+{
+ for (FX_WORD i = table_cur; i < index_num; i++) {
+ if (code_table[i].prefix == code_table[index_num].prefix &&
+ code_table[i].suffix == code_table[index_num].suffix) {
+ code_table[index_num].prefix = i;
+ code_table[index_num].suffix = _gif_cut_buf(buf, offset, src_bit_cut, bit_offset, src_bit_num);
+ table_cur = i;
+ return TRUE;
+ }
+ }
+ table_cur = code_end + 1;
+ return FALSE;
+}
+void CGifLZWEncoder::Finish(FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset)
+{
+ EncodeString(code_table[index_num].prefix, dst_buf, dst_len, offset);
+ EncodeString(code_end, dst_buf, dst_len, offset);
+ bit_offset = 0;
+ ClearTable();
+}
+gif_decompress_struct_p _gif_create_decompress()
+{
+ gif_decompress_struct_p gif_ptr = (gif_decompress_struct*)FX_Alloc(FX_BYTE, sizeof(gif_decompress_struct));
+ if(gif_ptr == NULL) {
+ return NULL;
+ }
+ FXSYS_memset32(gif_ptr, 0, sizeof(gif_decompress_struct));
+ gif_ptr->decode_status = GIF_D_STATUS_SIG;
+ gif_ptr->img_ptr_arr_ptr = FX_NEW CFX_ArrayTemplate<GifImage*>;
+ if(gif_ptr->img_ptr_arr_ptr == NULL) {
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ gif_ptr->cmt_data_ptr = FX_NEW CFX_ByteString;
+ if(gif_ptr->cmt_data_ptr == NULL) {
+ delete gif_ptr->img_ptr_arr_ptr;
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ gif_ptr->pt_ptr_arr_ptr = FX_NEW CFX_ArrayTemplate<GifPlainText*>;
+ if(gif_ptr->pt_ptr_arr_ptr == NULL) {
+ delete(gif_ptr->cmt_data_ptr);
+ delete gif_ptr->img_ptr_arr_ptr;
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+#endif
+ return gif_ptr;
+}
+void _gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr)
+{
+ if(gif_ptr_ptr == NULL || *gif_ptr_ptr == NULL) {
+ return;
+ }
+ gif_decompress_struct_p gif_ptr = *gif_ptr_ptr;
+ *gif_ptr_ptr = NULL;
+ if(gif_ptr->global_pal_ptr != NULL) {
+ FX_Free(gif_ptr->global_pal_ptr);
+ }
+ if(gif_ptr->img_decoder_ptr != NULL) {
+ delete gif_ptr->img_decoder_ptr;
+ }
+ if(gif_ptr->img_ptr_arr_ptr != NULL) {
+ FX_INT32 size_img_arr = gif_ptr->img_ptr_arr_ptr->GetSize();
+ for (FX_INT32 i = 0; i < size_img_arr; i++) {
+ GifImage* p = gif_ptr->img_ptr_arr_ptr->GetAt(i);
+ if(p->image_info_ptr != NULL) {
+ FX_Free(p->image_info_ptr);
+ }
+ if(p->image_gce_ptr != NULL) {
+ FX_Free(p->image_gce_ptr);
+ }
+ if(p->image_row_buf != NULL) {
+ FX_Free(p->image_row_buf);
+ }
+ if(p->local_pal_ptr != NULL && p->local_pal_ptr != gif_ptr->global_pal_ptr) {
+ FX_Free(p->local_pal_ptr);
+ }
+ FX_Free(p);
+ }
+ gif_ptr->img_ptr_arr_ptr->RemoveAll();
+ delete gif_ptr->img_ptr_arr_ptr;
+ }
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ if(gif_ptr->app_data != NULL) {
+ FX_Free(gif_ptr->app_data);
+ }
+#endif
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ if(gif_ptr->cmt_data_ptr != NULL) {
+ delete gif_ptr->cmt_data_ptr;
+ }
+#endif
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ if(gif_ptr->gce_ptr != NULL) {
+ FX_Free(gif_ptr->gce_ptr);
+ }
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ if(gif_ptr->pt_ptr_arr_ptr != NULL) {
+ FX_INT32 size_pt_arr = gif_ptr->pt_ptr_arr_ptr->GetSize();
+ for (FX_INT32 i = 0; i < size_pt_arr; i++) {
+ GifPlainText* p = gif_ptr->pt_ptr_arr_ptr->GetAt(i);
+ if(p->gce_ptr != NULL) {
+ FX_Free(p->gce_ptr);
+ }
+ if(p->pte_ptr != NULL) {
+ FX_Free(p->pte_ptr);
+ }
+ if(p->string_ptr != NULL) {
+ delete p->string_ptr;
+ }
+ }
+ gif_ptr->pt_ptr_arr_ptr->RemoveAll();
+ delete gif_ptr->pt_ptr_arr_ptr;
+ }
+#endif
+ FX_Free(gif_ptr);
+}
+gif_compress_struct_p _gif_create_compress()
+{
+ gif_compress_struct_p gif_ptr = (gif_compress_struct*)FX_Alloc(FX_BYTE, sizeof(gif_compress_struct));
+ if (gif_ptr == NULL) {
+ return NULL;
+ }
+ FXSYS_memset32(gif_ptr, 0, sizeof(gif_compress_struct));
+ gif_ptr->img_encoder_ptr = FX_NEW CGifLZWEncoder;
+ if (gif_ptr->img_encoder_ptr == NULL) {
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+ gif_ptr->header_ptr = (GifHeader*)FX_Alloc(FX_BYTE, sizeof(GifHeader));
+ if (gif_ptr->header_ptr == NULL) {
+ delete(gif_ptr->img_encoder_ptr);
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+ FXSYS_memcpy32(gif_ptr->header_ptr->signature, GIF_SIGNATURE, 3);
+ FXSYS_memcpy32(gif_ptr->header_ptr->version, "89a", 3);
+ gif_ptr->lsd_ptr = (GifLSD*)FX_Alloc(FX_BYTE, sizeof(GifLSD));
+ if (gif_ptr->lsd_ptr == NULL) {
+ FX_Free(gif_ptr->header_ptr);
+ delete(gif_ptr->img_encoder_ptr);
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+ FXSYS_memset32(gif_ptr->lsd_ptr, 0, sizeof(GifLSD));
+ gif_ptr->image_info_ptr = (GifImageInfo*)FX_Alloc(FX_BYTE, sizeof(GifImageInfo));
+ if (gif_ptr->image_info_ptr == NULL) {
+ FX_Free(gif_ptr->lsd_ptr);
+ FX_Free(gif_ptr->header_ptr);
+ delete(gif_ptr->img_encoder_ptr);
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+ FXSYS_memset32(gif_ptr->image_info_ptr, 0, sizeof(GifImageInfo));
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ FXSYS_memcpy32(gif_ptr->app_identify, "netscape", 8);
+ FXSYS_memcpy32(gif_ptr->app_authentication, "2.0", 3);
+#endif
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ gif_ptr->gce_ptr = (GifGCE*)FX_Alloc(FX_BYTE, sizeof(GifGCE));
+ if (gif_ptr->gce_ptr == NULL) {
+ FX_Free(gif_ptr->image_info_ptr);
+ FX_Free(gif_ptr->lsd_ptr);
+ FX_Free(gif_ptr->header_ptr);
+ delete(gif_ptr->img_encoder_ptr);
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ gif_ptr->pte_ptr = (GifPTE*)FX_Alloc(FX_BYTE, sizeof(GifPTE));
+ if (gif_ptr->pte_ptr == NULL) {
+ FX_Free(gif_ptr->gce_ptr);
+ FX_Free(gif_ptr->image_info_ptr);
+ FX_Free(gif_ptr->lsd_ptr);
+ FX_Free(gif_ptr->header_ptr);
+ delete(gif_ptr->img_encoder_ptr);
+ FX_Free(gif_ptr);
+ return NULL;
+ }
+ FXSYS_memset32(gif_ptr->pte_ptr, 0, sizeof(GifPTE));
+ gif_ptr->pte_ptr->block_size = 12;
+#endif
+ return gif_ptr;
+}
+void _gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr)
+{
+ if(gif_ptr_ptr == NULL || *gif_ptr_ptr == NULL) {
+ return;
+ }
+ gif_compress_struct_p gif_ptr = *gif_ptr_ptr;
+ *gif_ptr_ptr = NULL;
+ if(gif_ptr->header_ptr != NULL) {
+ FX_Free(gif_ptr->header_ptr);
+ }
+ if(gif_ptr->lsd_ptr != NULL) {
+ FX_Free(gif_ptr->lsd_ptr);
+ }
+ if(gif_ptr->global_pal != NULL) {
+ FX_Free(gif_ptr->global_pal);
+ }
+ if(gif_ptr->image_info_ptr != NULL) {
+ FX_Free(gif_ptr->image_info_ptr);
+ }
+ if(gif_ptr->local_pal != NULL) {
+ FX_Free(gif_ptr->local_pal);
+ }
+ if(gif_ptr->img_encoder_ptr != NULL) {
+ delete gif_ptr->img_encoder_ptr;
+ }
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ if(gif_ptr->app_data != NULL) {
+ FX_Free(gif_ptr->app_data);
+ }
+#endif
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ if(gif_ptr->gce_ptr != NULL) {
+ FX_Free(gif_ptr->gce_ptr);
+ }
+#endif
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ if(gif_ptr->cmt_data_ptr != NULL) {
+ FX_Free(gif_ptr->cmt_data_ptr);
+ }
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ if(gif_ptr->pte_ptr != NULL) {
+ FX_Free(gif_ptr->pte_ptr);
+ }
+#endif
+ FX_Free(gif_ptr);
+}
+void _gif_error(gif_decompress_struct_p gif_ptr, FX_LPCSTR err_msg)
+{
+ if(gif_ptr != NULL && gif_ptr->_gif_error_fn != NULL) {
+ gif_ptr->_gif_error_fn(gif_ptr, err_msg);
+ }
+}
+void _gif_warn(gif_decompress_struct_p gif_ptr, FX_LPCSTR err_msg) {}
+FX_INT32 _gif_read_header(gif_decompress_struct_p gif_ptr)
+{
+ if(gif_ptr == NULL) {
+ return 0;
+ }
+ FX_DWORD skip_size_org = gif_ptr->skip_size;
+ ASSERT(sizeof(GifHeader) == 6);
+ GifHeader* gif_header_ptr = NULL;
+ if(_gif_read_data(gif_ptr, (FX_LPBYTE*)&gif_header_ptr, 6) == NULL) {
+ return 2;
+ }
+ if(FXSYS_strncmp(gif_header_ptr->signature, GIF_SIGNATURE, 3) != 0 ||
+ gif_header_ptr->version[0] != '8' ||
+ gif_header_ptr->version[2] != 'a') {
+ _gif_error(gif_ptr, "Not A Gif Image");
+ return 0;
+ }
+ ASSERT(sizeof(GifLSD) == 7);
+ GifLSD* gif_lsd_ptr = NULL;
+ if(_gif_read_data(gif_ptr, (FX_LPBYTE*)&gif_lsd_ptr, 7) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ if(((GifGF*)&gif_lsd_ptr->global_flag)->global_pal) {
+ gif_ptr->global_pal_num = 2 << ((GifGF*)&gif_lsd_ptr->global_flag)->pal_bits;
+ ASSERT(sizeof(GifPalette) == 3);
+ FX_INT32 global_pal_size = gif_ptr->global_pal_num * 3;
+ FX_LPBYTE global_pal_ptr = NULL;
+ if (_gif_read_data(gif_ptr, &global_pal_ptr, global_pal_size) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ gif_ptr->global_sort_flag = ((GifGF*)&gif_lsd_ptr->global_flag)->sort_flag;
+ gif_ptr->global_color_resolution = ((GifGF*)&gif_lsd_ptr->global_flag)->color_resolution;
+ if(gif_ptr->global_pal_ptr != NULL) {
+ FX_Free(gif_ptr->global_pal_ptr);
+ }
+ gif_ptr->global_pal_ptr = NULL;
+ gif_ptr->global_pal_ptr = (GifPalette*)FX_Alloc(FX_BYTE, global_pal_size);
+ GIF_PTR_NOT_NULL(gif_ptr->global_pal_ptr, gif_ptr);
+ FXSYS_memcpy32(gif_ptr->global_pal_ptr, global_pal_ptr, global_pal_size);
+ }
+ gif_ptr->width = (int)_GetWord_LSBFirst((FX_LPBYTE)&gif_lsd_ptr->width);
+ gif_ptr->height = (int)_GetWord_LSBFirst((FX_LPBYTE)&gif_lsd_ptr->height);
+ gif_ptr->bc_index = gif_lsd_ptr->bc_index;
+ gif_ptr->pixel_aspect = gif_lsd_ptr->pixel_aspect;
+ return 1;
+}
+FX_INT32 _gif_get_frame(gif_decompress_struct_p gif_ptr)
+{
+ if(gif_ptr == NULL) {
+ return 0;
+ }
+ FX_INT32 ret = 1;
+ while (TRUE) {
+ switch(gif_ptr->decode_status) {
+ case GIF_D_STATUS_TAIL:
+ return 1;
+ case GIF_D_STATUS_SIG: {
+ FX_LPBYTE sig_ptr = NULL;
+ if(_gif_read_data(gif_ptr, &sig_ptr, 1) == NULL) {
+ return 2;
+ }
+ switch(*sig_ptr) {
+ case GIF_SIG_EXTENSION:
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT);
+ continue;
+ case GIF_SIG_IMAGE:
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_INFO);
+ continue;
+ case GIF_SIG_TRAILER:
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
+ return 1;
+ default:
+ if (gif_ptr->avail_in) {
+ _gif_warn(gif_ptr, "The Gif File has non_standard Tag!");
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG);
+ continue;
+ }
+ _gif_warn(gif_ptr, "The Gif File Doesn't have Trailer Tag!");
+ return 1;
+ }
+ }
+ case GIF_D_STATUS_EXT: {
+ FX_LPBYTE ext_ptr = NULL;
+ if(_gif_read_data(gif_ptr, &ext_ptr, 1) == NULL) {
+ return 2;
+ }
+ switch(*ext_ptr) {
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ case GIF_BLOCK_AE:
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_AE);
+ continue;
+#endif
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ case GIF_BLOCK_CE:
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_CE);
+ continue;
+#endif
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ case GIF_BLOCK_GCE:
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_GCE);
+ continue;
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ case GIF_BLOCK_PTE:
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_EXT_PTE);
+ continue;
+#endif
+ default: {
+ FX_INT32 status = GIF_D_STATUS_EXT_UNE;
+#ifndef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ if(*ext_ptr == GIF_BLOCK_PTE) {
+ status = GIF_D_STATUS_EXT_PTE;
+ }
+#endif
+ _gif_save_decoding_status(gif_ptr, status);
+ continue;
+ }
+ }
+ }
+ case GIF_D_STATUS_IMG_INFO: {
+ ret = _gif_decode_image_info(gif_ptr);
+ if(ret != 1) {
+ return ret;
+ }
+ continue;
+ }
+ case GIF_D_STATUS_IMG_DATA: {
+ FX_LPBYTE data_size_ptr = NULL;
+ FX_LPBYTE data_ptr = NULL;
+ FX_DWORD skip_size_org = gif_ptr->skip_size;
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ return 2;
+ }
+ while(*data_size_ptr != GIF_BLOCK_TERMINAL) {
+ if(_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
+ skip_size_org = gif_ptr->skip_size;
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ return 2;
+ }
+ }
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG);
+ continue;
+ }
+ default: {
+ ret = _gif_decode_extension(gif_ptr);
+ if(ret != 1) {
+ return ret;
+ }
+ continue;
+ }
+ }
+ }
+ return 1;
+}
+void _gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, GifGCE** gce_ptr_ptr)
+{
+ *gce_ptr_ptr = NULL;
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ if(gif_ptr->gce_ptr != NULL && gce_ptr_ptr != NULL) {
+ *gce_ptr_ptr = gif_ptr->gce_ptr;
+ gif_ptr->gce_ptr = NULL;
+ }
+#endif
+}
+FX_INT32 _gif_decode_extension(gif_decompress_struct_p gif_ptr)
+{
+ FX_LPBYTE data_size_ptr = NULL;
+ FX_LPBYTE data_ptr = NULL;
+ FX_DWORD skip_size_org = gif_ptr->skip_size;
+ switch(gif_ptr->decode_status) {
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ case GIF_D_STATUS_EXT_AE: {
+ ASSERT(sizeof(GifAE) == 12);
+ GifAE* gif_ae_ptr = NULL;
+ if(_gif_read_data(gif_ptr, (FX_LPBYTE*)&gif_ae_ptr, 12) == NULL) {
+ return 2;
+ }
+ CFX_ByteString gif_ae_data_str;
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ while(*data_size_ptr != GIF_BLOCK_TERMINAL) {
+ FX_BYTE data_size = *data_size_ptr;
+ if(_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL ||
+ _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ gif_ae_data_str += CFX_ByteString((FX_LPCBYTE)data_ptr, data_size);
+ }
+ FXSYS_memcpy32(gif_ptr->app_identify, gif_ae_ptr->app_identify, 8);
+ FXSYS_memcpy32(gif_ptr->app_authentication, gif_ae_ptr->app_authentication, 3);
+ gif_ptr->app_data_size = gif_ae_data_str.GetLength();
+ if(gif_ptr->app_data != NULL) {
+ FX_Free(gif_ptr->app_data);
+ gif_ptr->app_data = NULL;
+ }
+ gif_ptr->app_data = FX_Alloc(FX_BYTE, gif_ptr->app_data_size);
+ GIF_PTR_NOT_NULL(gif_ptr->app_data, gif_ptr);
+ FXSYS_memcpy32(gif_ptr->app_data, FX_LPCBYTE(gif_ae_data_str), gif_ptr->app_data_size);
+ }
+ break;
+#endif
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ case GIF_D_STATUS_EXT_CE: {
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ gif_ptr->cmt_data_ptr->Empty();
+ while(*data_size_ptr != GIF_BLOCK_TERMINAL) {
+ FX_BYTE data_size = *data_size_ptr;
+ if(_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL ||
+ _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ *(gif_ptr->cmt_data_ptr) += CFX_ByteString((FX_LPCSTR)data_ptr, data_size);
+ }
+ }
+ break;
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ case GIF_D_STATUS_EXT_PTE: {
+ ASSERT(sizeof(GifPTE) == 13);
+ GifPTE* gif_pte_ptr = NULL;
+ if(_gif_read_data(gif_ptr, (FX_LPBYTE*)&gif_pte_ptr, 13) == NULL) {
+ return 2;
+ }
+ GifPlainText* gif_pt_ptr = FX_Alloc(GifPlainText, 1);
+ GIF_PTR_NOT_NULL(gif_pt_ptr, gif_ptr);
+ FXSYS_memset32(gif_pt_ptr, 0, sizeof(GifPlainText));
+ _gif_takeover_gce_ptr(gif_ptr, &gif_pt_ptr->gce_ptr);
+ gif_pt_ptr->pte_ptr = (GifPTE*)FX_Alloc(FX_BYTE, sizeof(GifPTE));
+ GIF_PTR_NOT_NULL(gif_pt_ptr->pte_ptr, gif_ptr);
+ gif_pt_ptr->string_ptr = FX_NEW CFX_ByteString;
+ GIF_PTR_NOT_NULL(gif_pt_ptr->string_ptr, gif_ptr);
+ gif_pt_ptr->pte_ptr->block_size = gif_pte_ptr->block_size;
+ gif_pt_ptr->pte_ptr->grid_left = _GetWord_LSBFirst((FX_LPBYTE)&gif_pte_ptr->grid_left);
+ gif_pt_ptr->pte_ptr->grid_top = _GetWord_LSBFirst((FX_LPBYTE)&gif_pte_ptr->grid_top);
+ gif_pt_ptr->pte_ptr->grid_width = _GetWord_LSBFirst((FX_LPBYTE)&gif_pte_ptr->grid_width);
+ gif_pt_ptr->pte_ptr->grid_height = _GetWord_LSBFirst((FX_LPBYTE)&gif_pte_ptr->grid_height);
+ gif_pt_ptr->pte_ptr->char_width = gif_pte_ptr->char_width;
+ gif_pt_ptr->pte_ptr->char_height = gif_pte_ptr->char_height;
+ gif_pt_ptr->pte_ptr->fc_index = gif_pte_ptr->fc_index;
+ gif_pt_ptr->pte_ptr->bc_index = gif_pte_ptr->bc_index;
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ if(gif_pt_ptr != NULL) {
+ if(gif_pt_ptr->gce_ptr != NULL) {
+ FX_Free(gif_pt_ptr->gce_ptr);
+ }
+ if(gif_pt_ptr->pte_ptr != NULL) {
+ FX_Free(gif_pt_ptr->pte_ptr);
+ }
+ if(gif_pt_ptr->string_ptr != NULL) {
+ delete gif_pt_ptr->string_ptr;
+ }
+ FX_Free(gif_pt_ptr);
+ }
+ return 2;
+ }
+ while(*data_size_ptr != GIF_BLOCK_TERMINAL) {
+ FX_BYTE data_size = *data_size_ptr;
+ if(_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL ||
+ _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ if(gif_pt_ptr != NULL) {
+ if(gif_pt_ptr->gce_ptr != NULL) {
+ FX_Free(gif_pt_ptr->gce_ptr);
+ }
+ if(gif_pt_ptr->pte_ptr != NULL) {
+ FX_Free(gif_pt_ptr->pte_ptr);
+ }
+ if(gif_pt_ptr->string_ptr != NULL) {
+ delete gif_pt_ptr->string_ptr;
+ }
+ FX_Free(gif_pt_ptr);
+ }
+ return 2;
+ }
+ *(gif_pt_ptr->string_ptr) += CFX_ByteString((FX_LPCSTR)data_ptr, data_size);
+ }
+ gif_ptr->pt_ptr_arr_ptr->Add(gif_pt_ptr);
+ }
+ break;
+#endif
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ case GIF_D_STATUS_EXT_GCE: {
+ ASSERT(sizeof(GifGCE) == 5);
+ GifGCE* gif_gce_ptr = NULL;
+ if(_gif_read_data(gif_ptr, (FX_LPBYTE*)&gif_gce_ptr, 6) == NULL) {
+ return 2;
+ }
+ if(gif_ptr->gce_ptr == NULL) {
+ gif_ptr->gce_ptr = (GifGCE*)FX_Alloc(FX_BYTE, sizeof(GifGCE));
+ GIF_PTR_NOT_NULL(gif_ptr->gce_ptr, gif_ptr);
+ }
+ gif_ptr->gce_ptr->block_size = gif_gce_ptr->block_size;
+ gif_ptr->gce_ptr->gce_flag = gif_gce_ptr->gce_flag;
+ gif_ptr->gce_ptr->delay_time = _GetWord_LSBFirst((FX_LPBYTE)&gif_gce_ptr->delay_time);
+ gif_ptr->gce_ptr->trans_index = gif_gce_ptr->trans_index;
+ }
+ break;
+#endif
+ default: {
+#ifndef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ if(gif_ptr->decode_status == GIF_D_STATUS_EXT_PTE) {
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ if(gif_ptr->gce_ptr != NULL) {
+ FX_Free(gif_ptr->gce_ptr);
+ gif_ptr->gce_ptr = NULL;
+ }
+#endif
+ }
+#endif
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ return 2;
+ }
+ while(*data_size_ptr != GIF_BLOCK_TERMINAL) {
+ if(_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL ||
+ _gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL ) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ }
+ }
+ }
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_SIG);
+ return 1;
+}
+FX_INT32 _gif_decode_image_info(gif_decompress_struct_p gif_ptr)
+{
+ if(gif_ptr->width == 0 || gif_ptr->height == 0) {
+ _gif_error(gif_ptr, "No Image Header Info");
+ return 0;
+ }
+ FX_DWORD skip_size_org = gif_ptr->skip_size;
+ ASSERT(sizeof(GifImageInfo) == 9);
+ GifImageInfo* gif_img_info_ptr = NULL;
+ if(_gif_read_data(gif_ptr, (FX_LPBYTE*)&gif_img_info_ptr, 9) == NULL) {
+ return 2;
+ }
+ GifImage* gif_image_ptr = (GifImage*)FX_Alloc(FX_BYTE, sizeof(GifImage));
+ GIF_PTR_NOT_NULL(gif_image_ptr, gif_ptr);
+ FXSYS_memset32(gif_image_ptr, 0, sizeof(GifImage));
+ gif_image_ptr->image_info_ptr = (GifImageInfo*)FX_Alloc(FX_BYTE, sizeof(GifImageInfo));
+ GIF_PTR_NOT_NULL(gif_image_ptr->image_info_ptr, gif_ptr);
+ gif_image_ptr->image_info_ptr->left = _GetWord_LSBFirst((FX_LPBYTE)&gif_img_info_ptr->left);
+ gif_image_ptr->image_info_ptr->top = _GetWord_LSBFirst((FX_LPBYTE)&gif_img_info_ptr->top);
+ gif_image_ptr->image_info_ptr->width = _GetWord_LSBFirst((FX_LPBYTE)&gif_img_info_ptr->width);
+ gif_image_ptr->image_info_ptr->height = _GetWord_LSBFirst((FX_LPBYTE)&gif_img_info_ptr->height);
+ gif_image_ptr->image_info_ptr->local_flag = gif_img_info_ptr->local_flag;
+ if(gif_image_ptr->image_info_ptr->left + gif_image_ptr->image_info_ptr->width > gif_ptr->width ||
+ gif_image_ptr->image_info_ptr->top + gif_image_ptr->image_info_ptr->height > gif_ptr->height) {
+ if(gif_image_ptr->image_info_ptr != NULL) {
+ FX_Free(gif_image_ptr->image_info_ptr);
+ }
+ if(gif_image_ptr->image_row_buf != NULL) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ }
+ FX_Free(gif_image_ptr);
+ _gif_error(gif_ptr, "Image Data Out Of LSD, The File May Be Corrupt");
+ return 0;
+ }
+ GifLF* gif_img_info_lf_ptr = (GifLF*)&gif_img_info_ptr->local_flag;
+ if(gif_img_info_lf_ptr->local_pal) {
+ ASSERT(sizeof(GifPalette) == 3);
+ FX_INT32 loc_pal_size = (2 << gif_img_info_lf_ptr->pal_bits) * 3;
+ FX_LPBYTE loc_pal_ptr = NULL;
+ if(_gif_read_data(gif_ptr, &loc_pal_ptr, loc_pal_size) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ if(gif_image_ptr->image_info_ptr != NULL) {
+ FX_Free(gif_image_ptr->image_info_ptr);
+ }
+ if(gif_image_ptr->image_row_buf != NULL) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ }
+ FX_Free(gif_image_ptr);
+ return 2;
+ }
+ gif_image_ptr->local_pal_ptr = (GifPalette*)gif_ptr->_gif_ask_buf_for_pal_fn(gif_ptr, loc_pal_size);
+ if(gif_image_ptr->local_pal_ptr != NULL) {
+ FXSYS_memcpy32((FX_LPBYTE)gif_image_ptr->local_pal_ptr, loc_pal_ptr, loc_pal_size);
+ }
+ }
+ FX_LPBYTE code_size_ptr = NULL;
+ if(_gif_read_data(gif_ptr, &code_size_ptr, 1) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ if(gif_image_ptr->image_info_ptr != NULL) {
+ FX_Free(gif_image_ptr->image_info_ptr);
+ }
+ if(gif_image_ptr->local_pal_ptr != NULL) {
+ FX_Free(gif_image_ptr->local_pal_ptr);
+ }
+ if(gif_image_ptr->image_row_buf != NULL) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ }
+ FX_Free(gif_image_ptr);
+ return 2;
+ }
+ gif_image_ptr->image_code_size = *code_size_ptr;
+ gif_ptr->_gif_record_current_position_fn(gif_ptr, &gif_image_ptr->image_data_pos);
+ gif_image_ptr->image_data_pos += gif_ptr->skip_size;
+ _gif_takeover_gce_ptr(gif_ptr, &gif_image_ptr->image_gce_ptr);
+ gif_ptr->img_ptr_arr_ptr->Add(gif_image_ptr);
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
+ return 1;
+}
+FX_INT32 _gif_load_frame(gif_decompress_struct_p gif_ptr, FX_INT32 frame_num)
+{
+ if(gif_ptr == NULL ||
+ frame_num < 0 ||
+ frame_num >= gif_ptr->img_ptr_arr_ptr->GetSize()
+ ) {
+ return 0;
+ }
+ FX_LPBYTE data_size_ptr = NULL;
+ FX_LPBYTE data_ptr = NULL;
+ FX_DWORD skip_size_org = gif_ptr->skip_size;
+ GifImage* gif_image_ptr = gif_ptr->img_ptr_arr_ptr->GetAt(frame_num);
+ FX_DWORD gif_img_row_bytes = gif_image_ptr->image_info_ptr->width;
+ if(gif_ptr->decode_status == GIF_D_STATUS_TAIL) {
+ if(gif_image_ptr->image_row_buf) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ gif_image_ptr->image_row_buf = NULL;
+ }
+ gif_image_ptr->image_row_buf = FX_Alloc(FX_BYTE, gif_img_row_bytes);
+ GIF_PTR_NOT_NULL(gif_image_ptr->image_row_buf, gif_ptr);
+ GifGCE* gif_img_gce_ptr = gif_image_ptr->image_gce_ptr;
+ FX_INT32 loc_pal_num = ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->local_pal ?
+ (2 << ((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->pal_bits) : 0;
+ gif_ptr->avail_in = 0;
+ if(gif_img_gce_ptr == NULL) {
+ FX_BOOL bRes = gif_ptr->_gif_get_record_position_fn(gif_ptr, gif_image_ptr->image_data_pos,
+ gif_image_ptr->image_info_ptr->left,
+ gif_image_ptr->image_info_ptr->top,
+ gif_image_ptr->image_info_ptr->width,
+ gif_image_ptr->image_info_ptr->height,
+ loc_pal_num, gif_image_ptr->local_pal_ptr,
+ 0, 0, -1, 0,
+ (FX_BOOL)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->interlace
+ );
+ if(!bRes) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ gif_image_ptr->image_row_buf = NULL;
+ _gif_error(gif_ptr, "Error Read Record Position Data");
+ return 0;
+ }
+ } else {
+ FX_BOOL bRes = gif_ptr->_gif_get_record_position_fn(gif_ptr, gif_image_ptr->image_data_pos,
+ gif_image_ptr->image_info_ptr->left,
+ gif_image_ptr->image_info_ptr->top,
+ gif_image_ptr->image_info_ptr->width,
+ gif_image_ptr->image_info_ptr->height,
+ loc_pal_num, gif_image_ptr->local_pal_ptr,
+ (FX_INT32)gif_image_ptr->image_gce_ptr->delay_time,
+ (FX_BOOL)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)->user_input,
+ ((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)->transparency ?
+ (FX_INT32)gif_image_ptr->image_gce_ptr->trans_index : -1,
+ (FX_INT32)((GifCEF*)&gif_image_ptr->image_gce_ptr->gce_flag)->disposal_method,
+ (FX_BOOL)((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->interlace
+ );
+ if(!bRes) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ gif_image_ptr->image_row_buf = NULL;
+ _gif_error(gif_ptr, "Error Read Record Position Data");
+ return 0;
+ }
+ }
+ if(gif_ptr->img_decoder_ptr == NULL) {
+ gif_ptr->img_decoder_ptr = FX_NEW CGifLZWDecoder(gif_ptr->err_ptr);
+ GIF_PTR_NOT_NULL(gif_ptr->img_decoder_ptr, gif_ptr);
+ }
+ gif_ptr->img_decoder_ptr->InitTable(gif_image_ptr->image_code_size);
+ gif_ptr->img_row_offset = 0;
+ gif_ptr->img_row_avail_size = 0;
+ gif_ptr->img_pass_num = 0;
+ gif_image_ptr->image_row_num = 0;
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
+ }
+ CGifLZWDecoder* img_decoder_ptr = gif_ptr->img_decoder_ptr;
+ if(gif_ptr->decode_status == GIF_D_STATUS_IMG_DATA) {
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ return 2;
+ }
+ if(*data_size_ptr != GIF_BLOCK_TERMINAL) {
+ if(_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ img_decoder_ptr->Input(data_ptr, *data_size_ptr);
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
+ gif_ptr->img_row_offset += gif_ptr->img_row_avail_size;
+ gif_ptr->img_row_avail_size = gif_img_row_bytes - gif_ptr->img_row_offset;
+ FX_INT32 ret = img_decoder_ptr->Decode(gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, gif_ptr->img_row_avail_size);
+ if(ret == 0) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ gif_image_ptr->image_row_buf = NULL;
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
+ _gif_error(gif_ptr, "Decode Image Data Error");
+ return 0;
+ }
+ while (ret != 0) {
+ if(ret == 1) {
+ gif_ptr->_gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num, gif_image_ptr->image_row_buf);
+ FX_Free(gif_image_ptr->image_row_buf);
+ gif_image_ptr->image_row_buf = NULL;
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
+ return 1;
+ }
+ if(ret == 2) {
+ ASSERT(img_decoder_ptr->GetAvailInput() == 0);
+ skip_size_org = gif_ptr->skip_size;
+ if(_gif_read_data(gif_ptr, &data_size_ptr, 1) == NULL) {
+ return 2;
+ }
+ if (*data_size_ptr != GIF_BLOCK_TERMINAL) {
+ if(_gif_read_data(gif_ptr, &data_ptr, *data_size_ptr) == NULL) {
+ gif_ptr->skip_size = skip_size_org;
+ return 2;
+ }
+ img_decoder_ptr->Input(data_ptr, *data_size_ptr);
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_IMG_DATA);
+ gif_ptr->img_row_offset += gif_ptr->img_row_avail_size;
+ gif_ptr->img_row_avail_size = gif_img_row_bytes - gif_ptr->img_row_offset;
+ ret = img_decoder_ptr->Decode(gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, gif_ptr->img_row_avail_size);
+ }
+ }
+ if(ret == 3) {
+ if(((GifLF*)&gif_image_ptr->image_info_ptr->local_flag)->interlace) {
+ gif_ptr->_gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num, gif_image_ptr->image_row_buf);
+ gif_image_ptr->image_row_num += s_gif_interlace_step[gif_ptr->img_pass_num];
+ if(gif_image_ptr->image_row_num >= (FX_INT32)gif_image_ptr->image_info_ptr->height) {
+ gif_ptr->img_pass_num++;
+ gif_image_ptr->image_row_num = s_gif_interlace_step[gif_ptr->img_pass_num] / 2;
+ }
+ } else {
+ gif_ptr->_gif_get_row_fn(gif_ptr, gif_image_ptr->image_row_num++, gif_image_ptr->image_row_buf);
+ }
+ gif_ptr->img_row_offset = 0;
+ gif_ptr->img_row_avail_size = gif_img_row_bytes;
+ ret = img_decoder_ptr->Decode(gif_image_ptr->image_row_buf + gif_ptr->img_row_offset, gif_ptr->img_row_avail_size);
+ }
+ if(ret == 0) {
+ FX_Free(gif_image_ptr->image_row_buf);
+ gif_image_ptr->image_row_buf = NULL;
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
+ _gif_error(gif_ptr, "Decode Image Data Error");
+ return 0;
+ }
+ }
+ }
+ _gif_save_decoding_status(gif_ptr, GIF_D_STATUS_TAIL);
+ }
+ _gif_error(gif_ptr, "Decode Image Data Error");
+ return 0;
+}
+void _gif_save_decoding_status(gif_decompress_struct_p gif_ptr, FX_INT32 status)
+{
+ gif_ptr->decode_status = status;
+ gif_ptr->next_in += gif_ptr->skip_size;
+ gif_ptr->avail_in -= gif_ptr->skip_size;
+ gif_ptr->skip_size = 0;
+}
+FX_LPBYTE _gif_read_data(gif_decompress_struct_p gif_ptr, FX_LPBYTE* des_buf_pp, FX_DWORD data_size)
+{
+ if(gif_ptr == NULL ||
+ gif_ptr->avail_in < gif_ptr->skip_size + data_size) {
+ return NULL;
+ }
+ *des_buf_pp = gif_ptr->next_in + gif_ptr->skip_size;
+ gif_ptr->skip_size += data_size;
+ return *des_buf_pp;
+}
+void _gif_input_buffer(gif_decompress_struct_p gif_ptr, FX_LPBYTE src_buf, FX_DWORD src_size)
+{
+ gif_ptr->next_in = src_buf;
+ gif_ptr->avail_in = src_size;
+ gif_ptr->skip_size = 0;
+}
+FX_DWORD _gif_get_avail_input(gif_decompress_struct_p gif_ptr, FX_LPBYTE* avial_buf_ptr)
+{
+ if(avial_buf_ptr != NULL) {
+ *avial_buf_ptr = NULL;
+ if(gif_ptr->avail_in > 0) {
+ *avial_buf_ptr = gif_ptr->next_in;
+ }
+ }
+ return gif_ptr->avail_in;
+}
+FX_INT32 _gif_get_frame_num(gif_decompress_struct_p gif_ptr)
+{
+ return gif_ptr->img_ptr_arr_ptr->GetSize();
+}
+static FX_BOOL _gif_write_header( gif_compress_struct_p gif_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_len )
+{
+ if (gif_ptr->cur_offset) {
+ return TRUE;
+ }
+ dst_len = sizeof(GifHeader) + sizeof(GifLSD) + sizeof(GifGF);
+ dst_buf = FX_AllocNL(FX_BYTE, dst_len);
+ if (dst_buf == NULL) {
+ return FALSE;
+ }
+ FXSYS_memset32(dst_buf, 0, dst_len);
+ FXSYS_memcpy32(dst_buf, gif_ptr->header_ptr, sizeof(GifHeader));
+ gif_ptr->cur_offset += sizeof(GifHeader);
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->width);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->lsd_ptr->height);
+ gif_ptr->cur_offset += 2;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->global_flag;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->bc_index;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->lsd_ptr->pixel_aspect;
+ if (gif_ptr->global_pal) {
+ FX_WORD size = sizeof(GifPalette) * gif_ptr->gpal_num;
+ if (!_gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + size)) {
+ return FALSE;
+ }
+ FXSYS_memcpy32(&dst_buf[gif_ptr->cur_offset], gif_ptr->global_pal, size);
+ gif_ptr->cur_offset += size;
+ }
+ return TRUE;
+}
+void interlace_buf(FX_LPCBYTE buf, FX_DWORD pitch, FX_DWORD height)
+{
+ CFX_ArrayTemplate<FX_LPBYTE> pass[4];
+ int i, j;
+ FX_DWORD row;
+ row = 0;
+ FX_LPBYTE temp;
+ while (row < height) {
+ if (row % 8 == 0) {
+ j = 0;
+ } else if (row % 4 == 0) {
+ j = 1;
+ } else if (row % 2 == 0) {
+ j = 2;
+ } else {
+ j = 3;
+ }
+ temp = FX_Alloc(FX_BYTE, pitch);
+ if (temp == NULL) {
+ return;
+ }
+ FXSYS_memcpy32(temp, &buf[pitch * row], pitch);
+ pass[j].Add(temp);
+ row ++;
+ }
+ for (i = 0, row = 0; i < 4; i++) {
+ for (j = 0; j < pass[i].GetSize(); j++, row++) {
+ FXSYS_memcpy32((FX_LPBYTE)&buf[pitch * row], pass[i].GetAt(j), pitch);
+ FX_Free(pass[i].GetAt(j));
+ }
+ }
+}
+static void _gif_write_block_data(FX_LPCBYTE src_buf, FX_DWORD src_len, FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& dst_offset)
+{
+ FX_DWORD src_offset = 0;
+ while (src_len > GIF_DATA_BLOCK) {
+ dst_buf[dst_offset++] = GIF_DATA_BLOCK;
+ FXSYS_memcpy32(&dst_buf[dst_offset], &src_buf[src_offset], GIF_DATA_BLOCK);
+ dst_offset += GIF_DATA_BLOCK;
+ src_offset += GIF_DATA_BLOCK;
+ src_len -= GIF_DATA_BLOCK;
+ }
+ dst_buf[dst_offset++] = (FX_BYTE)src_len;
+ FXSYS_memcpy32(&dst_buf[dst_offset], &src_buf[src_offset], src_len);
+ dst_offset += src_len;
+}
+static FX_BOOL _gif_write_data( gif_compress_struct_p gif_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_len )
+{
+ if (!_gif_grow_buf(dst_buf, dst_len, gif_ptr->cur_offset + GIF_DATA_BLOCK)) {
+ return FALSE;
+ }
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ if (FXSYS_memcmp32(gif_ptr->header_ptr->version, "89a", 3) == 0) {
+ dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION;
+ dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_GCE;
+ gif_ptr->gce_ptr->block_size = 4;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->block_size;
+ gif_ptr->gce_ptr->gce_flag = 0;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->gce_flag;
+ gif_ptr->gce_ptr->delay_time = 10;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->gce_ptr->delay_time);
+ gif_ptr->cur_offset += 2;
+ gif_ptr->gce_ptr->trans_index = 0;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->gce_ptr->trans_index;
+ dst_buf[gif_ptr->cur_offset++] = 0;
+ }
+#endif
+ dst_buf[gif_ptr->cur_offset++] = GIF_SIG_IMAGE;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->image_info_ptr->left);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->image_info_ptr->top);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->image_info_ptr->width);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->image_info_ptr->height);
+ gif_ptr->cur_offset += 2;
+ GifLF& lf = (GifLF&)gif_ptr->image_info_ptr->local_flag;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->image_info_ptr->local_flag;
+ if (gif_ptr->local_pal) {
+ FX_DWORD pal_size = sizeof(GifPalette) * gif_ptr->lpal_num;
+ if (!_gif_grow_buf(dst_buf, dst_len, pal_size + gif_ptr->cur_offset)) {
+ return FALSE;
+ }
+ FXSYS_memcpy32(&dst_buf[gif_ptr->cur_offset], gif_ptr->local_pal, pal_size);
+ gif_ptr->cur_offset += pal_size;
+ }
+ if (lf.interlace) {
+ interlace_buf(gif_ptr->src_buf, gif_ptr->src_pitch, gif_ptr->image_info_ptr->height);
+ }
+ FX_BYTE code_bit = lf.pal_bits;
+ if (lf.local_pal == 0) {
+ GifGF& gf = (GifGF&)gif_ptr->lsd_ptr->global_flag;
+ code_bit = gf.pal_bits;
+ }
+ gif_ptr->img_encoder_ptr->Start(code_bit, gif_ptr->src_buf, dst_buf, gif_ptr->cur_offset);
+ FX_DWORD i;
+ for (i = 0; i < gif_ptr->src_row; i++) {
+ if (!gif_ptr->img_encoder_ptr->Encode(&gif_ptr->src_buf[i * gif_ptr->src_pitch], gif_ptr->src_width * (code_bit + 1),
+ dst_buf, dst_len, gif_ptr->cur_offset)) {
+ return FALSE;
+ }
+ }
+ gif_ptr->img_encoder_ptr->Finish(dst_buf, dst_len, gif_ptr->cur_offset);
+ dst_buf[gif_ptr->cur_offset++] = 0;
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ if (FXSYS_memcmp32(gif_ptr->header_ptr->version, "89a", 3) == 0 && gif_ptr->cmt_data_ptr) {
+ dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION;
+ dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_CE;
+ _gif_write_block_data(gif_ptr->cmt_data_ptr, gif_ptr->cmt_data_len, dst_buf, dst_len, gif_ptr->cur_offset);
+ dst_buf[gif_ptr->cur_offset++] = 0;
+ }
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ if (FXSYS_memcmp32(gif_ptr->header_ptr->version, "89a", 3) == 0 && gif_ptr->pte_data_ptr) {
+ dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION;
+ dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_PTE;
+ dst_buf[gif_ptr->cur_offset++] = gif_ptr->pte_ptr->block_size;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->grid_left);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->grid_top);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->grid_width);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->grid_height);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->char_width);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->char_height);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->fc_index);
+ gif_ptr->cur_offset += 2;
+ _SetWord_LSBFirst(dst_buf + gif_ptr->cur_offset, gif_ptr->pte_ptr->bc_index);
+ gif_ptr->cur_offset += 2;
+ _gif_write_block_data(gif_ptr->pte_data_ptr, gif_ptr->pte_data_len, dst_buf, dst_len, gif_ptr->cur_offset);
+ gif_ptr->cur_offset += gif_ptr->pte_data_len;
+ dst_buf[gif_ptr->cur_offset++] = 0;
+ }
+#endif
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ if (FXSYS_memcmp32(gif_ptr->header_ptr->version, "89a", 3) == 0 && gif_ptr->app_data) {
+ dst_buf[gif_ptr->cur_offset++] = GIF_SIG_EXTENSION;
+ dst_buf[gif_ptr->cur_offset++] = GIF_BLOCK_AE;
+ dst_buf[gif_ptr->cur_offset++] = 11;
+ FXSYS_memcpy32(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_identify, 8);
+ gif_ptr->cur_offset += 8;
+ FXSYS_memcpy32(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_authentication, 8);
+ gif_ptr->cur_offset += 3;
+ FXSYS_memcpy32(&dst_buf[gif_ptr->cur_offset], gif_ptr->app_data, gif_ptr->app_data_size);
+ gif_ptr->cur_offset += gif_ptr->app_data_size;
+ dst_buf[gif_ptr->cur_offset++] = 0;
+ }
+#endif
+ dst_buf[gif_ptr->cur_offset++] = GIF_SIG_TRAILER;
+ return TRUE;
+}
+FX_BOOL _gif_encode( gif_compress_struct_p gif_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_len )
+{
+ if (!_gif_write_header(gif_ptr, dst_buf, dst_len)) {
+ return FALSE;
+ }
+ FX_DWORD cur_offset = gif_ptr->cur_offset;
+ FX_BOOL res = TRUE;
+ if (gif_ptr->frames) {
+ gif_ptr->cur_offset--;
+ }
+ if (!_gif_write_data(gif_ptr, dst_buf, dst_len)) {
+ gif_ptr->cur_offset = cur_offset;
+ res = FALSE;
+ }
+ dst_len = gif_ptr->cur_offset;
+ dst_buf[dst_len - 1] = GIF_SIG_TRAILER;
+ if (res) {
+ gif_ptr->frames++;
+ }
+ return res;
+}
diff --git a/core/src/fxcodec/lgif/fx_gif.h b/core/src/fxcodec/lgif/fx_gif.h
new file mode 100644
index 0000000000..b499a542b6
--- /dev/null
+++ b/core/src/fxcodec/lgif/fx_gif.h
@@ -0,0 +1,307 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_BASIC_H_
+#include "../../../include/fxcrt/fx_basic.h"
+#endif
+extern FX_WORD _GetWord_LSBFirst(FX_LPBYTE p);
+extern void _SetWord_LSBFirst(FX_LPBYTE p, FX_WORD v);
+extern void _BpcConvert(FX_LPCBYTE src_buf, FX_DWORD src_len, FX_INT32 src_bpc, FX_INT32 dst_bpc,
+ FX_LPBYTE& dst_buf, FX_DWORD& dst_len);
+#define GIF_SUPPORT_COMMENT_EXTENSION
+#define GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+#define GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+#define GIF_SIGNATURE "GIF"
+#define GIF_SIG_EXTENSION 0x21
+#define GIF_SIG_IMAGE 0x2C
+#define GIF_SIG_TRAILER 0x3B
+#define GIF_BLOCK_GCE 0xF9
+#define GIF_BLOCK_PTE 0x01
+#define GIF_BLOCK_CE 0xFE
+#define GIF_BLOCK_AE 0xFF
+#define GIF_BLOCK_TERMINAL 0x00
+#define GIF_MAX_LZW_CODE 4096
+#define GIF_DATA_BLOCK 255
+#define GIF_MAX_ERROR_SIZE 256
+#define GIF_D_STATUS_SIG 0x01
+#define GIF_D_STATUS_TAIL 0x02
+#define GIF_D_STATUS_EXT 0x03
+#define GIF_D_STATUS_EXT_AE 0x04
+#define GIF_D_STATUS_EXT_CE 0x05
+#define GIF_D_STATUS_EXT_GCE 0x06
+#define GIF_D_STATUS_EXT_PTE 0x07
+#define GIF_D_STATUS_EXT_UNE 0x08
+#define GIF_D_STATUS_IMG_INFO 0x09
+#define GIF_D_STATUS_IMG_DATA 0x0A
+#pragma pack(1)
+typedef struct tagGifGF {
+ FX_BYTE pal_bits : 3;
+ FX_BYTE sort_flag : 1;
+ FX_BYTE color_resolution : 3;
+ FX_BYTE global_pal : 1;
+} GifGF;
+typedef struct tagGifLF {
+ FX_BYTE pal_bits : 3;
+ FX_BYTE reserved : 2;
+ FX_BYTE sort_flag : 1;
+ FX_BYTE interlace : 1;
+ FX_BYTE local_pal : 1;
+} GifLF;
+typedef struct tagGifHeader {
+ char signature[3];
+ char version[3];
+} GifHeader;
+typedef struct tagGifLSD {
+ FX_WORD width;
+ FX_WORD height;
+ FX_BYTE global_flag;
+ FX_BYTE bc_index;
+ FX_BYTE pixel_aspect;
+} GifLSD;
+typedef struct tagGifImageInfo {
+ FX_WORD left;
+ FX_WORD top;
+ FX_WORD width;
+ FX_WORD height;
+
+ FX_BYTE local_flag;
+} GifImageInfo;
+typedef struct tagGifCEF {
+ FX_BYTE transparency : 1;
+ FX_BYTE user_input : 1;
+ FX_BYTE disposal_method : 3;
+ FX_BYTE reserved : 3;
+} GifCEF;
+typedef struct tagGifGCE {
+ FX_BYTE block_size;
+ FX_BYTE gce_flag;
+ FX_WORD delay_time;
+ FX_BYTE trans_index;
+} GifGCE;
+typedef struct tagGifPTE {
+ FX_BYTE block_size;
+ FX_WORD grid_left;
+ FX_WORD grid_top;
+ FX_WORD grid_width;
+ FX_WORD grid_height;
+
+ FX_BYTE char_width;
+ FX_BYTE char_height;
+
+ FX_BYTE fc_index;
+ FX_BYTE bc_index;
+} GifPTE;
+typedef struct tagGifAE {
+ FX_BYTE block_size;
+ FX_BYTE app_identify[8];
+ FX_BYTE app_authentication[3];
+} GifAE;
+typedef struct tagGifPalette {
+ FX_BYTE r, g, b;
+} GifPalette;
+#pragma pack()
+typedef struct tagGifImage {
+ GifGCE* image_gce_ptr;
+ GifPalette* local_pal_ptr;
+ GifImageInfo* image_info_ptr;
+ FX_BYTE image_code_size;
+ FX_DWORD image_data_pos;
+ FX_LPBYTE image_row_buf;
+ FX_INT32 image_row_num;
+} GifImage;
+typedef struct tagGifPlainText {
+ GifGCE* gce_ptr;
+ GifPTE* pte_ptr;
+ CFX_ByteString* string_ptr;
+} GifPlainText;
+class CGifLZWDecoder : public CFX_Object
+{
+public:
+ struct tag_Table {
+ FX_WORD prefix;
+ FX_BYTE suffix;
+ };
+ CGifLZWDecoder(FX_LPSTR error_ptr = NULL)
+ {
+ err_msg_ptr = error_ptr;
+ }
+ void InitTable(FX_BYTE code_len);
+
+ FX_INT32 Decode(FX_LPBYTE des_buf, FX_DWORD& des_size);
+
+ void Input(FX_LPBYTE src_buf, FX_DWORD src_size);
+ FX_DWORD GetAvailInput();
+
+private:
+ void ClearTable();
+ void AddCode(FX_WORD prefix_code, FX_BYTE append_char);
+ void DecodeString(FX_WORD code);
+ FX_BYTE code_size;
+ FX_BYTE code_size_cur;
+ FX_WORD code_clear;
+ FX_WORD code_end;
+ FX_WORD code_next;
+ FX_BYTE code_first;
+ FX_BYTE stack[GIF_MAX_LZW_CODE];
+ FX_WORD stack_size;
+ tag_Table code_table[GIF_MAX_LZW_CODE];
+ FX_WORD code_old;
+
+ FX_LPBYTE next_in;
+ FX_DWORD avail_in;
+
+ FX_BYTE bits_left;
+ FX_DWORD code_store;
+
+ FX_LPSTR err_msg_ptr;
+};
+class CGifLZWEncoder : public CFX_Object
+{
+public:
+ struct tag_Table {
+ FX_WORD prefix;
+ FX_BYTE suffix;
+ };
+ CGifLZWEncoder();
+ ~CGifLZWEncoder();
+ void Start(FX_BYTE code_len, FX_LPCBYTE src_buf, FX_LPBYTE& dst_buf, FX_DWORD& offset);
+ FX_BOOL Encode(FX_LPCBYTE src_buf, FX_DWORD src_len, FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset);
+ void Finish(FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset);
+private:
+ void ClearTable();
+ FX_BOOL LookUpInTable(FX_LPCBYTE buf, FX_DWORD& offset, FX_BYTE& bit_offset);
+ void EncodeString(FX_DWORD index, FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset);
+ void WriteBlock(FX_LPBYTE& dst_buf, FX_DWORD& dst_len, FX_DWORD& offset);
+ jmp_buf jmp;
+ FX_DWORD src_offset;
+ FX_BYTE src_bit_offset;
+ FX_BYTE src_bit_cut;
+ FX_DWORD src_bit_num;
+ FX_BYTE code_size;
+ FX_WORD code_clear;
+ FX_WORD code_end;
+ FX_WORD index_num;
+ FX_BYTE bit_offset;
+ FX_BYTE index_bit_cur;
+ FX_BYTE index_buf[GIF_DATA_BLOCK];
+ FX_BYTE index_buf_len;
+ tag_Table code_table[GIF_MAX_LZW_CODE];
+ FX_WORD table_cur;
+};
+typedef struct tag_gif_decompress_struct gif_decompress_struct;
+typedef gif_decompress_struct *gif_decompress_struct_p;
+typedef gif_decompress_struct_p *gif_decompress_struct_pp;
+static FX_INT32 s_gif_interlace_step[4] = {8, 8, 4, 2};
+struct tag_gif_decompress_struct {
+ jmp_buf jmpbuf;
+ FX_LPSTR err_ptr;
+ void (*_gif_error_fn)(gif_decompress_struct_p gif_ptr, FX_LPCSTR err_msg);
+ void* context_ptr;
+ int width;
+ int height;
+ GifPalette* global_pal_ptr;
+ FX_INT32 global_pal_num;
+ FX_BYTE global_sort_flag;
+ FX_BYTE global_color_resolution;
+
+ FX_BYTE bc_index;
+ FX_BYTE pixel_aspect;
+ CGifLZWDecoder* img_decoder_ptr;
+ FX_DWORD img_row_offset;
+ FX_DWORD img_row_avail_size;
+ FX_BYTE img_pass_num;
+ CFX_ArrayTemplate<GifImage*>* img_ptr_arr_ptr;
+ FX_LPBYTE (*_gif_ask_buf_for_pal_fn)(gif_decompress_struct_p gif_ptr, FX_INT32 pal_size);
+ FX_LPBYTE next_in;
+ FX_DWORD avail_in;
+ FX_INT32 decode_status;
+ FX_DWORD skip_size;
+ void (*_gif_record_current_position_fn)(gif_decompress_struct_p gif_ptr, FX_DWORD* cur_pos_ptr);
+ void (*_gif_get_row_fn)(gif_decompress_struct_p gif_ptr, FX_INT32 row_num, FX_LPBYTE row_buf);
+ FX_BOOL (*_gif_get_record_position_fn)(gif_decompress_struct_p gif_ptr, FX_DWORD cur_pos,
+ FX_INT32 left, FX_INT32 top, FX_INT32 width, FX_INT32 height,
+ FX_INT32 pal_num, void* pal_ptr,
+ FX_INT32 delay_time, FX_BOOL user_input,
+ FX_INT32 trans_index, FX_INT32 disposal_method, FX_BOOL interlace);
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ FX_BYTE app_identify[8];
+ FX_BYTE app_authentication[3];
+ FX_DWORD app_data_size;
+ FX_LPBYTE app_data;
+#endif
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ CFX_ByteString* cmt_data_ptr;
+#endif
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ GifGCE* gce_ptr;
+#endif
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ CFX_ArrayTemplate<GifPlainText*>* pt_ptr_arr_ptr;
+#endif
+};
+typedef struct tag_gif_compress_struct gif_compress_struct;
+typedef gif_compress_struct *gif_compress_struct_p;
+typedef gif_compress_struct_p *gif_compress_struct_pp;
+struct tag_gif_compress_struct {
+ FX_LPCBYTE src_buf;
+ FX_DWORD src_pitch;
+ FX_DWORD src_width;
+ FX_DWORD src_row;
+ FX_DWORD cur_offset;
+ FX_DWORD frames;
+ GifHeader* header_ptr;
+ GifLSD* lsd_ptr;
+ GifPalette* global_pal;
+ FX_WORD gpal_num;
+ GifPalette* local_pal;
+ FX_WORD lpal_num;
+ GifImageInfo* image_info_ptr;
+ CGifLZWEncoder* img_encoder_ptr;
+#ifdef GIF_SUPPORT_APPLICATION_EXTENSION
+ FX_BYTE app_identify[8];
+ FX_BYTE app_authentication[3];
+ FX_DWORD app_data_size;
+ FX_LPBYTE app_data;
+#endif
+
+#ifdef GIF_SUPPORT_COMMENT_EXTENSION
+ FX_LPBYTE cmt_data_ptr;
+ FX_DWORD cmt_data_len;
+#endif
+
+#ifdef GIF_SUPPORT_GRAPHIC_CONTROL_EXTENSION
+ GifGCE* gce_ptr;
+#endif
+
+#ifdef GIF_SUPPORT_PLAIN_TEXT_EXTENSION
+ GifPTE* pte_ptr;
+ FX_LPCBYTE pte_data_ptr;
+ FX_DWORD pte_data_len;
+#endif
+};
+void _gif_error(gif_decompress_struct_p gif_ptr, FX_LPCSTR err_msg);
+void _gif_warn(gif_decompress_struct_p gif_ptr, FX_LPCSTR err_msg);
+gif_decompress_struct_p _gif_create_decompress();
+void _gif_destroy_decompress(gif_decompress_struct_pp gif_ptr_ptr);
+gif_compress_struct_p _gif_create_compress();
+void _gif_destroy_compress(gif_compress_struct_pp gif_ptr_ptr);
+FX_INT32 _gif_read_header(gif_decompress_struct_p gif_ptr);
+FX_INT32 _gif_get_frame(gif_decompress_struct_p gif_ptr);
+FX_INT32 _gif_get_frame_num(gif_decompress_struct_p gif_ptr);
+FX_INT32 _gif_decode_extension(gif_decompress_struct_p gif_ptr);
+FX_INT32 _gif_decode_image_info(gif_decompress_struct_p gif_ptr);
+void _gif_takeover_gce_ptr(gif_decompress_struct_p gif_ptr, GifGCE** gce_ptr_ptr);
+FX_INT32 _gif_load_frame(gif_decompress_struct_p gif_ptr, FX_INT32 frame_num);
+FX_LPBYTE _gif_read_data(gif_decompress_struct_p gif_ptr, FX_LPBYTE* des_buf_pp, FX_DWORD data_size);
+void _gif_save_decoding_status(gif_decompress_struct_p gif_ptr, FX_INT32 status);
+void _gif_input_buffer(gif_decompress_struct_p gif_ptr, FX_LPBYTE src_buf, FX_DWORD src_size);
+FX_DWORD _gif_get_avail_input(gif_decompress_struct_p gif_ptr, FX_LPBYTE* avial_buf_ptr);
+void interlace_buf(FX_LPCBYTE buf, FX_DWORD width, FX_DWORD height);
+FX_BOOL _gif_encode( gif_compress_struct_p gif_ptr, FX_LPBYTE& dst_buf, FX_DWORD& dst_len );
+#define GIF_PTR_NOT_NULL(ptr,gif_ptr) if(ptr == NULL){ \
+ _gif_error(gif_ptr,"Out Of Memory");\
+ return 0; \
+ }
diff --git a/core/src/fxcrt/extension.h b/core/src/fxcrt/extension.h
index c23a2e3369..05aad67e40 100644
--- a/core/src/fxcrt/extension.h
+++ b/core/src/fxcrt/extension.h
@@ -26,6 +26,44 @@ public:
virtual FX_BOOL Truncate(FX_FILESIZE szFile) = 0;
};
IFXCRT_FileAccess* FXCRT_FileAccess_Create();
+class CFX_CRTFileAccess : public IFX_FileAccess, public CFX_Object
+{
+public:
+ CFX_CRTFileAccess() : m_RefCount(0) {}
+
+ virtual void Release()
+ {
+ if (--m_RefCount == 0)
+ delete this;
+ }
+
+ IFX_FileAccess* Retain()
+ {
+ m_RefCount++;
+ return (IFX_FileAccess*)this;
+ }
+
+ virtual FX_BOOL Init(FX_WSTR wsPath)
+ {
+ m_path = wsPath;
+ m_RefCount = 1;
+ return TRUE;
+ }
+
+ virtual void GetPath(CFX_WideString& wsPath)
+ {
+ wsPath = m_path;
+ }
+
+ virtual IFX_FileStream* CreateFileStream(FX_DWORD dwModes)
+ {
+ return FX_CreateFileStream(m_path, dwModes);
+ }
+
+protected:
+ CFX_WideString m_path;
+ FX_DWORD m_RefCount;
+};
class CFX_CRTFileStream FX_FINAL : public IFX_FileStream, public CFX_Object
{
public:
diff --git a/core/src/fxcrt/fx_arabic.cpp b/core/src/fxcrt/fx_arabic.cpp
index 583ce817cf..dd5d1d81bd 100644
--- a/core/src/fxcrt/fx_arabic.cpp
+++ b/core/src/fxcrt/fx_arabic.cpp
@@ -7,6 +7,1084 @@
#include "../../include/fxcrt/fx_ext.h"
#include "fx_arabic.h"
extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
+#ifdef __cplusplus
+extern "C" {
+#endif
+static const FX_ARBFORMTABLE g_FX_ArabicFormTables[] = {
+ {0xFE81, 0xFE82, 0xFE81, 0xFE82},
+ {0xFE83, 0xFE84, 0xFE83, 0xFE84},
+ {0xFE85, 0xFE86, 0xFE85, 0xFE86},
+ {0xFE87, 0xFE88, 0xFE87, 0xFE88},
+ {0xFE89, 0xFE8A, 0xFE8B, 0xFE8C},
+ {0xFE8D, 0xFE8E, 0xFE8D, 0xFE8E},
+ {0xFE8F, 0xFE90, 0xFE91, 0xFE92},
+ {0xFE93, 0xFE94, 0xFE93, 0xFE94},
+ {0xFE95, 0xFE96, 0xFE97, 0xFE98},
+ {0xFE99, 0xFE9A, 0xFE9B, 0xFE9C},
+ {0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0},
+ {0xFEA1, 0xFEA2, 0xFEA3, 0xFEA4},
+ {0xFEA5, 0xFEA6, 0xFEA7, 0xFEA8},
+ {0xFEA9, 0xFEAA, 0xFEA9, 0xFEAA},
+ {0xFEAB, 0xFEAC, 0xFEAB, 0xFEAC},
+ {0xFEAD, 0xFEAE, 0xFEAD, 0xFEAE},
+ {0xFEAF, 0xFEB0, 0xFEAF, 0xFEB0},
+ {0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4},
+ {0xFEB5, 0xFEB6, 0xFEB7, 0xFEB8},
+ {0xFEB9, 0xFEBA, 0xFEBB, 0xFEBC},
+ {0xFEBD, 0xFEBE, 0xFEBF, 0xFEC0},
+ {0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4},
+ {0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8},
+ {0xFEC9, 0xFECA, 0xFECB, 0xFECC},
+ {0xFECD, 0xFECE, 0xFECF, 0xFED0},
+ {0x063B, 0x063B, 0x063B, 0x063B},
+ {0x063C, 0x063C, 0x063C, 0x063C},
+ {0x063D, 0x063D, 0x063D, 0x063D},
+ {0x063E, 0x063E, 0x063E, 0x063E},
+ {0x063F, 0x063F, 0x063F, 0x063F},
+ {0x0640, 0x0640, 0x0640, 0x0640},
+ {0xFED1, 0xFED2, 0xFED3, 0xFED4},
+ {0xFED5, 0xFED6, 0xFED7, 0xFED8},
+ {0xFED9, 0xFEDA, 0xFEDB, 0xFEDC},
+ {0xFEDD, 0xFEDE, 0xFEDF, 0xFEE0},
+ {0xFEE1, 0xFEE2, 0xFEE3, 0xFEE4},
+ {0xFEE5, 0xFEE6, 0xFEE7, 0xFEE8},
+ {0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC},
+ {0xFEED, 0xFEEE, 0xFEED, 0xFEEE},
+ {0xFEEF, 0xFEF0, 0xFBFE, 0xFBFF},
+ {0xFEF1, 0xFEF2, 0xFEF3, 0xFEF4},
+ {0x064B, 0x064B, 0x064B, 0x064B},
+ {0x064C, 0x064C, 0x064C, 0x064C},
+ {0x064D, 0x064D, 0x064D, 0x064D},
+ {0x064E, 0x064E, 0x064E, 0x064E},
+ {0x064F, 0x064F, 0x064F, 0x064F},
+ {0x0650, 0x0650, 0x0650, 0x0650},
+ {0x0651, 0x0651, 0x0651, 0x0651},
+ {0x0652, 0x0652, 0x0652, 0x0652},
+ {0x0653, 0x0653, 0x0653, 0x0653},
+ {0x0654, 0x0654, 0x0654, 0x0654},
+ {0x0655, 0x0655, 0x0655, 0x0655},
+ {0x0656, 0x0656, 0x0656, 0x0656},
+ {0x0657, 0x0657, 0x0657, 0x0657},
+ {0x0658, 0x0658, 0x0658, 0x0658},
+ {0x0659, 0x0659, 0x0659, 0x0659},
+ {0x065A, 0x065A, 0x065A, 0x065A},
+ {0x065B, 0x065B, 0x065B, 0x065B},
+ {0x065C, 0x065C, 0x065C, 0x065C},
+ {0x065D, 0x065D, 0x065D, 0x065D},
+ {0x065E, 0x065E, 0x065E, 0x065E},
+ {0x065F, 0x065F, 0x065F, 0x065F},
+ {0x0660, 0x0660, 0x0660, 0x0660},
+ {0x0661, 0x0661, 0x0661, 0x0661},
+ {0x0662, 0x0662, 0x0662, 0x0662},
+ {0x0663, 0x0663, 0x0663, 0x0663},
+ {0x0664, 0x0664, 0x0664, 0x0664},
+ {0x0665, 0x0665, 0x0665, 0x0665},
+ {0x0666, 0x0666, 0x0666, 0x0666},
+ {0x0667, 0x0667, 0x0667, 0x0667},
+ {0x0668, 0x0668, 0x0668, 0x0668},
+ {0x0669, 0x0669, 0x0669, 0x0669},
+ {0x066A, 0x066A, 0x066A, 0x066A},
+ {0x066B, 0x066B, 0x066B, 0x066B},
+ {0x066C, 0x066C, 0x066C, 0x066C},
+ {0x066D, 0x066D, 0x066D, 0x066D},
+ {0x066E, 0x066E, 0x066E, 0x066E},
+ {0x066F, 0x066F, 0x066F, 0x066F},
+ {0x0670, 0x0670, 0x0670, 0x0670},
+ {0xFB50, 0xFB51, 0xFB50, 0xFB51},
+ {0x0672, 0x0672, 0x0672, 0x0672},
+ {0x0673, 0x0673, 0x0673, 0x0673},
+ {0x0674, 0x0674, 0x0674, 0x0674},
+ {0x0675, 0x0675, 0x0675, 0x0675},
+ {0x0676, 0x0676, 0x0676, 0x0676},
+ {0x0677, 0x0677, 0x0677, 0x0677},
+ {0x0678, 0x0678, 0x0678, 0x0678},
+ {0xFB66, 0xFB67, 0xFB68, 0xFB69},
+ {0xFB5E, 0xFB5F, 0xFB60, 0xFB61},
+ {0xFB52, 0xFB53, 0xFB54, 0xFB55},
+ {0x067C, 0x067C, 0x067C, 0x067C},
+ {0x067D, 0x067D, 0x067D, 0x067D},
+ {0xFB56, 0xFB57, 0xFB58, 0xFB59},
+ {0xFB62, 0xFB63, 0xFB64, 0xFB65},
+ {0xFB5A, 0xFB5B, 0xFB5C, 0xFB5D},
+ {0x0681, 0x0681, 0x0681, 0x0681},
+ {0x0682, 0x0682, 0x0682, 0x0682},
+ {0xFB76, 0xFB77, 0xFB78, 0xFB79},
+ {0xFB72, 0xFB73, 0xFB74, 0xFB75},
+ {0x0685, 0x0685, 0x0685, 0x0685},
+ {0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D},
+ {0xFB7E, 0xFB7F, 0xFB80, 0xFB81},
+ {0xFB88, 0xFB89, 0xFB88, 0xFB89},
+ {0x0689, 0x0689, 0x0689, 0x0689},
+ {0x068A, 0x068A, 0x068A, 0x068A},
+ {0x068B, 0x068B, 0x068B, 0x068B},
+ {0xFB84, 0xFB85, 0xFB84, 0xFB85},
+ {0xFB82, 0xFB83, 0xFB82, 0xFB83},
+ {0xFB86, 0xFB87, 0xFB86, 0xFB87},
+ {0x068F, 0x068F, 0x068F, 0x068F},
+ {0x0690, 0x0690, 0x0690, 0x0690},
+ {0xFB8C, 0xFB8D, 0xFB8C, 0xFB8D},
+ {0x0692, 0x0692, 0x0692, 0x0692},
+ {0x0693, 0x0693, 0x0693, 0x0693},
+ {0x0694, 0x0694, 0x0694, 0x0694},
+ {0x0695, 0x0695, 0x0695, 0x0695},
+ {0x0696, 0x0696, 0x0696, 0x0696},
+ {0x0697, 0x0697, 0x0697, 0x0697},
+ {0xFB8A, 0xFB8B, 0xFB8A, 0xFB8B},
+ {0x0699, 0x0699, 0x0699, 0x0699},
+ {0x069A, 0x069A, 0x069A, 0x069A},
+ {0x069B, 0x069B, 0x069B, 0x069B},
+ {0x069C, 0x069C, 0x069C, 0x069C},
+ {0x069D, 0x069D, 0x069D, 0x069D},
+ {0x069E, 0x069E, 0x069E, 0x069E},
+ {0x069F, 0x069F, 0x069F, 0x069F},
+ {0x06A0, 0x06A0, 0x06A0, 0x06A0},
+ {0x06A1, 0x06A1, 0x06A1, 0x06A1},
+ {0x06A2, 0x06A2, 0x06A2, 0x06A2},
+ {0x06A3, 0x06A3, 0x06A3, 0x06A3},
+ {0xFB6A, 0xFB6B, 0xFB6C, 0xFB6D},
+ {0x06A5, 0x06A5, 0x06A5, 0x06A5},
+ {0xFB6E, 0xFB6F, 0xFB70, 0xFB71},
+ {0x06A7, 0x06A7, 0x06A7, 0x06A7},
+ {0x06A8, 0x06A8, 0x06A8, 0x06A8},
+ {0xFB8E, 0xFB8F, 0xFB90, 0xFB91},
+ {0x06AA, 0x06AA, 0x06AA, 0x06AA},
+ {0x06AB, 0x06AB, 0x06AB, 0x06AB},
+ {0x06AC, 0x06AC, 0x06AC, 0x06AC},
+ {0xFBD3, 0xFBD4, 0xFBD5, 0xFBD6},
+ {0x06AE, 0x06AE, 0x06AE, 0x06AE},
+ {0xFB92, 0xFB93, 0xFB94, 0xFB95},
+ {0x06B0, 0x06B0, 0x06B0, 0x06B0},
+ {0xFB9A, 0xFB9B, 0xFB9C, 0xFB9D},
+ {0x06B2, 0x06B2, 0x06B2, 0x06B2},
+ {0xFB96, 0xFB97, 0xFB98, 0xFB99},
+ {0x06B4, 0x06B4, 0x06B4, 0x06B4},
+ {0x06B5, 0x06B5, 0x06B5, 0x06B5},
+ {0x06B6, 0x06B6, 0x06B6, 0x06B6},
+ {0x06B7, 0x06B7, 0x06B7, 0x06B7},
+ {0x06B8, 0x06B8, 0x06B8, 0x06B8},
+ {0x06B9, 0x06B9, 0x06B9, 0x06B9},
+ {0xFB9E, 0xFB9F, 0xFBE8, 0xFBE9},
+ {0xFBA0, 0xFBA1, 0xFBA2, 0xFBA3},
+ {0x06BC, 0x06BC, 0x06BC, 0x06BC},
+ {0x06BD, 0x06BD, 0x06BD, 0x06BD},
+ {0xFBAA, 0xFBAB, 0xFBAC, 0xFBAD},
+ {0x06BF, 0x06BF, 0x06BF, 0x06BF},
+ {0xFBA4, 0xFBA5, 0xFBA4, 0xFBA5},
+ {0xFBA6, 0xFBA7, 0xFBA8, 0xFBA9},
+ {0x06C2, 0x06C2, 0x06C2, 0x06C2},
+ {0x06C3, 0x06C3, 0x06C3, 0x06C3},
+ {0x06C4, 0x06C4, 0x06C4, 0x06C4},
+ {0xFBE0, 0xFBE1, 0xFBE0, 0xFBE1},
+ {0xFBD9, 0xFBDA, 0xFBD9, 0xFBDA},
+ {0xFBD7, 0xFBD8, 0xFBD7, 0xFBD8},
+ {0xFBDB, 0xFBDC, 0xFBDB, 0xFBDC},
+ {0xFBE2, 0xFBE3, 0xFBE2, 0xFBE3},
+ {0x06CA, 0x06CA, 0x06CA, 0x06CA},
+ {0xFBDE, 0xFBDF, 0xFBDE, 0xFBDF},
+ {0xFBFC, 0xFBFD, 0xFBFE, 0xFBFF},
+ {0x06CD, 0x06CD, 0x06CD, 0x06CD},
+ {0x06CE, 0x06CE, 0x06CE, 0x06CE},
+ {0x06CF, 0x06CF, 0x06CF, 0x06CF},
+ {0xFBE4, 0xFBE5, 0xFBE6, 0xFBE7},
+ {0x06D1, 0x06D1, 0x06D1, 0x06D1},
+ {0xFBAE, 0xFBAF, 0xFBAE, 0xFBAF},
+ {0xFBB0, 0xFBB1, 0xFBB0, 0xFBB1},
+ {0x06D4, 0x06D4, 0x06D4, 0x06D4},
+ {0x06D5, 0x06D5, 0x06D5, 0x06D5},
+};
+static const FX_ARAALEF gs_FX_AlefTable[] = {
+ {0x0622, 0xFEF5},
+ {0x0623, 0xFEF7},
+ {0x0625, 0xFEF9},
+ {0x0627, 0xFEFB},
+};
+static const FX_ARASHADDA gs_FX_ShaddaTable[] = {
+ {0x064C, 0xFC5E},
+ {0x064D, 0xFC5F},
+ {0x064E, 0xFC60},
+ {0x064F, 0xFC61},
+ {0x0650, 0xFC62},
+};
+FX_LPCARBFORMTABLE FX_GetArabicFormTable(FX_WCHAR unicode)
+{
+ if (unicode < 0x622 || unicode > 0x6d5) {
+ return NULL;
+ }
+ return g_FX_ArabicFormTables + unicode - 0x622;
+}
+FX_WCHAR FX_GetArabicFromAlefTable(FX_WCHAR alef)
+{
+ static const FX_INT32 s_iAlefCount = sizeof(gs_FX_AlefTable) / sizeof(FX_ARAALEF);
+ for (FX_INT32 iStart = 0; iStart < s_iAlefCount; iStart ++) {
+ const FX_ARAALEF &v = gs_FX_AlefTable[iStart];
+ if (v.wAlef == alef) {
+ return v.wIsolated;
+ }
+ }
+ return alef;
+}
+FX_WCHAR FX_GetArabicFromShaddaTable(FX_WCHAR shadda)
+{
+ static const FX_INT32 s_iShaddaCount = sizeof(gs_FX_ShaddaTable) / sizeof(FX_ARASHADDA);
+ for (FX_INT32 iStart = 0; iStart < s_iShaddaCount; iStart ++) {
+ const FX_ARASHADDA &v = gs_FX_ShaddaTable[iStart];
+ if (v.wShadda == shadda) {
+ return v.wIsolated;
+ }
+ }
+ return shadda;
+}
+#ifdef __cplusplus
+};
+#endif
+IFX_ArabicChar* IFX_ArabicChar::Create()
+{
+ return FX_NEW CFX_ArabicChar;
+}
+FX_BOOL CFX_ArabicChar::IsArabicChar(FX_WCHAR wch) const
+{
+ FX_DWORD dwRet = (gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & FX_CHARTYPEBITSMASK);
+ return dwRet >= FX_CHARTYPE_ArabicAlef;
+}
+FX_BOOL CFX_ArabicChar::IsArabicFormChar(FX_WCHAR wch) const
+{
+ return (gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_ArabicForm;
+}
+FX_WCHAR CFX_ArabicChar::GetFormChar(FX_WCHAR wch, FX_WCHAR prev, FX_WCHAR next) const
+{
+ CFX_Char c(wch, gs_FX_TextLayout_CodeProperties[(FX_WORD)wch]);
+ CFX_Char p(prev, gs_FX_TextLayout_CodeProperties[(FX_WORD)prev]);
+ CFX_Char n(next, gs_FX_TextLayout_CodeProperties[(FX_WORD)next]);
+ return GetFormChar(&c, &p, &n);
+}
+FX_WCHAR CFX_ArabicChar::GetFormChar(const CFX_Char *cur, const CFX_Char *prev, const CFX_Char *next) const
+{
+ FX_CHARTYPE eCur;
+ FX_WCHAR wCur;
+ FX_LPCARBFORMTABLE ft = ParseChar(cur, wCur, eCur);
+ if (eCur < FX_CHARTYPE_ArabicAlef || eCur >= FX_CHARTYPE_ArabicNormal) {
+ return wCur;
+ }
+ FX_CHARTYPE ePrev;
+ FX_WCHAR wPrev;
+ ParseChar(prev, wPrev, ePrev);
+ if (wPrev == 0x0644 && eCur == FX_CHARTYPE_ArabicAlef) {
+ return 0xFEFF;
+ }
+ FX_CHARTYPE eNext;
+ FX_WCHAR wNext;
+ ParseChar(next, wNext, eNext);
+ FX_BOOL bAlef = (eNext == FX_CHARTYPE_ArabicAlef && wCur == 0x644);
+ if (ePrev < FX_CHARTYPE_ArabicAlef) {
+ if (bAlef) {
+ return FX_GetArabicFromAlefTable(wNext);
+ } else {
+ return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wIsolated : ft->wInitial;
+ }
+ } else {
+ if (bAlef) {
+ wCur = FX_GetArabicFromAlefTable(wNext);
+ return (ePrev != FX_CHARTYPE_ArabicDistortion) ? wCur : ++ wCur;
+ } else if (ePrev == FX_CHARTYPE_ArabicAlef || ePrev == FX_CHARTYPE_ArabicSpecial) {
+ return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wIsolated : ft->wInitial;
+ } else {
+ return (eNext < FX_CHARTYPE_ArabicAlef) ? ft->wFinal : ft->wMedial;
+ }
+ }
+}
+FX_LPCARBFORMTABLE CFX_ArabicChar::ParseChar(const CFX_Char *pTC, FX_WCHAR &wChar, FX_CHARTYPE &eType) const
+{
+ if (pTC == NULL) {
+ eType = FX_CHARTYPE_Unknown;
+ wChar = 0xFEFF;
+ return NULL;
+ }
+ eType = (FX_CHARTYPE)pTC->GetCharType();
+ wChar = (FX_WCHAR)pTC->m_wCharCode;
+ FX_LPCARBFORMTABLE pFT = FX_GetArabicFormTable(wChar);
+ if (pFT == NULL || eType >= FX_CHARTYPE_ArabicNormal) {
+ eType = FX_CHARTYPE_Unknown;
+ }
+ return pFT;
+}
+void FX_BidiReverseString(CFX_WideString &wsText, FX_INT32 iStart, FX_INT32 iCount)
+{
+ FXSYS_assert(iStart > -1 && iStart < wsText.GetLength());
+ FXSYS_assert(iCount >= 0 && iStart + iCount <= wsText.GetLength());
+ FX_WCHAR wch;
+ FX_LPWSTR pStart = (FX_LPWSTR)(FX_LPCWSTR)wsText;
+ pStart += iStart;
+ FX_LPWSTR pEnd = pStart + iCount - 1;
+ while (pStart < pEnd) {
+ wch = *pStart;
+ *pStart ++ = *pEnd;
+ *pEnd -- = wch;
+ }
+}
+void FX_BidiSetDeferredRun(CFX_Int32Array &values, FX_INT32 iStart, FX_INT32 iCount, FX_INT32 iValue)
+{
+ FXSYS_assert(iStart > -1 && iStart <= values.GetSize());
+ FXSYS_assert(iStart - iCount > -1);
+ for (FX_INT32 i = iStart - 1; i >= iStart - iCount; i --) {
+ values.SetAt(i, iValue);
+ }
+}
+const FX_INT32 gc_FX_BidiNTypes[] = {
+ FX_BIDICLASS_N,
+ FX_BIDICLASS_L,
+ FX_BIDICLASS_R,
+ FX_BIDICLASS_AN,
+ FX_BIDICLASS_EN,
+ FX_BIDICLASS_AL,
+ FX_BIDICLASS_NSM,
+ FX_BIDICLASS_CS,
+ FX_BIDICLASS_ES,
+ FX_BIDICLASS_ET,
+ FX_BIDICLASS_BN,
+ FX_BIDICLASS_BN,
+ FX_BIDICLASS_N,
+ FX_BIDICLASS_B,
+ FX_BIDICLASS_RLO,
+ FX_BIDICLASS_RLE,
+ FX_BIDICLASS_LRO,
+ FX_BIDICLASS_LRE,
+ FX_BIDICLASS_PDF,
+ FX_BIDICLASS_ON,
+};
+void FX_BidiClassify(const CFX_WideString &wsText, CFX_Int32Array &classes, FX_BOOL bWS)
+{
+ FXSYS_assert(wsText.GetLength() == classes.GetSize());
+ FX_INT32 iCount = wsText.GetLength();
+ FX_LPCWSTR pwsStart = (FX_LPCWSTR)wsText;
+ FX_WCHAR wch;
+ FX_INT32 iCls;
+ if (bWS) {
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ wch = *pwsStart ++;
+ iCls = ((gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS);
+ classes.SetAt(i, iCls);
+ }
+ } else {
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ wch = *pwsStart ++;
+ iCls = ((gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS);
+ classes.SetAt(i, gc_FX_BidiNTypes[iCls]);
+ }
+ }
+}
+FX_INT32 FX_BidiResolveExplicit(FX_INT32 iBaseLevel, FX_INT32 iDirection, CFX_Int32Array &classes, CFX_Int32Array &levels, FX_INT32 iStart, FX_INT32 iCount, FX_INT32 iNest)
+{
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL && iNest >= 0);
+ FXSYS_assert(classes.GetSize() == levels.GetSize());
+ FXSYS_assert(iStart >= 0 && iStart < classes.GetSize());
+ FXSYS_assert(iCount >= 0 && iStart + iCount <= classes.GetSize());
+ if (iCount < 1) {
+ return 0;
+ }
+#if 0
+ FX_INT32 iLastNest = iNest;
+#endif
+ FX_INT32 iSize = classes.GetSize();
+ FX_INT32 i = iStart, iCur, iCls;
+ for (; i < iSize && iCount > 0; i ++, iCount --) {
+ iCur = iCls = classes.GetAt(i);
+#if 0
+ switch (iCls) {
+ case FX_BIDICLASS_LRO:
+ case FX_BIDICLASS_LRE:
+ classes.SetAt(i, FX_BIDICLASS_BN);
+ iCls = FX_BIDICLASS_BN;
+ iNest ++;
+ if (FX_BidiGreaterEven(iBaseLevel) <= MAX_LEVEL) {
+ FX_INT32 iLevel = FX_BidiGreaterEven(iBaseLevel);
+ levels.SetAt(i, iLevel);
+ i += FX_BidiResolveExplicit(iLevel,
+ (iCls == FX_BIDICLASS_LRE ? FX_BIDICLASS_N : FX_BIDICLASS_L),
+ classes,
+ levels,
+ i + 1,
+ iCount - 1,
+ iNest);
+ iNest --;
+ continue;
+ }
+ break;
+ case FX_BIDICLASS_RLO:
+ case FX_BIDICLASS_RLE:
+ classes.SetAt(i, FX_BIDICLASS_BN);
+ iCls = FX_BIDICLASS_BN;
+ iNest ++;
+ if (FX_BidiGreaterOdd(iBaseLevel) <= MAX_LEVEL) {
+ FX_INT32 iLevel = FX_BidiGreaterOdd(iBaseLevel);
+ levels.SetAt(i, iLevel);
+ i += FX_BidiResolveExplicit(iLevel,
+ (iCls == FX_BIDICLASS_RLE ? FX_BIDICLASS_N : FX_BIDICLASS_R),
+ classes,
+ levels,
+ i + 1,
+ iCount - 1,
+ iNest);
+ iNest --;
+ continue;
+ }
+ break;
+ case FX_BIDICLASS_PDF:
+ classes.SetAt(i, FX_BIDICLASS_BN);
+ iCls = FX_BIDICLASS_BN;
+ if (iNest) {
+ if (iLastNest < iNest) {
+ iNest --;
+ } else {
+ iSize = i;
+ }
+ }
+ break;
+ }
+ iCur = iCls;
+#endif
+ if (iDirection != FX_BIDICLASS_N) {
+ iCls = iDirection;
+ }
+ if (iCur != FX_BIDICLASS_BN) {
+ classes.SetAt(i, iCls);
+ }
+ levels.SetAt(i, iBaseLevel);
+ }
+ return i - iStart;
+}
+const FX_INT32 gc_FX_BidiWeakStates[][10] = {
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSxa, FX_BWSao, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSxr, FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSxl, FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao, FX_BWSao, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro, FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo, FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSrt, FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlt, FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWScn, FX_BWSac, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSra, FX_BWSrc, FX_BWSro, FX_BWSrt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSre, FX_BWSrs, FX_BWSrs, FX_BWSret},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSla, FX_BWSlc, FX_BWSlo, FX_BWSlt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSle, FX_BWSls, FX_BWSls, FX_BWSlet},
+ {FX_BWSao, FX_BWSxl, FX_BWSxr, FX_BWScn, FX_BWScn, FX_BWSxa, FX_BWSao, FX_BWSao, FX_BWSao, FX_BWSao},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro, FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSro, FX_BWSro, FX_BWSro, FX_BWSrt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo, FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlo, FX_BWSlo, FX_BWSlo, FX_BWSlt},
+ {FX_BWSro, FX_BWSxl, FX_BWSxr, FX_BWSra, FX_BWSre, FX_BWSxa, FX_BWSret, FX_BWSro, FX_BWSro, FX_BWSret},
+ {FX_BWSlo, FX_BWSxl, FX_BWSxr, FX_BWSla, FX_BWSle, FX_BWSxa, FX_BWSlet, FX_BWSlo, FX_BWSlo, FX_BWSlet},
+};
+const FX_INT32 gc_FX_BidiWeakActions[][10] = {
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR, FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR, FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR, FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR, FX_BWAxxN, FX_BWAxxN, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR, FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR, FX_BWAxIx, FX_BWANxN, FX_BWANxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxA, FX_BWAxxR, FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxxN},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR, FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR, FX_BWAxxE, FX_BWAxIx, FX_BWAxIx, FX_BWAxxE},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR, FX_BWAxxA, FX_BWAxIx, FX_BWAxxN, FX_BWAxIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR, FX_BWAxxL, FX_BWAxIx, FX_BWAxIx, FX_BWAxxL},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWAAxA, FX_BWANxR, FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANxN},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxE, FX_BWANxR, FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAExE, FX_BWANxR, FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWAAxx, FX_BWANxL, FX_BWANxR, FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWANxx, FX_BWALxL, FX_BWANxR, FX_BWANxN, FX_BWANxN, FX_BWANxN, FX_BWANIx},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxE, FX_BWAxxR, FX_BWAxxE, FX_BWAxxN, FX_BWAxxN, FX_BWAxxE},
+ {FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxx, FX_BWAxxL, FX_BWAxxR, FX_BWAxxL, FX_BWAxxN, FX_BWAxxN, FX_BWAxxL},
+};
+void FX_BidiResolveWeak(FX_INT32 iBaseLevel, CFX_Int32Array &classes, CFX_Int32Array &levels)
+{
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ FXSYS_assert(classes.GetSize() == levels.GetSize());
+ FX_INT32 iSize = classes.GetSize();
+ if (iSize < 1) {
+ return;
+ }
+ iSize --;
+ FX_INT32 iLevelCur = iBaseLevel;
+ FX_INT32 iState = FX_IsOdd(iBaseLevel) ? FX_BWSxr : FX_BWSxl;
+ FX_INT32 i = 0, iCount = 0, iClsCur, iClsRun, iClsNew, iAction;
+ for (; i <= iSize; i ++) {
+ iClsCur = classes.GetAt(i);
+#if 0
+ if (iClsCur == FX_BIDICLASS_BN) {
+ levels.SetAt(i, iLevelCur);
+ if (i == iSize && iLevelCur != iBaseLevel) {
+ iClsCur = FX_BidiDirection(iLevelCur);
+ classes.SetAt(i, iClsCur);
+ } else if (i < iSize) {
+ FX_INT32 iLevelNext, iLevelNew;
+ iClsNew = classes.GetAt(i + 1);
+ iLevelNext = levels.GetAt(i + 1);
+ if (iClsNew != FX_BIDICLASS_BN && iLevelCur != iLevelNext) {
+ iLevelNew = iLevelNext;
+ if (iLevelCur > iLevelNew) {
+ iLevelNew = iLevelCur;
+ }
+ levels.SetAt(i, iLevelNew);
+ iClsCur = FX_BidiDirection(iLevelNew);
+ classes.SetAt(i, iClsCur);
+ iLevelCur = iLevelNext;
+ } else {
+ if (iCount) {
+ iCount ++;
+ }
+ continue;
+ }
+ } else {
+ if (iCount) {
+ iCount ++;
+ }
+ continue;
+ }
+ }
+#endif
+ FXSYS_assert(iClsCur <= FX_BIDICLASS_BN);
+ iAction = gc_FX_BidiWeakActions[iState][iClsCur];
+ iClsRun = FX_BidiGetDeferredType(iAction);
+ if (iClsRun != FX_BIDIWEAKACTION_XX && iCount > 0) {
+ FX_BidiSetDeferredRun(classes, i, iCount, iClsRun);
+ iCount = 0;
+ }
+ iClsNew = FX_BidiGetResolvedType(iAction);
+ if (iClsNew != FX_BIDIWEAKACTION_XX) {
+ classes.SetAt(i, iClsNew);
+ }
+ if (FX_BIDIWEAKACTION_IX & iAction) {
+ iCount ++;
+ }
+ iState = gc_FX_BidiWeakStates[iState][iClsCur];
+ }
+ iClsCur = FX_BidiDirection(iLevelCur);
+ iClsRun = FX_BidiGetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
+ if (iClsRun != FX_BIDIWEAKACTION_XX && iCount > 0) {
+ FX_BidiSetDeferredRun(classes, i, iCount, iClsRun);
+ }
+}
+const FX_INT32 gc_FX_BidiNeutralStates[][5] = {
+ {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
+ {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+ {FX_BNSrn, FX_BNSl, FX_BNSr, FX_BNSr, FX_BNSr},
+ {FX_BNSln, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+ {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+ {FX_BNSna, FX_BNSl, FX_BNSr, FX_BNSa, FX_BNSl},
+};
+const FX_INT32 gc_FX_BidiNeutralActions[][5] = {
+ {FX_BNAIn, 0, 0, 0, 0 },
+ {FX_BNAIn, 0, 0, 0, FX_BCL },
+ {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNARn },
+ {FX_BNAIn, FX_BNALn, FX_BNAEn, FX_BNAEn, FX_BNALnL },
+ {FX_BNAIn, 0, 0, 0, FX_BCL },
+ {FX_BNAIn, FX_BNAEn, FX_BNARn, FX_BNARn, FX_BNAEn },
+};
+FX_INT32 FX_BidiGetDeferredNeutrals(FX_INT32 iAction, FX_INT32 iLevel)
+{
+ iAction = (iAction >> 4) & 0xF;
+ if (iAction == (FX_BIDINEUTRALACTION_En >> 4)) {
+ return FX_BidiDirection(iLevel);
+ } else {
+ return iAction;
+ }
+}
+FX_INT32 FX_BidiGetResolvedNeutrals(FX_INT32 iAction)
+{
+ iAction = (iAction & 0xF);
+ if (iAction == FX_BIDINEUTRALACTION_In) {
+ return 0;
+ } else {
+ return iAction;
+ }
+}
+void FX_BidiResolveNeutrals(FX_INT32 iBaseLevel, CFX_Int32Array &classes, const CFX_Int32Array &levels)
+{
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ FXSYS_assert(classes.GetSize() == levels.GetSize());
+ FX_INT32 iSize = classes.GetSize();
+ if (iSize < 1) {
+ return;
+ }
+ iSize --;
+ FX_INT32 iLevel = iBaseLevel;
+ FX_INT32 iState = FX_IsOdd(iBaseLevel) ? FX_BNSr : FX_BNSl;
+ FX_INT32 i = 0, iCount = 0, iClsCur, iClsRun, iClsNew, iAction;
+ for (; i <= iSize; i ++) {
+ iClsCur = classes.GetAt(i);
+ if (iClsCur == FX_BIDICLASS_BN) {
+ if (iCount) {
+ iCount ++;
+ }
+ continue;
+ }
+ FXSYS_assert(iClsCur < FX_BIDICLASS_AL);
+ iAction = gc_FX_BidiNeutralActions[iState][iClsCur];
+ iClsRun = FX_BidiGetDeferredNeutrals(iAction, iLevel);
+ if (iClsRun != FX_BIDICLASS_N && iCount > 0) {
+ FX_BidiSetDeferredRun(classes, i, iCount, iClsRun);
+ iCount = 0;
+ }
+ iClsNew = FX_BidiGetResolvedNeutrals(iAction);
+ if (iClsNew != FX_BIDICLASS_N) {
+ classes.SetAt(i, iClsNew);
+ }
+ if (FX_BIDINEUTRALACTION_In & iAction) {
+ iCount ++;
+ }
+ iState = gc_FX_BidiNeutralStates[iState][iClsCur];
+ iLevel = levels.GetAt(i);
+ }
+ iClsCur = FX_BidiDirection(iLevel);
+ iClsRun = FX_BidiGetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur], iLevel);
+ if (iClsRun != FX_BIDICLASS_N && iCount > 0) {
+ FX_BidiSetDeferredRun(classes, i, iCount, iClsRun);
+ }
+}
+const FX_INT32 gc_FX_BidiAddLevel[][4] = {
+ {0, 1, 2, 2},
+ {1, 0, 1, 1},
+};
+void FX_BidiResolveImplicit(const CFX_Int32Array &classes, CFX_Int32Array &levels)
+{
+ FXSYS_assert(classes.GetSize() == levels.GetSize());
+ FX_INT32 iSize = classes.GetSize();
+ if (iSize < 1) {
+ return;
+ }
+ iSize --;
+ FX_INT32 iCls, iLevel;
+ for (FX_INT32 i = 0; i <= iSize; i ++) {
+ iCls = classes.GetAt(i);
+ if (iCls == FX_BIDICLASS_BN) {
+ continue;
+ }
+ FXSYS_assert(iCls > FX_BIDICLASS_ON && iCls < FX_BIDICLASS_AL);
+ iLevel = levels.GetAt(i);
+ iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
+ levels.SetAt(i, iLevel);
+ }
+}
+void FX_BidiResolveWhitespace(FX_INT32 iBaseLevel, const CFX_Int32Array &classes, CFX_Int32Array &levels)
+{
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ FXSYS_assert(classes.GetSize() == levels.GetSize());
+ FX_INT32 iSize = classes.GetSize();
+ if (iSize < 1) {
+ return;
+ }
+ iSize --;
+ FX_INT32 iLevel = iBaseLevel;
+ FX_INT32 i = 0, iCount = 0;
+ for (; i <= iSize; i ++) {
+ switch(classes.GetAt(i)) {
+ case FX_BIDICLASS_WS:
+ iCount ++;
+ break;
+ case FX_BIDICLASS_RLE:
+ case FX_BIDICLASS_LRE:
+ case FX_BIDICLASS_LRO:
+ case FX_BIDICLASS_RLO:
+ case FX_BIDICLASS_PDF:
+ case FX_BIDICLASS_BN:
+ levels.SetAt(i, iLevel);
+ iCount ++;
+ break;
+ case FX_BIDICLASS_S:
+ case FX_BIDICLASS_B:
+ if (iCount > 0) {
+ FX_BidiSetDeferredRun(levels, i, iCount, iBaseLevel);
+ }
+ levels.SetAt(i, iBaseLevel);
+ iCount = 0;
+ break;
+ default:
+ iCount = 0;
+ break;
+ }
+ iLevel = levels.GetAt(i);
+ }
+ if (iCount > 0) {
+ FX_BidiSetDeferredRun(levels, i, iCount, iBaseLevel);
+ }
+}
+FX_INT32 FX_BidiReorderLevel(FX_INT32 iBaseLevel, CFX_WideString &wsText, const CFX_Int32Array &levels, FX_INT32 iStart, FX_BOOL bReverse)
+{
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ FXSYS_assert(wsText.GetLength() == levels.GetSize());
+ FXSYS_assert(iStart >= 0 && iStart < wsText.GetLength());
+ FX_INT32 iSize = wsText.GetLength();
+ if (iSize < 1) {
+ return 0;
+ }
+ bReverse = bReverse || FX_IsOdd(iBaseLevel);
+ FX_INT32 i = iStart, iLevel;
+ for (; i < iSize; i ++) {
+ if ((iLevel = levels.GetAt(i)) == iBaseLevel) {
+ continue;
+ }
+ if (iLevel < iBaseLevel) {
+ break;
+ }
+ i += FX_BidiReorderLevel(iBaseLevel + 1, wsText, levels, i, bReverse) - 1;
+ }
+ FX_INT32 iCount = i - iStart;
+ if (bReverse && iCount > 1) {
+ FX_BidiReverseString(wsText, iStart, iCount);
+ }
+ return iCount;
+}
+void FX_BidiReorder(FX_INT32 iBaseLevel, CFX_WideString &wsText, const CFX_Int32Array &levels)
+{
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ FXSYS_assert(wsText.GetLength() == levels.GetSize());
+ FX_INT32 iSize = wsText.GetLength();
+ if (iSize < 1) {
+ return;
+ }
+ FX_INT32 i = 0;
+ while (i < iSize) {
+ i += FX_BidiReorderLevel(iBaseLevel, wsText, levels, i, FALSE);
+ }
+}
+void FX_BidiLine(CFX_WideString &wsText, FX_INT32 iBaseLevel)
+{
+ FX_INT32 iLength = wsText.GetLength();
+ if (iLength < 2) {
+ return;
+ }
+ CFX_Int32Array classes, levels;
+ classes.SetAtGrow(iLength - 1, 0);
+ levels.SetAtGrow(iLength - 1, 0);
+ FX_BidiClassify(wsText, classes, FALSE);
+ FX_BidiResolveExplicit(iBaseLevel, FX_BIDICLASS_N, classes, levels, 0, iLength, 0);
+ FX_BidiResolveWeak(iBaseLevel, classes, levels);
+ FX_BidiResolveNeutrals(iBaseLevel, classes, levels);
+ FX_BidiResolveImplicit(classes, levels);
+ FX_BidiClassify(wsText, classes, TRUE);
+ FX_BidiResolveWhitespace(iBaseLevel, classes, levels);
+ FX_BidiReorder(iBaseLevel, wsText, levels);
+ classes.RemoveAll();
+ levels.RemoveAll();
+}
+template<class baseType>
+class CFX_BidiLineTemplate
+{
+public:
+ void FX_BidiReverseString(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iStart, FX_INT32 iCount)
+ {
+ FXSYS_assert(iStart > -1 && iStart < chars.GetSize());
+ FXSYS_assert(iCount >= 0 && iStart + iCount <= chars.GetSize());
+ baseType *pStart, *pEnd;
+ FX_INT32 iEnd = iStart + iCount - 1, iTemp;
+ while (iStart < iEnd) {
+ pStart = chars.GetDataPtr(iStart ++);
+ pEnd = chars.GetDataPtr(iEnd --);
+ iTemp = pStart->m_iBidiPos;
+ pStart->m_iBidiPos = pEnd->m_iBidiPos;
+ pEnd->m_iBidiPos = iTemp;
+ }
+ }
+ void FX_BidiSetDeferredRun(CFX_ArrayTemplate<baseType> &chars, FX_BOOL bClass, FX_INT32 iStart, FX_INT32 iCount, FX_INT32 iValue)
+ {
+ FXSYS_assert(iStart > -1 && iStart <= chars.GetSize());
+ FXSYS_assert(iStart - iCount > -1);
+ baseType *pTC;
+ FX_INT32 iLast = iStart - iCount;
+ if (bClass) {
+ for (FX_INT32 i = iStart - 1; i >= iLast; i --) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiClass = (FX_INT16)iValue;
+ }
+ } else {
+ for (FX_INT32 i = iStart - 1; i >= iLast; i --) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiLevel = (FX_INT16)iValue;
+ }
+ }
+ }
+ void FX_BidiClassify(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_BOOL bWS)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ baseType *pTC;
+ if (bWS) {
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiClass = (FX_INT16)(pTC->m_dwCharProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
+ }
+ } else {
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiClass = (FX_INT16)gc_FX_BidiNTypes[(pTC->m_dwCharProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS];
+ }
+ }
+ }
+ void FX_BidiResolveExplicit(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ if (iCount < 1) {
+ return;
+ }
+ baseType *pTC;
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiLevel = (FX_INT16)iBaseLevel;
+ }
+ }
+ void FX_BidiResolveWeak(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ iCount --;
+ if (iCount < 1) {
+ return;
+ }
+ baseType *pTC, *pTCNext;
+ FX_INT32 iLevelCur = iBaseLevel;
+ FX_INT32 iState = FX_IsOdd(iBaseLevel) ? FX_BWSxr : FX_BWSxl;
+ FX_INT32 i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction;
+ for (; i <= iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ iClsCur = pTC->m_iBidiClass;
+ if (iClsCur == FX_BIDICLASS_BN) {
+ pTC->m_iBidiLevel = (FX_INT16)iLevelCur;
+ if (i == iCount && iLevelCur != iBaseLevel) {
+ iClsCur = FX_BidiDirection(iLevelCur);
+ pTC->m_iBidiClass = (FX_INT16)iClsCur;
+ } else if (i < iCount) {
+ pTCNext = chars.GetDataPtr(i + 1);
+ FX_INT32 iLevelNext, iLevelNew;
+ iClsNew = pTCNext->m_iBidiClass;
+ iLevelNext = pTCNext->m_iBidiLevel;
+ if (iClsNew != FX_BIDICLASS_BN && iLevelCur != iLevelNext) {
+ iLevelNew = iLevelNext;
+ if (iLevelCur > iLevelNew) {
+ iLevelNew = iLevelCur;
+ }
+ pTC->m_iBidiLevel = (FX_INT16)iLevelNew;
+ iClsCur = FX_BidiDirection(iLevelNew);
+ pTC->m_iBidiClass = (FX_INT16)iClsCur;
+ iLevelCur = iLevelNext;
+ } else {
+ if (iNum > 0) {
+ iNum ++;
+ }
+ continue;
+ }
+ } else {
+ if (iNum > 0) {
+ iNum ++;
+ }
+ continue;
+ }
+ }
+ FXSYS_assert(iClsCur <= FX_BIDICLASS_BN);
+ iAction = gc_FX_BidiWeakActions[iState][iClsCur];
+ iClsRun = FX_BidiGetDeferredType(iAction);
+ if (iClsRun != FX_BIDIWEAKACTION_XX && iNum > 0) {
+ FX_BidiSetDeferredRun(chars, TRUE, i, iNum, iClsRun);
+ iNum = 0;
+ }
+ iClsNew = FX_BidiGetResolvedType(iAction);
+ if (iClsNew != FX_BIDIWEAKACTION_XX) {
+ pTC->m_iBidiClass = (FX_INT16)iClsNew;
+ }
+ if (FX_BIDIWEAKACTION_IX & iAction) {
+ iNum ++;
+ }
+ iState = gc_FX_BidiWeakStates[iState][iClsCur];
+ }
+ if (iNum > 0) {
+ iClsCur = FX_BidiDirection(iBaseLevel);
+ iClsRun = FX_BidiGetDeferredType(gc_FX_BidiWeakActions[iState][iClsCur]);
+ if (iClsRun != FX_BIDIWEAKACTION_XX) {
+ FX_BidiSetDeferredRun(chars, TRUE, i, iNum, iClsRun);
+ }
+ }
+ }
+ void FX_BidiResolveNeutrals(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ iCount --;
+ if (iCount < 1) {
+ return;
+ }
+ baseType *pTC;
+ FX_INT32 iLevel = iBaseLevel;
+ FX_INT32 iState = FX_IsOdd(iBaseLevel) ? FX_BNSr : FX_BNSl;
+ FX_INT32 i = 0, iNum = 0, iClsCur, iClsRun, iClsNew, iAction;
+ for (; i <= iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ iClsCur = pTC->m_iBidiClass;
+ if (iClsCur == FX_BIDICLASS_BN) {
+ if (iNum) {
+ iNum ++;
+ }
+ continue;
+ }
+ FXSYS_assert(iClsCur < FX_BIDICLASS_AL);
+ iAction = gc_FX_BidiNeutralActions[iState][iClsCur];
+ iClsRun = FX_BidiGetDeferredNeutrals(iAction, iLevel);
+ if (iClsRun != FX_BIDICLASS_N && iNum > 0) {
+ FX_BidiSetDeferredRun(chars, TRUE, i, iNum, iClsRun);
+ iNum = 0;
+ }
+ iClsNew = FX_BidiGetResolvedNeutrals(iAction);
+ if (iClsNew != FX_BIDICLASS_N) {
+ pTC->m_iBidiClass = (FX_INT16)iClsNew;
+ }
+ if (FX_BIDINEUTRALACTION_In & iAction) {
+ iNum ++;
+ }
+ iState = gc_FX_BidiNeutralStates[iState][iClsCur];
+ iLevel = pTC->m_iBidiLevel;
+ }
+ if (iNum > 0) {
+ iClsCur = FX_BidiDirection(iLevel);
+ iClsRun = FX_BidiGetDeferredNeutrals(gc_FX_BidiNeutralActions[iState][iClsCur], iLevel);
+ if (iClsRun != FX_BIDICLASS_N) {
+ FX_BidiSetDeferredRun(chars, TRUE, i, iNum, iClsRun);
+ }
+ }
+ }
+ void FX_BidiResolveImplicit(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ baseType *pTC;
+ FX_INT32 iCls, iLevel;
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ iCls = pTC->m_iBidiClass;
+ if (iCls == FX_BIDICLASS_BN) {
+ continue;
+ }
+ FXSYS_assert(iCls > FX_BIDICLASS_ON && iCls < FX_BIDICLASS_AL);
+ iLevel = pTC->m_iBidiLevel;
+ iLevel += gc_FX_BidiAddLevel[FX_IsOdd(iLevel)][iCls - 1];
+ pTC->m_iBidiLevel = (FX_INT16)iLevel;
+ }
+ }
+ void FX_BidiResolveWhitespace(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ if (iCount < 1) {
+ return;
+ }
+ iCount --;
+ FX_INT32 iLevel = iBaseLevel;
+ FX_INT32 i = 0, iNum = 0;
+ baseType *pTC;
+ for (; i <= iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ switch(pTC->m_iBidiClass) {
+ case FX_BIDICLASS_WS:
+ iNum ++;
+ break;
+ case FX_BIDICLASS_RLE:
+ case FX_BIDICLASS_LRE:
+ case FX_BIDICLASS_LRO:
+ case FX_BIDICLASS_RLO:
+ case FX_BIDICLASS_PDF:
+ case FX_BIDICLASS_BN:
+ pTC->m_iBidiLevel = (FX_INT16)iLevel;
+ iNum ++;
+ break;
+ case FX_BIDICLASS_S:
+ case FX_BIDICLASS_B:
+ if (iNum > 0) {
+ FX_BidiSetDeferredRun(chars, FALSE, i, iNum, iBaseLevel);
+ }
+ pTC->m_iBidiLevel = (FX_INT16)iBaseLevel;
+ iNum = 0;
+ break;
+ default:
+ iNum = 0;
+ break;
+ }
+ iLevel = pTC->m_iBidiLevel;
+ }
+ if (iNum > 0) {
+ FX_BidiSetDeferredRun(chars, FALSE, i, iNum, iBaseLevel);
+ }
+ }
+ FX_INT32 FX_BidiReorderLevel(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_INT32 iBaseLevel, FX_INT32 iStart, FX_BOOL bReverse)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ FXSYS_assert(iStart >= 0 && iStart < iCount);
+ if (iCount < 1) {
+ return 0;
+ }
+ baseType *pTC;
+ bReverse = bReverse || FX_IsOdd(iBaseLevel);
+ FX_INT32 i = iStart, iLevel;
+ for (; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ if ((iLevel = pTC->m_iBidiLevel) == iBaseLevel) {
+ continue;
+ }
+ if (iLevel < iBaseLevel) {
+ break;
+ }
+ i += FX_BidiReorderLevel(chars, iCount, iBaseLevel + 1, i, bReverse) - 1;
+ }
+ FX_INT32 iNum = i - iStart;
+ if (bReverse && iNum > 1) {
+ FX_BidiReverseString(chars, iStart, iNum);
+ }
+ return iNum;
+ }
+ void FX_BidiReorder(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ FXSYS_assert(iBaseLevel >= 0 && iBaseLevel <= FX_BIDIMAXLEVEL);
+ FX_INT32 i = 0;
+ while (i < iCount) {
+ i += FX_BidiReorderLevel(chars, iCount, iBaseLevel, i, FALSE);
+ }
+ }
+ void FX_BidiPosition(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ baseType *pTC;
+ FX_INT32 i = 0;
+ while (i < iCount) {
+ pTC = chars.GetDataPtr(i);
+ pTC = chars.GetDataPtr(pTC->m_iBidiPos);
+ pTC->m_iBidiOrder = i ++;
+ }
+ }
+
+ void FX_BidiLine(CFX_ArrayTemplate<baseType> &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+ {
+ FXSYS_assert(iCount > -1 && iCount <= chars.GetSize());
+ if (iCount < 2) {
+ return;
+ }
+ FX_BidiClassify(chars, iCount, FALSE);
+ FX_BidiResolveExplicit(chars, iCount, iBaseLevel);
+ FX_BidiResolveWeak(chars, iCount, iBaseLevel);
+ FX_BidiResolveNeutrals(chars, iCount, iBaseLevel);
+ FX_BidiResolveImplicit(chars, iCount);
+ FX_BidiClassify(chars, iCount, TRUE);
+ FX_BidiResolveWhitespace(chars, iCount, iBaseLevel);
+ FX_BidiReorder(chars, iCount, iBaseLevel);
+ FX_BidiPosition(chars, iCount);
+ }
+};
+void FX_BidiLine(CFX_TxtCharArray &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+{
+ CFX_BidiLineTemplate<CFX_TxtChar> blt;
+ blt.FX_BidiLine(chars, iCount, iBaseLevel);
+}
+void FX_BidiLine(CFX_RTFCharArray &chars, FX_INT32 iCount, FX_INT32 iBaseLevel)
+{
+ CFX_BidiLineTemplate<CFX_RTFChar> blt;
+ blt.FX_BidiLine(chars, iCount, iBaseLevel);
+}
IFX_BidiChar* IFX_BidiChar::Create()
{
return FX_NEW CFX_BidiChar;
diff --git a/core/src/fxcrt/fx_arabic.h b/core/src/fxcrt/fx_arabic.h
index c404449af0..e44bfb8142 100644
--- a/core/src/fxcrt/fx_arabic.h
+++ b/core/src/fxcrt/fx_arabic.h
@@ -6,7 +6,180 @@
#ifndef _FX_ARABIC_IMP
#define _FX_ARABIC_IMP
-class CFX_BidiChar FX_FINAL : public IFX_BidiChar, public CFX_Object
+typedef struct _FX_ARABICCHARRANGE {
+ FX_WCHAR wStart;
+ FX_WCHAR wEnd;
+} FX_ARABICCHARRANGE;
+class CFX_ArabicChar : public IFX_ArabicChar, public CFX_Object
+{
+public:
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_BOOL IsArabicChar(FX_WCHAR wch) const;
+ virtual FX_BOOL IsArabicFormChar(FX_WCHAR wch) const;
+
+ virtual FX_WCHAR GetFormChar(FX_WCHAR wch, FX_WCHAR prev = 0, FX_WCHAR next = 0) const;
+ virtual FX_WCHAR GetFormChar(const CFX_Char *cur, const CFX_Char *prev, const CFX_Char *next) const;
+protected:
+ FX_LPCARBFORMTABLE ParseChar(const CFX_Char *pTC, FX_WCHAR &wChar, FX_CHARTYPE &eType) const;
+};
+void FX_BidiReverseString(CFX_WideString &wsText, FX_INT32 iStart, FX_INT32 iCount);
+void FX_BidiSetDeferredRun(CFX_Int32Array &values, FX_INT32 iStart, FX_INT32 iCount, FX_INT32 iValue);
+#define FX_BCON FX_BIDICLASS_ON
+#define FX_BCL FX_BIDICLASS_L
+#define FX_BCR FX_BIDICLASS_R
+#define FX_BCAN FX_BIDICLASS_AN
+#define FX_BCEN FX_BIDICLASS_EN
+#define FX_BCAL FX_BIDICLASS_AL
+#define FX_BCNSM FX_BIDICLASS_NSM
+#define FX_BCCS FX_BIDICLASS_CS
+#define FX_BCES FX_BIDICLASS_ES
+#define FX_BCET FX_BIDICLASS_ET
+#define FX_BCBN FX_BIDICLASS_BN
+#define FX_BCS FX_BIDICLASS_S
+#define FX_BCWS FX_BIDICLASS_WS
+#define FX_BCB FX_BIDICLASS_B
+#define FX_BCRLO FX_BIDICLASS_RLO
+#define FX_BCRLE FX_BIDICLASS_RLE
+#define FX_BCLRO FX_BIDICLASS_LRO
+#define FX_BCLRE FX_BIDICLASS_LRE
+#define FX_BCPDF FX_BIDICLASS_PDF
+#define FX_BCN FX_BIDICLASS_N
+void FX_BidiClassify(const CFX_WideString &wsText, CFX_Int32Array &classes, FX_BOOL bWS = FALSE);
+#define FX_BIDIMAXLEVEL 61
+#define FX_BidiGreaterEven(a) (FX_IsOdd(a) ? ((a) + 1) : ((a) + 2))
+#define FX_BidiGreaterOdd(a) (FX_IsOdd(a) ? ((a) + 2) : ((a) + 1))
+FX_INT32 FX_BidiResolveExplicit(FX_INT32 iBaseLevel, FX_INT32 iDirection, CFX_Int32Array &classes, CFX_Int32Array &levels, FX_INT32 iStart, FX_INT32 iCount, FX_INT32 iNest = 0);
+#define FX_BidiDirection(a) (FX_IsOdd(a) ? FX_BIDICLASS_R : FX_BIDICLASS_L)
+enum FX_BIDIWEAKSTATE {
+ FX_BIDIWEAKSTATE_xa = 0,
+ FX_BIDIWEAKSTATE_xr,
+ FX_BIDIWEAKSTATE_xl,
+ FX_BIDIWEAKSTATE_ao,
+ FX_BIDIWEAKSTATE_ro,
+ FX_BIDIWEAKSTATE_lo,
+ FX_BIDIWEAKSTATE_rt,
+ FX_BIDIWEAKSTATE_lt,
+ FX_BIDIWEAKSTATE_cn,
+ FX_BIDIWEAKSTATE_ra,
+ FX_BIDIWEAKSTATE_re,
+ FX_BIDIWEAKSTATE_la,
+ FX_BIDIWEAKSTATE_le,
+ FX_BIDIWEAKSTATE_ac,
+ FX_BIDIWEAKSTATE_rc,
+ FX_BIDIWEAKSTATE_rs,
+ FX_BIDIWEAKSTATE_lc,
+ FX_BIDIWEAKSTATE_ls,
+ FX_BIDIWEAKSTATE_ret,
+ FX_BIDIWEAKSTATE_let,
+};
+#define FX_BWSxa FX_BIDIWEAKSTATE_xa
+#define FX_BWSxr FX_BIDIWEAKSTATE_xr
+#define FX_BWSxl FX_BIDIWEAKSTATE_xl
+#define FX_BWSao FX_BIDIWEAKSTATE_ao
+#define FX_BWSro FX_BIDIWEAKSTATE_ro
+#define FX_BWSlo FX_BIDIWEAKSTATE_lo
+#define FX_BWSrt FX_BIDIWEAKSTATE_rt
+#define FX_BWSlt FX_BIDIWEAKSTATE_lt
+#define FX_BWScn FX_BIDIWEAKSTATE_cn
+#define FX_BWSra FX_BIDIWEAKSTATE_ra
+#define FX_BWSre FX_BIDIWEAKSTATE_re
+#define FX_BWSla FX_BIDIWEAKSTATE_la
+#define FX_BWSle FX_BIDIWEAKSTATE_le
+#define FX_BWSac FX_BIDIWEAKSTATE_ac
+#define FX_BWSrc FX_BIDIWEAKSTATE_rc
+#define FX_BWSrs FX_BIDIWEAKSTATE_rs
+#define FX_BWSlc FX_BIDIWEAKSTATE_lc
+#define FX_BWSls FX_BIDIWEAKSTATE_ls
+#define FX_BWSret FX_BIDIWEAKSTATE_ret
+#define FX_BWSlet FX_BIDIWEAKSTATE_let
+enum FX_BIDIWEAKACTION {
+ FX_BIDIWEAKACTION_IX = 0x100,
+ FX_BIDIWEAKACTION_XX = 0x0F,
+ FX_BIDIWEAKACTION_xxx = (0x0F << 4) + 0x0F,
+ FX_BIDIWEAKACTION_xIx = 0x100 + FX_BIDIWEAKACTION_xxx,
+ FX_BIDIWEAKACTION_xxN = (0x0F << 4) + FX_BIDICLASS_ON,
+ FX_BIDIWEAKACTION_xxE = (0x0F << 4) + FX_BIDICLASS_EN,
+ FX_BIDIWEAKACTION_xxA = (0x0F << 4) + FX_BIDICLASS_AN,
+ FX_BIDIWEAKACTION_xxR = (0x0F << 4) + FX_BIDICLASS_R,
+ FX_BIDIWEAKACTION_xxL = (0x0F << 4) + FX_BIDICLASS_L,
+ FX_BIDIWEAKACTION_Nxx = (FX_BIDICLASS_ON << 4) + 0x0F,
+ FX_BIDIWEAKACTION_Axx = (FX_BIDICLASS_AN << 4) + 0x0F,
+ FX_BIDIWEAKACTION_ExE = (FX_BIDICLASS_EN << 4) + FX_BIDICLASS_EN,
+ FX_BIDIWEAKACTION_NIx = (FX_BIDICLASS_ON << 4) + 0x0F + 0x100,
+ FX_BIDIWEAKACTION_NxN = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_ON,
+ FX_BIDIWEAKACTION_NxR = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_R,
+ FX_BIDIWEAKACTION_NxE = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_EN,
+ FX_BIDIWEAKACTION_AxA = (FX_BIDICLASS_AN << 4) + FX_BIDICLASS_AN,
+ FX_BIDIWEAKACTION_NxL = (FX_BIDICLASS_ON << 4) + FX_BIDICLASS_L,
+ FX_BIDIWEAKACTION_LxL = (FX_BIDICLASS_L << 4) + FX_BIDICLASS_L,
+ FX_BIDIWEAKACTION_xIL = (0x0F << 4) + FX_BIDICLASS_L + 0x100,
+ FX_BIDIWEAKACTION_AxR = (FX_BIDICLASS_AN << 4) + FX_BIDICLASS_R,
+ FX_BIDIWEAKACTION_Lxx = (FX_BIDICLASS_L << 4) + 0x0F,
+};
+#define FX_BWAIX FX_BIDIWEAKACTION_IX
+#define FX_BWAXX FX_BIDIWEAKACTION_XX
+#define FX_BWAxxx FX_BIDIWEAKACTION_xxx
+#define FX_BWAxIx FX_BIDIWEAKACTION_xIx
+#define FX_BWAxxN FX_BIDIWEAKACTION_xxN
+#define FX_BWAxxE FX_BIDIWEAKACTION_xxE
+#define FX_BWAxxA FX_BIDIWEAKACTION_xxA
+#define FX_BWAxxR FX_BIDIWEAKACTION_xxR
+#define FX_BWAxxL FX_BIDIWEAKACTION_xxL
+#define FX_BWANxx FX_BIDIWEAKACTION_Nxx
+#define FX_BWAAxx FX_BIDIWEAKACTION_Axx
+#define FX_BWAExE FX_BIDIWEAKACTION_ExE
+#define FX_BWANIx FX_BIDIWEAKACTION_NIx
+#define FX_BWANxN FX_BIDIWEAKACTION_NxN
+#define FX_BWANxR FX_BIDIWEAKACTION_NxR
+#define FX_BWANxE FX_BIDIWEAKACTION_NxE
+#define FX_BWAAxA FX_BIDIWEAKACTION_AxA
+#define FX_BWANxL FX_BIDIWEAKACTION_NxL
+#define FX_BWALxL FX_BIDIWEAKACTION_LxL
+#define FX_BWAxIL FX_BIDIWEAKACTION_xIL
+#define FX_BWAAxR FX_BIDIWEAKACTION_AxR
+#define FX_BWALxx FX_BIDIWEAKACTION_Lxx
+#define FX_BidiGetDeferredType(a) (((a) >> 4) & 0x0F)
+#define FX_BidiGetResolvedType(a) ((a) & 0x0F)
+void FX_BidiResolveWeak(FX_INT32 iBaseLevel, CFX_Int32Array &classes, CFX_Int32Array &levels);
+enum FX_BIDINEUTRALSTATE {
+ FX_BIDINEUTRALSTATE_r = 0,
+ FX_BIDINEUTRALSTATE_l,
+ FX_BIDINEUTRALSTATE_rn,
+ FX_BIDINEUTRALSTATE_ln,
+ FX_BIDINEUTRALSTATE_a,
+ FX_BIDINEUTRALSTATE_na,
+};
+#define FX_BNSr FX_BIDINEUTRALSTATE_r
+#define FX_BNSl FX_BIDINEUTRALSTATE_l
+#define FX_BNSrn FX_BIDINEUTRALSTATE_rn
+#define FX_BNSln FX_BIDINEUTRALSTATE_ln
+#define FX_BNSa FX_BIDINEUTRALSTATE_a
+#define FX_BNSna FX_BIDINEUTRALSTATE_na
+enum FX_BIDINEUTRALACTION {
+ FX_BIDINEUTRALACTION_nL = FX_BIDICLASS_L,
+ FX_BIDINEUTRALACTION_En = (FX_BIDICLASS_AN << 4),
+ FX_BIDINEUTRALACTION_Rn = (FX_BIDICLASS_R << 4),
+ FX_BIDINEUTRALACTION_Ln = (FX_BIDICLASS_L << 4),
+ FX_BIDINEUTRALACTION_In = FX_BIDIWEAKACTION_IX,
+ FX_BIDINEUTRALACTION_LnL = (FX_BIDICLASS_L << 4) + FX_BIDICLASS_L,
+};
+#define FX_BNAnL FX_BIDINEUTRALACTION_nL
+#define FX_BNAEn FX_BIDINEUTRALACTION_En
+#define FX_BNARn FX_BIDINEUTRALACTION_Rn
+#define FX_BNALn FX_BIDINEUTRALACTION_Ln
+#define FX_BNAIn FX_BIDINEUTRALACTION_In
+#define FX_BNALnL FX_BIDINEUTRALACTION_LnL
+FX_INT32 FX_BidiGetDeferredNeutrals(FX_INT32 iAction, FX_INT32 iLevel);
+FX_INT32 FX_BidiGetResolvedNeutrals(FX_INT32 iAction);
+void FX_BidiResolveNeutrals(FX_INT32 iBaseLevel, CFX_Int32Array &classes, const CFX_Int32Array &levels);
+void FX_BidiResolveImplicit(const CFX_Int32Array &classes, CFX_Int32Array &levels);
+void FX_BidiResolveWhitespace(FX_INT32 iBaseLevel, const CFX_Int32Array &classes, CFX_Int32Array &levels);
+FX_INT32 FX_BidiReorderLevel(FX_INT32 iBaseLevel, CFX_WideString &wsText, const CFX_Int32Array &levels, FX_INT32 iStart, FX_BOOL bReverse = FALSE);
+void FX_BidiReorder(FX_INT32 iBaseLevel, CFX_WideString &wsText, const CFX_Int32Array &levels);
+class CFX_BidiChar : public IFX_BidiChar, public CFX_Object
{
public:
CFX_BidiChar();
diff --git a/core/src/fxcrt/fx_extension.cpp b/core/src/fxcrt/fx_extension.cpp
index 7ff6b062b4..330c675457 100644
--- a/core/src/fxcrt/fx_extension.cpp
+++ b/core/src/fxcrt/fx_extension.cpp
@@ -80,6 +80,18 @@ FX_BOOL FX_File_Truncate(FX_HFILE hFile, FX_FILESIZE szFile)
FXSYS_assert(hFile != NULL);
return ((IFXCRT_FileAccess*)hFile)->Truncate(szFile);
}
+IFX_FileAccess* FX_CreateDefaultFileAccess(FX_WSTR wsPath)
+{
+ if (wsPath.GetLength() == 0)
+ return NULL;
+
+ CFX_CRTFileAccess* pFA = NULL;
+ pFA = FX_NEW CFX_CRTFileAccess;
+ if (NULL == pFA) return NULL;
+
+ pFA->Init(wsPath);
+ return pFA;
+}
IFX_FileStream* FX_CreateFileStream(FX_LPCSTR filename, FX_DWORD dwModes)
{
IFXCRT_FileAccess* pFA = FXCRT_FileAccess_Create();
@@ -383,3 +395,40 @@ void FX_Random_GenerateCrypto(FX_LPDWORD pBuffer, FX_INT32 iCount)
#ifdef __cplusplus
}
#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+void FX_GUID_CreateV4(FX_LPGUID pGUID)
+{
+#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_)
+#ifdef _FX_WINAPI_PARTITION_DESKTOP_
+ if (!FX_GenerateCryptoRandom((FX_LPDWORD)pGUID, 4)) {
+ FX_Random_GenerateMT((FX_LPDWORD)pGUID, 4);
+ }
+#else
+ FX_Random_GenerateMT((FX_LPDWORD)pGUID, 4);
+#endif
+#else
+ FX_Random_GenerateMT((FX_LPDWORD)pGUID, 4);
+#endif
+ FX_BYTE &b = ((FX_LPBYTE)pGUID)[6];
+ b = (b & 0x0F) | 0x40;
+}
+FX_LPCSTR gs_FX_pHexChars = "0123456789ABCDEF";
+void FX_GUID_ToString(FX_LPCGUID pGUID, CFX_ByteString &bsStr, FX_BOOL bSeparator)
+{
+ FX_LPSTR pBuf = bsStr.GetBuffer(40);
+ FX_BYTE b;
+ for (FX_INT32 i = 0; i < 16; i ++) {
+ b = ((FX_LPCBYTE)pGUID)[i];
+ *pBuf ++ = gs_FX_pHexChars[b >> 4];
+ *pBuf ++ = gs_FX_pHexChars[b & 0x0F];
+ if (bSeparator && (i == 3 || i == 5 || i == 7 || i == 9)) {
+ *pBuf ++ = L'-';
+ }
+ }
+ bsStr.ReleaseBuffer(bSeparator ? 36 : 32);
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/core/src/fxcrt/fx_xml_parser.cpp b/core/src/fxcrt/fx_xml_parser.cpp
index 05fc7d5fbe..bd418b2d08 100644
--- a/core/src/fxcrt/fx_xml_parser.cpp
+++ b/core/src/fxcrt/fx_xml_parser.cpp
@@ -672,7 +672,7 @@ FX_BOOL CXML_Element::GetAttrValue(FX_BSTR name, CFX_WideString& attribute) cons
FX_XML_SplitQualifiedName(name, bsSpace, bsName);
const CFX_WideString* pValue = m_AttrMap.Lookup(bsSpace, bsName);
if (pValue) {
- attribute = CFX_WideString((FX_LPCWSTR)pValue, pValue->GetLength());
+ attribute = CFX_WideString((FX_LPCWSTR)*pValue, pValue->GetLength());
return TRUE;
}
return FALSE;
@@ -681,7 +681,7 @@ FX_BOOL CXML_Element::GetAttrValue(FX_BSTR space, FX_BSTR name, CFX_WideString&
{
const CFX_WideString* pValue = m_AttrMap.Lookup(space, name);
if (pValue) {
- attribute = CFX_WideString((FX_LPCWSTR)pValue, pValue->GetLength());
+ attribute = CFX_WideString((FX_LPCWSTR)*pValue, pValue->GetLength());
return TRUE;
}
return FALSE;
diff --git a/core/src/fxge/ge/fx_ge_font.cpp b/core/src/fxge/ge/fx_ge_font.cpp
index 817f3712d9..e3c68e0f65 100644
--- a/core/src/fxge/ge/fx_ge_font.cpp
+++ b/core/src/fxge/ge/fx_ge_font.cpp
@@ -25,6 +25,52 @@ CFX_Font::CFX_Font()
m_pDwFont = NULL;
m_hHandle = NULL;
m_bDwLoaded = FALSE;
+ m_bLogic = FALSE;
+}
+FX_BOOL CFX_Font::LoadClone(const CFX_Font* pFont)
+{
+ if (pFont == NULL) {
+ return FALSE;
+ }
+ m_bLogic = TRUE;
+ if (pFont->m_pSubstFont) {
+ m_pSubstFont = FX_NEW CFX_SubstFont;
+ if (!m_pSubstFont) {
+ return FALSE;
+ }
+ m_pSubstFont->m_Charset = pFont->m_pSubstFont->m_Charset;
+ m_pSubstFont->m_ExtHandle = pFont->m_pSubstFont->m_ExtHandle;
+ m_pSubstFont->m_SubstFlags = pFont->m_pSubstFont->m_SubstFlags;
+ m_pSubstFont->m_Weight = pFont->m_pSubstFont->m_Weight;
+ m_pSubstFont->m_Family = pFont->m_pSubstFont->m_Family;
+ m_pSubstFont->m_ItalicAngle = pFont->m_pSubstFont->m_ItalicAngle;
+ }
+ if (pFont->m_OtfFontData.GetSize()) {
+ m_OtfFontData.AttachData(pFont->m_OtfFontData.GetBuffer(), pFont->m_OtfFontData.GetSize());
+ }
+ m_Face = pFont->m_Face;
+ m_bEmbedded = pFont->m_bEmbedded;
+ m_bVertical = pFont->m_bVertical;
+ m_dwSize = pFont->m_dwSize;
+ m_pFontData = pFont->m_pFontData;
+ m_pGsubData = pFont->m_pGsubData;
+#ifdef FOXIT_CHROME_BUILD
+ if (pFont->m_pFontDataAllocation) {
+ m_pFontDataAllocation = FX_Alloc(FX_BYTE, m_dwSize);
+ if (!m_pFontDataAllocation) {
+ return FALSE;
+ }
+ m_pFontData = m_pFontDataAllocation;
+ FXSYS_memcpy32(m_pFontDataAllocation, pFont->m_pFontDataAllocation, m_dwSize);
+ }
+#endif
+ m_pPlatformFont = pFont->m_pPlatformFont;
+ m_pPlatformFontCollection = pFont->m_pPlatformFontCollection;
+ m_pDwFont = pFont->m_pDwFont;
+ m_hHandle = pFont->m_hHandle;
+ m_bDwLoaded = pFont->m_bDwLoaded;
+ m_pOwnedStream = pFont->m_pOwnedStream;
+ return TRUE;
}
CFX_Font::~CFX_Font()
{
@@ -38,6 +84,10 @@ CFX_Font::~CFX_Font()
m_pFontDataAllocation = NULL;
}
#endif
+ if (m_bLogic) {
+ m_OtfFontData.DetachBuffer();
+ return;
+ }
if (m_Face) {
#ifdef FOXIT_CHROME_BUILD
if (FXFT_Get_Face_External_Stream(m_Face)) {
@@ -108,7 +158,7 @@ extern "C" {
{
}
};
-FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream)
+FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream, FX_INT32 faceIndex = 0)
{
FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(FX_BYTE, sizeof (FXFT_StreamRec));
if (!stream1) {
@@ -123,7 +173,7 @@ FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FX
FXFT_Open_Args args;
args.flags = FT_OPEN_STREAM;
args.stream = stream1;
- if (FXFT_Open_Face(library, &args, 0, Face)) {
+ if (FXFT_Open_Face(library, &args, faceIndex, Face)) {
FX_Free(stream1);
return FALSE;
}
@@ -132,19 +182,21 @@ FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FX
}
return TRUE;
}
-FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile)
+FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile, int nFaceIndex, int* pFaceCount)
{
m_bEmbedded = FALSE;
FXFT_Library library;
- if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
+ if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL)
FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
- }
library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
FXFT_Stream stream = NULL;
- if (!_LoadFile(library, &m_Face, pFile, &stream)) {
+ if (!_LoadFile(library, &m_Face, pFile, &stream, nFaceIndex))
return FALSE;
- }
+ if (pFaceCount)
+ *pFaceCount = (int)m_Face->num_faces;
+#ifndef FOXIT_CHROME_BUILD
m_pOwnedStream = stream;
+#endif
FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
return TRUE;
}
@@ -455,3 +507,168 @@ IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont)
pEncoding = FX_NEW CFX_UnicodeEncoding(pFont);
return pEncoding;
}
+CFX_FontEncodingEX::CFX_FontEncodingEX()
+{
+ m_pFont = NULL;
+ m_nEncodingID = FXFM_ENCODING_NONE;
+}
+FX_BOOL CFX_FontEncodingEX::Init(CFX_Font* pFont, FX_DWORD EncodingID)
+{
+ if (!pFont) {
+ return FALSE;
+ }
+ m_pFont = pFont;
+ m_nEncodingID = EncodingID;
+ return TRUE;
+}
+FX_DWORD CFX_FontEncodingEX::GlyphFromCharCode(FX_DWORD charcode)
+{
+ FXFT_Face face = m_pFont->m_Face;
+ FT_UInt nIndex = FXFT_Get_Char_Index(face, charcode);
+ if (nIndex > 0) {
+ return nIndex;
+ }
+ int nmaps = FXFT_Get_Face_CharmapCount(face);
+ int m = 0;
+ while (m < nmaps) {
+ int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]);
+ if (m_nEncodingID == nEncodingID) {
+ continue;
+ }
+ int error = FXFT_Select_Charmap(face, nEncodingID);
+ if (error) {
+ continue;
+ }
+ nIndex = FXFT_Get_Char_Index(face, charcode);
+ if (nIndex > 0) {
+ m_nEncodingID = nEncodingID;
+ return nIndex;
+ }
+ }
+ FXFT_Select_Charmap(face, m_nEncodingID);
+ return 0;
+}
+CFX_WideString CFX_FontEncodingEX::UnicodeFromCharCode(FX_DWORD charcode) const
+{
+ if (m_nEncodingID == FXFM_ENCODING_UNICODE) {
+ return CFX_WideString((FX_WCHAR)charcode);
+ }
+ return CFX_WideString((FX_WCHAR)0);
+}
+FX_DWORD CFX_FontEncodingEX::CharCodeFromUnicode(FX_WCHAR Unicode) const
+{
+ if (m_nEncodingID == FXFM_ENCODING_UNICODE || m_nEncodingID == FXFM_ENCODING_MS_SYMBOL) {
+ return Unicode;
+ }
+ FXFT_Face face = m_pFont->m_Face;
+ int nmaps = FXFT_Get_Face_CharmapCount(face);
+ for (int i = 0; i < nmaps; i++) {
+ int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i]);
+ if (nEncodingID == FXFM_ENCODING_UNICODE || nEncodingID == FXFM_ENCODING_MS_SYMBOL) {
+ return Unicode;
+ }
+ }
+ return -1;
+}
+FX_BOOL CFX_FontEncodingEX::IsUnicodeCompatible() const
+{
+ return m_nEncodingID == FXFM_ENCODING_UNICODE;
+}
+FX_DWORD CFX_FontEncodingEX::GlyphIndexFromName(FX_LPCSTR pStrName)
+{
+ FXFT_Face face = m_pFont->m_Face;
+ return FT_Get_Name_Index(face, (FT_String*)pStrName);
+}
+CFX_ByteString CFX_FontEncodingEX::NameFromGlyphIndex(FX_DWORD dwGlyphIndex)
+{
+ FXFT_Face face = m_pFont->m_Face;
+ CFX_ByteString glyphName(" ");
+ if (FT_HAS_GLYPH_NAMES(((FT_Face)face))) {
+ if (FT_Get_Glyph_Name((FT_Face)face, dwGlyphIndex, (FT_Pointer)(FX_LPCSTR)glyphName, 16)) {
+ glyphName.Empty();
+ return glyphName;
+ }
+ return glyphName;
+ } else {
+ return glyphName;
+ }
+}
+FX_DWORD CFX_FontEncodingEX::CharCodeFromGlyphIndex(FX_DWORD dwGlyphIndex)
+{
+ FXFT_Face face = m_pFont->GetFace();
+ FX_DWORD charcode;
+ FT_UInt gid;
+ charcode = FT_Get_First_Char((FT_Face)face, &gid);
+ while (gid != 0) {
+ if (dwGlyphIndex == gid) {
+ return charcode;
+ }
+ charcode = FT_Get_Next_Char((FT_Face)face, charcode, &gid);
+ }
+ int nmaps = FXFT_Get_Face_CharmapCount(face);
+ int m = 0;
+ while (m < nmaps) {
+ int nEncodingID = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[m++]);
+ if (m_nEncodingID == nEncodingID) {
+ continue;
+ }
+ int error = FXFT_Select_Charmap(face, nEncodingID);
+ if (error) {
+ continue;
+ }
+ charcode = FT_Get_First_Char((FT_Face)face, &gid);
+ while (gid != 0) {
+ if (dwGlyphIndex == gid) {
+ m_nEncodingID = nEncodingID;
+ return charcode;
+ }
+ charcode = FT_Get_Next_Char((FT_Face)face, charcode, &gid);
+ }
+ }
+ return (FX_DWORD) - 1;
+}
+static const FX_DWORD gs_EncodingID[] = {
+ FXFM_ENCODING_MS_SYMBOL,
+ FXFM_ENCODING_UNICODE,
+ FXFM_ENCODING_MS_SJIS,
+ FXFM_ENCODING_MS_GB2312,
+ FXFM_ENCODING_MS_BIG5,
+ FXFM_ENCODING_MS_WANSUNG,
+ FXFM_ENCODING_MS_JOHAB,
+ FXFM_ENCODING_ADOBE_STANDARD,
+ FXFM_ENCODING_ADOBE_EXPERT,
+ FXFM_ENCODING_ADOBE_CUSTOM,
+ FXFM_ENCODING_ADOBE_LATIN_1,
+ FXFM_ENCODING_OLD_LATIN_2,
+ FXFM_ENCODING_APPLE_ROMAN
+};
+static IFX_FontEncodingEx* _FXFM_CreateFontEncoding(CFX_Font* pFont, FX_DWORD nEncodingID)
+{
+ int error = FXFT_Select_Charmap(pFont->m_Face, nEncodingID);
+ if (error) {
+ return NULL;
+ }
+ CFX_FontEncodingEX* pFontEncoding = FX_NEW CFX_FontEncodingEX;
+ if (pFontEncoding && !pFontEncoding->Init(pFont, nEncodingID)) {
+ delete pFontEncoding;
+ pFontEncoding = NULL;
+ }
+ return pFontEncoding;
+}
+IFX_FontEncodingEx* FX_CreateFontEncodingEx(CFX_Font* pFont, FX_DWORD nEncodingID)
+{
+ if (!pFont || !pFont->m_Face) {
+ return NULL;
+ }
+ if (nEncodingID != FXFM_ENCODING_NONE) {
+ return _FXFM_CreateFontEncoding(pFont, nEncodingID);
+ }
+ static int s_count = sizeof(gs_EncodingID) / sizeof(FX_DWORD);
+ for (int i = 0; i < s_count; i++) {
+ IFX_FontEncodingEx* pFontEncoding = _FXFM_CreateFontEncoding(pFont, gs_EncodingID[i]);
+ if (pFontEncoding) {
+ return pFontEncoding;
+ }
+ }
+ return NULL;
+}
diff --git a/core/src/fxge/ge/fx_ge_fontmap.cpp b/core/src/fxge/ge/fx_ge_fontmap.cpp
index a5fa6443a8..fe790d8664 100644
--- a/core/src/fxge/ge/fx_ge_fontmap.cpp
+++ b/core/src/fxge/ge/fx_ge_fontmap.cpp
@@ -1156,6 +1156,9 @@ FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTru
pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT;
}
if (hFont == NULL) {
+ if (flags & FXFONT_EXACTMATCH) {
+ return NULL;
+ }
if (bCJK) {
if (italic_angle != 0) {
bItalic = TRUE;
@@ -1284,6 +1287,68 @@ FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTru
m_pFontInfo->DeleteFont(hFont);
return face;
}
+FXFT_Face CFX_FontMapper::FindSubstFontByUnicode(FX_DWORD dwUnicode, FX_DWORD flags, int weight, int italic_angle)
+{
+ if (m_pFontInfo == NULL) {
+ return NULL;
+ }
+ FX_BOOL bItalic = (flags & FXFONT_ITALIC) != 0;
+ int PitchFamily = 0;
+ if (flags & FXFONT_SERIF) {
+ PitchFamily |= FXFONT_FF_ROMAN;
+ }
+ if (flags & FXFONT_SCRIPT) {
+ PitchFamily |= FXFONT_FF_SCRIPT;
+ }
+ if (flags & FXFONT_FIXED_PITCH) {
+ PitchFamily |= FXFONT_FF_FIXEDPITCH;
+ }
+ void* hFont = m_pFontInfo->MapFontByUnicode(dwUnicode, weight, bItalic, PitchFamily);
+ if (hFont == NULL) {
+ return NULL;
+ }
+ FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0);
+ FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0);
+ if(font_size == 0 && ttc_size == 0) {
+ m_pFontInfo->DeleteFont(hFont);
+ return NULL;
+ }
+ FXFT_Face face = NULL;
+ if (ttc_size) {
+ FX_BYTE temp[1024];
+ m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024);
+ FX_DWORD checksum = 0;
+ for (int i = 0; i < 256; i ++) {
+ checksum += ((FX_DWORD*)temp)[i];
+ }
+ FX_LPBYTE pFontData;
+ face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, ttc_size - font_size, pFontData);
+ if (face == NULL) {
+ pFontData = FX_Alloc(FX_BYTE, ttc_size);
+ if (pFontData) {
+ m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size);
+ face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, ttc_size,
+ ttc_size - font_size);
+ }
+ }
+ } else {
+ CFX_ByteString SubstName;
+ m_pFontInfo->GetFaceName(hFont, SubstName);
+ FX_LPBYTE pFontData;
+ face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData);
+ if (face == NULL) {
+ pFontData = FX_Alloc(FX_BYTE, font_size);
+ if (!pFontData) {
+ m_pFontInfo->DeleteFont(hFont);
+ return NULL;
+ }
+ m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size);
+ face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, font_size, m_pFontInfo->GetFaceIndex(hFont));
+ }
+ }
+ m_pFontInfo->DeleteFont(hFont);
+ return face;
+}
extern "C" {
unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset,
unsigned char* buffer, unsigned long count);
@@ -1483,6 +1548,10 @@ void* CFX_FolderFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int
{
return NULL;
}
+void* CFX_FolderFontInfo::MapFontByUnicode(FX_DWORD dwUnicode, int weight, FX_BOOL bItalic, int pitch_family)
+{
+ return NULL;
+}
void* CFX_FolderFontInfo::GetFont(FX_LPCSTR face)
{
FX_LPVOID p;
diff --git a/core/src/fxge/ge/text_int.h b/core/src/fxge/ge/text_int.h
index c8d55965e3..e51976f172 100644
--- a/core/src/fxge/ge/text_int.h
+++ b/core/src/fxge/ge/text_int.h
@@ -101,5 +101,24 @@ public:
int m_PitchFamily;
CFX_ByteString m_FontTables;
};
-
+class CFX_FontEncodingEX : public IFX_FontEncodingEx
+{
+public:
+ CFX_FontEncodingEX();
+ FX_BOOL Init(CFX_Font* pFont, FX_DWORD EncodingID);
+ virtual FX_DWORD GlyphIndexFromName(FX_LPCSTR pStrName);
+ virtual CFX_ByteString NameFromGlyphIndex(FX_DWORD dwGlyphIndex);
+ virtual FX_DWORD CharCodeFromGlyphIndex(FX_DWORD dwGlyphIndex);
+ virtual FX_DWORD GlyphFromCharCode(FX_DWORD charcode);
+ virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const;
+ virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const;
+ virtual FX_BOOL IsUnicodeCompatible() const;
+ virtual FX_DWORD GlyphFromCharCodeEx(FX_DWORD charcode, int encoding = ENCODING_UNICODE)
+ {
+ return GlyphFromCharCode(charcode);
+ }
+private:
+ CFX_Font* m_pFont;
+ FX_DWORD m_nEncodingID;
+};
#endif // _TEXT_INT_H_
diff --git a/fpdfsdk/include/formfiller/FFL_ComboBox.h b/fpdfsdk/include/formfiller/FFL_ComboBox.h
index 6df8347a76..e3ad8b1c22 100644
--- a/fpdfsdk/include/formfiller/FFL_ComboBox.h
+++ b/fpdfsdk/include/formfiller/FFL_ComboBox.h
@@ -40,6 +40,8 @@ public:
virtual CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue);
virtual void OnKeyStroke(FX_BOOL bKeyDown, FX_UINT nFlag);
+ virtual FX_BOOL IsFieldFull(CPDFSDK_PageView* pPageView);
+
public:
virtual void OnSetFocus(CPWL_Wnd* pWnd);
virtual void OnKillFocus(CPWL_Wnd* pWnd);
diff --git a/fpdfsdk/include/formfiller/FFL_FormFiller.h b/fpdfsdk/include/formfiller/FFL_FormFiller.h
index 7a3402a7f9..18426a91ba 100644
--- a/fpdfsdk/include/formfiller/FFL_FormFiller.h
+++ b/fpdfsdk/include/formfiller/FFL_FormFiller.h
@@ -120,6 +120,7 @@ public:
virtual void SaveData(CPDFSDK_PageView* pPageView);
virtual void GetKeyStrokeData(CPDFSDK_PageView* pPageView, FFL_KeyStrokeData& data);
+ virtual FX_BOOL IsFieldFull(CPDFSDK_PageView* pPageView);
public:
CPWL_Wnd* GetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bNew);
diff --git a/fpdfsdk/include/formfiller/FFL_IFormFiller.h b/fpdfsdk/include/formfiller/FFL_IFormFiller.h
index 393f0be331..1b33edd4e8 100644
--- a/fpdfsdk/include/formfiller/FFL_IFormFiller.h
+++ b/fpdfsdk/include/formfiller/FFL_IFormFiller.h
@@ -76,6 +76,8 @@ public:
virtual void OnSetWindowRect(void* pPrivateData, const CPDF_Rect & rcWindow);
virtual void OnKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_INT32 nKeyCode, CFX_WideString & strChange,
const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, FX_BOOL & bRC, FX_BOOL & bExit);
+ virtual void OnPopupPreOpen(void* pPrivateData, FX_BOOL& bExit, FX_DWORD nFlag);
+ virtual void OnPopupPostOpen(void* pPrivateData, FX_BOOL& bExit, FX_DWORD nFlag);
public:
virtual void BeforeUndo(CPDFSDK_Document* pDocument);
@@ -116,6 +118,10 @@ public:
static int GetCommitKey();
static FX_BOOL GetKeyDown();
+ void OnClick(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag);
+ void OnFull(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag);
+ void OnPreOpen(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag);
+ void OnPostOpen(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag);
public:
// static MSG g_Msg;
diff --git a/fpdfsdk/include/formfiller/FFL_Notify.h b/fpdfsdk/include/formfiller/FFL_Notify.h
index cabc1aa113..c729b7452b 100644
--- a/fpdfsdk/include/formfiller/FFL_Notify.h
+++ b/fpdfsdk/include/formfiller/FFL_Notify.h
@@ -45,6 +45,7 @@ private:
FX_BOOL ExecuteActionTree(CPDF_AAction::AActionType eAAT, CPDF_Action & action, FX_BOOL& bExit);
FX_BOOL ExecuteAction(CPDF_AAction::AActionType eAAT,CPDF_Action & action,FX_BOOL& bExit);
+ CFFL_FormFiller * m_pFormFiller;
FX_BOOL m_bDoActioning;
FX_INT32 m_nNotifyFlag;
};
diff --git a/fpdfsdk/include/formfiller/FFL_TextField.h b/fpdfsdk/include/formfiller/FFL_TextField.h
index 3a5fd688b0..53ddfb7245 100644
--- a/fpdfsdk/include/formfiller/FFL_TextField.h
+++ b/fpdfsdk/include/formfiller/FFL_TextField.h
@@ -60,6 +60,8 @@ public:
virtual CPWL_Wnd* ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue);
+ virtual FX_BOOL IsFieldFull(CPDFSDK_PageView* pPageView);
+
public:
virtual void OnSetFocus(CPWL_Wnd* pWnd);
virtual void OnKillFocus(CPWL_Wnd* pWnd);
diff --git a/fpdfsdk/include/fpdf_dataavail.h b/fpdfsdk/include/fpdf_dataavail.h
index 971ab2505c..fb061b9bfa 100644
--- a/fpdfsdk/include/fpdf_dataavail.h
+++ b/fpdfsdk/include/fpdf_dataavail.h
@@ -64,6 +64,8 @@ typedef void* FPDF_AVAIL;
* A handle to the document availability provider. NULL for error.
* Comments:
* Application must call FPDFAvail_Destroy when done with the availability provider.
+* Notes:
+* The method can not support to load a document which consists of dynamic XFA fields now.
*/
DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail, FPDF_FILEACCESS* file);
diff --git a/fpdfsdk/include/fpdf_flatten.h b/fpdfsdk/include/fpdf_flatten.h
index 2e9e5092f9..0c555138ab 100644
--- a/fpdfsdk/include/fpdf_flatten.h
+++ b/fpdfsdk/include/fpdf_flatten.h
@@ -29,9 +29,12 @@ extern "C" {
//Return value:
// The result flag of the function, See flags above ( FLATTEN_FAIL, FLATTEN_SUCCESS, FLATTEN_NOTINGTODO ).
//
- // Comments: Current version all fails return zero. If necessary we will assign different value
+ //Comments: Current version all fails return zero. If necessary we will assign different value
// to indicate different fail reason.
//
+ //Notes:
+ // The method can not support to flatten the page which the document consists of dynamic XFA fields.
+ //
DLLEXPORT int STDCALL FPDFPage_Flatten( FPDF_PAGE page, int nFlag);
diff --git a/fpdfsdk/include/fpdf_progressive.h b/fpdfsdk/include/fpdf_progressive.h
index 029264eae2..69bbfba4cd 100644
--- a/fpdfsdk/include/fpdf_progressive.h
+++ b/fpdfsdk/include/fpdf_progressive.h
@@ -64,6 +64,8 @@ typedef struct _IFSDK_PAUSE
// pause - The IFSDK_PAUSE interface.A callback mechanism allowing the page rendering process
// Return value:
// Rendering Status. See flags for progressive process status for the details.
+// Notes:
+// The method cannot not support to render page which the document consists of dynamic XFA fields.
//
DLLEXPORT int STDCALL FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap, FPDF_PAGE page, int start_x, int start_y, int size_x,
int size_y, int rotate, int flags,IFSDK_PAUSE * pause);
@@ -76,6 +78,9 @@ DLLEXPORT int STDCALL FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap, FPDF_PAGE
// to be paused before it's finished. This can be NULL if you don't want to pause.
// Return value:
// The rendering status. See flags for progressive process status for the details.
+// Notes:
+// The method cannot not support to render page which the document consists of dynamic XFA fields.
+//
DLLEXPORT int STDCALL FPDF_RenderPage_Continue(FPDF_PAGE page,IFSDK_PAUSE * pause);
// Function: FPDF_RenderPage_Close
@@ -85,6 +90,9 @@ DLLEXPORT int STDCALL FPDF_RenderPage_Continue(FPDF_PAGE page,IFSDK_PAUSE * paus
// page - Handle to the page. Returned by FPDF_LoadPage function.
// Return value:
// NULL
+// Notes:
+// The method cannot not support to render page which the document consists of dynamic XFA fields.
+//
DLLEXPORT void STDCALL FPDF_RenderPage_Close(FPDF_PAGE page);
#ifdef __cplusplus
diff --git a/fpdfsdk/include/fpdf_transformpage.h b/fpdfsdk/include/fpdf_transformpage.h
index 69ffe24009..32b0ea008c 100644
--- a/fpdfsdk/include/fpdf_transformpage.h
+++ b/fpdfsdk/include/fpdf_transformpage.h
@@ -21,6 +21,7 @@ typedef void* FPDF_PAGEARCLOADER;
* @param[in] right - The right of the rectangle.
* @param[in] top - The top of the rectangle.
* @retval None.
+* @note The method can not support to set this feature for the document which consists of dynamic XFA fields.
*/
DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page, float left, float bottom, float right, float top);
@@ -32,6 +33,7 @@ DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page, float left, float bo
* @param[in] right - The right of the rectangle.
* @param[in] top - The top of the rectangle.
* @retval None.
+* @note The method can not support to set this feature for the document which consists of dynamic XFA fields.
*/
DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page, float left, float bottom, float right, float top);
@@ -43,6 +45,7 @@ DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page, float left, float bot
* @param[in] right - Pointer to a double value receiving the right of the rectangle.
* @param[in] top - Pointer to a double value receiving the top of the rectangle.
* @retval True if success,else fail.
+* @note The method can not support to get this feature for the document which consists of dynamic XFA fields.
*/
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page, float* left, float* bottom, float* right, float* top);
@@ -53,6 +56,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page, float* left, fl
* @param[in] right - Pointer to a double value receiving the right of the rectangle.
* @param[in] top - Pointer to a double value receiving the top of the rectangle.
* @retval True if success,else fail.
+* @note The method can not support to get this feature for the document which consists of dynamic XFA fields.
*/
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page, float* left, float* bottom, float* right, float* top);
@@ -63,6 +67,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page, float* left, flo
* @param[in] matrix - The transform matrix.
* @param[in] clipRect - A rectangle page area to be clipped.
* @Note. This function will transform the whole page, and would take effect to all the objects in the page.
+* The method can not support to get this feature for the document which consists of dynamic XFA fields.
*/
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX* matrix, FS_RECTF* clipRect);
@@ -105,7 +110,7 @@ DLLEXPORT void STDCALL FPDF_DestroyClipPath(FPDF_CLIPPATH clipPath);
* @param[in] page - A page handle.
* @param[in] clipPath - A handle to the clip path.
* @Note. A clip path will be inserted before the page content stream or content array. In this way, the page content will be clipped
-* by this clip path.
+* by this clip path. The method can not support this feature for the document consists of dynamic XFA fields.
*/
DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clipPath);
diff --git a/fpdfsdk/include/fpdfdoc.h b/fpdfsdk/include/fpdfdoc.h
index 54ede4037a..da49ba062a 100644
--- a/fpdfsdk/include/fpdfdoc.h
+++ b/fpdfsdk/include/fpdfdoc.h
@@ -116,6 +116,8 @@ DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document, FP
// Comments:
// The point coordinates are specified in page coordinate system. You can convert coordinates
// from screen system to page system using FPDF_DeviceToPage functions.
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
//
DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page, double x, double y);
@@ -148,6 +150,8 @@ DLLEXPORT FPDF_ACTION STDCALL FPDFLink_GetAction(FPDF_LINK link);
// linkAnnot[out] - Receive the link handle.
// Return value:
// TRUE if succceed, else False;
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
//
DLLEXPORT FPDF_BOOL STDCALL FPDFLink_Enumerate(FPDF_PAGE page, int* startPos, FPDF_LINK* linkAnnot);
diff --git a/fpdfsdk/include/fpdfedit.h b/fpdfsdk/include/fpdfedit.h
index 18b816843a..3be2fd3112 100644
--- a/fpdfsdk/include/fpdfedit.h
+++ b/fpdfsdk/include/fpdfedit.h
@@ -34,6 +34,7 @@ extern "C" {
// None.
// Return value:
// A handle to a document. If failed, NULL is returned.
+//
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument();
//////////////////////////////////////////////////////////////////////
@@ -53,6 +54,9 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument();
// The handle to the page.
// Comments:
// Loaded page can be deleted by FPDFPage_Delete.
+// Notes:
+// The method can not support to create a new page for the document consists of dynamic XFA fields.
+//
DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index, double width, double height);
// Function: FPDFPage_Delete
@@ -62,6 +66,9 @@ DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index,
// page_index - The index of a page.
// Return value:
// None.
+// Notes:
+// The method can not support to delete page for the document consists of dynamic XFA fields.
+//
DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index);
// Function: FPDFPage_GetRotation
@@ -72,6 +79,9 @@ DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index);
// The PDF page rotation.
// Comment:
// The PDF page rotation is rotated clockwise.
+// Notes:
+// The method can not support to get the page rotate for the document consists of dynamic XFA fields.
+//
DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page);
// Function: FPDFPage_SetRotation
@@ -83,6 +93,8 @@ DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page);
// None.
// Comment:
// The PDF page rotation is rotated clockwise.
+// Notes:
+// The method can not support to set this feature for the document consists of dynamic XFA fields.
//
DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate);
@@ -94,6 +106,9 @@ DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate);
// FPDFPageObj_NewPathObj.
// Return value:
// None.
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_obj);
// Function: FPDFPage_CountObject
@@ -102,6 +117,9 @@ DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT pag
// page - Handle to a page. Returned by FPDFPage_New or FPDF_LoadPage.
// Return value:
// The number of the page object.
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page);
// Function: FPDFPage_GetObject
@@ -111,6 +129,9 @@ DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page);
// index - The index of a page object.
// Return value:
// The handle of the page object. Null for failed.
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index);
// Function: FPDFPage_HasTransparency
@@ -120,6 +141,9 @@ DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index);
// Return value:
// TRUE means that the PDF page does contains transparency.
// Otherwise, returns FALSE.
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page);
// Function: FPDFPage_GenerateContent
@@ -131,6 +155,9 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page);
// Comment:
// Before you save the page to a file, or reload the page, you must call the FPDFPage_GenerateContent function.
// Or the changed information will be lost.
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page);
//////////////////////////////////////////////////////////////////////
@@ -175,6 +202,8 @@ DLLEXPORT void STDCALL FPDFPageObj_Transform(FPDF_PAGEOBJECT page_object,
// f - The coefficient "f" of the matrix.
// Return value:
// None.
+// Notes:
+// The method can not support this feature for the document consists of dynamic XFA fields.
DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
double a, double b, double c, double d, double e, double f);
@@ -212,6 +241,8 @@ DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewImgeObj(FPDF_DOCUMENT document)
// Note:
// The image object might already has an associated image, which is shared and cached by the loaded pages, In this case, we need to clear the cache of image for all the loaded pages.
// Pass pages and count to this API to clear the image cache.
+// The method can not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_LoadJpegFile(FPDF_PAGE* pages, int nCount,FPDF_PAGEOBJECT image_object, FPDF_FILEACCESS* fileAccess);
@@ -239,6 +270,9 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetMatrix(FPDF_PAGEOBJECT image_object,
// bitmap - The handle of the bitmap which you want to set it to the image object.
// Return value:
// TRUE if successful, FALSE otherwise.
+// Notes;
+// The method can not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages,int nCount,FPDF_PAGEOBJECT image_object, FPDF_BITMAP bitmap);
#ifdef __cplusplus
diff --git a/fpdfsdk/include/fpdfformfill.h b/fpdfsdk/include/fpdfformfill.h
index b69a8f69b2..a08bfd16b7 100644
--- a/fpdfsdk/include/fpdfformfill.h
+++ b/fpdfsdk/include/fpdfformfill.h
@@ -44,6 +44,8 @@ typedef struct _IPDF_JsPlatform
* 1-Warning;
* 2-Question;
* 3-Status.
+ * 4-Asterisk
+
* Return Value:
* The return value could be the folowing type:
* 1-OK;
@@ -216,7 +218,7 @@ typedef struct _IPDF_JsPlatform
* Comments:
* The filePath shoule be always input in local encoding.
*/
- int (*Field_browse)(struct _IPDF_JsPlatform* pThis,void* filePath, int length);
+ int (*Field_browse)(struct _IPDF_JsPlatform* pThis, void* filePath, int length);
/**
* pointer to FPDF_FORMFILLINFO interface.
@@ -256,6 +258,38 @@ typedef struct _FPDF_SYSTEMTIME
unsigned short wMilliseconds; /* milliseconds after the second - [0,999] */
}FPDF_SYSTEMTIME;
+//XFA
+/**
+ * @name Pageview event flags
+ */
+/*@{*/
+/** @brief After a new pageview is added. */
+#define FXFA_PAGEVIEWEVENT_POSTADDED 1
+/** @brief After a pageview is removed. */
+#define FXFA_PAGEVIEWEVENT_POSTREMOVED 3
+/*@}*/
+
+// menu
+/**
+ * @name Macro Definitions for Right Context Menu Features Of XFA Fields
+ */
+/*@{*/
+#define FXFA_MEMU_COPY 1
+#define FXFA_MEMU_CUT 2
+#define FXFA_MEMU_SELECTALL 4
+#define FXFA_MEMU_UNDO 8
+#define FXFA_MEMU_REDO 16
+#define FXFA_MEMU_PASTE 32
+/*@}*/
+
+// file type
+/**
+ * @name Macro Definitions for File Type.
+ */
+/*@{*/
+#define FXFA_SAVEAS_XML 1
+#define FXFA_SAVEAS_XDP 2
+/*@}*/
typedef struct _FPDF_FORMFILLINFO
{
@@ -526,8 +560,235 @@ typedef struct _FPDF_FORMFILLINFO
**/
void (*FFI_DoGoToAction)(struct _FPDF_FORMFILLINFO* pThis, int nPageIndex, int zoomMode, float* fPosArray, int sizeofArray);
/**
- * pointer to IPDF_JSPLATFORM interface
+ * Method: FFI_DisplayCaret
+ * This method will show the caret at specified position.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * page - Handle to page. Returned by FPDF_LoadPage function.
+ * left - Left position of the client area in PDF page coordinate.
+ * top - Top position of the client area in PDF page coordinate.
+ * right - Right position of the client area in PDF page coordinate.
+ * bottom - Bottom position of the client area in PDF page coordinate.
+ * Return value:
+ * None.
+ **/
+ void (*FFI_DisplayCaret)(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_BOOL bVisible, double left, double top, double right, double bottom);
+ /**
+ * Method: FFI_GetCurrentPageIndex
+ * This method will get the current page index.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * Return value:
+ * The index of current page.
**/
+ int (*FFI_GetCurrentPageIndex)(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document);
+ /**
+ * Method: FFI_SetCurrentPage
+ * This method will set the current page.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * iCurPage - The index of the PDF page.
+ * Return value:
+ * None.
+ **/
+ void (*FFI_SetCurrentPage)(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, int iCurPage);
+ /**
+ * Method: FFI_GotoURL
+ * This method will link to the specified URL.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * no
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * wsURL - The string value of the URL, in UTF-16LE format.
+ * Return value:
+ * None.
+ **/
+ void (*FFI_GotoURL)(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, FPDF_WIDESTRING wsURL);
+ /**
+ * Method: FFI_GetPageViewRect
+ * This method will get the current page view rectangle.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * page - Handle to page. Returned by FPDF_LoadPage function.
+ * left - The pointer to receive left position of the page view area in PDF page coordinate.
+ * top - The pointer to receive top position of the page view area in PDF page coordinate.
+ * right - The pointer to receive right position of the client area in PDF page coordinate.
+ * bottom - The pointer to receive bottom position of the client area in PDF page coordinate.
+ * Return value:
+ * None.
+ **/
+ void (*FFI_GetPageViewRect)(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, double* left, double* top, double* right, double* bottom);
+ /**
+ * Method: FFI_PopupMenu
+ * This method will track the right context menu for XFA fields.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * page - Handle to page. Returned by FPDF_LoadPage function.
+ * hWidget - Handle to XFA fields.
+ * menuFlag - The menu flags. Please refer to macro definition of FXFA_MEMU_XXX and this can be one or a combination of these macros.
+ * x - X position of the client area in PDF page coordinate.
+ * y - Y position of the client area in PDF page coordinate.
+ * Return value:
+ * TRUE indicates success; otherwise false.
+ **/
+ FPDF_BOOL (*FFI_PopupMenu)(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_WIDGET hWidget, int menuFlag, float x, float y);
+ /**
+ * Method: FFI_OpenFile
+ * This method will open the specified file with the specified mode.
+ * Interface Version
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * fileFlag - The file flag.Please refer to macro definition of FXFA_SAVEAS_XXX and this can be one of these macros.
+ * wsURL - The string value of the file URL, in UTF-16LE format.
+ * mode - The mode for open file.
+ * Return value:
+ * The handle to FPDF_FILEHANDLER.
+ **/
+ FPDF_FILEHANDLER* (*FFI_OpenFile)(struct _FPDF_FORMFILLINFO* pThis, int fileFlag, FPDF_WIDESTRING wsURL, const char* mode);
+ /**
+ * Method: FFI_EmailTo
+ * This method will email the specified file stream to the specified contacter.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * pFileHandler - Handle to the FPDF_FILEHANDLER.
+ * pTo - A semicolon-delimited list of recipients for the message,in UTF-16LE format.
+ * pSubject - The subject of the message,in UTF-16LE format.
+ * pCC - A semicolon-delimited list of CC recipients for the message,in UTF-16LE format.
+ * pBcc - A semicolon-delimited list of BCC recipients for the message,in UTF-16LE format.
+ * pMsg - Pointer to the data buffer to be sent.Can be NULL,in UTF-16LE format.
+ * Return value:
+ * None.
+ **/
+ void (*FFI_EmailTo)(struct _FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* fileHandler, FPDF_WIDESTRING pTo, FPDF_WIDESTRING pSubject, FPDF_WIDESTRING pCC, FPDF_WIDESTRING pBcc, FPDF_WIDESTRING pMsg);
+ /**
+ * Method: FFI_UploadTo
+ * This method will get upload the specified file stream to the specified URL.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * pFileHandler - Handle to the FPDF_FILEHANDLER.
+ * fileFlag - The file flag.Please refer to macro definition of FXFA_SAVEAS_XXX and this can be one of these macros.
+ * uploadTo - Pointer to the URL path, in UTF-16LE format.
+ * Return value:
+ * None.
+ **/
+ void (*FFI_UploadTo)(struct _FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* fileHandler, int fileFlag, FPDF_WIDESTRING uploadTo);
+
+ /**
+ * Method: FFI_GetPlatform
+ * This method will get the current platform.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * platform - Pointer to the data buffer to receive the platform.Can be NULL,in UTF-16LE format.
+ * length - The length of the buffer, number of bytes. Can be 0.
+ * Return value:
+ * The length of the buffer, number of bytes.
+ **/
+ int (*FFI_GetPlatform)(struct _FPDF_FORMFILLINFO* pThis, void* platform, int length);
+ /**
+ * Method: FFI_GetLanguage
+ * This method will get the current language.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * language - Pointer to the data buffer to receive the current language.Can be NULL.
+ * length - The length of the buffer, number of bytes. Can be 0.
+ * Return value:
+ * The length of the buffer, number of bytes.
+ **/
+ int (*FFI_GetLanguage)(struct _FPDF_FORMFILLINFO* pThis, void* language, int length);
+ /**
+ * Method: FFI_DownloadFromURL
+ * This method will download the specified file from the URL.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * URL - The string value of the file URL, in UTF-16LE format.
+ * Return value:
+ * The handle to FPDF_FILEHANDLER.
+ **/
+ FPDF_LPFILEHANDLER (*FFI_DownloadFromURL)(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING URL);
+ /**
+ * Method: FFI_PostRequestURL
+ * This method will post the request to the server URL.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * wsURL - The string value of the server URL, in UTF-16LE format.
+ * wsData - The post data,in UTF-16LE format.
+ * wsContentType - The content type of the request data,in UTF-16LE format.
+ * wsEncode - The encode type,in UTF-16LE format.
+ * wsHeader - The request header,in UTF-16LE format.
+ * response - Pointer to the FPDF_BSTR to receive the response data from server,,in UTF-16LE format.
+ * Return value:
+ * TRUE indicates success, otherwise FALSE.
+ **/
+ FPDF_BOOL (*FFI_PostRequestURL)(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsContentType, FPDF_WIDESTRING wsEncode, FPDF_WIDESTRING wsHeader, FPDF_BSTR* respone);
+ /**
+ * Method: FFI_PutRequestURL
+ * This method will put the request to the server URL.
+ * Interface Version:
+ * 1
+ * Implementation Required:
+ * yes
+ * Parameters:
+ * pThis - Pointer to the interface structure itself.
+ * wsURL - The string value of the server URL, in UTF-16LE format.
+ * wsData - The put data, in UTF-16LE format.
+ * wsEncode - The encode type, in UTR-16LE format.
+ * Return value:
+ * TRUE indicates success, otherwise FALSE.
+ **/
+ FPDF_BOOL (*FFI_PutRequestURL)(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsEncode);
+
IPDF_JSPLATFORM* m_pJsPlatform;
} FPDF_FORMFILLINFO;
@@ -688,6 +949,9 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle,FPDF_PAGE
**/
DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle,FPDF_PAGE page, int modifier, double page_x, double page_y);
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y);
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y);
+
/**
* Function: FORM_OnKeyDown
* You can call this member function when a nonsystem key is pressed.
@@ -746,7 +1010,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_ForceToKillFocus(FPDF_FORMHANDLE hHandle);
#define FPDF_FORMFIELD_COMBOBOX 4 // combo box type.
#define FPDF_FORMFIELD_LISTBOX 5 // list box type.
#define FPDF_FORMFIELD_TEXTFIELD 6 // text field type.
-
+#define FPDF_FORMFIELD_XFA 7 // text field type.
/**
* Function: FPDPage_HasFormFieldAtPoint
* Check the form filed position by point.
@@ -827,7 +1091,149 @@ DLLEXPORT void STDCALL FPDF_RemoveFormFieldHighlight(FPDF_FORMHANDLE hHandle);
DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle,FPDF_BITMAP bitmap, FPDF_PAGE page, int start_x, int start_y,
int size_x, int size_y, int rotate, int flags);
+/**
+ * Function: FPDF_LoadXFA
+ * If the document consists of XFA fields, there should call this method to load XFA fields.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * Return Value:
+ * TRUE indicates success,otherwise FALSE.
+ **/
+DLLEXPORT FPDF_BOOL STDCALL FPDF_LoadXFA(FPDF_DOCUMENT document);
+/**
+ * Function: FPDF_Widget_Undo
+ * This method will implement the undo feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document, FPDF_WIDGET hWidget);
+/**
+ * Function: FPDF_Widget_Redo
+ * This method will implement the redo feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document, FPDF_WIDGET hWidget);
+/**
+ * Function: FPDF_Widget_SelectAll
+ * This method will implement the select all feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document, FPDF_WIDGET hWidget);
+/**
+ * Function: FPDF_Widget_Copy
+ * This method will implement the copy feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * wsText - Pointer to data buffer to receive the copied data, in UTF-16LE format.
+ * size - The data buffer size.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, FPDF_WIDESTRING wsText, FPDF_DWORD* size);
+/**
+ * Function: FPDF_Widget_Cut
+ * This method will implement the cut feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * wsText - Pointer to data buffer to receive the cut data,in UTF-16LE format.
+ * size - The data buffer size,not the byte number.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, FPDF_WIDESTRING wsText, FPDF_DWORD* size);
+/**
+ * Function: FPDF_Widget_Paste
+ * This method will implement the paste feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * wsText - The paste text buffer, in UTF-16LE format.
+ * size - The data buffer size,not the byte number.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, FPDF_WIDESTRING wsText, FPDF_DWORD size);
+/**
+ * Function: FPDF_Widget_ReplaceSpellCheckWord
+ * This method will implement the spell check feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * x - The x value of the specified point.
+ * y - The y value of the specified point.
+ * bsText - The text buffer needed to be speck check, in UTF-16LE format.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, float x, float y, FPDF_BYTESTRING bsText);
+/**
+ * Function: FPDF_Widget_GetSpellCheckWords
+ * This method will implement the spell check feature for the specified xfa field.
+ * Parameters:
+ * document - Handle to document. Returned by FPDF_LoadDocument function.
+ * hWidget - Handle to the xfa field.
+ * x - The x value of the specified point.
+ * y - The y value of the specified point.
+ * stringHandle - Pointer to FPDF_STRINGHANDLE to receive the speck check text buffer, in UTF-16LE format.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, float x, float y, FPDF_STRINGHANDLE* stringHandle);
+/**
+ * Function: FPDF_StringHandleCounts
+ * This method will get the count of the text buffer.
+ * Parameters:
+ * stringHandle - Pointer to FPDF_STRINGHANDLE.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE stringHandle);
+/**
+ * Function: FPDF_StringHandleGetStringByIndex
+ * This method will get the specified index of the text buffer.
+ * Parameters:
+ * stringHandle - Pointer to FPDF_STRINGHANDLE.
+ * index - The specified index of text buffer.
+ * bsText - Pointer to data buffer to receive the text buffer, in UTF-16LE format.
+ * size - The byte size of data buffer.
+ * Return Value:
+ * TRUE indicates success, otherwise FALSE.
+ **/
+DLLEXPORT FPDF_BOOL STDCALL FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE stringHandle, int index, FPDF_BYTESTRING bsText, FPDF_DWORD* size);
+/**
+ * Function: FPDF_StringHandleRelease
+ * This method will release the FPDF_STRINGHANDLE.
+ * Parameters:
+ * stringHandle - Pointer to FPDF_STRINGHANDLE.
+ * Return Value:
+ * None.
+ **/
+DLLEXPORT void STDCALL FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle);
+/**
+ * Function: FPDF_StringHandleAddString
+ * This method will add the specified text buffer.
+ * Parameters:
+ * stringHandle - Pointer to FPDF_STRINGHANDLE.
+ * bsText - Pointer to data buffer of the text buffer, in UTF-16LE format.
+ * size - The byte size of data buffer.
+ * Return Value:
+ * TRUE indicates success, otherwise FALSE.
+ **/
+DLLEXPORT FPDF_BOOL STDCALL FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle, FPDF_BYTESTRING bsText, FPDF_DWORD size);
#ifdef __cplusplus
};
diff --git a/fpdfsdk/include/fpdfppo.h b/fpdfsdk/include/fpdfppo.h
index 3e7e5c9a5e..db78a1942d 100644
--- a/fpdfsdk/include/fpdfppo.h
+++ b/fpdfsdk/include/fpdfppo.h
@@ -23,6 +23,9 @@ extern "C" {
// index - The page index wanted to insert from.
// Return value:
// TRUE for succeed, FALSE for Failed.
+// Notes:
+// The method not support this feature for the document consists of dynamic XFA fields.
+//
DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,FPDF_DOCUMENT src_doc, FPDF_BYTESTRING pagerange, int index);
diff --git a/fpdfsdk/include/fpdftext.h b/fpdfsdk/include/fpdftext.h
index 8b897798e6..143a6c6a8e 100644
--- a/fpdfsdk/include/fpdftext.h
+++ b/fpdfsdk/include/fpdftext.h
@@ -24,6 +24,8 @@ extern "C" {
// Comments:
// Application must call FPDFText_ClosePage to release the text page information.
// If you don't purchase Text Module , this function will return NULL.
+// Notes:
+// The method can not support to load out FPDF_TEXTPAGE for the document consists of dynamic fields.
//
DLLEXPORT FPDF_TEXTPAGE STDCALL FPDFText_LoadPage(FPDF_PAGE page);
diff --git a/fpdfsdk/include/fpdfview.h b/fpdfsdk/include/fpdfview.h
index 4dcdcf620a..161bca2809 100644
--- a/fpdfsdk/include/fpdfview.h
+++ b/fpdfsdk/include/fpdfview.h
@@ -18,6 +18,8 @@ typedef void* FPDF_MODULEMGR;
// PDF types
typedef void* FPDF_DOCUMENT;
typedef void* FPDF_PAGE;
+typedef void* FPDF_WIDGET;
+typedef void* FPDF_STRINGHANDLE;
typedef void* FPDF_PAGEOBJECT; // Page object(text, path, etc)
typedef void* FPDF_PATH;
typedef void* FPDF_CLIPPATH;
@@ -37,6 +39,9 @@ typedef void* FPDF_LINK;
typedef void* FPDF_PAGERANGE;
// Basic data types
+typedef void* FPDF_LPVOID;
+typedef void const* FPDF_LPCVOID;
+typedef int FPDF_RESULT;
typedef int FPDF_BOOL;
typedef int FPDF_ERROR;
typedef unsigned long FPDF_DWORD;
@@ -54,6 +59,7 @@ typedef enum _FPDF_DUPLEXTYPE_ {
// String types
typedef unsigned short FPDF_WCHAR;
typedef unsigned char const* FPDF_LPCBYTE;
+typedef char const* FPDF_LPCSTR;
// FPDFSDK may use three types of strings: byte string, wide string (UTF-16LE encoded), and platform dependent string
typedef const char* FPDF_BYTESTRING;
@@ -61,6 +67,26 @@ typedef const char* FPDF_BYTESTRING;
typedef const unsigned short* FPDF_WIDESTRING; // Foxit PDF SDK always use UTF-16LE encoding wide string,
// each character use 2 bytes (except surrogation), with low byte first.
+#ifndef _FPDF_DEF_STR_
+#define _FPDF_DEF_STR_
+/** @brief Structure for byte string.
+ *
+ * @note In SDK, a byte string commonly means a UTF-16LE format string.
+ */
+typedef struct _FPDF_BSTR
+{
+ /**
+ * @brief String buffer.
+ */
+ char* str;
+ /**
+ * @brief Length of a string, in bytes.
+ */
+ int len;
+} FPDF_BSTR;
+
+#endif
+
// For Windows programmers: for most case it's OK to treat FPDF_WIDESTRING as Windows unicode string,
// however, special care needs to be taken if you expect to process Unicode larger than 0xffff.
// For Linux/Unix programmers: most compiler/library environment uses 4 bytes for a Unicode character,
@@ -166,6 +192,9 @@ DLLEXPORT void STDCALL FPDF_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable
* @note Loaded document can be closed by FPDF_CloseDocument.
* If this function fails, you can use FPDF_GetLastError() to retrieve
* the reason why it fails.
+* The application should call ::FPDF_LoadXFA function after PDF document loaded
+* to support XFA fields in fpdfformfill.h file.
+*
* @retval A handle to the loaded document. If failed, NULL is returned.
*/
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path,
@@ -185,6 +214,9 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path,
// Loaded document can be closed by FPDF_CloseDocument.
// If this function fails, you can use FPDF_GetLastError() to retrieve
// the reason why it fails.
+// Notes:
+// The application should call ::FPDF_LoadXFA function after PDF document loaded
+// to support XFA fields in fpdfformfill.h file.
//
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf,
int size, FPDF_BYTESTRING password);
@@ -206,6 +238,78 @@ typedef struct {
void* m_Param;
} FPDF_FILEACCESS;
+/**
+ * @brief Structure for file reading or writing (I/O).
+ *
+ * @note This is a handler and should be implemented by callers.
+ */
+typedef struct _FPDF_FILEHANDLER
+{
+ /**
+ * @brief User-defined data.
+ * @note Callers can use this field to track controls.
+ */
+ FPDF_LPVOID clientData;
+ /**
+ * @brief Callback function to release the current file stream object.
+ *
+ * @param[in] clientData Pointer to user-defined data.
+ *
+ * @return None.
+ */
+ void (*Release)(FPDF_LPVOID clientData);
+ /**
+ * @brief Callback function to retrieve the current file stream size.
+ *
+ * @param[in] clientData Pointer to user-defined data.
+ *
+ * @return Size of file stream.
+ */
+ FPDF_DWORD (*GetSize)(FPDF_LPVOID clientData);
+ /**
+ * @brief Callback function to read data from the current file stream.
+ *
+ * @param[in] clientData Pointer to user-defined data.
+ * @param[in] offset Offset position starts from the beginning of file stream. This parameter indicates reading position.
+ * @param[in] buffer Memory buffer to store data which are read from file stream. This parameter should not be <b>NULL</b>.
+ * @param[in] size Size of data which should be read from file stream, in bytes. The buffer indicated by the parameter <i>buffer</i> should be enough to store specified data.
+ *
+ * @return 0 for success, other value for failure.
+ */
+ FPDF_RESULT (*ReadBlock)(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPVOID buffer, FPDF_DWORD size);
+ /**
+ * @brief Callback function to write data into the current file stream.
+ *
+ * @param[in] clientData Pointer to user-defined data.
+ * @param[in] offset Offset position starts from the beginning of file stream. This parameter indicates writing position.
+ * @param[in] buffer Memory buffer contains data which is written into file stream. This parameter should not be <b>NULL</b>.
+ * @param[in] size Size of data which should be written into file stream, in bytes.
+ *
+ * @return 0 for success, other value for failure.
+ */
+ FPDF_RESULT (*WriteBlock)(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPCVOID buffer, FPDF_DWORD size);
+ /**
+ * @brief Callback function to flush all internal accessing buffers.
+ *
+ * @param[in] clientData Pointer to user-defined data.
+ *
+ * @return 0 for success, other value for failure.
+ */
+ FPDF_RESULT (*Flush)(FPDF_LPVOID clientData);
+ /**
+ * @brief Callback function to change file size.
+ *
+ * @details This function is called under writing mode usually. Implementer can determine whether to realize it based on application requests.
+ *
+ * @param[in] clientData Pointer to user-defined data.
+ * @param[in] size New size of file stream, in bytes.
+ *
+ * @return 0 for success, other value for failure.
+ */
+ FPDF_RESULT (*Truncate)(FPDF_LPVOID clientData, FPDF_DWORD size);
+
+} FPDF_FILEHANDLER, *FPDF_LPFILEHANDLER;
+
// Function: FPDF_LoadCustomDocument
// Load PDF document from a custom access descriptor.
// Parameters:
@@ -216,6 +320,10 @@ typedef struct {
// Comments:
// The application should maintain the file resources being valid until the PDF document close.
// Loaded document can be closed by FPDF_CloseDocument.
+// Notes:
+// The application should call ::FPDF_LoadXFA function after PDF document loaded
+// to support XFA fields in fpdfformfill.h file.
+//
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess,
FPDF_BYTESTRING password);
@@ -228,6 +336,7 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAc
// TRUE if this call succeed, If failed, FALSE is returned.
// Comments:
// If the document is created by function ::FPDF_CreateNewDocument, then this function would always fail.
+//
DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, int* fileVersion);
#define FPDF_ERR_SUCCESS 0 // No error.
@@ -237,6 +346,8 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, int* fileVers
#define FPDF_ERR_PASSWORD 4 // Password required or incorrect password.
#define FPDF_ERR_SECURITY 5 // Unsupported security scheme.
#define FPDF_ERR_PAGE 6 // Page not found or content error.
+#define FPDF_ERR_XFALOAD 7 // Load XFA error.
+#define FPDF_ERR_XFALAYOUT 8 // Layout XFA error.
// Function: FPDF_GetLastError
// Get last error code when an SDK function failed.
@@ -354,6 +465,8 @@ DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document, int page_i
// flags - 0 for normal display, or combination of flags defined above.
// Return value:
// None.
+// Notes:
+// The method can not support to render the page for the document consists of dynamic XFA fields.
//
DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
int rotate, int flags);
@@ -374,6 +487,8 @@ DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, FPDF_PAGE page, int start_x, int
// flags - 0 for normal display, or combination of flags defined above.
// Return value:
// None.
+// Notes:
+// The method can not support to render the page for the document consists of dynamic XFA fields.
//
DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page, int start_x, int start_y,
int size_x, int size_y, int rotate, int flags);
@@ -612,6 +727,18 @@ DLLEXPORT FPDF_DUPLEXTYPE STDCALL FPDF_VIEWERREF_GetDuplex(FPDF_DOCUMENT documen
//
DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,FPDF_BYTESTRING name);
+// Function: FPDF_BStr_Init
+// Helper function to initialize a byte string.
+DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Init(FPDF_BSTR* str);
+
+// Function: FPDF_BStr_Set
+// Helper function to set string data.
+DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Set(FPDF_BSTR* str, FPDF_LPCSTR bstr, int length);
+
+// Function: FPDF_BStr_Clear
+// Helper function to clear a byte string.
+DLLEXPORT FPDF_RESULT STDCALL FPDF_BStr_Clear(FPDF_BSTR* str);
+
#ifdef __cplusplus
};
#endif
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
new file mode 100644
index 0000000000..c77aae3b12
--- /dev/null
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_app.h
@@ -0,0 +1,140 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FPDFXFA_APP_H_
+#define _FPDFXFA_APP_H_
+
+class CPDFXFA_App;
+class IFXJS_Runtime;
+class CJS_RuntimeFactory;
+
+class CPDFXFA_App : public IXFA_AppProvider, public CFX_Object
+{
+public:
+ CPDFXFA_App();
+ ~CPDFXFA_App();
+
+ FX_BOOL Initialize();
+
+ IXFA_App* GetXFAApp() { return m_pXFAApp; }
+
+
+ /*CPDFDoc_Environment*GetFormFillEnv(){ return m_pEnv; }*/
+ FX_BOOL AddFormFillEnv(CPDFDoc_Environment* pEnv);
+ FX_BOOL RemoveFormFillEnv(CPDFDoc_Environment* pEnv);
+
+ FXJSE_HRUNTIME GetJSERuntime() { return m_hJSERuntime; }
+
+ void ReleaseRuntime();
+
+ FX_BOOL InitRuntime(FX_BOOL bReset = FALSE) {
+ if (bReset) {
+ m_bInitRuntime = FALSE;
+ return TRUE;
+ }
+ if (m_bInitRuntime)
+ return TRUE;
+ m_bInitRuntime = TRUE;
+ return FALSE;
+ }
+
+ //IFXJS_Runtime* GetJSRuntime();
+
+ CJS_RuntimeFactory* GetRuntimeFactory() {return m_pJSRuntimeFactory;}
+
+public:
+ /**
+ *Specifies the name of the client application in which a form currently exists. Such as Exchange-Pro.
+ */
+ virtual void GetAppType(CFX_WideString &wsAppType);
+ virtual void SetAppType(FX_WSTR wsAppType) ;
+ virtual void SetFoxitAppType(FX_WSTR wsFoxitAppType) { return; }
+ virtual void GetFoxitAppType(CFX_WideString &wsFoxitAppType) { return; }
+ virtual void GetFoxitAppName(CFX_WideString& wsFoxitName) {wsFoxitName = L"Foxit";}
+ virtual void GetFoxitVersion(CFX_WideString &wsFoxitVersion) {wsFoxitVersion = L"7.0";}
+ /**
+ *Returns the language of the running host application. Such as zh_CN
+ */
+ virtual void GetLanguage(CFX_WideString &wsLanguage);
+ /**
+ *Returns the platform of the machine running the script. Such as WIN
+ */
+ virtual void GetPlatform(CFX_WideString &wsPlatform);
+ /**
+ * Indicates the packaging of the application that is running the script. Such as Full
+ */
+ virtual void GetVariation(CFX_WideString &wsVariation);
+ /**
+ * Indicates the version number of the current application. Such as 9
+ */
+ virtual void GetVersion(CFX_WideString &wsVersion);
+ //Get application name, such as Phantom
+ virtual void GetAppName(CFX_WideString& wsName);
+ /**
+ *Causes the system to play a sound.
+ * @param[in] dwType The system code for the appropriate sound.0 (Error)1 (Warning)2 (Question)3 (Status)4 (Default)
+ */
+ virtual void Beep(FX_DWORD dwType);
+ /**
+ * Displays a message box.
+ * @param[in] dwIconType Icon type, refer to XFA_MBICON.
+ * @param[in] dwButtonType Button type, refer to XFA_MESSAGEBUTTON.
+ * @return A valid integer representing the value of the button pressed by the user, refer to XFA_ID.
+ */
+ virtual FX_INT32 MsgBox(FX_WSTR wsMessage, FX_WSTR wsTitle = FX_WSTRC(L""), FX_DWORD dwIconType = 0, FX_DWORD dwButtonType = 0);
+ //bMark True (default) Masks the user¡¯s answer with * (asterisks). False Does not mask the user¡¯s answer.
+ virtual void Response(CFX_WideString &wsAnswer, FX_WSTR wsQuestion, FX_WSTR wsTitle = FX_WSTRC(L""), FX_WSTR wsDefaultAnswer = FX_WSTRC(L""), FX_BOOL bMark = TRUE);
+ virtual FX_INT32 GetDocumentCountInBatch();
+ virtual FX_INT32 GetCurDocumentInBatch();
+ //wsURL http, ftp, such as "http://www.w3.org/TR/REC-xml-names/".
+ virtual IFX_FileRead* DownloadURL(FX_WSTR wsURL);
+ /*
+ * Post data to the given url.
+ * @param[in] wsURL the URL being uploaded.
+ * @param[in] wsData the data being uploaded.
+ * @param[in] wsContentType the content type of data including text/html, text/xml, text/plain, multipart/form-data,
+ * application/x-www-form-urlencoded, application/octet-stream, any valid MIME type.
+ * @param[in] wsEncode the encode of data including UTF-8, UTF-16, ISO8859-1, any recognized [IANA]character encoding
+ * @param[in] wsHeader any additional HTTP headers to be included in the post.
+ * @param[out] wsResponse decoded response from server.
+ * @return TRUE Server permitted the post request, FALSE otherwise.
+ */
+ virtual FX_BOOL PostRequestURL(FX_WSTR wsURL, FX_WSTR wsData, FX_WSTR wsContentType,
+ FX_WSTR wsEncode, FX_WSTR wsHeader, CFX_WideString &wsResponse);
+
+ /*
+ * Put data to the given url.
+ * @param[in] wsURL the URL being uploaded.
+ * @param[in] wsData the data being uploaded.
+ * @param[in] wsEncode the encode of data including UTF-8, UTF-16, ISO8859-1, any recognized [IANA]character encoding
+ * @return TRUE Server permitted the post request, FALSE otherwise.
+ */
+ virtual FX_BOOL PutRequestURL(FX_WSTR wsURL, FX_WSTR wsData, FX_WSTR wsEncode);
+
+ virtual void LoadString(FX_INT32 iStringID, CFX_WideString &wsString);
+ virtual FX_BOOL ShowFileDialog(FX_WSTR wsTitle, FX_WSTR wsFilter, CFX_WideStringArray &wsPathArr, FX_BOOL bOpen = TRUE);
+ virtual IFWL_AdapterTimerMgr* GetTimerMgr();
+
+ CFX_ArrayTemplate<CPDFDoc_Environment*> m_pEnvList;
+
+public:
+ static CPDFXFA_App* m_pApp;
+
+private:
+ IXFA_App* m_pXFAApp;
+ IXFA_FontMgr* m_pFontMgr;
+ FXJSE_HRUNTIME m_hJSERuntime;
+ IFXJS_Runtime* m_pJSRuntime;
+ CJS_RuntimeFactory* m_pJSRuntimeFactory;
+
+ CFX_WideString m_csAppType;
+ FX_BOOL m_bInitRuntime;
+};
+
+CPDFXFA_App* FPDFXFA_GetApp();
+void FPDFXFA_ReleaseApp();
+
+#endif
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
new file mode 100644
index 0000000000..fadded858f
--- /dev/null
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h
@@ -0,0 +1,148 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FPDFXFA_DOC_H_
+#define _FPDFXFA_DOC_H_
+
+class CPDFXFA_App;
+class CPDFXFA_Document;
+class CPDFXFA_Page;
+class CPDFSDK_Document;
+class CPDFDoc_Environment;
+class IFXJS_Runtime;
+class IFXJS_Context;
+
+class CPDFXFA_Document : public IXFA_DocProvider, public CFX_Object
+{
+public:
+ CPDFXFA_Document(CPDF_Document* pPDFDoc, CPDFXFA_App* pProvider);
+ ~CPDFXFA_Document();
+
+ FX_BOOL LoadXFADoc();
+ void CloseXFADoc();
+ CPDFXFA_App* GetApp() {return m_pApp;}
+ CPDF_Document* GetPDFDoc() { return m_pPDFDoc; }
+ XFA_HDOC GetXFADoc() { return m_pXFADoc; }
+ IXFA_DocView* GetXFADocView() { return m_pXFADocView; }
+
+ int GetPageCount();
+ CPDFXFA_Page* GetPage(int page_index);
+ CPDFXFA_Page* GetPage(IXFA_PageView* pPage);
+ void RemovePage(CPDFXFA_Page* page);
+ int GetDocType(){ return m_iDocType; }
+
+ CPDFSDK_Document* GetSDKDocument(CPDFDoc_Environment* pFormFillEnv);
+ void ReleaseSDKDoc();
+
+ void FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect);
+
+public:
+ virtual void SetChangeMark(XFA_HDOC hDoc);
+ virtual FX_BOOL GetChangeMark(XFA_HDOC hDoc);
+ //used in dynamic xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.
+ virtual void InvalidateRect(IXFA_PageView* pPageView, const CFX_RectF& rt, FX_DWORD dwFlags = 0);
+ //used in static xfa, dwFlags refer to XFA_INVALIDATE_XXX macros.
+ virtual void InvalidateRect(XFA_HWIDGET hWidget, FX_DWORD dwFlags = 0);
+ //show or hide caret
+ virtual void DisplayCaret(XFA_HWIDGET hWidget, FX_BOOL bVisible, const CFX_RectF* pRtAnchor);
+ //dwPos: (0:bottom 1:top)
+ virtual FX_BOOL GetPopupPos(XFA_HWIDGET hWidget, FX_FLOAT fMinPopup, FX_FLOAT fMaxPopup,
+ const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+ virtual FX_BOOL PopupMenu(XFA_HWIDGET hWidget, CFX_PointF ptPopup, const CFX_RectF* pRectExclude = NULL);
+
+ //dwFlags XFA_PAGEVIEWEVENT_Added, XFA_PAGEVIEWEVENT_Removing
+ virtual void PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags);
+ //dwEvent refer to XFA_WIDGETEVENT_XXX
+ virtual void WidgetEvent(XFA_HWIDGET hWidget, CXFA_WidgetAcc* pWidgetData, FX_DWORD dwEvent, FX_LPVOID pParam = NULL, FX_LPVOID pAdditional = NULL);
+
+ //return true if render it.
+ virtual FX_BOOL RenderCustomWidget(XFA_HWIDGET hWidget, CFX_Graphics* pGS, CFX_Matrix* pMatrix, const CFX_RectF& rtUI){return FALSE;}
+
+ //host method
+ virtual FX_INT32 CountPages(XFA_HDOC hDoc);
+ virtual FX_INT32 GetCurrentPage(XFA_HDOC hDoc);
+ virtual void SetCurrentPage(XFA_HDOC hDoc, FX_INT32 iCurPage);
+ virtual FX_BOOL IsCalculationsEnabled(XFA_HDOC hDoc);
+ virtual void SetCalculationsEnabled(XFA_HDOC hDoc, FX_BOOL bEnabled);
+ virtual void GetTitle(XFA_HDOC hDoc, CFX_WideString &wsTitle);
+ virtual void SetTitle(XFA_HDOC hDoc, FX_WSTR wsTitle);
+ virtual void ExportData(XFA_HDOC hDoc, FX_WSTR wsFilePath, FX_BOOL bXDP = TRUE);
+ virtual void ImportData(XFA_HDOC hDoc, FX_WSTR wsFilePath);
+ virtual void GotoURL(XFA_HDOC hDoc, FX_WSTR bsURL, FX_BOOL bAppend = TRUE);
+ virtual FX_BOOL IsValidationsEnabled(XFA_HDOC hDoc);
+ virtual void SetValidationsEnabled(XFA_HDOC hDoc, FX_BOOL bEnabled);
+ virtual void SetFocusWidget(XFA_HDOC hDoc, XFA_HWIDGET hWidget);
+ virtual void Print(XFA_HDOC hDoc, FX_INT32 nStartPage, FX_INT32 nEndPage, FX_DWORD dwOptions);
+
+ //LayoutPseudo method
+ virtual FX_INT32 AbsPageCountInBatch(XFA_HDOC hDoc){return 0;}
+ virtual FX_INT32 AbsPageInBatch(XFA_HDOC hDoc, XFA_HWIDGET hWidget){return 0;}
+ virtual FX_INT32 SheetCountInBatch(XFA_HDOC hDoc){return 0;}
+ virtual FX_INT32 SheetInBatch(XFA_HDOC hDoc, XFA_HWIDGET hWidget){return 0;}
+
+ //SignaturePseudoModel method
+ //TODO:
+ virtual FX_INT32 Verify(XFA_HDOC hDoc, CXFA_Node* pSigNode, FX_BOOL bUsed = TRUE/*, SecurityHandler* pHandler, SignatureInfo &info*/) {return 0;}
+ virtual FX_BOOL Sign(XFA_HDOC hDoc, CXFA_NodeList* pNodeList, FX_WSTR wsExpression, FX_WSTR wsXMLIdent, FX_WSTR wsValue = FX_WSTRC(L"open"), FX_BOOL bUsed = TRUE/*, SecurityHandler* pHandler = NULL, SignatureInfo &info*/) {return 0;}
+ virtual CXFA_NodeList* Enumerate(XFA_HDOC hDoc) {return 0;}
+ virtual FX_BOOL Clear(XFA_HDOC hDoc, CXFA_Node* pSigNode, FX_BOOL bCleared = TRUE) {return 0;}
+
+ //Get document path
+ virtual void GetURL(XFA_HDOC hDoc, CFX_WideString &wsDocURL);
+ virtual FX_ARGB GetHighlightColor(XFA_HDOC hDoc);
+ virtual void AddDoRecord(XFA_HWIDGET hWidget);
+ /**
+ *Submit data to email, http, ftp.
+ * @param[in] hDoc The document handler.
+ * @param[in] eFormat Determines the format in which the data will be submitted. XFA_ATTRIBUTEENUM_Xdp, XFA_ATTRIBUTEENUM_Xml...
+ * @param[in] wsTarget The URL to which the data will be submitted.
+ * @param[in] eEncoding The encoding of text content.
+ * @param[in] pXDPContent Controls what subset of the data is submitted, used only when the format property is xdp.
+ * @param[in] bEmbedPDF, specifies whether PDF is embedded in the submitted content or not.
+ */
+ virtual FX_BOOL SubmitData(XFA_HDOC hDoc, CXFA_Submit submit);
+
+ virtual FX_BOOL CheckWord(XFA_HDOC hDoc, FX_BSTR sWord){return FALSE;}
+ virtual FX_BOOL GetSuggestWords(XFA_HDOC hDoc, FX_BSTR sWord, CFX_ByteStringArray& sSuggest){return FALSE;}
+
+ //Get PDF javascript object, set the object to hValue.
+ virtual FX_BOOL GetPDFScriptObject(XFA_HDOC hDoc, FX_BSTR utf8Name, FXJSE_HVALUE hValue);
+
+ virtual FX_BOOL GetGlobalProperty(XFA_HDOC hDoc, FX_BSTR szPropName, FXJSE_HVALUE hValue);
+ virtual FX_BOOL SetGlobalProperty(XFA_HDOC hDoc, FX_BSTR szPropName, FXJSE_HVALUE hValue);
+ virtual CPDF_Document* OpenPDF(XFA_HDOC hDoc, IFX_FileRead* pFile, FX_BOOL bTakeOverFile){return NULL;}
+
+ virtual IFX_FileRead* OpenLinkedFile(XFA_HDOC hDoc, const CFX_WideString& wsLink);
+
+ FX_BOOL _GetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue, IFXJS_Runtime* runTime);
+ FX_BOOL _OnBeforeNotifySumbit();
+ void _OnAfterNotifySumbit();
+ FX_BOOL _NotifySubmit(FX_BOOL bPrevOrPost);
+ FX_BOOL _SubmitData(XFA_HDOC hDoc, CXFA_Submit submit);
+ FX_BOOL _MailToInfo(CFX_WideString& csURL, CFX_WideString& csToAddress, CFX_WideString& csCCAddress, CFX_WideString& csBCCAddress, CFX_WideString& csSubject, CFX_WideString& csMsg);
+ FX_BOOL _ExportSubmitFile(FPDF_FILEHANDLER* ppFileHandler, int fileType, FPDF_DWORD encodeType, FPDF_DWORD flag = 0x01111111);
+ void _ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag);
+ void _ClearChangeMark();
+
+private:
+ CPDF_Document* m_pPDFDoc;
+ XFA_HDOC m_pXFADoc;
+ IXFA_DocView* m_pXFADocView;
+ CFX_ArrayTemplate<CPDFXFA_Page*> m_XFAPageList;
+
+ CPDFSDK_Document* m_pSDKDoc;
+ CPDFXFA_App* m_pApp;
+
+ CFX_MapByteStringToPtr m_XfaGlobalProperty;
+
+ CFX_MapByteStringToPtr m_ValueMap;
+
+ IFXJS_Context* m_pJSContext;
+
+ int m_iDocType;
+};
+
+#endif
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h
new file mode 100644
index 0000000000..1d60c33e43
--- /dev/null
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_page.h
@@ -0,0 +1,50 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FPDFXFA_PAGEVIEW_H_
+#define _FPDFXFA_PAGEVIEW_H_
+
+class CPDFXFA_Page;
+
+class CPDFXFA_Page : public CFX_Object
+{
+public:
+ CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index);
+ ~CPDFXFA_Page();
+
+ void Release();
+ void AddRef(){ m_iRef ++; }
+ FX_BOOL LoadPage();
+ FX_BOOL LoadPDFPage(CPDF_Dictionary* pageDict);
+ CPDFXFA_Document* GetDocument() { return m_pDocument; }
+ int GetPageIndex() { return m_iPageIndex; }
+ CPDF_Page* GetPDFPage() { return m_pPDFPage; }
+ IXFA_PageView* GetXFAPageView() { return m_pXFAPageView; }
+
+ FX_FLOAT GetPageWidth();
+ FX_FLOAT GetPageHeight();
+
+ void DeviceToPage(int start_x, int start_y, int size_x, int size_y,
+ int rotate, int device_x, int device_y, double* page_x, double* page_y);
+ void PageToDevice(int start_x, int start_y, int size_x, int size_y,
+ int rotate, double page_x, double page_y, int* device_x, int* device_y);
+
+ void GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos,
+ int xSize, int ySize, int iRotate) const;
+
+protected:
+ FX_BOOL LoadPDFPage();
+ FX_BOOL LoadXFAPageView();
+
+private:
+ CPDF_Page* m_pPDFPage;
+ IXFA_PageView* m_pXFAPageView;
+ int m_iPageIndex;
+ CPDFXFA_Document* m_pDocument;
+ int m_iRef;
+};
+
+#endif
diff --git a/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h b/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h
new file mode 100644
index 0000000000..07ea65f2b1
--- /dev/null
+++ b/fpdfsdk/include/fpdfxfa/fpdfxfa_util.h
@@ -0,0 +1,50 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FPDFXFA_UTIL_H_
+#define _FPDFXFA_UTIL_H_
+
+#define DOCTYPE_PDF 0
+#define DOCTYPE_DYNIMIC_XFA 1 //Dynimic xfa Document Type
+#define DOCTYPE_STATIC_XFA 2 //Static xfa Document Type
+
+#define JS_STR_VIEWERTYPE_STANDARD L"Exchange"
+#define JS_STR_LANGUANGE L"ENU"
+#define JS_STR_VIEWERVARIATION L"Full"
+#define JS_STR_VIEWERVERSION_XFA L"11"
+
+FX_BOOL FPDF_HasXFAField(CPDF_Document* pPDFDoc, int& docType);
+
+class CXFA_FWLAdapterTimerMgr : public IFWL_AdapterTimerMgr, public CFX_Object
+{
+public:
+ CXFA_FWLAdapterTimerMgr(CPDFDoc_Environment* pEnv) : m_pEnv(pEnv)
+ {
+
+ }
+ virtual FWL_ERR Start(IFWL_Timer *pTimer, FX_DWORD dwElapse, FWL_HTIMER &hTimer, FX_BOOL bImmediately = TRUE);
+ virtual FWL_ERR Stop(FWL_HTIMER hTimer);
+
+protected:
+ static void TimerProc(FX_INT32 idEvent);
+
+ static CFX_PtrArray ms_timerArray;
+ CPDFDoc_Environment* m_pEnv;
+};
+
+class CFWL_TimerInfo : public CFX_Object
+{
+public:
+ CFWL_TimerInfo()
+ : pTimer(NULL)
+ {
+
+ }
+ FX_UINT32 uIDEvent;
+ IFWL_Timer *pTimer;
+};
+
+#endif
diff --git a/fpdfsdk/include/fsdk_annothandler.h b/fpdfsdk/include/fsdk_annothandler.h
index 9f97c52596..6aa9412f68 100644
--- a/fpdfsdk/include/fsdk_annothandler.h
+++ b/fpdfsdk/include/fsdk_annothandler.h
@@ -7,6 +7,7 @@
#ifndef _FSDK_ANNOTHANDLER_H_
#define _FSDK_ANNOTHANDLER_H_
+#define FSDK_XFAWIDGET_TYPENAME "XFAWidget"
class CPDFDoc_Environment;
class CFFL_IFormFiller;
@@ -26,6 +27,8 @@ public:
virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) = 0;
+ virtual CPDFSDK_Annot* NewAnnot(XFA_HWIDGET hWidget, CPDFSDK_PageView* pPage) = 0;
+
virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot) = 0;
virtual void DeleteAnnot(CPDFSDK_Annot* pAnnot) = 0;
@@ -78,6 +81,7 @@ public:
virtual FX_BOOL OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) = 0;
virtual FX_BOOL OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) = 0;
+ virtual FX_BOOL OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot, CPDFSDK_Annot* pNewAnnot) = 0;
};
@@ -97,6 +101,8 @@ public:
virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage);
+ virtual CPDFSDK_Annot* NewAnnot(XFA_HWIDGET hWidget, CPDFSDK_PageView* pPage);
+
virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot) ;
virtual void DeleteAnnot(CPDFSDK_Annot* pAnnot) {}
@@ -148,6 +154,7 @@ public:
virtual FX_BOOL OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
virtual FX_BOOL OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
+ virtual FX_BOOL OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot, CPDFSDK_Annot* pNewAnnot){ return TRUE; }
void SetFormFiller(CFFL_IFormFiller* pFiller){m_pFormFiller = pFiller;}
CFFL_IFormFiller* GetFormFiller() {return m_pFormFiller;}
@@ -157,6 +164,86 @@ private:
CFFL_IFormFiller* m_pFormFiller;
};
+class CPDFSDK_XFAAnnotHandler : public IPDFSDK_AnnotHandler
+{
+public:
+ CPDFSDK_XFAAnnotHandler(CPDFDoc_Environment* pApp);
+ ~CPDFSDK_XFAAnnotHandler(){}
+
+public:
+ virtual CFX_ByteString GetType() { return FSDK_XFAWIDGET_TYPENAME; }
+
+ virtual CFX_ByteString GetName() { return "XFAWidgetHandler"; }
+
+ virtual FX_BOOL CanAnswer(CPDFSDK_Annot* pAnnot);
+
+
+ virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPage) { return NULL; }
+
+ virtual CPDFSDK_Annot* NewAnnot(XFA_HWIDGET pAnnot, CPDFSDK_PageView* pPage);
+
+ virtual void ReleaseAnnot(CPDFSDK_Annot* pAnnot);
+
+ virtual void DeleteAnnot(CPDFSDK_Annot* pAnnot) {}
+
+
+ virtual CPDF_Rect GetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot);
+
+ virtual FX_BOOL HitTest(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, const CPDF_Point& point);
+
+
+ virtual void OnDraw(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot,
+ CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+ FX_DWORD dwFlags);
+
+ virtual void OnDrawSleep(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot,
+ CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+ const CPDF_Rect& rcWindow, FX_DWORD dwFlags) {}
+
+
+
+
+ virtual void OnCreate(CPDFSDK_Annot* pAnnot) {}
+
+ virtual void OnLoad(CPDFSDK_Annot* pAnnot) {}
+
+ virtual void OnDelete(CPDFSDK_Annot* pAnnot) {}
+
+ virtual void OnRelease(CPDFSDK_Annot* pAnnot) {}
+
+
+ virtual void OnMouseEnter(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
+ virtual void OnMouseExit(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
+
+
+ virtual FX_BOOL OnLButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point);
+ virtual FX_BOOL OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point) ;
+ virtual FX_BOOL OnLButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point) ;
+ virtual FX_BOOL OnMouseMove(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point);
+ virtual FX_BOOL OnMouseWheel(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, short zDelta, const CPDF_Point& point) ;
+ virtual FX_BOOL OnRButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point);
+ virtual FX_BOOL OnRButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point) ;
+ virtual FX_BOOL OnRButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point) ;
+ //by wjm.
+ virtual FX_BOOL OnChar(CPDFSDK_Annot* pAnnot, FX_DWORD nChar, FX_DWORD nFlags);
+ virtual FX_BOOL OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag);
+ virtual FX_BOOL OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag);
+
+ virtual void OnDeSelected(CPDFSDK_Annot* pAnnot) {}
+ virtual void OnSelected(CPDFSDK_Annot* pAnnot) {}
+
+ virtual FX_BOOL OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
+ virtual FX_BOOL OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag) ;
+ virtual FX_BOOL OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot, CPDFSDK_Annot* pNewAnnot);
+
+private:
+ IXFA_WidgetHandler* GetXFAWidgetHandler(CPDFSDK_Annot* pAnnot);
+ FX_DWORD GetFWLFlags(FX_DWORD dwFlag);
+
+private:
+ CPDFDoc_Environment* m_pApp;
+};
+
#define CBA_AnnotHandlerArray CFX_ArrayTemplate<IPDFSDK_AnnotHandler*>
class CPDFSDK_AnnotHandlerMgr
{
@@ -170,6 +257,7 @@ public:
void UnRegisterAnnotHandler(IPDFSDK_AnnotHandler* pAnnotHandler);
virtual CPDFSDK_Annot* NewAnnot(CPDF_Annot * pAnnot, CPDFSDK_PageView *pPageView);
+ virtual CPDFSDK_Annot* NewAnnot(XFA_HWIDGET pAnnot, CPDFSDK_PageView* pPageView);
virtual void ReleaseAnnot(CPDFSDK_Annot * pAnnot);
virtual void Annot_OnCreate(CPDFSDK_Annot* pAnnot);
@@ -198,6 +286,7 @@ public:
virtual FX_BOOL Annot_OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
virtual FX_BOOL Annot_OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag);
+ virtual FX_BOOL Annot_OnChangeFocus(CPDFSDK_Annot* pSetAnnot,CPDFSDK_Annot* pKillAnnot);
virtual CPDF_Rect Annot_OnGetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot);
virtual FX_BOOL Annot_OnHitTest(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, const CPDF_Point& point);
diff --git a/fpdfsdk/include/fsdk_baseannot.h b/fpdfsdk/include/fsdk_baseannot.h
index 797c3f16d1..5f56fc7000 100644
--- a/fpdfsdk/include/fsdk_baseannot.h
+++ b/fpdfsdk/include/fsdk_baseannot.h
@@ -61,20 +61,33 @@ public:
class CPDFSDK_Annot
{
public:
- CPDFSDK_Annot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView);
- virtual ~CPDFSDK_Annot();
+ CPDFSDK_Annot(CPDFSDK_PageView* pPageView);
+ virtual ~CPDFSDK_Annot() {};
public:
+ virtual FX_BOOL IsXFAField() { return FALSE; }
+
virtual FX_FLOAT GetMinWidth() const;
virtual FX_FLOAT GetMinHeight() const;
//define layout order to 5.
virtual int GetLayoutOrder() const { return 5; }
+ virtual CPDF_Annot* GetPDFAnnot() { return NULL; }
+ virtual XFA_HWIDGET GetXFAWidget() { return NULL; }
+
+ virtual CFX_ByteString GetType() const { return ""; }
+ virtual CFX_ByteString GetSubType() const { return ""; }
+
+ virtual void SetRect(const CPDF_Rect& rect) {}
+ virtual CPDF_Rect GetRect() const { return CPDF_Rect(); }
+
+ virtual void Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions) {}
+
public:
- CPDF_Annot* GetPDFAnnot();
+ CPDF_Page* GetPDFPage();
+ CPDFXFA_Page* GetPDFXFAPage();
- void SetPage(CPDFSDK_PageView* pPageView);
- CPDFSDK_PageView* GetPageView();
- FX_DWORD GetFlags();
+ void SetPage(CPDFSDK_PageView* pPageView) { m_pPageView = pPageView; }
+ CPDFSDK_PageView* GetPageView() { return m_pPageView; }
// Tab Order
int GetTabOrder();
@@ -84,17 +97,35 @@ public:
FX_BOOL IsSelected();
void SetSelected(FX_BOOL bSelected);
- CFX_ByteString GetType() const;
+protected:
+ CPDF_Annot* m_pAnnot;
+ CPDFSDK_PageView* m_pPageView;
+ FX_BOOL m_bSelected;
+ int m_nTabOrder;
+
+};
+
+class CPDFSDK_BAAnnot : public CPDFSDK_Annot
+{
+public:
+ CPDFSDK_BAAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView);
+ virtual ~CPDFSDK_BAAnnot();
+
+public:
+ virtual FX_BOOL IsXFAField();
+
+ virtual CFX_ByteString GetType() const;
virtual CFX_ByteString GetSubType() const;
- CPDF_Page* GetPDFPage();
+ virtual void SetRect(const CPDF_Rect& rect);
+ virtual CPDF_Rect GetRect() const;
+
+ virtual CPDF_Annot* GetPDFAnnot();
+ virtual void Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions);
public:
CPDF_Dictionary* GetAnnotDict() const;
- void SetRect(const CPDF_Rect& rect);
- CPDF_Rect GetRect() const;
-
void SetContents(const CFX_WideString& sContents);
CFX_WideString GetContents() const;
@@ -151,32 +182,24 @@ public:
virtual CPDF_Action GetAAction(CPDF_AAction::AActionType eAAT);
public:
- FX_BOOL IsAppearanceValid();
- FX_BOOL IsAppearanceValid(CPDF_Annot::AppearanceMode mode);
- void DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
+ virtual FX_BOOL IsAppearanceValid();
+ virtual FX_BOOL IsAppearanceValid(CPDF_Annot::AppearanceMode mode);
+ virtual void DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions);
void DrawBorder(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
const CPDF_RenderOptions* pOptions);
void ClearCachedAP();
+ virtual void ResetAppearance();
void WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox,
const CPDF_Matrix& matrix, const CFX_ByteString& sContents,
const CFX_ByteString& sAPState = "");
-public:
- virtual void Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions);
-public:
-
-
private:
FX_BOOL CreateFormFiller();
protected:
CPDF_Annot* m_pAnnot;
- CPDFSDK_PageView* m_pPageView;
- FX_BOOL m_bSelected;
- int m_nTabOrder;
-
};
diff --git a/fpdfsdk/include/fsdk_baseform.h b/fpdfsdk/include/fsdk_baseform.h
index 073c99f199..0e199c1d90 100644
--- a/fpdfsdk/include/fsdk_baseform.h
+++ b/fpdfsdk/include/fsdk_baseform.h
@@ -20,6 +20,13 @@ class CFFL_FormFiller;
class CPDFSDK_PageView;
class CPDFSDK_InterForm;
+typedef enum _PDFSDK_XFAAActionType
+{
+ PDFSDK_XFA_Click = 0,
+ PDFSDK_XFA_Full,
+ PDFSDK_XFA_PreOpen,
+ PDFSDK_XFA_PostOpen
+}PDFSDK_XFAAActionType;
typedef struct _PDFSDK_FieldAction
{
@@ -48,9 +55,26 @@ typedef struct _PDFSDK_FieldAction
FX_BOOL bFieldFull; //in
FX_BOOL bRC; //in[out]
}PDFSDK_FieldAction;
-class CPDFSDK_Widget:public CPDFSDK_Annot
+class CPDFSDK_Widget:public CPDFSDK_BAAnnot
{
public:
+ XFA_HWIDGET GetMixXFAWidget();
+ XFA_HWIDGET GetGroupMixXFAWidget();
+ IXFA_WidgetHandler* GetXFAWidgetHandler();
+
+ FX_BOOL HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT);
+ FX_BOOL OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT, PDFSDK_FieldAction& data, CPDFSDK_PageView* pPageView);
+
+ void Synchronize(FX_BOOL bSynchronizeElse);
+ void SynchronizeXFAValue();
+ void SynchronizeXFAItems();
+
+ static void SynchronizeXFAValue(IXFA_DocView* pXFADocView, XFA_HWIDGET hWidget,
+ CPDF_FormField* pFormField, CPDF_FormControl* pFormControl);
+ static void SynchronizeXFAItems(IXFA_DocView* pXFADocView, XFA_HWIDGET hWidget,
+ CPDF_FormField* pFormField, CPDF_FormControl* pFormControl);
+
+public:
CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm);
virtual ~CPDFSDK_Widget();
@@ -61,6 +85,7 @@ public:
int GetFieldType() const;
//define layout order to 2.
virtual int GetLayoutOrder() const {return 2;}
+ virtual FX_BOOL IsAppearanceValid();
/*
FIELDFLAG_READONLY
FIELDFLAG_REQUIRED
@@ -75,14 +100,14 @@ public:
FX_BOOL GetTextColor(FX_COLORREF& color) const;
FX_FLOAT GetFontSize() const;
- int GetSelectedIndex(int nIndex) const;
- CFX_WideString GetValue() const;
+ int GetSelectedIndex(int nIndex);
+ CFX_WideString GetValue(FX_BOOL bDisplay = TRUE);
CFX_WideString GetDefaultValue() const;
CFX_WideString GetOptionLabel(int nIndex) const;
int CountOptions() const;
- FX_BOOL IsOptionSelected(int nIndex) const;
+ FX_BOOL IsOptionSelected(int nIndex);
int GetTopVisibleIndex() const;
- FX_BOOL IsChecked() const;
+ FX_BOOL IsChecked();
/*
BF_ALIGN_LEFT
BF_ALIGN_MIDDL
@@ -90,6 +115,7 @@ public:
*/
int GetAlignment() const;
int GetMaxLen() const;
+ CFX_WideString GetName();
CFX_WideString GetAlternateName() const;
//Set Properties.
@@ -100,6 +126,7 @@ public:
void ClearSelection(FX_BOOL bNotify);
void SetTopVisibleIndex(int index);
+ void ResetAppearance(FX_BOOL bValueChanged);
void ResetAppearance(FX_LPCWSTR sValue, FX_BOOL bValueChanged);
void ResetFieldAppearance(FX_BOOL bValueChanged);
void UpdateField();
@@ -155,9 +182,37 @@ private:
FX_BOOL m_bAppModified;
FX_INT32 m_nAppAge;
FX_INT32 m_nValueAge;
+
+ XFA_HWIDGET m_hMixXFAWidget;
+ IXFA_WidgetHandler* m_pWidgetHandler;
+};
+
+class CPDFSDK_XFAWidget : public CPDFSDK_Annot
+{
+public:
+ CPDFSDK_XFAWidget(XFA_HWIDGET pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm);
+ virtual ~CPDFSDK_XFAWidget(){}
+
+public:
+ virtual FX_BOOL IsXFAField();
+ virtual XFA_HWIDGET GetXFAWidget() { return m_hXFAWidget; }
+
+ virtual CFX_ByteString GetType() const ;
+ virtual CFX_ByteString GetSubType() const { return ""; }
+
+ virtual CFX_FloatRect GetRect();
+
+public:
+ CPDFSDK_InterForm* GetInterForm() { return m_pInterForm; }
+
+private:
+ CPDFSDK_InterForm* m_pInterForm;
+ XFA_HWIDGET m_hXFAWidget;
};
#define CPDFSDK_WidgetMap CFX_MapPtrTemplate<CPDF_FormControl*, CPDFSDK_Widget*>
+#define CPDFSDK_XFAWidgetMap CFX_MapPtrTemplate<XFA_HWIDGET, CPDFSDK_XFAWidget*>
+#define CPDFSDK_FieldSynchronizeMap CFX_MapPtrTemplate<CPDF_FormField*, int>
class CPDFSDK_InterForm : public CPDF_FormNotify
{
@@ -180,9 +235,19 @@ public:
void AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget);
void RemoveMap(CPDF_FormControl* pControl);
+ void AddXFAMap(XFA_HWIDGET hWidget, CPDFSDK_XFAWidget* pWidget);
+ void RemoveXFAMap(XFA_HWIDGET hWidget);
+ CPDFSDK_XFAWidget* GetXFAWidget(XFA_HWIDGET hWidget);
+
void EnableCalculate(FX_BOOL bEnabled);
FX_BOOL IsCalculateEnabled() const;
+ void XfaEnableCalculate(FX_BOOL bEnabled);
+ FX_BOOL IsXfaCalculateEnabled() const;
+
+ FX_BOOL IsXfaValidationsEnabled();
+ void XfaSetValidationsEnabled(FX_BOOL bEnabled);
+
#ifdef _WIN32
CPDF_Stream* LoadImageFromFile(const CFX_WideString& sFile);
#endif
@@ -216,6 +281,8 @@ public:
FX_BOOL ImportFormFromTxtFile(const CFX_WideString& sTxtFileName);
CFX_WideString GetTemporaryFileName(const CFX_WideString& sFileExt);
+ void SynchronizeField(CPDF_FormField* pFormField, FX_BOOL bSynchronizeElse);
+
private:
virtual int BeforeValueChange(const CPDF_FormField* pField, CFX_WideString& csValue);
virtual int AfterValueChange(const CPDF_FormField* pField);
@@ -237,7 +304,11 @@ private:
CPDFSDK_Document* m_pDocument;
CPDF_InterForm* m_pInterForm;
CPDFSDK_WidgetMap m_Map;
+ CPDFSDK_XFAWidgetMap m_XFAMap;
+ CPDFSDK_FieldSynchronizeMap m_FieldSynchronizeMap;
FX_BOOL m_bCalculate;
+ FX_BOOL m_bXfaCalculate;
+ FX_BOOL m_bXfaValidationsEnabled;
FX_BOOL m_bBusy;
public:
@@ -248,9 +319,9 @@ public:
void SetHighlightColor(FX_COLORREF clr, int nFieldType);
FX_COLORREF GetHighlightColor(int nFieldType);
private:
- FX_COLORREF m_aHighlightColor[6];
+ FX_COLORREF m_aHighlightColor[7];
FX_BYTE m_iHighlightAlpha;
- FX_BOOL m_bNeedHightlight[6];
+ FX_BOOL m_bNeedHightlight[7];
};
#define BAI_STRUCTURE 0
diff --git a/fpdfsdk/include/fsdk_define.h b/fpdfsdk/include/fsdk_define.h
index d249f0887f..b95d63eab4 100644
--- a/fpdfsdk/include/fsdk_define.h
+++ b/fpdfsdk/include/fsdk_define.h
@@ -59,7 +59,14 @@
#include "../../core/include/fpdfdoc/fpdf_vt.h"
#include "../../core/include/fxcrt/fx_xml.h"
- // #include "../../core/include/fdrm/fx_crypt.h"
+ #include "../../xfa/include/fxbarcode/BC_BarCode.h"
+ #include "../../xfa/include/fxjse/fxjse.h"
+ #include "../../xfa/include/fxgraphics/fx_graphics.h"
+ #include "../../xfa/include/fxfa/fxfa.h"
+
+ #include "../../xfa/include/fwl/core/fwl_error.h"
+ #include "../../xfa/include/fwl/core/fwl_timer.h"
+ #include "../../xfa/include/fwl/adapter/fwl_adaptertimermgr.h"
#ifdef _LICENSED_BUILD_
#include "../../cryptopp/Cryptlib.h"
#endif
@@ -107,14 +114,41 @@ public:
CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess);
~CPDF_CustomAccess() {}
+ virtual CFX_ByteString GetFullPath() { return ""; }
virtual FX_FILESIZE GetSize() FX_OVERRIDE { return m_FileAccess.m_FileLen; }
+ virtual FX_BOOL GetByte(FX_DWORD pos, FX_BYTE& ch);
+ virtual FX_BOOL GetBlock(FX_DWORD pos, FX_LPBYTE pBuf, FX_DWORD size);
virtual void Release() FX_OVERRIDE { delete this; }
virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size) FX_OVERRIDE;
-private:
FPDF_FILEACCESS m_FileAccess;
+ FX_BYTE m_Buffer[512];
+ FX_DWORD m_BufferOffset;
+};
+
+class CFPDF_FileStream : public IFX_FileStream, public CFX_Object
+{
+public:
+ CFPDF_FileStream(FPDF_FILEHANDLER* pFS);
+ virtual ~CFPDF_FileStream() {}
+
+ virtual IFX_FileStream* Retain();
+ virtual void Release();
+
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL IsEOF();
+ virtual FX_FILESIZE GetPosition() {return m_nCurPos;}
+ virtual void SetPosition(FX_FILESIZE pos) {m_nCurPos = pos; }
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+ virtual size_t ReadBlock(void* buffer, size_t size);
+ virtual FX_BOOL WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size);
+ virtual FX_BOOL Flush();
+
+protected:
+ FPDF_FILEHANDLER* m_pFS;
+ FX_FILESIZE m_nCurPos;
};
void FSDK_SetSandBoxPolicy(FPDF_DWORD policy, FPDF_BOOL enable);
diff --git a/fpdfsdk/include/fsdk_mgr.h b/fpdfsdk/include/fsdk_mgr.h
index a6f990c36f..5f82919e49 100644
--- a/fpdfsdk/include/fsdk_mgr.h
+++ b/fpdfsdk/include/fsdk_mgr.h
@@ -10,6 +10,8 @@
#include "fsdk_common.h"
#include "fsdk_define.h"
#include "fx_systemhandler.h"
+#include "fpdfxfa/fpdfxfa_doc.h"
+#include "fpdfxfa/fpdfxfa_page.h"
#include "fsdk_baseannot.h"
#include "fsdk_baseform.h"
#include "fpdfformfill.h"
@@ -34,11 +36,17 @@ class CJS_RuntimeFactory;
class CPDFDoc_Environment FX_FINAL
{
public:
- CPDFDoc_Environment(CPDF_Document * pDoc);
+ CPDFDoc_Environment(CPDFXFA_Document * pDoc);
~CPDFDoc_Environment();
int RegAppHandle(FPDF_FORMFILLINFO* pFFinfo);//{ m_pInfo = pFFinfo; return TRUE;}
+ virtual void Release()
+ {
+ if (m_pInfo && m_pInfo->Release)
+ m_pInfo->Release(m_pInfo);
+ delete this;
+ }
void FFI_Invalidate(FPDF_PAGE page, double left, double top, double right, double bottom)
{
if (m_pInfo && m_pInfo->FFI_Invalidate)
@@ -345,19 +353,359 @@ public:
}
}
+ void FFI_DisplayCaret(FPDF_PAGE page, FPDF_BOOL bVisible, double left, double top, double right, double bottom)
+ {
+ if (m_pInfo && m_pInfo->FFI_DisplayCaret)
+ {
+ m_pInfo->FFI_DisplayCaret(m_pInfo, page, bVisible, left, top, right, bottom);
+ }
+ }
+ int FFI_GetCurrentPageIndex(FPDF_DOCUMENT document)
+ {
+ if (m_pInfo && m_pInfo->FFI_GetCurrentPageIndex)
+ {
+ m_pInfo->FFI_GetCurrentPageIndex(m_pInfo, document);
+ }
+ return -1;
+ }
+ int FFI_SetCurrentPage(FPDF_DOCUMENT document, int iCurPage)
+ {
+ if (m_pInfo && m_pInfo->FFI_SetCurrentPage)
+ {
+ m_pInfo->FFI_SetCurrentPage(m_pInfo, document, iCurPage);
+ }
+ return -1;
+ }
+
+ CFX_WideString FFI_GetAppName()
+ {
+ return CFX_WideString(L"Acrobat");
+
+ //if (m_pInfo && m_pInfo->FFI_GetAppName)
+ //{
+ // int nLen = m_pInfo->FFI_GetAppName(m_pInfo, NULL, 0);
+ // if(nLen <= 0)
+ // return L"";
+ // char* pbuff = new char[nLen];
+ // if(pbuff)
+ // memset(pbuff, 0, nLen);
+ // else
+ // return L"";
+ // nLen = m_pInfo->FFI_GetAppName(m_pInfo, pbuff, nLen);
+ // CFX_ByteString bsRet = CFX_ByteString(pbuff, nLen);
+ // CFX_WideString wsRet = CFX_WideString::FromLocal(bsRet);
+ // delete[] pbuff;
+ // return wsRet;
+ //}
+
+ //return L"";
+ }
+
+ CFX_WideString FFI_GetPlatform()
+ {
+ if (m_pInfo && m_pInfo->FFI_GetPlatform)
+ {
+ int nRequiredLen = m_pInfo->FFI_GetPlatform(m_pInfo, NULL, 0);
+ if (nRequiredLen <= 0)
+ return L"";
+
+ char* pbuff = new char[nRequiredLen];
+ if (!pbuff)
+ return L"";
+
+ memset(pbuff, 0, nRequiredLen);
+ int nActualLen = m_pInfo->FFI_GetPlatform(m_pInfo, pbuff, nRequiredLen);
+ if (nActualLen <= 0 || nActualLen > nRequiredLen)
+ {
+ delete[] pbuff;
+ return L"";
+ }
+ CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
+ CFX_WideString wsRet = CFX_WideString::FromUTF16LE((unsigned short*)bsRet.GetBuffer(bsRet.GetLength()), bsRet.GetLength()/sizeof(unsigned short));
+ delete[] pbuff;
+ return wsRet;
+ }
+ return L"";
+ }
+
+ void FFI_GotoURL(FPDF_DOCUMENT document, FX_WSTR wsURL, FX_BOOL bAppend)
+ {
+ if (m_pInfo && m_pInfo->FFI_GotoURL)
+ {
+ CFX_ByteString bsTo = CFX_WideString(wsURL).UTF16LE_Encode();
+ FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(wsURL.GetLength());
+ m_pInfo->FFI_GotoURL(m_pInfo, document, pTo);
+ bsTo.ReleaseBuffer();
+ }
+ }
+ void FFI_GetURL(FPDF_DOCUMENT document, CFX_WideString& wsURL)
+ {
+ wsURL = CFX_WideString();
+ return;
+ //if (m_pInfo && m_pInfo->FFI_GetURL)
+ //{
+ // FPDF_WIDESTRING url = m_pInfo->FFI_GetURL(m_pInfo, document);
+ // CFX_WideString tmp;
+ // tmp.FromUTF16LE(url);
+ // wsURL = tmp;
+ //}
+ }
+
+ void FFI_AddDoRecord(FPDF_DOCUMENT document, FPDF_WIDGET hWidget)
+ {
+ //if (m_pInfo && m_pInfo->FFI_AddDoRecord)
+ //{
+ // m_pInfo->FFI_AddDoRecord(m_pInfo, document, hWidget);
+ //}
+ }
+ void FFI_PageEvent(FPDF_PAGE page, FPDF_DWORD flag)
+ {
+ //if (m_pInfo && m_pInfo->FFI_PageEvent)
+ //{
+ // m_pInfo->FFI_PageEvent(m_pInfo, page, flag);
+ //}
+ }
+
+ void FFI_GetPageViewRect(FPDF_PAGE page, FS_RECTF& dstRect)
+ {
+ if (m_pInfo && m_pInfo->FFI_GetPageViewRect)
+ {
+ double left;
+ double top;
+ double right;
+ double bottom;
+ m_pInfo->FFI_GetPageViewRect(m_pInfo, page, &left, &top, &right, &bottom);
+
+ dstRect.left = left;
+ dstRect.top = top < bottom? bottom:top;
+ dstRect.bottom = top < bottom? top:bottom;
+ dstRect.right = right;
+ }
+ }
+
+
+ FX_BOOL FFI_PopupMenu(FPDF_PAGE page, FPDF_WIDGET hWidget, int menuFlag, CFX_PointF ptPopup, const CFX_PointF* pRectExclude)
+ {
+ if (m_pInfo && m_pInfo->FFI_PopupMenu)
+ {
+ return m_pInfo->FFI_PopupMenu(m_pInfo, page, hWidget, menuFlag, ptPopup.x, ptPopup.y);
+ }
+ return FALSE;
+ }
+
+ void FFI_Alert(FPDF_WIDESTRING Msg, FPDF_WIDESTRING Title, int Type, int Icon)
+ {
+ if(m_pInfo && m_pInfo->m_pJsPlatform && m_pInfo->m_pJsPlatform->app_alert)
+ {
+ m_pInfo->m_pJsPlatform->app_alert(m_pInfo->m_pJsPlatform, Msg, Title, Type, Icon);
+ }
+ }
+ void FFI_EmailTo(FPDF_FILEHANDLER* fileHandler, FPDF_WIDESTRING pTo, FPDF_WIDESTRING pSubject, FPDF_WIDESTRING pCC, FPDF_WIDESTRING pBcc, FPDF_WIDESTRING pMsg)
+ {
+ if(m_pInfo && m_pInfo->FFI_EmailTo)
+ {
+ m_pInfo->FFI_EmailTo(m_pInfo, fileHandler, pTo, pSubject, pCC, pBcc, pMsg);
+ }
+ }
+ void FFI_UploadTo(FPDF_FILEHANDLER* fileHandler, int fileFlag, FPDF_WIDESTRING uploadTo)
+ {
+ if(m_pInfo && m_pInfo->FFI_UploadTo)
+ {
+ m_pInfo->FFI_UploadTo(m_pInfo, fileHandler, fileFlag, uploadTo);
+ }
+ }
+ FPDF_FILEHANDLER* FFI_OpenFile(int fileType, FPDF_WIDESTRING wsURL, const char* mode)
+ {
+ if(m_pInfo && m_pInfo->FFI_OpenFile)
+ {
+ return m_pInfo->FFI_OpenFile(m_pInfo, fileType, wsURL, mode);
+ }
+ return NULL;
+ }
+ CFX_WideString FFI_GetFilePath(FPDF_FILEHANDLER* pFileHandler)
+ {
+#if 0
+ if (m_pInfo && m_pInfo->FFI_GetFilePath)
+ {
+ int nRequiredLen = m_pInfo->FFI_GetFilePath(m_pInfo, pFileHandler, NULL, 0);
+ if (nRequiredLen <= 0)
+ return L"";
+
+ char* pbuff = new char[nRequiredLen];
+ if (!pbuff)
+ return L"";
+
+ memset(pbuff, 0, nRequiredLen);
+ int nActualLen = m_pInfo->FFI_GetFilePath(m_pInfo, pFileHandler, pbuff, nRequiredLen);
+ if (nActualLen <= 0 || nActualLen > nRequiredLen)
+ {
+ delete[] pbuff;
+ return L"";
+ }
+ CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
+ CFX_WideString wsRet = CFX_WideString::FromUTF16LE((unsigned short*)bsRet.GetBuffer(bsRet.GetLength()), bsRet.GetLength()/sizeof(unsigned short));
+ delete[] pbuff;
+ return wsRet;
+ }
+ return L"";
+#else
+ return L"";
+#endif
+ }
+ int FFI_GetDocumentCount()
+ {
+ //if (m_pInfo && m_pInfo->FFI_GetDocumentCount)
+ //{
+ //return m_pInfo->FFI_GetDocumentCount(m_pInfo);
+ //}
+ return 0;
+ }
+
+ int FFI_GetCurDocument()
+ {
+ //if (m_pInfo && m_pInfo->FFI_GetCurDocumentIndex)
+ //{
+ // return m_pInfo->FFI_GetCurDocumentIndex(m_pInfo);
+ //}
+ return 0;
+ }
+
+ IFX_FileRead* FFI_DownloadFromURL(FX_LPCWSTR url)
+ {
+ if (m_pInfo && m_pInfo->FFI_DownloadFromURL)
+ {
+ CFX_ByteString bstrURL = CFX_WideString(url).UTF16LE_Encode();
+ FPDF_WIDESTRING wsURL = (FPDF_WIDESTRING)bstrURL.GetBuffer(bstrURL.GetLength());
+
+ FPDF_LPFILEHANDLER fileHandler = m_pInfo->FFI_DownloadFromURL(m_pInfo, wsURL);
+
+ CFPDF_FileStream* fileStream = FX_NEW CFPDF_FileStream(fileHandler);
+ return fileStream;
+ }
+ return NULL;
+ }
+
+ CFX_WideString FFI_PostRequestURL(FX_LPCWSTR wsURL, FX_LPCWSTR wsData, FX_LPCWSTR wsContentType, FX_LPCWSTR wsEncode, FX_LPCWSTR wsHeader)
+ {
+ if (m_pInfo && m_pInfo->FFI_PostRequestURL)
+ {
+ CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
+ FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
+
+ CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
+ FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
+
+ CFX_ByteString bsContentType = CFX_WideString(wsContentType).UTF16LE_Encode();
+ FPDF_WIDESTRING contentType = (FPDF_WIDESTRING)bsContentType.GetBuffer(bsContentType.GetLength());
+
+ CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
+ FPDF_WIDESTRING encode = (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
+
+ CFX_ByteString bsHeader = CFX_WideString(wsHeader).UTF16LE_Encode();
+ FPDF_WIDESTRING header = (FPDF_WIDESTRING)bsHeader.GetBuffer(bsHeader.GetLength());
+
+ FPDF_BSTR respone;
+ FPDF_BStr_Init(&respone);
+ FPDF_BOOL bRet = m_pInfo->FFI_PostRequestURL(m_pInfo, URL, data, contentType, encode, header, &respone);
+
+ CFX_WideString wsRet = CFX_WideString::FromUTF16LE((unsigned short*)respone.str, respone.len/sizeof(unsigned short));
+ FPDF_BStr_Clear(&respone);
+
+ return wsRet;
+ }
+ return L"";
+ }
+
+ FPDF_BOOL FFI_PutRequestURL(FX_LPCWSTR wsURL, FX_LPCWSTR wsData, FX_LPCWSTR wsEncode)
+ {
+ if (m_pInfo && m_pInfo->FFI_PutRequestURL)
+ {
+ CFX_ByteString bsURL = CFX_WideString(wsURL).UTF16LE_Encode();
+ FPDF_WIDESTRING URL = (FPDF_WIDESTRING)bsURL.GetBuffer(bsURL.GetLength());
+
+ CFX_ByteString bsData = CFX_WideString(wsData).UTF16LE_Encode();
+ FPDF_WIDESTRING data = (FPDF_WIDESTRING)bsData.GetBuffer(bsData.GetLength());
+
+ CFX_ByteString bsEncode = CFX_WideString(wsEncode).UTF16LE_Encode();
+ FPDF_WIDESTRING encode = (FPDF_WIDESTRING)bsEncode.GetBuffer(bsEncode.GetLength());
+
+ return m_pInfo->FFI_PutRequestURL(m_pInfo, URL, data, encode);
+ }
+ return FALSE;
+ }
+
+ FPDF_BOOL FFI_ShowFileDialog(FX_LPCWSTR wsTitle, FX_LPCWSTR wsFilter, CFX_WideStringArray &wsPathArr, FX_BOOL bOpen)
+ {
+ /*CFX_ByteString bsTitle = CFX_WideString(wsTitle).UTF16LE_Encode();
+ FPDF_WIDESTRING title = (FPDF_WIDESTRING)bsTitle.GetBuffer(bsTitle.GetLength());
+
+ CFX_ByteString bsFilter = CFX_WideString(wsFilter).UTF16LE_Encode();
+ FPDF_WIDESTRING filter = (FPDF_WIDESTRING)bsFilter.GetBuffer(bsFilter.GetLength());
+
+ CFX_ByteStringArray* strPathArr = FX_NEW CFX_ByteStringArray();
+ if (m_pInfo && m_pInfo->FFI_ShowFileDialog)
+ {
+ FPDF_BOOL bRet = m_pInfo->FFI_ShowFileDialog(m_pInfo, title, filter, bOpen, (FPDF_STRINGHANDLE)strPathArr);
+ if (bRet)
+ {
+ int count = strPathArr->GetSize();
+ for (int i=0; i<count; i++)
+ {
+ CFX_ByteString bsPath = *strPathArr->GetDataPtr(i);
+ CFX_WideString wsPath = CFX_WideString::FromUTF16LE((unsigned short*)bsPath.GetBuffer(bsPath.GetLength()), bsPath.GetLength()/sizeof(unsigned short));
+ if (!wsPath.IsEmpty())
+ wsPathArr.Add(wsPath);
+ wsPath = L"";
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+ */
+
+ return FALSE;
+ }
+ CFX_WideString FFI_GetLanguage()
+ {
+ if (m_pInfo && m_pInfo->FFI_GetLanguage)
+ {
+ int nRequiredLen = m_pInfo->FFI_GetLanguage(m_pInfo, NULL, 0);
+ if (nRequiredLen <= 0)
+ return L"";
+
+ char* pbuff = new char[nRequiredLen];
+ if (!pbuff)
+ return L"";
+
+ memset(pbuff, 0, nRequiredLen);
+ int nActualLen = m_pInfo->FFI_GetLanguage(m_pInfo, pbuff, nRequiredLen);
+ if (nActualLen <= 0 || nActualLen > nRequiredLen)
+ {
+ delete[] pbuff;
+ return L"";
+ }
+ CFX_ByteString bsRet = CFX_ByteString(pbuff, nActualLen);
+ CFX_WideString wsRet = CFX_WideString::FromUTF16LE((unsigned short*)bsRet.GetBuffer(bsRet.GetLength()), bsRet.GetLength()/sizeof(unsigned short));
+ delete[] pbuff;
+ return wsRet;
+ }
+ return L"";
+ }
+
public:
FX_BOOL IsJSInitiated();
public:
void SetCurrentDoc(CPDFSDK_Document* pFXDoc) {m_pSDKDoc = pFXDoc;}
CPDFSDK_Document* GetCurrentDoc();
- CPDF_Document* GetPDFDocument() {return m_pPDFDoc;}
+ CPDFXFA_Document* GetPDFXFADocument() {return m_pDoc;}
// CPDFSDK_Document* GetDocument(int nIndex);
// int CountDocuments() {return m_docMap.GetCount();}
- CPDFSDK_Document* OpenDocument(CFX_WideString &fileName);
- CPDFSDK_Document* OpenMemPDFDoc(CPDF_Document* pNewDoc, CFX_WideString &fileName);
- FX_BOOL OpenURL(CFX_WideString &filePath);
+ CPDFSDK_Document* OpenDocument(CFX_WideString &fileName){return NULL;}
+ CPDFSDK_Document* OpenMemPDFDoc(CPDF_Document* pNewDoc, CFX_WideString &fileName){return NULL;}
+ FX_BOOL OpenURL(CFX_WideString &filePath){return FALSE;}
CFX_ByteString GetAppName() {return "";}
@@ -379,13 +727,13 @@ private:
FPDF_FORMFILLINFO* m_pInfo;
// CFX_MapPtrTemplate<CPDF_Document*, CPDFSDK_Document*> m_docMap;
CPDFSDK_Document* m_pSDKDoc;
- CPDF_Document* m_pPDFDoc;
+ CPDFXFA_Document* m_pDoc;
CFFL_IFormFiller* m_pIFormFiller;
IFX_SystemHandler* m_pSysHandler;
public:
- CJS_RuntimeFactory* m_pJSRuntimeFactory;
+ //CJS_RuntimeFactory* m_pJSRuntimeFactory;
};
@@ -407,19 +755,20 @@ class CPDFSDK_InterForm;
class CPDFSDK_Document
{
public:
- CPDFSDK_Document(CPDF_Document* pDoc, CPDFDoc_Environment* pEnv);
+ CPDFSDK_Document(CPDFXFA_Document* pDoc, CPDFDoc_Environment* pEnv);
~CPDFSDK_Document();
public:
CPDFSDK_InterForm* GetInterForm() ;
- CPDF_Document* GetDocument() {return m_pDoc;}
+ CPDFXFA_Document* GetDocument() {return m_pDoc;}
public:
void InitPageView();
- void AddPageView(CPDF_Page* pPDFPage, CPDFSDK_PageView* pPageView);
- CPDFSDK_PageView* GetPageView(CPDF_Page* pPDFPage, FX_BOOL ReNew = TRUE);
+ int GetPageViewCount(){return m_pageMap.GetCount();}
+ void AddPageView(CPDFXFA_Page* pPDFXFAPage, CPDFSDK_PageView* pPageView);
+ CPDFSDK_PageView* GetPageView(CPDFXFA_Page* pPDFXFAPage, FX_BOOL ReNew = TRUE);
CPDFSDK_PageView* GetPageView(int nIndex);
CPDFSDK_PageView* GetCurrentView();
- void ReMovePageView(CPDF_Page* pPDFPage);
+ void ReMovePageView(CPDFXFA_Page* pPDFPage);
void UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot* pAnnot);
CPDFSDK_Annot* GetFocusAnnot();//{return NULL;}
@@ -444,15 +793,15 @@ public:
// FX_BOOL GetChangeMark(){return FALSE;}//IsAnnotModified()||IsFormModified() || IsWidgetModified()|| m_nChangeMark>0 ;}
// void ClearChangeMark(){}
CFX_WideString GetPath() ;
- CPDF_Page* GetPage(int nIndex);
+ CPDFXFA_Page* GetPage(int nIndex);
CPDFDoc_Environment * GetEnv() {return m_pEnv; }
void ProcJavascriptFun();
FX_BOOL ProcOpenAction();
CPDF_OCContext* GetOCContext();
private:
//CFX_ArrayTemplate<CPDFSDK_PageView*> m_pageArray;
- CFX_MapPtrTemplate<CPDF_Page*, CPDFSDK_PageView*> m_pageMap;
- CPDF_Document* m_pDoc;
+ CFX_MapPtrTemplate<CPDFXFA_Page*, CPDFSDK_PageView*> m_pageMap;
+ CPDFXFA_Document* m_pDoc;
CPDFSDK_InterForm* m_pInterForm;
CPDFSDK_Annot* m_pFocusAnnot;
@@ -460,12 +809,13 @@ private:
CPDF_OCContext * m_pOccontent;
FX_BOOL m_bChangeMask;
};
+
class CPDFSDK_PageView FX_FINAL
{
public:
- CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDF_Page* page);
+ CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDFXFA_Page* page);
~CPDFSDK_PageView();
- void PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions) ;
+ void PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions, FX_RECT* pClip = NULL) ;
CPDF_Annot* GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
CPDFSDK_Annot* GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
CPDF_Annot* GetPDFWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pageY);
@@ -478,16 +828,21 @@ public:
CPDFSDK_Annot* AddAnnot(CPDF_Dictionary * pDict);
CPDFSDK_Annot* AddAnnot(FX_LPCSTR lpSubType,CPDF_Dictionary * pDict);
CPDFSDK_Annot* AddAnnot(CPDF_Annot * pPDFAnnot);
+ CPDFSDK_Annot* AddAnnot(XFA_HWIDGET pPDFAnnot);
FX_BOOL DeleteAnnot(CPDFSDK_Annot* pAnnot);
int CountAnnots();
CPDFSDK_Annot* GetAnnot(int nIndex);
CPDFSDK_Annot* GetAnnotByDict(CPDF_Dictionary * pDict);
- CPDF_Page* GetPDFPage(){return m_page;}
+ CPDFSDK_Annot* GetAnnotByXFAWidget(XFA_HWIDGET hWidget);
+ CPDFXFA_Page* GetPDFXFAPage(){return m_page;}
+ CPDF_Page* GetPDFPage();
CPDF_Document* GetPDFDocument();
CPDFSDK_Document* GetSDKDocument() {return m_pSDKDoc;}
FX_BOOL OnLButtonDown(const CPDF_Point & point, FX_UINT nFlag);
FX_BOOL OnLButtonUp(const CPDF_Point & point, FX_UINT nFlag);
+ FX_BOOL OnRButtonDown(const CPDF_Point & point, FX_UINT nFlag);
+ FX_BOOL OnRButtonUp(const CPDF_Point & point, FX_UINT nFlag);
FX_BOOL OnChar(int nChar, FX_UINT nFlag);
FX_BOOL OnKeyDown(int nKeyCode, int nFlag);
FX_BOOL OnKeyUp(int nKeyCode, int nFlag);
@@ -502,27 +857,26 @@ public:
int GetPageIndex();
void LoadFXAnnots();
-
- void SetValid(FX_BOOL bValid) {m_bValid = bValid;}
- FX_BOOL IsValid() {return m_bValid;}
- void SetLock(FX_BOOL bLocked) {m_bLocked= bLocked;}
- FX_BOOL IsLocked() {return m_bLocked;}
- void TakeOverPage() {m_bTakeOverPage = TRUE;}
+ void SetValid(FX_BOOL bValid) {m_bValid = bValid;}
+ FX_BOOL IsValid() {return m_bValid;}
+ void SetLock(FX_BOOL bLocked) {m_bLocked= bLocked;}
+ FX_BOOL IsLocked() {return m_bLocked;}
+ void TakeOverPage() {m_bTakeOverPage = TRUE;}
private:
void PageView_OnHighlightFormFields(CFX_RenderDevice* pDevice, CPDFSDK_Widget* pWidget);
- CPDF_Matrix m_curMatrix;
- CPDF_Page* m_page;
+ CPDF_Matrix m_curMatrix;
+ CPDFXFA_Page* m_page;
CPDF_AnnotList* m_pAnnotList;
//CPDFSDK_Annot* m_pFocusAnnot;
CFX_PtrArray m_fxAnnotArray;
CPDFSDK_Document* m_pSDKDoc;
- CPDFSDK_Widget* m_CaptureWidget;
+ CPDFSDK_Annot* m_CaptureWidget;
FX_BOOL m_bEnterWidget;
FX_BOOL m_bExitWidget;
FX_BOOL m_bOnWidget;
FX_BOOL m_bValid;
- FX_BOOL m_bLocked;
- FX_BOOL m_bTakeOverPage;
+ FX_BOOL m_bLocked;
+ FX_BOOL m_bTakeOverPage;
};
diff --git a/fpdfsdk/include/javascript/IJavaScript.h b/fpdfsdk/include/javascript/IJavaScript.h
index 7633bbb486..7754537af2 100644
--- a/fpdfsdk/include/javascript/IJavaScript.h
+++ b/fpdfsdk/include/javascript/IJavaScript.h
@@ -88,6 +88,8 @@ public:
virtual void Exit() = 0;
virtual void Enter() = 0;
virtual FX_BOOL IsEntered() = 0;
+ virtual FX_BOOL GetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue) = 0;
+ virtual FX_BOOL SetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue) = 0;
};
class CPDFDoc_Environment;
diff --git a/fpdfsdk/include/javascript/JS_Context.h b/fpdfsdk/include/javascript/JS_Context.h
index 806808651d..adb28cdaed 100644
--- a/fpdfsdk/include/javascript/JS_Context.h
+++ b/fpdfsdk/include/javascript/JS_Context.h
@@ -74,7 +74,7 @@ public:
FX_BOOL IsMsgBoxEnabled() const {return m_bMsgBoxEnable;}
public:
- CPDFDoc_Environment* GetReaderApp();
+ CPDFDoc_Environment* GetReaderApp();
CJS_Runtime* GetJSRuntime(){return m_pRuntime;}
FX_BOOL DoJob(int nMode, const CFX_WideString& script, CFX_WideString& info);
diff --git a/fpdfsdk/include/javascript/JS_Define.h b/fpdfsdk/include/javascript/JS_Define.h
index 108c1e23ee..1798e01591 100644
--- a/fpdfsdk/include/javascript/JS_Define.h
+++ b/fpdfsdk/include/javascript/JS_Define.h
@@ -93,11 +93,8 @@ typedef CFX_WideString JS_ErrorString;
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
CJS_PropValue value(isolate);\
value.StartGetting();\
@@ -129,11 +126,8 @@ typedef CFX_WideString JS_ErrorString;
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
CJS_PropValue propValue(CJS_Value(isolate,value,VT_unknown));\
propValue.StartSetting();\
@@ -170,11 +164,8 @@ JS_STATIC_PROP_SET(prop_name, class_name)
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
CJS_Parameters parameters;\
for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
@@ -359,11 +350,8 @@ const wchar_t * js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
v8::String::Utf8Value utf8_value(property);\
CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
@@ -397,11 +385,8 @@ const wchar_t * js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
v8::String::Utf8Value utf8_value(property);\
CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
@@ -434,11 +419,8 @@ const wchar_t * js_class_name::m_pClassName = JS_WIDESTRING(class_name);\
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
v8::String::Utf8Value utf8_value(property);\
CFX_WideString propname = CFX_WideString::FromUTF8(*utf8_value, utf8_value.length());\
@@ -525,11 +507,8 @@ void js_class_name::GetMethods(JSMethodSpec*& pMethods, int& nSize)\
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
CJS_Parameters parameters;\
for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
@@ -568,11 +547,8 @@ static void fun_name##_static(JS_METHOD_ARGS)\
{\
v8::Isolate* isolate = info.GetIsolate();\
v8::Local<v8::Context> context = isolate->GetCurrentContext();\
- v8::Local<v8::Value> v = context->GetEmbedderData(1);\
- ASSERT(!v.IsEmpty());\
- if(v.IsEmpty()) return;\
- v8::Handle<v8::External> field = v8::Handle<v8::External>::Cast(v);\
- IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)field->Value();\
+ IFXJS_Runtime* pRuntime = (IFXJS_Runtime*)isolate->GetData(2);\
+ if (pRuntime == NULL) return;\
IFXJS_Context* cc = pRuntime->GetCurrentContext();\
CJS_Parameters parameters;\
for (unsigned int i = 0; i<(unsigned int)info.Length(); i++)\
diff --git a/fpdfsdk/include/javascript/JS_GlobalData.h b/fpdfsdk/include/javascript/JS_GlobalData.h
index 8eee158a00..c54d7b550d 100644
--- a/fpdfsdk/include/javascript/JS_GlobalData.h
+++ b/fpdfsdk/include/javascript/JS_GlobalData.h
@@ -91,6 +91,7 @@ private:
private:
CFX_ArrayTemplate<CJS_GlobalData_Element*> m_arrayGlobalData;
CFX_WideString m_sFilePath;
+ CPDFDoc_Environment* m_pApp;
};
#endif //_JS_GLOBALDATA_H_
diff --git a/fpdfsdk/include/javascript/JS_Object.h b/fpdfsdk/include/javascript/JS_Object.h
index a6dac5d2a3..ca6f4a1d11 100644
--- a/fpdfsdk/include/javascript/JS_Object.h
+++ b/fpdfsdk/include/javascript/JS_Object.h
@@ -26,7 +26,7 @@ public:
operator CJS_Object* (){return m_pJSObject;};
CPDFSDK_PageView * JSGetPageView(IFXJS_Context* cc);
- int MsgBox(CPDFDoc_Environment* pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0, FX_UINT nIcon = 0);
+ int MsgBox(CPDFDoc_Environment * pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0, FX_UINT nIcon = 0);
void Alert(CJS_Context* pContext, FX_LPCWSTR swMsg);
FX_BOOL IsSafeMode(IFXJS_Context* cc);
@@ -56,7 +56,7 @@ public:
CJS_EmbedObj * GetEmbedObject(){return m_pEmbedObj;};
static CPDFSDK_PageView * JSGetPageView(IFXJS_Context* cc);
- static int MsgBox(CPDFDoc_Environment* pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0,FX_UINT nIcon = 0);
+ static int MsgBox(CPDFDoc_Environment * pApp, CPDFSDK_PageView* pPageView, FX_LPCWSTR swMsg, FX_LPCWSTR swTitle = NULL, FX_UINT nType = 0,FX_UINT nIcon = 0);
static void Alert(CJS_Context* pContext, FX_LPCWSTR swMsg);
v8::Isolate* GetIsolate() {return m_pIsolate;}
@@ -164,7 +164,7 @@ class CJS_Runtime;
class CJS_Timer
{
public:
- CJS_Timer(CJS_EmbedObj * pObj,CPDFDoc_Environment* pApp):
+ CJS_Timer(CJS_EmbedObj * pObj, CPDFDoc_Environment* pApp):
m_nTimerID(0),
m_pEmbedObj(pObj),
m_bProcessing(FALSE),
@@ -197,6 +197,11 @@ public:
{
if (m_nTimerID)
{
+ if (m_pApp == NULL) {
+ m_sTimeMap.RemoveAt(m_nTimerID);
+ m_nTimerID = 0;
+ return;
+ }
IFX_SystemHandler* pHandler = m_pApp->GetSysHandler();
pHandler->KillTimer(m_nTimerID);
m_sTimeMap.RemoveAt(m_nTimerID);
@@ -277,8 +282,8 @@ private:
FX_BOOL m_bProcessing;
//data
- FX_DWORD m_dwStartTime;
- FX_DWORD m_dwTimeOut;
+ FX_DWORD m_dwStartTime;
+ FX_DWORD m_dwTimeOut;
FX_DWORD m_dwElapse;
CJS_Runtime* m_pRuntime;
CFX_WideString m_swJScript;
diff --git a/fpdfsdk/include/javascript/JS_Runtime.h b/fpdfsdk/include/javascript/JS_Runtime.h
index 0a195f132c..217a985869 100644
--- a/fpdfsdk/include/javascript/JS_Runtime.h
+++ b/fpdfsdk/include/javascript/JS_Runtime.h
@@ -37,7 +37,7 @@ public:
virtual void Enter();
virtual FX_BOOL IsEntered();
- CPDFDoc_Environment * GetReaderApp(){return m_pApp;}
+ CPDFDoc_Environment * GetReaderApp(){return m_pApp;}
FX_BOOL InitJSObjects();
@@ -50,19 +50,23 @@ public:
FX_BOOL IsBlocking(){return m_bBlocking;}
operator IJS_Runtime*() {return (IJS_Runtime*)m_isolate;}
- v8::Isolate* GetIsolate(){return m_isolate;};
+ v8::Isolate* GetIsolate(){return m_isolate;};
void SetIsolate(v8::Isolate* isolate){m_isolate = isolate;}
- v8::Handle<v8::Context> NewJSContext();
+ v8::Handle<v8::Context> NewJSContext();
+
+
+ virtual FX_BOOL GetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue);
+ virtual FX_BOOL SetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue);
protected:
CFX_ArrayTemplate<CJS_Context *> m_ContextArray;
- CPDFDoc_Environment * m_pApp;
+ CPDFDoc_Environment * m_pApp;
CPDFSDK_Document * m_pDocument;
FX_BOOL m_bBlocking;
CJS_FieldEvent* m_pFieldEventPath;
- v8::Isolate* m_isolate;
- v8::Persistent<v8::Context> m_context;
+ v8::Isolate* m_isolate;
+ v8::Persistent<v8::Context> m_context;
FX_BOOL m_bRegistered;
};
diff --git a/fpdfsdk/include/javascript/JavaScript.h b/fpdfsdk/include/javascript/JavaScript.h
index 166472b61e..ca5922e074 100644
--- a/fpdfsdk/include/javascript/JavaScript.h
+++ b/fpdfsdk/include/javascript/JavaScript.h
@@ -28,6 +28,7 @@
#include "../fxedit/fx_edit.h"
#include "../pdfwindow/IPDFWindow.h"
#include "../fsdk_mgr.h"
+#include "../fpdfxfa/fpdfxfa_app.h"
#include <string>
diff --git a/fpdfsdk/include/pdfwindow/PWL_Edit.h b/fpdfsdk/include/pdfwindow/PWL_Edit.h
index d86cb77d2c..6af324d5f7 100644
--- a/fpdfsdk/include/pdfwindow/PWL_Edit.h
+++ b/fpdfsdk/include/pdfwindow/PWL_Edit.h
@@ -21,6 +21,9 @@ public:
int nSelStart, int nSelEnd,
FX_BOOL bKeyDown, FX_BOOL & bRC, FX_BOOL & bExit, FX_DWORD nFlag) = 0;
virtual void OnAfterKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_BOOL & bExit, FX_DWORD nFlag) = 0;
+
+ virtual void OnPopupPreOpen(void* pPrivateData, FX_BOOL& bExit, FX_DWORD nFlag) = 0;
+ virtual void OnPopupPostOpen(void* pPrivateData, FX_BOOL& bExit, FX_DWORD nFlag) = 0;
};
class PWL_CLASS CPWL_Edit : public CPWL_EditCtrl, public IFX_Edit_OprNotify
diff --git a/fpdfsdk/src/formfiller/FFL_ComboBox.cpp b/fpdfsdk/src/formfiller/FFL_ComboBox.cpp
index ee6b7bd83a..1c5b49812e 100644
--- a/fpdfsdk/src/formfiller/FFL_ComboBox.cpp
+++ b/fpdfsdk/src/formfiller/FFL_ComboBox.cpp
@@ -348,6 +348,19 @@ void CFFL_ComboBox::OnKeyStroke(FX_BOOL bKeyDown, FX_UINT nFlag)
}
}
+FX_BOOL CFFL_ComboBox::IsFieldFull(CPDFSDK_PageView* pPageView)
+{
+ if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+ {
+ if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
+ {
+ return pEdit->IsTextFull();
+ }
+ }
+
+ return FALSE;
+}
+
void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd)
{
ASSERT(m_pApp != NULL);
diff --git a/fpdfsdk/src/formfiller/FFL_FormFiller.cpp b/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
index 530b80ce6f..c9dd6681d2 100644
--- a/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
+++ b/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
@@ -292,7 +292,7 @@ FX_BOOL CFFL_FormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
{
CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
- CPDF_Page * pPage = pWidget->GetPDFPage();
+ CPDFXFA_Page * pPage = pWidget->GetPDFXFAPage();
CPDFSDK_Document * pDoc = m_pApp->GetCurrentDoc();
CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
ASSERT(pPageView != NULL);
@@ -567,7 +567,7 @@ CPDF_Rect CFFL_FormFiller::GetPDFWindowRect() const
CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView()
{
- CPDF_Page* pPage = m_pAnnot->GetPDFPage();
+ CPDFXFA_Page* pPage = m_pAnnot->GetPDFXFAPage();
CPDFSDK_Document* pSDKDoc = m_pApp->GetCurrentDoc();
if(pSDKDoc)
{
@@ -713,6 +713,11 @@ void CFFL_FormFiller::GetKeyStrokeData(CPDFSDK_PageView* pPageView, FFL_KeyStrok
{
}
+FX_BOOL CFFL_FormFiller::IsFieldFull(CPDFSDK_PageView* pPageView)
+{
+ return FALSE;
+}
+
void CFFL_FormFiller::SetChangeMark()
{
m_pApp->FFI_OnChange();
@@ -803,7 +808,7 @@ void CFFL_FormFiller::DoPaste(CPDFSDK_Document* pDocument)
void CFFL_FormFiller::InvalidateRect(double left, double top, double right, double bottom)
{
- CPDF_Page * pPage = m_pWidget->GetPDFPage();
+ CPDFXFA_Page * pPage = m_pWidget->GetPDFXFAPage();
m_pApp->FFI_Invalidate(pPage, left, top, right, bottom);
}
diff --git a/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp b/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
index 2b21e13cfc..61cb55f66d 100644
--- a/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
+++ b/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
@@ -335,6 +335,9 @@ FX_BOOL CFFL_IFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot
FX_BOOL bReset = FALSE;
OnButtonUp(pWidget, pPageView, bReset, bExit,nFlags);
if (bExit) return TRUE;
+
+ OnClick(pWidget, pPageView, bReset, bExit, nFlags);
+ if (bExit) return TRUE;
}
return bRet;
}
@@ -830,7 +833,7 @@ void CFFL_IFormFiller::OnSetWindowRect(void* pPrivateData, const CPDF_Rect & rcW
unRect.right = (FX_FLOAT)(unRect.right + 0.5);
unRect.top = (FX_FLOAT)(unRect.top + 0.5);
unRect.bottom = (FX_FLOAT)(unRect.bottom -0.5);
- m_pApp->FFI_Invalidate(pData->pWidget->GetPDFPage(), unRect.left, unRect.top, unRect.right, unRect.bottom);
+ m_pApp->FFI_Invalidate(pData->pWidget->GetPDFXFAPage(), unRect.left, unRect.top, unRect.right, unRect.bottom);
}
}
@@ -1037,6 +1040,190 @@ FX_BOOL CFFL_IFormFiller::GetKeyDown()
// return msg.message == WM_KEYDOWN || msg.message == WM_CHAR;
}
+void CFFL_IFormFiller::OnClick(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag)
+{
+ ASSERT(pWidget != NULL);
+
+ if (!m_bNotifying)
+ {
+ if (pWidget->HasXFAAAction(PDFSDK_XFA_Click))
+ {
+ m_bNotifying = TRUE;
+ int nAge = pWidget->GetAppearanceAge();
+ int nValueAge = pWidget->GetValueAge();
+
+ PDFSDK_FieldAction fa;
+ fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+
+ pWidget->OnXFAAAction(PDFSDK_XFA_Click, fa, pPageView);
+ m_bNotifying = FALSE;
+
+ if (!IsValidAnnot(pPageView, pWidget))
+ {
+ bExit = TRUE;
+ return;
+ }
+
+ if (nAge != pWidget->GetAppearanceAge())
+ {
+ if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+ {
+ pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+ }
+
+ bReset = TRUE;
+ }
+ }
+ }
+}
+
+void CFFL_IFormFiller::OnFull(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag)
+{
+ ASSERT(pWidget != NULL);
+
+ if (!m_bNotifying)
+ {
+ if (pWidget->HasXFAAAction(PDFSDK_XFA_Full))
+ {
+ m_bNotifying = TRUE;
+ int nAge = pWidget->GetAppearanceAge();
+ int nValueAge = pWidget->GetValueAge();
+
+ PDFSDK_FieldAction fa;
+ fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+
+ pWidget->OnXFAAAction(PDFSDK_XFA_Full, fa, pPageView);
+ m_bNotifying = FALSE;
+
+ if (!IsValidAnnot(pPageView, pWidget))
+ {
+ bExit = TRUE;
+ return;
+ }
+
+ if (nAge != pWidget->GetAppearanceAge())
+ {
+ if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+ {
+ pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+ }
+
+ bReset = TRUE;
+ }
+ }
+ }
+}
+
+void CFFL_IFormFiller::OnPopupPreOpen(void* pPrivateData, FX_BOOL& bExit, FX_DWORD nFlag)
+{
+ ASSERT(pPrivateData != NULL);
+ CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+ ASSERT(pData->pWidget != NULL);
+
+ FX_BOOL bTempReset = FALSE;
+ FX_BOOL bTempExit = FALSE;
+ this->OnPreOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit, nFlag);
+
+ if (bTempReset || bTempExit)
+ {
+ bExit = TRUE;
+ }
+}
+
+void CFFL_IFormFiller::OnPopupPostOpen(void* pPrivateData, FX_BOOL& bExit, FX_DWORD nFlag)
+{
+ ASSERT(pPrivateData != NULL);
+ CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+ ASSERT(pData->pWidget != NULL);
+
+ FX_BOOL bTempReset = FALSE;
+ FX_BOOL bTempExit = FALSE;
+ this->OnPostOpen(pData->pWidget, pData->pPageView, bTempReset, bTempExit, nFlag);
+
+ if (bTempReset || bTempExit)
+ {
+ bExit = TRUE;
+ }
+}
+
+void CFFL_IFormFiller::OnPreOpen(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag)
+{
+ ASSERT(pWidget != NULL);
+
+ if (!m_bNotifying)
+ {
+ if (pWidget->HasXFAAAction(PDFSDK_XFA_PreOpen))
+ {
+ m_bNotifying = TRUE;
+ int nAge = pWidget->GetAppearanceAge();
+ int nValueAge = pWidget->GetValueAge();
+
+ PDFSDK_FieldAction fa;
+ fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+
+ pWidget->OnXFAAAction(PDFSDK_XFA_PreOpen, fa, pPageView);
+ m_bNotifying = FALSE;
+
+ if (!IsValidAnnot(pPageView, pWidget))
+ {
+ bExit = TRUE;
+ return;
+ }
+
+ if (nAge != pWidget->GetAppearanceAge())
+ {
+ if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+ {
+ pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+ }
+
+ bReset = TRUE;
+ }
+ }
+ }
+}
+
+void CFFL_IFormFiller::OnPostOpen(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit, FX_UINT nFlag)
+{
+ ASSERT(pWidget != NULL);
+
+ if (!m_bNotifying)
+ {
+ if (pWidget->HasXFAAAction(PDFSDK_XFA_PostOpen))
+ {
+ m_bNotifying = TRUE;
+ int nAge = pWidget->GetAppearanceAge();
+ int nValueAge = pWidget->GetValueAge();
+
+ PDFSDK_FieldAction fa;
+ fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+
+ pWidget->OnXFAAAction(PDFSDK_XFA_PostOpen, fa, pPageView);
+ m_bNotifying = FALSE;
+
+ if (!IsValidAnnot(pPageView, pWidget))
+ {
+ bExit = TRUE;
+ return;
+ }
+
+ if (nAge != pWidget->GetAppearanceAge())
+ {
+ if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+ {
+ pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+ }
+
+ bReset = TRUE;
+ }
+ }
+ }
+}
+
FX_BOOL CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot)
{
@@ -1109,6 +1296,19 @@ void CFFL_IFormFiller::OnBeforeKeyStroke(FX_BOOL bEditOrList, void* pPrivateData
CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
ASSERT(pFormFiller != NULL);
+ if (pFormFiller->IsFieldFull(pData->pPageView))
+ {
+ FX_BOOL bFullExit = FALSE;
+ FX_BOOL bFullReset = FALSE;
+ OnFull(pData->pWidget, pData->pPageView, bFullReset, bFullExit, nFlag);
+
+ if (bFullReset || bFullExit)
+ {
+ bExit = TRUE;
+ return;
+ }
+ }
+
if (!m_bNotifying)
{
if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke))
diff --git a/fpdfsdk/src/formfiller/FFL_TextField.cpp b/fpdfsdk/src/formfiller/FFL_TextField.cpp
index 45c716280c..f9c93914a5 100644
--- a/fpdfsdk/src/formfiller/FFL_TextField.cpp
+++ b/fpdfsdk/src/formfiller/FFL_TextField.cpp
@@ -176,7 +176,7 @@ FX_BOOL CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFl
ASSERT(pPageView != NULL);
m_bValid = !m_bValid;
CPDF_Rect rcAnnot = pAnnot->GetRect();
- m_pApp->FFI_Invalidate(pAnnot->GetPDFPage(), rcAnnot.left, rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
+ m_pApp->FFI_Invalidate(pAnnot->GetPDFXFAPage(), rcAnnot.left, rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
if (m_bValid)
{
@@ -348,6 +348,16 @@ CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bR
return pRet;
}
+FX_BOOL CFFL_TextField::IsFieldFull(CPDFSDK_PageView* pPageView)
+{
+ if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+ {
+ return pWnd->IsTextFull();
+ }
+
+ return FALSE;
+}
+
void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd)
{
ASSERT(m_pApp != NULL);
diff --git a/fpdfsdk/src/fpdf_dataavail.cpp b/fpdfsdk/src/fpdf_dataavail.cpp
index b5483f9c39..efd12078a4 100644
--- a/fpdfsdk/src/fpdf_dataavail.cpp
+++ b/fpdfsdk/src/fpdf_dataavail.cpp
@@ -6,6 +6,9 @@
#include "../include/fsdk_define.h"
#include "../include/fpdf_dataavail.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfformfill.h"
+#include "../include/fpdfxfa/fpdfxfa_app.h"
extern void ProcessParseError(FX_DWORD err_code);
class CFPDF_FileAvailWrap : public IFX_FileAvail
@@ -133,13 +136,19 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDFAvail_GetDocument(FPDF_AVAIL avail, FPDF_BYT
}
((CFPDF_DataAvail*)avail)->m_pDataAvail->SetDocument(pParser->GetDocument());
CheckUnSupportError(pParser->GetDocument(), FPDF_ERR_SUCCESS);
- return pParser->GetDocument();
+ CPDF_Document* pPDFDoc = pParser->GetDocument();
+
+ CPDFXFA_App* pApp = FPDFXFA_GetApp();
+ CPDFXFA_Document* pDocument = FX_NEW CPDFXFA_Document(pPDFDoc, pApp);
+ //pDocument->LoadXFADoc();
+
+ return pDocument;
}
DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc)
{
if (doc == NULL) return 0;
- CPDF_Document* pDoc = (CPDF_Document*)doc;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)doc)->GetPDFDoc();
return ((CPDF_Parser*)pDoc->GetParser())->GetFirstPageNo();
}
diff --git a/fpdfsdk/src/fpdf_ext.cpp b/fpdfsdk/src/fpdf_ext.cpp
index 93f6e187da..512a617920 100644
--- a/fpdfsdk/src/fpdf_ext.cpp
+++ b/fpdfsdk/src/fpdf_ext.cpp
@@ -6,6 +6,7 @@
#include "../include/fsdk_define.h"
#include "../include/fpdf_ext.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
#define FPDFSDK_UNSUPPORT_CALL 100
@@ -220,7 +221,7 @@ void CheckUnSupportError(CPDF_Document * pDoc, FX_DWORD err_code)
DLLEXPORT int FPDFDoc_GetPageMode(FPDF_DOCUMENT document)
{
if (!document) return PAGEMODE_UNKNOWN;
- CPDF_Dictionary *pRoot = ((CPDF_Document*)document)->GetRoot();
+ CPDF_Dictionary *pRoot = (((CPDFXFA_Document*)document)->GetPDFDoc())->GetRoot();
if (!pRoot)
return PAGEMODE_UNKNOWN;
CPDF_Object* pName = pRoot->GetElement("PageMode");
diff --git a/fpdfsdk/src/fpdf_flatten.cpp b/fpdfsdk/src/fpdf_flatten.cpp
index 6d3440f556..e07ccc91b7 100644
--- a/fpdfsdk/src/fpdf_flatten.cpp
+++ b/fpdfsdk/src/fpdf_flatten.cpp
@@ -6,6 +6,8 @@
#include "../include/fsdk_define.h"
#include "../include/fpdf_flatten.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
typedef CFX_ArrayTemplate<CPDF_Dictionary*> CPDF_ObjectArray;
typedef CFX_ArrayTemplate<CPDF_Rect> CPDF_RectArray;
@@ -332,7 +334,10 @@ DLLEXPORT int STDCALL FPDFPage_Flatten( FPDF_PAGE page, int nFlag)
return FLATTEN_FAIL;
}
- CPDF_Page * pPage = (CPDF_Page*)( page );
+ CPDF_Page * pPage = ((CPDFXFA_Page*)( page ))->GetPDFPage();
+ if (!pPage)
+ return FLATTEN_FAIL;
+
CPDF_Document * pDocument = pPage->m_pDocument;
CPDF_Dictionary * pPageDict = pPage->m_pFormDict;
diff --git a/fpdfsdk/src/fpdf_progressive.cpp b/fpdfsdk/src/fpdf_progressive.cpp
index 2490df8c2f..5226770d48 100644
--- a/fpdfsdk/src/fpdf_progressive.cpp
+++ b/fpdfsdk/src/fpdf_progressive.cpp
@@ -8,6 +8,8 @@
#include "../include/fsdk_define.h"
#include "../include/fpdfview.h"
#include "../include/fsdk_rendercontext.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
extern void (*Func_RenderPage)( CRenderContext*, FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
int rotate, int flags,FX_BOOL bNeedToRestore, IFSDK_PAUSE_Adapter * pause );
@@ -28,7 +30,9 @@ DLLEXPORT int STDCALL FPDF_RenderPageBitmap_Start( FPDF_BITMAP bitmap, FPDF_PAGE
if (pause->version !=1)
return FPDF_RENDER_FAILED;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage)
+ return FPDF_RENDER_FAILED;
// FXMT_CSLOCK_OBJ(&pPage->m_PageLock);
@@ -71,7 +75,9 @@ DLLEXPORT int STDCALL FPDF_RenderPage_Continue(FPDF_PAGE page,IFSDK_PAUSE * paus
if (pause->version !=1)
return FPDF_RENDER_FAILED;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage)
+ return FPDF_RENDER_FAILED;
// FXMT_CSLOCK_OBJ(&pPage->m_PageLock);
@@ -92,7 +98,8 @@ DLLEXPORT int STDCALL FPDF_RenderPage_Continue(FPDF_PAGE page,IFSDK_PAUSE * paus
DLLEXPORT void STDCALL FPDF_RenderPage_Close(FPDF_PAGE page)
{
if (page == NULL) return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
// FXMT_CSLOCK_OBJ(&pPage->m_PageLock);
diff --git a/fpdfsdk/src/fpdf_transformpage.cpp b/fpdfsdk/src/fpdf_transformpage.cpp
index a666666d55..043c02cc27 100644
--- a/fpdfsdk/src/fpdf_transformpage.cpp
+++ b/fpdfsdk/src/fpdf_transformpage.cpp
@@ -6,12 +6,15 @@
#include "../include/fsdk_define.h"
#include "../include/fpdf_transformpage.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
DLLEXPORT void STDCALL FPDFPage_SetMediaBox(FPDF_PAGE page, float left, float bottom, float right, float top)
{
if(!page)
return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
CPDF_Array* pMediaBoxArray = FX_NEW CPDF_Array;
pMediaBoxArray->Add(FX_NEW CPDF_Number(left));
@@ -27,7 +30,8 @@ DLLEXPORT void STDCALL FPDFPage_SetCropBox(FPDF_PAGE page, float left, float bot
{
if(!page)
return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
CPDF_Array* pCropBoxArray = FX_NEW CPDF_Array;
pCropBoxArray->Add(FX_NEW CPDF_Number(left));
@@ -44,7 +48,8 @@ DLLEXPORT FX_BOOL STDCALL FPDFPage_GetMediaBox(FPDF_PAGE page, float* left, floa
{
if(!page)
return FALSE;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return FALSE;
CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
CPDF_Array* pArray = pPageDict->GetArray("MediaBox");
if(pArray)
@@ -62,7 +67,8 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GetCropBox(FPDF_PAGE page, float* left, flo
{
if(!page)
return FALSE;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return FALSE;
CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
CPDF_Array* pArray = pPageDict->GetArray("CropBox");
if(pArray)
@@ -81,6 +87,10 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX
if(!page)
return FALSE;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage)
+ return FALSE;
+
CFX_ByteTextBuf textBuf;
textBuf<<"q ";
CFX_FloatRect rect(clipRect->left, clipRect->bottom, clipRect->right, clipRect->top);
@@ -94,7 +104,6 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPage_TransFormWithClip(FPDF_PAGE page, FS_MATRIX
textBuf<<bsMatix;
- CPDF_Page* pPage = (CPDF_Page*)page;
CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
CPDF_Object* pContentObj = pPageDic ? pPageDic->GetElement("Contents") : NULL;
if(!pContentObj)
@@ -258,7 +267,8 @@ DLLEXPORT void STDCALL FPDFPage_InsertClipPath(FPDF_PAGE page,FPDF_CLIPPATH clip
{
if(!page)
return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
CPDF_Dictionary* pPageDic = pPage->m_pFormDict;
CPDF_Object* pContentObj = pPageDic ? pPageDic->GetElement("Contents") : NULL;
if(!pContentObj)
diff --git a/fpdfsdk/src/fpdfdoc.cpp b/fpdfsdk/src/fpdfdoc.cpp
index e974ffbcf2..643e398cfd 100644
--- a/fpdfsdk/src/fpdfdoc.cpp
+++ b/fpdfsdk/src/fpdfdoc.cpp
@@ -6,6 +6,8 @@
#include "../include/fsdk_define.h"
#include "../include/fpdfdoc.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
static int this_module = 0;
@@ -33,7 +35,7 @@ DLLEXPORT FPDF_BOOKMARK STDCALL FPDFBookmark_Find(FPDF_DOCUMENT document, FPDF_W
if (document == NULL) return NULL;
if (title == NULL || title[0] == 0) return NULL;
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
CPDF_BookmarkTree tree(pDoc);
FX_STRSIZE len = CFX_WideString::WStringLength(title);
@@ -47,7 +49,7 @@ DLLEXPORT FPDF_DEST STDCALL FPDFBookmark_GetDest(FPDF_DOCUMENT document, FPDF_BO
if (bookmark == NULL) return NULL;
CPDF_Bookmark Bookmark = (CPDF_Dictionary*)bookmark;
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
CPDF_Dest dest = Bookmark.GetDest(pDoc);
if (dest != NULL) return dest;
@@ -90,7 +92,7 @@ DLLEXPORT FPDF_DEST STDCALL FPDFAction_GetDest(FPDF_DOCUMENT document, FPDF_ACTI
{
if (document == NULL) return NULL;
if (action == NULL) return NULL;
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
CPDF_Action Action = (CPDF_Dictionary*)action;
return Action.GetDest(pDoc);
@@ -101,7 +103,7 @@ DLLEXPORT unsigned long STDCALL FPDFAction_GetURIPath(FPDF_DOCUMENT document, FP
{
if (document == NULL) return 0;
if (action == NULL) return 0;
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
CPDF_Action Action = (CPDF_Dictionary*)action;
CFX_ByteString path = Action.GetURI(pDoc);
@@ -115,7 +117,7 @@ DLLEXPORT unsigned long STDCALL FPDFDest_GetPageIndex(FPDF_DOCUMENT document, FP
{
if (document == NULL) return 0;
if (dest == NULL) return 0;
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
CPDF_Dest Dest = (CPDF_Array*)dest;
return Dest.GetPageIndex(pDoc);
@@ -129,7 +131,8 @@ static void ReleaseLinkList(FX_LPVOID data)
DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page, double x, double y)
{
if (page == NULL) return NULL;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return NULL;
// Link list is stored with the document
CPDF_Document* pDoc = pPage->m_pDocument;
@@ -145,7 +148,7 @@ DLLEXPORT FPDF_LINK STDCALL FPDFLink_GetLinkAtPoint(FPDF_PAGE page, double x, do
DLLEXPORT FPDF_DEST STDCALL FPDFLink_GetDest(FPDF_DOCUMENT document, FPDF_LINK link)
{
if (document == NULL) return NULL;
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
if (link == NULL) return NULL;
CPDF_Link Link = (CPDF_Dictionary*)link;
@@ -170,7 +173,8 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFLink_Enumerate(FPDF_PAGE page, int* startPos, FP
{
if(!page || !startPos || !linkAnnot)
return FALSE;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return FALSE;
if(!pPage->m_pFormDict) return FALSE;
CPDF_Array* pAnnots = pPage->m_pFormDict->GetArray("Annots");
if(!pAnnots) return FALSE;
@@ -240,7 +244,7 @@ DLLEXPORT unsigned long STDCALL FPDF_GetMetaText(FPDF_DOCUMENT doc, FPDF_BYTESTR
{
if (doc == NULL || tag == NULL) return 0;
- CPDF_Document* pDoc = (CPDF_Document*)doc;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)doc)->GetPDFDoc();
// Get info dictionary
CPDF_Dictionary* pInfo = pDoc->GetInfo();
if (pInfo == NULL) return 0;
diff --git a/fpdfsdk/src/fpdfeditimg.cpp b/fpdfsdk/src/fpdfeditimg.cpp
index c29d2b74f8..188b5f070d 100644
--- a/fpdfsdk/src/fpdfeditimg.cpp
+++ b/fpdfsdk/src/fpdfeditimg.cpp
@@ -6,6 +6,8 @@
#include "../include/fsdk_define.h"
#include "../include/fpdfedit.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewImgeObj(FPDF_DOCUMENT document)
@@ -13,14 +15,14 @@ DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPageObj_NewImgeObj(FPDF_DOCUMENT document)
if (!document)
return NULL;
CPDF_ImageObject* pImageObj = FX_NEW CPDF_ImageObject;
- CPDF_Image* pImg = FX_NEW CPDF_Image((CPDF_Document *)document);
+ CPDF_Image* pImg = FX_NEW CPDF_Image(((CPDFXFA_Document *)document)->GetPDFDoc());
pImageObj->m_pImage = pImg;
return pImageObj;
}
DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_LoadJpegFile(FPDF_PAGE* pages, int nCount,FPDF_PAGEOBJECT image_object, FPDF_FILEACCESS* fileAccess)
{
- if (!image_object || !fileAccess)
+ if (!image_object || !fileAccess || !pages)
return FALSE;
IFX_FileRead* pFile = FX_NEW CPDF_CustomAccess(fileAccess);
@@ -29,7 +31,9 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_LoadJpegFile(FPDF_PAGE* pages, int nCou
pImgObj->m_GeneralState.GetModify();
for (int index=0;index<nCount;index++)
{
- CPDF_Page* pPage = (CPDF_Page*)pages[index];
+ CPDF_Page* pPage = ((CPDFXFA_Page*)pages[index])->GetPDFPage();
+ if (!pPage)
+ continue;
pImgObj->m_pImage->ResetCache(pPage,NULL);
}
pImgObj->m_pImage->SetJpegImage(pFile);
@@ -56,7 +60,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetMatrix (FPDF_PAGEOBJECT image_object
DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages,int nCount,FPDF_PAGEOBJECT image_object,FPDF_BITMAP bitmap)
{
- if (!image_object || !bitmap)
+ if (!image_object || !bitmap || !pages)
return FALSE;
CFX_DIBitmap* pBmp = NULL;
pBmp = (CFX_DIBitmap*)bitmap;
@@ -64,7 +68,8 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFImageObj_SetBitmap(FPDF_PAGE* pages,int nCount,F
pImgObj->m_GeneralState.GetModify();
for (int index=0;index<nCount;index++)
{
- CPDF_Page* pPage = (CPDF_Page*)pages[index];
+ CPDF_Page* pPage = ((CPDFXFA_Page*)pages[index])->GetPDFPage();
+ if (!pPage) continue;
pImgObj->m_pImage->ResetCache(pPage,NULL);
}
pImgObj->m_pImage->SetImage(pBmp,FALSE);
diff --git a/fpdfsdk/src/fpdfeditpage.cpp b/fpdfsdk/src/fpdfeditpage.cpp
index 5c43d4d4b2..68dad9dbfe 100644
--- a/fpdfsdk/src/fpdfeditpage.cpp
+++ b/fpdfsdk/src/fpdfeditpage.cpp
@@ -7,6 +7,10 @@
// #include "x:/pdf/fpdfapi5/include/fpdfapi.h"
#include "../include/fsdk_define.h"
#include "../include/fpdfedit.h"
+#include "../include/fpdfformfill.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_app.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
#if _FX_OS_ == _FX_ANDROID_
@@ -51,12 +55,15 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_CreateNewDocument()
#endif
}
- return pDoc;
+ CPDFXFA_App* pApp = FPDFXFA_GetApp();
+ CPDFXFA_Document* document = FX_NEW CPDFXFA_Document(pDoc, pApp);
+
+ return document;
}
DLLEXPORT void STDCALL FPDFPage_Delete(FPDF_DOCUMENT document, int page_index)
{
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
if (pDoc == NULL)
return;
if (page_index < 0 || page_index >= pDoc->GetPageCount())
@@ -71,7 +78,7 @@ DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index,
return NULL;
// CPDF_Parser* pParser = (CPDF_Parser*)document;
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDF_Document* pDoc = ((CPDFXFA_Document*)document)->GetPDFDoc();
if(page_index < 0)
page_index = 0;
if(pDoc->GetPageCount()<page_index)
@@ -92,16 +99,19 @@ DLLEXPORT FPDF_PAGE STDCALL FPDFPage_New(FPDF_DOCUMENT document, int page_index,
pPageDict->SetAt("Rotate", FX_NEW CPDF_Number(0));
pPageDict->SetAt("Resources", FX_NEW CPDF_Dictionary);
- CPDF_Page* pPage = FX_NEW CPDF_Page;
- pPage->Load(pDoc,pPageDict);
- pPage->ParseContent();
+// CPDF_Page* pPage = FX_NEW CPDF_Page;
+// pPage->Load(pDoc,pPageDict);
+// pPage->ParseContent();
+
+ CPDFXFA_Page* pPage = FX_NEW CPDFXFA_Page((CPDFXFA_Document*)document, page_index);
+ pPage->LoadPDFPage(pPageDict);
return pPage;
}
DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page)
{
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
{
@@ -143,7 +153,7 @@ DLLEXPORT int STDCALL FPDFPage_GetRotation(FPDF_PAGE page)
DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT page_obj)
{
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
{
@@ -198,7 +208,7 @@ DLLEXPORT void STDCALL FPDFPage_InsertObject(FPDF_PAGE page, FPDF_PAGEOBJECT pag
DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page)
{
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
{
@@ -210,7 +220,7 @@ DLLEXPORT int STDCALL FPDFPage_CountObject(FPDF_PAGE page)
DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index)
{
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type")
|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
{
@@ -223,7 +233,8 @@ DLLEXPORT FPDF_PAGEOBJECT STDCALL FPDFPage_GetObject(FPDF_PAGE page, int index)
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_HasTransparency(FPDF_PAGE page)
{
if(!page) return FALSE;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return FALSE;
return pPage->BackgroundAlphaNeeded();
}
@@ -262,7 +273,7 @@ DLLEXPORT FPDF_BOOL STDCALL FPDFPageObj_HasTransparency(FPDF_PAGEOBJECT pageObje
DLLEXPORT FPDF_BOOL STDCALL FPDFPage_GenerateContent(FPDF_PAGE page)
{
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
{
@@ -289,7 +300,8 @@ DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
{
if(page == NULL)
return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
CPDF_AnnotList AnnotList(pPage);
for (int i=0; i<AnnotList.Count();i++)
{
@@ -317,7 +329,11 @@ DLLEXPORT void STDCALL FPDFPage_TransformAnnots(FPDF_PAGE page,
DLLEXPORT void STDCALL FPDFPage_SetRotation(FPDF_PAGE page, int rotate)
{
- CPDF_Page* pPage = (CPDF_Page*)page;
+ if (page == NULL)
+ return;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
+
if (!pPage || !pPage->m_pFormDict || !pPage->m_pFormDict->KeyExist("Type") || !pPage->m_pFormDict->GetElement("Type")->GetDirect()
|| pPage->m_pFormDict->GetElement("Type")->GetDirect()->GetString().Compare("Page"))
{
diff --git a/fpdfsdk/src/fpdfformfill.cpp b/fpdfsdk/src/fpdfformfill.cpp
index 2de76033fe..38a71fc6d9 100644
--- a/fpdfsdk/src/fpdfformfill.cpp
+++ b/fpdfsdk/src/fpdfformfill.cpp
@@ -7,7 +7,10 @@
#include "../include/fpdfview.h"
#include "../include/fpdfformfill.h"
#include "../include/fsdk_define.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
#include "../include/fsdk_mgr.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
+#include "../include/fpdfxfa/fpdfxfa_app.h"
#include "../include/javascript/IJavaScript.h"
@@ -17,60 +20,109 @@ DLLEXPORT int STDCALL FPDPage_HasFormFieldAtPoint(FPDF_FORMHANDLE hHandle, FPDF_
{
if(!page || !hHandle)
return -1;
- CPDF_Page * pPage = (CPDF_Page*) page;
-
- CPDF_InterForm * pInterForm = NULL;
- pInterForm = new CPDF_InterForm(pPage->m_pDocument,FALSE);
- if (!pInterForm)
- return -1;
- CPDF_FormControl* pFormCtrl = pInterForm->GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y);
- if(!pFormCtrl)
+ CPDF_Page * pPage = ((CPDFXFA_Page*) page)->GetPDFPage();
+ if (pPage)
{
+ CPDF_InterForm * pInterForm = NULL;
+ pInterForm = new CPDF_InterForm(pPage->m_pDocument,FALSE);
+ if (!pInterForm)
+ return -1;
+ CPDF_FormControl* pFormCtrl = pInterForm->GetControlAtPoint(pPage, (FX_FLOAT)page_x, (FX_FLOAT)page_y);
+ if(!pFormCtrl)
+ {
+ delete pInterForm;
+ return -1;
+ }
+ CPDF_FormField* pFormField = pFormCtrl->GetField();
+ if(!pFormField)
+ {
+ delete pInterForm;
+ return -1;
+ }
+
+ int nType = pFormField->GetFieldType();
delete pInterForm;
- return -1;
+ return nType;
}
- CPDF_FormField* pFormField = pFormCtrl->GetField();
- if(!pFormField)
+
+ IXFA_PageView* pPageView = ((CPDFXFA_Page*)page)->GetXFAPageView();
+ if (pPageView)
{
- delete pInterForm;
- return -1;
+ IXFA_WidgetHandler* pWidgetHandler = NULL;
+ IXFA_DocView* pDocView = pPageView->GetDocView();
+ if (!pDocView)
+ return -1;
+
+ pWidgetHandler = pDocView->GetWidgetHandler();
+ if (!pWidgetHandler)
+ return -1;
+
+ XFA_HWIDGET pXFAAnnot = NULL;
+ IXFA_WidgetIterator* pWidgetIterator = pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form, XFA_WIDGETFILTER_Viewable|XFA_WIDGETFILTER_AllType);
+ if (!pWidgetIterator)
+ return -1;
+ pXFAAnnot = pWidgetIterator->MoveToNext();
+ while (pXFAAnnot) {
+ CFX_RectF rcBBox;
+ pWidgetHandler->GetBBox (pXFAAnnot, rcBBox, 0);
+ CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, rcBBox.top+rcBBox.height);
+ rcWidget.left -= 1.0f;
+ rcWidget.right += 1.0f;
+ rcWidget.bottom -= 1.0f;
+ rcWidget.top += 1.0f;
+
+ if (rcWidget.Contains(page_x, page_y)) {
+ pWidgetIterator->Release();
+ return FPDF_FORMFIELD_XFA;
+ }
+ pXFAAnnot = pWidgetIterator->MoveToNext();
+ }
+
+ pWidgetIterator->Release();
}
- int nType = pFormField->GetFieldType();
- delete pInterForm;
- return nType;
+ return -1;
}
DLLEXPORT FPDF_FORMHANDLE STDCALL FPDFDOC_InitFormFillEnviroument(FPDF_DOCUMENT document, FPDF_FORMFILLINFO* formInfo)
{
if(!document || !formInfo || formInfo->version!=1)
return NULL;
- CPDF_Document * pDocument = (CPDF_Document*) document;
+ CPDFXFA_Document * pDocument = (CPDFXFA_Document*) document;
CPDFDoc_Environment * pEnv = NULL;
pEnv = new CPDFDoc_Environment(pDocument);
if (!pEnv)
return NULL;
pEnv->RegAppHandle(formInfo);
- if(pEnv->GetPDFDocument())
+ CPDFXFA_App* pApp = FPDFXFA_GetApp();
+ pApp->AddFormFillEnv(pEnv);
+
+ if(pEnv->GetPDFXFADocument())
{
- CPDFSDK_Document* pSDKDoc = new CPDFSDK_Document(pEnv->GetPDFDocument(), pEnv);
- if(pSDKDoc)
+ //CPDFSDK_Document* pSDKDoc = new CPDFSDK_Document(pEnv->GetPDFXFADocument(), pEnv);
+ CPDFSDK_Document* pSDKDoc = pDocument->GetSDKDocument(pEnv);
+ if(pSDKDoc) {
pEnv->SetCurrentDoc(pSDKDoc);
+ }
}
return pEnv;
}
DLLEXPORT void STDCALL FPDFDOC_ExitFormFillEnviroument(FPDF_FORMHANDLE hHandle)
{
- if(!hHandle)
+ if (!hHandle)
return;
- CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
- if(pSDKDoc)
- {
- ((CPDFDoc_Environment*)hHandle)->SetCurrentDoc(NULL);
- delete pSDKDoc;
- }
+ //CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
+ //if(pSDKDoc)
+ //{
+ //((CPDFDoc_Environment*)hHandle)->SetCurrentDoc(NULL);
+ //CPDFXFA_Document* pDoc = ((CPDFDoc_Environment*)hHandle)->GetPDFXFADocument();
+ //if (pDoc)
+ // pDoc->ReleaseSDKDoc();
+ //}
+ CPDFXFA_App* pApp = FPDFXFA_GetApp();
+ pApp->RemoveFormFillEnv((CPDFDoc_Environment*)hHandle);
delete (CPDFDoc_Environment*)hHandle;
hHandle = NULL;
}
@@ -85,7 +137,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnMouseMove(FPDF_FORMHANDLE hHandle, FPDF_PAGE
CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(!pFXDoc)
return FALSE;
- CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
if(!pPageView)
return FALSE;
@@ -103,7 +155,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonDown(FPDF_FORMHANDLE hHandle, FPDF_PAG
CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(!pFXDoc)
return FALSE;
- CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
if(!pPageView)
return FALSE;
// double page_x = 0;
@@ -120,7 +172,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE
CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(!pFXDoc)
return FALSE;
- CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
if(!pPageView)
return FALSE;
// double page_x = 0;
@@ -130,6 +182,38 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnLButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE
return pPageView->OnLButtonUp(pt, modifier);
}
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
+{
+ if (!hHandle || !page)
+ return FALSE;
+
+ CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
+ if(!pFXDoc)
+ return FALSE;
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
+ if(!pPageView)
+ return FALSE;
+
+ CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
+ return pPageView->OnRButtonDown(pt, modifier);
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FORM_OnRButtonUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int modifier, double page_x, double page_y)
+{
+ if (!hHandle || !page)
+ return FALSE;
+
+ CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
+ if(!pFXDoc)
+ return FALSE;
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
+ if(!pPageView)
+ return FALSE;
+
+ CPDF_Point pt((FX_FLOAT)page_x, (FX_FLOAT)page_y);
+ return pPageView->OnRButtonUp(pt, modifier);
+}
+
DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE page, int nKeyCode, int modifier)
{
if (!hHandle || !page)
@@ -137,7 +221,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyDown(FPDF_FORMHANDLE hHandle, FPDF_PAGE pa
CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(!pFXDoc)
return FALSE;
- CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
if(!pPageView)
return FALSE;
@@ -152,7 +236,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnKeyUp(FPDF_FORMHANDLE hHandle, FPDF_PAGE page
CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(!pFXDoc)
return FALSE;
- CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
if(!pPageView)
return FALSE;
@@ -168,7 +252,7 @@ DLLEXPORT FPDF_BOOL STDCALL FORM_OnChar(FPDF_FORMHANDLE hHandle, FPDF_PAGE page,
CPDFSDK_Document* pFXDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(!pFXDoc)
return FALSE;
- CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDF_Page*)page);
+ CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page);
if(!pPageView)
return FALSE;
return pPageView->OnChar(nChar, modifier);
@@ -191,27 +275,19 @@ DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, FPDF_BITMAP bitmap,
{
if (!hHandle || !page)
return ;
- CPDF_Page* pPage = (CPDF_Page*)page;
- CPDF_RenderOptions options;
- if (flags & FPDF_LCD_TEXT)
- options.m_Flags |= RENDER_CLEARTYPE;
- else
- options.m_Flags &= ~RENDER_CLEARTYPE;
-
- //Grayscale output
- if (flags & FPDF_GRAYSCALE)
- {
- options.m_ColorMode = RENDER_COLOR_GRAY;
- options.m_ForeColor = 0;
- options.m_BackColor = 0xffffff;
- }
-
- options.m_AddFlags = flags >> 8;
-
- options.m_pOCContext = FX_NEW CPDF_OCContext(pPage->m_pDocument);
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
+ CPDFXFA_Document* pDocument = pPage->GetDocument();
+ if (!pDocument)
+ return;
+ CPDF_Document* pPDFDoc = pDocument->GetPDFDoc();
+ if (!pPDFDoc)
+ return;
- //FXMT_CSLOCK_OBJ(&pPage->m_PageLock);
+ CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
+ CPDFSDK_Document* pFXDoc = pEnv->GetCurrentDoc();
+ if (!pFXDoc)
+ return;
CFX_AffineMatrix matrix;
pPage->GetDisplayMatrix(matrix, start_x, start_y, size_x, size_y, rotate);
@@ -235,31 +311,26 @@ DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, FPDF_BITMAP bitmap,
pDevice->SaveState();
pDevice->SetClip_Rect(&clip);
+ CPDF_RenderOptions options;
+ if (flags & FPDF_LCD_TEXT)
+ options.m_Flags |= RENDER_CLEARTYPE;
+ else
+ options.m_Flags &= ~RENDER_CLEARTYPE;
- CPDF_RenderContext* pContext = NULL;
- pContext = FX_NEW CPDF_RenderContext;
- if (!pContext)
+ //Grayscale output
+ if (flags & FPDF_GRAYSCALE)
{
- delete pDevice;
- pDevice = NULL;
- return;
+ options.m_ColorMode = RENDER_COLOR_GRAY;
+ options.m_ForeColor = 0;
+ options.m_BackColor = 0xffffff;
}
+ options.m_AddFlags = flags >> 8;
+ options.m_pOCContext = FX_NEW CPDF_OCContext(pPDFDoc);
-// CPDF_Document* pDoc = pPage->m_pDocument;
- CPDFDoc_Environment* pEnv = (CPDFDoc_Environment*)hHandle;
- CPDFSDK_Document* pFXDoc = pEnv->GetCurrentDoc();
- if(!pFXDoc)
+ if(CPDFSDK_PageView* pPageView = pFXDoc->GetPageView((CPDFXFA_Page*)page))
{
- delete pContext;
- delete pDevice;
- pContext = NULL;
- pDevice = NULL;
- return;
- }
- if(CPDFSDK_PageView* pPageView = pFXDoc->GetPageView(pPage))
- {
- pPageView->PageView_OnDraw(pDevice, &matrix, &options);
+ pPageView->PageView_OnDraw(pDevice, &matrix, &options, &clip);
}
pDevice->RestoreState();
@@ -268,11 +339,6 @@ DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, FPDF_BITMAP bitmap,
delete options.m_pOCContext;
options.m_pOCContext = NULL;
}
- if(pContext)
- {
- delete pContext;
- pContext = NULL;
- }
if(pDevice)
{
delete pDevice;
@@ -280,6 +346,235 @@ DLLEXPORT void STDCALL FPDF_FFLDraw(FPDF_FORMHANDLE hHandle, FPDF_BITMAP bitmap,
}
}
+DLLEXPORT void STDCALL FPDF_Widget_Undo(FPDF_DOCUMENT document, FPDF_WIDGET hWidget)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ pXFAMenuHander->Undo((XFA_HWIDGET)hWidget);
+
+}
+DLLEXPORT void STDCALL FPDF_Widget_Redo(FPDF_DOCUMENT document, FPDF_WIDGET hWidget)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ pXFAMenuHander->Redo((XFA_HWIDGET)hWidget);
+}
+
+DLLEXPORT void STDCALL FPDF_Widget_SelectAll(FPDF_DOCUMENT document, FPDF_WIDGET hWidget)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ pXFAMenuHander->SelectAll((XFA_HWIDGET)hWidget);
+}
+DLLEXPORT void STDCALL FPDF_Widget_Copy(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, FPDF_WIDESTRING wsText, FPDF_DWORD* size)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ CFX_WideString wsCpText;
+ pXFAMenuHander->Copy((XFA_HWIDGET)hWidget, wsCpText);
+
+ CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
+
+ int len = bsCpText.GetLength()/sizeof(unsigned short);
+
+ if (wsText == NULL) {
+ *size = len;
+ return;
+ }
+
+ int real_size = len < *size ? len : *size;
+ if (real_size > 0)
+ {
+ FXSYS_memcpy((void*)wsText,bsCpText.GetBuffer(real_size*sizeof(unsigned short)),real_size*sizeof(unsigned short));
+ bsCpText.ReleaseBuffer(real_size*sizeof(unsigned short));
+ }
+ *size = real_size;
+}
+DLLEXPORT void STDCALL FPDF_Widget_Cut(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, FPDF_WIDESTRING wsText, FPDF_DWORD* size)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ CFX_WideString wsCpText;
+ pXFAMenuHander->Cut((XFA_HWIDGET)hWidget, wsCpText);
+
+ CFX_ByteString bsCpText = wsCpText.UTF16LE_Encode();
+
+ int len = bsCpText.GetLength()/sizeof(unsigned short);
+
+ if (wsText == NULL) {
+ *size = len;
+ return;
+ }
+
+ int real_size = len < *size ? len : *size;
+ if (real_size > 0)
+ {
+ FXSYS_memcpy((void*)wsText,bsCpText.GetBuffer(real_size*sizeof(unsigned short)),real_size*sizeof(unsigned short));
+ bsCpText.ReleaseBuffer(real_size*sizeof(unsigned short));
+ }
+ *size = real_size;
+}
+DLLEXPORT void STDCALL FPDF_Widget_Paste(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, FPDF_WIDESTRING wsText, FPDF_DWORD size)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ CFX_WideString wstr = CFX_WideString::FromUTF16LE(wsText, size);
+
+ pXFAMenuHander->Paste((XFA_HWIDGET)hWidget, wstr);
+
+}
+DLLEXPORT void STDCALL FPDF_Widget_ReplaceSpellCheckWord(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, float x, float y, FPDF_BYTESTRING bsText)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ CFX_PointF ptPopup;
+ ptPopup.x = x;
+ ptPopup.y = y;
+ CFX_ByteStringC bs(bsText);
+ pXFAMenuHander->ReplaceSpellCheckWord((XFA_HWIDGET)hWidget,ptPopup,bs);
+
+}
+DLLEXPORT void STDCALL FPDF_Widget_GetSpellCheckWords(FPDF_DOCUMENT document, FPDF_WIDGET hWidget, float x, float y, FPDF_STRINGHANDLE* stringHandle)
+{
+ if (NULL == hWidget || NULL == document)
+ return;
+
+ CPDFXFA_Document* pDocument = (CPDFXFA_Document*)document;
+ if (pDocument->GetDocType() != XFA_DOCTYPE_Dynamic && pDocument->GetDocType() != XFA_DOCTYPE_Static)
+ return;
+
+ IXFA_MenuHandler* pXFAMenuHander = FPDFXFA_GetApp()->GetXFAApp()->GetMenuHandler();
+
+ if (pXFAMenuHander == NULL)
+ return;
+
+ CFX_ByteStringArray* sSuggestWords = FX_NEW CFX_ByteStringArray;
+ CFX_PointF ptPopup;
+ ptPopup.x = x;
+ ptPopup.y = y;
+ pXFAMenuHander->GetSuggestWords((XFA_HWIDGET)hWidget, ptPopup, *sSuggestWords);
+ *stringHandle = (FPDF_STRINGHANDLE)sSuggestWords;
+}
+DLLEXPORT int STDCALL FPDF_StringHandleCounts(FPDF_STRINGHANDLE stringHandle)
+{
+ if (stringHandle == NULL)
+ return -1;
+ CFX_ByteStringArray* sSuggestWords = (CFX_ByteStringArray*)stringHandle;
+ return sSuggestWords->GetSize();
+}
+DLLEXPORT FPDF_BOOL STDCALL FPDF_StringHandleGetStringByIndex(FPDF_STRINGHANDLE stringHandle, int index, FPDF_BYTESTRING bsText, FPDF_DWORD* size)
+{
+ if (stringHandle == NULL || size == NULL)
+ return FALSE;
+ int count = FPDF_StringHandleCounts(stringHandle);
+ if (index < 0|| index >= count)
+ return FALSE;
+
+ CFX_ByteStringArray sSuggestWords = *(CFX_ByteStringArray*)stringHandle;
+ int len = sSuggestWords[index].GetLength();
+
+ if (bsText == NULL) {
+ *size = len;
+ return TRUE;
+ }
+
+ int real_size = len < *size ? len : *size;
+ if (real_size > 0)
+ FXSYS_memcpy((void*)bsText, (FX_LPCSTR)(sSuggestWords[index]), real_size);
+ *size = real_size;
+
+ return TRUE;
+}
+DLLEXPORT void STDCALL FPDF_StringHandleRelease(FPDF_STRINGHANDLE stringHandle)
+{
+ if (stringHandle == NULL)
+ return;
+ CFX_ByteStringArray* sSuggestWords = (CFX_ByteStringArray*)stringHandle;
+ delete sSuggestWords;
+}
+
+DLLEXPORT FPDF_BOOL STDCALL FPDF_StringHandleAddString(FPDF_STRINGHANDLE stringHandle, FPDF_BYTESTRING bsText, FPDF_DWORD size)
+{
+ if (stringHandle == NULL || bsText == NULL || size <= 0)
+ return FALSE;
+
+ CFX_ByteStringArray* stringArr = (CFX_ByteStringArray*)stringHandle;
+ CFX_ByteString bsStr(bsText, size);
+
+ stringArr->Add(bsStr);
+ return TRUE;
+}
DLLEXPORT void STDCALL FPDF_SetFormFieldHighlightColor(FPDF_FORMHANDLE hHandle, int fieldType, unsigned long color)
{
@@ -329,7 +624,7 @@ DLLEXPORT void STDCALL FORM_OnAfterLoadPage(FPDF_PAGE page, FPDF_FORMHANDLE hHan
CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(!pSDKDoc)
return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, TRUE);
if(pPageView)
{
@@ -342,7 +637,7 @@ DLLEXPORT void STDCALL FORM_OnBeforeClosePage(FPDF_PAGE page, FPDF_FORMHANDLE hH
if(!hHandle || !page)
return;
CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);
if(pPageView)
{
@@ -380,7 +675,7 @@ DLLEXPORT void STDCALL FORM_DoDocumentAAction(FPDF_FORMHANDLE hHandle, int aaTyp
CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
if(pSDKDoc)
{
- CPDF_Document* pDoc = pSDKDoc->GetDocument();
+ CPDF_Document* pDoc = pSDKDoc->GetDocument()->GetPDFDoc();
CPDF_Dictionary* pDic = pDoc->GetRoot();
if (!pDic)
return;
@@ -400,7 +695,7 @@ DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page, FPDF_FORMHANDLE hHandl
if(!hHandle || !page)
return;
CPDFSDK_Document* pSDKDoc = ((CPDFDoc_Environment*)hHandle)->GetCurrentDoc();
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
CPDFSDK_PageView* pPageView = pSDKDoc->GetPageView(pPage, FALSE);
if(pPageView)
{
@@ -410,7 +705,9 @@ DLLEXPORT void STDCALL FORM_DoPageAAction(FPDF_PAGE page, FPDF_FORMHANDLE hHandl
CPDFSDK_ActionHandler *pActionHandler = pEnv->GetActionHander();
ASSERT(pActionHandler != NULL);
- CPDF_Dictionary *pPageDict = pPage->m_pFormDict;
+ if (!pPage->GetPDFPage())
+ return;
+ CPDF_Dictionary *pPageDict = pPage->GetPDFPage()->m_pFormDict;
ASSERT(pPageDict != NULL);
CPDF_AAction aa = pPageDict->GetDict(FX_BSTRC("AA"));
diff --git a/fpdfsdk/src/fpdfppo.cpp b/fpdfsdk/src/fpdfppo.cpp
index a5c4275648..ed0c8565c0 100644
--- a/fpdfsdk/src/fpdfppo.cpp
+++ b/fpdfsdk/src/fpdfppo.cpp
@@ -6,6 +6,7 @@
#include "../include/fpdfppo.h"
#include "../include/fsdk_define.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
class CPDF_PageOrganizer
{
@@ -428,8 +429,9 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,FPDF_DOCUMEN
if(dest_doc == NULL || src_doc == NULL )
return FALSE;
CFX_WordArray pageArray;
- CPDF_Document* pSrcDoc = (CPDF_Document*)src_doc;
- int nCount = pSrcDoc->GetPageCount();
+ CPDFXFA_Document* pSrcDoc = (CPDFXFA_Document*)src_doc;
+ CPDF_Document* pSrcPDFDoc = pSrcDoc->GetPDFDoc();
+ int nCount = pSrcPDFDoc->GetPageCount();
if(pagerange)
{
if(ParserPageRangeString(pagerange,&pageArray,nCount) == FALSE)
@@ -443,12 +445,13 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,FPDF_DOCUMEN
}
}
- CPDF_Document* pDestDoc = (CPDF_Document*)dest_doc;
+ CPDFXFA_Document* pDestDoc = (CPDFXFA_Document*)dest_doc;
+ CPDF_Document* pDestPDFDoc = pDestDoc->GetPDFDoc();
CPDF_PageOrganizer pageOrg;
- pageOrg.PDFDocInit(pDestDoc,pSrcDoc);
+ pageOrg.PDFDocInit(pDestPDFDoc,pSrcPDFDoc);
- if(pageOrg.ExportPage(pSrcDoc,&pageArray,pDestDoc,index))
+ if(pageOrg.ExportPage(pSrcPDFDoc,&pageArray,pDestPDFDoc,index))
return TRUE;
return FALSE;
}
@@ -457,13 +460,15 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, F
{
if(src_doc == NULL || dest_doc == NULL)
return false;
- CPDF_Document* pSrcDoc = (CPDF_Document*)src_doc;
- CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot();
- pSrcDict = pSrcDict->GetDict(FX_BSTRC("ViewerPreferences"));;
+ CPDFXFA_Document* pSrcDoc = (CPDFXFA_Document*)src_doc;
+ CPDF_Document* pSrcPDFDoc = pSrcDoc->GetPDFDoc();
+ CPDF_Dictionary* pSrcDict = pSrcPDFDoc->GetRoot();
+ pSrcDict = pSrcDict->GetDict(FX_BSTRC("ViewerPreferences"));
if(!pSrcDict)
return FALSE;
- CPDF_Document* pDstDoc = (CPDF_Document*)dest_doc;
- CPDF_Dictionary* pDstDict = pDstDoc->GetRoot();
+ CPDFXFA_Document* pDstDoc = (CPDFXFA_Document*)dest_doc;
+ CPDF_Document* pDstPDFDoc = pDstDoc->GetPDFDoc();
+ CPDF_Dictionary* pDstDict = pDstPDFDoc->GetRoot();
if(!pDstDict)
return FALSE;
pDstDict->SetAt(FX_BSTRC("ViewerPreferences"), pSrcDict->Clone(TRUE));
diff --git a/fpdfsdk/src/fpdfsave.cpp b/fpdfsdk/src/fpdfsave.cpp
index 45dfbf7214..229e580dec 100644
--- a/fpdfsdk/src/fpdfsave.cpp
+++ b/fpdfsdk/src/fpdfsave.cpp
@@ -7,6 +7,9 @@
#include "../include/fsdk_define.h"
#include "../include/fpdfsave.h"
#include "../include/fpdfedit.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_app.h"
+#include "../include/fpdfxfa/fpdfxfa_util.h"
#if _FX_OS_ == _FX_ANDROID_
#include "time.h"
#else
@@ -53,11 +56,258 @@ FX_BOOL CFX_IFileWrite::WriteBlock(const void* pData, size_t size)
return FALSE;
}
-FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,FPDF_DWORD flags, FPDF_BOOL bSetVersion,
+#define XFA_DATASETS 0
+#define XFA_FORMS 1
+
+FX_BOOL _SaveXFADocumentData(CPDFXFA_Document* pDocument, CFX_PtrArray& fileList)
+{
+ if (!pDocument)
+ return FALSE;
+ if (pDocument->GetDocType() != DOCTYPE_DYNIMIC_XFA && pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
+ return TRUE;
+ if (!FPDFXFA_GetApp()->GetXFAApp())
+ return TRUE;
+
+ IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
+ if (NULL == pXFADocView)
+ return TRUE;
+ IXFA_DocHandler *pXFADocHandler = FPDFXFA_GetApp()->GetXFAApp()->GetDocHandler();
+
+ CPDF_Document * pPDFDocument = pDocument->GetPDFDoc();
+ if (pDocument == NULL)
+ return FALSE;
+ CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
+ if (pRoot == NULL)
+ return FALSE;
+ CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
+ if (NULL == pAcroForm)
+ return FALSE;
+ CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
+ if (pXFA == NULL)
+ return TRUE;
+ if(pXFA->GetType() != PDFOBJ_ARRAY)
+ return FALSE;
+ CPDF_Array* pArray = pXFA->GetArray();
+ if (NULL == pArray)
+ return FALSE;
+ int size = pArray->GetCount();
+ int iFormIndex = -1;
+ int iDataSetsIndex = -1;
+ int iTemplate = -1;
+ int iLast = size - 2;
+ for (int i = 0; i < size - 1; i++)
+ {
+ CPDF_Object* pPDFObj = pArray->GetElement(i);
+ if (pPDFObj->GetType() != PDFOBJ_STRING)
+ continue;
+ if (pPDFObj->GetString() == "form")
+ iFormIndex = i+1;
+ else if (pPDFObj->GetString() == "datasets")
+ iDataSetsIndex = i+1;
+ else if (pPDFObj->GetString() == FX_BSTRC("template"))
+ iTemplate = i + 1;
+ }
+ IXFA_ChecksumContext* pContext = NULL;
+#define XFA_USECKSUM
+#ifdef XFA_USECKSUM
+ //Checksum
+ pContext = XFA_Checksum_Create();
+ FXSYS_assert(pContext);
+ pContext->StartChecksum();
+
+ //template
+ if (iTemplate > -1)
+ {
+ CPDF_Stream *pTemplateStream = pArray->GetStream(iTemplate);
+ CPDF_StreamAcc streamAcc;
+ streamAcc.LoadAllData(pTemplateStream);
+ FX_LPBYTE pData = (FX_LPBYTE)streamAcc.GetData();
+ FX_DWORD dwSize2 = streamAcc.GetSize();
+ IFX_FileStream *pTemplate = FX_CreateMemoryStream(pData, dwSize2);
+ pContext->UpdateChecksum((IFX_FileRead*)pTemplate);
+ pTemplate->Release();
+ }
+#endif
+ CPDF_Stream* pFormStream = NULL;
+ CPDF_Stream* pDataSetsStream = NULL;
+ if (iFormIndex != -1)
+ {
+ //Get form CPDF_Stream
+ CPDF_Object* pFormPDFObj = pArray->GetElement(iFormIndex);
+ if (pFormPDFObj->GetType() == PDFOBJ_REFERENCE)
+ {
+ CPDF_Reference* pFormRefObj = (CPDF_Reference*)pFormPDFObj;
+ CPDF_Object* pFormDircetObj = pFormPDFObj->GetDirect();
+ if (NULL != pFormDircetObj && pFormDircetObj->GetType() == PDFOBJ_STREAM)
+ {
+ pFormStream = (CPDF_Stream*)pFormDircetObj;
+ }
+ }
+ else if (pFormPDFObj->GetType() == PDFOBJ_STREAM)
+ {
+ pFormStream = (CPDF_Stream*)pFormPDFObj;
+ }
+ }
+
+ if (iDataSetsIndex != -1)
+ {
+ //Get datasets CPDF_Stream
+ CPDF_Object* pDataSetsPDFObj = pArray->GetElement(iDataSetsIndex);
+ if (pDataSetsPDFObj->GetType() == PDFOBJ_REFERENCE)
+ {
+ CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
+ CPDF_Object* pDataSetsDircetObj = pDataSetsRefObj->GetDirect();
+ if (NULL != pDataSetsDircetObj && pDataSetsDircetObj->GetType() == PDFOBJ_STREAM)
+ {
+ pDataSetsStream = (CPDF_Stream*)pDataSetsDircetObj;
+ }
+ }
+ else if (pDataSetsPDFObj->GetType() == PDFOBJ_STREAM)
+ {
+ pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
+ }
+ }
+ //end
+ //L"datasets"
+ {
+ IFX_FileStream* pDsfileWrite = FX_CreateMemoryStream();
+ if ( NULL == pDsfileWrite )
+ {
+ pContext->Release();
+ pDsfileWrite->Release();
+ return FALSE;
+ }
+ if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(), CFX_WideStringC(L"datasets"), pDsfileWrite) && pDsfileWrite->GetSize()>0)
+ {
+#ifdef XFA_USECKSUM
+ //Datasets
+ pContext->UpdateChecksum((IFX_FileRead*)pDsfileWrite);
+ pContext->FinishChecksum();
+#endif
+ CPDF_Dictionary* pDataDict = FX_NEW CPDF_Dictionary;
+ if (iDataSetsIndex != -1)
+ {
+ if (pDataSetsStream)
+ pDataSetsStream->InitStream(pDsfileWrite, pDataDict);
+ }
+ else
+ {
+ CPDF_Stream* pData = FX_NEW CPDF_Stream(NULL, 0, NULL);
+ pData->InitStream(pDsfileWrite, pDataDict);
+ FX_DWORD AppStreamobjnum = pPDFDocument->AddIndirectObject(pData);
+ CPDF_Reference* pRef = (CPDF_Reference*)pPDFDocument->GetIndirectObject(AppStreamobjnum);
+ {
+ iLast = pArray->GetCount() -2;
+ pArray->InsertAt(iLast,CPDF_String::Create("datasets"));
+ pArray->InsertAt(iLast+1, pData, pPDFDocument);
+ }
+ }
+ fileList.Add(pDsfileWrite);
+ }
+ }
+
+
+ //L"form"
+ {
+
+ IFX_FileStream* pfileWrite = FX_CreateMemoryStream();
+ if (NULL == pfileWrite)
+ {
+ pContext->Release();
+ return FALSE;
+ }
+ if(pXFADocHandler->SavePackage(pXFADocView->GetDoc(), CFX_WideStringC(L"form"), pfileWrite, pContext) && pfileWrite > 0)
+ {
+ CPDF_Dictionary* pDataDict = FX_NEW CPDF_Dictionary;
+ if (iFormIndex != -1)
+ {
+ if (pFormStream)
+ pFormStream->InitStream(pfileWrite, pDataDict);
+ }
+ else
+ {
+ CPDF_Stream* pData = FX_NEW CPDF_Stream(NULL, 0, NULL);
+ pData->InitStream(pfileWrite, pDataDict);
+ FX_DWORD AppStreamobjnum = pPDFDocument->AddIndirectObject(pData);
+ CPDF_Reference* pRef = (CPDF_Reference*)pPDFDocument->GetIndirectObject(AppStreamobjnum);
+ {
+ iLast = pArray->GetCount() -2;
+ pArray->InsertAt(iLast, CPDF_String::Create("form"));
+ pArray->InsertAt(iLast+1, pData, pPDFDocument);
+ }
+ }
+ fileList.Add(pfileWrite);
+ }
+ }
+ pContext->Release();
+ return TRUE;
+}
+
+
+FX_BOOL _SendPostSaveToXFADoc(CPDFXFA_Document* pDocument)
+{
+ if (!pDocument)
+ return FALSE;
+
+ if (pDocument->GetDocType() != DOCTYPE_DYNIMIC_XFA && pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
+ return TRUE;
+
+ IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
+ if (NULL == pXFADocView)
+ return FALSE;
+ IXFA_WidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
+
+ CXFA_WidgetAcc* pWidgetAcc = NULL;
+ IXFA_WidgetAccIterator* pWidgetAccIterator = pXFADocView->CreateWidgetAccIterator();
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ while(pWidgetAcc)
+ {
+ CXFA_EventParam preParam;
+ preParam.m_eType = XFA_EVENT_PostSave;
+ pWidgetHander->ProcessEvent(pWidgetAcc,&preParam);
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ }
+ pWidgetAccIterator->Release();
+ pXFADocView->UpdateDocView();
+ pDocument->_ClearChangeMark();
+ return TRUE;
+}
+
+
+FX_BOOL _SendPreSaveToXFADoc(CPDFXFA_Document* pDocument, CFX_PtrArray& fileList)
+{
+ if (pDocument->GetDocType() != DOCTYPE_DYNIMIC_XFA && pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
+ return TRUE;
+ IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
+ if (NULL == pXFADocView)
+ return TRUE;
+ IXFA_WidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
+ CXFA_WidgetAcc* pWidgetAcc = NULL;
+ IXFA_WidgetAccIterator* pWidgetAccIterator = pXFADocView->CreateWidgetAccIterator();
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ while(pWidgetAcc)
+ {
+ CXFA_EventParam preParam;
+ preParam.m_eType = XFA_EVENT_PreSave;
+ pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ }
+ pWidgetAccIterator->Release();
+ pXFADocView->UpdateDocView();
+ return _SaveXFADocumentData(pDocument, fileList);
+}
+
+FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document, FPDF_FILEWRITE * pFileWrite,FPDF_DWORD flags, FPDF_BOOL bSetVersion,
int fileVerion)
{
- CPDF_Document* pDoc = (CPDF_Document*)document;
- if (!pDoc)
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
+
+ CFX_PtrArray fileList;
+
+ _SendPreSaveToXFADoc(pDoc, fileList);
+
+ CPDF_Document* pPDFDoc = pDoc->GetPDFDoc();
+ if (!pPDFDoc)
return 0;
if ( flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY )
@@ -65,10 +315,10 @@ FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,FPDF
flags = 0;
}
- CPDF_Creator FileMaker(pDoc);
- if(bSetVersion)
+ CPDF_Creator FileMaker(pPDFDoc);
+ if (bSetVersion)
FileMaker.SetFileVersion(fileVerion);
- if(flags == FPDF_REMOVE_SECURITY)
+ if (flags == FPDF_REMOVE_SECURITY)
{
flags = 0;
FileMaker.RemoveSecurity();
@@ -78,6 +328,17 @@ FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,FPDF
pStreamWrite = new CFX_IFileWrite;
pStreamWrite->Init( pFileWrite );
bRet = FileMaker.Create(pStreamWrite, flags);
+
+ _SendPostSaveToXFADoc(pDoc);
+ //pDoc->_ClearChangeMark();
+
+ for (int i = 0; i < fileList.GetSize(); i++)
+ {
+ IFX_FileStream* pFile = (IFX_FileStream*)fileList.GetAt(i);
+ pFile->Release();
+ }
+ fileList.RemoveAll();
+
delete pStreamWrite;
return bRet;
}
@@ -88,9 +349,9 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy( FPDF_DOCUMENT document,FPDF_FILEWRI
return _FPDF_Doc_Save(document, pFileWrite, flags, FALSE , 0);
}
-
DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion( FPDF_DOCUMENT document,FPDF_FILEWRITE * pFileWrite,
FPDF_DWORD flags, int fileVersion)
{
return _FPDF_Doc_Save(document, pFileWrite, flags, TRUE , fileVersion);
}
+
diff --git a/fpdfsdk/src/fpdftext.cpp b/fpdfsdk/src/fpdftext.cpp
index 264631b630..002637483d 100644
--- a/fpdfsdk/src/fpdftext.cpp
+++ b/fpdfsdk/src/fpdftext.cpp
@@ -6,6 +6,8 @@
#include "../include/fsdk_define.h"
#include "../include/fpdftext.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
#ifdef _WIN32
#include <tchar.h>
@@ -18,9 +20,13 @@ DLLEXPORT FPDF_TEXTPAGE STDCALL FPDFText_LoadPage(FPDF_PAGE page)
{
if (!page) return NULL;
IPDF_TextPage* textpage=NULL;
- CPDF_ViewerPreferences viewRef(((CPDF_Page*)page)->m_pDocument);
- textpage=IPDF_TextPage::CreateTextPage((CPDF_Page*)page,viewRef.IsDirectionR2L());
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
+ if (!pPage->GetPDFPage()) return NULL;
+ CPDFXFA_Document* pDoc = pPage->GetDocument();
+ CPDF_ViewerPreferences viewRef(pDoc->GetPDFDoc());
+ textpage=IPDF_TextPage::CreateTextPage((CPDF_Page*)pPage->GetPDFPage(),viewRef.IsDirectionR2L());
textpage->ParseTextPage();
+
return textpage;
}
DLLEXPORT void STDCALL FPDFText_ClosePage(FPDF_TEXTPAGE text_page)
diff --git a/fpdfsdk/src/fpdfview.cpp b/fpdfsdk/src/fpdfview.cpp
index bd49862e1c..ae8f3ccd91 100644
--- a/fpdfsdk/src/fpdfview.cpp
+++ b/fpdfsdk/src/fpdfview.cpp
@@ -11,11 +11,116 @@
#include "../include/fpdf_progressive.h"
#include "../include/fpdf_ext.h"
#include "../../third_party/numerics/safe_conversions_impl.h"
+#include "../include/fpdfformfill.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_app.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
+#include "../include/fpdfxfa/fpdfxfa_util.h"
+
+CFPDF_FileStream::CFPDF_FileStream(FPDF_FILEHANDLER* pFS)
+{
+ m_pFS = pFS;
+ m_nCurPos = 0;
+}
+
+IFX_FileStream* CFPDF_FileStream::Retain()
+{
+ return this;
+}
+
+void CFPDF_FileStream::Release()
+{
+ if (m_pFS && m_pFS->Release)
+ m_pFS->Release(m_pFS->clientData);
+ delete this;
+}
+
+FX_FILESIZE CFPDF_FileStream::GetSize()
+{
+ if (m_pFS && m_pFS->GetSize)
+ return (FX_FILESIZE)m_pFS->GetSize(m_pFS->clientData);
+ return 0;
+}
+
+FX_BOOL CFPDF_FileStream::IsEOF()
+{
+ return m_nCurPos >= GetSize();
+}
+
+FX_BOOL CFPDF_FileStream::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
+{
+ if (!buffer || !size || !m_pFS->ReadBlock) return FALSE;
+
+ if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer, (FPDF_DWORD)size) == 0)
+ {
+ m_nCurPos = offset + size;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+size_t CFPDF_FileStream::ReadBlock(void* buffer, size_t size)
+{
+ if (!buffer || !size || !m_pFS->ReadBlock) return 0;
+
+ FX_FILESIZE nSize = GetSize();
+ if (m_nCurPos >= nSize) return 0;
+ FX_FILESIZE dwAvail = nSize - m_nCurPos;
+ if (dwAvail < (FX_FILESIZE)size) size = (size_t)dwAvail;
+ if (m_pFS->ReadBlock(m_pFS->clientData, (FPDF_DWORD)m_nCurPos, buffer, (FPDF_DWORD)size) == 0)
+ {
+ m_nCurPos += size;
+ return size;
+ }
+
+ return 0;
+}
+
+FX_BOOL CFPDF_FileStream::WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size)
+{
+ if (!m_pFS || !m_pFS->WriteBlock) return FALSE;
+
+ if(m_pFS->WriteBlock(m_pFS->clientData, (FPDF_DWORD)offset, buffer, (FPDF_DWORD)size) == 0)
+ {
+ m_nCurPos = offset + size;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FX_BOOL CFPDF_FileStream::Flush()
+{
+ if (!m_pFS || !m_pFS->Flush) return TRUE;
+
+ return m_pFS->Flush(m_pFS->clientData) == 0;
+}
CPDF_CustomAccess::CPDF_CustomAccess(FPDF_FILEACCESS* pFileAccess)
{
- if (pFileAccess)
- m_FileAccess = *pFileAccess;
+ m_FileAccess = *pFileAccess;
+ m_BufferOffset = (FX_DWORD)-1;
+}
+
+FX_BOOL CPDF_CustomAccess::GetByte(FX_DWORD pos, FX_BYTE& ch)
+{
+ if (pos >= m_FileAccess.m_FileLen) return FALSE;
+ if (m_BufferOffset == (FX_DWORD)-1 || pos < m_BufferOffset || pos >= m_BufferOffset + 512) {
+ // Need to read from file access
+ m_BufferOffset = pos;
+ int size = 512;
+ if (pos + 512 > m_FileAccess.m_FileLen)
+ size = m_FileAccess.m_FileLen - pos;
+ if (!m_FileAccess.m_GetBlock(m_FileAccess.m_Param, m_BufferOffset, m_Buffer, size))
+ return FALSE;
+ }
+ ch = m_Buffer[pos - m_BufferOffset];
+ return TRUE;
+}
+
+FX_BOOL CPDF_CustomAccess::GetBlock(FX_DWORD pos, FX_LPBYTE pBuf, FX_DWORD size)
+{
+ if (pos + size > m_FileAccess.m_FileLen) return FALSE;
+ return m_FileAccess.m_GetBlock(m_FileAccess.m_Param, pos, pBuf, size);
}
FX_BOOL CPDF_CustomAccess::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
@@ -161,6 +266,9 @@ DLLEXPORT void STDCALL FPDF_InitLibrary(FX_LPVOID hInstance)
#endif
#endif
+ CPDFXFA_App* pAppProvider = FPDFXFA_GetApp();
+ pAppProvider->Initialize();
+
#ifdef _WIN32
// Get module path
TCHAR app_path[MAX_PATH];
@@ -187,6 +295,7 @@ DLLEXPORT void STDCALL FPDF_InitLibrary(FX_LPVOID hInstance)
DLLEXPORT void STDCALL FPDF_DestroyLibrary()
{
+ FPDFXFA_ReleaseApp();
#if _FX_OS_ == _FX_LINUX_EMBEDDED_
if (g_pFontMapper) delete g_pFontMapper;
@@ -254,8 +363,26 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadDocument(FPDF_STRING file_path, FPDF_BY
ProcessParseError(err_code);
return NULL;
}
- return pParser->GetDocument();
+ CPDF_Document* pPDFDoc = pParser->GetDocument();
+ if (!pPDFDoc)
+ return NULL;
+
+ CPDFXFA_App* pProvider = FPDFXFA_GetApp();
+ CPDFXFA_Document* pDocument = FX_NEW CPDFXFA_Document(pPDFDoc, pProvider);
+ return pDocument;
}
+DLLEXPORT FPDF_BOOL STDCALL FPDF_LoadXFA(FPDF_DOCUMENT document)
+{
+ if (!document||!((CPDFXFA_Document*)document)->GetPDFDoc())
+ return FALSE;
+
+ int iDocType = DOCTYPE_PDF;
+ FX_BOOL hasXFAField = FPDF_HasXFAField(((CPDFXFA_Document*)document)->GetPDFDoc(), iDocType);
+ if (!hasXFAField)
+ return FALSE;
+ return ((CPDFXFA_Document*)document)->LoadXFADoc();
+}
+
extern void CheckUnSupportError(CPDF_Document * pDoc, FX_DWORD err_code);
@@ -297,7 +424,15 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadMemDocument(const void* data_buf, int s
CPDF_Document * pDoc = NULL;
pDoc = pParser?pParser->GetDocument():NULL;
CheckUnSupportError(pDoc, err_code);
- return pParser->GetDocument();
+ CPDF_Document* pPDFDoc = pParser->GetDocument();
+ if (!pPDFDoc)
+ return NULL;
+
+ CPDFXFA_App* pProvider = FPDFXFA_GetApp();
+ CPDFXFA_Document* pDocument = FX_NEW CPDFXFA_Document(pPDFDoc, pProvider);
+ //pDocument->LoadXFADoc();
+
+ return pDocument;
}
DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAccess, FPDF_BYTESTRING password)
@@ -314,15 +449,26 @@ DLLEXPORT FPDF_DOCUMENT STDCALL FPDF_LoadCustomDocument(FPDF_FILEACCESS* pFileAc
CPDF_Document * pDoc = NULL;
pDoc = pParser?pParser->GetDocument():NULL;
CheckUnSupportError(pDoc, err_code);
- return pParser->GetDocument();
+ CPDF_Document* pPDFDoc = pParser->GetDocument();
+ if (!pPDFDoc)
+ return NULL;
+
+ CPDFXFA_App* pProvider = FPDFXFA_GetApp();
+ CPDFXFA_Document* pDocument = FX_NEW CPDFXFA_Document(pPDFDoc, pProvider);
+ //pDocument->LoadXFADoc();
+
+ return pDocument;
}
DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, int* fileVersion)
{
if(!doc||!fileVersion) return FALSE;
*fileVersion = 0;
- CPDF_Document* pDoc = (CPDF_Document*)doc;
- CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser();
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)doc;
+ CPDF_Document* pPDFDoc = pDoc->GetPDFDoc();
+ if (!pPDFDoc) return (FX_DWORD)-1;
+ CPDF_Parser* pParser = (CPDF_Parser*)pPDFDoc->GetParser();
+
if(!pParser)
return FALSE;
*fileVersion = pParser->GetFileVersion();
@@ -333,8 +479,10 @@ DLLEXPORT FPDF_BOOL STDCALL FPDF_GetFileVersion(FPDF_DOCUMENT doc, int* fileVers
DLLEXPORT unsigned long STDCALL FPDF_GetDocPermissions(FPDF_DOCUMENT document)
{
if (document == NULL) return 0;
- CPDF_Document*pDoc = (CPDF_Document*)document;
- CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser();
+ CPDFXFA_Document*pDoc = (CPDFXFA_Document*)document;
+ CPDF_Document* pPDFDoc = pDoc->GetPDFDoc();
+ if (!pPDFDoc) return (FX_DWORD)-1;
+ CPDF_Parser* pParser = (CPDF_Parser*)pPDFDoc->GetParser();
CPDF_Dictionary* pDict = pParser->GetEncryptDict();
if (pDict == NULL) return (FX_DWORD)-1;
@@ -355,38 +503,33 @@ DLLEXPORT int STDCALL FPDF_GetSecurityHandlerRevision(FPDF_DOCUMENT document)
DLLEXPORT int STDCALL FPDF_GetPageCount(FPDF_DOCUMENT document)
{
if (document == NULL) return 0;
- return ((CPDF_Document*)document)->GetPageCount();
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
+ return pDoc->GetPageCount();
+// return ((CPDF_Document*)document)->GetPageCount();
}
DLLEXPORT FPDF_PAGE STDCALL FPDF_LoadPage(FPDF_DOCUMENT document, int page_index)
{
if (document == NULL) return NULL;
- if (page_index < 0 || page_index >= FPDF_GetPageCount(document)) return NULL;
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
+ if (page_index < 0 || page_index >= pDoc->GetPageCount()) return NULL;
// CPDF_Parser* pParser = (CPDF_Parser*)document;
- CPDF_Document* pDoc = (CPDF_Document*)document;
- if (pDoc == NULL) return NULL;
- CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
- if (pDict == NULL) return NULL;
- CPDF_Page* pPage = FX_NEW CPDF_Page;
- pPage->Load(pDoc, pDict);
- pPage->ParseContent();
-
-// CheckUnSupportError(pDoc, 0);
-
- return pPage;
+ return pDoc->GetPage(page_index);
}
DLLEXPORT double STDCALL FPDF_GetPageWidth(FPDF_PAGE page)
{
if (!page)
return 0.0;
- return ((CPDF_Page*)page)->GetPageWidth();
+ return ((CPDFXFA_Page*)page)->GetPageWidth();
+// return ((CPDF_Page*)page)->GetPageWidth();
}
DLLEXPORT double STDCALL FPDF_GetPageHeight(FPDF_PAGE page)
{
if (!page) return 0.0;
- return ((CPDF_Page*)page)->GetPageHeight();
+// return ((CPDF_Page*)page)->GetPageHeight();
+ return ((CPDFXFA_Page*)page)->GetPageHeight();
}
void DropContext(void* data)
@@ -408,7 +551,8 @@ DLLEXPORT void STDCALL FPDF_RenderPage(HDC dc, FPDF_PAGE page, int start_x, int
int rotate, int flags)
{
if (page==NULL) return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
CRenderContext* pContext = FX_NEW CRenderContext;
pPage->SetPrivateData((void*)1, pContext, DropContext);
@@ -562,8 +706,8 @@ DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page,
int size_x, int size_y, int rotate, int flags)
{
if (bitmap == NULL || page == NULL) return;
- CPDF_Page* pPage = (CPDF_Page*)page;
-
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
+ if (!pPage) return;
CRenderContext* pContext = FX_NEW CRenderContext;
pPage->SetPrivateData((void*)1, pContext, DropContext);
@@ -592,12 +736,14 @@ DLLEXPORT void STDCALL FPDF_RenderPageBitmap(FPDF_BITMAP bitmap, FPDF_PAGE page,
DLLEXPORT void STDCALL FPDF_ClosePage(FPDF_PAGE page)
{
if (!page) return;
- CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)(((CPDF_Page*)page))->GetPrivateData((FX_LPVOID)page);
- if (pPageView && pPageView->IsLocked()) {
- pPageView->TakeOverPage();
- return;
- }
- delete (CPDF_Page*)page;
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
+
+ pPage->Release();
+// CPDFXFA_Document* pDoc = pPage->GetDocument();
+// if (pDoc) {
+// pDoc->RemovePage(pPage);
+// }
+// delete (CPDFXFA_Page*)page;
}
@@ -605,14 +751,16 @@ DLLEXPORT void STDCALL FPDF_CloseDocument(FPDF_DOCUMENT document)
{
if (!document)
return;
- CPDF_Document* pDoc = (CPDF_Document*)document;
- CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser();
- if (pParser == NULL)
- {
- delete pDoc;
- return;
- }
- delete pParser;
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
+ delete pDoc;
+
+// CPDF_Parser* pParser = (CPDF_Parser*)pDoc->GetParser();
+// if (pParser == NULL)
+// {
+// delete pDoc;
+// return;
+// }
+// delete pParser;
// delete pDoc;
}
@@ -625,34 +773,17 @@ DLLEXPORT void STDCALL FPDF_DeviceToPage(FPDF_PAGE page, int start_x, int start_
int rotate, int device_x, int device_y, double* page_x, double* page_y)
{
if (page == NULL || page_x == NULL || page_y == NULL) return;
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
- CPDF_Matrix page2device;
- pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
- CPDF_Matrix device2page;
- device2page.SetReverse(page2device);
-
- FX_FLOAT page_x_f, page_y_f;
- device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, page_y_f);
-
- *page_x = (page_x_f);
- *page_y = (page_y_f);
+ pPage->DeviceToPage(start_x, start_y, size_x, size_y, rotate, device_x, device_y, page_x, page_y);
}
DLLEXPORT void STDCALL FPDF_PageToDevice(FPDF_PAGE page, int start_x, int start_y, int size_x, int size_y,
int rotate, double page_x, double page_y, int* device_x, int* device_y)
{
if (page == NULL || device_x == NULL || device_y == NULL) return;
- CPDF_Page* pPage = (CPDF_Page*)page;
-
- CPDF_Matrix page2device;
- pPage->GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
-
- FX_FLOAT device_x_f, device_y_f;
- page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, device_y_f);
-
- *device_x = FXSYS_round(device_x_f);
- *device_y = FXSYS_round(device_y_f);
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)page;
+ pPage->PageToDevice(start_x, start_y, size_x, size_y, rotate, page_x, page_y, device_x, device_y);
}
DLLEXPORT FPDF_BITMAP STDCALL FPDFBitmap_Create(int width, int height, int alpha)
@@ -734,7 +865,7 @@ void FPDF_RenderPage_Retail(CRenderContext* pContext, FPDF_PAGE page, int start_
int rotate, int flags,FX_BOOL bNeedToRestore, IFSDK_PAUSE_Adapter * pause )
{
//#ifdef _LICENSED_BUILD_
- CPDF_Page* pPage = (CPDF_Page*)page;
+ CPDF_Page* pPage = ((CPDFXFA_Page*)page)->GetPDFPage();
if (pPage == NULL) return;
if (!pContext->m_pOptions)
@@ -797,26 +928,43 @@ void FPDF_RenderPage_Retail(CRenderContext* pContext, FPDF_PAGE page, int start_
DLLEXPORT int STDCALL FPDF_GetPageSizeByIndex(FPDF_DOCUMENT document, int page_index, double* width, double* height)
{
- CPDF_Document* pDoc = (CPDF_Document*)document;
- if(pDoc == NULL)
+// CPDF_Document* pDoc = (CPDF_Document*)document;
+// if(pDoc == NULL)
+// return FALSE;
+//
+// CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
+// if (pDict == NULL) return FALSE;
+//
+// CPDF_Page page;
+// page.Load(pDoc, pDict);
+// *width = page.GetPageWidth();
+// *height = page.GetPageHeight();
+
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
+ if (pDoc == NULL)
return FALSE;
- CPDF_Dictionary* pDict = pDoc->GetPage(page_index);
- if (pDict == NULL) return FALSE;
+ int count = pDoc->GetPageCount();
+ if (page_index < 0 || page_index >= count)
+ return FALSE;
- CPDF_Page page;
- page.Load(pDoc, pDict);
- *width = page.GetPageWidth();
- *height = page.GetPageHeight();
+ CPDFXFA_Page* pPage = pDoc->GetPage(page_index);
+ if (!pPage)
+ return FALSE;
+
+ *width = pPage->GetPageWidth();
+ *height = pPage->GetPageHeight();
return TRUE;
}
DLLEXPORT FPDF_BOOL STDCALL FPDF_VIEWERREF_GetPrintScaling(FPDF_DOCUMENT document)
{
- CPDF_Document* pDoc = (CPDF_Document*)document;
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
if (!pDoc) return TRUE;
- CPDF_ViewerPreferences viewRef(pDoc);
+ CPDF_Document* pPDFDoc = pDoc->GetPDFDoc();
+ if (!pPDFDoc) return TRUE;
+ CPDF_ViewerPreferences viewRef(pPDFDoc);
return viewRef.PrintScaling();
}
@@ -858,7 +1006,67 @@ DLLEXPORT FPDF_DEST STDCALL FPDF_GetNamedDestByName(FPDF_DOCUMENT document,FPDF_
if (name == NULL || name[0] == 0)
return NULL;
- CPDF_Document* pDoc = (CPDF_Document*)document;
- CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests"));
- return name_tree.LookupNamedDest(pDoc, name);
+ CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;
+ CPDF_Document* pPDFDoc = pDoc->GetPDFDoc();
+ if (!pPDFDoc)
+ return NULL;
+ CPDF_NameTree name_tree(pPDFDoc, FX_BSTRC("Dests"));
+ return name_tree.LookupNamedDest(pPDFDoc, name);
+}
+
+FPDF_RESULT FPDF_BStr_Init(FPDF_BSTR* str)
+{
+ if (!str)
+ return -1;
+
+ FXSYS_memset32(str, 0, sizeof(FPDF_BSTR));
+ return 0;
+}
+
+FPDF_RESULT FPDF_BStr_Set(FPDF_BSTR* str, FPDF_LPCSTR bstr, int length)
+{
+ if (!str) return -1;
+ if (!bstr || !length)
+ return -1;
+ if (length == -1)
+ length = FXSYS_strlen(bstr);
+
+ if (length == 0)
+ {
+ if (str->str)
+ {
+ FX_Free(str->str);
+ str->str = NULL;
+ }
+ str->len = 0;
+ return 0;
+ }
+
+ if (str->str && str->len < length)
+ str->str = FX_Realloc(char, str->str, length+1);
+ else if (!str->str)
+ str->str = FX_Alloc(char, length+1);
+
+ str->str[length] = 0;
+ if (str->str == NULL)
+ return -1;
+
+ FXSYS_memcpy(str->str, bstr, length);
+ str->len = length;
+
+ return 0;
+}
+
+FPDF_RESULT FPDF_BStr_Clear(FPDF_BSTR* str)
+{
+ if(!str)
+ return -1;
+
+ if (str->str)
+ {
+ FX_Free(str->str);
+ str->str = NULL;
+ }
+ str->len = 0;
+ return 0;
}
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp
new file mode 100644
index 0000000000..7abd2741a0
--- /dev/null
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp
@@ -0,0 +1,640 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../include/fsdk_define.h"
+#include "../../include/fpdfformfill.h"
+#include "../../include/fsdk_mgr.h"
+#include "../../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../../include/fpdfxfa/fpdfxfa_util.h"
+#include "../../include/jsapi/fxjs_v8.h"
+#include "../../include/javascript/IJavaScript.h"
+#include "../../include/fpdfxfa/fpdfxfa_app.h"
+CPDFXFA_App* CPDFXFA_App::m_pApp = NULL;
+
+CPDFXFA_App* FPDFXFA_GetApp()
+{
+ if (!CPDFXFA_App::m_pApp)
+ CPDFXFA_App::m_pApp = FX_NEW CPDFXFA_App();
+
+ return CPDFXFA_App::m_pApp;
+}
+
+void FPDFXFA_ReleaseApp()
+{
+ if (CPDFXFA_App::m_pApp)
+ delete CPDFXFA_App::m_pApp;
+ CPDFXFA_App::m_pApp = NULL;
+}
+
+CJS_RuntimeFactory* g_GetJSRuntimeFactory()
+{
+ static CJS_RuntimeFactory g_JSRuntimeFactory;
+ return &g_JSRuntimeFactory;
+}
+
+CPDFXFA_App::CPDFXFA_App() :
+ m_pXFAApp(NULL),
+ m_pFontMgr(NULL),
+ m_hJSERuntime(NULL),
+ //m_pJSRuntime(NULL),
+ //m_pEnv(NULL),
+ m_csAppType(JS_STR_VIEWERTYPE_STANDARD)
+{
+ m_pJSRuntimeFactory = NULL;
+ m_pJSRuntimeFactory = g_GetJSRuntimeFactory();
+ m_pJSRuntimeFactory->AddRef();
+ m_pEnvList.RemoveAll();
+ m_bInitRuntime = FALSE;
+}
+//IFXJS_Runtime* CPDFXFA_App::GetJSRuntime()
+//{
+// FXSYS_assert(m_pJSRuntimeFactory);
+// if(!m_pJSRuntime)
+// m_pJSRuntime = m_pJSRuntimeFactory->NewJSRuntime(this);
+// return m_pJSRuntime;
+//}
+
+CPDFXFA_App::~CPDFXFA_App()
+{
+ if (m_pFontMgr)
+ {
+ m_pFontMgr->Release();
+ m_pFontMgr = NULL;
+ }
+
+ if (m_pXFAApp)
+ {
+ m_pXFAApp->Release();
+ m_pXFAApp = NULL;
+ }
+
+ //if (m_pJSRuntime && m_pJSRuntimeFactory)
+ // m_pJSRuntimeFactory->DeleteJSRuntime(m_pJSRuntime);
+ m_pJSRuntimeFactory->Release();
+
+
+ if (m_hJSERuntime)
+ {
+ FXJSE_Runtime_Release(m_hJSERuntime);
+ m_hJSERuntime = NULL;
+ }
+
+ FXJSE_Finalize();
+
+ BC_Library_Destory();
+}
+
+FX_BOOL CPDFXFA_App::Initialize()
+{
+ BC_Library_Init();
+
+ FXJSE_Initialize();
+ m_hJSERuntime = FXJSE_Runtime_Create();
+
+ if (!m_hJSERuntime)
+ return FALSE;
+
+ //m_pJSRuntime = m_pJSRuntimeFactory->NewJSRuntime(this);
+
+ m_pXFAApp = IXFA_App::Create(this);
+ if (!m_pXFAApp)
+ return FALSE;
+
+ m_pFontMgr = XFA_GetDefaultFontMgr();
+ if (!m_pFontMgr)
+ return FALSE;
+
+ m_pXFAApp->SetDefaultFontMgr(m_pFontMgr);
+
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_App::AddFormFillEnv(CPDFDoc_Environment* pEnv)
+{
+ if (!pEnv) return FALSE;
+
+ m_pEnvList.Add(pEnv);
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_App::RemoveFormFillEnv(CPDFDoc_Environment* pEnv)
+{
+ if (!pEnv) return FALSE;
+
+ int nFind = m_pEnvList.Find(pEnv);
+ if (nFind != -1) {
+ m_pEnvList.RemoveAt(nFind);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+void CPDFXFA_App::ReleaseRuntime()
+{
+ v8::Persistent<v8::Context> context;
+ JS_ReleaseRuntime((IJS_Runtime*)m_hJSERuntime, context);
+}
+
+void CPDFXFA_App::GetAppType(CFX_WideString &wsAppType)
+{
+ wsAppType = m_csAppType;
+}
+
+void CPDFXFA_App::GetAppName(CFX_WideString& wsName)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ wsName = pEnv->FFI_GetAppName();
+ }
+}
+
+void CPDFXFA_App::SetAppType(FX_WSTR wsAppType)
+{
+ m_csAppType = wsAppType;
+}
+
+void CPDFXFA_App::GetLanguage(CFX_WideString &wsLanguage)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ wsLanguage = pEnv->FFI_GetLanguage();
+ }
+}
+
+void CPDFXFA_App::GetPlatform(CFX_WideString &wsPlatform)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ wsPlatform = pEnv->FFI_GetPlatform();
+ }
+}
+
+void CPDFXFA_App::GetVariation(CFX_WideString &wsVariation)
+{
+ wsVariation = JS_STR_VIEWERVARIATION;
+}
+
+void CPDFXFA_App::GetVersion(CFX_WideString &wsVersion)
+{
+ wsVersion = JS_STR_VIEWERVERSION_XFA;
+}
+
+void CPDFXFA_App::Beep(FX_DWORD dwType)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ pEnv->JS_appBeep(dwType);
+ }
+}
+
+FX_INT32 CPDFXFA_App::MsgBox(FX_WSTR wsMessage, FX_WSTR wsTitle, FX_DWORD dwIconType, FX_DWORD dwButtonType)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (!pEnv)
+ return -1;
+
+ FX_DWORD iconType = 0;
+ int iButtonType = 0;
+ switch (dwIconType)
+ {
+ case XFA_MBICON_Error:
+ iconType |= 0;
+ break;
+ case XFA_MBICON_Warning:
+ iconType |= 1;
+ break;
+ case XFA_MBICON_Question:
+ iconType |= 2;
+ break;
+ case XFA_MBICON_Status:
+ iconType |= 3;
+ break;
+ }
+ switch (dwButtonType)
+ {
+ case XFA_MB_OK:
+ iButtonType |= 0;
+ break;
+ case XFA_MB_OKCancel:
+ iButtonType |= 1;
+ break;
+ case XFA_MB_YesNo:
+ iButtonType |= 2;
+ break;
+ case XFA_MB_YesNoCancel:
+ iButtonType |= 3;
+ break;
+ }
+ FX_INT32 iRet = pEnv->JS_appAlert(wsMessage.GetPtr(), wsTitle.GetPtr(), iButtonType, iconType);
+ switch (iRet)
+ {
+ case 1:
+ return XFA_IDOK;
+ case 2:
+ return XFA_IDCancel;
+ case 3:
+ return XFA_IDNo;
+ case 4:
+ return XFA_IDYes;
+ }
+ return XFA_IDYes;
+}
+
+void CPDFXFA_App::Response(CFX_WideString &wsAnswer, FX_WSTR wsQuestion, FX_WSTR wsTitle, FX_WSTR wsDefaultAnswer, FX_BOOL bMark)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ int nLength = 2048;
+ char* pBuff = new char[nLength];
+ nLength = pEnv->JS_appResponse(wsQuestion.GetPtr(), wsTitle.GetPtr(), wsDefaultAnswer.GetPtr(), NULL, bMark, pBuff, nLength);
+ if(nLength > 0)
+ {
+ nLength = nLength>2046?2046:nLength;
+ pBuff[nLength] = 0;
+ pBuff[nLength+1] = 0;
+ wsAnswer = CFX_WideString::FromUTF16LE((unsigned short*)pBuff, nLength);
+ }
+ delete[] pBuff;
+ }
+}
+
+FX_INT32 CPDFXFA_App::GetCurDocumentInBatch()
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ return pEnv->FFI_GetCurDocument();
+ }
+ return 0;
+}
+
+FX_INT32 CPDFXFA_App::GetDocumentCountInBatch()
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ return pEnv->FFI_GetDocumentCount();
+ }
+
+ return 0;
+}
+
+IFX_FileRead* CPDFXFA_App::DownloadURL(FX_WSTR wsURL)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ return pEnv->FFI_DownloadFromURL(wsURL.GetPtr());
+ }
+ return NULL;
+}
+
+FX_BOOL CPDFXFA_App::PostRequestURL(FX_WSTR wsURL, FX_WSTR wsData, FX_WSTR wsContentType,
+ FX_WSTR wsEncode, FX_WSTR wsHeader, CFX_WideString &wsResponse)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ wsResponse = pEnv->FFI_PostRequestURL(wsURL.GetPtr(), wsData.GetPtr(), wsContentType.GetPtr(), wsEncode.GetPtr(), wsHeader.GetPtr());
+ return TRUE;
+ }
+ return FALSE;
+}
+
+FX_BOOL CPDFXFA_App::PutRequestURL(FX_WSTR wsURL, FX_WSTR wsData, FX_WSTR wsEncode)
+{
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ {
+ return pEnv->FFI_PutRequestURL(wsURL.GetPtr(), wsData.GetPtr(), wsEncode.GetPtr());
+ }
+ return FALSE;
+}
+
+void CPDFXFA_App::LoadString(FX_INT32 iStringID, CFX_WideString &wsString)
+{
+ switch (iStringID)
+ {
+ case XFA_IDS_ValidateFailed:
+ wsString = L"%s validate failed";
+ return;
+ case XFA_IDS_CalcOverride:
+ wsString = L"Calculate Override";
+ return;
+ case XFA_IDS_ModifyField:
+ wsString = L"Are you sure you want to modify this field?";
+ return;
+ case XFA_IDS_NotModifyField:
+ wsString = L"You are not allowed to modify this field.";
+ return;
+ case XFA_IDS_AppName:
+ wsString = L"Foxit";
+ return;
+ case XFA_IDS_ImageFilter:
+ wsString = L"Image Files(*.bmp;*.jpg;*.png;*.gif;*.tif)|*.bmp;*.jpg;*.png;*.gif;*.tif|All Files(*.*)|*.*||";
+ return;
+ case XFA_IDS_UNKNOW_CATCHED:
+ wsString = L"unknown error is catched!";
+ return;
+ case XFA_IDS_Unable_TO_SET:
+ wsString = L"Unable to set ";
+ return;
+ case XFA_IDS_VALUE_EXCALMATORY:
+ wsString = L" value!";
+ return;
+ case XFA_IDS_INVALID_ENUM_VALUE:
+ wsString = L"Invalid enumerated value: ";
+ return;
+ case XFA_IDS_UNSUPPORT_METHOD:
+ wsString = L"unsupport %s method.";
+ return;
+ case XFA_IDS_UNSUPPORT_PROP:
+ wsString = L"unsupport %s property.";
+ return;
+ case XFA_IDS_INVAlID_PROP_SET:
+ wsString = L"Invalid property set operation;";
+ return;
+ case XFA_IDS_NOT_DEFAUL_VALUE:
+ wsString = L" doesn't have a default property";
+ return;
+ case XFA_IDS_UNABLE_SET_LANGUAGE:
+ wsString = L"Unable to set language value!";
+ return;
+ case XFA_IDS_UNABLE_SET_NUMPAGES:
+ wsString = L"Unable to set numPages value!";
+ return;
+ case XFA_IDS_UNABLE_SET_PLATFORM:
+ wsString = L"Unable to set platform value!";
+ return;
+ case XFA_IDS_UNABLE_SET_VALIDATIONENABLE:
+ wsString = L"Unable to set validationsEnabled value!";
+ return;
+ case XFA_IDS_UNABLE_SET_VARIATION:
+ wsString = L"Unable to set variation value!";
+ return;
+ case XFA_IDS_UNABLE_SET_VERSION:
+ wsString = L"Unable to set version value!";
+ return;
+ case XFA_IDS_UNABLE_SET_READY:
+ wsString = L"Unable to set ready value!";
+ return;
+ case XFA_IDS_NUMBER_OF_OCCUR:
+ wsString = L"The element [%s] has violated its allowable number of occurrences";
+ return;
+ case XFA_IDS_UNABLE_SET_CLASS_NAME:
+ wsString = L"Unable to set className value!";
+ return;
+ case XFA_IDS_UNABLE_SET_LENGTH_VALUE:
+ wsString = L"Unable to set length value!";
+ return;
+ case XFA_IDS_UNSUPPORT_CHAR:
+ wsString = L"unsupported char '%c'";
+ return;
+ case XFA_IDS_BAD_SUFFIX:
+ wsString = L"bad suffix on number";
+ return;
+ case XFA_IDS_EXPECTED_IDENT:
+ wsString = L"expected identifier instead of '%s'";
+ return;
+ case XFA_IDS_EXPECTED_STRING:
+ wsString = L"expected '%s' instead of '%s'";
+ return;
+ case XFA_IDS_INVALIDATE_CHAR:
+ wsString = L"invalidate char '%c'";
+ return;
+ case XFA_IDS_REDEFINITION:
+ wsString = L"'%s' redefinition ";
+ return;
+ case XFA_IDS_INVALIDATE_TOKEN:
+ wsString = L"invalidate token '%s'";
+ return;
+ case XFA_IDS_INVALIDATE_EXPRESSION:
+ wsString = L"invalidate expression '%s'";
+ return;
+ case XFA_IDS_UNDEFINE_IDENTIFIER:
+ wsString = L"undefined identifier '%s'";
+ return;
+ case XFA_IDS_INVALIDATE_LEFTVALUE:
+ wsString = L"invalidate left-value '%s'";
+ return;
+ case XFA_IDS_COMPILER_ERROR:
+ wsString = L"compiler error";
+ return;
+ case XFA_IDS_CANNOT_MODIFY_VALUE:
+ wsString = L"can't modify the '%s' value";
+ return;
+ case XFA_IDS_ERROR_PARAMETERS:
+ wsString = L"function '%s' has not %d parameters";
+ return;
+ case XFA_IDS_EXPECT_ENDIF:
+ wsString = L"expected 'endif' instead of '%s'";
+ return;
+ case XFA_IDS_UNEXPECTED_EXPRESSION:
+ wsString = L"unexpected expression '%s'";
+ return;
+ case XFA_IDS_CONDITION_IS_NULL:
+ wsString = L"condition is null";
+ return;
+ case XFA_IDS_ILLEGALBREAK:
+ wsString = L"illegal break";
+ return;
+ case XFA_IDS_ILLEGALCONTINUE:
+ wsString = L"illegal continue";
+ return;
+ case XFA_IDS_EXPECTED_OPERATOR:
+ wsString = L"expected operator '%s' instead of '%s'";
+ return;
+ case XFA_IDS_DIVIDE_ZERO:
+ wsString = L"divide by zero";
+ return;
+ case XFA_IDS_CANNOT_COVERT_OBJECT:
+ wsString = L"%s.%s can not covert to object";
+ return;
+ case XFA_IDS_NOT_FOUND_CONTAINER:
+ wsString = L"can not found container '%s'";
+ return;
+ case XFA_IDS_NOT_FOUND_PROPERTY:
+ wsString = L"can not found property '%s'";
+ return;
+ case XFA_IDS_NOT_FOUND_METHOD:
+ wsString = L"can not found method '%s'";
+ return;
+ case XFA_IDS_NOT_FOUND_CONST:
+ wsString = L"can not found const '%s'";
+ return;
+ case XFA_IDS_NOT_ASSIGN_OBJECT:
+ wsString = L"can not direct assign value to object";
+ return;
+ case XFA_IDS_IVALIDATE_INSTRUCTION:
+ wsString = L"invalidate instruction";
+ return;
+ case XFA_IDS_EXPECT_NUMBER:
+ wsString = L"expected number instead of '%s'";
+ return;
+ case XFA_IDS_VALIDATE_OUT_ARRAY:
+ wsString = L"validate access index '%s' out of array";
+ return;
+ case XFA_IDS_CANNOT_ASSIGN_IDENT:
+ wsString = L"can not assign to %s";
+ return;
+ case XFA_IDS_NOT_FOUNT_FUNCTION:
+ wsString = L"can not found '%s' function";
+ return;
+ case XFA_IDS_NOT_ARRAY:
+ wsString = L"'%s' doesn't an array";
+ return;
+ case XFA_IDS_OUT_ARRAY:
+ wsString = L"out of range of '%s' array";
+ return;
+ case XFA_IDS_NOT_SUPPORT_CALC:
+ wsString = L"'%s' operator can not support array calculate";
+ return;
+ case XFA_IDS_ARGUMENT_NOT_ARRAY:
+ wsString = L"'%s' function's %d argument can not be array";
+ return;
+ case XFA_IDS_ARGUMENT_EXPECT_CONTAINER:
+ wsString = L"'%s' argument expected a container";
+ return;
+ case XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT:
+ wsString = L"an attempt was made to reference property '%s' of a non-object in SOM expression %s";
+ return;
+ case XFA_IDS_FUNCTION_IS_BUILDIN:
+ wsString = L"function '%s' is buildin";
+ return;
+ case XFA_IDS_ERROR_MSG:
+ wsString = L"%s : %s";
+ return;
+ case XFA_IDS_INDEX_OUT_OF_BOUNDS:
+ wsString = L"Index value is out of bounds";
+ return;
+ case XFA_IDS_INCORRECT_NUMBER_OF_METHOD:
+ wsString = L"Incorrect number of parameters calling method '%s'";
+ return;
+ case XFA_IDS_ARGUMENT_MISMATCH:
+ wsString = L"Argument mismatch in property or function argument";
+ return;
+ case XFA_IDS_INVALID_ENUMERATE:
+ wsString = L"Invalid enumerated value: %s";
+ return;
+ case XFA_IDS_INVALID_APPEND:
+ wsString = L"Invalid append operation: %s cannot have a child element of %s";
+ return;
+ case XFA_IDS_SOM_EXPECTED_LIST:
+ wsString = L"SOM expression returned list when single result was expected";
+ return;
+ case XFA_IDS_NOT_HAVE_PROPERTY:
+ wsString = L"'%s' doesn't have property '%s'";
+ return;
+ case XFA_IDS_INVALID_NODE_TYPE:
+ wsString = L"Invalid node type : '%s'";
+ return;
+ case XFA_IDS_VIOLATE_BOUNDARY:
+ wsString = L"The element [%s] has violated its allowable number of occurrences";
+ return;
+ case XFA_IDS_SERVER_DENY:
+ wsString = L"Server does not permit";
+ return;
+ /*case XFA_IDS_StringWeekDay_Sun:
+ wsString = L"?¨¹¨¨?";
+ return;
+ case XFA_IDS_StringWeekDay_Mon:
+ wsString = L"?¨¹¨°?";
+ return;
+ case XFA_IDS_StringWeekDay_Tue:
+ wsString = L"?¨¹?t";
+ return;
+ case XFA_IDS_StringWeekDay_Wed:
+ wsString = L"?¨¹¨¨y";
+ return;
+ case XFA_IDS_StringWeekDay_Thu:
+ wsString = L"?¨¹??";
+ return;
+ case XFA_IDS_StringWeekDay_Fri:
+ wsString = L"?¨¹??";
+ return;
+ case XFA_IDS_StringWeekDay_Sat:
+ wsString = L"?¨¹¨¢¨´";
+ return;
+ case XFA_IDS_StringMonth_Jan:
+ wsString = L"1??";
+ return;
+ case XFA_IDS_StringMonth_Feb:
+ wsString = L"2??";
+ return;
+ case XFA_IDS_StringMonth_March:
+ wsString = L"3??";
+ return;
+ case XFA_IDS_StringMonth_April:
+ wsString = L"4??";
+ return;
+ case XFA_IDS_StringMonth_May:
+ wsString = L"5??";
+ return;
+ case XFA_IDS_StringMonth_June:
+ wsString = L"6??";
+ return;
+ case XFA_IDS_StringMonth_July:
+ wsString = L"7??";
+ return;
+ case XFA_IDS_StringMonth_Aug:
+ wsString = L"8??";
+ return;
+ case XFA_IDS_StringMonth_Sept:
+ wsString = L"9??";
+ return;
+ case XFA_IDS_StringMonth_Oct:
+ wsString = L"10??";
+ return;
+ case XFA_IDS_StringMonth_Nov:
+ wsString = L"11??";
+ return;
+ case XFA_IDS_StringMonth_Dec:
+ wsString = L"12??";
+ return;
+ case XFA_IDS_String_Today:
+ wsString = L"??¨¬¨¬";
+ return;*/
+ case XFA_IDS_ValidateLimit:
+ wsString = FX_WSTRC(L"Message limit exceeded. Remaining %d validation errors not reported.");
+ return;
+ case XFA_IDS_ValidateNullWarning:
+ wsString = FX_WSTRC(L"%s cannot be left blank. To ignore validations for %s, click Ignore.");
+ return;
+ case XFA_IDS_ValidateNullError:
+ wsString = FX_WSTRC(L"%s cannot be left blank.");
+ return;
+ case XFA_IDS_ValidateWarning:
+ wsString = FX_WSTRC(L"The value you entered for %s is invalid. To ignore validations for %s, click Ignore.");
+ return;
+ case XFA_IDS_ValidateError:
+ wsString = FX_WSTRC(L"The value you entered for %s is invalid.");
+ return;
+ }
+
+}
+
+FX_BOOL CPDFXFA_App::ShowFileDialog(FX_WSTR wsTitle, FX_WSTR wsFilter, CFX_WideStringArray &wsPathArr, FX_BOOL bOpen)
+{
+ //if (m_pEnv)
+ //{
+ // return m_pEnv->FFI_ShowFileDialog(wsTitle.GetPtr(), wsFilter.GetPtr(), wsPathArr, bOpen);
+ //}
+ return FALSE;
+}
+
+IFWL_AdapterTimerMgr* CPDFXFA_App::GetTimerMgr()
+{
+ CXFA_FWLAdapterTimerMgr* pAdapter = NULL;
+ CPDFDoc_Environment* pEnv = m_pEnvList.GetAt(0);
+ if (pEnv)
+ pAdapter = FX_NEW CXFA_FWLAdapterTimerMgr(pEnv);
+ return pAdapter;
+}
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp
new file mode 100644
index 0000000000..b416da0abc
--- /dev/null
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp
@@ -0,0 +1,1476 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../include/fsdk_define.h"
+#include "../../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../../include/fpdfformfill.h"
+#include "../../include/fsdk_mgr.h"
+#include "../../include/fpdfxfa/fpdfxfa_app.h"
+#include "../../include/fpdfxfa/fpdfxfa_util.h"
+#include "../../include/fpdfxfa/fpdfxfa_page.h"
+#include "../../include/javascript/IJavaScript.h"
+
+
+
+#define IDS_XFA_StringMonth_April "April"
+#define IDS_XFA_StringMonth_May "May"
+#define IDS_XFA_StringMonth_June "June"
+#define IDS_XFA_StringMonth_July "July"
+#define IDS_XFA_StringMonth_Aug "August"
+#define IDS_XFA_StringMonth_Sept "September"
+#define IDS_XFA_StringMonth_Oct "October"
+#define IDS_XFA_StringMonth_Nov "November"
+#define IDS_XFA_StringMonth_Dec "December"
+#define IDS_XFA_String_Today "Today"
+#define IDS_XFA_ValidateLimit "Message limit exceeded. Remaining %d validation errors not reported."
+#define IDS_XFA_Validate_Input "At least one required field was empty. Please fill in the required fields\r\n(highlighted) before continuing."
+
+// submit
+#define FXFA_CONFIG 0x00000001
+#define FXFA_TEMPLATE 0x00000010
+#define FXFA_LOCALESET 0x00000100
+#define FXFA_DATASETS 0x00001000
+#define FXFA_XMPMETA 0x00010000
+#define FXFA_XFDF 0x00100000
+#define FXFA_FORM 0x01000000
+#define FXFA_PDF 0x10000000
+
+#ifndef _WIN32
+extern void SetLastError(int err);
+
+extern int GetLastError();
+#endif
+
+CPDFXFA_Document::CPDFXFA_Document(CPDF_Document* pPDFDoc, CPDFXFA_App* pProvider) :
+ m_pPDFDoc(pPDFDoc),
+ m_pApp(pProvider),
+ m_pXFADoc(NULL),
+ m_pXFADocView(NULL),
+ m_iDocType(DOCTYPE_PDF),
+ m_pJSContext(NULL),
+ m_pSDKDoc(NULL)
+{
+ m_XFAPageList.RemoveAll();
+}
+
+CPDFXFA_Document::~CPDFXFA_Document()
+{
+ if (m_pPDFDoc)
+ {
+ CPDF_Parser* pParser = (CPDF_Parser*)m_pPDFDoc->GetParser();
+ if (pParser == NULL)
+ {
+ delete m_pPDFDoc;
+ }else
+ {
+ delete pParser;
+ }
+ m_pPDFDoc = NULL;
+ }
+ if (m_pXFADoc)
+ {
+ IXFA_App* pApp = m_pApp->GetXFAApp();
+ if (pApp)
+ {
+ IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();
+ if (pDocHandler)
+ {
+ pDocHandler->CloseDoc(m_pXFADoc);
+ pDocHandler->ReleaseDoc(m_pXFADoc);
+ m_pXFADoc = NULL;
+ }
+ }
+ }
+
+ if (m_pJSContext)
+ {
+ if (m_pSDKDoc && m_pSDKDoc->GetEnv())
+ {
+ m_pSDKDoc->GetEnv()->GetJSRuntime()->ReleaseContext(m_pJSContext);
+ m_pJSContext = NULL;
+ }
+ }
+
+
+ if (m_pSDKDoc)
+ delete m_pSDKDoc;
+ m_pSDKDoc = NULL;
+}
+
+FX_BOOL CPDFXFA_Document::LoadXFADoc()
+{
+ if (!m_pPDFDoc)
+ return FALSE;
+
+ m_XFAPageList.RemoveAll();
+
+ int iDocType = DOCTYPE_PDF;
+ FX_BOOL hasXFAField = FPDF_HasXFAField(m_pPDFDoc, iDocType);
+
+ if (hasXFAField)
+ {
+ IXFA_App* pApp = m_pApp->GetXFAApp();
+ if (pApp)
+ {
+ m_pXFADoc = pApp->CreateDoc(this, m_pPDFDoc);
+ if (!m_pXFADoc)
+ {
+ SetLastError(FPDF_ERR_XFALOAD);
+ return FALSE;
+ }
+
+ IXFA_DocHandler* pDocHandler = pApp->GetDocHandler();
+ if (pDocHandler)
+ {
+ int iStatus = pDocHandler->StartLoad(m_pXFADoc);
+ iStatus = pDocHandler->DoLoad(m_pXFADoc, NULL);
+ if (iStatus != 100)
+ {
+ pDocHandler->CloseDoc(m_pXFADoc);
+ pDocHandler->ReleaseDoc(m_pXFADoc);
+ m_pXFADoc = NULL;
+
+ SetLastError(FPDF_ERR_XFALOAD);
+ return FALSE;
+ }
+ pDocHandler->StopLoad(m_pXFADoc);
+ pDocHandler->SetJSERuntime(m_pXFADoc, m_pApp->GetJSERuntime());
+
+ if (pDocHandler->GetDocType(m_pXFADoc) == XFA_DOCTYPE_Dynamic)
+ m_iDocType = DOCTYPE_DYNIMIC_XFA;
+ else
+ m_iDocType = DOCTYPE_STATIC_XFA;
+
+ m_pXFADocView = pDocHandler->CreateDocView(m_pXFADoc, XFA_DOCVIEW_View);
+ FXSYS_assert(m_pXFADocView);
+
+ if (m_pXFADocView->StartLayout() < 0)
+ {
+ pDocHandler->CloseDoc(m_pXFADoc);
+ pDocHandler->ReleaseDoc(m_pXFADoc);
+ m_pXFADoc = NULL;
+
+ SetLastError(FPDF_ERR_XFALAYOUT);
+ return FALSE;
+ }
+ else
+ {
+ m_pXFADocView->DoLayout(NULL);
+ m_pXFADocView->StopLayout();
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int CPDFXFA_Document::GetPageCount()
+{
+ if (!m_pPDFDoc && !m_pXFADoc)
+ return 0;
+
+ switch (m_iDocType)
+ {
+ case DOCTYPE_PDF:
+ case DOCTYPE_STATIC_XFA:
+ if (m_pPDFDoc)
+ return m_pPDFDoc->GetPageCount();
+ case DOCTYPE_DYNIMIC_XFA:
+ if (m_pXFADoc)
+ return m_pXFADocView->CountPageViews();
+ default:
+ return 0;
+ }
+
+ return 0;
+}
+
+CPDFXFA_Page* CPDFXFA_Document::GetPage(int page_index)
+{
+ if (!m_pPDFDoc && !m_pXFADoc)
+ return NULL;
+
+ CPDFXFA_Page* pPage = NULL;
+ if (m_XFAPageList.GetSize())
+ {
+ pPage = m_XFAPageList.GetAt(page_index);
+ if (pPage)
+ pPage->AddRef();
+ }
+ else
+ {
+ m_XFAPageList.SetSize(GetPageCount());
+ }
+
+ if (!pPage)
+ {
+ pPage = FX_NEW CPDFXFA_Page(this, page_index);
+ FX_BOOL bRet = pPage->LoadPage();
+ if (!bRet) {
+ delete pPage;
+ return NULL;
+ }
+
+ m_XFAPageList.SetAt(page_index, pPage);
+ }
+
+ return pPage;
+}
+
+CPDFXFA_Page* CPDFXFA_Document::GetPage(IXFA_PageView* pPage)
+{
+ if (!pPage)
+ return NULL;
+
+ if (!m_pXFADoc)
+ return NULL;
+
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return NULL;
+
+ int nSize = m_XFAPageList.GetSize();
+ for (int i=0; i<nSize; i++)
+ {
+ CPDFXFA_Page* pTempPage = m_XFAPageList.GetAt(i);
+ if (!pTempPage) continue;
+ if (pTempPage->GetXFAPageView() && pTempPage->GetXFAPageView() == pPage)
+ return pTempPage;
+ }
+
+ return NULL;
+}
+
+void CPDFXFA_Document::RemovePage(CPDFXFA_Page* page)
+{
+ m_XFAPageList.SetAt(page->GetPageIndex(), NULL);
+}
+
+CPDFSDK_Document* CPDFXFA_Document::GetSDKDocument(CPDFDoc_Environment* pFormFillEnv)
+{
+ if (!pFormFillEnv)
+ return m_pSDKDoc;
+
+ if (m_pSDKDoc)
+ return m_pSDKDoc;
+
+ m_pSDKDoc = new CPDFSDK_Document(this, pFormFillEnv);
+ if (!m_pSDKDoc)
+ return NULL;
+
+ return m_pSDKDoc;
+}
+
+void CPDFXFA_Document::ReleaseSDKDoc()
+{
+ if (m_pSDKDoc)
+ delete m_pSDKDoc;
+
+ m_pSDKDoc = NULL;
+}
+
+void CPDFXFA_Document::FXRect2PDFRect(const CFX_RectF& fxRectF, CPDF_Rect& pdfRect)
+{
+ pdfRect.left = fxRectF.left;
+ pdfRect.top = fxRectF.bottom();
+ pdfRect.right = fxRectF.right();
+ pdfRect.bottom = fxRectF.top;
+}
+
+//////////////////////////////////////////////////////////////////////////
+void CPDFXFA_Document::SetChangeMark(XFA_HDOC hDoc)
+{
+ if (hDoc == m_pXFADoc && m_pSDKDoc)
+ {
+ m_pSDKDoc->SetChangeMark();
+ }
+}
+
+FX_BOOL CPDFXFA_Document::GetChangeMark(XFA_HDOC hDoc)
+{
+ if (hDoc == m_pXFADoc && m_pSDKDoc)
+ return m_pSDKDoc->GetChangeMark();
+ return FALSE;
+}
+
+void CPDFXFA_Document::InvalidateRect(IXFA_PageView* pPageView, const CFX_RectF& rt, FX_DWORD dwFlags /* = 0 */)
+{
+ if (!m_pXFADoc || !m_pSDKDoc)
+ return;
+
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return;
+
+ CPDF_Rect rcPage;
+ FXRect2PDFRect(rt, rcPage);
+
+ CPDFXFA_Page* pPage = GetPage(pPageView);
+
+ if (pPage == NULL)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (!pEnv)
+ return;
+
+ pEnv->FFI_Invalidate((FPDF_PAGE)pPage, rcPage.left, rcPage.bottom, rcPage.right, rcPage.top);
+}
+
+void CPDFXFA_Document::InvalidateRect(XFA_HWIDGET hWidget, FX_DWORD dwFlags /* = 0 */)
+{
+ if (!hWidget)
+ return;
+
+ if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)
+ return;
+
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return;
+
+ IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+ if (!pWidgetHandler)
+ return;
+
+ IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);
+ if (!pPageView)
+ return;
+
+ CFX_RectF rect;
+ pWidgetHandler->GetRect(hWidget, rect);
+ InvalidateRect(pPageView, rect, dwFlags);
+}
+
+void CPDFXFA_Document::DisplayCaret(XFA_HWIDGET hWidget, FX_BOOL bVisible, const CFX_RectF* pRtAnchor)
+{
+ if (!hWidget || pRtAnchor == NULL)
+ return;
+
+ if (!m_pXFADoc || !m_pSDKDoc || !m_pXFADocView)
+ return;
+
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return;
+
+ IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+ if (!pWidgetHandler)
+ return;
+
+ IXFA_PageView* pPageView = pWidgetHandler->GetPageView(hWidget);
+ if (!pPageView)
+ return;
+
+ CPDFXFA_Page* pPage = GetPage(pPageView);
+
+ if (pPage == NULL)
+ return;
+
+ CPDF_Rect rcCaret;
+ FXRect2PDFRect(*pRtAnchor, rcCaret);
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (!pEnv)
+ return;
+
+ pEnv->FFI_DisplayCaret((FPDF_PAGE)pPage, bVisible, rcCaret.left, rcCaret.top, rcCaret.right, rcCaret.bottom);
+
+}
+
+FX_BOOL CPDFXFA_Document::GetPopupPos(XFA_HWIDGET hWidget, FX_FLOAT fMinPopup, FX_FLOAT fMaxPopup, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ if (NULL == hWidget)
+ {
+ return FALSE;
+ }
+ IXFA_PageView* pXFAPageView = m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);
+ if (NULL == pXFAPageView)
+ {
+ return FALSE;
+ }
+ CPDFXFA_Page* pPage = GetPage(pXFAPageView);
+ if (pPage == NULL)
+ return FALSE;
+
+ CXFA_WidgetAcc* pWidgetAcc = m_pXFADocView->GetWidgetHandler()->GetDataAcc(hWidget);
+
+ int nRotate = pWidgetAcc->GetRotate();
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return FALSE;
+ FS_RECTF pageViewRect;
+ pEnv->FFI_GetPageViewRect(pPage, pageViewRect);
+
+ CPDF_Rect rcAnchor;
+
+ rcAnchor.left = rtAnchor.left;
+ rcAnchor.top = rtAnchor.bottom();
+ rcAnchor.right = rtAnchor.right();
+ rcAnchor.bottom = rtAnchor.top;
+
+ int t1,t2,t;
+ FX_DWORD dwPos; FX_FLOAT fPoupHeight;
+ switch(nRotate)
+ {
+
+ case 90:
+ {
+ t1 = (int)(pageViewRect.right - rcAnchor.right);
+ t2 = (int)(rcAnchor.left - pageViewRect.left);
+ if (rcAnchor.bottom < pageViewRect.bottom)
+ {
+ rtPopup.left += rcAnchor.bottom - pageViewRect.bottom;
+ }
+
+ break;
+ }
+
+ case 180:
+ {
+ t2 = (int)(pageViewRect.top - rcAnchor.top);
+ t1 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+ if (rcAnchor.left < pageViewRect.left)
+ {
+ rtPopup.left += rcAnchor.left - pageViewRect.left;
+ }
+ break;
+ }
+ case 270:
+ {
+ t1 = (int)(rcAnchor.left - pageViewRect.left);
+ t2 = (int)(pageViewRect.right - rcAnchor.right);
+
+ if (rcAnchor.top > pageViewRect.top)
+ {
+ rtPopup.left -= rcAnchor.top - pageViewRect.top;
+ }
+ break;
+ }
+ case 0:
+ default:
+ {
+ t1 = (int)(pageViewRect.top - rcAnchor.top);
+ t2 = (int)(rcAnchor.bottom - pageViewRect.bottom);
+ if (rcAnchor.right > pageViewRect.right)
+ {
+ rtPopup.left -= rcAnchor.right - pageViewRect.right;
+ }
+ break;
+ }
+
+ }
+
+ if (t1 <= 0 && t2 <= 0)
+ {
+ return FALSE;
+ }
+ if (t1 <= 0)
+ {
+ t = t2;
+ dwPos = 1;
+ }
+ else if(t2 <= 0)
+ {
+ t = t1;
+ dwPos = 0;
+ }
+ else if (t1 > t2 )
+ {
+ t = t1;
+ dwPos = 0;
+ }
+ else
+ {
+ t = t2;
+ dwPos = 1;
+ }
+ if (t<fMinPopup)
+ {
+ fPoupHeight = fMinPopup;
+ }
+ else if (t > fMaxPopup)
+ {
+ fPoupHeight = fMaxPopup;
+ }
+ else
+ {
+ fPoupHeight = (FX_FLOAT)t;
+ }
+
+ switch(nRotate)
+ {
+
+ case 0:
+ case 180:
+ {
+ if (dwPos == 0)
+ {
+ rtPopup.top = rtAnchor.height;
+ rtPopup.height = fPoupHeight;
+ }
+ else
+ {
+ rtPopup.top = - fPoupHeight;
+ rtPopup.height = fPoupHeight;
+ }
+ break;
+ }
+ case 90:
+ case 270:
+ {
+ if (dwPos == 0)
+ {
+ rtPopup.top = rtAnchor.width;
+ rtPopup.height = fPoupHeight;
+ }
+ else
+ {
+ rtPopup.top = - fPoupHeight;
+ rtPopup.height = fPoupHeight;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_Document::PopupMenu(XFA_HWIDGET hWidget, CFX_PointF ptPopup, const CFX_RectF* pRectExclude)
+{
+ if (NULL == hWidget)
+ {
+ return FALSE;
+ }
+ IXFA_PageView* pXFAPageView = m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);
+ if (pXFAPageView == NULL)
+ return FALSE;
+ CPDFXFA_Page* pPage = GetPage(pXFAPageView);
+
+ if (pPage == NULL)
+ return FALSE;
+
+ int menuFlag = 0;
+
+ IXFA_MenuHandler* pXFAMenuHander = m_pApp->GetXFAApp()->GetMenuHandler();
+ if (pXFAMenuHander->CanUndo(hWidget))
+ menuFlag |= FXFA_MEMU_UNDO;
+ if (pXFAMenuHander->CanRedo(hWidget))
+ menuFlag |= FXFA_MEMU_REDO;
+ if (pXFAMenuHander->CanPaste(hWidget))
+ menuFlag |= FXFA_MEMU_PASTE;
+ if (pXFAMenuHander->CanCopy(hWidget))
+ menuFlag |= FXFA_MEMU_COPY;
+ if (pXFAMenuHander->CanCut(hWidget))
+ menuFlag |= FXFA_MEMU_CUT;
+ if (pXFAMenuHander->CanSelectAll(hWidget))
+ menuFlag |= FXFA_MEMU_SELECTALL;
+
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return FALSE;
+
+ return pEnv->FFI_PopupMenu(pPage, hWidget, menuFlag, ptPopup, NULL);
+}
+
+void CPDFXFA_Document::PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags)
+{
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+
+ CPDFXFA_Page* pPage = GetPage(pPageView);
+ if (pPage == NULL)
+ return;
+
+ if (dwFlags == FXFA_PAGEVIEWEVENT_POSTADDED)
+ {
+ //pEnv->FFI_PageEvent(pPage, FXFA_PAGEVIEWEVENT_POSTADDED);
+ }
+ else if (dwFlags == FXFA_PAGEVIEWEVENT_POSTREMOVED)
+ {
+ //pEnv->FFI_PageEvent(pPage, FXFA_PAGEVIEWEVENT_POSTREMOVED);
+ //RemovePage(pPage);
+ //delete pPage;
+ }
+}
+
+void CPDFXFA_Document::WidgetEvent(XFA_HWIDGET hWidget, CXFA_WidgetAcc* pWidgetData, FX_DWORD dwEvent, FX_LPVOID pParam, FX_LPVOID pAdditional)
+{
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA || NULL == hWidget)
+ return;
+
+ int pageViewCount = m_pSDKDoc->GetPageViewCount();
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+
+ if (NULL == hWidget) return;
+
+ IXFA_PageView* pPageView = m_pXFADocView->GetWidgetHandler()->GetPageView(hWidget);
+
+ if (pPageView == NULL)
+ return;
+ CPDFXFA_Page* pXFAPage = GetPage(pPageView);
+ if (pXFAPage == NULL)
+ return;
+
+ CPDFSDK_PageView* pSdkPageView = m_pSDKDoc->GetPageView(pXFAPage);
+
+ CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
+
+
+ if (dwEvent == XFA_WIDGETEVENT_PostAdded)
+ {
+// CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(hWidget, pSdkPageView);
+// pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
+
+ //pEnv->FFI_WidgetEvent(hWidget, XFA_WIDGETEVENT_PostAdded);
+// IXFA_PageView* pOldPageView = (IXFA_PageView*)pAdditional;
+// if (pOldPageView)
+// {
+// CPDFXFA_Page* pDestPage = m_pSDKDoc->GetPageView((IXFA_PageView*)pOldPageView);
+// ASSERT(pDestPage);
+// CPDFSDK_Annot* pAnnot = pDestPage->GetAnnotByXFAWidget(hWidget);
+// if (pAnnot)
+// {
+// if (m_pSDKDoc->GetFocusAnnot() == pAnnot)
+// {
+// m_pSDKDoc->SetFocusAnnot(NULL);
+// }
+// pDestPage->DeleteAnnot(pAnnot);
+// }
+// }
+ pSdkPageView->AddAnnot(hWidget);
+
+ }
+ else if (dwEvent == XFA_WIDGETEVENT_PreRemoved)
+ {
+ CPDFSDK_Annot* pAnnot = pSdkPageView->GetAnnotByXFAWidget(hWidget);
+ if (pAnnot) {
+ pSdkPageView->DeleteAnnot(pAnnot);
+ //pEnv->FFI_WidgetEvent(hWidget, XFA_WIDGETEVENT_PreRemoved);
+ }
+ }
+}
+
+FX_INT32 CPDFXFA_Document::CountPages(XFA_HDOC hDoc)
+{
+ if (hDoc == m_pXFADoc && m_pSDKDoc)
+ {
+ return GetPageCount();
+ }
+ return 0;
+}
+FX_INT32 CPDFXFA_Document::GetCurrentPage(XFA_HDOC hDoc)
+{
+ if (hDoc != m_pXFADoc || !m_pSDKDoc)
+ return -1;
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return -1;
+
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return -1;
+
+ return pEnv->FFI_GetCurrentPageIndex(this);
+}
+void CPDFXFA_Document::SetCurrentPage(XFA_HDOC hDoc, FX_INT32 iCurPage)
+{
+ if (hDoc != m_pXFADoc || !m_pSDKDoc)
+ return;
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+
+ pEnv->FFI_SetCurrentPage(this, iCurPage);
+}
+FX_BOOL CPDFXFA_Document::IsCalculationsEnabled(XFA_HDOC hDoc)
+{
+ if (hDoc != m_pXFADoc || !m_pSDKDoc)
+ return FALSE;
+ if (m_pSDKDoc->GetInterForm())
+ return m_pSDKDoc->GetInterForm()->IsXfaCalculateEnabled();
+
+ return FALSE;
+
+}
+void CPDFXFA_Document::SetCalculationsEnabled(XFA_HDOC hDoc, FX_BOOL bEnabled)
+{
+ if (hDoc != m_pXFADoc || !m_pSDKDoc)
+ return;
+ if (m_pSDKDoc->GetInterForm())
+ m_pSDKDoc->GetInterForm()->XfaEnableCalculate(bEnabled);
+}
+
+void CPDFXFA_Document::GetTitle(XFA_HDOC hDoc, CFX_WideString &wsTitle)
+{
+ if (hDoc != m_pXFADoc)
+ return;
+ if (m_pPDFDoc == NULL)
+ return;
+ CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();
+
+ if (pInfoDict == NULL)
+ return;
+
+ CFX_ByteString csTitle = pInfoDict->GetString("Title");
+ wsTitle = wsTitle.FromLocal(csTitle.GetBuffer(csTitle.GetLength()));
+ csTitle.ReleaseBuffer(csTitle.GetLength());
+}
+void CPDFXFA_Document::SetTitle(XFA_HDOC hDoc, FX_WSTR wsTitle)
+{
+ if (hDoc != m_pXFADoc)
+ return;
+ if (m_pPDFDoc == NULL)
+ return;
+ CPDF_Dictionary* pInfoDict = m_pPDFDoc->GetInfo();
+
+ if (pInfoDict == NULL)
+ return;
+ pInfoDict->SetAt("Title", FX_NEW CPDF_String(wsTitle));
+}
+void CPDFXFA_Document::ExportData(XFA_HDOC hDoc, FX_WSTR wsFilePath, FX_BOOL bXDP)
+{
+ if (hDoc != m_pXFADoc)
+ return;
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)
+ return;
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+ int fileType = bXDP?FXFA_SAVEAS_XDP:FXFA_SAVEAS_XML;
+ CFX_ByteString bs = CFX_WideString(wsFilePath).UTF16LE_Encode();
+
+ if (wsFilePath.IsEmpty()) {
+ if (!pEnv->GetFormFillInfo() || pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)
+ return;
+ CFX_WideString filepath = pEnv->JS_fieldBrowse();
+ bs = filepath.UTF16LE_Encode();
+ }
+ int len = bs.GetLength()/sizeof(unsigned short);
+ FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(bXDP?FXFA_SAVEAS_XDP:FXFA_SAVEAS_XML, (FPDF_WIDESTRING)bs.GetBuffer(len*sizeof(unsigned short)), "wb");
+ bs.ReleaseBuffer(len*sizeof(unsigned short));
+
+ if (pFileHandler == NULL)
+ return;
+
+ CFPDF_FileStream fileWrite(pFileHandler);
+
+ IXFA_DocHandler *pXFADocHander = m_pApp->GetXFAApp()->GetDocHandler();
+ CFX_ByteString content;
+ if (fileType == FXFA_SAVEAS_XML)
+ {
+ content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+ fileWrite.WriteBlock((FX_LPCSTR)content, fileWrite.GetSize(), content.GetLength());
+ CFX_WideStringC data(L"data");
+ if( pXFADocHander->SavePackage(m_pXFADocView->GetDoc(),data, &fileWrite))
+ {
+ NULL;
+ }
+ }
+ /*else if (fileType == FXFA_FILE_STATIC_XDP)
+ {
+ content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+ fileWrite.WriteBlock((FX_LPCSTR)content, fileWrite.GetSize(), content.GetLength());
+ CFX_WideStringC data(L"data");
+ if( pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), data, &fileWrite))
+ {
+ NULL;
+ }
+ CFX_WideString wPath = pEnv->FFI_GetFilePath(pFileHandler);
+// CFX_WideString wPath;
+// wPath.FromUTF16LE(filePath);
+ CFX_ByteString bPath = wPath.UTF8Encode();
+ CFX_ByteString szFormat = "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
+ content.Format(szFormat,(char*)(FX_LPCSTR)bPath);
+ fileWrite.WriteBlock((FX_LPCSTR)content,fileWrite.GetSize(), content.GetLength());
+ }
+ */
+ else if (fileType == FXFA_SAVEAS_XDP)
+ {
+ if (m_pPDFDoc == NULL)
+ return;
+ CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();
+ if (pRoot == NULL)
+ return;
+ CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
+ if (NULL == pAcroForm)
+ return;
+ CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
+ if (pXFA == NULL)
+ return;
+ if (pXFA->GetType() != PDFOBJ_ARRAY)
+ return;
+ CPDF_Array* pArray = pXFA->GetArray();
+ if (NULL == pArray)
+ return;
+ int size = pArray->GetCount();
+ int iFormIndex = -1;
+ int iDataSetsIndex = -1;
+ for (int i=1; i<size;i+=2)
+ {
+ CPDF_Object* pPDFObj = pArray->GetElement(i);
+ CPDF_Object* pPrePDFObj = pArray->GetElement(i-1);
+ if(pPrePDFObj->GetType() != PDFOBJ_STRING)
+ continue;
+ if (pPDFObj->GetType() != PDFOBJ_REFERENCE)
+ continue;
+ CPDF_Object* pDirectObj = pPDFObj->GetDirect();
+ if(pDirectObj->GetType() != PDFOBJ_STREAM)
+ continue;
+ if (pPrePDFObj->GetString()=="form")
+ {
+ CFX_WideStringC form(L"form");
+ pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), form, &fileWrite);
+ }
+ else if (pPrePDFObj->GetString()=="datasets")
+ {
+ CFX_WideStringC datasets(L"datasets");
+ pXFADocHander->SavePackage(m_pXFADocView->GetDoc(), datasets, &fileWrite);
+ }
+ else
+ {
+ if (i == size-1)
+ {
+ //CFX_WideString wPath = pEnv->FFI_GetFilePath(pFileHandler);
+ CFX_WideString wPath = CFX_WideString::FromUTF16LE((unsigned short*)(FX_LPCSTR)bs, bs.GetLength()/sizeof(unsigned short));
+ CFX_ByteString bPath = wPath.UTF8Encode();
+ CFX_ByteString szFormat = "\n<pdf href=\"%s\" xmlns=\"http://ns.adobe.com/xdp/pdf/\"/>";
+ content.Format(szFormat,(char*)(FX_LPCSTR)bPath);
+ fileWrite.WriteBlock((FX_LPCSTR)content,fileWrite.GetSize(), content.GetLength());
+ }
+
+ CPDF_Stream* pStream = (CPDF_Stream*)pDirectObj;
+ CPDF_StreamAcc* pAcc = FX_NEW CPDF_StreamAcc;
+ pAcc->LoadAllData(pStream);
+ fileWrite.WriteBlock(pAcc->GetData(), fileWrite.GetSize(), pAcc->GetSize());
+ delete pAcc;
+ }
+ }
+ }
+ FX_BOOL bError= fileWrite.Flush();
+}
+void CPDFXFA_Document::ImportData(XFA_HDOC hDoc, FX_WSTR wsFilePath)
+{
+ //TODO...
+}
+
+void CPDFXFA_Document::GotoURL(XFA_HDOC hDoc, FX_WSTR bsURL, FX_BOOL bAppend)
+{
+ if (hDoc != m_pXFADoc)
+ return;
+
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+
+ CFX_WideStringC str(bsURL.GetPtr());
+
+ pEnv->FFI_GotoURL(this, str, bAppend);
+
+}
+
+FX_BOOL CPDFXFA_Document::IsValidationsEnabled(XFA_HDOC hDoc)
+{
+ if (hDoc != m_pXFADoc || !m_pSDKDoc)
+ return FALSE;
+ if (m_pSDKDoc->GetInterForm())
+ return m_pSDKDoc->GetInterForm()->IsXfaValidationsEnabled();
+
+ return TRUE;
+}
+void CPDFXFA_Document::SetValidationsEnabled(XFA_HDOC hDoc, FX_BOOL bEnabled)
+{
+ if (hDoc != m_pXFADoc || !m_pSDKDoc)
+ return;
+ if (m_pSDKDoc->GetInterForm())
+ m_pSDKDoc->GetInterForm()->XfaSetValidationsEnabled(bEnabled);
+}
+void CPDFXFA_Document::SetFocusWidget(XFA_HDOC hDoc, XFA_HWIDGET hWidget)
+{
+ if (hDoc != m_pXFADoc)
+ return;
+
+ if (NULL == hWidget) {
+ m_pSDKDoc->SetFocusAnnot(NULL);
+ return;
+ }
+
+ int pageViewCount = m_pSDKDoc->GetPageViewCount();
+ for (int i = 0; i < pageViewCount; i++)
+ {
+ CPDFSDK_PageView* pPageView = m_pSDKDoc->GetPageView(i);
+ if (pPageView == NULL)
+ continue;
+ CPDFSDK_Annot* pAnnot = pPageView->GetAnnotByXFAWidget(hWidget);
+ if (pAnnot) {
+ m_pSDKDoc->SetFocusAnnot(pAnnot);
+ break;
+ }
+ }
+}
+void CPDFXFA_Document::Print(XFA_HDOC hDoc, FX_INT32 nStartPage, FX_INT32 nEndPage, FX_DWORD dwOptions)
+{
+ if (hDoc != m_pXFADoc)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+
+ if (!pEnv->GetFormFillInfo() || pEnv->GetFormFillInfo()->m_pJsPlatform == NULL)
+ return;
+ if (pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print == NULL)
+ return;
+ pEnv->GetFormFillInfo()->m_pJsPlatform->Doc_print(pEnv->GetFormFillInfo()->m_pJsPlatform,dwOptions&XFA_PRINTOPT_ShowDialog,
+ nStartPage,nEndPage,dwOptions&XFA_PRINTOPT_CanCancel,dwOptions&XFA_PRINTOPT_ShrinkPage,dwOptions&XFA_PRINTOPT_AsImage,
+ dwOptions&XFA_PRINTOPT_ReverseOrder,dwOptions&XFA_PRINTOPT_PrintAnnot);
+}
+
+void CPDFXFA_Document::GetURL(XFA_HDOC hDoc, CFX_WideString &wsDocURL)
+{
+ if (hDoc != m_pXFADoc)
+ return;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+
+ pEnv->FFI_GetURL(this, wsDocURL);
+}
+
+FX_ARGB CPDFXFA_Document::GetHighlightColor(XFA_HDOC hDoc)
+{
+ if (hDoc != m_pXFADoc)
+ return 0;
+ if (m_pSDKDoc)
+ {
+ if(CPDFSDK_InterForm* pInterForm = m_pSDKDoc->GetInterForm())
+ {
+ FX_COLORREF color = pInterForm->GetHighlightColor(FPDF_FORMFIELD_XFA);
+ FX_BYTE alpha = pInterForm->GetHighlightAlpha();
+ FX_ARGB argb = ArgbEncode((int)alpha, color);
+ return argb;
+ }
+ }
+ return 0;
+}
+
+void CPDFXFA_Document::AddDoRecord(XFA_HWIDGET hWidget)
+{
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return;
+ return;
+ //pEnv->FFI_AddDoRecord(this, hWidget);
+}
+
+FX_BOOL CPDFXFA_Document::_NotifySubmit(FX_BOOL bPrevOrPost)
+{
+ if (bPrevOrPost)
+ return _OnBeforeNotifySumbit();
+ else
+ _OnAfterNotifySumbit();
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_Document::_OnBeforeNotifySumbit()
+{
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)
+ return TRUE;
+ if (m_pXFADocView == NULL)
+ return TRUE;
+ IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+ if (pWidgetHandler == NULL)
+ return TRUE;
+ IXFA_WidgetAccIterator* pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator();
+ if (pWidgetAccIterator)
+ {
+ CXFA_EventParam Param;
+ Param.m_eType = XFA_EVENT_PreSubmit;
+ CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ while (pWidgetAcc)
+ {
+ pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ }
+ pWidgetAccIterator->Release();
+ }
+ pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator();
+ if (pWidgetAccIterator)
+ {
+ CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ while (pWidgetAcc)
+ {
+ int fRet = pWidgetAcc->ProcessValidate(-1);
+ if (fRet == XFA_EVENTERROR_Error)
+ {
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return FALSE;
+ CFX_WideString ws;
+ ws.FromLocal(IDS_XFA_Validate_Input);
+ CFX_ByteString bs = ws.UTF16LE_Encode();
+ int len = bs.GetLength()/sizeof(unsigned short);
+ pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len*sizeof(unsigned short)), (FPDF_WIDESTRING)L"", 0, 1);
+ bs.ReleaseBuffer(len*sizeof(unsigned short));
+ pWidgetAccIterator->Release();
+ return FALSE;
+ }
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ }
+ pWidgetAccIterator->Release();
+ m_pXFADocView->UpdateDocView();
+ }
+
+ return TRUE;
+
+}
+void CPDFXFA_Document::_OnAfterNotifySumbit()
+{
+ if (m_iDocType != DOCTYPE_DYNIMIC_XFA && m_iDocType != DOCTYPE_STATIC_XFA)
+ return;
+ if (m_pXFADocView == NULL)
+ return;
+ IXFA_WidgetHandler* pWidgetHandler = m_pXFADocView->GetWidgetHandler();
+ if (pWidgetHandler == NULL)
+ return;
+ IXFA_WidgetAccIterator* pWidgetAccIterator = m_pXFADocView->CreateWidgetAccIterator();
+ if (pWidgetAccIterator == NULL)
+ return;
+ CXFA_EventParam Param;
+ Param.m_eType = XFA_EVENT_PostSubmit;
+
+ CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ while (pWidgetAcc)
+ {
+ pWidgetHandler->ProcessEvent(pWidgetAcc, &Param);
+ pWidgetAcc = pWidgetAccIterator->MoveToNext();
+ }
+ pWidgetAccIterator->Release();
+ m_pXFADocView->UpdateDocView();
+}
+
+FX_BOOL CPDFXFA_Document::SubmitData(XFA_HDOC hDoc, CXFA_Submit submit)
+{
+ if (!_NotifySubmit(TRUE))
+ return FALSE;
+ if (NULL == m_pXFADocView)
+ return FALSE;
+ m_pXFADocView->UpdateDocView();
+
+ FX_BOOL ret = _SubmitData(hDoc, submit);
+ _NotifySubmit(FALSE);
+ return ret;
+}
+
+IFX_FileRead* CPDFXFA_Document::OpenLinkedFile(XFA_HDOC hDoc, const CFX_WideString& wsLink)
+{
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return FALSE;
+ CFX_ByteString bs = wsLink.UTF16LE_Encode();
+ int len = bs.GetLength()/sizeof(unsigned short);
+ FPDF_FILEHANDLER* pFileHandler = pEnv->FFI_OpenFile(0, (FPDF_WIDESTRING)bs.GetBuffer(len*sizeof(unsigned short)), "rb");
+ bs.ReleaseBuffer(len*sizeof(unsigned short));
+
+ if (pFileHandler == NULL)
+ return NULL;
+ CFPDF_FileStream* pFileRead = FX_NEW CFPDF_FileStream(pFileHandler);
+ return pFileRead;
+}
+FX_BOOL CPDFXFA_Document::_ExportSubmitFile(FPDF_FILEHANDLER* pFileHandler, int fileType, FPDF_DWORD encodeType, FPDF_DWORD flag)
+{
+ if (NULL == m_pXFADocView)
+ return FALSE;
+ IXFA_DocHandler* pDocHandler = m_pApp->GetXFAApp()->GetDocHandler();
+ CFX_ByteString content;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return FALSE;
+
+ CFPDF_FileStream fileStream(pFileHandler);
+
+ if (fileType == FXFA_SAVEAS_XML)
+ {
+ CFX_WideString ws;
+ ws.FromLocal("data");
+ CFX_ByteString content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
+ fileStream.WriteBlock((FX_LPCSTR)content,0,content.GetLength());
+ pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);
+ }
+ else if (fileType == FXFA_SAVEAS_XDP)
+ {
+ if (flag == 0)
+ flag = FXFA_CONFIG|FXFA_TEMPLATE|FXFA_LOCALESET|FXFA_DATASETS|FXFA_XMPMETA|FXFA_XFDF|FXFA_FORM;
+ if (m_pPDFDoc == NULL)
+ {
+ fileStream.Flush();
+ return FALSE;
+ }
+ CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();
+ if (pRoot == NULL)
+ {
+ fileStream.Flush();
+ return FALSE;
+ }
+ CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
+ if (NULL == pAcroForm)
+ {
+ fileStream.Flush();
+ return FALSE;
+ }
+ CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
+ if (pXFA == NULL)
+ {
+ fileStream.Flush();
+ return FALSE;
+ }
+ if (pXFA->GetType() != PDFOBJ_ARRAY)
+ {
+ fileStream.Flush();
+ return FALSE;
+ }
+ CPDF_Array* pArray = pXFA->GetArray();
+ if (NULL == pArray)
+ {
+ fileStream.Flush();
+ return FALSE;
+ }
+ int size = pArray->GetCount();
+ int iFormIndex = -1;
+ int iDataSetsIndex = -1;
+ for (int i=1; i<size;i+=2)
+ {
+ CPDF_Object* pPDFObj = pArray->GetElement(i);
+ CPDF_Object* pPrePDFObj = pArray->GetElement(i-1);
+ if(pPrePDFObj->GetType() != PDFOBJ_STRING)
+ continue;
+ if (pPDFObj->GetType() != PDFOBJ_REFERENCE)
+ continue;
+ CPDF_Object* pDirectObj = pPDFObj->GetDirect();
+ if (pDirectObj->GetType() != PDFOBJ_STREAM)
+ continue;
+ if (pPrePDFObj->GetString()=="config" && !(flag & FXFA_CONFIG))
+ continue;
+ if (pPrePDFObj->GetString()=="template" && !(flag & FXFA_TEMPLATE))
+ continue;
+ if (pPrePDFObj->GetString()=="localeSet" && !(flag & FXFA_LOCALESET))
+ continue;
+ if (pPrePDFObj->GetString()=="datasets" && !(flag & FXFA_DATASETS))
+ continue;
+ if (pPrePDFObj->GetString()=="xmpmeta" && !(flag & FXFA_XMPMETA))
+ continue;
+ if (pPrePDFObj->GetString()=="xfdf" && !(flag & FXFA_XFDF))
+ continue;
+ if (pPrePDFObj->GetString()=="form" && !(flag & FXFA_FORM))
+ continue;
+ if (pPrePDFObj->GetString()=="form")
+ {
+ CFX_WideString ws;
+ ws.FromLocal("form");
+ pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);
+ }
+ else if (pPrePDFObj->GetString()=="datasets")
+ {
+ CFX_WideString ws;
+ ws.FromLocal("datasets");
+ pDocHandler->SavePackage(m_pXFADoc, ws, &fileStream);
+ }
+ else
+ {
+ //PDF,creator.
+ //TODO:
+ }
+ }
+ }
+ return TRUE;
+}
+
+void CPDFXFA_Document::_ClearChangeMark()
+{
+ if (m_pSDKDoc)
+ m_pSDKDoc->ClearChangeMark();
+}
+
+void CPDFXFA_Document::_ToXFAContentFlags(CFX_WideString csSrcContent, FPDF_DWORD& flag)
+{
+ if (csSrcContent.Find(L" config ", 0) != -1)
+ flag |= FXFA_CONFIG;
+ if (csSrcContent.Find(L" template ", 0) != -1)
+ flag |= FXFA_TEMPLATE;
+ if (csSrcContent.Find(L" localeSet ", 0) != -1)
+ flag |= FXFA_LOCALESET;
+ if (csSrcContent.Find(L" datasets ", 0) != -1)
+ flag |= FXFA_DATASETS;
+ if (csSrcContent.Find(L" xmpmeta ", 0) != -1)
+ flag |= FXFA_XMPMETA;
+ if (csSrcContent.Find(L" xfdf ", 0) != -1)
+ flag |= FXFA_XFDF;
+ if (csSrcContent.Find(L" form ", 0) != -1)
+ flag |= FXFA_FORM;
+ if (flag == 0)
+ flag = FXFA_CONFIG|FXFA_TEMPLATE|FXFA_LOCALESET|FXFA_DATASETS|FXFA_XMPMETA|FXFA_XFDF|FXFA_FORM;
+}
+FX_BOOL CPDFXFA_Document::_MailToInfo(CFX_WideString& csURL, CFX_WideString& csToAddress, CFX_WideString& csCCAddress, CFX_WideString& csBCCAddress, CFX_WideString& csSubject, CFX_WideString& csMsg)
+{
+ CFX_WideString srcURL = csURL;
+ srcURL.TrimLeft();
+ if (0 != srcURL.Left(7).CompareNoCase(L"mailto:"))
+ return FALSE;
+ int pos = srcURL.Find(L'?',0);
+ CFX_WideString tmp;
+ if (pos == -1) {
+ pos = srcURL.Find(L'@',0);
+ if (pos == -1)
+ return FALSE;
+ else
+ {
+ tmp = srcURL.Right(csURL.GetLength()-7);
+ tmp.TrimLeft();
+ tmp.TrimRight();
+ }
+ } else {
+ tmp = srcURL.Left(pos);
+ tmp = tmp.Right(tmp.GetLength()-7);
+ tmp.TrimLeft();
+ tmp.TrimRight();
+ }
+
+ csToAddress = tmp;
+
+ srcURL = srcURL.Right(srcURL.GetLength()-(pos+1));
+ while ( !srcURL.IsEmpty() )
+ {
+ srcURL.TrimLeft();
+ srcURL.TrimRight();
+ pos = srcURL.Find(L'&',0);
+ if (pos == -1)
+ tmp = srcURL;
+ else
+ tmp = srcURL.Left(pos);
+
+ tmp.TrimLeft();
+ tmp.TrimRight();
+ if (tmp.GetLength() >= 3 && 0 == tmp.Left(3).CompareNoCase(L"cc=") )
+ {
+ tmp = tmp.Right(tmp.GetLength()-3);
+ if (!csCCAddress.IsEmpty())
+ csCCAddress += L';';
+ csCCAddress += tmp;
+
+ }
+ else if (tmp.GetLength() >= 4 && 0 == tmp.Left(4).CompareNoCase(L"bcc="))
+ {
+ tmp = tmp.Right(tmp.GetLength() - 4);
+ if (!csBCCAddress.IsEmpty())
+ csBCCAddress += L';';
+ csBCCAddress += tmp;
+ }
+ else if (tmp.GetLength() >= 8 && 0 ==tmp.Left(8).CompareNoCase(L"subject=") )
+ {
+ tmp=tmp.Right(tmp.GetLength()-8);
+ csSubject += tmp;
+ }
+ else if(tmp.GetLength() >= 5 && 0 ==tmp.Left(5).CompareNoCase(L"body=") )
+ {
+ tmp=tmp.Right(tmp.GetLength() - 5);
+ csMsg += tmp;
+ }
+ if (pos == -1)
+ srcURL = L"";
+ else
+ srcURL = srcURL.Right(csURL.GetLength()-(pos+1));
+ }
+ csToAddress.Replace((FX_LPCWSTR)L",", (FX_LPCWSTR)L";");
+ csCCAddress.Replace((FX_LPCWSTR)L",", (FX_LPCWSTR)L";");
+ csBCCAddress.Replace((FX_LPCWSTR)L",", (FX_LPCWSTR)L";");
+ return TRUE;
+}
+
+FX_BOOL CPDFXFA_Document::_SubmitData(XFA_HDOC hDoc, CXFA_Submit submit)
+{
+ CFX_WideStringC csURLC;
+ submit.GetSubmitTarget(csURLC);
+ CFX_WideString csURL = csURLC;
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ if (pEnv == NULL)
+ return FALSE;
+ if (csURL.IsEmpty()){
+ CFX_WideString ws;
+ ws.FromLocal("Submit cancelled.");
+ CFX_ByteString bs = ws.UTF16LE_Encode();
+ int len = bs.GetLength()/sizeof(unsigned short);
+ pEnv->FFI_Alert((FPDF_WIDESTRING)bs.GetBuffer(len*sizeof(unsigned short)), (FPDF_WIDESTRING)L"", 0, 4);
+ bs.ReleaseBuffer(len*sizeof(unsigned short));
+ return FALSE;
+ }
+
+ FPDF_BOOL bRet = TRUE;
+ FPDF_FILEHANDLER* pFileHandler = NULL;
+ int fileFlag = -1;
+
+ if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xdp)
+ {
+ CFX_WideStringC csContentC;
+ submit.GetSubmitXDPContent(csContentC);
+ CFX_WideString csContent;
+ csContent = csContentC.GetPtr();
+ csContent.TrimLeft();
+ csContent.TrimRight();
+ CFX_WideString space;
+ space.FromLocal(" ");
+ csContent = space + csContent + space;
+ FPDF_DWORD flag = 0;
+ if (submit.IsSubmitEmbedPDF())
+ flag |= FXFA_PDF;
+ _ToXFAContentFlags(csContent, flag);
+ pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XDP, NULL, "wb");
+ fileFlag = FXFA_SAVEAS_XDP;
+ _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XDP, 0, flag);
+ }
+ else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xml )
+ {
+ pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");
+ fileFlag = FXFA_SAVEAS_XML;
+ _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);
+ }
+ else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Pdf )
+ {
+ //csfilename = csDocName;
+ }
+ else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Formdata )
+ {
+ return FALSE;
+ }
+ else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Urlencoded )
+ {
+ pFileHandler = pEnv->FFI_OpenFile(FXFA_SAVEAS_XML, NULL, "wb");
+ fileFlag = FXFA_SAVEAS_XML;
+ _ExportSubmitFile(pFileHandler, FXFA_SAVEAS_XML, 0);
+ }
+ else if (submit.GetSubmitFormat() == XFA_ATTRIBUTEENUM_Xfd )
+ {
+ return FALSE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ if (pFileHandler == NULL)
+ return FALSE;
+ if (0 == csURL.Left(7).CompareNoCase(L"mailto:"))
+ {
+ CFX_WideString csToAddress;
+ CFX_WideString csCCAddress;
+ CFX_WideString csBCCAddress;
+ CFX_WideString csSubject;
+ CFX_WideString csMsg;
+
+ bRet = _MailToInfo(csURL, csToAddress, csCCAddress, csBCCAddress, csSubject, csMsg);
+ if (FALSE == bRet)
+ return FALSE;
+
+ CFX_ByteString bsTo = CFX_WideString(csToAddress).UTF16LE_Encode();
+ CFX_ByteString bsCC = CFX_WideString(csCCAddress).UTF16LE_Encode();
+ CFX_ByteString bsBcc = CFX_WideString(csBCCAddress).UTF16LE_Encode();
+ CFX_ByteString bsSubject = CFX_WideString(csSubject).UTF16LE_Encode();
+ CFX_ByteString bsMsg = CFX_WideString(csMsg).UTF16LE_Encode();
+
+ FPDF_WIDESTRING pTo = (FPDF_WIDESTRING)bsTo.GetBuffer(bsTo.GetLength());
+ FPDF_WIDESTRING pCC = (FPDF_WIDESTRING)bsCC.GetBuffer(bsCC.GetLength());
+ FPDF_WIDESTRING pBcc = (FPDF_WIDESTRING)bsBcc.GetBuffer(bsBcc.GetLength());
+ FPDF_WIDESTRING pSubject = (FPDF_WIDESTRING)bsSubject.GetBuffer(bsSubject.GetLength());
+ FPDF_WIDESTRING pMsg = (FPDF_WIDESTRING)bsMsg.GetBuffer(bsMsg.GetLength());
+
+ pEnv->FFI_EmailTo(pFileHandler, pTo, pSubject, pCC, pBcc, pMsg);
+ bsTo.ReleaseBuffer();
+ bsCC.ReleaseBuffer();
+ bsBcc.ReleaseBuffer();
+ bsSubject.ReleaseBuffer();
+ bsMsg.ReleaseBuffer();
+ }
+ else
+ {
+ //http¡¢ftp
+ CFX_WideString ws;
+ CFX_ByteString bs = csURL.UTF16LE_Encode();
+ int len = bs.GetLength()/sizeof(unsigned short);
+ pEnv->FFI_UploadTo(pFileHandler, fileFlag, (FPDF_WIDESTRING)bs.GetBuffer(len*sizeof(unsigned short)));
+ bs.ReleaseBuffer(len*sizeof(unsigned short));
+ }
+
+ return bRet;
+}
+
+FX_BOOL CPDFXFA_Document::SetGlobalProperty(XFA_HDOC hDoc, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ if (hDoc != m_pXFADoc)
+ return FALSE;
+
+ if (m_pSDKDoc && m_pSDKDoc->GetEnv()->GetJSRuntime())
+ return m_pSDKDoc->GetEnv()->GetJSRuntime()->SetHValueByName(szPropName, hValue);
+ return FALSE;
+}
+FX_BOOL CPDFXFA_Document::GetPDFScriptObject(XFA_HDOC hDoc, FX_BSTR utf8Name, FXJSE_HVALUE hValue)
+{
+ if (hDoc != m_pXFADoc)
+ return FALSE;
+
+ if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())
+ return FALSE;
+
+ if (!m_pJSContext)
+ {
+ m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);
+ m_pJSContext =m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();
+ }
+
+ return _GetHValueByName(utf8Name, hValue, m_pSDKDoc->GetEnv()->GetJSRuntime());
+
+}
+FX_BOOL CPDFXFA_Document::GetGlobalProperty(XFA_HDOC hDoc, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ if (hDoc != m_pXFADoc)
+ return FALSE;
+ if (!m_pSDKDoc || !m_pSDKDoc->GetEnv()->GetJSRuntime())
+ return FALSE;
+
+ if (!m_pJSContext)
+ {
+ m_pSDKDoc->GetEnv()->GetJSRuntime()->SetReaderDocument(m_pSDKDoc);
+ m_pJSContext = m_pSDKDoc->GetEnv()->GetJSRuntime()->NewContext();
+ }
+
+ return _GetHValueByName(szPropName, hValue, m_pSDKDoc->GetEnv()->GetJSRuntime());
+
+}
+FX_BOOL CPDFXFA_Document::_GetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue, IFXJS_Runtime* runTime)
+{
+ return runTime->GetHValueByName(utf8Name, hValue);
+}
+
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp
new file mode 100644
index 0000000000..cf05d4ced7
--- /dev/null
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp
@@ -0,0 +1,276 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../include/fsdk_define.h"
+#include "../../include/fsdk_mgr.h"
+#include "../../include/fpdfxfa/fpdfxfa_util.h"
+#include "../../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../../include/fpdfxfa/fpdfxfa_page.h"
+
+CPDFXFA_Page::CPDFXFA_Page(CPDFXFA_Document* pDoc, int page_index) :
+ m_pPDFPage(NULL),
+ m_pXFAPageView(NULL),
+ m_iPageIndex(page_index),
+ m_pDocument(pDoc),
+ m_iRef(1)
+{
+
+}
+
+CPDFXFA_Page::~CPDFXFA_Page()
+{
+ if (m_pPDFPage)
+ delete m_pPDFPage;
+ m_pPDFPage = NULL;
+ m_pXFAPageView = NULL;
+}
+
+void CPDFXFA_Page::Release()
+{
+ m_iRef--;
+ if (m_iRef > 0)
+ return;
+
+ if (m_pDocument)
+ m_pDocument->RemovePage(this);
+
+ delete this;
+}
+
+FX_BOOL CPDFXFA_Page::LoadPDFPage()
+{
+ if (!m_pDocument) return FALSE;
+ CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();
+ if (pPDFDoc)
+ {
+ CPDF_Dictionary* pDict = pPDFDoc->GetPage(m_iPageIndex);
+ if (pDict == NULL) return FALSE;
+ if (m_pPDFPage) {
+ if (m_pPDFPage->m_pFormDict == pDict)
+ return TRUE;
+
+ delete m_pPDFPage;
+ m_pPDFPage = NULL;
+ }
+
+ m_pPDFPage = FX_NEW CPDF_Page;
+ m_pPDFPage->Load(pPDFDoc, pDict);
+ m_pPDFPage->ParseContent();
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+FX_BOOL CPDFXFA_Page::LoadXFAPageView()
+{
+ if (!m_pDocument)
+ return FALSE;
+ XFA_HDOC pXFADoc = m_pDocument->GetXFADoc();
+ if (pXFADoc)
+ {
+ IXFA_DocView* pXFADocView = m_pDocument->GetXFADocView();
+ if (!pXFADocView)
+ return FALSE;
+
+ IXFA_PageView* pPageView = pXFADocView->GetPageView(m_iPageIndex);
+ if (!pPageView)
+ return FALSE;
+
+ if (m_pXFAPageView)
+ if (m_pXFAPageView == pPageView)
+ return TRUE;
+
+ m_pXFAPageView = pPageView;
+ int iStatus = m_pXFAPageView->LoadPageView(NULL);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+FX_BOOL CPDFXFA_Page::LoadPage()
+{
+ if (!m_pDocument || m_iPageIndex < 0)
+ return FALSE;
+
+ int iDocType = m_pDocument->GetDocType();
+ CPDF_Document* pPDFDoc = m_pDocument->GetPDFDoc();
+ XFA_HDOC pXFADoc = m_pDocument->GetXFADoc();
+
+ switch (iDocType)
+ {
+ case DOCTYPE_PDF:
+ case DOCTYPE_STATIC_XFA:
+ {
+ return LoadPDFPage();
+ }
+ case DOCTYPE_DYNIMIC_XFA:
+ {
+ return LoadXFAPageView();
+ }
+ default:
+ return FALSE;
+ }
+
+ return FALSE;
+}
+
+FX_BOOL CPDFXFA_Page::LoadPDFPage(CPDF_Dictionary* pageDict)
+{
+ if (!m_pDocument || m_iPageIndex < 0 || !pageDict)
+ return FALSE;
+
+ if (m_pPDFPage)
+ delete m_pPDFPage;
+
+ m_pPDFPage = FX_NEW CPDF_Page();
+ m_pPDFPage->Load(m_pDocument->GetPDFDoc(), pageDict);
+ m_pPDFPage->ParseContent();
+
+ return TRUE;
+}
+
+FX_FLOAT CPDFXFA_Page::GetPageWidth()
+{
+ ASSERT(m_pDocument != NULL);
+
+ if (!m_pPDFPage && !m_pXFAPageView)
+ return 0.0f;
+
+ int nDocType = m_pDocument->GetDocType();
+ switch (nDocType)
+ {
+ case DOCTYPE_DYNIMIC_XFA:
+ {
+ if (m_pXFAPageView)
+ {
+ CFX_RectF rect;
+ m_pXFAPageView->GetPageViewRect(rect);
+ return rect.width;
+ }
+ }
+ break;
+ case DOCTYPE_STATIC_XFA:
+ case DOCTYPE_PDF:
+ {
+ if (m_pPDFPage)
+ return m_pPDFPage->GetPageWidth();
+ }
+ break;
+ default:
+ return 0.0f;
+ }
+
+ return 0.0f;
+}
+
+FX_FLOAT CPDFXFA_Page::GetPageHeight()
+{
+ ASSERT(m_pDocument != NULL);
+
+ if (!m_pPDFPage && !m_pXFAPageView)
+ return 0.0f;
+
+ int nDocType = m_pDocument->GetDocType();
+ switch (nDocType)
+ {
+ case DOCTYPE_PDF:
+ case DOCTYPE_STATIC_XFA:
+ {
+ if (m_pPDFPage)
+ return m_pPDFPage->GetPageHeight();
+ }
+ break;
+ case DOCTYPE_DYNIMIC_XFA:
+ {
+ if (m_pXFAPageView)
+ {
+ CFX_RectF rect;
+ m_pXFAPageView->GetPageViewRect(rect);
+ return rect.height;
+ }
+ }
+ break;
+ default:
+ return 0.0f;
+ }
+
+ return 0.0f;
+}
+
+void CPDFXFA_Page::DeviceToPage(int start_x, int start_y, int size_x, int size_y, int rotate, int device_x, int device_y, double* page_x, double* page_y)
+{
+ ASSERT(m_pDocument != NULL);
+
+ if (!m_pPDFPage && !m_pXFAPageView)
+ return;
+
+ CPDF_Matrix page2device;
+ CPDF_Matrix device2page;
+ FX_FLOAT page_x_f, page_y_f;
+
+ GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
+
+ device2page.SetReverse(page2device);
+ device2page.Transform((FX_FLOAT)(device_x), (FX_FLOAT)(device_y), page_x_f, page_y_f);
+
+ *page_x = (page_x_f);
+ *page_y = (page_y_f);
+}
+
+void CPDFXFA_Page::PageToDevice(int start_x, int start_y, int size_x, int size_y, int rotate, double page_x, double page_y, int* device_x, int* device_y)
+{
+ if (!m_pPDFPage && !m_pXFAPageView)
+ return;
+
+ CPDF_Matrix page2device;
+ FX_FLOAT device_x_f, device_y_f;
+
+ GetDisplayMatrix(page2device, start_x, start_y, size_x, size_y, rotate);
+
+ page2device.Transform(((FX_FLOAT)page_x), ((FX_FLOAT)page_y), device_x_f, device_y_f);
+
+ *device_x = FXSYS_round(device_x_f);
+ *device_y = FXSYS_round(device_y_f);
+}
+
+void CPDFXFA_Page::GetDisplayMatrix(CFX_AffineMatrix& matrix, int xPos, int yPos,
+ int xSize, int ySize, int iRotate) const
+{
+ ASSERT(m_pDocument != NULL);
+
+ if (!m_pPDFPage && !m_pXFAPageView)
+ return;
+
+ int nDocType = m_pDocument->GetDocType();
+ switch (nDocType)
+ {
+ case DOCTYPE_DYNIMIC_XFA:
+ {
+ if (m_pXFAPageView)
+ {
+ CFX_Rect rect;
+ rect.Set(xPos, yPos, xSize, ySize);
+ m_pXFAPageView->GetDisplayMatrix(matrix, rect, iRotate);
+ }
+ }
+ break;
+ case DOCTYPE_PDF:
+ case DOCTYPE_STATIC_XFA:
+ {
+ if (m_pPDFPage)
+ {
+ m_pPDFPage->GetDisplayMatrix(matrix, xPos, yPos, xSize, ySize, iRotate);
+ }
+ }
+ break;
+ default:
+ return;
+ }
+
+}
diff --git a/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp b/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp
new file mode 100644
index 0000000000..9bf1b63c8f
--- /dev/null
+++ b/fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp
@@ -0,0 +1,96 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../include/fsdk_define.h"
+#include "../../include/fsdk_mgr.h"
+#include "../../include/fpdfxfa/fpdfxfa_util.h"
+
+FX_BOOL FPDF_HasXFAField(CPDF_Document* pPDFDoc, int& docType)
+{
+ if (!pPDFDoc)
+ return FALSE;
+
+ CPDF_Dictionary* pRoot = pPDFDoc->GetRoot();
+ if (!pRoot)
+ return FALSE;
+
+ CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
+ if (!pAcroForm)
+ return FALSE;
+
+ CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
+ if (!pXFA)
+ return FALSE;
+
+ FX_BOOL bDymasticXFA = FALSE;
+ bDymasticXFA = pRoot->GetBoolean("NeedsRendering", FALSE);
+
+ if(bDymasticXFA)
+ docType = DOCTYPE_DYNIMIC_XFA;
+ else
+ docType = DOCTYPE_STATIC_XFA;
+
+ return TRUE;
+}
+
+CFX_PtrArray CXFA_FWLAdapterTimerMgr::ms_timerArray;
+
+FWL_ERR CXFA_FWLAdapterTimerMgr::Start(IFWL_Timer *pTimer, FX_DWORD dwElapse, FWL_HTIMER &hTimer, FX_BOOL bImmediately /* = TRUE */)
+{
+ if (m_pEnv)
+ {
+ FX_UINT32 uIDEvent = m_pEnv->FFI_SetTimer(dwElapse, TimerProc);
+ CFWL_TimerInfo *pInfo = FX_NEW CFWL_TimerInfo;
+ pInfo->uIDEvent = uIDEvent;
+ pInfo->pTimer = pTimer;
+ ms_timerArray.Add(pInfo);
+
+ hTimer = (FWL_HTIMER)pInfo;
+ return FWL_ERR_Succeeded;
+ }
+
+ return FWL_ERR_Indefinite;
+}
+
+FWL_ERR CXFA_FWLAdapterTimerMgr::Stop(FWL_HTIMER hTimer)
+{
+ if (!hTimer) return FWL_ERR_Indefinite;
+
+ if (m_pEnv)
+ {
+ CFWL_TimerInfo *pInfo = (CFWL_TimerInfo*)hTimer;
+
+ m_pEnv->FFI_KillTimer(pInfo->uIDEvent);
+
+ FX_INT32 index = ms_timerArray.Find(pInfo);
+ if (index >= 0)
+ {
+ ms_timerArray.RemoveAt(index);
+ delete pInfo;
+ }
+ return FWL_ERR_Succeeded;
+ }
+
+ return FWL_ERR_Indefinite;
+}
+
+void CXFA_FWLAdapterTimerMgr::TimerProc(FX_INT32 idEvent)
+{
+ CFWL_TimerInfo *pInfo = NULL;
+ FX_INT32 iCount = CXFA_FWLAdapterTimerMgr::ms_timerArray.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++)
+ {
+ CFWL_TimerInfo *pTemp = (CFWL_TimerInfo*)CXFA_FWLAdapterTimerMgr::ms_timerArray.GetAt(i);
+ if (pTemp->uIDEvent == idEvent)
+ {
+ pInfo = pTemp; break;
+ }
+ }
+ if (pInfo)
+ {
+ pInfo->pTimer->Run((FWL_HTIMER)pInfo);
+ }
+}
diff --git a/fpdfsdk/src/fsdk_actionhandler.cpp b/fpdfsdk/src/fsdk_actionhandler.cpp
index 518abd21f0..494b5298d3 100644
--- a/fpdfsdk/src/fsdk_actionhandler.cpp
+++ b/fpdfsdk/src/fsdk_actionhandler.cpp
@@ -5,6 +5,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "../include/fsdk_define.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
#include "../include/fsdk_mgr.h"
#include "../include/fsdk_actionhandler.h"
#include "../include/javascript/IJavaScript.h"
@@ -566,7 +567,7 @@ void CPDFSDK_ActionHandler::DoAction_GoTo(CPDFSDK_Document* pDocument, /*CReader
// ASSERT(pDocView != NULL);
ASSERT(action != NULL);
- CPDF_Document* pPDFDocument = pDocument->GetDocument();
+ CPDF_Document* pPDFDocument = pDocument->GetDocument()->GetPDFDoc();
ASSERT(pPDFDocument != NULL);
CPDFDoc_Environment* pApp = pDocument->GetEnv();
ASSERT(pApp != NULL);
@@ -610,7 +611,7 @@ void CPDFSDK_ActionHandler::DoAction_URI(CPDFSDK_Document* pDocument, const CPDF
CPDFDoc_Environment* pApp = pDocument->GetEnv();
ASSERT(pApp != NULL);
- CFX_ByteString sURI = action.GetURI(pDocument->GetDocument());
+ CFX_ByteString sURI = action.GetURI(pDocument->GetDocument()->GetPDFDoc());
pApp->FFI_DoURIAction(FX_LPCSTR(sURI));
}
diff --git a/fpdfsdk/src/fsdk_annothandler.cpp b/fpdfsdk/src/fsdk_annothandler.cpp
index 9f208d34e2..fff038b809 100644
--- a/fpdfsdk/src/fsdk_annothandler.cpp
+++ b/fpdfsdk/src/fsdk_annothandler.cpp
@@ -5,6 +5,8 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "../include/fsdk_define.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_util.h"
#include "../include/fsdk_mgr.h"
#include "../include/formfiller/FFL_FormFiller.h"
#include "../include/fsdk_annothandler.h"
@@ -17,6 +19,9 @@ CPDFSDK_AnnotHandlerMgr::CPDFSDK_AnnotHandlerMgr(CPDFDoc_Environment* pApp)
CPDFSDK_BFAnnotHandler* pHandler = new CPDFSDK_BFAnnotHandler(m_pApp);
pHandler->SetFormFiller(m_pApp->GetIFormFiller());
RegisterAnnotHandler(pHandler);
+
+ CPDFSDK_XFAAnnotHandler* pXFAAnnotHandler = new CPDFSDK_XFAAnnotHandler(m_pApp);
+ RegisterAnnotHandler(pXFAAnnotHandler);
}
CPDFSDK_AnnotHandlerMgr::~CPDFSDK_AnnotHandlerMgr()
@@ -66,7 +71,20 @@ CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(CPDF_Annot * pAnnot, CPDFSDK_Pa
return pAnnotHandler->NewAnnot(pAnnot, pPageView);
}
- return new CPDFSDK_Annot(pAnnot, pPageView);
+ return new CPDFSDK_BAAnnot(pAnnot, pPageView);
+}
+
+CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::NewAnnot(XFA_HWIDGET pAnnot, CPDFSDK_PageView* pPageView)
+{
+ ASSERT(pAnnot != NULL);
+ ASSERT(pPageView != NULL);
+
+ if (IPDFSDK_AnnotHandler* pAnnotHandler = GetAnnotHandler(FSDK_XFAWIDGET_TYPENAME))
+ {
+ return pAnnotHandler->NewAnnot(pAnnot, pPageView);
+ }
+
+ return NULL;
}
void CPDFSDK_AnnotHandlerMgr::ReleaseAnnot(CPDFSDK_Annot* pAnnot)
@@ -119,9 +137,11 @@ IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(CPDFSDK_Annot* pA
ASSERT(pAnnot != NULL);
CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
- ASSERT(pPDFAnnot != NULL);
-
- return GetAnnotHandler(pPDFAnnot->GetSubType());
+ if (pPDFAnnot)
+ return GetAnnotHandler(pPDFAnnot->GetSubType());
+ else if (pAnnot->GetXFAWidget())
+ return GetAnnotHandler(FSDK_XFAWIDGET_TYPENAME);
+ return NULL;
}
IPDFSDK_AnnotHandler* CPDFSDK_AnnotHandlerMgr::GetAnnotHandler(const CFX_ByteString& sType) const
@@ -141,7 +161,8 @@ void CPDFSDK_AnnotHandlerMgr::Annot_OnDraw(CPDFSDK_PageView* pPageView, CPDFSDK_
}
else
{
- pAnnot->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+ if (!pAnnot->IsXFAField())
+ ((CPDFSDK_BAAnnot*)pAnnot)->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
}
}
@@ -323,6 +344,20 @@ FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnKillFocus(CPDFSDK_Annot* pAnnot, FX_D
return FALSE;
}
+FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnChangeFocus(CPDFSDK_Annot* pSetAnnot,CPDFSDK_Annot* pKillAnnot)
+{
+ FX_BOOL bXFA = (pSetAnnot && pSetAnnot->GetXFAWidget()) ||
+ (pKillAnnot && pKillAnnot->GetXFAWidget());
+
+ if (bXFA)
+ {
+ if (IPDFSDK_AnnotHandler* pXFAAnnotHandler = GetAnnotHandler(FSDK_XFAWIDGET_TYPENAME))
+ return pXFAAnnotHandler->OnXFAChangedFocus(pKillAnnot, pSetAnnot);
+ }
+
+ return TRUE;
+}
+
CPDF_Rect CPDFSDK_AnnotHandlerMgr::Annot_OnGetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
{
ASSERT(pAnnot);
@@ -346,13 +381,30 @@ FX_BOOL CPDFSDK_AnnotHandlerMgr::Annot_OnHitTest(CPDFSDK_PageView *pPageView, CP
CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot,FX_BOOL bNext)
{
- CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), "Widget", "");
-
- CPDFSDK_Annot* pNext = bNext ?
- ai.GetNextAnnot(pSDKAnnot) :
+ CPDFSDK_PageView* pPageView = pSDKAnnot->GetPageView();
+ CPDFXFA_Page* pPage = pPageView->GetPDFXFAPage();
+ if (pPage == NULL)
+ return NULL;
+ if (pPage->GetPDFPage()) { // for pdf annots.
+ CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), pSDKAnnot->GetType(), "");
+ CPDFSDK_Annot* pNext = bNext ?
+ ai.GetNextAnnot(pSDKAnnot) :
ai.GetPrevAnnot(pSDKAnnot);
-
return pNext;
+ }
+ // for xfa annots
+ IXFA_WidgetIterator* pWidgetIterator = pPage->GetXFAPageView()->CreateWidgetIterator(XFA_TRAVERSEWAY_Tranvalse, XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_Viewable | XFA_WIDGETFILTER_Field);
+ if (pWidgetIterator == NULL)
+ return NULL;
+ if (pWidgetIterator->GetCurrentWidget() != pSDKAnnot->GetXFAWidget())
+ pWidgetIterator->SetCurrentWidget(pSDKAnnot->GetXFAWidget());
+ XFA_HWIDGET hNextFocus = NULL;
+ hNextFocus = bNext?pWidgetIterator->MoveToNext():pWidgetIterator->MoveToPrevious();
+ if (hNextFocus == NULL && pSDKAnnot != NULL)
+ hNextFocus = pWidgetIterator->MoveToFirst();
+
+ pWidgetIterator->Release();
+ return pPageView->GetAnnotByXFAWidget(hNextFocus);
}
FX_BOOL CPDFSDK_BFAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot)
@@ -414,6 +466,11 @@ CPDFSDK_Annot* CPDFSDK_BFAnnotHandler::NewAnnot(CPDF_Annot* pAnnot, CPDFSDK_Pag
return pWidget;
}
+CPDFSDK_Annot* CPDFSDK_BFAnnotHandler::NewAnnot(XFA_HWIDGET hWidget, CPDFSDK_PageView* pPage)
+{
+ return NULL;
+}
+
void CPDFSDK_BFAnnotHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot)
{
ASSERT(pAnnot != NULL);
@@ -440,7 +497,7 @@ void CPDFSDK_BFAnnotHandler::OnDraw(CPDFSDK_PageView *pPageView, CPDFSDK_Annot*
if (sSubType == BFFT_SIGNATURE)
{
- pAnnot->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+ ((CPDFSDK_BAAnnot*)pAnnot)->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
}
else
{
@@ -660,6 +717,15 @@ void CPDFSDK_BFAnnotHandler::OnLoad(CPDFSDK_Annot* pAnnot)
{
ASSERT(pAnnot != NULL);
+ CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+ ASSERT(pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
CFX_ByteString sSubType = pAnnot->GetSubType();
if (sSubType == BFFT_SIGNATURE)
@@ -685,6 +751,12 @@ void CPDFSDK_BFAnnotHandler::OnLoad(CPDFSDK_Annot* pAnnot)
}
}
+ if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA)
+ {
+ if (!pWidget->IsAppearanceValid() && !pWidget->GetValue().IsEmpty())
+ pWidget->ResetAppearance(FALSE);
+ }
+
if (m_pFormFiller)
m_pFormFiller->OnLoad(pAnnot);
@@ -752,6 +824,406 @@ FX_BOOL CPDFSDK_BFAnnotHandler::HitTest(CPDFSDK_PageView *pPageView, CPDFSDK_Ann
return rect.Contains(point.x, point.y);
}
+//CPDFSDK_XFAAnnotHandler
+
+#define FWL_WGTHITTEST_Unknown 0
+#define FWL_WGTHITTEST_Client 1 //arrow
+#define FWL_WGTHITTEST_Titlebar 11 //caption
+#define FWL_WGTHITTEST_HScrollBar 15
+#define FWL_WGTHITTEST_VScrollBar 16
+#define FWL_WGTHITTEST_Border 17
+#define FWL_WGTHITTEST_Edit 19
+#define FWL_WGTHITTEST_HyperLink 20
+
+CPDFSDK_XFAAnnotHandler::CPDFSDK_XFAAnnotHandler(CPDFDoc_Environment* pApp) :
+ m_pApp(pApp)
+{
+
+}
+
+CPDFSDK_Annot* CPDFSDK_XFAAnnotHandler::NewAnnot(XFA_HWIDGET pAnnot, CPDFSDK_PageView* pPage)
+{
+ ASSERT(pPage != NULL);
+ ASSERT(pAnnot != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pApp->GetCurrentDoc();
+ ASSERT(pSDKDoc);
+ CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pSDKDoc->GetInterForm();
+ ASSERT(pInterForm != NULL);
+
+ CPDFSDK_XFAWidget* pWidget = NULL;
+ pWidget = new CPDFSDK_XFAWidget(pAnnot, pPage, pInterForm);
+ ASSERT(pWidget != NULL);
+ pInterForm->AddXFAMap(pAnnot, pWidget);
+
+ return pWidget;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::CanAnswer(CPDFSDK_Annot* pAnnot)
+{
+ ASSERT(pAnnot != NULL);
+
+ return pAnnot->GetXFAWidget() != NULL;
+}
+
+void CPDFSDK_XFAAnnotHandler::OnDraw(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, FX_DWORD dwFlags)
+{
+ ASSERT(pPageView != NULL);
+ ASSERT(pAnnot != NULL);
+
+ CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ CFX_Graphics gs;
+ gs.Create(pDevice);
+
+ CFX_Matrix mt;
+ mt = *(CFX_Matrix*)pUser2Device;
+
+ XFA_HWIDGET hWidget = pAnnot->GetXFAWidget();
+ ASSERT(hWidget != NULL);
+
+ FX_BOOL bIsHighlight = FALSE;
+ if (pSDKDoc->GetFocusAnnot() != pAnnot)
+ bIsHighlight = TRUE;
+
+ pWidgetHandler->RenderWidget(pAnnot->GetXFAWidget(), &gs, &mt, bIsHighlight);
+
+ // to do highlight and shadow
+
+}
+
+void CPDFSDK_XFAAnnotHandler::ReleaseAnnot(CPDFSDK_Annot* pAnnot)
+{
+ ASSERT(pAnnot != NULL);
+
+ CPDFSDK_XFAWidget* pWidget = (CPDFSDK_XFAWidget*)pAnnot;
+ CPDFSDK_InterForm* pInterForm = pWidget->GetInterForm();
+ ASSERT(pInterForm != NULL);
+
+ pInterForm->RemoveXFAMap(pWidget->GetXFAWidget());
+
+ delete pWidget;
+}
+
+CPDF_Rect CPDFSDK_XFAAnnotHandler::GetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
+{
+ ASSERT(pAnnot != NULL);
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ XFA_ELEMENT eType = pWidgetHandler->GetDataAcc(pAnnot->GetXFAWidget())->GetUIType();
+ CFX_RectF rcBBox;
+ if (eType == XFA_ELEMENT_Signature)
+ pWidgetHandler->GetBBox (pAnnot->GetXFAWidget(), rcBBox, XFA_WIDGETSTATUS_Visible, TRUE);
+ else
+ pWidgetHandler->GetBBox (pAnnot->GetXFAWidget(), rcBBox, 0);
+
+ CFX_FloatRect rcWidget(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, rcBBox.top+rcBBox.height);
+ rcWidget.left -= 1.0f;
+ rcWidget.right += 1.0f;
+ rcWidget.bottom -= 1.0f;
+ rcWidget.top += 1.0f;
+
+ return rcWidget;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::HitTest(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
+ if (!pSDKDoc)
+ return FALSE;
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ if (!pDoc)
+ return FALSE;
+
+ IXFA_DocView* pDocView = pDoc->GetXFADocView();
+ if (!pDocView)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
+ if (!pWidgetHandler)
+ return FALSE;
+
+ FX_DWORD dwHitTest = pWidgetHandler->OnHitTest(pAnnot->GetXFAWidget(), point.x, point.y);
+ return (dwHitTest != FWL_WGTHITTEST_Unknown);
+}
+
+void CPDFSDK_XFAAnnotHandler::OnMouseEnter(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
+{
+ if (!pPageView || !pAnnot)
+ return;
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ pWidgetHandler->OnMouseEnter(pAnnot->GetXFAWidget());
+}
+
+void CPDFSDK_XFAAnnotHandler::OnMouseExit(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
+{
+ if (!pPageView || !pAnnot)
+ return;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ pWidgetHandler->OnMouseExit(pAnnot->GetXFAWidget());
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnLButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnLButtonDown(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnLButtonUp(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnLButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnLButtonDblClk(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnMouseMove(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnMouseMove(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnMouseWheel(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, short zDelta, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnMouseWheel(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), zDelta, point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnRButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnRButtonDown(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnRButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnRButtonUp(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnRButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_DWORD nFlags, const CPDF_Point& point)
+{
+ if (!pPageView || !pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnRButtonDblClk(pAnnot->GetXFAWidget(), GetFWLFlags(nFlags), point.x, point.y);
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnChar(CPDFSDK_Annot* pAnnot, FX_DWORD nChar, FX_DWORD nFlags)
+{
+ if (!pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnChar(pAnnot->GetXFAWidget(), nChar, GetFWLFlags(nFlags));
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnKeyDown(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag)
+{
+ if (!pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnKeyDown(pAnnot->GetXFAWidget(), nKeyCode, GetFWLFlags(nFlag));
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnKeyUp(CPDFSDK_Annot* pAnnot, int nKeyCode, int nFlag)
+{
+ if (!pAnnot)
+ return FALSE;
+
+ IXFA_WidgetHandler* pWidgetHandler = GetXFAWidgetHandler(pAnnot);
+ ASSERT(pWidgetHandler != NULL);
+
+ FX_BOOL bRet = FALSE;
+ bRet = pWidgetHandler->OnKeyUp(pAnnot->GetXFAWidget(), nKeyCode, GetFWLFlags(nFlag));
+
+ return bRet;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
+{
+ return TRUE;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_DWORD nFlag)
+{
+ return TRUE;
+}
+
+FX_BOOL CPDFSDK_XFAAnnotHandler::OnXFAChangedFocus(CPDFSDK_Annot* pOldAnnot, CPDFSDK_Annot* pNewAnnot)
+{
+ IXFA_WidgetHandler* pWidgetHandler = NULL;
+
+ if (pOldAnnot)
+ pWidgetHandler = GetXFAWidgetHandler(pOldAnnot);
+ else if (pNewAnnot)
+ pWidgetHandler = GetXFAWidgetHandler(pNewAnnot);
+
+ if (pWidgetHandler)
+ {
+ FX_BOOL bRet = TRUE; /*pWidgetHandler->OnFocusChange(pNewAnnot ? pNewAnnot->GetXFAWidget() : NULL,
+ pOldAnnot ? pOldAnnot->GetXFAWidget() : NULL); */
+
+ XFA_HWIDGET hWidget = pNewAnnot ? pNewAnnot->GetXFAWidget() : NULL;
+ if (hWidget)
+ {
+ IXFA_PageView* pXFAPageView = pWidgetHandler->GetPageView(hWidget);
+ if (pXFAPageView)
+ {
+ bRet = pXFAPageView->GetDocView()->SetFocus(hWidget);
+ if (pXFAPageView->GetDocView()->GetFocusWidget() == hWidget)
+ bRet = TRUE;
+ }
+ }
+ return bRet;
+ }
+
+ return TRUE;
+}
+
+IXFA_WidgetHandler* CPDFSDK_XFAAnnotHandler::GetXFAWidgetHandler(CPDFSDK_Annot* pAnnot)
+{
+ if (!pAnnot)
+ return NULL;
+
+ CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+ if (!pPageView)
+ return NULL;
+
+ CPDFSDK_Document* pSDKDoc = pPageView->GetSDKDocument();
+ if (!pSDKDoc)
+ return NULL;
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ if (!pDoc)
+ return NULL;
+
+ IXFA_DocView* pDocView = pDoc->GetXFADocView();
+ if (!pDocView)
+ return NULL;
+
+ return pDocView->GetWidgetHandler();
+}
+
+#define FWL_KEYFLAG_Ctrl (1 << 0)
+#define FWL_KEYFLAG_Alt (1 << 1)
+#define FWL_KEYFLAG_Shift (1 << 2)
+#define FWL_KEYFLAG_LButton (1 << 3)
+#define FWL_KEYFLAG_RButton (1 << 4)
+#define FWL_KEYFLAG_MButton (1 << 5)
+
+FX_DWORD CPDFSDK_XFAAnnotHandler::GetFWLFlags(FX_DWORD dwFlag)
+{
+ FX_DWORD dwFWLFlag = 0;
+
+ if (dwFlag & FWL_EVENTFLAG_ControlKey)
+ dwFWLFlag |= FWL_KEYFLAG_Ctrl;
+ if (dwFlag & FWL_EVENTFLAG_LeftButtonDown)
+ dwFWLFlag |= FWL_KEYFLAG_LButton;
+ if (dwFlag & FWL_EVENTFLAG_MiddleButtonDown)
+ dwFWLFlag |= FWL_KEYFLAG_MButton;
+ if (dwFlag & FWL_EVENTFLAG_RightButtonDown)
+ dwFWLFlag |= FWL_KEYFLAG_RButton;
+ if (dwFlag & FWL_EVENTFLAG_ShiftKey)
+ dwFWLFlag |= FWL_KEYFLAG_Shift;
+ if (dwFlag & FWL_EVENTFLAG_AltKey)
+ dwFWLFlag |= FWL_KEYFLAG_Alt;
+
+ return dwFWLFlag;
+}
+
//CReader_AnnotIteratorEx
CPDFSDK_AnnotIterator::CPDFSDK_AnnotIterator(CPDFSDK_PageView * pPageView,FX_BOOL bReverse,
diff --git a/fpdfsdk/src/fsdk_baseannot.cpp b/fpdfsdk/src/fsdk_baseannot.cpp
index ff054c8b20..90e22d32b2 100644
--- a/fpdfsdk/src/fsdk_baseannot.cpp
+++ b/fpdfsdk/src/fsdk_baseannot.cpp
@@ -5,6 +5,7 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "../include/fsdk_define.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
#include "../include/fsdk_mgr.h"
#include "../include/fsdk_baseannot.h"
@@ -500,40 +501,30 @@ CPDFSDK_DateTime& CPDFSDK_DateTime::AddSeconds(int seconds)
//---------------------------------------------------------------------------
// CPDFSDK_Annot
//---------------------------------------------------------------------------
-CPDFSDK_Annot::CPDFSDK_Annot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView) :
-m_pAnnot(pAnnot),
+CPDFSDK_Annot::CPDFSDK_Annot(CPDFSDK_PageView* pPageView) :
m_pPageView(pPageView),
m_bSelected(FALSE),
m_nTabOrder(-1)
{
}
-CPDFSDK_Annot::~CPDFSDK_Annot()
-{
- m_pAnnot = NULL;
- m_pPageView = NULL;
-}
-CPDF_Annot* CPDFSDK_Annot::GetPDFAnnot()
+//CPDFSDK_BAAnnot
+CPDFSDK_BAAnnot::CPDFSDK_BAAnnot(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView) :
+ CPDFSDK_Annot(pPageView),
+ m_pAnnot(pAnnot)
{
- return m_pAnnot;
-}
-FX_DWORD CPDFSDK_Annot::GetFlags()
-{
- ASSERT(m_pAnnot != NULL);
-
- return m_pAnnot->GetFlags();
}
-void CPDFSDK_Annot::SetPage(CPDFSDK_PageView* pPageView)
+CPDFSDK_BAAnnot::~CPDFSDK_BAAnnot()
{
- m_pPageView = pPageView;
+ m_pAnnot = NULL;
}
-CPDFSDK_PageView* CPDFSDK_Annot::GetPageView()
+CPDF_Annot* CPDFSDK_BAAnnot::GetPDFAnnot()
{
- return m_pPageView;
+ return m_pAnnot;
}
FX_BOOL CPDFSDK_Annot::IsSelected()
@@ -557,14 +548,14 @@ void CPDFSDK_Annot::SetTabOrder(int iTabOrder)
m_nTabOrder = iTabOrder;
}
-CPDF_Dictionary* CPDFSDK_Annot::GetAnnotDict() const
+CPDF_Dictionary* CPDFSDK_BAAnnot::GetAnnotDict() const
{
ASSERT(m_pAnnot != NULL);
return m_pAnnot->m_pAnnotDict;
}
-void CPDFSDK_Annot::SetRect(const CPDF_Rect& rect)
+void CPDFSDK_BAAnnot::SetRect(const CPDF_Rect& rect)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -574,7 +565,7 @@ void CPDFSDK_Annot::SetRect(const CPDF_Rect& rect)
m_pAnnot->m_pAnnotDict->SetAtRect("Rect", rect);
}
-CPDF_Rect CPDFSDK_Annot::GetRect() const
+CPDF_Rect CPDFSDK_BAAnnot::GetRect() const
{
ASSERT(m_pAnnot != NULL);
@@ -584,19 +575,24 @@ CPDF_Rect CPDFSDK_Annot::GetRect() const
return rect;
}
-CFX_ByteString CPDFSDK_Annot::GetType() const
+CFX_ByteString CPDFSDK_BAAnnot::GetType() const
{
ASSERT(m_pAnnot != NULL);
return m_pAnnot->GetSubType();
}
-CFX_ByteString CPDFSDK_Annot::GetSubType() const
+CFX_ByteString CPDFSDK_BAAnnot::GetSubType() const
{
return "";
}
-void CPDFSDK_Annot::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
+void CPDFSDK_BAAnnot::ResetAppearance()
+{
+ ASSERT(FALSE);
+}
+
+void CPDFSDK_BAAnnot::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions)
{
ASSERT(m_pPageView != NULL);
@@ -605,7 +601,7 @@ void CPDFSDK_Annot::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix*
m_pAnnot->DrawAppearance(m_pPageView->GetPDFPage(), pDevice, pUser2Device, mode, pOptions);
}
-FX_BOOL CPDFSDK_Annot::IsAppearanceValid()
+FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid()
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -613,7 +609,7 @@ FX_BOOL CPDFSDK_Annot::IsAppearanceValid()
return m_pAnnot->m_pAnnotDict->GetDict("AP") != NULL;
}
-FX_BOOL CPDFSDK_Annot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode)
+FX_BOOL CPDFSDK_BAAnnot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -637,20 +633,20 @@ FX_BOOL CPDFSDK_Annot::IsAppearanceValid(CPDF_Annot::AppearanceMode mode)
return TRUE;
}
-void CPDFSDK_Annot::DrawBorder(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
+void CPDFSDK_BAAnnot::DrawBorder(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
const CPDF_RenderOptions* pOptions)
{
ASSERT(m_pAnnot != NULL);
m_pAnnot->DrawBorder(pDevice, pUser2Device, pOptions);
}
-void CPDFSDK_Annot::ClearCachedAP()
+void CPDFSDK_BAAnnot::ClearCachedAP()
{
ASSERT(m_pAnnot != NULL);
m_pAnnot->ClearCachedAP();
}
-void CPDFSDK_Annot::SetContents(const CFX_WideString& sContents)
+void CPDFSDK_BAAnnot::SetContents(const CFX_WideString& sContents)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -661,7 +657,7 @@ void CPDFSDK_Annot::SetContents(const CFX_WideString& sContents)
m_pAnnot->m_pAnnotDict->SetAtString("Contents", PDF_EncodeText(sContents));
}
-CFX_WideString CPDFSDK_Annot::GetContents() const
+CFX_WideString CPDFSDK_BAAnnot::GetContents() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -669,7 +665,7 @@ CFX_WideString CPDFSDK_Annot::GetContents() const
return m_pAnnot->m_pAnnotDict->GetUnicodeText("Contents");
}
-void CPDFSDK_Annot::SetAnnotName(const CFX_WideString& sName)
+void CPDFSDK_BAAnnot::SetAnnotName(const CFX_WideString& sName)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -680,7 +676,7 @@ void CPDFSDK_Annot::SetAnnotName(const CFX_WideString& sName)
m_pAnnot->m_pAnnotDict->SetAtString("NM", PDF_EncodeText(sName));
}
-CFX_WideString CPDFSDK_Annot::GetAnnotName() const
+CFX_WideString CPDFSDK_BAAnnot::GetAnnotName() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -688,7 +684,7 @@ CFX_WideString CPDFSDK_Annot::GetAnnotName() const
return m_pAnnot->m_pAnnotDict->GetUnicodeText("NM");
}
-void CPDFSDK_Annot::SetModifiedDate(const FX_SYSTEMTIME& st)
+void CPDFSDK_BAAnnot::SetModifiedDate(const FX_SYSTEMTIME& st)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -702,7 +698,7 @@ void CPDFSDK_Annot::SetModifiedDate(const FX_SYSTEMTIME& st)
m_pAnnot->m_pAnnotDict->SetAtString("M", str);
}
-FX_SYSTEMTIME CPDFSDK_Annot::GetModifiedDate() const
+FX_SYSTEMTIME CPDFSDK_BAAnnot::GetModifiedDate() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -716,7 +712,7 @@ FX_SYSTEMTIME CPDFSDK_Annot::GetModifiedDate() const
return systime;
}
-void CPDFSDK_Annot::SetFlags(int nFlags)
+void CPDFSDK_BAAnnot::SetFlags(int nFlags)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -724,7 +720,7 @@ void CPDFSDK_Annot::SetFlags(int nFlags)
m_pAnnot->m_pAnnotDict->SetAtInteger("F", nFlags);
}
-int CPDFSDK_Annot::GetFlags() const
+int CPDFSDK_BAAnnot::GetFlags() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -732,7 +728,7 @@ int CPDFSDK_Annot::GetFlags() const
return m_pAnnot->m_pAnnotDict->GetInteger("F");
}
-void CPDFSDK_Annot::SetAppState(const CFX_ByteString& str)
+void CPDFSDK_BAAnnot::SetAppState(const CFX_ByteString& str)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -743,7 +739,7 @@ void CPDFSDK_Annot::SetAppState(const CFX_ByteString& str)
m_pAnnot->m_pAnnotDict->SetAtString("AS", str);
}
-CFX_ByteString CPDFSDK_Annot::GetAppState() const
+CFX_ByteString CPDFSDK_BAAnnot::GetAppState() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -751,7 +747,7 @@ CFX_ByteString CPDFSDK_Annot::GetAppState() const
return m_pAnnot->m_pAnnotDict->GetString("AS");
}
-void CPDFSDK_Annot::SetStructParent(int key)
+void CPDFSDK_BAAnnot::SetStructParent(int key)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -759,7 +755,7 @@ void CPDFSDK_Annot::SetStructParent(int key)
m_pAnnot->m_pAnnotDict->SetAtInteger("StructParent", key);
}
-int CPDFSDK_Annot::GetStructParent() const
+int CPDFSDK_BAAnnot::GetStructParent() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -768,7 +764,7 @@ int CPDFSDK_Annot::GetStructParent() const
}
//border
-void CPDFSDK_Annot::SetBorderWidth(int nWidth)
+void CPDFSDK_BAAnnot::SetBorderWidth(int nWidth)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -793,7 +789,7 @@ void CPDFSDK_Annot::SetBorderWidth(int nWidth)
}
}
-int CPDFSDK_Annot::GetBorderWidth() const
+int CPDFSDK_BAAnnot::GetBorderWidth() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -816,7 +812,7 @@ int CPDFSDK_Annot::GetBorderWidth() const
return 1;
}
-void CPDFSDK_Annot::SetBorderStyle(int nStyle)
+void CPDFSDK_BAAnnot::SetBorderStyle(int nStyle)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -848,7 +844,7 @@ void CPDFSDK_Annot::SetBorderStyle(int nStyle)
}
}
-int CPDFSDK_Annot::GetBorderStyle() const
+int CPDFSDK_BAAnnot::GetBorderStyle() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -878,7 +874,7 @@ int CPDFSDK_Annot::GetBorderStyle() const
return BBS_SOLID;
}
-void CPDFSDK_Annot::SetBorderDash(const CFX_IntArray& array)
+void CPDFSDK_BAAnnot::SetBorderDash(const CFX_IntArray& array)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -899,7 +895,7 @@ void CPDFSDK_Annot::SetBorderDash(const CFX_IntArray& array)
pBSDict->SetAt("D", pArray);
}
-void CPDFSDK_Annot::GetBorderDash(CFX_IntArray& array) const
+void CPDFSDK_BAAnnot::GetBorderDash(CFX_IntArray& array) const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -929,7 +925,7 @@ void CPDFSDK_Annot::GetBorderDash(CFX_IntArray& array) const
}
}
-void CPDFSDK_Annot::SetColor(FX_COLORREF color)
+void CPDFSDK_BAAnnot::SetColor(FX_COLORREF color)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -941,7 +937,7 @@ void CPDFSDK_Annot::SetColor(FX_COLORREF color)
m_pAnnot->m_pAnnotDict->SetAt("C", pArray);
}
-void CPDFSDK_Annot::RemoveColor()
+void CPDFSDK_BAAnnot::RemoveColor()
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -949,7 +945,7 @@ void CPDFSDK_Annot::RemoveColor()
m_pAnnot->m_pAnnotDict->RemoveAt("C") ;
}
-FX_BOOL CPDFSDK_Annot::GetColor(FX_COLORREF& color) const
+FX_BOOL CPDFSDK_BAAnnot::GetColor(FX_COLORREF& color) const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -996,7 +992,7 @@ FX_BOOL CPDFSDK_Annot::GetColor(FX_COLORREF& color) const
}
-void CPDFSDK_Annot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox,
+void CPDFSDK_BAAnnot::WriteAppearance(const CFX_ByteString& sAPType, const CPDF_Rect& rcBBox,
const CPDF_Matrix& matrix, const CFX_ByteString& sContents,
const CFX_ByteString& sAPState)
{
@@ -1078,17 +1074,17 @@ FX_FLOAT CPDFSDK_Annot::GetMinHeight() const
return BA_ANNOT_MINHEIGHT;
}
-FX_BOOL CPDFSDK_Annot::CreateFormFiller()
+FX_BOOL CPDFSDK_BAAnnot::CreateFormFiller()
{
return TRUE;
}
-FX_BOOL CPDFSDK_Annot::IsVisible() const
+FX_BOOL CPDFSDK_BAAnnot::IsVisible() const
{
int nFlags = GetFlags();
return !((nFlags & ANNOTFLAG_INVISIBLE) || (nFlags & ANNOTFLAG_HIDDEN) || (nFlags & ANNOTFLAG_NOVIEW));
}
-CPDF_Action CPDFSDK_Annot::GetAction() const
+CPDF_Action CPDFSDK_BAAnnot::GetAction() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -1096,7 +1092,7 @@ CPDF_Action CPDFSDK_Annot::GetAction() const
return m_pAnnot->m_pAnnotDict->GetDict("A");
}
-void CPDFSDK_Annot::SetAction(const CPDF_Action& action)
+void CPDFSDK_BAAnnot::SetAction(const CPDF_Action& action)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -1114,7 +1110,7 @@ void CPDFSDK_Annot::SetAction(const CPDF_Action& action)
}
}
-void CPDFSDK_Annot::RemoveAction()
+void CPDFSDK_BAAnnot::RemoveAction()
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -1122,7 +1118,7 @@ void CPDFSDK_Annot::RemoveAction()
m_pAnnot->m_pAnnotDict->RemoveAt("A");
}
-CPDF_AAction CPDFSDK_Annot::GetAAction() const
+CPDF_AAction CPDFSDK_BAAnnot::GetAAction() const
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -1130,7 +1126,7 @@ CPDF_AAction CPDFSDK_Annot::GetAAction() const
return m_pAnnot->m_pAnnotDict->GetDict("AA");
}
-void CPDFSDK_Annot::SetAAction(const CPDF_AAction& aa)
+void CPDFSDK_BAAnnot::SetAAction(const CPDF_AAction& aa)
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -1140,7 +1136,7 @@ void CPDFSDK_Annot::SetAAction(const CPDF_AAction& aa)
m_pAnnot->m_pAnnotDict->SetAt("AA", (CPDF_AAction&)aa);
}
-void CPDFSDK_Annot::RemoveAAction()
+void CPDFSDK_BAAnnot::RemoveAAction()
{
ASSERT(m_pAnnot != NULL);
ASSERT(m_pAnnot->m_pAnnotDict != NULL);
@@ -1148,7 +1144,7 @@ void CPDFSDK_Annot::RemoveAAction()
m_pAnnot->m_pAnnotDict->RemoveAt("AA");
}
-CPDF_Action CPDFSDK_Annot::GetAAction(CPDF_AAction::AActionType eAAT)
+CPDF_Action CPDFSDK_BAAnnot::GetAAction(CPDF_AAction::AActionType eAAT)
{
CPDF_AAction AAction = GetAAction();
@@ -1164,7 +1160,12 @@ CPDF_Action CPDFSDK_Annot::GetAAction(CPDF_AAction::AActionType eAAT)
return NULL;
}
-void CPDFSDK_Annot::Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, CPDF_RenderOptions* pOptions)
+FX_BOOL CPDFSDK_BAAnnot::IsXFAField()
+{
+ return FALSE;
+}
+
+void CPDFSDK_BAAnnot::Annot_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device, CPDF_RenderOptions* pOptions)
{
m_pAnnot->GetAPForm(m_pPageView->GetPDFPage(), CPDF_Annot::Normal);
@@ -1180,3 +1181,10 @@ CPDF_Page* CPDFSDK_Annot::GetPDFPage()
return NULL;
}
+CPDFXFA_Page* CPDFSDK_Annot::GetPDFXFAPage()
+{
+ if (m_pPageView)
+ return m_pPageView->GetPDFXFAPage();
+ return NULL;
+}
+
diff --git a/fpdfsdk/src/fsdk_baseform.cpp b/fpdfsdk/src/fsdk_baseform.cpp
index aa87dd56bb..c301a8760a 100644
--- a/fpdfsdk/src/fsdk_baseform.cpp
+++ b/fpdfsdk/src/fsdk_baseform.cpp
@@ -5,6 +5,8 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "../include/fsdk_define.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_util.h"
#include "../include/fsdk_mgr.h"
#include "../include/fsdk_baseannot.h"
#include "../include/fsdk_baseform.h"
@@ -23,10 +25,12 @@
#define IsFloatEqual(fa,fb) IsFloatZero((fa)-(fb))
CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm) :
- CPDFSDK_Annot(pAnnot, pPageView),
+ CPDFSDK_BAAnnot(pAnnot, pPageView),
m_pInterForm(pInterForm),
m_nAppAge(0),
- m_nValueAge(0)
+ m_nValueAge(0),
+ m_hMixXFAWidget(NULL),
+ m_pWidgetHandler(NULL)
{
ASSERT(m_pInterForm != NULL);
}
@@ -36,6 +40,527 @@ CPDFSDK_Widget::~CPDFSDK_Widget()
}
+XFA_HWIDGET CPDFSDK_Widget::GetMixXFAWidget()
+{
+ ASSERT(m_pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA)
+ {
+ if (!m_hMixXFAWidget)
+ {
+ if (IXFA_DocView* pDocView = pDoc->GetXFADocView())
+ {
+ CFX_WideString sName;
+ if (this->GetFieldType() == FIELDTYPE_RADIOBUTTON)
+ {
+ sName = this->GetAnnotName();
+ if (sName.IsEmpty())
+ sName = GetName();
+ }
+ else
+ sName = GetName();
+
+ if (!sName.IsEmpty())
+ m_hMixXFAWidget = pDocView->GetWidgetByName(sName);
+ }
+ }
+ return m_hMixXFAWidget;
+ }
+
+ return NULL;
+}
+
+XFA_HWIDGET CPDFSDK_Widget::GetGroupMixXFAWidget()
+{
+ ASSERT(m_pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA)
+ {
+ if (IXFA_DocView* pDocView = pDoc->GetXFADocView())
+ {
+ CFX_WideString sName = GetName();
+
+ if (!sName.IsEmpty())
+ return pDocView->GetWidgetByName(sName);
+ }
+ }
+
+ return NULL;
+}
+
+IXFA_WidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler()
+{
+ ASSERT(m_pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ if (pDoc->GetDocType() == DOCTYPE_STATIC_XFA)
+ {
+ if (!m_pWidgetHandler)
+ {
+ if (IXFA_DocView* pDocView = pDoc->GetXFADocView())
+ {
+ m_pWidgetHandler = pDocView->GetWidgetHandler();
+ }
+ }
+ return m_pWidgetHandler;
+ }
+
+ return NULL;
+}
+
+static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT)
+{
+ XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
+
+ switch (eXFAAAT)
+ {
+ case PDFSDK_XFA_Click:
+ eEventType = XFA_EVENT_Click;
+ break;
+ case PDFSDK_XFA_Full:
+ eEventType = XFA_EVENT_Full;
+ break;
+ case PDFSDK_XFA_PreOpen:
+ eEventType = XFA_EVENT_PreOpen;
+ break;
+ case PDFSDK_XFA_PostOpen:
+ eEventType = XFA_EVENT_PostOpen;
+ break;
+ }
+
+ return eEventType;
+}
+
+static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT, FX_BOOL bWillCommit)
+{
+ XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
+
+ switch (eAAT)
+ {
+ case CPDF_AAction::CursorEnter:
+ eEventType = XFA_EVENT_MouseEnter;
+ break;
+ case CPDF_AAction::CursorExit:
+ eEventType = XFA_EVENT_MouseExit;
+ break;
+ case CPDF_AAction::ButtonDown:
+ eEventType = XFA_EVENT_MouseDown;
+ break;
+ case CPDF_AAction::ButtonUp:
+ eEventType = XFA_EVENT_MouseUp;
+ break;
+ case CPDF_AAction::GetFocus:
+ eEventType = XFA_EVENT_Enter;
+ break;
+ case CPDF_AAction::LoseFocus:
+ eEventType = XFA_EVENT_Exit;
+ break;
+ case CPDF_AAction::PageOpen:
+ break;
+ case CPDF_AAction::PageClose:
+ break;
+ case CPDF_AAction::PageVisible:
+ break;
+ case CPDF_AAction::PageInvisible:
+ break;
+ case CPDF_AAction::KeyStroke:
+ if (!bWillCommit)
+ {
+ eEventType = XFA_EVENT_Change;
+ }
+ break;
+ case CPDF_AAction::Validate:
+ eEventType = XFA_EVENT_Validate;
+ break;
+ case CPDF_AAction::OpenPage:
+ case CPDF_AAction::ClosePage:
+ case CPDF_AAction::Format:
+ case CPDF_AAction::Calculate:
+ case CPDF_AAction::CloseDocument:
+ case CPDF_AAction::SaveDocument:
+ case CPDF_AAction::DocumentSaved:
+ case CPDF_AAction::PrintDocument:
+ case CPDF_AAction::DocumentPrinted:
+ break;
+ }
+
+ return eEventType;
+}
+
+FX_BOOL CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT)
+{
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
+
+ if ((eEventType == XFA_EVENT_Click ||
+ eEventType == XFA_EVENT_Change) &&
+ GetFieldType() == FIELDTYPE_RADIOBUTTON)
+ {
+ if (XFA_HWIDGET hGroupWidget = GetGroupMixXFAWidget())
+ {
+ CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
+ if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
+ return TRUE;
+ }
+ }
+
+ {
+ CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
+ return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+FX_BOOL CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT, PDFSDK_FieldAction& data, CPDFSDK_PageView* pPageView)
+{
+ ASSERT(m_pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
+
+ if (eEventType != XFA_EVENT_Unknown)
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ CXFA_EventParam param;
+ param.m_eType = eEventType;
+ param.m_wsChange = data.sChange;
+ param.m_iCommitKey = data.nCommitKey;
+ param.m_bShift = data.bShift;
+ param.m_iSelStart = data.nSelStart;
+ param.m_iSelEnd = data.nSelEnd;
+ param.m_wsFullText = data.sValue;
+ param.m_bKeyDown = data.bKeyDown;
+ param.m_bModifier = data.bModifier;
+ param.m_wsNewText = data.sValue;
+ if (data.nSelEnd > data.nSelStart)
+ param.m_wsNewText.Delete(data.nSelStart, data.nSelEnd - data.nSelStart);
+ for (int i=0; i<data.sChange.GetLength(); i++)
+ param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
+ param.m_wsPrevText = data.sValue;
+
+ if ((eEventType == XFA_EVENT_Click ||
+ eEventType == XFA_EVENT_Change) &&
+ GetFieldType() == FIELDTYPE_RADIOBUTTON)
+ {
+ if (XFA_HWIDGET hGroupWidget = GetGroupMixXFAWidget())
+ {
+ CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hGroupWidget);
+ param.m_pTarget = pAcc;
+ pXFAWidgetHandler->ProcessEvent(pAcc, &param);
+ }
+
+ {
+ CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
+ param.m_pTarget = pAcc;
+ FX_INT32 nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
+ return nRet == XFA_EVENTERROR_Sucess;
+ }
+ }
+ else
+ {
+ CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
+ param.m_pTarget = pAcc;
+ FX_INT32 nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
+ return nRet == XFA_EVENTERROR_Sucess;
+ }
+
+ if (IXFA_DocView* pDocView = pDoc->GetXFADocView())
+ {
+ pDocView->UpdateDocView();
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+void CPDFSDK_Widget::Synchronize(FX_BOOL bSynchronizeElse)
+{
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ CPDF_FormField* pFormField = GetFormField();
+ ASSERT(pFormField != NULL);
+
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ switch (GetFieldType())
+ {
+ case FIELDTYPE_CHECKBOX:
+ case FIELDTYPE_RADIOBUTTON:
+ {
+ CPDF_FormControl* pFormCtrl = GetFormControl();
+ ASSERT(pFormCtrl != NULL);
+
+ XFA_CHECKSTATE eCheckState = pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
+ pWidgetAcc->SetCheckState(eCheckState);
+ }
+ break;
+ case FIELDTYPE_TEXTFIELD:
+ pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
+ break;
+ case FIELDTYPE_LISTBOX:
+ {
+ pWidgetAcc->ClearAllSelections();
+
+ for (int i=0,sz=pFormField->CountSelectedItems(); i<sz; i++)
+ {
+ int nIndex = pFormField->GetSelectedIndex(i);
+ if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
+ pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
+ }
+ }
+ break;
+ case FIELDTYPE_COMBOBOX:
+ {
+ pWidgetAcc->ClearAllSelections();
+
+ for (int i=0,sz=pFormField->CountSelectedItems(); i<sz; i++)
+ {
+ int nIndex = pFormField->GetSelectedIndex(i);
+ if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
+ pWidgetAcc->SetItemState(nIndex, TRUE, FALSE);
+ }
+ }
+
+ pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
+ break;
+ }
+
+ if (bSynchronizeElse)
+ pWidgetAcc->ProcessValueChanged();
+ }
+ }
+ }
+}
+
+void CPDFSDK_Widget::SynchronizeXFAValue()
+{
+ ASSERT(m_pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
+ if (!pXFADocView) return;
+
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ CPDF_FormField* pFormField = GetFormField();
+ ASSERT(pFormField != NULL);
+
+ CPDF_FormControl* pFormCtrl = GetFormControl();
+ ASSERT(pFormCtrl != NULL);
+
+ CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, pFormField, pFormCtrl);
+ }
+ }
+}
+
+void CPDFSDK_Widget::SynchronizeXFAItems()
+{
+ ASSERT(m_pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ IXFA_DocView* pXFADocView = pDoc->GetXFADocView();
+ if (!pXFADocView) return;
+
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ CPDF_FormField* pFormField = GetFormField();
+ ASSERT(pFormField != NULL);
+
+ SynchronizeXFAItems(pXFADocView, hWidget, pFormField, NULL);
+ }
+ }
+}
+
+void CPDFSDK_Widget::SynchronizeXFAValue(IXFA_DocView* pXFADocView, XFA_HWIDGET hWidget,
+ CPDF_FormField* pFormField, CPDF_FormControl* pFormControl)
+{
+ ASSERT(pXFADocView != NULL);
+ ASSERT(hWidget != NULL);
+
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler())
+ {
+ ASSERT(pFormField != NULL);
+ ASSERT(pFormControl != NULL);
+
+ switch (pFormField->GetFieldType())
+ {
+ case FIELDTYPE_CHECKBOX:
+ {
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
+
+ pFormField->CheckControl(pFormField->GetControlIndex(pFormControl),
+ bChecked, TRUE);
+ }
+ }
+ break;
+ case FIELDTYPE_RADIOBUTTON:
+ {
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
+
+ pFormField->CheckControl(pFormField->GetControlIndex(pFormControl),
+ bChecked, TRUE);
+ }
+ }
+ break;
+ case FIELDTYPE_TEXTFIELD:
+ {
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ CFX_WideString sValue;
+ pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
+ pFormField->SetValue(sValue, TRUE);
+ }
+ }
+ break;
+ case FIELDTYPE_LISTBOX:
+ {
+ pFormField->ClearSelection(FALSE);
+
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ for (int i=0,sz=pWidgetAcc->CountSelectedItems(); i<sz; i++)
+ {
+ int nIndex = pWidgetAcc->GetSelectedItem(i);
+
+ if (nIndex > -1 && nIndex < pFormField->CountOptions())
+ {
+ pFormField->SetItemSelection(nIndex, TRUE, TRUE);
+ }
+ }
+ }
+ }
+ break;
+ case FIELDTYPE_COMBOBOX:
+ {
+ pFormField->ClearSelection(FALSE);
+
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ for (int i=0,sz=pWidgetAcc->CountSelectedItems(); i<sz; i++)
+ {
+ int nIndex = pWidgetAcc->GetSelectedItem(i);
+
+ if (nIndex > -1 && nIndex < pFormField->CountOptions())
+ {
+ pFormField->SetItemSelection(nIndex, TRUE, TRUE);
+ }
+ }
+
+ CFX_WideString sValue;
+ pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
+ pFormField->SetValue(sValue, TRUE);
+ }
+ }
+ break;
+ }
+ }
+}
+
+void CPDFSDK_Widget::SynchronizeXFAItems(IXFA_DocView* pXFADocView, XFA_HWIDGET hWidget,
+ CPDF_FormField* pFormField, CPDF_FormControl* pFormControl)
+{
+ ASSERT(pXFADocView != NULL);
+ ASSERT(hWidget != NULL);
+
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = pXFADocView->GetWidgetHandler())
+ {
+ ASSERT(pFormField != NULL);
+
+ switch (pFormField->GetFieldType())
+ {
+ case FIELDTYPE_LISTBOX:
+ {
+ pFormField->ClearSelection(FALSE);
+ pFormField->ClearOptions(TRUE);
+
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ for (int i=0,sz=pWidgetAcc->CountChoiceListItems(); i<sz; i++)
+ {
+ CFX_WideString swText;
+ pWidgetAcc->GetChoiceListItem(swText, i);
+
+ pFormField->InsertOption(swText, i, TRUE);
+ }
+ }
+ }
+ break;
+ case FIELDTYPE_COMBOBOX:
+ {
+ pFormField->ClearSelection(FALSE);
+ pFormField->ClearOptions(FALSE);
+
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ for (int i=0,sz=pWidgetAcc->CountChoiceListItems(); i<sz; i++)
+ {
+ CFX_WideString swText;
+ pWidgetAcc->GetChoiceListItem(swText, i);
+
+ pFormField->InsertOption(swText, i, FALSE);
+ }
+ }
+
+ pFormField->SetValue(L"", TRUE);
+ }
+ break;
+ }
+ }
+}
+
FX_BOOL CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode)
{
ASSERT(m_pAnnot != NULL);
@@ -90,6 +615,23 @@ int CPDFSDK_Widget::GetFieldType() const
return pField->GetFieldType();
}
+FX_BOOL CPDFSDK_Widget::IsAppearanceValid()
+{
+ ASSERT(m_pPageView != NULL);
+
+ CPDFSDK_Document* pSDKDoc = m_pPageView->GetSDKDocument();
+ ASSERT(pSDKDoc != NULL);
+
+ CPDFXFA_Document* pDoc = pSDKDoc->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ int nDocType = pDoc->GetDocType();
+ if (nDocType == DOCTYPE_PDF || nDocType == DOCTYPE_STATIC_XFA)
+ return CPDFSDK_BAAnnot::IsAppearanceValid();
+
+ return TRUE;
+}
+
int CPDFSDK_Widget::GetFieldFlags() const
{
CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
@@ -160,6 +702,16 @@ int CPDFSDK_Widget::GetRotate() const
return pCtrl->GetRotation() % 360;
}
+CFX_WideString CPDFSDK_Widget::GetName()
+{
+ ASSERT(m_pInterForm != NULL);
+
+ CPDF_FormField* pFormField = GetFormField();
+ ASSERT(pFormField != NULL);
+
+ return pFormField->GetFullName();
+}
+
FX_BOOL CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const
{
CPDF_FormControl* pFormCtrl = GetFormControl();
@@ -214,16 +766,41 @@ FX_FLOAT CPDFSDK_Widget::GetFontSize() const
return fFontSize;
}
-int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const
+int CPDFSDK_Widget::GetSelectedIndex(int nIndex)
{
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ if (nIndex < pWidgetAcc->CountSelectedItems())
+ return pWidgetAcc->GetSelectedItem(nIndex);
+ }
+ }
+ }
+
CPDF_FormField* pFormField = GetFormField();
ASSERT(pFormField != NULL);
return pFormField->GetSelectedIndex(nIndex);
}
-CFX_WideString CPDFSDK_Widget::GetValue() const
+CFX_WideString CPDFSDK_Widget::GetValue(FX_BOOL bDisplay)
{
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ CFX_WideString sValue;
+ pWidgetAcc->GetValue(sValue, bDisplay ? XFA_VALUEPICTURE_Display : XFA_VALUEPICTURE_Edit);
+ return sValue;
+ }
+ }
+ }
+
CPDF_FormField* pFormField = GetFormField();
ASSERT(pFormField != NULL);
@@ -254,8 +831,22 @@ int CPDFSDK_Widget::CountOptions() const
return pFormField->CountOptions();
}
-FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex) const
+FX_BOOL CPDFSDK_Widget::IsOptionSelected(int nIndex)
{
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
+ return pWidgetAcc->GetItemState(nIndex);
+ else
+ return FALSE;
+ }
+ }
+ }
+
CPDF_FormField* pFormField = GetFormField();
ASSERT(pFormField != NULL);
@@ -270,8 +861,20 @@ int CPDFSDK_Widget::GetTopVisibleIndex() const
return pFormField->GetTopVisibleIndex();
}
-FX_BOOL CPDFSDK_Widget::IsChecked() const
+FX_BOOL CPDFSDK_Widget::IsChecked()
{
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
+ {
+ if (CXFA_WidgetAcc* pWidgetAcc = pXFAWidgetHandler->GetDataAcc(hWidget))
+ {
+ FX_BOOL bChecked = pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
+ return bChecked;
+ }
+ }
+ }
+
CPDF_FormControl* pFormCtrl = GetFormControl();
ASSERT(pFormCtrl != NULL);
@@ -303,6 +906,10 @@ void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify)
ASSERT(pFormField != NULL);
pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked, bNotify);
+ if (!IsWidgetAppearanceValid(CPDF_Annot::Normal))
+ ResetAppearance(TRUE);
+ if (!bNotify)
+ Synchronize(TRUE);
}
void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify)
@@ -311,6 +918,9 @@ void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify)
ASSERT(pFormField != NULL);
pFormField->SetValue(sValue, bNotify);
+
+ if (!bNotify)
+ Synchronize(TRUE);
}
void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue)
@@ -322,6 +932,9 @@ void CPDFSDK_Widget::SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bN
ASSERT(pFormField != NULL);
pFormField->SetItemSelection(index, bSelected, bNotify);
+
+ if (!bNotify)
+ Synchronize(TRUE);
}
void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify)
@@ -330,6 +943,9 @@ void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify)
ASSERT(pFormField != NULL);
pFormField->ClearSelection(bNotify);
+
+ if (!bNotify)
+ Synchronize(TRUE);
}
void CPDFSDK_Widget::SetTopVisibleIndex(int index)
@@ -351,6 +967,27 @@ FX_BOOL CPDFSDK_Widget::IsAppModified() const
return m_bAppModified;
}
+void CPDFSDK_Widget::ResetAppearance(FX_BOOL bValueChanged)
+{
+ switch (GetFieldType())
+ {
+ case FIELDTYPE_TEXTFIELD:
+ case FIELDTYPE_COMBOBOX:
+ {
+ FX_BOOL bFormated = FALSE;
+ CFX_WideString sValue = this->OnFormat(0, bFormated);
+ if (bFormated)
+ this->ResetAppearance(sValue, TRUE);
+ else
+ this->ResetAppearance(NULL, TRUE);
+ }
+ break;
+ default:
+ this->ResetAppearance(NULL, FALSE);
+ break;
+ }
+}
+
void CPDFSDK_Widget::ResetAppearance(FX_LPCWSTR sValue, FX_BOOL bValueChanged)
{
SetAppModified();
@@ -433,7 +1070,7 @@ void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix
}
else
{
- CPDFSDK_Annot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
+ CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
}
}
@@ -1251,6 +1888,13 @@ void CPDFSDK_Widget::ResetAppearance_TextField(FX_LPCWSTR sValue)
FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
FX_FLOAT fFontSize = GetFontSize();
+ CFX_WideString sValueTmp;
+ if (!sValue && (NULL != this->GetMixXFAWidget()))
+ {
+ sValueTmp = GetValue(TRUE);
+ sValue = sValueTmp;
+ }
+
if (nMaxLen > 0)
{
if (bCharArray)
@@ -1589,16 +2233,59 @@ void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType)
FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type, PDFSDK_FieldAction& data, CPDFSDK_PageView* pPageView)
{
- CPDF_Action action = GetAAction(type);
+ CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
+ ASSERT(pDocument != NULL);
- if (action && action.GetType() != CPDF_Action::Unknown)
+ CPDFXFA_Document* pDoc = pDocument->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ CPDFDoc_Environment* pEnv = pDocument->GetEnv();
+ ASSERT(pEnv != NULL);
+
+ if (XFA_HWIDGET hWidget = this->GetMixXFAWidget())
{
- CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
- ASSERT(pDocument != NULL);
+ XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit);
- CPDFDoc_Environment* pEnv = pDocument->GetEnv();
- ASSERT(pEnv != NULL);
+ if (eEventType != XFA_EVENT_Unknown)
+ {
+ if (IXFA_WidgetHandler* pXFAWidgetHandler = this->GetXFAWidgetHandler())
+ {
+ CXFA_EventParam param;
+ param.m_eType = eEventType;
+ param.m_wsChange = data.sChange;
+ param.m_iCommitKey = data.nCommitKey;
+ param.m_bShift = data.bShift;
+ param.m_iSelStart = data.nSelStart;
+ param.m_iSelEnd = data.nSelEnd;
+ param.m_wsFullText = data.sValue;
+ param.m_bKeyDown = data.bKeyDown;
+ param.m_bModifier = data.bModifier;
+ param.m_wsNewText = data.sValue;
+ if (data.nSelEnd > data.nSelStart)
+ param.m_wsNewText.Delete(data.nSelStart, data.nSelEnd - data.nSelStart);
+ for (int i=data.sChange.GetLength() - 1; i>=0; i--)
+ param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
+ param.m_wsPrevText = data.sValue;
+
+ CXFA_WidgetAcc* pAcc = pXFAWidgetHandler->GetDataAcc(hWidget);
+ param.m_pTarget = pAcc;
+ FX_INT32 nRet = pXFAWidgetHandler->ProcessEvent(pAcc, &param);
+
+ if (IXFA_DocView* pDocView = pDoc->GetXFADocView())
+ {
+ pDocView->UpdateDocView();
+ }
+ if (nRet == XFA_EVENTERROR_Sucess)
+ return TRUE;
+ }
+ }
+ }
+
+ CPDF_Action action = GetAAction(type);
+
+ if (action && action.GetType() != CPDF_Action::Unknown)
+ {
CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();/*(CPDFSDK_ActionHandler*)pApp->GetActionHandler();*/
ASSERT(pActionHandler != NULL);
@@ -1622,7 +2309,7 @@ CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT)
case CPDF_AAction::PageClose:
case CPDF_AAction::PageVisible:
case CPDF_AAction::PageInvisible:
- return CPDFSDK_Annot::GetAAction(eAAT);
+ return CPDFSDK_BAAnnot::GetAAction(eAAT);
case CPDF_AAction::KeyStroke:
case CPDF_AAction::Format:
case CPDF_AAction::Validate:
@@ -1634,7 +2321,7 @@ CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT)
if (CPDF_AAction aa = pField->GetAdditionalAction())
return aa.GetAction(eAAT);
else
- return CPDFSDK_Annot::GetAAction(eAAT);
+ return CPDFSDK_BAAnnot::GetAAction(eAAT);
}
default:
return NULL;
@@ -1681,14 +2368,59 @@ FX_BOOL CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY)
return FALSE;
}
+//CPDFSDK_XFAWidget
+CPDFSDK_XFAWidget::CPDFSDK_XFAWidget(XFA_HWIDGET pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm) :
+ CPDFSDK_Annot(pPageView),
+ m_hXFAWidget(pAnnot),
+ m_pInterForm(pInterForm)
+{
+
+}
+
+FX_BOOL CPDFSDK_XFAWidget::IsXFAField()
+{
+ return TRUE;
+}
+
+CFX_ByteString CPDFSDK_XFAWidget::GetType() const
+{
+ return FSDK_XFAWIDGET_TYPENAME;
+}
+
+CFX_FloatRect CPDFSDK_XFAWidget::GetRect()
+{
+ CPDFSDK_PageView* pPageView = GetPageView();
+ ASSERT(pPageView != NULL);
+
+ CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
+ ASSERT(pDocument != NULL);
+
+ CPDFXFA_Document* pDoc = pDocument->GetDocument();
+ ASSERT(pDoc != NULL);
+
+ IXFA_DocView* pDocView = pDoc->GetXFADocView();
+ ASSERT(pDocView != NULL);
+
+ IXFA_WidgetHandler* pWidgetHandler = pDocView->GetWidgetHandler();
+ ASSERT(pWidgetHandler != NULL);
+
+ CFX_RectF rcBBox;
+ pWidgetHandler->GetRect(GetXFAWidget(), rcBBox);
+
+ return CFX_FloatRect(rcBBox.left, rcBBox.top, rcBBox.left + rcBBox.width, rcBBox.top+rcBBox.height);
+}
+
+//CPDFSDK_InterForm
CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
:m_pDocument(pDocument),
m_pInterForm(NULL),
m_bCalculate(TRUE),
+ m_bXfaCalculate(TRUE),
+ m_bXfaValidationsEnabled(TRUE),
m_bBusy(FALSE)
{
ASSERT(m_pDocument != NULL);
- m_pInterForm = new CPDF_InterForm(m_pDocument->GetDocument(), FALSE);
+ m_pInterForm = new CPDF_InterForm(m_pDocument->GetDocument()->GetPDFDoc(), FALSE);
ASSERT(m_pInterForm != NULL);
m_pInterForm->SetFormNotify(this);
@@ -1704,6 +2436,7 @@ CPDFSDK_InterForm::~CPDFSDK_InterForm()
m_pInterForm = NULL;
m_Map.RemoveAll();
+ m_XFAMap.RemoveAll();
}
void CPDFSDK_InterForm::Destroy()
@@ -1730,7 +2463,7 @@ CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL b
{
ASSERT(pWidget != NULL);
- CBA_AnnotIterator* pIterator = new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", "");
+ CBA_AnnotIterator* pIterator = new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", "");//XfA?
ASSERT(pIterator != NULL);
CPDFSDK_Widget* pRet = NULL;
@@ -1759,7 +2492,7 @@ CPDFSDK_Widget* CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const
ASSERT(pControlDict != NULL);
ASSERT(m_pDocument != NULL);
- CPDF_Document* pDocument = m_pDocument->GetDocument();
+ CPDF_Document* pDocument = m_pDocument->GetDocument()->GetPDFDoc();
CPDFSDK_PageView* pPage = NULL;
@@ -1852,6 +2585,24 @@ void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl)
m_Map.RemoveKey(pControl);
}
+void CPDFSDK_InterForm::AddXFAMap(XFA_HWIDGET hWidget, CPDFSDK_XFAWidget* pWidget)
+{
+ m_XFAMap.SetAt(hWidget, pWidget);
+}
+
+void CPDFSDK_InterForm::RemoveXFAMap(XFA_HWIDGET hWidget)
+{
+ m_XFAMap.RemoveKey(hWidget);
+}
+
+CPDFSDK_XFAWidget* CPDFSDK_InterForm::GetXFAWidget(XFA_HWIDGET hWidget)
+{
+ CPDFSDK_XFAWidget* pWidget = NULL;
+ m_XFAMap.Lookup(hWidget, pWidget);
+
+ return pWidget;
+}
+
void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled)
{
m_bCalculate = bEnabled;
@@ -1862,11 +2613,29 @@ FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const
return m_bCalculate;
}
+void CPDFSDK_InterForm::XfaEnableCalculate(FX_BOOL bEnabled)
+{
+ m_bXfaCalculate = bEnabled;
+}
+FX_BOOL CPDFSDK_InterForm::IsXfaCalculateEnabled() const
+{
+ return m_bXfaCalculate;
+}
+
+FX_BOOL CPDFSDK_InterForm::IsXfaValidationsEnabled()
+{
+ return m_bXfaValidationsEnabled;
+}
+void CPDFSDK_InterForm::XfaSetValidationsEnabled(FX_BOOL bEnabled)
+{
+ m_bXfaValidationsEnabled = bEnabled;
+}
+
#ifdef _WIN32
CPDF_Stream* CPDFSDK_InterForm::LoadImageFromFile(const CFX_WideString& sFile)
{
ASSERT(m_pDocument != NULL);
- CPDF_Document* pDocument = m_pDocument->GetDocument();
+ CPDF_Document* pDocument = m_pDocument->GetDocument()->GetPDFDoc();
ASSERT(pDocument != NULL);
CPDF_Stream* pRetStream = NULL;
@@ -2089,7 +2858,7 @@ void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField)
CPDFDoc_Environment * pEnv = m_pDocument->GetEnv();
CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
- CPDF_Page * pPage = pWidget->GetPDFPage();
+ CPDFXFA_Page * pPage = pWidget->GetPDFXFAPage();
CPDFSDK_PageView * pPageView = m_pDocument->GetPageView(pPage,FALSE);
FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
@@ -2399,6 +3168,27 @@ FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(const CFX_PtrArray& fields,F
return bRet;
}
+void CPDFSDK_InterForm::SynchronizeField(CPDF_FormField* pFormField, FX_BOOL bSynchronizeElse)
+{
+ ASSERT(pFormField != NULL);
+
+ int x = 0;
+ if (m_FieldSynchronizeMap.Lookup(pFormField, x))
+ return;
+
+ for (int i=0,sz=pFormField->CountControls(); i<sz; i++)
+ {
+ CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
+ ASSERT(pFormCtrl != NULL);
+
+ ASSERT(m_pInterForm != NULL);
+ if (CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
+ {
+ pWidget->Synchronize(bSynchronizeElse);
+ }
+ }
+}
+
CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(const CFX_WideString& sFileExt)
{
CFX_WideString sFileName;
@@ -2621,6 +3411,9 @@ int CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField)
ASSERT(pField != NULL);
CPDF_FormField* pFormField = (CPDF_FormField*)pField;
+
+ SynchronizeField(pFormField, FALSE);
+
int nType = pFormField->GetFieldType();
if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
@@ -2724,23 +3517,23 @@ int CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm)
FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType)
{
- if(nFieldType <1 || nFieldType > 6)
+ if(nFieldType <1 || nFieldType > 7)
return FALSE;
return m_bNeedHightlight[nFieldType-1];
}
void CPDFSDK_InterForm::RemoveAllHighLight()
{
- memset((void*)m_bNeedHightlight, 0, 6*sizeof(FX_BOOL));
+ memset((void*)m_bNeedHightlight, 0, 7*sizeof(FX_BOOL));
}
void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType)
{
- if(nFieldType <0 || nFieldType > 6) return;
+ if(nFieldType <0 || nFieldType > 7) return;
switch(nFieldType)
{
case 0:
{
- for(int i=0; i<6; i++)
+ for(int i=0; i<7; i++)
{
m_aHighlightColor[i] = clr;
m_bNeedHightlight[i] = TRUE;
@@ -2759,7 +3552,7 @@ void CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType)
FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType)
{
- if(nFieldType <0 || nFieldType >6) return FXSYS_RGB(255,255,255);
+ if(nFieldType <0 || nFieldType >7) return FXSYS_RGB(255,255,255);
if(nFieldType == 0)
return m_aHighlightColor[0];
else
diff --git a/fpdfsdk/src/fsdk_mgr.cpp b/fpdfsdk/src/fsdk_mgr.cpp
index efb21a7efc..2340ffa720 100644
--- a/fpdfsdk/src/fsdk_mgr.cpp
+++ b/fpdfsdk/src/fsdk_mgr.cpp
@@ -5,10 +5,14 @@
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
#include "../include/fsdk_define.h"
+#include "../include/fpdfxfa/fpdfxfa_doc.h"
+#include "../include/fpdfxfa/fpdfxfa_page.h"
+#include "../include/fpdfxfa/fpdfxfa_util.h"
#include "../include/fsdk_mgr.h"
#include "../include/fpdf_ext.h"
#include "../include/formfiller/FFL_FormFiller.h"
#include "../include/javascript/IJavaScript.h"
+#include "../include/fpdfxfa/fpdfxfa_app.h"
#if _FX_OS_ == _FX_ANDROID_
#include "time.h"
@@ -81,10 +85,10 @@ void CFX_SystemHandler::InvalidateRect(FX_HWND hWnd, FX_RECT rect)
{
//g_pFormFillApp->FFI_Invalidate();
CPDFSDK_Annot* pSDKAnnot = (CPDFSDK_Annot*)hWnd;
- CPDF_Page* pPage = NULL;
+ CPDFXFA_Page* pPage = NULL;
CPDFSDK_PageView* pPageView = NULL;
pPageView = pSDKAnnot->GetPageView();
- pPage = pSDKAnnot->GetPDFPage();
+ pPage = pSDKAnnot->GetPDFXFAPage();
if(!pPage || !pPageView)
return;
CPDF_Matrix page2device;
@@ -114,7 +118,7 @@ void CFX_SystemHandler::OutputSelectedRect(void* pFormFiller, CPDF_Rect& rect)
CPDFSDK_Annot* pAnnot = pFFL->GetSDKAnnot();
ASSERT(pAnnot);
- CPDF_Page* pPage = pAnnot->GetPDFPage();
+ CPDFXFA_Page* pPage = pAnnot->GetPDFXFAPage();
ASSERT(pPage);
m_pEnv->FFI_OutputSelectedRect(pPage, ptA.x, ptB.y, ptB.x, ptA.y);
}
@@ -212,29 +216,22 @@ FX_SYSTEMTIME CFX_SystemHandler::GetLocalTime()
}
-CJS_RuntimeFactory* GetJSRuntimeFactory()
-{
- static CJS_RuntimeFactory s_JSRuntimeFactory;
- return &s_JSRuntimeFactory;
-}
-CPDFDoc_Environment::CPDFDoc_Environment(CPDF_Document* pDoc) :
+CPDFDoc_Environment::CPDFDoc_Environment(CPDFXFA_Document* pDoc) :
m_pAnnotHandlerMgr(NULL),
m_pActionHandler(NULL),
m_pJSRuntime(NULL),
m_pInfo(NULL),
m_pSDKDoc(NULL),
- m_pPDFDoc(pDoc),
+ m_pDoc(pDoc),
m_pIFormFiller(NULL)
{
m_pSysHandler = NULL;
m_pSysHandler = new CFX_SystemHandler(this);
+ //m_pJSRuntimeFactory = pDoc->GetApp()->GetRuntimeFactory();
- m_pJSRuntimeFactory = NULL;
- m_pJSRuntimeFactory = GetJSRuntimeFactory();
- m_pJSRuntimeFactory->AddRef();
}
CPDFDoc_Environment::~CPDFDoc_Environment()
@@ -245,9 +242,15 @@ CPDFDoc_Environment::~CPDFDoc_Environment()
delete m_pIFormFiller;
m_pIFormFiller = NULL;
}
- if(m_pJSRuntime && m_pJSRuntimeFactory)
- m_pJSRuntimeFactory->DeleteJSRuntime(m_pJSRuntime);
- m_pJSRuntimeFactory->Release();
+
+ if (m_pJSRuntime && FPDFXFA_GetApp()->GetRuntimeFactory())
+ FPDFXFA_GetApp()->GetRuntimeFactory()->DeleteJSRuntime(m_pJSRuntime);
+
+ if (FPDFXFA_GetApp()->m_pEnvList.GetSize() == 0)
+ {
+ FPDFXFA_GetApp()->ReleaseRuntime();
+ FPDFXFA_GetApp()->InitRuntime(TRUE);
+ }
if(m_pSysHandler)
{
@@ -274,9 +277,8 @@ IFXJS_Runtime* CPDFDoc_Environment::GetJSRuntime()
{
if(!IsJSInitiated())
return NULL;
- assert(m_pJSRuntimeFactory);
if(!m_pJSRuntime)
- m_pJSRuntime = m_pJSRuntimeFactory->NewJSRuntime(this);
+ m_pJSRuntime = FPDFXFA_GetApp()->GetRuntimeFactory()->NewJSRuntime(this);
return m_pJSRuntime;
}
@@ -324,7 +326,7 @@ FX_BOOL CPDFDoc_Environment::IsJSInitiated()
return FALSE;
}
-CPDFSDK_Document::CPDFSDK_Document(CPDF_Document* pDoc,CPDFDoc_Environment* pEnv):m_pDoc(pDoc),
+CPDFSDK_Document::CPDFSDK_Document(CPDFXFA_Document* pDoc,CPDFDoc_Environment* pEnv):m_pDoc(pDoc),
m_pInterForm(NULL),m_pEnv(pEnv),m_pOccontent(NULL),m_bChangeMask(FALSE)
{
m_pFocusAnnot = NULL;
@@ -332,14 +334,7 @@ CPDFSDK_Document::CPDFSDK_Document(CPDF_Document* pDoc,CPDFDoc_Environment* pEnv
CPDFSDK_Document::~CPDFSDK_Document()
{
- FX_POSITION pos = m_pageMap.GetStartPosition();
- while (pos) {
- CPDF_Page* pPage = NULL;
- CPDFSDK_PageView* pPageView = NULL;
- m_pageMap.GetNextAssoc(pos, pPage, pPageView);
- delete pPageView;
- }
- m_pageMap.RemoveAll();
+ m_pageMap.RemoveAll();
if(m_pInterForm)
{
m_pInterForm->Destroy();
@@ -363,20 +358,20 @@ void CPDFSDK_Document::InitPageView()
}
}
-void CPDFSDK_Document::AddPageView(CPDF_Page* pPDFPage, CPDFSDK_PageView* pPageView)
+void CPDFSDK_Document::AddPageView(CPDFXFA_Page* pPDFXFAPage, CPDFSDK_PageView* pPageView)
{
- m_pageMap.SetAt(pPDFPage, pPageView);
+ m_pageMap.SetAt(pPDFXFAPage, pPageView);
}
-CPDFSDK_PageView* CPDFSDK_Document::GetPageView(CPDF_Page* pPDFPage, FX_BOOL ReNew)
+CPDFSDK_PageView* CPDFSDK_Document::GetPageView(CPDFXFA_Page* pPDFXFAPage, FX_BOOL ReNew)
{
- CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)m_pageMap.GetValueAt(pPDFPage);
+ CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)m_pageMap.GetValueAt(pPDFXFAPage);
if(pPageView != NULL)
return pPageView;
if(ReNew)
{
- pPageView = new CPDFSDK_PageView(this,pPDFPage);
- m_pageMap.SetAt(pPDFPage, pPageView);
+ pPageView = new CPDFSDK_PageView(this,pPDFXFAPage);
+ m_pageMap.SetAt(pPDFXFAPage, pPageView);
//Delay to load all the annotations, to avoid endless loop.
pPageView->LoadFXAnnots();
}
@@ -386,7 +381,7 @@ CPDFSDK_PageView* CPDFSDK_Document::GetPageView(CPDF_Page* pPDFPage, FX_BOOL ReN
CPDFSDK_PageView* CPDFSDK_Document::GetCurrentView()
{
- CPDF_Page * pPage = (CPDF_Page *)m_pEnv->FFI_GetCurrentPage(m_pDoc);
+ CPDFXFA_Page * pPage = (CPDFXFA_Page *)m_pEnv->FFI_GetCurrentPage(m_pDoc);
if(pPage)
return this->GetPageView(pPage, TRUE);
return NULL;
@@ -395,7 +390,7 @@ CPDFSDK_PageView* CPDFSDK_Document::GetCurrentView()
CPDFSDK_PageView* CPDFSDK_Document::GetPageView(int nIndex)
{
CPDFSDK_PageView * pTempPageView = NULL;
- CPDF_Page * pTempPage = (CPDF_Page*)m_pEnv->FFI_GetPage(m_pDoc,nIndex);
+ CPDFXFA_Page * pTempPage = (CPDFXFA_Page*)m_pEnv->FFI_GetPage(m_pDoc,nIndex);
if(!pTempPage)
return NULL;
@@ -408,8 +403,8 @@ CPDFSDK_PageView* CPDFSDK_Document::GetPageView(int nIndex)
void CPDFSDK_Document:: ProcJavascriptFun()
{
- CPDF_Document* pPDFDoc = this->GetDocument();
- CPDF_DocJSActions docJS(pPDFDoc);
+ CPDFXFA_Document* pPDFDoc = this->GetDocument();
+ CPDF_DocJSActions docJS(pPDFDoc->GetPDFDoc());
int iCount = docJS.CountJSActions();
if (iCount < 1) return;
for (int i = 0; i < iCount; i ++)
@@ -426,7 +421,7 @@ FX_BOOL CPDFSDK_Document::ProcOpenAction()
{
if(!m_pDoc) return FALSE;
- CPDF_Dictionary* pRoot = m_pDoc->GetRoot();
+ CPDF_Dictionary* pRoot = m_pDoc->GetPDFDoc()->GetRoot();
if (!pRoot) return FALSE;
CPDF_Object* pOpenAction = pRoot->GetDict("OpenAction");//
if(!pOpenAction) pOpenAction = pRoot->GetArray("OpenAction");//
@@ -453,23 +448,23 @@ FX_BOOL CPDFSDK_Document::ProcOpenAction()
CPDF_OCContext* CPDFSDK_Document::GetOCContext()
{
if(!m_pOccontent)
- m_pOccontent = new CPDF_OCContext(m_pDoc);
+ m_pOccontent = new CPDF_OCContext(m_pDoc->GetPDFDoc());
return m_pOccontent;
}
-void CPDFSDK_Document::ReMovePageView(CPDF_Page* pPDFPage)
+void CPDFSDK_Document::ReMovePageView(CPDFXFA_Page* pPDFXFAPage)
{
- CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)m_pageMap.GetValueAt(pPDFPage);
- if(pPageView && !pPageView->IsLocked())
+ CPDFSDK_PageView* pPageView = (CPDFSDK_PageView*)m_pageMap.GetValueAt(pPDFXFAPage);
+ if(pPageView)
{
delete pPageView;
- m_pageMap.RemoveKey(pPDFPage);
+ m_pageMap.RemoveKey(pPDFXFAPage);
}
}
-CPDF_Page * CPDFSDK_Document::GetPage(int nIndex)
+CPDFXFA_Page * CPDFSDK_Document::GetPage(int nIndex)
{
- CPDF_Page * pTempPage = (CPDF_Page*)m_pEnv->FFI_GetPage(m_pDoc,nIndex);
+ CPDFXFA_Page * pTempPage = (CPDFXFA_Page*)m_pEnv->FFI_GetPage(m_pDoc,nIndex);
if(!pTempPage)
return NULL;
return pTempPage;
@@ -486,7 +481,7 @@ void CPDFSDK_Document::UpdateAllViews(CPDFSDK_PageView* pSender, CPDFSDK_Annot*
{
FX_POSITION pos = m_pageMap.GetStartPosition();
- CPDF_Page * pPage = NULL;
+ CPDFXFA_Page * pPage = NULL;
CPDFSDK_PageView * pPageView = NULL;
while(pos)
{
@@ -509,17 +504,24 @@ FX_BOOL CPDFSDK_Document::SetFocusAnnot(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
if(m_pFocusAnnot==pAnnot) return TRUE;
+ CPDFSDK_Annot* pLastFocusAnnot = m_pFocusAnnot;
+
if(m_pFocusAnnot)
{
if(!this->KillFocusAnnot(nFlag) ) return FALSE;
}
- CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+ CPDFSDK_PageView* pPageView = NULL;
+ if (pAnnot)
+ pPageView = pAnnot->GetPageView();
if(pAnnot && pPageView->IsValid())
{
CPDFSDK_AnnotHandlerMgr *pAnnotHandler=m_pEnv->GetAnnotHandlerMgr();
if(pAnnotHandler&&!m_pFocusAnnot)
{
+ if (!pAnnotHandler->Annot_OnChangeFocus(pAnnot,pLastFocusAnnot))
+ return FALSE;
+
if (!pAnnotHandler->Annot_OnSetFocus(pAnnot,nFlag))
return FALSE;
if(!m_pFocusAnnot)
@@ -541,6 +543,10 @@ FX_BOOL CPDFSDK_Document::KillFocusAnnot(FX_UINT nFlag)
{
CPDFSDK_Annot* pFocusAnnot = m_pFocusAnnot;
m_pFocusAnnot = NULL;
+
+ if (!pAnnotHandler->Annot_OnChangeFocus(NULL, pFocusAnnot))
+ return FALSE;
+
if(pAnnotHandler->Annot_OnKillFocus(pFocusAnnot, nFlag))
{
@@ -571,7 +577,7 @@ FX_BOOL CPDFSDK_Document::DeletePages(int nStart, int nCount)
return FALSE;
}
- CPDF_Page * pTempPage = NULL;
+ CPDFXFA_Page * pTempPage = NULL;
for ( int i = nCount-1; i >= 0; i-- )
{
pTempPage = GetPage(nStart+i);
@@ -590,7 +596,7 @@ void CPDFSDK_Document::OnCloseDocument()
FX_BOOL CPDFSDK_Document::GetPermissions(int nFlag)
{
- FX_DWORD dwPermissions = m_pDoc->GetUserPermissions();
+ FX_DWORD dwPermissions = m_pDoc->GetPDFDoc()->GetUserPermissions();
return dwPermissions&nFlag;
}
@@ -607,15 +613,16 @@ CFX_WideString CPDFSDK_Document::GetPath()
}
-CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDF_Page* page):m_page(page),m_pSDKDoc(pSDKDoc)
+CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDFXFA_Page* page):m_page(page),m_pSDKDoc(pSDKDoc)
{
CPDFSDK_InterForm* pInterForm = pSDKDoc->GetInterForm();
if(pInterForm)
{
CPDF_InterForm* pPDFInterForm = pInterForm->GetInterForm();
- pPDFInterForm->FixPageFields(page);
+ if (page->GetPDFPage())
+ pPDFInterForm->FixPageFields(page->GetPDFPage());
}
- m_page->SetPrivateData((FX_LPVOID)m_page, (FX_LPVOID)this, NULL);
+
m_fxAnnotArray.RemoveAll();
m_bEnterWidget = FALSE;
@@ -623,15 +630,13 @@ CPDFSDK_PageView::CPDFSDK_PageView(CPDFSDK_Document* pSDKDoc,CPDF_Page* page):m_
m_bOnWidget = FALSE;
m_CaptureWidget = NULL;
m_bValid = FALSE;
- m_bLocked = FALSE;
- m_bTakeOverPage = FALSE;
+ m_pAnnotList = NULL;
}
CPDFSDK_PageView::~CPDFSDK_PageView()
{
CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
int nAnnotCount = m_fxAnnotArray.GetSize();
-
for (int i=0; i<nAnnotCount; i++)
{
CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
@@ -648,30 +653,49 @@ CPDFSDK_PageView::~CPDFSDK_PageView()
delete m_pAnnotList;
m_pAnnotList = NULL;
}
- m_page->RemovePrivateData((FX_LPVOID)m_page);
- if(m_bTakeOverPage) {
- delete m_page;
- }
}
-void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions)
+void CPDFSDK_PageView::PageView_OnDraw(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,CPDF_RenderOptions* pOptions, FX_RECT* pClip)
{
m_curMatrix = *pUser2Device;
-
// m_pAnnotList->DisplayAnnots(m_page, pDevice, pUser2Device, FALSE, pOptions);
CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ CPDFXFA_Page* pPage = GetPDFXFAPage();
+
+ if (pPage == NULL) return;
+
+ if (pPage->GetDocument()->GetDocType() == DOCTYPE_DYNIMIC_XFA) {
+ CFX_Graphics gs;
+ gs.Create(pDevice);
+ if (pClip) {
+ CFX_RectF rectClip;
+ rectClip.Set(pClip->left, pClip->top, pClip->Width(), pClip->Height());
+ gs.SetClipRect(rectClip);
+ }
+ IXFA_RenderContext* pRenderContext = XFA_RenderContext_Create();
+ if (!pRenderContext)
+ return;
+ CXFA_RenderOptions renderOptions;
+ renderOptions.m_bHighlight = TRUE;
+ pRenderContext->StartRender(pPage->GetXFAPageView(), &gs, *pUser2Device, renderOptions);
+ pRenderContext->DoRender();
+ pRenderContext->StopRender();
+ pRenderContext->Release();
+ return;
+ }
+ // for pdf/static xfa.
CPDFSDK_AnnotIterator annotIterator(this, TRUE);
CPDFSDK_Annot * pSDKAnnot=NULL;
int index=-1;
- while((pSDKAnnot = annotIterator.Next(index)))
+ pSDKAnnot = annotIterator.Next(index);
+ while(pSDKAnnot)
{
CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
ASSERT(pAnnotHandlerMgr);
pAnnotHandlerMgr->Annot_OnDraw(this, pSDKAnnot, pDevice, pUser2Device, 0);
+ pSDKAnnot = annotIterator.Next(index);
}
-
}
-
CPDF_Annot* CPDFSDK_PageView::GetPDFAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT pageY)
{
@@ -713,11 +737,13 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetFXAnnotAtPoint(FX_FLOAT pageX, FX_FLOAT page
CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
CPDFSDK_Annot* pSDKAnnot = NULL;
int index = -1;
- while((pSDKAnnot = annotIterator.Next(index)))
+ pSDKAnnot = annotIterator.Next(index);
+ while(pSDKAnnot)
{
CPDF_Rect rc = pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
if(rc.Contains(pageX, pageY))
return pSDKAnnot;
+ pSDKAnnot = annotIterator.Next(index);
}
return NULL;
@@ -731,9 +757,10 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pag
CPDFSDK_AnnotHandlerMgr* pAnnotMgr = pEnv->GetAnnotHandlerMgr();
CPDFSDK_Annot* pSDKAnnot = NULL;
int index = -1;
- while((pSDKAnnot = annotIterator.Next(index)))
+ pSDKAnnot = annotIterator.Next(index);
+ while(pSDKAnnot)
{
- if(pSDKAnnot->GetType() == "Widget")
+ if(pSDKAnnot->GetType() == "Widget" || pSDKAnnot->GetType() == FSDK_XFAWIDGET_TYPENAME)
{
pAnnotMgr->Annot_OnGetViewBBox(this, pSDKAnnot);
CPDF_Point point(pageX, pageY);
@@ -741,6 +768,7 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetFXWidgetAtPoint(FX_FLOAT pageX, FX_FLOAT pag
// if(rc.Contains(pageX, pageY))
return pSDKAnnot;
}
+ pSDKAnnot = annotIterator.Next(index);
}
return NULL;
@@ -781,6 +809,32 @@ CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Annot * pPDFAnnot)
return pSDKAnnot;
}
+CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(XFA_HWIDGET pPDFAnnot)
+{
+ if (!pPDFAnnot) return NULL;
+
+ CPDFSDK_Annot* pSDKAnnot = GetAnnotByXFAWidget(pPDFAnnot);
+ if (pSDKAnnot)
+ return pSDKAnnot;
+
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ ASSERT(pEnv);
+ CPDFSDK_AnnotHandlerMgr * pAnnotHandler= pEnv->GetAnnotHandlerMgr();
+
+ pSDKAnnot =NULL;
+
+ if(pAnnotHandler)
+ {
+ pSDKAnnot = pAnnotHandler->NewAnnot(pPDFAnnot, this);
+ }
+ if(!pSDKAnnot)
+ return NULL;
+
+ m_fxAnnotArray.Add(pSDKAnnot);
+
+ return pSDKAnnot;
+}
+
CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(CPDF_Dictionary * pDict)
{
if(pDict)
@@ -795,21 +849,42 @@ CPDFSDK_Annot* CPDFSDK_PageView::AddAnnot(FX_LPCSTR lpSubType,CPDF_Dictionary *
FX_BOOL CPDFSDK_PageView::DeleteAnnot(CPDFSDK_Annot* pAnnot)
{
- return FALSE;
+ if (!pAnnot)
+ return FALSE;
+ CPDFXFA_Page* pPage = pAnnot->GetPDFXFAPage();
+ if (!pPage || (pPage->GetDocument()->GetDocType() != DOCTYPE_STATIC_XFA && pPage->GetDocument()->GetDocType() != DOCTYPE_DYNIMIC_XFA))
+ return FALSE;
+
+ int index = m_fxAnnotArray.Find(pAnnot);
+ m_fxAnnotArray.RemoveAt(index);
+ if (m_CaptureWidget == pAnnot)
+ m_CaptureWidget = NULL;
+
+ return TRUE;
}
CPDF_Document* CPDFSDK_PageView::GetPDFDocument()
{
if(m_page)
{
- return m_page->m_pDocument;
+ return m_page->GetDocument()->GetPDFDoc();
}
return NULL;
}
+CPDF_Page* CPDFSDK_PageView::GetPDFPage()
+{
+ if (m_page)
+ {
+ return m_page->GetPDFPage();
+ }
+
+ return NULL;
+}
+
int CPDFSDK_PageView::CountAnnots()
{
- return m_pAnnotList->Count();
+ return m_fxAnnotArray.GetSize();
}
CPDFSDK_Annot* CPDFSDK_PageView::GetAnnot(int nIndex)
@@ -834,6 +909,20 @@ CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByDict(CPDF_Dictionary * pDict)
}
return NULL;
}
+CPDFSDK_Annot* CPDFSDK_PageView::GetAnnotByXFAWidget(XFA_HWIDGET hWidget)
+{
+ if (hWidget == NULL)
+ return NULL;
+ int annotCount = m_fxAnnotArray.GetSize();
+
+ for(int i = 0; i < annotCount; i++)
+ {
+ CPDFSDK_Annot* pAnnot = (CPDFSDK_Annot*)m_fxAnnotArray.GetAt(i);
+ if(pAnnot->GetXFAWidget() == hWidget)
+ return pAnnot;
+ }
+ return NULL;
+}
FX_BOOL CPDFSDK_PageView::OnLButtonDown(const CPDF_Point & point, FX_UINT nFlag)
{
@@ -859,6 +948,45 @@ FX_BOOL CPDFSDK_PageView::OnLButtonDown(const CPDF_Point & point, FX_UINT nFlag)
return FALSE;
}
+FX_BOOL CPDFSDK_PageView::OnRButtonDown(const CPDF_Point & point, FX_UINT nFlag)
+{
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ ASSERT(pEnv);
+ CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
+ ASSERT(pAnnotHandlerMgr);
+
+ CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
+
+ if (pFXAnnot == NULL)
+ return FALSE;
+
+ FX_BOOL bRet = pAnnotHandlerMgr->Annot_OnRButtonDown(this, pFXAnnot, nFlag,point);
+ if (bRet)
+ {
+ SetFocusAnnot(pFXAnnot);
+ }
+ return TRUE;
+}
+
+FX_BOOL CPDFSDK_PageView::OnRButtonUp(const CPDF_Point & point, FX_UINT nFlag)
+{
+ CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ ASSERT(pEnv);
+ CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
+ ASSERT(pAnnotHandlerMgr);
+
+ CPDFSDK_Annot* pFXAnnot = GetFXWidgetAtPoint(point.x, point.y);
+
+ if (pFXAnnot == NULL)
+ return FALSE;
+
+ FX_BOOL bRet = pAnnotHandlerMgr->Annot_OnRButtonUp(this, pFXAnnot, nFlag,point);
+ if (bRet)
+ {
+ SetFocusAnnot(pFXAnnot);
+ }
+ return TRUE;
+}
FX_BOOL CPDFSDK_PageView::OnLButtonUp(const CPDF_Point & point, FX_UINT nFlag)
{
@@ -978,27 +1106,61 @@ extern void CheckUnSupportAnnot(CPDF_Document * pDoc, CPDF_Annot* pPDFAnnot);
void CPDFSDK_PageView::LoadFXAnnots()
{
+ ASSERT(m_page != NULL);
+
CPDFDoc_Environment* pEnv = m_pSDKDoc->GetEnv();
+ ASSERT(pEnv != NULL);
- FX_BOOL enableAPUpdate = CPDF_InterForm::UpdatingAPEnabled();
- //Disable the default AP construction.
- CPDF_InterForm::EnableUpdateAP(FALSE);
- m_pAnnotList = new CPDF_AnnotList(m_page);
- CPDF_InterForm::EnableUpdateAP(enableAPUpdate);
- int nCount = m_pAnnotList->Count();
- SetLock(TRUE);
- for(int i=0; i<nCount; i++)
+ CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
+ ASSERT(pAnnotHandlerMgr != NULL);
+
+ if (m_pSDKDoc->GetDocument()->GetDocType() == DOCTYPE_DYNIMIC_XFA)
{
- CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
- CPDF_Document * pDoc = this->GetPDFDocument();
+ IXFA_PageView* pageView = NULL;
+ pageView = m_page->GetXFAPageView();
+ ASSERT(pageView != NULL);
+
+ XFA_HWIDGET pXFAAnnot = NULL;
+ IXFA_WidgetIterator* pWidgetHander = pageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form, XFA_WIDGETFILTER_Visible|XFA_WIDGETFILTER_Viewable|XFA_WIDGETFILTER_AllType);
+ if (!pWidgetHander)
+ return;
+
+ pXFAAnnot = pWidgetHander->MoveToNext();
+ while (pXFAAnnot) {
+ CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pXFAAnnot, this);
+ if(!pAnnot) {
+ pXFAAnnot = pWidgetHander->MoveToNext();
+ continue;
+ }
+ m_fxAnnotArray.Add(pAnnot);
- CheckUnSupportAnnot(pDoc, pPDFAnnot);
+ pAnnotHandlerMgr->Annot_OnLoad(pAnnot);
- CPDFSDK_AnnotHandlerMgr* pAnnotHandlerMgr = pEnv->GetAnnotHandlerMgr();
- ASSERT(pAnnotHandlerMgr != NULL);
+ pXFAAnnot = pWidgetHander->MoveToNext();
- if(pAnnotHandlerMgr)
+ }
+
+ pWidgetHander->Release();
+ }
+ else
+ {
+ CPDF_Page* pPage = m_page->GetPDFPage();
+ ASSERT(pPage != NULL);
+
+ FX_BOOL enableAPUpdate = CPDF_InterForm::UpdatingAPEnabled();
+ //Disable the default AP construction.
+ CPDF_InterForm::EnableUpdateAP(FALSE);
+ m_pAnnotList = new CPDF_AnnotList(pPage);
+ CPDF_InterForm::EnableUpdateAP(enableAPUpdate);
+
+ int nCount = m_pAnnotList->Count();
+ for(int i=0; i<nCount; i++)
{
+ CPDF_Annot* pPDFAnnot = m_pAnnotList->GetAt(i);
+ CPDF_Document * pDoc = this->GetPDFDocument();
+
+ CheckUnSupportAnnot(pDoc, pPDFAnnot);
+
CPDFSDK_Annot* pAnnot = pAnnotHandlerMgr->NewAnnot(pPDFAnnot, this);
if(!pAnnot)
continue;
@@ -1008,7 +1170,6 @@ void CPDFSDK_PageView::LoadFXAnnots()
}
}
- SetLock(FALSE);
}
void CPDFSDK_PageView::UpdateRects(CFX_RectArray& rects)
@@ -1037,11 +1198,11 @@ int CPDFSDK_PageView::GetPageIndex()
{
if(m_page)
{
- CPDF_Dictionary* pDic = m_page->m_pFormDict;
- CPDF_Document* pDoc = m_pSDKDoc->GetDocument();
+ CPDF_Dictionary* pDic = m_page->GetPDFPage()->m_pFormDict;
+ CPDFXFA_Document* pDoc = m_pSDKDoc->GetDocument();
if(pDoc && pDic)
{
- return pDoc->GetPageIndex(pDic->GetObjNum());
+ return pDoc->GetPDFDoc()->GetPageIndex(pDic->GetObjNum());
}
}
return -1;
diff --git a/fpdfsdk/src/javascript/Document.cpp b/fpdfsdk/src/javascript/Document.cpp
index 229d9770a1..fa3b9de75b 100644
--- a/fpdfsdk/src/javascript/Document.cpp
+++ b/fpdfsdk/src/javascript/Document.cpp
@@ -605,7 +605,7 @@ FX_BOOL Document::mailForm(OBJ_METHOD_PARAMS)
ASSERT(pRuntime != NULL);
pRuntime->BeginBlock();
- pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg);
+ pEnv->JS_docmailForm(textBuf.GetBuffer(), textBuf.GetLength(), bUI, (FX_LPCWSTR)cTo, (FX_LPCWSTR)cSubject, (FX_LPCWSTR)cCc, (FX_LPCWSTR)cBcc, (FX_LPCWSTR)cMsg);
pRuntime->EndBlock();
return TRUE;
}
@@ -723,7 +723,7 @@ FX_BOOL Document::removeField(OBJ_METHOD_PARAMS)
CFX_RectArray aRefresh;
aRefresh.Add(rcAnnot);
- CPDF_Page* pPage = pWidget->GetPDFPage();
+ CPDFXFA_Page* pPage = pWidget->GetPDFXFAPage();
ASSERT(pPage != NULL);
CPDFSDK_PageView* pPageView = m_pDocument->GetPageView(pPage);
@@ -1009,7 +1009,7 @@ FX_BOOL Document::author(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1033,7 +1033,7 @@ FX_BOOL Document::info(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
CFX_WideString cwAuthor = pDictionary->GetUnicodeText("Author");
@@ -1092,7 +1092,7 @@ FX_BOOL Document::creationDate(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1117,7 +1117,7 @@ FX_BOOL Document::creator(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1183,7 +1183,7 @@ FX_BOOL Document::keywords(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1207,7 +1207,7 @@ FX_BOOL Document::modDate(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1231,7 +1231,7 @@ FX_BOOL Document::producer(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1255,7 +1255,7 @@ FX_BOOL Document::subject(OBJ_PROP_PARAMS)
{
ASSERT(m_pDocument != NULL);
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1282,7 +1282,7 @@ FX_BOOL Document::title(OBJ_PROP_PARAMS)
if (m_pDocument == NULL || m_pDocument->GetDocument() == NULL)
return FALSE;
- CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetInfo();
+ CPDF_Dictionary* pDictionary = m_pDocument->GetDocument()->GetPDFDoc()->GetInfo();
if (!pDictionary)return FALSE;
if (vp.IsGetting())
@@ -1874,7 +1874,7 @@ FX_BOOL Document::getPageNthWord(OBJ_METHOD_PARAMS)
int nWordNo = params.GetSize() > 1 ? (int)params[1] : 0;
bool bStrip = params.GetSize() > 2 ? (bool)params[2] : true;
- CPDF_Document* pDocument = m_pDocument->GetDocument();
+ CPDF_Document* pDocument = m_pDocument->GetDocument()->GetPDFDoc();
if (!pDocument) return FALSE;
if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
@@ -1945,7 +1945,7 @@ FX_BOOL Document::getPageNumWords(OBJ_METHOD_PARAMS)
int nPageNo = params.GetSize() > 0 ? (int)params[0] : 0;
- CPDF_Document* pDocument = m_pDocument->GetDocument();
+ CPDF_Document* pDocument = m_pDocument->GetDocument()->GetPDFDoc();
ASSERT(pDocument != NULL);
if (nPageNo < 0 || nPageNo >= pDocument->GetPageCount())
diff --git a/fpdfsdk/src/javascript/Field.cpp b/fpdfsdk/src/javascript/Field.cpp
index f5f9bf0539..c484cbb1fd 100644
--- a/fpdfsdk/src/javascript/Field.cpp
+++ b/fpdfsdk/src/javascript/Field.cpp
@@ -3820,7 +3820,7 @@ FX_BOOL Field::setFocus(OBJ_METHOD_PARAMS)
{
CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
ASSERT(pEnv);
- CPDF_Page* pPage = (CPDF_Page*)pEnv->FFI_GetCurrentPage(m_pDocument->GetDocument());
+ CPDFXFA_Page* pPage = (CPDFXFA_Page*)pEnv->FFI_GetCurrentPage(m_pDocument->GetDocument());
if(!pPage)
return FALSE;
if (CPDFSDK_PageView* pCurPageView = m_pDocument->GetPageView(pPage))
diff --git a/fpdfsdk/src/javascript/JS_Context.cpp b/fpdfsdk/src/javascript/JS_Context.cpp
index a83e1e057d..31969e4858 100644
--- a/fpdfsdk/src/javascript/JS_Context.cpp
+++ b/fpdfsdk/src/javascript/JS_Context.cpp
@@ -107,6 +107,7 @@ FX_BOOL CJS_Context::DoJob(int nMode, const CFX_WideString& script, CFX_WideStri
FX_BOOL CJS_Context::RunScript(const CFX_WideString& script, CFX_WideString& info)
{
v8::Isolate::Scope isolate_scope(m_pRuntime->GetIsolate());
+ v8::Locker locker(m_pRuntime->GetIsolate());
v8::HandleScope handle_scope(m_pRuntime->GetIsolate());
v8::Local<v8::Context> context = m_pRuntime->NewJSContext();
v8::Context::Scope context_scope(context);
diff --git a/fpdfsdk/src/javascript/JS_GlobalData.cpp b/fpdfsdk/src/javascript/JS_GlobalData.cpp
index 83771dfe57..2207726890 100644
--- a/fpdfsdk/src/javascript/JS_GlobalData.cpp
+++ b/fpdfsdk/src/javascript/JS_GlobalData.cpp
@@ -117,7 +117,7 @@ static const FX_BYTE JS_RC4KEY[] = {0x19,0xa8,0xe8,0x01,0xf6,0xa8,0xb6,0x4d,0x82
0x55,0x8b,0x6e,0x6b,0x19,0xa0,0xf8,0x77,0xd5,0xa3
};
-CJS_GlobalData::CJS_GlobalData(CPDFDoc_Environment* pApp)
+CJS_GlobalData::CJS_GlobalData(CPDFDoc_Environment* pApp) : m_pApp(pApp)
{
// IBaseAnnot* pBaseAnnot = IBaseAnnot::GetBaseAnnot(m_pApp);
// ASSERT(pBaseAnnot != NULL);
diff --git a/fpdfsdk/src/javascript/JS_Object.cpp b/fpdfsdk/src/javascript/JS_Object.cpp
index 3b7774d4d8..09150e796b 100644
--- a/fpdfsdk/src/javascript/JS_Object.cpp
+++ b/fpdfsdk/src/javascript/JS_Object.cpp
@@ -16,7 +16,7 @@ int FXJS_MsgBox(CPDFDoc_Environment* pApp, CPDFSDK_PageView* pPageView, FX_LPCWS
{
int nRet = 0;
- if(pApp)
+ if (pApp)
{
CPDFSDK_Document* pDoc = pApp->GetCurrentDoc();
if(pDoc)
@@ -65,7 +65,7 @@ void CJS_EmbedObj::Alert(CJS_Context* pContext, FX_LPCWSTR swMsg)
CJS_Object::Alert(pContext, swMsg);
}
-CJS_Timer* CJS_EmbedObj::BeginTimer(CPDFDoc_Environment * pApp,FX_UINT nElapse)
+CJS_Timer* CJS_EmbedObj::BeginTimer(CPDFDoc_Environment* pApp, FX_UINT nElapse)
{
CJS_Timer* pTimer = new CJS_Timer(this,pApp);
pTimer->SetJSTimer(nElapse);
diff --git a/fpdfsdk/src/javascript/JS_Runtime.cpp b/fpdfsdk/src/javascript/JS_Runtime.cpp
index d7802b572e..269f23bbd7 100644
--- a/fpdfsdk/src/javascript/JS_Runtime.cpp
+++ b/fpdfsdk/src/javascript/JS_Runtime.cpp
@@ -26,6 +26,12 @@
#include "../../include/javascript/JS_GlobalData.h"
#include "../../include/javascript/global.h"
#include "../../include/javascript/console.h"
+#include "../../include/fpdfxfa/fpdfxfa_app.h"
+#ifndef FOXIT_CHROME_BUILD
+#include "../../../fxjse/value.h"
+#else
+#include "../../../xfa/src/fxjse/src/value.h"
+#endif
#include <libplatform/libplatform.h>
@@ -101,16 +107,26 @@ void CJS_RuntimeFactory::ReleaseGlobalData()
}
/* ------------------------------ CJS_Runtime ------------------------------ */
-
-CJS_Runtime::CJS_Runtime(CPDFDoc_Environment * pApp) :
+extern v8::Persistent<v8::ObjectTemplate>& _getGlobalObjectTemplate(IJS_Runtime* pJSRuntime);
+CJS_Runtime::CJS_Runtime(CPDFDoc_Environment* pApp) :
m_pApp(pApp),
m_pDocument(NULL),
m_bBlocking(FALSE),
m_pFieldEventPath(NULL),
m_bRegistered(FALSE)
{
- m_isolate = v8::Isolate::New();
+ m_isolate = FPDFXFA_GetApp()->GetJSERuntime()?(v8::Isolate*)FPDFXFA_GetApp()->GetJSERuntime():v8::Isolate::New();
//m_isolate->Enter();
+ v8::Isolate* isolate = m_isolate;
+ v8::Isolate::Scope isolate_scope(isolate);
+ v8::Locker locker(isolate);
+ v8::HandleScope handle_scope(isolate);
+ if (FPDFXFA_GetApp()->InitRuntime(FALSE)) {
+ CJS_Context * pContext = (CJS_Context*)NewContext();
+ JS_InitialRuntime(*this, this, pContext, m_context);
+ ReleaseContext(pContext);
+ return;
+ }
InitJSObjects();
@@ -121,12 +137,13 @@ CJS_Runtime::CJS_Runtime(CPDFDoc_Environment * pApp) :
CJS_Runtime::~CJS_Runtime()
{
- for (int i=0, sz=m_ContextArray.GetSize(); i<sz; i++)
+ int size = m_ContextArray.GetSize();
+ for (int i=0;i < size; i++)
delete m_ContextArray.GetAt(i);
m_ContextArray.RemoveAll();
- JS_ReleaseRuntime(*this, m_context);
+ //JS_ReleaseRuntime(*this, m_context);
RemoveEventsInLoop(m_pFieldEventPath);
@@ -136,12 +153,14 @@ CJS_Runtime::~CJS_Runtime()
m_context.Reset();
//m_isolate->Exit();
- m_isolate->Dispose();
+ //m_isolate->Dispose();
+ m_isolate = NULL;
}
FX_BOOL CJS_Runtime::InitJSObjects()
{
v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::Locker locker(GetIsolate());
v8::HandleScope handle_scope(GetIsolate());
v8::Handle<v8::Context> context = v8::Context::New(GetIsolate());
v8::Context::Scope context_scope(context);
@@ -215,6 +234,7 @@ void CJS_Runtime::SetReaderDocument(CPDFSDK_Document* pReaderDoc)
if (m_pDocument != pReaderDoc)
{
v8::Isolate::Scope isolate_scope(m_isolate);
+ v8::Locker locker(m_isolate);
v8::HandleScope handle_scope(m_isolate);
v8::Local<v8::Context> context =v8::Local<v8::Context>::New(m_isolate, m_context);
v8::Context::Scope context_scope(context);
@@ -476,3 +496,45 @@ void CJS_Runtime::Enter()
{
if(m_isolate) m_isolate->Enter();
}
+FX_BOOL CJS_Runtime::GetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue)
+{
+ FX_LPCSTR name = utf8Name.GetCStr();
+
+ v8::Locker lock(GetIsolate());
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(GetIsolate(), m_context);
+ v8::Context::Scope context_scope(context);
+
+
+ //v8::Local<v8::Context> tmpCotext = v8::Local<v8::Context>::New(GetIsolate(), m_context);
+ v8::Local<v8::Value> propvalue = context->Global()->Get(v8::String::NewFromUtf8(GetIsolate(), name, v8::String::kNormalString, utf8Name.GetLength()));
+
+ if (propvalue.IsEmpty()) {
+ FXJSE_Value_SetUndefined(hValue);
+ return FALSE;
+ }
+ ((CFXJSE_Value*)hValue)->ForceSetValue(propvalue);
+
+ return TRUE;
+}
+FX_BOOL CJS_Runtime::SetHValueByName(FX_BSTR utf8Name, FXJSE_HVALUE hValue)
+{
+ if (utf8Name.IsEmpty() || hValue == NULL)
+ return FALSE;
+ FX_LPCSTR name = utf8Name.GetCStr();
+ v8::Isolate* pIsolate = GetIsolate();
+ v8::Locker lock(pIsolate);
+ v8::Isolate::Scope isolate_scope(pIsolate);
+ v8::HandleScope handle_scope(pIsolate);
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(pIsolate, m_context);
+ v8::Context::Scope context_scope(context);
+
+ //v8::Local<v8::Context> tmpCotext = v8::Local<v8::Context>::New(GetIsolate(), m_context);
+ v8::Local<v8::Value> propvalue = v8::Local<v8::Value>::New(GetIsolate(),((CFXJSE_Value*)hValue)->DirectGetValue());
+ context->Global()->Set(v8::String::NewFromUtf8(pIsolate, name, v8::String::kNormalString, utf8Name.GetLength()), propvalue);
+
+ return TRUE;
+}
diff --git a/fpdfsdk/src/javascript/app.cpp b/fpdfsdk/src/javascript/app.cpp
index 1c4da08ccb..42692382c8 100644
--- a/fpdfsdk/src/javascript/app.cpp
+++ b/fpdfsdk/src/javascript/app.cpp
@@ -68,6 +68,7 @@ CJS_Timer* TimerObj::GetTimer() const
#define JS_STR_PLATFORM L"WIN"
#define JS_STR_LANGUANGE L"ENU"
#define JS_STR_VIEWERVERSION 8
+#define JS_STR_VIEWERVERSION_XFA 11
#define JS_NUM_FORMSVERSION 7
#define JS_FILEPATH_MAXLEN 2000
@@ -152,8 +153,8 @@ FX_BOOL app::activeDocs(OBJ_PROP_PARAMS)
CJS_Array aDocs(pRuntime->GetIsolate());
// int iNumDocs = pApp->CountDocuments();
-// for(int iIndex = 0; iIndex<iNumDocs; iIndex++)
-// {
+// for(int iIndex = 0; iIndex<iNumDocs; iIndex++)
+// {
CPDFSDK_Document* pDoc = pApp->GetCurrentDoc();
if (pDoc)
{
@@ -209,10 +210,10 @@ FX_BOOL app::calculate(OBJ_PROP_PARAMS)
ASSERT(pRuntime != NULL);
CJS_Array aDocs(pRuntime->GetIsolate());
-// int iNumDocs = pApp->CountDocuments();
+// int iNumDocs = pApp->CountDocuments();
//
-// for (int iIndex = 0;iIndex < iNumDocs; iIndex++)
-// {
+// for (int iIndex = 0;iIndex < iNumDocs; iIndex++)
+// {
if (CPDFSDK_Document* pDoc = pApp->GetCurrentDoc())
{
CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDoc->GetInterForm();
@@ -278,7 +279,19 @@ FX_BOOL app::viewerVersion(OBJ_PROP_PARAMS)
{
if (vp.IsGetting())
{
- vp << JS_STR_VIEWERVERSION;
+ CJS_Context* pContext = (CJS_Context *)cc;
+ ASSERT(pContext != NULL);
+
+ CPDFDoc_Environment* pApp = pContext->GetReaderApp();
+ ASSERT(pApp != NULL);
+
+ CPDFSDK_Document* pCurDoc = pContext->GetReaderDocument();
+
+ CPDFXFA_Document* pDoc = pCurDoc->GetDocument();
+ if (pDoc->GetDocType() == 1 || pDoc->GetDocType() == 2)
+ vp << JS_STR_VIEWERVERSION_XFA;
+ else
+ vp << JS_STR_VIEWERVERSION;
return TRUE;
}
diff --git a/fpdfsdk/src/javascript/global.cpp b/fpdfsdk/src/javascript/global.cpp
index 295a8d49af..6bf0861e1a 100644
--- a/fpdfsdk/src/javascript/global.cpp
+++ b/fpdfsdk/src/javascript/global.cpp
@@ -13,6 +13,7 @@
#include "../../include/javascript/global.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_Context.h"
+#include "../../include/fpdfxfa/fpdfxfa_app.h"
/* ---------------------------- global ---------------------------- */
@@ -54,7 +55,7 @@ global_alternate::~global_alternate(void)
// CommitGlobalPersisitentVariables();
DestroyGlobalPersisitentVariables();
- CJS_RuntimeFactory* pFactory = m_pApp->m_pJSRuntimeFactory;
+ CJS_RuntimeFactory* pFactory = FPDFXFA_GetApp()->GetRuntimeFactory();
ASSERT(pFactory);
pFactory->ReleaseGlobalData();
@@ -64,7 +65,7 @@ void global_alternate::Initial(CPDFDoc_Environment* pApp)
{
m_pApp = pApp;
- CJS_RuntimeFactory* pFactory = pApp->m_pJSRuntimeFactory;
+ CJS_RuntimeFactory* pFactory = FPDFXFA_GetApp()->GetRuntimeFactory();
ASSERT(pFactory);
m_pGlobalData = pFactory->NewGlobalData(pApp);
UpdateGlobalPersistentVariables();
diff --git a/fpdfsdk/src/jsapi/fxjs_v8.cpp b/fpdfsdk/src/jsapi/fxjs_v8.cpp
index 5eb9873f5c..dcad30edaf 100644
--- a/fpdfsdk/src/jsapi/fxjs_v8.cpp
+++ b/fpdfsdk/src/jsapi/fxjs_v8.cpp
@@ -76,11 +76,11 @@ int JS_DefineObj(IJS_Runtime* pJSRuntime, const wchar_t* sObjName, FXJSOBJTYPE e
v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray)
{
pArray = FX_NEW CFX_PtrArray();
- isolate->SetData(0, pArray);
+ isolate->SetData(1, pArray);
}
CJS_ObjDefintion* pObjDef = FX_NEW CJS_ObjDefintion(isolate, sObjName, eObjType, pConstructor, pDestructor, bApplyNew);
pArray->Add(pObjDef);
@@ -96,7 +96,7 @@ int JS_DefineObjMethod(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* s
CFX_WideString ws = CFX_WideString((FX_LPCWSTR)sMethodName);
CFX_ByteString bsMethodName = ws.UTF8Encode();
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return 0;
if(nObjDefnID<0 || nObjDefnID>= pArray->GetSize()) return 0;
@@ -116,7 +116,7 @@ int JS_DefineObjProperty(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t*
CFX_WideString ws = CFX_WideString((FX_LPCWSTR)sPropName);
CFX_ByteString bsPropertyName = ws.UTF8Encode();
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return 0;
if(nObjDefnID<0 || nObjDefnID>= pArray->GetSize()) return 0;
@@ -133,7 +133,7 @@ int JS_DefineObjAllProperties(IJS_Runtime* pJSRuntime, int nObjDefnID, v8::Named
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return 0;
if(nObjDefnID<0 || nObjDefnID>= pArray->GetSize()) return 0;
@@ -150,7 +150,7 @@ int JS_DefineObjConst(IJS_Runtime* pJSRuntime, int nObjDefnID, const wchar_t* sC
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return 0;
CFX_WideString ws = CFX_WideString((FX_LPCWSTR)sConstName);
@@ -170,7 +170,7 @@ static v8::Persistent<v8::ObjectTemplate>& _getGlobalObjectTemplate(IJS_Runtime*
v8::Isolate::Scope isolate_scope(isolate);
v8::HandleScope handle_scope(isolate);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
ASSERT(pArray != NULL);
for(int i=0; i<pArray->GetSize(); i++)
{
@@ -234,16 +234,18 @@ void JS_InitialRuntime(IJS_Runtime* pJSRuntime,IFXJS_Runtime* pFXRuntime, IFXJS_
{
v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
v8::Isolate::Scope isolate_scope(isolate);
+ v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
v8::Persistent<v8::ObjectTemplate>& globalObjTemp = _getGlobalObjectTemplate(pJSRuntime);
v8::Handle<v8::Context> v8Context = v8::Context::New(isolate, NULL, v8::Local<v8::ObjectTemplate>::New(isolate, globalObjTemp));
v8::Context::Scope context_scope(v8Context);
- v8::Handle<v8::External> ptr = v8::External::New(isolate, pFXRuntime);
- v8Context->SetEmbedderData(1, ptr);
+ //v8::Handle<External> ptr = External::New(isolate, pFXRuntime);
+ //v8Context->SetEmbedderData(1, ptr);
+ isolate->SetData(2, pFXRuntime);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return;
for(int i=0; i<pArray->GetSize(); i++)
@@ -257,7 +259,8 @@ void JS_InitialRuntime(IJS_Runtime* pJSRuntime,IFXJS_Runtime* pFXRuntime, IFXJS_
if(pObjDef->objType == JS_DYNAMIC)
{
//Document is set as global object, need to construct it first.
- if(ws.Equal(L"Document"))
+ CFX_WideString wsString(L"Document");
+ if(ws.Equal(wsString))
{
CJS_PrivateData* pPrivateData = FX_NEW CJS_PrivateData;
@@ -284,11 +287,10 @@ void JS_ReleaseRuntime(IJS_Runtime* pJSRuntime, v8::Persistent<v8::Context>& v8P
{
v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
v8::Isolate::Scope isolate_scope(isolate);
+ v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = v8::Local<v8::Context>::New(isolate, v8PersistentContext);
- v8::Context::Scope context_scope(context);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return ;
for(int i=0; i<pArray->GetSize(); i++)
@@ -304,14 +306,15 @@ void JS_ReleaseRuntime(IJS_Runtime* pJSRuntime, v8::Persistent<v8::Context>& v8P
delete pObjDef;
}
delete pArray;
- isolate->SetData(0,NULL);
+ isolate->SetData(1,NULL);
+ isolate->SetData(2,NULL);
}
void JS_Initial()
{
-#ifndef FOXIT_CHROME_BUILD
- v8::V8::InitializeICU();
-#endif
+//#ifndef FOXIT_CHROME_BUILD
+// v8::V8::InitializeICU();
+//#endif
}
void JS_Release()
{
@@ -368,7 +371,7 @@ v8::Handle<v8::Object> JS_NewFxDynamicObj(IJS_Runtime* pJSRuntime, IFXJS_Context
return objTempl->NewInstance();
}
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return v8::Handle<v8::Object>();
@@ -396,7 +399,7 @@ v8::Handle<v8::Object> JS_GetStaticObj(IJS_Runtime* pJSRuntime, int nObjDefnID)
v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
v8::Isolate::Scope isolate_scope(isolate);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return v8::Handle<v8::Object>();
if(nObjDefnID<0 || nObjDefnID>= pArray->GetSize()) return v8::Handle<v8::Object>();
@@ -415,7 +418,7 @@ v8::Handle<v8::Object> JS_GetThisObj(IJS_Runtime * pJSRuntime)
v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
v8::Isolate::Scope isolate_scope(isolate);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return v8::Handle<v8::Object>();
v8::Local<v8::Context> context = isolate->GetCurrentContext();
@@ -445,7 +448,7 @@ int JS_GetObjDefnID(IJS_Runtime * pJSRuntime, const wchar_t* pObjName)
v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
v8::Isolate::Scope isolate_scope(isolate);
- CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(0);
+ CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(1);
if(!pArray) return -1;
for(int i=0; i<pArray->GetSize(); i++)
@@ -464,12 +467,12 @@ void JS_Error(v8::Value * pError,const wchar_t * main,const wchar_t * sub)
unsigned JS_CalcHash(const wchar_t* main, unsigned nLen)
{
- return (unsigned)FX_HashCode_String_GetW(main, nLen);
+ return (unsigned)FX_HashCode_String_GetW((FX_LPCWSTR)main, nLen);
}
unsigned JS_CalcHash(const wchar_t* main)
{
- return (unsigned)FX_HashCode_String_GetW(main, FXSYS_wcslen(main));
+ return (unsigned)FX_HashCode_String_GetW((FX_LPCWSTR)main, FXSYS_wcslen(main));
}
const wchar_t* JS_GetTypeof(v8::Handle<v8::Value> pObj)
{
diff --git a/fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp b/fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp
index 01810ffd7a..744118fb9c 100644
--- a/fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp
+++ b/fpdfsdk/src/pdfwindow/PWL_ComboBox.cpp
@@ -502,6 +502,10 @@ void CPWL_ComboBox::SetPopup(FX_BOOL bPopup)
{
if (m_pFillerNotify)
{
+ FX_BOOL bExit = FALSE;
+ m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, 0);
+ if (bExit) return;
+
FX_INT32 nWhere = 0;
FX_FLOAT fPopupRet = 0.0f;
FX_FLOAT fPopupMin = 0.0f;
@@ -529,6 +533,10 @@ void CPWL_ComboBox::SetPopup(FX_BOOL bPopup)
m_nPopupWhere = nWhere;
Move(rcWindow, TRUE, TRUE);
+
+ bExit = FALSE;
+ m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, 0);
+ if (bExit) return;
}
}
}
@@ -552,6 +560,15 @@ FX_BOOL CPWL_ComboBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag)
if (m_pList->GetCurSel() > 0)
{
FX_BOOL bExit = FALSE;
+
+ if (m_pFillerNotify)
+ {
+ m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
+ if (bExit) return FALSE;
+ bExit = FALSE;
+ m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
+ if (bExit) return FALSE;
+ }
if (m_pList->OnKeyDownWithExit(nChar,bExit,nFlag))
{
if (bExit) return FALSE;
@@ -563,6 +580,15 @@ FX_BOOL CPWL_ComboBox::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag)
if (m_pList->GetCurSel() < m_pList->GetCount() - 1)
{
FX_BOOL bExit = FALSE;
+
+ if (m_pFillerNotify)
+ {
+ m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
+ if (bExit) return FALSE;
+ bExit = FALSE;
+ m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
+ if (bExit) return FALSE;
+ }
if (m_pList->OnKeyDownWithExit(nChar,bExit,nFlag))
{
if (bExit) return FALSE;
@@ -592,6 +618,16 @@ FX_BOOL CPWL_ComboBox::OnChar(FX_WORD nChar, FX_DWORD nFlag)
}
else
{
+ if (m_pFillerNotify)
+ {
+ bExit = FALSE;
+ m_pFillerNotify->OnPopupPreOpen(GetAttachedData(), bExit, nFlag);
+ if (bExit) return FALSE;
+
+ bExit = FALSE;
+ m_pFillerNotify->OnPopupPostOpen(GetAttachedData(), bExit, nFlag);
+ if (bExit) return FALSE;
+ }
if (m_pList->OnCharWithExit(nChar,bExit,nFlag))
{
return bExit;
diff --git a/pdfium.gyp b/pdfium.gyp
index 606925c5e2..8f0ff893a1 100644
--- a/pdfium.gyp
+++ b/pdfium.gyp
@@ -48,6 +48,7 @@
'javascript',
'jsapi',
'pdfwindow',
+ 'fpdfxfa',
],
'ldflags': [ '-L<(PRODUCT_DIR)',],
'sources': [
@@ -326,13 +327,19 @@
'core/include/fxcodec/fx_codec_provider.h',
'core/src/fxcodec/codec/codec_int.h',
'core/src/fxcodec/codec/fx_codec.cpp',
+ 'core/src/fxcodec/codec/fx_codec_bmp.cpp',
'core/src/fxcodec/codec/fx_codec_fax.cpp',
'core/src/fxcodec/codec/fx_codec_flate.cpp',
+ 'core/src/fxcodec/codec/fx_codec_gif.cpp',
'core/src/fxcodec/codec/fx_codec_icc.cpp',
'core/src/fxcodec/codec/fx_codec_jbig.cpp',
'core/src/fxcodec/codec/fx_codec_jbig_enc.cpp',
'core/src/fxcodec/codec/fx_codec_jpeg.cpp',
'core/src/fxcodec/codec/fx_codec_jpx_opj.cpp',
+ 'core/src/fxcodec/codec/fx_codec_png.cpp',
+ 'core/src/fxcodec/codec/fx_codec_progress.cpp',
+ 'core/src/fxcodec/codec/fx_codec_progress.h',
+ 'core/src/fxcodec/codec/fx_codec_tiff.cpp',
'core/src/fxcodec/fx_libopenjpeg/include/fx_openjpeg.h',
'core/src/fxcodec/fx_libopenjpeg/src/fx_bio.c',
'core/src/fxcodec/fx_libopenjpeg/src/fx_cio.c',
@@ -356,6 +363,58 @@
'core/src/fxcodec/fx_libopenjpeg/src/fx_t2.c',
'core/src/fxcodec/fx_libopenjpeg/src/fx_tcd.c',
'core/src/fxcodec/fx_libopenjpeg/src/fx_tgt.c',
+ 'core/src/fxcodec/fx_lpng/include/fx_png.h',
+ 'core/src/fxcodec/fx_lpng/src/fx_png.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngerror.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngget.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngmem.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngpread.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngread.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngrio.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngrtran.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngrutil.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngset.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngtrans.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngwio.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngwrite.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngwtran.c',
+ 'core/src/fxcodec/fx_lpng/src/fx_pngwutil.c',
+ 'core/src/fxcodec/fx_tiff/include/fx_tiffiop.h',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_aux.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_close.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_codec.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_color.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_compress.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_dir.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_dirinfo.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_dirread.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_dirwrite.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_dumpmode.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_error.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_extension.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_fax3.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_fax3sm.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_flush.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_getimage.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_jpeg.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_luv.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_lzw.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_next.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_ojpeg.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_open.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_packbits.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_pixarlog.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_predict.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_print.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_read.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_strip.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_swab.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_thunder.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_tile.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_version.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_warning.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_write.c',
+ 'core/src/fxcodec/fx_tiff/src/fx_tif_zip.c',
'core/src/fxcodec/fx_zlib/include/fx_zlib.h',
'core/src/fxcodec/fx_zlib/src/fx_zlib_adler32.c',
'core/src/fxcodec/fx_zlib/src/fx_zlib_compress.c',
@@ -400,6 +459,8 @@
'core/src/fxcodec/jbig2/JBig2_Segment.h',
'core/src/fxcodec/jbig2/JBig2_SymbolDict.cpp',
'core/src/fxcodec/jbig2/JBig2_SymbolDict.h',
+ 'core/src/fxcodec/lbmp/fx_bmp.cpp',
+ 'core/src/fxcodec/lbmp/fx_bmp.h',
'core/src/fxcodec/lcms2/src/fx_cmscam02.c',
'core/src/fxcodec/lcms2/src/fx_cmscgats.c',
'core/src/fxcodec/lcms2/src/fx_cmscnvrt.c',
@@ -425,6 +486,8 @@
'core/src/fxcodec/lcms2/src/fx_cmsvirt.c',
'core/src/fxcodec/lcms2/src/fx_cmswtpnt.c',
'core/src/fxcodec/lcms2/src/fx_cmsxform.c',
+ 'core/src/fxcodec/lgif/fx_gif.cpp',
+ 'core/src/fxcodec/lgif/fx_gif.h',
'core/src/fxcodec/libjpeg/cderror.h',
'core/src/fxcodec/libjpeg/cdjpeg.h',
'core/src/fxcodec/libjpeg/fpdfapi_jcapimin.c',
@@ -733,6 +796,24 @@
],
},
{
+ 'target_name': 'fpdfxfa',
+ 'type': 'static_library',
+ 'ldflags': [ '-L<(PRODUCT_DIR)',],
+ 'dependencies': [
+ 'xfa.gyp:xfa',
+ ],
+ 'sources': [
+ 'fpdfsdk/src/fpdfxfa/fpdfxfa_app.cpp',
+ 'fpdfsdk/src/fpdfxfa/fpdfxfa_doc.cpp',
+ 'fpdfsdk/src/fpdfxfa/fpdfxfa_page.cpp',
+ 'fpdfsdk/src/fpdfxfa/fpdfxfa_util.cpp',
+ 'fpdfsdk/include/fpdfxfa/fpdfxfa_app.h',
+ 'fpdfsdk/include/fpdfxfa/fpdfxfa_doc.h',
+ 'fpdfsdk/include/fpdfxfa/fpdfxfa_page.h',
+ 'fpdfsdk/include/fpdfxfa/fpdfxfa_util.h',
+ ],
+ },
+ {
'target_name': 'javascript',
'type': 'static_library',
'include_dirs': [
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index 0f0c875f3d..a9904ab221 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -290,6 +290,7 @@ void RenderPdf(const char* name, const char* pBuf, size_t len,
(void) FPDFAvail_IsFormAvail(pdf_avail, &hints);
FPDF_FORMHANDLE form = FPDFDOC_InitFormFillEnviroument(doc, &form_callbacks);
+ FPDF_LoadXFA(doc);
FPDF_SetFormFieldHighlightColor(form, 0, 0xFFE4DD);
FPDF_SetFormFieldHighlightAlpha(form, 100);
diff --git a/xfa.gyp b/xfa.gyp
new file mode 100644
index 0000000000..3ed55692fb
--- /dev/null
+++ b/xfa.gyp
@@ -0,0 +1,715 @@
+{
+ "targets":[
+ {
+ "target_name":"xfa",
+ "type":"static_library",
+ 'dependencies': [
+ '<(DEPTH)/v8/tools/gyp/v8.gyp:v8',
+ ],
+ 'export_dependent_settings': [
+ '<(DEPTH)/v8/tools/gyp/v8.gyp:v8',
+ ],
+ 'include_dirs': [
+ '<(DEPTH)/v8',
+ '<(DEPTH)/v8/include',
+ ],
+ "sources":[
+ "xfa/include/foxitxfa.h",
+ "xfa/include/fwl/adapter/fwl_adapterclipboardmgr.h",
+ "xfa/include/fwl/adapter/fwl_adaptercursormgr.h",
+ "xfa/include/fwl/adapter/fwl_adaptermonitormgr.h",
+ "xfa/include/fwl/adapter/fwl_adapternative.h",
+ "xfa/include/fwl/adapter/fwl_adapterthreadmgr.h",
+ "xfa/include/fwl/adapter/fwl_adaptertimermgr.h",
+ "xfa/include/fwl/adapter/fwl_adapterwidgetmgr.h",
+ "xfa/include/fwl/adapter/fwl_sdadapterimp.h",
+ "xfa/include/fwl/basewidget/fwl_barcode.h",
+ "xfa/include/fwl/basewidget/fwl_caret.h",
+ "xfa/include/fwl/basewidget/fwl_checkbox.h",
+ "xfa/include/fwl/basewidget/fwl_combobox.h",
+ "xfa/include/fwl/basewidget/fwl_datetimepicker.h",
+ "xfa/include/fwl/basewidget/fwl_edit.h",
+ "xfa/include/fwl/basewidget/fwl_listbox.h",
+ "xfa/include/fwl/basewidget/fwl_menu.h",
+ "xfa/include/fwl/basewidget/fwl_monthcalendar.h",
+ "xfa/include/fwl/basewidget/fwl_picturebox.h",
+ "xfa/include/fwl/basewidget/fwl_pushbutton.h",
+ "xfa/include/fwl/basewidget/fwl_scrollbar.h",
+ "xfa/include/fwl/basewidget/fwl_spinbutton.h",
+ "xfa/include/fwl/basewidget/fwl_tooltipctrl.h",
+ "xfa/include/fwl/basewidget/fxmath_barcode.h",
+ "xfa/include/fwl/core/fwl_app.h",
+ "xfa/include/fwl/core/fwl_content.h",
+ "xfa/include/fwl/core/fwl_error.h",
+ "xfa/include/fwl/core/fwl_form.h",
+ "xfa/include/fwl/core/fwl_grid.h",
+ "xfa/include/fwl/core/fwl_note.h",
+ "xfa/include/fwl/core/fwl_panel.h",
+ "xfa/include/fwl/core/fwl_target.h",
+ "xfa/include/fwl/core/fwl_theme.h",
+ "xfa/include/fwl/core/fwl_thread.h",
+ "xfa/include/fwl/core/fwl_timer.h",
+ "xfa/include/fwl/core/fwl_widget.h",
+ "xfa/include/fwl/core/fwl_widgetdef.h",
+ "xfa/include/fwl/core/fwl_widgetmgr.h",
+ "xfa/include/fwl/fwl.h",
+ "xfa/include/fwl/lightwidget/app.h",
+ "xfa/include/fwl/lightwidget/barcode.h",
+ "xfa/include/fwl/lightwidget/caret.h",
+ "xfa/include/fwl/lightwidget/checkbox.h",
+ "xfa/include/fwl/lightwidget/combobox.h",
+ "xfa/include/fwl/lightwidget/datetimepicker.h",
+ "xfa/include/fwl/lightwidget/edit.h",
+ "xfa/include/fwl/lightwidget/listbox.h",
+ "xfa/include/fwl/lightwidget/picturebox.h",
+ "xfa/include/fwl/lightwidget/pushbutton.h",
+ "xfa/include/fwl/lightwidget/scrollbar.h",
+ "xfa/include/fwl/lightwidget/theme.h",
+ "xfa/include/fwl/lightwidget/tooltipctrl.h",
+ "xfa/include/fwl/lightwidget/widget.h",
+ "xfa/include/fwl/theme/barcodetp.h",
+ "xfa/include/fwl/theme/carettp.h",
+ "xfa/include/fwl/theme/checkboxtp.h",
+ "xfa/include/fwl/theme/comboboxtp.h",
+ "xfa/include/fwl/theme/datetimepickertp.h",
+ "xfa/include/fwl/theme/edittp.h",
+ "xfa/include/fwl/theme/formtp.h",
+ "xfa/include/fwl/theme/listboxtp.h",
+ "xfa/include/fwl/theme/monthcalendartp.h",
+ "xfa/include/fwl/theme/pictureboxtp.h",
+ "xfa/include/fwl/theme/pushbuttontp.h",
+ "xfa/include/fwl/theme/scrollbartp.h",
+ "xfa/include/fwl/theme/utils.h",
+ "xfa/include/fwl/theme/widgettp.h",
+ "xfa/include/fxbarcode/BC_BarCode.h",
+ "xfa/include/fxfa/fxfa.h",
+ "xfa/include/fxfa/fxfa_basic.h",
+ "xfa/include/fxfa/fxfa_objectacc.h",
+ "xfa/include/fxfa/fxfa_widget.h",
+ "xfa/include/fxgraphics/fx_graphics.h",
+ "xfa/include/fxjse/fxjse.h",
+ "xfa/src/fdp/include/fde.h",
+ "xfa/src/fdp/include/fde_brs.h",
+ "xfa/src/fdp/include/fde_css.h",
+ "xfa/src/fdp/include/fde_img.h",
+ "xfa/src/fdp/include/fde_mem.h",
+ "xfa/src/fdp/include/fde_pen.h",
+ "xfa/src/fdp/include/fde_psr.h",
+ "xfa/src/fdp/include/fde_pth.h",
+ "xfa/src/fdp/include/fde_rdr.h",
+ "xfa/src/fdp/include/fde_rdv.h",
+ "xfa/src/fdp/include/fde_tto.h",
+ "xfa/src/fdp/include/fde_xml.h",
+ "xfa/src/fdp/src/css/fde_csscache.cpp",
+ "xfa/src/fdp/src/css/fde_csscache.h",
+ "xfa/src/fdp/src/css/fde_cssdatatable.cpp",
+ "xfa/src/fdp/src/css/fde_cssdatatable.h",
+ "xfa/src/fdp/src/css/fde_cssdeclaration.cpp",
+ "xfa/src/fdp/src/css/fde_cssdeclaration.h",
+ "xfa/src/fdp/src/css/fde_cssstyleselector.cpp",
+ "xfa/src/fdp/src/css/fde_cssstyleselector.h",
+ "xfa/src/fdp/src/css/fde_cssstylesheet.cpp",
+ "xfa/src/fdp/src/css/fde_cssstylesheet.h",
+ "xfa/src/fdp/src/css/fde_csssyntax.cpp",
+ "xfa/src/fdp/src/css/fde_csssyntax.h",
+ "xfa/src/fdp/src/fde/fde_devbasic.cpp",
+ "xfa/src/fdp/src/fde/fde_devbasic.h",
+ "xfa/src/fdp/src/fde/fde_gedevice.cpp",
+ "xfa/src/fdp/src/fde/fde_gedevice.h",
+ "xfa/src/fdp/src/fde/fde_geobject.cpp",
+ "xfa/src/fdp/src/fde/fde_geobject.h",
+ "xfa/src/fdp/src/fde/fde_iterator.cpp",
+ "xfa/src/fdp/src/fde/fde_iterator.h",
+ "xfa/src/fdp/src/fde/fde_object.cpp",
+ "xfa/src/fdp/src/fde/fde_object.h",
+ "xfa/src/fdp/src/fde/fde_render.cpp",
+ "xfa/src/fdp/src/fde/fde_render.h",
+ "xfa/src/fdp/src/tto/fde_textout.cpp",
+ "xfa/src/fdp/src/tto/fde_textout.h",
+ "xfa/src/fdp/src/xml/fde_xml.cpp",
+ "xfa/src/fdp/src/xml/fde_xml.h",
+ "xfa/src/fee/include/fx_wordbreak.h",
+ "xfa/src/fee/include/ifde_txtedtbuf.h",
+ "xfa/src/fee/include/ifde_txtedtengine.h",
+ "xfa/src/fee/include/ifde_txtedtpage.h",
+ "xfa/src/fee/src/fee/fde_txtedtblock.cpp",
+ "xfa/src/fee/src/fee/fde_txtedtblock.h",
+ "xfa/src/fee/src/fee/fde_txtedtbuf.cpp",
+ "xfa/src/fee/src/fee/fde_txtedtbuf.h",
+ "xfa/src/fee/src/fee/fde_txtedtengine.cpp",
+ "xfa/src/fee/src/fee/fde_txtedtengine.h",
+ "xfa/src/fee/src/fee/fde_txtedtkmpmatch.cpp",
+ "xfa/src/fee/src/fee/fde_txtedtkmpmatch.h",
+ "xfa/src/fee/src/fee/fde_txtedtpage.cpp",
+ "xfa/src/fee/src/fee/fde_txtedtpage.h",
+ "xfa/src/fee/src/fee/fde_txtedtparag.cpp",
+ "xfa/src/fee/src/fee/fde_txtedtparag.h",
+ "xfa/src/fee/src/fx_wordbreak/fx_wordbreakdata.cpp",
+ "xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.cpp",
+ "xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.h",
+ "xfa/src/fgas/include/fgas.h",
+ "xfa/src/fgas/include/fx_alg.h",
+ "xfa/src/fgas/include/fx_cpg.h",
+ "xfa/src/fgas/include/fx_datetime.h",
+ "xfa/src/fgas/include/fx_fnt.h",
+ "xfa/src/fgas/include/fx_lbk.h",
+ "xfa/src/fgas/include/fx_lgg.h",
+ "xfa/src/fgas/include/fx_locale.h",
+ "xfa/src/fgas/include/fx_mem.h",
+ "xfa/src/fgas/include/fx_rbk.h",
+ "xfa/src/fgas/include/fx_sax.h",
+ "xfa/src/fgas/include/fx_stm.h",
+ "xfa/src/fgas/include/fx_sys.h",
+ "xfa/src/fgas/include/fx_tbk.h",
+ "xfa/src/fgas/include/fx_ucd.h",
+ "xfa/src/fgas/include/fx_utl.h",
+ "xfa/src/fgas/src/crt/fx_algorithm.cpp",
+ "xfa/src/fgas/src/crt/fx_codepage.cpp",
+ "xfa/src/fgas/src/crt/fx_codepage.h",
+ "xfa/src/fgas/src/crt/fx_encode.cpp",
+ "xfa/src/fgas/src/crt/fx_memory.cpp",
+ "xfa/src/fgas/src/crt/fx_memory.h",
+ "xfa/src/fgas/src/crt/fx_stream.cpp",
+ "xfa/src/fgas/src/crt/fx_stream.h",
+ "xfa/src/fgas/src/crt/fx_system.cpp",
+ "xfa/src/fgas/src/crt/fx_utils.cpp",
+ "xfa/src/fgas/src/crt/fx_utils.h",
+ "xfa/src/fgas/src/fgas_base.h",
+ "xfa/src/fgas/src/font/fx_fontutils.cpp",
+ "xfa/src/fgas/src/font/fx_fontutils.h",
+ "xfa/src/fgas/src/font/fx_gefont.cpp",
+ "xfa/src/fgas/src/font/fx_gefont.h",
+ "xfa/src/fgas/src/font/fx_stdfontmgr.cpp",
+ "xfa/src/fgas/src/font/fx_stdfontmgr.h",
+ "xfa/src/fgas/src/layout/fx_linebreak.cpp",
+ "xfa/src/fgas/src/layout/fx_rtfbreak.cpp",
+ "xfa/src/fgas/src/layout/fx_rtfbreak.h",
+ "xfa/src/fgas/src/layout/fx_textbreak.cpp",
+ "xfa/src/fgas/src/layout/fx_textbreak.h",
+ "xfa/src/fgas/src/layout/fx_unicode.cpp",
+ "xfa/src/fgas/src/layout/fx_unicode.h",
+ "xfa/src/fgas/src/localization/fx_datetime.cpp",
+ "xfa/src/fgas/src/localization/fx_locale.cpp",
+ "xfa/src/fgas/src/localization/fx_localeimp.h",
+ "xfa/src/fgas/src/localization/fx_localemgr.cpp",
+ "xfa/src/fgas/src/localization/fx_localemgr.h",
+ "xfa/src/fgas/src/xml/fx_sax_imp.cpp",
+ "xfa/src/fgas/src/xml/fx_sax_imp.h",
+ "xfa/src/foxitlib.h",
+ "xfa/src/fwl/src/basewidget/fwl_barcodeimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_caretimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_checkboximp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_comboboximp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_datetimepickerimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_editimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_formproxyimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_listboximp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_monthcalendarimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_pictureboximp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_pushbuttonimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_scrollbarimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_spinbuttonimp.cpp",
+ "xfa/src/fwl/src/basewidget/fwl_tooltipctrlimp.cpp",
+ "xfa/src/fwl/src/basewidget/fxmath_barcodeimp.cpp",
+ "xfa/src/fwl/src/basewidget/include/fwl_barcodeimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_caretimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_checkboximp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_datetimepickerimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_editimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_listboximp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_monthcalendarimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_pictureboximp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_pushbuttonimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_spinbuttonimp.h",
+ "xfa/src/fwl/src/basewidget/include/fwl_tooltipctrlimp.h",
+ "xfa/src/fwl/src/basewidget/include/fxmath_barcodeimp.h",
+ "xfa/src/fwl/src/core/fwl_appimp.cpp",
+ "xfa/src/fwl/src/core/fwl_contentimp.cpp",
+ "xfa/src/fwl/src/core/fwl_formimp.cpp",
+ "xfa/src/fwl/src/core/fwl_gridimp.cpp",
+ "xfa/src/fwl/src/core/fwl_noteimp.cpp",
+ "xfa/src/fwl/src/core/fwl_panelimp.cpp",
+ "xfa/src/fwl/src/core/fwl_sdadapterimp.cpp",
+ "xfa/src/fwl/src/core/fwl_targetimp.cpp",
+ "xfa/src/fwl/src/core/fwl_threadimp.cpp",
+ "xfa/src/fwl/src/core/fwl_timerimp.cpp",
+ "xfa/src/fwl/src/core/fwl_widgetimp.cpp",
+ "xfa/src/fwl/src/core/fwl_widgetmgrimp.cpp",
+ "xfa/src/fwl/src/core/include/fwl_appimp.h",
+ "xfa/src/fwl/src/core/include/fwl_contentimp.h",
+ "xfa/src/fwl/src/core/include/fwl_formimp.h",
+ "xfa/src/fwl/src/core/include/fwl_gridimp.h",
+ "xfa/src/fwl/src/core/include/fwl_noteimp.h",
+ "xfa/src/fwl/src/core/include/fwl_panelimp.h",
+ "xfa/src/fwl/src/core/include/fwl_targetimp.h",
+ "xfa/src/fwl/src/core/include/fwl_threadimp.h",
+ "xfa/src/fwl/src/core/include/fwl_widgetimp.h",
+ "xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h",
+ "xfa/src/fwl/src/lightwidget/app.cpp",
+ "xfa/src/fwl/src/lightwidget/barcode.cpp",
+ "xfa/src/fwl/src/lightwidget/caret.cpp",
+ "xfa/src/fwl/src/lightwidget/checkbox.cpp",
+ "xfa/src/fwl/src/lightwidget/combobox.cpp",
+ "xfa/src/fwl/src/lightwidget/datetimepicker.cpp",
+ "xfa/src/fwl/src/lightwidget/edit.cpp",
+ "xfa/src/fwl/src/lightwidget/listbox.cpp",
+ "xfa/src/fwl/src/lightwidget/picturebox.cpp",
+ "xfa/src/fwl/src/lightwidget/pushbutton.cpp",
+ "xfa/src/fwl/src/lightwidget/scrollbar.cpp",
+ "xfa/src/fwl/src/lightwidget/theme.cpp",
+ "xfa/src/fwl/src/lightwidget/tooltipctrl.cpp",
+ "xfa/src/fwl/src/lightwidget/widget.cpp",
+ "xfa/src/fwl/src/theme/barcodetp.cpp",
+ "xfa/src/fwl/src/theme/carettp.cpp",
+ "xfa/src/fwl/src/theme/checkboxtp.cpp",
+ "xfa/src/fwl/src/theme/comboboxtp.cpp",
+ "xfa/src/fwl/src/theme/datetimepickertp.cpp",
+ "xfa/src/fwl/src/theme/edittp.cpp",
+ "xfa/src/fwl/src/theme/formtp.cpp",
+ "xfa/src/fwl/src/theme/listboxtp.cpp",
+ "xfa/src/fwl/src/theme/monthcalendartp.cpp",
+ "xfa/src/fwl/src/theme/pictureboxtp.cpp",
+ "xfa/src/fwl/src/theme/pushbuttontp.cpp",
+ "xfa/src/fwl/src/theme/scrollbartp.cpp",
+ "xfa/src/fwl/src/theme/widgettp.cpp",
+ "xfa/src/fxbarcode/src/barcode.h",
+ "xfa/src/fxbarcode/src/BC_ASCIIEncoder.cpp",
+ "xfa/src/fxbarcode/src/BC_BarCode.cpp",
+ "xfa/src/fxbarcode/src/BC_Base256Encoder.cpp",
+ "xfa/src/fxbarcode/src/BC_Binarizer.cpp",
+ "xfa/src/fxbarcode/src/BC_BinaryBitmap.cpp",
+ "xfa/src/fxbarcode/src/BC_BufferedImageLuminanceSource.cpp",
+ "xfa/src/fxbarcode/src/BC_C40Encoder.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonBitArray.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonBitMatrix.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonBitSource.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonByteArray.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonByteMatrix.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonCharacterSetECI.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonDecoderResult.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonECI.cpp",
+ "xfa/src/fxbarcode/src/BC_CommonPerspectiveTransform.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixBitMatrixParser.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixDataBlock.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixDecodedBitStreamParser.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixDecoder.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixDetector.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixReader.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixSymbolInfo144.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixVersion.cpp",
+ "xfa/src/fxbarcode/src/BC_DataMatrixWriter.cpp",
+ "xfa/src/fxbarcode/src/BC_DefaultPlacement.cpp",
+ "xfa/src/fxbarcode/src/BC_Dimension.cpp",
+ "xfa/src/fxbarcode/src/BC_EdifactEncoder.cpp",
+ "xfa/src/fxbarcode/src/BC_Encoder.cpp",
+ "xfa/src/fxbarcode/src/BC_EncoderContext.cpp",
+ "xfa/src/fxbarcode/src/BC_ErrorCorrection.cpp",
+ "xfa/src/fxbarcode/src/BC_FinderPatternInfo.cpp",
+ "xfa/src/fxbarcode/src/BC_GlobalHistogramBinarizer.cpp",
+ "xfa/src/fxbarcode/src/BC_HighLevelEncoder.cpp",
+ "xfa/src/fxbarcode/src/BC_Library.cpp",
+ "xfa/src/fxbarcode/src/BC_LuminanceSource.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedCodaBarReader.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedCodaBarWriter.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedCode128Reader.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedCode128Writer.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedCode39Reader.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedCode39Writer.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedEAN13Reader.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedEAN13Writer.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedEAN8Reader.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedEAN8Writer.cpp",
+ "xfa/src/fxbarcode/src/BC_OneDimReader.cpp",
+ "xfa/src/fxbarcode/src/BC_OneDimWriter.cpp",
+ "xfa/src/fxbarcode/src/BC_OneDReader.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedUPCAReader.cpp",
+ "xfa/src/fxbarcode/src/BC_OnedUPCAWriter.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417BarcodeMatrix.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417BarcodeMetadata.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417BarcodeRow.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417BarcodeValue.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417BoundingBox.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417Codeword.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417CodewordDecoder.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417Common.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417Compaction.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417DecodedBitStreamParser.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417DetectionResult.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417DetectionResultColumn.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417DetectionResultRowIndicatorColumn.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417Detector.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417DetectorResult.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417Dimensions.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417ECErrorCorrection.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417ECModulusGF.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417ECModulusPoly.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417ErrorCorrection.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417HighLevelEncoder.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417Reader.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417ResultMetadata.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417ScanningDecoder.cpp",
+ "xfa/src/fxbarcode/src/BC_PDF417Writer.cpp",
+ "xfa/src/fxbarcode/src/BC_QRAlignmentPattern.cpp",
+ "xfa/src/fxbarcode/src/BC_QRAlignmentPatternFinder.cpp",
+ "xfa/src/fxbarcode/src/BC_QRBitMatrixParser.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoder.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderBitVector.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderBlockPair.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderDecoder.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCodeReader.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderECB.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderECBlocks.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderEncoder.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderErrorCorrectionLevel.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderFormatInformation.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderMaskUtil.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderMatrixUtil.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderMode.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCoderVersion.cpp",
+ "xfa/src/fxbarcode/src/BC_QRCodeWriter.cpp",
+ "xfa/src/fxbarcode/src/BC_QRDataBlock.cpp",
+ "xfa/src/fxbarcode/src/BC_QRDataMask.cpp",
+ "xfa/src/fxbarcode/src/BC_QRDecodedBitStreamParser.cpp",
+ "xfa/src/fxbarcode/src/BC_QRDetector.cpp",
+ "xfa/src/fxbarcode/src/BC_QRDetectorResult.cpp",
+ "xfa/src/fxbarcode/src/BC_QRFinderPattern.cpp",
+ "xfa/src/fxbarcode/src/BC_QRFinderPatternFinder.cpp",
+ "xfa/src/fxbarcode/src/BC_QRGridSampler.cpp",
+ "xfa/src/fxbarcode/src/BC_Reader.cpp",
+ "xfa/src/fxbarcode/src/BC_ReedSolomon.cpp",
+ "xfa/src/fxbarcode/src/BC_ReedSolomonDecoder.cpp",
+ "xfa/src/fxbarcode/src/BC_ReedSolomonGF256.cpp",
+ "xfa/src/fxbarcode/src/BC_ReedSolomonGF256Poly.cpp",
+ "xfa/src/fxbarcode/src/BC_ResultPoint.cpp",
+ "xfa/src/fxbarcode/src/BC_SymbolInfo.cpp",
+ "xfa/src/fxbarcode/src/BC_SymbolShapeHint.cpp",
+ "xfa/src/fxbarcode/src/BC_TextEncoder.cpp",
+ "xfa/src/fxbarcode/src/BC_TwoDimWriter.cpp",
+ "xfa/src/fxbarcode/src/BC_UtilCodingConvert.cpp",
+ "xfa/src/fxbarcode/src/BC_UtilRSS.cpp",
+ "xfa/src/fxbarcode/src/BC_Utils.cpp",
+ "xfa/src/fxbarcode/src/BC_WhiteRectangleDetector.cpp",
+ "xfa/src/fxbarcode/src/BC_Writer.cpp",
+ "xfa/src/fxbarcode/src/BC_X12Encoder.cpp",
+ "xfa/src/fxbarcode/src/include/BC_ASCIIEncoder.h",
+ "xfa/src/fxbarcode/src/include/BC_Base256Encoder.h",
+ "xfa/src/fxbarcode/src/include/BC_Binarizer.h",
+ "xfa/src/fxbarcode/src/include/BC_BinaryBitmap.h",
+ "xfa/src/fxbarcode/src/include/BC_BufferedImageLuminanceSource.h",
+ "xfa/src/fxbarcode/src/include/BC_C40Encoder.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonBitArray.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonBitMatrix.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonBitSource.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonByteArray.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonByteMatrix.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonCharacterSetECI.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonDecoderResult.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonECI.h",
+ "xfa/src/fxbarcode/src/include/BC_CommonPerspectiveTransform.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixBitMatrixParser.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixDataBlock.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixDecodedBitStreamParser.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixDecoder.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixDetector.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixReader.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixSymbolInfo144.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixVersion.h",
+ "xfa/src/fxbarcode/src/include/BC_DataMatrixWriter.h",
+ "xfa/src/fxbarcode/src/include/BC_DecoderResult.h",
+ "xfa/src/fxbarcode/src/include/BC_DefaultPlacement.h",
+ "xfa/src/fxbarcode/src/include/BC_Dimension.h",
+ "xfa/src/fxbarcode/src/include/BC_EdifactEncoder.h",
+ "xfa/src/fxbarcode/src/include/BC_Encoder.h",
+ "xfa/src/fxbarcode/src/include/BC_EncoderContext.h",
+ "xfa/src/fxbarcode/src/include/BC_ErrorCorrection.h",
+ "xfa/src/fxbarcode/src/include/BC_FinderPatternInfo.h",
+ "xfa/src/fxbarcode/src/include/BC_GlobalHistogramBinarizer.h",
+ "xfa/src/fxbarcode/src/include/BC_HighLevelEncoder.h",
+ "xfa/src/fxbarcode/src/include/BC_LuminanceSource.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedCodaBarReader.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedCodaBarWriter.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedCode128Reader.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedCode128Writer.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedCode39Reader.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedCode39Writer.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedEAN13Reader.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedEAN13Writer.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedEAN8Reader.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedEAN8Writer.h",
+ "xfa/src/fxbarcode/src/include/BC_OneDimReader.h",
+ "xfa/src/fxbarcode/src/include/BC_OneDimWriter.h",
+ "xfa/src/fxbarcode/src/include/BC_OneDReader.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedUPCAReader.h",
+ "xfa/src/fxbarcode/src/include/BC_OnedUPCAWriter.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMatrix.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMetadata.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417BarcodeRow.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417BarcodeValue.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417BoundingBox.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417Codeword.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417CodewordDecoder.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417Common.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417Compaction.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417DecodedBitStreamParser.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417DetectionResult.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultColumn.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultRowIndicatorColumn.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417Detector.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417DetectorResult.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417Dimensions.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417ECErrorCorrection.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417ECModulusGF.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417ECModulusPoly.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417ErrorCorrection.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417HighLevelEncoder.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417Reader.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417ResultMetadata.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417ScanningDecoder.h",
+ "xfa/src/fxbarcode/src/include/BC_PDF417Writer.h",
+ "xfa/src/fxbarcode/src/include/BC_QRAlignmentPattern.h",
+ "xfa/src/fxbarcode/src/include/BC_QRAlignmentPatternFinder.h",
+ "xfa/src/fxbarcode/src/include/BC_QRBitMatrixParser.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoder.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderBitVector.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderBlockPair.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderDecoder.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCodeReader.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderECB.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderECBlocks.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderEncoder.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderErrorCorrectionLevel.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderFormatInformation.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderMaskUtil.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderMatrixUtil.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderMode.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCoderVersion.h",
+ "xfa/src/fxbarcode/src/include/BC_QRCodeWriter.h",
+ "xfa/src/fxbarcode/src/include/BC_QRDataBlock.h",
+ "xfa/src/fxbarcode/src/include/BC_QRDataMask.h",
+ "xfa/src/fxbarcode/src/include/BC_QRDecodedBitStreamParser.h",
+ "xfa/src/fxbarcode/src/include/BC_QRDetector.h",
+ "xfa/src/fxbarcode/src/include/BC_QRDetectorResult.h",
+ "xfa/src/fxbarcode/src/include/BC_QRFinderPattern.h",
+ "xfa/src/fxbarcode/src/include/BC_QRFinderPatternFinder.h",
+ "xfa/src/fxbarcode/src/include/BC_QRGridSampler.h",
+ "xfa/src/fxbarcode/src/include/BC_Reader.h",
+ "xfa/src/fxbarcode/src/include/BC_ReedSolomon.h",
+ "xfa/src/fxbarcode/src/include/BC_ReedSolomonDecoder.h",
+ "xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256.h",
+ "xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256Poly.h",
+ "xfa/src/fxbarcode/src/include/BC_ResultPoint.h",
+ "xfa/src/fxbarcode/src/include/BC_SymbolInfo.h",
+ "xfa/src/fxbarcode/src/include/BC_SymbolShapeHint.h",
+ "xfa/src/fxbarcode/src/include/BC_TextEncoder.h",
+ "xfa/src/fxbarcode/src/include/BC_TwoDimWriter.h",
+ "xfa/src/fxbarcode/src/include/BC_UtilCodingConvert.h",
+ "xfa/src/fxbarcode/src/include/BC_UtilRSS.h",
+ "xfa/src/fxbarcode/src/include/BC_WhiteRectangleDetector.h",
+ "xfa/src/fxbarcode/src/include/BC_Writer.h",
+ "xfa/src/fxbarcode/src/include/BC_X12Encoder.h",
+ "xfa/src/fxbarcode/src/include/utils.h",
+ "xfa/src/fxfa/src/app/xfa_checksum.cpp",
+ "xfa/src/fxfa/src/app/xfa_checksum.h",
+ "xfa/src/fxfa/src/app/xfa_ffapp.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffapp.h",
+ "xfa/src/fxfa/src/app/xfa_ffbarcode.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffbarcode.h",
+ "xfa/src/fxfa/src/app/xfa_ffcheckbutton.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffcheckbutton.h",
+ "xfa/src/fxfa/src/app/xfa_ffchoicelist.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffchoicelist.h",
+ "xfa/src/fxfa/src/app/xfa_ffConfigAcc.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffConfigAcc.h",
+ "xfa/src/fxfa/src/app/xfa_ffdoc.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffdoc.h",
+ "xfa/src/fxfa/src/app/xfa_ffdochandler.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffdochandler.h",
+ "xfa/src/fxfa/src/app/xfa_ffdocview.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffdocview.h",
+ "xfa/src/fxfa/src/app/xfa_ffdraw.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffdraw.h",
+ "xfa/src/fxfa/src/app/xfa_ffexclgroup.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffexclgroup.h",
+ "xfa/src/fxfa/src/app/xfa_fffield.cpp",
+ "xfa/src/fxfa/src/app/xfa_fffield.h",
+ "xfa/src/fxfa/src/app/xfa_ffimage.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffimage.h",
+ "xfa/src/fxfa/src/app/xfa_ffimageedit.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffimageedit.h",
+ "xfa/src/fxfa/src/app/xfa_ffnotify.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffnotify.h",
+ "xfa/src/fxfa/src/app/xfa_ffpageview.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffpageview.h",
+ "xfa/src/fxfa/src/app/xfa_ffpath.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffpath.h",
+ "xfa/src/fxfa/src/app/xfa_ffpushbutton.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffpushbutton.h",
+ "xfa/src/fxfa/src/app/xfa_ffsignature.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffsignature.h",
+ "xfa/src/fxfa/src/app/xfa_ffsubform.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffsubform.h",
+ "xfa/src/fxfa/src/app/xfa_fftext.cpp",
+ "xfa/src/fxfa/src/app/xfa_fftext.h",
+ "xfa/src/fxfa/src/app/xfa_fftextedit.cpp",
+ "xfa/src/fxfa/src/app/xfa_fftextedit.h",
+ "xfa/src/fxfa/src/app/xfa_ffwidget.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffwidget.h",
+ "xfa/src/fxfa/src/app/xfa_ffwidgetacc.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffwidgetacc.h",
+ "xfa/src/fxfa/src/app/xfa_ffwidgethandler.cpp",
+ "xfa/src/fxfa/src/app/xfa_ffwidgethandler.h",
+ "xfa/src/fxfa/src/app/xfa_fontmgr.cpp",
+ "xfa/src/fxfa/src/app/xfa_fontmgr.h",
+ "xfa/src/fxfa/src/app/xfa_fwladapter.cpp",
+ "xfa/src/fxfa/src/app/xfa_fwladapter.h",
+ "xfa/src/fxfa/src/app/xfa_fwltheme.cpp",
+ "xfa/src/fxfa/src/app/xfa_fwltheme.h",
+ "xfa/src/fxfa/src/app/xfa_rendercontext.cpp",
+ "xfa/src/fxfa/src/app/xfa_rendercontext.h",
+ "xfa/src/fxfa/src/app/xfa_textlayout.cpp",
+ "xfa/src/fxfa/src/app/xfa_textlayout.h",
+ "xfa/src/fxfa/src/common/fxfa_localevalue.h",
+ "xfa/src/fxfa/src/common/xfa_common.h",
+ "xfa/src/fxfa/src/common/xfa_debug.h",
+ "xfa/src/fxfa/src/common/xfa_docdata.h",
+ "xfa/src/fxfa/src/common/xfa_doclayout.h",
+ "xfa/src/fxfa/src/common/xfa_document.h",
+ "xfa/src/fxfa/src/common/xfa_fm2jsapi.h",
+ "xfa/src/fxfa/src/common/xfa_localemgr.h",
+ "xfa/src/fxfa/src/common/xfa_object.h",
+ "xfa/src/fxfa/src/common/xfa_parser.h",
+ "xfa/src/fxfa/src/common/xfa_script.h",
+ "xfa/src/fxfa/src/common/xfa_utils.h",
+ "xfa/src/fxfa/src/fm2js/xfa_error.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_error.h",
+ "xfa/src/fxfa/src/fm2js/xfa_expression.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_expression.h",
+ "xfa/src/fxfa/src/fm2js/xfa_fm2js.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_fm2js.h",
+ "xfa/src/fxfa/src/fm2js/xfa_fm2jsapi.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.h",
+ "xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_fmparse.h",
+ "xfa/src/fxfa/src/fm2js/xfa_lexer.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_lexer.h",
+ "xfa/src/fxfa/src/fm2js/xfa_program.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_program.h",
+ "xfa/src/fxfa/src/fm2js/xfa_simpleexpression.cpp",
+ "xfa/src/fxfa/src/fm2js/xfa_simpleexpression.h",
+ "xfa/src/fxfa/src/parser/xfa_basic_data.cpp",
+ "xfa/src/fxfa/src/parser/xfa_basic_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_basic_imp.h",
+ "xfa/src/fxfa/src/parser/xfa_debug_parser.cpp",
+ "xfa/src/fxfa/src/parser/xfa_debug_parser.h",
+ "xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.h",
+ "xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.h",
+ "xfa/src/fxfa/src/parser/xfa_document_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_document_imp.h",
+ "xfa/src/fxfa/src/parser/xfa_document_layout_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_document_layout_imp.h",
+ "xfa/src/fxfa/src/parser/xfa_document_serialize.cpp",
+ "xfa/src/fxfa/src/parser/xfa_document_serialize.h",
+ "xfa/src/fxfa/src/parser/xfa_layout_appadapter.cpp",
+ "xfa/src/fxfa/src/parser/xfa_layout_appadapter.h",
+ "xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp",
+ "xfa/src/fxfa/src/parser/xfa_layout_itemlayout.h",
+ "xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.cpp",
+ "xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.h",
+ "xfa/src/fxfa/src/parser/xfa_locale.cpp",
+ "xfa/src/fxfa/src/parser/xfa_locale.h",
+ "xfa/src/fxfa/src/parser/xfa_localemgr.cpp",
+ "xfa/src/fxfa/src/parser/xfa_localevalue.cpp",
+ "xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_object_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_parser_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_parser_imp.h",
+ "xfa/src/fxfa/src/parser/xfa_script_datawindow.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_datawindow.h",
+ "xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.h",
+ "xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.h",
+ "xfa/src/fxfa/src/parser/xfa_script_imp.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_imp.h",
+ "xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.h",
+ "xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.h",
+ "xfa/src/fxfa/src/parser/xfa_script_nodehelper.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_nodehelper.h",
+ "xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.h",
+ "xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.cpp",
+ "xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.h",
+ "xfa/src/fxfa/src/parser/xfa_utils_imp.cpp",
+ "xfa/src/fxgraphics/src/fx_graphics.cpp",
+ "xfa/src/fxgraphics/src/fx_path_generator.cpp",
+ "xfa/src/fxgraphics/src/fx_path_generator.h",
+ "xfa/src/fxgraphics/src/pre.h",
+ "xfa/src/fxjse/src/class.cpp",
+ "xfa/src/fxjse/src/class.h",
+ "xfa/src/fxjse/src/context.cpp",
+ "xfa/src/fxjse/src/context.h",
+ "xfa/src/fxjse/src/dynprop.cpp",
+ "xfa/src/fxjse/src/runtime.cpp",
+ "xfa/src/fxjse/src/runtime.h",
+ "xfa/src/fxjse/src/scope_inline.h",
+ "xfa/src/fxjse/src/util_inline.h",
+ "xfa/src/fxjse/src/value.cpp",
+ "xfa/src/fxjse/src/value.h"
+ ],
+ "conditions":[
+ [
+ "OS == 'win'",
+ {
+ "configurations":{
+ "Debug":{
+ "msvs_configuration_attributes":{
+ },
+ "msvs_settings":{
+ "VCCLCompilerTool":{
+ },
+ "VCLibrarianTool":{
+ },
+ "VCLinkerTool":{
+ }
+ }
+ },
+ "Release":{
+ "msvs_configuration_attributes":{
+ },
+ "msvs_settings":{
+ "VCCLCompilerTool":{
+ },
+ "VCLibrarianTool":{
+ },
+ "VCLinkerTool":{
+ }
+ }
+ }
+ },
+ "sources":[
+ ]
+ }
+ ],
+ [
+ "OS == 'mac'",
+ {
+ "configurations":{
+ },
+ "sources":[
+ ]
+ }
+ ]
+ ]
+ }
+ ]
+}
diff --git a/xfa/include/foxitxfa.h b/xfa/include/foxitxfa.h
new file mode 100644
index 0000000000..26ab6cd8f3
--- /dev/null
+++ b/xfa/include/foxitxfa.h
@@ -0,0 +1,20 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FOXIT_XFA_H_
+#define _FOXIT_XFA_H_
+#include "../../core/include/fxcrt/fx_ext.h"
+#include "../../core/include/fxge/fx_ge.h"
+#include "../../core/include/fxcodec/fx_codec.h"
+#include "../../core/include/fpdfapi/fpdfapi.h"
+#include "../../core/include/fdrm/fx_crypt.h"
+#include "../../core/include/fpdfdoc/fpdf_doc.h"
+#include "./fxbarcode/BC_BarCode.h"
+#include "./fxgraphics/fx_graphics.h"
+#include "./fwl/fwl.h"
+#include "./fxjse/fxjse.h"
+#include "./fxfa/fxfa.h"
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_adapterclipboardmgr.h b/xfa/include/fwl/adapter/fwl_adapterclipboardmgr.h
new file mode 100644
index 0000000000..82a098ebbb
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_adapterclipboardmgr.h
@@ -0,0 +1,36 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ADAPTER_CLIPBOARDMGR_H
+#define _FWL_ADAPTER_CLIPBOARDMGR_H
+class IFWL_Widget;
+class IFWL_AdapterClipboardMgr;
+enum FWL_CLIPBOARDFORMAT {
+ FWL_CLIPBOARDFORMAT_Dib,
+ FWL_CLIPBOARDFORMAT_Text,
+ FWL_CLIPBOARDFORMAT_UncodeText,
+};
+typedef struct _FWL_HCLIPBOARDDATA {
+ FX_LPVOID pData;
+} * FWL_HCLIPBOARDDATA;
+class IFWL_AdapterClipboardMgr
+{
+public:
+ virtual FWL_ERR Empty() = 0;
+ virtual FX_BOOL IsDataAvailable(FX_DWORD dwFormat) = 0;
+ virtual FWL_HCLIPBOARDDATA GetData(FX_DWORD dwFormat) = 0;
+ virtual FWL_ERR SetData(FX_DWORD dwFormat, FX_BYTE *pBuf, FX_INT32 iSize) = 0;
+ virtual FX_INT32 GetDataSize(FWL_HCLIPBOARDDATA hData) = 0;
+ virtual FX_LPVOID LockDataBuffer(FWL_HCLIPBOARDDATA hData) = 0;
+ virtual FX_BOOL UnLockDataBuffer(FWL_HCLIPBOARDDATA hData) = 0;
+ virtual FWL_ERR SetStringData(FX_WSTR ws) = 0;
+ virtual FWL_ERR SetStringData(FX_BSTR bs) = 0;
+ virtual FWL_ERR GetStringData(CFX_WideString &ws) = 0;
+ virtual FWL_ERR GetStringData(CFX_ByteString &bs) = 0;
+ virtual FWL_ERR EnumFormats(CFX_DWordArray &formats) = 0;
+ virtual FX_DWORD RegisterFormat(FX_WSTR wsFormat) = 0;
+};
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_adaptercursormgr.h b/xfa/include/fwl/adapter/fwl_adaptercursormgr.h
new file mode 100644
index 0000000000..225a22ca2f
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_adaptercursormgr.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ADAPTER_CURSORMGR_H
+#define _FWL_ADAPTER_CURSORMGR_H
+class CFX_DIBitmap;
+class IFWL_AdapterCursorMgr;
+enum FWL_CURSORTYPE {
+ FWL_CURSORTYPE_Arrow = 0,
+ FWL_CURSORTYPE_Cross,
+ FWL_CURSORTYPE_Hand,
+ FWL_CURSORTYPE_InputBeam,
+ FWL_CURSORTYPE_Wait,
+ FWL_CURSORTYPE_SizeAll,
+ FWL_CURSORTYPE_SizeNWSE,
+ FWL_CURSORTYPE_SizeNESW,
+ FWL_CURSORTYPE_SizeWE,
+ FWL_CURSORTYPE_SizeNS,
+ FWL_CURSORTYPE_Prohibition,
+ FWL_CURSORTYPE_Help
+};
+typedef struct _FWL_HCURSOR {
+ FX_LPVOID pData;
+} *FWL_HCURSOR;
+class IFWL_AdapterCursorMgr
+{
+public:
+ virtual FWL_HCURSOR GetSystemCursor(FWL_CURSORTYPE eCursorType) = 0;
+ virtual FWL_HCURSOR GetCustomCursor(const CFX_DIBitmap *pBitmap, FX_FLOAT xHotspot = 0, FX_FLOAT yHotspot = 0) = 0;
+ virtual FWL_ERR SetCursor(FWL_HCURSOR hCursor) = 0;
+ virtual FWL_ERR ShowCursor(FX_BOOL bShow) = 0;
+ virtual FWL_ERR GetCursorPos(CFX_PointF &pt) = 0;
+};
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_adaptermonitormgr.h b/xfa/include/fwl/adapter/fwl_adaptermonitormgr.h
new file mode 100644
index 0000000000..bd194964c9
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_adaptermonitormgr.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ADAPTER_MONITORMGR_H
+#define _FWL_ADAPTER_MONITORMGR_H
+class IFWL_AdapterMonitorMgr;
+typedef struct _FWL_HMONITOR {
+ FX_LPVOID pData;
+} *FWL_HMONITOR;
+class IFWL_AdapterMonitorMgr
+{
+public:
+ virtual FX_INT32 CountMonitors() = 0;
+ virtual FWL_HMONITOR GetMonitor(FX_INT32 nIndex) = 0;
+ virtual FWL_HMONITOR GetCurrentMonitor() = 0;
+ virtual FWL_HMONITOR GetMonitorByRect(const CFX_RectF &rect) = 0;
+ virtual FWL_HMONITOR GetMonitorByPoint(FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FWL_ERR GetMonitorSize(FWL_HMONITOR hMonitor, FX_FLOAT &fx, FX_FLOAT &fy) = 0;
+};
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_adapternative.h b/xfa/include/fwl/adapter/fwl_adapternative.h
new file mode 100644
index 0000000000..55532945f9
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_adapternative.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ADAPTER_NATIVE_H
+#define _FWL_ADAPTER_NATIVE_H
+class IFWL_WidgetMgrDelegate;
+class IFWL_AdapterWidgetMgr;
+class IFWL_AdapterThreadMgr;
+class IFWL_AdapterTimerMgr;
+class IFWL_AdapterCursorMgr;
+class IFWL_AdapterMonitorMgr;
+class IFWL_AdapterClipboardMgr;
+class IFWL_AdapterNative;
+class IFWL_AdapterNative
+{
+public:
+ virtual IFWL_AdapterWidgetMgr* GetWidgetMgr(IFWL_WidgetMgrDelegate *pDelegate) = 0;
+ virtual IFWL_AdapterThreadMgr* GetThreadMgr() = 0;
+ virtual IFWL_AdapterTimerMgr* GetTimerMgr() = 0;
+ virtual IFWL_AdapterCursorMgr* GetCursorMgr() = 0;
+ virtual IFWL_AdapterMonitorMgr* GetMonitorMgr() = 0;
+ virtual IFWL_AdapterClipboardMgr* GetClipboardMgr() = 0;
+};
+IFWL_AdapterNative* FWL_CreateFuelAdapterNative();
+void FWL_ReleaseFuelAdapterNative(IFWL_AdapterNative *pAdapterNative);
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_adapterthreadmgr.h b/xfa/include/fwl/adapter/fwl_adapterthreadmgr.h
new file mode 100644
index 0000000000..ad6cd58245
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_adapterthreadmgr.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ADAPTER_THREAD_H
+#define _FWL_ADAPTER_THREAD_H
+class IFWL_Thread;
+class IFWL_AdapterThreadMgr;
+class IFWL_AdapterMutex;
+class IFWL_AdapterSemaphore;
+class IFWL_AdapterThreadMgr
+{
+public:
+ virtual FWL_ERR Start(IFWL_Thread *pThread, FWL_HTHREAD &hThread, FX_BOOL bSuspended = FALSE) = 0;
+ virtual FWL_ERR Resume(FWL_HTHREAD hThread) = 0;
+ virtual FWL_ERR Suspend(FWL_HTHREAD hThread) = 0;
+ virtual FWL_ERR Kill(FWL_HTHREAD hThread, FX_INT32 iExitCode) = 0;
+ virtual FWL_ERR Stop(FWL_HTHREAD hThread, FX_INT32 iExitCode) = 0;
+ virtual IFWL_Thread* GetCurrentThread() = 0;
+};
+class IFWL_AdapterSemaphore
+{
+public:
+ static IFWL_AdapterSemaphore * Create();
+ virtual FWL_ERR Destroy() = 0;
+ virtual FWL_ERR Wait() const = 0;
+ virtual FWL_ERR Post() = 0;
+ virtual FWL_ERR Value(FX_DWORD &val) const = 0;
+ virtual FWL_ERR Reset(FX_INT32 init) = 0;
+};
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_adaptertimermgr.h b/xfa/include/fwl/adapter/fwl_adaptertimermgr.h
new file mode 100644
index 0000000000..4c7f7e76dc
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_adaptertimermgr.h
@@ -0,0 +1,17 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ADAPTER_TIMERMGR_H
+#define _FWL_ADAPTER_TIMERMGR_H
+class IFWL_Timer;
+class IFWL_AdapterTimerMgr;
+class IFWL_AdapterTimerMgr
+{
+public:
+ virtual FWL_ERR Start(IFWL_Timer *pTimer, FX_DWORD dwElapse, FWL_HTIMER &hTimer, FX_BOOL bImmediately = TRUE) = 0;
+ virtual FWL_ERR Stop(FWL_HTIMER hTimer) = 0;
+};
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_adapterwidgetmgr.h b/xfa/include/fwl/adapter/fwl_adapterwidgetmgr.h
new file mode 100644
index 0000000000..fbc296f7fa
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_adapterwidgetmgr.h
@@ -0,0 +1,55 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ADAPTER_WIDGETMGR_H
+#define _FWL_ADAPTER_WIDGETMGR_H
+class IFWL_Widget;
+class IFWL_Menu;
+class IFWL_MenuDP;
+class CFX_Path;
+class CFX_DIBitmap;
+class IFWL_AdapterWidgetMgr;
+class IFWL_AdapterMessageHook;
+class IFWL_AppDelegate;
+class IFWL_AdapterWidgetMgr
+{
+public:
+ virtual FWL_ERR CreateWidget(IFWL_Widget *pWidget, IFWL_Widget *pParent = NULL) = 0;
+ virtual FWL_ERR DestroyWidget(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR GetWidgetRect(IFWL_Widget *pWidget, CFX_RectF &rect) = 0;
+ virtual FWL_ERR SetWidgetRect(IFWL_Widget *pWidget, const CFX_RectF &rect) = 0;
+ virtual FWL_ERR SetWidgetPosition(IFWL_Widget *pWidget, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FWL_ERR SetParentWidget(IFWL_Widget *pWidget, IFWL_Widget *pParent) = 0;
+ virtual FWL_ERR SetWidgetIcon(IFWL_Widget *pWidget, const CFX_DIBitmap *pIcon, FX_BOOL bBig) = 0;
+ virtual FWL_ERR SetWidgetCaption(IFWL_Widget *pWidget, FX_WSTR wsCaption) = 0;
+ virtual FWL_ERR SetBorderRegion(IFWL_Widget *pWidget, CFX_Path *pPath) = 0;
+ virtual FWL_ERR SetTransparent(IFWL_Widget *pWidget, FX_DWORD dwAlpha) = 0;
+ virtual FWL_ERR ShowWidget(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR HideWidget(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR SetNormal(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR SetMaximize(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR SetMinimize(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR SetFullScreen(IFWL_Widget *pWidget, FX_BOOL bFullScreen) = 0;
+ virtual FX_BOOL CheckMessage() = 0;
+ virtual FX_BOOL IsIdleMessage() = 0;
+ virtual FWL_ERR DispatchMessage() = 0;
+ virtual FWL_ERR RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect) = 0;
+ virtual FWL_ERR Exit(FX_INT32 iExitCode) = 0;
+ virtual FWL_ERR CreateWidgetWithNativeId(IFWL_Widget *pWidget, FX_LPVOID UserData) = 0;
+ virtual FWL_ERR GetWidgetDC(IFWL_Widget *pWidget, FX_LPVOID &pDC) = 0;
+ virtual FWL_ERR ReleaseWidgetDC(IFWL_Widget *pWidget, FX_LPVOID pDC, CFX_RectF *pClip = 0) = 0;
+ virtual FX_LPVOID GetWindow(IFWL_Widget *pWidget) = 0;
+ virtual FX_DWORD GetKeyState(FX_DWORD dwVirtKey) = 0;
+ virtual FWL_ERR RunLoop(IFWL_Widget *widget) = 0;
+ virtual FWL_ERR EndLoop() = 0;
+ virtual FWL_ERR InitMenu(IFWL_Menu *pMenu, IFWL_MenuDP *pMenuData) = 0;
+ virtual FWL_ERR UpdateMenu(IFWL_Menu *pMenu, FX_LPCVOID hItem, FX_INT32 iType) = 0;
+ virtual FX_INT32 TrackPopupMenu(IFWL_Menu *pMenu, IFWL_MenuDP *pMenuData) = 0;
+ virtual FWL_ERR SetMessageHook(IFWL_AdapterMessageHook *hook) = 0;
+ virtual FWL_ERR GetSystemBorder(FX_FLOAT &l, FX_FLOAT &t, FX_FLOAT &r, FX_FLOAT &b) = 0;
+ virtual FX_BOOL GetPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup) = 0;
+};
+#endif
diff --git a/xfa/include/fwl/adapter/fwl_sdadapterimp.h b/xfa/include/fwl/adapter/fwl_sdadapterimp.h
new file mode 100644
index 0000000000..98b2ecbaf0
--- /dev/null
+++ b/xfa/include/fwl/adapter/fwl_sdadapterimp.h
@@ -0,0 +1,72 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_SDAPATER_IMP_H
+#define _FWL_SDAPATER_IMP_H
+class IFWL_AdapterNative;
+class IFWL_AdapterWidgetMgr;
+class IFWL_AdapterThreadMgr;
+class IFWL_AdapterTimerMgr;
+class IFWL_WidgetMgrDelegate;
+class CFWL_SDAdatperNative;
+class CFWL_SDAdapterWidgetMgr;
+class CFWL_SDAdapterTimerMgr;
+class CFWL_SDAdapterWidgetMgr : public IFWL_AdapterWidgetMgr, public CFX_Object
+{
+public:
+ CFWL_SDAdapterWidgetMgr();
+ ~CFWL_SDAdapterWidgetMgr();
+ virtual FWL_ERR CreateWidget(IFWL_Widget *pWidget, IFWL_Widget *pParent = NULL);
+ virtual FWL_ERR DestroyWidget(IFWL_Widget *pWidget);
+ virtual FWL_ERR SetWidgetRect(IFWL_Widget *pWidget, const CFX_RectF &rect);
+ virtual FWL_ERR SetWidgetPosition(IFWL_Widget *pWidget, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR SetParentWidget(IFWL_Widget *pWidget, IFWL_Widget *pParent);
+ virtual FWL_ERR ShowWidget(IFWL_Widget *pWidget);
+ virtual FWL_ERR HideWidget(IFWL_Widget *pWidget);
+ virtual FWL_ERR SetNormal(IFWL_Widget *pWidget);
+ virtual FWL_ERR SetMaximize(IFWL_Widget *pWidget);
+ virtual FWL_ERR SetMinimize(IFWL_Widget *pWidget);
+ virtual FWL_ERR RunWidget(IFWL_Widget *pWidget);
+ virtual FWL_ERR RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect);
+ virtual FWL_ERR Exit(FX_INT32 iExitCode);
+ virtual FWL_ERR CreateWidgetWithNativeId(IFWL_Widget *pWidget, void *vp);
+ virtual FX_BOOL GetPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+public:
+ virtual FWL_ERR GetWidgetRect(IFWL_Widget *pWidget, CFX_RectF &rect);
+ virtual FWL_ERR SetWidgetIcon(IFWL_Widget *pWidget, const CFX_DIBitmap *pIcon, FX_BOOL bBig);
+ virtual FWL_ERR SetWidgetCaption(IFWL_Widget *pWidget, FX_WSTR wsCaption);
+ virtual FWL_ERR SetBorderRegion(IFWL_Widget *pWidget, CFX_Path *pPath);
+ virtual FWL_ERR SetTransparent(IFWL_Widget *pWidget, FX_DWORD dwAlpha);
+ virtual FWL_ERR SetFullScreen(IFWL_Widget *pWidget, FX_BOOL bFullScreen);
+ virtual FX_BOOL CheckMessage();
+ virtual FX_BOOL IsIdleMessage();
+ virtual FWL_ERR DispatchMessage();
+ virtual FWL_ERR GetWidgetDC(IFWL_Widget *pWidget, FX_LPVOID &pDC);
+ virtual FWL_ERR ReleaseWidgetDC(IFWL_Widget *pWidget, FX_LPVOID pDC, CFX_RectF *pClip = 0);
+ virtual FX_LPVOID GetWindow(IFWL_Widget *pWidget);
+ virtual FX_DWORD GetKeyState(FX_DWORD dwVirtKey);
+ virtual FWL_ERR RunLoop(IFWL_Widget *widget);
+ virtual FWL_ERR EndLoop();
+ virtual FWL_ERR InitMenu(IFWL_Menu *pMenu, IFWL_MenuDP *pMenuData);
+ virtual FWL_ERR UpdateMenu(IFWL_Menu *pMenu, FX_LPCVOID hItem, FX_INT32 iType);
+ virtual FX_INT32 TrackPopupMenu(IFWL_Menu *pMenu, IFWL_MenuDP *pMenuData);
+ virtual FWL_ERR SetMessageHook(IFWL_AdapterMessageHook *hook);
+ virtual FWL_ERR GetSystemBorder(FX_FLOAT &l, FX_FLOAT &t, FX_FLOAT &r, FX_FLOAT &b);
+};
+class CFWL_SDAdapterThreadMgr : public IFWL_AdapterThreadMgr, public CFX_Object
+{
+public:
+ CFWL_SDAdapterThreadMgr();
+ ~CFWL_SDAdapterThreadMgr();
+public:
+ virtual FWL_ERR Start(IFWL_Thread *pThread, FWL_HTHREAD &hThread, FX_BOOL bSuspended = FALSE);
+ virtual FWL_ERR Resume(FWL_HTHREAD hThread);
+ virtual FWL_ERR Suspend(FWL_HTHREAD hThread);
+ virtual FWL_ERR Kill(FWL_HTHREAD hThread, FX_INT32 iExitCode);
+ virtual FWL_ERR Stop(FWL_HTHREAD hThread, FX_INT32 iExitCode);
+ virtual IFWL_Thread* GetCurrentThread();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_barcode.h b/xfa/include/fwl/basewidget/fwl_barcode.h
new file mode 100644
index 0000000000..ba6e99691e
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_barcode.h
@@ -0,0 +1,63 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_BARCODE_H
+#define _FWL_BARCODE_H
+#include "fwl_edit.h"
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_BarcodeDP;
+class IFWL_Barcode;
+#define FWL_CLASS_Barcode L"FWL_BARCODE"
+#define FWL_CLASSHASH_Barcode 366886968
+#define FWL_BCDATTRIBUTE_CHARENCODING (1L << 0)
+#define FWL_BCDATTRIBUTE_MODULEHEIGHT (1L << 1)
+#define FWL_BCDATTRIBUTE_MODULEWIDTH (1L << 2)
+#define FWL_BCDATTRIBUTE_DATALENGTH (1L << 3)
+#define FWL_BCDATTRIBUTE_CALCHECKSUM (1L << 4)
+#define FWL_BCDATTRIBUTE_PRINTCHECKSUM (1L << 5)
+#define FWL_BCDATTRIBUTE_TEXTLOCATION (1L << 6)
+#define FWL_BCDATTRIBUTE_WIDENARROWRATIO (1L << 7)
+#define FWL_BCDATTRIBUTE_STARTCHAR (1L << 8)
+#define FWL_BCDATTRIBUTE_ENDCHAR (1L << 9)
+#define FWL_BCDATTRIBUTE_VERSION (1L << 10)
+#define FWL_BCDATTRIBUTE_ECLEVEL (1L << 11)
+#define FWL_BCDATTRIBUTE_TRUNCATED (1L << 12)
+#define FWL_PART_BCD_Border 1
+#define FWL_PART_BCD_Edge 2
+#define FWL_PART_BCD_Background 3
+#define FWL_BCUPDATECMD_Data FWL_WGTUPDATECMD_User
+class IFWL_BarcodeDP : public IFWL_EditDP
+{
+public:
+ virtual BC_CHAR_ENCODING GetCharEncoding() = 0;
+ virtual FX_INT32 GetModuleHeight() = 0;
+ virtual FX_INT32 GetModuleWidth() = 0;
+ virtual FX_INT32 GetDataLength() = 0;
+ virtual FX_INT32 GetCalChecksum() = 0;
+ virtual FX_BOOL GetPrintChecksum() = 0;
+ virtual BC_TEXT_LOC GetTextLocation() = 0;
+ virtual FX_INT32 GetWideNarrowRatio() = 0;
+ virtual FX_CHAR GetStartChar() = 0;
+ virtual FX_CHAR GetEndChar() = 0;
+ virtual FX_INT32 GetVersion() = 0;
+ virtual FX_INT32 GetErrorCorrectionLevel() = 0;
+ virtual FX_BOOL GetTruncated() = 0;
+ virtual FX_DWORD GetBarcodeAttributeMask() = 0;
+};
+class IFWL_Barcode : public IFWL_Edit
+{
+public:
+ static IFWL_Barcode* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ void SetType(BC_TYPE type);
+ FX_BOOL IsProtectedType();
+protected:
+ IFWL_Barcode();
+ virtual ~IFWL_Barcode();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_caret.h b/xfa/include/fwl/basewidget/fwl_caret.h
new file mode 100644
index 0000000000..0d29fca863
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_caret.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CARET_H
+#define _FWL_CARET_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_Caret;
+#define FWL_CLASS_Caret L"FWL_CARET"
+#define FWL_CLASSHASH_Caret 671181879
+#define FWL_STATE_CAT_HightLight 1
+#define FWL_PART_CAT_Background 1
+#define FWL_PARTSTATE_CAT_HightLight 1
+class IFWL_Caret : public IFWL_Widget
+{
+public:
+ static IFWL_Caret* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+
+ FWL_ERR ShowCaret(FX_BOOL bFlag = TRUE);
+ FWL_ERR GetFrequency(FX_DWORD &elapse);
+ FWL_ERR SetFrequency(FX_DWORD elapse);
+ FWL_ERR SetColor(CFX_Color crFill);
+protected:
+ IFWL_Caret();
+ virtual ~IFWL_Caret();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_checkbox.h b/xfa/include/fwl/basewidget/fwl_checkbox.h
new file mode 100644
index 0000000000..625ad489c2
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_checkbox.h
@@ -0,0 +1,95 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CHECKBOX_H
+#define _FWL_CHECKBOX_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_CheckBoxDP;
+class IFWL_CheckBox;
+#define FWL_CLASS_CheckBox L"FWL_CHECKBOX"
+#define FWL_CLASS_RadioButton L"FWL_RADIOBUTTON"
+#define FWL_CLASSHASH_CheckBox 4107183823
+#define FWL_CLASSHASH_RadioButton 3811304691
+#define FWL_STYLEEXT_CKB_Left (0L << 0)
+#define FWL_STYLEEXT_CKB_Center (1L << 0)
+#define FWL_STYLEEXT_CKB_Right (2L << 0)
+#define FWL_STYLEEXT_CKB_Top (0L << 2)
+#define FWL_STYLEEXT_CKB_VCenter (1L << 2)
+#define FWL_STYLEEXT_CKB_Bottom (2L << 2)
+#define FWL_STYLEEXT_CKB_LeftText (1L << 4)
+#define FWL_STYLEEXT_CKB_MultiLine (1L << 5)
+#define FWL_STYLEEXT_CKB_3State (1L << 6)
+#define FWL_STYLEEXT_CKB_RadioButton (1L << 7)
+#define FWL_STYLEEXT_CKB_ShapeSolidSquare (0L << 8)
+#define FWL_STYLEEXT_CKB_ShapeSunkenSquare (1L << 8)
+#define FWL_STYLEEXT_CKB_ShapeSolidCircle (2L << 8)
+#define FWL_STYLEEXT_CKB_ShapeSunkenCircle (3L << 8)
+#define FWL_STYLEEXT_CKB_SignShapeCheck (0L << 10)
+#define FWL_STYLEEXT_CKB_SignShapeCircle (1L << 10)
+#define FWL_STYLEEXT_CKB_SignShapeCross (2L << 10)
+#define FWL_STYLEEXT_CKB_SignShapeDiamond (3L << 10)
+#define FWL_STYLEEXT_CKB_SignShapeSquare (4L << 10)
+#define FWL_STYLEEXT_CKB_SignShapeStar (5L << 10)
+#define FWL_STYLEEXT_CKB_HLayoutMask (3L << 0)
+#define FWL_STYLEEXT_CKB_VLayoutMask (3L << 2)
+#define FWL_STYLEEXT_CKB_ShapeMask (3L << 8)
+#define FWL_STYLEEXT_CKB_SignShapeMask (7L << 10)
+#define FWL_STATE_CKB_Hovered (1 << FWL_WGTSTATE_MAX)
+#define FWL_STATE_CKB_Pressed (1 << (FWL_WGTSTATE_MAX + 1))
+#define FWL_STATE_CKB_Unchecked (0 << (FWL_WGTSTATE_MAX + 2))
+#define FWL_STATE_CKB_Checked (1 << (FWL_WGTSTATE_MAX + 2))
+#define FWL_STATE_CKB_Neutral (2 << (FWL_WGTSTATE_MAX + 2))
+#define FWL_STATE_CKB_CheckMask (3L << (FWL_WGTSTATE_MAX + 2))
+#define FWL_PART_CKB_Border 1
+#define FWL_PART_CKB_Edge 2
+#define FWL_PART_CKB_Background 3
+#define FWL_PART_CKB_CheckBox 4
+#define FWL_PART_CKB_Caption 5
+#define FWL_PARTSTATE_CKB_Normal (0L << 0)
+#define FWL_PARTSTATE_CKB_Pressed (1L << 0)
+#define FWL_PARTSTATE_CKB_Hovered (2L << 0)
+#define FWL_PARTSTATE_CKB_Disabled (3L << 0)
+#define FWL_PARTSTATE_CKB_UnChecked (0L << 2)
+#define FWL_PARTSTATE_CKB_Checked (1L << 2)
+#define FWL_PARTSTATE_CKB_Neutral (2L << 2)
+#define FWL_PARTSTATE_CKB_Focused (1L << 4)
+#define FWL_PARTSTATE_CKB_Mask1 (3L << 0)
+#define FWL_PARTSTATE_CKB_Mask2 (3L << 2)
+#define FWL_EVT_CKB_CheckStateChanged L"FWL_EVENT_CKB_CheckStateChanged"
+#define FWL_EVTHASH_CKB_CheckStateChanged 2503252963
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCkbCheckStateChanged, FWL_EVTHASH_CKB_CheckStateChanged)
+END_FWL_EVENT_DEF
+class IFWL_CheckBoxDP : public IFWL_DataProvider
+{
+public:
+ virtual FX_FLOAT GetBoxSize(IFWL_Widget *pWidget) = 0;
+};
+class IFWL_CheckBox : public IFWL_Widget
+{
+public:
+ static IFWL_CheckBox* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FX_INT32 GetCheckState();
+ FWL_ERR SetCheckState(FX_INT32 iCheck);
+protected:
+ IFWL_CheckBox();
+ virtual ~IFWL_CheckBox();
+};
+class IFWL_RadioButton : public IFWL_Widget
+{
+public:
+ static IFWL_RadioButton* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FX_INT32 GetCheckState();
+ FWL_ERR SetCheckState(FX_INT32 iCheck);
+protected:
+ IFWL_RadioButton();
+ virtual ~IFWL_RadioButton();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_combobox.h b/xfa/include/fwl/basewidget/fwl_combobox.h
new file mode 100644
index 0000000000..74d6bdf24b
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_combobox.h
@@ -0,0 +1,139 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_COMBOBOX_H
+#define _FWL_COMBOBOX_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_ListBox;
+class IFWL_ComboBoxDP;
+class IFWL_ComboBox;
+#define FWL_CLASS_ComboBox L"FWL_COMBOBOX"
+#define FWL_CLASSHASH_ComboBox 602353697
+#define FWL_STYLEEXT_CMB_DropList (0L << 0)
+#define FWL_STYLEEXT_CMB_DropDown (1L << 0)
+#define FWL_STYLEEXT_CMB_Sort (1L << 1)
+#define FWL_STYLEEXT_CMB_ListDrag (1L << 2)
+#define FWL_STYLEEXT_CMB_OwnerDraw (1L << 3)
+#define FWL_STYLEEXT_CMB_EditHNear (0L << 4)
+#define FWL_STYLEEXT_CMB_EditHCenter (1L << 4)
+#define FWL_STYLEEXT_CMB_EditHFar (2L << 4)
+#define FWL_STYLEEXT_CMB_EditVNear (0L << 6)
+#define FWL_STYLEEXT_CMB_EditVCenter (1L << 6)
+#define FWL_STYLEEXT_CMB_EditVFar (2L << 6)
+#define FWL_STYLEEXT_CMB_EditJustified (1L << 8)
+#define FWL_STYLEEXT_CMB_EditDistributed (2L << 8)
+#define FWL_STYLEEXT_CMB_EditHAlignMask (3L << 4)
+#define FWL_STYLEEXT_CMB_EditVAlignMask (3L << 6)
+#define FWL_STYLEEXT_CMB_EditHAlignModeMask (3L << 8)
+#define FWL_STYLEEXT_CMB_ListItemLeftAlign (0L << 10)
+#define FWL_STYLEEXT_CMB_ListItemCenterAlign (1L << 10)
+#define FWL_STYLEEXT_CMB_ListItemRightAlign (2L << 10)
+#define FWL_STYLEEXT_CMB_ListItemText (0L << 12)
+#define FWL_STYLEEXT_CMB_ListItemIconText (1L << 12)
+#define FWL_STYLEEXT_CMB_ListItemAlignMask (3L << 12)
+#define FWL_STYLEEXT_CMB_ReadOnly (1L << 13)
+#define FWL_PART_CMB_Border 1
+#define FWL_PART_CMB_Edge 2
+#define FWL_PART_CMB_Background 3
+#define FWL_PART_CMB_DropDownButton 4
+#define FWL_PART_CMB_Caption 5
+#define FWL_PART_CMB_StretcgHandler 6
+#define FWL_PARTSTATE_CMB_Normal (0L << 0)
+#define FWL_PARTSTATE_CMB_Hovered (1L << 0)
+#define FWL_PARTSTATE_CMB_Pressed (2L << 0)
+#define FWL_PARTSTATE_CMB_Disabled (3L << 0)
+#define FWL_PARTSTATE_CMB_Selected (1L << 2)
+#define FWL_WGTCAPACITY_CMB_ComboFormHandler (FWL_WGTCAPACITY_MAX + 7)
+enum FWL_CMB_TEXTCHANGED {
+ FWL_CMB_TEXTCHANGED_Insert = 0 ,
+ FWL_CMB_TEXTCHANGED_Delete ,
+ FWL_CMB_TEXTCHANGED_Replace ,
+};
+#define FWL_EVT_CMB_DropDown L"FWL_EVENT_CMB_PreDropDown"
+#define FWL_EVT_CMB_PostDropDown L"FWL_EVENT_CMB_PostDropDown"
+#define FWL_EVT_CMB_CloseUp L"FWL_EVENT_CMB_CloseUp"
+#define FWL_EVT_CMB_EditChanged L"FWL_EVENT_CMB_EditChanged"
+#define FWL_EVT_CMB_SelChanged L"FWL_EVENT_CMB_SelChanged"
+#define FWL_EVT_CMB_HoverChanged L"FWL_EVENT_CMB_HoverChanged"
+#define FWL_EVT_CMB_DrawItem L"FWL_EVENT_CMB_DrawItem"
+#define FWL_EVTHASH_CMB_PreDropDown 1357646798
+#define FWL_EVTHASH_CMB_PostDropDown 3677010285
+#define FWL_EVTHASH_CMB_CloseUp 2871271190
+#define FWL_EVTHASH_CMB_EditChanged 1527034762
+#define FWL_EVTHASH_CMB_SelChanged 2923227784
+#define FWL_EVTHASH_CMB_HoverChanged 944325448
+#define FWL_EVTHASH_CMB_DrawItem 917354551
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCmbPreDropDown, FWL_EVTHASH_CMB_PreDropDown)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCmbPostDropDown, FWL_EVTHASH_CMB_PostDropDown)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCmbCloseUp, FWL_EVTHASH_CMB_CloseUp)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCmbEditChanged, FWL_EVTHASH_CMB_EditChanged)
+FX_INT32 nChangeType;
+CFX_WideString wsInsert;
+CFX_WideString wsDelete;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCmbSelChanged, FWL_EVTHASH_CMB_SelChanged)
+CFX_Int32Array iArraySels;
+FX_BOOL bLButtonUp;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCmbHoverChanged, FWL_EVTHASH_CMB_HoverChanged)
+FX_INT32 m_iCurHover;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtCmbDrawItem, FWL_EVTHASH_CMB_DrawItem)
+CFX_Graphics *m_pGraphics;
+CFX_Matrix m_matrix;
+FX_INT32 m_index;
+CFX_RectF m_rtItem;
+END_FWL_EVENT_DEF
+class IFWL_ComboBoxDP : public IFWL_ListBoxDP
+{
+public:
+ virtual FX_FLOAT GetListHeight(IFWL_Widget *pWidget) = 0;
+};
+class IFWL_ComboBox : public IFWL_Widget
+{
+public:
+ static IFWL_ComboBox* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FX_INT32 GetCurSel();
+ FWL_ERR SetCurSel(FX_INT32 iSel);
+ FWL_ERR SetEditText(const CFX_WideString &wsText);
+ FX_INT32 GetEditTextLength() const;
+ FWL_ERR GetEditText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const;
+ FWL_ERR SetEditSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ FX_INT32 GetEditSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ FX_INT32 GetEditLimit();
+ FWL_ERR SetEditLimit(FX_INT32 nLimit);
+ FWL_ERR EditDoClipboard(FX_INT32 iCmd);
+ FX_BOOL EditRedo(FX_BSTR bsRecord);
+ FX_BOOL EditUndo(FX_BSTR bsRecord);
+ IFWL_ListBox* GetListBoxt();
+ FX_BOOL AfterFocusShowDropList();
+ FX_ERR OpenDropDownList(FX_BOOL bActivate);
+ FX_BOOL EditCanUndo();
+ FX_BOOL EditCanRedo();
+ FX_BOOL EditUndo();
+ FX_BOOL EditRedo();
+ FX_BOOL EditCanCopy();
+ FX_BOOL EditCanCut();
+ FX_BOOL EditCanSelectAll();
+ FX_BOOL EditCopy(CFX_WideString &wsCopy);
+ FX_BOOL EditCut(CFX_WideString &wsCut);
+ FX_BOOL EditPaste(const CFX_WideString &wsPaste);
+ FX_BOOL EditSelectAll();
+ FX_BOOL EditDelete();
+ FX_BOOL EditDeSelect();
+ FWL_ERR GetBBox(CFX_RectF &rect);
+ FWL_ERR EditModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+protected:
+ IFWL_ComboBox();
+ virtual ~IFWL_ComboBox();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_datetimepicker.h b/xfa/include/fwl/basewidget/fwl_datetimepicker.h
new file mode 100644
index 0000000000..898264eeec
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_datetimepicker.h
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_DATETIMEPICKER_H
+#define _FWL_DATETIMEPICKER_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_DateTimePickerDP;
+class IFWL_DateTimePicker;
+#define FWL_CLASS_DateTimePicker L"FWL_DATETIMEPICKER"
+#define FWL_CLASSHASH_DateTimePicker 3851176257
+#define FWL_STYLEEXT_DTP_AllowEdit (1L << 0)
+#define FWL_STYLEEXT_DTP_LongDateFormat (0L << 1)
+#define FWL_STYLEEXT_DTP_ShortDateFormat (1L << 1)
+#define FWL_STYLEEXT_DTP_TimeFormat (2L << 1)
+#define FWL_STYLEEXT_DTP_Spin (1L << 3)
+#define FWL_STYLEEXT_DTP_EditHNear (0L << 4)
+#define FWL_STYLEEXT_DTP_EditHCenter (1L << 4)
+#define FWL_STYLEEXT_DTP_EditHFar (2L << 4)
+#define FWL_STYLEEXT_DTP_EditVNear (0L << 6)
+#define FWL_STYLEEXT_DTP_EditVCenter (1L << 6)
+#define FWL_STYLEEXT_DTP_EditVFar (2L << 6)
+#define FWL_STYLEEXT_DTP_EditJustified (1L << 8)
+#define FWL_STYLEEXT_DTP_EditDistributed (2L << 8)
+#define FWL_STYLEEXT_DTP_EditHAlignMask (3L << 4)
+#define FWL_STYLEEXT_DTP_EditVAlignMask (3L << 6)
+#define FWL_STYLEEXT_DTP_EditHAlignModeMask (3L << 8)
+#define FWL_PART_DTP_Border 1
+#define FWL_PART_DTP_Edge 2
+#define FWL_PART_DTP_Background 3
+#define FWL_PART_DTP_DropDownButton 4
+#define FWL_PARTSTATE_DTP_Normal (0L << 0)
+#define FWL_PARTSTATE_DTP_Hovered (1L << 0)
+#define FWL_PARTSTATE_DTP_Pressed (2L << 0)
+#define FWL_PARTSTATE_DTP_Disabled (3L << 0)
+#define FWL_EVT_DTP_DropDown L"FWL_EVENT_DTP_DropDown"
+#define FWL_EVTHASH_DTP_DropDown 264728733
+#define FWL_EVT_DTP_CloseUp L"FWL_EVENT_DTP_CloseUp"
+#define FWL_EVTHASH_DTP_CloseUp 4280973803
+#define FWL_EVT_DTP_EditChanged L"FWL_EVENT_DTP_EditChanged"
+#define FWL_EVTHASH_DTP_EditChanged 4009610944
+#define FWL_EVT_DTP_HoverChanged L"FWL_EVENT_DTP_HoverChanged"
+#define FWL_EVTHASH_DTP_HoverChanged 686674750
+#define FWL_EVT_DTP_SelectChanged L"FWL_EVENT_DTP_SelectChanged"
+#define FWL_EVTHASH_DTP_SelectChanged 1589616858
+BEGIN_FWL_EVENT_DEF(CFWL_Event_DtpDropDown, FWL_EVTHASH_DTP_DropDown)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_Event_DtpCloseUp, FWL_EVTHASH_DTP_CloseUp)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_Event_DtpEditChanged, FWL_EVTHASH_DTP_EditChanged)
+CFX_WideString m_wsText;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_Event_DtpHoverChanged, FWL_EVTHASH_DTP_HoverChanged)
+FX_INT32 hoverday;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_Event_DtpSelectChanged, FWL_EVTHASH_DTP_SelectChanged)
+FX_INT32 iYear;
+FX_INT32 iMonth;
+FX_INT32 iDay;
+END_FWL_EVENT_DEF
+class IFWL_DateTimePickerDP : public IFWL_DataProvider
+{
+public:
+ virtual FWL_ERR GetToday(IFWL_Widget *pWidget, FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay) = 0;
+};
+class IFWL_DateTimePicker : public IFWL_Widget
+{
+public:
+ static IFWL_DateTimePicker* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FWL_ERR GetCurSel(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay);
+ FWL_ERR SetCurSel(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+ FWL_ERR SetEditText(const CFX_WideString &wsText);
+ FWL_ERR GetEditText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const;
+ FX_INT32 CountSelRanges();
+ FX_INT32 GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ FX_BOOL CanUndo();
+ FX_BOOL CanRedo();
+ FX_BOOL Undo();
+ FX_BOOL Redo();
+ FX_BOOL CanCopy();
+ FX_BOOL CanCut();
+ FX_BOOL CanSelectAll();
+ FX_BOOL Copy(CFX_WideString &wsCopy);
+ FX_BOOL Cut(CFX_WideString &wsCut);
+ FX_BOOL Paste(const CFX_WideString &wsPaste);
+ FX_BOOL SelectAll();
+ FX_BOOL Delete();
+ FX_BOOL DeSelect();
+ FWL_ERR GetBBox(CFX_RectF &rect);
+ FWL_ERR SetEditLimit(FX_INT32 nLimit);
+ FWL_ERR ModifyEditStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+protected:
+ IFWL_DateTimePicker();
+ virtual ~IFWL_DateTimePicker();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_edit.h b/xfa/include/fwl/basewidget/fwl_edit.h
new file mode 100644
index 0000000000..18bdee662b
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_edit.h
@@ -0,0 +1,165 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_EDIT_H
+#define _FWL_EDIT_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_EditDP;
+class IFWL_Edit;
+#define FWL_CLASS_Edit L"FWL_EDIT"
+#define FWL_CLASSHASH_Edit 2893987822
+#define FWL_STYLEEXT_EDT_ReadOnly (1L << 0)
+#define FWL_STYLEEXT_EDT_MultiLine (1L << 1)
+#define FWL_STYLEEXT_EDT_WantReturn (1L << 2)
+#define FWL_STYLEEXT_EDT_NoHideSel (1L << 3)
+#define FWL_STYLEEXT_EDT_AutoHScroll (1L << 4)
+#define FWL_STYLEEXT_EDT_AutoVScroll (1L << 5)
+#define FWL_STYLEEXT_EDT_NoRedoUndo (1L << 6)
+#define FWL_STYLEEXT_EDT_Validate (1L << 7)
+#define FWL_STYLEEXT_EDT_Password (1L << 8)
+#define FWL_STYLEEXT_EDT_Number (1L << 9)
+#define FWL_STYLEEXT_EDT_HSelfAdaption (1L << 10)
+#define FWL_STYLEEXT_EDT_VSelfAdaption (1L << 11)
+#define FWL_STYLEEXT_EDT_VerticalLayout (1L << 12)
+#define FWL_STYLEEXT_EDT_VerticalChars (1L << 13)
+#define FWL_STYLEEXT_EDT_ReverseLine (1L << 14)
+#define FWL_STYLEEXT_EDT_ArabicShapes (1L << 15)
+#define FWL_STYLEEXT_EDT_ExpandTab (1L << 16)
+#define FWL_STYLEEXT_EDT_CombText (1L << 17)
+#define FWL_STYLEEXT_EDT_HNear (0L << 18)
+#define FWL_STYLEEXT_EDT_HCenter (1L << 18)
+#define FWL_STYLEEXT_EDT_HFar (2L << 18)
+#define FWL_STYLEEXT_EDT_VNear (0L << 20)
+#define FWL_STYLEEXT_EDT_VCenter (1L << 20)
+#define FWL_STYLEEXT_EDT_VFar (2L << 20)
+#define FWL_STYLEEXT_EDT_Justified (1L << 22)
+#define FWL_STYLEEXT_EDT_Distributed (2L << 22)
+#define FWL_STYLEEXT_EDT_HAlignMask (3L << 18)
+#define FWL_STYLEEXT_EDT_VAlignMask (3L << 20)
+#define FWL_STYLEEXT_EDT_HAlignModeMask (3L << 22)
+#define FWL_STYLEEXT_EDT_InnerCaret (1L << 24)
+#define FWL_STYLEEXT_EDT_ShowScrollbarFocus (1L << 25)
+#define FWL_STYLEEXT_EDT_OuterScrollbar (1L << 26)
+#define FWL_STYLEEXT_EDT_LastLineHeight (1L << 27)
+#define FWL_STATE_EDT_Editing (1 << FWL_WGTSTATE_MAX)
+#define FWL_PART_EDT_Border 1
+#define FWL_PART_EDT_Edge 2
+#define FWL_PART_EDT_Background 3
+#define FWL_PART_EDT_CombTextLine 4
+#define FWL_PARTDATA_EDT_Background 0
+#define FWL_PARTDATA_EDT_StaticBackground 1
+#define FWL_PARTSTATE_EDT_Normal (0L << 0)
+#define FWL_PARTSTATE_EDT_ReadOnly (1L << 0)
+#define FWL_PARTSTATE_EDT_Disable (2L << 0)
+enum FWL_EDT_TEXTCHANGED {
+ FWL_EDT_TEXTCHANGED_Insert = 0 ,
+ FWL_EDT_TEXTCHANGED_Delete ,
+ FWL_EDT_TEXTCHANGED_Replace ,
+};
+#define FWL_EVT_EDT_AddDoRecord L"FWL_EVENT_EDT_AddDoRecord"
+#define FWL_EVTHASH_EDT_AddDoRecord 3701672224
+#define FWL_EVT_EDT_TextChanged L"FWL_EVENT_EDT_TextChanged"
+#define FWL_EVTHASH_EDT_TextChanged 1064022132
+#define FWL_EVT_EDT_PreSelfAdaption L"FWL_EVENT_PreSelfAdaption"
+#define FWL_EVTHASH_EDT_PreSelfAdaption 1001979178
+#define FWL_EVT_EDT_Validate L"FWL_EVTHASH_EDT_Validate"
+#define FWL_EVTHASH_EDT_Validate 3373308608
+#define FWL_EVT_EDT_CheckWord L"FWL_EVTHASH_EDT_CheckWord"
+#define FWL_EVTHASH_EDT_CheckWord 2897181520
+#define FWL_EVT_EDT_GetSuggestWords L"FWL_EVTHASH_EDT_GetSuggestWords"
+#define FWL_EVTHASH_EDT_GetSuggestWords 315782791
+#define FWL_EVT_EDT_TextFull L"FWL_EVTHASH_EDT_TextFull"
+#define FWL_EVTHASH_EDT_TextFull 2158580174
+BEGIN_FWL_EVENT_DEF(CFWL_EvtEdtAddDoRecord, FWL_EVTHASH_EDT_AddDoRecord)
+CFX_ByteString m_wsDoRecord;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtEdtTextChanged, FWL_EVTHASH_EDT_TextChanged)
+FX_INT32 nChangeType;
+CFX_WideString wsInsert;
+CFX_WideString wsDelete;
+CFX_WideString wsPrevText;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtEdtTextFull, FWL_EVTHASH_EDT_TextFull)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtEdtPreSelfAdaption, FWL_EVTHASH_EDT_PreSelfAdaption)
+FX_BOOL bHSelfAdaption;
+FX_BOOL bVSelfAdaption;
+CFX_RectF rtAfterChange;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtEdtValidate, FWL_EVTHASH_EDT_Validate)
+IFWL_Widget* pDstWidget;
+CFX_WideString wsInsert;
+FX_BOOL bValidate;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtEdtCheckWord, FWL_EVTHASH_EDT_CheckWord)
+CFX_ByteString bsWord;
+FX_BOOL bCheckWord;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtEdtGetSuggestWords, FWL_EVTHASH_EDT_GetSuggestWords)
+FX_BOOL bSuggestWords;
+CFX_ByteString bsWord;
+CFX_ByteStringArray bsArraySuggestWords;
+END_FWL_EVENT_DEF
+class IFWL_EditDP : public IFWL_DataProvider
+{
+};
+#define FWL_EDT_FIND_FLAGS_Prev (0L << 0)
+#define FWL_EDT_FIND_FLAGS_Next (1L << 0)
+#define FWL_EDT_FIND_FLAGS_WholeWord (1L << 1)
+#define FWL_EDT_FIND_FLAGS_NoCase (1L << 2)
+typedef struct _FWL_HEDTFIND {
+ FX_LPVOID pData;
+}* FWL_HEDTFIND;
+class IFWL_Edit : public IFWL_Widget
+{
+public:
+ static IFWL_Edit* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FWL_ERR SetText(const CFX_WideString &wsText);
+ FX_INT32 GetTextLength() const;
+ FWL_ERR GetText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const;
+ FWL_ERR ClearText();
+ FX_INT32 GetCaretPos() const;
+ FX_INT32 SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore = TRUE);
+ FWL_ERR AddSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ FX_INT32 CountSelRanges();
+ FX_INT32 GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ FWL_ERR ClearSelections();
+ FX_INT32 GetLimit();
+ FWL_ERR SetLimit(FX_INT32 nLimit);
+ FWL_ERR SetAliasChar(FX_WCHAR wAlias);
+ FWL_ERR SetFormatString(const CFX_WideString &wsFormat);
+ FWL_ERR Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen);
+ FWL_ERR DeleteSelections();
+ FWL_ERR DeleteRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ FWL_ERR ReplaceSelections(const CFX_WideStringC &wsReplace);
+ FWL_ERR Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace);
+ FWL_ERR DoClipboard(FX_INT32 iCmd);
+ FX_BOOL Copy(CFX_WideString &wsCopy);
+ FX_BOOL Cut(CFX_WideString &wsCut);
+ FX_BOOL Paste(const CFX_WideString &wsPaste);
+ FX_BOOL Delete();
+ FX_BOOL Redo(FX_BSTR bsRecord);
+ FX_BOOL Undo(FX_BSTR bsRecord);
+ FX_BOOL Undo();
+ FX_BOOL Redo();
+ FX_BOOL CanUndo();
+ FX_BOOL CanRedo();
+ FWL_ERR SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant);
+ FWL_ERR SetOuter(IFWL_Widget *pOuter);
+ FWL_ERR SetNumberRange(FX_INT32 iMin, FX_INT32 iMax);
+ FWL_ERR SetBackColor(FX_DWORD dwColor);
+ FWL_ERR SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize);
+ void SetScrollOffset(FX_FLOAT fScrollOffset);
+ FX_BOOL GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest);
+ FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace);
+protected:
+ IFWL_Edit();
+ virtual ~IFWL_Edit();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_listbox.h b/xfa/include/fwl/basewidget/fwl_listbox.h
new file mode 100644
index 0000000000..4b2f2555c5
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_listbox.h
@@ -0,0 +1,110 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_LISTBOX_H
+#define _FWL_LISTBOX_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_ListBoxDP;
+class IFWL_ListBox;
+#define FWL_CLASS_ListBox L"FWL_LISTBOX"
+#define FWL_CLASSHASH_ListBox 1777358317
+#define FWL_STYLEEXT_LTB_MultiSelection (1L << 0)
+#define FWL_STYLEEXT_LTB_Sort (1L << 1)
+#define FWL_STYLEEXT_LTB_ShowScrollBarAlaways (1L << 2)
+#define FWL_STYLEEXT_LTB_MultiColumn (1L << 3)
+#define FWL_STYLEEXT_LTB_LeftAlign (0L << 4)
+#define FWL_STYLEEXT_LTB_CenterAlign (1L << 4)
+#define FWL_STYLEEXT_LTB_RightAlign (2L << 4)
+#define FWL_STYLEEXT_LTB_MultiLine (1L << 6)
+#define FWL_STYLEEXT_LTB_OwnerDraw (1L << 7)
+#define FWL_STYLEEXT_LTB_Icon (1L << 8)
+#define FWL_STYLEEXT_LTB_Check (1L << 9)
+#define FWL_STYLEEXT_LTB_AlignMask (3L << 4)
+#define FWL_STYLEEXT_LTB_ShowScrollBarFocus (1L << 10)
+#define FWL_ITEMSTATE_LTB_Selected (1L << 0)
+#define FWL_ITEMSTATE_LTB_Focused (1L << 1)
+#define FWL_ITEMSTATE_LTB_Checked (1L << 2)
+#define FWL_PART_LTB_Border 1
+#define FWL_PART_LTB_Edge 2
+#define FWL_PART_LTB_Background 3
+#define FWL_PART_LTB_ListItem 4
+#define FWL_PART_LTB_Check 5
+#define FWL_PART_LTB_Icon 6
+#define FWL_PARTSTATE_LTB_Normal (0L << 0)
+#define FWL_PARTSTATE_LTB_Selected (1L << 0)
+#define FWL_PARTSTATE_LTB_Disabled (2L << 0)
+#define FWL_PARTSTATE_LTB_Focused (1L << 2)
+#define FWL_PARTSTATE_LTB_UnChecked (0L << 3)
+#define FWL_PARTSTATE_LTB_Checked (1L << 3)
+#define FWL_PARTSTATE_LTB_Mask (3L << 0)
+#define FWL_WGTHITTEST_LTB_Item FWL_WGTHITTEST_MAX + 1
+#define FWL_WGTHITTEST_LTB_HScrollBar FWL_WGTHITTEST_MAX + 2
+#define FWL_WGTHITTEST_LTB_VScrollBar FWL_WGTHITTEST_MAX + 3
+#define FWL_EVT_LTB_SelChanged L"FWL_EVENT_LTB_SelChanged"
+#define FWL_EVT_LTB_DrawItem L"FWL_EVENT_LTB_DrawItem"
+#define FWL_EVTHASH_LTB_SelChanged 1701781688
+#define FWL_EVTHASH_LTB_DrawItem 1050853991
+BEGIN_FWL_EVENT_DEF(CFWL_EvtLtbSelChanged, FWL_EVTHASH_LTB_SelChanged)
+CFX_Int32Array iarraySels;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtLtbDrawItem, FWL_EVTHASH_LTB_DrawItem)
+CFX_Graphics *m_pGraphics;
+CFX_Matrix m_matrix;
+FX_INT32 m_index;
+CFX_RectF m_rect;
+END_FWL_EVENT_DEF
+typedef struct _FWL_HLISTITEM {
+ FX_LPVOID pData;
+}* FWL_HLISTITEM;
+typedef struct _FWL_ListBoxItemData {
+ IFWL_ListBoxDP *pDataProvider;
+ FX_INT32 iIndex;
+} FWL_ListBoxItemData;
+class IFWL_ListBoxDP : public IFWL_DataProvider
+{
+public:
+ virtual FX_INT32 CountItems(IFWL_Widget *pWidget) = 0;
+ virtual FWL_HLISTITEM GetItem(IFWL_Widget *pWidget, FX_INT32 nIndex) = 0;
+ virtual FX_INT32 GetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem) = 0;
+ virtual FX_BOOL SetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_INT32 nIndex) = 0;
+ virtual FX_DWORD GetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem) = 0;
+ virtual FWL_ERR GetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_WideString &wsText) = 0;
+ virtual FWL_ERR GetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF &rtItem) = 0;
+ virtual FX_LPVOID GetItemData(IFWL_Widget *pWidget, FWL_HLISTITEM hItem) = 0;
+ virtual FWL_ERR SetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwStyle) = 0;
+ virtual FWL_ERR SetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_LPCWSTR pszText) = 0;
+ virtual FWL_ERR SetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF &rtItem) = 0;
+ virtual FX_FLOAT GetItemHeight(IFWL_Widget *pWidget) = 0;
+ virtual CFX_DIBitmap* GetItemIcon(IFWL_Widget *pWidget, FWL_HLISTITEM hItem) = 0;
+ virtual FWL_ERR GetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF& rtCheck) = 0;
+ virtual FWL_ERR SetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF& rtCheck) = 0;
+ virtual FX_DWORD GetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem) = 0;
+ virtual FWL_ERR SetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwCheckState) = 0;
+};
+class IFWL_ListBoxCompare
+{
+public:
+ virtual FX_INT32 Compare(FWL_HLISTITEM hLeft, FWL_HLISTITEM hRight) = 0;
+};
+class IFWL_ListBox : public IFWL_Widget
+{
+public:
+ static IFWL_ListBox* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FX_INT32 CountSelItems();
+ FWL_HLISTITEM GetSelItem(FX_INT32 nIndexSel);
+ FX_INT32 GetSelIndex(FX_INT32 nIndex);
+ FWL_ERR SetSelItem(FWL_HLISTITEM hItem, FX_BOOL bSelect = TRUE);
+ FWL_ERR GetItemText(FWL_HLISTITEM hItem, CFX_WideString &wsText);
+ FWL_ERR GetScrollPos(FX_FLOAT &fPos, FX_BOOL bVert = TRUE);
+ FWL_ERR* Sort(IFWL_ListBoxCompare *pCom);
+protected:
+ IFWL_ListBox();
+ virtual ~IFWL_ListBox();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_menu.h b/xfa/include/fwl/basewidget/fwl_menu.h
new file mode 100644
index 0000000000..156274344f
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_menu.h
@@ -0,0 +1,15 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_MENU_H
+#define _FWL_MENU_H
+#define FWL_CLASS_Menu L"FWL_MENU"
+#define FWL_CLASSHASH_Menu 3957949655
+#define FWL_STYLEEXT_MNU_Horz (0L << 0)
+#define FWL_STYLEEXT_MNU_Vert (1L << 0)
+#define FWL_STYLEEXT_MNU_Dock (1L << 1)
+#define FWL_STYLEEXT_MNU_OwnerDraw (1L << 2)
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_monthcalendar.h b/xfa/include/fwl/basewidget/fwl_monthcalendar.h
new file mode 100644
index 0000000000..7ad8f8a364
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_monthcalendar.h
@@ -0,0 +1,130 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_MONTHCALENDAR_H
+#define _FWL_MONTHCALENDAR_H
+class IFWL_MonthCalendarDP;
+class IFWL_MonthCalendar;
+#define FWL_CLASS_MonthCalendar L"FWL_MONTHCALENDAR"
+#define FWL_CLASSHASH_MonthCalendar 2733931374
+#define FWL_STYLEEXT_MCD_MultiSelect (1L << 0)
+#define FWL_STYLEEXT_MCD_NoToday (1L << 1)
+#define FWL_STYLEEXT_MCD_NoTodayCircle (1L << 2)
+#define FWL_STYLEEXT_MCD_WeekNumbers (1L << 3)
+#define FWL_WGTCAPACITY_MC_HEADER_WIDTH 12
+#define FWL_WGTCAPACITY_MC_HEADER_Height 13
+#define FWL_WGTCAPACITY_MC_HEADER_BTN_WIDTH 14
+#define FWL_WGTCAPACITY_MC_HEADER_BTN_HEIGHT 15
+#define FWL_WGTCAPACITY_MC_HEADER_BTN_HMARGIN 16
+#define FWL_WGTCAPACITY_MC_HEADER_BTN_VMARGIN 17
+#define FWL_WGTCAPACITY_MC_HEADER_TEXTWIDHT 18
+#define FWL_WGTCAPACITY_MC_HEADER_TEXTHEIGHT 19
+#define FWL_WGTCAPACITY_MC_HEADER_TEXT_HMARGIN 20
+#define FWL_WGTCAPACITY_MC_HEADER_TEXT_VMARGIN 21
+#define FWL_WGTCAPACITY_MC_HSEP_WIDTH 22
+#define FWL_WGTCAPACITY_MC_HSEP_HEIGHT 23
+#define FWL_WGTCAPACITY_MC_VSEP_WIDTH 24
+#define FWL_WGTCAPACITY_MC_VSEP_HEIGHT 25
+#define FWL_WGTCAPACITY_MC_WEEKNUM_WIDTH 26
+#define FWL_WGTCAPACITY_MC_SEP_DOFFSET 40
+#define FWL_WGTCAPACITY_MC_SEP_X 27
+#define FWL_WGTCAPACITY_MC_SEP_Y 28
+#define FWL_WGTCAPACITY_MC_WEEKNUM_HEIGHT 29
+#define FWL_WGTCAPACITY_MC_WEEK_WIDTH 30
+#define FWL_WGTCAPACITY_MC_WEEK_HEIGHT 31
+#define FWL_WGTCAPACITY_MC_DATES_CELL_WIDTH 32
+#define FWL_WGTCAPACITY_MC_DATES_CELL_HEIGHT 33
+#define FWL_WGTCAPACITY_MC_TODAY_WIDHT 34
+#define FWL_WGTCAPACITY_MC_TODAY_HEIGHT 35
+#define FWL_WGTCAPACITY_MC_TODAY_FLAG_WIDHT 36
+#define FWL_WGTCAPACITY_MC_WIDTH 37
+#define FWL_WGTCAPACITY_MC_HEIGHT 38
+#define FWL_ITEMSTATE_MCD_Nomal (0L << 0)
+#define FWL_ITEMSTATE_MCD_Flag (1L << 0)
+#define FWL_ITEMSTATE_MCD_Selected (1L << 1)
+#define FWL_ITEMSTATE_MCD_Focused (1L << 2)
+#define FWL_PART_MCD_Border 1
+#define FWL_PART_MCD_Edge 2
+#define FWL_PART_MCD_Background 3
+#define FWL_PART_MCD_LBtn 4
+#define FWL_PART_MCD_RBtn 5
+#define FWL_PART_MCD_HSeparator 6
+#define FWL_PART_MCD_VSeparator 7
+#define FWL_PART_MCD_TodayCircle 8
+#define FWL_PART_MCD_DateInCircle 9
+#define FWL_PART_MCD_DateInBK 10
+#define FWL_PART_MCD_Caption 9
+#define FWL_PART_MCD_DatesIn 10
+#define FWL_PART_MCD_DatesOut 11
+#define FWL_PART_MCD_Week 12
+#define FWL_PART_MCD_Today 13
+#define FWL_PART_MCD_Header 14
+#define FWL_PART_MCD_WeekNum 15
+#define FWL_PART_MCD_WeekNumSep 16
+#define FWL_PARTSTATE_MCD_Normal (0L << 0)
+#define FWL_PARTSTATE_MCD_Pressed (1L << 0)
+#define FWL_PARTSTATE_MCD_Hovered (2L << 0)
+#define FWL_PARTSTATE_MCD_Selected (3L << 0)
+#define FWL_PARTSTATE_MCD_LSelected (1L << 2)
+#define FWL_PARTSTATE_MCD_RSelected (2L << 2)
+#define FWL_PARTSTATE_MCD_Flagged (1L << 3)
+#define FWL_PARTSTATE_MCD_Focused (1L << 4)
+#define FWL_MCCAPACITY_Sun FWL_WGTCAPACITY_MAX + 5
+#define FWL_MCCAPACITY_Mon FWL_WGTCAPACITY_MAX + 6
+#define FWL_MCCAPACITY_Tue FWL_WGTCAPACITY_MAX + 7
+#define FWL_MCCAPACITY_Wed FWL_WGTCAPACITY_MAX + 8
+#define FWL_MCCAPACITY_Thu FWL_WGTCAPACITY_MAX + 9
+#define FWL_MCCAPACITY_Fri FWL_WGTCAPACITY_MAX + 10
+#define FWL_MCCAPACITY_Sat FWL_WGTCAPACITY_MAX + 11
+#define FWL_MCCAPACITY_January FWL_WGTCAPACITY_MAX + 12
+#define FWL_MCCAPACITY_February FWL_WGTCAPACITY_MAX + 13
+#define FWL_MCCAPACITY_March FWL_WGTCAPACITY_MAX + 14
+#define FWL_MCCAPACITY_April FWL_WGTCAPACITY_MAX + 15
+#define FWL_MCCAPACITY_May FWL_WGTCAPACITY_MAX + 16
+#define FWL_MCCAPACITY_June FWL_WGTCAPACITY_MAX + 17
+#define FWL_MCCAPACITY_July FWL_WGTCAPACITY_MAX + 18
+#define FWL_MCCAPACITY_August FWL_WGTCAPACITY_MAX + 19
+#define FWL_MCCAPACITY_September FWL_WGTCAPACITY_MAX + 20
+#define FWL_MCCAPACITY_October FWL_WGTCAPACITY_MAX + 21
+#define FWL_MCCAPACITY_November FWL_WGTCAPACITY_MAX + 22
+#define FWL_MCCAPACITY_December FWL_WGTCAPACITY_MAX + 23
+#define FWL_MCCAPACITY_Today FWL_WGTCAPACITY_MAX + 24
+#define FWL_EVENT_MCD_DATESELECTED L"FWL_EVENT_MCD_DateSelected"
+#define FWL_EVT_MCD_DateChanged L"FWL_EVENT_MCD_DateChanged"
+#define FWL_NOTEHASH_MCD_DATASELECTED 1085596932
+#define FWL_EVTHASH_MCD_DateChanged 54212227
+BEGIN_FWL_EVENT_DEF(CFWL_Event_McdDateSelected, FWL_NOTEHASH_MCD_DATASELECTED)
+FX_INT32 m_iStartDay;
+FX_INT32 m_iEndDay;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EventMcdDateChanged, FWL_EVTHASH_MCD_DateChanged)
+FX_INT32 m_iOldYear;
+FX_INT32 m_iOldMonth;
+FX_INT32 m_iStartDay;
+FX_INT32 m_iEndDay;
+END_FWL_EVENT_DEF
+class IFWL_MonthCalendarDP : public IFWL_DataProvider
+{
+public:
+ virtual FX_INT32 GetCurDay(IFWL_Widget *pWidget) = 0;
+ virtual FX_INT32 GetCurMonth(IFWL_Widget *pWidget) = 0;
+ virtual FX_INT32 GetCurYear(IFWL_Widget *pWidget) = 0;
+};
+class IFWL_MonthCalendar : public IFWL_Widget
+{
+public:
+ static IFWL_MonthCalendar* Create();
+
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FX_INT32 CountSelect();
+ FX_BOOL GetSelect(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay, FX_INT32 nIndex = 0);
+ FX_BOOL SetSelect(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+protected:
+ IFWL_MonthCalendar();
+ virtual ~IFWL_MonthCalendar();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_picturebox.h b/xfa/include/fwl/basewidget/fwl_picturebox.h
new file mode 100644
index 0000000000..419fd4e0d1
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_picturebox.h
@@ -0,0 +1,55 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PICTUREBOX_H
+#define _FWL_PICTUREBOX_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_PictureBoxDP;
+class IFWL_PictureBox;
+#define FWL_CLASS_PictureBox L"FWL_PICTUREBOX"
+#define FWL_CLASSHASH_PictureBox 2974721741
+#define FWL_STYLEEXT_PTB_Left 0L << 0
+#define FWL_STYLEEXT_PTB_Center 1L << 0
+#define FWL_STYLEEXT_PTB_Right 2L << 0
+#define FWL_STYLEEXT_PTB_Top 0L << 2
+#define FWL_STYLEEXT_PTB_Vcenter 1L << 2
+#define FWL_STYLEEXT_PTB_Bottom 2L << 2
+#define FWL_STYLEEXT_PTB_Normal 0L << 4
+#define FWL_STYLEEXT_PTB_AutoSize 1L << 4
+#define FWL_STYLEEXT_PTB_StretchImage 2L << 4
+#define FWL_STYLEEXT_PTB_StretchHImage 3L << 4
+#define FWL_STYLEEXT_PTB_StretchVImage 4L << 4
+#define FWL_STYLEEXT_PTB_HAlignMask 3L << 0
+#define FWL_STYLEEXT_PTB_VAlignMask 3L << 2
+#define FWL_STYLEEXT_PTB_StretchAlignMask 7L << 4
+#define FWL_PART_PTB_Border 1
+#define FWL_PART_PTB_Edge 2
+#define FWL_PART_PTB_Image 3
+#define FWL_PARTSTATE_PTB_Normal (0L << 0)
+#define FWL_PARTSTATE_PTB_Disabled (1L << 0)
+class IFWL_PictureBoxDP : public IFWL_DataProvider
+{
+public:
+ virtual CFX_DIBitmap* GetPicture(IFWL_Widget *pWidget) = 0;
+ virtual CFX_DIBitmap* GetErrorPicture(IFWL_Widget *pWidget) = 0;
+ virtual CFX_DIBitmap* GetInitialPicture(IFWL_Widget *pWidget) = 0;
+ virtual FX_INT32 GetOpacity(IFWL_Widget *pWidget) = 0;
+ virtual FX_INT32 GetFlipMode(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR GetMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix) = 0;
+};
+class IFWL_PictureBox : public IFWL_Widget
+{
+public:
+ static IFWL_PictureBox* Create();
+
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+protected:
+ IFWL_PictureBox();
+ virtual ~IFWL_PictureBox();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_pushbutton.h b/xfa/include/fwl/basewidget/fwl_pushbutton.h
new file mode 100644
index 0000000000..890689a141
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_pushbutton.h
@@ -0,0 +1,57 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PUSHBUTTON_H
+#define _FWL_PUSHBUTTON_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_PushButtonDP;
+class IFWL_PushButton;
+#define FWL_CLASS_PushButton L"FWL_PUSHBUTTON"
+#define FWL_CLASSHASH_PushButton 3521614244
+#define FWL_STYLEEXT_PSB_Left (0L << 0)
+#define FWL_STYLEEXT_PSB_Center (1L << 0)
+#define FWL_STYLEEXT_PSB_Right (2L << 0)
+#define FWL_STYLEEXT_PSB_Top (0L << 2)
+#define FWL_STYLEEXT_PSB_VCenter (1L << 2)
+#define FWL_STYLEEXT_PSB_Bottom (2L << 2)
+#define FWL_STYLEEXT_PSB_TextOnly (0L << 4)
+#define FWL_STYLEEXT_PSB_IconOnly (1L << 4)
+#define FWL_STYLEEXT_PSB_TextIcon (2L << 4)
+#define FWL_STYLEEXT_PSB_HLayoutMask (3L << 0)
+#define FWL_STYLEEXT_PSB_VLayoutMask (3L << 2)
+#define FWL_STYLEEXT_PSB_ModeMask (3L << 4)
+#define FWL_STATE_PSB_Hovered (1 << FWL_WGTSTATE_MAX)
+#define FWL_STATE_PSB_Pressed (1 << (FWL_WGTSTATE_MAX + 1))
+#define FWL_STATE_PSB_Default (1 << (FWL_WGTSTATE_MAX + 2))
+#define FWL_WGTCAPACITY_PSB_Margin (FWL_WGTCAPACITY_MAX + 1)
+#define FWL_PART_PSB_Border 1
+#define FWL_PART_PSB_Edge 2
+#define FWL_PART_PSB_Background 3
+#define FWL_PART_PSB_Caption 4
+#define FWL_PARTSTATE_PSB_Normal (0L << 0)
+#define FWL_PARTSTATE_PSB_Pressed (1L << 0)
+#define FWL_PARTSTATE_PSB_Hovered (2L << 0)
+#define FWL_PARTSTATE_PSB_Default (3L << 0)
+#define FWL_PARTSTATE_PSB_Disabled (4L << 0)
+#define FWL_PARTSTATE_PSB_Focused (1L << 3)
+#define FWL_PARTSTATE_PSB_Mask (7L << 0)
+class IFWL_PushButtonDP : public IFWL_DataProvider
+{
+public:
+ virtual CFX_DIBitmap* GetPicture(IFWL_Widget *pWidget) = 0;
+};
+class IFWL_PushButton : public IFWL_Widget
+{
+public:
+ static IFWL_PushButton* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+protected:
+ IFWL_PushButton();
+ virtual ~IFWL_PushButton();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_scrollbar.h b/xfa/include/fwl/basewidget/fwl_scrollbar.h
new file mode 100644
index 0000000000..8fc76f6dae
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_scrollbar.h
@@ -0,0 +1,73 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_SCROLLBAR_H
+#define _FWL_SCROLLBAR_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_ScrollBarDP;
+class IFWL_ScrollBar;
+#define FWL_CLASS_ScrollBar L"FWL_SCROLLBAR"
+#define FWL_CLASSHASH_ScrollBar 2826584844
+#define FWL_STYLEEXT_SCB_Horz (0L << 0)
+#define FWL_STYLEEXT_SCB_Vert (1L << 0)
+#define FWL_PART_SCB_Border 1
+#define FWL_PART_SCB_Edge 2
+#define FWL_PART_SCB_Background 3
+#define FWL_PART_SCB_ForeArrow 4
+#define FWL_PART_SCB_BackArrow 5
+#define FWL_PART_SCB_Thumb 6
+#define FWL_PART_SCB_LowerTrack 7
+#define FWL_PART_SCB_UpperTrack 8
+#define FWL_PARTSTATE_SCB_Normal (0L << 0)
+#define FWL_PARTSTATE_SCB_Hovered (1L << 0)
+#define FWL_PARTSTATE_SCB_Pressed (2L << 0)
+#define FWL_PARTSTATE_SCB_Disabled (3L << 0)
+#define FWL_WGTHITTEST_SCB_ForeArrow FWL_WGTHITTEST_MAX + 1
+#define FWL_WGTHITTEST_SCB_BackArrow FWL_WGTHITTEST_MAX + 2
+#define FWL_WGTHITTEST_SCB_LowerTrack FWL_WGTHITTEST_MAX + 3
+#define FWL_WGTHITTEST_SCB_UpperTrack FWL_WGTHITTEST_MAX + 4
+#define FWL_WGTHITTEST_SCB_Thumb FWL_WGTHITTEST_MAX + 5
+#define FWL_CAPACITY_SCB_Size FWL_WGTCAPACITY_MAX
+enum FWL_SCBCODE {
+ FWL_SCBCODE_None = 1,
+ FWL_SCBCODE_Min ,
+ FWL_SCBCODE_Max ,
+ FWL_SCBCODE_PageBackward ,
+ FWL_SCBCODE_PageForward ,
+ FWL_SCBCODE_StepBackward ,
+ FWL_SCBCODE_StepForward ,
+ FWL_SCBCODE_Pos ,
+ FWL_SCBCODE_TrackPos ,
+ FWL_SCBCODE_EndScroll ,
+};
+class IFWL_ScrollBarDP : public IFWL_DataProvider
+{
+};
+class IFWL_ScrollBar : public IFWL_Widget
+{
+public:
+ static IFWL_ScrollBar* Create();
+
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FX_BOOL IsVertical();
+ FWL_ERR GetRange(FX_FLOAT &fMin, FX_FLOAT &fMax);
+ FWL_ERR SetRange(FX_FLOAT fMin, FX_FLOAT fMax);
+ FX_FLOAT GetPageSize();
+ FWL_ERR SetPageSize(FX_FLOAT fPageSize);
+ FX_FLOAT GetStepSize();
+ FWL_ERR SetStepSize(FX_FLOAT fStepSize);
+ FX_FLOAT GetPos();
+ FWL_ERR SetPos(FX_FLOAT fPos);
+ FX_FLOAT GetTrackPos();
+ FWL_ERR SetTrackPos(FX_FLOAT fTrackPos);
+ FX_BOOL DoScroll(FX_DWORD dwCode, FX_FLOAT fPos = 0.0f);
+protected:
+ IFWL_ScrollBar();
+ virtual ~IFWL_ScrollBar();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_spinbutton.h b/xfa/include/fwl/basewidget/fwl_spinbutton.h
new file mode 100644
index 0000000000..ba417f30bb
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_spinbutton.h
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_SPINBUTTON_H
+#define _FWL_SPINBUTTON_H
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_SpinButton;
+#define FWL_CLASS_SpinButton L"FWL_SPINBUTTON"
+#define FWL_CLASSHASH_SpinButton 3793043646
+#define FWL_STYLEEXE_SPB_Vert (1L << 0)
+#define FWL_PART_SPB_Border 1
+#define FWL_PART_SPB_Edge 2
+#define FWL_PART_SPB_UpButton 3
+#define FWL_PART_SPB_DownButton 4
+#define FWL_PARTSTATE_SPB_Normal (0L << 0)
+#define FWL_PARTSTATE_SPB_Hovered (1L << 0)
+#define FWL_PARTSTATE_SPB_Pressed (2L << 0)
+#define FWL_PARTSTATE_SPB_Disabled (3L << 0)
+#define FWL_WGTHITTEST_SPB_UpButton (FWL_WGTHITTEST_MAX + 1)
+#define FWL_WGTHITTEST_SPB_DownButton (FWL_WGTHITTEST_MAX + 2)
+#define FWL_EVT_SPB_Click L"FWL_EVENT_SPB_Click"
+#define FWL_EVTHASH_SPB_Click 2927651187
+BEGIN_FWL_EVENT_DEF(CFWL_EvtSpbClick, FWL_EVTHASH_SPB_Click)
+FX_BOOL m_bUp;
+END_FWL_EVENT_DEF
+class IFWL_SpinButton : public IFWL_Widget
+{
+public:
+ static IFWL_SpinButton* Create();
+
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FWL_ERR EnableButton(FX_BOOL bEnable, FX_BOOL bUp = TRUE);
+ FX_BOOL IsButtonEnable(FX_BOOL bUp = TRUE);
+protected:
+ IFWL_SpinButton();
+ virtual ~IFWL_SpinButton();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fwl_tooltipctrl.h b/xfa/include/fwl/basewidget/fwl_tooltipctrl.h
new file mode 100644
index 0000000000..d27b9a2638
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fwl_tooltipctrl.h
@@ -0,0 +1,45 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_TOOLTIP_H
+#define _FWL_TOOLTIP_H
+class CFWL_WidgetImpProperties;
+class IFWL_Form;
+class IFWL_ToolTipDP;
+class IFWL_ToolTip;
+#define FWL_CLASS_ToolTip L"FWL_TOOLTIP"
+#define FWL_CLASSHASH_ToolTip 1111984755
+#define FWL_STYLEEXT_TTP_Rectangle (0L << 3)
+#define FWL_STYLEEXT_TTP_RoundCorner (1L << 3)
+#define FWL_STYLEEXT_TTP_Balloon (1L << 4)
+#define FWL_STYLEEXT_TTP_Multiline (1L << 5)
+#define FWL_STYLEEXT_TTP_NoAnchor (1L << 6)
+#define FWL_PART_TTP_Border 1
+#define FWL_PART_TTP_Background 2
+#define FWL_PART_TTP_Caption 3
+class IFWL_ToolTipDP : public IFWL_DataProvider
+{
+public:
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption) = 0;
+ virtual FX_INT32 GetInitialDelay(IFWL_Widget *pWidget) = 0;
+ virtual FX_INT32 GetAutoPopDelay(IFWL_Widget *pWidget) = 0;
+ virtual CFX_DIBitmap* GetToolTipIcon(IFWL_Widget *pWidget) = 0;
+ virtual CFX_SizeF GetToolTipIconSize(IFWL_Widget *pWidget) = 0;
+};
+class IFWL_ToolTip : public IFWL_Form
+{
+public:
+ static IFWL_ToolTip* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FWL_ERR SetAnchor(const CFX_RectF &rtAnchor);
+ FWL_ERR Show();
+ FWL_ERR Hide();
+protected:
+ IFWL_ToolTip();
+ virtual ~IFWL_ToolTip();
+};
+#endif
diff --git a/xfa/include/fwl/basewidget/fxmath_barcode.h b/xfa/include/fwl/basewidget/fxmath_barcode.h
new file mode 100644
index 0000000000..d885ac4c57
--- /dev/null
+++ b/xfa/include/fwl/basewidget/fxmath_barcode.h
@@ -0,0 +1,41 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXMATH_BARCODE_H_
+#define _FXMATH_BARCODE_H_
+class IFX_Barcode
+{
+public:
+ virtual void Release() = 0;
+ virtual BC_TYPE GetType() = 0;
+ virtual FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e) = 0;
+ virtual FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e) = 0;
+ virtual FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e) = 0;
+ virtual CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 height, FX_INT32 &errorCode) = 0;
+ virtual CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &errorCode) = 0;
+ virtual FX_BOOL SetCharEncoding(BC_CHAR_ENCODING encoding) = 0;
+ virtual FX_BOOL SetModuleHeight(FX_INT32 moduleHeight) = 0;
+ virtual FX_BOOL SetModuleWidth(FX_INT32 moduleWidth) = 0;
+ virtual FX_BOOL SetHeight(FX_INT32 height) = 0;
+ virtual FX_BOOL SetWidth(FX_INT32 width) = 0;
+ virtual FX_BOOL CheckContentValidity(FX_WSTR contents) = 0;
+ virtual FX_BOOL SetPrintChecksum(FX_BOOL checksum) = 0;
+ virtual FX_BOOL SetDataLength(FX_INT32 length) = 0;
+ virtual FX_BOOL SetCalChecksum(FX_INT32 state) = 0;
+ virtual FX_BOOL SetFont(CFX_Font* pFont) = 0;
+ virtual FX_BOOL SetFontSize(FX_FLOAT size) = 0;
+ virtual FX_BOOL SetFontStyle(FX_INT32 style) = 0;
+ virtual FX_BOOL SetFontColor(FX_ARGB color) = 0;
+ virtual FX_BOOL SetTextLocation(BC_TEXT_LOC location) = 0;
+ virtual FX_BOOL SetWideNarrowRatio(FX_INT32 ratio) = 0;
+ virtual FX_BOOL SetStartChar(FX_CHAR start) = 0;
+ virtual FX_BOOL SetEndChar(FX_CHAR end) = 0;
+ virtual FX_BOOL SetVersion(FX_INT32 version) = 0;
+ virtual FX_BOOL SetErrorCorrectionLevel (FX_INT32 level) = 0;
+ virtual FX_BOOL SetTruncated(FX_BOOL truncated) = 0;
+};
+IFX_Barcode* FX_Barcode_Create(BC_TYPE type);
+#endif
diff --git a/xfa/include/fwl/core/fwl_app.h b/xfa/include/fwl/core/fwl_app.h
new file mode 100644
index 0000000000..89f6309a31
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_app.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_APP_H
+#define _FWL_APP_H
+class IFWL_NoteThread;
+class IFWL_AdapterNative;
+class IFWL_Widget;
+class IFWL_WidgetMgr;
+class IFWL_ThemeProvider;
+class IFWL_AdapterWidgetMgr;
+class IFWL_App;
+class IFWL_App : public IFWL_NoteThread
+{
+public:
+ static IFWL_App* Create(IFWL_AdapterNative *pAdapter);
+ virtual FWL_ERR Initialize() = 0;
+ virtual FWL_ERR Finalize() = 0;
+ virtual IFWL_AdapterNative* GetAdapterNative() = 0;
+ virtual IFWL_WidgetMgr* GetWidgetMgr() = 0;
+ virtual FWL_ERR SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) = 0;
+ virtual FWL_ERR Exit(FX_INT32 iExitCode = 0) = 0;
+};
+IFWL_App* FWL_GetApp();
+void FWL_SetApp(IFWL_App *pApp);
+IFWL_AdapterNative* FWL_GetAdapterNative();
+IFWL_AdapterWidgetMgr* FWL_GetAdapterWidgetMgr();
+IFWL_ThemeProvider* FWL_GetThemeProvider();
+extern FWL_ERR FWL_Execute(FX_WSTR wsExecutable, FX_WSTR wsParameters);
+FWL_ERR FWL_SetFullScreen(IFWL_Widget *pWidget, FX_BOOL bFullScreen);
+FX_BOOL FWL_AppIsActived();
+#endif
diff --git a/xfa/include/fwl/core/fwl_content.h b/xfa/include/fwl/core/fwl_content.h
new file mode 100644
index 0000000000..51d5e9e8df
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_content.h
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CONTENT_H
+#define _FWL_CONTENT_H
+class IFWL_Widget;
+class IFWL_Content;
+class IFWL_Content : public IFWL_Widget
+{
+public:
+ static IFWL_Content* Create();
+ FWL_ERR Initialize();
+ FWL_ERR InsertWidget(IFWL_Widget *pChild, FX_INT32 nIndex = -1);
+ FWL_ERR RemoveWidget(IFWL_Widget *pWidget);
+ FWL_ERR RemoveAllWidgets();
+ FWL_ERR GetMinSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight);
+ FWL_ERR SetMinSize(FX_FLOAT fWidth, FX_FLOAT fHeight);
+ FWL_ERR GetMaxSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight);
+ FWL_ERR SetMaxSize(FX_FLOAT fWidth, FX_FLOAT fHeight);
+protected:
+ IFWL_Content();
+ virtual ~IFWL_Content();
+};
+#endif
diff --git a/xfa/include/fwl/core/fwl_error.h b/xfa/include/fwl/core/fwl_error.h
new file mode 100644
index 0000000000..4bd2ae4407
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_error.h
@@ -0,0 +1,49 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ERROR_H
+#define _FWL_ERROR_H
+typedef FX_INT32 FWL_ERR;
+#define FWL_ERR_Succeeded 0
+#define FWL_ERR_Indefinite -1
+#define FWL_ERR_Parameter_Invalid -100
+#define FWL_ERR_Property_Invalid -200
+#define FWL_ERR_Intermediate_Value__Invalid -300
+#define FWL_ERR_Method_Not_Supported -400
+#define FWL_ERR_Out_Of_Memory -500
+#if defined (__WIN32__) || defined (_WIN32)
+#define _FWL_ALARM_IF_FAIL(arg, alarm) { if (!(arg)) ::OutputDebugString(alarm); }
+#elif defined (__linux) || defined (linux) || defined (__APPLE__) || defined (__MACOSX__)
+#define _FWL_ALARM_IF_FAIL(arg, alarm) { if (!(arg)) printf(alarm); }
+#else
+#endif
+#define _FWL_RETURN_IF_FAIL(arg) { if (!(arg)) return; }
+#define _FWL_RETURN_VALUE_IF_FAIL(arg, val) { if (!(arg)) return val; }
+#define _FWL_GOTO_POSITION_IF_FAIL(arg, pos) { if (!(arg)) goto pos; }
+#if defined (__WIN32__) || defined (_WIN32)
+#define \
+ _FWL_ERR_CHECK_ALARM_IF_FAIL(arg) \
+ { \
+ if ((arg) != FWL_ERR_Succeeded) \
+ { \
+ char buf[16]; \
+ sprintf(buf, "Error code is %d\n", arg); \
+ ::OutputDebugString(buf); \
+ } \
+ }
+#elif defined (__linux) || defined (linux) || defined (__APPLE__) || defined (__MACOSX__)
+#define \
+ _FWL_ERR_CHECK_ALARM_IF_FAIL(arg) \
+ { \
+ if ((arg) != FWL_ERR_Succeeded) \
+ printf("%d\n", arg); \
+ }
+#else
+#endif
+#define _FWL_ERR_CHECK_RETURN_IF_FAIL(arg) { if ((arg) != FWL_ERR_Succeeded) return; }
+#define _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(arg, val) { if ((arg) != FWL_ERR_Succeeded) return val; }
+#define _FWL_ERR_CHECK_GOTO_POSITION_IF_FAIL(arg, pos) { if ((arg) != FWL_ERR_Succeeded) goto pos; }
+#endif
diff --git a/xfa/include/fwl/core/fwl_form.h b/xfa/include/fwl/core/fwl_form.h
new file mode 100644
index 0000000000..eb0b083008
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_form.h
@@ -0,0 +1,83 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_FORM_H
+#define _FWL_FORM_H
+class IFWL_Widget;
+class IFWL_Panel;
+class IFWL_Form;
+#define FWL_CLASS_Form L"FWL_FORM"
+#define FWL_CLASSHASH_Form 881567292
+#define FWL_CLASS_FormProxy L"FWL_FORMPROXY"
+#define FWL_CLASSHASH_FormProxy 881567291
+#define FWL_STYLEEXT_FRM_Resize (1L << 0)
+#define FWL_STYLEEXT_FRM_NativeBorder (1L << 1)
+#define FWL_STYLEEXT_FRM_RoundCorner (2L << 1)
+#define FWL_STYLEEXT_FRM_RoundCorner4 (3L << 1)
+#define FWL_STYLEEXT_FRM_NoDrawClient (1L << 3)
+#define FWL_STYLEEXT_FRM_BorderCornerMask (3L << 1)
+#define FWL_STYLEEXT_FRM_Max (3)
+#if (_FX_OS_==_FX_MACOSX_)
+#define FWL_UseMacSystemBorder
+#endif
+#define FWL_WGTCAPACITY_FRM_CYCaption (FWL_WGTCAPACITY_MAX + 1)
+#define FWL_WGTCAPACITY_FRM_CYNarrowCaption (FWL_WGTCAPACITY_MAX + 2)
+#define FWL_WGTCAPACITY_FRM_BigIcon (FWL_WGTCAPACITY_MAX + 3)
+#define FWL_WGTCAPACITY_FRM_SmallIcon (FWL_WGTCAPACITY_MAX + 4)
+#define FWL_PART_FRM_Border 1
+#define FWL_PART_FRM_Edge 2
+#define FWL_PART_FRM_Background 3
+#define FWL_PART_FRM_Caption 4
+#define FWL_PART_FRM_NarrowCaption 5
+#define FWL_PART_FRM_CloseBox 6
+#define FWL_PART_FRM_MinimizeBox 7
+#define FWL_PART_FRM_MaximizeBox 8
+#define FWL_PART_FRM_HeadText 9
+#define FWL_PART_FRM_Icon 10
+#define FWL_PARTSTATE_FRM_Normal 1
+#define FWL_PARTSTATE_FRM_Hover 2
+#define FWL_PARTSTATE_FRM_Pressed 3
+#define FWL_PARTSTATE_FRM_Inactive 4
+#define FWL_PARTSTATE_FRM_Disabled 5
+class IFWL_FormDP : public IFWL_DataProvider
+{
+public:
+ virtual CFX_DIBitmap* GetIcon(IFWL_Widget *pWidget, FX_BOOL bBig) = 0;
+};
+enum FWL_FORMSIZE {
+ FWL_FORMSIZE_Manual = 0,
+ FWL_FORMSIZE_Width,
+ FWL_FORMSIZE_Height,
+ FWL_FORMSIZE_All,
+};
+enum FWL_COMMANDID {
+ FWL_COMMANDID_Close = 0,
+ FWL_COMMANDID_Ok,
+ FWL_COMMANDID_Cancel,
+ FWL_COMMANDID_Abort,
+ FWL_COMMANDID_Retry,
+ FWL_COMMANDID_Ignore,
+ FWL_COMMANDID_Yes,
+ FWL_COMMANDID_No,
+};
+class IFWL_Form : public IFWL_Panel
+{
+public:
+ static IFWL_Form* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(CFWL_WidgetImpProperties &properties, CFX_WideString *classname, IFWL_Widget *pOuter = NULL);
+ FWL_FORMSIZE GetFormSize();
+ FWL_ERR SetFormSize(FWL_FORMSIZE eFormSize);
+ IFWL_Widget* DoModal();
+ IFWL_Widget* DoModal(FX_DWORD &dwCommandID);
+ FWL_ERR EndDoModal();
+ FWL_ERR SetBorderRegion(CFX_Path *pPath);
+protected:
+ IFWL_Form();
+ virtual ~IFWL_Form();
+};
+#endif
diff --git a/xfa/include/fwl/core/fwl_grid.h b/xfa/include/fwl/core/fwl_grid.h
new file mode 100644
index 0000000000..2883fd3784
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_grid.h
@@ -0,0 +1,76 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_GRID_H
+#define _FWL_GRID_H
+class IFWL_Widget;
+class IFWL_Content;
+class IFWL_Grid;
+#define FWL_CLASS_Grid L"FWL_GRID"
+#define FWL_CLASSHASH_Grid 3150298670
+#define FWL_GRIDSTYLEEXT_ShowGridLines (1L << 0)
+struct FWL_LAYOUTDATA : public CFX_Object {
+ FX_FLOAT fWidth;
+ FX_FLOAT fHeight;
+};
+enum FWL_GRIDUNIT {
+ FWL_GRIDUNIT_Auto = 0,
+ FWL_GRIDUNIT_Fixed,
+ FWL_GRIDUNIT_Scaled,
+ FWL_GRIDUNIT_Infinity,
+};
+enum FWL_GRIDMARGIN {
+ FWL_GRIDMARGIN_Left = 0,
+ FWL_GRIDMARGIN_Top,
+ FWL_GRIDMARGIN_Right,
+ FWL_GRIDMARGIN_Bottom,
+};
+enum FWL_GRIDSIZE {
+ FWL_GRIDSIZE_Width = 0,
+ FWL_GRIDSIZE_Height,
+ FWL_GRIDSIZE_MinWidth,
+ FWL_GRIDSIZE_MinHeight,
+ FWL_GRIDSIZE_MaxWidth,
+ FWL_GRIDSIZE_MaxHeight,
+};
+typedef struct _FWL_HGRIDCOLROW {
+ FX_LPVOID pData;
+} * FWL_HGRIDCOLROW;
+class IFWL_Grid : public IFWL_Content
+{
+public:
+ static IFWL_Grid* Create();
+ FWL_ERR Initialize();
+ FWL_ERR Initialize(CFWL_WidgetImpProperties &properties);
+
+ FWL_HGRIDCOLROW InsertColRow(FX_BOOL bColumn, FX_INT32 nIndex = -1);
+ FX_INT32 CountColRows(FX_BOOL bColumn);
+ FWL_HGRIDCOLROW GetColRow(FX_BOOL bColumn, FX_INT32 nIndex);
+ FX_INT32 GetIndex(FWL_HGRIDCOLROW hColRow);
+ FX_FLOAT GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit);
+ FWL_ERR SetSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit);
+ FX_FLOAT GetMinSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit);
+ FWL_ERR SetMinSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit);
+ FX_FLOAT GetMaxSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit);
+ FWL_ERR SetMaxSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit);
+ FX_BOOL DeleteColRow(FWL_HGRIDCOLROW hColRow);
+ FX_BOOL IsColumn(FWL_HGRIDCOLROW hColRow);
+ FX_INT32 GetWidgetPos(IFWL_Widget *pWidget, FX_BOOL bColumn);
+ FWL_ERR SetWidgetPos(IFWL_Widget *pWidget, FX_INT32 iPos, FX_BOOL bColumn);
+ FX_INT32 GetWidgetSpan(IFWL_Widget *pWidget, FX_BOOL bColumn);
+ FWL_ERR SetWidgetSpan(IFWL_Widget *pWidget, FX_INT32 iSpan, FX_BOOL bColumn);
+ FX_FLOAT GetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit);
+ FWL_ERR SetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit);
+ FX_BOOL GetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT &fMargin);
+ FWL_ERR SetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT fMargin);
+ FWL_ERR RemoveWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin);
+ FX_FLOAT GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit);
+ FWL_ERR SetGridSize(FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit);
+protected:
+ IFWL_Grid();
+ virtual ~IFWL_Grid();
+};
+#endif
diff --git a/xfa/include/fwl/core/fwl_note.h b/xfa/include/fwl/core/fwl_note.h
new file mode 100644
index 0000000000..01d7ae44ca
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_note.h
@@ -0,0 +1,389 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_NOTE_H
+#define _FWL_NOTE_H
+class IFWL_Target;
+class IFWL_Widget;
+class IFWL_NoteThread;
+class IFWL_ThemeProvider;
+class CFWL_Note;
+class CFWL_Message;
+class CFWL_MsgActivate;
+class CFWL_MsgDeactivate;
+class CFWL_MsgMouse;
+class CFWL_MsgMouseWheel;
+class CFWL_MsgKey;
+class CFWL_MsgSetFocus;
+class CFWL_MsgKillFocus;
+class CFWL_MsgCursor;
+class CFWL_MsgSize;
+class CFWL_MsgWindowMove;
+class CFWL_MsgDropFiles;
+class CFWL_MsgTaskClicked;
+class CFWL_MsgClose;
+class CFWL_MsgWindowWillMove;
+class CFWL_Event;
+class CFWL_EvtMouse;
+class CFWL_EvtMouseWheel;
+class CFWL_EvtKey;
+class CFWL_EvtSetFocus;
+class CFWL_EvtKillFocus;
+class CFWL_EvtDraw;
+class CFWL_EvtClick;
+class CFWL_EvtScroll;
+class CFWL_EvtClose;
+class CFWL_EvtContextMenu;
+class CFWL_EvtMenuCommand;
+class CFWL_EvtSizeChanged;
+class CFWL_EvtIdle;
+class IFWL_NoteDriver;
+class IFWL_NoteLoop;
+#define FWL_MSG_Activate L"FWL_MESSAGE_Activate"
+#define FWL_MSG_Deactivate L"FWL_MESSAGE_Deactivate"
+#define FWL_MSG_SetFocus L"FWL_MESSAGE_SetFocus"
+#define FWL_MSG_KillFocus L"FWL_MESSAGE_KillFocus"
+#define FWL_MSG_Mouse L"FWL_MESSAGE_Mouse"
+#define FWL_MSG_MouseWheel L"FWL_MESSAGE_MouseWheel"
+#define FWL_MSG_Key L"FWL_MESSAGE_Key"
+#define FWL_MSG_Cursor L"FWL_MESSAGE_Cursor"
+#define FWL_MSG_Size L"FWL_MESSAGE_Size"
+#define FWL_MSG_WindowMove L"FWL_MESSAGE_WindowMove"
+#define FWL_MSG_DropFiles L"FWL_MESSAGE_DropFiles"
+#define FWL_MSG_TaskClicked L"FWL_MESSAGE_TaskClicked"
+#define FWL_MSG_Close L"FWL_MESSAGE_Close"
+#define FWL_MSG_Post L"FWL_MESSAGE_Post"
+#define FWL_MSG_WindowWillMove L"FWL_MESSAGE_WindowWillMove"
+#define FWL_MSGHASH_Activate 2410369469
+#define FWL_MSGHASH_Deactivate 1184214790
+#define FWL_MSGHASH_SetFocus 4174512504
+#define FWL_MSGHASH_KillFocus 1557903832
+#define FWL_MSGHASH_Mouse 706128309
+#define FWL_MSGHASH_MouseWheel 893703466
+#define FWL_MSGHASH_Key 3751372405
+#define FWL_MSGHASH_Cursor 3182626218
+#define FWL_MSGHASH_Size 160077735
+#define FWL_MSGHASH_WindowMove 1032269377
+#define FWL_MSGHASH_DropFiles 2004165236
+#define FWL_MSGHASH_TaskClicked 3128231086
+#define FWL_MSGHASH_Close 2977563906
+#define FWL_MSGHASH_Post 1969633074
+#define FWL_MSGHASH_WindowWillMove 2229175763
+#define FWL_EVT_Mouse L"FWL_EVENT_Mouse"
+#define FWL_EVT_MouseWheel L"FWL_EVENT_MouseWheel"
+#define FWL_EVT_Key L"FWL_EVENT_Key"
+#define FWL_EVT_SetFocus L"FWL_EVENT_SetFocus"
+#define FWL_EVT_KillFocus L"FWL_EVENT_KillFocus"
+#define FWL_EVT_Click L"FWL_EVENT_Click"
+#define FWL_EVT_Draw L"FWL_EVENT_Draw"
+#define FWL_EVT_Scroll L"FWL_EVENT_Scroll"
+#define FWL_EVT_Close L"FWL_EVENT_Close"
+#define FWL_EVT_ContextMenu L"FWL_EVENT_ContextMenu"
+#define FWL_EVT_MenuCommand L"FWL_EVENT_MenuCommand"
+#define FWL_EVT_SizeChanged L"FWL_EVENT_SizeChanged"
+#define FWL_EVTHASH_Mouse 1765258002
+#define FWL_EVTHASH_MouseWheel 3907114407
+#define FWL_EVTHASH_Key 2408354450
+#define FWL_EVTHASH_SetFocus 3909721269
+#define FWL_EVTHASH_KillFocus 1779363253
+#define FWL_EVTHASH_Draw 2430713303
+#define FWL_EVTHASH_Click 4026328783
+#define FWL_EVTHASH_Scroll 2965158968
+#define FWL_EVTHASH_Close 4036693599
+#define FWL_EVTHASH_ContextMenu 2717307715
+#define FWL_EVTHASH_MenuCommand 497763741
+#define FWL_EVTHASH_SizeChanged 3083958510
+#define FWL_EVTHASH_Idle 839546759
+#define FWL_MSGMOUSECMD_LButtonDown 1
+#define FWL_MSGMOUSECMD_LButtonUp 2
+#define FWL_MSGMOUSECMD_LButtonDblClk 3
+#define FWL_MSGMOUSECMD_RButtonDown 4
+#define FWL_MSGMOUSECMD_RButtonUp 5
+#define FWL_MSGMOUSECMD_RButtonDblClk 6
+#define FWL_MSGMOUSECMD_MButtonDown 7
+#define FWL_MSGMOUSECMD_MButtonUp 8
+#define FWL_MSGMOUSECMD_MButtonDblClk 9
+#define FWL_MSGMOUSECMD_MouseMove 10
+#define FWL_MSGMOUSECMD_MouseEnter 11
+#define FWL_MSGMOUSECMD_MouseLeave 12
+#define FWL_MSGMOUSECMD_MouseHover 13
+#define FWL_MSGKEYCMD_KeyDown 1
+#define FWL_MSGKEYCMD_KeyUp 2
+#define FWL_MSGKEYCMD_Char 3
+#define FWL_KEYFLAG_Ctrl (1 << 0)
+#define FWL_KEYFLAG_Alt (1 << 1)
+#define FWL_KEYFLAG_Shift (1 << 2)
+#define FWL_KEYFLAG_Command (1 << 3)
+#define FWL_KEYFLAG_LButton (1 << 4)
+#define FWL_KEYFLAG_RButton (1 << 5)
+#define FWL_KEYFLAG_MButton (1 << 6)
+class CFWL_Note : public CFX_Object
+{
+public:
+ virtual FX_DWORD Release()
+ {
+ m_dwRefCount --;
+ FX_DWORD dwRefCount = m_dwRefCount;
+ if (!m_dwRefCount) {
+ delete this;
+ }
+ return dwRefCount;
+ }
+ virtual IFWL_Target* Retain()
+ {
+ m_dwRefCount ++;
+ return (IFWL_Target*)this;
+ }
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const
+ {
+ wsClass = L"CFWL_Note";
+ return FWL_ERR_Succeeded;
+ }
+ virtual FX_DWORD GetClassID() const
+ {
+ return 0;
+ }
+ virtual FX_BOOL IsInstance(FX_WSTR wsClass) const
+ {
+ return TRUE;
+ }
+ virtual CFWL_Note* Clone()
+ {
+ return NULL;
+ }
+ FX_BOOL IsEvent() const
+ {
+ return m_bIsEvent;
+ }
+ IFWL_Widget *m_pSrcTarget;
+ IFWL_Widget *m_pDstTarget;
+protected:
+ CFWL_Note(FX_BOOL bIsEvent)
+ : m_pSrcTarget(NULL)
+ , m_pDstTarget(NULL)
+ , m_dwRefCount(1)
+ , m_bIsEvent(bIsEvent)
+ , m_dwExtend(0)
+ {
+ }
+ virtual ~CFWL_Note() {}
+ virtual FX_BOOL Initialize()
+ {
+ return TRUE;
+ }
+ virtual FX_INT32 Finalize()
+ {
+ return 0;
+ }
+ FX_DWORD m_dwRefCount;
+ FX_BOOL m_bIsEvent;
+public:
+ FX_DWORD m_dwExtend;
+};
+class CFWL_Message : public CFWL_Note
+{
+public:
+ CFWL_Message() : CFWL_Note(FALSE) {}
+ virtual ~CFWL_Message() {}
+ virtual CFWL_Event* CloneToEvent()
+ {
+ return NULL;
+ }
+};
+#define BEGIN_FWL_MESSAGE_DEF(classname, msghashcode) \
+ class classname : public CFWL_Message \
+ { \
+ public: \
+ classname() : CFWL_Message() {} \
+ virtual CFWL_Note* Clone() {return FX_NEW classname(*this);} \
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const {wsClass = L" ## classname ## "; return FWL_ERR_Succeeded;} \
+ virtual FX_DWORD GetClassID() const {return msghashcode;} \
+ virtual CFWL_Event* CloneToEvent() {classname *pEvent = FX_NEW classname; pEvent->m_bIsEvent = TRUE; return (CFWL_Event*)pEvent;}
+#define END_FWL_MESSAGE_DEF \
+ };
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgActivate, FWL_MSGHASH_Activate)
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgDeactivate, FWL_MSGHASH_Deactivate)
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgMouse, FWL_MSGHASH_Mouse)
+FX_FLOAT m_fx;
+FX_FLOAT m_fy;
+FX_DWORD m_dwFlags;
+FX_DWORD m_dwCmd;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgMouseWheel, FWL_MSGHASH_MouseWheel)
+FX_FLOAT m_fx;
+FX_FLOAT m_fy;
+FX_FLOAT m_fDeltaX;
+FX_FLOAT m_fDeltaY;
+FX_DWORD m_dwFlags;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgSetFocus, FWL_MSGHASH_SetFocus)
+IFWL_Widget *m_pKillFocus;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgKillFocus, FWL_MSGHASH_KillFocus)
+IFWL_Widget *m_pSetFocus;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgKey, FWL_MSGHASH_Key)
+FX_DWORD m_dwKeyCode;
+FX_DWORD m_dwFlags;
+FX_DWORD m_dwCmd;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgCursor, FWL_MSGHASH_Cursor)
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgSize, FWL_MSGHASH_Size)
+FX_INT32 m_iWidth;
+FX_INT32 m_iHeight;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgWindowMove, FWL_MSGHASH_WindowMove)
+FX_FLOAT m_fx;
+FX_FLOAT m_fy;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgDropFiles, FWL_MSGHASH_DropFiles)
+CFWL_MsgDropFiles(const CFWL_MsgDropFiles& copy)
+{
+ m_pDstTarget = copy.m_pDstTarget;
+ m_pSrcTarget = copy.m_pSrcTarget;
+ m_fx = copy.m_fx;
+ m_fy = copy.m_fy;
+ m_files.Append(copy.m_files);
+}
+FX_FLOAT m_fx;
+FX_FLOAT m_fy;
+CFX_WideStringArray m_files;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgTaskClicked, FWL_MSGHASH_TaskClicked)
+FX_FLOAT m_fx;
+FX_FLOAT m_fy;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgClose, FWL_MSGHASH_Close)
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_MESSAGE_DEF(CFWL_MsgWindowWillMove, FWL_MSGHASH_WindowWillMove)
+END_FWL_MESSAGE_DEF
+class CFWL_Event : public CFWL_Note
+{
+public:
+ CFWL_Event() : CFWL_Note(TRUE) {}
+ virtual ~CFWL_Event() {}
+};
+#define BEGIN_FWL_EVENT_DEF(classname, eventhashcode) \
+ class classname : public CFWL_Event \
+ { \
+ public: \
+ classname() : CFWL_Event() {} \
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const {wsClass = L" ## classname ## "; return FWL_ERR_Succeeded;} \
+ virtual FX_DWORD GetClassID() const {return eventhashcode;}
+#define END_FWL_EVENT_DEF \
+ };
+BEGIN_FWL_EVENT_DEF(CFWL_EvtMouse, FWL_EVTHASH_Mouse)
+FX_FLOAT m_fx;
+FX_FLOAT m_fy;
+FX_DWORD m_dwFlags;
+FX_DWORD m_dwCmd;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtMouseWheel, FWL_EVTHASH_MouseWheel)
+FX_FLOAT m_fx;
+FX_FLOAT m_fy;
+FX_FLOAT m_fDeltaX;
+FX_FLOAT m_fDeltaY;
+FX_DWORD m_dwFlags;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtKey, FWL_EVTHASH_Key)
+FX_DWORD m_dwKeyCode;
+FX_DWORD m_dwFlags;
+FX_DWORD m_dwCmd;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtSetFocus, FWL_EVTHASH_SetFocus)
+IFWL_Widget *m_pSetFocus;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtKillFocus, FWL_EVTHASH_KillFocus)
+IFWL_Widget *m_pKillFocus;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtDraw, FWL_EVTHASH_Draw)
+CFX_Graphics *m_pGraphics;
+IFWL_Widget *m_pWidget;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtClick, FWL_EVTHASH_Click)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtScroll, FWL_EVTHASH_Scroll)
+FX_DWORD m_iScrollCode;
+FX_FLOAT m_fPos;
+FX_BOOL *m_pRet;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtClose, FWL_EVTHASH_Close)
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtContextMenu, FWL_EVTHASH_ContextMenu)
+FX_FLOAT m_fPosX;
+FX_FLOAT m_fPosY;
+IFWL_Widget *m_pOwner;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtMenuCommand, FWL_EVTHASH_MenuCommand)
+FX_INT32 m_iCommand;
+FX_LPVOID m_pData;
+END_FWL_EVENT_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtSizeChanged, FWL_EVTHASH_SizeChanged)
+IFWL_Widget *m_pWidget;
+CFX_RectF m_rtOld;
+CFX_RectF m_rtNew;
+END_FWL_MESSAGE_DEF
+BEGIN_FWL_EVENT_DEF(CFWL_EvtIdle, FWL_EVTHASH_Idle)
+END_FWL_EVENT_DEF
+typedef enum {
+ FWL_EVENT_MOUSE_MASK = 1 << 0,
+ FWL_EVENT_MOUSEWHEEL_MASK = 1 << 1,
+ FWL_EVENT_KEY_MASK = 1 << 2,
+ FWL_EVENT_FOCUSCHANGED_MASK = 1 << 3,
+ FWL_EVENT_DRAW_MASK = 1 << 4,
+ FWL_EVENT_CLOSE_MASK = 1 << 5,
+ FWL_EVENT_SIZECHANGED_MASK = 1 << 6,
+ FWL_EVENT_IDLE_MASK = 1 << 7,
+ FWL_EVENT_CONTROL_MASK = 1 << 8,
+ FWL_EVENT_ALL_MASK = 0xFF
+} FWLEventMask;
+class IFWL_NoteDriver
+{
+public:
+ virtual FX_BOOL SendNote(CFWL_Note *pNote) = 0;
+ virtual FX_BOOL PostMessage(CFWL_Message *pMessage) = 0;
+ virtual FWL_ERR RegisterEventTarget(IFWL_Widget *pListener, IFWL_Widget *pEventSource = NULL, FX_DWORD dwFilter = FWL_EVENT_ALL_MASK) = 0;
+ virtual FWL_ERR UnregisterEventTarget(IFWL_Widget *pListener) = 0;
+ virtual void ClearEventTargets(FX_BOOL bRemoveAll) = 0;
+ virtual FX_INT32 GetQueueMaxSize() const = 0;
+ virtual FWL_ERR SetQueueMaxSize(const FX_INT32 size) = 0;
+ virtual IFWL_NoteThread* GetOwnerThread() const = 0;
+ virtual FWL_ERR PushNoteLoop(IFWL_NoteLoop *pNoteLoop) = 0;
+ virtual IFWL_NoteLoop* PopNoteLoop() = 0;
+ virtual FX_BOOL SetFocus(IFWL_Widget *pFocus, FX_BOOL bNotify = FALSE) = 0;
+ virtual FWL_ERR Run() = 0;
+};
+IFWL_Widget* FWL_GetCurrentThreadModalWidget(IFWL_NoteThread *pNoteThread);
+class IFWL_NoteLoop
+{
+public:
+ virtual FX_BOOL PreProcessMessage(CFWL_Message *pMessage) = 0;
+ virtual FWL_ERR Idle(FX_INT32 count) = 0;
+};
+class IFWL_ToolTipTarget
+{
+public:
+ virtual IFWL_Widget* GetWidget() = 0;
+ virtual FX_BOOL IsShowed() = 0;
+ virtual FWL_ERR DrawToolTip(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix, IFWL_Widget *pToolTip) = 0;
+ virtual FX_BOOL UseDefaultTheme() = 0;
+ virtual FWL_ERR GetCaption(CFX_WideString &wsCaption) = 0;
+ virtual FWL_ERR GetToolTipSize(CFX_SizeF &sz) = 0;
+ virtual FWL_ERR GetToolTipPos(CFX_PointF &pt)
+ {
+ return FWL_ERR_Indefinite;
+ }
+};
+FWL_ERR FWL_AddToolTipTarget(IFWL_ToolTipTarget *pTarget);
+FWL_ERR FWL_RemoveToolTipTarget(IFWL_ToolTipTarget *pTarget);
+FWL_ERR FWL_SetToolTipInitialDelay(FX_INT32 iDelayTime);
+FWL_ERR FWL_SetToolTipAutoPopDelay(FX_INT32 iDelayTime);
+typedef FX_BOOL (*FWLMessageHookCallback)(CFWL_Message *msg, FX_LPVOID info);
+FWL_ERR FWL_SetHook(IFWL_NoteDriver *driver, FWLMessageHookCallback callback, FX_LPVOID info);
+#endif
diff --git a/xfa/include/fwl/core/fwl_panel.h b/xfa/include/fwl/core/fwl_panel.h
new file mode 100644
index 0000000000..94c354a698
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_panel.h
@@ -0,0 +1,40 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PANEL_H
+#define _FWL_PANEL_H
+class IFWL_Widget;
+class IFWL_Content;
+class IFWL_Panel;
+class IFWL_CustomPanel;
+#define FWL_CLASS_Panel L"FWL_Panel"
+#define FWL_CLASSHASH_Panel 881567292
+class IFWL_Panel : public IFWL_Widget
+{
+public:
+ static IFWL_Panel* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ IFWL_Content* GetContent();
+ FWL_ERR SetContent(IFWL_Content *pContent);
+protected:
+ IFWL_Panel();
+ virtual ~IFWL_Panel();
+};
+class IFWL_CustomPanel : public IFWL_Widget
+{
+public:
+ static IFWL_CustomPanel* Create();
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ IFWL_Content* GetContent();
+ FWL_ERR SetContent(IFWL_Content *pContent);
+ FWL_ERR SetProxy(IFWL_Proxy *pProxy);
+protected:
+ IFWL_CustomPanel();
+ virtual ~IFWL_CustomPanel();
+};
+#endif
diff --git a/xfa/include/fwl/core/fwl_target.h b/xfa/include/fwl/core/fwl_target.h
new file mode 100644
index 0000000000..3c8b531f24
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_target.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_TARGET_H
+#define _FWL_TARGET_H
+class IFWL_Target;
+class IFWL_Target
+{
+public:
+ FX_DWORD Release();
+ IFWL_Target* Retain();
+ FX_DWORD GetRefCount() const;
+ FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ FX_DWORD GetClassID() const;
+ FX_BOOL IsInstance(FX_WSTR wsClass) const;
+ FWL_ERR Initialize();
+ FWL_ERR Finalize();
+protected:
+ virtual ~IFWL_Target();
+ FX_LPVOID m_pData;
+};
+#endif
diff --git a/xfa/include/fwl/core/fwl_theme.h b/xfa/include/fwl/core/fwl_theme.h
new file mode 100644
index 0000000000..efef288afc
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_theme.h
@@ -0,0 +1,91 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_THEME_H
+#define _FWL_THEME_H
+class IFWL_Widget;
+class CFWL_ThemePart;
+class CFWL_ThemeBackground;
+class CFWL_ThemeText;
+class CFWL_ThemeElement;
+class IFWL_ThemeProvider;
+#define FWL_WGTCAPACITY_CXBorder 1
+#define FWL_WGTCAPACITY_CYBorder 2
+#define FWL_WGTCAPACITY_ScrollBarWidth 3
+#define FWL_WGTCAPACITY_EdgeFlat 4
+#define FWL_WGTCAPACITY_EdgeRaised 5
+#define FWL_WGTCAPACITY_EdgeSunken 6
+#define FWL_WGTCAPACITY_Font 7
+#define FWL_WGTCAPACITY_FontSize 8
+#define FWL_WGTCAPACITY_TextColor 9
+#define FWL_WGTCAPACITY_TextSelColor 10
+#define FWL_WGTCAPACITY_LineHeight 11
+#define FWL_WGTCAPACITY_UIMargin 12
+#define FWL_WGTCAPACITY_SpaceAboveBelow 13
+#define FWL_WGTCAPACITY_MAX 65535
+class CFWL_ThemePart : public CFX_Object
+{
+public:
+ CFWL_ThemePart()
+ : m_pWidget(NULL)
+ , m_iPart(0)
+ , m_dwStates(0)
+ , m_dwData(0)
+ , m_pData(NULL)
+ {
+ m_rtPart.Reset();
+ m_matrix.Reset();
+ }
+ CFX_Matrix m_matrix;
+ CFX_RectF m_rtPart;
+ IFWL_Widget *m_pWidget;
+ FX_INT32 m_iPart;
+ FX_DWORD m_dwStates;
+ FX_DWORD m_dwData;
+ FX_LPVOID m_pData;
+};
+class CFWL_ThemeBackground : public CFWL_ThemePart
+{
+public:
+ CFWL_ThemeBackground()
+ : m_pGraphics(NULL)
+ , m_pImage(NULL)
+ , m_pPath(NULL)
+ {
+ }
+ CFX_Graphics *m_pGraphics;
+ CFX_DIBitmap *m_pImage;
+ CFX_Path *m_pPath;
+};
+class CFWL_ThemeText : public CFWL_ThemePart
+{
+public:
+ CFWL_ThemeText()
+ : m_pGraphics(NULL)
+ {
+ }
+ CFX_WideString m_wsText;
+ FX_DWORD m_dwTTOStyles;
+ FX_INT32 m_iTTOAlign;
+ CFX_Graphics *m_pGraphics;
+};
+class IFWL_ThemeProvider
+{
+public:
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget) = 0;
+ virtual FX_DWORD GetThemeID(IFWL_Widget *pWidget) = 0;
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE) = 0;
+ virtual FWL_ERR GetThemeMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix) = 0;
+ virtual FWL_ERR SetThemeMatrix(IFWL_Widget *pWidget, const CFX_Matrix &matrix) = 0;
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams) = 0;
+ virtual FX_BOOL DrawText(CFWL_ThemeText *pParams) = 0;
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity) = 0;
+ virtual FX_BOOL IsCustomizedLayout(IFWL_Widget *pWidget) = 0;
+ virtual FWL_ERR GetPartRect(CFWL_ThemePart *pThemePart, CFX_RectF &rtPart) = 0;
+ virtual FX_BOOL IsInPart(CFWL_ThemePart *pThemePart, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL CalcTextRect(CFWL_ThemeText *pParams, CFX_RectF &rect) = 0;
+};
+#endif
diff --git a/xfa/include/fwl/core/fwl_thread.h b/xfa/include/fwl/core/fwl_thread.h
new file mode 100644
index 0000000000..9ce742b368
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_thread.h
@@ -0,0 +1,56 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_THREAD_H
+#define _FWL_THREAD_H
+class IFWL_NoteDriver;
+class IFWL_Thread;
+class IFWL_NoteThread;
+typedef struct _FWL_HTHREAD {
+ FX_LPVOID pData;
+} *FWL_HTHREAD;
+class IFWL_Thread
+{
+public:
+ static IFWL_Thread * Create();
+protected:
+ virtual ~IFWL_Thread() {}
+public:
+ virtual void Release() = 0;
+ virtual FWL_ERR Run(FWL_HTHREAD hThread) = 0;
+};
+FWL_HTHREAD FWL_StartThread(IFWL_Thread *pThread, FX_BOOL bSuspended = FALSE);
+FWL_ERR FWL_ResumeThread(FWL_HTHREAD hThread);
+FWL_ERR FWL_SuspendThread(FWL_HTHREAD hThread);
+FWL_ERR FWL_KillThread(FWL_HTHREAD hThread, FX_INT32 iExitCode);
+FWL_ERR FWL_StopThread(FWL_HTHREAD hThread, FX_INT32 iExitCode);
+FWL_ERR FWL_Sleep(FX_DWORD dwMilliseconds);
+class IFWL_NoteThread : public IFWL_Thread
+{
+public:
+ static IFWL_NoteThread* Create();
+ virtual FWL_ERR Run(FWL_HTHREAD hThread) = 0;
+ virtual IFWL_NoteDriver* GetNoteDriver() = 0;
+};
+typedef struct _FWL_HMUTEX {
+ FX_LPVOID pData;
+} *FWL_HMUTEX;
+FWL_HMUTEX FWL_CreateMutex();
+FWL_ERR FWL_DestroyMutex(FWL_HMUTEX hMutex);
+FWL_ERR FWL_LockMutex(FWL_HMUTEX hMutex);
+FWL_ERR FWL_TryLockMutex(FWL_HMUTEX hMutex);
+FWL_ERR FWL_UnlockMutex(FWL_HMUTEX hMutex);
+FWL_ERR FWL_IsLockedMutex(FWL_HMUTEX hMutex, FX_BOOL &bLocked);
+typedef struct _FWL_HSEMAPHORE {
+ FX_LPVOID pData;
+} *FWL_HSEMAPHORE;
+FWL_HSEMAPHORE FWL_CreateSemaphore();
+FWL_ERR FWL_DestroySemaphore(FWL_HSEMAPHORE hSemaphore);
+FWL_ERR FWL_WaitSemaphore(FWL_HSEMAPHORE hSemaphore);
+FWL_ERR FWL_PostSemaphore(FWL_HSEMAPHORE hSemaphore, FX_INT32 down = 1);
+FWL_ERR FWL_GetSemaphoreValue(FWL_HSEMAPHORE hSemaphore, FX_INT32 &value);
+FWL_ERR FWL_ResetSemaphore(FWL_HSEMAPHORE hSemaphore, FX_INT32 init);
+#endif
diff --git a/xfa/include/fwl/core/fwl_timer.h b/xfa/include/fwl/core/fwl_timer.h
new file mode 100644
index 0000000000..3e83c299ff
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_timer.h
@@ -0,0 +1,20 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_TIMER_H
+#define _FWL_TIMER_H
+class IFWL_Timer;
+typedef struct _FWL_HTIMER {
+ FX_LPVOID pData;
+} *FWL_HTIMER;
+class IFWL_Timer
+{
+public:
+ virtual FX_INT32 Run(FWL_HTIMER hTimer) = 0;
+};
+FWL_HTIMER FWL_StartTimer(IFWL_Timer *pTimer, FX_DWORD dwElapse, FX_BOOL bImmediately = TRUE);
+FX_INT32 FWL_StopTimer(FWL_HTIMER hTimer);
+#endif
diff --git a/xfa/include/fwl/core/fwl_widget.h b/xfa/include/fwl/core/fwl_widget.h
new file mode 100644
index 0000000000..f29932f2f2
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_widget.h
@@ -0,0 +1,122 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_WIDGET_H
+#define _FWL_WIDGET_H
+class IFWL_Target;
+class IFWL_ThemeProvider;
+class CFWL_WidgetImpProperties;
+class IFWL_DataProvider;
+class IFWL_Widget;
+class IFWL_WidgetDelegate;
+class IFWL_Custom;
+class IFWL_Proxy;
+class IFWL_Form;
+class IFWL_DataProvider
+{
+public:
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption) = 0;
+};
+class IFWL_Widget : public IFWL_Target
+{
+public:
+ FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ FWL_ERR GetGlobalRect(CFX_RectF &rect);
+ FWL_ERR SetWidgetRect(const CFX_RectF &rect);
+ FWL_ERR GetClientRect(CFX_RectF &rect);
+ IFWL_Widget* GetParent();
+ FWL_ERR SetParent(IFWL_Widget *pParent);
+ IFWL_Widget* GetOwner();
+ FWL_ERR SetOwner(IFWL_Widget *pOwner);
+ IFWL_Widget* GetOuter();
+ FX_DWORD GetStyles();
+ FWL_ERR ModifyStyles(FX_DWORD dwStylesAdded, FX_DWORD dwStylesRemoved);
+ FX_DWORD GetStylesEx();
+ FWL_ERR ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+ FX_DWORD GetStates();
+ FWL_ERR SetStates(FX_DWORD dwStates, FX_BOOL bSet = TRUE);
+ FWL_ERR SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback);
+ FX_LPVOID GetPrivateData(FX_LPVOID module_id);
+ FWL_ERR Update();
+ FWL_ERR LockUpdate();
+ FWL_ERR UnlockUpdate();
+ FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ FWL_ERR TransformTo(IFWL_Widget *pWidget, FX_FLOAT &fx, FX_FLOAT &fy);
+ FWL_ERR TransformTo(IFWL_Widget *pWidget, CFX_RectF &rt);
+ FWL_ERR GetMatrix(CFX_Matrix &matrix, FX_BOOL bGlobal = FALSE);
+ FWL_ERR SetMatrix(const CFX_Matrix &matrix);
+ FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ IFWL_ThemeProvider* GetThemeProvider();
+ FWL_ERR SetThemeProvider(IFWL_ThemeProvider *pThemeProvider);
+ FWL_ERR SetDataProvider(IFWL_DataProvider *pDataProvider);
+ IFWL_WidgetDelegate* SetDelegate(IFWL_WidgetDelegate *pDelegate);
+ IFWL_NoteThread* GetOwnerThread() const;
+ CFX_SizeF GetOffsetFromParent(IFWL_Widget *pParent);
+};
+class IFWL_WidgetDelegate
+{
+public:
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage) = 0;
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent) = 0;
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL) = 0;
+};
+class CFWL_WidgetImpProperties : public CFX_Object
+{
+public:
+ CFWL_WidgetImpProperties()
+ {
+ m_ctmOnParent.Reset();
+ m_rtWidget.Set(0, 0, 0, 0);
+ m_dwStyles = FWL_WGTSTYLE_Child;
+ m_dwStyleExes = 0;
+ m_dwStates = 0;
+ m_pThemeProvider = NULL;
+ m_pDataProvider = NULL;
+ m_pParent = NULL;
+ m_pOwner = NULL;
+ }
+ CFX_Matrix m_ctmOnParent;
+ CFX_RectF m_rtWidget;
+ FX_DWORD m_dwStyles;
+ FX_DWORD m_dwStyleExes;
+ FX_DWORD m_dwStates;
+ IFWL_ThemeProvider *m_pThemeProvider;
+ IFWL_DataProvider *m_pDataProvider;
+ IFWL_Widget *m_pParent;
+ IFWL_Widget *m_pOwner;
+};
+class IFWL_Custom : public IFWL_Widget
+{
+public:
+ static IFWL_Custom* Create();
+
+ FWL_ERR Initialize(IFWL_Widget *pOuter = NULL);
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ FWL_ERR SetProxy(IFWL_Proxy *pProxy);
+protected:
+ IFWL_Custom();
+ virtual ~IFWL_Custom();
+};
+class IFWL_Proxy
+{
+public:
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE) = 0;
+ virtual FWL_ERR Update() = 0;
+};
+#define FWL_ACCEL_Control (1L << 0)
+#define FWL_ACCEL_Alt (1L << 1)
+#define FWL_ACCEL_Shift (1L << 2)
+#define FWL_ACCEL_VirtKey (1L << 3)
+typedef struct _FWL_ACCEL {
+ FX_DWORD dwKey;
+ FX_DWORD dwCmd;
+} FWL_ACCEL;
+typedef CFX_MapPtrTemplate <FX_DWORD, FX_DWORD> CFX_MapAccelerators;
+FWL_ERR FWL_Accelerator_SetApp(CFX_MapAccelerators *pMapAccel);
+FWL_ERR FWL_Accelerator_SetThread(CFX_MapAccelerators *pMapAccel);
+FWL_ERR FWL_Accelerator_SetForm(IFWL_Form *pFrom, CFX_MapAccelerators *pMapAccel);
+FWL_ERR FWL_EnabelWidget(IFWL_Widget *widget, FX_BOOL bEnable);
+#endif
diff --git a/xfa/include/fwl/core/fwl_widgetdef.h b/xfa/include/fwl/core/fwl_widgetdef.h
new file mode 100644
index 0000000000..27c3b55b67
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_widgetdef.h
@@ -0,0 +1,247 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_WIDGETDEF_H
+#define _FWL_WIDGETDEF_H
+#define FWL_WGTSTYLE_OverLapper (0L << 0)
+#define FWL_WGTSTYLE_Popup (1L << 0)
+#define FWL_WGTSTYLE_Child (2L << 0)
+#define FWL_WGTSTYLE_Border (1L << 2)
+#define FWL_WGTSTYLE_Caption (1L << 3)
+#define FWL_WGTSTYLE_NarrowCaption (1L << 4)
+#define FWL_WGTSTYLE_Icon (1L << 5)
+#define FWL_WGTSTYLE_MinimizeBox (1L << 6)
+#define FWL_WGTSTYLE_MaximizeBox (1L << 7)
+#define FWL_WGTSTYLE_CloseBox (1L << 8)
+#define FWL_WGTSTYLE_HScroll (1L << 9)
+#define FWL_WGTSTYLE_VScroll (1L << 11)
+#define FWL_WGTSTYLE_LeftScrollbar (1L << 12)
+#define FWL_WGTSTYLE_LeftAlignment (0L << 13)
+#define FWL_WGTSTYLE_CenterAlignment (1L << 13)
+#define FWL_WGTSTYLE_RightAlignment (2L << 13)
+#define FWL_WGTSTYLE_TopAlignment (0L << 15)
+#define FWL_WGTSTYLE_VCenterAlignment (1L << 15)
+#define FWL_WGTSTYLE_BottomAlignment (2L << 15)
+#define FWL_WGTSTYLE_RTLReading (1L << 17)
+#define FWL_WGTSTYLE_RTLLayout (1L << 18)
+#define FWL_WGTSTYLE_EdgeNone (0L << 19)
+#define FWL_WGTSTYLE_EdgeFlat (1L << 19)
+#define FWL_WGTSTYLE_EdgeRaised (2L << 19)
+#define FWL_WGTSTYLE_EdgeSunken (3L << 19)
+#define FWL_WGTSTYLE_EdgeMask (3L << 19)
+#define FWL_WGTSTYLE_Shadow (3L << 21)
+#define FWL_WGTSTYLE_Group (1L << 22)
+#define FWL_WGTSTYLE_TabStop (1L << 23)
+#define FWL_WGTSTYLE_Offscreen (1L << 24)
+#define FWL_WGTSTYLE_DragAcceptFiles (1L << 25)
+#define FWL_WGTSTYLE_TopMost (1L << 26)
+#define FWL_WGTSTYLE_TransParent (1L << 27)
+#define FWL_WGTSTYLE_NoBackground (1L << 28)
+#define FWL_WGTSTYLE_WindowTypeMask (3L << 0)
+#define FWL_WGTSTATE_Restored (0L << 0)
+#define FWL_WGTSTATE_Minimized (1L << 0)
+#define FWL_WGTSTATE_Maximized (2L << 0)
+#define FWL_WGTSTATE_Disabled (1L << 2)
+#define FWL_WGTSTATE_Deactivated (1L << 3)
+#define FWL_WGTSTATE_Focused (1L << 4)
+#define FWL_WGTSTATE_Invisible (1L << 5)
+#define FWL_WGTSTATE_MAX (6)
+#define FWL_WGTHITTEST_Unknown 0
+#define FWL_WGTHITTEST_Client 1
+#define FWL_WGTHITTEST_Left 2
+#define FWL_WGTHITTEST_Top 3
+#define FWL_WGTHITTEST_Right 4
+#define FWL_WGTHITTEST_Bottom 5
+#define FWL_WGTHITTEST_LeftTop 6
+#define FWL_WGTHITTEST_RightTop 7
+#define FWL_WGTHITTEST_LeftBottom 8
+#define FWL_WGTHITTEST_RightBottom 9
+#define FWL_WGTHITTEST_Icon 10
+#define FWL_WGTHITTEST_Titlebar 11
+#define FWL_WGTHITTEST_MinBox 12
+#define FWL_WGTHITTEST_MaxBox 13
+#define FWL_WGTHITTEST_CloseBox 14
+#define FWL_WGTHITTEST_HScrollBar 15
+#define FWL_WGTHITTEST_VScrollBar 16
+#define FWL_WGTHITTEST_Border 17
+#define FWL_WGTHITTEST_Edge 18
+#define FWL_WGTHITTEST_Edit 19
+#define FWL_WGTHITTEST_Transparent 20
+#define FWL_WGTHITTEST_MAX 21
+#define FWL_VKEY_LButton 0x01
+#define FWL_VKEY_RButton 0x02
+#define FWL_VKEY_MButton 0x04
+#define FWL_VKEY_Back 0x08
+#define FWL_VKEY_Tab 0x09
+#define FWL_VKEY_Clear 0x0C
+#define FWL_VKEY_Return 0x0D
+#define FWL_VKEY_Shift 0x10
+#define FWL_VKEY_Control 0x11
+#define FWL_VKEY_Menu 0x12
+#define FWL_VKEY_Pause 0x13
+#define FWL_VKEY_Capital 0x14
+#define FWL_VKEY_Kana 0x15
+#define FWL_VKEY_Hangul 0x15
+#define FWL_VKEY_Junja 0x17
+#define FWL_VKEY_Final 0x18
+#define FWL_VKEY_Hanja 0x19
+#define FWL_VKEY_Kanji 0x19
+#define FWL_VKEY_Escape 0x1B
+#define FWL_VKEY_Convert 0x1C
+#define FWL_VKEY_NonConvert 0x1D
+#define FWL_VKEY_Accept 0x1E
+#define FWL_VKEY_ModeChange 0x1F
+#define FWL_VKEY_Space 0x20
+#define FWL_VKEY_Prior 0x21
+#define FWL_VKEY_Next 0x22
+#define FWL_VKEY_End 0x23
+#define FWL_VKEY_Home 0x24
+#define FWL_VKEY_Left 0x25
+#define FWL_VKEY_Up 0x26
+#define FWL_VKEY_Right 0x27
+#define FWL_VKEY_Down 0x28
+#define FWL_VKEY_Select 0x29
+#define FWL_VKEY_Print 0x2A
+#define FWL_VKEY_Execute 0x2B
+#define FWL_VKEY_Snapshot 0x2C
+#define FWL_VKEY_Insert 0x2D
+#define FWL_VKEY_Delete 0x2E
+#define FWL_VKEY_Help 0x2F
+#define FWL_VKEY_0 0x30
+#define FWL_VKEY_1 0x31
+#define FWL_VKEY_2 0x32
+#define FWL_VKEY_3 0x33
+#define FWL_VKEY_4 0x34
+#define FWL_VKEY_5 0x35
+#define FWL_VKEY_6 0x36
+#define FWL_VKEY_7 0x37
+#define FWL_VKEY_8 0x38
+#define FWL_VKEY_9 0x39
+#define FWL_VKEY_A 0x41
+#define FWL_VKEY_B 0x42
+#define FWL_VKEY_C 0x43
+#define FWL_VKEY_D 0x44
+#define FWL_VKEY_E 0x45
+#define FWL_VKEY_F 0x46
+#define FWL_VKEY_G 0x47
+#define FWL_VKEY_H 0x48
+#define FWL_VKEY_I 0x49
+#define FWL_VKEY_J 0x4A
+#define FWL_VKEY_K 0x4B
+#define FWL_VKEY_L 0x4C
+#define FWL_VKEY_M 0x4D
+#define FWL_VKEY_N 0x4E
+#define FWL_VKEY_O 0x4F
+#define FWL_VKEY_P 0x50
+#define FWL_VKEY_Q 0x51
+#define FWL_VKEY_R 0x52
+#define FWL_VKEY_S 0x53
+#define FWL_VKEY_T 0x54
+#define FWL_VKEY_U 0x55
+#define FWL_VKEY_V 0x56
+#define FWL_VKEY_W 0x57
+#define FWL_VKEY_X 0x58
+#define FWL_VKEY_Y 0x59
+#define FWL_VKEY_Z 0x5A
+#define FWL_VKEY_LWin 0x5B
+#define FWL_VKEY_Command 0x5B
+#define FWL_VKEY_RWin 0x5C
+#define FWL_VKEY_Apps 0x5D
+#define FWL_VKEY_Sleep 0x5F
+#define FWL_VKEY_NumPad0 0x60
+#define FWL_VKEY_NumPad1 0x61
+#define FWL_VKEY_NumPad2 0x62
+#define FWL_VKEY_NumPad3 0x63
+#define FWL_VKEY_NumPad4 0x64
+#define FWL_VKEY_NumPad5 0x65
+#define FWL_VKEY_NumPad6 0x66
+#define FWL_VKEY_NumPad7 0x67
+#define FWL_VKEY_NumPad8 0x68
+#define FWL_VKEY_NumPad9 0x69
+#define FWL_VKEY_Multiply 0x6A
+#define FWL_VKEY_Add 0x6B
+#define FWL_VKEY_Separator 0x6C
+#define FWL_VKEY_Subtract 0x6D
+#define FWL_VKEY_Decimal 0x6E
+#define FWL_VKEY_Divide 0x6F
+#define FWL_VKEY_F1 0x70
+#define FWL_VKEY_F2 0x71
+#define FWL_VKEY_F3 0x72
+#define FWL_VKEY_F4 0x73
+#define FWL_VKEY_F5 0x74
+#define FWL_VKEY_F6 0x75
+#define FWL_VKEY_F7 0x76
+#define FWL_VKEY_F8 0x77
+#define FWL_VKEY_F9 0x78
+#define FWL_VKEY_F10 0x79
+#define FWL_VKEY_F11 0x7A
+#define FWL_VKEY_F12 0x7B
+#define FWL_VKEY_F13 0x7C
+#define FWL_VKEY_F14 0x7D
+#define FWL_VKEY_F15 0x7E
+#define FWL_VKEY_F16 0x7F
+#define FWL_VKEY_F17 0x80
+#define FWL_VKEY_F18 0x81
+#define FWL_VKEY_F19 0x82
+#define FWL_VKEY_F20 0x83
+#define FWL_VKEY_F21 0x84
+#define FWL_VKEY_F22 0x85
+#define FWL_VKEY_F23 0x86
+#define FWL_VKEY_F24 0x87
+#define FWL_VKEY_NunLock 0x90
+#define FWL_VKEY_Scroll 0x91
+#define FWL_VKEY_LShift 0xA0
+#define FWL_VKEY_RShift 0xA1
+#define FWL_VKEY_LControl 0xA2
+#define FWL_VKEY_RControl 0xA3
+#define FWL_VKEY_LMenu 0xA4
+#define FWL_VKEY_RMenu 0xA5
+#define FWL_VKEY_BROWSER_Back 0xA6
+#define FWL_VKEY_BROWSER_Forward 0xA7
+#define FWL_VKEY_BROWSER_Refresh 0xA8
+#define FWL_VKEY_BROWSER_Stop 0xA9
+#define FWL_VKEY_BROWSER_Search 0xAA
+#define FWL_VKEY_BROWSER_Favorites 0xAB
+#define FWL_VKEY_BROWSER_Home 0xAC
+#define FWL_VKEY_VOLUME_Mute 0xAD
+#define FWL_VKEY_VOLUME_Down 0xAE
+#define FWL_VKEY_VOLUME_Up 0xAF
+#define FWL_VKEY_MEDIA_NEXT_Track 0xB0
+#define FWL_VKEY_MEDIA_PREV_Track 0xB1
+#define FWL_VKEY_MEDIA_Stop 0xB2
+#define FWL_VKEY_MEDIA_PLAY_Pause 0xB3
+#define FWL_VKEY_MEDIA_LAUNCH_Mail 0xB4
+#define FWL_VKEY_MEDIA_LAUNCH_MEDIA_Select 0xB5
+#define FWL_VKEY_MEDIA_LAUNCH_APP1 0xB6
+#define FWL_VKEY_MEDIA_LAUNCH_APP2 0xB7
+#define FWL_VKEY_OEM_1 0xBA
+#define FWL_VKEY_OEM_Plus 0xBB
+#define FWL_VKEY_OEM_Comma 0xBC
+#define FWL_VKEY_OEM_Minus 0xBD
+#define FWL_VKEY_OEM_Period 0xBE
+#define FWL_VKEY_OEM_2 0xBF
+#define FWL_VKEY_OEM_3 0xC0
+#define FWL_VKEY_OEM_4 0xDB
+#define FWL_VKEY_OEM_5 0xDC
+#define FWL_VKEY_OEM_6 0xDD
+#define FWL_VKEY_OEM_7 0xDE
+#define FWL_VKEY_OEM_8 0xDF
+#define FWL_VKEY_OEM_102 0xE2
+#define FWL_VKEY_ProcessKey 0xE5
+#define FWL_VKEY_Packet 0xE7
+#define FWL_VKEY_Attn 0xF6
+#define FWL_VKEY_Crsel 0xF7
+#define FWL_VKEY_Exsel 0xF8
+#define FWL_VKEY_Ereof 0xF9
+#define FWL_VKEY_Play 0xFA
+#define FWL_VKEY_Zoom 0xFB
+#define FWL_VKEY_NoName 0xFC
+#define FWL_VKEY_PA1 0xFD
+#define FWL_VKEY_OEM_Clear 0xFE
+#define FWL_VKEY_Unknown 0
+#define FWL_VKEYSTATE_Toggled 0x0001
+#define FWL_VKEYSTATE_Down 0x0100
+#endif
diff --git a/xfa/include/fwl/core/fwl_widgetmgr.h b/xfa/include/fwl/core/fwl_widgetmgr.h
new file mode 100644
index 0000000000..8db4f34503
--- /dev/null
+++ b/xfa/include/fwl/core/fwl_widgetmgr.h
@@ -0,0 +1,47 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_WIDGETMGR_H
+#define _FWL_WIDGETMGR_H
+class IFWL_Widget;
+class IFWL_WidgetMgr;
+class IFWL_WidgetMgrDelegate;
+enum FWL_WGTRELATION {
+ FWL_WGTRELATION_Parent = 0,
+ FWL_WGTRELATION_Owner,
+ FWL_WGTRELATION_FirstSibling,
+ FWL_WGTRELATION_PriorSibling,
+ FWL_WGTRELATION_NextSibling,
+ FWL_WGTRELATION_LastSibling,
+ FWL_WGTRELATION_FirstChild,
+ FWL_WGTRELATION_LastChild,
+ FWL_WGTRELATION_SystemForm
+};
+class IFWL_WidgetMgr
+{
+public:
+ virtual FX_INT32 CountWidgets(IFWL_Widget *pParent = NULL) = 0;
+ virtual IFWL_Widget* GetWidget(FX_INT32 nIndex, IFWL_Widget *pParent = NULL) = 0;
+ virtual IFWL_Widget* GetWidget(IFWL_Widget *pWidget, FWL_WGTRELATION eRelation) = 0;
+ virtual FX_INT32 GetWidgetIndex(IFWL_Widget *pWidget) = 0;
+ virtual FX_BOOL SetWidgetIndex(IFWL_Widget *pWidget, FX_INT32 nIndex) = 0;
+ virtual FX_BOOL IsWidget(FX_LPVOID pObj) = 0;
+ virtual FWL_ERR RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect = NULL) = 0;
+ virtual FX_DWORD GetCapability() = 0;
+};
+IFWL_WidgetMgr* FWL_GetWidgetMgr();
+FX_BOOL FWL_WidgetIsChild(IFWL_Widget *parent, IFWL_Widget *find);
+#define FWL_WGTMGR_DisableThread 0x00000001
+#define FWL_WGTMGR_DisableForm 0x00000002
+class IFWL_WidgetMgrDelegate
+{
+public:
+ virtual FWL_ERR OnSetCapability(FX_DWORD dwCapability = FWL_WGTMGR_DisableThread) = 0;
+ virtual FX_INT32 OnProcessMessageToForm(CFWL_Message *pMessage) = 0;
+ virtual FWL_ERR OnDrawWidget(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL) = 0;
+};
+FWL_ERR FWL_WidgetMgrSnapshot(IFWL_Widget *pWidget, const CFX_WideString *saveFile, const CFX_Matrix *pMatrix = NULL);
+#endif
diff --git a/xfa/include/fwl/fwl.h b/xfa/include/fwl/fwl.h
new file mode 100644
index 0000000000..a8363a192b
--- /dev/null
+++ b/xfa/include/fwl/fwl.h
@@ -0,0 +1,76 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_H
+#define _FWL_H
+#include "core/fwl_error.h"
+#include "core/fwl_target.h"
+#include "core/fwl_thread.h"
+#include "core/fwl_note.h"
+#include "core/fwl_widgetdef.h"
+#include "core/fwl_theme.h"
+#include "core/fwl_widget.h"
+#include "core/fwl_content.h"
+#include "core/fwl_panel.h"
+#include "core/fwl_form.h"
+#include "core/fwl_widgetmgr.h"
+#include "core/fwl_timer.h"
+#include "core/fwl_app.h"
+#include "core/fwl_grid.h"
+#include "basewidget/fwl_pushbutton.h"
+#include "basewidget/fwl_checkbox.h"
+#include "basewidget/fwl_scrollbar.h"
+#include "basewidget/fwl_listbox.h"
+#include "basewidget/fwl_edit.h"
+#include "basewidget/fwl_picturebox.h"
+#include "basewidget/fwl_combobox.h"
+#include "basewidget/fwl_menu.h"
+#include "basewidget/fwl_monthcalendar.h"
+#include "basewidget/fwl_datetimepicker.h"
+#include "basewidget/fwl_spinbutton.h"
+#include "basewidget/fwl_barcode.h"
+#include "basewidget/fxmath_barcode.h"
+#include "basewidget/fwl_tooltipctrl.h"
+#include "basewidget/fwl_caret.h"
+#include "lightwidget/app.h"
+#include "lightwidget/widget.h"
+#include "lightwidget/pushbutton.h"
+#include "lightwidget/checkbox.h"
+#include "lightwidget/scrollbar.h"
+#include "lightwidget/listbox.h"
+#include "lightwidget/picturebox.h"
+#include "lightwidget/edit.h"
+#include "lightwidget/combobox.h"
+#include "lightwidget/datetimepicker.h"
+#include "lightwidget/barcode.h"
+#include "lightwidget/theme.h"
+#include "lightwidget/tooltipctrl.h"
+#include "lightwidget/caret.h"
+#include "theme/utils.h"
+#include "theme/widgettp.h"
+#include "theme/barcodetp.h"
+#include "theme/checkboxtp.h"
+#include "theme/comboboxtp.h"
+#include "theme/datetimepickertp.h"
+#include "theme/edittp.h"
+#include "theme/formtp.h"
+#include "theme/listboxtp.h"
+#include "theme/monthcalendartp.h"
+#include "theme/pictureboxtp.h"
+#include "theme/pushbuttontp.h"
+#include "theme/scrollbartp.h"
+#include "theme/widgettp.h"
+#include "theme/barcodetp.h"
+#include "theme/carettp.h"
+#include "adapter/fwl_adapternative.h"
+#include "adapter/fwl_adapterthreadmgr.h"
+#include "adapter/fwl_adaptertimermgr.h"
+#include "adapter/fwl_adapterwidgetmgr.h"
+#include "adapter/fwl_adaptercursormgr.h"
+#include "adapter/fwl_adaptermonitormgr.h"
+#include "adapter/fwl_adapterclipboardmgr.h"
+#include "adapter/fwl_sdadapterimp.h"
+#endif
diff --git a/xfa/include/fwl/lightwidget/app.h b/xfa/include/fwl/lightwidget/app.h
new file mode 100644
index 0000000000..11919508aa
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/app.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_APP_LIGHT_H
+#define _FWL_APP_LIGHT_H
+class CFWL_Theme;
+class IFWL_App;
+class CFWL_App;
+class CFWL_App : public CFX_Object
+{
+public:
+ CFWL_App();
+ virtual ~CFWL_App();
+ FWL_ERR Initialize();
+ CFWL_Theme* GetTheme();
+ FWL_ERR Exit(FX_INT32 iExitCode = 0);
+ IFWL_App* GetApp();
+protected:
+ IFWL_App *m_pAppImp;
+ CFWL_Theme *m_pThemeProvider;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/barcode.h b/xfa/include/fwl/lightwidget/barcode.h
new file mode 100644
index 0000000000..e8fcfea476
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/barcode.h
@@ -0,0 +1,177 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_BARCODE_LIGHT_H
+#define _FWL_BARCODE_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_BarcodeDP;
+class CFWL_Edit;
+class CFWL_Barcode;
+class CFWL_BarcodeDP;
+class CFWL_Barcode : public CFWL_Edit
+{
+public:
+ static CFWL_Barcode* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ void SetType(BC_TYPE type);
+ FX_BOOL IsProtectedType();
+public:
+ void SetCharEncoding(BC_CHAR_ENCODING encoding)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_CHARENCODING;
+ m_barcodeData.m_eCharEncoding = encoding;
+ }
+ void SetModuleHeight(FX_INT32 height)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_MODULEHEIGHT;
+ m_barcodeData.m_nModuleHeight = height;
+ }
+ void SetModuleWidth(FX_INT32 width)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_MODULEWIDTH;
+ m_barcodeData.m_nModuleWidth = width;
+ }
+ void SetDataLength(FX_INT32 dataLength)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_DATALENGTH;
+ m_barcodeData.m_nDataLength = dataLength;
+ ((IFWL_Barcode*)m_pImp)->SetLimit(dataLength);
+ }
+ void SetCalChecksum(FX_INT32 calChecksum)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_CALCHECKSUM;
+ m_barcodeData.m_nCalChecksum = calChecksum;
+ }
+ void SetPrintChecksum(FX_BOOL printChecksum)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_PRINTCHECKSUM;
+ m_barcodeData.m_bPrintChecksum = printChecksum;
+ }
+ void SetTextLocation(BC_TEXT_LOC location)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_TEXTLOCATION;
+ m_barcodeData.m_eTextLocation = location;
+ }
+ void SetWideNarrowRatio(FX_INT32 ratio)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_WIDENARROWRATIO;
+ m_barcodeData.m_nWideNarrowRatio = ratio;
+ }
+ void SetStartChar(FX_CHAR startChar)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_STARTCHAR;
+ m_barcodeData.m_cStartChar = startChar;
+ }
+ void SetEndChar(FX_CHAR endChar)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_ENDCHAR;
+ m_barcodeData.m_cEndChar = endChar;
+ }
+ void SetVersion(FX_INT32 version)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_VERSION;
+ m_barcodeData.m_nVersion = version;
+ }
+ void SetErrorCorrectionLevel(FX_INT32 ecLevel)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_ECLEVEL;
+ m_barcodeData.m_nECLevel = ecLevel;
+ }
+ void SetTruncated(FX_BOOL truncated)
+ {
+ m_barcodeData.m_dwAttributeMask |= FWL_BCDATTRIBUTE_TRUNCATED;
+ m_barcodeData.m_bTruncated = truncated;
+ }
+ void ResetBarcodeAttributes()
+ {
+ m_barcodeData.m_dwAttributeMask = 0;
+ }
+protected:
+ CFWL_Barcode();
+ virtual ~CFWL_Barcode();
+ class CFWL_BarcodeDP : public IFWL_BarcodeDP
+ {
+ public:
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+ BC_CHAR_ENCODING m_eCharEncoding;
+ virtual BC_CHAR_ENCODING GetCharEncoding()
+ {
+ return m_eCharEncoding;
+ }
+ FX_INT32 m_nModuleHeight, m_nModuleWidth;
+ virtual FX_INT32 GetModuleHeight()
+ {
+ return m_nModuleHeight;
+ }
+ virtual FX_INT32 GetModuleWidth()
+ {
+ return m_nModuleWidth;
+ }
+ FX_INT32 m_nDataLength;
+ virtual FX_INT32 GetDataLength()
+ {
+ return m_nDataLength;
+ }
+ FX_INT32 m_nCalChecksum;
+ virtual FX_INT32 GetCalChecksum()
+ {
+ return m_nCalChecksum;
+ }
+ FX_BOOL m_bPrintChecksum;
+ virtual FX_BOOL GetPrintChecksum()
+ {
+ return m_bPrintChecksum;
+ }
+
+ BC_TEXT_LOC m_eTextLocation;
+ virtual BC_TEXT_LOC GetTextLocation()
+ {
+ return m_eTextLocation;
+ }
+ FX_INT32 m_nWideNarrowRatio;
+ virtual FX_INT32 GetWideNarrowRatio()
+ {
+ return m_nWideNarrowRatio;
+ }
+ FX_CHAR m_cStartChar, m_cEndChar;
+ virtual FX_CHAR GetStartChar()
+ {
+ return m_cStartChar;
+ }
+ virtual FX_CHAR GetEndChar()
+ {
+ return m_cEndChar;
+ }
+ FX_INT32 m_nVersion;
+ virtual FX_INT32 GetVersion()
+ {
+ return m_nVersion;
+ }
+ FX_INT32 m_nECLevel;
+ virtual FX_INT32 GetErrorCorrectionLevel()
+ {
+ return m_nECLevel;
+ }
+ FX_BOOL m_bTruncated;
+ virtual FX_BOOL GetTruncated()
+ {
+ return m_bTruncated;
+ }
+ FX_DWORD m_dwAttributeMask;
+ virtual FX_DWORD GetBarcodeAttributeMask()
+ {
+ return m_dwAttributeMask;
+ }
+ public:
+ CFWL_BarcodeDP()
+ : m_dwAttributeMask(0)
+ {
+ }
+ };
+ CFWL_BarcodeDP m_barcodeData;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/caret.h b/xfa/include/fwl/lightwidget/caret.h
new file mode 100644
index 0000000000..d4c2e7702f
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/caret.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CARET_LIGHT_H
+#define _FWL_CARET_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class CFWL_Caret;
+class CFWL_Caret : public CFWL_Widget
+{
+public:
+ static CFWL_Caret* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FWL_ERR ShowCaret(FX_BOOL bFlag = TRUE);
+ FWL_ERR GetFrequency(FX_DWORD &elapse);
+ FWL_ERR SetFrequency(FX_DWORD elapse);
+ FWL_ERR SetColor(CFX_Color crFill);
+protected:
+ CFWL_Caret();
+ virtual ~CFWL_Caret();
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/checkbox.h b/xfa/include/fwl/lightwidget/checkbox.h
new file mode 100644
index 0000000000..2f7b2bac97
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/checkbox.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CHECKBOX_LIGHT_H
+#define _FWL_CHECKBOX_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_CheckBoxDP;
+class CFWL_CheckBox;
+class CFWL_CheckBoxDP;
+class CFWL_CheckBox : public CFWL_Widget
+{
+public:
+ static CFWL_CheckBox* Create();
+
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FWL_ERR GetCaption(CFX_WideString &wsCaption);
+ FWL_ERR SetCaption(FX_WSTR wsCaption);
+ FWL_ERR SetBoxSize(FX_FLOAT fHeight);
+ FX_INT32 GetCheckState();
+ FWL_ERR SetCheckState(FX_INT32 iCheck);
+ CFWL_CheckBox();
+ virtual ~CFWL_CheckBox();
+protected:
+ class CFWL_CheckBoxDP : public IFWL_CheckBoxDP
+ {
+ public:
+ CFWL_CheckBoxDP();
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+ virtual FX_FLOAT GetBoxSize(IFWL_Widget *pWidget);
+ FX_FLOAT m_fBoxHeight;
+ CFX_WideString m_wsCaption;
+ };
+ CFWL_CheckBoxDP m_checkboxData;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/combobox.h b/xfa/include/fwl/lightwidget/combobox.h
new file mode 100644
index 0000000000..eac58569aa
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/combobox.h
@@ -0,0 +1,115 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_COMBOBOX_LIGHT_H
+#define _FWL_COMBOBOX_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_ComboBoxDP;
+class CFWL_ComboBox;
+class CFWL_ComboBoxDP;
+class CFWL_ComboBoxItem;
+class CFWL_ComboBox : public CFWL_Widget
+{
+public:
+ static CFWL_ComboBox* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FX_INT32 AddString(FX_WSTR wsText);
+ FX_INT32 AddString(FX_WSTR wsText, CFX_DIBitmap *pIcon);
+ FX_INT32 RemoveAt(FX_INT32 iIndex);
+ FX_INT32 RemoveAll();
+ FX_INT32 CountItems();
+ FWL_ERR GetTextByIndex(FX_INT32 iIndex, CFX_WideString &wsText);
+ FX_INT32 GetCurSel();
+ FWL_ERR SetCurSel(FX_INT32 iSel);
+ FWL_ERR SetEditText(FX_WSTR wsText);
+ FX_INT32 GetEditTextLength() const;
+ FWL_ERR GetEditText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const ;
+ FWL_ERR SetEditSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ FX_INT32 GetEditSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ FX_INT32 GetEditLimit();
+ FWL_ERR SetEditLimit(FX_INT32 nLimit);
+ FWL_ERR EditDoClipboard(FX_INT32 iCmd);
+ FX_BOOL EditRedo(FX_BSTR bsRecord);
+ FX_BOOL EditUndo(FX_BSTR bsRecord);
+ FWL_ERR SetMaxListHeight(FX_FLOAT fMaxHeight);
+ FWL_ERR SetItemData(FX_INT32 iIndex, FX_LPVOID pData);
+ FX_LPVOID GetItemData(FX_INT32 iIndex);
+ FWL_ERR SetListTheme(IFWL_ThemeProvider *pTheme);
+ FX_BOOL AfterFocusShowDropList();
+ FWL_ERR OpenDropDownList(FX_BOOL bActivate);
+public:
+ FX_BOOL EditCanUndo();
+ FX_BOOL EditCanRedo();
+ FX_BOOL EditUndo();
+ FX_BOOL EditRedo();
+ FX_BOOL EditCanCopy();
+ FX_BOOL EditCanCut();
+ FX_BOOL EditCanSelectAll();
+ FX_BOOL EditCopy(CFX_WideString &wsCopy);
+ FX_BOOL EditCut(CFX_WideString &wsCut);
+ FX_BOOL EditPaste(const CFX_WideString &wsPaste);
+ FX_BOOL EditSelectAll();
+ FX_BOOL EditDelete();
+ FX_BOOL EditDeSelect();
+ FWL_ERR GetBBox(CFX_RectF &rect);
+ FWL_ERR EditModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+ CFWL_ComboBox();
+ virtual ~CFWL_ComboBox();
+protected:
+ class CFWL_ComboBoxDP : public IFWL_ComboBoxDP
+ {
+ public:
+ CFWL_ComboBoxDP();
+ ~CFWL_ComboBoxDP();
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+ {
+ return FWL_ERR_Succeeded;
+ }
+
+ virtual FX_INT32 CountItems(IFWL_Widget *pWidget);
+ virtual FWL_HLISTITEM GetItem(IFWL_Widget *pWidget, FX_INT32 nIndex);
+ virtual FX_INT32 GetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FX_BOOL SetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_INT32 nIndex);
+
+ virtual FX_DWORD GetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FWL_ERR GetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_WideString &wsText);
+ virtual FWL_ERR GetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF& rtItem);
+ virtual FX_LPVOID GetItemData(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FWL_ERR SetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwStyle);
+ virtual FWL_ERR SetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_LPCWSTR pszText);
+ virtual FWL_ERR SetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF& rtItem);
+ virtual FX_FLOAT GetItemHeight(IFWL_Widget *pWidget);
+ virtual CFX_DIBitmap* GetItemIcon(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FWL_ERR GetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF& rtCheck);
+ virtual FWL_ERR SetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF& rtCheck);
+ virtual FX_DWORD GetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FWL_ERR SetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwCheckState);
+ virtual FX_FLOAT GetListHeight(IFWL_Widget *pWidget);
+
+ CFX_PtrArray m_arrItem;
+ FX_FLOAT m_fMaxListHeight;
+ FX_FLOAT m_fItemHeight;
+ };
+ CFWL_ComboBoxDP m_comboBoxData;
+};
+class CFWL_ComboBoxItem : public CFX_Object
+{
+public:
+ CFWL_ComboBoxItem()
+ {
+ m_pDIB = NULL;
+ m_pData = NULL;
+ }
+ CFX_RectF m_rtItem;
+ FX_DWORD m_dwStyles;
+ CFX_WideString m_wsText;
+ CFX_DIBitmap *m_pDIB;
+ FX_DWORD m_dwCheckState;
+ CFX_RectF m_rtCheckBox;
+ FX_LPVOID m_pData;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/datetimepicker.h b/xfa/include/fwl/lightwidget/datetimepicker.h
new file mode 100644
index 0000000000..73a382c08c
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/datetimepicker.h
@@ -0,0 +1,58 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_DATETIMEPICKER_LIGHT_H
+#define _FWL_DATETIMEPICKER_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_DateTimePickerDP;
+class CFWL_DateTimePicker;
+class CFWL_DateTimePickerDP;
+class CFWL_DateTimePicker : public CFWL_Widget
+{
+public:
+ static CFWL_DateTimePicker* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FWL_ERR SetToday(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+ FWL_ERR GetEditText(CFX_WideString &wsText);
+ FWL_ERR SetEditText(FX_WSTR wsText);
+ FX_INT32 CountSelRanges();
+ FX_INT32 GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ FWL_ERR GetCurSel(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay);
+ FWL_ERR SetCurSel(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+ FX_BOOL CanUndo();
+ FX_BOOL CanRedo();
+ FX_BOOL Undo();
+ FX_BOOL Redo();
+ FX_BOOL CanCopy();
+ FX_BOOL CanCut();
+ FX_BOOL CanSelectAll();
+ FX_BOOL Copy(CFX_WideString &wsCopy);
+ FX_BOOL Cut(CFX_WideString &wsCut);
+ FX_BOOL Paste(const CFX_WideString &wsPaste);
+ FX_BOOL SelectAll();
+ FX_BOOL Delete();
+ FX_BOOL DeSelect();
+ FWL_ERR GetBBox(CFX_RectF &rect);
+ FWL_ERR SetEditLimit(FX_INT32 nLimit);
+ FWL_ERR ModifyEditStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+protected:
+ CFWL_DateTimePicker();
+ virtual ~CFWL_DateTimePicker();
+ class CFWL_DateTimePickerDP : public IFWL_DateTimePickerDP
+ {
+ public:
+ CFWL_DateTimePickerDP();
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+ virtual FWL_ERR GetToday(IFWL_Widget *pWidget, FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay);
+ FX_INT32 m_iYear;
+ FX_INT32 m_iMonth;
+ FX_INT32 m_iDay;
+ CFX_WideString m_wsData;
+ };
+ CFWL_DateTimePickerDP m_DateTimePickerDP;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/edit.h b/xfa/include/fwl/lightwidget/edit.h
new file mode 100644
index 0000000000..8299a20322
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/edit.h
@@ -0,0 +1,57 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_EDIT_LIGHT_H
+#define _FWL_EDIT_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class CFWL_Edit;
+class CFWL_Edit : public CFWL_Widget
+{
+public:
+ static CFWL_Edit* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FWL_ERR SetText(const CFX_WideString &wsText);
+ FX_INT32 GetTextLength() const;
+ FWL_ERR GetText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const;
+ FWL_ERR ClearText();
+ FX_INT32 GetCaretPos() const;
+ FX_INT32 SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore = TRUE);
+ FWL_ERR AddSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ FX_INT32 CountSelRanges();
+ FX_INT32 GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ FWL_ERR ClearSelections();
+ FX_INT32 GetLimit();
+ FWL_ERR SetLimit(FX_INT32 nLimit);
+ FWL_ERR SetAliasChar(FX_WCHAR wAlias);
+ FWL_ERR SetFormatString(const CFX_WideString &wsFormat);
+ FWL_ERR Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen);
+ FWL_ERR DeleteSelections();
+ FWL_ERR DeleteRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ FWL_ERR ReplaceSelections(const CFX_WideStringC &wsReplace);
+ FWL_ERR Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace);
+ FWL_ERR DoClipboard(FX_INT32 iCmd);
+ FX_BOOL Redo(FX_BSTR bsRecord);
+ FX_BOOL Undo(FX_BSTR bsRecord);
+ FWL_ERR SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant);
+ FWL_ERR SetNumberRange(FX_INT32 iMin, FX_INT32 iMax);
+ FWL_ERR SetBackColor(FX_DWORD dwColor);
+ FWL_ERR SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize);
+ FX_BOOL CanUndo();
+ FX_BOOL CanRedo();
+ FX_BOOL Undo();
+ FX_BOOL Redo();
+ FX_BOOL Copy(CFX_WideString &wsCopy);
+ FX_BOOL Cut(CFX_WideString &wsCut);
+ FX_BOOL Paste(const CFX_WideString &wsPaste);
+ FX_BOOL Delete();
+ void SetScrollOffset(FX_FLOAT fScrollOffset);
+ FX_BOOL GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest);
+ FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace);
+ CFWL_Edit();
+ virtual ~CFWL_Edit();
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/listbox.h b/xfa/include/fwl/lightwidget/listbox.h
new file mode 100644
index 0000000000..3cb1131e8b
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/listbox.h
@@ -0,0 +1,98 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_LISTBOX_LIGHT_H
+#define _FWL_LISTBOX_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_ListBoxDP;
+class CFWL_ListBox;
+class CFWL_ListItem;
+class CFWL_ListBox : public CFWL_Widget
+{
+public:
+ static CFWL_ListBox* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FWL_ERR AddDIBitmap(CFX_DIBitmap * pDIB, FWL_HLISTITEM hItem);
+ FWL_HLISTITEM AddString(FX_WSTR wsAdd, FX_BOOL bSelect = FALSE);
+ FX_BOOL DeleteString(FWL_HLISTITEM hItem);
+ FX_BOOL DeleteAll();
+ FX_INT32 CountSelItems();
+ FWL_HLISTITEM GetSelItem(FX_INT32 nIndexSel);
+ FX_INT32 GetSelIndex(FX_INT32 nIndex);
+ FWL_ERR SetSelItem(FWL_HLISTITEM hItem, FX_BOOL bSelect = TRUE);
+ FWL_ERR GetItemText(FWL_HLISTITEM hItem, CFX_WideString &wsText);
+ FWL_ERR GetScrollPos(FX_FLOAT &fPos, FX_BOOL bVert = TRUE);
+ FWL_ERR SetItemHeight(FX_FLOAT fItemHeight);
+ FWL_HLISTITEM GetFocusItem();
+ FWL_ERR SetFocusItem(FWL_HLISTITEM hItem);
+ FWL_ERR* Sort(IFWL_ListBoxCompare *pCom);
+ FX_INT32 CountItems();
+ FWL_HLISTITEM GetItem(FX_INT32 nIndex);
+ FWL_ERR SetItemString(FWL_HLISTITEM hItem, FX_WSTR wsText);
+ FWL_ERR GetItemString(FWL_HLISTITEM hItem, CFX_WideString &wsText);
+ FWL_ERR SetItemData(FWL_HLISTITEM hItem, FX_LPVOID pData);
+ FX_LPVOID GetItemData(FWL_HLISTITEM hItem);
+ FWL_HLISTITEM GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy);
+ FX_DWORD GetItemStates(FWL_HLISTITEM hItem);
+ CFWL_ListBox();
+ virtual ~CFWL_ListBox();
+protected:
+ class CFWL_ListBoxDP : public IFWL_ListBoxDP, public CFX_Object
+ {
+ public:
+ CFWL_ListBoxDP();
+ ~CFWL_ListBoxDP();
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+
+ virtual FX_INT32 CountItems(IFWL_Widget *pWidget);
+ virtual FWL_HLISTITEM GetItem(IFWL_Widget *pWidget, FX_INT32 nIndex);
+ virtual FX_INT32 GetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FX_BOOL SetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_INT32 nIndex);
+
+ virtual FX_DWORD GetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FWL_ERR GetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_WideString &wsText);
+ virtual FWL_ERR GetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF &rtItem);
+ virtual FX_LPVOID GetItemData(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+
+ virtual FWL_ERR SetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwStyle);
+ virtual FWL_ERR SetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_LPCWSTR pszText);
+ virtual FWL_ERR SetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF &rtItem);
+ virtual FX_FLOAT GetItemHeight(IFWL_Widget *pWidget);
+ virtual CFX_DIBitmap* GetItemIcon(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FWL_ERR GetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF& rtCheck);
+ virtual FWL_ERR SetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF& rtCheck);
+ virtual FX_DWORD GetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem);
+ virtual FWL_ERR SetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwCheckState);
+
+ CFX_PtrArray m_arrItem;
+ CFX_WideString m_wsData;
+ FX_FLOAT m_fItemHeight;
+ };
+ CFWL_ListBoxDP m_ListBoxDP;
+};
+class CFWL_ListItem : public CFX_Object
+{
+public:
+ CFWL_ListItem()
+ {
+ m_rtItem.Reset();
+ m_dwStates = 0;
+ m_wsText = L"";
+ m_pDIB = NULL;
+ m_pData = NULL;
+ m_dwCheckState = 0;
+ m_rtCheckBox.Reset();
+ }
+ CFX_RectF m_rtItem;
+ FX_DWORD m_dwStates;
+ CFX_WideString m_wsText;
+ CFX_DIBitmap *m_pDIB;
+ FX_LPVOID m_pData;
+ FX_DWORD m_dwCheckState;
+ CFX_RectF m_rtCheckBox;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/picturebox.h b/xfa/include/fwl/lightwidget/picturebox.h
new file mode 100644
index 0000000000..dd87d6806b
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/picturebox.h
@@ -0,0 +1,65 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PICTUREBOX_LIGHT_H
+#define _FWL_PICTUREBOX_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_PictureBoxDP;
+class CFWL_PictureBox;
+class CFWL_PictureBoxDP;
+class CFWL_PictureBox : public CFWL_Widget
+{
+public:
+ static CFWL_PictureBox* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ CFX_DIBitmap* GetPicture();
+ FWL_ERR SetPicture(CFX_DIBitmap *pBitmap);
+ FX_FLOAT GetRotation();
+ FWL_ERR SetRotation(FX_FLOAT fRotation);
+ FX_INT32 GetFlipMode();
+ FWL_ERR SetFlipMode(FX_INT32 iFlipMode);
+ FX_INT32 GetOpacity();
+ FWL_ERR SetOpacity(FX_INT32 iOpacity);
+ FWL_ERR GetScale(FX_FLOAT &fScaleX, FX_FLOAT &fScaleY);
+ FWL_ERR SetScale(FX_FLOAT fScaleX, FX_FLOAT fScaleY);
+ FWL_ERR GetOffset(FX_FLOAT &fx, FX_FLOAT &fy);
+ FWL_ERR SetOffset(FX_FLOAT fx, FX_FLOAT fy);
+ CFWL_PictureBox();
+ virtual ~CFWL_PictureBox();
+protected:
+ class CFWL_PictureBoxDP : public IFWL_PictureBoxDP
+ {
+ public:
+ CFWL_PictureBoxDP()
+ {
+ m_fRotation = 0.0f;
+ m_fScaleX = 1.0f;
+ m_fScaleY = 1.0f;
+ m_fOffSetX = 0.0f;
+ m_fOffSetY = 0.0f;
+ m_pBitmap = NULL;
+ };
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+ virtual CFX_DIBitmap* GetPicture(IFWL_Widget *pWidget);
+ virtual CFX_DIBitmap* GetErrorPicture(IFWL_Widget *pWidget);
+ virtual CFX_DIBitmap* GetInitialPicture(IFWL_Widget *pWidget);
+ virtual FX_INT32 GetOpacity(IFWL_Widget *pWidget);
+ virtual FX_INT32 GetFlipMode(IFWL_Widget *pWidget);
+ virtual FWL_ERR GetMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix);
+ CFX_DIBitmap *m_pBitmap;
+ FX_INT32 m_iOpacity;
+ FX_INT32 m_iFlipMode;
+ FX_FLOAT m_fRotation;
+ FX_FLOAT m_fScaleX;
+ FX_FLOAT m_fScaleY;
+ FX_FLOAT m_fOffSetX;
+ FX_FLOAT m_fOffSetY;
+ CFX_WideString m_wsData;
+ };
+ CFWL_PictureBoxDP m_PictureBoxDP;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/pushbutton.h b/xfa/include/fwl/lightwidget/pushbutton.h
new file mode 100644
index 0000000000..a7c2a13cfa
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/pushbutton.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PUSHBUTTON_LIGHT_H
+#define _FWL_PUSHBUTTON_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_PushButtonDP;
+class CFWL_PushButton;
+class CFWL_PushButtonDP;
+class CFWL_PushButton : public CFWL_Widget
+{
+public:
+ static CFWL_PushButton* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FWL_ERR GetCaption(CFX_WideString &wsCaption);
+ FWL_ERR SetCaption(FX_WSTR wsCaption);
+ CFX_DIBitmap* GetPicture();
+ FWL_ERR SetPicture(CFX_DIBitmap *pBitmap);
+ CFWL_PushButton();
+ virtual ~CFWL_PushButton();
+protected:
+ class CFWL_PushButtonDP : public IFWL_PushButtonDP
+ {
+ public:
+ CFWL_PushButtonDP(): m_pBitmap(NULL) {}
+ FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+ virtual CFX_DIBitmap* GetPicture(IFWL_Widget *pWidget);
+ CFX_WideString m_wsCaption;
+ CFX_DIBitmap *m_pBitmap;
+ };
+ CFWL_PushButtonDP m_buttonData;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/scrollbar.h b/xfa/include/fwl/lightwidget/scrollbar.h
new file mode 100644
index 0000000000..5aabd56685
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/scrollbar.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_SCROLLBAR_LIGHT_H
+#define _FWL_SCROLLBAR_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class CFWL_ScrollBar;
+class CFWL_ScrollBar : public CFWL_Widget
+{
+public:
+ static CFWL_ScrollBar* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FX_BOOL IsVertical();
+ FWL_ERR GetRange(FX_FLOAT &fMin, FX_FLOAT &fMax);
+ FWL_ERR SetRange(FX_FLOAT fMin, FX_FLOAT fMax);
+ FX_FLOAT GetPageSize();
+ FWL_ERR SetPageSize(FX_FLOAT fPageSize);
+ FX_FLOAT GetStepSize();
+ FWL_ERR SetStepSize(FX_FLOAT fStepSize);
+ FX_FLOAT GetPos();
+ FWL_ERR SetPos(FX_FLOAT fPos);
+ FX_FLOAT GetTrackPos();
+ FWL_ERR SetTrackPos(FX_FLOAT fTrackPos);
+ FX_BOOL DoScroll(FX_DWORD dwCode, FX_FLOAT fPos = 0.0f);
+ CFWL_ScrollBar();
+ virtual ~CFWL_ScrollBar();
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/theme.h b/xfa/include/fwl/lightwidget/theme.h
new file mode 100644
index 0000000000..95e4ed16e3
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/theme.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_THEME_LIGHT_H
+#define _FWL_THEME_LIGHT_H
+class CFWL_ThemeBackground;
+class CFWL_ThemeText;
+class CFWL_ThemePart;
+class CFWL_WidgetTP;
+class IFWL_Widget;
+class CFWL_Theme;
+class CFWL_Theme : public CFX_Object
+{
+public:
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD GetThemeID(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FWL_ERR GetThemeMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix);
+ virtual FWL_ERR SetThemeMatrix(IFWL_Widget *pWidget, const CFX_Matrix &matrix);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_BOOL DrawText(CFWL_ThemeText *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+ virtual FX_BOOL IsCustomizedLayout(IFWL_Widget *pWidget);
+ virtual FWL_ERR GetPartRect(CFWL_ThemePart* pThemePart, CFX_RectF &rtPart);
+ virtual FX_BOOL IsInPart(CFWL_ThemePart* pThemePart, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL CalcTextRect(CFWL_ThemeText *pParams, CFX_RectF &rect);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ CFWL_Theme();
+ virtual ~CFWL_Theme();
+ FWL_ERR SetFont(IFWL_Widget *pWidget, FX_LPCWSTR strFont, FX_FLOAT fFontSize, FX_ARGB rgbFont);
+ CFWL_WidgetTP* GetTheme(IFWL_Widget* pWidget);
+protected:
+ CFX_PtrArray m_arrThemes;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/tooltipctrl.h b/xfa/include/fwl/lightwidget/tooltipctrl.h
new file mode 100644
index 0000000000..114696ff13
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/tooltipctrl.h
@@ -0,0 +1,54 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ToolTip_LIGHT_H
+#define _FWL_ToolTip_LIGHT_H
+class CFWL_Widget;
+class CFWL_WidgetProperties;
+class IFWL_ToolTipDP;
+class CFWL_ToolTip;
+class CFWL_ToolTipDP;
+class CFWL_ToolTip : public CFWL_Widget
+{
+public:
+ static CFWL_ToolTip* Create();
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+ FWL_ERR GetCaption(CFX_WideString &wsCaption);
+ FWL_ERR SetCaption(FX_WSTR wsCaption);
+ FX_INT32 GetInitialDelay();
+ FX_INT32 SetInitialDelay(FX_INT32 nDelayTime);
+ FX_INT32 GetAutoPopDelay();
+ FX_INT32 SetAutoPopDelay(FX_INT32 nDelayTime);
+ CFX_DIBitmap* GetToolTipIcon();
+ FWL_ERR SetToolTipIcon(CFX_DIBitmap* pBitmap);
+ CFX_SizeF GetToolTipIconSize();
+ FWL_ERR SetToolTipIconSize( CFX_SizeF fSize);
+ FWL_ERR SetAnchor(const CFX_RectF &rtAnchor);
+ FWL_ERR Show();
+ FWL_ERR Hide();
+ CFWL_ToolTip();
+ virtual ~CFWL_ToolTip();
+protected:
+ class CFWL_ToolTipDP : public IFWL_ToolTipDP
+ {
+ public:
+ CFWL_ToolTipDP();
+ FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+ FX_INT32 GetInitialDelay(IFWL_Widget *pWidget);
+ FX_INT32 GetAutoPopDelay(IFWL_Widget *pWidget);
+ CFX_DIBitmap* GetToolTipIcon(IFWL_Widget *pWidget);
+ CFX_SizeF GetToolTipIconSize(IFWL_Widget *pWidget);
+ CFX_RectF GetAnchor();
+ CFX_WideString m_wsCaption;
+ FX_INT32 m_nInitDelayTime;
+ FX_INT32 m_nAutoPopDelayTime;
+ CFX_DIBitmap* m_pBitmap;
+ CFX_SizeF m_fIconSize;
+ CFX_RectF m_fAnchor;
+ };
+ CFWL_ToolTipDP m_tooltipData;
+};
+#endif
diff --git a/xfa/include/fwl/lightwidget/widget.h b/xfa/include/fwl/lightwidget/widget.h
new file mode 100644
index 0000000000..af5bddb5e7
--- /dev/null
+++ b/xfa/include/fwl/lightwidget/widget.h
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_WIDGET_LIGHT_H
+#define _FWL_WIDGET_LIGHT_H
+class CFWL_WidgetMgr;
+class CFWL_Message;
+class CFWL_Event;
+class IFWL_WidgetDelegate;
+class IFWL_Widget;
+class CFWL_Widget;
+class CFWL_WidgetDelegate;
+class CFWL_WidgetProperties : public CFX_Object
+{
+public:
+ CFWL_WidgetProperties()
+ {
+ m_ctmOnParent.Reset();
+ m_rtWidget.Set(0, 0, 0, 0);
+ m_dwStyles = FWL_WGTSTYLE_Child;
+ m_dwStyleExes = 0;
+ m_dwStates = 0;
+ m_pParent = NULL;
+ m_pOwner = NULL;
+ }
+ CFX_WideString m_wsWindowclass;
+ CFX_Matrix m_ctmOnParent;
+ CFX_RectF m_rtWidget;
+ FX_DWORD m_dwStyles;
+ FX_DWORD m_dwStyleExes;
+ FX_DWORD m_dwStates;
+ CFWL_Widget *m_pParent;
+ CFWL_Widget *m_pOwner;
+};
+class CFWL_Widget : public CFX_Object
+{
+public:
+ IFWL_Widget* GetWidget();
+ FX_DWORD Release();
+ CFWL_Widget* Retain();
+ FX_DWORD GetRefCount() const;
+ FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ FX_DWORD GetClassID() const;
+ virtual FX_BOOL IsInstance(FX_WSTR wsClass) const;
+protected:
+ FWL_ERR Initialize(const CFWL_WidgetProperties *pProperties = NULL);
+public:
+ FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ FWL_ERR GetGlobalRect(CFX_RectF &rect);
+ FWL_ERR SetWidgetRect(const CFX_RectF &rect);
+ FWL_ERR GetClientRect(CFX_RectF &rtClient);
+ CFWL_Widget* GetParent();
+ FWL_ERR SetParent(CFWL_Widget *pParent);
+ CFWL_Widget* GetOwner();
+ FWL_ERR SetOwner(CFWL_Widget *pOwner);
+ FX_DWORD GetStyles();
+ FWL_ERR ModifyStyles(FX_DWORD dwStylesAdded, FX_DWORD dwStylesRemoved);
+ FX_DWORD GetStylesEx();
+ FWL_ERR ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+ FX_DWORD GetStates();
+ FWL_ERR SetStates(FX_DWORD dwStates, FX_BOOL bSet = TRUE);
+ FWL_ERR SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback);
+ FX_LPVOID GetPrivateData(FX_LPVOID module_id);
+ FWL_ERR Update();
+ FWL_ERR LockUpdate();
+ FWL_ERR UnlockUpdate();
+ FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ FWL_ERR TransformTo(CFWL_Widget *pWidget, FX_FLOAT &fx, FX_FLOAT &fy);
+ FWL_ERR TransformTo(CFWL_Widget *pWidget, CFX_RectF &rt);
+ FWL_ERR GetMatrix(CFX_Matrix &matrix, FX_BOOL bGlobal = FALSE);
+ FWL_ERR SetMatrix(const CFX_Matrix &matrix);
+ FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ FWL_ERR GetProperties(CFWL_WidgetProperties &properties);
+ FWL_ERR SetProperties(const CFWL_WidgetProperties &properties);
+ IFWL_WidgetDelegate* SetDelegate(IFWL_WidgetDelegate* pDelegate);
+ FWL_ERR Repaint(const CFX_RectF *pRect = NULL);
+ FWL_ERR SetFocus(FX_BOOL bFocus);
+ FWL_ERR SetGrab(FX_BOOL bSet);
+ CFWL_Widget();
+ virtual ~CFWL_Widget();
+ void RegisterEventTarget(CFWL_Widget *pEventSource = NULL, FX_DWORD dwFilter = FWL_EVENT_ALL_MASK);
+ void DispatchEvent(CFWL_Event *pEvent);
+ CFX_SizeF CalcTextSize(const CFX_WideString &wsText, FX_BOOL bMultiLine = FALSE, FX_INT32 iLineWidth = -1);
+ IFWL_Widget *m_pImp;
+ IFWL_WidgetDelegate *m_pDelegate;
+ CFWL_WidgetMgr *m_pWidgetMgr;
+ CFWL_WidgetProperties *m_pProperties;
+};
+class CFWL_WidgetDelegate : public CFX_Object, public IFWL_WidgetDelegate
+{
+public:
+ CFWL_WidgetDelegate();
+ virtual ~CFWL_WidgetDelegate();
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+};
+#endif
diff --git a/xfa/include/fwl/theme/barcodetp.h b/xfa/include/fwl/theme/barcodetp.h
new file mode 100644
index 0000000000..803e06bd04
--- /dev/null
+++ b/xfa/include/fwl/theme/barcodetp.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_BARCODETP_H
+#define _FWL_BARCODETP_H
+class CFWL_WidgetTP;
+class CFWL_BarcodeTP;
+class CFWL_BarcodeTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_BarcodeTP();
+ virtual ~CFWL_BarcodeTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+};
+#endif
diff --git a/xfa/include/fwl/theme/carettp.h b/xfa/include/fwl/theme/carettp.h
new file mode 100644
index 0000000000..57ea85b708
--- /dev/null
+++ b/xfa/include/fwl/theme/carettp.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CARETTP_H
+#define _FWL_CARETTP_H
+class CFWL_WidgetTP;
+class CFWL_CaretTP;
+class CFWL_CaretTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_CaretTP();
+ virtual ~CFWL_CaretTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+protected:
+ void DrawCaretBK(CFX_Graphics *pGraphics, FX_DWORD dwStates, const CFX_RectF *pRect, CFX_Color *crFill, CFX_Matrix *pMatrix = NULL);
+};
+#endif
diff --git a/xfa/include/fwl/theme/checkboxtp.h b/xfa/include/fwl/theme/checkboxtp.h
new file mode 100644
index 0000000000..384effe732
--- /dev/null
+++ b/xfa/include/fwl/theme/checkboxtp.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CHECKBOXTP_H
+#define _FWL_CHECKBOXTP_H
+class CFWL_WidgetTP;
+class CFWL_CheckBoxTP;
+class CFWL_CheckBoxTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_CheckBoxTP();
+ virtual ~CFWL_CheckBoxTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FX_BOOL DrawText(CFWL_ThemeText *pParams);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+protected:
+ void DrawBoxBk(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_DWORD dwStates, CFX_Matrix *pMatrix = NULL);
+ void DrawSign(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRtBox, FX_DWORD dwStates, CFX_Matrix *pMatrix = NULL);
+ void DrawSignNeutral(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, CFX_Matrix *pMatrix = NULL);
+ void DrawSignCheck(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix = NULL);
+ void DrawSignCircle(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix = NULL);
+ void DrawSignCross(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix = NULL);
+ void DrawSignDiamond(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix = NULL);
+ void DrawSignSquare(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix = NULL);
+ void DrawSignStar(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix = NULL);
+ void DrawSignBorder(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRtBox, FX_BOOL bDisable = FALSE, CFX_Matrix *pMatrix = NULL);
+ void SetThemeData(FX_DWORD dwID);
+ void initCheckPath(FX_FLOAT fCheckLen);
+ struct CKBThemeData : public CFX_Object {
+ public:
+ FX_ARGB clrBoxBk[13][2];
+ FX_ARGB clrSignBorderNormal;
+ FX_ARGB clrSignBorderDisable;
+ FX_ARGB clrSignCheck;
+ FX_ARGB clrSignNeutral;
+ FX_ARGB clrSignNeutralNormal;
+ FX_ARGB clrSignNeutralHover;
+ FX_ARGB clrSignNeutralPressed;
+ } *m_pThemeData;
+ CFX_Path *m_pCheckPath;
+};
+#endif
diff --git a/xfa/include/fwl/theme/comboboxtp.h b/xfa/include/fwl/theme/comboboxtp.h
new file mode 100644
index 0000000000..1ed39742e6
--- /dev/null
+++ b/xfa/include/fwl/theme/comboboxtp.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_COMBOBOXTP_H
+#define _FWL_COMBOBOXTP_H
+class CFWL_WidgetTP;
+class CFWL_ComboBoxTP;
+class CFWL_ComboBoxTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_ComboBoxTP();
+ virtual ~CFWL_ComboBoxTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+protected:
+ void DrawDropDownButton(CFWL_ThemeBackground *pParams, FX_DWORD dwStates, CFX_Matrix *pMatrix);
+ void DrawStrethHandler(CFWL_ThemeBackground *pParams, FX_DWORD dwStates, CFX_Matrix *pMatrix);
+};
+#endif
diff --git a/xfa/include/fwl/theme/datetimepickertp.h b/xfa/include/fwl/theme/datetimepickertp.h
new file mode 100644
index 0000000000..01a775a6f1
--- /dev/null
+++ b/xfa/include/fwl/theme/datetimepickertp.h
@@ -0,0 +1,26 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_DATETIMEPICKERTP_H
+#define _FWL_DATETIMEPICKERTP_H
+class CFWL_WidgetTP;
+class CFWL_DateTimePickerTP;
+class CFWL_DateTimePickerTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_DateTimePickerTP();
+ virtual ~CFWL_DateTimePickerTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+protected:
+ void DrawDropDownButton(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ void initThemeData();
+ struct DTPThemeData : public CFX_Object {
+ public:
+ FX_ARGB BoxBkColor[13][2];
+ } *m_pThemeData;
+};
+#endif
diff --git a/xfa/include/fwl/theme/edittp.h b/xfa/include/fwl/theme/edittp.h
new file mode 100644
index 0000000000..307382e343
--- /dev/null
+++ b/xfa/include/fwl/theme/edittp.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_EDITTP_H
+#define _FWL_EDITTP_H
+class CFWL_WidgetTP;
+class CFWL_EditTP;
+class CFWL_EditTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_EditTP();
+ virtual ~CFWL_EditTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+};
+#endif
diff --git a/xfa/include/fwl/theme/formtp.h b/xfa/include/fwl/theme/formtp.h
new file mode 100644
index 0000000000..b7e68e2d5b
--- /dev/null
+++ b/xfa/include/fwl/theme/formtp.h
@@ -0,0 +1,74 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_FORM_THEMEPROVIDER_H
+#define _FWL_FORM_THEMEPROVIDER_H
+class CFWL_WidgetTP;
+class CFWL_FormTP;
+class CFWL_FormTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_FormTP();
+ virtual ~CFWL_FormTP();
+
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_BOOL DrawText(CFWL_ThemeText *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+ virtual FWL_ERR GetPartRect(CFWL_ThemePart *pThemePart, CFX_RectF& rtPart);
+protected:
+
+ void CalCloseBox(IFWL_Widget *pWidget, CFX_RectF &rect);
+ void CalMaxBox(IFWL_Widget *pWidget, CFX_RectF &rect);
+ void CalMinBox(IFWL_Widget *pWidget, CFX_RectF &rect);
+ void CalCaption(IFWL_Widget *pWidget, CFX_RectF &rect);
+ void CalIcon(IFWL_Widget *pWidget, CFX_RectF &rect);
+
+ void DrawFormBorder(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void DrawCaption(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void DrawNarrowCaption(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void DrawCloseBox(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void DrawMinMaxBoxCommon(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void DrawMinimizeBox(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void DrawMaximizeBox(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, FX_BOOL bMax, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void DrawIconImage(CFX_Graphics *pGraphics, CFX_DIBitmap *pDIBitmap, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive = 0);
+ void SetThemeData(FX_DWORD dwID);
+ void TransModeColor(FX_ARGB clrFore, FX_ARGB &clrBack);
+ void DeactiveForm();
+ void InitCaption(FX_BOOL bActive);
+ CFX_DIBitmap *m_pActiveBitmap;
+ CFX_DIBitmap *m_pDeactivebitmap;
+ CFX_RectF m_rtDisCaption;
+ CFX_RectF m_rtDisLBorder;
+ CFX_RectF m_rtDisRBorder;
+ CFX_RectF m_rtDisBBorder;
+ struct SBThemeData : public CFX_Object {
+ public:
+ FX_ARGB clrHeadBK[2][4];
+ FX_ARGB clrHeadEdgeLeft[2][3];
+ FX_ARGB clrHeadEdgeRight[2][3];
+ FX_ARGB clrHeadEdgeTop[2][3];
+ FX_ARGB clrHeadEdgeBottom[2][3];
+ FX_ARGB clrCloseBtBKStart[2][3];
+ FX_ARGB clrCloseBtBKEnd[2][3];
+ FX_ARGB clrCloseBtEdgeLight[2][3];
+ FX_ARGB clrCloseBtEdgeDark[2][3];
+ FX_ARGB clrNormalBtBKStart[2][3];
+ FX_ARGB clrNormalBtBKEnd[2][3];
+ FX_ARGB clrNormalBtEdgeLight[2][3];
+ FX_ARGB clrNormalBtEdgeDark[2][3];
+ FX_ARGB clrBtnEdgeOut[2];
+ FX_ARGB clrBtnCornerLight[2][3];
+ FX_ARGB clrHeadText[2];
+ FX_ARGB clrFormBorder[2][5];
+ FX_ARGB clrFormBorderLight[2];
+ FX_ARGB clrTransWhite;
+ } *m_pThemeData;
+};
+#endif
diff --git a/xfa/include/fwl/theme/listboxtp.h b/xfa/include/fwl/theme/listboxtp.h
new file mode 100644
index 0000000000..aaae2eba38
--- /dev/null
+++ b/xfa/include/fwl/theme/listboxtp.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_LISTBOXTP_H
+#define _FWL_LISTBOXTP_H
+class CFWL_WidgetTP;
+class CFWL_ScrollBarTP;
+class CFWL_ListBoxTP;
+class CFWL_ListBoxTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_ListBoxTP();
+ virtual ~CFWL_ListBoxTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+protected:
+ void DrawListBoxItem(CFX_Graphics *pGraphics, FX_DWORD dwStates, const CFX_RectF *prtItem, FX_LPVOID pData = NULL, CFX_Matrix *pMatrix = NULL);
+};
+#endif
diff --git a/xfa/include/fwl/theme/monthcalendartp.h b/xfa/include/fwl/theme/monthcalendartp.h
new file mode 100644
index 0000000000..55d991d404
--- /dev/null
+++ b/xfa/include/fwl/theme/monthcalendartp.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_MONTHCALENDARTP_H
+#define _FWL_MONTHCALENDARTP_H
+class CFWL_WidgetTP;
+class CFWL_MonthCalendarTP;
+class CFWL_MonthCalendarTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_MonthCalendarTP();
+ virtual ~CFWL_MonthCalendarTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_BOOL DrawText(CFWL_ThemeText *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+protected:
+ FX_BOOL DrawTotalBK(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawHeadBk(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawLButton(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawRButton(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawDatesInBK(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawDatesInCircle(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawTodayCircle(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawHSeperator(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FX_BOOL DrawWeekNumSep(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix);
+ FWLTHEME_STATE GetState(FX_DWORD dwFWLStates);
+ void SetThemeData(FX_DWORD dwThemeID);
+ class MCThemeData : public CFX_Object
+ {
+ public:
+ FX_ARGB clrCaption;
+ FX_ARGB clrSeperator;
+ FX_ARGB clrDatesHoverBK;
+ FX_ARGB clrDatesSelectedBK;
+ FX_ARGB clrDatesCircle;
+ FX_ARGB clrToday;
+ FX_ARGB clrBK;
+ } *m_pThemeData;
+ CFX_WideString wsResource;
+};
+#endif
diff --git a/xfa/include/fwl/theme/pictureboxtp.h b/xfa/include/fwl/theme/pictureboxtp.h
new file mode 100644
index 0000000000..938ac07b1d
--- /dev/null
+++ b/xfa/include/fwl/theme/pictureboxtp.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PICTUREBOXTP_H
+#define _FWL_PICTUREBOXTP_H
+class CFWL_WidgetTP;
+class CFWL_PictureBoxTP;
+class CFWL_PictureBoxTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_PictureBoxTP();
+ virtual ~CFWL_PictureBoxTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+};
+#endif
diff --git a/xfa/include/fwl/theme/pushbuttontp.h b/xfa/include/fwl/theme/pushbuttontp.h
new file mode 100644
index 0000000000..676a5fce50
--- /dev/null
+++ b/xfa/include/fwl/theme/pushbuttontp.h
@@ -0,0 +1,41 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PUSHBUTTONTP_H
+#define _FWL_PUSHBUTTONTP_H
+class CFWL_WidgetTP;
+class CFWL_PushButtonTP;
+class CFWL_PushButtonTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_PushButtonTP();
+ virtual ~CFWL_PushButtonTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+protected:
+ void SetThemeData(FX_DWORD dwID);
+ void SetTopLineColor(FX_DWORD *pData);
+ void SetLeftLineColor(FX_DWORD *pData);
+ void SetRightLineColor(FX_DWORD *pData);
+ void SetBottomLineColor(FX_DWORD *pData);
+ void SetBackgroudColor(FX_DWORD *pData);
+ void SetCaptionColor(FX_DWORD *pData);
+ void SetCornerColor(FX_DWORD *pData);
+ FX_INT32 GetColorID(FX_DWORD dwStates);
+
+ struct PBThemeData : CFX_Object {
+ public:
+ FX_ARGB clrBorder[5];
+ FX_ARGB clrStart[5];
+ FX_ARGB clrEnd[5];
+ FX_ARGB clrFill[5];
+ } *m_pThemeData;
+};
+#endif
diff --git a/xfa/include/fwl/theme/scrollbartp.h b/xfa/include/fwl/theme/scrollbartp.h
new file mode 100644
index 0000000000..b7f1926029
--- /dev/null
+++ b/xfa/include/fwl/theme/scrollbartp.h
@@ -0,0 +1,36 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_SCROLLBARTP_H
+#define _FWL_SCROLLBARTP_H
+class CFWL_WidgetTP;
+class CFWL_ScrollBarTP;
+class CFWL_ScrollBarTP : public CFWL_WidgetTP
+{
+public:
+ CFWL_ScrollBarTP();
+ virtual ~CFWL_ScrollBarTP();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+protected:
+ void DrawThumbBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, FX_BOOL bPawButton = TRUE, CFX_Matrix *pMatrix = NULL);
+ void DrawTrack(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, FX_BOOL bLowerTrack, CFX_Matrix *pMatrix = NULL);
+ void DrawMaxMinBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FWLTHEME_STATE eState, CFX_Matrix *pMatrix = NULL);
+ void DrawPaw(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, CFX_Matrix *pMatrix = NULL);
+ void SetThemeData(FX_DWORD dwID);
+ struct SBThemeData : public CFX_Object {
+ public:
+ FX_ARGB clrPawColorLight[4];
+ FX_ARGB clrPawColorDark[4];
+ FX_ARGB clrBtnBK[4][2];
+ FX_ARGB clrBtnBorder[4];
+ FX_ARGB clrTrackBKStart;
+ FX_ARGB clrTrackBKEnd;
+ } *m_pThemeData;
+};
+#endif
diff --git a/xfa/include/fwl/theme/utils.h b/xfa/include/fwl/theme/utils.h
new file mode 100644
index 0000000000..f1b6b55876
--- /dev/null
+++ b/xfa/include/fwl/theme/utils.h
@@ -0,0 +1,87 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_THEME_UTILS_H
+#define _FWL_THEME_UTILS_H
+#define THEME_XPSimilar
+enum FWLTHEME_EDGE {
+ FWLTHEME_EDGE_Flat = 0,
+ FWLTHEME_EDGE_Raised,
+ FWLTHEME_EDGE_Sunken
+};
+enum FWLTHEME_STATE {
+ FWLTHEME_STATE_Normal = 1,
+ FWLTHEME_STATE_Hover,
+ FWLTHEME_STATE_Pressed,
+ FWLTHEME_STATE_Disabale
+};
+enum FWLTHEME_DIRECTION {
+ FWLTHEME_DIRECTION_Up = 0,
+ FWLTHEME_DIRECTION_Down,
+ FWLTHEME_DIRECTION_Left,
+ FWLTHEME_DIRECTION_Right
+};
+typedef struct _FWLCOLOR {
+ union {
+ FX_DWORD color;
+ struct {
+ FX_BYTE b;
+ FX_BYTE g;
+ FX_BYTE r;
+ FX_BYTE a;
+ };
+ };
+
+ _FWLCOLOR()
+ {
+ color = 0;
+ }
+ _FWLCOLOR(FX_DWORD c)
+ {
+ color = c;
+ }
+ _FWLCOLOR(const _FWLCOLOR &c)
+ {
+ color = c.color;
+ }
+
+ bool operator == (const _FWLCOLOR &frColor)
+ {
+ return color == frColor.color;
+ }
+
+ operator FX_DWORD()
+ {
+ return color;
+ }
+} FWLCOLOR;
+#define FWLTHEME_BEZIER 0.5522847498308f
+#define FWLTHEME_PI 3.141592f
+#define FWLTHEME_PI_2_1 1.570796f
+#define FWLTHEME_PI_2_3 4.712388f
+#define FWLTHEME_COLOR_EDGELT1 (ArgbEncode(255, 172, 168, 153))
+#define FWLTHEME_COLOR_EDGELT2 (ArgbEncode(255, 113, 111, 100))
+#define FWLTHEME_COLOR_EDGERB1 (ArgbEncode(255, 241, 239, 226))
+#define FWLTHEME_COLOR_EDGERB2 (ArgbEncode(255, 255, 255, 255))
+#define FWLTHEME_COLOR_Background (ArgbEncode(255, 236, 233, 216))
+#define FWLTHEME_COLOR_BKSelected (ArgbEncode(255, 153, 193, 218))
+#define FWLTHEME_COLOR_Green_BKSelected (ArgbEncode(255, 147, 160, 112))
+#ifdef THEME_XPSimilar
+#define FWLTHEME_CAPACITY_EdgeFlat 2.0f
+#else
+#define FWLTHEME_CAPACITY_EdgeFlat 0.0f
+#endif
+#define FWLTHEME_CAPACITY_EdgeRaised 2.0f
+#define FWLTHEME_CAPACITY_EdgeSunken 2.0f
+#define FWLTHEME_CAPACITY_FontSize 12.0f
+#define FWLTHEME_CAPACITY_LineHeight 12.0f
+#define FWLTHEME_CAPACITY_TextColor (ArgbEncode(255, 0, 0, 0))
+#define FWLTHEME_CAPACITY_TextSelColor (ArgbEncode(255, 153, 193, 218))
+#define FWLTHEME_CAPACITY_TextDisColor (ArgbEncode(255, 172, 168, 153))
+#define FWLTHEME_CAPACITY_ScrollBarWidth 17.0f
+#define FWLTHEME_CAPACITY_CXBorder 1.0f
+#define FWLTHEME_CAPACITY_CYBorder 1.0f
+#endif
diff --git a/xfa/include/fwl/theme/widgettp.h b/xfa/include/fwl/theme/widgettp.h
new file mode 100644
index 0000000000..3ede92f5d7
--- /dev/null
+++ b/xfa/include/fwl/theme/widgettp.h
@@ -0,0 +1,126 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_WIDGETTP_H
+#define _FWL_WIDGETTP_H
+class CFX_Object;
+class IFWL_ThemeProvider;
+class IFWL_Widget;
+class IFDE_TextOut;
+class IFX_Font;
+class IFX_FontMgr;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+class IFX_FontSourceEnum;
+#endif
+class CFWL_WidgetTP;
+class CFWL_ArrowData;
+class CFWL_WidgetTP : public CFX_Object
+{
+public:
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD GetThemeID(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FWL_ERR GetThemeMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix);
+ virtual FWL_ERR SetThemeMatrix(IFWL_Widget *pWidget, const CFX_Matrix &matrix);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_BOOL DrawText(CFWL_ThemeText *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+ virtual FX_BOOL IsCustomizedLayout(IFWL_Widget *pWidget);
+ virtual FWL_ERR GetPartRect(CFWL_ThemePart *pThemePart, CFX_RectF &rtPart);
+ virtual FX_BOOL IsInPart(CFWL_ThemePart *pThemePart, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL CalcTextRect(CFWL_ThemeText *pParams, CFX_RectF &rect);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual ~CFWL_WidgetTP();
+ FWL_ERR SetFont(IFWL_Widget *pWidget, FX_LPCWSTR strFont, FX_FLOAT fFontSize, FX_ARGB rgbFont);
+ FWL_ERR SetFont(IFWL_Widget *pWidget, IFX_Font *pFont, FX_FLOAT fFontSize, FX_ARGB rgbFont);
+ IFX_Font* GetFont(IFWL_Widget *pWidget);
+protected:
+ CFWL_WidgetTP();
+ FX_ERR InitTTO();
+ FX_ERR FinalizeTTO();
+ void DrawEdge(CFX_Graphics *pGraphics, FX_DWORD dwStyles, const CFX_RectF *pRect, CFX_Matrix *pMatrix = NULL);
+ void Draw3DRect(CFX_Graphics *pGraphics, FWLTHEME_EDGE eType, FX_FLOAT fWidth, const CFX_RectF *pRect, FX_ARGB cr1, FX_ARGB cr2, FX_ARGB cr3, FX_ARGB cr4, CFX_Matrix *pMatrix = NULL);
+ void Draw3DCircle(CFX_Graphics *pGraphics, FWLTHEME_EDGE eType, FX_FLOAT fWidth, const CFX_RectF *pRect, FX_ARGB cr1, FX_ARGB cr2, FX_ARGB cr3, FX_ARGB cr4, CFX_Matrix *pMatrix = NULL);
+ void DrawBorder(CFX_Graphics *pGraphics, const CFX_RectF *pRect, CFX_Matrix *pMatrix = NULL);
+ void FillBackground(CFX_Graphics *pGraphics, const CFX_RectF *pRect, CFX_Matrix *pMatrix = NULL);
+ void FillSoildRect(CFX_Graphics *pGraphics, FX_ARGB fillColor, const CFX_RectF *pRect, CFX_Matrix *pMatrix = NULL);
+ void DrawAxialShading(CFX_Graphics *pGraphics, FX_FLOAT fx1, FX_FLOAT fy1, FX_FLOAT fx2, FX_FLOAT fy2, FX_ARGB beginColor, FX_ARGB endColor, CFX_Path *path, FX_INT32 fillMode = FXFILL_WINDING, CFX_Matrix *pMatrix = NULL);
+ void DrawAnnulusRect(CFX_Graphics *pGraphics, FX_ARGB fillColor, const CFX_RectF *pRect, FX_FLOAT fRingWidth = 1, CFX_Matrix *pMatrix = NULL);
+ void DrawAnnulusCircle(CFX_Graphics *pGraphics, FX_ARGB fillColor, const CFX_RectF *pRect, FX_FLOAT fWidth = 1, CFX_Matrix *pMatrix = NULL);
+ void DrawFocus(CFX_Graphics *pGraphics, const CFX_RectF *pRect, CFX_Matrix *pMatrix = NULL);
+ void DrawArrow(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FX_ARGB argbFill, FX_BOOL bPressed, CFX_Matrix *pMatrix = NULL);
+ void DrawArrow(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FX_ARGB argSign, CFX_Matrix *pMatrix = NULL);
+ void DrawBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix = NULL);
+ void DrawArrowBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FWLTHEME_STATE eState, CFX_Matrix *pMatrix = NULL);
+ FWLCOLOR BlendColor(FWLCOLOR srcColor, FWLCOLOR renderColor, FX_BYTE scale);
+ FX_DWORD m_dwRefCount;
+ IFDE_TextOut *m_pTextOut;
+ IFX_Font *m_pFDEFont;
+ FX_FLOAT m_fValue;
+ FX_DWORD m_dwValue;
+ CFX_RectF m_rtMargin;
+ FX_DWORD m_dwThemeID;
+ CFX_Matrix _ctm;
+};
+FX_BOOL FWLTHEME_Init();
+void FWLTHEME_Release();
+FX_DWORD FWL_GetThemeLayout(FX_DWORD dwThemeID);
+FX_DWORD FWL_GetThemeColor(FX_DWORD dwThemeID);
+FX_DWORD FWL_MakeThemeID(FX_DWORD dwLayout, FX_DWORD dwColor);
+class CFWL_ArrowData : public CFX_Object
+{
+public:
+ static CFWL_ArrowData* GetInstance();
+ static FX_BOOL IsInstance();
+ static void DestroyInstance();
+ virtual ~CFWL_ArrowData();
+ void SetColorData(FX_DWORD dwID);
+
+ class CColorData : public CFX_Object
+ {
+ public:
+ FX_ARGB clrBorder[4];
+ FX_ARGB clrStart[4];
+ FX_ARGB clrEnd[4];
+ FX_ARGB clrSign[4];
+ } *m_pColorData;
+protected:
+ CFWL_ArrowData();
+ static CFWL_ArrowData *m_pInstance;
+};
+class CFWL_FontData : public CFX_Object
+{
+public:
+ CFWL_FontData();
+ virtual ~CFWL_FontData();
+ FX_BOOL Equal(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage);
+ FX_BOOL LoadFont(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage);
+ IFX_Font* GetFont() const
+ {
+ return m_pFont;
+ }
+protected:
+ CFX_WideString m_wsFamily;
+ FX_DWORD m_dwStyles;
+ FX_DWORD m_dwCodePage;
+ IFX_Font *m_pFont;
+ IFX_FontMgr *m_pFontMgr;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ IFX_FontSourceEnum *m_pFontSource;
+#endif
+};
+class CFWL_FontManager : public CFX_Object
+{
+public:
+ CFWL_FontManager();
+ virtual ~CFWL_FontManager();
+ IFX_Font* FindFont(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD dwCodePage);
+protected:
+ CFX_PtrArray m_arrFonts;
+};
+CFWL_FontManager *FWL_GetFontManager();
+#endif
diff --git a/xfa/include/fxbarcode/BC_BarCode.h b/xfa/include/fxbarcode/BC_BarCode.h
new file mode 100644
index 0000000000..9ace5e0451
--- /dev/null
+++ b/xfa/include/fxbarcode/BC_BarCode.h
@@ -0,0 +1,249 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_CODEBASE_H_
+#define _BC_CODEBASE_H_
+void BC_Library_Init();
+void BC_Library_Destory();
+class CBC_CodeBase;
+class CBC_Writer;
+class CBC_Reader;
+enum BC_TEXT_LOC {
+ BC_TEXT_LOC_NONE = 0,
+ BC_TEXT_LOC_ABOVE,
+ BC_TEXT_LOC_BELOW,
+ BC_TEXT_LOC_ABOVEEMBED,
+ BC_TEXT_LOC_BELOWEMBED
+};
+enum BC_CHAR_ENCODING {
+ CHAR_ENCODING_UTF8 = 0,
+ CHAR_ENCODING_UNICODE
+};
+enum BC_TYPE {
+ BC_UNKNOWN = -1,
+ BC_CODE39 = 0,
+ BC_CODABAR,
+ BC_CODE128,
+ BC_CODE128_B,
+ BC_CODE128_C,
+ BC_EAN8,
+ BC_UPCA,
+ BC_EAN13,
+ BC_QR_CODE,
+ BC_PDF417,
+ BC_DATAMATRIX
+};
+class CBC_CodeBase : public CFX_Object
+{
+public:
+ CBC_CodeBase();
+ virtual ~CBC_CodeBase();
+ virtual BC_TYPE GetType() = 0;
+ virtual FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e) = 0;
+ virtual FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e) = 0;
+ virtual FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e) = 0;
+ virtual CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e) = 0;
+ virtual CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e) = 0;
+
+ virtual FX_BOOL SetCharEncoding(FX_INT32 encoding);
+ virtual FX_BOOL SetModuleHeight(FX_INT32 moduleHeight);
+ virtual FX_BOOL SetModuleWidth(FX_INT32 moduleWidth);
+
+ virtual FX_BOOL SetHeight(FX_INT32 height);
+ virtual FX_BOOL SetWidth(FX_INT32 width);
+ virtual void SetBackgroundColor(FX_ARGB backgroundColor);
+ virtual void SetBarcodeColor(FX_ARGB foregroundColor);
+protected:
+ CBC_Writer * m_pBCWriter;
+ CBC_Reader * m_pBCReader;
+};
+class CBC_OneCode : public CBC_CodeBase
+{
+public:
+ CBC_OneCode();
+ virtual ~CBC_OneCode();
+ virtual BC_TYPE GetType() = 0;
+ virtual FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e) = 0;
+ virtual FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e) = 0;
+ virtual FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e) = 0;
+ virtual CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e) = 0;
+ virtual CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e) = 0;
+ virtual FX_BOOL CheckContentValidity(FX_WSTR contents);
+ virtual CFX_WideString FilterContents(FX_WSTR contents);
+ virtual void SetPrintChecksum(FX_BOOL checksum);
+ virtual void SetDataLength(FX_INT32 length);
+ virtual void SetCalChecksum(FX_BOOL calc);
+ virtual FX_BOOL SetFont(CFX_Font * cFont);
+ virtual void SetFontSize(FX_FLOAT size);
+ virtual void SetFontStyle(FX_INT32 style);
+ virtual void SetFontColor(FX_ARGB color);
+};
+class CBC_Code39 : public CBC_OneCode
+{
+public:
+ CBC_Code39();
+ CBC_Code39(FX_BOOL usingCheckDigit);
+ CBC_Code39(FX_BOOL usingCheckDigit, FX_BOOL extendedMode);
+ virtual ~CBC_Code39();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_CODE39;
+ }
+ FX_BOOL SetTextLocation(BC_TEXT_LOC location);
+ FX_BOOL SetWideNarrowRatio(FX_INT32 ratio);
+private:
+ CFX_WideString m_renderContents;
+};
+class CBC_Codabar : public CBC_OneCode
+{
+public:
+ CBC_Codabar();
+ virtual ~CBC_Codabar();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_CODABAR;
+ }
+ FX_BOOL SetStartChar(FX_CHAR start);
+ FX_BOOL SetEndChar(FX_CHAR end);
+ FX_BOOL SetTextLocation(BC_TEXT_LOC location);
+ FX_BOOL SetWideNarrowRatio(FX_INT32 ratio);
+private:
+ CFX_WideString m_renderContents;
+};
+class CBC_Code128 : public CBC_OneCode
+{
+private:
+ BC_TYPE m_type;
+public:
+ CBC_Code128(BC_TYPE type);
+ virtual ~CBC_Code128();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_CODE128;
+ }
+ FX_BOOL SetTextLocation(BC_TEXT_LOC loction);
+private:
+ CFX_WideString m_renderContents;
+};
+class CBC_EAN8 : public CBC_OneCode
+{
+public:
+ CBC_EAN8();
+ virtual ~CBC_EAN8();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_EAN8;
+ }
+private:
+ CFX_WideString Preprocess(FX_WSTR contents);
+ CFX_WideString m_renderContents;
+};
+class CBC_EAN13 : public CBC_OneCode
+{
+public:
+ CBC_EAN13();
+ virtual ~CBC_EAN13();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_EAN13;
+ }
+private:
+ CFX_WideString Preprocess(FX_WSTR contents);
+ CFX_WideString m_renderContents;
+};
+class CBC_UPCA : public CBC_OneCode
+{
+public:
+ CBC_UPCA();
+ virtual ~CBC_UPCA();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_UPCA;
+ }
+private:
+ CFX_WideString Preprocess(FX_WSTR contents);
+ CFX_WideString m_renderContents;
+};
+class CBC_QRCode : public CBC_CodeBase
+{
+public:
+ CBC_QRCode();
+ virtual ~CBC_QRCode();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_QR_CODE;
+ }
+ FX_BOOL SetVersion(FX_INT32 version);
+ FX_BOOL SetErrorCorrectionLevel (FX_INT32 level);
+};
+class CBC_PDF417I : public CBC_CodeBase
+{
+public:
+ CBC_PDF417I();
+ virtual ~CBC_PDF417I();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_PDF417;
+ }
+ FX_BOOL SetErrorCorrectionLevel (FX_INT32 level);
+ void SetTruncated(FX_BOOL truncated);
+};
+class CBC_DataMatrix : public CBC_CodeBase
+{
+public:
+ CBC_DataMatrix();
+ virtual ~CBC_DataMatrix();
+ FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e);
+ CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e);
+ BC_TYPE GetType()
+ {
+ return BC_DATAMATRIX;
+ }
+};
+#endif
diff --git a/xfa/include/fxfa/fxfa.h b/xfa/include/fxfa/fxfa.h
new file mode 100644
index 0000000000..a3c3a73e68
--- /dev/null
+++ b/xfa/include/fxfa/fxfa.h
@@ -0,0 +1,622 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA
+#define _FXFA
+class IFDE_XMLElement;
+class CXFA_Node;
+class CXFA_NodeList;
+class CXFA_WidgetAcc;
+class IFWL_AdapterTimerMgr;
+class IFX_Font;
+class CFX_Graphics;
+class IXFA_AppProvider;
+class IXFA_App;
+class IXFA_FontMgr;
+class IXFA_DocProvider;
+class IXFA_DocHandler;
+class IXFA_DocView;
+class IXFA_PageViewRender;
+class IXFA_PageView;
+class IXFA_WidgetHandler;
+class IXFA_WidgetIterator;
+class IXFA_MenuHandler;
+class IXFA_ChecksumContext;
+class IXFA_WidgetAccIterator;
+typedef struct _XFA_HDOC {
+ FX_LPVOID pData;
+}* XFA_HDOC;
+typedef struct _XFA_HWIDGET {
+ FX_LPVOID pData;
+}* XFA_HWIDGET;
+#include "fxfa_basic.h"
+#include "fxfa_widget.h"
+#define XFA_MBICON_Error 0
+#define XFA_MBICON_Warning 1
+#define XFA_MBICON_Question 2
+#define XFA_MBICON_Status 3
+#define XFA_MB_OK 0
+#define XFA_MB_OKCancel 1
+#define XFA_MB_YesNo 2
+#define XFA_MB_YesNoCancel 3
+#define XFA_IDOK 1
+#define XFA_IDCancel 2
+#define XFA_IDNo 3
+#define XFA_IDYes 4
+#define XFA_IDS_ValidateFailed 1
+#define XFA_IDS_CalcOverride 2
+#define XFA_IDS_ModifyField 3
+#define XFA_IDS_NotModifyField 4
+#define XFA_IDS_AppName 5
+#define XFA_IDS_ImageFilter 6
+#define XFA_IDS_UNKNOW_CATCHED 7
+#define XFA_IDS_Unable_TO_SET 8
+#define XFA_IDS_VALUE_EXCALMATORY 9
+#define XFA_IDS_INVALID_ENUM_VALUE 10
+#define XFA_IDS_UNSUPPORT_METHOD 11
+#define XFA_IDS_UNSUPPORT_PROP 12
+#define XFA_IDS_INVAlID_PROP_SET 13
+#define XFA_IDS_NOT_DEFAUL_VALUE 14
+#define XFA_IDS_UNABLE_SET_LANGUAGE 15
+#define XFA_IDS_UNABLE_SET_NUMPAGES 16
+#define XFA_IDS_UNABLE_SET_PLATFORM 17
+#define XFA_IDS_UNABLE_SET_VALIDATIONENABLE 18
+#define XFA_IDS_UNABLE_SET_VARIATION 19
+#define XFA_IDS_UNABLE_SET_VERSION 20
+#define XFA_IDS_UNABLE_SET_READY 21
+#define XFA_IDS_NUMBER_OF_OCCUR 22
+#define XFA_IDS_UNABLE_SET_CLASS_NAME 23
+#define XFA_IDS_UNABLE_SET_LENGTH_VALUE 24
+#define XFA_IDS_UNSUPPORT_CHAR 25
+#define XFA_IDS_BAD_SUFFIX 26
+#define XFA_IDS_EXPECTED_IDENT 27
+#define XFA_IDS_EXPECTED_STRING 28
+#define XFA_IDS_INVALIDATE_CHAR 29
+#define XFA_IDS_REDEFINITION 30
+#define XFA_IDS_INVALIDATE_TOKEN 31
+#define XFA_IDS_INVALIDATE_EXPRESSION 32
+#define XFA_IDS_UNDEFINE_IDENTIFIER 33
+#define XFA_IDS_INVALIDATE_LEFTVALUE 34
+#define XFA_IDS_COMPILER_ERROR 35
+#define XFA_IDS_CANNOT_MODIFY_VALUE 36
+#define XFA_IDS_ERROR_PARAMETERS 37
+#define XFA_IDS_EXPECT_ENDIF 38
+#define XFA_IDS_UNEXPECTED_EXPRESSION 39
+#define XFA_IDS_CONDITION_IS_NULL 40
+#define XFA_IDS_ILLEGALBREAK 41
+#define XFA_IDS_ILLEGALCONTINUE 42
+#define XFA_IDS_EXPECTED_OPERATOR 43
+#define XFA_IDS_DIVIDE_ZERO 44
+#define XFA_IDS_CANNOT_COVERT_OBJECT 45
+#define XFA_IDS_NOT_FOUND_CONTAINER 46
+#define XFA_IDS_NOT_FOUND_PROPERTY 47
+#define XFA_IDS_NOT_FOUND_METHOD 48
+#define XFA_IDS_NOT_FOUND_CONST 49
+#define XFA_IDS_NOT_ASSIGN_OBJECT 50
+#define XFA_IDS_IVALIDATE_INSTRUCTION 51
+#define XFA_IDS_EXPECT_NUMBER 52
+#define XFA_IDS_VALIDATE_OUT_ARRAY 53
+#define XFA_IDS_CANNOT_ASSIGN_IDENT 54
+#define XFA_IDS_NOT_FOUNT_FUNCTION 55
+#define XFA_IDS_NOT_ARRAY 56
+#define XFA_IDS_OUT_ARRAY 57
+#define XFA_IDS_NOT_SUPPORT_CALC 58
+#define XFA_IDS_ARGUMENT_NOT_ARRAY 59
+#define XFA_IDS_ARGUMENT_EXPECT_CONTAINER 60
+#define XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT 61
+#define XFA_IDS_FUNCTION_IS_BUILDIN 62
+#define XFA_IDS_ERROR_MSG 63
+#define XFA_IDS_INDEX_OUT_OF_BOUNDS 64
+#define XFA_IDS_INCORRECT_NUMBER_OF_METHOD 65
+#define XFA_IDS_ARGUMENT_MISMATCH 66
+#define XFA_IDS_INVALID_ENUMERATE 67
+#define XFA_IDS_INVALID_APPEND 68
+#define XFA_IDS_SOM_EXPECTED_LIST 69
+#define XFA_IDS_NOT_HAVE_PROPERTY 70
+#define XFA_IDS_INVALID_NODE_TYPE 71
+#define XFA_IDS_VIOLATE_BOUNDARY 72
+#define XFA_IDS_SERVER_DENY 73
+#define XFA_IDS_StringWeekDay_Sun 74
+#define XFA_IDS_StringWeekDay_Mon 75
+#define XFA_IDS_StringWeekDay_Tue 76
+#define XFA_IDS_StringWeekDay_Wed 77
+#define XFA_IDS_StringWeekDay_Thu 78
+#define XFA_IDS_StringWeekDay_Fri 79
+#define XFA_IDS_StringWeekDay_Sat 80
+#define XFA_IDS_StringMonth_Jan 81
+#define XFA_IDS_StringMonth_Feb 82
+#define XFA_IDS_StringMonth_March 83
+#define XFA_IDS_StringMonth_April 84
+#define XFA_IDS_StringMonth_May 85
+#define XFA_IDS_StringMonth_June 86
+#define XFA_IDS_StringMonth_July 87
+#define XFA_IDS_StringMonth_Aug 88
+#define XFA_IDS_StringMonth_Sept 89
+#define XFA_IDS_StringMonth_Oct 90
+#define XFA_IDS_StringMonth_Nov 91
+#define XFA_IDS_StringMonth_Dec 92
+#define XFA_IDS_String_Today 93
+#define XFA_IDS_ValidateLimit 94
+#define XFA_IDS_ValidateNullWarning 95
+#define XFA_IDS_ValidateNullError 96
+#define XFA_IDS_ValidateWarning 97
+#define XFA_IDS_ValidateError 98
+class IXFA_AppProvider
+{
+public:
+
+ virtual void SetAppType(FX_WSTR wsAppType) = 0;
+ virtual void GetAppType(CFX_WideString &wsAppType) = 0;
+
+ virtual void SetFoxitAppType(FX_WSTR wsFoxitAppType)
+ {
+ return;
+ }
+ virtual void GetFoxitAppType(CFX_WideString &wsFoxitAppType)
+ {
+ return;
+ }
+
+ virtual void GetLanguage(CFX_WideString &wsLanguage) = 0;
+
+ virtual void GetPlatform(CFX_WideString &wsPlatform) = 0;
+
+ virtual void GetVariation(CFX_WideString &wsVariation) = 0;
+
+ virtual void GetVersion(CFX_WideString &wsVersion) = 0;
+
+ virtual void GetFoxitVersion(CFX_WideString &wsFoxitVersion)
+ {
+ return;
+ }
+
+ virtual void GetAppName(CFX_WideString& wsName) = 0;
+
+ virtual void GetFoxitAppName(CFX_WideString& wsFoxitName)
+ {
+ return;
+ }
+
+ virtual void Beep(FX_DWORD dwType) = 0;
+
+ virtual FX_INT32 MsgBox(FX_WSTR wsMessage, FX_WSTR wsTitle = FX_WSTRC(L""), FX_DWORD dwIconType = 0, FX_DWORD dwButtonType = 0) = 0;
+ virtual void Response(CFX_WideString &wsAnswer, FX_WSTR wsQuestion, FX_WSTR wsTitle = FX_WSTRC(L""), FX_WSTR wsDefaultAnswer = FX_WSTRC(L""), FX_BOOL bMark = TRUE) = 0;
+ virtual FX_INT32 GetDocumentCountInBatch() = 0;
+ virtual FX_INT32 GetCurDocumentInBatch() = 0;
+ virtual IFX_FileRead* DownloadURL(FX_WSTR wsURL) = 0;
+
+ virtual FX_BOOL PostRequestURL(FX_WSTR wsURL, FX_WSTR wsData, FX_WSTR wsContentType,
+ FX_WSTR wsEncode, FX_WSTR wsHeader, CFX_WideString &wsResponse) = 0;
+
+ virtual FX_BOOL PutRequestURL(FX_WSTR wsURL, FX_WSTR wsData, FX_WSTR wsEncode) = 0;
+ virtual void LoadString(FX_INT32 iStringID, CFX_WideString &wsString) = 0;
+ virtual FX_BOOL ShowFileDialog(FX_WSTR wsTitle, FX_WSTR wsFilter, CFX_WideStringArray &wsPathArr, FX_BOOL bOpen = TRUE) = 0;
+ virtual IFWL_AdapterTimerMgr* GetTimerMgr() = 0;;
+};
+class IXFA_FontMgr
+{
+public:
+ virtual void Release() = 0;
+ virtual IFX_Font* GetFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF) = 0;
+ virtual IFX_Font* GetDefaultFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF) = 0;
+};
+IXFA_FontMgr* XFA_GetDefaultFontMgr();
+class IXFA_App
+{
+public:
+ static IXFA_App* Create(IXFA_AppProvider* pProvider);
+ virtual void Release() = 0;
+ virtual IXFA_DocHandler* GetDocHandler() = 0;
+ virtual XFA_HDOC CreateDoc(IXFA_DocProvider* pProvider, IFX_FileRead* pStream, FX_BOOL bTakeOverFile = TRUE) = 0;
+ virtual XFA_HDOC CreateDoc(IXFA_DocProvider* pProvider, CPDF_Document* pPDFDoc) = 0;
+ virtual IXFA_AppProvider* GetAppProvider() = 0;
+ virtual void SetDefaultFontMgr(IXFA_FontMgr* pFontMgr) = 0;
+ virtual IXFA_MenuHandler* GetMenuHandler() = 0;
+};
+class IXFA_MenuHandler
+{
+public:
+ virtual FX_BOOL CanCopy(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL CanCut(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL CanPaste(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL CanSelectAll(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL CanDelete(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL CanDeSelect(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL Copy(XFA_HWIDGET hWidget, CFX_WideString &wsText) = 0;
+ virtual FX_BOOL Cut(XFA_HWIDGET hWidget, CFX_WideString &wsText) = 0;
+ virtual FX_BOOL Paste(XFA_HWIDGET hWidget, const CFX_WideString &wsText) = 0;
+ virtual FX_BOOL SelectAll(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL Delete(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL DeSelect(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL CanUndo(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL CanRedo(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL Undo(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL Redo(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL GetSuggestWords(XFA_HWIDGET hWidget, CFX_PointF pointf, CFX_ByteStringArray &sSuggest) = 0;
+ virtual FX_BOOL ReplaceSpellCheckWord(XFA_HWIDGET hWidget, CFX_PointF pointf, FX_BSTR bsReplace) = 0;
+};
+#define XFA_INVALIDATE_AllPages 0x00000000
+#define XFA_INVALIDATE_CurrentPage 0x00000001
+#define XFA_PRINTOPT_ShowDialog 0x00000001
+#define XFA_PRINTOPT_CanCancel 0x00000002
+#define XFA_PRINTOPT_ShrinkPage 0x00000004
+#define XFA_PRINTOPT_AsImage 0x00000008
+#define XFA_PRINTOPT_ReverseOrder 0x00000010
+#define XFA_PRINTOPT_PrintAnnot 0x00000020
+#define XFA_PAGEVIEWEVENT_PostAdded 1
+#define XFA_PAGEVIEWEVENT_PostRemoved 3
+#define XFA_WIDGETEVENT_PostAdded 2
+#define XFA_WIDGETEVENT_PreRemoved 3
+#define XFA_WIDGETEVENT_PostContentChanged 6
+#define XFA_WIDGETEVENT_ListItemRemoved 7
+#define XFA_WIDGETEVENT_ListItemAdded 8
+#define XFA_WIDGETEVENT_AccessChanged 9
+class IXFA_DocProvider
+{
+public:
+ virtual void SetChangeMark(XFA_HDOC hDoc) = 0;
+ virtual void InvalidateRect(IXFA_PageView* pPageView, const CFX_RectF& rt, FX_DWORD dwFlags = 0) = 0;
+ virtual void DisplayCaret(XFA_HWIDGET hWidget, FX_BOOL bVisible, const CFX_RectF* pRtAnchor) = 0;
+ virtual FX_BOOL GetPopupPos(XFA_HWIDGET hWidget, FX_FLOAT fMinPopup, FX_FLOAT fMaxPopup,
+ const CFX_RectF &rtAnchor, CFX_RectF &rtPopup) = 0;
+ virtual FX_BOOL PopupMenu(XFA_HWIDGET hWidget, CFX_PointF ptPopup, const CFX_RectF* pRectExclude = NULL) = 0;
+ virtual void PageViewEvent(IXFA_PageView* pPageView, FX_DWORD dwFlags) = 0;
+ virtual void WidgetEvent(XFA_HWIDGET hWidget, CXFA_WidgetAcc* pWidgetData, FX_DWORD dwEvent, FX_LPVOID pParam = NULL, FX_LPVOID pAdditional = NULL) = 0;
+ virtual FX_BOOL RenderCustomWidget(XFA_HWIDGET hWidget, CFX_Graphics* pGS, CFX_Matrix* pMatrix, const CFX_RectF& rtUI)
+ {
+ return FALSE;
+ }
+ virtual FX_INT32 CountPages(XFA_HDOC hDoc) = 0;
+ virtual FX_INT32 GetCurrentPage(XFA_HDOC hDoc) = 0;
+ virtual void SetCurrentPage(XFA_HDOC hDoc, FX_INT32 iCurPage) = 0;
+ virtual FX_BOOL IsCalculationsEnabled(XFA_HDOC hDoc) = 0;
+ virtual void SetCalculationsEnabled(XFA_HDOC hDoc, FX_BOOL bEnabled) = 0;
+ virtual void GetTitle(XFA_HDOC hDoc, CFX_WideString &wsTitle) = 0;
+ virtual void SetTitle(XFA_HDOC hDoc, FX_WSTR wsTitle) = 0;
+ virtual void ExportData(XFA_HDOC hDoc, FX_WSTR wsFilePath, FX_BOOL bXDP = TRUE) = 0;
+ virtual void ImportData(XFA_HDOC hDoc, FX_WSTR wsFilePath) = 0;
+ virtual void GotoURL(XFA_HDOC hDoc, FX_WSTR bsURL, FX_BOOL bAppend = TRUE) = 0;
+ virtual FX_BOOL IsValidationsEnabled(XFA_HDOC hDoc) = 0;
+ virtual void SetValidationsEnabled(XFA_HDOC hDoc, FX_BOOL bEnabled) = 0;
+ virtual void SetFocusWidget(XFA_HDOC hDoc, XFA_HWIDGET hWidget) = 0;
+ virtual void Print(XFA_HDOC hDoc, FX_INT32 nStartPage, FX_INT32 nEndPage, FX_DWORD dwOptions) = 0;
+ virtual FX_INT32 AbsPageCountInBatch(XFA_HDOC hDoc) = 0;
+ virtual FX_INT32 AbsPageInBatch(XFA_HDOC hDoc, XFA_HWIDGET hWidget) = 0;
+ virtual FX_INT32 SheetCountInBatch(XFA_HDOC hDoc) = 0;
+ virtual FX_INT32 SheetInBatch(XFA_HDOC hDoc, XFA_HWIDGET hWidget) = 0;
+ virtual FX_INT32 Verify(XFA_HDOC hDoc, CXFA_Node* pSigNode, FX_BOOL bUsed = TRUE)
+ {
+ return 0;
+ }
+ virtual FX_BOOL Sign(XFA_HDOC hDoc, CXFA_NodeList* pNodeList, FX_WSTR wsExpression, FX_WSTR wsXMLIdent, FX_WSTR wsValue = FX_WSTRC(L"open"), FX_BOOL bUsed = TRUE)
+ {
+ return 0;
+ }
+ virtual CXFA_NodeList* Enumerate(XFA_HDOC hDoc)
+ {
+ return 0;
+ }
+ virtual FX_BOOL Clear(XFA_HDOC hDoc, CXFA_Node* pSigNode, FX_BOOL bCleared = TRUE)
+ {
+ return 0;
+ }
+ virtual void GetURL(XFA_HDOC hDoc, CFX_WideString &wsDocURL) = 0;
+ virtual FX_ARGB GetHighlightColor(XFA_HDOC hDoc) = 0;
+ virtual void AddDoRecord(XFA_HWIDGET hWidget) = 0;
+
+ virtual FX_BOOL SubmitData(XFA_HDOC hDoc, CXFA_Submit submit) = 0;
+ virtual FX_BOOL CheckWord(XFA_HDOC hDoc, FX_BSTR sWord) = 0;
+ virtual FX_BOOL GetSuggestWords(XFA_HDOC hDoc, FX_BSTR sWord, CFX_ByteStringArray& sSuggest) = 0;
+ virtual FX_BOOL GetPDFScriptObject(XFA_HDOC hDoc, FX_BSTR utf8Name, FXJSE_HVALUE hValue) = 0;
+ virtual FX_BOOL GetGlobalProperty(XFA_HDOC hDoc, FX_BSTR szPropName, FXJSE_HVALUE hValue) = 0;
+ virtual FX_BOOL SetGlobalProperty(XFA_HDOC hDoc, FX_BSTR szPropName, FXJSE_HVALUE hValue) = 0;
+ virtual CPDF_Document* OpenPDF(XFA_HDOC hDoc, IFX_FileRead* pFile, FX_BOOL bTakeOverFile) = 0;
+ virtual IFX_FileRead* OpenLinkedFile(XFA_HDOC hDoc, const CFX_WideString& wsLink) = 0;
+};
+#define XFA_DOCVIEW_View 0x00000000
+#define XFA_DOCVIEW_MasterPage 0x00000001
+#define XFA_DOCVIEW_Design 0x00000002
+#define XFA_DOCTYPE_Dynamic 0
+#define XFA_DOCTYPE_Static 1
+#define XFA_DOCTYPE_XDP 2
+#define XFA_PARSESTATUS_StatusErr -3
+#define XFA_PARSESTATUS_StreamErr -2
+#define XFA_PARSESTATUS_SyntaxErr -1
+#define XFA_PARSESTATUS_Ready 0
+#define XFA_PARSESTATUS_Done 100
+class IXFA_DocHandler
+{
+public:
+ virtual void ReleaseDoc(XFA_HDOC hDoc) = 0;
+ virtual IXFA_DocProvider* GetDocProvider(XFA_HDOC hDoc) = 0;
+
+ virtual FX_DWORD GetDocType(XFA_HDOC hDoc) = 0;
+ virtual FX_INT32 StartLoad(XFA_HDOC hDoc) = 0;
+ virtual FX_INT32 DoLoad(XFA_HDOC hDoc, IFX_Pause *pPause = NULL) = 0;
+ virtual void StopLoad(XFA_HDOC hDoc) = 0;
+
+ virtual IXFA_DocView* CreateDocView(XFA_HDOC hDoc, FX_DWORD dwView = 0) = 0;
+
+ virtual FX_INT32 CountPackages(XFA_HDOC hDoc) = 0;
+ virtual void GetPackageName(XFA_HDOC hDoc, FX_INT32 iPackage, CFX_WideStringC &wsPackage) = 0;
+
+ virtual FX_BOOL SavePackage(XFA_HDOC hDoc, FX_WSTR wsPackage, IFX_FileWrite* pFile, IXFA_ChecksumContext *pCSContext = NULL) = 0;
+ virtual FX_BOOL CloseDoc(XFA_HDOC hDoc) = 0;
+
+ virtual FX_BOOL ImportData(XFA_HDOC hDoc, IFX_FileRead* pStream, FX_BOOL bXDP = TRUE) = 0;
+ virtual void SetJSERuntime(XFA_HDOC hDoc, FXJSE_HRUNTIME hRuntime) = 0;
+ virtual FXJSE_HVALUE GetXFAScriptObject(XFA_HDOC hDoc) = 0;
+ virtual XFA_ATTRIBUTEENUM GetRestoreState(XFA_HDOC hDoc) = 0;
+ virtual FX_BOOL RunDocScript(XFA_HDOC hDoc, XFA_SCRIPTTYPE eScriptType, FX_WSTR wsScript, FXJSE_HVALUE hRetValue, FXJSE_HVALUE hThisObject) = 0;
+};
+enum XFA_EVENTTYPE {
+ XFA_EVENT_Click,
+ XFA_EVENT_Change,
+ XFA_EVENT_DocClose,
+ XFA_EVENT_DocReady,
+ XFA_EVENT_Enter,
+ XFA_EVENT_Exit,
+ XFA_EVENT_Full,
+ XFA_EVENT_IndexChange,
+ XFA_EVENT_Initialize,
+ XFA_EVENT_MouseDown,
+ XFA_EVENT_MouseEnter,
+ XFA_EVENT_MouseExit,
+ XFA_EVENT_MouseUp,
+ XFA_EVENT_PostExecute,
+ XFA_EVENT_PostOpen,
+ XFA_EVENT_PostPrint,
+ XFA_EVENT_PostSave,
+ XFA_EVENT_PostSign,
+ XFA_EVENT_PostSubmit,
+ XFA_EVENT_PreExecute,
+ XFA_EVENT_PreOpen,
+ XFA_EVENT_PrePrint,
+ XFA_EVENT_PreSave,
+ XFA_EVENT_PreSign,
+ XFA_EVENT_PreSubmit,
+ XFA_EVENT_Ready,
+ XFA_EVENT_InitCalculate,
+ XFA_EVENT_InitVariables,
+ XFA_EVENT_Calculate,
+ XFA_EVENT_Validate,
+ XFA_EVENT_Unknown,
+};
+#define XFA_VALIDATE_preSubmit 1
+#define XFA_VALIDATE_prePrint 2
+#define XFA_VALIDATE_preExecute 3
+#define XFA_VALIDATE_preSave 4
+class CXFA_EventParam : public CFX_Object
+{
+public:
+ CXFA_EventParam()
+ {
+ m_pTarget = NULL;
+ m_eType = XFA_EVENT_Unknown;
+ m_wsResult.Empty();
+ Reset();
+ }
+ void Reset()
+ {
+ m_wsChange.Empty();
+ m_iCommitKey = 0;
+ m_wsFullText.Empty();
+ m_bKeyDown = FALSE;
+ m_bModifier = FALSE;
+ m_wsNewContentType.Empty();
+ m_wsNewText.Empty();
+ m_wsPrevContentType.Empty();
+ m_wsPrevText.Empty();
+ m_bReenter = FALSE;
+ m_iSelEnd = 0;
+ m_iSelStart = 0;
+ m_bShift = FALSE;
+ m_wsSoapFaultCode.Empty();
+ m_wsSoapFaultString.Empty();
+ m_bIsFormReady = FALSE;
+ m_iValidateActivities = XFA_VALIDATE_preSubmit;
+ }
+ CXFA_WidgetAcc* m_pTarget;
+ XFA_EVENTTYPE m_eType;
+ CFX_WideString m_wsResult;
+ FX_BOOL m_bCancelAction;
+ FX_INT32 m_iCommitKey;
+ FX_BOOL m_bKeyDown;
+ FX_BOOL m_bModifier;
+ FX_BOOL m_bReenter;
+ FX_INT32 m_iSelEnd;
+ FX_INT32 m_iSelStart;
+ FX_BOOL m_bShift;
+ CFX_WideString m_wsChange;
+ CFX_WideString m_wsFullText;
+ CFX_WideString m_wsNewContentType;
+ CFX_WideString m_wsNewText;
+ CFX_WideString m_wsPrevContentType;
+ CFX_WideString m_wsPrevText;
+ CFX_WideString m_wsSoapFaultCode;
+ CFX_WideString m_wsSoapFaultString;
+ FX_BOOL m_bIsFormReady;
+ FX_INT32 m_iValidateActivities;
+};
+#define XFA_EVENTERROR_Sucess 1
+#define XFA_EVENTERROR_Error -1
+#define XFA_EVENTERROR_NotExist 0
+#define XFA_EVENTERROR_Disabled 2
+enum XFA_WIDGETORDER {
+ XFA_WIDGETORDER_PreOrder,
+};
+class IXFA_DocView
+{
+public:
+ virtual XFA_HDOC GetDoc() = 0;
+ virtual FX_INT32 StartLayout(FX_INT32 iStartPage = 0) = 0;
+ virtual FX_INT32 DoLayout(IFX_Pause *pPause = NULL) = 0;
+ virtual void StopLayout() = 0;
+
+ virtual FX_INT32 GetLayoutStatus() = 0;
+ virtual void UpdateDocView() = 0;
+ virtual FX_INT32 CountPageViews() = 0;
+ virtual IXFA_PageView* GetPageView(FX_INT32 nIndex) = 0;
+ virtual XFA_HWIDGET GetWidgetByName(FX_WSTR wsName) = 0;
+ virtual CXFA_WidgetAcc* GetWidgetAccByName(FX_WSTR wsName) = 0;
+ virtual void ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc = NULL) = 0;
+ virtual FX_INT32 ProcessWidgetEvent(CXFA_EventParam* pParam, CXFA_WidgetAcc* pWidgetAcc = NULL) = 0;
+ virtual IXFA_WidgetHandler* GetWidgetHandler() = 0;
+ virtual IXFA_WidgetIterator* CreateWidgetIterator() = 0;
+ virtual IXFA_WidgetAccIterator* CreateWidgetAccIterator(XFA_WIDGETORDER eOrder = XFA_WIDGETORDER_PreOrder) = 0;
+ virtual XFA_HWIDGET GetFocusWidget() = 0;
+ virtual void KillFocus() = 0;
+ virtual FX_BOOL SetFocus(XFA_HWIDGET hWidget) = 0;
+};
+#define XFA_TRAVERSEWAY_Tranvalse 0x0001
+#define XFA_TRAVERSEWAY_Form 0x0002
+#define XFA_WIDGETFILTER_Visible 0x0001
+#define XFA_WIDGETFILTER_Viewable 0x0010
+#define XFA_WIDGETFILTER_Printable 0x0020
+#define XFA_WIDGETFILTER_Field 0x0100
+#define XFA_WIDGETFILTER_AllType 0x0F00
+class IXFA_PageView
+{
+public:
+ virtual IXFA_DocView* GetDocView() = 0;
+ virtual FX_INT32 GetPageViewIndex() = 0;
+ virtual void GetPageViewRect(CFX_RectF &rtPage) = 0;
+
+ virtual void GetDisplayMatrix(CFX_Matrix &mt, const CFX_Rect &rtDisp, FX_INT32 iRotate) = 0;
+
+ virtual FX_INT32 LoadPageView(IFX_Pause *pPause = NULL) = 0;
+ virtual void UnloadPageView() = 0;
+ virtual XFA_HWIDGET GetWidgetByPos(FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual IXFA_WidgetIterator* CreateWidgetIterator(FX_DWORD dwTraverseWay = XFA_TRAVERSEWAY_Form, FX_DWORD dwWidgetFilter = XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_Viewable | XFA_WIDGETFILTER_AllType) = 0;
+};
+class CXFA_RenderOptions : public CFX_Object
+{
+public:
+ CXFA_RenderOptions()
+ : m_bPrint(FALSE)
+ , m_bHighlight(TRUE)
+ {
+ }
+ FX_BOOL m_bPrint;
+ FX_BOOL m_bHighlight;
+};
+#define XFA_RENDERSTATUS_Ready 1
+#define XFA_RENDERSTATUS_ToBeContinued 2
+#define XFA_RENDERSTATUS_Done 3
+#define XFA_RENDERSTATUS_Failed -1
+class IXFA_RenderContext
+{
+public:
+ virtual void Release() = 0;
+ virtual FX_INT32 StartRender(IXFA_PageView* pPageView, CFX_Graphics* pGS, const CFX_Matrix& pMatrix, const CXFA_RenderOptions& options) = 0;
+ virtual FX_INT32 DoRender(IFX_Pause* pPause = NULL) = 0;
+ virtual void StopRender() = 0;
+};
+IXFA_RenderContext* XFA_RenderContext_Create();
+enum XFA_WIDGETTYPE {
+ XFA_WIDGETTYPE_Barcode,
+ XFA_WIDGETTYPE_PushButton,
+ XFA_WIDGETTYPE_CheckButton,
+ XFA_WIDGETTYPE_RadioButton,
+ XFA_WIDGETTYPE_DatetimeEdit,
+ XFA_WIDGETTYPE_DecimalField,
+ XFA_WIDGETTYPE_NumericField,
+ XFA_WIDGETTYPE_Signature,
+ XFA_WIDGETTYPE_TextEdit,
+ XFA_WIDGETTYPE_DropdownList,
+ XFA_WIDGETTYPE_ListBox,
+ XFA_WIDGETTYPE_ImageField,
+ XFA_WIDGETTYPE_PasswordEdit,
+ XFA_WIDGETTYPE_Arc,
+ XFA_WIDGETTYPE_Rectangle,
+ XFA_WIDGETTYPE_Image,
+ XFA_WIDGETTYPE_Line,
+ XFA_WIDGETTYPE_Text,
+ XFA_WIDGETTYPE_ExcludeGroup,
+ XFA_WIDGETTYPE_Subform,
+ XFA_WIDGETTYPE_Unknown,
+};
+#define XFA_WIDGETSTATUS_Visible 0x00000001
+#define XFA_WIDGETSTATUS_Invisible 0x00000002
+#define XFA_WIDGETSTATUS_Hidden 0x00000004
+#define XFA_WIDGETSTATUS_Viewable 0x00000010
+#define XFA_WIDGETSTATUS_Printable 0x00000020
+#define XFA_WIDGETSTATUS_Focused 0x00000100
+class IXFA_WidgetHandler
+{
+public:
+
+ virtual XFA_HWIDGET CreateWidget(XFA_HWIDGET hParent, XFA_WIDGETTYPE eType, XFA_HWIDGET hBefore = NULL) = 0;
+ virtual IXFA_PageView* GetPageView(XFA_HWIDGET hWidget) = 0;
+ virtual void GetRect(XFA_HWIDGET hWidget, CFX_RectF &rt) = 0;
+ virtual FX_DWORD GetStatus(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL GetBBox(XFA_HWIDGET hWidget, CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus = FALSE) = 0;
+ virtual CXFA_WidgetAcc* GetDataAcc(XFA_HWIDGET hWidget) = 0;
+
+ virtual void GetName(XFA_HWIDGET hWidget, CFX_WideString &wsName, FX_INT32 iNameType = 0) = 0;
+ virtual FX_BOOL GetToolTip(XFA_HWIDGET hWidget, CFX_WideString &wsToolTip) = 0;
+ virtual void SetPrivateData(XFA_HWIDGET hWidget, FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback) = 0;
+ virtual FX_LPVOID GetPrivateData(XFA_HWIDGET hWidget, FX_LPVOID module_id) = 0;
+ virtual FX_BOOL OnMouseEnter(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL OnMouseExit(XFA_HWIDGET hWidget) = 0;
+ virtual FX_BOOL OnLButtonDown(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnLButtonUp(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnLButtonDblClk(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnMouseMove(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnMouseWheel(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnRButtonDown(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnRButtonUp(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnRButtonDblClk(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) = 0;
+
+ virtual FX_BOOL OnKeyDown(XFA_HWIDGET hWidget, FX_DWORD dwKeyCode, FX_DWORD dwFlags) = 0;
+ virtual FX_BOOL OnKeyUp(XFA_HWIDGET hWidget, FX_DWORD dwKeyCode, FX_DWORD dwFlags) = 0;
+ virtual FX_BOOL OnChar(XFA_HWIDGET hWidget, FX_DWORD dwChar, FX_DWORD dwFlags) = 0;
+ virtual FX_DWORD OnHitTest(XFA_HWIDGET hWidget, FX_FLOAT fx, FX_FLOAT fy) = 0;
+ virtual FX_BOOL OnSetCursor(XFA_HWIDGET hWidget, FX_FLOAT fx, FX_FLOAT fy) = 0;
+
+ virtual void RenderWidget(XFA_HWIDGET hWidget, CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_BOOL bHighlight = FALSE) = 0;
+ virtual FX_BOOL HasEvent(CXFA_WidgetAcc* pWidgetAcc, XFA_EVENTTYPE eEventType) = 0;
+ virtual FX_INT32 ProcessEvent(CXFA_WidgetAcc* pWidgetAcc, CXFA_EventParam* pParam) = 0;
+};
+class IXFA_WidgetIterator
+{
+public:
+ virtual void Release() = 0;
+ virtual void Reset() = 0;
+ virtual XFA_HWIDGET MoveToFirst() = 0;
+ virtual XFA_HWIDGET MoveToLast() = 0;
+ virtual XFA_HWIDGET MoveToNext() = 0;
+ virtual XFA_HWIDGET MoveToPrevious() = 0;
+ virtual XFA_HWIDGET GetCurrentWidget() = 0;
+ virtual FX_BOOL SetCurrentWidget(XFA_HWIDGET hWidget) = 0;
+};
+class IXFA_WidgetAccIterator
+{
+public:
+ virtual void Release() = 0;
+
+ virtual void Reset() = 0;
+ virtual CXFA_WidgetAcc* MoveToFirst() = 0;
+ virtual CXFA_WidgetAcc* MoveToLast() = 0;
+ virtual CXFA_WidgetAcc* MoveToNext() = 0;
+ virtual CXFA_WidgetAcc* MoveToPrevious() = 0;
+ virtual CXFA_WidgetAcc* GetCurrentWidgetAcc() = 0;
+ virtual FX_BOOL SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget) = 0;
+ virtual void SkipTree() = 0;
+};
+IXFA_WidgetAccIterator* XFA_WidgetAccIterator_Create(CXFA_WidgetAcc* pTravelRoot, XFA_WIDGETORDER eOrder = XFA_WIDGETORDER_PreOrder);
+class IXFA_ChecksumContext
+{
+public:
+ virtual void Release() = 0;
+
+ virtual FX_BOOL StartChecksum() = 0;
+ virtual FX_BOOL UpdateChecksum(IFX_FileRead* pSrcFile, FX_FILESIZE offset = 0, size_t size = 0) = 0;
+ virtual void FinishChecksum() = 0;
+ virtual void GetChecksum(CFX_ByteString &bsChecksum) = 0;
+};
+IXFA_ChecksumContext* XFA_Checksum_Create();
+#endif
diff --git a/xfa/include/fxfa/fxfa_basic.h b/xfa/include/fxfa/fxfa_basic.h
new file mode 100644
index 0000000000..6e45060b19
--- /dev/null
+++ b/xfa/include/fxfa/fxfa_basic.h
@@ -0,0 +1,1073 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_BASIC_H
+#define _FXFA_BASIC_H
+class CXFA_Measurement;
+#define XFA_HASHCODE_Xfa 0xc56b9ff
+#define XFA_HASHCODE_Config 0x4e1e39b6
+#define XFA_HASHCODE_Template 0x803550fc
+#define XFA_HASHCODE_Datasets 0x99b95079
+#define XFA_HASHCODE_Data 0xbde9abda
+#define XFA_HASHCODE_Form 0xcd309ff4
+#define XFA_HASHCODE_LocaleSet 0x5473b6dc
+#define XFA_HASHCODE_ConnectionSet 0xe14c801c
+#define XFA_HASHCODE_SourceSet 0x811929d
+#define XFA_HASHCODE_Xdc 0xc56afbf
+#define XFA_HASHCODE_Pdf 0xb843dba
+#define XFA_HASHCODE_Xfdf 0x48d004a8
+#define XFA_HASHCODE_Xmpmeta 0x132a8fbc
+#define XFA_HASHCODE_Signature 0x8b036f32
+#define XFA_HASHCODE_Stylesheet 0x6038580a
+#define XFA_HASHCODE_XDP 0xc56afcc
+#define XFA_HASHCODE_Record 0x5779d65f
+#define XFA_HASHCODE_DataWindow 0x83a550d2
+#define XFA_HASHCODE_Host 0xdb075bde
+#define XFA_HASHCODE_Log 0x0b1b3d22
+#define XFA_HASHCODE_Event 0x185e41e2
+#define XFA_HASHCODE_Layout 0x7e7e845e
+#define XFA_HASHCODE_Occur 0xf7eebe1c
+#define XFA_HASHCODE_This 0x2d574d58
+#define XFA_HASHCODE_DataDescription 0x2b5df51e
+#define XFA_HASHCODE_Name 0x31b19c1
+enum XFA_PACKET {
+ XFA_PACKET_USER,
+ XFA_PACKET_SourceSet,
+ XFA_PACKET_Pdf,
+ XFA_PACKET_Xdc,
+ XFA_PACKET_XDP,
+ XFA_PACKET_Xmpmeta,
+ XFA_PACKET_Xfdf,
+ XFA_PACKET_Config,
+ XFA_PACKET_LocaleSet,
+ XFA_PACKET_Stylesheet,
+ XFA_PACKET_Template,
+ XFA_PACKET_Signature,
+ XFA_PACKET_Datasets,
+ XFA_PACKET_Form,
+ XFA_PACKET_ConnectionSet,
+};
+enum XFA_XDPPACKET {
+ XFA_XDPPACKET_UNKNOWN = 0,
+ XFA_XDPPACKET_Config = 1 << XFA_PACKET_Config ,
+ XFA_XDPPACKET_Template = 1 << XFA_PACKET_Template ,
+ XFA_XDPPACKET_Datasets = 1 << XFA_PACKET_Datasets ,
+ XFA_XDPPACKET_Form = 1 << XFA_PACKET_Form ,
+ XFA_XDPPACKET_LocaleSet = 1 << XFA_PACKET_LocaleSet ,
+ XFA_XDPPACKET_ConnectionSet = 1 << XFA_PACKET_ConnectionSet ,
+ XFA_XDPPACKET_SourceSet = 1 << XFA_PACKET_SourceSet ,
+ XFA_XDPPACKET_Xdc = 1 << XFA_PACKET_Xdc ,
+ XFA_XDPPACKET_Pdf = 1 << XFA_PACKET_Pdf ,
+ XFA_XDPPACKET_Xfdf = 1 << XFA_PACKET_Xfdf ,
+ XFA_XDPPACKET_Xmpmeta = 1 << XFA_PACKET_Xmpmeta ,
+ XFA_XDPPACKET_Signature = 1 << XFA_PACKET_Signature ,
+ XFA_XDPPACKET_Stylesheet = 1 << XFA_PACKET_Stylesheet ,
+ XFA_XDPPACKET_USER = 1 << XFA_PACKET_USER ,
+ XFA_XDPPACKET_XDP = 1 << XFA_PACKET_XDP ,
+};
+enum XFA_XDPPACKET_FLAGS {
+ XFA_XDPPACKET_FLAGS_COMPLETEMATCH = 1,
+ XFA_XDPPACKET_FLAGS_PREFIXMATCH = 2,
+ XFA_XDPPACKET_FLAGS_NOMATCH = 4,
+ XFA_XDPPACKET_FLAGS_SUPPORTONE = 8,
+ XFA_XDPPACKET_FLAGS_SUPPORTMANY = 16,
+};
+typedef struct _XFA_PACKETINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ XFA_XDPPACKET eName;
+ FX_LPCWSTR pURI;
+ FX_DWORD eFlags;
+} XFA_PACKETINFO, * XFA_LPPACKETINFO;
+typedef XFA_PACKETINFO const * XFA_LPCPACKETINFO;
+XFA_LPCPACKETINFO XFA_GetPacketByName(FX_WSTR wsName);
+XFA_LPCPACKETINFO XFA_GetPacketByID(FX_DWORD dwPacket);
+extern const XFA_PACKETINFO g_XFAPacketData[];
+inline XFA_LPCPACKETINFO XFA_GetPacketByIndex(XFA_PACKET ePacket)
+{
+ return g_XFAPacketData + ePacket;
+}
+enum XFA_ATTRIBUTEENUM {
+ XFA_ATTRIBUTEENUM_Asterisk,
+ XFA_ATTRIBUTEENUM_Slash,
+ XFA_ATTRIBUTEENUM_Backslash,
+ XFA_ATTRIBUTEENUM_On,
+ XFA_ATTRIBUTEENUM_Tb,
+ XFA_ATTRIBUTEENUM_Up,
+ XFA_ATTRIBUTEENUM_MetaData,
+ XFA_ATTRIBUTEENUM_Delegate,
+ XFA_ATTRIBUTEENUM_PostSubmit,
+ XFA_ATTRIBUTEENUM_Name,
+ XFA_ATTRIBUTEENUM_Cross,
+ XFA_ATTRIBUTEENUM_Next,
+ XFA_ATTRIBUTEENUM_None,
+ XFA_ATTRIBUTEENUM_ShortEdge,
+ XFA_ATTRIBUTEENUM_1mod10_1mod11,
+ XFA_ATTRIBUTEENUM_Height,
+ XFA_ATTRIBUTEENUM_CrossDiagonal,
+ XFA_ATTRIBUTEENUM_All,
+ XFA_ATTRIBUTEENUM_Any,
+ XFA_ATTRIBUTEENUM_ToRight,
+ XFA_ATTRIBUTEENUM_MatchTemplate,
+ XFA_ATTRIBUTEENUM_Dpl,
+ XFA_ATTRIBUTEENUM_Invisible,
+ XFA_ATTRIBUTEENUM_Fit,
+ XFA_ATTRIBUTEENUM_Width,
+ XFA_ATTRIBUTEENUM_PreSubmit,
+ XFA_ATTRIBUTEENUM_Ipl,
+ XFA_ATTRIBUTEENUM_FlateCompress,
+ XFA_ATTRIBUTEENUM_Med,
+ XFA_ATTRIBUTEENUM_Odd,
+ XFA_ATTRIBUTEENUM_Off,
+ XFA_ATTRIBUTEENUM_Pdf,
+ XFA_ATTRIBUTEENUM_Row,
+ XFA_ATTRIBUTEENUM_Top,
+ XFA_ATTRIBUTEENUM_Xdp,
+ XFA_ATTRIBUTEENUM_Xfd,
+ XFA_ATTRIBUTEENUM_Xml,
+ XFA_ATTRIBUTEENUM_Zip,
+ XFA_ATTRIBUTEENUM_Zpl,
+ XFA_ATTRIBUTEENUM_Visible,
+ XFA_ATTRIBUTEENUM_Exclude,
+ XFA_ATTRIBUTEENUM_MouseEnter,
+ XFA_ATTRIBUTEENUM_Pair,
+ XFA_ATTRIBUTEENUM_Filter,
+ XFA_ATTRIBUTEENUM_MoveLast,
+ XFA_ATTRIBUTEENUM_ExportAndImport,
+ XFA_ATTRIBUTEENUM_Push,
+ XFA_ATTRIBUTEENUM_Portrait,
+ XFA_ATTRIBUTEENUM_Default,
+ XFA_ATTRIBUTEENUM_StoredProc,
+ XFA_ATTRIBUTEENUM_StayBOF,
+ XFA_ATTRIBUTEENUM_StayEOF,
+ XFA_ATTRIBUTEENUM_PostPrint,
+ XFA_ATTRIBUTEENUM_UsCarrier,
+ XFA_ATTRIBUTEENUM_Right,
+ XFA_ATTRIBUTEENUM_PreOpen,
+ XFA_ATTRIBUTEENUM_Actual,
+ XFA_ATTRIBUTEENUM_Rest,
+ XFA_ATTRIBUTEENUM_TopCenter,
+ XFA_ATTRIBUTEENUM_StandardSymbol,
+ XFA_ATTRIBUTEENUM_Initialize,
+ XFA_ATTRIBUTEENUM_JustifyAll,
+ XFA_ATTRIBUTEENUM_Normal,
+ XFA_ATTRIBUTEENUM_Landscape,
+ XFA_ATTRIBUTEENUM_NonInteractive,
+ XFA_ATTRIBUTEENUM_MouseExit,
+ XFA_ATTRIBUTEENUM_Minus,
+ XFA_ATTRIBUTEENUM_DiagonalLeft,
+ XFA_ATTRIBUTEENUM_SimplexPaginated,
+ XFA_ATTRIBUTEENUM_Document,
+ XFA_ATTRIBUTEENUM_Warning,
+ XFA_ATTRIBUTEENUM_Auto,
+ XFA_ATTRIBUTEENUM_Below,
+ XFA_ATTRIBUTEENUM_BottomLeft,
+ XFA_ATTRIBUTEENUM_BottomCenter,
+ XFA_ATTRIBUTEENUM_Tcpl,
+ XFA_ATTRIBUTEENUM_Text,
+ XFA_ATTRIBUTEENUM_Grouping,
+ XFA_ATTRIBUTEENUM_SecureSymbol,
+ XFA_ATTRIBUTEENUM_PreExecute,
+ XFA_ATTRIBUTEENUM_DocClose,
+ XFA_ATTRIBUTEENUM_Keyset,
+ XFA_ATTRIBUTEENUM_Vertical,
+ XFA_ATTRIBUTEENUM_PreSave,
+ XFA_ATTRIBUTEENUM_PreSign,
+ XFA_ATTRIBUTEENUM_Bottom,
+ XFA_ATTRIBUTEENUM_ToTop,
+ XFA_ATTRIBUTEENUM_Verify,
+ XFA_ATTRIBUTEENUM_First,
+ XFA_ATTRIBUTEENUM_ContentArea,
+ XFA_ATTRIBUTEENUM_Solid,
+ XFA_ATTRIBUTEENUM_Pessimistic,
+ XFA_ATTRIBUTEENUM_DuplexPaginated,
+ XFA_ATTRIBUTEENUM_Round,
+ XFA_ATTRIBUTEENUM_Remerge,
+ XFA_ATTRIBUTEENUM_Ordered,
+ XFA_ATTRIBUTEENUM_Percent,
+ XFA_ATTRIBUTEENUM_Even,
+ XFA_ATTRIBUTEENUM_Exit,
+ XFA_ATTRIBUTEENUM_ToolTip,
+ XFA_ATTRIBUTEENUM_OrderedOccurrence,
+ XFA_ATTRIBUTEENUM_ReadOnly,
+ XFA_ATTRIBUTEENUM_Currency,
+ XFA_ATTRIBUTEENUM_Concat,
+ XFA_ATTRIBUTEENUM_Thai,
+ XFA_ATTRIBUTEENUM_Embossed,
+ XFA_ATTRIBUTEENUM_Formdata,
+ XFA_ATTRIBUTEENUM_Greek,
+ XFA_ATTRIBUTEENUM_Decimal,
+ XFA_ATTRIBUTEENUM_Select,
+ XFA_ATTRIBUTEENUM_LongEdge,
+ XFA_ATTRIBUTEENUM_Protected,
+ XFA_ATTRIBUTEENUM_BottomRight,
+ XFA_ATTRIBUTEENUM_Zero,
+ XFA_ATTRIBUTEENUM_ForwardOnly,
+ XFA_ATTRIBUTEENUM_DocReady,
+ XFA_ATTRIBUTEENUM_Hidden,
+ XFA_ATTRIBUTEENUM_Include,
+ XFA_ATTRIBUTEENUM_Dashed,
+ XFA_ATTRIBUTEENUM_MultiSelect,
+ XFA_ATTRIBUTEENUM_Inactive,
+ XFA_ATTRIBUTEENUM_Embed,
+ XFA_ATTRIBUTEENUM_Static,
+ XFA_ATTRIBUTEENUM_OnEntry,
+ XFA_ATTRIBUTEENUM_Cyrillic,
+ XFA_ATTRIBUTEENUM_NonBlank,
+ XFA_ATTRIBUTEENUM_TopRight,
+ XFA_ATTRIBUTEENUM_Hebrew,
+ XFA_ATTRIBUTEENUM_TopLeft,
+ XFA_ATTRIBUTEENUM_Center,
+ XFA_ATTRIBUTEENUM_MoveFirst,
+ XFA_ATTRIBUTEENUM_Diamond,
+ XFA_ATTRIBUTEENUM_PageOdd,
+ XFA_ATTRIBUTEENUM_1mod10,
+ XFA_ATTRIBUTEENUM_Korean,
+ XFA_ATTRIBUTEENUM_AboveEmbedded,
+ XFA_ATTRIBUTEENUM_ZipCompress,
+ XFA_ATTRIBUTEENUM_Numeric,
+ XFA_ATTRIBUTEENUM_Circle,
+ XFA_ATTRIBUTEENUM_ToBottom,
+ XFA_ATTRIBUTEENUM_Inverted,
+ XFA_ATTRIBUTEENUM_Update,
+ XFA_ATTRIBUTEENUM_Isoname,
+ XFA_ATTRIBUTEENUM_Server,
+ XFA_ATTRIBUTEENUM_Position,
+ XFA_ATTRIBUTEENUM_MiddleCenter,
+ XFA_ATTRIBUTEENUM_Optional,
+ XFA_ATTRIBUTEENUM_UsePrinterSetting,
+ XFA_ATTRIBUTEENUM_Outline,
+ XFA_ATTRIBUTEENUM_IndexChange,
+ XFA_ATTRIBUTEENUM_Change,
+ XFA_ATTRIBUTEENUM_PageArea,
+ XFA_ATTRIBUTEENUM_Once,
+ XFA_ATTRIBUTEENUM_Only,
+ XFA_ATTRIBUTEENUM_Open,
+ XFA_ATTRIBUTEENUM_Caption,
+ XFA_ATTRIBUTEENUM_Raised,
+ XFA_ATTRIBUTEENUM_Justify,
+ XFA_ATTRIBUTEENUM_RefAndDescendants,
+ XFA_ATTRIBUTEENUM_Short,
+ XFA_ATTRIBUTEENUM_PageFront,
+ XFA_ATTRIBUTEENUM_Monospace,
+ XFA_ATTRIBUTEENUM_Middle,
+ XFA_ATTRIBUTEENUM_PrePrint,
+ XFA_ATTRIBUTEENUM_Always,
+ XFA_ATTRIBUTEENUM_Unknown,
+ XFA_ATTRIBUTEENUM_ToLeft,
+ XFA_ATTRIBUTEENUM_Above,
+ XFA_ATTRIBUTEENUM_DashDot,
+ XFA_ATTRIBUTEENUM_Gregorian,
+ XFA_ATTRIBUTEENUM_Roman,
+ XFA_ATTRIBUTEENUM_MouseDown,
+ XFA_ATTRIBUTEENUM_Symbol,
+ XFA_ATTRIBUTEENUM_PageEven,
+ XFA_ATTRIBUTEENUM_Sign,
+ XFA_ATTRIBUTEENUM_AddNew,
+ XFA_ATTRIBUTEENUM_Star,
+ XFA_ATTRIBUTEENUM_Optimistic,
+ XFA_ATTRIBUTEENUM_Rl_tb,
+ XFA_ATTRIBUTEENUM_MiddleRight,
+ XFA_ATTRIBUTEENUM_Maintain,
+ XFA_ATTRIBUTEENUM_Package,
+ XFA_ATTRIBUTEENUM_SimplifiedChinese,
+ XFA_ATTRIBUTEENUM_ToCenter,
+ XFA_ATTRIBUTEENUM_Back,
+ XFA_ATTRIBUTEENUM_Unspecified,
+ XFA_ATTRIBUTEENUM_BatchOptimistic,
+ XFA_ATTRIBUTEENUM_Bold,
+ XFA_ATTRIBUTEENUM_Both,
+ XFA_ATTRIBUTEENUM_Butt,
+ XFA_ATTRIBUTEENUM_Client,
+ XFA_ATTRIBUTEENUM_2mod10,
+ XFA_ATTRIBUTEENUM_ImageOnly,
+ XFA_ATTRIBUTEENUM_Horizontal,
+ XFA_ATTRIBUTEENUM_Dotted,
+ XFA_ATTRIBUTEENUM_UserControl,
+ XFA_ATTRIBUTEENUM_DiagonalRight,
+ XFA_ATTRIBUTEENUM_ConsumeData,
+ XFA_ATTRIBUTEENUM_Check,
+ XFA_ATTRIBUTEENUM_Data,
+ XFA_ATTRIBUTEENUM_Down,
+ XFA_ATTRIBUTEENUM_SansSerif,
+ XFA_ATTRIBUTEENUM_Inline,
+ XFA_ATTRIBUTEENUM_TraditionalChinese,
+ XFA_ATTRIBUTEENUM_Warn,
+ XFA_ATTRIBUTEENUM_RefOnly,
+ XFA_ATTRIBUTEENUM_InteractiveForms,
+ XFA_ATTRIBUTEENUM_Word,
+ XFA_ATTRIBUTEENUM_Unordered,
+ XFA_ATTRIBUTEENUM_Required,
+ XFA_ATTRIBUTEENUM_ImportOnly,
+ XFA_ATTRIBUTEENUM_BelowEmbedded,
+ XFA_ATTRIBUTEENUM_Japanese,
+ XFA_ATTRIBUTEENUM_Full,
+ XFA_ATTRIBUTEENUM_Rl_row,
+ XFA_ATTRIBUTEENUM_Vietnamese,
+ XFA_ATTRIBUTEENUM_EastEuropeanRoman,
+ XFA_ATTRIBUTEENUM_MouseUp,
+ XFA_ATTRIBUTEENUM_ExportOnly,
+ XFA_ATTRIBUTEENUM_Clear,
+ XFA_ATTRIBUTEENUM_Click,
+ XFA_ATTRIBUTEENUM_Base64,
+ XFA_ATTRIBUTEENUM_Close,
+ XFA_ATTRIBUTEENUM_Host,
+ XFA_ATTRIBUTEENUM_Global,
+ XFA_ATTRIBUTEENUM_Blank,
+ XFA_ATTRIBUTEENUM_Table,
+ XFA_ATTRIBUTEENUM_Import,
+ XFA_ATTRIBUTEENUM_Custom,
+ XFA_ATTRIBUTEENUM_MiddleLeft,
+ XFA_ATTRIBUTEENUM_PostExecute,
+ XFA_ATTRIBUTEENUM_Radix,
+ XFA_ATTRIBUTEENUM_PostOpen,
+ XFA_ATTRIBUTEENUM_Enter,
+ XFA_ATTRIBUTEENUM_Ignore,
+ XFA_ATTRIBUTEENUM_Lr_tb,
+ XFA_ATTRIBUTEENUM_Fantasy,
+ XFA_ATTRIBUTEENUM_Italic,
+ XFA_ATTRIBUTEENUM_Author,
+ XFA_ATTRIBUTEENUM_ToEdge,
+ XFA_ATTRIBUTEENUM_Choice,
+ XFA_ATTRIBUTEENUM_Disabled,
+ XFA_ATTRIBUTEENUM_CrossHatch,
+ XFA_ATTRIBUTEENUM_DataRef,
+ XFA_ATTRIBUTEENUM_DashDotDot,
+ XFA_ATTRIBUTEENUM_Square,
+ XFA_ATTRIBUTEENUM_Dynamic,
+ XFA_ATTRIBUTEENUM_Manual,
+ XFA_ATTRIBUTEENUM_Etched,
+ XFA_ATTRIBUTEENUM_ValidationState,
+ XFA_ATTRIBUTEENUM_Cursive,
+ XFA_ATTRIBUTEENUM_Last,
+ XFA_ATTRIBUTEENUM_Left,
+ XFA_ATTRIBUTEENUM_Link,
+ XFA_ATTRIBUTEENUM_Long,
+ XFA_ATTRIBUTEENUM_InternationalCarrier,
+ XFA_ATTRIBUTEENUM_PDF1_3,
+ XFA_ATTRIBUTEENUM_PDF1_6,
+ XFA_ATTRIBUTEENUM_Serif,
+ XFA_ATTRIBUTEENUM_PostSave,
+ XFA_ATTRIBUTEENUM_Ready,
+ XFA_ATTRIBUTEENUM_PostSign,
+ XFA_ATTRIBUTEENUM_Arabic,
+ XFA_ATTRIBUTEENUM_Error,
+ XFA_ATTRIBUTEENUM_Urlencoded,
+ XFA_ATTRIBUTEENUM_Lowered,
+};
+enum XFA_ATTRIBUTE {
+ XFA_ATTRIBUTE_H,
+ XFA_ATTRIBUTE_W,
+ XFA_ATTRIBUTE_X,
+ XFA_ATTRIBUTE_Y,
+ XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_To,
+ XFA_ATTRIBUTE_LineThrough,
+ XFA_ATTRIBUTE_HAlign,
+ XFA_ATTRIBUTE_Typeface,
+ XFA_ATTRIBUTE_BeforeTarget,
+ XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Next,
+ XFA_ATTRIBUTE_DataRowCount,
+ XFA_ATTRIBUTE_Break,
+ XFA_ATTRIBUTE_VScrollPolicy,
+ XFA_ATTRIBUTE_FontHorizontalScale,
+ XFA_ATTRIBUTE_TextIndent,
+ XFA_ATTRIBUTE_Context,
+ XFA_ATTRIBUTE_TrayOut,
+ XFA_ATTRIBUTE_Cap,
+ XFA_ATTRIBUTE_Max,
+ XFA_ATTRIBUTE_Min,
+ XFA_ATTRIBUTE_Ref,
+ XFA_ATTRIBUTE_Rid,
+ XFA_ATTRIBUTE_Url,
+ XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_LeftInset,
+ XFA_ATTRIBUTE_Widows,
+ XFA_ATTRIBUTE_Level,
+ XFA_ATTRIBUTE_BottomInset,
+ XFA_ATTRIBUTE_OverflowTarget,
+ XFA_ATTRIBUTE_AllowMacro,
+ XFA_ATTRIBUTE_PagePosition,
+ XFA_ATTRIBUTE_ColumnWidths,
+ XFA_ATTRIBUTE_OverflowLeader,
+ XFA_ATTRIBUTE_Action,
+ XFA_ATTRIBUTE_NonRepudiation,
+ XFA_ATTRIBUTE_Rate,
+ XFA_ATTRIBUTE_AllowRichText,
+ XFA_ATTRIBUTE_Role,
+ XFA_ATTRIBUTE_OverflowTrailer,
+ XFA_ATTRIBUTE_Operation,
+ XFA_ATTRIBUTE_Timeout,
+ XFA_ATTRIBUTE_TopInset,
+ XFA_ATTRIBUTE_Access,
+ XFA_ATTRIBUTE_CommandType,
+ XFA_ATTRIBUTE_Format,
+ XFA_ATTRIBUTE_DataPrep,
+ XFA_ATTRIBUTE_WidgetData,
+ XFA_ATTRIBUTE_Abbr,
+ XFA_ATTRIBUTE_MarginRight,
+ XFA_ATTRIBUTE_DataDescription,
+ XFA_ATTRIBUTE_EncipherOnly,
+ XFA_ATTRIBUTE_KerningMode,
+ XFA_ATTRIBUTE_Rotate,
+ XFA_ATTRIBUTE_WordCharacterCount,
+ XFA_ATTRIBUTE_Type,
+ XFA_ATTRIBUTE_Reserve,
+ XFA_ATTRIBUTE_TextLocation,
+ XFA_ATTRIBUTE_Priority,
+ XFA_ATTRIBUTE_Underline,
+ XFA_ATTRIBUTE_ModuleWidth,
+ XFA_ATTRIBUTE_Hyphenate,
+ XFA_ATTRIBUTE_Listen,
+ XFA_ATTRIBUTE_Delimiter,
+ XFA_ATTRIBUTE_ContentType,
+ XFA_ATTRIBUTE_StartNew,
+ XFA_ATTRIBUTE_EofAction,
+ XFA_ATTRIBUTE_AllowNeutral,
+ XFA_ATTRIBUTE_Connection,
+ XFA_ATTRIBUTE_BaselineShift,
+ XFA_ATTRIBUTE_OverlinePeriod,
+ XFA_ATTRIBUTE_FracDigits,
+ XFA_ATTRIBUTE_Orientation,
+ XFA_ATTRIBUTE_TimeStamp,
+ XFA_ATTRIBUTE_PrintCheckDigit,
+ XFA_ATTRIBUTE_MarginLeft,
+ XFA_ATTRIBUTE_Stroke,
+ XFA_ATTRIBUTE_ModuleHeight,
+ XFA_ATTRIBUTE_TransferEncoding,
+ XFA_ATTRIBUTE_Usage,
+ XFA_ATTRIBUTE_Presence,
+ XFA_ATTRIBUTE_RadixOffset,
+ XFA_ATTRIBUTE_Preserve,
+ XFA_ATTRIBUTE_AliasNode,
+ XFA_ATTRIBUTE_MultiLine,
+ XFA_ATTRIBUTE_Version,
+ XFA_ATTRIBUTE_StartChar,
+ XFA_ATTRIBUTE_ScriptTest,
+ XFA_ATTRIBUTE_StartAngle,
+ XFA_ATTRIBUTE_CursorType,
+ XFA_ATTRIBUTE_DigitalSignature,
+ XFA_ATTRIBUTE_CodeType,
+ XFA_ATTRIBUTE_Output,
+ XFA_ATTRIBUTE_BookendTrailer,
+ XFA_ATTRIBUTE_ImagingBBox,
+ XFA_ATTRIBUTE_ExcludeInitialCap,
+ XFA_ATTRIBUTE_Force,
+ XFA_ATTRIBUTE_CrlSign,
+ XFA_ATTRIBUTE_Previous,
+ XFA_ATTRIBUTE_PushCharacterCount,
+ XFA_ATTRIBUTE_NullTest,
+ XFA_ATTRIBUTE_RunAt,
+ XFA_ATTRIBUTE_SpaceBelow,
+ XFA_ATTRIBUTE_SweepAngle,
+ XFA_ATTRIBUTE_NumberOfCells,
+ XFA_ATTRIBUTE_LetterSpacing,
+ XFA_ATTRIBUTE_LockType,
+ XFA_ATTRIBUTE_PasswordChar,
+ XFA_ATTRIBUTE_VAlign,
+ XFA_ATTRIBUTE_SourceBelow,
+ XFA_ATTRIBUTE_Inverted,
+ XFA_ATTRIBUTE_Mark,
+ XFA_ATTRIBUTE_MaxH,
+ XFA_ATTRIBUTE_MaxW,
+ XFA_ATTRIBUTE_Truncate,
+ XFA_ATTRIBUTE_MinH,
+ XFA_ATTRIBUTE_MinW,
+ XFA_ATTRIBUTE_Initial,
+ XFA_ATTRIBUTE_Mode,
+ XFA_ATTRIBUTE_Layout,
+ XFA_ATTRIBUTE_Server,
+ XFA_ATTRIBUTE_EmbedPDF,
+ XFA_ATTRIBUTE_OddOrEven,
+ XFA_ATTRIBUTE_TabDefault,
+ XFA_ATTRIBUTE_Contains,
+ XFA_ATTRIBUTE_RightInset,
+ XFA_ATTRIBUTE_MaxChars,
+ XFA_ATTRIBUTE_Open,
+ XFA_ATTRIBUTE_Relation,
+ XFA_ATTRIBUTE_WideNarrowRatio,
+ XFA_ATTRIBUTE_Relevant,
+ XFA_ATTRIBUTE_SignatureType,
+ XFA_ATTRIBUTE_LineThroughPeriod,
+ XFA_ATTRIBUTE_Shape,
+ XFA_ATTRIBUTE_TabStops,
+ XFA_ATTRIBUTE_OutputBelow,
+ XFA_ATTRIBUTE_Short,
+ XFA_ATTRIBUTE_FontVerticalScale,
+ XFA_ATTRIBUTE_Thickness,
+ XFA_ATTRIBUTE_CommitOn,
+ XFA_ATTRIBUTE_RemainCharacterCount,
+ XFA_ATTRIBUTE_KeyAgreement,
+ XFA_ATTRIBUTE_ErrorCorrectionLevel,
+ XFA_ATTRIBUTE_UpsMode,
+ XFA_ATTRIBUTE_MergeMode,
+ XFA_ATTRIBUTE_Circular,
+ XFA_ATTRIBUTE_PsName,
+ XFA_ATTRIBUTE_Trailer,
+ XFA_ATTRIBUTE_UnicodeRange,
+ XFA_ATTRIBUTE_ExecuteType,
+ XFA_ATTRIBUTE_DuplexImposition,
+ XFA_ATTRIBUTE_TrayIn,
+ XFA_ATTRIBUTE_BindingNode,
+ XFA_ATTRIBUTE_BofAction,
+ XFA_ATTRIBUTE_Save,
+ XFA_ATTRIBUTE_TargetType,
+ XFA_ATTRIBUTE_KeyEncipherment,
+ XFA_ATTRIBUTE_CredentialServerPolicy,
+ XFA_ATTRIBUTE_Size,
+ XFA_ATTRIBUTE_InitialNumber,
+ XFA_ATTRIBUTE_Slope,
+ XFA_ATTRIBUTE_CSpace,
+ XFA_ATTRIBUTE_ColSpan,
+ XFA_ATTRIBUTE_Binding,
+ XFA_ATTRIBUTE_Checksum,
+ XFA_ATTRIBUTE_CharEncoding,
+ XFA_ATTRIBUTE_Bind,
+ XFA_ATTRIBUTE_TextEntry,
+ XFA_ATTRIBUTE_Archive,
+ XFA_ATTRIBUTE_Uuid,
+ XFA_ATTRIBUTE_Posture,
+ XFA_ATTRIBUTE_After,
+ XFA_ATTRIBUTE_Orphans,
+ XFA_ATTRIBUTE_QualifiedName,
+ XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Locale,
+ XFA_ATTRIBUTE_Weight,
+ XFA_ATTRIBUTE_UnderlinePeriod,
+ XFA_ATTRIBUTE_Data,
+ XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Numbered,
+ XFA_ATTRIBUTE_DataColumnCount,
+ XFA_ATTRIBUTE_Overline,
+ XFA_ATTRIBUTE_UrlPolicy,
+ XFA_ATTRIBUTE_AnchorType,
+ XFA_ATTRIBUTE_LabelRef,
+ XFA_ATTRIBUTE_BookendLeader,
+ XFA_ATTRIBUTE_MaxLength,
+ XFA_ATTRIBUTE_AccessKey,
+ XFA_ATTRIBUTE_CursorLocation,
+ XFA_ATTRIBUTE_DelayedOpen,
+ XFA_ATTRIBUTE_Target,
+ XFA_ATTRIBUTE_DataEncipherment,
+ XFA_ATTRIBUTE_AfterTarget,
+ XFA_ATTRIBUTE_Leader,
+ XFA_ATTRIBUTE_Picker,
+ XFA_ATTRIBUTE_From,
+ XFA_ATTRIBUTE_BaseProfile,
+ XFA_ATTRIBUTE_Aspect,
+ XFA_ATTRIBUTE_RowColumnRatio,
+ XFA_ATTRIBUTE_LineHeight,
+ XFA_ATTRIBUTE_Highlight,
+ XFA_ATTRIBUTE_ValueRef,
+ XFA_ATTRIBUTE_MaxEntries,
+ XFA_ATTRIBUTE_DataLength,
+ XFA_ATTRIBUTE_Activity,
+ XFA_ATTRIBUTE_Input,
+ XFA_ATTRIBUTE_Value,
+ XFA_ATTRIBUTE_BlankOrNotBlank,
+ XFA_ATTRIBUTE_AddRevocationInfo,
+ XFA_ATTRIBUTE_GenericFamily,
+ XFA_ATTRIBUTE_Hand,
+ XFA_ATTRIBUTE_Href,
+ XFA_ATTRIBUTE_TextEncoding,
+ XFA_ATTRIBUTE_LeadDigits,
+ XFA_ATTRIBUTE_Permissions,
+ XFA_ATTRIBUTE_SpaceAbove,
+ XFA_ATTRIBUTE_CodeBase,
+ XFA_ATTRIBUTE_Stock,
+ XFA_ATTRIBUTE_IsNull,
+ XFA_ATTRIBUTE_RestoreState,
+ XFA_ATTRIBUTE_ExcludeAllCaps,
+ XFA_ATTRIBUTE_FormatTest,
+ XFA_ATTRIBUTE_HScrollPolicy,
+ XFA_ATTRIBUTE_Join,
+ XFA_ATTRIBUTE_KeyCertSign,
+ XFA_ATTRIBUTE_Radius,
+ XFA_ATTRIBUTE_SourceAbove,
+ XFA_ATTRIBUTE_Override,
+ XFA_ATTRIBUTE_ClassId,
+ XFA_ATTRIBUTE_Disable,
+ XFA_ATTRIBUTE_Scope,
+ XFA_ATTRIBUTE_Match,
+ XFA_ATTRIBUTE_Placement,
+ XFA_ATTRIBUTE_Before,
+ XFA_ATTRIBUTE_WritingScript,
+ XFA_ATTRIBUTE_EndChar,
+ XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Long,
+ XFA_ATTRIBUTE_Intact,
+ XFA_ATTRIBUTE_XdpContent,
+ XFA_ATTRIBUTE_DecipherOnly,
+};
+enum XFA_ELEMENT {
+ XFA_ELEMENT_Ps,
+ XFA_ELEMENT_To,
+ XFA_ELEMENT_Ui,
+ XFA_ELEMENT_RecordSet,
+ XFA_ELEMENT_SubsetBelow,
+ XFA_ELEMENT_SubformSet,
+ XFA_ELEMENT_AdobeExtensionLevel,
+ XFA_ELEMENT_Typeface,
+ XFA_ELEMENT_Break,
+ XFA_ELEMENT_FontInfo,
+ XFA_ELEMENT_NumberPattern,
+ XFA_ELEMENT_DynamicRender,
+ XFA_ELEMENT_PrintScaling,
+ XFA_ELEMENT_CheckButton,
+ XFA_ELEMENT_DatePatterns,
+ XFA_ELEMENT_SourceSet,
+ XFA_ELEMENT_Amd,
+ XFA_ELEMENT_Arc,
+ XFA_ELEMENT_Day,
+ XFA_ELEMENT_Era,
+ XFA_ELEMENT_Jog,
+ XFA_ELEMENT_Log,
+ XFA_ELEMENT_Map,
+ XFA_ELEMENT_Mdp,
+ XFA_ELEMENT_BreakBefore,
+ XFA_ELEMENT_Oid,
+ XFA_ELEMENT_Pcl,
+ XFA_ELEMENT_Pdf,
+ XFA_ELEMENT_Ref,
+ XFA_ELEMENT_Uri,
+ XFA_ELEMENT_Xdc,
+ XFA_ELEMENT_Xdp,
+ XFA_ELEMENT_Xfa,
+ XFA_ELEMENT_Xsl,
+ XFA_ELEMENT_Zpl,
+ XFA_ELEMENT_Cache,
+ XFA_ELEMENT_Margin,
+ XFA_ELEMENT_KeyUsage,
+ XFA_ELEMENT_Exclude,
+ XFA_ELEMENT_ChoiceList,
+ XFA_ELEMENT_Level,
+ XFA_ELEMENT_LabelPrinter,
+ XFA_ELEMENT_CalendarSymbols,
+ XFA_ELEMENT_Para,
+ XFA_ELEMENT_Part,
+ XFA_ELEMENT_Pdfa,
+ XFA_ELEMENT_Filter,
+ XFA_ELEMENT_Present,
+ XFA_ELEMENT_Pagination,
+ XFA_ELEMENT_Encoding,
+ XFA_ELEMENT_Event,
+ XFA_ELEMENT_Whitespace,
+ XFA_ELEMENT_DefaultUi,
+ XFA_ELEMENT_DataModel,
+ XFA_ELEMENT_Barcode,
+ XFA_ELEMENT_TimePattern,
+ XFA_ELEMENT_BatchOutput,
+ XFA_ELEMENT_Enforce,
+ XFA_ELEMENT_CurrencySymbols,
+ XFA_ELEMENT_AddSilentPrint,
+ XFA_ELEMENT_Rename,
+ XFA_ELEMENT_Operation,
+ XFA_ELEMENT_Typefaces,
+ XFA_ELEMENT_SubjectDNs,
+ XFA_ELEMENT_Issuers,
+ XFA_ELEMENT_SignaturePseudoModel,
+ XFA_ELEMENT_WsdlConnection,
+ XFA_ELEMENT_Debug,
+ XFA_ELEMENT_Delta,
+ XFA_ELEMENT_EraNames,
+ XFA_ELEMENT_ModifyAnnots,
+ XFA_ELEMENT_StartNode,
+ XFA_ELEMENT_Button,
+ XFA_ELEMENT_Format,
+ XFA_ELEMENT_Border,
+ XFA_ELEMENT_Area,
+ XFA_ELEMENT_Hyphenation,
+ XFA_ELEMENT_Text,
+ XFA_ELEMENT_Time,
+ XFA_ELEMENT_Type,
+ XFA_ELEMENT_Overprint,
+ XFA_ELEMENT_Certificates,
+ XFA_ELEMENT_EncryptionMethods,
+ XFA_ELEMENT_SetProperty,
+ XFA_ELEMENT_PrinterName,
+ XFA_ELEMENT_StartPage,
+ XFA_ELEMENT_PageOffset,
+ XFA_ELEMENT_DateTime,
+ XFA_ELEMENT_Comb,
+ XFA_ELEMENT_Pattern,
+ XFA_ELEMENT_IfEmpty,
+ XFA_ELEMENT_SuppressBanner,
+ XFA_ELEMENT_OutputBin,
+ XFA_ELEMENT_Field,
+ XFA_ELEMENT_Agent,
+ XFA_ELEMENT_OutputXSL,
+ XFA_ELEMENT_AdjustData,
+ XFA_ELEMENT_AutoSave,
+ XFA_ELEMENT_ContentArea,
+ XFA_ELEMENT_EventPseudoModel,
+ XFA_ELEMENT_WsdlAddress,
+ XFA_ELEMENT_Solid,
+ XFA_ELEMENT_DateTimeSymbols,
+ XFA_ELEMENT_EncryptionLevel,
+ XFA_ELEMENT_Edge,
+ XFA_ELEMENT_Stipple,
+ XFA_ELEMENT_Attributes,
+ XFA_ELEMENT_VersionControl,
+ XFA_ELEMENT_Meridiem,
+ XFA_ELEMENT_ExclGroup,
+ XFA_ELEMENT_ToolTip,
+ XFA_ELEMENT_Compress,
+ XFA_ELEMENT_Reason,
+ XFA_ELEMENT_Execute,
+ XFA_ELEMENT_ContentCopy,
+ XFA_ELEMENT_DateTimeEdit,
+ XFA_ELEMENT_Config,
+ XFA_ELEMENT_Image,
+ XFA_ELEMENT_SharpxHTML,
+ XFA_ELEMENT_NumberOfCopies,
+ XFA_ELEMENT_BehaviorOverride,
+ XFA_ELEMENT_TimeStamp,
+ XFA_ELEMENT_Month,
+ XFA_ELEMENT_ViewerPreferences,
+ XFA_ELEMENT_ScriptModel,
+ XFA_ELEMENT_Decimal,
+ XFA_ELEMENT_Subform,
+ XFA_ELEMENT_Select,
+ XFA_ELEMENT_Window,
+ XFA_ELEMENT_LocaleSet,
+ XFA_ELEMENT_Handler,
+ XFA_ELEMENT_HostPseudoModel,
+ XFA_ELEMENT_Presence,
+ XFA_ELEMENT_Record,
+ XFA_ELEMENT_Embed,
+ XFA_ELEMENT_Version,
+ XFA_ELEMENT_Command,
+ XFA_ELEMENT_Copies,
+ XFA_ELEMENT_Staple,
+ XFA_ELEMENT_SubmitFormat,
+ XFA_ELEMENT_Boolean,
+ XFA_ELEMENT_Message,
+ XFA_ELEMENT_Output,
+ XFA_ELEMENT_PsMap,
+ XFA_ELEMENT_ExcludeNS,
+ XFA_ELEMENT_Assist,
+ XFA_ELEMENT_Picture,
+ XFA_ELEMENT_Traversal,
+ XFA_ELEMENT_SilentPrint,
+ XFA_ELEMENT_WebClient,
+ XFA_ELEMENT_LayoutPseudoModel,
+ XFA_ELEMENT_Producer,
+ XFA_ELEMENT_Corner,
+ XFA_ELEMENT_MsgId,
+ XFA_ELEMENT_Color,
+ XFA_ELEMENT_Keep,
+ XFA_ELEMENT_Query,
+ XFA_ELEMENT_Insert,
+ XFA_ELEMENT_ImageEdit,
+ XFA_ELEMENT_Validate,
+ XFA_ELEMENT_DigestMethods,
+ XFA_ELEMENT_NumberPatterns,
+ XFA_ELEMENT_PageSet,
+ XFA_ELEMENT_Integer,
+ XFA_ELEMENT_SoapAddress,
+ XFA_ELEMENT_Equate,
+ XFA_ELEMENT_FormFieldFilling,
+ XFA_ELEMENT_PageRange,
+ XFA_ELEMENT_Update,
+ XFA_ELEMENT_ConnectString,
+ XFA_ELEMENT_Mode,
+ XFA_ELEMENT_Layout,
+ XFA_ELEMENT_Sharpxml,
+ XFA_ELEMENT_XsdConnection,
+ XFA_ELEMENT_Traverse,
+ XFA_ELEMENT_Encodings,
+ XFA_ELEMENT_Template,
+ XFA_ELEMENT_Acrobat,
+ XFA_ELEMENT_ValidationMessaging,
+ XFA_ELEMENT_Signing,
+ XFA_ELEMENT_DataWindow,
+ XFA_ELEMENT_Script,
+ XFA_ELEMENT_AddViewerPreferences,
+ XFA_ELEMENT_AlwaysEmbed,
+ XFA_ELEMENT_PasswordEdit,
+ XFA_ELEMENT_NumericEdit,
+ XFA_ELEMENT_EncryptionMethod,
+ XFA_ELEMENT_Change,
+ XFA_ELEMENT_PageArea,
+ XFA_ELEMENT_SubmitUrl,
+ XFA_ELEMENT_Oids,
+ XFA_ELEMENT_Signature,
+ XFA_ELEMENT_ADBE_JSConsole,
+ XFA_ELEMENT_Caption,
+ XFA_ELEMENT_Relevant,
+ XFA_ELEMENT_FlipLabel,
+ XFA_ELEMENT_ExData,
+ XFA_ELEMENT_DayNames,
+ XFA_ELEMENT_SoapAction,
+ XFA_ELEMENT_DefaultTypeface,
+ XFA_ELEMENT_Manifest,
+ XFA_ELEMENT_Overflow,
+ XFA_ELEMENT_Linear,
+ XFA_ELEMENT_CurrencySymbol,
+ XFA_ELEMENT_Delete,
+ XFA_ELEMENT_Deltas,
+ XFA_ELEMENT_DigestMethod,
+ XFA_ELEMENT_InstanceManager,
+ XFA_ELEMENT_EquateRange,
+ XFA_ELEMENT_Medium,
+ XFA_ELEMENT_TextEdit,
+ XFA_ELEMENT_TemplateCache,
+ XFA_ELEMENT_CompressObjectStream,
+ XFA_ELEMENT_DataValue,
+ XFA_ELEMENT_AccessibleContent,
+ XFA_ELEMENT_NodeList,
+ XFA_ELEMENT_IncludeXDPContent,
+ XFA_ELEMENT_XmlConnection,
+ XFA_ELEMENT_ValidateApprovalSignatures,
+ XFA_ELEMENT_SignData,
+ XFA_ELEMENT_Packets,
+ XFA_ELEMENT_DatePattern,
+ XFA_ELEMENT_DuplexOption,
+ XFA_ELEMENT_Base,
+ XFA_ELEMENT_Bind,
+ XFA_ELEMENT_Compression,
+ XFA_ELEMENT_User,
+ XFA_ELEMENT_Rectangle,
+ XFA_ELEMENT_EffectiveOutputPolicy,
+ XFA_ELEMENT_ADBE_JSDebugger,
+ XFA_ELEMENT_Acrobat7,
+ XFA_ELEMENT_Interactive,
+ XFA_ELEMENT_Locale,
+ XFA_ELEMENT_CurrentPage,
+ XFA_ELEMENT_Data,
+ XFA_ELEMENT_Date,
+ XFA_ELEMENT_Desc,
+ XFA_ELEMENT_Encrypt,
+ XFA_ELEMENT_Draw,
+ XFA_ELEMENT_Encryption,
+ XFA_ELEMENT_MeridiemNames,
+ XFA_ELEMENT_Messaging,
+ XFA_ELEMENT_Speak,
+ XFA_ELEMENT_DataGroup,
+ XFA_ELEMENT_Common,
+ XFA_ELEMENT_Sharptext,
+ XFA_ELEMENT_PaginationOverride,
+ XFA_ELEMENT_Reasons,
+ XFA_ELEMENT_SignatureProperties,
+ XFA_ELEMENT_Threshold,
+ XFA_ELEMENT_AppearanceFilter,
+ XFA_ELEMENT_Fill,
+ XFA_ELEMENT_Font,
+ XFA_ELEMENT_Form,
+ XFA_ELEMENT_MediumInfo,
+ XFA_ELEMENT_Certificate,
+ XFA_ELEMENT_Password,
+ XFA_ELEMENT_RunScripts,
+ XFA_ELEMENT_Trace,
+ XFA_ELEMENT_Float,
+ XFA_ELEMENT_RenderPolicy,
+ XFA_ELEMENT_LogPseudoModel,
+ XFA_ELEMENT_Destination,
+ XFA_ELEMENT_Value,
+ XFA_ELEMENT_Bookend,
+ XFA_ELEMENT_ExObject,
+ XFA_ELEMENT_OpenAction,
+ XFA_ELEMENT_NeverEmbed,
+ XFA_ELEMENT_BindItems,
+ XFA_ELEMENT_Calculate,
+ XFA_ELEMENT_Print,
+ XFA_ELEMENT_Extras,
+ XFA_ELEMENT_Proto,
+ XFA_ELEMENT_DSigData,
+ XFA_ELEMENT_Creator,
+ XFA_ELEMENT_Connect,
+ XFA_ELEMENT_Permissions,
+ XFA_ELEMENT_ConnectionSet,
+ XFA_ELEMENT_Submit,
+ XFA_ELEMENT_Range,
+ XFA_ELEMENT_Linearized,
+ XFA_ELEMENT_Packet,
+ XFA_ELEMENT_RootElement,
+ XFA_ELEMENT_PlaintextMetadata,
+ XFA_ELEMENT_NumberSymbols,
+ XFA_ELEMENT_PrintHighQuality,
+ XFA_ELEMENT_Driver,
+ XFA_ELEMENT_IncrementalLoad,
+ XFA_ELEMENT_SubjectDN,
+ XFA_ELEMENT_CompressLogicalStructure,
+ XFA_ELEMENT_IncrementalMerge,
+ XFA_ELEMENT_Radial,
+ XFA_ELEMENT_Variables,
+ XFA_ELEMENT_TimePatterns,
+ XFA_ELEMENT_EffectiveInputPolicy,
+ XFA_ELEMENT_NameAttr,
+ XFA_ELEMENT_Conformance,
+ XFA_ELEMENT_Transform,
+ XFA_ELEMENT_LockDocument,
+ XFA_ELEMENT_BreakAfter,
+ XFA_ELEMENT_Line,
+ XFA_ELEMENT_List,
+ XFA_ELEMENT_Source,
+ XFA_ELEMENT_Occur,
+ XFA_ELEMENT_PickTrayByPDFSize,
+ XFA_ELEMENT_MonthNames,
+ XFA_ELEMENT_Severity,
+ XFA_ELEMENT_GroupParent,
+ XFA_ELEMENT_DocumentAssembly,
+ XFA_ELEMENT_NumberSymbol,
+ XFA_ELEMENT_Tagged,
+ XFA_ELEMENT_Items,
+};
+#define XFA_ELEMENT_UNKNOWN ((XFA_ELEMENT)-1)
+typedef struct _XFA_ELEMENTINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ XFA_ELEMENT eName;
+ FX_DWORD dwPackets;
+ FX_DWORD eObjectType;
+} XFA_ELEMENTINFO, * XFA_LPELEMENTINFO;
+typedef XFA_ELEMENTINFO const * XFA_LPCELEMENTINFO;
+FX_INT32 XFA_GetElementCount();
+XFA_LPCELEMENTINFO XFA_GetElementByName(FX_WSTR wsName);
+XFA_LPCELEMENTINFO XFA_GetElementByID(XFA_ELEMENT eName);
+enum XFA_ATTRIBUTETYPE {
+ XFA_ATTRIBUTETYPE_NOTSURE,
+ XFA_ATTRIBUTETYPE_Enum,
+ XFA_ATTRIBUTETYPE_Cdata,
+ XFA_ATTRIBUTETYPE_Boolean,
+ XFA_ATTRIBUTETYPE_Integer,
+ XFA_ATTRIBUTETYPE_Measure,
+};
+typedef struct _XFA_ATTRIBUTEINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ XFA_ATTRIBUTE eName;
+ XFA_ATTRIBUTETYPE eType;
+ FX_DWORD dwPackets;
+ FX_LPVOID pDefValue;
+} XFA_ATTRIBUTEINFO, * XFA_LPATTRIBUTEINFO;
+typedef XFA_ATTRIBUTEINFO const * XFA_LPCATTRIBUTEINFO;
+FX_INT32 XFA_GetAttributeCount();
+XFA_LPCATTRIBUTEINFO XFA_GetAttributeByName(FX_WSTR wsName);
+XFA_LPCATTRIBUTEINFO XFA_GetAttributeByID(XFA_ATTRIBUTE eName);
+FX_BOOL XFA_GetAttributeDefaultValue(FX_LPVOID &pValue, XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, XFA_ATTRIBUTETYPE eType, FX_DWORD dwPacket);
+XFA_ATTRIBUTEENUM XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket);
+CFX_WideStringC XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket);
+FX_BOOL XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket);
+FX_INT32 XFA_GetAttributeDefaultValue_Integer(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket);
+CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket);
+typedef struct _XFA_ELEMENTHIERARCHY {
+ FX_WORD wStart;
+ FX_WORD wCount;
+ FX_WORD wParentIndex;
+} XFA_ELEMENTHIERARCHY, * XFA_LPELEMENTHIERARCHY;
+typedef XFA_ELEMENTHIERARCHY const * XFA_LPCELEMENTHIERARCHY;
+typedef struct _XFA_SCRIPTHIERARCHY {
+ FX_WORD wMethodStart;
+ FX_WORD wMethodCount;
+ FX_WORD wAttributeStart;
+ FX_WORD wAttributeCount;
+ FX_SHORT wParentIndex;
+} XFA_SCRIPTHIERARCHY, * XFA_LPSCRIPTHIERARCHY;
+typedef XFA_SCRIPTHIERARCHY const * XFA_LPCSCRIPTHIERARCHY;
+FX_LPCWORD XFA_GetElementChildren(XFA_ELEMENT eElement, FX_INT32 &iCount);
+FX_LPCBYTE XFA_GetElementAttributes(XFA_ELEMENT eElement, FX_INT32 &iCount);
+XFA_LPCELEMENTINFO XFA_GetChildOfElement(XFA_ELEMENT eElement, XFA_ELEMENT eChild, FX_DWORD dwPacket);
+XFA_LPCATTRIBUTEINFO XFA_GetAttributeOfElement(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket);
+#define XFA_PROPERTYFLAG_OneOf 0x01
+#define XFA_PROPERTYFLAG_DefaultOneOf 0x02
+typedef struct _XFA_PROPERTY {
+ FX_WORD eName;
+ FX_BYTE uOccur;
+ FX_BYTE uFlags;
+} XFA_PROPERTY, * XFA_LPPROPERTY;
+typedef XFA_PROPERTY const * XFA_LPCPROPERTY;
+XFA_LPCPROPERTY XFA_GetElementProperties(XFA_ELEMENT eElement, FX_INT32 &iCount);
+XFA_LPCPROPERTY XFA_GetPropertyOfElement(XFA_ELEMENT eElement, XFA_ELEMENT eProperty, FX_DWORD dwPacket);
+typedef struct _XFA_ATTRIBUTEENUMINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ XFA_ATTRIBUTEENUM eName;
+} XFA_ATTRIBUTEENUMINFO, * XFA_LPATTRIBUTEENUMINFO;
+typedef XFA_ATTRIBUTEENUMINFO const * XFA_LPCATTRIBUTEENUMINFO;
+XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByName(FX_WSTR wsName);
+XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName);
+enum XFA_UNIT {
+ XFA_UNIT_Unknown,
+ XFA_UNIT_Percent,
+ XFA_UNIT_Angle,
+ XFA_UNIT_Em,
+ XFA_UNIT_Pt,
+ XFA_UNIT_In,
+ XFA_UNIT_Pc,
+ XFA_UNIT_Cm,
+ XFA_UNIT_Mm,
+ XFA_UNIT_Mp,
+};
+class CXFA_Measurement
+{
+public:
+ void Set(FX_WSTR wsMeasure);
+ void Set(FX_FLOAT fValue, XFA_UNIT eUnit)
+ {
+ m_fValue = fValue;
+ m_eUnit = eUnit;
+ }
+
+ XFA_UNIT GetUnit() const
+ {
+ return m_eUnit;
+ }
+ FX_FLOAT GetValue() const
+ {
+ return m_fValue;
+ }
+ FX_BOOL ToString(CFX_WideString &wsMeasure) const;
+ FX_BOOL ToUnit(XFA_UNIT eUnit, FX_FLOAT &fValue) const;
+ FX_FLOAT ToUnit(XFA_UNIT eUnit) const
+ {
+ FX_FLOAT f;
+ return ToUnit(eUnit, f) ? f : 0;
+ }
+ CXFA_Measurement()
+ {
+ Set(-1, XFA_UNIT_Unknown);
+ }
+ CXFA_Measurement(FX_WSTR wsMeasure)
+ {
+ Set(wsMeasure);
+ }
+ CXFA_Measurement(FX_FLOAT fValue, XFA_UNIT eUnit)
+ {
+ Set(fValue, eUnit);
+ }
+ static XFA_UNIT GetUnit(FX_WSTR wsUnit);
+protected:
+ FX_FLOAT m_fValue;
+ XFA_UNIT m_eUnit;
+};
+class CFXJSE_Arguments;
+class CXFA_Object;
+typedef void (CXFA_Object::*XFA_METHOD_CALLBACK) (CFXJSE_Arguments* pArguments);
+typedef struct _XFA_METHODINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ XFA_METHOD_CALLBACK lpfnCallback;
+} XFA_METHODINFO, * XFA_LPMETHODINFO;
+typedef XFA_METHODINFO const * XFA_LPCMETHODINFO;
+FX_INT32 XFA_GetMethodCount();
+XFA_LPCMETHODINFO XFA_GetMethodByName(XFA_ELEMENT eElement, FX_WSTR wsMethodName);
+typedef void (CXFA_Object::*XFA_ATTRIBUTE_CALLBACK) (FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+enum XFA_SCRIPT_TYPE {
+ XFA_SCRIPT_Basic,
+ XFA_SCRIPT_Object,
+};
+typedef struct _XFA_SCRIPTATTRIBUTEINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ XFA_ATTRIBUTE_CALLBACK lpfnCallback;
+ FX_INT32 eAttribute;
+ FX_WORD eValueType;
+} XFA_SCRIPTATTRIBUTEINFO, * XFA_LPSCRIPTATTRIBUTEINFO;
+typedef XFA_SCRIPTATTRIBUTEINFO const * XFA_LPCSCRIPTATTRIBUTEINFO;
+XFA_LPCSCRIPTATTRIBUTEINFO XFA_GetScriptAttributeByName(XFA_ELEMENT eElement, FX_WSTR wsAttributeName);
+#endif
diff --git a/xfa/include/fxfa/fxfa_objectacc.h b/xfa/include/fxfa/fxfa_objectacc.h
new file mode 100644
index 0000000000..14bd1ed69d
--- /dev/null
+++ b/xfa/include/fxfa/fxfa_objectacc.h
@@ -0,0 +1,931 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_NODEACC_H
+#define _FXFA_NODEACC_H
+class CXFA_Node;
+class IFX_Locale;
+class CXFA_Data;
+class CXFA_Font;
+class CXFA_Fill;
+class CXFA_Margin;
+class CXFA_Caption;
+class CXFA_Para;
+class CXFA_Event;
+class CXFA_Script;
+class CXFA_Value;
+class CXFA_Calculate;
+class CXFA_Line;
+class CXFA_Text;
+class CXFA_ExData;
+class CXFA_Image;
+class CXFA_Validate;
+class CXFA_Variables;
+class CXFA_Bind;
+class CXFA_Assist;
+class CXFA_ToolTip;
+class CXFA_Keep;
+class CXFA_Submit;
+class CXFA_BindItems;
+class CXFA_Stroke;
+class CXFA_Corner;
+class CXFA_Edge;
+class CXFA_Box;
+class CXFA_Arc;
+class CXFA_Border;
+class CXFA_Rectangle;
+class CXFA_WidgetData;
+class CXFA_Occur;
+class CXFA_Filter;
+class CXFA_Certificate;
+class CXFA_WrapCertificate;
+class CXFA_Oids;
+class CXFA_SubjectDNs;
+class CXFA_DigestMethods;
+class CXFA_Encodings;
+class CXFA_EncryptionMethods;
+class CXFA_Reasons;
+class CXFA_Manifest;
+inline FX_BOOL XFA_IsSpace(FX_WCHAR c)
+{
+ return (c == 0x20) || (c == 0x0d) || (c == 0x0a) || (c == 0x09);
+}
+inline FX_BOOL XFA_IsDigit(FX_WCHAR c)
+{
+ return c >= '0' && c <= '9';
+}
+typedef CFX_ArrayTemplate<CXFA_Node*> CXFA_NodeArray;
+typedef CFX_ArrayTemplate<CXFA_Object*> CXFA_ObjArray;
+class CXFA_Data : public CFX_Object
+{
+public:
+ CXFA_Data(CXFA_Node* pNode) : m_pNode(pNode) {}
+ operator CXFA_Node*() const
+ {
+ return m_pNode;
+ }
+ CXFA_Node* GetNode()
+ {
+ return m_pNode;
+ }
+
+ FX_BOOL IsExistInXML() const
+ {
+ return m_pNode != NULL;
+ }
+
+ XFA_ELEMENT GetClassID() const;
+protected:
+ FX_BOOL TryMeasure(XFA_ATTRIBUTE eAttr, FX_FLOAT &fValue, FX_BOOL bUseDefault = FALSE) const;
+ FX_BOOL SetMeasure(XFA_ATTRIBUTE eAttr, FX_FLOAT fValue);
+ CXFA_Node* m_pNode;
+};
+class CXFA_Fill : public CXFA_Data
+{
+public:
+ CXFA_Fill(CXFA_Node* pNode);
+ ~CXFA_Fill();
+
+ FX_INT32 GetPresence();
+
+ FX_ARGB GetColor(FX_BOOL bText = FALSE);
+
+ void SetColor(FX_ARGB color);
+
+
+ FX_INT32 GetFillType();
+
+ FX_INT32 GetPattern(FX_ARGB& foreColor);
+
+ FX_INT32 GetStipple(FX_ARGB& stippleColor);
+
+ FX_INT32 GetLinear(FX_ARGB& endColor);
+
+ FX_INT32 GetRadial(FX_ARGB& endColor);
+ FX_BOOL SetPresence(FX_INT32 iPresence);
+ FX_BOOL SetFillType(FX_INT32 iType);
+ FX_BOOL SetPattern(FX_INT32 iPattern, FX_ARGB foreColor);
+ FX_BOOL SetStipple(FX_INT32 iStipple, FX_ARGB stippleColor);
+ FX_BOOL SetLinear(FX_INT32 iLinear, FX_ARGB endColor);
+ FX_BOOL SetRadial(FX_INT32 iRadial, FX_ARGB endColor);
+};
+class CXFA_Margin : public CXFA_Data
+{
+public:
+ CXFA_Margin(CXFA_Node* pNode);
+ FX_BOOL GetLeftInset(FX_FLOAT &fInset, FX_FLOAT fDefInset = 0) const;
+ FX_BOOL GetTopInset(FX_FLOAT &fInset, FX_FLOAT fDefInset = 0) const;
+ FX_BOOL GetRightInset(FX_FLOAT &fInset, FX_FLOAT fDefInset = 0) const;
+ FX_BOOL GetBottomInset(FX_FLOAT &fInset, FX_FLOAT fDefInset = 0) const;
+ FX_BOOL SetLeftInset(FX_FLOAT fInset);
+ FX_BOOL SetTopInset(FX_FLOAT fInset);
+ FX_BOOL SetRightInset(FX_FLOAT fInset);
+ FX_BOOL SetBottomInset(FX_FLOAT fInset);
+};
+class CXFA_Font : public CXFA_Data
+{
+public:
+ CXFA_Font(CXFA_Node* pNode);
+
+ FX_FLOAT GetBaselineShift();
+
+ FX_FLOAT GetHorizontalScale();
+
+ FX_FLOAT GetVerticalScale();
+
+ FX_FLOAT GetLetterSpacing();
+
+ FX_INT32 GetLineThrough();
+
+ FX_INT32 GetLineThroughPeriod();
+
+ FX_INT32 GetOverline();
+
+ FX_INT32 GetOverlinePeriod();
+
+ FX_INT32 GetUnderline();
+
+ FX_INT32 GetUnderlinePeriod();
+
+ FX_FLOAT GetFontSize();
+
+ void GetTypeface(CFX_WideStringC &wsTypeFace);
+
+ FX_BOOL IsBold();
+
+ FX_BOOL IsItalic();
+
+ FX_BOOL IsUseKerning();
+
+ FX_ARGB GetColor();
+
+ void SetColor(FX_ARGB color);
+ FX_BOOL SetBaselineShift(FX_FLOAT fBaselineShift);
+ FX_BOOL SetHorizontalScale(FX_FLOAT fHorizontalScale);
+ FX_BOOL SetVerticalScale(FX_FLOAT fVerticalScale);
+ FX_BOOL SetLetterSpacing(FX_FLOAT fLetterSpacing, XFA_UNIT eUnit);
+ FX_BOOL SetLineThrough(FX_INT32 iLineThrough);
+ FX_BOOL SetLineThroughPeriod(FX_INT32 iLineThroughPeriod);
+ FX_BOOL SetOverline(FX_INT32 iOverline);
+ FX_BOOL SetOverlinePeriod(FX_INT32 iOverlinePeriod);
+ FX_BOOL SetUnderline(FX_INT32 iUnderline);
+ FX_BOOL SetUnderlinePeriod(FX_INT32 iUnderlinePeriod);
+};
+class CXFA_Caption : public CXFA_Data
+{
+public:
+ CXFA_Caption(CXFA_Node* pNode);
+
+ FX_INT32 GetPresence();
+
+ FX_INT32 GetPlacementType();
+
+ FX_FLOAT GetReserve();
+
+ CXFA_Margin GetMargin();
+
+ CXFA_Font GetFont();
+
+ CXFA_Value GetValue();
+
+ CXFA_Para GetPara();
+ FX_BOOL SetPresence(FX_INT32 iPresence);
+ FX_BOOL SetPlacementType(FX_INT32 iType);
+ FX_BOOL SetReserve(FX_FLOAT fReserve);
+};
+class CXFA_Para : public CXFA_Data
+{
+public:
+ CXFA_Para(CXFA_Node* pNode);
+
+ FX_INT32 GetHorizontalAlign();
+
+ FX_INT32 GetVerticalAlign();
+
+ FX_FLOAT GetLineHeight();
+ FX_FLOAT GetMarginLeft();
+ FX_FLOAT GetMarginRight();
+ FX_INT32 GetOrphans();
+ FX_FLOAT GetRadixOffset();
+ FX_FLOAT GetSpaceAbove();
+ FX_FLOAT GetSpaceBelow();
+ FX_FLOAT GetTextIndent();
+ FX_INT32 GetWidows();
+ FX_BOOL SetHorizontalAlign(FX_INT32 iHorizontalAlign);
+ FX_BOOL SetVerticalAlign(FX_INT32 iVerticalAlign);
+ FX_BOOL SetLineHeight(FX_FLOAT fLineHeight);
+ FX_BOOL SetMarginLeft(FX_FLOAT fMarginLeft);
+ FX_BOOL SetMarginRight(FX_FLOAT fMarginRight);
+ FX_BOOL SetOrphans(FX_INT32 iOrphans);
+ FX_BOOL SetRadixOffset(FX_FLOAT fRadixOffset);
+ FX_BOOL SetSpaceAbove(FX_FLOAT fSpaceAbove);
+ FX_BOOL SetSpaceBelow(FX_FLOAT fSpaceBelow);
+ FX_BOOL SetTextIndent(FX_FLOAT fTextIndent);
+ FX_BOOL SetWidows(FX_INT32 iWidows);
+};
+class CXFA_Keep : public CXFA_Data
+{
+public:
+ CXFA_Keep(CXFA_Node *pNode, CXFA_Node *pParent);
+
+ FX_INT32 GetIntact();
+ FX_INT32 GetNext();
+ FX_INT32 GetPrevious();
+ FX_BOOL SetIntact(FX_INT32 iIntact);
+ FX_BOOL SetNext(FX_INT32 iNext);
+ FX_BOOL SetPrevious(FX_INT32 iPrevious);
+private:
+ CXFA_Node *m_pParent;
+};
+enum XFA_TEXTENCODING {
+ XFA_TEXTENCODING_None,
+ XFA_TEXTENCODING_Big5,
+ XFA_TEXTENCODING_FontSpecific,
+ XFA_TEXTENCODING_GBK,
+ XFA_TEXTENCODING_GB18030,
+ XFA_TEXTENCODING_GB2312,
+ XFA_TEXTENCODING_ISO8859NN,
+ XFA_TEXTENCODING_KSC5601,
+ XFA_TEXTENCODING_ShiftJIS,
+ XFA_TEXTENCODING_UCS2,
+ XFA_TEXTENCODING_UTF16,
+ XFA_TEXTENCODING_UTF8
+};
+class CXFA_Event : public CXFA_Data
+{
+public:
+ CXFA_Event(CXFA_Node* pNode);
+
+
+ FX_INT32 GetActivity();
+
+ FX_INT32 GetEventType();
+ void GetRef(CFX_WideStringC &wsRef);
+
+ FX_INT32 GetExecuteRunAt();
+ FX_INT32 GetExecuteType();
+ void GetExecuteConnection(CFX_WideString &wsConnection);
+
+
+ CXFA_Script GetScript();
+
+
+ CXFA_Submit GetSubmit();
+
+
+ FX_INT32 GetSignDataOperation();
+ void GetSignDataTarget(CFX_WideString &wsTarget);
+ FX_BOOL SetActivity(FX_INT32 iActivity);
+ FX_BOOL SetEventType(FX_INT32 iEventType);
+ FX_BOOL SetExecuteRunAt(FX_INT32 iExecuteRunAt);
+ FX_BOOL SetExecuteType(FX_INT32 iExecuteType);
+ FX_BOOL SetExecuteConnection(const CFX_WideString& wsConnection);
+ FX_BOOL SetSignDataOperation(FX_INT32 iOperation);
+ FX_BOOL SetSignDataTarget(const CFX_WideString& wsTarget);
+};
+enum XFA_SCRIPTTYPE {
+ XFA_SCRIPTTYPE_Formcalc = 0,
+ XFA_SCRIPTTYPE_Javascript,
+ XFA_SCRIPTTYPE_Unkown,
+};
+class CXFA_Script : public CXFA_Data
+{
+public:
+ CXFA_Script(CXFA_Node* pNode);
+ void GetBinding(CFX_WideString &wsBinding);
+
+ XFA_SCRIPTTYPE GetContentType();
+ FX_INT32 GetRunAt();
+ void GetExpression(CFX_WideString &wsExpression);
+ FX_BOOL SetBinding(const CFX_WideString& wsBinding);
+ FX_BOOL SetContentType(XFA_SCRIPTTYPE eType);
+ FX_BOOL SetRunAt(FX_INT32 iRunAt);
+ FX_BOOL SetExpression(const CFX_WideString& wsExpression);
+};
+class CXFA_Submit : public CXFA_Data
+{
+public:
+ CXFA_Submit(CXFA_Node* pNode);
+ FX_BOOL IsSubmitEmbedPDF();
+ FX_INT32 GetSubmitFormat();
+ void GetSubmitTarget(CFX_WideStringC &wsTarget);
+ XFA_TEXTENCODING GetSubmitTextEncoding();
+ void GetSubmitXDPContent(CFX_WideStringC &wsContent);
+ FX_BOOL SetSubmitFormat(FX_INT32 iSubmitFormat);
+ FX_BOOL SetSubmitTarget(const CFX_WideString& wsTarget);
+ FX_BOOL SetSubmitTextEncoding(XFA_TEXTENCODING eTextEncoding);
+ FX_BOOL SetSubmitXDPContent(const CFX_WideString& wsContent);
+};
+class CXFA_Value : public CXFA_Data
+{
+public:
+ CXFA_Value(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+
+ XFA_ELEMENT GetChildValueClassID();
+
+ FX_BOOL GetChildValueContent(CFX_WideString &wsContent);
+ CXFA_Arc GetArc();
+ CXFA_Line GetLine();
+ CXFA_Rectangle GetRectangle();
+ CXFA_Text GetText();
+ CXFA_ExData GetExData();
+ CXFA_Image GetImage();
+ FX_BOOL SetChildValueContent(const CFX_WideString& wsContent, FX_BOOL bNotify = FALSE, XFA_ELEMENT iType = XFA_ELEMENT_UNKNOWN);
+};
+class CXFA_Line : public CXFA_Data
+{
+public:
+ CXFA_Line(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ FX_INT32 GetHand();
+ FX_BOOL GetSlop();
+ CXFA_Edge GetEdge();
+ FX_BOOL SetHand(FX_INT32 iHand);
+ FX_BOOL SetSlop(FX_INT32 iSlop);
+};
+class CXFA_Text : public CXFA_Data
+{
+public:
+ CXFA_Text(CXFA_Node* pNode);
+ void GetName(CFX_WideStringC &wsName);
+ FX_INT32 GetMaxChars();
+ void GetRid(CFX_WideStringC &wsRid);
+ void GetContent(CFX_WideString &wsText);
+ void SetContent(CFX_WideString wsText, FX_BOOL bNotify = TRUE);
+ FX_BOOL SetName(const CFX_WideString& wsName);
+ FX_BOOL SetMaxChars(FX_INT32 iMaxChars);
+ FX_BOOL SetRid(const CFX_WideString& wsRid);
+};
+class CXFA_ExData : public CXFA_Data
+{
+public:
+ CXFA_ExData(CXFA_Node* pNode);
+ void GetContentType(CFX_WideStringC &wsContentType);
+ void GetHref(CFX_WideStringC &wsHref);
+ FX_INT32 GetMaxLength();
+ void GetRid(CFX_WideStringC &wsRid);
+ FX_INT32 GetTransferEncoding();
+ void GetContent(CFX_WideString &wsText);
+ FX_BOOL SetContentType(const CFX_WideString& wsContentType);
+ FX_BOOL SetHref(const CFX_WideString& wsHref);
+ FX_BOOL SetMaxLength(FX_INT32 iMaxLength);
+ FX_BOOL SetRid(const CFX_WideString& wsRid);
+ FX_BOOL SetTransferEncoding(FX_INT32 iTransferEncoding);
+ FX_BOOL SetContent(const CFX_WideString& wsText, FX_BOOL bNotify = FALSE, FX_BOOL bScriptModify = FALSE, FX_BOOL bSyncData = TRUE);
+};
+class CXFA_Image : public CXFA_Data
+{
+public:
+ CXFA_Image(CXFA_Node* pNode, FX_BOOL bDefValue);
+ FX_INT32 GetAspect();
+ FX_BOOL GetContentType(CFX_WideString &wsContentType);
+ FX_BOOL GetHref(CFX_WideString &wsHref);
+ FX_INT32 GetTransferEncoding();
+ FX_BOOL GetContent(CFX_WideString &wsText);
+ FX_BOOL SetAspect(FX_INT32 iAspect);
+ FX_BOOL SetContentType(const CFX_WideString& wsContentType);
+ FX_BOOL SetHref(const CFX_WideString& wsHref);
+ FX_BOOL SetTransferEncoding(FX_INT32 iTransferEncoding);
+ FX_BOOL SetContent(const CFX_WideString& wsText);
+protected:
+ FX_BOOL m_bDefValue;
+};
+class CXFA_Calculate : public CXFA_Data
+{
+public:
+ CXFA_Calculate(CXFA_Node* pNode);
+
+ FX_INT32 GetOverride();
+ CXFA_Script GetScript();
+ void GetMessageText(CFX_WideString &wsMessage);
+ FX_BOOL SetOverride(FX_INT32 iOverride);
+ FX_BOOL SetMessageText(const CFX_WideString& wsMessage);
+};
+class CXFA_Validate : public CXFA_Data
+{
+public:
+ CXFA_Validate(CXFA_Node* pNode);
+ FX_INT32 GetFormatTest();
+ FX_BOOL SetFormatTest(CFX_WideString wsValue);
+ FX_INT32 GetNullTest();
+ FX_BOOL SetNullTest(CFX_WideString wsValue);
+ FX_INT32 GetScriptTest();
+ void GetFormatMessageText(CFX_WideString &wsMessage);
+ void SetFormatMessageText(CFX_WideString wsMessage);
+ void GetNullMessageText(CFX_WideString &wsMessage);
+ void SetNullMessageText(CFX_WideString wsMessage);
+ void GetScriptMessageText(CFX_WideString &wsMessage);
+ void SetScriptMessageText(CFX_WideString wsMessage);
+ void GetPicture(CFX_WideString &wsPicture);
+ CXFA_Script GetScript();
+protected:
+ void GetMessageText(CFX_WideString &wsMessage, FX_WSTR wsMessageType);
+ void SetMessageText(CFX_WideString &wsMessage, FX_WSTR wsMessageType);
+ FX_BOOL SetTestValue(FX_INT32 iType, CFX_WideString &wsValue, XFA_ATTRIBUTEENUM eName);
+};
+class CXFA_Variables : public CXFA_Data
+{
+public:
+ CXFA_Variables(CXFA_Node* pNode);
+
+ FX_INT32 CountScripts();
+ CXFA_Script GetScript(FX_INT32 nIndex);
+};
+class CXFA_Bind : public CXFA_Data
+{
+public:
+ CXFA_Bind(CXFA_Node* pNode);
+ FX_INT32 GetMatch();
+ void GetRef(CFX_WideStringC &wsRef);
+ void GetPicture(CFX_WideString &wsPicture);
+ FX_BOOL SetMatch(FX_INT32 iMatch);
+ FX_BOOL SetRef(const CFX_WideString& wsRef);
+ FX_BOOL SetPicture(const CFX_WideString& wsPicture);
+};
+class CXFA_Assist : public CXFA_Data
+{
+public:
+ CXFA_Assist(CXFA_Node* pNode);
+
+ CXFA_ToolTip GetToolTip();
+};
+class CXFA_ToolTip : public CXFA_Data
+{
+public:
+ CXFA_ToolTip(CXFA_Node* pNode);
+ FX_BOOL GetTip(CFX_WideString &wsTip);
+ FX_BOOL SetTip(const CFX_WideString& wsTip);
+};
+class CXFA_BindItems : public CXFA_Data
+{
+public:
+ CXFA_BindItems(CXFA_Node* pNode);
+ void GetConnection(CFX_WideStringC &wsConnection);
+ void GetLabelRef(CFX_WideStringC &wsLabelRef);
+ void GetValueRef(CFX_WideStringC &wsValueRef);
+ void GetRef(CFX_WideStringC &wsRef);
+ FX_BOOL SetConnection(const CFX_WideString& wsConnection);
+ FX_BOOL SetLabelRef(const CFX_WideString& wsLabelRef);
+ FX_BOOL SetValueRef(const CFX_WideString& wsValueRef);
+ FX_BOOL SetRef(const CFX_WideString& wsRef);
+};
+#define XFA_STROKE_SAMESTYLE_NoPresence 1
+#define XFA_STROKE_SAMESTYLE_Corner 2
+class CXFA_Stroke : public CXFA_Data
+{
+public:
+
+ CXFA_Stroke(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+
+ FX_BOOL IsCorner() const
+ {
+ return GetClassID() == XFA_ELEMENT_Corner;
+ }
+
+ FX_BOOL IsEdge() const
+ {
+ return GetClassID() == XFA_ELEMENT_Edge;
+ }
+
+ FX_INT32 GetPresence() const;
+ FX_BOOL IsVisible() const
+ {
+ return GetPresence() == XFA_ATTRIBUTEENUM_Visible;
+ }
+
+ FX_INT32 GetCapType() const;
+
+ FX_INT32 GetStrokeType() const;
+
+ FX_FLOAT GetThickness() const;
+ CXFA_Measurement GetMSThickness() const;
+
+ void SetThickness(FX_FLOAT fThickness);
+ void SetMSThickness(CXFA_Measurement msThinkness);
+
+ FX_ARGB GetColor() const;
+
+ void SetColor(FX_ARGB argb);
+
+ FX_INT32 GetJoinType() const;
+
+ FX_BOOL IsInverted() const;
+
+ FX_FLOAT GetRadius() const;
+
+ FX_BOOL SameStyles(CXFA_Stroke stroke, FX_DWORD dwFlags = 0) const;
+};
+class CXFA_Corner : public CXFA_Stroke
+{
+public:
+ CXFA_Corner(CXFA_Node* pNode) : CXFA_Stroke(pNode) {}
+};
+class CXFA_Edge : public CXFA_Stroke
+{
+public:
+ CXFA_Edge(CXFA_Node* pNode) : CXFA_Stroke(pNode) {}
+};
+typedef CFX_ArrayTemplate<CXFA_Stroke> CXFA_StrokeArray;
+typedef CFX_ArrayTemplate<CXFA_Edge> CXFA_EdgeArray;
+typedef CFX_ArrayTemplate<CXFA_Corner> CXFA_CornerArray;
+class CXFA_Box : public CXFA_Data
+{
+public:
+
+ CXFA_Box(CXFA_Node *pNode) : CXFA_Data(pNode) {}
+
+ FX_BOOL IsArc() const
+ {
+ return GetClassID() == XFA_ELEMENT_Arc;
+ }
+
+ FX_BOOL IsBorder() const
+ {
+ return GetClassID() == XFA_ELEMENT_Border;
+ }
+
+ FX_BOOL IsRectangle() const
+ {
+ return GetClassID() == XFA_ELEMENT_Rectangle;
+ }
+
+ FX_INT32 GetBreak() const;
+
+ FX_INT32 GetHand() const;
+
+ FX_INT32 GetPresence() const;
+
+ FX_INT32 CountCorners() const;
+
+ CXFA_Corner GetCorner(FX_INT32 nIndex) const;
+
+ FX_INT32 CountEdges() const;
+
+ CXFA_Edge GetEdge(FX_INT32 nIndex = 0) const;
+
+ void GetStrokes(CXFA_StrokeArray &strokes) const;
+
+ FX_BOOL IsCircular() const;
+
+ FX_BOOL GetStartAngle(FX_FLOAT &fStartAngle) const;
+ FX_FLOAT GetStartAngle() const
+ {
+ FX_FLOAT fStartAngle;
+ GetStartAngle(fStartAngle);
+ return fStartAngle;
+ }
+
+ FX_BOOL GetSweepAngle(FX_FLOAT &fSweepAngle) const;
+ FX_FLOAT GetSweepAngle() const
+ {
+ FX_FLOAT fSweepAngle;
+ GetSweepAngle(fSweepAngle);
+ return fSweepAngle;
+ }
+
+ CXFA_Fill GetFill(FX_BOOL bModified = FALSE) const;
+
+ CXFA_Margin GetMargin() const;
+
+ FX_BOOL SameStyles() const;
+
+ FX_INT32 Get3DStyle(FX_BOOL &bVisible, FX_FLOAT &fThickness) const;
+};
+class CXFA_Arc : public CXFA_Box
+{
+public:
+ CXFA_Arc(CXFA_Node *pNode) : CXFA_Box(pNode) {}
+};
+class CXFA_Border : public CXFA_Box
+{
+public:
+ CXFA_Border(CXFA_Node *pNode) : CXFA_Box(pNode) {}
+};
+class CXFA_Rectangle : public CXFA_Box
+{
+public:
+ CXFA_Rectangle(CXFA_Node *pNode) : CXFA_Box(pNode) {}
+};
+enum XFA_CHECKSTATE {
+ XFA_CHECKSTATE_On = 0,
+ XFA_CHECKSTATE_Off = 1,
+ XFA_CHECKSTATE_Neutral = 2,
+};
+enum XFA_VALUEPICTURE {
+ XFA_VALUEPICTURE_Raw = 0,
+ XFA_VALUEPICTURE_Display,
+ XFA_VALUEPICTURE_Edit,
+ XFA_VALUEPICTURE_DataBind,
+};
+class CXFA_WidgetData : public CXFA_Data
+{
+public:
+ CXFA_WidgetData(CXFA_Node *pNode);
+ CXFA_Node* GetUIChild();
+
+ XFA_ELEMENT GetUIType();
+ CFX_WideString GetRawValue();
+
+ FX_INT32 GetAccess(FX_BOOL bTemplate = FALSE);
+
+ FX_BOOL GetAccessKey(CFX_WideStringC &wsAccessKey);
+
+ FX_INT32 GetAnchorType();
+
+ FX_INT32 GetColSpan();
+
+ FX_INT32 GetPresence();
+
+ FX_INT32 GetRotate();
+
+ CXFA_Border GetBorder(FX_BOOL bModified = FALSE);
+
+ CXFA_Caption GetCaption(FX_BOOL bModified = FALSE);
+
+ CXFA_Font GetFont(FX_BOOL bModified = FALSE);
+
+ CXFA_Margin GetMargin(FX_BOOL bModified = FALSE);
+
+ CXFA_Para GetPara(FX_BOOL bModified = FALSE);
+
+ CXFA_Keep GetKeep(FX_BOOL bModified = FALSE);
+
+ void GetEventList(CXFA_NodeArray &events);
+ FX_INT32 GetEventByActivity(FX_INT32 iActivity, CXFA_NodeArray &events, FX_BOOL bIsFormReady = FALSE);
+
+ CXFA_Value GetDefaultValue(FX_BOOL bModified = FALSE);
+
+ CXFA_Value GetFormValue(FX_BOOL bModified = FALSE);
+
+ CXFA_Calculate GetCalculate(FX_BOOL bModified = FALSE);
+
+ CXFA_Validate GetValidate(FX_BOOL bModified = FALSE);
+
+ CXFA_Variables GetVariables(FX_BOOL bModified = FALSE);
+
+ CXFA_Bind GetBind(FX_BOOL bModified = FALSE);
+
+ CXFA_Assist GetAssist(FX_BOOL bModified = FALSE);
+
+ void GetRelevant(CFX_WideStringC &wsRelevant);
+ FX_DWORD GetRelevantStatus();
+
+ FX_BOOL GetWidth(FX_FLOAT &fWidth);
+ FX_BOOL GetHeight(FX_FLOAT &fHeight);
+
+ FX_BOOL GetMinWidth(FX_FLOAT &fMinWidth);
+ FX_BOOL GetMinHeight(FX_FLOAT &fMinHeight);
+
+ FX_BOOL GetMaxWidth(FX_FLOAT &fMaxWidth);
+ FX_BOOL GetMaxHeight(FX_FLOAT &fMaxHeight);
+
+ CXFA_BindItems GetBindItems();
+ FX_BOOL SetAccess(FX_INT32 iAccess, FX_BOOL bNotify = TRUE);
+ FX_BOOL SetAccessKey(const CFX_WideString& wsAccessKey);
+ FX_BOOL SetAnchorType(FX_INT32 iType);
+ FX_BOOL SetColSpan(FX_INT32 iColSpan);
+ FX_BOOL SetPresence(FX_INT32 iPresence);
+ FX_BOOL SetRotate(FX_INT32 iRotate);
+ FX_BOOL SetRelevant(const CFX_WideString& wsRelevant);
+ FX_BOOL SetStatus(FX_DWORD dwStatus);
+ FX_BOOL SetWidth(FX_FLOAT fWidth);
+ FX_BOOL SetHeight(FX_FLOAT fHeight);
+ FX_BOOL SetMinWidth(FX_FLOAT fMinWidth);
+ FX_BOOL SetMinHeight(FX_FLOAT fMinHeight);
+ FX_BOOL SetMaxWidth(FX_FLOAT fMaxWidth);
+ FX_BOOL SetMaxHeight(FX_FLOAT fMaxHeight);
+ FX_BOOL SetPos(FX_FLOAT x, FX_FLOAT y);
+ FX_BOOL SetName(const CFX_WideString& wsName);
+ FX_BOOL SetButtonHighlight(FX_INT32 iButtonHighlight);
+ FX_BOOL SetButtonRollover(const CFX_WideString &wsRollover, FX_BOOL bRichText);
+ FX_BOOL SetButtonDown(const CFX_WideString& wsDown, FX_BOOL bRichText);
+ FX_BOOL SetCheckButtonShape(FX_INT32 iCheckButtonShape);
+ FX_BOOL SetCheckButtonMark(FX_INT32 iCheckButtonMark);
+ FX_BOOL SetCheckButtonSize(FX_FLOAT fCheckButtonMark);
+
+ CXFA_Border GetUIBorder(FX_BOOL bModified = FALSE);
+
+ CXFA_Margin GetUIMargin(FX_BOOL bModified = FALSE);
+ void GetUIMargin(CFX_RectF &rtUIMargin);
+
+ FX_INT32 GetButtonHighlight();
+ FX_BOOL GetButtonRollover(CFX_WideString &wsRollover, FX_BOOL &bRichText);
+ FX_BOOL GetButtonDown(CFX_WideString &wsDown, FX_BOOL &bRichText);
+
+
+ FX_INT32 GetCheckButtonShape();
+
+ FX_INT32 GetCheckButtonMark();
+
+ FX_FLOAT GetCheckButtonSize();
+
+ FX_BOOL IsAllowNeutral();
+ FX_BOOL IsRadioButton();
+ XFA_CHECKSTATE GetCheckState();
+ void SetCheckState(XFA_CHECKSTATE eCheckState, FX_BOOL bNotify = TRUE);
+
+ CXFA_Node* GetExclGroupNode();
+
+ CXFA_Node* GetSelectedMember();
+
+ CXFA_Node* SetSelectedMember(FX_WSTR wsName, FX_BOOL bNotify = TRUE);
+
+ void SetSelectedMemberByValue(FX_WSTR wsValue, FX_BOOL bNotify = TRUE, FX_BOOL bScriptModify = FALSE, FX_BOOL bSyncData = TRUE);
+ CXFA_Node* GetExclGroupFirstMember();
+ CXFA_Node* GetExclGroupNextMember(CXFA_Node* pNode);
+
+ FX_INT32 GetChoiceListCommitOn();
+
+ FX_BOOL IsChoiceListAllowTextEntry();
+
+ FX_INT32 GetChoiceListOpen();
+ FX_BOOL IsListBox();
+ FX_INT32 CountChoiceListItems(FX_BOOL bSaveValue = FALSE);
+
+ FX_BOOL GetChoiceListItem(CFX_WideString &wsText, FX_INT32 nIndex, FX_BOOL bSaveValue = FALSE);
+ void GetChoiceListItems(CFX_WideStringArray &wsTextArray, FX_BOOL bSaveValue = FALSE);
+
+ FX_INT32 CountSelectedItems();
+
+ FX_INT32 GetSelectedItem(FX_INT32 nIndex = 0);
+ void GetSelectedItems(CFX_Int32Array &iSelArray);
+ void GetSelectedItemsValue(CFX_WideStringArray &wsSelTextArray);
+
+ FX_BOOL GetItemState(FX_INT32 nIndex);
+
+ void SetItemState(FX_INT32 nIndex, FX_BOOL bSelected, FX_BOOL bNotify = FALSE, FX_BOOL bScriptModify = FALSE, FX_BOOL bSyncData = TRUE);
+ void SetSelectdItems(CFX_Int32Array &iSelArray, FX_BOOL bNotify = FALSE, FX_BOOL bScriptModify = FALSE, FX_BOOL bSyncData = TRUE);
+ void ClearAllSelections();
+ void InsertItem(const CFX_WideString &wsLabel, const CFX_WideString &wsValue, FX_INT32 nIndex = -1, FX_BOOL bNotify = FALSE);
+ void GetItemLabel(FX_WSTR wsValue, CFX_WideString &wsLabel);
+ void GetItemValue(FX_WSTR wsLabel, CFX_WideString &wsValue);
+ FX_BOOL DeleteItem(FX_INT32 nIndex, FX_BOOL bNotify = FALSE, FX_BOOL bScriptModify = FALSE, FX_BOOL bSyncData = TRUE);
+
+ FX_INT32 GetHorizontalScrollPolicy();
+
+ FX_INT32 GetNumberOfCells();
+
+ FX_BOOL IsDateTimeEditUsePicker();
+
+ FX_BOOL SetValue(const CFX_WideString& wsValue, XFA_VALUEPICTURE eValueType);
+ FX_BOOL GetPictureContent(CFX_WideString &wsPicture, XFA_VALUEPICTURE ePicture);
+ IFX_Locale* GetLocal();
+ FX_BOOL GetValue(CFX_WideString &wsValue, XFA_VALUEPICTURE eValueType);
+ FX_BOOL GetNormalizeDataValue(FX_WSTR wsValue, CFX_WideString &wsNormalizeValue);
+ FX_BOOL GetFormatDataValue(FX_WSTR wsValue, CFX_WideString &wsFormatedValue);
+ void NormalizeNumStr(const CFX_WideString& wsValue, CFX_WideString& wsOutput);
+
+ CFX_WideString GetBarcodeType();
+ FX_BOOL GetBarcodeAttribute_CharEncoding(FX_INT32& val);
+ FX_BOOL GetBarcodeAttribute_Checksum(FX_INT32& val);
+ FX_BOOL GetBarcodeAttribute_DataLength(FX_INT32& val);
+ FX_BOOL GetBarcodeAttribute_StartChar(FX_CHAR& val);
+ FX_BOOL GetBarcodeAttribute_EndChar(FX_CHAR& val);
+ FX_BOOL GetBarcodeAttribute_ECLevel(FX_INT32& val);
+ FX_BOOL GetBarcodeAttribute_ModuleWidth(FX_INT32& val);
+ FX_BOOL GetBarcodeAttribute_ModuleHeight(FX_INT32& val);
+ FX_BOOL GetBarcodeAttribute_PrintChecksum(FX_BOOL& val);
+ FX_BOOL GetBarcodeAttribute_TextLocation(FX_INT32& val);
+ FX_BOOL GetBarcodeAttribute_Truncate(FX_BOOL& val);
+ FX_BOOL GetBarcodeAttribute_WideNarrowRatio(FX_FLOAT& val);
+
+ void GetPasswordChar(CFX_WideString &wsPassWord);
+
+ FX_BOOL IsAllowRichText();
+
+ FX_BOOL IsMultiLine();
+
+ FX_INT32 GetVerticalScrollPolicy();
+
+ FX_INT32 GetMaxChars(XFA_ELEMENT& eType);
+
+ FX_BOOL GetFracDigits(FX_INT32 &iFracDigits);
+
+ FX_BOOL GetLeadDigits(FX_INT32 &iLeadDigits);
+
+ CXFA_Filter GetFilter(FX_BOOL bModified = FALSE);
+ CXFA_Manifest GetManifest(FX_BOOL bModified = FALSE);
+ FX_BOOL m_bIsNull;
+ FX_BOOL m_bPreNull;
+protected:
+ void SyncValue(const CFX_WideString& wsValue, FX_BOOL bNotify);
+ void InsertListTextItem(CXFA_Node* pItems, FX_WSTR wsText, FX_INT32 nIndex = -1);
+ void FormatNumStr(const CFX_WideString& wsValue, IFX_Locale* pLocale, CFX_WideString& wsOutput);
+ CXFA_Node* m_pUiChildNode;
+ XFA_ELEMENT m_eUIType;
+};
+class CXFA_Occur : public CXFA_Data
+{
+public:
+ CXFA_Occur(CXFA_Node* pNode);
+ FX_INT32 GetMax();
+ FX_INT32 GetMin();
+ FX_INT32 GetInitial();
+ FX_BOOL GetOccurInfo(FX_INT32& iMin, FX_INT32& iMax, FX_INT32& iInit);
+ void SetMax(FX_INT32 iMax);
+ void SetMin(FX_INT32 iMin);
+};
+class CXFA_Filter : public CXFA_Data
+{
+public:
+ CXFA_Filter(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ CFX_WideString GetFilterString(XFA_ATTRIBUTE eAttribute);
+ XFA_ATTRIBUTEENUM GetAppearanceFilterType();
+ CFX_WideString GetAppearanceFilterContent();
+ XFA_ATTRIBUTEENUM GetCertificatesCredentialServerPolicy();
+ CFX_WideString GetCertificatesURL();
+ CFX_WideString GetCertificatesURLPolicy();
+ CXFA_WrapCertificate GetCertificatesEncryption(FX_BOOL bModified = FALSE);
+ CXFA_WrapCertificate GetCertificatesIssuers(FX_BOOL bModified = FALSE);
+ CFX_WideString GetCertificatesKeyUsageString(XFA_ATTRIBUTE eAttribute);
+ CXFA_Oids GetCertificatesOids();
+ CXFA_WrapCertificate GetCertificatesSigning(FX_BOOL bModified = FALSE);
+ CXFA_DigestMethods GetDigestMethods(FX_BOOL bModified = FALSE);
+ CXFA_Encodings GetEncodings(FX_BOOL bModified = FALSE);
+ CXFA_EncryptionMethods GetEncryptionMethods(FX_BOOL bModified = FALSE);
+ XFA_ATTRIBUTEENUM GetHandlerType();
+ CFX_WideString GetHandlerContent();
+ XFA_ATTRIBUTEENUM GetlockDocumentType();
+ CFX_WideString GetlockDocumentContent();
+ FX_INT32 GetMDPPermissions();
+ XFA_ATTRIBUTEENUM GetMDPSignatureType();
+
+ CXFA_Reasons GetReasons(FX_BOOL bModified = FALSE);
+ CFX_WideString GetTimeStampServer();
+ XFA_ATTRIBUTEENUM GetTimeStampType();
+};
+class CXFA_Certificate : public CXFA_Data
+{
+public:
+ CXFA_Certificate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ CFX_WideString GetCertificateName();
+ CFX_WideString GetCertificateContent();
+};
+class CXFA_WrapCertificate : public CXFA_Data
+{
+public:
+ CXFA_WrapCertificate(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetType();
+ FX_INT32 CountCertificates();
+ CXFA_Certificate GetCertificate(FX_INT32 nIndex);
+};
+class CXFA_Oids : public CXFA_Data
+{
+public:
+ CXFA_Oids(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetOidsType();
+ FX_INT32 CountOids();
+ CFX_WideString GetOidContent(FX_INT32 nIndex);
+};
+class CXFA_SubjectDNs : public CXFA_Data
+{
+public:
+ CXFA_SubjectDNs(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetSubjectDNsType();
+ FX_INT32 CountSubjectDNs();
+ CFX_WideString GetSubjectDNString(FX_INT32 nIndex, XFA_ATTRIBUTE eAttribute);
+ CFX_WideString GetSubjectDNContent(FX_INT32 nIndex);
+};
+class CXFA_DigestMethods : public CXFA_Data
+{
+public:
+ CXFA_DigestMethods(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetDigestMethodsType();
+ FX_INT32 CountDigestMethods();
+ CFX_WideString GetDigestMethodContent(FX_INT32 nIndex);
+};
+class CXFA_Encodings : public CXFA_Data
+{
+public:
+ CXFA_Encodings(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetEncodingsType();
+ FX_INT32 CountEncodings();
+ CFX_WideString GetEncodingContent(FX_INT32 nIndex);
+};
+class CXFA_EncryptionMethods : public CXFA_Data
+{
+public:
+ CXFA_EncryptionMethods(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetEncryptionMethodsType();
+ FX_INT32 CountEncryptionMethods();
+ CFX_WideString GetEncryptionMethodContent(FX_INT32 nIndex);
+};
+class CXFA_Reasons : public CXFA_Data
+{
+public:
+ CXFA_Reasons(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetReasonsType();
+ FX_INT32 CountReasons();
+ CFX_WideString GetReasonContent(FX_INT32 nIndex);
+};
+class CXFA_Manifest : public CXFA_Data
+{
+public:
+ CXFA_Manifest(CXFA_Node* pNode) : CXFA_Data(pNode) {}
+ XFA_ATTRIBUTEENUM GetAction();
+ FX_INT32 CountReives();
+ CFX_WideString GetRefContent(FX_INT32 nIndex);
+};
+#endif
diff --git a/xfa/include/fxfa/fxfa_widget.h b/xfa/include/fxfa/fxfa_widget.h
new file mode 100644
index 0000000000..4488502bf7
--- /dev/null
+++ b/xfa/include/fxfa/fxfa_widget.h
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_WIDGET_H
+#define _FXFA_WIDGET_H
+class CXFA_Node;
+class CXFA_FFDocView;
+class CXFA_FFDoc;
+class CXFA_FFApp;
+class CXFA_Node;
+class CXFA_EventParam;
+class CXFA_FFWidget;
+class CXFA_TextLayout;
+class CXFA_TextProvider;
+class CXFA_WidgetLayoutData;
+class IFX_Font;
+class CXFA_WidgetAcc;
+#include "fxfa_objectacc.h"
+class CXFA_WidgetAcc : public CXFA_WidgetData
+{
+public:
+ CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode);
+ ~CXFA_WidgetAcc();
+
+ FX_BOOL GetName(CFX_WideString &wsName, FX_INT32 iNameType = 0);
+ FX_BOOL ProcessValueChanged();
+
+public:
+
+ void ResetData();
+
+
+ void SetImageEdit(FX_WSTR wsContentType, FX_WSTR wsHref, FX_WSTR wsData);
+
+ CXFA_WidgetAcc* GetExclGroup();
+ CXFA_FFDocView* GetDocView();
+ CXFA_FFDoc* GetDoc();
+ CXFA_FFApp* GetApp();
+ IXFA_AppProvider* GetAppProvider();
+
+ FX_INT32 ProcessEvent(FX_INT32 iActivity, CXFA_EventParam* pEventParam);
+ FX_INT32 ProcessEvent(CXFA_Event& event, CXFA_EventParam* pEventParam);
+ FX_INT32 ProcessCalculate();
+ FX_INT32 ProcessValidate(FX_INT32 iFlags = 0);
+ FX_INT32 ExecuteScript(CXFA_Script script, CXFA_EventParam* pEventParam, FXJSE_HVALUE* pRetValue = NULL);
+
+ CXFA_FFWidget* GetNextWidget(CXFA_FFWidget* pWidget);
+ void StartWidgetLayout(FX_FLOAT &fCalcWidth, FX_FLOAT& fCalcHeight);
+ FX_BOOL FindSplitPos(FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeight);
+ FX_BOOL LoadCaption();
+ FX_BOOL LoadText();
+ FX_BOOL LoadImageImage();
+ FX_BOOL LoadImageEditImage();
+ void GetImageDpi(FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi);
+ void GetImageEditDpi(FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi);
+ CXFA_TextLayout* GetCaptionTextLayout();
+ CXFA_TextLayout* GetTextLayout();
+ CFX_DIBitmap* GetImageImage();
+ CFX_DIBitmap* GetImageEditImage();
+ void SetImageImage(CFX_DIBitmap* newImage);
+ void SetImageEditImage(CFX_DIBitmap* newImage);
+ void UpdateUIDisplay(CXFA_FFWidget* pExcept = NULL);
+ void NotifyEvent(FX_DWORD dwEvent, CXFA_FFWidget* pWidget = NULL, FX_LPVOID pParam = NULL, FX_LPVOID pAdditional = NULL);
+
+
+ CXFA_Node* GetDatasets();
+ IFX_Font* GetFDEFont();
+ FX_FLOAT GetFontSize();
+ FX_ARGB GetTextColor();
+ FX_FLOAT GetLineHeight();
+ CXFA_WidgetLayoutData* GetWidgetLayoutData();
+protected:
+ void ProcessScriptTestValidate(CXFA_Validate validate, FX_INT32 iRet, FXJSE_HVALUE pRetValue, FX_BOOL bVersionFlag);
+ FX_INT32 ProcessFormatTestValidate(CXFA_Validate validate, FX_BOOL bVersionFlag);
+ FX_INT32 ProcessNullTestValidate(CXFA_Validate validate, FX_INT32 iFlags, FX_BOOL bVersionFlag);
+ void GetValidateCaptionName(CFX_WideString& wsCaptionName, FX_BOOL bVersionFlag);
+ void GetValidateMessage(IXFA_AppProvider* pAppProvider, CFX_WideString& wsMessage, FX_BOOL bError, FX_BOOL bVersionFlag);
+ void CalcCaptionSize(CFX_SizeF &szCap);
+ FX_BOOL CalculateFieldAutoSize(CFX_SizeF &size);
+ FX_BOOL CalculateWidgetAutoSize(CFX_SizeF &size);
+ FX_BOOL CalculateTextEditAutoSize(CFX_SizeF &size);
+ FX_BOOL CalculateCheckButtonAutoSize(CFX_SizeF &size);
+ FX_BOOL CalculatePushButtonAutoSize(CFX_SizeF &size);
+ FX_BOOL CalculateImageEditAutoSize(CFX_SizeF &size);
+ FX_BOOL CalculateImageAutoSize(CFX_SizeF &size);
+ FX_BOOL CalculateTextAutoSize(CFX_SizeF &size);
+ FX_FLOAT CalculateWidgetAutoHeight(FX_FLOAT fHeightCalc);
+ FX_FLOAT CalculateWidgetAutoWidth(FX_FLOAT fWidthCalc);
+ FX_FLOAT GetWidthWithoutMargin(FX_FLOAT fWidthCalc);
+ FX_FLOAT GetHeightWithoutMargin(FX_FLOAT fHeightCalc);
+ void CalculateTextContentSize(CFX_SizeF &size);
+ void CalculateAccWidthAndHeight(XFA_ELEMENT eUIType, FX_FLOAT& fWidth, FX_FLOAT& fCalcHeight);
+ void InitLayoutData();
+ void StartTextLayout(FX_FLOAT& fCalcWidth, FX_FLOAT& fCalcHeight);
+ CXFA_FFDocView* m_pDocView;
+ CXFA_WidgetLayoutData* m_pLayoutData;
+};
+#endif
diff --git a/xfa/include/fxgraphics/fx_graphics.h b/xfa/include/fxgraphics/fx_graphics.h
new file mode 100644
index 0000000000..ddec9605b7
--- /dev/null
+++ b/xfa/include/fxgraphics/fx_graphics.h
@@ -0,0 +1,511 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef __H_FX_GRAPHICS__
+#define __H_FX_GRAPHICS__
+#define FX_ERR_Succeeded 0
+#define FX_ERR_Indefinite -1
+#define FX_ERR_Parameter_Invalid -100
+#define FX_ERR_Property_Invalid -200
+#define FX_ERR_Intermediate_Value_Invalid -300
+#define FX_ERR_Method_Not_Supported -400
+#define FX_ERR_Out_Of_Memory -500
+#define _FX_RETURN_IF_FAIL(arg) {if (!(arg)) return;}
+#define _FX_RETURN_VALUE_IF_FAIL(arg, val) {if (!(arg)) return val;}
+#define _FX_GOTO_POSITION_IF_FAIL(arg, pos) {if (!(arg)) goto pos;}
+#define _FX_ERR_CHECK_RETURN_IF_FAIL(arg) {if ((arg) != FX_ERR_Succeeded) return;}
+#define _FX_ERR_CHECK_RETURN_VALUE_IF_FAIL(arg, val) {if ((arg) != FX_ERR_Succeeded) return val;}
+#define _FX_ERR_CHECK_GOTO_POSITION_IF_FAIL(arg, pos) {if ((arg) != FX_ERR_Succeeded) goto pos;}
+#define FX_SHADING_Steps 256
+typedef FX_INT32 FX_DashStyle;
+enum {
+ FX_DASHSTYLE_Solid = 0,
+ FX_DASHSTYLE_Dash = 1,
+ FX_DASHSTYLE_Dot = 2,
+ FX_DASHSTYLE_DashDot = 3,
+ FX_DASHSTYLE_DashDotDot = 4
+};
+typedef FX_INT32 FX_StrokeAlignment;
+enum {
+ FX_STROKEALIGNMENT_Center = 0,
+ FX_STROKEALIGNMENT_Inset = 1,
+ FX_STROKEALIGNMENT_Outset = 2,
+ FX_STROKEALIGNMENT_Left = 3,
+ FX_STROKEALIGNMENT_Right = 4
+};
+typedef FX_INT32 FX_HatchStyle;
+enum {
+ FX_HATCHSTYLE_Horizontal = 0,
+ FX_HATCHSTYLE_Vertical = 1,
+ FX_HATCHSTYLE_ForwardDiagonal = 2,
+ FX_HATCHSTYLE_BackwardDiagonal = 3,
+ FX_HATCHSTYLE_Cross = 4,
+ FX_HATCHSTYLE_DiagonalCross = 5,
+ FX_HATCHSTYLE_05Percent = 6,
+ FX_HATCHSTYLE_10Percent = 7,
+ FX_HATCHSTYLE_20Percent = 8,
+ FX_HATCHSTYLE_25Percent = 9,
+ FX_HATCHSTYLE_30Percent = 10,
+ FX_HATCHSTYLE_40Percent = 11,
+ FX_HATCHSTYLE_50Percent = 12,
+ FX_HATCHSTYLE_60Percent = 13,
+ FX_HATCHSTYLE_70Percent = 14,
+ FX_HATCHSTYLE_75Percent = 15,
+ FX_HATCHSTYLE_80Percent = 16,
+ FX_HATCHSTYLE_90Percent = 17,
+ FX_HATCHSTYLE_LightDownwardDiagonal = 18,
+ FX_HATCHSTYLE_LightUpwardDiagonal = 19,
+ FX_HATCHSTYLE_DarkDownwardDiagonal = 20,
+ FX_HATCHSTYLE_DarkUpwardDiagonal = 21,
+ FX_HATCHSTYLE_WideDownwardDiagonal = 22,
+ FX_HATCHSTYLE_WideUpwardDiagonal = 23,
+ FX_HATCHSTYLE_LightVertical = 24,
+ FX_HATCHSTYLE_LightHorizontal = 25,
+ FX_HATCHSTYLE_NarrowVertical = 26,
+ FX_HATCHSTYLE_NarrowHorizontal = 27,
+ FX_HATCHSTYLE_DarkVertical = 28,
+ FX_HATCHSTYLE_DarkHorizontal = 29,
+ FX_HATCHSTYLE_DashedDownwardDiagonal = 30,
+ FX_HATCHSTYLE_DashedUpwardDiagonal = 31,
+ FX_HATCHSTYLE_DashedHorizontal = 32,
+ FX_HATCHSTYLE_DashedVertical = 33,
+ FX_HATCHSTYLE_SmallConfetti = 34,
+ FX_HATCHSTYLE_LargeConfetti = 35,
+ FX_HATCHSTYLE_ZigZag = 36,
+ FX_HATCHSTYLE_Wave = 37,
+ FX_HATCHSTYLE_DiagonalBrick = 38,
+ FX_HATCHSTYLE_HorizontalBrick = 39,
+ FX_HATCHSTYLE_Weave = 40,
+ FX_HATCHSTYLE_Plaid = 41,
+ FX_HATCHSTYLE_Divot = 42,
+ FX_HATCHSTYLE_DottedGrid = 43,
+ FX_HATCHSTYLE_DottedDiamond = 44,
+ FX_HATCHSTYLE_Shingle = 45,
+ FX_HATCHSTYLE_Trellis = 46,
+ FX_HATCHSTYLE_Sphere = 47,
+ FX_HATCHSTYLE_SmallGrid = 48,
+ FX_HATCHSTYLE_SmallCheckerBoard = 49,
+ FX_HATCHSTYLE_LargeCheckerBoard = 50,
+ FX_HATCHSTYLE_OutlinedDiamond = 51,
+ FX_HATCHSTYLE_SolidDiamond = 52
+};
+typedef FX_INT32 FX_DeviceCap;
+typedef FX_INT32 FX_FillMode;
+class CFX_Object;
+class CFX_RenderDevice;
+class CFX_GraphStateData;
+class CFX_Matrix;
+class CFX_DIBSource;
+class CFX_DIBitmap;
+class CFX_Font;
+class CFX_WideString;
+class IFX_FileRead;
+class CFX_PathGenerator;
+class CAGG_Graphics;
+class CFX_Graphics;
+class CFX_Color;
+class CFX_Path;
+class CFX_Pattern;
+class CFX_Shading;
+class CFX_Graphics : public CFX_Object
+{
+public:
+
+
+ CFX_Graphics();
+
+ FX_ERR Create(CFX_RenderDevice * renderDevice, FX_BOOL isAntialiasing = TRUE);
+
+ FX_ERR Create(FX_INT32 width,
+ FX_INT32 height,
+ FXDIB_Format format,
+ FX_BOOL isNative = TRUE,
+ FX_BOOL isAntialiasing = TRUE);
+
+
+ virtual ~CFX_Graphics();
+
+
+
+ FX_ERR GetDeviceCap(const FX_INT32 capID, FX_DeviceCap & capVal);
+ FX_ERR IsPrinterDevice(FX_BOOL & isPrinter);
+ FX_ERR EnableAntialiasing(FX_BOOL isAntialiasing);
+
+
+
+ FX_ERR SaveGraphState();
+
+ FX_ERR RestoreGraphState();
+
+
+
+ FX_ERR GetLineCap(CFX_GraphStateData::LineCap & lineCap);
+
+ FX_ERR SetLineCap(CFX_GraphStateData::LineCap lineCap);
+
+ FX_ERR GetDashCount(FX_INT32 & dashCount);
+
+ FX_ERR GetLineDash(FX_FLOAT & dashPhase, FX_FLOAT * dashArray);
+
+ FX_ERR SetLineDash(FX_FLOAT dashPhase, FX_FLOAT * dashArray, FX_INT32 dashCount);
+
+ FX_ERR SetLineDash(FX_DashStyle dashStyle);
+
+ FX_ERR GetLineJoin(CFX_GraphStateData::LineJoin & lineJoin);
+
+ FX_ERR SetLineJoin(CFX_GraphStateData::LineJoin lineJoin);
+
+ FX_ERR GetMiterLimit(FX_FLOAT & miterLimit);
+
+ FX_ERR SetMiterLimit(FX_FLOAT miterLimit);
+
+ FX_ERR GetLineWidth(FX_FLOAT & lineWidth);
+
+ FX_ERR SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash = FALSE);
+
+ FX_ERR GetStrokeAlignment(FX_StrokeAlignment & strokeAlignment);
+
+ FX_ERR SetStrokeAlignment(FX_StrokeAlignment strokeAlignment);
+
+
+
+ FX_ERR SetStrokeColor(CFX_Color * color);
+
+ FX_ERR SetFillColor(CFX_Color * color);
+
+
+
+ FX_ERR StrokePath(CFX_Path * path, CFX_Matrix * matrix = NULL);
+
+ FX_ERR FillPath(CFX_Path * path,
+ FX_FillMode fillMode = FXFILL_WINDING,
+ CFX_Matrix * matrix = NULL);
+
+ FX_ERR ClipPath(CFX_Path * path,
+ FX_FillMode fillMode = FXFILL_WINDING,
+ CFX_Matrix * matrix = NULL);
+
+
+
+ FX_ERR DrawImage(CFX_DIBSource * source,
+ const CFX_PointF & point,
+ CFX_Matrix * matrix = NULL);
+
+ FX_ERR StretchImage(CFX_DIBSource * source,
+ const CFX_RectF & rect,
+ CFX_Matrix * matrix = NULL);
+
+
+
+ FX_ERR ConcatMatrix(CFX_Matrix * matrix);
+
+ CFX_Matrix * GetMatrix();
+
+
+
+ FX_ERR GetClipRect(CFX_RectF & rect);
+
+ FX_ERR SetClipRect(const CFX_RectF & rect);
+
+ FX_ERR ClearClip();
+
+
+
+ FX_ERR SetFont(CFX_Font * font);
+
+ FX_ERR SetFontSize(const FX_FLOAT size);
+
+ FX_ERR SetFontHScale(const FX_FLOAT scale);
+
+ FX_ERR SetCharSpacing(const FX_FLOAT spacing);
+
+ FX_ERR SetTextDrawingMode(const FX_INT32 mode);
+
+
+ FX_ERR ShowText(const CFX_PointF & point,
+ const CFX_WideString & text,
+ CFX_Matrix * matrix = NULL);
+
+
+ FX_ERR CalcTextRect(CFX_RectF & rect,
+ const CFX_WideString & text,
+ FX_BOOL isMultiline = FALSE,
+ CFX_Matrix * matrix = NULL);
+
+
+
+ FX_ERR Transfer(CFX_Graphics * graphics, CFX_Matrix * matrix = NULL);
+
+
+ FX_ERR Transfer(CFX_Graphics * graphics,
+ FX_FLOAT srcLeft,
+ FX_FLOAT srcTop,
+ const CFX_RectF & dstRect,
+ CFX_Matrix * matrix = NULL);
+
+
+
+
+ CFX_RenderDevice * GetRenderDevice();
+
+ FX_ERR InverseRect(const CFX_RectF & rect);
+ FX_ERR XorDIBitmap(const CFX_DIBitmap * srcBitmap, const CFX_RectF & rect);
+ FX_ERR EqvDIBitmap(const CFX_DIBitmap * srcBitmap, const CFX_RectF & rect);
+private:
+
+ FX_ERR RenderDeviceSetLineDash(FX_DashStyle dashStyle);
+
+ FX_ERR RenderDeviceStrokePath(CFX_Path * path, CFX_Matrix * matrix);
+
+ FX_ERR RenderDeviceFillPath(CFX_Path * path,
+ FX_FillMode fillMode,
+ CFX_Matrix * matrix);
+
+
+ FX_ERR RenderDeviceDrawImage(CFX_DIBSource * source,
+ const CFX_PointF & point,
+ CFX_Matrix * matrix);
+
+ FX_ERR RenderDeviceStretchImage(CFX_DIBSource * source,
+ const CFX_RectF & rect,
+ CFX_Matrix * matrix);
+
+ FX_ERR RenderDeviceShowText(const CFX_PointF & point,
+ const CFX_WideString & text,
+ CFX_Matrix * matrix);
+
+ FX_ERR StrokePathWithPattern(CFX_Path * path, CFX_Matrix * matrix);
+
+ FX_ERR StrokePathWithShading(CFX_Path * path, CFX_Matrix * matrix);
+
+ FX_ERR FillPathWithPattern(CFX_Path * path,
+ FX_FillMode fillMode,
+ CFX_Matrix * matrix);
+
+ FX_ERR FillPathWithShading(CFX_Path * path,
+ FX_FillMode fillMode,
+ CFX_Matrix * matrix);
+ FX_ERR SetDIBitsWithMatrix(CFX_DIBSource * source, CFX_Matrix * matrix);
+ FX_ERR CalcTextInfo(const CFX_WideString & text, FX_DWORD * charCodes, FXTEXT_CHARPOS * charPos, CFX_RectF & rect);
+
+
+protected:
+ FX_INT32 _type;
+private:
+ struct TInfo : public CFX_Object {
+ CFX_GraphStateData _graphState;
+ FX_BOOL _isAntialiasing;
+ FX_StrokeAlignment _strokeAlignment;
+ CFX_Matrix _CTM;
+ FX_BOOL _isActOnDash;
+ CFX_Color * _strokeColor;
+ CFX_Color * _fillColor;
+ CFX_Font * _font;
+ FX_FLOAT _fontSize;
+ FX_FLOAT _fontHScale;
+ FX_FLOAT _fontSpacing;
+ } _info;
+ CFX_RenderDevice * _renderDevice;
+ CFX_PtrArray _infoStack;
+ CAGG_Graphics * _aggGraphics;
+ friend class CAGG_Graphics;
+
+};
+class CFX_Path : public CFX_Object
+{
+public:
+
+
+ CFX_Path();
+
+ FX_ERR Create();
+
+ virtual ~CFX_Path();
+
+
+ FX_ERR MoveTo(FX_FLOAT x, FX_FLOAT y);
+
+ FX_ERR LineTo(FX_FLOAT x, FX_FLOAT y);
+
+ FX_ERR BezierTo(FX_FLOAT ctrlX1,
+ FX_FLOAT ctrlY1,
+ FX_FLOAT ctrlX2,
+ FX_FLOAT ctrlY2,
+ FX_FLOAT toX,
+ FX_FLOAT toY);
+
+ FX_ERR ArcTo(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle);
+
+ FX_ERR Close();
+
+
+ FX_ERR AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
+
+ FX_ERR AddBezier(FX_FLOAT startX,
+ FX_FLOAT startY,
+ FX_FLOAT ctrlX1,
+ FX_FLOAT ctrlY1,
+ FX_FLOAT ctrlX2,
+ FX_FLOAT ctrlY2,
+ FX_FLOAT endX,
+ FX_FLOAT endY);
+
+ FX_ERR AddRectangle(FX_FLOAT left, FX_FLOAT top, FX_FLOAT width, FX_FLOAT height);
+
+ FX_ERR AddEllipse(FX_FLOAT left, FX_FLOAT top, FX_FLOAT width, FX_FLOAT height);
+
+ FX_ERR AddEllipse(const CFX_RectF & rect);
+
+ FX_ERR AddArc(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle);
+
+ FX_ERR AddPie(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle);
+
+ FX_ERR AddSubpath(CFX_Path * path);
+
+ FX_ERR Clear();
+
+ FX_BOOL IsEmpty();
+
+ CFX_PathData * GetPathData();
+private:
+ CFX_PathGenerator * _generator;
+};
+class CFX_Color : public CFX_Object
+{
+public:
+
+ CFX_Color();
+
+ CFX_Color(const FX_ARGB argb);
+
+
+ CFX_Color(CFX_Pattern * pattern, const FX_ARGB argb = 0x0);
+
+
+ CFX_Color(CFX_Shading * shading);
+
+
+ virtual ~CFX_Color();
+
+
+ FX_ERR Set(const FX_ARGB argb);
+
+
+ FX_ERR Set(CFX_Pattern * pattern, const FX_ARGB argb = 0x0);
+
+
+ FX_ERR Set(CFX_Shading * shading);
+
+private:
+ FX_INT32 _type;
+ union {
+ struct {
+ FX_ARGB _argb;
+ CFX_Pattern * _pattern;
+ };
+ CFX_Shading * _shading;
+ };
+
+ friend class CFX_Graphics;
+};
+class CFX_Pattern : public CFX_Object
+{
+public:
+
+
+ CFX_Pattern();
+
+ FX_ERR Create(CFX_DIBitmap * bitmap,
+ const FX_FLOAT xStep,
+ const FX_FLOAT yStep,
+ CFX_Matrix * matrix = NULL);
+
+ FX_ERR Create(FX_HatchStyle hatchStyle,
+ const FX_ARGB foreArgb,
+ const FX_ARGB backArgb,
+ CFX_Matrix * matrix = NULL);
+
+ virtual ~CFX_Pattern();
+
+private:
+ FX_INT32 _type;
+ CFX_Matrix _matrix;
+ union {
+ struct {
+ CFX_RectF _rect;
+ FX_FLOAT _xStep;
+ FX_FLOAT _yStep;
+ FX_BOOL _isColored;
+ };
+ struct {
+ CFX_DIBitmap * _bitmap;
+ FX_FLOAT _x1Step;
+ FX_FLOAT _y1Step;
+ };
+ struct {
+ FX_HatchStyle _hatchStyle;
+ FX_ARGB _foreArgb;
+ FX_ARGB _backArgb;
+ };
+ };
+ friend class CFX_Graphics;
+};
+class CFX_Shading : public CFX_Object
+{
+public:
+
+
+ CFX_Shading();
+
+ FX_ERR CreateAxial(const CFX_PointF & beginPoint,
+ const CFX_PointF & endPoint,
+ FX_BOOL isExtendedBegin,
+ FX_BOOL isExtendedEnd,
+ const FX_ARGB beginArgb,
+ const FX_ARGB endArgb);
+
+ FX_ERR CreateRadial(const CFX_PointF & beginPoint,
+ const CFX_PointF & endPoint,
+ const FX_FLOAT beginRadius,
+ const FX_FLOAT endRadius,
+ FX_BOOL isExtendedBegin,
+ FX_BOOL isExtendedEnd,
+ const FX_ARGB beginArgb,
+ const FX_ARGB endArgb);
+
+ virtual ~CFX_Shading();
+
+private:
+ FX_ERR InitArgbArray();
+private:
+ FX_INT32 _type;
+ CFX_PointF _beginPoint;
+ CFX_PointF _endPoint;
+ FX_FLOAT _beginRadius;
+ FX_FLOAT _endRadius;
+ FX_BOOL _isExtendedBegin;
+ FX_BOOL _isExtendedEnd;
+ FX_ARGB _beginArgb;
+ FX_ARGB _endArgb;
+ FX_ARGB _argbArray[FX_SHADING_Steps];
+ friend class CFX_Graphics;
+};
+#endif
diff --git a/xfa/include/fxjse/fxjse.h b/xfa/include/fxjse/fxjse.h
new file mode 100644
index 0000000000..0bd44347a4
--- /dev/null
+++ b/xfa/include/fxjse/fxjse.h
@@ -0,0 +1,125 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXJSE_H_
+#define _FXJSE_H_
+#ifdef __cplusplus
+#define FXJSE_DEFINEINHERITHANDLE(name, subtypename) typedef struct _##subtypename : public _##name {} * subtypename;
+#else
+#define FXJSE_DEFINEINHERITHANDLE(name, subtypename) typedef name subtypename;
+#endif
+FX_DEFINEHANDLE(FXJSE_HRUNTIME);
+FX_DEFINEHANDLE(FXJSE_HCONTEXT);
+FX_DEFINEHANDLE(FXJSE_HCLASS);
+FX_DEFINEHANDLE(FXJSE_HVALUE);
+FXJSE_DEFINEINHERITHANDLE(FXJSE_HVALUE, FXJSE_HOBJECT);
+typedef double FXJSE_DOUBLE;
+void FXJSE_Initialize();
+void FXJSE_Finalize();
+FXJSE_HRUNTIME FXJSE_Runtime_Create();
+void FXJSE_Runtime_Release(FXJSE_HRUNTIME hRuntime);
+typedef struct _FXJSE_CLASS FXJSE_CLASS;
+FXJSE_HCONTEXT FXJSE_Context_Create (FXJSE_HRUNTIME hRuntime, const FXJSE_CLASS* lpGlobalClass = NULL, FX_LPVOID lpGlobalObject = NULL);
+void FXJSE_Context_Release (FXJSE_HCONTEXT hContext);
+FXJSE_HVALUE FXJSE_Context_GetGlobalObject(FXJSE_HCONTEXT hContext);
+FXJSE_HRUNTIME FXJSE_Context_GetRuntime(FXJSE_HCONTEXT hContext);
+enum FXJSE_CompatibleModeFlags {
+ FXJSE_COMPATIBLEMODEFLAG_CONSTRUCTOREXTRAMETHODS = (1 << 0),
+ FXJSE_COMPATIBLEMODEFLAGCOUNT = 1,
+};
+void FXJSE_Context_EnableCompatibleMode(FXJSE_HCONTEXT hContext, FX_DWORD dwCompatibleFlags);
+class CFXJSE_Arguments
+{
+public:
+ FXJSE_HRUNTIME GetRuntime() const;
+ FX_INT32 GetLength() const;
+ FXJSE_HVALUE GetValue(FX_INT32 index) const;
+ FX_BOOL GetBoolean(FX_INT32 index) const;
+ FX_INT32 GetInt32(FX_INT32 index) const;
+ FX_FLOAT GetFloat(FX_INT32 index) const;
+ CFX_ByteString GetUTF8String(FX_INT32 index) const;
+ FX_LPVOID GetObject(FX_INT32 index, FXJSE_HCLASS hClass = NULL) const;
+ FXJSE_HVALUE GetReturnValue();
+};
+typedef void (*FXJSE_FuncCallback) (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+typedef void (*FXJSE_PropAccessor) (FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue);
+typedef FX_INT32(*FXJSE_PropTypeGetter) (FXJSE_HOBJECT hObject, FX_BSTR szPropName, FX_BOOL bQueryIn);
+typedef FX_BOOL (*FXJSE_PropDeleter) (FXJSE_HOBJECT hObject, FX_BSTR szPropName);
+typedef struct _FXJSE_FUNCTION {
+ FX_LPCSTR name;
+ FXJSE_FuncCallback callbackProc;
+} FXJSE_FUNCTION;
+#define FXJSE_DEF_FUNCTION(functionName, functionCallback) {functionName, functionCallback}
+void FXJSE_DefineFunctions(FXJSE_HCONTEXT hContext, const FXJSE_FUNCTION* lpFunctions, int nNum);
+typedef struct _FXJSE_PROPERTY {
+ FX_LPCSTR name;
+ FXJSE_PropAccessor getProc;
+ FXJSE_PropAccessor setProc;
+} FXJSE_PROPERTY;
+enum FXJSE_ClassPropTypes {
+ FXJSE_ClassPropType_None,
+ FXJSE_ClassPropType_Property,
+ FXJSE_ClassPropType_Method
+};
+typedef struct _FXJSE_CLASS {
+ FX_LPCSTR name;
+ FXJSE_FuncCallback constructor;
+ FXJSE_PROPERTY* properties;
+ FXJSE_FUNCTION* methods;
+ FX_INT32 propNum;
+ FX_INT32 methNum;
+ FXJSE_PropTypeGetter dynPropTypeGetter;
+ FXJSE_PropAccessor dynPropGetter;
+ FXJSE_PropAccessor dynPropSetter;
+ FXJSE_PropDeleter dynPropDeleter;
+ FXJSE_FuncCallback dynMethodCall;
+} FXJSE_CLASS;
+FXJSE_HCLASS FXJSE_DefineClass(FXJSE_HCONTEXT hContext, const FXJSE_CLASS* lpClass);
+FXJSE_HCLASS FXJSE_GetClass(FXJSE_HCONTEXT hContext, FX_BSTR szName);
+FXJSE_HVALUE FXJSE_Value_Create(FXJSE_HRUNTIME hRuntime);
+void FXJSE_Value_Release(FXJSE_HVALUE hValue);
+FXJSE_HRUNTIME FXJSE_Value_GetRuntime(FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsUndefined (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsNull (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsBoolean (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsUTF8String (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsNumber (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsInteger (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsObject (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsArray (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsFunction (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_IsDate (FXJSE_HVALUE hValue);
+FX_BOOL FXJSE_Value_ToBoolean (FXJSE_HVALUE hValue);
+FX_FLOAT FXJSE_Value_ToFloat (FXJSE_HVALUE hValue);
+FXJSE_DOUBLE FXJSE_Value_ToDouble (FXJSE_HVALUE hValue);
+FX_INT32 FXJSE_Value_ToInteger (FXJSE_HVALUE hValue);
+void FXJSE_Value_ToUTF8String (FXJSE_HVALUE hValue, CFX_ByteString& szStrOutput);
+FX_LPVOID FXJSE_Value_ToObject (FXJSE_HVALUE hValue, FXJSE_HCLASS hClass);
+void FXJSE_Value_SetUndefined (FXJSE_HVALUE hValue);
+void FXJSE_Value_SetNull (FXJSE_HVALUE hValue);
+void FXJSE_Value_SetBoolean (FXJSE_HVALUE hValue, FX_BOOL bBoolean);
+void FXJSE_Value_SetUTF8String (FXJSE_HVALUE hValue, FX_BSTR szString);
+void FXJSE_Value_SetInteger (FXJSE_HVALUE hValue, FX_INT32 nInteger);
+void FXJSE_Value_SetFloat (FXJSE_HVALUE hValue, FX_FLOAT fFloat);
+void FXJSE_Value_SetDouble (FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble);
+void FXJSE_Value_SetObject (FXJSE_HVALUE hValue, FX_LPVOID lpObject, FXJSE_HCLASS hClass);
+void FXJSE_Value_SetArray (FXJSE_HVALUE hValue, FX_UINT32 uValueCount, FXJSE_HVALUE* rgValues);
+void FXJSE_Value_SetDate (FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble);
+void FXJSE_Value_Set (FXJSE_HVALUE hValue, FXJSE_HVALUE hOriginalValue);
+FX_BOOL FXJSE_Value_GetObjectProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FXJSE_HVALUE hPropValue);
+FX_BOOL FXJSE_Value_SetObjectProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FXJSE_HVALUE hPropValue);
+FX_BOOL FXJSE_Value_GetObjectPropByIdx (FXJSE_HVALUE hValue, FX_UINT32 uPropIdx, FXJSE_HVALUE hPropValue);
+FX_BOOL FXJSE_Value_SetObjectPropByIdx (FXJSE_HVALUE hValue, FX_UINT32 uPropIdx, FXJSE_HVALUE hPropValue);
+FX_BOOL FXJSE_Value_DeleteObjectProp (FXJSE_HVALUE hValue, FX_BSTR szPropName);
+FX_BOOL FXJSE_Value_ObjectHasOwnProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FX_BOOL bUseTypeGetter);
+FX_BOOL FXJSE_Value_SetObjectOwnProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FXJSE_HVALUE hPropValue);
+FX_BOOL FXJSE_Value_CallFunction (FXJSE_HVALUE hFunction, FXJSE_HVALUE hThis, FXJSE_HVALUE hRetValue, FX_UINT32 nArgCount, FXJSE_HVALUE* lpArgs);
+FX_BOOL FXJSE_Value_SetFunctionBind (FXJSE_HVALUE hValue, FXJSE_HVALUE hOldFunction, FXJSE_HVALUE hNewThis);
+FX_BOOL FXJSE_ExecuteScript(FXJSE_HCONTEXT hContext, FX_LPCSTR szScript, FXJSE_HVALUE hRetValue, FXJSE_HVALUE hNewThisObject = NULL);
+void FXJSE_ThrowMessage(FX_BSTR utf8Name, FX_BSTR utf8Message);
+FX_BOOL FXJSE_ReturnValue_GetMessage(FXJSE_HVALUE hRetValue, CFX_ByteString& utf8Name, CFX_ByteString& utf8Message);
+FX_BOOL FXJSE_ReturnValue_GetLineInfo(FXJSE_HVALUE hRetValue, FX_INT32& nLine, FX_INT32& nCol);
+#endif
diff --git a/xfa/src/fdp/include/fde.h b/xfa/src/fdp/include/fde.h
new file mode 100644
index 0000000000..1e2c311188
--- /dev/null
+++ b/xfa/src/fdp/include/fde.h
@@ -0,0 +1,20 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE
+#define _FDE
+#include "fde_mem.h"
+#include "fde_xml.h"
+#include "fde_img.h"
+#include "fde_brs.h"
+#include "fde_pen.h"
+#include "fde_pth.h"
+#include "fde_tto.h"
+#include "fde_psr.h"
+#include "fde_css.h"
+#include "fde_rdv.h"
+#include "fde_rdr.h"
+#endif
diff --git a/xfa/src/fdp/include/fde_brs.h b/xfa/src/fdp/include/fde_brs.h
new file mode 100644
index 0000000000..04a4f48ad5
--- /dev/null
+++ b/xfa/src/fdp/include/fde_brs.h
@@ -0,0 +1,143 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_BRUSH
+#define _FDE_BRUSH
+class IFDE_Image;
+class IFDE_Path;
+class IFDE_Brush;
+class IFDE_SolidBrush;
+class IFDE_HatchBrush;
+class IFDE_TextureBrush;
+class IFDE_LinearGradientBrush;
+#define FDE_BRUSHTYPE_Unknown -1
+#define FDE_BRUSHTYPE_Solid 0
+#define FDE_BRUSHTYPE_Hatch 1
+#define FDE_BRUSHTYPE_Texture 2
+#define FDE_BRUSHTYPE_LinearGradient 3
+#define FDE_BRUSHTYPE_MAX 3
+#define FDE_WRAPMODE_Tile 0
+#define FDE_WRAPMODE_TileFlipX 1
+#define FDE_WRAPMODE_TileFlipY 2
+#define FDE_WRAPMODE_TileFlipXY 3
+#define FDE_WRAPMODE_Clamp 4
+typedef struct _FDE_GRADIENTCOLOR {
+ FX_FLOAT pos;
+ FX_ARGB color;
+} FDE_GRADIENTCOLOR, * FDE_LPGRADIENTCOLOR;
+typedef FDE_GRADIENTCOLOR const * FDE_LPCGRADIENTCOLOR;
+typedef CFX_ArrayTemplate<FDE_GRADIENTCOLOR> CFDE_GradientColors;
+class IFDE_Brush
+{
+public:
+ static IFDE_Brush* Create(FX_INT32 iType);
+ virtual void Release() = 0;
+ virtual FX_INT32 GetType() const = 0;
+};
+class IFDE_SolidBrush : public IFDE_Brush
+{
+public:
+ virtual FX_ARGB GetColor() const = 0;
+ virtual void SetColor(FX_ARGB color) = 0;
+ virtual const CFX_Matrix& GetMatrix() const = 0;
+ virtual void ResetMatrix() = 0;
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy) = 0;
+ virtual void RotateMatrix(FX_FLOAT fRadian) = 0;
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy) = 0;
+ virtual void ConcatMatrix(const CFX_Matrix &matrix) = 0;
+ virtual void SetMatrix(const CFX_Matrix &matrix) = 0;
+};
+#define FDE_HATCHSTYLE_Horizontal 0
+#define FDE_HATCHSTYLE_Vertical 1
+#define FDE_HATCHSTYLE_ForwardDiagonal 2
+#define FDE_HATCHSTYLE_BackwardDiagonal 3
+#define FDE_HATCHSTYLE_Cross 4
+#define FDE_HATCHSTYLE_DiagonalCross 5
+#define FDE_HATCHSTYLE_05Percent 6
+#define FDE_HATCHSTYLE_10Percent 7
+#define FDE_HATCHSTYLE_20Percent 8
+#define FDE_HATCHSTYLE_25Percent 9
+#define FDE_HATCHSTYLE_30Percent 10
+#define FDE_HATCHSTYLE_40Percent 11
+#define FDE_HATCHSTYLE_50Percent 12
+#define FDE_HATCHSTYLE_60Percent 13
+#define FDE_HATCHSTYLE_70Percent 14
+#define FDE_HATCHSTYLE_75Percent 15
+#define FDE_HATCHSTYLE_80Percent 16
+#define FDE_HATCHSTYLE_90Percent 17
+#define FDE_HATCHSTYLE_LightDownwardDiagonal 18
+#define FDE_HATCHSTYLE_LightUpwardDiagonal 19
+#define FDE_HATCHSTYLE_DarkDownwardDiagonal 20
+#define FDE_HATCHSTYLE_DarkUpwardDiagonal 21
+#define FDE_HATCHSTYLE_WideDownwardDiagonal 22
+#define FDE_HATCHSTYLE_WideUpwardDiagonal 23
+#define FDE_HATCHSTYLE_LightVertical 24
+#define FDE_HATCHSTYLE_LightHorizontal 25
+#define FDE_HATCHSTYLE_NarrowVertical 26
+#define FDE_HATCHSTYLE_NarrowHorizontal 27
+#define FDE_HATCHSTYLE_DarkVertical 28
+#define FDE_HATCHSTYLE_DarkHorizontal 29
+#define FDE_HATCHSTYLE_DashedDownwardDiagonal 30
+#define FDE_HATCHSTYLE_DashedUpwardDiagonal 31
+#define FDE_HATCHSTYLE_DashedHorizontal 32
+#define FDE_HATCHSTYLE_DashedVertical 33
+#define FDE_HATCHSTYLE_SmallConfetti 34
+#define FDE_HATCHSTYLE_LargeConfetti 35
+#define FDE_HATCHSTYLE_ZigZag 36
+#define FDE_HATCHSTYLE_Wave 37
+#define FDE_HATCHSTYLE_DiagonalBrick 38
+#define FDE_HATCHSTYLE_HorizontalBrick 39
+#define FDE_HATCHSTYLE_Weave 40
+#define FDE_HATCHSTYLE_Plaid 41
+#define FDE_HATCHSTYLE_Divot 42
+#define FDE_HATCHSTYLE_DottedGrid 43
+#define FDE_HATCHSTYLE_DottedDiamond 44
+#define FDE_HATCHSTYLE_Shingle 45
+#define FDE_HATCHSTYLE_Trellis 46
+#define FDE_HATCHSTYLE_Sphere 47
+#define FDE_HATCHSTYLE_SmallGrid 48
+#define FDE_HATCHSTYLE_SmallCheckerBoard 49
+#define FDE_HATCHSTYLE_LargeCheckerBoard 50
+#define FDE_HATCHSTYLE_OutlinedDiamond 51
+#define FDE_HATCHSTYLE_SolidDiamond 52
+#define FDE_HATCHSTYLE_Total 53
+#define FDE_HATCHSTYLE_LargeGrid FDE_HATCHSTYLE_Cross
+#define FDE_HATCHSTYLE_Min FDE_HATCHSTYLE_Horizontal
+#define FDE_HATCHSTYLE_Max (FDE_HATCHSTYLE_Total - 1)
+class IFDE_HatchBrush : public IFDE_Brush
+{
+public:
+ virtual FX_ARGB GetColor(FX_BOOL bForegroundColor) const = 0;
+ virtual void SetColor(FX_ARGB color, FX_BOOL bForegroundColor) = 0;
+ virtual FX_INT32 GetHatchStyle() const = 0;
+ virtual FX_BOOL SetHatchStyle(FX_INT32 iHatchStyle) = 0;
+};
+class IFDE_TextureBrush : public IFDE_Brush
+{
+public:
+ virtual IFDE_Image* GetImage() const = 0;
+ virtual void SetImage(IFDE_Image *pImage, FX_BOOL bAutoRelease) = 0;
+ virtual FX_INT32 GetWrapMode() const = 0;
+ virtual void SetWrapMode(FX_INT32 iWrapMode) = 0;
+};
+#define FDE_LINEARGRADIENTMODE_Horizontal 0
+#define FDE_LINEARGRADIENTMODE_Vertical 1
+#define FDE_LINEARGRADIENTMODE_ForwardDiagonal 2
+#define FDE_LINEARGRADIENTMODE_BackwardDiagonal 3
+class IFDE_LinearGradientBrush : public IFDE_Brush
+{
+public:
+ virtual void GetLinearPoints(CFX_PointF &startingPoint, CFX_PointF &endingPoint) const = 0;
+ virtual void SetLinearPoints(const CFX_PointF &startingPoint, const CFX_PointF &endingPoint) = 0;
+ virtual void GetLinearColors(FX_ARGB &startingColor, FX_ARGB &endingColor) const = 0;
+ virtual void SetLinearColors(const FX_ARGB &startingColor, const FX_ARGB &endingColor) = 0;
+ virtual FX_INT32 CountGradientColors() const = 0;
+ virtual FX_BOOL GetGradientColors(CFDE_GradientColors &colors) const = 0;
+ virtual FX_BOOL SetGradientColors(const CFDE_GradientColors &colors) = 0;
+ virtual FX_INT32 GetWrapMode() const = 0;
+ virtual void SetWrapMode(FX_INT32 iWrapMode) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_css.h b/xfa/src/fdp/include/fde_css.h
new file mode 100644
index 0000000000..2870c8d27a
--- /dev/null
+++ b/xfa/src/fdp/include/fde_css.h
@@ -0,0 +1,1082 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSS
+#define _FDE_CSS
+class IFDE_HTMNotify;
+class IFDE_CSSValue;
+class IFDE_CSSPrimitiveValue;
+class IFDE_CSSValueList;
+class IFDE_CSSDeclaration;
+class IFDE_CSSSelector;
+class IFDE_CSSRule;
+class IFDE_CSSStyleRule;
+class IFDE_CSSMediaRule;
+class IFDE_CSSFontFaceRule;
+class IFDE_CSSStyleSheet;
+class IFDE_CSSStyleSheetCache;
+class IFDE_CSSSyntaxParser;
+class IFDE_CSSRubyStyle;
+class IFDE_CSSMultiColumnStyle;
+class IFDE_CSSGeneratedContentStyle;
+class IFDE_CSSFontStyle;
+class IFDE_CSSBoundaryStyle;
+class IFDE_CSSPositionStyle;
+class IFDE_CSSParagraphStyle;
+class IFDE_CSSBackgroundStyle;
+class IFDE_CSSListStyle;
+class IFDE_CSSTableStyle;
+class IFDE_CSSVisualStyle;
+class IFDE_CSSComputedStyle;
+class IFDE_CSSTagProvider;
+class IFDE_CSSAccelerator;
+class IFDE_CSSStyleSelector;
+class IFDE_CSSCounterContext;
+class IFDE_CSSCounterManager;
+class IFDE_CSSQuoteContext;
+class IFDE_CSSContentContext;
+class IFDE_CSSMultiColumnContext;
+class IFDE_CSSFloatContext;
+enum FDE_CSSVALUETYPE {
+ FDE_CSSVALUETYPE_Primitive = 1,
+ FDE_CSSVALUETYPE_List = 2,
+ FDE_CSSVALUETYPE_Shorthand,
+};
+enum FDE_CSSPRIMITIVETYPE {
+ FDE_CSSPRIMITIVETYPE_Unknown = 0,
+ FDE_CSSPRIMITIVETYPE_Number = 1,
+ FDE_CSSPRIMITIVETYPE_Percent = 2,
+ FDE_CSSPRIMITIVETYPE_EMS = 3,
+ FDE_CSSPRIMITIVETYPE_EXS = 4,
+ FDE_CSSPRIMITIVETYPE_PX = 5,
+ FDE_CSSPRIMITIVETYPE_CM = 6,
+ FDE_CSSPRIMITIVETYPE_MM = 7,
+ FDE_CSSPRIMITIVETYPE_IN = 8,
+ FDE_CSSPRIMITIVETYPE_PT = 9,
+ FDE_CSSPRIMITIVETYPE_PC = 10,
+ FDE_CSSPRIMITIVETYPE_String = 19,
+ FDE_CSSPRIMITIVETYPE_URI = 20,
+ FDE_CSSPRIMITIVETYPE_RGB = 25,
+ FDE_CSSPRIMITIVETYPE_Enum,
+ FDE_CSSPRIMITIVETYPE_Function,
+};
+enum FDE_CSSPROPERTYVALUE {
+ FDE_CSSPROPERTYVALUE_Bolder,
+ FDE_CSSPROPERTYVALUE_LowerLatin,
+ FDE_CSSPROPERTYVALUE_Lowercase,
+ FDE_CSSPROPERTYVALUE_LowerGreek,
+ FDE_CSSPROPERTYVALUE_Sesame,
+ FDE_CSSPROPERTYVALUE_None,
+ FDE_CSSPROPERTYVALUE_NwResize,
+ FDE_CSSPROPERTYVALUE_WResize,
+ FDE_CSSPROPERTYVALUE_Dot,
+ FDE_CSSPROPERTYVALUE_End,
+ FDE_CSSPROPERTYVALUE_Ltr,
+ FDE_CSSPROPERTYVALUE_Pre,
+ FDE_CSSPROPERTYVALUE_Rtl,
+ FDE_CSSPROPERTYVALUE_Sub,
+ FDE_CSSPROPERTYVALUE_Top,
+ FDE_CSSPROPERTYVALUE_Visible,
+ FDE_CSSPROPERTYVALUE_Filled,
+ FDE_CSSPROPERTYVALUE_SwResize,
+ FDE_CSSPROPERTYVALUE_NoRepeat,
+ FDE_CSSPROPERTYVALUE_Default,
+ FDE_CSSPROPERTYVALUE_Transparent,
+ FDE_CSSPROPERTYVALUE_Ridge,
+ FDE_CSSPROPERTYVALUE_Right,
+ FDE_CSSPROPERTYVALUE_HorizontalTb,
+ FDE_CSSPROPERTYVALUE_DistributeLetter,
+ FDE_CSSPROPERTYVALUE_DoubleCircle,
+ FDE_CSSPROPERTYVALUE_Ruby,
+ FDE_CSSPROPERTYVALUE_Collapse,
+ FDE_CSSPROPERTYVALUE_Normal,
+ FDE_CSSPROPERTYVALUE_Avoid,
+ FDE_CSSPROPERTYVALUE_UpperRoman,
+ FDE_CSSPROPERTYVALUE_Auto,
+ FDE_CSSPROPERTYVALUE_Text,
+ FDE_CSSPROPERTYVALUE_XSmall,
+ FDE_CSSPROPERTYVALUE_Thin,
+ FDE_CSSPROPERTYVALUE_Repeat,
+ FDE_CSSPROPERTYVALUE_Small,
+ FDE_CSSPROPERTYVALUE_NeResize,
+ FDE_CSSPROPERTYVALUE_NoContent,
+ FDE_CSSPROPERTYVALUE_Outside,
+ FDE_CSSPROPERTYVALUE_EResize,
+ FDE_CSSPROPERTYVALUE_TableRow,
+ FDE_CSSPROPERTYVALUE_Bottom,
+ FDE_CSSPROPERTYVALUE_Underline,
+ FDE_CSSPROPERTYVALUE_CjkIdeographic,
+ FDE_CSSPROPERTYVALUE_SeResize,
+ FDE_CSSPROPERTYVALUE_Fixed,
+ FDE_CSSPROPERTYVALUE_Double,
+ FDE_CSSPROPERTYVALUE_Solid,
+ FDE_CSSPROPERTYVALUE_RubyBaseGroup,
+ FDE_CSSPROPERTYVALUE_OpenQuote,
+ FDE_CSSPROPERTYVALUE_Lighter,
+ FDE_CSSPROPERTYVALUE_LowerRoman,
+ FDE_CSSPROPERTYVALUE_Strict,
+ FDE_CSSPROPERTYVALUE_TableCaption,
+ FDE_CSSPROPERTYVALUE_Oblique,
+ FDE_CSSPROPERTYVALUE_Decimal,
+ FDE_CSSPROPERTYVALUE_Loose,
+ FDE_CSSPROPERTYVALUE_Hebrew,
+ FDE_CSSPROPERTYVALUE_Hidden,
+ FDE_CSSPROPERTYVALUE_Dashed,
+ FDE_CSSPROPERTYVALUE_Embed,
+ FDE_CSSPROPERTYVALUE_TableRowGroup,
+ FDE_CSSPROPERTYVALUE_TableColumn,
+ FDE_CSSPROPERTYVALUE_Static,
+ FDE_CSSPROPERTYVALUE_Outset,
+ FDE_CSSPROPERTYVALUE_DecimalLeadingZero,
+ FDE_CSSPROPERTYVALUE_KeepWords,
+ FDE_CSSPROPERTYVALUE_KatakanaIroha,
+ FDE_CSSPROPERTYVALUE_Super,
+ FDE_CSSPROPERTYVALUE_Center,
+ FDE_CSSPROPERTYVALUE_TableHeaderGroup,
+ FDE_CSSPROPERTYVALUE_Inside,
+ FDE_CSSPROPERTYVALUE_XxLarge,
+ FDE_CSSPROPERTYVALUE_Triangle,
+ FDE_CSSPROPERTYVALUE_RubyTextGroup,
+ FDE_CSSPROPERTYVALUE_Circle,
+ FDE_CSSPROPERTYVALUE_Hiragana,
+ FDE_CSSPROPERTYVALUE_RepeatX,
+ FDE_CSSPROPERTYVALUE_RepeatY,
+ FDE_CSSPROPERTYVALUE_Move,
+ FDE_CSSPROPERTYVALUE_HiraganaIroha,
+ FDE_CSSPROPERTYVALUE_RubyBase,
+ FDE_CSSPROPERTYVALUE_Scroll,
+ FDE_CSSPROPERTYVALUE_Smaller,
+ FDE_CSSPROPERTYVALUE_TableFooterGroup,
+ FDE_CSSPROPERTYVALUE_Baseline,
+ FDE_CSSPROPERTYVALUE_Separate,
+ FDE_CSSPROPERTYVALUE_Armenian,
+ FDE_CSSPROPERTYVALUE_Open,
+ FDE_CSSPROPERTYVALUE_Relative,
+ FDE_CSSPROPERTYVALUE_Thick,
+ FDE_CSSPROPERTYVALUE_Justify,
+ FDE_CSSPROPERTYVALUE_Middle,
+ FDE_CSSPROPERTYVALUE_Always,
+ FDE_CSSPROPERTYVALUE_DistributeSpace,
+ FDE_CSSPROPERTYVALUE_LineEdge,
+ FDE_CSSPROPERTYVALUE_PreWrap,
+ FDE_CSSPROPERTYVALUE_Medium,
+ FDE_CSSPROPERTYVALUE_NResize,
+ FDE_CSSPROPERTYVALUE_ListItem,
+ FDE_CSSPROPERTYVALUE_Show,
+ FDE_CSSPROPERTYVALUE_Currentcolor,
+ FDE_CSSPROPERTYVALUE_NoCloseQuote,
+ FDE_CSSPROPERTYVALUE_VerticalLr,
+ FDE_CSSPROPERTYVALUE_VerticalRl,
+ FDE_CSSPROPERTYVALUE_Pointer,
+ FDE_CSSPROPERTYVALUE_XxSmall,
+ FDE_CSSPROPERTYVALUE_Bold,
+ FDE_CSSPROPERTYVALUE_Both,
+ FDE_CSSPROPERTYVALUE_SmallCaps,
+ FDE_CSSPROPERTYVALUE_Katakana,
+ FDE_CSSPROPERTYVALUE_After,
+ FDE_CSSPROPERTYVALUE_Horizontal,
+ FDE_CSSPROPERTYVALUE_Dotted,
+ FDE_CSSPROPERTYVALUE_Disc,
+ FDE_CSSPROPERTYVALUE_Georgian,
+ FDE_CSSPROPERTYVALUE_Inline,
+ FDE_CSSPROPERTYVALUE_Overline,
+ FDE_CSSPROPERTYVALUE_Wait,
+ FDE_CSSPROPERTYVALUE_BreakAll,
+ FDE_CSSPROPERTYVALUE_UpperAlpha,
+ FDE_CSSPROPERTYVALUE_Capitalize,
+ FDE_CSSPROPERTYVALUE_Nowrap,
+ FDE_CSSPROPERTYVALUE_TextBottom,
+ FDE_CSSPROPERTYVALUE_NoOpenQuote,
+ FDE_CSSPROPERTYVALUE_Groove,
+ FDE_CSSPROPERTYVALUE_Progress,
+ FDE_CSSPROPERTYVALUE_Larger,
+ FDE_CSSPROPERTYVALUE_CloseQuote,
+ FDE_CSSPROPERTYVALUE_TableCell,
+ FDE_CSSPROPERTYVALUE_PreLine,
+ FDE_CSSPROPERTYVALUE_Absolute,
+ FDE_CSSPROPERTYVALUE_InlineTable,
+ FDE_CSSPROPERTYVALUE_BidiOverride,
+ FDE_CSSPROPERTYVALUE_InlineBlock,
+ FDE_CSSPROPERTYVALUE_Inset,
+ FDE_CSSPROPERTYVALUE_Crosshair,
+ FDE_CSSPROPERTYVALUE_UpperLatin,
+ FDE_CSSPROPERTYVALUE_Help,
+ FDE_CSSPROPERTYVALUE_Hide,
+ FDE_CSSPROPERTYVALUE_Uppercase,
+ FDE_CSSPROPERTYVALUE_SResize,
+ FDE_CSSPROPERTYVALUE_Table,
+ FDE_CSSPROPERTYVALUE_Blink,
+ FDE_CSSPROPERTYVALUE_Block,
+ FDE_CSSPROPERTYVALUE_Start,
+ FDE_CSSPROPERTYVALUE_TableColumnGroup,
+ FDE_CSSPROPERTYVALUE_Italic,
+ FDE_CSSPROPERTYVALUE_LineThrough,
+ FDE_CSSPROPERTYVALUE_KeepAll,
+ FDE_CSSPROPERTYVALUE_LowerAlpha,
+ FDE_CSSPROPERTYVALUE_RunIn,
+ FDE_CSSPROPERTYVALUE_Square,
+ FDE_CSSPROPERTYVALUE_XLarge,
+ FDE_CSSPROPERTYVALUE_Large,
+ FDE_CSSPROPERTYVALUE_Before,
+ FDE_CSSPROPERTYVALUE_Left,
+ FDE_CSSPROPERTYVALUE_TextTop,
+ FDE_CSSPROPERTYVALUE_RubyText,
+ FDE_CSSPROPERTYVALUE_NoDisplay,
+ FDE_CSSPROPERTYVALUE_MAX
+};
+class IFDE_CSSValue
+{
+public:
+ virtual FDE_CSSVALUETYPE GetType() const = 0;
+};
+class IFDE_CSSPrimitiveValue : public IFDE_CSSValue
+{
+public:
+ virtual FDE_CSSVALUETYPE GetType() const
+ {
+ return FDE_CSSVALUETYPE_Primitive;
+ }
+ virtual FDE_CSSPRIMITIVETYPE GetPrimitiveType() const = 0;
+ virtual FX_ARGB GetRGBColor() const = 0;
+ virtual FX_FLOAT GetFloat() const = 0;
+ virtual FX_LPCWSTR GetString(FX_INT32 &iLength) const = 0;
+ virtual FDE_CSSPROPERTYVALUE GetEnum() const = 0;
+ virtual FX_LPCWSTR GetFuncName() const = 0;
+ virtual FX_INT32 CountArgs() const = 0;
+ virtual IFDE_CSSValue* GetArgs(FX_INT32 index) const = 0;
+};
+class IFDE_CSSValueList : public IFDE_CSSValue
+{
+public:
+ virtual FDE_CSSVALUETYPE GetType() const
+ {
+ return FDE_CSSVALUETYPE_List;
+ }
+ virtual FX_INT32 CountValues() const = 0;
+ virtual IFDE_CSSValue* GetValue(FX_INT32 index) const = 0;
+};
+enum FDE_CSSPROPERTY {
+ FDE_CSSPROPERTY_WritingMode,
+ FDE_CSSPROPERTY_ColumnRuleWidth,
+ FDE_CSSPROPERTY_BorderLeft,
+ FDE_CSSPROPERTY_ColumnRule,
+ FDE_CSSPROPERTY_Height,
+ FDE_CSSPROPERTY_CounterReset,
+ FDE_CSSPROPERTY_Content,
+ FDE_CSSPROPERTY_RubyPosition,
+ FDE_CSSPROPERTY_BackgroundColor,
+ FDE_CSSPROPERTY_Width,
+ FDE_CSSPROPERTY_Src,
+ FDE_CSSPROPERTY_Top,
+ FDE_CSSPROPERTY_Margin,
+ FDE_CSSPROPERTY_BorderColor,
+ FDE_CSSPROPERTY_Widows,
+ FDE_CSSPROPERTY_BorderBottomColor,
+ FDE_CSSPROPERTY_TextIndent,
+ FDE_CSSPROPERTY_Right,
+ FDE_CSSPROPERTY_TextEmphasisStyle,
+ FDE_CSSPROPERTY_PaddingLeft,
+ FDE_CSSPROPERTY_ColumnWidth,
+ FDE_CSSPROPERTY_MarginLeft,
+ FDE_CSSPROPERTY_Border,
+ FDE_CSSPROPERTY_BorderTop,
+ FDE_CSSPROPERTY_RubyOverhang,
+ FDE_CSSPROPERTY_PageBreakBefore,
+ FDE_CSSPROPERTY_MaxHeight,
+ FDE_CSSPROPERTY_MinWidth,
+ FDE_CSSPROPERTY_BorderLeftColor,
+ FDE_CSSPROPERTY_Bottom,
+ FDE_CSSPROPERTY_Quotes,
+ FDE_CSSPROPERTY_MaxWidth,
+ FDE_CSSPROPERTY_PaddingRight,
+ FDE_CSSPROPERTY_ListStyleImage,
+ FDE_CSSPROPERTY_WhiteSpace,
+ FDE_CSSPROPERTY_BorderBottom,
+ FDE_CSSPROPERTY_ListStyleType,
+ FDE_CSSPROPERTY_WordBreak,
+ FDE_CSSPROPERTY_OverflowX,
+ FDE_CSSPROPERTY_OverflowY,
+ FDE_CSSPROPERTY_BorderTopColor,
+ FDE_CSSPROPERTY_FontFamily,
+ FDE_CSSPROPERTY_Cursor,
+ FDE_CSSPROPERTY_RubyAlign,
+ FDE_CSSPROPERTY_ColumnRuleColor,
+ FDE_CSSPROPERTY_FontWeight,
+ FDE_CSSPROPERTY_BorderRightStyle,
+ FDE_CSSPROPERTY_MinHeight,
+ FDE_CSSPROPERTY_Color,
+ FDE_CSSPROPERTY_LetterSpacing,
+ FDE_CSSPROPERTY_EmptyCells,
+ FDE_CSSPROPERTY_TextAlign,
+ FDE_CSSPROPERTY_RubySpan,
+ FDE_CSSPROPERTY_Position,
+ FDE_CSSPROPERTY_BorderStyle,
+ FDE_CSSPROPERTY_BorderBottomStyle,
+ FDE_CSSPROPERTY_BorderCollapse,
+ FDE_CSSPROPERTY_ColumnCount,
+ FDE_CSSPROPERTY_BorderRightWidth,
+ FDE_CSSPROPERTY_UnicodeBidi,
+ FDE_CSSPROPERTY_VerticalAlign,
+ FDE_CSSPROPERTY_PaddingTop,
+ FDE_CSSPROPERTY_Columns,
+ FDE_CSSPROPERTY_Overflow,
+ FDE_CSSPROPERTY_TableLayout,
+ FDE_CSSPROPERTY_FontVariant,
+ FDE_CSSPROPERTY_ListStyle,
+ FDE_CSSPROPERTY_BackgroundPosition,
+ FDE_CSSPROPERTY_BorderWidth,
+ FDE_CSSPROPERTY_TextEmphasisColor,
+ FDE_CSSPROPERTY_BorderLeftStyle,
+ FDE_CSSPROPERTY_PageBreakInside,
+ FDE_CSSPROPERTY_TextEmphasis,
+ FDE_CSSPROPERTY_BorderBottomWidth,
+ FDE_CSSPROPERTY_ColumnGap,
+ FDE_CSSPROPERTY_Orphans,
+ FDE_CSSPROPERTY_BorderRight,
+ FDE_CSSPROPERTY_FontSize,
+ FDE_CSSPROPERTY_PageBreakAfter,
+ FDE_CSSPROPERTY_CaptionSide,
+ FDE_CSSPROPERTY_BackgroundRepeat,
+ FDE_CSSPROPERTY_BorderTopStyle,
+ FDE_CSSPROPERTY_BorderSpacing,
+ FDE_CSSPROPERTY_TextTransform,
+ FDE_CSSPROPERTY_FontStyle,
+ FDE_CSSPROPERTY_Font,
+ FDE_CSSPROPERTY_LineHeight,
+ FDE_CSSPROPERTY_MarginRight,
+ FDE_CSSPROPERTY_Float,
+ FDE_CSSPROPERTY_BorderLeftWidth,
+ FDE_CSSPROPERTY_Display,
+ FDE_CSSPROPERTY_Clear,
+ FDE_CSSPROPERTY_ColumnRuleStyle,
+ FDE_CSSPROPERTY_TextCombine,
+ FDE_CSSPROPERTY_ListStylePosition,
+ FDE_CSSPROPERTY_Visibility,
+ FDE_CSSPROPERTY_PaddingBottom,
+ FDE_CSSPROPERTY_BackgroundAttachment,
+ FDE_CSSPROPERTY_BackgroundImage,
+ FDE_CSSPROPERTY_LineBreak,
+ FDE_CSSPROPERTY_Background,
+ FDE_CSSPROPERTY_BorderTopWidth,
+ FDE_CSSPROPERTY_WordSpacing,
+ FDE_CSSPROPERTY_BorderRightColor,
+ FDE_CSSPROPERTY_CounterIncrement,
+ FDE_CSSPROPERTY_Left,
+ FDE_CSSPROPERTY_TextDecoration,
+ FDE_CSSPROPERTY_Padding,
+ FDE_CSSPROPERTY_MarginBottom,
+ FDE_CSSPROPERTY_MarginTop,
+ FDE_CSSPROPERTY_Direction,
+ FDE_CSSPROPERTY_MAX
+};
+class IFDE_CSSDeclaration
+{
+public:
+ virtual IFDE_CSSValue* GetProperty(FDE_CSSPROPERTY eProperty, FX_BOOL &bImportant) const = 0;
+ virtual FX_POSITION GetStartPosition() const = 0;
+ virtual void GetNextProperty(FX_POSITION &pos, FDE_CSSPROPERTY &eProperty, IFDE_CSSValue *&pValue, FX_BOOL &bImportant) const = 0;
+ virtual FX_POSITION GetStartCustom() const = 0;
+ virtual void GetNextCustom(FX_POSITION &pos, CFX_WideString &wsName, CFX_WideString &wsValue) const = 0;
+};
+typedef CFX_ArrayTemplate<IFDE_CSSDeclaration*> CFDE_CSSDeclarationArray;
+enum FDE_CSSPERSUDO {
+ FDE_CSSPERSUDO_After,
+ FDE_CSSPERSUDO_Before,
+ FDE_CSSPERSUDO_NONE
+};
+enum FDE_CSSSELECTORTYPE {
+ FDE_CSSSELECTORTYPE_Element,
+ FDE_CSSSELECTORTYPE_Descendant,
+ FDE_CSSSELECTORTYPE_Class,
+ FDE_CSSSELECTORTYPE_Persudo,
+ FDE_CSSSELECTORTYPE_ID,
+};
+class IFDE_CSSSelector
+{
+public:
+ virtual FDE_CSSSELECTORTYPE GetType() const = 0;
+ virtual FX_DWORD GetNameHash() const = 0;
+ virtual IFDE_CSSSelector* GetNextSelector() const = 0;
+};
+#define FDE_CSSMEDIATYPE_Braille 0x01
+#define FDE_CSSMEDIATYPE_Emboss 0x02
+#define FDE_CSSMEDIATYPE_Handheld 0x04
+#define FDE_CSSMEDIATYPE_Print 0x08
+#define FDE_CSSMEDIATYPE_Projection 0x10
+#define FDE_CSSMEDIATYPE_Screen 0x20
+#define FDE_CSSMEDIATYPE_TTY 0x40
+#define FDE_CSSMEDIATYPE_TV 0x80
+#define FDE_CSSMEDIATYPE_ALL 0xFF
+enum FDE_CSSRULETYPE {
+ FDE_CSSRULETYPE_Unknown = 0,
+ FDE_CSSRULETYPE_Style = 1,
+ FDE_CSSRULETYPE_Media = 4,
+ FDE_CSSRULETYPE_FontFace = 5,
+};
+class IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const = 0;
+};
+typedef CFX_MassArrayTemplate<IFDE_CSSRule*> CFDE_CSSRuleArray;
+class IFDE_CSSStyleRule : public IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const
+ {
+ return FDE_CSSRULETYPE_Style;
+ }
+ virtual FX_INT32 CountSelectorLists() const = 0;
+ virtual IFDE_CSSSelector* GetSelectorList(FX_INT32 index) const = 0;
+ virtual IFDE_CSSDeclaration* GetDeclaration() const = 0;
+};
+class IFDE_CSSMediaRule : public IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const
+ {
+ return FDE_CSSRULETYPE_Media;
+ }
+ virtual FX_DWORD GetMediaList() const = 0;
+ virtual FX_INT32 CountRules() const = 0;
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index) = 0;
+};
+class IFDE_CSSFontFaceRule : public IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const
+ {
+ return FDE_CSSRULETYPE_FontFace;
+ }
+ virtual IFDE_CSSDeclaration* GetDeclaration() const = 0;
+};
+class IFDE_CSSStyleSheet : public IFX_Unknown
+{
+public:
+ static IFDE_CSSStyleSheet* LoadHTMLStandardStyleSheet();
+ static IFDE_CSSStyleSheet* LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage, FX_DWORD dwMediaList = FDE_CSSMEDIATYPE_ALL);
+ static IFDE_CSSStyleSheet* LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage, FX_DWORD dwMediaList = FDE_CSSMEDIATYPE_ALL);
+ virtual FX_BOOL GetUrl(CFX_WideString &szUrl) = 0;
+ virtual FX_DWORD GetMediaList() const = 0;
+ virtual FX_WORD GetCodePage() const = 0;
+
+ virtual FX_INT32 CountRules() const = 0;
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index) = 0;
+};
+typedef CFX_ArrayTemplate<IFDE_CSSStyleSheet*> CFDE_CSSStyleSheetArray;
+#define FDE_CSSUSERSTYLESHEET (FX_BSTRC("#USERSHEET"))
+#define FDE_CSSUAGENTSTYLESHEET (FX_BSTRC("#AGENTSHEET"))
+class IFDE_CSSStyleSheetCache
+{
+public:
+ static IFDE_CSSStyleSheetCache* Create();
+ virtual void Release() = 0;
+ virtual void SetMaxItems(FX_INT32 iMaxCount = 5) = 0;
+ virtual void AddStyleSheet(FX_BSTR szKey, IFDE_CSSStyleSheet *pStyleSheet) = 0;
+ virtual IFDE_CSSStyleSheet* GetStyleSheet(FX_BSTR szKey) const = 0;
+ virtual void RemoveStyleSheet(FX_BSTR szKey) = 0;
+};
+enum FDE_CSSSYNTAXSTATUS {
+ FDE_CSSSYNTAXSTATUS_Error,
+ FDE_CSSSYNTAXSTATUS_EOS,
+ FDE_CSSSYNTAXSTATUS_None,
+ FDE_CSSSYNTAXSTATUS_Charset,
+ FDE_CSSSYNTAXSTATUS_ImportRule,
+ FDE_CSSSYNTAXSTATUS_ImportClose,
+ FDE_CSSSYNTAXSTATUS_PageRule,
+ FDE_CSSSYNTAXSTATUS_StyleRule,
+ FDE_CSSSYNTAXSTATUS_FontFaceRule,
+ FDE_CSSSYNTAXSTATUS_MediaRule,
+ FDE_CSSSYNTAXSTATUS_MediaType,
+ FDE_CSSSYNTAXSTATUS_URI,
+ FDE_CSSSYNTAXSTATUS_Selector,
+ FDE_CSSSYNTAXSTATUS_DeclOpen,
+ FDE_CSSSYNTAXSTATUS_DeclClose,
+ FDE_CSSSYNTAXSTATUS_PropertyName,
+ FDE_CSSSYNTAXSTATUS_PropertyValue,
+};
+class IFDE_CSSSyntaxParser
+{
+public:
+ static IFDE_CSSSyntaxParser* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL Init(IFX_Stream *pStream, FX_INT32 iCSSPlaneSize, FX_INT32 iTextDataSize = 32, FX_BOOL bOnlyDeclaration = FALSE) = 0;
+ virtual FX_BOOL Init(FX_LPCWSTR pBuffer, FX_INT32 iBufferSize, FX_INT32 iTextDatSize = 32, FX_BOOL bOnlyDeclaration = FALSE) = 0;
+
+ virtual FDE_CSSSYNTAXSTATUS DoSyntaxParse() = 0;
+ virtual FX_LPCWSTR GetCurrentString(FX_INT32 &iLength) const = 0;
+};
+enum FDE_CSSLENGTHUNIT {
+ FDE_CSSLENGTHUNIT_Auto,
+ FDE_CSSLENGTHUNIT_None,
+ FDE_CSSLENGTHUNIT_Normal,
+ FDE_CSSLENGTHUNIT_Point,
+ FDE_CSSLENGTHUNIT_Percent,
+};
+#define FDE_CSSUNITBITS (3)
+#define FDE_CSSUNITMASK ((1 << FDE_CSSUNITBITS) - 1)
+struct FDE_CSSLENGTH {
+ FDE_CSSLENGTH& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ m_iData = eUnit;
+ return *this;
+ }
+ FDE_CSSLENGTH& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ m_iData = ((FX_INTPTR)(fValue * 1024.0f) << FDE_CSSUNITBITS) | eUnit;
+ return *this;
+ }
+ FDE_CSSLENGTHUNIT GetUnit() const
+ {
+ return (FDE_CSSLENGTHUNIT)(m_iData & FDE_CSSUNITMASK);
+ }
+ FX_FLOAT GetValue() const
+ {
+ return (m_iData >> FDE_CSSUNITBITS) / 1024.0f;
+ }
+ FX_BOOL NonZero() const
+ {
+ return (m_iData >> FDE_CSSUNITBITS) != 0;
+ }
+private:
+ FX_INTPTR m_iData;
+};
+struct FDE_CSSPOINT {
+ FDE_CSSPOINT& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ x.Set(eUnit);
+ y.Set(eUnit);
+ return *this;
+ }
+ FDE_CSSPOINT& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ x.Set(eUnit, fValue);
+ y.Set(eUnit, fValue);
+ return *this;
+ }
+ FDE_CSSLENGTH x, y;
+};
+struct FDE_CSSSIZE {
+ FDE_CSSSIZE& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ cx.Set(eUnit);
+ cy.Set(eUnit);
+ return *this;
+ }
+ FDE_CSSSIZE& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ cx.Set(eUnit, fValue);
+ cy.Set(eUnit, fValue);
+ return *this;
+ }
+ FDE_CSSLENGTH cx, cy;
+};
+struct FDE_CSSRECT {
+ FDE_CSSRECT& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ left.Set(eUnit);
+ top.Set(eUnit);
+ right.Set(eUnit);
+ bottom.Set(eUnit);
+ return *this;
+ }
+ FDE_CSSRECT& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ left.Set(eUnit, fValue);
+ top.Set(eUnit, fValue);
+ right.Set(eUnit, fValue);
+ bottom.Set(eUnit, fValue);
+ return *this;
+ }
+
+ FDE_CSSLENGTH left, top, right, bottom;
+};
+enum FDE_CSSBKGATTACHMENT {
+ FDE_CSSBKGATTACHMENT_Scroll,
+ FDE_CSSBKGATTACHMENT_Fixed,
+};
+enum FDE_CSSBKGREPEAT {
+ FDE_CSSBKGREPEAT_Repeat,
+ FDE_CSSBKGREPEAT_RepeatX,
+ FDE_CSSBKGREPEAT_RepeatY,
+ FDE_CSSBKGREPEAT_NoRepeat,
+};
+enum FDE_CSSBORDERSTYLE {
+ FDE_CSSBORDERSTYLE_None,
+ FDE_CSSBORDERSTYLE_Hidden,
+ FDE_CSSBORDERSTYLE_Dotted,
+ FDE_CSSBORDERSTYLE_Dashed,
+ FDE_CSSBORDERSTYLE_Solid,
+ FDE_CSSBORDERSTYLE_Double,
+ FDE_CSSBORDERSTYLE_Groove,
+ FDE_CSSBORDERSTYLE_Ridge,
+ FDE_CSSBORDERSTYLE_Inset,
+ FDE_CSSBORDERSTYLE_outset,
+};
+enum FDE_CSSCLEAR {
+ FDE_CSSCLEAR_None,
+ FDE_CSSCLEAR_Left,
+ FDE_CSSCLEAR_Right,
+ FDE_CSSCLEAR_Both,
+};
+enum FDE_CSSDISPLAY {
+ FDE_CSSDISPLAY_None,
+ FDE_CSSDISPLAY_ListItem,
+ FDE_CSSDISPLAY_RunIn,
+ FDE_CSSDISPLAY_Block,
+ FDE_CSSDISPLAY_Inline,
+ FDE_CSSDISPLAY_InlineBlock,
+ FDE_CSSDISPLAY_InlineTable,
+ FDE_CSSDISPLAY_Table,
+ FDE_CSSDISPLAY_TableRow,
+ FDE_CSSDISPLAY_TableCell,
+ FDE_CSSDISPLAY_TableCaption,
+ FDE_CSSDISPLAY_TableColumn,
+ FDE_CSSDISPLAY_TableRowGroup,
+ FDE_CSSDISPLAY_TableColumnGroup,
+ FDE_CSSDISPLAY_TableHeaderGroup,
+ FDE_CSSDISPLAY_TableFooterGroup,
+ FDE_CSSDISPLAY_Ruby,
+ FDE_CSSDISPLAY_RubyBase,
+ FDE_CSSDISPLAY_RubyText,
+ FDE_CSSDISPLSY_RubyBaseGroup,
+ FDE_CSSDISPLAY_RubyTextGroup,
+};
+enum FDE_CSSVISIBILITY {
+ FDE_CSSVISIBILITY_Visible,
+ FDE_CSSVISIBILITY_Hidden,
+ FDE_CSSVISIBILITY_Collapse,
+};
+enum FDE_CSSFONTSTYLE {
+ FDE_CSSFONTSTYLE_Normal,
+ FDE_CSSFONTSTYLE_Italic,
+};
+enum FDE_CSSFLOAT {
+ FDE_CSSFLOAT_None,
+ FDE_CSSFLOAT_Left,
+ FDE_CSSFLOAT_Right,
+};
+enum FDE_CSSWRITINGMODE {
+ FDE_CSSWRITINGMODE_HorizontalTb,
+ FDE_CSSWRITINGMODE_VerticalRl,
+ FDE_CSSWRITINGMODE_VerticalLr,
+};
+enum FDE_CSSWORDBREAK {
+ FDE_CSSWORDBREAK_Normal,
+ FDE_CSSWORDBREAK_KeepAll,
+ FDE_CSSWORDBREAK_BreakAll,
+ FDE_CSSWORDBREAK_KeepWords,
+};
+enum FDE_CSSPAGEBREAK {
+ FDE_CSSPAGEBREAK_Auto,
+ FDE_CSSPAGEBREAK_Always,
+ FDE_CSSPAGEBREAK_Avoid,
+ FDE_CSSPAGEBREAK_Left,
+ FDE_CSSPAGEBREAK_Right,
+};
+enum FDE_CSSOVERFLOW {
+ FDE_CSSOVERFLOW_Visible,
+ FDE_CSSOVERFLOW_Hidden,
+ FDE_CSSOVERFLOW_Scroll,
+ FDE_CSSOVERFLOW_Auto,
+ FDE_CSSOVERFLOW_NoDisplay,
+ FDE_CSSOVERFLOW_NoContent,
+};
+enum FDE_CSSLINEBREAK {
+ FDE_CSSLINEBREAK_Auto,
+ FDE_CSSLINEBREAK_Loose,
+ FDE_CSSLINEBREAK_Normal,
+ FDE_CSSLINEBREAK_Strict,
+};
+enum FDE_CSSTEXTEMPHASISFILL {
+ FDE_CSSTEXTEMPHASISFILL_Filled,
+ FDE_CSSTEXTEMPHASISFILL_Open,
+};
+enum FDE_CSSTEXTEMPHASISMARK {
+ FDE_CSSTEXTEMPHASISMARK_None,
+ FDE_CSSTEXTEMPHASISMARK_Auto,
+ FDE_CSSTEXTEMPHASISMARK_Dot,
+ FDE_CSSTEXTEMPHASISMARK_Circle,
+ FDE_CSSTEXTEMPHASISMARK_DoubleCircle,
+ FDE_CSSTEXTEMPHASISMARK_Triangle,
+ FDE_CSSTEXTEMPHASISMARK_Sesame,
+ FDE_CSSTEXTEMPHASISMARK_Custom,
+};
+enum FDE_CSSTEXTCOMBINE {
+ FDE_CSSTEXTCOMBINE_Horizontal,
+ FDE_CSSTEXTCOMBINE_None,
+};
+enum FDE_CSSCURSOR {
+ FDE_CSSCURSOR_Auto,
+ FDE_CSSCURSOR_Crosshair,
+ FDE_CSSCURSOR_Default,
+ FDE_CSSCURSOR_Pointer,
+ FDE_CSSCURSOR_Move,
+ FDE_CSSCURSOR_EResize,
+ FDE_CSSCURSOR_NeResize,
+ FDE_CSSCURSOR_NwResize,
+ FDE_CSSCURSOR_NResize,
+ FDE_CSSCURSOR_SeResize,
+ FDE_CSSCURSOR_SwResize,
+ FDE_CSSCURSOR_SResize,
+ FDE_CSSCURSOR_WResize,
+ FDE_CSSCURSOR_Text,
+ FDE_CSSCURSOR_Wait,
+ FDE_CSSCURSOR_Help,
+ FDE_CSSCURSOR_Progress,
+};
+enum FDE_CSSPOSITION {
+ FDE_CSSPOSITION_Static,
+ FDE_CSSPOSITION_Relative,
+ FDE_CSSPOSITION_Absolute,
+ FDE_CSSPOSITION_Fixed,
+};
+enum FDE_CSSCAPTIONSIDE {
+ FDE_CSSCAPTIONSIDE_Top,
+ FDE_CSSCAPTIONSIDE_Bottom,
+ FDE_CSSCAPTIONSIDE_Left,
+ FDE_CSSCAPTIONSIDE_Right,
+ FDE_CSSCAPTIONSIDE_Before,
+ FDE_CSSCAPTIONSIDE_After,
+};
+enum FDE_CSSRUBYALIGN {
+ FDE_CSSRUBYALIGN_Auto,
+ FDE_CSSRUBYALIGN_Start,
+ FDE_CSSRUBYALIGN_Left,
+ FDE_CSSRUBYALIGN_Center,
+ FDE_CSSRUBYALIGN_End,
+ FDE_CSSRUBYALIGN_Right,
+ FDE_CSSRUBYALIGN_DistributeLetter,
+ FDE_CSSRUBYALIGN_DistributeSpace,
+ FDE_CSSRUBYALIGN_LineEdge,
+};
+enum FDE_CSSRUBYOVERHANG {
+ FDE_CSSRUBYOVERHANG_Auto,
+ FDE_CSSRUBYOVERHANG_Start,
+ FDE_CSSRUBYOVERHANG_End,
+ FDE_CSSRUBYOVERHANG_None,
+};
+enum FDE_CSSRUBYPOSITION {
+ FDE_CSSRUBYPOSITION_Before,
+ FDE_CSSRUBYPOSITION_After,
+ FDE_CSSRUBYPOSITION_Right,
+ FDE_CSSRUBYPOSITION_Inline,
+};
+enum FDE_CSSRUBYSPAN {
+ FDE_CSSRUBYSPAN_None,
+ FDE_CSSRUBYSPAN_Attr,
+};
+enum FDE_CSSTEXTALIGN {
+ FDE_CSSTEXTALIGN_Left,
+ FDE_CSSTEXTALIGN_Right,
+ FDE_CSSTEXTALIGN_Center,
+ FDE_CSSTEXTALIGN_Justify,
+ FDE_CSSTEXTALIGN_JustifyAll,
+};
+enum FDE_CSSVERTICALALIGN {
+ FDE_CSSVERTICALALIGN_Baseline,
+ FDE_CSSVERTICALALIGN_Sub,
+ FDE_CSSVERTICALALIGN_Super,
+ FDE_CSSVERTICALALIGN_Top,
+ FDE_CSSVERTICALALIGN_TextTop,
+ FDE_CSSVERTICALALIGN_Middle,
+ FDE_CSSVERTICALALIGN_Bottom,
+ FDE_CSSVERTICALALIGN_TextBottom,
+ FDE_CSSVERTICALALIGN_Number,
+};
+enum FDE_CSSLISTSTYLETYPE {
+ FDE_CSSLISTSTYLETYPE_Disc,
+ FDE_CSSLISTSTYLETYPE_Circle,
+ FDE_CSSLISTSTYLETYPE_Square,
+ FDE_CSSLISTSTYLETYPE_Decimal,
+ FDE_CSSLISTSTYLETYPE_DecimalLeadingZero,
+ FDE_CSSLISTSTYLETYPE_LowerRoman,
+ FDE_CSSLISTSTYLETYPE_UpperRoman,
+ FDE_CSSLISTSTYLETYPE_LowerGreek,
+ FDE_CSSLISTSTYLETYPE_LowerLatin,
+ FDE_CSSLISTSTYLETYPE_UpperLatin,
+ FDE_CSSLISTSTYLETYPE_Armenian,
+ FDE_CSSLISTSTYLETYPE_Georgian,
+ FDE_CSSLISTSTYLETYPE_LowerAlpha,
+ FDE_CSSLISTSTYLETYPE_UpperAlpha,
+ FDE_CSSLISTSTYLETYPE_None,
+ FDE_CSSLISTSTYLETYPE_CjkIdeographic,
+ FDE_CSSLISTSTYLETYPE_Hebrew,
+ FDE_CSSLISTSTYLETYPE_Hiragana,
+ FDE_CSSLISTSTYLETYPE_HiraganaIroha,
+ FDE_CSSLISTSTYLETYPE_Katakana,
+ FDE_CSSLISTSTYLETYPE_KatakanaIroha,
+};
+enum FDE_CSSLISTSTYLEPOSITION {
+ FDE_CSSLISTSTYLEPOSITION_Outside,
+ FDE_CSSLISTSTYLEPOSITION_Inside,
+};
+enum FDE_CSSWHITESPACE {
+ FDE_CSSWHITESPACE_Normal,
+ FDE_CSSWHITESPACE_Pre,
+ FDE_CSSWHITESPACE_Nowrap,
+ FDE_CSSWHITESPACE_PreWrap,
+ FDE_CSSWHITESPACE_PreLine,
+};
+enum FDE_CSSFONTVARIANT {
+ FDE_CSSFONTVARIANT_Normal,
+ FDE_CSSFONTVARIANT_SmallCaps,
+};
+enum FDE_CSSTEXTTRANSFORM {
+ FDE_CSSTEXTTRANSFORM_None,
+ FDE_CSSTEXTTRANSFORM_Capitalize,
+ FDE_CSSTEXTTRANSFORM_UpperCase,
+ FDE_CSSTEXTTRANSFORM_LowerCase,
+};
+enum FDE_CSSTEXTDECORATION {
+ FDE_CSSTEXTDECORATION_None = 0,
+ FDE_CSSTEXTDECORATION_Underline = 1,
+ FDE_CSSTEXTDECORATION_Overline = 2,
+ FDE_CSSTEXTDECORATION_LineThrough = 4,
+ FDE_CSSTEXTDECORATION_Blink = 8,
+ FDE_CSSTEXTDECORATION_Double = 16,
+};
+class IFDE_CSSRubyStyle
+{
+public:
+ virtual FDE_CSSRUBYALIGN GetRubyAlign() const = 0;
+ virtual FDE_CSSRUBYOVERHANG GetRubyOverhang() const = 0;
+ virtual FDE_CSSRUBYPOSITION GetRubyPosition() const = 0;
+ virtual FDE_CSSRUBYSPAN GetRubySpanType() const = 0;
+ virtual IFDE_CSSValue* GetRubySpanAttr() const = 0;
+};
+class IFDE_CSSMultiColumnStyle
+{
+public:
+ virtual const FDE_CSSLENGTH& GetColumnCount() const = 0;
+ virtual const FDE_CSSLENGTH& GetColumnGap() const = 0;
+ virtual FX_ARGB GetColumnRuleColor() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetColumnRuleStyle() const = 0;
+ virtual const FDE_CSSLENGTH& GetColumnRuleWidth() const = 0;
+ virtual const FDE_CSSLENGTH& GetColumnWidth() const = 0;
+ virtual void SetColumnCount(const FDE_CSSLENGTH &columnCount) = 0;
+ virtual void SetColumnGap(const FDE_CSSLENGTH &columnGap) = 0;
+ virtual void SetColumnRuleColor(FX_ARGB dwColumnRuleColor) = 0;
+ virtual void SetColumnRuleStyle(FDE_CSSBORDERSTYLE eColumnRuleStyle) = 0;
+ virtual void SetColumnRuleWidth(const FDE_CSSLENGTH &columnRuleWidth) = 0;
+ virtual void SetColumnWidth(const FDE_CSSLENGTH &columnWidth) = 0;
+};
+class IFDE_CSSGeneratedContentStyle
+{
+public:
+ virtual FX_INT32 CountCounters() = 0;
+ virtual FX_LPCWSTR GetCounterIdentifier(FX_INT32 index) = 0;
+ virtual FX_BOOL GetCounterReset(FX_INT32 index, FX_INT32 &iValue) = 0;
+ virtual FX_BOOL GetCounterIncrement(FX_INT32 index, FX_INT32 &iValue) = 0;
+ virtual IFDE_CSSValueList* GetContent() const = 0;
+ virtual FX_INT32 CountQuotes() const = 0;
+ virtual FX_LPCWSTR GetQuotes(FX_INT32 index) const = 0;
+};
+class IFDE_CSSFontStyle
+{
+public:
+ virtual FX_INT32 CountFontFamilies() const = 0;
+ virtual FX_LPCWSTR GetFontFamily(FX_INT32 index) const = 0;
+ virtual FX_WORD GetFontWeight() const = 0;
+ virtual FDE_CSSFONTVARIANT GetFontVariant() const = 0;
+ virtual FDE_CSSFONTSTYLE GetFontStyle() const = 0;
+ virtual FX_FLOAT GetFontSize() const = 0;
+ virtual FX_ARGB GetColor() const = 0;
+ virtual void SetFontWeight(FX_WORD wFontWeight) = 0;
+ virtual void SetFontVariant(FDE_CSSFONTVARIANT eFontVariant) = 0;
+ virtual void SetFontStyle(FDE_CSSFONTSTYLE eFontStyle) = 0;
+ virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
+ virtual void SetColor(FX_ARGB dwFontColor) = 0;
+};
+class IFDE_CSSBoundaryStyle
+{
+public:
+ virtual FX_ARGB GetBorderLeftColor() const = 0;
+ virtual FX_ARGB GetBorderTopColor() const = 0;
+ virtual FX_ARGB GetBorderRightColor() const = 0;
+ virtual FX_ARGB GetBorderBottomColor() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderLeftStyle() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderTopStyle() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderRightStyle() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderBottomStyle() const = 0;
+ virtual const FDE_CSSRECT* GetBorderWidth() const = 0;
+ virtual const FDE_CSSRECT* GetMarginWidth() const = 0;
+ virtual const FDE_CSSRECT* GetPaddingWidth() const = 0;
+ virtual void SetBorderLeftColor(FX_ARGB dwBorderColor) = 0;
+ virtual void SetBorderTopColor(FX_ARGB dwBorderColor) = 0;
+ virtual void SetBorderRightColor(FX_ARGB dwBorderColor) = 0;
+ virtual void SetBorderBottomColor(FX_ARGB dwBorderColor) = 0;
+
+ virtual void SetBorderLeftStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+ virtual void SetBorderTopStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+ virtual void SetBorderRightStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+ virtual void SetBorderBottomStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+
+ virtual void SetBorderWidth(const FDE_CSSRECT &rect) = 0;
+ virtual void SetMarginWidth(const FDE_CSSRECT &rect) = 0;
+ virtual void SetPaddingWidth(const FDE_CSSRECT &rect) = 0;
+};
+class IFDE_CSSPositionStyle
+{
+public:
+ virtual FDE_CSSDISPLAY GetDisplay() const = 0;
+ virtual const FDE_CSSSIZE& GetBoxSize() const = 0;
+ virtual const FDE_CSSSIZE& GetMinBoxSize() const = 0;
+ virtual const FDE_CSSSIZE& GetMaxBoxSize() const = 0;
+ virtual FDE_CSSFLOAT GetFloat() const = 0;
+ virtual FDE_CSSCLEAR GetClear() const = 0;
+ virtual FDE_CSSPOSITION GetPosition() const = 0;
+ virtual FDE_CSSLENGTH GetTop() const = 0;
+ virtual FDE_CSSLENGTH GetBottom() const = 0;
+ virtual FDE_CSSLENGTH GetLeft() const = 0;
+ virtual FDE_CSSLENGTH GetRight() const = 0;
+ virtual void SetDisplay(FDE_CSSDISPLAY eDisplay) = 0;
+ virtual void SetBoxSize(const FDE_CSSSIZE &boxSize) = 0;
+ virtual void SetMinBoxSize(const FDE_CSSSIZE &minBoxSize) = 0;
+ virtual void SetMaxBoxSize(const FDE_CSSSIZE &maxBoxSize) = 0;
+ virtual void SetFloat(FDE_CSSFLOAT eFloat) = 0;
+ virtual void SetClear(FDE_CSSCLEAR eClear) = 0;
+};
+class IFDE_CSSParagraphStyle
+{
+public:
+ virtual FX_FLOAT GetLineHeight() const = 0;
+ virtual FDE_CSSWHITESPACE GetWhiteSpace() const = 0;
+ virtual const FDE_CSSLENGTH& GetTextIndent() const = 0;
+ virtual FDE_CSSTEXTALIGN GetTextAlign() const = 0;
+ virtual FDE_CSSVERTICALALIGN GetVerticalAlign() const = 0;
+ virtual FX_FLOAT GetNumberVerticalAlign() const = 0;
+ virtual FDE_CSSTEXTTRANSFORM GetTextTransform() const = 0;
+ virtual FX_DWORD GetTextDecoration() const = 0;
+ virtual const FDE_CSSLENGTH& GetLetterSpacing() const = 0;
+ virtual const FDE_CSSLENGTH& GetWordSpacing() const = 0;
+ virtual FDE_CSSWRITINGMODE GetWritingMode() const = 0;
+ virtual FDE_CSSWORDBREAK GetWordBreak() const = 0;
+ virtual FX_INT32 GetWidows() const = 0;
+ virtual FX_ARGB GetTextEmphasisColor() const = 0;
+ virtual FDE_CSSPAGEBREAK GetPageBreakBefore() const = 0;
+ virtual FDE_CSSPAGEBREAK GetPageBreakAfter() const = 0;
+ virtual FDE_CSSPAGEBREAK GetPageBreakInside() const = 0;
+ virtual FX_INT32 GetOrphans() const = 0;
+ virtual FDE_CSSLINEBREAK GetLineBreak() const = 0;
+ virtual FDE_CSSTEXTEMPHASISMARK GetTextEmphasisMark() const = 0;
+ virtual FDE_CSSTEXTEMPHASISFILL GetTextEmphasisFill() const = 0;
+ virtual FX_LPCWSTR GetTextEmphasisCustom() const = 0;
+ virtual FDE_CSSTEXTCOMBINE GetTextCombineType() const = 0;
+ virtual FX_BOOL HasTextCombineNumber() const = 0;
+ virtual FX_FLOAT GetTextCombineNumber() const = 0;
+ virtual void SetLineHeight(FX_FLOAT fLineHeight) = 0;
+ virtual void SetWhiteSpace(FDE_CSSWHITESPACE eWhiteSpace) = 0;
+ virtual void SetTextIndent(const FDE_CSSLENGTH &textIndent) = 0;
+ virtual void SetTextAlign(FDE_CSSTEXTALIGN eTextAlign) = 0;
+ virtual void SetVerticalAlign(FDE_CSSVERTICALALIGN eVerticalAlign) = 0;
+ virtual void SetNumberVerticalAlign(FX_FLOAT fAlign) = 0;
+ virtual void SetTextTransform(FDE_CSSTEXTTRANSFORM eTextTransform) = 0;
+ virtual void SetTextDecoration(FX_DWORD dwTextDecoration) = 0;
+ virtual void SetLetterSpacing(const FDE_CSSLENGTH &letterSpacing) = 0;
+ virtual void SetWordSpacing(const FDE_CSSLENGTH &wordSpacing) = 0;
+ virtual void SetWritingMode(FDE_CSSWRITINGMODE eWritingMode) = 0;
+ virtual void SetWordBreak(FDE_CSSWORDBREAK eWordBreak) = 0;
+ virtual void SetWidows(FX_INT32 iWidows) = 0;
+ virtual void SetTextEmphasisColor(FX_ARGB dwTextEmphasisColor) = 0;
+ virtual void SetPageBreakBefore(FDE_CSSPAGEBREAK ePageBreakBefore) = 0;
+ virtual void SetPageBreakAfter(FDE_CSSPAGEBREAK ePageBreakAfter) = 0;
+ virtual void SetPageBreakInside(FDE_CSSPAGEBREAK ePageBreakInside) = 0;
+ virtual void SetOrphans(FX_INT32 iOrphans) = 0;
+ virtual void SetLineBreak(FDE_CSSLINEBREAK eLineBreak) = 0;
+};
+class IFDE_CSSBackgroundStyle
+{
+public:
+ virtual FX_ARGB GetBKGColor() const = 0;
+ virtual FX_LPCWSTR GetBKGImage() const = 0;
+ virtual FDE_CSSBKGREPEAT GetBKGRepeat() const = 0;
+ virtual FDE_CSSBKGATTACHMENT GetBKGAttachment() const = 0;
+ virtual const FDE_CSSPOINT& GetBKGPosition() const = 0;
+ virtual void SetBKGColor(FX_ARGB dwBKGColor) = 0;
+ virtual void SetBKGPosition(const FDE_CSSPOINT &bkgPosition) = 0;
+};
+class IFDE_CSSListStyle
+{
+public:
+ virtual FDE_CSSLISTSTYLETYPE GetListStyleType() const = 0;
+ virtual FDE_CSSLISTSTYLEPOSITION GetListStylePosition() const = 0;
+ virtual FX_LPCWSTR GetListStyleImage() const = 0;
+ virtual void SetListStyleType(FDE_CSSLISTSTYLETYPE eListStyleType) = 0;
+ virtual void SetListStylePosition(FDE_CSSLISTSTYLEPOSITION eListStylePosition) = 0;
+};
+class IFDE_CSSTableStyle
+{
+public:
+ virtual FDE_CSSCAPTIONSIDE GetCaptionSide() const = 0;
+};
+class IFDE_CSSVisualStyle
+{
+public:
+ virtual FDE_CSSVISIBILITY GetVisibility() const = 0;
+ virtual FDE_CSSOVERFLOW GetOverflowX() const = 0;
+ virtual FDE_CSSOVERFLOW GetOverflowY() const = 0;
+ virtual void SetVisibility(FDE_CSSVISIBILITY eVisibility) = 0;
+};
+class IFDE_CSSComputedStyle : public IFX_Unknown
+{
+public:
+ virtual void Reset() = 0;
+ virtual IFDE_CSSFontStyle* GetFontStyles() const = 0;
+ virtual IFDE_CSSBoundaryStyle* GetBoundaryStyles() const = 0;
+ virtual IFDE_CSSPositionStyle* GetPositionStyles() const = 0;
+ virtual IFDE_CSSParagraphStyle* GetParagraphStyles() const = 0;
+ virtual IFDE_CSSBackgroundStyle* GetBackgroundStyles() const = 0;
+ virtual IFDE_CSSVisualStyle* GetVisualStyles() const = 0;
+ virtual IFDE_CSSListStyle* GetListStyles() const = 0;
+ virtual IFDE_CSSMultiColumnStyle* GetMultiColumnStyle() const = 0;
+ virtual IFDE_CSSTableStyle* GetTableStyle() const = 0;
+ virtual IFDE_CSSGeneratedContentStyle* GetGeneratedContentStyle() const = 0;
+ virtual IFDE_CSSRubyStyle* GetRubyStyle() const = 0;
+ virtual FX_BOOL GetCustomStyle(FX_WSTR wsName, CFX_WideString &wsValue) const = 0;
+};
+enum FDE_CSSSTYLESHEETGROUP {
+ FDE_CSSSTYLESHEETGROUP_UserAgent,
+ FDE_CSSSTYLESHEETGROUP_User,
+ FDE_CSSSTYLESHEETGROUP_Author,
+ FDE_CSSSTYLESHEETGROUP_MAX,
+};
+enum FDE_CSSSTYLESHEETPRIORITY {
+ FDE_CSSSTYLESHEETPRIORITY_High,
+ FDE_CSSSTYLESHEETPRIORITY_Mid,
+ FDE_CSSSTYLESHEETPRIORITY_Low,
+ FDE_CSSSTYLESHEETPRIORITY_MAX,
+};
+class IFDE_CSSTagProvider
+{
+public:
+ virtual CFX_WideStringC GetTagName() = 0;
+ virtual FX_POSITION GetFirstAttribute() = 0;
+ virtual void GetNextAttribute(FX_POSITION &pos, CFX_WideStringC &wsAttr, CFX_WideStringC &wsValue) = 0;
+};
+class IFDE_CSSAccelerator
+{
+public:
+ virtual void OnEnterTag(IFDE_CSSTagProvider *pTag) = 0;
+ virtual void OnLeaveTag(IFDE_CSSTagProvider *pTag) = 0;
+};
+class IFDE_CSSStyleSelector
+{
+public:
+ static IFDE_CSSStyleSelector* Create();
+ virtual void Release() = 0;
+ virtual void SetFontMgr(IFX_FontMgr *pFontMgr) = 0;
+ virtual void SetDefFontSize(FX_FLOAT fFontSize) = 0;
+ virtual FX_BOOL SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType, IFDE_CSSStyleSheet *pSheet) = 0;
+ virtual FX_BOOL SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType, const CFDE_CSSStyleSheetArray *pArray) = 0;
+ virtual void SetStylePriority(FDE_CSSSTYLESHEETGROUP eType, FDE_CSSSTYLESHEETPRIORITY ePriority) = 0;
+ virtual void UpdateStyleIndex(FX_DWORD dwMediaList) = 0;
+ virtual IFDE_CSSAccelerator* InitAccelerator() = 0;
+ virtual IFDE_CSSComputedStyle* CreateComputedStyle(IFDE_CSSComputedStyle *pParentStyle) = 0;
+ virtual FX_INT32 MatchDeclarations(IFDE_CSSTagProvider *pTag, CFDE_CSSDeclarationArray &matchedDecls, FDE_CSSPERSUDO ePersudoType = FDE_CSSPERSUDO_NONE) = 0;
+ virtual void ComputeStyle(IFDE_CSSTagProvider *pTag, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_img.h b/xfa/src/fdp/include/fde_img.h
new file mode 100644
index 0000000000..808bc4c304
--- /dev/null
+++ b/xfa/src/fdp/include/fde_img.h
@@ -0,0 +1,76 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_IMAGE
+#define _FDE_IMAGE
+class IFDE_Image;
+#define FDE_IMAGEFORMAT_Unknown -1
+#define FDE_IMAGEFORMAT_BMP 0
+#define FDE_IMAGEFORMAT_GIF 1
+#define FDE_IMAGEFORMAT_JPEG 2
+#define FDE_IMAGEFORMAT_PNG 3
+#define FDE_IMAGEFORMAT_TIFF 4
+#define FDE_IMAGEFORMAT_JPEG2000 5
+#define FDE_IMAGEFORMAT_JBig2 6
+class IFDE_Image
+{
+public:
+ static IFDE_Image* Create(IFX_Stream *pStream, FX_INT32 iFormat = FDE_IMAGEFORMAT_Unknown);
+ virtual void Release() = 0;
+ virtual FX_BOOL LoadImage() = 0;
+ virtual void FreeImage() = 0;
+ virtual FX_INT32 CountFrames() const = 0;
+ virtual FX_BOOL LoadFrame(FX_INT32 index) = 0;
+ virtual CFX_DIBitmap* GetFrameImage() = 0;
+ virtual FX_INT32 GetImageFormat() const = 0;
+ virtual FX_INT32 GetImageWidth() const = 0;
+ virtual FX_INT32 GetImageHeight() const = 0;
+ virtual FX_INT32 GetDelayTime(FX_INT32 iFrameIndex) const = 0;
+ virtual FX_INT32 GetLoopCount() const = 0;
+ virtual FX_BOOL StartLoadImage(CFX_DIBitmap *pDIBitmap, FX_INT32 dibX, FX_INT32 dibY, FX_INT32 dibCX, FX_INT32 dibCY,
+ FX_INT32 imgX, FX_INT32 imgY, FX_INT32 imgCX, FX_INT32 imgCY, FX_INT32 iFrameIndex = 0) = 0;
+ virtual FX_INT32 DoLoadImage(IFX_Pause *pPause = NULL) = 0;
+ virtual void StopLoadImage() = 0;
+};
+#define FDE_IMAGEFILTER_Unknown -1
+#define FDE_IMAGEFILTER_Opacity 0
+#define FDE_IMAGEFILTER_GrayScale 1
+#define FDE_IMAGEFILTER_BlackWhite 2
+#define FDE_IMAGEFILTER_InvertColor 3
+#define FDE_IMAGEFILTER_TransparentColor 4
+#define FDE_IMAGEFILTER_MaskColor 5
+#define FDE_IMAGEFILTER_Brightness 6
+#define FDE_IMAGEFILTER_Contrast 7
+typedef struct _FDE_IMAGEFILTERPARAMS : public CFX_Target {
+ FX_INT32 iFilterType;
+} FDE_IMAGEFILTERPARAMS, * FDE_LPIMAGEFILTERPARAMS;
+typedef FDE_IMAGEFILTERPARAMS const * FDE_LPCIMAGEFILTERPARAMS;
+typedef struct _FDE_OPACITYPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_INT32 iOpacity;
+} FDE_OPACITYPARAMS, * FDE_LPOPACITYPARAMS;
+typedef FDE_OPACITYPARAMS const * FDE_LPCOPACITYPARAMS;
+typedef struct _FDE_BLACKWHITEPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_ARGB dwBlackColor;
+ FX_ARGB dwWhiteColor;
+} FDE_BLACKWHITEPARAMS, * FDE_LPBLACKWHITEPARAMS;
+typedef FDE_BLACKWHITEPARAMS const * FDE_LPCBLACKWHITEPARAMS;
+typedef struct _FDE_TRANSPARENTPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_ARGB color;
+} FDE_TRANSPARENTPARAMS, * FDE_LPTRANSPARENTPARAMS;
+typedef FDE_TRANSPARENTPARAMS const * FDE_LPCTRANSPARENTPARAMS;
+typedef struct _FDE_MASKCOLORPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_ARGB color;
+} FDE_MASKCOLORPARAMS, * FDE_LPMASKCOLORPARAMS;
+typedef FDE_MASKCOLORPARAMS const * FDE_LPCMASKCOLORPARAMS;
+typedef struct _FDE_BRIGHTNESSPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_INT32 iBrightness;
+} FDE_BRIGHTNESSPARAMS, * FDE_LPBRIGHTNESSPARAMS;
+typedef FDE_BRIGHTNESSPARAMS const * FDE_LPCBRIGHTNESSPARAMS;
+typedef struct _FDE_CONTRASTPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_INT32 iContrast;
+} FDE_CONTRASTPARAMS, * FDE_LPCONTRASTPARAMS;
+typedef FDE_CONTRASTPARAMS const * FDE_LPCCONTRASTPARAMS;
+#endif
diff --git a/xfa/src/fdp/include/fde_mem.h b/xfa/src/fdp/include/fde_mem.h
new file mode 100644
index 0000000000..516e67c945
--- /dev/null
+++ b/xfa/src/fdp/include/fde_mem.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_MEM
+#define _FDE_MEM
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define FDE_Alloc(size) FX_Alloc(FX_BYTE, size)
+#define FDE_Realloc(ptr, newSize) FX_Realloc(FX_BYTE, ptr, newSize)
+#define FDE_Free(ptr) FX_Free(ptr)
+#define FDE_New FXTARGET_New
+#define FDE_Delete FXTARGET_Delete
+#define FDE_NewWith FXTARGET_NewWith
+#define FDE_DeleteWith FXTARGET_DeleteWith
+
+#ifdef __cplusplus
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/include/fde_pen.h b/xfa/src/fdp/include/fde_pen.h
new file mode 100644
index 0000000000..7730b6a964
--- /dev/null
+++ b/xfa/src/fdp/include/fde_pen.h
@@ -0,0 +1,61 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_PEN
+#define _FDE_PEN
+class IFDE_Pen;
+#define FDE_PENTYPE_Unknown FDE_BRUSHTYPE_Unknown
+#define FDE_PENTYPE_SolidColor FDE_BRUSHTYPE_Solid
+#define FDE_PENTYPE_HatchBrush FDE_BRUSHTYPE_Hatch
+#define FDE_PENTYPE_TextureBrush FDE_BRUSHTYPE_Texture
+#define FDE_PENTYPE_LinearGradient FDE_BRUSHTYPE_LinearGradient
+#define FDE_PENTYPE_MAX FDE_BRUSHTYPE_MAX
+#define FDE_DASHSTYLE_Solid 0
+#define FDE_DASHSTYLE_Dash 1
+#define FDE_DASHSTYLE_Dot 2
+#define FDE_DASHSTYLE_DashDot 3
+#define FDE_DASHSTYLE_DashDotDot 4
+#define FDE_DASHSTYLE_Customized 5
+#define FDE_LINEJOIN_Miter 0
+#define FDE_LINEJOIN_Round 1
+#define FDE_LINEJOIN_Bevel 2
+#define FDE_LINECAP_Flat 0
+#define FDE_LINECAP_Round 1
+#define FDE_LINECAP_Square 2
+typedef struct _FDE_COMPOUNDPATTERN {
+ FX_FLOAT pos;
+ FX_FLOAT width;
+} FDE_COMPOUNDPATTERN, * FDE_LPCOMPOUNDPATTERN;
+typedef FDE_COMPOUNDPATTERN const * FDE_LPCCOMPOUNDPATTERN;
+typedef CFX_ArrayTemplate<FDE_COMPOUNDPATTERN> CFDE_CompoundPatterns;
+class IFDE_Pen
+{
+public:
+ static IFDE_Pen* Create();
+ virtual void Release() = 0;
+ virtual FX_INT32 GetType() const = 0;
+ virtual FX_ARGB GetColor() const = 0;
+ virtual void SetColor(FX_ARGB color) = 0;
+ virtual IFDE_Brush* GetBrush() const = 0;
+ virtual void SetBrush(IFDE_Brush *pBrush, FX_BOOL bAutoRelease) = 0;
+ virtual FX_INT32 GetLineCap() const = 0;
+ virtual void SetLineCap(FX_INT32 iLineCap) = 0;
+ virtual FX_INT32 GetDashStyle() const = 0;
+ virtual void SetDashStyle(FX_INT32 iDashStyle) = 0;
+ virtual FX_FLOAT GetDashPhase() const = 0;
+ virtual void SetDashPhase(FX_FLOAT fPhase) = 0;
+ virtual FX_INT32 CountDashArray() const = 0;
+ virtual FX_INT32 GetDashArray(CFX_FloatArray &dashArray) const = 0;
+ virtual void SetDashArray(const CFX_FloatArray &dashArray) = 0;
+ virtual FX_INT32 GetLineJoin() const = 0;
+ virtual void SetLineJoin(FX_INT32 iLineJoin) = 0;
+ virtual FX_FLOAT GetMiterLimit() const = 0;
+ virtual void SetMiterLimit(FX_FLOAT fMiterLimit) = 0;
+ virtual FX_INT32 CountCompoundPatterns() const = 0;
+ virtual FX_BOOL GetCompoundPatterns(CFDE_CompoundPatterns &compoundPatterns) const = 0;
+ virtual FX_BOOL SetCompoundPatterns(const CFDE_CompoundPatterns &compoundPatterns) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_psr.h b/xfa/src/fdp/include/fde_psr.h
new file mode 100644
index 0000000000..64070e6648
--- /dev/null
+++ b/xfa/src/fdp/include/fde_psr.h
@@ -0,0 +1,94 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_PARSER
+#define _FDE_PARSER
+enum FDE_VISUALOBJTYPE {
+ FDE_VISUALOBJ_Canvas = 0x00,
+ FDE_VISUALOBJ_Text = 0x01 ,
+ FDE_VISUALOBJ_Image = 0x02 ,
+ FDE_VISUALOBJ_Path = 0x04 ,
+ FDE_VISUALOBJ_Widget = 0x08 ,
+};
+typedef struct _FDE_HVISUALOBJ {
+ FX_LPVOID pData;
+} const * FDE_HVISUALOBJ;
+class IFDE_VisualSet
+{
+public:
+ virtual FDE_VISUALOBJTYPE GetType() = 0;
+ virtual FX_BOOL GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF &bbox) = 0;
+ virtual FX_BOOL GetMatrix(FDE_HVISUALOBJ hVisualObj, CFX_Matrix &matrix) = 0;
+ virtual FX_BOOL GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt) = 0;
+ virtual FX_BOOL GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt) = 0;
+};
+class IFDE_CanvasSet : public IFDE_VisualSet
+{
+public:
+ virtual FX_POSITION GetFirstPosition(FDE_HVISUALOBJ hCanvas) = 0;
+ virtual FDE_HVISUALOBJ GetNext(FDE_HVISUALOBJ hCanvas, FX_POSITION &pos, IFDE_VisualSet *&pVisualSet) = 0;
+ virtual FDE_HVISUALOBJ GetParentCanvas(FDE_HVISUALOBJ hCanvas, IFDE_VisualSet *&pVisualSet) = 0;
+};
+class IFDE_TextSet : public IFDE_VisualSet
+{
+public:
+ virtual FX_INT32 GetString(FDE_HVISUALOBJ hText, CFX_WideString &wsText) = 0;
+ virtual IFX_Font* GetFont(FDE_HVISUALOBJ hText) = 0;
+ virtual FX_FLOAT GetFontSize(FDE_HVISUALOBJ hText) = 0;
+ virtual FX_ARGB GetFontColor(FDE_HVISUALOBJ hText) = 0;
+ virtual FX_INT32 GetDisplayPos(FDE_HVISUALOBJ hText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL) = 0;
+ virtual FX_INT32 GetCharRects(FDE_HVISUALOBJ hText, CFX_RectFArray &rtArray) = 0;
+};
+class IFDE_ImageSet : public IFDE_VisualSet
+{
+public:
+ virtual IFDE_Image* GetImage(FDE_HVISUALOBJ hImage) = 0;
+ virtual FX_POSITION GetFirstFilterPosition(FDE_HVISUALOBJ hImage) = 0;
+ virtual FDE_LPCIMAGEFILTERPARAMS GetNextFilter(FDE_HVISUALOBJ hImage, FX_POSITION &pos) = 0;
+};
+#define FDE_FILLMODE_Alternate 1
+#define FDE_FILLMODE_Winding 2
+#define FDE_PATHRENDER_Stroke 1
+#define FDE_PATHRENDER_Fill 2
+#define FDE_PATHRENDER_FillStroke 3
+class IFDE_PathSet : public IFDE_VisualSet
+{
+public:
+ virtual IFDE_Path* GetPath(FDE_HVISUALOBJ hPath) = 0;
+ virtual FX_INT32 GetFillMode(FDE_HVISUALOBJ hPath) = 0;
+ virtual FX_INT32 GetRenderMode(FDE_HVISUALOBJ hPath) = 0;
+ virtual IFDE_Pen* GetPen(FDE_HVISUALOBJ hPath) = 0;
+ virtual FX_FLOAT GetPenWidth(FDE_HVISUALOBJ hPath) = 0;
+ virtual IFDE_Brush* GetBrush(FDE_HVISUALOBJ hPath) = 0;
+};
+enum FDE_WIDGETOBJ {
+ FDE_WIDGETOBJ_Unknown = 0x0000,
+ FDE_WIDGETOBJ_Anchor = 0x0100,
+ FDE_WIDGETOBJ_NamedDest = 0x0200,
+ FDE_WIDGETOBJ_HyperLink = 0x0400,
+};
+#define FDE_WIDGETPARAM_Uri 1
+#define FDE_WIDGETPARAM_Rects 2
+class IFDE_WidgetSet : public IFDE_VisualSet
+{
+public:
+ virtual FDE_WIDGETOBJ GetWidgetType(FDE_HVISUALOBJ hWidget) = 0;
+ virtual FX_FLOAT GetFloat(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, FX_FLOAT fDefVal = 0.0f) = 0;
+ virtual FX_INT32 GetInteger(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, FX_INT32 iDefVal = 0) = 0;
+ virtual FX_BOOL GetString(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, CFX_WideString &wsValue) = 0;
+ virtual FX_BOOL GetRects(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, CFX_RectFArray &rects) = 0;
+};
+class IFDE_VisualSetIterator
+{
+public:
+ static IFDE_VisualSetIterator* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL AttachCanvas(IFDE_CanvasSet *pCanvas) = 0;
+ virtual FX_BOOL FilterObjects(FX_DWORD dwObjects = 0xFFFFFFFF) = 0;
+ virtual void Reset() = 0;
+ virtual FDE_HVISUALOBJ GetNext(IFDE_VisualSet *&pVisualSet, FDE_HVISUALOBJ *phCanvasObj = NULL, IFDE_CanvasSet **ppCanvasSet = NULL) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_pth.h b/xfa/src/fdp/include/fde_pth.h
new file mode 100644
index 0000000000..be3cc8d50e
--- /dev/null
+++ b/xfa/src/fdp/include/fde_pth.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_PATH
+#define _FDE_PATH
+class IFDE_Path;
+class IFDE_Path
+{
+public:
+ static IFDE_Path* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL StartFigure() = 0;
+ virtual FX_BOOL CloseFigure() = 0;
+ virtual void AddBezier(const CFX_PointsF &points) = 0;
+ virtual void AddBeziers(const CFX_PointsF &points) = 0;
+ virtual void AddCurve(const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f) = 0;
+ virtual void AddEllipse(const CFX_RectF &rect) = 0;
+ virtual void AddLines(const CFX_PointsF &points) = 0;
+ virtual void AddLine(const CFX_PointF &pt1, const CFX_PointF &pt2) = 0;
+ virtual void AddPath(const IFDE_Path *pSrc, FX_BOOL bConnect) = 0;
+ virtual void AddPolygon(const CFX_PointsF &points) = 0;
+ virtual void AddRectangle(const CFX_RectF &rect) = 0;
+ virtual void GetBBox(CFX_RectF &bbox) const = 0;
+ virtual void GetBBox(CFX_RectF &bbox, FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_rdr.h b/xfa/src/fdp/include/fde_rdr.h
new file mode 100644
index 0000000000..74c5d24516
--- /dev/null
+++ b/xfa/src/fdp/include/fde_rdr.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_RENDERCONTEXT
+#define _FDE_RENDERCONTEXT
+class IFDE_Page;
+class IFDE_RenderDevice;
+class IFDE_RenderContext;
+void FDE_GetPageMatrix(CFX_Matrix &pageMatrix, const CFX_RectF &docPageRect, const CFX_Rect &devicePageRect, FX_INT32 iRotate, FX_DWORD dwCoordinatesType = 0);
+enum FDE_RENDERSTATUS {
+ FDE_RENDERSTATUS_Reset = 0,
+ FDE_RENDERSTATUS_Paused ,
+ FDE_RENDERSTATUS_Done ,
+ FDE_RENDERSTATUS_Failed ,
+};
+class IFDE_RenderContext
+{
+public:
+ static IFDE_RenderContext* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL StartRender(IFDE_RenderDevice *pRenderDevice,
+ IFDE_CanvasSet *pCanvasSet,
+ const CFX_Matrix &tmDoc2Device
+ ) = 0;
+ virtual FDE_RENDERSTATUS GetStatus() const = 0;
+ virtual FDE_RENDERSTATUS DoRender(IFX_Pause *pPause = NULL) = 0;
+ virtual void StopRender() = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_rdv.h b/xfa/src/fdp/include/fde_rdv.h
new file mode 100644
index 0000000000..ee1e922c48
--- /dev/null
+++ b/xfa/src/fdp/include/fde_rdv.h
@@ -0,0 +1,53 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_RENDERDEVICE
+#define _FDE_RENDERDEVICE
+class IFDE_Pen;
+class IFDE_Brush;
+class IFDE_Image;
+class CFX_DIBitmap;
+class CFX_DIBSource;
+class IFDE_RenderDevice;
+typedef struct _FDE_HDEVICESTATE {
+ FX_LPVOID pData;
+} * FDE_HDEVICESTATE;
+class IFDE_RenderDevice
+{
+public:
+ static IFDE_RenderDevice* Create(CFX_DIBitmap *pBitmap, FX_BOOL bRgbByteOrder = FALSE);
+ static IFDE_RenderDevice* Create(CFX_RenderDevice *pDevice);
+ virtual void Release() = 0;
+
+ virtual FX_INT32 GetWidth() const = 0;
+ virtual FX_INT32 GetHeight() const = 0;
+ virtual FDE_HDEVICESTATE SaveState() = 0;
+ virtual void RestoreState(FDE_HDEVICESTATE hState) = 0;
+ virtual FX_BOOL SetClipPath(const IFDE_Path *pClip) = 0;
+ virtual IFDE_Path* GetClipPath() const = 0;
+ virtual FX_BOOL SetClipRect(const CFX_RectF &rtClip) = 0;
+ virtual const CFX_RectF& GetClipRect() = 0;
+
+ virtual FX_FLOAT GetDpiX() const = 0;
+ virtual FX_FLOAT GetDpiY() const = 0;
+
+ virtual FX_BOOL DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL) = 0;
+ virtual FX_BOOL DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_tto.h b/xfa/src/fdp/include/fde_tto.h
new file mode 100644
index 0000000000..25dead13ca
--- /dev/null
+++ b/xfa/src/fdp/include/fde_tto.h
@@ -0,0 +1,69 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TEXTOUT
+#define _FDE_TEXTOUT
+class IFDE_TextOut;
+#define FDE_TTOSTYLE_Underline 0x0001
+#define FDE_TTOSTYLE_Strikeout 0x0002
+#define FDE_TTOSTYLE_VerticalLayout 0x0004
+#define FDE_TTOSTYLE_SingleLine 0x0010
+#define FDE_TTOSTYLE_ExpandTab 0x0020
+#define FDE_TTOSTYLE_HotKey 0x0040
+#define FDE_TTOSTYLE_Ellipsis 0x0080
+#define FDE_TTOSTYLE_LineWrap 0x0100
+#define FDE_TTOSTYLE_ArabicShapes 0x0200
+#define FDE_TTOSTYLE_RTL 0x0400
+#define FDE_TTOSTYLE_ArabicContext 0x0800
+#define FDE_TTOSTYLE_LastLineHeight 0x1000
+#define FDE_TTOALIGNMENT_TopLeft 0
+#define FDE_TTOALIGNMENT_TopCenter 1
+#define FDE_TTOALIGNMENT_TopRight 2
+#define FDE_TTOALIGNMENT_TopAuto 3
+#define FDE_TTOALIGNMENT_CenterLeft 4
+#define FDE_TTOALIGNMENT_Center 5
+#define FDE_TTOALIGNMENT_CenterRight 6
+#define FDE_TTOALIGNMENT_CenterAuto 7
+#define FDE_TTOALIGNMENT_BottomLeft 8
+#define FDE_TTOALIGNMENT_BottomCenter 9
+#define FDE_TTOALIGNMENT_BottomRight 10
+#define FDE_TTOALIGNMENT_BottomAuto 11
+class IFDE_TextOut
+{
+public:
+ static IFDE_TextOut* Create();
+ virtual void Release() = 0;
+ virtual void SetFont(IFX_Font *pFont) = 0;
+ virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
+ virtual void SetTextColor(FX_ARGB color) = 0;
+ virtual void SetStyles(FX_DWORD dwStyles) = 0;
+ virtual void SetTabWidth(FX_FLOAT fTabWidth) = 0;
+ virtual void SetEllipsisString(const CFX_WideString &wsEllipsis) = 0;
+ virtual void SetParagraphBreakChar(FX_WCHAR wch) = 0;
+ virtual void SetAlignment(FX_INT32 iAlignment) = 0;
+ virtual void SetLineSpace(FX_FLOAT fLineSpace) = 0;
+ virtual void SetDIBitmap(CFX_DIBitmap *pDIB) = 0;
+ virtual void SetRenderDevice(CFX_RenderDevice *pDevice) = 0;
+ virtual void SetClipRect(const CFX_Rect &rtClip) = 0;
+ virtual void SetClipRect(const CFX_RectF &rtClip) = 0;
+ virtual void SetMatrix(const CFX_Matrix &matrix) = 0;
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Size &size) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Rect &rect) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_INT32 x, FX_INT32 y) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_Rect &rect) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect) = 0;
+ virtual void SetLogicClipRect(const CFX_RectF &rtClip) = 0;
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size) = 0;
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect) = 0;
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y) = 0;
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect) = 0;
+ virtual FX_INT32 GetTotalLines() = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_xml.h b/xfa/src/fdp/include/fde_xml.h
new file mode 100644
index 0000000000..b8b136b5aa
--- /dev/null
+++ b/xfa/src/fdp/include/fde_xml.h
@@ -0,0 +1,188 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_XML
+#define _FDE_XML
+class IFDE_XMLNode;
+class IFDE_XMLInstruction;
+class IFDE_XMLDeclaration;
+class IFDE_XMLDeclComment;
+class IFDE_XMLDeclCharData;
+class IFDE_XMLDeclDocType;
+class IFDE_XMLDeclElement;
+class IFDE_XMLDeclAttriList;
+class IFDE_XMLDeclNotition;
+class IFDE_XMLDeclEntity;
+class IFDE_XMLElement;
+class IFDE_XMLText;
+class IFDE_XMLDoc;
+class IFDE_XMLParser;
+class IFDE_XMLSyntaxParser;
+#ifdef __cplusplus
+extern "C" {
+#endif
+enum FDE_XMLNODETYPE {
+ FDE_XMLNODE_Unknown = 0,
+ FDE_XMLNODE_Instruction ,
+ FDE_XMLNODE_Element ,
+ FDE_XMLNODE_Text ,
+ FDE_XMLNODE_CharData ,
+};
+typedef struct _FDE_XMLNODE {
+ FX_INT32 iNodeNum;
+ FDE_XMLNODETYPE eNodeType;
+} FDE_XMLNODE, * FDE_LPXMLNODE;
+typedef FDE_XMLNODE const * FDE_LPCXMLNODE;
+typedef CFX_StackTemplate<FDE_XMLNODE> CFDE_XMLNodeStack;
+FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch);
+FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch);
+FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar);
+#ifdef __cplusplus
+}
+#endif
+class IFDE_XMLNode
+{
+public:
+ virtual void Release() = 0;
+ virtual FDE_XMLNODETYPE GetType() const = 0;
+ virtual FX_INT32 CountChildNodes() const = 0;
+ virtual IFDE_XMLNode* GetChildNode(FX_INT32 index) const = 0;
+ virtual FX_INT32 GetChildNodeIndex(IFDE_XMLNode *pNode) const = 0;
+ virtual IFDE_XMLNode* GetPath(FX_LPCWSTR pPath, FX_INT32 iLength = -1, FX_BOOL bQualifiedName = TRUE) const = 0;
+ virtual FX_INT32 InsertChildNode(IFDE_XMLNode *pNode, FX_INT32 index = -1) = 0;
+ virtual void RemoveChildNode(IFDE_XMLNode *pNode) = 0;
+ virtual void DeleteChildren() = 0;
+ enum NodeItem {Root = 0, Parent, FirstSibling, PriorSibling, NextSibling, LastSibling, FirstNeighbor, PriorNeighbor, NextNeighbor, LastNeighbor, FirstChild, LastChild};
+ virtual IFDE_XMLNode* GetNodeItem(NodeItem eItem) const = 0;
+ virtual FX_INT32 GetNodeLevel() const = 0;
+ virtual FX_BOOL InsertNodeItem(IFDE_XMLNode::NodeItem eItem, IFDE_XMLNode *pNode) = 0;
+ virtual IFDE_XMLNode* RemoveNodeItem(IFDE_XMLNode::NodeItem eItem) = 0;
+ virtual IFDE_XMLNode* Clone(FX_BOOL bRecursive) = 0;
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream) = 0;
+};
+class IFDE_XMLInstruction : public IFDE_XMLNode
+{
+public:
+ static IFDE_XMLInstruction* Create(const CFX_WideString &wsTarget);
+ virtual void GetTargetName(CFX_WideString &wsTarget) const = 0;
+ virtual FX_INT32 CountAttributes() const = 0;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const = 0;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const = 0;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const = 0;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue) = 0;
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const = 0;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue) = 0;
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const = 0;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue) = 0;
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName) = 0;
+ virtual FX_INT32 CountData() const = 0;
+ virtual FX_BOOL GetData(FX_INT32 index, CFX_WideString &wsData) const = 0;
+ virtual void AppendData(const CFX_WideString &wsData) = 0;
+ virtual void RemoveData(FX_INT32 index) = 0;
+};
+class IFDE_XMLElement : public IFDE_XMLNode
+{
+public:
+ static IFDE_XMLElement* Create(const CFX_WideString &wsTag);
+ virtual void GetTagName(CFX_WideString &wsTag) const = 0;
+ virtual void GetLocalTagName(CFX_WideString &wsTag) const = 0;
+ virtual void GetNamespacePrefix(CFX_WideString &wsPrefix) const = 0;
+ virtual void GetNamespaceURI(CFX_WideString &wsNamespace) const = 0;
+ virtual FX_INT32 CountAttributes() const = 0;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const = 0;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const = 0;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const = 0;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue) = 0;
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const = 0;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue) = 0;
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const = 0;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue) = 0;
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName) = 0;
+ virtual void GetTextData(CFX_WideString &wsText) const = 0;
+ virtual void SetTextData(const CFX_WideString &wsText) = 0;
+};
+class IFDE_XMLText : public IFDE_XMLNode
+{
+public:
+ static IFDE_XMLText* Create(const CFX_WideString &wsText);
+ virtual void GetText(CFX_WideString &wsText) const = 0;
+ virtual void SetText(const CFX_WideString &wsText) = 0;
+};
+class IFDE_XMLDeclaration : public IFDE_XMLNode
+{
+public:
+};
+class IFDE_XMLCharData : public IFDE_XMLDeclaration
+{
+public:
+ static IFDE_XMLCharData* Create(const CFX_WideString &wsCData);
+
+ virtual void GetCharData(CFX_WideString &wsCData) const = 0;
+ virtual void SetCharData(const CFX_WideString &wsCData) = 0;
+};
+typedef struct _FDE_XMLREADERHANDLER {
+ FX_LPVOID pData;
+
+ void (*OnTagEnter)(_FDE_XMLREADERHANDLER *pThis, FDE_XMLNODETYPE eType, const CFX_WideString &wsTagName);
+ void (*OnTagBreak)(_FDE_XMLREADERHANDLER *pThis, const CFX_WideString &wsTagName);
+ void (*OnTagClose)(_FDE_XMLREADERHANDLER *pThis, const CFX_WideString &wsTagName);
+ void (*OnAttribute)(_FDE_XMLREADERHANDLER *pThis, const CFX_WideString &wsName, const CFX_WideString &wsValue);
+ void (*OnData)(_FDE_XMLREADERHANDLER *pThis, FDE_XMLNODETYPE eType, const CFX_WideString &wsValue);
+} FDE_XMLREADERHANDLER, * FDE_LPXMLREADERHANDLER;
+class IFDE_XMLDoc
+{
+public:
+ static IFDE_XMLDoc* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL LoadXML(IFX_Stream *pXMLStream, FX_INT32 iXMLPlaneSize = 8192, FX_INT32 iTextDataSize = 256, FDE_LPXMLREADERHANDLER pHandler = NULL) = 0;
+ virtual FX_BOOL LoadXML(IFDE_XMLParser *pXMLParser) = 0;
+ virtual FX_INT32 DoLoad(IFX_Pause *pPause = NULL) = 0;
+ virtual void CloseXML() = 0;
+ virtual IFDE_XMLNode* GetRoot() const = 0;
+ virtual void SaveXML(IFX_Stream *pXMLStream = NULL, FX_BOOL bSaveBOM = TRUE) = 0;
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream, IFDE_XMLNode *pNode) = 0;
+};
+class IFDE_XMLParser
+{
+public:
+ virtual void Release() = 0;
+ virtual FX_INT32 DoParser(IFX_Pause *pPause) = 0;
+};
+#define FDE_XMLSYNTAXSTATUS_None 0x00
+#define FDE_XMLSYNTAXSTATUS_InstructionOpen 0x01
+#define FDE_XMLSYNTAXSTATUS_InstructionClose 0x02
+#define FDE_XMLSYNTAXSTATUS_ElementOpen 0x03
+#define FDE_XMLSYNTAXSTATUS_ElementBreak 0x04
+#define FDE_XMLSYNTAXSTATUS_ElementClose 0x05
+#define FDE_XMLSYNTAXSTATUS_TargetName 0x06
+#define FDE_XMLSYNTAXSTATUS_TagName 0x07
+#define FDE_XMLSYNTAXSTATUS_AttriName 0x08
+#define FDE_XMLSYNTAXSTATUS_AttriValue 0x09
+#define FDE_XMLSYNTAXSTATUS_Text 0x0A
+#define FDE_XMLSYNTAXSTATUS_CData 0x0B
+#define FDE_XMLSYNTAXSTATUS_TargetData 0x0C
+#define FDE_XMLSYNTAXSTATUS_Error 0xFE
+#define FDE_XMLSYNTAXSTATUS_EOS 0xFF
+class IFDE_XMLSyntaxParser
+{
+public:
+ static IFDE_XMLSyntaxParser* Create();
+ virtual void Release() = 0;
+ virtual void Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize = 256) = 0;
+ virtual FX_DWORD DoSyntaxParse() = 0;
+ virtual FX_INT32 GetStatus() const = 0;
+ virtual FX_INT32 GetCurrentPos() const = 0;
+ virtual FX_FILESIZE GetCurrentBinaryPos() const = 0;
+ virtual FX_INT32 GetCurrentNodeNumber() const = 0;
+ virtual FX_INT32 GetLastNodeNumber() const = 0;
+ virtual void GetTargetName(CFX_WideString &wsTarget) const = 0;
+ virtual void GetTagName(CFX_WideString &wsTag) const = 0;
+ virtual void GetAttributeName(CFX_WideString &wsAttriName) const = 0;
+ virtual void GetAttributeValue(CFX_WideString &wsAttriValue) const = 0;
+ virtual void GetTextData(CFX_WideString &wsText) const = 0;
+ virtual void GetTargetData(CFX_WideString &wsData) const = 0;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_csscache.cpp b/xfa/src/fdp/src/css/fde_csscache.cpp
new file mode 100644
index 0000000000..13ff27b8e7
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csscache.cpp
@@ -0,0 +1,163 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csscache.h"
+_FDE_CSSCACHEITEM::_FDE_CSSCACHEITEM(IFDE_CSSStyleSheet *p)
+ : pStylesheet(p)
+ , dwActivity(0)
+{
+ FXSYS_assert(pStylesheet);
+ pStylesheet->AddRef();
+}
+_FDE_CSSCACHEITEM::~_FDE_CSSCACHEITEM()
+{
+ pStylesheet->Release();
+}
+IFDE_CSSStyleSheetCache* IFDE_CSSStyleSheetCache::Create()
+{
+ return FDE_New CFDE_CSSStyleSheetCache;
+}
+CFDE_CSSStyleSheetCache::CFDE_CSSStyleSheetCache()
+ : m_pFixedStore(NULL)
+ , m_iMaxItems(5)
+{
+}
+CFDE_CSSStyleSheetCache::~CFDE_CSSStyleSheetCache()
+{
+ FX_POSITION pos = m_Stylesheets.GetStartPosition();
+ if (pos != NULL) {
+ CFX_ByteString szKey;
+ FX_LPVOID pValue;
+ while (pos != NULL) {
+ m_Stylesheets.GetNextAssoc(pos, szKey, pValue);
+ FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, (FDE_LPCSSCACHEITEM)pValue);
+ }
+ m_Stylesheets.RemoveAll();
+ }
+ if (m_pFixedStore != NULL) {
+ m_pFixedStore->Release();
+ }
+}
+void CFDE_CSSStyleSheetCache::AddStyleSheet(FX_BSTR szKey, IFDE_CSSStyleSheet *pStyleSheet)
+{
+ FXSYS_assert(pStyleSheet != NULL);
+ if (m_pFixedStore == NULL) {
+ m_pFixedStore = FX_CreateAllocator(FX_ALLOCTYPE_Fixed, FX_MAX(10, m_iMaxItems), sizeof(FDE_CSSCACHEITEM));
+ FXSYS_assert(m_pFixedStore != NULL);
+ }
+ FX_LPVOID pValue = NULL;
+ if (m_Stylesheets.Lookup(szKey, pValue)) {
+ FDE_LPCSSCACHEITEM pItem = (FDE_LPCSSCACHEITEM)pValue;
+ if (pItem->pStylesheet != pStyleSheet) {
+ pItem->pStylesheet->Release();
+ pItem->pStylesheet = pStyleSheet;
+ pItem->pStylesheet->AddRef();
+ pItem->dwActivity = 0;
+ }
+ } else {
+ while (m_Stylesheets.GetCount() >= m_iMaxItems) {
+ RemoveLowestActivityItem();
+ }
+ FDE_LPCSSCACHEITEM pItem = FDE_NewWith(m_pFixedStore) FDE_CSSCACHEITEM(pStyleSheet);
+ FXSYS_assert(pItem != NULL);
+ m_Stylesheets.SetAt(szKey, pItem);
+ }
+}
+IFDE_CSSStyleSheet* CFDE_CSSStyleSheetCache::GetStyleSheet(FX_BSTR szKey) const
+{
+ FX_LPVOID pValue = NULL;
+ if (m_Stylesheets.Lookup(szKey, pValue)) {
+ FDE_LPCSSCACHEITEM pItem = (FDE_LPCSSCACHEITEM)pValue;
+ pItem->dwActivity++;
+ pItem->pStylesheet->AddRef();
+ return pItem->pStylesheet;
+ }
+ return NULL;
+}
+void CFDE_CSSStyleSheetCache::RemoveStyleSheet(FX_BSTR szKey)
+{
+ FX_LPVOID pValue = NULL;
+ if (!m_Stylesheets.Lookup(szKey, pValue)) {
+ return;
+ }
+ FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, (FDE_LPCSSCACHEITEM)pValue);
+ m_Stylesheets.RemoveKey(szKey);
+}
+void CFDE_CSSStyleSheetCache::RemoveLowestActivityItem()
+{
+ FX_POSITION pos = m_Stylesheets.GetStartPosition();
+ CFX_ByteString szKey;
+ FX_LPVOID pValue;
+ FDE_LPCSSCACHEITEM pItem = NULL;
+ CFX_ByteString szItem;
+ while (pos != NULL) {
+ m_Stylesheets.GetNextAssoc(pos, szKey, pValue);
+ switch (szKey.GetID()) {
+ case FXBSTR_ID('#', 'U', 'S', 'E'):
+ case FXBSTR_ID('#', 'A', 'G', 'E'):
+ continue;
+ }
+ FDE_LPCSSCACHEITEM p = (FDE_LPCSSCACHEITEM)pValue;
+ if (pItem == NULL || pItem->dwActivity > p->dwActivity) {
+ szItem = szKey;
+ pItem = p;
+ }
+ }
+ if (pItem != NULL) {
+ FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, pItem);
+ m_Stylesheets.RemoveKey(szItem);
+ }
+}
+_FDE_CSSTAGCACHE::_FDE_CSSTAGCACHE(_FDE_CSSTAGCACHE *parent, IFDE_CSSTagProvider *tag)
+ : pTag(tag)
+ , pParent(parent)
+ , dwIDHash(0)
+ , dwTagHash(0)
+ , iClassIndex(0)
+ , dwClassHashs(1)
+{
+ FXSYS_assert(pTag != NULL);
+ CFX_WideStringC wsValue, wsName = pTag->GetTagName();
+ dwTagHash = FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), TRUE);
+ FX_POSITION pos = pTag->GetFirstAttribute();
+ while (pos != NULL) {
+ pTag->GetNextAttribute(pos, wsName, wsValue);
+ FX_DWORD dwNameHash = FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), TRUE);
+ static const FX_DWORD s_dwIDHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"id", 2, TRUE);
+ static const FX_DWORD s_dwClassHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"class", 5, TRUE);
+ if (dwNameHash == s_dwClassHash) {
+ FX_DWORD dwHash = FX_HashCode_String_GetW(wsValue.GetPtr(), wsValue.GetLength());
+ dwClassHashs.Add(dwHash);
+ } else if (dwNameHash == s_dwIDHash) {
+ dwIDHash = FX_HashCode_String_GetW(wsValue.GetPtr(), wsValue.GetLength());
+ }
+ }
+}
+_FDE_CSSTAGCACHE::_FDE_CSSTAGCACHE(const _FDE_CSSTAGCACHE &it)
+ : pTag(it.pTag)
+ , pParent(it.pParent)
+ , dwIDHash(it.dwIDHash)
+ , dwTagHash(it.dwTagHash)
+ , iClassIndex(0)
+ , dwClassHashs(1)
+{
+ if (it.dwClassHashs.GetSize() > 0) {
+ dwClassHashs.Copy(it.dwClassHashs);
+ }
+}
+void CFDE_CSSAccelerator::OnEnterTag(IFDE_CSSTagProvider *pTag)
+{
+ FDE_CSSTAGCACHE *pTop = GetTopElement();
+ FDE_CSSTAGCACHE item(pTop, pTag);
+ m_Stack.Push(item);
+}
+void CFDE_CSSAccelerator::OnLeaveTag(IFDE_CSSTagProvider *pTag)
+{
+ FDE_CSSTAGCACHE *pItem = m_Stack.GetTopElement();
+ FXSYS_assert(pItem && pItem->GetTag() == pTag);
+ m_Stack.Pop();
+}
diff --git a/xfa/src/fdp/src/css/fde_csscache.h b/xfa/src/fdp/src/css/fde_csscache.h
new file mode 100644
index 0000000000..f4b8cffd57
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csscache.h
@@ -0,0 +1,97 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSCACHE
+#define _FDE_CSSCACHE
+typedef struct _FDE_CSSCACHEITEM : public CFX_Target {
+ _FDE_CSSCACHEITEM(IFDE_CSSStyleSheet *p);
+ ~_FDE_CSSCACHEITEM();
+ IFDE_CSSStyleSheet *pStylesheet;
+ FX_DWORD dwActivity;
+} FDE_CSSCACHEITEM, * FDE_LPCSSCACHEITEM;
+class CFDE_CSSStyleSheetCache : public IFDE_CSSStyleSheetCache, public CFX_ThreadLock, public CFX_Target
+{
+public:
+ CFDE_CSSStyleSheetCache();
+ ~CFDE_CSSStyleSheetCache();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual void SetMaxItems(FX_INT32 iMaxCount = 5)
+ {
+ FXSYS_assert(iMaxCount >= 3);
+ m_iMaxItems = iMaxCount;
+ }
+
+ virtual void AddStyleSheet(FX_BSTR szKey, IFDE_CSSStyleSheet *pStyleSheet);
+ virtual IFDE_CSSStyleSheet* GetStyleSheet(FX_BSTR szKey) const;
+ virtual void RemoveStyleSheet(FX_BSTR szKey);
+protected:
+ void RemoveLowestActivityItem();
+ CFX_MapByteStringToPtr m_Stylesheets;
+ IFX_MEMAllocator *m_pFixedStore;
+ FX_INT32 m_iMaxItems;
+};
+typedef struct _FDE_CSSTAGCACHE : public CFX_Target {
+public:
+ _FDE_CSSTAGCACHE(_FDE_CSSTAGCACHE *parent, IFDE_CSSTagProvider *tag);
+ _FDE_CSSTAGCACHE(const _FDE_CSSTAGCACHE &it);
+ _FDE_CSSTAGCACHE* GetParent() const
+ {
+ return pParent;
+ }
+ IFDE_CSSTagProvider* GetTag() const
+ {
+ return pTag;
+ }
+ FX_DWORD HashID() const
+ {
+ return dwIDHash;
+ }
+ FX_DWORD HashTag() const
+ {
+ return dwTagHash;
+ }
+ FX_INT32 CountHashClass() const
+ {
+ return dwClassHashs.GetSize();
+ }
+ void SetClassIndex(FX_INT32 index)
+ {
+ iClassIndex = index;
+ }
+ FX_DWORD HashClass() const
+ {
+ return iClassIndex < dwClassHashs.GetSize() ? dwClassHashs.GetAt(iClassIndex) : 0;
+ }
+protected:
+ IFDE_CSSTagProvider *pTag;
+ _FDE_CSSTAGCACHE *pParent;
+ FX_DWORD dwIDHash;
+ FX_DWORD dwTagHash;
+ FX_INT32 iClassIndex;
+ CFDE_DWordArray dwClassHashs;
+} FDE_CSSTAGCACHE, * FDE_LPCSSTAGCACHE;
+typedef CFX_ObjectStackTemplate<FDE_CSSTAGCACHE> CFDE_CSSTagStack;
+class CFDE_CSSAccelerator : public IFDE_CSSAccelerator, public CFX_Target
+{
+public:
+ virtual void OnEnterTag(IFDE_CSSTagProvider *pTag);
+ virtual void OnLeaveTag(IFDE_CSSTagProvider *pTag);
+ void Clear()
+ {
+ m_Stack.RemoveAll();
+ }
+ FDE_LPCSSTAGCACHE GetTopElement() const
+ {
+ return m_Stack.GetTopElement();
+ }
+protected:
+ CFDE_CSSTagStack m_Stack;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssdatatable.cpp b/xfa/src/fdp/src/css/fde_cssdatatable.cpp
new file mode 100644
index 0000000000..b449b27c25
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdatatable.cpp
@@ -0,0 +1,729 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_cssdatatable.h"
+#ifdef _cplusplus
+extern "C" {
+#endif
+ FX_BOOL FDE_CSSLengthToFloat(const FDE_CSSLENGTH &len, FX_FLOAT fPercentBase, FX_FLOAT &fResult)
+ {
+ switch (len.GetUnit()) {
+ case FDE_CSSLENGTHUNIT_Point:
+ fResult = len.GetValue();
+ return TRUE;
+ case FDE_CSSLENGTHUNIT_Percent:
+ fResult = len.GetValue() * fPercentBase;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
+ CFX_FloatRect FDE_CSSBoundaryToRect(IFDE_CSSBoundaryStyle *pBoundStyle, FX_FLOAT fContainerWidth, FX_BOOL bPadding, FX_BOOL bBorder, FX_BOOL bMargin)
+ {
+ FXSYS_assert(pBoundStyle != NULL);
+ FX_FLOAT fResult;
+ const FDE_CSSRECT *pRect;
+ CFX_FloatRect rect(0, 0, 0, 0);
+ if (bPadding) {
+ pRect = pBoundStyle->GetPaddingWidth();
+ if (pRect != NULL) {
+ if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) {
+ rect.left += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) {
+ rect.top += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) {
+ rect.right += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) {
+ rect.bottom += fResult;
+ }
+ }
+ }
+ if (bBorder) {
+ pRect = pBoundStyle->GetBorderWidth();
+ if (pRect != NULL) {
+ if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) {
+ rect.left += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) {
+ rect.top += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) {
+ rect.right += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) {
+ rect.bottom += fResult;
+ }
+ }
+ }
+ if (bMargin) {
+ pRect = pBoundStyle->GetMarginWidth();
+ if (pRect != NULL) {
+ if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) {
+ rect.left += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) {
+ rect.top += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) {
+ rect.right += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) {
+ rect.bottom += fResult;
+ }
+ }
+ }
+ return rect;
+ }
+ FX_DWORD FDE_CSSFontStyleToFDE(IFDE_CSSFontStyle *pFontStyle)
+ {
+ FXSYS_assert(pFontStyle != NULL);
+ FX_DWORD dwFontStyle = FX_FONTSTYLE_Normal;
+ if (pFontStyle->GetFontStyle() == FDE_CSSFONTSTYLE_Italic) {
+ dwFontStyle |= FX_FONTSTYLE_Italic;
+ }
+ if (pFontStyle->GetFontWeight() >= 700) {
+ dwFontStyle |= FX_FONTSTYLE_Bold;
+ }
+ return dwFontStyle;
+ }
+ static const FDE_CSSPROPERTYTABLE g_FDE_CSSProperties[] = {
+ {FDE_CSSPROPERTY_WritingMode, (FX_LPCWSTR)L"writing-mode", 0x01878076, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnRuleWidth, (FX_LPCWSTR)L"column-rule-width", 0x0200FB00, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderLeft, (FX_LPCWSTR)L"border-left", 0x04080036, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_ColumnRule, (FX_LPCWSTR)L"column-rule", 0x04C83DF3, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_Height, (FX_LPCWSTR)L"height", 0x05A5C519, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_CounterReset, (FX_LPCWSTR)L"counter-reset", 0x0894F9B0, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_Content, (FX_LPCWSTR)L"content", 0x097BE91B, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeURI | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_RubyPosition, (FX_LPCWSTR)L"ruby-position", 0x09ACD024, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BackgroundColor, (FX_LPCWSTR)L"background-color", 0x09E8E8AC, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_Width, (FX_LPCWSTR)L"width", 0x0A8A8F80, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Src, (FX_LPCWSTR)L"src", 0x0BD37048, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeURI},
+ {FDE_CSSPROPERTY_Top, (FX_LPCWSTR)L"top", 0x0BEDAF33, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Margin, (FX_LPCWSTR)L"margin", 0x0CB016BE, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderColor, (FX_LPCWSTR)L"border-color", 0x0CBB528A, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_Widows, (FX_LPCWSTR)L"widows", 0x1026C59D, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderBottomColor, (FX_LPCWSTR)L"border-bottom-color", 0x121E22EC, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_TextIndent, (FX_LPCWSTR)L"text-indent", 0x169ADB74, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Right, (FX_LPCWSTR)L"right", 0x193ADE3E, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextEmphasisStyle, (FX_LPCWSTR)L"text-emphasis-style", 0x20DBAF4A, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_PaddingLeft, (FX_LPCWSTR)L"padding-left", 0x228CF02F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ColumnWidth, (FX_LPCWSTR)L"column-width", 0x24C9AC9B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MarginLeft, (FX_LPCWSTR)L"margin-left", 0x297C5656, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Border, (FX_LPCWSTR)L"border", 0x2A23349E, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BorderTop, (FX_LPCWSTR)L"border-top", 0x2B866ADE, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_RubyOverhang, (FX_LPCWSTR)L"ruby-overhang", 0x2CCA0D89, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_PageBreakBefore, (FX_LPCWSTR)L"page-break-before", 0x3119B36F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_MaxHeight, (FX_LPCWSTR)L"max-height", 0x343597EC, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MinWidth, (FX_LPCWSTR)L"min-width", 0x35832871, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderLeftColor, (FX_LPCWSTR)L"border-left-color", 0x35C64022, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_Bottom, (FX_LPCWSTR)L"bottom", 0x399F02B5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Quotes, (FX_LPCWSTR)L"quotes", 0x3D8C6A01, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_MaxWidth, (FX_LPCWSTR)L"max-width", 0x3EA274F3, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_PaddingRight, (FX_LPCWSTR)L"padding-right", 0x3F616AC2, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ListStyleImage, (FX_LPCWSTR)L"list-style-image", 0x42A8A86A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeURI},
+ {FDE_CSSPROPERTY_WhiteSpace, (FX_LPCWSTR)L"white-space", 0x42F0429A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderBottom, (FX_LPCWSTR)L"border-bottom", 0x452CE780, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_ListStyleType, (FX_LPCWSTR)L"list-style-type", 0x48094789, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_WordBreak, (FX_LPCWSTR)L"word-break", 0x4D74A3CE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_OverflowX, (FX_LPCWSTR)L"overflow-x", 0x4ECEBF99, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_OverflowY, (FX_LPCWSTR)L"overflow-y", 0x4ECEBF9A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderTopColor, (FX_LPCWSTR)L"border-top-color", 0x5109B8CA, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_FontFamily, (FX_LPCWSTR)L"font-family", 0x574686E6, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_Cursor, (FX_LPCWSTR)L"cursor", 0x59DFCA5E, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_RubyAlign, (FX_LPCWSTR)L"ruby-align", 0x6077BDFA, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnRuleColor, (FX_LPCWSTR)L"column-rule-color", 0x65DDFD9F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_FontWeight, (FX_LPCWSTR)L"font-weight", 0x6692F60C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRightStyle, (FX_LPCWSTR)L"border-right-style", 0x6920DDA7, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_MinHeight, (FX_LPCWSTR)L"min-height", 0x6AAE312A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Color, (FX_LPCWSTR)L"color", 0x6E67921F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_LetterSpacing, (FX_LPCWSTR)L"letter-spacing", 0x70536102, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_EmptyCells, (FX_LPCWSTR)L"empty-cells", 0x7531528F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_TextAlign, (FX_LPCWSTR)L"text-align", 0x7553F1BD, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_RubySpan, (FX_LPCWSTR)L"ruby-span", 0x76FCFCE1, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeFunction},
+ {FDE_CSSPROPERTY_Position, (FX_LPCWSTR)L"position", 0x814F82B5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderStyle, (FX_LPCWSTR)L"border-style", 0x82A4CD5C, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderBottomStyle, (FX_LPCWSTR)L"border-bottom-style", 0x88079DBE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderCollapse, (FX_LPCWSTR)L"border-collapse", 0x8883C7FE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnCount, (FX_LPCWSTR)L"column-count", 0x89936A64, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRightWidth, (FX_LPCWSTR)L"border-right-width", 0x8F5A6036, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_UnicodeBidi, (FX_LPCWSTR)L"unicode-bidi", 0x91670F6C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_VerticalAlign, (FX_LPCWSTR)L"vertical-align", 0x934A87D2, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_PaddingTop, (FX_LPCWSTR)L"padding-top", 0x959D22B7, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Columns, (FX_LPCWSTR)L"columns", 0x96FA5D81, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_Overflow, (FX_LPCWSTR)L"overflow", 0x97B76B54, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_TableLayout, (FX_LPCWSTR)L"table-layout", 0x9B1CB4B3, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_FontVariant, (FX_LPCWSTR)L"font-variant", 0x9C785779, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ListStyle, (FX_LPCWSTR)L"list-style", 0x9E6C471A, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BackgroundPosition, (FX_LPCWSTR)L"background-position", 0xA8846D22, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderWidth, (FX_LPCWSTR)L"border-width", 0xA8DE4FEB, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextEmphasisColor, (FX_LPCWSTR)L"text-emphasis-color", 0xAAF23478, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_BorderLeftStyle, (FX_LPCWSTR)L"border-left-style", 0xABAFBAF4, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_PageBreakInside, (FX_LPCWSTR)L"page-break-inside", 0xACB695F8, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_TextEmphasis, (FX_LPCWSTR)L"text-emphasis", 0xAD0E580C, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BorderBottomWidth, (FX_LPCWSTR)L"border-bottom-width", 0xAE41204D, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ColumnGap, (FX_LPCWSTR)L"column-gap", 0xB5C1BA73, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Orphans, (FX_LPCWSTR)L"orphans", 0xB716467B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRight, (FX_LPCWSTR)L"border-right", 0xB78E9EA9, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_FontSize, (FX_LPCWSTR)L"font-size", 0xB93956DF, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_PageBreakAfter, (FX_LPCWSTR)L"page-break-after", 0xBC358AEE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_CaptionSide, (FX_LPCWSTR)L"caption-side", 0xC03F3560, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BackgroundRepeat, (FX_LPCWSTR)L"background-repeat", 0xC2C2FDCE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderTopStyle, (FX_LPCWSTR)L"border-top-style", 0xC6F3339C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderSpacing, (FX_LPCWSTR)L"border-spacing", 0xC72030F0, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextTransform, (FX_LPCWSTR)L"text-transform", 0xC88EEA6E, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_FontStyle, (FX_LPCWSTR)L"font-style", 0xCB1950F5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Font, (FX_LPCWSTR)L"font", 0xCD308B77, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_LineHeight, (FX_LPCWSTR)L"line-height", 0xCFCACE2E, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MarginRight, (FX_LPCWSTR)L"margin-right", 0xD13C58C9, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Float, (FX_LPCWSTR)L"float", 0xD1532876, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderLeftWidth, (FX_LPCWSTR)L"border-left-width", 0xD1E93D83, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Display, (FX_LPCWSTR)L"display", 0xD4224C36, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Clear, (FX_LPCWSTR)L"clear", 0xD8ED1467, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnRuleStyle, (FX_LPCWSTR)L"column-rule-style", 0xDBC77871, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_TextCombine, (FX_LPCWSTR)L"text-combine", 0xDC5207CF, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ListStylePosition, (FX_LPCWSTR)L"list-style-position", 0xE1A1DE3C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Visibility, (FX_LPCWSTR)L"visibility", 0xE29F5168, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_PaddingBottom, (FX_LPCWSTR)L"padding-bottom", 0xE555B3B9, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BackgroundAttachment, (FX_LPCWSTR)L"background-attachment", 0xE77981F6, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BackgroundImage, (FX_LPCWSTR)L"background-image", 0xE9AEB710, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeURI},
+ {FDE_CSSPROPERTY_LineBreak, (FX_LPCWSTR)L"line-break", 0xEA2D1D9A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Background, (FX_LPCWSTR)L"background", 0xEB49DD40, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BorderTopWidth, (FX_LPCWSTR)L"border-top-width", 0xED2CB62B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_WordSpacing, (FX_LPCWSTR)L"word-spacing", 0xEDA63BAE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRightColor, (FX_LPCWSTR)L"border-right-color", 0xF33762D5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_CounterIncrement, (FX_LPCWSTR)L"counter-increment", 0xF4CFB1B2, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_Left, (FX_LPCWSTR)L"left", 0xF5AD782B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextDecoration, (FX_LPCWSTR)L"text-decoration", 0xF7C634BA, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Padding, (FX_LPCWSTR)L"padding", 0xF8C373F7, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MarginBottom, (FX_LPCWSTR)L"margin-bottom", 0xF93485A0, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_MarginTop, (FX_LPCWSTR)L"margin-top", 0xFE51DCFE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Direction, (FX_LPCWSTR)L"direction", 0xFE746E61, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ };
+ static const FDE_CSSPROPERTYVALUETABLE g_FDE_CSSPropertyValues[] = {
+ {FDE_CSSPROPERTYVALUE_Bolder, (FX_LPCWSTR)L"bolder", 0x009F1058},
+ {FDE_CSSPROPERTYVALUE_LowerLatin, (FX_LPCWSTR)L"lower-latin", 0x016014CE},
+ {FDE_CSSPROPERTYVALUE_Lowercase, (FX_LPCWSTR)L"lowercase", 0x02ACB805},
+ {FDE_CSSPROPERTYVALUE_LowerGreek, (FX_LPCWSTR)L"lower-greek", 0x03D81D64},
+ {FDE_CSSPROPERTYVALUE_Sesame, (FX_LPCWSTR)L"sesame", 0x0432ECDE},
+ {FDE_CSSPROPERTYVALUE_None, (FX_LPCWSTR)L"none", 0x048B6670},
+ {FDE_CSSPROPERTYVALUE_NwResize, (FX_LPCWSTR)L"nw-resize", 0x054B4BE4},
+ {FDE_CSSPROPERTYVALUE_WResize, (FX_LPCWSTR)L"w-resize", 0x0A2F8D76},
+ {FDE_CSSPROPERTYVALUE_Dot, (FX_LPCWSTR)L"dot", 0x0A48CB27},
+ {FDE_CSSPROPERTYVALUE_End, (FX_LPCWSTR)L"end", 0x0A631437},
+ {FDE_CSSPROPERTYVALUE_Ltr, (FX_LPCWSTR)L"ltr", 0x0B1B56D2},
+ {FDE_CSSPROPERTYVALUE_Pre, (FX_LPCWSTR)L"pre", 0x0B848587},
+ {FDE_CSSPROPERTYVALUE_Rtl, (FX_LPCWSTR)L"rtl", 0x0BB92C52},
+ {FDE_CSSPROPERTYVALUE_Sub, (FX_LPCWSTR)L"sub", 0x0BD37FAA},
+ {FDE_CSSPROPERTYVALUE_Top, (FX_LPCWSTR)L"top", 0x0BEDAF33},
+ {FDE_CSSPROPERTYVALUE_Visible, (FX_LPCWSTR)L"visible", 0x0F55D7EE},
+ {FDE_CSSPROPERTYVALUE_Filled, (FX_LPCWSTR)L"filled", 0x10827DD0},
+ {FDE_CSSPROPERTYVALUE_SwResize, (FX_LPCWSTR)L"sw-resize", 0x10B548E9},
+ {FDE_CSSPROPERTYVALUE_NoRepeat, (FX_LPCWSTR)L"no-repeat", 0x1235C18B},
+ {FDE_CSSPROPERTYVALUE_Default, (FX_LPCWSTR)L"default", 0x14DA2125},
+ {FDE_CSSPROPERTYVALUE_Transparent, (FX_LPCWSTR)L"transparent", 0x17B64DB2},
+ {FDE_CSSPROPERTYVALUE_Ridge, (FX_LPCWSTR)L"ridge", 0x18EBEE4B},
+ {FDE_CSSPROPERTYVALUE_Right, (FX_LPCWSTR)L"right", 0x193ADE3E},
+ {FDE_CSSPROPERTYVALUE_HorizontalTb, (FX_LPCWSTR)L"horizontal-tb", 0x1A66A86D},
+ {FDE_CSSPROPERTYVALUE_DistributeLetter, (FX_LPCWSTR)L"distribute-letter", 0x1EDBD75C},
+ {FDE_CSSPROPERTYVALUE_DoubleCircle, (FX_LPCWSTR)L"double-circle", 0x1FF082BA},
+ {FDE_CSSPROPERTYVALUE_Ruby, (FX_LPCWSTR)L"ruby", 0x20D66C02},
+ {FDE_CSSPROPERTYVALUE_Collapse, (FX_LPCWSTR)L"collapse", 0x2128D673},
+ {FDE_CSSPROPERTYVALUE_Normal, (FX_LPCWSTR)L"normal", 0x247CF3E9},
+ {FDE_CSSPROPERTYVALUE_Avoid, (FX_LPCWSTR)L"avoid", 0x24E684B3},
+ {FDE_CSSPROPERTYVALUE_UpperRoman, (FX_LPCWSTR)L"upper-roman", 0x28BAC2B6},
+ {FDE_CSSPROPERTYVALUE_Auto, (FX_LPCWSTR)L"auto", 0x2B35B6D9},
+ {FDE_CSSPROPERTYVALUE_Text, (FX_LPCWSTR)L"text", 0x2D08AF85},
+ {FDE_CSSPROPERTYVALUE_XSmall, (FX_LPCWSTR)L"x-small", 0x2D2FCAFE},
+ {FDE_CSSPROPERTYVALUE_Thin, (FX_LPCWSTR)L"thin", 0x2D574D53},
+ {FDE_CSSPROPERTYVALUE_Repeat, (FX_LPCWSTR)L"repeat", 0x306614A1},
+ {FDE_CSSPROPERTYVALUE_Small, (FX_LPCWSTR)L"small", 0x316A3739},
+ {FDE_CSSPROPERTYVALUE_NeResize, (FX_LPCWSTR)L"ne-resize", 0x31FD5E12},
+ {FDE_CSSPROPERTYVALUE_NoContent, (FX_LPCWSTR)L"no-content", 0x33A1C545},
+ {FDE_CSSPROPERTYVALUE_Outside, (FX_LPCWSTR)L"outside", 0x36DF693D},
+ {FDE_CSSPROPERTYVALUE_EResize, (FX_LPCWSTR)L"e-resize", 0x36E19FA4},
+ {FDE_CSSPROPERTYVALUE_TableRow, (FX_LPCWSTR)L"table-row", 0x3912A02D},
+ {FDE_CSSPROPERTYVALUE_Bottom, (FX_LPCWSTR)L"bottom", 0x399F02B5},
+ {FDE_CSSPROPERTYVALUE_Underline, (FX_LPCWSTR)L"underline", 0x3A0273A6},
+ {FDE_CSSPROPERTYVALUE_CjkIdeographic, (FX_LPCWSTR)L"cjk-ideographic", 0x3A641CC4},
+ {FDE_CSSPROPERTYVALUE_SeResize, (FX_LPCWSTR)L"se-resize", 0x3D675B17},
+ {FDE_CSSPROPERTYVALUE_Fixed, (FX_LPCWSTR)L"fixed", 0x3D7DEB10},
+ {FDE_CSSPROPERTYVALUE_Double, (FX_LPCWSTR)L"double", 0x3D98515B},
+ {FDE_CSSPROPERTYVALUE_Solid, (FX_LPCWSTR)L"solid", 0x40623B5B},
+ {FDE_CSSPROPERTYVALUE_RubyBaseGroup, (FX_LPCWSTR)L"ruby-base-group", 0x41014E84},
+ {FDE_CSSPROPERTYVALUE_OpenQuote, (FX_LPCWSTR)L"open-quote", 0x44A41E8D},
+ {FDE_CSSPROPERTYVALUE_Lighter, (FX_LPCWSTR)L"lighter", 0x45BEB7AF},
+ {FDE_CSSPROPERTYVALUE_LowerRoman, (FX_LPCWSTR)L"lower-roman", 0x5044D253},
+ {FDE_CSSPROPERTYVALUE_Strict, (FX_LPCWSTR)L"strict", 0x52F4EBD9},
+ {FDE_CSSPROPERTYVALUE_TableCaption, (FX_LPCWSTR)L"table-caption", 0x5325CD63},
+ {FDE_CSSPROPERTYVALUE_Oblique, (FX_LPCWSTR)L"oblique", 0x53EBDDB1},
+ {FDE_CSSPROPERTYVALUE_Decimal, (FX_LPCWSTR)L"decimal", 0x54034C2F},
+ {FDE_CSSPROPERTYVALUE_Loose, (FX_LPCWSTR)L"loose", 0x54D3A1E2},
+ {FDE_CSSPROPERTYVALUE_Hebrew, (FX_LPCWSTR)L"hebrew", 0x565792DD},
+ {FDE_CSSPROPERTYVALUE_Hidden, (FX_LPCWSTR)L"hidden", 0x573CB40C},
+ {FDE_CSSPROPERTYVALUE_Dashed, (FX_LPCWSTR)L"dashed", 0x58A3DD29},
+ {FDE_CSSPROPERTYVALUE_Embed, (FX_LPCWSTR)L"embed", 0x59C8F27D},
+ {FDE_CSSPROPERTYVALUE_TableRowGroup, (FX_LPCWSTR)L"table-row-group", 0x5A43BD07},
+ {FDE_CSSPROPERTYVALUE_TableColumn, (FX_LPCWSTR)L"table-column", 0x5E705DA3},
+ {FDE_CSSPROPERTYVALUE_Static, (FX_LPCWSTR)L"static", 0x5E7555E8},
+ {FDE_CSSPROPERTYVALUE_Outset, (FX_LPCWSTR)L"outset", 0x61236164},
+ {FDE_CSSPROPERTYVALUE_DecimalLeadingZero, (FX_LPCWSTR)L"decimal-leading-zero", 0x61DFC55D},
+ {FDE_CSSPROPERTYVALUE_KeepWords, (FX_LPCWSTR)L"keep-words", 0x63964801},
+ {FDE_CSSPROPERTYVALUE_KatakanaIroha, (FX_LPCWSTR)L"katakana-iroha", 0x65D7C91C},
+ {FDE_CSSPROPERTYVALUE_Super, (FX_LPCWSTR)L"super", 0x6A4F842F},
+ {FDE_CSSPROPERTYVALUE_Center, (FX_LPCWSTR)L"center", 0x6C51AFC1},
+ {FDE_CSSPROPERTYVALUE_TableHeaderGroup, (FX_LPCWSTR)L"table-header-group", 0x706103D8},
+ {FDE_CSSPROPERTYVALUE_Inside, (FX_LPCWSTR)L"inside", 0x709CB0FC},
+ {FDE_CSSPROPERTYVALUE_XxLarge, (FX_LPCWSTR)L"xx-large", 0x70BB1508},
+ {FDE_CSSPROPERTYVALUE_Triangle, (FX_LPCWSTR)L"triangle", 0x7524EDF6},
+ {FDE_CSSPROPERTYVALUE_RubyTextGroup, (FX_LPCWSTR)L"ruby-text-group", 0x78C2B98E},
+ {FDE_CSSPROPERTYVALUE_Circle, (FX_LPCWSTR)L"circle", 0x7ABEC0D2},
+ {FDE_CSSPROPERTYVALUE_Hiragana, (FX_LPCWSTR)L"hiragana", 0x7BF5E25B},
+ {FDE_CSSPROPERTYVALUE_RepeatX, (FX_LPCWSTR)L"repeat-x", 0x7C8F3226},
+ {FDE_CSSPROPERTYVALUE_RepeatY, (FX_LPCWSTR)L"repeat-y", 0x7C8F3227},
+ {FDE_CSSPROPERTYVALUE_Move, (FX_LPCWSTR)L"move", 0x7DA03417},
+ {FDE_CSSPROPERTYVALUE_HiraganaIroha, (FX_LPCWSTR)L"hiragana-iroha", 0x7EE863FB},
+ {FDE_CSSPROPERTYVALUE_RubyBase, (FX_LPCWSTR)L"ruby-base", 0x7FD1B1EA},
+ {FDE_CSSPROPERTYVALUE_Scroll, (FX_LPCWSTR)L"scroll", 0x84787AEF},
+ {FDE_CSSPROPERTYVALUE_Smaller, (FX_LPCWSTR)L"smaller", 0x849769F0},
+ {FDE_CSSPROPERTYVALUE_TableFooterGroup, (FX_LPCWSTR)L"table-footer-group", 0x85BDD97E},
+ {FDE_CSSPROPERTYVALUE_Baseline, (FX_LPCWSTR)L"baseline", 0x87436BA3},
+ {FDE_CSSPROPERTYVALUE_Separate, (FX_LPCWSTR)L"separate", 0x877C66B5},
+ {FDE_CSSPROPERTYVALUE_Armenian, (FX_LPCWSTR)L"armenian", 0x889BE4EB},
+ {FDE_CSSPROPERTYVALUE_Open, (FX_LPCWSTR)L"open", 0x8B90E1F2},
+ {FDE_CSSPROPERTYVALUE_Relative, (FX_LPCWSTR)L"relative", 0x8C995B5C},
+ {FDE_CSSPROPERTYVALUE_Thick, (FX_LPCWSTR)L"thick", 0x8CC35EB3},
+ {FDE_CSSPROPERTYVALUE_Justify, (FX_LPCWSTR)L"justify", 0x8D269CAE},
+ {FDE_CSSPROPERTYVALUE_Middle, (FX_LPCWSTR)L"middle", 0x947FA00F},
+ {FDE_CSSPROPERTYVALUE_Always, (FX_LPCWSTR)L"always", 0x959AB231},
+ {FDE_CSSPROPERTYVALUE_DistributeSpace, (FX_LPCWSTR)L"distribute-space", 0x97A20E58},
+ {FDE_CSSPROPERTYVALUE_LineEdge, (FX_LPCWSTR)L"line-edge", 0x9A845D2A},
+ {FDE_CSSPROPERTYVALUE_PreWrap, (FX_LPCWSTR)L"pre-wrap", 0x9D59588E},
+ {FDE_CSSPROPERTYVALUE_Medium, (FX_LPCWSTR)L"medium", 0xA084A381},
+ {FDE_CSSPROPERTYVALUE_NResize, (FX_LPCWSTR)L"n-resize", 0xA088968D},
+ {FDE_CSSPROPERTYVALUE_ListItem, (FX_LPCWSTR)L"list-item", 0xA32382B8},
+ {FDE_CSSPROPERTYVALUE_Show, (FX_LPCWSTR)L"show", 0xA66C10C1},
+ {FDE_CSSPROPERTYVALUE_Currentcolor, (FX_LPCWSTR)L"currentColor", 0xA7883922},
+ {FDE_CSSPROPERTYVALUE_NoCloseQuote, (FX_LPCWSTR)L"no-close-quote", 0xA79CBFFB},
+ {FDE_CSSPROPERTYVALUE_VerticalLr, (FX_LPCWSTR)L"vertical-lr", 0xA8673F65},
+ {FDE_CSSPROPERTYVALUE_VerticalRl, (FX_LPCWSTR)L"vertical-rl", 0xA8675E25},
+ {FDE_CSSPROPERTYVALUE_Pointer, (FX_LPCWSTR)L"pointer", 0xA90929C1},
+ {FDE_CSSPROPERTYVALUE_XxSmall, (FX_LPCWSTR)L"xx-small", 0xADE1FC76},
+ {FDE_CSSPROPERTYVALUE_Bold, (FX_LPCWSTR)L"bold", 0xB18313A1},
+ {FDE_CSSPROPERTYVALUE_Both, (FX_LPCWSTR)L"both", 0xB1833CAD},
+ {FDE_CSSPROPERTYVALUE_SmallCaps, (FX_LPCWSTR)L"small-caps", 0xB299428D},
+ {FDE_CSSPROPERTYVALUE_Katakana, (FX_LPCWSTR)L"katakana", 0xB421A4BC},
+ {FDE_CSSPROPERTYVALUE_After, (FX_LPCWSTR)L"after", 0xB6B44172},
+ {FDE_CSSPROPERTYVALUE_Horizontal, (FX_LPCWSTR)L"horizontal", 0xB7732DEA},
+ {FDE_CSSPROPERTYVALUE_Dotted, (FX_LPCWSTR)L"dotted", 0xB88652A4},
+ {FDE_CSSPROPERTYVALUE_Disc, (FX_LPCWSTR)L"disc", 0xBEBC18C3},
+ {FDE_CSSPROPERTYVALUE_Georgian, (FX_LPCWSTR)L"georgian", 0xBEF99E8C},
+ {FDE_CSSPROPERTYVALUE_Inline, (FX_LPCWSTR)L"inline", 0xC02D649F},
+ {FDE_CSSPROPERTYVALUE_Overline, (FX_LPCWSTR)L"overline", 0xC0EC9FA4},
+ {FDE_CSSPROPERTYVALUE_Wait, (FX_LPCWSTR)L"wait", 0xC1613BB5},
+ {FDE_CSSPROPERTYVALUE_BreakAll, (FX_LPCWSTR)L"break-all", 0xC3145BAB},
+ {FDE_CSSPROPERTYVALUE_UpperAlpha, (FX_LPCWSTR)L"upper-alpha", 0xC52D4A9F},
+ {FDE_CSSPROPERTYVALUE_Capitalize, (FX_LPCWSTR)L"capitalize", 0xC5321D46},
+ {FDE_CSSPROPERTYVALUE_Nowrap, (FX_LPCWSTR)L"nowrap", 0xC7994417},
+ {FDE_CSSPROPERTYVALUE_TextBottom, (FX_LPCWSTR)L"text-bottom", 0xC7D08D87},
+ {FDE_CSSPROPERTYVALUE_NoOpenQuote, (FX_LPCWSTR)L"no-open-quote", 0xC8CD7877},
+ {FDE_CSSPROPERTYVALUE_Groove, (FX_LPCWSTR)L"groove", 0xCB24A412},
+ {FDE_CSSPROPERTYVALUE_Progress, (FX_LPCWSTR)L"progress", 0xCD1D9835},
+ {FDE_CSSPROPERTYVALUE_Larger, (FX_LPCWSTR)L"larger", 0xCD3C409D},
+ {FDE_CSSPROPERTYVALUE_CloseQuote, (FX_LPCWSTR)L"close-quote", 0xCF8696D1},
+ {FDE_CSSPROPERTYVALUE_TableCell, (FX_LPCWSTR)L"table-cell", 0xCFB5E595},
+ {FDE_CSSPROPERTYVALUE_PreLine, (FX_LPCWSTR)L"pre-line", 0xD04FEDBC},
+ {FDE_CSSPROPERTYVALUE_Absolute, (FX_LPCWSTR)L"absolute", 0xD0B2D55F},
+ {FDE_CSSPROPERTYVALUE_InlineTable, (FX_LPCWSTR)L"inline-table", 0xD131F494},
+ {FDE_CSSPROPERTYVALUE_BidiOverride, (FX_LPCWSTR)L"bidi-override", 0xD161FDE5},
+ {FDE_CSSPROPERTYVALUE_InlineBlock, (FX_LPCWSTR)L"inline-block", 0xD26A8BD7},
+ {FDE_CSSPROPERTYVALUE_Inset, (FX_LPCWSTR)L"inset", 0xD6F23243},
+ {FDE_CSSPROPERTYVALUE_Crosshair, (FX_LPCWSTR)L"crosshair", 0xD6F8018E},
+ {FDE_CSSPROPERTYVALUE_UpperLatin, (FX_LPCWSTR)L"upper-latin", 0xD9D60531},
+ {FDE_CSSPROPERTYVALUE_Help, (FX_LPCWSTR)L"help", 0xDA002969},
+ {FDE_CSSPROPERTYVALUE_Hide, (FX_LPCWSTR)L"hide", 0xDA69395A},
+ {FDE_CSSPROPERTYVALUE_Uppercase, (FX_LPCWSTR)L"uppercase", 0xDAD595A8},
+ {FDE_CSSPROPERTYVALUE_SResize, (FX_LPCWSTR)L"s-resize", 0xDB3AADF2},
+ {FDE_CSSPROPERTYVALUE_Table, (FX_LPCWSTR)L"table", 0xDB9BE968},
+ {FDE_CSSPROPERTYVALUE_Blink, (FX_LPCWSTR)L"blink", 0xDC36E390},
+ {FDE_CSSPROPERTYVALUE_Block, (FX_LPCWSTR)L"block", 0xDCD480AB},
+ {FDE_CSSPROPERTYVALUE_Start, (FX_LPCWSTR)L"start", 0xE1D9D5AE},
+ {FDE_CSSPROPERTYVALUE_TableColumnGroup, (FX_LPCWSTR)L"table-column-group", 0xE2258EFD},
+ {FDE_CSSPROPERTYVALUE_Italic, (FX_LPCWSTR)L"italic", 0xE31D5396},
+ {FDE_CSSPROPERTYVALUE_LineThrough, (FX_LPCWSTR)L"line-through", 0xE4C5A276},
+ {FDE_CSSPROPERTYVALUE_KeepAll, (FX_LPCWSTR)L"keep-all", 0xE704A72B},
+ {FDE_CSSPROPERTYVALUE_LowerAlpha, (FX_LPCWSTR)L"lower-alpha", 0xECB75A3C},
+ {FDE_CSSPROPERTYVALUE_RunIn, (FX_LPCWSTR)L"run-in", 0xEEC930B9},
+ {FDE_CSSPROPERTYVALUE_Square, (FX_LPCWSTR)L"square", 0xEF85D351},
+ {FDE_CSSPROPERTYVALUE_XLarge, (FX_LPCWSTR)L"x-large", 0xF008E390},
+ {FDE_CSSPROPERTYVALUE_Large, (FX_LPCWSTR)L"large", 0xF4434FCB},
+ {FDE_CSSPROPERTYVALUE_Before, (FX_LPCWSTR)L"before", 0xF4FFCE73},
+ {FDE_CSSPROPERTYVALUE_Left, (FX_LPCWSTR)L"left", 0xF5AD782B},
+ {FDE_CSSPROPERTYVALUE_TextTop, (FX_LPCWSTR)L"text-top", 0xFCB58D45},
+ {FDE_CSSPROPERTYVALUE_RubyText, (FX_LPCWSTR)L"ruby-text", 0xFCC77174},
+ {FDE_CSSPROPERTYVALUE_NoDisplay, (FX_LPCWSTR)L"no-display", 0xFE482860},
+ };
+ static const FDE_CSSMEDIATYPETABLE g_FDE_CSSMediaTypes[] = {
+ {0xF09, 0x02},
+ {0x4880, 0x20},
+ {0x536A, 0x80},
+ {0x741D, 0x10},
+ {0x76ED, 0x08},
+ {0x7CFB, 0x01},
+ {0x9578, 0x04},
+ {0xC8E1, 0x40},
+ {0xD0F9, 0xFF},
+ };
+ static const FDE_CSSLENGTHUNITTABLE g_FDE_CSSLengthUnits[] = {
+ {0x0672, 3},
+ {0x067D, 4},
+ {0x1AF7, 8},
+ {0x2F7A, 7},
+ {0x3ED3, 10},
+ {0x3EE4, 9},
+ {0x3EE8, 5},
+ {0xFC30, 6},
+ };
+ static const FDE_CSSCOLORTABLE g_FDE_CSSColors[] = {
+ {0x031B47FE, 0xff000080},
+ {0x0BB8DF5B, 0xffff0000},
+ {0x0D82A78C, 0xff800000},
+ {0x2ACC82E8, 0xff00ffff},
+ {0x2D083986, 0xff008080},
+ {0x4A6A6195, 0xffc0c0c0},
+ {0x546A8EF3, 0xff808080},
+ {0x65C9169C, 0xffffa500},
+ {0x8422BB61, 0xffffffff},
+ {0x9271A558, 0xff800080},
+ {0xA65A3EE3, 0xffff00ff},
+ {0xB1345708, 0xff0000ff},
+ {0xB6D2CF1F, 0xff808000},
+ {0xD19B5E1C, 0xffffff00},
+ {0xDB64391D, 0xff000000},
+ {0xF616D507, 0xff00ff00},
+ {0xF6EFFF31, 0xff008000},
+ };
+ static const FDE_CSSPERSUDOTABLE g_FDE_CSSPersudoType[] = {
+ {FDE_CSSPERSUDO_After, (FX_LPCWSTR)L":after", 0x16EE1FEC},
+ {FDE_CSSPERSUDO_Before, (FX_LPCWSTR)L":before", 0x7DCDDE2D},
+ };
+ FDE_LPCCSSPERSUDOTABLE FDE_GetCSSPersudoByEnum(FDE_CSSPERSUDO ePersudo)
+ {
+ return (ePersudo < FDE_CSSPERSUDO_NONE) ? (g_FDE_CSSPersudoType + ePersudo) : NULL;
+ }
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = FDE_CSSPROPERTY_MAX - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_DWORD dwMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ dwMid = g_FDE_CSSProperties[iMid].dwHash;
+ if (dwHash == dwMid) {
+ return g_FDE_CSSProperties + iMid;
+ } else if (dwHash > dwMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByEnum(FDE_CSSPROPERTY eName)
+ {
+ return (eName < FDE_CSSPROPERTY_MAX) ? (g_FDE_CSSProperties + eName) : NULL;
+ }
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = FDE_CSSPROPERTYVALUE_MAX - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_DWORD dwMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ dwMid = g_FDE_CSSPropertyValues[iMid].dwHash;
+ if (dwHash == dwMid) {
+ return g_FDE_CSSPropertyValues + iMid;
+ } else if (dwHash > dwMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByEnum(FDE_CSSPROPERTYVALUE eName)
+ {
+ return (eName < FDE_CSSPROPERTYVALUE_MAX) ? (g_FDE_CSSPropertyValues + eName) : NULL;
+ }
+ FDE_LPCCSSMEDIATYPETABLE FDE_GetCSSMediaTypeByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_WORD wHash = (FX_WORD)FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = sizeof(g_FDE_CSSMediaTypes) / sizeof(FDE_CSSMEDIATYPETABLE) - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_WORD uMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ uMid = g_FDE_CSSMediaTypes[iMid].wHash;
+ if (wHash == uMid) {
+ return g_FDE_CSSMediaTypes + iMid;
+ } else if (wHash > uMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSLENGTHUNITTABLE FDE_GetCSSLengthUnitByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_WORD wHash = (FX_WORD)FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = sizeof(g_FDE_CSSLengthUnits) / sizeof(FDE_CSSLENGTHUNITTABLE) - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_WORD wMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ wMid = g_FDE_CSSLengthUnits[iMid].wHash;
+ if (wHash == wMid) {
+ return g_FDE_CSSLengthUnits + iMid;
+ } else if (wHash > wMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSCOLORTABLE FDE_GetCSSColorByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = sizeof(g_FDE_CSSColors) / sizeof(FDE_CSSCOLORTABLE) - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_DWORD dwMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ dwMid = g_FDE_CSSColors[iMid].dwHash;
+ if (dwHash == dwMid) {
+ return g_FDE_CSSColors + iMid;
+ } else if (dwHash > dwMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FX_BOOL FDE_ParseCSSNumber(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_FLOAT &fValue, FDE_CSSPRIMITIVETYPE &eUnit)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ FX_INT32 iUsedLen = 0;
+ fValue = FX_wcstof(pszValue, iValueLen, &iUsedLen);
+ if (iUsedLen <= 0) {
+ return FALSE;
+ }
+ iValueLen -= iUsedLen;
+ pszValue += iUsedLen;
+ eUnit = FDE_CSSPRIMITIVETYPE_Number;
+ if (iValueLen >= 1 && *pszValue == '%') {
+ eUnit = FDE_CSSPRIMITIVETYPE_Percent;
+ } else if (iValueLen == 2) {
+ FDE_LPCCSSLENGTHUNITTABLE pUnit = FDE_GetCSSLengthUnitByName(pszValue, 2);
+ if (pUnit != NULL) {
+ eUnit = (FDE_CSSPRIMITIVETYPE)pUnit->wValue;
+ }
+ }
+ return TRUE;
+ }
+
+ FX_BOOL FDE_ParseCSSString(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ iOffset = 0;
+ iLength = iValueLen;
+ if (iValueLen >= 2) {
+ FX_WCHAR first = pszValue[0], last = pszValue[iValueLen - 1];
+ if ((first == '\"' && last == '\"') || (first == '\'' && last == '\'')) {
+ iOffset = 1, iLength -= 2;
+ }
+ }
+ return iValueLen > 0;
+ }
+
+ FX_BOOL FDE_ParseCSSURI(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ if (iValueLen < 6 || pszValue[iValueLen - 1] != ')' || FX_wcsnicmp((FX_LPCWSTR)L"url(", pszValue, 4)) {
+ return FALSE;
+ }
+ if (FDE_ParseCSSString(pszValue + 4, iValueLen - 5, iOffset, iLength)) {
+ iOffset += 4;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ FX_BOOL FDE_ParseCSSColor(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_ARGB &dwColor)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ if (*pszValue == '#') {
+ switch (iValueLen) {
+ case 4: {
+ FX_BYTE red = FX_Hex2Dec((FX_BYTE)pszValue[1], (FX_BYTE)pszValue[1]);
+ FX_BYTE green = FX_Hex2Dec((FX_BYTE)pszValue[2], (FX_BYTE)pszValue[2]);
+ FX_BYTE blue = FX_Hex2Dec((FX_BYTE)pszValue[3], (FX_BYTE)pszValue[3]);
+ dwColor = ArgbEncode(255, red, green, blue);
+ }
+ return TRUE;
+ case 7: {
+ FX_BYTE red = FX_Hex2Dec((FX_BYTE)pszValue[1], (FX_BYTE)pszValue[2]);
+ FX_BYTE green = FX_Hex2Dec((FX_BYTE)pszValue[3], (FX_BYTE)pszValue[4]);
+ FX_BYTE blue = FX_Hex2Dec((FX_BYTE)pszValue[5], (FX_BYTE)pszValue[6]);
+ dwColor = ArgbEncode(255, red, green, blue);
+ }
+ return TRUE;
+ }
+ } else if (iValueLen >= 10) {
+ if (pszValue[iValueLen - 1] != ')' || FX_wcsnicmp((FX_LPCWSTR)L"rgb(", pszValue, 4)) {
+ return FALSE;
+ }
+ FX_BYTE rgb[3] = {0};
+ FX_FLOAT fValue;
+ FDE_CSSPRIMITIVETYPE eType;
+ CFDE_CSSValueListParser list(pszValue + 4, iValueLen - 5, ',');
+ for (FX_INT32 i = 0; i < 3; ++i) {
+ if (!list.NextValue(eType, pszValue, iValueLen)) {
+ return FALSE;
+ }
+ if (eType != FDE_CSSPRIMITIVETYPE_Number) {
+ return FALSE;
+ }
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ return FALSE;
+ }
+ rgb[i] = eType == FDE_CSSPRIMITIVETYPE_Percent ? FXSYS_round(fValue * 2.55f) : FXSYS_round(fValue);
+ }
+ dwColor = ArgbEncode(255, rgb[0], rgb[1], rgb[2]);
+ return TRUE;
+ } else {
+ FDE_LPCCSSCOLORTABLE pColor = FDE_GetCSSColorByName(pszValue, iValueLen);
+ if (pColor != NULL) {
+ dwColor = pColor->dwValue;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+#ifdef _cplusplus
+};
+#endif
+CFDE_CSSValueList::CFDE_CSSValueList(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list)
+{
+ m_iCount = list.GetSize();
+ FX_INT32 iByteCount = m_iCount * sizeof(IFDE_CSSValue*);
+ m_ppList = (IFDE_CSSValue**)pStaticStore->Alloc(iByteCount);
+ FXSYS_memcpy(m_ppList, list.GetData(), iByteCount);
+}
+FX_BOOL CFDE_CSSValueListParser::NextValue(FDE_CSSPRIMITIVETYPE &eType, FX_LPCWSTR &pStart, FX_INT32 &iLength)
+{
+ while (m_pCur < m_pEnd && (*m_pCur <= ' ' || *m_pCur == m_Separator)) {
+ ++m_pCur;
+ }
+ if (m_pCur >= m_pEnd) {
+ return FALSE;
+ }
+ eType = FDE_CSSPRIMITIVETYPE_Unknown;
+ pStart = m_pCur;
+ iLength = 0;
+ FX_WCHAR wch = *m_pCur;
+ if (wch == '#') {
+ iLength = SkipTo(' ');
+ if (iLength == 4 || iLength == 7) {
+ eType = FDE_CSSPRIMITIVETYPE_RGB;
+ }
+ } else if ((wch >= '0' && wch <= '9') || wch == '.' || wch == '-' || wch == '+') {
+ while (m_pCur < m_pEnd && (*m_pCur > ' ' && *m_pCur != m_Separator)) {
+ ++m_pCur;
+ }
+ iLength = m_pCur - pStart;
+ if (iLength > 0) {
+ eType = FDE_CSSPRIMITIVETYPE_Number;
+ }
+ } else if (wch == '\"' || wch == '\'') {
+ pStart++;
+ iLength = SkipTo(wch) - 1;
+ m_pCur++;
+ eType = FDE_CSSPRIMITIVETYPE_String;
+ } else if (m_pEnd - m_pCur > 5 && m_pCur[3] == '(') {
+ if (FX_wcsnicmp((FX_LPCWSTR)L"url", m_pCur, 3) == 0) {
+ wch = m_pCur[4];
+ if (wch == '\"' || wch == '\'') {
+ pStart += 5;
+ iLength = SkipTo(wch) - 6;
+ m_pCur += 2;
+ } else {
+ pStart += 4;
+ iLength = SkipTo(')') - 4;
+ m_pCur++;
+ }
+ eType = FDE_CSSPRIMITIVETYPE_URI;
+ } else if (FX_wcsnicmp((FX_LPCWSTR)L"rgb", m_pCur, 3) == 0) {
+ iLength = SkipTo(')') + 1;
+ m_pCur++;
+ eType = FDE_CSSPRIMITIVETYPE_RGB;
+ }
+ } else {
+ iLength = SkipTo(m_Separator, TRUE, TRUE);
+ eType = FDE_CSSPRIMITIVETYPE_String;
+ }
+ return m_pCur <= m_pEnd && iLength > 0;
+}
+FX_INT32 CFDE_CSSValueListParser::SkipTo(FX_WCHAR wch, FX_BOOL bWSSeparator , FX_BOOL bBrContinue )
+{
+ FX_LPCWSTR pStart = m_pCur;
+ if (!bBrContinue) {
+ if (bWSSeparator)
+ while (++m_pCur < m_pEnd && *m_pCur != wch && *m_pCur > ' ') ;
+ else
+ while (++m_pCur < m_pEnd && *m_pCur != wch) ;
+ } else {
+ FX_INT32 iBracketCount = 0;
+ if (bWSSeparator) {
+ while (m_pCur < m_pEnd && *m_pCur != wch && *m_pCur > ' ') {
+ if (*m_pCur == '(') {
+ iBracketCount++;
+ } else if (*m_pCur == ')') {
+ iBracketCount--;
+ }
+ m_pCur++;
+ }
+ } else {
+ while (m_pCur < m_pEnd && *m_pCur != wch) {
+ if (*m_pCur == '(') {
+ iBracketCount++;
+ } else if (*m_pCur == ')') {
+ iBracketCount--;
+ }
+ m_pCur++;
+ }
+ }
+ while (iBracketCount > 0 && m_pCur < m_pEnd) {
+ if (*m_pCur == ')') {
+ iBracketCount--;
+ }
+ m_pCur++;
+ }
+ }
+ return m_pCur - pStart;
+}
diff --git a/xfa/src/fdp/src/css/fde_cssdatatable.h b/xfa/src/fdp/src/css/fde_cssdatatable.h
new file mode 100644
index 0000000000..0ebcccfab7
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdatatable.h
@@ -0,0 +1,195 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSDATATABLE
+#define _FDE_CSSDATATABLE
+class CFDE_CSSFunction: public CFX_Target
+{
+public:
+ CFDE_CSSFunction(FX_LPCWSTR pszFuncName, IFDE_CSSValueList *pArgList): m_pszFuncName(pszFuncName), m_pArgList(pArgList)
+ {
+ FXSYS_assert(pArgList != NULL);
+ }
+ FX_INT32 CountArgs() const
+ {
+ return m_pArgList->CountValues();
+ }
+ IFDE_CSSValue* GetArgs(FX_INT32 index) const
+ {
+ return m_pArgList->GetValue(index);
+ }
+ FX_LPCWSTR GetFuncName() const
+ {
+ return m_pszFuncName;
+ };
+
+protected:
+ IFDE_CSSValueList *m_pArgList;
+ FX_LPCWSTR m_pszFuncName;
+};
+class CFDE_CSSPrimitiveValue : public IFDE_CSSPrimitiveValue, public CFX_Target
+{
+public:
+ CFDE_CSSPrimitiveValue(const CFDE_CSSPrimitiveValue &src)
+ {
+ *this = src;
+ }
+ CFDE_CSSPrimitiveValue(FX_ARGB color) : m_eType(FDE_CSSPRIMITIVETYPE_RGB), m_dwColor(color) { }
+ CFDE_CSSPrimitiveValue(FDE_CSSPROPERTYVALUE eValue) : m_eType(FDE_CSSPRIMITIVETYPE_Enum) , m_eEnum(eValue) { }
+ CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE eType, FX_FLOAT fValue) : m_eType(eType), m_fNumber(fValue) { }
+ CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE eType, FX_LPCWSTR pValue) : m_eType(eType), m_pString(pValue)
+ {
+ FXSYS_assert(m_pString != NULL);
+ }
+ CFDE_CSSPrimitiveValue(CFDE_CSSFunction *pFunction) : m_eType(FDE_CSSPRIMITIVETYPE_Function), m_pFunction(pFunction) {}
+
+ virtual FDE_CSSPRIMITIVETYPE GetPrimitiveType() const
+ {
+ return m_eType;
+ }
+
+ virtual FX_ARGB GetRGBColor() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_RGB);
+ return m_dwColor;
+ }
+ virtual FX_FLOAT GetFloat() const
+ {
+ FXSYS_assert(m_eType >= FDE_CSSPRIMITIVETYPE_Number && m_eType <= FDE_CSSPRIMITIVETYPE_PC);
+ return m_fNumber;
+ }
+ virtual FX_LPCWSTR GetString(FX_INT32 &iLength) const
+ {
+ FXSYS_assert(m_eType >= FDE_CSSPRIMITIVETYPE_String && m_eType <= FDE_CSSPRIMITIVETYPE_URI);
+ iLength = FXSYS_wcslen(m_pString);
+ return m_pString;
+ }
+ virtual FDE_CSSPROPERTYVALUE GetEnum() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Enum);
+ return m_eEnum;
+ }
+ virtual FX_LPCWSTR GetFuncName() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Function);
+ return m_pFunction->GetFuncName();
+ }
+ virtual FX_INT32 CountArgs() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Function);
+ return m_pFunction->CountArgs();
+ }
+ virtual IFDE_CSSValue* GetArgs(FX_INT32 index) const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Function);
+ return m_pFunction->GetArgs(index);
+ }
+
+ FDE_CSSPRIMITIVETYPE m_eType;
+ union {
+ FX_ARGB m_dwColor;
+ FX_FLOAT m_fNumber;
+ FX_LPCWSTR m_pString;
+ FDE_CSSPROPERTYVALUE m_eEnum;
+ CFDE_CSSFunction *m_pFunction;
+ };
+};
+typedef CFX_ArrayTemplate<IFDE_CSSPrimitiveValue*> CFDE_CSSPrimitiveArray;
+typedef CFX_ArrayTemplate<IFDE_CSSValue*> CFDE_CSSValueArray;
+class CFDE_CSSValueList : public IFDE_CSSValueList, public CFX_Target
+{
+public:
+ CFDE_CSSValueList(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list);
+ virtual FX_INT32 CountValues() const
+ {
+ return m_iCount;
+ }
+ virtual IFDE_CSSValue* GetValue(FX_INT32 index) const
+ {
+ return m_ppList[index];
+ }
+protected:
+ IFDE_CSSValue **m_ppList;
+ FX_INT32 m_iCount;
+};
+class CFDE_CSSValueListParser : public CFX_Target
+{
+public:
+ CFDE_CSSValueListParser(FX_LPCWSTR psz, FX_INT32 iLen, FX_WCHAR separator)
+ : m_Separator(separator), m_pCur(psz), m_pEnd(psz + iLen)
+ {
+ FXSYS_assert(psz != NULL && iLen > 0);
+ }
+ FX_BOOL NextValue(FDE_CSSPRIMITIVETYPE &eType, FX_LPCWSTR &pStart, FX_INT32 &iLength);
+ FX_WCHAR m_Separator;
+protected:
+ FX_INT32 SkipTo(FX_WCHAR wch, FX_BOOL bWSSeparator = FALSE, FX_BOOL bBrContinue = FALSE);
+ FX_LPCWSTR m_pCur;
+ FX_LPCWSTR m_pEnd;
+};
+#ifdef _cplusplus
+extern "C" {
+#endif
+#define FDE_CSSVALUETYPE_MaybeNumber 0x0100
+#define FDE_CSSVALUETYPE_MaybeEnum 0x0200
+#define FDE_CSSVALUETYPE_MaybeURI 0x0400
+#define FDE_CSSVALUETYPE_MaybeString 0x0800
+#define FDE_CSSVALUETYPE_MaybeColor 0x1000
+#define FDE_CSSVALUETYPE_MaybeFunction 0x2000
+#define FDE_IsOnlyValue(type,enum) (((type) & ~(enum)) == FDE_CSSVALUETYPE_Primitive)
+ struct FDE_CSSPROPERTYTABLE {
+ FDE_CSSPROPERTY eName;
+ FX_LPCWSTR pszName;
+ FX_DWORD dwHash;
+ FX_DWORD dwType;
+ };
+ typedef FDE_CSSPROPERTYTABLE const * FDE_LPCCSSPROPERTYTABLE;
+
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByEnum(FDE_CSSPROPERTY eName);
+ struct FDE_CSSPROPERTYVALUETABLE {
+ FDE_CSSPROPERTYVALUE eName;
+ FX_LPCWSTR pszName;
+ FX_DWORD dwHash;
+ };
+ typedef FDE_CSSPROPERTYVALUETABLE const * FDE_LPCCSSPROPERTYVALUETABLE;
+
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByEnum(FDE_CSSPROPERTYVALUE eName);
+ struct FDE_CSSMEDIATYPETABLE {
+ FX_WORD wHash;
+ FX_WORD wValue;
+ };
+ typedef FDE_CSSMEDIATYPETABLE const * FDE_LPCCSSMEDIATYPETABLE;
+ FDE_LPCCSSMEDIATYPETABLE FDE_GetCSSMediaTypeByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ struct FDE_CSSLENGTHUNITTABLE {
+ FX_WORD wHash;
+ FX_WORD wValue;
+ };
+ typedef FDE_CSSLENGTHUNITTABLE const * FDE_LPCCSSLENGTHUNITTABLE;
+ FDE_LPCCSSLENGTHUNITTABLE FDE_GetCSSLengthUnitByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ struct FDE_CSSCOLORTABLE {
+ FX_DWORD dwHash;
+ FX_ARGB dwValue;
+ };
+ typedef FDE_CSSCOLORTABLE const * FDE_LPCCSSCOLORTABLE;
+ FDE_LPCCSSCOLORTABLE FDE_GetCSSColorByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ struct FDE_CSSPERSUDOTABLE {
+ FDE_CSSPERSUDO eName;
+ FX_LPCWSTR pszName;
+ FX_DWORD dwHash;
+ };
+ typedef FDE_CSSPERSUDOTABLE const * FDE_LPCCSSPERSUDOTABLE;
+
+ FDE_LPCCSSPERSUDOTABLE FDE_GetCSSPersudoByEnum(FDE_CSSPERSUDO ePersudo);
+ FX_BOOL FDE_ParseCSSNumber(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_FLOAT &fValue, FDE_CSSPRIMITIVETYPE &eUnit);
+ FX_BOOL FDE_ParseCSSString(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength);
+ FX_BOOL FDE_ParseCSSColor(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_ARGB &dwColor);
+ FX_BOOL FDE_ParseCSSURI(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength);
+#ifdef _cplusplus
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssdeclaration.cpp b/xfa/src/fdp/src/css/fde_cssdeclaration.cpp
new file mode 100644
index 0000000000..4abbc5cfa9
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdeclaration.cpp
@@ -0,0 +1,1193 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_cssdeclaration.h"
+IFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSPROPERTY eProperty, FX_BOOL &bImportant) const
+{
+ for (FDE_LPCSSPROPERTYHOLDER pHolder = m_pFirstProperty; pHolder; pHolder = pHolder->pNext) {
+ if (pHolder->eProperty == eProperty) {
+ bImportant = pHolder->bImportant;
+ return pHolder->pValue;
+ }
+ }
+ return NULL;
+}
+FX_POSITION CFDE_CSSDeclaration::GetStartPosition() const
+{
+ return (FX_POSITION)m_pFirstProperty;
+}
+void CFDE_CSSDeclaration::GetNextProperty(FX_POSITION &pos, FDE_CSSPROPERTY &eProperty, IFDE_CSSValue *&pValue, FX_BOOL &bImportant) const
+{
+ FDE_LPCSSPROPERTYHOLDER pHolder = (FDE_LPCSSPROPERTYHOLDER)pos;
+ FXSYS_assert(pHolder != NULL);
+ bImportant = pHolder->bImportant;
+ eProperty = (FDE_CSSPROPERTY)pHolder->eProperty;
+ pValue = pHolder->pValue;
+ pos = (FX_POSITION)pHolder->pNext;
+}
+FX_POSITION CFDE_CSSDeclaration::GetStartCustom() const
+{
+ return (FX_POSITION)m_pFirstCustom;
+}
+void CFDE_CSSDeclaration::GetNextCustom(FX_POSITION &pos, CFX_WideString &wsName, CFX_WideString &wsValue) const
+{
+ FDE_LPCSSCUSTOMPROPERTY pProperty = (FDE_LPCSSCUSTOMPROPERTY)pos;
+ if (pProperty == NULL) {
+ return;
+ }
+ wsName = pProperty->pwsName;
+ wsValue = pProperty->pwsValue;
+ pos = (FX_POSITION)pProperty->pNext;
+}
+FX_LPCWSTR CFDE_CSSDeclaration::CopyToLocal(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FXSYS_assert(iValueLen > 0);
+ CFX_MapPtrToPtr *pCache = pArgs->pStringCache;
+ FX_LPVOID pKey = NULL;
+ if (pCache) {
+ FX_LPVOID pszCached = NULL;
+ pKey = (FX_LPVOID)(FX_UINTPTR)FX_HashCode_String_GetW(pszValue, iValueLen, FALSE);
+ if (pCache->Lookup(pKey, pszCached)) {
+ return (FX_LPCWSTR)pszCached;
+ }
+ }
+ FX_LPWSTR psz = (FX_LPWSTR)pArgs->pStaticStore->Alloc((iValueLen + 1) * sizeof(FX_WCHAR));
+ if (psz == NULL) {
+ return NULL;
+ }
+ FXSYS_wcsncpy(psz, pszValue, iValueLen);
+ psz[iValueLen] = '\0';
+ if (pCache) {
+ pCache->SetAt(pKey, psz);
+ }
+ return psz;
+}
+IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewNumberValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue) const
+{
+ static CFDE_CSSPrimitiveValue s_ZeroValue(FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ if (eUnit == FDE_CSSPRIMITIVETYPE_Number && FXSYS_fabs(fValue) < 0.001f) {
+ return &s_ZeroValue;
+ }
+ return FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eUnit, fValue);
+}
+inline IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewEnumValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTYVALUE eValue) const
+{
+ return FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eValue);
+}
+void CFDE_CSSDeclaration::AddPropertyHolder(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, FX_BOOL bImportant)
+{
+ FDE_LPCSSPROPERTYHOLDER pHolder = FDE_NewWith(pStaticStore) FDE_CSSPROPERTYHOLDER;
+ pHolder->bImportant = bImportant;
+ pHolder->eProperty = eProperty;
+ pHolder->pValue = pValue;
+ pHolder->pNext = NULL;
+ if (m_pLastProperty == NULL) {
+ m_pLastProperty = m_pFirstProperty = pHolder;
+ } else {
+ m_pLastProperty->pNext = pHolder;
+ m_pLastProperty = pHolder;
+ }
+}
+FX_BOOL CFDE_CSSDeclaration::AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FXSYS_assert(iValueLen > 0);
+ FX_BOOL bImportant = FALSE;
+ if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!'
+ && FX_wcsnicmp((FX_LPCWSTR)L"important", pszValue + iValueLen - 9, 9) == 0) {
+ if ((iValueLen -= 10) == 0) {
+ return FALSE;
+ }
+ bImportant = TRUE;
+ }
+ const FX_DWORD dwType = pArgs->pProperty->dwType;
+ switch (dwType & 0x0F) {
+ case FDE_CSSVALUETYPE_Primitive: {
+ static const FX_DWORD g_ValueGuessOrder[] = {
+ FDE_CSSVALUETYPE_MaybeNumber,
+ FDE_CSSVALUETYPE_MaybeEnum,
+ FDE_CSSVALUETYPE_MaybeColor,
+ FDE_CSSVALUETYPE_MaybeURI,
+ FDE_CSSVALUETYPE_MaybeFunction,
+ FDE_CSSVALUETYPE_MaybeString,
+ };
+ static const FX_INT32 g_ValueGuessCount = sizeof(g_ValueGuessOrder) / sizeof(FX_DWORD);
+ for (FX_INT32 i = 0; i < g_ValueGuessCount; ++i) {
+ const FX_DWORD dwMatch = dwType & g_ValueGuessOrder[i];
+ if (dwMatch == 0) {
+ continue;
+ }
+ IFDE_CSSValue *pCSSValue = NULL;
+ switch (dwMatch) {
+ case FDE_CSSVALUETYPE_MaybeFunction:
+ pCSSValue = ParseFunction(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeNumber:
+ pCSSValue = ParseNumber(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeEnum:
+ pCSSValue = ParseEnum(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeColor:
+ pCSSValue = ParseColor(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeURI:
+ pCSSValue = ParseURI(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeString:
+ pCSSValue = ParseString(pArgs, pszValue, iValueLen);
+ break;
+ default:
+ break;
+ }
+ if (pCSSValue != NULL) {
+ AddPropertyHolder(pArgs->pStaticStore, pArgs->pProperty->eName, pCSSValue, bImportant);
+ return TRUE;
+ }
+ if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) {
+ return FALSE;
+ }
+ }
+ }
+ break;
+ case FDE_CSSVALUETYPE_Shorthand: {
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ IFDE_CSSValue *pColor, *pStyle, *pWidth;
+ switch (pArgs->pProperty->eName) {
+ case FDE_CSSPROPERTY_Font:
+ return ParseFontProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_Background:
+ return ParseBackgroundProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_ListStyle:
+ return ParseListStyleProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_Border:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderLeftColor, FDE_CSSPROPERTY_BorderLeftStyle, FDE_CSSPROPERTY_BorderLeftWidth);
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderTopWidth);
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderRightWidth);
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderBottomColor, FDE_CSSPROPERTY_BorderBottomStyle, FDE_CSSPROPERTY_BorderBottomWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderLeft:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderLeftColor, FDE_CSSPROPERTY_BorderLeftStyle, FDE_CSSPROPERTY_BorderLeftWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderTop:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderTopWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderRight:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderRightWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderBottom:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderBottomColor, FDE_CSSPROPERTY_BorderBottomStyle, FDE_CSSPROPERTY_BorderBottomWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_Overflow:
+ return ParseOverflowProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_ColumnRule:
+ return ParseColumnRuleProperty(pArgs, pszValue, iValueLen, bImportant);
+ default:
+ break;
+ }
+ }
+ break;
+ case FDE_CSSVALUETYPE_List:
+ switch (pArgs->pProperty->eName) {
+ case FDE_CSSPROPERTY_CounterIncrement:
+ case FDE_CSSPROPERTY_CounterReset:
+ return ParseCounterProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_Content:
+ return ParseContentProperty(pArgs, pszValue, iValueLen, bImportant);
+ default:
+ return ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant);
+ }
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_CSSDeclaration::AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszName, FX_INT32 iNameLen, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FDE_LPCSSCUSTOMPROPERTY pProperty = FDE_NewWith(pArgs->pStaticStore) FDE_CSSCUSTOMPROPERTY;
+ pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen);
+ pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ pProperty->pNext = NULL;
+ if (m_pLastCustom == NULL) {
+ m_pLastCustom = m_pFirstCustom = pProperty;
+ } else {
+ m_pLastCustom->pNext = pProperty;
+ m_pLastCustom = pProperty;
+ }
+ return TRUE;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseNumber(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_FLOAT fValue;
+ FDE_CSSPRIMITIVETYPE eUnit;
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) {
+ return NULL;
+ }
+ return NewNumberValue(pArgs->pStaticStore, eUnit, fValue);
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseEnum(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ return pValue ? NewEnumValue(pArgs->pStaticStore, pValue->eName) : NULL;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseColor(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_ARGB dwColor;
+ if (!FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ return NULL;
+ }
+ return FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseURI(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_INT32 iOffset;
+ if (!FDE_ParseCSSURI(pszValue, iValueLen, iOffset, iValueLen)) {
+ return NULL;
+ }
+ if (iValueLen <= 0) {
+ return NULL;
+ }
+ pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen);
+ return pszValue ? FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_URI, pszValue) : NULL;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseString(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_INT32 iOffset;
+ if (!FDE_ParseCSSString(pszValue, iValueLen, iOffset, iValueLen)) {
+ return NULL;
+ }
+ if (iValueLen <= 0) {
+ return NULL;
+ }
+ pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen);
+ return pszValue ? FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue) : NULL;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ if (pszValue[iValueLen - 1] != ')') {
+ return NULL;
+ }
+ FX_INT32 iStartBracket = 0;
+ while (pszValue[iStartBracket] != '(') {
+ if (iStartBracket < iValueLen) {
+ iStartBracket++;
+ } else {
+ return NULL;
+ }
+ }
+ if (iStartBracket == 0) {
+ return NULL;
+ }
+ FX_LPCWSTR pszFuncName = CopyToLocal(pArgs, pszValue, iStartBracket);
+ pszValue += (iStartBracket + 1);
+ iValueLen -= (iStartBracket + 2);
+ CFDE_CSSValueArray argumentArr;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ',');
+ FDE_CSSPRIMITIVETYPE ePrimitiveType;
+ while (parser.NextValue(ePrimitiveType, pszValue, iValueLen)) {
+ switch (ePrimitiveType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pPropertyValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pPropertyValue != NULL) {
+ argumentArr.Add(NewEnumValue(pArgs->pStaticStore, pPropertyValue->eName));
+ continue;
+ }
+ IFDE_CSSValue *pFunctionValue = ParseFunction(pArgs, pszValue, iValueLen);
+ if (pFunctionValue != NULL) {
+ argumentArr.Add(pFunctionValue);
+ continue;
+ }
+ argumentArr.Add(FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, CopyToLocal(pArgs, pszValue, iValueLen)));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, ePrimitiveType)) {
+ argumentArr.Add(NewNumberValue(pArgs->pStaticStore, ePrimitiveType, fValue));
+ }
+ }
+ break;
+ default:
+ argumentArr.Add(FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, CopyToLocal(pArgs, pszValue, iValueLen)));
+ break;
+ }
+ }
+ IFDE_CSSValueList *pArgumentList = FDE_NewWith(pArgs->pStaticStore) CFDE_CSSValueList(pArgs->pStaticStore, argumentArr);
+ CFDE_CSSFunction *pFunction = FDE_NewWith(pArgs->pStaticStore) CFDE_CSSFunction(pszFuncName, pArgumentList);
+ return FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(pFunction);
+}
+FX_BOOL CFDE_CSSDeclaration::ParseContentProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator* pStaticStore = (IFX_MEMAllocator*)pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ FDE_CSSPRIMITIVETYPE eType;
+ CFDE_CSSValueArray list;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_URI:
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen)));
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number:
+ return FALSE;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ case FDE_CSSPROPERTYVALUE_None: {
+ if (list.GetSize() == 0) {
+ list.Add(NewEnumValue(pStaticStore, pValue->eName));
+ } else {
+ return FALSE;
+ }
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_OpenQuote:
+ case FDE_CSSPROPERTYVALUE_CloseQuote:
+ case FDE_CSSPROPERTYVALUE_NoOpenQuote:
+ case FDE_CSSPROPERTYVALUE_NoCloseQuote:
+ list.Add(NewEnumValue(pStaticStore, pValue->eName));
+ break;
+ default:
+ return FALSE;
+ }
+ continue;
+ }
+ IFDE_CSSValue *pFunction = ParseFunction(pArgs, pszValue, iValueLen);
+ if (pFunction != NULL) {
+ list.Add(pFunction);
+ continue;
+ }
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen)));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ return FALSE;
+ default:
+ break;
+ }
+ }
+ if (list.GetSize() == 0) {
+ return FALSE;
+ }
+ AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list), bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseCounterProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ CFDE_CSSValueArray list;
+ CFDE_CSSValueArray listFull;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ if (list.GetSize() == 1) {
+ list.Add(NewNumberValue(pStaticStore, eType, fValue));
+ listFull.Add(FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list));
+ list.RemoveAll();
+ } else {
+ return FALSE;
+ }
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ if (list.GetSize() == 0) {
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ } else {
+ listFull.Add(FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list));
+ list.RemoveAll();
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (list.GetSize() == 1) {
+ listFull.Add(FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list));
+ }
+ if (listFull.GetSize() == 0) {
+ return FALSE;
+ }
+ AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, listFull), bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseValueListProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ FX_WCHAR separator = (pArgs->pProperty->eName == FDE_CSSPROPERTY_FontFamily) ? ',' : ' ';
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, separator);
+ const FX_DWORD dwType = pArgs->pProperty->dwType;
+ FDE_CSSPRIMITIVETYPE eType;
+ CFDE_CSSValueArray list;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number:
+ if (dwType & FDE_CSSVALUETYPE_MaybeNumber) {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ list.Add(NewNumberValue(pStaticStore, eType, fValue));
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String:
+ if (dwType & FDE_CSSVALUETYPE_MaybeColor) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor));
+ continue;
+ }
+ }
+ if (dwType & FDE_CSSVALUETYPE_MaybeEnum) {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ list.Add(NewEnumValue(pStaticStore, pValue->eName));
+ continue;
+ }
+ }
+ if (dwType & FDE_CSSVALUETYPE_MaybeString) {
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ if (dwType & FDE_CSSVALUETYPE_MaybeColor) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (list.GetSize() == 0) {
+ return FALSE;
+ }
+ switch (pArgs->pProperty->eName) {
+ case FDE_CSSPROPERTY_BorderColor:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftColor,
+ FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderBottomColor);
+ case FDE_CSSPROPERTY_BorderStyle:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftStyle,
+ FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderBottomStyle);
+ case FDE_CSSPROPERTY_BorderWidth:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftWidth,
+ FDE_CSSPROPERTY_BorderTopWidth, FDE_CSSPROPERTY_BorderRightWidth, FDE_CSSPROPERTY_BorderBottomWidth);
+ case FDE_CSSPROPERTY_Margin:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_MarginLeft,
+ FDE_CSSPROPERTY_MarginTop, FDE_CSSPROPERTY_MarginRight, FDE_CSSPROPERTY_MarginBottom);
+ case FDE_CSSPROPERTY_Padding:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_PaddingLeft,
+ FDE_CSSPROPERTY_PaddingTop, FDE_CSSPROPERTY_PaddingRight, FDE_CSSPROPERTY_PaddingBottom);
+ default: {
+ CFDE_CSSValueList *pList = FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list);
+ AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, pList, bImportant);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_CSSDeclaration::Add4ValuesProperty(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list, FX_BOOL bImportant, FDE_CSSPROPERTY eLeft, FDE_CSSPROPERTY eTop, FDE_CSSPROPERTY eRight, FDE_CSSPROPERTY eBottom)
+{
+ switch (list.GetSize()) {
+ case 1:
+ AddPropertyHolder(pStaticStore, eLeft, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant);
+ return TRUE;
+ case 2:
+ AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant);
+ return TRUE;
+ case 3:
+ AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant);
+ return TRUE;
+ case 4:
+ AddPropertyHolder(pStaticStore, eLeft, list[3], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant);
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseBorderPropoerty(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR pszValue, FX_INT32 iValueLen, IFDE_CSSValue *&pColor, IFDE_CSSValue *&pStyle, IFDE_CSSValue *&pWidth) const
+{
+ pColor = pStyle = pWidth = NULL;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number:
+ if (pWidth == NULL) {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ pWidth = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ if (pColor == NULL) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSCOLORTABLE pColorItem = FDE_GetCSSColorByName(pszValue, iValueLen);
+ if (pColorItem != NULL) {
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue);
+ }
+ continue;
+ }
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue == NULL) {
+ continue;
+ }
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Thin:
+ case FDE_CSSPROPERTYVALUE_Thick:
+ case FDE_CSSPROPERTYVALUE_Medium:
+ if (pWidth == NULL) {
+ pWidth = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_None:
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ case FDE_CSSPROPERTYVALUE_Dotted:
+ case FDE_CSSPROPERTYVALUE_Dashed:
+ case FDE_CSSPROPERTYVALUE_Solid:
+ case FDE_CSSPROPERTYVALUE_Double:
+ case FDE_CSSPROPERTYVALUE_Groove:
+ case FDE_CSSPROPERTYVALUE_Ridge:
+ case FDE_CSSPROPERTYVALUE_Inset:
+ case FDE_CSSPROPERTYVALUE_Outset:
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ };
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pWidth == NULL) {
+ pWidth = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ }
+ return TRUE;
+}
+void CFDE_CSSDeclaration::AddBorderProperty(IFX_MEMAllocator *pStaticStore, IFDE_CSSValue *pColor, IFDE_CSSValue *pStyle, IFDE_CSSValue *pWidth, FX_BOOL bImportant, FDE_CSSPROPERTY eColor, FDE_CSSPROPERTY eStyle, FDE_CSSPROPERTY eWidth)
+{
+ AddPropertyHolder(pStaticStore, eStyle, pStyle, bImportant);
+ AddPropertyHolder(pStaticStore, eWidth, pWidth, bImportant);
+ AddPropertyHolder(pStaticStore, eColor, pColor, bImportant);
+}
+FX_BOOL CFDE_CSSDeclaration::ParseListStyleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pType = NULL, *pImage = NULL, *pPosition = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_URI:
+ if (pImage == NULL) {
+ pImage = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue == NULL) {
+ break;
+ }
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_None:
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pType == NULL) {
+ pImage = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Inside:
+ case FDE_CSSPROPERTYVALUE_Outside:
+ if (pPosition == NULL) {
+ pPosition = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Disc:
+ case FDE_CSSPROPERTYVALUE_Circle:
+ case FDE_CSSPROPERTYVALUE_Square:
+ case FDE_CSSPROPERTYVALUE_Decimal:
+ case FDE_CSSPROPERTYVALUE_DecimalLeadingZero:
+ case FDE_CSSPROPERTYVALUE_LowerRoman:
+ case FDE_CSSPROPERTYVALUE_UpperRoman:
+ case FDE_CSSPROPERTYVALUE_LowerGreek:
+ case FDE_CSSPROPERTYVALUE_LowerLatin:
+ case FDE_CSSPROPERTYVALUE_UpperLatin:
+ case FDE_CSSPROPERTYVALUE_Armenian:
+ case FDE_CSSPROPERTYVALUE_Georgian:
+ case FDE_CSSPROPERTYVALUE_LowerAlpha:
+ case FDE_CSSPROPERTYVALUE_UpperAlpha:
+ if (pType == NULL) {
+ pType = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ };
+ break;
+ default:
+ break;
+ }
+ }
+ if (pPosition == NULL) {
+ pPosition = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Outside);
+ }
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pType == NULL) {
+ pType = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStylePosition, pPosition, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleImage, pImage, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleType, pType, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseBackgroundProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pColor = NULL, *pImage = NULL, *pRepeat = NULL;
+ IFDE_CSSPrimitiveValue *pPosX = NULL, *pPosY = NULL, *pAttachment = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_URI:
+ if (pImage == NULL) {
+ pImage = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ break;
+ }
+ if (pPosX == NULL) {
+ pPosX = NewNumberValue(pStaticStore, eType, fValue);
+ } else if (pPosY == NULL) {
+ pPosY = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_None:
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Fixed:
+ case FDE_CSSPROPERTYVALUE_Scroll:
+ if (pAttachment == NULL) {
+ pAttachment = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Repeat:
+ case FDE_CSSPROPERTYVALUE_RepeatX:
+ case FDE_CSSPROPERTYVALUE_RepeatY:
+ case FDE_CSSPROPERTYVALUE_NoRepeat:
+ if (pRepeat == NULL) {
+ pRepeat = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Left:
+ case FDE_CSSPROPERTYVALUE_Right:
+ if (pPosX == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Top:
+ case FDE_CSSPROPERTYVALUE_Bottom:
+ if (pPosY == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Center:
+ if (pPosX == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pPosY == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ FDE_LPCCSSCOLORTABLE pColorItem = FDE_GetCSSColorByName(pszValue, iValueLen);
+ if (pColorItem != NULL)
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ if (pColor == NULL) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pRepeat == NULL) {
+ pRepeat = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Repeat);
+ }
+ if (pAttachment == NULL) {
+ pAttachment = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Scroll);
+ }
+ if (pPosX == NULL) {
+ pPosX = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ } else if (pPosY == NULL) {
+ pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ }
+ CFDE_CSSValueArray position;
+ position.Add(pPosX);
+ position.Add(pPosY);
+ CFDE_CSSValueList *pPosList = FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, position);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundColor, pColor, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundImage, pImage, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundRepeat, pRepeat, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundPosition, pPosList, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundAttachment, pAttachment, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseFontProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, '/');
+ IFDE_CSSPrimitiveValue *pStyle = NULL, *pVariant = NULL, *pWeight = NULL;
+ IFDE_CSSPrimitiveValue *pFontSize = NULL, *pLineHeight = NULL;
+ CFDE_CSSValueArray familyList;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_XxSmall:
+ case FDE_CSSPROPERTYVALUE_XSmall:
+ case FDE_CSSPROPERTYVALUE_Small:
+ case FDE_CSSPROPERTYVALUE_Medium:
+ case FDE_CSSPROPERTYVALUE_Large:
+ case FDE_CSSPROPERTYVALUE_XLarge:
+ case FDE_CSSPROPERTYVALUE_XxLarge:
+ case FDE_CSSPROPERTYVALUE_Smaller:
+ case FDE_CSSPROPERTYVALUE_Larger:
+ if (pFontSize == NULL) {
+ pFontSize = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_Bold:
+ case FDE_CSSPROPERTYVALUE_Bolder:
+ case FDE_CSSPROPERTYVALUE_Lighter:
+ if (pWeight == NULL) {
+ pWeight = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_Italic:
+ case FDE_CSSPROPERTYVALUE_Oblique:
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_SmallCaps:
+ if (pVariant == NULL) {
+ pVariant = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_Normal:
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pVariant == NULL) {
+ pVariant = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pWeight == NULL) {
+ pWeight = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pFontSize == NULL) {
+ pFontSize = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pLineHeight == NULL) {
+ pLineHeight = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ default:
+ break;
+ }
+ }
+ if (pFontSize != NULL) {
+ familyList.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen)));
+ }
+ parser.m_Separator = ',';
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ break;
+ }
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ switch ((FX_INT32)fValue) {
+ case 100:
+ case 200:
+ case 300:
+ case 400:
+ case 500:
+ case 600:
+ case 700:
+ case 800:
+ case 900:
+ if (pWeight == NULL) {
+ pWeight = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, fValue);
+ }
+ continue;
+ }
+ }
+ if (pFontSize == NULL) {
+ pFontSize = NewNumberValue(pStaticStore, eType, fValue);
+ } else if (pLineHeight == NULL) {
+ pLineHeight = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ if (pVariant == NULL) {
+ pVariant = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ if (pWeight == NULL) {
+ pWeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ if (pFontSize == NULL) {
+ pFontSize = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium);
+ }
+ if (pLineHeight == NULL) {
+ pLineHeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontStyle, pStyle, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontVariant, pVariant, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontWeight, pWeight, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontSize, pFontSize, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_LineHeight, pLineHeight, bImportant);
+ if (familyList.GetSize() > 0) {
+ CFDE_CSSValueList *pList = FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, familyList);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontFamily, pList, bImportant);
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseColumnRuleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pColumnRuleWidth = NULL;
+ IFDE_CSSPrimitiveValue *pColumnRuleStyle = NULL;
+ IFDE_CSSPrimitiveValue *pColumnRuleColor = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_None:
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ case FDE_CSSPROPERTYVALUE_Dotted:
+ case FDE_CSSPROPERTYVALUE_Dashed:
+ case FDE_CSSPROPERTYVALUE_Solid:
+ case FDE_CSSPROPERTYVALUE_Double:
+ case FDE_CSSPROPERTYVALUE_Groove:
+ case FDE_CSSPROPERTYVALUE_Ridge:
+ case FDE_CSSPROPERTYVALUE_Inset:
+ case FDE_CSSPROPERTYVALUE_Outset:
+ if (pColumnRuleStyle == NULL) {
+ pColumnRuleStyle = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ if (pColumnRuleColor == NULL) {
+ pColumnRuleColor = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Thin:
+ case FDE_CSSPROPERTYVALUE_Medium:
+ case FDE_CSSPROPERTYVALUE_Thick:
+ if (pColumnRuleWidth == NULL) {
+ pColumnRuleWidth = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ continue;
+ }
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor) && pColumnRuleColor == NULL) {
+ pColumnRuleColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)dwColor);
+ continue;
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType) && pColumnRuleWidth == NULL) {
+ pColumnRuleWidth = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB: {
+ FX_ARGB dwColor;
+ if (pColumnRuleColor == NULL && FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pColumnRuleColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)dwColor);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColumnRuleColor == NULL && pColumnRuleStyle == NULL && pColumnRuleWidth == NULL) {
+ return FALSE;
+ }
+ if (pColumnRuleStyle == NULL) {
+ pColumnRuleStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pColumnRuleWidth == NULL) {
+ pColumnRuleWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium);
+ }
+ if (pColumnRuleColor == NULL) {
+ pColumnRuleColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleStyle, pColumnRuleStyle, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleWidth, pColumnRuleWidth, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleColor, pColumnRuleColor, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseTextEmphasisProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ CFDE_CSSValueArray arrEmphasisStyle;
+ FDE_CSSPRIMITIVETYPE eType;
+ IFDE_CSSPrimitiveValue *pEmphasisColor = NULL;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ arrEmphasisStyle.Add(NewEnumValue(pStaticStore, pValue->eName));
+ continue;
+ }
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pEmphasisColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ continue;
+ }
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ arrEmphasisStyle.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB: {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pEmphasisColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (arrEmphasisStyle.GetSize() != 0) {
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisStyle, FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, arrEmphasisStyle), bImportant);
+ }
+ if (pEmphasisColor != NULL) {
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisColor, pEmphasisColor, bImportant);
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseColumnsProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pColumnWidth = NULL;
+ IFDE_CSSPrimitiveValue *pColumnCount = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue == NULL && pValue->eName == FDE_CSSPROPERTYVALUE_Auto) {
+ pColumnWidth = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number:
+ if (pColumnCount == NULL) {
+ pColumnCount = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ break;
+ default:
+ if (pColumnWidth == NULL) {
+ pColumnWidth = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColumnWidth == NULL && pColumnCount == NULL) {
+ return FALSE;
+ } else if (pColumnWidth == NULL) {
+ pColumnWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto);
+ } else if (pColumnCount == NULL) {
+ pColumnCount = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnWidth, pColumnWidth, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnCount, pColumnCount, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseOverflowProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pOverflowX = NULL;
+ IFDE_CSSPrimitiveValue *pOverflowY = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ if (eType == FDE_CSSPRIMITIVETYPE_String) {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSOVERFLOW_Visible:
+ case FDE_CSSOVERFLOW_Hidden:
+ case FDE_CSSOVERFLOW_Scroll:
+ case FDE_CSSOVERFLOW_Auto:
+ case FDE_CSSOVERFLOW_NoDisplay:
+ case FDE_CSSOVERFLOW_NoContent:
+ if (pOverflowX != NULL && pOverflowY != NULL) {
+ return FALSE;
+ } else if (pOverflowX == NULL) {
+ pOverflowX = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pOverflowY == NULL) {
+ pOverflowY = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ if (pOverflowX == NULL && pOverflowY == NULL) {
+ return FALSE;
+ } else if (pOverflowY == NULL) {
+ pOverflowY = NewEnumValue(pStaticStore, pOverflowX->GetEnum());
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowX, pOverflowX, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowY, pOverflowY, bImportant);
+ return TRUE;
+}
diff --git a/xfa/src/fdp/src/css/fde_cssdeclaration.h b/xfa/src/fdp/src/css/fde_cssdeclaration.h
new file mode 100644
index 0000000000..ca0add9dea
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdeclaration.h
@@ -0,0 +1,70 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSDECLARATION
+#define _FDE_CSSDECLARATION
+#include "fde_cssdatatable.h"
+typedef struct _FDE_CSSPROPERTYHOLDER : public CFX_Target {
+ FX_INT16 eProperty;
+ FX_INT16 bImportant;
+ IFDE_CSSValue *pValue;
+ _FDE_CSSPROPERTYHOLDER *pNext;
+} FDE_CSSPROPERTYHOLDER, *FDE_LPCSSPROPERTYHOLDER;
+typedef struct _FDE_CSSCUSTOMPROPERTY : public CFX_Target {
+ FX_LPCWSTR pwsName;
+ FX_LPCWSTR pwsValue;
+ _FDE_CSSCUSTOMPROPERTY *pNext;
+} FDE_CSSCUSTOMPROPERTY, * FDE_LPCSSCUSTOMPROPERTY;
+typedef struct _FDE_CSSPROPERTYARGS : public CFX_Target {
+ IFX_MEMAllocator *pStaticStore;
+ CFX_MapPtrToPtr *pStringCache;
+ FDE_LPCCSSPROPERTYTABLE pProperty;
+} FDE_CSSPROPERTYARGS;
+typedef FDE_CSSPROPERTYARGS const * FDE_LPCCSSPROPERTYARGS;
+class CFDE_CSSDeclaration : public IFDE_CSSDeclaration, public CFX_Target
+{
+public:
+ CFDE_CSSDeclaration() : m_pFirstProperty(NULL), m_pLastProperty(NULL), m_pFirstCustom(NULL), m_pLastCustom(NULL) { }
+ virtual IFDE_CSSValue* GetProperty(FDE_CSSPROPERTY eProperty, FX_BOOL &bImportant) const;
+ virtual FX_POSITION GetStartPosition() const;
+ virtual void GetNextProperty(FX_POSITION &pos, FDE_CSSPROPERTY &eProperty, IFDE_CSSValue *&pValue, FX_BOOL &bImportant) const;
+ virtual FX_POSITION GetStartCustom() const;
+ virtual void GetNextCustom(FX_POSITION &pos, CFX_WideString &wsName, CFX_WideString &wsValue) const;
+ FX_BOOL AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ FX_BOOL AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszName, FX_INT32 iNameLen, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+protected:
+ FX_BOOL ParseTextEmphasisProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseColumnsProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseColumnRuleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseOverflowProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseFontProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseBackgroundProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseListStyleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseBorderPropoerty(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR pszValue, FX_INT32 iValueLen,
+ IFDE_CSSValue *&pColor, IFDE_CSSValue *&pStyle, IFDE_CSSValue *&pWidth) const;
+ void AddBorderProperty(IFX_MEMAllocator *pStaticStore, IFDE_CSSValue *pColor, IFDE_CSSValue *pStyle, IFDE_CSSValue *pWidth, FX_BOOL bImportant,
+ FDE_CSSPROPERTY eColor, FDE_CSSPROPERTY eStyle, FDE_CSSPROPERTY eWidth);
+ FX_BOOL ParseContentProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseCounterProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseValueListProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL Add4ValuesProperty(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list, FX_BOOL bImportant,
+ FDE_CSSPROPERTY eLeft, FDE_CSSPROPERTY eTop, FDE_CSSPROPERTY eRight, FDE_CSSPROPERTY eBottom);
+ IFDE_CSSValue* ParseNumber(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseEnum(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseColor(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseURI(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseString(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseFunction(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ FX_LPCWSTR CopyToLocal(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ void AddPropertyHolder(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, FX_BOOL bImportant);
+ IFDE_CSSPrimitiveValue* NewNumberValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue) const;
+ IFDE_CSSPrimitiveValue* NewEnumValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTYVALUE eValue) const;
+ FDE_LPCSSPROPERTYHOLDER m_pFirstProperty;
+ FDE_LPCSSPROPERTYHOLDER m_pLastProperty;
+ FDE_LPCSSCUSTOMPROPERTY m_pFirstCustom;
+ FDE_LPCSSCUSTOMPROPERTY m_pLastCustom;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssstyleselector.cpp b/xfa/src/fdp/src/css/fde_cssstyleselector.cpp
new file mode 100644
index 0000000000..6372a8cb20
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstyleselector.cpp
@@ -0,0 +1,1715 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csscache.h"
+#include "fde_cssdeclaration.h"
+#include "fde_cssstyleselector.h"
+FX_INT32 CFDE_CSSCounterStyle::FindIndex(FX_LPCWSTR pszIdentifier)
+{
+ FX_INT32 iCount = m_arrCounterData.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ if (FXSYS_wcscmp(pszIdentifier, m_arrCounterData.ElementAt(i).m_pszIdent) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+void CFDE_CSSCounterStyle::DoUpdateIndex(IFDE_CSSValueList *pList)
+{
+ if (pList == NULL) {
+ return;
+ }
+ FX_INT32 iCount = pList->CountValues();
+ FX_FLOAT fDefValue = 1.0;
+ FX_BOOL bDefIncrement = TRUE;
+ if (pList == m_pCounterReset) {
+ fDefValue = 0.0;
+ bDefIncrement = FALSE;
+ }
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ IFDE_CSSValueList *pCounter = (IFDE_CSSValueList*)pList->GetValue(i);
+ FX_INT32 iLen;
+ FX_LPCWSTR pszIdentifier = ((IFDE_CSSPrimitiveValue*)(pCounter->GetValue(0)))->GetString(iLen);
+ FX_FLOAT fValue = fDefValue;
+ if (pCounter->CountValues() > 1) {
+ fValue = ((IFDE_CSSPrimitiveValue*)(pCounter->GetValue(1)))->GetFloat();
+ }
+ FX_INT32 iIndex = FindIndex(pszIdentifier);
+ if (iIndex == -1) {
+ FDE_CSSCOUNTERDATA data;
+ data.m_pszIdent = pszIdentifier;
+ if (bDefIncrement) {
+ data.m_bIncrement = TRUE;
+ data.m_iIncVal = (FX_INT32)fValue;
+ } else {
+ data.m_iResetVal = (FX_INT32)fValue;
+ data.m_bReset = TRUE;
+ }
+ m_arrCounterData.Add(data);
+ } else {
+ FDE_CSSCOUNTERDATA &data = m_arrCounterData.ElementAt(iIndex);
+ if (bDefIncrement) {
+ data.m_bIncrement = TRUE;
+ data.m_iIncVal += (FX_INT32)fValue;
+ } else {
+ data.m_bReset = TRUE;
+ data.m_iResetVal = (FX_INT32)fValue;
+ }
+ }
+ }
+}
+void CFDE_CSSCounterStyle::UpdateIndex()
+{
+ if (!m_bIndexDirty) {
+ return;
+ }
+ m_arrCounterData.RemoveAll();
+ DoUpdateIndex(m_pCounterInc);
+ DoUpdateIndex(m_pCounterReset);
+ m_bIndexDirty = FALSE;
+}
+FDE_CSSTEXTEMPHASISMARK CFDE_CSSComputedStyle::GetTextEmphasisMark() const
+{
+ if (m_InheritedData.m_eTextEmphasisMark != FDE_CSSTEXTEMPHASISMARK_Auto) {
+ return (FDE_CSSTEXTEMPHASISMARK)m_InheritedData.m_eTextEmphasisMark;
+ }
+ if (m_InheritedData.m_eWritingMode == FDE_CSSWRITINGMODE_HorizontalTb) {
+ return FDE_CSSTEXTEMPHASISMARK_Dot;
+ }
+ return FDE_CSSTEXTEMPHASISMARK_Sesame;
+}
+_FDE_CSSRULEDATA::_FDE_CSSRULEDATA(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl, FX_DWORD dwPos)
+ : pSelector(pSel)
+ , pDeclaration(pDecl)
+ , dwPriority(dwPos)
+ , pNext(NULL)
+{
+ static const FX_DWORD s_Specific[5] = {0x00010000, 0x00010000, 0x00100000, 0x00100000, 0x01000000};
+ for (; pSel != NULL; pSel = pSel->GetNextSelector()) {
+ FDE_CSSSELECTORTYPE eType = pSel->GetType();
+ if (eType > FDE_CSSSELECTORTYPE_Descendant || pSel->GetNameHash() != FDE_CSSUNIVERSALHASH) {
+ dwPriority += s_Specific[eType];
+ }
+ }
+}
+void CFDE_CSSRuleCollection::Clear()
+{
+ m_IDRules.RemoveAll();
+ m_TagRules.RemoveAll();
+ m_ClassRules.RemoveAll();
+ m_pUniversalRules = NULL;
+ m_pStaticStore = NULL;
+ m_iSelectors = 0;
+}
+void CFDE_CSSRuleCollection::AddRulesFrom(const CFDE_CSSStyleSheetArray &sheets, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr)
+{
+ FX_INT32 iSheets = sheets.GetSize();
+ for (FX_INT32 i = 0; i < iSheets; ++i) {
+ IFDE_CSSStyleSheet *pSheet = sheets.GetAt(i);
+ if (FX_DWORD dwMatchMedia = pSheet->GetMediaList() & dwMediaList) {
+ FX_INT32 iRules = pSheet->CountRules();
+ for (FX_INT32 j = 0; j < iRules; j++) {
+ AddRulesFrom(pSheet, pSheet->GetRule(j), dwMatchMedia, pFontMgr);
+ }
+ }
+ }
+}
+void CFDE_CSSRuleCollection::AddRulesFrom(IFDE_CSSStyleSheet *pStyleSheet, IFDE_CSSRule *pRule, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr)
+{
+ switch (pRule->GetType()) {
+ case FDE_CSSRULETYPE_Style: {
+ IFDE_CSSStyleRule *pStyleRule = (IFDE_CSSStyleRule*)pRule;
+ IFDE_CSSDeclaration *pDeclaration = pStyleRule->GetDeclaration();
+ FX_INT32 iSelectors = pStyleRule->CountSelectorLists();
+ for (FX_INT32 i = 0; i < iSelectors; ++i) {
+ IFDE_CSSSelector *pSelector = pStyleRule->GetSelectorList(i);
+ if (pSelector->GetType() == FDE_CSSSELECTORTYPE_Persudo) {
+ FDE_LPCSSRULEDATA pData = NewRuleData(pSelector, pDeclaration);
+ AddRuleTo(m_pPersudoRules, pData);
+ continue;
+ }
+ if (pSelector->GetNameHash() != FDE_CSSUNIVERSALHASH) {
+ AddRuleTo(m_TagRules, pSelector->GetNameHash(), pSelector, pDeclaration);
+ continue;
+ }
+ IFDE_CSSSelector *pNext = pSelector->GetNextSelector();
+ if (pNext == NULL) {
+ FDE_LPCSSRULEDATA pData = NewRuleData(pSelector, pDeclaration);
+ AddRuleTo(m_pUniversalRules, pData);
+ continue;
+ }
+ switch (pNext->GetType()) {
+ case FDE_CSSSELECTORTYPE_ID:
+ AddRuleTo(m_IDRules, pNext->GetNameHash(), pSelector, pDeclaration);
+ break;
+ case FDE_CSSSELECTORTYPE_Class:
+ AddRuleTo(m_ClassRules, pNext->GetNameHash(), pSelector, pDeclaration);
+ break;
+ case FDE_CSSSELECTORTYPE_Descendant:
+ case FDE_CSSSELECTORTYPE_Element:
+ AddRuleTo(m_pUniversalRules, NewRuleData(pSelector, pDeclaration));
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+ }
+ break;
+ case FDE_CSSRULETYPE_Media: {
+ IFDE_CSSMediaRule *pMediaRule = (IFDE_CSSMediaRule*)pRule;
+ if (pMediaRule->GetMediaList() & dwMediaList) {
+ FX_INT32 iRules = pMediaRule->CountRules();
+ for (FX_INT32 i = 0; i < iRules; ++i) {
+ AddRulesFrom(pStyleSheet, pMediaRule->GetRule(i), dwMediaList, pFontMgr);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+void CFDE_CSSRuleCollection::AddRuleTo(CFX_MapPtrToPtr &map, FX_DWORD dwKey, IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl)
+{
+ FX_LPVOID pKey = (FX_LPVOID)(FX_UINTPTR)dwKey;
+ FDE_LPCSSRULEDATA pData = NewRuleData(pSel, pDecl);
+ FDE_LPCSSRULEDATA pList = NULL;
+ if (!map.Lookup(pKey, (FX_LPVOID&)pList)) {
+ map.SetAt(pKey, pData);
+ } else if (AddRuleTo(pList, pData)) {
+ map.SetAt(pKey, pList);
+ }
+}
+inline FX_BOOL CFDE_CSSRuleCollection::AddRuleTo(FDE_LPCSSRULEDATA &pList, FDE_LPCSSRULEDATA pData)
+{
+ if (pList == NULL) {
+ pList = pData;
+ return TRUE;
+ } else {
+ pData->pNext = pList->pNext;
+ pList->pNext = pData;
+ return FALSE;
+ }
+}
+inline FDE_LPCSSRULEDATA CFDE_CSSRuleCollection::NewRuleData(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl)
+{
+ return FDE_NewWith(m_pStaticStore) FDE_CSSRULEDATA(pSel, pDecl, ++m_iSelectors);
+}
+IFDE_CSSStyleSelector* IFDE_CSSStyleSelector::Create()
+{
+ return FDE_New CFDE_CSSStyleSelector;
+}
+CFDE_CSSStyleSelector::CFDE_CSSStyleSelector()
+ : m_pFontMgr(NULL)
+ , m_fDefFontSize(12.0f)
+ , m_pRuleDataStore(NULL)
+ , m_pInlineStyleStore(NULL)
+ , m_pFixedStyleStore(NULL)
+ , m_pAccelerator(NULL)
+{
+ m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_High] = FDE_CSSSTYLESHEETGROUP_Author;
+ m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_Mid] = FDE_CSSSTYLESHEETGROUP_User;
+ m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_Low] = FDE_CSSSTYLESHEETGROUP_UserAgent;
+}
+CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector()
+{
+ Reset();
+ if (m_pInlineStyleStore != NULL) {
+ m_pInlineStyleStore->Release();
+ }
+ if (m_pFixedStyleStore != NULL) {
+ m_pFixedStyleStore->Release();
+ }
+ if (m_pAccelerator != NULL) {
+ FDE_Delete m_pAccelerator;
+ }
+}
+void CFDE_CSSStyleSelector::SetFontMgr(IFX_FontMgr *pFontMgr)
+{
+ m_pFontMgr = pFontMgr;
+}
+void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize)
+{
+ FXSYS_assert(fFontSize > 0);
+ m_fDefFontSize = fFontSize;
+}
+IFDE_CSSAccelerator* CFDE_CSSStyleSelector::InitAccelerator()
+{
+ if (m_pAccelerator == NULL) {
+ m_pAccelerator = FDE_New CFDE_CSSAccelerator;
+ FXSYS_assert(m_pAccelerator != NULL);
+ }
+ m_pAccelerator->Clear();
+ return m_pAccelerator;
+}
+IFDE_CSSComputedStyle* CFDE_CSSStyleSelector::CreateComputedStyle(IFDE_CSSComputedStyle *pParentStyle)
+{
+ if (m_pFixedStyleStore == NULL) {
+ m_pFixedStyleStore = FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 16, sizeof(CFDE_CSSComputedStyle));
+ FXSYS_assert(m_pFixedStyleStore != NULL);
+ }
+ CFDE_CSSComputedStyle *pStyle = FDE_NewWith(m_pFixedStyleStore) CFDE_CSSComputedStyle(m_pFixedStyleStore);
+ if (pParentStyle) {
+ pStyle->m_InheritedData = ((CFDE_CSSComputedStyle*)pParentStyle)->m_InheritedData;
+ } else {
+ pStyle->m_InheritedData.Reset();
+ }
+ pStyle->m_NonInheritedData.Reset();
+ return pStyle;
+}
+FX_BOOL CFDE_CSSStyleSelector::SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType, IFDE_CSSStyleSheet *pSheet)
+{
+ FXSYS_assert(eType < FDE_CSSSTYLESHEETGROUP_MAX);
+ CFDE_CSSStyleSheetArray &dest = m_SheetGroups[eType];
+ dest.RemoveAt(0, dest.GetSize());
+ if (pSheet != NULL) {
+ dest.Add(pSheet);
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_CSSStyleSelector::SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType, const CFDE_CSSStyleSheetArray *pArray)
+{
+ FXSYS_assert(eType < FDE_CSSSTYLESHEETGROUP_MAX);
+ CFDE_CSSStyleSheetArray &dest = m_SheetGroups[eType];
+ if (pArray == NULL) {
+ dest.RemoveAt(0, dest.GetSize());
+ } else {
+ dest.Copy(*pArray);
+ }
+ return TRUE;
+}
+void CFDE_CSSStyleSelector::SetStylePriority(FDE_CSSSTYLESHEETGROUP eType, FDE_CSSSTYLESHEETPRIORITY ePriority)
+{
+ m_ePriorities[ePriority] = eType;
+}
+void CFDE_CSSStyleSelector::UpdateStyleIndex(FX_DWORD dwMediaList)
+{
+ Reset();
+ m_pRuleDataStore = FX_CreateAllocator(FX_ALLOCTYPE_Static, 1024, 0);
+ FXSYS_assert(m_pRuleDataStore != NULL);
+ for (FX_INT32 iGroup = 0; iGroup < FDE_CSSSTYLESHEETGROUP_MAX; ++iGroup) {
+ CFDE_CSSRuleCollection &rules = m_RuleCollection[iGroup];
+ rules.m_pStaticStore = m_pRuleDataStore;
+ rules.AddRulesFrom(m_SheetGroups[iGroup], dwMediaList, m_pFontMgr);
+ }
+}
+void CFDE_CSSStyleSelector::Reset()
+{
+ for (FX_INT32 iGroup = 0; iGroup < FDE_CSSSTYLESHEETGROUP_MAX; ++iGroup) {
+ m_RuleCollection[iGroup].Clear();
+ }
+ if (m_pRuleDataStore != NULL) {
+ m_pRuleDataStore->Release();
+ m_pRuleDataStore = NULL;
+ }
+}
+FX_INT32 CFDE_CSSStyleSelector::MatchDeclarations(IFDE_CSSTagProvider *pTag, CFDE_CSSDeclarationArray &matchedDecls, FDE_CSSPERSUDO ePersudoType)
+{
+ FXSYS_assert(m_pAccelerator != NULL && pTag != NULL);
+ FDE_LPCSSTAGCACHE pCache = m_pAccelerator->GetTopElement();
+ FXSYS_assert(pCache != NULL && pCache->GetTag() == pTag);
+ matchedDecls.RemoveAt(0, matchedDecls.GetSize());
+ for (FX_INT32 ePriority = FDE_CSSSTYLESHEETPRIORITY_MAX - 1; ePriority >= 0; --ePriority) {
+ FDE_CSSSTYLESHEETGROUP eGroup = m_ePriorities[ePriority];
+ CFDE_CSSRuleCollection &rules = m_RuleCollection[eGroup];
+ if (rules.CountSelectors() == 0) {
+ continue;
+ }
+ if (ePersudoType == FDE_CSSPERSUDO_NONE) {
+ MatchRules(pCache, rules.GetUniversalRuleData(), ePersudoType);
+ if (pCache->HashTag()) {
+ MatchRules(pCache, rules.GetTagRuleData(pCache->HashTag()), ePersudoType);
+ }
+ FX_INT32 iCount = pCache->CountHashClass();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ pCache->SetClassIndex(i);
+ MatchRules(pCache, rules.GetClassRuleData(pCache->HashClass()), ePersudoType);
+ }
+ } else {
+ MatchRules(pCache, rules.GetPersudoRuleData(), ePersudoType);
+ }
+ if (m_MatchedRules.GetSize() > 0) {
+ SortRulesTo(matchedDecls);
+ m_MatchedRules.RemoveAt(0, m_MatchedRules.GetSize());
+ }
+ }
+ return matchedDecls.GetSize();
+}
+inline void CFDE_CSSStyleSelector::MatchRules(FDE_LPCSSTAGCACHE pCache, FDE_LPCSSRULEDATA pList, FDE_CSSPERSUDO ePersudoType)
+{
+ while (pList != NULL) {
+ if (MatchSelector(pCache, pList->pSelector, ePersudoType)) {
+ m_MatchedRules.Add(pList);
+ }
+ pList = pList->pNext;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::MatchSelector(FDE_LPCSSTAGCACHE pCache, IFDE_CSSSelector *pSel, FDE_CSSPERSUDO ePersudoType)
+{
+ FX_DWORD dwHash;
+ while (pSel != NULL && pCache != NULL) {
+ switch (pSel->GetType()) {
+ case FDE_CSSSELECTORTYPE_Descendant:
+ dwHash = pSel->GetNameHash();
+ while ((pCache = pCache->GetParent()) != NULL) {
+ if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) {
+ continue;
+ }
+ if (MatchSelector(pCache, pSel->GetNextSelector(), ePersudoType)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ case FDE_CSSSELECTORTYPE_ID:
+ dwHash = pCache->HashID();
+ if (dwHash != pSel->GetNameHash()) {
+ return FALSE;
+ }
+ break;
+ case FDE_CSSSELECTORTYPE_Class:
+ dwHash = pCache->HashClass();
+ if (dwHash != pSel->GetNameHash()) {
+ return FALSE;
+ }
+ break;
+ case FDE_CSSSELECTORTYPE_Element:
+ dwHash = pSel->GetNameHash();
+ if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) {
+ return FALSE;
+ }
+ break;
+ case FDE_CSSSELECTORTYPE_Persudo:
+ dwHash = FDE_GetCSSPersudoByEnum(ePersudoType)->dwHash;
+ if (dwHash != pSel->GetNameHash()) {
+ return FALSE;
+ }
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ pSel = pSel->GetNextSelector();
+ }
+ return pSel == NULL && pCache != NULL;
+}
+void CFDE_CSSStyleSelector::SortRulesTo(CFDE_CSSDeclarationArray &matchDecls)
+{
+ for (FX_INT32 j = m_MatchedRules.GetUpperBound(); j >= 0; --j) {
+ FDE_LPCSSRULEDATA &pMin = m_MatchedRules.ElementAt(j);
+ FX_DWORD dwMin = pMin->dwPriority;
+ for (FX_INT32 i = j - 1; i >= 0; --i) {
+ FDE_LPCSSRULEDATA &pCur = m_MatchedRules.ElementAt(i);
+ if (dwMin > pCur->dwPriority) {
+ dwMin = pCur->dwPriority;
+ FDE_LPCSSRULEDATA p = pMin;
+ pMin = pCur;
+ pCur = p;
+ }
+ }
+ matchDecls.Add(pMin->pDeclaration);
+ }
+}
+void CFDE_CSSStyleSelector::ComputeStyle(IFDE_CSSTagProvider *pTag, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle)
+{
+ CFDE_CSSComputedStyle *pComputedStyle = (CFDE_CSSComputedStyle*)pDestStyle;
+ FXSYS_assert(pTag && iDeclCount >= 0 && pComputedStyle != NULL);
+ FX_POSITION pos = pTag->GetFirstAttribute();
+ if (pos != NULL) {
+ if (m_pInlineStyleStore == NULL) {
+ m_pInlineStyleStore = FX_CreateAllocator(FX_ALLOCTYPE_Static, 2048, 0);
+ }
+ CFDE_CSSDeclaration *pDecl = NULL;
+ CFX_WideStringC wsAttri, wsValue;
+ FX_DWORD dwAttriHash;
+ do {
+ pTag->GetNextAttribute(pos, wsAttri, wsValue);
+ dwAttriHash = FX_HashCode_String_GetW(wsAttri.GetPtr(), wsAttri.GetLength(), TRUE);
+ static const FX_DWORD s_dwStyleHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"style", 5, TRUE);
+ static const FX_DWORD s_dwAlignHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"align", 5, TRUE);
+ if (dwAttriHash == s_dwStyleHash) {
+ if (pDecl == NULL) {
+ pDecl = FDE_NewWith(m_pInlineStyleStore) CFDE_CSSDeclaration;
+ }
+ AppendInlineStyle(pDecl, wsValue.GetPtr(), wsValue.GetLength());
+ } else if (dwAttriHash == s_dwAlignHash) {
+ if (pDecl == NULL) {
+ pDecl = FDE_NewWith(m_pInlineStyleStore) CFDE_CSSDeclaration;
+ }
+ FDE_CSSPROPERTYARGS args;
+ args.pStringCache = NULL;
+ args.pStaticStore = m_pInlineStyleStore;
+ args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSPROPERTY_TextAlign);
+ pDecl->AddProperty(&args, wsValue.GetPtr(), wsValue.GetLength());
+ }
+ } while (pos != NULL);
+ if (pDecl != NULL) {
+ CFDE_CSSDeclarationArray decls;
+ decls.SetSize(iDeclCount + 1);
+ IFDE_CSSDeclaration **ppInline = decls.GetData();
+ FXSYS_memcpy(ppInline, ppDeclArray, iDeclCount * sizeof(IFDE_CSSDeclaration*));
+ ppInline[iDeclCount++] = pDecl;
+ ApplyDeclarations(TRUE, (const IFDE_CSSDeclaration **)ppInline, iDeclCount, pDestStyle);
+ ApplyDeclarations(FALSE, (const IFDE_CSSDeclaration **)ppInline, iDeclCount, pDestStyle);
+ return;
+ }
+ }
+ if (iDeclCount > 0) {
+ FXSYS_assert(ppDeclArray != NULL);
+ ApplyDeclarations(TRUE, ppDeclArray, iDeclCount, pDestStyle);
+ ApplyDeclarations(FALSE, ppDeclArray, iDeclCount, pDestStyle);
+ }
+}
+void CFDE_CSSStyleSelector::ApplyDeclarations(FX_BOOL bPriority, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle)
+{
+ CFDE_CSSComputedStyle *pComputedStyle = (CFDE_CSSComputedStyle*)pDestStyle;
+ IFDE_CSSValue *pVal;
+ FX_BOOL bImportant;
+ FX_INT32 i;
+ if (bPriority) {
+ IFDE_CSSValue *pLastest = NULL, *pImportant = NULL;
+ for (i = 0; i < iDeclCount; ++i) {
+ pVal = ppDeclArray[i]->GetProperty(FDE_CSSPROPERTY_FontSize, bImportant);
+ if (pVal == NULL) {
+ continue;
+ } else if (bImportant) {
+ pImportant = pVal;
+ } else {
+ pLastest = pVal;
+ }
+ }
+ if (pImportant) {
+ ApplyProperty(FDE_CSSPROPERTY_FontSize, pImportant, pComputedStyle);
+ } else if (pLastest) {
+ ApplyProperty(FDE_CSSPROPERTY_FontSize, pLastest, pComputedStyle);
+ }
+ } else {
+ CFDE_CSSDeclarationArray importants;
+ const IFDE_CSSDeclaration *pDecl = NULL;
+ FDE_CSSPROPERTY eProp;
+ FX_POSITION pos;
+ for (i = 0; i < iDeclCount; ++i) {
+ pDecl = ppDeclArray[i];
+ pos = pDecl->GetStartPosition();
+ while (pos != NULL) {
+ pDecl->GetNextProperty(pos, eProp, pVal, bImportant);
+ if (eProp == FDE_CSSPROPERTY_FontSize) {
+ continue;
+ } else if (!bImportant) {
+ ApplyProperty(eProp, pVal, pComputedStyle);
+ } else if (importants.GetSize() == 0 || importants[importants.GetUpperBound()] != pDecl) {
+ importants.Add((IFDE_CSSDeclaration*)pDecl);
+ }
+ }
+ }
+ iDeclCount = importants.GetSize();
+ for (i = 0; i < iDeclCount; ++i) {
+ pDecl = importants[i];
+ pos = pDecl->GetStartPosition();
+ while (pos != NULL) {
+ pDecl->GetNextProperty(pos, eProp, pVal, bImportant);
+ if (bImportant && eProp != FDE_CSSPROPERTY_FontSize) {
+ ApplyProperty(eProp, pVal, pComputedStyle);
+ }
+ }
+ }
+ CFX_WideString wsName, wsValue;
+ pos = pDecl->GetStartCustom();
+ while (pos) {
+ pDecl->GetNextCustom(pos, wsName, wsValue);
+ pComputedStyle->AddCustomStyle(wsName, wsValue);
+ }
+ }
+}
+void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration *pDecl, FX_LPCWSTR psz, FX_INT32 iLen)
+{
+ FXSYS_assert(pDecl != NULL && psz != NULL && iLen > 0);
+ IFDE_CSSSyntaxParser *pSyntax = IFDE_CSSSyntaxParser::Create();
+ if (pSyntax == NULL) {
+ return;
+ }
+ if (pSyntax->Init(psz, iLen, 32, TRUE)) {
+ FX_INT32 iLen;
+ FX_LPCWSTR psz;
+ FDE_CSSPROPERTYARGS args;
+ args.pStringCache = NULL;
+ args.pStaticStore = m_pInlineStyleStore;
+ args.pProperty = NULL;
+ CFX_WideString wsName;
+ for (;;) {
+ FDE_CSSSYNTAXSTATUS eStatus = pSyntax->DoSyntaxParse();
+ if (eStatus == FDE_CSSSYNTAXSTATUS_PropertyName) {
+ psz = pSyntax->GetCurrentString(iLen);
+ args.pProperty = FDE_GetCSSPropertyByName(psz, iLen);
+ if (args.pProperty == NULL) {
+ wsName = CFX_WideStringC(psz, iLen);
+ }
+ } else if (eStatus == FDE_CSSSYNTAXSTATUS_PropertyValue) {
+ if (args.pProperty != NULL) {
+ psz = pSyntax->GetCurrentString(iLen);
+ if (iLen > 0) {
+ pDecl->AddProperty(&args, psz, iLen);
+ }
+ } else if (iLen > 0) {
+ psz = pSyntax->GetCurrentString(iLen);
+ if (iLen > 0) {
+ pDecl->AddProperty(&args, wsName, wsName.GetLength(), psz, iLen);
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ pSyntax->Release();
+}
+void CFDE_CSSStyleSelector::ApplyProperty(FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, CFDE_CSSComputedStyle *pComputedStyle)
+{
+#define FDE_CSSNONINHERITS (pComputedStyle->m_NonInheritedData)
+#define FDE_CSSINHERITS (pComputedStyle->m_InheritedData)
+#define FDE_CSSFONTSIZE (FDE_CSSINHERITS.m_fFontSize)
+ if (pComputedStyle->m_InheritedData.m_pFontFamily && *(FX_DWORD*)pComputedStyle->m_InheritedData.m_pFontFamily == 0xcdcdcdcd) {
+ pComputedStyle = pComputedStyle;
+ }
+ if (pValue->GetType() == FDE_CSSVALUETYPE_Primitive) {
+ IFDE_CSSPrimitiveValue *pPrimitive = (IFDE_CSSPrimitiveValue*)pValue;
+ FDE_CSSPRIMITIVETYPE eType = pPrimitive->GetPrimitiveType();
+ switch (eProperty) {
+ case FDE_CSSPROPERTY_Display:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eDisplay = ToDisplay(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_FontSize: {
+ FX_FLOAT &fFontSize = FDE_CSSFONTSIZE;
+ if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ fFontSize = ApplyNumber(eType, pPrimitive->GetFloat(), fFontSize);
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ fFontSize = ToFontSize(pPrimitive->GetEnum(), fFontSize);
+ }
+ }
+ break;
+ case FDE_CSSPROPERTY_LineHeight:
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSINHERITS.m_fLineHeight = pPrimitive->GetFloat() * FDE_CSSFONTSIZE;
+ } else if (eType > FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ FDE_CSSINHERITS.m_fLineHeight = ApplyNumber(eType, pPrimitive->GetFloat(), FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_TextAlign:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eTextAligh = ToTextAlign(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_TextIndent:
+ SetLengthWithPercent(FDE_CSSINHERITS.m_TextIndent, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_FontWeight:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_wFontWeight = ToFontWeight(pPrimitive->GetEnum());
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FX_INT32 iValue = (FX_INT32)pPrimitive->GetFloat() / 100;
+ if (iValue >= 1 && iValue <= 9) {
+ FDE_CSSINHERITS.m_wFontWeight = iValue * 100;
+ }
+ }
+ break;
+ case FDE_CSSPROPERTY_FontStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eFontStyle = ToFontStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Color:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSINHERITS.m_dwFontColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_MarginLeft:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MarginTop:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MarginRight:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MarginBottom:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingLeft:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingTop:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingRight:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingBottom:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderLeftWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderTopWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderRightWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderBottomWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderLeftStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRLeftStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderTopStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRTopStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderRightStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRRightStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderBottomStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRBottomStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderLeftColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRLeftColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderTopColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRTopColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderRightColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRRightColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderBottomColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRBottomColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_ListStyleType:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eListStyleType = ToListStyleType(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_ListStylePosition:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eListStylePosition = ToListStylePosition(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BackgroundColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBKGColor = pPrimitive->GetRGBColor();
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_dwBKGColor = 0;
+ }
+ break;
+ case FDE_CSSPROPERTY_Visibility:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eVisibility = ToVisibility(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Width:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_BoxSize.cx, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Height:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_BoxSize.cy, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MinWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MinBoxSize.cx, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MinHeight:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MinBoxSize.cy, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MaxWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MaxBoxSize.cx, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MaxHeight:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MaxBoxSize.cy, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_VerticalAlign:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eVerticalAlign = ToVerticalAlign(pPrimitive->GetEnum());
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ FDE_CSSNONINHERITS.m_eVerticalAlign = FDE_CSSVERTICALALIGN_Number;
+ FDE_CSSNONINHERITS.m_fVerticalAlign = ApplyNumber(eType, pPrimitive->GetFloat(), FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_WhiteSpace:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eWhiteSpace = ToWhiteSpace(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_TextTransform:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eTextTransform = ToTextTransform(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_FontVariant:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eFontVariant = ToFontVariant(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_LetterSpacing:
+ if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
+ break;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_LetterSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ SetLengthWithPercent(FDE_CSSINHERITS.m_LetterSpacing, eType, pPrimitive, FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_WordSpacing:
+ if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
+ break;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_WordSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ SetLengthWithPercent(FDE_CSSINHERITS.m_WordSpacing, eType, pPrimitive, FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_Float:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eFloat = ToFloat(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Clear:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eClear = ToClear(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_WritingMode:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eWritingMode = ToWritingMode(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_WordBreak:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eWordBreak = ToWordBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Widows:
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSINHERITS.m_iWidows = (FX_INT32)pPrimitive->GetFloat();
+ }
+ break;
+ case FDE_CSSPROPERTY_Orphans:
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSINHERITS.m_iOrphans = (FX_INT32)pPrimitive->GetFloat();
+ }
+ break;
+ case FDE_CSSPROPERTY_TextEmphasisColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ switch (pPrimitive->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ FDE_CSSINHERITS.m_dwTextEmphasisColor = 0;
+ FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = FALSE;
+ break;
+ case FDE_CSSPROPERTYVALUE_Currentcolor:
+ FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = TRUE;
+ break;
+ default:
+ break;
+ }
+ } else if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSINHERITS.m_dwTextEmphasisColor = pPrimitive->GetRGBColor();
+ FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = FALSE;
+ }
+ break;
+ case FDE_CSSPROPERTY_PageBreakBefore:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePageBreakBefore = ToPageBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_PageBreakAfter:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePageBreakAfter = ToPageBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_PageBreakInside:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePageBreakInside = ToPageBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_OverflowX:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eOverflowX = ToOverflow(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_OverflowY:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eOverflowY = ToOverflow(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_LineBreak:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eLineBreak = ToLineBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnCount:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Auto);
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSNONINHERITS.m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Point, pPrimitive->GetFloat());
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnGap:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnGap, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_ColumnRuleColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwColumnRuleColor = pPrimitive->GetRGBColor();
+ FDE_CSSNONINHERITS.m_bColumnRuleColorSame = FALSE;
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnRuleStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eColumnRuleStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnRuleWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnRuleWidth, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_ColumnWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnWidth, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BackgroundImage:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_pszBKGImage = NULL;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_URI) {
+ FX_INT32 iLength;
+ FDE_CSSNONINHERITS.m_pszBKGImage = pPrimitive->GetString(iLength);
+ }
+ break;
+ case FDE_CSSPROPERTY_Position:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePosition = ToPosition(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Top:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Bottom:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Left:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Right:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_ListStyleImage:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_pszListStyleImage = NULL;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_URI) {
+ FX_INT32 iLength;
+ FDE_CSSINHERITS.m_pszListStyleImage = pPrimitive->GetString(iLength);
+ }
+ break;
+ case FDE_CSSPROPERTY_CaptionSide:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eCaptionSide = ToCaptionSide(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BackgroundRepeat:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBKGRepeat = ToBKGRepeat(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BackgroundAttachment:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBKGAttachment = ToBKGAttachment(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubyAlign:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eRubyAlign = ToRubyAlign(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubyOverhang:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eRubyOverhang = ToRubyOverhang(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubyPosition:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eRubyPosition = ToRubyPosition(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubySpan:
+ FDE_CSSNONINHERITS.m_pRubySpan = pPrimitive;
+ break;
+ default:
+ break;
+ }
+ } else if (pValue->GetType() == FDE_CSSVALUETYPE_List) {
+ IFDE_CSSValueList *pList = (IFDE_CSSValueList*)pValue;
+ FX_INT32 iCount = pList->CountValues();
+ if (iCount > 0) {
+ switch (eProperty) {
+ case FDE_CSSPROPERTY_FontFamily:
+ FDE_CSSINHERITS.m_pFontFamily = pList;
+ break;
+ case FDE_CSSPROPERTY_TextDecoration:
+ FDE_CSSNONINHERITS.m_dwTextDecoration = ToTextDecoration(pList);
+ break;
+ case FDE_CSSPROPERTY_CounterIncrement: {
+ if (FDE_CSSNONINHERITS.m_pCounterStyle == NULL) {
+ FDE_CSSNONINHERITS.m_pCounterStyle = FDE_New CFDE_CSSCounterStyle;
+ }
+ FDE_CSSNONINHERITS.m_pCounterStyle->SetCounterIncrementList(pList);
+ }
+ break;
+ case FDE_CSSPROPERTY_CounterReset: {
+ if (FDE_CSSNONINHERITS.m_pCounterStyle == NULL) {
+ FDE_CSSNONINHERITS.m_pCounterStyle = FDE_New CFDE_CSSCounterStyle;
+ }
+ FDE_CSSNONINHERITS.m_pCounterStyle->SetCounterResetList(pList);
+ }
+ break;
+ case FDE_CSSPROPERTY_Content:
+ FDE_CSSNONINHERITS.m_pContentList = pList;
+ break;
+ case FDE_CSSPROPERTY_Quotes:
+ FDE_CSSINHERITS.m_pQuotes = pList;
+ break;
+ case FDE_CSSPROPERTY_TextCombine: {
+ for (FX_INT32 i = 0; i < pList->CountValues(); i++) {
+ IFDE_CSSPrimitiveValue *pVal = (IFDE_CSSPrimitiveValue*)pList->GetValue(i);
+ switch (pVal->GetPrimitiveType()) {
+ case FDE_CSSPRIMITIVETYPE_Enum: {
+ switch (pVal->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_None: {
+ FDE_CSSNONINHERITS.m_eTextCombine = FDE_CSSTEXTCOMBINE_None;
+ FDE_CSSNONINHERITS.m_bHasTextCombineNumber = FALSE;
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Horizontal: {
+ FDE_CSSNONINHERITS.m_eTextCombine = FDE_CSSTEXTCOMBINE_Horizontal;
+ FDE_CSSNONINHERITS.m_bHasTextCombineNumber = FALSE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number:
+ FDE_CSSNONINHERITS.m_fTextCombineNumber = pVal->GetFloat();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ case FDE_CSSPROPERTY_TextEmphasisStyle: {
+ FDE_CSSTEXTEMPHASISFILL eFill;
+ FDE_CSSTEXTEMPHASISMARK eMark;
+ for (FX_INT32 i = 0; i < pList->CountValues(); i++) {
+ IFDE_CSSPrimitiveValue *pVal = (IFDE_CSSPrimitiveValue*)pList->GetValue(i);
+ switch (pVal->GetPrimitiveType()) {
+ case FDE_CSSPRIMITIVETYPE_Enum: {
+ if (ToTextEmphasisFill(pVal->GetEnum(), eFill)) {
+ FDE_CSSINHERITS.m_eTextEmphasisFill = eFill;
+ continue;
+ } else if (ToTextEmphasisMark(pVal->GetEnum(), eMark)) {
+ FDE_CSSINHERITS.m_eTextEmphasisMark = eMark;
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_CSSINHERITS.m_eTextEmphasisMark = FDE_CSSTEXTEMPHASISMARK_Custom;
+ FX_INT32 iLen;
+ FDE_CSSINHERITS.m_pszTextEmphasisCustomMark = pVal->GetString(iLen);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ FXSYS_assert(FALSE);
+ }
+}
+FX_FLOAT CFDE_CSSStyleSelector::ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue, FX_FLOAT fPercentBase)
+{
+ switch (eUnit) {
+ case FDE_CSSPRIMITIVETYPE_PX:
+ case FDE_CSSPRIMITIVETYPE_Number:
+ return fValue * 72 / 96;
+ case FDE_CSSPRIMITIVETYPE_PT:
+ return fValue;
+ case FDE_CSSPRIMITIVETYPE_EMS:
+ case FDE_CSSPRIMITIVETYPE_EXS:
+ return fValue * fPercentBase;
+ case FDE_CSSPRIMITIVETYPE_Percent:
+ return fValue * fPercentBase / 100.0f;
+ case FDE_CSSPRIMITIVETYPE_CM:
+ return fValue * 28.3464f;
+ case FDE_CSSPRIMITIVETYPE_MM:
+ return fValue * 2.8346f;
+ case FDE_CSSPRIMITIVETYPE_IN:
+ return fValue * 72.0f;
+ case FDE_CSSPRIMITIVETYPE_PC:
+ return fValue / 12.0f;
+ default:
+ return fValue;
+ }
+}
+FDE_CSSRUBYSPAN CFDE_CSSStyleSelector::ToRubySpan(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ default:
+ return FDE_CSSRUBYSPAN_None;
+ }
+}
+FDE_CSSRUBYPOSITION CFDE_CSSStyleSelector::ToRubyPosition(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Before:
+ return FDE_CSSRUBYPOSITION_Before;
+ case FDE_CSSPROPERTYVALUE_After:
+ return FDE_CSSRUBYPOSITION_After;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSRUBYPOSITION_Right;
+ case FDE_CSSPROPERTYVALUE_Inline:
+ return FDE_CSSRUBYPOSITION_Inline;
+ default:
+ return FDE_CSSRUBYPOSITION_Before;
+ }
+}
+FDE_CSSRUBYOVERHANG CFDE_CSSStyleSelector::ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSRUBYOVERHANG_Auto;
+ case FDE_CSSPROPERTYVALUE_Start:
+ return FDE_CSSRUBYOVERHANG_Start;
+ case FDE_CSSPROPERTYVALUE_End:
+ return FDE_CSSRUBYOVERHANG_End;
+ case FDE_CSSPROPERTYVALUE_None:
+ default:
+ return FDE_CSSRUBYOVERHANG_None;
+ }
+}
+FDE_CSSRUBYALIGN CFDE_CSSStyleSelector::ToRubyAlign(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSRUBYALIGN_Auto;
+ case FDE_CSSPROPERTYVALUE_Start:
+ return FDE_CSSRUBYALIGN_Start;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSRUBYALIGN_End;
+ case FDE_CSSPROPERTYVALUE_Center:
+ return FDE_CSSRUBYALIGN_Center;
+ case FDE_CSSPROPERTYVALUE_End:
+ return FDE_CSSRUBYALIGN_End;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSRUBYALIGN_Right;
+ case FDE_CSSPROPERTYVALUE_DistributeLetter:
+ return FDE_CSSRUBYALIGN_DistributeLetter;
+ case FDE_CSSPROPERTYVALUE_DistributeSpace:
+ return FDE_CSSRUBYALIGN_DistributeSpace;
+ case FDE_CSSPROPERTYVALUE_LineEdge:
+ return FDE_CSSRUBYALIGN_LineEdge;
+ default:
+ return FDE_CSSRUBYALIGN_Auto;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISMARK &eMark)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ eMark = FDE_CSSTEXTEMPHASISMARK_None;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Dot:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Dot;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Circle:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Circle;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_DoubleCircle:
+ eMark = FDE_CSSTEXTEMPHASISMARK_DoubleCircle;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Triangle:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Triangle;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Sesame:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Sesame;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISFILL &eFill)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Filled:
+ eFill = FDE_CSSTEXTEMPHASISFILL_Filled;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Open:
+ eFill = FDE_CSSTEXTEMPHASISFILL_Open;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+FDE_CSSBKGATTACHMENT CFDE_CSSStyleSelector::ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Fixed:
+ return FDE_CSSBKGATTACHMENT_Fixed;
+ case FDE_CSSPROPERTYVALUE_Scroll:
+ return FDE_CSSBKGATTACHMENT_Scroll;
+ default:
+ return FDE_CSSBKGATTACHMENT_Fixed;
+ }
+}
+FDE_CSSCAPTIONSIDE CFDE_CSSStyleSelector::ToCaptionSide(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Top:
+ return FDE_CSSCAPTIONSIDE_Top;
+ case FDE_CSSPROPERTYVALUE_Bottom:
+ return FDE_CSSCAPTIONSIDE_Bottom;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSCAPTIONSIDE_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSCAPTIONSIDE_Right;
+ case FDE_CSSPROPERTYVALUE_Before:
+ return FDE_CSSCAPTIONSIDE_Before;
+ case FDE_CSSPROPERTYVALUE_After:
+ return FDE_CSSCAPTIONSIDE_After;
+ default:
+ return FDE_CSSCAPTIONSIDE_Top;
+ }
+}
+FDE_CSSPOSITION CFDE_CSSStyleSelector::ToPosition(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Static:
+ return FDE_CSSPOSITION_Static;
+ case FDE_CSSPROPERTYVALUE_Relative:
+ return FDE_CSSPOSITION_Relative;
+ case FDE_CSSPROPERTYVALUE_Fixed:
+ return FDE_CSSPOSITION_Fixed;
+ case FDE_CSSPROPERTYVALUE_Absolute:
+ return FDE_CSSPOSITION_Absolute;
+ default:
+ return FDE_CSSPOSITION_Static;
+ }
+}
+FDE_CSSCURSOR CFDE_CSSStyleSelector::ToCursor(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSCURSOR_Auto;
+ case FDE_CSSPROPERTYVALUE_Crosshair:
+ return FDE_CSSCURSOR_Crosshair;
+ case FDE_CSSPROPERTYVALUE_Default:
+ return FDE_CSSCURSOR_Default;
+ case FDE_CSSPROPERTYVALUE_Pointer:
+ return FDE_CSSCURSOR_Pointer;
+ case FDE_CSSPROPERTYVALUE_Move:
+ return FDE_CSSCURSOR_Move;
+ case FDE_CSSPROPERTYVALUE_EResize:
+ return FDE_CSSCURSOR_EResize;
+ case FDE_CSSPROPERTYVALUE_NeResize:
+ return FDE_CSSCURSOR_NeResize;
+ case FDE_CSSPROPERTYVALUE_NwResize:
+ return FDE_CSSCURSOR_NwResize;
+ case FDE_CSSPROPERTYVALUE_NResize:
+ return FDE_CSSCURSOR_NResize;
+ case FDE_CSSPROPERTYVALUE_SeResize:
+ return FDE_CSSCURSOR_SeResize;
+ case FDE_CSSPROPERTYVALUE_SwResize:
+ return FDE_CSSCURSOR_SwResize;
+ default:
+ return FDE_CSSCURSOR_Auto;
+ }
+}
+FDE_CSSBKGREPEAT CFDE_CSSStyleSelector::ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Repeat:
+ return FDE_CSSBKGREPEAT_Repeat;
+ case FDE_CSSPROPERTYVALUE_RepeatX:
+ return FDE_CSSBKGREPEAT_RepeatX;
+ case FDE_CSSPROPERTYVALUE_RepeatY:
+ return FDE_CSSBKGREPEAT_RepeatY;
+ case FDE_CSSPROPERTYVALUE_NoRepeat:
+ return FDE_CSSBKGREPEAT_NoRepeat;
+ default:
+ return FDE_CSSBKGREPEAT_Repeat;
+ }
+}
+FDE_CSSTEXTCOMBINE CFDE_CSSStyleSelector::ToTextCombine(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Horizontal:
+ return FDE_CSSTEXTCOMBINE_Horizontal;
+ case FDE_CSSPROPERTYVALUE_None:
+ default:
+ return FDE_CSSTEXTCOMBINE_None;
+ }
+}
+FDE_CSSLINEBREAK CFDE_CSSStyleSelector::ToLineBreak(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSLINEBREAK_Auto;
+ case FDE_CSSPROPERTYVALUE_Loose:
+ return FDE_CSSLINEBREAK_Loose;
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return FDE_CSSLINEBREAK_Normal;
+ case FDE_CSSPROPERTYVALUE_Strict:
+ return FDE_CSSLINEBREAK_Strict;
+ default:
+ return FDE_CSSLINEBREAK_Auto;
+ }
+}
+FDE_CSSOVERFLOW CFDE_CSSStyleSelector::ToOverflow(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Visible:
+ return FDE_CSSOVERFLOW_Visible;
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ return FDE_CSSOVERFLOW_Hidden;
+ case FDE_CSSPROPERTYVALUE_Scroll:
+ return FDE_CSSOVERFLOW_Scroll;
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSOVERFLOW_Auto;
+ case FDE_CSSPROPERTYVALUE_NoDisplay:
+ return FDE_CSSOVERFLOW_NoDisplay;
+ case FDE_CSSPROPERTYVALUE_NoContent:
+ return FDE_CSSOVERFLOW_NoContent;
+ default:
+ return FDE_CSSOVERFLOW_Visible;
+ }
+}
+FDE_CSSWRITINGMODE CFDE_CSSStyleSelector::ToWritingMode(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_HorizontalTb:
+ return FDE_CSSWRITINGMODE_HorizontalTb;
+ case FDE_CSSPROPERTYVALUE_VerticalRl:
+ return FDE_CSSWRITINGMODE_VerticalRl;
+ case FDE_CSSPROPERTYVALUE_VerticalLr:
+ return FDE_CSSWRITINGMODE_VerticalLr;
+ default:
+ return FDE_CSSWRITINGMODE_HorizontalTb;
+ }
+}
+FDE_CSSWORDBREAK CFDE_CSSStyleSelector::ToWordBreak(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return FDE_CSSWORDBREAK_Normal;
+ case FDE_CSSPROPERTYVALUE_KeepAll:
+ return FDE_CSSWORDBREAK_KeepAll;
+ case FDE_CSSPROPERTYVALUE_BreakAll:
+ return FDE_CSSWORDBREAK_BreakAll;
+ case FDE_CSSPROPERTYVALUE_KeepWords:
+ return FDE_CSSWORDBREAK_KeepWords;
+ default:
+ return FDE_CSSWORDBREAK_Normal;
+ }
+}
+FDE_CSSFLOAT CFDE_CSSStyleSelector::ToFloat(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSFLOAT_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSFLOAT_Right;
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSFLOAT_None;
+ default:
+ return FDE_CSSFLOAT_None;
+ }
+}
+FDE_CSSCLEAR CFDE_CSSStyleSelector::ToClear(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSCLEAR_None;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSCLEAR_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSCLEAR_Right;
+ case FDE_CSSPROPERTYVALUE_Both:
+ return FDE_CSSCLEAR_Both;
+ default:
+ return FDE_CSSCLEAR_None;
+ }
+}
+FDE_CSSPAGEBREAK CFDE_CSSStyleSelector::ToPageBreak(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Avoid:
+ return FDE_CSSPAGEBREAK_Avoid;
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSPAGEBREAK_Auto;
+ case FDE_CSSPROPERTYVALUE_Always:
+ return FDE_CSSPAGEBREAK_Always;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSPAGEBREAK_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSPAGEBREAK_Right;
+ default:
+ return FDE_CSSPAGEBREAK_Auto;
+ }
+}
+FDE_CSSDISPLAY CFDE_CSSStyleSelector::ToDisplay(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Inline:
+ return FDE_CSSDISPLAY_Inline;
+ case FDE_CSSPROPERTYVALUE_Block:
+ return FDE_CSSDISPLAY_Block;
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSDISPLAY_None;
+ case FDE_CSSPROPERTYVALUE_ListItem:
+ return FDE_CSSDISPLAY_ListItem;
+ case FDE_CSSPROPERTYVALUE_TableCell:
+ return FDE_CSSDISPLAY_TableCell;
+ case FDE_CSSPROPERTYVALUE_TableRow:
+ return FDE_CSSDISPLAY_TableRow;
+ case FDE_CSSPROPERTYVALUE_Table:
+ return FDE_CSSDISPLAY_Table;
+ case FDE_CSSPROPERTYVALUE_TableCaption:
+ return FDE_CSSDISPLAY_TableCaption;
+ case FDE_CSSPROPERTYVALUE_TableRowGroup:
+ return FDE_CSSDISPLAY_TableRowGroup;
+ case FDE_CSSPROPERTYVALUE_TableHeaderGroup:
+ return FDE_CSSDISPLAY_TableHeaderGroup;
+ case FDE_CSSPROPERTYVALUE_TableFooterGroup:
+ return FDE_CSSDISPLAY_TableFooterGroup;
+ case FDE_CSSPROPERTYVALUE_TableColumnGroup:
+ return FDE_CSSDISPLAY_TableColumnGroup;
+ case FDE_CSSPROPERTYVALUE_TableColumn:
+ return FDE_CSSDISPLAY_TableColumn;
+ case FDE_CSSPROPERTYVALUE_InlineTable:
+ return FDE_CSSDISPLAY_InlineTable;
+ case FDE_CSSPROPERTYVALUE_InlineBlock:
+ return FDE_CSSDISPLAY_InlineBlock;
+ case FDE_CSSPROPERTYVALUE_RunIn:
+ return FDE_CSSDISPLAY_RunIn;
+ case FDE_CSSPROPERTYVALUE_Ruby:
+ return FDE_CSSDISPLAY_Ruby;
+ case FDE_CSSPROPERTYVALUE_RubyBase:
+ return FDE_CSSDISPLAY_RubyBase;
+ case FDE_CSSPROPERTYVALUE_RubyText:
+ return FDE_CSSDISPLAY_RubyText;
+ case FDE_CSSPROPERTYVALUE_RubyBaseGroup:
+ return FDE_CSSDISPLSY_RubyBaseGroup;
+ case FDE_CSSPROPERTYVALUE_RubyTextGroup:
+ return FDE_CSSDISPLAY_RubyTextGroup;
+ default:
+ return FDE_CSSDISPLAY_Inline;
+ }
+}
+FDE_CSSTEXTALIGN CFDE_CSSStyleSelector::ToTextAlign(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSTEXTALIGN_Left;
+ case FDE_CSSPROPERTYVALUE_Center:
+ return FDE_CSSTEXTALIGN_Center;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSTEXTALIGN_Right;
+ case FDE_CSSPROPERTYVALUE_Justify:
+ return FDE_CSSTEXTALIGN_Justify;
+ default:
+ return FDE_CSSTEXTALIGN_Left;
+ }
+}
+FX_WORD CFDE_CSSStyleSelector::ToFontWeight(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return 400;
+ case FDE_CSSPROPERTYVALUE_Bold:
+ return 700;
+ case FDE_CSSPROPERTYVALUE_Bolder:
+ return 900;
+ case FDE_CSSPROPERTYVALUE_Lighter:
+ return 200;
+ default:
+ return 400;
+ }
+}
+FDE_CSSFONTSTYLE CFDE_CSSStyleSelector::ToFontStyle(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Italic:
+ case FDE_CSSPROPERTYVALUE_Oblique:
+ return FDE_CSSFONTSTYLE_Italic;
+ default:
+ return FDE_CSSFONTSTYLE_Normal;
+ }
+}
+FDE_CSSBORDERSTYLE CFDE_CSSStyleSelector::ToBorderStyle(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSBORDERSTYLE_None;
+ case FDE_CSSPROPERTYVALUE_Solid:
+ return FDE_CSSBORDERSTYLE_Solid;
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ return FDE_CSSBORDERSTYLE_Hidden;
+ case FDE_CSSPROPERTYVALUE_Dotted:
+ return FDE_CSSBORDERSTYLE_Dotted;
+ case FDE_CSSPROPERTYVALUE_Dashed:
+ return FDE_CSSBORDERSTYLE_Dashed;
+ case FDE_CSSPROPERTYVALUE_Double:
+ return FDE_CSSBORDERSTYLE_Double;
+ case FDE_CSSPROPERTYVALUE_Groove:
+ return FDE_CSSBORDERSTYLE_Groove;
+ case FDE_CSSPROPERTYVALUE_Ridge:
+ return FDE_CSSBORDERSTYLE_Ridge;
+ case FDE_CSSPROPERTYVALUE_Inset:
+ return FDE_CSSBORDERSTYLE_Inset;
+ case FDE_CSSPROPERTYVALUE_Outset:
+ return FDE_CSSBORDERSTYLE_outset;
+ default:
+ return FDE_CSSBORDERSTYLE_None;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::SetLengthWithPercent(FDE_CSSLENGTH &width, FDE_CSSPRIMITIVETYPE eType, IFDE_CSSPrimitiveValue *pPrimitive, FX_FLOAT fFontSize)
+{
+ if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
+ width.Set(FDE_CSSLENGTHUNIT_Percent, pPrimitive->GetFloat() / 100.0f);
+ return width.NonZero();
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ FX_FLOAT fValue = ApplyNumber(eType, pPrimitive->GetFloat(), fFontSize);
+ width.Set(FDE_CSSLENGTHUNIT_Point, fValue);
+ return width.NonZero();
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ switch (pPrimitive->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ width.Set(FDE_CSSLENGTHUNIT_Auto);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_None:
+ width.Set(FDE_CSSLENGTHUNIT_None);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Thin:
+ width.Set(FDE_CSSLENGTHUNIT_Point, 2);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Medium:
+ width.Set(FDE_CSSLENGTHUNIT_Point, 3);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Thick:
+ width.Set(FDE_CSSLENGTHUNIT_Point, 4);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+FX_FLOAT CFDE_CSSStyleSelector::ToFontSize(FDE_CSSPROPERTYVALUE eValue, FX_FLOAT fCurFontSize)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_XxSmall:
+ return m_fDefFontSize / 1.2f / 1.2f / 1.2f;
+ case FDE_CSSPROPERTYVALUE_XSmall:
+ return m_fDefFontSize / 1.2f / 1.2f;
+ case FDE_CSSPROPERTYVALUE_Small:
+ return m_fDefFontSize / 1.2f;
+ case FDE_CSSPROPERTYVALUE_Medium:
+ return m_fDefFontSize;
+ case FDE_CSSPROPERTYVALUE_Large:
+ return m_fDefFontSize * 1.2f;
+ case FDE_CSSPROPERTYVALUE_XLarge:
+ return m_fDefFontSize * 1.2f * 1.2f;
+ case FDE_CSSPROPERTYVALUE_XxLarge:
+ return m_fDefFontSize * 1.2f * 1.2f * 1.2f;
+ case FDE_CSSPROPERTYVALUE_Larger:
+ return fCurFontSize * 1.2f;
+ case FDE_CSSPROPERTYVALUE_Smaller:
+ return fCurFontSize / 1.2f;
+ default:
+ return fCurFontSize;
+ }
+}
+FDE_CSSVERTICALALIGN CFDE_CSSStyleSelector::ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Baseline:
+ return FDE_CSSVERTICALALIGN_Baseline;
+ case FDE_CSSPROPERTYVALUE_Middle:
+ return FDE_CSSVERTICALALIGN_Middle;
+ case FDE_CSSPROPERTYVALUE_Bottom:
+ return FDE_CSSVERTICALALIGN_Bottom;
+ case FDE_CSSPROPERTYVALUE_Super:
+ return FDE_CSSVERTICALALIGN_Super;
+ case FDE_CSSPROPERTYVALUE_Sub:
+ return FDE_CSSVERTICALALIGN_Sub;
+ case FDE_CSSPROPERTYVALUE_Top:
+ return FDE_CSSVERTICALALIGN_Top;
+ case FDE_CSSPROPERTYVALUE_TextTop:
+ return FDE_CSSVERTICALALIGN_TextTop;
+ case FDE_CSSPROPERTYVALUE_TextBottom:
+ return FDE_CSSVERTICALALIGN_TextBottom;
+ default:
+ return FDE_CSSVERTICALALIGN_Baseline;
+ }
+}
+FDE_CSSLISTSTYLETYPE CFDE_CSSStyleSelector::ToListStyleType(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSLISTSTYLETYPE_None;
+ case FDE_CSSPROPERTYVALUE_Disc:
+ return FDE_CSSLISTSTYLETYPE_Disc;
+ case FDE_CSSPROPERTYVALUE_Circle:
+ return FDE_CSSLISTSTYLETYPE_Circle;
+ case FDE_CSSPROPERTYVALUE_Square:
+ return FDE_CSSLISTSTYLETYPE_Square;
+ case FDE_CSSPROPERTYVALUE_Decimal:
+ return FDE_CSSLISTSTYLETYPE_Decimal;
+ case FDE_CSSPROPERTYVALUE_DecimalLeadingZero:
+ return FDE_CSSLISTSTYLETYPE_DecimalLeadingZero;
+ case FDE_CSSPROPERTYVALUE_LowerRoman:
+ return FDE_CSSLISTSTYLETYPE_LowerRoman;
+ case FDE_CSSPROPERTYVALUE_UpperRoman:
+ return FDE_CSSLISTSTYLETYPE_UpperRoman;
+ case FDE_CSSPROPERTYVALUE_LowerGreek:
+ return FDE_CSSLISTSTYLETYPE_LowerGreek;
+ case FDE_CSSPROPERTYVALUE_LowerLatin:
+ return FDE_CSSLISTSTYLETYPE_LowerLatin;
+ case FDE_CSSPROPERTYVALUE_UpperLatin:
+ return FDE_CSSLISTSTYLETYPE_UpperLatin;
+ case FDE_CSSPROPERTYVALUE_Armenian:
+ return FDE_CSSLISTSTYLETYPE_Armenian;
+ case FDE_CSSPROPERTYVALUE_Georgian:
+ return FDE_CSSLISTSTYLETYPE_Georgian;
+ case FDE_CSSPROPERTYVALUE_LowerAlpha:
+ return FDE_CSSLISTSTYLETYPE_LowerAlpha;
+ case FDE_CSSPROPERTYVALUE_UpperAlpha:
+ return FDE_CSSLISTSTYLETYPE_UpperAlpha;
+ case FDE_CSSPROPERTYVALUE_CjkIdeographic:
+ return FDE_CSSLISTSTYLETYPE_CjkIdeographic;
+ case FDE_CSSPROPERTYVALUE_Hebrew:
+ return FDE_CSSLISTSTYLETYPE_Hebrew;
+ case FDE_CSSLISTSTYLETYPE_Hiragana:
+ return FDE_CSSLISTSTYLETYPE_Hiragana;
+ case FDE_CSSLISTSTYLETYPE_HiraganaIroha:
+ return FDE_CSSLISTSTYLETYPE_HiraganaIroha;
+ case FDE_CSSLISTSTYLETYPE_Katakana:
+ return FDE_CSSLISTSTYLETYPE_Katakana;
+ case FDE_CSSLISTSTYLETYPE_KatakanaIroha:
+ return FDE_CSSLISTSTYLETYPE_KatakanaIroha;
+ default:
+ return FDE_CSSLISTSTYLETYPE_Disc;
+ }
+}
+FDE_CSSLISTSTYLEPOSITION CFDE_CSSStyleSelector::ToListStylePosition(FDE_CSSPROPERTYVALUE eValue)
+{
+ return eValue == FDE_CSSPROPERTYVALUE_Inside ? FDE_CSSLISTSTYLEPOSITION_Inside : FDE_CSSLISTSTYLEPOSITION_Outside;
+}
+FDE_CSSVISIBILITY CFDE_CSSStyleSelector::ToVisibility(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Visible:
+ return FDE_CSSVISIBILITY_Visible;
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ return FDE_CSSVISIBILITY_Hidden;
+ case FDE_CSSPROPERTYVALUE_Collapse:
+ return FDE_CSSVISIBILITY_Collapse;
+ default:
+ return FDE_CSSVISIBILITY_Visible;
+ }
+}
+FDE_CSSWHITESPACE CFDE_CSSStyleSelector::ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return FDE_CSSWHITESPACE_Normal;
+ case FDE_CSSPROPERTYVALUE_Pre:
+ return FDE_CSSWHITESPACE_Pre;
+ case FDE_CSSPROPERTYVALUE_Nowrap:
+ return FDE_CSSWHITESPACE_Nowrap;
+ case FDE_CSSPROPERTYVALUE_PreWrap:
+ return FDE_CSSWHITESPACE_PreWrap;
+ case FDE_CSSPROPERTYVALUE_PreLine:
+ return FDE_CSSWHITESPACE_PreLine;
+ default:
+ return FDE_CSSWHITESPACE_Normal;
+ }
+}
+FX_DWORD CFDE_CSSStyleSelector::ToTextDecoration(IFDE_CSSValueList *pValue)
+{
+ FX_DWORD dwDecoration = 0;
+ for (FX_INT32 i = pValue->CountValues() - 1; i >= 0; --i) {
+ IFDE_CSSPrimitiveValue *pPrimitive = (IFDE_CSSPrimitiveValue*)pValue->GetValue(i);
+ if (pPrimitive->GetPrimitiveType() == FDE_CSSPRIMITIVETYPE_Enum) {
+ switch (pPrimitive->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_Underline:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
+ break;
+ case FDE_CSSPROPERTYVALUE_LineThrough:
+ dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
+ break;
+ case FDE_CSSPROPERTYVALUE_Overline:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Overline;
+ break;
+ case FDE_CSSPROPERTYVALUE_Blink:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Blink;
+ break;
+ case FDE_CSSPROPERTYVALUE_Double:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Double;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return dwDecoration;
+}
+FDE_CSSTEXTTRANSFORM CFDE_CSSStyleSelector::ToTextTransform(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSTEXTTRANSFORM_None;
+ case FDE_CSSPROPERTYVALUE_Capitalize:
+ return FDE_CSSTEXTTRANSFORM_Capitalize;
+ case FDE_CSSPROPERTYVALUE_Uppercase:
+ return FDE_CSSTEXTTRANSFORM_UpperCase;
+ case FDE_CSSPROPERTYVALUE_Lowercase:
+ return FDE_CSSTEXTTRANSFORM_LowerCase;
+ default:
+ return FDE_CSSTEXTTRANSFORM_None;
+ }
+}
+FDE_CSSFONTVARIANT CFDE_CSSStyleSelector::ToFontVariant(FDE_CSSPROPERTYVALUE eValue)
+{
+ return eValue == FDE_CSSPROPERTYVALUE_SmallCaps ? FDE_CSSFONTVARIANT_SmallCaps : FDE_CSSFONTVARIANT_Normal;
+}
diff --git a/xfa/src/fdp/src/css/fde_cssstyleselector.h b/xfa/src/fdp/src/css/fde_cssstyleselector.h
new file mode 100644
index 0000000000..4100299664
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstyleselector.h
@@ -0,0 +1,1000 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSSTYLESELECTOR
+#define _FDE_CSSSTYLESELECTOR
+#define FDE_CSSUNIVERSALHASH ('*')
+typedef struct _FDE_CSSRULEDATA : public CFX_Target {
+public:
+ _FDE_CSSRULEDATA(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl, FX_DWORD dwPos);
+ IFDE_CSSSelector *pSelector;
+ IFDE_CSSDeclaration *pDeclaration;
+ FX_DWORD dwPriority;
+ _FDE_CSSRULEDATA *pNext;
+} FDE_CSSRULEDATA, * FDE_LPCSSRULEDATA;
+typedef CFX_ArrayTemplate<FDE_LPCSSRULEDATA> CFDE_CSSRuleDataArray;
+class CFDE_CSSRuleCollection : public CFX_Target
+{
+public:
+ CFDE_CSSRuleCollection() : m_pStaticStore(NULL), m_pUniversalRules(NULL) , m_iSelectors(0), m_pPersudoRules(NULL) { }
+ ~CFDE_CSSRuleCollection()
+ {
+ Clear();
+ }
+ void AddRulesFrom(const CFDE_CSSStyleSheetArray &sheets, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr);
+ void Clear();
+
+ FX_INT32 CountSelectors() const
+ {
+ return m_iSelectors;
+ }
+ FDE_LPCSSRULEDATA GetIDRuleData(FX_DWORD dwIDHash)
+ {
+ FX_LPVOID pData;
+ return m_IDRules.Lookup((FX_LPVOID)(FX_UINTPTR)dwIDHash, pData) ? (FDE_LPCSSRULEDATA)pData : NULL;
+ }
+ FDE_LPCSSRULEDATA GetTagRuleData(FX_DWORD dwTagHasn)
+ {
+ FX_LPVOID pData;
+ return m_TagRules.Lookup((FX_LPVOID)(FX_UINTPTR)dwTagHasn, pData) ? (FDE_LPCSSRULEDATA)pData : NULL;
+ }
+ FDE_LPCSSRULEDATA GetClassRuleData(FX_DWORD dwIDHash)
+ {
+ FX_LPVOID pData;
+ return m_ClassRules.Lookup((FX_LPVOID)(FX_UINTPTR)dwIDHash, pData) ? (FDE_LPCSSRULEDATA)pData : NULL;
+ }
+ FDE_LPCSSRULEDATA GetUniversalRuleData()
+ {
+ return m_pUniversalRules;
+ }
+ FDE_LPCSSRULEDATA GetPersudoRuleData()
+ {
+ return m_pPersudoRules;
+ }
+ IFX_MEMAllocator *m_pStaticStore;
+protected:
+ void AddRulesFrom(IFDE_CSSStyleSheet *pStyleSheet, IFDE_CSSRule *pRule, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr);
+ void AddRuleTo(CFX_MapPtrToPtr &map, FX_DWORD dwKey, IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl);
+ FX_BOOL AddRuleTo(FDE_LPCSSRULEDATA &pList, FDE_LPCSSRULEDATA pData);
+ FDE_LPCSSRULEDATA NewRuleData(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl);
+ CFX_MapPtrToPtr m_IDRules;
+ CFX_MapPtrToPtr m_TagRules;
+ CFX_MapPtrToPtr m_ClassRules;
+ FDE_LPCSSRULEDATA m_pUniversalRules;
+ FDE_LPCSSRULEDATA m_pPersudoRules;
+ FX_INT32 m_iSelectors;
+};
+class CFDE_CSSAccelerator;
+class CFDE_CSSComputedStyle;
+class CFDE_CSSStyleSelector : public IFDE_CSSStyleSelector, public CFX_Target
+{
+public:
+ CFDE_CSSStyleSelector();
+ ~CFDE_CSSStyleSelector();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual void SetFontMgr(IFX_FontMgr *pFontMgr);
+ virtual void SetDefFontSize(FX_FLOAT fFontSize);
+
+ virtual FX_BOOL SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType, IFDE_CSSStyleSheet *pSheet);
+ virtual FX_BOOL SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType, const CFDE_CSSStyleSheetArray *pArray);
+ virtual void SetStylePriority(FDE_CSSSTYLESHEETGROUP eType, FDE_CSSSTYLESHEETPRIORITY ePriority);
+ virtual void UpdateStyleIndex(FX_DWORD dwMediaList);
+ virtual IFDE_CSSAccelerator* InitAccelerator();
+ virtual IFDE_CSSComputedStyle* CreateComputedStyle(IFDE_CSSComputedStyle *pParentStyle);
+ virtual FX_INT32 MatchDeclarations(IFDE_CSSTagProvider *pTag, CFDE_CSSDeclarationArray &matchedDecls, FDE_CSSPERSUDO ePersudoType = FDE_CSSPERSUDO_NONE);
+ virtual void ComputeStyle(IFDE_CSSTagProvider *pTag, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle);
+protected:
+ void Reset();
+ void MatchRules(FDE_LPCSSTAGCACHE pCache, FDE_LPCSSRULEDATA pList, FDE_CSSPERSUDO ePersudoType);
+ void SortRulesTo(CFDE_CSSDeclarationArray &matchDecls);
+ FX_BOOL MatchSelector(FDE_LPCSSTAGCACHE pCache, IFDE_CSSSelector *pSel, FDE_CSSPERSUDO ePersudoType);
+ void AppendInlineStyle(CFDE_CSSDeclaration *pDecl, FX_LPCWSTR psz, FX_INT32 iLen);
+ void ApplyDeclarations(FX_BOOL bPriority, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle);
+ void ApplyProperty(FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, CFDE_CSSComputedStyle *pComputedStyle);
+
+ FX_FLOAT ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue, FX_FLOAT fPercentBase);
+ FX_BOOL SetLengthWithPercent(FDE_CSSLENGTH &width, FDE_CSSPRIMITIVETYPE eType, IFDE_CSSPrimitiveValue *pPrimitive, FX_FLOAT fFontSize);
+ FX_FLOAT ToFontSize(FDE_CSSPROPERTYVALUE eValue, FX_FLOAT fCurFontSize);
+ FDE_CSSDISPLAY ToDisplay(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSTEXTALIGN ToTextAlign(FDE_CSSPROPERTYVALUE eValue);
+ FX_WORD ToFontWeight(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSFONTSTYLE ToFontStyle(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSBORDERSTYLE ToBorderStyle(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSVERTICALALIGN ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSLISTSTYLETYPE ToListStyleType(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSLISTSTYLEPOSITION ToListStylePosition(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSVISIBILITY ToVisibility(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSWHITESPACE ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue);
+ FX_DWORD ToTextDecoration(IFDE_CSSValueList *pList);
+ FDE_CSSTEXTTRANSFORM ToTextTransform(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSFONTVARIANT ToFontVariant(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSFLOAT ToFloat(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSCLEAR ToClear(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSWRITINGMODE ToWritingMode(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSWORDBREAK ToWordBreak(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSPAGEBREAK ToPageBreak(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSOVERFLOW ToOverflow(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSLINEBREAK ToLineBreak(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSTEXTCOMBINE ToTextCombine(FDE_CSSPROPERTYVALUE eValue);
+ FX_BOOL ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISMARK &eMark);
+ FX_BOOL ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISFILL &eFill);
+ FDE_CSSCURSOR ToCursor(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSPOSITION ToPosition(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSCAPTIONSIDE ToCaptionSide(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSBKGREPEAT ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSBKGATTACHMENT ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYALIGN ToRubyAlign(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYOVERHANG ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYPOSITION ToRubyPosition(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYSPAN ToRubySpan(FDE_CSSPROPERTYVALUE eValue);
+ IFX_FontMgr *m_pFontMgr;
+ FX_FLOAT m_fDefFontSize;
+ IFX_MEMAllocator *m_pRuleDataStore;
+ CFDE_CSSStyleSheetArray m_SheetGroups[FDE_CSSSTYLESHEETGROUP_MAX];
+ CFDE_CSSRuleCollection m_RuleCollection[FDE_CSSSTYLESHEETGROUP_MAX];
+ FDE_CSSSTYLESHEETGROUP m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_MAX];
+ IFX_MEMAllocator *m_pInlineStyleStore;
+ IFX_MEMAllocator *m_pFixedStyleStore;
+ CFDE_CSSAccelerator *m_pAccelerator;
+ CFDE_CSSRuleDataArray m_MatchedRules;
+};
+typedef struct _FDE_CSSCOUNTERDATA {
+public:
+ _FDE_CSSCOUNTERDATA()
+ {
+ FX_memset(this, 0, sizeof(_FDE_CSSCOUNTERDATA));
+ }
+ FX_BOOL GetCounterIncrement(FX_INT32 &iValue)
+ {
+ iValue = m_iIncVal;
+ return m_bIncrement;
+ }
+ FX_BOOL GetCounterReset(FX_INT32 &iValue)
+ {
+ iValue = m_iResetVal;
+ return m_bReset;
+ }
+ FX_LPCWSTR m_pszIdent;
+ FX_BOOL m_bIncrement;
+ FX_BOOL m_bReset;
+ FX_INT32 m_iIncVal;
+ FX_INT32 m_iResetVal;
+} FDE_CSSCOUNTERDATA, *FDE_LPCSSCOUNTERDATA;
+class CFDE_CSSCounterStyle
+{
+public:
+ CFDE_CSSCounterStyle(): m_pCounterInc(NULL), m_pCounterReset(NULL) {}
+ void SetCounterIncrementList(IFDE_CSSValueList *pList)
+ {
+ m_pCounterInc = pList;
+ m_bIndexDirty = TRUE;
+ }
+ void SetCounterResetList(IFDE_CSSValueList *pList)
+ {
+ m_pCounterReset = pList;
+ m_bIndexDirty = TRUE;
+ }
+ FX_INT32 CountCounters()
+ {
+ UpdateIndex();
+ return m_arrCounterData.GetSize();
+ }
+ FX_BOOL GetCounterIncrement(FX_INT32 index, FX_INT32 &iValue)
+ {
+ UpdateIndex();
+ return m_arrCounterData.ElementAt(index).GetCounterIncrement(iValue);
+ }
+ FX_BOOL GetCounterReset(FX_INT32 index, FX_INT32 &iValue)
+ {
+ UpdateIndex();
+ return m_arrCounterData.ElementAt(index).GetCounterReset(iValue);
+ }
+ FX_LPCWSTR GetCounterIdentifier(FX_INT32 index)
+ {
+ UpdateIndex();
+ return m_arrCounterData.ElementAt(index).m_pszIdent;
+ }
+protected:
+ void UpdateIndex();
+ void DoUpdateIndex(IFDE_CSSValueList *pList);
+ FX_INT32 FindIndex(FX_LPCWSTR pszIdentifier);
+ IFDE_CSSValueList *m_pCounterInc;
+ IFDE_CSSValueList *m_pCounterReset;
+ CFX_ArrayTemplate<FDE_CSSCOUNTERDATA> m_arrCounterData;
+ FX_BOOL m_bIndexDirty;
+};
+class CFDE_CSSInheritedData
+{
+public:
+ void Reset()
+ {
+ FX_memset(this, 0, sizeof(CFDE_CSSInheritedData));
+ m_LetterSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ m_WordSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ m_TextIndent.Set(FDE_CSSLENGTHUNIT_Point, 0);
+ m_fFontSize = 12.0f;
+ m_fLineHeight = 14.0f;
+ m_wFontWeight = 400;
+ m_dwFontColor = 0xFF000000;
+ m_iWidows = 2;
+ m_bTextEmphasisColorCurrent = TRUE;
+ m_iOrphans = 2;
+ }
+ FX_LPCWSTR m_pszListStyleImage;
+ FDE_CSSLENGTH m_LetterSpacing;
+ FDE_CSSLENGTH m_WordSpacing;
+ FDE_CSSLENGTH m_TextIndent;
+ IFDE_CSSValueList *m_pFontFamily;
+ IFDE_CSSValueList *m_pQuotes;
+ IFDE_CSSValueList *m_pCursorUris;
+ FDE_CSSCURSOR m_eCursor;
+ FX_FLOAT m_fFontSize;
+ FX_FLOAT m_fLineHeight;
+ FX_ARGB m_dwFontColor;
+ FX_ARGB m_dwTextEmphasisColor;
+ FX_WORD m_wFontWeight;
+ FX_INT32 m_iWidows;
+ FX_INT32 m_iOrphans;
+ FX_LPCWSTR m_pszTextEmphasisCustomMark;
+ FX_WORD m_eFontVariant : 1;
+ FX_WORD m_eFontStyle : 1;
+ FX_WORD m_bTextEmphasisColorCurrent: 1;
+ FX_WORD m_eTextAligh : 2;
+ FX_WORD m_eVisibility : 2;
+ FX_WORD m_eWhiteSpace : 3;
+ FX_WORD m_eTextTransform : 2;
+ FX_WORD m_eWritingMode : 2;
+ FX_WORD m_eWordBreak : 2;
+ FX_WORD m_eLineBreak : 2;
+ FX_WORD m_eTextEmphasisFill : 1;
+ FX_WORD m_eTextEmphasisMark : 3;
+ FX_WORD m_eCaptionSide : 3;
+
+ FX_WORD m_eRubyAlign : 4;
+ FX_WORD m_eRubyOverhang : 2;
+ FX_WORD m_eRubyPosition : 2;
+};
+class CFDE_CSSNonInheritedData
+{
+public:
+ void Reset()
+ {
+ FX_memset(this, 0, sizeof(CFDE_CSSNonInheritedData));
+ m_MarginWidth = m_BorderWidth = m_PaddingWidth.Set(FDE_CSSLENGTHUNIT_Point, 0);
+ m_MinBoxSize.Set(FDE_CSSLENGTHUNIT_Point, 0);
+ m_MaxBoxSize.Set(FDE_CSSLENGTHUNIT_None);
+ m_eDisplay = FDE_CSSDISPLAY_Inline;
+ m_fVerticalAlign = 0.0f;
+ m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Auto);
+ m_ColumnGap.Set(FDE_CSSLENGTHUNIT_Normal);
+ m_bColumnRuleColorSame = TRUE;
+ m_ColumnWidth.Set(FDE_CSSLENGTHUNIT_Auto);
+ m_ColumnRuleWidth.Set(FDE_CSSLENGTHUNIT_Auto);
+ m_eTextCombine = FDE_CSSTEXTCOMBINE_None;
+ }
+
+ IFDE_CSSValueList *m_pContentList;
+ CFDE_CSSCounterStyle *m_pCounterStyle;
+ FDE_CSSRECT m_MarginWidth;
+ FDE_CSSRECT m_BorderWidth;
+ FDE_CSSRECT m_PaddingWidth;
+ FDE_CSSSIZE m_BoxSize;
+ FDE_CSSSIZE m_MinBoxSize;
+ FDE_CSSSIZE m_MaxBoxSize;
+ FDE_CSSPOINT m_BKGPosition;
+ FX_LPCWSTR m_pszBKGImage;
+ FX_ARGB m_dwBKGColor;
+ FX_ARGB m_dwBDRLeftColor;
+ FX_ARGB m_dwBDRTopColor;
+ FX_ARGB m_dwBDRRightColor;
+ FX_ARGB m_dwBDRBottomColor;
+ IFDE_CSSValue *m_pRubySpan;
+ FDE_CSSLENGTH m_ColumnCount;
+ FDE_CSSLENGTH m_ColumnGap;
+ FDE_CSSLENGTH m_ColumnRuleWidth;
+ FDE_CSSLENGTH m_ColumnWidth;
+ FX_ARGB m_dwColumnRuleColor;
+ FDE_CSSLENGTH m_Top;
+ FDE_CSSLENGTH m_Bottom;
+ FDE_CSSLENGTH m_Left;
+ FDE_CSSLENGTH m_Right;
+
+ FX_FLOAT m_fVerticalAlign;
+ FX_FLOAT m_fTextCombineNumber;
+ FX_DWORD m_eBDRLeftStyle : 4;
+ FX_DWORD m_eBDRTopStyle : 4;
+ FX_DWORD m_eBDRRightStyle : 4;
+ FX_DWORD m_eBDRBottomStyle : 4;
+ FX_DWORD m_eDisplay : 5;
+ FX_DWORD m_eVerticalAlign : 4;
+ FX_DWORD m_eListStyleType : 5;
+ FX_DWORD m_eColumnRuleStyle : 4;
+ FX_DWORD m_ePageBreakInside : 3;
+ FX_DWORD m_ePageBreakAfter : 3;
+ FX_DWORD m_ePageBreakBefore : 3;
+ FX_DWORD m_ePosition : 2;
+ FX_DWORD m_eBKGRepeat : 2;
+ FX_DWORD m_eFloat : 2;
+ FX_DWORD m_eClear : 2;
+ FX_DWORD m_eOverflowX : 3;
+ FX_DWORD m_eOverflowY : 3;
+ FX_DWORD m_eListStylePosition: 1;
+ FX_DWORD m_eBKGAttachment : 1;
+ FX_DWORD m_bHasMargin : 1;
+ FX_DWORD m_bHasBorder : 1;
+ FX_DWORD m_bHasPadding : 1;
+ FX_DWORD m_dwTextDecoration : 5;
+ FX_DWORD m_eTextCombine : 1;
+ FX_DWORD m_bColumnRuleColorSame : 1;
+ FX_DWORD m_bHasTextCombineNumber : 1;
+};
+class CFDE_CSSComputedStyle : public IFDE_CSSComputedStyle, public IFDE_CSSFontStyle,
+ public IFDE_CSSBoundaryStyle, public IFDE_CSSPositionStyle,
+ public IFDE_CSSParagraphStyle, public IFDE_CSSBackgroundStyle,
+ public IFDE_CSSVisualStyle, public IFDE_CSSListStyle,
+ public IFDE_CSSMultiColumnStyle, public IFDE_CSSGeneratedContentStyle,
+ public IFDE_CSSTableStyle, public IFDE_CSSRubyStyle,
+ public CFX_Target
+{
+public:
+ CFDE_CSSComputedStyle(IFX_MEMAllocator *pAlloc) : m_dwRefCount(1), m_pAllocator(pAlloc) {}
+ ~CFDE_CSSComputedStyle() {}
+ virtual FX_DWORD AddRef()
+ {
+ return ++m_dwRefCount;
+ }
+ virtual FX_DWORD Release()
+ {
+ FX_DWORD dwRefCount = --m_dwRefCount;
+ if (dwRefCount == 0) {
+ if (m_NonInheritedData.m_pCounterStyle != NULL) {
+ FDE_Delete m_NonInheritedData.m_pCounterStyle;
+ }
+ FDE_DeleteWith(CFDE_CSSComputedStyle, m_pAllocator, this);
+ }
+ return dwRefCount;
+ }
+
+ virtual void Reset()
+ {
+ m_InheritedData.Reset();
+ m_NonInheritedData.Reset();
+ }
+ virtual IFDE_CSSFontStyle* GetFontStyles() const
+ {
+ return (IFDE_CSSFontStyle * const)this;
+ }
+ virtual IFDE_CSSBoundaryStyle* GetBoundaryStyles() const
+ {
+ return (IFDE_CSSBoundaryStyle * const)this;
+ }
+ virtual IFDE_CSSPositionStyle* GetPositionStyles() const
+ {
+ return (IFDE_CSSPositionStyle * const)this;
+ }
+ virtual IFDE_CSSParagraphStyle* GetParagraphStyles() const
+ {
+ return (IFDE_CSSParagraphStyle * const)this;
+ }
+ virtual IFDE_CSSBackgroundStyle* GetBackgroundStyles() const
+ {
+ return (IFDE_CSSBackgroundStyle * const)this;
+ }
+ virtual IFDE_CSSVisualStyle* GetVisualStyles() const
+ {
+ return (IFDE_CSSVisualStyle * const)this;
+ }
+ virtual IFDE_CSSListStyle* GetListStyles() const
+ {
+ return (IFDE_CSSListStyle * const)this;
+ }
+ virtual IFDE_CSSTableStyle* GetTableStyle() const
+ {
+ return (IFDE_CSSTableStyle * const)this;
+ }
+ virtual IFDE_CSSMultiColumnStyle* GetMultiColumnStyle() const
+ {
+ return (IFDE_CSSMultiColumnStyle * const)this;
+ }
+ virtual IFDE_CSSGeneratedContentStyle* GetGeneratedContentStyle() const
+ {
+ return (IFDE_CSSGeneratedContentStyle * const)this;
+ }
+ virtual IFDE_CSSRubyStyle* GetRubyStyle() const
+ {
+ return (IFDE_CSSRubyStyle * const)this;
+ }
+ virtual FX_BOOL GetCustomStyle(FX_WSTR wsName, CFX_WideString &wsValue) const
+ {
+ for (FX_INT32 i = m_CustomProperties.GetSize() - 2; i > -1; i -= 2) {
+ if (wsName == m_CustomProperties[i]) {
+ wsValue = m_CustomProperties[i + 1];
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ virtual FDE_CSSRUBYALIGN GetRubyAlign() const
+ {
+ return (FDE_CSSRUBYALIGN)m_InheritedData.m_eRubyAlign;
+ }
+ virtual FDE_CSSRUBYPOSITION GetRubyPosition() const
+ {
+ return (FDE_CSSRUBYPOSITION)m_InheritedData.m_eRubyPosition;
+ }
+ virtual FDE_CSSRUBYOVERHANG GetRubyOverhang() const
+ {
+ return (FDE_CSSRUBYOVERHANG)m_InheritedData.m_eRubyOverhang;
+ }
+ virtual FDE_CSSRUBYSPAN GetRubySpanType() const
+ {
+ return m_NonInheritedData.m_pRubySpan == NULL ? FDE_CSSRUBYSPAN_None : FDE_CSSRUBYSPAN_Attr;
+ }
+ virtual IFDE_CSSValue* GetRubySpanAttr() const
+ {
+ return m_NonInheritedData.m_pRubySpan;
+ }
+ virtual FDE_CSSCAPTIONSIDE GetCaptionSide() const
+ {
+ return (FDE_CSSCAPTIONSIDE)m_InheritedData.m_eCaptionSide;
+ }
+ virtual FX_INT32 CountCounters()
+ {
+ return (m_NonInheritedData.m_pCounterStyle == NULL) ? 0 : m_NonInheritedData.m_pCounterStyle->CountCounters();
+ }
+ virtual FX_LPCWSTR GetCounterIdentifier(FX_INT32 index)
+ {
+ return m_NonInheritedData.m_pCounterStyle->GetCounterIdentifier(index);
+ }
+ virtual FX_BOOL GetCounterReset(FX_INT32 index, FX_INT32 &iValue)
+ {
+ return m_NonInheritedData.m_pCounterStyle->GetCounterReset(index, iValue);
+ }
+ virtual FX_BOOL GetCounterIncrement(FX_INT32 index, FX_INT32 &iValue)
+ {
+ return m_NonInheritedData.m_pCounterStyle->GetCounterIncrement(index, iValue);
+ }
+ virtual IFDE_CSSValueList* GetContent() const
+ {
+ return m_NonInheritedData.m_pContentList;
+ }
+ virtual FX_INT32 CountQuotes() const
+ {
+ return m_InheritedData.m_pQuotes == NULL ? 0 : m_InheritedData.m_pQuotes->CountValues();
+ }
+ virtual FX_LPCWSTR GetQuotes(FX_INT32 index) const
+ {
+ FXSYS_assert(m_InheritedData.m_pQuotes != NULL && m_InheritedData.m_pQuotes->CountValues() > index);
+ return ((IFDE_CSSPrimitiveValue*)(m_InheritedData.m_pQuotes->GetValue(index)))->GetString(index);
+ }
+ virtual const FDE_CSSLENGTH& GetColumnCount() const
+ {
+ return m_NonInheritedData.m_ColumnCount;
+ }
+ virtual const FDE_CSSLENGTH& GetColumnGap() const
+ {
+ return m_NonInheritedData.m_ColumnGap;
+ }
+ virtual FX_ARGB GetColumnRuleColor() const
+ {
+ return m_NonInheritedData.m_bColumnRuleColorSame ? m_InheritedData.m_dwFontColor : m_NonInheritedData.m_dwColumnRuleColor;
+ }
+ virtual FDE_CSSBORDERSTYLE GetColumnRuleStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eColumnRuleStyle;
+ }
+ virtual const FDE_CSSLENGTH& GetColumnRuleWidth() const
+ {
+ return m_NonInheritedData.m_ColumnRuleWidth;
+ }
+ virtual const FDE_CSSLENGTH& GetColumnWidth() const
+ {
+ return m_NonInheritedData.m_ColumnWidth;
+ }
+ virtual void SetColumnCount(const FDE_CSSLENGTH &columnCount)
+ {
+ m_NonInheritedData.m_ColumnCount = columnCount;
+ }
+ virtual void SetColumnGap(const FDE_CSSLENGTH &columnGap)
+ {
+ m_NonInheritedData.m_ColumnGap = columnGap;
+ }
+ virtual void SetColumnRuleColor(FX_ARGB dwColumnRuleColor)
+ {
+ m_NonInheritedData.m_dwColumnRuleColor = dwColumnRuleColor, m_NonInheritedData.m_bColumnRuleColorSame = FALSE;
+ }
+ virtual void SetColumnRuleStyle(FDE_CSSBORDERSTYLE eColumnRuleStyle)
+ {
+ m_NonInheritedData.m_eColumnRuleStyle = eColumnRuleStyle;
+ }
+ virtual void SetColumnRuleWidth(const FDE_CSSLENGTH &columnRuleWidth)
+ {
+ m_NonInheritedData.m_ColumnRuleWidth = columnRuleWidth;
+ }
+ virtual void SetColumnWidth(const FDE_CSSLENGTH &columnWidth)
+ {
+ m_NonInheritedData.m_ColumnWidth = columnWidth;
+ }
+ virtual FX_INT32 CountFontFamilies() const
+ {
+ return m_InheritedData.m_pFontFamily ? m_InheritedData.m_pFontFamily->CountValues() : 0;
+ }
+ virtual FX_LPCWSTR GetFontFamily(FX_INT32 index) const
+ {
+ return ((IFDE_CSSPrimitiveValue*)(m_InheritedData.m_pFontFamily->GetValue(index)))->GetString(index);
+ }
+ virtual FX_WORD GetFontWeight() const
+ {
+ return m_InheritedData.m_wFontWeight;
+ }
+ virtual FDE_CSSFONTVARIANT GetFontVariant() const
+ {
+ return (FDE_CSSFONTVARIANT)m_InheritedData.m_eFontVariant;
+ }
+ virtual FDE_CSSFONTSTYLE GetFontStyle() const
+ {
+ return (FDE_CSSFONTSTYLE)m_InheritedData.m_eFontStyle;
+ }
+ virtual FX_FLOAT GetFontSize() const
+ {
+ return m_InheritedData.m_fFontSize;
+ }
+ virtual FX_ARGB GetColor() const
+ {
+ return m_InheritedData.m_dwFontColor;
+ }
+ virtual void SetFontWeight(FX_WORD wFontWeight)
+ {
+ m_InheritedData.m_wFontWeight = wFontWeight;
+ }
+ virtual void SetFontVariant(FDE_CSSFONTVARIANT eFontVariant)
+ {
+ m_InheritedData.m_eFontVariant = eFontVariant;
+ }
+ virtual void SetFontStyle(FDE_CSSFONTSTYLE eFontStyle)
+ {
+ m_InheritedData.m_eFontStyle = eFontStyle;
+ }
+ virtual void SetFontSize(FX_FLOAT fFontSize)
+ {
+ m_InheritedData.m_fFontSize = fFontSize;
+ }
+ virtual void SetColor(FX_ARGB dwFontColor)
+ {
+ m_InheritedData.m_dwFontColor = dwFontColor;
+ }
+ virtual FX_ARGB GetBorderLeftColor() const
+ {
+ return m_NonInheritedData.m_dwBDRLeftColor;
+ }
+ virtual FX_ARGB GetBorderTopColor() const
+ {
+ return m_NonInheritedData.m_dwBDRTopColor;
+ }
+ virtual FX_ARGB GetBorderRightColor() const
+ {
+ return m_NonInheritedData.m_dwBDRRightColor;
+ }
+ virtual FX_ARGB GetBorderBottomColor() const
+ {
+ return m_NonInheritedData.m_dwBDRBottomColor;
+ }
+
+ virtual FDE_CSSBORDERSTYLE GetBorderLeftStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRLeftStyle;
+ }
+ virtual FDE_CSSBORDERSTYLE GetBorderTopStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRTopStyle;
+ }
+ virtual FDE_CSSBORDERSTYLE GetBorderRightStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRRightStyle;
+ }
+ virtual FDE_CSSBORDERSTYLE GetBorderBottomStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRBottomStyle;
+ }
+
+ virtual const FDE_CSSRECT* GetBorderWidth() const
+ {
+ return m_NonInheritedData.m_bHasBorder ? &(m_NonInheritedData.m_BorderWidth) : NULL;
+ }
+ virtual const FDE_CSSRECT* GetMarginWidth() const
+ {
+ return m_NonInheritedData.m_bHasMargin ? &(m_NonInheritedData.m_MarginWidth) : NULL;
+ }
+ virtual const FDE_CSSRECT* GetPaddingWidth() const
+ {
+ return m_NonInheritedData.m_bHasPadding ? &(m_NonInheritedData.m_PaddingWidth) : NULL;
+ }
+ virtual void SetBorderLeftColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRLeftColor = dwBorderColor;
+ }
+ virtual void SetBorderTopColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRTopColor = dwBorderColor;
+ }
+ virtual void SetBorderRightColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRRightColor = dwBorderColor;
+ }
+ virtual void SetBorderBottomColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRBottomColor = dwBorderColor;
+ }
+
+ virtual void SetBorderLeftStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRLeftStyle = eBorderStyle;
+ }
+ virtual void SetBorderTopStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRTopStyle = eBorderStyle;
+ }
+ virtual void SetBorderRightStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRRightStyle = eBorderStyle;
+ }
+ virtual void SetBorderBottomStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRBottomStyle = eBorderStyle;
+ }
+
+ virtual void SetBorderWidth(const FDE_CSSRECT &rect)
+ {
+ m_NonInheritedData.m_BorderWidth = rect;
+ m_NonInheritedData.m_bHasBorder = TRUE;
+ }
+ virtual void SetMarginWidth(const FDE_CSSRECT &rect)
+ {
+ m_NonInheritedData.m_MarginWidth = rect;
+ m_NonInheritedData.m_bHasMargin = TRUE;
+ }
+ virtual void SetPaddingWidth(const FDE_CSSRECT &rect)
+ {
+ m_NonInheritedData.m_PaddingWidth = rect;
+ m_NonInheritedData.m_bHasPadding = TRUE;
+ }
+ virtual FDE_CSSDISPLAY GetDisplay() const
+ {
+ return (FDE_CSSDISPLAY)m_NonInheritedData.m_eDisplay;
+ }
+ virtual const FDE_CSSSIZE& GetBoxSize() const
+ {
+ return m_NonInheritedData.m_BoxSize;
+ }
+ virtual const FDE_CSSSIZE& GetMinBoxSize() const
+ {
+ return m_NonInheritedData.m_MinBoxSize;
+ }
+ virtual const FDE_CSSSIZE& GetMaxBoxSize() const
+ {
+ return m_NonInheritedData.m_MaxBoxSize;
+ }
+ virtual FDE_CSSFLOAT GetFloat() const
+ {
+ return (FDE_CSSFLOAT)m_NonInheritedData.m_eFloat;
+ }
+ virtual FDE_CSSCLEAR GetClear() const
+ {
+ return (FDE_CSSCLEAR)m_NonInheritedData.m_eClear;
+ }
+ virtual FDE_CSSPOSITION GetPosition() const
+ {
+ return (FDE_CSSPOSITION)m_NonInheritedData.m_ePosition;
+ }
+ virtual FDE_CSSLENGTH GetTop() const
+ {
+ return m_NonInheritedData.m_Top;
+ }
+ virtual FDE_CSSLENGTH GetBottom() const
+ {
+ return m_NonInheritedData.m_Bottom;
+ }
+ virtual FDE_CSSLENGTH GetLeft() const
+ {
+ return m_NonInheritedData.m_Left;
+ }
+ virtual FDE_CSSLENGTH GetRight() const
+ {
+ return m_NonInheritedData.m_Right;
+ }
+
+ virtual void SetDisplay(FDE_CSSDISPLAY eDisplay)
+ {
+ m_NonInheritedData.m_eDisplay = eDisplay;
+ }
+ virtual void SetBoxSize(const FDE_CSSSIZE &size)
+ {
+ m_NonInheritedData.m_BoxSize = size;
+ }
+ virtual void SetMinBoxSize(const FDE_CSSSIZE &size)
+ {
+ m_NonInheritedData.m_MinBoxSize = size;
+ }
+ virtual void SetMaxBoxSize(const FDE_CSSSIZE &size)
+ {
+ m_NonInheritedData.m_MaxBoxSize = size;
+ }
+ virtual void SetFloat(FDE_CSSFLOAT eFloat)
+ {
+ m_NonInheritedData.m_eFloat = eFloat;
+ }
+ virtual void SetClear(FDE_CSSCLEAR eClear)
+ {
+ m_NonInheritedData.m_eClear = eClear;
+ }
+ virtual FX_FLOAT GetLineHeight() const
+ {
+ return m_InheritedData.m_fLineHeight;
+ }
+ virtual FDE_CSSWHITESPACE GetWhiteSpace() const
+ {
+ return (FDE_CSSWHITESPACE)m_InheritedData.m_eWhiteSpace;
+ }
+ virtual const FDE_CSSLENGTH& GetTextIndent() const
+ {
+ return m_InheritedData.m_TextIndent;
+ }
+ virtual FDE_CSSTEXTALIGN GetTextAlign() const
+ {
+ return (FDE_CSSTEXTALIGN)m_InheritedData.m_eTextAligh;
+ }
+ virtual FDE_CSSVERTICALALIGN GetVerticalAlign() const
+ {
+ return (FDE_CSSVERTICALALIGN)m_NonInheritedData.m_eVerticalAlign;
+ }
+ virtual FX_FLOAT GetNumberVerticalAlign() const
+ {
+ return m_NonInheritedData.m_fVerticalAlign;
+ }
+ virtual FDE_CSSTEXTTRANSFORM GetTextTransform() const
+ {
+ return (FDE_CSSTEXTTRANSFORM)m_InheritedData.m_eTextTransform;
+ }
+ virtual FX_DWORD GetTextDecoration() const
+ {
+ return m_NonInheritedData.m_dwTextDecoration;
+ }
+ virtual const FDE_CSSLENGTH& GetLetterSpacing() const
+ {
+ return m_InheritedData.m_LetterSpacing;
+ }
+ virtual const FDE_CSSLENGTH& GetWordSpacing() const
+ {
+ return m_InheritedData.m_WordSpacing;
+ }
+ virtual FDE_CSSWRITINGMODE GetWritingMode() const
+ {
+ return (FDE_CSSWRITINGMODE)m_InheritedData.m_eWritingMode;
+ }
+ virtual FDE_CSSWORDBREAK GetWordBreak() const
+ {
+ return (FDE_CSSWORDBREAK)m_InheritedData.m_eWordBreak;
+ }
+ virtual FX_INT32 GetWidows() const
+ {
+ return m_InheritedData.m_iWidows;
+ }
+ virtual FX_ARGB GetTextEmphasisColor() const
+ {
+ return m_InheritedData.m_bTextEmphasisColorCurrent ? m_InheritedData.m_dwFontColor : m_InheritedData.m_dwTextEmphasisColor;
+ }
+ virtual FDE_CSSPAGEBREAK GetPageBreakBefore() const
+ {
+ return (FDE_CSSPAGEBREAK)m_NonInheritedData.m_ePageBreakBefore;
+ }
+ virtual FDE_CSSPAGEBREAK GetPageBreakAfter() const
+ {
+ return (FDE_CSSPAGEBREAK)m_NonInheritedData.m_ePageBreakAfter;
+ }
+ virtual FDE_CSSPAGEBREAK GetPageBreakInside() const
+ {
+ return (FDE_CSSPAGEBREAK)m_NonInheritedData.m_ePageBreakInside;
+ }
+ virtual FX_INT32 GetOrphans() const
+ {
+ return m_InheritedData.m_iOrphans;
+ }
+ virtual FDE_CSSLINEBREAK GetLineBreak() const
+ {
+ return (FDE_CSSLINEBREAK)m_InheritedData.m_eLineBreak;
+ }
+ virtual FDE_CSSTEXTEMPHASISMARK GetTextEmphasisMark() const;
+ virtual FDE_CSSTEXTEMPHASISFILL GetTextEmphasisFill() const
+ {
+ return (FDE_CSSTEXTEMPHASISFILL)m_InheritedData.m_eTextEmphasisFill;
+ }
+ virtual FX_LPCWSTR GetTextEmphasisCustom() const
+ {
+ FXSYS_assert(m_InheritedData.m_eTextEmphasisMark == FDE_CSSTEXTEMPHASISMARK_Custom);
+ return m_InheritedData.m_pszTextEmphasisCustomMark;
+ }
+ virtual FDE_CSSTEXTCOMBINE GetTextCombineType() const
+ {
+ return (FDE_CSSTEXTCOMBINE)m_NonInheritedData.m_eTextCombine;
+ }
+ virtual FX_BOOL HasTextCombineNumber() const
+ {
+ return m_NonInheritedData.m_bHasTextCombineNumber;
+ }
+ virtual FX_FLOAT GetTextCombineNumber() const
+ {
+ FXSYS_assert(m_NonInheritedData.m_eTextCombine == FDE_CSSTEXTCOMBINE_Horizontal);
+ return m_NonInheritedData.m_fTextCombineNumber;
+ }
+ virtual void SetLineHeight(FX_FLOAT fLineHeight)
+ {
+ m_InheritedData.m_fLineHeight = fLineHeight;
+ }
+ virtual void SetWhiteSpace(FDE_CSSWHITESPACE eWhiteSpace)
+ {
+ m_InheritedData.m_eWhiteSpace = eWhiteSpace;
+ }
+ virtual void SetTextIndent(const FDE_CSSLENGTH &textIndent)
+ {
+ m_InheritedData.m_TextIndent = textIndent;
+ }
+ virtual void SetTextAlign(FDE_CSSTEXTALIGN eTextAlign)
+ {
+ m_InheritedData.m_eTextAligh = eTextAlign;
+ }
+ virtual void SetVerticalAlign(FDE_CSSVERTICALALIGN eVerticalAlign)
+ {
+ m_NonInheritedData.m_eVerticalAlign = eVerticalAlign;
+ }
+ virtual void SetNumberVerticalAlign(FX_FLOAT fAlign)
+ {
+ m_NonInheritedData.m_eVerticalAlign = FDE_CSSVERTICALALIGN_Number, m_NonInheritedData.m_fVerticalAlign = fAlign;
+ }
+ virtual void SetTextTransform(FDE_CSSTEXTTRANSFORM eTextTransform)
+ {
+ m_InheritedData.m_eTextTransform = eTextTransform;
+ }
+ virtual void SetTextDecoration(FX_DWORD dwTextDecoration)
+ {
+ m_NonInheritedData.m_dwTextDecoration = dwTextDecoration;
+ }
+ virtual void SetLetterSpacing(const FDE_CSSLENGTH &letterSpacing)
+ {
+ m_InheritedData.m_LetterSpacing = letterSpacing;
+ }
+ virtual void SetWordSpacing(const FDE_CSSLENGTH &wordSpacing)
+ {
+ m_InheritedData.m_WordSpacing = wordSpacing;
+ }
+ virtual void SetWritingMode(FDE_CSSWRITINGMODE eWritingMode)
+ {
+ m_InheritedData.m_eWritingMode = eWritingMode;
+ }
+ virtual void SetWordBreak(FDE_CSSWORDBREAK eWordBreak)
+ {
+ m_InheritedData.m_eWordBreak = eWordBreak;
+ }
+ virtual void SetWidows(FX_INT32 iWidows)
+ {
+ m_InheritedData.m_iWidows = iWidows;
+ }
+ virtual void SetTextEmphasisColor(FX_ARGB dwTextEmphasisColor)
+ {
+ m_InheritedData.m_dwTextEmphasisColor = dwTextEmphasisColor, m_InheritedData.m_bTextEmphasisColorCurrent = FALSE;
+ }
+ virtual void SetPageBreakBefore(FDE_CSSPAGEBREAK ePageBreakBefore)
+ {
+ m_NonInheritedData.m_ePageBreakBefore = ePageBreakBefore;
+ }
+ virtual void SetPageBreakAfter(FDE_CSSPAGEBREAK ePageBreakAfter)
+ {
+ m_NonInheritedData.m_ePageBreakAfter = ePageBreakAfter;
+ }
+ virtual void SetPageBreakInside(FDE_CSSPAGEBREAK ePageBreakInside)
+ {
+ m_NonInheritedData.m_ePageBreakInside = ePageBreakInside;
+ }
+ virtual void SetOrphans(FX_INT32 iOrphans)
+ {
+ m_InheritedData.m_iOrphans = iOrphans;
+ }
+ virtual void SetLineBreak(FDE_CSSLINEBREAK eLineBreak)
+ {
+ m_InheritedData.m_eLineBreak = eLineBreak;
+ }
+ virtual FX_ARGB GetBKGColor() const
+ {
+ return m_NonInheritedData.m_dwBKGColor;
+ }
+ virtual FX_LPCWSTR GetBKGImage() const
+ {
+ return m_NonInheritedData.m_pszBKGImage;
+ }
+ virtual const FDE_CSSPOINT& GetBKGPosition() const
+ {
+ return m_NonInheritedData.m_BKGPosition;
+ }
+ virtual FDE_CSSBKGREPEAT GetBKGRepeat() const
+ {
+ return (FDE_CSSBKGREPEAT)m_NonInheritedData.m_eBKGRepeat;
+ }
+ virtual FDE_CSSBKGATTACHMENT GetBKGAttachment() const
+ {
+ return (FDE_CSSBKGATTACHMENT)m_NonInheritedData.m_eBKGAttachment;
+ }
+ virtual void SetBKGColor(FX_ARGB dwBKGColor)
+ {
+ m_NonInheritedData.m_dwBKGColor = dwBKGColor;
+ }
+ virtual void SetBKGPosition(const FDE_CSSPOINT &bkgPosition)
+ {
+ m_NonInheritedData.m_BKGPosition = bkgPosition;
+ }
+ virtual FDE_CSSVISIBILITY GetVisibility() const
+ {
+ return (FDE_CSSVISIBILITY)m_InheritedData.m_eVisibility;
+ }
+ virtual FDE_CSSOVERFLOW GetOverflowX() const
+ {
+ return (FDE_CSSOVERFLOW)m_NonInheritedData.m_eOverflowX;
+ }
+ virtual FDE_CSSOVERFLOW GetOverflowY() const
+ {
+ return (FDE_CSSOVERFLOW)m_NonInheritedData.m_eOverflowY;
+ }
+ virtual FX_INT32 CountCursorUrls() const
+ {
+ return m_InheritedData.m_pCursorUris == NULL ? 0 : m_InheritedData.m_pCursorUris->CountValues();
+ }
+ virtual FX_LPCWSTR GetCursorUrl(FX_INT32 index) const
+ {
+ FXSYS_assert(m_InheritedData.m_pCursorUris != NULL);
+ return ((IFDE_CSSPrimitiveValue*)(m_InheritedData.m_pCursorUris->GetValue(index)))->GetString(index);
+ }
+ virtual FDE_CSSCURSOR GetCursorType() const
+ {
+ return m_InheritedData.m_eCursor;
+ }
+ virtual void SetVisibility(FDE_CSSVISIBILITY eVisibility)
+ {
+ m_InheritedData.m_eVisibility = eVisibility;
+ }
+ virtual FDE_CSSLISTSTYLETYPE GetListStyleType() const
+ {
+ return (FDE_CSSLISTSTYLETYPE)m_NonInheritedData.m_eListStyleType;
+ }
+ virtual FDE_CSSLISTSTYLEPOSITION GetListStylePosition() const
+ {
+ return (FDE_CSSLISTSTYLEPOSITION)m_NonInheritedData.m_eListStylePosition;
+ }
+ virtual FX_LPCWSTR GetListStyleImage() const
+ {
+ return m_InheritedData.m_pszListStyleImage;
+ }
+ virtual void SetListStyleType(FDE_CSSLISTSTYLETYPE eListStyleType)
+ {
+ m_NonInheritedData.m_eListStyleType = eListStyleType;
+ }
+ virtual void SetListStylePosition(FDE_CSSLISTSTYLEPOSITION eListStylePosition)
+ {
+ m_NonInheritedData.m_eListStylePosition = eListStylePosition;
+ }
+ void AddCustomStyle(const CFX_WideString &wsName, const CFX_WideString &wsValue)
+ {
+ m_CustomProperties.Add(wsName);
+ m_CustomProperties.Add(wsValue);
+ }
+ FX_DWORD m_dwRefCount;
+ IFX_MEMAllocator *m_pAllocator;
+ CFDE_CSSInheritedData m_InheritedData;
+ CFDE_CSSNonInheritedData m_NonInheritedData;
+ CFX_WideStringArray m_CustomProperties;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssstylesheet.cpp b/xfa/src/fdp/src/css/fde_cssstylesheet.cpp
new file mode 100644
index 0000000000..19bef6632c
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstylesheet.cpp
@@ -0,0 +1,481 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csssyntax.h"
+#include "fde_cssdatatable.h"
+#include "fde_cssstylesheet.h"
+IFDE_CSSStyleSheet* IFDE_CSSStyleSheet::LoadHTMLStandardStyleSheet()
+{
+ static const FX_LPCWSTR s_pStyle = (FX_LPCWSTR)L"html,address,blockquote,body,dd,div,dl,dt,fieldset,form,frame,frameset,h1,h2,h3,h4,h5,h6,noframes,ol,p,ul,center,dir,hr,menu,pre{display:block}"
+ L"li{display:list-item}head{display:none}table{display:table}tr{display:table-row}thead{display:table-header-group}tbody{display:table-row-group}tfoot{display:table-footer-group}"
+ L"col{display:table-column}colgroup{display:table-column-group}td,th{display:table-cell}caption{display:table-caption}th{font-weight:bolder;text-align:center}caption{text-align:center}"
+ L"body{margin:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.75em 0}h3{font-size:1.17em;margin:.83em 0}h4,p,blockquote,ul,fieldset,form,ol,dl,dir,menu{margin:1.12em 0}"
+ L"h5{font-size:.83em;margin:1.5em 0}h6{font-size:.75em;margin:1.67em 0}h1,h2,h3,h4,h5,h6,b,strong{font-weight:bolder}blockquote{margin-left:40px;margin-right:40px}i,cite,em,var,address{font-style:italic}"
+ L"pre,tt,code,kbd,samp{font-family:monospace}pre{white-space:pre}button,textarea,input,select{display:inline-block}big{font-size:1.17em}small,sub,sup{font-size:.83em}sub{vertical-align:sub}"
+ L"sup{vertical-align:super}table{border-spacing:2px}thead,tbody,tfoot{vertical-align:middle}td,th,tr{vertical-align:inherit}s,strike,del{text-decoration:line-through}hr{border:1px inset silver}"
+ L"ol,ul,dir,menu,dd{margin-left:40px}ol{list-style-type:decimal}ol ul,ul ol,ul ul,ol ol{margin-top:0;margin-bottom:0}u,ins{text-decoration:underline}center{text-align:center}"
+ L"ruby{display:ruby}rt{display:ruby-text;font-size:.5em}rb{display:ruby-base}rbc{display:ruby-base-group}rtc{display:ruby-text-group}"
+ L"q:before{content:open-quote}q:after{content:close-quote}"
+ L"rp{display:none}";
+ return IFDE_CSSStyleSheet::LoadFromBuffer(CFX_WideString(), s_pStyle, FXSYS_wcslen(s_pStyle), FX_CODEPAGE_UTF8);
+}
+IFDE_CSSStyleSheet* IFDE_CSSStyleSheet::LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage, FX_DWORD dwMediaList )
+{
+ CFDE_CSSStyleSheet *pStyleSheet = FDE_New CFDE_CSSStyleSheet(dwMediaList);
+ if (pStyleSheet == NULL) {
+ return NULL;
+ }
+ if (!pStyleSheet->LoadFromStream(szUrl, pStream, wCodePage)) {
+ pStyleSheet->Release();
+ pStyleSheet = NULL;
+ }
+ return pStyleSheet;
+}
+IFDE_CSSStyleSheet* IFDE_CSSStyleSheet::LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage, FX_DWORD dwMediaList )
+{
+ CFDE_CSSStyleSheet *pStyleSheet = FDE_New CFDE_CSSStyleSheet(dwMediaList);
+ if (pStyleSheet == NULL) {
+ return NULL;
+ }
+ if (!pStyleSheet->LoadFromBuffer(szUrl, pBuffer, iBufSize, wCodePage)) {
+ pStyleSheet->Release();
+ pStyleSheet = NULL;
+ }
+ return pStyleSheet;
+}
+CFDE_CSSStyleSheet::CFDE_CSSStyleSheet(FX_DWORD dwMediaList)
+ : m_wCodePage(FX_CODEPAGE_UTF8)
+ , m_wRefCount(1)
+ , m_dwMediaList(dwMediaList)
+ , m_pAllocator(NULL)
+{
+ FXSYS_assert(m_dwMediaList > 0);
+}
+CFDE_CSSStyleSheet::~CFDE_CSSStyleSheet()
+{
+ Reset();
+}
+void CFDE_CSSStyleSheet::Reset()
+{
+ for (FX_INT32 i = m_RuleArray.GetSize() - 1; i >= 0; --i) {
+ IFDE_CSSRule *pRule = m_RuleArray.GetAt(i);
+ switch (pRule->GetType()) {
+ case FDE_CSSRULETYPE_Style:
+ ((CFDE_CSSStyleRule*)pRule)->~CFDE_CSSStyleRule();
+ break;
+ case FDE_CSSRULETYPE_Media:
+ ((CFDE_CSSMediaRule*)pRule)->~CFDE_CSSMediaRule();
+ break;
+ case FDE_CSSRULETYPE_FontFace:
+ ((CFDE_CSSFontFaceRule*)pRule)->~CFDE_CSSFontFaceRule();
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+ m_RuleArray.RemoveAll();
+ m_Selectors.RemoveAll();
+ m_StringCache.RemoveAll();
+ if (m_pAllocator) {
+ m_pAllocator->Release();
+ m_pAllocator = NULL;
+ }
+}
+FX_DWORD CFDE_CSSStyleSheet::AddRef()
+{
+ return ++m_wRefCount;
+}
+FX_DWORD CFDE_CSSStyleSheet::Release()
+{
+ FX_DWORD dwRefCount = --m_wRefCount;
+ if (dwRefCount == 0) {
+ FDE_Delete this;
+ }
+ return dwRefCount;
+}
+FX_INT32 CFDE_CSSStyleSheet::CountRules() const
+{
+ return m_RuleArray.GetSize();
+}
+IFDE_CSSRule* CFDE_CSSStyleSheet::GetRule(FX_INT32 index)
+{
+ return m_RuleArray.GetAt(index);
+}
+FX_BOOL CFDE_CSSStyleSheet::LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage)
+{
+ FXSYS_assert(pStream != NULL);
+ IFDE_CSSSyntaxParser *pSyntax = IFDE_CSSSyntaxParser::Create();
+ if (pSyntax == NULL) {
+ return FALSE;
+ }
+ if (pStream->GetCodePage() != wCodePage) {
+ pStream->SetCodePage(wCodePage);
+ }
+ FX_BOOL bRet = pSyntax->Init(pStream, 4096) && LoadFromSyntax(pSyntax);
+ pSyntax->Release();
+ m_wCodePage = wCodePage;
+ m_szUrl = szUrl;
+ return bRet;
+}
+FX_BOOL CFDE_CSSStyleSheet::LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage)
+{
+ FXSYS_assert(pBuffer != NULL && iBufSize > 0);
+ IFDE_CSSSyntaxParser *pSyntax = IFDE_CSSSyntaxParser::Create();
+ if (pSyntax == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = pSyntax->Init(pBuffer, iBufSize) && LoadFromSyntax(pSyntax);
+ pSyntax->Release();
+ m_wCodePage = wCodePage;
+ m_szUrl = szUrl;
+ return bRet;
+}
+FX_BOOL CFDE_CSSStyleSheet::LoadFromSyntax(IFDE_CSSSyntaxParser *pSyntax)
+{
+ Reset();
+ m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Static, 1024, 0);
+ if (m_pAllocator == NULL) {
+ return FALSE;
+ }
+ FDE_CSSSYNTAXSTATUS eStatus;
+ do {
+ switch (eStatus = pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_StyleRule:
+ eStatus = LoadStyleRule(pSyntax, m_RuleArray);
+ break;
+ case FDE_CSSSYNTAXSTATUS_MediaRule:
+ eStatus = LoadMediaRule(pSyntax);
+ break;
+ case FDE_CSSSYNTAXSTATUS_FontFaceRule:
+ eStatus = LoadFontFaceRule(pSyntax, m_RuleArray);
+ break;
+ case FDE_CSSSYNTAXSTATUS_ImportRule:
+ eStatus = LoadImportRule(pSyntax);
+ break;
+ case FDE_CSSSYNTAXSTATUS_PageRule:
+ eStatus = LoadPageRule(pSyntax);
+ break;
+ default:
+ break;
+ }
+ } while (eStatus >= FDE_CSSSYNTAXSTATUS_None);
+ m_Selectors.RemoveAll();
+ m_StringCache.RemoveAll();
+ return eStatus != FDE_CSSSYNTAXSTATUS_Error;
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadMediaRule(IFDE_CSSSyntaxParser *pSyntax)
+{
+ FX_DWORD dwMediaList = 0;
+ CFDE_CSSMediaRule *pMediaRule = NULL;
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_MediaType: {
+ FX_INT32 iLen;
+ FX_LPCWSTR psz = pSyntax->GetCurrentString(iLen);
+ FDE_LPCCSSMEDIATYPETABLE pMediaType = FDE_GetCSSMediaTypeByName(psz, iLen);
+ if (pMediaType != NULL) {
+ dwMediaList |= pMediaType->wValue;
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_StyleRule:
+ if (pMediaRule == NULL) {
+ SkipRuleSet(pSyntax);
+ } else {
+ FDE_CSSSYNTAXSTATUS eStatus = LoadStyleRule(pSyntax, pMediaRule->GetArray());
+ if (eStatus < FDE_CSSSYNTAXSTATUS_None) {
+ return eStatus;
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ if ((dwMediaList & m_dwMediaList) > 0 && pMediaRule == NULL) {
+ pMediaRule = FDE_NewWith(m_pAllocator) CFDE_CSSMediaRule(dwMediaList);
+ m_RuleArray.Add(pMediaRule);
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadStyleRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray)
+{
+ m_Selectors.RemoveAt(0, m_Selectors.GetSize());
+ CFDE_CSSStyleRule *pStyleRule = NULL;
+ FX_LPCWSTR pszValue = NULL;
+ FX_INT32 iValueLen = 0;
+ FDE_CSSPROPERTYARGS propertyArgs;
+ propertyArgs.pStaticStore = m_pAllocator;
+ propertyArgs.pStringCache = &m_StringCache;
+ propertyArgs.pProperty = NULL;
+ CFX_WideString wsName;
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_Selector: {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ IFDE_CSSSelector *pSelector = CFDE_CSSSelector::FromString(m_pAllocator, pszValue, iValueLen);
+ if (pSelector != NULL) {
+ m_Selectors.Add(pSelector);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_PropertyName:
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ propertyArgs.pProperty = FDE_GetCSSPropertyByName(pszValue, iValueLen);
+ if (propertyArgs.pProperty == NULL) {
+ wsName = CFX_WideStringC(pszValue, iValueLen);
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_PropertyValue:
+ if (propertyArgs.pProperty != NULL) {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ if (iValueLen > 0) {
+ pStyleRule->GetDeclImp().AddProperty(&propertyArgs, pszValue, iValueLen);
+ }
+ } else if (iValueLen > 0) {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ if (iValueLen > 0) {
+ pStyleRule->GetDeclImp().AddProperty(&propertyArgs, wsName, wsName.GetLength(), pszValue, iValueLen);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ if (pStyleRule == NULL && m_Selectors.GetSize() > 0) {
+ pStyleRule = FDE_NewWith(m_pAllocator) CFDE_CSSStyleRule;
+ pStyleRule->SetSelector(m_pAllocator, m_Selectors);
+ ruleArray.Add(pStyleRule);
+ } else {
+ SkipRuleSet(pSyntax);
+ return FDE_CSSSYNTAXSTATUS_None;
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ if (pStyleRule != NULL && pStyleRule->GetDeclImp().GetStartPosition() == NULL) {
+ pStyleRule->~CFDE_CSSStyleRule();
+ ruleArray.RemoveLast(1);
+ }
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadFontFaceRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray)
+{
+ CFDE_CSSFontFaceRule *pFontFaceRule = NULL;
+ FX_LPCWSTR pszValue = NULL;
+ FX_INT32 iValueLen = 0;
+ FDE_CSSPROPERTYARGS propertyArgs;
+ propertyArgs.pStaticStore = m_pAllocator;
+ propertyArgs.pStringCache = &m_StringCache;
+ propertyArgs.pProperty = NULL;
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_PropertyName:
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ propertyArgs.pProperty = FDE_GetCSSPropertyByName(pszValue, iValueLen);
+ break;
+ case FDE_CSSSYNTAXSTATUS_PropertyValue:
+ if (propertyArgs.pProperty != NULL) {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ if (iValueLen > 0) {
+ pFontFaceRule->GetDeclImp().AddProperty(&propertyArgs, pszValue, iValueLen);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ if (pFontFaceRule == NULL) {
+ pFontFaceRule = FDE_NewWith(m_pAllocator) CFDE_CSSFontFaceRule;
+ ruleArray.Add(pFontFaceRule);
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+ return FDE_CSSSYNTAXSTATUS_None;
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadImportRule(IFDE_CSSSyntaxParser *pSyntax)
+{
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_ImportClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ case FDE_CSSSYNTAXSTATUS_URI:
+ break;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadPageRule(IFDE_CSSSyntaxParser *pSyntax)
+{
+ return SkipRuleSet(pSyntax);
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::SkipRuleSet(IFDE_CSSSyntaxParser *pSyntax)
+{
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_Selector:
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ case FDE_CSSSYNTAXSTATUS_PropertyName:
+ case FDE_CSSSYNTAXSTATUS_PropertyValue:
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+ return FDE_CSSSYNTAXSTATUS_None;
+}
+void CFDE_CSSStyleRule::SetSelector(IFX_MEMAllocator *pStaticStore, const CFDE_CSSSelectorArray &list)
+{
+ FXSYS_assert(m_ppSelector == NULL);
+ m_iSelectors = list.GetSize();
+ m_ppSelector = (IFDE_CSSSelector**)pStaticStore->Alloc(m_iSelectors * sizeof(IFDE_CSSSelector*));
+ for (FX_INT32 i = 0; i < m_iSelectors; ++i) {
+ m_ppSelector[i] = list.GetAt(i);
+ }
+}
+CFDE_CSSMediaRule::~CFDE_CSSMediaRule()
+{
+ for (FX_INT32 i = m_RuleArray.GetSize() - 1; i >= 0; --i) {
+ IFDE_CSSRule *pRule = m_RuleArray.GetAt(i);
+ switch (pRule->GetType()) {
+ case FDE_CSSRULETYPE_Style:
+ ((CFDE_CSSStyleRule*)pRule)->~CFDE_CSSStyleRule();
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+}
+inline FX_BOOL FDE_IsCSSChar(FX_WCHAR wch)
+{
+ return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z');
+}
+FX_INT32 FDE_GetCSSPersudoLen(FX_LPCWSTR psz, FX_LPCWSTR pEnd)
+{
+ FXSYS_assert(*psz == ':');
+ FX_LPCWSTR pStart = psz;
+ while (psz < pEnd) {
+ FX_WCHAR wch = *psz;
+ if (FDE_IsCSSChar(wch) || wch == ':') {
+ ++psz;
+ } else {
+ break;
+ }
+ }
+ return psz - pStart;
+}
+FX_INT32 FDE_GetCSSNameLen(FX_LPCWSTR psz, FX_LPCWSTR pEnd)
+{
+ FX_LPCWSTR pStart = psz;
+ while (psz < pEnd) {
+ FX_WCHAR wch = *psz;
+ if (FDE_IsCSSChar(wch)
+ || (wch >= '0' && wch <= '9')
+ || wch == '_' || wch == '-') {
+ ++psz;
+ } else {
+ break;
+ }
+ }
+ return psz - pStart;
+}
+IFDE_CSSSelector* CFDE_CSSSelector::FromString(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR psz, FX_INT32 iLen)
+{
+ FXSYS_assert(pStaticStore != NULL && psz != NULL && iLen > 0);
+ FX_LPCWSTR pStart = psz;
+ FX_LPCWSTR pEnd = psz + iLen;
+ for (; psz < pEnd; ++psz) {
+ switch (*psz) {
+ case '>':
+ case '[':
+ case '+':
+ return NULL;
+ }
+ }
+ CFDE_CSSSelector *pFirst = NULL, *pLast = NULL;
+ CFDE_CSSSelector *pPersudoFirst = NULL, *pPersudoLast = NULL;
+ for (psz = pStart ; psz < pEnd; ) {
+ FX_WCHAR wch = *psz;
+ if (wch == '.' || wch == '#') {
+ if (psz == pStart || psz[-1] == ' ') {
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, (FX_LPCWSTR)L"*", 1, TRUE);
+ if (p == NULL) {
+ return NULL;
+ }
+ if (pFirst != NULL) {
+ pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
+ p->SetNext(pFirst);
+ }
+ pFirst = pLast = p;
+ }
+ FXSYS_assert(pLast != NULL);
+ FX_INT32 iNameLen = FDE_GetCSSNameLen(++psz, pEnd);
+ if (iNameLen == 0) {
+ return NULL;
+ }
+ FDE_CSSSELECTORTYPE eType = wch == '.' ? FDE_CSSSELECTORTYPE_Class : FDE_CSSSELECTORTYPE_ID;
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(eType, psz, iNameLen, FALSE);
+ if (p == NULL) {
+ return NULL;
+ }
+ p->SetNext(pLast->GetNextSelector());
+ pLast->SetNext(p);
+ pLast = p;
+ psz += iNameLen;
+ } else if (FDE_IsCSSChar(wch) || wch == '*') {
+ FX_INT32 iNameLen = wch == '*' ? 1 : FDE_GetCSSNameLen(psz, pEnd);
+ if (iNameLen == 0) {
+ return NULL;
+ }
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, psz, iNameLen, TRUE);
+ if (p == NULL) {
+ return NULL;
+ }
+ if (pFirst == NULL) {
+ pFirst = pLast = p;
+ } else {
+ pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
+ p->SetNext(pFirst);
+ pFirst = pLast = p;
+ }
+ psz += iNameLen;
+ } else if (wch == ':') {
+ FX_INT32 iNameLen = FDE_GetCSSPersudoLen(psz, pEnd);
+ if (iNameLen == 0) {
+ return NULL;
+ }
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Persudo, psz, iNameLen, TRUE);
+ if (p == NULL) {
+ return NULL;
+ }
+ if (pPersudoFirst == NULL) {
+ pPersudoFirst = pPersudoLast = p;
+ } else {
+ pPersudoLast->SetNext(p);
+ pPersudoLast = p;
+ }
+ psz += iNameLen;
+ } else if (wch == ' ') {
+ psz++;
+ } else {
+ return NULL;
+ }
+ }
+ if (pPersudoFirst == NULL) {
+ return pFirst;
+ } else {
+ pPersudoLast->SetNext(pFirst);
+ return pPersudoFirst;
+ }
+}
diff --git a/xfa/src/fdp/src/css/fde_cssstylesheet.h b/xfa/src/fdp/src/css/fde_cssstylesheet.h
new file mode 100644
index 0000000000..04251a0c6b
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstylesheet.h
@@ -0,0 +1,163 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSSTYLESHEET
+#define _FDE_CSSSTYLESHEET
+#include "fde_cssdeclaration.h"
+class CFDE_CSSSelector : public IFDE_CSSSelector, public CFX_Target
+{
+public:
+ CFDE_CSSSelector(FDE_CSSSELECTORTYPE eType, FX_LPCWSTR psz, FX_INT32 iLen, FX_BOOL bIgnoreCase)
+ : m_eType(eType), m_dwHash(FX_HashCode_String_GetW(psz, iLen, bIgnoreCase)), m_pNext(NULL)
+ {
+ }
+ virtual FDE_CSSSELECTORTYPE GetType() const
+ {
+ return m_eType;
+ }
+
+ virtual FX_DWORD GetNameHash() const
+ {
+ return m_dwHash;
+ }
+
+ virtual IFDE_CSSSelector* GetNextSelector() const
+ {
+ return m_pNext;
+ }
+ static IFDE_CSSSelector* FromString(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR psz, FX_INT32 iLen);
+ void SetNext(IFDE_CSSSelector *pNext)
+ {
+ m_pNext = pNext;
+ }
+protected:
+ static CFDE_CSSSelector* ParseSelector(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR psz, FX_INT32 &iOff, FX_INT32 iLen, FDE_CSSSELECTORTYPE eType);
+ void SetType(FDE_CSSSELECTORTYPE eType)
+ {
+ m_eType = eType;
+ }
+ FDE_CSSSELECTORTYPE m_eType;
+ FX_DWORD m_dwHash;
+ IFDE_CSSSelector *m_pNext;
+};
+typedef CFX_ArrayTemplate<IFDE_CSSSelector*> CFDE_CSSSelectorArray;
+class CFDE_CSSStyleRule : public IFDE_CSSStyleRule, public CFX_Target
+{
+public:
+ CFDE_CSSStyleRule() : m_ppSelector(NULL), m_iSelectors(0) { }
+ virtual FX_INT32 CountSelectorLists() const
+ {
+ return m_iSelectors;
+ }
+ virtual IFDE_CSSSelector* GetSelectorList(FX_INT32 index) const
+ {
+ return m_ppSelector[index];
+ }
+
+ virtual IFDE_CSSDeclaration* GetDeclaration() const
+ {
+ return (IFDE_CSSDeclaration*)&m_Declaration;
+ }
+ CFDE_CSSDeclaration& GetDeclImp()
+ {
+ return m_Declaration;
+ }
+ void SetSelector(IFX_MEMAllocator *pStaticStore, const CFDE_CSSSelectorArray &list);
+protected:
+ CFDE_CSSDeclaration m_Declaration;
+ IFDE_CSSSelector **m_ppSelector;
+ FX_INT32 m_iSelectors;
+};
+class CFDE_CSSMediaRule : public IFDE_CSSMediaRule, public CFX_Target
+{
+public:
+ CFDE_CSSMediaRule(FX_DWORD dwMediaList) : m_dwMediaList(dwMediaList) { }
+ ~CFDE_CSSMediaRule();
+
+ virtual FX_DWORD GetMediaList() const
+ {
+ return m_dwMediaList;
+ }
+
+ virtual FX_INT32 CountRules() const
+ {
+ return m_RuleArray.GetSize();
+ }
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index)
+ {
+ return m_RuleArray.GetAt(index);
+ }
+ CFDE_CSSRuleArray& GetArray()
+ {
+ return m_RuleArray;
+ }
+protected:
+ FX_DWORD m_dwMediaList;
+ CFDE_CSSRuleArray m_RuleArray;
+};
+class CFDE_CSSFontFaceRule : public IFDE_CSSFontFaceRule, public CFX_Target
+{
+public:
+ virtual IFDE_CSSDeclaration* GetDeclaration() const
+ {
+ return (IFDE_CSSDeclaration*)&m_Declaration;
+ }
+ CFDE_CSSDeclaration& GetDeclImp()
+ {
+ return m_Declaration;
+ }
+protected:
+ CFDE_CSSDeclaration m_Declaration;
+};
+#define FDE_CSSSWITCHDEFAULTS() case FDE_CSSSYNTAXSTATUS_EOS: \
+ return FDE_CSSSYNTAXSTATUS_EOS; \
+ case FDE_CSSSYNTAXSTATUS_Error: \
+ default: \
+ return FDE_CSSSYNTAXSTATUS_Error;
+class CFDE_CSSStyleSheet : public IFDE_CSSStyleSheet, public CFX_Target
+{
+public:
+ CFDE_CSSStyleSheet(FX_DWORD dwMediaList);
+ ~CFDE_CSSStyleSheet();
+ virtual FX_DWORD AddRef();
+ virtual FX_DWORD Release();
+
+ virtual FX_BOOL GetUrl(CFX_WideString &szUrl)
+ {
+ szUrl = m_szUrl;
+ return szUrl.GetLength() > 0;
+ }
+ virtual FX_DWORD GetMediaList() const
+ {
+ return m_dwMediaList;
+ }
+ virtual FX_WORD GetCodePage() const
+ {
+ return m_wCodePage;
+ }
+ virtual FX_INT32 CountRules() const;
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index);
+ FX_BOOL LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage);
+ FX_BOOL LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage);
+protected:
+ void Reset();
+ FX_BOOL LoadFromSyntax(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadStyleRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray);
+ FDE_CSSSYNTAXSTATUS LoadImportRule(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadPageRule(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadMediaRule(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadFontFaceRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray);
+ FDE_CSSSYNTAXSTATUS SkipRuleSet(IFDE_CSSSyntaxParser *pSyntax);
+ FX_WORD m_wCodePage;
+ FX_WORD m_wRefCount;
+ FX_DWORD m_dwMediaList;
+ IFX_MEMAllocator *m_pAllocator;
+ CFDE_CSSRuleArray m_RuleArray;
+ CFX_WideString m_szUrl;
+ CFDE_CSSSelectorArray m_Selectors;
+ CFX_MapPtrToPtr m_StringCache;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_csssyntax.cpp b/xfa/src/fdp/src/css/fde_csssyntax.cpp
new file mode 100644
index 0000000000..b7e5da9d6c
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csssyntax.cpp
@@ -0,0 +1,495 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csssyntax.h"
+#include "fde_cssdatatable.h"
+#ifdef _cplusplus
+extern "C" {
+#endif
+ inline FX_BOOL FDE_IsSelectorStart(FX_WCHAR wch)
+ {
+ return wch == '.' || wch == '#' || wch == '*'
+ || (wch >= 'a' && wch <= 'z')
+ || (wch >= 'A' && wch <= 'Z');
+ }
+#ifdef _cplusplus
+};
+#endif
+IFDE_CSSSyntaxParser* IFDE_CSSSyntaxParser::Create()
+{
+ return FDE_New CFDE_CSSSyntaxParser;
+}
+CFDE_CSSSyntaxParser::CFDE_CSSSyntaxParser()
+ : m_pStream(NULL)
+ , m_iStreamPos(0)
+ , m_iPlaneSize(0)
+ , m_iTextDatLen(0)
+ , m_dwCheck((FX_DWORD) - 1)
+ , m_eMode(FDE_CSSSYNTAXMODE_RuleSet)
+ , m_eStatus(FDE_CSSSYNTAXSTATUS_None)
+{
+}
+CFDE_CSSSyntaxParser::~CFDE_CSSSyntaxParser()
+{
+ m_TextData.Reset();
+ m_TextPlane.Reset();
+}
+FX_BOOL CFDE_CSSSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iCSSPlaneSize, FX_INT32 iTextDataSize , FX_BOOL bOnlyDeclaration )
+{
+ FXSYS_assert(pStream != NULL && iCSSPlaneSize > 0 && iTextDataSize > 0);
+ Reset(bOnlyDeclaration);
+ if (!m_TextData.EstimateSize(iTextDataSize)) {
+ return FALSE;
+ }
+ FX_BYTE bom[4];
+ m_pStream = pStream;
+ m_iStreamPos = m_pStream->GetBOM(bom);
+ m_iPlaneSize = iCSSPlaneSize;
+ return TRUE;
+}
+FX_BOOL CFDE_CSSSyntaxParser::Init(FX_LPCWSTR pBuffer, FX_INT32 iBufferSize, FX_INT32 iTextDatSize , FX_BOOL bOnlyDeclaration )
+{
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0 && iTextDatSize > 0);
+ Reset(bOnlyDeclaration);
+ if (!m_TextData.EstimateSize(iTextDatSize)) {
+ return FALSE;
+ }
+ return m_TextPlane.AttachBuffer(pBuffer, iBufferSize);
+}
+void CFDE_CSSSyntaxParser::Reset(FX_BOOL bOnlyDeclaration)
+{
+ m_TextPlane.Reset();
+ m_TextData.Reset();
+ m_pStream = NULL;
+ m_iStreamPos = 0;
+ m_iTextDatLen = 0;
+ m_dwCheck = (FX_DWORD) - 1;
+ m_eStatus = FDE_CSSSYNTAXSTATUS_None;
+ m_eMode = bOnlyDeclaration ? FDE_CSSSYNTAXMODE_PropertyName : FDE_CSSSYNTAXMODE_RuleSet;
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSSyntaxParser::DoSyntaxParse()
+{
+ while (m_eStatus >= FDE_CSSSYNTAXSTATUS_None) {
+ if (m_TextPlane.IsEOF()) {
+ if (m_pStream == NULL) {
+ if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue;
+ }
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS;
+ }
+ FX_BOOL bEOS;
+ FX_INT32 iLen = m_TextPlane.LoadFromStream(m_pStream, m_iStreamPos, m_iPlaneSize, bEOS);
+ m_iStreamPos = m_pStream->GetPosition();
+ if (iLen < 1) {
+ if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue;
+ }
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS;
+ }
+ }
+ FX_WCHAR wch;
+ while (!m_TextPlane.IsEOF()) {
+ wch = m_TextPlane.GetChar();
+ switch (m_eMode) {
+ case FDE_CSSSYNTAXMODE_RuleSet:
+ switch (wch) {
+ case '@':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_AtRule);
+ break;
+ case '}':
+ m_TextPlane.MoveNext();
+ if (RestoreMode()) {
+ return FDE_CSSSYNTAXSTATUS_DeclClose;
+ } else {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ m_ModeStack.Push(m_eMode);
+ SwitchMode(FDE_CSSSYNTAXMODE_Comment);
+ break;
+ }
+ default:
+ if (wch <= ' ') {
+ m_TextPlane.MoveNext();
+ } else if (FDE_IsSelectorStart(wch)) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ return FDE_CSSSYNTAXSTATUS_StyleRule;
+ } else {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_Selector:
+ switch (wch) {
+ case ',':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ if (m_iTextDatLen > 0) {
+ return FDE_CSSSYNTAXSTATUS_Selector;
+ }
+ break;
+ case '{':
+ if (m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return FDE_CSSSYNTAXSTATUS_Selector;
+ } else {
+ m_TextPlane.MoveNext();
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_RuleSet);
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyName);
+ return FDE_CSSSYNTAXSTATUS_DeclOpen;
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_Selector;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_PropertyName:
+ switch (wch) {
+ case ':':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyValue);
+ return FDE_CSSSYNTAXSTATUS_PropertyName;
+ case '}':
+ m_TextPlane.MoveNext();
+ if (RestoreMode()) {
+ return FDE_CSSSYNTAXSTATUS_DeclClose;
+ } else {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_PropertyName;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_PropertyValue:
+ switch (wch) {
+ case ';':
+ m_TextPlane.MoveNext();
+ case '}':
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyName);
+ return FDE_CSSSYNTAXSTATUS_PropertyValue;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_PropertyValue;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_Comment:
+ if (wch == '/' && m_TextData.GetLength() > 0
+ && m_TextData.GetAt(m_TextData.GetLength() - 1) == '*') {
+ RestoreMode();
+ } else {
+ m_TextData.AppendChar(wch);
+ }
+ m_TextPlane.MoveNext();
+ break;
+ case FDE_CSSSYNTAXMODE_MediaType:
+ switch (wch) {
+ case ',':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType);
+ if (m_iTextDatLen > 0) {
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ }
+ break;
+ case '{': {
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_MediaRule) {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ if (m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ } else {
+ m_TextPlane.MoveNext();
+ *pMode = FDE_CSSSYNTAXMODE_RuleSet;
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ return FDE_CSSSYNTAXSTATUS_DeclOpen;
+ }
+ }
+ break;
+ case ';': {
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ if (m_TextData.GetLength() > 0) {
+ SaveTextData();
+ if (IsImportEnabled()) {
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ }
+ } else {
+ FX_BOOL bEnabled = IsImportEnabled();
+ m_TextPlane.MoveNext();
+ m_ModeStack.Pop();
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ if (bEnabled) {
+ DisableImport();
+ return FDE_CSSSYNTAXSTATUS_ImportClose;
+ }
+ }
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_URI: {
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ if (wch <= ' ' || wch == ';') {
+ FX_INT32 iURIStart, iURILength = m_TextData.GetLength();
+ if (iURILength > 0 && FDE_ParseCSSURI(m_TextData.GetBuffer(), iURILength, iURIStart, iURILength)) {
+ m_TextData.Subtract(iURIStart, iURILength);
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType);
+ if (IsImportEnabled()) {
+ return FDE_CSSSYNTAXSTATUS_URI;
+ } else {
+ break;
+ }
+ }
+ }
+ AppendChar(wch);
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_AtRule:
+ if (wch > ' ') {
+ AppendChar(wch);
+ } else {
+ FX_INT32 iLen = m_TextData.GetLength();
+ FX_LPCWSTR psz = m_TextData.GetBuffer();
+ if (FXSYS_wcsncmp(L"charset", psz, iLen) == 0) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Charset);
+ } else if (FXSYS_wcsncmp(L"import", psz, iLen) == 0) {
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_Import);
+ SwitchMode(FDE_CSSSYNTAXMODE_URI);
+ if (IsImportEnabled()) {
+ return FDE_CSSSYNTAXSTATUS_ImportRule;
+ } else {
+ break;
+ }
+ } else if (FXSYS_wcsncmp(L"media", psz, iLen) == 0) {
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_MediaRule);
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType);
+ return FDE_CSSSYNTAXSTATUS_MediaRule;
+ } else if (FXSYS_wcsncmp(L"font-face", psz, iLen) == 0) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ return FDE_CSSSYNTAXSTATUS_FontFaceRule;
+ } else if (FXSYS_wcsncmp(L"page", psz, iLen) == 0) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ return FDE_CSSSYNTAXSTATUS_PageRule;
+ } else {
+ SwitchMode(FDE_CSSSYNTAXMODE_UnknownRule);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_Charset:
+ if (wch == ';') {
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ if (IsCharsetEnabled()) {
+ DisableCharset();
+ if (m_iTextDatLen > 0) {
+ if (m_pStream != NULL) {
+ FX_WORD wCodePage = FX_GetCodePageFormStringW(m_TextData.GetBuffer(), m_iTextDatLen);
+ if (wCodePage < 0xFFFF && m_pStream->GetCodePage() != wCodePage) {
+ m_pStream->SetCodePage(wCodePage);
+ }
+ }
+ return FDE_CSSSYNTAXSTATUS_Charset;
+ }
+ }
+ } else {
+ AppendChar(wch);
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_UnknownRule:
+ if (wch == ';') {
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ }
+ m_TextPlane.MoveNext();
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+ }
+ return m_eStatus;
+}
+FX_BOOL CFDE_CSSSyntaxParser::IsImportEnabled() const
+{
+ if ((m_dwCheck & FDE_CSSSYNTAXCHECK_AllowImport) == 0) {
+ return FALSE;
+ }
+ if (m_ModeStack.GetSize() > 1) {
+ return FALSE;
+ }
+ return TRUE;
+}
+inline FX_BOOL CFDE_CSSSyntaxParser::AppendChar(FX_WCHAR wch)
+{
+ m_TextPlane.MoveNext();
+ if (m_TextData.GetLength() > 0 || wch > ' ') {
+ m_TextData.AppendChar(wch);
+ return TRUE;
+ }
+ return FALSE;
+}
+inline FX_INT32 CFDE_CSSSyntaxParser::SaveTextData()
+{
+ m_iTextDatLen = m_TextData.TrimEnd();
+ m_TextData.Clear();
+ return m_iTextDatLen;
+}
+inline void CFDE_CSSSyntaxParser::SwitchMode(FDE_CSSSYNTAXMODE eMode)
+{
+ m_eMode = eMode;
+ SaveTextData();
+}
+inline FX_INT32 CFDE_CSSSyntaxParser::SwitchToComment()
+{
+ FX_INT32 iLength = m_TextData.GetLength();
+ m_ModeStack.Push(m_eMode);
+ SwitchMode(FDE_CSSSYNTAXMODE_Comment);
+ return iLength;
+}
+inline FX_BOOL CFDE_CSSSyntaxParser::RestoreMode()
+{
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL) {
+ return FALSE;
+ }
+ SwitchMode(*pMode);
+ m_ModeStack.Pop();
+ return TRUE;
+}
+FX_LPCWSTR CFDE_CSSSyntaxParser::GetCurrentString(FX_INT32 &iLength) const
+{
+ iLength = m_iTextDatLen;
+ return m_TextData.GetBuffer();
+}
+CFDE_CSSTextBuf::CFDE_CSSTextBuf()
+ : m_bExtBuf(FALSE)
+ , m_pBuffer(NULL)
+ , m_iBufLen(0)
+ , m_iDatLen(0)
+ , m_iDatPos(0)
+{
+}
+CFDE_CSSTextBuf::~CFDE_CSSTextBuf()
+{
+ Reset();
+}
+void CFDE_CSSTextBuf::Reset()
+{
+ if (!m_bExtBuf && m_pBuffer != NULL) {
+ FDE_Free(m_pBuffer);
+ m_pBuffer = NULL;
+ }
+ m_iDatPos = m_iDatLen = m_iBufLen;
+}
+FX_BOOL CFDE_CSSTextBuf::AttachBuffer(FX_LPCWSTR pBuffer, FX_INT32 iBufLen)
+{
+ Reset();
+ m_pBuffer = (FX_LPWSTR)pBuffer;
+ m_iDatLen = m_iBufLen = iBufLen;
+ return m_bExtBuf = TRUE;
+}
+FX_BOOL CFDE_CSSTextBuf::EstimateSize(FX_INT32 iAllocSize)
+{
+ FXSYS_assert(iAllocSize > 0);
+ Clear();
+ m_bExtBuf = FALSE;
+ return ExpandBuf(iAllocSize);
+}
+FX_INT32 CFDE_CSSTextBuf::LoadFromStream(IFX_Stream *pTxtStream, FX_INT32 iStreamOffset, FX_INT32 iMaxChars, FX_BOOL &bEOS)
+{
+ FXSYS_assert(iStreamOffset >= 0 && iMaxChars > 0);
+ Clear();
+ m_bExtBuf = FALSE;
+ if (!ExpandBuf(iMaxChars)) {
+ return 0;
+ }
+ pTxtStream->Lock();
+ if (pTxtStream->GetPosition() != iStreamOffset) {
+ pTxtStream->Seek(FX_STREAMSEEK_Begin, iStreamOffset);
+ }
+ m_iDatLen = pTxtStream->ReadString(m_pBuffer, iMaxChars, bEOS);
+ pTxtStream->Unlock();
+ return m_iDatLen;
+}
+FX_BOOL CFDE_CSSTextBuf::ExpandBuf(FX_INT32 iDesiredSize)
+{
+ if (m_bExtBuf) {
+ return FALSE;
+ } else if (m_pBuffer == NULL) {
+ m_pBuffer = (FX_LPWSTR)FDE_Alloc(iDesiredSize * sizeof(FX_WCHAR));
+ } else if (m_iBufLen != iDesiredSize) {
+ m_pBuffer = (FX_LPWSTR)FDE_Realloc(m_pBuffer, iDesiredSize * sizeof(FX_WCHAR));
+ } else {
+ return TRUE;
+ }
+ if (m_pBuffer == NULL) {
+ m_iBufLen = 0;
+ return FALSE;
+ } else {
+ m_iBufLen = iDesiredSize;
+ return TRUE;
+ }
+}
+void CFDE_CSSTextBuf::Subtract(FX_INT32 iStart, FX_INT32 iLength)
+{
+ FXSYS_assert(iStart >= 0 && iLength > 0);
+ if (iLength > m_iDatLen - iStart) {
+ iLength = m_iDatLen - iStart;
+ }
+ if (iLength < 0) {
+ iLength = 0;
+ } else {
+ FXSYS_memmove(m_pBuffer, m_pBuffer + iStart, iLength * sizeof(FX_WCHAR));
+ }
+ m_iDatLen = iLength;
+}
diff --git a/xfa/src/fdp/src/css/fde_csssyntax.h b/xfa/src/fdp/src/css/fde_csssyntax.h
new file mode 100644
index 0000000000..c18e0f9717
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csssyntax.h
@@ -0,0 +1,135 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSSYNTAX
+#define _FDE_CSSSYNTAX
+class CFDE_CSSTextBuf : public CFX_Target
+{
+public:
+ CFDE_CSSTextBuf();
+ ~CFDE_CSSTextBuf();
+ FX_BOOL AttachBuffer(FX_LPCWSTR pBuffer, FX_INT32 iBufLen);
+ FX_BOOL EstimateSize(FX_INT32 iAllocSize);
+ FX_INT32 LoadFromStream(IFX_Stream *pTxtStream, FX_INT32 iStreamOffset, FX_INT32 iMaxChars, FX_BOOL &bEOS);
+ FX_BOOL AppendChar(FX_WCHAR wch)
+ {
+ if (m_iDatLen >= m_iBufLen && !ExpandBuf(m_iBufLen * 2)) {
+ return FALSE;
+ }
+ return (m_pBuffer[m_iDatLen++] = wch), TRUE;
+ }
+ void Clear()
+ {
+ m_iDatPos = m_iDatLen = 0;
+ }
+ void Reset();
+ FX_INT32 TrimEnd()
+ {
+ while (m_iDatLen > 0 && m_pBuffer[m_iDatLen - 1] <= ' ') {
+ --m_iDatLen;
+ }
+ AppendChar(0);
+ return --m_iDatLen;
+ }
+ void Subtract(FX_INT32 iStart, FX_INT32 iLength);
+ FX_BOOL IsEOF() const
+ {
+ return m_iDatPos >= m_iDatLen;
+ }
+ FX_WCHAR GetAt(FX_INT32 index) const
+ {
+ return m_pBuffer[index];
+ }
+ FX_WCHAR GetChar() const
+ {
+ return m_pBuffer[m_iDatPos];
+ }
+ FX_WCHAR GetNextChar() const
+ {
+ return (m_iDatPos + 1 >= m_iDatLen) ? 0 : m_pBuffer[m_iDatPos + 1];
+ }
+ void MoveNext()
+ {
+ m_iDatPos++;
+ }
+ FX_INT32 GetLength() const
+ {
+ return m_iDatLen;
+ }
+ FX_LPCWSTR GetBuffer() const
+ {
+ return m_pBuffer;
+ }
+protected:
+ FX_BOOL ExpandBuf(FX_INT32 iDesiredSize);
+ FX_BOOL m_bExtBuf;
+ FX_LPWSTR m_pBuffer;
+ FX_INT32 m_iBufLen;
+ FX_INT32 m_iDatLen;
+ FX_INT32 m_iDatPos;
+};
+#define FDE_CSSSYNTAXCHECK_AllowCharset 1
+#define FDE_CSSSYNTAXCHECK_AllowImport 2
+enum FDE_CSSSYNTAXMODE {
+ FDE_CSSSYNTAXMODE_RuleSet,
+ FDE_CSSSYNTAXMODE_Comment,
+ FDE_CSSSYNTAXMODE_AtRule,
+ FDE_CSSSYNTAXMODE_UnknownRule,
+ FDE_CSSSYNTAXMODE_Charset,
+ FDE_CSSSYNTAXMODE_Import,
+ FDE_CSSSYNTAXMODE_MediaRule,
+ FDE_CSSSYNTAXMODE_URI,
+ FDE_CSSSYNTAXMODE_MediaType,
+ FDE_CSSSYNTAXMODE_Selector,
+ FDE_CSSSYNTAXMODE_PropertyName,
+ FDE_CSSSYNTAXMODE_PropertyValue,
+};
+class CFDE_CSSSyntaxParser : public IFDE_CSSSyntaxParser, public CFX_Target
+{
+public:
+ CFDE_CSSSyntaxParser();
+ ~CFDE_CSSSyntaxParser();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_BOOL Init(IFX_Stream *pStream, FX_INT32 iCSSPlaneSize, FX_INT32 iTextDataSize = 32, FX_BOOL bOnlyDeclaration = FALSE);
+ virtual FX_BOOL Init(FX_LPCWSTR pBuffer, FX_INT32 iBufferSize, FX_INT32 iTextDatSize = 32, FX_BOOL bOnlyDeclaration = FALSE);
+ virtual FDE_CSSSYNTAXSTATUS DoSyntaxParse();
+ virtual FX_LPCWSTR GetCurrentString(FX_INT32 &iLength) const;
+protected:
+ void Reset(FX_BOOL bOnlyDeclaration);
+ void SwitchMode(FDE_CSSSYNTAXMODE eMode);
+ FX_INT32 SwitchToComment();
+
+ FX_BOOL RestoreMode();
+ FX_BOOL AppendChar(FX_WCHAR wch);
+ FX_INT32 SaveTextData();
+ FX_BOOL IsCharsetEnabled() const
+ {
+ return (m_dwCheck & FDE_CSSSYNTAXCHECK_AllowCharset) != 0;
+ }
+ void DisableCharset()
+ {
+ m_dwCheck = FDE_CSSSYNTAXCHECK_AllowImport;
+ }
+ FX_BOOL IsImportEnabled() const;
+ void DisableImport()
+ {
+ m_dwCheck = 0;
+ }
+ IFX_Stream *m_pStream;
+ FX_INT32 m_iStreamPos;
+ FX_INT32 m_iPlaneSize;
+ CFDE_CSSTextBuf m_TextData;
+ CFDE_CSSTextBuf m_TextPlane;
+ FX_INT32 m_iTextDatLen;
+ FX_DWORD m_dwCheck;
+ FDE_CSSSYNTAXMODE m_eMode;
+ FDE_CSSSYNTAXSTATUS m_eStatus;
+ CFX_StackTemplate<FDE_CSSSYNTAXMODE> m_ModeStack;
+};
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_devbasic.cpp b/xfa/src/fdp/src/fde/fde_devbasic.cpp
new file mode 100644
index 0000000000..780f1188c8
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_devbasic.cpp
@@ -0,0 +1,70 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_devbasic.h"
+static const FDE_HATCHDATA gs_HatchBitmapData[FDE_HATCHSTYLE_Total] = {
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,}},
+ {16, 16, {0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,}},
+ {16, 16, {0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00,}},
+ {16, 16, {0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,}},
+ {16, 16, {0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00, 0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00,}},
+ {16, 16, {0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00,}},
+ {16, 16, {0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00,}},
+ {16, 16, {0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+};
+FDE_LPCHATCHDATA FDE_DEVGetHatchData(FX_INT32 iHatchStyle)
+{
+ if (iHatchStyle < FDE_HATCHSTYLE_Min || iHatchStyle > FDE_HATCHSTYLE_Max) {
+ return NULL;
+ }
+ return &gs_HatchBitmapData[iHatchStyle];
+}
diff --git a/xfa/src/fdp/src/fde/fde_devbasic.h b/xfa/src/fdp/src/fde/fde_devbasic.h
new file mode 100644
index 0000000000..36d2471b2c
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_devbasic.h
@@ -0,0 +1,16 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_DEVICE_BASIC_IMP
+#define _FDE_DEVICE_BASIC_IMP
+struct FDE_HATCHDATA {
+ FX_INT32 iWidth;
+ FX_INT32 iHeight;
+ FX_BYTE MaskBits[64];
+};
+typedef FDE_HATCHDATA const * FDE_LPCHATCHDATA;
+FDE_LPCHATCHDATA FDE_DEVGetHatchData(FX_INT32 iHatchStyle);
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gdidevice.cpp b/xfa/src/fdp/src/fde/fde_gdidevice.cpp
new file mode 100644
index 0000000000..ad7f6cc9e5
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gdidevice.cpp
@@ -0,0 +1,555 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "stdafx.h"
+#include "fde_gdidevice.h"
+#include "fde_gdiobject.h"
+#ifdef _FDEPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_DIBitmap *pBitmap, FX_BOOL bRgbByteOrder )
+{
+ return FDE_New CFDE_GdiDevice(pBitmap);
+}
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_RenderDevice *pDevice)
+{
+ return NULL;
+}
+CFDE_GdiDevice::CFDE_GdiDevice(CFX_DIBitmap *pBitmap)
+ : m_dwGlyphLen(0)
+ , m_pGlyphBuf(NULL)
+ , m_pGraphics(NULL)
+ , m_pBitmap(NULL)
+ , m_pClipPath(NULL)
+{
+ FXSYS_assert(pBitmap != NULL);
+ BITMAPINFO bmi;
+ FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = pBitmap->GetWidth();
+ bmi.bmiHeader.biHeight = -pBitmap->GetHeight();
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
+ m_pBitmap = Gdiplus::Bitmap::FromBITMAPINFO(&bmi, pBitmap->GetBuffer());
+ FXSYS_assert(m_pBitmap != NULL);
+ m_pGraphics = Gdiplus::Graphics::FromImage(m_pBitmap);
+ FXSYS_assert(m_pGraphics != NULL);
+ m_rtClipRect.Set(0, 0, (FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)pBitmap->GetHeight());
+ m_pGraphics->SetClip((const Gdiplus::RectF&)m_rtClipRect);
+}
+CFDE_GdiDevice::~CFDE_GdiDevice()
+{
+ delete m_pGraphics;
+ delete m_pBitmap;
+ if (m_pGlyphBuf) {
+ FDE_Free(m_pGlyphBuf);
+ }
+}
+FX_INT32 CFDE_GdiDevice::GetWidth() const
+{
+ return m_pBitmap->GetWidth();
+}
+FX_INT32 CFDE_GdiDevice::GetHeight() const
+{
+ return m_pBitmap->GetHeight();
+}
+FDE_HDEVICESTATE CFDE_GdiDevice::SaveState()
+{
+ return (FDE_HDEVICESTATE)m_pGraphics->Save();
+}
+void CFDE_GdiDevice::RestoreState(FDE_HDEVICESTATE hState)
+{
+ Gdiplus::Status eRet = m_pGraphics->Restore((Gdiplus::GraphicsState)hState);
+ if (eRet == Gdiplus::Ok) {
+ Gdiplus::Rect rt;
+ eRet = m_pGraphics->GetClipBounds(&rt);
+ if (eRet == Gdiplus::Ok) {
+ m_rtClipRect.Set((FX_FLOAT)rt.X, (FX_FLOAT)rt.Y, (FX_FLOAT)rt.Width, (FX_FLOAT)rt.Height);
+ }
+ }
+}
+FX_BOOL CFDE_GdiDevice::SetClipRect(const CFX_RectF &rtClip)
+{
+ m_rtClipRect = rtClip;
+ return m_pGraphics->SetClip((const Gdiplus::RectF&)rtClip) == Gdiplus::Ok;
+}
+const CFX_RectF& CFDE_GdiDevice::GetClipRect()
+{
+ return m_rtClipRect;
+}
+FX_BOOL CFDE_GdiDevice::SetClipPath(const IFDE_Path *pClip)
+{
+ m_pClipPath = (CFDE_GdiPath*)pClip;
+ Gdiplus::GraphicsPath *pPath = m_pClipPath ? &m_pClipPath->m_Path : NULL;
+ return m_pGraphics->SetClip(pPath) == Gdiplus::Ok;
+}
+IFDE_Path* CFDE_GdiDevice::GetClipPath() const
+{
+ return m_pClipPath;
+}
+FX_FLOAT CFDE_GdiDevice::GetDpiX() const
+{
+ return m_pGraphics->GetDpiX();
+}
+FX_FLOAT CFDE_GdiDevice::GetDpiY() const
+{
+ return m_pGraphics->GetDpiY();
+}
+FX_BOOL CFDE_GdiDevice::DrawImage(IFDE_Image *pImg, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix, const CFX_Matrix *pDevMatrix)
+{
+ CFDE_GdiImage *pGdiImg = (CFDE_GdiImage*)pImg;
+ FXSYS_assert(pGdiImg != NULL && pGdiImg->m_pImage != NULL);
+ CFX_RectF srcRect;
+ if (pSrcRect) {
+ srcRect = *pSrcRect;
+ } else {
+ srcRect.left = srcRect.top = 0;
+ srcRect.width = (FX_FLOAT)pImg->GetImageWidth();
+ srcRect.height = (FX_FLOAT)pImg->GetImageHeight();
+ }
+ CFX_Matrix matrix;
+ if (pImgMatrix) {
+ matrix = *pImgMatrix;
+ } else {
+ matrix.Reset();
+ }
+ matrix.Translate(dstRect.left, dstRect.top);
+ matrix.Scale((dstRect.width / srcRect.width), (dstRect.height / srcRect.height), TRUE);
+ if (pDevMatrix) {
+ matrix.Concat(*pDevMatrix);
+ }
+ CFX_PointF dstPoints[3];
+ dstPoints[0].Set(0, 0);
+ dstPoints[1].Set(srcRect.width, 0);
+ dstPoints[2].Set(0, srcRect.height);
+ matrix.TransformPoints(dstPoints, 3);
+ m_pGraphics->DrawImage(pGdiImg->m_pImage, (Gdiplus::PointF*)dstPoints, 3,
+ srcRect.left, srcRect.top, srcRect.width, srcRect.height,
+ Gdiplus::UnitPixel, NULL, NULL, NULL);
+ return TRUE;
+}
+FX_BOOL CFDE_GdiDevice::DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix, const CFX_Matrix *pDevMatrix)
+{
+ FXSYS_assert(pDib != NULL);
+ BITMAPINFO bmi;
+ FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = pDib->GetWidth();
+ bmi.bmiHeader.biHeight = pDib->GetHeight();
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = pDib->GetBPP();
+ Gdiplus::Bitmap bmp(&bmi, pDib->GetBuffer());
+ CFDE_GdiImage img(&bmp);
+ return DrawImage(&img, pSrcRect, dstRect, pImgMatrix, pDevMatrix);
+}
+FX_BOOL CFDE_GdiDevice::DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pBrush != NULL && pFont != NULL && pCharPos != NULL);
+ FX_ARGB argb = 0xFF000000;
+ if (pBrush->GetType() == FDE_BRUSHTYPE_Solid) {
+ argb = ((IFDE_SolidBrush*)pBrush)->GetColor();
+ }
+ CFDE_GdiFont *pGdiFont = (CFDE_GdiFont*)pFont;
+ GLYPHMETRICS gm;
+ MAT2 mat2;
+ FX_FLOAT fScale = fFontSize / 1000.0f;
+ FX_FLOAT ma, mb, mc, md;
+ FX_FLOAT fx, fy;
+ while (--iCount >= 0) {
+ mb = mc = 0;
+ ma = md = fScale;
+ if (pCharPos->m_bGlyphAdjust) {
+ FX_FLOAT aa = ma * -pCharPos->m_AdjustMatrix[0] + mb * pCharPos->m_AdjustMatrix[2];
+ FX_FLOAT bb = -ma * pCharPos->m_AdjustMatrix[1] + mb * pCharPos->m_AdjustMatrix[3];
+ FX_FLOAT cc = mc * -pCharPos->m_AdjustMatrix[0] + md * pCharPos->m_AdjustMatrix[2];
+ FX_FLOAT dd = -mc * pCharPos->m_AdjustMatrix[1] + md * pCharPos->m_AdjustMatrix[3];
+ ma = aa;
+ mb = bb;
+ mc = cc;
+ md = dd;
+ }
+ if (pMatrix) {
+ FX_FLOAT aa = ma * pMatrix->a + mb * pMatrix->c;
+ FX_FLOAT bb = ma * pMatrix->b + mb * pMatrix->d;
+ FX_FLOAT cc = mc * pMatrix->a + md * pMatrix->c;
+ FX_FLOAT dd = mc * pMatrix->b + md * pMatrix->d;
+ ma = aa;
+ mb = bb;
+ mc = cc;
+ md = dd;
+ }
+ *(long*)(&mat2.eM11) = (long)(ma * 65536);
+ *(long*)(&mat2.eM21) = (long)(mb * 65536);
+ *(long*)(&mat2.eM12) = (long)(mc * 65536);
+ *(long*)(&mat2.eM22) = (long)(md * 65536);
+ FX_DWORD dwSize = pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb, &mat2, gm, NULL, 0);
+ if (dwSize > 0) {
+ if (m_pGlyphBuf == NULL) {
+ m_pGlyphBuf = FDE_Alloc(dwSize);
+ m_dwGlyphLen = dwSize;
+ } else if (m_dwGlyphLen < dwSize) {
+ m_pGlyphBuf = FDE_Realloc(m_pGlyphBuf, dwSize);
+ m_dwGlyphLen = dwSize;
+ }
+ pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb, &mat2, gm, m_pGlyphBuf, m_dwGlyphLen);
+ Gdiplus::Bitmap bmp(gm.gmBlackBoxX, gm.gmBlackBoxY, gm.gmBlackBoxX * 4, PixelFormat32bppARGB, m_pGlyphBuf);
+ if (pMatrix) {
+ fx = pMatrix->a * pCharPos->m_OriginX + pMatrix->c * pCharPos->m_OriginY + pMatrix->e;
+ fy = pMatrix->b * pCharPos->m_OriginX + pMatrix->d * pCharPos->m_OriginY + pMatrix->f;
+ } else {
+ fx = pCharPos->m_OriginX;
+ fy = pCharPos->m_OriginY;
+ }
+ m_pGraphics->DrawImage(&bmp, (FXSYS_round(fx) + gm.gmptGlyphOrigin.x), (FXSYS_round(fy) - gm.gmptGlyphOrigin.y));
+ }
+ pCharPos++;
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_GdiDevice::DrawArc(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ startAngle = FX_RAD2DEG(startAngle);
+ sweepAngle = FX_RAD2DEG(sweepAngle);
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawArc(pGdiPen, rect.left, rect.top, rect.width, rect.height, startAngle, sweepAngle);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawBezier(pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y, pt4.x, pt4.y);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = bClosed
+ ? m_pGraphics->DrawClosedCurve(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), fTension)
+ : m_pGraphics->DrawCurve(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), fTension);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawEllipse(pGdiPen, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawLines(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
+ ApplyMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawLine(pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath *pGdiPath = (CFDE_GdiPath*)pPath;
+ if (pGdiPath == NULL) {
+ return FALSE;
+ }
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawPath(pGdiPen, &pGdiPath->m_Path);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawPie(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ startAngle = FX_RAD2DEG(startAngle);
+ sweepAngle = FX_RAD2DEG(sweepAngle);
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawPie(pGdiPen, rect.left, rect.top, rect.width, rect.height, startAngle, sweepAngle);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawChord(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ CFX_ArcF chord;
+ chord.Set(rect, startAngle, sweepAngle);
+ CFDE_GdiPath path;
+ path.AddChord(chord);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_GdiDevice::DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawPolygon(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawRectangle(pGdiPen, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawRoundRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath path;
+ path.AddRoundRectangle(rect, round);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_GdiDevice::FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillClosedCurve(pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), Gdiplus::FillModeAlternate, fTension);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillEllipse(pGdiBrush, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath *pGdiPath = (CFDE_GdiPath*)pPath;
+ if (pGdiPath == NULL) {
+ return FALSE;
+ }
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillPath(pGdiBrush, &pGdiPath->m_Path);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillPie(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ startAngle = FX_RAD2DEG(startAngle);
+ sweepAngle = FX_RAD2DEG(sweepAngle);
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillPie(pGdiBrush, rect.left, rect.top, rect.width, rect.height, startAngle, sweepAngle);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillChord(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ CFX_ArcF chord;
+ chord.Set(rect, startAngle, sweepAngle);
+ CFDE_GdiPath path;
+ path.AddChord(chord);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_GdiDevice::FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillPolygon(pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillRectangle(pGdiBrush, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillRoundRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath path;
+ path.AddRoundRectangle(rect, round);
+ return FillPath(pBrush, &path, pMatrix);
+}
+Gdiplus::Pen* CFDE_GdiDevice::CreateGdiPen(IFDE_Pen *pPen, FX_FLOAT fPenWidth)
+{
+ if (pPen == NULL || fPenWidth < 0.01f) {
+ return NULL;
+ }
+ Gdiplus::Pen *pGdiPen = NULL;
+ switch (pPen->GetType()) {
+ case FDE_PENTYPE_SolidColor: {
+ Gdiplus::Color gdiColor((Gdiplus::ARGB)pPen->GetColor());
+ pGdiPen = new Gdiplus::Pen(gdiColor, fPenWidth);
+ }
+ break;
+ case FDE_PENTYPE_HatchBrush:
+ case FDE_PENTYPE_TextureBrush:
+ case FDE_PENTYPE_LinearGradient: {
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pPen->GetBrush());
+ if (pGdiBrush) {
+ pGdiPen = new Gdiplus::Pen(pGdiBrush, fPenWidth);
+ }
+ }
+ break;
+ }
+ if (pGdiPen) {
+ CFX_FloatArray dashArray;
+ pPen->GetDashArray(dashArray);
+ pGdiPen->SetDashPattern(dashArray.GetData(), dashArray.GetSize());
+ pGdiPen->SetDashOffset(pPen->GetDashPhase());
+ pGdiPen->SetDashStyle((Gdiplus::DashStyle)pPen->GetDashStyle());
+ pGdiPen->SetStartCap((Gdiplus::LineCap)pPen->GetLineCap());
+ pGdiPen->SetEndCap((Gdiplus::LineCap)pPen->GetLineCap());
+ pGdiPen->SetLineJoin((Gdiplus::LineJoin)pPen->GetLineJoin());
+ pGdiPen->SetMiterLimit(pPen->GetMiterLimit());
+ }
+ return pGdiPen;
+}
+void CFDE_GdiDevice::ReleaseGdiPen(Gdiplus::Pen *pGdiPen)
+{
+ if (pGdiPen) {
+ ReleaseGdiBrush(pGdiPen->GetBrush());
+ delete pGdiPen;
+ }
+}
+Gdiplus::Brush* CFDE_GdiDevice::CreateGdiBrush(IFDE_Brush *pBrush)
+{
+ if (pBrush == NULL) {
+ return NULL;
+ }
+ Gdiplus::Brush *pGdiBrush = NULL;
+ switch (pBrush->GetType()) {
+ case FDE_BRUSHTYPE_Solid: {
+ IFDE_SolidBrush *pSolidBrush = (IFDE_SolidBrush*)pBrush;
+ Gdiplus::Color gdiColor((Gdiplus::ARGB)pSolidBrush->GetColor());
+ pGdiBrush = new Gdiplus::SolidBrush(gdiColor);
+ }
+ break;
+ case FDE_BRUSHTYPE_Hatch: {
+ IFDE_HatchBrush *pHatchBrush = (IFDE_HatchBrush*)pBrush;
+ Gdiplus::Color foreColor((Gdiplus::ARGB)pHatchBrush->GetColor(TRUE));
+ Gdiplus::Color backColor((Gdiplus::ARGB)pHatchBrush->GetColor(FALSE));
+ Gdiplus::HatchStyle hatchStyle = (Gdiplus::HatchStyle)pHatchBrush->GetHatchStyle();
+ pGdiBrush = new Gdiplus::HatchBrush(hatchStyle, foreColor, backColor);
+ }
+ break;
+ case FDE_BRUSHTYPE_Texture: {
+ IFDE_TextureBrush *pTextureBrush = (IFDE_TextureBrush*)pBrush;
+ CFDE_GdiImage *pImgHolder = (CFDE_GdiImage*)pTextureBrush->GetImage();
+ Gdiplus::Image *pGdiImage = pImgHolder ? pImgHolder->m_pImage : NULL;
+ Gdiplus::WrapMode wrapMode = (Gdiplus::WrapMode)pTextureBrush->GetWrapMode();
+ pGdiBrush = new Gdiplus::TextureBrush(pGdiImage, wrapMode);
+ }
+ break;
+ case FDE_BRUSHTYPE_LinearGradient: {
+ IFDE_LinearGradientBrush *pLinearBrush = (IFDE_LinearGradientBrush*)pBrush;
+ Gdiplus::WrapMode wrapMode = (Gdiplus::WrapMode)pLinearBrush->GetWrapMode();
+ CFX_PointF ptStart, ptEnd;
+ pLinearBrush->GetLinearPoints(ptStart, ptEnd);
+ FX_ARGB crStart, crEnd;
+ pLinearBrush->GetLinearColors(crStart, crEnd);
+ pGdiBrush = new Gdiplus::LinearGradientBrush((const Gdiplus::PointF&)ptStart,
+ (const Gdiplus::PointF&)ptEnd,
+ (const Gdiplus::Color&)crStart,
+ (const Gdiplus::Color&)crEnd);
+ }
+ break;
+ }
+ return pGdiBrush;
+}
+void CFDE_GdiDevice::ReleaseGdiBrush(Gdiplus::Brush *pGdiBrush)
+{
+ if (pGdiBrush) {
+ delete pGdiBrush;
+ }
+}
+void CFDE_GdiDevice::ApplyMatrix(const CFX_Matrix *pMatrix)
+{
+ if (pMatrix) {
+ m_GraphicsState = m_pGraphics->Save();
+ Gdiplus::Matrix gdiMatrix(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f);
+ m_pGraphics->SetTransform(&gdiMatrix);
+ }
+}
+void CFDE_GdiDevice::RestoreMatrix(const CFX_Matrix *pMatrix)
+{
+ if (pMatrix) {
+ m_pGraphics->Restore(m_GraphicsState);
+ }
+}
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gdidevice.h b/xfa/src/fdp/src/fde/fde_gdidevice.h
new file mode 100644
index 0000000000..c22ed2b4ba
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gdidevice.h
@@ -0,0 +1,76 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_GDIPLUSDEVICE_IMP
+#define _FDE_GDIPLUSDEVICE_IMP
+#ifdef _FDEPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+class CFDE_GdiPath;
+class CFDE_GdiDevice : public IFDE_RenderDevice, public CFX_Target
+{
+public:
+ CFDE_GdiDevice(CFX_DIBitmap *pDib);
+ ~CFDE_GdiDevice();
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_INT32 GetWidth() const;
+ virtual FX_INT32 GetHeight() const;
+ virtual FDE_HDEVICESTATE SaveState();
+ virtual void RestoreState(FDE_HDEVICESTATE hState);
+ virtual FX_BOOL SetClipPath(const IFDE_Path *pClip);
+ virtual IFDE_Path* GetClipPath() const;
+ virtual FX_BOOL SetClipRect(const CFX_RectF &rtClip);
+ virtual const CFX_RectF& GetClipRect();
+
+ virtual FX_FLOAT GetDpiX() const;
+ virtual FX_FLOAT GetDpiY() const;
+
+ virtual FX_BOOL DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL);
+ virtual FX_BOOL DrawImage(IFDE_Image *pImg, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL);
+ virtual FX_BOOL DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawArc(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPie(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawChord(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawRoundRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPie(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillChord(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillRoundRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix = NULL);
+
+protected:
+ Gdiplus::Pen* CreateGdiPen(IFDE_Pen *pPen, FX_FLOAT fPenWidth);
+ void ReleaseGdiPen(Gdiplus::Pen *pGdiPen);
+ Gdiplus::Brush* CreateGdiBrush(IFDE_Brush *pBrush);
+ void ReleaseGdiBrush(Gdiplus::Brush *pGdiBrush);
+ void ApplyMatrix(const CFX_Matrix *pMatrix);
+ void RestoreMatrix(const CFX_Matrix *pMatrix);
+ Gdiplus::GraphicsState m_GraphicsState;
+ Gdiplus::Graphics *m_pGraphics;
+ Gdiplus::Bitmap *m_pBitmap;
+ FX_LPBYTE m_pGlyphBuf;
+ FX_DWORD m_dwGlyphLen;
+ CFX_RectF m_rtClipRect;
+ CFDE_GdiPath *m_pClipPath;
+};
+#endif
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gedevice.cpp b/xfa/src/fdp/src/fde/fde_gedevice.cpp
new file mode 100644
index 0000000000..81d7ef5a0c
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gedevice.cpp
@@ -0,0 +1,532 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_gedevice.h"
+#include "fde_geobject.h"
+#include "fde_devbasic.h"
+#ifndef _FDEPLUS
+#ifdef _cplusplus
+exten "C" {
+#endif
+ FX_BOOL FDE_GetStockHatchMask(FX_INT32 iHatchStyle, CFX_DIBitmap & hatchMask)
+ {
+ FDE_LPCHATCHDATA pData = FDE_DEVGetHatchData(iHatchStyle);
+ if (!pData) {
+ return FALSE;
+ }
+ hatchMask.Create(pData->iWidth, pData->iHeight, FXDIB_1bppMask);
+ FXSYS_memcpy(hatchMask.GetBuffer(), pData->MaskBits, hatchMask.GetPitch() * pData->iHeight);
+ return TRUE;
+ }
+#ifdef _cplusplus
+}
+#endif
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_DIBitmap *pBitmap, FX_BOOL bRgbByteOrder )
+{
+ if (pBitmap == NULL) {
+ return NULL;
+ }
+ CFX_FxgeDevice *pDevice = FX_NEW CFX_FxgeDevice;
+ if (pDevice == NULL) {
+ return NULL;
+ }
+ pDevice->Attach(pBitmap, 0, bRgbByteOrder);
+ return FDE_New CFDE_FxgeDevice(pDevice, TRUE);
+}
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_RenderDevice *pDevice)
+{
+ if (pDevice == NULL) {
+ return NULL;
+ }
+ return FDE_New CFDE_FxgeDevice(pDevice, FALSE);
+}
+CFDE_FxgeDevice::CFDE_FxgeDevice(CFX_RenderDevice *pDevice, FX_BOOL bOwnerDevice)
+ : m_pDevice(pDevice)
+ , m_bOwnerDevice(bOwnerDevice)
+ , m_pCharPos(NULL)
+ , m_iCharCount(0)
+{
+ FXSYS_assert(pDevice != NULL);
+ FX_RECT rt = m_pDevice->GetClipBox();
+ m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(), (FX_FLOAT)rt.Height());
+}
+CFDE_FxgeDevice::~CFDE_FxgeDevice()
+{
+ if (m_pCharPos != NULL) {
+ FDE_Free(m_pCharPos);
+ }
+ if (m_bOwnerDevice && m_pDevice) {
+ delete m_pDevice;
+ }
+}
+FX_INT32 CFDE_FxgeDevice::GetWidth() const
+{
+ return m_pDevice->GetWidth();
+}
+FX_INT32 CFDE_FxgeDevice::GetHeight() const
+{
+ return m_pDevice->GetHeight();
+}
+FDE_HDEVICESTATE CFDE_FxgeDevice::SaveState()
+{
+ m_pDevice->SaveState();
+ return NULL;
+}
+void CFDE_FxgeDevice::RestoreState(FDE_HDEVICESTATE hState)
+{
+ m_pDevice->RestoreState();
+ const FX_RECT &rt = m_pDevice->GetClipBox();
+ m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(), (FX_FLOAT)rt.Height());
+}
+FX_BOOL CFDE_FxgeDevice::SetClipRect(const CFX_RectF &rtClip)
+{
+ m_rtClip = rtClip;
+ FX_RECT rt((FX_INT32)FXSYS_floor(rtClip.left), (FX_INT32)FXSYS_floor(rtClip.top),
+ (FX_INT32)FXSYS_ceil(rtClip.right()), (FX_INT32)FXSYS_ceil(rtClip.bottom()));
+ return m_pDevice->SetClip_Rect(&rt);
+}
+const CFX_RectF& CFDE_FxgeDevice::GetClipRect()
+{
+ return m_rtClip;
+}
+FX_BOOL CFDE_FxgeDevice::SetClipPath(const IFDE_Path *pClip)
+{
+ return FALSE;
+}
+IFDE_Path* CFDE_FxgeDevice::GetClipPath() const
+{
+ return NULL;
+}
+FX_FLOAT CFDE_FxgeDevice::GetDpiX() const
+{
+ return 96;
+}
+FX_FLOAT CFDE_FxgeDevice::GetDpiY() const
+{
+ return 96;
+}
+FX_BOOL CFDE_FxgeDevice::DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix, const CFX_Matrix *pDevMatrix)
+{
+ FXSYS_assert(pDib != NULL);
+ CFX_RectF srcRect;
+ if (pSrcRect) {
+ srcRect = *pSrcRect;
+ } else {
+ srcRect.Set(0, 0, (FX_FLOAT)pDib->GetWidth(), (FX_FLOAT)pDib->GetHeight());
+ }
+ if (srcRect.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_Matrix dib2fxdev;
+ if (pImgMatrix) {
+ dib2fxdev = *pImgMatrix;
+ } else {
+ dib2fxdev.Reset();
+ }
+ dib2fxdev.a = dstRect.width;
+ dib2fxdev.d = -dstRect.height;
+ dib2fxdev.e = dstRect.left;
+ dib2fxdev.f = dstRect.bottom();
+ if (pDevMatrix) {
+ dib2fxdev.Concat(*pDevMatrix);
+ }
+ FX_LPVOID handle = NULL;
+ m_pDevice->StartDIBits(pDib, 255, 0, (const CFX_AffineMatrix*)&dib2fxdev, 0, handle);
+ while (m_pDevice->ContinueDIBits(handle, NULL)) { }
+ m_pDevice->CancelDIBits(handle);
+ return handle != NULL;
+}
+FX_BOOL CFDE_FxgeDevice::DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pBrush != NULL && pFont != NULL && pCharPos != NULL && iCount > 0);
+ CFX_FontCache *pCache = CFX_GEModule::Get()->GetFontCache();
+ CFX_Font *pFxFont = (CFX_Font*)pFont->GetDevFont();
+ switch (pBrush->GetType()) {
+ case FDE_BRUSHTYPE_Solid: {
+ FX_ARGB argb = ((IFDE_SolidBrush*)pBrush)->GetColor();
+ if ((pFont->GetFontStyles() & FX_FONTSTYLE_Italic) != 0 && !pFxFont->IsItalic()) {
+ FXTEXT_CHARPOS *pCP = (FXTEXT_CHARPOS*)pCharPos;
+ FX_FLOAT *pAM;
+ for (FX_INT32 i = 0; i < iCount; ++i) {
+ static const FX_FLOAT mc = 0.267949f;
+ pAM = pCP->m_AdjustMatrix;
+ pAM[2] = mc * pAM[0] + pAM[2];
+ pAM[3] = mc * pAM[1] + pAM[3];
+ pCP ++;
+ }
+ }
+ FXTEXT_CHARPOS *pCP = (FXTEXT_CHARPOS*)pCharPos;
+ IFX_Font *pCurFont = NULL;
+ IFX_Font *pSTFont = NULL;
+ FXTEXT_CHARPOS *pCurCP = NULL;
+ FX_INT32 iCurCount = 0;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FX_DWORD dwFontStyle = pFont->GetFontStyles();
+ CFX_Font FxFont;
+ CFX_SubstFont SubstFxFont;
+ FxFont.m_pSubstFont = &SubstFxFont;
+ SubstFxFont.m_Weight = dwFontStyle & FX_FONTSTYLE_Bold ? 700 : 400;
+ SubstFxFont.m_WeightCJK = SubstFxFont.m_Weight;
+ SubstFxFont.m_ItalicAngle = dwFontStyle & FX_FONTSTYLE_Italic ? -12 : 0;
+ SubstFxFont.m_bItlicCJK = dwFontStyle & FX_FONTSTYLE_Italic ? TRUE : FALSE;
+#endif
+ for (FX_INT32 i = 0; i < iCount; ++i) {
+ pSTFont = pFont->GetSubstFont((FX_INT32)pCP->m_GlyphIndex);
+ pCP->m_GlyphIndex &= 0x00FFFFFF;
+ pCP->m_bFontStyle = FALSE;
+ if (pCurFont != pSTFont) {
+ if (pCurFont != NULL) {
+ pFxFont = (CFX_Font*)pCurFont->GetDevFont();
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FxFont.m_Face = pFxFont->m_Face;
+ m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+#else
+ m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+#endif
+ }
+ pCurFont = pSTFont;
+ pCurCP = pCP;
+ iCurCount = 1;
+ } else {
+ iCurCount ++;
+ }
+ pCP ++;
+ }
+ if (pCurFont != NULL && iCurCount) {
+ pFxFont = (CFX_Font*)pCurFont->GetDevFont();
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FxFont.m_Face = pFxFont->m_Face;
+ FX_BOOL bRet = m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+ FxFont.m_pSubstFont = NULL;
+ FxFont.m_Face = NULL;
+ return bRet;
+#else
+ return m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+#endif
+ }
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FxFont.m_pSubstFont = NULL;
+ FxFont.m_Face = NULL;
+#endif
+ return TRUE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFDE_FxgeDevice::DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix )
+{
+ CFX_PointsF points;
+ points.Add(pt1);
+ points.Add(pt2);
+ points.Add(pt3);
+ points.Add(pt4);
+ CFDE_Path path;
+ path.AddBezier(points);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddCurve(points, bClosed, fTension);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddEllipse(rect);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddLines(points);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddLine(pt1, pt2);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path *pGePath = (CFDE_Path*)pPath;
+ if (pGePath == NULL) {
+ return FALSE;
+ }
+ CFX_GraphStateData graphState;
+ if (!CreatePen(pPen, fPenWidth, graphState)) {
+ return FALSE;
+ }
+ return m_pDevice->DrawPath(&pGePath->m_Path, (const CFX_AffineMatrix*)pMatrix, &graphState, 0, pPen->GetColor(), 0);
+}
+FX_BOOL CFDE_FxgeDevice::DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddPolygon(points);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddRectangle(rect);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddCurve(points, TRUE, fTension);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddEllipse(rect);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddPolygon(points);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddRectangle(rect);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::CreatePen(IFDE_Pen *pPen, FX_FLOAT fPenWidth, CFX_GraphStateData &graphState)
+{
+ if (pPen == NULL) {
+ return FALSE;
+ }
+ graphState.m_LineCap = (CFX_GraphStateData::LineCap)pPen->GetLineCap();
+ graphState.m_LineJoin = (CFX_GraphStateData::LineJoin)pPen->GetLineJoin();
+ graphState.m_LineWidth = fPenWidth;
+ graphState.m_MiterLimit = pPen->GetMiterLimit();
+ graphState.m_DashPhase = pPen->GetDashPhase();
+ CFX_FloatArray dashArray;
+ switch (pPen->GetDashStyle()) {
+ case FDE_DASHSTYLE_Dash:
+ dashArray.Add(3);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_Dot:
+ dashArray.Add(1);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_DashDot:
+ dashArray.Add(3);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_DashDotDot:
+ dashArray.Add(3);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_Customized:
+ pPen->GetDashArray(dashArray);
+ break;
+ }
+ FX_INT32 iDashCount = dashArray.GetSize();
+ if (iDashCount > 0) {
+ graphState.SetDashCount(iDashCount);
+ for (FX_INT32 i = 0; i < iDashCount; ++i) {
+ graphState.m_DashArray[i] = dashArray[i] * fPenWidth;
+ }
+ }
+ return TRUE;
+}
+typedef FX_BOOL (CFDE_FxgeDevice::*pfFillPath)(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+static const pfFillPath gs_FillPath[] = {
+ &CFDE_FxgeDevice::FillSolidPath,
+ &CFDE_FxgeDevice::FillHatchPath,
+ &CFDE_FxgeDevice::FillTexturePath,
+ &CFDE_FxgeDevice::FillLinearGradientPath,
+};
+FX_BOOL CFDE_FxgeDevice::FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix)
+{
+ CFDE_Path *pGePath = (CFDE_Path*)pPath;
+ if (pGePath == NULL) {
+ return FALSE;
+ }
+ if (pBrush == NULL) {
+ return FALSE;
+ }
+ FX_INT32 iType = pBrush->GetType();
+ if (iType < 0 || iType > FDE_BRUSHTYPE_MAX) {
+ return FALSE;
+ }
+ return (this->*gs_FillPath[iType])(pBrush, &pGePath->m_Path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillSolidPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Solid);
+ IFDE_SolidBrush *pSolidBrush = (IFDE_SolidBrush*)pBrush;
+ return m_pDevice->DrawPath(pPath, (const CFX_AffineMatrix*)pMatrix, NULL, pSolidBrush->GetColor(), 0, FXFILL_WINDING);
+}
+FX_BOOL CFDE_FxgeDevice::FillHatchPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Hatch);
+ IFDE_HatchBrush *pHatchBrush = (IFDE_HatchBrush*)pBrush;
+ FX_INT32 iStyle = pHatchBrush->GetHatchStyle();
+ if (iStyle < FDE_HATCHSTYLE_Min || iStyle > FDE_HATCHSTYLE_Max) {
+ return FALSE;
+ }
+ CFX_DIBitmap mask;
+ if (!FDE_GetStockHatchMask(iStyle, mask)) {
+ return FALSE;
+ }
+ FX_ARGB dwForeColor = pHatchBrush->GetColor(TRUE);
+ FX_ARGB dwBackColor = pHatchBrush->GetColor(FALSE);
+ CFX_FloatRect rectf = pPath->GetBoundingBox();
+ if (pMatrix) {
+ rectf.Transform((const CFX_AffineMatrix*)pMatrix);
+ }
+ FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
+ FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
+ m_pDevice->SaveState();
+ m_pDevice->StartRendering();
+ m_pDevice->SetClip_PathFill(pPath, (const CFX_AffineMatrix*)pMatrix, FXFILL_WINDING);
+ m_pDevice->FillRect(&rect, dwBackColor);
+ for (FX_INT32 j = rect.bottom; j < rect.top; j += mask.GetHeight())
+ for (FX_INT32 i = rect.left; i < rect.right; i += mask.GetWidth()) {
+ m_pDevice->SetBitMask(&mask, i, j, dwForeColor);
+ }
+ m_pDevice->EndRendering();
+ m_pDevice->RestoreState();
+ return TRUE;
+}
+FX_BOOL CFDE_FxgeDevice::FillTexturePath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Texture);
+ IFDE_TextureBrush *pTextureBrush = (IFDE_TextureBrush*)pBrush;
+ IFDE_Image *pImage = (IFDE_Image*)pTextureBrush->GetImage();
+ if (pImage == NULL) {
+ return FALSE;
+ }
+ CFX_Size size;
+ size.Set(pImage->GetImageWidth(), pImage->GetImageHeight());
+ CFX_DIBitmap bmp;
+ bmp.Create(size.x, size.y, FXDIB_Argb);
+ if (!pImage->StartLoadImage(&bmp, 0, 0, size.x, size.y, 0, 0, size.x, size.y)) {
+ return FALSE;
+ }
+ if (pImage->DoLoadImage() < 100) {
+ return FALSE;
+ }
+ pImage->StopLoadImage();
+ return WrapTexture(pTextureBrush->GetWrapMode(), &bmp, pPath, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::WrapTexture(FX_INT32 iWrapMode, const CFX_DIBitmap *pBitmap, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ CFX_FloatRect rectf = pPath->GetBoundingBox();
+ if (pMatrix) {
+ rectf.Transform((const CFX_AffineMatrix*)pMatrix);
+ }
+ FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
+ FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
+ rect.Normalize();
+ if (rect.IsEmpty()) {
+ return FALSE;
+ }
+ m_pDevice->SaveState();
+ m_pDevice->StartRendering();
+ m_pDevice->SetClip_PathFill(pPath, (const CFX_AffineMatrix*)pMatrix, FXFILL_WINDING);
+ switch (iWrapMode) {
+ case FDE_WRAPMODE_Tile:
+ case FDE_WRAPMODE_TileFlipX:
+ case FDE_WRAPMODE_TileFlipY:
+ case FDE_WRAPMODE_TileFlipXY: {
+ FX_BOOL bFlipX = iWrapMode == FDE_WRAPMODE_TileFlipXY || iWrapMode == FDE_WRAPMODE_TileFlipX;
+ FX_BOOL bFlipY = iWrapMode == FDE_WRAPMODE_TileFlipXY || iWrapMode == FDE_WRAPMODE_TileFlipY;
+ const CFX_DIBitmap *pFlip[2][2];
+ pFlip[0][0] = pBitmap;
+ pFlip[0][1] = bFlipX ? pBitmap->FlipImage(TRUE, FALSE) : pBitmap;
+ pFlip[1][0] = bFlipY ? pBitmap->FlipImage(FALSE, TRUE) : pBitmap;
+ pFlip[1][1] = (bFlipX || bFlipY) ? pBitmap->FlipImage(bFlipX, bFlipY) : pBitmap;
+ FX_INT32 iCounterY = 0;
+ for (FX_INT32 j = rect.top; j < rect.bottom; j += pBitmap->GetHeight()) {
+ FX_INT32 indexY = iCounterY++ % 2;
+ FX_INT32 iCounterX = 0;
+ for (FX_INT32 i = rect.left; i < rect.right; i += pBitmap->GetWidth()) {
+ FX_INT32 indexX = iCounterX++ % 2;
+ m_pDevice->SetDIBits(pFlip[indexY][indexX], i, j);
+ }
+ }
+ if (pFlip[0][1] != pFlip[0][0]) {
+ delete pFlip[0][1];
+ }
+ if (pFlip[1][0] != pFlip[0][0]) {
+ delete pFlip[1][0];
+ }
+ if (pFlip[1][1] != pFlip[0][0]) {
+ delete pFlip[1][1];
+ }
+ }
+ break;
+ case FDE_WRAPMODE_Clamp: {
+ m_pDevice->SetDIBits(pBitmap, rect.left, rect.bottom);
+ }
+ break;
+ }
+ m_pDevice->EndRendering();
+ m_pDevice->RestoreState();
+ return TRUE;
+}
+FX_BOOL CFDE_FxgeDevice::FillLinearGradientPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_LinearGradient);
+ IFDE_LinearGradientBrush *pLinearBrush = (IFDE_LinearGradientBrush*)pBrush;
+ CFX_PointF pt0, pt1;
+ pLinearBrush->GetLinearPoints(pt0, pt1);
+ CFX_VectorF fDiagonal;
+ fDiagonal.Set(pt0, pt1);
+ FX_FLOAT fTheta = FXSYS_atan2(fDiagonal.y, fDiagonal.x);
+ FX_FLOAT fLength = fDiagonal.Length();
+ FX_FLOAT fTotalX = fLength / FXSYS_cos(fTheta);
+ FX_FLOAT fTotalY = fLength / FXSYS_cos(FX_PI / 2 - fTheta);
+ FX_FLOAT fSteps = FX_MAX(fTotalX, fTotalY);
+ FX_FLOAT dx = fTotalX / fSteps;
+ FX_FLOAT dy = fTotalY / fSteps;
+ FX_ARGB cr0, cr1;
+ pLinearBrush->GetLinearColors(cr0, cr1);
+ FX_FLOAT a0 = FXARGB_A(cr0);
+ FX_FLOAT r0 = FXARGB_R(cr0);
+ FX_FLOAT g0 = FXARGB_G(cr0);
+ FX_FLOAT b0 = FXARGB_B(cr0);
+ FX_FLOAT da = (FXARGB_A(cr1) - a0) / fSteps;
+ FX_FLOAT dr = (FXARGB_R(cr1) - r0) / fSteps;
+ FX_FLOAT dg = (FXARGB_G(cr1) - g0) / fSteps;
+ FX_FLOAT db = (FXARGB_B(cr1) - b0) / fSteps;
+ CFX_DIBitmap bmp;
+ bmp.Create(FXSYS_round(FXSYS_fabs(fDiagonal.x)), FXSYS_round(FXSYS_fabs(fDiagonal.y)), FXDIB_Argb);
+ CFX_FxgeDevice dev;
+ dev.Attach(&bmp);
+ pt1 = pt0;
+ FX_INT32 iSteps = FXSYS_round(FXSYS_ceil(fSteps));
+ while (--iSteps >= 0) {
+ cr0 = ArgbEncode(FXSYS_round(a0), FXSYS_round(r0), FXSYS_round(g0), FXSYS_round(b0));
+ dev.DrawCosmeticLine(pt0.x, pt0.y, pt1.x, pt1.y, cr0);
+ pt1.x += dx;
+ pt0.y += dy;
+ a0 += da;
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+ }
+ return WrapTexture(pLinearBrush->GetWrapMode(), &bmp, pPath, pMatrix);
+}
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gedevice.h b/xfa/src/fdp/src/fde/fde_gedevice.h
new file mode 100644
index 0000000000..6290e53390
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gedevice.h
@@ -0,0 +1,63 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_FXGEDEVICE_IMP
+#define _FDE_FXGEDEVICE_IMP
+#ifndef _FDEPLUS
+class CFDE_FxgeDevice : public IFDE_RenderDevice, public CFX_Target
+{
+public:
+ CFDE_FxgeDevice(CFX_RenderDevice *pDevice, FX_BOOL bOwnerDevice);
+ ~CFDE_FxgeDevice();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_INT32 GetWidth() const;
+ virtual FX_INT32 GetHeight() const;
+ virtual FDE_HDEVICESTATE SaveState();
+ virtual void RestoreState(FDE_HDEVICESTATE hState);
+ virtual FX_BOOL SetClipPath(const IFDE_Path *pClip);
+ virtual IFDE_Path* GetClipPath() const;
+ virtual FX_BOOL SetClipRect(const CFX_RectF &rtClip);
+ virtual const CFX_RectF& GetClipRect();
+
+ virtual FX_FLOAT GetDpiX() const;
+ virtual FX_FLOAT GetDpiY() const;
+
+ virtual FX_BOOL DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL);
+ virtual FX_BOOL DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ FX_BOOL FillSolidPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL FillHatchPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL FillTexturePath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL FillLinearGradientPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL DrawSolidString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix);
+ FX_BOOL DrawStringPath(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix);
+protected:
+ FX_BOOL CreatePen(IFDE_Pen *pPen, FX_FLOAT fPenWidth, CFX_GraphStateData &graphState);
+ FX_BOOL WrapTexture(FX_INT32 iWrapMode, const CFX_DIBitmap *pBitmap, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ CFX_RenderDevice *m_pDevice;
+ CFX_RectF m_rtClip;
+ FX_BOOL m_bOwnerDevice;
+ FXTEXT_CHARPOS *m_pCharPos;
+ FX_INT32 m_iCharCount;
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_geobject.cpp b/xfa/src/fdp/src/fde/fde_geobject.cpp
new file mode 100644
index 0000000000..9f34cf3051
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_geobject.cpp
@@ -0,0 +1,270 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_object.h"
+#include "fde_geobject.h"
+#ifndef _FDEPLUS
+IFDE_Path* IFDE_Path::Create()
+{
+ return FDE_New CFDE_Path;
+}
+FX_BOOL CFDE_Path::StartFigure()
+{
+ return CloseFigure();
+}
+FX_BOOL CFDE_Path::CloseFigure()
+{
+ FX_PATHPOINT *pPoint = GetLastPoint();
+ if (pPoint) {
+ pPoint->m_Flag |= FXPT_CLOSEFIGURE;
+ }
+ return TRUE;
+}
+FX_PATHPOINT* CFDE_Path::GetLastPoint(FX_INT32 iCount ) const
+{
+ if (iCount < 1) {
+ return NULL;
+ }
+ FX_INT32 iPoints = m_Path.GetPointCount();
+ if (iCount > iPoints) {
+ return NULL;
+ }
+ return m_Path.GetPoints() + iPoints - iCount;
+}
+FX_BOOL CFDE_Path::FigureClosed() const
+{
+ FX_PATHPOINT *pPoint = GetLastPoint();
+ return pPoint ? (pPoint->m_Flag & FXPT_CLOSEFIGURE) : TRUE;
+}
+FX_PATHPOINT* CFDE_Path::AddPoints(FX_INT32 iCount)
+{
+ if (iCount < 1) {
+ return NULL;
+ }
+ FX_INT32 iPoints = m_Path.GetPointCount();
+ m_Path.AddPointCount(iCount);
+ return m_Path.GetPoints() + iPoints;
+}
+void CFDE_Path::MoveTo(FX_FLOAT fx, FX_FLOAT fy)
+{
+ FX_PATHPOINT *pPoint = AddPoints(1);
+ pPoint->m_PointX = fx;
+ pPoint->m_PointY = fy;
+ pPoint->m_Flag = FXPT_MOVETO;
+}
+void CFDE_Path::LineTo(FX_FLOAT fx, FX_FLOAT fy)
+{
+ FX_PATHPOINT *pPoint = AddPoints(1);
+ pPoint->m_PointX = fx;
+ pPoint->m_PointY = fy;
+ pPoint->m_Flag = FXPT_LINETO;
+}
+void CFDE_Path::BezierTo(const CFX_PointF &p1, const CFX_PointF &p2, const CFX_PointF &p3)
+{
+ FX_PATHPOINT *p = AddPoints(3);
+ p[0].m_PointX = p1.x;
+ p[0].m_PointY = p1.y;
+ p[0].m_Flag = FXPT_BEZIERTO;
+ p[1].m_PointX = p2.x;
+ p[1].m_PointY = p2.y;
+ p[1].m_Flag = FXPT_BEZIERTO;
+ p[2].m_PointX = p3.x;
+ p[2].m_PointY = p3.y;
+ p[2].m_Flag = FXPT_BEZIERTO;
+}
+void CFDE_Path::ArcTo(FX_BOOL bStart, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT endAngle)
+{
+ FX_FLOAT rx = rect.width / 2;
+ FX_FLOAT ry = rect.height / 2;
+ FX_FLOAT cx = rect.left + rx;
+ FX_FLOAT cy = rect.top + ry;
+ FX_FLOAT alpha = FXSYS_atan2(rx * FXSYS_sin(startAngle), ry * FXSYS_cos(startAngle));
+ FX_FLOAT beta = FXSYS_atan2(rx * FXSYS_sin(endAngle), ry * FXSYS_cos(endAngle));
+ if (FXSYS_fabs(beta - alpha) > FX_PI) {
+ if (beta > alpha) {
+ beta -= 2 * FX_PI;
+ } else {
+ alpha -= 2 * FX_PI;
+ }
+ }
+ FX_FLOAT half_delta = (beta - alpha) / 2;
+ FX_FLOAT bcp = 4.0f / 3 * (1 - FXSYS_cos(half_delta)) / FXSYS_sin(half_delta);
+ FX_FLOAT sin_alpha = FXSYS_sin(alpha);
+ FX_FLOAT sin_beta = FXSYS_sin(beta);
+ FX_FLOAT cos_alpha = FXSYS_cos(alpha);
+ FX_FLOAT cos_beta = FXSYS_cos(beta);
+ if (bStart) {
+ CFX_PointF p0;
+ p0.Set(cx + rx * cos_alpha, cy + ry * sin_alpha);
+ MoveTo(p0);
+ }
+ CFX_PointF p1;
+ p1.Set(cx + rx * (cos_alpha - bcp * sin_alpha), cy + ry * (sin_alpha + bcp * cos_alpha));
+ CFX_PointF p2;
+ p2.Set(cx + rx * (cos_beta + bcp * sin_beta), cy + ry * (sin_beta - bcp * cos_beta));
+ CFX_PointF p3;
+ p3.Set(cx + rx * cos_beta, cy + ry * sin_beta);
+ BezierTo(p1, p2, p3);
+}
+void CFDE_Path::AddBezier(const CFX_PointsF &points)
+{
+ if (points.GetSize() != 4) {
+ return;
+ }
+ FX_LPCPOINTF p = points.GetData();
+ MoveTo(p[0]);
+ BezierTo(p[1], p[2], p[3]);
+}
+void CFDE_Path::AddBeziers(const CFX_PointsF &points)
+{
+ FX_INT32 iCount = points.GetSize();
+ if (iCount < 4) {
+ return;
+ }
+ FX_LPCPOINTF p = points.GetData();
+ FX_LPCPOINTF pEnd = p + iCount;
+ MoveTo(p[0]);
+ for (++p; p <= pEnd - 3; p += 3) {
+ BezierTo(p[0], p[1], p[2]);
+ }
+}
+void CFDE_Path::GetCurveTangents(const CFX_PointsF &points, CFX_PointsF &tangents, FX_BOOL bClosed, FX_FLOAT fTension) const
+{
+ FX_INT32 iCount = points.GetSize();
+ tangents.SetSize(iCount);
+ if (iCount < 3) {
+ return;
+ }
+ FX_FLOAT fCoefficient = fTension / 3.0f;
+ FX_LPCPOINTF pPoints = points.GetData();
+ FX_LPPOINTF pTangents = tangents.GetData();
+ for (FX_INT32 i = 0; i < iCount; ++i) {
+ FX_INT32 r = i + 1;
+ FX_INT32 s = i - 1;
+ if (r >= iCount) {
+ r = bClosed ? (r - iCount) : (iCount - 1);
+ }
+ if (s < 0) {
+ s = bClosed ? (s + iCount) : 0;
+ }
+ pTangents[i].x += (fCoefficient * (pPoints[r].x - pPoints[s].x));
+ pTangents[i].y += (fCoefficient * (pPoints[r].y - pPoints[s].y));
+ }
+}
+void CFDE_Path::AddCurve(const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension)
+{
+ FX_INT32 iLast = points.GetUpperBound();
+ if (iLast < 1) {
+ return;
+ }
+ CFX_PointsF tangents;
+ GetCurveTangents(points, tangents, bClosed, fTension);
+ FX_LPCPOINTF pPoints = points.GetData();
+ FX_LPPOINTF pTangents = tangents.GetData();
+ MoveTo(pPoints[0]);
+ for (FX_INT32 i = 0; i < iLast; ++i) {
+ FX_INT32 j = i + 1;
+ CFX_PointF p1;
+ p1.Set(pPoints[i].x + pTangents[i].x, pPoints[i].y + pTangents[i].y);
+ CFX_PointF p2;
+ p2.Set(pPoints[j].x - pTangents[j].x, pPoints[j].y - pTangents[j].y);
+ CFX_PointF p3;
+ p3.Set(pPoints[j].x, pPoints[j].y);
+ BezierTo(p1, p2, p3);
+ }
+ if (bClosed) {
+ CFX_PointF p1;
+ p1.Set(pPoints[iLast].x + pTangents[iLast].x, pPoints[iLast].y + pTangents[iLast].y);
+ CFX_PointF p2;
+ p2.Set(pPoints[0].x - pTangents[0].x, pPoints[0].y - pTangents[0].y);
+ CFX_PointF p3;
+ p3.Set(pPoints[0].x, pPoints[0].y);
+ BezierTo(p1, p2, p3);
+ CloseFigure();
+ }
+}
+void CFDE_Path::AddEllipse(const CFX_RectF &rect)
+{
+ FX_FLOAT fStartAngle = 0;
+ FX_FLOAT fEndAngle = FX_PI / 2;
+ for (FX_INT32 i = 0; i < 4; ++i) {
+ ArcTo(i == 0, rect, fStartAngle, fEndAngle);
+ fStartAngle += FX_PI / 2;
+ fEndAngle += FX_PI / 2;
+ }
+ CloseFigure();
+}
+void CFDE_Path::AddLine(const CFX_PointF &pt1, const CFX_PointF &pt2)
+{
+ FX_PATHPOINT *pLast = GetLastPoint();
+ if (pLast == NULL || FXSYS_fabs(pLast->m_PointX - pt1.x) > 0.001 || FXSYS_fabs(pLast->m_PointY - pt1.y) > 0.001) {
+ MoveTo(pt1);
+ }
+ LineTo(pt2);
+}
+void CFDE_Path::AddPath(const IFDE_Path *pSrc, FX_BOOL bConnect)
+{
+ CFDE_Path *pPath = (CFDE_Path*)pSrc;
+ if (pPath == NULL) {
+ return;
+ }
+ FX_INT32 iCount = pPath->m_Path.GetPointCount();
+ if (iCount < 1) {
+ return;
+ }
+ if (bConnect) {
+ LineTo(pPath->m_Path.GetPointX(0), pPath->m_Path.GetPointY(0));
+ }
+ m_Path.Append(&pPath->m_Path, NULL);
+}
+void CFDE_Path::AddPolygon(const CFX_PointsF &points)
+{
+ FX_INT32 iCount = points.GetSize();
+ if (iCount < 2) {
+ return;
+ }
+ AddLines(points);
+ FX_LPCPOINTF p = points.GetData();
+ if (FXSYS_fabs(p[0].x - p[iCount - 1].x) < 0.01f || FXSYS_fabs(p[0].y - p[iCount - 1].y) < 0.01f) {
+ LineTo(p[0]);
+ }
+ CloseFigure();
+}
+void CFDE_Path::AddLines(const CFX_PointsF &points)
+{
+ FX_INT32 iCount = points.GetSize();
+ if (iCount < 2) {
+ return;
+ }
+ FX_LPCPOINTF p = points.GetData();
+ FX_LPCPOINTF pEnd = p + iCount;
+ MoveTo(p[0]);
+ for (++p; p < pEnd; ++p) {
+ LineTo(*p);
+ }
+}
+void CFDE_Path::AddRectangle(const CFX_RectF &rect)
+{
+ MoveTo(rect.TopLeft());
+ LineTo(rect.TopRight());
+ LineTo(rect.BottomRight());
+ LineTo(rect.BottomLeft());
+ CloseFigure();
+}
+void CFDE_Path::GetBBox(CFX_RectF &bbox) const
+{
+ CFX_FloatRect rect = m_Path.GetBoundingBox();
+ bbox.Set(rect.left, rect.top, rect.Width(), rect.Height());
+ bbox.Normalize();
+}
+void CFDE_Path::GetBBox(CFX_RectF &bbox, FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const
+{
+ CFX_FloatRect rect = m_Path.GetBoundingBox(fLineWidth, fMiterLimit);
+ bbox.Set(rect.left, rect.top, rect.Width(), rect.Height());
+ bbox.Normalize();
+}
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_geobject.h b/xfa/src/fdp/src/fde/fde_geobject.h
new file mode 100644
index 0000000000..8552b6f7b8
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_geobject.h
@@ -0,0 +1,53 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_GRAPHOBJS_IMP
+#define _FDE_GRAPHOBJS_IMP
+#ifndef _FDEPLUS
+#include "../../../foxitlib.h"
+class CFDE_GEFontMgr;
+class CFDE_Path : public IFDE_Path, public CFX_Target
+{
+public:
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_BOOL StartFigure();
+ virtual FX_BOOL CloseFigure();
+
+ virtual void AddBezier(const CFX_PointsF &points);
+ virtual void AddBeziers(const CFX_PointsF &points);
+ virtual void AddCurve(const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f);
+ virtual void AddEllipse(const CFX_RectF &rect);
+ virtual void AddLines(const CFX_PointsF &points);
+ virtual void AddLine(const CFX_PointF &pt1, const CFX_PointF &pt2);
+ virtual void AddPath(const IFDE_Path *pSrc, FX_BOOL bConnect);
+ virtual void AddPolygon(const CFX_PointsF &points);
+ virtual void AddRectangle(const CFX_RectF &rect);
+ virtual void GetBBox(CFX_RectF &bbox) const;
+ virtual void GetBBox(CFX_RectF &bbox, FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const;
+ FX_PATHPOINT* AddPoints(FX_INT32 iCount);
+ FX_PATHPOINT* GetLastPoint(FX_INT32 iCount = 1) const;
+ FX_BOOL FigureClosed() const;
+ void MoveTo(FX_FLOAT fx, FX_FLOAT fy);
+ void LineTo(FX_FLOAT fx, FX_FLOAT fy);
+ void BezierTo(const CFX_PointF &p1, const CFX_PointF &p2, const CFX_PointF &p3);
+ void ArcTo(FX_BOOL bStart, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT endAngle);
+ void MoveTo(const CFX_PointF &p0)
+ {
+ MoveTo(p0.x, p0.y);
+ }
+ void LineTo(const CFX_PointF &p1)
+ {
+ LineTo(p1.x, p1.y);
+ }
+ void GetCurveTangents(const CFX_PointsF &points, CFX_PointsF &tangents, FX_BOOL bClosed, FX_FLOAT fTension) const;
+ CFX_PathData m_Path;
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_iterator.cpp b/xfa/src/fdp/src/fde/fde_iterator.cpp
new file mode 100644
index 0000000000..5f6e0aa7e8
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_iterator.cpp
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_iterator.h"
+IFDE_VisualSetIterator* IFDE_VisualSetIterator::Create()
+{
+ return FDE_New CFDE_VisualSetIterator;
+}
+CFDE_VisualSetIterator::CFDE_VisualSetIterator()
+ : m_dwFilter(0)
+{
+}
+CFDE_VisualSetIterator::~CFDE_VisualSetIterator()
+{
+ m_CanvasStack.RemoveAll();
+}
+FX_BOOL CFDE_VisualSetIterator::AttachCanvas(IFDE_CanvasSet *pCanvas)
+{
+ FXSYS_assert(pCanvas != NULL);
+ m_CanvasStack.RemoveAll();
+ FDE_CANVASITEM canvas;
+ canvas.hCanvas = NULL;
+ canvas.pCanvas = pCanvas;
+ canvas.hPos = pCanvas->GetFirstPosition(NULL);
+ if (canvas.hPos == NULL) {
+ return FALSE;
+ }
+ return m_CanvasStack.Push(canvas) == 0;
+}
+FX_BOOL CFDE_VisualSetIterator::FilterObjects(FX_DWORD dwObjects )
+{
+ if (m_CanvasStack.GetSize() == 0) {
+ return FALSE;
+ }
+ while (m_CanvasStack.GetSize() > 1) {
+ m_CanvasStack.Pop();
+ }
+ m_dwFilter = dwObjects & ~(FX_DWORD)FDE_VISUALOBJ_Widget;
+ if (dwObjects & FDE_VISUALOBJ_Widget) {
+ m_dwFilter |= 0xFF00;
+ }
+ FDE_LPCANVASITEM pCanvas = m_CanvasStack.GetTopElement();
+ FXSYS_assert(pCanvas != NULL && pCanvas->pCanvas != NULL);
+ pCanvas->hPos = pCanvas->pCanvas->GetFirstPosition(NULL);
+ return pCanvas->hPos != NULL;
+}
+void CFDE_VisualSetIterator::Reset()
+{
+ FilterObjects(m_dwFilter);
+}
+FDE_HVISUALOBJ CFDE_VisualSetIterator::GetNext(IFDE_VisualSet *&pVisualSet, FDE_HVISUALOBJ *phCanvasObj , IFDE_CanvasSet **ppCanvasSet )
+{
+ while (m_CanvasStack.GetSize() > 0) {
+ FDE_LPCANVASITEM pCanvas = m_CanvasStack.GetTopElement();
+ FXSYS_assert(pCanvas != NULL && pCanvas->pCanvas != NULL);
+ if (pCanvas->hPos == NULL) {
+ if (m_CanvasStack.GetSize() == 1) {
+ break;
+ }
+ m_CanvasStack.Pop();
+ continue;
+ }
+ do {
+ FDE_HVISUALOBJ hObj = pCanvas->pCanvas->GetNext(pCanvas->hCanvas, pCanvas->hPos, pVisualSet);
+ FXSYS_assert(hObj != NULL);
+ FDE_VISUALOBJTYPE eType = pVisualSet->GetType();
+ if (eType == FDE_VISUALOBJ_Canvas) {
+ FDE_CANVASITEM canvas;
+ canvas.hCanvas = hObj;
+ canvas.pCanvas = (IFDE_CanvasSet*)pVisualSet;
+ canvas.hPos = canvas.pCanvas->GetFirstPosition(hObj);
+ m_CanvasStack.Push(canvas);
+ break;
+ }
+ FX_DWORD dwObj = (eType == FDE_VISUALOBJ_Widget)
+ ? (FX_DWORD)((IFDE_WidgetSet*)pVisualSet)->GetWidgetType(hObj)
+ : (FX_DWORD)eType;
+ if ((m_dwFilter & dwObj) != 0) {
+ if (ppCanvasSet) {
+ *ppCanvasSet = pCanvas->pCanvas;
+ }
+ if (phCanvasObj) {
+ *phCanvasObj = pCanvas->hCanvas;
+ }
+ return hObj;
+ }
+ } while (pCanvas->hPos != NULL);
+ }
+ if (ppCanvasSet) {
+ *ppCanvasSet = NULL;
+ }
+ if (phCanvasObj) {
+ *phCanvasObj = NULL;
+ }
+ pVisualSet = NULL;
+ return NULL;
+}
diff --git a/xfa/src/fdp/src/fde/fde_iterator.h b/xfa/src/fdp/src/fde/fde_iterator.h
new file mode 100644
index 0000000000..6ebd5c566f
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_iterator.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_ITERATOR_IMP
+#define _FDE_ITERATOR_IMP
+typedef struct _FDE_CANVASITEM : public CFX_Target {
+ IFDE_CanvasSet *pCanvas;
+ FDE_HVISUALOBJ hCanvas;
+ FX_POSITION hPos;
+} FDE_CANVASITEM, * FDE_LPCANVASITEM;
+class CFDE_VisualSetIterator : public IFDE_VisualSetIterator, public CFX_Target
+{
+public:
+ CFDE_VisualSetIterator();
+ ~CFDE_VisualSetIterator();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_BOOL AttachCanvas(IFDE_CanvasSet *pCanvas);
+ virtual FX_BOOL FilterObjects(FX_DWORD dwObjects = 0xFFFFFFFF);
+
+ virtual void Reset();
+ virtual FDE_HVISUALOBJ GetNext(IFDE_VisualSet *&pVisualSet, FDE_HVISUALOBJ *phCanvasObj = NULL, IFDE_CanvasSet **ppCanvasSet = NULL);
+protected:
+ FX_DWORD m_dwFilter;
+ CFX_StackTemplate<FDE_CANVASITEM> m_CanvasStack;
+};
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_object.cpp b/xfa/src/fdp/src/fde/fde_object.cpp
new file mode 100644
index 0000000000..d8a555a7bd
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_object.cpp
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_object.h"
+IFDE_Pen* IFDE_Pen::Create()
+{
+ return FDE_New CFDE_Pen();
+}
+IFDE_Brush* IFDE_Brush::Create(FX_INT32 iType)
+{
+ switch (iType) {
+ case FDE_BRUSHTYPE_Solid:
+ return FDE_New CFDE_SolidBrush;
+ case FDE_BRUSHTYPE_Hatch:
+ return FDE_New CFDE_HatchBrush;
+ case FDE_BRUSHTYPE_Texture:
+ return FDE_New CFDE_TextureBrush;
+ case FDE_BRUSHTYPE_LinearGradient:
+ return FDE_New CFDE_LinearBrush;
+ default:
+ return NULL;
+ }
+}
diff --git a/xfa/src/fdp/src/fde/fde_object.h b/xfa/src/fdp/src/fde/fde_object.h
new file mode 100644
index 0000000000..553d77fb21
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_object.h
@@ -0,0 +1,427 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_BASEOBJECT_IMP
+#define _FDE_BASEOBJECT_IMP
+class CFDE_Pen : public IFDE_Pen, public CFX_Target
+{
+public:
+ CFDE_Pen()
+ : m_Color(0)
+ , m_iLineCap(0)
+ , m_iLineJoin(0)
+ , m_iDashStyle(0)
+ , m_fDashPhase(0)
+ , m_fMiterLimit(10)
+ , m_bAutoRelease(FALSE)
+ , m_pBrush(NULL)
+ {
+ }
+
+ ~CFDE_Pen()
+ {
+ if (m_pBrush && m_bAutoRelease) {
+ m_pBrush->Release();
+ }
+ }
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_INT32 GetType() const
+ {
+ return m_pBrush ? m_pBrush->GetType() : FDE_PENTYPE_SolidColor;
+ }
+
+ virtual FX_ARGB GetColor() const
+ {
+ return m_Color;
+ }
+ virtual void SetColor(FX_ARGB color)
+ {
+ m_Color = color;
+ }
+ virtual IFDE_Brush* GetBrush() const
+ {
+ return m_pBrush;
+ }
+ virtual void SetBrush(IFDE_Brush *pBrush, FX_BOOL bAutoRelease)
+ {
+ m_bAutoRelease = bAutoRelease;
+ m_pBrush = pBrush;
+ if (m_pBrush && m_pBrush->GetType() == FDE_BRUSHTYPE_Solid) {
+ m_Color = ((IFDE_SolidBrush*)m_pBrush)->GetColor();
+ }
+ }
+ virtual FX_INT32 GetLineCap() const
+ {
+ return m_iLineCap;
+ }
+ virtual void SetLineCap(FX_INT32 iLineCap)
+ {
+ m_iLineCap = iLineCap;
+ }
+ virtual FX_INT32 GetDashStyle() const
+ {
+ return m_iDashStyle;
+ }
+ virtual void SetDashStyle(FX_INT32 iDashStyle)
+ {
+ m_iDashStyle = iDashStyle;
+ }
+ virtual FX_FLOAT GetDashPhase() const
+ {
+ return m_fDashPhase;
+ }
+ virtual void SetDashPhase(FX_FLOAT fPhase)
+ {
+ m_fDashPhase = fPhase;
+ }
+ virtual FX_INT32 CountDashArray() const
+ {
+ return m_DashArray.GetSize();
+ }
+ virtual FX_INT32 GetDashArray(CFX_FloatArray &dashArray) const
+ {
+ dashArray.Copy(m_DashArray);
+ return dashArray.GetSize();
+ }
+ virtual void SetDashArray(const CFX_FloatArray &dashArray)
+ {
+ m_DashArray.Copy(dashArray);
+ }
+ virtual FX_INT32 GetLineJoin() const
+ {
+ return m_iLineJoin;
+ }
+ virtual void SetLineJoin(FX_INT32 iLineJoin)
+ {
+ m_iLineJoin = iLineJoin;
+ }
+ virtual FX_FLOAT GetMiterLimit() const
+ {
+ return m_fMiterLimit;
+ }
+ virtual void SetMiterLimit(FX_FLOAT fMiterLimit)
+ {
+ m_fMiterLimit = fMiterLimit;
+ }
+ virtual FX_INT32 CountCompoundPatterns() const
+ {
+ return m_CompoundPatterns.GetSize();
+ }
+ virtual FX_BOOL GetCompoundPatterns(CFDE_CompoundPatterns &compoundPatterns) const
+ {
+ return compoundPatterns.Copy(m_CompoundPatterns), TRUE;
+ }
+ virtual FX_BOOL SetCompoundPatterns(const CFDE_CompoundPatterns &compoundPatterns)
+ {
+ return m_CompoundPatterns.Copy(compoundPatterns), TRUE;
+ }
+
+ FX_ARGB m_Color;
+ FX_INT32 m_iLineCap;
+ FX_INT32 m_iLineJoin;
+ FX_INT32 m_iDashStyle;
+ FX_FLOAT m_fDashPhase;
+ FX_FLOAT m_fMiterLimit;
+ FX_BOOL m_bAutoRelease;
+ IFDE_Brush *m_pBrush;
+ CFX_FloatArray m_DashArray;
+ CFDE_CompoundPatterns m_CompoundPatterns;
+};
+class CFDE_SolidBrush : public IFDE_SolidBrush, public CFX_Target
+{
+public:
+ CFDE_SolidBrush() : m_Color(0xFF000000)
+ {
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_Solid;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual FX_ARGB GetColor() const
+ {
+ return m_Color;
+ }
+ virtual void SetColor(FX_ARGB color)
+ {
+ m_Color = color;
+ }
+
+ FX_ARGB m_Color;
+ CFX_Matrix m_Matrix;
+};
+class CFDE_HatchBrush : public IFDE_HatchBrush, public CFX_Target
+{
+public:
+ CFDE_HatchBrush() : m_iStyle(-1), m_BackColor(0), m_ForeColor(0)
+ {
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_Hatch;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual FX_ARGB GetColor(FX_BOOL bForegroundColor) const
+ {
+ return bForegroundColor ? m_ForeColor : m_BackColor;
+ }
+ virtual void SetColor(FX_ARGB color, FX_BOOL bForegroundColor)
+ {
+ if (bForegroundColor) {
+ m_ForeColor = color;
+ } else {
+ m_BackColor = color;
+ }
+ }
+
+ virtual FX_INT32 GetHatchStyle() const
+ {
+ return m_iStyle;
+ };
+ virtual FX_BOOL SetHatchStyle(FX_INT32 iHatchStyle)
+ {
+ m_iStyle = iHatchStyle;
+ return m_iStyle >= FDE_HATCHSTYLE_Min && m_iStyle <= FDE_HATCHSTYLE_Max;
+ }
+ FX_INT32 m_iStyle;
+ FX_ARGB m_BackColor;
+ FX_ARGB m_ForeColor;
+ CFX_Matrix m_Matrix;
+};
+class CFDE_TextureBrush : public IFDE_TextureBrush, public CFX_Target
+{
+public:
+ CFDE_TextureBrush()
+ : m_iWrap(0)
+ , m_pImage(NULL)
+ , m_bAutoRelease(FALSE)
+ {
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_Texture;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual IFDE_Image* GetImage() const
+ {
+ return m_pImage;
+ }
+ virtual void SetImage(IFDE_Image *pImage, FX_BOOL bAutoRelease)
+ {
+ m_pImage = pImage;
+ m_bAutoRelease = bAutoRelease;
+ }
+ virtual FX_INT32 GetWrapMode() const
+ {
+ return m_iWrap;
+ }
+ virtual void SetWrapMode(FX_INT32 iWrapMode)
+ {
+ m_iWrap = iWrapMode;
+ }
+ FX_INT32 m_iWrap;
+ IFDE_Image *m_pImage;
+ FX_BOOL m_bAutoRelease;
+ CFX_Matrix m_Matrix;
+};
+class CFDE_LinearBrush : public IFDE_LinearGradientBrush, public CFX_Target
+{
+public:
+ CFDE_LinearBrush() : m_EndColor(0), m_StartColor(0), m_iWrapMode(0)
+ {
+ m_StartPoint.x = m_StartPoint.y = m_EndPoint.x = m_EndPoint.y = 0;
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_LinearGradient;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual void GetLinearPoints(CFX_PointF &startingPoint, CFX_PointF &endingPoint) const
+ {
+ startingPoint = m_StartPoint;
+ endingPoint = m_EndPoint;
+ }
+ virtual void SetLinearPoints(const CFX_PointF &startingPoint, const CFX_PointF &endingPoint)
+ {
+ m_StartPoint = startingPoint;
+ m_EndPoint = endingPoint;
+ }
+ virtual void GetLinearColors(FX_ARGB &startingColor, FX_ARGB &endingColor) const
+ {
+ startingColor = m_StartColor;
+ endingColor = m_EndColor;
+ }
+ virtual void SetLinearColors(const FX_ARGB &startingColor, const FX_ARGB &endingColor)
+ {
+ m_StartColor = startingColor;
+ m_EndColor = endingColor;
+ }
+ virtual FX_INT32 CountGradientColors() const
+ {
+ return m_GradColors.GetSize();
+ }
+ virtual FX_BOOL GetGradientColors(CFDE_GradientColors &colors) const
+ {
+ return colors.Copy(m_GradColors), TRUE;
+ }
+ virtual FX_BOOL SetGradientColors(const CFDE_GradientColors &colors)
+ {
+ return m_GradColors.Copy(colors), TRUE;
+ }
+
+ virtual FX_INT32 GetWrapMode() const
+ {
+ return m_iWrapMode;
+ }
+ virtual void SetWrapMode(FX_INT32 iWrapMode)
+ {
+ m_iWrapMode = iWrapMode;
+ }
+ CFX_PointF m_EndPoint;
+ CFX_PointF m_StartPoint;
+ FX_ARGB m_EndColor;
+ FX_ARGB m_StartColor;
+ CFDE_GradientColors m_GradColors;
+ FX_INT32 m_iWrapMode;
+ CFX_Matrix m_Matrix;
+};
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_render.cpp b/xfa/src/fdp/src/fde/fde_render.cpp
new file mode 100644
index 0000000000..e8e9149e02
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_render.cpp
@@ -0,0 +1,253 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_render.h"
+void FDE_GetPageMatrix(CFX_Matrix &pageMatrix, const CFX_RectF &docPageRect, const CFX_Rect &devicePageRect, FX_INT32 iRotate, FX_DWORD dwCoordinatesType)
+{
+ FXSYS_assert(iRotate >= 0 && iRotate <= 3);
+ FX_BOOL bFlipX = (dwCoordinatesType & 0x01) != 0;
+ FX_BOOL bFlipY = (dwCoordinatesType & 0x02) != 0;
+ CFX_Matrix m;
+ m.Set((bFlipX ? -1.0f : 1.0f), 0, 0, (bFlipY ? -1.0f : 1.0f), 0, 0);
+ if (iRotate == 0 || iRotate == 2) {
+ m.a *= (FX_FLOAT)devicePageRect.width / docPageRect.width;
+ m.d *= (FX_FLOAT)devicePageRect.height / docPageRect.height;
+ } else {
+ m.a *= (FX_FLOAT)devicePageRect.height / docPageRect.width;
+ m.d *= (FX_FLOAT)devicePageRect.width / docPageRect.height;
+ }
+ m.Rotate(iRotate * 1.57079632675f);
+ switch (iRotate) {
+ case 0:
+ m.e = bFlipX ? (FX_FLOAT)devicePageRect.right() : (FX_FLOAT)devicePageRect.left;
+ m.f = bFlipY ? (FX_FLOAT)devicePageRect.bottom() : (FX_FLOAT)devicePageRect.top;
+ break;
+ case 1:
+ m.e = bFlipY ? (FX_FLOAT)devicePageRect.left : (FX_FLOAT)devicePageRect.right();
+ m.f = bFlipX ? (FX_FLOAT)devicePageRect.bottom() : (FX_FLOAT)devicePageRect.top;
+ break;
+ case 2:
+ m.e = bFlipX ? (FX_FLOAT)devicePageRect.left : (FX_FLOAT)devicePageRect.right();
+ m.f = bFlipY ? (FX_FLOAT)devicePageRect.top : (FX_FLOAT)devicePageRect.bottom();
+ break;
+ case 3:
+ m.e = bFlipY ? (FX_FLOAT)devicePageRect.right() : (FX_FLOAT)devicePageRect.left;
+ m.f = bFlipX ? (FX_FLOAT)devicePageRect.top : (FX_FLOAT)devicePageRect.bottom();
+ break;
+ default:
+ break;
+ }
+ pageMatrix = m;
+}
+IFDE_RenderContext* IFDE_RenderContext::Create()
+{
+ return FDE_New CFDE_RenderContext;
+}
+CFDE_RenderContext::CFDE_RenderContext()
+ : CFX_ThreadLock()
+ , m_eStatus(FDE_RENDERSTATUS_Reset)
+ , m_pRenderDevice(NULL)
+ , m_pSolidBrush(NULL)
+ , m_Transform()
+ , m_pCharPos(NULL)
+ , m_iCharPosCount(0)
+ , m_pIterator(NULL)
+{
+ m_Transform.Reset();
+}
+CFDE_RenderContext::~CFDE_RenderContext()
+{
+ StopRender();
+}
+FX_BOOL CFDE_RenderContext::StartRender(IFDE_RenderDevice *pRenderDevice, IFDE_CanvasSet *pCanvasSet, const CFX_Matrix &tmDoc2Device )
+{
+ if (m_pRenderDevice != NULL) {
+ return FALSE;
+ }
+ if (pRenderDevice == NULL) {
+ return FALSE;
+ }
+ if (pCanvasSet == NULL) {
+ return FALSE;
+ }
+ Lock();
+ m_eStatus = FDE_RENDERSTATUS_Paused;
+ m_pRenderDevice = pRenderDevice;
+ m_Transform = tmDoc2Device;
+ if (m_pIterator == NULL) {
+ m_pIterator = IFDE_VisualSetIterator::Create();
+ FXSYS_assert(m_pIterator != NULL);
+ }
+ FX_BOOL bAttach = m_pIterator->AttachCanvas(pCanvasSet) && m_pIterator->FilterObjects();
+ Unlock();
+ return bAttach;
+}
+FDE_RENDERSTATUS CFDE_RenderContext::DoRender(IFX_Pause *pPause)
+{
+ if (m_pRenderDevice == NULL) {
+ return FDE_RENDERSTATUS_Failed;
+ }
+ if (m_pIterator == NULL) {
+ return FDE_RENDERSTATUS_Failed;
+ }
+ Lock();
+ FDE_RENDERSTATUS eStatus = FDE_RENDERSTATUS_Paused;
+ CFX_Matrix rm;
+ rm.SetReverse(m_Transform);
+ CFX_RectF rtDocClip = m_pRenderDevice->GetClipRect();
+ if (rtDocClip.IsEmpty()) {
+ rtDocClip.left = rtDocClip.top = 0;
+ rtDocClip.width = (FX_FLOAT)m_pRenderDevice->GetWidth();
+ rtDocClip.height = (FX_FLOAT)m_pRenderDevice->GetHeight();
+ }
+ rm.TransformRect(rtDocClip);
+ IFDE_VisualSet *pVisualSet;
+ FDE_HVISUALOBJ hVisualObj;
+ CFX_RectF rtObj;
+ FX_INT32 iCount = 0;
+ while(TRUE) {
+ hVisualObj = m_pIterator->GetNext(pVisualSet);
+ if (hVisualObj == NULL || pVisualSet == NULL) {
+ eStatus = FDE_RENDERSTATUS_Done;
+ break;
+ }
+ rtObj.Empty();
+ pVisualSet->GetRect(hVisualObj, rtObj);
+ if (!rtDocClip.IntersectWith(rtObj)) {
+ continue;
+ }
+ switch (pVisualSet->GetType()) {
+ case FDE_VISUALOBJ_Text:
+ RenderText((IFDE_TextSet*)pVisualSet, hVisualObj);
+ iCount += 5;
+ break;
+ case FDE_VISUALOBJ_Path:
+ RenderPath((IFDE_PathSet*)pVisualSet, hVisualObj);
+ iCount += 20;
+ break;
+ case FDE_VISUALOBJ_Widget:
+ iCount += 10;
+ break;
+ case FDE_VISUALOBJ_Canvas:
+ FXSYS_assert(FALSE);
+ break;
+ default:
+ break;
+ }
+ if (iCount >= 100 && pPause != NULL && pPause->NeedToPauseNow()) {
+ eStatus = FDE_RENDERSTATUS_Paused;
+ break;
+ }
+ }
+ Unlock();
+ return m_eStatus = eStatus;
+}
+void CFDE_RenderContext::StopRender()
+{
+ Lock();
+ m_eStatus = FDE_RENDERSTATUS_Reset;
+ m_pRenderDevice = NULL;
+ m_Transform.Reset();
+ if (m_pIterator != NULL) {
+ m_pIterator->Release();
+ m_pIterator = NULL;
+ }
+ if (m_pSolidBrush != NULL) {
+ m_pSolidBrush->Release();
+ m_pSolidBrush = NULL;
+ }
+ if (m_pCharPos != NULL) {
+ FDE_Free(m_pCharPos);
+ m_pCharPos = NULL;
+ }
+ m_iCharPosCount = 0;
+ Unlock();
+}
+void CFDE_RenderContext::RenderText(IFDE_TextSet *pTextSet, FDE_HVISUALOBJ hText)
+{
+ FXSYS_assert(m_pRenderDevice != NULL);
+ FXSYS_assert(pTextSet != NULL && hText != NULL);
+ IFX_Font *pFont = pTextSet->GetFont(hText);
+ if (pFont == NULL) {
+ return;
+ }
+ FX_INT32 iCount = pTextSet->GetDisplayPos(hText, NULL, FALSE);
+ if (iCount < 1) {
+ return;
+ }
+ if (m_pSolidBrush == NULL) {
+ m_pSolidBrush = (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
+ if (m_pSolidBrush == NULL) {
+ return;
+ }
+ }
+ if (m_pCharPos == NULL) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Alloc(sizeof(FXTEXT_CHARPOS) * iCount);
+ } else if (m_iCharPosCount < iCount) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Realloc(m_pCharPos, sizeof(FXTEXT_CHARPOS) * iCount);
+ }
+ if (m_iCharPosCount < iCount) {
+ m_iCharPosCount = iCount;
+ }
+ iCount = pTextSet->GetDisplayPos(hText, m_pCharPos, FALSE);
+ FX_FLOAT fFontSize = pTextSet->GetFontSize(hText);
+ FX_ARGB dwColor = pTextSet->GetFontColor(hText);
+ m_pSolidBrush->SetColor(dwColor);
+ FDE_HDEVICESTATE hState;
+ FX_BOOL bClip = ApplyClip(pTextSet, hText, hState);
+ m_pRenderDevice->DrawString(m_pSolidBrush, pFont, m_pCharPos, iCount, fFontSize, &m_Transform);
+ if (bClip) {
+ RestoreClip(hState);
+ }
+}
+void CFDE_RenderContext::RenderPath(IFDE_PathSet *pPathSet, FDE_HVISUALOBJ hPath)
+{
+ FXSYS_assert(m_pRenderDevice != NULL);
+ FXSYS_assert(pPathSet != NULL && hPath != NULL);
+ IFDE_Path *pPath = pPathSet->GetPath(hPath);
+ if (pPath == NULL) {
+ return;
+ }
+ FDE_HDEVICESTATE hState;
+ FX_BOOL bClip = ApplyClip(pPathSet, hPath, hState);
+ FX_INT32 iRenderMode = pPathSet->GetRenderMode(hPath);
+ if (iRenderMode & FDE_PATHRENDER_Stroke) {
+ IFDE_Pen *pPen = pPathSet->GetPen(hPath);
+ FX_FLOAT fWidth = pPathSet->GetPenWidth(hPath);
+ if (pPen != NULL && fWidth > 0) {
+ m_pRenderDevice->DrawPath(pPen, fWidth, pPath, &m_Transform);
+ }
+ }
+ if (iRenderMode & FDE_PATHRENDER_Fill) {
+ IFDE_Brush *pBrush = pPathSet->GetBrush(hPath);
+ if (pBrush != NULL) {
+ m_pRenderDevice->FillPath(pBrush, pPath, &m_Transform);
+ }
+ }
+ if (bClip) {
+ RestoreClip(hState);
+ }
+}
+FX_BOOL CFDE_RenderContext::ApplyClip(IFDE_VisualSet *pVisualSet, FDE_HVISUALOBJ hObj, FDE_HDEVICESTATE &hState)
+{
+ CFX_RectF rtClip;
+ if (!pVisualSet->GetClip(hObj, rtClip)) {
+ return FALSE;
+ }
+ CFX_RectF rtObj;
+ pVisualSet->GetRect(hObj, rtObj);
+ rtClip.Offset(rtObj.left, rtObj.top);
+ m_Transform.TransformRect(rtClip);
+ const CFX_RectF &rtDevClip = m_pRenderDevice->GetClipRect();
+ rtClip.Intersect(rtDevClip);
+ hState = m_pRenderDevice->SaveState();
+ return m_pRenderDevice->SetClipRect(rtClip);
+}
+void CFDE_RenderContext::RestoreClip(FDE_HDEVICESTATE hState)
+{
+ m_pRenderDevice->RestoreState(hState);
+}
diff --git a/xfa/src/fdp/src/fde/fde_render.h b/xfa/src/fdp/src/fde/fde_render.h
new file mode 100644
index 0000000000..909987a032
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_render.h
@@ -0,0 +1,42 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_RENDER_IMP
+#define _FDE_RENDER_IMP
+class CFDE_RenderContext;
+class CFDE_RenderContext : public IFDE_RenderContext, public CFX_ThreadLock, public CFX_Target
+{
+public:
+ CFDE_RenderContext();
+ virtual ~CFDE_RenderContext();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_BOOL StartRender(IFDE_RenderDevice *pRenderDevice,
+ IFDE_CanvasSet *pCanvasSet,
+ const CFX_Matrix &tmDoc2Device
+ );
+ virtual FDE_RENDERSTATUS GetStatus() const
+ {
+ return m_eStatus;
+ }
+ virtual FDE_RENDERSTATUS DoRender(IFX_Pause *pPause = NULL);
+ virtual void StopRender();
+ void RenderPath(IFDE_PathSet *pPathSet, FDE_HVISUALOBJ hPath);
+ void RenderText(IFDE_TextSet *pTextSet, FDE_HVISUALOBJ hText);
+ FX_BOOL ApplyClip(IFDE_VisualSet *pVisualSet, FDE_HVISUALOBJ hObj, FDE_HDEVICESTATE &hState);
+ void RestoreClip(FDE_HDEVICESTATE hState);
+protected:
+ FDE_RENDERSTATUS m_eStatus;
+ IFDE_RenderDevice *m_pRenderDevice;
+ IFDE_SolidBrush *m_pSolidBrush;
+ CFX_Matrix m_Transform;
+ FXTEXT_CHARPOS *m_pCharPos;
+ FX_INT32 m_iCharPosCount;
+ IFDE_VisualSetIterator *m_pIterator;
+};
+#endif
diff --git a/xfa/src/fdp/src/tto/fde_textout.cpp b/xfa/src/fdp/src/tto/fde_textout.cpp
new file mode 100644
index 0000000000..e03620244f
--- /dev/null
+++ b/xfa/src/fdp/src/tto/fde_textout.cpp
@@ -0,0 +1,952 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_textout.h"
+IFDE_TextOut* IFDE_TextOut::Create()
+{
+ return FDE_New CFDE_TextOut;
+}
+CFDE_TextOut::CFDE_TextOut()
+ : m_pFont(NULL)
+ , m_fFontSize(12.0f)
+ , m_fLineSpace(m_fFontSize)
+ , m_fLinePos(0.0f)
+ , m_fTolerance(0.0f)
+ , m_iAlignment(0)
+ , m_iTxtBkAlignment(0)
+ , m_pCharWidths(NULL)
+ , m_iChars(0)
+ , m_pEllCharWidths(NULL)
+ , m_iEllChars(0)
+ , m_wParagraphBkChar(L'\n')
+ , m_TxtColor(0xFF000000)
+ , m_dwStyles(0)
+ , m_dwTxtBkStyles(0)
+ , m_bElliChanged(FALSE)
+ , m_iEllipsisWidth(0)
+ , m_ttoLines(5)
+ , m_iCurLine(0)
+ , m_iTotalLines(0)
+ , m_iCurPiece(0)
+ , m_pCharPos(NULL)
+ , m_iCharPosSize(0)
+ , m_pRenderDevice(NULL)
+{
+ m_pTxtBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None);
+ FXSYS_assert(m_pTxtBreak != NULL);
+ m_Matrix.Reset();
+ m_rtClip.Reset();
+ m_rtLogicClip.Reset();
+}
+CFDE_TextOut::~CFDE_TextOut()
+{
+ if (m_pTxtBreak != NULL) {
+ m_pTxtBreak->Release();
+ }
+ if (m_pCharWidths != NULL) {
+ FDE_Free(m_pCharWidths);
+ }
+ if (m_pEllCharWidths != NULL) {
+ FDE_Free(m_pEllCharWidths);
+ }
+ if (m_pRenderDevice != NULL) {
+ m_pRenderDevice->Release();
+ }
+ if (m_pCharPos != NULL) {
+ FDE_Free(m_pCharPos);
+ }
+ m_ttoLines.RemoveAll();
+}
+void CFDE_TextOut::SetFont(IFX_Font *pFont)
+{
+ FXSYS_assert(pFont != NULL);
+ m_pFont = pFont;
+ m_pTxtBreak->SetFont(pFont);
+}
+void CFDE_TextOut::SetFontSize(FX_FLOAT fFontSize)
+{
+ FXSYS_assert(fFontSize > 0);
+ m_fFontSize = fFontSize;
+ m_pTxtBreak->SetFontSize(fFontSize);
+}
+void CFDE_TextOut::SetTextColor(FX_ARGB color)
+{
+ m_TxtColor = color;
+}
+void CFDE_TextOut::SetStyles(FX_DWORD dwStyles)
+{
+ m_dwStyles = dwStyles;
+ m_dwTxtBkStyles = 0;
+ if (dwStyles & FDE_TTOSTYLE_SingleLine) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_SingleLine;
+ }
+ if (dwStyles & FDE_TTOSTYLE_ExpandTab) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ExpandTab;
+ }
+ if (dwStyles & FDE_TTOSTYLE_ArabicShapes) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ArabicShapes;
+ }
+ if (dwStyles & FDE_TTOSTYLE_RTL) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_RTLReadingOrder;
+ }
+ if (dwStyles & FDE_TTOSTYLE_ArabicContext) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ArabicContext;
+ }
+ if (dwStyles & FDE_TTOSTYLE_VerticalLayout) {
+ m_dwTxtBkStyles |= (FX_TXTLAYOUTSTYLE_VerticalChars | FX_TXTLAYOUTSTYLE_VerticalLayout);
+ }
+ m_pTxtBreak->SetLayoutStyles(m_dwTxtBkStyles);
+}
+void CFDE_TextOut::SetTabWidth(FX_FLOAT fTabWidth)
+{
+ FXSYS_assert(fTabWidth > 1.0f);
+ m_pTxtBreak->SetTabWidth(fTabWidth, FALSE);
+}
+void CFDE_TextOut::SetEllipsisString(const CFX_WideString &wsEllipsis)
+{
+ m_bElliChanged = TRUE;
+ m_wsEllipsis = wsEllipsis;
+}
+void CFDE_TextOut::SetParagraphBreakChar(FX_WCHAR wch)
+{
+ m_wParagraphBkChar = wch;
+ m_pTxtBreak->SetParagraphBreakChar(wch);
+}
+void CFDE_TextOut::SetAlignment(FX_INT32 iAlignment)
+{
+ m_iAlignment = iAlignment;
+ switch (m_iAlignment) {
+ case FDE_TTOALIGNMENT_TopCenter:
+ case FDE_TTOALIGNMENT_Center:
+ case FDE_TTOALIGNMENT_BottomCenter:
+ m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Center;
+ break;
+ case FDE_TTOALIGNMENT_TopRight:
+ case FDE_TTOALIGNMENT_CenterRight:
+ case FDE_TTOALIGNMENT_BottomRight:
+ m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Right;
+ break;
+ default:
+ m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Left;
+ break;
+ }
+ m_pTxtBreak->SetAlignment(m_iTxtBkAlignment);
+}
+void CFDE_TextOut::SetLineSpace(FX_FLOAT fLineSpace)
+{
+ FXSYS_assert(fLineSpace > 1.0f);
+ m_fLineSpace = fLineSpace;
+}
+void CFDE_TextOut::SetDIBitmap(CFX_DIBitmap *pDIB)
+{
+ FXSYS_assert(pDIB != NULL);
+ if (m_pRenderDevice != NULL) {
+ m_pRenderDevice->Release();
+ }
+ m_pRenderDevice = IFDE_RenderDevice::Create(pDIB);
+}
+void CFDE_TextOut::SetRenderDevice(CFX_RenderDevice *pDevice)
+{
+ FXSYS_assert(pDevice != NULL);
+ if (m_pRenderDevice != NULL) {
+ m_pRenderDevice->Release();
+ }
+ m_pRenderDevice = IFDE_RenderDevice::Create(pDevice);
+}
+void CFDE_TextOut::SetClipRect(const CFX_Rect &rtClip)
+{
+ m_rtClip.Set((FX_FLOAT)rtClip.left, (FX_FLOAT)rtClip.top, (FX_FLOAT)rtClip.Width(), (FX_FLOAT)rtClip.Height());
+}
+void CFDE_TextOut::SetClipRect(const CFX_RectF &rtClip)
+{
+ m_rtClip = rtClip;
+}
+void CFDE_TextOut::SetLogicClipRect(const CFX_RectF &rtClip)
+{
+ m_rtLogicClip = rtClip;
+}
+void CFDE_TextOut::SetMatrix(const CFX_Matrix &matrix)
+{
+ m_Matrix = matrix;
+}
+void CFDE_TextOut::SetLineBreakTolerance(FX_FLOAT fTolerance)
+{
+ m_fTolerance = fTolerance;
+ m_pTxtBreak->SetLineBreakTolerance(m_fTolerance);
+}
+FX_INT32 CFDE_TextOut::GetTotalLines()
+{
+ return m_iTotalLines;
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Size &size)
+{
+ CFX_RectF rtText;
+ rtText.Set(0.0f, 0.0f, (FX_FLOAT)size.x, (FX_FLOAT)size.y);
+ CalcSize(pwsStr, iLength, rtText);
+ size.x = (FX_INT32)rtText.Width();
+ size.y = (FX_INT32)rtText.Height();
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size)
+{
+ CFX_RectF rtText;
+ rtText.Set(0.0f, 0.0f, size.x, size.y);
+ CalcSize(pwsStr, iLength, rtText);
+ size.x = rtText.Width();
+ size.y = rtText.Height();
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Rect &rect)
+{
+ CFX_RectF rtText;
+ rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.Width(), (FX_FLOAT)rect.Height());
+ CalcSize(pwsStr, iLength, rtText);
+ rect.Set((FX_INT32)rtText.left, (FX_INT32)rtText.top, (FX_INT32)rtText.Width(), (FX_INT32)rtText.Height());
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect)
+{
+ if (pwsStr == NULL || iLength < 1) {
+ rect.width = 0.0f;
+ rect.height = 0.0f;
+ } else {
+ CFX_Matrix rm;
+ rm.SetReverse(m_Matrix);
+ rm.TransformRect(rect);
+ CalcTextSize(pwsStr, iLength, rect);
+ m_Matrix.TransformRect(rect);
+ }
+}
+void CFDE_TextOut::CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size)
+{
+ CFX_RectF rtText;
+ rtText.Set(0.0f, 0.0f, size.x, size.y);
+ CalcLogicSize(pwsStr, iLength, rtText);
+ size.x = rtText.Width();
+ size.y = rtText.Height();
+}
+void CFDE_TextOut::CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect)
+{
+ if (pwsStr == NULL || iLength < 1) {
+ rect.width = 0.0f;
+ rect.height = 0.0f;
+ } else {
+ CalcTextSize(pwsStr, iLength, rect);
+ }
+}
+void CFDE_TextOut::CalcTextSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect)
+{
+ FXSYS_assert(m_pFont != NULL && m_fFontSize >= 1.0f);
+ SetLineWidth(rect);
+ m_iTotalLines = 0;
+ FX_LPCWSTR pStr = pwsStr;
+ FX_BOOL bHotKey = (m_dwStyles & FDE_TTOSTYLE_HotKey) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_FLOAT fWidth = 0.0f;
+ FX_FLOAT fHeight = 0.0f;
+ FX_FLOAT fStartPos = bVertical ? rect.bottom() : rect.right();
+ FX_DWORD dwBreakStatus = 0;
+ FX_WCHAR wPreChar = 0;
+ FX_WCHAR wch;
+ FX_WCHAR wBreak = 0;
+ while (iLength-- > 0) {
+ wch = *pStr++;
+ if (wBreak == 0 && (wch == L'\n' || wch == L'\r')) {
+ wBreak = wch;
+ m_pTxtBreak->SetParagraphBreakChar(wch);
+ }
+ if (bHotKey && wch == L'&' && wPreChar != L'&') {
+ wPreChar = wch;
+ continue;
+ }
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);
+ }
+ wPreChar = 0;
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);
+ }
+ m_pTxtBreak->Reset();
+ FX_FLOAT fInc = rect.Height() - fHeight;
+ if (bVertical) {
+ fInc = rect.Width() - fHeight;
+ }
+ if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) {
+ fInc /= 2.0f;
+ } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) {
+ fInc = 0.0f;
+ }
+ if (bVertical) {
+ rect.top += fStartPos;
+ rect.left += fInc;
+ rect.width = fHeight;
+ rect.height = FX_MIN(fWidth, rect.Height());
+ } else {
+ rect.left += fStartPos;
+ rect.top += fInc;
+ rect.width = FX_MIN(fWidth, rect.Width());
+ rect.height = fHeight;
+ if (m_dwStyles & FDE_TTOSTYLE_LastLineHeight) {
+ rect.height -= m_fLineSpace - m_fFontSize;
+ }
+ }
+}
+void CFDE_TextOut::SetLineWidth(CFX_RectF &rect)
+{
+ if ((m_dwStyles & FDE_TTOSTYLE_SingleLine) == 0) {
+ FX_FLOAT fLineWidth = 0.0f;
+ if (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) {
+ if (rect.Height() < 1.0f) {
+ rect.height = m_fFontSize * 1000.0f;
+ }
+ fLineWidth = rect.Height();
+ } else {
+ if (rect.Width() < 1.0f) {
+ rect.width = m_fFontSize * 1000.0f;
+ }
+ fLineWidth = rect.Width();
+ }
+ m_pTxtBreak->SetLineWidth(fLineWidth);
+ }
+}
+FX_BOOL CFDE_TextOut::RetrieveLineWidth(FX_DWORD dwBreakStatus, FX_FLOAT &fStartPos, FX_FLOAT &fWidth, FX_FLOAT &fHeight)
+{
+ if (dwBreakStatus <= FX_TXTBREAK_PieceBreak) {
+ return FALSE;
+ }
+ FX_FLOAT fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
+ FX_BOOL bLineWrap = (m_dwStyles & FDE_TTOSTYLE_LineWrap) ? TRUE : FALSE;
+ FX_FLOAT fLineWidth = 0.0f;
+ FX_INT32 iCount = m_pTxtBreak->CountBreakPieces();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ const CFX_TxtPiece *pPiece = m_pTxtBreak->GetBreakPiece(i);
+ fLineWidth += (FX_FLOAT)pPiece->m_iWidth / 20000.0f;
+ fStartPos = FX_MIN(fStartPos, (FX_FLOAT)pPiece->m_iStartPos / 20000.0f);
+ }
+ m_pTxtBreak->ClearBreakPieces();
+ if (dwBreakStatus == FX_TXTBREAK_ParagraphBreak) {
+ m_pTxtBreak->Reset();
+ }
+ if (!bLineWrap && dwBreakStatus == FX_TXTBREAK_LineBreak) {
+ fWidth += fLineWidth;
+ } else {
+ fWidth = FX_MAX(fWidth, fLineWidth);
+ fHeight += fLineStep;
+ }
+ m_iTotalLines++;
+ return TRUE;
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_INT32 x, FX_INT32 y)
+{
+ CFX_RectF rtText;
+ rtText.Set((FX_FLOAT)x, (FX_FLOAT)y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
+ DrawText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y)
+{
+ CFX_RectF rtText;
+ rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
+ DrawText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_Rect &rect)
+{
+ CFX_RectF rtText;
+ rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.width, (FX_FLOAT)rect.height);
+ DrawText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect)
+{
+ CFX_RectF rtText;
+ rtText.Set(rect.left, rect.top, rect.width, rect.height);
+ CFX_Matrix rm;
+ rm.SetReverse(m_Matrix);
+ rm.TransformRect(rtText);
+ DrawText(pwsStr, iLength, rtText, m_rtClip);
+}
+void CFDE_TextOut::DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y)
+{
+ CFX_RectF rtText;
+ rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
+ DrawLogicText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect)
+{
+ CFX_RectF rtClip;
+ rtClip.Set(m_rtLogicClip.left, m_rtLogicClip.top, m_rtLogicClip.width, m_rtLogicClip.height);
+ m_Matrix.TransformRect(rtClip);
+ DrawText(pwsStr, iLength, rect, rtClip);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect, const CFX_RectF &rtClip)
+{
+ FXSYS_assert(m_pFont != NULL && m_fFontSize >= 1.0f);
+ if (pwsStr == NULL || iLength < 1) {
+ return;
+ }
+ if (rect.width < m_fFontSize || rect.height < m_fFontSize) {
+ return;
+ }
+ FX_FLOAT fLineWidth = rect.width;
+ if (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) {
+ fLineWidth = rect.height;
+ }
+ m_pTxtBreak->SetLineWidth(fLineWidth);
+ m_ttoLines.RemoveAll(TRUE);
+ m_wsText.Empty();
+ LoadText(pwsStr, iLength, rect);
+ if (m_dwStyles & FDE_TTOSTYLE_Ellipsis) {
+ ReplaceWidthEllipsis();
+ }
+ Reload(rect);
+ DoAlignment(rect);
+ OnDraw(rtClip);
+}
+void CFDE_TextOut::ExpandBuffer(FX_INT32 iSize, FX_INT32 iType)
+{
+ switch (iType) {
+ case 0:
+ if (m_pCharWidths == NULL) {
+ m_pCharWidths = (FX_INT32*)FDE_Alloc(iSize * sizeof(FX_INT32));
+ m_iChars = iSize;
+ } else if (m_iChars < iSize) {
+ m_pCharWidths = (FX_INT32*)FDE_Realloc(m_pCharWidths, iSize * sizeof(FX_INT32));
+ m_iChars = iSize;
+ }
+ FXSYS_memset(m_pCharWidths, 0, iSize);
+ break;
+ case 1:
+ if (m_pEllCharWidths == NULL) {
+ m_pEllCharWidths = (FX_INT32*)FDE_Alloc(iSize * sizeof(FX_INT32));
+ m_iEllChars = iSize;
+ } else if (m_iEllChars < iSize) {
+ m_pEllCharWidths = (FX_INT32*)FDE_Realloc(m_pEllCharWidths, iSize * sizeof(FX_INT32));
+ m_iEllChars = iSize;
+ }
+ FXSYS_memset(m_pEllCharWidths, 0, iSize);
+ break;
+ case 2:
+ if (m_pCharPos == NULL) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Alloc(iSize * sizeof(FXTEXT_CHARPOS));
+ m_iCharPosSize = iSize;
+ } else if (m_iCharPosSize < iSize) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Realloc(m_pCharPos, iSize * sizeof(FXTEXT_CHARPOS));
+ m_iCharPosSize = iSize;
+ }
+ break;
+ }
+}
+void CFDE_TextOut::LoadEllipsis()
+{
+ if (!m_bElliChanged) {
+ return;
+ }
+ m_bElliChanged = FALSE;
+ m_iEllipsisWidth = 0;
+ FX_INT32 iLength = m_wsEllipsis.GetLength();
+ if (iLength < 1) {
+ return;
+ }
+ ExpandBuffer(iLength, 1);
+ FX_LPCWSTR pStr = (FX_LPCWSTR)m_wsEllipsis;
+ FX_INT32 *pCharWidths = m_pEllCharWidths;
+ FX_DWORD dwBreakStatus;
+ FX_WCHAR wch;
+ while (iLength-- > 0) {
+ wch = *pStr++;
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveEllPieces(pCharWidths);
+ }
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveEllPieces(pCharWidths);
+ }
+ m_pTxtBreak->Reset();
+}
+void CFDE_TextOut::RetrieveEllPieces(FX_INT32 *&pCharWidths)
+{
+ FX_INT32 iCount = m_pTxtBreak->CountBreakPieces();
+ CFX_Char *pTC;
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ const CFX_TxtPiece *pPiece = m_pTxtBreak->GetBreakPiece(i);
+ FX_INT32 iPieceChars = pPiece->GetLength();
+ for (FX_INT32 j = 0; j < iPieceChars; j++) {
+ pTC = pPiece->GetCharPtr(j);
+ if (pTC->m_iCharWidth <= 0) {
+ *pCharWidths = 0;
+ } else {
+ *pCharWidths = pTC->m_iCharWidth;
+ }
+ m_iEllipsisWidth += *pCharWidths;
+ pCharWidths++;
+ }
+ }
+ m_pTxtBreak->ClearBreakPieces();
+}
+void CFDE_TextOut::LoadText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect)
+{
+ FX_LPWSTR pStr = m_wsText.GetBuffer(iLength);
+ FX_INT32 iTxtLength = iLength;
+ ExpandBuffer(iTxtLength, 0);
+ FX_BOOL bHotKey = (m_dwStyles & FDE_TTOSTYLE_HotKey) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_BOOL bLineWrap = (m_dwStyles & FDE_TTOSTYLE_LineWrap) ? TRUE : FALSE;
+ FX_FLOAT fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
+ FX_FLOAT fLineStop = bVertical ? rect.left : rect.bottom();
+ m_fLinePos = bVertical ? rect.right() : rect.top;
+ if (bVertical) {
+ fLineStep = -fLineStep;
+ }
+ m_hotKeys.RemoveAll();
+ FX_INT32 iStartChar = 0;
+ FX_INT32 iChars = 0;
+ FX_INT32 iPieceWidths = 0;
+ FX_DWORD dwBreakStatus;
+ FX_WCHAR wch;
+ FX_BOOL bRet = FALSE;
+ while (iTxtLength-- > 0) {
+ wch = *pwsStr++;
+ if (wch == L'&' && bHotKey && (pStr - 1) != NULL && *(pStr - 1) != L'&') {
+ if (iTxtLength > 0) {
+ m_hotKeys.Add(iChars);
+ }
+ continue;
+ }
+ *pStr++ = wch;
+ iChars++;
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ FX_BOOL bEndofLine = RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, FALSE, rect);
+ if (bEndofLine && (bLineWrap || (dwBreakStatus > FX_TXTBREAK_LineBreak && !bLineWrap))) {
+ iPieceWidths = 0;
+ m_iCurLine++;
+ m_fLinePos += fLineStep;
+ }
+ if ((bVertical && m_fLinePos + fLineStep < fLineStop) || (!bVertical && m_fLinePos + fLineStep > fLineStop)) {
+ FX_INT32 iCurLine = m_iCurLine;
+ if (bEndofLine) {
+ iCurLine--;
+ }
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(iCurLine);
+ pLine->m_bNewReload = TRUE;
+ bRet = TRUE;
+ break;
+ }
+ }
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak && !bRet) {
+ RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, FALSE, rect);
+ }
+ m_pTxtBreak->ClearBreakPieces();
+ m_pTxtBreak->Reset();
+ m_wsText.ReleaseBuffer(iLength);
+}
+FX_BOOL CFDE_TextOut::RetriecePieces(FX_DWORD dwBreakStatus, FX_INT32 &iStartChar, FX_INT32 &iPieceWidths, FX_BOOL bReload,
+ const CFX_RectF &rect)
+{
+ FX_BOOL bSingleLine = (m_dwStyles & FDE_TTOSTYLE_SingleLine) ? TRUE : FALSE;
+ FX_BOOL bLineWrap = (m_dwStyles & FDE_TTOSTYLE_LineWrap) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_FLOAT fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
+ if (bVertical) {
+ fLineStep = -fLineStep;
+ }
+ CFX_Char *pTC = NULL;
+ FX_BOOL bNeedReload = FALSE;
+ FX_FLOAT fLineWidth = bVertical ? rect.Height() : rect.Width();
+ FX_INT32 iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
+ FX_INT32 iCount = m_pTxtBreak->CountBreakPieces();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ const CFX_TxtPiece *pPiece = m_pTxtBreak->GetBreakPiece(i);
+ FX_INT32 iPieceChars = pPiece->GetLength();
+ FX_INT32 iChar = iStartChar;
+ FX_INT32 iWidth = 0;
+ FX_INT32 j = 0;
+ for (; j < iPieceChars; j++) {
+ pTC = pPiece->GetCharPtr(j);
+ FX_INT32 iCurCharWidth = pTC->m_iCharWidth > 0 ? pTC->m_iCharWidth : 0;
+ if (bSingleLine || !bLineWrap) {
+ if (iLineWidth - iPieceWidths - iWidth < iCurCharWidth) {
+ bNeedReload = TRUE;
+ break;
+ }
+ }
+ iWidth += iCurCharWidth;
+ m_pCharWidths[iChar++] = iCurCharWidth;
+ }
+ if (j == 0 && !bReload) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(m_iCurLine);
+ pLine->m_bNewReload = TRUE;
+ } else if (j > 0) {
+ CFX_RectF rtPiece;
+ if (bVertical) {
+ rtPiece.left = m_fLinePos;
+ rtPiece.top = rect.top + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
+ rtPiece.width = fLineStep;
+ rtPiece.height = iWidth / 20000.0f;
+ } else {
+ rtPiece.left = rect.left + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
+ rtPiece.top = m_fLinePos;
+ rtPiece.width = iWidth / 20000.0f;
+ rtPiece.height = fLineStep;
+ }
+ FDE_TTOPIECE ttoPiece;
+ ttoPiece.iStartChar = iStartChar;
+ ttoPiece.iChars = j;
+ ttoPiece.rtPiece = rtPiece;
+ ttoPiece.dwCharStyles = pPiece->m_dwCharStyles;
+ if (FX_IsOdd(pPiece->m_iBidiLevel)) {
+ ttoPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;
+ }
+ AppendPiece(ttoPiece, bNeedReload, (bReload && i == iCount - 1));
+ }
+ iStartChar += iPieceChars;
+ iPieceWidths += iWidth;
+ }
+ m_pTxtBreak->ClearBreakPieces();
+ FX_BOOL bRet = bSingleLine || bLineWrap || (!bLineWrap && bNeedReload) || dwBreakStatus == FX_TXTBREAK_ParagraphBreak;
+ return bRet;
+}
+void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE &ttoPiece, FX_BOOL bNeedReload, FX_BOOL bEnd)
+{
+ if (m_iCurLine >= m_ttoLines.GetSize()) {
+ CFDE_TTOLine ttoLine;
+ ttoLine.m_bNewReload = bNeedReload;
+ m_iCurPiece = ttoLine.AddPiece(m_iCurPiece, ttoPiece);
+ m_iCurLine = m_ttoLines.Add(ttoLine);
+ } else {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(m_iCurLine);
+ pLine->m_bNewReload = bNeedReload;
+ m_iCurPiece = pLine->AddPiece(m_iCurPiece, ttoPiece);
+ if (bEnd) {
+ FX_INT32 iPieces = pLine->GetSize();
+ if (m_iCurPiece < iPieces) {
+ pLine->RemoveLast(iPieces - m_iCurPiece - 1);
+ }
+ }
+ }
+ if (!bEnd && bNeedReload) {
+ m_iCurPiece = 0;
+ }
+}
+void CFDE_TextOut::ReplaceWidthEllipsis()
+{
+ LoadEllipsis();
+ FX_INT32 iLength = m_wsEllipsis.GetLength();
+ if (iLength < 1) {
+ return;
+ }
+ FX_INT32 iLines = m_ttoLines.GetSize();
+ for (FX_INT32 i = 0; i < iLines; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ if (!pLine->m_bNewReload) {
+ continue;
+ }
+ FX_INT32 iEllipsisCharIndex = iLength - 1;
+ FX_INT32 iCharWidth = 0;
+ FX_INT32 iCharCount = 0;
+ FX_INT32 iPiece = pLine->GetSize();
+ while (iPiece-- > 0) {
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(iPiece);
+ if (pPiece == NULL) {
+ break;
+ }
+ for (FX_INT32 j = pPiece->iChars - 1; j >= 0; j--) {
+ if (iEllipsisCharIndex < 0) {
+ break;
+ }
+ FX_INT32 index = pPiece->iStartChar + j;
+ iCharWidth += m_pCharWidths[index];
+ iCharCount++;
+ if (iCharCount <= iLength) {
+ m_wsText.SetAt(index, m_wsEllipsis.GetAt(iEllipsisCharIndex));
+ m_pCharWidths[index] = m_pEllCharWidths[iEllipsisCharIndex];
+ } else if (iCharWidth <= m_iEllipsisWidth) {
+ m_wsText.SetAt(index, 0);
+ m_pCharWidths[index] = 0;
+ }
+ iEllipsisCharIndex--;
+ }
+ if (iEllipsisCharIndex < 0) {
+ break;
+ }
+ }
+ }
+}
+void CFDE_TextOut::Reload(const CFX_RectF &rect)
+{
+ FX_INT32 iCount = m_ttoLines.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ if (pLine == NULL || !pLine->m_bNewReload) {
+ continue;
+ }
+ m_iCurLine = i;
+ m_iCurPiece = 0;
+ ReloadLinePiece(pLine, rect);
+ }
+}
+void CFDE_TextOut::ReloadLinePiece(CFDE_TTOLine *pLine, const CFX_RectF &rect)
+{
+ FX_LPCWSTR pwsStr = (FX_LPCWSTR)m_wsText;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_INT32 iPieceWidths = 0;
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(0);
+ FX_INT32 iStartChar = pPiece->iStartChar;
+ m_fLinePos = bVertical ? pPiece->rtPiece.left : pPiece->rtPiece.top;
+ FX_INT32 iPieceCount = pLine->GetSize();
+ FX_INT32 iPieceIndex = 0;
+ FX_DWORD dwBreakStatus = 0;
+ FX_WCHAR wch;
+ while (iPieceIndex < iPieceCount) {
+ FX_INT32 iStar = iStartChar;
+ FX_INT32 iEnd = pPiece->iChars + iStar;
+ while (iStar < iEnd) {
+ wch = *(pwsStr + iStar);
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, TRUE, rect);
+ }
+ iStar++;
+ }
+ iPieceIndex++;
+ pPiece = pLine->GetPtrAt(iPieceIndex);
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, TRUE, rect);
+ }
+ m_pTxtBreak->Reset();
+}
+void CFDE_TextOut::DoAlignment(const CFX_RectF &rect)
+{
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_FLOAT fLineStopS = bVertical ? rect.right() : rect.bottom();
+ FX_INT32 iLines = m_ttoLines.GetSize();
+ if (iLines < 1) {
+ return;
+ }
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(iLines - 1);
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(0);
+ if (pPiece == NULL) {
+ return;
+ }
+ FX_FLOAT fLineStopD = bVertical ? pPiece->rtPiece.right() : pPiece->rtPiece.bottom();
+ FX_FLOAT fInc = fLineStopS - fLineStopD;
+ if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) {
+ fInc /= 2.0f;
+ } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) {
+ fInc = 0.0f;
+ }
+ if (fInc < 1.0f) {
+ return;
+ }
+ for (FX_INT32 i = 0; i < iLines; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ FX_INT32 iPieces = pLine->GetSize();
+ for (FX_INT32 j = 0; j < iPieces; j++) {
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(j);
+ if (bVertical) {
+ pPiece->rtPiece.left += fInc;
+ } else {
+ pPiece->rtPiece.top += fInc;
+ }
+ }
+ }
+}
+void CFDE_TextOut::OnDraw(const CFX_RectF &rtClip)
+{
+ if (m_pRenderDevice == NULL) {
+ return;
+ }
+ FX_INT32 iLines = m_ttoLines.GetSize();
+ if (iLines < 1) {
+ return;
+ }
+ IFDE_SolidBrush *pBrush = (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
+ pBrush->SetColor(m_TxtColor);
+ IFDE_Pen *pPen = NULL;
+ FDE_HDEVICESTATE hDev = m_pRenderDevice->SaveState();
+ if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) {
+ m_pRenderDevice->SetClipRect(rtClip);
+ }
+ for (FX_INT32 i = 0; i < iLines; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ FX_INT32 iPieces = pLine->GetSize();
+ for (FX_INT32 j = 0; j < iPieces; j++) {
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(j);
+ if (pPiece == NULL) {
+ continue;
+ }
+ FX_INT32 iCount = GetDisplayPos(pPiece);
+ if (iCount > 0) {
+ m_pRenderDevice->DrawString(pBrush, m_pFont, m_pCharPos, iCount, m_fFontSize, &m_Matrix);
+ }
+ DrawLine(pPiece, pPen);
+ }
+ }
+ m_pRenderDevice->RestoreState(hDev);
+ if (pBrush) {
+ pBrush->Release();
+ }
+ if (pPen) {
+ pPen->Release();
+ }
+}
+FX_INT32 CFDE_TextOut::GetDisplayPos(FDE_LPTTOPIECE pPiece)
+{
+ FX_TXTRUN tr;
+ ToTextRun(pPiece, tr);
+ ExpandBuffer(tr.iLength, 2);
+ return m_pTxtBreak->GetDisplayPos(&tr, m_pCharPos);
+}
+FX_INT32 CFDE_TextOut::GetCharRects(FDE_LPTTOPIECE pPiece)
+{
+ FX_TXTRUN tr;
+ ToTextRun(pPiece, tr);
+ m_rectArray.RemoveAll();
+ return m_pTxtBreak->GetCharRects(&tr, m_rectArray);
+}
+void CFDE_TextOut::ToTextRun(const FDE_LPTTOPIECE pPiece, FX_TXTRUN &tr)
+{
+ tr.pAccess = NULL;
+ tr.pIdentity = NULL;
+ tr.pStr = (FX_LPCWSTR)m_wsText + pPiece->iStartChar;
+ tr.pWidths = m_pCharWidths + pPiece->iStartChar;
+ tr.iLength = pPiece->iChars;
+ tr.pFont = m_pFont;
+ tr.fFontSize = m_fFontSize;
+ tr.dwStyles = m_dwTxtBkStyles;
+ tr.iCharRotation = 0;
+ tr.dwCharStyles = pPiece->dwCharStyles;
+ tr.wLineBreakChar = m_wParagraphBkChar;
+ tr.pRect = &pPiece->rtPiece;
+}
+void CFDE_TextOut::DrawLine(const FDE_LPTTOPIECE pPiece, IFDE_Pen *&pPen)
+{
+ FX_BOOL bUnderLine = (m_dwStyles & FDE_TTOSTYLE_Underline) ? TRUE : FALSE;
+ FX_BOOL bStrikeOut = (m_dwStyles & FDE_TTOSTYLE_Strikeout) ? TRUE : FALSE;
+ FX_BOOL bHotKey = (m_dwStyles & FDE_TTOSTYLE_HotKey) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ if (!bUnderLine && !bStrikeOut && !bHotKey) {
+ return;
+ }
+ if (pPen == NULL) {
+ pPen = IFDE_Pen::Create();
+ pPen->SetColor(m_TxtColor);
+ }
+ IFDE_Path *pPath = IFDE_Path::Create();
+ FX_INT32 iLineCount = 0;
+ CFX_RectF rtText = pPiece->rtPiece;
+ CFX_PointF pt1, pt2;
+ if (bUnderLine) {
+ if (bVertical) {
+ pt1.x = rtText.left;
+ pt1.y = rtText.top;
+ pt2.x = rtText.left;
+ pt2.y = rtText.bottom();
+ } else {
+ pt1.x = rtText.left;
+ pt1.y = rtText.bottom();
+ pt2.x = rtText.right();
+ pt2.y = rtText.bottom();
+ }
+ pPath->AddLine(pt1, pt2);
+ iLineCount++;
+ }
+ if (bStrikeOut) {
+ if (bVertical) {
+ pt1.x = rtText.left + rtText.width * 2.0f / 5.0f;
+ pt1.y = rtText.top;;
+ pt2.x = pt1.x;
+ pt2.y = rtText.bottom();
+ } else {
+ pt1.x = rtText.left;
+ pt1.y = rtText.bottom() - rtText.height * 2.0f / 5.0f;
+ pt2.x = rtText.right();
+ pt2.y = pt1.y;
+ }
+ pPath->AddLine(pt1, pt2);
+ iLineCount++;
+ }
+ if (bHotKey) {
+ FX_INT32 iHotKeys = m_hotKeys.GetSize();
+ FX_INT32 iCount = GetCharRects(pPiece);
+ if (iCount > 0) {
+ for (FX_INT32 i = 0; i < iHotKeys; i++) {
+ FX_INT32 iCharIndex = m_hotKeys.GetAt(i);
+ if (iCharIndex >= pPiece->iStartChar && iCharIndex < pPiece->iStartChar + pPiece->iChars) {
+ CFX_RectF rect = m_rectArray.GetAt(iCharIndex - pPiece->iStartChar);
+ if (bVertical) {
+ pt1.x = rect.left;
+ pt1.y = rect.top;
+ pt2.x = rect.left;
+ pt2.y = rect.bottom();
+ } else {
+ pt1.x = rect.left;
+ pt1.y = rect.bottom();
+ pt2.x = rect.right();
+ pt2.y = rect.bottom();
+ }
+ pPath->AddLine(pt1, pt2);
+ iLineCount++;
+ }
+ }
+ }
+ }
+ if (iLineCount > 0) {
+ m_pRenderDevice->DrawPath(pPen, 1, pPath, &m_Matrix);
+ }
+ pPath->Release();
+}
+CFDE_TTOLine::CFDE_TTOLine()
+ : m_bNewReload(FALSE)
+ , m_pieces(5)
+ , m_iPieceCount(0)
+{
+}
+CFDE_TTOLine::CFDE_TTOLine(const CFDE_TTOLine &ttoLine)
+ : m_pieces(5)
+{
+ m_bNewReload = ttoLine.m_bNewReload;
+ m_iPieceCount = ttoLine.m_iPieceCount;
+ m_pieces.Copy(ttoLine.m_pieces);
+}
+CFDE_TTOLine::~CFDE_TTOLine()
+{
+}
+FX_INT32 CFDE_TTOLine::AddPiece(FX_INT32 index, const FDE_TTOPIECE &ttoPiece)
+{
+ if (index >= m_iPieceCount) {
+ index = m_pieces.Add(ttoPiece) + 1;
+ m_iPieceCount++;
+ } else {
+ FDE_TTOPIECE &piece = m_pieces.GetAt(index);
+ piece = ttoPiece;
+ }
+ return index;
+}
+FX_INT32 CFDE_TTOLine::GetSize() const
+{
+ return m_iPieceCount;
+}
+FDE_LPTTOPIECE CFDE_TTOLine::GetPtrAt(FX_INT32 index)
+{
+ if (index >= m_iPieceCount) {
+ return NULL;
+ }
+ return m_pieces.GetPtrAt(index);
+}
+void CFDE_TTOLine::RemoveLast(FX_INT32 iCount)
+{
+ m_pieces.RemoveLast(iCount);
+}
+void CFDE_TTOLine::RemoveAll(FX_BOOL bLeaveMemory)
+{
+ m_pieces.RemoveAll(bLeaveMemory);
+}
diff --git a/xfa/src/fdp/src/tto/fde_textout.h b/xfa/src/fdp/src/tto/fde_textout.h
new file mode 100644
index 0000000000..116ad89d5d
--- /dev/null
+++ b/xfa/src/fdp/src/tto/fde_textout.h
@@ -0,0 +1,132 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TEXTOUT_IMP
+#define _FDE_TEXTOUT_IMP
+struct FDE_TTOPIECE {
+public:
+ FX_INT32 iStartChar;
+ FX_INT32 iChars;
+ FX_DWORD dwCharStyles;
+ CFX_RectF rtPiece;
+};
+typedef FDE_TTOPIECE * FDE_LPTTOPIECE;
+typedef CFX_MassArrayTemplate<FDE_TTOPIECE> CFDE_TTOPieceArray;
+class CFDE_TTOLine : public CFX_Target
+{
+public:
+ CFDE_TTOLine();
+ CFDE_TTOLine(const CFDE_TTOLine &ttoLine);
+ ~CFDE_TTOLine();
+ FX_INT32 AddPiece(FX_INT32 index, const FDE_TTOPIECE &ttoPiece);
+ FX_INT32 GetSize() const;
+ FDE_LPTTOPIECE GetPtrAt(FX_INT32 index);
+ void RemoveLast(FX_INT32 iCount);
+ void RemoveAll(FX_BOOL bLeaveMemory);
+ FX_BOOL m_bNewReload;
+ CFDE_TTOPieceArray m_pieces;
+protected:
+ FX_INT32 m_iPieceCount;
+};
+typedef CFX_ObjectMassArrayTemplate<CFDE_TTOLine> CFDE_TTOLineArray;
+class CFDE_TextOut : public IFDE_TextOut, public CFX_Target
+{
+public:
+ CFDE_TextOut();
+ ~CFDE_TextOut();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual void SetFont(IFX_Font *pFont);
+ virtual void SetFontSize(FX_FLOAT fFontSize);
+ virtual void SetTextColor(FX_ARGB color);
+ virtual void SetStyles(FX_DWORD dwStyles);
+ virtual void SetTabWidth(FX_FLOAT fTabWidth);
+ virtual void SetEllipsisString(const CFX_WideString &wsEllipsis);
+ virtual void SetParagraphBreakChar(FX_WCHAR wch);
+ virtual void SetAlignment(FX_INT32 iAlignment);
+ virtual void SetLineSpace(FX_FLOAT fLineSpace);
+ virtual void SetDIBitmap(CFX_DIBitmap *pDIB);
+ virtual void SetRenderDevice(CFX_RenderDevice *pDevice);
+ virtual void SetClipRect(const CFX_Rect &rtClip);
+ virtual void SetClipRect(const CFX_RectF &rtClip);
+ virtual void SetMatrix(const CFX_Matrix &matrix);
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Size &size);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Rect &rect);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect);
+
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_INT32 x, FX_INT32 y);
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y);
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_Rect &rect);
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect);
+
+ virtual void SetLogicClipRect(const CFX_RectF &rtClip);
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size);
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect);
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y);
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect);
+ virtual FX_INT32 GetTotalLines();
+protected:
+ void CalcTextSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect);
+ FX_BOOL RetrieveLineWidth(FX_DWORD dwBreakStatus, FX_FLOAT &fStartPos, FX_FLOAT &fWidth, FX_FLOAT &fHeight);
+ void SetLineWidth(CFX_RectF &rect);
+ void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect, const CFX_RectF &rtClip);
+ void LoadText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect);
+ void LoadEllipsis();
+ void ExpandBuffer(FX_INT32 iSize, FX_INT32 iType);
+ void RetrieveEllPieces(FX_INT32 *&pCharWidths);
+
+ void Reload(const CFX_RectF &rect);
+ void ReloadLinePiece(CFDE_TTOLine *pLine, const CFX_RectF &rect);
+ FX_BOOL RetriecePieces(FX_DWORD dwBreakStatus, FX_INT32 &iStartChar, FX_INT32 &iPieceWidths, FX_BOOL bReload, const CFX_RectF &rect);
+ void AppendPiece(const FDE_TTOPIECE &ttoPiece, FX_BOOL bNeedReload, FX_BOOL bEnd);
+ void ReplaceWidthEllipsis();
+ void DoAlignment(const CFX_RectF &rect);
+ void OnDraw(const CFX_RectF &rtClip);
+ FX_INT32 GetDisplayPos(FDE_LPTTOPIECE pPiece);
+ FX_INT32 GetCharRects(FDE_LPTTOPIECE pPiece);
+
+ void ToTextRun(const FDE_LPTTOPIECE pPiece, FX_TXTRUN &tr);
+ void DrawLine(const FDE_LPTTOPIECE pPiece, IFDE_Pen *&pPen);
+
+ IFX_TxtBreak *m_pTxtBreak;
+ IFX_Font *m_pFont;
+ FX_FLOAT m_fFontSize;
+ FX_FLOAT m_fLineSpace;
+ FX_FLOAT m_fLinePos;
+ FX_FLOAT m_fTolerance;
+
+ FX_INT32 m_iAlignment;
+ FX_INT32 m_iTxtBkAlignment;
+ FX_INT32 *m_pCharWidths;
+ FX_INT32 m_iChars;
+ FX_INT32 *m_pEllCharWidths;
+ FX_INT32 m_iEllChars;
+ FX_WCHAR m_wParagraphBkChar;
+ FX_ARGB m_TxtColor;
+ FX_DWORD m_dwStyles;
+ FX_DWORD m_dwTxtBkStyles;
+ CFX_WideString m_wsEllipsis;
+ FX_BOOL m_bElliChanged;
+ FX_INT32 m_iEllipsisWidth;
+ CFX_WideString m_wsText;
+ CFX_RectF m_rtClip;
+ CFX_RectF m_rtLogicClip;
+ CFX_Matrix m_Matrix;
+ CFDE_TTOLineArray m_ttoLines;
+ FX_INT32 m_iCurLine;
+ FX_INT32 m_iCurPiece;
+ FX_INT32 m_iTotalLines;
+ FXTEXT_CHARPOS *m_pCharPos;
+ FX_INT32 m_iCharPosSize;
+ IFDE_RenderDevice *m_pRenderDevice;
+ CFX_Int32Array m_hotKeys;
+ CFX_RectFArray m_rectArray;
+};
+#endif
diff --git a/xfa/src/fdp/src/xml/fde_xml.cpp b/xfa/src/fdp/src/xml/fde_xml.cpp
new file mode 100644
index 0000000000..3ee4b4028c
--- /dev/null
+++ b/xfa/src/fdp/src/xml/fde_xml.cpp
@@ -0,0 +1,2712 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_xml.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define FDE_XMLVALIDCHARRANGENUM 5
+static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = {{0x09, 0x09}, {0x0A, 0x0A}, {0x0D, 0x0D}, {0x20, 0xD7FF}, {0xE000, 0xFFFD}};
+FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch)
+{
+ FX_INT32 iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid;
+ while (iStart <= iEnd) {
+ iMid = (iStart + iEnd) / 2;
+ if (ch < g_XMLValidCharRange[iMid][0]) {
+ iEnd = iMid - 1;
+ } else if (ch > g_XMLValidCharRange[iMid][1]) {
+ iStart = iMid + 1;
+ } else {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch)
+{
+ return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09;
+}
+typedef struct _FDE_XMLNAMECHAR {
+ FX_WCHAR wStart;
+ FX_WCHAR wEnd;
+ FX_BOOL bStartChar;
+} FDE_XMLNAMECHAR;
+#define FDE_XMLNAMECHARSNUM 20
+static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = {
+ {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, {L'A', L'Z', TRUE},
+ {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE},
+ {0xD8, 0xF6, TRUE}, {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE},
+ {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, {0x2070, 0x218F, TRUE},
+ {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE},
+};
+FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar)
+{
+ FX_INT32 iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid;
+ while (iStart <= iEnd) {
+ iMid = (iStart + iEnd) / 2;
+ if (ch < g_XMLNameChars[iMid].wStart) {
+ iEnd = iMid - 1;
+ } else if (ch > g_XMLNameChars[iMid].wEnd) {
+ iStart = iMid + 1;
+ } else {
+ if (bFirstChar) {
+ return g_XMLNameChars[iMid].bStartChar;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+#ifdef __cplusplus
+}
+#endif
+CFDE_XMLNode::CFDE_XMLNode()
+ : m_pParent(NULL)
+ , m_pChild(NULL)
+ , m_pPrior(NULL)
+ , m_pNext(NULL)
+{
+}
+CFDE_XMLNode::~CFDE_XMLNode()
+{
+ DeleteChildren();
+}
+void CFDE_XMLNode::DeleteChildren()
+{
+ CFDE_XMLNode *pChild = m_pChild, *pTemp;
+ while (pChild != NULL) {
+ pTemp = pChild->m_pNext;
+ pChild->Release();
+ pChild = pTemp;
+ }
+ m_pChild = NULL;
+}
+FX_INT32 CFDE_XMLNode::CountChildNodes() const
+{
+ FX_INT32 iCount = 0;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ iCount ++;
+ pChild = pChild->m_pNext;
+ }
+ return iCount;
+}
+CFDE_XMLNode* CFDE_XMLNode::GetChildNode(FX_INT32 index) const
+{
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ if (index == 0) {
+ return pChild;
+ }
+ index --;
+ pChild = pChild->m_pNext;
+ }
+ return NULL;
+}
+FX_INT32 CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode *pNode) const
+{
+ FX_INT32 index = 0;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ if (pChild == pNode) {
+ return index;
+ }
+ index ++;
+ pChild = pChild->m_pNext;
+ }
+ return -1;
+}
+CFDE_XMLNode* CFDE_XMLNode::GetPath(FX_LPCWSTR pPath, FX_INT32 iLength, FX_BOOL bQualifiedName) const
+{
+ FXSYS_assert(pPath != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pPath);
+ }
+ if (iLength == 0) {
+ return NULL;
+ }
+ CFX_WideString csPath;
+ FX_LPCWSTR pStart = pPath, pEnd = pPath + iLength;
+ FX_WCHAR ch;
+ while (pStart < pEnd) {
+ ch = *pStart ++;
+ if (ch == L'/') {
+ break;
+ } else {
+ csPath += ch;
+ }
+ }
+ iLength -= pStart - pPath;
+ CFDE_XMLNode *pFind = NULL;
+ if (csPath.GetLength() < 1) {
+ pFind = GetNodeItem(IFDE_XMLNode::Root);
+ } else if (csPath.Compare(L"..") == 0) {
+ pFind = m_pParent;
+ } else if (csPath.Compare(L".") == 0) {
+ pFind = (CFDE_XMLNode*)this;
+ } else {
+ CFX_WideString wsTag;
+ CFDE_XMLNode *pNode = m_pChild;
+ while (pNode != NULL) {
+ if (pNode->GetType() == FDE_XMLNODE_Element) {
+ if (bQualifiedName) {
+ ((CFDE_XMLElement*)pNode)->GetTagName(wsTag);
+ } else {
+ ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag);
+ }
+ if (wsTag.Compare(csPath) == 0) {
+ if (iLength < 1) {
+ pFind = pNode;
+ } else {
+ pFind = pNode->GetPath(pStart, iLength, bQualifiedName);
+ }
+ if (pFind != NULL) {
+ return pFind;
+ }
+ }
+ }
+ pNode = pNode->m_pNext;
+ }
+ }
+ if (pFind == NULL || iLength < 1) {
+ return pFind;
+ }
+ return pFind->GetPath(pStart, iLength, bQualifiedName);
+}
+FX_INT32 CFDE_XMLNode::InsertChildNode(CFDE_XMLNode *pNode, FX_INT32 index)
+{
+ FXSYS_assert(pNode != NULL);
+ pNode->m_pParent = this;
+ if (m_pChild == NULL) {
+ m_pChild = pNode;
+ pNode->m_pPrior = NULL;
+ pNode->m_pNext = NULL;
+ return 0;
+ } else if (index == 0) {
+ pNode->m_pNext = m_pChild;
+ pNode->m_pPrior = NULL;
+ m_pChild->m_pPrior = pNode;
+ m_pChild = pNode;
+ return 0;
+ }
+ FX_INT32 iCount = 0;
+ CFDE_XMLNode *pFind = m_pChild;
+ while (++iCount != index && pFind->m_pNext != NULL) {
+ pFind = pFind->m_pNext;
+ }
+ pNode->m_pPrior = pFind;
+ pNode->m_pNext = pFind->m_pNext;
+ if (pFind->m_pNext != NULL) {
+ pFind->m_pNext->m_pPrior = pNode;
+ }
+ pFind->m_pNext = pNode;
+ return iCount;
+}
+void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode *pNode)
+{
+ FXSYS_assert(m_pChild != NULL && pNode != NULL);
+ if (m_pChild == pNode) {
+ m_pChild = pNode->m_pNext;
+ } else {
+ pNode->m_pPrior->m_pNext = pNode->m_pNext;
+ }
+ if (pNode->m_pNext != NULL) {
+ pNode->m_pNext->m_pPrior = pNode->m_pPrior;
+ }
+ pNode->m_pParent = NULL;
+ pNode->m_pNext = NULL;
+ pNode->m_pPrior = NULL;
+}
+CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const
+{
+ switch (eItem) {
+ case IFDE_XMLNode::Root: {
+ CFDE_XMLNode *pParent = (CFDE_XMLNode*)this;
+ while (pParent->m_pParent != NULL) {
+ pParent = pParent->m_pParent;
+ }
+ return pParent;
+ }
+ case IFDE_XMLNode::Parent:
+ return m_pParent;
+ case IFDE_XMLNode::FirstSibling: {
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while (pItem->m_pPrior != NULL) {
+ pItem = pItem->m_pPrior;
+ }
+ return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
+ }
+ case IFDE_XMLNode::PriorSibling:
+ return m_pPrior;
+ case IFDE_XMLNode::NextSibling:
+ return m_pNext;
+ case IFDE_XMLNode::LastSibling: {
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while (pItem->m_pNext != NULL) {
+ pItem = pItem->m_pNext;
+ }
+ return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
+ }
+ case IFDE_XMLNode::FirstNeighbor: {
+ CFDE_XMLNode *pParent = (CFDE_XMLNode*)this;
+ while (pParent->m_pParent != NULL) {
+ pParent = pParent->m_pParent;
+ }
+ return pParent == (CFDE_XMLNode*)this ? NULL : pParent;
+ }
+ case IFDE_XMLNode::PriorNeighbor: {
+ if (m_pPrior == NULL) {
+ return m_pParent;
+ }
+ CFDE_XMLNode *pItem = m_pPrior;
+ while (CFDE_XMLNode *pTemp = pItem->m_pChild) {
+ pItem = pTemp;
+ while ((pTemp = pItem->m_pNext) != NULL) {
+ pItem = pTemp;
+ }
+ }
+ return pItem;
+ }
+ case IFDE_XMLNode::NextNeighbor: {
+ if (m_pChild != NULL) {
+ return m_pChild;
+ }
+ if (m_pNext != NULL) {
+ return m_pNext;
+ }
+ CFDE_XMLNode *pItem = m_pParent;
+ while (pItem != NULL) {
+ if (pItem->m_pNext != NULL) {
+ return pItem->m_pNext;
+ }
+ pItem = pItem->m_pParent;
+ }
+ return NULL;
+ }
+ case IFDE_XMLNode::LastNeighbor: {
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while (pItem->m_pParent != NULL) {
+ pItem = pItem->m_pParent;
+ }
+ while (TRUE) {
+ while (pItem->m_pNext != NULL) {
+ pItem = pItem->m_pNext;
+ }
+ if (pItem->m_pChild == NULL) {
+ break;
+ }
+ pItem = pItem->m_pChild;
+ }
+ return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
+ }
+ case IFDE_XMLNode::FirstChild:
+ return m_pChild;
+ case IFDE_XMLNode::LastChild: {
+ if (m_pChild == NULL) {
+ return NULL;
+ }
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild->m_pNext != NULL) {
+ pChild = pChild->m_pNext;
+ }
+ return pChild;
+ }
+ default:
+ break;
+ }
+ return NULL;
+}
+FX_INT32 CFDE_XMLNode::GetNodeLevel() const
+{
+ FX_INT32 iLevel = 0;
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while ((pItem = pItem->m_pParent) != NULL) {
+ iLevel ++;
+ }
+ return iLevel;
+}
+FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, CFDE_XMLNode *pNode)
+{
+ FXSYS_assert(pNode != NULL);
+ switch (eItem) {
+ case IFDE_XMLNode::NextSibling: {
+ pNode->m_pParent = m_pParent;
+ pNode->m_pNext = m_pNext;
+ pNode->m_pPrior = this;
+ if (m_pNext) {
+ m_pNext->m_pPrior = pNode;
+ }
+ m_pNext = pNode;
+ return TRUE;
+ }
+ case IFDE_XMLNode::PriorSibling: {
+ pNode->m_pParent = m_pParent;
+ pNode->m_pNext = this;
+ pNode->m_pPrior = m_pPrior;
+ if (m_pPrior) {
+ m_pPrior->m_pNext = pNode;
+ } else if (m_pParent) {
+ m_pParent->m_pChild = pNode;
+ }
+ m_pPrior = pNode;
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem)
+{
+ CFDE_XMLNode* pNode = NULL;
+ switch (eItem) {
+ case IFDE_XMLNode::NextSibling:
+ if (m_pNext) {
+ pNode = m_pNext;
+ m_pNext = pNode->m_pNext;
+ if (m_pNext) {
+ m_pNext->m_pPrior = this;
+ }
+ pNode->m_pParent = NULL;
+ pNode->m_pNext = NULL;
+ pNode->m_pPrior = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+ return pNode;
+}
+CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive)
+{
+ return NULL;
+}
+void CFDE_XMLNode::SaveXMLNode(IFX_Stream *pXMLStream)
+{
+ CFDE_XMLNode *pNode = (CFDE_XMLNode*)this;
+ FXSYS_assert(pXMLStream != NULL && pNode != NULL);
+ switch (pNode->GetType()) {
+ case FDE_XMLNODE_Instruction: {
+ CFX_WideString ws;
+ CFDE_XMLInstruction *pInstruction = (CFDE_XMLInstruction*)pNode;
+ if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) {
+ ws = L"<?xml version=\"1.0\" encoding=\"";
+ FX_WORD wCodePage = pXMLStream->GetCodePage();
+ if (wCodePage == FX_CODEPAGE_UTF16LE) {
+ ws += L"UTF-16";
+ } else if (wCodePage == FX_CODEPAGE_UTF16BE) {
+ ws += L"UTF-16be";
+ } else {
+ ws += L"UTF-8";
+ }
+ ws += L"\"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws.Format((FX_LPCWSTR)L"<?%s", (FX_LPCWSTR)pInstruction->m_wsTarget);
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = pInstruction->m_Attributes;
+ FX_INT32 i, iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ CFX_WideStringArray &targetdata = pInstruction->m_TargetData;
+ iCount = targetdata.GetSize();
+ for (i = 0; i < iCount; i++) {
+ ws = L" \"";
+ ws += targetdata[i];
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ ws = L"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Element: {
+ CFX_WideString ws;
+ ws = L"<";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = ((CFDE_XMLElement*)pNode)->m_Attributes;
+ FX_INT32 iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ if (pNode->m_pChild == NULL) {
+ ws = L"\n/>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws = L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFDE_XMLNode *pChild = pNode->m_pChild;
+ while (pChild != NULL) {
+ pChild->SaveXMLNode(pXMLStream);
+ pChild = pChild->m_pNext;
+ }
+ ws = L"</";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ ws += L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Text: {
+ CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
+ ws.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ ws.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ ws.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ ws.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ ws.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_CharData: {
+ CFX_WideString ws = L"<![CDATA[";
+ ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
+ ws += L"]]>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_Unknown:
+ break;
+ default:
+ break;
+ }
+}
+void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone)
+{
+ if (!m_pChild) {
+ return;
+ }
+ CFDE_XMLNode* pNext = m_pChild;
+ CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE);
+ pClone->InsertChildNode(pCloneNext);
+ pNext = pNext->m_pNext;
+ while (pNext) {
+ CFDE_XMLNode* pChild = pNext->Clone(TRUE);
+ pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild);
+ pCloneNext = pChild;
+ pNext = pNext->m_pNext;
+ }
+}
+IFDE_XMLInstruction* IFDE_XMLInstruction::Create(const CFX_WideString &wsTarget)
+{
+ return (IFDE_XMLInstruction*)FDE_New CFDE_XMLInstruction(wsTarget);
+}
+CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString &wsTarget)
+ : CFDE_XMLNode()
+ , m_wsTarget(wsTarget)
+ , m_TargetData()
+ , m_Attributes()
+{
+ FXSYS_assert(m_wsTarget.GetLength() > 0);
+}
+CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLInstruction* pClone = FDE_New CFDE_XMLInstruction(m_wsTarget);
+ if (!pClone) {
+ return pClone;
+ }
+ pClone->m_Attributes.Copy(m_Attributes);
+ pClone->m_TargetData.Copy(m_TargetData);
+ if (bRecursive) {
+ CloneChildren(pClone);
+ }
+ return pClone;
+}
+FX_INT32 CFDE_XMLInstruction::CountAttributes() const
+{
+ return m_Attributes.GetSize() / 2;
+}
+FX_BOOL CFDE_XMLInstruction::GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ FXSYS_assert(index > -1 && index < iCount / 2);
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (index == 0) {
+ wsAttriName = m_Attributes[i];
+ wsAttriValue = m_Attributes[i + 1];
+ return TRUE;
+ }
+ index --;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_XMLInstruction::HasAttribute(FX_LPCWSTR pwsAttriName) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CFDE_XMLInstruction::GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ wsAttriValue = m_Attributes[i + 1];
+ return;
+ }
+ }
+ wsAttriValue = pwsDefValue;
+}
+void CFDE_XMLInstruction::SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue)
+{
+ FXSYS_assert(wsAttriName.GetLength() > 0);
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(wsAttriName) == 0) {
+ m_Attributes[i] = wsAttriName;
+ m_Attributes[i + 1] = wsAttriValue;
+ return;
+ }
+ }
+ m_Attributes.Add(wsAttriName);
+ m_Attributes.Add(wsAttriValue);
+}
+FX_INT32 CFDE_XMLInstruction::GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FXSYS_wtoi((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return iDefValue;
+}
+void CFDE_XMLInstruction::SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%d", iAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+FX_FLOAT CFDE_XMLInstruction::GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FX_wcstof((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return fDefValue;
+}
+void CFDE_XMLInstruction::SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%f", fAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+void CFDE_XMLInstruction::RemoveAttribute(FX_LPCWSTR pwsAttriName)
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ m_Attributes.RemoveAt(i + 1);
+ m_Attributes.RemoveAt(i);
+ return;
+ }
+ }
+}
+FX_INT32 CFDE_XMLInstruction::CountData() const
+{
+ return m_TargetData.GetSize();
+}
+FX_BOOL CFDE_XMLInstruction::GetData(FX_INT32 index, CFX_WideString &wsData) const
+{
+ if (index < 0 || index >= m_TargetData.GetSize()) {
+ return FALSE;
+ }
+ wsData = m_TargetData[index];
+ return TRUE;
+}
+void CFDE_XMLInstruction::AppendData(const CFX_WideString &wsData)
+{
+ m_TargetData.Add(wsData);
+}
+void CFDE_XMLInstruction::RemoveData(FX_INT32 index)
+{
+ m_TargetData.RemoveAt(index);
+}
+IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString &wsTag)
+{
+ return (IFDE_XMLElement*)FDE_New CFDE_XMLElement(wsTag);
+}
+CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString &wsTag)
+ : CFDE_XMLNode()
+ , m_wsTag(wsTag)
+ , m_Attributes()
+{
+ FXSYS_assert(m_wsTag.GetLength() > 0);
+}
+CFDE_XMLElement::~CFDE_XMLElement()
+{
+ m_Attributes.RemoveAll();
+}
+CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLElement* pClone = FDE_New CFDE_XMLElement(m_wsTag);
+ if (!pClone) {
+ return NULL;
+ }
+ pClone->m_Attributes.Copy(m_Attributes);
+ if (bRecursive) {
+ CloneChildren(pClone);
+ } else {
+ CFX_WideString wsText;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ switch (pChild->GetType()) {
+ case FDE_XMLNODE_Text:
+ wsText += ((CFDE_XMLText*)pChild)->m_wsText;
+ break;
+ default:
+ break;
+ }
+ pChild = pChild->m_pNext;
+ }
+ pClone->SetTextData(wsText);
+ }
+ return pClone;
+}
+void CFDE_XMLElement::GetTagName(CFX_WideString &wsTag) const
+{
+ wsTag = m_wsTag;
+}
+void CFDE_XMLElement::GetLocalTagName(CFX_WideString &wsTag) const
+{
+ FX_STRSIZE iFind = m_wsTag.Find(L':', 0);
+ if (iFind < 0) {
+ wsTag = m_wsTag;
+ } else {
+ wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1);
+ }
+}
+void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString &wsPrefix) const
+{
+ FX_STRSIZE iFind = m_wsTag.Find(L':', 0);
+ if (iFind < 0) {
+ wsPrefix.Empty();
+ } else {
+ wsPrefix = m_wsTag.Left(iFind);
+ }
+}
+void CFDE_XMLElement::GetNamespaceURI(CFX_WideString &wsNamespace) const
+{
+ CFX_WideString wsAttri(L"xmlns"), wsPrefix;
+ GetNamespacePrefix(wsPrefix);
+ if (wsPrefix.GetLength() > 0) {
+ wsAttri += L":";
+ wsAttri += wsPrefix;
+ }
+ wsNamespace.Empty();
+ CFDE_XMLNode *pNode = (CFDE_XMLNode*)this;
+ while (pNode != NULL) {
+ if (pNode->GetType() != FDE_XMLNODE_Element) {
+ break;
+ }
+ CFDE_XMLElement *pElement = (CFDE_XMLElement*)pNode;
+ if (!pElement->HasAttribute(wsAttri)) {
+ pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent);
+ continue;
+ }
+ pElement->GetString(wsAttri, wsNamespace);
+ break;
+ }
+}
+FX_INT32 CFDE_XMLElement::CountAttributes() const
+{
+ return m_Attributes.GetSize() / 2;
+}
+FX_BOOL CFDE_XMLElement::GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ FXSYS_assert(index > -1 && index < iCount / 2);
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (index == 0) {
+ wsAttriName = m_Attributes[i];
+ wsAttriValue = m_Attributes[i + 1];
+ return TRUE;
+ }
+ index --;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_XMLElement::HasAttribute(FX_LPCWSTR pwsAttriName) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CFDE_XMLElement::GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ wsAttriValue = m_Attributes[i + 1];
+ return;
+ }
+ }
+ wsAttriValue = pwsDefValue;
+}
+void CFDE_XMLElement::SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue)
+{
+ FXSYS_assert(wsAttriName.GetLength() > 0);
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(wsAttriName) == 0) {
+ m_Attributes[i] = wsAttriName;
+ m_Attributes[i + 1] = wsAttriValue;
+ return;
+ }
+ }
+ m_Attributes.Add(wsAttriName);
+ m_Attributes.Add(wsAttriValue);
+}
+FX_INT32 CFDE_XMLElement::GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FXSYS_wtoi((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return iDefValue;
+}
+void CFDE_XMLElement::SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%d", iAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+FX_FLOAT CFDE_XMLElement::GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FX_wcstof((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return fDefValue;
+}
+void CFDE_XMLElement::SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%f", fAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+void CFDE_XMLElement::RemoveAttribute(FX_LPCWSTR pwsAttriName)
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ m_Attributes.RemoveAt(i + 1);
+ m_Attributes.RemoveAt(i);
+ return;
+ }
+ }
+}
+void CFDE_XMLElement::GetTextData(CFX_WideString &wsText) const
+{
+ CFX_WideTextBuf buffer;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ switch (pChild->GetType()) {
+ case FDE_XMLNODE_Text:
+ buffer << ((CFDE_XMLText*)pChild)->m_wsText;
+ break;
+ case FDE_XMLNODE_CharData:
+ buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData;
+ break;
+ default:
+ break;
+ }
+ pChild = pChild->m_pNext;
+ }
+ wsText = buffer.GetWideString();
+}
+void CFDE_XMLElement::SetTextData(const CFX_WideString &wsText)
+{
+ if (wsText.GetLength() < 1) {
+ return;
+ }
+ InsertChildNode(FDE_New CFDE_XMLText(wsText));
+}
+IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString &wsText)
+{
+ return (IFDE_XMLText*)FDE_New CFDE_XMLText(wsText);
+}
+CFDE_XMLText::CFDE_XMLText(const CFX_WideString &wsText)
+ : CFDE_XMLNode()
+ , m_wsText(wsText)
+{
+}
+CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLText* pClone = FDE_New CFDE_XMLText(m_wsText);
+ return pClone;
+}
+IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString &wsCData)
+{
+ return (IFDE_XMLCharData*)FDE_New CFDE_XMLCharData(wsCData);
+}
+CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString &wsCData)
+ : CFDE_XMLDeclaration()
+ , m_wsCharData(wsCData)
+{
+}
+CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLCharData* pClone = FDE_New CFDE_XMLCharData(m_wsCharData);
+ return pClone;
+}
+IFDE_XMLDoc* IFDE_XMLDoc::Create()
+{
+ return (IFDE_XMLDoc*)FDE_New CFDE_XMLDoc;
+}
+CFDE_XMLDoc::CFDE_XMLDoc()
+ : m_pRoot(NULL)
+ , m_pSyntaxParser(NULL)
+ , m_pXMLParser(NULL)
+{
+ Reset(TRUE);
+ CFDE_XMLInstruction *pXML = FDE_New CFDE_XMLInstruction((FX_LPCWSTR)L"xml");
+ m_pRoot->InsertChildNode(pXML);
+}
+CFDE_XMLDoc::~CFDE_XMLDoc()
+{
+ Reset(FALSE);
+}
+void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot)
+{
+ m_iStatus = 0;
+ m_pStream = NULL;
+ if (bInitRoot) {
+ if (m_pRoot == NULL) {
+ m_pRoot = FDE_New CFDE_XMLNode;
+ } else {
+ m_pRoot->DeleteChildren();
+ }
+ } else {
+ if (m_pRoot != NULL) {
+ m_pRoot->Release();
+ m_pRoot = NULL;
+ }
+ }
+ ReleaseParser();
+}
+void CFDE_XMLDoc::ReleaseParser()
+{
+ if (m_pXMLParser != NULL) {
+ m_pXMLParser->Release();
+ m_pXMLParser = NULL;
+ }
+ if (m_pSyntaxParser != NULL) {
+ m_pSyntaxParser->Release();
+ m_pSyntaxParser = NULL;
+ }
+}
+FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream *pXMLStream, FX_INT32 iXMLPlaneSize , FX_INT32 iTextDataSize , FDE_LPXMLREADERHANDLER pHandler )
+{
+ if (pXMLStream == NULL) {
+ return FALSE;
+ }
+ Reset(TRUE);
+ iXMLPlaneSize = iXMLPlaneSize / 1024;
+ if (iXMLPlaneSize < 1) {
+ iXMLPlaneSize = 1;
+ }
+ iXMLPlaneSize *= 1024;
+ if (iXMLPlaneSize < 4096) {
+ iXMLPlaneSize = 4096;
+ }
+ iTextDataSize = iTextDataSize / 128;
+ if (iTextDataSize < 1) {
+ iTextDataSize = 1;
+ }
+ iTextDataSize *= 128;
+ if (iTextDataSize < 128) {
+ iTextDataSize = 128;
+ }
+ m_pStream = pXMLStream;
+ FX_WORD wCodePage = m_pStream->GetCodePage();
+ if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && wCodePage != FX_CODEPAGE_UTF8) {
+ m_pStream->SetCodePage(FX_CODEPAGE_UTF8);
+ }
+ m_pSyntaxParser = IFDE_XMLSyntaxParser::Create();
+ if (m_pSyntaxParser == NULL) {
+ return FALSE;
+ }
+ m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize);
+ if (pHandler == NULL) {
+ m_pXMLParser = FDE_New CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser);
+ } else {
+ m_pXMLParser = FDE_New CFDE_XMLSAXParser(pHandler, m_pSyntaxParser);
+ }
+ return m_pXMLParser != NULL;
+}
+FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser *pXMLParser)
+{
+ if (pXMLParser == NULL) {
+ return FALSE;
+ }
+ Reset(TRUE);
+ m_pXMLParser = pXMLParser;
+ return m_pXMLParser != NULL;
+}
+FX_INT32 CFDE_XMLDoc::DoLoad(IFX_Pause *pPause)
+{
+ if (m_iStatus >= 100) {
+ return m_iStatus;
+ }
+ FXSYS_assert(m_pXMLParser != NULL);
+ return m_iStatus = m_pXMLParser->DoParser(pPause);
+}
+void CFDE_XMLDoc::CloseXML()
+{
+ ReleaseParser();
+}
+void CFDE_XMLDoc::SaveXMLNode(IFX_Stream *pXMLStream, IFDE_XMLNode *pINode)
+{
+ CFDE_XMLNode *pNode = (CFDE_XMLNode*)pINode;
+ FXSYS_assert(pXMLStream != NULL && pNode != NULL);
+ switch (pNode->GetType()) {
+ case FDE_XMLNODE_Instruction: {
+ CFX_WideString ws;
+ CFDE_XMLInstruction *pInstruction = (CFDE_XMLInstruction*)pNode;
+ if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) {
+ ws = L"<?xml version=\"1.0\" encoding=\"";
+ FX_WORD wCodePage = pXMLStream->GetCodePage();
+ if (wCodePage == FX_CODEPAGE_UTF16LE) {
+ ws += L"UTF-16";
+ } else if (wCodePage == FX_CODEPAGE_UTF16BE) {
+ ws += L"UTF-16be";
+ } else {
+ ws += L"UTF-8";
+ }
+ ws += L"\"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws.Format((FX_LPCWSTR)L"<?%s", (FX_LPCWSTR)pInstruction->m_wsTarget);
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = pInstruction->m_Attributes;
+ FX_INT32 i, iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ CFX_WideStringArray &targetdata = pInstruction->m_TargetData;
+ iCount = targetdata.GetSize();
+ for (i = 0; i < iCount; i++) {
+ ws = L" \"";
+ ws += targetdata[i];
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ ws = L"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Element: {
+ CFX_WideString ws;
+ ws = L"<";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = ((CFDE_XMLElement*)pNode)->m_Attributes;
+ FX_INT32 iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ if (pNode->m_pChild == NULL) {
+ ws = L"\n/>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws = L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFDE_XMLNode *pChild = pNode->m_pChild;
+ while (pChild != NULL) {
+ SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild);
+ pChild = pChild->m_pNext;
+ }
+ ws = L"</";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ ws += L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Text: {
+ CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
+ ws.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ ws.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ ws.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ ws.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ ws.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_CharData: {
+ CFX_WideString ws = L"<![CDATA[";
+ ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
+ ws += L"]]>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_Unknown:
+ break;
+ default:
+ break;
+ }
+}
+void CFDE_XMLDoc::SaveXML(IFX_Stream *pXMLStream, FX_BOOL bSaveBOM)
+{
+ if (pXMLStream == NULL || pXMLStream == m_pStream) {
+ m_pStream->Seek(FX_STREAMSEEK_Begin, 0);
+ pXMLStream = m_pStream;
+ }
+ FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0);
+ FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0);
+ FX_WORD wCodePage = pXMLStream->GetCodePage();
+ if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && wCodePage != FX_CODEPAGE_UTF8) {
+ wCodePage = FX_CODEPAGE_UTF8;
+ pXMLStream->SetCodePage(wCodePage);
+ }
+ if (bSaveBOM) {
+ pXMLStream->WriteString((FX_LPCWSTR)L"\xFEFF", 1);
+ }
+ CFDE_XMLNode *pNode = m_pRoot->m_pChild;
+ while (pNode != NULL) {
+ SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode);
+ pNode = pNode->m_pNext;
+ }
+ if (pXMLStream == m_pStream) {
+ FX_INT32 iPos = pXMLStream->GetPosition();
+ pXMLStream->SetLength(iPos);
+ }
+}
+CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode *pRoot, IFDE_XMLSyntaxParser *pParser)
+ : m_pRoot(pRoot)
+ , m_pParser(pParser)
+ , m_pParent(pRoot)
+ , m_pChild(NULL)
+ , m_NodeStack(16)
+ , m_ws1()
+ , m_ws2()
+{
+ m_NodeStack.Push(m_pParent);
+}
+CFDE_XMLDOMParser::~CFDE_XMLDOMParser()
+{
+ m_NodeStack.RemoveAll();
+ m_ws1.Empty();
+ m_ws2.Empty();
+}
+FX_INT32 CFDE_XMLDOMParser::DoParser(IFX_Pause *pPause)
+{
+ FX_DWORD dwRet;
+ FX_INT32 iCount = 0;
+ while (TRUE) {
+ dwRet = m_pParser->DoSyntaxParse();
+ switch (dwRet) {
+ case FDE_XMLSYNTAXSTATUS_InstructionOpen:
+ break;
+ case FDE_XMLSYNTAXSTATUS_InstructionClose:
+ if (m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementOpen:
+ case FDE_XMLSYNTAXSTATUS_ElementBreak:
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementClose:
+ if (m_pChild->GetType() != FDE_XMLNODE_Element) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParser->GetTagName(m_ws1);
+ ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2);
+ if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_NodeStack.Pop();
+ if (m_NodeStack.GetSize() < 1) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement();
+ m_pChild = m_pParent;
+ iCount++;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetName:
+ m_pParser->GetTargetName(m_ws1);
+ m_pChild = FDE_New CFDE_XMLInstruction(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_TagName:
+ m_pParser->GetTagName(m_ws1);
+ m_pChild = FDE_New CFDE_XMLElement(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_NodeStack.Push(m_pChild);
+ m_pParent = m_pChild;
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriName:
+ m_pParser->GetAttributeName(m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriValue:
+ if (m_pChild == NULL) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParser->GetAttributeName(m_ws2);
+ if (m_pChild->GetType() == FDE_XMLNODE_Element) {
+ ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2);
+ } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) {
+ ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2);
+ }
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_Text:
+ m_pParser->GetTextData(m_ws1);
+ m_pChild = FDE_New CFDE_XMLText(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_CData:
+ m_pParser->GetTextData(m_ws1);
+ m_pChild = FDE_New CFDE_XMLCharData(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetData:
+ if (m_pChild == NULL || m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ if (!m_ws1.IsEmpty()) {
+ ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+ }
+ m_pParser->GetTargetData(m_ws1);
+ ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+ m_ws1.Empty();
+ break;
+ default:
+ break;
+ }
+ if (dwRet == FDE_XMLSYNTAXSTATUS_Error || dwRet == FDE_XMLSYNTAXSTATUS_EOS) {
+ break;
+ }
+ if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) {
+ break;
+ }
+ }
+ return m_pParser->GetStatus();
+}
+CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, IFDE_XMLSyntaxParser *pParser)
+ : m_pHandler(pHandler)
+ , m_pParser(pParser)
+ , m_TagStack(16)
+ , m_pTagTop(NULL)
+ , m_ws1()
+ , m_ws2()
+{
+}
+CFDE_XMLSAXParser::~CFDE_XMLSAXParser()
+{
+ m_TagStack.RemoveAll();
+ m_ws1.Empty();
+ m_ws2.Empty();
+}
+FX_INT32 CFDE_XMLSAXParser::DoParser(IFX_Pause *pPause)
+{
+ FX_DWORD dwRet = 0;
+ FX_INT32 iCount = 0;
+ while (TRUE) {
+ dwRet = m_pParser->DoSyntaxParse();
+ switch (dwRet) {
+ case FDE_XMLSYNTAXSTATUS_ElementBreak:
+ if (m_pTagTop == NULL) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ if (m_pTagTop->eType == FDE_XMLNODE_Element) {
+ m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName);
+ }
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementClose:
+ if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParser->GetTagName(m_ws1);
+ if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ } else if (m_ws1.GetLength() == 0) {
+ m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName);
+ }
+ m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName);
+ Pop();
+ iCount++;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetName: {
+ m_pParser->GetTargetName(m_ws1);
+ CFDE_XMLTAG xmlTag;
+ xmlTag.wsTagName = m_ws1;
+ xmlTag.eType = FDE_XMLNODE_Instruction;
+ Push(xmlTag);
+ m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, m_pTagTop->wsTagName);
+ m_ws1.Empty();
+ }
+ break;
+ case FDE_XMLSYNTAXSTATUS_TagName: {
+ m_pParser->GetTargetName(m_ws1);
+ CFDE_XMLTAG xmlTag;
+ xmlTag.wsTagName = m_ws1;
+ xmlTag.eType = FDE_XMLNODE_Element;
+ Push(xmlTag);
+ m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, m_pTagTop->wsTagName);
+ }
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriName:
+ m_pParser->GetTargetName(m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriValue:
+ m_pParser->GetAttributeName(m_ws2);
+ if (m_pTagTop == NULL) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ if (m_pTagTop->eType == FDE_XMLNODE_Element) {
+ m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2);
+ }
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_CData:
+ m_pParser->GetTextData(m_ws1);
+ m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_Text:
+ m_pParser->GetTextData(m_ws1);
+ m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetData:
+ m_pParser->GetTargetData(m_ws1);
+ m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1);
+ m_ws1.Empty();
+ break;
+ default:
+ break;
+ }
+ if (dwRet == FDE_XMLSYNTAXSTATUS_Error || dwRet == FDE_XMLSYNTAXSTATUS_EOS) {
+ break;
+ }
+ if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) {
+ break;
+ }
+ }
+ return m_pParser->GetStatus();
+}
+inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG &xmlTag)
+{
+ m_TagStack.Push(xmlTag);
+ m_pTagTop = m_TagStack.GetTopElement();
+}
+inline void CFDE_XMLSAXParser::Pop()
+{
+ m_TagStack.Pop();
+ m_pTagTop = m_TagStack.GetTopElement();
+}
+#ifdef _FDE_BLOCK_BUFFER
+CFDE_BlockBuffer::CFDE_BlockBuffer(FX_INT32 iAllocStep)
+ : m_iAllocStep(iAllocStep),
+ m_iStartPosition(0),
+ m_iBufferSize(0),
+ m_iDataLength(0)
+{
+}
+CFDE_BlockBuffer::~CFDE_BlockBuffer()
+{
+ ClearBuffer();
+}
+FX_LPWSTR CFDE_BlockBuffer::GetAvailableBlock(FX_INT32& iIndexInBlock)
+{
+ iIndexInBlock = 0;
+ FX_INT32 iBlockNum = m_BlockArray.GetSize();
+ if (iBlockNum == 0) {
+ return NULL;
+ }
+ FX_INT32 iRealIndex = m_iStartPosition + m_iDataLength;
+ FX_LPWSTR pDataBlock = NULL;
+ if(iRealIndex == m_iBufferSize) {
+ FX_LPWSTR pBlock = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
+ if (pBlock) {
+ m_BlockArray.Add(pBlock);
+ m_iBufferSize += m_iAllocStep;
+ }
+ iIndexInBlock = 0;
+ pDataBlock = pBlock;
+ } else {
+ FX_INT32 iBlockIndex = iRealIndex / m_iAllocStep;
+ FX_INT32 iInnerIndex = iRealIndex % m_iAllocStep;
+ iIndexInBlock = iInnerIndex;
+ pDataBlock = (FX_LPWSTR)m_BlockArray[iBlockIndex];
+ }
+ return pDataBlock;
+}
+FX_BOOL CFDE_BlockBuffer::InitBuffer(FX_INT32 iBufferSize)
+{
+ ClearBuffer();
+ FX_INT32 iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1;
+ for (FX_INT32 i = 0; i < iNumOfBlock; i++) {
+ FX_LPWSTR pBlockBuffer = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
+ if (pBlockBuffer == NULL) {
+ ClearBuffer();
+ return FALSE;
+ }
+ m_BlockArray.Add(pBlockBuffer);
+ }
+ m_iBufferSize = iNumOfBlock * m_iAllocStep;
+ return TRUE;
+}
+void CFDE_BlockBuffer::SetTextChar(FX_INT32 iIndex, FX_WCHAR ch)
+{
+ if (iIndex < 0) {
+ return;
+ }
+ FX_INT32 iRealIndex = m_iStartPosition + iIndex;
+ FX_INT32 iBlockIndex = iRealIndex / m_iAllocStep;
+ FX_INT32 iInnerIndex = iRealIndex % m_iAllocStep;
+ FX_INT32 iBlockSize = m_BlockArray.GetSize();
+ if (iBlockIndex >= iBlockSize) {
+ FX_INT32 iNewBlocks = iBlockIndex - iBlockSize + 1;
+ do {
+ FX_LPWSTR pBlock = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
+ if (!pBlock) {
+ return;
+ }
+ m_BlockArray.Add(pBlock);
+ m_iBufferSize += m_iAllocStep;
+ } while (--iNewBlocks);
+ }
+ FX_LPWSTR pTextData = (FX_LPWSTR)m_BlockArray[iBlockIndex];
+ *(pTextData + iInnerIndex) = ch;
+ if (m_iDataLength <= iIndex) {
+ m_iDataLength = iIndex + 1;
+ }
+}
+FX_INT32 CFDE_BlockBuffer::DeleteTextChars(FX_INT32 iCount, FX_BOOL bDirection )
+{
+ if (iCount <= 0) {
+ return m_iDataLength;
+ }
+ if (iCount >= m_iDataLength) {
+ Reset(FALSE);
+ return 0;
+ }
+ if (bDirection) {
+ m_iStartPosition += iCount;
+ m_iDataLength -= iCount;
+ } else {
+ m_iDataLength -= iCount;
+ }
+ return m_iDataLength;
+}
+void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, FX_INT32 iStart, FX_INT32 iLength) const
+{
+ wsTextData.Empty();
+ FX_INT32 iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition;
+ if (iStart < 0 || iStart > iMaybeDataLength) {
+ return;
+ }
+ if (iLength == -1 || iLength > iMaybeDataLength) {
+ iLength = iMaybeDataLength;
+ }
+ if (iLength <= 0) {
+ return;
+ }
+ FX_LPWSTR pBuf = wsTextData.GetBuffer(iLength);
+ if (!pBuf) {
+ return;
+ }
+ FX_INT32 iStartBlockIndex = 0;
+ FX_INT32 iStartInnerIndex = 0;
+ TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex);
+ FX_INT32 iEndBlockIndex = 0;
+ FX_INT32 iEndInnerIndex = 0;
+ TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex);
+ FX_INT32 iPointer = 0;
+ for (FX_INT32 i = iStartBlockIndex; i <= iEndBlockIndex; i++) {
+ FX_INT32 iBufferPointer = 0;
+ FX_INT32 iCopyLength = m_iAllocStep;
+ if (i == iStartBlockIndex) {
+ iCopyLength -= iStartInnerIndex;
+ iBufferPointer = iStartInnerIndex;
+ }
+ if (i == iEndBlockIndex) {
+ iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex);
+ }
+ FX_LPWSTR pBlockBuf = (FX_LPWSTR)m_BlockArray[i];
+ FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, iCopyLength * sizeof(FX_WCHAR));
+ iPointer += iCopyLength;
+ }
+ wsTextData.ReleaseBuffer(iLength);
+}
+void CFDE_BlockBuffer::TextDataIndex2BufIndex(const FX_INT32 iIndex, FX_INT32& iBlockIndex, FX_INT32& iInnerIndex) const
+{
+ FXSYS_assert(iIndex >= 0);
+ FX_INT32 iRealIndex = m_iStartPosition + iIndex;
+ iBlockIndex = iRealIndex / m_iAllocStep;
+ iInnerIndex = iRealIndex % m_iAllocStep;
+}
+void CFDE_BlockBuffer::ClearBuffer()
+{
+ m_iBufferSize = 0;
+ FX_INT32 iSize = m_BlockArray.GetSize();
+ for (FX_INT32 i = 0; i < iSize; i++) {
+ FDE_Free(m_BlockArray[i]);
+ m_BlockArray[i] = NULL;
+ }
+ m_BlockArray.RemoveAll();
+}
+#endif
+IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create()
+{
+ return FDE_New CFDE_XMLSyntaxParser;
+}
+#ifdef _FDE_BLOCK_BUFFER
+CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser()
+ : m_pStream(NULL)
+ , m_iXMLPlaneSize(-1)
+ , m_iCurrentPos(0)
+ , m_iCurrentNodeNum(-1)
+ , m_iLastNodeNum(-1)
+ , m_iParsedChars(0)
+ , m_iParsedBytes(0)
+ , m_pBuffer(NULL)
+ , m_iBufferChars(0)
+ , m_bEOS(FALSE)
+ , m_pStart(NULL)
+ , m_pEnd(NULL)
+ , m_XMLNodeStack(16)
+ , m_dwStatus(FDE_XMLSYNTAXSTATUS_None)
+ , m_dwMode(FDE_XMLSYNTAXMODE_Text)
+ , m_wQuotationMark(0)
+ , m_BlockBuffer()
+ , m_pCurrentBlock(NULL)
+ , m_iIndexInBlock(0)
+ , m_iDataLength(m_BlockBuffer.GetDataLengthRef())
+ , m_iAllocStep(m_BlockBuffer.GetAllocStep())
+ , m_iTextDataLength(0)
+ , m_iEntityStart(-1)
+ , m_SkipStack(16)
+{
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+}
+void CFDE_XMLSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize )
+{
+ FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL);
+ FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0);
+ FX_INT32 iStreamLength = pStream->GetLength();
+ FXSYS_assert(iStreamLength > 0);
+ m_pStream = pStream;
+ m_iXMLPlaneSize = FX_MIN(iXMLPlaneSize, iStreamLength);
+ FX_BYTE bom[4];
+ m_iCurrentPos = m_pStream->GetBOM(bom);
+ FXSYS_assert(m_pBuffer == NULL);
+ m_pBuffer = (FX_LPWSTR)FDE_Alloc(m_iXMLPlaneSize * sizeof(FX_WCHAR));
+ m_pStart = m_pEnd = m_pBuffer;
+ FXSYS_assert(!m_BlockBuffer.IsInitialized());
+ m_BlockBuffer.InitBuffer();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_iParsedBytes = m_iParsedChars = 0;
+ m_iBufferChars = 0;
+}
+FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse()
+{
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ return m_dwStatus;
+ }
+ FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_BlockBuffer.IsInitialized());
+ FX_INT32 iStreamLength = m_pStream->GetLength();
+ FX_INT32 iPos;
+ FX_WCHAR ch;
+ FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None;
+ while (TRUE) {
+ if (m_pStart >= m_pEnd) {
+ if (m_bEOS || m_iCurrentPos >= iStreamLength) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iParsedChars += (m_pEnd - m_pBuffer);
+ m_iParsedBytes = m_iCurrentPos;
+ m_pStream->Lock();
+ if (m_pStream->GetPosition() != m_iCurrentPos) {
+ m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos);
+ }
+ m_iBufferChars = m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS);
+ iPos = m_pStream->GetPosition();
+ m_pStream->Unlock();
+ if (m_iBufferChars < 1) {
+ m_iCurrentPos = iStreamLength;
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iCurrentPos = iPos;
+ m_pStart = m_pBuffer;
+ m_pEnd = m_pBuffer + m_iBufferChars;
+ }
+ while (m_pStart < m_pEnd) {
+ ch = *m_pStart;
+ switch (m_dwMode) {
+ case FDE_XMLSYNTAXMODE_Text:
+ if (ch == L'<') {
+ if (m_iDataLength > 0) {
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_iEntityStart = -1;
+ dwStatus = FDE_XMLSYNTAXSTATUS_Text;
+ } else {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Node;
+ }
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Node:
+ if (ch == L'!') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl;
+ } else if (ch == L'/') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else if (ch == L'?') {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Instruction;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Target;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen;
+ } else {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Element;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_dwMode = FDE_XMLSYNTAXMODE_Tag;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Target:
+ case FDE_XMLSYNTAXMODE_Tag:
+ if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
+ if (m_iDataLength < 1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (m_dwMode != FDE_XMLSYNTAXMODE_Target) {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TagName;
+ } else {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetName;
+ }
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriName:
+ if (m_iDataLength < 1 && FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
+ if (m_iDataLength < 1) {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Element) {
+ if (ch == L'>' || ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_BreakElement;
+ break;
+ }
+ } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch == L'?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ }
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ }
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriName;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriEqualSign:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'=') {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriQuotation:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'\"' && ch != L'\'') {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_wQuotationMark = ch;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriValue;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriValue:
+ if (ch == m_wQuotationMark) {
+ if (m_iEntityStart > -1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_iTextDataLength = m_iDataLength;
+ m_wQuotationMark = 0;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue;
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_CloseInstruction:
+ if (ch != L'>') {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ } else if (m_iDataLength > 0) {
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_pStart ++;
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_BreakElement:
+ if (ch == L'>') {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak;
+ } else if (ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_CloseElement:
+ if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
+ if (ch == L'>') {
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose;
+ } else if (!FDE_IsXMLWhiteSpace(ch)) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_SkipCommentOrDecl:
+ if (ch == '-') {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipComment;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode;
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipDeclNode:
+ if (m_SkipChar == L'\'' || m_SkipChar == L'\"') {
+ m_pStart ++;
+ if (ch != m_SkipChar) {
+ break;
+ }
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ } else {
+ switch (ch) {
+ case L'<':
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ break;
+ case L'[':
+ m_SkipChar = L']';
+ m_SkipStack.Push(L']');
+ break;
+ case L'(':
+ m_SkipChar = L')';
+ m_SkipStack.Push(L')');
+ break;
+ case L'\'':
+ m_SkipChar = L'\'';
+ m_SkipStack.Push(L'\'');
+ break;
+ case L'\"':
+ m_SkipChar = L'\"';
+ m_SkipStack.Push(L'\"');
+ break;
+ default:
+ if (ch == m_SkipChar) {
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ if (m_iDataLength >= 9) {
+ CFX_WideString wsHeader;
+ m_BlockBuffer.GetTextData(wsHeader, 0, 7);
+ if (wsHeader.Equal(FX_WSTRC(L"[CDATA["))) {
+ CFX_WideString wsTailer;
+ m_BlockBuffer.GetTextData(wsTailer, m_iDataLength - 2, 2);
+ if (wsTailer.Equal(FX_WSTRC(L"]]"))) {
+ m_BlockBuffer.DeleteTextChars(7, TRUE);
+ m_BlockBuffer.DeleteTextChars(2, FALSE);
+ dwStatus = FDE_XMLSYNTAXSTATUS_CData;
+ }
+ }
+ }
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ }
+ break;
+ }
+ if (m_SkipStack.GetSize() > 0) {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ }
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipComment:
+ if (ch == L'-') {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = L'-';
+ m_iDataLength++;
+ } else if (ch == L'>') {
+ if (m_iDataLength > 1) {
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ }
+ } else {
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ }
+ m_pStart++;
+ break;
+ case FDE_XMLSYNTAXMODE_TargetData:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ if (m_iDataLength < 1) {
+ m_pStart ++;
+ break;
+ } else if (m_wQuotationMark == 0) {
+ m_iTextDataLength = m_iDataLength;
+ m_wQuotationMark = 0;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ break;
+ }
+ }
+ if (ch == '?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else if (ch == '\"') {
+ if (m_wQuotationMark == 0) {
+ m_wQuotationMark = ch;
+ m_pStart++;
+ } else if (ch == m_wQuotationMark) {
+ m_iTextDataLength = m_iDataLength;
+ m_wQuotationMark = 0;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_pStart ++;
+ }
+ break;
+ default:
+ break;
+ }
+ if (dwStatus != FDE_XMLSYNTAXSTATUS_None) {
+ return dwStatus;
+ }
+ }
+ }
+ return 0;
+}
+#else
+CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser()
+ : m_pStream(NULL)
+ , m_iXMLPlaneSize(-1)
+ , m_iTextDataSize(256)
+ , m_iCurrentPos(0)
+ , m_iCurrentNodeNum(-1)
+ , m_iLastNodeNum(-1)
+ , m_iParsedChars(0)
+ , m_iParsedBytes(0)
+ , m_pBuffer(NULL)
+ , m_iBufferChars(0)
+ , m_bEOS(FALSE)
+ , m_pStart(NULL)
+ , m_pEnd(NULL)
+ , m_XMLNodeStack(16)
+ , m_pwsTextData(NULL)
+ , m_iDataPos(0)
+ , m_dwStatus(FDE_XMLSYNTAXSTATUS_None)
+ , m_dwMode(FDE_XMLSYNTAXMODE_Text)
+ , m_wQuotationMark(0)
+ , m_iTextDataLength(0)
+ , m_iEntityStart(-1)
+ , m_SkipStack(16)
+{
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+}
+void CFDE_XMLSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize )
+{
+ FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL);
+ FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0);
+ FX_INT32 iStreamLength = pStream->GetLength();
+ FXSYS_assert(iStreamLength > 0);
+ m_pStream = pStream;
+ m_iXMLPlaneSize = FX_MIN(iXMLPlaneSize, iStreamLength);
+ m_iTextDataSize = iTextDataSize;
+ FX_BYTE bom[4];
+ m_iCurrentPos = m_pStream->GetBOM(bom);
+ FXSYS_assert(m_pBuffer == NULL);
+ m_pBuffer = (FX_LPWSTR)FDE_Alloc(m_iXMLPlaneSize * sizeof(FX_WCHAR));
+ m_pStart = m_pEnd = m_pBuffer;
+ FXSYS_assert(m_pwsTextData == NULL);
+ m_pwsTextData = (FX_LPWSTR)FDE_Alloc(m_iTextDataSize * sizeof(FX_WCHAR));
+ m_iParsedBytes = m_iParsedChars = 0;
+ m_iBufferChars = 0;
+}
+FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse()
+{
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ return m_dwStatus;
+ }
+ FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL);
+ FX_INT32 iStreamLength = m_pStream->GetLength();
+ FX_INT32 iPos;
+ FX_WCHAR ch;
+ FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None;
+ while (TRUE) {
+ if (m_pStart >= m_pEnd) {
+ if (m_bEOS || m_iCurrentPos >= iStreamLength) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iParsedChars += (m_pEnd - m_pBuffer);
+ m_iParsedBytes = m_iCurrentPos;
+ m_pStream->Lock();
+ if (m_pStream->GetPosition() != m_iCurrentPos) {
+ m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos);
+ }
+ m_iBufferChars = m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS);
+ iPos = m_pStream->GetPosition();
+ m_pStream->Unlock();
+ if (m_iBufferChars < 1) {
+ m_iCurrentPos = iStreamLength;
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iCurrentPos = iPos;
+ m_pStart = m_pBuffer;
+ m_pEnd = m_pBuffer + m_iBufferChars;
+ }
+ while (m_pStart < m_pEnd) {
+ ch = *m_pStart;
+ switch (m_dwMode) {
+ case FDE_XMLSYNTAXMODE_Text:
+ if (ch == L'<') {
+ if (m_iDataPos > 0) {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_iEntityStart = -1;
+ dwStatus = FDE_XMLSYNTAXSTATUS_Text;
+ } else {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Node;
+ }
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Node:
+ if (ch == L'!') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl;
+ } else if (ch == L'/') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else if (ch == L'?') {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Instruction;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Target;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen;
+ } else {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Element;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_dwMode = FDE_XMLSYNTAXMODE_Tag;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Target:
+ case FDE_XMLSYNTAXMODE_Tag:
+ if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
+ if (m_iDataPos < 1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_dwMode != FDE_XMLSYNTAXMODE_Target) {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TagName;
+ } else {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetName;
+ }
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriName:
+ if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
+ if (m_iDataPos < 1) {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Element) {
+ if (ch == L'>' || ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_BreakElement;
+ break;
+ }
+ } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch == L'?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ }
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ }
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriName;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriEqualSign:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'=') {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriQuotation:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'\"' && ch != L'\'') {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_wQuotationMark = ch;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriValue;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriValue:
+ if (ch == m_wQuotationMark) {
+ if (m_iEntityStart > -1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_iTextDataLength = m_iDataPos;
+ m_wQuotationMark = 0;
+ m_iDataPos = 0;
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue;
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_CloseInstruction:
+ if (ch != L'>') {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ } else if (m_iDataPos > 0) {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_pStart ++;
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_BreakElement:
+ if (ch == L'>') {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak;
+ } else if (ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_CloseElement:
+ if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
+ if (ch == L'>') {
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose;
+ } else if (!FDE_IsXMLWhiteSpace(ch)) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_SkipCommentOrDecl:
+ if (ch == '-') {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipComment;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode;
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipDeclNode:
+ if (m_SkipChar == L'\'' || m_SkipChar == L'\"') {
+ m_pStart ++;
+ if (ch != m_SkipChar) {
+ break;
+ }
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ } else {
+ switch (ch) {
+ case L'<':
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ break;
+ case L'[':
+ m_SkipChar = L']';
+ m_SkipStack.Push(L']');
+ break;
+ case L'(':
+ m_SkipChar = L')';
+ m_SkipStack.Push(L')');
+ break;
+ case L'\'':
+ m_SkipChar = L'\'';
+ m_SkipStack.Push(L'\'');
+ break;
+ case L'\"':
+ m_SkipChar = L'\"';
+ m_SkipStack.Push(L'\"');
+ break;
+ default:
+ if (ch == m_SkipChar) {
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_iTextDataLength >= 9
+ && FXSYS_memcmp(m_pwsTextData, L"[CDATA[", 7 * sizeof(FX_WCHAR)) == 0
+ && FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, L"]]", 2 * sizeof(FX_WCHAR)) == 0) {
+ m_iTextDataLength -= 9;
+ FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, m_iTextDataLength * sizeof(FX_WCHAR));
+ dwStatus = FDE_XMLSYNTAXSTATUS_CData;
+ }
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ }
+ break;
+ }
+ if (m_SkipStack.GetSize() > 0) {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ }
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipComment:
+ if (ch == L'-') {
+ m_iDataPos++;
+ } else if (ch == L'>') {
+ if (m_iDataPos > 1) {
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ }
+ } else {
+ m_iDataPos = 0;
+ }
+ m_pStart++;
+ break;
+ case FDE_XMLSYNTAXMODE_TargetData:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ if (m_iDataPos < 1) {
+ m_pStart ++;
+ break;
+ } else if (m_wQuotationMark == 0) {
+ m_iTextDataLength = m_iDataPos;
+ m_wQuotationMark = 0;
+ m_iDataPos = 0;
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ break;
+ }
+ }
+ if (ch == '?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else if (ch == '\"') {
+ if (m_wQuotationMark == 0) {
+ m_wQuotationMark = ch;
+ m_pStart++;
+ } else if (ch == m_wQuotationMark) {
+ m_iTextDataLength = m_iDataPos;
+ m_wQuotationMark = 0;
+ m_iDataPos = 0;
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_pStart ++;
+ }
+ break;
+ default:
+ break;
+ }
+ if (dwStatus != FDE_XMLSYNTAXSTATUS_None) {
+ return dwStatus;
+ }
+ }
+ }
+ return 0;
+}
+#endif
+CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser()
+{
+#ifdef _FDE_BLOCK_BUFFER
+ if (m_pCurrentBlock) {
+ m_pCurrentBlock = NULL;
+ }
+#else
+ if (m_pwsTextData != NULL) {
+ FDE_Free(m_pwsTextData);
+ }
+#endif
+ if (m_pBuffer != NULL) {
+ FDE_Free(m_pBuffer);
+ }
+}
+FX_INT32 CFDE_XMLSyntaxParser::GetStatus() const
+{
+ if (m_pStream == NULL) {
+ return -1;
+ }
+ FX_INT32 iStreamLength = m_pStream->GetLength();
+ if (iStreamLength < 1) {
+ return 100;
+ }
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) {
+ return -1;
+ }
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ return 100;
+ }
+ return m_iParsedBytes * 100 / iStreamLength;
+}
+static FX_INT32 FX_GetUTF8EncodeLength(FX_LPCWSTR pSrc, FX_INT32 iSrcLen)
+{
+ FX_DWORD unicode = 0;
+ FX_INT32 iDstNum = 0;
+ while (iSrcLen -- > 0) {
+ unicode = *pSrc ++;
+ int nbytes = 0;
+ if ((FX_DWORD)unicode < 0x80) {
+ nbytes = 1;
+ } else if ((FX_DWORD)unicode < 0x800) {
+ nbytes = 2;
+ } else if ((FX_DWORD)unicode < 0x10000) {
+ nbytes = 3;
+ } else if ((FX_DWORD)unicode < 0x200000) {
+ nbytes = 4;
+ } else if ((FX_DWORD)unicode < 0x4000000) {
+ nbytes = 5;
+ } else {
+ nbytes = 6;
+ }
+ iDstNum += nbytes;
+ }
+ return iDstNum;
+}
+FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const
+{
+ if (m_pStream == NULL) {
+ return 0;
+ }
+ FX_INT32 nSrcLen = m_pStart - m_pBuffer;
+ FX_INT32 nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen);
+ return m_iParsedBytes + nDstLen;
+}
+#ifdef _FDE_BLOCK_BUFFER
+void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch)
+{
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ if (m_iEntityStart > -1 && ch == L';') {
+ CFX_WideString csEntity;
+ m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, (m_iDataLength - 1) - m_iEntityStart - 1);
+ FX_INT32 iLen = csEntity.GetLength();
+ if (iLen > 0) {
+ if (csEntity[0] == L'#') {
+ ch = 0;
+ FX_WCHAR w;
+ if (iLen > 1 && csEntity[1] == L'x') {
+ for (FX_INT32 i = 2; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w >= L'0' && w <= L'9') {
+ ch = (ch << 4) + w - L'0';
+ } else if (w >= L'A' && w <= L'F') {
+ ch = (ch << 4) + w - 55;
+ } else if (w >= L'a' && w <= L'f') {
+ ch = (ch << 4) + w - 87;
+ } else {
+ break;
+ }
+ }
+ } else {
+ for (FX_INT32 i = 1; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w < L'0' || w > L'9') {
+ break;
+ }
+ ch = ch * 10 + w - L'0';
+ }
+ }
+ if (ch != 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, ch);
+ m_iEntityStart ++;
+ }
+ } else {
+ if (csEntity.Compare(L"amp") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'&');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"lt") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'<');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"gt") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'>');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"apos") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'\'');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"quot") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"');
+ m_iEntityStart ++;
+ }
+ }
+ }
+ m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE);
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_iEntityStart = -1;
+ } else {
+ if (m_iEntityStart < 0 && ch == L'&') {
+ m_iEntityStart = m_iDataLength - 1;
+ }
+ }
+ m_pStart ++;
+}
+#else
+void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch)
+{
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos] = ch;
+ if (m_iEntityStart > -1 && ch == L';') {
+ CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, m_iDataPos - m_iEntityStart - 1);
+ FX_INT32 iLen = csEntity.GetLength();
+ if (iLen > 0) {
+ if (csEntity[0] == L'#') {
+ ch = 0;
+ FX_WCHAR w;
+ if (iLen > 1 && csEntity[1] == L'x') {
+ for (FX_INT32 i = 2; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w >= L'0' && w <= L'9') {
+ ch = (ch << 4) + w - L'0';
+ } else if (w >= L'A' && w <= L'F') {
+ ch = (ch << 4) + w - 55;
+ } else if (w >= L'a' && w <= L'f') {
+ ch = (ch << 4) + w - 87;
+ } else {
+ break;
+ }
+ }
+ } else {
+ for (FX_INT32 i = 1; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w < L'0' || w > L'9') {
+ break;
+ }
+ ch = ch * 10 + w - L'0';
+ }
+ }
+ if (ch != 0) {
+ m_pwsTextData[m_iEntityStart ++] = ch;
+ }
+ } else {
+ if (csEntity.Compare(L"amp") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'&';
+ } else if (csEntity.Compare(L"lt") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'<';
+ } else if (csEntity.Compare(L"gt") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'>';
+ } else if (csEntity.Compare(L"apos") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'\'';
+ } else if (csEntity.Compare(L"quot") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'\"';
+ }
+ }
+ }
+ m_iDataPos = m_iEntityStart;
+ m_iEntityStart = -1;
+ } else {
+ if (m_iEntityStart < 0 && ch == L'&') {
+ m_iEntityStart = m_iDataPos;
+ }
+ m_iDataPos ++;
+ }
+ m_pStart ++;
+}
+void CFDE_XMLSyntaxParser::ReallocTextDataBuffer()
+{
+ FXSYS_assert(m_pwsTextData != NULL);
+ if (m_iTextDataSize <= 1024 * 1024) {
+ m_iTextDataSize *= 2;
+ } else {
+ m_iTextDataSize += 1024 * 1024;
+ }
+ m_pwsTextData = (FX_LPWSTR)FDE_Realloc(m_pwsTextData, m_iTextDataSize * sizeof(FX_WCHAR));
+}
+void CFDE_XMLSyntaxParser::GetData(CFX_WideString &wsData) const
+{
+ FX_LPWSTR pBuf = wsData.GetBuffer(m_iTextDataLength);
+ FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR));
+ wsData.ReleaseBuffer(m_iTextDataLength);
+}
+#endif
diff --git a/xfa/src/fdp/src/xml/fde_xml.h b/xfa/src/fdp/src/xml/fde_xml.h
new file mode 100644
index 0000000000..edbf01584a
--- /dev/null
+++ b/xfa/src/fdp/src/xml/fde_xml.h
@@ -0,0 +1,443 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_XML_IMP
+#define _FDE_XML_IMP
+#define _FDE_BLOCK_BUFFER
+#ifdef _FDE_BLOCK_BUFFER
+class CFDE_BlockBuffer;
+#endif
+class CFDE_XMLNode;
+class CFDE_XMLInstruction;
+class CFDE_XMLElement;
+class CFDE_XMLText;
+class CFDE_XMLDoc;
+class IFDE_XMLParser;
+class CFDE_XMLDOMParser;
+class CFDE_XMLSAXParser;
+class CFDE_XMLSyntaxParser;
+class CFDE_XMLNode : public CFX_Target
+{
+public:
+ CFDE_XMLNode();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Unknown;
+ }
+ virtual FX_INT32 CountChildNodes() const;
+ virtual CFDE_XMLNode* GetChildNode(FX_INT32 index) const;
+ virtual FX_INT32 GetChildNodeIndex(CFDE_XMLNode *pNode) const;
+ virtual CFDE_XMLNode* GetPath(FX_LPCWSTR pPath, FX_INT32 iLength = -1, FX_BOOL bQualifiedName = TRUE) const;
+ virtual FX_INT32 InsertChildNode(CFDE_XMLNode *pNode, FX_INT32 index = -1);
+ virtual void RemoveChildNode(CFDE_XMLNode *pNode);
+ virtual void DeleteChildren();
+ virtual CFDE_XMLNode* GetNodeItem(IFDE_XMLNode::NodeItem eItem) const;
+ virtual FX_INT32 GetNodeLevel() const;
+ virtual FX_BOOL InsertNodeItem(IFDE_XMLNode::NodeItem eItem, CFDE_XMLNode *pNode);
+ virtual CFDE_XMLNode* RemoveNodeItem(IFDE_XMLNode::NodeItem eItem);
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream);
+public:
+ ~CFDE_XMLNode();
+ void CloneChildren(CFDE_XMLNode* pClone);
+ CFDE_XMLNode *m_pParent;
+ CFDE_XMLNode *m_pChild;
+ CFDE_XMLNode *m_pPrior;
+ CFDE_XMLNode *m_pNext;
+};
+class CFDE_XMLInstruction : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLInstruction(const CFX_WideString &wsTarget);
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Instruction;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetTargetName(CFX_WideString &wsTarget) const
+ {
+ wsTarget = m_wsTarget;
+ }
+ virtual FX_INT32 CountAttributes() const;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue);
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue);
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue);
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName);
+ virtual FX_INT32 CountData() const;
+ virtual FX_BOOL GetData(FX_INT32 index, CFX_WideString &wsData) const;
+ virtual void AppendData(const CFX_WideString &wsData);
+ virtual void RemoveData(FX_INT32 index);
+public:
+ ~CFDE_XMLInstruction() {}
+ CFX_WideString m_wsTarget;
+ CFX_WideStringArray m_Attributes;
+ CFX_WideStringArray m_TargetData;
+};
+class CFDE_XMLElement : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLElement(const CFX_WideString &wsTag);
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Element;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetTagName(CFX_WideString &wsTag) const;
+ virtual void GetLocalTagName(CFX_WideString &wsTag) const;
+ virtual void GetNamespacePrefix(CFX_WideString &wsPrefix) const;
+ virtual void GetNamespaceURI(CFX_WideString &wsNamespace) const;
+ virtual FX_INT32 CountAttributes() const;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue);
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue);
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue);
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName);
+ virtual void GetTextData(CFX_WideString &wsText) const;
+ virtual void SetTextData(const CFX_WideString &wsText);
+public:
+ ~CFDE_XMLElement();
+ CFX_WideString m_wsTag;
+ CFX_WideStringArray m_Attributes;
+};
+class CFDE_XMLText : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLText(const CFX_WideString &wsText);
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Text;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetText(CFX_WideString &wsText) const
+ {
+ wsText = m_wsText;
+ }
+ virtual void SetText(const CFX_WideString &wsText)
+ {
+ m_wsText = wsText;
+ }
+public:
+ ~CFDE_XMLText() {}
+ CFX_WideString m_wsText;
+};
+class CFDE_XMLDeclaration : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLDeclaration() : CFDE_XMLNode() { }
+};
+class CFDE_XMLCharData : public CFDE_XMLDeclaration
+{
+public:
+ CFDE_XMLCharData(const CFX_WideString &wsCData);
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_CharData;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetCharData(CFX_WideString &wsCharData) const
+ {
+ wsCharData = m_wsCharData;
+ }
+ virtual void SetCharData(const CFX_WideString &wsCData)
+ {
+ m_wsCharData = wsCData;
+ }
+
+public:
+ ~CFDE_XMLCharData() {}
+
+ CFX_WideString m_wsCharData;
+};
+class CFDE_XMLDoc : public CFX_Target
+{
+public:
+ CFDE_XMLDoc();
+ ~CFDE_XMLDoc();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_BOOL LoadXML(IFX_Stream *pXMLStream, FX_INT32 iXMLPlaneSize = 8192, FX_INT32 iTextDataSize = 256, FDE_LPXMLREADERHANDLER pHandler = NULL);
+ virtual FX_BOOL LoadXML(IFDE_XMLParser *pXMLParser);
+ virtual FX_INT32 DoLoad(IFX_Pause *pPause = NULL);
+ virtual void CloseXML();
+ virtual CFDE_XMLNode* GetRoot() const
+ {
+ return m_pRoot;
+ }
+ virtual void SaveXML(IFX_Stream *pXMLStream = NULL, FX_BOOL bSaveBOM = TRUE);
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream, IFDE_XMLNode *pNode);
+protected:
+ IFX_Stream *m_pStream;
+ FX_INT32 m_iStatus;
+ CFDE_XMLNode *m_pRoot;
+ IFDE_XMLSyntaxParser *m_pSyntaxParser;
+ IFDE_XMLParser *m_pXMLParser;
+ void Reset(FX_BOOL bInitRoot);
+ void ReleaseParser();
+};
+typedef CFX_StackTemplate<CFDE_XMLNode*> CFDE_XMLDOMNodeStack;
+class CFDE_XMLDOMParser : public IFDE_XMLParser, public CFX_Target
+{
+public:
+ CFDE_XMLDOMParser(CFDE_XMLNode *pRoot, IFDE_XMLSyntaxParser *pParser);
+ ~CFDE_XMLDOMParser();
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 DoParser(IFX_Pause *pPause);
+private:
+ CFDE_XMLNode *m_pRoot;
+ IFDE_XMLSyntaxParser *m_pParser;
+ CFDE_XMLNode *m_pParent;
+ CFDE_XMLNode *m_pChild;
+ CFDE_XMLDOMNodeStack m_NodeStack;
+ CFX_WideString m_ws1;
+ CFX_WideString m_ws2;
+};
+class CFDE_XMLTAG : public CFX_Target
+{
+public:
+ CFDE_XMLTAG() : eType(FDE_XMLNODE_Unknown) {}
+ CFDE_XMLTAG(const CFDE_XMLTAG &src) : wsTagName(src.wsTagName), eType(src.eType) {}
+ CFX_WideString wsTagName;
+ FDE_XMLNODETYPE eType;
+};
+typedef CFX_ObjectStackTemplate<CFDE_XMLTAG> CFDE_XMLTagStack;
+class CFDE_XMLSAXParser : public IFDE_XMLParser, public CFX_Target
+{
+public:
+ CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, IFDE_XMLSyntaxParser *pParser);
+ ~CFDE_XMLSAXParser();
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 DoParser(IFX_Pause *pPause);
+private:
+ void Push(const CFDE_XMLTAG &xmlTag);
+ void Pop();
+ FDE_LPXMLREADERHANDLER m_pHandler;
+ IFDE_XMLSyntaxParser *m_pParser;
+ CFDE_XMLTagStack m_TagStack;
+ CFDE_XMLTAG *m_pTagTop;
+ CFX_WideString m_ws1;
+ CFX_WideString m_ws2;
+};
+#ifdef _FDE_BLOCK_BUFFER
+class CFDE_BlockBuffer : public CFX_Target
+{
+public:
+ CFDE_BlockBuffer(FX_INT32 iAllocStep = 1024 * 1024);
+ ~CFDE_BlockBuffer();
+
+ FX_BOOL InitBuffer(FX_INT32 iBufferSize = 1024 * 1024);
+ FX_BOOL IsInitialized()
+ {
+ return m_iBufferSize / m_iAllocStep >= 1;
+ }
+ void ReleaseBuffer()
+ {
+ FDE_Delete this;
+ }
+ FX_LPWSTR GetAvailableBlock(FX_INT32& iIndexInBlock);
+ inline FX_INT32 GetAllocStep() const
+ {
+ return m_iAllocStep;
+ }
+ inline FX_INT32& GetDataLengthRef()
+ {
+ return m_iDataLength;
+ }
+ inline void Reset(FX_BOOL bReserveData = TRUE)
+ {
+ if (!bReserveData) {
+ m_iStartPosition = 0;
+ }
+ m_iDataLength = 0;
+ }
+ void SetTextChar(FX_INT32 iIndex, FX_WCHAR ch);
+ FX_INT32 DeleteTextChars(FX_INT32 iCount, FX_BOOL bDirection = TRUE);
+ void GetTextData(CFX_WideString& wsTextData, FX_INT32 iStart = 0, FX_INT32 iLength = -1) const;
+
+protected:
+ inline void TextDataIndex2BufIndex(const FX_INT32 iIndex, FX_INT32& iBlockIndex, FX_INT32& iInnerIndex) const;
+ void ClearBuffer();
+ CFX_PtrArray m_BlockArray;
+ FX_INT32 m_iDataLength;
+ FX_INT32 m_iBufferSize;
+ FX_INT32 m_iAllocStep;
+ FX_INT32 m_iStartPosition;
+};
+#endif
+#define FDE_XMLSYNTAXMODE_Text 0
+#define FDE_XMLSYNTAXMODE_Node 1
+#define FDE_XMLSYNTAXMODE_Target 2
+#define FDE_XMLSYNTAXMODE_Tag 3
+#define FDE_XMLSYNTAXMODE_AttriName 4
+#define FDE_XMLSYNTAXMODE_AttriEqualSign 5
+#define FDE_XMLSYNTAXMODE_AttriQuotation 6
+#define FDE_XMLSYNTAXMODE_AttriValue 7
+#define FDE_XMLSYNTAXMODE_Entity 8
+#define FDE_XMLSYNTAXMODE_EntityDecimal 9
+#define FDE_XMLSYNTAXMODE_EntityHex 10
+#define FDE_XMLSYNTAXMODE_CloseInstruction 11
+#define FDE_XMLSYNTAXMODE_BreakElement 12
+#define FDE_XMLSYNTAXMODE_CloseElement 13
+#define FDE_XMLSYNTAXMODE_SkipDeclNode 14
+#define FDE_XMLSYNTAXMODE_DeclCharData 15
+#define FDE_XMLSYNTAXMODE_SkipComment 16
+#define FDE_XMLSYNTAXMODE_SkipCommentOrDecl 17
+#define FDE_XMLSYNTAXMODE_TargetData 18
+class CFDE_XMLSyntaxParser : public IFDE_XMLSyntaxParser, public CFX_Target
+{
+public:
+ CFDE_XMLSyntaxParser();
+ ~CFDE_XMLSyntaxParser();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual void Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize = 256);
+ virtual FX_DWORD DoSyntaxParse();
+ virtual FX_INT32 GetStatus() const;
+ virtual FX_INT32 GetCurrentPos() const
+ {
+ return m_iParsedChars + (m_pStart - m_pBuffer);
+ }
+ virtual FX_FILESIZE GetCurrentBinaryPos() const;
+ virtual FX_INT32 GetCurrentNodeNumber() const
+ {
+ return m_iCurrentNodeNum;
+ }
+ virtual FX_INT32 GetLastNodeNumber() const
+ {
+ return m_iLastNodeNum;
+ }
+#ifdef _FDE_BLOCK_BUFFER
+ virtual void GetTargetName(CFX_WideString &wsTarget) const
+ {
+ m_BlockBuffer.GetTextData(wsTarget, 0, m_iTextDataLength);
+ }
+ virtual void GetTagName(CFX_WideString &wsTag) const
+ {
+ m_BlockBuffer.GetTextData(wsTag, 0, m_iTextDataLength);
+ }
+ virtual void GetAttributeName(CFX_WideString &wsAttriName) const
+ {
+ m_BlockBuffer.GetTextData(wsAttriName, 0, m_iTextDataLength);
+ }
+ virtual void GetAttributeValue(CFX_WideString &wsAttriValue) const
+ {
+ m_BlockBuffer.GetTextData(wsAttriValue, 0, m_iTextDataLength);
+ }
+ virtual void GetTextData(CFX_WideString &wsText) const
+ {
+ m_BlockBuffer.GetTextData(wsText, 0, m_iTextDataLength);
+ }
+ virtual void GetTargetData(CFX_WideString &wsData) const
+ {
+ m_BlockBuffer.GetTextData(wsData, 0, m_iTextDataLength);
+ }
+#else
+ virtual void GetTargetName(CFX_WideString &wsTarget) const
+ {
+ GetData(wsTarget);
+ }
+ virtual void GetTagName(CFX_WideString &wsTag) const
+ {
+ GetData(wsTag);
+ }
+ virtual void GetAttributeName(CFX_WideString &wsAttriName) const
+ {
+ GetData(wsAttriName);
+ }
+ virtual void GetAttributeValue(CFX_WideString &wsAttriValue) const
+ {
+ GetData(wsAttriValue);
+ }
+ virtual void GetTextData(CFX_WideString &wsText) const
+ {
+ GetData(wsText);
+ }
+ virtual void GetTargetData(CFX_WideString &wsData) const
+ {
+ GetData(wsData);
+ }
+#endif
+protected:
+ IFX_Stream *m_pStream;
+ FX_INT32 m_iXMLPlaneSize;
+ FX_INT32 m_iCurrentPos;
+ FX_INT32 m_iCurrentNodeNum;
+ FX_INT32 m_iLastNodeNum;
+ FX_INT32 m_iParsedChars;
+ FX_INT32 m_iParsedBytes;
+ FX_LPWSTR m_pBuffer;
+ FX_INT32 m_iBufferChars;
+ FX_BOOL m_bEOS;
+ FX_LPWSTR m_pStart;
+ FX_LPWSTR m_pEnd;
+ FDE_XMLNODE m_CurNode;
+ CFDE_XMLNodeStack m_XMLNodeStack;
+#ifdef _FDE_BLOCK_BUFFER
+ CFDE_BlockBuffer m_BlockBuffer;
+ FX_INT32 m_iAllocStep;
+ FX_INT32& m_iDataLength;
+ FX_LPWSTR m_pCurrentBlock;
+ FX_INT32 m_iIndexInBlock;
+#else
+ FX_INT32 m_iTextDataSize;
+ FX_LPWSTR m_pwsTextData;
+ FX_INT32 m_iDataPos;
+#endif
+ FX_INT32 m_iTextDataLength;
+ FX_DWORD m_dwStatus;
+ FX_DWORD m_dwMode;
+ FX_WCHAR m_wQuotationMark;
+ FX_INT32 m_iEntityStart;
+ CFX_DWordStack m_SkipStack;
+ FX_WCHAR m_SkipChar;
+ inline void ParseTextChar(FX_WCHAR ch);
+#ifndef _FDE_BLOCK_BUFFER
+ void ReallocTextDataBuffer();
+ void GetData(CFX_WideString &wsData) const;
+#endif
+};
+#endif
diff --git a/xfa/src/fee/include/fx_wordbreak.h b/xfa/src/fee/include/fx_wordbreak.h
new file mode 100644
index 0000000000..c91aca694a
--- /dev/null
+++ b/xfa/src/fee/include/fx_wordbreak.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_WORDBREAK_H
+#define _FX_WORDBREAK_H
+class IFX_CharIter;
+class IFX_WordBreak
+{
+public:
+ virtual void Release() = 0;
+ virtual void Attach(IFX_CharIter * pIter) = 0;
+ virtual void Attach(const CFX_WideString & wsText) = 0;
+ virtual FX_BOOL Next(FX_BOOL bPrev) = 0;
+ virtual void SetAt(FX_INT32 nIndex) = 0;
+ virtual FX_INT32 GetWordPos() const = 0;
+ virtual FX_INT32 GetWordLength() const = 0;
+ virtual void GetWord(CFX_WideString &wsWord) const = 0;
+ virtual FX_BOOL IsEOF(FX_BOOL bTail = TRUE) const = 0;
+};
+IFX_WordBreak * FX_WordBreak_Create();
+#endif
diff --git a/xfa/src/fee/include/ifde_txtedtbuf.h b/xfa/src/fee/include/ifde_txtedtbuf.h
new file mode 100644
index 0000000000..6cfc3ec977
--- /dev/null
+++ b/xfa/src/fee/include/ifde_txtedtbuf.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _IFDE_TXTEDTBUF_H
+#define _IFDE_TXTEDTBUF_H
+#define FDE_DEFCHUNKLENGTH (1024)
+class IFDE_TxtEdtBuf;
+class IFDE_TxtEdtBuf
+{
+public:
+ virtual void Release() = 0;
+
+ virtual FX_BOOL SetChunkSize(FX_INT32 nChunkSize) = 0;
+ virtual FX_INT32 GetChunkSize() const = 0;
+ virtual FX_INT32 GetTextLength() const = 0;
+ virtual void SetText(const CFX_WideString &wsText) = 0;
+ virtual void GetText(CFX_WideString &wsText) const = 0;
+ virtual FX_WCHAR GetCharByIndex(FX_INT32 nIndex) const = 0;
+ virtual void GetRange(CFX_WideString &wsText, FX_INT32 nBegin, FX_INT32 nCount = - 1) const = 0;
+
+ virtual void Insert(FX_INT32 nPos, FX_LPCWSTR lpText, FX_INT32 nLength = 1) = 0;
+ virtual void Delete(FX_INT32 nIndex, FX_INT32 nLength = 1) = 0;
+
+ virtual void Clear(FX_BOOL bRelease = TRUE) = 0;
+
+ virtual FX_BOOL Optimize(IFX_Pause * pPause = NULL) = 0;
+};
+#endif
diff --git a/xfa/src/fee/include/ifde_txtedtengine.h b/xfa/src/fee/include/ifde_txtedtengine.h
new file mode 100644
index 0000000000..a47739c3c5
--- /dev/null
+++ b/xfa/src/fee/include/ifde_txtedtengine.h
@@ -0,0 +1,233 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _IFDE_TXTEDTENGINE_H
+#define _IFDE_TXTEDTENGINE_H
+class IFDE_TxtEdtBuf;
+class IFDE_TxtEdtPage;
+class IFDE_TxtEdtEngine;
+class IFDE_TxtEdtEventSink;
+class IFDE_TxtEdtParag;
+#define FDE_TXTEDT_FIND_FLAGS_Prev (0L << 0)
+#define FDE_TXTEDT_FIND_FLAGS_Next (1L << 0)
+#define FDE_TXTEDT_FIND_FLAGS_WholeWord (1L << 1)
+#define FDE_TXTEDT_FIND_FLAGS_NoCase (1L << 2)
+typedef struct _FDE_HTXTEDTFIND {
+ FX_LPVOID pData;
+} * FDE_HTXTEDTFIND;
+#define FDE_TEXTEDITMODE_MultiLines (1L << 0)
+#define FDE_TEXTEDITMODE_AutoLineWrap (1L << 1)
+#define FDE_TEXTEDITMODE_ReadOnly (1L << 2)
+#define FDE_TEXTEDITMODE_LimitArea_Vert (1L << 3)
+#define FDE_TEXTEDITMODE_LimitArea_Horz (1L << 4)
+#define FDE_TEXTEDITMODE_NoRedoUndo (1L << 5)
+#define FDE_TEXTEDITMODE_FIELD_TAB (1L << 6)
+#define FDE_TEXTEDITMODE_FIELD_AUTO (1L << 7)
+#define FDE_TEXTEDITMODE_Validate (1L << 8)
+#define FDE_TEXTEDITMODE_Password (1L << 9)
+#define FDE_TEXTEDITALIGN_Left (0L << 0)
+#define FDE_TEXTEDITALIGN_Center (1L << 0)
+#define FDE_TEXTEDITALIGN_Right (2L << 0)
+#define FDE_TEXTEDITALIGN_Normal (1L << 3)
+#define FDE_TEXTEDITALIGN_Justified (1L << 4)
+#define FDE_TEXTEDITALIGN_Distributed (1L << 5)
+#define FDE_TEXTEDITLAYOUT_DocVertical (1L << 0)
+#define FDE_TEXTEDITLAYOUT_CharVertial (1L << 1)
+#define FDE_TEXTEDITLAYOUT_LineReserve (1L << 2)
+#define FDE_TEXTEDITLAYOUT_RTL (1L << 3)
+#define FDE_TEXTEDITLAYOUT_CombText (1L << 4)
+#define FDE_TEXTEDITLAYOUT_ExpandTab (1L << 5)
+#define FDE_TEXTEDITLAYOUT_ArabicContext (1L << 6)
+#define FDE_TEXTEDITLAYOUT_ArabicShapes (1L << 7)
+#define FDE_TEXTEDITLAYOUT_LastLineHeight (1L << 8)
+enum FDE_TXTEDTMOVECARET {
+ MC_MoveNone = 0 ,
+ MC_Left ,
+ MC_Right ,
+ MC_Up ,
+ MC_Down ,
+ MC_WordBackward ,
+ MC_WordForward ,
+ MC_LineStart ,
+ MC_LineEnd ,
+ MC_ParagStart ,
+ MC_ParagEnd ,
+ MC_PageUp ,
+ MC_PageDown ,
+ MC_Home ,
+ MC_End ,
+};
+enum FDE_TXTEDT_MODIFY_RET {
+ FDE_TXTEDT_MODIFY_RET_F_Tab = -6,
+ FDE_TXTEDT_MODIFY_RET_F_Locked = -5,
+ FDE_TXTEDT_MODIFY_RET_F_Invalidate = -4,
+ FDE_TXTEDT_MODIFY_RET_F_Boundary = -3,
+ FDE_TXTEDT_MODIFY_RET_F_Full = -2,
+ FDE_TXTEDT_MODIFY_RET_F_Normal = -1,
+ FDE_TXTEDT_MODIFY_RET_S_Normal = 0,
+ FDE_TXTEDT_MODIFY_RET_S_Full = 1,
+ FDE_TXTEDT_MODIFY_RET_S_Part = 2,
+ FDE_TXTEDT_MODIFY_RET_S_Empty = 3,
+ FDE_TXTEDT_MODIFY_RET_T_Tab = 4,
+};
+enum FDE_TXTEDIT_LINEEND {
+ FDE_TXTEDIT_LINEEND_Auto,
+ FDE_TXTEDIT_LINEEND_CRLF,
+ FDE_TXTEDIT_LINEEND_CR,
+ FDE_TXTEDIT_LINEEND_LF,
+};
+struct _FDE_TXTEDTPARAMS : public CFX_Object {
+ _FDE_TXTEDTPARAMS()
+ : fPlateWidth(0)
+ , fPlateHeight(0)
+ , nLineCount(0)
+ , dwLayoutStyles(0)
+ , dwAlignment(0)
+ , dwMode(0)
+ , pFont(NULL)
+ , fFontSize(10.0f)
+ , dwFontColor(0xff000000)
+ , fLineSpace(10.0f)
+ , fTabWidth(36)
+ , bTabEquidistant(FALSE)
+ , wDefChar(0xFEFF)
+ , wLineBreakChar('\n')
+ , nCharRotation(0)
+ , nLineEnd(0)
+ , nHorzScale(100)
+ , fCharSpace(0)
+ , pEventSink(NULL)
+ {
+ }
+ FX_FLOAT fPlateWidth;
+ FX_FLOAT fPlateHeight;
+ FX_INT32 nLineCount;
+ FX_DWORD dwLayoutStyles;
+ FX_DWORD dwAlignment;
+ FX_DWORD dwMode;
+ IFX_Font *pFont;
+ FX_FLOAT fFontSize;
+ FX_ARGB dwFontColor;
+ FX_FLOAT fLineSpace;
+ FX_FLOAT fTabWidth;
+ FX_BOOL bTabEquidistant;
+ FX_WCHAR wDefChar;
+ FX_WCHAR wLineBreakChar;
+ FX_INT32 nCharRotation;
+ FX_INT32 nLineEnd;
+ FX_INT32 nHorzScale;
+ FX_FLOAT fCharSpace;
+ IFDE_TxtEdtEventSink * pEventSink;
+};
+typedef _FDE_TXTEDTPARAMS FDE_TXTEDTPARAMS;
+typedef _FDE_TXTEDTPARAMS* FDE_LPTXTEDTPARAMS;
+enum FDE_TXTEDT_TEXTCHANGE_TYPE {
+ FDE_TXTEDT_TEXTCHANGE_TYPE_Insert = 0 ,
+ FDE_TXTEDT_TEXTCHANGE_TYPE_Delete ,
+ FDE_TXTEDT_TEXTCHANGE_TYPE_Replace ,
+};
+struct _FDE_TXTEDT_TEXTCHANGE_INFO : public CFX_Object {
+ FX_INT32 nChangeType;
+ CFX_WideString wsInsert;
+ CFX_WideString wsDelete;
+ CFX_WideString wsPrevText;
+};
+typedef _FDE_TXTEDT_TEXTCHANGE_INFO FDE_TXTEDT_TEXTCHANGE_INFO;
+typedef _FDE_TXTEDT_TEXTCHANGE_INFO* FDE_LPTXTEDT_TEXTCHANGE_INFO;
+class IFDE_TxtEdtEventSink
+{
+public:
+ virtual void On_CaretChanged(IFDE_TxtEdtEngine * pEdit, FX_INT32 nPage, FX_BOOL bVisible = TRUE) = 0;
+ virtual void On_TextChanged(IFDE_TxtEdtEngine * pEdit, FDE_TXTEDT_TEXTCHANGE_INFO &ChangeInfo) = 0;
+ virtual void On_PageCountChanged(IFDE_TxtEdtEngine * pEdit) = 0;
+ virtual void On_SelChanged(IFDE_TxtEdtEngine * pEdit) = 0;
+ virtual FX_BOOL On_PageLoad(IFDE_TxtEdtEngine * pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose) = 0;
+ virtual FX_BOOL On_PageUnload(IFDE_TxtEdtEngine * pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose) = 0;
+ virtual FX_BOOL On_PageChange(IFDE_TxtEdtEngine * pEdit, FX_INT32 nPageIndex) = 0;
+ virtual void On_AddDoRecord(IFDE_TxtEdtEngine * pEdit, FX_BSTR bsDoRecord) = 0;
+ virtual FX_BOOL On_ValidateField(IFDE_TxtEdtEngine * pEdit, FX_INT32 nBlockIndex, FX_INT32 nFieldIndex, \
+ const CFX_WideString &wsFieldText, FX_INT32 nCharIndex) = 0;
+ virtual FX_BOOL On_ValidateBlock(IFDE_TxtEdtEngine * pEdit, FX_INT32 nBlockIndex) = 0;
+ virtual FX_BOOL On_GetBlockFormatText(IFDE_TxtEdtEngine * pEdit, FX_INT32 nBlockIndex, CFX_WideString &wsBlockText) = 0;
+ virtual FX_BOOL On_Validate(IFDE_TxtEdtEngine * pEdit, CFX_WideString &wsText) = 0;
+};
+class IFX_CharIter
+{
+public:
+ virtual void Release() = 0;
+ virtual FX_BOOL Next(FX_BOOL bPrev = FALSE) = 0;
+ virtual FX_WCHAR GetChar() = 0;
+ virtual void SetAt(FX_INT32 nIndex) = 0;
+ virtual FX_INT32 GetAt() const = 0;
+ virtual FX_BOOL IsEOF(FX_BOOL bTail = TRUE) const = 0;
+ virtual IFX_CharIter * Clone() = 0;
+};
+class IFDE_TxtEdtEngine
+{
+public:
+ static IFDE_TxtEdtEngine* Create();
+
+ virtual void Release() = 0;
+ virtual void SetEditParams(const FDE_TXTEDTPARAMS &params) = 0;
+ virtual const FDE_TXTEDTPARAMS* GetEditParams() const = 0;
+
+ virtual FX_INT32 CountPages() const = 0;
+ virtual IFDE_TxtEdtPage* GetPage(FX_INT32 nIndex) = 0;
+ virtual FX_BOOL SetBufChunkSize(FX_INT32 nChunkSize) = 0;
+ virtual void SetTextByStream(IFX_Stream * pStream) = 0;
+ virtual void SetText(const CFX_WideString &wsText) = 0;
+ virtual FX_INT32 GetTextLength() const = 0;
+ virtual void GetText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount = -1) = 0;
+ virtual void ClearText() = 0;
+
+ virtual FX_INT32 GetCaretRect(CFX_RectF &rtCaret) const = 0;
+ virtual FX_INT32 GetCaretPos() const = 0;
+ virtual FX_INT32 SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore = TRUE) = 0;
+ virtual FX_INT32 MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret, FX_BOOL bShift = FALSE, FX_BOOL bCtrl = FALSE) = 0;
+
+ virtual void Lock() = 0;
+ virtual void Unlock() = 0;
+ virtual FX_BOOL IsLocked() const = 0;
+
+ virtual FX_INT32 Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLength) = 0;
+ virtual FX_INT32 Delete(FX_INT32 nStart, FX_BOOL bBackspace = FALSE) = 0;
+ virtual FX_INT32 DeleteRange(FX_INT32 nStart, FX_INT32 nCount = -1) = 0;
+ virtual FX_INT32 Replace(FX_INT32 nStart, FX_INT32 nLength, const CFX_WideString &wsReplace) = 0;
+ virtual void SetLimit(FX_INT32 nLimit) = 0;
+ virtual void SetAliasChar(FX_WCHAR wAlias) = 0;
+ virtual void SetFormatBlock(FX_INT32 nIndex, const CFX_WideString &wsBlockFormat) = 0;
+ virtual FX_INT32 CountEditBlocks() const = 0;
+ virtual void GetEditBlockText(FX_INT32 nIndex, CFX_WideString &wsBlockText) const = 0;
+ virtual FX_INT32 CountEditFields(FX_INT32 nBlockIndex) const = 0;
+ virtual void GetEditFieldText(FX_INT32 nBlockIndex, FX_INT32 nFieldIndex, CFX_WideString &wsFieldText) const = 0;
+ virtual void StartEdit() = 0;
+ virtual void EndEdit() = 0;
+ virtual void AddSelRange(FX_INT32 nStart, FX_INT32 nCount = -1) = 0;
+ virtual FX_INT32 CountSelRanges() = 0;
+ virtual FX_INT32 GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart) = 0;
+ virtual void ClearSelection() = 0;
+
+ virtual FX_BOOL Redo(FX_BSTR bsRedo) = 0;
+ virtual FX_BOOL Undo(FX_BSTR bsUndo) = 0;
+
+ virtual FX_INT32 StartLayout() = 0;
+ virtual FX_INT32 DoLayout(IFX_Pause *pPause) = 0;
+ virtual void EndLayout() = 0;
+
+ virtual FX_BOOL Optimize(IFX_Pause * pPause = NULL) = 0;
+ virtual FX_INT32 CountParags() const = 0;
+ virtual IFDE_TxtEdtParag* GetParag(FX_INT32 nParagIndex) const = 0;
+ virtual IFX_CharIter* CreateCharIter() = 0;
+};
+class IFDE_TxtEdtParag
+{
+public:
+ virtual FX_INT32 GetTextLength() const = 0;
+ virtual FX_INT32 GetStartIndex() const = 0;
+ virtual FX_INT32 CountLines() const = 0;
+ virtual void GetLineRange(FX_INT32 nLineIndex, FX_INT32& nStart, FX_INT32& nCount) const = 0;
+};
+#endif
diff --git a/xfa/src/fee/include/ifde_txtedtpage.h b/xfa/src/fee/include/ifde_txtedtpage.h
new file mode 100644
index 0000000000..7555434f5f
--- /dev/null
+++ b/xfa/src/fee/include/ifde_txtedtpage.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _IFDE_TXTEDTPAGE_H
+#define _IFDE_TXTEDTPAGE_H
+class IFDE_TxtEdtEngine;
+class IFDE_TxtEdtPage;
+class IFDE_TxtEdtPage : public IFDE_CanvasSet, public IFX_TxtAccess
+{
+public:
+ static IFDE_TxtEdtPage * Create(IFDE_TxtEdtEngine * pEngine, FX_INT32 nIndex);
+
+ virtual void Release() = 0;
+
+ virtual IFDE_TxtEdtEngine * GetEngine() const = 0;
+ virtual FX_INT32 GetCharRect(FX_INT32 nIndex, CFX_RectF &rect, FX_BOOL bBBox = FALSE) const = 0;
+ virtual FX_INT32 GetCharIndex(const CFX_PointF &fPoint, FX_BOOL &bBefore) = 0;
+ virtual void CalcRangeRectArray(FX_INT32 nStart, FX_INT32 nCount, CFX_RectFArray &RectFArr) const = 0;
+ virtual FX_INT32 SelectWord (const CFX_PointF &fPoint, FX_INT32 &nCount) = 0;
+ virtual FX_INT32 GetCharStart() const = 0;
+ virtual FX_INT32 GetCharCount() const = 0;
+
+ virtual FX_INT32 GetDisplayPos(const CFX_RectF &rtClip, FXTEXT_CHARPOS* &pCharPos, FX_LPRECTF pBBox = NULL) const = 0;
+ virtual FX_BOOL IsLoaded(FX_LPCRECTF pClipBox = NULL) = 0;
+ virtual FX_INT32 LoadPage(FX_LPCRECTF pClipBox = NULL, IFX_Pause *pPause = NULL) = 0;
+ virtual void UnloadPage(FX_LPCRECTF pClipBox = NULL) = 0;
+ virtual const CFX_RectF& GetContentsBox() = 0;
+};
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtblock.cpp b/xfa/src/fee/src/fee/fde_txtedtblock.cpp
new file mode 100644
index 0000000000..89515bdb00
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtblock.cpp
@@ -0,0 +1,674 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_txtedtblock.h"
+#ifdef FDE_USEFORMATBLOCK
+#define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9
+#define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB
+#define FDE_TXTEDT_ZEROWIDTHSPACE 0x200B
+#define FDE_TXTEDT_ISINTEGER(a) ((a) >= L'0' && (a) <= L'9')
+#define FDE_TXTEDT_ISSIGN(a) (((a) == L'-') || ((a) == L'+'))
+CFDE_TxtEdtBlock::CFDE_TxtEdtBlock(CFDE_TxtEdtEngine * pEngine, const CFX_WideString &wsBlock, FX_INT32 nPosition)
+ : m_pEngine(pEngine)
+ , m_nDisplayLength(0)
+ , m_nIndex(0)
+ , m_nPosition(nPosition)
+{
+ FX_LPCWSTR lpBuf = FX_LPCWSTR(wsBlock);
+ FX_INT32 nCount = wsBlock.GetLength();
+ FX_INT32 i = 0;
+ CFX_WideString wsFix;
+ FX_INT32 j = 0;
+ while (i < nCount) {
+ if (lpBuf[i] != L'%') {
+ wsFix += lpBuf[i];
+ } else {
+ i ++;
+ if (i < nCount) {
+ if (lpBuf[i] == L'%') {
+ wsFix += lpBuf[i];
+ } else {
+ if (!wsFix.IsEmpty()) {
+ CFDE_TxtEdtField * pField = CFDE_TxtEdtField::Create(wsFix, j, this);
+ j ++;
+ FXSYS_assert(pField);
+ m_FieldArr.Add(pField);
+ m_nDisplayLength += pField->GetDisplayLength();
+ wsFix.Empty();
+ }
+ FX_INT32 nPos = i - 1;
+ while (lpBuf[i ++] != L')')
+ ;
+ i ++;
+ CFX_WideStringC wsField(lpBuf + nPos, i - nPos);
+ CFDE_TxtEdtField * pField = CFDE_TxtEdtField::Create(wsField, j, this);
+ j ++;
+ FXSYS_assert(pField);
+ m_FieldArr.Add(pField);
+ m_EditFieldArr.Add(pField);
+ m_nDisplayLength += pField->GetDisplayLength();
+ i --;
+ }
+ }
+ }
+ i ++;
+ }
+ if (!wsFix.IsEmpty()) {
+ CFDE_TxtEdtField * pField = CFDE_TxtEdtField::Create(wsFix, j, this);
+ FXSYS_assert(pField);
+ m_FieldArr.Add(pField);
+ m_nDisplayLength += pField->GetDisplayLength();
+ }
+}
+CFDE_TxtEdtBlock::~CFDE_TxtEdtBlock()
+{
+ FX_INT32 nCount = m_FieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFDE_TxtEdtField * pField = m_FieldArr[i];
+ pField->Release();
+ }
+ m_FieldArr.RemoveAll();
+}
+void CFDE_TxtEdtBlock::GetDisplayText(CFX_WideString &wsDisplay)
+{
+ FX_INT32 nCount = m_FieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFDE_TxtEdtField * pField = m_FieldArr[i];
+ CFX_WideString wsTemp;
+ pField->GetDisplayText(wsTemp);
+ wsDisplay += wsTemp;
+ }
+}
+FX_INT32 CFDE_TxtEdtBlock::GetLength() const
+{
+ FX_INT32 nDisplayLength = 0;
+ FX_INT32 nCount = m_FieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFDE_TxtEdtField * pField = m_FieldArr[i];
+ nDisplayLength += pField->GetDisplayLength();
+ }
+ return nDisplayLength;
+}
+void CFDE_TxtEdtBlock::GetBlockText(CFX_WideString &wsBlock)
+{
+ FX_INT32 nCount = m_FieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFDE_TxtEdtField * pField = m_FieldArr[i];
+ CFX_WideString wsTemp;
+ pField->GetFieldText(wsTemp);
+ wsBlock += wsTemp;
+ }
+}
+FX_INT32 CFDE_TxtEdtBlock::CountField() const
+{
+ return m_EditFieldArr.GetSize();
+}
+void CFDE_TxtEdtBlock::GetFieldText(FX_INT32 nIndex, CFX_WideString &wsField)
+{
+ CFDE_TxtEdtField * pField = m_EditFieldArr[nIndex];
+ pField->GetFieldText(wsField);
+}
+FX_INT32 CFDE_TxtEdtBlock::GetFieldTextLength() const
+{
+ FX_INT32 nTotalLength = 0;
+ FX_INT32 nCount = m_EditFieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFDE_TxtEdtField * pField = m_EditFieldArr[i];
+ nTotalLength = pField->GetFieldTextLength();
+ }
+ return nTotalLength;
+}
+FX_INT32 CFDE_TxtEdtBlock::GetPos() const
+{
+ return m_nPosition;
+}
+void CFDE_TxtEdtBlock::GetRealText(CFX_WideString &wsText) const
+{
+ FX_INT32 nCount = m_FieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFDE_TxtEdtField * pField = m_FieldArr[i];
+ CFX_WideString wsTemp;
+ pField->GetFieldText(wsTemp);
+ wsText += wsTemp;
+ }
+}
+void CFDE_TxtEdtBlock::Backup()
+{
+ FX_INT32 nCount = m_EditFieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ m_EditFieldArr[i]->Backup();
+ }
+}
+void CFDE_TxtEdtBlock::Restore()
+{
+ FX_INT32 nCount = m_EditFieldArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ m_EditFieldArr[i]->Restore();
+ }
+}
+CFDE_TxtEdtFieldFormatParser::CFDE_TxtEdtFieldFormatParser()
+{
+}
+CFDE_TxtEdtFieldFormatParser::~CFDE_TxtEdtFieldFormatParser()
+{
+ FDE_LPTXTEDTFORMATITEM lpItem = NULL;
+ FX_INT32 nCount = m_ItemArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ lpItem = m_ItemArr[i];
+ delete lpItem;
+ }
+ m_ItemArr.RemoveAll();
+}
+FX_BOOL CFDE_TxtEdtFieldFormatParser::Parse(const CFX_WideString &wsFormat)
+{
+ m_wsFormat = wsFormat;
+ FX_LPCWSTR pBuf = FX_LPCWSTR(m_wsFormat);
+ FX_INT32 nCount = m_wsFormat.GetLength();
+ nCount -= 2;
+ FX_INT32 i = 0;
+ for (; i < nCount; i ++) {
+ FX_WCHAR wChar = pBuf[i];
+ if (wChar == L'(') {
+ break;
+ }
+ }
+ i ++;
+ FDE_TXTEDTFORMATITEM FormatItem;
+ for (; i < nCount; i ++) {
+ while (pBuf[i] == L' ') {
+ i ++;
+ }
+ FormatItem.nKeyStart = i;
+ while (pBuf[i] != L':') {
+ i ++;
+ }
+ FormatItem.nKeyCount = i - FormatItem.nKeyStart;
+ i ++;
+ FormatItem.nValStart = i;
+ while (pBuf[i] != L';' && i < nCount) {
+ i ++;
+ }
+ FormatItem.nValCount = i - FormatItem.nValStart;
+ FDE_LPTXTEDTFORMATITEM pFormatItem = FX_NEW FDE_TXTEDTFORMATITEM;
+ FXSYS_memcpy(pFormatItem, &FormatItem, sizeof(FDE_TXTEDTFORMATITEM));
+ m_ItemArr.Add(pFormatItem);
+ }
+ return TRUE;
+}
+FX_INT32 CFDE_TxtEdtFieldFormatParser::CountItems() const
+{
+ return m_ItemArr.GetSize();
+}
+void CFDE_TxtEdtFieldFormatParser::GetItem(FX_INT32 nIndex, CFX_WideString &wsKey, CFX_WideString &wsValue) const
+{
+ FDE_LPTXTEDTFORMATITEM lpItem = m_ItemArr[nIndex];
+ FX_LPCWSTR lpSrcBuf = FX_LPCWSTR(m_wsFormat);
+ FX_LPWSTR lpDstBuf = wsKey.GetBuffer(lpItem->nKeyCount);
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf + lpItem->nKeyStart, lpItem->nKeyCount * sizeof(FX_WCHAR));
+ wsKey.ReleaseBuffer(lpItem->nKeyCount);
+ lpDstBuf = wsValue.GetBuffer(lpItem->nValCount);
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf + lpItem->nValStart, lpItem->nValCount * sizeof(FX_WCHAR));
+ wsValue.ReleaseBuffer(lpItem->nValCount);
+}
+CFDE_TxtEdtField * CFDE_TxtEdtField::Create(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock)
+{
+ if (wsField[0] != L'%' || (wsField[0] == L'%' && wsField[1] == L'%')) {
+ return FX_NEW CFDE_TxtEdtField_Fixed(wsField, nIndex, pBlock);
+ }
+ FX_WCHAR wcType = wsField[wsField.GetLength() - 1];
+ switch(wcType) {
+ case L'd':
+ return FX_NEW CFDE_TxtEdtField_Integer(wsField, nIndex, pBlock);
+ case L'f':
+ return FX_NEW CFDE_TxtEdtField_Float(wsField, nIndex, pBlock);
+ case L's':
+ return FX_NEW CFDE_TxtEdtField_String(wsField, nIndex, pBlock);
+ case L'p':
+ return FX_NEW CFDE_TxtEdtField_Password(wsField, nIndex, pBlock);
+ default:
+ break;
+ }
+ return NULL;
+}
+void CFDE_TxtEdtField::Release()
+{
+ delete this;
+}
+CFDE_TxtEdtField::CFDE_TxtEdtField(FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock)
+ : m_nLength(-1)
+ , m_wcFill(L' ')
+ , m_bReserveSpace(FALSE)
+ , m_bLeftAlignment(TRUE)
+ , m_nIndex(nIndex)
+ , m_pBlock(pBlock)
+{
+ FXSYS_assert(pBlock);
+}
+FX_INT32 CFDE_TxtEdtField::Insert(FX_INT32 nIndex, const CFX_WideString &wsIns,
+ FX_INT32 &nCaret, FX_BOOL &bBefore)
+{
+ FX_INT32 nFieldLength = m_wsField.GetLength();
+ FX_INT32 nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+ if (m_bReserveSpace && !m_bLeftAlignment) {
+ nInnerIndex -= (m_nLength - nFieldLength);
+ }
+ FXSYS_assert(nInnerIndex >= 0 && nInnerIndex <= nFieldLength);
+ CFX_WideString wsTemp = m_wsField;
+ FX_INT32 nInsLength = wsIns.GetLength();
+ for (FX_INT32 i = 0; i < nInsLength; i ++, nInnerIndex ++) {
+ wsTemp.Insert(nInnerIndex, wsIns[i]);
+ }
+ FX_INT32 nRet = Validate(wsTemp);
+ switch (nRet) {
+ case FDE_FORMAT_FIELD_VALIDATE_F_FULL:
+ return FDE_FORMAT_FIELD_INSERT_RET_F_FULL;
+ case FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE:
+ return FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE;
+ case FDE_FORMAT_FIELD_VALIDATE_S:
+ default:
+ break;
+ }
+ m_wsField = wsTemp;
+ nCaret = nIndex + ((m_bReserveSpace && !m_bLeftAlignment) ? -nInsLength : nInsLength);
+ bBefore = TRUE;
+ return (nFieldLength + nInsLength < m_nLength) ? FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL : FDE_FORMAT_FIELD_INSERT_RET_S_FULL;
+}
+FX_INT32 CFDE_TxtEdtField::Delete(FX_INT32 nIndex, FX_INT32 nCount,
+ CFX_WideString &wsDel, FX_INT32 &nCaret, FX_BOOL &bBefore)
+{
+ FX_INT32 nFieldLength = m_wsField.GetLength();
+ FX_INT32 nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+ if (m_bReserveSpace && !m_bLeftAlignment) {
+ nInnerIndex -= (m_nLength - nFieldLength);
+ }
+ if (nInnerIndex < 0 || (nInnerIndex + nCount) > nFieldLength) {
+ return FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY;
+ }
+ CFX_WideString wsTemp = m_wsField;
+ wsTemp.Delete(nInnerIndex, nCount);
+ FX_INT32 nRet = Validate(wsTemp);
+ switch (nRet) {
+ case FDE_FORMAT_FIELD_VALIDATE_F_FULL:
+ return FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY;
+ case FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE:
+ return FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE;
+ case FDE_FORMAT_FIELD_VALIDATE_S:
+ default:
+ break;
+ }
+ FX_LPWSTR lpBuf = wsDel.GetBuffer(nCount);
+ FXSYS_memcpy(lpBuf, FX_LPCWSTR(m_wsField) + nInnerIndex, nCount * sizeof(FX_WCHAR));
+ wsDel.ReleaseBuffer(nCount);
+ m_wsField = wsTemp;
+ nCaret = nIndex + (m_bReserveSpace && !m_bLeftAlignment) ? nCount : 0;
+ bBefore = TRUE;
+ return FDE_FORMAT_FIELD_DELETE_RET_S;
+}
+FX_INT32 CFDE_TxtEdtField::Replace(FX_INT32 nIndex, FX_INT32 nCount, const CFX_WideString &wsIns,
+ CFX_WideString &wsDel, FX_INT32 &nCaret, FX_BOOL &bBefore)
+{
+ FX_INT32 nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+ FX_INT32 nInsLength = wsIns.GetLength();
+ FX_INT32 nFieldLength = m_wsField.GetLength();
+ CFX_WideString wsTemp = m_wsField;
+ if (m_bReserveSpace && !m_bLeftAlignment) {
+ nInnerIndex -= (m_nLength - nFieldLength);
+ }
+ FXSYS_assert(nInnerIndex >= 0 && nInnerIndex <= nFieldLength);
+ if (nInnerIndex + nCount > nFieldLength) {
+ return FALSE;
+ }
+ wsTemp.Delete(nInnerIndex, nCount);
+ FX_INT32 nInnerIndexBK = nInnerIndex;
+ for (FX_INT32 i = 0; i < nInsLength; i ++, nInnerIndex ++) {
+ wsTemp.Insert(nInnerIndex, wsIns[i]);
+ }
+ FX_INT32 nRet = Validate(wsTemp);
+ switch(nRet) {
+ case FDE_FORMAT_FIELD_VALIDATE_F_FULL:
+ return FDE_FORMAT_FIELD_INSERT_RET_F_FULL;
+ case FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE:
+ return FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE;
+ default:
+ break;
+ }
+ FX_LPWSTR lpBuffer = wsDel.GetBuffer(nCount);
+ FX_LPCWSTR lpSrcBuf = FX_LPCWSTR(m_wsField);
+ FXSYS_memcpy(lpBuffer, lpSrcBuf + nInnerIndexBK, nCount * sizeof(FX_WCHAR));
+ wsDel.ReleaseBuffer(nCount);
+ m_wsField = wsTemp;
+ nCaret = nIndex + ((m_bReserveSpace && !m_bLeftAlignment) ? (nCount - nInsLength) : (nInsLength));
+ return FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL;
+}
+void CFDE_TxtEdtField::GetDisplayText(CFX_WideString &wsDisplay)
+{
+ CFX_WideString wsField;
+ GetNormalizedFieldText(wsField);
+ FX_INT32 nLength = wsField.GetLength() + FDE_FORMAT_EDIT_FIELD_HADERSIZE + FDE_FORMAT_EDIT_FIELD_TAILSIZE;
+ FX_LPWSTR lpBuffer = wsDisplay.GetBuffer(nLength);
+ lpBuffer[0] = FDE_TXTEDT_FORMATBLOCK_BGN;
+ lpBuffer[nLength - 1] = FDE_TXTEDT_FORMATBLOCK_END;
+ FX_DWORD nAddress = (FX_DWORD)this;
+ FXSYS_memcpy(lpBuffer + 1, &nAddress, sizeof(FX_DWORD));
+ FXSYS_memcpy(lpBuffer + 3, FX_LPCWSTR(wsField), (nLength - 4) * sizeof(FX_WCHAR));
+ wsDisplay.ReleaseBuffer(nLength);
+}
+FX_INT32 CFDE_TxtEdtField::GetDisplayLength()
+{
+ return (m_bReserveSpace ? m_nLength : m_wsField.GetLength()) + FDE_FORMAT_EDIT_FIELD_HADERSIZE + FDE_FORMAT_EDIT_FIELD_TAILSIZE;
+}
+void CFDE_TxtEdtField::GetFieldText(CFX_WideString &wsField)
+{
+ wsField = m_wsField;
+}
+FX_INT32 CFDE_TxtEdtField::GetFieldTextLength() const
+{
+ return m_wsField.GetLength();
+}
+FX_INT32 CFDE_TxtEdtField::GetRealIndex(FX_INT32 nIndex) const
+{
+ FX_INT32 nInnerIndex = nIndex - FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+ if (nInnerIndex < 0) {
+ return 0;
+ }
+ FX_INT32 nFieldLength = m_wsField.GetLength();
+ if (m_bReserveSpace && !m_bLeftAlignment) {
+ nInnerIndex -= (m_nLength - nFieldLength);
+ }
+ if (nInnerIndex < 0) {
+ return 0;
+ }
+ if (nInnerIndex >= nFieldLength) {
+ return nFieldLength;
+ }
+ return nInnerIndex + 1;
+}
+FX_INT32 CFDE_TxtEdtField::NormalizeCaretPos(FX_INT32 nIndex, FDE_FORMAT_CARET_DIRECTION eDirection ) const
+{
+ nIndex -= FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+ FX_INT32 nLength = m_wsField.GetLength();
+ if (m_bReserveSpace) {
+ FX_INT32 nFieldLength = m_wsField.GetLength();
+ if (m_bLeftAlignment) {
+ if (nIndex > nFieldLength) {
+ if (eDirection == FDE_FORMAT_CARET_FORWARD) {
+ return -1;
+ }
+ nIndex = nFieldLength;
+ }
+ } else {
+ FX_INT32 nReserveLength = m_nLength - nFieldLength;
+ if (nIndex < nReserveLength) {
+ if (eDirection == FDE_FORMAT_CARET_BACKWARD) {
+ return -2;
+ }
+ nIndex = nReserveLength;
+ }
+ }
+ }
+ return nIndex + FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+}
+FX_BOOL CFDE_TxtEdtField::GetEditableRange(FX_INT32 &nBgn, FX_INT32 &nEnd) const
+{
+ if (m_bReserveSpace && !m_bLeftAlignment) {
+ nEnd = FDE_FORMAT_EDIT_FIELD_HADERSIZE + m_nLength;
+ nBgn = nEnd - m_wsField.GetLength();
+ } else {
+ nBgn = FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+ nEnd = nBgn + m_wsField.GetLength();
+ }
+ return TRUE;
+}
+void CFDE_TxtEdtField::Backup()
+{
+ m_wsBackup = m_wsField;
+}
+void CFDE_TxtEdtField::Restore()
+{
+ m_wsField = m_wsBackup;
+}
+FX_INT32 CFDE_TxtEdtField::Validate(const CFX_WideString & wsText) const
+{
+ if (m_nLength < 0) {
+ return FDE_FORMAT_FIELD_DELETE_RET_S;
+ }
+ return wsText.GetLength() <= m_nLength ? FDE_FORMAT_FIELD_VALIDATE_S : FDE_FORMAT_FIELD_VALIDATE_F_FULL;
+}
+void CFDE_TxtEdtField::GetNormalizedFieldText(CFX_WideString &wsField) const
+{
+ wsField = m_wsField;
+ if (m_nLength == -1) {
+ return;
+ }
+ if (m_bReserveSpace) {
+ FX_INT32 nField = wsField.GetLength();
+ FX_INT32 nFill = m_nLength - nField;
+ if (m_bLeftAlignment) {
+ while (nFill --) {
+ wsField.Insert(nField++, m_wcFill);
+ }
+ } else {
+ while (nFill --) {
+ wsField.Insert(0, m_wcFill);
+ }
+ }
+ }
+}
+CFDE_TxtEdtField_Integer::CFDE_TxtEdtField_Integer(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock)
+ : m_bSign(FALSE)
+ , CFDE_TxtEdtField(nIndex, pBlock)
+{
+ CFDE_TxtEdtFieldFormatParser FormatParser;
+ FormatParser.Parse(wsField);
+ FX_INT32 nCount = FormatParser.CountItems();
+ CFX_WideString wskey;
+ CFX_WideString wsVal;
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FormatParser.GetItem(i, wskey, wsVal);
+ if (wskey.Equal(L"Length")) {
+ m_nLength = wsVal.GetInteger();
+ } else if (wskey.Equal(L"Sign")) {
+ m_bSign = wsVal.GetInteger() != 0;
+ } else if (wskey.Equal(L"FillChar")) {
+ m_wcFill = wsVal[0];
+ } else {
+ FXSYS_assert(0);
+ }
+ wskey.Empty();
+ wsVal.Empty();
+ }
+ if (m_nLength == -1) {
+ m_bReserveSpace = FALSE;
+ }
+}
+FX_INT32 CFDE_TxtEdtField_Integer::Validate(const CFX_WideString &wsText) const
+{
+ FX_INT32 i = 0;
+ if (m_bSign) {
+ FX_WCHAR wcTemp = wsText[0];
+ if (FDE_TXTEDT_ISSIGN(wcTemp)) {
+ i ++;
+ }
+ }
+ FX_INT32 nLength = wsText.GetLength();
+ if (m_nLength > 0) {
+ if (nLength - i > (m_nLength - (m_bSign ? 1 : 0))) {
+ return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
+ }
+ }
+ for (; i < nLength; i ++) {
+ FX_WCHAR wcTemp = wsText[i];
+ if (!FDE_TXTEDT_ISINTEGER(wcTemp)) {
+ return FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE;
+ }
+ }
+ return FDE_FORMAT_FIELD_VALIDATE_S;
+}
+CFDE_TxtEdtField_Float::CFDE_TxtEdtField_Float(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock)
+ : CFDE_TxtEdtField(nIndex, pBlock)
+ , m_bSigned(FALSE)
+ , m_nIntPartlength(-1)
+ , m_nDecPartLength(-1)
+{
+ CFDE_TxtEdtFieldFormatParser FormatParser;
+ FormatParser.Parse(wsField);
+ FX_INT32 nCount = FormatParser.CountItems();
+ CFX_WideString wskey;
+ CFX_WideString wsVal;
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FormatParser.GetItem(i, wskey, wsVal);
+ if (wskey.Equal(L"DecLength")) {
+ m_nDecPartLength = wsVal.GetInteger();
+ } else if (wskey.Equal(L"IntLength")) {
+ m_nIntPartlength = wsVal.GetInteger();
+ } else if (wskey.Equal(L"Sign")) {
+ m_bSigned = wsVal.GetInteger() != 0;
+ } else if (wskey.Equal(L"FillChar")) {
+ m_wcFill = wsVal[0];
+ } else {
+ FXSYS_assert(0);
+ }
+ if (m_nIntPartlength == -1 || m_nDecPartLength == -1) {
+ m_nLength = -1;
+ } else {
+ m_nLength = m_nIntPartlength + m_nDecPartLength + 1 + (m_bSigned ? 1 : 0);
+ }
+ m_bReserveSpace = TRUE;
+ wskey.Empty();
+ wsVal.Empty();
+ }
+}
+FX_INT32 CFDE_TxtEdtField_Float::Validate(const CFX_WideString & wsText) const
+{
+ FX_INT32 nLength = wsText.GetLength();
+ if (m_nLength != -1 && (nLength > m_nLength)) {
+ return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
+ }
+ FX_LPCWSTR lpBuf = FX_LPCWSTR(wsText);
+ FX_INT32 i = 0;
+ if (m_bSigned) {
+ FX_WCHAR wcTemp = lpBuf[0];
+ if (FDE_TXTEDT_ISSIGN(wcTemp)) {
+ i ++;
+ }
+ }
+ FX_INT32 nIntPart = 0;
+ FX_INT32 nPoint = 0;
+ for (; i < nLength; i ++) {
+ FX_WCHAR wcTemp = lpBuf[i];
+ if (!FDE_TXTEDT_ISINTEGER(wcTemp)) {
+ if (wcTemp != L'.') {
+ return FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE;
+ }
+ nPoint = 1;
+ break;
+ }
+ nIntPart ++;
+ }
+ if (m_nIntPartlength != -1 && (nIntPart > m_nIntPartlength)) {
+ return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
+ }
+ if (m_nDecPartLength != -1 && (nLength - nIntPart - nPoint > m_nDecPartLength)) {
+ return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
+ }
+ i ++;
+ for (; i < nLength; i ++) {
+ FX_WCHAR wcTemp = lpBuf[i];
+ if (!FDE_TXTEDT_ISINTEGER(wcTemp)) {
+ return FDE_FORMAT_FIELD_VALIDATE_F_FULL;
+ }
+ }
+ return FDE_FORMAT_FIELD_VALIDATE_S;
+}
+CFDE_TxtEdtField_Password::CFDE_TxtEdtField_Password(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock)
+ : CFDE_TxtEdtField(nIndex, pBlock)
+ , m_wcAlias(L'*')
+{
+ CFDE_TxtEdtFieldFormatParser FormatParser;
+ FormatParser.Parse(wsField);
+ FX_INT32 nCount = FormatParser.CountItems();
+ CFX_WideString wskey;
+ CFX_WideString wsVal;
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FormatParser.GetItem(i, wskey, wsVal);
+ if (wskey.Equal(L"Length")) {
+ m_nLength = wsVal.GetInteger();
+ } else if (wskey.Equal(L"AliasChar")) {
+ m_wcAlias = wsVal[0];
+ } else {
+ FXSYS_assert(0);
+ }
+ wskey.Empty();
+ wsVal.Empty();
+ }
+ if (m_nLength == -1) {
+ m_bReserveSpace = FALSE;
+ }
+}
+void CFDE_TxtEdtField_Password::GetNormalizedFieldText(CFX_WideString &wsField) const
+{
+ FX_INT32 nFiledLength = m_wsField.GetLength();
+ FX_INT32 nLength = m_bReserveSpace ? m_nLength : nFiledLength;
+ FX_LPWSTR lpBuf = wsField.GetBuffer(nLength);
+ FX_INT32 nSpaceLength = nLength - nFiledLength;
+ FX_INT32 nFirstPart = m_bLeftAlignment ? nFiledLength : nSpaceLength;
+ FX_WCHAR wFirstChar = m_bLeftAlignment ? m_wcAlias : L' ';
+ FX_WCHAR wSecondChar = m_bLeftAlignment ? L' ' : m_wcAlias;
+ FX_INT32 i = 0;
+ for (; i < nFirstPart; i ++) {
+ lpBuf[i] = wFirstChar;
+ }
+ for (; i < nLength; i ++) {
+ lpBuf[i] = wSecondChar;
+ }
+ wsField.ReleaseBuffer(nLength);
+}
+CFDE_TxtEdtField_String::CFDE_TxtEdtField_String(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock)
+ : CFDE_TxtEdtField(nIndex, pBlock)
+{
+ CFDE_TxtEdtFieldFormatParser FormatParser;
+ FormatParser.Parse(wsField);
+ FX_INT32 nCount = FormatParser.CountItems();
+ CFX_WideString wskey;
+ CFX_WideString wsVal;
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FormatParser.GetItem(i, wskey, wsVal);
+ if (wskey.Equal(L"Length")) {
+ m_nLength = wsVal.GetInteger();
+ } else {
+ FXSYS_assert(0);
+ }
+ wskey.Empty();
+ wsVal.Empty();
+ }
+}
+CFDE_TxtEdtField_Fixed::CFDE_TxtEdtField_Fixed(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock)
+ : CFDE_TxtEdtField(nIndex, pBlock)
+{
+ m_wsField = wsField;
+ m_nLength = wsField.GetLength();
+}
+void CFDE_TxtEdtField_Fixed::GetDisplayText(CFX_WideString &wsDisplay)
+{
+ FX_INT32 nLength = m_wsField.GetLength() + FDE_FORMAT_EDIT_FIELD_HADERSIZE + FDE_FORMAT_EDIT_FIELD_TAILSIZE;
+ FX_LPWSTR lpBuffer = wsDisplay.GetBuffer(nLength);
+ lpBuffer[0] = FDE_TXTEDT_FORMATBLOCK_BGN;
+ lpBuffer[nLength - 1] = FDE_TXTEDT_FORMATBLOCK_END;
+ FX_DWORD nAddress = (FX_DWORD)this;
+ FXSYS_memcpy(lpBuffer + 1, &nAddress, sizeof(FX_DWORD));
+ FXSYS_memcpy(lpBuffer + 3, FX_LPCWSTR(m_wsField), (nLength - 4) * sizeof(FX_WCHAR));
+ wsDisplay.ReleaseBuffer(nLength);
+}
+FX_INT32 CFDE_TxtEdtField_Fixed::NormalizeCaretPos(FX_INT32 nIndex, FDE_FORMAT_CARET_DIRECTION eDirection ) const
+{
+ FXSYS_assert(nIndex >= 0 && nIndex <= m_nLength);
+ if (eDirection == FDE_FORMAT_CARET_MIDDLE) {
+ return (nIndex > m_wsField.GetLength() / 2) ? -1 : -2;
+ }
+ return eDirection == FDE_FORMAT_CARET_BACKWARD ? -2 : -1;
+}
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtblock.h b/xfa/src/fee/src/fee/fde_txtedtblock.h
new file mode 100644
index 0000000000..12aee74d39
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtblock.h
@@ -0,0 +1,227 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TXTEDTBLOCK_H
+#define _FDE_TXTEDTBLOCK_H
+#ifdef FDE_USEFORMATBLOCK
+class CFDE_TxtEdtEngine;
+class CFDE_TxtEdtBlock;
+class CFDE_TxtEdtFieldFormatParser;
+class CFDE_TxtEdtField;
+class CFDE_TxtEdtField_Integer;
+class CFDE_TxtEdtField_Float;
+class CFDE_TxtEdtField_Password;
+class CFDE_TxtEdtField_String;
+class CFDE_TxtEdtField_Fixed;
+#define FDE_FORMAT_EDIT_FIELD_HADERSIZE 3
+#define FDE_FORMAT_EDIT_FIELD_TAILSIZE 1
+enum FDE_FORMAT_FIELD_INSERT_RET {
+ FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL = 0,
+ FDE_FORMAT_FIELD_INSERT_RET_S_FULL ,
+ FDE_FORMAT_FIELD_INSERT_RET_F_FULL ,
+ FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE,
+};
+enum FDE_FORMAT_FIELD_DELETE_RET {
+ FDE_FORMAT_FIELD_DELETE_RET_S = 0 ,
+ FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE ,
+ FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY ,
+};
+enum FDE_FORMAT_FIELD_VALIDATE_RET {
+ FDE_FORMAT_FIELD_VALIDATE_S = 0 ,
+ FDE_FORMAT_FIELD_VALIDATE_F_FULL ,
+ FDE_FORMAT_FIELD_VALIDATE_F_INVALIDATE ,
+};
+enum FDE_FORMAT_CARET_DIRECTION {
+ FDE_FORMAT_CARET_FORWARD,
+ FDE_FORMAT_CARET_MIDDLE,
+ FDE_FORMAT_CARET_BACKWARD
+};
+class CFDE_TxtEdtBlock : public CFX_Object
+{
+public:
+ CFDE_TxtEdtBlock(CFDE_TxtEdtEngine * pEngine, const CFX_WideString &wsBlock, FX_INT32 nPosition);
+ ~CFDE_TxtEdtBlock();
+ void GetDisplayText(CFX_WideString &wsDisplay);
+ FX_INT32 GetLength() const;
+ void GetBlockText(CFX_WideString &wsBlock);
+ FX_INT32 CountField() const;
+ void GetFieldText(FX_INT32 nIndex, CFX_WideString &wsField);
+ FX_INT32 GetFieldTextLength() const;
+
+ FX_INT32 GetPos() const;
+ void GetRealText(CFX_WideString &wsText) const;
+ void Backup();
+ void Restore();
+ void SetIndex(FX_INT32 nIndex)
+ {
+ m_nIndex = nIndex;
+ }
+ FX_INT32 GetIndex() const
+ {
+ return m_nIndex;
+ }
+private:
+ CFDE_TxtEdtEngine * m_pEngine;
+ FX_INT32 m_nDisplayLength;
+ FX_INT32 m_nIndex;
+
+ FX_INT32 m_nPosition;
+ CFX_ArrayTemplate<CFDE_TxtEdtField*> m_FieldArr;
+ CFX_ArrayTemplate<CFDE_TxtEdtField*> m_EditFieldArr;
+};
+class CFDE_TxtEdtFieldFormatParser : public CFX_Object
+{
+public:
+ CFDE_TxtEdtFieldFormatParser();
+ ~CFDE_TxtEdtFieldFormatParser();
+ FX_BOOL Parse(const CFX_WideString &wsFormat);
+ FX_INT32 CountItems() const;
+ void GetItem(FX_INT32 nIndex, CFX_WideString &wsKey, CFX_WideString &wsValue) const;
+private:
+ typedef struct : public CFX_Object {
+ FX_INT32 nKeyStart;
+ FX_INT32 nKeyCount;
+ FX_INT32 nValStart;
+ FX_INT32 nValCount;
+ } FDE_TXTEDTFORMATITEM, * FDE_LPTXTEDTFORMATITEM;
+
+ CFX_WideString m_wsFormat;
+ CFX_ArrayTemplate<FDE_LPTXTEDTFORMATITEM> m_ItemArr;
+};
+class CFDE_TxtEdtField : public CFX_Object
+{
+public:
+ static CFDE_TxtEdtField * Create(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock);
+ virtual void Release();
+ virtual FX_INT32 Insert( FX_INT32 nIndex, const CFX_WideString &wsIns,
+ FX_INT32 &nCaret, FX_BOOL &bBefore);
+ virtual FX_INT32 Delete( FX_INT32 nIndex, FX_INT32 nCount,
+ CFX_WideString &wsDel, FX_INT32 &nCaret,
+ FX_BOOL &bBefore);
+ virtual FX_INT32 Replace(FX_INT32 nIndex, FX_INT32 nCount,
+ const CFX_WideString &wsIns, CFX_WideString &wsDel,
+ FX_INT32 &nCaret, FX_BOOL &bBefore);
+ virtual void GetDisplayText(CFX_WideString &wsDisplay);
+ virtual FX_INT32 GetDisplayLength();
+ virtual void GetFieldText(CFX_WideString &wsField);
+ virtual FX_INT32 GetFieldTextLength() const;
+ virtual FX_INT32 GetRealIndex(FX_INT32 nIndex) const;
+
+
+ virtual FX_INT32 NormalizeCaretPos( FX_INT32 nIndex,
+ FDE_FORMAT_CARET_DIRECTION eDirection = FDE_FORMAT_CARET_MIDDLE) const;
+
+ virtual FX_BOOL GetEditableRange(FX_INT32 &nBgn, FX_INT32 &nEnd) const;
+ virtual void Backup();
+ virtual void Restore();
+ virtual FX_BOOL IsFix() const
+ {
+ return FALSE;
+ }
+ void SetIndex(FX_INT32 nIndex)
+ {
+ m_nIndex = nIndex;
+ }
+ FX_INT32 GetIndex() const
+ {
+ return m_nIndex;
+ }
+ FX_INT32 GetBlockIndex() const
+ {
+ return m_pBlock->GetIndex();
+ }
+protected:
+ CFDE_TxtEdtField(FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock);
+ virtual ~CFDE_TxtEdtField() {}
+ virtual FX_INT32 Validate(const CFX_WideString & wsText) const;
+ virtual void GetNormalizedFieldText(CFX_WideString &wsField) const;
+ FX_INT32 m_nLength;
+ CFX_WideString m_wsField;
+ CFX_WideString m_wsBackup;
+ FX_WCHAR m_wcFill;
+ FX_BOOL m_bReserveSpace;
+ FX_BOOL m_bLeftAlignment;
+ FX_INT32 m_nIndex;
+ CFDE_TxtEdtBlock * m_pBlock;
+};
+class CFDE_TxtEdtField_Integer : public CFDE_TxtEdtField
+{
+public:
+ CFDE_TxtEdtField_Integer(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock);
+protected:
+ virtual ~CFDE_TxtEdtField_Integer() {}
+ virtual FX_INT32 Validate(const CFX_WideString &wsText) const;
+private:
+ FX_BOOL m_bSign;
+};
+class CFDE_TxtEdtField_Float : public CFDE_TxtEdtField
+{
+public:
+ CFDE_TxtEdtField_Float(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock);
+protected:
+ virtual ~CFDE_TxtEdtField_Float() {}
+ virtual FX_INT32 Validate(const CFX_WideString & wsText) const;
+private:
+ FX_BOOL m_bSigned;
+ FX_INT32 m_nIntPartlength;
+ FX_INT32 m_nDecPartLength;
+};
+class CFDE_TxtEdtField_Password : public CFDE_TxtEdtField
+{
+public:
+ CFDE_TxtEdtField_Password(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock);
+
+protected:
+ virtual ~CFDE_TxtEdtField_Password() {}
+ virtual void GetNormalizedFieldText(CFX_WideString &wsField) const;
+private:
+ FX_WCHAR m_wcAlias;
+};
+class CFDE_TxtEdtField_String : public CFDE_TxtEdtField
+{
+public:
+ CFDE_TxtEdtField_String(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock);
+protected:
+ virtual ~CFDE_TxtEdtField_String() {}
+};
+class CFDE_TxtEdtField_Fixed : public CFDE_TxtEdtField
+{
+public:
+ CFDE_TxtEdtField_Fixed(const CFX_WideString &wsField, FX_INT32 nIndex, CFDE_TxtEdtBlock * pBlock);
+ virtual FX_INT32 Insert( FX_INT32 nIndex, const CFX_WideString &wsIns,
+ FX_INT32 &nCaret, FX_BOOL &bBefore)
+ {
+ return FALSE;
+ }
+ virtual FX_INT32 Delete( FX_INT32 nIndex, FX_INT32 nCount, CFX_WideString &wsDel,
+ FX_INT32 &nCaret, FX_BOOL &bBefore)
+ {
+ return FALSE;
+ }
+ virtual FX_INT32 Replace(FX_INT32 nIndex, FX_INT32 nCount, const CFX_WideString &wsIns,
+ CFX_WideString &wsDel, FX_INT32 &nCaret, FX_BOOL &bBefore)
+ {
+ return FALSE;
+ }
+ virtual void GetDisplayText(CFX_WideString &wsDisplay);
+ virtual FX_INT32 NormalizeCaretPos( FX_INT32 nIndex,
+ FDE_FORMAT_CARET_DIRECTION eDirection ) const;
+ virtual FX_BOOL GetEditableRange(FX_INT32 &nBgn, FX_INT32 &nEnd) const
+ {
+ return FALSE;
+ }
+ virtual void Backup() {}
+ virtual void Restore() {}
+
+ virtual FX_BOOL IsFix() const
+ {
+ return TRUE;
+ }
+protected:
+ virtual ~CFDE_TxtEdtField_Fixed() {}
+};
+#endif
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtbuf.cpp b/xfa/src/fee/src/fee/fde_txtedtbuf.cpp
new file mode 100644
index 0000000000..f2cb0c57f2
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtbuf.cpp
@@ -0,0 +1,446 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../../include/ifde_txtedtbuf.h"
+#include "../../include/ifde_txtedtengine.h"
+#include "fde_txtedtbuf.h"
+#define FDE_DEFCHUNKCOUNT 2
+#define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9
+#define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB
+#define FDE_TXTEDT_ZEROWIDTHSPACE 0x200B
+#ifdef FDE_USEFORMATBLOCK
+CFDE_TxtEdtBufIter::CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf * pBuf, FX_BOOL bForDisplay )
+#else
+CFDE_TxtEdtBufIter::CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf * pBuf, FX_WCHAR wcAlias )
+#endif
+ : m_nCurChunk(0)
+ , m_nCurIndex(0)
+ , m_nIndex(0)
+ , m_pBuf(pBuf)
+#ifdef FDE_USEFORMATBLOCK
+ , m_bForDisplay(bForDisplay)
+ , m_nAliasCount(0)
+#endif
+ , m_bInField(FALSE)
+ , m_Alias(wcAlias)
+{
+ FXSYS_assert(m_pBuf);
+}
+CFDE_TxtEdtBufIter::~CFDE_TxtEdtBufIter()
+{
+}
+void CFDE_TxtEdtBufIter::Release()
+{
+ delete this;
+}
+FX_BOOL CFDE_TxtEdtBufIter::Next(FX_BOOL bPrev )
+{
+ if (bPrev) {
+ if (m_nIndex == 0) {
+ return FALSE;
+ }
+ FXSYS_assert(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
+ CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunk = NULL;
+ if (m_nCurIndex > 0) {
+ m_nCurIndex --;
+ } else {
+ while (m_nCurChunk > 0) {
+ --m_nCurChunk;
+ lpChunk = (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
+ if (lpChunk->nUsed > 0) {
+ m_nCurIndex = lpChunk->nUsed - 1;
+ break;
+ }
+ }
+ }
+ FXSYS_assert(m_nCurChunk >= 0);
+ m_nIndex --;
+ return TRUE;
+ } else {
+ if (m_nIndex >= (m_pBuf->m_nTotal - 1)) {
+ return FALSE;
+ }
+ FXSYS_assert(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
+ CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunk = \
+ (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
+ if (lpChunk->nUsed != (m_nCurIndex + 1)) {
+ m_nCurIndex ++;
+ } else {
+ FX_INT32 nEnd = m_pBuf->m_Chunks.GetSize() - 1;
+ while (m_nCurChunk < nEnd) {
+ m_nCurChunk ++;
+ CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunkTemp = \
+ (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
+ if (lpChunkTemp->nUsed > 0) {
+ m_nCurIndex = 0;
+ break;
+ }
+ }
+ }
+ m_nIndex ++;
+ return TRUE;
+ }
+}
+void CFDE_TxtEdtBufIter::SetAt(FX_INT32 nIndex)
+{
+ FXSYS_assert(nIndex >= 0 && nIndex < m_pBuf->m_nTotal);
+ CFDE_TxtEdtBuf::FDE_CHUNKPLACE cp;
+ m_pBuf->Index2CP(nIndex, cp);
+ m_nIndex = nIndex;
+ m_nCurChunk = cp.nChunkIndex;
+ m_nCurIndex = cp.nCharIndex;
+}
+FX_INT32 CFDE_TxtEdtBufIter::GetAt() const
+{
+ return m_nIndex;
+}
+FX_WCHAR CFDE_TxtEdtBufIter::GetChar()
+{
+ FXSYS_assert(m_nIndex >= 0 && m_nIndex < m_pBuf->m_nTotal);
+#ifdef FDE_USEFORMATBLOCK
+ if (m_bForDisplay) {
+ if (m_bInField) {
+ FXSYS_assert(m_nAliasCount >= 0 && m_nAliasCount <= 2);
+ if (m_nAliasCount > 0) {
+ m_nAliasCount --;
+ return FDE_TXTEDT_ZEROWIDTHSPACE;
+ }
+ FX_WCHAR wc = ((CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk])->wChars[m_nCurIndex];
+ if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
+ m_nAliasCount = 0;
+ m_bInField = FALSE;
+ }
+ return wc;
+ } else {
+ FX_WCHAR wc = ((CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk])->wChars[m_nCurIndex];
+ if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
+ m_nAliasCount = 2;
+ m_bInField = TRUE;
+ }
+ return wc;
+ }
+ }
+#endif
+ if (m_Alias == 0 || m_nIndex == (m_pBuf->m_nTotal - 1)) {
+ return ((CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk])->wChars[m_nCurIndex];
+ }
+ return m_Alias;
+}
+FX_BOOL CFDE_TxtEdtBufIter::IsEOF(FX_BOOL bTail ) const
+{
+ return bTail ? m_nIndex == (m_pBuf->GetTextLength() - 2) : m_nIndex == 0;
+}
+IFX_CharIter * CFDE_TxtEdtBufIter::Clone()
+{
+ CFDE_TxtEdtBufIter * pIter = FX_NEW CFDE_TxtEdtBufIter(m_pBuf);
+ pIter->m_nCurChunk = m_nCurChunk;
+ pIter->m_nCurIndex = m_nCurIndex;
+ pIter->m_nIndex = m_nIndex;
+ pIter->m_Alias = m_Alias;
+ return pIter;
+}
+CFDE_TxtEdtBuf::CFDE_TxtEdtBuf(FX_INT32 nDefChunkSize )
+ : m_nChunkSize(nDefChunkSize)
+ , m_nTotal(0)
+ , m_bChanged(FALSE)
+ , m_pAllocator(NULL)
+{
+ FXSYS_assert(m_nChunkSize);
+ ResetChunkBuffer(FDE_DEFCHUNKCOUNT, m_nChunkSize);
+}
+void CFDE_TxtEdtBuf::Release()
+{
+ delete this;
+}
+CFDE_TxtEdtBuf::~CFDE_TxtEdtBuf()
+{
+ Clear(TRUE);
+ m_pAllocator->Release();
+ m_Chunks.RemoveAll();
+}
+FX_BOOL CFDE_TxtEdtBuf::SetChunkSize(FX_INT32 nChunkSize)
+{
+ FXSYS_assert(nChunkSize);
+ ResetChunkBuffer(FDE_DEFCHUNKCOUNT, nChunkSize);
+ return TRUE;
+}
+FX_INT32 CFDE_TxtEdtBuf::GetChunkSize() const
+{
+ return m_nChunkSize;
+}
+FX_INT32 CFDE_TxtEdtBuf::GetTextLength() const
+{
+ return m_nTotal;
+}
+void CFDE_TxtEdtBuf::SetText(const CFX_WideString &wsText)
+{
+ FXSYS_assert(!wsText.IsEmpty());
+ Clear(FALSE);
+ FX_INT32 nTextLength = wsText.GetLength();
+ FX_INT32 nNeedCount = ((nTextLength - 1) / m_nChunkSize + 1) - m_Chunks.GetSize();
+ FX_INT32 i = 0;
+ for (i = 0; i < nNeedCount; i ++) {
+ FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(sizeof(FDE_CHUNKHEADER) + \
+ (m_nChunkSize - 1) * sizeof(FX_WCHAR));
+ lpChunk->nUsed = 0;
+ m_Chunks.Add(lpChunk);
+ }
+ FX_INT32 nTotalCount = m_Chunks.GetSize();
+ FX_LPCWSTR lpSrcBuf = FX_LPCWSTR(wsText);
+ FX_INT32 nLeave = nTextLength;
+ FX_INT32 nCopyedLength = m_nChunkSize;
+ for (i = 0; i < nTotalCount && nLeave > 0; i ++) {
+ if (nLeave < nCopyedLength) {
+ nCopyedLength = nLeave;
+ }
+ FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
+ FXSYS_memcpy(lpChunk->wChars, lpSrcBuf, nCopyedLength * sizeof(FX_WCHAR));
+ nLeave -= nCopyedLength;
+ lpSrcBuf += nCopyedLength;
+ lpChunk->nUsed = nCopyedLength;
+ }
+ m_nTotal = nTextLength;
+ m_bChanged = TRUE;
+}
+void CFDE_TxtEdtBuf::GetText(CFX_WideString &wsText) const
+{
+ GetRange(wsText, 0, m_nTotal);
+}
+FX_WCHAR CFDE_TxtEdtBuf::GetCharByIndex(FX_INT32 nIndex) const
+{
+ FXSYS_assert(nIndex >= 0 && nIndex < GetTextLength());
+ FDE_LPCHUNKHEADER pChunkHeader = NULL;
+ FX_INT32 nTotal = 0;
+ FX_INT32 nCount = m_Chunks.GetSize();
+ FX_INT32 i = 0;
+ for (i = 0; i < nCount; i ++) {
+ pChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[i];
+ nTotal += pChunkHeader->nUsed;
+ if (nTotal > nIndex) {
+ break;
+ }
+ }
+ FXSYS_assert(pChunkHeader);
+ return pChunkHeader->wChars[pChunkHeader->nUsed - (nTotal - nIndex)];
+}
+void CFDE_TxtEdtBuf::GetRange(CFX_WideString &wsText, FX_INT32 nBegin, FX_INT32 nLength) const
+{
+ FDE_CHUNKPLACE cp;
+ Index2CP(nBegin, cp);
+ FX_INT32 nLeave = nLength;
+ FX_INT32 nCount = m_Chunks.GetSize();
+ FX_LPWSTR lpDstBuf = wsText.GetBuffer(nLength);
+ FX_INT32 nChunkIndex = cp.nChunkIndex;
+ FDE_LPCHUNKHEADER lpChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[nChunkIndex];
+ FX_INT32 nCopyLength = lpChunkHeader->nUsed - cp.nCharIndex;
+ FX_LPWSTR lpSrcBuf = lpChunkHeader->wChars + cp.nCharIndex;
+ while (nLeave > 0) {
+ if (nLeave <= nCopyLength) {
+ nCopyLength = nLeave;
+ }
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf, nCopyLength * sizeof(FX_WCHAR));
+ nChunkIndex ++;
+ if (nChunkIndex >= nCount) {
+ break;
+ }
+ lpChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[nChunkIndex];
+ lpSrcBuf = lpChunkHeader->wChars;
+ nLeave -= nCopyLength;
+ lpDstBuf += nCopyLength;
+ nCopyLength = lpChunkHeader->nUsed;
+ }
+ wsText.ReleaseBuffer();
+}
+void CFDE_TxtEdtBuf::Insert(FX_INT32 nPos, FX_LPCWSTR lpText, FX_INT32 nLength )
+{
+ FXSYS_assert(nPos >= 0 && nPos <= m_nTotal);
+ FDE_CHUNKPLACE cp;
+ Index2CP(nPos, cp);
+ FX_INT32 nLengthTemp = nLength;
+ if (cp.nCharIndex != 0) {
+ FDE_LPCHUNKHEADER lpNewChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(sizeof(FDE_CHUNKHEADER) + \
+ (m_nChunkSize - 1) * sizeof(FX_WCHAR));
+ FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex];
+ FX_INT32 nCopy = lpChunk->nUsed - cp.nCharIndex;
+ FXSYS_memcpy(lpNewChunk->wChars, lpChunk->wChars + cp.nCharIndex, nCopy * sizeof(FX_WCHAR));
+ lpChunk->nUsed -= nCopy;
+ cp.nChunkIndex ++;
+ m_Chunks.InsertAt(cp.nChunkIndex, lpNewChunk);
+ lpNewChunk->nUsed = nCopy;
+ cp.nCharIndex = 0;
+ }
+ if (cp.nChunkIndex != 0) {
+ FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex - 1];
+ if (lpChunk->nUsed != m_nChunkSize) {
+ cp.nChunkIndex --;
+ FX_INT32 nFree = m_nChunkSize - lpChunk->nUsed;
+ FX_INT32 nCopy = FX_MIN(nLengthTemp, nFree);
+ FXSYS_memcpy(lpChunk->wChars + lpChunk->nUsed, lpText, nCopy * sizeof(FX_WCHAR));
+ lpText += nCopy;
+ nLengthTemp -= nCopy;
+ lpChunk->nUsed += nCopy;
+ cp.nChunkIndex++;
+ }
+ }
+ while (nLengthTemp > 0) {
+ FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(sizeof(FDE_CHUNKHEADER) + \
+ (m_nChunkSize - 1) * sizeof(FX_WCHAR));
+ FXSYS_assert(lpChunk);
+ FX_INT32 nCopy = FX_MIN(nLengthTemp, m_nChunkSize);
+ FXSYS_memcpy(lpChunk->wChars, lpText, nCopy * sizeof(FX_WCHAR));
+ lpText += nCopy;
+ nLengthTemp -= nCopy;
+ lpChunk->nUsed = nCopy;
+ m_Chunks.InsertAt(cp.nChunkIndex, lpChunk);
+ cp.nChunkIndex ++;
+ }
+ m_nTotal += nLength;
+ m_bChanged = TRUE;
+}
+void CFDE_TxtEdtBuf::Delete(FX_INT32 nIndex, FX_INT32 nLength )
+{
+ FXSYS_assert(nLength > 0 && nIndex >= 0 && nIndex + nLength <= m_nTotal);
+ FDE_CHUNKPLACE cpEnd;
+ Index2CP(nIndex + nLength - 1, cpEnd);
+ m_nTotal -= nLength;
+ FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cpEnd.nChunkIndex];
+ FX_INT32 nFirstPart = cpEnd.nCharIndex + 1;
+ FX_INT32 nMovePart = lpChunk->nUsed - nFirstPart;
+ if (nMovePart != 0) {
+ FX_INT32 nDelete = FX_MIN(nFirstPart, nLength);
+ FXSYS_memmove(lpChunk->wChars + nFirstPart - nDelete, \
+ lpChunk->wChars + nFirstPart, nMovePart * sizeof(FX_WCHAR));
+ lpChunk->nUsed -= nDelete;
+ nLength -= nDelete;
+ cpEnd.nChunkIndex --;
+ }
+ while (nLength > 0) {
+ lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cpEnd.nChunkIndex];
+ FX_INT32 nDeleted = FX_MIN(lpChunk->nUsed, nLength);
+ lpChunk->nUsed -= nDeleted;
+ if (lpChunk->nUsed == 0) {
+ m_pAllocator->Free(lpChunk);
+ m_Chunks.RemoveAt(cpEnd.nChunkIndex);
+ lpChunk = NULL;
+ }
+ nLength -= nDeleted;
+ cpEnd.nChunkIndex --;
+ }
+ m_bChanged = TRUE;
+}
+void CFDE_TxtEdtBuf::Clear(FX_BOOL bRelease )
+{
+ FX_INT32 i = 0;
+ FX_INT32 nCount = m_Chunks.GetSize();
+ if (bRelease) {
+ while (i < nCount) {
+ m_pAllocator->Free(m_Chunks[i++]);
+ }
+ m_Chunks.RemoveAll();
+ } else {
+ while (i < nCount) {
+ ((FDE_LPCHUNKHEADER)m_Chunks[i++])->nUsed = 0;
+ }
+ }
+ m_nTotal = 0;
+ m_bChanged = TRUE;
+}
+FX_BOOL CFDE_TxtEdtBuf::Optimize(IFX_Pause * pPause )
+{
+ if (m_bChanged == FALSE) {
+ return TRUE;
+ }
+ if (m_nTotal == 0) {
+ return TRUE;
+ }
+ FX_INT32 nCount = m_Chunks.GetSize();
+ if (nCount == 0) {
+ return TRUE;
+ }
+ FX_INT32 i = 0;
+ for ( ; i < nCount; i ++) {
+ FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
+ if (lpChunk->nUsed == 0) {
+ m_pAllocator->Free(lpChunk);
+ m_Chunks.RemoveAt(i);
+ --i;
+ --nCount;
+ }
+ }
+ if (pPause != NULL && pPause->NeedToPauseNow()) {
+ return FALSE;
+ }
+ FDE_LPCHUNKHEADER lpPreChunk = (FDE_LPCHUNKHEADER)m_Chunks[0];
+ FDE_LPCHUNKHEADER lpCurChunk = NULL;
+ for (i = 1; i < nCount; i ++) {
+ lpCurChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
+ if (lpPreChunk->nUsed + lpCurChunk->nUsed <= m_nChunkSize) {
+ FXSYS_memcpy(lpPreChunk->wChars + lpPreChunk->nUsed, lpCurChunk->wChars, \
+ lpCurChunk->nUsed * sizeof(FX_WCHAR));
+ lpPreChunk->nUsed += lpCurChunk->nUsed;
+ m_pAllocator->Free(lpCurChunk);
+ m_Chunks.RemoveAt(i);
+ --i;
+ --nCount;
+ } else {
+ lpPreChunk = lpCurChunk;
+ }
+ if (pPause != NULL && pPause->NeedToPauseNow()) {
+ return FALSE;
+ }
+ }
+ m_bChanged = FALSE;
+ return TRUE;
+}
+void CFDE_TxtEdtBuf::ResetChunkBuffer(FX_INT32 nDefChunkCount, FX_INT32 nChunkSize)
+{
+ FXSYS_assert(nChunkSize);
+ FXSYS_assert(nDefChunkCount);
+ if (m_pAllocator) {
+ m_pAllocator->Release();
+ m_pAllocator = NULL;
+ }
+ m_Chunks.RemoveAll();
+ m_nChunkSize = nChunkSize;
+ FX_INT32 nChunkLength = sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR);
+ m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Fixed, nDefChunkCount, nChunkLength);
+ FXSYS_assert(m_pAllocator);
+ FDE_LPCHUNKHEADER lpChunkHeader = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(nChunkLength);
+ FXSYS_assert(lpChunkHeader);
+ lpChunkHeader->nUsed = 0;
+ m_Chunks.Add(lpChunkHeader);
+ m_nTotal = 0;
+}
+FX_INT32 CFDE_TxtEdtBuf::CP2Index(const FDE_CHUNKPLACE & cp) const
+{
+ FX_INT32 nTotal = cp.nCharIndex;
+ FX_INT32 i = 0;
+ for (i = 0; i < cp.nChunkIndex; i ++) {
+ nTotal += ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed;
+ }
+ return nTotal;
+}
+void CFDE_TxtEdtBuf::Index2CP(FX_INT32 nIndex, FDE_CHUNKPLACE & cp) const
+{
+ FXSYS_assert(nIndex <= GetTextLength());
+ if (nIndex == m_nTotal) {
+ cp.nChunkIndex = m_Chunks.GetSize() - 1;
+ cp.nCharIndex = ((FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex])->nUsed;
+ return;
+ }
+ FX_INT32 i = 0;
+ FX_INT32 nTotal = 0;
+ FX_INT32 nCount = m_Chunks.GetSize();
+ for ( ; i < nCount; i ++) {
+ nTotal += ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed;
+ if (nTotal > nIndex) {
+ break;
+ }
+ }
+ cp.nChunkIndex = i;
+ cp.nCharIndex = ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed - (nTotal - nIndex);
+}
diff --git a/xfa/src/fee/src/fee/fde_txtedtbuf.h b/xfa/src/fee/src/fee/fde_txtedtbuf.h
new file mode 100644
index 0000000000..5baeacd2f6
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtbuf.h
@@ -0,0 +1,90 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TXTEDTBUF_H
+#define _FDE_TXTEDTBUF_H
+class IFX_CharIter;
+class CFDE_TxtEdtBufIter;
+class CFDE_TxtEdtBuf;
+class CFDE_TxtEdtBufIter : public IFX_CharIter, public CFX_Object
+{
+public:
+#ifdef FDE_USEFORMATBLOCK
+ CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf * pBuf, FX_BOOL bForDisplay = TRUE);
+#else
+ CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf * pBuf, FX_WCHAR wcAlias = 0);
+#endif
+
+ virtual void Release();
+ virtual FX_BOOL Next(FX_BOOL bPrev = FALSE);
+ virtual FX_WCHAR GetChar();
+ virtual void SetAt(FX_INT32 nIndex);
+ virtual FX_INT32 GetAt() const;
+ virtual FX_BOOL IsEOF(FX_BOOL bTail = TRUE) const;
+ virtual IFX_CharIter * Clone();
+protected:
+ ~CFDE_TxtEdtBufIter();
+private:
+ CFDE_TxtEdtBuf* m_pBuf;
+ FX_INT32 m_nCurChunk;
+ FX_INT32 m_nCurIndex;
+ FX_INT32 m_nIndex;
+ FX_BOOL m_bInField;
+#ifdef FDE_USEFORMATBLOCK
+ FX_BOOL m_bForDisplay;
+ FX_INT32 m_nAliasCount;
+#endif
+ FX_WCHAR m_Alias;
+};
+class CFDE_TxtEdtBuf : public IFDE_TxtEdtBuf, public CFX_Object
+{
+ friend class CFDE_TxtEdtBufIter;
+ struct _FDE_CHUNKHEADER : public CFX_Object {
+ FX_INT32 nUsed;
+ FX_WCHAR wChars[1];
+ };
+ typedef _FDE_CHUNKHEADER FDE_CHUNKHEADER;
+ typedef _FDE_CHUNKHEADER* FDE_LPCHUNKHEADER;
+ struct _FDE_CHUNKPLACE : public CFX_Object {
+ FX_INT32 nChunkIndex;
+ FX_INT32 nCharIndex;
+ };
+ typedef _FDE_CHUNKPLACE FDE_CHUNKPLACE;
+ typedef _FDE_CHUNKPLACE* FDE_LPCHUNKPLACE;
+
+public:
+ CFDE_TxtEdtBuf(FX_INT32 nDefChunkSize = FDE_DEFCHUNKLENGTH);
+
+ virtual void Release();
+ virtual FX_BOOL SetChunkSize(FX_INT32 nChunkSize);
+ virtual FX_INT32 GetChunkSize() const;
+ virtual FX_INT32 GetTextLength() const;
+ virtual void SetText(const CFX_WideString &wsText);
+ virtual void GetText(CFX_WideString &wsText) const;
+ virtual FX_WCHAR GetCharByIndex(FX_INT32 nIndex) const;
+ virtual void GetRange(CFX_WideString &wsText, FX_INT32 nBegine, FX_INT32 nCount = -1) const;
+
+ virtual void Insert(FX_INT32 nPos, FX_LPCWSTR lpText, FX_INT32 nLength = 1);
+ virtual void Delete(FX_INT32 nIndex, FX_INT32 nLength = 1);
+ virtual void Clear(FX_BOOL bRelease = TRUE);
+
+ virtual FX_BOOL Optimize(IFX_Pause * pPause = NULL);
+
+protected:
+ virtual ~CFDE_TxtEdtBuf();
+private:
+ void ResetChunkBuffer(FX_INT32 nDefChunkCount, FX_INT32 nChunkSize);
+ FX_INT32 CP2Index(const FDE_CHUNKPLACE & cp) const;
+ void Index2CP(FX_INT32 nIndex, FDE_CHUNKPLACE & cp) const;
+
+ FX_INT32 m_nChunkSize;
+
+ FX_INT32 m_nTotal;
+ FX_BOOL m_bChanged;
+ CFX_PtrArray m_Chunks;
+ IFX_MEMAllocator * m_pAllocator;
+};
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtengine.cpp b/xfa/src/fee/src/fee/fde_txtedtengine.cpp
new file mode 100644
index 0000000000..2dbd1384cb
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtengine.cpp
@@ -0,0 +1,2871 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../../include/ifde_txtedtengine.h"
+#include "../../include/ifde_txtedtbuf.h"
+#include "../../include/ifde_txtedtpage.h"
+#include "fde_txtedtengine.h"
+#include "fde_txtedtparag.h"
+#include "fde_txtedtkmpmatch.h"
+#include "fde_txtedtbuf.h"
+#ifdef FDE_USEFORMATBLOCK
+#include "fde_txtedtblock.h"
+#endif
+#define FDE_PAGEWIDTH_MAX 0xFFFF
+#define FDE_TXTPLATESIZE (1024 * 12)
+#define FDE_UNICODE_PARAGRAPH_SPERATOR (0x2029)
+#define FDE_TXTEDT_DORECORD_INS 0
+#define FDE_TXTEDT_DORECORD_DEL 1
+#ifdef FDE_USEFORMATBLOCK
+#define FDE_TXTEDT_DORECORD_FORMATINS 3
+#define FDE_TXTEDT_DORECORD_FORMATDEL 4
+#define FDE_TXTEDT_DORECORD_FORMATREP 5
+#define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9
+#define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB
+#endif
+IFDE_TxtEdtEngine * IFDE_TxtEdtEngine::Create()
+{
+ return FX_NEW CFDE_TxtEdtEngine();
+}
+CFDE_TxtEdtEngine::CFDE_TxtEdtEngine()
+ : m_nPageLineCount(20)
+ , m_nLineCount(0)
+ , m_nAnchorPos(-1)
+ , m_nLayoutPos(0)
+ , m_fCaretPosReserve(0.0)
+ , m_nCaret(0)
+ , m_bBefore(TRUE)
+ , m_nCaretPage(0)
+ , m_bLock(FALSE)
+ , m_nLimit(0)
+ , m_wcAliasChar(L'*')
+ , m_pTextBreak(NULL)
+#ifdef FDE_USEFORMATBLOCK
+ , m_nFixLength(-1)
+#endif
+ , m_dwFindFlags(0)
+ , m_nFirstLineEnd(FDE_TXTEDIT_LINEEND_Auto)
+ , m_wLineEnd(FDE_UNICODE_PARAGRAPH_SPERATOR)
+ , m_bAutoLineEnd(TRUE)
+{
+ FXSYS_memset(&m_rtCaret, 0, sizeof(CFX_RectF));
+ m_pTxtBuf = FX_NEW CFDE_TxtEdtBuf();
+ m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto);
+}
+CFDE_TxtEdtEngine::~CFDE_TxtEdtEngine()
+{
+ if (m_pTxtBuf) {
+ m_pTxtBuf->Release();
+ m_pTxtBuf = NULL;
+ }
+ if (m_pTextBreak) {
+ m_pTextBreak->Release();
+ m_pTextBreak = NULL;
+ }
+#ifdef FDE_USEFORMATBLOCK
+ FX_INT32 nBlockCount = m_BlockArray.GetSize();
+ if (nBlockCount > 0) {
+ FX_INT32 i = 0;
+ for (; i < nBlockCount; i ++) {
+ CFDE_TxtEdtBlock * pBlock = m_BlockArray[i];
+ delete pBlock;
+ }
+ m_BlockArray.RemoveAll();
+ }
+#endif
+ RemoveAllParags();
+ RemoveAllPages();
+ m_Param.pEventSink = NULL;
+ ClearSelection();
+}
+void CFDE_TxtEdtEngine::Release()
+{
+ delete this;
+}
+void CFDE_TxtEdtEngine::SetEditParams(const FDE_TXTEDTPARAMS &params)
+{
+ if (m_pTextBreak == NULL) {
+ m_pTextBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None);
+ }
+ FXSYS_memcpy(&m_Param, &params, sizeof(FDE_TXTEDTPARAMS));
+ m_wLineEnd = params.wLineBreakChar;
+ m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto);
+ UpdateTxtBreak();
+}
+const FDE_TXTEDTPARAMS * CFDE_TxtEdtEngine::GetEditParams() const
+{
+ return &m_Param;
+}
+FX_INT32 CFDE_TxtEdtEngine::CountPages() const
+{
+ if (m_nLineCount == 0) {
+ return 0;
+ }
+ return ((m_nLineCount - 1) / m_nPageLineCount) + 1;
+}
+IFDE_TxtEdtPage * CFDE_TxtEdtEngine::GetPage(FX_INT32 nIndex)
+{
+ if (m_PagePtrArray.GetSize() <= nIndex) {
+ return NULL;
+ }
+ return (IFDE_TxtEdtPage*)m_PagePtrArray[nIndex];
+}
+FX_BOOL CFDE_TxtEdtEngine::SetBufChunkSize(FX_INT32 nChunkSize)
+{
+ return m_pTxtBuf->SetChunkSize(nChunkSize);
+}
+void CFDE_TxtEdtEngine::SetTextByStream(IFX_Stream *pStream)
+{
+ ResetEngine();
+ FX_INT32 nIndex = 0;
+ if (pStream != NULL && pStream->GetLength()) {
+ FX_INT32 nStreamLength = pStream->GetLength();
+ FX_BOOL bValid = TRUE;
+ if (m_nLimit > 0 && nStreamLength > m_nLimit) {
+ bValid = FALSE;
+ }
+ FX_BOOL bPreIsCR = FALSE;
+ if (bValid) {
+ FX_BYTE bom[4];
+ FX_INT32 nPos = pStream->GetBOM(bom);
+ pStream->Seek(FX_STREAMSEEK_Begin, nPos);
+ FX_INT32 bEos = FALSE;
+ FX_INT32 nPlateSize = FX_MIN(nStreamLength, m_pTxtBuf->GetChunkSize());
+ FX_LPWSTR lpwstr = (FX_LPWSTR)FDE_Alloc(nPlateSize * sizeof(FX_WCHAR));
+ FXSYS_assert(lpwstr);
+ FX_INT32 nRead = 0;
+ while (!bEos) {
+ nRead = pStream->ReadString(lpwstr, nPlateSize, bEos);
+ bPreIsCR = ReplaceParagEnd(lpwstr, nRead, bPreIsCR);
+ m_pTxtBuf->Insert(nIndex, lpwstr, nRead);
+ nIndex += nRead;
+ }
+ FDE_Free(lpwstr);
+ }
+ }
+ m_pTxtBuf->Insert(nIndex, &m_wLineEnd, 1);
+ RebuildParagraphs();
+}
+void CFDE_TxtEdtEngine::SetText(const CFX_WideString &wsText)
+{
+ ResetEngine();
+ FX_INT32 nLength = wsText.GetLength();
+ if (nLength > 0) {
+ CFX_WideString wsTemp;
+ FX_LPWSTR lpBuffer = wsTemp.GetBuffer(nLength);
+ FXSYS_memcpy(lpBuffer, FX_LPCWSTR(wsText), nLength * sizeof(FX_WCHAR));
+ ReplaceParagEnd(lpBuffer, nLength, FALSE);
+ wsTemp.ReleaseBuffer(nLength);
+ if (m_nLimit > 0 && nLength > m_nLimit) {
+ wsTemp.Delete(m_nLimit, nLength - m_nLimit);
+ nLength = m_nLimit;
+ }
+ m_pTxtBuf->SetText(wsTemp);
+ }
+ m_pTxtBuf->Insert(nLength, &m_wLineEnd, 1);
+ RebuildParagraphs();
+}
+FX_INT32 CFDE_TxtEdtEngine::GetTextLength() const
+{
+ return GetTextBufLength();
+}
+void CFDE_TxtEdtEngine::GetText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount )
+{
+ FX_INT32 nTextBufLength = GetTextBufLength();
+ if (nCount == -1) {
+ nCount = nTextBufLength - nStart;
+ }
+#ifdef FDE_USEFORMATBLOCK
+ FX_INT32 nBlockCount = m_BlockArray.GetSize();
+ if (nBlockCount == 0 || m_wsFixText.IsEmpty()) {
+ m_pTxtBuf->GetRange(wsText, nStart, nCount);
+ return;
+ }
+ CFX_WideString wsTemp;
+ FX_LPCWSTR lpFixBuffer = FX_LPCWSTR(m_wsFixText);
+ FX_LPWSTR lpBuffer = wsTemp.GetBuffer(nTextBufLength);
+ FX_INT32 nRealLength = 0;
+ FX_INT32 nPrePos = 0;
+ for (FX_INT32 i = 0; i < nBlockCount; i ++) {
+ CFDE_TxtEdtBlock *pBlock = m_BlockArray[i];
+ FX_INT32 nPos = pBlock->GetPos();
+ FX_INT32 nCopyLength = nPos - nPrePos;
+ FXSYS_memcpy(lpBuffer + nRealLength, lpFixBuffer + nPrePos, nCopyLength * sizeof(FX_WCHAR));
+ nRealLength += nCopyLength;
+ nPrePos = nPos;
+ CFX_WideString wsBlock;
+ pBlock->GetRealText(wsBlock);
+ nCopyLength = wsBlock.GetLength();
+ FXSYS_memcpy(lpBuffer + nRealLength, FX_LPCWSTR(wsBlock), nCopyLength * sizeof(FX_WCHAR));
+ nRealLength += nCopyLength;
+ }
+ FX_INT32 nLeftLength = m_wsFixText.GetLength() - nPrePos;
+ if (nLeftLength > 0) {
+ FXSYS_memcpy(lpBuffer + nRealLength, lpFixBuffer + nPrePos, nLeftLength * sizeof(FX_WCHAR));
+ nRealLength += nLeftLength;
+ }
+ wsTemp.ReleaseBuffer(nRealLength);
+ FX_INT32 nRealBgn = GetRealIndex(nStart);
+ FX_INT32 nRealEnd = GetRealIndex(nStart + nCount - 1);
+ FX_INT32 nRealCount = nRealEnd - nRealBgn;
+ FX_LPWSTR lpDestBuf = wsText.GetBuffer(nRealCount);
+ FXSYS_memcpy(lpDestBuf, FX_LPCWSTR(wsTemp) + nRealBgn, nRealCount * sizeof(FX_WCHAR));
+ wsText.ReleaseBuffer();
+#else
+ m_pTxtBuf->GetRange(wsText, nStart, nCount);
+ RecoverParagEnd(wsText);
+ return;
+#endif
+}
+void CFDE_TxtEdtEngine::ClearText()
+{
+ DeleteRange(0, -1);
+}
+FX_INT32 CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF &rtCaret) const
+{
+ rtCaret = m_rtCaret;
+ return m_nCaret;
+}
+FX_INT32 CFDE_TxtEdtEngine::GetCaretPos() const
+{
+ if (IsLocked()) {
+ return 0;
+ }
+ return m_nCaret + (m_bBefore ? 0 : 1);
+}
+FX_INT32 CFDE_TxtEdtEngine::SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore)
+{
+ if (IsLocked()) {
+ return 0;
+ }
+ FXSYS_assert(nIndex >= 0 && nIndex <= GetTextBufLength());
+ if (m_PagePtrArray.GetSize() <= m_nCaretPage) {
+ return 0;
+ }
+#ifdef FDE_USEFORMATBLOCK
+ if (m_BlockArray.GetSize() > 0) {
+ nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_MIDDLE, bBefore);
+ }
+#endif
+ m_bBefore = bBefore;
+ m_nCaret = nIndex;
+ MovePage2Char(m_nCaret);
+ GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore);
+ if (!m_bBefore) {
+ m_nCaret ++;
+ m_bBefore = TRUE;
+ }
+ m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) ? \
+ m_rtCaret.top : m_rtCaret.left;
+ m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0);
+ m_nAnchorPos = -1;
+ return m_nCaret;
+}
+FX_INT32 CFDE_TxtEdtEngine::MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret,
+ FX_BOOL bShift ,
+ FX_BOOL bCtrl )
+{
+ if (IsLocked()) {
+ return 0;
+ }
+ if (m_PagePtrArray.GetSize() <= m_nCaretPage) {
+ return 0;
+ }
+ FX_BOOL bSelChange = FALSE;
+ if (IsSelect()) {
+ ClearSelection();
+ bSelChange = TRUE;
+ }
+ if (bShift) {
+ if (m_nAnchorPos == -1) {
+ m_nAnchorPos = m_nCaret;
+ }
+ } else {
+ m_nAnchorPos = -1;
+ }
+ FX_BOOL bVertical = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical;
+ FX_INT32 nCaret = m_nCaret;
+ FX_INT32 nCaretPage = m_nCaretPage;
+ switch (eMoveCaret) {
+ case MC_Left: {
+ if (bVertical) {
+ CFX_PointF ptCaret;
+ if (MoveUp(ptCaret)) {
+ UpdateCaretIndex(ptCaret);
+ }
+ } else {
+ FX_BOOL bBefore = TRUE;
+ FX_INT32 nIndex = MoveBackward(bBefore);
+#ifdef FDE_USEFORMATBLOCK
+ if (m_BlockArray.GetSize()) {
+ nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_BACKWARD, bBefore);
+ if (nIndex < 0) {
+ return m_nCaret;
+ }
+ }
+#endif
+ if (nIndex >= 0) {
+ UpdateCaretRect(nIndex, bBefore);
+ }
+ }
+ }
+ break;
+ case MC_Right: {
+ if (bVertical) {
+ CFX_PointF ptCaret;
+ if (MoveDown(ptCaret)) {
+ UpdateCaretIndex(ptCaret);
+ }
+ } else {
+ FX_BOOL bBefore = TRUE;
+ FX_INT32 nIndex = MoveForward(bBefore);
+#ifdef FDE_USEFORMATBLOCK
+ if (m_BlockArray.GetSize()) {
+ if (nIndex == -1) {
+ nIndex = GetTextBufLength();
+ }
+ nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_FORWARD, bBefore);
+ }
+#endif
+ if (nIndex >= 0) {
+ UpdateCaretRect(nIndex, bBefore);
+ }
+ }
+ }
+ break;
+ case MC_Up: {
+ if (bVertical) {
+ FX_BOOL bBefore = TRUE;
+ FX_INT32 nIndex = MoveBackward(bBefore);
+#ifdef FDE_USEFORMATBLOCK
+ if (m_BlockArray.GetSize()) {
+ nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_BACKWARD, bBefore);
+ }
+#endif
+ if (nIndex >= 0) {
+ UpdateCaretRect(nIndex, bBefore);
+ }
+ } else {
+ CFX_PointF ptCaret;
+ if (MoveUp(ptCaret)) {
+ UpdateCaretIndex(ptCaret);
+ }
+ }
+ }
+ break;
+ case MC_Down: {
+ if (bVertical) {
+ FX_BOOL bBefore = TRUE;
+ FX_INT32 nIndex = MoveForward(bBefore);
+#ifdef FDE_USEFORMATBLOCK
+ if (m_BlockArray.GetSize()) {
+ nIndex = NormalizeCaretPos(nIndex, FDE_FORMAT_CARET_FORWARD, bBefore);
+ }
+#endif
+ if (nIndex >= 0) {
+ UpdateCaretRect(nIndex, bBefore);
+ }
+ } else {
+ CFX_PointF ptCaret;
+ if (MoveDown(ptCaret)) {
+ UpdateCaretIndex(ptCaret);
+ }
+ }
+ }
+ break;
+ case MC_WordBackward:
+ break;
+ case MC_WordForward:
+ break;
+ case MC_LineStart:
+ MoveLineStart();
+ break;
+ case MC_LineEnd:
+ MoveLineEnd();
+ break;
+ case MC_ParagStart:
+ MoveParagStart();
+ break;
+ case MC_ParagEnd:
+ MoveParagEnd();
+ break;
+ case MC_PageDown:
+ break;
+ case MC_PageUp:
+ break;
+ case MC_Home:
+ MoveHome();
+ break;
+ case MC_End:
+ MoveEnd();
+ break;
+ default:
+ break;
+ }
+ if (bShift && m_nAnchorPos != -1 && (m_nAnchorPos != m_nCaret)) {
+ AddSelRange(FX_MIN(m_nAnchorPos, m_nCaret), FXSYS_abs(m_nAnchorPos - m_nCaret));
+ m_Param.pEventSink->On_SelChanged(this);
+ }
+ if (bSelChange) {
+ m_Param.pEventSink->On_SelChanged(this);
+ }
+ return m_nCaret;
+}
+void CFDE_TxtEdtEngine::Lock()
+{
+ m_bLock = TRUE;
+}
+void CFDE_TxtEdtEngine::Unlock()
+{
+ m_bLock = FALSE;
+}
+FX_BOOL CFDE_TxtEdtEngine::IsLocked() const
+{
+ return m_bLock;
+}
+FX_INT32 CFDE_TxtEdtEngine::Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLength)
+{
+ if (IsLocked()) {
+ return FDE_TXTEDT_MODIFY_RET_F_Locked;
+ }
+#ifdef FDE_USEFORMATBLOCK
+ FX_INT32 nBlockCount = m_BlockArray.GetSize();
+ if (nBlockCount) {
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_FIELD_TAB && nLength == 1 && lpText[0] == L'\t') {
+ return Move2NextEditableField(nStart) ? FDE_TXTEDT_MODIFY_RET_T_Tab : \
+ FDE_TXTEDT_MODIFY_RET_F_Tab;
+ }
+ FX_INT32 nSelRangeCount = CountSelRanges();
+ if (nSelRangeCount > 0) {
+ if (nSelRangeCount > 1) {
+ return FDE_TXTEDT_MODIFY_RET_F_Boundary;
+ }
+ FX_INT32 nSelStart;
+ FX_INT32 nSelCount;
+ nSelCount = GetSelRange(0, nSelStart);
+ FX_INT32 nSelEnd = nSelStart + nSelCount;
+ FX_INT32 nBgn = 0;
+ FX_INT32 nEnd = 0;
+ CFDE_TxtEdtField * pField = NULL;
+ FX_BOOL bInField = GetFieldBoundary(nSelStart, nBgn, nEnd, pField);
+ if (nSelEnd > nEnd) {
+ return FDE_TXTEDT_MODIFY_RET_F_Boundary;
+ }
+ if (bInField) {
+ pField->Backup();
+ FX_BOOL bBefore = FALSE;
+ CFX_WideString wsDel;
+ FX_INT32 nCaret;
+ FX_INT32 nIndexInField = nSelStart - nBgn;
+ FX_INT32 nRet = pField->Replace(nSelStart - nBgn, nSelCount, CFX_WideStringC(lpText, nLength), wsDel, nCaret, bBefore);
+ switch(nRet) {
+ case FDE_FORMAT_FIELD_INSERT_RET_F_FULL:
+ pField->Restore();
+ return FDE_TXTEDT_MODIFY_RET_F_Full;
+ case FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE:
+ pField->Restore();
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ default:
+ break;
+ }
+ CFX_WideString wsField;
+ pField->GetFieldText(wsField);
+ if (!m_Param.pEventSink->On_ValidateField(this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) {
+ pField->Restore();
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ }
+ CFX_WideString wsDisplay;
+ pField->GetDisplayText(wsDisplay);
+ if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) || (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) {
+ CFX_WideString wsText;
+ GetPreReplaceText(wsText, nBgn, nEnd - nBgn + 1, FX_LPCWSTR(wsDisplay), wsDisplay.GetLength());
+ if (!IsFitArea(wsText)) {
+ pField->Restore();
+ return FDE_TXTEDT_MODIFY_RET_F_Full;
+ }
+ }
+ Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
+ FX_INT32 nNewCaret = nBgn + nCaret;
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
+ IFDE_TxtEdtDoRecord * pRecord = FX_NEW CFDE_TxtEdtDoRecord_FieldReplace(this, \
+ m_nCaret, nNewCaret, pField, nIndexInField, nBgn, wsDisplay.GetLength(), \
+ wsDel, CFX_WideStringC(lpText, nLength), TRUE);
+ CFX_ByteString bsDoRecord;
+ pRecord->Serialize(bsDoRecord);
+ m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
+ pRecord->Release();
+ }
+ SetCaretPos(nBgn + nCaret, bBefore);
+ return FDE_TXTEDT_MODIFY_RET_S_Normal;
+ }
+ }
+ FX_INT32 nBgn = 0;
+ FX_INT32 nEnd = 0;
+ CFDE_TxtEdtField * pField = NULL;
+ FX_BOOL bInField = GetFieldBoundary(m_nCaret, nBgn, nEnd, pField);
+ FX_INT32 nCaretInField = m_nCaret - nBgn;
+ FX_BOOL bBefore = FALSE;
+ if (bInField) {
+ pField->Backup();
+ CFX_WideStringC wsIns(lpText, nLength);
+ FX_INT32 nRet = pField->Insert(nCaretInField, wsIns, nCaretInField, bBefore);
+ FX_BOOL bFull = FALSE;
+ switch (nRet) {
+ case FDE_FORMAT_FIELD_INSERT_RET_S_NORMAL:
+ break;
+ case FDE_FORMAT_FIELD_INSERT_RET_S_FULL:
+ bFull = TRUE;
+ break;
+ case FDE_FORMAT_FIELD_INSERT_RET_F_FULL:
+ return FDE_TXTEDT_MODIFY_RET_F_Full;
+ case FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE:
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ default:
+ return FDE_TXTEDT_MODIFY_RET_F_Normal;
+ }
+ CFX_WideString wsField;
+ pField->GetFieldText(wsField);
+ if (!m_Param.pEventSink->On_ValidateField(this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) {
+ pField->Restore();
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ }
+ CFX_WideString wsDisplay;
+ pField->GetDisplayText(wsDisplay);
+ if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) || (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) {
+ CFX_WideString wsText;
+ GetPreReplaceText(wsText, nBgn, nEnd - nBgn + 1, FX_LPCWSTR(wsDisplay), wsDisplay.GetLength());
+ if (!IsFitArea(wsText)) {
+ pField->Restore();
+ return FDE_TXTEDT_MODIFY_RET_F_Full;
+ }
+ }
+ Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
+ IFDE_TxtEdtDoRecord * pRecord = FX_NEW CFDE_TxtEdtDoRecord_FieldInsert(this, \
+ m_nCaret, pField, m_nCaret - nBgn, nBgn, \
+ nEnd - nBgn + 1, wsDisplay.GetLength(), \
+ CFX_WideStringC(lpText, nLength), FALSE);
+ CFX_ByteString bsDoRecord;
+ pRecord->Serialize(bsDoRecord);
+ m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
+ pRecord->Release();
+ }
+ FX_INT32 nCaretPos = nBgn + nCaretInField;
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_FIELD_AUTO && bFull && nCaretPos == nEnd) {
+ if (Move2NextEditableField(nEnd, TRUE, FALSE)) {
+ return TRUE;
+ }
+ }
+ SetCaretPos(nCaretPos, bBefore);
+ return bFull ? FDE_TXTEDT_MODIFY_RET_S_Full : FDE_TXTEDT_MODIFY_RET_S_Normal;
+ }
+ FXSYS_assert(0);
+ return FDE_TXTEDT_MODIFY_RET_F_Normal;
+ }
+#endif
+ CFX_WideString wsTemp;
+ FX_LPWSTR lpBuffer = wsTemp.GetBuffer(nLength);
+ FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR));
+ ReplaceParagEnd(lpBuffer, nLength, FALSE);
+ wsTemp.ReleaseBuffer(nLength);
+ FX_BOOL bPart = FALSE;
+ if (m_nLimit > 0) {
+ FX_INT32 nTotalLength = GetTextBufLength();
+ FX_INT32 nDelLength = 0;
+ FX_INT32 nCount = m_SelRangePtrArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FDE_LPTXTEDTSELRANGE lpSelRange = m_SelRangePtrArr.GetAt(i);
+ nTotalLength -= lpSelRange->nCount;
+ }
+ FX_INT32 nExpectLength = nTotalLength + nLength;
+ if (nTotalLength == m_nLimit) {
+ return FDE_TXTEDT_MODIFY_RET_F_Full;
+ }
+ if (nExpectLength > m_nLimit) {
+ nLength -= (nExpectLength - m_nLimit);
+ bPart = TRUE;
+ }
+ }
+ if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) || (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) {
+ FX_INT32 nTemp = nLength;
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_Password) {
+ CFX_WideString wsText;
+ while (nLength > 0) {
+ GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
+ FX_INT32 nTotal = wsText.GetLength();
+ FX_LPWSTR lpBuf = wsText.GetBuffer(nTotal);
+ for (FX_INT32 i = 0; i < nTotal; i ++) {
+ lpBuf[i] = m_wcAliasChar;
+ }
+ wsText.ReleaseBuffer(nTotal);
+ if (IsFitArea(wsText)) {
+ break;
+ }
+ nLength --;
+ }
+ } else {
+ CFX_WideString wsText;
+ while (nLength > 0) {
+ GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
+ if (IsFitArea(wsText)) {
+ break;
+ }
+ nLength --;
+ }
+ }
+ if (nLength == 0) {
+ return FDE_TXTEDT_MODIFY_RET_F_Full;
+ }
+ if (nLength < nTemp) {
+ bPart = TRUE;
+ }
+ }
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
+ CFX_WideString wsText;
+ GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
+ if (!m_Param.pEventSink->On_Validate(this, wsText)) {
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ }
+ }
+ if (IsSelect()) {
+ DeleteSelect();
+ }
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
+ IFDE_TxtEdtDoRecord * pRecord = FX_NEW CFDE_TxtEdtDoRecord_Insert(this, m_nCaret, lpBuffer, nLength);
+ CFX_ByteString bsDoRecord;
+ pRecord->Serialize(bsDoRecord);
+ m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
+ pRecord->Release();
+ }
+ GetText(m_ChangeInfo.wsPrevText, 0);
+ Inner_Insert(m_nCaret, lpBuffer, nLength);
+ m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
+ m_ChangeInfo.wsInsert = CFX_WideString(lpBuffer, nLength);
+ nStart = m_nCaret;
+ nStart += nLength;
+ FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1);
+ FX_BOOL bBefore = TRUE;
+ if (wChar != L'\n' && wChar != L'\r') {
+ nStart --;
+ bBefore = FALSE;
+ }
+ SetCaretPos(nStart, bBefore);
+ m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
+ return bPart ? FDE_TXTEDT_MODIFY_RET_S_Part : FDE_TXTEDT_MODIFY_RET_S_Normal;
+}
+FX_INT32 CFDE_TxtEdtEngine::Delete(FX_INT32 nStart, FX_BOOL bBackspace )
+{
+ if (IsLocked()) {
+ return FDE_TXTEDT_MODIFY_RET_F_Locked;
+ }
+ if (IsSelect()) {
+ DeleteSelect();
+ return FDE_TXTEDT_MODIFY_RET_S_Normal;
+ }
+#ifdef FDE_USEFORMATBLOCK
+ FX_INT32 nBlockCount = m_BlockArray.GetSize();
+ if (nBlockCount > 0) {
+ if (bBackspace) {
+ nStart --;
+ }
+ FX_INT32 nCount = 1;
+ FX_INT32 nBgn = 0;
+ FX_INT32 nEnd = 0;
+ CFDE_TxtEdtField * pField = NULL;
+ FX_BOOL bInField = GetFieldBoundary(nStart, nBgn, nEnd, pField);
+ FX_INT32 nCaretInField = nStart - nBgn;
+ FX_BOOL bBefore = FALSE;
+ if (bInField && !pField->IsFix()) {
+ pField->Backup();
+ CFX_WideString wsDel;
+ FX_INT32 nCaret = 0;
+ FX_INT32 nRet = pField->Delete(nCaretInField, nCount, wsDel, nCaret, bBefore);
+ nCaret += nBgn;
+ switch (nRet) {
+ case FDE_FORMAT_FIELD_DELETE_RET_S:
+ break;
+ case FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE:
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ case FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY:
+ return FDE_TXTEDT_MODIFY_RET_F_Boundary;
+ default:
+ FXSYS_assert(0);
+ break;
+ }
+ CFX_WideString wsField;
+ pField->GetFieldText(wsField);
+ if (!m_Param.pEventSink->On_ValidateField(this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) {
+ pField->Restore();
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ }
+ CFX_WideString wsDisplay;
+ pField->GetDisplayText(wsDisplay);
+ Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
+ IFDE_TxtEdtDoRecord * pRecord = FX_NEW CFDE_TxtEdtDoRecord_FieldDelete(this, nStart, pField, nCaretInField,
+ nBgn, nEnd - nBgn + 1, wsDisplay.GetLength(), wsDel, FALSE);
+ CFX_ByteString bsDoRecord;
+ pRecord->Serialize(bsDoRecord);
+ m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
+ pRecord->Release();
+ }
+ SetCaretPos(nStart, bBefore);
+ return FDE_TXTEDT_MODIFY_RET_S_Normal;
+ }
+ return FDE_TXTEDT_MODIFY_RET_F_Boundary;
+ }
+#endif
+ FX_INT32 nCount = 1;
+ if (bBackspace) {
+ if (nStart == 0) {
+ return FDE_TXTEDT_MODIFY_RET_F_Boundary;
+ }
+ if (nStart > 2 && m_pTxtBuf->GetCharByIndex(nStart - 1) == L'\n' && \
+ m_pTxtBuf->GetCharByIndex(nStart - 2) == L'\r') {
+ nStart --;
+ nCount ++;
+ }
+ nStart --;
+ } else {
+ if (nStart == GetTextBufLength()) {
+ return FDE_TXTEDT_MODIFY_RET_F_Full;
+ }
+ if ((nStart + 1 < GetTextBufLength()) && (m_pTxtBuf->GetCharByIndex(nStart) == L'\r') && \
+ (m_pTxtBuf->GetCharByIndex(nStart + 1) == L'\n')) {
+ nCount ++;
+ }
+ }
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
+ CFX_WideString wsText;
+ GetPreDeleteText(wsText, nStart, nCount);
+ if (!m_Param.pEventSink->On_Validate(this, wsText)) {
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ }
+ }
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
+ CFX_WideString wsRange;
+ m_pTxtBuf->GetRange(wsRange, nStart, nCount);
+ IFDE_TxtEdtDoRecord * pRecord = FX_NEW CFDE_TxtEdtDoRecord_DeleteRange(this, nStart, m_nCaret, wsRange);
+ CFX_ByteString bsDoRecord;
+ pRecord->Serialize(bsDoRecord);
+ m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
+ pRecord->Release();
+ }
+ m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
+ GetText(m_ChangeInfo.wsDelete, nStart, nCount);
+ Inner_DeleteRange(nStart, nCount);
+ SetCaretPos(nStart + ((!bBackspace && nStart > 0) ? -1 : 0), (bBackspace || nStart == 0));
+ m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
+ return FDE_TXTEDT_MODIFY_RET_S_Normal;
+}
+FX_INT32 CFDE_TxtEdtEngine::DeleteRange(FX_INT32 nStart, FX_INT32 nCount )
+{
+ if (IsLocked()) {
+ return FDE_TXTEDT_MODIFY_RET_F_Locked;
+ }
+ if (nCount == -1) {
+ nCount = GetTextBufLength();
+ }
+ if (nCount == 0) {
+ return FDE_TXTEDT_MODIFY_RET_S_Normal;
+ }
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
+ CFX_WideString wsText;
+ GetPreDeleteText(wsText, nStart, nCount);
+ if (!m_Param.pEventSink->On_Validate(this, wsText)) {
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ }
+ }
+ DeleteRange_DoRecord(nStart, nCount);
+ m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
+ SetCaretPos(nStart, TRUE);
+ return FDE_TXTEDT_MODIFY_RET_S_Normal;
+}
+FX_INT32 CFDE_TxtEdtEngine::Replace(FX_INT32 nStart, FX_INT32 nLength, const CFX_WideString &wsReplace)
+{
+ if (IsLocked()) {
+ return FDE_TXTEDT_MODIFY_RET_F_Locked;
+ }
+ if (nStart < 0 || (nStart + nLength > GetTextBufLength())) {
+ return FDE_TXTEDT_MODIFY_RET_F_Boundary;
+ }
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
+ CFX_WideString wsText;
+ GetPreReplaceText(wsText, nStart, nLength, FX_LPCWSTR(wsReplace), wsReplace.GetLength());
+ if (!m_Param.pEventSink->On_Validate(this, wsText)) {
+ return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
+ }
+ }
+ if (IsSelect()) {
+ ClearSelection();
+ }
+ m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Replace;
+ GetText(m_ChangeInfo.wsDelete, nStart, nLength);
+ if (nLength > 0) {
+ Inner_DeleteRange(nStart, nLength);
+ }
+ FX_INT32 nTextLength = wsReplace.GetLength();
+ if (nTextLength > 0) {
+ Inner_Insert(nStart, FX_LPCWSTR(wsReplace), nTextLength);
+ }
+ m_ChangeInfo.wsInsert = CFX_WideString(FX_LPCWSTR(wsReplace), nTextLength);
+ nStart += nTextLength;
+ FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1);
+ FX_BOOL bBefore = TRUE;
+ if (wChar != L'\n' && wChar != L'\r') {
+ nStart --;
+ bBefore = FALSE;
+ }
+ SetCaretPos(nStart, bBefore);
+ m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
+ m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
+ m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
+ return FDE_TXTEDT_MODIFY_RET_S_Normal;
+}
+void CFDE_TxtEdtEngine::SetLimit(FX_INT32 nLimit)
+{
+ m_nLimit = nLimit;
+}
+void CFDE_TxtEdtEngine::SetAliasChar(FX_WCHAR wcAlias)
+{
+ m_wcAliasChar = wcAlias;
+}
+void CFDE_TxtEdtEngine::SetFormatBlock(FX_INT32 nIndex, const CFX_WideString &wsBlockFormat)
+{
+#ifdef FDE_USEFORMATBLOCK
+ if (m_nFixLength == -1) {
+ m_nFixLength = GetTextLength();
+ FXSYS_assert(m_wsFixText.IsEmpty());
+ GetText(m_wsFixText, 0, -1);
+ }
+ FX_BOOL bInBlock = FALSE;
+ FX_INT32 nCharIndex = 0;
+ FX_INT32 nBlockIndex = 0;
+ FX_INT32 nBlockPos = -1;
+ FX_WCHAR wc;
+ CFDE_TxtEdtBufIter * pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
+ pIter->SetAt(0);
+ do {
+ wc = pIter->GetChar();
+ if (bInBlock) {
+ if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
+ nBlockIndex ++;
+ bInBlock = FALSE;
+ }
+ } else {
+ if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
+ bInBlock = TRUE;
+ } else {
+ if (nCharIndex ++ == nIndex) {
+ nBlockPos = pIter->GetAt();
+ break;
+ }
+ }
+ }
+ } while (pIter->Next());
+ pIter->Release();
+ if (nBlockPos == -1) {
+ nBlockPos = GetTextBufLength();
+ }
+ CFDE_TxtEdtBlock * pEditBlock = FX_NEW CFDE_TxtEdtBlock(this, wsBlockFormat, nIndex);
+ m_BlockArray.InsertAt(m_BlockArray.GetSize(), pEditBlock);
+ CFX_WideString wsDisplay;
+ pEditBlock->GetDisplayText(wsDisplay);
+ m_nCaret = nBlockPos;
+ if (wsDisplay.GetLength() > 0) {
+ RawInsert(nBlockPos, FX_LPCWSTR(wsDisplay), wsDisplay.GetLength());
+ }
+#endif
+}
+FX_INT32 CFDE_TxtEdtEngine::CountEditBlocks() const
+{
+#ifdef FDE_USEFORMATBLOCK
+ return m_BlockArray.GetSize();
+#else
+ return 0;
+#endif
+}
+void CFDE_TxtEdtEngine::GetEditBlockText(FX_INT32 nIndex, CFX_WideString &wsBlockText) const
+{
+#ifdef FDE_USEFORMATBLOCK
+ CFDE_TxtEdtBlock * pBlock = m_BlockArray[nIndex];
+ pBlock->GetBlockText(wsBlockText);
+#endif
+}
+FX_INT32 CFDE_TxtEdtEngine::CountEditFields(FX_INT32 nBlockIndex) const
+{
+#ifdef FDE_USEFORMATBLOCK
+ CFDE_TxtEdtBlock * pBlock = m_BlockArray[nBlockIndex];
+ return pBlock->CountField();
+#else
+ return 0;
+#endif
+}
+void CFDE_TxtEdtEngine::GetEditFieldText(FX_INT32 nBlockIndex, FX_INT32 nFieldIndex, CFX_WideString &wsFieldText) const
+{
+#ifdef FDE_USEFORMATBLOCK
+ CFDE_TxtEdtBlock * pBlock = m_BlockArray[nBlockIndex];
+ pBlock->GetFieldText(nFieldIndex, wsFieldText);
+#endif
+}
+void CFDE_TxtEdtEngine::StartEdit()
+{
+#ifdef FDE_USEFORMATBLOCK
+#endif
+}
+void CFDE_TxtEdtEngine::EndEdit()
+{
+#ifdef FDE_USEFORMATBLOCK
+#endif
+}
+void CFDE_TxtEdtEngine::RemoveSelRange(FX_INT32 nStart, FX_INT32 nCount )
+{
+ FDE_LPTXTEDTSELRANGE lpTemp = NULL;
+ FX_INT32 nRangeCount = m_SelRangePtrArr.GetSize();
+ FX_INT32 i = 0;
+ for (i = 0; i < nRangeCount; i ++) {
+ lpTemp = m_SelRangePtrArr[i];
+ if (lpTemp->nStart == nStart && lpTemp->nCount == nCount) {
+ delete lpTemp;
+ m_SelRangePtrArr.RemoveAt(i);
+ return;
+ }
+ }
+ return;
+}
+void CFDE_TxtEdtEngine::AddSelRange(FX_INT32 nStart, FX_INT32 nCount )
+{
+ if (nCount == -1) {
+ nCount = GetTextLength() - nStart;
+ }
+ FX_INT32 nSize = m_SelRangePtrArr.GetSize();
+ if (nSize <= 0) {
+ FDE_LPTXTEDTSELRANGE lpSelRange = FX_NEW FDE_TXTEDTSELRANGE;
+ lpSelRange->nStart = nStart;
+ lpSelRange->nCount = nCount;
+ m_SelRangePtrArr.Add(lpSelRange);
+ m_Param.pEventSink->On_SelChanged(this);
+ return;
+ }
+ FDE_LPTXTEDTSELRANGE lpTemp = NULL;
+ lpTemp = m_SelRangePtrArr[nSize - 1];
+ if (nStart >= lpTemp->nStart + lpTemp->nCount) {
+ FDE_LPTXTEDTSELRANGE lpSelRange = FX_NEW FDE_TXTEDTSELRANGE;
+ lpSelRange->nStart = nStart;
+ lpSelRange->nCount = nCount;
+ m_SelRangePtrArr.Add(lpSelRange);
+ m_Param.pEventSink->On_SelChanged(this);
+ return;
+ }
+ FX_INT32 nEnd = nStart + nCount - 1;
+ FX_BOOL bBegin = FALSE;
+ FX_INT32 nRangeBgn = 0;
+ FX_INT32 nRangeCnt = 0;
+ for (FX_INT32 i = 0; i < nSize; i ++) {
+ lpTemp = m_SelRangePtrArr[i];
+ FX_INT32 nTempBgn = lpTemp->nStart;
+ FX_INT32 nTempEnd = nTempBgn + lpTemp->nCount - 1;
+ if (bBegin) {
+ if (nEnd < nTempBgn) {
+ break;
+ } else if (nStart >= nTempBgn && nStart <= nTempEnd) {
+ nRangeCnt ++;
+ break;
+ }
+ nRangeCnt ++;
+ } else {
+ if (nStart <= nTempEnd) {
+ nRangeBgn = i;
+ if (nEnd < nTempBgn) {
+ break;
+ }
+ nRangeCnt = 1;
+ bBegin = TRUE;
+ }
+ }
+ }
+ if (nRangeCnt == 0) {
+ FDE_LPTXTEDTSELRANGE lpSelRange = FX_NEW FDE_TXTEDTSELRANGE;
+ lpSelRange->nStart = nStart;
+ lpSelRange->nCount = nCount;
+ m_SelRangePtrArr.InsertAt(nRangeBgn, lpSelRange);
+ } else {
+ lpTemp = m_SelRangePtrArr[nRangeBgn];
+ lpTemp->nStart = nStart;
+ lpTemp->nCount = nCount;
+ nRangeCnt --;
+ nRangeBgn ++;
+ while (nRangeCnt--) {
+ delete m_SelRangePtrArr[nRangeBgn];
+ m_SelRangePtrArr.RemoveAt(nRangeBgn);
+ }
+ }
+ m_Param.pEventSink->On_SelChanged(this);
+ return;
+}
+FX_INT32 CFDE_TxtEdtEngine::CountSelRanges()
+{
+ return m_SelRangePtrArr.GetSize();
+}
+FX_INT32 CFDE_TxtEdtEngine::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ nStart = m_SelRangePtrArr[nIndex]->nStart;
+ return m_SelRangePtrArr[nIndex]->nCount;
+}
+void CFDE_TxtEdtEngine::ClearSelection()
+{
+ FX_INT32 nCount = m_SelRangePtrArr.GetSize();
+ FDE_LPTXTEDTSELRANGE lpRange = NULL;
+ FX_INT32 i = 0;
+ for (i = 0; i < nCount; i ++) {
+ lpRange = m_SelRangePtrArr[i];
+ if (lpRange != NULL) {
+ delete lpRange;
+ lpRange = NULL;
+ }
+ }
+ m_SelRangePtrArr.RemoveAll();
+ if (nCount && m_Param.pEventSink) {
+ m_Param.pEventSink->On_SelChanged(this);
+ }
+}
+FX_BOOL CFDE_TxtEdtEngine::Redo(FX_BSTR bsRedo)
+{
+ if (IsLocked()) {
+ return FALSE;
+ }
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) {
+ return FALSE;
+ }
+ IFDE_TxtEdtDoRecord * pDoRecord = IFDE_TxtEdtDoRecord::Create(bsRedo);
+ FXSYS_assert(pDoRecord);
+ if (pDoRecord == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bOK = pDoRecord->Redo();
+ pDoRecord->Release();
+ return bOK;
+}
+FX_BOOL CFDE_TxtEdtEngine::Undo(FX_BSTR bsUndo)
+{
+ if (IsLocked()) {
+ return FALSE;
+ }
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) {
+ return FALSE;
+ }
+ IFDE_TxtEdtDoRecord * pDoRecord = IFDE_TxtEdtDoRecord::Create(bsUndo);
+ FXSYS_assert(pDoRecord);
+ if (pDoRecord == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bOK = pDoRecord->Undo();
+ pDoRecord->Release();
+ return bOK;
+}
+FX_INT32 CFDE_TxtEdtEngine::StartLayout()
+{
+ Lock();
+ RemoveAllPages();
+ m_nLayoutPos = 0;
+ m_nLineCount = 0;
+ return 0;
+}
+FX_INT32 CFDE_TxtEdtEngine::DoLayout(IFX_Pause * pPause)
+{
+ FX_INT32 nCount = m_ParagPtrArray.GetSize();
+ CFDE_TxtEdtParag * pParag = NULL;
+ FX_INT32 nLineCount = 0;
+ for (; m_nLayoutPos < nCount; m_nLayoutPos ++) {
+ pParag = m_ParagPtrArray[m_nLayoutPos];
+ pParag->CalcLines();
+ nLineCount += pParag->m_nLineCount;
+ if ((pPause != NULL) && (nLineCount > m_nPageLineCount) && pPause->NeedToPauseNow()) {
+ m_nLineCount += nLineCount;
+ return (++m_nLayoutPos * 100) / nCount;
+ }
+ }
+ m_nLineCount += nLineCount;
+ return 100;
+}
+void CFDE_TxtEdtEngine::EndLayout()
+{
+ UpdatePages();
+ FX_INT32 nLength = GetTextLength();
+ if (m_nCaret > nLength) {
+ m_nCaret = nLength;
+ }
+ FX_INT32 nIndex = m_nCaret;
+ if (!m_bBefore) {
+ nIndex --;
+ }
+ m_rtCaret.Set(0, 0, 1, m_Param.fFontSize);
+ Unlock();
+}
+FX_BOOL CFDE_TxtEdtEngine::Optimize(IFX_Pause * pPause )
+{
+ return m_pTxtBuf->Optimize(pPause);
+}
+IFDE_TxtEdtBuf * CFDE_TxtEdtEngine::GetTextBuf() const
+{
+ return (IFDE_TxtEdtBuf*)m_pTxtBuf;
+}
+FX_INT32 CFDE_TxtEdtEngine::GetTextBufLength() const
+{
+ return m_pTxtBuf->GetTextLength() - 1;
+}
+IFX_TxtBreak * CFDE_TxtEdtEngine::GetTextBreak() const
+{
+ return m_pTextBreak;
+}
+FX_INT32 CFDE_TxtEdtEngine::GetLineCount() const
+{
+ return m_nLineCount;
+}
+FX_INT32 CFDE_TxtEdtEngine::GetPageLineCount() const
+{
+ return m_nPageLineCount;
+}
+FX_INT32 CFDE_TxtEdtEngine::CountParags() const
+{
+ return m_ParagPtrArray.GetSize();
+}
+IFDE_TxtEdtParag* CFDE_TxtEdtEngine::GetParag(FX_INT32 nParagIndex) const
+{
+ return m_ParagPtrArray[nParagIndex];
+}
+IFX_CharIter* CFDE_TxtEdtEngine::CreateCharIter()
+{
+ if (!m_pTxtBuf) {
+ return NULL;
+ }
+ return FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf);
+}
+FX_INT32 CFDE_TxtEdtEngine::Line2Parag(FX_INT32 nStartParag, FX_INT32 nStartLineofParag, \
+ FX_INT32 nLineIndex, FX_INT32 &nStartLine) const
+{
+ FX_INT32 nLineTotal = nStartLineofParag;
+ FX_INT32 nCount = m_ParagPtrArray.GetSize();
+ CFDE_TxtEdtParag * pParag = NULL;
+ FX_INT32 i = nStartParag;
+ for (; i < nCount; i ++) {
+ pParag = m_ParagPtrArray[i];
+ nLineTotal += pParag->m_nLineCount;
+ if (nLineTotal > nLineIndex) {
+ break;
+ }
+ }
+ nStartLine = nLineTotal - pParag->m_nLineCount;
+ return i;
+}
+void CFDE_TxtEdtEngine::GetPreDeleteText(CFX_WideString &wsText, FX_INT32 nIndex, FX_INT32 nLength)
+{
+ GetText(wsText, 0, GetTextBufLength());
+ wsText.Delete(nIndex, nLength);
+}
+void CFDE_TxtEdtEngine::GetPreInsertText(CFX_WideString &wsText, FX_INT32 nIndex, FX_LPCWSTR lpText, FX_INT32 nLength)
+{
+ GetText(wsText, 0, GetTextBufLength());
+ FX_INT32 nSelIndex = 0;
+ FX_INT32 nSelLength = 0;
+ FX_INT32 nSelCount = CountSelRanges();
+ while (nSelCount --) {
+ nSelLength = GetSelRange(nSelCount, nSelIndex);
+ wsText.Delete(nSelIndex, nSelLength);
+ nIndex = nSelIndex;
+ }
+ CFX_WideString wsTemp;
+ FX_INT32 nOldLength = wsText.GetLength();
+ FX_LPCWSTR pOldBuffer = FX_LPCWSTR(wsText);
+ FX_LPWSTR lpBuffer = wsTemp.GetBuffer(nOldLength + nLength);
+ FXSYS_memcpy(lpBuffer, pOldBuffer, (nIndex) * sizeof(FX_WCHAR));
+ FXSYS_memcpy(lpBuffer + nIndex, lpText, nLength * sizeof(FX_WCHAR));
+ FXSYS_memcpy(lpBuffer + nIndex + nLength, pOldBuffer + nIndex, (nOldLength - nIndex) * sizeof(FX_WCHAR));
+ wsTemp.ReleaseBuffer(nOldLength + nLength);
+ wsText = wsTemp;
+}
+void CFDE_TxtEdtEngine::GetPreReplaceText(CFX_WideString &wsText, FX_INT32 nIndex, FX_INT32 nOriginLength, FX_LPCWSTR lpText, FX_INT32 nLength)
+{
+ GetText(wsText, 0, GetTextBufLength());
+ FX_INT32 nSelIndex = 0;
+ FX_INT32 nSelLength = 0;
+ FX_INT32 nSelCount = CountSelRanges();
+ while (nSelCount --) {
+ nSelLength = GetSelRange(nSelCount, nSelIndex);
+ wsText.Delete(nSelIndex, nSelLength);
+ }
+ wsText.Delete(nIndex, nOriginLength);
+ FX_INT32 i = 0;
+ for (i = 0; i < nLength; i ++) {
+ wsText.Insert(nIndex ++, lpText[i]);
+ }
+}
+void CFDE_TxtEdtEngine::Inner_Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLength)
+{
+ FXSYS_assert(nLength > 0);
+ FDE_TXTEDTPARAGPOS ParagPos;
+ TextPos2ParagPos(nStart, ParagPos);
+ m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
+ FX_INT32 nParagCount = m_ParagPtrArray.GetSize();
+ FX_INT32 i = 0;
+ for (i = ParagPos.nParagIndex + 1; i < nParagCount; i ++) {
+ m_ParagPtrArray[i]->m_nCharStart += nLength;
+ }
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[ParagPos.nParagIndex];
+ FX_INT32 nReserveLineCount = pParag->m_nLineCount;
+ FX_INT32 nReserveCharStart = pParag->m_nCharStart;
+ FX_INT32 nLeavePart = ParagPos.nCharIndex;
+ FX_INT32 nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex;
+ FX_INT32 nTextStart = 0;
+ FX_WCHAR wCurChar = L' ';
+ FX_LPCWSTR lpPos = lpText;
+ FX_BOOL bFirst = TRUE;
+ FX_INT32 nParagIndex = ParagPos.nParagIndex;
+ for (i = 0; i < nLength; i ++, lpPos ++) {
+ wCurChar = *lpPos;
+ if (wCurChar == m_wLineEnd) {
+ if (bFirst) {
+ pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1);
+ pParag->m_nLineCount = -1;
+ nReserveCharStart += pParag->m_nCharCount;
+ bFirst = FALSE;
+ } else {
+ pParag = FX_NEW CFDE_TxtEdtParag(this);
+ pParag->m_nLineCount = -1;
+ pParag->m_nCharCount = i - nTextStart + 1;
+ pParag->m_nCharStart = nReserveCharStart;
+ m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
+ nReserveCharStart += pParag->m_nCharCount;
+ }
+ nTextStart = i + 1;
+ }
+ }
+ if (bFirst) {
+ pParag->m_nCharCount += nLength;
+ pParag->m_nLineCount = -1;
+ bFirst = FALSE;
+ } else {
+ pParag = FX_NEW CFDE_TxtEdtParag(this);
+ pParag->m_nLineCount = -1;
+ pParag->m_nCharCount = nLength - nTextStart + nCutPart;
+ pParag->m_nCharStart = nReserveCharStart;
+ m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
+ }
+ m_pTxtBuf->Insert(nStart, lpText, nLength);
+ FX_INT32 nTotalLineCount = 0;
+ for (i = ParagPos.nParagIndex; i <= nParagIndex; i ++) {
+ pParag = m_ParagPtrArray[i];
+ pParag->CalcLines();
+ nTotalLineCount += pParag->m_nLineCount;
+ }
+ m_nLineCount += nTotalLineCount - nReserveLineCount;
+ m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
+ UpdatePages();
+}
+#ifdef FDE_USEFORMATBLOCK
+void CFDE_TxtEdtEngine::RawInsert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLength)
+{
+ FXSYS_assert(nLength > 0);
+ FDE_TXTEDTPARAGPOS ParagPos;
+ TextPos2ParagPos(nStart, ParagPos);
+ FX_INT32 nParagCount = m_ParagPtrArray.GetSize();
+ FX_INT32 i = 0;
+ for (i = ParagPos.nParagIndex + 1; i < nParagCount; i ++) {
+ m_ParagPtrArray[i]->m_nCharStart += nLength;
+ }
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[ParagPos.nParagIndex];
+ FX_INT32 nReserveLineCount = pParag->m_nLineCount;
+ FX_INT32 nReserveCharStart = pParag->m_nCharStart;
+ FX_INT32 nLeavePart = ParagPos.nCharIndex;
+ FX_INT32 nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex;
+ FX_INT32 nTextStart = 0;
+ FX_WCHAR wCurChar = L' ';
+ FX_LPCWSTR lpPos = lpText;
+ FX_BOOL bFirst = TRUE;
+ FX_INT32 nParagIndex = ParagPos.nParagIndex;
+ for (i = 0; i < nLength; i ++, lpPos ++) {
+ wCurChar = *lpPos;
+ if (wCurChar == m_wLineEnd) {
+ if (bFirst) {
+ pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1);
+ pParag->m_nLineCount = -1;
+ nReserveCharStart += pParag->m_nCharCount;
+ bFirst = FALSE;
+ } else {
+ pParag = FX_NEW CFDE_TxtEdtParag(this);
+ pParag->m_nLineCount = -1;
+ pParag->m_nCharCount = i - nTextStart + 1;
+ pParag->m_nCharStart = nReserveCharStart;
+ m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
+ nReserveCharStart += pParag->m_nCharCount;
+ }
+ nTextStart = i + 1;
+ }
+ }
+ if (bFirst) {
+ pParag->m_nCharCount += nLength;
+ pParag->m_nLineCount = -1;
+ bFirst = FALSE;
+ } else {
+ pParag = FX_NEW CFDE_TxtEdtParag(this);
+ pParag->m_nLineCount = -1;
+ pParag->m_nCharCount = nLength - nTextStart + nCutPart;
+ pParag->m_nCharStart = nReserveCharStart;
+ m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
+ }
+ m_pTxtBuf->Insert(nStart, lpText, nLength);
+}
+#endif
+void CFDE_TxtEdtEngine::Inner_DeleteRange(FX_INT32 nStart, FX_INT32 nCount )
+{
+ if (nCount == -1) {
+ nCount = m_pTxtBuf->GetTextLength() - nStart;
+ }
+ FX_INT32 nEnd = nStart + nCount - 1;
+ FXSYS_assert(nStart >= 0 && nEnd < m_pTxtBuf->GetTextLength());
+ m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
+ FDE_TXTEDTPARAGPOS ParagPosBgn, ParagPosEnd;
+ TextPos2ParagPos(nStart, ParagPosBgn);
+ TextPos2ParagPos(nEnd, ParagPosEnd);
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[ParagPosEnd.nParagIndex];
+ FX_BOOL bLastParag = FALSE;
+ if (ParagPosEnd.nCharIndex == pParag->m_nCharCount - 1) {
+ if (ParagPosEnd.nParagIndex < m_ParagPtrArray.GetSize() - 1) {
+ ParagPosEnd.nParagIndex ++;
+ } else {
+ bLastParag = TRUE;
+ }
+ }
+ FX_INT32 nTotalLineCount = 0;
+ FX_INT32 nTotalCharCount = 0;
+ FX_INT32 i = 0;
+ for (i = ParagPosBgn.nParagIndex; i <= ParagPosEnd.nParagIndex; i ++) {
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[i];
+ pParag->CalcLines();
+ nTotalLineCount += pParag->m_nLineCount;
+ nTotalCharCount += pParag->m_nCharCount;
+ }
+ m_pTxtBuf->Delete(nStart, nCount);
+ CFDE_TxtEdtParag * pEndParag = m_ParagPtrArray[ParagPosEnd.nParagIndex];
+ FX_INT32 nNextParagIndex = (ParagPosBgn.nCharIndex == 0 && bLastParag) ? ParagPosBgn.nParagIndex : \
+ (ParagPosBgn.nParagIndex + 1);
+ for (i = nNextParagIndex; i <= ParagPosEnd.nParagIndex; i ++) {
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[nNextParagIndex];
+ delete pParag;
+ m_ParagPtrArray.RemoveAt(nNextParagIndex);
+ }
+ if (!(bLastParag && ParagPosBgn.nCharIndex == 0)) {
+ pParag = m_ParagPtrArray[ParagPosBgn.nParagIndex];
+ pParag->m_nCharCount = nTotalCharCount - nCount;
+ pParag->CalcLines();
+ nTotalLineCount -= pParag->m_nLineCount;
+ }
+ FX_INT32 nParagCount = m_ParagPtrArray.GetSize();
+ for (i = nNextParagIndex; i < nParagCount; i ++) {
+ m_ParagPtrArray[i]->m_nCharStart -= nCount;
+ }
+ m_nLineCount -= nTotalLineCount;
+ UpdatePages();
+ FX_INT32 nPageCount = CountPages();
+ if (m_nCaretPage >= nPageCount) {
+ m_nCaretPage = nPageCount - 1;
+ }
+ m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
+}
+void CFDE_TxtEdtEngine::DeleteRange_DoRecord(FX_INT32 nStart, FX_INT32 nCount, FX_BOOL bSel )
+{
+ FXSYS_assert(nStart >= 0);
+ if (nCount == -1) {
+ nCount = GetTextLength() - nStart;
+ }
+ FXSYS_assert((nStart + nCount) <= m_pTxtBuf->GetTextLength());
+#ifdef FDE_USEFORMATBLOCK
+ FX_INT32 nBlockCount = m_BlockArray.GetSize();
+ if (nBlockCount > 0) {
+ }
+#endif
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
+ CFX_WideString wsRange;
+ m_pTxtBuf->GetRange(wsRange, nStart, nCount);
+ IFDE_TxtEdtDoRecord * pRecord = FX_NEW CFDE_TxtEdtDoRecord_DeleteRange(this, nStart, m_nCaret, \
+ wsRange, bSel);
+ CFX_ByteString bsDoRecord;
+ pRecord->Serialize(bsDoRecord);
+ m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
+ pRecord->Release();
+ }
+ m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
+ GetText(m_ChangeInfo.wsDelete, nStart, nCount);
+ Inner_DeleteRange(nStart, nCount);
+}
+void CFDE_TxtEdtEngine::ResetEngine()
+{
+ RemoveAllPages();
+ RemoveAllParags();
+ ClearSelection();
+ m_nCaret = 0;
+ m_pTxtBuf->Clear(FALSE);
+ m_nCaret = 0;
+}
+void CFDE_TxtEdtEngine::RebuildParagraphs()
+{
+ RemoveAllParags();
+ FX_WCHAR wChar = L' ';
+ FX_WCHAR wCharPre = L' ';
+ FX_INT32 nParagStart = 0;
+ FX_INT32 nCount = m_pTxtBuf->GetTextLength();
+ FX_INT32 nIndex = 0;
+ CFDE_TxtEdtParag * pParag = NULL;
+ IFX_CharIter * pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf);
+ pIter->SetAt(0);
+ do {
+ wChar = pIter->GetChar();
+ nIndex = pIter->GetAt();
+ if (wChar == m_wLineEnd) {
+ CFDE_TxtEdtParag * pParag = FX_NEW CFDE_TxtEdtParag(this);
+ pParag->m_nCharStart = nParagStart;
+ pParag->m_nCharCount = nIndex - nParagStart + 1;
+ pParag->m_nLineCount = -1;
+ m_ParagPtrArray.Add(pParag);
+ nParagStart = nIndex + 1;
+ }
+ } while (pIter->Next());
+ pIter->Release();
+}
+void CFDE_TxtEdtEngine::RemoveAllParags()
+{
+ FX_INT32 nCount = m_ParagPtrArray.GetSize();
+ FX_INT32 i = 0;
+ for (i = 0; i < nCount; i ++) {
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[i];
+ if (pParag) {
+ delete pParag;
+ }
+ }
+ m_ParagPtrArray.RemoveAll();
+}
+void CFDE_TxtEdtEngine::RemoveAllPages()
+{
+ FX_INT32 nCount = m_PagePtrArray.GetSize();
+ FX_INT32 i = 0;
+ for (i = 0; i < nCount; i ++) {
+ IFDE_TxtEdtPage * pPage = m_PagePtrArray[i];
+ if (pPage) {
+ pPage->Release();
+ }
+ }
+ m_PagePtrArray.RemoveAll();
+}
+void CFDE_TxtEdtEngine::UpdateParags()
+{
+ FX_INT32 nCount = m_ParagPtrArray.GetSize();
+ if (nCount == 0) {
+ return;
+ }
+ CFDE_TxtEdtParag * pParag = NULL;
+ FX_INT32 nLineCount = 0;
+ FX_INT32 i = 0;
+ for (i = 0; i < nCount; i ++) {
+ pParag = m_ParagPtrArray[i];
+ if (pParag->m_nLineCount == -1) {
+ pParag->CalcLines();
+ }
+ nLineCount += pParag->m_nLineCount;
+ }
+ m_nLineCount = nLineCount;
+}
+void CFDE_TxtEdtEngine::UpdatePages()
+{
+ if (m_nLineCount == 0) {
+ return;
+ }
+ FX_INT32 nPageCount = (m_nLineCount - 1) / (m_nPageLineCount) + 1;
+ FX_INT32 nSize = m_PagePtrArray.GetSize();
+ if (nSize == nPageCount) {
+ return;
+ }
+ if (nSize > nPageCount) {
+ IFDE_TxtEdtPage * pPage = NULL;
+ FX_INT32 i = 0;
+ for (i = nSize - 1; i >= nPageCount; i --) {
+ pPage = m_PagePtrArray[i];
+ if (pPage) {
+ pPage->Release();
+ }
+ m_PagePtrArray.RemoveAt(i);
+ }
+ m_Param.pEventSink->On_PageCountChanged(this);
+ return;
+ }
+ if (nSize < nPageCount) {
+ IFDE_TxtEdtPage * pPage = NULL;
+ FX_INT32 i = 0;
+ for (i = nSize; i < nPageCount; i ++) {
+ pPage = IFDE_TxtEdtPage::Create(this, i);
+ m_PagePtrArray.Add(pPage);
+ }
+ m_Param.pEventSink->On_PageCountChanged(this);
+ return;
+ }
+}
+void CFDE_TxtEdtEngine::UpdateTxtBreak()
+{
+ FX_DWORD dwStyle = m_pTextBreak->GetLayoutStyles();
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines) {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_SingleLine;
+ } else {
+ dwStyle |= FX_TXTLAYOUTSTYLE_SingleLine;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_VerticalLayout;
+ } else {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalLayout;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_ReverseLine;
+ } else {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_ReverseLine;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_RTL) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_RTLReadingOrder;
+ } else {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_RTLReadingOrder;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_CombText;
+ } else {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_CombText;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CharVertial) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_VerticalChars;
+ } else {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalChars;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ExpandTab) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_ExpandTab;
+ } else {
+ dwStyle &= ~ FX_TXTLAYOUTSTYLE_ExpandTab;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicContext) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_ArabicContext;
+ } else {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicContext;
+ }
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicShapes) {
+ dwStyle |= FX_TXTLAYOUTSTYLE_ArabicShapes;
+ } else {
+ dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicShapes;
+ }
+ m_pTextBreak->SetLayoutStyles(dwStyle);
+ FX_DWORD dwAligment = 0;
+ if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Justified) {
+ dwAligment |= FX_TXTLINEALIGNMENT_Justified;
+ } else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Distributed) {
+ dwAligment |= FX_TXTLINEALIGNMENT_Distributed;
+ }
+ if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Center) {
+ dwAligment |= FX_TXTLINEALIGNMENT_Center;
+ } else if(m_Param.dwAlignment & FDE_TEXTEDITALIGN_Right) {
+ dwAligment |= FX_TXTLINEALIGNMENT_Right;
+ }
+ m_pTextBreak->SetAlignment(dwAligment);
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
+ m_pTextBreak->SetLineWidth(m_Param.fPlateHeight);
+ } else {
+ m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX);
+ }
+ } else {
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
+ m_pTextBreak->SetLineWidth(m_Param.fPlateWidth);
+ } else {
+ m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX);
+ }
+ }
+ m_nPageLineCount = m_Param.nLineCount;
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) {
+ FX_FLOAT fCombWidth = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical ?
+ m_Param.fPlateHeight : m_Param.fPlateWidth;
+ if (m_nLimit > 0) {
+ fCombWidth /= m_nLimit;
+ }
+ m_pTextBreak->SetCombWidth(fCombWidth);
+ }
+ m_pTextBreak->SetFont(m_Param.pFont);
+ m_pTextBreak->SetFontSize(m_Param.fFontSize);
+ m_pTextBreak->SetTabWidth(m_Param.fTabWidth, m_Param.bTabEquidistant);
+ m_pTextBreak->SetDefaultChar(m_Param.wDefChar);
+ m_pTextBreak->SetParagraphBreakChar(m_Param.wLineBreakChar);
+ m_pTextBreak->SetCharRotation(m_Param.nCharRotation);
+ m_pTextBreak->SetLineBreakTolerance(m_Param.fFontSize * 0.2f);
+ m_pTextBreak->SetHorizontalScale(m_Param.nHorzScale);
+ m_pTextBreak->SetCharSpace(m_Param.fCharSpace);
+}
+FX_BOOL CFDE_TxtEdtEngine::ReplaceParagEnd(FX_LPWSTR &lpText, FX_INT32 &nLength, FX_BOOL bPreIsCR )
+{
+ for (FX_INT32 i = 0; i < nLength; i ++) {
+ FX_WCHAR wc = lpText[i];
+ switch(wc) {
+ case L'\r': {
+ lpText[i] = m_wLineEnd;
+ bPreIsCR = TRUE;
+ }
+ break;
+ case L'\n': {
+ if (bPreIsCR == TRUE) {
+ FX_INT32 nNext = i + 1;
+ if (nNext < nLength) {
+ FXSYS_memmove(lpText + i, lpText + nNext, (nLength - nNext) * sizeof(FX_WCHAR));
+ }
+ i --;
+ nLength --;
+ bPreIsCR = FALSE;
+ if (m_bAutoLineEnd) {
+ m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CRLF;
+ m_bAutoLineEnd = FALSE;
+ }
+ } else {
+ lpText[i] = m_wLineEnd;
+ if (m_bAutoLineEnd) {
+ m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_LF;
+ m_bAutoLineEnd = FALSE;
+ }
+ }
+ }
+ break;
+ default: {
+ if (bPreIsCR && m_bAutoLineEnd) {
+ m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CR;
+ m_bAutoLineEnd = FALSE;
+ }
+ bPreIsCR = FALSE;
+ }
+ break;
+ }
+ }
+ return bPreIsCR;
+}
+void CFDE_TxtEdtEngine::RecoverParagEnd(CFX_WideString &wsText)
+{
+ FX_WCHAR wc = (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CR) ? L'\n' : L'\r';
+ if (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CRLF) {
+ CFX_ArrayTemplate<FX_INT32> PosArr;
+ FX_INT32 nLength = wsText.GetLength();
+ FX_INT32 i = 0;
+ FX_LPWSTR lpPos = (FX_LPWSTR)(FX_LPCWSTR)wsText;
+ for (i = 0; i < nLength; i ++, lpPos ++) {
+ if (*lpPos == m_wLineEnd) {
+ *lpPos = wc;
+ PosArr.Add(i);
+ }
+ }
+ FX_LPCWSTR lpSrcBuf = FX_LPCWSTR(wsText);
+ CFX_WideString wsTemp;
+ FX_INT32 nCount = PosArr.GetSize();
+ FX_LPWSTR lpDstBuf = wsTemp.GetBuffer(nLength + nCount);
+ FX_INT32 nDstPos = 0;
+ FX_INT32 nSrcPos = 0;
+ for (i = 0; i < nCount; i ++) {
+ FX_INT32 nPos = PosArr[i];
+ FX_INT32 nCopyLen = nPos - nSrcPos + 1;
+ FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos, nCopyLen * sizeof(FX_WCHAR));
+ nDstPos += nCopyLen;
+ nSrcPos += nCopyLen;
+ lpDstBuf[nDstPos] = L'\n';
+ nDstPos ++;
+ }
+ if (nSrcPos < nLength) {
+ FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos, (nLength - nSrcPos) * sizeof(FX_WCHAR));
+ }
+ wsTemp.ReleaseBuffer(nLength + nCount);
+ wsText = wsTemp;
+ } else {
+ FX_INT32 nLength = wsText.GetLength();
+ FX_LPWSTR lpBuf = (FX_LPWSTR)(FX_LPCWSTR)wsText;
+ for (FX_INT32 i = 0; i < nLength; i ++, lpBuf++) {
+ if (*lpBuf == m_wLineEnd) {
+ *lpBuf = wc;
+ }
+ }
+ }
+}
+FX_INT32 CFDE_TxtEdtEngine::MovePage2Char(FX_INT32 nIndex)
+{
+ FXSYS_assert(nIndex >= 0);
+ FXSYS_assert(nIndex <= m_pTxtBuf->GetTextLength());
+ if (m_nCaretPage >= 0) {
+ IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
+ m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
+ FX_INT32 nPageCharStart = pPage->GetCharStart();
+ FX_INT32 nPageCharCount = pPage->GetCharCount();
+ if (nIndex >= nPageCharStart && nIndex < nPageCharStart + nPageCharCount) {
+ m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
+ return m_nCaretPage;
+ }
+ m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
+ }
+ CFDE_TxtEdtParag * pParag = NULL;
+ FX_INT32 nLineCount = 0;
+ FX_INT32 nParagCount = m_ParagPtrArray.GetSize();
+ FX_INT32 i = 0;
+ for (i = 0; i < nParagCount; i ++) {
+ pParag = m_ParagPtrArray[i];
+ if (pParag->m_nCharStart <= nIndex && nIndex < (pParag->m_nCharStart + pParag->m_nCharCount)) {
+ break;
+ }
+ nLineCount += pParag->m_nLineCount;
+ }
+ pParag->LoadParag();
+ FX_INT32 nLineStart = -1;
+ FX_INT32 nLineCharCount = -1;
+ for (i = 0; i < pParag->m_nLineCount; i ++) {
+ pParag->GetLineRange(i, nLineStart, nLineCharCount);
+ if (nLineStart <= nIndex && nIndex < (nLineStart + nLineCharCount)) {
+ break;
+ }
+ }
+ FXSYS_assert(i < pParag->m_nLineCount);
+ nLineCount += (i + 1);
+ m_nCaretPage = (nLineCount - 1) / m_nPageLineCount + 1 - 1;
+ m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
+ pParag->UnloadParag();
+ return m_nCaretPage;
+}
+void CFDE_TxtEdtEngine::TextPos2ParagPos(FX_INT32 nIndex, FDE_TXTEDTPARAGPOS &ParagPos) const
+{
+ FXSYS_assert(nIndex >= 0 && nIndex < m_pTxtBuf->GetTextLength());
+ FX_INT32 nCount = m_ParagPtrArray.GetSize();
+ FX_INT32 nBgn = 0;
+ FX_INT32 nMid = 0;
+ FX_INT32 nEnd = nCount - 1;
+ while (nEnd > nBgn) {
+ nMid = (nBgn + nEnd) / 2;
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[nMid];
+ if (nIndex < pParag->m_nCharStart) {
+ nEnd = nMid - 1;
+ } else if (nIndex >= (pParag->m_nCharStart + pParag->m_nCharCount)) {
+ nBgn = nMid + 1;
+ } else {
+ break;
+ }
+ }
+ if (nBgn == nEnd) {
+ nMid = nBgn;
+ }
+ FXSYS_assert(nIndex >= m_ParagPtrArray[nMid]->m_nCharStart && \
+ (nIndex < m_ParagPtrArray[nMid]->m_nCharStart + m_ParagPtrArray[nMid]->m_nCharCount));
+ ParagPos.nParagIndex = nMid;
+ ParagPos.nCharIndex = nIndex - m_ParagPtrArray[nMid]->m_nCharStart;
+}
+FX_INT32 CFDE_TxtEdtEngine::MoveForward(FX_BOOL &bBefore)
+{
+ if (m_nCaret == m_pTxtBuf->GetTextLength() - 1) {
+ return -1;
+ }
+ FX_INT32 nCaret = m_nCaret;
+ if ((nCaret + 1 < m_pTxtBuf->GetTextLength()) && (m_pTxtBuf->GetCharByIndex(nCaret) == L'\r') && \
+ (m_pTxtBuf->GetCharByIndex(nCaret + 1) == L'\n')) {
+ nCaret ++;
+ }
+ nCaret ++;
+ bBefore = TRUE;
+ return nCaret;
+}
+FX_INT32 CFDE_TxtEdtEngine::MoveBackward(FX_BOOL &bBefore)
+{
+ if (m_nCaret == 0) {
+ return FALSE;
+ }
+ FX_INT32 nCaret = m_nCaret;
+ if (nCaret > 2 && m_pTxtBuf->GetCharByIndex(nCaret - 1) == L'\n' && \
+ m_pTxtBuf->GetCharByIndex(nCaret - 2) == L'\r') {
+ nCaret --;
+ }
+ nCaret --;
+ bBefore = TRUE;
+ return nCaret;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveUp(CFX_PointF &ptCaret)
+{
+ IFDE_TxtEdtPage * pPage = GetPage(m_nCaretPage);
+ const CFX_RectF& rtContent = pPage->GetContentsBox();
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
+ ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 - m_Param.fLineSpace;
+ ptCaret.y = m_fCaretPosReserve;
+ FX_BOOL bLineReserve = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
+ if (ptCaret.x < rtContent.left) {
+ if (bLineReserve) {
+ if (m_nCaretPage == CountPages() - 1) {
+ return FALSE;
+ }
+ } else {
+ if (m_nCaretPage == 0) {
+ return FALSE;
+ }
+ }
+ if (bLineReserve) {
+ m_nCaretPage ++;
+ } else {
+ m_nCaretPage --;
+ }
+ m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
+ ptCaret.x -= rtContent.left;
+ IFDE_TxtEdtPage * pCurPage = GetPage(m_nCaretPage);
+ ptCaret.x += pCurPage->GetContentsBox().right();
+ }
+ } else {
+ ptCaret.x = m_fCaretPosReserve;
+ ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 - m_Param.fLineSpace;
+ if (ptCaret.y < rtContent.top) {
+ if (m_nCaretPage == 0) {
+ return FALSE;
+ }
+ ptCaret.y -= rtContent.top;
+ m_nCaretPage --;
+ m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
+ IFDE_TxtEdtPage * pCurPage = GetPage(m_nCaretPage);
+ ptCaret.y += pCurPage->GetContentsBox().bottom();
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveDown(CFX_PointF &ptCaret)
+{
+ IFDE_TxtEdtPage * pPage = GetPage(m_nCaretPage);
+ const CFX_RectF& rtContent = pPage->GetContentsBox();
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
+ ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 + m_Param.fLineSpace;
+ ptCaret.y = m_fCaretPosReserve;
+ if (ptCaret.x >= rtContent.right()) {
+ FX_BOOL bLineReserve = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
+ if (bLineReserve) {
+ if (m_nCaretPage == 0) {
+ return FALSE;
+ }
+ } else {
+ if (m_nCaretPage == CountPages() - 1) {
+ return FALSE;
+ }
+ }
+ if (bLineReserve) {
+ m_nCaretPage --;
+ } else {
+ m_nCaretPage ++;
+ }
+ m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
+ ptCaret.x -= rtContent.right();
+ IFDE_TxtEdtPage * pCurPage = GetPage(m_nCaretPage);
+ ptCaret.x += pCurPage->GetContentsBox().left;
+ }
+ } else {
+ ptCaret.x = m_fCaretPosReserve;
+ ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 + m_Param.fLineSpace;
+ if (ptCaret.y >= rtContent.bottom()) {
+ if (m_nCaretPage == CountPages() - 1) {
+ return FALSE;
+ }
+ ptCaret.y -= rtContent.bottom();
+ m_nCaretPage ++;
+ m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
+ IFDE_TxtEdtPage * pCurPage = GetPage(m_nCaretPage);
+ ptCaret.y += pCurPage->GetContentsBox().top;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveLineStart()
+{
+ FX_INT32 nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
+ FDE_TXTEDTPARAGPOS ParagPos;
+ TextPos2ParagPos(nIndex, ParagPos);
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[ParagPos.nParagIndex];
+ pParag->LoadParag();
+ FX_INT32 nLineCount = pParag->m_nLineCount;
+ FX_INT32 i = 0;
+ FX_INT32 nStart = 0;
+ FX_INT32 nCount = 0;
+ for (; i < nLineCount; i ++) {
+ pParag->GetLineRange(i, nStart, nCount);
+ if (nIndex >= nStart && nIndex < nStart + nCount) {
+ break;
+ }
+ }
+ UpdateCaretRect(nStart, TRUE);
+ pParag->UnloadParag();
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveLineEnd()
+{
+ FX_INT32 nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
+ FDE_TXTEDTPARAGPOS ParagPos;
+ TextPos2ParagPos(nIndex, ParagPos);
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[ParagPos.nParagIndex];
+ pParag->LoadParag();
+ FX_INT32 nLineCount = pParag->m_nLineCount;
+ FX_INT32 i = 0;
+ FX_INT32 nStart = 0;
+ FX_INT32 nCount = 0;
+ for (; i < nLineCount; i ++) {
+ pParag->GetLineRange(i, nStart, nCount);
+ if (nIndex >= nStart && nIndex < nStart + nCount) {
+ break;
+ }
+ }
+ nIndex = nStart + nCount - 1;
+ FXSYS_assert(nIndex <= GetTextBufLength());
+ FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex);
+ FX_BOOL bBefore = FALSE;
+ if (nIndex <= GetTextBufLength()) {
+ if (wChar == L'\r') {
+ bBefore = TRUE;
+ } else if (wChar == L'\n' && nIndex > nStart) {
+ bBefore = TRUE;
+ nIndex --;
+ wChar = m_pTxtBuf->GetCharByIndex(nIndex);
+ if (wChar != L'\r') {
+ nIndex ++;
+ }
+ }
+ }
+ UpdateCaretRect(nIndex, bBefore);
+ pParag->UnloadParag();
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveParagStart()
+{
+ FX_INT32 nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
+ FDE_TXTEDTPARAGPOS ParagPos;
+ TextPos2ParagPos(nIndex, ParagPos);
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[ParagPos.nParagIndex];
+ UpdateCaretRect(pParag->m_nCharStart, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveParagEnd()
+{
+ FX_INT32 nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
+ FDE_TXTEDTPARAGPOS ParagPos;
+ TextPos2ParagPos(nIndex, ParagPos);
+ CFDE_TxtEdtParag * pParag = m_ParagPtrArray[ParagPos.nParagIndex];
+ nIndex = pParag->m_nCharStart + pParag->m_nCharCount - 1;
+ FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex);
+ if (wChar == L'\n' && nIndex > 0) {
+ nIndex --;
+ wChar = m_pTxtBuf->GetCharByIndex(nIndex);
+ if (wChar != L'\r') {
+ nIndex ++;
+ }
+ }
+ UpdateCaretRect(nIndex, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveHome()
+{
+ UpdateCaretRect(0, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtEngine::MoveEnd()
+{
+ UpdateCaretRect(GetTextBufLength(), TRUE);
+ return TRUE;
+}
+#ifdef FDE_USEFORMATBLOCK
+FX_INT32 CFDE_TxtEdtEngine::NormalizeCaretPos(FX_INT32 nIndex, FX_INT32 nFlags, FX_BOOL &bBefore)
+{
+ bBefore = TRUE;
+ FX_INT32 nBgn = 0, nEnd = 0;
+ FX_INT32 nRecord = -1;
+ CFDE_TxtEdtField * pField = NULL;
+ FX_BOOL bRet = GetFieldBoundary(nIndex, nBgn, nEnd, pField);
+ FX_INT32 nDelta = 0;
+ if (bRet && !pField->IsFix()) {
+ if (nIndex - nBgn < FDE_FORMAT_EDIT_FIELD_HADERSIZE) {
+ if (nFlags == FDE_FORMAT_CARET_BACKWARD) {
+ CFDE_TxtEdtField * pEditableField = NULL;
+ if (FindEditableField(nIndex, nBgn, nEnd, pEditableField, FALSE)) {
+ return pEditableField->NormalizeCaretPos(nEnd - nBgn, FDE_FORMAT_CARET_BACKWARD) + nBgn;
+ }
+ }
+ nIndex = nBgn + FDE_FORMAT_EDIT_FIELD_HADERSIZE;
+ }
+ FX_INT32 nRet = pField->NormalizeCaretPos(nIndex - nBgn, (FDE_FORMAT_CARET_DIRECTION)nFlags);
+ if (nRet >= 0) {
+ return nRet + nBgn;
+ }
+ if (nRet == -2) {
+ FX_INT32 nEditablePosBgn = 0, nEditablePosEnd = 0;
+ pField->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
+ nRecord = nBgn + nEditablePosBgn;
+ nFlags = FDE_FORMAT_CARET_BACKWARD;
+ } else {
+ FXSYS_assert(nRet == -1);
+ FX_INT32 nEditablePosBgn = 0, nEditablePosEnd = 0;
+ pField->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
+ nRecord = nBgn + nEditablePosEnd;
+ nFlags = FDE_FORMAT_CARET_FORWARD;
+ }
+ } else if (!bRet) {
+ nDelta = FDE_FORMAT_EDIT_FIELD_HADERSIZE - FDE_FORMAT_EDIT_FIELD_TAILSIZE;
+ }
+ switch (nFlags) {
+ case FDE_FORMAT_CARET_FORWARD: {
+ if (FindEditableField(nIndex, nBgn, nEnd, pField)) {
+ return pField->NormalizeCaretPos(FDE_FORMAT_EDIT_FIELD_HADERSIZE, FDE_FORMAT_CARET_FORWARD) + nBgn;
+ } else {
+ if (nRecord != -1) {
+ return nRecord;
+ }
+ bRet = FindEditableField(nIndex, nBgn, nEnd, pField, FALSE);
+ FXSYS_assert(bRet);
+ return pField->NormalizeCaretPos(nEnd - nBgn, FDE_FORMAT_CARET_BACKWARD) + nBgn;
+ }
+ }
+ break;
+ case FDE_FORMAT_CARET_MIDDLE: {
+ FX_INT32 nBgn1 = 0, nEnd1 = 0, nBgn2 = 0, nEnd2 = 0;
+ CFDE_TxtEdtField * pEditableField1 = NULL;
+ CFDE_TxtEdtField * pEditableField2 = NULL;
+ FX_BOOL bRet1 = FindEditableField(nIndex, nBgn1, nEnd1, pEditableField1, FALSE);
+ FX_BOOL bRet2 = FindEditableField(nIndex, nBgn2, nEnd2, pEditableField2);
+ if (bRet1 == FALSE) {
+ FXSYS_assert(bRet2);
+ return pEditableField2->NormalizeCaretPos(FDE_FORMAT_EDIT_FIELD_HADERSIZE, FDE_FORMAT_CARET_FORWARD) + nBgn2;
+ } else if (bRet2 == FALSE) {
+ FXSYS_assert(bRet1);
+ return pEditableField1->NormalizeCaretPos(nEnd1 - nBgn1, FDE_FORMAT_CARET_BACKWARD) + nBgn1;
+ } else {
+ FX_INT32 nEditablePosBgn = 0, nEditablePosEnd = 0;
+ if (nIndex - nEnd1 < nBgn2 + nDelta - nIndex) {
+ pEditableField1->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
+ return nEditablePosEnd + nBgn1;
+ } else {
+ pEditableField2->GetEditableRange(nEditablePosBgn, nEditablePosEnd);
+ return nEditablePosBgn + nBgn2;
+ }
+ }
+ }
+ break;
+ case FDE_FORMAT_CARET_BACKWARD: {
+ if (FindEditableField(nIndex, nBgn, nEnd, pField, FALSE)) {
+ return pField->NormalizeCaretPos(nEnd - nBgn, FDE_FORMAT_CARET_BACKWARD) + nBgn;
+ } else {
+ if (nRecord != -1) {
+ return nRecord;
+ }
+ bRet = FindEditableField(nIndex, nBgn, nEnd, pField);
+ FXSYS_assert(bRet);
+ return pField->NormalizeCaretPos(FDE_FORMAT_EDIT_FIELD_HADERSIZE, FDE_FORMAT_CARET_FORWARD) + nBgn;
+ }
+ }
+ break;
+ default:
+ FXSYS_assert(0);
+ return nIndex;
+ }
+}
+FX_BOOL CFDE_TxtEdtEngine::GetFieldBoundary(FX_INT32 nIndex, FX_INT32 &nBgn, FX_INT32 &nEnd, CFDE_TxtEdtField * &pField)
+{
+ CFDE_TxtEdtBufIter * pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
+ pIter->SetAt(nIndex);
+ FX_BOOL bFind = FALSE;
+ do {
+ FX_WCHAR wc = pIter->GetChar();
+ if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
+ nEnd = pIter->GetAt();
+ bFind = TRUE;
+ nIndex --;
+ break;
+ }
+ if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
+ pIter->Release();
+ return FALSE;
+ }
+ } while (pIter->Next());
+ if (!bFind) {
+ pIter->Release();
+ return FALSE;
+ }
+ pIter->SetAt(nIndex);
+ do {
+ FX_WCHAR wc = pIter->GetChar();
+ if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
+ nBgn = pIter->GetAt();
+ pIter->Next();
+ FX_DWORD dwPre = (FX_DWORD)pIter->GetChar();
+ pIter->Next();
+ FX_DWORD dwCur = (FX_DWORD)pIter->GetChar();
+ pField = (CFDE_TxtEdtField *)((dwCur << 16) | dwPre);
+ pIter->Release();
+ return TRUE;
+ }
+ if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
+ pIter->Release();
+ return FALSE;
+ }
+ } while (pIter->Next(TRUE));
+ pIter->Release();
+ return FALSE;
+}
+FX_BOOL CFDE_TxtEdtEngine::FindEditableField(FX_INT32 nIndex, FX_INT32 &nBgn, FX_INT32 &nEnd, CFDE_TxtEdtField * &pField, FX_BOOL bForward )
+{
+ FX_WCHAR wcFirst = FDE_TXTEDT_FORMATBLOCK_BGN;
+ FX_WCHAR wcSecond = FDE_TXTEDT_FORMATBLOCK_END;
+ if (!bForward) {
+ wcFirst = FDE_TXTEDT_FORMATBLOCK_END;
+ wcSecond = FDE_TXTEDT_FORMATBLOCK_BGN;
+ }
+ CFDE_TxtEdtBufIter * pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
+ pIter->SetAt(nIndex);
+ FX_INT32 bFind = FALSE;
+ do {
+ FX_WCHAR wc = pIter->GetChar();
+ if (wc == wcFirst) {
+ nBgn = pIter->GetAt();
+ bFind = TRUE;
+ break;
+ }
+ } while (pIter->Next(!bForward));
+ if (!bFind) {
+ pIter->Release();
+ return FALSE;
+ }
+ bFind = FALSE;
+ do {
+ FX_WCHAR wc = pIter->GetChar();
+ if (wc == wcSecond) {
+ nEnd = pIter->GetAt();
+ bFind = TRUE;
+ break;
+ }
+ } while (pIter->Next(!bForward));
+ FXSYS_assert(bFind);
+ if (!bForward) {
+ FX_INT32 nTemp = nBgn;
+ nBgn = nEnd;
+ nEnd = nTemp;
+ }
+ pIter->SetAt(nBgn + 1);
+ FX_DWORD dwPre = (FX_DWORD)pIter->GetChar();
+ pIter->Next();
+ FX_DWORD dwCur = (FX_DWORD)pIter->GetChar();
+ pField = (CFDE_TxtEdtField *)((dwCur << 16) | dwPre);
+ pIter->Release();
+ if (!pField->IsFix()) {
+ return TRUE;
+ }
+ return FindEditableField((bForward ? nEnd : nBgn), nBgn, nEnd, pField, bForward);
+}
+FX_BOOL CFDE_TxtEdtEngine::Move2NextEditableField(FX_INT32 nIndex, FX_BOOL bForward , FX_BOOL bSelect )
+{
+ if (m_SelRangePtrArr.GetSize() > 0) {
+ ClearSelection();
+ m_Param.pEventSink->On_SelChanged(this);
+ }
+ FX_INT32 nBgn = 0, nEnd = 0;
+ CFDE_TxtEdtField * pField = NULL;
+ FX_BOOL bRet = FindEditableField(nIndex, nBgn, nEnd, pField, bForward);
+ if (!bRet) {
+ return FALSE;
+ }
+ FX_INT32 nEditableBgn = 0, nEditableEnd = 0;
+ pField->GetEditableRange(nEditableBgn, nEditableEnd);
+ nEditableBgn += nBgn;
+ nEditableEnd += nBgn;
+ if (bSelect) {
+ FX_INT32 nRangeCount = nEditableEnd - nEditableBgn;
+ if (nRangeCount > 0) {
+ AddSelRange(nEditableBgn, nEditableEnd - nEditableBgn);
+ }
+ }
+ SetCaretPos(nEditableEnd, TRUE);
+ return TRUE;
+}
+FX_INT32 CFDE_TxtEdtEngine::GetRealIndex(FX_INT32 nIndex) const
+{
+ CFDE_TxtEdtBufIter * pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf, FALSE);
+ pIter->SetAt(0);
+ FX_BOOL bInField = FALSE;
+ FX_INT32 nFieldBgn = 0;
+ FX_INT32 nRealIndex = 0;
+ for (FX_INT32 i = 0; i <= nIndex; i ++) {
+ FX_WCHAR wc = pIter->GetChar();
+ if (bInField) {
+ if (wc == FDE_TXTEDT_FORMATBLOCK_END) {
+ FX_DWORD dwPre = (FX_DWORD)m_pTxtBuf->GetCharByIndex(nFieldBgn + 1);
+ FX_DWORD dwCur = (FX_DWORD)m_pTxtBuf->GetCharByIndex(nFieldBgn + 2);
+ CFDE_TxtEdtField * pField = (CFDE_TxtEdtField *)((dwCur << 16) | dwPre);
+ nRealIndex += pField->GetFieldTextLength();
+ bInField = FALSE;
+ }
+ } else {
+ if (wc == FDE_TXTEDT_FORMATBLOCK_BGN) {
+ bInField = TRUE;
+ nFieldBgn = pIter->GetAt();
+ } else {
+ nRealIndex ++;
+ }
+ }
+ pIter->Next();
+ }
+ if (!bInField) {
+ pIter->Release();
+ return nRealIndex;
+ }
+ pIter->SetAt(nFieldBgn + 1);
+ FX_DWORD dwPre = (FX_DWORD)pIter->GetChar();
+ pIter->Next();
+ FX_DWORD dwCur = (FX_DWORD)pIter->GetChar();
+ CFDE_TxtEdtField * pField = (CFDE_TxtEdtField *)((dwCur << 16) | dwPre);
+ pIter->Release();
+ if (pField->IsFix()) {
+ FX_INT32 nDelta = nIndex - nFieldBgn - FDE_FORMAT_EDIT_FIELD_HADERSIZE + 1;
+ return nRealIndex + (nDelta > 0 ? nDelta : 0);
+ } else {
+ return nRealIndex + pField->GetRealIndex(nIndex - nFieldBgn);
+ }
+}
+#endif
+FX_BOOL CFDE_TxtEdtEngine::IsFitArea(CFX_WideString &wsText)
+{
+ IFDE_TextOut * pTextOut = IFDE_TextOut::Create();
+ pTextOut->SetLineSpace(m_Param.fLineSpace);
+ pTextOut->SetFont(m_Param.pFont);
+ pTextOut->SetFontSize(m_Param.fFontSize);
+ CFX_RectF rcText;
+ FXSYS_memset(&rcText, 0, sizeof(rcText));
+ FX_DWORD dwStyle = 0;
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines)) {
+ dwStyle |= FDE_TTOSTYLE_SingleLine;
+ }
+ if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
+ dwStyle |= FDE_TTOSTYLE_LineWrap;
+ rcText.width = m_Param.fPlateWidth;
+ } else {
+ rcText.width = 65535;
+ }
+ pTextOut->SetStyles(dwStyle);
+ wsText += L"\n";
+ pTextOut->CalcLogicSize(wsText, wsText.GetLength(), rcText);
+ pTextOut->Release();
+ wsText.Delete(wsText.GetLength() - 1);
+ if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz) && (rcText.width > m_Param.fPlateWidth)) {
+ return FALSE;
+ }
+ if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) && \
+ (rcText.height > m_Param.fLineSpace * m_Param.nLineCount)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+void CFDE_TxtEdtEngine::UpdateCaretRect(FX_INT32 nIndex, FX_BOOL bBefore)
+{
+ MovePage2Char(nIndex);
+ GetCaretRect(m_rtCaret, m_nCaretPage, nIndex, bBefore);
+ m_nCaret = nIndex;
+ m_bBefore = bBefore;
+ if (!m_bBefore) {
+ m_nCaret ++;
+ m_bBefore = TRUE;
+ }
+ m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) ? \
+ m_rtCaret.top : m_rtCaret.left;
+ m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0);
+}
+void CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF &rtCaret, FX_INT32 nPageIndex, FX_INT32 nCaret, FX_BOOL bBefore )
+{
+ IFDE_TxtEdtPage * pPage = m_PagePtrArray[m_nCaretPage];
+ m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
+ FX_BOOL bCombText = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText;
+ FX_INT32 nIndexInpage = nCaret - pPage->GetCharStart();
+ if (bBefore && bCombText && nIndexInpage > 0) {
+ nIndexInpage--;
+ bBefore = FALSE;
+ }
+ FX_INT32 nBIDILevel = pPage->GetCharRect(nIndexInpage, rtCaret, bCombText);
+ if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
+ if ((!FX_IsOdd(nBIDILevel) && !bBefore) || (FX_IsOdd(nBIDILevel) && bBefore)) {
+ rtCaret.Offset(0, rtCaret.height - 1.0f);
+ }
+ if (rtCaret.height == 0 && rtCaret.top > 1.0f) {
+ rtCaret.top -= 1.0f;
+ }
+ rtCaret.height = 1.0f;
+ } else {
+ if ((!FX_IsOdd(nBIDILevel) && !bBefore) || (FX_IsOdd(nBIDILevel) && bBefore)) {
+ rtCaret.Offset(rtCaret.width - 1.0f, 0);
+ }
+ if (rtCaret.width == 0 && rtCaret.left > 1.0f) {
+ rtCaret.left -= 1.0f;
+ }
+ rtCaret.width = 1.0f;
+ }
+ m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
+}
+void CFDE_TxtEdtEngine::UpdateCaretIndex(const CFX_PointF & ptCaret)
+{
+ IFDE_TxtEdtPage * pPage = m_PagePtrArray[m_nCaretPage];
+ m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
+ m_nCaret = pPage->GetCharIndex(ptCaret, m_bBefore);
+ GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore);
+ if (!m_bBefore) {
+ m_nCaret ++;
+ m_bBefore = TRUE;
+ }
+ m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage);
+ m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
+}
+FX_BOOL CFDE_TxtEdtEngine::IsSelect()
+{
+ return m_SelRangePtrArr.GetSize() > 0;
+}
+void CFDE_TxtEdtEngine::DeleteSelect()
+{
+ FX_INT32 nCountRange = CountSelRanges();
+ if (nCountRange > 0) {
+#ifdef FDE_USEFORMATBLOCK
+ FX_INT32 nBlockCount = m_BlockArray.GetSize();
+ if (nBlockCount > 0) {
+ if (nCountRange > 1) {
+ return;
+ }
+ FX_INT32 nSelStart;
+ FX_INT32 nSelCount;
+ nSelCount = GetSelRange(0, nSelStart);
+ FX_INT32 nSelEnd = nSelStart + nSelCount;
+ FX_INT32 nBgn = 0;
+ FX_INT32 nEnd = 0;
+ CFDE_TxtEdtField * pField = NULL;
+ FX_BOOL bInField = GetFieldBoundary(nSelStart, nBgn, nEnd, pField);
+ FX_INT32 nCaretInField = nSelStart - nBgn;
+ FX_BOOL bBefore = FALSE;
+ if (!bInField || pField->IsFix() || nSelEnd > nEnd) {
+ return;
+ }
+ pField->Backup();
+ CFX_WideString wsDel;
+ FX_INT32 nCaret = 0;
+ FX_INT32 nRet = pField->Delete(nCaretInField, nSelCount, wsDel, nCaret, bBefore);
+ nCaret += nBgn;
+ switch (nRet) {
+ case FDE_FORMAT_FIELD_DELETE_RET_S:
+ break;
+ case FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE:
+ case FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY:
+ return;
+ default:
+ FXSYS_assert(0);
+ break;
+ }
+ CFX_WideString wsField;
+ pField->GetFieldText(wsField);
+ if (!m_Param.pEventSink->On_ValidateField(this, pField->GetBlockIndex(), pField->GetIndex(), wsField, 0)) {
+ pField->Restore();
+ return;
+ }
+ CFX_WideString wsDisplay;
+ pField->GetDisplayText(wsDisplay);
+ Replace(nBgn, nEnd - nBgn + 1, wsDisplay);
+ if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
+ IFDE_TxtEdtDoRecord * pRecord = FX_NEW CFDE_TxtEdtDoRecord_FieldDelete(this, nSelStart, pField, nCaretInField,
+ nBgn, nEnd - nBgn + 1, wsDisplay.GetLength(), wsDel, FALSE);
+ CFX_ByteString bsDoRecord;
+ pRecord->Serialize(bsDoRecord);
+ m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
+ pRecord->Release();
+ }
+ SetCaretPos(nSelStart, bBefore);
+ return;
+ }
+#endif
+ FX_INT32 nSelStart;
+ FX_INT32 nSelCount;
+ while (nCountRange > 0) {
+ nSelCount = GetSelRange(--nCountRange, nSelStart);
+ FDE_LPTXTEDTSELRANGE lpTemp = m_SelRangePtrArr[nCountRange];
+ delete lpTemp;
+ m_SelRangePtrArr.RemoveAt(nCountRange);
+ DeleteRange_DoRecord(nSelStart, nSelCount, TRUE);
+ }
+ ClearSelection();
+ m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
+ m_Param.pEventSink->On_SelChanged(this);
+ SetCaretPos(nSelStart, TRUE);
+ return;
+ }
+}
+IFDE_TxtEdtDoRecord * IFDE_TxtEdtDoRecord::Create(FX_BSTR bsDoRecord)
+{
+ FX_LPCSTR lpBuf = bsDoRecord.GetCStr();
+ FX_INT32 nType = *((FX_INT32*)lpBuf);
+ switch(nType) {
+ case FDE_TXTEDT_DORECORD_INS:
+ return FX_NEW CFDE_TxtEdtDoRecord_Insert(bsDoRecord);
+ case FDE_TXTEDT_DORECORD_DEL:
+ return FX_NEW CFDE_TxtEdtDoRecord_DeleteRange(bsDoRecord);
+#ifdef FDE_USEFORMATBLOCK
+ case FDE_TXTEDT_DORECORD_FORMATINS:
+ return FX_NEW CFDE_TxtEdtDoRecord_FieldInsert(bsDoRecord);
+ case FDE_TXTEDT_DORECORD_FORMATDEL:
+ return FX_NEW CFDE_TxtEdtDoRecord_FieldDelete(bsDoRecord);
+ case FDE_TXTEDT_DORECORD_FORMATREP:
+ return FX_NEW CFDE_TxtEdtDoRecord_FieldReplace(bsDoRecord);
+#endif
+ default:
+ break;
+ }
+ return NULL;
+}
+CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert(FX_BSTR bsDoRecord)
+{
+ Deserialize(bsDoRecord);
+}
+CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert(CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ FX_LPCWSTR lpText,
+ FX_INT32 nLength)
+ : m_pEngine(pEngine)
+ , m_nCaret(nCaret)
+{
+ FXSYS_assert(pEngine);
+ FX_LPWSTR lpBuffer = m_wsInsert.GetBuffer(nLength);
+ FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR));
+ m_wsInsert.ReleaseBuffer();
+}
+CFDE_TxtEdtDoRecord_Insert::~CFDE_TxtEdtDoRecord_Insert()
+{
+}
+void CFDE_TxtEdtDoRecord_Insert::Release()
+{
+ delete this;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_Insert::Undo()
+{
+ if (m_pEngine->IsSelect()) {
+ m_pEngine->ClearSelection();
+ }
+ m_pEngine->Inner_DeleteRange(m_nCaret, m_wsInsert.GetLength());
+ FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
+ m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
+ m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert;
+ Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
+ m_pEngine->SetCaretPos(m_nCaret, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_Insert::Redo()
+{
+ m_pEngine->Inner_Insert(m_nCaret, FX_LPCWSTR(m_wsInsert), m_wsInsert.GetLength());
+ FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
+ m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
+ m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert;
+ Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
+ m_pEngine->SetCaretPos(m_nCaret, FALSE);
+ return TRUE;
+}
+void CFDE_TxtEdtDoRecord_Insert::Serialize(CFX_ByteString &bsDoRecord) const
+{
+ CFX_ArchiveSaver ArchiveSaver;
+ ArchiveSaver << FX_INT32(FDE_TXTEDT_DORECORD_INS);
+ ArchiveSaver << (FX_INT32)(FX_UINTPTR)m_pEngine;
+ ArchiveSaver << m_nCaret;
+ ArchiveSaver << m_wsInsert;
+ FX_INT32 nLength = ArchiveSaver.GetLength();
+ FX_LPCBYTE lpSrcBuf = ArchiveSaver.GetBuffer();
+ FX_LPSTR lpDstBuf = bsDoRecord.GetBuffer(nLength);
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
+ bsDoRecord.ReleaseBuffer(nLength);
+}
+void CFDE_TxtEdtDoRecord_Insert::Deserialize(FX_BSTR bsDoRecord)
+{
+ CFX_ArchiveLoader ArchiveLoader((FX_LPCBYTE)bsDoRecord.GetCStr(), bsDoRecord.GetLength());
+ FX_INT32 nType = 0;
+ ArchiveLoader >> nType;
+ FXSYS_assert(nType == FDE_TXTEDT_DORECORD_INS);
+ FX_INT32 nEngine = 0;
+ ArchiveLoader >> nEngine;
+ m_pEngine = (CFDE_TxtEdtEngine*)(FX_UINTPTR)nEngine;
+ ArchiveLoader >> m_nCaret;
+ ArchiveLoader >> m_wsInsert;
+}
+CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange(FX_BSTR bsDoRecord)
+{
+ Deserialize(bsDoRecord);
+}
+CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange(CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nIndex,
+ FX_INT32 nCaret,
+ const CFX_WideString &wsRange,
+ FX_BOOL bSel)
+ : m_pEngine(pEngine)
+ , m_nIndex(nIndex)
+ , m_nCaret(nCaret)
+ , m_wsRange(wsRange)
+ , m_bSel(bSel)
+{
+ FXSYS_assert(pEngine);
+}
+CFDE_TxtEdtDoRecord_DeleteRange::~CFDE_TxtEdtDoRecord_DeleteRange()
+{
+}
+void CFDE_TxtEdtDoRecord_DeleteRange::Release()
+{
+ delete this;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Undo()
+{
+ if (m_pEngine->IsSelect()) {
+ m_pEngine->ClearSelection();
+ }
+ m_pEngine->Inner_Insert(m_nIndex, FX_LPCWSTR(m_wsRange), m_wsRange.GetLength());
+ if (m_bSel) {
+ m_pEngine->AddSelRange(m_nIndex, m_wsRange.GetLength());
+ }
+ FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
+ m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
+ m_pEngine->m_ChangeInfo.wsDelete = m_wsRange;
+ Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
+ m_pEngine->SetCaretPos(m_nCaret, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Redo()
+{
+ m_pEngine->Inner_DeleteRange(m_nIndex, m_wsRange.GetLength());
+ if (m_bSel) {
+ m_pEngine->RemoveSelRange(m_nIndex, m_wsRange.GetLength());
+ }
+ FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
+ m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
+ m_pEngine->m_ChangeInfo.wsDelete = m_wsRange;
+ Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
+ m_pEngine->SetCaretPos(m_nIndex, TRUE);
+ return TRUE;
+}
+void CFDE_TxtEdtDoRecord_DeleteRange::Serialize(CFX_ByteString &bsDoRecord) const
+{
+ CFX_ArchiveSaver ArchiveSaver;
+ ArchiveSaver << FX_INT32(FDE_TXTEDT_DORECORD_DEL);
+ ArchiveSaver << (FX_INT32)(FX_UINTPTR)m_pEngine;
+ ArchiveSaver << m_bSel;
+ ArchiveSaver << m_nIndex;
+ ArchiveSaver << m_nCaret;
+ ArchiveSaver << m_wsRange;
+ FX_INT32 nLength = ArchiveSaver.GetLength();
+ FX_LPCBYTE lpSrcBuf = ArchiveSaver.GetBuffer();
+ FX_LPSTR lpDstBuf = bsDoRecord.GetBuffer(nLength);
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
+ bsDoRecord.ReleaseBuffer(nLength);
+}
+void CFDE_TxtEdtDoRecord_DeleteRange::Deserialize(FX_BSTR bsDoRecord)
+{
+ CFX_ArchiveLoader ArchiveLoader((FX_LPCBYTE)bsDoRecord.GetCStr(), bsDoRecord.GetLength());
+ FX_INT32 nType = 0;
+ ArchiveLoader >> nType;
+ FXSYS_assert(nType == FDE_TXTEDT_DORECORD_DEL);
+ FX_INT32 nEngine = 0;
+ ArchiveLoader >> nEngine;
+ m_pEngine = (CFDE_TxtEdtEngine*)(FX_UINTPTR)nEngine;
+ ArchiveLoader >> m_bSel;
+ ArchiveLoader >> m_nIndex;
+ ArchiveLoader >> m_nCaret;
+ ArchiveLoader >> m_wsRange;
+}
+#ifdef FDE_USEFORMATBLOCK
+CFDE_TxtEdtDoRecord_FieldInsert::CFDE_TxtEdtDoRecord_FieldInsert(FX_BSTR bsDoRecord)
+{
+ Deserialize(bsDoRecord);
+}
+CFDE_TxtEdtDoRecord_FieldInsert::CFDE_TxtEdtDoRecord_FieldInsert(CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ CFDE_TxtEdtField * pField,
+ FX_INT32 nIndexInField,
+ FX_INT32 nFieldBgn,
+ FX_INT32 nOldFieldLength,
+ FX_INT32 nNewFieldLength,
+ const CFX_WideString &wsIns,
+ FX_BOOL bSel )
+ : m_pEngine(pEngine)
+ , m_nCaret(nCaret)
+ , m_pField(pField)
+ , m_nIndexInField(nIndexInField)
+ , m_nFieldBgn(nFieldBgn)
+ , m_nOldFieldLength(nOldFieldLength)
+ , m_nNewFieldLength(nNewFieldLength)
+ , m_wsIns(wsIns)
+ , m_bSel(bSel)
+{
+ FXSYS_assert(pEngine);
+ FXSYS_assert(pField);
+}
+CFDE_TxtEdtDoRecord_FieldInsert::~CFDE_TxtEdtDoRecord_FieldInsert()
+{
+}
+void CFDE_TxtEdtDoRecord_FieldInsert::Release()
+{
+ delete this;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_FieldInsert::Undo()
+{
+ CFX_WideString wsDel;
+ FX_INT32 nCaret = 0;
+ FX_BOOL bBefore = FALSE;
+ FX_INT32 nRet = m_pField->Delete(m_nIndexInField, m_wsIns.GetLength(), wsDel, nCaret, bBefore);
+ FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
+ CFX_WideString wsDisplay;
+ m_pField->GetDisplayText(wsDisplay);
+ m_pEngine->Replace(m_nFieldBgn, m_nNewFieldLength, wsDisplay);
+ m_pEngine->SetCaretPos(m_nCaret, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_FieldInsert::Redo()
+{
+ FX_INT32 nCaret = 0;
+ FX_BOOL bBefore = FALSE;
+ FX_INT32 nRet = m_pField->Insert(m_nIndexInField, m_wsIns, nCaret, bBefore);
+ FXSYS_assert(nRet != FDE_FORMAT_FIELD_INSERT_RET_F_FULL && nRet != FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE);
+ CFX_WideString wsDisplay;
+ m_pField->GetDisplayText(wsDisplay);
+ m_pEngine->Replace(m_nFieldBgn, m_nOldFieldLength, wsDisplay);
+ m_pEngine->SetCaretPos(m_nCaret + m_wsIns.GetLength(), TRUE);
+ return TRUE;
+}
+void CFDE_TxtEdtDoRecord_FieldInsert::Serialize(CFX_ByteString &bsDoRecord) const
+{
+ CFX_ArchiveSaver ArchiveSaver;
+ ArchiveSaver << FX_INT32(FDE_TXTEDT_DORECORD_FORMATINS);
+ ArchiveSaver << FX_INT32(m_pEngine);
+ ArchiveSaver << m_nCaret;
+ ArchiveSaver << FX_INT32(m_pField);
+ ArchiveSaver << m_nIndexInField;
+ ArchiveSaver << m_nFieldBgn;
+ ArchiveSaver << m_nOldFieldLength;
+ ArchiveSaver << m_nNewFieldLength;
+ ArchiveSaver << m_wsIns;
+ ArchiveSaver << m_bSel;
+ FX_INT32 nLength = ArchiveSaver.GetLength();
+ FX_LPCBYTE lpSrcBuf = ArchiveSaver.GetBuffer();
+ FX_LPSTR lpDstBuf = bsDoRecord.GetBuffer(nLength);
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
+ bsDoRecord.ReleaseBuffer(nLength);
+}
+void CFDE_TxtEdtDoRecord_FieldInsert::Deserialize(FX_BSTR bsDoRecord)
+{
+ CFX_ArchiveLoader ArchiveLoader((FX_LPCBYTE)bsDoRecord.GetCStr(), bsDoRecord.GetLength());
+ FX_INT32 nType = 0;
+ ArchiveLoader >> nType;
+ FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATINS);
+ FX_INT32 nEngine = 0;
+ ArchiveLoader >> nEngine;
+ m_pEngine = (CFDE_TxtEdtEngine*)(FX_UINTPTR)nEngine;
+ ArchiveLoader >> m_nCaret;
+ FX_INT32 nField = 0;
+ ArchiveLoader >> nField;
+ m_pField = (CFDE_TxtEdtField*)nField;
+ ArchiveLoader >> m_nIndexInField;
+ ArchiveLoader >> m_nFieldBgn;
+ ArchiveLoader >> m_nOldFieldLength;
+ ArchiveLoader >> m_nNewFieldLength;
+ ArchiveLoader >> m_wsIns;
+ ArchiveLoader >> m_bSel;
+}
+CFDE_TxtEdtDoRecord_FieldDelete::CFDE_TxtEdtDoRecord_FieldDelete(FX_BSTR bsDoRecord)
+{
+ Deserialize(bsDoRecord);
+}
+CFDE_TxtEdtDoRecord_FieldDelete::CFDE_TxtEdtDoRecord_FieldDelete(CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ CFDE_TxtEdtField * pField,
+ FX_INT32 nIndexInField,
+ FX_INT32 nFieldBgn,
+ FX_INT32 nOldLength,
+ FX_INT32 nNewLength,
+ const CFX_WideString &wsDel,
+ FX_BOOL bSel )
+ : m_pEngine(pEngine)
+ , m_nCaret(nCaret)
+ , m_pField(pField)
+ , m_nIndexInField(nIndexInField)
+ , m_nFieldBgn(nFieldBgn)
+ , m_nOldFieldLength(nOldLength)
+ , m_nNewFieldLength(nNewLength)
+ , m_wsDel(wsDel)
+ , m_bSel(bSel)
+{
+ FXSYS_assert(m_pEngine);
+ FXSYS_assert(m_pField);
+}
+CFDE_TxtEdtDoRecord_FieldDelete::~CFDE_TxtEdtDoRecord_FieldDelete()
+{
+}
+void CFDE_TxtEdtDoRecord_FieldDelete::Release()
+{
+ delete this;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_FieldDelete::Undo()
+{
+ FX_INT32 nCaret = 0;
+ FX_BOOL bBefore = FALSE;
+ FX_INT32 nRet = m_pField->Insert(m_nIndexInField, m_wsDel, nCaret, bBefore);
+ FXSYS_assert(nRet != FDE_FORMAT_FIELD_INSERT_RET_F_FULL && nRet != FDE_FORMAT_FIELD_INSERT_RET_F_INVALIDATE);
+ CFX_WideString wsDisplay;
+ m_pField->GetDisplayText(wsDisplay);
+ m_pEngine->Replace(m_nFieldBgn, m_nNewFieldLength, wsDisplay);
+ m_pEngine->SetCaretPos(m_nCaret, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_FieldDelete::Redo()
+{
+ FX_INT32 nCaret = 0;
+ FX_BOOL bBefore = 0;
+ CFX_WideString wsDel;
+ FX_INT32 nRet = m_pField->Delete(m_nIndexInField, m_wsDel.GetLength(), wsDel, nCaret, bBefore);
+ FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
+ CFX_WideString wsDisplay;
+ m_pField->GetDisplayText(wsDisplay);
+ m_pEngine->Replace(m_nFieldBgn, m_nOldFieldLength, wsDisplay);
+ m_pEngine->SetCaretPos(m_nCaret - m_wsDel.GetLength(), TRUE);
+ return TRUE;
+}
+void CFDE_TxtEdtDoRecord_FieldDelete::Serialize(CFX_ByteString &bsDoRecord) const
+{
+ CFX_ArchiveSaver ArchiveSaver;
+ ArchiveSaver << FX_INT32(FDE_TXTEDT_DORECORD_FORMATDEL);
+ ArchiveSaver << FX_INT32(m_pEngine);
+ ArchiveSaver << m_nCaret;
+ ArchiveSaver << FX_INT32(m_pField);
+ ArchiveSaver << m_nIndexInField;
+ ArchiveSaver << m_nFieldBgn;
+ ArchiveSaver << m_nOldFieldLength;
+ ArchiveSaver << m_nNewFieldLength;
+ ArchiveSaver << m_wsDel;
+ ArchiveSaver << m_bSel;
+ FX_INT32 nLength = ArchiveSaver.GetLength();
+ FX_LPCBYTE lpSrcBuf = ArchiveSaver.GetBuffer();
+ FX_LPSTR lpDstBuf = bsDoRecord.GetBuffer(nLength);
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
+ bsDoRecord.ReleaseBuffer(nLength);
+}
+void CFDE_TxtEdtDoRecord_FieldDelete::Deserialize(FX_BSTR bsDoRecord)
+{
+ CFX_ArchiveLoader ArchiveLoader((FX_LPCBYTE)bsDoRecord.GetCStr(), bsDoRecord.GetLength());
+ FX_INT32 nType = 0;
+ ArchiveLoader >> nType;
+ FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATDEL);
+ FX_INT32 nEngine = 0;
+ ArchiveLoader >> nEngine;
+ m_pEngine = (CFDE_TxtEdtEngine*)(FX_UINTPTR)nEngine;
+ ArchiveLoader >> m_nCaret;
+ FX_INT32 nField = 0;
+ ArchiveLoader >> nField;
+ m_pField = (CFDE_TxtEdtField*)nField;
+ ArchiveLoader >> m_nIndexInField;
+ ArchiveLoader >> m_nFieldBgn;
+ ArchiveLoader >> m_nOldFieldLength;
+ ArchiveLoader >> m_nNewFieldLength;
+ ArchiveLoader >> m_wsDel;
+ ArchiveLoader >> m_bSel;
+}
+CFDE_TxtEdtDoRecord_FieldReplace::CFDE_TxtEdtDoRecord_FieldReplace(FX_BSTR bsDoRecord)
+{
+ Deserialize(bsDoRecord);
+}
+CFDE_TxtEdtDoRecord_FieldReplace::CFDE_TxtEdtDoRecord_FieldReplace( CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ FX_INT32 nNewCaret,
+ CFDE_TxtEdtField * pField,
+ FX_INT32 nIndexInField,
+ FX_INT32 nFieldBgn,
+ FX_INT32 nFieldNewLength,
+ const CFX_WideString &wsDel,
+ const CFX_WideString &wsIns,
+ FX_BOOL bSel)
+ : m_pEngine(pEngine)
+ , m_nCaret(nCaret)
+ , m_nNewCaret(nNewCaret)
+ , m_pField(pField)
+ , m_nIndexInField(nIndexInField)
+ , m_nFieldBgn(nFieldBgn)
+ , m_nFieldNewLength(nFieldNewLength)
+ , m_wsDel(wsDel)
+ , m_wsIns(wsIns)
+ , m_bSel(bSel)
+{
+ FXSYS_assert(m_pEngine);
+ FXSYS_assert(m_pField);
+}
+CFDE_TxtEdtDoRecord_FieldReplace::~CFDE_TxtEdtDoRecord_FieldReplace()
+{
+}
+void CFDE_TxtEdtDoRecord_FieldReplace::Release()
+{
+ delete this;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_FieldReplace::Undo()
+{
+ CFX_WideString wsDel;
+ FX_INT32 nCaret = 0;
+ FX_BOOL bBefore = FALSE;
+ FX_INT32 nRet = m_pField->Replace(m_nIndexInField, m_wsIns.GetLength(), m_wsDel, wsDel, nCaret, bBefore);
+ FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
+ CFX_WideString wsDisplay;
+ m_pField->GetDisplayText(wsDisplay);
+ m_pEngine->Replace(m_nFieldBgn, m_nFieldNewLength, wsDisplay);
+ m_pEngine->SetCaretPos(m_nCaret, TRUE);
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtDoRecord_FieldReplace::Redo()
+{
+ CFX_WideString wsDel;
+ FX_INT32 nCaret = 0;
+ FX_BOOL bBefore = FALSE;
+ FX_INT32 nRet = m_pField->Replace(m_nIndexInField, m_wsDel.GetLength(), m_wsIns, wsDel, nCaret, bBefore);
+ FXSYS_assert(nRet != FDE_FORMAT_FIELD_DELETE_RET_F_INVALIDATE && nRet != FDE_FORMAT_FIELD_DELETE_RET_F_BOUNDARY);
+ CFX_WideString wsDisplay;
+ m_pField->GetDisplayText(wsDisplay);
+ m_pEngine->Replace(m_nFieldBgn, m_nFieldNewLength, wsDisplay);
+ m_pEngine->SetCaretPos(m_nNewCaret, TRUE);
+ return TRUE;
+}
+void CFDE_TxtEdtDoRecord_FieldReplace::Serialize(CFX_ByteString &bsDoRecord) const
+{
+ CFX_ArchiveSaver ArchiveSaver;
+ ArchiveSaver << FX_INT32(FDE_TXTEDT_DORECORD_FORMATREP);
+ ArchiveSaver << FX_INT32(m_pEngine);
+ ArchiveSaver << m_nCaret;
+ ArchiveSaver << m_nNewCaret;
+ ArchiveSaver << FX_INT32(m_pField);
+ ArchiveSaver << m_nIndexInField;
+ ArchiveSaver << m_nFieldBgn;
+ ArchiveSaver << m_nFieldNewLength;
+ ArchiveSaver << m_wsDel;
+ ArchiveSaver << m_wsIns;
+ ArchiveSaver << m_bSel;
+ FX_INT32 nLength = ArchiveSaver.GetLength();
+ FX_LPCBYTE lpSrcBuf = ArchiveSaver.GetBuffer();
+ FX_LPSTR lpDstBuf = bsDoRecord.GetBuffer(nLength);
+ FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
+ bsDoRecord.ReleaseBuffer(nLength);
+}
+void CFDE_TxtEdtDoRecord_FieldReplace::Deserialize(FX_BSTR bsDoRecord)
+{
+ CFX_ArchiveLoader ArchiveLoader((FX_LPCBYTE)bsDoRecord.GetCStr(), bsDoRecord.GetLength());
+ FX_INT32 nType = 0;
+ ArchiveLoader >> nType;
+ FXSYS_assert(nType == FDE_TXTEDT_DORECORD_FORMATREP);
+ FX_INT32 nEngine = 0;
+ ArchiveLoader >> nEngine;
+ m_pEngine = (CFDE_TxtEdtEngine*)(FX_UINTPTR)nEngine;
+ ArchiveLoader >> m_nCaret;
+ ArchiveLoader >> m_nNewCaret;
+ FX_INT32 nField = 0;
+ ArchiveLoader >> nField;
+ m_pField = (CFDE_TxtEdtField*)nField;
+ ArchiveLoader >> m_nIndexInField;
+ ArchiveLoader >> m_nFieldBgn;
+ ArchiveLoader >> m_nFieldNewLength;
+ ArchiveLoader >> m_wsDel;
+ ArchiveLoader >> m_wsIns;
+ ArchiveLoader >> m_bSel;
+}
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtengine.h b/xfa/src/fee/src/fee/fde_txtedtengine.h
new file mode 100644
index 0000000000..f9f7a6dc8e
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtengine.h
@@ -0,0 +1,341 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TXTEDTENGINE_H
+#define _FDE_TXTEDTENGINE_H
+class CFDE_TxtEdtBuf;
+class CFDE_TxtEdtPage;
+class IFX_TxtBreak;
+class CFDE_TxtEdtParag;
+class CFDE_TxtEdtKMPMatch;
+class IFDE_TxtEdtFormator;
+class CFDE_TxtEdtField;
+class CFDE_TxtEdtBlock;
+class IFX_CharIter;
+class CFDE_TxtEdtEngine;
+class CFDE_TxtEdtDoRecord_Insert;
+class CFDE_TxtEdtDoRecord_DeleteRange;
+#ifdef FDE_USEFORMATBLOCK
+class CFDE_TxtEdtDoRecord_FormatInsert;
+class CFDE_TxtEdtDoRecord_FormatDelete;
+class CFDE_TxtEdtDoRecord_FormatReplace;
+class CFDE_TxtEdtDoRecord_FieldInsert;
+class CFDE_TxtEdtDoRecord_FieldDelete;
+class CFDE_TxtEdtDoRecord_FieldReplace;
+#endif
+class IFDE_TxtEdtDoRecord
+{
+public:
+ static IFDE_TxtEdtDoRecord * Create(FX_BSTR bsDoRecord);
+ virtual void Release() = 0;
+ virtual FX_BOOL Redo() = 0;
+ virtual FX_BOOL Undo() = 0;
+ virtual void Serialize(CFX_ByteString &bsDoRecord) const = 0;
+};
+class CFDE_TxtEdtEngine : public IFDE_TxtEdtEngine, public CFX_Object
+{
+ friend class CFDE_TxtEdtDoRecord_Insert;
+ friend class CFDE_TxtEdtDoRecord_DeleteRange;
+ friend class CFDE_TxtEdtPage;
+#ifdef FDE_USEFORMATBLOCK
+ friend class CFDE_TxtEdtDoRecord_FormatInsert;
+ friend class CFDE_TxtEdtDoRecord_FormatDelete;
+ friend class CFDE_TxtEdtDoRecord_FormatReplace;
+ friend class CFDE_TxtEdtBlock;
+#endif
+ struct _FDE_TXTEDTSELRANGE : public CFX_Object {
+ FX_INT32 nStart;
+ FX_INT32 nCount;
+ };
+ typedef _FDE_TXTEDTSELRANGE FDE_TXTEDTSELRANGE;
+ typedef _FDE_TXTEDTSELRANGE * FDE_LPTXTEDTSELRANGE;
+ struct _FDE_TXTEDTPARAGPOS : public CFX_Object {
+ FX_INT32 nParagIndex;
+ FX_INT32 nCharIndex;
+ };
+ typedef _FDE_TXTEDTPARAGPOS FDE_TXTEDTPARAGPOS;
+ typedef _FDE_TXTEDTPARAGPOS * FDE_LPTXTEDTPARAGPOS;
+public:
+ CFDE_TxtEdtEngine();
+ virtual void Release();
+
+ virtual void SetEditParams(const FDE_TXTEDTPARAMS &params);
+ virtual const FDE_TXTEDTPARAMS* GetEditParams() const;
+
+ virtual FX_INT32 CountPages() const;
+ virtual IFDE_TxtEdtPage* GetPage(FX_INT32 nIndex);
+
+ virtual FX_BOOL SetBufChunkSize(FX_INT32 nChunkSize);
+ virtual void SetTextByStream(IFX_Stream *pStream);
+ virtual void SetText(const CFX_WideString &wsText);
+ virtual FX_INT32 GetTextLength() const;
+ virtual void GetText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount = -1);
+ virtual void ClearText();
+
+ virtual FX_INT32 GetCaretRect(CFX_RectF &rtCaret) const;
+ virtual FX_INT32 GetCaretPos() const;
+ virtual FX_INT32 SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore);
+ virtual FX_INT32 MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret, FX_BOOL bShift = FALSE, FX_BOOL bCtrl = FALSE);
+ virtual void Lock();
+ virtual void Unlock();
+ virtual FX_BOOL IsLocked() const;
+
+ virtual FX_INT32 Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLength);
+ virtual FX_INT32 Delete(FX_INT32 nStart, FX_BOOL bBackspace = FALSE);
+ virtual FX_INT32 DeleteRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ virtual FX_INT32 Replace(FX_INT32 nStart, FX_INT32 nLength, const CFX_WideString &wsReplace);
+
+ virtual void SetLimit(FX_INT32 nLimit);
+ virtual void SetAliasChar(FX_WCHAR wcAlias);
+ virtual void SetFormatBlock(FX_INT32 nIndex, const CFX_WideString &wsBlockFormat);
+ virtual FX_INT32 CountEditBlocks() const;
+ virtual void GetEditBlockText(FX_INT32 nIndex, CFX_WideString &wsBlockText) const;
+ virtual FX_INT32 CountEditFields(FX_INT32 nBlockIndex) const;
+ virtual void GetEditFieldText(FX_INT32 nBlockIndex, FX_INT32 nFieldIndex, CFX_WideString &wsFieldText) const;
+ virtual void StartEdit();
+ virtual void EndEdit();
+
+ void RemoveSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+
+ virtual void AddSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ virtual FX_INT32 CountSelRanges();
+ virtual FX_INT32 GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ virtual void ClearSelection();
+
+ virtual FX_BOOL Redo(FX_BSTR bsRedo);
+ virtual FX_BOOL Undo(FX_BSTR bsUndo);
+
+ virtual FX_INT32 StartLayout();
+ virtual FX_INT32 DoLayout(IFX_Pause *pPause);
+ virtual void EndLayout();
+
+ virtual FX_BOOL Optimize(IFX_Pause * pPause = NULL);
+ virtual FX_INT32 CountParags() const;
+ virtual IFDE_TxtEdtParag* GetParag(FX_INT32 nParagIndex) const;
+ virtual IFX_CharIter* CreateCharIter();
+ IFDE_TxtEdtBuf* GetTextBuf() const;
+ FX_INT32 GetTextBufLength() const;
+ IFX_TxtBreak* GetTextBreak() const;
+ FX_INT32 GetLineCount() const;
+ FX_INT32 GetPageLineCount() const;
+
+ FX_INT32 Line2Parag(FX_INT32 nStartParag, FX_INT32 nStartLineofParag,
+ FX_INT32 nLineIndex, FX_INT32 &nStartLine) const;
+ FX_WCHAR GetAliasChar() const
+ {
+ return m_wcAliasChar;
+ }
+
+protected:
+ virtual ~CFDE_TxtEdtEngine();
+private:
+ void Inner_Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLength);
+#ifdef FDE_USEFORMATBLOCK
+ void RawInsert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLength);
+#endif
+ void GetPreDeleteText(CFX_WideString &wsText, FX_INT32 nIndex, FX_INT32 nLength);
+ void GetPreInsertText(CFX_WideString &wsText, FX_INT32 nIndex, FX_LPCWSTR lpText, FX_INT32 nLength);
+ void GetPreReplaceText(CFX_WideString &wsText, FX_INT32 nIndex, FX_INT32 nOriginLength, FX_LPCWSTR lpText, FX_INT32 nLength);
+
+ void Inner_DeleteRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ void DeleteRange_DoRecord(FX_INT32 nStart, FX_INT32 nCount, FX_BOOL bSel = FALSE);
+ void ResetEngine();
+ void RebuildParagraphs();
+ void RemoveAllParags();
+ void RemoveAllPages();
+ void UpdateParags();
+ void UpdatePages();
+ void UpdateTxtBreak();
+
+ FX_BOOL ReplaceParagEnd(FX_LPWSTR &lpText, FX_INT32 &nLength, FX_BOOL bPreIsCR = FALSE);
+ void RecoverParagEnd(CFX_WideString &wsText);
+ FX_INT32 MovePage2Char(FX_INT32 nIndex);
+ void TextPos2ParagPos(FX_INT32 nIndex, FDE_TXTEDTPARAGPOS &ParagPos) const;
+ FX_INT32 MoveForward(FX_BOOL &bBefore);
+ FX_INT32 MoveBackward(FX_BOOL &bBefore);
+ FX_BOOL MoveUp(CFX_PointF &ptCaret);
+ FX_BOOL MoveDown(CFX_PointF &ptCaret);
+ FX_BOOL MoveLineStart();
+ FX_BOOL MoveLineEnd();
+ FX_BOOL MoveParagStart();
+ FX_BOOL MoveParagEnd();
+ FX_BOOL MoveHome();
+ FX_BOOL MoveEnd();
+ FX_BOOL IsFitArea(CFX_WideString &wsText);
+ void UpdateCaretRect(FX_INT32 nIndex, FX_BOOL bBefore = TRUE);
+ void GetCaretRect(CFX_RectF &rtCaret, FX_INT32 nPageIndex, FX_INT32 nCaret, FX_BOOL bBefore = TRUE);
+ void UpdateCaretIndex(const CFX_PointF & ptCaret);
+
+ FX_BOOL IsSelect();
+ void DeleteSelect();
+ IFDE_TxtEdtBuf* m_pTxtBuf;
+ IFX_TxtBreak* m_pTextBreak;
+ FDE_TXTEDTPARAMS m_Param;
+ CFX_ArrayTemplate<IFDE_TxtEdtPage*> m_PagePtrArray;
+ CFX_ArrayTemplate<CFDE_TxtEdtParag*> m_ParagPtrArray;
+ CFX_ArrayTemplate<FDE_LPTXTEDTSELRANGE> m_SelRangePtrArr;
+ FX_INT32 m_nPageLineCount;
+ FX_INT32 m_nLineCount;
+ FX_INT32 m_nAnchorPos;
+ FX_INT32 m_nLayoutPos;
+ FX_FLOAT m_fCaretPosReserve;
+ FX_INT32 m_nCaret;
+ FX_BOOL m_bBefore;
+ FX_INT32 m_nCaretPage;
+ CFX_RectF m_rtCaret;
+ FX_DWORD m_dwFindFlags;
+
+ FX_BOOL m_bLock;
+ FX_INT32 m_nLimit;
+ FX_WCHAR m_wcAliasChar;
+ FX_INT32 m_nFirstLineEnd;
+ FX_BOOL m_bAutoLineEnd;
+ FX_WCHAR m_wLineEnd;
+
+ FDE_TXTEDT_TEXTCHANGE_INFO m_ChangeInfo;
+};
+class CFDE_TxtEdtDoRecord_Insert : public IFDE_TxtEdtDoRecord, public CFX_Object
+{
+public:
+ CFDE_TxtEdtDoRecord_Insert(FX_BSTR bsDoRecord);
+ CFDE_TxtEdtDoRecord_Insert( CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ FX_LPCWSTR lpText,
+ FX_INT32 nLength);
+ virtual void Release();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual void Serialize(CFX_ByteString &bsDoRecord) const;
+protected:
+ ~CFDE_TxtEdtDoRecord_Insert();
+ void Deserialize(FX_BSTR bsDoRecord);
+private:
+ CFDE_TxtEdtEngine * m_pEngine;
+ FX_INT32 m_nCaret;
+ CFX_WideString m_wsInsert;
+};
+class CFDE_TxtEdtDoRecord_DeleteRange : public IFDE_TxtEdtDoRecord, public CFX_Object
+{
+public:
+ CFDE_TxtEdtDoRecord_DeleteRange(FX_BSTR bsDoRecord);
+ CFDE_TxtEdtDoRecord_DeleteRange(CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nIndex,
+ FX_INT32 nCaret,
+ const CFX_WideString &wsRange,
+ FX_BOOL bSel = FALSE);
+ virtual void Release();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual void Serialize(CFX_ByteString &bsDoRecord) const;
+protected:
+ ~CFDE_TxtEdtDoRecord_DeleteRange();
+ void Deserialize(FX_BSTR bsDoRecord);
+private:
+ CFDE_TxtEdtEngine * m_pEngine;
+ FX_BOOL m_bSel;
+ FX_INT32 m_nIndex;
+ FX_INT32 m_nCaret;
+ CFX_WideString m_wsRange;
+};
+#ifdef FDE_USEFORMATBLOCK
+class CFDE_TxtEdtDoRecord_FieldInsert : public IFDE_TxtEdtDoRecord, public CFX_Object
+{
+public:
+ CFDE_TxtEdtDoRecord_FieldInsert(FX_BSTR bsDoRecord);
+ CFDE_TxtEdtDoRecord_FieldInsert(CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ CFDE_TxtEdtField * pField,
+ FX_INT32 nIndexInField,
+ FX_INT32 nFieldBgn,
+ FX_INT32 nOldFieldLength,
+ FX_INT32 nNewFieldLength,
+ const CFX_WideString &wsIns,
+ FX_BOOL bSel = FALSE);
+ virtual void Release();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual void Serialize(CFX_ByteString &bsDoRecord) const;
+protected:
+ ~CFDE_TxtEdtDoRecord_FieldInsert();
+ void Deserialize(FX_BSTR bsDoRecord);
+
+private:
+ CFDE_TxtEdtEngine * m_pEngine;
+ FX_INT32 m_nCaret;
+ CFDE_TxtEdtField * m_pField;
+ FX_INT32 m_nIndexInField;
+ FX_INT32 m_nFieldBgn;
+ FX_INT32 m_nOldFieldLength;
+ FX_INT32 m_nNewFieldLength;
+ CFX_WideString m_wsIns;
+ FX_BOOL m_bSel;
+};
+class CFDE_TxtEdtDoRecord_FieldDelete : public IFDE_TxtEdtDoRecord, public CFX_Object
+{
+public:
+ CFDE_TxtEdtDoRecord_FieldDelete(FX_BSTR bsDoRecord);
+ CFDE_TxtEdtDoRecord_FieldDelete(CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ CFDE_TxtEdtField * pField,
+ FX_INT32 nIndexInField,
+ FX_INT32 nFieldBgn,
+ FX_INT32 nOldLength,
+ FX_INT32 nNewLength,
+ const CFX_WideString &wsDel,
+ FX_BOOL bSel = FALSE);
+ virtual void Release();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual void Serialize(CFX_ByteString &bsDoRecord) const;
+protected:
+ ~CFDE_TxtEdtDoRecord_FieldDelete();
+ void Deserialize(FX_BSTR bsDoRecord);
+private:
+ CFDE_TxtEdtEngine * m_pEngine;
+ FX_INT32 m_nCaret;
+ CFDE_TxtEdtField * m_pField;
+ FX_INT32 m_nIndexInField;
+ FX_INT32 m_nFieldBgn;
+ FX_INT32 m_nOldFieldLength;
+ FX_INT32 m_nNewFieldLength;
+ CFX_WideString m_wsDel;
+ FX_BOOL m_bSel;
+};
+class CFDE_TxtEdtDoRecord_FieldReplace : public IFDE_TxtEdtDoRecord, public CFX_Object
+{
+public:
+ CFDE_TxtEdtDoRecord_FieldReplace(FX_BSTR bsDoRecord);
+ CFDE_TxtEdtDoRecord_FieldReplace( CFDE_TxtEdtEngine * pEngine,
+ FX_INT32 nCaret,
+ FX_INT32 nNewCaret,
+ CFDE_TxtEdtField * pField,
+ FX_INT32 nIndexInField,
+ FX_INT32 nFieldBgn,
+ FX_INT32 nFieldNewLength,
+ const CFX_WideString &wsDel,
+ const CFX_WideString &wsIns,
+ FX_BOOL bSel);
+ virtual void Release();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual void Serialize(CFX_ByteString &bsDoRecord) const;
+protected:
+ ~CFDE_TxtEdtDoRecord_FieldReplace();
+ void Deserialize(FX_BSTR bsDoRecord);
+private:
+ CFDE_TxtEdtEngine * m_pEngine;
+ FX_INT32 m_nCaret;
+ FX_INT32 m_nNewCaret;
+ CFDE_TxtEdtField * m_pField;
+ FX_INT32 m_nIndexInField;
+ FX_INT32 m_nFieldBgn;
+ FX_INT32 m_nFieldNewLength;
+ CFX_WideString m_wsDel;
+ CFX_WideString m_wsIns;
+ FX_BOOL m_bSel;
+};
+#endif
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtkmpmatch.cpp b/xfa/src/fee/src/fee/fde_txtedtkmpmatch.cpp
new file mode 100644
index 0000000000..7d0790bf8c
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtkmpmatch.cpp
@@ -0,0 +1,8 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_txtedtkmpmatch.h"
diff --git a/xfa/src/fee/src/fee/fde_txtedtkmpmatch.h b/xfa/src/fee/src/fee/fde_txtedtkmpmatch.h
new file mode 100644
index 0000000000..0b5b477172
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtkmpmatch.h
@@ -0,0 +1,9 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_KMPMATCH_H
+#define _FDE_KMPMATCH_H
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtpage.cpp b/xfa/src/fee/src/fee/fde_txtedtpage.cpp
new file mode 100644
index 0000000000..e0a94f81fa
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtpage.cpp
@@ -0,0 +1,647 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../../include/ifde_txtedtbuf.h"
+#include "../../include/ifde_txtedtengine.h"
+#include "../../include/ifde_txtedtpage.h"
+#include "../../include/fx_wordbreak.h"
+#include "fde_txtedtpage.h"
+#include "fde_txtedtengine.h"
+#include "fde_txtedtparag.h"
+#include "fde_txtedtbuf.h"
+#define FDE_TXTEDT_TOLERANCE 0.1f
+IFDE_TxtEdtPage * IFDE_TxtEdtPage::Create(IFDE_TxtEdtEngine * pEngine, FX_INT32 nIndex)
+{
+ return (IFDE_TxtEdtPage*)FX_NEW CFDE_TxtEdtPage(pEngine, nIndex);
+}
+CFDE_TxtEdtTextSet::CFDE_TxtEdtTextSet(CFDE_TxtEdtPage * pPage)
+ : m_pPage(pPage)
+{
+}
+CFDE_TxtEdtTextSet::~CFDE_TxtEdtTextSet()
+{
+}
+FDE_VISUALOBJTYPE CFDE_TxtEdtTextSet::GetType()
+{
+ return FDE_VISUALOBJ_Text;
+}
+FX_BOOL CFDE_TxtEdtTextSet::GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF &bbox)
+{
+ return FALSE;
+}
+FX_BOOL CFDE_TxtEdtTextSet::GetMatrix(FDE_HVISUALOBJ hVisualObj, CFX_Matrix &matrix)
+{
+ return FALSE;
+}
+FX_BOOL CFDE_TxtEdtTextSet::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt)
+{
+ rt = ((FDE_LPTEXTEDITPIECE)(hVisualObj))->rtPiece;
+ return TRUE;
+}
+FX_BOOL CFDE_TxtEdtTextSet::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt)
+{
+ return FALSE;
+}
+FX_INT32 CFDE_TxtEdtTextSet::GetString(FDE_HVISUALOBJ hText, CFX_WideString &wsText)
+{
+ FDE_LPTEXTEDITPIECE pPiece = (FDE_LPTEXTEDITPIECE)hText;
+ FX_LPWSTR pBuffer = wsText.GetBuffer(pPiece->nCount);
+ for (FX_INT32 i = 0; i < pPiece->nCount; i++) {
+ pBuffer[i] = m_pPage->GetChar((FX_LPVOID)hText, i);
+ }
+ wsText.ReleaseBuffer(pPiece->nCount);
+ return pPiece->nCount;
+}
+IFX_Font* CFDE_TxtEdtTextSet::GetFont(FDE_HVISUALOBJ hText)
+{
+ return m_pPage->GetEngine()->GetEditParams()->pFont;
+}
+FX_FLOAT CFDE_TxtEdtTextSet::GetFontSize(FDE_HVISUALOBJ hText)
+{
+ return m_pPage->GetEngine()->GetEditParams()->fFontSize;
+}
+FX_ARGB CFDE_TxtEdtTextSet::GetFontColor(FDE_HVISUALOBJ hText)
+{
+ return m_pPage->GetEngine()->GetEditParams()->dwFontColor;
+}
+FX_INT32 CFDE_TxtEdtTextSet::GetDisplayPos(FDE_HVISUALOBJ hText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode , CFX_WideString *pWSForms )
+{
+ if (hText == NULL) {
+ return 0;
+ }
+ FDE_LPTEXTEDITPIECE pPiece = (FDE_LPTEXTEDITPIECE)hText;
+ FX_INT32 nLength = pPiece->nCount;
+ if (nLength < 1) {
+ return 0;
+ }
+ CFDE_TxtEdtEngine * pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine());
+ const FDE_TXTEDTPARAMS * pTextParams = pEngine->GetEditParams();
+ IFX_TxtBreak * pBreak = pEngine->GetTextBreak();
+ FX_DWORD dwLayoutStyle = pBreak->GetLayoutStyles();
+ FX_TXTRUN tr;
+ tr.pAccess = m_pPage;
+ tr.pIdentity = (FX_LPVOID)hText;
+ tr.pStr = NULL;
+ tr.pWidths = NULL;
+ tr.iLength = nLength;
+ tr.pFont = pTextParams->pFont;
+ tr.fFontSize = pTextParams->fFontSize;
+ tr.dwStyles = dwLayoutStyle;
+ tr.iCharRotation = pTextParams->nCharRotation;
+ tr.dwCharStyles = pPiece->dwCharStyles;
+ tr.pRect = &(pPiece->rtPiece);
+ tr.wLineBreakChar = pTextParams->wLineBreakChar;
+ return pBreak->GetDisplayPos(&tr, pCharPos, bCharCode, pWSForms);
+}
+FX_INT32 CFDE_TxtEdtTextSet::GetCharRects(FDE_HVISUALOBJ hText, CFX_RectFArray &rtArray)
+{
+ return GetCharRects_Impl(hText, rtArray);
+}
+FX_INT32 CFDE_TxtEdtTextSet::GetCharRects_Impl(FDE_HVISUALOBJ hText, CFX_RectFArray &rtArray, FX_BOOL bBBox )
+{
+ if (hText == NULL) {
+ return 0;
+ }
+ FDE_LPTEXTEDITPIECE pPiece = (FDE_LPTEXTEDITPIECE)hText;
+ CFDE_TxtEdtEngine * pEngine = (CFDE_TxtEdtEngine*)(m_pPage->GetEngine());
+ FX_INT32 nLength = pPiece->nCount;
+ if (nLength < 1) {
+ return 0;
+ }
+ const FDE_TXTEDTPARAMS * pTextParams = pEngine->GetEditParams();
+ FX_DWORD dwLayoutStyle = pEngine->GetTextBreak()->GetLayoutStyles();
+ FX_TXTRUN tr;
+ tr.pAccess = m_pPage;
+ tr.pIdentity = (FX_LPVOID)hText;
+ tr.pStr = NULL;
+ tr.pWidths = NULL;
+ tr.iLength = nLength;
+ tr.pFont = pTextParams->pFont;
+ tr.fFontSize = pTextParams->fFontSize;
+ tr.dwStyles = dwLayoutStyle;
+ tr.iCharRotation = pTextParams->nCharRotation;
+ tr.dwCharStyles = pPiece->dwCharStyles;
+ tr.pRect = &(pPiece->rtPiece);
+ tr.wLineBreakChar = pTextParams->wLineBreakChar;
+ return pEngine->GetTextBreak()->GetCharRects(&tr, rtArray, bBBox);
+}
+CFDE_TxtEdtPage::CFDE_TxtEdtPage(IFDE_TxtEdtEngine * pEngine, FX_INT32 nPageIndex)
+ : m_pIter(NULL)
+ , m_pTextSet(NULL)
+ , m_nRefCount(0)
+ , m_nPageStart(-1)
+ , m_nCharCount(0)
+ , m_nPageIndex(nPageIndex)
+ , m_bLoaded(FALSE)
+ , m_bLastPage(FALSE)
+ , m_pCharWidth(NULL)
+ , m_pBgnParag(NULL)
+ , m_pEndParag(NULL)
+{
+ FXSYS_memset(&m_rtPage, 0, sizeof(CFX_RectF));
+ FXSYS_memset(&m_rtPageMargin, 0, sizeof(CFX_RectF));
+ FXSYS_memset(&m_rtPageContents, 0, sizeof(CFX_RectF));
+ FXSYS_memset(&m_rtPageCanvas, 0, sizeof(CFX_RectF));
+ m_pEditEngine = (CFDE_TxtEdtEngine*)pEngine;
+}
+CFDE_TxtEdtPage::~CFDE_TxtEdtPage()
+{
+ m_PieceMassArr.RemoveAll(TRUE);
+ if (m_pTextSet) {
+ delete m_pTextSet;
+ m_pTextSet = NULL;
+ }
+ if (m_pCharWidth) {
+ delete [] m_pCharWidth;
+ m_pCharWidth = NULL;
+ }
+ if (m_pIter != NULL) {
+ m_pIter->Release();
+ m_pIter = NULL;
+ }
+}
+void CFDE_TxtEdtPage::Release()
+{
+ delete this;
+}
+IFDE_TxtEdtEngine * CFDE_TxtEdtPage::GetEngine() const
+{
+ return (IFDE_TxtEdtEngine*)m_pEditEngine;
+}
+FDE_VISUALOBJTYPE CFDE_TxtEdtPage::GetType()
+{
+ return FDE_VISUALOBJ_Text;
+}
+FX_BOOL CFDE_TxtEdtPage::GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF &bbox)
+{
+ return FALSE;
+}
+FX_BOOL CFDE_TxtEdtPage::GetMatrix(FDE_HVISUALOBJ hVisualObj, CFX_Matrix &matrix)
+{
+ return FALSE;
+}
+FX_BOOL CFDE_TxtEdtPage::GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt)
+{
+ return FALSE;
+}
+FX_BOOL CFDE_TxtEdtPage::GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt)
+{
+ return FALSE;
+}
+FX_INT32 CFDE_TxtEdtPage::GetCharRect(FX_INT32 nIndex, CFX_RectF &rect, FX_BOOL bBBox ) const
+{
+ FXSYS_assert(m_nRefCount > 0);
+ FXSYS_assert(nIndex >= 0 && nIndex < m_nCharCount);
+ if (m_nRefCount < 1) {
+ return 0;
+ }
+ FX_INT32 nCount = m_PieceMassArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ const FDE_LPTEXTEDITPIECE pPiece = m_PieceMassArr.GetPtrAt(i);
+ if (nIndex >= pPiece->nStart && nIndex < (pPiece->nStart + pPiece->nCount)) {
+ CFX_RectFArray rectArr;
+ if (bBBox) {
+ m_pTextSet->GetCharRects_Impl((FDE_HVISUALOBJ)pPiece, rectArr, bBBox);
+ } else {
+ m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr);
+ }
+ rect = rectArr[nIndex - pPiece->nStart];
+ return pPiece->nBidiLevel;
+ }
+ }
+ FXSYS_assert(0);
+ return 0;
+}
+FX_INT32 CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF &fPoint, FX_BOOL &bBefore)
+{
+ FX_BOOL bVertical = m_pEditEngine->GetEditParams()->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical;
+ CFX_PointF ptF = fPoint;
+ NormalizePt2Rect(ptF, m_rtPageContents, FDE_TXTEDT_TOLERANCE);
+ FX_INT32 nCount = m_PieceMassArr.GetSize();
+ CFX_RectF rtLine;
+ FX_INT32 nBgn = 0;
+ FX_INT32 nEnd = 0;
+ FX_BOOL bInLine = FALSE;
+ FX_INT32 i = 0;
+ for (i = 0; i < nCount; i ++) {
+ const FDE_LPTEXTEDITPIECE pPiece = m_PieceMassArr.GetPtrAt(i);
+ if (!bInLine && (bVertical ? (pPiece->rtPiece.left <= ptF.x && pPiece->rtPiece.right() > ptF.x) \
+ : (pPiece->rtPiece.top <= ptF.y && pPiece->rtPiece.bottom() > ptF.y))) {
+ nBgn = nEnd = i;
+ rtLine = pPiece->rtPiece;
+ bInLine = TRUE;
+ } else if (bInLine) {
+ if (bVertical ? (!(pPiece->rtPiece.left <= ptF.x && pPiece->rtPiece.right() > ptF.x)) : \
+ (pPiece->rtPiece.bottom() <= ptF.y || pPiece->rtPiece.top > ptF.y)) {
+ nEnd = i - 1;
+ break;
+ } else {
+ rtLine.Union(pPiece->rtPiece);
+ }
+ }
+ }
+ NormalizePt2Rect(ptF, rtLine, FDE_TXTEDT_TOLERANCE);
+ FX_INT32 nCaret = 0;
+ FDE_LPTEXTEDITPIECE pPiece = NULL;
+ for (i = nBgn; i <= nEnd; i ++) {
+ pPiece = m_PieceMassArr.GetPtrAt(i);
+ nCaret = m_nPageStart + pPiece->nStart;
+ if (pPiece->rtPiece.Contains(ptF)) {
+ CFX_RectFArray rectArr;
+ m_pTextSet->GetCharRects((FDE_HVISUALOBJ)pPiece, rectArr);
+ FX_INT32 nRtCount = rectArr.GetSize();
+ for (FX_INT32 j = 0; j < nRtCount; j ++) {
+ if (rectArr[j].Contains(ptF)) {
+ nCaret = m_nPageStart + pPiece->nStart + j;
+ if (nCaret >= m_pEditEngine->GetTextBufLength()) {
+ bBefore = TRUE;
+ return m_pEditEngine->GetTextBufLength();
+ }
+ FX_WCHAR wChar = m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret);
+ if (wChar == L'\n' || wChar == L'\r') {
+ if (wChar == L'\n') {
+ if (m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret - 1) == L'\r') {
+ nCaret --;
+ }
+ }
+ bBefore = TRUE;
+ return nCaret;
+ }
+ if (bVertical ? (ptF.y > ((rectArr[j].top + rectArr[j].bottom()) / 2)) : \
+ (ptF.x > ((rectArr[j].left + rectArr[j].right()) / 2))) {
+ bBefore = FX_IsOdd(pPiece->nBidiLevel);
+ } else {
+ bBefore = !FX_IsOdd(pPiece->nBidiLevel);
+ }
+ return nCaret;
+ }
+ }
+ }
+ }
+ bBefore = TRUE;
+ return nCaret;
+}
+FX_INT32 CFDE_TxtEdtPage::GetCharStart() const
+{
+ return m_nPageStart;
+}
+FX_INT32 CFDE_TxtEdtPage::GetCharCount() const
+{
+ return m_nCharCount;
+}
+FX_INT32 CFDE_TxtEdtPage::GetDisplayPos(const CFX_RectF &rtClip, FXTEXT_CHARPOS *&pCharPos, FX_LPRECTF pBBox ) const
+{
+ pCharPos = (FXTEXT_CHARPOS*)FDE_Alloc(sizeof(FXTEXT_CHARPOS) * m_nCharCount);
+ FX_INT32 nCharPosCount = 0;
+ FDE_HVISUALOBJ hVisualObj = NULL;
+ FX_INT32 nVisualObjCount = m_PieceMassArr.GetSize();
+ FXTEXT_CHARPOS* pos = pCharPos;
+ CFX_RectF rtObj;
+ for (FX_INT32 i = 0; i < nVisualObjCount; i ++) {
+ hVisualObj = (FDE_HVISUALOBJ)m_PieceMassArr.GetPtrAt(i);
+ m_pTextSet->GetRect(hVisualObj, rtObj);
+ if (!rtClip.IntersectWith(rtObj)) {
+ continue;
+ }
+ FX_INT32 nCount = m_pTextSet->GetDisplayPos(hVisualObj, pos, FALSE);
+ nCharPosCount += nCount;
+ pos += nCount;
+ }
+ if ((nCharPosCount * 5) < (m_nCharCount << 2)) {
+ FX_INT32 nLength = sizeof(FXTEXT_CHARPOS) * nCharPosCount;
+ FXTEXT_CHARPOS * pTemp = (FXTEXT_CHARPOS*)FDE_Alloc(nLength);
+ FXSYS_memcpy(pTemp, pCharPos, nLength);
+ FDE_Free(pCharPos);
+ pCharPos = pTemp;
+ }
+ return nCharPosCount;
+}
+void CFDE_TxtEdtPage::CalcRangeRectArray(FX_INT32 nStart, FX_INT32 nCount, CFX_RectFArray &RectFArr) const
+{
+ FX_INT32 nPieceCount = m_PieceMassArr.GetSize();
+ FX_INT32 nEnd = nStart + nCount - 1;
+ FX_BOOL bInRange = FALSE;
+ for (FX_INT32 i = 0; i < nPieceCount; i ++) {
+ FDE_LPTEXTEDITPIECE piece = m_PieceMassArr.GetPtrAt(i);
+ if (!bInRange) {
+ if (nStart >= piece->nStart && nStart < (piece->nStart + piece->nCount)) {
+ FX_INT32 nRangeEnd = piece->nCount - 1;
+ FX_BOOL bEnd = FALSE;
+ if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) {
+ nRangeEnd = nEnd - piece->nStart;
+ bEnd = TRUE;
+ }
+ CFX_RectFArray rcArr;
+ m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr);
+ FX_INT32 nSize = rcArr.GetSize();
+ CFX_RectF rectPiece = rcArr[nStart - piece->nStart];
+ rectPiece.Union(rcArr[nRangeEnd]);
+ RectFArr.Add(rectPiece);
+ if (bEnd) {
+ return;
+ }
+ bInRange = TRUE;
+ }
+ } else {
+ if (nEnd >= piece->nStart && nEnd < (piece->nStart + piece->nCount)) {
+ CFX_RectFArray rcArr;
+ m_pTextSet->GetCharRects((FDE_HVISUALOBJ)piece, rcArr);
+ CFX_RectF rectPiece = rcArr[0];
+ rectPiece.Union(rcArr[nEnd - piece->nStart]);
+ RectFArr.Add(rectPiece);
+ return;
+ }
+ RectFArr.Add(piece->rtPiece);
+ }
+ }
+ return;
+}
+FX_INT32 CFDE_TxtEdtPage::SelectWord(const CFX_PointF &fPoint, FX_INT32 &nCount)
+{
+ if (m_nRefCount < 0) {
+ return - 1;
+ }
+ IFDE_TxtEdtBuf * pBuf = m_pEditEngine->GetTextBuf();
+ FX_BOOL bBefore;
+ FX_INT32 nIndex = GetCharIndex(fPoint, bBefore);
+ if (nIndex == m_pEditEngine->GetTextBufLength()) {
+ nIndex = m_pEditEngine->GetTextBufLength() - 1;
+ }
+ if (nIndex < 0) {
+ return -1;
+ }
+ IFX_WordBreak * pIter = FX_WordBreak_Create();
+ pIter->Attach(FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf));
+ pIter->SetAt(nIndex);
+ nCount = pIter->GetWordLength();
+ FX_INT32 nRet = pIter->GetWordPos();
+ pIter->Release();
+ return nRet;
+}
+FX_BOOL CFDE_TxtEdtPage::IsLoaded(FX_LPCRECTF pClipBox )
+{
+ return m_bLoaded;
+}
+FX_INT32 CFDE_TxtEdtPage::LoadPage(FX_LPCRECTF pClipBox , IFX_Pause *pPause )
+{
+ if (m_nRefCount > 0) {
+ m_nRefCount ++;
+ return m_nRefCount;
+ }
+ IFDE_TxtEdtBuf * pBuf = m_pEditEngine->GetTextBuf();
+ const FDE_TXTEDTPARAMS * pParams = m_pEditEngine->GetEditParams();
+ if (m_pIter != NULL) {
+ m_pIter->Release();
+ }
+ FX_WCHAR wcAlias = 0;
+ if (pParams->dwMode & FDE_TEXTEDITMODE_Password) {
+ wcAlias = m_pEditEngine->GetAliasChar();
+ }
+ m_pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pBuf, wcAlias);
+ IFX_TxtBreak * pBreak = m_pEditEngine->GetTextBreak();
+ pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ pBreak->ClearBreakPieces();
+ FX_INT32 nLineCount = m_pEditEngine->GetLineCount();
+ FX_INT32 nPageLineCount = m_pEditEngine->GetPageLineCount();
+ FX_INT32 nLength = pBuf->GetTextLength();
+ FX_INT32 nStartLine = nPageLineCount * m_nPageIndex;
+ FX_INT32 nEndLine = FX_MIN((nStartLine + nPageLineCount - 1), (m_pEditEngine->GetLineCount() - 1));
+ FX_INT32 nPageStart, nPageEnd, nTemp, nBgnParag, nStartLineInParag, nEndParag, nEndLineInParag;
+ nBgnParag = m_pEditEngine->Line2Parag(0, 0, nStartLine, nStartLineInParag);
+ m_pBgnParag = (CFDE_TxtEdtParag*)m_pEditEngine->GetParag(nBgnParag);
+ m_pBgnParag->LoadParag();
+ m_pBgnParag->GetLineRange(nStartLine - nStartLineInParag, nPageStart, nTemp);
+ nEndParag = m_pEditEngine->Line2Parag(nBgnParag, nStartLineInParag, nEndLine, nEndLineInParag);
+ m_pEndParag = (CFDE_TxtEdtParag*)m_pEditEngine->GetParag(nEndParag);
+ m_pEndParag->LoadParag();
+ m_pEndParag->GetLineRange(nEndLine - nEndLineInParag, nPageEnd, nTemp);
+ nPageEnd += (nTemp - 1);
+ FX_BOOL bVertial = pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical;
+ FX_BOOL bLineReserve = pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
+ FX_FLOAT fLineStart = bVertial ? (bLineReserve ? (pParams->fPlateWidth - pParams->fLineSpace) : 0.0f) : 0.0f;
+ FX_FLOAT fLineStep = (bVertial && bLineReserve) ? (-pParams->fLineSpace) : pParams->fLineSpace;
+ FX_FLOAT fLinePos = fLineStart;
+ if (m_pTextSet == NULL) {
+ m_pTextSet = FX_NEW CFDE_TxtEdtTextSet(this);
+ }
+ m_PieceMassArr.RemoveAll(TRUE);
+ FX_DWORD dwBreakStatus = FX_TXTBREAK_None;
+ FX_INT32 nLineStart = nPageStart;
+ FX_INT32 nPieceStart = 0;
+ if (m_pCharWidth != NULL) {
+ delete [] m_pCharWidth;
+ }
+ m_pCharWidth = new FX_INT32[nPageEnd - nPageStart + 1];
+ pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ pBreak->ClearBreakPieces();
+ m_nPageStart = nPageStart;
+ m_nCharCount = nPageEnd - nPageStart + 1;
+ FX_BOOL bReload = FALSE;
+ FX_FLOAT fDefCharWidth = 0;
+ IFX_CharIter * pIter = m_pIter->Clone();
+ pIter->SetAt(nPageStart);
+ m_pIter->SetAt(nPageStart);
+ FX_INT32 nTextEnd = m_pEditEngine->GetTextBufLength();
+ FX_BOOL bFirstPiece = TRUE;
+ do {
+ if (bReload) {
+ dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ } else {
+ FX_WCHAR wAppend = pIter->GetChar();
+ dwBreakStatus = pBreak->AppendChar(wAppend);
+ }
+ if (pIter->GetAt() == nPageEnd && dwBreakStatus < FX_TXTBREAK_LineBreak) {
+ dwBreakStatus = pBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ }
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ FX_INT32 nPieceCount = pBreak->CountBreakPieces();
+ for (FX_INT32 j = 0; j < nPieceCount; j ++) {
+ const CFX_TxtPiece * pPiece = pBreak->GetBreakPiece(j);
+ FDE_TEXTEDITPIECE TxtEdtPiece;
+ FXSYS_memset(&TxtEdtPiece, 0, sizeof(FDE_TEXTEDITPIECE));
+ TxtEdtPiece.nBidiLevel = pPiece->m_iBidiLevel;
+ TxtEdtPiece.nCount = pPiece->GetLength();
+ TxtEdtPiece.nStart = nPieceStart;
+ TxtEdtPiece.dwCharStyles = pPiece->m_dwCharStyles;
+ if (FX_IsOdd(pPiece->m_iBidiLevel)) {
+ TxtEdtPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;
+ }
+ FX_FLOAT fParaBreakWidth = 0.0f;
+ if (pPiece->m_dwStatus > FX_TXTBREAK_PieceBreak) {
+ FX_WCHAR wRtChar = pParams->wLineBreakChar;
+ if (TxtEdtPiece.nCount >= 2) {
+ FX_WCHAR wChar = pBuf->GetCharByIndex(m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
+ FX_WCHAR wCharPre = pBuf->GetCharByIndex(m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 2);
+ if (wChar == wRtChar) {
+ fParaBreakWidth += fDefCharWidth;
+ }
+ if (wCharPre == wRtChar) {
+ fParaBreakWidth += fDefCharWidth;
+ }
+ } else if (TxtEdtPiece.nCount >= 1) {
+ FX_WCHAR wChar = pBuf->GetCharByIndex(m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
+ if (wChar == wRtChar) {
+ fParaBreakWidth += fDefCharWidth;
+ }
+ }
+ }
+ if (pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
+ TxtEdtPiece.rtPiece.left = fLinePos;
+ TxtEdtPiece.rtPiece.top = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
+ TxtEdtPiece.rtPiece.width = pParams->fLineSpace;
+ TxtEdtPiece.rtPiece.height = (FX_FLOAT)pPiece->m_iWidth / 20000.0f + fParaBreakWidth;
+ } else {
+ TxtEdtPiece.rtPiece.left = (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
+ TxtEdtPiece.rtPiece.top = fLinePos;
+ TxtEdtPiece.rtPiece.width = (FX_FLOAT)pPiece->m_iWidth / 20000.0f + fParaBreakWidth;
+ TxtEdtPiece.rtPiece.height = pParams->fLineSpace;
+ }
+ if (bFirstPiece) {
+ m_rtPageContents = TxtEdtPiece.rtPiece;
+ bFirstPiece = FALSE;
+ } else {
+ m_rtPageContents.Union(TxtEdtPiece.rtPiece);
+ }
+ nPieceStart += TxtEdtPiece.nCount;
+ m_PieceMassArr.Add(TxtEdtPiece);
+ for (FX_INT32 k = 0; k < TxtEdtPiece.nCount; k ++) {
+ CFX_Char* ptc = pPiece->GetCharPtr(k);
+ m_pCharWidth[TxtEdtPiece.nStart + k] = ptc->m_iCharWidth;
+ }
+ }
+ fLinePos += fLineStep;
+ pBreak->ClearBreakPieces();
+ }
+ if (pIter->GetAt() == nPageEnd && dwBreakStatus == FX_TXTBREAK_LineBreak) {
+ bReload = TRUE;
+ pIter->Next(TRUE);
+ }
+ } while (pIter->Next(FALSE) && (pIter->GetAt() <= nPageEnd));
+ if (m_rtPageContents.left != 0) {
+ FX_FLOAT fDelta = 0.0f;
+ if (m_rtPageContents.width < pParams->fPlateWidth) {
+ if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Right) {
+ fDelta = pParams->fPlateWidth - m_rtPageContents.width;
+ } else if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Center) {
+ if ((pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) && m_nCharCount > 1) {
+ FX_INT32 nCount = m_nCharCount - 1;
+ FX_INT32 n = (m_pEditEngine->m_nLimit - nCount) / 2;
+ fDelta = (m_rtPageContents.width / nCount) * n;
+ } else {
+ fDelta = (pParams->fPlateWidth - m_rtPageContents.width) / 2;
+ }
+ }
+ }
+ FX_FLOAT fOffset = m_rtPageContents.left - fDelta;
+ FX_INT32 nCount = m_PieceMassArr.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FDE_LPTEXTEDITPIECE pPiece = m_PieceMassArr.GetPtrAt(i);
+ pPiece->rtPiece.Offset(-fOffset, 0.0f);
+ }
+ m_rtPageContents.Offset(-fOffset, 0.0f);
+ }
+ if (m_pEditEngine->GetEditParams()->dwLayoutStyles & FDE_TEXTEDITLAYOUT_LastLineHeight) {
+ m_rtPageContents.height -= pParams->fLineSpace - pParams->fFontSize;
+ FX_INT32 nCount = m_PieceMassArr.GetSize();
+ FDE_LPTEXTEDITPIECE pPiece = m_PieceMassArr.GetPtrAt(nCount - 1);
+ pPiece->rtPiece.height = pParams->fFontSize;
+ }
+ pIter->Release();
+ m_nRefCount = 1;
+ m_bLoaded = TRUE;
+ return 0;
+}
+void CFDE_TxtEdtPage::UnloadPage(FX_LPCRECTF pClipBox )
+{
+ FXSYS_assert(m_nRefCount > 0);
+ m_nRefCount --;
+ if (m_nRefCount == 0) {
+ m_PieceMassArr.RemoveAll();
+ if (m_pTextSet) {
+ delete m_pTextSet;
+ m_pTextSet = NULL;
+ }
+ if (m_pCharWidth) {
+ delete [] m_pCharWidth;
+ m_pCharWidth = NULL;
+ }
+ if (m_pBgnParag) {
+ m_pBgnParag->UnloadParag();
+ }
+ if (m_pEndParag) {
+ m_pEndParag->UnloadParag();
+ }
+ if (m_pIter) {
+ m_pIter->Release();
+ m_pIter = NULL;
+ }
+ m_pBgnParag = NULL;
+ m_pEndParag = NULL;
+ }
+ return;
+}
+const CFX_RectF& CFDE_TxtEdtPage::GetContentsBox()
+{
+ return m_rtPageContents;
+}
+FX_POSITION CFDE_TxtEdtPage::GetFirstPosition(FDE_HVISUALOBJ hCanvas)
+{
+ if (m_PieceMassArr.GetSize() < 1) {
+ return NULL;
+ }
+ return (FX_POSITION)1;
+}
+FDE_HVISUALOBJ CFDE_TxtEdtPage::GetNext(FDE_HVISUALOBJ hCanvas, FX_POSITION &pos, IFDE_VisualSet *&pVisualSet)
+{
+ if (m_pTextSet == NULL) {
+ pos = NULL;
+ return NULL;
+ }
+ FX_INT32 nPos = (FX_INT32)(FX_UINTPTR)pos;
+ pVisualSet = m_pTextSet;
+ if (nPos + 1 > m_PieceMassArr.GetSize()) {
+ pos = NULL;
+ } else {
+ pos = (FX_POSITION)(FX_UINTPTR)(nPos + 1);
+ }
+ return (FDE_HVISUALOBJ)(m_PieceMassArr.GetPtrAt(nPos - 1));
+}
+FDE_HVISUALOBJ CFDE_TxtEdtPage::GetParentCanvas(FDE_HVISUALOBJ hCanvas, IFDE_VisualSet *&pVisualSet)
+{
+ return NULL;
+}
+FX_WCHAR CFDE_TxtEdtPage::GetChar(FX_LPVOID pIdentity, FX_INT32 index) const
+{
+ FX_INT32 nIndex = m_nPageStart + ((FDE_LPTEXTEDITPIECE)pIdentity)->nStart + index;
+ if (nIndex != m_pIter->GetAt()) {
+ m_pIter->SetAt(nIndex);
+ }
+ FX_WCHAR wChar = m_pIter->GetChar();
+ m_pIter->Next();
+ return wChar;
+}
+FX_INT32 CFDE_TxtEdtPage::GetWidth(FX_LPVOID pIdentity, FX_INT32 index) const
+{
+ FX_INT32 nWidth = m_pCharWidth[((FDE_LPTEXTEDITPIECE)pIdentity)->nStart + index];
+ return nWidth;
+}
+void CFDE_TxtEdtPage::NormalizePt2Rect(CFX_PointF &ptF, const CFX_RectF &rtF, FX_FLOAT fTolerance) const
+{
+ if (rtF.Contains(ptF.x, ptF.y)) {
+ return;
+ }
+ if (ptF.x < rtF.left) {
+ ptF.x = rtF.left;
+ } else if (ptF.x >= rtF.right()) {
+ ptF.x = rtF.right() - fTolerance;
+ }
+ if (ptF.y < rtF.top) {
+ ptF.y = rtF.top;
+ } else if (ptF.y >= rtF.bottom()) {
+ ptF.y = rtF.bottom() - fTolerance;
+ }
+}
diff --git a/xfa/src/fee/src/fee/fde_txtedtpage.h b/xfa/src/fee/src/fee/fde_txtedtpage.h
new file mode 100644
index 0000000000..36021b66aa
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtpage.h
@@ -0,0 +1,130 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TXTEDTPAGE_H
+#define _FDE_TXTEDTPAGE_H
+class CFDE_TxtEdtEngine;
+class IFX_CharIter;
+class CFDE_TxtEdtPage;
+class CFDE_TxtEdtLineExt;
+class CFDE_TxtEdtTextSet;
+class CFDE_TxtEdtParag;
+enum FDE_TXTEDT_CHARTYPE {
+ FDE_TXTEDT_CHARTYPE_Unknown = 0 ,
+ FDE_TXTEDT_CHARTYPE_Tab ,
+ FDE_TXTEDT_CHARTYPE_Space ,
+ FDE_TXTEDT_CHARTYPE_Punctuation ,
+ FDE_TXTEDT_CHARTYPE_LineBreak ,
+ FDE_TXTEDT_CHARTYPE_Number ,
+ FDE_TXTEDT_CHARTYPE_Char ,
+ FDE_TXTEDT_CHARTYPE_CJK ,
+};
+static FDE_TXTEDT_CHARTYPE FDE_GetEditSelCharType(FX_WCHAR wChar)
+{
+ if (wChar == 0x9) {
+ return FDE_TXTEDT_CHARTYPE_Tab;
+ } else if (wChar == 0x20 || wChar == 0xA0) {
+ return FDE_TXTEDT_CHARTYPE_Space;
+ } else if (wChar == 0x9 || wChar == 0x20 || wChar == 0xA0 || (wChar >= L'!' && wChar <= L'/') || (wChar >= L':' && wChar <= L'@') || (wChar >= L'[' && wChar <= L'^') ||
+ (wChar >= L'{' && wChar <= L'~') || wChar == 0x60) {
+ return FDE_TXTEDT_CHARTYPE_Punctuation;
+ } else if (wChar == 0x0a || wChar == 0x0d) {
+ return FDE_TXTEDT_CHARTYPE_LineBreak;
+ } else if (wChar >= '0' && wChar <= '9') {
+ return FDE_TXTEDT_CHARTYPE_Number;
+ } else if ((wChar >= 0x2e80 && wChar <= 0x2eff) || (wChar >= 0x3000 && wChar <= 0x303f) || (wChar >= 0x31c0 && wChar <= 0x31ef)
+ || (wChar >= 0x3200 && wChar <= 0x32ff) || (wChar >= 0x3300 && wChar <= 0x33ff) || (wChar >= 0x3400 && wChar <= 0x4dbf)
+ || (wChar >= 0x4e00 && wChar <= 0x9fff) || (wChar >= 0xf900 && wChar <= 0xfaff) || (wChar >= 0xfe30 && wChar <= 0xfe4f)) {
+ return FDE_TXTEDT_CHARTYPE_CJK;
+ } else {
+ return FDE_TXTEDT_CHARTYPE_Char;
+ }
+}
+typedef struct _FDE_TXTEDTPIECE : public CFX_Object {
+ FX_INT32 nStart;
+ FX_INT32 nCount;
+ FX_INT32 nBidiLevel;
+ CFX_RectF rtPiece;
+ FX_DWORD dwCharStyles;
+} FDE_TEXTEDITPIECE, * FDE_LPTEXTEDITPIECE;
+typedef CFX_MassArrayTemplate<FDE_TEXTEDITPIECE> CFDE_TXTEDTPieceMassArray;
+class CFDE_TxtEdtTextSet : public IFDE_TextSet, public CFX_Object
+{
+public:
+ CFDE_TxtEdtTextSet(CFDE_TxtEdtPage * pPage);
+ ~CFDE_TxtEdtTextSet();
+
+ virtual FDE_VISUALOBJTYPE GetType();
+ virtual FX_BOOL GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF &bbox);
+ virtual FX_BOOL GetMatrix(FDE_HVISUALOBJ hVisualObj, CFX_Matrix &matrix);
+ virtual FX_BOOL GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt);
+ virtual FX_BOOL GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt);
+ virtual FX_INT32 GetString(FDE_HVISUALOBJ hText, CFX_WideString &wsText);
+ virtual IFX_Font* GetFont(FDE_HVISUALOBJ hText);
+ virtual FX_FLOAT GetFontSize(FDE_HVISUALOBJ hText);
+ virtual FX_ARGB GetFontColor(FDE_HVISUALOBJ hText);
+ virtual FX_INT32 GetDisplayPos(FDE_HVISUALOBJ hText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL);
+ virtual FX_INT32 GetCharRects(FDE_HVISUALOBJ hText, CFX_RectFArray &rtArray);
+ virtual FX_INT32 GetCharRects_Impl(FDE_HVISUALOBJ hText, CFX_RectFArray &rtArray, FX_BOOL bBBox = FALSE);
+private:
+
+ CFDE_TxtEdtPage * m_pPage;
+};
+class CFDE_TxtEdtPage : public CFX_Object, public IFDE_TxtEdtPage
+{
+public:
+ CFDE_TxtEdtPage(IFDE_TxtEdtEngine * pEngine, FX_INT32 nLineIndex);
+
+ virtual void Release();
+ virtual IFDE_TxtEdtEngine * GetEngine() const;
+
+ virtual FDE_VISUALOBJTYPE GetType();
+ virtual FX_BOOL GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF &bbox);
+ virtual FX_BOOL GetMatrix(FDE_HVISUALOBJ hVisualObj, CFX_Matrix &matrix);
+ virtual FX_BOOL GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt);
+ virtual FX_BOOL GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt);
+ virtual FX_INT32 GetCharRect(FX_INT32 nIndex, CFX_RectF &rect, FX_BOOL bBBox = FALSE) const;
+ virtual FX_INT32 GetCharIndex(const CFX_PointF &fPoint, FX_BOOL &bBefore);
+ virtual FX_INT32 SelectWord(const CFX_PointF &fPoint, FX_INT32 &nCount);
+ virtual FX_INT32 GetCharStart() const;
+ virtual FX_INT32 GetCharCount() const;
+ virtual void CalcRangeRectArray(FX_INT32 nStart, FX_INT32 nCount, CFX_RectFArray &RectFArr) const;
+ virtual FX_INT32 GetDisplayPos(const CFX_RectF &rtClip, FXTEXT_CHARPOS *&pCharPos, FX_LPRECTF pBBox) const;
+
+ virtual FX_BOOL IsLoaded(FX_LPCRECTF pClipBox = NULL);
+ virtual FX_INT32 LoadPage(FX_LPCRECTF pClipBox = NULL, IFX_Pause *pPause = NULL);
+ virtual void UnloadPage(FX_LPCRECTF pClipBox = NULL);
+
+ virtual const CFX_RectF& GetContentsBox();
+ virtual FX_POSITION GetFirstPosition(FDE_HVISUALOBJ hCanvas);
+ virtual FDE_HVISUALOBJ GetNext(FDE_HVISUALOBJ hCanvas, FX_POSITION &pos, IFDE_VisualSet *&pVisualSet);
+ virtual FDE_HVISUALOBJ GetParentCanvas(FDE_HVISUALOBJ hCanvas, IFDE_VisualSet *&pVisualSet);
+ virtual FX_WCHAR GetChar(FX_LPVOID pIdentity, FX_INT32 index) const;
+ virtual FX_INT32 GetWidth(FX_LPVOID pIdentity, FX_INT32 index) const;
+protected:
+ virtual ~CFDE_TxtEdtPage();
+private:
+ void NormalizePt2Rect(CFX_PointF &ptF, const CFX_RectF &rtF, FX_FLOAT fTolerance) const;
+ IFX_CharIter *m_pIter;
+ CFDE_TxtEdtTextSet *m_pTextSet;
+ CFDE_TxtEdtEngine *m_pEditEngine;
+ CFDE_TXTEDTPieceMassArray m_PieceMassArr;
+ CFDE_TxtEdtParag * m_pBgnParag;
+ CFDE_TxtEdtParag * m_pEndParag;
+
+ FX_INT32 m_nRefCount;
+ FX_INT32 m_nPageStart;
+ FX_INT32 m_nCharCount;
+ FX_INT32 m_nPageIndex;
+ FX_BOOL m_bLoaded;
+ FX_BOOL m_bLastPage;
+ CFX_RectF m_rtPage;
+ CFX_RectF m_rtPageMargin;
+ CFX_RectF m_rtPageContents;
+ CFX_RectF m_rtPageCanvas;
+ FX_INT32* m_pCharWidth;
+};
+#endif
diff --git a/xfa/src/fee/src/fee/fde_txtedtparag.cpp b/xfa/src/fee/src/fee/fde_txtedtparag.cpp
new file mode 100644
index 0000000000..9887ddcd3c
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtparag.cpp
@@ -0,0 +1,149 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../../include/ifde_txtedtbuf.h"
+#include "../../include/ifde_txtedtengine.h"
+#include "../../include/fx_wordbreak.h"
+#include "fde_txtedtparag.h"
+#include "fde_txtedtengine.h"
+#include "fde_txtedtbuf.h"
+CFDE_TxtEdtParag::CFDE_TxtEdtParag(CFDE_TxtEdtEngine * pEngine)
+ : m_nLineCount(0)
+ , m_nCharStart(0)
+ , m_nCharCount(0)
+ , m_lpData(NULL)
+ , m_pEngine(pEngine)
+{
+ FXSYS_assert(m_pEngine);
+}
+CFDE_TxtEdtParag::~CFDE_TxtEdtParag()
+{
+ if (m_lpData != NULL) {
+ FX_Free(m_lpData);
+ }
+}
+void CFDE_TxtEdtParag::LoadParag()
+{
+ if (m_lpData != NULL) {
+ ((FX_INT32*)m_lpData)[0]++;
+ return;
+ }
+ IFX_TxtBreak * pTxtBreak = m_pEngine->GetTextBreak();
+ IFDE_TxtEdtBuf * pTxtBuf = m_pEngine->GetTextBuf();
+ const FDE_TXTEDTPARAMS *pParam = m_pEngine->GetEditParams();
+ FX_WCHAR wcAlias = 0;
+ if (pParam->dwMode & FDE_TEXTEDITMODE_Password) {
+ wcAlias = m_pEngine->GetAliasChar();
+ }
+ IFX_CharIter * pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pTxtBuf, wcAlias);
+ pIter->SetAt(m_nCharStart);
+ FX_INT32 nEndIndex = m_nCharStart + m_nCharCount;
+ CFX_ArrayTemplate<FX_INT32> LineBaseArr;
+ FX_BOOL bReload = FALSE;
+ FX_DWORD dwBreakStatus = FX_TXTBREAK_None;
+ FX_INT32 nTextEnd = m_pEngine->GetTextBufLength();
+ do {
+ if (bReload) {
+ dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ } else {
+ FX_WCHAR wAppend = pIter->GetChar();
+ dwBreakStatus = pTxtBreak->AppendChar(wAppend);
+ }
+ if (pIter->GetAt() + 1 == nEndIndex && dwBreakStatus < FX_TXTBREAK_LineBreak) {
+ dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ }
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ FX_INT32 nCount = pTxtBreak->CountBreakPieces();
+ FX_INT32 nTotal = 0;
+ for (FX_INT32 j = 0; j < nCount; j ++) {
+ const CFX_TxtPiece * Piece = pTxtBreak->GetBreakPiece(j);
+ nTotal += Piece->GetLength();
+ }
+ LineBaseArr.Add(nTotal);
+ pTxtBreak->ClearBreakPieces();
+ }
+ if ((pIter->GetAt() + 1 == nEndIndex) && (dwBreakStatus == FX_TXTBREAK_LineBreak)) {
+ bReload = TRUE;
+ pIter->Next(TRUE);
+ }
+ } while (pIter->Next(FALSE) && (pIter->GetAt() < nEndIndex));
+ pIter->Release();
+ pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ pTxtBreak->ClearBreakPieces();
+ FX_INT32 nLineCount = LineBaseArr.GetSize();
+ m_nLineCount = nLineCount;
+ if (m_lpData == NULL) {
+ m_lpData = FX_Alloc(FX_INT32, nLineCount + 1);
+ } else {
+ m_lpData = FX_Realloc(FX_INT32, m_lpData, (nLineCount + 1));
+ }
+ FX_INT32 * pIntArr = (FX_INT32*)m_lpData;
+ pIntArr[0] = 1;
+ m_nLineCount = nLineCount;
+ pIntArr ++;
+ for (FX_INT32 j = 0; j < nLineCount; j ++, pIntArr ++) {
+ *pIntArr = LineBaseArr[j];
+ }
+ LineBaseArr.RemoveAll();
+}
+void CFDE_TxtEdtParag::UnloadParag()
+{
+ FXSYS_assert(m_lpData != NULL);
+ ((FX_INT32*)m_lpData)[0]--;
+ FXSYS_assert(((FX_INT32*)m_lpData)[0] >= 0);
+ if (((FX_INT32*)m_lpData)[0] == 0) {
+ FX_Free(m_lpData);
+ m_lpData = NULL;
+ }
+}
+void CFDE_TxtEdtParag::CalcLines()
+{
+ IFX_TxtBreak * pTxtBreak = m_pEngine->GetTextBreak();
+ IFDE_TxtEdtBuf * pTxtBuf = m_pEngine->GetTextBuf();
+ IFX_CharIter * pIter = FX_NEW CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)pTxtBuf);
+ FX_INT32 nCount = 0;
+ FX_DWORD dwBreakStatus = FX_TXTBREAK_None;
+ FX_INT32 nEndIndex = m_nCharStart + m_nCharCount;
+ pIter->SetAt(m_nCharStart);
+ FX_BOOL bReload = FALSE;
+ FX_INT32 nTextEnd = m_pEngine->GetTextBufLength();
+ do {
+ if (bReload) {
+ dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ } else {
+ FX_WCHAR wAppend = pIter->GetChar();
+ dwBreakStatus = pTxtBreak->AppendChar(wAppend);
+ }
+ if (pIter->GetAt() + 1 == nEndIndex && dwBreakStatus < FX_TXTBREAK_LineBreak) {
+ dwBreakStatus = pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ }
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ nCount ++;
+ pTxtBreak->ClearBreakPieces();
+ }
+ if ((pIter->GetAt() + 1 == nEndIndex) && (dwBreakStatus == FX_TXTBREAK_LineBreak)) {
+ bReload = TRUE;
+ pIter->Next(TRUE);
+ }
+ } while (pIter->Next(FALSE) && (pIter->GetAt() < nEndIndex));
+ pIter->Release();
+ pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ pTxtBreak->ClearBreakPieces();
+ m_nLineCount = nCount;
+}
+void CFDE_TxtEdtParag::GetLineRange(FX_INT32 nLineIndex, FX_INT32& nStart, FX_INT32& nCount) const
+{
+ FX_INT32 * pLineBaseArr = (FX_INT32*)m_lpData;
+ FXSYS_assert(nLineIndex < m_nLineCount);
+ nStart = m_nCharStart;
+ pLineBaseArr ++;
+ for (FX_INT32 i = 0; i < nLineIndex; i ++) {
+ nStart += *pLineBaseArr;
+ pLineBaseArr ++;
+ }
+ nCount = *pLineBaseArr;
+}
diff --git a/xfa/src/fee/src/fee/fde_txtedtparag.h b/xfa/src/fee/src/fee/fde_txtedtparag.h
new file mode 100644
index 0000000000..72584feca8
--- /dev/null
+++ b/xfa/src/fee/src/fee/fde_txtedtparag.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TXTEDTPARAG_H
+#define _FDE_TXTEDTPARAG_H
+class CFDE_TxtEdtEngine;
+class CFDE_TxtEdtParag;
+class CFDE_TxtEdtParag : public IFDE_TxtEdtParag, public CFX_Object
+{
+public:
+ CFDE_TxtEdtParag(CFDE_TxtEdtEngine * pEngine);
+ ~CFDE_TxtEdtParag();
+ virtual FX_INT32 GetTextLength() const
+ {
+ return m_nCharCount;
+ }
+ virtual FX_INT32 GetStartIndex() const
+ {
+ return m_nCharStart;
+ }
+ virtual FX_INT32 CountLines() const
+ {
+ return m_nLineCount;
+ }
+ virtual void GetLineRange(FX_INT32 nLineIndex, FX_INT32& nStart, FX_INT32& nCount) const;
+ void LoadParag();
+ void UnloadParag();
+ void CalcLines();
+ FX_INT32 m_nCharStart;
+ FX_INT32 m_nCharCount;
+ FX_INT32 m_nLineCount;
+private:
+ FX_LPVOID m_lpData;
+ CFDE_TxtEdtEngine* m_pEngine;
+};
+#endif
diff --git a/xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.cpp b/xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.cpp
new file mode 100644
index 0000000000..4847af9ed3
--- /dev/null
+++ b/xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.cpp
@@ -0,0 +1,263 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fx_wordbreak_impl.h"
+#define FX_IsOdd(a) ((a) & 1)
+FX_WordBreakProp FX_GetWordBreakProperty(FX_WCHAR wcCodePoint)
+{
+ FX_DWORD dwProperty = (FX_DWORD)gs_FX_WordBreak_CodePointProperties[wcCodePoint >> 1];
+ return (FX_WordBreakProp)(FX_IsOdd(wcCodePoint) ? (dwProperty & 0x0F) : (dwProperty >> 4));
+}
+CFX_CharIter::CFX_CharIter(const CFX_WideString & wsText)
+ : m_wsText(wsText)
+ , m_nIndex(0)
+{
+ FXSYS_assert(!wsText.IsEmpty());
+}
+CFX_CharIter::~CFX_CharIter()
+{
+}
+void CFX_CharIter::Release()
+{
+ delete this;
+}
+FX_BOOL CFX_CharIter::Next(FX_BOOL bPrev )
+{
+ if (bPrev) {
+ if (m_nIndex <= 0) {
+ return FALSE;
+ }
+ m_nIndex --;
+ } else {
+ if (m_nIndex + 1 >= m_wsText.GetLength()) {
+ return FALSE;
+ }
+ m_nIndex ++;
+ }
+ return TRUE;
+}
+FX_WCHAR CFX_CharIter::GetChar()
+{
+ return m_wsText.GetAt(m_nIndex);
+}
+void CFX_CharIter::SetAt(FX_INT32 nIndex)
+{
+ if (nIndex < 0 || nIndex >= m_wsText.GetLength()) {
+ return;
+ }
+ m_nIndex = nIndex;
+}
+FX_INT32 CFX_CharIter::GetAt() const
+{
+ return m_nIndex;
+}
+FX_BOOL CFX_CharIter::IsEOF(FX_BOOL bTail ) const
+{
+ return bTail ? (m_nIndex + 1 == m_wsText.GetLength()) : (m_nIndex == 0);
+}
+IFX_CharIter * CFX_CharIter::Clone()
+{
+ CFX_CharIter * pIter = new CFX_CharIter(m_wsText);
+ pIter->m_nIndex = m_nIndex;
+ return pIter;
+}
+CFX_WordBreak::CFX_WordBreak()
+ : m_pPreIter(NULL)
+ , m_pCurIter(NULL)
+{
+}
+CFX_WordBreak::~CFX_WordBreak()
+{
+ if (m_pPreIter) {
+ m_pPreIter->Release();
+ m_pPreIter = NULL;
+ }
+ if (m_pCurIter) {
+ m_pCurIter->Release();
+ m_pCurIter = NULL;
+ }
+}
+void CFX_WordBreak::Release()
+{
+ delete this;
+}
+void CFX_WordBreak::Attach(IFX_CharIter * pIter)
+{
+ FXSYS_assert(pIter);
+ m_pCurIter = pIter;
+}
+void CFX_WordBreak::Attach(const CFX_WideString &wsText)
+{
+ m_pCurIter = new CFX_CharIter(wsText);
+}
+FX_BOOL CFX_WordBreak::Next(FX_BOOL bPrev)
+{
+ IFX_CharIter * pIter = bPrev ? m_pPreIter->Clone() : m_pCurIter->Clone();
+ if (pIter->IsEOF(!bPrev)) {
+ return FALSE;
+ }
+ pIter->Next(bPrev);
+ if (!FindNextBreakPos(pIter, bPrev, TRUE)) {
+ pIter->Release();
+ return FALSE;
+ }
+ if (bPrev) {
+ m_pCurIter->Release();
+ m_pCurIter = m_pPreIter;
+ m_pCurIter->Next(TRUE);
+ m_pPreIter = pIter;
+ } else {
+ m_pPreIter->Release();
+ m_pPreIter = m_pCurIter;
+ m_pPreIter->Next();
+ m_pCurIter = pIter;
+ }
+ return TRUE;
+}
+void CFX_WordBreak::SetAt(FX_INT32 nIndex)
+{
+ if (m_pPreIter) {
+ m_pPreIter->Release();
+ m_pPreIter = NULL;
+ }
+ m_pCurIter->SetAt(nIndex);
+ FindNextBreakPos(m_pCurIter, TRUE, FALSE);
+ m_pPreIter = m_pCurIter;
+ m_pCurIter = m_pPreIter->Clone();
+ FindNextBreakPos(m_pCurIter, FALSE, FALSE);
+}
+FX_INT32 CFX_WordBreak::GetWordPos() const
+{
+ return m_pPreIter->GetAt();
+}
+FX_INT32 CFX_WordBreak::GetWordLength() const
+{
+ return m_pCurIter->GetAt() - m_pPreIter->GetAt() + 1;
+}
+void CFX_WordBreak::GetWord(CFX_WideString &wsWord) const
+{
+ FX_INT32 nWordLength = GetWordLength();
+ if (nWordLength <= 0) {
+ return;
+ }
+ FX_LPWSTR lpBuf = wsWord.GetBuffer(nWordLength);
+ IFX_CharIter * pTempIter = m_pPreIter->Clone();
+ FX_INT32 i = 0;
+ while (pTempIter->GetAt() <= m_pCurIter->GetAt()) {
+ lpBuf[i++] = pTempIter->GetChar();
+ FX_BOOL bEnd = pTempIter->Next();
+ if (!bEnd) {
+ break;
+ }
+ }
+ pTempIter->Release();
+ wsWord.ReleaseBuffer(nWordLength);
+}
+FX_BOOL CFX_WordBreak::IsEOF(FX_BOOL bTail) const
+{
+ return m_pCurIter->IsEOF(bTail);
+}
+FX_BOOL CFX_WordBreak::FindNextBreakPos(IFX_CharIter * pIter, FX_BOOL bPrev,
+ FX_BOOL bFromNext )
+{
+ FX_WordBreakProp ePreType = FX_WordBreakProp_None;
+ FX_WordBreakProp eCurType = FX_WordBreakProp_None;
+ FX_WordBreakProp eNextType = FX_WordBreakProp_None;
+ if (pIter->IsEOF(!bPrev)) {
+ return TRUE;
+ }
+ if (!(bFromNext || pIter->IsEOF(bPrev))) {
+ pIter->Next(!bPrev);
+ FX_WCHAR wcTemp = pIter->GetChar();
+ ePreType = FX_GetWordBreakProperty(wcTemp);
+ pIter->Next(bPrev);
+ }
+ FX_WCHAR wcTemp = pIter->GetChar();
+ eCurType = FX_GetWordBreakProperty(wcTemp);
+ FX_BOOL bFirst = TRUE;
+ do {
+ pIter->Next(bPrev);
+ FX_WCHAR wcTemp = pIter->GetChar();
+ eNextType = FX_GetWordBreakProperty(wcTemp);
+ FX_WORD wBreak = gs_FX_WordBreak_Table[eCurType] & ((FX_WORD)(1 << eNextType));
+ if (wBreak) {
+ if (pIter->IsEOF(!bPrev)) {
+ pIter->Next(!bPrev);
+ return TRUE;
+ }
+ if (bFirst) {
+ FX_INT32 nFlags = 0;
+ if (eCurType == FX_WordBreakProp_MidLetter) {
+ if (eNextType == FX_WordBreakProp_ALetter) {
+ nFlags = 1;
+ }
+ } else if (eCurType == FX_WordBreakProp_MidNum) {
+ if (eNextType == FX_WordBreakProp_Numberic) {
+ nFlags = 2;
+ }
+ } else if (eCurType == FX_WordBreakProp_MidNumLet) {
+ if (eNextType == FX_WordBreakProp_ALetter) {
+ nFlags = 1;
+ } else if (eNextType == FX_WordBreakProp_Numberic) {
+ nFlags = 2;
+ }
+ }
+ if (nFlags > 0) {
+ FXSYS_assert(nFlags <= 2);
+ if (!((nFlags == 1 && ePreType == FX_WordBreakProp_ALetter) ||
+ (nFlags == 2 && ePreType == FX_WordBreakProp_Numberic))) {
+ pIter->Next(!bPrev);
+ return TRUE;
+ }
+ pIter->Next(bPrev);
+ wBreak = FALSE;
+ }
+ bFirst = FALSE;
+ }
+ if (wBreak) {
+ FX_INT32 nFlags = 0;
+ if (eNextType == FX_WordBreakProp_MidLetter) {
+ if (eCurType == FX_WordBreakProp_ALetter) {
+ nFlags = 1;
+ }
+ } else if (eNextType == FX_WordBreakProp_MidNum) {
+ if (eCurType == FX_WordBreakProp_Numberic) {
+ nFlags = 2;
+ }
+ } else if (eNextType == FX_WordBreakProp_MidNumLet) {
+ if (eCurType == FX_WordBreakProp_ALetter) {
+ nFlags = 1;
+ } else if (eCurType == FX_WordBreakProp_Numberic) {
+ nFlags = 2;
+ }
+ }
+ if (nFlags <= 0) {
+ pIter->Next(!bPrev);
+ return TRUE;
+ }
+ FXSYS_assert(nFlags <= 2);
+ pIter->Next(bPrev);
+ wcTemp = pIter->GetChar();
+ eNextType = (FX_WordBreakProp)FX_GetWordBreakProperty(wcTemp);
+ if (!((nFlags == 1 && eNextType == FX_WordBreakProp_ALetter) ||
+ (nFlags == 2 && eNextType == FX_WordBreakProp_Numberic))) {
+ pIter->Next(!bPrev);
+ pIter->Next(!bPrev);
+ return TRUE;
+ }
+ }
+ }
+ ePreType = eCurType;
+ eCurType = eNextType;
+ bFirst = FALSE;
+ } while (!pIter->IsEOF(!bPrev));
+ return TRUE;
+}
+IFX_WordBreak * FX_WordBreak_Create()
+{
+ return new CFX_WordBreak;
+}
diff --git a/xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.h b/xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.h
new file mode 100644
index 0000000000..91895a54d7
--- /dev/null
+++ b/xfa/src/fee/src/fx_wordbreak/fx_wordbreak_impl.h
@@ -0,0 +1,64 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_WORDBREAK_IMPL_H
+#define _FX_WORDBREAK_IMPL_H
+extern const FX_WORD gs_FX_WordBreak_Table[16];
+extern const FX_BYTE gs_FX_WordBreak_CodePointProperties[(0xFFFF - 1) / 2 + 1];
+enum FX_WordBreakProp {
+ FX_WordBreakProp_None = 0 ,
+ FX_WordBreakProp_CR ,
+ FX_WordBreakProp_LF ,
+ FX_WordBreakProp_NewLine ,
+ FX_WordBreakProp_Extend ,
+ FX_WordBreakProp_Format ,
+ FX_WordBreakProp_KataKana ,
+ FX_WordBreakProp_ALetter ,
+ FX_WordBreakProp_MidLetter ,
+ FX_WordBreakProp_MidNum ,
+ FX_WordBreakProp_MidNumLet ,
+ FX_WordBreakProp_Numberic ,
+ FX_WordBreakProp_ExtendNumLet ,
+};
+FX_WordBreakProp FX_GetWordBreakProperty(FX_WCHAR wcCodePoint);
+class CFX_CharIter : public IFX_CharIter, public CFX_Object
+{
+public:
+ CFX_CharIter(const CFX_WideString & wsText);
+ virtual void Release();
+ virtual FX_BOOL Next(FX_BOOL bPrev = FALSE);
+ virtual FX_WCHAR GetChar();
+ virtual void SetAt(FX_INT32 nIndex);
+ virtual FX_INT32 GetAt() const;
+ virtual FX_BOOL IsEOF(FX_BOOL bTail = TRUE) const;
+ virtual IFX_CharIter * Clone();
+protected:
+ ~CFX_CharIter();
+private:
+ const CFX_WideString &m_wsText;
+ FX_INT32 m_nIndex;
+};
+class CFX_WordBreak : public IFX_WordBreak, public CFX_Object
+{
+public:
+ CFX_WordBreak();
+ virtual void Release();
+ virtual void Attach(IFX_CharIter * pIter);
+ virtual void Attach(const CFX_WideString &wsText);
+ virtual FX_BOOL Next(FX_BOOL bPrev);
+ virtual void SetAt(FX_INT32 nIndex);
+ virtual FX_INT32 GetWordPos() const;
+ virtual FX_INT32 GetWordLength() const;
+ virtual void GetWord(CFX_WideString &wsWord) const;
+ virtual FX_BOOL IsEOF(FX_BOOL bTail ) const;
+protected:
+ ~CFX_WordBreak();
+ FX_BOOL FindNextBreakPos(IFX_CharIter * pIter, FX_BOOL bPrev, FX_BOOL bFromNext = TRUE);
+private:
+ IFX_CharIter * m_pPreIter;
+ IFX_CharIter * m_pCurIter;
+};
+#endif
diff --git a/xfa/src/fee/src/fx_wordbreak/fx_wordbreakdata.cpp b/xfa/src/fee/src/fx_wordbreak/fx_wordbreakdata.cpp
new file mode 100644
index 0000000000..23e30479f4
--- /dev/null
+++ b/xfa/src/fee/src/fx_wordbreak/fx_wordbreakdata.cpp
@@ -0,0 +1,2062 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fx_wordbreak_impl.h"
+extern const FX_WORD gs_FX_WordBreak_Table[16] = {
+ 0xFFFF, 0xFFF9, 0xFFFB, 0xFFFB, 0xFFFB, 0xFFFB, 0xEFBB, 0xE77B,
+ 0xFFFB, 0xFFFB, 0xFFFB, 0xE77B, 0xE73B, 0xFFFB, 0xFFFB, 0xFFFB,
+};
+extern const FX_BYTE gs_FX_WordBreak_CodePointProperties[(0xFFFF - 1) / 2 + 1] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x90, 0xA0, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x89, 0x00, 0x00,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x0C,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00,
+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x05, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x70, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x77, 0x77, 0x70, 0x77, 0x00, 0x77, 0x77, 0x90,
+ 0x00, 0x00, 0x00, 0x78, 0x77, 0x70, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x07, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x04, 0x44, 0x44, 0x44, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x07, 0x00, 0x00, 0x00,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x09, 0x00, 0x00, 0x00, 0x04, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x04,
+ 0x04, 0x40, 0x44, 0x04, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x77, 0x77, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, 0x00, 0x00,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x74, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x0B, 0x90, 0x77, 0x47, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x07, 0x44, 0x44, 0x44, 0x45, 0x44,
+ 0x44, 0x44, 0x47, 0x74, 0x40, 0x44, 0x44, 0x77, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x77, 0x70, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x74, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x44, 0x44, 0x44, 0x44, 0x44, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x74, 0x44, 0x44, 0x44, 0x44, 0x77, 0x00, 0x90, 0x70, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x44, 0x44, 0x74, 0x44, 0x44,
+ 0x44, 0x44, 0x74, 0x44, 0x74, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x44, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x47, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, 0x74, 0x44, 0x44, 0x00, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x07, 0x70, 0x00, 0x00, 0x07, 0x77, 0x77, 0x77,
+ 0x04, 0x44, 0x07, 0x77, 0x77, 0x77, 0x70, 0x07, 0x70, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x70, 0x00, 0x77, 0x77, 0x00, 0x47, 0x44,
+ 0x44, 0x44, 0x40, 0x04, 0x40, 0x04, 0x44, 0x70, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x77, 0x07,
+ 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x44, 0x07, 0x77, 0x77, 0x70, 0x00, 0x07, 0x70, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x77, 0x07, 0x70, 0x77, 0x00, 0x40, 0x44,
+ 0x44, 0x40, 0x00, 0x04, 0x40, 0x04, 0x44, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x77, 0x70, 0x70,
+ 0x00, 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x44, 0x77, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x44, 0x07, 0x77, 0x77, 0x77, 0x77, 0x07, 0x77, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x77, 0x07, 0x77, 0x77, 0x00, 0x47, 0x44,
+ 0x44, 0x44, 0x44, 0x04, 0x44, 0x04, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x44, 0x07, 0x77, 0x77, 0x77, 0x70, 0x07, 0x70, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x77, 0x07, 0x77, 0x77, 0x00, 0x47, 0x44,
+ 0x44, 0x44, 0x40, 0x04, 0x40, 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x77, 0x07,
+ 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x47, 0x07, 0x77, 0x77, 0x70, 0x00, 0x77, 0x70, 0x77, 0x77, 0x00, 0x07, 0x70, 0x70, 0x77,
+ 0x00, 0x07, 0x70, 0x00, 0x77, 0x70, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x44,
+ 0x44, 0x40, 0x00, 0x44, 0x40, 0x44, 0x44, 0x00, 0x70, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x44, 0x07, 0x77, 0x77, 0x77, 0x70, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x07, 0x77, 0x77, 0x00, 0x07, 0x44,
+ 0x44, 0x44, 0x40, 0x44, 0x40, 0x44, 0x44, 0x00, 0x00, 0x00, 0x04, 0x40, 0x77, 0x00, 0x00, 0x00,
+ 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x44, 0x07, 0x77, 0x77, 0x77, 0x70, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x07, 0x77, 0x77, 0x00, 0x47, 0x44,
+ 0x44, 0x44, 0x40, 0x44, 0x40, 0x44, 0x44, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x70,
+ 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x44, 0x07, 0x77, 0x77, 0x77, 0x70, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x07, 0x44,
+ 0x44, 0x44, 0x40, 0x44, 0x40, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77,
+ 0x00, 0x44, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x07, 0x77, 0x77, 0x77, 0x77, 0x07, 0x00,
+ 0x77, 0x77, 0x77, 0x70, 0x00, 0x40, 0x00, 0x04, 0x44, 0x44, 0x40, 0x40, 0x44, 0x44, 0x44, 0x44,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x44, 0x44, 0x44, 0x40, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x44, 0x44, 0x44, 0x40, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x44, 0x44, 0x44, 0x04, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x44,
+ 0x77, 0x77, 0x77, 0x77, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x04, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x40, 0x44, 0x77, 0x77, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x04, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x44,
+ 0x40, 0x44, 0x40, 0x04, 0x44, 0x44, 0x44, 0x00, 0x04, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x04, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x44, 0x44, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x70, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x70, 0x70, 0x77, 0x77, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x70,
+ 0x70, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x70, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x74, 0x70, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x40, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xB0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x74, 0x44, 0x44, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x44, 0x44, 0x44, 0x40,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, 0x04,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x44, 0x47, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x47, 0x77, 0x77, 0x77, 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x47, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x74, 0x44, 0x44, 0x44, 0x44, 0x40, 0x00, 0x77, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x07, 0x77, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x47, 0x77, 0x74, 0x77, 0x77, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x44,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x77, 0x07, 0x07, 0x07, 0x07,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x70,
+ 0x00, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x00, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x55, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xA0, 0x08, 0x33, 0x55, 0x55, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C,
+ 0xC0, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x55, 0x55, 0x50, 0x00, 0x00, 0x55, 0x55, 0x55, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x70, 0x00, 0x07, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x07, 0x00, 0x07, 0x77, 0x77, 0x00,
+ 0x00, 0x00, 0x70, 0x70, 0x70, 0x77, 0x77, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77,
+ 0x00, 0x00, 0x07, 0x77, 0x77, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x70, 0x00, 0x00, 0x07, 0x77, 0x74, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70,
+ 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x70,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x06, 0x66, 0x66, 0x00, 0x00, 0x07, 0x70, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x46, 0x60, 0x00,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x66, 0x66,
+ 0x00, 0x00, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x74, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x44, 0x07,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x77, 0x77, 0x77, 0x77,
+ 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x07, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x77, 0x77,
+ 0x77, 0x47, 0x77, 0x47, 0x77, 0x74, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x74, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x44, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x77, 0x77, 0x77, 0x00, 0x07, 0x00, 0x00,
+ 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x44, 0x44, 0x44, 0x44, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x74, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00,
+ 0x44, 0x44, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x74, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x74, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x74, 0x77, 0x77, 0x77, 0x77, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, 0x40, 0x04, 0x40, 0x00, 0x00, 0x44,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x74, 0x44, 0x44, 0x44, 0x40, 0x44, 0x00, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x70, 0x00, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x77, 0x77, 0x77, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x77, 0x77, 0x00, 0x00, 0x07, 0x47,
+ 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x77, 0x77, 0x70, 0x70,
+ 0x77, 0x07, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x00, 0x00,
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x90, 0x08, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x44, 0x44, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0xCC, 0x90, 0xA0, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x70, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x05,
+ 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x0C,
+ 0x07, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x44,
+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x70,
+ 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x77, 0x77, 0x00, 0x77, 0x70, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x55, 0x00, 0x00,
+};
diff --git a/xfa/src/fgas/include/fgas.h b/xfa/src/fgas/include/fgas.h
new file mode 100644
index 0000000000..8f085e4791
--- /dev/null
+++ b/xfa/src/fgas/include/fgas.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FGAS_
+#define _FGAS_
+#include "fx_sys.h"
+#include "fx_mem.h"
+#include "fx_lgg.h"
+#include "fx_utl.h"
+#include "fx_alg.h"
+#include "fx_cpg.h"
+#include "fx_stm.h"
+#include "fx_datetime.h"
+#include "fx_locale.h"
+#include "fx_sax.h"
+#include "fx_fnt.h"
+#include "fx_ucd.h"
+#include "fx_lbk.h"
+#include "fx_tbk.h"
+#include "fx_rbk.h"
+#endif
diff --git a/xfa/src/fgas/include/fx_alg.h b/xfa/src/fgas/include/fx_alg.h
new file mode 100644
index 0000000000..ed946641f2
--- /dev/null
+++ b/xfa/src/fgas/include/fx_alg.h
@@ -0,0 +1,46 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_ALGORITHM
+#define _FX_ALGORITHM
+#define FX_IsOdd(a) ((a) & 1)
+#ifdef __cplusplus
+extern "C" {
+#endif
+FX_INT32 FX_Base64EncodeA(FX_LPCBYTE pSrc, FX_INT32 iSrcLen, FX_LPSTR pDst);
+FX_INT32 FX_Base64DecodeA(FX_LPCSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE pDst);
+FX_INT32 FX_Base64DecodeW(FX_LPCWSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE pDst);
+FX_BYTE FX_Hex2Dec(FX_BYTE hexHigh, FX_BYTE hexLow);
+FX_INT32 FX_SeparateStringW(FX_LPCWSTR pStr, FX_INT32 iStrLen, FX_WCHAR delimiter, CFX_WideStringArray &pieces);
+#ifdef __cplusplus
+};
+#endif
+template<class baseType>
+class CFX_DSPATemplate
+{
+public:
+ FX_INT32 Lookup(const baseType &find, const baseType *pArray, FX_INT32 iCount)
+ {
+ FXSYS_assert(pArray != NULL);
+ if (iCount < 1) {
+ return -1;
+ }
+ FX_INT32 iStart = 0, iEnd = iCount - 1, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const baseType &v = pArray[iMid];
+ if (find == v) {
+ return iMid;
+ } else if (find < v) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return -1;
+ }
+};
+#endif
diff --git a/xfa/src/fgas/include/fx_cpg.h b/xfa/src/fgas/include/fx_cpg.h
new file mode 100644
index 0000000000..43c6520152
--- /dev/null
+++ b/xfa/src/fgas/include/fx_cpg.h
@@ -0,0 +1,233 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_CODEPAGE
+#define _FX_CODEPAGE
+class IFX_CodePage;
+#define FX_CODEPAGE_DefANSI 0
+#define FX_CODEPAGE_DefOEM 1
+#define FX_CODEPAGE_DefMAC 2
+#define FX_CODEPAGE_Thread 3
+#define FX_CODEPAGE_Symbol 42
+#define FX_CODEPAGE_MSDOS_US 437
+#define FX_CODEPAGE_Arabic_ASMO708 708
+#define FX_CODEPAGE_Arabic_ASMO449Plus 709
+#define FX_CODEPAGE_Arabic_Transparent 710
+#define FX_CODEPAGE_Arabic_NafithaEnhanced 711
+#define FX_CODEPAGE_Arabic_TransparentASMO 720
+#define FX_CODEPAGE_MSDOS_Greek1 737
+#define FX_CODEPAGE_MSDOS_Baltic 775
+#define FX_CODEPAGE_MSWin31_WesternEuropean 819
+#define FX_CODEPAGE_MSDOS_WesternEuropean 850
+#define FX_CODEPAGE_MSDOS_EasternEuropean 852
+#define FX_CODEPAGE_MSDOS_Latin3 853
+#define FX_CODEPAGE_MSDOS_Cyrillic 855
+#define FX_CODEPAGE_MSDOS_Turkish 857
+#define FX_CODEPAGE_MSDOS_Latin1Euro 858
+#define FX_CODEPAGE_MSDOS_Portuguese 860
+#define FX_CODEPAGE_MSDOS_Icelandic 861
+#define FX_CODEPAGE_MSDOS_Hebrew 862
+#define FX_CODEPAGE_MSDOS_FrenchCanadian 863
+#define FX_CODEPAGE_MSDOS_Arabic 864
+#define FX_CODEPAGE_MSDOS_Norwegian 865
+#define FX_CODEPAGE_MSDOS_Russian 866
+#define FX_CODEPAGE_MSDOS_Greek2 869
+#define FX_CODEPAGE_MSDOS_Thai 874
+#define FX_CODEPAGE_MSDOS_KamenickyCS 895
+#define FX_CODEPAGE_ShiftJIS 932
+#define FX_CODEPAGE_ChineseSimplified 936
+#define FX_CODEPAGE_Korean 949
+#define FX_CODEPAGE_ChineseTraditional 950
+#define FX_CODEPAGE_UTF16LE 1200
+#define FX_CODEPAGE_UTF16BE 1201
+#define FX_CODEPAGE_MSWin_EasternEuropean 1250
+#define FX_CODEPAGE_MSWin_Cyrillic 1251
+#define FX_CODEPAGE_MSWin_WesternEuropean 1252
+#define FX_CODEPAGE_MSWin_Greek 1253
+#define FX_CODEPAGE_MSWin_Turkish 1254
+#define FX_CODEPAGE_MSWin_Hebrew 1255
+#define FX_CODEPAGE_MSWin_Arabic 1256
+#define FX_CODEPAGE_MSWin_Baltic 1257
+#define FX_CODEPAGE_MSWin_Vietnamese 1258
+#define FX_CODEPAGE_Johab 1361
+#define FX_CODEPAGE_MAC_Roman 10000
+#define FX_CODEPAGE_MAC_ShiftJIS 10001
+#define FX_CODEPAGE_MAC_ChineseTraditional 10002
+#define FX_CODEPAGE_MAC_Korean 10003
+#define FX_CODEPAGE_MAC_Arabic 10004
+#define FX_CODEPAGE_MAC_Hebrew 10005
+#define FX_CODEPAGE_MAC_Greek 10006
+#define FX_CODEPAGE_MAC_Cyrillic 10007
+#define FX_CODEPAGE_MAC_ChineseSimplified 10008
+#define FX_CODEPAGE_MAC_Thai 10021
+#define FX_CODEPAGE_MAC_EasternEuropean 10029
+#define FX_CODEPAGE_MAC_Turkish 10081
+#define FX_CODEPAGE_UTF32LE 12000
+#define FX_CODEPAGE_UTF32BE 12001
+#define FX_CODEPAGE_ISO8859_1 28591
+#define FX_CODEPAGE_ISO8859_2 28592
+#define FX_CODEPAGE_ISO8859_3 28593
+#define FX_CODEPAGE_ISO8859_4 28594
+#define FX_CODEPAGE_ISO8859_5 28595
+#define FX_CODEPAGE_ISO8859_6 28596
+#define FX_CODEPAGE_ISO8859_7 28597
+#define FX_CODEPAGE_ISO8859_8 28598
+#define FX_CODEPAGE_ISO8859_9 28599
+#define FX_CODEPAGE_ISO8859_10 28600
+#define FX_CODEPAGE_ISO8859_11 28601
+#define FX_CODEPAGE_ISO8859_12 28602
+#define FX_CODEPAGE_ISO8859_13 28603
+#define FX_CODEPAGE_ISO8859_14 28604
+#define FX_CODEPAGE_ISO8859_15 28605
+#define FX_CODEPAGE_ISO8859_16 28606
+#define FX_CODEPAGE_ISCII_Devanagari 57002
+#define FX_CODEPAGE_ISCII_Bengali 57003
+#define FX_CODEPAGE_ISCII_Tamil 57004
+#define FX_CODEPAGE_ISCII_Telugu 57005
+#define FX_CODEPAGE_ISCII_Assamese 57006
+#define FX_CODEPAGE_ISCII_Oriya 57007
+#define FX_CODEPAGE_ISCII_Kannada 57008
+#define FX_CODEPAGE_ISCII_Malayalam 57009
+#define FX_CODEPAGE_ISCII_Gujarati 57010
+#define FX_CODEPAGE_ISCII_Punjabi 57011
+#define FX_CODEPAGE_UTF7 65000
+#define FX_CODEPAGE_UTF8 65001
+#define FX_CHARSET_ANSI 0
+#define FX_CHARSET_Default 1
+#define FX_CHARSET_Symbol 2
+#define FX_CHARSET_MAC_Roman 77
+#define FX_CHARSET_MAC_ShiftJIS 78
+#define FX_CHARSET_MAC_Korean 79
+#define FX_CHARSET_MAC_ChineseSimplified 80
+#define FX_CHARSET_MAC_ChineseTriditional 81
+#define FX_CHARSET_MAC_Johab 82
+#define FX_CHARSET_MAC_Hebrew 83
+#define FX_CHARSET_MAC_Arabic 84
+#define FX_CHARSET_MAC_Greek 85
+#define FX_CHARSET_MAC_Turkish 86
+#define FX_CHARSET_MAC_Thai 87
+#define FX_CHARSET_MAC_EasternEuropean 88
+#define FX_CHARSET_MAC_Cyrillic 89
+#define FX_CHARSET_ShiftJIS 128
+#define FX_CHARSET_Korean 129
+#define FX_CHARSET_Johab 130
+#define FX_CHARSET_ChineseSimplified 134
+#define FX_CHARSET_ChineseTriditional 136
+#define FX_CHARSET_MSWin_Greek 161
+#define FX_CHARSET_MSWin_Turkish 162
+#define FX_CHARSET_MSWin_Vietnamese 163
+#define FX_CHARSET_MSWin_Hebrew 177
+#define FX_CHARSET_MSWin_Arabic 178
+#define FX_CHARSET_ArabicTraditional 179
+#define FX_CHARSET_ArabicUser 180
+#define FX_CHARSET_HebrewUser 181
+#define FX_CHARSET_MSWin_Baltic 186
+#define FX_CHARSET_MSWin_Cyrillic 204
+#define FX_CHARSET_Thai 222
+#define FX_CHARSET_MSWin_EasterEuropean 238
+#define FX_CHARSET_US 254
+#define FX_CHARSET_OEM 255
+FX_WORD FX_GetCodePageFromCharset(FX_BYTE charset);
+FX_WORD FX_GetCharsetFromCodePage(FX_WORD codepage);
+FX_WORD FX_GetCodePageFromStringA(FX_LPCSTR pStr, FX_INT32 iLength);
+FX_WORD FX_GetCodePageFormStringW(FX_LPCWSTR pStr, FX_INT32 iLength);
+FX_WORD FX_GetDefCodePageByLanguage(FX_WORD wLanguage);
+void FX_SwapByteOrder(FX_LPWSTR pStr, FX_INT32 iLength);
+void FX_SwapByteOrderCopy(FX_LPCWSTR pSrc, FX_LPWSTR pDst, FX_INT32 iLength);
+void FX_UTF16ToWChar(FX_LPVOID pBuffer, FX_INT32 iLength);
+void FX_UTF16ToWCharCopy(const FX_WORD *pUTF16, FX_LPWSTR pWChar, FX_INT32 iLength);
+void FX_WCharToUTF16(FX_LPVOID pBuffer, FX_INT32 iLength);
+void FX_WCharToUTF16Copy(FX_LPCWSTR pWChar, FX_WORD *pUTF16, FX_INT32 iLength);
+FX_INT32 FX_DecodeString(FX_WORD wCodePage, FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen, FX_BOOL bErrBreak = FALSE);
+FX_INT32 FX_UTF8Decode(FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen);
+enum FX_CODESYSTEM {
+ FX_MBCS = 0,
+ FX_SBCS ,
+ FX_DBCS ,
+};
+typedef struct _FX_CODEPAGE_HEADER {
+ FX_UINT16 uCPID;
+ FX_UINT8 uMinCharBytes;
+ FX_UINT8 uMaxCharBytes;
+ FX_CODESYSTEM eCPType;
+ FX_BOOL bHasLeadByte;
+ FX_WCHAR wMinChar;
+ FX_WCHAR wMaxChar;
+ FX_WCHAR wDefChar;
+ FX_WCHAR wMinUnicode;
+ FX_WCHAR wMaxUnicode;
+ FX_WCHAR wDefUnicode;
+} FX_CODEPAGE_HEADER;
+#define FX_CPMAPTYPE_Consecution 1
+#define FX_CPMAPTYPE_Strict 2
+#define FX_CPMAPTYPE_NoMapping 3
+#define FX_CPMAPTYPE_Delta 4
+typedef struct _FX_CPCU_MAPTABLE1 {
+ FX_UINT16 uMapType;
+ FX_UINT16 uUniocde;
+} FX_CPCU_MAPTABLE1;
+typedef struct _FX_CPCU_MAPTABLE2 {
+ FX_UINT8 uTrailByte;
+ FX_UINT8 uMapType;
+ FX_UINT16 uOffset;
+} FX_CPCU_MAPTABLE2;
+typedef struct _FX_CPCU_MAPINFO {
+ FX_CPCU_MAPTABLE1 *pMapTable1;
+ FX_CPCU_MAPTABLE2 *pMapTable2;
+ FX_LPCBYTE pMapData;
+} FX_CPCU_MAPINFO;
+typedef struct _FX_CPUC_MAPTABLE {
+ FX_UINT16 uStartUnicode;
+ FX_UINT16 uEndUnicode;
+ FX_UINT16 uMapType;
+ FX_UINT16 uOffset;
+} FX_CPUC_MAPTABLE;
+typedef struct _FX_CPUC_MAPINFO {
+ FX_UINT32 uMapCount;
+ FX_CPUC_MAPTABLE *pMapTable;
+ FX_LPCBYTE pMapData;
+} FX_CPUC_MAPINFO;
+typedef struct _FX_CODEPAGE {
+ FX_CODEPAGE_HEADER const *pCPHeader;
+ FX_CPCU_MAPINFO const *pCPCUMapInfo;
+ FX_CPUC_MAPINFO const *pCPUCMapInfo;
+} FX_CODEPAGE, * FX_LPCODEPAGE;
+typedef FX_CODEPAGE const * FX_LPCCODEPAGE;
+typedef struct _FX_STR2CPHASH {
+ FX_UINT32 uHash;
+ FX_UINT32 uCodePage;
+} FX_STR2CPHASH;
+typedef struct _FX_CHARSET_MAP {
+ FX_UINT16 charset;
+ FX_UINT16 codepage;
+} FX_CHARSET_MAP;
+typedef struct _FX_LANG2CPMAP {
+ FX_WORD wLanguage;
+ FX_WORD wCodepage;
+} FX_LANG2CPMAP;
+class IFX_CodePage
+{
+public:
+ static IFX_CodePage* Create(FX_WORD wCodePage);
+ virtual void Release() = 0;
+ virtual FX_WORD GetCodePageNumber() const = 0;
+ virtual FX_CODESYSTEM GetCodeSystemType() const = 0;
+ virtual FX_BOOL HasLeadByte() const = 0;
+ virtual FX_BOOL IsLeadByte(FX_BYTE byte) const = 0;
+ virtual FX_INT32 GetMinBytesPerChar() const = 0;
+ virtual FX_INT32 GetMaxBytesPerChar() const = 0;
+ virtual FX_WCHAR GetMinCharcode() const = 0;
+ virtual FX_WCHAR GetMaxCharcode() const = 0;
+ virtual FX_WCHAR GetDefCharcode() const = 0;
+ virtual FX_WCHAR GetMinUnicode() const = 0;
+ virtual FX_WCHAR GetMaxUnicode() const = 0;
+ virtual FX_WCHAR GetDefUnicode() const = 0;
+ virtual FX_BOOL IsValidCharcode(FX_WORD wCharcode) const = 0;
+ virtual FX_WCHAR GetUnicode(FX_WORD wCharcode) const = 0;
+ virtual FX_BOOL IsValidUnicode(FX_WCHAR wUnicode) const = 0;
+ virtual FX_WORD GetCharcode(FX_WCHAR wUnicode) const = 0;
+};
+#endif
diff --git a/xfa/src/fgas/include/fx_datetime.h b/xfa/src/fgas/include/fx_datetime.h
new file mode 100644
index 0000000000..dd0a5d6147
--- /dev/null
+++ b/xfa/src/fgas/include/fx_datetime.h
@@ -0,0 +1,470 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_DATETIME_H_
+#define _FX_DATETIME_H_
+class CFX_Unitime;
+class CFX_DateTime;
+typedef FX_INT64 FX_UNITIME;
+enum FX_WEEKDAY {
+ FX_Sunday = 0,
+ FX_Monday ,
+ FX_Tuesday ,
+ FX_Wednesday ,
+ FX_Thursday ,
+ FX_Friday ,
+ FX_Saturday ,
+};
+FX_BOOL FX_IsLeapYear(FX_INT32 iYear);
+FX_INT32 FX_DaysInYear(FX_INT32 iYear);
+FX_BYTE FX_DaysInMonth(FX_INT32 iYear, FX_BYTE iMonth);
+class CFX_Unitime : public CFX_Object
+{
+public:
+ CFX_Unitime()
+ {
+ m_iUnitime = 0;
+ }
+ CFX_Unitime(FX_UNITIME iUnitime)
+ {
+ m_iUnitime = iUnitime;
+ }
+ CFX_Unitime(const CFX_Unitime &unitime)
+ {
+ m_iUnitime = unitime.m_iUnitime;
+ }
+ operator FX_UNITIME * ()
+ {
+ return &m_iUnitime;
+ }
+ operator FX_UNITIME const * () const
+ {
+ return &m_iUnitime;
+ }
+ operator FX_UNITIME& ()
+ {
+ return m_iUnitime;
+ }
+ operator const FX_UNITIME& () const
+ {
+ return m_iUnitime;
+ }
+ CFX_Unitime& operator = (const CFX_Unitime &t)
+ {
+ m_iUnitime = t.m_iUnitime;
+ return *this;
+ }
+ CFX_Unitime& operator = (FX_UNITIME t)
+ {
+ m_iUnitime = t;
+ return *this;
+ }
+ CFX_Unitime& operator += (const CFX_Unitime &t)
+ {
+ m_iUnitime += t.m_iUnitime;
+ return *this;
+ }
+ CFX_Unitime& operator += (FX_UNITIME t)
+ {
+ m_iUnitime += t;
+ return *this;
+ }
+ CFX_Unitime& operator -= (const CFX_Unitime &t)
+ {
+ m_iUnitime -= t.m_iUnitime;
+ return *this;
+ }
+ CFX_Unitime& operator -= (FX_UNITIME t)
+ {
+ m_iUnitime -= t;
+ return *this;
+ }
+ void Now();
+ void SetGMTime();
+ void Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour = 0, FX_BYTE minute = 0, FX_BYTE second = 0, FX_WORD millisecond = 0);
+ void Set(FX_UNITIME t);
+ FX_INT32 GetYear() const;
+ FX_BYTE GetMonth() const;
+ FX_BYTE GetDay() const;
+ FX_WEEKDAY GetDayOfWeek() const;
+ FX_WORD GetDayOfYear() const;
+ FX_INT64 GetDayOfAD() const;
+ FX_BYTE GetHour() const;
+ FX_BYTE GetMinute() const;
+ FX_BYTE GetSecond() const;
+ FX_WORD GetMillisecond() const;
+ FX_BOOL AddYears(FX_INT32 iYears);
+ FX_BOOL AddMonths(FX_INT32 iMonths);
+ FX_BOOL AddDays(FX_INT32 iDays);
+ FX_BOOL AddHours(FX_INT32 iHours);
+ FX_BOOL AddMinutes(FX_INT32 iMinutes);
+ FX_BOOL AddSeconds(FX_INT32 iSeconds);
+ FX_BOOL AddMilliseconds(FX_INT32 iMilliseconds);
+ friend CFX_Unitime operator + (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return CFX_Unitime(t1.m_iUnitime + t2.m_iUnitime);
+ }
+ friend CFX_Unitime operator + (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return CFX_Unitime(t1.m_iUnitime + t2);
+ }
+ friend CFX_Unitime operator + (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return CFX_Unitime(t1 + t2.m_iUnitime);
+ }
+ friend CFX_Unitime operator - (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return CFX_Unitime(t1.m_iUnitime + t2.m_iUnitime);
+ }
+ friend CFX_Unitime operator - (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return CFX_Unitime(t1.m_iUnitime + t2);
+ }
+ friend CFX_Unitime operator - (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return CFX_Unitime(t1 + t2.m_iUnitime);
+ }
+ friend FX_BOOL operator == (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return t1.m_iUnitime == t2.m_iUnitime;
+ }
+ friend FX_BOOL operator == (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return t1.m_iUnitime == t2;
+ }
+ friend FX_BOOL operator == (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return t1 == t2.m_iUnitime;
+ }
+ friend FX_BOOL operator != (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return t1.m_iUnitime != t2.m_iUnitime;
+ }
+ friend FX_BOOL operator != (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return t1.m_iUnitime != t2;
+ }
+ friend FX_BOOL operator != (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return t1 != t2.m_iUnitime;
+ }
+ friend FX_BOOL operator > (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return t1.m_iUnitime > t2.m_iUnitime;
+ }
+ friend FX_BOOL operator > (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return t1.m_iUnitime > t2;
+ }
+ friend FX_BOOL operator > (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return t1 > t2.m_iUnitime;
+ }
+ friend FX_BOOL operator >= (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return t1.m_iUnitime >= t2.m_iUnitime;
+ }
+ friend FX_BOOL operator >= (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return t1.m_iUnitime >= t2;
+ }
+ friend FX_BOOL operator >= (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return t1 >= t2.m_iUnitime;
+ }
+ friend FX_BOOL operator < (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return t1.m_iUnitime < t2.m_iUnitime;
+ }
+ friend FX_BOOL operator < (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return t1.m_iUnitime < t2;
+ }
+ friend FX_BOOL operator < (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return t1 < t2.m_iUnitime;
+ }
+ friend FX_BOOL operator <= (const CFX_Unitime &t1, const CFX_Unitime &t2)
+ {
+ return t1.m_iUnitime <= t2.m_iUnitime;
+ }
+ friend FX_BOOL operator <= (const CFX_Unitime &t1, FX_UNITIME t2)
+ {
+ return t1.m_iUnitime <= t2;
+ }
+ friend FX_BOOL operator <= (FX_UNITIME t1, const CFX_Unitime &t2)
+ {
+ return t1 <= t2.m_iUnitime;
+ }
+private:
+ FX_UNITIME m_iUnitime;
+};
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(push, 1)
+#endif
+typedef struct _FX_DATE {
+ FX_INT32 year;
+ FX_BYTE month;
+ FX_BYTE day;
+} FX_DATE, * FX_LPDATE;
+typedef FX_DATE const * FX_LPCDATE;
+typedef struct _FX_TIME {
+ FX_BYTE hour;
+ FX_BYTE minute;
+ FX_BYTE second;
+ FX_WORD millisecond;
+} FX_TIME, * FX_LPTIME;
+typedef FX_TIME const * FX_LPCTIME;
+typedef struct _FX_TIMEZONE {
+ FX_INT8 tzHour;
+ FX_BYTE tzMinute;
+} FX_TIMEZONE, * FX_LPTIMEZONE;
+typedef FX_TIMEZONE const * FX_LPCTIMEZONE;
+typedef struct _FX_DATETIME {
+ union {
+ struct {
+ FX_INT32 year;
+ FX_BYTE month;
+ FX_BYTE day;
+ } sDate;
+ FX_DATE aDate;
+ } Date;
+ union {
+ struct {
+ FX_BYTE hour;
+ FX_BYTE minute;
+ FX_BYTE second;
+ FX_WORD millisecond;
+ } sTime;
+ FX_TIME aTime;
+ } Time;
+} FX_DATETIME, * FX_LPDATETIME;
+typedef FX_DATETIME const * FX_LPCDATETIME;
+typedef struct _FX_DATETIMEZONE {
+ union {
+ struct {
+ union {
+ struct {
+ FX_INT32 year;
+ FX_BYTE month;
+ FX_BYTE day;
+ };
+ FX_DATE date;
+ };
+ union {
+ struct {
+ FX_BYTE hour;
+ FX_BYTE minute;
+ FX_BYTE second;
+ FX_WORD millisecond;
+ };
+ FX_TIME time;
+ };
+ };
+ FX_DATETIME dt;
+ };
+ union {
+ struct {
+ FX_INT8 tzHour;
+ FX_BYTE tzMinute;
+ };
+ FX_TIMEZONE tz;
+ };
+} FX_DATETIMEZONE, * FX_LPDATETIMEZONE;
+typedef FX_DATETIMEZONE const * FX_LPCDATETIMEZONE;
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(pop)
+#endif
+class CFX_DateTime : public CFX_Object
+{
+public:
+ CFX_DateTime() {}
+ CFX_DateTime(const FX_DATETIME &dt)
+ {
+ m_DateTime = dt;
+ }
+ CFX_DateTime(const CFX_DateTime &dt)
+ {
+ m_DateTime = dt.m_DateTime;
+ }
+ operator FX_DATETIME * ()
+ {
+ return &m_DateTime;
+ }
+ operator FX_DATETIME const * () const
+ {
+ return &m_DateTime;
+ }
+ operator FX_DATETIME& ()
+ {
+ return m_DateTime;
+ }
+ operator const FX_DATETIME& () const
+ {
+ return m_DateTime;
+ }
+ CFX_DateTime& operator = (const CFX_DateTime &dt)
+ {
+ m_DateTime = dt.m_DateTime;
+ return *this;
+ }
+ CFX_DateTime& operator = (const FX_DATETIME &dt)
+ {
+ m_DateTime = dt;
+ return *this;
+ }
+ CFX_DateTime& operator += (const CFX_DateTime &dt)
+ {
+ FromUnitime(ToUnitime() + dt.ToUnitime());
+ return *this;
+ }
+ CFX_DateTime& operator += (const FX_DATETIME &dt)
+ {
+ FromUnitime(ToUnitime() + ((const CFX_DateTime&)dt).ToUnitime());
+ return *this;
+ }
+ CFX_DateTime& operator -= (const CFX_DateTime &dt)
+ {
+ FromUnitime(ToUnitime() - dt.ToUnitime());
+ return *this;
+ }
+ CFX_DateTime& operator -= (const FX_DATETIME &dt)
+ {
+ FromUnitime(ToUnitime() - ((const CFX_DateTime&)dt).ToUnitime());
+ return *this;
+ }
+ virtual FX_BOOL Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour = 0, FX_BYTE minute = 0, FX_BYTE second = 0, FX_WORD millisecond = 0);
+ virtual FX_BOOL FromUnitime(FX_UNITIME t);
+ virtual FX_UNITIME ToUnitime() const;
+ virtual FX_INT32 GetYear() const;
+ virtual FX_BYTE GetMonth() const;
+ virtual FX_BYTE GetDay() const;
+ virtual FX_WEEKDAY GetDayOfWeek() const;
+ virtual FX_WORD GetDayOfYear() const;
+ virtual FX_INT64 GetDayOfAD() const;
+ virtual FX_BYTE GetHour() const;
+ virtual FX_BYTE GetMinute() const;
+ virtual FX_BYTE GetSecond() const;
+ virtual FX_WORD GetMillisecond() const;
+ virtual FX_BOOL AddYears(FX_INT32 iYears);
+ virtual FX_BOOL AddMonths(FX_INT32 iMonths);
+ virtual FX_BOOL AddDays(FX_INT32 iDays);
+ virtual FX_BOOL AddHours(FX_INT32 iHours);
+ virtual FX_BOOL AddMinutes(FX_INT32 iMinutes);
+ virtual FX_BOOL AddSeconds(FX_INT32 iSeconds);
+ virtual FX_BOOL AddMilliseconds(FX_INT32 iMilliseconds);
+ friend CFX_DateTime operator + (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ CFX_DateTime dt;
+ dt.FromUnitime(dt1.ToUnitime() + dt2.ToUnitime());
+ return dt;
+ }
+ friend CFX_DateTime operator + (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ CFX_DateTime dt;
+ dt.FromUnitime(dt1.ToUnitime() + ((const CFX_DateTime&)dt2).ToUnitime());
+ return dt;
+ }
+ friend CFX_DateTime operator + (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ CFX_DateTime dt;
+ dt.FromUnitime(((const CFX_DateTime&)dt1).ToUnitime() + dt2.ToUnitime());
+ return dt;
+ }
+ friend CFX_DateTime operator - (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ CFX_DateTime dt;
+ dt.FromUnitime(dt1.ToUnitime() - dt2.ToUnitime());
+ return dt;
+ }
+ friend CFX_DateTime operator - (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ CFX_DateTime dt;
+ dt.FromUnitime(dt1.ToUnitime() - ((const CFX_DateTime&)dt2).ToUnitime());
+ return dt;
+ }
+ friend CFX_DateTime operator - (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ CFX_DateTime dt;
+ dt.FromUnitime(((const CFX_DateTime&)dt1).ToUnitime() - dt2.ToUnitime());
+ return dt;
+ }
+ friend FX_BOOL operator == (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ return FXSYS_memcmp((FX_LPCDATETIME)dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) == 0;
+ }
+ friend FX_BOOL operator == (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ return FXSYS_memcmp((FX_LPCDATETIME)dt1, &dt2, sizeof(FX_DATETIME)) == 0;
+ }
+ friend FX_BOOL operator == (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ return FXSYS_memcmp(&dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) == 0;
+ }
+ friend FX_BOOL operator != (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ return FXSYS_memcmp((FX_LPCDATETIME)dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) != 0;
+ }
+ friend FX_BOOL operator != (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ return FXSYS_memcmp((FX_LPCDATETIME)dt1, &dt2, sizeof(FX_DATETIME)) != 0;
+ }
+ friend FX_BOOL operator != (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ return FXSYS_memcmp(&dt1, (FX_LPCDATETIME)dt2, sizeof(FX_DATETIME)) != 0;
+ }
+ friend FX_BOOL operator > (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ return dt1.ToUnitime() > dt2.ToUnitime();
+ }
+ friend FX_BOOL operator > (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ return dt1.ToUnitime() > ((const CFX_DateTime&)dt2).ToUnitime();
+ }
+ friend FX_BOOL operator > (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ return ((const CFX_DateTime&)dt1).ToUnitime() > dt2.ToUnitime();
+ }
+ friend FX_BOOL operator >= (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ return dt1.ToUnitime() >= dt2.ToUnitime();
+ }
+ friend FX_BOOL operator >= (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ return dt1.ToUnitime() >= ((const CFX_DateTime&)dt2).ToUnitime();
+ }
+ friend FX_BOOL operator >= (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ return ((const CFX_DateTime&)dt1).ToUnitime() >= dt2.ToUnitime();
+ }
+ friend FX_BOOL operator < (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ return dt1.ToUnitime() < dt2.ToUnitime();
+ }
+ friend FX_BOOL operator < (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ return dt1.ToUnitime() < ((const CFX_DateTime&)dt2).ToUnitime();
+ }
+ friend FX_BOOL operator < (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ return ((const CFX_DateTime&)dt1).ToUnitime() < dt2.ToUnitime();
+ }
+ friend FX_BOOL operator <= (const CFX_DateTime &dt1, const CFX_DateTime &dt2)
+ {
+ return dt1.ToUnitime() <= dt2.ToUnitime();
+ }
+ friend FX_BOOL operator <= (const CFX_DateTime &dt1, const FX_DATETIME &dt2)
+ {
+ return dt1.ToUnitime() <= ((const CFX_DateTime&)dt2).ToUnitime();
+ }
+ friend FX_BOOL operator <= (const FX_DATETIME &dt1, const CFX_DateTime &dt2)
+ {
+ return ((const CFX_DateTime&)dt1).ToUnitime() <= dt2.ToUnitime();
+ }
+private:
+ FX_DATETIME m_DateTime;
+};
+#endif
diff --git a/xfa/src/fgas/include/fx_fnt.h b/xfa/src/fgas/include/fx_fnt.h
new file mode 100644
index 0000000000..d664853df7
--- /dev/null
+++ b/xfa/src/fgas/include/fx_fnt.h
@@ -0,0 +1,170 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_FONT
+#define _FX_FONT
+class IFX_Font;
+class IFX_FontMgr;
+#define FX_FONTSTYLE_Normal 0x00
+#define FX_FONTSTYLE_FixedPitch 0x01
+#define FX_FONTSTYLE_Serif 0x02
+#define FX_FONTSTYLE_Symbolic 0x04
+#define FX_FONTSTYLE_Script 0x08
+#define FX_FONTSTYLE_Italic 0x40
+#define FX_FONTSTYLE_Bold 0x40000
+#define FX_FONTSTYLE_BoldItalic (FX_FONTSTYLE_Bold|FX_FONTSTYLE_Italic)
+#define FX_FONTSTYLE_ExactMatch 0x80000000
+#define FX_FONTDECORATION_Underline 0x00000001
+#define FX_FONTDECORATION_Strikeout 0x00000002
+#define FX_FONTDECORATION_Overline 0x00000004
+#define FX_FONTDECORATION_Emphasis 0x00000008
+#define FX_FONTDECORATION_Superscript 0x00000010
+#define FX_FONTDECORATION_Subscript 0x00000020
+#define FX_FONTDECORATION_SmallCapital 0x00000040
+#define FX_FONTDECORATION_Capital 0x00000080
+#define FX_FONTDECORATION_Lowercase 0x000000C0
+#define FX_FONTDECORATION_Raised 0x00000100
+#define FX_FONTDECORATION_Sunken 0x00000200
+#define FX_FONTDECORATION_Shadow 0x00000400
+#define FX_FONTDECORATION_BoundingShape 0x20000000
+#define FX_FONTDECORATION_Hide 0x40000000
+#define FX_FONTDECORATION_StrokeFill 0x80000000
+#define FX_BOUNDINGSHAPE_None 0
+#define FX_BOUNDINGSHAPE_Circle 1
+#define FX_BOUNDINGSHAPE_Square 2
+#define FX_BOUNDINGSHAPE_Triangle 3
+#define FX_BOUNDINGSHAPE_Diamond 4
+class IFX_FontProvider
+{
+public:
+ virtual FX_BOOL GetCharWidth(IFX_Font* pFont, FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE) = 0;
+};
+class IFX_Font
+{
+public:
+ static IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage, IFX_FontMgr *pFontMgr);
+ static IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, IFX_FontMgr *pFontMgr);
+ static IFX_Font* LoadFont(FX_LPCWSTR pszFileName, IFX_FontMgr *pFontMgr);
+ static IFX_Font* LoadFont(IFX_Stream *pFontStream, IFX_FontMgr *pFontMgr, FX_BOOL bSaveStream = FALSE);
+ static IFX_Font* LoadFont(CFX_Font *pExtFont, IFX_FontMgr *pFontMgr, FX_BOOL bTakeOver = FALSE);
+ virtual void Release() = 0;
+ virtual IFX_Font* Retain() = 0;
+ virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0) = 0;
+ virtual void GetFamilyName(CFX_WideString &wsFamily) const = 0;
+ virtual void GetPsName(CFX_WideString &wsName) const = 0;
+ virtual FX_DWORD GetFontStyles() const = 0;
+ virtual FX_BYTE GetCharSet() const = 0;
+ virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE) = 0;
+ virtual FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE) = 0;
+ virtual FX_INT32 GetAscent() const = 0;
+ virtual FX_INT32 GetDescent() const = 0;
+ virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode = FALSE) = 0;
+ virtual FX_BOOL GetBBox(CFX_Rect &bbox) = 0;
+ virtual FX_INT32 GetItalicAngle() const = 0;
+ virtual void Reset() = 0;
+ virtual IFX_Font* GetSubstFont(FX_INT32 iGlyphIndex) const = 0;
+ virtual void* GetDevFont() const = 0;
+ virtual void SetFontProvider(IFX_FontProvider* pProvider) = 0;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ virtual void SetLogicalFontStyle(FX_DWORD dwLogFontStyle) = 0;
+#endif
+};
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+typedef struct _FX_FONTMATCHPARAMS : public CFX_Object {
+ FX_LPCWSTR pwsFamily;
+ FX_DWORD dwFontStyles;
+ FX_DWORD dwUSB;
+ FX_DWORD dwMatchFlags;
+ FX_WCHAR wUnicode;
+ FX_WORD wCodePage;
+} FX_FONTMATCHPARAMS, * FX_LPFONTMATCHPARAMS;
+typedef FX_FONTMATCHPARAMS const * FX_LPCFONTMATCHPARAMS;
+typedef struct _FX_FONTSIGNATURE : public CFX_Target {
+ FX_DWORD fsUsb[4];
+ FX_DWORD fsCsb[2];
+} FX_FONTSIGNATURE;
+typedef struct _FX_FONTDESCRIPTOR : public CFX_Target {
+ FX_WCHAR wsFontFace[32];
+ FX_DWORD dwFontStyles;
+ FX_BYTE uCharSet;
+ FX_FONTSIGNATURE FontSignature;
+} FX_FONTDESCRIPTOR, * FX_LPFONTDESCRIPTOR;
+typedef FX_FONTDESCRIPTOR const * FX_LPCFONTDESCRIPTOR;
+typedef CFX_MassArrayTemplate<FX_FONTDESCRIPTOR> CFX_FontDescriptors;
+inline FX_BOOL operator == (const FX_FONTDESCRIPTOR &left, const FX_FONTDESCRIPTOR &right)
+{
+ return left.uCharSet == right.uCharSet
+ && left.dwFontStyles == right.dwFontStyles
+ && FXSYS_wcscmp(left.wsFontFace, right.wsFontFace) == 0
+ && FXSYS_memcmp(&left.FontSignature, &right.FontSignature, sizeof(FX_FONTSIGNATURE)) == 0;
+}
+#define FX_FONTMATCHPARA_MacthStyle 0x01
+#define FX_FONTMATCHPARA_MacthFamily 0x02
+#define FX_FONTMATCHPARA_MacthUnicode 0x04
+typedef void (*FX_LPEnumAllFonts)(CFX_FontDescriptors &fonts, FX_LPVOID pUserData, FX_LPCWSTR pwsFaceName, FX_WCHAR wUnicode);
+FX_LPEnumAllFonts FX_GetDefFontEnumerator();
+typedef FX_LPCFONTDESCRIPTOR (*FX_LPMatchFont)(FX_LPFONTMATCHPARAMS pParams, const CFX_FontDescriptors &fonts, FX_LPVOID pUserData);
+FX_LPMatchFont FX_GetDefFontMatchor();
+class IFX_FontMgr
+{
+public:
+ static IFX_FontMgr* Create(FX_LPEnumAllFonts pEnumerator, FX_LPMatchFont pMatcher = NULL, FX_LPVOID pUserData = NULL);
+ virtual void Release() = 0;
+ virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF) = 0;
+ virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength) = 0;
+ virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName) = 0;
+ virtual IFX_Font* LoadFont(IFX_Stream *pFontStream, FX_LPCWSTR pszFontAlias = NULL, FX_DWORD dwFontStyles = 0, FX_WORD wCodePage = 0, FX_BOOL bSaveStream = FALSE) = 0;
+ virtual IFX_Font* LoadFont(IFX_Font *pSrcFont, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF) = 0;
+ virtual void ClearFontCache() = 0;
+ virtual void RemoveFont(IFX_Font *pFont) = 0;
+};
+#else
+class IFX_FontMgrDelegate
+{
+public:
+ virtual IFX_Font* GetDefFontByCodePage(IFX_FontMgr* pFontMgr, FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByCharset(IFX_FontMgr* pFontMgr, FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByUnicode(IFX_FontMgr* pFontMgr, FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByLanguage(IFX_FontMgr* pFontMgr, FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+};
+class IFX_FontSourceEnum
+{
+public:
+ virtual void Release() = 0;
+ virtual FX_POSITION GetStartPosition(FX_LPVOID pUserData = NULL) = 0;
+ virtual IFX_FileAccess* GetNext(FX_POSITION& pos, FX_LPVOID pUserData = NULL) = 0;
+};
+IFX_FontSourceEnum* FX_CreateDefaultFontSourceEnum();
+class IFX_FontMgr
+{
+public:
+ static IFX_FontMgr* Create(IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate = NULL, FX_LPVOID pUserData = NULL);
+ virtual void Release() = 0;
+ virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ inline IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+ {
+ return GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
+ }
+ virtual IFX_Font* GetFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* GetFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL) = 0;
+ virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, FX_INT32 iFaceIndex, FX_INT32* pFaceCount = NULL) = 0;
+ virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName, FX_INT32 iFaceIndex, FX_INT32* pFaceCount = NULL) = 0;
+ virtual IFX_Font* LoadFont(IFX_Stream *pFontStream, FX_INT32 iFaceIndex, FX_INT32* pFaceCount = NULL, FX_BOOL bSaveStream = FALSE) = 0;
+
+ virtual void ClearFontCache() = 0;
+ virtual void RemoveFont(IFX_Font *pFont) = 0;
+};
+#endif
+#endif
diff --git a/xfa/src/fgas/include/fx_lbk.h b/xfa/src/fgas/include/fx_lbk.h
new file mode 100644
index 0000000000..3c7aa5d7dd
--- /dev/null
+++ b/xfa/src/fgas/include/fx_lbk.h
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_LINEBREAK
+#define _FX_LINEBREAK
+enum FX_LINEBREAKTYPE {
+ FX_LBT_UNKNOWN = 0x00,
+ FX_LBT_DIRECT_BRK = 0x1A,
+ FX_LBT_INDIRECT_BRK = 0x2B,
+ FX_LBT_COM_INDIRECT_BRK = 0x3C,
+ FX_LBT_COM_PROHIBITED_BRK = 0x4D,
+ FX_LBT_PROHIBITED_BRK = 0x5E,
+ FX_LBT_HANGUL_SPACE_BRK = 0x6F,
+};
+#define FX_LBUN FX_LBT_UNKNOWN
+#define FX_LBDB FX_LBT_DIRECT_BRK
+#define FX_LBIB FX_LBT_INDIRECT_BRK
+#define FX_LBCB FX_LBT_COM_INDIRECT_BRK
+#define FX_LBCP FX_LBT_COM_PROHIBITED_BRK
+#define FX_LBPB FX_LBT_PROHIBITED_BRK
+#define FX_LBHS FX_LBT_HANGUL_SPACE_BRK
+void FX_GetLineBreakPositions(FX_LPCWSTR pwsText, FX_LINEBREAKTYPE *pBrkType, FX_INT32 iLength);
+void FX_GetLineBreakPositions(FX_LPCWSTR pwsText, FX_INT32 iLength, CFX_Int32MassArray &bp);
+#endif
diff --git a/xfa/src/fgas/include/fx_lgg.h b/xfa/src/fgas/include/fx_lgg.h
new file mode 100644
index 0000000000..6f4786e319
--- /dev/null
+++ b/xfa/src/fgas/include/fx_lgg.h
@@ -0,0 +1,267 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_LANGUAGE
+#define _FX_LANGUAGE
+#define FX_LANG_Neutral 0x0000
+#define FX_LANG_Invariant 0x007f
+#define FX_LANG_UserDefault 0x0400
+#define FX_LANG_SystemDefault 0x0800
+#define FX_LANG_Afrikaans_SouthAfrica 0x0436
+#define FX_LANG_Albanian_Albania 0x041c
+#define FX_LANG_Alsatian_France 0x0484
+#define FX_LANG_Amharic_Ethiopia 0x045e
+#define FX_LANG_Arabic_Algeria 0x1401
+#define FX_LANG_Arabic_Bahrain 0x3c01
+#define FX_LANG_Arabic_Egypt 0x0c01
+#define FX_LANG_Arabic_Iraq 0x0801
+#define FX_LANG_Arabic_Jordan 0x2c01
+#define FX_LANG_Arabic_Kuwait 0x3401
+#define FX_LANG_Arabic_Lebanon 0x3001
+#define FX_LANG_Arabic_Libya 0x1001
+#define FX_LANG_Arabic_Morocco 0x1801
+#define FX_LANG_Arabic_Oman 0x2001
+#define FX_LANG_Arabic_Qatar 0x4001
+#define FX_LANG_Arabic_SaudiArabia 0x0401
+#define FX_LANG_Arabic_Syria 0x2801
+#define FX_LANG_Arabic_Tunisia 0x1c01
+#define FX_LANG_Arabic_UAE 0x3801
+#define FX_LANG_Arabic_Yemen 0x2401
+#define FX_LANG_Armenian_Armenia 0x042b
+#define FX_LANG_Assamese_India 0x044d
+#define FX_LANG_Azerbaijan_Cyrillic 0x082c
+#define FX_LANG_Azerbaijan_Latin 0x042c
+#define FX_LANG_Bashkir_Russia 0x046d
+#define FX_LANG_Basque_Basque 0x042d
+#define FX_LANG_Belarusian_Belarus 0x0423
+#define FX_LANG_Bengali_Bangladesh 0x0845
+#define FX_LANG_Bengali_India 0x0445
+#define FX_LANG_Bosnia_Herzegovina 0x101a
+#define FX_LANG_Bosnian_Cyrillic 0x201a
+#define FX_LANG_Bosnian_Latin 0x141a
+#define FX_LANG_Breton_France 0x047e
+#define FX_LANG_Bulgarian_Bulgaria 0x0402
+#define FX_LANG_Burmese 0x0455
+#define FX_LANG_Catalan_Catalan 0x0403
+#define FX_LANG_Cherokee 0x045c
+#define FX_LANG_Chinese_HongKong 0x0c04
+#define FX_LANG_Chinese_Macao 0x1404
+#define FX_LANG_Chinese_PRC 0x0804
+#define FX_LANG_Chinese_Singapore 0x1004
+#define FX_LANG_Chinese_Taiwan 0x0404
+#define FX_LANG_Corsican_France 0x0483
+#define FX_LANG_Croatian_Croatia 0x041a
+#define FX_LANG_Croatian_Latin 0x101a
+#define FX_LANG_CustomCurrent 0x0c00
+#define FX_LANG_CzechRepublic 0x0405
+#define FX_LANG_Danish_Denmark 0x0406
+#define FX_LANG_Dari_Afghanistan 0x048c
+#define FX_LANG_Divehi_Maldives 0x0465
+#define FX_LANG_Dutch_Belgium 0x0813
+#define FX_LANG_Dutch_Netherlands 0x0413
+#define FX_LANG_Dutch_Preferred 0x0013
+#define FX_LANG_Dzongkha 0x0851
+#define FX_LANG_Edo 0x0466
+#define FX_LANG_English_Australia 0x0c09
+#define FX_LANG_English_Belize 0x2809
+#define FX_LANG_English_Canada 0x1009
+#define FX_LANG_English_Caribbean 0x2409
+#define FX_LANG_English_HongKong 0x3c09
+#define FX_LANG_English_India 0x4009
+#define FX_LANG_English_Indonesia 0x3809
+#define FX_LANG_English_Ireland 0x1809
+#define FX_LANG_English_Jamaica 0x2009
+#define FX_LANG_English_Malaysia 0x4409
+#define FX_LANG_English_NewZealand 0x1409
+#define FX_LANG_English_Philippines 0x3409
+#define FX_LANG_English_Singapore 0x4809
+#define FX_LANG_English_SouthAfrica 0x1c09
+#define FX_LANG_English_TrinidadTobago 0x2c09
+#define FX_LANG_English_UnitedKingdom 0x0809
+#define FX_LANG_English_UnitedStates 0x0409
+#define FX_LANG_English_Zimbabwe 0x3009
+#define FX_LANG_Estonian_Estonia 0x0425
+#define FX_LANG_Faroese_FaroeIslands 0x0438
+#define FX_LANG_Filipino_Philippines 0x0464
+#define FX_LANG_Finnish_Finland 0x040b
+#define FX_LANG_French_Belgium 0x080c
+#define FX_LANG_French_Cameroon 0x2c0c
+#define FX_LANG_French_Canada 0x0c0c
+#define FX_LANG_French_CongoDRC 0x240c
+#define FX_LANG_French_CotedIvoire 0x300c
+#define FX_LANG_French_France 0x040c
+#define FX_LANG_French_Haiti 0x3c0c
+#define FX_LANG_French_Luxembourg 0x140c
+#define FX_LANG_French_Mali 0x340c
+#define FX_LANG_French_Monaco 0x180c
+#define FX_LANG_French_Morocco 0x380c
+#define FX_LANG_French_Reunion 0x200c
+#define FX_LANG_French_Senegal 0x280c
+#define FX_LANG_French_Switzerland 0x100c
+#define FX_LANG_French_WestIndies 0x1c0c
+#define FX_LANG_Frisian_Netherlands 0x0462
+#define FX_LANG_Fulfulde 0x0467
+#define FX_LANG_Gaelic_Ireland 0x083c
+#define FX_LANG_Gaelic_Scotland 0x043c
+#define FX_LANG_Galician_Galician 0x0456
+#define FX_LANG_Georgian_Georgia 0x0437
+#define FX_LANG_German_Austria 0x0c07
+#define FX_LANG_German_Germany 0x0407
+#define FX_LANG_German_Liechtenstein 0x1407
+#define FX_LANG_German_Luxembourg 0x1007
+#define FX_LANG_German_Switzerland 0x0807
+#define FX_LANG_Greek_Greece 0x0408
+#define FX_LANG_Greenlandic_Greenland 0x046f
+#define FX_LANG_Guarani 0x0474
+#define FX_LANG_Gujarati_India 0x0447
+#define FX_LANG_Hausa_LatinNigeria 0x0468
+#define FX_LANG_Hawaiian 0x0475
+#define FX_LANG_Hebrew_Israel 0x040d
+#define FX_LANG_Hindi_India 0x0439
+#define FX_LANG_Hungarian_Hungary 0x040e
+#define FX_LANG_Ibibio_Nigeria 0x0469
+#define FX_LANG_Icelandic_Iceland 0x040f
+#define FX_LANG_Igbo_Nigeria 0x0470
+#define FX_LANG_Indonesian_Indonesia 0x0421
+#define FX_LANG_Inuktitut_LatinCanada 0x085d
+#define FX_LANG_Inuktitut_SyllabicsCanada 0x045d
+#define FX_LANG_IsiXhosa_SouthAfrica 0x0434
+#define FX_LANG_IsiZulu_SouthAfrica 0x0435
+#define FX_LANG_Italian_Italy 0x0410
+#define FX_LANG_Italian_Switzerland 0x0810
+#define FX_LANG_Japanese_Japan 0x0411
+#define FX_LANG_Kannada_India 0x044b
+#define FX_LANG_Kanuri 0x0471
+#define FX_LANG_Kashmiri 0x0860
+#define FX_LANG_Kashmiri_Arabic 0x0460
+#define FX_LANG_Kazakh_Kazakhstan 0x043f
+#define FX_LANG_Khmer_Cambodia 0x0453
+#define FX_LANG_Kiche_Guatemala 0x0486
+#define FX_LANG_Kinyarwanda_Rwanda 0x0487
+#define FX_LANG_Kiswahili_Kenya 0x0441
+#define FX_LANG_Konkani_India 0x0457
+#define FX_LANG_Korean_Korea 0x0412
+#define FX_LANG_Kyrgyz_Kyrgyzstan 0x0440
+#define FX_LANG_Lao_LaoPDR 0x0454
+#define FX_LANG_Latin 0x0476
+#define FX_LANG_Latvian_Latvia 0x0426
+#define FX_LANG_Lithuanian_Lithuania 0x0427
+#define FX_LANG_LithuanianTrad 0x0827
+#define FX_LANG_Lower Sorbian_Germany 0x082e
+#define FX_LANG_Luxembourgish_Luxembourg 0x046e
+#define FX_LANG_Macedonian 0x042f
+#define FX_LANG_Malay_BruneiDarussalam 0x083e
+#define FX_LANG_Malay_Malaysia 0x043e
+#define FX_LANG_Malayalam_India 0x044c
+#define FX_LANG_Maldivian 0x0465
+#define FX_LANG_Maltese_Malta 0x043a
+#define FX_LANG_Manipuri 0x0458
+#define FX_LANG_Maori_NewZealand 0x0481
+#define FX_LANG_Mapudungun_Chile 0x047a
+#define FX_LANG_Marathi_India 0x044e
+#define FX_LANG_Mohawk_Mohawk 0x047c
+#define FX_LANG_Mongolian_CyrillicMongolia 0x0450
+#define FX_LANG_Mongolian_TraditionalMongolian 0x0850
+#define FX_LANG_Nepali_India 0x0861
+#define FX_LANG_Nepali_Nepal 0x0461
+#define FX_LANG_Norwegian_Bokmal 0x0414
+#define FX_LANG_Norwegian_Nynorsk 0x0814
+#define FX_LANG_Occitan_France 0x0482
+#define FX_LANG_Oriya_India 0x0448
+#define FX_LANG_Oromo 0x0472
+#define FX_LANG_Papiamentu 0x0479
+#define FX_LANG_Pashto_Afghanistan 0x0463
+#define FX_LANG_Persian 0x0429
+#define FX_LANG_Polish_Poland 0x0415
+#define FX_LANG_Portuguese_Brazil 0x0416
+#define FX_LANG_Portuguese_Portugal 0x0816
+#define FX_LANG_Punjabi_India 0x0446
+#define FX_LANG_Punjabi_Pakistan 0x0846
+#define FX_LANG_Quechua_Bolivia 0x046b
+#define FX_LANG_Quechua_Ecuador 0x086b
+#define FX_LANG_Quechua_Peru 0x0c6b
+#define FX_LANG_Romanian_Moldova 0x0818
+#define FX_LANG_Romanian_Romania 0x0418
+#define FX_LANG_Romansh_Switzerland 0x0417
+#define FX_LANG_Russian_Moldova 0x0819
+#define FX_LANG_Russian_Russia 0x0419
+#define FX_LANG_Sami_InariFinland 0x243b
+#define FX_LANG_Sami_LuleNorway 0x103b
+#define FX_LANG_Sami_LuleSweden 0x143b
+#define FX_LANG_Sami_NorthernFinland 0x0c3b
+#define FX_LANG_Sami_NorthernNorway 0x043b
+#define FX_LANG_Sami_NorthernSweden 0x083b
+#define FX_LANG_Sami_SkoltFinland 0x203b
+#define FX_LANG_Sami_SouthernNorway 0x183b
+#define FX_LANG_Sami_SouthernSweden 0x1c3b
+#define FX_LANG_SanskritIndia 0x044f
+#define FX_LANG_SerbianCyrillic_BosniaHerzegovina 0x1c1a
+#define FX_LANG_SerbianCyrillic_Serbia 0x0c1a
+#define FX_LANG_SerbianLatin_BosniaHerzegovina 0x181a
+#define FX_LANG_SerbianLatin_Serbia 0x081a
+#define FX_LANG_SesothoSaLeboa 0x046c
+#define FX_LANG_Setswana_SouthAfrica 0x0432
+#define FX_LANG_Sindhi_Arabic 0x0859
+#define FX_LANG_Sindhi_Devanagari 0x0459
+#define FX_LANG_Sinhala_SriLanka 0x045b
+#define FX_LANG_Slovak_Slovakia 0x041b
+#define FX_LANG_Slovenian_Slovenia 0x0424
+#define FX_LANG_Somali 0x0477
+#define FX_LANG_Spanish_Argentina 0x2c0a
+#define FX_LANG_Spanish_Bolivia 0x400a
+#define FX_LANG_Spanish_Chile 0x340a
+#define FX_LANG_Spanish_Colombia 0x240a
+#define FX_LANG_Spanish_CostaRica 0x140a
+#define FX_LANG_Spanish_DominicanRepublic 0x1c0a
+#define FX_LANG_Spanish_Ecuador 0x300a
+#define FX_LANG_Spanish_ElSalvador 0x440a
+#define FX_LANG_Spanish_Guatemala 0x100a
+#define FX_LANG_Spanish_Honduras 0x480a
+#define FX_LANG_Spanish_Mexico 0x080a
+#define FX_LANG_Spanish_Nicaragua 0x4c0a
+#define FX_LANG_Spanish_Panama 0x180a
+#define FX_LANG_Spanish_Paraguay 0x3c0a
+#define FX_LANG_Spanish_Peru 0x280a
+#define FX_LANG_Spanish_PuertoRico 0x500a
+#define FX_LANG_Spanish_InternationalSort 0x0c0a
+#define FX_LANG_Spanish_TraditionalSort 0x040a
+#define FX_LANG_Spanish_UnitedStates 0x540a
+#define FX_LANG_Spanish_Uruguay 0x380a
+#define FX_LANG_Spanish_Venezuela 0x200a
+#define FX_LANG_Sutu_SouthAfrica 0x0430
+#define FX_LANG_Swedish_Finland 0x081d
+#define FX_LANG_Swedish_Sweden 0x041d
+#define FX_LANG_Syriac_Syria 0x045a
+#define FX_LANG_Tajik_CyrillicTajikistan 0x0428
+#define FX_LANG_Tamazight_ArabicMorocco 0x045f
+#define FX_LANG_Tamazight_LatinAlgeria 0x085f
+#define FX_LANG_Tamil_India 0x0449
+#define FX_LANG_Tatar_Russia 0x0444
+#define FX_LANG_Telugu_India 0x044a
+#define FX_LANG_Thai_Thailand 0x041e
+#define FX_LANG_TibetanPRC 0x0451
+#define FX_LANG_Tigrigna_Eritrea 0x0873
+#define FX_LANG_Tigrigna_Ethiopia 0x0473
+#define FX_LANG_Tsonga 0x0431
+#define FX_LANG_Turkish_Turkey 0x041f
+#define FX_LANG_Turkmen_Turkmenistan 0x0442
+#define FX_LANG_UighurPRC 0x0480
+#define FX_LANG_Ukrainian_Ukraine 0x0422
+#define FX_LANG_UpperSorbian_Germany 0x042e
+#define FX_LANG_Urdu_Pakistan 0x0420
+#define FX_LANG_Urdu_India 0x0820
+#define FX_LANG_Uzbek_CyrillicUzbekistan 0x0843
+#define FX_LANG_Uzbek_LatinUzbekistan 0x0443
+#define FX_LANG_Venda 0x0433
+#define FX_LANG_Vietnamese_Vietnam 0x042a
+#define FX_LANG_Welsh_UnitedKingdom 0x0452
+#define FX_LANG_Wolof_Senegal 0x0488
+#define FX_LANG_Xhosa 0x0434
+#define FX_LANG_Yakut_Russia 0x0485
+#define FX_LANG_YiPRC 0x0478
+#define FX_LANG_Yiddish 0x043d
+#define FX_LANG_Yoruba_Nigeria 0x046a
+#endif
diff --git a/xfa/src/fgas/include/fx_locale.h b/xfa/src/fgas/include/fx_locale.h
new file mode 100644
index 0000000000..6886974fd2
--- /dev/null
+++ b/xfa/src/fgas/include/fx_locale.h
@@ -0,0 +1,160 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_LOCALE_H_
+#define _FX_LOCALE_H_
+class CFX_Unitime;
+class IFX_Locale;
+class IFX_FormatString;
+class IFX_LocaleMgr;
+enum FX_LOCALENUMSYMBOL {
+ FX_LOCALENUMSYMBOL_Decimal,
+ FX_LOCALENUMSYMBOL_Grouping,
+ FX_LOCALENUMSYMBOL_Percent,
+ FX_LOCALENUMSYMBOL_Minus,
+ FX_LOCALENUMSYMBOL_Zero,
+ FX_LOCALENUMSYMBOL_CurrencySymbol,
+ FX_LOCALENUMSYMBOL_CurrencyName,
+};
+enum FX_LOCALEDATETIMESUBCATEGORY {
+ FX_LOCALEDATETIMESUBCATEGORY_Default,
+ FX_LOCALEDATETIMESUBCATEGORY_Short,
+ FX_LOCALEDATETIMESUBCATEGORY_Medium,
+ FX_LOCALEDATETIMESUBCATEGORY_Full,
+ FX_LOCALEDATETIMESUBCATEGORY_Long,
+};
+enum FX_LOCALENUMSUBCATEGORY {
+ FX_LOCALENUMPATTERN_Percent,
+ FX_LOCALENUMPATTERN_Currency,
+ FX_LOCALENUMPATTERN_Decimal,
+ FX_LOCALENUMPATTERN_Integer,
+};
+enum FX_LOCALECATEGORY {
+ FX_LOCALECATEGORY_Unknown,
+ FX_LOCALECATEGORY_Date,
+ FX_LOCALECATEGORY_Time,
+ FX_LOCALECATEGORY_DateTime,
+ FX_LOCALECATEGORY_Num,
+ FX_LOCALECATEGORY_Text,
+ FX_LOCALECATEGORY_Zero,
+ FX_LOCALECATEGORY_Null,
+};
+enum FX_DATETIMETYPE {
+ FX_DATETIMETYPE_Unknown,
+ FX_DATETIMETYPE_Date,
+ FX_DATETIMETYPE_Time,
+ FX_DATETIMETYPE_DateTime,
+ FX_DATETIMETYPE_TimeDate,
+};
+class IFX_Locale
+{
+public:
+ static IFX_Locale* Create(CXML_Element* pLocaleData);
+
+ virtual void Release() = 0;
+
+
+ virtual CFX_WideString GetName() = 0;
+
+ virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const = 0;
+ virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const = 0;
+ virtual void GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr = TRUE) const = 0;
+ virtual void GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr = TRUE) const = 0;
+ virtual void GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM = TRUE) const = 0;
+ virtual void GetTimeZone(FX_TIMEZONE& tz) const = 0;
+ virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const = 0;
+ virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const = 0;
+ virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const = 0;
+ virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const = 0;
+};
+class IFX_LocaleMgr
+{
+public:
+ virtual void Release() = 0;
+ virtual FX_WORD GetDefLocaleID() = 0;
+ virtual IFX_Locale* GetDefLocale() = 0;
+ virtual IFX_Locale* GetLocale(FX_WORD lcid) = 0;
+ virtual IFX_Locale* GetLocaleByName(FX_WSTR wsLocaleName) = 0;
+};
+IFX_LocaleMgr* FX_LocaleMgr_Create(FX_LPCWSTR pszLocalPath, FX_WORD wDefaultLCID);
+void FX_ParseNumString(const CFX_WideString& wsNum, CFX_WideString& wsResult);
+FX_BOOL FX_DateFromCanonical(const CFX_WideString& wsDate, CFX_Unitime& datetime);
+FX_BOOL FX_TimeFromCanonical(FX_WSTR wsTime, CFX_Unitime& datetime, IFX_Locale* pLocale);
+class IFX_FormatString
+{
+public:
+ static IFX_FormatString* Create(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID);
+
+ virtual void Release() = 0;
+ virtual void SplitFormatString(const CFX_WideString& wsFormatString, CFX_WideStringArray& wsPatterns) = 0;
+ virtual FX_LOCALECATEGORY GetCategory(const CFX_WideString& wsPattern) = 0;
+ virtual FX_WORD GetLCID(const CFX_WideString& wsPattern) = 0;
+ virtual CFX_WideString GetLocaleName(const CFX_WideString& wsPattern) = 0;
+ virtual FX_BOOL ParseText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsValue) = 0;
+ virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, FX_FLOAT &fValue) = 0;
+ virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString &wsValue) = 0;
+ virtual FX_BOOL ParseDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, FX_DATETIMETYPE eDateTimeType, CFX_Unitime& dtValue) = 0;
+ virtual FX_BOOL ParseZero(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern) = 0;
+ virtual FX_BOOL ParseNull(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern) = 0;
+ virtual FX_BOOL FormatText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0;
+ virtual FX_BOOL FormatNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0;
+ virtual FX_BOOL FormatNum(FX_FLOAT fNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0;
+ virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0;
+ virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput, FX_DATETIMETYPE eDateTimeType) = 0;
+ virtual FX_BOOL FormatDateTime(const CFX_Unitime& dt, const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0;
+ virtual FX_BOOL FormatZero(const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0;
+ virtual FX_BOOL FormatNull(const CFX_WideString& wsPattern, CFX_WideString& wsOutput) = 0;
+};
+class CFX_Decimal : CFX_Object
+{
+public:
+ CFX_Decimal();
+ CFX_Decimal(FX_UINT32 val);
+ CFX_Decimal(FX_UINT64 val);
+ CFX_Decimal(FX_INT32 val);
+ CFX_Decimal(FX_INT64 val);
+ CFX_Decimal(FX_FLOAT val, FX_UINT8 scale = 3);
+ CFX_Decimal(FX_WSTR str);
+ CFX_Decimal(FX_BSTR str);
+ operator CFX_WideString() const;
+ operator double() const;
+ FX_BOOL operator == (const CFX_Decimal& val) const;
+ FX_BOOL operator <= (const CFX_Decimal& val) const;
+ FX_BOOL operator >= (const CFX_Decimal& val) const;
+ FX_BOOL operator != (const CFX_Decimal& val) const;
+ FX_BOOL operator < (const CFX_Decimal& val) const;
+ FX_BOOL operator > (const CFX_Decimal& val) const;
+ CFX_Decimal operator + (const CFX_Decimal& val) const;
+ CFX_Decimal operator - (const CFX_Decimal& val) const;
+ CFX_Decimal operator * (const CFX_Decimal& val) const;
+ CFX_Decimal operator / (const CFX_Decimal& val) const;
+ CFX_Decimal operator % (const CFX_Decimal& val) const;
+ void SetScale(FX_UINT8 newScale);
+ FX_UINT8 GetScale();
+ void SetAbs();
+ void SetNegate();
+ void SetFloor();
+ void SetCeiling();
+ void SetTruncate();
+protected:
+ CFX_Decimal(FX_UINT32 hi, FX_UINT32 mid, FX_UINT32 lo, FX_BOOL neg, FX_UINT8 scale);
+ inline FX_BOOL IsNotZero() const
+ {
+ return m_uHi || m_uMid || m_uLo;
+ }
+ inline FX_INT8 Compare (const CFX_Decimal& val) const;
+ inline void Swap(CFX_Decimal& val);
+ inline void FloorOrCeil(FX_BOOL bFloor);
+ CFX_Decimal AddOrMinus(const CFX_Decimal& val, FX_BOOL isAdding) const;
+ CFX_Decimal Multiply(const CFX_Decimal& val) const;
+ CFX_Decimal Divide(const CFX_Decimal& val) const;
+ CFX_Decimal Modulus(const CFX_Decimal& val) const;
+ FX_UINT32 m_uFlags;
+ FX_UINT32 m_uHi;
+ FX_UINT32 m_uLo;
+ FX_UINT32 m_uMid;
+};
+#endif
diff --git a/xfa/src/fgas/include/fx_mem.h b/xfa/src/fgas/include/fx_mem.h
new file mode 100644
index 0000000000..18cd85e422
--- /dev/null
+++ b/xfa/src/fgas/include/fx_mem.h
@@ -0,0 +1,58 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_MEMORY
+#define _FX_MEMORY
+class IFX_MEMAllocator;
+class CFX_Target;
+enum FX_ALLOCTYPE {
+ FX_ALLOCTYPE_Default = 0,
+ FX_ALLOCTYPE_Static ,
+ FX_ALLOCTYPE_Fixed ,
+ FX_ALLOCTYPE_Dynamic ,
+};
+class IFX_MEMAllocator
+{
+public:
+ virtual void Release() = 0;
+ virtual void* Alloc(size_t size) = 0;
+ virtual void Free(void *pBlock) = 0;
+ virtual size_t GetBlockSize() const = 0;
+ virtual size_t GetDefChunkSize() const = 0;
+ virtual size_t SetDefChunkSize(size_t size) = 0;
+ virtual size_t GetCurrentDataSize() const = 0;
+};
+IFX_MEMAllocator* FX_CreateAllocator(FX_ALLOCTYPE eType, size_t chunkSize, size_t blockSize);
+class CFX_Target
+{
+public:
+ void* operator new(size_t size)
+ {
+ return FX_Alloc(FX_BYTE, size);
+ }
+ void operator delete(void *p)
+ {
+ FX_Free(p);
+ }
+ void* operator new(size_t size, IFX_MEMAllocator *pAllocator)
+ {
+ return pAllocator->Alloc(size);
+ }
+ void operator delete(void *p, IFX_MEMAllocator *pAllocator)
+ {
+ pAllocator->Free(p);
+ }
+ void* operator new(size_t size, void *place)
+ {
+ return place;
+ }
+ void operator delete(void *p, void *place) {}
+};
+#define FXTARGET_New new
+#define FXTARGET_NewWith(__allocator__) new(__allocator__)
+#define FXTARGET_Delete delete
+#define FXTARGET_DeleteWith(__class__, __allocator__, pointer) {(pointer)->~__class__(); (pointer)->operator delete((pointer), (__allocator__));}
+#endif
diff --git a/xfa/src/fgas/include/fx_rbk.h b/xfa/src/fgas/include/fx_rbk.h
new file mode 100644
index 0000000000..3053fc5e1b
--- /dev/null
+++ b/xfa/src/fgas/include/fx_rbk.h
@@ -0,0 +1,235 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_RTFBREAK
+#define _FX_RTFBREAK
+class IFX_Unknown;
+class IFX_Font;
+class CFX_Char;
+class CFX_RTFChar;
+class CFX_RTFBreakPiece;
+class IFX_RTFBreak;
+#define FX_RTFBREAKPOLICY_None 0x00
+#define FX_RTFBREAKPOLICY_SpaceBreak 0x01
+#define FX_RTFBREAKPOLICY_NumberBreak 0x02
+#define FX_RTFBREAKPOLICY_InfixBreak 0x04
+#define FX_RTFBREAKPOLICY_TabBreak 0x08
+#define FX_RTFBREAKPOLICY_OrphanPositionedTab 0x10
+#define FX_RTFBREAK_None 0x00
+#define FX_RTFBREAK_PieceBreak 0x01
+#define FX_RTFBREAK_LineBreak 0x02
+#define FX_RTFBREAK_ParagraphBreak 0x03
+#define FX_RTFBREAK_PageBreak 0x04
+#define FX_RTFLAYOUTSTYLE_Pagination 0x01
+#define FX_RTFLAYOUTSTYLE_VerticalLayout 0x02
+#define FX_RTFLAYOUTSTYLE_VerticalChars 0x04
+#define FX_RTFLAYOUTSTYLE_LineDirection 0x08
+#define FX_RTFLAYOUTSTYLE_ExpandTab 0x10
+#define FX_RTFLAYOUTSTYLE_ArabicNumber 0x20
+#define FX_RTFLAYOUTSTYLE_SingleLine 0x40
+#define FX_RTFLAYOUTSTYLE_MBCSCode 0x80
+#define FX_RTFCHARSTYLE_Alignment 0x000F
+#define FX_RTFCHARSTYLE_ArabicNumber 0x0010
+#define FX_RTFCHARSTYLE_ArabicShadda 0x0020
+#define FX_RTFCHARSTYLE_OddBidiLevel 0x0040
+#define FX_RTFCHARSTYLE_RTLReadingOrder 0x0080
+#define FX_RTFCHARSTYLE_ArabicContext 0x0300
+#define FX_RTFCHARSTYLE_ArabicIndic 0x0400
+#define FX_RTFCHARSTYLE_ArabicComma 0x0800
+#define FX_RTFLINEALIGNMENT_Left 0
+#define FX_RTFLINEALIGNMENT_Center 1
+#define FX_RTFLINEALIGNMENT_Right 2
+#define FX_RTFLINEALIGNMENT_Justified (1 << 2)
+#define FX_RTFLINEALIGNMENT_Distributed (2 << 2)
+#define FX_RTFLINEALIGNMENT_JustifiedLeft (FX_RTFLINEALIGNMENT_Left | FX_RTFLINEALIGNMENT_Justified)
+#define FX_RTFLINEALIGNMENT_JustifiedCenter (FX_RTFLINEALIGNMENT_Center | FX_RTFLINEALIGNMENT_Justified)
+#define FX_RTFLINEALIGNMENT_JustifiedRight (FX_RTFLINEALIGNMENT_Right | FX_RTFLINEALIGNMENT_Justified)
+#define FX_RTFLINEALIGNMENT_DistributedLeft (FX_RTFLINEALIGNMENT_Left | FX_RTFLINEALIGNMENT_Distributed)
+#define FX_RTFLINEALIGNMENT_DistributedCenter (FX_RTFLINEALIGNMENT_Center | FX_RTFLINEALIGNMENT_Distributed)
+#define FX_RTFLINEALIGNMENT_DistributedRight (FX_RTFLINEALIGNMENT_Right | FX_RTFLINEALIGNMENT_Distributed)
+#define FX_RTFLINEALIGNMENT_LowerMask 0x03
+#define FX_RTFLINEALIGNMENT_HigherMask 0x0C
+typedef struct _FX_RTFTEXTOBJ {
+ _FX_RTFTEXTOBJ()
+ {
+ pStr = NULL;
+ pWidths = NULL;
+ iLength = 0;
+ pFont = NULL;
+ fFontSize = 12.0f;
+ dwLayoutStyles = 0;
+ iCharRotation = 0;
+ iBidiLevel = 0;
+ pRect = NULL;
+ wLineBreakChar = L'\n';
+ iHorizontalScale = 100;
+ iVerticalScale = 100;
+ }
+ FX_LPCWSTR pStr;
+ FX_INT32 *pWidths;
+ FX_INT32 iLength;
+ IFX_Font *pFont;
+ FX_FLOAT fFontSize;
+ FX_DWORD dwLayoutStyles;
+ FX_INT32 iCharRotation;
+ FX_INT32 iBidiLevel;
+ FX_LPCRECTF pRect;
+ FX_WCHAR wLineBreakChar;
+ FX_INT32 iHorizontalScale;
+ FX_INT32 iVerticalScale;
+} FX_RTFTEXTOBJ, * FX_LPRTFTEXTOBJ;
+typedef FX_RTFTEXTOBJ const * FX_LPCRTFTEXTOBJ;
+class CFX_RTFPiece : public CFX_Target
+{
+public:
+ CFX_RTFPiece() : m_dwStatus(FX_RTFBREAK_PieceBreak)
+ , m_iStartPos(0)
+ , m_iWidth(-1)
+ , m_iStartChar(0)
+ , m_iChars(0)
+ , m_iBidiLevel(0)
+ , m_iBidiPos(0)
+ , m_iFontSize(0)
+ , m_iFontHeight(0)
+ , m_iHorizontalScale(100)
+ , m_iVerticalScale(100)
+ , m_dwLayoutStyles(0)
+ , m_dwIdentity(0)
+ , m_pChars(NULL)
+ , m_pUserData(NULL)
+ {
+ }
+ ~CFX_RTFPiece()
+ {
+ Reset();
+ }
+ void AppendChar(const CFX_RTFChar &tc)
+ {
+ FXSYS_assert(m_pChars != NULL);
+ m_pChars->Add(tc);
+ if (m_iWidth < 0) {
+ m_iWidth = tc.m_iCharWidth;
+ } else {
+ m_iWidth += tc.m_iCharWidth;
+ }
+ m_iChars ++;
+ }
+ FX_INT32 GetEndPos() const
+ {
+ return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth;
+ }
+ FX_INT32 GetLength() const
+ {
+ return m_iChars;
+ }
+ FX_INT32 GetEndChar() const
+ {
+ return m_iStartChar + m_iChars;
+ }
+ CFX_RTFChar& GetChar(FX_INT32 index)
+ {
+ FXSYS_assert(index > -1 && index < m_iChars && m_pChars != NULL);
+ return *m_pChars->GetDataPtr(m_iStartChar + index);
+ }
+ CFX_RTFChar* GetCharPtr(FX_INT32 index) const
+ {
+ FXSYS_assert(index > -1 && index < m_iChars && m_pChars != NULL);
+ return m_pChars->GetDataPtr(m_iStartChar + index);
+ }
+ void GetString (FX_LPWSTR pText) const
+ {
+ FXSYS_assert(pText != NULL);
+ FX_INT32 iEndChar = m_iStartChar + m_iChars;
+ CFX_RTFChar *pChar;
+ for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) {
+ pChar = m_pChars->GetDataPtr(i);
+ *pText ++ = (FX_WCHAR)pChar->m_wCharCode;
+ }
+ }
+ void GetString(CFX_WideString &wsText) const
+ {
+ FX_LPWSTR pText = wsText.GetBuffer(m_iChars);
+ GetString(pText);
+ wsText.ReleaseBuffer(m_iChars);
+ }
+ void GetWidths(FX_INT32 *pWidths) const
+ {
+ FXSYS_assert(pWidths != NULL);
+ FX_INT32 iEndChar = m_iStartChar + m_iChars;
+ CFX_RTFChar *pChar;
+ for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) {
+ pChar = m_pChars->GetDataPtr(i);
+ *pWidths ++ = pChar->m_iCharWidth;
+ }
+ }
+ void Reset()
+ {
+ m_dwStatus = FX_RTFBREAK_PieceBreak;
+ if (m_iWidth > -1) {
+ m_iStartPos += m_iWidth;
+ }
+ m_iWidth = -1;
+ m_iStartChar += m_iChars;
+ m_iChars = 0;
+ m_iBidiLevel = 0;
+ m_iBidiPos = 0;
+ m_iHorizontalScale = 100;
+ m_iVerticalScale = 100;
+ }
+ FX_DWORD m_dwStatus;
+ FX_INT32 m_iStartPos;
+ FX_INT32 m_iWidth;
+ FX_INT32 m_iStartChar;
+ FX_INT32 m_iChars;
+ FX_INT32 m_iBidiLevel;
+ FX_INT32 m_iBidiPos;
+ FX_INT32 m_iFontSize;
+ FX_INT32 m_iFontHeight;
+ FX_INT32 m_iHorizontalScale;
+ FX_INT32 m_iVerticalScale;
+ FX_DWORD m_dwLayoutStyles;
+ FX_DWORD m_dwIdentity;
+ CFX_RTFCharArray *m_pChars;
+ IFX_Unknown *m_pUserData;
+};
+typedef CFX_BaseArrayTemplate<CFX_RTFPiece> CFX_RTFPieceArray;
+class IFX_RTFBreak
+{
+public:
+ static IFX_RTFBreak* Create(FX_DWORD dwPolicies);
+ virtual void Release() = 0;
+ virtual void SetLineWidth(FX_FLOAT fLineStart, FX_FLOAT fLineEnd) = 0;
+ virtual void SetLinePos(FX_FLOAT fLinePos) = 0;
+ virtual FX_DWORD GetLayoutStyles() const = 0;
+ virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles) = 0;
+ virtual void SetFont(IFX_Font *pFont) = 0;
+ virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
+ virtual void SetTabWidth(FX_FLOAT fTabWidth) = 0;
+ virtual void AddPositionedTab(FX_FLOAT fTabPos) = 0;
+ virtual void SetPositionedTabs(const CFX_FloatArray &tabs) = 0;
+ virtual void ClearPositionedTabs() = 0;
+ virtual void SetDefaultChar(FX_WCHAR wch) = 0;
+ virtual void SetLineBreakChar(FX_WCHAR wch) = 0;
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance) = 0;
+ virtual void SetHorizontalScale(FX_INT32 iScale) = 0;
+ virtual void SetVerticalScale(FX_INT32 iScale) = 0;
+ virtual void SetCharRotation(FX_INT32 iCharRotation) = 0;
+ virtual void SetCharSpace(FX_FLOAT fCharSpace) = 0;
+ virtual void SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace) = 0;
+ virtual void SetReadingOrder(FX_BOOL bRTL = FALSE) = 0;
+ virtual void SetAlignment(FX_INT32 iAlignment = FX_RTFLINEALIGNMENT_Left) = 0;
+ virtual void SetUserData(IFX_Unknown *pUserData) = 0;
+ virtual FX_DWORD AppendChar(FX_WCHAR wch) = 0;
+ virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_RTFBREAK_PieceBreak) = 0;
+ virtual FX_INT32 CountBreakPieces() const = 0;
+ virtual const CFX_RTFPiece* GetBreakPiece(FX_INT32 index) const = 0;
+ virtual void GetLineRect(CFX_RectF &rect) const = 0;
+ virtual void ClearBreakPieces() = 0;
+ virtual void Reset() = 0;
+ virtual FX_INT32 GetDisplayPos(FX_LPCRTFTEXTOBJ pText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const = 0;
+ virtual FX_INT32 GetCharRects(FX_LPCRTFTEXTOBJ pText, CFX_RectFArray &rtArray, FX_BOOL bCharBBox = FALSE) const = 0;
+};
+#endif
diff --git a/xfa/src/fgas/include/fx_sax.h b/xfa/src/fgas/include/fx_sax.h
new file mode 100644
index 0000000000..c0159f8c22
--- /dev/null
+++ b/xfa/src/fgas/include/fx_sax.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_SAX_
+#define _FX_SAX_
+class IFX_SAXReaderHandler;
+class IFX_SAXReader;
+#define FX_SAXPARSEMODE_NotConvert_amp 0x0001
+#define FX_SAXPARSEMODE_NotConvert_lt 0x0002
+#define FX_SAXPARSEMODE_NotConvert_gt 0x0004
+#define FX_SAXPARSEMODE_NotConvert_apos 0x0008
+#define FX_SAXPARSEMODE_NotConvert_quot 0x0010
+#define FX_SAXPARSEMODE_NotConvert_sharp 0x0020
+#define FX_SAXPARSEMODE_NotSkipSpace 0x0100
+enum FX_SAXNODE {
+ FX_SAXNODE_Unknown = 0,
+ FX_SAXNODE_Instruction,
+ FX_SAXNODE_Declaration,
+ FX_SAXNODE_Comment,
+ FX_SAXNODE_Tag,
+ FX_SAXNODE_Text,
+ FX_SAXNODE_CharData,
+};
+class IFX_SAXReaderHandler
+{
+public:
+ virtual FX_LPVOID OnTagEnter(FX_BSTR bsTagName, FX_SAXNODE eType, FX_DWORD dwStartPos) = 0;
+ virtual void OnTagAttribute(FX_LPVOID pTag, FX_BSTR bsAttri, FX_BSTR bsValue) = 0;
+ virtual void OnTagBreak(FX_LPVOID pTag) = 0;
+ virtual void OnTagData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos) = 0;
+ virtual void OnTagClose(FX_LPVOID pTag, FX_DWORD dwEndPos) = 0;
+ virtual void OnTagEnd(FX_LPVOID pTag, FX_BSTR bsTagName, FX_DWORD dwEndPos) = 0;
+ virtual void OnTargetData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos) = 0;
+};
+class IFX_SAXReader
+{
+public:
+ virtual void Release() = 0;
+ virtual FX_INT32 StartParse(IFX_FileRead *pFile, FX_DWORD dwStart = 0, FX_DWORD dwLen = -1, FX_DWORD dwParseMode = 0) = 0;
+ virtual FX_INT32 ContinueParse(IFX_Pause *pPause = NULL) = 0;
+ virtual void SkipCurrentNode() = 0;
+ virtual void SetHandler(IFX_SAXReaderHandler *pHandler) = 0;
+};
+IFX_SAXReader* FX_SAXReader_Create();
+#endif
diff --git a/xfa/src/fgas/include/fx_stm.h b/xfa/src/fgas/include/fx_stm.h
new file mode 100644
index 0000000000..ae424dba2d
--- /dev/null
+++ b/xfa/src/fgas/include/fx_stm.h
@@ -0,0 +1,60 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_STREAM
+#define _FX_STREAM
+class IFX_Stream;
+IFX_FileRead* FX_CreateFileRead(IFX_Stream *pBaseStream, FX_BOOL bReleaseStream = FALSE);
+#ifdef FX_FILESIZE
+IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_FILESIZE iFileSize = -1, FX_BOOL bReleaseStream = TRUE);
+#else
+IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize = -1, FX_BOOL bReleaseStream = TRUE);
+#endif
+IFX_FileWrite* FX_CreateFileWrite(IFX_Stream *pBaseStream, FX_BOOL bReleaseStream = FALSE);
+enum FX_STREAMACCESS {
+ FX_STREAMACCESS_Binary = 0x00,
+ FX_STREAMACCESS_Text = 0x01,
+ FX_STREAMACCESS_Read = 0x02,
+ FX_STREAMACCESS_Write = 0x04,
+ FX_STREAMACCESS_Truncate = 0x10,
+ FX_STREAMACCESS_Append = 0x20,
+ FX_STREAMACCESS_Create = 0x80,
+};
+enum FX_STREAMSEEK {
+ FX_STREAMSEEK_Begin = 0 ,
+ FX_STREAMSEEK_Current ,
+ FX_STREAMSEEK_End ,
+};
+class IFX_Stream
+{
+public:
+ static IFX_Stream* CreateStream(IFX_FileRead *pFileRead, FX_DWORD dwAccess);
+ static IFX_Stream* CreateStream(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess);
+ static IFX_Stream* CreateStream(FX_LPCWSTR pszFileName, FX_DWORD dwAccess);
+ static IFX_Stream* CreateStream(FX_LPBYTE pData, FX_INT32 length, FX_DWORD dwAccess);
+ static IFX_Stream* CreateStream(IFX_BufferRead *pBufferRead, FX_DWORD dwAccess, FX_INT32 iFileSize = -1, FX_BOOL bReleaseBufferRead = TRUE);
+ static IFX_Stream* CreateTextStream(IFX_Stream *pBaseStream, FX_BOOL bDeleteOnRelease);
+ virtual void Release() = 0;
+ virtual IFX_Stream* Retain() = 0;
+ virtual FX_DWORD GetAccessModes() const = 0;
+ virtual FX_INT32 GetLength() const = 0;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) = 0;
+ virtual FX_INT32 GetPosition() = 0;
+ virtual FX_BOOL IsEOF() const = 0;
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) = 0;
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize = NULL) = 0;
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) = 0;
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) = 0;
+ virtual void Flush() = 0;
+ virtual FX_BOOL SetLength(FX_INT32 iLength) = 0;
+ virtual FX_INT32 GetBOM(FX_BYTE bom[4]) const = 0;
+ virtual FX_WORD GetCodePage() const = 0;
+ virtual FX_WORD SetCodePage(FX_WORD wCodePage) = 0;
+ virtual void Lock() = 0;
+ virtual void Unlock() = 0;
+ virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength) = 0;
+};
+#endif
diff --git a/xfa/src/fgas/include/fx_sys.h b/xfa/src/fgas/include/fx_sys.h
new file mode 100644
index 0000000000..c0b5c7445f
--- /dev/null
+++ b/xfa/src/fgas/include/fx_sys.h
@@ -0,0 +1,63 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_SYSTEM
+#define _FX_SYSTEM
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define FX_RAD2DEG(r) ((r) * 180.0f / FX_PI)
+#define FX_DEG2RAD(a) ((a) * FX_PI / 180.0f)
+typedef FX_INT8 * FX_LPINT8;
+typedef FX_INT8 const * FX_LPCINT8;
+typedef FX_INT32 * FX_LPINT32;
+typedef FX_INT32 const * FX_LPCINT32;
+typedef long FX_LONG;
+typedef FX_LONG * FX_LPLONG;
+typedef FX_LONG const * FX_LPCLONG;
+typedef FX_FLOAT const * FX_LPCFLOAT;
+typedef double FX_DOUBLE;
+typedef FX_DOUBLE * FX_LPDOUBLE;
+typedef FX_DOUBLE const * FX_LPCDOUBLE;
+FX_FLOAT FX_tan(FX_FLOAT a);
+FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x);
+FX_FLOAT FX_strtof(FX_LPCSTR pcsStr, FX_INT32 iLength = -1, FX_INT32 *pUsedLen = NULL);
+FX_FLOAT FX_wcstof(FX_LPCWSTR pwsStr, FX_INT32 iLength = -1, FX_INT32 *pUsedLen = NULL);
+FX_LPWSTR FX_wcsncpy(FX_LPWSTR dstStr, FX_LPCWSTR srcStr, size_t count);
+FX_INT32 FX_wcsnicmp(FX_LPCWSTR s1, FX_LPCWSTR s2, size_t count);
+FX_INT32 FX_strnicmp(FX_LPCSTR s1, FX_LPCSTR s2, size_t count);
+inline FX_BOOL FX_islower(FX_INT32 ch)
+{
+ return ch >= 'a' && ch <= 'z';
+}
+inline FX_BOOL FX_isupper(FX_INT32 ch)
+{
+ return ch >= 'A' && ch <= 'Z';
+}
+inline FX_INT32 FX_tolower(FX_INT32 ch)
+{
+ return FX_isupper(ch) ? (ch + 0x20) : ch;
+}
+inline FX_INT32 FX_toupper(FX_INT32 ch)
+{
+ return FX_islower(ch) ? (ch - 0x20) : ch;
+}
+FX_INT32 FX_filelength(FXSYS_FILE *file);
+FX_BOOL FX_fsetsize(FXSYS_FILE *file, FX_INT32 size);
+void FX_memset(FX_LPVOID pBuf, FX_INT32 iValue, size_t size);
+void FX_memcpy(FX_LPVOID pDst, FX_LPCVOID pSrc, size_t size);
+FX_BOOL FX_IsRelativePath(const CFX_WideStringC &wsPath);
+FX_BOOL FX_JoinPath(const CFX_WideStringC &wsBasePath, const CFX_WideStringC &wsRelativePath, CFX_WideString &wsAbsolutePath);
+typedef struct _FX_VERSION {
+ FX_DWORD dwMajorVersion;
+ FX_DWORD dwMinorVersion;
+ FX_DWORD dwBuildVersion;
+} FX_VERSION, * FX_LPVERSION;
+typedef FX_VERSION const * FX_LPCVERSION;
+#ifdef __cplusplus
+};
+#endif
+#endif
diff --git a/xfa/src/fgas/include/fx_tbk.h b/xfa/src/fgas/include/fx_tbk.h
new file mode 100644
index 0000000000..ab64d1dac0
--- /dev/null
+++ b/xfa/src/fgas/include/fx_tbk.h
@@ -0,0 +1,211 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_TEXTBREAK
+#define _FX_TEXTBREAK
+class IFX_Font;
+class CFX_Char;
+class IFX_TxtAccess;
+class CFX_TxtChar;
+class CFX_TxtPiece;
+class IFX_TxtBreak;
+#define FX_TXTBREAKPOLICY_None 0x00
+#define FX_TXTBREAKPOLICY_Pagination 0x01
+#define FX_TXTBREAKPOLICY_SpaceBreak 0x02
+#define FX_TXTBREAKPOLICY_NumberBreak 0x04
+#define FX_TXTBREAK_None 0x00
+#define FX_TXTBREAK_PieceBreak 0x01
+#define FX_TXTBREAK_LineBreak 0x02
+#define FX_TXTBREAK_ParagraphBreak 0x03
+#define FX_TXTBREAK_PageBreak 0x04
+#define FX_TXTBREAK_ControlChar 0x10
+#define FX_TXTBREAK_BreakChar 0x20
+#define FX_TXTBREAK_UnknownChar 0x40
+#define FX_TXTBREAK_RemoveChar 0x80
+#define FX_TXTLAYOUTSTYLE_MutipleFormat 0x0001
+#define FX_TXTLAYOUTSTYLE_VerticalLayout 0x0002
+#define FX_TXTLAYOUTSTYLE_VerticalChars 0x0004
+#define FX_TXTLAYOUTSTYLE_ReverseLine 0x0008
+#define FX_TXTLAYOUTSTYLE_ArabicContext 0x0010
+#define FX_TXTLAYOUTSTYLE_ArabicShapes 0x0020
+#define FX_TXTLAYOUTSTYLE_RTLReadingOrder 0x0040
+#define FX_TXTLAYOUTSTYLE_ExpandTab 0x0100
+#define FX_TXTLAYOUTSTYLE_SingleLine 0x0200
+#define FX_TXTLAYOUTSTYLE_CombText 0x0400
+#define FX_TXTCHARSTYLE_Alignment 0x000F
+#define FX_TXTCHARSTYLE_ArabicNumber 0x0010
+#define FX_TXTCHARSTYLE_ArabicShadda 0x0020
+#define FX_TXTCHARSTYLE_OddBidiLevel 0x0040
+#define FX_TXTCHARSTYLE_RTLReadingOrder 0x0080
+#define FX_TXTCHARSTYLE_ArabicContext 0x0300
+#define FX_TXTCHARSTYLE_ArabicIndic 0x0400
+#define FX_TXTCHARSTYLE_ArabicComma 0x0800
+#define FX_TXTLINEALIGNMENT_Left 0
+#define FX_TXTLINEALIGNMENT_Center 1
+#define FX_TXTLINEALIGNMENT_Right 2
+#define FX_TXTLINEALIGNMENT_Justified (1 << 2)
+#define FX_TXTLINEALIGNMENT_Distributed (2 << 2)
+#define FX_TXTLINEALIGNMENT_JustifiedLeft (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Justified)
+#define FX_TXTLINEALIGNMENT_JustifiedCenter (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Justified)
+#define FX_TXTLINEALIGNMENT_JustifiedRight (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Justified)
+#define FX_TXTLINEALIGNMENT_DistributedLeft (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Distributed)
+#define FX_TXTLINEALIGNMENT_DistributedCenter (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Distributed)
+#define FX_TXTLINEALIGNMENT_DistributedRight (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Distributed)
+#define FX_TXTLINEALIGNMENT_LowerMask 0x03
+#define FX_TXTLINEALIGNMENT_HigherMask 0x0C
+#define FX_TXTBREAK_MinimumTabWidth 160000
+class IFX_TxtAccess
+{
+public:
+ virtual FX_WCHAR GetChar(FX_LPVOID pIdentity, FX_INT32 index) const = 0;
+ virtual FX_INT32 GetWidth(FX_LPVOID pIdentity, FX_INT32 index) const = 0;
+};
+typedef struct _FX_TXTRUN {
+ _FX_TXTRUN()
+ {
+ pAccess = NULL;
+ pIdentity = NULL;
+ pStr = NULL;
+ pWidths = NULL;
+ iLength = 0;
+ pFont = NULL;
+ fFontSize = 12;
+ dwStyles = 0;
+ iHorizontalScale = 100;
+ iVerticalScale = 100;
+ iCharRotation = 0;
+ dwCharStyles = 0;
+ pRect = NULL;
+ wLineBreakChar = L'\n';
+ bSkipSpace = TRUE;
+ }
+ IFX_TxtAccess *pAccess;
+ FX_LPVOID pIdentity;
+ FX_LPCWSTR pStr;
+ FX_INT32 *pWidths;
+ FX_INT32 iLength;
+ IFX_Font *pFont;
+ FX_FLOAT fFontSize;
+ FX_DWORD dwStyles;
+ FX_INT32 iHorizontalScale;
+ FX_INT32 iVerticalScale;
+ FX_INT32 iCharRotation;
+ FX_DWORD dwCharStyles;
+ FX_LPCRECTF pRect;
+ FX_WCHAR wLineBreakChar;
+ FX_BOOL bSkipSpace;
+} FX_TXTRUN, * FX_LPTXTRUN;
+typedef FX_TXTRUN const * FX_LPCTXTRUN;
+class CFX_TxtPiece : public CFX_Target
+{
+public:
+ CFX_TxtPiece() : m_dwStatus(FX_TXTBREAK_PieceBreak)
+ , m_iStartPos(0)
+ , m_iWidth(-1)
+ , m_iStartChar(0)
+ , m_iChars(0)
+ , m_iBidiLevel(0)
+ , m_iBidiPos(0)
+ , m_iHorizontalScale(100)
+ , m_iVerticalScale(100)
+ , m_dwCharStyles(0)
+ , m_pChars(NULL)
+ , m_pUserData(NULL)
+ {
+ }
+ FX_INT32 GetEndPos() const
+ {
+ return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth;
+ }
+ FX_INT32 GetLength() const
+ {
+ return m_iChars;
+ }
+ FX_INT32 GetEndChar() const
+ {
+ return m_iStartChar + m_iChars;
+ }
+ CFX_TxtChar* GetCharPtr(FX_INT32 index) const
+ {
+ FXSYS_assert(index > -1 && index < m_iChars && m_pChars != NULL);
+ return m_pChars->GetDataPtr(m_iStartChar + index);
+ }
+ void GetString(FX_LPWSTR pText) const
+ {
+ FXSYS_assert(pText != NULL);
+ FX_INT32 iEndChar = m_iStartChar + m_iChars;
+ CFX_Char *pChar;
+ for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) {
+ pChar = m_pChars->GetDataPtr(i);
+ *pText ++ = (FX_WCHAR)pChar->m_wCharCode;
+ }
+ }
+
+ void GetString(CFX_WideString &wsText) const
+ {
+ FX_LPWSTR pText = wsText.GetBuffer(m_iChars);
+ GetString(pText);
+ wsText.ReleaseBuffer(m_iChars);
+ }
+ void GetWidths(FX_INT32 *pWidths) const
+ {
+ FXSYS_assert(pWidths != NULL);
+ FX_INT32 iEndChar = m_iStartChar + m_iChars;
+ CFX_Char *pChar;
+ for (FX_INT32 i = m_iStartChar; i < iEndChar; i ++) {
+ pChar = m_pChars->GetDataPtr(i);
+ *pWidths ++ = pChar->m_iCharWidth;
+ }
+ }
+ FX_DWORD m_dwStatus;
+ FX_INT32 m_iStartPos;
+ FX_INT32 m_iWidth;
+ FX_INT32 m_iStartChar;
+ FX_INT32 m_iChars;
+ FX_INT32 m_iBidiLevel;
+ FX_INT32 m_iBidiPos;
+ FX_INT32 m_iHorizontalScale;
+ FX_INT32 m_iVerticalScale;
+ FX_DWORD m_dwCharStyles;
+ CFX_TxtCharArray *m_pChars;
+ FX_LPVOID m_pUserData;
+};
+typedef CFX_BaseArrayTemplate<CFX_TxtPiece> CFX_TxtPieceArray;
+class IFX_TxtBreak
+{
+public:
+ static IFX_TxtBreak* Create(FX_DWORD dwPolicies);
+ virtual void Release() = 0;
+ virtual void SetLineWidth(FX_FLOAT fLineWidth) = 0;
+ virtual void SetLinePos(FX_FLOAT fLinePos) = 0;
+ virtual FX_DWORD GetLayoutStyles() const = 0;
+ virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles) = 0;
+ virtual void SetFont(IFX_Font *pFont) = 0;
+ virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
+ virtual void SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) = 0;
+ virtual void SetDefaultChar(FX_WCHAR wch) = 0;
+ virtual void SetParagraphBreakChar(FX_WCHAR wch) = 0;
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance) = 0;
+ virtual void SetHorizontalScale(FX_INT32 iScale) = 0;
+ virtual void SetVerticalScale(FX_INT32 iScale) = 0;
+ virtual void SetCharRotation(FX_INT32 iCharRotation) = 0;
+ virtual void SetCharSpace(FX_FLOAT fCharSpace) = 0;
+ virtual void SetAlignment(FX_INT32 iAlignment) = 0;
+ virtual FX_DWORD GetContextCharStyles() const = 0;
+ virtual void SetContextCharStyles(FX_DWORD dwCharStyles) = 0;
+ virtual void SetCombWidth(FX_FLOAT fCombWidth) = 0;
+ virtual void SetUserData(FX_LPVOID pUserData) = 0;
+ virtual FX_DWORD AppendChar(FX_WCHAR wch) = 0;
+ virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_TXTBREAK_PieceBreak) = 0;
+ virtual FX_INT32 CountBreakChars() const = 0;
+ virtual FX_INT32 CountBreakPieces() const = 0;
+ virtual const CFX_TxtPiece* GetBreakPiece(FX_INT32 index) const = 0;
+ virtual void ClearBreakPieces() = 0;
+ virtual void Reset() = 0;
+ virtual FX_INT32 GetDisplayPos(FX_LPCTXTRUN pTxtRun, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const = 0;
+ virtual FX_INT32 GetCharRects(FX_LPCTXTRUN pTxtRun, CFX_RectFArray &rtArray, FX_BOOL bCharBBox = FALSE) const = 0;
+};
+#endif
diff --git a/xfa/src/fgas/include/fx_ucd.h b/xfa/src/fgas/include/fx_ucd.h
new file mode 100644
index 0000000000..715c8af4dd
--- /dev/null
+++ b/xfa/src/fgas/include/fx_ucd.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FGAS_UNICODE_
+#define _FGAS_UNICODE_
+#define FX_JAPCHARPROPERTYEX_Left 0x01
+#define FX_JAPCHARPROPERTYEX_Center 0x02
+#define FX_JAPCHARPROPERTYEX_Right 0x03
+#define FX_JAPCHARPROPERTYEX_Top 0x10
+#define FX_JAPCHARPROPERTYEX_Middle 0x20
+#define FX_JAPCHARPROPERTYEX_Bottom 0x30
+typedef struct _FX_JAPCHARPROPERTYEX {
+ FX_WCHAR wChar;
+ FX_BYTE uAlign;
+} FX_JAPCHARPROPERTYEX, *FX_LPJAPCHARPROPERTYEX;
+typedef FX_JAPCHARPROPERTYEX const * FX_LPCJAPCHARPROPERTYEX;
+FX_LPCJAPCHARPROPERTYEX FX_GetJapCharPropertyEx(FX_WCHAR wch);
+typedef FX_BOOL (*FX_AdjustCharDisplayPos)(FX_WCHAR wch, FX_BOOL bMBCSCode, IFX_Font *pFont, FX_FLOAT fFontSize, FX_BOOL bVertical, CFX_PointF &ptOffset);
+FX_BOOL FX_AdjustJapCharDisplayPos(FX_WCHAR wch, FX_BOOL bMBCSCode, IFX_Font *pFont, FX_FLOAT fFontSize, FX_BOOL bVertical, CFX_PointF &ptOffset);
+#endif
diff --git a/xfa/src/fgas/include/fx_utl.h b/xfa/src/fgas/include/fx_utl.h
new file mode 100644
index 0000000000..3bb7b61986
--- /dev/null
+++ b/xfa/src/fgas/include/fx_utl.h
@@ -0,0 +1,797 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_UTILS
+#define _FX_UTILS
+class CFX_ThreadLock;
+class CFX_BaseArray;
+template<class baseType> class CFX_BaseArrayTemplate;
+template<class baseType> class CFX_ObjectBaseArrayTemplate;
+class CFX_BaseMassArray;
+template<class baseType> class CFX_MassArrayTemplate;
+template<class baseType> class CFX_ObjectMassArrayTemplate;
+class CFX_BaseDiscreteArray;
+template<class baseType> class CFX_DiscreteArrayTemplate;
+class CFX_BaseStack;
+template<class baseType> class CFX_StackTemplate;
+template<class baseType> class CFX_ObjectStackTemplate;
+template<class baseType> class CFX_CPLTreeNode;
+template<class baseType> class CFX_CPLTree;
+class CFX_ThreadLock
+{
+public:
+ CFX_ThreadLock();
+ virtual ~CFX_ThreadLock();
+ void Lock();
+ void Unlock();
+private:
+ FX_LPVOID m_pData;
+};
+class CFX_BaseArray : public CFX_Target
+{
+protected:
+ CFX_BaseArray(FX_INT32 iGrowSize, FX_INT32 iBlockSize);
+ ~CFX_BaseArray();
+ FX_INT32 GetSize() const;
+ FX_INT32 GetBlockSize() const;
+ FX_LPBYTE AddSpaceTo(FX_INT32 index);
+ FX_LPBYTE GetAt(FX_INT32 index) const;
+ FX_LPBYTE GetBuffer() const;
+ FX_INT32 Append(const CFX_BaseArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1);
+ FX_INT32 Copy(const CFX_BaseArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1);
+ FX_INT32 RemoveLast(FX_INT32 iCount = -1);
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ FX_LPVOID m_pData;
+};
+template<class baseType>
+class CFX_BaseArrayTemplate : public CFX_BaseArray
+{
+public:
+ CFX_BaseArrayTemplate(FX_INT32 iGrowSize = 100) : CFX_BaseArray(iGrowSize, sizeof(baseType)) {}
+ CFX_BaseArrayTemplate(FX_INT32 iGrowSize, FX_INT32 iBlockSize) : CFX_BaseArray(iGrowSize, iBlockSize) {}
+ FX_INT32 GetSize() const
+ {
+ return CFX_BaseArray::GetSize();
+ }
+ FX_INT32 GetBlockSize() const
+ {
+ return CFX_BaseArray::GetBlockSize();
+ }
+ baseType* AddSpace()
+ {
+ return (baseType*)CFX_BaseArray::AddSpaceTo(CFX_BaseArray::GetSize());
+ }
+ FX_INT32 Add(const baseType &element)
+ {
+ FX_INT32 index = CFX_BaseArray::GetSize();
+ *(baseType*)CFX_BaseArray::AddSpaceTo(index) = element;
+ return index;
+ }
+ baseType* GetBuffer() const
+ {
+ return (baseType*)CFX_BaseArray::GetBuffer();
+ }
+ baseType& GetAt(FX_INT32 index) const
+ {
+ return *(baseType*)CFX_BaseArray::GetAt(index);
+ }
+ baseType* GetPtrAt(FX_INT32 index) const
+ {
+ return (baseType*)CFX_BaseArray::GetAt(index);
+ }
+ void SetAt(FX_INT32 index, const baseType &element)
+ {
+ *(baseType*)CFX_BaseArray::GetAt(index) = element;
+ }
+ void SetAtGrow(FX_INT32 index, const baseType &element)
+ {
+ *(baseType*)CFX_BaseArray::AddSpaceTo(index) = element;
+ }
+ FX_INT32 Append(const CFX_BaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ return CFX_BaseArray::Append(src, iStart, iCount);
+ }
+ FX_INT32 Copy(const CFX_BaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ return CFX_BaseArray::Copy(src, iStart, iCount);
+ }
+ FX_INT32 RemoveLast(FX_INT32 iCount = -1)
+ {
+ return CFX_BaseArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ CFX_BaseArray::RemoveAll(bLeaveMemory);
+ }
+};
+typedef CFX_BaseArrayTemplate<FX_LPVOID> CFDE_PtrArray;
+typedef CFX_BaseArrayTemplate<FX_DWORD> CFDE_DWordArray;
+typedef CFX_BaseArrayTemplate<FX_WORD> CFDE_WordArray;
+template<class baseType>
+class CFX_ObjectBaseArrayTemplate : public CFX_BaseArray
+{
+public:
+ CFX_ObjectBaseArrayTemplate(FX_INT32 iGrowSize = 100) : CFX_BaseArray(iGrowSize, sizeof(baseType)) {}
+ ~CFX_ObjectBaseArrayTemplate()
+ {
+ RemoveAll(FALSE);
+ }
+ FX_INT32 GetSize() const
+ {
+ return CFX_BaseArray::GetSize();
+ }
+ FX_INT32 GetBlockSize() const
+ {
+ return CFX_BaseArray::GetBlockSize();
+ }
+ FX_INT32 Add(const baseType &element)
+ {
+ FX_INT32 index = CFX_BaseArray::GetSize();
+ baseType *p = (baseType*)CFX_BaseArray::AddSpaceTo(index);
+ FXTARGET_New ((void*)p)baseType(element);
+ return index;
+ }
+ baseType& GetAt(FX_INT32 index) const
+ {
+ return *(baseType*)CFX_BaseArray::GetAt(index);
+ }
+ baseType* GetPtrAt(FX_INT32 index) const
+ {
+ return (baseType*)CFX_BaseArray::GetAt(index);
+ }
+ FX_INT32 Append(const CFX_ObjectBaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ FXSYS_assert(GetBlockSize() == src.GetBlockSize());
+ if (iCount == 0) {
+ return 0;
+ }
+ FX_INT32 iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ if (iStart + iCount > iSize) {
+ iCount = iSize - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ iSize = CFX_BaseArray::GetSize();
+ CFX_BaseArray::AddSpaceTo(iSize + iCount - 1);
+ FX_LPBYTE *pStart = CFX_BaseArray::GetAt(iSize);
+ FX_INT32 iBlockSize = CFX_BaseArray::GetBlockSize();
+ iSize = iStart + iCount;
+ for (FX_INT32 i = iStart; i < iSize; i ++) {
+ FXTARGET_NewWith ((void*)pStart)baseType(src.GetAt(i));
+ pStart += iBlockSize;
+ }
+ return iCount;
+ }
+ FX_INT32 Copy(const CFX_ObjectBaseArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ FXSYS_assert(GetBlockSize() == src.GetBlockSize());
+ if (iCount == 0) {
+ return 0;
+ }
+ FX_INT32 iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ if (iStart + iCount > iSize) {
+ iCount = iSize - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ RemoveAll(TRUE);
+ CFX_BaseArray::AddSpaceTo(iCount - 1);
+ FX_LPBYTE *pStart = CFX_BaseArray::GetAt(0);
+ FX_INT32 iBlockSize = CFX_BaseArray::GetBlockSize();
+ iSize = iStart + iCount;
+ for (FX_INT32 i = iStart; i < iSize; i ++) {
+ FXTARGET_New ((void*)pStart)baseType(src.GetAt(i));
+ pStart += iBlockSize;
+ }
+ return iCount;
+ }
+ FX_INT32 RemoveLast(FX_INT32 iCount = -1)
+ {
+ FX_INT32 iSize = CFX_BaseArray::GetSize();
+ if (iCount < 0 || iCount > iSize) {
+ iCount = iSize;
+ }
+ if (iCount == 0) {
+ return iSize;
+ }
+ for (FX_INT32 i = iSize - iCount; i < iSize; i ++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ return CFX_BaseArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ FX_INT32 iSize = CFX_BaseArray::GetSize();
+ for (FX_INT32 i = 0; i < iSize; i ++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ CFX_BaseArray::RemoveAll(bLeaveMemory);
+ }
+};
+class CFX_BaseMassArray : public CFX_Target
+{
+protected:
+ CFX_BaseMassArray(FX_INT32 iChunkSize, FX_INT32 iBlockSize);
+ ~CFX_BaseMassArray();
+ FX_INT32 GetSize() const;
+ FX_LPBYTE AddSpaceTo(FX_INT32 index);
+ FX_LPBYTE GetAt(FX_INT32 index) const;
+ FX_INT32 Append(const CFX_BaseMassArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1);
+ FX_INT32 Copy(const CFX_BaseMassArray &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1);
+ FX_INT32 RemoveLast(FX_INT32 iCount = -1);
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ FX_LPVOID m_pData;
+};
+template<class baseType>
+class CFX_MassArrayTemplate : public CFX_BaseMassArray
+{
+public:
+ CFX_MassArrayTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {}
+ CFX_MassArrayTemplate(FX_INT32 iChunkSize, FX_INT32 iBlockSize) : CFX_BaseMassArray(iChunkSize, iBlockSize) {}
+ FX_INT32 GetSize() const
+ {
+ return CFX_BaseMassArray::GetSize();
+ }
+ baseType* AddSpace()
+ {
+ return (baseType*)CFX_BaseMassArray::AddSpaceTo(CFX_BaseMassArray::GetSize());
+ }
+ FX_INT32 Add(const baseType &element)
+ {
+ FX_INT32 index = CFX_BaseMassArray::GetSize();
+ *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element;
+ return index;
+ }
+ baseType& GetAt(FX_INT32 index) const
+ {
+ return *(baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ baseType* GetPtrAt(FX_INT32 index) const
+ {
+ return (baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ void SetAt(FX_INT32 index, const baseType &element)
+ {
+ *(baseType*)CFX_BaseMassArray::GetAt(index) = element;
+ }
+ void SetAtGrow(FX_INT32 index, const baseType &element)
+ {
+ *(baseType*)CFX_BaseMassArray::AddSpaceTo(index) = element;
+ }
+ FX_INT32 Append(const CFX_MassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ return CFX_BaseMassArray::Append(src, iStart, iCount);
+ }
+ FX_INT32 Copy(const CFX_MassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ return CFX_BaseMassArray::Copy(src, iStart, iCount);
+ }
+ FX_INT32 RemoveLast(FX_INT32 iCount = -1)
+ {
+ return CFX_BaseMassArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ CFX_BaseMassArray::RemoveAll(bLeaveMemory);
+ }
+};
+typedef CFX_MassArrayTemplate<FX_LPVOID> CFX_PtrMassArray;
+typedef CFX_MassArrayTemplate<FX_INT32> CFX_Int32MassArray;
+typedef CFX_MassArrayTemplate<FX_DWORD> CFX_DWordMassArray;
+typedef CFX_MassArrayTemplate<FX_WORD> CFX_WordMassArray;
+typedef CFX_MassArrayTemplate<CFX_Rect> CFX_RectMassArray;
+typedef CFX_MassArrayTemplate<CFX_RectF> CFX_RectFMassArray;
+template<class baseType>
+class CFX_ObjectMassArrayTemplate : public CFX_BaseMassArray
+{
+public:
+ CFX_ObjectMassArrayTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseMassArray(iChunkSize, sizeof(baseType)) {}
+ ~CFX_ObjectMassArrayTemplate()
+ {
+ RemoveAll(FALSE);
+ }
+ FX_INT32 GetSize() const
+ {
+ return CFX_BaseMassArray::GetSize();
+ }
+ FX_INT32 Add(const baseType &element)
+ {
+ FX_INT32 index = CFX_BaseMassArray::GetSize();
+ baseType *p = (baseType*)CFX_BaseMassArray::AddSpaceTo(index);
+ FXTARGET_New ((void*)p)baseType(element);
+ return index;
+ }
+ baseType& GetAt(FX_INT32 index) const
+ {
+ return *(baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ baseType* GetPtrAt(FX_INT32 index) const
+ {
+ return (baseType*)CFX_BaseMassArray::GetAt(index);
+ }
+ FX_INT32 Append(const CFX_ObjectMassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ if (iCount == 0) {
+ return CFX_BaseMassArray::GetSize();
+ }
+ FX_INT32 iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ FX_INT32 iEnd = iStart + iCount;
+ if (iEnd > iSize) {
+ iEnd = iSize;
+ }
+ for (FX_INT32 i = iStart; i < iEnd; i ++) {
+ Add(src.GetAt(i));
+ }
+ return CFX_BaseMassArray::GetSize();
+ }
+ FX_INT32 Copy(const CFX_ObjectMassArrayTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ if (iCount == 0) {
+ return CFX_BaseMassArray::GetSize();
+ }
+ FX_INT32 iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ FX_INT32 iEnd = iStart + iCount;
+ if (iEnd > iSize) {
+ iEnd = iSize;
+ }
+ RemoveAll(TRUE);
+ for (FX_INT32 i = iStart; i < iEnd; i ++) {
+ Add(src.GetAt(i));
+ }
+ return CFX_BaseMassArray::GetSize();
+ }
+ FX_INT32 RemoveLast(FX_INT32 iCount = -1)
+ {
+ FX_INT32 iSize = CFX_BaseMassArray::GetSize();
+ if (iCount < 0 || iCount > iSize) {
+ iCount = iSize;
+ }
+ if (iCount == 0) {
+ return iSize;
+ }
+ for (FX_INT32 i = iSize - iCount; i < iSize; i ++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ return CFX_BaseMassArray::RemoveLast(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ FX_INT32 iSize = CFX_BaseMassArray::GetSize();
+ for (FX_INT32 i = 0; i < iSize; i ++) {
+ ((baseType*)GetPtrAt(i))->~baseType();
+ }
+ CFX_BaseMassArray::RemoveAll(bLeaveMemory);
+ }
+};
+class CFX_BaseDiscreteArray : public CFX_Target
+{
+protected:
+ CFX_BaseDiscreteArray(FX_INT32 iChunkSize, FX_INT32 iBlockSize);
+ ~CFX_BaseDiscreteArray();
+ FX_LPBYTE AddSpaceTo(FX_INT32 index);
+ FX_LPBYTE GetAt(FX_INT32 index) const;
+ void RemoveAll();
+ FX_LPVOID m_pData;
+};
+template<class baseType>
+class CFX_DiscreteArrayTemplate : public CFX_BaseDiscreteArray
+{
+public:
+ CFX_DiscreteArrayTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseDiscreteArray(iChunkSize, sizeof(baseType)) {}
+ baseType& GetAt(FX_INT32 index, const baseType &defValue) const
+ {
+ baseType *p = (baseType*)CFX_BaseDiscreteArray::GetAt(index);
+ return p == NULL ? (baseType&)defValue : *p;
+ }
+ baseType* GetPtrAt(FX_INT32 index) const
+ {
+ return (baseType*)CFX_BaseDiscreteArray::GetAt(index);
+ }
+ void SetAtGrow(FX_INT32 index, const baseType &element)
+ {
+ *(baseType*)CFX_BaseDiscreteArray::AddSpaceTo(index) = element;
+ }
+ void RemoveAll()
+ {
+ CFX_BaseDiscreteArray::RemoveAll();
+ }
+};
+typedef CFX_DiscreteArrayTemplate<FX_LPVOID> CFX_PtrDiscreteArray;
+typedef CFX_DiscreteArrayTemplate<FX_DWORD> CFX_DWordDiscreteArray;
+typedef CFX_DiscreteArrayTemplate<FX_WORD> CFX_WordDiscreteArray;
+class CFX_BaseStack : public CFX_Target
+{
+protected:
+ CFX_BaseStack(FX_INT32 iChunkSize, FX_INT32 iBlockSize);
+ ~CFX_BaseStack();
+ FX_LPBYTE Push();
+ void Pop();
+ FX_LPBYTE GetTopElement() const;
+ FX_INT32 GetSize() const;
+ FX_LPBYTE GetAt(FX_INT32 index) const;
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ FX_LPVOID m_pData;
+};
+template<class baseType>
+class CFX_StackTemplate : public CFX_BaseStack
+{
+public:
+ CFX_StackTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseStack(iChunkSize, sizeof(baseType)) {}
+ FX_INT32 Push(const baseType &element)
+ {
+ FX_INT32 index = CFX_BaseStack::GetSize();
+ *(baseType*)CFX_BaseStack::Push() = element;
+ return index;
+ }
+ void Pop()
+ {
+ CFX_BaseStack::Pop();
+ }
+ baseType* GetTopElement() const
+ {
+ return (baseType*)CFX_BaseStack::GetTopElement();
+ }
+ FX_INT32 GetSize() const
+ {
+ return CFX_BaseStack::GetSize();
+ }
+ baseType* GetAt(FX_INT32 index) const
+ {
+ return (baseType*)CFX_BaseStack::GetAt(index);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ CFX_BaseStack::RemoveAll(bLeaveMemory);
+ }
+};
+typedef CFX_StackTemplate<FX_LPVOID> CFX_PtrStack;
+typedef CFX_StackTemplate<FX_DWORD> CFX_DWordStack;
+typedef CFX_StackTemplate<FX_WORD> CFX_WordStack;
+typedef CFX_StackTemplate<FX_INT32> CFX_Int32Stack;
+template<class baseType>
+class CFX_ObjectStackTemplate : public CFX_BaseStack
+{
+public:
+ CFX_ObjectStackTemplate(FX_INT32 iChunkSize = 100) : CFX_BaseStack(iChunkSize, sizeof(baseType)) {}
+ ~CFX_ObjectStackTemplate()
+ {
+ RemoveAll();
+ }
+ FX_INT32 Push(const baseType &element)
+ {
+ FX_INT32 index = CFX_BaseStack::GetSize();
+ baseType *p = (baseType*)CFX_BaseStack::Push();
+ FXTARGET_New ((void*)p)baseType(element);
+ return index;
+ }
+ void Pop()
+ {
+ baseType *p = (baseType*)CFX_BaseStack::GetTopElement();
+ if (p != NULL) {
+ p->~baseType();
+ }
+ CFX_BaseStack::Pop();
+ }
+ baseType* GetTopElement() const
+ {
+ return (baseType*)CFX_BaseStack::GetTopElement();
+ }
+ FX_INT32 GetSize() const
+ {
+ return CFX_BaseStack::GetSize();
+ }
+ baseType* GetAt(FX_INT32 index) const
+ {
+ return (baseType*)CFX_BaseStack::GetAt(index);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ FX_INT32 iSize = CFX_BaseStack::GetSize();
+ for (FX_INT32 i = 0; i < iSize; i ++) {
+ ((baseType*)CFX_BaseStack::GetAt(i))->~baseType();
+ }
+ CFX_BaseStack::RemoveAll(bLeaveMemory);
+ }
+ FX_INT32 Copy(const CFX_ObjectStackTemplate &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1)
+ {
+ if (iCount == 0) {
+ return CFX_BaseStack::GetSize();
+ }
+ FX_INT32 iSize = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iSize);
+ if (iCount < 0) {
+ iCount = iSize;
+ }
+ FX_INT32 iEnd = iStart + iCount;
+ if (iEnd > iSize) {
+ iEnd = iSize;
+ }
+ RemoveAll(TRUE);
+ for (FX_INT32 i = iStart; i < iEnd; i ++) {
+ Push(*src.GetAt(i));
+ }
+ return CFX_BaseStack::GetSize();
+ }
+};
+template<class baseType>
+class CFX_CPLTreeNode : public CFX_Target
+{
+public:
+ typedef CFX_CPLTreeNode<baseType> CPLTreeNode;
+ CFX_CPLTreeNode() : m_pParentNode(NULL)
+ , m_pChildNode(NULL)
+ , m_pPrevNode(NULL)
+ , m_pNextNode(NULL)
+ , m_Data()
+ {
+ }
+ enum TreeNode {Root = 0, Parent, FirstSibling, PreviousSibling, NextSibling, LastSibling, FirstNeighbor, PreviousNeighbor, NextNeighbor, LastNeighbor, FirstChild, LastChild};
+ CPLTreeNode* GetNode(TreeNode eNode) const
+ {
+ switch (eNode) {
+ case Root: {
+ CPLTreeNode *pParent = (CPLTreeNode*)this;
+ CPLTreeNode *pTemp;
+ while ((pTemp = pParent->m_pParentNode) != NULL) {
+ pParent = pTemp;
+ }
+ return pParent;
+ }
+ case Parent:
+ return m_pParentNode;
+ case FirstSibling: {
+ CPLTreeNode *pNode = (CPLTreeNode*)this;
+ CPLTreeNode *pTemp;
+ while ((pTemp = pNode->m_pPrevNode) != NULL) {
+ pNode = pTemp;
+ }
+ return pNode == (CPLTreeNode*)this ? NULL : pNode;
+ }
+ case PreviousSibling:
+ return m_pPrevNode;
+ case NextSibling:
+ return m_pNextNode;
+ case LastSibling: {
+ CPLTreeNode *pNode = (CPLTreeNode*)this;
+ CPLTreeNode *pTemp;
+ while ((pTemp = pNode->m_pNextNode) != NULL) {
+ pNode = pTemp;
+ }
+ return pNode == (CPLTreeNode*)this ? NULL : pNode;
+ }
+ case FirstNeighbor: {
+ CPLTreeNode *pParent = (CPLTreeNode*)this;
+ CPLTreeNode *pTemp;
+ while ((pTemp = pParent->m_pParentNode) != NULL) {
+ pParent = pTemp;
+ }
+ return pParent == (CPLTreeNode*)this ? NULL : pParent;
+ }
+ case PreviousNeighbor: {
+ if (m_pPrevNode == NULL) {
+ return m_pParentNode;
+ }
+ CPLTreeNode *pNode = m_pPrevNode;
+ CPLTreeNode *pTemp;
+ while ((pTemp = pNode->m_pChildNode) != NULL) {
+ pNode = pTemp;
+ while ((pTemp = pNode->m_pNextNode) != NULL) {
+ pNode = pTemp;
+ }
+ }
+ return pNode;
+ }
+ case NextNeighbor: {
+ if (m_pChildNode != NULL) {
+ return m_pChildNode;
+ }
+ if (m_pNextNode != NULL) {
+ return m_pNextNode;
+ }
+ CPLTreeNode *pNode = m_pParentNode;
+ while (pNode != NULL) {
+ if (pNode->m_pNextNode != NULL) {
+ return pNode->m_pNextNode;
+ }
+ pNode = pNode->m_pParentNode;
+ }
+ return NULL;
+ }
+ case LastNeighbor: {
+ CPLTreeNode *pNode = (CPLTreeNode*)this;
+ CPLTreeNode *pTemp;
+ while ((pTemp = pNode->m_pParentNode) != NULL) {
+ pNode = pTemp;
+ }
+ while (TRUE) {
+ CPLTreeNode *pTemp;
+ while ((pTemp = pNode->m_pNextNode) != NULL) {
+ pNode = pTemp;
+ }
+ if (pNode->m_pChildNode == NULL) {
+ break;
+ }
+ pNode = pNode->m_pChildNode;
+ }
+ return pNode == (CPLTreeNode*)this ? NULL : pNode;
+ }
+ case FirstChild:
+ return m_pChildNode;
+ case LastChild: {
+ if (m_pChildNode == NULL) {
+ return NULL;
+ }
+ CPLTreeNode *pChild = m_pChildNode;
+ CPLTreeNode *pTemp;
+ while ((pTemp = pChild->m_pNextNode) != NULL) {
+ pChild = pTemp;
+ }
+ return pChild;
+ }
+ default:
+ break;
+ }
+ return NULL;
+ }
+ void SetParentNode(CPLTreeNode *pNode)
+ {
+ m_pParentNode = pNode;
+ }
+ FX_INT32 CountChildNodes() const
+ {
+ FX_INT32 iCount = 0;
+ CPLTreeNode *pNode = m_pChildNode;
+ while (pNode) {
+ iCount ++;
+ pNode = pNode->m_pNextNode;
+ }
+ return iCount;
+ }
+ CPLTreeNode* GetChildNode(FX_INT32 iIndex) const
+ {
+ FX_INT32 iCount = 0;
+ CPLTreeNode *pNode = m_pChildNode;
+ while (pNode) {
+ if (iIndex == iCount) {
+ return pNode;
+ }
+ iCount ++;
+ pNode = pNode->m_pNextNode;
+ }
+ return NULL;
+ }
+ FX_INT32 GetNodeIndex() const
+ {
+ FX_INT32 index = 0;
+ CPLTreeNode *pNode = m_pPrevNode;
+ while (pNode != NULL) {
+ index ++;
+ pNode = pNode->m_pPrevNode;
+ }
+ return index;
+ }
+ FX_BOOL IsParentNode(const CPLTreeNode *pNode) const
+ {
+ CPLTreeNode *pParent = m_pParentNode;
+ while (pParent != NULL) {
+ if (pParent == pNode) {
+ return TRUE;
+ }
+ pParent = pParent->GetTreeNode(Parent);
+ }
+ return FALSE;
+ }
+ FX_BOOL IsChildNode(const CPLTreeNode *pNode) const
+ {
+ if (pNode == NULL) {
+ return FALSE;
+ }
+ return pNode->IsParentNode((const CPLTreeNode*)this);
+ }
+ void SetChildNode(CPLTreeNode *pNode)
+ {
+ m_pChildNode = pNode;
+ }
+ void SetPrevNode(CPLTreeNode *pNode)
+ {
+ m_pPrevNode = pNode;
+ }
+ void SetNextNode(CPLTreeNode *pNode)
+ {
+ m_pNextNode = pNode;
+ }
+ FX_INT32 GetNodeLevel() const
+ {
+ FX_INT32 iLevel = 0;
+ CPLTreeNode *pNode = (CPLTreeNode*)this;
+ while ((pNode = pNode->m_pParentNode) != NULL) {
+ iLevel ++;
+ }
+ return iLevel;
+ }
+ FX_BOOL IsRootNode() const
+ {
+ return m_pParentNode == NULL;
+ }
+ baseType GetData() const
+ {
+ return m_Data;
+ }
+ void SetData(baseType data)
+ {
+ m_Data = data;
+ }
+protected:
+ CPLTreeNode *m_pParentNode;
+ CPLTreeNode *m_pChildNode;
+ CPLTreeNode *m_pPrevNode;
+ CPLTreeNode *m_pNextNode;
+ baseType m_Data;
+ friend class CFX_CPLTree<baseType>;
+};
+template<class baseType>
+class CFX_CPLTree : public CFX_Object
+{
+public:
+ typedef CFX_CPLTreeNode<baseType> CPLTreeNode;
+ CFX_CPLTree() : m_Root()
+ {
+ }
+ ~CFX_CPLTree()
+ {
+ CPLTreeNode *pNode = m_Root.GetNode(CPLTreeNode::LastNeighbor);
+ while (pNode != NULL) {
+ if (pNode->IsRootNode()) {
+ break;
+ }
+ CPLTreeNode *pTemp = pNode->GetNode(CPLTreeNode::PreviousNeighbor);
+ delete pNode;
+ pNode = pTemp;
+ }
+ }
+ CPLTreeNode* GetRoot()
+ {
+ return &m_Root;
+ }
+ CPLTreeNode* AddChild(baseType data, CPLTreeNode *pParent = NULL)
+ {
+ if (pParent == NULL) {
+ pParent = &m_Root;
+ }
+ CPLTreeNode *pChild = FXTARGET_New CPLTreeNode;
+ pChild->SetParentNode(pParent);
+ pChild->SetData(data);
+ if (pParent->m_pChildNode == NULL) {
+ pParent->m_pChildNode = pChild;
+ } else {
+ CPLTreeNode *pLast = pParent->GetNode(CPLTreeNode::LastChild);
+ pChild->SetPrevNode(pLast);
+ pLast->SetNextNode(pChild);
+ }
+ return pChild;
+ }
+protected:
+ CPLTreeNode m_Root;
+};
+#endif
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1250.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1250.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1250.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1251.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1251.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1251.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1252.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1252.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1252.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1253.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1253.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1253.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1254.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1254.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1254.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1255.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1255.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1255.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1256.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1256.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1256.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1257.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1257.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1257.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu1258.cpp b/xfa/src/fgas/src/crt/codepage/cpcu1258.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu1258.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu874.cpp b/xfa/src/fgas/src/crt/codepage/cpcu874.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu874.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu932.cpp b/xfa/src/fgas/src/crt/codepage/cpcu932.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu932.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu936.cpp b/xfa/src/fgas/src/crt/codepage/cpcu936.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu936.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu949.cpp b/xfa/src/fgas/src/crt/codepage/cpcu949.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu949.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpcu950.cpp b/xfa/src/fgas/src/crt/codepage/cpcu950.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpcu950.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1250.cpp b/xfa/src/fgas/src/crt/codepage/cphi1250.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1250.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1251.cpp b/xfa/src/fgas/src/crt/codepage/cphi1251.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1251.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1252.cpp b/xfa/src/fgas/src/crt/codepage/cphi1252.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1252.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1253.cpp b/xfa/src/fgas/src/crt/codepage/cphi1253.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1253.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1254.cpp b/xfa/src/fgas/src/crt/codepage/cphi1254.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1254.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1255.cpp b/xfa/src/fgas/src/crt/codepage/cphi1255.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1255.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1256.cpp b/xfa/src/fgas/src/crt/codepage/cphi1256.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1256.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1257.cpp b/xfa/src/fgas/src/crt/codepage/cphi1257.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1257.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi1258.cpp b/xfa/src/fgas/src/crt/codepage/cphi1258.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi1258.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi874.cpp b/xfa/src/fgas/src/crt/codepage/cphi874.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi874.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi932.cpp b/xfa/src/fgas/src/crt/codepage/cphi932.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi932.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi936.cpp b/xfa/src/fgas/src/crt/codepage/cphi936.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi936.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi949.cpp b/xfa/src/fgas/src/crt/codepage/cphi949.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi949.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cphi950.cpp b/xfa/src/fgas/src/crt/codepage/cphi950.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cphi950.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1250.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1250.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1250.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1251.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1251.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1251.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1252.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1252.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1252.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1253.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1253.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1253.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1254.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1254.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1254.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1255.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1255.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1255.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1256.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1256.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1256.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1257.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1257.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1257.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc1258.cpp b/xfa/src/fgas/src/crt/codepage/cpuc1258.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc1258.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc874.cpp b/xfa/src/fgas/src/crt/codepage/cpuc874.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc874.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc932.cpp b/xfa/src/fgas/src/crt/codepage/cpuc932.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc932.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc936.cpp b/xfa/src/fgas/src/crt/codepage/cpuc936.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc936.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc949.cpp b/xfa/src/fgas/src/crt/codepage/cpuc949.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc949.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/codepage/cpuc950.cpp b/xfa/src/fgas/src/crt/codepage/cpuc950.cpp
new file mode 100644
index 0000000000..6cd252bcf4
--- /dev/null
+++ b/xfa/src/fgas/src/crt/codepage/cpuc950.cpp
@@ -0,0 +1,6 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
diff --git a/xfa/src/fgas/src/crt/fx_algorithm.cpp b/xfa/src/fgas/src/crt/fx_algorithm.cpp
new file mode 100644
index 0000000000..e2d77d1a0e
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_algorithm.cpp
@@ -0,0 +1,315 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+const static FX_CHAR g_FXBase64EncoderMap[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+ 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+ 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+ 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+ 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', '+', '/',
+};
+typedef struct _FX_BASE64DATA {
+
+ FX_DWORD data1 : 2;
+ FX_DWORD data2 : 6;
+ FX_DWORD data3 : 4;
+ FX_DWORD data4 : 4;
+ FX_DWORD data5 : 6;
+ FX_DWORD data6 : 2;
+ FX_DWORD data7 : 8;
+} FX_BASE64DATA, * FX_LPBASE64ENCODEDATA;
+typedef FX_BASE64DATA const * FX_LPCBASE64DATA;
+static void FX_Base64EncodePiece(const FX_BASE64DATA &src, FX_INT32 iBytes, FX_CHAR dst[4])
+{
+ dst[0] = g_FXBase64EncoderMap[src.data2];
+ FX_DWORD b = src.data1 << 4;
+ if (iBytes > 1) {
+ b |= src.data4;
+ }
+ dst[1] = g_FXBase64EncoderMap[b];
+ if (iBytes > 1) {
+ b = src.data3 << 2;
+ if (iBytes > 2) {
+ b |= src.data6;
+ }
+ dst[2] = g_FXBase64EncoderMap[b];
+ if (iBytes > 2) {
+ dst[3] = g_FXBase64EncoderMap[src.data5];
+ } else {
+ dst[3] = '=';
+ }
+ } else {
+ dst[2] = dst[3] = '=';
+ }
+}
+FX_INT32 FX_Base64EncodeA(FX_LPCBYTE pSrc, FX_INT32 iSrcLen, FX_LPSTR pDst)
+{
+ FXSYS_assert(pSrc != NULL);
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ if (pDst == NULL) {
+ FX_INT32 iDstLen = iSrcLen / 3 * 4;
+ if ((iSrcLen % 3) != 0) {
+ iDstLen += 4;
+ }
+ return iDstLen;
+ }
+ FX_BASE64DATA srcData;
+ FX_INT32 iBytes = 3;
+ FX_LPSTR pDstEnd = pDst;
+ while (iSrcLen > 0) {
+ if (iSrcLen > 2) {
+ ((FX_LPBYTE)&srcData)[0] = *pSrc ++;
+ ((FX_LPBYTE)&srcData)[1] = *pSrc ++;
+ ((FX_LPBYTE)&srcData)[2] = *pSrc ++;
+ iSrcLen -= 3;
+ } else {
+ *((FX_LPDWORD)&srcData) = 0;
+ ((FX_LPBYTE)&srcData)[0] = *pSrc ++;
+ if (iSrcLen > 1) {
+ ((FX_LPBYTE)&srcData)[1] = *pSrc ++;
+ }
+ iBytes = iSrcLen;
+ iSrcLen = 0;
+ }
+ FX_Base64EncodePiece(srcData, iBytes, pDstEnd);
+ pDstEnd += 4;
+ }
+ return pDstEnd - pDst;
+}
+const static FX_BYTE g_FXBase64DecoderMap[256] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
+ 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
+ 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
+ 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+static void FX_Base64DecodePiece(const FX_CHAR src[4], FX_INT32 iChars, FX_BASE64DATA &dst, FX_INT32 &iBytes)
+{
+ FXSYS_assert(iChars > 0 && iChars < 5);
+ iBytes = 1;
+ dst.data2 = g_FXBase64DecoderMap[(FX_BYTE)src[0]];
+ if (iChars > 1) {
+ FX_BYTE b = g_FXBase64DecoderMap[(FX_BYTE)src[1]];
+ dst.data1 = b >> 4;
+ dst.data4 = b;
+ if (iChars > 2) {
+ iBytes = 2;
+ b = g_FXBase64DecoderMap[(FX_BYTE)src[2]];
+ dst.data3 = b >> 2;
+ dst.data6 = b;
+ if (iChars > 3) {
+ iBytes = 3;
+ dst.data5 = g_FXBase64DecoderMap[(FX_BYTE)src[3]];
+ } else {
+ dst.data5 = 0;
+ }
+ } else {
+ dst.data3 = 0;
+ }
+ } else {
+ dst.data1 = 0;
+ }
+}
+FX_INT32 FX_Base64DecodeA(FX_LPCSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE pDst)
+{
+ FXSYS_assert(pSrc != NULL);
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {
+ iSrcLen --;
+ }
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ if (pDst == NULL) {
+ FX_INT32 iDstLen = iSrcLen / 4 * 3;
+ iSrcLen %= 4;
+ if (iSrcLen == 1) {
+ iDstLen += 1;
+ } else if (iSrcLen == 2) {
+ iDstLen += 1;
+ } else if (iSrcLen == 3) {
+ iDstLen += 2;
+ }
+ return iDstLen;
+ }
+ FX_CHAR srcData[4];
+ FX_BASE64DATA dstData;
+ FX_INT32 iChars = 4, iBytes;
+ FX_LPBYTE pDstEnd = pDst;
+ while (iSrcLen > 0) {
+ if (iSrcLen > 3) {
+ *((FX_DWORD*)srcData) = *((FX_DWORD*)pSrc);
+ pSrc += 4;
+ iSrcLen -= 4;
+ } else {
+ *((FX_LPDWORD)&dstData) = 0;
+ *((FX_DWORD*)srcData) = 0;
+ srcData[0] = *pSrc ++;
+ if (iSrcLen > 1) {
+ srcData[1] = *pSrc ++;
+ }
+ if (iSrcLen > 2) {
+ srcData[2] = *pSrc ++;
+ }
+ iChars = iSrcLen;
+ iSrcLen = 0;
+ }
+ FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);
+ *pDstEnd ++ = ((FX_LPBYTE)&dstData)[0];
+ if (iBytes > 1) {
+ *pDstEnd ++ = ((FX_LPBYTE)&dstData)[1];
+ }
+ if (iBytes > 2) {
+ *pDstEnd ++ = ((FX_LPBYTE)&dstData)[2];
+ }
+ }
+ return pDstEnd - pDst;
+}
+FX_INT32 FX_Base64DecodeW(FX_LPCWSTR pSrc, FX_INT32 iSrcLen, FX_LPBYTE pDst)
+{
+ FXSYS_assert(pSrc != NULL);
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {
+ iSrcLen --;
+ }
+ if (iSrcLen < 1) {
+ return 0;
+ }
+ if (pDst == NULL) {
+ FX_INT32 iDstLen = iSrcLen / 4 * 3;
+ iSrcLen %= 4;
+ if (iSrcLen == 1) {
+ iDstLen += 1;
+ } else if (iSrcLen == 2) {
+ iDstLen += 1;
+ } else if (iSrcLen == 3) {
+ iDstLen += 2;
+ }
+ return iDstLen;
+ }
+ FX_CHAR srcData[4];
+ FX_BASE64DATA dstData;
+ FX_INT32 iChars = 4, iBytes;
+ FX_LPBYTE pDstEnd = pDst;
+ while (iSrcLen > 0) {
+ if (iSrcLen > 3) {
+ srcData[0] = (FX_CHAR) * pSrc ++;
+ srcData[1] = (FX_CHAR) * pSrc ++;
+ srcData[2] = (FX_CHAR) * pSrc ++;
+ srcData[3] = (FX_CHAR) * pSrc ++;
+ iSrcLen -= 4;
+ } else {
+ *((FX_LPDWORD)&dstData) = 0;
+ *((FX_DWORD*)srcData) = 0;
+ srcData[0] = (FX_CHAR) * pSrc ++;
+ if (iSrcLen > 1) {
+ srcData[1] = (FX_CHAR) * pSrc ++;
+ }
+ if (iSrcLen > 2) {
+ srcData[2] = (FX_CHAR) * pSrc ++;
+ }
+ iChars = iSrcLen;
+ iSrcLen = 0;
+ }
+ FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);
+ *pDstEnd ++ = ((FX_LPBYTE)&dstData)[0];
+ if (iBytes > 1) {
+ *pDstEnd ++ = ((FX_LPBYTE)&dstData)[1];
+ }
+ if (iBytes > 2) {
+ *pDstEnd ++ = ((FX_LPBYTE)&dstData)[2];
+ }
+ }
+ return pDstEnd - pDst;
+}
+const static FX_BYTE g_FXHex2DecMap[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
+ 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+FX_BYTE FX_Hex2Dec(FX_BYTE hexHigh, FX_BYTE hexLow)
+{
+ return (g_FXHex2DecMap[hexHigh] << 4) + g_FXHex2DecMap[hexLow];
+}
+FX_INT32 FX_SeparateStringW(FX_LPCWSTR pStr, FX_INT32 iStrLen, FX_WCHAR delimiter, CFX_WideStringArray &pieces)
+{
+ if (pStr == NULL) {
+ return 0;
+ }
+ if (iStrLen < 0) {
+ iStrLen = FXSYS_wcslen(pStr);
+ }
+ FX_LPCWSTR pToken = pStr;
+ FX_LPCWSTR pEnd = pStr + iStrLen;
+ while (TRUE) {
+ if (pStr >= pEnd || delimiter == *pStr) {
+ CFX_WideString sub(pToken, pStr - pToken);
+ pieces.Add(sub);
+ pToken = pStr + 1;
+ if (pStr >= pEnd) {
+ break;
+ }
+ }
+ pStr ++;
+ }
+ return pieces.GetSize();
+}
+#ifdef __cplusplus
+};
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_codepage.cpp b/xfa/src/fgas/src/crt/fx_codepage.cpp
new file mode 100644
index 0000000000..798edc9776
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_codepage.cpp
@@ -0,0 +1,373 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_codepage.h"
+static const FX_CHARSET_MAP g_FXCharset2CodePageTable[] = {
+ { 0, 1252 },
+ { 1, 0 },
+ { 2, 42 },
+ { 77, 10000 },
+ { 78, 10001 },
+ { 79, 10003 },
+ { 80, 10008 },
+ { 81, 10002 },
+ { 83, 10005 },
+ { 84, 10004 },
+ { 85, 10006 },
+ { 86, 10081 },
+ { 87, 10021 },
+ { 88, 10029 },
+ { 89, 10007 },
+ { 128, 932 },
+ { 129, 949 },
+ { 130, 1361 },
+ { 134, 936 },
+ { 136, 950 },
+ { 161, 1253 },
+ { 162, 1254 },
+ { 163, 1258 },
+ { 177, 1255 },
+ { 178, 1256 },
+ { 186, 1257 },
+ { 204, 1251 },
+ { 222, 874 },
+ { 238, 1250 },
+ { 254, 437 },
+ { 255, 850 },
+};
+FX_WORD FX_GetCodePageFromCharset(FX_BYTE charset)
+{
+ FX_INT32 iEnd = sizeof(g_FXCharset2CodePageTable) / sizeof(FX_CHARSET_MAP) - 1;
+ FXSYS_assert(iEnd >= 0);
+ FX_INT32 iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_CHARSET_MAP & cp = g_FXCharset2CodePageTable[iMid];
+ if (charset == cp.charset) {
+ return cp.codepage;
+ } else if (charset < cp.charset) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+static const FX_CHARSET_MAP g_FXCodepage2CharsetTable[] = {
+ { 1, 0 },
+ { 2, 42 },
+ { 254, 437 },
+ { 255, 850 },
+ { 222, 874 },
+ { 128, 932 },
+ { 134, 936 },
+ { 129, 949 },
+ { 136, 950 },
+ { 238, 1250 },
+ { 204, 1251 },
+ { 0, 1252 },
+ { 161, 1253 },
+ { 162, 1254 },
+ { 177, 1255 },
+ { 178, 1256 },
+ { 186, 1257 },
+ { 163, 1258 },
+ { 130, 1361 },
+ { 77, 10000 },
+ { 78, 10001 },
+ { 79, 10003 },
+ { 80, 10008 },
+ { 81, 10002 },
+ { 83, 10005 },
+ { 84, 10004 },
+ { 85, 10006 },
+ { 86, 10081 },
+ { 87, 10021 },
+ { 88, 10029 },
+ { 89, 10007 },
+};
+FX_WORD FX_GetCharsetFromCodePage(FX_WORD codepage)
+{
+ FX_INT32 iEnd = sizeof(g_FXCodepage2CharsetTable) / sizeof(FX_CHARSET_MAP) - 1;
+ FXSYS_assert(iEnd >= 0);
+ FX_INT32 iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_CHARSET_MAP & cp = g_FXCodepage2CharsetTable[iMid];
+ if (codepage == cp.codepage) {
+ return cp.charset;
+ } else if (codepage < cp.codepage) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+const FX_LANG2CPMAP g_FXLang2CodepageTable[] = {
+ {FX_LANG_Arabic_SaudiArabia , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Bulgarian_Bulgaria , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Catalan_Catalan , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Chinese_Taiwan , FX_CODEPAGE_ChineseTraditional },
+ {FX_LANG_CzechRepublic , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Danish_Denmark , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_German_Germany , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Greek_Greece , FX_CODEPAGE_MSWin_Greek },
+ {FX_LANG_English_UnitedStates , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_TraditionalSort , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Finnish_Finland , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_France , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Hebrew_Israel , FX_CODEPAGE_MSWin_Hebrew },
+ {FX_LANG_Hungarian_Hungary , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Icelandic_Iceland , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Italian_Italy , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Japanese_Japan , FX_CODEPAGE_ShiftJIS },
+ {FX_LANG_Korean_Korea , FX_CODEPAGE_Korean },
+ {FX_LANG_Dutch_Netherlands , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Norwegian_Bokmal , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Polish_Poland , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Portuguese_Brazil , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Romanian_Romania , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Russian_Russia , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Croatian_Croatia , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Slovak_Slovakia , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Albanian_Albania , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Swedish_Sweden , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Thai_Thailand , FX_CODEPAGE_MSDOS_Thai },
+ {FX_LANG_Turkish_Turkey , FX_CODEPAGE_MSWin_Turkish },
+ {FX_LANG_Urdu_Pakistan , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Indonesian_Indonesia , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Ukrainian_Ukraine , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Belarusian_Belarus , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Slovenian_Slovenia , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Estonian_Estonia , FX_CODEPAGE_MSWin_Baltic },
+ {FX_LANG_Latvian_Latvia , FX_CODEPAGE_MSWin_Baltic },
+ {FX_LANG_Lithuanian_Lithuania , FX_CODEPAGE_MSWin_Baltic },
+ {FX_LANG_Persian , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Vietnamese_Vietnam , FX_CODEPAGE_MSWin_Vietnamese },
+ {FX_LANG_Armenian_Armenia , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Azerbaijan_Latin , FX_CODEPAGE_MSWin_Turkish },
+ {FX_LANG_Basque_Basque , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Macedonian , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Afrikaans_SouthAfrica , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Georgian_Georgia , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Faroese_FaroeIslands , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Hindi_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Malay_Malaysia , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Kazakh_Kazakhstan , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Kyrgyz_Kyrgyzstan , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Kiswahili_Kenya , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Uzbek_LatinUzbekistan , FX_CODEPAGE_MSWin_Turkish },
+ {FX_LANG_Tatar_Russia , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Punjabi_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Gujarati_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Tamil_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Telugu_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Kannada_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Marathi_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_SanskritIndia , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Mongolian_CyrillicMongolia, FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Galician_Galician , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Konkani_India , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Syriac_Syria , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Divehi_Maldives , FX_CODEPAGE_DefANSI },
+ {FX_LANG_Arabic_Iraq , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Chinese_PRC , FX_CODEPAGE_ChineseSimplified },
+ {FX_LANG_German_Switzerland , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_UnitedKingdom , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Mexico , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Belgium , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Italian_Switzerland , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Dutch_Belgium , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Norwegian_Nynorsk , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Portuguese_Portugal , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_SerbianLatin_Serbia , FX_CODEPAGE_MSWin_EasternEuropean},
+ {FX_LANG_Swedish_Finland , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Azerbaijan_Cyrillic , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Malay_BruneiDarussalam , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Uzbek_CyrillicUzbekistan , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Arabic_Egypt , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Chinese_HongKong , FX_CODEPAGE_ChineseTraditional },
+ {FX_LANG_German_Austria , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_Australia , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_InternationalSort, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Canada , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_SerbianCyrillic_Serbia , FX_CODEPAGE_MSWin_Cyrillic },
+ {FX_LANG_Arabic_Libya , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Chinese_Singapore , FX_CODEPAGE_ChineseSimplified },
+ {FX_LANG_German_Luxembourg , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_Canada , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Guatemala , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Switzerland , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Algeria , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Chinese_Macao , FX_CODEPAGE_ChineseTraditional },
+ {FX_LANG_German_Liechtenstein , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_English_NewZealand , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_CostaRica , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Luxembourg , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Morocco , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_Ireland , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Panama , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_French_Monaco , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Tunisia , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_SouthAfrica , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_DominicanRepublic, FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Oman , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_Jamaica , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Venezuela , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Yemen , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_Caribbean , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Colombia , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Syria , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_Belize , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Peru , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Jordan , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_TrinidadTobago , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Argentina , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Lebanon , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_Zimbabwe , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Ecuador , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Kuwait , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_English_Philippines , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Chile , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_UAE , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Spanish_Uruguay , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Bahrain , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Spanish_Paraguay , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Arabic_Qatar , FX_CODEPAGE_MSWin_Arabic },
+ {FX_LANG_Spanish_Bolivia , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_ElSalvador , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Honduras , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_Nicaragua , FX_CODEPAGE_MSWin_WesternEuropean},
+ {FX_LANG_Spanish_PuertoRico , FX_CODEPAGE_MSWin_WesternEuropean},
+};
+FX_WORD FX_GetDefCodePageByLanguage(FX_WORD wLanguage)
+{
+ FX_INT32 iEnd = sizeof(g_FXLang2CodepageTable) / sizeof(FX_LANG2CPMAP) - 1;
+ FXSYS_assert(iEnd >= 0);
+ FX_INT32 iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_LANG2CPMAP &cp = g_FXLang2CodepageTable[iMid];
+ if (wLanguage == cp.wLanguage) {
+ return cp.wCodepage;
+ } else if (wLanguage < cp.wLanguage) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+static const FX_STR2CPHASH g_FXCPHashTable[] = {
+ { 0xd45, 0x6faf }, { 0xd46, 0x6fb0 }, { 0xd47, 0x6fb1 }, { 0xd48, 0x6fb2 },
+ { 0xd49, 0x4e6 }, { 0xd4d, 0x6fbd }, { 0xe9e, 0x4e4 }, { 0xc998, 0x1b5 },
+ { 0x18ef0, 0x3a8 }, { 0x19f85, 0x5182 }, { 0x2e2335, 0x3b6 }, { 0x325153, 0x5182 },
+ { 0x145bded, 0x2716 }, { 0x3c9a5f2, 0xc6f3 }, { 0x4c45f2d, 0x3a4 }, { 0x4c45f4e, 0xc431 },
+ { 0x58caf51, 0x4e4 }, { 0x5a5cd7d, 0x3a8 }, { 0x5a6c6a7, 0x4e4 }, { 0x5a6ca0b, 0x1b5 },
+ { 0x5a6cd68, 0x307 }, { 0x5a6d8d3, 0x4e4 }, { 0x5a6d948, 0x354 }, { 0x5a6d96b, 0x362 },
+ { 0x5a6d984, 0x366 }, { 0x5a90e35, 0x1b5 }, { 0x5e0cf00, 0x6fb5 }, { 0x609c324, 0x551 },
+ { 0x617d97f, 0x5182 }, { 0x6a6fd91, 0xfde8 }, { 0x6a6fd92, 0xfde9 }, { 0x6b102de, 0xcadc },
+ { 0x6b10f48, 0x4e89 }, { 0x1020805f, 0x4e4 }, { 0x10f0524c, 0x6fb5 }, { 0x11d558fe, 0x6fb0 },
+ { 0x13898d19, 0xc42d }, { 0x13898d3a, 0xc431 }, { 0x138a319e, 0x6fb1 }, { 0x14679c09, 0x96c6 },
+ { 0x153f0a3d, 0x6fb2 }, { 0x1576eeb3, 0x4e20 }, { 0x169a0ce6, 0xc6f9 }, { 0x16f3e2dc, 0x6fb3 },
+ { 0x18a8bb7a, 0x6fb4 }, { 0x1a5d9419, 0x6fb5 }, { 0x1a847b48, 0x3a8 }, { 0x1b762419, 0xcec8 },
+ { 0x1b9d7847, 0x475 }, { 0x1c126cb9, 0x6fb6 }, { 0x1ccdbc7d, 0x4f42 }, { 0x1d330f5f, 0x2714 },
+ { 0x1dc74559, 0x4e6 }, { 0x1edd80da, 0x4e4 }, { 0x23e4b03d, 0xfde8 }, { 0x24f28a16, 0x4f3d },
+ { 0x286e7a32, 0x2715 }, { 0x2c7c18ed, 0x3a8 }, { 0x2e2103b7, 0x2713 }, { 0x304bf479, 0x6fb4 },
+ { 0x304bf47d, 0x6fb5 }, { 0x309bb869, 0xfde8 }, { 0x309bb86a, 0xfde9 }, { 0x33664357, 0x3b6 },
+ { 0x352d6b49, 0x3a4 }, { 0x36f5661c, 0x1b5 }, { 0x392e8f48, 0xcadc }, { 0x3dc7c64c, 0x47c },
+ { 0x3ed2e8e1, 0x4e4 }, { 0x3f0c2fea, 0xcaed }, { 0x3f0fef8f, 0xc6f2 }, { 0x3f5e130f, 0x5182 },
+ { 0x47174d1f, 0x3a8 }, { 0x49686b7b, 0x6fb4 }, { 0x4b80b0d9, 0x3a4 }, { 0x4dcda97a, 0x4e4 },
+ { 0x4dcda9b6, 0x4e4 }, { 0x4e881e6a, 0x5221 }, { 0x4ffdf5a1, 0x36a }, { 0x4ffdf5a5, 0x6fbd },
+ { 0x5241ce16, 0x4e8b }, { 0x546bab9d, 0x4e4 }, { 0x54a3d64e, 0x6fb6 }, { 0x562179bd, 0x5161 },
+ { 0x57c1df15, 0xc6f7 }, { 0x61ff6e62, 0x4f36 }, { 0x6359c7d8, 0x4f35 }, { 0x63f3c335, 0x3a8 },
+ { 0x645a0f78, 0x477 }, { 0x691ac2fd, 0x275f }, { 0x6dc2eab0, 0x2d0 }, { 0x6dc2eeef, 0x35e },
+ { 0x6dc2ef10, 0x36a }, { 0x7103138a, 0x47d }, { 0x710dfbd0, 0xc6f5 }, { 0x7319f6cb, 0x36a },
+ { 0x745096ad, 0x3a8 }, { 0x74866229, 0x4e8c }, { 0x77185fa5, 0x3a8 }, { 0x7953f002, 0x6faf },
+ { 0x7953f003, 0x6fb0 }, { 0x7953f004, 0x6fb1 }, { 0x7953f005, 0x6fb2 }, { 0x7953f006, 0x6fb7 },
+ { 0x7953f00a, 0x6fbd }, { 0x7c577571, 0x2761 }, { 0x7e8c8ff1, 0x479 }, { 0x8031f47f, 0x3b5 },
+ { 0x8031f481, 0x3b5 }, { 0x80c4a710, 0x5187 }, { 0x857c7e14, 0xfde8 }, { 0x857c7e15, 0xfde9 },
+ { 0x86b59c90, 0x4e4 }, { 0x86b59c91, 0x6fb0 }, { 0x86b59c92, 0x6fb1 }, { 0x86b59c93, 0x6fb2 },
+ { 0x86b59c94, 0x6fb3 }, { 0x86b59c95, 0x6fb4 }, { 0x86b59c96, 0x6fb5 }, { 0x86b59c97, 0x4e7 },
+ { 0x86b59c98, 0x4e6 }, { 0x8b4b24ec, 0x5190 }, { 0x8face362, 0x4e4 }, { 0x8ff9ec2a, 0xfde9 },
+ { 0x919d3989, 0xcadc }, { 0x9967e5ad, 0x4e22 }, { 0x99f8b933, 0x6fbd }, { 0x9bd2a380, 0x4fc7 },
+ { 0x9befad23, 0x4f38 }, { 0x9c7ac649, 0x4f3c }, { 0xa02468db, 0xdeae }, { 0xa02468ec, 0xdeab },
+ { 0xa024692a, 0xdeaa }, { 0xa0246997, 0xdeb2 }, { 0xa02469ff, 0xdeb0 }, { 0xa0246a3d, 0xdeb1 },
+ { 0xa0246a8c, 0xdeaf }, { 0xa0246a9a, 0xdeb3 }, { 0xa0246b16, 0xdeac }, { 0xa0246b1a, 0xdead },
+ { 0xa071addc, 0x4b1 }, { 0xa38b62dc, 0x474 }, { 0xa4c09fed, 0x3a8 }, { 0xa51e86e5, 0x4e7 },
+ { 0xa67ab13e, 0x3a4 }, { 0xa7414244, 0x51a9 }, { 0xa9ddbead, 0xc6fb }, { 0xab24ffab, 0x4e8a },
+ { 0xabef8ac4, 0x2710 }, { 0xabfa20ac, 0x6fb4 }, { 0xad36895e, 0x4e2 }, { 0xad36895f, 0x4e3 },
+ { 0xaf310e90, 0x402 }, { 0xaf31166f, 0x4e8 }, { 0xaf7277a5, 0x3b6 }, { 0xafc0d8b3, 0x96c6 },
+ { 0xb0fd5dba, 0xcae0 }, { 0xb0fd5e95, 0xcadc }, { 0xb1052893, 0x7149 }, { 0xb1e98745, 0x36a },
+ { 0xb277e91c, 0x5166 }, { 0xb2f7eac5, 0xcae0 }, { 0xb2f7eba0, 0xcadc }, { 0xb2f7ebc1, 0x3b5 },
+ { 0xb53fa77d, 0x3a8 }, { 0xb6391138, 0x6fb5 }, { 0xb7358b7f, 0x6fb6 }, { 0xb8c42b40, 0x4e4 },
+ { 0xb8c42ea4, 0x1b5 }, { 0xb8c439e7, 0x2e1 }, { 0xb8c43a61, 0x307 }, { 0xb8c43d6c, 0x4e4 },
+ { 0xb8c43ddf, 0x352 }, { 0xb8c43de1, 0x354 }, { 0xb8c43de6, 0x359 }, { 0xb8c43dff, 0x35d },
+ { 0xb8c43e04, 0x362 }, { 0xb8c43e07, 0x365 }, { 0xbcd29a7f, 0x3a8 }, { 0xbce34e78, 0x5182 },
+ { 0xbce34e7b, 0x556a }, { 0xbce81504, 0x3b5 }, { 0xbd8a4c95, 0x272d }, { 0xbdd89dad, 0x4e4 },
+ { 0xbdd89dae, 0x6fb0 }, { 0xbdd89daf, 0x6fb1 }, { 0xbdd89db0, 0x6fb2 }, { 0xbdd89db1, 0x4e6 },
+ { 0xbdd89db5, 0x6fbd }, { 0xc1756e9f, 0x36b }, { 0xc7482444, 0x47a }, { 0xc9281c18, 0x4e4 },
+ { 0xc9ef95df, 0x47b }, { 0xccc9db0d, 0x4e4 }, { 0xccc9db0e, 0x6fb0 }, { 0xcd73425f, 0x3b6 },
+ { 0xce38b40b, 0x4b0 }, { 0xce99e549, 0x25 }, { 0xcf598740, 0x4e7 }, { 0xcf6d6f78, 0x4e4 },
+ { 0xcf758df6, 0x3a4 }, { 0xd1266e51, 0x6fb5 }, { 0xd2910213, 0x2718 }, { 0xd29196bb, 0x2712 },
+ { 0xd3eb2fc2, 0x476 }, { 0xd442dc2c, 0x4fc4 }, { 0xd9da4da4, 0x2711 }, { 0xdbad2f42, 0x4e4 },
+ { 0xdbad2f43, 0x6fb0 }, { 0xdbad2f44, 0x6fb1 }, { 0xdbad2f45, 0x6fb2 }, { 0xdbad2f46, 0x6fb3 },
+ { 0xdbad2f47, 0x6fb4 }, { 0xdbad2f48, 0x6fb5 }, { 0xdbad2f49, 0x6fb6 }, { 0xdbad2f4a, 0x4e6 },
+ { 0xdc438033, 0x4f31 }, { 0xdccb439b, 0x477 }, { 0xdccdc626, 0x3b5 }, { 0xdd80a595, 0x4e4 },
+ { 0xdd80a596, 0x6fb0 }, { 0xdd80a59e, 0x6fb1 }, { 0xdd80a5b4, 0x6fb2 }, { 0xdd80a5d9, 0x6fb5 },
+ { 0xdd80a5da, 0x6fb4 }, { 0xdd80a5fa, 0x6fb6 }, { 0xdd80a615, 0x6fb3 }, { 0xdd80a619, 0x4e6 },
+ { 0xdd80a61a, 0x3b5 }, { 0xdd80c0f8, 0x4e9f }, { 0xdf7e46ff, 0x4fc8 }, { 0xdf8680fd, 0x556a },
+ { 0xdfb0bd6e, 0xc42d }, { 0xdff05486, 0x2c4 }, { 0xe3323399, 0x3a4 }, { 0xe60412dd, 0x3b5 },
+ { 0xeee47add, 0x4b0 }, { 0xf021a186, 0x4e2 }, { 0xf021a187, 0x4e3 }, { 0xf021a188, 0x4e4 },
+ { 0xf021a189, 0x4e5 }, { 0xf021a18a, 0x4e6 }, { 0xf021a18b, 0x4e7 }, { 0xf021a18c, 0x4e8 },
+ { 0xf021a18d, 0x4e9 }, { 0xf021a18e, 0x4ea }, { 0xf0700456, 0x6fb3 }, { 0xf274f175, 0x3b5 },
+ { 0xf2a9730b, 0x3a8 }, { 0xf3d463c2, 0x3a4 }, { 0xf52a70a3, 0xc42e }, { 0xf5693147, 0x6fb3 },
+ { 0xf637e157, 0x478 }, { 0xfc213f3a, 0x2717 }, { 0xff654d14, 0x3b5 },
+};
+FX_WORD FX_GetCodePageFromStringA(FX_LPCSTR pStr, FX_INT32 iLength)
+{
+ FXSYS_assert(pStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_strlen(pStr);
+ }
+ if (iLength == 0) {
+ return 0xFFFF;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetA(pStr, iLength, TRUE);
+ FX_INT32 iStart = 0, iMid;
+ FX_INT32 iEnd = sizeof(g_FXCPHashTable) / sizeof(FX_STR2CPHASH) - 1;
+ FXSYS_assert(iEnd >= 0);
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_STR2CPHASH & cp = g_FXCPHashTable[iMid];
+ if (uHash == cp.uHash) {
+ return (FX_WORD)cp.uCodePage;
+ } else if (uHash < cp.uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 0xFFFF;
+}
+FX_WORD FX_GetCodePageFormStringW(FX_LPCWSTR pStr, FX_INT32 iLength)
+{
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pStr);
+ }
+ if (iLength == 0) {
+ return 0xFFFF;
+ }
+ CFX_ByteString csStr;
+ FX_LPSTR pBuf = csStr.GetBuffer(iLength + 1);
+ for (FX_INT32 i = 0; i < iLength; ++i) {
+ *pBuf ++ = (FX_CHAR) * pStr ++;
+ }
+ csStr.ReleaseBuffer(iLength);
+ return FX_GetCodePageFromStringA(csStr, iLength);
+}
diff --git a/xfa/src/fgas/src/crt/fx_codepage.h b/xfa/src/fgas/src/crt/fx_codepage.h
new file mode 100644
index 0000000000..031f4642cb
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_codepage.h
@@ -0,0 +1,9 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_CODEPAGE_IMP
+#define _FX_CODEPAGE_IMP
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_cpmgr.cpp b/xfa/src/fgas/src/crt/fx_cpmgr.cpp
new file mode 100644
index 0000000000..7bb2aa4a8d
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_cpmgr.cpp
@@ -0,0 +1,65 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_codepage.h"
+#ifdef _FXCP
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+extern const FX_CODEPAGE_HEADER g_CP936_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP932_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP949_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP950_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP874_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1250_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1251_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1252_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1253_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1254_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1255_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1256_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1257_MapHeader;
+extern const FX_CODEPAGE_HEADER g_CP1258_MapHeader;
+extern const FX_CPCU_MAPINFO g_CP936_CUMap;
+extern const FX_CPCU_MAPINFO g_CP932_CUMap;
+extern const FX_CPCU_MAPINFO g_CP949_CUMap;
+extern const FX_CPCU_MAPINFO g_CP950_CUMap;
+extern const FX_CPCU_MAPINFO g_CP874_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1250_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1251_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1252_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1253_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1254_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1255_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1256_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1257_CUMap;
+extern const FX_CPCU_MAPINFO g_CP1258_CUMap;
+FX_LPCCODEPAGE FX_GetCodePage(FX_WORD wCodePage)
+{
+ FX_INT32 iEnd = sizeof(g_FXCodePageMgr) / sizeof(FX_CODEPAGE) - 1;
+ FXSYS_assert(iEnd >= 0);
+ FX_INT32 iStart = 0, iMid;
+ FX_UINT16 uCPID;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FX_CODEPAGE &cp = g_FXCodePageMgr[iMid];
+ uCPID = cp.pCPHeader->uCPID;
+ if (wCodePage == uCPID) {
+ return g_FXCodePageMgr + iMid;
+ } else if (wCodePage < uCPID) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_encode.cpp b/xfa/src/fgas/src/crt/fx_encode.cpp
new file mode 100644
index 0000000000..892b5a9059
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_encode.cpp
@@ -0,0 +1,189 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_codepage.h"
+void FX_SwapByteOrder(FX_LPWSTR pStr, FX_INT32 iLength)
+{
+ FXSYS_assert(pStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pStr);
+ }
+ FX_WORD wch;
+ if (sizeof(FX_WCHAR) > 2) {
+ while (iLength -- > 0) {
+ wch = (FX_WORD) * pStr;
+ wch = (wch >> 8) | (wch << 8);
+ wch &= 0x00FF;
+ *pStr ++ = wch;
+ }
+ } else {
+ while (iLength -- > 0) {
+ wch = (FX_WORD) * pStr;
+ wch = (wch >> 8) | (wch << 8);
+ *pStr ++ = wch;
+ }
+ }
+}
+void FX_SwapByteOrderCopy(FX_LPCWSTR pSrc, FX_LPWSTR pDst, FX_INT32 iLength)
+{
+ FXSYS_assert(pSrc != NULL && pDst != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pSrc);
+ }
+ FX_WORD wch;
+ if (sizeof(FX_WCHAR) > 2) {
+ while (iLength -- > 0) {
+ wch = (FX_WORD) * pSrc ++;
+ wch = (wch >> 8) | (wch << 8);
+ wch &= 0x00FF;
+ *pDst ++ = wch;
+ }
+ } else {
+ while (iLength -- > 0) {
+ wch = (FX_WORD) * pSrc ++;
+ wch = (wch >> 8) | (wch << 8);
+ *pDst ++ = wch;
+ }
+ }
+}
+void FX_UTF16ToWChar(FX_LPVOID pBuffer, FX_INT32 iLength)
+{
+ FXSYS_assert(pBuffer != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ return;
+ }
+ FX_WORD *pSrc = (FX_WORD*)pBuffer;
+ FX_LPWSTR pDst = (FX_LPWSTR)pBuffer;
+ while (--iLength >= 0) {
+ pDst[iLength] = (FX_WCHAR)pSrc[iLength];
+ }
+}
+void FX_UTF16ToWCharCopy(const FX_WORD *pUTF16, FX_LPWSTR pWChar, FX_INT32 iLength)
+{
+ FXSYS_assert(pUTF16 != NULL && pWChar != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ FXSYS_memcpy(pWChar, pUTF16, iLength * sizeof(FX_WCHAR));
+ } else {
+ while (--iLength >= 0) {
+ pWChar[iLength] = (FX_WCHAR)pUTF16[iLength];
+ }
+ }
+}
+void FX_WCharToUTF16(FX_LPVOID pBuffer, FX_INT32 iLength)
+{
+ FXSYS_assert(pBuffer != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ return;
+ }
+ FX_LPCWSTR pSrc = (FX_LPCWSTR)pBuffer;
+ FX_WORD *pDst = (FX_WORD*)pBuffer;
+ while (--iLength >= 0) {
+ *pDst++ = (FX_WORD) * pSrc++;
+ }
+}
+void FX_WCharToUTF16Copy(FX_LPCWSTR pWChar, FX_WORD *pUTF16, FX_INT32 iLength)
+{
+ FXSYS_assert(pWChar != NULL && pUTF16 != NULL && iLength > 0);
+ if (sizeof(FX_WCHAR) == 2) {
+ FXSYS_memcpy(pUTF16, pWChar, iLength * sizeof(FX_WCHAR));
+ } else {
+ while (--iLength >= 0) {
+ *pUTF16++ = (FX_WORD) * pWChar++;
+ }
+ }
+}
+inline FX_DWORD FX_DWordFromBytes(FX_LPCBYTE pStr)
+{
+ return FXBSTR_ID(pStr[3], pStr[2], pStr[1], pStr[0]);
+}
+inline FX_WORD FX_WordFromBytes(FX_LPCBYTE pStr)
+{
+ return (pStr[1] << 8 | pStr[0]);
+}
+FX_INT32 FX_DecodeString(FX_WORD wCodePage, FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen, FX_BOOL bErrBreak)
+{
+ if (wCodePage == FX_CODEPAGE_UTF8) {
+ return FX_UTF8Decode(pSrc, pSrcLen, pDst, pDstLen);
+ }
+ return -1;
+}
+FX_INT32 FX_UTF8Decode(FX_LPCSTR pSrc, FX_INT32 *pSrcLen, FX_LPWSTR pDst, FX_INT32 *pDstLen)
+{
+ if (pSrcLen == NULL || pDstLen == NULL) {
+ return -1;
+ }
+ FX_INT32 iSrcLen = *pSrcLen;
+ if (iSrcLen < 1) {
+ *pSrcLen = *pDstLen = 0;
+ return 1;
+ }
+ FX_INT32 iDstLen = *pDstLen;
+ FX_BOOL bValidDst = (pDst != NULL && iDstLen > 0);
+ FX_DWORD dwCode = 0;
+ FX_INT32 iPending = 0;
+ FX_INT32 iSrcNum = 0, iDstNum = 0;
+ FX_INT32 k = 0;
+ FX_INT32 iIndex = 0;
+ k = 1;
+ while (iIndex < iSrcLen) {
+ FX_BYTE byte = (FX_BYTE) * (pSrc + iIndex);
+ if (byte < 0x80) {
+ iPending = 0;
+ k = 1;
+ iDstNum ++;
+ iSrcNum += k;
+ if (bValidDst) {
+ *pDst ++ = byte;
+ if (iDstNum >= iDstLen) {
+ break;
+ }
+ }
+ } else if (byte < 0xc0) {
+ if (iPending < 1) {
+ break;
+ }
+ iPending--;
+ dwCode |= (byte & 0x3f) << (iPending * 6);
+ if (iPending == 0) {
+ iDstNum ++;
+ iSrcNum += k;
+ if (bValidDst) {
+ *pDst ++ = dwCode;
+ if (iDstNum >= iDstLen) {
+ break;
+ }
+ }
+ }
+ } else if (byte < 0xe0) {
+ iPending = 1;
+ k = 2;
+ dwCode = (byte & 0x1f) << 6;
+ } else if (byte < 0xf0) {
+ iPending = 2;
+ k = 3;
+ dwCode = (byte & 0x0f) << 12;
+ } else if (byte < 0xf8) {
+ iPending = 3;
+ k = 4;
+ dwCode = (byte & 0x07) << 18;
+ } else if (byte < 0xfc) {
+ iPending = 4;
+ k = 5;
+ dwCode = (byte & 0x03) << 24;
+ } else if (byte < 0xfe) {
+ iPending = 5;
+ k = 6;
+ dwCode = (byte & 0x01) << 30;
+ } else {
+ break;
+ }
+ iIndex++;
+ }
+ *pSrcLen = iSrcNum;
+ *pDstLen = iDstNum;
+ return 1;
+}
diff --git a/xfa/src/fgas/src/crt/fx_memory.cpp b/xfa/src/fgas/src/crt/fx_memory.cpp
new file mode 100644
index 0000000000..12d081a645
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_memory.cpp
@@ -0,0 +1,334 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_memory.h"
+#define FX_4BYTEALIGN(size) (((size) + 3) / 4 * 4)
+IFX_MEMAllocator* FX_CreateAllocator(FX_ALLOCTYPE eType, size_t chunkSize, size_t blockSize)
+{
+ switch (eType) {
+#ifndef _FXEMB
+ case FX_ALLOCTYPE_Dynamic:
+ return FXTARGET_New CFX_DynamicStore(chunkSize);
+#endif
+ case FX_ALLOCTYPE_Default:
+ return FXTARGET_New CFX_DefStore();
+ case FX_ALLOCTYPE_Static:
+ return FXTARGET_New CFX_StaticStore(chunkSize);
+ case FX_ALLOCTYPE_Fixed:
+ return FXTARGET_New CFX_FixedStore(blockSize, chunkSize);
+ default:
+ return NULL;
+ }
+}
+CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize)
+ : m_iAllocatedSize(0)
+ , m_iDefChunkSize(iDefChunkSize)
+ , m_pChunk(NULL)
+ , m_pLastChunk(NULL)
+{
+ FXSYS_assert(m_iDefChunkSize != 0);
+}
+CFX_StaticStore::~CFX_StaticStore()
+{
+ register FX_LPSTATICSTORECHUNK pChunk, pNext;
+ pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ pNext = pChunk->pNextChunk;
+ FX_Free(pChunk);
+ pChunk = pNext;
+ }
+}
+FX_LPSTATICSTORECHUNK CFX_StaticStore::AllocChunk(size_t size)
+{
+ FXSYS_assert(size != 0);
+ register FX_LPSTATICSTORECHUNK pChunk = (FX_LPSTATICSTORECHUNK)FX_Alloc(FX_BYTE, sizeof(FX_STATICSTORECHUNK) + size);
+ if (pChunk == NULL) {
+ return NULL;
+ }
+ pChunk->iChunkSize = size;
+ pChunk->iFreeSize = size;
+ pChunk->pNextChunk = NULL;
+ if (m_pLastChunk == NULL) {
+ m_pChunk = pChunk;
+ } else {
+ m_pLastChunk->pNextChunk = pChunk;
+ }
+ m_pLastChunk = pChunk;
+ return pChunk;
+}
+FX_LPSTATICSTORECHUNK CFX_StaticStore::FindChunk(size_t size)
+{
+ FXSYS_assert(size != 0);
+ if (m_pLastChunk == NULL || m_pLastChunk->iFreeSize < size) {
+ return AllocChunk(FX_MAX(m_iDefChunkSize, size));
+ }
+ return m_pLastChunk;
+}
+void* CFX_StaticStore::Alloc(size_t size)
+{
+ size = FX_4BYTEALIGN(size);
+ FXSYS_assert(size != 0);
+ register FX_LPSTATICSTORECHUNK pChunk = FindChunk(size);
+ FXSYS_assert(pChunk != NULL && pChunk->iFreeSize >= size);
+ register FX_LPBYTE p = (FX_LPBYTE)pChunk;
+ p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize;
+ pChunk->iFreeSize -= size;
+ m_iAllocatedSize += size;
+ return p;
+}
+size_t CFX_StaticStore::SetDefChunkSize(size_t size)
+{
+ FXSYS_assert(size != 0);
+ size_t v = m_iDefChunkSize;
+ m_iDefChunkSize = size;
+ return v;
+}
+CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk)
+ : m_iBlockSize(FX_4BYTEALIGN(iBlockSize))
+ , m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk))
+ , m_pChunk(NULL)
+{
+ FXSYS_assert(m_iBlockSize != 0 && m_iDefChunkSize != 0);
+}
+CFX_FixedStore::~CFX_FixedStore()
+{
+ register FX_LPFIXEDSTORECHUNK pChunk, pNext;
+ pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ pNext = pChunk->pNextChunk;
+ FX_Free(pChunk);
+ pChunk = pNext;
+ }
+}
+FX_LPFIXEDSTORECHUNK CFX_FixedStore::AllocChunk()
+{
+ FX_INT32 iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize + m_iBlockSize * m_iDefChunkSize;
+ register FX_LPFIXEDSTORECHUNK pChunk = (FX_LPFIXEDSTORECHUNK)FX_Alloc(FX_BYTE, iTotalSize);
+ if (pChunk == NULL) {
+ return NULL;
+ }
+ FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize);
+ pChunk->pNextChunk = m_pChunk;
+ pChunk->iChunkSize = m_iDefChunkSize;
+ pChunk->iFreeNum = m_iDefChunkSize;
+ m_pChunk = pChunk;
+ return pChunk;
+}
+void* CFX_FixedStore::Alloc(size_t size)
+{
+ if (size > m_iBlockSize) {
+ return NULL;
+ }
+ register FX_LPFIXEDSTORECHUNK pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ if (pChunk->iFreeNum > 0) {
+ break;
+ }
+ pChunk = pChunk->pNextChunk;
+ }
+ if (pChunk == NULL) {
+ pChunk = AllocChunk();
+ }
+ FXSYS_assert(pChunk != NULL);
+ register FX_LPBYTE pFlags = pChunk->FirstFlag();
+ register size_t i = 0;
+ for (; i < pChunk->iChunkSize; i ++)
+ if (pFlags[i] == 0) {
+ break;
+ }
+ FXSYS_assert(i < pChunk->iChunkSize);
+ pFlags[i] = 1;
+ pChunk->iFreeNum --;
+ return pChunk->FirstBlock() + i * m_iBlockSize;
+}
+void CFX_FixedStore::Free(void* pBlock)
+{
+ FXSYS_assert(pBlock != NULL);
+ register FX_LPFIXEDSTORECHUNK pPrior, pChunk;
+ pPrior = NULL, pChunk = m_pChunk;
+ register FX_LPBYTE pStart = NULL, pEnd;
+ while (pChunk != NULL) {
+ pStart = pChunk->FirstBlock();
+ if (pBlock >= pStart) {
+ pEnd = pStart + m_iBlockSize * pChunk->iChunkSize;
+ if (pBlock < pEnd) {
+ break;
+ }
+ }
+ pPrior = pChunk, pChunk = pChunk->pNextChunk;
+ }
+ FXSYS_assert(pChunk != NULL);
+ register size_t iPos = ((FX_LPBYTE)pBlock - pStart) / m_iBlockSize;
+ FXSYS_assert(iPos < pChunk->iChunkSize);
+ register FX_LPBYTE pFlags = pChunk->FirstFlag();
+ if (pFlags[iPos] == 0) {
+ return;
+ }
+ pFlags[iPos] = 0;
+ pChunk->iFreeNum ++;
+ if (pChunk->iFreeNum == pChunk->iChunkSize) {
+ if (pPrior == NULL) {
+ m_pChunk = pChunk->pNextChunk;
+ } else {
+ pPrior->pNextChunk = pChunk->pNextChunk;
+ }
+ FX_Free(pChunk);
+ }
+}
+size_t CFX_FixedStore::SetDefChunkSize(size_t iChunkSize)
+{
+ FXSYS_assert(iChunkSize != 0);
+ size_t v = m_iDefChunkSize;
+ m_iDefChunkSize = FX_4BYTEALIGN(iChunkSize);
+ return v;
+}
+#ifndef _FXEMB
+CFX_DynamicStore::CFX_DynamicStore(size_t iDefChunkSize)
+ : m_iDefChunkSize(iDefChunkSize)
+ , m_pChunk(NULL)
+{
+ FXSYS_assert(m_iDefChunkSize != 0);
+}
+CFX_DynamicStore::~CFX_DynamicStore()
+{
+ register FX_LPDYNAMICSTORECHUNK pChunk, pNext;
+ pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ pNext = pChunk->pNextChunk;
+ FX_Free(pChunk);
+ pChunk = pNext;
+ }
+}
+FX_LPDYNAMICSTORECHUNK CFX_DynamicStore::AllocChunk(size_t size)
+{
+ FXSYS_assert(size != 0);
+ register FX_LPDYNAMICSTORECHUNK pChunk = (FX_LPDYNAMICSTORECHUNK)FX_Alloc(FX_BYTE, sizeof(FX_DYNAMICSTORECHUNK) + sizeof(FX_DYNAMICSTOREBLOCK) * 2 + size);
+ if (pChunk == NULL) {
+ return NULL;
+ }
+ pChunk->iChunkSize = size;
+ pChunk->iFreeSize = size;
+ register FX_LPDYNAMICSTOREBLOCK pBlock = pChunk->FirstBlock();
+ pBlock->iBlockSize = size;
+ pBlock->bUsed = FALSE;
+ pBlock = pBlock->NextBlock();
+ pBlock->iBlockSize = 0;
+ pBlock->bUsed = TRUE;
+ if (m_pChunk != NULL && size >= m_iDefChunkSize) {
+ FX_LPDYNAMICSTORECHUNK pLast = m_pChunk;
+ while (pLast->pNextChunk != NULL) {
+ pLast = pLast->pNextChunk;
+ }
+ pLast->pNextChunk = pChunk;
+ pChunk->pNextChunk = NULL;
+ } else {
+ pChunk->pNextChunk = m_pChunk;
+ m_pChunk = pChunk;
+ }
+ return pChunk;
+}
+void* CFX_DynamicStore::Alloc(size_t size)
+{
+ size = FX_4BYTEALIGN(size);
+ FXSYS_assert(size != 0);
+ register FX_LPDYNAMICSTORECHUNK pChunk = m_pChunk;
+ register FX_LPDYNAMICSTOREBLOCK pBlock = NULL;
+ while (pChunk != NULL) {
+ if (pChunk->iFreeSize >= size) {
+ pBlock = pChunk->FirstBlock();
+ register FX_BOOL bFind = FALSE;
+ while(pBlock->iBlockSize != 0) {
+ if (!pBlock->bUsed && pBlock->iBlockSize >= size) {
+ bFind = TRUE;
+ break;
+ }
+ pBlock = pBlock->NextBlock();
+ }
+ if (bFind) {
+ break;
+ }
+ }
+ pChunk = pChunk->pNextChunk;
+ }
+ if (pChunk == NULL) {
+ pChunk = AllocChunk(FX_MAX(m_iDefChunkSize, size));
+ pBlock = pChunk->FirstBlock();
+ }
+ FXSYS_assert(pChunk != NULL && pBlock != NULL);
+ register size_t m = size + sizeof(FX_DYNAMICSTOREBLOCK);
+ pBlock->bUsed = TRUE;
+ if (pBlock->iBlockSize > m) {
+ register size_t n = pBlock->iBlockSize;
+ pBlock->iBlockSize = size;
+ register FX_LPDYNAMICSTOREBLOCK pNextBlock = pBlock->NextBlock();
+ pNextBlock->bUsed = FALSE;
+ pNextBlock->iBlockSize = n - size - sizeof(FX_DYNAMICSTOREBLOCK);
+ pChunk->iFreeSize -= size + sizeof(FX_DYNAMICSTOREBLOCK);
+ } else {
+ pChunk->iFreeSize -= pBlock->iBlockSize;
+ }
+ return pBlock->Data();
+}
+void CFX_DynamicStore::Free(void* pBlock)
+{
+ FXSYS_assert(pBlock != NULL);
+ register FX_LPDYNAMICSTORECHUNK pPriorChunk, pChunk;
+ pPriorChunk = NULL, pChunk = m_pChunk;
+ while (pChunk != NULL) {
+ if (pBlock > pChunk && pBlock <= ((FX_LPBYTE)pChunk + sizeof(FX_DYNAMICSTORECHUNK) + pChunk->iChunkSize)) {
+ break;
+ }
+ pPriorChunk = pChunk, pChunk = pChunk->pNextChunk;
+ }
+ FXSYS_assert(pChunk != NULL);
+ register FX_LPDYNAMICSTOREBLOCK pPriorBlock, pFindBlock;
+ pPriorBlock = NULL, pFindBlock = pChunk->FirstBlock();
+ while(pFindBlock->iBlockSize != 0) {
+ if (pBlock == (void*)pFindBlock->Data()) {
+ break;
+ }
+ pPriorBlock = pFindBlock;
+ pFindBlock = pFindBlock->NextBlock();
+ }
+ FXSYS_assert(pFindBlock->iBlockSize != 0 && pFindBlock->bUsed && pBlock == (void*)pFindBlock->Data());
+ pFindBlock->bUsed = FALSE;
+ pChunk->iFreeSize += pFindBlock->iBlockSize;
+ if (pPriorBlock == NULL) {
+ pPriorBlock = pChunk->FirstBlock();
+ } else if (pPriorBlock->bUsed) {
+ pPriorBlock = pFindBlock;
+ }
+ pFindBlock = pPriorBlock;
+ register size_t sizeFree = 0;
+ register size_t sizeBlock = 0;
+ while (pFindBlock->iBlockSize != 0 && !pFindBlock->bUsed) {
+ if (pFindBlock != pPriorBlock) {
+ sizeFree += sizeof(FX_DYNAMICSTOREBLOCK);
+ sizeBlock += sizeof(FX_DYNAMICSTOREBLOCK);
+ }
+ sizeBlock += pFindBlock->iBlockSize;
+ pFindBlock = pFindBlock->NextBlock();
+ }
+ pPriorBlock->iBlockSize = sizeBlock;
+ pChunk->iFreeSize += sizeFree;
+ if (pChunk->iFreeSize == pChunk->iChunkSize) {
+ if (pPriorChunk == NULL) {
+ m_pChunk = pChunk->pNextChunk;
+ } else {
+ pPriorChunk->pNextChunk = pChunk->pNextChunk;
+ }
+ FX_Free(pChunk);
+ }
+}
+size_t CFX_DynamicStore::SetDefChunkSize(size_t size)
+{
+ FXSYS_assert(size != 0);
+ size_t v = m_iDefChunkSize;
+ m_iDefChunkSize = size;
+ return v;
+}
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_memory.h b/xfa/src/fgas/src/crt/fx_memory.h
new file mode 100644
index 0000000000..9121c32c0f
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_memory.h
@@ -0,0 +1,199 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_MEMORY_IMP
+#define _FX_MEMORY_IMP
+class CFX_DefStore;
+class CFX_StaticStore;
+class CFX_FixedStore;
+class CFX_DynamicStore;
+class CFX_DefStore : public IFX_MEMAllocator, public CFX_Target
+{
+public:
+ CFX_DefStore() {}
+ ~CFX_DefStore() {}
+ virtual void Release()
+ {
+ FXTARGET_Delete this;
+ }
+ virtual void* Alloc(size_t size)
+ {
+ return FX_Alloc(FX_BYTE, size);
+ }
+ virtual void Free(void *pBlock)
+ {
+ FX_Free(pBlock);
+ }
+ virtual size_t GetBlockSize() const
+ {
+ return 0;
+ }
+ virtual size_t GetDefChunkSize() const
+ {
+ return 0;
+ }
+ virtual size_t SetDefChunkSize(size_t size)
+ {
+ return 0;
+ }
+ virtual size_t GetCurrentDataSize() const
+ {
+ return 0;
+ }
+};
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(push, 1)
+#endif
+typedef struct _FX_STATICSTORECHUNK {
+ _FX_STATICSTORECHUNK* pNextChunk;
+ size_t iChunkSize;
+ size_t iFreeSize;
+} FX_STATICSTORECHUNK, * FX_LPSTATICSTORECHUNK;
+typedef FX_STATICSTORECHUNK const * FX_LPCSTATICSTORECHUNK;
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(pop)
+#endif
+class CFX_StaticStore : public IFX_MEMAllocator, public CFX_Target
+{
+public:
+ CFX_StaticStore(size_t iDefChunkSize = 4096);
+ ~CFX_StaticStore();
+ virtual void Release()
+ {
+ FXTARGET_Delete this;
+ }
+ virtual void* Alloc(size_t size);
+ virtual void Free(FX_LPVOID pBlock) {}
+ virtual size_t GetBlockSize() const
+ {
+ return 0;
+ }
+ virtual size_t GetDefChunkSize() const
+ {
+ return m_iDefChunkSize;
+ }
+ virtual size_t SetDefChunkSize(size_t size);
+ virtual size_t GetCurrentDataSize() const
+ {
+ return m_iAllocatedSize;
+ }
+protected:
+ size_t m_iAllocatedSize;
+ size_t m_iDefChunkSize;
+ FX_LPSTATICSTORECHUNK m_pChunk;
+ FX_LPSTATICSTORECHUNK m_pLastChunk;
+ FX_LPSTATICSTORECHUNK AllocChunk(size_t size);
+ FX_LPSTATICSTORECHUNK FindChunk(size_t size);
+};
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(push, 1)
+#endif
+typedef struct _FX_FIXEDSTORECHUNK {
+ FX_LPBYTE FirstFlag() const
+ {
+ return (FX_LPBYTE)this + sizeof(_FX_FIXEDSTORECHUNK);
+ }
+ FX_LPBYTE FirstBlock() const
+ {
+ return FirstFlag() + iChunkSize;
+ }
+ _FX_FIXEDSTORECHUNK* pNextChunk;
+ size_t iChunkSize;
+ size_t iFreeNum;
+} FX_FIXEDSTORECHUNK, * FX_LPFIXEDSTORECHUNK;
+typedef FX_FIXEDSTORECHUNK const * FX_LPCFIXEDSTORECHUNK;
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(pop)
+#endif
+class CFX_FixedStore : public IFX_MEMAllocator, public CFX_Target
+{
+public:
+ CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk);
+ virtual ~CFX_FixedStore();
+ virtual void Release()
+ {
+ FXTARGET_Delete this;
+ }
+ virtual void* Alloc(size_t size);
+ virtual void Free(FX_LPVOID pBlock);
+ virtual size_t GetBlockSize() const
+ {
+ return m_iBlockSize;
+ }
+ virtual size_t GetDefChunkSize() const
+ {
+ return m_iDefChunkSize;
+ }
+ virtual size_t SetDefChunkSize(size_t iChunkSize);
+ virtual size_t GetCurrentDataSize() const
+ {
+ return 0;
+ }
+protected:
+ size_t m_iBlockSize;
+ size_t m_iDefChunkSize;
+ FX_LPFIXEDSTORECHUNK m_pChunk;
+ FX_LPFIXEDSTORECHUNK AllocChunk();
+};
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(push, 1)
+#endif
+typedef struct _FX_DYNAMICSTOREBLOCK {
+ _FX_DYNAMICSTOREBLOCK* NextBlock() const
+ {
+ return (_FX_DYNAMICSTOREBLOCK*)(Data() + iBlockSize);
+ }
+ FX_LPBYTE Data() const
+ {
+ return (FX_LPBYTE)this + sizeof(_FX_DYNAMICSTOREBLOCK);
+ }
+ size_t iBlockSize;
+ FX_BOOL bUsed;
+} FX_DYNAMICSTOREBLOCK, * FX_LPDYNAMICSTOREBLOCK;
+typedef FX_DYNAMICSTOREBLOCK const * FX_LPCDYNAMICSTOREBLOCK;
+typedef struct _FX_DYNAMICSTORECHUNK {
+ FX_LPDYNAMICSTOREBLOCK FirstBlock() const
+ {
+ return (FX_LPDYNAMICSTOREBLOCK)((FX_LPBYTE)this + sizeof(_FX_DYNAMICSTORECHUNK));
+ }
+ _FX_DYNAMICSTORECHUNK* pNextChunk;
+ size_t iChunkSize;
+ size_t iFreeSize;
+} FX_DYNAMICSTORECHUNK, * FX_LPDYNAMICSTORECHUNK;
+typedef FX_DYNAMICSTORECHUNK const * FX_LPCDYNAMICSTORECHUNK;
+#if _FX_OS_ != _FX_ANDROID_
+#pragma pack(pop)
+#endif
+class CFX_DynamicStore : public IFX_MEMAllocator, public CFX_Target
+{
+public:
+ CFX_DynamicStore(size_t iDefChunkSize = 4096);
+ virtual ~CFX_DynamicStore();
+ virtual void Release()
+ {
+ FXTARGET_Delete this;
+ }
+ virtual void* Alloc(size_t size);
+ virtual void Free(FX_LPVOID pBlock);
+ virtual size_t GetBlockSize() const
+ {
+ return 0;
+ }
+ virtual size_t GetDefChunkSize() const
+ {
+ return m_iDefChunkSize;
+ }
+ virtual size_t SetDefChunkSize(size_t size);
+ virtual size_t GetCurrentDataSize() const
+ {
+ return 0;
+ }
+protected:
+ size_t m_iDefChunkSize;
+ FX_LPDYNAMICSTORECHUNK m_pChunk;
+ FX_LPDYNAMICSTORECHUNK AllocChunk(size_t size);
+};
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_stream.cpp b/xfa/src/fgas/src/crt/fx_stream.cpp
new file mode 100644
index 0000000000..fff3fe1e86
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_stream.cpp
@@ -0,0 +1,1613 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_stream.h"
+IFX_Stream* IFX_Stream::CreateStream(IFX_BufferRead *pBufferRead, FX_DWORD dwAccess, FX_INT32 iFileSize, FX_BOOL bReleaseBufferRead )
+{
+ CFX_Stream *pSR = FX_NEW CFX_Stream;
+ if (!pSR) {
+ return NULL;
+ }
+ if (!pSR->LoadBufferRead(pBufferRead, iFileSize, dwAccess, bReleaseBufferRead)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE);
+ if (!pTR) {
+ pTR->Release();
+ pTR = NULL;
+ }
+ return pTR;
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(IFX_FileRead *pFileRead, FX_DWORD dwAccess)
+{
+ CFX_Stream *pSR = FX_NEW CFX_Stream;
+ if (pSR == NULL) {
+ return NULL;
+ }
+ if (!pSR->LoadFileRead(pFileRead, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE);
+ if (pTR == NULL) {
+ pSR->Release();
+ return NULL;
+ }
+ return pTR;
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess)
+{
+ CFX_Stream *pSR = FX_NEW CFX_Stream;
+ if (pSR == NULL) {
+ return NULL;
+ }
+ if (!pSR->LoadFileWrite(pFileWrite, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE);
+ if (pTR == NULL) {
+ pSR->Release();
+ return NULL;
+ }
+ return pTR;
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(FX_LPCWSTR pszFileName, FX_DWORD dwAccess)
+{
+ CFX_Stream *pSR = FX_NEW CFX_Stream;
+ if (pSR == NULL) {
+ return NULL;
+ }
+ if (!pSR->LoadFile(pszFileName, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE);
+ if (pTR == NULL) {
+ pSR->Release();
+ return NULL;
+ }
+ return pTR;
+ }
+ return pSR;
+}
+IFX_Stream* IFX_Stream::CreateStream(FX_LPBYTE pData, FX_INT32 length, FX_DWORD dwAccess)
+{
+ CFX_Stream *pSR = FX_NEW CFX_Stream;
+ if (pSR == NULL) {
+ return NULL;
+ }
+ if (!pSR->LoadBuffer(pData, length, dwAccess)) {
+ pSR->Release();
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE);
+ if (pTR == NULL) {
+ pSR->Release();
+ return NULL;
+ }
+ return pTR;
+ }
+ return pSR;
+}
+CFX_StreamImp::CFX_StreamImp()
+ : CFX_ThreadLock()
+ , m_dwAccess(0)
+{
+}
+CFX_FileStreamImp::CFX_FileStreamImp()
+ : CFX_StreamImp()
+ , m_hFile(NULL)
+ , m_iLength(0)
+{
+}
+CFX_FileStreamImp::~CFX_FileStreamImp()
+{
+ if (m_hFile != NULL) {
+ FXSYS_fclose(m_hFile);
+ }
+}
+FX_BOOL CFX_FileStreamImp::LoadFile(FX_LPCWSTR pszSrcFileName, FX_DWORD dwAccess)
+{
+ FXSYS_assert(m_hFile == NULL);
+ FXSYS_assert(pszSrcFileName != NULL && FXSYS_wcslen(pszSrcFileName) > 0);
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+ CFX_WideString wsMode;
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Append) {
+ wsMode = L"a+b";
+ } else if (dwAccess & FX_STREAMACCESS_Truncate) {
+ wsMode = L"w+b";
+ } else {
+ wsMode = L"r+b";
+ }
+ } else {
+ wsMode = L"rb";
+ }
+#ifdef _FX_WINAPI_PARTITION_APP_
+ CFX_WideString wsSrcFileName(pszSrcFileName);
+ _wfopen_s(&m_hFile, wsSrcFileName, wsMode);
+#else
+ m_hFile = FXSYS_wfopen(pszSrcFileName, wsMode);
+#endif
+ if (m_hFile == NULL) {
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Create) {
+#ifdef _FX_WINAPI_PARTITION_APP_
+ CFX_WideString wsSrcFileName(pszSrcFileName);
+ _wfopen_s(&m_hFile, wsSrcFileName, L"w+b");
+#else
+ m_hFile = FXSYS_wfopen(pszSrcFileName, L"w+b");
+#endif
+ }
+ if (m_hFile == NULL) {
+#ifdef _FX_WINAPI_PARTITION_APP_
+ CFX_WideString wsSrcFileName(pszSrcFileName);
+ _wfopen_s(&m_hFile, wsSrcFileName, L"r+b");
+#else
+ m_hFile = FXSYS_wfopen(pszSrcFileName, L"r+b");
+#endif
+ if (m_hFile == NULL) {
+ return FALSE;
+ }
+ if (dwAccess & FX_STREAMACCESS_Truncate) {
+ FX_fsetsize(m_hFile, 0);
+ }
+ }
+ } else {
+ return FALSE;
+ }
+ }
+#else
+ CFX_ByteString wsMode;
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Append) {
+ wsMode = "a+b";
+ } else if (dwAccess & FX_STREAMACCESS_Truncate) {
+ wsMode = "w+b";
+ } else {
+ wsMode = "r+b";
+ }
+ } else {
+ wsMode = "rb";
+ }
+ CFX_ByteString szFileName = CFX_ByteString::FromUnicode(pszSrcFileName);
+ m_hFile = FXSYS_fopen(szFileName, wsMode);
+ if (m_hFile == NULL) {
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ if (dwAccess & FX_STREAMACCESS_Create) {
+ m_hFile = FXSYS_fopen(szFileName, "w+b");
+ }
+ if (m_hFile == NULL) {
+ m_hFile = FXSYS_fopen(szFileName, "r+b");
+ if (m_hFile == NULL) {
+ return FALSE;
+ }
+ if (dwAccess & FX_STREAMACCESS_Truncate) {
+ FX_fsetsize(m_hFile, 0);
+ }
+ }
+ } else {
+ return FALSE;
+ }
+ }
+#endif
+ m_dwAccess = dwAccess;
+ if ((dwAccess & (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) == (FX_STREAMACCESS_Write | FX_STREAMACCESS_Truncate)) {
+ m_iLength = 0;
+ } else {
+ m_iLength = FX_filelength(m_hFile);
+ }
+ return TRUE;
+}
+FX_INT32 CFX_FileStreamImp::GetLength() const
+{
+ FXSYS_assert(m_hFile != NULL);
+ return m_iLength;
+}
+FX_INT32 CFX_FileStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ FXSYS_assert(m_hFile != NULL);
+ FXSYS_fseek(m_hFile, iOffset, eSeek);
+ return FXSYS_ftell(m_hFile);
+}
+FX_INT32 CFX_FileStreamImp::GetPosition()
+{
+ FXSYS_assert(m_hFile != NULL);
+ return FXSYS_ftell(m_hFile);
+}
+FX_BOOL CFX_FileStreamImp::IsEOF() const
+{
+ FXSYS_assert(m_hFile != NULL);
+ return FXSYS_ftell(m_hFile) >= m_iLength;
+}
+FX_INT32 CFX_FileStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(m_hFile != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ return FXSYS_fread(pBuffer, 1, iBufferSize, m_hFile);
+}
+FX_INT32 CFX_FileStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS)
+{
+ FXSYS_assert(m_hFile != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ if (m_iLength <= 0) {
+ return 0;
+ }
+ FX_INT32 iPosition = FXSYS_ftell(m_hFile);
+ FX_INT32 iLen = FX_MIN((m_iLength - iPosition) / 2, iMaxLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ iLen = FXSYS_fread(pStr, 2, iLen, m_hFile);
+ FX_INT32 iCount = 0;
+ while (*pStr != L'\0' && iCount < iLen) {
+ pStr ++, iCount ++;
+ }
+ iPosition += iCount * 2;
+ if (FXSYS_ftell(m_hFile) != iPosition) {
+ FXSYS_fseek(m_hFile, iPosition, 0);
+ }
+ bEOS = (iPosition >= m_iLength);
+ return iCount;
+}
+FX_INT32 CFX_FileStreamImp::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ FX_INT32 iRet = FXSYS_fwrite(pBuffer, 1, iBufferSize, m_hFile);
+ if (iRet != 0) {
+ FX_INT32 iPos = FXSYS_ftell(m_hFile);
+ if (iPos > m_iLength) {
+ m_iLength = iPos;
+ }
+ }
+ return iRet;
+}
+FX_INT32 CFX_FileStreamImp::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+{
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ FX_INT32 iRet = FXSYS_fwrite(pStr, 2, iLength, m_hFile);
+ if (iRet != 0) {
+ FX_INT32 iPos = FXSYS_ftell(m_hFile);
+ if (iPos > m_iLength) {
+ m_iLength = iPos;
+ }
+ }
+ return iRet;
+}
+void CFX_FileStreamImp::Flush()
+{
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_fflush(m_hFile);
+}
+FX_BOOL CFX_FileStreamImp::SetLength(FX_INT32 iLength)
+{
+ FXSYS_assert(m_hFile != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FX_BOOL bRet = FX_fsetsize(m_hFile, iLength);
+ m_iLength = FX_filelength(m_hFile);
+ return bRet;
+}
+CFX_FileReadStreamImp::CFX_FileReadStreamImp()
+ : m_pFileRead(NULL)
+ , m_iPosition(0)
+ , m_iLength(0)
+{
+}
+FX_BOOL CFX_FileReadStreamImp::LoadFileRead(IFX_FileRead *pFileRead, FX_DWORD dwAccess)
+{
+ FXSYS_assert(m_pFileRead == NULL && pFileRead != NULL);
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ return FALSE;
+ }
+ m_pFileRead = pFileRead;
+ m_iLength = m_pFileRead->GetSize();
+ return TRUE;
+}
+FX_INT32 CFX_FileReadStreamImp::GetLength() const
+{
+ return m_iLength;
+}
+FX_INT32 CFX_FileReadStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ switch (eSeek) {
+ case FX_STREAMSEEK_Begin:
+ m_iPosition = iOffset;
+ break;
+ case FX_STREAMSEEK_Current:
+ m_iPosition += iOffset;
+ break;
+ case FX_STREAMSEEK_End:
+ m_iPosition = m_iLength + iOffset;
+ break;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ } else if (m_iPosition >= m_iLength) {
+ m_iPosition = m_iLength;
+ }
+ return m_iPosition;
+}
+FX_BOOL CFX_FileReadStreamImp::IsEOF() const
+{
+ return m_iPosition >= m_iLength;
+}
+FX_INT32 CFX_FileReadStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(m_pFileRead != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ if (iBufferSize > m_iLength - m_iPosition) {
+ iBufferSize = m_iLength - m_iPosition;
+ }
+ if (m_pFileRead->ReadBlock(pBuffer, m_iPosition, iBufferSize)) {
+ m_iPosition += iBufferSize;
+ return iBufferSize;
+ }
+ return 0;
+}
+FX_INT32 CFX_FileReadStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS)
+{
+ FXSYS_assert(m_pFileRead != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ iMaxLength = ReadData((FX_LPBYTE)pStr, iMaxLength * 2) / 2;
+ if (iMaxLength <= 0) {
+ return 0;
+ }
+ FX_INT32 i = 0;
+ while (i < iMaxLength && pStr[i] != L'\0') {
+ ++i;
+ }
+ bEOS = (m_iPosition >= m_iLength) || pStr[i] == L'\0';
+ return i;
+}
+CFX_BufferReadStreamImp::CFX_BufferReadStreamImp()
+ : m_pBufferRead(NULL)
+ , m_bReleaseBufferRead(FALSE)
+ , m_iPosition(0)
+ , m_iBufferSize(0)
+{
+}
+CFX_BufferReadStreamImp::~CFX_BufferReadStreamImp()
+{
+ if (m_bReleaseBufferRead && m_pBufferRead != NULL) {
+ m_pBufferRead->Release();
+ }
+}
+FX_BOOL CFX_BufferReadStreamImp::LoadBufferRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_DWORD dwAccess, FX_BOOL bReleaseBufferRead)
+{
+ FXSYS_assert(m_pBufferRead == NULL && pBufferRead != NULL);
+ if (dwAccess & FX_STREAMACCESS_Write) {
+ return FALSE;
+ }
+ m_bReleaseBufferRead = bReleaseBufferRead;
+ m_pBufferRead = pBufferRead;
+ m_iBufferSize = iFileSize;
+ if (m_iBufferSize >= 0) {
+ return TRUE;
+ }
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return FALSE;
+ }
+ m_iBufferSize = m_pBufferRead->GetBlockSize();
+ while (!m_pBufferRead->IsEOF()) {
+ m_pBufferRead->ReadNextBlock(FALSE);
+ m_iBufferSize += m_pBufferRead->GetBlockSize();
+ }
+ return TRUE;
+}
+FX_INT32 CFX_BufferReadStreamImp::GetLength() const
+{
+ return m_iBufferSize;
+}
+FX_INT32 CFX_BufferReadStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ FX_INT32 iLength = GetLength();
+ switch (eSeek) {
+ case FX_STREAMSEEK_Begin:
+ m_iPosition = iOffset;
+ break;
+ case FX_STREAMSEEK_Current:
+ m_iPosition += iOffset;
+ break;
+ case FX_STREAMSEEK_End:
+ m_iPosition = iLength + iOffset;
+ break;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ } else if (m_iPosition >= iLength) {
+ m_iPosition = iLength;
+ }
+ return m_iPosition;
+}
+FX_BOOL CFX_BufferReadStreamImp::IsEOF() const
+{
+ return m_pBufferRead ? m_pBufferRead->IsEOF() : TRUE;
+}
+FX_INT32 CFX_BufferReadStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(m_pBufferRead != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ FX_INT32 iLength = GetLength();
+ if (m_iPosition >= iLength) {
+ return 0;
+ }
+ if (iBufferSize > iLength - m_iPosition) {
+ iBufferSize = iLength - m_iPosition;
+ }
+ FX_DWORD dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ FX_DWORD dwBlockSize = m_pBufferRead->GetBlockSize();
+ if (m_iPosition < (FX_INT32)dwBlockOffset) {
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return 0;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ }
+ while (m_iPosition < (FX_INT32)dwBlockOffset || m_iPosition >= (FX_INT32)(dwBlockOffset + dwBlockSize)) {
+ if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ }
+ if (m_iPosition < (FX_INT32)dwBlockOffset || m_iPosition >= (FX_INT32)(dwBlockOffset + dwBlockSize)) {
+ return 0;
+ }
+ FX_LPCBYTE pBufferTmp = m_pBufferRead->GetBlockBuffer();
+ FX_DWORD dwOffsetTmp = m_iPosition - dwBlockOffset;
+ FX_DWORD dwCopySize = FX_MIN(iBufferSize, (FX_INT32)(dwBlockSize - dwOffsetTmp));
+ FXSYS_memcpy(pBuffer, pBufferTmp + dwOffsetTmp, dwCopySize);
+ dwOffsetTmp = dwCopySize;
+ iBufferSize -= dwCopySize;
+ while (iBufferSize > 0) {
+ if (!m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ pBufferTmp = m_pBufferRead->GetBlockBuffer();
+ dwCopySize = FX_MIN((FX_DWORD)iBufferSize, dwBlockSize);
+ FXSYS_memcpy(pBuffer + dwOffsetTmp, pBufferTmp, dwCopySize);
+ dwOffsetTmp += dwCopySize;
+ iBufferSize -= dwCopySize;
+ }
+ m_iPosition += dwOffsetTmp;
+ return dwOffsetTmp;
+}
+FX_INT32 CFX_BufferReadStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS)
+{
+ FXSYS_assert(m_pBufferRead != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ iMaxLength = ReadData((FX_LPBYTE)pStr, iMaxLength * 2) / 2;
+ if (iMaxLength <= 0) {
+ return 0;
+ }
+ FX_INT32 i = 0;
+ while (i < iMaxLength && pStr[i] != L'\0') {
+ ++i;
+ }
+ bEOS = (m_iPosition >= GetLength()) || pStr[i] == L'\0';
+ return i;
+}
+CFX_FileWriteStreamImp::CFX_FileWriteStreamImp()
+ : m_pFileWrite(NULL)
+ , m_iPosition(0)
+{
+}
+FX_BOOL CFX_FileWriteStreamImp::LoadFileWrite(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess)
+{
+ FXSYS_assert(m_pFileWrite == NULL && pFileWrite != NULL);
+ if (dwAccess & FX_STREAMACCESS_Read) {
+ return FALSE;
+ }
+ if (dwAccess & FX_STREAMACCESS_Append) {
+ m_iPosition = pFileWrite->GetSize();
+ }
+ m_pFileWrite = pFileWrite;
+ return TRUE;
+}
+FX_INT32 CFX_FileWriteStreamImp::GetLength() const
+{
+ if (!m_pFileWrite) {
+ return 0;
+ }
+ return (FX_INT32)m_pFileWrite->GetSize();
+}
+FX_INT32 CFX_FileWriteStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ FX_INT32 iLength = GetLength();
+ switch (eSeek) {
+ case FX_STREAMSEEK_Begin:
+ m_iPosition = iOffset;
+ break;
+ case FX_STREAMSEEK_Current:
+ m_iPosition += iOffset;
+ break;
+ case FX_STREAMSEEK_End:
+ m_iPosition = iLength + iOffset;
+ break;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ } else if (m_iPosition >= iLength) {
+ m_iPosition = iLength;
+ }
+ return m_iPosition;
+}
+FX_BOOL CFX_FileWriteStreamImp::IsEOF() const
+{
+ return m_iPosition >= GetLength();
+}
+FX_INT32 CFX_FileWriteStreamImp::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ if (!m_pFileWrite) {
+ return 0;
+ }
+ if (m_pFileWrite->WriteBlock(pBuffer, m_iPosition, iBufferSize)) {
+ m_iPosition += iBufferSize;
+ }
+ return iBufferSize;
+}
+FX_INT32 CFX_FileWriteStreamImp::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+{
+ return WriteData((FX_LPCBYTE)pStr, iLength * sizeof(FX_WCHAR));
+}
+void CFX_FileWriteStreamImp::Flush()
+{
+ if (m_pFileWrite) {
+ m_pFileWrite->Flush();
+ }
+}
+CFX_BufferStreamImp::CFX_BufferStreamImp()
+ : CFX_StreamImp()
+ , m_pData(NULL)
+ , m_iTotalSize(0)
+ , m_iPosition(0)
+ , m_iLength(0)
+{
+}
+FX_BOOL CFX_BufferStreamImp::LoadBuffer(FX_LPBYTE pData, FX_INT32 iTotalSize, FX_DWORD dwAccess)
+{
+ FXSYS_assert(m_pData == NULL);
+ FXSYS_assert(pData != NULL && iTotalSize > 0);
+ m_dwAccess = dwAccess;
+ m_pData = pData;
+ m_iTotalSize = iTotalSize;
+ m_iPosition = 0;
+ m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iTotalSize;
+ return TRUE;
+}
+FX_INT32 CFX_BufferStreamImp::GetLength() const
+{
+ FXSYS_assert(m_pData != NULL);
+ return m_iLength;
+}
+FX_INT32 CFX_BufferStreamImp::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ FXSYS_assert(m_pData != NULL);
+ if (eSeek == FX_STREAMSEEK_Begin) {
+ m_iPosition = iOffset;
+ } else if (eSeek == FX_STREAMSEEK_Current) {
+ m_iPosition += iOffset;
+ } else if (eSeek == FX_STREAMSEEK_End) {
+ m_iPosition = m_iLength + iOffset;
+ }
+ if (m_iPosition > m_iLength) {
+ m_iPosition = m_iLength;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ }
+ return m_iPosition;
+}
+FX_INT32 CFX_BufferStreamImp::GetPosition()
+{
+ FXSYS_assert(m_pData != NULL);
+ return m_iPosition;
+}
+FX_BOOL CFX_BufferStreamImp::IsEOF() const
+{
+ FXSYS_assert(m_pData != NULL);
+ return m_iPosition >= m_iLength;
+}
+FX_INT32 CFX_BufferStreamImp::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(m_pData != NULL);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ FX_INT32 iLen = FX_MIN(m_iLength - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ FXSYS_memcpy(pBuffer, m_pData + m_iPosition, iLen);
+ m_iPosition += iLen;
+ return iLen;
+}
+FX_INT32 CFX_BufferStreamImp::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS)
+{
+ FXSYS_assert(m_pData != NULL);
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ FX_INT32 iLen = FX_MIN((m_iLength - m_iPosition) / 2, iMaxLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ FX_LPCWSTR pSrc = (FX_LPCWSTR)(FX_LPSTR)(m_pData + m_iPosition);
+ FX_INT32 iCount = 0;
+ while (*pSrc != L'\0' && iCount < iLen) {
+ *pStr ++ = *pSrc ++, iCount ++;
+ }
+ m_iPosition += iCount * 2;
+ bEOS = (*pSrc == L'\0') || (m_iPosition >= m_iLength);
+ return iCount;
+}
+FX_INT32 CFX_BufferStreamImp::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ FX_INT32 iLen = FX_MIN(m_iTotalSize - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ FXSYS_memcpy(m_pData + m_iPosition, pBuffer, iLen);
+ m_iPosition += iLen;
+ if (m_iPosition > m_iLength) {
+ m_iLength = m_iPosition;
+ }
+ return iLen;
+}
+FX_INT32 CFX_BufferStreamImp::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+{
+ FXSYS_assert(m_pData != NULL && (m_dwAccess & FX_STREAMACCESS_Write) != 0);
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ FX_INT32 iLen = FX_MIN((m_iTotalSize - m_iPosition) / 2, iLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ FXSYS_memcpy(m_pData + m_iPosition, pStr, iLen * 2);
+ m_iPosition += iLen * 2;
+ if (m_iPosition > m_iLength) {
+ m_iLength = m_iPosition;
+ }
+ return iLen;
+}
+IFX_Stream* IFX_Stream::CreateTextStream(IFX_Stream *pBaseStream, FX_BOOL bDeleteOnRelease)
+{
+ FXSYS_assert(pBaseStream != NULL);
+ return FX_NEW CFX_TextStream(pBaseStream, bDeleteOnRelease);
+}
+CFX_TextStream::CFX_TextStream(IFX_Stream *pStream, FX_BOOL bDelStream)
+ : m_wCodePage(FX_CODEPAGE_DefANSI)
+ , m_wBOMLength(0)
+ , m_dwBOM(0)
+ , m_pBuf(NULL)
+ , m_iBufSize(0)
+ , m_bDelStream(bDelStream)
+ , m_pStreamImp(pStream)
+ , m_iRefCount(1)
+{
+ FXSYS_assert(m_pStreamImp != NULL);
+ m_pStreamImp->Retain();
+ InitStream();
+}
+CFX_TextStream::~CFX_TextStream()
+{
+ m_pStreamImp->Release();
+ if (m_bDelStream) {
+ m_pStreamImp->Release();
+ }
+ if (m_pBuf != NULL) {
+ FX_Free(m_pBuf);
+ }
+}
+void CFX_TextStream::InitStream()
+{
+ FX_INT32 iPosition = m_pStreamImp->GetPosition();
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, 0);
+ m_pStreamImp->ReadData((FX_LPBYTE)&m_dwBOM, 3);
+#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
+ m_dwBOM &= 0x00FFFFFF;
+ if (m_dwBOM == 0x00BFBBEF) {
+ m_wBOMLength = 3;
+ m_wCodePage = FX_CODEPAGE_UTF8;
+ } else {
+ m_dwBOM &= 0x0000FFFF;
+ if (m_dwBOM == 0x0000FFFE) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16BE;
+ } else if (m_dwBOM == 0x0000FEFF) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16LE;
+ } else {
+ m_wBOMLength = 0;
+ m_dwBOM = 0;
+ m_wCodePage = FXSYS_GetACP();
+ }
+ }
+#else
+ m_dwBOM &= 0xFFFFFF00;
+ if (m_dwBOM == 0xEFBBBF00) {
+ m_wBOMLength = 3;
+ m_wCodePage = FX_CODEPAGE_UTF8;
+ } else {
+ m_dwBOM &= 0xFFFF0000;
+ if (m_dwBOM == 0xFEFF0000) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16BE;
+ } else if (m_dwBOM == 0xFFFE0000) {
+ m_wBOMLength = 2;
+ m_wCodePage = FX_CODEPAGE_UTF16LE;
+ } else {
+ m_wBOMLength = 0;
+ m_dwBOM = 0;
+ m_wCodePage = FXSYS_GetACP();
+ }
+ }
+#endif
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, FX_MAX(m_wBOMLength, iPosition));
+}
+void CFX_TextStream::Release()
+{
+ if (--m_iRefCount < 1) {
+ delete this;
+ }
+}
+IFX_Stream* CFX_TextStream::Retain()
+{
+ m_iRefCount++;
+ return this;
+}
+FX_DWORD CFX_TextStream::GetAccessModes() const
+{
+ return m_pStreamImp->GetAccessModes() | FX_STREAMACCESS_Text;
+}
+FX_INT32 CFX_TextStream::GetLength() const
+{
+ return m_pStreamImp->GetLength();
+}
+FX_INT32 CFX_TextStream::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ return m_pStreamImp->Seek(eSeek, iOffset);
+}
+FX_INT32 CFX_TextStream::GetPosition()
+{
+ return m_pStreamImp->GetPosition();
+}
+FX_BOOL CFX_TextStream::IsEOF() const
+{
+ return m_pStreamImp->IsEOF();
+}
+FX_INT32 CFX_TextStream::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ return m_pStreamImp->ReadData(pBuffer, iBufferSize);
+}
+FX_INT32 CFX_TextStream::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ return m_pStreamImp->WriteData(pBuffer, iBufferSize);
+}
+void CFX_TextStream::Flush()
+{
+ m_pStreamImp->Flush();
+}
+FX_BOOL CFX_TextStream::SetLength(FX_INT32 iLength)
+{
+ return m_pStreamImp->SetLength(iLength);
+}
+FX_WORD CFX_TextStream::GetCodePage() const
+{
+ return m_wCodePage;
+}
+IFX_Stream* CFX_TextStream::CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength)
+{
+ IFX_Stream *pSR = m_pStreamImp->CreateSharedStream(dwAccess, iOffset, iLength);
+ if (pSR == NULL) {
+ return NULL;
+ }
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ IFX_Stream *pTR = FX_NEW CFX_TextStream(pSR, TRUE);
+ if (pTR == NULL) {
+ pSR->Release();
+ return NULL;
+ }
+ return pTR;
+ }
+ return pSR;
+}
+FX_INT32 CFX_TextStream::GetBOM(FX_BYTE bom[4]) const
+{
+ if (m_wBOMLength < 1) {
+ return 0;
+ }
+ *(FX_DWORD*)bom = m_dwBOM;
+ return (FX_INT32)m_wBOMLength;
+}
+FX_WORD CFX_TextStream::SetCodePage(FX_WORD wCodePage)
+{
+ if (m_wBOMLength > 0) {
+ return m_wCodePage;
+ }
+ FX_WORD v = m_wCodePage;
+ m_wCodePage = wCodePage;
+ return v;
+}
+FX_INT32 CFX_TextStream::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize)
+{
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ FX_INT32 iLen;
+ if (m_wCodePage == FX_CODEPAGE_UTF16LE || m_wCodePage == FX_CODEPAGE_UTF16BE) {
+ FX_INT32 iBytes = pByteSize == NULL ? iMaxLength * 2 : *pByteSize;
+ m_pStreamImp->Lock();
+ iLen = m_pStreamImp->ReadData((FX_LPBYTE)pStr, iBytes);
+ m_pStreamImp->Unlock();
+ iMaxLength = iLen / 2;
+ if (sizeof(FX_WCHAR) > 2) {
+ FX_UTF16ToWChar(pStr, iMaxLength);
+ }
+#if _FX_ENDIAN_ == _FX_BIG_ENDIAN_
+ if (m_wCodePage == FX_CODEPAGE_UTF16LE) {
+ FX_SwapByteOrder(pStr, iMaxLength);
+ }
+#else
+ if (m_wCodePage == FX_CODEPAGE_UTF16BE) {
+ FX_SwapByteOrder(pStr, iMaxLength);
+ }
+#endif
+ } else {
+ FX_INT32 pos = m_pStreamImp->GetPosition();
+ FX_INT32 iBytes = pByteSize == NULL ? iMaxLength : *pByteSize;
+ iBytes = FX_MIN(iBytes, m_pStreamImp->GetLength() - pos);
+ if (iBytes > 0) {
+ if (m_pBuf == NULL) {
+ m_pBuf = (FX_LPBYTE)FX_Alloc(FX_BYTE, iBytes);
+ m_iBufSize = iBytes;
+ } else if (iBytes > m_iBufSize) {
+ m_pBuf = (FX_LPBYTE)FX_Realloc(FX_BYTE, m_pBuf, iBytes);
+ m_iBufSize = iBytes;
+ }
+ m_pStreamImp->Lock();
+ iLen = m_pStreamImp->ReadData(m_pBuf, iBytes);
+ FX_INT32 iSrc = iLen;
+ FX_INT32 iDecode = FX_DecodeString(m_wCodePage, (FX_LPCSTR)m_pBuf, &iSrc, pStr, &iMaxLength, TRUE);
+ m_pStreamImp->Seek(FX_STREAMSEEK_Current, iSrc - iLen);
+ m_pStreamImp->Unlock();
+ if (iDecode < 1) {
+ return -1;
+ }
+ } else {
+ iMaxLength = 0;
+ }
+ }
+ bEOS = m_pStreamImp->IsEOF();
+ return iMaxLength;
+}
+FX_INT32 CFX_TextStream::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+{
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ if ((m_pStreamImp->GetAccessModes() & FX_STREAMACCESS_Write) == 0) {
+ return -1;
+ }
+ if (m_wCodePage == FX_CODEPAGE_UTF8) {
+ FX_INT32 len = iLength;
+ CFX_UTF8Encoder encoder;
+ while (len -- > 0) {
+ encoder.Input(*pStr ++);
+ }
+ CFX_ByteStringC bsResult = encoder.GetResult();
+ m_pStreamImp->Lock();
+ m_pStreamImp->WriteData((FX_LPCBYTE)bsResult.GetCStr(), bsResult.GetLength());
+ m_pStreamImp->Unlock();
+ }
+ return iLength;
+}
+CFX_Stream::CFX_Stream()
+ : m_eStreamType(FX_SREAMTYPE_Unknown)
+ , m_pStreamImp(NULL)
+ , m_dwAccess(0)
+ , m_iTotalSize(0)
+ , m_iPosition(0)
+ , m_iStart(0)
+ , m_iLength(0)
+ , m_iRefCount(1)
+{
+}
+CFX_Stream::~CFX_Stream()
+{
+ if (m_eStreamType != FX_STREAMTYPE_Stream && m_pStreamImp != NULL) {
+ m_pStreamImp->Release();
+ }
+}
+FX_BOOL CFX_Stream::LoadFile(FX_LPCWSTR pszSrcFileName, FX_DWORD dwAccess)
+{
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pszSrcFileName == NULL || FXSYS_wcslen(pszSrcFileName) < 1) {
+ return FALSE;
+ }
+ m_pStreamImp = FX_NEW CFX_FileStreamImp();
+ if (m_pStreamImp == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = ((CFX_FileStreamImp*)m_pStreamImp)->LoadFile(pszSrcFileName, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_File;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadFileRead(IFX_FileRead *pFileRead, FX_DWORD dwAccess)
+{
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pFileRead == NULL) {
+ return FALSE;
+ }
+ m_pStreamImp = FX_NEW CFX_FileReadStreamImp();
+ if (m_pStreamImp == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = ((CFX_FileReadStreamImp*)m_pStreamImp)->LoadFileRead(pFileRead, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_File;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadFileWrite(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess)
+{
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pFileWrite == NULL) {
+ return FALSE;
+ }
+ m_pStreamImp = FX_NEW CFX_FileWriteStreamImp();
+ if (m_pStreamImp == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = ((CFX_FileWriteStreamImp*)m_pStreamImp)->LoadFileWrite(pFileWrite, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_File;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadBuffer(FX_LPBYTE pData, FX_INT32 iTotalSize, FX_DWORD dwAccess)
+{
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (pData == NULL || iTotalSize < 1) {
+ return FALSE;
+ }
+ m_pStreamImp = FX_NEW CFX_BufferStreamImp();
+ if (m_pStreamImp == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = ((CFX_BufferStreamImp*)m_pStreamImp)->LoadBuffer(pData, iTotalSize, dwAccess);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_Buffer;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+FX_BOOL CFX_Stream::LoadBufferRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_DWORD dwAccess, FX_BOOL bReleaseBufferRead)
+{
+ if (m_eStreamType != FX_SREAMTYPE_Unknown || m_pStreamImp != NULL) {
+ return FALSE;
+ }
+ if (!pBufferRead) {
+ return FALSE;
+ }
+ m_pStreamImp = FX_NEW CFX_BufferReadStreamImp;
+ if (m_pStreamImp == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = ((CFX_BufferReadStreamImp*)m_pStreamImp)->LoadBufferRead(pBufferRead, iFileSize, dwAccess, bReleaseBufferRead);
+ if (!bRet) {
+ m_pStreamImp->Release();
+ m_pStreamImp = NULL;
+ } else {
+ m_eStreamType = FX_STREAMTYPE_BufferRead;
+ m_dwAccess = dwAccess;
+ m_iLength = m_pStreamImp->GetLength();
+ }
+ return bRet;
+}
+void CFX_Stream::Release()
+{
+ if (--m_iRefCount < 1) {
+ delete this;
+ }
+}
+IFX_Stream* CFX_Stream::Retain()
+{
+ m_iRefCount++;
+ return this;
+}
+FX_INT32 CFX_Stream::GetLength() const
+{
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File || m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_pStreamImp->GetLength();
+ }
+ return m_iLength;
+}
+FX_INT32 CFX_Stream::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File || m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_iPosition = m_pStreamImp->Seek(eSeek, iOffset);
+ }
+ FX_INT32 iEnd = m_iStart + m_iLength;
+ FX_INT32 iPosition = m_iStart + iOffset;
+ if (eSeek == FX_STREAMSEEK_Begin) {
+ m_iPosition = iPosition;
+ } else if (eSeek == FX_STREAMSEEK_Current) {
+ m_iPosition += iOffset;
+ } else if (eSeek == FX_STREAMSEEK_End) {
+ m_iPosition = iEnd + iOffset;
+ }
+ if (m_iPosition > iEnd) {
+ m_iPosition = iEnd;
+ }
+ if (m_iPosition < m_iStart) {
+ m_iPosition = m_iStart;
+ }
+ return m_iPosition - m_iStart;
+}
+FX_INT32 CFX_Stream::GetPosition()
+{
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File || m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_iPosition = m_pStreamImp->GetPosition();
+ }
+ return m_iPosition - m_iStart;
+}
+FX_BOOL CFX_Stream::IsEOF() const
+{
+ if (m_pStreamImp == NULL) {
+ return TRUE;
+ }
+ if (m_eStreamType == FX_STREAMTYPE_File || m_eStreamType == FX_STREAMTYPE_Buffer) {
+ return m_pStreamImp->IsEOF();
+ }
+ return m_iPosition >= m_iStart + m_iLength;
+}
+FX_INT32 CFX_Stream::ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ FX_INT32 iLen = FX_MIN(m_iStart + m_iLength - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ m_pStreamImp->Lock();
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->ReadData(pBuffer, iLen);
+ m_iPosition = m_pStreamImp->GetPosition();
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+FX_INT32 CFX_Stream::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize)
+{
+ FXSYS_assert(pStr != NULL && iMaxLength > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ FX_INT32 iEnd = m_iStart + m_iLength;
+ FX_INT32 iLen = iEnd - m_iPosition;
+ if (pByteSize != NULL) {
+ iLen = FX_MIN(iLen, *pByteSize);
+ }
+ iLen = FX_MIN(iEnd / 2, iMaxLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ m_pStreamImp->Lock();
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->ReadString(pStr, iLen, bEOS);
+ m_iPosition = m_pStreamImp->GetPosition();
+ if (iLen > 0 && m_iPosition >= iEnd) {
+ bEOS = TRUE;
+ }
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+FX_INT32 CFX_Stream::WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+{
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return -1;
+ }
+ FX_INT32 iLen = iBufferSize;
+ if (m_eStreamType == FX_STREAMTYPE_Stream) {
+ iLen = FX_MIN(m_iStart + m_iTotalSize - m_iPosition, iBufferSize);
+ if (iLen <= 0) {
+ return 0;
+ }
+ }
+ m_pStreamImp->Lock();
+ FX_INT32 iEnd = m_iStart + m_iLength;
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->WriteData(pBuffer, iLen);
+ m_iPosition = m_pStreamImp->GetPosition();
+ if (m_iPosition > iEnd) {
+ m_iLength = m_iPosition - m_iStart;
+ }
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+FX_INT32 CFX_Stream::WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+{
+ FXSYS_assert(pStr != NULL && iLength > 0);
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return -1;
+ }
+ FX_INT32 iLen = iLength;
+ if (m_eStreamType == FX_STREAMTYPE_Stream) {
+ iLen = FX_MIN((m_iStart + m_iTotalSize - m_iPosition) / 2, iLength);
+ if (iLen <= 0) {
+ return 0;
+ }
+ }
+ m_pStreamImp->Lock();
+ FX_INT32 iEnd = m_iStart + m_iLength;
+ if (m_pStreamImp->GetPosition() != m_iPosition) {
+ m_pStreamImp->Seek(FX_STREAMSEEK_Begin, m_iPosition);
+ }
+ iLen = m_pStreamImp->WriteString(pStr, iLen);
+ m_iPosition = m_pStreamImp->GetPosition();
+ if (m_iPosition > iEnd) {
+ m_iLength = m_iPosition - m_iStart;
+ }
+ m_pStreamImp->Unlock();
+ return iLen;
+}
+void CFX_Stream::Flush()
+{
+ if (m_pStreamImp == NULL) {
+ return;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return;
+ }
+ m_pStreamImp->Flush();
+}
+FX_BOOL CFX_Stream::SetLength(FX_INT32 iLength)
+{
+ if (m_pStreamImp == NULL) {
+ return FALSE;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0) {
+ return FALSE;
+ }
+ return m_pStreamImp->SetLength(iLength);
+}
+FX_INT32 CFX_Stream::GetBOM(FX_BYTE bom[4]) const
+{
+ if (m_pStreamImp == NULL) {
+ return -1;
+ }
+ return 0;
+}
+FX_WORD CFX_Stream::GetCodePage() const
+{
+#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
+ return FX_CODEPAGE_UTF16LE;
+#else
+ return FX_CODEPAGE_UTF16BE;
+#endif
+}
+FX_WORD CFX_Stream::SetCodePage(FX_WORD wCodePage)
+{
+#if _FX_ENDIAN_ == _FX_LITTLE_ENDIAN_
+ return FX_CODEPAGE_UTF16LE;
+#else
+ return FX_CODEPAGE_UTF16BE;
+#endif
+}
+IFX_Stream* CFX_Stream::CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength)
+{
+ FXSYS_assert( iLength > 0);
+ if (m_pStreamImp == NULL) {
+ return NULL;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Text) != 0 && (dwAccess & FX_STREAMACCESS_Text) == 0) {
+ return NULL;
+ }
+ if ((m_dwAccess & FX_STREAMACCESS_Write) == 0 && (dwAccess & FX_STREAMACCESS_Write) != 0) {
+ return NULL;
+ }
+ register FX_INT32 iStart = m_iStart + iOffset;
+ register FX_INT32 iTotal = m_iStart + m_iLength;
+ if (iStart < m_iStart || iStart >= iTotal) {
+ return NULL;
+ }
+ register FX_INT32 iEnd = iStart + iLength;
+ if (iEnd < iStart || iEnd > iTotal) {
+ return NULL;
+ }
+ CFX_Stream *pShared = FX_NEW CFX_Stream;
+ if (pShared == NULL) {
+ return NULL;
+ }
+ pShared->m_eStreamType = FX_STREAMTYPE_Stream;
+ pShared->m_pStreamImp = m_pStreamImp;
+ pShared->m_dwAccess = dwAccess;
+ pShared->m_iTotalSize = iLength;
+ pShared->m_iPosition = iStart;
+ pShared->m_iStart = iStart;
+ pShared->m_iLength = (dwAccess & FX_STREAMACCESS_Write) != 0 ? 0 : iLength;
+ if (dwAccess & FX_STREAMACCESS_Text) {
+ return IFX_Stream::CreateTextStream(pShared, TRUE);
+ }
+ return pShared;
+}
+IFX_FileRead* FX_CreateFileRead(IFX_Stream *pBaseStream, FX_BOOL bReleaseStream)
+{
+ FXSYS_assert(pBaseStream != NULL);
+ return FX_NEW CFGAS_FileRead(pBaseStream, bReleaseStream);
+}
+#ifdef FX_FILESIZE
+CFGAS_FileRead::CFGAS_FileRead(IFX_Stream *pStream, FX_BOOL bReleaseStream)
+ : m_bReleaseStream(bReleaseStream)
+ , m_pStream(pStream)
+{
+ FXSYS_assert(m_pStream != NULL);
+}
+CFGAS_FileRead::~CFGAS_FileRead()
+{
+ if (m_bReleaseStream) {
+ m_pStream->Release();
+ }
+}
+FX_FILESIZE CFGAS_FileRead::GetSize()
+{
+ return (FX_FILESIZE)m_pStream->GetLength();
+}
+FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
+{
+ m_pStream->Lock();
+ m_pStream->Seek(FX_STREAMSEEK_Begin, (FX_INT32)offset);
+ FX_INT32 iLen = m_pStream->ReadData((FX_LPBYTE)buffer, (FX_INT32)size);
+ m_pStream->Unlock();
+ return iLen == (FX_INT32)size;
+}
+#else
+CFGAS_FileRead::CFGAS_FileRead(IFX_Stream *pStream, FX_BOOL bReleaseStream)
+ : m_bReleaseStream(bReleaseStream)
+ , m_pStream(pStream)
+{
+ FXSYS_assert(m_pStream != NULL);
+}
+CFGAS_FileRead::~CFGAS_FileRead()
+{
+ if (m_bReleaseStream) {
+ m_pStream->Release();
+ }
+}
+FX_DWORD CFGAS_FileRead::GetSize()
+{
+ return (FX_DWORD)m_pStream->GetLength();
+}
+FX_BOOL CFGAS_FileRead::ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size)
+{
+ m_pStream->Lock();
+ m_pStream->Seek(FX_STREAMSEEK_Begin, (FX_INT32)offset);
+ FX_INT32 iLen = m_pStream->ReadData((FX_LPBYTE)buffer, (FX_INT32)size);
+ m_pStream->Unlock();
+ return iLen == (FX_INT32)size;
+}
+#endif
+#ifdef FX_FILESIZE
+IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_FILESIZE iFileSize, FX_BOOL bReleaseStream)
+{
+ if (!pBufferRead) {
+ return NULL;
+ }
+ return FX_NEW CFX_BufferAccImp(pBufferRead, iFileSize, bReleaseStream);
+}
+CFX_BufferAccImp::CFX_BufferAccImp(IFX_BufferRead *pBufferRead, FX_FILESIZE iFileSize, FX_BOOL bReleaseStream)
+ : m_pBufferRead(pBufferRead)
+ , m_bReleaseStream(bReleaseStream)
+ , m_iBufSize(iFileSize)
+{
+ FXSYS_assert(m_pBufferRead);
+}
+CFX_BufferAccImp::~CFX_BufferAccImp()
+{
+ if (m_bReleaseStream && m_pBufferRead) {
+ m_pBufferRead->Release();
+ }
+}
+FX_FILESIZE CFX_BufferAccImp::GetSize()
+{
+ if (!m_pBufferRead) {
+ return 0;
+ }
+ if (m_iBufSize >= 0) {
+ return m_iBufSize;
+ }
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return 0;
+ }
+ m_iBufSize = (FX_FILESIZE)m_pBufferRead->GetBlockSize();
+ while (!m_pBufferRead->IsEOF()) {
+ m_pBufferRead->ReadNextBlock(FALSE);
+ m_iBufSize += (FX_FILESIZE)m_pBufferRead->GetBlockSize();
+ }
+ return m_iBufSize;
+}
+FX_BOOL CFX_BufferAccImp::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
+{
+ if (!m_pBufferRead) {
+ return FALSE;
+ }
+ if (!buffer || !size) {
+ return TRUE;
+ }
+ FX_FILESIZE dwBufSize = GetSize();
+ if (offset >= dwBufSize) {
+ return FALSE;
+ }
+ size_t dwBlockSize = m_pBufferRead->GetBlockSize();
+ FX_FILESIZE dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ if (offset < dwBlockOffset) {
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return FALSE;
+ }
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ }
+ while (offset < dwBlockOffset || offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) {
+ if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ }
+ if (offset < dwBlockOffset || offset >= (FX_FILESIZE)(dwBlockOffset + dwBlockSize)) {
+ return FALSE;
+ }
+ FX_LPCBYTE pBuffer = m_pBufferRead->GetBlockBuffer();
+ FX_FILESIZE dwOffset = offset - dwBlockOffset;
+ size_t dwCopySize = FX_MIN(size, dwBlockSize - dwOffset);
+ FXSYS_memcpy(buffer, pBuffer + dwOffset, dwCopySize);
+ offset = dwCopySize;
+ size -= dwCopySize;
+ while (size) {
+ if (!m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ pBuffer = m_pBufferRead->GetBlockBuffer();
+ dwCopySize = FX_MIN(size, dwBlockSize);
+ FXSYS_memcpy(((FX_LPBYTE)buffer) + offset, pBuffer, dwCopySize);
+ offset += dwCopySize;
+ size -= dwCopySize;
+ }
+ return TRUE;
+}
+#else
+IFX_FileRead* FX_CreateFileRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_BOOL bReleaseStream)
+{
+ if (!pBufferRead) {
+ return NULL;
+ }
+ return FX_NEW CFX_BufferAccImp(pBufferRead, iFileSize, bReleaseStream);
+}
+CFX_BufferAccImp::CFX_BufferAccImp(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_BOOL bReleaseStream)
+ : m_pBufferRead(pBufferRead)
+ , m_bReleaseStream(bReleaseStream)
+ , m_iBufSize(iFileSize)
+{
+ FXSYS_assert(m_pBufferRead);
+}
+CFX_BufferAccImp::~CFX_BufferAccImp()
+{
+ if (m_bReleaseStream && m_pBufferRead) {
+ m_pBufferRead->Release();
+ }
+}
+FX_DWORD CFX_BufferAccImp::GetSize()
+{
+ if (!m_pBufferRead) {
+ return 0;
+ }
+ if (m_iBufSize >= 0) {
+ return m_iBufSize;
+ }
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return 0;
+ }
+ m_iBufSize = (FX_DWORD)m_pBufferRead->GetBlockSize();
+ while (!m_pBufferRead->IsEOF()) {
+ m_pBufferRead->ReadNextBlock(FALSE);
+ m_iBufSize += (FX_DWORD)m_pBufferRead->GetBlockSize();
+ }
+ return m_iBufSize;
+}
+FX_BOOL CFX_BufferAccImp::ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size)
+{
+ if (!m_pBufferRead) {
+ return FALSE;
+ }
+ if (!buffer || !size) {
+ return TRUE;
+ }
+ FX_DWORD dwBufSize = GetSize();
+ if (offset >= dwBufSize) {
+ return FALSE;
+ }
+ size_t dwBlockSize = m_pBufferRead->GetBlockSize();
+ FX_DWORD dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ if (offset < dwBlockOffset) {
+ if (!m_pBufferRead->ReadNextBlock(TRUE)) {
+ return FALSE;
+ }
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ }
+ while (offset < dwBlockOffset || offset >= (FX_DWORD)(dwBlockOffset + dwBlockSize)) {
+ if (m_pBufferRead->IsEOF() || !m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ }
+ if (offset < dwBlockOffset || offset >= (FX_DWORD)(dwBlockOffset + dwBlockSize)) {
+ return FALSE;
+ }
+ FX_LPCBYTE pBuffer = m_pBufferRead->GetBlockBuffer();
+ FX_DWORD dwOffset = offset - dwBlockOffset;
+ FX_DWORD dwCopySize = FX_MIN(size, dwBlockSize - dwOffset);
+ FXSYS_memcpy(buffer, pBuffer + dwOffset, dwCopySize);
+ offset = dwCopySize;
+ size -= dwCopySize;
+ while (size) {
+ if (!m_pBufferRead->ReadNextBlock(FALSE)) {
+ break;
+ }
+ dwBlockOffset = m_pBufferRead->GetBlockOffset();
+ dwBlockSize = m_pBufferRead->GetBlockSize();
+ pBuffer = m_pBufferRead->GetBlockBuffer();
+ dwCopySize = FX_MIN(size, dwBlockSize);
+ FXSYS_memcpy(((FX_LPBYTE)buffer) + offset, pBuffer, dwCopySize);
+ offset += dwCopySize;
+ size -= dwCopySize;
+ }
+ return TRUE;
+}
+#endif
+IFX_FileWrite* FX_CreateFileWrite(IFX_Stream *pBaseStream, FX_BOOL bReleaseStream)
+{
+ FXSYS_assert(pBaseStream != NULL);
+ return FX_NEW CFGAS_FileWrite(pBaseStream, bReleaseStream);
+}
+#ifdef FX_FILESIZE
+CFGAS_FileWrite::CFGAS_FileWrite(IFX_Stream *pStream, FX_BOOL bReleaseStream)
+ : m_pStream(pStream)
+ , m_bReleaseStream(bReleaseStream)
+{
+ FXSYS_assert(m_pStream != NULL);
+}
+CFGAS_FileWrite::~CFGAS_FileWrite()
+{
+ if (m_bReleaseStream) {
+ m_pStream->Release();
+ }
+}
+FX_FILESIZE CFGAS_FileWrite::GetSize()
+{
+ return m_pStream->GetLength();
+}
+FX_BOOL CFGAS_FileWrite::Flush()
+{
+ m_pStream->Flush();
+ return TRUE;
+}
+FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, size_t size)
+{
+ return m_pStream->WriteData((FX_LPCBYTE)pData, (FX_INT32)size) == (FX_INT32)size;
+}
+FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, FX_FILESIZE offset, size_t size)
+{
+ m_pStream->Lock();
+ m_pStream->Seek(FX_STREAMSEEK_Begin, offset);
+ FX_INT32 iLen = m_pStream->WriteData((FX_LPBYTE)pData, (FX_INT32)size);
+ m_pStream->Unlock();
+ return iLen == (FX_INT32)size;
+}
+#else
+CFGAS_FileWrite::CFGAS_FileWrite(IFX_Stream *pStream, FX_BOOL bReleaseStream)
+ : m_pStream(pStream)
+ , m_bReleaseStream(bReleaseStream)
+{
+ FXSYS_assert(m_pStream != NULL);
+}
+CFGAS_FileWrite::~CFGAS_FileWrite()
+{
+ if (m_bReleaseStream) {
+ m_pStream->Release();
+ }
+}
+FX_DWORD CFGAS_FileWrite::GetSize()
+{
+ return m_pStream->GetLength();
+}
+FX_DWORD CFGAS_FileWrite::Flush()
+{
+ m_pStream->Flush();
+ return 0;
+}
+FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, FX_DWORD size)
+{
+ return m_pStream->WriteData((FX_LPCBYTE)pData, (FX_INT32)size) == (FX_INT32)size;
+}
+FX_BOOL CFGAS_FileWrite::WriteBlock(const void* pData, FX_DWORD offset, FX_DWORD size)
+{
+ m_pStream->Lock();
+ m_pStream->Seek(FX_STREAMSEEK_Begin, offset);
+ FX_INT32 iLen = m_pStream->WriteData((FX_LPBYTE)pData, (FX_INT32)size);
+ m_pStream->Unlock();
+ return iLen == (FX_INT32)size;
+}
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_stream.h b/xfa/src/fgas/src/crt/fx_stream.h
new file mode 100644
index 0000000000..630a0fb77f
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_stream.h
@@ -0,0 +1,405 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_STREAM_IMP
+#define _FX_STREAM_IMP
+class CFX_StreamImp;
+class CFX_FileStreamImp;
+class CFX_BufferStreamImp;
+class CFX_FileReadStreamImp;
+class CFX_BufferReadStreamImp;
+class CFX_FileWriteStreamImp;
+class CFX_Stream;
+class CFX_TextStream;
+class CFX_FileRead;
+class CFX_FileWrite;
+class CFX_BufferAccImp;
+class CFX_StreamImp : public CFX_ThreadLock, public CFX_Object
+{
+public:
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_DWORD GetAccessModes() const
+ {
+ return m_dwAccess;
+ }
+ virtual FX_INT32 GetLength() const = 0;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset) = 0;
+ virtual FX_INT32 GetPosition() = 0;
+ virtual FX_BOOL IsEOF() const = 0;
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize) = 0;
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS) = 0;
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize) = 0;
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength) = 0;
+ virtual void Flush() = 0;
+ virtual FX_BOOL SetLength(FX_INT32 iLength) = 0;
+protected:
+ CFX_StreamImp();
+ virtual ~CFX_StreamImp() {}
+ FX_DWORD m_dwAccess;
+};
+class CFX_FileStreamImp : public CFX_StreamImp
+{
+public:
+ CFX_FileStreamImp();
+ virtual ~CFX_FileStreamImp();
+ FX_BOOL LoadFile(FX_LPCWSTR pszSrcFileName, FX_DWORD dwAccess);
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition();
+ virtual FX_BOOL IsEOF() const;
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS);
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(FX_INT32 iLength);
+protected:
+ FXSYS_FILE *m_hFile;
+ FX_INT32 m_iLength;
+};
+class CFX_BufferStreamImp : public CFX_StreamImp
+{
+public:
+ CFX_BufferStreamImp();
+ virtual ~CFX_BufferStreamImp() {}
+ FX_BOOL LoadBuffer(FX_LPBYTE pData, FX_INT32 iTotalSize, FX_DWORD dwAccess);
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition();
+ virtual FX_BOOL IsEOF() const;
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS);
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength);
+ virtual void Flush() {}
+ virtual FX_BOOL SetLength(FX_INT32 iLength)
+ {
+ return FALSE;
+ }
+protected:
+ FX_LPBYTE m_pData;
+ FX_INT32 m_iTotalSize;
+ FX_INT32 m_iPosition;
+ FX_INT32 m_iLength;
+};
+class CFX_FileReadStreamImp : public CFX_StreamImp
+{
+public:
+ CFX_FileReadStreamImp();
+ virtual ~CFX_FileReadStreamImp() {}
+ FX_BOOL LoadFileRead(IFX_FileRead *pFileRead, FX_DWORD dwAccess);
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition()
+ {
+ return m_iPosition;
+ }
+ virtual FX_BOOL IsEOF() const;
+
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS);
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+ {
+ return 0;
+ }
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+ {
+ return 0;
+ }
+ virtual void Flush() {}
+ virtual FX_BOOL SetLength(FX_INT32 iLength)
+ {
+ return FALSE;
+ }
+protected:
+ IFX_FileRead *m_pFileRead;
+ FX_INT32 m_iPosition;
+ FX_INT32 m_iLength;
+};
+class CFX_BufferReadStreamImp : public CFX_StreamImp
+{
+public:
+ CFX_BufferReadStreamImp();
+ ~CFX_BufferReadStreamImp();
+ FX_BOOL LoadBufferRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_DWORD dwAccess, FX_BOOL bReleaseBufferRead);
+
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition()
+ {
+ return m_iPosition;
+ }
+ virtual FX_BOOL IsEOF() const;
+
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS);
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+ {
+ return 0;
+ }
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+ {
+ return 0;
+ }
+ virtual void Flush() {}
+ virtual FX_BOOL SetLength(FX_INT32 iLength)
+ {
+ return FALSE;
+ }
+private:
+ IFX_BufferRead *m_pBufferRead;
+ FX_BOOL m_bReleaseBufferRead;
+ FX_INT32 m_iPosition;
+ FX_INT32 m_iBufferSize;
+};
+class CFX_FileWriteStreamImp : public CFX_StreamImp
+{
+public:
+ CFX_FileWriteStreamImp();
+ virtual ~CFX_FileWriteStreamImp() {}
+ FX_BOOL LoadFileWrite(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess);
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition()
+ {
+ return m_iPosition;
+ }
+ virtual FX_BOOL IsEOF() const;
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+ {
+ return 0;
+ }
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS)
+ {
+ return 0;
+ }
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(FX_INT32 iLength)
+ {
+ return FALSE;
+ }
+protected:
+ IFX_FileWrite *m_pFileWrite;
+ FX_INT32 m_iPosition;
+};
+enum FX_STREAMTYPE {
+ FX_SREAMTYPE_Unknown = 0,
+ FX_STREAMTYPE_File ,
+ FX_STREAMTYPE_Buffer ,
+ FX_STREAMTYPE_Stream ,
+ FX_STREAMTYPE_BufferRead ,
+};
+class CFX_Stream : public IFX_Stream, public CFX_ThreadLock, public CFX_Object
+{
+public:
+ CFX_Stream();
+ ~CFX_Stream();
+ FX_BOOL LoadFile(FX_LPCWSTR pszSrcFileName, FX_DWORD dwAccess);
+ FX_BOOL LoadBuffer(FX_LPBYTE pData, FX_INT32 iTotalSize, FX_DWORD dwAccess);
+ FX_BOOL LoadFileRead(IFX_FileRead *pFileRead, FX_DWORD dwAccess);
+ FX_BOOL LoadFileWrite(IFX_FileWrite *pFileWrite, FX_DWORD dwAccess);
+ FX_BOOL LoadBufferRead(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_DWORD dwAccess, FX_BOOL bReleaseBufferRead);
+ virtual void Release();
+ virtual IFX_Stream* Retain();
+ virtual FX_DWORD GetAccessModes() const
+ {
+ return m_dwAccess;
+ }
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition();
+ virtual FX_BOOL IsEOF() const;
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize = NULL);
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(FX_INT32 iLength);
+ virtual FX_INT32 GetBOM(FX_BYTE bom[4]) const;
+ virtual FX_WORD GetCodePage() const;
+ virtual FX_WORD SetCodePage(FX_WORD wCodePage);
+ virtual void Lock()
+ {
+ CFX_ThreadLock::Lock();
+ }
+ virtual void Unlock()
+ {
+ CFX_ThreadLock::Unlock();
+ }
+ virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength);
+protected:
+ FX_STREAMTYPE m_eStreamType;
+ CFX_StreamImp *m_pStreamImp;
+ FX_DWORD m_dwAccess;
+ FX_INT32 m_iTotalSize;
+ FX_INT32 m_iPosition;
+ FX_INT32 m_iStart;
+ FX_INT32 m_iLength;
+ FX_INT32 m_iRefCount;
+};
+class CFX_TextStream : public IFX_Stream, public CFX_ThreadLock, public CFX_Object
+{
+public:
+ CFX_TextStream(IFX_Stream *pStream, FX_BOOL bDelStream);
+ ~CFX_TextStream();
+ virtual void Release();
+ virtual IFX_Stream* Retain();
+
+ virtual FX_DWORD GetAccessModes() const;
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition();
+ virtual FX_BOOL IsEOF() const;
+
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize = NULL);
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize);
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength);
+ virtual void Flush();
+ virtual FX_BOOL SetLength(FX_INT32 iLength);
+
+ virtual FX_INT32 GetBOM(FX_BYTE bom[4]) const;
+ virtual FX_WORD GetCodePage() const;
+ virtual FX_WORD SetCodePage(FX_WORD wCodePage);
+
+ virtual void Lock()
+ {
+ CFX_ThreadLock::Lock();
+ }
+ virtual void Unlock()
+ {
+ CFX_ThreadLock::Unlock();
+ }
+
+ virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength);
+protected:
+ FX_WORD m_wCodePage;
+ FX_WORD m_wBOMLength;
+ FX_DWORD m_dwBOM;
+ FX_LPBYTE m_pBuf;
+ FX_INT32 m_iBufSize;
+ FX_BOOL m_bDelStream;
+ IFX_Stream *m_pStreamImp;
+ FX_INT32 m_iRefCount;
+ void InitStream();
+};
+#ifdef FX_FILESIZE
+class CFGAS_FileRead : public IFX_FileRead, public CFX_Object
+{
+public:
+ CFGAS_FileRead(IFX_Stream *pStream, FX_BOOL bReleaseStream);
+ virtual ~CFGAS_FileRead();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+protected:
+ FX_BOOL m_bReleaseStream;
+ IFX_Stream *m_pStream;
+};
+#else
+class CFGAS_FileRead : public IFX_FileRead, public CFX_Object
+{
+public:
+ CFGAS_FileRead(IFX_Stream *pStream, FX_BOOL bReleaseStream);
+ virtual ~CFGAS_FileRead();
+
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_DWORD GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size);
+
+protected:
+ FX_BOOL m_bReleaseStream;
+ IFX_Stream *m_pStream;
+};
+#endif
+#ifdef FX_FILESIZE
+class CFX_BufferAccImp : public IFX_FileRead, public CFX_Object
+{
+public:
+ CFX_BufferAccImp(IFX_BufferRead *pBufferRead, FX_FILESIZE iFileSize, FX_BOOL bReleaseStream);
+ virtual ~CFX_BufferAccImp();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+protected:
+ IFX_BufferRead *m_pBufferRead;
+ FX_BOOL m_bReleaseStream;
+ FX_FILESIZE m_iBufSize;
+};
+#else
+class CFX_BufferAccImp : public IFX_FileRead, public CFX_Object
+{
+public:
+ CFX_BufferAccImp(IFX_BufferRead *pBufferRead, FX_INT32 iFileSize, FX_BOOL bReleaseStream);
+ virtual ~CFX_BufferAccImp();
+
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_DWORD GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_DWORD offset, FX_DWORD size);
+
+protected:
+ IFX_BufferRead *m_pBufferRead;
+ FX_BOOL m_bReleaseStream;
+ FX_INT32 m_iBufSize;
+};
+#endif
+#ifdef FX_FILESIZE
+class CFGAS_FileWrite : public IFX_FileWrite, public CFX_Object
+{
+public:
+ CFGAS_FileWrite(IFX_Stream *pStream, FX_BOOL bReleaseStream);
+ virtual ~CFGAS_FileWrite();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL Flush();
+ virtual FX_BOOL WriteBlock(const void* pData, size_t size);
+ virtual FX_BOOL WriteBlock(const void* pData, FX_FILESIZE offset, size_t size);
+protected:
+ IFX_Stream *m_pStream;
+ FX_BOOL m_bReleaseStream;
+};
+#else
+class CFGAS_FileWrite : public IFX_FileWrite, public CFX_Object
+{
+public:
+ CFGAS_FileWrite(IFX_Stream *pStream, FX_BOOL bReleaseStream);
+ virtual ~CFGAS_FileWrite();
+
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_DWORD GetSize();
+ virtual FX_DWORD Flush();
+ virtual FX_BOOL WriteBlock(const void* pData, FX_DWORD size);
+ virtual FX_BOOL WriteBlock(const void* pData, FX_DWORD offset, FX_DWORD size);
+
+protected:
+ IFX_Stream *m_pStream;
+ FX_BOOL m_bReleaseStream;
+};
+#endif
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_system.cpp b/xfa/src/fgas/src/crt/fx_system.cpp
new file mode 100644
index 0000000000..c8e4407a79
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_system.cpp
@@ -0,0 +1,236 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+#include <io.h>
+#elif _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_Mini_
+#include <sys/times.h>
+#endif
+#ifdef __cplusplus
+extern "C" {
+#endif
+FX_FLOAT FX_tan(FX_FLOAT a)
+{
+ return (FX_FLOAT)tan(a);
+}
+FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x)
+{
+ return FXSYS_log(x) / FXSYS_log(b);
+}
+FX_LPWSTR FX_wcsncpy(FX_LPWSTR dstStr, FX_LPCWSTR srcStr, size_t count)
+{
+ FXSYS_assert(dstStr != NULL && srcStr != NULL && count > 0);
+ for (size_t i = 0; i < count; ++i)
+ if ((dstStr[i] = srcStr[i]) == L'\0') {
+ break;
+ }
+ return dstStr;
+}
+FX_INT32 FX_wcsnicmp(FX_LPCWSTR s1, FX_LPCWSTR s2, size_t count)
+{
+ FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
+ FX_WCHAR wch1 = 0, wch2 = 0;
+ while (count-- > 0) {
+ wch1 = (FX_WCHAR)FX_tolower(*s1++);
+ wch2 = (FX_WCHAR)FX_tolower(*s2++);
+ if (wch1 != wch2) {
+ break;
+ }
+ }
+ return wch1 - wch2;
+}
+FX_INT32 FX_strnicmp(FX_LPCSTR s1, FX_LPCSTR s2, size_t count)
+{
+ FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);
+ FX_CHAR ch1 = 0, ch2 = 0;
+ while (count-- > 0) {
+ ch1 = (FX_CHAR)FX_tolower(*s1++);
+ ch2 = (FX_CHAR)FX_tolower(*s2++);
+ if (ch1 != ch2) {
+ break;
+ }
+ }
+ return ch1 - ch2;
+}
+FX_INT32 FX_filelength(FXSYS_FILE *file)
+{
+ FXSYS_assert(file != NULL);
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+ return _filelength(_fileno(file));
+#else
+ FX_INT32 iPos = FXSYS_ftell(file);
+ FXSYS_fseek(file, 0, FXSYS_SEEK_END);
+ FX_INT32 iLen = FXSYS_ftell(file);
+ FXSYS_fseek(file, iPos, FXSYS_SEEK_SET);
+ return iLen;
+#endif
+}
+FX_BOOL FX_fsetsize(FXSYS_FILE *file, FX_INT32 size)
+{
+ FXSYS_assert(file != NULL);
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+ return _chsize(_fileno(file), size) == 0;
+#elif _FX_OS_ == _FX_WIN32_MOBILE_
+ HANDLE hFile = _fileno(file);
+ FX_DWORD dwPos = ::SetFilePointer(hFile, 0, 0, FILE_CURRENT);
+ ::SetFilePointer(hFile, size, 0, FILE_BEGIN);
+ FX_BOOL bRet = ::SetEndOfFile(hFile);
+ ::SetFilePointer(hFile, (FX_INT32)dwPos, 0, FILE_BEGIN);
+ return bRet;
+#else
+ return FALSE;
+#endif
+}
+FX_FLOAT FX_strtof(FX_LPCSTR pcsStr, FX_INT32 iLength , FX_INT32 *pUsedLen )
+{
+ FXSYS_assert(pcsStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_strlen(pcsStr);
+ }
+ return FX_wcstof(CFX_WideString::FromLocal(pcsStr, iLength), iLength, pUsedLen);
+}
+FX_FLOAT FX_wcstof(FX_LPCWSTR pwsStr, FX_INT32 iLength , FX_INT32 *pUsedLen )
+{
+ FXSYS_assert(pwsStr != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pwsStr);
+ }
+ if (iLength == 0) {
+ return 0.0f;
+ }
+ FX_INT32 iUsedLen = 0;
+ FX_BOOL bNegtive = FALSE;
+ switch (pwsStr[iUsedLen]) {
+ case '-':
+ bNegtive = TRUE;
+ case '+':
+ iUsedLen++;
+ break;
+ }
+ FX_FLOAT fValue = 0.0f;
+ while (iUsedLen < iLength) {
+ FX_WCHAR wch = pwsStr[iUsedLen];
+ if (wch >= L'0' && wch <= L'9') {
+ fValue = fValue * 10.0f + (wch - L'0');
+ } else {
+ break;
+ }
+ iUsedLen++;
+ }
+ if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') {
+ FX_FLOAT fPrecise = 0.1f;
+ while (++iUsedLen < iLength) {
+ FX_WCHAR wch = pwsStr[iUsedLen];
+ if (wch >= L'0' && wch <= L'9') {
+ fValue += (wch - L'0') * fPrecise;
+ fPrecise *= 0.1f;
+ } else {
+ break;
+ }
+ }
+ }
+ if (pUsedLen) {
+ *pUsedLen = iUsedLen;
+ }
+ return bNegtive ? -fValue : fValue;
+}
+void FX_memset(FX_LPVOID pBuf, FX_INT32 iValue, size_t size)
+{
+ FXSYS_assert(pBuf != NULL && size > 0 && (size & 0x03) == 0);
+ FXSYS_assert((((size_t)pBuf) & 0x03) == 0);
+ FX_DWORD *pStart = (FX_DWORD*)pBuf;
+ FX_DWORD *pEnd = pStart + (size >> 2);
+ while (pStart < pEnd) {
+ *pStart ++ = iValue;
+ }
+}
+void FX_memcpy(FX_LPVOID pDst, FX_LPCVOID pSrc, size_t size)
+{
+ FXSYS_assert(pDst != NULL && pSrc != NULL && size > 0 && (size & 0x03) == 0);
+ FXSYS_assert((((size_t)pDst) & 0x03) == 0 && (((size_t)pSrc) & 0x03) == 0);
+ FX_DWORD *pStart = (FX_DWORD*)pDst;
+ FX_DWORD *pEnd = pStart + (size >> 2);
+ FX_DWORD *pValue = (FX_DWORD*)pSrc;
+ while (pStart < pEnd) {
+ *pStart ++ = *pValue ++;
+ }
+}
+FX_BOOL FX_IsRelativePath(const CFX_WideStringC &wsUrl)
+{
+ FX_INT32 iUrlLen = wsUrl.GetLength();
+ if (iUrlLen == 0) {
+ return TRUE;
+ }
+ for (FX_INT32 i = FX_MIN(5, iUrlLen) - 1; i >= 0; --i)
+ if (wsUrl.GetAt(i) == ':') {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL FX_JoinPath(const CFX_WideStringC &wsBasePath, const CFX_WideStringC &wsRelativePath, CFX_WideString &wsAbsolutePath)
+{
+ if (!FX_IsRelativePath(wsRelativePath)) {
+ wsAbsolutePath = wsRelativePath;
+ return TRUE;
+ }
+ FX_LPCWSTR pRelStart = wsRelativePath.GetPtr();
+ FX_LPCWSTR pRelEnd = pRelStart + wsRelativePath.GetLength();
+ if (pRelStart < pRelEnd) {
+ switch (*pRelStart) {
+ case '#':
+ wsAbsolutePath = CFX_WideString(wsBasePath, wsRelativePath);
+ return wsAbsolutePath.GetLength() > 0;
+ case '/':
+ case '\\':
+ wsAbsolutePath = wsRelativePath;
+ return wsAbsolutePath.GetLength() > 0;
+ }
+ }
+ FX_INT32 nBackCount = 0;
+ for(;;) {
+ if (pRelStart >= pRelEnd) {
+ wsAbsolutePath = wsBasePath;
+ return TRUE;
+ }
+ if (*pRelStart != '.') {
+ break;
+ }
+ if (pRelStart + 1 < pRelEnd &&
+ (pRelStart[1] == '/' || pRelStart[1] == '\\')) {
+ pRelStart += 2;
+ } else if (pRelStart + 2 < pRelEnd
+ && pRelStart[1] == '.'
+ && (pRelStart[2] == '/' || pRelStart[2] == '\\')) {
+ pRelStart += 3;
+ nBackCount++;
+ } else {
+ return FALSE;
+ }
+ }
+ FX_LPCWSTR pBaseStart = wsBasePath.GetPtr();
+ FX_LPCWSTR pBaseEnd = pBaseStart + wsBasePath.GetLength();
+ while(pBaseStart < (--pBaseEnd) && *pBaseEnd != '/' && *pBaseEnd != '\\')
+ ;
+ if (pBaseStart == pBaseEnd) {
+ wsAbsolutePath = CFX_WideStringC(pRelStart, pRelEnd - pRelStart);
+ return wsAbsolutePath.GetLength() > 0;
+ }
+ while (nBackCount > 0) {
+ if (pBaseStart >= (--pBaseEnd)) {
+ return FALSE;
+ } else if (*pBaseEnd == '/' || *pBaseEnd == '\\')
+ if ((--nBackCount) <= 0) {
+ break;
+ }
+ }
+ wsAbsolutePath = CFX_WideString(CFX_WideStringC(pBaseStart, pBaseEnd - pBaseStart + 1),
+ CFX_WideStringC(pRelStart, pRelEnd - pRelStart));
+ return wsAbsolutePath.GetLength() > 0;
+}
+#ifdef __cplusplus
+};
+#endif
diff --git a/xfa/src/fgas/src/crt/fx_utils.cpp b/xfa/src/fgas/src/crt/fx_utils.cpp
new file mode 100644
index 0000000000..f13af23216
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_utils.cpp
@@ -0,0 +1,456 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_utils.h"
+CFX_ThreadLock::CFX_ThreadLock()
+ : m_pData(NULL)
+{
+}
+CFX_ThreadLock::~CFX_ThreadLock()
+{
+}
+void CFX_ThreadLock::Lock()
+{
+}
+void CFX_ThreadLock::Unlock()
+{
+}
+typedef struct _FX_BASEARRAYDATA : public CFX_Target {
+ FX_INT32 iGrowSize;
+ FX_INT32 iBlockSize;
+ FX_INT32 iTotalCount;
+ FX_INT32 iBlockCount;
+ FX_LPBYTE pBuffer;
+} FX_BASEARRAYDATA, * FX_LPBASEARRAYDATA;
+typedef FX_BASEARRAYDATA const * FX_LPCBASEARRAYDATA;
+CFX_BaseArray::CFX_BaseArray(FX_INT32 iGrowSize, FX_INT32 iBlockSize)
+{
+ FXSYS_assert(iGrowSize > 0 && iBlockSize > 0);
+ m_pData = FXTARGET_New FX_BASEARRAYDATA;
+ FX_memset(m_pData, 0, sizeof(FX_BASEARRAYDATA));
+ ((FX_LPBASEARRAYDATA)m_pData)->iGrowSize = iGrowSize;
+ ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize = iBlockSize;
+}
+CFX_BaseArray::~CFX_BaseArray()
+{
+ FX_LPBASEARRAYDATA pData = (FX_LPBASEARRAYDATA)m_pData;
+ if (pData->pBuffer != NULL) {
+ FX_Free(pData->pBuffer);
+ }
+ FXTARGET_Delete pData;
+}
+FX_INT32 CFX_BaseArray::GetSize() const
+{
+ return ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount;
+}
+FX_INT32 CFX_BaseArray::GetBlockSize() const
+{
+ return ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize;
+}
+FX_LPBYTE CFX_BaseArray::AddSpaceTo(FX_INT32 index)
+{
+ FXSYS_assert(index > -1);
+ FX_LPBYTE &pBuffer = ((FX_LPBASEARRAYDATA)m_pData)->pBuffer;
+ FX_INT32 &iTotalCount = ((FX_LPBASEARRAYDATA)m_pData)->iTotalCount;
+ FX_INT32 iBlockSize = ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize;
+ if (index >= iTotalCount) {
+ FX_INT32 iGrowSize = ((FX_LPBASEARRAYDATA)m_pData)->iGrowSize;
+ iTotalCount = (index / iGrowSize + 1) * iGrowSize;
+ FX_INT32 iNewSize = iTotalCount * iBlockSize;
+ if (pBuffer == NULL) {
+ pBuffer = (FX_LPBYTE)FX_Alloc(FX_BYTE, iNewSize);
+ } else {
+ pBuffer = (FX_LPBYTE)FX_Realloc(FX_BYTE, pBuffer, iNewSize);
+ }
+ }
+ FXSYS_assert(pBuffer != NULL);
+ FX_INT32 &iBlockCount = ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount;
+ if (index >= iBlockCount) {
+ iBlockCount = index + 1;
+ }
+ return pBuffer + index * iBlockSize;
+}
+FX_LPBYTE CFX_BaseArray::GetAt(FX_INT32 index) const
+{
+ FXSYS_assert(index > -1 && index < ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount);
+ return ((FX_LPBASEARRAYDATA)m_pData)->pBuffer + index * ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize;
+}
+FX_LPBYTE CFX_BaseArray::GetBuffer() const
+{
+ return ((FX_LPBASEARRAYDATA)m_pData)->pBuffer;
+}
+FX_INT32 CFX_BaseArray::Append(const CFX_BaseArray &src, FX_INT32 iStart, FX_INT32 iCount)
+{
+ FX_INT32 iBlockSize = ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize;
+ FXSYS_assert(iBlockSize == ((FX_LPBASEARRAYDATA)src.m_pData)->iBlockSize);
+ FX_INT32 &iBlockCount = ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount;
+ FX_INT32 iAdded = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iAdded);
+ if (iCount < 0) {
+ iCount = iAdded;
+ }
+ if (iStart + iCount > iAdded) {
+ iCount = iAdded - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ FX_LPBYTE pDst = ((FX_LPBASEARRAYDATA)m_pData)->pBuffer + iBlockCount * iBlockSize;
+ AddSpaceTo(iBlockCount + iCount - 1);
+ FX_memcpy(pDst, ((FX_LPBASEARRAYDATA)src.m_pData)->pBuffer + iStart * iBlockSize, iCount * iBlockSize);
+ return iCount;
+}
+FX_INT32 CFX_BaseArray::Copy(const CFX_BaseArray &src, FX_INT32 iStart, FX_INT32 iCount)
+{
+ FX_INT32 iBlockSize = ((FX_LPBASEARRAYDATA)m_pData)->iBlockSize;
+ FXSYS_assert(iBlockSize == ((FX_LPBASEARRAYDATA)src.m_pData)->iBlockSize);
+ FX_INT32 iCopied = src.GetSize();
+ FXSYS_assert(iStart > -1 && iStart < iCopied);
+ if (iCount < 0) {
+ iCount = iCopied;
+ }
+ if (iStart + iCount > iCopied) {
+ iCount = iCopied - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ RemoveAll(TRUE);
+ AddSpaceTo(iCount - 1);
+ FX_memcpy(((FX_LPBASEARRAYDATA)m_pData)->pBuffer, ((FX_LPBASEARRAYDATA)src.m_pData)->pBuffer + iStart * iBlockSize, iCount * iBlockSize);
+ return iCount;
+}
+FX_INT32 CFX_BaseArray::RemoveLast(FX_INT32 iCount)
+{
+ FX_INT32 &iBlockCount = ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount;
+ if (iCount < 0 || iCount > iBlockCount) {
+ iCount = iBlockCount;
+ iBlockCount = 0;
+ } else {
+ iBlockCount -= iCount;
+ }
+ return iCount;
+}
+void CFX_BaseArray::RemoveAll(FX_BOOL bLeaveMemory)
+{
+ if (!bLeaveMemory) {
+ FX_LPBYTE &pBuffer = ((FX_LPBASEARRAYDATA)m_pData)->pBuffer;
+ if (pBuffer != NULL) {
+ FX_Free(pBuffer);
+ pBuffer = NULL;
+ }
+ ((FX_LPBASEARRAYDATA)m_pData)->iTotalCount = 0;
+ }
+ ((FX_LPBASEARRAYDATA)m_pData)->iBlockCount = 0;
+}
+CFX_BaseMassArrayImp::CFX_BaseMassArrayImp(FX_INT32 iChunkSize, FX_INT32 iBlockSize)
+ : m_iChunkSize(iChunkSize)
+ , m_iBlockSize(iBlockSize)
+ , m_iChunkCount(0)
+ , m_iBlockCount(0)
+{
+ FXSYS_assert(m_iChunkSize > 0 && m_iBlockSize > 0);
+ m_pData = FX_NEW CFX_PtrArray;
+ m_pData->SetSize(16);
+}
+CFX_BaseMassArrayImp::~CFX_BaseMassArrayImp()
+{
+ RemoveAll();
+ delete m_pData;
+}
+FX_LPBYTE CFX_BaseMassArrayImp::AddSpaceTo(FX_INT32 index)
+{
+ FXSYS_assert(index > -1);
+ FX_LPBYTE pChunk;
+ if (index < m_iBlockCount) {
+ pChunk = (FX_LPBYTE)m_pData->GetAt(index / m_iChunkSize);
+ } else {
+ FX_INT32 iMemSize = m_iChunkSize * m_iBlockSize;
+ while (TRUE) {
+ if (index < m_iChunkCount * m_iChunkSize) {
+ pChunk = (FX_LPBYTE)m_pData->GetAt(index / m_iChunkSize);
+ break;
+ } else {
+ pChunk = (FX_LPBYTE)FX_Alloc(FX_BYTE, iMemSize);
+ if (m_iChunkCount < m_pData->GetSize()) {
+ m_pData->SetAt(m_iChunkCount, pChunk);
+ } else {
+ m_pData->Add(pChunk);
+ }
+ m_iChunkCount ++;
+ }
+ }
+ }
+ FXSYS_assert(pChunk != NULL);
+ m_iBlockCount = index + 1;
+ return pChunk + (index % m_iChunkSize) * m_iBlockSize;
+}
+FX_LPBYTE CFX_BaseMassArrayImp::GetAt(FX_INT32 index) const
+{
+ FXSYS_assert(index > -1 && index < m_iBlockCount);
+ FX_LPBYTE pChunk = (FX_LPBYTE)m_pData->GetAt(index / m_iChunkSize);
+ FXSYS_assert(pChunk != NULL);
+ return pChunk + (index % m_iChunkSize) * m_iBlockSize;
+}
+FX_INT32 CFX_BaseMassArrayImp::Append(const CFX_BaseMassArrayImp &src, FX_INT32 iStart, FX_INT32 iCount)
+{
+ FXSYS_assert(m_iBlockSize == src.m_iBlockSize);
+ FX_INT32 iAdded = src.m_iBlockCount;
+ FXSYS_assert(iStart > -1 && iStart < iAdded);
+ if (iCount < 0) {
+ iCount = iAdded;
+ }
+ if (iStart + iCount > iAdded) {
+ iCount = iAdded - iStart;
+ }
+ if (iCount < 1) {
+ return m_iBlockCount;
+ }
+ FX_INT32 iBlockCount = m_iBlockCount;
+ FX_INT32 iTotal = m_iBlockCount + iCount;
+ AddSpaceTo(iTotal - 1);
+ Append(iBlockCount, src, iStart, iCount);
+ return m_iBlockCount;
+}
+FX_INT32 CFX_BaseMassArrayImp::Copy(const CFX_BaseMassArrayImp &src, FX_INT32 iStart, FX_INT32 iCount)
+{
+ FXSYS_assert(m_iBlockSize == src.m_iBlockSize);
+ FX_INT32 iCopied = src.m_iBlockCount;
+ FXSYS_assert(iStart > -1);
+ if (iStart >= iCopied) {
+ return 0;
+ }
+ RemoveAll(TRUE);
+ if (iCount < 0) {
+ iCount = iCopied;
+ }
+ if (iStart + iCount > iCopied) {
+ iCount = iCopied - iStart;
+ }
+ if (iCount < 1) {
+ return 0;
+ }
+ if (m_iBlockCount < iCount) {
+ AddSpaceTo(iCount - 1);
+ }
+ Append(0, src, iStart, iCount);
+ return m_iBlockCount;
+}
+void CFX_BaseMassArrayImp::Append(FX_INT32 iDstStart, const CFX_BaseMassArrayImp &src, FX_INT32 iSrcStart, FX_INT32 iSrcCount)
+{
+ FXSYS_assert(iDstStart > -1 && m_iBlockSize == src.m_iBlockSize);
+ FX_INT32 iSrcTotal = src.m_iBlockCount;
+ FXSYS_assert(iSrcTotal > 0 && m_iBlockCount >= iDstStart + iSrcCount);
+ FXSYS_assert(iSrcStart > -1 && iSrcStart < iSrcTotal && iSrcCount > 0 && iSrcStart + iSrcCount <= iSrcTotal);
+ FX_INT32 iDstChunkIndex = iDstStart / m_iChunkSize;
+ FX_INT32 iSrcChunkIndex = iSrcStart / src.m_iChunkSize;
+ FX_LPBYTE pDstChunk = (FX_LPBYTE)GetAt(iDstStart);
+ FX_LPBYTE pSrcChunk = (FX_LPBYTE)src.GetAt(iSrcStart);
+ FX_INT32 iDstChunkSize = m_iChunkSize - (iDstStart % m_iChunkSize);
+ FX_INT32 iSrcChunkSize = src.m_iChunkSize - (iSrcStart % src.m_iChunkSize);
+ FX_INT32 iCopySize = FX_MIN(iSrcCount, FX_MIN(iSrcChunkSize, iDstChunkSize));
+ FX_INT32 iCopyBytes = iCopySize * m_iBlockSize;
+ while (iSrcCount > 0) {
+ FXSYS_assert(pDstChunk != NULL && pSrcChunk != NULL);
+ FXSYS_memcpy(pDstChunk, pSrcChunk, iCopyBytes);
+ iSrcCount -= iCopySize;
+ iSrcChunkSize -= iCopySize;
+ if (iSrcChunkSize < 1) {
+ iSrcChunkSize = src.m_iChunkSize;
+ iSrcChunkIndex ++;
+ pSrcChunk = (FX_LPBYTE)src.m_pData->GetAt(iSrcChunkIndex);
+ } else {
+ pSrcChunk += iCopyBytes;
+ }
+ iDstChunkSize -= iCopySize;
+ if (iDstChunkSize < 1) {
+ iDstChunkSize = m_iChunkSize;
+ iDstChunkIndex ++;
+ pDstChunk = (FX_LPBYTE)m_pData->GetAt(iDstChunkIndex);
+ } else {
+ pDstChunk += iCopyBytes;
+ }
+ iCopySize = FX_MIN(iSrcCount, FX_MIN(iSrcChunkSize, iDstChunkSize));
+ iCopyBytes = iCopySize * m_iBlockSize;
+ }
+}
+FX_INT32 CFX_BaseMassArrayImp::RemoveLast(FX_INT32 iCount)
+{
+ if (iCount < 0 || iCount >= m_iBlockCount) {
+ m_iBlockCount = 0;
+ } else {
+ m_iBlockCount -= iCount;
+ }
+ return m_iBlockCount;
+}
+void CFX_BaseMassArrayImp::RemoveAll(FX_BOOL bLeaveMemory)
+{
+ if (bLeaveMemory) {
+ m_iBlockCount = 0;
+ return;
+ }
+ for (FX_INT32 i = 0; i < m_iChunkCount; i ++) {
+ FX_LPVOID p = m_pData->GetAt(i);
+ if (p == NULL) {
+ continue;
+ }
+ FX_Free(p);
+ }
+ m_pData->RemoveAll();
+ m_iChunkCount = 0;
+ m_iBlockCount = 0;
+}
+CFX_BaseMassArray::CFX_BaseMassArray(FX_INT32 iChunkSize, FX_INT32 iBlockSize)
+{
+ m_pData = FXTARGET_New CFX_BaseMassArrayImp(iChunkSize, iBlockSize);
+}
+CFX_BaseMassArray::~CFX_BaseMassArray()
+{
+ FXTARGET_Delete (CFX_BaseMassArrayImp*)m_pData;
+}
+FX_INT32 CFX_BaseMassArray::GetSize() const
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount;
+}
+FX_LPBYTE CFX_BaseMassArray::AddSpaceTo(FX_INT32 index)
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->AddSpaceTo(index);
+}
+FX_LPBYTE CFX_BaseMassArray::GetAt(FX_INT32 index) const
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->GetAt(index);
+}
+FX_INT32 CFX_BaseMassArray::Append(const CFX_BaseMassArray &src, FX_INT32 iStart, FX_INT32 iCount)
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->Append(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount);
+}
+FX_INT32 CFX_BaseMassArray::Copy(const CFX_BaseMassArray &src, FX_INT32 iStart, FX_INT32 iCount)
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->Copy(*(CFX_BaseMassArrayImp*)src.m_pData, iStart, iCount);
+}
+FX_INT32 CFX_BaseMassArray::RemoveLast(FX_INT32 iCount)
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->RemoveLast(iCount);
+}
+void CFX_BaseMassArray::RemoveAll(FX_BOOL bLeaveMemory)
+{
+ ((CFX_BaseMassArrayImp*)m_pData)->RemoveAll(bLeaveMemory);
+}
+typedef struct _FX_BASEDISCRETEARRAYDATA : public CFX_Object {
+ FX_INT32 iBlockSize;
+ FX_INT32 iChunkSize;
+ FX_INT32 iChunkCount;
+ CFX_PtrArray ChunkBuffer;
+} FX_BASEDISCRETEARRAYDATA, * FX_LPBASEDISCRETEARRAYDATA;
+typedef FX_BASEDISCRETEARRAYDATA const * FX_LPCBASEDISCRETEARRAYDATA;
+CFX_BaseDiscreteArray::CFX_BaseDiscreteArray(FX_INT32 iChunkSize, FX_INT32 iBlockSize)
+{
+ FXSYS_assert(iChunkSize > 0 && iBlockSize > 0);
+ FX_LPBASEDISCRETEARRAYDATA pData;
+ m_pData = pData = FX_NEW FX_BASEDISCRETEARRAYDATA;
+ pData->ChunkBuffer.SetSize(16);
+ pData->iChunkCount = 0;
+ pData->iChunkSize = iChunkSize;
+ pData->iBlockSize = iBlockSize;
+}
+CFX_BaseDiscreteArray::~CFX_BaseDiscreteArray()
+{
+ RemoveAll();
+ delete (FX_LPBASEDISCRETEARRAYDATA)m_pData;
+}
+FX_LPBYTE CFX_BaseDiscreteArray::AddSpaceTo(FX_INT32 index)
+{
+ FXSYS_assert(index > -1);
+ FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
+ FX_INT32 &iChunkCount = pData->iChunkCount;
+ FX_INT32 iChunkSize = pData->iChunkSize;
+ FX_LPBYTE pChunk = NULL;
+ FX_INT32 iChunk = index / iChunkSize;
+ if (iChunk < iChunkCount) {
+ pChunk = (FX_LPBYTE)pData->ChunkBuffer.GetAt(iChunk);
+ }
+ if (pChunk == NULL) {
+ FX_INT32 iMemSize = iChunkSize * pData->iBlockSize;
+ pChunk = (FX_LPBYTE)FX_Alloc(FX_BYTE, iMemSize);
+ FXSYS_memset(pChunk, 0, iMemSize);
+ pData->ChunkBuffer.SetAtGrow(iChunk, pChunk);
+ if (iChunkCount <= iChunk) {
+ iChunkCount = iChunk + 1;
+ }
+ }
+ return pChunk + (index % iChunkSize) * pData->iBlockSize;
+}
+FX_LPBYTE CFX_BaseDiscreteArray::GetAt(FX_INT32 index) const
+{
+ FXSYS_assert(index > -1);
+ FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
+ FX_INT32 iChunkSize = pData->iChunkSize;
+ FX_INT32 iChunk = index / iChunkSize;
+ if (iChunk >= pData->iChunkCount) {
+ return NULL;
+ }
+ FX_LPBYTE pChunk = (FX_LPBYTE)pData->ChunkBuffer.GetAt(iChunk);
+ if (pChunk == NULL) {
+ return NULL;
+ }
+ return pChunk + (index % iChunkSize) * pData->iBlockSize;
+}
+void CFX_BaseDiscreteArray::RemoveAll()
+{
+ FX_LPBASEDISCRETEARRAYDATA pData = (FX_LPBASEDISCRETEARRAYDATA)m_pData;
+ CFX_PtrArray &ChunkBuffer = pData->ChunkBuffer;
+ FX_INT32 &iChunkCount = pData->iChunkCount;
+ for (FX_INT32 i = 0; i < iChunkCount; i++) {
+ FX_LPVOID p = ChunkBuffer.GetAt(i);
+ if (p == NULL) {
+ continue;
+ }
+ FX_Free(p);
+ }
+ ChunkBuffer.RemoveAll();
+ iChunkCount = 0;
+}
+CFX_BaseStack::CFX_BaseStack(FX_INT32 iChunkSize, FX_INT32 iBlockSize)
+{
+ m_pData = FXTARGET_New CFX_BaseMassArrayImp(iChunkSize, iBlockSize);
+}
+CFX_BaseStack::~CFX_BaseStack()
+{
+ FXTARGET_Delete (CFX_BaseMassArrayImp*)m_pData;
+}
+FX_LPBYTE CFX_BaseStack::Push()
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->AddSpace();
+}
+void CFX_BaseStack::Pop()
+{
+ FX_INT32 &iBlockCount = ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount;
+ if (iBlockCount < 1) {
+ return;
+ }
+ iBlockCount --;
+}
+FX_LPBYTE CFX_BaseStack::GetTopElement() const
+{
+ FX_INT32 iSize = ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount;
+ if (iSize < 1) {
+ return NULL;
+ }
+ return ((CFX_BaseMassArrayImp*)m_pData)->GetAt(iSize - 1);
+}
+FX_INT32 CFX_BaseStack::GetSize() const
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->m_iBlockCount;
+}
+FX_LPBYTE CFX_BaseStack::GetAt(FX_INT32 index) const
+{
+ return ((CFX_BaseMassArrayImp*)m_pData)->GetAt(index);
+}
+void CFX_BaseStack::RemoveAll(FX_BOOL bLeaveMemory )
+{
+ ((CFX_BaseMassArrayImp*)m_pData)->RemoveAll(bLeaveMemory);
+}
diff --git a/xfa/src/fgas/src/crt/fx_utils.h b/xfa/src/fgas/src/crt/fx_utils.h
new file mode 100644
index 0000000000..a073b80e57
--- /dev/null
+++ b/xfa/src/fgas/src/crt/fx_utils.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_UTILS_IMP
+#define _FX_UTILS_IMP
+class CFX_BaseMassArrayImp : public CFX_Target
+{
+public:
+ CFX_BaseMassArrayImp(FX_INT32 iChunkSize, FX_INT32 iBlockSize);
+ ~CFX_BaseMassArrayImp();
+ FX_LPBYTE AddSpace()
+ {
+ return AddSpaceTo(m_iBlockCount);
+ }
+ FX_LPBYTE AddSpaceTo(FX_INT32 index);
+ FX_LPBYTE GetAt(FX_INT32 index) const;
+ FX_INT32 Append(const CFX_BaseMassArrayImp &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1);
+ FX_INT32 Copy(const CFX_BaseMassArrayImp &src, FX_INT32 iStart = 0, FX_INT32 iCount = -1);
+ FX_INT32 RemoveLast(FX_INT32 iCount = -1);
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE);
+ FX_INT32 m_iChunkSize;
+ FX_INT32 m_iBlockSize;
+ FX_INT32 m_iChunkCount;
+ FX_INT32 m_iBlockCount;
+ CFX_PtrArray *m_pData;
+protected:
+ void Append(FX_INT32 iDstStart, const CFX_BaseMassArrayImp &src, FX_INT32 iSrcStart = 0, FX_INT32 iSrcCount = -1);
+};
+#endif
diff --git a/xfa/src/fgas/src/fgas_base.h b/xfa/src/fgas/src/fgas_base.h
new file mode 100644
index 0000000000..d860ec3c9b
--- /dev/null
+++ b/xfa/src/fgas/src/fgas_base.h
@@ -0,0 +1,12 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXMATH_BASE_
+#define _FXMATH_BASE_
+#include "../../foxitlib.h"
+#include "../../../../core/include/fxge/fx_freetype.h"
+#include "../include/fgas.h"
+#endif
diff --git a/xfa/src/fgas/src/font/fx_fontutils.cpp b/xfa/src/fgas/src/font/fx_fontutils.cpp
new file mode 100644
index 0000000000..b2a7028fb8
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_fontutils.cpp
@@ -0,0 +1,236 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_fontutils.h"
+FX_DWORD FGAS_GetFontHashCode(FX_WORD wCodePage, FX_DWORD dwFontStyles)
+{
+ FX_DWORD dwHash = wCodePage;
+ if (dwFontStyles & FX_FONTSTYLE_FixedPitch) {
+ dwHash |= 0x00010000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Serif) {
+ dwHash |= 0x00020000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
+ dwHash |= 0x00040000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Script) {
+ dwHash |= 0x00080000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ dwHash |= 0x00100000;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Bold) {
+ dwHash |= 0x00200000;
+ }
+ return dwHash;
+}
+FX_DWORD FGAS_GetFontFamilyHash(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ CFX_WideString wsFont(pszFontFamily);
+ if (dwFontStyles & FX_FONTSTYLE_Bold) {
+ wsFont += L"Bold";
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ wsFont += L"Italic";
+ }
+ wsFont += wCodePage;
+ return FX_HashCode_String_GetW((FX_LPCWSTR)wsFont, wsFont.GetLength());
+}
+static const FGAS_FONTUSB g_FXGdiFontUSBTable[] = {
+ {0x0000 , 0x007F , 0 , 1252 },
+ {0x0080 , 0x00FF , 1 , 1252 },
+ {0x0100 , 0x017F , 2 , 1250 },
+ {0x0180 , 0x024F , 3 , 1250 },
+ {0x0250 , 0x02AF , 4 , 0xFFFF},
+ {0x02B0 , 0x02FF , 5 , 0xFFFF},
+ {0x0300 , 0x036F , 6 , 0xFFFF},
+ {0x0370 , 0x03FF , 7 , 1253 },
+ {0x0400 , 0x04FF , 9 , 1251 },
+ {0x0500 , 0x052F , 9 , 0xFFFF},
+ {0x0530 , 0x058F , 10 , 0xFFFF},
+ {0x0590 , 0x05FF , 11 , 1255 },
+ {0x0600 , 0x06FF , 13 , 1256 },
+ {0x0700 , 0x074F , 71 , 0xFFFF},
+ {0x0750 , 0x077F , 13 , 0xFFFF},
+ {0x0780 , 0x07BF , 72 , 0xFFFF},
+ {0x07C0 , 0x07FF , 14 , 0xFFFF},
+ {0x0800 , 0x08FF , 999, 0xFFFF},
+ {0x0900 , 0x097F , 15 , 0xFFFF},
+ {0x0980 , 0x09FF , 16 , 0xFFFF},
+ {0x0A00 , 0x0A7F , 17 , 0xFFFF},
+ {0x0A80 , 0x0AFF , 18 , 0xFFFF},
+ {0x0B00 , 0x0B7F , 19 , 0xFFFF},
+ {0x0B80 , 0x0BFF , 20 , 0xFFFF},
+ {0x0C00 , 0x0C7F , 21 , 0xFFFF},
+ {0x0C80 , 0x0CFF , 22 , 0xFFFF},
+ {0x0D00 , 0x0D7F , 23 , 0xFFFF},
+ {0x0D80 , 0x0DFF , 73 , 0xFFFF},
+ {0x0E00 , 0x0E7F , 24 , 874 },
+ {0x0E80 , 0x0EFF , 25 , 0xFFFF},
+ {0x0F00 , 0x0FFF , 70 , 0xFFFF},
+ {0x1000 , 0x109F , 74 , 0xFFFF},
+ {0x10A0 , 0x10FF , 26 , 0xFFFF},
+ {0x1100 , 0x11FF , 28 , 0xFFFF},
+ {0x1200 , 0x137F , 75 , 0xFFFF},
+ {0x1380 , 0x139F , 75 , 0xFFFF},
+ {0x13A0 , 0x13FF , 76 , 0xFFFF},
+ {0x1400 , 0x167F , 77 , 0xFFFF},
+ {0x1680 , 0x169F , 78 , 0xFFFF},
+ {0x16A0 , 0x16FF , 79 , 0xFFFF},
+ {0x1700 , 0x171F , 84 , 0xFFFF},
+ {0x1720 , 0x173F , 84 , 0xFFFF},
+ {0x1740 , 0x175F , 84 , 0xFFFF},
+ {0x1760 , 0x177F , 84 , 0xFFFF},
+ {0x1780 , 0x17FF , 80 , 0xFFFF},
+ {0x1800 , 0x18AF , 81 , 0xFFFF},
+ {0x18B0 , 0x18FF , 999, 0xFFFF},
+ {0x1900 , 0x194F , 93 , 0xFFFF},
+ {0x1950 , 0x197F , 94 , 0xFFFF},
+ {0x1980 , 0x19DF , 95 , 0xFFFF},
+ {0x19E0 , 0x19FF , 80 , 0xFFFF},
+ {0x1A00 , 0x1A1F , 96 , 0xFFFF},
+ {0x1A20 , 0x1AFF , 999, 0xFFFF},
+ {0x1B00 , 0x1B7F , 27 , 0xFFFF},
+ {0x1B80 , 0x1BBF , 112, 0xFFFF},
+ {0x1BC0 , 0x1BFF , 999, 0xFFFF},
+ {0x1C00 , 0x1C4F , 113, 0xFFFF},
+ {0x1C50 , 0x1C7F , 114, 0xFFFF},
+ {0x1C80 , 0x1CFF , 999, 0xFFFF},
+ {0x1D00 , 0x1D7F , 4 , 0xFFFF},
+ {0x1D80 , 0x1DBF , 4 , 0xFFFF},
+ {0x1DC0 , 0x1DFF , 6 , 0xFFFF},
+ {0x1E00 , 0x1EFF , 29 , 0xFFFF},
+ {0x1F00 , 0x1FFF , 30 , 0xFFFF},
+ {0x2000 , 0x206F , 31 , 0xFFFF},
+ {0x2070 , 0x209F , 32 , 0xFFFF},
+ {0x20A0 , 0x20CF , 33 , 0xFFFF},
+ {0x20D0 , 0x20FF , 34 , 0xFFFF},
+ {0x2100 , 0x214F , 35 , 0xFFFF},
+ {0x2150 , 0x215F , 36 , 0xFFFF},
+ {0x2160 , 0x216B , 36 , 936 },
+ {0x216C , 0x216F , 36 , 0xFFFF},
+ {0x2170 , 0x2179 , 36 , 936 },
+ {0x217A , 0x218F , 36 , 0xFFFF},
+ {0x2190 , 0x2199 , 37 , 949 },
+ {0x219A , 0x21FF , 37 , 0xFFFF},
+ {0x2200 , 0x22FF , 38 , 0xFFFF},
+ {0x2300 , 0x23FF , 39 , 0xFFFF},
+ {0x2400 , 0x243F , 40 , 0xFFFF},
+ {0x2440 , 0x245F , 41 , 0xFFFF},
+ {0x2460 , 0x2473 , 42 , 932 },
+ {0x2474 , 0x249B , 42 , 936 },
+ {0x249C , 0x24E9 , 42 , 949 },
+ {0x24EA , 0x24FF , 42 , 0xFFFF},
+ {0x2500 , 0x2573 , 43 , 936 },
+ {0x2574 , 0x257F , 43 , 0xFFFF},
+ {0x2580 , 0x2580 , 44 , 0xFFFF},
+ {0x2581 , 0x258F , 44 , 936 },
+ {0x2590 , 0x259F , 44 , 0xFFFF},
+ {0x25A0 , 0x25FF , 45 , 0xFFFF},
+ {0x2600 , 0x26FF , 46 , 0xFFFF},
+ {0x2700 , 0x27BF , 47 , 0xFFFF},
+ {0x27C0 , 0x27EF , 38 , 0xFFFF},
+ {0x27F0 , 0x27FF , 37 , 0xFFFF},
+ {0x2800 , 0x28FF , 82 , 0xFFFF},
+ {0x2900 , 0x297F , 37 , 0xFFFF},
+ {0x2980 , 0x29FF , 38 , 0xFFFF},
+ {0x2A00 , 0x2AFF , 38 , 0xFFFF},
+ {0x2B00 , 0x2BFF , 37 , 0xFFFF},
+ {0x2C00 , 0x2C5F , 97 , 0xFFFF},
+ {0x2C60 , 0x2C7F , 29 , 0xFFFF},
+ {0x2C80 , 0x2CFF , 8 , 0xFFFF},
+ {0x2D00 , 0x2D2F , 26 , 0xFFFF},
+ {0x2D30 , 0x2D7F , 98 , 0xFFFF},
+ {0x2D80 , 0x2DDF , 75 , 0xFFFF},
+ {0x2DE0 , 0x2DFF , 9 , 0xFFFF},
+ {0x2E00 , 0x2E7F , 31 , 0xFFFF},
+ {0x2E80 , 0x2EFF , 59 , 0xFFFF},
+ {0x2F00 , 0x2FDF , 59 , 0xFFFF},
+ {0x2FE0 , 0x2FEF , 999, 0xFFFF},
+ {0x2FF0 , 0x2FFF , 59 , 0xFFFF},
+ {0x3000 , 0x303F , 48 , 0xFFFF},
+ {0x3040 , 0x309F , 49 , 932 },
+ {0x30A0 , 0x30FF , 50 , 932 },
+ {0x3100 , 0x3129 , 51 , 936 },
+ {0x312A , 0x312F , 51 , 0xFFFF},
+ {0x3130 , 0x318F , 52 , 949 },
+ {0x3190 , 0x319F , 59 , 0xFFFF},
+ {0x31A0 , 0x31BF , 51 , 0xFFFF},
+ {0x31C0 , 0x31EF , 61 , 0xFFFF},
+ {0x31F0 , 0x31FF , 50 , 0xFFFF},
+ {0x3200 , 0x321C , 54 , 949 },
+ {0x321D , 0x325F , 54 , 0xFFFF},
+ {0x3260 , 0x327F , 54 , 949 },
+ {0x3280 , 0x32FF , 54 , 0xFFFF},
+ {0x3300 , 0x3387 , 55 , 0xFFFF},
+ {0x3388 , 0x33D0 , 55 , 949 },
+ {0x33D1 , 0x33FF , 55 , 0xFFFF},
+ {0x3400 , 0x4DBF , 59 , 0xFFFF},
+ {0x4DC0 , 0x4DFF , 99 , 0xFFFF},
+ {0x4E00 , 0x9FA5 , 59 , 936 },
+ {0x9FA6 , 0x9FFF , 59 , 0xFFFF},
+ {0xA000 , 0xA48F , 83 , 0xFFFF},
+ {0xA490 , 0xA4CF , 83 , 0xFFFF},
+ {0xA4D0 , 0xA4FF , 999, 0xFFFF},
+ {0xA500 , 0xA63F , 12 , 0xFFFF},
+ {0xA640 , 0xA69F , 9 , 0xFFFF},
+ {0xA6A0 , 0xA6FF , 999, 0xFFFF},
+ {0xA700 , 0xA71F , 5 , 0xFFFF},
+ {0xA720 , 0xA7FF , 29 , 0xFFFF},
+ {0xA800 , 0xA82F , 100, 0xFFFF},
+ {0xA830 , 0xA8FF , 999, 0xFFFF},
+ {0xA840 , 0xA87F , 53 , 0xFFFF},
+ {0xA880 , 0xA8DF , 115, 0xFFFF},
+ {0xA8E0 , 0xA8FF , 999, 0xFFFF},
+ {0xA900 , 0xA92F , 116, 0xFFFF},
+ {0xA930 , 0xA95F , 117, 0xFFFF},
+ {0xA960 , 0xA9FF , 999, 0xFFFF},
+ {0xAA00 , 0xAA5F , 118, 0xFFFF},
+ {0xAA60 , 0xABFF , 999, 0xFFFF},
+ {0xAC00 , 0xD7AF , 56 , 949 },
+ {0xD7B0 , 0xD7FF , 999, 0xFFFF},
+ {0xD800 , 0xDB7F , 57 , 0xFFFF},
+ {0xDB80 , 0xDBFF , 57 , 0xFFFF},
+ {0xDC00 , 0xDFFF , 57 , 0xFFFF},
+ {0xE000 , 0xE814 , 60 , 0xFFFF},
+ {0xE815 , 0xE864 , 60 , 936 },
+ {0xE865 , 0xF8FF , 60 , 0xFFFF},
+ {0xF900 , 0xFA0B , 61 , 949 },
+ {0xFA0C , 0xFA0D , 61 , 936 },
+ {0xFA0E , 0xFA2D , 61 , 932 },
+ {0xFA2E , 0xFAFF , 61 , 0xFFFF},
+ {0xFB00 , 0xFB4F , 62 , 0xFFFF},
+ {0xFB50 , 0xFDFF , 63 , 1256 },
+ {0xFE00 , 0xFE0F , 91 , 0xFFFF},
+ {0xFE10 , 0xFE1F , 65 , 0xFFFF},
+ {0xFE20 , 0xFE2F , 64 , 0xFFFF},
+ {0xFE30 , 0xFE4F , 65 , 0xFFFF},
+ {0xFE50 , 0xFE6F , 66 , 0xFFFF},
+ {0xFE70 , 0xFEFF , 67 , 1256 },
+ {0xFF00 , 0xFF5F , 68 , 936 },
+ {0xFF60 , 0xFF9F , 68 , 932 },
+ {0xFFA0 , 0xFFEF , 68 , 0xFFFF},
+};
+FGAS_LPCFONTUSB FGAS_GetUnicodeBitField(FX_WCHAR wUnicode)
+{
+ FX_INT32 iEnd = sizeof(g_FXGdiFontUSBTable) / sizeof(FGAS_FONTUSB) - 1;
+ FXSYS_assert(iEnd >= 0);
+ FX_INT32 iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const FGAS_FONTUSB &usb = g_FXGdiFontUSBTable[iMid];
+ if (wUnicode < usb.wStartUnicode) {
+ iEnd = iMid - 1;
+ } else if (wUnicode > usb.wEndUnicode) {
+ iStart = iMid + 1;
+ } else {
+ return &usb;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
diff --git a/xfa/src/fgas/src/font/fx_fontutils.h b/xfa/src/fgas/src/font/fx_fontutils.h
new file mode 100644
index 0000000000..1e3088fde8
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_fontutils.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FGAS_FONTUTIL_H_
+#define _FGAS_FONTUTIL_H_
+typedef struct _FGAS_FONTUSB {
+ FX_WCHAR wStartUnicode;
+ FX_WCHAR wEndUnicode;
+ FX_WORD wBitField;
+ FX_WORD wCodePage;
+} FGAS_FONTUSB, * FGAS_LPFONTUSB;
+typedef FGAS_FONTUSB const * FGAS_LPCFONTUSB;
+FX_DWORD FGAS_GetFontHashCode(FX_WORD wCodePage, FX_DWORD dwFontStyles);
+FX_DWORD FGAS_GetFontFamilyHash(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage);
+FGAS_LPCFONTUSB FGAS_GetUnicodeBitField(FX_WCHAR wUnicode);
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gdifont.cpp b/xfa/src/fgas/src/font/fx_gdifont.cpp
new file mode 100644
index 0000000000..e9ab665b5a
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_gdifont.cpp
@@ -0,0 +1,532 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_gdifont.h"
+#include "fx_stdfontmgr.h"
+#ifdef _FXPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+CFX_GdiFontCache::CFX_GdiFontCache()
+ : m_GlyphMap(128)
+{
+}
+CFX_GdiFontCache::~CFX_GdiFontCache()
+{
+ FX_POSITION pos = m_GlyphMap.GetStartPosition();
+ FX_INT32 iGlyph;
+ FX_LPGDIGOCACHE pGlyph;
+ while (pos != NULL) {
+ pGlyph = NULL;
+ m_GlyphMap.GetNextAssoc(pos, (void*&)iGlyph, (void*&)pGlyph);
+ if (pGlyph != NULL) {
+ FDE_Free(pGlyph->pOutline);
+ FDE_Free(pGlyph);
+ }
+ }
+ m_GlyphMap.RemoveAll();
+}
+void CFX_GdiFontCache::SetCachedGlyphOutline(FX_DWORD dwGlyph, const GLYPHMETRICS &gm, FX_LPBYTE pOutline)
+{
+ FXSYS_assert(pOutline != NULL);
+ FX_LPGDIGOCACHE pGlyph = (FX_LPGDIGOCACHE)FDE_Alloc(sizeof(FX_GDIGOCACHE));
+ pGlyph->gm = gm;
+ pGlyph->pOutline = pOutline;
+ m_GlyphMap.SetAt((void*)dwGlyph, (void*)pGlyph);
+}
+FX_LPCGDIGOCACHE CFX_GdiFontCache::GetCachedGlyphOutline(FX_DWORD dwGlyph) const
+{
+ FX_LPCGDIGOCACHE pGlyph = NULL;
+ if (!m_GlyphMap.Lookup((void*)dwGlyph, (void*&)pGlyph)) {
+ return FALSE;
+ }
+ return pGlyph;
+}
+IFX_Font* IFX_Font::LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage, IFX_FontMgr *pFontMgr)
+{
+ CFX_GdiFont *pFont = FX_NEW CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, IFX_FontMgr *pFontMgr)
+{
+ CFX_GdiFont *pFont = FX_NEW CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pBuffer, iLength)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(FX_LPCWSTR pszFileName, IFX_FontMgr *pFontMgr)
+{
+ CFX_GdiFont *pFont = FX_NEW CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pszFileName)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(IFX_Stream *pFontStream, IFX_FontMgr *pFontMgr, FX_BOOL bSaveStream )
+{
+ CFX_GdiFont *pFont = FX_NEW CFX_GdiFont(pFontMgr);
+ if (!pFont->LoadFont(pFontStream)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+IFX_Font* IFX_Font::LoadFont(CFX_Font *pExtFont, IFX_FontMgr *pFontMgr)
+{
+ FXSYS_assert(FALSE);
+ return NULL;
+}
+#define FX_GDIFONT_FONTCACHESIZE 8
+CFX_GdiFont::CFX_GdiFont(IFX_FontMgr *pFontMgr)
+ : m_pFontMgr(pFontMgr)
+ , m_iRefCount(1)
+ , m_WidthCache(1024)
+ , m_hOldFont(NULL)
+ , m_hFont(NULL)
+ , m_hDC(NULL)
+ , m_wsFontFileName()
+ , m_FontFamilies()
+ , m_hRes(NULL)
+ , m_dwStyles(0)
+ , m_SubstFonts()
+ , m_FontMapper(16)
+ , m_FontCache(FX_GDIFONT_FONTCACHESIZE)
+{
+ m_hDC = ::CreateCompatibleDC(NULL);
+ FX_memset(&m_LogFont, 0, sizeof(m_LogFont));
+ FXSYS_assert(m_hDC != NULL);
+}
+CFX_GdiFont::~CFX_GdiFont()
+{
+ FX_INT32 iCount = m_SubstFonts.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ IFX_Font *pFont = (IFX_Font*)m_SubstFonts[i];
+ pFont->Release();
+ }
+ m_SubstFonts.RemoveAll();
+ m_FontMapper.RemoveAll();
+ if (m_hFont != NULL) {
+ ::SelectObject(m_hDC, m_hOldFont);
+ ::DeleteObject(m_hFont);
+ }
+ ::DeleteDC(m_hDC);
+ if (m_hRes != NULL) {
+ if (m_wsFontFileName.GetLength() > 0) {
+ ::RemoveFontResourceW((FX_LPCWSTR)m_wsFontFileName);
+ } else {
+ ::RemoveFontMemResourceEx(m_hRes);
+ }
+ }
+ m_WidthCache.RemoveAll();
+ ClearCache();
+}
+void CFX_GdiFont::ClearCache()
+{
+ FX_INT32 iCount = m_SubstFonts.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ IFX_Font *pFont = (IFX_Font*)m_SubstFonts[i];
+ ((CFX_GdiFont*)pFont)->ClearCache();
+ }
+ FX_POSITION pos = m_FontCache.GetStartPosition();
+ FX_DWORD dwMAT2;
+ CFX_GdiFontCache *pCache;
+ while (pos != NULL) {
+ pCache = NULL;
+ m_FontCache.GetNextAssoc(pos, (void*&)dwMAT2, (void*&)pCache);
+ if (pCache != NULL) {
+ delete pCache;
+ }
+ }
+ m_FontCache.RemoveAll();
+}
+void CFX_GdiFont::Release()
+{
+ if (-- m_iRefCount < 1) {
+ if (m_pFontMgr != NULL) {
+ m_pFontMgr->RemoveFont(this);
+ }
+ delete this;
+ }
+}
+IFX_Font* CFX_GdiFont::Retain()
+{
+ ++ m_iRefCount;
+ return this;
+}
+FX_BOOL CFX_GdiFont::LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ FXSYS_assert(m_hFont == NULL);
+ LOGFONTW lf;
+ FX_memset(&lf, 0, sizeof(lf));
+ lf.lfHeight = -1000;
+ lf.lfWeight = (dwFontStyles & FX_FONTSTYLE_Bold) ? FW_BOLD : FW_NORMAL;
+ lf.lfItalic = (dwFontStyles & FX_FONTSTYLE_Italic) != 0;
+ lf.lfPitchAndFamily = (dwFontStyles & FX_FONTSTYLE_FixedPitch) ? FIXED_PITCH : VARIABLE_PITCH;
+ if (dwFontStyles & FX_FONTSTYLE_Serif) {
+ lf.lfPitchAndFamily |= FF_ROMAN;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Script) {
+ lf.lfPitchAndFamily |= FF_SCRIPT;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
+ lf.lfCharSet = SYMBOL_CHARSET;
+ } else {
+ FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage);
+ lf.lfCharSet = wCharSet != 0xFFFF ? (FX_BYTE)wCharSet : DEFAULT_CHARSET;
+ }
+ if (pszFontFamily == NULL) {
+ lf.lfFaceName[0] = L'\0';
+ } else {
+ FXSYS_wcsncpy(lf.lfFaceName, pszFontFamily, 31);
+ }
+ return LoadFont(lf);
+}
+FX_BOOL CFX_GdiFont::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength)
+{
+ FXSYS_assert(m_hFont == NULL && pBuffer != NULL && iLength > 0);
+ Gdiplus::PrivateFontCollection pfc;
+ if (pfc.AddMemoryFont(pBuffer, iLength) != Gdiplus::Ok) {
+ return FALSE;
+ }
+ if (GetFontFamilies(pfc) < 1) {
+ return FALSE;
+ }
+ FX_DWORD dwCount = 0;
+ m_hRes = ::AddFontMemResourceEx((void*)pBuffer, iLength, 0, &dwCount);
+ if (m_hRes == NULL) {
+ return FALSE;
+ }
+ CFX_WideString wsFamily = m_FontFamilies[0];
+ m_hFont = ::CreateFontW(-1000, 0, 0, 0, FW_NORMAL, FALSE, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, (FX_LPCWSTR)wsFamily);
+ if (m_hFont == NULL) {
+ ::RemoveFontMemResourceEx(m_hRes);
+ m_hRes = NULL;
+ return FALSE;
+ }
+ RetrieveFontStyles();
+ m_hOldFont = ::SelectObject(m_hDC, m_hFont);
+ ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
+ return TRUE;
+}
+FX_BOOL CFX_GdiFont::LoadFont(FX_LPCWSTR pszFileName)
+{
+ FXSYS_assert(m_hFont == NULL && pszFileName != NULL);
+ Gdiplus::PrivateFontCollection pfc;
+ if (pfc.AddFontFile(pszFileName) != Gdiplus::Ok) {
+ return FALSE;
+ }
+ if (GetFontFamilies(pfc) < 1) {
+ return FALSE;
+ }
+ m_wsFontFileName = pszFileName;
+ m_hRes = (HANDLE)::AddFontResourceW(pszFileName);
+ if (m_hRes == NULL) {
+ return FALSE;
+ }
+ CFX_WideString wsFamily = m_FontFamilies[0];
+ m_hFont = ::CreateFontW(-1000, 0, 0, 0, FW_NORMAL, FALSE, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, (FX_LPCWSTR)wsFamily);
+ if (m_hFont == NULL) {
+ ::RemoveFontResourceW(pszFileName);
+ m_hRes = NULL;
+ return FALSE;
+ }
+ RetrieveFontStyles();
+ ::SelectObject(m_hDC, m_hFont);
+ ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
+ return TRUE;
+}
+FX_BOOL CFX_GdiFont::LoadFont(IFX_Stream *pFontStream)
+{
+ FXSYS_assert(m_hFont == NULL && pFontStream != NULL);
+ FX_INT32 iLength = pFontStream->GetLength();
+ if (iLength < 1) {
+ return FALSE;
+ }
+ FX_LPBYTE pBuf = (FX_LPBYTE)FDE_Alloc(iLength);
+ if (pBuf == NULL) {
+ return FALSE;
+ }
+ iLength = pFontStream->ReadData(pBuf, iLength);
+ FX_BOOL bRet = LoadFont(pBuf, iLength);
+ FDE_Free(pBuf);
+ return bRet;
+}
+FX_BOOL CFX_GdiFont::LoadFont(const LOGFONTW &lf)
+{
+ FXSYS_assert(m_hFont == NULL);
+ m_hFont = ::CreateFontIndirectW((LPLOGFONTW)&lf);
+ if (m_hFont == NULL) {
+ return FALSE;
+ }
+ RetrieveFontStyles();
+ ::SelectObject(m_hDC, m_hFont);
+ ::GetOutlineTextMetricsW(m_hDC, sizeof(m_OutlineTM), &m_OutlineTM);
+ return TRUE;
+}
+FX_INT32 CFX_GdiFont::GetFontFamilies(Gdiplus::FontCollection &fc)
+{
+ FX_INT32 iCount = fc.GetFamilyCount();
+ if (iCount < 1) {
+ return iCount;
+ }
+ Gdiplus::FontFamily *pFontFamilies = (Gdiplus::FontFamily*)FDE_Alloc(iCount * sizeof(Gdiplus::FontFamily));
+ if (pFontFamilies == NULL) {
+ return -1;
+ }
+ FX_INT32 iFind = 0;
+ fc.GetFamilies(iCount, pFontFamilies, &iFind);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFX_WideString wsFamilyName;
+ FX_LPWSTR pName = wsFamilyName.GetBuffer(LF_FACESIZE);
+ pFontFamilies[i].GetFamilyName(pName);
+ wsFamilyName.ReleaseBuffer();
+ m_FontFamilies.Add(wsFamilyName);
+ }
+ FDE_Free(pFontFamilies);
+ return iCount;
+}
+void CFX_GdiFont::RetrieveFontStyles()
+{
+ FXSYS_assert(m_hFont != NULL);
+ FX_memset(&m_LogFont, 0, sizeof(m_LogFont));
+ ::GetObjectW(m_hFont, sizeof(m_LogFont), &m_LogFont);
+ m_dwStyles = FX_GetGdiFontStyles(m_LogFont);
+}
+void CFX_GdiFont::GetFamilyName(CFX_WideString &wsFamily) const
+{
+ FXSYS_assert(m_hFont != NULL);
+ wsFamily = m_LogFont.lfFaceName;
+}
+FX_BOOL CFX_GdiFont::GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bRecursive, FX_BOOL bCharCode)
+{
+ iWidth = (FX_INT32)(FX_SHORT)m_WidthCache.GetAt(wUnicode, 0);
+ if (iWidth == 0 || iWidth == -1) {
+ IFX_Font *pFont = NULL;
+ FX_INT32 iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
+ if (iGlyph != 0xFFFF && pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ if (!::GetCharWidthI(m_hDC, iGlyph, 1, NULL, &iWidth)) {
+ iWidth = -1;
+ }
+ } else if (((CFX_GdiFont*)pFont)->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) {
+ return TRUE;
+ }
+ } else {
+ iWidth = -1;
+ }
+ Lock();
+ m_WidthCache.SetAtGrow(wUnicode, (FX_SHORT)iWidth);
+ Unlock();
+ }
+ return iWidth > 0;
+}
+FX_BOOL CFX_GdiFont::GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode)
+{
+ return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode);
+}
+FX_INT32 CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bRecursive, IFX_Font **ppFont, FX_BOOL bCharCode)
+{
+ FX_INT32 iGlyph = 0XFFFF;
+ if (::GetGlyphIndicesW(m_hDC, &wUnicode, 1, (LPWORD)&iGlyph, GGI_MARK_NONEXISTING_GLYPHS) != GDI_ERROR && iGlyph != 0xFFFF) {
+ if (ppFont != NULL) {
+ *ppFont = (IFX_Font*)this;
+ }
+ return iGlyph;
+ }
+ FX_LPCFONTUSB pFontUSB = FX_GetUnicodeBitField(wUnicode);
+ if (pFontUSB == NULL) {
+ return 0xFFFF;
+ }
+ FX_WORD wBitField = pFontUSB->wBitField;
+ if (wBitField >= 128) {
+ return 0xFFFF;
+ }
+ IFX_Font *pFont = NULL;
+ m_FontMapper.Lookup((void*)wBitField, (void*&)pFont);
+ if (pFont != NULL && pFont != (IFX_Font*)this) {
+ iGlyph = ((CFX_GdiFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyph != 0xFFFF) {
+ FX_INT32 i = m_SubstFonts.Find(pFont);
+ if (i > -1) {
+ iGlyph |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyph;
+ }
+ }
+ }
+ if (m_pFontMgr != NULL && bRecursive) {
+ IFX_Font *pFont = m_pFontMgr->GetDefFontByUnicode(wUnicode, m_dwStyles, m_LogFont.lfFaceName);
+ if (pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ pFont->Release();
+ return 0xFFFF;
+ }
+ m_FontMapper.SetAt((void*)wBitField, (void*)pFont);
+ FX_INT32 i = m_SubstFonts.GetSize();
+ m_SubstFonts.Add(pFont);
+ iGlyph = ((CFX_GdiFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyph != 0xFFFF) {
+ iGlyph |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyph;
+ }
+ }
+ }
+ return 0xFFFF;
+}
+FX_INT32 CFX_GdiFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode)
+{
+ return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode);
+}
+FX_INT32 CFX_GdiFont::GetAscent() const
+{
+ return m_OutlineTM.otmAscent;
+}
+FX_INT32 CFX_GdiFont::GetDescent() const
+{
+ return m_OutlineTM.otmDescent;
+}
+FX_BOOL CFX_GdiFont::GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode)
+{
+ FX_INT32 iGlyphIndex = GetGlyphIndex(wUnicode, bCharCode);
+ if (iGlyphIndex == 0xFFFF) {
+ return FALSE;
+ }
+ IFX_Font *pFont = GetSubstFont(iGlyphIndex);
+ if (pFont == NULL) {
+ return FALSE;
+ }
+ GLYPHMETRICS gm;
+ iGlyphIndex &= 0x00FFFFFF;
+ static const MAT2 mat2 = {{0, 1}, {0, 0}, {0, 0}, {0, 1}};
+ if (::GetGlyphOutlineW(((CFX_GdiFont*)pFont)->m_hDC, iGlyphIndex, GGO_GLYPH_INDEX | GGO_METRICS, &gm, 0, NULL, &mat2) != GDI_ERROR) {
+ bbox.left = gm.gmptGlyphOrigin.x;
+ bbox.top = gm.gmptGlyphOrigin.y;
+ bbox.width = gm.gmBlackBoxX;
+ bbox.height = gm.gmBlackBoxY;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CFX_GdiFont::GetBBox(CFX_Rect &bbox)
+{
+ bbox.left = m_OutlineTM.otmrcFontBox.left;
+ bbox.top = m_OutlineTM.otmrcFontBox.top;
+ bbox.width = m_OutlineTM.otmrcFontBox.right - m_OutlineTM.otmrcFontBox.left;
+ bbox.height = m_OutlineTM.otmrcFontBox.bottom - m_OutlineTM.otmrcFontBox.top;
+ return TRUE;
+}
+FX_INT32 CFX_GdiFont::GetItalicAngle() const
+{
+ return m_OutlineTM.otmItalicAngle / 10;
+}
+void CFX_GdiFont::Reset()
+{
+ Lock();
+ m_WidthCache.RemoveAll();
+ ClearCache();
+ Unlock();
+}
+IFX_Font* CFX_GdiFont::GetSubstFont(FX_INT32 iGlyphIndex) const
+{
+ FX_INT32 iHigher = (iGlyphIndex & 0x7F000000) >> 24;
+ if (iHigher == 0) {
+ return (IFX_Font*)this;
+ }
+ if (iHigher > m_SubstFonts.GetSize()) {
+ return (IFX_Font*)this;
+ }
+ return (IFX_Font*)m_SubstFonts[iHigher - 1];
+}
+FX_DWORD CFX_GdiFont::GetGlyphDIBits(FX_INT32 iGlyphIndex, FX_ARGB argb, const MAT2 *pMatrix, GLYPHMETRICS &gm, FX_LPVOID pBuffer, FX_DWORD bufSize)
+{
+ static const UINT uFormat = GGO_GLYPH_INDEX | GGO_GRAY8_BITMAP;
+ IFX_Font *pFont = GetSubstFont(iGlyphIndex);
+ if (pFont == NULL) {
+ return 0;
+ }
+ if (pFont != (IFX_Font*)this) {
+ return ((CFX_GdiFont*)pFont)->GetGlyphDIBits(iGlyphIndex & 0x00FFFFFF, argb, pMatrix, gm, pBuffer, bufSize);
+ }
+ FX_LPBYTE pGlyphOutline = NULL;
+ FXSYS_assert(pMatrix != NULL);
+ FX_DWORD dwMAT2 = GetMAT2HashCode((const FIXED*)pMatrix);
+ CFX_GdiFontCache *pCache = NULL;
+ if (m_FontCache.Lookup((void*)dwMAT2, (void*&)pCache) && pCache != NULL) {
+ FX_LPCGDIGOCACHE pGO = pCache->GetCachedGlyphOutline(iGlyphIndex);
+ if (pGO != NULL) {
+ gm = pGO->gm;
+ pGlyphOutline = pGO->pOutline;
+ }
+ }
+ if (pGlyphOutline == NULL) {
+ FX_DWORD dwGlyphSize = ::GetGlyphOutlineW(m_hDC, iGlyphIndex, uFormat, &gm, 0, NULL, pMatrix);
+ if (dwGlyphSize == 0 || dwGlyphSize == GDI_ERROR) {
+ return 0;
+ }
+ pGlyphOutline = (FX_LPBYTE)FX_Alloc(dwGlyphSize);
+ ::GetGlyphOutlineW(m_hDC, iGlyphIndex, uFormat, &gm, dwGlyphSize, pGlyphOutline, pMatrix);
+ if (pCache == NULL) {
+ pCache = FX_NEW CFX_GdiFontCache;
+ if (m_FontCache.GetCount() >= FX_GDIFONT_FONTCACHESIZE) {
+ ClearCache();
+ }
+ m_FontCache.SetAt((void*)dwMAT2, (void*)pCache);
+ }
+ pCache->SetCachedGlyphOutline(iGlyphIndex, gm, pGlyphOutline);
+ }
+ FX_DWORD dwDibSize = gm.gmBlackBoxX * 4 * gm.gmBlackBoxY;
+ if (pBuffer == NULL || bufSize < dwDibSize) {
+ return dwDibSize;
+ }
+ CreateGlyphBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY, pGlyphOutline, (FX_LPDWORD)pBuffer, argb);
+ return dwDibSize;
+}
+FX_DWORD CFX_GdiFont::GetHashCode() const
+{
+ return FX_GetFontHashCode(FX_GetCodePageFromCharset(m_LogFont.lfCharSet), FX_GetGdiFontStyles(m_LogFont));
+}
+FX_DWORD CFX_GdiFont::GetMAT2HashCode(const FIXED *pFixed)
+{
+ FXSYS_assert(pFixed != NULL);
+ FX_DWORD dwHash1 = 0, dwHash2 = 5381, dwRet;
+ for (int i = 0; i < 4; i ++) {
+ dwRet = *((const FX_DWORD*)pFixed);
+ dwHash1 = 1313 * dwHash1 + dwRet;
+ dwHash2 += (dwHash2 << 5) + dwRet;
+ pFixed ++;
+ }
+ return ((dwHash1 & 0x0000FFFF) << 16) | (dwHash2 & 0x0000FFFF);
+}
+void CFX_GdiFont::CreateGlyphBitmap(FX_INT32 iWidth, FX_INT32 iHeight, FX_LPBYTE pOutline, FX_LPDWORD pDIB, FX_ARGB argb)
+{
+ FX_INT32 padding = ((iWidth + 3) / 4) * 4 - iWidth;
+ FX_DWORD alpha;
+ FX_INT32 i, j;
+ for (j = iHeight - 1; j >= 0; --j) {
+ for (i = iWidth - 1; i >= 0; --i) {
+ if ((alpha = *pOutline++) == 0) {
+ *pDIB++ = 0;
+ } else {
+ alpha = (argb >> 24) * (alpha * 4 - 1) / 256;
+ *pDIB++ = (alpha << 24) | (argb & 0x00FFFFFF);
+ }
+ }
+ pOutline += padding;
+ }
+}
+#endif
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gdifont.h b/xfa/src/fgas/src/font/fx_gdifont.h
new file mode 100644
index 0000000000..f6d88f38a0
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_gdifont.h
@@ -0,0 +1,89 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_GDIOBJECT_IMP
+#define _FX_GDIOBJECT_IMP
+#ifdef _FXPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+typedef struct _FX_GDIGOCACHE {
+ GLYPHMETRICS gm;
+ FX_LPBYTE pOutline;
+} FX_GDIGOCACHE, * FX_LPGDIGOCACHE;
+typedef FX_GDIGOCACHE const * FX_LPCGDIGOCACHE;
+class CFX_GdiFontCache : public CFX_Object
+{
+public:
+ CFX_GdiFontCache();
+ ~CFX_GdiFontCache();
+ void SetCachedGlyphOutline(FX_DWORD dwGlyph, const GLYPHMETRICS &gm, FX_LPBYTE pOutline);
+ FX_LPCGDIGOCACHE GetCachedGlyphOutline(FX_DWORD dwGlyph) const;
+protected:
+ CFX_MapPtrToPtr m_GlyphMap;
+};
+class CFX_GdiFont : public IFX_Font, public CFX_ThreadLock, public CFX_Object
+{
+public:
+ CFX_GdiFont(IFX_FontMgr *pFontMgr);
+ ~CFX_GdiFont();
+ virtual void Release();
+ virtual IFX_Font* Retain();
+ FX_BOOL LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage);
+ FX_BOOL LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength);
+ FX_BOOL LoadFont(FX_LPCWSTR pszFileName);
+ FX_BOOL LoadFont(IFX_Stream *pFontStream);
+ FX_BOOL LoadFont(const LOGFONTW &lf);
+ virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0)
+ {
+ return NULL;
+ }
+ virtual void GetFamilyName(CFX_WideString &wsFamily) const;
+ virtual FX_DWORD GetFontStyles() const
+ {
+ return m_dwStyles;
+ }
+ virtual FX_BYTE GetCharSet() const
+ {
+ return m_LogFont.lfCharSet;
+ }
+ virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE);
+ virtual FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE);
+ virtual FX_INT32 GetAscent() const;
+ virtual FX_INT32 GetDescent() const;
+ virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode = FALSE);
+ virtual FX_BOOL GetBBox(CFX_Rect &bbox);
+ virtual FX_INT32 GetItalicAngle() const;
+ virtual void Reset();
+ FX_DWORD GetGlyphDIBits(FX_INT32 iGlyphIndex, FX_ARGB argb, const MAT2 *pMatrix, GLYPHMETRICS &gm, FX_LPVOID pBuffer, FX_DWORD bufSize);
+ FX_DWORD GetHashCode() const;
+protected:
+ IFX_FontMgr *m_pFontMgr;
+ FX_INT32 m_iRefCount;
+ CFX_WordDiscreteArray m_WidthCache;
+ OUTLINETEXTMETRICW m_OutlineTM;
+ HGDIOBJ m_hOldFont;
+ HFONT m_hFont;
+ HDC m_hDC;
+ LOGFONTW m_LogFont;
+ CFX_WideString m_wsFontFileName;
+ CFX_WideStringArray m_FontFamilies;
+ HANDLE m_hRes;
+ FX_DWORD m_dwStyles;
+ CFX_PtrArray m_SubstFonts;
+ CFX_MapPtrToPtr m_FontMapper;
+ CFX_MapPtrToPtr m_FontCache;
+ void ClearCache();
+ FX_INT32 GetFontFamilies(Gdiplus::FontCollection &fc);
+ void RetrieveFontStyles();
+ IFX_Font* GetSubstFont(FX_INT32 iGlyphIndex) const;
+ FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bRecursive, FX_BOOL bCharCode = FALSE);
+ FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bRecursive, IFX_Font **ppFont, FX_BOOL bCharCode = FALSE);
+ FX_DWORD GetMAT2HashCode(const FIXED *pFixed);
+ void CreateGlyphBitmap(FX_INT32 iWidth, FX_INT32 iHeight, FX_LPBYTE pOutline, FX_LPDWORD pDIB, FX_ARGB argb);
+ friend class CFX_GdiFontMgr;
+};
+#endif
+#endif
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gefont.cpp b/xfa/src/fgas/src/font/fx_gefont.cpp
new file mode 100644
index 0000000000..f952bc730e
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_gefont.cpp
@@ -0,0 +1,595 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_gefont.h"
+#include "fx_fontutils.h"
+#ifndef _FXPLUS
+IFX_Font* IFX_Font::LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage, IFX_FontMgr *pFontMgr)
+{
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->GetFontByCodePage(wCodePage, dwFontStyles, pszFontFamily);
+ }
+ return NULL;
+#else
+ CFX_GEFont *pFont = FX_NEW CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pszFontFamily, dwFontStyles, wCodePage)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, IFX_FontMgr *pFontMgr)
+{
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->LoadFont(pBuffer, iLength, 0, NULL);
+ }
+ return NULL;
+#else
+ CFX_GEFont *pFont = FX_NEW CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pBuffer, iLength)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(FX_LPCWSTR pszFileName, IFX_FontMgr *pFontMgr)
+{
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->LoadFont(pszFileName, 0, NULL);
+ }
+ return NULL;
+#else
+ CFX_GEFont *pFont = FX_NEW CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pszFileName)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(IFX_Stream *pFontStream, IFX_FontMgr *pFontMgr, FX_BOOL bSaveStream)
+{
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (NULL != pFontMgr) {
+ return pFontMgr->LoadFont(pFontStream, 0, NULL);
+ }
+ return NULL;
+#else
+ CFX_GEFont *pFont = FX_NEW CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pFontStream, bSaveStream)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+#endif
+}
+IFX_Font* IFX_Font::LoadFont(CFX_Font *pExtFont, IFX_FontMgr *pFontMgr, FX_BOOL bTakeOver)
+{
+ CFX_GEFont *pFont = FX_NEW CFX_GEFont(pFontMgr);
+ if (!pFont->LoadFont(pExtFont, bTakeOver)) {
+ pFont->Release();
+ return NULL;
+ }
+ return pFont;
+}
+CFX_GEFont::CFX_GEFont(IFX_FontMgr *pFontMgr)
+ : CFX_ThreadLock()
+ , m_pFont(NULL)
+ , m_pFontMgr(pFontMgr)
+ , m_iRefCount(1)
+ , m_bExtFont(FALSE)
+ , m_pStream(NULL)
+ , m_pFileRead(NULL)
+ , m_pFontEncoding(NULL)
+ , m_pCharWidthMap(NULL)
+ , m_pRectArray(NULL)
+ , m_pBBoxMap(NULL)
+ , m_wCharSet(0xFFFF)
+ , m_pProvider(NULL)
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ , m_bUseLogFontStyle(FALSE)
+ , m_dwLogFontStyle(0)
+#endif
+ , m_SubstFonts()
+ , m_FontMapper(16)
+{
+}
+CFX_GEFont::CFX_GEFont(const CFX_GEFont &src, FX_DWORD dwFontStyles)
+ : CFX_ThreadLock()
+ , m_pFont(NULL)
+ , m_pFontMgr(src.m_pFontMgr)
+ , m_iRefCount(1)
+ , m_bExtFont(FALSE)
+ , m_pStream(NULL)
+ , m_pFileRead(NULL)
+ , m_pFontEncoding(NULL)
+ , m_pCharWidthMap(NULL)
+ , m_pRectArray(NULL)
+ , m_pBBoxMap(NULL)
+ , m_wCharSet(0xFFFF)
+ , m_pProvider(NULL)
+ , m_SubstFonts()
+ , m_FontMapper(16)
+{
+ m_pFont = FX_NEW CFX_Font;
+ FXSYS_assert(m_pFont != NULL);
+ FXSYS_assert(src.m_pFont != NULL);
+ m_pFont->LoadClone(src.m_pFont);
+ CFX_SubstFont *&pSubst = m_pFont->m_pSubstFont;
+ if (pSubst == NULL) {
+ pSubst = FX_NEW CFX_SubstFont;
+ }
+ if (pSubst) {
+ pSubst->m_Weight = (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ pSubst->m_SubstFlags |= FXFONT_SUBST_ITALIC;
+ }
+ }
+ InitFont();
+}
+CFX_GEFont::~CFX_GEFont()
+{
+ FX_INT32 iCount = m_SubstFonts.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ IFX_Font *pFont = (IFX_Font*)m_SubstFonts[i];
+ pFont->Release();
+ }
+ m_SubstFonts.RemoveAll();
+ m_FontMapper.RemoveAll();
+ if (m_pFileRead != NULL) {
+ m_pFileRead->Release();
+ }
+ if (m_pStream != NULL) {
+ m_pStream->Release();
+ }
+ if (m_pFontEncoding != NULL) {
+ delete m_pFontEncoding;
+ }
+ if (m_pCharWidthMap != NULL) {
+ FXTARGET_Delete m_pCharWidthMap;
+ }
+ if (m_pRectArray != NULL) {
+ FXTARGET_Delete m_pRectArray;
+ }
+ if (m_pBBoxMap != NULL) {
+ delete m_pBBoxMap;
+ }
+ if (m_pFont != NULL && !m_bExtFont) {
+ delete m_pFont;
+ }
+}
+void CFX_GEFont::Release()
+{
+ if (-- m_iRefCount < 1) {
+ if (m_pFontMgr != NULL) {
+ m_pFontMgr->RemoveFont(this);
+ }
+ delete this;
+ }
+}
+IFX_Font* CFX_GEFont::Retain()
+{
+ ++ m_iRefCount;
+ return this;
+}
+FX_BOOL CFX_GEFont::LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ if (m_pFont != NULL) {
+ return FALSE;
+ }
+ Lock();
+ CFX_ByteString csFontFamily;
+ if (pszFontFamily != NULL) {
+ csFontFamily = CFX_ByteString::FromUnicode(pszFontFamily);
+ }
+ FX_DWORD dwFlags = 0;
+ if (dwFontStyles & FX_FONTSTYLE_FixedPitch) {
+ dwFlags |= FXFONT_FIXED_PITCH;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Serif) {
+ dwFlags |= FXFONT_SERIF;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Symbolic) {
+ dwFlags |= FXFONT_SYMBOLIC;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Script) {
+ dwFlags |= FXFONT_SCRIPT;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ dwFlags |= FXFONT_ITALIC;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Bold) {
+ dwFlags |= FXFONT_BOLD;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_ExactMatch) {
+ dwFlags |= FXFONT_EXACTMATCH;
+ }
+ FX_INT32 iWeight = (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
+ FX_WORD wCharSet = FX_GetCharsetFromCodePage(wCodePage);
+ if (wCharSet == 0xFFFF) {
+ wCharSet = FXSYS_GetACP();
+ }
+ m_wCharSet = wCharSet;
+ m_pFont = FX_NEW CFX_Font;
+ if ((dwFlags & FXFONT_ITALIC) && (dwFlags & FXFONT_BOLD)) {
+ csFontFamily += ",BoldItalic";
+ } else if (dwFlags & FXFONT_BOLD) {
+ csFontFamily += ",Bold";
+ } else if (dwFlags & FXFONT_ITALIC) {
+ csFontFamily += ",Italic";
+ }
+ FX_BOOL bRet = m_pFont->LoadSubst(csFontFamily, TRUE, dwFlags, iWeight, 0, wCodePage);
+ bRet = m_pFont->m_Face != NULL;
+ if (bRet) {
+ InitFont();
+ }
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 length)
+{
+ if (m_pFont != NULL) {
+ return FALSE;
+ }
+ Lock();
+ m_pFont = FX_NEW CFX_Font;
+ FX_BOOL bRet = m_pFont->LoadEmbedded(pBuffer, length);
+ if (bRet) {
+ InitFont();
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(FX_LPCWSTR pszFileName)
+{
+ if (m_pFont != NULL) {
+ return FALSE;
+ }
+ if (m_pStream != NULL) {
+ return FALSE;
+ }
+ if (m_pFileRead != NULL) {
+ return FALSE;
+ }
+ Lock();
+ m_pStream = IFX_Stream::CreateStream(pszFileName, FX_STREAMACCESS_Binary | FX_STREAMACCESS_Read);
+ m_pFileRead = FX_CreateFileRead(m_pStream);
+ FX_BOOL bRet = FALSE;
+ if (m_pStream != NULL && m_pFileRead != NULL) {
+ m_pFont = FX_NEW CFX_Font;
+ bRet = m_pFont->LoadFile(m_pFileRead);
+ if (!bRet) {
+ m_pFileRead->Release();
+ m_pFileRead = NULL;
+ } else {
+ InitFont();
+ }
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(IFX_Stream *pFontStream, FX_BOOL bSaveStream)
+{
+ if (m_pFont != NULL) {
+ return FALSE;
+ }
+ if (pFontStream == NULL || pFontStream->GetLength() < 1) {
+ return FALSE;
+ }
+ if (m_pFileRead != NULL) {
+ return FALSE;
+ }
+ Lock();
+ if (bSaveStream) {
+ m_pStream = pFontStream;
+ }
+ m_pFileRead = FX_CreateFileRead(pFontStream);
+ m_pFont = FX_NEW CFX_Font;
+ FX_BOOL bRet = m_pFont->LoadFile(m_pFileRead);
+ if (!bRet) {
+ m_pFileRead->Release();
+ m_pFileRead = NULL;
+ } else {
+ InitFont();
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return bRet;
+}
+FX_BOOL CFX_GEFont::LoadFont(CFX_Font *pExtFont, FX_BOOL bTakeOver)
+{
+ if (m_pFont != NULL) {
+ return FALSE;
+ }
+ if (pExtFont == NULL) {
+ return FALSE;
+ }
+ Lock();
+ if ((m_pFont = pExtFont) != NULL) {
+ m_bExtFont = !bTakeOver;
+ InitFont();
+ } else {
+ m_bExtFont = TRUE;
+ }
+ m_wCharSet = 0xFFFF;
+ Unlock();
+ return m_pFont != NULL;
+}
+void CFX_GEFont::InitFont()
+{
+ if (m_pFont == NULL) {
+ return;
+ }
+ if (m_pFontEncoding == NULL) {
+#ifdef FXFM_ENCODING_NONE
+ m_pFontEncoding = FX_CreateFontEncodingEx(m_pFont);
+#else
+ m_pFontEncoding = FXGE_CreateUnicodeEncoding(m_pFont);
+#endif
+ }
+ if (m_pCharWidthMap == NULL) {
+ m_pCharWidthMap = FXTARGET_New CFX_WordDiscreteArray(1024);
+ }
+ if (m_pRectArray == NULL) {
+ m_pRectArray = FXTARGET_New CFX_RectMassArray(16);
+ }
+ if (m_pBBoxMap == NULL) {
+ m_pBBoxMap = FX_NEW CFX_MapPtrToPtr(16);
+ }
+}
+IFX_Font* CFX_GEFont::Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage )
+{
+ if (GetFontStyles() == dwFontStyles) {
+ return Retain();
+ }
+ return FX_NEW CFX_GEFont(*this, dwFontStyles);
+}
+FX_BYTE CFX_GEFont::GetCharSet() const
+{
+ FXSYS_assert(m_pFont != NULL);
+ if (m_wCharSet != 0xFFFF) {
+ return (FX_BYTE)m_wCharSet;
+ }
+ if (m_pFont->m_pSubstFont == NULL) {
+ return FX_CHARSET_Default;
+ }
+ return m_pFont->m_pSubstFont->m_Charset;
+}
+void CFX_GEFont::GetFamilyName(CFX_WideString &wsFamily) const
+{
+ FXSYS_assert(m_pFont != NULL);
+ if (m_pFont->m_pSubstFont == NULL || m_pFont->m_pSubstFont->m_Family.GetLength() == 0) {
+ wsFamily = CFX_WideString::FromLocal(m_pFont->GetFamilyName());
+ } else {
+ wsFamily = CFX_WideString::FromLocal(m_pFont->m_pSubstFont->m_Family);
+ }
+}
+void CFX_GEFont::GetPsName(CFX_WideString &wsName) const
+{
+ wsName = m_pFont->GetPsName();
+}
+FX_DWORD CFX_GEFont::GetFontStyles() const
+{
+ FXSYS_assert(m_pFont != NULL);
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if (m_bUseLogFontStyle) {
+ return m_dwLogFontStyle;
+ }
+#endif
+ FX_DWORD dwStyles = 0;
+ if (m_pFont->m_pSubstFont == NULL) {
+ if (m_pFont->IsBold()) {
+ dwStyles |= FX_FONTSTYLE_Bold;
+ }
+ if (m_pFont->IsItalic()) {
+ dwStyles |= FX_FONTSTYLE_Italic;
+ }
+ } else {
+ if (m_pFont->m_pSubstFont->m_Weight == FXFONT_FW_BOLD) {
+ dwStyles |= FX_FONTSTYLE_Bold;
+ }
+ if (m_pFont->m_pSubstFont->m_SubstFlags & FXFONT_SUBST_ITALIC) {
+ dwStyles |= FX_FONTSTYLE_Italic;
+ }
+ }
+ return dwStyles;
+}
+FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode)
+{
+ return GetCharWidth(wUnicode, iWidth, TRUE, bCharCode);
+}
+FX_BOOL CFX_GEFont::GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bRecursive, FX_BOOL bCharCode)
+{
+ FXSYS_assert (m_pCharWidthMap != NULL);
+ iWidth = m_pCharWidthMap->GetAt(wUnicode, 0);
+ if (iWidth < 1) {
+ if (!m_pProvider || !m_pProvider->GetCharWidth(this, wUnicode, iWidth, bCharCode)) {
+ IFX_Font *pFont = NULL;
+ FX_INT32 iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
+ if (iGlyph != 0xFFFF && pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ iWidth = m_pFont->GetGlyphWidth(iGlyph);
+ if (iWidth < 0) {
+ iWidth = -1;
+ }
+ } else if (((CFX_GEFont*)pFont)->GetCharWidth(wUnicode, iWidth, FALSE, bCharCode)) {
+ return TRUE;
+ }
+ } else {
+ iWidth = -1;
+ }
+ }
+ Lock();
+ m_pCharWidthMap->SetAtGrow(wUnicode, (FX_SHORT)iWidth);
+ Unlock();
+ } else if (iWidth == 65535) {
+ iWidth = -1;
+ }
+ return iWidth > 0;
+}
+FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode)
+{
+ return GetCharBBox(wUnicode, bbox, TRUE, bCharCode);
+}
+FX_BOOL CFX_GEFont::GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bRecursive, FX_BOOL bCharCode)
+{
+ FXSYS_assert(m_pRectArray != NULL);
+ FXSYS_assert(m_pBBoxMap != NULL);
+ FX_LPVOID pRect = NULL;
+ if (!m_pBBoxMap->Lookup((void*)(FX_UINTPTR)wUnicode, pRect)) {
+ IFX_Font *pFont = NULL;
+ FX_INT32 iGlyph = GetGlyphIndex(wUnicode, TRUE, &pFont, bCharCode);
+ if (iGlyph != 0xFFFF && pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ FX_RECT rtBBox;
+ if (m_pFont->GetGlyphBBox(iGlyph, rtBBox)) {
+ Lock();
+ CFX_Rect rt;
+ rt.Set(rtBBox.left, rtBBox.top, rtBBox.Width(), rtBBox.Height());
+ FX_INT32 index = m_pRectArray->Add(rt);
+ pRect = m_pRectArray->GetPtrAt(index);
+ m_pBBoxMap->SetAt((void*)(FX_UINTPTR)wUnicode, pRect);
+ Unlock();
+ }
+ } else if (((CFX_GEFont*)pFont)->GetCharBBox(wUnicode, bbox, FALSE, bCharCode)) {
+ return TRUE;
+ }
+ }
+ }
+ if (pRect == NULL) {
+ return FALSE;
+ }
+ bbox = *(FX_LPCRECT)pRect;
+ return TRUE;
+}
+FX_BOOL CFX_GEFont::GetBBox(CFX_Rect &bbox)
+{
+ FX_RECT rt(0, 0, 0, 0);
+ FX_BOOL bRet = m_pFont->GetBBox(rt);
+ if (bRet) {
+ bbox.left = rt.left;
+ bbox.width = rt.Width();
+ bbox.top = rt.bottom;
+ bbox.height = -rt.Height();
+ }
+ return bRet;
+}
+FX_INT32 CFX_GEFont::GetItalicAngle() const
+{
+ if (m_pFont->m_pSubstFont == NULL) {
+ return 0;
+ }
+ return m_pFont->m_pSubstFont->m_ItalicAngle;
+}
+FX_INT32 CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode)
+{
+ return GetGlyphIndex(wUnicode, TRUE, NULL, bCharCode);
+}
+FX_INT32 CFX_GEFont::GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bRecursive, IFX_Font **ppFont, FX_BOOL bCharCode)
+{
+ FXSYS_assert (m_pFontEncoding != NULL);
+ FX_INT32 iGlyphIndex = m_pFontEncoding->GlyphFromCharCode(wUnicode);
+ if (iGlyphIndex > 0) {
+ if (ppFont != NULL) {
+ *ppFont = (IFX_Font*)this;
+ }
+ return iGlyphIndex;
+ }
+ FGAS_LPCFONTUSB pFontUSB = FGAS_GetUnicodeBitField(wUnicode);
+ if (pFontUSB == NULL) {
+ return 0xFFFF;
+ }
+ FX_WORD wBitField = pFontUSB->wBitField;
+ if (wBitField >= 128) {
+ return 0xFFFF;
+ }
+ IFX_Font *pFont = NULL;
+ m_FontMapper.Lookup((void*)(FX_UINTPTR)wUnicode, (void*&)pFont);
+ if (pFont != NULL && pFont != (IFX_Font*)this) {
+ iGlyphIndex = ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyphIndex != 0xFFFF) {
+ FX_INT32 i = m_SubstFonts.Find(pFont);
+ if (i > -1) {
+ iGlyphIndex |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyphIndex;
+ }
+ }
+ }
+ if (m_pFontMgr != NULL && bRecursive) {
+ CFX_WideString wsFamily;
+ GetFamilyName(wsFamily);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ IFX_Font *pFont = m_pFontMgr->GetDefFontByUnicode(wUnicode, GetFontStyles(), (FX_LPCWSTR)wsFamily);
+#else
+ IFX_Font *pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), (FX_LPCWSTR)wsFamily);
+ if (NULL == pFont) {
+ pFont = m_pFontMgr->GetFontByUnicode(wUnicode, GetFontStyles(), NULL);
+ }
+#endif
+ if (pFont != NULL) {
+ if (pFont == (IFX_Font*)this) {
+ pFont->Release();
+ return 0xFFFF;
+ }
+ m_FontMapper.SetAt((void*)(FX_UINTPTR)wUnicode, (void*)pFont);
+ FX_INT32 i = m_SubstFonts.GetSize();
+ m_SubstFonts.Add(pFont);
+ iGlyphIndex = ((CFX_GEFont*)pFont)->GetGlyphIndex(wUnicode, FALSE, NULL, bCharCode);
+ if (iGlyphIndex != 0xFFFF) {
+ iGlyphIndex |= ((i + 1) << 24);
+ if (ppFont != NULL) {
+ *ppFont = pFont;
+ }
+ return iGlyphIndex;
+ }
+ }
+ }
+ return 0xFFFF;
+}
+FX_INT32 CFX_GEFont::GetAscent() const
+{
+ return m_pFont->GetAscent();
+}
+FX_INT32 CFX_GEFont::GetDescent() const
+{
+ return m_pFont->GetDescent();
+}
+void CFX_GEFont::Reset()
+{
+ Lock();
+ FX_INT32 iCount = m_SubstFonts.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ IFX_Font *pFont = (IFX_Font*)m_SubstFonts[i];
+ ((CFX_GEFont*)pFont)->Reset();
+ }
+ if (m_pCharWidthMap != NULL) {
+ m_pCharWidthMap->RemoveAll();
+ }
+ if (m_pBBoxMap != NULL) {
+ m_pBBoxMap->RemoveAll();
+ }
+ if (m_pRectArray != NULL) {
+ m_pRectArray->RemoveAll();
+ }
+ Unlock();
+}
+IFX_Font* CFX_GEFont::GetSubstFont(FX_INT32 iGlyphIndex) const
+{
+ iGlyphIndex = ((FX_DWORD)iGlyphIndex) >> 24;
+ return iGlyphIndex == 0 ? (IFX_Font*)this : (IFX_Font*)m_SubstFonts[iGlyphIndex - 1];
+}
+#endif
diff --git a/xfa/src/fgas/src/font/fx_gefont.h b/xfa/src/fgas/src/font/fx_gefont.h
new file mode 100644
index 0000000000..430ff09852
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_gefont.h
@@ -0,0 +1,81 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_GRAPHOBJS_IMP
+#define _FX_GRAPHOBJS_IMP
+#ifndef _FXPLUS
+class CFX_GEFontMgr;
+#ifndef FXFONT_SUBST_ITALIC
+#define FXFONT_SUBST_ITALIC 0x02
+#endif
+class CFX_GEFont : public IFX_Font, public CFX_ThreadLock, public CFX_Object
+{
+public:
+ CFX_GEFont(const CFX_GEFont &src, FX_DWORD dwFontStyles);
+ CFX_GEFont(IFX_FontMgr *pFontMgr);
+ ~CFX_GEFont();
+ virtual void Release();
+ virtual IFX_Font* Retain();
+ FX_BOOL LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage);
+ FX_BOOL LoadFont(FX_LPCBYTE pBuffer, FX_INT32 length);
+ FX_BOOL LoadFont(FX_LPCWSTR pszFileName);
+ FX_BOOL LoadFont(IFX_Stream *pFontStream, FX_BOOL bSaveStream);
+ FX_BOOL LoadFont(CFX_Font *pExtFont, FX_BOOL bTakeOver = FALSE);
+ virtual IFX_Font* Derive(FX_DWORD dwFontStyles, FX_WORD wCodePage = 0);
+ virtual void GetFamilyName(CFX_WideString &wsFamily) const;
+ virtual void GetPsName(CFX_WideString &wsName) const;
+ virtual FX_DWORD GetFontStyles() const;
+ virtual FX_BYTE GetCharSet() const;
+ virtual FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode = FALSE);
+ virtual FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bCharCode = FALSE);
+ virtual FX_INT32 GetAscent() const;
+ virtual FX_INT32 GetDescent() const;
+ virtual FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bCharCode = FALSE);
+ virtual FX_BOOL GetBBox(CFX_Rect &bbox);
+ virtual FX_INT32 GetItalicAngle() const;
+ virtual void Reset();
+ virtual IFX_Font* GetSubstFont(FX_INT32 iGlyphIndex) const;
+ virtual void* GetDevFont()const
+ {
+ return (void*)m_pFont;
+ }
+ virtual void SetFontProvider(IFX_FontProvider* pProvider)
+ {
+ m_pProvider = pProvider;
+ }
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ virtual void SetLogicalFontStyle(FX_DWORD dwLogFontStyle)
+ {
+ m_bUseLogFontStyle = TRUE;
+ m_dwLogFontStyle = dwLogFontStyle;
+ };
+#endif
+protected:
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FX_BOOL m_bUseLogFontStyle;
+ FX_DWORD m_dwLogFontStyle;
+#endif
+ CFX_Font *m_pFont;
+ IFX_FontMgr *m_pFontMgr;
+ FX_INT32 m_iRefCount;
+ FX_BOOL m_bExtFont;
+ IFX_Stream *m_pStream;
+ IFX_FileRead *m_pFileRead;
+ IFX_FontEncoding *m_pFontEncoding;
+ CFX_WordDiscreteArray *m_pCharWidthMap;
+ CFX_RectMassArray *m_pRectArray;
+ CFX_MapPtrToPtr *m_pBBoxMap;
+ IFX_FontProvider *m_pProvider;
+ FX_WORD m_wCharSet;
+ CFX_PtrArray m_SubstFonts;
+ CFX_MapPtrToPtr m_FontMapper;
+ void InitFont();
+ FX_BOOL GetCharBBox(FX_WCHAR wUnicode, CFX_Rect &bbox, FX_BOOL bRecursive, FX_BOOL bCharCode = FALSE);
+ FX_BOOL GetCharWidth(FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bRecursive, FX_BOOL bCharCode = FALSE);
+ FX_INT32 GetGlyphIndex(FX_WCHAR wUnicode, FX_BOOL bRecursive, IFX_Font **ppFont, FX_BOOL bCharCode = FALSE);
+};
+#endif
+#endif
diff --git a/xfa/src/fgas/src/font/fx_stdfontmgr.cpp b/xfa/src/fgas/src/font/fx_stdfontmgr.cpp
new file mode 100644
index 0000000000..ae59cab2e5
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_stdfontmgr.cpp
@@ -0,0 +1,1490 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_stdfontmgr.h"
+#include "fx_fontutils.h"
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+IFX_FontMgr* IFX_FontMgr::Create(FX_LPEnumAllFonts pEnumerator, FX_LPMatchFont pMatcher , FX_LPVOID pUserData )
+{
+ return FX_NEW CFX_StdFontMgrImp(pEnumerator, pMatcher, pUserData);
+}
+CFX_StdFontMgrImp::CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator, FX_LPMatchFont pMatcher, FX_LPVOID pUserData)
+ : m_pMatcher(pMatcher)
+ , m_pEnumerator(pEnumerator)
+ , m_FontFaces()
+ , m_Fonts()
+ , m_CPFonts(8)
+ , m_FamilyFonts(16)
+ , m_UnicodeFonts(16)
+ , m_BufferFonts(4)
+ , m_FileFonts(4)
+ , m_StreamFonts(4)
+ , m_DeriveFonts(4)
+ , m_pUserData(pUserData)
+{
+ if (m_pEnumerator != NULL) {
+ m_pEnumerator(m_FontFaces, m_pUserData, NULL, 0xFEFF);
+ }
+ if (m_pMatcher == NULL) {
+ m_pMatcher = FX_DefFontMatcher;
+ }
+ FXSYS_assert(m_pMatcher != NULL);
+}
+CFX_StdFontMgrImp::~CFX_StdFontMgrImp()
+{
+ m_FontFaces.RemoveAll();
+ m_CPFonts.RemoveAll();
+ m_FamilyFonts.RemoveAll();
+ m_UnicodeFonts.RemoveAll();
+ m_BufferFonts.RemoveAll();
+ m_FileFonts.RemoveAll();
+ m_StreamFonts.RemoveAll();
+ m_DeriveFonts.RemoveAll();
+ for (FX_INT32 i = m_Fonts.GetUpperBound(); i >= 0; i--) {
+ IFX_Font *pFont = (IFX_Font*)m_Fonts[i];
+ if (pFont != NULL) {
+ pFont->Release();
+ }
+ }
+ m_Fonts.RemoveAll();
+}
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily)
+{
+ FX_DWORD dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
+ IFX_Font *pFont = NULL;
+ if (m_CPFonts.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)pFont)) {
+ return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : NULL;
+ }
+ FX_LPCFONTDESCRIPTOR pFD;
+ if ((pFD = FindFont(pszFontFamily, dwFontStyles, TRUE, wCodePage)) == NULL)
+ if ((pFD = FindFont(NULL, dwFontStyles, TRUE, wCodePage)) == NULL)
+ if ((pFD = FindFont(NULL, dwFontStyles, FALSE, wCodePage)) == NULL) {
+ return NULL;
+ }
+ FXSYS_assert(pFD != NULL);
+ pFont = IFX_Font::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_CPFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontFamilyHash(pFD->wsFontFace, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily)
+{
+ return GetDefFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles, pszFontFamily);
+}
+#define _FX_USEGASFONTMGR_
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily)
+{
+ FGAS_LPCFONTUSB pRet = FGAS_GetUnicodeBitField(wUnicode);
+ if (pRet->wBitField == 999) {
+ return NULL;
+ }
+ FX_DWORD dwHash = FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, pRet->wBitField);
+ IFX_Font *pFont = NULL;
+ if (m_UnicodeFonts.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)pFont)) {
+ return pFont ? LoadFont(pFont, dwFontStyles, pRet->wCodePage) : NULL;
+ }
+#ifdef _FX_USEGASFONTMGR_
+ FX_LPCFONTDESCRIPTOR pFD = FindFont(pszFontFamily, dwFontStyles, FALSE, pRet->wCodePage, pRet->wBitField, wUnicode);
+ if (pFD == NULL && pszFontFamily) {
+ pFD = FindFont(NULL, dwFontStyles, FALSE, pRet->wCodePage, pRet->wBitField, wUnicode);
+ }
+ if (pFD == NULL) {
+ return NULL;
+ }
+ FXSYS_assert(pFD);
+ FX_WORD wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
+ FX_LPCWSTR pFontFace = pFD->wsFontFace;
+ pFont = IFX_Font::LoadFont(pFontFace, dwFontStyles, wCodePage, this);
+#else
+ CFX_FontMapper* pBuiltinMapper = CFX_GEModule::Get()->GetFontMgr()->m_pBuiltinMapper;
+ if (pBuiltinMapper == NULL) {
+ return NULL;
+ }
+ FX_INT32 iWeight = (dwFontStyles & FX_FONTSTYLE_Bold) ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL;
+ int italic_angle = 0;
+ FXFT_Face ftFace = pBuiltinMapper->FindSubstFontByUnicode(wUnicode, dwFontStyles, iWeight, italic_angle);
+ if (ftFace == NULL) {
+ return NULL;
+ }
+ CFX_Font* pFXFont = FX_NEW CFX_Font;
+ if (pFXFont == NULL) {
+ return NULL;
+ }
+ pFXFont->m_Face = ftFace;
+ pFXFont->m_pFontData = FXFT_Get_Face_Stream_Base(ftFace);
+ pFXFont->m_dwSize = FXFT_Get_Face_Stream_Size(ftFace);
+ pFont = IFX_Font::LoadFont(pFXFont, this);
+ FX_WORD wCodePage = pRet->wCodePage;
+ CFX_WideString wsPsName = pFXFont->GetPsName();
+ FX_LPCWSTR pFontFace = wsPsName;
+#endif
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_UnicodeFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
+ m_CPFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontFamilyHash(pFontFace, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily)
+{
+ return GetDefFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage), dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ FX_DWORD dwHash = FGAS_GetFontFamilyHash(pszFontFamily, dwFontStyles, wCodePage);
+ IFX_Font *pFont = NULL;
+ if (m_FamilyFonts.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)pFont)) {
+ return pFont ? LoadFont(pFont, dwFontStyles, wCodePage) : NULL;
+ }
+ FX_LPCFONTDESCRIPTOR pFD = NULL;
+ if ((pFD = FindFont(pszFontFamily, dwFontStyles, TRUE, wCodePage)) == NULL)
+ if ((pFD = FindFont(pszFontFamily, dwFontStyles, FALSE, wCodePage)) == NULL) {
+ return NULL;
+ }
+ FXSYS_assert(pFD != NULL);
+ if (wCodePage == 0xFFFF) {
+ wCodePage = FX_GetCodePageFromCharset(pFD->uCharSet);
+ }
+ pFont = IFX_Font::LoadFont(pFD->wsFontFace, dwFontStyles, wCodePage, this);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ dwHash = FGAS_GetFontHashCode(wCodePage, dwFontStyles);
+ m_CPFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength)
+{
+ FXSYS_assert(pBuffer != NULL && iLength > 0);
+ IFX_Font *pFont = NULL;
+ if (m_BufferFonts.Lookup((void*)pBuffer, (void*&)pFont)) {
+ if (pFont != NULL) {
+ return pFont->Retain();
+ }
+ }
+ pFont = IFX_Font::LoadFont(pBuffer, iLength, this);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_BufferFonts.SetAt((void*)pBuffer, pFont);
+ return pFont->Retain();
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(FX_LPCWSTR pszFileName)
+{
+ FXSYS_assert(pszFileName != NULL);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszFileName, -1);
+ IFX_Font *pFont = NULL;
+ if (m_FileFonts.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)pFont)) {
+ if (pFont != NULL) {
+ return pFont->Retain();
+ }
+ }
+ pFont = IFX_Font::LoadFont(pszFileName, NULL);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_FileFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ return pFont->Retain();
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(IFX_Stream *pFontStream, FX_LPCWSTR pszFontAlias , FX_DWORD dwFontStyles , FX_WORD wCodePage , FX_BOOL bSaveStream )
+{
+ FXSYS_assert(pFontStream != NULL && pFontStream->GetLength() > 0);
+ IFX_Font *pFont = NULL;
+ if (m_StreamFonts.Lookup((void*)pFontStream, (void*&)pFont)) {
+ if (pFont != NULL) {
+ if (pszFontAlias != NULL) {
+ FX_DWORD dwHash = FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ }
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ }
+ pFont = IFX_Font::LoadFont(pFontStream, this, bSaveStream);
+ if (pFont != NULL) {
+ m_Fonts.Add(pFont);
+ m_StreamFonts.SetAt((void*)pFontStream, (void*)pFont);
+ if (pszFontAlias != NULL) {
+ FX_DWORD dwHash = FGAS_GetFontFamilyHash(pszFontAlias, dwFontStyles, wCodePage);
+ m_FamilyFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ }
+ return LoadFont(pFont, dwFontStyles, wCodePage);
+ }
+ return NULL;
+}
+IFX_Font* CFX_StdFontMgrImp::LoadFont(IFX_Font *pSrcFont, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ FXSYS_assert(pSrcFont != NULL);
+ if (pSrcFont->GetFontStyles() == dwFontStyles) {
+ return pSrcFont->Retain();
+ }
+ void* buffer[3] = {pSrcFont, (void*)(FX_UINTPTR)dwFontStyles, (void*)(FX_UINTPTR)wCodePage};
+ FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)buffer, 3 * sizeof(void*));
+ IFX_Font *pFont = NULL;
+ if (m_DeriveFonts.GetCount() > 0) {
+ m_DeriveFonts.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)pFont);
+ if (pFont != NULL) {
+ return pFont->Retain();
+ }
+ }
+ pFont = pSrcFont->Derive(dwFontStyles, wCodePage);
+ if (pFont != NULL) {
+ m_DeriveFonts.SetAt((void*)(FX_UINTPTR)dwHash, (void*)pFont);
+ FX_INT32 index = m_Fonts.Find(pFont);
+ if (index < 0) {
+ m_Fonts.Add(pFont);
+ pFont->Retain();
+ }
+ return pFont;
+ }
+ return NULL;
+}
+void CFX_StdFontMgrImp::ClearFontCache()
+{
+ FX_INT32 iCount = m_Fonts.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ IFX_Font *pFont = (IFX_Font*)m_Fonts[i];
+ if (pFont != NULL) {
+ pFont->Reset();
+ }
+ }
+}
+void CFX_StdFontMgrImp::RemoveFont(CFX_MapPtrToPtr &fontMap, IFX_Font *pFont)
+{
+ FX_POSITION pos = fontMap.GetStartPosition();
+ FX_LPVOID pKey;
+ FX_LPVOID pFind;
+ while (pos != NULL) {
+ pFind = NULL;
+ fontMap.GetNextAssoc(pos, pKey, pFind);
+ if (pFind != (void*)pFont) {
+ continue;
+ }
+ fontMap.RemoveKey(pKey);
+ break;
+ }
+}
+void CFX_StdFontMgrImp::RemoveFont(IFX_Font *pFont)
+{
+ RemoveFont(m_CPFonts, pFont);
+ RemoveFont(m_FamilyFonts, pFont);
+ RemoveFont(m_UnicodeFonts, pFont);
+ RemoveFont(m_BufferFonts, pFont);
+ RemoveFont(m_FileFonts, pFont);
+ RemoveFont(m_StreamFonts, pFont);
+ RemoveFont(m_DeriveFonts, pFont);
+ FX_INT32 iFind = m_Fonts.Find(pFont);
+ if (iFind > -1) {
+ m_Fonts.RemoveAt(iFind, 1);
+ }
+}
+FX_LPCFONTDESCRIPTOR CFX_StdFontMgrImp::FindFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_DWORD dwMatchFlags, FX_WORD wCodePage, FX_DWORD dwUSB , FX_WCHAR wUnicode )
+{
+ if (m_pMatcher == NULL) {
+ return NULL;
+ }
+ FX_FONTMATCHPARAMS params;
+ FX_memset(&params, 0, sizeof(params));
+ params.dwUSB = dwUSB;
+ params.wUnicode = wUnicode;
+ params.wCodePage = wCodePage;
+ params.pwsFamily = pszFontFamily;
+ params.dwFontStyles = dwFontStyles;
+ params.dwMatchFlags = dwMatchFlags;
+ FX_LPCFONTDESCRIPTOR pDesc = m_pMatcher(&params, m_FontFaces, m_pUserData);
+ if (pDesc) {
+ return pDesc;
+ }
+ if (pszFontFamily && m_pEnumerator) {
+ CFX_FontDescriptors namedFonts;
+ m_pEnumerator(namedFonts, m_pUserData, pszFontFamily, wUnicode);
+ params.pwsFamily = NULL;
+ pDesc = m_pMatcher(&params, namedFonts, m_pUserData);
+ if (pDesc == NULL) {
+ return NULL;
+ }
+ for (FX_INT32 i = m_FontFaces.GetSize() - 1; i >= 0; i--) {
+ FX_LPCFONTDESCRIPTOR pMatch = m_FontFaces.GetPtrAt(i);
+ if (*pMatch == *pDesc) {
+ return pMatch;
+ }
+ }
+ int index = m_FontFaces.Add(*pDesc);
+ return m_FontFaces.GetPtrAt(index);
+ }
+ return NULL;
+}
+FX_LPCFONTDESCRIPTOR FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams, const CFX_FontDescriptors &fonts, FX_LPVOID pUserData)
+{
+ FX_LPCFONTDESCRIPTOR pBestFont = NULL;
+ FX_INT32 iBestSimilar = 0;
+ FX_BOOL bMatchStyle = (pParams->dwMatchFlags & FX_FONTMATCHPARA_MacthStyle) > 0;
+ FX_INT32 iCount = fonts.GetSize();
+ for (FX_INT32 i = 0; i < iCount; ++i) {
+ FX_LPCFONTDESCRIPTOR pFont = fonts.GetPtrAt(i);
+ if ((pFont->dwFontStyles & FX_FONTSTYLE_BoldItalic) == FX_FONTSTYLE_BoldItalic) {
+ continue;
+ }
+ if (pParams->pwsFamily) {
+ if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace)) {
+ continue;
+ }
+ if (pFont->uCharSet == FX_CHARSET_Symbol) {
+ return pFont;
+ }
+ }
+ if (pFont->uCharSet == FX_CHARSET_Symbol) {
+ continue;
+ }
+ if (pParams->wCodePage != 0xFFFF) {
+ if (FX_GetCodePageFromCharset(pFont->uCharSet) != pParams->wCodePage) {
+ continue;
+ }
+ } else {
+ if (pParams->dwUSB < 128) {
+ FX_DWORD dwByte = pParams->dwUSB / 32;
+ FX_DWORD dwUSB = 1 << (pParams->dwUSB % 32);
+ if ((pFont->FontSignature.fsUsb[dwByte] & dwUSB) == 0) {
+ continue;
+ }
+ }
+ }
+ if (bMatchStyle) {
+ if ((pFont->dwFontStyles & 0x0F) == (pParams->dwFontStyles & 0x0F)) {
+ return pFont;
+ } else {
+ continue;
+ }
+ }
+ if (pParams->pwsFamily != NULL) {
+ if (FXSYS_wcsicmp(pParams->pwsFamily, pFont->wsFontFace) == 0) {
+ return pFont;
+ }
+ }
+ FX_INT32 iSimilarValue = FX_GetSimilarValue(pFont, pParams->dwFontStyles);
+ if (iBestSimilar < iSimilarValue) {
+ iBestSimilar = iSimilarValue;
+ pBestFont = pFont;
+ }
+ }
+ return iBestSimilar < 1 ? NULL : pBestFont;
+}
+FX_INT32 FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles)
+{
+ FX_INT32 iValue = 0;
+ if ((dwFontStyles & FX_FONTSTYLE_Symbolic) == (pFont->dwFontStyles & FX_FONTSTYLE_Symbolic)) {
+ iValue += 64;
+ }
+ if ((dwFontStyles & FX_FONTSTYLE_FixedPitch) == (pFont->dwFontStyles & FX_FONTSTYLE_FixedPitch)) {
+ iValue += 32;
+ }
+ if ((dwFontStyles & FX_FONTSTYLE_Serif) == (pFont->dwFontStyles & FX_FONTSTYLE_Serif)) {
+ iValue += 16;
+ }
+ if ((dwFontStyles & FX_FONTSTYLE_Script) == (pFont->dwFontStyles & FX_FONTSTYLE_Script)) {
+ iValue += 8;
+ }
+ return iValue;
+}
+FX_LPMatchFont FX_GetDefFontMatchor()
+{
+ return FX_DefFontMatcher;
+}
+FX_DWORD FX_GetGdiFontStyles(const LOGFONTW &lf)
+{
+ FX_DWORD dwStyles = 0;
+ if ((lf.lfPitchAndFamily & 0x03) == FIXED_PITCH) {
+ dwStyles |= FX_FONTSTYLE_FixedPitch;
+ }
+ FX_BYTE nFamilies = lf.lfPitchAndFamily & 0xF0;
+ if (nFamilies == FF_ROMAN) {
+ dwStyles |= FX_FONTSTYLE_Serif;
+ }
+ if (nFamilies == FF_SCRIPT) {
+ dwStyles |= FX_FONTSTYLE_Script;
+ }
+ if (lf.lfCharSet == SYMBOL_CHARSET) {
+ dwStyles |= FX_FONTSTYLE_Symbolic;
+ }
+ return dwStyles;
+}
+static FX_INT32 CALLBACK FX_GdiFontEnumProc(ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme, DWORD dwFontType, LPARAM lParam)
+{
+ if (dwFontType != TRUETYPE_FONTTYPE) {
+ return 1;
+ }
+ const LOGFONTW &lf = ((LPENUMLOGFONTEXW)lpelfe)->elfLogFont;
+ if (lf.lfFaceName[0] == L'@') {
+ return 1;
+ }
+ FX_LPFONTDESCRIPTOR pFont = FX_Alloc(FX_FONTDESCRIPTOR, 1);
+ if (NULL == pFont) {
+ return 0;
+ }
+ FXSYS_memset(pFont, 0, sizeof(FX_FONTDESCRIPTOR));
+ pFont->uCharSet = lf.lfCharSet;
+ pFont->dwFontStyles = FX_GetGdiFontStyles(lf);
+ FXSYS_wcsncpy(pFont->wsFontFace, (FX_LPCWSTR)lf.lfFaceName, 31);
+ pFont->wsFontFace[31] = 0;
+ FX_memcpy(&pFont->FontSignature, &lpntme->ntmFontSig, sizeof(lpntme->ntmFontSig));
+ ((CFX_FontDescriptors*)lParam)->Add(*pFont);
+ FX_Free(pFont);
+ return 1;
+}
+static void FX_EnumGdiFonts(CFX_FontDescriptors &fonts, FX_LPVOID pUserData, FX_LPCWSTR pwsFaceName, FX_WCHAR wUnicode)
+{
+ HDC hDC = ::GetDC(NULL);
+ LOGFONTW lfFind;
+ FX_memset(&lfFind, 0, sizeof(lfFind));
+ lfFind.lfCharSet = DEFAULT_CHARSET;
+ if (pwsFaceName) {
+ FXSYS_wcsncpy((FX_LPWSTR)lfFind.lfFaceName, pwsFaceName, 31);
+ lfFind.lfFaceName[31] = 0;
+ }
+ EnumFontFamiliesExW(hDC, (LPLOGFONTW)&lfFind, (FONTENUMPROCW)FX_GdiFontEnumProc, (LPARAM)&fonts, 0);
+ ::ReleaseDC(NULL, hDC);
+}
+FX_LPEnumAllFonts FX_GetDefFontEnumerator()
+{
+ return FX_EnumGdiFonts;
+}
+#else
+FX_LPCSTR g_FontFolders[] = {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
+ (FX_LPCSTR)"/usr/share/fonts",
+ (FX_LPCSTR)"/usr/share/X11/fonts/Type1",
+ (FX_LPCSTR)"/usr/share/X11/fonts/TTF",
+ (FX_LPCSTR)"/usr/local/share/fonts",
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ (FX_LPCSTR)"~/Library/Fonts",
+ (FX_LPCSTR)"/Library/Fonts",
+ (FX_LPCSTR)"/System/Library/Fonts",
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+ (FX_LPCSTR)"/system/fonts",
+#endif
+};
+CFX_FontSourceEnum_File::CFX_FontSourceEnum_File()
+{
+ for (FX_INT32 i = 0; i < sizeof(g_FontFolders) / sizeof(FX_LPCSTR); i++) {
+ m_FolderPaths.Add(g_FontFolders[i]);
+ }
+}
+CFX_ByteString CFX_FontSourceEnum_File::GetNextFile()
+{
+Restart:
+ FX_LPVOID pCurHandle = m_FolderQueue.GetSize() == 0 ? NULL : m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle;
+ if (NULL == pCurHandle) {
+ if (m_FolderPaths.GetSize() < 1) {
+ return "";
+ }
+ pCurHandle = FX_OpenFolder(m_FolderPaths[m_FolderPaths.GetSize() - 1]);
+ FX_HandleParentPath hpp;
+ hpp.pFileHandle = pCurHandle;
+ hpp.bsParentPath = m_FolderPaths[m_FolderPaths.GetSize() - 1];
+ m_FolderQueue.Add(hpp);
+ }
+ CFX_ByteString bsName;
+ FX_BOOL bFolder;
+ CFX_ByteString bsFolderSpearator = CFX_ByteString::FromUnicode(CFX_WideString(FX_GetFolderSeparator()));
+ while (TRUE) {
+ if (!FX_GetNextFile(pCurHandle, bsName, bFolder)) {
+ FX_CloseFolder(pCurHandle);
+ m_FolderQueue.RemoveAt(m_FolderQueue.GetSize() - 1);
+ if (m_FolderQueue.GetSize() == 0) {
+ m_FolderPaths.RemoveAt(m_FolderPaths.GetSize() - 1);
+ if (m_FolderPaths.GetSize() == 0) {
+ return "";
+ } else {
+ goto Restart;
+ }
+ }
+ pCurHandle = m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->pFileHandle;
+ continue;
+ }
+ if (bsName == "." || bsName == "..") {
+ continue;
+ }
+ if (bFolder) {
+ FX_HandleParentPath hpp;
+ hpp.bsParentPath = m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath + bsFolderSpearator + bsName;
+ hpp.pFileHandle = FX_OpenFolder(hpp.bsParentPath);
+ if (hpp.pFileHandle == NULL) {
+ continue;
+ }
+ m_FolderQueue.Add(hpp);
+ pCurHandle = hpp.pFileHandle;
+ continue;
+ }
+ bsName = m_FolderQueue.GetDataPtr(m_FolderQueue.GetSize() - 1)->bsParentPath + bsFolderSpearator + bsName;
+ break;
+ }
+ return bsName;
+}
+FX_POSITION CFX_FontSourceEnum_File::GetStartPosition( FX_LPVOID pUserData )
+{
+ m_wsNext = GetNextFile().UTF8Decode();
+ if (0 == m_wsNext.GetLength()) {
+ return (FX_POSITION)0;
+ }
+ return (FX_POSITION) - 1;
+}
+IFX_FileAccess* CFX_FontSourceEnum_File::GetNext( FX_POSITION& pos, FX_LPVOID pUserData )
+{
+ IFX_FileAccess* pAccess = FX_CreateDefaultFileAccess(m_wsNext);
+ m_wsNext = GetNextFile().UTF8Decode();
+ pos = 0 != m_wsNext.GetLength() ? pAccess : NULL;
+ return (IFX_FileAccess*)pAccess;
+}
+IFX_FontSourceEnum* FX_CreateDefaultFontSourceEnum()
+{
+ return (IFX_FontSourceEnum*)FX_NEW CFX_FontSourceEnum_File;
+}
+IFX_FontMgr* IFX_FontMgr::Create(IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate, FX_LPVOID pUserData)
+{
+ if (NULL == pFontEnum) {
+ return NULL;
+ }
+ CFX_FontMgrImp* pFontMgr = FX_NEW CFX_FontMgrImp(pFontEnum, pDelegate, pUserData);
+ if (NULL == pFontMgr) {
+ return NULL;
+ }
+ if (pFontMgr->EnumFonts()) {
+ return pFontMgr;
+ }
+ delete pFontMgr;
+ return NULL;
+}
+CFX_FontMgrImp::CFX_FontMgrImp( IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate , FX_LPVOID pUserData )
+ : m_pFontSource(pFontEnum)
+ , m_pDelegate(pDelegate)
+ , m_pUserData(pUserData)
+{
+}
+FX_BOOL CFX_FontMgrImp::EnumFonts()
+{
+ FXFT_Library& library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
+ if (library == NULL) {
+ FXFT_Init_FreeType(&library);
+ }
+ if (library == NULL) {
+ return FALSE;
+ }
+ FXFT_Face pFace = NULL;
+ FX_POSITION pos = m_pFontSource->GetStartPosition();
+ IFX_FileAccess* pFontSource = NULL;
+ IFX_FileRead* pFontStream = NULL;
+ while (pos) {
+ pFontSource = m_pFontSource->GetNext(pos);
+ pFontStream = pFontSource->CreateFileStream(FX_FILEMODE_ReadOnly);
+ if (NULL == pFontStream) {
+ pFontSource->Release();
+ continue;
+ }
+ if (NULL == (pFace = LoadFace(pFontStream, 0))) {
+ pFontStream->Release();
+ pFontSource->Release();
+ continue;
+ }
+ FX_INT32 nFaceCount = pFace->num_faces;
+ ReportFace(pFace, m_InstalledFonts, pFontSource);
+ if (FXFT_Get_Face_External_Stream(pFace)) {
+ FXFT_Clear_Face_External_Stream(pFace);
+ }
+ FXFT_Done_Face(pFace);
+ for (FX_INT32 i = 1; i < nFaceCount; i++) {
+ if (NULL == (pFace = LoadFace(pFontStream, i))) {
+ continue;
+ }
+ ReportFace(pFace, m_InstalledFonts, pFontSource);
+ if (FXFT_Get_Face_External_Stream(pFace)) {
+ FXFT_Clear_Face_External_Stream(pFace);
+ }
+ FXFT_Done_Face(pFace);
+ }
+ pFontStream->Release();
+ pFontSource->Release();
+ }
+ return TRUE;
+}
+void CFX_FontMgrImp::Release()
+{
+ for (FX_INT32 i = 0; i < m_InstalledFonts.GetSize(); i++) {
+ delete m_InstalledFonts[i];
+ }
+ FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_FontDescriptorInfos* pDescs;
+ m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
+ if (NULL != pDescs) {
+ delete pDescs;
+ }
+ }
+ pos = m_Hash2Fonts.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_ArrayTemplate<IFX_Font*>* pFonts;
+ m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
+ if (NULL != pFonts) {
+ delete pFonts;
+ }
+ }
+ m_Hash2Fonts.RemoveAll();
+ pos = m_Hash2FileAccess.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_FileAccess* pFileAccess;
+ m_Hash2FileAccess.GetNextAssoc(pos, dwHash, pFileAccess);
+ if (NULL != pFileAccess) {
+ pFileAccess->Release();
+ }
+ }
+ pos = m_FileAccess2IFXFont.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_Font* pFont;
+ m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pFont);
+ if (NULL != pFont) {
+ pFont->Release();
+ }
+ }
+ pos = m_IFXFont2FileRead.GetStartPosition();
+ while (pos) {
+ IFX_Font* pFont;
+ IFX_FileRead* pFileRead;
+ m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
+ pFileRead->Release();
+ }
+ delete this;
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByCodePage( FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByCodePage(this, wCodePage, dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByCharset( FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByCharset(this, nCharset, dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByUnicode( FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByUnicode(this, wUnicode, dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetDefFontByLanguage( FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ return NULL == m_pDelegate ? NULL : m_pDelegate->GetDefFontByLanguage(this, wLanguage, dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetFontByCodePage( FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ CFX_ByteString bsHash;
+ bsHash.Format("%d, %d", wCodePage, dwFontStyles);
+ bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
+ FX_DWORD dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
+ CFX_ArrayTemplate<IFX_Font*>* pFonts = NULL;
+ IFX_Font* pFont = NULL;
+ if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
+ if (NULL == pFonts) {
+ return NULL;
+ }
+ if (0 != pFonts->GetSize()) {
+ return pFonts->GetAt(0)->Retain();
+ }
+ }
+ if (NULL == pFonts) {
+ pFonts = FX_NEW CFX_ArrayTemplate<IFX_Font*>;
+ }
+ if (NULL == pFonts) {
+ return NULL;
+ }
+ m_Hash2Fonts.SetAt(dwHash, pFonts);
+ CFX_FontDescriptorInfos* sortedFonts = NULL;
+ if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
+ sortedFonts = FX_NEW CFX_FontDescriptorInfos;
+ MatchFonts(*sortedFonts, wCodePage, dwFontStyles, CFX_WideString(pszFontFamily), 0);
+ m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
+ }
+ if (sortedFonts->GetSize() == 0) {
+ return NULL;
+ }
+ CFX_FontDescriptor* pDesc = sortedFonts->GetAt(0).pFont;
+ pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, NULL);
+ if (NULL != pFont) {
+ pFont->SetLogicalFontStyle(dwFontStyles);
+ }
+ pFonts->Add(pFont);
+ return pFont;
+}
+IFX_Font* CFX_FontMgrImp::GetFontByCharset( FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ return GetFontByCodePage(FX_GetCodePageFromCharset(nCharset), dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::GetFontByUnicode( FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ IFX_Font* pFont = NULL;
+ if (m_FailedUnicodes2NULL.Lookup(wUnicode, pFont)) {
+ return NULL;
+ }
+ FGAS_LPCFONTUSB x = FGAS_GetUnicodeBitField(wUnicode);
+ FX_WORD wCodePage = NULL == x ? 0xFFFF : x->wCodePage;
+ FX_WORD wBitField = NULL == x ? 999 : x->wBitField;
+ CFX_ByteString bsHash;
+ if (wCodePage == 0xFFFF) {
+ bsHash.Format("%d, %d, %d", wCodePage, wBitField, dwFontStyles);
+ } else {
+ bsHash.Format("%d, %d", wCodePage, dwFontStyles);
+ }
+ bsHash += CFX_WideString(pszFontFamily).UTF8Encode();
+ FX_DWORD dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
+ CFX_ArrayTemplate<IFX_Font*>* pFonts = NULL;
+ if (m_Hash2Fonts.Lookup(dwHash, pFonts)) {
+ if (NULL == pFonts) {
+ return NULL;
+ }
+ if (0 != pFonts->GetSize()) {
+ for (FX_INT32 i = 0; i < pFonts->GetSize(); i++) {
+ if (VerifyUnicode(pFonts->GetAt(i), wUnicode)) {
+ return pFonts->GetAt(i)->Retain();
+ }
+ }
+ }
+ }
+ if (NULL == pFonts) {
+ pFonts = FX_NEW CFX_ArrayTemplate<IFX_Font*>;
+ }
+ if (NULL == pFonts) {
+ return NULL;
+ }
+ m_Hash2Fonts.SetAt(dwHash, pFonts);
+ CFX_FontDescriptorInfos* sortedFonts = NULL;
+ if (!m_Hash2CandidateList.Lookup(dwHash, sortedFonts)) {
+ sortedFonts = FX_NEW CFX_FontDescriptorInfos;
+ MatchFonts(*sortedFonts, wCodePage, dwFontStyles, CFX_WideString(pszFontFamily), wUnicode);
+ m_Hash2CandidateList.SetAt(dwHash, sortedFonts);
+ }
+ for (FX_INT32 i = 0; i < sortedFonts->GetSize(); i++) {
+ CFX_FontDescriptor* pDesc = sortedFonts->GetAt(i).pFont;
+ if (VerifyUnicode(pDesc, wUnicode)) {
+ pFont = LoadFont(pDesc->m_pFileAccess, pDesc->m_nFaceIndex, NULL);
+ if (NULL != pFont) {
+ pFont->SetLogicalFontStyle(dwFontStyles);
+ }
+ pFonts->Add(pFont);
+ return pFont;
+ }
+ }
+ if (NULL == pszFontFamily) {
+ m_FailedUnicodes2NULL.SetAt(wUnicode, NULL);
+ }
+ return NULL;
+}
+FX_BOOL CFX_FontMgrImp::VerifyUnicode( CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode )
+{
+ IFX_FileRead* pFileRead = pDesc->m_pFileAccess->CreateFileStream(FX_FILEMODE_ReadOnly);
+ if (NULL == pFileRead) {
+ return FALSE;
+ }
+ FXFT_Face pFace = LoadFace(pFileRead, pDesc->m_nFaceIndex);
+ if (NULL == pFace) {
+ goto BadRet;
+ }
+ if (0 != FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE)) {
+ goto BadRet;
+ }
+ if (0 == FXFT_Get_Char_Index(pFace, wcUnicode)) {
+ goto BadRet;
+ }
+ pFileRead->Release();
+ if (FXFT_Get_Face_External_Stream(pFace)) {
+ FXFT_Clear_Face_External_Stream(pFace);
+ }
+ FXFT_Done_Face(pFace);
+ return TRUE;
+BadRet:
+ if (NULL != pFileRead) {
+ pFileRead->Release();
+ }
+ if (NULL != pFace) {
+ if (FXFT_Get_Face_External_Stream(pFace)) {
+ FXFT_Clear_Face_External_Stream(pFace);
+ }
+ FXFT_Done_Face(pFace);
+ }
+ return FALSE;
+}
+FX_BOOL CFX_FontMgrImp::VerifyUnicode( IFX_Font* pFont, FX_WCHAR wcUnicode )
+{
+ if (NULL == pFont) {
+ return FALSE;
+ }
+ FXFT_Face pFace = ((CFX_Font*)pFont->GetDevFont())->m_Face;
+ FXFT_CharMap charmap = FXFT_Get_Face_Charmap(pFace);
+ if (0 != FXFT_Select_Charmap(pFace, FXFT_ENCODING_UNICODE)) {
+ return FALSE;
+ }
+ if (0 == FXFT_Get_Char_Index(pFace, wcUnicode)) {
+ FXFT_Set_Charmap(pFace, charmap);
+ return FALSE;
+ }
+ return TRUE;
+}
+IFX_Font* CFX_FontMgrImp::GetFontByLanguage( FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily )
+{
+ return GetFontByCodePage(FX_GetDefCodePageByLanguage(wLanguage), dwFontStyles, pszFontFamily);
+}
+IFX_Font* CFX_FontMgrImp::LoadFont( FX_LPCBYTE pBuffer, FX_INT32 iLength, FX_INT32 iFaceIndex, FX_INT32* pFaceCount )
+{
+ FX_LPVOID Hash[2] = {(FX_LPVOID)(FX_UINTPTR)pBuffer, (FX_LPVOID)(FX_UINTPTR)iLength};
+ FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)Hash, 2 * sizeof (FX_LPVOID));
+ IFX_FileAccess* pFontAccess = NULL;
+ if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
+ }
+ if (NULL != pFontAccess) {
+ return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
+ } else {
+ return NULL;
+ }
+}
+IFX_Font* CFX_FontMgrImp::LoadFont( FX_LPCWSTR pszFileName, FX_INT32 iFaceIndex, FX_INT32* pFaceCount )
+{
+ CFX_ByteString bsHash;
+ bsHash += CFX_WideString(pszFileName).UTF8Encode();
+ FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)bsHash, bsHash.GetLength());
+ IFX_FileAccess* pFontAccess = NULL;
+ if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
+ pFontAccess = FX_CreateDefaultFileAccess(pszFileName);
+ m_Hash2FileAccess.SetAt(dwHash, pFontAccess);
+ }
+ if (NULL != pFontAccess) {
+ return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
+ } else {
+ return NULL;
+ }
+}
+IFX_Font* CFX_FontMgrImp::LoadFont( IFX_Stream* pFontStream, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bSaveStream )
+{
+ FX_LPVOID Hash[1] = {(FX_LPVOID)(FX_UINTPTR)pFontStream};
+ FX_DWORD dwHash = FX_HashCode_String_GetA((FX_LPCSTR)Hash, 1 * sizeof (FX_LPVOID));
+ IFX_FileAccess* pFontAccess = NULL;
+ if (!m_Hash2FileAccess.Lookup(dwHash, pFontAccess)) {
+ }
+ if (NULL != pFontAccess) {
+ return LoadFont(pFontAccess, iFaceIndex, pFaceCount, TRUE);
+ } else {
+ return NULL;
+ }
+}
+IFX_Font* CFX_FontMgrImp::LoadFont( IFX_FileAccess* pFontAccess, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bWantCache )
+{
+ FX_DWORD dwHash = 0;
+ IFX_Font* pFont = NULL;
+ if (bWantCache) {
+ CFX_ByteString bsHash;
+ bsHash.Format("%d, %d", (FX_UINTPTR)pFontAccess, iFaceIndex);
+ dwHash = FX_HashCode_String_GetA(bsHash, bsHash.GetLength());
+ if (m_FileAccess2IFXFont.Lookup(dwHash, pFont)) {
+ if (NULL != pFont) {
+ if (NULL != pFaceCount) {
+ *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->m_Face->num_faces;
+ }
+ return pFont->Retain();
+ }
+ }
+ }
+ CFX_Font* pInternalFont = FX_NEW CFX_Font;
+ if (NULL == pInternalFont) {
+ return NULL;
+ }
+ IFX_FileRead* pFontStream = pFontAccess->CreateFileStream(FX_FILEMODE_ReadOnly);
+ if (NULL == pFontStream) {
+ delete pInternalFont;
+ return NULL;
+ }
+ if (!pInternalFont->LoadFile(pFontStream, iFaceIndex)) {
+ delete pInternalFont;
+ pFontStream->Release();
+ return NULL;
+ }
+ pFont = IFX_Font::LoadFont(pInternalFont, this, TRUE);
+ if (NULL == pFont) {
+ delete pInternalFont;
+ pFontStream->Release();
+ return NULL;
+ }
+ if (bWantCache) {
+ m_FileAccess2IFXFont.SetAt(dwHash, pFont);
+ }
+ m_IFXFont2FileRead.SetAt(pFont, pFontStream);
+ if (NULL != pFaceCount) {
+ *pFaceCount = ((CFX_Font*)pFont->GetDevFont())->m_Face->num_faces;
+ }
+ return pFont;
+}
+extern "C"
+{
+ unsigned long _ftStreamRead(FXFT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count)
+ {
+ if (count == 0) {
+ return 0;
+ }
+ IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
+ int res = pFile->ReadBlock(buffer, offset, count);
+ if (res) {
+ return count;
+ }
+ return 0;
+ }
+ void _ftStreamClose(FXFT_Stream stream)
+ {
+ }
+};
+FXFT_Face CFX_FontMgrImp::LoadFace( IFX_FileRead* pFontStream, FX_INT32 iFaceIndex )
+{
+ FXFT_Library& library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
+ FXFT_Open_Args ftArgs;
+ FXFT_Stream ftStream = FX_Alloc(FXFT_StreamRec, 1);
+ FXFT_Face pFace = NULL;
+ if (library == NULL) {
+ FXFT_Init_FreeType(&library);
+ }
+ if (library == NULL) {
+ goto BadRet;
+ }
+ FXSYS_memset(&ftArgs, 0, sizeof(FXFT_Open_Args));
+ if (NULL == ftStream) {
+ goto BadRet;
+ }
+ FXSYS_memset(ftStream, 0, sizeof(FXFT_StreamRec));
+ if (NULL == pFontStream) {
+ goto BadRet;
+ }
+ ftStream->base = NULL;
+ ftStream->descriptor.pointer = pFontStream;
+ ftStream->pos = 0;
+ ftStream->size = (unsigned long)pFontStream->GetSize();
+ ftStream->read = _ftStreamRead;
+ ftStream->close = _ftStreamClose;
+ ftArgs.flags |= FT_OPEN_STREAM;
+ ftArgs.stream = ftStream;
+ if (0 != FXFT_Open_Face(library, &ftArgs, iFaceIndex, &pFace)) {
+ goto BadRet;
+ }
+ FXFT_Set_Pixel_Sizes(pFace, 0, 64);
+ return pFace;
+BadRet:
+ if (NULL != ftStream) {
+ FX_Free(ftStream);
+ }
+ return NULL;
+}
+FX_INT32 CFX_FontMgrImp::MatchFonts( CFX_FontDescriptorInfos& MatchedFonts, FX_WORD wCodePage, FX_DWORD dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode )
+{
+ MatchedFonts.RemoveAll();
+ CFX_WideString wsNormalizedFontName = FontName;
+ NormalizeFontName(wsNormalizedFontName);
+ static const FX_INT32 nMax = 0xffff;
+ CFX_FontDescriptor* pFont = NULL;
+ FX_INT32 nCount = m_InstalledFonts.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i++) {
+ pFont = m_InstalledFonts[i];
+ FX_INT32 nPenalty = CalcPenalty(pFont, wCodePage, dwFontStyles, wsNormalizedFontName, wcUnicode);
+ if (nPenalty >= 0xFFFF) {
+ continue;
+ }
+ FX_FontDescriptorInfo FontInfo;
+ FontInfo.pFont = pFont;
+ FontInfo.nPenalty = nPenalty;
+ MatchedFonts.Add(FontInfo);
+ if (MatchedFonts.GetSize() == nMax) {
+ break;
+ }
+ }
+ if (MatchedFonts.GetSize() == 0) {
+ return 0;
+ }
+ CFX_SSortTemplate<FX_FontDescriptorInfo> ssort;
+ ssort.ShellSort(MatchedFonts.GetData(), MatchedFonts.GetSize());
+ return MatchedFonts.GetSize();
+}
+struct FX_BitCodePage {
+ FX_WORD wBit;
+ FX_WORD wCodePage;
+};
+static const FX_BitCodePage g_Bit2CodePage[] = {
+ {0, 1252},
+ {1, 1250},
+ {2, 1251},
+ {3, 1253},
+ {4, 1254},
+ {5, 1255},
+ {6, 1256},
+ {7, 1257},
+ {8, 1258},
+ {9, 0},
+ {10, 0},
+ {11, 0},
+ {12, 0},
+ {13, 0},
+ {14, 0},
+ {15, 0},
+ {16, 874},
+ {17, 932},
+ {18, 936},
+ {19, 949},
+ {20, 950},
+ {21, 1361},
+ {22, 0},
+ {23, 0},
+ {24, 0},
+ {25, 0},
+ {26, 0},
+ {27, 0},
+ {28, 0},
+ {29, 0},
+ {30, 0},
+ {31, 0},
+ {32, 0},
+ {33, 0},
+ {34, 0},
+ {35, 0},
+ {36, 0},
+ {37, 0},
+ {38, 0},
+ {39, 0},
+ {40, 0},
+ {41, 0},
+ {42, 0},
+ {43, 0},
+ {44, 0},
+ {45, 0},
+ {46, 0},
+ {47, 0},
+ {48, 869},
+ {49, 866},
+ {50, 865},
+ {51, 864},
+ {52, 863},
+ {53, 862},
+ {54, 861},
+ {55, 860},
+ {56, 857},
+ {57, 855},
+ {58, 852},
+ {59, 775},
+ {60, 737},
+ {61, 708},
+ {62, 850},
+ {63, 437},
+};
+FX_WORD FX_GetCodePageBit(FX_WORD wCodePage)
+{
+ for (FX_INT32 i = 0; i < sizeof(g_Bit2CodePage) / sizeof (FX_BitCodePage); i++) {
+ if (g_Bit2CodePage[i].wCodePage == wCodePage) {
+ return g_Bit2CodePage[i].wBit;
+ }
+ }
+ return (FX_WORD) - 1;
+}
+FX_WORD FX_GetUnicodeBit(FX_WCHAR wcUnicode)
+{
+ FGAS_LPCFONTUSB x = FGAS_GetUnicodeBitField(wcUnicode);
+ if (NULL == x) {
+ return 999;
+ }
+ return x->wBitField;
+}
+FX_INT32 CFX_FontMgrImp::CalcPenalty( CFX_FontDescriptor* pInstalled, FX_WORD wCodePage, FX_DWORD dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode )
+{
+ FX_INT32 nPenalty = 30000;
+ if (0 != FontName.GetLength()) {
+ if (FontName != pInstalled->m_wsFaceName) {
+ FX_INT32 i;
+ for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
+ if (pInstalled->m_wsFamilyNames[i] == FontName) {
+ break;
+ }
+ }
+ if (i == pInstalled->m_wsFamilyNames.GetSize()) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 28000;
+ }
+ } else {
+ nPenalty -= 30000;
+ }
+ if (30000 == nPenalty && 0 == IsPartName(pInstalled->m_wsFaceName, FontName)) {
+ FX_INT32 i;
+ for (i = 0; i < pInstalled->m_wsFamilyNames.GetSize(); i++) {
+ if (0 != IsPartName(pInstalled->m_wsFamilyNames[i], FontName)) {
+ break;
+ }
+ }
+ if (i == pInstalled->m_wsFamilyNames.GetSize()) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 26000;
+ }
+ } else {
+ nPenalty -= 27000;
+ }
+ }
+ FX_DWORD dwStyleMask = pInstalled->m_dwFontStyles ^ dwFontStyles;
+ if (dwStyleMask & FX_FONTSTYLE_Bold) {
+ nPenalty += 4500;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_FixedPitch) {
+ nPenalty += 10000;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_Italic) {
+ nPenalty += 10000;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_Serif) {
+ nPenalty += 500;
+ }
+ if (dwStyleMask & FX_FONTSTYLE_Symbolic) {
+ nPenalty += 0xFFFF;
+ }
+ if (nPenalty >= 0xFFFF) {
+ return 0xFFFF;
+ }
+ FX_WORD wBit = ((0 == wCodePage || 0xFFFF == wCodePage) ? (FX_WORD) - 1 : FX_GetCodePageBit(wCodePage));
+ if (wBit != (FX_WORD) - 1) {
+ FXSYS_assert(wBit < 64);
+ if (0 == (pInstalled->m_dwCsb[wBit / 32] & (1 << (wBit % 32)))) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 60000;
+ }
+ }
+ wBit = ((0 == wcUnicode || 0xFFFE == wcUnicode) ? (FX_WORD)999 : FX_GetUnicodeBit(wcUnicode));
+ if (wBit != (FX_WORD)999) {
+ FXSYS_assert(wBit < 128);
+ if (0 == (pInstalled->m_dwUsb[wBit / 32] & (1 << (wBit % 32)))) {
+ nPenalty += 0xFFFF;
+ } else {
+ nPenalty -= 60000;
+ }
+ }
+ return nPenalty;
+}
+void CFX_FontMgrImp::ClearFontCache()
+{
+ FX_POSITION pos = m_Hash2CandidateList.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_FontDescriptorInfos* pDescs;
+ m_Hash2CandidateList.GetNextAssoc(pos, dwHash, pDescs);
+ if (NULL != pDescs) {
+ delete pDescs;
+ }
+ }
+ pos = m_FileAccess2IFXFont.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_Font* pFont;
+ m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pFont);
+ if (NULL != pFont) {
+ pFont->Release();
+ }
+ }
+ pos = m_IFXFont2FileRead.GetStartPosition();
+ while (pos) {
+ IFX_Font* pFont;
+ IFX_FileRead* pFileRead;
+ m_IFXFont2FileRead.GetNextAssoc(pos, pFont, pFileRead);
+ pFileRead->Release();
+ }
+}
+void CFX_FontMgrImp::RemoveFont( IFX_Font* pEFont )
+{
+ if (NULL == pEFont) {
+ return ;
+ }
+ IFX_FileRead* pFileRead;
+ if (m_IFXFont2FileRead.Lookup(pEFont, pFileRead)) {
+ pFileRead->Release();
+ m_IFXFont2FileRead.RemoveKey(pEFont);
+ }
+ FX_POSITION pos;
+ pos = m_FileAccess2IFXFont.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ IFX_Font* pCFont;
+ m_FileAccess2IFXFont.GetNextAssoc(pos, dwHash, pCFont);
+ if (pCFont == pEFont) {
+ m_FileAccess2IFXFont.RemoveKey(dwHash);
+ break;
+ }
+ }
+ pos = m_Hash2Fonts.GetStartPosition();
+ while (pos) {
+ FX_DWORD dwHash;
+ CFX_ArrayTemplate<IFX_Font*>* pFonts;
+ m_Hash2Fonts.GetNextAssoc(pos, dwHash, pFonts);
+ if (NULL != pFonts) {
+ for (FX_INT32 i = 0; i < pFonts->GetSize(); i++) {
+ if (pFonts->GetAt(i) == pEFont) {
+ pFonts->SetAt(i, NULL);
+ }
+ }
+ } else {
+ m_Hash2Fonts.RemoveKey(dwHash);
+ }
+ }
+}
+void CFX_FontMgrImp::ReportFace( FXFT_Face pFace, CFX_FontDescriptors& Fonts, IFX_FileAccess* pFontAccess)
+{
+ if (0 == (pFace->face_flags & FT_FACE_FLAG_SCALABLE)) {
+ return ;
+ }
+ CFX_FontDescriptor* pFont = FX_NEW CFX_FontDescriptor;
+ if (NULL == pFont) {
+ return;
+ }
+ pFont->m_dwFontStyles |= FXFT_Is_Face_Bold(pFace) ? FX_FONTSTYLE_Bold : 0;
+ pFont->m_dwFontStyles |= FXFT_Is_Face_Italic(pFace) ? FX_FONTSTYLE_Italic : 0;
+ pFont->m_dwFontStyles |= GetFlags(pFace);
+ CFX_WordArray Charsets;
+ GetCharsets(pFace, Charsets);
+ GetUSBCSB(pFace, pFont->m_dwUsb, pFont->m_dwCsb);
+ unsigned long nLength = 0;
+ FT_ULong dwTag;
+ FX_LPBYTE pTable = NULL;
+ FT_ENC_TAG(dwTag, 'n', 'a', 'm', 'e');
+ unsigned int error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, NULL, &nLength);
+ if (0 == error && 0 != nLength) {
+ pTable = FX_Alloc(FX_BYTE, nLength);
+ if (NULL != pTable) {
+ error = FXFT_Load_Sfnt_Table(pFace, dwTag, 0, pTable, NULL);
+ if (0 != error) {
+ FX_Free(pTable);
+ pTable = NULL;
+ }
+ }
+ }
+ GetNames(pTable, pFont->m_wsFamilyNames);
+ if (NULL != pTable) {
+ FX_Free(pTable);
+ }
+ pFont->m_wsFamilyNames.Add(CFX_ByteString(pFace->family_name).UTF8Decode());
+ pFont->m_wsFaceName = CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(pFace));
+ pFont->m_nFaceIndex = pFace->face_index;
+ pFont->m_pFileAccess = pFontAccess->Retain();
+ NormalizeFontName(pFont->m_wsFaceName);
+ for (FX_INT32 i = 0; i < pFont->m_wsFamilyNames.GetSize(); i++) {
+ NormalizeFontName(pFont->m_wsFamilyNames[i]);
+ }
+ Fonts.Add(pFont);
+}
+FX_DWORD CFX_FontMgrImp::GetFlags(FXFT_Face pFace)
+{
+ FX_DWORD flag = 0;
+ if (FT_IS_FIXED_WIDTH(pFace)) {
+ flag |= FX_FONTSTYLE_FixedPitch;
+ }
+ TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
+ if (!pOS2) {
+ return flag;
+ }
+ if (pOS2->ulCodePageRange1 & (1 << 31)) {
+ flag |= FX_FONTSTYLE_Symbolic;
+ }
+ if (pOS2->panose[0] == 2) {
+ FX_BYTE uSerif = pOS2->panose[1];
+ if ((uSerif > 1 && uSerif < 10) || uSerif > 13) {
+ flag |= FX_FONTSTYLE_Serif;
+ }
+ }
+ return flag;
+}
+#define GetUInt8(p) ((FX_UINT8)((p)[0]))
+#define GetUInt16(p) ((FX_UINT16)((p)[0] << 8 | (p)[1]))
+#define GetUInt32(p) ((FX_UINT32)((p)[0] << 24 | (p)[1] << 16 | (p)[2] << 8 | (p)[3]))
+void CFX_FontMgrImp::GetNames(FX_LPCBYTE name_table, CFX_WideStringArray& Names)
+{
+ if (NULL == name_table) {
+ return;
+ }
+ FX_LPBYTE lpTable = (FX_LPBYTE)name_table;
+ CFX_WideString wsFamily;
+ FX_LPBYTE sp = lpTable + 2;
+ FX_LPBYTE lpNameRecord = lpTable + 6;
+ FX_UINT16 nNameCount = GetUInt16(sp);
+ FX_LPBYTE lpStr = lpTable + GetUInt16(sp + 2);
+ for (FX_UINT16 j = 0; j < nNameCount; j++) {
+ FX_UINT16 nNameID = GetUInt16(lpNameRecord + j * 12 + 6);
+ if (nNameID != 1) {
+ continue;
+ }
+ FX_UINT16 nPlatformID = GetUInt16(lpNameRecord + j * 12 + 0);
+ FX_UINT16 nNameLength = GetUInt16(lpNameRecord + j * 12 + 8);
+ FX_UINT16 nNameOffset = GetUInt16(lpNameRecord + j * 12 + 10);
+ wsFamily.Empty();
+ if (nPlatformID != 1) {
+ for (FX_UINT16 k = 0; k < nNameLength / 2; k++) {
+ FX_WCHAR wcTemp = GetUInt16(lpStr + nNameOffset + k * 2);
+ wsFamily += wcTemp;
+ }
+ Names.Add(wsFamily);
+ } else {
+ for (FX_UINT16 k = 0; k < nNameLength; k++) {
+ FX_WCHAR wcTemp = GetUInt8(lpStr + nNameOffset + k);
+ wsFamily += wcTemp;
+ }
+ Names.Add(wsFamily);
+ }
+ }
+}
+#undef GetUInt8
+#undef GetUInt16
+#undef GetUInt32
+struct FX_BIT2CHARSET {
+ FX_WORD wBit;
+ FX_WORD wCharset;
+};
+FX_BIT2CHARSET g_FX_Bit2Charset1[16] = {
+ {1 << 0 , FX_CHARSET_ANSI},
+ {1 << 1 , FX_CHARSET_MSWin_EasterEuropean},
+ {1 << 2 , FX_CHARSET_MSWin_Cyrillic},
+ {1 << 3 , FX_CHARSET_MSWin_Greek},
+ {1 << 4 , FX_CHARSET_MSWin_Turkish},
+ {1 << 5 , FX_CHARSET_MSWin_Hebrew},
+ {1 << 6 , FX_CHARSET_MSWin_Arabic},
+ {1 << 7 , FX_CHARSET_MSWin_Baltic},
+ {1 << 8 , FX_CHARSET_MSWin_Vietnamese},
+ {1 << 9 , FX_CHARSET_Default},
+ {1 << 10 , FX_CHARSET_Default},
+ {1 << 11 , FX_CHARSET_Default},
+ {1 << 12 , FX_CHARSET_Default},
+ {1 << 13 , FX_CHARSET_Default},
+ {1 << 14 , FX_CHARSET_Default},
+ {1 << 15 , FX_CHARSET_Default},
+};
+FX_BIT2CHARSET g_FX_Bit2Charset2[16] = {
+ {1 << 0 , FX_CHARSET_Thai},
+ {1 << 1 , FX_CHARSET_ShiftJIS},
+ {1 << 2 , FX_CHARSET_ChineseSimplified},
+ {1 << 3 , FX_CHARSET_Korean},
+ {1 << 4 , FX_CHARSET_ChineseTriditional},
+ {1 << 5 , FX_CHARSET_Johab},
+ {1 << 6 , FX_CHARSET_Default},
+ {1 << 7 , FX_CHARSET_Default},
+ {1 << 8 , FX_CHARSET_Default},
+ {1 << 9 , FX_CHARSET_Default},
+ {1 << 10 , FX_CHARSET_Default},
+ {1 << 11 , FX_CHARSET_Default},
+ {1 << 12 , FX_CHARSET_Default},
+ {1 << 13 , FX_CHARSET_Default},
+ {1 << 14 , FX_CHARSET_OEM},
+ {1 << 15 , FX_CHARSET_Symbol},
+};
+FX_BIT2CHARSET g_FX_Bit2Charset3[16] = {
+ {1 << 0 , FX_CHARSET_Default},
+ {1 << 1 , FX_CHARSET_Default},
+ {1 << 2 , FX_CHARSET_Default},
+ {1 << 3 , FX_CHARSET_Default},
+ {1 << 4 , FX_CHARSET_Default},
+ {1 << 5 , FX_CHARSET_Default},
+ {1 << 6 , FX_CHARSET_Default},
+ {1 << 7 , FX_CHARSET_Default},
+ {1 << 8 , FX_CHARSET_Default},
+ {1 << 9 , FX_CHARSET_Default},
+ {1 << 10 , FX_CHARSET_Default},
+ {1 << 11 , FX_CHARSET_Default},
+ {1 << 12 , FX_CHARSET_Default},
+ {1 << 13 , FX_CHARSET_Default},
+ {1 << 14 , FX_CHARSET_Default},
+ {1 << 15 , FX_CHARSET_Default},
+};
+FX_BIT2CHARSET g_FX_Bit2Charset4[16] = {
+ {1 << 0 , FX_CHARSET_Default },
+ {1 << 1 , FX_CHARSET_Default },
+ {1 << 2 , FX_CHARSET_Default },
+ {1 << 3 , FX_CHARSET_Default },
+ {1 << 4 , FX_CHARSET_Default },
+ {1 << 5 , FX_CHARSET_Default },
+ {1 << 6 , FX_CHARSET_Default },
+ {1 << 7 , FX_CHARSET_Default },
+ {1 << 8 , FX_CHARSET_Default },
+ {1 << 9 , FX_CHARSET_Default },
+ {1 << 10 , FX_CHARSET_Default },
+ {1 << 11 , FX_CHARSET_Default },
+ {1 << 12 , FX_CHARSET_Default },
+ {1 << 13 , FX_CHARSET_Default },
+ {1 << 14 , FX_CHARSET_Default },
+ {1 << 15 , FX_CHARSET_US },
+};
+#define CODEPAGERANGE_IMPLEMENT(n) \
+ for (FX_INT32 i = 0; i < 16; i++)\
+ {\
+ if ((a##n & g_FX_Bit2Charset##n[i].wBit) != 0)\
+ {\
+ Charsets.Add(g_FX_Bit2Charset##n[i].wCharset);\
+ }\
+ }
+void CFX_FontMgrImp::GetCharsets( FXFT_Face pFace, CFX_WordArray& Charsets )
+{
+ Charsets.RemoveAll();
+ TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
+ if (NULL != pOS2) {
+ FX_WORD a1, a2, a3, a4;
+ a1 = pOS2->ulCodePageRange1 & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(1);
+ a2 = (pOS2->ulCodePageRange1 >> 16) & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(2);
+ a3 = pOS2->ulCodePageRange2 & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(3);
+ a4 = (pOS2->ulCodePageRange2 >> 16) & 0x0000ffff;
+ CODEPAGERANGE_IMPLEMENT(4);
+ } else {
+ Charsets.Add(FX_CHARSET_Default);
+ }
+}
+#undef CODEPAGERANGE_IMPLEMENT
+void CFX_FontMgrImp::GetUSBCSB( FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB )
+{
+ TT_OS2* pOS2 = (TT_OS2*)FT_Get_Sfnt_Table(pFace, ft_sfnt_os2);
+ if (NULL != pOS2) {
+ USB[0] = pOS2->ulUnicodeRange1;
+ USB[1] = pOS2->ulUnicodeRange2;
+ USB[2] = pOS2->ulUnicodeRange3;
+ USB[3] = pOS2->ulUnicodeRange4;
+ CSB[0] = pOS2->ulCodePageRange1;
+ CSB[1] = pOS2->ulCodePageRange2;
+ } else {
+ USB[0] = 0;
+ USB[1] = 0;
+ USB[2] = 0;
+ USB[3] = 0;
+ CSB[0] = 0;
+ CSB[1] = 0;
+ }
+}
+void CFX_FontMgrImp::NormalizeFontName( CFX_WideString& FontName )
+{
+ FontName.MakeLower();
+ FontName.Remove(' ');
+ FontName.Remove('-');
+}
+FX_INT32 CFX_FontMgrImp::IsPartName( const CFX_WideString& Name1, const CFX_WideString& Name2 )
+{
+ if (Name1.Find((FX_LPCWSTR)Name2) != -1) {
+ return 1;
+ }
+ return 0;
+}
+#endif
diff --git a/xfa/src/fgas/src/font/fx_stdfontmgr.h b/xfa/src/fgas/src/font/fx_stdfontmgr.h
new file mode 100644
index 0000000000..adcc737ca5
--- /dev/null
+++ b/xfa/src/fgas/src/font/fx_stdfontmgr.h
@@ -0,0 +1,175 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_FONTMGR_IMP
+#define _FX_FONTMGR_IMP
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+FX_INT32 FX_GetSimilarValue(FX_LPCFONTDESCRIPTOR pFont, FX_DWORD dwFontStyles);
+FX_LPCFONTDESCRIPTOR FX_DefFontMatcher(FX_LPFONTMATCHPARAMS pParams, const CFX_FontDescriptors &fonts, FX_LPVOID pUserData);
+class CFX_StdFontMgrImp : public IFX_FontMgr, public CFX_Object
+{
+public:
+ CFX_StdFontMgrImp(FX_LPEnumAllFonts pEnumerator, FX_LPMatchFont pMatcher, FX_LPVOID pUserData);
+ ~CFX_StdFontMgrImp();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* LoadFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF);
+ virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength);
+ virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName);
+ virtual IFX_Font* LoadFont(IFX_Stream *pFontStream, FX_LPCWSTR pszFontAlias = NULL, FX_DWORD dwFontStyles = 0, FX_WORD wCodePage = 0, FX_BOOL bSaveStream = FALSE);
+ virtual IFX_Font* LoadFont(IFX_Font *pSrcFont, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF);
+ virtual void ClearFontCache();
+ virtual void RemoveFont(IFX_Font *pFont);
+protected:
+ FX_LPMatchFont m_pMatcher;
+ FX_LPEnumAllFonts m_pEnumerator;
+ CFX_FontDescriptors m_FontFaces;
+ CFX_PtrArray m_Fonts;
+ CFX_MapPtrToPtr m_CPFonts;
+ CFX_MapPtrToPtr m_FamilyFonts;
+ CFX_MapPtrToPtr m_UnicodeFonts;
+ CFX_MapPtrToPtr m_BufferFonts;
+ CFX_MapPtrToPtr m_FileFonts;
+ CFX_MapPtrToPtr m_StreamFonts;
+ CFX_MapPtrToPtr m_DeriveFonts;
+ FX_LPVOID m_pUserData;
+ void RemoveFont(CFX_MapPtrToPtr &fontMap, IFX_Font *pFont);
+ FX_LPCFONTDESCRIPTOR FindFont(FX_LPCWSTR pszFontFamily, FX_DWORD dwFontStyles, FX_DWORD dwMatchFlags, FX_WORD wCodePage, FX_DWORD dwUSB = 999, FX_WCHAR wUnicode = 0);
+ IFX_Font* GetFont(FX_LPCFONTDESCRIPTOR pFD, FX_DWORD dwFontStyles);
+};
+FX_DWORD FX_GetGdiFontStyles(const LOGFONTW &lf);
+#else
+class CFX_FontDescriptor : public CFX_Object
+{
+public:
+ CFX_FontDescriptor()
+ : m_pFileAccess(NULL)
+ , m_nFaceIndex(0)
+ , m_dwFontStyles(0)
+ {
+ m_dwUsb[0] = m_dwUsb[1] = m_dwUsb[2] = m_dwUsb[3] = 0;
+ m_dwCsb[0] = m_dwCsb[1] = 0;
+ }
+ ~CFX_FontDescriptor()
+ {
+ if (NULL != m_pFileAccess) {
+ m_pFileAccess->Release();
+ }
+ }
+ IFX_FileAccess* m_pFileAccess;
+ FX_INT32 m_nFaceIndex;
+ CFX_WideString m_wsFaceName;
+ CFX_WideStringArray m_wsFamilyNames;
+ FX_DWORD m_dwFontStyles;
+ FX_DWORD m_dwUsb[4];
+ FX_DWORD m_dwCsb[2];
+};
+typedef CFX_ArrayTemplate<CFX_FontDescriptor*> CFX_FontDescriptors;
+struct FX_FontDescriptorInfo {
+public:
+ CFX_FontDescriptor* pFont;
+ FX_INT32 nPenalty;
+ FX_BOOL operator > (const FX_FontDescriptorInfo& x)
+ {
+ return this->nPenalty > x.nPenalty;
+ };
+ FX_BOOL operator < (const FX_FontDescriptorInfo& x)
+ {
+ return this->nPenalty < x.nPenalty;
+ };
+ FX_BOOL operator == (const FX_FontDescriptorInfo& x)
+ {
+ return this->nPenalty == x.nPenalty;
+ };
+};
+typedef CFX_ArrayTemplate<FX_FontDescriptorInfo> CFX_FontDescriptorInfos;
+struct FX_HandleParentPath : public CFX_Object {
+ FX_HandleParentPath()
+ {
+ }
+ FX_HandleParentPath(const FX_HandleParentPath& x)
+ {
+ pFileHandle = x.pFileHandle;
+ bsParentPath = x.bsParentPath;
+ }
+ void* pFileHandle;
+ CFX_ByteString bsParentPath;
+};
+class CFX_FontSourceEnum_File : public IFX_FontSourceEnum, public CFX_Object
+{
+public:
+ CFX_FontSourceEnum_File();
+ virtual void Release()
+ {
+ delete this;
+ };
+ virtual FX_POSITION GetStartPosition(FX_LPVOID pUserData = NULL);
+ virtual IFX_FileAccess* GetNext(FX_POSITION& pos, FX_LPVOID pUserData = NULL);
+private:
+ CFX_ByteString GetNextFile();
+ CFX_WideString m_wsNext;
+ CFX_ObjectArray<FX_HandleParentPath> m_FolderQueue;
+ CFX_ByteStringArray m_FolderPaths;
+};
+typedef CFX_MapPtrTemplate<FX_DWORD, IFX_FileAccess*> CFX_HashFileMap;
+typedef CFX_MapPtrTemplate<FX_DWORD, IFX_Font*> CFX_HashFontMap;
+typedef CFX_MapPtrTemplate<FX_DWORD, CFX_FontDescriptorInfos*> CFX_HashFontDescsMap;
+typedef CFX_MapPtrTemplate<FX_DWORD, CFX_ArrayTemplate<IFX_Font*>* > CFX_HashFontsMap;
+typedef CFX_MapPtrTemplate<FX_WCHAR, IFX_Font*> CFX_UnicodeFontMap;
+typedef CFX_MapPtrTemplate<IFX_FileAccess*, CFX_ArrayTemplate<IFX_Font*>* > CFX_FileFontMap;
+typedef CFX_MapPtrTemplate<IFX_Font*, IFX_FileRead*> CFX_FonStreamtMap;
+class CFX_FontMgrImp : public IFX_FontMgr, public CFX_Object
+{
+public:
+ CFX_FontMgrImp(IFX_FontSourceEnum* pFontEnum, IFX_FontMgrDelegate* pDelegate = NULL, FX_LPVOID pUserData = NULL);
+ virtual void Release();
+ virtual IFX_Font* GetDefFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetDefFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByCodePage(FX_WORD wCodePage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByCharset(FX_BYTE nCharset, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByUnicode(FX_WCHAR wUnicode, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* GetFontByLanguage(FX_WORD wLanguage, FX_DWORD dwFontStyles, FX_LPCWSTR pszFontFamily = NULL);
+ virtual IFX_Font* LoadFont(FX_LPCBYTE pBuffer, FX_INT32 iLength, FX_INT32 iFaceIndex, FX_INT32* pFaceCount);
+ virtual IFX_Font* LoadFont(FX_LPCWSTR pszFileName, FX_INT32 iFaceIndex, FX_INT32* pFaceCount);
+ virtual IFX_Font* LoadFont(IFX_Stream* pFontStream, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bSaveStream = FALSE);
+ virtual void ClearFontCache();
+ virtual void RemoveFont(IFX_Font* pFont);
+ FX_BOOL EnumFonts();
+protected:
+ void ReportFace(FXFT_Face pFace, CFX_FontDescriptors& Fonts, IFX_FileAccess* pFontAccess);
+ void GetNames(FX_LPCBYTE name_table, CFX_WideStringArray& Names);
+ void GetCharsets(FXFT_Face pFace, CFX_WordArray& Charsets);
+ void GetUSBCSB(FXFT_Face pFace, FX_DWORD* USB, FX_DWORD* CSB);
+ FX_DWORD GetFlags(FXFT_Face pFace);
+ CFX_FontDescriptors m_InstalledFonts;
+ FX_BOOL VerifyUnicode(CFX_FontDescriptor* pDesc, FX_WCHAR wcUnicode);
+ FX_BOOL VerifyUnicode(IFX_Font* pFont, FX_WCHAR wcUnicode);
+ void NormalizeFontName( CFX_WideString& FontName );
+ FX_INT32 IsPartName(const CFX_WideString& Name1, const CFX_WideString& Name2);
+ FX_INT32 MatchFonts(CFX_FontDescriptorInfos& MatchedFonts, FX_WORD wCodePage, FX_DWORD dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode = 0xFFFE);
+ FX_INT32 CalcPenalty(CFX_FontDescriptor* pInstalled, FX_WORD wCodePage, FX_DWORD dwFontStyles, const CFX_WideString& FontName, FX_WCHAR wcUnicode = 0xFFFE);
+ IFX_Font* LoadFont(IFX_FileAccess* pFontAccess, FX_INT32 iFaceIndex, FX_INT32* pFaceCount, FX_BOOL bWantCache = FALSE);
+ FXFT_Face LoadFace(IFX_FileRead* pFontStream, FX_INT32 iFaceIndex);
+ CFX_HashFontDescsMap m_Hash2CandidateList;
+ CFX_HashFontsMap m_Hash2Fonts;
+ CFX_HashFileMap m_Hash2FileAccess;
+ CFX_HashFontMap m_FileAccess2IFXFont;
+ CFX_FonStreamtMap m_IFXFont2FileRead;
+ CFX_UnicodeFontMap m_FailedUnicodes2NULL;
+ IFX_FontSourceEnum* m_pFontSource;
+ IFX_FontMgrDelegate* m_pDelegate;
+ FX_LPVOID m_pUserData;
+};
+#endif
+#endif
diff --git a/xfa/src/fgas/src/layout/fx_linebreak.cpp b/xfa/src/fgas/src/layout/fx_linebreak.cpp
new file mode 100644
index 0000000000..4662e1c122
--- /dev/null
+++ b/xfa/src/fgas/src/layout/fx_linebreak.cpp
@@ -0,0 +1,121 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
+extern const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32] = {
+ {FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBCP, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBPB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBIB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBDB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBPB, FX_LBDB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBDB, FX_LBPB, FX_LBIB, FX_LBDB, FX_LBIB, FX_LBPB, FX_LBPB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBIB, FX_LBIB, FX_LBDB, FX_LBDB, FX_LBPB, FX_LBCB, FX_LBPB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBDB, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+ {FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN, FX_LBUN},
+};
+void FX_GetLineBreakPositions(FX_LPCWSTR pwsText, FX_LINEBREAKTYPE *pBrkType, FX_INT32 iLength)
+{
+ if (iLength < 2) {
+ return;
+ }
+ FX_DWORD dwCur, dwNext;
+ FX_WCHAR wch;
+ wch = *pwsText ++;
+ dwCur = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & 0x003F;
+ iLength --;
+ for (FX_INT32 i = 0; i < iLength; i ++) {
+ wch = *pwsText ++;
+ dwNext = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & 0x003F;
+ if (dwNext == FX_CBP_SP) {
+ pBrkType[i] = FX_LBT_PROHIBITED_BRK;
+ } else {
+ pBrkType[i] = *((const FX_LINEBREAKTYPE *)gs_FX_LineBreak_PairTable + (dwCur << 5) + dwNext);
+ }
+ dwCur = dwNext;
+ }
+ pBrkType[iLength] = FX_LBT_INDIRECT_BRK;
+}
+void FX_GetLineBreakPositions(FX_LPCWSTR pwsText, FX_INT32 iLength, CFX_Int32MassArray &bp)
+{
+ if (iLength < 2) {
+ return;
+ }
+ FX_LINEBREAKTYPE eType;
+ FX_DWORD dwCur, dwNext;
+ FX_WCHAR wch;
+ wch = *pwsText ++;
+ dwCur = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & 0x003F;
+ iLength --;
+ for (FX_INT32 i = 0; i < iLength; i ++) {
+ wch = *pwsText ++;
+ dwNext = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch] & 0x003F;
+ if (dwNext == FX_CBP_SP) {
+ eType = FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE *)gs_FX_LineBreak_PairTable + (dwCur << 5) + dwNext);
+ }
+ if (eType == FX_LBT_DIRECT_BRK) {
+ bp.Add(i);
+ }
+ dwCur = dwNext;
+ }
+}
diff --git a/xfa/src/fgas/src/layout/fx_rtfbreak.cpp b/xfa/src/fgas/src/layout/fx_rtfbreak.cpp
new file mode 100644
index 0000000000..24c64c453b
--- /dev/null
+++ b/xfa/src/fgas/src/layout/fx_rtfbreak.cpp
@@ -0,0 +1,1522 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_unicode.h"
+#include "fx_rtfbreak.h"
+extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
+extern const FX_WCHAR gs_FX_TextLayout_VerticalMirror[64];
+extern const FX_WCHAR gs_FX_TextLayout_BidiMirror[512];
+extern const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32];
+IFX_RTFBreak* IFX_RTFBreak::Create(FX_DWORD dwPolicies)
+{
+ return FX_NEW CFX_RTFBreak(dwPolicies);
+}
+CFX_RTFBreak::CFX_RTFBreak(FX_DWORD dwPolicies)
+ : m_dwPolicies(dwPolicies)
+ , m_pArabicChar(NULL)
+ , m_iLineStart(0)
+ , m_iLineEnd(2000000)
+ , m_dwLayoutStyles(0)
+ , m_bPagination(FALSE)
+ , m_bVertical(FALSE)
+ , m_bSingleLine(FALSE)
+ , m_bCharCode(FALSE)
+ , m_pFont(NULL)
+ , m_iFontHeight(240)
+ , m_iFontSize(240)
+ , m_iTabWidth(720000)
+ , m_PositionedTabs()
+ , m_bOrphanLine(FALSE)
+ , m_wDefChar(0xFEFF)
+ , m_iDefChar(0)
+ , m_wLineBreakChar(L'\n')
+ , m_iHorizontalScale(100)
+ , m_iVerticalScale(100)
+ , m_iLineRotation(0)
+ , m_iCharRotation(0)
+ , m_iRotation(0)
+ , m_iCharSpace(0)
+ , m_bWordSpace(FALSE)
+ , m_iWordSpace(0)
+ , m_bRTL(FALSE)
+ , m_iAlignment(FX_RTFLINEALIGNMENT_Left)
+ , m_pUserData(NULL)
+ , m_dwCharType(0)
+ , m_dwIdentity(0)
+ , m_RTFLine1()
+ , m_RTFLine2()
+ , m_pCurLine(NULL)
+ , m_iReady(0)
+ , m_iTolerance(0)
+{
+ m_pArabicChar = IFX_ArabicChar::Create();
+ m_pCurLine = &m_RTFLine1;
+}
+CFX_RTFBreak::~CFX_RTFBreak()
+{
+ Reset();
+ m_PositionedTabs.RemoveAll();
+ m_pArabicChar->Release();
+ if (m_pUserData != NULL) {
+ m_pUserData->Release();
+ }
+}
+void CFX_RTFBreak::SetLineWidth(FX_FLOAT fLineStart, FX_FLOAT fLineEnd)
+{
+ m_iLineStart = FXSYS_round(fLineStart * 20000.0f);
+ m_iLineEnd = FXSYS_round(fLineEnd * 20000.0f);
+ FXSYS_assert(m_iLineEnd >= m_iLineStart);
+ if (m_pCurLine->m_iStart < m_iLineStart) {
+ m_pCurLine->m_iStart = m_iLineStart;
+ }
+}
+void CFX_RTFBreak::SetLinePos(FX_FLOAT fLinePos)
+{
+ FX_INT32 iLinePos = FXSYS_round(fLinePos * 20000.0f);
+ if (iLinePos > m_iLineEnd) {
+ iLinePos = m_iLineEnd;
+ }
+ m_pCurLine->m_iStart = iLinePos;
+}
+void CFX_RTFBreak::SetLayoutStyles(FX_DWORD dwLayoutStyles)
+{
+ if (m_dwLayoutStyles == dwLayoutStyles) {
+ return;
+ }
+ SetBreakStatus();
+ m_dwLayoutStyles = dwLayoutStyles;
+ m_bPagination = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_Pagination) != 0;
+ m_bVertical = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0;
+ m_bSingleLine = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0;
+ m_bCharCode = (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0;
+ m_iLineRotation = GetLineRotation(m_dwLayoutStyles);
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_RTFBreak::SetFont(IFX_Font *pFont)
+{
+ if (pFont == NULL) {
+ return;
+ }
+ if (m_pFont == pFont) {
+ return;
+ }
+ SetBreakStatus();
+ m_pFont = pFont;
+ m_iDefChar = 0;
+ if (m_pFont != NULL) {
+ m_iFontHeight = m_iFontSize;
+ if (m_wDefChar != 0xFEFF) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_RTFBreak::SetFontSize(FX_FLOAT fFontSize)
+{
+ FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f);
+ if (m_iFontSize == iFontSize) {
+ return;
+ }
+ SetBreakStatus();
+ m_iFontSize = iFontSize;
+ m_iDefChar = 0;
+ if (m_pFont != NULL) {
+ m_iFontHeight = m_iFontSize;
+ if (m_wDefChar != 0xFEFF) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_RTFBreak::SetTabWidth(FX_FLOAT fTabWidth)
+{
+ m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f);
+}
+void CFX_RTFBreak::AddPositionedTab(FX_FLOAT fTabPos)
+{
+ FX_INT32 iLineEnd = m_iLineEnd;
+ FX_INT32 iTabPos = FXSYS_round(fTabPos * 20000.0f) + m_iLineStart;
+ if (iTabPos > iLineEnd) {
+ iTabPos = iLineEnd;
+ }
+ if (m_PositionedTabs.Find(iTabPos, 0) > -1) {
+ return;
+ }
+ FX_INT32 iCount = m_PositionedTabs.GetSize();
+ FX_INT32 iFind = 0;
+ for (; iFind < iCount; iFind ++) {
+ if (m_PositionedTabs[iFind] > iTabPos) {
+ break;
+ }
+ }
+ m_PositionedTabs.InsertAt(iFind, iTabPos);
+ if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) {
+ m_bOrphanLine = GetLastPositionedTab() >= iLineEnd;
+ } else {
+ m_bOrphanLine = FALSE;
+ }
+}
+void CFX_RTFBreak::SetPositionedTabs(const CFX_FloatArray &tabs)
+{
+ m_PositionedTabs.RemoveAll();
+ FX_INT32 iCount = tabs.GetSize();
+ m_PositionedTabs.SetSize(iCount);
+ FX_INT32 iLineEnd = m_iLineEnd;
+ FX_INT32 iTabPos;
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ iTabPos = FXSYS_round(tabs[i] * 20000.0f) + m_iLineStart;
+ if (iTabPos > iLineEnd) {
+ iTabPos = iLineEnd;
+ }
+ m_PositionedTabs[i] = iTabPos;
+ }
+ if (m_dwPolicies & FX_RTFBREAKPOLICY_OrphanPositionedTab) {
+ m_bOrphanLine = GetLastPositionedTab() >= iLineEnd;
+ } else {
+ m_bOrphanLine = FALSE;
+ }
+}
+void CFX_RTFBreak::ClearPositionedTabs()
+{
+ m_PositionedTabs.RemoveAll();
+ m_bOrphanLine = FALSE;
+}
+void CFX_RTFBreak::SetDefaultChar(FX_WCHAR wch)
+{
+ m_wDefChar = wch;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ if (m_iDefChar < 0) {
+ m_iDefChar = 0;
+ } else {
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_RTFBreak::SetLineBreakChar(FX_WCHAR wch)
+{
+ if (wch != L'\r' && wch != L'\n') {
+ return;
+ }
+ m_wLineBreakChar = wch;
+}
+void CFX_RTFBreak::SetLineBreakTolerance(FX_FLOAT fTolerance)
+{
+ m_iTolerance = FXSYS_round(fTolerance * 20000.0f);
+}
+void CFX_RTFBreak::SetHorizontalScale(FX_INT32 iScale)
+{
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (m_iHorizontalScale == iScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iHorizontalScale = iScale;
+}
+void CFX_RTFBreak::SetVerticalScale(FX_INT32 iScale)
+{
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (m_iVerticalScale == iScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iVerticalScale = iScale;
+}
+void CFX_RTFBreak::SetCharRotation(FX_INT32 iCharRotation)
+{
+ if (iCharRotation < 0) {
+ iCharRotation += (-iCharRotation / 4 + 1) * 4;
+ } else if (iCharRotation > 3) {
+ iCharRotation -= (iCharRotation / 4) * 4;
+ }
+ if (m_iCharRotation == iCharRotation) {
+ return;
+ }
+ SetBreakStatus();
+ m_iCharRotation = iCharRotation;
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_RTFBreak::SetCharSpace(FX_FLOAT fCharSpace)
+{
+ m_iCharSpace = FXSYS_round(fCharSpace * 20000.0f);
+}
+void CFX_RTFBreak::SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace)
+{
+ m_bWordSpace = !bDefault;
+ m_iWordSpace = FXSYS_round(fWordSpace * 20000.0f);
+}
+void CFX_RTFBreak::SetReadingOrder(FX_BOOL bRTL)
+{
+ m_bRTL = bRTL;
+}
+void CFX_RTFBreak::SetAlignment(FX_INT32 iAlignment)
+{
+ FXSYS_assert(iAlignment >= FX_RTFLINEALIGNMENT_Left && iAlignment <= FX_RTFLINEALIGNMENT_Distributed);
+ m_iAlignment = iAlignment;
+}
+void CFX_RTFBreak::SetUserData(IFX_Unknown *pUserData)
+{
+ if (m_pUserData == pUserData) {
+ return;
+ }
+ SetBreakStatus();
+ if (m_pUserData != NULL) {
+ m_pUserData->Release();
+ }
+ m_pUserData = pUserData;
+ if (m_pUserData != NULL) {
+ m_pUserData->AddRef();
+ }
+}
+static const FX_INT32 gs_FX_RTFLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2};
+FX_INT32 CFX_RTFBreak::GetLineRotation(FX_DWORD dwStyles) const
+{
+ return gs_FX_RTFLineRotations[(dwStyles & 0x0E) >> 1];
+}
+void CFX_RTFBreak::SetBreakStatus()
+{
+ m_dwIdentity ++;
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return;
+ }
+ CFX_RTFChar &tc = m_pCurLine->GetChar(iCount - 1);
+ if (tc.m_dwStatus == 0) {
+ tc.m_dwStatus = FX_RTFBREAK_PieceBreak;
+ }
+}
+CFX_RTFChar* CFX_RTFBreak::GetLastChar(FX_INT32 index) const
+{
+ CFX_RTFCharArray &tca = m_pCurLine->m_LineChars;
+ FX_INT32 iCount = tca.GetSize();
+ if (index < 0 || index >= iCount) {
+ return NULL;
+ }
+ CFX_RTFChar *pTC;
+ FX_INT32 iStart = iCount - 1;
+ while (iStart > -1) {
+ pTC = tca.GetDataPtr(iStart --);
+ if (pTC->m_iCharWidth >= 0 || pTC->GetCharType() != FX_CHARTYPE_Combination) {
+ if (--index < 0) {
+ return pTC;
+ }
+ }
+ }
+ return NULL;
+}
+CFX_RTFLine* CFX_RTFBreak::GetRTFLine(FX_BOOL bReady) const
+{
+ if (bReady) {
+ if (m_iReady == 1) {
+ return (CFX_RTFLine*)&m_RTFLine1;
+ } else if (m_iReady == 2) {
+ return (CFX_RTFLine*)&m_RTFLine2;
+ } else {
+ return NULL;
+ }
+ }
+ FXSYS_assert(m_pCurLine != NULL);
+ return m_pCurLine;
+}
+CFX_RTFPieceArray* CFX_RTFBreak::GetRTFPieces(FX_BOOL bReady) const
+{
+ CFX_RTFLine *pRTFLine = GetRTFLine(bReady);
+ if (pRTFLine == NULL) {
+ return NULL;
+ }
+ return &pRTFLine->m_LinePieces;
+}
+inline FX_DWORD CFX_RTFBreak::GetUnifiedCharType(FX_DWORD dwType) const
+{
+ return dwType >= FX_CHARTYPE_ArabicAlef ? FX_CHARTYPE_Arabic : dwType;
+}
+FX_INT32 CFX_RTFBreak::GetLastPositionedTab() const
+{
+ FX_INT32 iCount = m_PositionedTabs.GetSize();
+ if (iCount < 1) {
+ return m_iLineStart;
+ }
+ return m_PositionedTabs[iCount - 1];
+}
+FX_BOOL CFX_RTFBreak::GetPositionedTab(FX_INT32 &iTabPos) const
+{
+ FX_INT32 iCount = m_PositionedTabs.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ if (m_PositionedTabs[i] > iTabPos) {
+ iTabPos = m_PositionedTabs[i];
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+typedef FX_DWORD (CFX_RTFBreak::*FX_RTFBreak_LPFAppendChar)(CFX_RTFChar *pCurChar, FX_INT32 iRotation);
+static const FX_RTFBreak_LPFAppendChar g_FX_RTFBreak_lpfAppendChar[16] = {
+ &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Tab,
+ &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Control,
+ &CFX_RTFBreak::AppendChar_Combination,
+ &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Arabic,
+ &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Others,
+ &CFX_RTFBreak::AppendChar_Others,
+};
+FX_DWORD CFX_RTFBreak::AppendChar(FX_WCHAR wch)
+{
+ FXSYS_assert(m_pFont != NULL && m_pCurLine != NULL && m_pArabicChar != NULL);
+ if (m_bCharCode) {
+ return AppendChar_CharCode(wch);
+ }
+ FX_DWORD dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
+ CFX_RTFCharArray &tca = m_pCurLine->m_LineChars;
+ CFX_RTFChar *pCurChar = tca.AddSpace();
+ pCurChar->m_dwStatus = 0;
+ pCurChar->m_wCharCode = wch;
+ pCurChar->m_dwCharProps = dwProps;
+ pCurChar->m_dwCharStyles = 0;
+ pCurChar->m_dwLayoutStyles = 0;
+ pCurChar->m_iFontSize = m_iFontSize;
+ pCurChar->m_iFontHeight = m_iFontHeight;
+ pCurChar->m_iHorizontalScale = m_iHorizontalScale;
+ pCurChar->m_iVertialScale = m_iVerticalScale;
+ pCurChar->m_nRotation = m_iCharRotation;
+ pCurChar->m_iCharWidth = 0;
+ pCurChar->m_dwIdentity = m_dwIdentity;
+ if (m_pUserData != NULL) {
+ m_pUserData->AddRef();
+ }
+ pCurChar->m_pUserData = m_pUserData;
+ FX_DWORD dwRet1 = FX_RTFBREAK_None;
+ if (dwType != FX_CHARTYPE_Combination && GetUnifiedCharType(m_dwCharType) != GetUnifiedCharType(dwType)) {
+ if (!m_bSingleLine && !m_bOrphanLine && m_dwCharType > 0 && m_pCurLine->GetLineEnd() > m_iLineEnd + m_iTolerance) {
+ if (m_dwCharType != FX_CHARTYPE_Space || dwType != FX_CHARTYPE_Control) {
+ dwRet1 = EndBreak(FX_RTFBREAK_LineBreak);
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ if (iCount > 0) {
+ pCurChar = m_pCurLine->m_LineChars.GetDataPtr(iCount - 1);
+ }
+ }
+ }
+ }
+ FX_INT32 iRotation = m_iRotation;
+ if (m_bVertical && (dwProps & 0x8000) != 0) {
+ iRotation = (iRotation + 1) % 4;
+ }
+ FX_DWORD dwRet2 = (this->*g_FX_RTFBreak_lpfAppendChar[dwType >> FX_CHARTYPEBITS])(pCurChar, iRotation);
+ m_dwCharType = dwType;
+ return FX_MAX(dwRet1, dwRet2);
+}
+FX_DWORD CFX_RTFBreak::AppendChar_CharCode(FX_WCHAR wch)
+{
+ FXSYS_assert(m_pFont != NULL && m_pCurLine != NULL);
+ FXSYS_assert(m_bCharCode);
+ m_pCurLine->m_iMBCSChars ++;
+ CFX_RTFCharArray &tca = m_pCurLine->m_LineChars;
+ CFX_RTFChar *pCurChar = tca.AddSpace();
+ pCurChar->m_dwStatus = 0;
+ pCurChar->m_wCharCode = wch;
+ pCurChar->m_dwCharProps = 0;
+ pCurChar->m_dwCharStyles = 0;
+ pCurChar->m_dwLayoutStyles = m_dwLayoutStyles;
+ pCurChar->m_iFontSize = m_iFontSize;
+ pCurChar->m_iFontHeight = m_iFontHeight;
+ pCurChar->m_iHorizontalScale = m_iHorizontalScale;
+ pCurChar->m_iVertialScale = m_iVerticalScale;
+ pCurChar->m_nRotation = m_iCharRotation;
+ pCurChar->m_iCharWidth = 0;
+ pCurChar->m_dwIdentity = m_dwIdentity;
+ if (m_pUserData != NULL) {
+ m_pUserData->AddRef();
+ }
+ pCurChar->m_pUserData = m_pUserData;
+ FX_INT32 iCharWidth = 0;
+ if (m_bVertical != FX_IsOdd(m_iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wch, iCharWidth, TRUE)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ iCharWidth += m_iCharSpace;
+ pCurChar->m_iCharWidth = iCharWidth;
+ m_pCurLine->m_iWidth += iCharWidth;
+ m_dwCharType = 0;
+ if (!m_bSingleLine && m_pCurLine->GetLineEnd() > m_iLineEnd + m_iTolerance) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Combination(CFX_RTFChar *pCurChar, FX_INT32 iRotation)
+{
+ FX_INT32 iCharWidth = 0;
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth, m_bCharCode)) {
+ iCharWidth = 0;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ CFX_RTFChar *pLastChar = GetLastChar(0);
+ if (pLastChar != NULL && pLastChar->GetCharType() > FX_CHARTYPE_Combination) {
+ iCharWidth = -iCharWidth;
+ } else {
+ m_dwCharType = FX_CHARTYPE_Combination;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ if (iCharWidth > 0) {
+ m_pCurLine->m_iWidth += iCharWidth;
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Tab(CFX_RTFChar *pCurChar, FX_INT32 iRotation)
+{
+ if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ExpandTab) {
+ FX_BOOL bBreak = FALSE;
+ if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) {
+ bBreak = (m_pCurLine->GetLineEnd() > m_iLineEnd + m_iTolerance);
+ }
+ FX_INT32 &iLineWidth = m_pCurLine->m_iWidth;
+ FX_INT32 iCharWidth = iLineWidth;
+ if (GetPositionedTab(iCharWidth)) {
+ iCharWidth -= iLineWidth;
+ } else {
+ iCharWidth = m_iTabWidth * (iLineWidth / m_iTabWidth + 1) - iLineWidth;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ if (!m_bSingleLine && !m_bOrphanLine && bBreak) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Control(CFX_RTFChar *pCurChar, FX_INT32 iRotation)
+{
+ FX_DWORD dwRet2 = FX_RTFBREAK_None;
+ if (!m_bSingleLine) {
+ switch (pCurChar->m_wCharCode) {
+ case L'\v':
+ case 0x2028:
+ dwRet2 = FX_RTFBREAK_LineBreak;
+ break;
+ case L'\f':
+ dwRet2 = FX_RTFBREAK_PageBreak;
+ break;
+ case 0x2029:
+ dwRet2 = FX_RTFBREAK_ParagraphBreak;
+ break;
+ default:
+ if (pCurChar->m_wCharCode == m_wLineBreakChar) {
+ dwRet2 = FX_RTFBREAK_ParagraphBreak;
+ }
+ break;
+ }
+ if (dwRet2 != FX_RTFBREAK_None) {
+ dwRet2 = EndBreak(dwRet2);
+ }
+ }
+ return dwRet2;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Arabic(CFX_RTFChar *pCurChar, FX_INT32 iRotation)
+{
+ CFX_RTFChar *pLastChar = NULL;
+ FX_INT32 &iLineWidth = m_pCurLine->m_iWidth;
+ FX_INT32 iCharWidth = 0;
+ FX_WCHAR wForm;
+ FX_BOOL bAlef = FALSE;
+ if (m_dwCharType >= FX_CHARTYPE_ArabicAlef && m_dwCharType <= FX_CHARTYPE_ArabicDistortion) {
+ pLastChar = GetLastChar(1);
+ if (pLastChar != NULL) {
+ iLineWidth -= pLastChar->m_iCharWidth;
+ CFX_RTFChar *pPrevChar = GetLastChar(2);
+ wForm = m_pArabicChar->GetFormChar(pLastChar, pPrevChar, pCurChar);
+ bAlef = (wForm == 0xFEFF && pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef);
+ FX_INT32 iLastRotation = pLastChar->m_nRotation + m_iLineRotation;
+ if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) {
+ iLastRotation ++;
+ }
+ if (m_bVertical != FX_IsOdd(iLastRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode))
+ if (!m_pFont->GetCharWidth(pLastChar->m_wCharCode, iCharWidth, m_bCharCode)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ pLastChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ iCharWidth = 0;
+ }
+ }
+ wForm = m_pArabicChar->GetFormChar(pCurChar, (bAlef ? NULL : pLastChar), NULL);
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode))
+ if (!m_pFont->GetCharWidth(pCurChar->m_wCharCode, iCharWidth, m_bCharCode)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ m_pCurLine->m_iArabicChars ++;
+ if (!m_bSingleLine && !m_bOrphanLine && m_pCurLine->GetLineEnd() > m_iLineEnd + m_iTolerance) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::AppendChar_Others(CFX_RTFChar *pCurChar, FX_INT32 iRotation)
+{
+ FX_DWORD dwType = (pCurChar->m_dwCharProps & FX_CHARTYPEBITSMASK);
+ FX_WCHAR wForm;
+ if (dwType == FX_CHARTYPE_Numeric) {
+ if (m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) {
+ wForm = pCurChar->m_wCharCode + 0x0630;
+ } else {
+ wForm = pCurChar->m_wCharCode;
+ }
+ } else if (m_bRTL || m_bVertical) {
+ wForm = FX_GetMirrorChar(pCurChar->m_wCharCode, pCurChar->m_dwCharProps, m_bRTL, m_bVertical);
+ } else {
+ wForm = pCurChar->m_wCharCode;
+ }
+ FX_INT32 iCharWidth = 0;
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, m_bCharCode)) {
+ iCharWidth = m_iDefChar;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorizontalScale / 100;
+ iCharWidth += m_iCharSpace;
+ if (dwType == FX_CHARTYPE_Space && m_bWordSpace) {
+ iCharWidth += m_iWordSpace;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ m_pCurLine->m_iWidth += iCharWidth;
+ FX_BOOL bBreak = (dwType != FX_CHARTYPE_Space || (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0);
+ if (!m_bSingleLine && !m_bOrphanLine && bBreak && m_pCurLine->GetLineEnd() > m_iLineEnd + m_iTolerance) {
+ return EndBreak(FX_RTFBREAK_LineBreak);
+ }
+ return FX_RTFBREAK_None;
+}
+FX_DWORD CFX_RTFBreak::EndBreak(FX_DWORD dwStatus)
+{
+ FXSYS_assert(dwStatus >= FX_RTFBREAK_PieceBreak && dwStatus <= FX_RTFBREAK_PageBreak);
+ m_dwIdentity ++;
+ CFX_RTFPieceArray *pCurPieces = &m_pCurLine->m_LinePieces;
+ FX_INT32 iCount = pCurPieces->GetSize();
+ if (iCount > 0) {
+ CFX_RTFPiece *pLastPiece = pCurPieces->GetPtrAt(-- iCount);
+ if (dwStatus > FX_RTFBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ } else {
+ CFX_RTFLine *pLastLine = GetRTFLine(TRUE);
+ if (pLastLine != NULL) {
+ pCurPieces = &pLastLine->m_LinePieces;
+ iCount = pCurPieces->GetSize();
+ if (iCount -- > 0) {
+ CFX_RTFPiece *pLastPiece = pCurPieces->GetPtrAt(iCount);
+ if (dwStatus > FX_RTFBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ }
+ return FX_RTFBREAK_None;
+ }
+ iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return FX_RTFBREAK_None;
+ }
+ CFX_RTFChar &tc = m_pCurLine->GetChar(iCount - 1);
+ tc.m_dwStatus = dwStatus;
+ if (dwStatus <= FX_RTFBREAK_PieceBreak) {
+ return dwStatus;
+ }
+ }
+ m_iReady = (m_pCurLine == &m_RTFLine1) ? 1 : 2;
+ CFX_RTFLine *pNextLine = (m_pCurLine == &m_RTFLine1) ? &m_RTFLine2 : &m_RTFLine1;
+ FX_BOOL bAllChars = (m_iAlignment > FX_RTFLINEALIGNMENT_Right);
+ CFX_TPOArray tpos;
+ if (EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) {
+ goto EndBreak_Ret;
+ }
+ if (!m_bCharCode) {
+ EndBreak_BidiLine(tpos, dwStatus);
+ }
+ if (!m_bPagination && m_iAlignment > FX_RTFLINEALIGNMENT_Left) {
+ EndBreak_Alignment(tpos, bAllChars, dwStatus);
+ }
+EndBreak_Ret:
+ m_pCurLine = pNextLine;
+ m_pCurLine->m_iStart = m_iLineStart;
+ CFX_RTFChar *pTC = GetLastChar(0);
+ m_dwCharType = pTC == NULL ? 0 : pTC->GetCharType();
+ return dwStatus;
+}
+FX_BOOL CFX_RTFBreak::EndBreak_SplitLine(CFX_RTFLine *pNextLine, FX_BOOL bAllChars, FX_DWORD dwStatus)
+{
+ FX_BOOL bDone = FALSE;
+ if (!m_bSingleLine && !m_bOrphanLine && m_pCurLine->GetLineEnd() > m_iLineEnd + m_iTolerance) {
+ CFX_RTFChar &tc = m_pCurLine->GetChar(m_pCurLine->CountChars() - 1);
+ switch (tc.GetCharType()) {
+ case FX_CHARTYPE_Tab:
+ if ((m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0) {
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ }
+ break;
+ case FX_CHARTYPE_Control:
+ break;
+ case FX_CHARTYPE_Space:
+ if ((m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0) {
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ }
+ break;
+ default:
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ break;
+ }
+ }
+ if (m_bPagination || m_pCurLine->m_iMBCSChars > 0) {
+ const CFX_RTFChar *pCurChars = m_pCurLine->m_LineChars.GetData();
+ const CFX_RTFChar *pTC;
+ CFX_RTFPieceArray *pCurPieces = &m_pCurLine->m_LinePieces;
+ CFX_RTFPiece tp;
+ tp.m_pChars = &m_pCurLine->m_LineChars;
+ FX_BOOL bNew = TRUE;
+ FX_DWORD dwIdentity = (FX_DWORD) - 1;
+ FX_INT32 iLast = m_pCurLine->CountChars() - 1, j = 0;
+ for (FX_INT32 i = 0; i <= iLast;) {
+ pTC = pCurChars + i;
+ if (bNew) {
+ tp.m_iStartChar = i;
+ tp.m_iStartPos += tp.m_iWidth;
+ tp.m_iWidth = 0;
+ tp.m_dwStatus = pTC->m_dwStatus;
+ tp.m_iFontSize = pTC->m_iFontSize;
+ tp.m_iFontHeight = pTC->m_iFontHeight;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ tp.m_dwLayoutStyles = pTC->m_dwLayoutStyles;
+ dwIdentity = pTC->m_dwIdentity;
+ tp.m_dwIdentity = dwIdentity;
+ tp.m_pUserData = pTC->m_pUserData;
+ j = i;
+ bNew = FALSE;
+ }
+ if (i == iLast || pTC->m_dwStatus != FX_RTFBREAK_None || pTC->m_dwIdentity != dwIdentity) {
+ tp.m_iChars = i - j;
+ if (pTC->m_dwIdentity == dwIdentity) {
+ tp.m_dwStatus = pTC->m_dwStatus;
+ tp.m_iWidth += pTC->m_iCharWidth;
+ tp.m_iChars += 1;
+ i ++;
+ }
+ pCurPieces->Add(tp);
+ bNew = TRUE;
+ } else {
+ tp.m_iWidth += pTC->m_iCharWidth;
+ i ++;
+ }
+ }
+ return TRUE;
+ }
+ if (bAllChars && !bDone) {
+ FX_INT32 iEndPos = m_pCurLine->GetLineEnd();
+ GetBreakPos(m_pCurLine->m_LineChars, iEndPos, bAllChars, TRUE);
+ }
+ return FALSE;
+}
+void CFX_RTFBreak::EndBreak_BidiLine(CFX_TPOArray &tpos, FX_DWORD dwStatus)
+{
+ FX_TPO tpo;
+ CFX_RTFPiece tp;
+ CFX_RTFChar *pTC;
+ FX_INT32 i, j;
+ CFX_RTFCharArray &chars = m_pCurLine->m_LineChars;
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ FX_BOOL bDone = (!m_bPagination && !m_bCharCode && (m_pCurLine->m_iArabicChars > 0 || m_bRTL));
+ if (bDone) {
+ FX_INT32 iBidiNum = 0;
+ for (i = 0; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiPos = i;
+ if (pTC->GetCharType() != FX_CHARTYPE_Control) {
+ iBidiNum = i;
+ }
+ if (i == 0) {
+ pTC->m_iBidiLevel = 1;
+ }
+ }
+ FX_BidiLine(chars, iBidiNum + 1, m_bRTL ? 1 : 0);
+ } else {
+ for (i = 0; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiLevel = 0;
+ pTC->m_iBidiPos = 0;
+ pTC->m_iBidiOrder = 0;
+ }
+ }
+ tp.m_dwStatus = FX_RTFBREAK_PieceBreak;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_pChars = &chars;
+ CFX_RTFPieceArray *pCurPieces = &m_pCurLine->m_LinePieces;
+ FX_INT32 iBidiLevel = -1, iCharWidth;
+ FX_DWORD dwIdentity = (FX_DWORD) - 1;
+ i = j = 0;
+ while (i < iCount) {
+ pTC = chars.GetDataPtr(i);
+ if (iBidiLevel < 0) {
+ iBidiLevel = pTC->m_iBidiLevel;
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth < 1) {
+ tp.m_iWidth = 0;
+ } else {
+ tp.m_iWidth = iCharWidth;
+ }
+ tp.m_iBidiLevel = iBidiLevel;
+ tp.m_iBidiPos = pTC->m_iBidiOrder;
+ tp.m_iFontSize = pTC->m_iFontSize;
+ tp.m_iFontHeight = pTC->m_iFontHeight;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ dwIdentity = pTC->m_dwIdentity;
+ tp.m_dwIdentity = dwIdentity;
+ tp.m_pUserData = pTC->m_pUserData;
+ tp.m_dwStatus = FX_RTFBREAK_PieceBreak;
+ i ++;
+ } else if (iBidiLevel != pTC->m_iBidiLevel || pTC->m_dwIdentity != dwIdentity) {
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tp.m_iStartPos += tp.m_iWidth;
+ tp.m_iStartChar = i;
+ tpo.index = j ++;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ iBidiLevel = -1;
+ } else {
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ tp.m_iWidth += iCharWidth;
+ }
+ i ++;
+ }
+ }
+ if (i > tp.m_iStartChar) {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tpo.index = j;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ }
+ if (!m_bCharCode) {
+ j = tpos.GetSize() - 1;
+ FX_TEXTLAYOUT_PieceSort(tpos, 0, j);
+ FX_INT32 iStartPos = m_pCurLine->m_iStart;
+ for (i = 0; i <= j; i ++) {
+ tpo = tpos.GetAt(i);
+ CFX_RTFPiece &ttp = pCurPieces->GetAt(tpo.index);
+ ttp.m_iStartPos = iStartPos;
+ iStartPos += ttp.m_iWidth;
+ }
+ }
+}
+void CFX_RTFBreak::EndBreak_Alignment(CFX_TPOArray &tpos, FX_BOOL bAllChars, FX_DWORD dwStatus)
+{
+ CFX_RTFPieceArray *pCurPieces = &m_pCurLine->m_LinePieces;
+ FX_INT32 iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth;
+ FX_INT32 iCount = pCurPieces->GetSize();
+ FX_BOOL bFind = FALSE;
+ FX_DWORD dwCharType;
+ FX_INT32 i, j;
+ FX_TPO tpo;
+ for (i = iCount - 1; i > -1; i --) {
+ tpo = tpos.GetAt(i);
+ CFX_RTFPiece &ttp = pCurPieces->GetAt(tpo.index);
+ if (!bFind) {
+ iNetWidth = ttp.GetEndPos();
+ }
+ FX_BOOL bArabic = FX_IsOdd(ttp.m_iBidiLevel);
+ j = bArabic ? 0 : ttp.m_iChars - 1;
+ while (j > -1 && j < ttp.m_iChars) {
+ const CFX_RTFChar &tc = ttp.GetChar(j);
+ if (tc.m_nBreakType == FX_LBT_DIRECT_BRK) {
+ iGapChars ++;
+ }
+ if (!bFind || !bAllChars) {
+ dwCharType = tc.GetCharType();
+ if (dwCharType == FX_CHARTYPE_Space || dwCharType == FX_CHARTYPE_Control) {
+ if (!bFind) {
+ iCharWidth = tc.m_iCharWidth;
+ if (bAllChars && iCharWidth > 0) {
+ iNetWidth -= iCharWidth;
+ }
+ }
+ } else {
+ bFind = TRUE;
+ if (!bAllChars) {
+ break;
+ }
+ }
+ }
+ j += bArabic ? 1 : -1;
+ }
+ if (!bAllChars && bFind) {
+ break;
+ }
+ }
+ FX_INT32 iOffset = m_iLineEnd - iNetWidth;
+ FX_INT32 iLowerAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_LowerMask);
+ FX_INT32 iHigherAlignment = (m_iAlignment & FX_RTFLINEALIGNMENT_HigherMask);
+ if (iGapChars > 0 && (iHigherAlignment == FX_RTFLINEALIGNMENT_Distributed || (iHigherAlignment == FX_RTFLINEALIGNMENT_Justified && dwStatus != FX_RTFBREAK_ParagraphBreak))) {
+ FX_INT32 iStart = -1;
+ for (i = 0; i < iCount; i ++) {
+ tpo = tpos.GetAt(i);
+ CFX_RTFPiece &ttp = pCurPieces->GetAt(tpo.index);
+ if (iStart < 0) {
+ iStart = ttp.m_iStartPos;
+ } else {
+ ttp.m_iStartPos = iStart;
+ }
+ FX_INT32 k;
+ for (j = 0; j < ttp.m_iChars; j ++) {
+ CFX_RTFChar &tc = ttp.GetChar(j);
+ if (tc.m_nBreakType != FX_LBT_DIRECT_BRK || tc.m_iCharWidth < 0) {
+ continue;
+ }
+ k = iOffset / iGapChars;
+ tc.m_iCharWidth += k;
+ ttp.m_iWidth += k;
+ iOffset -= k;
+ iGapChars --;
+ if (iGapChars < 1) {
+ break;
+ }
+ }
+ iStart += ttp.m_iWidth;
+ }
+ } else if (iLowerAlignment > FX_RTFLINEALIGNMENT_Left) {
+ if (iLowerAlignment == FX_RTFLINEALIGNMENT_Center) {
+ iOffset /= 2;
+ }
+ if (iOffset > 0) {
+ for (i = 0; i < iCount; i ++) {
+ CFX_RTFPiece &ttp = pCurPieces->GetAt(i);
+ ttp.m_iStartPos += iOffset;
+ }
+ }
+ }
+}
+FX_INT32 CFX_RTFBreak::GetBreakPos(CFX_RTFCharArray &tca, FX_INT32 &iEndPos, FX_BOOL bAllChars, FX_BOOL bOnlyBrk)
+{
+ FX_INT32 iLength = tca.GetSize() - 1;
+ if (iLength < 1) {
+ return iLength;
+ }
+ FX_INT32 iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1, iLast = -1, iLastPos = -1;
+ if (m_bSingleLine || m_bOrphanLine || iEndPos <= m_iLineEnd) {
+ if (!bAllChars || m_bCharCode) {
+ return iLength;
+ }
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ }
+ CFX_RTFChar *pCharArray = tca.GetData();
+ if (m_bCharCode) {
+ const CFX_RTFChar *pChar;
+ FX_INT32 iCharWidth;
+ while (iLength > 0) {
+ if (iEndPos <= m_iLineEnd) {
+ break;
+ }
+ pChar = pCharArray + iLength--;
+ iCharWidth = pChar->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ }
+ return iLength;
+ }
+ FX_BOOL bSpaceBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_SpaceBreak) != 0;
+ FX_BOOL bTabBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_TabBreak) != 0;
+ FX_BOOL bNumberBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_NumberBreak) != 0;
+ FX_BOOL bInfixBreak = (m_dwPolicies & FX_RTFBREAKPOLICY_InfixBreak) != 0;
+ FX_LINEBREAKTYPE eType;
+ FX_DWORD nCodeProp, nCur, nNext;
+ CFX_RTFChar *pCur = pCharArray + iLength--;
+ if (bAllChars) {
+ pCur->m_nBreakType = FX_LBT_UNKNOWN;
+ }
+ nCodeProp = pCur->m_dwCharProps;
+ nNext = nCodeProp & 0x003F;
+ FX_INT32 iCharWidth = pCur->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ while (iLength >= 0) {
+ pCur = pCharArray + iLength;
+ nCodeProp = pCur->m_dwCharProps;
+ nCur = nCodeProp & 0x003F;
+ FX_BOOL bNeedBreak = FALSE;
+ if (nCur == FX_CBP_SP) {
+ bNeedBreak = !bSpaceBreak;
+ if (nNext == FX_CBP_SP) {
+ eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE *)gs_FX_LineBreak_PairTable + (nCur << 5) + nNext);
+ }
+ } else if (nCur == FX_CBP_TB) {
+ bNeedBreak = !bTabBreak;
+ if (nNext == FX_CBP_TB) {
+ eType = bTabBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE *)gs_FX_LineBreak_PairTable + (nCur << 5) + nNext);
+ }
+ } else if (bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) {
+ eType = FX_LBT_DIRECT_BRK;
+ } else if (bInfixBreak && nCur == FX_CBP_IS && nNext == FX_CBP_IS) {
+ eType = FX_LBT_DIRECT_BRK;
+ } else {
+ if (nNext == FX_CBP_SP) {
+ eType = FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE *)gs_FX_LineBreak_PairTable + (nCur << 5) + nNext);
+ }
+ }
+ if (bAllChars) {
+ pCur->m_nBreakType = eType;
+ }
+ if (!bOnlyBrk) {
+ iCharWidth = pCur->m_iCharWidth;
+ FX_BOOL bBreak = FALSE;
+ if (nCur == FX_CBP_TB && bTabBreak) {
+ bBreak = iCharWidth > 0 && iEndPos - iCharWidth <= m_iLineEnd;
+ } else {
+ bBreak = iEndPos <= m_iLineEnd;
+ }
+ if (m_bSingleLine || m_bOrphanLine || bBreak || bNeedBreak) {
+ if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) {
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ if (!bAllChars) {
+ return iLength;
+ }
+ } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) {
+ iIndirect = iLength;
+ iIndirectPos = iEndPos;
+ }
+ if (iLast < 0) {
+ iLast = iLength;
+ iLastPos = iEndPos;
+ }
+ }
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ }
+ nNext = nCodeProp & 0x003F;
+ iLength --;
+ }
+ if (bOnlyBrk) {
+ return 0;
+ }
+ if (iBreak > -1) {
+ iEndPos = iBreakPos;
+ return iBreak;
+ }
+ if (iIndirect > -1) {
+ iEndPos = iIndirectPos;
+ return iIndirect;
+ }
+ if (iLast > -1) {
+ iEndPos = iLastPos;
+ return iLast;
+ }
+ return 0;
+}
+void CFX_RTFBreak::SplitTextLine(CFX_RTFLine *pCurLine, CFX_RTFLine *pNextLine, FX_BOOL bAllChars)
+{
+ FXSYS_assert(pCurLine != NULL && pNextLine != NULL);
+ FX_INT32 iCount = pCurLine->CountChars();
+ if (iCount < 2) {
+ return;
+ }
+ FX_INT32 iEndPos = pCurLine->GetLineEnd();
+ CFX_RTFCharArray &curChars = pCurLine->m_LineChars;
+ FX_INT32 iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, FALSE);
+ if (iCharPos < 0) {
+ iCharPos = 0;
+ }
+ iCharPos ++;
+ if (iCharPos >= iCount) {
+ pNextLine->RemoveAll(TRUE);
+ CFX_Char *pTC = curChars.GetDataPtr(iCharPos - 1);
+ pTC->m_nBreakType = FX_LBT_UNKNOWN;
+ return;
+ }
+ CFX_RTFCharArray &nextChars = pNextLine->m_LineChars;
+ int cur_size = curChars.GetSize();
+ nextChars.SetSize(cur_size - iCharPos);
+ FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos), (cur_size - iCharPos) * sizeof(CFX_RTFChar));
+ iCount -= iCharPos;
+ cur_size = curChars.GetSize();
+ curChars.RemoveAt(cur_size - iCount, iCount);
+ pNextLine->m_iStart = pCurLine->m_iStart;
+ pNextLine->m_iWidth = pCurLine->GetLineEnd() - iEndPos;
+ pCurLine->m_iWidth = iEndPos;
+ CFX_RTFChar* tc = curChars.GetDataPtr(iCharPos - 1);
+ tc->m_nBreakType = FX_LBT_UNKNOWN;
+ iCount = nextChars.GetSize();
+ CFX_RTFChar *pNextChars = nextChars.GetData();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFX_RTFChar* tc = pNextChars + i;
+ if (tc->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
+ pCurLine->m_iArabicChars --;
+ pNextLine->m_iArabicChars ++;
+ }
+ if (tc->m_dwLayoutStyles & FX_RTFLAYOUTSTYLE_MBCSCode) {
+ pCurLine->m_iMBCSChars --;
+ pNextLine->m_iMBCSChars ++;
+ }
+ tc->m_dwStatus = 0;
+ }
+}
+FX_INT32 CFX_RTFBreak::CountBreakPieces() const
+{
+ CFX_RTFPieceArray *pRTFPieces = GetRTFPieces(TRUE);
+ if (pRTFPieces == NULL) {
+ return 0;
+ }
+ return pRTFPieces->GetSize();
+}
+const CFX_RTFPiece* CFX_RTFBreak::GetBreakPiece(FX_INT32 index) const
+{
+ CFX_RTFPieceArray *pRTFPieces = GetRTFPieces(TRUE);
+ if (pRTFPieces == NULL) {
+ return NULL;
+ }
+ if (index < 0 || index >= pRTFPieces->GetSize()) {
+ return NULL;
+ }
+ return pRTFPieces->GetPtrAt(index);
+}
+void CFX_RTFBreak::GetLineRect(CFX_RectF &rect) const
+{
+ rect.top = 0;
+ CFX_RTFLine *pRTFLine = GetRTFLine(TRUE);
+ if (pRTFLine == NULL) {
+ rect.left = ((FX_FLOAT)m_iLineStart) / 20000.0f;
+ rect.width = rect.height = 0;
+ return;
+ }
+ rect.left = ((FX_FLOAT)pRTFLine->m_iStart) / 20000.0f;
+ rect.width = ((FX_FLOAT)pRTFLine->m_iWidth) / 20000.0f;
+ CFX_RTFPieceArray &rtfPieces = pRTFLine->m_LinePieces;
+ FX_INT32 iCount = rtfPieces.GetSize();
+ if (iCount < 1) {
+ rect.width = 0;
+ return;
+ }
+ CFX_RTFPiece *pBreakPiece;
+ FX_INT32 iLineHeight = 0, iMax;
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pBreakPiece = rtfPieces.GetPtrAt(i);
+ FX_INT32 iFontHeight = FXSYS_round(pBreakPiece->m_iFontHeight * pBreakPiece->m_iVerticalScale / 100.0f);
+ iMax = FX_MAX(pBreakPiece->m_iFontSize, iFontHeight);
+ if (i == 0) {
+ iLineHeight = iMax;
+ } else if (iLineHeight < iMax) {
+ iLineHeight = iMax;
+ }
+ }
+ rect.height = ((FX_FLOAT)iLineHeight) / 20.0f;
+}
+void CFX_RTFBreak::ClearBreakPieces()
+{
+ CFX_RTFLine *pRTFLine = GetRTFLine(TRUE);
+ if (pRTFLine != NULL) {
+ pRTFLine->RemoveAll(TRUE);
+ }
+ m_iReady = 0;
+}
+void CFX_RTFBreak::Reset()
+{
+ m_dwCharType = 0;
+ m_RTFLine1.RemoveAll(TRUE);
+ m_RTFLine2.RemoveAll(TRUE);
+}
+FX_INT32 CFX_RTFBreak::GetDisplayPos(FX_LPCRTFTEXTOBJ pText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode , CFX_WideString *pWSForms , FX_AdjustCharDisplayPos pAdjustPos ) const
+{
+ if (pText == NULL || pText->iLength < 1) {
+ return 0;
+ }
+ FXSYS_assert(pText->pStr != NULL && pText->pWidths != NULL && pText->pFont != NULL && pText->pRect != NULL);
+ FX_LPCWSTR pStr = pText->pStr;
+ FX_INT32 *pWidths = pText->pWidths;
+ FX_INT32 iLength = pText->iLength - 1;
+ IFX_Font *pFont = pText->pFont;
+ FX_DWORD dwStyles = pText->dwLayoutStyles;
+ CFX_RectF rtText(*pText->pRect);
+ FX_BOOL bRTLPiece = FX_IsOdd(pText->iBidiLevel);
+ FX_FLOAT fFontSize = pText->fFontSize;
+ FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f);
+ FX_INT32 iAscent = pFont->GetAscent();
+ FX_INT32 iDescent = pFont->GetDescent();
+ FX_INT32 iMaxHeight = iAscent - iDescent;
+ FX_FLOAT fFontHeight = fFontSize;
+ FX_FLOAT fAscent = fFontHeight * (FX_FLOAT)iAscent / (FX_FLOAT)iMaxHeight;
+ FX_FLOAT fDescent = fFontHeight * (FX_FLOAT)iDescent / (FX_FLOAT)iMaxHeight;
+ FX_BOOL bVerticalDoc = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bVerticalChar = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalChars) != 0;
+ FX_BOOL bArabicNumber = (dwStyles & FX_RTFLAYOUTSTYLE_ArabicNumber) != 0;
+ FX_BOOL bMBCSCode = (dwStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0;
+ FX_INT32 iRotation = GetLineRotation(dwStyles) + pText->iCharRotation;
+ FX_INT32 iCharRotation;
+ FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm;
+ FX_INT32 iWidth, iCharWidth, iCharHeight;
+ FX_FLOAT fX, fY, fCharWidth, fCharHeight;
+ FX_INT32 iHorScale = pText->iHorizontalScale;
+ FX_INT32 iVerScale = pText->iVerticalScale;
+ FX_BOOL bEmptyChar;
+ FX_DWORD dwProps, dwCharType;
+ fX = rtText.left;
+ fY = rtText.top;
+ if (bVerticalDoc) {
+ fX += (rtText.width - fFontSize) / 2.0f;
+ if (bRTLPiece) {
+ fY = rtText.bottom();
+ }
+ } else {
+ if (bRTLPiece) {
+ fX = rtText.right();
+ }
+ fY += fAscent;
+ }
+ FX_INT32 iCount = 0;
+ for (FX_INT32 i = 0; i <= iLength; i ++) {
+ wch = *pStr ++;
+ iWidth = *pWidths ++;
+ if (!bMBCSCode) {
+ dwProps = FX_GetUnicodeProperties(wch);
+ dwCharType = (dwProps & FX_CHARTYPEBITSMASK);
+ if (dwCharType == FX_CHARTYPE_ArabicAlef && iWidth == 0) {
+ wPrev = 0xFEFF;
+ continue;
+ }
+ } else {
+ dwProps = 0;
+ dwCharType = 0;
+ }
+ if (iWidth != 0) {
+ iCharWidth = iWidth;
+ if (iCharWidth < 0) {
+ iCharWidth = -iCharWidth;
+ }
+ if (!bMBCSCode) {
+ bEmptyChar = (dwCharType >= FX_CHARTYPE_Tab && dwCharType <= FX_CHARTYPE_Control);
+ } else {
+ bEmptyChar = FALSE;
+ }
+ if (!bEmptyChar) {
+ iCount ++;
+ }
+ if (pCharPos != NULL) {
+ iCharWidth /= iFontSize;
+ wForm = wch;
+ if (!bMBCSCode) {
+ if (dwCharType >= FX_CHARTYPE_ArabicAlef) {
+ if (i < iLength) {
+ wNext = *pStr;
+ if (*pWidths < 0) {
+ if (i + 1 < iLength) {
+ wNext = pStr[1];
+ }
+ }
+ } else {
+ wNext = 0xFEFF;
+ }
+ wForm = m_pArabicChar->GetFormChar(wch, wPrev, wNext);
+ } else if (bRTLPiece || bVerticalChar) {
+ wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar);
+ } else if (dwCharType == FX_CHARTYPE_Numeric && bArabicNumber) {
+ wForm = wch + 0x0630;
+ }
+ dwProps = FX_GetUnicodeProperties(wForm);
+ }
+ iCharRotation = iRotation;
+ if (!bMBCSCode && bVerticalChar && (dwProps & 0x8000) != 0) {
+ iCharRotation ++;
+ iCharRotation %= 4;
+ }
+ if (!bEmptyChar) {
+ if (bCharCode) {
+ pCharPos->m_GlyphIndex = wch;
+ } else {
+ pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wForm, bMBCSCode);
+ if(pCharPos->m_GlyphIndex == 0xFFFF) {
+ pCharPos->m_GlyphIndex = pFont->GetGlyphIndex(wch, bMBCSCode);
+ }
+ }
+ pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
+ pCharPos->m_FontCharWidth = iCharWidth;
+ if (pWSForms) {
+ *pWSForms += wForm;
+ }
+ }
+ if (bVerticalDoc) {
+ iCharHeight = iCharWidth;
+ iCharWidth = 1000;
+ } else {
+ iCharHeight = 1000;
+ }
+ fCharWidth = fFontSize * iCharWidth / 1000.0f;
+ fCharHeight = fFontSize * iCharHeight / 1000.0f;
+ if (!bMBCSCode && bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY -= fCharHeight;
+ } else {
+ fX -= fCharWidth;
+ }
+ }
+ if (!bEmptyChar) {
+ CFX_PointF ptOffset;
+ ptOffset.Reset();
+ FX_BOOL bAdjusted = FALSE;
+ if (pAdjustPos) {
+ bAdjusted = pAdjustPos(wForm, bMBCSCode, pFont, fFontSize, bVerticalChar, ptOffset);
+ }
+ if (!pAdjustPos && bVerticalChar && (dwProps & 0x00010000) != 0) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wForm, rtBBox, bMBCSCode)) {
+ ptOffset.x = fFontSize * (850 - rtBBox.right()) / 1000.0f;
+ ptOffset.y = fFontSize * (1000 - rtBBox.height) / 2000.0f;
+ }
+ }
+ pCharPos->m_OriginX = fX + ptOffset.x;
+ pCharPos->m_OriginY = fY - ptOffset.y;
+ }
+ if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY += fCharHeight;
+ } else {
+ fX += fCharWidth;
+ }
+ }
+ if (!bEmptyChar) {
+ pCharPos->m_bGlyphAdjust = TRUE;
+ if (bVerticalDoc) {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ pCharPos->m_OriginY += fAscent * iVerScale / 100.0f;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -= fDescent + fAscent * iVerScale / 100.0f - fAscent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY += fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += fAscent;
+ pCharPos->m_OriginY += fCharWidth;
+ }
+ } else {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ pCharPos->m_OriginY += fAscent * iVerScale / 100.0f - fAscent;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -= fDescent;
+ pCharPos->m_OriginY -= fAscent + fDescent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY -= fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += fAscent * iVerScale / 100.0f;
+ }
+ }
+ if (iHorScale != 100 || iVerScale != 100) {
+ pCharPos->m_AdjustMatrix[0] = pCharPos->m_AdjustMatrix[0] * iHorScale / 100.0f;
+ pCharPos->m_AdjustMatrix[1] = pCharPos->m_AdjustMatrix[1] * iHorScale / 100.0f;
+ pCharPos->m_AdjustMatrix[2] = pCharPos->m_AdjustMatrix[2] * iVerScale / 100.0f;
+ pCharPos->m_AdjustMatrix[3] = pCharPos->m_AdjustMatrix[3] * iVerScale / 100.0f;
+ }
+ pCharPos ++;
+ }
+ }
+ }
+ if (iWidth > 0) {
+ wPrev = wch;
+ }
+ }
+ return iCount;
+}
+FX_INT32 CFX_RTFBreak::GetCharRects(FX_LPCRTFTEXTOBJ pText, CFX_RectFArray &rtArray, FX_BOOL bCharBBox ) const
+{
+ if (pText == NULL || pText->iLength < 1) {
+ return 0;
+ }
+ FXSYS_assert(pText->pStr != NULL && pText->pWidths != NULL && pText->pFont != NULL && pText->pRect != NULL);
+ FX_LPCWSTR pStr = pText->pStr;
+ FX_INT32 *pWidths = pText->pWidths;
+ FX_INT32 iLength = pText->iLength;
+ CFX_RectF rect(*pText->pRect);
+ FX_BOOL bRTLPiece = FX_IsOdd(pText->iBidiLevel);
+ FX_FLOAT fFontSize = pText->fFontSize;
+ FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f);
+ FX_FLOAT fScale = fFontSize / 1000.0f;
+ IFX_Font *pFont = pText->pFont;
+ if (pFont == NULL) {
+ bCharBBox = FALSE;
+ }
+ CFX_Rect bbox;
+ bbox.Set(0, 0, 0, 0);
+ if (bCharBBox) {
+ bCharBBox = pFont->GetBBox(bbox);
+ }
+ FX_FLOAT fLeft = FX_MAX(0, bbox.left * fScale);
+ FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
+ rtArray.RemoveAll();
+ rtArray.SetSize(iLength);
+ FX_DWORD dwStyles = pText->dwLayoutStyles;
+ FX_BOOL bVertical = (dwStyles & FX_RTFLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bMBCSCode = (dwStyles & FX_RTFLAYOUTSTYLE_MBCSCode) != 0;
+ FX_BOOL bSingleLine = (dwStyles & FX_RTFLAYOUTSTYLE_SingleLine) != 0;
+ FX_BOOL bCombText = (dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
+ FX_WCHAR wch, wLineBreakChar = pText->wLineBreakChar;
+ FX_INT32 iCharSize;
+ FX_FLOAT fCharSize, fStart;
+ if (bVertical) {
+ fStart = bRTLPiece ? rect.bottom() : rect.top;
+ } else {
+ fStart = bRTLPiece ? rect.right() : rect.left;
+ }
+ for (FX_INT32 i = 0; i < iLength; i ++) {
+ wch = *pStr ++;
+ iCharSize = *pWidths ++;
+ fCharSize = (FX_FLOAT)iCharSize / 20000.0f;
+ FX_BOOL bRet = (!bSingleLine && FX_IsCtrlCode(wch));
+ if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 || (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) {
+ bRet = FALSE;
+ }
+ if (bRet) {
+ iCharSize = iFontSize * 500;
+ fCharSize = fFontSize / 2.0f;
+ }
+ if (bVertical) {
+ rect.top = fStart;
+ if (bRTLPiece) {
+ rect.top -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.height = fCharSize;
+ } else {
+ rect.left = fStart;
+ if (bRTLPiece) {
+ rect.left -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.width = fCharSize;
+ }
+ if (bCharBBox && !bRet) {
+ FX_INT32 iCharWidth = 1000;
+ pFont->GetCharWidth(wch, iCharWidth);
+ FX_FLOAT fRTLeft = 0, fCharWidth = 0;
+ if (iCharWidth > 0) {
+ fCharWidth = iCharWidth * fScale;
+ fRTLeft = fLeft;
+ if (bCombText) {
+ fRTLeft = (rect.width - fCharWidth) / 2.0f;
+ }
+ }
+ CFX_RectF rtBBoxF;
+ if (bVertical) {
+ rtBBoxF.top = rect.left + fRTLeft;
+ rtBBoxF.left = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.height = fCharWidth;
+ rtBBoxF.width = fHeight;
+ rtBBoxF.left = FX_MAX(rtBBoxF.left, 0);
+ } else {
+ rtBBoxF.left = rect.left + fRTLeft;
+ rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.width = fCharWidth;
+ rtBBoxF.height = fHeight;
+ rtBBoxF.top = FX_MAX(rtBBoxF.top, 0);
+ }
+ rtArray.SetAt(i, rtBBoxF);
+ continue;
+ }
+ rtArray.SetAt(i, rect);
+ }
+ return iLength;
+}
diff --git a/xfa/src/fgas/src/layout/fx_rtfbreak.h b/xfa/src/fgas/src/layout/fx_rtfbreak.h
new file mode 100644
index 0000000000..bf5f1ee4b5
--- /dev/null
+++ b/xfa/src/fgas/src/layout/fx_rtfbreak.h
@@ -0,0 +1,180 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_RTFBREAK_IMP
+#define _FX_RTFBREAK_IMP
+class CFX_RTFLine;
+class CFX_RTFBreak;
+class CFX_RTFLine : public CFX_Object
+{
+public:
+ CFX_RTFLine() : m_LinePieces(16)
+ , m_iStart(0)
+ , m_iWidth(0)
+ , m_iArabicChars(0)
+ , m_iMBCSChars(0)
+ {
+ }
+ ~CFX_RTFLine()
+ {
+ RemoveAll();
+ }
+ FX_INT32 CountChars() const
+ {
+ return m_LineChars.GetSize();
+ }
+ CFX_RTFChar& GetChar(FX_INT32 index)
+ {
+ FXSYS_assert(index > -1 && index < m_LineChars.GetSize());
+ return *m_LineChars.GetDataPtr(index);
+ }
+ CFX_RTFChar* GetCharPtr(FX_INT32 index)
+ {
+ FXSYS_assert(index > -1 && index < m_LineChars.GetSize());
+ return m_LineChars.GetDataPtr(index);
+ }
+ FX_INT32 CountPieces() const
+ {
+ return m_LinePieces.GetSize();
+ }
+ CFX_RTFPiece& GetPiece(FX_INT32 index) const
+ {
+ FXSYS_assert(index > -1 && index < m_LinePieces.GetSize());
+ return m_LinePieces.GetAt(index);
+ }
+ CFX_RTFPiece* GetPiecePtr(FX_INT32 index) const
+ {
+ FXSYS_assert(index > -1 && index < m_LinePieces.GetSize());
+ return m_LinePieces.GetPtrAt(index);
+ }
+ FX_INT32 GetLineEnd() const
+ {
+ return m_iStart + m_iWidth;
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ CFX_RTFChar *pChar;
+ IFX_Unknown *pUnknown;
+ FX_INT32 iCount = m_LineChars.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pChar = m_LineChars.GetDataPtr(i);
+ if ((pUnknown = pChar->m_pUserData) != NULL) {
+ pUnknown->Release();
+ }
+ }
+ m_LineChars.RemoveAll();
+ m_LinePieces.RemoveAll(bLeaveMemory);
+ m_iWidth = 0;
+ m_iArabicChars = 0;
+ m_iMBCSChars = 0;
+ }
+ CFX_RTFCharArray m_LineChars;
+ CFX_RTFPieceArray m_LinePieces;
+ FX_INT32 m_iStart;
+ FX_INT32 m_iWidth;
+ FX_INT32 m_iArabicChars;
+ FX_INT32 m_iMBCSChars;
+};
+class CFX_RTFBreak : public IFX_RTFBreak, public CFX_Object
+{
+public:
+ CFX_RTFBreak(FX_DWORD dwPolicies);
+ ~CFX_RTFBreak();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual void SetLineWidth(FX_FLOAT fLineStart, FX_FLOAT fLineEnd);
+ virtual void SetLinePos(FX_FLOAT fLinePos);
+ virtual FX_DWORD GetLayoutStyles() const
+ {
+ return m_dwLayoutStyles;
+ }
+ virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles);
+ virtual void SetFont(IFX_Font *pFont);
+ virtual void SetFontSize(FX_FLOAT fFontSize);
+ virtual void SetTabWidth(FX_FLOAT fTabWidth);
+ virtual void AddPositionedTab(FX_FLOAT fTabPos);
+ virtual void SetPositionedTabs(const CFX_FloatArray &tabs);
+ virtual void ClearPositionedTabs();
+ virtual void SetDefaultChar(FX_WCHAR wch);
+ virtual void SetLineBreakChar(FX_WCHAR wch);
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance);
+ virtual void SetHorizontalScale(FX_INT32 iScale);
+ virtual void SetVerticalScale(FX_INT32 iScale);
+ virtual void SetCharRotation(FX_INT32 iCharRotation);
+ virtual void SetCharSpace(FX_FLOAT fCharSpace);
+ virtual void SetWordSpace(FX_BOOL bDefault, FX_FLOAT fWordSpace);
+ virtual void SetReadingOrder(FX_BOOL bRTL = FALSE);
+ virtual void SetAlignment(FX_INT32 iAlignment = FX_RTFLINEALIGNMENT_Left);
+ virtual void SetUserData(IFX_Unknown *pUserData);
+ virtual FX_DWORD AppendChar(FX_WCHAR wch);
+ virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_RTFBREAK_PieceBreak);
+ virtual FX_INT32 CountBreakPieces() const;
+ virtual const CFX_RTFPiece* GetBreakPiece(FX_INT32 index) const;
+ virtual void GetLineRect(CFX_RectF &rect) const;
+ virtual void ClearBreakPieces();
+ virtual void Reset();
+ virtual FX_INT32 GetDisplayPos(FX_LPCRTFTEXTOBJ pText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const;
+ virtual FX_INT32 GetCharRects(FX_LPCRTFTEXTOBJ pText, CFX_RectFArray &rtArray, FX_BOOL bCharBBox = FALSE) const;
+ FX_DWORD AppendChar_CharCode(FX_WCHAR wch);
+ FX_DWORD AppendChar_Combination(CFX_RTFChar *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Tab(CFX_RTFChar *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Control(CFX_RTFChar *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Arabic(CFX_RTFChar *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Others(CFX_RTFChar *pCurChar, FX_INT32 iRotation);
+protected:
+ FX_DWORD m_dwPolicies;
+ IFX_ArabicChar *m_pArabicChar;
+ FX_INT32 m_iLineStart;
+ FX_INT32 m_iLineEnd;
+ FX_DWORD m_dwLayoutStyles;
+ FX_BOOL m_bPagination;
+ FX_BOOL m_bVertical;
+ FX_BOOL m_bSingleLine;
+ FX_BOOL m_bCharCode;
+ IFX_Font *m_pFont;
+ FX_INT32 m_iFontHeight;
+ FX_INT32 m_iFontSize;
+ FX_INT32 m_iTabWidth;
+ CFX_Int32Array m_PositionedTabs;
+ FX_BOOL m_bOrphanLine;
+ FX_WCHAR m_wDefChar;
+ FX_INT32 m_iDefChar;
+ FX_WCHAR m_wLineBreakChar;
+ FX_INT32 m_iHorizontalScale;
+ FX_INT32 m_iVerticalScale;
+ FX_INT32 m_iLineRotation;
+ FX_INT32 m_iCharRotation;
+ FX_INT32 m_iRotation;
+ FX_INT32 m_iCharSpace;
+ FX_BOOL m_bWordSpace;
+ FX_INT32 m_iWordSpace;
+ FX_BOOL m_bRTL;
+ FX_INT32 m_iAlignment;
+ IFX_Unknown *m_pUserData;
+ FX_DWORD m_dwCharType;
+ FX_DWORD m_dwIdentity;
+ CFX_RTFLine m_RTFLine1;
+ CFX_RTFLine m_RTFLine2;
+ CFX_RTFLine *m_pCurLine;
+ FX_INT32 m_iReady;
+ FX_INT32 m_iTolerance;
+ FX_INT32 GetLineRotation(FX_DWORD dwStyles) const;
+ void SetBreakStatus();
+ CFX_RTFChar* GetLastChar(FX_INT32 index) const;
+ CFX_RTFLine* GetRTFLine(FX_BOOL bReady) const;
+ CFX_RTFPieceArray* GetRTFPieces(FX_BOOL bReady) const;
+ FX_DWORD GetUnifiedCharType(FX_DWORD dwType) const;
+ FX_INT32 GetLastPositionedTab() const;
+ FX_BOOL GetPositionedTab(FX_INT32 &iTabPos) const;
+ FX_INT32 GetBreakPos(CFX_RTFCharArray &tca, FX_INT32 &iEndPos, FX_BOOL bAllChars = FALSE, FX_BOOL bOnlyBrk = FALSE);
+ void SplitTextLine(CFX_RTFLine *pCurLine, CFX_RTFLine *pNextLine, FX_BOOL bAllChars = FALSE);
+ FX_BOOL EndBreak_SplitLine(CFX_RTFLine *pNextLine, FX_BOOL bAllChars, FX_DWORD dwStatus);
+ void EndBreak_BidiLine(CFX_TPOArray &tpos, FX_DWORD dwStatus);
+ void EndBreak_Alignment(CFX_TPOArray &tpos, FX_BOOL bAllChars, FX_DWORD dwStatus);
+};
+#endif
diff --git a/xfa/src/fgas/src/layout/fx_textbreak.cpp b/xfa/src/fgas/src/layout/fx_textbreak.cpp
new file mode 100644
index 0000000000..0bb7b69585
--- /dev/null
+++ b/xfa/src/fgas/src/layout/fx_textbreak.cpp
@@ -0,0 +1,1653 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_unicode.h"
+#include "fx_textbreak.h"
+extern const FX_DWORD gs_FX_TextLayout_CodeProperties[65536];
+extern const FX_WCHAR gs_FX_TextLayout_VerticalMirror[64];
+extern const FX_WCHAR gs_FX_TextLayout_BidiMirror[512];
+extern const FX_LINEBREAKTYPE gs_FX_LineBreak_PairTable[64][32];
+IFX_TxtBreak* IFX_TxtBreak::Create(FX_DWORD dwPolicies)
+{
+ return FX_NEW CFX_TxtBreak(dwPolicies);
+}
+CFX_TxtBreak::CFX_TxtBreak(FX_DWORD dwPolicies)
+ : m_dwPolicies(dwPolicies)
+ , m_pArabicChar(NULL)
+ , m_iLineWidth(2000000)
+ , m_dwLayoutStyles(0)
+ , m_bVertical(FALSE)
+ , m_bArabicContext(FALSE)
+ , m_bArabicShapes(FALSE)
+ , m_bRTL(FALSE)
+ , m_bSingleLine(FALSE)
+ , m_bCombText(FALSE)
+ , m_iArabicContext(1)
+ , m_iCurArabicContext(1)
+ , m_pFont(NULL)
+ , m_iFontSize(240)
+ , m_bEquidistant(TRUE)
+ , m_iTabWidth(720000)
+ , m_wDefChar(0xFEFF)
+ , m_wParagBreakChar(L'\n')
+ , m_iDefChar(0)
+ , m_iLineRotation(0)
+ , m_iCharRotation(0)
+ , m_iRotation(0)
+ , m_iAlignment(FX_TXTLINEALIGNMENT_Left)
+ , m_dwContextCharStyles(0)
+ , m_iCombWidth(360000)
+ , m_pUserData(NULL)
+ , m_dwCharType(0)
+ , m_bArabicNumber(FALSE)
+ , m_bArabicComma(FALSE)
+ , m_pCurLine(NULL)
+ , m_iReady(0)
+ , m_iTolerance(0)
+ , m_iHorScale(100)
+ , m_iVerScale(100)
+ , m_iCharSpace(0)
+{
+ m_bPagination = (m_dwPolicies & FX_TXTBREAKPOLICY_Pagination) != 0;
+ m_pArabicChar = IFX_ArabicChar::Create();
+ if (m_bPagination) {
+ m_pTxtLine1 = FX_NEW CFX_TxtLine(sizeof(CFX_Char));
+ m_pTxtLine2 = FX_NEW CFX_TxtLine(sizeof(CFX_Char));
+ } else {
+ m_pTxtLine1 = FX_NEW CFX_TxtLine(sizeof(CFX_TxtChar));
+ m_pTxtLine2 = FX_NEW CFX_TxtLine(sizeof(CFX_TxtChar));
+ }
+ m_pCurLine = m_pTxtLine1;
+ ResetArabicContext();
+}
+CFX_TxtBreak::~CFX_TxtBreak()
+{
+ Reset();
+ delete m_pTxtLine1;
+ delete m_pTxtLine2;
+ m_pArabicChar->Release();
+}
+void CFX_TxtBreak::SetLineWidth(FX_FLOAT fLineWidth)
+{
+ m_iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
+ FXSYS_assert(m_iLineWidth >= 20000);
+}
+void CFX_TxtBreak::SetLinePos(FX_FLOAT fLinePos)
+{
+ FX_INT32 iLinePos = FXSYS_round(fLinePos * 20000.0f);
+ if (iLinePos < 0) {
+ iLinePos = 0;
+ }
+ if (iLinePos > m_iLineWidth) {
+ iLinePos = m_iLineWidth;
+ }
+ m_pCurLine->m_iStart = iLinePos;
+ m_pCurLine->m_iWidth += iLinePos;
+}
+void CFX_TxtBreak::SetLayoutStyles(FX_DWORD dwLayoutStyles)
+{
+ m_dwLayoutStyles = dwLayoutStyles;
+ m_bVertical = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_VerticalChars) != 0;
+ m_bArabicContext = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ArabicContext) != 0;
+ m_bArabicShapes = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ArabicShapes) != 0;
+ m_bRTL = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_RTLReadingOrder) != 0;
+ m_bSingleLine = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_SingleLine) != 0;
+ m_bCombText = (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
+ ResetArabicContext();
+ m_iLineRotation = GetLineRotation(m_dwLayoutStyles);
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_TxtBreak::SetFont(IFX_Font *pFont)
+{
+ if (pFont == NULL) {
+ return;
+ }
+ if (m_pFont == pFont) {
+ return;
+ }
+ SetBreakStatus();
+ m_pFont = pFont;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+}
+void CFX_TxtBreak::SetFontSize(FX_FLOAT fFontSize)
+{
+ FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f);
+ if (m_iFontSize == iFontSize) {
+ return;
+ }
+ SetBreakStatus();
+ m_iFontSize = iFontSize;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ m_iDefChar *= m_iFontSize;
+ }
+}
+void CFX_TxtBreak::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant)
+{
+ m_iTabWidth = FXSYS_round(fTabWidth * 20000.0f);
+ if (m_iTabWidth < FX_TXTBREAK_MinimumTabWidth) {
+ m_iTabWidth = FX_TXTBREAK_MinimumTabWidth;
+ }
+ m_bEquidistant = bEquidistant;
+}
+void CFX_TxtBreak::SetDefaultChar(FX_WCHAR wch)
+{
+ m_wDefChar = wch;
+ m_iDefChar = 0;
+ if (m_wDefChar != 0xFEFF && m_pFont != NULL) {
+ m_pFont->GetCharWidth(m_wDefChar, m_iDefChar, FALSE);
+ if (m_iDefChar < 0) {
+ m_iDefChar = 0;
+ } else {
+ m_iDefChar *= m_iFontSize;
+ }
+ }
+}
+void CFX_TxtBreak::SetParagraphBreakChar(FX_WCHAR wch)
+{
+ if (wch != L'\r' && wch != L'\n') {
+ return;
+ }
+ m_wParagBreakChar = wch;
+}
+void CFX_TxtBreak::SetLineBreakTolerance(FX_FLOAT fTolerance)
+{
+ m_iTolerance = FXSYS_round(fTolerance * 20000.0f);
+}
+void CFX_TxtBreak::SetCharRotation(FX_INT32 iCharRotation)
+{
+ if (iCharRotation < 0) {
+ iCharRotation += (-iCharRotation / 4 + 1) * 4;
+ } else if (iCharRotation > 3) {
+ iCharRotation -= (iCharRotation / 4) * 4;
+ }
+ if (m_iCharRotation == iCharRotation) {
+ return;
+ }
+ SetBreakStatus();
+ m_iCharRotation = iCharRotation;
+ m_iRotation = m_iLineRotation + m_iCharRotation;
+ m_iRotation %= 4;
+}
+void CFX_TxtBreak::SetAlignment(FX_INT32 iAlignment)
+{
+ FXSYS_assert(iAlignment >= FX_TXTLINEALIGNMENT_Left && iAlignment <= FX_TXTLINEALIGNMENT_Distributed);
+ m_iAlignment = iAlignment;
+ ResetArabicContext();
+}
+void CFX_TxtBreak::ResetContextCharStyles()
+{
+ m_dwContextCharStyles = m_bArabicContext ? m_iCurAlignment : m_iAlignment;
+ if (m_bArabicNumber) {
+ m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicNumber;
+ }
+ if (m_bArabicComma) {
+ m_dwContextCharStyles |= FX_TXTCHARSTYLE_ArabicComma;
+ }
+ if ((m_bArabicContext && m_bCurRTL) || (!m_bArabicContext && m_bRTL)) {
+ m_dwContextCharStyles |= FX_TXTCHARSTYLE_RTLReadingOrder;
+ }
+ m_dwContextCharStyles |= (m_iArabicContext << 8);
+}
+FX_DWORD CFX_TxtBreak::GetContextCharStyles() const
+{
+ return m_dwContextCharStyles;
+}
+void CFX_TxtBreak::SetContextCharStyles(FX_DWORD dwCharStyles)
+{
+ m_iCurAlignment = dwCharStyles & 0x0F;
+ m_bArabicNumber = (dwCharStyles & FX_TXTCHARSTYLE_ArabicNumber) != 0;
+ m_bArabicComma = (dwCharStyles & FX_TXTCHARSTYLE_ArabicComma) != 0;
+ m_bCurRTL = (dwCharStyles & FX_TXTCHARSTYLE_RTLReadingOrder) != 0;
+ m_iCurArabicContext = m_iArabicContext = ((dwCharStyles & 0x0300) >> 8);
+ ResetContextCharStyles();
+}
+void CFX_TxtBreak::SetCombWidth(FX_FLOAT fCombWidth)
+{
+ m_iCombWidth = FXSYS_round(fCombWidth * 20000.0f);
+}
+void CFX_TxtBreak::SetUserData(FX_LPVOID pUserData)
+{
+ if (m_pUserData == pUserData) {
+ return;
+ }
+ SetBreakStatus();
+ m_pUserData = pUserData;
+}
+void CFX_TxtBreak::SetBreakStatus()
+{
+ if (m_bPagination) {
+ return;
+ }
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return;
+ }
+ CFX_TxtChar *pTC = (CFX_TxtChar*)m_pCurLine->GetCharPtr(iCount - 1);
+ if (pTC->m_dwStatus == 0) {
+ pTC->m_dwStatus = FX_TXTBREAK_PieceBreak;
+ }
+}
+void CFX_TxtBreak::SetHorizontalScale(FX_INT32 iScale)
+{
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (iScale == m_iHorScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iHorScale = iScale;
+}
+void CFX_TxtBreak::SetVerticalScale(FX_INT32 iScale)
+{
+ if (iScale < 0) {
+ iScale = 0;
+ }
+ if (iScale == m_iHorScale) {
+ return;
+ }
+ SetBreakStatus();
+ m_iVerScale = iScale;
+}
+void CFX_TxtBreak::SetCharSpace(FX_FLOAT fCharSpace)
+{
+ m_iCharSpace = FXSYS_round(fCharSpace * 20000.0f);
+}
+static const FX_INT32 gs_FX_TxtLineRotations[8] = {0, 3, 1, 0, 2, 1, 3, 2};
+FX_INT32 CFX_TxtBreak::GetLineRotation(FX_DWORD dwStyles) const
+{
+ return gs_FX_TxtLineRotations[(dwStyles & 0x0E) >> 1];
+}
+CFX_TxtChar* CFX_TxtBreak::GetLastChar(FX_INT32 index, FX_BOOL bOmitChar) const
+{
+ CFX_TxtCharArray &ca = *m_pCurLine->m_pLineChars;
+ FX_INT32 iCount = ca.GetSize();
+ if (index < 0 || index >= iCount) {
+ return NULL;
+ }
+ CFX_TxtChar *pTC;
+ FX_INT32 iStart = iCount - 1;
+ while (iStart > -1) {
+ pTC = ca.GetDataPtr(iStart --);
+ if (bOmitChar && pTC->GetCharType() == FX_CHARTYPE_Combination) {
+ continue;
+ }
+ if (--index < 0) {
+ return pTC;
+ }
+ }
+ return NULL;
+}
+CFX_TxtLine* CFX_TxtBreak::GetTxtLine(FX_BOOL bReady) const
+{
+ if (!bReady) {
+ return m_pCurLine;
+ }
+ if (m_iReady == 1) {
+ return m_pTxtLine1;
+ } else if (m_iReady == 2) {
+ return m_pTxtLine2;
+ } else {
+ return NULL;
+ }
+}
+CFX_TxtPieceArray* CFX_TxtBreak::GetTxtPieces(FX_BOOL bReady) const
+{
+ CFX_TxtLine *pTxtLine = GetTxtLine(bReady);
+ if (pTxtLine == NULL) {
+ return NULL;
+ }
+ return pTxtLine->m_pLinePieces;
+}
+inline FX_DWORD CFX_TxtBreak::GetUnifiedCharType(FX_DWORD dwType) const
+{
+ return dwType >= FX_CHARTYPE_ArabicAlef ? FX_CHARTYPE_Arabic : dwType;
+}
+void CFX_TxtBreak::ResetArabicContext()
+{
+ if (m_bArabicContext) {
+ m_bCurRTL = m_iCurArabicContext > 1;
+ m_iCurAlignment = m_iCurArabicContext > 1 ? FX_TXTLINEALIGNMENT_Right : FX_TXTLINEALIGNMENT_Left;
+ m_iCurAlignment |= (m_iAlignment & FX_TXTLINEALIGNMENT_HigherMask);
+ m_bArabicNumber = m_iArabicContext >= 1 && m_bArabicShapes;
+ } else {
+ if (m_bPagination) {
+ m_bCurRTL = FALSE;
+ m_iCurAlignment = 0;
+ } else {
+ m_bCurRTL = m_bRTL;
+ m_iCurAlignment = m_iAlignment;
+ }
+ if (m_bRTL) {
+ m_bArabicNumber = m_iArabicContext >= 1;
+ } else {
+ m_bArabicNumber = m_iArabicContext > 1;
+ }
+ m_bArabicNumber = m_bArabicNumber && m_bArabicShapes;
+ }
+ m_bArabicComma = m_bArabicNumber;
+ ResetContextCharStyles();
+}
+void CFX_TxtBreak::AppendChar_PageLoad(CFX_Char *pCurChar, FX_DWORD dwProps)
+{
+ if (!m_bPagination) {
+ ((CFX_TxtChar*)pCurChar)->m_dwStatus = 0;
+ ((CFX_TxtChar*)pCurChar)->m_pUserData = m_pUserData;
+ }
+ if (m_bArabicContext || m_bArabicShapes) {
+ FX_INT32 iBidiCls = (dwProps & FX_BIDICLASSBITSMASK) >> FX_BIDICLASSBITS;
+ FX_INT32 iArabicContext = (iBidiCls == FX_BIDICLASS_R || iBidiCls == FX_BIDICLASS_AL) ? 2 : ((iBidiCls == FX_BIDICLASS_L || iBidiCls == FX_BIDICLASS_S) ? 0 : 1);
+ if (iArabicContext != m_iArabicContext && iArabicContext != 1) {
+ m_iArabicContext = iArabicContext;
+ if (m_iCurArabicContext == 1) {
+ m_iCurArabicContext = iArabicContext;
+ }
+ ResetArabicContext();
+ if (!m_bPagination) {
+ CFX_TxtChar *pLastChar = (CFX_TxtChar*)GetLastChar(1, FALSE);
+ if (pLastChar != NULL && pLastChar->m_dwStatus < 1) {
+ pLastChar->m_dwStatus = FX_TXTBREAK_PieceBreak;
+ }
+ }
+ }
+ }
+ pCurChar->m_dwCharStyles = m_dwContextCharStyles;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Combination(CFX_Char *pCurChar, FX_INT32 iRotation)
+{
+ FXSYS_assert(pCurChar != NULL);
+ FX_WCHAR wch = pCurChar->m_wCharCode;
+ FX_WCHAR wForm;
+ FX_INT32 iCharWidth = 0;
+ CFX_Char *pLastChar;
+ pCurChar->m_iCharWidth = -1;
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ wForm = wch;
+ if (!m_bPagination) {
+ pLastChar = GetLastChar(0, FALSE);
+ if (pLastChar != NULL && (((CFX_TxtChar*)pLastChar)->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicShadda) == 0) {
+ FX_BOOL bShadda = FALSE;
+ if (wch == 0x0651) {
+ FX_WCHAR wLast = pLastChar->m_wCharCode;
+ if (wLast >= 0x064C && wLast <= 0x0650) {
+ wForm = FX_GetArabicFromShaddaTable(wLast);
+ bShadda = TRUE;
+ }
+ } else if (wch >= 0x064C && wch <= 0x0650) {
+ if (pLastChar->m_wCharCode == 0x0651) {
+ wForm = FX_GetArabicFromShaddaTable(wch);
+ bShadda = TRUE;
+ }
+ }
+ if (bShadda) {
+ ((CFX_TxtChar*)pLastChar)->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicShadda;
+ ((CFX_TxtChar*)pLastChar)->m_iCharWidth = 0;
+ ((CFX_TxtChar*)pCurChar)->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicShadda;
+ }
+ }
+ }
+ if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
+ iCharWidth = 0;
+ }
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ pCurChar->m_iCharWidth = -iCharWidth;
+ return FX_TXTBREAK_None;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Tab(CFX_Char *pCurChar, FX_INT32 iRotation)
+{
+ m_dwCharType = FX_CHARTYPE_Tab;
+ if ((m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_ExpandTab) == 0) {
+ return FX_TXTBREAK_None;
+ }
+ FX_INT32 &iLineWidth = m_pCurLine->m_iWidth;
+ FX_INT32 iCharWidth;
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bEquidistant) {
+ iCharWidth = iLineWidth;
+ iCharWidth = m_iTabWidth * (iCharWidth / m_iTabWidth + 1) - iCharWidth;
+ if (iCharWidth < FX_TXTBREAK_MinimumTabWidth) {
+ iCharWidth += m_iTabWidth;
+ }
+ } else {
+ iCharWidth = m_iTabWidth;
+ }
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ if (!m_bSingleLine && iLineWidth >= m_iLineWidth + m_iTolerance) {
+ return EndBreak(FX_TXTBREAK_LineBreak);
+ }
+ return FX_TXTBREAK_None;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Control(CFX_Char *pCurChar, FX_INT32 iRotation)
+{
+ m_dwCharType = FX_CHARTYPE_Control;
+ FX_DWORD dwRet = FX_TXTBREAK_None;
+ if (!m_bSingleLine) {
+ FX_WCHAR wch = pCurChar->m_wCharCode;
+ switch (wch) {
+ case L'\v':
+ case 0x2028:
+ dwRet = FX_TXTBREAK_LineBreak;
+ break;
+ case L'\f':
+ dwRet = FX_TXTBREAK_PageBreak;
+ break;
+ case 0x2029:
+ dwRet = FX_TXTBREAK_ParagraphBreak;
+ break;
+ default:
+ if (wch == m_wParagBreakChar) {
+ dwRet = FX_TXTBREAK_ParagraphBreak;
+ }
+ break;
+ }
+ if (dwRet != FX_TXTBREAK_None) {
+ dwRet = EndBreak(dwRet);
+ }
+ }
+ return dwRet;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Arabic(CFX_Char *pCurChar, FX_INT32 iRotation)
+{
+ FX_DWORD dwType = (pCurChar->m_dwCharProps & FX_CHARTYPEBITSMASK);
+ FX_INT32 &iLineWidth = m_pCurLine->m_iWidth;
+ FX_WCHAR wForm;
+ FX_INT32 iCharWidth = 0;
+ CFX_Char *pLastChar = NULL;
+ FX_BOOL bAlef = FALSE;
+ if (!m_bCombText && m_dwCharType >= FX_CHARTYPE_ArabicAlef && m_dwCharType <= FX_CHARTYPE_ArabicDistortion) {
+ pLastChar = GetLastChar(1);
+ if (pLastChar != NULL) {
+ iCharWidth = pLastChar->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iLineWidth -= iCharWidth;
+ }
+ CFX_Char *pPrevChar = GetLastChar(2);
+ wForm = m_pArabicChar->GetFormChar(pLastChar, pPrevChar, pCurChar);
+ bAlef = (wForm == 0xFEFF && pLastChar->GetCharType() == FX_CHARTYPE_ArabicAlef);
+ FX_INT32 iLastRotation = pLastChar->m_nRotation + m_iLineRotation;
+ if (m_bVertical && (pLastChar->m_dwCharProps & 0x8000) != 0) {
+ iLastRotation ++;
+ }
+ if (m_bVertical != FX_IsOdd(iLastRotation)) {
+ iCharWidth = 1000;
+ } else {
+ m_pFont->GetCharWidth(wForm, iCharWidth, FALSE);
+ }
+ if (wForm == 0xFEFF) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ pLastChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ iCharWidth = 0;
+ }
+ }
+ m_dwCharType = dwType;
+ wForm = m_pArabicChar->GetFormChar(pCurChar, bAlef ? NULL : pLastChar, NULL);
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else {
+ m_pFont->GetCharWidth(wForm, iCharWidth, FALSE);
+ }
+ if (wForm == 0xFEFF) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ m_pCurLine->m_iArabicChars ++;
+ if (!m_bSingleLine && iLineWidth > m_iLineWidth + m_iTolerance) {
+ return EndBreak(FX_TXTBREAK_LineBreak);
+ }
+ return FX_TXTBREAK_None;
+}
+FX_DWORD CFX_TxtBreak::AppendChar_Others(CFX_Char *pCurChar, FX_INT32 iRotation)
+{
+ FX_DWORD dwProps = pCurChar->m_dwCharProps;
+ FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
+ FX_INT32 &iLineWidth = m_pCurLine->m_iWidth;
+ FX_INT32 iCharWidth = 0;
+ m_dwCharType = dwType;
+ FX_WCHAR wch = pCurChar->m_wCharCode;
+ FX_WCHAR wForm = wch;
+ if (dwType == FX_CHARTYPE_Numeric) {
+ if (m_bArabicNumber) {
+ wForm = wch + 0x0630;
+ pCurChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicIndic;
+ }
+ } else if (wch == L',') {
+ if (m_bArabicShapes && m_iCurArabicContext > 0) {
+ wForm = 0x060C;
+ pCurChar->m_dwCharStyles |= FX_TXTCHARSTYLE_ArabicComma;
+ }
+ } else if (m_bCurRTL || m_bVertical) {
+ wForm = FX_GetMirrorChar(wch, dwProps, m_bCurRTL, m_bVertical);
+ }
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ iCharWidth += m_iCharSpace;
+ pCurChar->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ FX_BOOL bBreak = (dwType != FX_CHARTYPE_Space || (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0);
+ if (!m_bSingleLine && bBreak && iLineWidth > m_iLineWidth + m_iTolerance) {
+ return EndBreak(FX_TXTBREAK_LineBreak);
+ }
+ return FX_TXTBREAK_None;
+}
+typedef FX_DWORD (CFX_TxtBreak::*FX_TxtBreak_LPFAppendChar)(CFX_Char *pCurChar, FX_INT32 iRotation);
+static const FX_TxtBreak_LPFAppendChar g_FX_TxtBreak_lpfAppendChar[16] = {
+ &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Tab,
+ &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Control,
+ &CFX_TxtBreak::AppendChar_Combination,
+ &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Arabic,
+ &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Others,
+ &CFX_TxtBreak::AppendChar_Others,
+};
+FX_DWORD CFX_TxtBreak::AppendChar(FX_WCHAR wch)
+{
+ FX_DWORD dwProps = gs_FX_TextLayout_CodeProperties[(FX_WORD)wch];
+ FX_DWORD dwType = (dwProps & FX_CHARTYPEBITSMASK);
+ CFX_TxtChar *pCurChar = m_pCurLine->m_pLineChars->AddSpace();
+ pCurChar->m_wCharCode = (FX_WORD)wch;
+ pCurChar->m_nRotation = m_iCharRotation;
+ pCurChar->m_dwCharProps = dwProps;
+ pCurChar->m_dwCharStyles = 0;
+ pCurChar->m_iCharWidth = 0;
+ pCurChar->m_iHorizontalScale = m_iHorScale;
+ pCurChar->m_iVertialScale = m_iVerScale;
+ pCurChar->m_dwStatus = 0;
+ pCurChar->m_iBidiClass = 0;
+ pCurChar->m_iBidiLevel = 0;
+ pCurChar->m_iBidiPos = 0;
+ pCurChar->m_iBidiOrder = 0;
+ pCurChar->m_pUserData = NULL;
+ AppendChar_PageLoad(pCurChar, dwProps);
+ FX_DWORD dwRet1 = FX_TXTBREAK_None;
+ if (dwType != FX_CHARTYPE_Combination && GetUnifiedCharType(m_dwCharType) != GetUnifiedCharType(dwType)) {
+ if (m_dwCharType > 0 && m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance && !m_bSingleLine) {
+ if (m_dwCharType != FX_CHARTYPE_Space || dwType != FX_CHARTYPE_Control) {
+ dwRet1 = EndBreak(FX_TXTBREAK_LineBreak);
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ if (iCount > 0) {
+ pCurChar = m_pCurLine->m_pLineChars->GetDataPtr(iCount - 1);
+ }
+ }
+ }
+ }
+ FX_INT32 iRotation = m_iRotation;
+ if (m_bVertical && (dwProps & 0x8000) != 0) {
+ iRotation = (iRotation + 1) % 4;
+ }
+ FX_DWORD dwRet2 = (this->*g_FX_TxtBreak_lpfAppendChar[dwType >> FX_CHARTYPEBITS])(pCurChar, iRotation);
+ return FX_MAX(dwRet1, dwRet2);
+}
+void CFX_TxtBreak::EndBreak_UpdateArabicShapes()
+{
+ FXSYS_assert(m_bArabicShapes);
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ if (iCount < 2) {
+ return;
+ }
+ FX_INT32 &iLineWidth = m_pCurLine->m_iWidth;
+ CFX_Char *pCur, *pNext;
+ pCur = m_pCurLine->GetCharPtr(0);
+ FX_BOOL bPrevNum = (pCur->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
+ pCur = m_pCurLine->GetCharPtr(1);
+ FX_WCHAR wch, wForm;
+ FX_BOOL bNextNum;
+ FX_INT32 i = 1, iCharWidth, iRotation;
+ do {
+ i ++;
+ if (i < iCount) {
+ pNext = m_pCurLine->GetCharPtr(i);
+ bNextNum = (pNext->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
+ } else {
+ pNext = NULL;
+ bNextNum = FALSE;
+ }
+ wch = pCur->m_wCharCode;
+ if (wch == L'.') {
+ if (bPrevNum && bNextNum) {
+ iRotation = m_iRotation;
+ if (m_bVertical && (pCur->m_dwCharProps & 0x8000) != 0) {
+ iRotation = ((iRotation + 1) & 0x03);
+ }
+ wForm = wch == L'.' ? 0x066B : 0x066C;
+ iLineWidth -= pCur->m_iCharWidth;
+ if (m_bCombText) {
+ iCharWidth = m_iCombWidth;
+ } else {
+ if (m_bVertical != FX_IsOdd(iRotation)) {
+ iCharWidth = 1000;
+ } else if (!m_pFont->GetCharWidth(wForm, iCharWidth, FALSE)) {
+ iCharWidth = m_iDefChar;
+ }
+ iCharWidth *= m_iFontSize;
+ iCharWidth = iCharWidth * m_iHorScale / 100;
+ }
+ pCur->m_iCharWidth = iCharWidth;
+ iLineWidth += iCharWidth;
+ }
+ }
+ bPrevNum = (pCur->m_dwCharStyles & FX_TXTCHARSTYLE_ArabicIndic) != 0;
+ pCur = pNext;
+ } while (i < iCount);
+}
+FX_BOOL CFX_TxtBreak::EndBreak_SplitLine(CFX_TxtLine *pNextLine, FX_BOOL bAllChars, FX_DWORD dwStatus)
+{
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ FX_BOOL bDone = FALSE;
+ CFX_Char *pTC;
+ if (!m_bSingleLine && m_pCurLine->m_iWidth > m_iLineWidth + m_iTolerance) {
+ pTC = m_pCurLine->GetCharPtr(iCount - 1);
+ switch (pTC->GetCharType()) {
+ case FX_CHARTYPE_Tab:
+ case FX_CHARTYPE_Control:
+ break;
+ case FX_CHARTYPE_Space:
+ if ((m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0) {
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ }
+ break;
+ default:
+ SplitTextLine(m_pCurLine, pNextLine, !m_bPagination && bAllChars);
+ bDone = TRUE;
+ break;
+ }
+ }
+ iCount = m_pCurLine->CountChars();
+ CFX_TxtPieceArray *pCurPieces = m_pCurLine->m_pLinePieces;
+ CFX_TxtPiece tp;
+ if (m_bPagination) {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_iWidth = m_pCurLine->m_iWidth;
+ tp.m_iStartChar = 0;
+ tp.m_iChars = iCount;
+ tp.m_pChars = m_pCurLine->m_pLineChars;
+ tp.m_pUserData = m_pUserData;
+ pTC = m_pCurLine->GetCharPtr(0);
+ tp.m_dwCharStyles = pTC->m_dwCharStyles;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ pCurPieces->Add(tp);
+ m_pCurLine = pNextLine;
+ m_dwCharType = 0;
+ return TRUE;
+ }
+ if (bAllChars && !bDone) {
+ FX_INT32 iEndPos = m_pCurLine->m_iWidth;
+ GetBreakPos(*m_pCurLine->m_pLineChars, iEndPos, bAllChars, TRUE);
+ }
+ return FALSE;
+}
+void CFX_TxtBreak::EndBreak_BidiLine(CFX_TPOArray &tpos, FX_DWORD dwStatus)
+{
+ CFX_TxtPiece tp;
+ FX_TPO tpo;
+ CFX_TxtChar *pTC;
+ FX_INT32 i, j;
+ CFX_TxtCharArray &chars = *m_pCurLine->m_pLineChars;
+ FX_INT32 iCount = m_pCurLine->CountChars();
+ FX_BOOL bDone = (m_pCurLine->m_iArabicChars > 0 || m_bCurRTL);
+ if (!m_bPagination && bDone) {
+ FX_INT32 iBidiNum = 0;
+ for (i = 0; i < iCount; i ++) {
+ pTC = chars.GetDataPtr(i);
+ pTC->m_iBidiPos = i;
+ if (pTC->GetCharType() != FX_CHARTYPE_Control) {
+ iBidiNum = i;
+ }
+ if (i == 0) {
+ pTC->m_iBidiLevel = 1;
+ }
+ }
+ FX_BidiLine(chars, iBidiNum + 1, m_bCurRTL ? 1 : 0);
+ }
+ CFX_TxtPieceArray *pCurPieces = m_pCurLine->m_pLinePieces;
+ if (!m_bPagination && (bDone || (m_dwLayoutStyles & FX_TXTLAYOUTSTYLE_MutipleFormat) != 0)) {
+ tp.m_dwStatus = FX_TXTBREAK_PieceBreak;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_pChars = m_pCurLine->m_pLineChars;
+ FX_INT32 iBidiLevel = -1, iCharWidth;
+ i = 0, j = -1;
+ while (i < iCount) {
+ pTC = chars.GetDataPtr(i);
+ if (iBidiLevel < 0) {
+ iBidiLevel = pTC->m_iBidiLevel;
+ tp.m_iWidth = 0;
+ tp.m_iBidiLevel = iBidiLevel;
+ tp.m_iBidiPos = pTC->m_iBidiOrder;
+ tp.m_dwCharStyles = pTC->m_dwCharStyles;
+ tp.m_pUserData = pTC->m_pUserData;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ tp.m_dwStatus = FX_TXTBREAK_PieceBreak;
+ }
+ if (iBidiLevel != pTC->m_iBidiLevel || pTC->m_dwStatus != 0) {
+ if (iBidiLevel == pTC->m_iBidiLevel) {
+ tp.m_dwStatus = pTC->m_dwStatus;
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ tp.m_iWidth += iCharWidth;
+ }
+ i ++;
+ }
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tp.m_iStartPos += tp.m_iWidth;
+ tp.m_iStartChar = i;
+ tpo.index = ++ j;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ iBidiLevel = -1;
+ } else {
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ tp.m_iWidth += iCharWidth;
+ }
+ i ++;
+ }
+ }
+ if (i > tp.m_iStartChar) {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iChars = i - tp.m_iStartChar;
+ pCurPieces->Add(tp);
+ tpo.index = ++ j;
+ tpo.pos = tp.m_iBidiPos;
+ tpos.Add(tpo);
+ }
+ if (j > -1) {
+ if (j > 0) {
+ FX_TEXTLAYOUT_PieceSort(tpos, 0, j);
+ FX_INT32 iStartPos = 0;
+ for (i = 0; i <= j; i ++) {
+ tpo = tpos.GetAt(i);
+ CFX_TxtPiece &ttp = pCurPieces->GetAt(tpo.index);
+ ttp.m_iStartPos = iStartPos;
+ iStartPos += ttp.m_iWidth;
+ }
+ }
+ CFX_TxtPiece &ttp = pCurPieces->GetAt(j);
+ ttp.m_dwStatus = dwStatus;
+ }
+ } else {
+ tp.m_dwStatus = dwStatus;
+ tp.m_iStartPos = m_pCurLine->m_iStart;
+ tp.m_iWidth = m_pCurLine->m_iWidth;
+ tp.m_iStartChar = 0;
+ tp.m_iChars = iCount;
+ tp.m_pChars = m_pCurLine->m_pLineChars;
+ tp.m_pUserData = m_pUserData;
+ pTC = chars.GetDataPtr(0);
+ tp.m_dwCharStyles = pTC->m_dwCharStyles;
+ tp.m_iHorizontalScale = pTC->m_iHorizontalScale;
+ tp.m_iVerticalScale = pTC->m_iVertialScale;
+ pCurPieces->Add(tp);
+ tpo.index = 0;
+ tpo.pos = 0;
+ tpos.Add(tpo);
+ }
+}
+void CFX_TxtBreak::EndBreak_Alignment(CFX_TPOArray &tpos, FX_BOOL bAllChars, FX_DWORD dwStatus)
+{
+ FX_INT32 iNetWidth = m_pCurLine->m_iWidth, iGapChars = 0, iCharWidth;
+ CFX_TxtPieceArray *pCurPieces = m_pCurLine->m_pLinePieces;
+ FX_INT32 i, j, iCount = pCurPieces->GetSize();
+ FX_BOOL bFind = FALSE;
+ FX_TPO tpo;
+ CFX_TxtChar *pTC;
+ FX_DWORD dwCharType;
+ for (i = iCount - 1; i > -1; i --) {
+ tpo = tpos.GetAt(i);
+ CFX_TxtPiece &ttp = pCurPieces->GetAt(tpo.index);
+ if (!bFind) {
+ iNetWidth = ttp.GetEndPos();
+ }
+ FX_BOOL bArabic = FX_IsOdd(ttp.m_iBidiLevel);
+ j = bArabic ? 0 : ttp.m_iChars - 1;
+ while (j > -1 && j < ttp.m_iChars) {
+ pTC = ttp.GetCharPtr(j);
+ if (pTC->m_nBreakType == FX_LBT_DIRECT_BRK) {
+ iGapChars ++;
+ }
+ if (!bFind || !bAllChars) {
+ dwCharType = pTC->GetCharType();
+ if (dwCharType == FX_CHARTYPE_Space || dwCharType == FX_CHARTYPE_Control) {
+ if (!bFind) {
+ iCharWidth = pTC->m_iCharWidth;
+ if (bAllChars && iCharWidth > 0) {
+ iNetWidth -= iCharWidth;
+ }
+ }
+ } else {
+ bFind = TRUE;
+ if (!bAllChars) {
+ break;
+ }
+ }
+ }
+ j += bArabic ? 1 : -1;
+ }
+ if (!bAllChars && bFind) {
+ break;
+ }
+ }
+ FX_INT32 iOffset = m_iLineWidth - iNetWidth;
+ FX_INT32 iLowerAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_LowerMask);
+ FX_INT32 iHigherAlignment = (m_iCurAlignment & FX_TXTLINEALIGNMENT_HigherMask);
+ if (iGapChars > 0 && (iHigherAlignment == FX_TXTLINEALIGNMENT_Distributed || (iHigherAlignment == FX_TXTLINEALIGNMENT_Justified && dwStatus != FX_TXTBREAK_ParagraphBreak))) {
+ FX_INT32 iStart = -1;
+ for (i = 0; i < iCount; i ++) {
+ tpo = tpos.GetAt(i);
+ CFX_TxtPiece &ttp = pCurPieces->GetAt(tpo.index);
+ if (iStart < -1) {
+ iStart = ttp.m_iStartPos;
+ } else {
+ ttp.m_iStartPos = iStart;
+ }
+ FX_INT32 k;
+ for (j = 0; j < ttp.m_iChars; j ++) {
+ pTC = ttp.GetCharPtr(j);
+ if (pTC->m_nBreakType != FX_LBT_DIRECT_BRK || pTC->m_iCharWidth < 0) {
+ continue;
+ }
+ k = iOffset / iGapChars;
+ pTC->m_iCharWidth += k;
+ ttp.m_iWidth += k;
+ iOffset -= k;
+ iGapChars --;
+ if (iGapChars < 1) {
+ break;
+ }
+ }
+ iStart += ttp.m_iWidth;
+ }
+ } else if (iLowerAlignment > FX_TXTLINEALIGNMENT_Left) {
+ if (iLowerAlignment == FX_TXTLINEALIGNMENT_Center) {
+ iOffset /= 2;
+ }
+ if (iOffset > 0) {
+ for (i = 0; i < iCount; i ++) {
+ CFX_TxtPiece &ttp = pCurPieces->GetAt(i);
+ ttp.m_iStartPos += iOffset;
+ }
+ }
+ }
+}
+FX_DWORD CFX_TxtBreak::EndBreak(FX_DWORD dwStatus)
+{
+ FXSYS_assert(dwStatus >= FX_TXTBREAK_PieceBreak && dwStatus <= FX_TXTBREAK_PageBreak);
+ CFX_TxtPieceArray *pCurPieces = m_pCurLine->m_pLinePieces;
+ FX_INT32 iCount = pCurPieces->GetSize();
+ if (iCount > 0) {
+ CFX_TxtPiece *pLastPiece = pCurPieces->GetPtrAt(-- iCount);
+ if (dwStatus > FX_TXTBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ } else {
+ CFX_TxtLine *pLastLine = GetTxtLine(TRUE);
+ if (pLastLine != NULL) {
+ pCurPieces = pLastLine->m_pLinePieces;
+ iCount = pCurPieces->GetSize();
+ if (iCount -- > 0) {
+ CFX_TxtPiece *pLastPiece = pCurPieces->GetPtrAt(iCount);
+ if (dwStatus > FX_TXTBREAK_PieceBreak) {
+ pLastPiece->m_dwStatus = dwStatus;
+ } else {
+ dwStatus = pLastPiece->m_dwStatus;
+ }
+ return dwStatus;
+ }
+ return FX_TXTBREAK_None;
+ }
+ iCount = m_pCurLine->CountChars();
+ if (iCount < 1) {
+ return FX_TXTBREAK_None;
+ }
+ if (!m_bPagination) {
+ CFX_TxtChar *pTC = m_pCurLine->GetCharPtr(iCount - 1);
+ pTC->m_dwStatus = dwStatus;
+ }
+ if (dwStatus <= FX_TXTBREAK_PieceBreak) {
+ return dwStatus;
+ }
+ }
+ m_iReady = (m_pCurLine == m_pTxtLine1) ? 1 : 2;
+ CFX_TxtLine *pNextLine = (m_pCurLine == m_pTxtLine1) ? m_pTxtLine2 : m_pTxtLine1;
+ FX_BOOL bAllChars = (m_iCurAlignment > FX_TXTLINEALIGNMENT_Right);
+ CFX_TPOArray tpos;
+ CFX_Char *pTC;
+ if (m_bArabicShapes) {
+ EndBreak_UpdateArabicShapes();
+ }
+ if (EndBreak_SplitLine(pNextLine, bAllChars, dwStatus)) {
+ goto EndBreak_Ret;
+ }
+ EndBreak_BidiLine(tpos, dwStatus);
+ if (!m_bPagination && m_iCurAlignment > FX_TXTLINEALIGNMENT_Left) {
+ EndBreak_Alignment(tpos, bAllChars, dwStatus);
+ }
+EndBreak_Ret:
+ m_pCurLine = pNextLine;
+ pTC = GetLastChar(0, FALSE);
+ m_dwCharType = pTC == NULL ? 0 : pTC->GetCharType();
+ if (dwStatus == FX_TXTBREAK_ParagraphBreak) {
+ m_iArabicContext = m_iCurArabicContext = 1;
+ ResetArabicContext();
+ }
+ return dwStatus;
+}
+FX_INT32 CFX_TxtBreak::GetBreakPos(CFX_TxtCharArray &ca, FX_INT32 &iEndPos, FX_BOOL bAllChars, FX_BOOL bOnlyBrk)
+{
+ FX_INT32 iLength = ca.GetSize() - 1;
+ if (iLength < 1) {
+ return iLength;
+ }
+ FX_INT32 iBreak = -1, iBreakPos = -1, iIndirect = -1, iIndirectPos = -1, iLast = -1, iLastPos = -1;
+ if (m_bSingleLine || iEndPos <= m_iLineWidth) {
+ if (!bAllChars) {
+ return iLength;
+ }
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ }
+ FX_BOOL bSpaceBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_SpaceBreak) != 0;
+ FX_BOOL bNumberBreak = (m_dwPolicies & FX_TXTBREAKPOLICY_NumberBreak) != 0;
+ FX_LINEBREAKTYPE eType;
+ FX_DWORD nCodeProp, nCur, nNext;
+ CFX_Char *pCur = ca.GetDataPtr(iLength --);
+ if (bAllChars) {
+ pCur->m_nBreakType = FX_LBT_UNKNOWN;
+ }
+ nCodeProp = pCur->m_dwCharProps;
+ nNext = nCodeProp & 0x003F;
+ FX_INT32 iCharWidth = pCur->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ while (iLength >= 0) {
+ pCur = ca.GetDataPtr(iLength);
+ nCodeProp = pCur->m_dwCharProps;
+ nCur = nCodeProp & 0x003F;
+ if (nCur == FX_CBP_SP) {
+ if (nNext == FX_CBP_SP) {
+ eType = bSpaceBreak ? FX_LBT_DIRECT_BRK : FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE *)gs_FX_LineBreak_PairTable + (nCur << 5) + nNext);
+ }
+ } else if (bNumberBreak && nCur == FX_CBP_NU && nNext == FX_CBP_NU) {
+ eType = FX_LBT_DIRECT_BRK;
+ } else {
+ if (nNext == FX_CBP_SP) {
+ eType = FX_LBT_PROHIBITED_BRK;
+ } else {
+ eType = *((const FX_LINEBREAKTYPE *)gs_FX_LineBreak_PairTable + (nCur << 5) + nNext);
+ }
+ }
+ if (bAllChars) {
+ pCur->m_nBreakType = (FX_BYTE)eType;
+ }
+ if (!bOnlyBrk) {
+ if (m_bSingleLine || iEndPos <= m_iLineWidth || (nCur == FX_CBP_SP && !bSpaceBreak)) {
+ if (eType == FX_LBT_DIRECT_BRK && iBreak < 0) {
+ iBreak = iLength;
+ iBreakPos = iEndPos;
+ if (!bAllChars) {
+ return iLength;
+ }
+ } else if (eType == FX_LBT_INDIRECT_BRK && iIndirect < 0) {
+ iIndirect = iLength;
+ iIndirectPos = iEndPos;
+ }
+ if (iLast < 0) {
+ iLast = iLength;
+ iLastPos = iEndPos;
+ }
+ }
+ iCharWidth = pCur->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iEndPos -= iCharWidth;
+ }
+ }
+ nNext = nCodeProp & 0x003F;
+ iLength --;
+ }
+ if (bOnlyBrk) {
+ return 0;
+ }
+ if (iBreak > -1) {
+ iEndPos = iBreakPos;
+ return iBreak;
+ }
+ if (iIndirect > -1) {
+ iEndPos = iIndirectPos;
+ return iIndirect;
+ }
+ if (iLast > -1) {
+ iEndPos = iLastPos;
+ return iLast;
+ }
+ return 0;
+}
+void CFX_TxtBreak::SplitTextLine(CFX_TxtLine *pCurLine, CFX_TxtLine *pNextLine, FX_BOOL bAllChars)
+{
+ FXSYS_assert(pCurLine != NULL && pNextLine != NULL);
+ FX_INT32 iCount = pCurLine->CountChars();
+ if (iCount < 2) {
+ return;
+ }
+ FX_INT32 iEndPos = pCurLine->m_iWidth;
+ CFX_TxtCharArray &curChars = *pCurLine->m_pLineChars;
+ FX_INT32 iCharPos = GetBreakPos(curChars, iEndPos, bAllChars, FALSE);
+ if (iCharPos < 0) {
+ iCharPos = 0;
+ }
+ iCharPos ++;
+ if (iCharPos >= iCount) {
+ pNextLine->RemoveAll(TRUE);
+ CFX_Char *pTC = curChars.GetDataPtr(iCharPos - 1);
+ pTC->m_nBreakType = FX_LBT_UNKNOWN;
+ return;
+ }
+ CFX_TxtCharArray &nextChars = *pNextLine->m_pLineChars;
+ int cur_size = curChars.GetSize();
+ nextChars.SetSize(cur_size - iCharPos);
+ FXSYS_memcpy(nextChars.GetData(), curChars.GetDataPtr(iCharPos), (cur_size - iCharPos) * sizeof(CFX_TxtChar));
+ iCount -= iCharPos;
+ cur_size = curChars.GetSize();
+ curChars.RemoveAt(cur_size - iCount, iCount);
+ pCurLine->m_iWidth = iEndPos;
+ CFX_TxtChar *pTC = curChars.GetDataPtr(iCharPos - 1);
+ pTC->m_nBreakType = FX_LBT_UNKNOWN;
+ iCount = nextChars.GetSize();
+ FX_INT32 iCharWidth, iWidth = 0;
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pTC = nextChars.GetDataPtr(i);
+ if (pTC->GetCharType() >= FX_CHARTYPE_ArabicAlef) {
+ pCurLine->m_iArabicChars --;
+ pNextLine->m_iArabicChars ++;
+ }
+ iCharWidth = pTC->m_iCharWidth;
+ if (iCharWidth > 0) {
+ iWidth += iCharWidth;
+ }
+ if (m_bPagination) {
+ continue;
+ }
+ pTC->m_dwStatus = 0;
+ }
+ pNextLine->m_iWidth = iWidth;
+}
+FX_INT32 CFX_TxtBreak::CountBreakChars() const
+{
+ CFX_TxtLine *pTxtLine = GetTxtLine(TRUE);
+ return pTxtLine == NULL ? 0 : pTxtLine->CountChars();
+}
+FX_INT32 CFX_TxtBreak::CountBreakPieces() const
+{
+ CFX_TxtPieceArray *pTxtPieces = GetTxtPieces(TRUE);
+ if (pTxtPieces == NULL) {
+ return 0;
+ }
+ return pTxtPieces->GetSize();
+}
+const CFX_TxtPiece* CFX_TxtBreak::GetBreakPiece(FX_INT32 index) const
+{
+ CFX_TxtPieceArray *pTxtPieces = GetTxtPieces(TRUE);
+ if (pTxtPieces == NULL) {
+ return NULL;
+ }
+ if (index < 0 || index >= pTxtPieces->GetSize()) {
+ return NULL;
+ }
+ return pTxtPieces->GetPtrAt(index);
+}
+void CFX_TxtBreak::ClearBreakPieces()
+{
+ CFX_TxtLine *pTxtLine = GetTxtLine(TRUE);
+ if (pTxtLine != NULL) {
+ pTxtLine->RemoveAll(TRUE);
+ }
+ m_iReady = 0;
+}
+void CFX_TxtBreak::Reset()
+{
+ m_dwCharType = 0;
+ m_iArabicContext = m_iCurArabicContext = 1;
+ ResetArabicContext();
+ m_pTxtLine1->RemoveAll(TRUE);
+ m_pTxtLine2->RemoveAll(TRUE);
+}
+typedef struct _FX_FORMCHAR {
+ FX_WORD wch;
+ FX_WORD wForm;
+ FX_INT32 iWidth;
+} FX_FORMCHAR, * FX_LPFORMCHAR;
+typedef FX_FORMCHAR const * FX_LPCFORMCHAR;
+FX_INT32 CFX_TxtBreak::GetDisplayPos(FX_LPCTXTRUN pTxtRun, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode , CFX_WideString *pWSForms , FX_AdjustCharDisplayPos pAdjustPos ) const
+{
+ if (pTxtRun == NULL || pTxtRun->iLength < 1) {
+ return 0;
+ }
+ IFX_TxtAccess *pAccess = pTxtRun->pAccess;
+ FX_LPVOID pIdentity = pTxtRun->pIdentity;
+ FX_LPCWSTR pStr = pTxtRun->pStr;
+ FX_INT32 *pWidths = pTxtRun->pWidths;
+ FX_INT32 iLength = pTxtRun->iLength - 1;
+ IFX_Font *pFont = pTxtRun->pFont;
+ FX_DWORD dwStyles = pTxtRun->dwStyles;
+ CFX_RectF rtText(*pTxtRun->pRect);
+ FX_BOOL bRTLPiece = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
+ FX_BOOL bArabicNumber = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_ArabicNumber) != 0;
+ FX_BOOL bArabicComma = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_ArabicComma) != 0;
+ FX_FLOAT fFontSize = pTxtRun->fFontSize;
+ FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f);
+ FX_INT32 iAscent = pFont->GetAscent();
+ FX_INT32 iDescent = pFont->GetDescent();
+ FX_INT32 iMaxHeight = iAscent - iDescent;
+ FX_FLOAT fFontHeight = fFontSize;
+ FX_FLOAT fAscent = fFontHeight * (FX_FLOAT)iAscent / (FX_FLOAT)iMaxHeight;
+ FX_FLOAT fDescent = fFontHeight * (FX_FLOAT)iDescent / (FX_FLOAT)iMaxHeight;
+ FX_BOOL bVerticalDoc = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bVerticalChar = (dwStyles & FX_TXTLAYOUTSTYLE_VerticalChars) != 0;
+ FX_INT32 iRotation = GetLineRotation(dwStyles) + pTxtRun->iCharRotation;
+ FX_INT32 iCharRotation;
+ FX_WCHAR wch, wPrev = 0xFEFF, wNext, wForm, wLast = 0xFEFF;
+ FX_INT32 iWidth, iCharWidth, iCharHeight;
+ FX_FLOAT fX, fY, fCharWidth, fCharHeight;
+ FX_INT32 iHorScale = pTxtRun->iHorizontalScale;
+ FX_INT32 iVerScale = pTxtRun->iVerticalScale;
+ FX_BOOL bSkipSpace = pTxtRun->bSkipSpace;
+ FX_BOOL bEmptyChar, bShadda = FALSE, bLam = FALSE;
+ FX_DWORD dwProps, dwCharType;
+ FX_FORMCHAR formChars[3];
+ FX_FLOAT fYBase;
+ fX = rtText.left;
+ if (bVerticalDoc) {
+ fX += (rtText.width - fFontSize) / 2.0f;
+ fYBase = bRTLPiece ? rtText.bottom() : rtText.top;
+ fY = fYBase;
+ } else {
+ if (bRTLPiece) {
+ fX = rtText.right();
+ }
+ fYBase = rtText.top + (rtText.height - fFontSize) / 2.0f;
+ fY = fYBase + fAscent;
+ }
+ FX_INT32 iCount = 0, iNext, iForms;
+ for (FX_INT32 i = 0; i <= iLength; i ++) {
+ if (pAccess != NULL) {
+ wch = pAccess->GetChar(pIdentity, i);
+ iWidth = pAccess->GetWidth(pIdentity, i);
+ } else {
+ wch = *pStr ++;
+ iWidth = *pWidths ++;
+ }
+ dwProps = FX_GetUnicodeProperties(wch);
+ dwCharType = (dwProps & FX_CHARTYPEBITSMASK);
+ if (dwCharType == FX_CHARTYPE_ArabicAlef && iWidth == 0) {
+ wPrev = 0xFEFF;
+ wLast = wch;
+ continue;
+ }
+ if (dwCharType >= FX_CHARTYPE_ArabicAlef) {
+ if (i < iLength) {
+ if (pAccess != NULL) {
+ iNext = i + 1;
+ while (iNext <= iLength) {
+ wNext = pAccess->GetChar(pIdentity, iNext);
+ dwProps = FX_GetUnicodeProperties(wNext);
+ if ((dwProps & FX_CHARTYPEBITSMASK) != FX_CHARTYPE_Combination) {
+ break;
+ }
+ iNext ++;
+ }
+ if (iNext > iLength) {
+ wNext = 0xFEFF;
+ }
+ } else {
+ FX_INT32 j = -1;
+ do {
+ j ++;
+ if (i + j >= iLength) {
+ break;
+ }
+ wNext = pStr[j];
+ dwProps = FX_GetUnicodeProperties(wNext);
+ } while ((dwProps & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_Combination);
+ if (i + j >= iLength) {
+ wNext = 0xFEFF;
+ }
+ }
+ } else {
+ wNext = 0xFEFF;
+ }
+ wForm = m_pArabicChar->GetFormChar(wch, wPrev, wNext);
+ bLam = (wPrev == 0x0644 && wch == 0x0644 && wNext == 0x0647);
+ } else if (dwCharType == FX_CHARTYPE_Combination) {
+ wForm = wch;
+ if (wch >= 0x064C && wch <= 0x0651) {
+ if (bShadda) {
+ wForm = 0xFEFF;
+ bShadda = FALSE;
+ } else {
+ wNext = 0xFEFF;
+ if (pAccess != NULL) {
+ iNext = i + 1;
+ if (iNext <= iLength) {
+ wNext = pAccess->GetChar(pIdentity, iNext);
+ }
+ } else {
+ if (i < iLength) {
+ wNext = *pStr;
+ }
+ }
+ if (wch == 0x0651) {
+ if (wNext >= 0x064C && wNext <= 0x0650) {
+ wForm = FX_GetArabicFromShaddaTable(wNext);
+ bShadda = TRUE;
+ }
+ } else {
+ if (wNext == 0x0651) {
+ wForm = FX_GetArabicFromShaddaTable(wch);
+ bShadda = TRUE;
+ }
+ }
+ }
+ } else {
+ bShadda = FALSE;
+ }
+ } else if (dwCharType == FX_CHARTYPE_Numeric) {
+ wForm = wch;
+ if (bArabicNumber) {
+ wForm += 0x0630;
+ }
+ } else if (wch == L'.') {
+ wForm = wch;
+ if (bArabicNumber) {
+ wNext = 0xFEFF;
+ if (pAccess != NULL) {
+ iNext = i + 1;
+ if (iNext <= iLength) {
+ wNext = pAccess->GetChar(pIdentity, iNext);
+ }
+ } else {
+ if (i < iLength) {
+ wNext = *pStr;
+ }
+ }
+ if (wNext >= L'0' && wNext <= L'9') {
+ wForm = 0x066B;
+ }
+ }
+ } else if (wch == L',') {
+ wForm = wch;
+ if (bArabicComma) {
+ wForm = 0x060C;
+ }
+ } else if (bRTLPiece || bVerticalChar) {
+ wForm = FX_GetMirrorChar(wch, dwProps, bRTLPiece, bVerticalChar);
+ } else {
+ wForm = wch;
+ }
+ if (dwCharType != FX_CHARTYPE_Combination) {
+ bShadda = FALSE;
+ }
+ if (dwCharType < FX_CHARTYPE_ArabicAlef) {
+ bLam = FALSE;
+ }
+ dwProps = FX_GetUnicodeProperties(wForm);
+ iCharRotation = iRotation;
+ if (bVerticalChar && (dwProps & 0x8000) != 0) {
+ iCharRotation ++;
+ }
+ iCharRotation %= 4;
+ bEmptyChar = (dwCharType >= FX_CHARTYPE_Tab && dwCharType <= FX_CHARTYPE_Control);
+ if (wForm == 0xFEFF) {
+ bEmptyChar = TRUE;
+ }
+ iForms = bLam ? 3 : 1;
+ iCount += (bEmptyChar && bSkipSpace) ? 0 : iForms;
+ if (pCharPos == NULL) {
+ if (iWidth > 0) {
+ wPrev = wch;
+ }
+ wLast = wch;
+ continue;
+ }
+ iCharWidth = iWidth;
+ if (iCharWidth < 0) {
+ iCharWidth = -iCharWidth;
+ }
+ iCharWidth /= iFontSize;
+ formChars[0].wch = wch;
+ formChars[0].wForm = wForm;
+ formChars[0].iWidth = iCharWidth;
+ if (bLam) {
+ formChars[1].wForm = 0x0651;
+ iCharWidth = 0;
+ pFont->GetCharWidth(0x0651, iCharWidth, FALSE);
+ formChars[1].iWidth = iCharWidth;
+ formChars[2].wForm = 0x0670;
+ iCharWidth = 0;
+ pFont->GetCharWidth(0x0670, iCharWidth, FALSE);
+ formChars[2].iWidth = iCharWidth;
+ }
+ for (FX_INT32 j = 0; j < iForms; j ++) {
+ wForm = (FX_WCHAR)formChars[j].wForm;
+ iCharWidth = formChars[j].iWidth;
+ if (j > 0) {
+ dwCharType = FX_CHARTYPE_Combination;
+ wch = wForm;
+ wLast = (FX_WCHAR)formChars[j - 1].wForm;
+ }
+ if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
+ pCharPos->m_GlyphIndex = bCharCode ? wch : pFont->GetGlyphIndex(wForm, FALSE);
+ pCharPos->m_ExtGID = pCharPos->m_GlyphIndex;
+ pCharPos->m_FontCharWidth = iCharWidth;
+ if (pWSForms) {
+ *pWSForms += wForm;
+ }
+ }
+ if (bVerticalDoc) {
+ iCharHeight = iCharWidth;
+ iCharWidth = 1000;
+ } else {
+ iCharHeight = 1000;
+ }
+ fCharWidth = fFontSize * iCharWidth / 1000.0f;
+ fCharHeight = fFontSize * iCharHeight / 1000.0f;
+ if (bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY -= fCharHeight;
+ } else {
+ fX -= fCharWidth;
+ }
+ }
+ if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
+ pCharPos->m_OriginX = fX;
+ pCharPos->m_OriginY = fY;
+ if ((dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0) {
+ FX_INT32 iFormWidth = iCharWidth;
+ pFont->GetCharWidth(wForm, iFormWidth, FALSE);
+ FX_FLOAT fOffset = fFontSize * (iCharWidth - iFormWidth) / 2000.0f;
+ if (bVerticalDoc) {
+ pCharPos->m_OriginY += fOffset;
+ } else {
+ pCharPos->m_OriginX += fOffset;
+ }
+ }
+ if (dwCharType == FX_CHARTYPE_Combination) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wForm, rtBBox, FALSE)) {
+ pCharPos->m_OriginY = fYBase + fFontSize - fFontSize * (FX_FLOAT)rtBBox.height / (FX_FLOAT)iMaxHeight;
+ }
+ if (wForm == wch && wLast != 0xFEFF) {
+ FX_DWORD dwLastProps = FX_GetUnicodeProperties(wLast);
+ if ((dwLastProps & FX_CHARTYPEBITSMASK) == FX_CHARTYPE_Combination) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wLast, rtBBox, FALSE)) {
+ pCharPos->m_OriginY -= fFontSize * rtBBox.height / iMaxHeight;
+ }
+ }
+ }
+ }
+ CFX_PointF ptOffset;
+ ptOffset.Reset();
+ FX_BOOL bAdjusted = FALSE;
+ if (pAdjustPos) {
+ bAdjusted = pAdjustPos(wForm, bCharCode, pFont, fFontSize, bVerticalChar, ptOffset);
+ }
+ if (!bAdjusted && bVerticalChar && (dwProps & 0x00010000) != 0) {
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wForm, rtBBox, FALSE)) {
+ ptOffset.x = fFontSize * (850 - rtBBox.right()) / iMaxHeight;
+ ptOffset.y = fFontSize * (iAscent - rtBBox.top - 150) / iMaxHeight;
+ }
+ }
+ pCharPos->m_OriginX += ptOffset.x;
+ pCharPos->m_OriginY -= ptOffset.y;
+ }
+ if (!bRTLPiece && dwCharType != FX_CHARTYPE_Combination) {
+ if (bVerticalDoc) {
+ fY += fCharHeight;
+ } else {
+ fX += fCharWidth;
+ }
+ }
+ if (!bEmptyChar || (bEmptyChar && !bSkipSpace)) {
+ pCharPos->m_bGlyphAdjust = TRUE;
+ if (bVerticalDoc) {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ pCharPos->m_OriginY += fAscent;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -= fDescent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY += fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += fAscent;
+ }
+ } else {
+ if (iCharRotation == 0) {
+ pCharPos->m_AdjustMatrix[0] = -1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = 1;
+ } else if (iCharRotation == 1) {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = -1;
+ pCharPos->m_AdjustMatrix[2] = -1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX -= fDescent;
+ pCharPos->m_OriginY -= fAscent + fDescent;
+ } else if (iCharRotation == 2) {
+ pCharPos->m_AdjustMatrix[0] = 1;
+ pCharPos->m_AdjustMatrix[1] = 0;
+ pCharPos->m_AdjustMatrix[2] = 0;
+ pCharPos->m_AdjustMatrix[3] = -1;
+ pCharPos->m_OriginX += fCharWidth;
+ pCharPos->m_OriginY -= fAscent;
+ } else {
+ pCharPos->m_AdjustMatrix[0] = 0;
+ pCharPos->m_AdjustMatrix[1] = 1;
+ pCharPos->m_AdjustMatrix[2] = 1;
+ pCharPos->m_AdjustMatrix[3] = 0;
+ pCharPos->m_OriginX += fAscent;
+ }
+ }
+ if (iHorScale != 100 || iVerScale != 100) {
+ pCharPos->m_AdjustMatrix[0] = pCharPos->m_AdjustMatrix[0] * iHorScale / 100.0f;
+ pCharPos->m_AdjustMatrix[1] = pCharPos->m_AdjustMatrix[1] * iHorScale / 100.0f;
+ pCharPos->m_AdjustMatrix[2] = pCharPos->m_AdjustMatrix[2] * iVerScale / 100.0f;
+ pCharPos->m_AdjustMatrix[3] = pCharPos->m_AdjustMatrix[3] * iVerScale / 100.0f;
+ }
+ pCharPos ++;
+ }
+ }
+ if (iWidth > 0) {
+ wPrev = (FX_WCHAR)formChars[0].wch;
+ }
+ wLast = wch;
+ }
+ return iCount;
+}
+FX_INT32 CFX_TxtBreak::GetCharRects(FX_LPCTXTRUN pTxtRun, CFX_RectFArray &rtArray, FX_BOOL bCharBBox ) const
+{
+ if (pTxtRun == NULL || pTxtRun->iLength < 1) {
+ return 0;
+ }
+ IFX_TxtAccess *pAccess = pTxtRun->pAccess;
+ FX_LPVOID pIdentity = pTxtRun->pIdentity;
+ FX_LPCWSTR pStr = pTxtRun->pStr;
+ FX_INT32 *pWidths = pTxtRun->pWidths;
+ FX_INT32 iLength = pTxtRun->iLength;
+ CFX_RectF rect(*pTxtRun->pRect);
+ FX_BOOL bRTLPiece = (pTxtRun->dwCharStyles & FX_TXTCHARSTYLE_OddBidiLevel) != 0;
+ FX_FLOAT fFontSize = pTxtRun->fFontSize;
+ FX_INT32 iFontSize = FXSYS_round(fFontSize * 20.0f);
+ FX_FLOAT fScale = fFontSize / 1000.0f;
+ IFX_Font *pFont = pTxtRun->pFont;
+ if (pFont == NULL) {
+ bCharBBox = FALSE;
+ }
+ CFX_Rect bbox;
+ bbox.Set(0, 0, 0, 0);
+ if (bCharBBox) {
+ bCharBBox = pFont->GetBBox(bbox);
+ }
+ FX_FLOAT fLeft = FX_MAX(0, bbox.left * fScale);
+ FX_FLOAT fHeight = FXSYS_fabs(bbox.height * fScale);
+ rtArray.RemoveAll();
+ rtArray.SetSize(iLength);
+ FX_BOOL bVertical = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_VerticalLayout) != 0;
+ FX_BOOL bSingleLine = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_SingleLine) != 0;
+ FX_BOOL bCombText = (pTxtRun->dwStyles & FX_TXTLAYOUTSTYLE_CombText) != 0;
+ FX_WCHAR wch, wLineBreakChar = pTxtRun->wLineBreakChar;
+ FX_INT32 iCharSize;
+ FX_FLOAT fCharSize, fStart;
+ if (bVertical) {
+ fStart = bRTLPiece ? rect.bottom() : rect.top;
+ } else {
+ fStart = bRTLPiece ? rect.right() : rect.left;
+ }
+ for (FX_INT32 i = 0; i < iLength; i ++) {
+ if (pAccess != NULL) {
+ wch = pAccess->GetChar(pIdentity, i);
+ iCharSize = pAccess->GetWidth(pIdentity, i);
+ } else {
+ wch = *pStr ++;
+ iCharSize = *pWidths ++;
+ }
+ fCharSize = (FX_FLOAT)iCharSize / 20000.0f;
+ FX_BOOL bRet = (!bSingleLine && FX_IsCtrlCode(wch));
+ if (!(wch == L'\v' || wch == L'\f' || wch == 0x2028 || wch == 0x2029 || (wLineBreakChar != 0xFEFF && wch == wLineBreakChar))) {
+ bRet = FALSE;
+ }
+ if (bRet) {
+ iCharSize = iFontSize * 500;
+ fCharSize = fFontSize / 2.0f;
+ }
+ if (bVertical) {
+ rect.top = fStart;
+ if (bRTLPiece) {
+ rect.top -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.height = fCharSize;
+ } else {
+ rect.left = fStart;
+ if (bRTLPiece) {
+ rect.left -= fCharSize;
+ fStart -= fCharSize;
+ } else {
+ fStart += fCharSize;
+ }
+ rect.width = fCharSize;
+ }
+ if (bCharBBox && !bRet) {
+ FX_INT32 iCharWidth = 1000;
+ pFont->GetCharWidth(wch, iCharWidth);
+ FX_FLOAT fRTLeft = 0, fCharWidth = 0;
+ if (iCharWidth > 0) {
+ fCharWidth = iCharWidth * fScale;
+ fRTLeft = fLeft;
+ if (bCombText) {
+ fRTLeft = (rect.width - fCharWidth) / 2.0f;
+ }
+ }
+ CFX_RectF rtBBoxF;
+ if (bVertical) {
+ rtBBoxF.top = rect.left + fRTLeft;
+ rtBBoxF.left = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.height = fCharWidth;
+ rtBBoxF.width = fHeight;
+ rtBBoxF.left = FX_MAX(rtBBoxF.left, 0);
+ } else {
+ rtBBoxF.left = rect.left + fRTLeft;
+ rtBBoxF.top = rect.top + (rect.height - fHeight) / 2.0f;
+ rtBBoxF.width = fCharWidth;
+ rtBBoxF.height = fHeight;
+ rtBBoxF.top = FX_MAX(rtBBoxF.top, 0);
+ }
+ rtArray.SetAt(i, rtBBoxF);
+ continue;
+ }
+ rtArray.SetAt(i, rect);
+ }
+ return iLength;
+}
diff --git a/xfa/src/fgas/src/layout/fx_textbreak.h b/xfa/src/fgas/src/layout/fx_textbreak.h
new file mode 100644
index 0000000000..c5bbc40946
--- /dev/null
+++ b/xfa/src/fgas/src/layout/fx_textbreak.h
@@ -0,0 +1,171 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_TEXTBREAK_IMP
+#define _FX_TEXTBREAK_IMP
+class CFX_TxtLine;
+class CFX_Txtbreak;
+class CFX_TxtLine : public CFX_Object
+{
+public:
+ CFX_TxtLine(FX_INT32 iBlockSize) : m_iStart(0)
+ , m_iWidth(0)
+ , m_iArabicChars(0)
+ {
+ m_pLineChars = FX_NEW CFX_TxtCharArray;
+ m_pLinePieces = FXTARGET_New CFX_TxtPieceArray(16);
+ }
+ ~CFX_TxtLine()
+ {
+ RemoveAll();
+ delete m_pLineChars;
+ FXTARGET_Delete m_pLinePieces;
+ }
+ FX_INT32 CountChars() const
+ {
+ return m_pLineChars->GetSize();
+ }
+ CFX_TxtChar* GetCharPtr(FX_INT32 index) const
+ {
+ FXSYS_assert(index > -1 && index < m_pLineChars->GetSize());
+ return m_pLineChars->GetDataPtr(index);
+ }
+ FX_INT32 CountPieces() const
+ {
+ return m_pLinePieces->GetSize();
+ }
+ CFX_TxtPiece* GetPiecePtr(FX_INT32 index) const
+ {
+ FXSYS_assert(index > -1 && index < m_pLinePieces->GetSize());
+ return m_pLinePieces->GetPtrAt(index);
+ }
+ void GetString(CFX_WideString &wsStr) const
+ {
+ FX_INT32 iCount = m_pLineChars->GetSize();
+ FX_LPWSTR pBuf = wsStr.GetBuffer(iCount);
+ CFX_Char *pChar;
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ pChar = m_pLineChars->GetDataPtr(i);
+ *pBuf ++ = (FX_WCHAR)pChar->m_wCharCode;
+ }
+ wsStr.ReleaseBuffer(iCount);
+ }
+ void RemoveAll(FX_BOOL bLeaveMemory = FALSE)
+ {
+ m_pLineChars->RemoveAll();
+ m_pLinePieces->RemoveAll(bLeaveMemory);
+ m_iWidth = 0;
+ m_iArabicChars = 0;
+ }
+ CFX_TxtCharArray *m_pLineChars;
+ CFX_TxtPieceArray *m_pLinePieces;
+ FX_INT32 m_iStart;
+ FX_INT32 m_iWidth;
+ FX_INT32 m_iArabicChars;
+};
+class CFX_TxtBreak : public IFX_TxtBreak, public CFX_Object
+{
+public:
+ CFX_TxtBreak(FX_DWORD dwPolicies);
+ ~CFX_TxtBreak();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual void SetLineWidth(FX_FLOAT fLineWidth);
+ virtual void SetLinePos(FX_FLOAT fLinePos);
+ virtual FX_DWORD GetLayoutStyles() const
+ {
+ return m_dwLayoutStyles;
+ }
+ virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles);
+ virtual void SetFont(IFX_Font *pFont);
+ virtual void SetFontSize(FX_FLOAT fFontSize);
+ virtual void SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant);
+ virtual void SetDefaultChar(FX_WCHAR wch);
+ virtual void SetParagraphBreakChar(FX_WCHAR wch);
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance);
+ virtual void SetHorizontalScale(FX_INT32 iScale);
+ virtual void SetVerticalScale(FX_INT32 iScale);
+ virtual void SetCharRotation(FX_INT32 iCharRotation);
+ virtual void SetCharSpace(FX_FLOAT fCharSpace);
+ virtual void SetAlignment(FX_INT32 iAlignment);
+ virtual FX_DWORD GetContextCharStyles() const;
+ virtual void SetContextCharStyles(FX_DWORD dwCharStyles);
+ virtual void SetCombWidth(FX_FLOAT fCombWidth);
+ virtual void SetUserData(FX_LPVOID pUserData);
+ virtual FX_DWORD AppendChar(FX_WCHAR wch);
+ virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_TXTBREAK_PieceBreak);
+ virtual FX_INT32 CountBreakChars() const;
+ virtual FX_INT32 CountBreakPieces() const;
+ virtual const CFX_TxtPiece* GetBreakPiece(FX_INT32 index) const;
+ virtual void ClearBreakPieces();
+ virtual void Reset();
+ virtual FX_INT32 GetDisplayPos(FX_LPCTXTRUN pTxtRun, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL, FX_AdjustCharDisplayPos pAdjustPos = NULL) const;
+ virtual FX_INT32 GetCharRects(FX_LPCTXTRUN pTxtRun, CFX_RectFArray &rtArray, FX_BOOL bCharBBox = FALSE) const;
+ void AppendChar_PageLoad(CFX_Char *pCurChar, FX_DWORD dwProps);
+ FX_DWORD AppendChar_Combination(CFX_Char *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Tab(CFX_Char *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Control(CFX_Char *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Arabic(CFX_Char *pCurChar, FX_INT32 iRotation);
+ FX_DWORD AppendChar_Others(CFX_Char *pCurChar, FX_INT32 iRotation);
+protected:
+ FX_DWORD m_dwPolicies;
+ FX_BOOL m_bPagination;
+ IFX_ArabicChar *m_pArabicChar;
+ FX_INT32 m_iLineWidth;
+ FX_DWORD m_dwLayoutStyles;
+ FX_BOOL m_bVertical;
+ FX_BOOL m_bArabicContext;
+ FX_BOOL m_bArabicShapes;
+ FX_BOOL m_bRTL;
+ FX_BOOL m_bSingleLine;
+ FX_BOOL m_bCombText;
+ FX_INT32 m_iArabicContext;
+ FX_INT32 m_iCurArabicContext;
+ IFX_Font *m_pFont;
+ FX_INT32 m_iFontSize;
+ FX_BOOL m_bEquidistant;
+ FX_INT32 m_iTabWidth;
+ FX_WCHAR m_wDefChar;
+ FX_WCHAR m_wParagBreakChar;
+ FX_INT32 m_iDefChar;
+ FX_INT32 m_iLineRotation;
+ FX_INT32 m_iCharRotation;
+ FX_INT32 m_iRotation;
+ FX_INT32 m_iAlignment;
+ FX_DWORD m_dwContextCharStyles;
+ FX_INT32 m_iCombWidth;
+ FX_LPVOID m_pUserData;
+ FX_DWORD m_dwCharType;
+ FX_BOOL m_bCurRTL;
+ FX_INT32 m_iCurAlignment;
+ FX_BOOL m_bArabicNumber;
+ FX_BOOL m_bArabicComma;
+ CFX_TxtLine *m_pTxtLine1;
+ CFX_TxtLine *m_pTxtLine2;
+ CFX_TxtLine *m_pCurLine;
+ FX_INT32 m_iReady;
+ FX_INT32 m_iTolerance;
+ FX_INT32 m_iHorScale;
+ FX_INT32 m_iVerScale;
+ FX_INT32 m_iCharSpace;
+ void SetBreakStatus();
+ FX_INT32 GetLineRotation(FX_DWORD dwStyles) const;
+ CFX_TxtChar* GetLastChar(FX_INT32 index, FX_BOOL bOmitChar = TRUE) const;
+ CFX_TxtLine* GetTxtLine(FX_BOOL bReady) const;
+ CFX_TxtPieceArray* GetTxtPieces(FX_BOOL bReady) const;
+ FX_DWORD GetUnifiedCharType(FX_DWORD dwType) const;
+ void ResetArabicContext();
+ void ResetContextCharStyles();
+ void EndBreak_UpdateArabicShapes();
+ FX_BOOL EndBreak_SplitLine(CFX_TxtLine *pNextLine, FX_BOOL bAllChars, FX_DWORD dwStatus);
+ void EndBreak_BidiLine(CFX_TPOArray &tpos, FX_DWORD dwStatus);
+ void EndBreak_Alignment(CFX_TPOArray &tpos, FX_BOOL bAllChars, FX_DWORD dwStatus);
+ FX_INT32 GetBreakPos(CFX_TxtCharArray &ca, FX_INT32 &iEndPos, FX_BOOL bAllChars = FALSE, FX_BOOL bOnlyBrk = FALSE);
+ void SplitTextLine(CFX_TxtLine *pCurLine, CFX_TxtLine *pNextLine, FX_BOOL bAllChars = FALSE);
+};
+#endif
diff --git a/xfa/src/fgas/src/layout/fx_unicode.cpp b/xfa/src/fgas/src/layout/fx_unicode.cpp
new file mode 100644
index 0000000000..def5d707f5
--- /dev/null
+++ b/xfa/src/fgas/src/layout/fx_unicode.cpp
@@ -0,0 +1,146 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_unicode.h"
+void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray &tpos, FX_INT32 iStart, FX_INT32 iEnd)
+{
+ FXSYS_assert(iStart > -1 && iStart < tpos.GetSize());
+ FXSYS_assert(iEnd > -1 && iEnd < tpos.GetSize());
+ if (iStart >= iEnd) {
+ return;
+ }
+ FX_INT32 i = iStart, j = iEnd;
+ FX_TPO *pCur = tpos.GetPtrAt(iStart), *pSort;
+ FX_INT32 v = pCur->pos;
+ while (i < j) {
+ while (j > i) {
+ pSort = tpos.GetPtrAt(j);
+ if (pSort->pos < v) {
+ FX_TPO t = *pSort;
+ *pSort = *pCur;
+ *pCur = t;
+ pCur = pSort;
+ break;
+ }
+ j --;
+ }
+ while (i < j) {
+ pSort = tpos.GetPtrAt(i);
+ if (pSort->pos > v) {
+ FX_TPO t = *pSort;
+ *pSort = *pCur;
+ *pCur = t;
+ pCur = pSort;
+ break;
+ }
+ i ++;
+ }
+ }
+ i --, j ++;
+ if (iStart < i) {
+ FX_TEXTLAYOUT_PieceSort(tpos, iStart, i);
+ }
+ if (j < iEnd) {
+ FX_TEXTLAYOUT_PieceSort(tpos, j, iEnd);
+ }
+}
+static const FX_JAPCHARPROPERTYEX gs_FX_JapCharPropertysEx[] = {
+ {0x3001, 0x13},
+ {0x3002, 0x13},
+ {0x3041, 0x23},
+ {0x3043, 0x23},
+ {0x3045, 0x23},
+ {0x3047, 0x23},
+ {0x3049, 0x23},
+ {0x3063, 0x23},
+ {0x3083, 0x23},
+ {0x3085, 0x23},
+ {0x3087, 0x23},
+ {0x308E, 0x23},
+ {0x3095, 0x23},
+ {0x3096, 0x23},
+ {0x30A1, 0x23},
+ {0x30A3, 0x23},
+ {0x30A5, 0x23},
+ {0x30A7, 0x23},
+ {0x30A9, 0x23},
+ {0x30C3, 0x23},
+ {0x30E3, 0x23},
+ {0x30E5, 0x23},
+ {0x30E7, 0x23},
+ {0x30EE, 0x23},
+ {0x30F5, 0x23},
+ {0x30F6, 0x23},
+ {0x30FB, 0x22},
+ {0x31F0, 0x23},
+ {0x31F1, 0x23},
+ {0x31F2, 0x23},
+ {0x31F3, 0x23},
+ {0x31F4, 0x23},
+ {0x31F5, 0x23},
+ {0x31F6, 0x23},
+ {0x31F7, 0x23},
+ {0x31F8, 0x23},
+ {0x31F9, 0x23},
+ {0x31FA, 0x23},
+ {0x31FB, 0x23},
+ {0x31FC, 0x23},
+ {0x31FD, 0x23},
+ {0x31FE, 0x23},
+ {0x31FF, 0x23},
+};
+FX_LPCJAPCHARPROPERTYEX FX_GetJapCharPropertyEx(FX_WCHAR wch)
+{
+ FX_INT32 iStart = 0;
+ FX_INT32 iEnd = sizeof(gs_FX_JapCharPropertysEx) / sizeof(FX_JAPCHARPROPERTYEX);
+ while (iStart <= iEnd) {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ FX_WCHAR wJapChar = gs_FX_JapCharPropertysEx[iMid].wChar;
+ if (wch == wJapChar) {
+ return gs_FX_JapCharPropertysEx + iMid;
+ } else if (wch < wJapChar) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ }
+ return NULL;
+}
+FX_BOOL FX_AdjustJapCharDisplayPos(FX_WCHAR wch, FX_BOOL bMBCSCode, IFX_Font *pFont, FX_FLOAT fFontSize, FX_BOOL bVertical, CFX_PointF &ptOffset)
+{
+ if (pFont == NULL || !bVertical) {
+ return FALSE;
+ }
+ if (wch < 0x3001 || wch > 0x31FF) {
+ return FALSE;
+ }
+ FX_LPCJAPCHARPROPERTYEX pJapChar = FX_GetJapCharPropertyEx(wch);
+ if (pJapChar == NULL) {
+ return FALSE;
+ }
+ CFX_Rect rtBBox;
+ rtBBox.Reset();
+ if (pFont->GetCharBBox(wch, rtBBox, bMBCSCode)) {
+ switch (pJapChar->uAlign & 0xF0) {
+ case FX_JAPCHARPROPERTYEX_Top:
+ ptOffset.y = fFontSize * (1000 - rtBBox.height) / 1200.0f;
+ break;
+ case FX_JAPCHARPROPERTYEX_Middle:
+ ptOffset.y = fFontSize * (1000 - rtBBox.height) / 6000.0f;
+ break;
+ }
+ switch (pJapChar->uAlign & 0x0F) {
+ case FX_JAPCHARPROPERTYEX_Center:
+ ptOffset.x = fFontSize * (600 - rtBBox.right()) / 1000.0f;
+ break;
+ case FX_JAPCHARPROPERTYEX_Right:
+ ptOffset.x = fFontSize * (950 - rtBBox.right()) / 1000.0f;
+ break;
+ }
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fgas/src/layout/fx_unicode.h b/xfa/src/fgas/src/layout/fx_unicode.h
new file mode 100644
index 0000000000..5eadb5506f
--- /dev/null
+++ b/xfa/src/fgas/src/layout/fx_unicode.h
@@ -0,0 +1,15 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FGAS_UNICODE_IMP
+#define _FGAS_UNICODE_IMP
+typedef struct _FX_TPO {
+ FX_INT32 index;
+ FX_INT32 pos;
+} FX_TPO;
+typedef CFX_MassArrayTemplate<FX_TPO> CFX_TPOArray;
+void FX_TEXTLAYOUT_PieceSort(CFX_TPOArray &tpos, FX_INT32 iStart, FX_INT32 iEnd);
+#endif
diff --git a/xfa/src/fgas/src/localization/fx_datetime.cpp b/xfa/src/fgas/src/localization/fx_datetime.cpp
new file mode 100644
index 0000000000..03ecb5bf48
--- /dev/null
+++ b/xfa/src/fgas/src/localization/fx_datetime.cpp
@@ -0,0 +1,548 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+const FX_BYTE g_FXDaysPerMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+const FX_BYTE g_FXDaysPerLeapMonth[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+const FX_INT32 g_FXDaysBeforeMonth[12] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+const FX_INT32 g_FXDaysBeforeLeapMonth[12] = {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335};
+const FX_INT32 g_FXDaysPerYear = 365;
+const FX_INT32 g_FXDaysPerLeapYear = 366;
+const FX_INT32 g_FXDaysPer4Years = 1461;
+const FX_INT32 g_FXDaysPer100Years = 36524;
+const FX_INT32 g_FXDaysPer400Years = 146097;
+const FX_INT64 g_FXMillisecondsPerSecond = 1000;
+const FX_INT64 g_FXMillisecondsPerMinute = 60000;
+const FX_INT64 g_FXMillisecondsPerHour = 3600000;
+const FX_INT64 g_FXMillisecondsPerDay = 86400000;
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+const FX_INT64 g_FXMillisecondsPerYear = 0x0757B12C00;
+const FX_INT64 g_FXMillisecondsPerLeapYear = 0x075CD78800;
+const FX_INT64 g_FXMillisecondsPer4Years = 0x1D63EB0C00;
+const FX_INT64 g_FXMillisecondsPer100Years = 0x02DEBCCDD000;
+const FX_INT64 g_FXMillisecondsPer400Years = 0x0B7AF85D9C00;
+#endif
+FX_BOOL FX_IsLeapYear(FX_INT32 iYear)
+{
+ FXSYS_assert(iYear != 0);
+ return ((iYear % 4) == 0 && (iYear % 100) != 0) || (iYear % 400) == 0;
+}
+FX_INT32 FX_DaysInYear(FX_INT32 iYear)
+{
+ FXSYS_assert(iYear != 0);
+ return FX_IsLeapYear(iYear) ? g_FXDaysPerLeapYear : g_FXDaysPerYear;
+}
+FX_BYTE FX_DaysInMonth(FX_INT32 iYear, FX_BYTE iMonth)
+{
+ FXSYS_assert(iYear != 0);
+ FXSYS_assert(iMonth >= 1 && iMonth <= 12);
+ const FX_BYTE *p = FX_IsLeapYear(iYear) ? g_FXDaysPerLeapMonth : g_FXDaysPerMonth;
+ return p[iMonth - 1];
+}
+static FX_INT32 FX_DaysBeforeMonthInYear(FX_INT32 iYear, FX_BYTE iMonth)
+{
+ FXSYS_assert(iYear != 0);
+ FXSYS_assert(iMonth >= 1 && iMonth <= 12);
+ const FX_INT32 *p = FX_IsLeapYear(iYear) ? g_FXDaysBeforeLeapMonth : g_FXDaysBeforeMonth;
+ return p[iMonth - 1];
+}
+static FX_INT64 FX_DateToDays(FX_INT32 iYear, FX_BYTE iMonth, FX_BYTE iDay, FX_BOOL bIncludeThisDay = FALSE)
+{
+ FXSYS_assert(iYear != 0);
+ FXSYS_assert(iMonth >= 1 && iMonth <= 12);
+ FXSYS_assert(iDay >= 1 && iDay <= FX_DaysInMonth(iYear, iMonth));
+ FX_INT64 iDays = FX_DaysBeforeMonthInYear(iYear, iMonth);
+ iDays += iDay;
+ if (!bIncludeThisDay) {
+ iDays --;
+ }
+ if (iYear > 0) {
+ iYear --;
+ } else {
+ iDays -= FX_DaysInYear(iYear);
+ iYear ++;
+ }
+ return iDays + (FX_INT64)iYear * 365 + iYear / 4 - iYear / 100 + iYear / 400;
+}
+static void FX_DaysToDate(FX_INT64 iDays, FX_INT32 &iYear, FX_BYTE &iMonth, FX_BYTE &iDay)
+{
+ FX_BOOL bBC = iDays < 0;
+ if (bBC) {
+ iDays = -iDays;
+ }
+ iYear = 1;
+ iMonth = 1;
+ iDay = 1;
+ if (iDays >= g_FXDaysPer400Years) {
+ iYear += (FX_INT32)(iDays / g_FXDaysPer400Years * 400);
+ iDays %= g_FXDaysPer400Years;
+ }
+ if (iDays >= g_FXDaysPer100Years) {
+ if (iDays == g_FXDaysPer100Years * 4) {
+ iYear += 300;
+ iDays -= g_FXDaysPer100Years * 3;
+ } else {
+ iYear += (FX_INT32)(iDays / g_FXDaysPer100Years * 100);
+ iDays %= g_FXDaysPer100Years;
+ }
+ }
+ if (iDays >= g_FXDaysPer4Years) {
+ iYear += (FX_INT32)(iDays / g_FXDaysPer4Years * 4);
+ iDays %= g_FXDaysPer4Years;
+ }
+ while (TRUE) {
+ FX_INT32 iYearDays = FX_DaysInYear(iYear);
+ if (iDays < iYearDays) {
+ if (bBC) {
+ iYear = -iYear;
+ iDays = iYearDays - iDays;
+ }
+ break;
+ }
+ iYear ++;
+ iDays -= iYearDays;
+ }
+ while (TRUE) {
+ FX_INT32 iMonthDays = FX_DaysInMonth(iYear, iMonth);
+ if (iDays < iMonthDays) {
+ break;
+ }
+ iMonth ++;
+ iDays -= iMonthDays;
+ }
+ iDay += (FX_BYTE)iDays;
+}
+#if _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_EMBEDDED_ || _FX_OS_ == _FX_ANDROID_ || _FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_
+#include <time.h>
+#include <sys/time.h>
+#endif
+typedef struct _FXUT_SYSTEMTIME {
+ FX_WORD wYear;
+ FX_WORD wMonth;
+ FX_WORD wDayOfWeek;
+ FX_WORD wDay;
+ FX_WORD wHour;
+ FX_WORD wMinute;
+ FX_WORD wSecond;
+ FX_WORD wMilliseconds;
+} FXUT_SYSTEMTIME;
+void CFX_Unitime::Now()
+{
+ FXUT_SYSTEMTIME utLocal;
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+ ::GetLocalTime((LPSYSTEMTIME)&utLocal);
+#elif _FX_OS_ != _FX_EMBEDDED_
+#if 1
+ timeval curTime;
+ gettimeofday(&curTime, NULL);
+#else
+ struct timespec curTime;
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &curTime);
+#endif
+ struct tm st;
+ localtime_r(&curTime.tv_sec, &st);
+ utLocal.wYear = st.tm_year + 1900;
+ utLocal.wMonth = st.tm_mon + 1;
+ utLocal.wDayOfWeek = st.tm_wday;
+ utLocal.wDay = st.tm_mday;
+ utLocal.wHour = st.tm_hour;
+ utLocal.wMinute = st.tm_min;
+ utLocal.wSecond = st.tm_sec;
+ utLocal.wMilliseconds = curTime.tv_usec / 1000;
+#endif
+ Set(utLocal.wYear, (FX_BYTE)utLocal.wMonth, (FX_BYTE)utLocal.wDay,
+ (FX_BYTE)utLocal.wHour, (FX_BYTE)utLocal.wMinute, (FX_BYTE)utLocal.wSecond, (FX_WORD)utLocal.wMilliseconds);
+}
+void CFX_Unitime::SetGMTime()
+{
+ FXUT_SYSTEMTIME utLocal;
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+ ::GetSystemTime((LPSYSTEMTIME)&utLocal);
+#elif _FX_OS_ != _FX_EMBEDDED_
+#if 1
+ timeval curTime;
+ gettimeofday(&curTime, NULL);
+#else
+ struct timespec curTime;
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &curTime);
+#endif
+ struct tm st;
+ gmtime_r(&curTime.tv_sec, &st);
+ utLocal.wYear = st.tm_year + 1900;
+ utLocal.wMonth = st.tm_mon + 1;
+ utLocal.wDayOfWeek = st.tm_wday;
+ utLocal.wDay = st.tm_mday;
+ utLocal.wHour = st.tm_hour;
+ utLocal.wMinute = st.tm_min;
+ utLocal.wSecond = st.tm_sec;
+ utLocal.wMilliseconds = curTime.tv_usec / 1000;
+#endif
+ Set(utLocal.wYear, (FX_BYTE)utLocal.wMonth, (FX_BYTE)utLocal.wDay,
+ (FX_BYTE)utLocal.wHour, (FX_BYTE)utLocal.wMinute, (FX_BYTE)utLocal.wSecond, (FX_WORD)utLocal.wMilliseconds);
+}
+void CFX_Unitime::Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour, FX_BYTE minute, FX_BYTE second, FX_WORD millisecond)
+{
+ FXSYS_assert(hour <= 23);
+ FXSYS_assert(minute <= 59);
+ FXSYS_assert(second <= 59);
+ FXSYS_assert(millisecond <= 999);
+ m_iUnitime = (FX_INT64)hour * g_FXMillisecondsPerHour + (FX_INT64)minute * g_FXMillisecondsPerMinute + (FX_INT64)second * g_FXMillisecondsPerSecond + millisecond;
+ if (year > 0) {
+ m_iUnitime = m_iUnitime + FX_DateToDays(year, month, day, FALSE) * g_FXMillisecondsPerDay;
+ }
+}
+void CFX_Unitime::Set(FX_UNITIME t)
+{
+ m_iUnitime = t;
+}
+FX_INT32 CFX_Unitime::GetYear() const
+{
+ FX_INT32 iYear;
+ FX_BYTE iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return iYear;
+}
+FX_BYTE CFX_Unitime::GetMonth() const
+{
+ FX_INT32 iYear;
+ FX_BYTE iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return iMonth;
+}
+FX_BYTE CFX_Unitime::GetDay() const
+{
+ FX_INT32 iYear;
+ FX_BYTE iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return iDay;
+}
+FX_WEEKDAY CFX_Unitime::GetDayOfWeek() const
+{
+ FX_INT32 v = (FX_INT32)((m_iUnitime / g_FXMillisecondsPerDay + 1) % 7);
+ if (v < 0) {
+ v += 7;
+ }
+ return (FX_WEEKDAY)v;
+}
+FX_WORD CFX_Unitime::GetDayOfYear() const
+{
+ FX_INT32 iYear;
+ FX_BYTE iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ return FX_DaysBeforeMonthInYear(iYear, iMonth) + iDay;
+}
+FX_INT64 CFX_Unitime::GetDayOfAD() const
+{
+ FX_BOOL bBC = m_iUnitime < 0;
+ FX_INT64 iDays = m_iUnitime / g_FXMillisecondsPerDay;
+ iDays += bBC ? -1 : 0;
+ if (bBC && (m_iUnitime % g_FXMillisecondsPerDay) == 0) {
+ iDays ++;
+ }
+ return iDays;
+}
+FX_BYTE CFX_Unitime::GetHour() const
+{
+ FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerDay);
+ if (v < 0) {
+ v += g_FXMillisecondsPerDay;
+ }
+ return (FX_BYTE)(v / g_FXMillisecondsPerHour);
+}
+FX_BYTE CFX_Unitime::GetMinute() const
+{
+ FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerHour);
+ if (v < 0) {
+ v += g_FXMillisecondsPerHour;
+ }
+ return (FX_BYTE)(v / g_FXMillisecondsPerMinute);
+}
+FX_BYTE CFX_Unitime::GetSecond() const
+{
+ FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerMinute);
+ if (v < 0) {
+ v += g_FXMillisecondsPerMinute;
+ }
+ return (FX_BYTE)(v / g_FXMillisecondsPerSecond);
+}
+FX_WORD CFX_Unitime::GetMillisecond() const
+{
+ FX_INT32 v = (FX_INT32)(m_iUnitime % g_FXMillisecondsPerSecond);
+ if (v < 0) {
+ v += g_FXMillisecondsPerSecond;
+ }
+ return (FX_WORD)v;
+}
+FX_BOOL CFX_Unitime::AddYears(FX_INT32 iYears)
+{
+ FX_UNITIME ut = m_iUnitime;
+ if (ut < 0) {
+ ut = -ut;
+ }
+ FX_UNITIME r = ut % g_FXMillisecondsPerDay;
+ FX_INT32 iYear;
+ FX_BYTE iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ iYear += iYears;
+ if (iYear == 0) {
+ iYear = iYears > 0 ? 1 : -1;
+ }
+ m_iUnitime = FX_DateToDays(iYear, iMonth, iDay, FALSE) * g_FXMillisecondsPerDay;
+ m_iUnitime += (iYear < 0) ? -r : r;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddMonths(FX_INT32 iMonths)
+{
+ FX_BOOL b = iMonths > 0;
+ FX_UNITIME ut = m_iUnitime;
+ if (ut < 0) {
+ ut = -ut;
+ }
+ FX_UNITIME r = ut % g_FXMillisecondsPerDay;
+ FX_INT32 iYear;
+ FX_BYTE iMonth, iDay;
+ FX_DaysToDate(GetDayOfAD(), iYear, iMonth, iDay);
+ iMonths += iMonth;
+ while (iMonths < 1) {
+ iYear --, iMonths += 12;
+ }
+ while (iMonths > 12) {
+ iYear ++, iMonths -= 12;
+ }
+ if (iYear == 0) {
+ iYear = b ? 1 : -1;
+ }
+ m_iUnitime = FX_DateToDays(iYear, (FX_BYTE)iMonths, iDay, FALSE) * g_FXMillisecondsPerDay;
+ m_iUnitime += (iYear < 0) ? -r : r;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddDays(FX_INT32 iDays)
+{
+ m_iUnitime += (FX_INT64)iDays * g_FXMillisecondsPerDay;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddHours(FX_INT32 iHours)
+{
+ m_iUnitime += (FX_INT64)iHours * g_FXMillisecondsPerHour;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddMinutes(FX_INT32 iMinutes)
+{
+ m_iUnitime += (FX_INT64)iMinutes * g_FXMillisecondsPerMinute;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddSeconds(FX_INT32 iSeconds)
+{
+ m_iUnitime += ((FX_INT64)iSeconds) * g_FXMillisecondsPerSecond;
+ return TRUE;
+}
+FX_BOOL CFX_Unitime::AddMilliseconds(FX_INT32 iMilliseconds)
+{
+ m_iUnitime += iMilliseconds;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::Set(FX_INT32 year, FX_BYTE month, FX_BYTE day, FX_BYTE hour, FX_BYTE minute, FX_BYTE second, FX_WORD millisecond)
+{
+ ASSERT(year != 0);
+ ASSERT(month >= 1 && month <= 12);
+ ASSERT(day >= 1 && day <= FX_DaysInMonth(year, month));
+ ASSERT(hour <= 23);
+ ASSERT(minute <= 59);
+ ASSERT(second <= 59);
+ ASSERT(millisecond <= 999);
+ m_DateTime.Date.sDate.year = year;
+ m_DateTime.Date.sDate.month = month;
+ m_DateTime.Date.sDate.day = day;
+ m_DateTime.Time.sTime.hour = hour;
+ m_DateTime.Time.sTime.minute = minute;
+ m_DateTime.Time.sTime.second = second;
+ m_DateTime.Time.sTime.millisecond = millisecond;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::FromUnitime(FX_UNITIME t)
+{
+ CFX_Unitime ut(t);
+ FX_DaysToDate(ut.GetDayOfAD(), m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day);
+ m_DateTime.Date.sDate.day = ut.GetHour();
+ m_DateTime.Time.sTime.minute = ut.GetMinute();
+ m_DateTime.Time.sTime.second = ut.GetSecond();
+ m_DateTime.Time.sTime.millisecond = ut.GetMillisecond();
+ return TRUE;
+}
+FX_UNITIME CFX_DateTime::ToUnitime() const
+{
+ FX_UNITIME v = (FX_INT64)m_DateTime.Date.sDate.day * g_FXMillisecondsPerHour + (FX_INT64)m_DateTime.Time.sTime.minute * g_FXMillisecondsPerMinute + (FX_INT64)m_DateTime.Time.sTime.second * g_FXMillisecondsPerSecond + m_DateTime.Time.sTime.millisecond;
+ v += FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day, FALSE) * g_FXMillisecondsPerDay;
+ return v;
+}
+FX_INT32 CFX_DateTime::GetYear() const
+{
+ return m_DateTime.Date.sDate.year;
+}
+FX_BYTE CFX_DateTime::GetMonth() const
+{
+ return m_DateTime.Date.sDate.month;
+}
+FX_BYTE CFX_DateTime::GetDay() const
+{
+ return m_DateTime.Date.sDate.day;
+}
+FX_WEEKDAY CFX_DateTime::GetDayOfWeek() const
+{
+ FX_INT32 v = (FX_INT32)(FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day, TRUE) % 7);
+ if (v < 0) {
+ v += 7;
+ }
+ return (FX_WEEKDAY)v;
+}
+FX_WORD CFX_DateTime::GetDayOfYear() const
+{
+ return FX_DaysBeforeMonthInYear(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month) + m_DateTime.Date.sDate.day;
+}
+FX_INT64 CFX_DateTime::GetDayOfAD() const
+{
+ return FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day, TRUE);
+}
+FX_BYTE CFX_DateTime::GetHour() const
+{
+ return m_DateTime.Date.sDate.day;
+}
+FX_BYTE CFX_DateTime::GetMinute() const
+{
+ return m_DateTime.Time.sTime.minute;
+}
+FX_BYTE CFX_DateTime::GetSecond() const
+{
+ return m_DateTime.Time.sTime.second;
+}
+FX_WORD CFX_DateTime::GetMillisecond() const
+{
+ return m_DateTime.Time.sTime.millisecond;
+}
+FX_BOOL CFX_DateTime::AddYears(FX_INT32 iYears)
+{
+ if (iYears == 0) {
+ return FALSE;
+ }
+ FX_INT32 v = m_DateTime.Date.sDate.year + iYears;
+ if (v >= 0 && m_DateTime.Date.sDate.year < 0) {
+ v ++;
+ } else if (v <= 0 && m_DateTime.Date.sDate.year > 0) {
+ v --;
+ }
+ m_DateTime.Date.sDate.year = v;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddMonths(FX_INT32 iMonths)
+{
+ if (iMonths == 0) {
+ return FALSE;
+ }
+ FX_BOOL b = iMonths > 0;
+ iMonths += m_DateTime.Date.sDate.month;
+ while (iMonths < 1) {
+ m_DateTime.Date.sDate.year --;
+ if (m_DateTime.Date.sDate.year == 0) {
+ m_DateTime.Date.sDate.year = -1;
+ }
+ iMonths += 12;
+ }
+ while (iMonths > 12) {
+ m_DateTime.Date.sDate.year ++;
+ if (m_DateTime.Date.sDate.year == 0) {
+ m_DateTime.Date.sDate.year = 1;
+ }
+ iMonths -= 12;
+ }
+ if (m_DateTime.Date.sDate.year == 0) {
+ m_DateTime.Date.sDate.year = b ? 1 : -1;
+ }
+ m_DateTime.Date.sDate.month = (FX_BYTE)iMonths;
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddDays(FX_INT32 iDays)
+{
+ if (iDays == 0) {
+ return FALSE;
+ }
+ FX_INT64 v1 = FX_DateToDays(m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day, TRUE);
+ FX_INT64 v2 = v1 + iDays;
+ if (v2 <= 0 && v1 > 0) {
+ v2 --;
+ } else if (v2 >= 0 && v1 < 0) {
+ v2 ++;
+ }
+ FX_DaysToDate(v2, m_DateTime.Date.sDate.year, m_DateTime.Date.sDate.month, m_DateTime.Date.sDate.day);
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddHours(FX_INT32 iHours)
+{
+ if (iHours == 0) {
+ return FALSE;
+ }
+ iHours += m_DateTime.Date.sDate.day;
+ FX_INT32 iDays = iHours / 24;
+ iHours %= 24;
+ if (iHours < 0) {
+ iDays --, iHours += 24;
+ }
+ m_DateTime.Date.sDate.day = (FX_BYTE)iHours;
+ if (iDays != 0) {
+ AddDays(iDays);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddMinutes(FX_INT32 iMinutes)
+{
+ if (iMinutes == 0) {
+ return FALSE;
+ }
+ iMinutes += m_DateTime.Time.sTime.minute;
+ FX_INT32 iHours = iMinutes / 60;
+ iMinutes %= 60;
+ if (iMinutes < 0) {
+ iHours --, iMinutes += 60;
+ }
+ m_DateTime.Time.sTime.minute = (FX_BYTE)iMinutes;
+ if (iHours != 0) {
+ AddHours(iHours);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddSeconds(FX_INT32 iSeconds)
+{
+ if (iSeconds == 0) {
+ return FALSE;
+ }
+ iSeconds += m_DateTime.Time.sTime.second;
+ FX_INT32 iMinutes = iSeconds / 60;
+ iSeconds %= 60;
+ if (iSeconds < 0) {
+ iMinutes --, iSeconds += 60;
+ }
+ m_DateTime.Time.sTime.second = (FX_BYTE)iSeconds;
+ if (iMinutes != 0) {
+ AddMinutes(iMinutes);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DateTime::AddMilliseconds(FX_INT32 iMilliseconds)
+{
+ if (iMilliseconds == 0) {
+ return FALSE;
+ }
+ iMilliseconds += m_DateTime.Time.sTime.millisecond;
+ FX_INT32 iSeconds = (FX_INT32)(iMilliseconds / g_FXMillisecondsPerSecond);
+ iMilliseconds %= g_FXMillisecondsPerSecond;
+ if (iMilliseconds < 0) {
+ iSeconds --, iMilliseconds += g_FXMillisecondsPerSecond;
+ }
+ m_DateTime.Time.sTime.millisecond = (FX_WORD)iMilliseconds;
+ if (iSeconds != 0) {
+ AddSeconds(iSeconds);
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fgas/src/localization/fx_locale.cpp b/xfa/src/fgas/src/localization/fx_locale.cpp
new file mode 100644
index 0000000000..a932a6c1a3
--- /dev/null
+++ b/xfa/src/fgas/src/localization/fx_locale.cpp
@@ -0,0 +1,4954 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_localeimp.h"
+#define FX_LOCALECATEGORY_DateHash 0xbde9abde
+#define FX_LOCALECATEGORY_TimeHash 0x2d71b00f
+#define FX_LOCALECATEGORY_DateTimeHash 0x158c72ed
+#define FX_LOCALECATEGORY_NumHash 0x0b4ff870
+#define FX_LOCALECATEGORY_TextHash 0x2d08af85
+#define FX_LOCALECATEGORY_ZeroHash 0x568cb500
+#define FX_LOCALECATEGORY_NullHash 0x052931bb
+typedef struct _FX_LOCALESUBCATEGORYINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ FX_INT32 eSubCategory;
+} FX_LOCALESUBCATEGORYINFO, * FX_LPLOCALESUBCATEGORYINFO;
+typedef FX_LOCALESUBCATEGORYINFO const * FX_LPCLOCALESUBCATEGORYINFO;
+const static FX_LOCALESUBCATEGORYINFO g_FXLocaleDateTimeSubCatData[] = {
+ {0x14da2125, (FX_LPCWSTR)L"default", FX_LOCALEDATETIMESUBCATEGORY_Default},
+ {0x9041d4b0, (FX_LPCWSTR)L"short", FX_LOCALEDATETIMESUBCATEGORY_Short},
+ {0xa084a381, (FX_LPCWSTR)L"medium", FX_LOCALEDATETIMESUBCATEGORY_Medium},
+ {0xcdce56b3, (FX_LPCWSTR)L"full", FX_LOCALEDATETIMESUBCATEGORY_Full},
+ {0xf6b4afb0, (FX_LPCWSTR)L"long", FX_LOCALEDATETIMESUBCATEGORY_Long},
+};
+const static FX_INT32 g_iFXLocaleDateTimeSubCatCount = sizeof(g_FXLocaleDateTimeSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO);
+const static FX_LOCALESUBCATEGORYINFO g_FXLocaleNumSubCatData[] = {
+ {0x46f95531, (FX_LPCWSTR)L"percent", FX_LOCALENUMPATTERN_Percent},
+ {0x4c4e8acb, (FX_LPCWSTR)L"currency", FX_LOCALENUMPATTERN_Currency},
+ {0x54034c2f, (FX_LPCWSTR)L"decimal", FX_LOCALENUMPATTERN_Decimal},
+ {0x7568e6ae, (FX_LPCWSTR)L"integer", FX_LOCALENUMPATTERN_Integer},
+};
+const static FX_INT32 g_iFXLocaleNumSubCatCount = sizeof(g_FXLocaleNumSubCatData) / sizeof(FX_LOCALESUBCATEGORYINFO);
+typedef struct _FX_LOCALETIMEZONEINFO {
+ FX_DWORD uHash;
+ FX_INT16 iHour;
+ FX_INT16 iMinute;
+} FX_LOCALETIMEZONEINFO, * FX_LPLOCALETIMEZONEINFO;
+typedef FX_LOCALETIMEZONEINFO const * FX_LPCLOCALETIMEZONEINFO;
+const static FX_LOCALETIMEZONEINFO g_FXLocaleTimeZoneData[] = {
+ {FXBSTR_ID(0, 'C', 'D', 'T'), -5, 0}, {FXBSTR_ID(0, 'C', 'S', 'T'), -6, 0},
+ {FXBSTR_ID(0, 'E', 'D', 'T'), -4, 0}, {FXBSTR_ID(0, 'E', 'S', 'T'), -5, 0},
+ {FXBSTR_ID(0, 'M', 'D', 'T'), -6, 0}, {FXBSTR_ID(0, 'M', 'S', 'T'), -7, 0},
+ {FXBSTR_ID(0, 'P', 'D', 'T'), -7, 0}, {FXBSTR_ID(0, 'P', 'S', 'T'), -8, 0},
+};
+const static FX_INT32 g_iFXLocaleTimeZoneCount = sizeof(g_FXLocaleTimeZoneData) / sizeof(FX_LOCALETIMEZONEINFO);
+const static CFX_WideStringC gs_wsTextSymbols = FX_WSTRC(L"AXO09");
+const static CFX_WideStringC gs_wsTimeSymbols = FX_WSTRC(L"hHkKMSFAzZ");
+const static CFX_WideStringC gs_wsDateSymbols = FX_WSTRC(L"DJMEeGgYwW");
+const static CFX_WideStringC gs_wsConstChars = FX_WSTRC(L",-:/. ");
+static FX_STRSIZE FX_Local_Find(FX_WSTR wsSymbols, FX_WCHAR ch, FX_STRSIZE nStart = 0)
+{
+ FX_STRSIZE nLength = wsSymbols.GetLength();
+ if (nLength < 1 || nStart > nLength) {
+ return -1;
+ }
+ FX_LPCWSTR lpsz = (FX_LPCWSTR)FXSYS_wcschr(wsSymbols.GetPtr() + nStart, ch);
+ return (lpsz == NULL) ? -1 : (FX_STRSIZE)(lpsz - wsSymbols.GetPtr());
+}
+const static FX_LPCWSTR gs_LocalNumberSymbols[] = {
+ (FX_LPCWSTR)L"decimal", (FX_LPCWSTR)L"grouping", (FX_LPCWSTR)L"percent", (FX_LPCWSTR)L"minus", (FX_LPCWSTR)L"zero",
+ (FX_LPCWSTR)L"currencySymbol", (FX_LPCWSTR)L"currencyName",
+};
+IFX_Locale* IFX_Locale::Create(CXML_Element* pLocaleData)
+{
+ return FX_NEW CFX_Locale(pLocaleData);
+}
+CFX_Locale::CFX_Locale(CXML_Element* pLocaleData)
+{
+ m_pElement = pLocaleData;
+}
+CFX_Locale::~CFX_Locale()
+{
+}
+CFX_WideString CFX_Locale::GetName()
+{
+ return CFX_WideString();
+}
+static CFX_WideString FX_GetXMLContent(FX_BSTR bsSpace, CXML_Element* pxmlElement, FX_BSTR bsTag, FX_WSTR wsName)
+{
+ CXML_Element* pDatePattern = NULL;
+ FX_INT32 nCount = pxmlElement->CountElements(bsSpace, bsTag);
+ FX_INT32 i = 0;
+ for (; i < nCount; i++) {
+ pDatePattern = pxmlElement->GetElement(bsSpace, bsTag, i);
+ if (pDatePattern->GetAttrValue(FX_BSTRC("name")) == wsName) {
+ break;
+ }
+ }
+ if (i < nCount && pDatePattern) {
+ return pDatePattern->GetContent(0);
+ }
+ return L"";
+}
+void CFX_Locale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ CFX_ByteString bsSpace;
+ CFX_WideString wsName = gs_LocalNumberSymbols[eType];
+ CXML_Element* pNumberSymbols = m_pElement->GetElement(bsSpace, FX_BSTRC("numberSymbols"));
+ if (!pNumberSymbols) {
+ return;
+ }
+ wsNumSymbol = FX_GetXMLContent(bsSpace, pNumberSymbols, FX_BSTRC("numberSymbol"), wsName);
+}
+void CFX_Locale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ CFX_ByteString bsSpace;
+ CXML_Element* pNumberSymbols = m_pElement->GetElement(bsSpace, FX_BSTRC("dateTimeSymbols"));
+ if (!pNumberSymbols) {
+ return;
+ }
+ wsDtSymbol = pNumberSymbols->GetContent(0);
+}
+static void FX_GetCalendarSymbol(CXML_Element* pXmlElement, const CFX_ByteString &symbol_type, FX_INT32 index, FX_BOOL bAbbr, CFX_WideString &wsName)
+{
+ CFX_ByteString bsSpace;
+ CFX_ByteString pstrSymbolNames = symbol_type + FX_BSTRC("Names");
+ CXML_Element* pChild = pXmlElement->GetElement(bsSpace, FX_BSTRC("calendarSymbols"));
+ if (!pChild) {
+ return;
+ }
+ CXML_Element* pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames);
+ if (!pSymbolNames) {
+ return;
+ }
+ if (pSymbolNames->GetAttrInteger(FX_BSTRC("abbr")) != bAbbr) {
+ pSymbolNames = pChild->GetElement(bsSpace, pstrSymbolNames, 1);
+ }
+ if (pSymbolNames && pSymbolNames->GetAttrInteger(FX_BSTRC("abbr")) == bAbbr) {
+ CXML_Element* pSymbolName = pSymbolNames->GetElement(bsSpace, symbol_type, index);
+ if (pSymbolName) {
+ wsName = pSymbolName->GetContent(0);
+ }
+ }
+}
+void CFX_Locale::GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr ) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "month", nMonth, bAbbr, wsMonthName);
+}
+void CFX_Locale::GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr ) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "day", nWeek, bAbbr, wsDayName);
+}
+void CFX_Locale::GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM ) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "meridiem", bAM ? 0 : 1, FALSE, wsMeridiemName);
+}
+static FX_INT32 FX_ParseTimeZone(FX_LPCWSTR pStr, FX_INT32 iLen, FX_TIMEZONE& tz)
+{
+ tz.tzHour = 0;
+ tz.tzMinute = 0;
+ if (iLen < 0) {
+ return 0;
+ }
+ FX_INT32 iStart = 1;
+ FX_INT32 iEnd = iStart + 2;
+ while (iStart < iLen && iStart < iEnd) {
+ tz.tzHour = tz.tzHour * 10 + pStr[iStart++] - '0';
+ }
+ if (iStart < iLen && pStr[iStart] == ':') {
+ iStart++;
+ }
+ iEnd = iStart + 2;
+ while (iStart < iLen && iStart < iEnd) {
+ tz.tzMinute = tz.tzMinute * 10 + pStr[iStart++] - '0';
+ }
+ if (pStr[0] == '-') {
+ tz.tzHour = -tz.tzHour;
+ }
+ return iStart;
+}
+void CFX_Locale::GetTimeZone(FX_TIMEZONE& tz) const
+{
+ tz.tzHour = 0;
+ tz.tzMinute = 0;
+ if (!m_pElement) {
+ return;
+ }
+ CXML_Element* pxmlTimeZone = m_pElement->GetElement("", FX_BSTRC("timeZone"));
+ if (pxmlTimeZone) {
+ CFX_WideString wsTimeZone = pxmlTimeZone->GetContent(0);
+ FX_ParseTimeZone(wsTimeZone, wsTimeZone.GetLength(), tz);
+ }
+}
+void CFX_Locale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD ) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetCalendarSymbol(m_pElement, "era", bAD ? 0 : 1, FALSE, wsEraName);
+}
+static void FX_GetPattern(CXML_Element* pXmlElement, const CFX_ByteString& bsCategory, const CFX_WideString& wsSubCategory, CFX_WideString& wsPattern)
+{
+ CFX_ByteString bsSpace;
+ CXML_Element* pDatePatterns = pXmlElement->GetElement(bsSpace, bsCategory + "s");
+ if (!pDatePatterns) {
+ return;
+ }
+ wsPattern = FX_GetXMLContent(bsSpace, pDatePatterns, bsCategory, wsSubCategory);
+}
+static void FX_GetDateTimePattern(CXML_Element* pXmlElement, const CFX_ByteString& bsCategory, FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern)
+{
+ CFX_WideString wsType = g_FXLocaleDateTimeSubCatData[eType].pName;
+ FX_GetPattern(pXmlElement, bsCategory, wsType, wsPattern);
+}
+void CFX_Locale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetDateTimePattern(m_pElement, "datePattern", eType, wsPattern);
+}
+void CFX_Locale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ if (!m_pElement) {
+ return;
+ }
+ FX_GetDateTimePattern(m_pElement, "timePattern", eType, wsPattern);
+}
+void CFX_Locale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ CFX_WideString wsType = g_FXLocaleNumSubCatData[eType].pName;
+ FX_GetPattern(m_pElement, "numberPattern", wsType, wsPattern);
+}
+static FX_BOOL FX_IsDigit(FX_WCHAR c)
+{
+ return c >= '0' && c <= '9';
+}
+static FX_BOOL FX_IsAlpha(FX_WCHAR c)
+{
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+static FX_BOOL FX_IsSpace(FX_WCHAR c)
+{
+ return (c == 0x20) || (c == 0x0d) || (c == 0x0a) || (c == 0x09);
+}
+static const FX_FLOAT gs_fraction_scales[] = {0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f,
+ 0.0000001f, 0.00000001f, 0.000000001f, 0.0000000001f, 0.00000000001f
+ };
+static const FX_INT32 gs_fraction_count = sizeof(gs_fraction_scales) / sizeof(FX_FLOAT);
+class CFX_LCNumeric : public CFX_Object
+{
+public:
+ CFX_LCNumeric();
+ CFX_LCNumeric(FX_INT64 integral, FX_DWORD fractional = 0, FX_INT32 exponent = 0);
+ CFX_LCNumeric(FX_FLOAT dbRetValue);
+ CFX_LCNumeric(double dbvalue);
+ CFX_LCNumeric(CFX_WideString& wsNumeric);
+
+ FX_FLOAT GetFloat() const;
+ double GetDouble() const;
+ CFX_WideString ToString() const;
+ CFX_WideString ToString(FX_INT32 nTreading, FX_BOOL bTrimTailZeros) const;
+ FX_INT64 m_Integral;
+ FX_DWORD m_Fractional;
+#ifdef FX_NUM_DOUBLE
+ CFX_WideString m_wsValue;
+#endif
+ FX_INT32 m_Exponent;
+};
+static FX_BOOL FX_WStringToNumeric(const CFX_WideString& wsValue, CFX_LCNumeric& lcnum)
+{
+ FX_INT64 *pIntegral = &lcnum.m_Integral;
+ FX_DWORD *pFractional = &lcnum.m_Fractional;
+ FX_INT32 *pExponent = &lcnum.m_Exponent;
+ *pIntegral = 0;
+ *pFractional = 0;
+ *pExponent = 0;
+#ifdef FX_NUM_DOUBLE
+ lcnum.m_wsValue.Empty();
+#endif
+ if (wsValue.IsEmpty()) {
+ return FALSE;
+ }
+ const FX_INT32 nIntegralMaxLen = 17;
+ FX_INT32 cc = 0;
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsValue;
+ FX_INT32 len = wsValue.GetLength();
+ while (cc < len && FX_IsSpace(str[cc])) {
+ cc++;
+ }
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bNegative = TRUE;
+ cc++;
+ }
+ FX_INT32 nIntegralLen = 0;
+ while (cc < len) {
+ if (str[cc] == '.') {
+ break;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ if (nIntegralLen < nIntegralMaxLen) {
+ *pIntegral = *pIntegral * 10 + str[cc] - '0';
+ nIntegralLen++;
+ }
+ cc ++;
+ }
+ *pIntegral = bNegative ? -*pIntegral : *pIntegral;
+ if (cc < len && str[cc] == '.') {
+ int scale = 0;
+ double fraction = 0.0;
+ cc ++;
+ while (cc < len) {
+ if (scale >= gs_fraction_count) {
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ cc++;
+ }
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ fraction += gs_fraction_scales[scale] * (str[cc] - '0');
+ scale ++;
+ cc ++;
+ }
+ *pFractional = (FX_DWORD)(fraction * 4294967296.0);
+ }
+ if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+ cc ++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ *pExponent = *pExponent * 10 + str[cc] - '0';
+ cc ++;
+ }
+ *pExponent = bExpSign ? -*pExponent : *pExponent;
+ }
+#ifdef FX_NUM_DOUBLE
+ else {
+ lcnum.m_wsValue = wsValue;
+ }
+#endif
+ return TRUE;
+}
+CFX_LCNumeric::CFX_LCNumeric()
+{
+ m_Integral = 0;
+ m_Fractional = 0;
+ m_Exponent = 0;
+}
+CFX_LCNumeric::CFX_LCNumeric(FX_INT64 integral, FX_DWORD fractional , FX_INT32 exponent )
+{
+ m_Integral = integral;
+ m_Fractional = fractional;
+ m_Exponent = exponent;
+}
+CFX_LCNumeric::CFX_LCNumeric(FX_FLOAT dbRetValue)
+{
+ m_Integral = (FX_INT64)dbRetValue;
+ m_Fractional = (FX_DWORD)(((dbRetValue > 0) ? (dbRetValue - m_Integral) : (m_Integral - dbRetValue)) * 4294967296);
+ m_Exponent = 0;
+}
+CFX_LCNumeric::CFX_LCNumeric(double dbvalue)
+{
+ m_Integral = (FX_INT64)dbvalue;
+ m_Fractional = (FX_DWORD)(((dbvalue > 0) ? (dbvalue - m_Integral) : (m_Integral - dbvalue)) * 4294967296);
+ m_Exponent = 0;
+}
+CFX_LCNumeric::CFX_LCNumeric(CFX_WideString& wsNumeric)
+{
+ FX_WStringToNumeric(wsNumeric, *this);
+}
+FX_FLOAT CFX_LCNumeric::GetFloat() const
+{
+ FX_FLOAT dbRetValue = m_Fractional / 4294967296.0f;
+ dbRetValue = m_Integral + (m_Integral >= 0 ? dbRetValue : -dbRetValue);
+ if (m_Exponent != 0) {
+ dbRetValue *= FXSYS_pow(10, (FX_FLOAT)m_Exponent);
+ }
+ return dbRetValue;
+}
+double CFX_LCNumeric::GetDouble() const
+{
+ double value = m_Fractional / 4294967296.0;
+ value = m_Integral + (m_Integral >= 0 ? value : -value);
+ if (m_Exponent != 0) {
+ value *= FXSYS_pow(10, (FX_FLOAT)m_Exponent);
+ }
+ return value;
+}
+CFX_WideString CFX_LCNumeric::ToString() const
+{
+ return ToString(8, TRUE);
+}
+CFX_WideString CFX_LCNumeric::ToString(FX_INT32 nTreading, FX_BOOL bTrimTailZeros) const
+{
+#ifdef FX_NUM_DOUBLE
+ CFX_WideString wsResult;
+ if (!m_wsValue.IsEmpty()) {
+ const FX_INT32 nIntegralMaxLen = 17;
+ FX_INT32 cc = 0;
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+ FX_LPCWSTR str = (FX_LPCWSTR)m_wsValue;
+ FX_INT32 len = m_wsValue.GetLength();
+ while (cc < len && FX_IsSpace(str[cc])) {
+ cc++;
+ }
+ if (cc >= len) {
+ return wsResult;
+ }
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bNegative = TRUE;
+ cc++;
+ }
+ FX_INT32 nIntegralLen = 0;
+ while (cc < len) {
+ if (str[cc] == '.') {
+ break;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return wsResult;
+ }
+ }
+ if (nIntegralLen < nIntegralMaxLen) {
+ *pIntegral = *pIntegral * 10 + str[cc] - '0';
+ nIntegralLen++;
+ }
+ cc ++;
+ }
+ *pIntegral = bNegative ? -*pIntegral : *pIntegral;
+ if (cc < len && str[cc] == '.') {
+ int scale = 0;
+ double fraction = 0.0;
+ cc ++;
+ while (cc < len) {
+ if (scale >= gs_fraction_count) {
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ cc++;
+ }
+ }
+ if (!FX_IsDigit(str[cc])) {
+ if ((str[cc] == 'E' || str[cc] == 'e')) {
+ break;
+ } else {
+ return FALSE;
+ }
+ }
+ fraction += gs_fraction_scales[scale] * (str[cc] - '0');
+ scale ++;
+ cc ++;
+ }
+ *pFractional = (FX_DWORD)(fraction * 4294967296.0);
+ }
+ }
+ double dbValeu = GetDouble();
+ FX_INT64 iInte = (FX_INT64)dbValeu;
+ wsResult.Format((FX_LPCWSTR)L"%l", (FX_INT64)iInte);
+ if (m_Fractional) {
+ CFX_WideString wsFormat;
+ wsFormat.Format((FX_LPCWSTR)L"%%.%dG", nTreading);
+ double dblMantissa = (dbValeu > 0) ? (dbValeu - iInte) : (iInte - dbValeu);
+ CFX_WideString wsFrac;
+ wsFrac.Format((FX_LPCWSTR)wsFormat, dblMantissa);
+ wsResult += CFX_WideStringC((FX_LPCWSTR)wsFrac + 1, wsFrac.GetLength() - 1);
+ if (bTrimTailZeros && nTreading > 0) {
+ wsResult.TrimRight(L"0");
+ wsResult.TrimRight(L".");
+ }
+ }
+#endif
+ CFX_WideString wsFormat;
+ wsFormat.Format((FX_LPCWSTR)L"%%.%df", nTreading);
+ CFX_WideString wsResult;
+ wsResult.Format(FX_LPCWSTR(wsFormat), GetDouble());
+ if (bTrimTailZeros && nTreading > 0) {
+ wsResult.TrimRight(L"0");
+ wsResult.TrimRight(L".");
+ }
+ return wsResult;
+}
+IFX_FormatString* IFX_FormatString::Create(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID)
+{
+ if (!pLocaleMgr) {
+ return NULL;
+ }
+ return FX_NEW CFX_FormatString(pLocaleMgr, bUseLCID);
+}
+CFX_FormatString::CFX_FormatString(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID)
+ : m_pLocaleMgr(pLocaleMgr)
+ , m_bUseLCID(bUseLCID)
+{
+}
+CFX_FormatString::~CFX_FormatString()
+{
+}
+void CFX_FormatString::SplitFormatString(const CFX_WideString& wsFormatString, CFX_WideStringArray& wsPatterns)
+{
+ FX_INT32 iStrLen = wsFormatString.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsFormatString;
+ FX_LPCWSTR pToken = pStr;
+ FX_LPCWSTR pEnd = pStr + iStrLen;
+ FX_BOOL iQuote = FALSE;
+ while (TRUE) {
+ if (pStr >= pEnd) {
+ CFX_WideString sub(pToken, pStr - pToken);
+ wsPatterns.Add(sub);
+ return;
+ } else if (*pStr == '\'') {
+ iQuote = !iQuote;
+ } else if (*pStr == L'|' && !iQuote) {
+ CFX_WideString sub(pToken, pStr - pToken);
+ wsPatterns.Add(sub);
+ pToken = pStr + 1;
+ }
+ pStr ++;
+ }
+}
+static CFX_WideString FX_GetLiteralText(FX_LPCWSTR pStrPattern, FX_INT32 &iPattern, FX_INT32 iLenPattern)
+{
+ CFX_WideString wsOutput;
+ if (pStrPattern[iPattern] != '\'') {
+ return wsOutput;
+ }
+ iPattern++;
+ FX_INT32 iQuote = 1;
+ while (iPattern < iLenPattern) {
+ if (pStrPattern[iPattern] == '\'') {
+ iQuote++;
+ if ((iPattern + 1 >= iLenPattern) || ((pStrPattern[iPattern + 1] != '\'') && (iQuote % 2 == 0))) {
+ break;
+ } else {
+ iQuote++;
+ }
+ iPattern++;
+ } else if (pStrPattern[iPattern] == '\\' && (iPattern + 1 < iLenPattern) && pStrPattern[iPattern + 1] == 'u') {
+ FX_INT32 iKeyValue = 0;
+ iPattern += 2;
+ FX_INT32 i = 0;
+ while (iPattern < iLenPattern && i++ < 4) {
+ FX_WCHAR ch = pStrPattern[iPattern++];
+ if ((ch >= '0' && ch <= '9')) {
+ iKeyValue = iKeyValue * 16 + ch - '0';
+ } else if ((ch >= 'a' && ch <= 'f')) {
+ iKeyValue = iKeyValue * 16 + ch - 'a' + 10;
+ } else if ((ch >= 'A' && ch <= 'F')) {
+ iKeyValue = iKeyValue * 16 + ch - 'A' + 10;
+ }
+ }
+ if (iKeyValue != 0) {
+ wsOutput += (FX_WCHAR)(iKeyValue & 0x0000FFFF);
+ }
+ continue;
+ }
+ wsOutput += pStrPattern[iPattern++];
+ }
+ return wsOutput;
+}
+static CFX_WideString FX_GetLiteralTextReverse(FX_LPCWSTR pStrPattern, FX_INT32 &iPattern)
+{
+ CFX_WideString wsOutput;
+ if (pStrPattern[iPattern] != '\'') {
+ return wsOutput;
+ }
+ iPattern--;
+ FX_INT32 iQuote = 1;
+ while (iPattern >= 0) {
+ if (pStrPattern[iPattern] == '\'') {
+ iQuote++;
+ if (iPattern - 1 >= 0 || ((pStrPattern[iPattern - 1] != '\'') && (iQuote % 2 == 0))) {
+ break;
+ } else {
+ iQuote++;
+ }
+ iPattern--;
+ } else if (pStrPattern[iPattern] == '\\' && pStrPattern[iPattern + 1] == 'u') {
+ iPattern--;
+ FX_INT32 iKeyValue = 0;
+ FX_INT32 iLen = wsOutput.GetLength();
+ FX_INT32 i = 1;
+ for (; i < iLen && i < 5; i++) {
+ FX_WCHAR ch = wsOutput[i];
+ if ((ch >= '0' && ch <= '9')) {
+ iKeyValue = iKeyValue * 16 + ch - '0';
+ } else if ((ch >= 'a' && ch <= 'f')) {
+ iKeyValue = iKeyValue * 16 + ch - 'a' + 10;
+ } else if ((ch >= 'A' && ch <= 'F')) {
+ iKeyValue = iKeyValue * 16 + ch - 'A' + 10;
+ }
+ }
+ if (iKeyValue != 0) {
+ wsOutput.Delete(0, i);
+ wsOutput = (FX_WCHAR)(iKeyValue & 0x0000FFFF) + wsOutput;
+ }
+ continue;
+ }
+ wsOutput = pStrPattern[iPattern--] + wsOutput;
+ }
+ return wsOutput;
+}
+FX_LOCALECATEGORY CFX_FormatString::GetCategory(const CFX_WideString& wsPattern)
+{
+ FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
+ FX_INT32 ccf = 0;
+ FX_INT32 iLenf = wsPattern.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern;
+ FX_BOOL bBraceOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ } else if (!bBraceOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsCategory(pStr[ccf]);
+ ccf++;
+ while (TRUE) {
+ if (ccf == iLenf) {
+ return eCategory;
+ }
+ if ( pStr[ccf] == '.' || pStr[ccf] == '(') {
+ break;
+ }
+ if (pStr[ccf] == '{') {
+ bBraceOpen = TRUE;
+ break;
+ }
+ wsCategory += pStr[ccf];
+ ccf++;
+ }
+ FX_DWORD dwHash = FX_HashCode_String_GetW(wsCategory, wsCategory.GetLength());
+ if (dwHash == FX_LOCALECATEGORY_DateHash) {
+ if (eCategory == FX_LOCALECATEGORY_Time) {
+ return FX_LOCALECATEGORY_DateTime;
+ }
+ eCategory = FX_LOCALECATEGORY_Date;
+ } else if (dwHash == FX_LOCALECATEGORY_TimeHash) {
+ if (eCategory == FX_LOCALECATEGORY_Date) {
+ return FX_LOCALECATEGORY_DateTime;
+ }
+ eCategory = FX_LOCALECATEGORY_Time;
+ } else if (dwHash == FX_LOCALECATEGORY_DateTimeHash) {
+ return FX_LOCALECATEGORY_DateTime;
+ } else if (dwHash == FX_LOCALECATEGORY_TextHash) {
+ return FX_LOCALECATEGORY_Text;
+ } else if (dwHash == FX_LOCALECATEGORY_NumHash) {
+ return FX_LOCALECATEGORY_Num;
+ } else if (dwHash == FX_LOCALECATEGORY_ZeroHash) {
+ return FX_LOCALECATEGORY_Zero;
+ } else if (dwHash == FX_LOCALECATEGORY_NullHash) {
+ return FX_LOCALECATEGORY_Null;
+ }
+ } else if (pStr[ccf] == '}') {
+ bBraceOpen = FALSE;
+ }
+ ccf++;
+ }
+ return eCategory;
+}
+static FX_WORD FX_WStringToLCID(FX_LPCWSTR pstrLCID)
+{
+ if (!pstrLCID) {
+ return 0;
+ }
+ wchar_t* pEnd;
+ return (FX_WORD)wcstol((wchar_t*)pstrLCID, &pEnd, 16);
+}
+FX_WORD CFX_FormatString::GetLCID(const CFX_WideString& wsPattern)
+{
+ return FX_WStringToLCID(GetLocaleName(wsPattern));
+}
+CFX_WideString CFX_FormatString::GetLocaleName(const CFX_WideString& wsPattern)
+{
+ FX_INT32 ccf = 0;
+ FX_INT32 iLenf = wsPattern.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ } else if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ return wsLCID;
+ }
+ ccf++;
+ }
+ return CFX_WideString();
+}
+IFX_Locale* CFX_FormatString::GetTextFormat(const CFX_WideString &wsPattern, FX_WSTR wsCategory, CFX_WideString& wsPurgePattern)
+{
+ IFX_Locale* pLocale = NULL;
+ FX_INT32 ccf = 0;
+ FX_INT32 iLenf = wsPattern.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern;
+ FX_BOOL bBrackOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_INT32 iCurChar = ccf;
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ wsPurgePattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
+ } else if (!bBrackOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsSearchCategory(pStr[ccf]);
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' && pStr[ccf] != '(') {
+ wsSearchCategory += pStr[ccf];
+ ccf++;
+ }
+ if (wsSearchCategory != wsCategory) {
+ continue;
+ }
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ pLocale = GetPatternLocale(wsLCID);
+ } else if (pStr[ccf] == '{') {
+ bBrackOpen = TRUE;
+ break;
+ }
+ ccf++;
+ }
+ } else if (pStr[ccf] != '}') {
+ wsPurgePattern += pStr[ccf];
+ }
+ ccf++;
+ }
+ if (!bBrackOpen) {
+ wsPurgePattern = wsPattern;
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ return pLocale;
+}
+#define FX_NUMSTYLE_Percent 0x01
+#define FX_NUMSTYLE_Exponent 0x02
+#define FX_NUMSTYLE_DotVorv 0x04
+IFX_Locale* CFX_FormatString::GetNumericFormat(const CFX_WideString& wsPattern, FX_INT32& iDotIndex, FX_DWORD& dwStyle, CFX_WideString& wsPurgePattern)
+{
+ dwStyle = 0;
+ IFX_Locale* pLocale = NULL;
+ FX_INT32 ccf = 0;
+ FX_INT32 iLenf = wsPattern.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern;
+ FX_BOOL bFindDot = FALSE;
+ FX_BOOL bBrackOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_INT32 iCurChar = ccf;
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ wsPurgePattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
+ } else if (!bBrackOpen && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsCategory(pStr[ccf]);
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' && pStr[ccf] != '(') {
+ wsCategory += pStr[ccf];
+ ccf++;
+ }
+ if (wsCategory != FX_WSTRC(L"num")) {
+ bBrackOpen = TRUE;
+ ccf = 0;
+ continue;
+ }
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ pLocale = GetPatternLocale(wsLCID);
+ } else if (pStr[ccf] == '{') {
+ bBrackOpen = TRUE;
+ break;
+ } else if (pStr[ccf] == '.') {
+ CFX_WideString wsSubCategory;
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '(' && pStr[ccf] != '{') {
+ wsSubCategory += pStr[ccf++];
+ }
+ FX_DWORD dwSubHash = FX_HashCode_String_GetW(wsSubCategory, wsSubCategory.GetLength());
+ FX_LOCALENUMSUBCATEGORY eSubCategory = FX_LOCALENUMPATTERN_Decimal;
+ for (FX_INT32 i = 0; i < g_iFXLocaleNumSubCatCount; i++) {
+ if (g_FXLocaleNumSubCatData[i].uHash == dwSubHash) {
+ eSubCategory = (FX_LOCALENUMSUBCATEGORY)g_FXLocaleNumSubCatData[i].eSubCategory;
+ break;
+ }
+ }
+ wsSubCategory.Empty();
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ FXSYS_assert(pLocale != NULL);
+ pLocale->GetNumPattern(eSubCategory, wsSubCategory);
+ iDotIndex = wsSubCategory.Find('.');
+ if (iDotIndex > 0) {
+ iDotIndex += wsPurgePattern.GetLength() ;
+ bFindDot = TRUE;
+ dwStyle |= FX_NUMSTYLE_DotVorv;
+ }
+ wsPurgePattern += wsSubCategory;
+ if (eSubCategory == FX_LOCALENUMPATTERN_Percent) {
+ dwStyle |= FX_NUMSTYLE_Percent;
+ }
+ continue;
+ }
+ ccf++;
+ }
+ } else if (pStr[ccf] == 'E') {
+ dwStyle |= FX_NUMSTYLE_Exponent;
+ wsPurgePattern += pStr[ccf];
+ } else if (pStr[ccf] == '%') {
+ dwStyle |= FX_NUMSTYLE_Percent;
+ wsPurgePattern += pStr[ccf];
+ } else if (pStr[ccf] != '}') {
+ wsPurgePattern += pStr[ccf];
+ }
+ if (!bFindDot) {
+ if (pStr[ccf] == '.' || pStr[ccf] == 'V' || pStr[ccf] == 'v') {
+ bFindDot = TRUE;
+ iDotIndex = wsPurgePattern.GetLength() - 1;
+ dwStyle |= FX_NUMSTYLE_DotVorv;
+ }
+ }
+ ccf++;
+ }
+ if (!bFindDot) {
+ iDotIndex = wsPurgePattern.GetLength();
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ return pLocale;
+}
+static FX_BOOL FX_GetNumericDotIndex(const CFX_WideString& wsNum, const CFX_WideString& wsDotSymbol, FX_INT32 &iDotIndex)
+{
+ FX_INT32 ccf = 0;
+ FX_INT32 iLenf = wsNum.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsNum;
+ FX_INT32 iLenDot = wsDotSymbol.GetLength();
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ } else if (ccf + iLenDot <= iLenf && !FXSYS_wcsncmp(pStr + ccf, (FX_LPCWSTR)wsDotSymbol, iLenDot)) {
+ iDotIndex = ccf;
+ return TRUE;
+ }
+ ccf++;
+ }
+ iDotIndex = wsNum.Find('.');
+ if (iDotIndex < 0) {
+ iDotIndex = iLenf;
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::ParseText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsValue)
+{
+ wsValue.Empty();
+ if (wsSrcText.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat);
+ if (wsTextFormat.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 iText = 0, iPattern = 0;
+ FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText;
+ FX_INT32 iLenText = wsSrcText.GetLength();
+ FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat;
+ FX_INT32 iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern && iText < iLenText) {
+ switch (pStrPattern[iPattern]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ if (iText + iLiteralLen > iLenText || FXSYS_wcsncmp(pStrText + iText, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ wsValue = wsSrcText;
+ return FALSE;
+ }
+ iText += iLiteralLen;
+ iPattern++;
+ break;
+ }
+ case 'A':
+ if (FX_IsAlpha(pStrText[iText])) {
+ wsValue += pStrText[iText];
+ iText++;
+ }
+ iPattern++;
+ break;
+ case 'X':
+ wsValue += pStrText[iText];
+ iText++;
+ iPattern++;
+ break;
+ case 'O':
+ case '0':
+ if (FX_IsDigit(pStrText[iText]) || FX_IsAlpha(pStrText[iText])) {
+ wsValue += pStrText[iText];
+ iText++;
+ }
+ iPattern++;
+ break;
+ case '9':
+ if (FX_IsDigit(pStrText[iText])) {
+ wsValue += pStrText[iText];
+ iText++;
+ }
+ iPattern++;
+ break;
+ default:
+ if (pStrPattern[iPattern] != pStrText[iText]) {
+ wsValue = wsSrcText;
+ return FALSE;
+ }
+ iPattern++;
+ iText++;
+ break;
+ }
+ }
+ return iPattern == iLenPattern && iText == iLenText;
+}
+FX_BOOL CFX_FormatString::ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, FX_FLOAT &fValue)
+{
+ fValue = 0.0f;
+ if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 dot_index_f = -1;
+ FX_DWORD dwFormatStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale = GetNumericFormat(wsPattern, dot_index_f, dwFormatStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 iExponent = 0;
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ FX_INT32 iDotLen = wsDotSymbol.GetLength();
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ FX_INT32 iGroupLen = wsGroupSymbol.GetLength();
+ CFX_WideString wsMinus;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus);
+ FX_INT32 iMinusLen = wsMinus.GetLength();
+ int cc = 0, ccf = 0;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsSrcNum;
+ int len = wsSrcNum.GetLength();
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ double dbRetValue = 0;
+ double coeff = 1;
+ FX_BOOL bHavePercentSymbol = FALSE;
+ FX_BOOL bNeg = FALSE;
+ FX_BOOL bReverseParse = FALSE;
+ FX_INT32 dot_index = 0;
+ if (!FX_GetNumericDotIndex(wsSrcNum, wsDotSymbol, dot_index) && (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
+ bReverseParse = TRUE;
+ }
+ bReverseParse = FALSE;
+ if (bReverseParse) {
+ ccf = lenf - 1;
+ cc = len - 1;
+ while (ccf > dot_index_f && cc >= 0) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ cc -= iLiteralLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
+ coeff *= 0.1;
+ cc--;
+ ccf--;
+ break;
+ case 'z':
+ if (cc >= 0) {
+ dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
+ coeff *= 0.1;
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ dbRetValue = dbRetValue * coeff + (str[cc] - '0') * 0.1;
+ coeff *= 0.1;
+ }
+ cc--;
+ ccf--;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ if (cc >= dot_index) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ while (cc >= 0) {
+ if (str[cc] == 'E' || str[cc] == 'e') {
+ break;
+ }
+ if (FX_IsDigit(str[cc])) {
+ iExponent = iExponent + (str[cc] - '0') * 10;
+ cc--;
+ continue;
+ } else if (str[cc] == '+') {
+ cc--;
+ continue;
+ } else if (cc - iMinusLen + 1 > 0 && !FXSYS_wcsncmp(str + (cc - iMinusLen + 1), (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ bExpSign = TRUE;
+ cc -= iMinusLen;
+ } else {
+ return FALSE;
+ }
+ }
+ cc --;
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf--;
+ }
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ FX_INT32 iSymbolLen = wsSymbol.GetLength();
+ cc -= iSymbolLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf --;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf --;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ FX_INT32 iSysmbolLen = wsSymbol.GetLength();
+ cc -= iSysmbolLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSysmbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ bHavePercentSymbol = TRUE;
+ }
+ break;
+ case '8':
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ dbRetValue = (str[cc] - '0') * coeff + dbRetValue;
+ coeff *= 0.1;
+ cc++;
+ }
+ break;
+ case ',': {
+ if (cc >= 0) {
+ cc -= iGroupLen - 1;
+ if (cc >= 0 && FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsGroupSymbol, iGroupLen) == 0) {
+ cc--;
+ } else {
+ cc += iGroupLen - 1;
+ }
+ }
+ ccf--;
+ }
+ break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ }
+ dot_index = cc + 1;
+ }
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ coeff = 1;
+ while (ccf >= 0 && cc >= 0) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ cc -= iLiteralLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 10;
+ cc--;
+ ccf--;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 10;
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 10;
+ cc--;
+ }
+ } else {
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ if (cc >= dot_index) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ while (cc >= 0) {
+ if (str[cc] == 'E' || str[cc] == 'e') {
+ break;
+ }
+ if (FX_IsDigit(str[cc])) {
+ iExponent = iExponent + (str[cc] - '0') * 10;
+ cc--;
+ continue;
+ } else if (str[cc] == '+') {
+ cc--;
+ continue;
+ } else if (cc - iMinusLen + 1 > 0 && !FXSYS_wcsncmp(str + (cc - iMinusLen + 1), (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ bExpSign = TRUE;
+ cc -= iMinusLen;
+ } else {
+ return FALSE;
+ }
+ }
+ cc --;
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf--;
+ }
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ FX_INT32 iSymbolLen = wsSymbol.GetLength();
+ cc -= iSymbolLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf --;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf --;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ FX_INT32 iSysmbolLen = wsSymbol.GetLength();
+ cc -= iSysmbolLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSysmbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ bHavePercentSymbol = TRUE;
+ }
+ break;
+ case '8':
+ return FALSE;
+ case ',': {
+ if (cc >= 0) {
+ cc -= iGroupLen - 1;
+ if (cc >= 0 && FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsGroupSymbol, iGroupLen) == 0) {
+ cc--;
+ } else {
+ cc += iGroupLen - 1;
+ }
+ }
+ ccf--;
+ }
+ break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ return FALSE;
+ }
+ if (!bReverseParse) {
+ ccf = dot_index_f + 1;
+ cc = (dot_index == len) ? len : dot_index + 1;
+ coeff = 0.1;
+ while (cc < len && ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 0.1;
+ }
+ cc++;
+ ccf++;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 0.1;
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ dbRetValue = dbRetValue + (str[cc] - '0') * coeff;
+ coeff *= 0.1;
+ cc++;
+ }
+ } else {
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 'E': {
+ if (cc >= len || (str[cc] != 'E' && str[cc] != 'e')) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ cc ++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ iExponent = iExponent * 10 + str[cc] - '0';
+ cc ++;
+ }
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf++;
+ }
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ FX_INT32 iSymbolLen = wsSymbol.GetLength();
+ if (cc + iSymbolLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc += iSymbolLen;
+ ccf++;
+ }
+ break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ FX_INT32 iSysmbolLen = wsSymbol.GetLength();
+ if (cc + iSysmbolLen <= len && !FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSysmbolLen)) {
+ cc += iSysmbolLen;
+ }
+ ccf++;
+ bHavePercentSymbol = TRUE;
+ }
+ break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ dbRetValue = (str[cc] - '0') * coeff + dbRetValue;
+ coeff *= 0.1;
+ cc++;
+ }
+ }
+ break;
+ case ',': {
+ if (cc + iGroupLen <= len && FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsGroupSymbol, iGroupLen) == 0) {
+ cc += iGroupLen;
+ }
+ ccf++;
+ }
+ break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ }
+ }
+ if (cc != len) {
+ return FALSE;
+ }
+ }
+ if (iExponent) {
+ dbRetValue *= FXSYS_pow(10, (FX_FLOAT)iExponent);
+ }
+ if (bHavePercentSymbol) {
+ dbRetValue /= 100.0;
+ }
+ if (bNeg) {
+ dbRetValue = -dbRetValue;
+ }
+ fValue = (FX_FLOAT)dbRetValue;
+ return TRUE;
+}
+void FX_ParseNumString(const CFX_WideString& wsNum, CFX_WideString& wsResult)
+{
+ FX_INT32 iCount = wsNum.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsNum;
+ FX_LPWSTR pDst = wsResult.GetBuffer(iCount);
+ FX_INT32 nIndex = 0;
+ FX_BOOL bMinus = FALSE;
+ FX_INT32 i = 0;
+ for (i = 0; i < iCount; i++) {
+ FX_WCHAR wc = pStr[i];
+ if (wc == '.') {
+ break;
+ }
+ if ((wc == L'0' || wc == L' ' || wc == '+') && nIndex == 0) {
+ continue;
+ }
+ if (wc == '-') {
+ pDst[nIndex++] = wc;
+ bMinus = TRUE;
+ continue;
+ }
+ if (wc == L'0' && nIndex == 1 && bMinus) {
+ continue;
+ }
+ pDst[nIndex++] = wc;
+ }
+ if (bMinus && nIndex == 1) {
+ pDst[nIndex++] = '0';
+ }
+ if (nIndex == 0) {
+ wsResult.ReleaseBuffer(0);
+ pDst = wsResult.GetBuffer(iCount + 1);
+ pDst[nIndex++] = '0';
+ }
+ FX_INT32 j = 0;
+ for (j = iCount - 1; j > i; j--) {
+ FX_WCHAR wc = pStr[j];
+ if (wc != L'0' && wc != L' ') {
+ break;
+ }
+ }
+ if (j > i) {
+ pDst[nIndex++] = '.';
+ FXSYS_wcsncpy(pDst + nIndex, pStr + i + 1, j - i);
+ nIndex += j - i;
+ }
+ wsResult.ReleaseBuffer(nIndex);
+}
+FX_BOOL CFX_FormatString::ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString &wsValue)
+{
+ wsValue.Empty();
+ if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 dot_index_f = -1;
+ FX_DWORD dwFormatStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale = GetNumericFormat(wsPattern, dot_index_f, dwFormatStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 iExponent = 0;
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ FX_INT32 iDotLen = wsDotSymbol.GetLength();
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ FX_INT32 iGroupLen = wsGroupSymbol.GetLength();
+ CFX_WideString wsMinus;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinus);
+ FX_INT32 iMinusLen = wsMinus.GetLength();
+ int cc = 0, ccf = 0;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsSrcNum;
+ int len = wsSrcNum.GetLength();
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ FX_BOOL bHavePercentSymbol = FALSE;
+ FX_BOOL bNeg = FALSE;
+ FX_BOOL bReverseParse = FALSE;
+ FX_INT32 dot_index = 0;
+ if (!FX_GetNumericDotIndex(wsSrcNum, wsDotSymbol, dot_index) && (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
+ bReverseParse = TRUE;
+ }
+ bReverseParse = FALSE;
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ while (ccf >= 0 && cc >= 0) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralTextReverse(strf, ccf);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ cc -= iLiteralLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsValue = CFX_WideStringC(str[cc]) + wsValue;
+ cc--;
+ ccf--;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ wsValue = CFX_WideStringC(str[cc]) + wsValue;
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ wsValue = CFX_WideStringC(str[cc]) + wsValue;
+ cc--;
+ }
+ } else {
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc--;
+ } else {
+ cc -= iMinusLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ cc--;
+ bNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ if (cc >= dot_index) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ while (cc >= 0) {
+ if (str[cc] == 'E' || str[cc] == 'e') {
+ break;
+ }
+ if (FX_IsDigit(str[cc])) {
+ iExponent = iExponent + (str[cc] - '0') * 10;
+ cc--;
+ continue;
+ } else if (str[cc] == '+') {
+ cc--;
+ continue;
+ } else if (cc - iMinusLen + 1 > 0 && !FXSYS_wcsncmp(str + (cc - iMinusLen + 1), (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ bExpSign = TRUE;
+ cc -= iMinusLen;
+ } else {
+ return FALSE;
+ }
+ }
+ cc --;
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf--;
+ }
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ FX_INT32 iSymbolLen = wsSymbol.GetLength();
+ cc -= iSymbolLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf --;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'R' && cc - 1 >= 0 && str[cc - 1] == 'C') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf --;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'B' && cc - 1 >= 0 && str[cc - 1] == 'D') {
+ bNeg = TRUE;
+ cc -= 2;
+ }
+ ccf -= 2;
+ } else {
+ ccf--;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ FX_INT32 iSysmbolLen = wsSymbol.GetLength();
+ cc -= iSysmbolLen - 1;
+ if (cc < 0 || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSysmbolLen)) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ bHavePercentSymbol = TRUE;
+ }
+ break;
+ case '8':
+ return FALSE;
+ case ',': {
+ if (cc >= 0) {
+ cc -= iGroupLen - 1;
+ if (cc >= 0 && FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsGroupSymbol, iGroupLen) == 0) {
+ cc--;
+ } else {
+ cc += iGroupLen - 1;
+ }
+ }
+ ccf--;
+ }
+ break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc--;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ if (str[cc] == '-') {
+ bNeg = TRUE;
+ cc --;
+ }
+ if (cc >= 0) {
+ return FALSE;
+ }
+ }
+ if (dot_index < len && (dwFormatStyle & FX_NUMSTYLE_DotVorv)) {
+ wsValue += '.';
+ }
+ if (!bReverseParse) {
+ ccf = dot_index_f + 1;
+ cc = (dot_index == len) ? len : dot_index + 1;
+ while (cc < len && ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'': {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ break;
+ }
+ case '9':
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ {
+ wsValue += str[cc];
+ }
+ cc++;
+ ccf++;
+ break;
+ case 'z':
+ if (FX_IsDigit(str[cc])) {
+ wsValue += str[cc];
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (str[cc] != ' ') {
+ if (FX_IsDigit(str[cc])) {
+ wsValue += str[cc];
+ cc++;
+ }
+ } else {
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'S':
+ if (str[cc] == '+' || str[cc] == ' ') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 's':
+ if (str[cc] == '+') {
+ cc++;
+ } else {
+ if (cc + iMinusLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsMinus, iMinusLen)) {
+ return FALSE;
+ }
+ bNeg = TRUE;
+ cc += iMinusLen;
+ }
+ ccf++;
+ break;
+ case 'E': {
+ if (cc >= len || (str[cc] != 'E' && str[cc] != 'e')) {
+ return FALSE;
+ }
+ FX_BOOL bExpSign = FALSE;
+ cc ++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ break;
+ }
+ iExponent = iExponent * 10 + str[cc] - '0';
+ cc ++;
+ }
+ iExponent = bExpSign ? -iExponent : iExponent;
+ ccf++;
+ }
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ FX_INT32 iSymbolLen = wsSymbol.GetLength();
+ if (cc + iSymbolLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSymbolLen)) {
+ return FALSE;
+ }
+ cc += iSymbolLen;
+ ccf++;
+ }
+ break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'C' && cc + 1 < len && str[cc + 1] == 'R') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (str[cc] == ' ') {
+ cc++;
+ } else if (str[cc] == 'D' && cc + 1 < len && str[cc + 1] == 'B') {
+ bNeg = TRUE;
+ cc += 2;
+ }
+ ccf += 2;
+ }
+ break;
+ case '.':
+ case 'V':
+ case 'v':
+ return FALSE;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ FX_INT32 iSysmbolLen = wsSymbol.GetLength();
+ if (cc + iSysmbolLen <= len && !FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsSymbol, iSysmbolLen)) {
+ cc += iSysmbolLen;
+ }
+ ccf++;
+ bHavePercentSymbol = TRUE;
+ }
+ break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ wsValue += str[cc];
+ cc++;
+ }
+ }
+ break;
+ case ',': {
+ if (cc + iGroupLen <= len && FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsGroupSymbol, iGroupLen) == 0) {
+ cc += iGroupLen;
+ }
+ ccf++;
+ }
+ break;
+ case '(':
+ if (str[cc] == L'(') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ case ')':
+ if (str[cc] == L')') {
+ bNeg = TRUE;
+ } else if (str[cc] != L' ') {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ break;
+ default:
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ }
+ }
+ if (cc != len) {
+ return FALSE;
+ }
+ }
+ if (iExponent || bHavePercentSymbol) {
+ CFX_Decimal decimal = CFX_Decimal(wsValue);
+ if (iExponent) {
+ decimal = decimal * CFX_Decimal(FXSYS_pow(10, (FX_FLOAT)iExponent));
+ }
+ if (bHavePercentSymbol) {
+ decimal = decimal / CFX_Decimal(100);
+ }
+ wsValue = decimal;
+ }
+ if (bNeg) {
+ wsValue = CFX_WideStringC('-') + wsValue;
+ }
+ return TRUE;
+}
+FX_DATETIMETYPE CFX_FormatString::GetDateTimeFormat(const CFX_WideString& wsPattern, IFX_Locale*& pLocale, CFX_WideString &wsDatePattern, CFX_WideString &wsTimePattern)
+{
+ pLocale = NULL;
+ CFX_WideString wsTempPattern;
+ FX_LOCALECATEGORY eCategory = FX_LOCALECATEGORY_Unknown;
+ FX_INT32 ccf = 0;
+ FX_INT32 iLenf = wsPattern.GetLength();
+ FX_LPCWSTR pStr = (FX_LPCWSTR)wsPattern;
+ FX_INT32 iFindCategory = 0;
+ FX_BOOL bBraceOpen = FALSE;
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '\'') {
+ FX_INT32 iCurChar = ccf;
+ FX_GetLiteralText(pStr, ccf, iLenf);
+ wsTempPattern += CFX_WideStringC(pStr + iCurChar, ccf - iCurChar + 1);
+ } else if (!bBraceOpen && iFindCategory != 3 && FX_Local_Find(gs_wsConstChars, pStr[ccf]) < 0) {
+ CFX_WideString wsCategory(pStr[ccf]);
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '{' && pStr[ccf] != '.' && pStr[ccf] != '(') {
+ if (pStr[ccf] == 'T') {
+ wsDatePattern = wsPattern.Left(ccf);
+ wsTimePattern = wsPattern.Right(wsPattern.GetLength() - ccf);
+ wsTimePattern.SetAt(0, ' ');
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ return FX_DATETIMETYPE_DateTime;
+ }
+ wsCategory += pStr[ccf];
+ ccf++;
+ }
+ if (!(iFindCategory & 1) && wsCategory == FX_WSTRC(L"date")) {
+ iFindCategory |= 1;
+ eCategory = FX_LOCALECATEGORY_Date;
+ if (iFindCategory & 2) {
+ iFindCategory = 4;
+ }
+ } else if (!(iFindCategory & 2) && wsCategory == FX_WSTRC(L"time")) {
+ iFindCategory |= 2;
+ eCategory = FX_LOCALECATEGORY_Time;
+ } else if (wsCategory == FX_WSTRC(L"datetime")) {
+ iFindCategory = 3;
+ eCategory = FX_LOCALECATEGORY_DateTime;
+ } else {
+ continue;
+ }
+ while (ccf < iLenf) {
+ if (pStr[ccf] == '(') {
+ ccf++;
+ CFX_WideString wsLCID;
+ while (ccf < iLenf && pStr[ccf] != ')') {
+ wsLCID += pStr[ccf++];
+ }
+ pLocale = GetPatternLocale(wsLCID);
+ } else if (pStr[ccf] == '{') {
+ bBraceOpen = TRUE;
+ break;
+ } else if (pStr[ccf] == '.') {
+ CFX_WideString wsSubCategory;
+ ccf++;
+ while (ccf < iLenf && pStr[ccf] != '(' && pStr[ccf] != '{') {
+ wsSubCategory += pStr[ccf++];
+ }
+ FX_DWORD dwSubHash = FX_HashCode_String_GetW(wsSubCategory, wsSubCategory.GetLength());
+ FX_LOCALEDATETIMESUBCATEGORY eSubCategory = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ for (FX_INT32 i = 0; i < g_iFXLocaleDateTimeSubCatCount; i++) {
+ if (g_FXLocaleDateTimeSubCatData[i].uHash == dwSubHash) {
+ eSubCategory = (FX_LOCALEDATETIMESUBCATEGORY)g_FXLocaleDateTimeSubCatData[i].eSubCategory;
+ break;
+ }
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ FXSYS_assert(pLocale != NULL);
+ switch (eCategory) {
+ case FX_LOCALECATEGORY_Date:
+ pLocale->GetDatePattern(eSubCategory, wsDatePattern);
+ wsDatePattern = wsTempPattern + wsDatePattern;
+ break;
+ case FX_LOCALECATEGORY_Time:
+ pLocale->GetTimePattern(eSubCategory, wsTimePattern);
+ wsTimePattern = wsTempPattern + wsTimePattern;
+ break;
+ case FX_LOCALECATEGORY_DateTime:
+ pLocale->GetDatePattern(eSubCategory, wsDatePattern);
+ wsDatePattern = wsTempPattern + wsDatePattern;
+ pLocale->GetTimePattern(eSubCategory, wsTimePattern);
+ break;
+ default:
+ break;
+ }
+ wsTempPattern.Empty();
+ continue;
+ }
+ ccf++;
+ }
+ } else if (pStr[ccf] == '}') {
+ bBraceOpen = FALSE;
+ if (!wsTempPattern.IsEmpty()) {
+ if (eCategory == FX_LOCALECATEGORY_Time) {
+ wsTimePattern = wsTempPattern;
+ } else if (eCategory == FX_LOCALECATEGORY_Date) {
+ wsDatePattern = wsTempPattern;
+ }
+ wsTempPattern.Empty();
+ }
+ } else {
+ wsTempPattern += pStr[ccf];
+ }
+ ccf++;
+ }
+ if (!wsTempPattern.IsEmpty()) {
+ if (eCategory == FX_LOCALECATEGORY_Date) {
+ wsDatePattern += wsTempPattern;
+ } else {
+ wsTimePattern += wsTempPattern;
+ }
+ }
+ if (!pLocale) {
+ pLocale = m_pLocaleMgr->GetDefLocale();
+ }
+ if (!iFindCategory) {
+ wsTimePattern.Empty();
+ wsDatePattern = wsPattern;
+ }
+ return (FX_DATETIMETYPE)iFindCategory;
+}
+static FX_BOOL FX_ParseLocaleDate(const CFX_WideString& wsDate, const CFX_WideString& wsDatePattern, IFX_Locale* pLocale, CFX_Unitime &datetime, FX_INT32 &cc)
+{
+ FX_INT32 year = 1900;
+ FX_INT32 month = 1;
+ FX_INT32 day = 1;
+ FX_INT32 ccf = 0;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsDate;
+ FX_INT32 len = wsDate.GetLength();
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsDatePattern;
+ FX_INT32 lenf = wsDatePattern.GetLength();
+ while (cc < len && ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsDateSymbols, strf[ccf]) < 0) {
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'D', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ day = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ day = day * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'D', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ day = str[cc++] - '0';
+ if (cc < len) {
+ day = day * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '1')) {
+ int i = 0;
+ while (cc < len && i < 3 && FX_IsDigit(str[cc])) {
+ cc++;
+ i++;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '3')) {
+ cc += 3;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ month = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ month = month * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ month = str[cc++] - '0';
+ if (cc < len) {
+ month = month * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '3')) {
+ CFX_WideString wsMonthNameAbbr;
+ FX_WORD i = 0;
+ for (; i < 12; i++) {
+ pLocale->GetMonthName(i, wsMonthNameAbbr, TRUE);
+ if (wsMonthNameAbbr.IsEmpty()) {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((FX_LPCWSTR)wsMonthNameAbbr, str + cc, wsMonthNameAbbr.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsMonthNameAbbr.GetLength();
+ month = i + 1;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '4')) {
+ CFX_WideString wsMonthName;
+ FX_WORD i = 0;
+ for (; i < 12; i++) {
+ pLocale->GetMonthName(i, wsMonthName, FALSE);
+ if (wsMonthName.IsEmpty()) {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((FX_LPCWSTR)wsMonthName, str + cc, wsMonthName.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsMonthName.GetLength();
+ month = i + 1;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '1')) {
+ cc += 1;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '3')) {
+ CFX_WideString wsDayNameAbbr;
+ FX_WORD i = 0;
+ for (; i < 7; i++) {
+ pLocale->GetDayName(i, wsDayNameAbbr, TRUE);
+ if (wsDayNameAbbr.IsEmpty()) {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((FX_LPCWSTR)wsDayNameAbbr, str + cc, wsDayNameAbbr.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsDayNameAbbr.GetLength();
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '4')) {
+ CFX_WideString wsDayName;
+ FX_INT32 i = 0;
+ for (; i < 7; i++) {
+ pLocale->GetDayName(i, wsDayName, FALSE);
+ if (wsDayName == L"") {
+ continue;
+ }
+ if (!FXSYS_wcsncmp((FX_LPCWSTR)wsDayName, str + cc, wsDayName.GetLength())) {
+ break;
+ }
+ }
+ if (i < 12) {
+ cc += wsDayName.GetLength();
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'e', '1')) {
+ cc += 1;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'G', '1')) {
+ cc += 2;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '2')) {
+ if (cc + 2 > len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ year = str[cc++] - '0';
+ if (cc >= len || !FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ year = year * 10 + str[cc++] - '0';
+ if (year <= 29) {
+ year += 2000;
+ } else {
+ year += 1900;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '4')) {
+ int i = 0;
+ year = 0;
+ if (cc + 4 > len) {
+ return FALSE;
+ }
+ while (i < 4) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ year = year * 10 + str[cc] - '0';
+ cc++;
+ i++;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'w', '1')) {
+ cc += 1;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'W', '2')) {
+ cc += 2;
+ }
+ }
+ CFX_Unitime ut;
+ ut.Set(year, month, day);
+ datetime = datetime + ut;
+ return cc;
+}
+static void FX_ResolveZone(FX_BYTE& wHour, FX_BYTE& wMinute, FX_TIMEZONE tzDiff, IFX_Locale* pLocale)
+{
+ FX_INT32 iMinuteDiff = wHour * 60 + wMinute;
+ FX_TIMEZONE tzLocale;
+ pLocale->GetTimeZone(tzLocale);
+ iMinuteDiff += tzLocale.tzHour * 60 + (tzLocale.tzHour < 0 ? -tzLocale.tzMinute : tzLocale.tzMinute);
+ iMinuteDiff -= tzDiff.tzHour * 60 + (tzDiff.tzHour < 0 ? -tzDiff.tzMinute : tzDiff.tzMinute);
+ while (iMinuteDiff > 1440) {
+ iMinuteDiff -= 1440;
+ }
+ while (iMinuteDiff < 0) {
+ iMinuteDiff += 1440;
+ }
+ wHour = iMinuteDiff / 60;
+ wMinute = iMinuteDiff % 60;
+}
+static FX_BOOL FX_ParseLocaleTime(const CFX_WideString& wsTime, const CFX_WideString& wsTimePattern, IFX_Locale* pLocale, CFX_Unitime &datetime, FX_INT32 &cc)
+{
+ FX_BYTE hour = 0;
+ FX_BYTE minute = 0;
+ FX_BYTE second = 0;
+ FX_WORD millisecond = 0;
+ FX_INT32 ccf = 0;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsTime;
+ int len = wsTime.GetLength();
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsTimePattern;
+ int lenf = wsTimePattern.GetLength();
+ FX_BOOL bHasA = FALSE;
+ FX_BOOL bPM = FALSE;
+ while (cc < len && ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ CFX_WideString wsLiteral = FX_GetLiteralText(strf, ccf, lenf);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ if (cc + iLiteralLen > len || FXSYS_wcsncmp(str + cc, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ cc += iLiteralLen;
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsTimeSymbols, strf[ccf]) == -1) {
+ if (strf[ccf] != str[cc]) {
+ return FALSE;
+ }
+ cc++;
+ ccf++;
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'k', '1') || dwSymbol == FXBSTR_ID(0, 0, 'H', '1') || dwSymbol == FXBSTR_ID(0, 0, 'h', '1') || dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ hour = hour * 10 + str[cc++] - '0';
+ }
+ if (dwSymbol == FXBSTR_ID(0, 0, 'K', '1') && hour == 24) {
+ hour = 0;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '2') || dwSymbol == FXBSTR_ID(0, 0, 'H', '2') || dwSymbol == FXBSTR_ID(0, 0, 'h', '2') || dwSymbol == FXBSTR_ID(0, 0, 'K', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = str[cc++] - '0';
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = hour * 10 + str[cc++] - '0';
+ if (dwSymbol == FXBSTR_ID(0, 0, 'K', '2') && hour == 24) {
+ hour = 0;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ minute = minute * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = str[cc++] - '0';
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = minute * 10 + str[cc++] - '0';
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '1')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = str[cc++] - '0';
+ if (cc < len && FX_IsDigit(str[cc])) {
+ second = second * 10 + str[cc++] - '0';
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '2')) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = str[cc++] - '0';
+ if (cc >= len) {
+ return FALSE;
+ }
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = second * 10 + str[cc++] - '0';
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'F', '3')) {
+ if (cc + 3 >= len) {
+ return FALSE;
+ }
+ int i = 0;
+ while (i < 3) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ millisecond = millisecond * 10 + str[cc++] - '0';
+ i++;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'A', '1')) {
+ CFX_WideString wsAM;
+ pLocale->GetMeridiemName(wsAM, TRUE);
+ CFX_WideString wsPM;
+ pLocale->GetMeridiemName(wsPM, FALSE);
+ if ((cc + wsAM.GetLength() <= len) && (CFX_WideStringC(str + cc, wsAM.GetLength()) == wsAM)) {
+ cc += wsAM.GetLength();
+ bHasA = TRUE;
+ } else if ((cc + wsPM.GetLength() <= len) && (CFX_WideStringC(str + cc, wsPM.GetLength()) == wsPM)) {
+ cc += wsPM.GetLength();
+ bHasA = TRUE;
+ bPM = TRUE;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Z', '1')) {
+ if (cc + 3 > len) {
+ continue;
+ }
+ FX_DWORD dwHash = str[cc++];
+ dwHash = (dwHash << 8) | str[cc++];
+ dwHash = (dwHash << 8) | str[cc++];
+ if (dwHash == FXBSTR_ID(0, 'G', 'M', 'T')) {
+ FX_TIMEZONE tzDiff;
+ tzDiff.tzHour = 0;
+ tzDiff.tzMinute = 0;
+ if (cc < len && (str[cc] == '-' || str[cc] == '+')) {
+ cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
+ }
+ FX_ResolveZone(hour, minute, tzDiff, pLocale);
+ } else {
+ FX_LPCLOCALETIMEZONEINFO pTimeZoneInfo = NULL;
+ FX_INT32 iStart = 0, iEnd = g_iFXLocaleTimeZoneCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ FX_LPCLOCALETIMEZONEINFO pInfo = g_FXLocaleTimeZoneData + iMid;
+ if (dwHash == pInfo->uHash) {
+ pTimeZoneInfo = pInfo;
+ break;
+ } else if (dwHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ if (pTimeZoneInfo) {
+ hour += pTimeZoneInfo->iHour;
+ minute += pTimeZoneInfo->iHour > 0 ? pTimeZoneInfo->iMinute : -pTimeZoneInfo->iMinute;
+ }
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'z', '1')) {
+ if (str[cc] != 'Z') {
+ FX_TIMEZONE tzDiff;
+ cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
+ FX_ResolveZone(hour, minute, tzDiff, pLocale);
+ } else {
+ cc++;
+ }
+ }
+ }
+ if (bHasA) {
+ if (bPM) {
+ hour += 12;
+ if (hour == 24) {
+ hour = 12;
+ }
+ } else {
+ if (hour == 12) {
+ hour = 0;
+ }
+ }
+ }
+ CFX_Unitime ut;
+ ut.Set(0, 0, 0, hour, minute, second, millisecond);
+ datetime = datetime + ut;
+ return cc;
+}
+FX_BOOL CFX_FormatString::ParseDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, FX_DATETIMETYPE eDateTimeType, CFX_Unitime& dtValue)
+{
+ dtValue.Set(0);
+ if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory = GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (!pLocale) {
+ return FALSE;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ eCategory = eDateTimeType;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ return FALSE;
+ }
+ if (eCategory == FX_DATETIMETYPE_TimeDate) {
+ FX_INT32 iStart = 0;
+ if (!FX_ParseLocaleTime(wsSrcDateTime, wsTimePattern, pLocale, dtValue, iStart)) {
+ return FALSE;
+ }
+ if (!FX_ParseLocaleDate(wsSrcDateTime, wsDatePattern, pLocale, dtValue, iStart)) {
+ return FALSE;
+ }
+ } else {
+ FX_INT32 iStart = 0;
+ if ((eCategory & FX_DATETIMETYPE_Date) && !FX_ParseLocaleDate(wsSrcDateTime, wsDatePattern, pLocale, dtValue, iStart)) {
+ return FALSE;
+ }
+ if ((eCategory & FX_DATETIMETYPE_Time) && !FX_ParseLocaleTime(wsSrcDateTime, wsTimePattern, pLocale, dtValue, iStart)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::ParseZero(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern)
+{
+ CFX_WideString wsTextFormat;
+ IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat);
+ FX_INT32 iText = 0, iPattern = 0;
+ FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText;
+ FX_INT32 iLenText = wsSrcText.GetLength();
+ FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat;
+ FX_INT32 iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern && iText < iLenText) {
+ if (pStrPattern[iPattern] == '\'') {
+ CFX_WideString wsLiteral = FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ if (iText + iLiteralLen > iLenText || FXSYS_wcsncmp(pStrText + iText, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ iText += iLiteralLen;
+ iPattern++;
+ continue;
+ } else if (pStrPattern[iPattern] != pStrText[iText]) {
+ return FALSE;
+ } else {
+ iText++;
+ iPattern++;
+ }
+ }
+ return iPattern == iLenPattern && iText == iLenText;
+}
+FX_BOOL CFX_FormatString::ParseNull(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern)
+{
+ CFX_WideString wsTextFormat;
+ IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat);
+ FX_INT32 iText = 0, iPattern = 0;
+ FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText;
+ FX_INT32 iLenText = wsSrcText.GetLength();
+ FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat;
+ FX_INT32 iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern && iText < iLenText) {
+ if (pStrPattern[iPattern] == '\'') {
+ CFX_WideString wsLiteral = FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ FX_INT32 iLiteralLen = wsLiteral.GetLength();
+ if (iText + iLiteralLen > iLenText || FXSYS_wcsncmp(pStrText + iText, (FX_LPCWSTR)wsLiteral, iLiteralLen)) {
+ return FALSE;
+ }
+ iText += iLiteralLen;
+ iPattern++;
+ continue;
+ } else if (pStrPattern[iPattern] != pStrText[iText]) {
+ return FALSE;
+ } else {
+ iText++;
+ iPattern++;
+ }
+ }
+ return iPattern == iLenPattern && iText == iLenText;
+}
+FX_BOOL CFX_FormatString::FormatText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 iLenText = wsSrcText.GetLength();
+ if (iLenText == 0) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"text"), wsTextFormat);
+ FX_INT32 iText = 0, iPattern = 0;
+ FX_LPCWSTR pStrText = (FX_LPCWSTR)wsSrcText;
+ FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat;
+ FX_INT32 iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern) {
+ switch (pStrPattern[iPattern]) {
+ case '\'': {
+ wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ iPattern++;
+ break;
+ }
+ case 'A':
+ if (iText >= iLenText || !FX_IsAlpha(pStrText[iText])) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ case 'X':
+ if (iText >= iLenText) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ case 'O':
+ case '0':
+ if (iText >= iLenText || (!FX_IsDigit(pStrText[iText]) && !FX_IsAlpha(pStrText[iText]))) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ case '9':
+ if (iText >= iLenText || !FX_IsDigit(pStrText[iText])) {
+ return FALSE;
+ }
+ wsOutput += pStrText[iText++];
+ iPattern++;
+ break;
+ default:
+ wsOutput += pStrPattern[iPattern++];
+ break;
+ }
+ }
+ return iText == iLenText;
+}
+static FX_INT32 FX_GetNumTrailingLimit(const CFX_WideString& wsFormat, int iDotPos, FX_BOOL &bTrimTailZeros)
+{
+ if (iDotPos < 0) {
+ return 0;
+ }
+ FX_INT32 iCount = wsFormat.GetLength();
+ FX_INT32 iTreading = 0;
+ for (iDotPos ++; iDotPos < iCount; iDotPos ++) {
+ FX_WCHAR wc = wsFormat[iDotPos];
+ if (wc == L'z' || wc == L'9' || wc == 'Z') {
+ iTreading ++;
+ bTrimTailZeros = (wc == L'9' ? FALSE : TRUE);
+ }
+ }
+ return iTreading;
+}
+FX_BOOL CFX_FormatString::FormatStrNum(FX_WSTR wsInputNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsInputNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 dot_index_f = -1;
+ FX_DWORD dwNumStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale = GetNumericFormat(wsPattern, dot_index_f, dwNumStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 cc = 0, ccf = 0;
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ CFX_WideString wsSrcNum = wsInputNum;
+ wsSrcNum.TrimLeft('0');
+ if (wsSrcNum.IsEmpty() || wsSrcNum[0] == '.') {
+ wsSrcNum.Insert(0, '0');
+ }
+ CFX_Decimal decimal = CFX_Decimal(wsSrcNum);
+ if (dwNumStyle & FX_NUMSTYLE_Percent) {
+ decimal = decimal * CFX_Decimal(100);
+ wsSrcNum = decimal;
+ }
+ FX_INT32 exponent = 0;
+ if (dwNumStyle & FX_NUMSTYLE_Exponent) {
+ int fixed_count = 0;
+ while (ccf < dot_index_f) {
+ switch (strf[ccf]) {
+ case '\'':
+ FX_GetLiteralText(strf, ccf, dot_index_f);
+ break;
+ case '9':
+ case 'z':
+ case 'Z':
+ fixed_count++;
+ break;
+ }
+ ccf++;
+ }
+ int threshold = 1;
+ while (fixed_count > 1) {
+ threshold *= 10;
+ fixed_count--;
+ }
+ if (decimal != CFX_Decimal(0)) {
+ if (decimal < CFX_Decimal(threshold)) {
+ decimal = decimal * CFX_Decimal(10);
+ exponent = -1;
+ while (decimal < CFX_Decimal(threshold)) {
+ decimal = decimal * CFX_Decimal(10);
+ exponent -= 1;
+ }
+ } else if (decimal > CFX_Decimal(threshold)) {
+ threshold *= 10;
+ while (decimal > CFX_Decimal(threshold)) {
+ decimal = decimal / CFX_Decimal(10);
+ exponent += 1;
+ }
+ }
+ }
+ }
+ FX_BOOL bTrimTailZeros = FALSE;
+ FX_INT32 iTreading = FX_GetNumTrailingLimit(wsNumFormat, dot_index_f, bTrimTailZeros);
+ FX_INT32 scale = decimal.GetScale();
+ if (iTreading < scale) {
+ decimal.SetScale(iTreading);
+ wsSrcNum = decimal;
+ }
+ if (bTrimTailZeros && scale > 0 && iTreading > 0) {
+ wsSrcNum.TrimRight((FX_LPCWSTR)L"0");
+ wsSrcNum.TrimRight((FX_LPCWSTR)L".");
+ }
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ FX_BOOL bNeg = FALSE;
+ if (wsSrcNum[0] == '-') {
+ bNeg = TRUE;
+ wsSrcNum.Delete(0, 1);
+ }
+ FX_BOOL bAddNeg = FALSE;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsSrcNum;
+ int len = wsSrcNum.GetLength();
+ int dot_index = wsSrcNum.Find('.');
+ if (dot_index == -1) {
+ dot_index = len;
+ }
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ while (ccf >= 0) {
+ switch (strf[ccf]) {
+ case '9':
+ if (cc >= 0) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L'0') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'z':
+ if (cc >= 0) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ if (str[0] != '0') {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (cc >= 0) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ if (str[0] == '0') {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ } else {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format((FX_LPCWSTR)L"E%+d", exponent);
+ wsOutput = wsExp + wsOutput;
+ }
+ ccf--;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (bNeg) {
+ wsOutput = L"db" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (bNeg) {
+ wsOutput = L"DB" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case ',':
+ if (cc >= 0) {
+ wsOutput = wsGroupSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput = L"(" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ bAddNeg = TRUE;
+ ccf--;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput = L")" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf--;
+ break;
+ case '\'':
+ wsOutput = FX_GetLiteralTextReverse(strf, ccf) + wsOutput;
+ ccf--;
+ break;
+ default:
+ wsOutput = CFX_WideStringC(strf[ccf]) + wsOutput;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ int nPos = dot_index % 3;
+ wsOutput.Empty();
+ for (FX_INT32 i = 0; i < dot_index; i++) {
+ if (i % 3 == nPos && i != 0) {
+ wsOutput += wsGroupSymbol;
+ }
+ wsOutput += wsSrcNum[i];
+ }
+ if (dot_index < len) {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
+ wsOutput += wsSymbol;
+ wsOutput += wsSrcNum.Right(len - dot_index - 1);
+ }
+ if (bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return FALSE;
+ }
+ if (dot_index_f == wsNumFormat.GetLength()) {
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return TRUE;
+ }
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ if (strf[dot_index_f] == 'V') {
+ wsOutput += wsDotSymbol;
+ } else if (strf[dot_index_f] == '.') {
+ if (dot_index < len) {
+ wsOutput += wsDotSymbol;
+ } else {
+ if (strf[dot_index_f + 1] == '9' || strf[dot_index_f + 1] == 'Z') {
+ wsOutput += wsDotSymbol;
+ }
+ }
+ }
+ ccf = dot_index_f + 1;
+ cc = dot_index + 1;
+ while (ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'':
+ wsOutput += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ break;
+ case '9':
+ if (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'z':
+ if (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput += str[cc];
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (cc < len) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format((FX_LPCWSTR)L"E%+d", exponent);
+ wsOutput += wsExp;
+ }
+ ccf++;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (bNeg) {
+ wsOutput += L"db";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (bNeg) {
+ wsOutput += L"DB";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ wsOutput += str[cc];
+ cc++;
+ }
+ }
+ break;
+ case ',':
+ wsOutput += wsGroupSymbol;
+ ccf++;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput += '(';
+ } else {
+ wsOutput += ' ';
+ }
+ bAddNeg = TRUE;
+ ccf++;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput += ')';
+ } else {
+ wsOutput += ' ';
+ }
+ ccf++;
+ break;
+ default:
+ ccf++;
+ }
+ }
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput[0] + wsOutput.Mid(1, wsOutput.GetLength() - 1);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::FormatLCNumeric(CFX_LCNumeric& lcNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ FX_INT32 dot_index_f = -1;
+ FX_DWORD dwNumStyle = 0;
+ CFX_WideString wsNumFormat;
+ IFX_Locale* pLocale = GetNumericFormat(wsPattern, dot_index_f, dwNumStyle, wsNumFormat);
+ if (!pLocale || wsNumFormat.IsEmpty()) {
+ return FALSE;
+ }
+ FX_INT32 cc = 0, ccf = 0;
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsNumFormat;
+ int lenf = wsNumFormat.GetLength();
+ double dbOrgRaw = lcNum.GetDouble();
+ double dbRetValue = dbOrgRaw;
+ if (dwNumStyle & FX_NUMSTYLE_Percent) {
+ dbRetValue *= 100;
+ }
+ FX_INT32 exponent = 0;
+ if (dwNumStyle & FX_NUMSTYLE_Exponent) {
+ int fixed_count = 0;
+ while (ccf < dot_index_f) {
+ switch (strf[ccf]) {
+ case '\'':
+ FX_GetLiteralText(strf, ccf, dot_index_f);
+ break;
+ case '9':
+ case 'z':
+ case 'Z':
+ fixed_count++;
+ break;
+ }
+ ccf++;
+ }
+ int threshold = 1;
+ while (fixed_count > 1) {
+ threshold *= 10;
+ fixed_count--;
+ }
+ if (dbRetValue != 0) {
+ if (dbRetValue < threshold) {
+ dbRetValue *= 10;
+ exponent = -1;
+ while (dbRetValue < threshold) {
+ dbRetValue *= 10;
+ exponent -= 1;
+ }
+ } else if (dbRetValue > threshold) {
+ threshold *= 10;
+ while (dbRetValue > threshold) {
+ dbRetValue /= 10;
+ exponent += 1;
+ }
+ }
+ }
+ }
+ if (dwNumStyle & (FX_NUMSTYLE_Percent | FX_NUMSTYLE_Exponent)) {
+ lcNum = CFX_LCNumeric(dbRetValue);
+ }
+ FX_BOOL bTrimTailZeros = FALSE;
+ FX_INT32 iTreading = FX_GetNumTrailingLimit(wsNumFormat, dot_index_f, bTrimTailZeros);
+ CFX_WideString wsNumeric = lcNum.ToString(iTreading, bTrimTailZeros);
+ if (wsNumeric.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ FX_BOOL bNeg = FALSE;
+ if (wsNumeric[0] == '-') {
+ bNeg = TRUE;
+ wsNumeric.Delete(0, 1);
+ }
+ FX_BOOL bAddNeg = FALSE;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsNumeric;
+ int len = wsNumeric.GetLength();
+ int dot_index = wsNumeric.Find('.');
+ if (dot_index == -1) {
+ dot_index = len;
+ }
+ ccf = dot_index_f - 1;
+ cc = dot_index - 1;
+ while (ccf >= 0) {
+ switch (strf[ccf]) {
+ case '9':
+ if (cc >= 0) {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L'0') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'z':
+ if (cc >= 0) {
+ if (lcNum.m_Integral != 0) {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ }
+ ccf--;
+ break;
+ case 'Z':
+ if (cc >= 0) {
+ if (lcNum.m_Integral == 0) {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ } else {
+ wsOutput = CFX_WideStringC(str[cc]) + wsOutput;
+ }
+ cc--;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'S':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ } else {
+ wsOutput = CFX_WideStringC(L' ') + wsOutput;
+ }
+ ccf--;
+ break;
+ case 's':
+ if (bNeg) {
+ CFX_WideString wsMinusSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusSymbol);
+ wsOutput = wsMinusSymbol + wsOutput;
+ bAddNeg = TRUE;
+ }
+ ccf--;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format((FX_LPCWSTR)L"E%+d", exponent);
+ wsOutput = wsExp + wsOutput;
+ }
+ ccf--;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case 'r':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'c') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'R':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'C') {
+ if (bNeg) {
+ wsOutput = L"CR" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'b':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'd') {
+ if (bNeg) {
+ wsOutput = L"db" + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'B':
+ if (ccf - 1 >= 0 && strf[ccf - 1] == 'D') {
+ if (bNeg) {
+ wsOutput = L"DB" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf -= 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput = wsSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case ',':
+ if (cc >= 0) {
+ wsOutput = wsGroupSymbol + wsOutput;
+ }
+ ccf--;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput = L"(" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ bAddNeg = TRUE;
+ ccf--;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput = L")" + wsOutput;
+ } else {
+ wsOutput = L" " + wsOutput;
+ }
+ ccf--;
+ break;
+ case '\'':
+ wsOutput = FX_GetLiteralTextReverse(strf, ccf) + wsOutput;
+ ccf--;
+ break;
+ default:
+ wsOutput = CFX_WideStringC(strf[ccf]) + wsOutput;
+ ccf--;
+ }
+ }
+ if (cc >= 0) {
+ int nPos = dot_index % 3;
+ wsOutput.Empty();
+ for (FX_INT32 i = 0; i < dot_index; i++) {
+ if (i % 3 == nPos && i != 0) {
+ wsOutput += wsGroupSymbol;
+ }
+ wsOutput += wsNumeric[i];
+ }
+ if (dot_index < len) {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
+ wsOutput += wsSymbol;
+ wsOutput += wsNumeric.Right(len - dot_index - 1);
+ }
+ if (bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return FALSE;
+ }
+ if (dot_index_f == wsNumFormat.GetLength()) {
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ return TRUE;
+ }
+ CFX_WideString wsDotSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDotSymbol);
+ if (strf[dot_index_f] == 'V') {
+ wsOutput += wsDotSymbol;
+ } else if (strf[dot_index_f] == '.') {
+ if (dot_index < len) {
+ wsOutput += wsDotSymbol;
+ } else {
+ if (strf[dot_index_f + 1] == '9' || strf[dot_index_f + 1] == 'Z') {
+ wsOutput += wsDotSymbol;
+ }
+ }
+ }
+ ccf = dot_index_f + 1;
+ cc = dot_index + 1;
+ while (ccf < lenf) {
+ switch (strf[ccf]) {
+ case '\'':
+ wsOutput += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ break;
+ case '9':
+ if (cc < len) {
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'z':
+ if (cc < len) {
+ wsOutput += str[cc];
+ cc++;
+ }
+ ccf++;
+ break;
+ case 'Z':
+ if (cc < len) {
+ wsOutput += str[cc];
+ cc++;
+ } else {
+ wsOutput += L'0';
+ }
+ ccf++;
+ break;
+ case 'E': {
+ CFX_WideString wsExp;
+ wsExp.Format((FX_LPCWSTR)L"E%+d", exponent);
+ wsOutput += wsExp;
+ }
+ ccf++;
+ break;
+ case '$': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_CurrencySymbol, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case 'c':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'r') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'C':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'R') {
+ if (bNeg) {
+ wsOutput += L"CR";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'd':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'b') {
+ if (bNeg) {
+ wsOutput += L"db";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case 'D':
+ if (ccf + 1 < lenf && strf[ccf + 1] == 'B') {
+ if (bNeg) {
+ wsOutput += L"DB";
+ } else {
+ wsOutput += L" ";
+ }
+ ccf += 2;
+ bAddNeg = TRUE;
+ }
+ break;
+ case '%': {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Percent, wsSymbol);
+ wsOutput += wsSymbol;
+ }
+ ccf++;
+ break;
+ case '8': {
+ while (ccf < lenf && strf[ccf] == '8') {
+ ccf++;
+ }
+ while (cc < len && FX_IsDigit(str[cc])) {
+ wsOutput += str[cc];
+ cc++;
+ }
+ }
+ break;
+ case ',':
+ wsOutput += wsGroupSymbol;
+ ccf++;
+ break;
+ case '(':
+ if (bNeg) {
+ wsOutput += '(';
+ } else {
+ wsOutput += ' ';
+ }
+ bAddNeg = TRUE;
+ ccf++;
+ break;
+ case ')':
+ if (bNeg) {
+ wsOutput += ')';
+ } else {
+ wsOutput += ' ';
+ }
+ ccf++;
+ break;
+ default:
+ ccf++;
+ }
+ }
+ if (!bAddNeg && bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsOutput[0] + wsMinusymbol + wsOutput.Mid(1, wsOutput.GetLength() - 1);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::FormatNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsSrcNum.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ return FormatStrNum(wsSrcNum, wsPattern, wsOutput);
+}
+FX_BOOL CFX_FormatString::FormatNum(FX_FLOAT fNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_LCNumeric lcNum(fNum);
+ return FormatLCNumeric(lcNum, wsPattern, wsOutput);
+}
+FX_BOOL FX_DateFromCanonical(const CFX_WideString& wsDate, CFX_Unitime& datetime)
+{
+ FX_INT32 year = 1900;
+ FX_INT32 month = 1;
+ FX_INT32 day = 1;
+ FX_WORD wYear = 0;
+ int cc_start = 0, cc = 0;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsDate;
+ int len = wsDate.GetLength();
+ if(len > 10) {
+ return FALSE;
+ }
+ while (cc < len && cc < 4) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ wYear = wYear * 10 + str[cc++] - '0';
+ }
+ year = wYear;
+ if (cc < 4 || wYear < 1900) {
+ return FALSE;
+ }
+ if(cc < len) {
+ if (str[cc] == '-') {
+ cc++;
+ }
+ cc_start = cc;
+ FX_BYTE tmpM = 0;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ tmpM = tmpM * 10 + str[cc++] - '0';
+ }
+ month = tmpM;
+ if (cc == cc_start + 1 || tmpM > 12 || tmpM < 1) {
+ return FALSE;
+ }
+ if(cc < len) {
+ if (str[cc] == '-') {
+ cc++;
+ }
+ FX_BYTE tmpD = 0;
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ tmpD = tmpD * 10 + str[cc++] - '0';
+ }
+ day = tmpD;
+ if (tmpD < 1) {
+ return FALSE;
+ }
+ if ((tmpM == 1 || tmpM == 3 || tmpM == 5 || tmpM == 7 || tmpM == 8 || tmpM == 10 || tmpM == 12) && tmpD > 31) {
+ return FALSE;
+ }
+ if((tmpM == 4 || tmpM == 6 || tmpM == 9 || tmpM == 11) && tmpD > 30) {
+ return FALSE;
+ }
+ FX_BOOL iLeapYear;
+ if((wYear % 4 == 0 && wYear % 100 != 0 ) || wYear % 400 == 0) {
+ iLeapYear = TRUE;
+ } else {
+ iLeapYear = FALSE;
+ }
+ if ((iLeapYear && tmpM == 2 && tmpD > 29) || (!iLeapYear && tmpM == 2 && tmpD > 28)) {
+ return FALSE;
+ }
+ }
+ }
+ CFX_Unitime ut;
+ ut.Set(year, month, day);
+ datetime = datetime + ut;
+ return TRUE;
+}
+FX_BOOL FX_TimeFromCanonical(FX_WSTR wsTime, CFX_Unitime& datetime, IFX_Locale* pLocale)
+{
+ if (wsTime.GetLength() == 0) {
+ return FALSE;
+ }
+ FX_BYTE hour = 0;
+ FX_BYTE minute = 0;
+ FX_BYTE second = 0;
+ FX_WORD millisecond = 0;
+ int cc_start = 0, cc = cc_start;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsTime.GetPtr();
+ int len = wsTime.GetLength();
+ while (cc < len && cc < 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ hour = hour * 10 + str[cc++] - '0';
+ }
+ if (cc < 2 || hour >= 24) {
+ return FALSE;
+ }
+ if(cc < len) {
+ if (str[cc] == ':') {
+ cc++;
+ }
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ minute = minute * 10 + str[cc++] - '0';
+ }
+ if (cc == cc_start + 1 || minute >= 60) {
+ return FALSE;
+ }
+ if(cc < len) {
+ if (str[cc] == ':') {
+ cc++;
+ }
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 2) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ second = second * 10 + str[cc++] - '0';
+ }
+ if (cc == cc_start + 1 || second >= 60) {
+ return FALSE;
+ }
+ if(cc < len) {
+ if (str[cc] == '.') {
+ cc++;
+ cc_start = cc;
+ while (cc < len && cc < cc_start + 3) {
+ if (!FX_IsDigit(str[cc])) {
+ return FALSE;
+ }
+ millisecond = millisecond * 10 + str[cc++] - '0';
+ }
+ if (cc < cc_start + 3 || millisecond >= 1000) {
+ return FALSE;
+ }
+ }
+ if(cc < len) {
+ FX_TIMEZONE tzDiff;
+ tzDiff.tzHour = 0;
+ tzDiff.tzMinute = 0;
+ if (str[cc] != 'Z') {
+ cc += FX_ParseTimeZone(str + cc, len - cc, tzDiff);
+ }
+ FX_ResolveZone(hour, minute, tzDiff, pLocale);
+ }
+ }
+ }
+ }
+ CFX_Unitime ut;
+ ut.Set(0, 0, 0, hour, minute, second, millisecond);
+ datetime = datetime + ut;
+ return TRUE;
+}
+static FX_WORD FX_GetSolarMonthDays(FX_WORD year, FX_WORD month)
+{
+ if (month % 2) {
+ return 31;
+ } else if (month == 2) {
+ return FX_IsLeapYear(year) ? 29 : 28;
+ }
+ return 30;
+}
+static FX_WORD FX_GetWeekDay(FX_WORD year, FX_WORD month, FX_WORD day)
+{
+ FX_WORD g_month_day[] = { 0, 3, 3, 6, 1, 4, 6, 2, 5, 0, 3, 5 };
+ FX_WORD nDays = (year - 1) % 7 + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400;
+ nDays += g_month_day[month - 1] + day;
+ if (FX_IsLeapYear(year) && month > 2) {
+ nDays++;
+ }
+ return nDays % 7;
+}
+static FX_WORD FX_GetWeekOfMonth(FX_WORD year, FX_WORD month, FX_WORD day)
+{
+ FX_WORD week_day = FX_GetWeekDay(year, month, 1);
+ FX_WORD week_index = 0;
+ week_index += day / 7;
+ day = day % 7;
+ if (week_day + day > 7) {
+ week_index++;
+ }
+ return week_index;
+}
+static FX_WORD FX_GetWeekOfYear(FX_WORD year, FX_WORD month, FX_WORD day)
+{
+ FX_WORD nDays = 0;
+ for (FX_WORD i = 1; i < month; i++) {
+ nDays += FX_GetSolarMonthDays(year, i);
+ }
+ nDays += day;
+ FX_WORD week_day = FX_GetWeekDay(year, 1, 1);
+ FX_WORD week_index = 1;
+ week_index += nDays / 7;
+ nDays = nDays % 7;
+ if (week_day + nDays > 7) {
+ week_index++;
+ }
+ return week_index;
+}
+static FX_BOOL FX_DateFormat(const CFX_WideString& wsDatePattern, IFX_Locale *pLocale, const CFX_Unitime &datetime, CFX_WideString& wsResult)
+{
+ FX_BOOL bRet = TRUE;
+ FX_INT32 year = datetime.GetYear();
+ FX_BYTE month = datetime.GetMonth();
+ FX_BYTE day = datetime.GetDay();
+ FX_INT32 ccf = 0;
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsDatePattern;
+ FX_INT32 lenf = wsDatePattern.GetLength();
+ while (ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ wsResult += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsDateSymbols, strf[ccf]) < 0) {
+ wsResult += strf[ccf++];
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'D', '1')) {
+ CFX_WideString wsDay;
+ wsDay.Format((FX_LPCWSTR)L"%d", day);
+ wsResult += wsDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'D', '2')) {
+ CFX_WideString wsDay;
+ wsDay.Format((FX_LPCWSTR)L"%02d", day);
+ wsResult += wsDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '1')) {
+ FX_WORD nDays = 0;
+ for (int i = 1; i < month; i++) {
+ nDays += FX_GetSolarMonthDays(year, i);
+ }
+ nDays += day;
+ CFX_WideString wsDays;
+ wsDays.Format((FX_LPCWSTR)L"%d", nDays);
+ wsResult += wsDays;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'J', '3')) {
+ FX_WORD nDays = 0;
+ for (int i = 1; i < month; i++) {
+ nDays += FX_GetSolarMonthDays(year, i);
+ }
+ nDays += day;
+ CFX_WideString wsDays;
+ wsDays.Format((FX_LPCWSTR)L"%03d", nDays);
+ wsResult += wsDays;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ CFX_WideString wsMonth;
+ wsMonth.Format((FX_LPCWSTR)L"%d", month);
+ wsResult += wsMonth;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ CFX_WideString wsMonth;
+ wsMonth.Format((FX_LPCWSTR)L"%02d", month);
+ wsResult += wsMonth;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '3')) {
+ CFX_WideString wsTemp;
+ pLocale->GetMonthName(month - 1, wsTemp, TRUE);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '4')) {
+ CFX_WideString wsTemp;
+ pLocale->GetMonthName(month - 1, wsTemp, FALSE);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '1')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ CFX_WideString wsWeekDay;
+ wsWeekDay.Format((FX_LPCWSTR)L"%d", wWeekDay + 1);
+ wsResult += wsWeekDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '3')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ CFX_WideString wsTemp;
+ pLocale->GetDayName(wWeekDay, wsTemp, TRUE);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'E', '4')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ if (pLocale) {
+ CFX_WideString wsTemp;
+ pLocale->GetDayName(wWeekDay, wsTemp, FALSE);
+ wsResult += wsTemp;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'e', '1')) {
+ FX_WORD wWeekDay = FX_GetWeekDay(year, month, day);
+ CFX_WideString wsWeekDay;
+ wsWeekDay.Format((FX_LPCWSTR)L"%d", wWeekDay ? wWeekDay : 7);
+ wsResult += wsWeekDay;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'G', '1')) {
+ CFX_WideString wsTemp;
+ pLocale->GetEraName(wsTemp, year < 0);
+ wsResult += wsTemp;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '2')) {
+ CFX_WideString wsYear;
+ wsYear.Format((FX_LPCWSTR)L"%02d", year % 100);
+ wsResult += wsYear;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Y', '4')) {
+ CFX_WideString wsYear;
+ wsYear.Format((FX_LPCWSTR)L"%d", year);
+ wsResult += wsYear;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'w', '1')) {
+ FX_WORD week_index = FX_GetWeekOfMonth(year, month, day);
+ CFX_WideString wsWeekInMonth;
+ wsWeekInMonth.Format((FX_LPCWSTR)L"%d", week_index);
+ wsResult += wsWeekInMonth;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'W', '2')) {
+ FX_WORD week_index = FX_GetWeekOfYear(year, month, day);
+ CFX_WideString wsWeekInYear;
+ wsWeekInYear.Format((FX_LPCWSTR)L"%02d", week_index);
+ wsResult += wsWeekInYear;
+ }
+ }
+ return bRet;
+}
+static FX_BOOL FX_TimeFormat(const CFX_WideString& wsTimePattern, IFX_Locale *pLocale, const CFX_Unitime &datetime, CFX_WideString& wsResult)
+{
+ FX_BOOL bGMT = FALSE;
+ FX_BOOL bRet = TRUE;
+ FX_BYTE hour = datetime.GetHour();
+ FX_BYTE minute = datetime.GetMinute();
+ FX_BYTE second = datetime.GetSecond();
+ FX_WORD millisecond = datetime.GetMillisecond();
+ FX_INT32 ccf = 0;
+ FX_LPCWSTR strf = (FX_LPCWSTR)wsTimePattern;
+ FX_INT32 lenf = wsTimePattern.GetLength();
+ FX_WORD wHour = hour;
+ FX_BOOL bPM = FALSE;
+ if (wsTimePattern.Find('A') != -1) {
+ if (wHour >= 12) {
+ bPM = TRUE;
+ }
+ }
+ while (ccf < lenf) {
+ if (strf[ccf] == '\'') {
+ wsResult += FX_GetLiteralText(strf, ccf, lenf);
+ ccf++;
+ continue;
+ } else if (FX_Local_Find(gs_wsTimeSymbols, strf[ccf]) < 0) {
+ wsResult += strf[ccf++];
+ continue;
+ }
+ FX_DWORD dwSymbolNum = 1;
+ FX_DWORD dwSymbol = strf[ccf++];
+ while (ccf < lenf && strf[ccf] == dwSymbol) {
+ ccf++;
+ dwSymbolNum++;
+ }
+ dwSymbol = (dwSymbol << 8) | (dwSymbolNum + '0');
+ if (dwSymbol == FXBSTR_ID(0, 0, 'h', '1')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%d", wHour == 0 ? 12 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'h', '2')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%02d", wHour == 0 ? 12 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '1')) {
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%d", wHour == 0 ? 24 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'K', '2')) {
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%02d", wHour == 0 ? 24 : wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '1')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '1')) {
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'k', '2')) {
+ if (wHour > 12) {
+ wHour -= 12;
+ }
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%02d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'H', '2')) {
+ CFX_WideString wsHour;
+ wsHour.Format((FX_LPCWSTR)L"%02d", wHour);
+ wsResult += wsHour;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '1')) {
+ CFX_WideString wsMinute;
+ wsMinute.Format((FX_LPCWSTR)L"%d", minute);
+ wsResult += wsMinute;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'M', '2')) {
+ CFX_WideString wsMinute;
+ wsMinute.Format((FX_LPCWSTR)L"%02d", minute);
+ wsResult += wsMinute;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '1')) {
+ CFX_WideString wsSecond;
+ wsSecond.Format((FX_LPCWSTR)L"%d", second);
+ wsResult += wsSecond;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'S', '2')) {
+ CFX_WideString wsSecond;
+ wsSecond.Format((FX_LPCWSTR)L"%02d", second);
+ wsResult += wsSecond;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'F', '3')) {
+ CFX_WideString wsMilliseconds;
+ wsMilliseconds.Format((FX_LPCWSTR)L"%03d", millisecond);
+ wsResult += wsMilliseconds;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'A', '1')) {
+ CFX_WideString wsMeridiem;
+ pLocale->GetMeridiemName(wsMeridiem, !bPM);
+ wsResult += wsMeridiem;
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'Z', '1')) {
+ wsResult += FX_WSTRC(L"GMT");
+ FX_TIMEZONE tz;
+ pLocale->GetTimeZone(tz);
+ if (!bGMT && (tz.tzHour != 0 || tz.tzMinute != 0)) {
+ if (tz.tzHour < 0) {
+ wsResult += FX_WSTRC(L"-");
+ } else {
+ wsResult += FX_WSTRC(L"+");
+ }
+ CFX_WideString wsTimezone;
+ wsTimezone.Format((FX_LPCWSTR)L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute);
+ wsResult += wsTimezone;
+ }
+ } else if (dwSymbol == FXBSTR_ID(0, 0, 'z', '1')) {
+ FX_TIMEZONE tz;
+ pLocale->GetTimeZone(tz);
+ if (!bGMT && tz.tzHour != 0 && tz.tzMinute != 0) {
+ if (tz.tzHour < 0) {
+ wsResult += FX_WSTRC(L"-");
+ } else {
+ wsResult += FX_WSTRC(L"+");
+ }
+ CFX_WideString wsTimezone;
+ wsTimezone.Format((FX_LPCWSTR)L"%02d:%02d", FXSYS_abs(tz.tzHour), tz.tzMinute);
+ wsResult += wsTimezone;
+ }
+ }
+ }
+ return bRet;
+}
+static FX_BOOL FX_FormatDateTime(const CFX_Unitime& dt, const CFX_WideString& wsDatePattern, const CFX_WideString& wsTimePattern,
+ FX_BOOL bDateFirst, IFX_Locale* pLocale, CFX_WideString& wsOutput)
+{
+ FX_BOOL bRet = TRUE;
+ CFX_WideString wsDateOut, wsTimeOut;
+ if (!wsDatePattern.IsEmpty()) {
+ bRet &= FX_DateFormat(wsDatePattern, pLocale, dt, wsDateOut);
+ }
+ if (!wsTimePattern.IsEmpty()) {
+ bRet &= FX_TimeFormat(wsTimePattern, pLocale, dt, wsTimeOut);
+ }
+ wsOutput = bDateFirst ? wsDateOut + wsTimeOut : wsTimeOut + wsDateOut;
+ return bRet;
+}
+FX_BOOL CFX_FormatString::FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory = GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (pLocale == NULL || eCategory == FX_DATETIMETYPE_Unknown) {
+ return FALSE;
+ }
+ CFX_Unitime dt(0);
+ FX_INT32 iT = wsSrcDateTime.Find(L"T");
+ if (iT < 0) {
+ if (eCategory == FX_DATETIMETYPE_Date) {
+ FX_DateFromCanonical(wsSrcDateTime, dt);
+ } else if (eCategory == FX_DATETIMETYPE_Time) {
+ FX_TimeFromCanonical(wsSrcDateTime, dt, pLocale);
+ }
+ } else {
+ FX_DateFromCanonical(wsSrcDateTime.Left(iT), dt);
+ FX_TimeFromCanonical(wsSrcDateTime.Right(wsSrcDateTime.GetLength() - iT - 1), dt, pLocale);
+ }
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, eCategory != FX_DATETIMETYPE_TimeDate, pLocale, wsOutput);
+}
+FX_BOOL CFX_FormatString::FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput, FX_DATETIMETYPE eDateTimeType)
+{
+ if (wsSrcDateTime.IsEmpty() || wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory = GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (!pLocale) {
+ return FALSE;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ if (eDateTimeType == FX_DATETIMETYPE_Time) {
+ wsTimePattern = wsDatePattern;
+ wsDatePattern.Empty();
+ }
+ eCategory = eDateTimeType;
+ }
+ if (eCategory == FX_DATETIMETYPE_Unknown) {
+ return FALSE;
+ }
+ CFX_Unitime dt(0);
+ FX_INT32 iT = wsSrcDateTime.Find(L"T");
+ if (iT < 0) {
+ if (eCategory == FX_DATETIMETYPE_Date && FX_DateFromCanonical(wsSrcDateTime, dt)) {
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, TRUE, pLocale, wsOutput);
+ } else if (eCategory == FX_DATETIMETYPE_Time && FX_TimeFromCanonical(wsSrcDateTime, dt, pLocale)) {
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, TRUE, pLocale, wsOutput);
+ }
+ } else {
+ CFX_WideStringC wsSrcDate((FX_LPCWSTR)wsSrcDateTime, iT);
+ CFX_WideStringC wsSrcTime((FX_LPCWSTR)wsSrcDateTime + iT + 1, wsSrcDateTime.GetLength() - iT - 1);
+ if(wsSrcDate.IsEmpty() || wsSrcTime.IsEmpty()) {
+ return FALSE;
+ }
+ if(FX_DateFromCanonical(wsSrcDate, dt) && FX_TimeFromCanonical(wsSrcTime, dt, pLocale)) {
+ return FX_FormatDateTime(dt, wsDatePattern, wsTimePattern, eCategory != FX_DATETIMETYPE_TimeDate, pLocale, wsOutput);
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CFX_FormatString::FormatDateTime(const CFX_Unitime& dt, const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsDatePattern, wsTimePattern;
+ IFX_Locale* pLocale = NULL;
+ FX_DATETIMETYPE eCategory = GetDateTimeFormat(wsPattern, pLocale, wsDatePattern, wsTimePattern);
+ if (!pLocale) {
+ return FALSE;
+ }
+ return FX_FormatDateTime(dt, wsPattern, wsTimePattern, eCategory != FX_DATETIMETYPE_TimeDate, pLocale, wsOutput);
+}
+FX_BOOL CFX_FormatString::FormatZero(const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"zero"), wsTextFormat);
+ FX_INT32 iPattern = 0;
+ FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat;
+ FX_INT32 iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern) {
+ if (pStrPattern[iPattern] == '\'') {
+ wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ iPattern++;
+ continue;
+ } else {
+ wsOutput += pStrPattern[iPattern++];
+ continue;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_FormatString::FormatNull(const CFX_WideString& wsPattern, CFX_WideString& wsOutput)
+{
+ if (wsPattern.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_WideString wsTextFormat;
+ IFX_Locale* pLocale = GetTextFormat(wsPattern, FX_WSTRC(L"null"), wsTextFormat);
+ FX_INT32 iPattern = 0;
+ FX_LPCWSTR pStrPattern = (FX_LPCWSTR)wsTextFormat;
+ FX_INT32 iLenPattern = wsTextFormat.GetLength();
+ while (iPattern < iLenPattern) {
+ if (pStrPattern[iPattern] == '\'') {
+ wsOutput += FX_GetLiteralText(pStrPattern, iPattern, iLenPattern);
+ iPattern++;
+ continue;
+ } else {
+ wsOutput += pStrPattern[iPattern++];
+ continue;
+ }
+ }
+ return TRUE;
+}
+IFX_Locale* CFX_FormatString::GetPatternLocale(FX_WSTR wsLocale)
+{
+ if (m_bUseLCID) {
+ }
+ return m_pLocaleMgr->GetLocaleByName(wsLocale);
+}
+#define FXMATH_DECIMAL_SCALELIMIT 0x1c
+#define FXMATH_DECIMAL_NEGMASK (0x80000000L)
+#define FXMATH_DECIMAL_FORCEBOOL(x) (!(!(x)))
+#define FXMATH_DECIMAL_MAKEFLAGS(NEG, SCALE) (((SCALE) << 0x10) | ((NEG) ? FXMATH_DECIMAL_NEGMASK : 0))
+#define FXMATH_DECIMAL_FLAGS2NEG(FLAGS) FXMATH_DECIMAL_FORCEBOOL((FLAGS) & FXMATH_DECIMAL_NEGMASK)
+#define FXMATH_DECIMAL_FLAGS2SCALE(FLAGS) ((FX_UINT8)(((FLAGS) & ~FXMATH_DECIMAL_NEGMASK) >> 0x10))
+#define FXMATH_DECIMAL_RSHIFT32BIT(x) ((x)>>0x10>>0x10)
+#define FXMATH_DECIMAL_LSHIFT32BIT(x) ((x)<<0x10<<0x10)
+static inline FX_UINT8 fxmath_decimal_helper_div10(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo)
+{
+ FX_UINT8 retVal;
+ pmid += FXMATH_DECIMAL_LSHIFT32BIT(phi % 0xA);
+ phi /= 0xA;
+ plo += FXMATH_DECIMAL_LSHIFT32BIT(pmid % 0xA);
+ pmid /= 0xA;
+ retVal = plo % 0xA;
+ plo /= 0xA;
+ return retVal;
+}
+static inline FX_UINT8 fxmath_decimal_helper_div10_any(FX_UINT64 nums[], FX_UINT8 numcount)
+{
+ FX_UINT8 retVal = 0;
+ for(int i = numcount - 1; i > 0; i --) {
+ nums[i - 1] += FXMATH_DECIMAL_LSHIFT32BIT(nums[i] % 0xA);
+ nums[i] /= 0xA;
+ }
+ if(numcount) {
+ retVal = nums[0] % 0xA;
+ nums[0] /= 0xA;
+ }
+ return retVal;
+}
+static inline void fxmath_decimal_helper_mul10(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo)
+{
+ plo *= 0xA;
+ pmid = pmid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(plo);
+ plo = (FX_UINT32)plo;
+ phi = phi * 0xA + FXMATH_DECIMAL_RSHIFT32BIT(pmid);
+ pmid = (FX_UINT32)pmid;
+}
+static inline void fxmath_decimal_helper_mul10_any(FX_UINT64 nums[], FX_UINT8 numcount)
+{
+ nums[0] *= 0xA;
+ for(int i = 1; i < numcount; i++) {
+ nums[i] = nums[i] * 0xA + FXMATH_DECIMAL_RSHIFT32BIT (nums[i - 1]);
+ nums[i - 1] = (FX_UINT32)nums[i - 1];
+ }
+}
+static inline void fxmath_decimal_helper_normalize(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo)
+{
+ phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid);
+ pmid = (FX_UINT32)pmid;
+ pmid += FXMATH_DECIMAL_RSHIFT32BIT(plo);
+ plo = (FX_UINT32)plo;
+ phi += FXMATH_DECIMAL_RSHIFT32BIT(pmid);
+ pmid = (FX_UINT32)pmid;
+}
+static inline void fxmath_decimal_helper_normalize_any(FX_UINT64 nums[], FX_UINT8 len)
+{
+ {
+ for(int i = len - 2; i > 0; i --) {
+ nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]);
+ nums[i] = (FX_UINT32)nums[i];
+ }
+ }
+ {
+ for(int i = 0; i < len - 1; i ++) {
+ nums[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(nums[i]);
+ nums[i] = (FX_UINT32)nums[i];
+ }
+ }
+}
+static inline FX_INT8 fxmath_decimal_helper_raw_compare(FX_UINT32 hi1, FX_UINT32 mid1, FX_UINT32 lo1, FX_UINT32 hi2, FX_UINT32 mid2, FX_UINT32 lo2)
+{
+ FX_INT8 retVal = 0;
+ if (!retVal) {
+ retVal += (hi1 > hi2 ? 1 : (hi1 < hi2 ? -1 : 0));
+ }
+ if (!retVal) {
+ retVal += (mid1 > mid2 ? 1 : (mid1 < mid2 ? -1 : 0));
+ }
+ if (!retVal) {
+ retVal += (lo1 > lo2 ? 1 : (lo1 < lo2 ? -1 : 0));
+ }
+ return retVal;
+}
+static inline FX_INT8 fxmath_decimal_helper_raw_compare_any(FX_UINT64 a[], FX_UINT8 al, FX_UINT64 b[], FX_UINT8 bl)
+{
+ FX_INT8 retVal = 0;
+ for(int i = FX_MAX(al - 1, bl - 1); i >= 0; i --) {
+ FX_UINT64 l = (i >= al ? 0 : a[i]), r = (i >= bl ? 0 : b[i]);
+ retVal += (l > r ? 1 : (l < r ? -1 : 0));
+ if(retVal) {
+ return retVal;
+ }
+ }
+ return retVal;
+}
+static inline void fxmath_decimal_helper_dec_any(FX_UINT64 a[], FX_UINT8 al)
+{
+ for(int i = 0; i < al; i ++) {
+ if(a[i]--) {
+ return;
+ }
+ }
+}
+static inline void fxmath_decimal_helper_inc_any(FX_UINT64 a[], FX_UINT8 al)
+{
+ for(int i = 0; i < al; i ++) {
+ a[i]++;
+ if((FX_UINT32)a[i] == a[i]) {
+ return;
+ }
+ a[i] = 0;
+ }
+}
+static inline void fxmath_decimal_helper_raw_mul(FX_UINT64 a[], FX_UINT8 al, FX_UINT64 b[], FX_UINT8 bl, FX_UINT64 c[], FX_UINT8 cl)
+{
+ assert(al + bl <= cl);
+ {
+ for(int i = 0; i < cl; i++) {
+ c[i] = 0;
+ }
+ }
+ {
+ for(int i = 0; i < al; i++) {
+ for(int j = 0; j < bl; j++) {
+ FX_UINT64 m = (FX_UINT64)a[i] * b[j];
+ c[i + j] += (FX_UINT32)m;
+ c[i + j + 1] += FXMATH_DECIMAL_RSHIFT32BIT(m);
+ }
+ }
+ }
+ {
+ for(int i = 0; i < cl - 1; i++) {
+ c[i + 1] += FXMATH_DECIMAL_RSHIFT32BIT(c[i]);
+ c[i] = (FX_UINT32)c[i];
+ }
+ }
+ {
+ for(int i = 0; i < cl; i++) {
+ c[i] = (FX_UINT32)c[i];
+ }
+ }
+}
+static inline void fxmath_decimal_helper_raw_div(FX_UINT64 a[], FX_UINT8 al, FX_UINT64 b[], FX_UINT8 bl, FX_UINT64 c[], FX_UINT8 cl)
+{
+ int i;
+ for(i = 0; i < cl; i++) {
+ c[i] = 0;
+ }
+ FX_UINT64 left[16] = {0}, right[16] = {0};
+ left[0] = 0;
+ for(i = 0; i < al; i++) {
+ right[i] = a[i];
+ }
+ FX_UINT64 tmp[16];
+ while(fxmath_decimal_helper_raw_compare_any(left, al, right, al) <= 0) {
+ FX_UINT64 cur[16];
+ for(i = 0; i < al; i++) {
+ cur[i] = left[i] + right[i];
+ }
+ for(i = al - 1; i >= 0; i--) {
+ if(i) {
+ cur[i - 1] += FXMATH_DECIMAL_LSHIFT32BIT(cur[i] % 2);
+ }
+ cur[i] /= 2;
+ }
+ fxmath_decimal_helper_raw_mul(cur, al, b, bl, tmp, 16);
+ switch(fxmath_decimal_helper_raw_compare_any(tmp, 16, a, al)) {
+ case -1:
+ for(i = 0; i < 16; i++) {
+ left[i] = cur[i];
+ }
+ left[0]++;
+ fxmath_decimal_helper_normalize_any(left, al);
+ break;
+ case 1:
+ for(i = 0; i < 16; i++) {
+ right[i] = cur[i];
+ }
+ fxmath_decimal_helper_dec_any(right, al);
+ break;
+ case 0:
+ for(i = 0; i < FX_MIN(al, cl); i++) {
+ c[i] = cur[i];
+ }
+ return;
+ }
+ }
+ for(i = 0; i < FX_MIN(al, cl); i++) {
+ c[i] = left[i];
+ }
+}
+static inline FX_BOOL fxmath_decimal_helper_outofrange(FX_UINT64 a[], FX_UINT8 al, FX_UINT8 goal)
+{
+ for(int i = goal; i < al; i++) {
+ if(a[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+static inline void fxmath_decimal_helper_shrinkintorange(FX_UINT64 a[], FX_UINT8 al, FX_UINT8 goal, FX_UINT8& scale)
+{
+ FX_BOOL bRoundUp = FALSE;
+ while(scale != 0 && (scale > FXMATH_DECIMAL_SCALELIMIT || fxmath_decimal_helper_outofrange(a, al, goal))) {
+ bRoundUp = fxmath_decimal_helper_div10_any(a, al) >= 5;
+ scale --;
+ }
+ if(bRoundUp) {
+ fxmath_decimal_helper_normalize_any(a, goal);
+ fxmath_decimal_helper_inc_any(a, goal);
+ }
+}
+static inline void fxmath_decimal_helper_truncate(FX_UINT64& phi, FX_UINT64& pmid, FX_UINT64& plo, FX_UINT8& scale, FX_UINT8 minscale = 0)
+{
+ while(scale > minscale) {
+ FX_UINT64 thi = phi, tmid = pmid, tlo = plo;
+ if(fxmath_decimal_helper_div10(thi, tmid, tlo) != 0) {
+ break;
+ }
+ phi = thi, pmid = tmid, plo = tlo;
+ scale--;
+ }
+}
+CFX_Decimal::CFX_Decimal()
+{
+ m_uLo = m_uMid = m_uHi = m_uFlags = 0;
+}
+CFX_Decimal::CFX_Decimal(FX_UINT64 val)
+{
+ m_uLo = (FX_UINT32)val;
+ m_uMid = (FX_UINT32)FXMATH_DECIMAL_RSHIFT32BIT(val);
+ m_uHi = 0;
+ m_uFlags = 0;
+}
+CFX_Decimal::CFX_Decimal(FX_UINT32 val)
+{
+ m_uLo = (FX_UINT32)val;
+ m_uMid = m_uHi = 0;
+ m_uFlags = 0;
+}
+CFX_Decimal::CFX_Decimal(FX_UINT32 lo, FX_UINT32 mid, FX_UINT32 hi, FX_BOOL neg, FX_UINT8 scale)
+{
+ scale = (scale > FXMATH_DECIMAL_SCALELIMIT ? 0 : scale);
+ m_uLo = lo;
+ m_uMid = mid;
+ m_uHi = hi;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(neg && IsNotZero(), scale);
+}
+CFX_Decimal::CFX_Decimal(FX_INT32 val)
+{
+ if(val >= 0) {
+ *this = CFX_Decimal((FX_UINT32)val);
+ } else {
+ *this = CFX_Decimal((FX_UINT32) - val);
+ SetNegate();
+ }
+}
+CFX_Decimal::CFX_Decimal(FX_INT64 val)
+{
+ if(val >= 0) {
+ *this = CFX_Decimal((FX_UINT64)val);
+ } else {
+ *this = CFX_Decimal((FX_UINT64) - val);
+ SetNegate();
+ }
+}
+CFX_Decimal::CFX_Decimal(FX_FLOAT val, FX_UINT8 scale )
+{
+ FX_FLOAT newval = fabs(val);
+ FX_UINT64 phi, pmid, plo;
+ plo = (FX_UINT64)newval;
+ pmid = (FX_UINT64)(newval / 1e32);
+ phi = (FX_UINT64)(newval / 1e64);
+ newval = FXSYS_fmod(newval, 1.0f);
+ for(FX_UINT8 iter = 0; iter < scale; iter++) {
+ fxmath_decimal_helper_mul10(phi, pmid, plo);
+ newval *= 10;
+ plo += (FX_UINT64)newval;
+ newval = FXSYS_fmod(newval, 1.0f);
+ }
+ plo += FXSYS_round(newval);
+ fxmath_decimal_helper_normalize(phi, pmid, plo);
+ m_uHi = (FX_UINT32)phi;
+ m_uMid = (FX_UINT32)pmid;
+ m_uLo = (FX_UINT32)plo;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(val < 0 && IsNotZero(), scale);
+}
+CFX_Decimal::CFX_Decimal(FX_WSTR strObj)
+{
+ FX_LPCWSTR str = strObj.GetPtr();
+ FX_LPCWSTR strBound = str + strObj.GetLength();
+ FX_BOOL pointmet = 0;
+ FX_BOOL negmet = 0;
+ FX_UINT8 scale = 0;
+ m_uHi = m_uMid = m_uLo = 0;
+ while (str != strBound && *str == ' ') {
+ str++;
+ }
+ if (str != strBound && *str == '-') {
+ negmet = 1;
+ str++;
+ } else if (str != strBound && *str == '+') {
+ str++;
+ }
+ while (str != strBound && ((*str >= '0' && *str <= '9') || *str == '.') && scale < FXMATH_DECIMAL_SCALELIMIT) {
+ if (*str == '.') {
+ if(pointmet) {
+ goto cont;
+ }
+ pointmet = 1;
+ } else {
+ m_uHi = m_uHi * 0xA + FXMATH_DECIMAL_RSHIFT32BIT((FX_UINT64)m_uMid * 0xA);
+ m_uMid = m_uMid * 0xA + FXMATH_DECIMAL_RSHIFT32BIT((FX_UINT64)m_uLo * 0xA);
+ m_uLo = m_uLo * 0xA + (*str - '0');
+ if(pointmet) {
+ scale++;
+ }
+ }
+cont:
+ str++;
+ }
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(negmet && IsNotZero(), scale);
+}
+CFX_Decimal::CFX_Decimal(FX_BSTR strObj)
+{
+ CFX_WideString wstrObj;
+ wstrObj.ConvertFrom(strObj);
+ *this = CFX_Decimal(wstrObj);
+}
+CFX_Decimal::operator CFX_WideString() const
+{
+ CFX_WideString retString;
+ CFX_WideString tmpbuf;
+ FX_UINT64 phi = m_uHi, pmid = m_uMid, plo = m_uLo;
+ while(phi || pmid || plo) {
+ tmpbuf += fxmath_decimal_helper_div10(phi, pmid, plo) + '0';
+ }
+ FX_UINT8 outputlen = (FX_UINT8)tmpbuf.GetLength();
+ FX_UINT8 scale = (FX_UINT8)FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ while (scale >= outputlen) {
+ tmpbuf += '0';
+ outputlen++;
+ }
+ if (FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero()) {
+ retString += '-';
+ }
+ for (FX_UINT8 idx = 0; idx < outputlen; idx++) {
+ if (idx == (outputlen - scale) && scale != 0) {
+ retString += '.';
+ }
+ retString += tmpbuf[outputlen - 1 - idx];
+ }
+ return retString;
+}
+CFX_Decimal::operator double() const
+{
+ double pow = (double)(1 << 16) * (1 << 16);
+ double base = ((double)m_uHi) * pow * pow + ((double)m_uMid) * pow + ((double)m_uLo);
+ FX_INT8 scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ FX_BOOL bNeg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags);
+ return (bNeg ? -1 : 1) * base * ::pow(10.0, -scale);
+}
+void CFX_Decimal::SetScale(FX_UINT8 newscale)
+{
+ FX_UINT8 oldscale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ if (newscale > oldscale) {
+ FX_UINT64 phi = m_uHi, pmid = m_uMid, plo = m_uLo;
+ for (FX_UINT8 iter = 0; iter < newscale - oldscale; iter++) {
+ fxmath_decimal_helper_mul10(phi, pmid, plo);
+ }
+ m_uHi = (FX_UINT32)phi;
+ m_uMid = (FX_UINT32)pmid;
+ m_uLo = (FX_UINT32)plo;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale);
+ } else if (newscale < oldscale) {
+ FX_UINT64 phi, pmid, plo;
+ phi = 0, pmid = 0, plo = 5;
+ {
+ for(FX_UINT8 iter = 0; iter < oldscale - newscale - 1; iter++) {
+ fxmath_decimal_helper_mul10(phi, pmid, plo);
+ }
+ }
+ phi += m_uHi;
+ pmid += m_uMid;
+ plo += m_uLo;
+ fxmath_decimal_helper_normalize(phi, pmid, plo);
+ {
+ for(FX_UINT8 iter = 0; iter < oldscale - newscale; iter++) {
+ fxmath_decimal_helper_div10(phi, pmid, plo);
+ }
+ }
+ m_uHi = (FX_UINT32)phi;
+ m_uMid = (FX_UINT32)pmid;
+ m_uLo = (FX_UINT32)plo;
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), newscale);
+ }
+}
+FX_UINT8 CFX_Decimal::GetScale()
+{
+ FX_UINT8 oldscale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags);
+ return oldscale;
+}
+void CFX_Decimal::SetAbs()
+{
+ m_uFlags &= ~FXMATH_DECIMAL_NEGMASK;
+}
+void CFX_Decimal::SetNegate()
+{
+ if(IsNotZero()) {
+ m_uFlags ^= FXMATH_DECIMAL_NEGMASK;
+ }
+}
+void CFX_Decimal::FloorOrCeil(FX_BOOL bFloor)
+{
+ FX_UINT64 nums[3] = {m_uLo, m_uMid, m_uHi};
+ FX_BOOL bDataLoss = FALSE;
+ for(int i = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags); i > 0; i --) {
+ bDataLoss = fxmath_decimal_helper_div10_any(nums, 3) || bDataLoss;
+ }
+ if(bDataLoss && (bFloor ? FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) : !FXMATH_DECIMAL_FLAGS2NEG(m_uFlags))) {
+ fxmath_decimal_helper_inc_any(nums, 3);
+ }
+ m_uHi = (FX_UINT32)nums[2];
+ m_uMid = (FX_UINT32)nums[1];
+ m_uLo = (FX_UINT32)nums[0];
+ m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) && IsNotZero(), 0);
+}
+void CFX_Decimal::SetFloor()
+{
+ FloorOrCeil(TRUE);
+}
+void CFX_Decimal::SetCeiling()
+{
+ FloorOrCeil(FALSE);
+}
+void CFX_Decimal::SetTruncate()
+{
+ FloorOrCeil(!FXMATH_DECIMAL_FLAGS2NEG(m_uFlags));
+}
+void CFX_Decimal::Swap(CFX_Decimal& val)
+{
+ FX_UINT32 tmp;
+ tmp = m_uHi;
+ m_uHi = val.m_uHi;
+ val.m_uHi = tmp;
+ tmp = m_uMid;
+ m_uMid = val.m_uMid;
+ val.m_uMid = tmp;
+ tmp = m_uLo;
+ m_uLo = val.m_uLo;
+ val.m_uLo = tmp;
+ tmp = m_uFlags;
+ m_uFlags = val.m_uFlags;
+ val.m_uFlags = tmp;
+}
+FX_INT8 CFX_Decimal::Compare (const CFX_Decimal& val) const
+{
+ CFX_Decimal lhs = *this, rhs = val;
+ FX_INT8 retVal = 0;
+ if (FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) != FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags)) {
+ FX_UINT8 scale = FX_MIN(FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags), FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags));
+ lhs.SetScale(scale);
+ rhs.SetScale(scale);
+ }
+ retVal = - (FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) - FXMATH_DECIMAL_FLAGS2NEG(rhs.m_uFlags));
+ if (retVal) {
+ return retVal;
+ }
+ retVal = fxmath_decimal_helper_raw_compare(lhs.m_uHi, lhs.m_uMid, lhs.m_uLo, rhs.m_uHi, rhs.m_uMid, rhs.m_uLo);
+ return (FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) ? - retVal : retVal);
+}
+CFX_Decimal CFX_Decimal::AddOrMinus(const CFX_Decimal& val, FX_BOOL isAdding) const
+{
+ CFX_Decimal lhs = *this, rhs = val;
+ if (FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) != FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags)) {
+ FX_UINT8 scale = FX_MAX(FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags), FXMATH_DECIMAL_FLAGS2SCALE(rhs.m_uFlags));
+ lhs.SetScale(scale);
+ rhs.SetScale(scale);
+ }
+ if(!isAdding) {
+ rhs.SetNegate();
+ }
+ FX_BOOL doRawAdd = (FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags) == FXMATH_DECIMAL_FLAGS2NEG(rhs.m_uFlags));
+ if (doRawAdd) {
+ FX_UINT64 phi = lhs.m_uHi, pmid = lhs.m_uMid, plo = lhs.m_uLo;
+ phi += rhs.m_uHi;
+ pmid += rhs.m_uMid;
+ plo += rhs.m_uLo;
+ fxmath_decimal_helper_normalize(phi, pmid, plo);
+ if(FXMATH_DECIMAL_RSHIFT32BIT(phi) && FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) != 0) {
+ fxmath_decimal_helper_div10(phi, pmid, plo);
+ lhs.m_uFlags = FXMATH_DECIMAL_MAKEFLAGS(FXMATH_DECIMAL_FLAGS2NEG(lhs.m_uFlags), FXMATH_DECIMAL_FLAGS2SCALE(lhs.m_uFlags) - 1);
+ }
+ lhs.m_uHi = (FX_UINT32)phi;
+ lhs.m_uMid = (FX_UINT32)pmid;
+ lhs.m_uLo = (FX_UINT32)plo;
+ return lhs;
+ } else {
+ if(fxmath_decimal_helper_raw_compare(lhs.m_uHi, lhs.m_uMid, lhs.m_uLo, rhs.m_uHi, rhs.m_uMid, rhs.m_uLo) < 0) {
+ lhs.Swap(rhs);
+ }
+ lhs.m_uHi -= rhs.m_uHi;
+ if(lhs.m_uMid < rhs.m_uMid) {
+ lhs.m_uHi--;
+ }
+ lhs.m_uMid -= rhs.m_uMid;
+ if(lhs.m_uLo < rhs.m_uLo) {
+ if(!lhs.m_uMid) {
+ lhs.m_uHi--;
+ }
+ lhs.m_uMid--;
+ }
+ lhs.m_uLo -= rhs.m_uLo;
+ return lhs;
+ }
+}
+CFX_Decimal CFX_Decimal::Multiply(const CFX_Decimal& val) const
+{
+ FX_UINT64 a[3] = {m_uLo, m_uMid, m_uHi}, b[3] = {val.m_uLo, val.m_uMid, val.m_uHi};
+ FX_UINT64 c[6];
+ fxmath_decimal_helper_raw_mul(a, 3, b, 3, c, 6);
+ FX_BOOL neg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) ^ FXMATH_DECIMAL_FLAGS2NEG(val.m_uFlags);
+ FX_UINT8 scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) + FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags);
+ fxmath_decimal_helper_shrinkintorange(c, 6, 3, scale);
+ return CFX_Decimal((FX_UINT32)c[0], (FX_UINT32)c[1], (FX_UINT32)c[2], neg, scale);
+}
+CFX_Decimal CFX_Decimal::Divide(const CFX_Decimal& val) const
+{
+ if(!val.IsNotZero()) {
+ return CFX_Decimal();
+ }
+ FX_BOOL neg = FXMATH_DECIMAL_FLAGS2NEG(m_uFlags) ^ FXMATH_DECIMAL_FLAGS2NEG(val.m_uFlags);
+ FX_UINT64 a[7] = {m_uLo, m_uMid, m_uHi}, b[3] = {val.m_uLo, val.m_uMid, val.m_uHi}, c[7] = {0};
+ FX_UINT8 scale = 0;
+ if(FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) < FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags)) {
+ for(int i = FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags) - FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags); i > 0; i--) {
+ fxmath_decimal_helper_mul10_any(a, 7);
+ }
+ } else {
+ scale = FXMATH_DECIMAL_FLAGS2SCALE(m_uFlags) - FXMATH_DECIMAL_FLAGS2SCALE(val.m_uFlags);
+ }
+ FX_UINT8 minscale = scale;
+ if(!IsNotZero()) {
+ return CFX_Decimal(0, 0, 0, 0, minscale);
+ }
+ while(!a[6]) {
+ fxmath_decimal_helper_mul10_any(a, 7);
+ scale++;
+ }
+ fxmath_decimal_helper_div10_any(a, 7);
+ scale--;
+ fxmath_decimal_helper_raw_div(a, 6, b, 3, c, 7);
+ fxmath_decimal_helper_shrinkintorange(c, 6, 3, scale);
+ fxmath_decimal_helper_truncate(c[2], c[1], c[0], scale, minscale);
+ return CFX_Decimal((FX_UINT32)c[0], (FX_UINT32)c[1], (FX_UINT32)c[2], neg, scale);
+}
+CFX_Decimal CFX_Decimal::Modulus(const CFX_Decimal& val) const
+{
+ CFX_Decimal lhs = *this, rhs_abs = val;
+ rhs_abs.SetAbs();
+ if(!rhs_abs.IsNotZero()) {
+ return *this;
+ }
+ while(TRUE) {
+ CFX_Decimal lhs_abs = lhs;
+ lhs_abs.SetAbs();
+ if(lhs_abs < rhs_abs) {
+ break;
+ }
+ CFX_Decimal quot = lhs / rhs_abs;
+ quot.SetTruncate();
+ lhs = lhs - quot * rhs_abs;
+ }
+ return lhs;
+}
+FX_BOOL CFX_Decimal::operator == (const CFX_Decimal& val) const
+{
+ return Compare(val) == 0;
+}
+FX_BOOL CFX_Decimal::operator <= (const CFX_Decimal& val) const
+{
+ return Compare(val) <= 0;
+}
+FX_BOOL CFX_Decimal::operator >= (const CFX_Decimal& val) const
+{
+ return Compare(val) >= 0;
+}
+FX_BOOL CFX_Decimal::operator != (const CFX_Decimal& val) const
+{
+ return Compare(val) != 0;
+}
+FX_BOOL CFX_Decimal::operator < (const CFX_Decimal& val) const
+{
+ return Compare(val) < 0;
+}
+FX_BOOL CFX_Decimal::operator > (const CFX_Decimal& val) const
+{
+ return Compare(val) > 0;
+}
+CFX_Decimal CFX_Decimal::operator + (const CFX_Decimal& val) const
+{
+ return AddOrMinus(val, TRUE);
+}
+CFX_Decimal CFX_Decimal::operator - (const CFX_Decimal& val) const
+{
+ return AddOrMinus(val, FALSE);
+}
+CFX_Decimal CFX_Decimal::operator * (const CFX_Decimal& val) const
+{
+ return Multiply(val);
+}
+CFX_Decimal CFX_Decimal::operator / (const CFX_Decimal& val) const
+{
+ return Divide(val);
+}
+CFX_Decimal CFX_Decimal::operator % (const CFX_Decimal& val) const
+{
+ return Modulus(val);
+}
diff --git a/xfa/src/fgas/src/localization/fx_localeimp.h b/xfa/src/fgas/src/localization/fx_localeimp.h
new file mode 100644
index 0000000000..7698388020
--- /dev/null
+++ b/xfa/src/fgas/src/localization/fx_localeimp.h
@@ -0,0 +1,74 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_LOCALE_IMP_H_
+#define _FX_LOCALE_IMP_H_
+class CFX_LCNumeric;
+class CFX_Locale : public IFX_Locale, public CFX_Object
+{
+public:
+ CFX_Locale(CXML_Element* pLocaleData);
+ virtual void Release()
+ {
+ delete this;
+ }
+
+ virtual CFX_WideString GetName();
+ virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const;
+
+ virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const;
+ virtual void GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr = TRUE) const;
+ virtual void GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr = TRUE) const;
+ virtual void GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM = TRUE) const;
+ virtual void GetTimeZone(FX_TIMEZONE& tz) const;
+ virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const;
+
+ virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const;
+ virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const;
+ virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const;
+protected:
+ virtual ~CFX_Locale();
+ CXML_Element* m_pElement;
+};
+class CFX_FormatString : public IFX_FormatString, public CFX_Object
+{
+public:
+ CFX_FormatString(IFX_LocaleMgr* pLocaleMgr, FX_BOOL bUseLCID);
+ virtual void Release()
+ {
+ delete this;
+ }
+
+ virtual void SplitFormatString(const CFX_WideString& wsFormatString, CFX_WideStringArray& wsPatterns);
+ virtual FX_LOCALECATEGORY GetCategory(const CFX_WideString& wsPattern);
+ virtual FX_WORD GetLCID(const CFX_WideString& wsPattern);
+ virtual CFX_WideString GetLocaleName(const CFX_WideString& wsPattern);
+ virtual FX_BOOL ParseText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsValue);
+ virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, FX_FLOAT &fValue);
+ virtual FX_BOOL ParseNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString &wsValue);
+ virtual FX_BOOL ParseDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, FX_DATETIMETYPE eDateTimeType, CFX_Unitime& dtValue);
+ virtual FX_BOOL ParseZero(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern);
+ virtual FX_BOOL ParseNull(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern);
+ virtual FX_BOOL FormatText(const CFX_WideString& wsSrcText, const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatNum(const CFX_WideString& wsSrcNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatNum(FX_FLOAT fNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatDateTime(const CFX_WideString& wsSrcDateTime, const CFX_WideString& wsPattern, CFX_WideString& wsOutput, FX_DATETIMETYPE eDateTimeType);
+ virtual FX_BOOL FormatDateTime(const CFX_Unitime& dt, const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatZero(const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ virtual FX_BOOL FormatNull(const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+protected:
+ virtual ~CFX_FormatString();
+ IFX_Locale* GetTextFormat(const CFX_WideString &wsPattern, FX_WSTR wsCategory, CFX_WideString& wsPurgePattern);
+ IFX_Locale* GetNumericFormat(const CFX_WideString& wsPattern, FX_INT32& iDotIndex, FX_DWORD& dwStyle, CFX_WideString& wsPurgePattern);
+ FX_BOOL FormatStrNum(FX_WSTR wsInputNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ FX_BOOL FormatLCNumeric(CFX_LCNumeric& lcNum, const CFX_WideString& wsPattern, CFX_WideString& wsOutput);
+ FX_DATETIMETYPE GetDateTimeFormat(const CFX_WideString& wsPattern, IFX_Locale*& pLocale, CFX_WideString &wsDatePattern, CFX_WideString &wsTimePattern);
+ IFX_Locale* GetPatternLocale(FX_WSTR wsLocale);
+ IFX_LocaleMgr* m_pLocaleMgr;
+ FX_BOOL m_bUseLCID;
+};
+#endif
diff --git a/xfa/src/fgas/src/localization/fx_localemgr.cpp b/xfa/src/fgas/src/localization/fx_localemgr.cpp
new file mode 100644
index 0000000000..3b93f101a3
--- /dev/null
+++ b/xfa/src/fgas/src/localization/fx_localemgr.cpp
@@ -0,0 +1,100 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_localemgr.h"
+IFX_LocaleMgr* FX_LocaleMgr_Create(FX_LPCWSTR pszLocalPath, FX_WORD wDefaultLCID)
+{
+ void* pPathHandle = FX_OpenFolder(pszLocalPath);
+ if (!pPathHandle) {
+ return NULL;
+ }
+ CFX_LocaleMgr* pLocaleMgr = FX_NEW CFX_LocaleMgr(wDefaultLCID);
+ CFX_WideString wsFileName;
+ FX_BOOL bFolder = FALSE;
+ while (FX_GetNextFile(pPathHandle, wsFileName, bFolder)) {
+ if (!bFolder) {
+ if (wsFileName.GetLength() < 4) {
+ continue;
+ }
+ CFX_WideString wsExt = wsFileName.Right(4);
+ wsExt.MakeLower();
+ if (wsExt != L".xml") {
+ continue;
+ }
+ CFX_WideString wsFullPath(pszLocalPath);
+ wsFullPath += L"\\" + wsFileName;
+ IFX_FileRead* pRead = FX_CreateFileRead(wsFullPath);
+ if (!pRead) {
+ continue;
+ }
+ CXML_Element* pXmlLocale = CXML_Element::Parse(pRead);
+ pRead->Release();
+ CFX_ByteString bssp = pXmlLocale->GetNamespace();
+ if (bssp == "http://www.foxitsoftware.com/localization") {
+ CFX_WideString wsLCID = pXmlLocale->GetAttrValue("", "lcid");
+ wchar_t* pEnd = NULL;
+ FX_DWORD dwLCID = wcstol(wsLCID, &pEnd, 16);
+ if (pLocaleMgr->m_lcid2xml.GetValueAt((FX_LPVOID)(FX_UINTPTR)dwLCID)) {
+ delete pXmlLocale;
+ } else {
+ pLocaleMgr->m_lcid2xml.SetAt((FX_LPVOID)(FX_UINTPTR)dwLCID, pXmlLocale);
+ }
+ } else {
+ delete pXmlLocale;
+ }
+ }
+ }
+ FX_CloseFolder(pPathHandle);
+ return pLocaleMgr;
+}
+CFX_LocaleMgr::CFX_LocaleMgr(FX_WORD wDefLCID)
+ : m_wDefLCID(wDefLCID)
+{
+}
+CFX_LocaleMgr::~CFX_LocaleMgr()
+{
+ FX_POSITION ps = m_lcid2locale.GetStartPosition();
+ while (ps) {
+ FX_LPVOID plcid;
+ IFX_Locale* pLocale = NULL;
+ m_lcid2locale.GetNextAssoc(ps, plcid, (void*&)pLocale);
+ pLocale->Release();
+ }
+ m_lcid2locale.RemoveAll();
+ ps = m_lcid2xml.GetStartPosition();
+ while (ps) {
+ FX_LPVOID plcid;
+ CXML_Element* pxml = NULL;
+ m_lcid2xml.GetNextAssoc(ps, plcid, (void*&)pxml);
+ delete pxml;
+ }
+ m_lcid2xml.RemoveAll();
+}
+FX_WORD CFX_LocaleMgr::GetDefLocaleID()
+{
+ return m_wDefLCID;
+}
+IFX_Locale* CFX_LocaleMgr::GetDefLocale()
+{
+ return GetLocale(m_wDefLCID);
+}
+IFX_Locale* CFX_LocaleMgr::GetLocale(FX_WORD lcid)
+{
+ IFX_Locale* pLocale = (IFX_Locale*)m_lcid2locale.GetValueAt((FX_LPVOID)(FX_UINTPTR)lcid);
+ if (!pLocale) {
+ CXML_Element* pxml = (CXML_Element*)m_lcid2xml.GetValueAt((FX_LPVOID)(FX_UINTPTR)lcid);
+ if (pxml) {
+ pLocale = IFX_Locale::Create(pxml);
+ m_lcid2locale.SetAt((FX_LPVOID)(FX_UINTPTR)lcid, pLocale);
+ }
+ }
+ return pLocale;
+}
+IFX_Locale* CFX_LocaleMgr::GetLocaleByName(FX_WSTR wsLocaleName)
+{
+ return NULL;
+}
diff --git a/xfa/src/fgas/src/localization/fx_localemgr.h b/xfa/src/fgas/src/localization/fx_localemgr.h
new file mode 100644
index 0000000000..b23940e8d5
--- /dev/null
+++ b/xfa/src/fgas/src/localization/fx_localemgr.h
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_LOCALEMGR_IMP_H_
+#define _FX_LOCALEMGR_IMP_H_
+class CFX_LocaleMgr : public IFX_LocaleMgr, public CFX_Object
+{
+public:
+ CFX_LocaleMgr(FX_WORD wDefLCID);
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_WORD GetDefLocaleID();
+ virtual IFX_Locale* GetDefLocale();
+ virtual IFX_Locale* GetLocale(FX_WORD lcid);
+ virtual IFX_Locale* GetLocaleByName(FX_WSTR wsLocaleName);
+ CFX_MapPtrToPtr m_lcid2xml;
+protected:
+ ~CFX_LocaleMgr();
+ CFX_MapPtrToPtr m_lcid2locale;
+ FX_WORD m_wDefLCID;
+};
+#endif
diff --git a/xfa/src/fgas/src/xml/fx_sax_imp.cpp b/xfa/src/fgas/src/xml/fx_sax_imp.cpp
new file mode 100644
index 0000000000..b41ee3fef4
--- /dev/null
+++ b/xfa/src/fgas/src/xml/fx_sax_imp.cpp
@@ -0,0 +1,720 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../fgas_base.h"
+#include "fx_sax_imp.h"
+IFX_SAXReader* FX_SAXReader_Create()
+{
+ return FX_NEW CFX_SAXReader;
+}
+CFX_SAXFile::CFX_SAXFile()
+ : m_pFile(NULL)
+ , m_dwStart(0)
+ , m_dwEnd(0)
+ , m_dwCur(0)
+ , m_pBuf(NULL)
+ , m_dwBufSize(0)
+ , m_dwBufIndex(0)
+{
+}
+FX_BOOL CFX_SAXFile::StartFile(IFX_FileRead *pFile, FX_DWORD dwStart, FX_DWORD dwLen)
+{
+ FXSYS_assert(m_pFile == NULL && pFile != NULL);
+ FX_DWORD dwSize = pFile->GetSize();
+ if (dwStart >= dwSize) {
+ return FALSE;
+ }
+ if (dwLen == -1 || dwStart + dwLen > dwSize) {
+ dwLen = dwSize - dwStart;
+ }
+ if (dwLen == 0) {
+ return FALSE;
+ }
+ m_dwBufSize = FX_MIN(dwLen, FX_SAXFILE_BUFSIZE);
+ m_pBuf = FX_Alloc(FX_BYTE, m_dwBufSize);
+ if (!m_pBuf) {
+ return FALSE;
+ }
+ if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize)) {
+ return FALSE;
+ }
+ m_dwStart = dwStart;
+ m_dwEnd = dwStart + dwLen;
+ m_dwCur = dwStart;
+ m_pFile = pFile;
+ m_dwBufIndex = 0;
+ return TRUE;
+}
+FX_BOOL CFX_SAXFile::ReadNextBlock()
+{
+ FXSYS_assert(m_pFile != NULL);
+ FX_DWORD dwSize = m_dwEnd - m_dwCur;
+ if (dwSize == 0) {
+ return FALSE;
+ }
+ m_dwBufSize = FX_MIN(dwSize, FX_SAXFILE_BUFSIZE);
+ if (!m_pFile->ReadBlock(m_pBuf, m_dwCur, m_dwBufSize)) {
+ return FALSE;
+ }
+ m_dwBufIndex = 0;
+ return TRUE;
+}
+void CFX_SAXFile::Reset()
+{
+ if (m_pBuf) {
+ FX_Free(m_pBuf);
+ m_pBuf = NULL;
+ }
+ m_pFile = NULL;
+}
+#define FX_SAXCHARTYPE_Normal 0
+#define FX_SAXCHARTYPE_Space 1
+static FX_BYTE g_SAX_CharType[256] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+CFX_SAXReader::CFX_SAXReader()
+ : m_File()
+ , m_pHandler(NULL)
+ , m_iState(-1)
+ , m_pRoot(NULL)
+ , m_pCurItem(NULL)
+ , m_dwItemID(0)
+ , m_iDataSize(256)
+ , m_iNameSize(256)
+ , m_pCommentContext(NULL)
+ , m_dwParseMode(0)
+{
+ m_pszData = (FX_LPBYTE)FX_Alloc(FX_BYTE, m_iDataSize);
+ m_pszName = (FX_LPBYTE)FX_Alloc(FX_BYTE, m_iNameSize);
+}
+CFX_SAXReader::~CFX_SAXReader()
+{
+ Reset();
+ if (m_pszData) {
+ FX_Free(m_pszData);
+ m_pszData = NULL;
+ }
+ if (m_pszName) {
+ FX_Free(m_pszName);
+ m_pszName = NULL;
+ }
+}
+void CFX_SAXReader::Reset()
+{
+ m_File.Reset();
+ CFX_SAXItem *pItem = m_pRoot;
+ while (pItem) {
+ CFX_SAXItem *pNext = pItem->m_pNext;
+ delete pItem;
+ pItem = pNext;
+ }
+ m_pRoot = NULL;
+ m_pCurItem = NULL;
+ m_dwItemID = 0;
+ m_SkipStack.RemoveAll();
+ m_SkipChar = 0;
+ m_iDataLength = 0;
+ m_iEntityStart = -1;
+ m_iNameLength = 0;
+ m_iDataPos = 0;
+ if (m_pCommentContext) {
+ delete m_pCommentContext;
+ m_pCommentContext = NULL;
+ }
+}
+inline void CFX_SAXReader::Push()
+{
+ CFX_SAXItem *pNew = FX_NEW CFX_SAXItem;
+ pNew->m_dwID = ++m_dwItemID;
+ pNew->m_bSkip = m_pCurItem->m_bSkip;
+ pNew->m_pPrev = m_pCurItem;
+ m_pCurItem->m_pNext = pNew;
+ m_pCurItem = pNew;
+}
+inline void CFX_SAXReader::Pop()
+{
+ if (!m_pCurItem) {
+ return;
+ }
+ CFX_SAXItem *pPrev = m_pCurItem->m_pPrev;
+ pPrev->m_pNext = NULL;
+ delete m_pCurItem;
+ m_pCurItem = pPrev;
+}
+inline void CFX_SAXReader::AppendData(FX_BYTE ch)
+{
+ ReallocDataBuffer();
+ m_pszData[m_iDataPos++] = ch;
+}
+inline void CFX_SAXReader::AppendName(FX_BYTE ch)
+{
+ ReallocNameBuffer();
+ m_pszName[m_iDataPos++] = ch;
+}
+void CFX_SAXReader::ReallocDataBuffer()
+{
+ if (m_iDataPos < m_iDataSize) {
+ return;
+ }
+ if (m_iDataSize <= 1024 * 1024) {
+ m_iDataSize *= 2;
+ } else {
+ m_iDataSize += 1024 * 1024;
+ }
+ m_pszData = (FX_LPBYTE)FX_Realloc(FX_BYTE, m_pszData, m_iDataSize);
+}
+void CFX_SAXReader::ReallocNameBuffer()
+{
+ if (m_iDataPos < m_iNameSize) {
+ return;
+ }
+ if (m_iNameSize <= 1024 * 1024) {
+ m_iNameSize *= 2;
+ } else {
+ m_iNameSize += 1024 * 1024;
+ }
+ m_pszName = (FX_LPBYTE)FX_Realloc(FX_BYTE, m_pszName, m_iNameSize);
+}
+inline FX_BOOL CFX_SAXReader::SkipSpace(FX_BYTE ch)
+{
+ return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21;
+}
+FX_INT32 CFX_SAXReader::StartParse(IFX_FileRead *pFile, FX_DWORD dwStart , FX_DWORD dwLen , FX_DWORD dwParseMode )
+{
+ m_iState = -1;
+ Reset();
+ if (!m_File.StartFile(pFile, dwStart, dwLen)) {
+ return -1;
+ }
+ m_iState = 0;
+ m_eMode = FX_SAXMODE_Text;
+ m_ePrevMode = FX_SAXMODE_Text;
+ m_bCharData = FALSE;
+ m_dwDataOffset = 0;
+ m_pRoot = m_pCurItem = FX_NEW CFX_SAXItem;
+ m_pCurItem->m_dwID = ++m_dwItemID;
+ m_dwParseMode = dwParseMode;
+ return 0;
+}
+typedef void (CFX_SAXReader::*FX_SAXReader_LPFParse)();
+static const FX_SAXReader_LPFParse g_FX_SAXReader_LPFParse[FX_SAXMODE_MAX] = {
+ &CFX_SAXReader::ParseText,
+ &CFX_SAXReader::ParseNodeStart,
+ &CFX_SAXReader::ParseDeclOrComment,
+ &CFX_SAXReader::ParseDeclNode,
+ &CFX_SAXReader::ParseComment,
+ &CFX_SAXReader::ParseCommentContent,
+ &CFX_SAXReader::ParseTagName,
+ &CFX_SAXReader::ParseTagAttributeName,
+ &CFX_SAXReader::ParseTagAttributeEqual,
+ &CFX_SAXReader::ParseTagAttributeValue,
+ &CFX_SAXReader::ParseMaybeClose,
+ &CFX_SAXReader::ParseTagClose,
+ &CFX_SAXReader::ParseTagEnd,
+ &CFX_SAXReader::ParseTargetData,
+};
+FX_INT32 CFX_SAXReader::ContinueParse(IFX_Pause *pPause )
+{
+ if (m_iState < 0 || m_iState > 99) {
+ return m_iState;
+ }
+ while(m_File.m_dwCur < m_File.m_dwEnd) {
+ FX_DWORD &index = m_File.m_dwBufIndex;
+ FX_DWORD size = m_File.m_dwBufSize;
+ FX_LPCBYTE pBuf = m_File.m_pBuf;
+ while (index < size) {
+ m_CurByte = pBuf[index];
+ (this->*g_FX_SAXReader_LPFParse[m_eMode])();
+ index ++;
+ }
+ m_File.m_dwCur += index;
+ m_iState = (m_File.m_dwCur - m_File.m_dwStart) * 100 / (m_File.m_dwEnd - m_File.m_dwStart);
+ if (m_File.m_dwCur >= m_File.m_dwEnd) {
+ break;
+ }
+ if (!m_File.ReadNextBlock()) {
+ m_iState = -2;
+ break;
+ }
+ m_dwDataOffset = 0;
+ if (pPause && pPause->NeedToPauseNow()) {
+ break;
+ }
+ }
+ return m_iState;
+}
+void CFX_SAXReader::ParseChar(FX_BYTE ch)
+{
+ ReallocDataBuffer();
+ m_pszData[m_iDataPos] = ch;
+ if (m_iEntityStart > -1 && ch == ';') {
+ FX_INT32 iSaveEntityStart = m_iEntityStart;
+ CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1, m_iDataPos - m_iEntityStart - 1);
+ FX_INT32 iLen = csEntity.GetLength();
+ if (iLen > 0) {
+ if (csEntity[0] == '#') {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_sharp) == 0) {
+ ch = 0;
+ FX_BYTE w;
+ if (iLen > 1 && csEntity[1] == 'x') {
+ for (FX_INT32 i = 2; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w >= '0' && w <= '9') {
+ ch = (ch << 4) + w - '0';
+ } else if (w >= 'A' && w <= 'F') {
+ ch = (ch << 4) + w - 55;
+ } else if (w >= 'a' && w <= 'f') {
+ ch = (ch << 4) + w - 87;
+ } else {
+ break;
+ }
+ }
+ } else {
+ for (FX_INT32 i = 1; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w < '0' || w > '9') {
+ break;
+ }
+ ch = ch * 10 + w - '0';
+ }
+ }
+ if (ch != 0) {
+ m_pszData[m_iEntityStart ++] = ch;
+ }
+ }
+ } else {
+ if (csEntity.Compare("amp") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_amp) == 0) {
+ m_pszData[m_iEntityStart ++] = '&';
+ }
+ } else if (csEntity.Compare("lt") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_lt) == 0) {
+ m_pszData[m_iEntityStart ++] = '<';
+ }
+ } else if (csEntity.Compare("gt") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_gt) == 0) {
+ m_pszData[m_iEntityStart ++] = '>';
+ }
+ } else if (csEntity.Compare("apos") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_apos) == 0) {
+ m_pszData[m_iEntityStart ++] = '\'';
+ }
+ } else if (csEntity.Compare("quot") == 0) {
+ if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_quot) == 0) {
+ m_pszData[m_iEntityStart ++] = '\"';
+ }
+ }
+ }
+ }
+ if (iSaveEntityStart != m_iEntityStart) {
+ m_iDataPos = m_iEntityStart;
+ m_iEntityStart = -1;
+ } else {
+ m_iDataPos ++;
+ m_iEntityStart = -1;
+ }
+ } else {
+ if (m_iEntityStart < 0 && ch == '&') {
+ m_iEntityStart = m_iDataPos;
+ }
+ m_iDataPos ++;
+ }
+}
+void CFX_SAXReader::ParseText()
+{
+ if (m_CurByte == '<') {
+ if (m_iDataPos > 0) {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyData();
+ }
+ }
+ Push();
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ m_eMode = FX_SAXMODE_NodeStart;
+ return;
+ }
+ if (m_iDataPos < 1 && SkipSpace(m_CurByte)) {
+ return;
+ }
+ ParseChar(m_CurByte);
+}
+void CFX_SAXReader::ParseNodeStart()
+{
+ if (m_CurByte == '?') {
+ m_pCurItem->m_eNode = FX_SAXNODE_Instruction;
+ m_eMode = FX_SAXMODE_TagName;
+ return;
+ }
+ if (m_CurByte == '!') {
+ m_eMode = FX_SAXMODE_DeclOrComment;
+ return;
+ }
+ if (m_CurByte == '/') {
+ m_eMode = FX_SAXMODE_TagEnd;
+ return;
+ }
+ if (m_CurByte == '>') {
+ Pop();
+ m_eMode = FX_SAXMODE_Text;
+ return;
+ }
+ if (m_CurByte > 0x20) {
+ m_dwDataOffset = m_File.m_dwBufIndex;
+ m_pCurItem->m_eNode = FX_SAXNODE_Tag;
+ m_eMode = FX_SAXMODE_TagName;
+ AppendData(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseDeclOrComment()
+{
+ if (m_CurByte == '-') {
+ m_eMode = FX_SAXMODE_Comment;
+ m_pCurItem->m_eNode = FX_SAXNODE_Comment;
+ if (m_pCommentContext == NULL) {
+ m_pCommentContext = FX_NEW CFX_SAXCommentContext;
+ }
+ m_pCommentContext->m_iHeaderCount = 1;
+ m_pCommentContext->m_iTailCount = 0;
+ } else {
+ m_eMode = FX_SAXMODE_DeclNode;
+ m_dwDataOffset = m_File.m_dwBufIndex;
+ m_SkipChar = '>';
+ m_SkipStack.Add('>');
+ SkipNode();
+ }
+}
+void CFX_SAXReader::ParseComment()
+{
+ m_pCommentContext->m_iHeaderCount = 2;
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ m_eMode = FX_SAXMODE_CommentContent;
+}
+void CFX_SAXReader::ParseCommentContent()
+{
+ if (m_CurByte == '-') {
+ m_pCommentContext->m_iTailCount++;
+ } else if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyTargetData();
+ }
+ Pop();
+ m_eMode = FX_SAXMODE_Text;
+ } else {
+ while (m_pCommentContext->m_iTailCount > 0) {
+ AppendData('-');
+ m_pCommentContext->m_iTailCount--;
+ }
+ AppendData(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseDeclNode()
+{
+ SkipNode();
+}
+void CFX_SAXReader::ParseTagName()
+{
+ if (m_CurByte < 0x21 || m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyEnter();
+ }
+ if (m_CurByte < 0x21) {
+ m_eMode = FX_SAXMODE_TagAttributeName;
+ } else if (m_CurByte == '/' || m_CurByte == '?') {
+ m_ePrevMode = m_eMode;
+ m_eMode = FX_SAXMODE_TagMaybeClose;
+ } else {
+ if (m_pHandler) {
+ NotifyBreak();
+ }
+ m_eMode = FX_SAXMODE_Text;
+ }
+ } else {
+ AppendData(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseTagAttributeName()
+{
+ if (m_CurByte < 0x21 || m_CurByte == '=') {
+ if (m_iDataPos < 1 && m_CurByte < 0x21) {
+ return;
+ }
+ m_iNameLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_SkipChar = 0;
+ m_eMode = m_CurByte == '=' ? FX_SAXMODE_TagAttributeValue : FX_SAXMODE_TagAttributeEqual;
+ return;
+ }
+ if (m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') {
+ if (m_CurByte == '/' || m_CurByte == '?') {
+ m_ePrevMode = m_eMode;
+ m_eMode = FX_SAXMODE_TagMaybeClose;
+ } else {
+ if (m_pHandler) {
+ NotifyBreak();
+ }
+ m_eMode = FX_SAXMODE_Text;
+ }
+ return;
+ }
+ if (m_iDataPos < 1) {
+ m_dwDataOffset = m_File.m_dwBufIndex;
+ }
+ AppendName(m_CurByte);
+}
+void CFX_SAXReader::ParseTagAttributeEqual()
+{
+ if (m_CurByte == '=') {
+ m_SkipChar = 0;
+ m_eMode = FX_SAXMODE_TagAttributeValue;
+ return;
+ } else if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_iDataPos = m_iNameLength;
+ AppendName(0x20);
+ m_eMode = FX_SAXMODE_TargetData;
+ ParseTargetData();
+ }
+}
+void CFX_SAXReader::ParseTagAttributeValue()
+{
+ if (m_SkipChar) {
+ if (m_SkipChar == m_CurByte) {
+ {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyAttribute();
+ }
+ }
+ m_SkipChar = 0;
+ m_eMode = FX_SAXMODE_TagAttributeName;
+ return;
+ }
+ ParseChar(m_CurByte);
+ return;
+ }
+ if (m_CurByte < 0x21) {
+ return;
+ }
+ if (m_iDataPos < 1) {
+ if (m_CurByte == '\'' || m_CurByte == '\"') {
+ m_SkipChar = m_CurByte;
+ }
+ }
+}
+void CFX_SAXReader::ParseMaybeClose()
+{
+ if (m_CurByte == '>') {
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_iNameLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyTargetData();
+ }
+ }
+ ParseTagClose();
+ m_eMode = FX_SAXMODE_Text;
+ } else if (m_ePrevMode == FX_SAXMODE_TagName) {
+ AppendData('/');
+ m_eMode = FX_SAXMODE_TagName;
+ m_ePrevMode = FX_SAXMODE_Text;
+ ParseTagName();
+ } else if (m_ePrevMode == FX_SAXMODE_TagAttributeName) {
+ AppendName('/');
+ m_eMode = FX_SAXMODE_TagAttributeName;
+ m_ePrevMode = FX_SAXMODE_Text;
+ ParseTagAttributeName();
+ } else if (m_ePrevMode == FX_SAXMODE_TargetData) {
+ AppendName('?');
+ m_eMode = FX_SAXMODE_TargetData;
+ m_ePrevMode = FX_SAXMODE_Text;
+ ParseTargetData();
+ }
+}
+void CFX_SAXReader::ParseTagClose()
+{
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ if (m_pHandler) {
+ NotifyClose();
+ }
+ Pop();
+}
+void CFX_SAXReader::ParseTagEnd()
+{
+ if (m_CurByte < 0x21) {
+ return;
+ }
+ if (m_CurByte == '>') {
+ Pop();
+ m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_pHandler) {
+ NotifyEnd();
+ }
+ Pop();
+ m_eMode = FX_SAXMODE_Text;
+ } else {
+ ParseChar(m_CurByte);
+ }
+}
+void CFX_SAXReader::ParseTargetData()
+{
+ if (m_CurByte == '?') {
+ m_ePrevMode = m_eMode;
+ m_eMode = FX_SAXMODE_TagMaybeClose;
+ } else {
+ AppendName(m_CurByte);
+ }
+}
+void CFX_SAXReader::SkipNode()
+{
+ FX_INT32 iLen = m_SkipStack.GetSize();
+ if (m_SkipChar == '\'' || m_SkipChar == '\"') {
+ if (m_CurByte != m_SkipChar) {
+ return;
+ }
+ iLen --;
+ FXSYS_assert(iLen > -1);
+ m_SkipStack.RemoveAt(iLen, 1);
+ m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
+ return;
+ }
+ switch (m_CurByte) {
+ case '<':
+ m_SkipChar = '>';
+ m_SkipStack.Add('>');
+ break;
+ case '[':
+ m_SkipChar = ']';
+ m_SkipStack.Add(']');
+ break;
+ case '(':
+ m_SkipChar = ')';
+ m_SkipStack.Add(')');
+ break;
+ case '\'':
+ m_SkipChar = '\'';
+ m_SkipStack.Add('\'');
+ break;
+ case '\"':
+ m_SkipChar = '\"';
+ m_SkipStack.Add('\"');
+ break;
+ default:
+ if (m_CurByte == m_SkipChar) {
+ iLen --;
+ m_SkipStack.RemoveAt(iLen, 1);
+ m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
+ if (iLen == 0 && m_CurByte == '>') {
+ m_iDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_iDataLength >= 9
+ && FXSYS_memcmp(m_pszData, "[CDATA[", 7 * sizeof(FX_BYTE)) == 0
+ && FXSYS_memcmp(m_pszData + m_iDataLength - 2, "]]", 2 * sizeof(FX_BYTE)) == 0) {
+ Pop();
+ m_iDataLength -= 9;
+ m_dwDataOffset += 7;
+ FXSYS_memmove(m_pszData , m_pszData + 7, m_iDataLength * sizeof(FX_BYTE));
+ m_bCharData = TRUE;
+ if (m_pHandler) {
+ NotifyData();
+ }
+ m_bCharData = FALSE;
+ } else {
+ Pop();
+ }
+ m_eMode = FX_SAXMODE_Text;
+ }
+ }
+ break;
+ }
+ if (iLen > 0) {
+ ParseChar(m_CurByte);
+ }
+}
+void CFX_SAXReader::NotifyData()
+{
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag)
+ m_pHandler->OnTagData(m_pCurItem->m_pNode, m_bCharData ? FX_SAXNODE_CharData : FX_SAXNODE_Text,
+ CFX_ByteStringC(m_pszData, m_iDataLength), m_File.m_dwCur + m_dwDataOffset);
+}
+void CFX_SAXReader::NotifyEnter()
+{
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag || m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pCurItem->m_pNode = m_pHandler->OnTagEnter(CFX_ByteStringC(m_pszData, m_iDataLength), m_pCurItem->m_eNode, m_dwNodePos);
+ }
+}
+void CFX_SAXReader::NotifyAttribute()
+{
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag || m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pHandler->OnTagAttribute(m_pCurItem->m_pNode, CFX_ByteStringC(m_pszName, m_iNameLength), CFX_ByteStringC(m_pszData, m_iDataLength));
+ }
+}
+void CFX_SAXReader::NotifyBreak()
+{
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
+ m_pHandler->OnTagBreak(m_pCurItem->m_pNode);
+ }
+}
+void CFX_SAXReader::NotifyClose()
+{
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag || m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pHandler->OnTagClose(m_pCurItem->m_pNode, m_dwNodePos);
+ }
+}
+void CFX_SAXReader::NotifyEnd()
+{
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
+ m_pHandler->OnTagEnd(m_pCurItem->m_pNode, CFX_ByteStringC(m_pszData, m_iDataLength), m_dwNodePos);
+ }
+}
+void CFX_SAXReader::NotifyTargetData()
+{
+ FXSYS_assert(m_pHandler != NULL);
+ if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
+ m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode, CFX_ByteStringC(m_pszName, m_iNameLength), m_dwNodePos);
+ } else if (m_pCurItem->m_eNode == FX_SAXNODE_Comment) {
+ m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode, CFX_ByteStringC(m_pszData, m_iDataLength), m_dwNodePos);
+ }
+}
+void CFX_SAXReader::SkipCurrentNode()
+{
+ if (!m_pCurItem) {
+ return;
+ }
+ m_pCurItem->m_bSkip = TRUE;
+}
+void CFX_SAXReader::SetHandler(IFX_SAXReaderHandler *pHandler)
+{
+ m_pHandler = pHandler;
+}
diff --git a/xfa/src/fgas/src/xml/fx_sax_imp.h b/xfa/src/fgas/src/xml/fx_sax_imp.h
new file mode 100644
index 0000000000..f18173183f
--- /dev/null
+++ b/xfa/src/fgas/src/xml/fx_sax_imp.h
@@ -0,0 +1,140 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_SAX_IMP_
+#define _FX_SAX_IMP_
+#define FX_SAXFILE_BUFSIZE 32768
+class CFX_SAXFile : public CFX_Object
+{
+public:
+ CFX_SAXFile();
+ FX_BOOL StartFile(IFX_FileRead *pFile, FX_DWORD dwStart, FX_DWORD dwLen);
+ FX_BOOL ReadNextBlock();
+ void Reset();
+ IFX_FileRead* m_pFile;
+ FX_DWORD m_dwStart;
+ FX_DWORD m_dwEnd;
+ FX_DWORD m_dwCur;
+ FX_LPBYTE m_pBuf;
+ FX_DWORD m_dwBufSize;
+ FX_DWORD m_dwBufIndex;
+};
+enum FX_SAXMODE {
+ FX_SAXMODE_Text = 0,
+ FX_SAXMODE_NodeStart,
+ FX_SAXMODE_DeclOrComment,
+ FX_SAXMODE_DeclNode,
+ FX_SAXMODE_Comment,
+ FX_SAXMODE_CommentContent,
+ FX_SAXMODE_TagName,
+ FX_SAXMODE_TagAttributeName,
+ FX_SAXMODE_TagAttributeEqual,
+ FX_SAXMODE_TagAttributeValue,
+ FX_SAXMODE_TagMaybeClose,
+ FX_SAXMODE_TagClose,
+ FX_SAXMODE_TagEnd,
+ FX_SAXMODE_TargetData,
+ FX_SAXMODE_MAX,
+};
+class CFX_SAXItem : public CFX_Object
+{
+public:
+ CFX_SAXItem() : m_pNode(NULL)
+ , m_eNode(FX_SAXNODE_Unknown)
+ , m_dwID(0)
+ , m_bSkip(FALSE)
+ , m_pPrev(NULL)
+ , m_pNext(NULL)
+ {}
+ FX_LPVOID m_pNode;
+ FX_SAXNODE m_eNode;
+ FX_DWORD m_dwID;
+ FX_BOOL m_bSkip;
+ CFX_SAXItem* m_pPrev;
+ CFX_SAXItem* m_pNext;
+};
+class CFX_SAXCommentContext : public CFX_Object
+{
+public:
+ CFX_SAXCommentContext() : m_iHeaderCount(0)
+ , m_iTailCount(0)
+ {
+ }
+ FX_INT32 m_iHeaderCount;
+ FX_INT32 m_iTailCount;
+};
+class CFX_SAXReader : public IFX_SAXReader, public CFX_Object
+{
+public:
+ CFX_SAXReader();
+ ~CFX_SAXReader();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_INT32 StartParse(IFX_FileRead *pFile, FX_DWORD dwStart = 0, FX_DWORD dwLen = -1, FX_DWORD dwParseMode = 0);
+ virtual FX_INT32 ContinueParse(IFX_Pause *pPause = NULL);
+ virtual void SkipCurrentNode();
+ virtual void SetHandler(IFX_SAXReaderHandler *pHandler);
+ void AppendData(FX_BYTE ch);
+ void AppendName(FX_BYTE ch);
+ void ParseText();
+ void ParseNodeStart();
+ void ParseInstruction();
+ void ParseDeclOrComment();
+ void ParseDeclNode();
+ void ParseComment();
+ void ParseCommentContent();
+ void ParseTagName();
+ void ParseTagAttributeName();
+ void ParseTagAttributeEqual();
+ void ParseTagAttributeValue();
+ void ParseMaybeClose();
+ void ParseTagClose();
+ void ParseTagEnd();
+ void ParseTargetData();
+protected:
+ CFX_SAXFile m_File;
+ IFX_SAXReaderHandler* m_pHandler;
+ FX_INT32 m_iState;
+ CFX_SAXItem* m_pRoot;
+ CFX_SAXItem* m_pCurItem;
+ FX_DWORD m_dwItemID;
+ FX_SAXMODE m_eMode;
+ FX_SAXMODE m_ePrevMode;
+ FX_BOOL m_bCharData;
+ FX_BYTE m_CurByte;
+ FX_DWORD m_dwDataOffset;
+ CFX_ByteArray m_SkipStack;
+ FX_BYTE m_SkipChar;
+ FX_DWORD m_dwNodePos;
+ FX_LPBYTE m_pszData;
+ FX_INT32 m_iDataSize;
+ FX_INT32 m_iDataLength;
+ FX_INT32 m_iEntityStart;
+ FX_INT32 m_iDataPos;
+ FX_LPBYTE m_pszName;
+ FX_INT32 m_iNameSize;
+ FX_INT32 m_iNameLength;
+ FX_DWORD m_dwParseMode;
+ CFX_SAXCommentContext *m_pCommentContext;
+ void Reset();
+ void Push();
+ void Pop();
+ FX_BOOL SkipSpace(FX_BYTE ch);
+ void SkipNode();
+ void NotifyData();
+ void NotifyEnter();
+ void NotifyAttribute();
+ void NotifyBreak();
+ void NotifyClose();
+ void NotifyEnd();
+ void NotifyTargetData();
+ void ReallocDataBuffer();
+ void ReallocNameBuffer();
+ void ParseChar(FX_BYTE ch);
+};
+#endif
diff --git a/xfa/src/foxitlib.h b/xfa/src/foxitlib.h
new file mode 100644
index 0000000000..f70c0770aa
--- /dev/null
+++ b/xfa/src/foxitlib.h
@@ -0,0 +1,15 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FOXIT_LIB_H_
+#define _FOXIT_LIB_H_
+#include "../include/foxitxfa.h"
+#include "./fgas/include/fgas.h"
+#include "./fdp/include/fde.h"
+#include "./fee/include/ifde_txtedtengine.h"
+#include "./fee/include/ifde_txtedtpage.h"
+#include "./fee/include/fx_wordbreak.h"
+#endif
diff --git a/xfa/src/fwl/src/basewidget/fwl_barcodeimp.cpp b/xfa/src/fwl/src/basewidget/fwl_barcodeimp.cpp
new file mode 100644
index 0000000000..8ac141a686
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_barcodeimp.cpp
@@ -0,0 +1,247 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_editimp.h"
+#include "include/fwl_barcodeimp.h"
+IFWL_Barcode* IFWL_Barcode::Create()
+{
+ return new IFWL_Barcode;
+}
+IFWL_Barcode::IFWL_Barcode()
+{
+ m_pData = NULL;
+}
+IFWL_Barcode::~IFWL_Barcode()
+{
+ if (m_pData) {
+ delete (CFWL_BarcodeImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_Barcode::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_BarcodeImp(pOuter);
+ ((CFWL_BarcodeImp*)m_pData)->SetInterface(this);
+ return ((CFWL_BarcodeImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Barcode::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_BarcodeImp(properties, pOuter);
+ ((CFWL_BarcodeImp*)m_pData)->SetInterface(this);
+ return ((CFWL_BarcodeImp*)m_pData)->Initialize();
+}
+void IFWL_Barcode::SetType(BC_TYPE type)
+{
+ ((CFWL_BarcodeImp*)m_pData)->SetType(type);
+}
+FX_BOOL IFWL_Barcode::IsProtectedType()
+{
+ return ((CFWL_BarcodeImp*)m_pData)->IsProtectedType();
+}
+CFWL_BarcodeImp::CFWL_BarcodeImp(IFWL_Widget *pOuter )
+ : CFWL_EditImp(pOuter)
+ , m_pBarcodeEngine(NULL)
+ , m_dwStatus(0)
+ , m_type(BC_UNKNOWN)
+{
+}
+CFWL_BarcodeImp::CFWL_BarcodeImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_EditImp(properties, pOuter)
+ , m_pBarcodeEngine(NULL)
+ , m_dwStatus(0)
+ , m_type(BC_UNKNOWN)
+{
+}
+CFWL_BarcodeImp::~CFWL_BarcodeImp()
+{
+ ReleaseBarcodeEngine();
+}
+FWL_ERR CFWL_BarcodeImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_Barcode;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_BarcodeImp::GetClassID() const
+{
+ return FWL_CLASSHASH_Barcode;
+}
+FWL_ERR CFWL_BarcodeImp::Initialize()
+{
+ if (!m_pDelegate) {
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_BarcodeImpDelegate(this);
+ }
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_EditImp::Initialize(), FWL_ERR_Indefinite);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_BarcodeImp::Finalize()
+{
+ if (m_pDelegate) {
+ delete (CFWL_BarcodeImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ ReleaseBarcodeEngine();
+ return CFWL_EditImp::Finalize();
+}
+FWL_ERR CFWL_BarcodeImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ FWL_ERR ret = CFWL_EditImp::Update();
+ GenerateBarcodeImageCache();
+ return ret;
+}
+FWL_ERR CFWL_BarcodeImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ GenerateBarcodeImageCache();
+ if (!m_pBarcodeEngine || (m_dwStatus & XFA_BCS_EncodeSuccess) == 0) {
+ return FWL_ERR_Succeeded;
+ }
+ CFX_Matrix mt;
+ mt.e = m_rtClient.left;
+ mt.f = m_rtClient.top;
+ if (pMatrix) {
+ mt.Concat(*pMatrix);
+ }
+ FX_INT32 errorCode = 0;
+ _FWL_RETURN_VALUE_IF_FAIL(m_pBarcodeEngine->RenderDevice(pGraphics->GetRenderDevice(), pMatrix, errorCode), FWL_ERR_Indefinite);
+ return FWL_ERR_Succeeded;
+ }
+ return CFWL_EditImp::DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_BarcodeImp::GenerateBarcodeImageCache()
+{
+ if ((m_dwStatus & XFA_BCS_NeedUpdate) == 0) {
+ return;
+ }
+ m_dwStatus = 0;;
+ CreateBarcodeEngine();
+ IFWL_BarcodeDP *pData = (IFWL_BarcodeDP*)m_pProperties->m_pDataProvider;
+ _FWL_RETURN_IF_FAIL(pData);
+ _FWL_RETURN_IF_FAIL(m_pBarcodeEngine);
+ CFX_WideString wsText;
+ _FWL_RETURN_IF_FAIL(GetText(wsText) == FWL_ERR_Succeeded);
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pInterface;
+ IFWL_ThemeProvider *pTheme = GetAvailableTheme();
+ IFX_Font* pFont = (IFX_Font*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_Font);
+ CFX_Font* pCXFont = (CFX_Font*)(pFont ? pFont->GetDevFont() : NULL);
+ if(pCXFont) {
+ m_pBarcodeEngine->SetFont(pCXFont);
+ }
+ FX_FLOAT* pFontSize = (FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_FontSize);
+ if(pFontSize) {
+ m_pBarcodeEngine->SetFontSize(*pFontSize);
+ }
+ FX_ARGB* pFontColor = (FX_ARGB*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_TextColor);
+ if(pFontColor) {
+ m_pBarcodeEngine->SetFontColor(*pFontColor);
+ }
+ m_pBarcodeEngine->SetHeight(FX_INT32(m_rtClient.height));
+ m_pBarcodeEngine->SetWidth(FX_INT32(m_rtClient.width));
+ FX_DWORD dwAttributeMask = pData->GetBarcodeAttributeMask();
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_CHARENCODING) {
+ m_pBarcodeEngine->SetCharEncoding (pData->GetCharEncoding());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEHEIGHT) {
+ m_pBarcodeEngine->SetModuleHeight (pData->GetModuleHeight());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_MODULEWIDTH) {
+ m_pBarcodeEngine->SetModuleWidth (pData->GetModuleWidth());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_DATALENGTH) {
+ m_pBarcodeEngine->SetDataLength (pData->GetDataLength());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_CALCHECKSUM) {
+ m_pBarcodeEngine->SetCalChecksum (pData->GetCalChecksum());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_PRINTCHECKSUM) {
+ m_pBarcodeEngine->SetPrintChecksum (pData->GetPrintChecksum());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_TEXTLOCATION) {
+ m_pBarcodeEngine->SetTextLocation (pData->GetTextLocation());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_WIDENARROWRATIO) {
+ m_pBarcodeEngine->SetWideNarrowRatio (pData->GetWideNarrowRatio());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_STARTCHAR) {
+ m_pBarcodeEngine->SetStartChar (pData->GetStartChar());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_ENDCHAR) {
+ m_pBarcodeEngine->SetEndChar (pData->GetEndChar());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_VERSION) {
+ m_pBarcodeEngine->SetVersion (pData->GetVersion());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_ECLEVEL) {
+ m_pBarcodeEngine->SetErrorCorrectionLevel (pData->GetErrorCorrectionLevel());
+ }
+ if (dwAttributeMask & FWL_BCDATTRIBUTE_TRUNCATED) {
+ m_pBarcodeEngine->SetTruncated (pData->GetTruncated());
+ }
+ FX_INT32 errorCode = 0;
+ m_dwStatus = m_pBarcodeEngine->Encode(wsText, TRUE, errorCode) ? XFA_BCS_EncodeSuccess : 0;
+}
+void CFWL_BarcodeImp::CreateBarcodeEngine()
+{
+ if ((m_pBarcodeEngine == NULL) && (m_type != BC_UNKNOWN)) {
+ m_pBarcodeEngine = FX_Barcode_Create(m_type);
+ }
+}
+void CFWL_BarcodeImp::ReleaseBarcodeEngine()
+{
+ if (m_pBarcodeEngine) {
+ m_pBarcodeEngine->Release();
+ m_pBarcodeEngine = NULL;
+ }
+}
+void CFWL_BarcodeImp::SetType(BC_TYPE type)
+{
+ if (m_type == type) {
+ return;
+ }
+ ReleaseBarcodeEngine();
+ m_type = type;
+ m_dwStatus = XFA_BCS_NeedUpdate;
+}
+FWL_ERR CFWL_BarcodeImp::SetText(const CFX_WideString &wsText)
+{
+ ReleaseBarcodeEngine();
+ m_dwStatus = XFA_BCS_NeedUpdate;
+ return CFWL_EditImp::SetText(wsText);
+}
+FX_BOOL CFWL_BarcodeImp::IsProtectedType()
+{
+ if (!m_pBarcodeEngine) {
+ return TRUE;
+ }
+ BC_TYPE tEngineType = m_pBarcodeEngine->GetType();
+ if (tEngineType == BC_QR_CODE || tEngineType == BC_PDF417 || tEngineType == BC_DATAMATRIX) {
+ return TRUE;
+ }
+ return FALSE;
+}
+CFWL_BarcodeImpDelegate::CFWL_BarcodeImpDelegate(CFWL_BarcodeImp *pOwner)
+ : CFWL_EditImpDelegate(pOwner)
+{
+}
+FWL_ERR CFWL_BarcodeImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ FX_DWORD dwFlag = pEvent->GetClassID();
+ if (dwFlag == FWL_EVTHASH_EDT_TextChanged) {
+ CFWL_BarcodeImp* pOwner = (CFWL_BarcodeImp*)m_pOwner;
+ pOwner->ReleaseBarcodeEngine();
+ pOwner->m_dwStatus = XFA_BCS_NeedUpdate;
+ }
+ return CFWL_EditImpDelegate::OnProcessEvent(pEvent);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_caretimp.cpp b/xfa/src/fwl/src/basewidget/fwl_caretimp.cpp
new file mode 100644
index 0000000000..f8c7d09eb2
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_caretimp.cpp
@@ -0,0 +1,192 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_caretimp.h"
+IFWL_Caret* IFWL_Caret::Create()
+{
+ return new IFWL_Caret;
+}
+IFWL_Caret::IFWL_Caret()
+{
+ m_pData = NULL;
+}
+IFWL_Caret::~IFWL_Caret()
+{
+ if (m_pData) {
+ delete (CFWL_CaretImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_Caret::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_CaretImp(pOuter);
+ ((CFWL_CaretImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CaretImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Caret::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_CaretImp(properties, pOuter);
+ ((CFWL_CaretImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CaretImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Caret::ShowCaret(FX_BOOL bFlag)
+{
+ return ((CFWL_CaretImp*)m_pData)->ShowCaret(bFlag);
+}
+FWL_ERR IFWL_Caret::GetFrequency(FX_DWORD &elapse)
+{
+ return ((CFWL_CaretImp*)m_pData)->GetFrequency(elapse);
+}
+FWL_ERR IFWL_Caret::SetFrequency(FX_DWORD elapse)
+{
+ return ((CFWL_CaretImp*)m_pData)->SetFrequency(elapse);
+}
+FWL_ERR IFWL_Caret::SetColor(CFX_Color crFill)
+{
+ return ((CFWL_CaretImp*)m_pData)->SetColor(crFill);
+}
+CFWL_CaretImp::CFWL_CaretImp(IFWL_Widget *pOuter)
+ : m_hTimer(NULL)
+{
+ m_dwElapse = 400;
+ m_pTimer = FX_NEW CFWL_CaretTimer(this);
+ m_bSetColor = FALSE;
+ SetStates(FWL_STATE_CAT_HightLight);
+}
+CFWL_CaretImp::CFWL_CaretImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter): m_hTimer(NULL)
+{
+ m_dwElapse = 400;
+ m_pTimer = FX_NEW CFWL_CaretTimer(this);
+ m_bSetColor = FALSE;
+ SetStates(FWL_STATE_CAT_HightLight);
+}
+CFWL_CaretImp::~CFWL_CaretImp()
+{
+ if (m_pTimer) {
+ delete m_pTimer;
+ m_pTimer = NULL;
+ }
+}
+FWL_ERR CFWL_CaretImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_Caret;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_CaretImp::GetClassID() const
+{
+ return FWL_CLASSHASH_Caret;
+}
+FWL_ERR CFWL_CaretImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_CaretImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CaretImp::Finalize()
+{
+ if (m_hTimer) {
+ FWL_StopTimer(m_hTimer);
+ m_hTimer = NULL;
+ }
+ if (m_pDelegate) {
+ delete (CFWL_CaretImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_CaretImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ DrawCaretBK(pGraphics, m_pProperties->m_pThemeProvider, pMatrix);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CaretImp::ShowCaret(FX_BOOL bFlag)
+{
+ if (m_hTimer) {
+ FWL_StopTimer(m_hTimer);
+ m_hTimer = NULL;
+ }
+ if (bFlag) {
+ m_hTimer = FWL_StartTimer((IFWL_Timer *)m_pTimer, m_dwElapse);
+ }
+ return SetStates(FWL_WGTSTATE_Invisible, !bFlag);
+}
+FWL_ERR CFWL_CaretImp::GetFrequency(FX_DWORD &elapse)
+{
+ elapse = m_dwElapse;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CaretImp::SetFrequency(FX_DWORD elapse)
+{
+ m_dwElapse = elapse;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CaretImp::SetColor(CFX_Color crFill)
+{
+ m_bSetColor = TRUE;
+ m_crFill = crFill;
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_CaretImp::DrawCaretBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFX_RectF rect;
+ GetWidgetRect(rect);
+ rect.Set(0, 0, rect.width, rect.height);
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_pGraphics = pGraphics;
+ param.m_rtPart = rect;
+ if (m_bSetColor) {
+ param.m_pData = &m_crFill;
+ }
+ if (!(m_pProperties->m_dwStates & FWL_STATE_CAT_HightLight)) {
+ return FWL_ERR_Succeeded;
+ }
+ param.m_iPart = FWL_PART_CAT_Background;
+ param.m_dwStates = FWL_PARTSTATE_CAT_HightLight;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&param);
+ return FWL_ERR_Succeeded;
+}
+CFWL_CaretImp::CFWL_CaretTimer::CFWL_CaretTimer(CFWL_CaretImp *m_pCaret)
+{
+ this->m_pCaret = m_pCaret;
+}
+FX_INT32 CFWL_CaretImp::CFWL_CaretTimer::Run(FWL_HTIMER hTimer)
+{
+ if (m_pCaret->GetStates() & FWL_STATE_CAT_HightLight) {
+ m_pCaret->SetStates(FWL_STATE_CAT_HightLight, FALSE);
+ } else {
+ m_pCaret->SetStates(FWL_STATE_CAT_HightLight);
+ }
+ CFX_RectF rt;
+ m_pCaret->GetWidgetRect(rt);
+ rt.Set(0, 0, rt.width + 1, rt.height);
+ m_pCaret->Repaint(&rt);
+ return 1;
+}
+CFWL_CaretImpDelegate::CFWL_CaretImpDelegate(CFWL_CaretImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_CaretImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return 1;
+}
+FWL_ERR CFWL_CaretImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_checkboximp.cpp b/xfa/src/fwl/src/basewidget/fwl_checkboximp.cpp
new file mode 100644
index 0000000000..89311b39f2
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_checkboximp.cpp
@@ -0,0 +1,606 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_widgetmgrimp.h"
+#include "include/fwl_checkboximp.h"
+#define FWL_CKB_CaptionMargin 5
+IFWL_CheckBox* IFWL_CheckBox::Create()
+{
+ return new IFWL_CheckBox;
+}
+IFWL_CheckBox::IFWL_CheckBox()
+{
+ m_pData = NULL;
+}
+IFWL_CheckBox::~IFWL_CheckBox()
+{
+ if (m_pData) {
+ delete (CFWL_CheckBoxImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_CheckBox::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_CheckBoxImp(pOuter);
+ ((CFWL_CheckBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CheckBoxImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_CheckBox::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_CheckBoxImp(properties, pOuter);
+ ((CFWL_CheckBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CheckBoxImp*)m_pData)->Initialize();
+}
+FX_INT32 IFWL_CheckBox::GetCheckState()
+{
+ return ((CFWL_CheckBoxImp*)m_pData)->GetCheckState();
+}
+FWL_ERR IFWL_CheckBox::SetCheckState(FX_INT32 iCheck)
+{
+ return ((CFWL_CheckBoxImp*)m_pData)->SetCheckState(iCheck);
+}
+IFWL_RadioButton* IFWL_RadioButton::Create()
+{
+ return new IFWL_RadioButton;
+}
+IFWL_RadioButton::IFWL_RadioButton()
+{
+ m_pData = NULL;
+}
+IFWL_RadioButton::~IFWL_RadioButton()
+{
+ if (m_pData) {
+ delete (CFWL_CheckBoxImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_RadioButton::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_CheckBoxImp(pOuter);
+ ((CFWL_CheckBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CheckBoxImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_RadioButton::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_CheckBoxImp(properties, pOuter);
+ ((CFWL_CheckBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CheckBoxImp*)m_pData)->Initialize();
+}
+CFWL_CheckBoxImp::CFWL_CheckBoxImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
+ , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
+ , m_bBtnDown(FALSE)
+{
+ m_rtClient.Reset();
+ m_rtBox.Reset();
+ m_rtCaption.Reset();
+ m_rtFocus.Reset();
+}
+CFWL_CheckBoxImp::CFWL_CheckBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
+ , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
+ , m_bBtnDown(FALSE)
+{
+ m_rtClient.Reset();
+ m_rtBox.Reset();
+ m_rtCaption.Reset();
+ m_rtFocus.Reset();
+}
+CFWL_CheckBoxImp::~CFWL_CheckBoxImp()
+{
+}
+FWL_ERR CFWL_CheckBoxImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_RadioButton) ? FWL_CLASS_RadioButton : FWL_CLASS_CheckBox;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_CheckBoxImp::GetClassID() const
+{
+ return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_RadioButton ? FWL_CLASSHASH_RadioButton : FWL_CLASSHASH_CheckBox;
+}
+FWL_ERR CFWL_CheckBoxImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_CheckBoxImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CheckBoxImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_CheckBoxImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_CheckBoxImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FWL_ERR_Indefinite);
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption);
+ if (wsCaption.GetLength() > 0) {
+ CFX_SizeF sz = CalcTextSize(wsCaption,
+ m_pProperties->m_pThemeProvider,
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine);
+ rect.Set(0, 0, sz.x, sz.y);
+ }
+ rect.Inflate(FWL_CKB_CaptionMargin, FWL_CKB_CaptionMargin);
+ IFWL_CheckBoxDP *pData = (IFWL_CheckBoxDP*)m_pProperties->m_pDataProvider;
+ FX_FLOAT fCheckBox = pData->GetBoxSize(m_pInterface);
+ rect.width += fCheckBox;
+ if (rect.height < fCheckBox) {
+ rect.height = fCheckBox;
+ }
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CheckBoxImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ UpdateTextOutStyles();
+ Layout();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CheckBoxImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_CKB_Border, m_pProperties->m_pThemeProvider, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_CKB_Edge, pTheme, pMatrix);
+ }
+ FX_INT32 dwStates = GetPartStates();
+ {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_CKB_Background;
+ param.m_dwStates = dwStates;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtClient;
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ param.m_pData = &m_rtFocus;
+ }
+ pTheme->DrawBackground(&param);
+ param.m_iPart = FWL_PART_CKB_CheckBox;
+ param.m_rtPart = m_rtBox;
+ pTheme->DrawBackground(&param);
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FWL_ERR_Indefinite);
+ {
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption);
+ FX_INT32 iLen = wsCaption.GetLength();
+ _FWL_RETURN_VALUE_IF_FAIL(iLen > 0, FWL_ERR_Indefinite);
+ CFWL_ThemeText textParam;
+ textParam.m_pWidget = m_pInterface;
+ textParam.m_iPart = FWL_PART_CKB_Caption;
+ textParam.m_dwStates = dwStates;
+ textParam.m_pGraphics = pGraphics;
+ if(pMatrix) {
+ textParam.m_matrix.Concat(*pMatrix);
+ }
+ textParam.m_rtPart = m_rtCaption;
+ textParam.m_wsText = wsCaption;
+ textParam.m_dwTTOStyles = m_dwTTOStyles;
+ textParam.m_iTTOAlign = m_iTTOAlign;
+ pTheme->DrawText(&textParam);
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_CheckBoxImp::GetCheckState()
+{
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State)
+ && ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == FWL_STATE_CKB_Neutral)) {
+ return 2;
+ }
+ if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == FWL_STATE_CKB_Checked) {
+ return 1;
+ }
+ return 0;
+}
+FWL_ERR CFWL_CheckBoxImp::SetCheckState(FX_INT32 iCheck)
+{
+ m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask;
+ switch(iCheck) {
+ case 0: {
+ break;
+ }
+ case 1: {
+ m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
+ break;
+ }
+ case 2: {
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) {
+ m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral;
+ }
+ break;
+ }
+ default: {
+ }
+ }
+ Repaint(&m_rtClient);
+ return FWL_ERR_Succeeded;
+}
+void CFWL_CheckBoxImp::Layout()
+{
+ FX_INT32 width = FX_INT32(m_pProperties->m_rtWidget.width + 0.5f);
+ FX_INT32 height = FX_INT32(m_pProperties->m_rtWidget.height + 0.5f);
+ m_pProperties->m_rtWidget.width = (FX_FLOAT)width;
+ m_pProperties->m_rtWidget.height = (FX_FLOAT)height;
+ GetClientRect(m_rtClient);
+ FX_FLOAT fBoxTop = m_rtClient.top;
+ FX_FLOAT fBoxLeft = m_rtClient.left;
+ FX_FLOAT fTextLeft = 0.0, fTextRight = 0.0;
+ FX_FLOAT fClientRight = m_rtClient.right();
+ FX_FLOAT fClientBottom = m_rtClient.bottom();
+ _FWL_RETURN_IF_FAIL(m_pProperties->m_pDataProvider);
+ IFWL_CheckBoxDP *pData = (IFWL_CheckBoxDP*)m_pProperties->m_pDataProvider;
+ FX_FLOAT fCheckBox = pData->GetBoxSize(m_pInterface);
+ switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) {
+ case FWL_STYLEEXT_CKB_Top: {
+ fBoxTop = m_rtClient.top;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Bottom: {
+ fBoxTop = fClientBottom - fCheckBox;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_VCenter:
+ default: {
+ fBoxTop = m_rtClient.top + (m_rtClient.height - fCheckBox) / 2;
+ fBoxTop = FXSYS_floor(fBoxTop);
+ }
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_LeftText) {
+ fBoxLeft = fClientRight - fCheckBox;
+ fTextLeft = m_rtClient.left;
+ fTextRight = fBoxLeft;
+ } else {
+ fTextLeft = fBoxLeft + fCheckBox;
+ fTextRight = fClientRight;
+ }
+ m_rtBox.Set(fBoxLeft, fBoxTop, fCheckBox, fCheckBox);
+ m_rtCaption.Set(fTextLeft, m_rtClient.top, fTextRight - fTextLeft, m_rtClient.height);
+ m_rtCaption.Inflate(-FWL_CKB_CaptionMargin, -FWL_CKB_CaptionMargin);
+ CFX_RectF rtFocus;
+ rtFocus.Set(m_rtCaption.left, m_rtCaption.top, m_rtCaption.width, m_rtCaption.height);
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption);
+ if (wsCaption.IsEmpty()) {
+ m_rtFocus.Set(0, 0, 0, 0);
+ } else {
+ CalcTextRect(wsCaption, m_pProperties->m_pThemeProvider, m_dwTTOStyles, m_iTTOAlign, rtFocus);
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) == 0) {
+ FX_FLOAT fWidth = FX_MAX(m_rtCaption.width, rtFocus.width);
+ FX_FLOAT fHeight = FX_MIN(m_rtCaption.height, rtFocus.height);
+ FX_FLOAT fLeft = m_rtCaption.left;
+ FX_FLOAT fTop = m_rtCaption.top;
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == FWL_STYLEEXT_CKB_Center) {
+ fLeft = m_rtCaption.left + (m_rtCaption.width - fWidth) / 2;
+ } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_HLayoutMask) == FWL_STYLEEXT_CKB_Right) {
+ fLeft = m_rtCaption.right() - fWidth;
+ }
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == FWL_STYLEEXT_CKB_VCenter) {
+ fTop = m_rtCaption.top + (m_rtCaption.height - fHeight) / 2;
+ } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_VLayoutMask) == FWL_STYLEEXT_CKB_Bottom) {
+ fTop = m_rtCaption.bottom() - fHeight;
+ }
+ m_rtFocus.Set(fLeft, fTop, fWidth, fHeight);
+ } else {
+ m_rtFocus.Set(rtFocus.left, rtFocus.top, rtFocus.width, rtFocus.height);
+ }
+ m_rtFocus.Inflate(1, 1);
+ }
+}
+FX_DWORD CFWL_CheckBoxImp::GetPartStates()
+{
+ FX_INT32 dwStates = FWL_PARTSTATE_CKB_UnChecked;
+ if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == FWL_STATE_CKB_Neutral) {
+ dwStates = FWL_PARTSTATE_CKB_Neutral;
+ } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == FWL_STATE_CKB_Checked) {
+ dwStates = FWL_PARTSTATE_CKB_Checked;
+ }
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ dwStates |= FWL_PARTSTATE_CKB_Disabled;
+ } else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered ) {
+ dwStates |= FWL_PARTSTATE_CKB_Hovered;
+ } else if (m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed ) {
+ dwStates |= FWL_PARTSTATE_CKB_Pressed;
+ } else {
+ dwStates |= FWL_PARTSTATE_CKB_Normal;
+ }
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ dwStates |= FWL_PARTSTATE_CKB_Focused;
+ }
+ return dwStates;
+}
+void CFWL_CheckBoxImp::UpdateTextOutStyles()
+{
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ switch (m_pProperties->m_dwStyleExes & (FWL_STYLEEXT_CKB_HLayoutMask | FWL_STYLEEXT_CKB_VLayoutMask)) {
+ case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Top: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Top: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Top: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_TopRight;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Left | FWL_STYLEEXT_CKB_Bottom: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Center | FWL_STYLEEXT_CKB_Bottom: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter;
+ break;
+ }
+ case FWL_STYLEEXT_CKB_Right | FWL_STYLEEXT_CKB_Bottom: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight;
+ break;
+ }
+ default: {
+ }
+ }
+ m_dwTTOStyles = 0;
+ if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_MultiLine) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_LineWrap;
+ } else {
+ m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine;
+ }
+}
+void CFWL_CheckBoxImp::NextStates()
+{
+ FX_DWORD dwFirststate = m_pProperties->m_dwStates;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_RadioButton) {
+ if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == FWL_STATE_CKB_Unchecked) {
+ IFWL_WidgetMgr *pWMgr = FWL_GetWidgetMgr();
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr* )pWMgr;
+ if (!pWidgetMgr->IsFormDisabled()) {
+ CFX_PtrArray radioarr;
+ pWidgetMgr->GetSameGroupRadioButton(m_pInterface, radioarr);
+ IFWL_CheckBox *pCheckBox = NULL;
+ FX_INT32 iCount = radioarr.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ pCheckBox = (IFWL_CheckBox *)radioarr[i];
+ if (pCheckBox != m_pInterface && pCheckBox->GetStates() & FWL_STATE_CKB_Checked) {
+ pCheckBox->SetCheckState(0);
+ CFX_RectF rt;
+ pCheckBox->GetWidgetRect(rt);
+ rt.left = rt.top = 0;
+ m_pWidgetMgr->RepaintWidget(pCheckBox, &rt);
+ break;
+ }
+ }
+ }
+ m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
+ }
+ } else {
+ if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == FWL_STATE_CKB_Neutral) {
+ m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) {
+ m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
+ }
+ } else if ((m_pProperties->m_dwStates & FWL_STATE_CKB_CheckMask) == FWL_STATE_CKB_Checked) {
+ m_pProperties->m_dwStates &= ~FWL_STATE_CKB_CheckMask;
+ } else {
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CKB_3State) {
+ m_pProperties->m_dwStates |= FWL_STATE_CKB_Neutral;
+ } else {
+ m_pProperties->m_dwStates |= FWL_STATE_CKB_Checked;
+ }
+ }
+ }
+ Repaint(&m_rtClient);
+ FX_DWORD dwLaststate = m_pProperties->m_dwStates;
+ if (dwFirststate != dwLaststate) {
+ CFWL_EvtCkbCheckStateChanged wmCheckBoxState;
+ wmCheckBoxState.m_pSrcTarget = m_pInterface;
+ DispatchEvent(&wmCheckBoxState);
+ }
+}
+CFWL_CheckBoxImpDelegate::CFWL_CheckBoxImpDelegate(CFWL_CheckBoxImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_CheckBoxImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_INT32 iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_Activate: {
+ OnActivate(pMessage);
+ break;
+ }
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch (dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ CFWL_MsgKey *pKey = (CFWL_MsgKey*)pMessage;
+ if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
+ OnKeyDown((CFWL_MsgKey*)pKey);
+ }
+ break;
+ }
+ default: {
+ iRet = 0;
+ }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+ return iRet;
+}
+FWL_ERR CFWL_CheckBoxImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_CheckBoxImpDelegate::OnActivate(CFWL_Message *pMsg)
+{
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&(m_pOwner->m_rtClient));
+}
+void CFWL_CheckBoxImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet )
+{
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ }
+ m_pOwner->Repaint(&(m_pOwner->m_rtClient));
+}
+void CFWL_CheckBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ m_pOwner->m_bBtnDown = TRUE;
+ m_pOwner->m_pProperties->m_dwStates &= ~ FWL_STATE_CKB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed;
+ m_pOwner->Repaint(&(m_pOwner->m_rtClient));
+}
+void CFWL_CheckBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ if (!m_pOwner->m_bBtnDown) {
+ return;
+ }
+ m_pOwner->m_bBtnDown = FALSE;
+ if (!m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed;
+ m_pOwner->NextStates();
+}
+void CFWL_CheckBoxImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ if (m_pOwner->m_bBtnDown) {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) == 0) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Pressed;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered)) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
+ }
+ } else {
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Pressed) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Pressed;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ }
+ }
+ } else {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_CKB_Hovered) == 0) {
+ bRepaint = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ }
+ }
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&(m_pOwner->m_rtBox));
+ }
+}
+void CFWL_CheckBoxImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_bBtnDown) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_CKB_Hovered;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_CKB_Hovered;
+ }
+ m_pOwner->Repaint(&(m_pOwner->m_rtBox));
+}
+void CFWL_CheckBoxImpDelegate::OnKeyDown(CFWL_MsgKey *pMsg)
+{
+ if (pMsg->m_dwKeyCode == FWL_VKEY_Tab) {
+ m_pOwner->DispatchKeyEvent(pMsg);
+ return;
+ }
+ if (pMsg->m_dwKeyCode == FWL_VKEY_Return || pMsg->m_dwKeyCode == FWL_VKEY_Space) {
+ m_pOwner->NextStates();
+ }
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_comboboximp.cpp b/xfa/src/fwl/src/basewidget/fwl_comboboximp.cpp
new file mode 100644
index 0000000000..0200f92eaa
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_comboboximp.cpp
@@ -0,0 +1,1991 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../../src/core/include/fwl_threadimp.h"
+#include "../../src/core/include/fwl_appimp.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_panelimp.h"
+#include "../core/include/fwl_formimp.h"
+#include "../core/include/fwl_widgetmgrimp.h"
+#include "include/fwl_scrollbarimp.h"
+#include "include/fwl_editimp.h"
+#include "include/fwl_listboximp.h"
+#include "include/fwl_formproxyimp.h"
+#include "include/fwl_comboboximp.h"
+IFWL_ComboBox* IFWL_ComboBox::Create()
+{
+ return new IFWL_ComboBox;
+}
+IFWL_ComboBox::IFWL_ComboBox()
+{
+ m_pData = NULL;
+}
+IFWL_ComboBox::~IFWL_ComboBox()
+{
+ if (m_pData) {
+ delete (CFWL_ComboBoxImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_ComboBox::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ComboBoxImp(pOuter);
+ ((CFWL_ComboBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ComboBoxImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_ComboBox::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ComboBoxImp(properties, pOuter);
+ ((CFWL_ComboBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ComboBoxImp*)m_pData)->Initialize();
+}
+FX_INT32 IFWL_ComboBox::GetCurSel()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->GetCurSel();
+}
+FWL_ERR IFWL_ComboBox::SetCurSel(FX_INT32 iSel)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->SetCurSel(iSel);
+}
+FWL_ERR IFWL_ComboBox::SetEditText(const CFX_WideString &wsText)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->SetEditText(wsText);
+}
+FX_INT32 IFWL_ComboBox::GetEditTextLength() const
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->GetEditTextLength();
+}
+FWL_ERR IFWL_ComboBox::GetEditText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount) const
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->GetEditText(wsText, nStart, nCount);
+}
+FWL_ERR IFWL_ComboBox::SetEditSelRange(FX_INT32 nStart, FX_INT32 nCount)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->SetEditSelRange(nStart, nCount);
+}
+FX_INT32 IFWL_ComboBox::GetEditSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->GetEditSelRange(nIndex, nStart);
+}
+FX_INT32 IFWL_ComboBox::GetEditLimit()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->GetEditLimit();
+}
+FWL_ERR IFWL_ComboBox::SetEditLimit(FX_INT32 nLimit)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->SetEditLimit(nLimit);
+}
+FWL_ERR IFWL_ComboBox::EditDoClipboard(FX_INT32 iCmd)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditDoClipboard(iCmd);
+}
+FX_BOOL IFWL_ComboBox::EditRedo(FX_BSTR bsRecord)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditRedo(bsRecord);
+}
+FX_BOOL IFWL_ComboBox::EditUndo(FX_BSTR bsRecord)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditUndo(bsRecord);
+}
+IFWL_ListBox* IFWL_ComboBox::GetListBoxt()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->GetListBoxt();
+}
+FX_BOOL IFWL_ComboBox::AfterFocusShowDropList()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->AfterFocusShowDropList();
+}
+FX_ERR IFWL_ComboBox::OpenDropDownList(FX_BOOL bActivate)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->OpenDropDownList(bActivate);
+}
+FX_BOOL IFWL_ComboBox::EditCanUndo()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditCanUndo();
+}
+FX_BOOL IFWL_ComboBox::EditCanRedo()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditCanRedo();
+}
+FX_BOOL IFWL_ComboBox::EditUndo()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditUndo();
+}
+FX_BOOL IFWL_ComboBox::EditRedo()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditRedo();
+}
+FX_BOOL IFWL_ComboBox::EditCanCopy()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditCanCopy();
+}
+FX_BOOL IFWL_ComboBox::EditCanCut()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditCanCut();
+}
+FX_BOOL IFWL_ComboBox::EditCanSelectAll()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditCanSelectAll();
+}
+FX_BOOL IFWL_ComboBox::EditCopy(CFX_WideString &wsCopy)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditCopy(wsCopy);
+}
+FX_BOOL IFWL_ComboBox::EditCut(CFX_WideString &wsCut)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditCut(wsCut);
+}
+FX_BOOL IFWL_ComboBox::EditPaste(const CFX_WideString &wsPaste)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditPaste(wsPaste);
+}
+FX_BOOL IFWL_ComboBox::EditSelectAll()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditSelectAll();
+}
+FX_BOOL IFWL_ComboBox::EditDelete()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditDelete();
+}
+FX_BOOL IFWL_ComboBox::EditDeSelect()
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditDeSelect();
+}
+FWL_ERR IFWL_ComboBox::GetBBox(CFX_RectF &rect)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->GetBBox(rect);
+}
+FWL_ERR IFWL_ComboBox::EditModifyStylesEx(FX_DWORD dwStylesExAdded,
+ FX_DWORD dwStylesExRemoved)
+{
+ return ((CFWL_ComboBoxImp*)m_pData)->EditModifyStylesEx(dwStylesExAdded,
+ dwStylesExRemoved);
+}
+CFWL_ComboEdit::CFWL_ComboEdit(IFWL_Widget *pOuter)
+ : CFWL_EditImp(pOuter)
+{
+ FXSYS_assert(pOuter != NULL);
+ m_pOuter = (CFWL_ComboBoxImp*)(((IFWL_TargetData*)pOuter)->GetData());
+}
+CFWL_ComboEdit::CFWL_ComboEdit(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+ : CFWL_EditImp(properties, pOuter)
+{
+ FXSYS_assert(pOuter != NULL);
+ m_pOuter = (CFWL_ComboBoxImp*)(((IFWL_TargetData*)pOuter)->GetData());
+}
+
+CFWL_ComboEditDelegate::CFWL_ComboEditDelegate(CFWL_ComboEdit *pOwner)
+ : CFWL_EditImpDelegate(pOwner)
+ , m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_ComboEditDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_BOOL backDefault = TRUE;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ if (dwMsgCode == FWL_MSGHASH_SetFocus) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ }
+ backDefault = FALSE;
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ if ((pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) &&
+ ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0)) {
+ m_pOwner->SetSelected();
+ m_pOwner->SetComboBoxFocus(TRUE);
+ }
+ break;
+ }
+ default: {
+ }
+ }
+ if (!backDefault) {
+ return 1;
+ }
+ return CFWL_EditImpDelegate::OnProcessMessage(pMessage);
+}
+void CFWL_ComboEdit::ClearSelected()
+{
+ ClearSelections();
+ Repaint(&m_rtClient);
+}
+void CFWL_ComboEdit::SetSelected()
+{
+ FlagFocus(TRUE);
+ EndCaret();
+ AddSelRange(0);
+}
+void CFWL_ComboEdit::EndCaret()
+{
+ m_pEdtEngine->MoveCaretPos(MC_End);
+}
+void CFWL_ComboEdit::FlagFocus(FX_BOOL bSet)
+{
+ if (bSet) {
+ m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ ShowCaret(FALSE);
+ }
+};
+void CFWL_ComboEdit::SetComboBoxFocus(FX_BOOL bSet)
+{
+ m_pOuter->SetFocus(bSet);
+}
+CFWL_ComboList::CFWL_ComboList(IFWL_Widget *pOuter)
+ : CFWL_ListBoxImp(pOuter)
+ , m_bNotifyOwner(TRUE)
+{
+ FXSYS_assert(pOuter != NULL);
+}
+CFWL_ComboList::CFWL_ComboList(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+ : CFWL_ListBoxImp(properties, pOuter)
+ , m_bNotifyOwner(TRUE)
+{
+ FXSYS_assert(pOuter != NULL);
+}
+FWL_ERR CFWL_ComboList::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_ListBoxImp::Initialize(), FWL_ERR_Indefinite);
+ if (m_pDelegate) {
+ delete (CFWL_ComboListDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_ComboListDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboList::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_ComboListDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_ListBoxImp::Finalize();
+}
+FX_INT32 CFWL_ComboList::MatchItem(const CFX_WideString &wsMatch)
+{
+ if (wsMatch.IsEmpty()) {
+ return -1;
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, -1);
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ CFX_WideString wsText;
+ pData->GetItemText(m_pInterface, hItem, wsText);
+ FX_STRSIZE pos = wsText.Find((FX_LPCWSTR)wsMatch);
+ if (!pos) {
+ return i;
+ }
+ }
+ return -1;
+}
+void CFWL_ComboList::ChangeSelected(FX_INT32 iSel)
+{
+ _FWL_RETURN_IF_FAIL(m_pProperties->m_pDataProvider);
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iSel);
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Reset();
+ FWL_HLISTITEM hOld = GetSelItem(0);
+ FX_INT32 iOld = pData->GetItemIndex(m_pInterface, hOld);
+ if (iOld == iSel) {
+ return;
+ } else if (iOld > -1) {
+ GetItemRect(iOld, rtInvalidate);
+ SetSelItem(hOld, FALSE);
+ }
+ if (hItem) {
+ CFX_RectF rect;
+ GetItemRect(iSel, rect);
+ rtInvalidate.Union(rect);
+ FWL_HLISTITEM hSel = pData->GetItem(m_pInterface, iSel);
+ SetSelItem(hSel, TRUE);
+ }
+ if (!rtInvalidate.IsEmpty()) {
+ Repaint(&rtInvalidate);
+ }
+}
+FX_INT32 CFWL_ComboList::CountItems()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, 0);
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ return pData->CountItems(m_pInterface);
+}
+void CFWL_ComboList::GetItemRect(FX_INT32 nIndex, CFX_RectF &rtItem)
+{
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, nIndex);
+ pData->GetItemRect(m_pInterface, hItem, rtItem);
+}
+void CFWL_ComboList::ClientToOuter(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ fx += m_pProperties->m_rtWidget.left, fy += m_pProperties->m_rtWidget.top;
+ IFWL_Widget *pOwner = GetOwner();
+ _FWL_RETURN_IF_FAIL(pOwner);
+ pOwner->TransformTo(m_pOuter, fx, fy);
+}
+void CFWL_ComboList::SetFocus(FX_BOOL bSet)
+{
+ CFWL_WidgetImp::SetFocus(bSet);
+}
+CFWL_ComboListDelegate::CFWL_ComboListDelegate(CFWL_ComboList *pOwner)
+ : CFWL_ListBoxImpDelegate(pOwner)
+ , m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_ComboListDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwHashCode = pMessage->GetClassID();
+ FX_BOOL backDefault = TRUE;
+ if (dwHashCode == FWL_MSGHASH_SetFocus || dwHashCode == FWL_MSGHASH_KillFocus) {
+ OnDropListFocusChanged(pMessage, dwHashCode == FWL_MSGHASH_SetFocus);
+ } else if (dwHashCode == FWL_MSGHASH_Mouse) {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
+ CFX_RectF rect;
+ m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ pMsg->m_fx -= rect.left;
+ pMsg->m_fy -= rect.top;
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pVertScrollBar->SetDelegate(NULL);
+ return pDelegate->OnProcessMessage(pMsg);
+ }
+ }
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch (dwCmd) {
+ case FWL_MSGMOUSECMD_MouseMove: {
+ backDefault = FALSE;
+ OnDropListMouseMove(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ backDefault = FALSE;
+ OnDropListLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ backDefault = FALSE;
+ OnDropListLButtonUp(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ } else if (dwHashCode == FWL_MSGHASH_Key) {
+ CFWL_MsgKey *pMsg = (CFWL_MsgKey*)pMessage;
+ backDefault = !OnDropListKey(pMsg);
+ }
+ if (!backDefault) {
+ return 1;
+ }
+ return CFWL_ListBoxImpDelegate::OnProcessMessage(pMessage);
+}
+void CFWL_ComboListDelegate::OnDropListFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet )
+{
+ if (!bSet) {
+ CFWL_MsgKillFocus *pKill = (CFWL_MsgKillFocus*)pMsg;
+ CFWL_ComboBoxImp *pOuter = (CFWL_ComboBoxImp*)(((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData());
+ if (pKill->m_pSetFocus == (IFWL_Widget*)m_pOwner->m_pOuter || (IFWL_Widget*)pKill->m_pSetFocus == (IFWL_Widget*)pOuter->m_pEdit) {
+ pOuter->ShowDropList(FALSE);
+ }
+ }
+}
+FX_INT32 CFWL_ComboListDelegate::OnDropListMouseMove(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->m_bNotifyOwner) {
+ m_pOwner->m_bNotifyOwner = FALSE;
+ }
+ if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
+ CFX_RectF rect;
+ m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return 1;
+ }
+ }
+ FWL_HLISTITEM hItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (hItem) {
+ _FWL_RETURN_VALUE_IF_FAIL(m_pOwner->m_pProperties->m_pDataProvider, 0);
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pOwner->m_pProperties->m_pDataProvider;
+ FX_INT32 iSel = pData->GetItemIndex(m_pOwner->m_pInterface, hItem);
+ CFWL_EvtCmbHoverChanged event;
+ event.m_pSrcTarget = m_pOwner->m_pOuter;
+ event.m_iCurHover = iSel;
+ m_pOwner->DispatchEvent(&event);
+ m_pOwner->ChangeSelected(iSel);
+ }
+ } else if (m_pOwner->m_bNotifyOwner) {
+ m_pOwner->ClientToOuter(pMsg->m_fx, pMsg->m_fy);
+ CFWL_ComboBoxImp *pOuter = (CFWL_ComboBoxImp*)(((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData());
+ pOuter->m_pDelegate->OnProcessMessage(pMsg);
+ }
+ return 1;
+}
+FX_INT32 CFWL_ComboListDelegate::OnDropListLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return 0;
+ }
+ CFWL_ComboBoxImp *pOuter = (CFWL_ComboBoxImp*)((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData();
+ pOuter->ShowDropList(FALSE);
+ return 1;
+}
+FX_INT32 CFWL_ComboListDelegate::OnDropListLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ CFWL_ComboBoxImp *pOuter = (CFWL_ComboBoxImp*)((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData();
+ if (m_pOwner->m_bNotifyOwner) {
+ m_pOwner->ClientToOuter(pMsg->m_fx, pMsg->m_fy);
+ pOuter->m_pDelegate->OnProcessMessage(pMsg);
+ } else {
+ if (m_pOwner->IsShowScrollBar(TRUE) && m_pOwner->m_pVertScrollBar) {
+ CFX_RectF rect;
+ m_pOwner->m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return 1;
+ }
+ }
+ pOuter->ShowDropList(FALSE);
+ FWL_HLISTITEM hItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (hItem) {
+ pOuter->ProcessSelChanged(TRUE);
+ }
+ }
+ return 1;
+}
+FX_INT32 CFWL_ComboListDelegate::OnDropListKey(CFWL_MsgKey *pKey)
+{
+ CFWL_ComboBoxImp *pOuter = (CFWL_ComboBoxImp*)((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData();
+ FX_BOOL bPropagate = FALSE;
+ if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
+ FX_DWORD dwKeyCode = pKey->m_dwKeyCode;
+ switch (dwKeyCode) {
+ case FWL_VKEY_Return:
+ case FWL_VKEY_Escape: {
+ pOuter->ShowDropList(FALSE);
+ return 1;
+ }
+ case FWL_VKEY_Up:
+ case FWL_VKEY_Down: {
+ OnDropListKeyDown(pKey);
+ IFWL_WidgetDelegate *pDelegate = pOuter->SetDelegate(NULL);
+ pOuter->ProcessSelChanged(FALSE);
+ return 1;
+ }
+ default: {
+ bPropagate = TRUE;
+ }
+ }
+ } else if (pKey->m_dwCmd == FWL_MSGKEYCMD_Char) {
+ bPropagate = TRUE;
+ }
+ if (bPropagate) {
+ pKey->m_pDstTarget = (IFWL_Widget*)m_pOwner->m_pOuter;
+ pOuter->m_pDelegate->OnProcessMessage(pKey);
+ return 1;
+ }
+ return 0;
+}
+void CFWL_ComboListDelegate::OnDropListKeyDown(CFWL_MsgKey *pKey)
+{
+ FX_DWORD dwKeyCode = pKey->m_dwKeyCode;
+ switch(dwKeyCode) {
+ case FWL_VKEY_Up:
+ case FWL_VKEY_Down:
+ case FWL_VKEY_Home:
+ case FWL_VKEY_End: {
+ CFWL_ComboBoxImp *pOuter = (CFWL_ComboBoxImp*)((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData();
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pOwner->m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pOwner->m_pInterface, pOuter->m_iCurSel);
+ hItem = m_pOwner->GetItem(hItem, dwKeyCode);
+ if (!hItem) {
+ break;
+ }
+ m_pOwner->SetSelection(hItem, hItem, TRUE);
+ m_pOwner->ScrollToVisible(hItem);
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0,
+ 0,
+ m_pOwner->m_pProperties->m_rtWidget.width,
+ m_pOwner->m_pProperties->m_rtWidget.height);
+ m_pOwner->Repaint(&rtInvalidate);
+ break;
+ }
+ default: {
+ }
+ }
+}
+CFWL_ComboBoxImp::CFWL_ComboBoxImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_pEdit(NULL)
+ , m_pListBox(NULL)
+ , m_pForm(NULL)
+ , m_bLButtonDown(FALSE)
+ , m_iCurSel(-1)
+ , m_iBtnState(FWL_PARTSTATE_CMB_Normal)
+ , m_fComboFormHandler(0)
+ , m_bNeedShowList(FALSE)
+{
+ m_rtClient.Reset();
+ m_rtBtn.Reset();
+ m_rtHandler.Reset();
+}
+CFWL_ComboBoxImp::CFWL_ComboBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_pEdit(NULL)
+ , m_pListBox(NULL)
+ , m_pForm(NULL)
+ , m_bLButtonDown(FALSE)
+ , m_iCurSel(-1)
+ , m_iBtnState(FWL_PARTSTATE_CMB_Normal)
+ , m_fComboFormHandler(0)
+ , m_bNeedShowList(FALSE)
+{
+ m_rtClient.Reset();
+ m_rtBtn.Reset();
+ m_rtHandler.Reset();
+}
+CFWL_ComboBoxImp::~CFWL_ComboBoxImp()
+{
+ if (m_pEdit) {
+ m_pEdit->Release();
+ m_pEdit = NULL;
+ }
+ if (m_pListBox) {
+ m_pListBox->Release();
+ m_pListBox = NULL;
+ }
+}
+FWL_ERR CFWL_ComboBoxImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_ComboBox;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ComboBoxImp::GetClassID() const
+{
+ return FWL_CLASSHASH_ComboBox;
+}
+FWL_ERR CFWL_ComboBoxImp::Initialize()
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_Initialize();
+ }
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_WGTSTATE_Invisible);
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_ComboBoxImpDelegate(this);
+ CFWL_WidgetImpProperties prop;
+ prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ prop.m_dwStyles |= FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListItemIconText) {
+ prop.m_dwStyleExes |= FWL_STYLEEXT_LTB_Icon;
+ }
+ prop.m_pDataProvider = m_pProperties->m_pDataProvider;
+ CFWL_ComboList *pList = FX_NEW CFWL_ComboList(prop, m_pInterface);
+ m_pListBox = IFWL_ListBox::Create();
+ pList->SetInterface(m_pListBox);
+ ((IFWL_TargetData*)m_pListBox)->SetData(pList);
+ pList->Initialize();
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) && !m_pEdit) {
+ CFWL_ComboEdit *pEdit = FX_NEW CFWL_ComboEdit(m_pInterface);
+ m_pEdit = IFWL_Edit::Create();
+ pEdit->SetInterface(m_pEdit);
+ ((IFWL_TargetData*)m_pEdit)->SetData(pEdit);
+ pEdit->Initialize();
+ pEdit->SetOuter(m_pInterface);
+ }
+ if (m_pEdit) {
+ m_pEdit->SetParent(m_pInterface);
+ }
+ SetStates(m_pProperties->m_dwStates);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBoxImp::Finalize()
+{
+ if (m_pEdit) {
+ m_pEdit->Finalize();
+ }
+ m_pListBox->Finalize();
+ if ( m_pDelegate) {
+ delete (CFWL_ComboBoxImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_ComboBoxImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Reset();
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && m_pEdit) {
+ m_pEdit->GetWidgetRect(rect, TRUE);
+ } else {
+ rect.width = 100;
+ rect.height = 16;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ ReSetTheme();
+ }
+ FX_FLOAT *pFWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_VALUE_IF_FAIL(pFWidth, FWL_ERR_Indefinite);
+ rect.Inflate(0, 0, *pFWidth, 0);
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBoxImp::ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+ }
+ FX_BOOL bAddDropDown = dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown;
+ FX_BOOL bRemoveDropDown = dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown;
+ if (bAddDropDown && !m_pEdit) {
+ CFWL_ComboEdit *pEdit = FX_NEW CFWL_ComboEdit(m_pInterface);
+ m_pEdit = IFWL_Edit::Create();
+ pEdit->SetInterface(m_pEdit);
+ ((IFWL_TargetData*)m_pEdit)->SetData(pEdit);
+ pEdit->Initialize();
+ pEdit->SetOuter(m_pInterface);
+ m_pEdit->SetParent(m_pInterface);
+ } else if (bRemoveDropDown && m_pEdit) {
+ m_pEdit->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+ return CFWL_WidgetImp::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+FWL_ERR CFWL_ComboBoxImp::Update()
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_Update();
+ }
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ ReSetTheme();
+ FX_BOOL bDropDown = IsDropDownStyle();
+ if (bDropDown && m_pEdit) {
+ ReSetEditAlignment();
+ }
+ if (m_pProperties->m_pThemeProvider == NULL) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ Layout();
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pInterface;
+ m_fComboFormHandler = *(FX_FLOAT *) m_pProperties->m_pThemeProvider->GetCapacity(&part, FWL_WGTCAPACITY_CMB_ComboFormHandler);
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ComboBoxImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_HitTest(fx, fy);
+ }
+ return CFWL_WidgetImp::HitTest(fx, fy);
+}
+FWL_ERR CFWL_ComboBoxImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_DrawWidget(pGraphics, pMatrix);
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_CMB_Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_CMB_Edge, pTheme, pMatrix);
+ }
+ if (!bIsDropDown) {
+ CFX_RectF rtTextBk(m_rtClient);
+ rtTextBk.width -= m_rtBtn.width;
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_CMB_Background;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = rtTextBk;
+ if (m_iCurSel >= 0) {
+ IFWL_ListBoxDP* pData = (IFWL_ListBoxDP*)((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->m_pProperties->m_pDataProvider;
+ FX_LPVOID p = pData->GetItemData(m_pListBox, pData->GetItem(m_pListBox, m_iCurSel));
+ if (p != NULL) {
+ param.m_pData = p;
+ }
+ }
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ param.m_dwStates = FWL_PARTSTATE_CMB_Disabled;
+ } else if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && (m_iCurSel >= 0)) {
+ param.m_dwStates = FWL_PARTSTATE_CMB_Selected;
+ } else {
+ param.m_dwStates = FWL_PARTSTATE_CMB_Normal;
+ }
+ pTheme->DrawBackground(&param);
+ if (m_iCurSel >= 0) {
+ _FWL_RETURN_VALUE_IF_FAIL(m_pListBox, FWL_ERR_Indefinite);
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP *)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->GetItemText(hItem, wsText);
+ CFWL_ThemeText param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_CMB_Caption;
+ param.m_dwStates = m_iBtnState;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = rtTextBk;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) ? FWL_PARTSTATE_CMB_Selected : FWL_PARTSTATE_CMB_Normal;
+ param.m_wsText = wsText;
+ param.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ param.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
+ pTheme->DrawText(&param);
+ }
+ }
+ {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_CMB_DropDownButton;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ? FWL_PARTSTATE_CMB_Disabled : m_iBtnState;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = m_rtBtn;
+ pTheme->DrawBackground(&param);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBoxImp::SetThemeProvider(IFWL_ThemeProvider *pThemeProvider)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pThemeProvider, FWL_ERR_Indefinite);
+ m_pProperties->m_pThemeProvider = pThemeProvider;
+ if (m_pListBox && pThemeProvider->IsValidWidget(m_pListBox)) {
+ m_pListBox->SetThemeProvider(pThemeProvider);
+ }
+ if (m_pEdit && pThemeProvider->IsValidWidget(m_pEdit)) {
+ m_pEdit->SetThemeProvider(pThemeProvider);
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ComboBoxImp::GetCurSel()
+{
+ return m_iCurSel;
+}
+FWL_ERR CFWL_ComboBoxImp::SetCurSel(FX_INT32 iSel)
+{
+ FX_INT32 iCount = ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->CountItems();
+ FX_BOOL bClearSel = iSel < 0 || iSel >= iCount;
+ FX_BOOL bDropDown = IsDropDownStyle();
+ if (bDropDown && m_pEdit) {
+ if (bClearSel) {
+ m_pEdit->SetText(CFX_WideString());
+ } else {
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP *)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iSel);
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->GetItemText(hItem, wsText);
+ m_pEdit->SetText(wsText);
+ }
+ m_pEdit->Update();
+ }
+ m_iCurSel = bClearSel ? -1 : iSel;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBoxImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
+{
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && m_pEdit) {
+ m_pEdit->SetStates(dwStates, bSet);
+ }
+ if (m_pListBox) {
+ m_pListBox->SetStates(dwStates, bSet);
+ }
+ return CFWL_WidgetImp::SetStates(dwStates, bSet);
+}
+FWL_ERR CFWL_ComboBoxImp::SetEditText(const CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, FWL_ERR_Indefinite);
+ m_pEdit->SetText(wsText);
+ return m_pEdit->Update();
+}
+FX_INT32 CFWL_ComboBoxImp::GetEditTextLength() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, -1);
+ return m_pEdit->GetTextLength();
+}
+FWL_ERR CFWL_ComboBoxImp::GetEditText(CFX_WideString &wsText, FX_INT32 nStart , FX_INT32 nCount ) const
+{
+ if (m_pEdit) {
+ return m_pEdit->GetText(wsText, nStart, nCount);
+ } else if (m_pListBox) {
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP *)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
+ return m_pListBox->GetItemText(hItem, wsText);
+ }
+ return FWL_ERR_Indefinite;
+}
+FWL_ERR CFWL_ComboBoxImp::SetEditSelRange(FX_INT32 nStart, FX_INT32 nCount )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, FWL_ERR_Indefinite);
+ ((CFWL_ComboEdit*)((IFWL_TargetData*)m_pEdit)->GetData())->ClearSelected();
+ m_pEdit->AddSelRange(nStart, nCount);
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ComboBoxImp::GetEditSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, -1);
+ return m_pEdit->GetSelRange(nIndex, nStart);
+}
+FX_INT32 CFWL_ComboBoxImp::GetEditLimit()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, -1);
+ return m_pEdit->GetLimit();
+}
+FWL_ERR CFWL_ComboBoxImp::SetEditLimit(FX_INT32 nLimit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, FWL_ERR_Indefinite);
+ return m_pEdit->SetLimit(nLimit);
+}
+FWL_ERR CFWL_ComboBoxImp::EditDoClipboard(FX_INT32 iCmd)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, FWL_ERR_Indefinite);
+ return m_pEdit->DoClipboard(iCmd);
+}
+FX_BOOL CFWL_ComboBoxImp::EditRedo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, FALSE);
+ return m_pEdit->Redo(bsRecord);
+}
+FX_BOOL CFWL_ComboBoxImp::EditUndo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, FALSE);
+ return m_pEdit->Undo(bsRecord);
+}
+IFWL_ListBox* CFWL_ComboBoxImp::GetListBoxt()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pListBox, FALSE);
+ return m_pListBox;
+}
+FX_BOOL CFWL_ComboBoxImp::AfterFocusShowDropList()
+{
+ if (!m_bNeedShowList) {
+ return FALSE;
+ }
+ if (m_pEdit) {
+ MatchEditText();
+ }
+ ShowDropList(TRUE);
+ m_bNeedShowList = FALSE;
+ return TRUE;
+}
+FX_ERR CFWL_ComboBoxImp::OpenDropDownList(FX_BOOL bActivate)
+{
+ ShowDropList(bActivate);
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_ComboBoxImp::EditCanUndo()
+{
+ return m_pEdit->CanUndo();
+}
+FX_BOOL CFWL_ComboBoxImp::EditCanRedo()
+{
+ return m_pEdit->CanRedo();
+}
+FX_BOOL CFWL_ComboBoxImp::EditUndo()
+{
+ return m_pEdit->Undo();
+}
+FX_BOOL CFWL_ComboBoxImp::EditRedo()
+{
+ return m_pEdit->Redo();
+}
+FX_BOOL CFWL_ComboBoxImp::EditCanCopy()
+{
+ return m_pEdit->CountSelRanges() > 0;
+}
+FX_BOOL CFWL_ComboBoxImp::EditCanCut()
+{
+ if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
+ return FALSE;
+ }
+ return m_pEdit->CountSelRanges() > 0;
+}
+FX_BOOL CFWL_ComboBoxImp::EditCanSelectAll()
+{
+ return m_pEdit->GetTextLength() > 0;
+}
+FX_BOOL CFWL_ComboBoxImp::EditCopy(CFX_WideString &wsCopy)
+{
+ return m_pEdit->Copy(wsCopy);
+}
+FX_BOOL CFWL_ComboBoxImp::EditCut(CFX_WideString &wsCut)
+{
+ return m_pEdit->Cut(wsCut);
+}
+FX_BOOL CFWL_ComboBoxImp::EditPaste(const CFX_WideString &wsPaste)
+{
+ return m_pEdit->Paste(wsPaste);
+}
+FX_BOOL CFWL_ComboBoxImp::EditSelectAll()
+{
+ return (m_pEdit->AddSelRange(0) == FWL_ERR_Succeeded) ? TRUE : FALSE;
+}
+FX_BOOL CFWL_ComboBoxImp::EditDelete()
+{
+ return (m_pEdit->ClearText() == FWL_ERR_Succeeded) ? TRUE : FALSE;
+}
+FX_BOOL CFWL_ComboBoxImp::EditDeSelect()
+{
+ return (m_pEdit->ClearSelections() == FWL_ERR_Succeeded) ? TRUE : FALSE;
+}
+FWL_ERR CFWL_ComboBoxImp::GetBBox(CFX_RectF &rect)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_GetBBox(rect);
+ }
+ rect = m_pProperties->m_rtWidget;
+ if (m_pListBox && IsDropListShowed()) {
+ CFX_RectF rtList;
+ m_pListBox->GetWidgetRect(rtList);
+ rtList.Offset(rect.left, rect.top);
+ rect.Union(rtList);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBoxImp::EditModifyStylesEx(FX_DWORD dwStylesExAdded,
+ FX_DWORD dwStylesExRemoved)
+{
+ if (m_pEdit != NULL) {
+ return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+ } else {
+ return FWL_ERR_Parameter_Invalid;
+ }
+}
+FX_FLOAT CFWL_ComboBoxImp::GetListHeight()
+{
+ return ((IFWL_ComboBoxDP*)m_pProperties->m_pDataProvider)->GetListHeight(m_pInterface);
+}
+void CFWL_ComboBoxImp::DrawStretchHandler(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground param;
+ param.m_pGraphics = pGraphics;
+ param.m_iPart = FWL_PART_CMB_StretcgHandler;
+ param.m_dwStates = FWL_PARTSTATE_CMB_Normal;
+ param.m_pWidget = m_pInterface;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtHandler;
+ m_pProperties->m_pThemeProvider->DrawBackground(&param);
+}
+void CFWL_ComboBoxImp::ShowDropList(FX_BOOL bActivate)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_ShowDropList(bActivate);
+ }
+ FX_BOOL bDropList = IsDropListShowed();
+ if(bDropList == bActivate) {
+ return;
+ }
+ if (!m_pForm) {
+ InitProxyForm();
+ }
+ m_pListProxyDelegate->Reset();
+ if (bActivate) {
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->ChangeSelected(m_iCurSel);
+ ReSetListItemAlignment();
+ FX_DWORD dwStyleAdd = m_pProperties->m_dwStyleExes & (FWL_STYLEEXT_CMB_Sort | FWL_STYLEEXT_CMB_OwnerDraw);
+ m_pListBox->ModifyStylesEx(dwStyleAdd, 0);
+ m_pListBox->GetWidgetRect(m_rtList, TRUE);
+ FX_FLOAT fHeight = GetListHeight();
+ if (fHeight > 0) {
+ if (m_rtList.height > GetListHeight()) {
+ m_rtList.height = GetListHeight();
+ m_pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll, 0);
+ }
+ }
+ CFX_RectF rtAnchor;
+ rtAnchor.Set(0,
+ 0,
+ m_pProperties->m_rtWidget.width,
+ m_pProperties->m_rtWidget.height);
+ FX_FLOAT fMinHeight = 0;
+ FX_FLOAT fMaxHeight = m_rtList.height;
+ if (m_rtList.width < m_rtClient.width) {
+ m_rtList.width = m_rtClient.width;
+ }
+ m_rtProxy = m_rtList;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) {
+ m_rtProxy.height += m_fComboFormHandler;
+ }
+ GetPopupPos(fMinHeight, m_rtProxy.height, rtAnchor, m_rtProxy);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_ListDrag) {
+ FX_FLOAT fx = 0;
+ FX_FLOAT fy = m_rtClient.top + m_rtClient.height / 2;
+ TransformTo(NULL, fx, fy);
+ m_bUpFormHandler = fy > m_rtProxy.top;
+ if (m_bUpFormHandler) {
+ m_rtHandler.Set(0, 0, m_rtList.width, m_fComboFormHandler);
+ m_rtList.top = m_fComboFormHandler;
+ } else {
+ m_rtHandler.Set(0, m_rtList.height, m_rtList.width, m_fComboFormHandler);
+ }
+ }
+ m_pForm->SetWidgetRect(m_rtProxy);
+ m_pForm->Update();
+ m_pListBox->SetWidgetRect(m_rtList);
+ m_pListBox->Update();
+ CFWL_EvtCmbPreDropDown ev;
+ ev.m_pSrcTarget = m_pInterface;
+ DispatchEvent(&ev);
+ m_fItemHeight = ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->m_fItemHeight;
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->SetFocus(TRUE);
+ m_pForm->DoModal();
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->SetFocus(FALSE);
+ } else {
+ m_pForm->EndDoModal();
+ CFWL_EvtCmbCloseUp ev;
+ ev.m_pSrcTarget = m_pInterface;
+ DispatchEvent(&ev);
+ m_bLButtonDown = FALSE;
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->m_bNotifyOwner = TRUE;
+ SetFocus(TRUE);
+ }
+}
+FX_BOOL CFWL_ComboBoxImp::IsDropListShowed()
+{
+ return m_pForm && !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible);
+}
+FX_BOOL CFWL_ComboBoxImp::IsDropDownStyle() const
+{
+ return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown;
+}
+void CFWL_ComboBoxImp::MatchEditText()
+{
+ CFX_WideString wsText;
+ m_pEdit->GetText(wsText);
+ FX_INT32 iMatch = ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->MatchItem(wsText);
+ if (iMatch != m_iCurSel) {
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->ChangeSelected(iMatch);
+ if (iMatch >= 0) {
+ SynchrEditText(iMatch);
+ }
+ } else if (iMatch >= 0) {
+ ((CFWL_ComboEdit*)((IFWL_TargetData*)m_pEdit)->GetData())->SetSelected();
+ }
+ m_iCurSel = iMatch;
+}
+void CFWL_ComboBoxImp::SynchrEditText(FX_INT32 iListItem)
+{
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP *)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iListItem);
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->GetItemText(hItem, wsText);
+ m_pEdit->SetText(wsText);
+ m_pEdit->Update();
+ ((CFWL_ComboEdit*)((IFWL_TargetData*)m_pEdit)->GetData())->SetSelected();
+}
+void CFWL_ComboBoxImp::Layout()
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_Layout();
+ }
+ GetClientRect(m_rtClient);
+ FX_FLOAT *pFWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_IF_FAIL(pFWidth);
+ FX_FLOAT fBtn = *pFWidth;
+ m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn, m_rtClient.height);
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && m_pEdit) {
+ CFX_RectF rtEdit;
+ rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, m_rtClient.height);
+ m_pEdit->SetWidgetRect(rtEdit);
+ if (m_iCurSel >= 0) {
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP *)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->GetItemText(hItem, wsText);
+ m_pEdit->LockUpdate();
+ m_pEdit->SetText(wsText);
+ m_pEdit->UnlockUpdate();
+ }
+ m_pEdit->Update();
+ }
+}
+void CFWL_ComboBoxImp::ReSetTheme()
+{
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (!pTheme) {
+ pTheme = GetAvailableTheme();
+ m_pProperties->m_pThemeProvider = pTheme;
+ }
+ if (m_pListBox) {
+ if (!m_pListBox->GetThemeProvider() && pTheme->IsValidWidget(m_pListBox)) {
+ m_pListBox->SetThemeProvider(pTheme);
+ }
+ }
+ if (m_pEdit) {
+ if (!m_pEdit->GetThemeProvider() && pTheme->IsValidWidget(m_pEdit)) {
+ m_pEdit->SetThemeProvider(pTheme);
+ }
+ }
+}
+void CFWL_ComboBoxImp::ReSetEditAlignment()
+{
+ _FWL_RETURN_IF_FAIL(m_pEdit);
+ FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes;
+ FX_DWORD dwAdd = 0;
+ switch (dwStylExes & FWL_STYLEEXT_CMB_EditHAlignMask) {
+ case FWL_STYLEEXT_CMB_EditHCenter: {
+ dwAdd |= FWL_STYLEEXT_EDT_HCenter;
+ break;
+ }
+ case FWL_STYLEEXT_CMB_EditHFar: {
+ dwAdd |= FWL_STYLEEXT_EDT_HFar;
+ break;
+ }
+ default: {
+ dwAdd |= FWL_STYLEEXT_EDT_HNear;
+ }
+ }
+ switch (dwStylExes & FWL_STYLEEXT_CMB_EditVAlignMask) {
+ case FWL_STYLEEXT_CMB_EditVCenter: {
+ dwAdd |= FWL_STYLEEXT_EDT_VCenter;
+ break;
+ }
+ case FWL_STYLEEXT_CMB_EditVFar: {
+ dwAdd |= FWL_STYLEEXT_EDT_VFar;
+ break;
+ }
+ default: {
+ dwAdd |= FWL_STYLEEXT_EDT_VNear;
+ }
+ }
+ if (dwStylExes & FWL_STYLEEXT_CMB_EditJustified) {
+ dwAdd |= FWL_STYLEEXT_EDT_Justified;
+ }
+ if (dwStylExes & FWL_STYLEEXT_CMB_EditDistributed) {
+ dwAdd |= FWL_STYLEEXT_EDT_Distributed;
+ }
+ m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask |
+ FWL_STYLEEXT_EDT_HAlignModeMask |
+ FWL_STYLEEXT_EDT_VAlignMask);
+}
+void CFWL_ComboBoxImp::ReSetListItemAlignment()
+{
+ _FWL_RETURN_IF_FAIL(m_pListBox);
+ FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes;
+ FX_DWORD dwAdd = 0;
+ switch (dwStylExes & FWL_STYLEEXT_CMB_ListItemAlignMask) {
+ case FWL_STYLEEXT_CMB_ListItemCenterAlign: {
+ dwAdd |= FWL_STYLEEXT_LTB_CenterAlign;
+ }
+ case FWL_STYLEEXT_CMB_ListItemRightAlign: {
+ dwAdd |= FWL_STYLEEXT_LTB_RightAlign;
+ }
+ default: {
+ dwAdd |= FWL_STYLEEXT_LTB_LeftAlign;
+ }
+ }
+ m_pListBox->ModifyStylesEx(dwAdd, FWL_STYLEEXT_CMB_ListItemAlignMask);
+}
+void CFWL_ComboBoxImp::ProcessSelChanged(FX_BOOL bLButtonUp)
+{
+ IFWL_ComboBoxDP *pDatas = (IFWL_ComboBoxDP*)m_pProperties->m_pDataProvider;
+ m_iCurSel = pDatas->GetItemIndex(m_pInterface, m_pListBox->GetSelItem(0));
+ FX_BOOL bDropDown = IsDropDownStyle();
+ if (bDropDown) {
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP*)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
+ if (hItem) {
+ CFX_WideString wsText;
+ pData->GetItemText(m_pInterface, hItem, wsText);
+ if (m_pEdit) {
+ m_pEdit->SetText(wsText);
+ m_pEdit->Update();
+ ((CFWL_ComboEdit*)((IFWL_TargetData*)m_pEdit)->GetData())->SetSelected();
+ }
+ CFWL_EvtCmbSelChanged ev;
+ ev.bLButtonUp = bLButtonUp;
+ ev.m_pSrcTarget = m_pInterface;
+ ev.iArraySels.Add(m_iCurSel);
+ DispatchEvent(&ev);
+ }
+ } else {
+ Repaint(&m_rtClient);
+ }
+}
+void CFWL_ComboBoxImp::InitProxyForm()
+{
+ _FWL_RETURN_IF_FAIL(!m_pForm);
+ _FWL_RETURN_IF_FAIL(m_pListBox);
+ CFWL_WidgetImpProperties propForm;
+ propForm.m_pOwner = m_pInterface;
+ propForm.m_dwStyles = FWL_WGTSTYLE_Popup;
+ propForm.m_dwStates = FWL_WGTSTATE_Invisible;
+ m_pProxy = FX_NEW CFWL_FormProxyImp(propForm, m_pListBox);
+ m_pForm = IFWL_Form::Create();
+ m_pProxy->SetInterface(m_pForm);
+ ((IFWL_TargetData*)m_pForm)->SetData(m_pProxy);
+ m_pProxy->Initialize();
+ m_pListBox->SetParent((IFWL_Widget*)m_pForm);
+ m_pListProxyDelegate = FX_NEW CFWL_ComboProxyImpDelegate(m_pForm, this);
+ m_pProxy->SetDelegate((IFWL_WidgetDelegate*)m_pListProxyDelegate);
+}
+FWL_ERR CFWL_ComboBoxImp::DisForm_Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_WGTSTATE_Invisible);
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_ComboBoxImpDelegate(this);
+ DisForm_InitComboList();
+ DisForm_InitComboEdit();
+ return FWL_ERR_Succeeded;
+}
+void CFWL_ComboBoxImp::DisForm_InitComboList()
+{
+ if (m_pListBox) {
+ return;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_pParent = (IFWL_Widget*)this->m_pInterface;
+ prop.m_dwStyles = FWL_WGTSTYLE_Border | FWL_WGTSTYLE_VScroll;
+ prop.m_dwStates = FWL_WGTSTATE_Invisible;
+ prop.m_pDataProvider = m_pProperties->m_pDataProvider;
+ prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ CFWL_ComboList *pList = FX_NEW CFWL_ComboList(prop, m_pInterface);
+ m_pListBox = IFWL_ListBox::Create();
+ pList->SetInterface(m_pListBox);
+ ((IFWL_TargetData*)m_pListBox)->SetData(pList);
+ pList->Initialize();
+}
+void CFWL_ComboBoxImp::DisForm_InitComboEdit()
+{
+ if (m_pEdit) {
+ return;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_pParent = (IFWL_Widget*)this->m_pInterface;
+ prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_CMB_DropDown) == 0) {
+ }
+ CFWL_ComboEdit *pEdit = FX_NEW CFWL_ComboEdit(prop, m_pInterface);
+ m_pEdit = IFWL_Edit::Create();
+ pEdit->SetInterface(m_pEdit);
+ ((IFWL_TargetData*)m_pEdit)->SetData(pEdit);
+ pEdit->Initialize();
+ pEdit->SetOuter(m_pInterface);
+}
+void CFWL_ComboBoxImp::DisForm_ShowDropList(FX_BOOL bActivate)
+{
+ FX_BOOL bDropList = DisForm_IsDropListShowed();
+ if(bDropList == bActivate) {
+ return;
+ }
+ if (bActivate) {
+ CFWL_EvtCmbPreDropDown preEvent;
+ preEvent.m_pSrcTarget = m_pInterface;
+ DispatchEvent(&preEvent);
+ CFWL_ComboList* pComboList = (CFWL_ComboList*)(((IFWL_TargetData*)m_pListBox)->GetData());
+ FX_INT32 iItems = pComboList->CountItems();
+ if (iItems < 1) {
+ return;
+ }
+ ReSetListItemAlignment();
+ pComboList->ChangeSelected(m_iCurSel);
+ FX_FLOAT fItemHeight = pComboList->GetItemHeigt();
+ FX_FLOAT fBorder = GetBorderSize();
+ FX_DWORD nWhere = 0;
+ FX_FLOAT fPopupRet = 0.0f;
+ FX_FLOAT fPopupMin = 0.0f;
+ if (iItems > 3) {
+ fPopupMin = fItemHeight * 3 + fBorder * 2;
+ }
+ FX_FLOAT fPopupMax = fItemHeight * iItems + fBorder * 2;
+ CFX_RectF rtList;
+ rtList.left = m_rtClient.left;
+ rtList.width = m_pProperties->m_rtWidget.width;
+ rtList.top = 0;
+ rtList.height = 0;
+ GetPopupPos(fPopupMin, fPopupMax, m_pProperties->m_rtWidget, rtList);
+ m_pListBox->SetWidgetRect(rtList);
+ m_pListBox->Update();
+ } else {
+ SetFocus(TRUE);
+ }
+ m_pListBox->SetStates(FWL_WGTSTATE_Invisible, !bActivate);
+ if (bActivate) {
+ CFWL_EvtCmbPostDropDown postEvent;
+ postEvent.m_pSrcTarget = m_pInterface;
+ DispatchEvent(&postEvent);
+ }
+ CFX_RectF rect;
+ m_pListBox->GetWidgetRect(rect);
+ rect.Inflate(2, 2);
+ Repaint(&rect);
+}
+FX_BOOL CFWL_ComboBoxImp::DisForm_IsDropListShowed()
+{
+ return !(m_pListBox->GetStates() & FWL_WGTSTATE_Invisible);
+}
+FWL_ERR CFWL_ComboBoxImp::DisForm_ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ if (!m_pEdit) {
+ DisForm_InitComboEdit();
+ }
+ FX_BOOL bAddDropDown = dwStylesExAdded & FWL_STYLEEXT_CMB_DropDown;
+ FX_BOOL bDelDropDown = dwStylesExRemoved & FWL_STYLEEXT_CMB_DropDown;
+ dwStylesExRemoved &= ~FWL_STYLEEXT_CMB_DropDown;
+ m_pProperties->m_dwStyleExes |= FWL_STYLEEXT_CMB_DropDown;
+ if (bAddDropDown) {
+ m_pEdit->ModifyStylesEx(0, FWL_STYLEEXT_EDT_ReadOnly);
+ } else if (bDelDropDown) {
+ m_pEdit->ModifyStylesEx(FWL_STYLEEXT_EDT_ReadOnly, 0);
+ }
+ return CFWL_WidgetImp::ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+FWL_ERR CFWL_ComboBoxImp::DisForm_Update()
+{
+ if (m_iLock) {
+ return FWL_ERR_Indefinite;
+ }
+ if (m_pEdit) {
+ ReSetEditAlignment();
+ }
+ ReSetTheme();
+ Layout();
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ComboBoxImp::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rect;
+ rect.Set(0,
+ 0,
+ m_pProperties->m_rtWidget.width - m_rtBtn.width,
+ m_pProperties->m_rtWidget.height);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Edit;
+ }
+ if (m_rtBtn.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ if (DisForm_IsDropListShowed()) {
+ m_pListBox->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ }
+ return FWL_WGTHITTEST_Unknown;
+}
+FWL_ERR CFWL_ComboBoxImp::DisForm_DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ CFX_Matrix mtOrg;
+ mtOrg.Set(1, 0, 0, 1, 0, 0);
+ if (pMatrix) {
+ mtOrg = *pMatrix;
+ }
+ FX_BOOL bListShowed = m_pListBox && DisForm_IsDropListShowed();
+ pGraphics->SaveGraphState();
+ pGraphics->ConcatMatrix(&mtOrg);
+ if (!m_rtBtn.IsEmpty(0.1f)) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = (IFWL_Widget*)this->m_pInterface;
+ param.m_iPart = FWL_PART_CMB_DropDownButton;
+ param.m_dwStates = m_iBtnState;
+ param.m_pGraphics = pGraphics;
+ param.m_rtPart = m_rtBtn;
+ pTheme->DrawBackground(&param);
+ }
+ pGraphics->RestoreGraphState();
+ if (m_pEdit) {
+ CFX_RectF rtEdit;
+ m_pEdit->GetWidgetRect(rtEdit);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top);
+ mt.Concat(mtOrg);
+ m_pEdit->DrawWidget(pGraphics, &mt);
+ }
+ if (bListShowed) {
+ CFX_RectF rtList;
+ m_pListBox->GetWidgetRect(rtList);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtList.left, rtList.top);
+ mt.Concat(mtOrg);
+ m_pListBox->DrawWidget(pGraphics, &mt);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBoxImp::DisForm_GetBBox(CFX_RectF &rect)
+{
+ rect = m_pProperties->m_rtWidget;
+ if (m_pListBox && DisForm_IsDropListShowed()) {
+ CFX_RectF rtList;
+ m_pListBox->GetWidgetRect(rtList);
+ rtList.Offset(rect.left, rect.top);
+ rect.Union(rtList);
+ }
+ return FWL_ERR_Succeeded;
+}
+void CFWL_ComboBoxImp::DisForm_Layout()
+{
+ GetClientRect(m_rtClient);
+ m_rtContent = m_rtClient;
+ FX_FLOAT *pFWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_IF_FAIL(pFWidth);
+ FX_FLOAT borderWidth = 0;
+ {
+ borderWidth = FWL_PART_CMB_Border;
+ }
+ FX_FLOAT fBtn = *pFWidth;
+ if (!(this->GetStylesEx() & FWL_STYLEEXT_CMB_ReadOnly)) {
+ m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top + borderWidth,
+ fBtn - borderWidth, m_rtClient.height - 2 * borderWidth);
+ }
+ CFX_RectF* pUIMargin = (CFX_RectF*)GetThemeCapacity(FWL_WGTCAPACITY_UIMargin);
+ if (pUIMargin) {
+ m_rtContent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, pUIMargin->height);
+ }
+ FX_BOOL bIsDropDown = IsDropDownStyle();
+ if (bIsDropDown && m_pEdit) {
+ CFX_RectF rtEdit;
+ rtEdit.Set(m_rtContent.left,
+ m_rtContent.top, m_rtContent.width - fBtn, m_rtContent.height);
+ m_pEdit->SetWidgetRect(rtEdit);
+ if (m_iCurSel >= 0) {
+ CFX_WideString wsText;
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP *)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, m_iCurSel);
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pListBox)->GetData())->GetItemText(hItem, wsText);
+ m_pEdit->LockUpdate();
+ m_pEdit->SetText(wsText);
+ m_pEdit->UnlockUpdate();
+ }
+ m_pEdit->Update();
+ }
+}
+CFWL_ComboBoxImpDelegate::CFWL_ComboBoxImpDelegate(CFWL_ComboBoxImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_ComboBoxImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_OnProcessMessage(pMessage);
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_BOOL iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch(dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ OnKey((CFWL_MsgKey*)pMessage);
+ break;
+ }
+ default: {
+ iRet = 0;
+ }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+ return iRet;
+}
+FWL_ERR CFWL_ComboBoxImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ FX_DWORD dwFlag = pEvent->GetClassID();
+ if (dwFlag == FWL_EVTHASH_LTB_DrawItem) {
+ CFWL_EvtCmbDrawItem pTemp;
+ pTemp.m_pSrcTarget = m_pOwner->m_pInterface;
+ pTemp.m_pGraphics = ((CFWL_EvtLtbDrawItem *)pEvent)->m_pGraphics;
+ pTemp.m_index = ((CFWL_EvtLtbDrawItem *)pEvent)->m_index;
+ pTemp.m_rtItem = ((CFWL_EvtLtbDrawItem *)pEvent)->m_rect;
+ m_pOwner->DispatchEvent(&pTemp);
+ } else if (dwFlag == FWL_EVTHASH_Scroll) {
+ FX_DWORD dwScrollCode = ((CFWL_EvtScroll*)pEvent)->m_iScrollCode;
+ FX_FLOAT fPos = ((CFWL_EvtScroll*)pEvent)->m_fPos;
+ CFWL_EvtScroll pScrollEv;
+ pScrollEv.m_pSrcTarget = m_pOwner->m_pInterface;
+ pScrollEv.m_iScrollCode = dwScrollCode;
+ pScrollEv.m_fPos = fPos;
+ m_pOwner->DispatchEvent(&pScrollEv);
+ } else if (dwFlag == FWL_EVTHASH_EDT_TextChanged) {
+ CFWL_EvtCmbEditChanged pTemp;
+ pTemp.m_pSrcTarget = m_pOwner->m_pInterface;
+ pTemp.wsInsert = ((CFWL_EvtEdtTextChanged *)pEvent)->wsInsert;
+ pTemp.wsDelete = ((CFWL_EvtEdtTextChanged *)pEvent)->wsDelete;
+ pTemp.nChangeType = ((CFWL_EvtEdtTextChanged *)pEvent)->nChangeType;
+ m_pOwner->DispatchEvent(&pTemp);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBoxImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_ComboBoxImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet )
+{
+ IFWL_Target *pDstTarget = pMsg->m_pDstTarget;
+ IFWL_Target *pSrcTarget = pMsg->m_pSrcTarget;
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if (bDropDown && pSrcTarget != (IFWL_Widget*)m_pOwner->m_pListBox) {
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdit);
+ ((CFWL_ComboEdit*)((IFWL_TargetData*)m_pOwner->m_pEdit)->GetData())->SetSelected();
+ } else {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ if (bDropDown && pDstTarget != (IFWL_Widget*)m_pOwner->m_pListBox) {
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdit);
+ ((CFWL_ComboEdit*)((IFWL_TargetData*)m_pOwner->m_pEdit)->GetData())->FlagFocus(FALSE);
+ ((CFWL_ComboEdit*)((IFWL_TargetData*)m_pOwner->m_pEdit)->GetData())->ClearSelected();
+ } else {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ }
+}
+void CFWL_ComboBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ CFX_RectF& rtBtn = bDropDown ? m_pOwner->m_rtBtn : m_pOwner->m_rtClient;
+ FX_BOOL bClickBtn = rtBtn.Contains(pMsg->m_fx, pMsg->m_fy);
+ if (bClickBtn) {
+ if (bDropDown && m_pOwner->m_pEdit) {
+ m_pOwner->MatchEditText();
+ }
+ m_pOwner->m_bLButtonDown = TRUE;
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Pressed;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ m_pOwner->ShowDropList(TRUE);
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+}
+void CFWL_ComboBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->m_bLButtonDown = FALSE;
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Hovered;
+ } else {
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+void CFWL_ComboBoxImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ FX_INT32 iOldState = m_pOwner->m_iBtnState;
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iBtnState = m_pOwner->m_bLButtonDown ? FWL_PARTSTATE_CMB_Pressed : FWL_PARTSTATE_CMB_Hovered;
+ } else {
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
+ }
+ if ( (iOldState != m_pOwner->m_iBtnState) &&
+ !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == FWL_WGTSTATE_Disabled)) {
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+ }
+}
+void CFWL_ComboBoxImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)
+{
+ if (!m_pOwner->IsDropListShowed() &&
+ !((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == FWL_WGTSTATE_Disabled)) {
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_CMB_Normal;
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+ }
+}
+void CFWL_ComboBoxImpDelegate::OnKey(CFWL_MsgKey *pMsg)
+{
+ FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
+ if (dwKeyCode == FWL_VKEY_Tab) {
+ m_pOwner->DispatchKeyEvent(pMsg);
+ return;
+ }
+ FX_BOOL bSubCtrlKey = pMsg->m_pDstTarget == m_pOwner->m_pInterface;
+ if (bSubCtrlKey) {
+ DoSubCtrlKey(pMsg);
+ }
+}
+void CFWL_ComboBoxImpDelegate::DoSubCtrlKey(CFWL_MsgKey *pMsg)
+{
+ FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
+ FX_BOOL bUp = dwKeyCode == FWL_VKEY_Up;
+ FX_BOOL bDown = dwKeyCode == FWL_VKEY_Down;
+ if (bUp || bDown) {
+ FX_INT32 iCount = ((CFWL_ComboList*)((IFWL_TargetData*)m_pOwner->m_pListBox)->GetData())->CountItems();
+ if (iCount < 1) {
+ return;
+ }
+ FX_BOOL bMatchEqual = FALSE;
+ FX_INT32 iCurSel = m_pOwner->m_iCurSel;
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ if (bDropDown && m_pOwner->m_pEdit) {
+ CFX_WideString wsText;
+ m_pOwner->m_pEdit->GetText(wsText);
+ iCurSel = ((CFWL_ComboList*)((IFWL_TargetData*)m_pOwner->m_pListBox)->GetData())->MatchItem(wsText);
+ if (iCurSel >= 0) {
+ CFX_WideString wsTemp;
+ IFWL_ComboBoxDP *pData = (IFWL_ComboBoxDP *)m_pOwner->m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hItem = pData->GetItem(m_pOwner->m_pInterface, iCurSel);
+ ((CFWL_ComboList*)((IFWL_TargetData*)m_pOwner->m_pListBox)->GetData())->GetItemText(hItem, wsTemp);
+ bMatchEqual = wsText.Equal(wsTemp);
+ }
+ }
+ if (iCurSel < 0) {
+ iCurSel = 0;
+ } else if (!bDropDown || bMatchEqual) {
+ if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) {
+ return;
+ }
+ if (bUp) {
+ iCurSel --;
+ } else {
+ iCurSel ++;
+ }
+ }
+ m_pOwner->m_iCurSel = iCurSel;
+ if (bDropDown && m_pOwner->m_pEdit) {
+ m_pOwner->SynchrEditText(m_pOwner->m_iCurSel);
+ } else {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ return;
+ }
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ if (bDropDown) {
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(pMsg);
+ }
+}
+FX_INT32 CFWL_ComboBoxImpDelegate::DisForm_OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_BOOL backDefault = TRUE;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ backDefault = FALSE;
+ DisForm_OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ backDefault = FALSE;
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch(dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ DisForm_OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ backDefault = FALSE;
+ CFWL_MsgKey *pKey = (CFWL_MsgKey*)pMessage;
+ if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyUp) {
+ break;
+ }
+ if (m_pOwner->DisForm_IsDropListShowed() && pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
+ FX_DWORD dwKeyCode = pKey->m_dwKeyCode;
+ FX_BOOL bListKey = dwKeyCode == FWL_VKEY_Up ||
+ dwKeyCode == FWL_VKEY_Down ||
+ dwKeyCode == FWL_VKEY_Return ||
+ dwKeyCode == FWL_VKEY_Escape;
+ if (bListKey) {
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pListBox->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(pMessage);
+ break;
+ }
+ }
+ DisForm_OnKey((CFWL_MsgKey*)pMessage);
+ break;
+ }
+ default: {
+ }
+ }
+ if (!backDefault) {
+ return 1;
+ }
+ return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+void CFWL_ComboBoxImpDelegate::DisForm_OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ FX_BOOL bDropDown = m_pOwner->DisForm_IsDropListShowed();
+ CFX_RectF& rtBtn = bDropDown ? m_pOwner->m_rtBtn : m_pOwner->m_rtClient;
+ FX_BOOL bClickBtn = rtBtn.Contains(pMsg->m_fx, pMsg->m_fy);
+ if (bClickBtn) {
+ if (m_pOwner->DisForm_IsDropListShowed()) {
+ m_pOwner->DisForm_ShowDropList(FALSE);
+ return;
+ }
+ {
+ if (m_pOwner->m_pEdit) {
+ m_pOwner->MatchEditText();
+ }
+ m_pOwner->DisForm_ShowDropList(TRUE);
+ }
+ }
+}
+void CFWL_ComboBoxImpDelegate::DisForm_OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)
+{
+ IFWL_Target *pDstTarget = pMsg->m_pDstTarget;
+ IFWL_Target *pSrcTarget = pMsg->m_pSrcTarget;
+ FX_BOOL bDropDown = m_pOwner->IsDropDownStyle();
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if ((m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) == 0) {
+ CFWL_MsgSetFocus msg;
+ msg.m_pDstTarget = m_pOwner->m_pEdit;
+ msg.m_pSrcTarget = NULL;
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(&msg);
+ }
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ m_pOwner->DisForm_ShowDropList(FALSE);
+ CFWL_MsgKillFocus msg;
+ msg.m_pDstTarget = NULL;
+ msg.m_pSrcTarget = m_pOwner->m_pEdit;
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(&msg);
+ }
+}
+void CFWL_ComboBoxImpDelegate::DisForm_OnKey(CFWL_MsgKey *pMsg)
+{
+ FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
+ FX_BOOL bUp = dwKeyCode == FWL_VKEY_Up;
+ FX_BOOL bDown = dwKeyCode == FWL_VKEY_Down;
+ if (bUp || bDown) {
+ CFWL_ComboList* pComboList = ((CFWL_ComboList*)((IFWL_TargetData*)(m_pOwner->m_pListBox))->GetData());
+ FX_INT32 iCount = pComboList->CountItems();
+ if (iCount < 1) {
+ return;
+ }
+ FX_BOOL bMatchEqual = FALSE;
+ FX_INT32 iCurSel = m_pOwner->m_iCurSel;
+ if (m_pOwner->m_pEdit) {
+ CFX_WideString wsText;
+ m_pOwner->m_pEdit->GetText(wsText);
+ iCurSel = pComboList->MatchItem(wsText);
+ if (iCurSel >= 0) {
+ CFX_WideString wsTemp;
+ FWL_HLISTITEM item = m_pOwner->m_pListBox->GetSelItem(iCurSel);
+ m_pOwner->m_pListBox->GetItemText(item, wsTemp);
+ bMatchEqual = wsText.Equal(wsTemp);
+ }
+ }
+ if (iCurSel < 0) {
+ iCurSel = 0;
+ } else if (bMatchEqual) {
+ if ((bUp && iCurSel == 0) || (bDown && iCurSel == iCount - 1)) {
+ return;
+ }
+ if (bUp) {
+ iCurSel --;
+ } else {
+ iCurSel ++;
+ }
+ }
+ m_pOwner->m_iCurSel = iCurSel;
+ m_pOwner->SynchrEditText(m_pOwner->m_iCurSel);
+ return;
+ }
+ if (m_pOwner->m_pEdit) {
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(pMsg);
+ }
+}
+CFWL_ComboProxyImpDelegate::CFWL_ComboProxyImpDelegate(IFWL_Form *pForm, CFWL_ComboBoxImp *pComboBox)
+ : m_pForm(pForm)
+ , m_pComboBox(pComboBox)
+ , m_bLButtonDown(FALSE)
+ , m_bLButtonUpSelf(FALSE)
+ , m_fStartPos(0)
+{
+}
+FX_INT32 CFWL_ComboProxyImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ if (dwMsgCode == FWL_MSGHASH_Mouse) {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch(dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ }
+ if (dwMsgCode == FWL_MSGHASH_Deactivate) {
+ OnDeactive((CFWL_MsgDeactivate*)pMessage);
+ }
+ if (dwMsgCode == FWL_MSGHASH_KillFocus || dwMsgCode == FWL_MSGHASH_SetFocus) {
+ OnFocusChanged((CFWL_MsgKillFocus*)pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ }
+ return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+FWL_ERR CFWL_ComboProxyImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ m_pComboBox->DrawStretchHandler(pGraphics, pMatrix);
+ return FWL_ERR_Succeeded;
+}
+void CFWL_ComboProxyImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ IFWL_NoteThread *pThread = m_pForm->GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ CFX_RectF rtWidget;
+ m_pForm->GetWidgetRect(rtWidget);
+ rtWidget.left = rtWidget.top = 0;
+ if (rtWidget.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_bLButtonDown = TRUE;
+ pDriver->SetGrab(m_pForm, TRUE);
+ } else {
+ m_bLButtonDown = FALSE;
+ pDriver->SetGrab(m_pForm, FALSE);
+ m_pComboBox->ShowDropList(FALSE);
+ return;
+ }
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ IFWL_AdapterCursorMgr *pCursorMgr = pNative->GetCursorMgr();
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_pForm->TransformTo(NULL, pMsg->m_fx, pMsg->m_fy);
+ m_fStartPos = pMsg->m_fy;
+}
+void CFWL_ComboProxyImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ m_bLButtonDown = FALSE;
+ IFWL_NoteThread *pThread = m_pForm->GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ pDriver->SetGrab(m_pForm, FALSE);
+ if (m_bLButtonUpSelf) {
+ CFX_RectF rect;
+ m_pForm->GetWidgetRect(rect);
+ rect.left = rect.top = 0;
+ if (!rect.Contains(pMsg->m_fx, pMsg->m_fy) && m_pComboBox->IsDropListShowed()) {
+ m_pComboBox->ShowDropList(FALSE);
+ }
+ } else {
+ m_bLButtonUpSelf = TRUE;
+ }
+}
+void CFWL_ComboProxyImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ IFWL_AdapterCursorMgr *pCursorMgr = pNative->GetCursorMgr();
+ FWL_CURSORTYPE cursorType = FWL_CURSORTYPE_Arrow;
+ if (m_pComboBox->m_rtHandler.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ cursorType = FWL_CURSORTYPE_SizeNS;
+ }
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(cursorType);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!m_bLButtonDown) {
+ return;
+ }
+ m_pForm->TransformTo(NULL, pMsg->m_fx, pMsg->m_fy);
+ FX_FLOAT fChanged = pMsg->m_fy - m_fStartPos;
+ if (m_pComboBox->m_bUpFormHandler) {
+ fChanged = m_fStartPos - pMsg->m_fy;
+ }
+ if (m_pComboBox->m_rtList.height + fChanged < m_pComboBox->m_fItemHeight) {
+ return;
+ }
+ m_pComboBox->m_rtList.height += fChanged;
+ m_pComboBox->m_rtProxy.height += fChanged;
+ if (m_pComboBox->m_bUpFormHandler) {
+ m_pComboBox->m_rtProxy.top -= fChanged;
+ m_pComboBox->m_rtHandler.Set(0,
+ 0,
+ m_pComboBox->m_rtList.width,
+ m_pComboBox->m_fComboFormHandler);
+ } else {
+ m_pComboBox->m_rtHandler.Set(0,
+ m_pComboBox->m_rtList.height,
+ m_pComboBox->m_rtList.width,
+ m_pComboBox->m_fComboFormHandler);
+ }
+ m_pForm->SetWidgetRect(m_pComboBox->m_rtProxy);
+ m_pComboBox->m_pListBox->SetWidgetRect(m_pComboBox->m_rtList);
+ m_pComboBox->m_pListBox->Update();
+ m_fStartPos = pMsg->m_fy;
+}
+void CFWL_ComboProxyImpDelegate::OnDeactive(CFWL_MsgDeactivate *pMsg)
+{
+ m_pComboBox->ShowDropList(FALSE);
+}
+void CFWL_ComboProxyImpDelegate::OnFocusChanged(CFWL_MsgKillFocus *pMsg, FX_BOOL bSet )
+{
+ if (!bSet) {
+ if (pMsg->m_pSetFocus == NULL) {
+ m_pComboBox->ShowDropList(FALSE);
+ }
+ }
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_datetimepickerimp.cpp b/xfa/src/fwl/src/basewidget/fwl_datetimepickerimp.cpp
new file mode 100644
index 0000000000..b3e3b45dae
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_datetimepickerimp.cpp
@@ -0,0 +1,1202 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_panelimp.h"
+#include "../core/include/fwl_formimp.h"
+#include "../core/include/fwl_widgetmgrimp.h"
+#include "include/fwl_formproxyimp.h"
+#include "include/fwl_editimp.h"
+#include "include/fwl_monthcalendarimp.h"
+#include "include/fwl_datetimepickerimp.h"
+#define FWL_DTP_WIDTH 100
+#define FWL_DTP_HEIGHT 20
+IFWL_DateTimePicker* IFWL_DateTimePicker::Create()
+{
+ return new IFWL_DateTimePicker;
+}
+FWL_ERR IFWL_DateTimeForm::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_FormProxyImp(properties, pOuter);
+ ((CFWL_FormProxyImp*)m_pData)->SetInterface(this);
+ return ((CFWL_FormProxyImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_DateTimeCalender::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_DateTimeCalendar(properties, pOuter);
+ ((CFWL_DateTimeCalendar*)m_pData)->SetInterface(this);
+ return ((CFWL_DateTimeCalendar*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_DateTimeEdit::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_DateTimeEdit(properties, pOuter);
+ ((CFWL_DateTimeEdit*)m_pData)->SetInterface(this);
+ return ((CFWL_DateTimeEdit*)m_pData)->Initialize();
+}
+IFWL_DateTimePicker::IFWL_DateTimePicker()
+{
+ m_pData = NULL;
+}
+IFWL_DateTimePicker::~IFWL_DateTimePicker()
+{
+ if (m_pData) {
+ delete (CFWL_DateTimePickerImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_DateTimePicker::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_DateTimePickerImp(pOuter);
+ ((CFWL_DateTimePickerImp*)m_pData)->SetInterface(this);
+ return ((CFWL_DateTimePickerImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_DateTimePicker::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_DateTimePickerImp(properties, pOuter);
+ ((CFWL_DateTimePickerImp*)m_pData)->SetInterface(this);
+ return ((CFWL_DateTimePickerImp*)m_pData)->Initialize();
+}
+FX_INT32 IFWL_DateTimePicker::CountSelRanges()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->GetDataTimeEdit()->CountSelRanges();
+}
+FX_INT32 IFWL_DateTimePicker::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->GetDataTimeEdit()->GetSelRange(nIndex, nStart);
+}
+FWL_ERR IFWL_DateTimePicker::GetCurSel(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->GetCurSel(iYear, iMonth, iDay);
+}
+FWL_ERR IFWL_DateTimePicker::SetCurSel(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->SetCurSel(iYear, iMonth, iDay);
+}
+FWL_ERR IFWL_DateTimePicker::SetEditText(const CFX_WideString &wsText)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->SetEditText(wsText);
+}
+FWL_ERR IFWL_DateTimePicker::GetEditText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount) const
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->GetEditText(wsText, nStart, nCount);
+}
+FX_BOOL IFWL_DateTimePicker::CanUndo()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->CanUndo();
+}
+FX_BOOL IFWL_DateTimePicker::CanRedo()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->CanRedo();
+}
+FX_BOOL IFWL_DateTimePicker::Undo()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->Undo();
+}
+FX_BOOL IFWL_DateTimePicker::Redo()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->Redo();
+}
+FX_BOOL IFWL_DateTimePicker::CanCopy()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->CanCopy();
+}
+FX_BOOL IFWL_DateTimePicker::CanCut()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->CanCut();
+}
+FX_BOOL IFWL_DateTimePicker::CanSelectAll()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->CanSelectAll();
+}
+FX_BOOL IFWL_DateTimePicker::Copy(CFX_WideString &wsCopy)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->Copy(wsCopy);
+}
+FX_BOOL IFWL_DateTimePicker::Cut(CFX_WideString &wsCut)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->Cut(wsCut);
+}
+FX_BOOL IFWL_DateTimePicker::Paste(const CFX_WideString &wsPaste)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->Paste(wsPaste);
+}
+FX_BOOL IFWL_DateTimePicker::SelectAll()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->SelectAll();
+}
+FX_BOOL IFWL_DateTimePicker::Delete()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->Delete();
+}
+FX_BOOL IFWL_DateTimePicker::DeSelect()
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->DeSelect();
+}
+FWL_ERR IFWL_DateTimePicker::GetBBox(CFX_RectF &rect)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->GetBBox(rect);
+}
+FWL_ERR IFWL_DateTimePicker::SetEditLimit(FX_INT32 nLimit)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->SetEditLimit(nLimit);
+}
+FWL_ERR IFWL_DateTimePicker::ModifyEditStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ return ((CFWL_DateTimePickerImp*)m_pData)->ModifyEditStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+CFWL_DateTimeEdit::CFWL_DateTimeEdit(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+ : CFWL_EditImp(properties, pOuter)
+{
+}
+FWL_ERR CFWL_DateTimeEdit::Initialize()
+{
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_DateTimeEditDelegate(this);
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_EditImp::Initialize(), FWL_ERR_Indefinite);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimeEdit::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_DateTimeEditDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_EditImp::Finalize();
+}
+CFWL_DateTimeEditDelegate::CFWL_DateTimeEditDelegate(CFWL_DateTimeEdit *pOwner)
+ : CFWL_EditImpDelegate(pOwner)
+ , m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_DateTimeEditDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_OnProcessMessage(pMessage);
+ }
+ FX_DWORD dwHashCode = pMessage->GetClassID();
+ if (dwHashCode == FWL_MSGHASH_SetFocus || dwHashCode == FWL_MSGHASH_KillFocus) {
+ IFWL_Widget *pOuter = m_pOwner->GetOuter();
+ IFWL_WidgetDelegate *pDelegate = pOuter->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(pMessage);
+ }
+ return 1;
+}
+FX_INT32 CFWL_DateTimeEditDelegate::DisForm_OnProcessMessage(CFWL_Message *pMessage)
+{
+ FX_DWORD dwHashCode = pMessage->GetClassID();
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ if (dwHashCode == FWL_MSGHASH_Mouse) {
+ CFWL_MsgMouse *pMouse = (CFWL_MsgMouse*)pMessage;
+ if (pMouse->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown || pMouse->m_dwCmd == FWL_MSGMOUSECMD_RButtonDown) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ }
+ CFWL_DateTimePickerImp *pDateTime = (CFWL_DateTimePickerImp*)((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData();
+ if (pDateTime->IsMonthCalendarShowed()) {
+ CFX_RectF rtInvalidate;
+ pDateTime->GetWidgetRect(rtInvalidate);
+ pDateTime->ShowMonthCalendar(FALSE);
+ rtInvalidate.Offset(-rtInvalidate.left, -rtInvalidate.top);
+ pDateTime->Repaint(&rtInvalidate);
+ }
+ }
+ } else if (dwHashCode == FWL_MSGHASH_Key) {
+ return CFWL_EditImpDelegate::OnProcessMessage(pMessage);
+ }
+ }
+ return CFWL_EditImpDelegate::OnProcessMessage(pMessage);
+}
+CFWL_DateTimeCalendar::CFWL_DateTimeCalendar(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+ : CFWL_MonthCalendarImp(properties, pOuter)
+{
+}
+FWL_ERR CFWL_DateTimeCalendar::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_MonthCalendarImp::Initialize(), FWL_ERR_Indefinite);
+ if (m_pDelegate) {
+ delete (CFWL_MonthCalendarImpDelegate*)m_pDelegate;
+ }
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_DateTimeCalendarDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimeCalendar::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_DateTimeCalendarDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_MonthCalendarImp::Finalize();
+}
+CFWL_DateTimeCalendarDelegate::CFWL_DateTimeCalendarDelegate(CFWL_DateTimeCalendar *pOwner)
+ : CFWL_MonthCalendarImpDelegate(pOwner)
+ , m_pOwner(pOwner)
+{
+ m_bFlag = FALSE;
+}
+FX_INT32 CFWL_DateTimeCalendarDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ FX_DWORD dwCode = pMessage->GetClassID();
+ if (dwCode == FWL_MSGHASH_SetFocus || dwCode == FWL_MSGHASH_KillFocus) {
+ IFWL_Widget *pOuter = m_pOwner->GetOuter();
+ IFWL_WidgetDelegate *pDelegate = pOuter->SetDelegate(NULL);
+ return pDelegate->OnProcessMessage(pMessage);
+ } else if (dwCode == FWL_MSGHASH_Mouse) {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) {
+ OnLButtonDownEx(pMsg);
+ return 1;
+ } else if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonUp) {
+ OnLButtonUpEx(pMsg);
+ return 1;
+ }
+ }
+ return CFWL_MonthCalendarImpDelegate::OnProcessMessage(pMessage);
+}
+void CFWL_DateTimeCalendarDelegate::OnLButtonDownEx(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = FWL_PARTSTATE_MCD_Pressed;
+ m_pOwner->PrevMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates |= FWL_PARTSTATE_MCD_Pressed;
+ m_pOwner->NextMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday ) == 0) {
+ m_pOwner->JumpToToday();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ } else {
+ IFWL_DateTimePicker *pIPicker = (IFWL_DateTimePicker *)m_pOwner->m_pOuter;
+ CFWL_DateTimePickerImp *pPicker = (CFWL_DateTimePickerImp *)((IFWL_TargetData *)pIPicker)->GetData();
+ if (pPicker->IsMonthCalendarShowed()) {
+ m_bFlag = 1;
+ }
+ }
+}
+void CFWL_DateTimeCalendarDelegate::OnLButtonUpEx(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_OnLButtonUpEx(pMsg);
+ }
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtLBtn);
+ return;
+ }
+ if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtRBtn);
+ return;
+ }
+ if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ FX_INT32 iOldSel = 0;
+ if (m_pOwner->m_arrSelDays.GetSize() > 0) {
+ iOldSel = m_pOwner->m_arrSelDays[0];
+ }
+ FX_INT32 iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ CFX_RectF rt;
+ IFWL_DateTimePicker *pIPicker = (IFWL_DateTimePicker *)m_pOwner->m_pOuter;
+ CFWL_DateTimePickerImp *pPicker = (CFWL_DateTimePickerImp *)((IFWL_TargetData *)pIPicker)->GetData();
+ pPicker->m_pForm->GetWidgetRect(rt);
+ rt.Set(0, 0, rt.width, rt.height);
+ if (iCurSel > 0) {
+ LPDATEINFO lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iCurSel - 1);
+ CFX_RectF rtInvalidate(lpDatesInfo->rect);
+ if (iOldSel > 0 && iOldSel <= m_pOwner->m_arrDates.GetSize()) {
+ lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iOldSel - 1);
+ rtInvalidate.Union(lpDatesInfo->rect);
+ }
+ m_pOwner->AddSelDay(iCurSel);
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pOuter);
+ pPicker->ProcessSelChanged(m_pOwner->m_iCurYear, m_pOwner->m_iCurMonth, iCurSel);
+ pPicker->ShowMonthCalendar(FALSE);
+ } else if (m_bFlag && (!rt.Contains(pMsg->m_fx, pMsg->m_fy))) {
+ IFWL_DateTimePicker *pIPicker = (IFWL_DateTimePicker *)m_pOwner->m_pOuter;
+ CFWL_DateTimePickerImp *pPicker = (CFWL_DateTimePickerImp *)((IFWL_TargetData *)pIPicker)->GetData();
+ pPicker->ShowMonthCalendar(FALSE);
+ }
+ m_bFlag = 0;
+}
+void CFWL_DateTimeCalendarDelegate::OnMouseMoveEx(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, 0, 0);
+ if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ FX_INT32 iHover = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ bRepaint = m_pOwner->m_iHovered != iHover;
+ if (bRepaint) {
+ if (m_pOwner->m_iHovered > 0) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ if (iHover > 0) {
+ CFX_RectF rtDay;
+ m_pOwner->GetDayRect(iHover, rtDay);
+ if (rtInvalidate.IsEmpty()) {
+ rtInvalidate = rtDay;
+ } else {
+ rtInvalidate.Union(rtDay);
+ }
+ }
+ }
+ m_pOwner->m_iHovered = iHover;
+ CFWL_Event_DtpHoverChanged ev;
+ ev.hoverday = iHover;
+ m_pOwner->DispatchEvent(&ev);
+ } else {
+ bRepaint = m_pOwner->m_iHovered > 0;
+ if (bRepaint) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ m_pOwner->m_iHovered = -1;
+ }
+ if (bRepaint && !rtInvalidate.IsEmpty()) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+FX_INT32 CFWL_DateTimeCalendarDelegate::DisForm_OnProcessMessage(CFWL_Message *pMessage)
+{
+ if (pMessage->GetClassID() == FWL_MSGHASH_Mouse) {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_LButtonUp) {
+ DisForm_OnLButtonUpEx(pMsg);
+ return 1;
+ }
+ }
+ return CFWL_MonthCalendarImpDelegate::OnProcessMessage(pMessage);
+}
+void CFWL_DateTimeCalendarDelegate::DisForm_OnLButtonUpEx(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = 0;
+ m_pOwner->Repaint(&(m_pOwner->m_rtLBtn));
+ return;
+ }
+ if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates = 0;
+ m_pOwner->Repaint(&(m_pOwner->m_rtRBtn));
+ return;
+ }
+ if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ FX_INT32 iOldSel = 0;
+ if (m_pOwner->m_arrSelDays.GetSize() > 0) {
+ iOldSel = m_pOwner->m_arrSelDays[0];
+ }
+ FX_INT32 iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (iCurSel > 0) {
+ LPDATEINFO lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iCurSel - 1);
+ CFX_RectF rtInvalidate(lpDatesInfo->rect);
+ if (iOldSel > 0 && iOldSel <= m_pOwner->m_arrDates.GetSize()) {
+ lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iOldSel - 1);
+ rtInvalidate.Union(lpDatesInfo->rect);
+ }
+ m_pOwner->AddSelDay(iCurSel);
+ CFWL_DateTimePickerImp *pDateTime = (CFWL_DateTimePickerImp*)((IFWL_TargetData*)m_pOwner->m_pOuter)->GetData();
+ pDateTime->ProcessSelChanged(m_pOwner->m_iCurYear, m_pOwner->m_iCurMonth, iCurSel);
+ pDateTime->ShowMonthCalendar(FALSE);
+ }
+}
+CFWL_DateTimePickerImp::CFWL_DateTimePickerImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_bLBtnDown(FALSE)
+ , m_iBtnState(1)
+ , m_iYear(-1)
+ , m_iMonth(-1)
+ , m_iDay(-1)
+ , m_pEdit(NULL)
+ , m_pMonthCal(NULL)
+ , m_pForm(FALSE)
+{
+ m_rtBtn.Set(0, 0, 0, 0);
+}
+CFWL_DateTimePickerImp::CFWL_DateTimePickerImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_bLBtnDown(FALSE)
+ , m_iBtnState(1)
+ , m_iYear(-1)
+ , m_iMonth(-1)
+ , m_iDay(-1)
+ , m_pEdit(NULL)
+ , m_pMonthCal(NULL)
+ , m_pForm(FALSE)
+{
+ m_rtBtn.Set(0, 0, 0, 0);
+}
+CFWL_DateTimePickerImp::~CFWL_DateTimePickerImp()
+{
+ if (m_pEdit) {
+ m_pEdit->Release();
+ m_pEdit = NULL;
+ }
+ if (m_pMonthCal) {
+ m_pMonthCal->Release();
+ m_pMonthCal = NULL;
+ }
+ if (m_pForm) {
+ m_pForm->Release();
+ m_pForm = NULL;
+ }
+}
+FWL_ERR CFWL_DateTimePickerImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_DateTimePicker;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_DateTimePickerImp::GetClassID() const
+{
+ return FWL_CLASSHASH_DateTimePicker;
+}
+FWL_ERR CFWL_DateTimePickerImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_DateTimePickerImpDelegate(this);
+ m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat;
+ CFWL_WidgetImpProperties propMonth;
+ propMonth.m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border;
+ propMonth.m_dwStates = FWL_WGTSTATE_Invisible;
+ propMonth.m_pDataProvider = &m_MonthCalendarDP;
+ propMonth.m_pParent = m_pInterface;
+ propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pMonthCal = new IFWL_DateTimeCalender();
+ m_pMonthCal->Initialize(propMonth, m_pInterface);
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtMonthCal);
+ CFWL_WidgetImpProperties propEdit;
+ propEdit.m_pParent = m_pInterface;
+ propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pEdit = new IFWL_DateTimeEdit();
+ m_pEdit->Initialize(propEdit, m_pInterface);
+ RegisterEventTarget(m_pMonthCal);
+ RegisterEventTarget(m_pEdit);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::Finalize()
+{
+ if (m_pEdit) {
+ m_pEdit->Finalize();
+ }
+ if (m_pMonthCal) {
+ m_pMonthCal->Finalize();
+ }
+ if (m_pForm) {
+ m_pForm->Finalize();
+ }
+ UnregisterEventTarget();
+ if ( m_pDelegate) {
+ delete (CFWL_DateTimePickerImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_DateTimePickerImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_GetWidgetRect(rect, bAutoSize);
+ }
+ if (bAutoSize) {
+ rect.Set(0, 0, FWL_DTP_WIDTH, FWL_DTP_HEIGHT);
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::Update()
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_Update();
+ }
+ if (m_iLock) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider);
+ GetClientRect(m_rtClient);
+ FX_FLOAT *pFWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_VALUE_IF_FAIL(pFWidth, FWL_ERR_Indefinite);
+ FX_FLOAT fBtn = *pFWidth;
+ m_rtBtn.Set(m_rtClient.right() - fBtn, m_rtClient.top, fBtn - 1, m_rtClient.height - 1);
+ CFX_RectF rtEdit;
+ rtEdit.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width - fBtn, m_rtClient.height);
+ m_pEdit->SetWidgetRect(rtEdit);
+ ReSetEditAlignment();
+ m_pEdit->Update();
+ if (!(m_pMonthCal->GetThemeProvider())) {
+ m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider);
+ }
+ if (m_pProperties->m_pDataProvider) {
+ IFWL_DateTimePickerDP *pData = (IFWL_DateTimePickerDP*)m_pProperties->m_pDataProvider;
+ pData->GetToday(m_pInterface,
+ m_MonthCalendarDP.m_iCurYear,
+ m_MonthCalendarDP.m_iCurMonth,
+ m_MonthCalendarDP.m_iCurDay);
+ }
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ CFX_RectF rtPopUp;
+ rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + FWL_DTP_HEIGHT, rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtPopUp);
+ m_pMonthCal->Update();
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_DateTimePickerImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_HitTest(fx, fy);
+ }
+ if (m_rtClient.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rect;
+ m_pMonthCal->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ }
+ return FWL_WGTHITTEST_Unknown;
+}
+FWL_ERR CFWL_DateTimePickerImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_DTP_Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_DTP_Edge, pTheme, pMatrix);
+ }
+ if (!m_rtBtn.IsEmpty()) {
+ DrawDropDownButton(pGraphics, pTheme, pMatrix);
+ }
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_DrawWidget(pGraphics, pMatrix);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::SetThemeProvider(IFWL_ThemeProvider *pTP)
+{
+ m_pProperties->m_pThemeProvider = pTP;
+ m_pMonthCal->SetThemeProvider(pTP);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::GetCurSel(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay)
+{
+ iYear = m_iYear;
+ iMonth = m_iMonth;
+ iDay = m_iDay;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::SetCurSel(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(iYear > 0 && iYear < 3000, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(iMonth > 0 && iMonth < 13, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(iDay > 0 && iDay < 32, FWL_ERR_Indefinite);
+ m_iYear = iYear;
+ m_iMonth = iMonth;
+ m_iDay = iDay;
+ m_pMonthCal->SetSelect(iYear, iMonth, iDay);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::SetEditText(const CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdit, FWL_ERR_Indefinite);
+ FX_INT32 iRet = m_pEdit->SetText(wsText);
+ Repaint(&m_rtClient);
+ CFWL_Event_DtpEditChanged ev;
+ ev.m_wsText = wsText;
+ DispatchEvent(&ev);
+ return iRet;
+}
+FWL_ERR CFWL_DateTimePickerImp::GetEditText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount) const
+{
+ if (m_pEdit) {
+ return m_pEdit->GetText(wsText, nStart, nCount);
+ }
+ return FWL_ERR_Indefinite;
+}
+FX_BOOL CFWL_DateTimePickerImp::CanUndo()
+{
+ return m_pEdit->CanUndo();
+}
+FX_BOOL CFWL_DateTimePickerImp::CanRedo()
+{
+ return m_pEdit->CanRedo();
+}
+FX_BOOL CFWL_DateTimePickerImp::Undo()
+{
+ return m_pEdit->Undo();
+}
+FX_BOOL CFWL_DateTimePickerImp::Redo()
+{
+ return m_pEdit->Redo();
+}
+FX_BOOL CFWL_DateTimePickerImp::CanCopy()
+{
+ FX_INT32 nCount = m_pEdit->CountSelRanges();
+ return nCount > 0;
+}
+FX_BOOL CFWL_DateTimePickerImp::CanCut()
+{
+ if (m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
+ return FALSE;
+ }
+ FX_INT32 nCount = m_pEdit->CountSelRanges();
+ return nCount > 0;
+}
+FX_BOOL CFWL_DateTimePickerImp::CanSelectAll()
+{
+ return m_pEdit->GetTextLength() > 0;
+}
+FX_BOOL CFWL_DateTimePickerImp::Copy(CFX_WideString &wsCopy)
+{
+ return m_pEdit->Copy(wsCopy);
+}
+FX_BOOL CFWL_DateTimePickerImp::Cut(CFX_WideString &wsCut)
+{
+ return m_pEdit->Cut(wsCut);
+}
+FX_BOOL CFWL_DateTimePickerImp::Paste(const CFX_WideString &wsPaste)
+{
+ return m_pEdit->Paste(wsPaste);
+}
+FX_BOOL CFWL_DateTimePickerImp::SelectAll()
+{
+ return (m_pEdit->AddSelRange(0) == FWL_ERR_Succeeded) ? TRUE : FALSE;
+}
+FX_BOOL CFWL_DateTimePickerImp::Delete()
+{
+ return (m_pEdit->ClearText() == FWL_ERR_Succeeded) ? TRUE : FALSE;
+}
+FX_BOOL CFWL_DateTimePickerImp::DeSelect()
+{
+ return (m_pEdit->ClearSelections() == FWL_ERR_Succeeded) ? TRUE : FALSE;
+}
+FWL_ERR CFWL_DateTimePickerImp::GetBBox(CFX_RectF &rect)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_GetBBox(rect);
+ }
+ rect = m_pProperties->m_rtWidget;
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top);
+ rect.Union(rtMonth);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::SetEditLimit(FX_INT32 nLimit)
+{
+ return m_pEdit->SetLimit(nLimit);
+}
+FWL_ERR CFWL_DateTimePickerImp::ModifyEditStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ return m_pEdit->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+void CFWL_DateTimePickerImp::DrawDropDownButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_Spin) == FWL_STYLEEXT_DTP_Spin) {
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert;
+ prop.m_pParent = m_pInterface;
+ prop.m_rtWidget = m_rtBtn;
+ IFWL_SpinButton *pSpin = IFWL_SpinButton::Create();
+ pSpin->Initialize(prop, m_pInterface);
+ } else {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_DTP_DropDownButton;
+ param.m_dwStates = m_iBtnState;
+ param.m_pGraphics = pGraphics;
+ param.m_rtPart = m_rtBtn;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&param);
+ }
+}
+void CFWL_DateTimePickerImp::FormatDateString(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay, CFX_WideString &wsText)
+{
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_ShortDateFormat) == FWL_STYLEEXT_DTP_ShortDateFormat) {
+ wsText.Format(FX_LPCWSTR(L"%d-%d-%d"), iYear, iMonth, iDay);
+ } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_LongDateFormat) == FWL_STYLEEXT_DTP_LongDateFormat) {
+ wsText.Format(FX_LPCWSTR(L"%d Year %d Month %d Day"), iYear, iMonth, iDay);
+ } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_TimeFormat) == FWL_STYLEEXT_DTP_TimeFormat) {
+ }
+}
+void CFWL_DateTimePickerImp::ShowMonthCalendar(FX_BOOL bActivate)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_ShowMonthCalendar(bActivate);
+ }
+ if(IsMonthCalendarShowed() == bActivate) {
+ return;
+ }
+ if (!m_pForm) {
+ InitProxyForm();
+ }
+ if (bActivate) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ CFX_RectF rtAnchor;
+ rtAnchor.Set(0,
+ 0,
+ m_pProperties->m_rtWidget.width,
+ m_pProperties->m_rtWidget.height);
+ GetPopupPos(0, rtMonth.height, rtAnchor, rtMonth);
+ m_pForm->SetWidgetRect(rtMonth);
+ rtMonth.left = rtMonth.top = 0;
+ m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate);
+ m_pMonthCal->SetWidgetRect(rtMonth);
+ m_pMonthCal->Update();
+ m_pForm->DoModal();
+ } else {
+ m_pForm->EndDoModal();
+ }
+}
+FX_BOOL CFWL_DateTimePickerImp::IsMonthCalendarShowed()
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_IsMonthCalendarShowed();
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(m_pForm, FALSE);
+ return !(m_pForm->GetStates() & FWL_WGTSTATE_Invisible);
+}
+void CFWL_DateTimePickerImp::ReSetEditAlignment()
+{
+ _FWL_RETURN_IF_FAIL(m_pEdit);
+ FX_DWORD dwStylExes = m_pProperties->m_dwStyleExes;
+ FX_DWORD dwAdd = 0;
+ switch (dwStylExes & FWL_STYLEEXT_DTP_EditHAlignMask) {
+ case FWL_STYLEEXT_DTP_EditHCenter: {
+ dwAdd |= FWL_STYLEEXT_EDT_HCenter;
+ break;
+ }
+ case FWL_STYLEEXT_DTP_EditHFar: {
+ dwAdd |= FWL_STYLEEXT_EDT_HFar;
+ break;
+ }
+ default: {
+ dwAdd |= FWL_STYLEEXT_EDT_HNear;
+ }
+ }
+ switch (dwStylExes & FWL_STYLEEXT_DTP_EditVAlignMask) {
+ case FWL_STYLEEXT_DTP_EditVCenter: {
+ dwAdd |= FWL_STYLEEXT_EDT_VCenter;
+ break;
+ }
+ case FWL_STYLEEXT_DTP_EditVFar: {
+ dwAdd |= FWL_STYLEEXT_EDT_VFar;
+ break;
+ }
+ default: {
+ dwAdd |= FWL_STYLEEXT_EDT_VNear;
+ }
+ }
+ if (dwStylExes & FWL_STYLEEXT_DTP_EditJustified) {
+ dwAdd |= FWL_STYLEEXT_EDT_Justified;
+ }
+ if (dwStylExes & FWL_STYLEEXT_DTP_EditDistributed) {
+ dwAdd |= FWL_STYLEEXT_EDT_Distributed;
+ }
+ m_pEdit->ModifyStylesEx(dwAdd, FWL_STYLEEXT_EDT_HAlignMask |
+ FWL_STYLEEXT_EDT_HAlignModeMask |
+ FWL_STYLEEXT_EDT_VAlignMask);
+}
+void CFWL_DateTimePickerImp::ProcessSelChanged(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ m_iYear = iYear;
+ m_iMonth = iMonth;
+ m_iDay = iDay;
+ CFX_WideString wsText;
+ FormatDateString(m_iYear, m_iMonth, m_iDay, wsText);
+ m_pEdit->SetText(wsText);
+ m_pEdit->Update();
+ Repaint(&m_rtClient);
+ CFWL_Event_DtpSelectChanged ev;
+ ev.m_pSrcTarget = m_pInterface;
+ ev.iYear = m_iYear;
+ ev.iMonth = m_iMonth;
+ ev.iDay = m_iDay;
+ DispatchEvent(&ev);
+}
+void CFWL_DateTimePickerImp::InitProxyForm()
+{
+ _FWL_RETURN_IF_FAIL(!m_pForm);
+ _FWL_RETURN_IF_FAIL(m_pMonthCal);
+ CFWL_WidgetImpProperties propForm;
+ propForm.m_dwStyles = FWL_WGTSTYLE_Popup;
+ propForm.m_dwStates = FWL_WGTSTATE_Invisible;
+ propForm.m_pOwner = m_pInterface;
+ m_pForm = new IFWL_DateTimeForm();
+ m_pForm->Initialize(propForm, m_pMonthCal);
+ m_pMonthCal->SetParent((IFWL_Widget*)m_pForm);
+}
+IFWL_DateTimeEdit* CFWL_DateTimePickerImp::GetDataTimeEdit()
+{
+ return m_pEdit;
+}
+FWL_ERR CFWL_DateTimePickerImp::DisForm_Initialize()
+{
+ m_pProperties->m_dwStyleExes = FWL_STYLEEXT_DTP_ShortDateFormat;
+ DisForm_InitDateTimeCalendar();
+ DisForm_InitDateTimeEdit();
+ RegisterEventTarget(m_pMonthCal);
+ RegisterEventTarget(m_pEdit);
+ return FWL_ERR_Succeeded;
+}
+void CFWL_DateTimePickerImp::DisForm_InitDateTimeCalendar()
+{
+ if (m_pMonthCal) {
+ return;
+ }
+ CFWL_WidgetImpProperties propMonth;
+ propMonth.m_dwStyles = FWL_WGTSTYLE_Popup | FWL_WGTSTYLE_Border | FWL_WGTSTYLE_EdgeSunken;
+ propMonth.m_dwStates = FWL_WGTSTATE_Invisible;
+ propMonth.m_pParent = (IFWL_Widget*)this;
+ propMonth.m_pDataProvider = &m_MonthCalendarDP;
+ propMonth.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pMonthCal = new IFWL_DateTimeCalender();
+ m_pMonthCal->Initialize(propMonth, m_pInterface);
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ rtMonthCal.Set(0, 0, rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtMonthCal);
+}
+void CFWL_DateTimePickerImp::DisForm_InitDateTimeEdit()
+{
+ if (m_pEdit) {
+ return;
+ }
+ CFWL_WidgetImpProperties propEdit;
+ propEdit.m_pParent = (IFWL_Widget*)this;
+ propEdit.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ m_pEdit = new IFWL_DateTimeEdit();
+ m_pEdit->Initialize(propEdit, m_pInterface);
+}
+FX_BOOL CFWL_DateTimePickerImp::DisForm_IsMonthCalendarShowed()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pMonthCal, FALSE);
+ return !(m_pMonthCal->GetStates() & FWL_WGTSTATE_Invisible);
+}
+void CFWL_DateTimePickerImp::DisForm_ShowMonthCalendar(FX_BOOL bActivate)
+{
+ FX_BOOL bShowed = IsMonthCalendarShowed();
+ if(bShowed == bActivate) {
+ return;
+ }
+ if (bActivate) {
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ FX_DWORD dwPos = 0;
+ FX_FLOAT fPopupHeight = 0.0f;
+ FX_FLOAT fPopupMin = rtMonthCal.height;
+ FX_FLOAT fPopupMax = rtMonthCal.height;
+ CFX_RectF rtAnchor(m_pProperties->m_rtWidget);
+ rtAnchor.width = rtMonthCal.width;
+ rtMonthCal.left = m_rtClient.left;
+ rtMonthCal.top = rtAnchor.Height();
+ GetPopupPos(fPopupMin, fPopupMax, rtAnchor, rtMonthCal);
+ m_pMonthCal->SetWidgetRect(rtMonthCal);
+ if (m_iYear > 0 && m_iMonth > 0 && m_iDay > 0) {
+ m_pMonthCal->SetSelect(m_iYear, m_iMonth, m_iDay);
+ }
+ m_pMonthCal->Update();
+ }
+ m_pMonthCal->SetStates(FWL_WGTSTATE_Invisible, !bActivate);
+ if (bActivate) {
+ CFWL_MsgSetFocus msg;
+ msg.m_pDstTarget = m_pMonthCal;
+ msg.m_pSrcTarget = m_pEdit;
+ IFWL_WidgetDelegate *pDelegate = m_pEdit->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(&msg);
+ }
+ CFX_RectF rtInvalidate, rtCal;
+ rtInvalidate.Set(0,
+ 0,
+ m_pProperties->m_rtWidget.width,
+ m_pProperties->m_rtWidget.height);
+ m_pMonthCal->GetWidgetRect(rtCal);
+ rtInvalidate.Union(rtCal);
+ rtInvalidate.Inflate(2, 2);
+ Repaint(&rtInvalidate);
+}
+FX_DWORD CFWL_DateTimePickerImp::DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rect;
+ rect.Set(0, 0, m_pProperties->m_rtWidget.width, m_pProperties->m_rtWidget.height);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Edit;
+ }
+ if (DisForm_IsNeedShowButton()) {
+ rect.width += m_fBtn;
+ }
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ if (IsMonthCalendarShowed()) {
+ m_pMonthCal->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ }
+ return FWL_WGTHITTEST_Unknown;
+}
+FX_BOOL CFWL_DateTimePickerImp::DisForm_IsNeedShowButton()
+{
+ FX_BOOL bFocus = m_pProperties->m_dwStates & FWL_WGTSTATE_Focused ||
+ m_pMonthCal->GetStates() & FWL_WGTSTATE_Focused ||
+ m_pEdit->GetStates() & FWL_WGTSTATE_Focused;
+ return bFocus ;
+}
+FWL_ERR CFWL_DateTimePickerImp::DisForm_Update()
+{
+ if (m_iLock) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ m_pEdit->SetThemeProvider(m_pProperties->m_pThemeProvider);
+ GetClientRect(m_rtClient);
+ m_pEdit->SetWidgetRect(m_rtClient);
+ ReSetEditAlignment();
+ m_pEdit->Update();
+ if (m_pMonthCal->GetThemeProvider() == NULL) {
+ m_pMonthCal->SetThemeProvider(m_pProperties->m_pThemeProvider);
+ }
+ if (m_pProperties->m_pDataProvider) {
+ IFWL_DateTimePickerDP *pData = (IFWL_DateTimePickerDP*)m_pProperties->m_pDataProvider;
+ pData->GetToday((IFWL_Widget*)this,
+ m_MonthCalendarDP.m_iCurYear,
+ m_MonthCalendarDP.m_iCurMonth,
+ m_MonthCalendarDP.m_iCurDay);
+ }
+ FX_FLOAT *pWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_VALUE_IF_FAIL(pWidth, 0);
+ m_fBtn = *pWidth;
+ CFX_RectF rtMonthCal;
+ m_pMonthCal->GetWidgetRect(rtMonthCal, TRUE);
+ CFX_RectF rtPopUp;
+ rtPopUp.Set(rtMonthCal.left, rtMonthCal.top + FWL_DTP_HEIGHT, rtMonthCal.width, rtMonthCal.height);
+ m_pMonthCal->SetWidgetRect(rtPopUp);
+ m_pMonthCal->Update();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::DisForm_GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize)
+{
+ rect = m_pProperties->m_rtWidget;
+ if (DisForm_IsNeedShowButton()) {
+ rect.width += m_fBtn;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::DisForm_GetBBox(CFX_RectF &rect)
+{
+ rect = m_pProperties->m_rtWidget;
+ if (DisForm_IsNeedShowButton()) {
+ rect.width += m_fBtn;
+ }
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ rtMonth.Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top);
+ rect.Union(rtMonth);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePickerImp::DisForm_DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ if (m_pEdit) {
+ CFX_RectF rtEdit;
+ m_pEdit->GetWidgetRect(rtEdit);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtEdit.left, rtEdit.top);
+ if (pMatrix) {
+ mt.Concat(*pMatrix);
+ }
+ m_pEdit->DrawWidget(pGraphics, &mt);
+ }
+ if (IsMonthCalendarShowed()) {
+ CFX_RectF rtMonth;
+ m_pMonthCal->GetWidgetRect(rtMonth);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtMonth.left, rtMonth.top);
+ if (pMatrix) {
+ mt.Concat(*pMatrix);
+ }
+ m_pMonthCal->DrawWidget(pGraphics, &mt);
+ }
+ return FWL_ERR_Succeeded;
+}
+CFWL_DateTimePickerImpDelegate::CFWL_DateTimePickerImpDelegate(CFWL_DateTimePickerImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_DateTimePickerImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_INT32 iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMouse = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMouse->m_dwCmd;
+ switch(dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMouse);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMouse);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMouse);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave(pMouse);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ default: {
+ iRet = 0;
+ }
+ }
+ if(dwMsgCode == FWL_MSGHASH_Key && m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
+ return pDelegate->OnProcessMessage(pMessage);
+ }
+ return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+FWL_ERR CFWL_DateTimePickerImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_DateTimePickerImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)
+{
+ _FWL_RETURN_IF_FAIL(pMsg);
+ if (m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ return DisForm_OnFocusChanged(pMsg, bSet);
+ }
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ if(pMsg->m_pSrcTarget == (IFWL_Widget*)m_pOwner->m_pMonthCal && m_pOwner->IsMonthCalendarShowed()) {
+ m_pOwner->ShowMonthCalendar(FALSE);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_DateTimePickerImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(pMsg);
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->IsMonthCalendarShowed()) {
+ m_pOwner->ShowMonthCalendar(FALSE);
+ CFWL_Event_DtpCloseUp ev;
+ m_pOwner->DispatchEvent(&ev);
+ } else {
+ if (!(m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_DTP_TimeFormat)) {
+ m_pOwner->ShowMonthCalendar(TRUE);
+ CFWL_Event_DtpDropDown ev;
+ m_pOwner->DispatchEvent(&ev);
+ } else {
+ }
+ m_pOwner->m_bLBtnDown = TRUE;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ }
+}
+void CFWL_DateTimePickerImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(pMsg);
+ m_pOwner->m_bLBtnDown = FALSE;
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Hovered;
+ } else {
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+void CFWL_DateTimePickerImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ } else {
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+void CFWL_DateTimePickerImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(pMsg);
+ m_pOwner->m_iBtnState = FWL_PARTSTATE_DTP_Normal;
+ m_pOwner->Repaint(&m_pOwner->m_rtBtn);
+}
+void CFWL_DateTimePickerImpDelegate::DisForm_OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)
+{
+ CFX_RectF rtInvalidate(m_pOwner->m_rtBtn);
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if ( m_pOwner->m_pEdit && !(m_pOwner->m_pEdit->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly)) {
+ m_pOwner->m_rtBtn.Set(m_pOwner->m_pProperties->m_rtWidget.width,
+ 0,
+ m_pOwner->m_fBtn,
+ m_pOwner->m_pProperties->m_rtWidget.height - 1);
+ }
+ rtInvalidate = m_pOwner->m_rtBtn;
+ pMsg->m_pDstTarget = m_pOwner->m_pEdit;
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(pMsg);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ m_pOwner->m_rtBtn.Set(0, 0, 0, 0);
+ if (m_pOwner->DisForm_IsMonthCalendarShowed()) {
+ m_pOwner->ShowMonthCalendar(FALSE);
+ }
+ if (m_pOwner->m_pEdit->GetStates() & FWL_WGTSTATE_Focused) {
+ pMsg->m_pSrcTarget = m_pOwner->m_pEdit;
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pEdit->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(pMsg);
+ }
+ }
+ rtInvalidate.Inflate(2, 2);
+ m_pOwner->Repaint(&rtInvalidate);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_editimp.cpp b/xfa/src/fwl/src/basewidget/fwl_editimp.cpp
new file mode 100644
index 0000000000..c7bd922fc1
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_editimp.cpp
@@ -0,0 +1,2244 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_threadimp.h"
+#include "../core/include/fwl_appimp.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_widgetmgrimp.h"
+#include "include/fwl_scrollbarimp.h"
+#include "include/fwl_editimp.h"
+#include "include/fwl_caretimp.h"
+IFWL_Edit* IFWL_Edit::Create()
+{
+ return new IFWL_Edit;
+}
+IFWL_Edit::IFWL_Edit()
+{
+ m_pData = NULL;
+}
+IFWL_Edit::~IFWL_Edit()
+{
+ if (m_pData) {
+ delete (CFWL_EditImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_Edit::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_EditImp(pOuter);
+ ((CFWL_EditImp*)m_pData)->SetInterface(this);
+ return ((CFWL_EditImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Edit::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_EditImp(properties, pOuter);
+ ((CFWL_EditImp*)m_pData)->SetInterface(this);
+ return ((CFWL_EditImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Edit::SetText(const CFX_WideString &wsText)
+{
+ return ((CFWL_EditImp*)m_pData)->SetText(wsText);
+}
+FX_INT32 IFWL_Edit::GetTextLength() const
+{
+ return ((CFWL_EditImp*)m_pData)->GetTextLength();
+}
+FWL_ERR IFWL_Edit::GetText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount) const
+{
+ return ((CFWL_EditImp*)m_pData)->GetText(wsText, nStart, nCount);
+}
+FWL_ERR IFWL_Edit::ClearText()
+{
+ return ((CFWL_EditImp*)m_pData)->ClearText();
+}
+FX_INT32 IFWL_Edit::GetCaretPos() const
+{
+ return ((CFWL_EditImp*)m_pData)->GetCaretPos();
+}
+FX_INT32 IFWL_Edit::SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore)
+{
+ return ((CFWL_EditImp*)m_pData)->SetCaretPos(nIndex, bBefore);
+}
+FWL_ERR IFWL_Edit::AddSelRange(FX_INT32 nStart, FX_INT32 nCount)
+{
+ return ((CFWL_EditImp*)m_pData)->AddSelRange(nStart, nCount);
+}
+FX_INT32 IFWL_Edit::CountSelRanges()
+{
+ return ((CFWL_EditImp*)m_pData)->CountSelRanges();
+}
+FX_INT32 IFWL_Edit::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ return ((CFWL_EditImp*)m_pData)->GetSelRange(nIndex, nStart);
+}
+FWL_ERR IFWL_Edit::ClearSelections()
+{
+ return ((CFWL_EditImp*)m_pData)->ClearSelections();
+}
+FX_INT32 IFWL_Edit::GetLimit()
+{
+ return ((CFWL_EditImp*)m_pData)->GetLimit();
+}
+FWL_ERR IFWL_Edit::SetLimit(FX_INT32 nLimit)
+{
+ return ((CFWL_EditImp*)m_pData)->SetLimit(nLimit);
+}
+FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias)
+{
+ return ((CFWL_EditImp*)m_pData)->SetAliasChar(wAlias);
+}
+FWL_ERR IFWL_Edit::SetFormatString(const CFX_WideString &wsFormat)
+{
+ return ((CFWL_EditImp*)m_pData)->SetFormatString(wsFormat);
+}
+FWL_ERR IFWL_Edit::Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen)
+{
+ return ((CFWL_EditImp*)m_pData)->Insert(nStart, lpText, nLen);
+}
+FWL_ERR IFWL_Edit::DeleteSelections()
+{
+ return ((CFWL_EditImp*)m_pData)->DeleteSelections();
+}
+FWL_ERR IFWL_Edit::DeleteRange(FX_INT32 nStart, FX_INT32 nCount)
+{
+ return ((CFWL_EditImp*)m_pData)->DeleteRange(nStart, nCount);
+}
+FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC &wsReplace)
+{
+ return ((CFWL_EditImp*)m_pData)->ReplaceSelections(wsReplace);
+}
+FWL_ERR IFWL_Edit::Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace)
+{
+ return ((CFWL_EditImp*)m_pData)->Replace(nStart, nLen, wsReplace);
+}
+FWL_ERR IFWL_Edit::DoClipboard(FX_INT32 iCmd)
+{
+ return ((CFWL_EditImp*)m_pData)->DoClipboard(iCmd);
+}
+FX_BOOL IFWL_Edit::Copy(CFX_WideString &wsCopy)
+{
+ return ((CFWL_EditImp*)m_pData)->Copy(wsCopy);
+}
+FX_BOOL IFWL_Edit::Cut(CFX_WideString &wsCut)
+{
+ return ((CFWL_EditImp*)m_pData)->Cut(wsCut);
+}
+FX_BOOL IFWL_Edit::Paste(const CFX_WideString &wsPaste)
+{
+ return ((CFWL_EditImp*)m_pData)->Paste(wsPaste);
+}
+FX_BOOL IFWL_Edit::Delete()
+{
+ return ((CFWL_EditImp*)m_pData)->Delete();
+}
+FX_BOOL IFWL_Edit::Redo(FX_BSTR bsRecord)
+{
+ return ((CFWL_EditImp*)m_pData)->Redo(bsRecord);
+}
+FX_BOOL IFWL_Edit::Undo(FX_BSTR bsRecord)
+{
+ return ((CFWL_EditImp*)m_pData)->Undo(bsRecord);
+}
+FX_BOOL IFWL_Edit::Undo()
+{
+ return ((CFWL_EditImp*)m_pData)->Undo();
+}
+FX_BOOL IFWL_Edit::Redo()
+{
+ return ((CFWL_EditImp*)m_pData)->Redo();
+}
+FX_BOOL IFWL_Edit::CanUndo()
+{
+ return ((CFWL_EditImp*)m_pData)->CanUndo();
+}
+FX_BOOL IFWL_Edit::CanRedo()
+{
+ return ((CFWL_EditImp*)m_pData)->CanRedo();
+}
+FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant)
+{
+ return ((CFWL_EditImp*)m_pData)->SetTabWidth(fTabWidth, bEquidistant);
+}
+FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget *pOuter)
+{
+ return ((CFWL_EditImp*)m_pData)->SetOuter(pOuter);
+}
+FWL_ERR IFWL_Edit::SetNumberRange(FX_INT32 iMin, FX_INT32 iMax)
+{
+ return ((CFWL_EditImp*)m_pData)->SetNumberRange(iMin, iMax);
+}
+FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor)
+{
+ return ((CFWL_EditImp*)m_pData)->SetBackgroundColor(dwColor);
+}
+FWL_ERR IFWL_Edit::SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize)
+{
+ return ((CFWL_EditImp*)m_pData)->SetFont(wsFont, fSize);
+}
+void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset)
+{
+ return ((CFWL_EditImp*)m_pData)->SetScrollOffset(fScrollOffset);
+}
+FX_BOOL IFWL_Edit::GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest)
+{
+ return ((CFWL_EditImp*)m_pData)->GetSuggestWords(pointf, sSuggest);
+}
+FX_BOOL IFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace)
+{
+ return ((CFWL_EditImp*)m_pData)->ReplaceSpellCheckWord(pointf, bsReplace);
+}
+#define FWL_EDIT_Margin 3
+CFWL_EditImp::CFWL_EditImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_fVAlignOffset(0.0f)
+ , m_fScrollOffsetX(0.0f)
+ , m_fScrollOffsetY(0.0f)
+ , m_pEdtEngine(NULL)
+ , m_bLButtonDown(FALSE)
+ , m_nSelStart(0)
+ , m_nLimit(-1)
+ , m_fFontSize(0)
+ , m_pVertScrollBar(NULL)
+ , m_pHorzScrollBar(NULL)
+ , m_pCaret(NULL)
+ , m_iMin(-1)
+ , m_iMax(0xFFFFFFF)
+ , m_bSetRange(FALSE)
+ , m_pTextField(NULL)
+ , m_backColor(0)
+ , m_updateBackColor(FALSE)
+ , m_iCurRecord(-1)
+ , m_iMaxRecord(128)
+ , m_fSpaceAbove(0)
+ , m_fSpaceBelow(0)
+{
+ m_rtClient.Reset();
+ m_rtEngine.Reset();
+ m_rtStatic.Reset();
+}
+CFWL_EditImp::CFWL_EditImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_fVAlignOffset(0.0f)
+ , m_fScrollOffsetX(0.0f)
+ , m_fScrollOffsetY(0.0f)
+ , m_pEdtEngine(NULL)
+ , m_bLButtonDown(FALSE)
+ , m_nSelStart(0)
+ , m_nLimit(-1)
+ , m_fFontSize(0)
+ , m_pVertScrollBar(NULL)
+ , m_pHorzScrollBar(NULL)
+ , m_pCaret(NULL)
+ , m_iMin(-1)
+ , m_iMax(0xFFFFFFF)
+ , m_bSetRange(FALSE)
+ , m_pTextField(NULL)
+ , m_backColor(0)
+ , m_updateBackColor(FALSE)
+ , m_iCurRecord(-1)
+ , m_iMaxRecord(128)
+ , m_fSpaceAbove(0)
+ , m_fSpaceBelow(0)
+{
+ m_rtClient.Reset();
+ m_rtEngine.Reset();
+ m_rtStatic.Reset();
+}
+CFWL_EditImp::~CFWL_EditImp()
+{
+ if (m_pEdtEngine) {
+ m_pEdtEngine->Release();
+ m_pEdtEngine = NULL;
+ }
+ if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->Release();
+ m_pHorzScrollBar = NULL;
+ }
+ if (m_pVertScrollBar) {
+ m_pVertScrollBar->Release();
+ m_pVertScrollBar = NULL;
+ }
+ if (m_pCaret) {
+ m_pCaret->Release();
+ m_pCaret = NULL;
+ }
+ ClearRecord();
+}
+FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_Edit;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_EditImp::GetClassID() const
+{
+ return FWL_CLASSHASH_Edit;
+}
+FWL_ERR CFWL_EditImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ if (!m_pDelegate) {
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_EditImpDelegate(this);
+ }
+ InitCaret();
+ if (!m_pEdtEngine) {
+ InitEngine();
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::Finalize()
+{
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ ShowCaret(FALSE);
+ }
+ if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->Finalize();
+ }
+ if (m_pVertScrollBar) {
+ m_pVertScrollBar->Finalize();
+ }
+ if ( m_pDelegate) {
+ delete (CFWL_EditImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_EditImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (m_pEdtEngine) {
+ FX_INT32 iTextLen = m_pEdtEngine->GetTextLength();
+ if (iTextLen > 0) {
+ CFX_WideString wsText;
+ m_pEdtEngine->GetText(wsText, 0);
+ CFX_SizeF sz = CalcTextSize(wsText,
+ m_pProperties->m_pThemeProvider,
+ m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
+ rect.Set(0, 0, sz.x, sz.y);
+ }
+ }
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
+ if (IsShowScrollBar(TRUE)) {
+ FX_FLOAT *pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ rect.width += *pfWidth;
+ rect.width += FWL_EDIT_Margin;
+ }
+ if (IsShowScrollBar(FALSE)) {
+ FX_FLOAT *pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ rect.height += *pfWidth;
+ rect.height += FWL_EDIT_Margin;
+ }
+ }
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
+{
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) || (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ ShowCaret(FALSE);
+ }
+ return CFWL_WidgetImp::SetStates(dwStates, bSet);
+}
+FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF &rect)
+{
+ return CFWL_WidgetImp::SetWidgetRect(rect);
+}
+FWL_ERR CFWL_EditImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ Layout();
+ if (m_rtClient.IsEmpty()) {
+ return FWL_ERR_Indefinite;
+ }
+ UpdateEditEngine();
+ UpdateVAlignment();
+ UpdateScroll();
+ InitCaret();
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_EditImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
+ if (IsShowScrollBar(TRUE)) {
+ CFX_RectF rect;
+ m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_VScrollBar;
+ }
+ }
+ if (IsShowScrollBar(FALSE)) {
+ CFX_RectF rect;
+ m_pHorzScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_HScrollBar;
+ }
+ }
+ }
+ if (m_rtClient.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Edit;
+ }
+ return FWL_WGTHITTEST_Unknown;
+}
+#define FX_EDIT_ISLATINWORD(u) (u == 0x2D || (u <= 0x005A && u >= 0x0041) || (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || u == 0x0027)
+static void AddSquigglyPath(CFX_Path& PathData, FX_FLOAT fStartX, FX_FLOAT fEndX, FX_FLOAT fY, FX_FLOAT fStep)
+{
+ PathData.MoveTo(fStartX, fY);
+ FX_FLOAT fx;
+ FX_INT32 i;
+ for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) {
+ PathData.LineTo(fx, fY + (i & 1)*fStep);
+ }
+}
+void CFWL_EditImp::AddSpellCheckObj(CFX_Path& PathData, FX_INT32 nStart, FX_INT32 nCount, FX_FLOAT fOffSetX, FX_FLOAT fOffSetY)
+{
+ FX_FLOAT fStartX = 0.0f;
+ FX_FLOAT fEndX = 0.0f;
+ FX_FLOAT fY = 0.0f;
+ FX_FLOAT fStep = 0.0f;
+ IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);
+ CFX_RectFArray rectArray;
+ CFX_RectF rectText;
+ const FDE_TXTEDTPARAMS* txtEdtParams = m_pEdtEngine->GetEditParams();
+ FX_FLOAT fAsent = (FX_FLOAT)txtEdtParams->pFont->GetAscent() * txtEdtParams->fFontSize / 1000;
+ pPage->CalcRangeRectArray(nStart, nCount, rectArray);
+ for (int i = 0; i < rectArray.GetSize(); i++) {
+ rectText = rectArray.GetAt(i);
+ fY = rectText.top + fAsent + fOffSetY;
+ fStep = txtEdtParams->fFontSize / 16.0f;
+ fStartX = rectText.left + fOffSetX;
+ fEndX = fStartX + rectText.Width();
+ AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep);
+ }
+}
+FX_INT32 CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, FX_INT32& nCount)
+{
+ return 0;
+}
+FX_BOOL CFWL_EditImp::GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest)
+{
+ FX_INT32 nWordCount = 0;
+ FX_INT32 nWordStart = GetWordAtPoint(pointf, nWordCount);
+ if (nWordCount < 1) {
+ return FALSE;
+ }
+ CFX_WideString wsSpell;
+ GetText(wsSpell, nWordStart, nWordCount);
+ CFX_ByteString sLatinWord;
+ for (int i = 0; i < nWordCount; i++) {
+ if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
+ break;
+ }
+ sLatinWord += (FX_CHAR)wsSpell[i];
+ }
+ if (sLatinWord.IsEmpty()) {
+ return FALSE;
+ }
+ CFWL_EvtEdtCheckWord checkWordEvent;
+ checkWordEvent.m_pSrcTarget = m_pInterface;
+ checkWordEvent.bsWord = sLatinWord;
+ checkWordEvent.bCheckWord = TRUE;
+ DispatchEvent(&checkWordEvent);
+ if (checkWordEvent.bCheckWord) {
+ return FALSE;
+ }
+ CFWL_EvtEdtGetSuggestWords suggestWordsEvent;
+ suggestWordsEvent.m_pSrcTarget = m_pInterface;
+ suggestWordsEvent.bsWord = sLatinWord;
+ suggestWordsEvent.bsArraySuggestWords = sSuggest;
+ suggestWordsEvent.bSuggestWords = FALSE;
+ DispatchEvent(&checkWordEvent);
+ return suggestWordsEvent.bSuggestWords;
+}
+FX_BOOL CFWL_EditImp::ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace)
+{
+ FX_INT32 nWordCount = 0;
+ FX_INT32 nWordStart = GetWordAtPoint(pointf, nWordCount);
+ if (nWordCount < 1) {
+ return FALSE;
+ }
+ CFX_WideString wsSpell;
+ GetText(wsSpell, nWordStart, nWordCount);
+ for (int i = 0; i < nWordCount; i++) {
+ if (!FX_EDIT_ISLATINWORD(wsSpell[i])) {
+ nWordCount = i;
+ break;
+ }
+ }
+ FX_INT32 nDestLen = bsReplace.GetLength();
+ CFX_WideString wsDest;
+ FX_LPWSTR pBuffer = wsDest.GetBuffer(nDestLen);
+ for (FX_INT32 i = 0; i < nDestLen; i++) {
+ pBuffer[i] = bsReplace[i];
+ }
+ wsDest.ReleaseBuffer(nDestLen);
+ Replace(nWordStart, nWordCount, wsDest);
+ return TRUE;
+}
+void CFWL_EditImp::DrawSpellCheck(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ pGraphics->SaveGraphState();
+ if (pMatrix) {
+ pGraphics->ConcatMatrix((CFX_Matrix*)pMatrix);
+ }
+ FX_ARGB cr = 0xFFFF0000;
+ CFX_Color crLine(cr);
+ FX_FLOAT fWidth = 1.0f;
+ CFWL_EvtEdtCheckWord checkWordEvent;
+ checkWordEvent.m_pSrcTarget = m_pInterface;
+ CFX_ByteString sLatinWord;
+ CFX_Path pathSpell;
+ pathSpell.Create();
+ FX_INT32 nStart = 0;
+ FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
+ FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
+ CFX_WideString wsSpell;
+ this->GetText(wsSpell);
+ FX_INT32 nContentLen = wsSpell.GetLength();
+ for (int i = 0; i < nContentLen; i++) {
+ if (FX_EDIT_ISLATINWORD(wsSpell[i])) {
+ if (sLatinWord.IsEmpty()) {
+ nStart = i;
+ }
+ sLatinWord += (FX_CHAR)wsSpell[i];
+ } else {
+ checkWordEvent.bsWord = sLatinWord;
+ checkWordEvent.bCheckWord = TRUE;
+ DispatchEvent(&checkWordEvent);
+ if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
+ AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, fOffSetY);
+ }
+ sLatinWord.Empty();
+ }
+ }
+ checkWordEvent.bsWord = sLatinWord;
+ checkWordEvent.bCheckWord = TRUE;
+ DispatchEvent(&checkWordEvent);
+ if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) {
+ AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, fOffSetY);
+ }
+ if (!pathSpell.IsEmpty()) {
+ CFX_RectF rtClip = m_rtEngine;
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
+ if (pMatrix) {
+ pMatrix->TransformRect(rtClip);
+ mt.Concat(*pMatrix);
+ }
+ pGraphics->SetClipRect(rtClip);
+ pGraphics->SetStrokeColor(&crLine);
+ pGraphics->SetLineWidth(0);
+ pGraphics->StrokePath(&pathSpell, NULL);
+ }
+ pGraphics->RestoreGraphState();
+}
+FWL_ERR CFWL_EditImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ if (m_rtClient.IsEmpty()) {
+ return FWL_ERR_Indefinite;
+ }
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (!m_pWidgetMgr->IsFormDisabled()) {
+ DrawTextBk(pGraphics, pTheme, pMatrix);
+ }
+ if (m_pEdtEngine) {
+ DrawContent(pGraphics, pTheme, pMatrix);
+ }
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) {
+ DrawSpellCheck(pGraphics, pMatrix);
+ }
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_EDT_Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_EDT_Edge, pTheme, pMatrix);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetThemeProvider(IFWL_ThemeProvider *pThemeProvider)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pThemeProvider, FWL_ERR_Indefinite);
+ if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->SetThemeProvider(pThemeProvider);
+ }
+ if (m_pVertScrollBar) {
+ m_pVertScrollBar->SetThemeProvider(pThemeProvider);
+ }
+ if (m_pCaret) {
+ m_pCaret->SetThemeProvider(pThemeProvider);
+ }
+ m_pProperties->m_pThemeProvider = pThemeProvider;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetText(const CFX_WideString &wsText)
+{
+ m_pEdtEngine->SetText(wsText);
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_EditImp::GetTextLength() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);
+ return m_pEdtEngine->GetTextLength();
+}
+FWL_ERR CFWL_EditImp::GetText(CFX_WideString &wsText, FX_INT32 nStart , FX_INT32 nCount ) const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->GetText(wsText, nStart, nCount);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::ClearText()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->ClearText();
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_EditImp::GetCaretPos() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);
+ return m_pEdtEngine->GetCaretPos();
+}
+FX_INT32 CFWL_EditImp::SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);
+ return m_pEdtEngine->SetCaretPos(nIndex, bBefore);
+}
+FWL_ERR CFWL_EditImp::AddSelRange(FX_INT32 nStart, FX_INT32 nCount )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->AddSelRange(nStart, nCount);
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_EditImp::CountSelRanges()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, 0);
+ return m_pEdtEngine->CountSelRanges();
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_EditImp::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, -1);
+ return m_pEdtEngine->GetSelRange(nIndex, nStart);
+}
+FWL_ERR CFWL_EditImp::ClearSelections()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->ClearSelection();
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_EditImp::GetLimit()
+{
+ return m_nLimit;
+}
+FWL_ERR CFWL_EditImp::SetLimit(FX_INT32 nLimit)
+{
+ m_nLimit = nLimit;
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->SetLimit(nLimit);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetAliasChar(FX_WCHAR wAlias)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Indefinite);
+ m_pEdtEngine->SetAliasChar(wAlias);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetFormatString(const CFX_WideString &wsFormat)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->SetFormatBlock(0, wsFormat);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ if ( (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)
+ || (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ return FWL_ERR_Indefinite;
+ }
+ m_pEdtEngine->Insert(nStart, lpText, nLen);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::DeleteSelections()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ FX_INT32 iCount = m_pEdtEngine->CountSelRanges();
+ if (iCount > 0) {
+ m_pEdtEngine->Delete(-1);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::DeleteRange(FX_INT32 nStart, FX_INT32 nCount )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->DeleteRange(nStart, nCount);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::ReplaceSelections(const CFX_WideStringC &wsReplace)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ FX_INT32 iCount = m_pEdtEngine->CountSelRanges();
+ for (int i = 0; i < iCount; i ++) {
+ FX_INT32 nStart;
+ FX_INT32 nCount = m_pEdtEngine->GetSelRange(i, nStart);
+ m_pEdtEngine->Replace(nStart, nCount, wsReplace);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ m_pEdtEngine->Replace(nStart, nLen, wsReplace);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::DoClipboard(FX_INT32 iCmd)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ if ( (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)
+ || (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ return FWL_ERR_Succeeded;
+ }
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(pNative, FWL_ERR_Indefinite);
+ IFWL_AdapterClipboardMgr *pClipBorder = pNative->GetClipboardMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pClipBorder, FWL_ERR_Indefinite);
+ CFX_WideString wsText;
+ switch(iCmd) {
+ case 1: {
+ FX_INT32 nStart;
+ FX_INT32 nCount = m_pEdtEngine->GetSelRange(0, nStart);
+ if (nCount < 1) {
+ break;
+ }
+ m_pEdtEngine->GetText(wsText, nStart, nCount);
+ pClipBorder->SetStringData(wsText);
+ break;
+ }
+ case 2: {
+ FX_INT32 nStart;
+ FX_INT32 nCount = m_pEdtEngine->GetSelRange(0, nStart);
+ if (nCount < 1) {
+ break;
+ }
+ m_pEdtEngine->GetText(wsText, nStart, nCount);
+ m_pEdtEngine->DeleteRange(nStart, nCount);
+ m_pEdtEngine->ClearSelection();
+ pClipBorder->SetStringData(wsText);
+ break;
+ }
+ case 3: {
+ pClipBorder->GetStringData(wsText);
+ FX_INT32 iLen = wsText.GetLength();
+ if (iLen < 0) {
+ break;
+ }
+ if (wsText[iLen] == L'\0') {
+ if (iLen == 1) {
+ break;
+ }
+ iLen --;
+ wsText = wsText.Left(iLen);
+ }
+ FX_INT32 nPos = m_pEdtEngine->GetCaretPos();
+ m_pEdtEngine->Insert(nPos, wsText, iLen);
+ break;
+ }
+ default: {
+ }
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_EditImp::Copy(CFX_WideString &wsCopy)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);
+ FX_INT32 nCount = m_pEdtEngine->CountSelRanges();
+ if (nCount == 0) {
+ return FALSE;
+ }
+ wsCopy.Empty();
+ CFX_WideString wsTemp;
+ FX_INT32 nStart, nLength;
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ nLength = m_pEdtEngine->GetSelRange(i, nStart);
+ m_pEdtEngine->GetText(wsTemp, nStart, nLength);
+ wsCopy += wsTemp;
+ wsTemp.Empty();
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_EditImp::Cut(CFX_WideString &wsCut)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);
+ FX_INT32 nCount = m_pEdtEngine->CountSelRanges();
+ if (nCount == 0) {
+ return FALSE;
+ }
+ wsCut.Empty();
+ CFX_WideString wsTemp;
+ FX_INT32 nStart, nLength;
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ nLength = m_pEdtEngine->GetSelRange(i, nStart);
+ m_pEdtEngine->GetText(wsTemp, nStart, nLength);
+ wsCut += wsTemp;
+ wsTemp.Empty();
+ }
+ m_pEdtEngine->Delete(0);
+ return TRUE;
+}
+FX_BOOL CFWL_EditImp::Paste(const CFX_WideString &wsPaste)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);
+ FX_INT32 nCaret = m_pEdtEngine->GetCaretPos();
+ FX_INT32 iError = m_pEdtEngine->Insert(nCaret, FX_LPCWSTR(wsPaste), wsPaste.GetLength());
+ if (iError < 0) {
+ ProcessInsertError(iError);
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_EditImp::Delete()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);
+ FX_INT32 nCount = m_pEdtEngine->CountSelRanges();
+ if (nCount < 1) {
+ return FALSE;
+ }
+ m_pEdtEngine->Delete(0);
+ return TRUE;
+}
+FX_BOOL CFWL_EditImp::Redo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
+ return TRUE;
+ }
+ return m_pEdtEngine->Redo(bsRecord);
+}
+FX_BOOL CFWL_EditImp::Undo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) {
+ return TRUE;
+ }
+ return m_pEdtEngine->Undo(bsRecord);
+}
+FX_BOOL CFWL_EditImp::Undo()
+{
+ if (!CanUndo()) {
+ return FALSE;
+ }
+ CFX_ByteString bsRecord = m_RecordArr[m_iCurRecord--];
+ return Undo(bsRecord);
+}
+FX_BOOL CFWL_EditImp::Redo()
+{
+ if (!CanRedo()) {
+ return FALSE;
+ }
+ CFX_ByteString bsRecord = m_RecordArr[++m_iCurRecord];
+ return Redo(bsRecord);
+}
+FX_BOOL CFWL_EditImp::CanUndo()
+{
+ return m_iCurRecord >= 0;
+}
+FX_BOOL CFWL_EditImp::CanRedo()
+{
+ return m_iCurRecord < m_RecordArr.GetSize() - 1;
+}
+FWL_ERR CFWL_EditImp::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FWL_ERR_Succeeded);
+ FDE_LPTXTEDTPARAMS pParams = (FDE_LPTXTEDTPARAMS)m_pEdtEngine->GetEditParams();
+ pParams->fTabWidth = fTabWidth;
+ pParams->bTabEquidistant = bEquidistant;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget *pOuter)
+{
+ m_pOuter = pOuter;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetNumberRange(FX_INT32 iMin, FX_INT32 iMax)
+{
+ m_iMin = iMin;
+ m_iMax = iMax;
+ m_bSetRange = TRUE;
+ return FWL_ERR_Succeeded;
+}
+void CFWL_EditImp::On_CaretChanged(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPage, FX_BOOL bVisible )
+{
+ if (m_rtEngine.IsEmpty()) {
+ return;
+ }
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ return;
+ }
+ FX_BOOL bRepaintContent = UpdateOffset();
+ UpdateCaret();
+ CFX_RectF rtInvalid;
+ rtInvalid.Set(0, 0, 0, 0);
+ FX_BOOL bRepaintScroll = FALSE;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
+ IFWL_ScrollBar *pScroll = UpdateScroll();
+ if (pScroll) {
+ pScroll->GetWidgetRect(rtInvalid);
+ bRepaintScroll = TRUE;
+ }
+ }
+ if (bRepaintContent || bRepaintScroll) {
+ if (bRepaintContent) {
+ rtInvalid.Union(m_rtEngine);
+ }
+ Repaint(&rtInvalid);
+ }
+}
+void CFWL_EditImp::On_TextChanged(IFDE_TxtEdtEngine *pEdit, FDE_TXTEDT_TEXTCHANGE_INFO &ChangeInfo)
+{
+ FX_DWORD dwStyleEx = m_pProperties->m_dwStyleExes;
+ if (dwStyleEx & FWL_STYLEEXT_EDT_VAlignMask) {
+ UpdateVAlignment();
+ }
+ IFDE_TxtEdtPage *page = m_pEdtEngine->GetPage(0);
+ FX_FLOAT fContentWidth = page->GetContentsBox().width;
+ FX_FLOAT fContentHeight = page->GetContentsBox().height;
+ CFX_RectF rtTemp;
+ GetClientRect(rtTemp);
+ FX_BOOL bHSelfAdaption = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption;
+ FX_BOOL bVSelfAdaption = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption;
+ FX_BOOL bNeedUpdate = FALSE;
+ if (bHSelfAdaption || bVSelfAdaption) {
+ CFWL_EvtEdtPreSelfAdaption evt;
+ evt.m_pSrcTarget = m_pInterface;
+ evt.bHSelfAdaption = TRUE;
+ evt.bVSelfAdaption = TRUE;
+ FX_FLOAT fWidth;
+ FX_FLOAT fHight;
+ fWidth = bHSelfAdaption ? fContentWidth : m_pProperties->m_rtWidget.width;
+ fHight = bVSelfAdaption ? fContentHeight : m_pProperties->m_rtWidget.height;
+ evt.rtAfterChange.Set(0, 0, fWidth, fHight);
+ DispatchEvent(&evt);
+ if (!evt.bHSelfAdaption) {
+ ModifyStylesEx(0, FWL_STYLEEXT_EDT_HSelfAdaption | FWL_STYLEEXT_EDT_AutoHScroll);
+ }
+ if (!evt.bVSelfAdaption) {
+ ModifyStylesEx(0, FWL_STYLEEXT_EDT_VSelfAdaption | FWL_STYLEEXT_EDT_AutoVScroll);
+ }
+ bNeedUpdate = (bHSelfAdaption && !evt.bHSelfAdaption) || (bVSelfAdaption && !evt.bVSelfAdaption);
+ }
+ FX_FLOAT fContentWidth1 = fContentWidth;
+ FX_FLOAT fContentHeight1 = fContentHeight;
+ if (bNeedUpdate) {
+ UpdateEditParams();
+ UpdateEditLayout();
+ IFDE_TxtEdtPage *page1 = m_pEdtEngine->GetPage(0);
+ fContentWidth1 = page1->GetContentsBox().width;
+ fContentHeight1 = page1->GetContentsBox().height;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption) {
+ rtTemp.width = FX_MAX(m_pProperties->m_rtWidget.width, fContentWidth1);
+ m_pProperties->m_rtWidget.width = fContentWidth1;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption) {
+ rtTemp.height = FX_MAX(m_pProperties->m_rtWidget.height, fContentHeight1);
+ m_pProperties->m_rtWidget.height = fContentHeight1;
+ }
+ CFWL_EvtEdtTextChanged event;
+ event.m_pSrcTarget = m_pInterface;
+ event.nChangeType = ChangeInfo.nChangeType;
+ event.wsInsert = ChangeInfo.wsInsert;
+ event.wsDelete = ChangeInfo.wsDelete;
+ event.wsPrevText = ChangeInfo.wsPrevText;
+ DispatchEvent(&event);
+ LayoutScrollBar();
+ Repaint(&rtTemp);
+}
+void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine *pEdit)
+{
+ CFX_RectF rtTemp;
+ GetClientRect(rtTemp);
+ Repaint(&rtTemp);
+}
+FX_BOOL CFWL_EditImp::On_PageLoad(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose)
+{
+ IFDE_TxtEdtEngine *pEdtEngine = m_pEdtEngine;
+ IFDE_TxtEdtPage *pPage = pEdtEngine->GetPage(nPageIndex);
+ _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);
+ pPage->LoadPage();
+ return TRUE;
+}
+FX_BOOL CFWL_EditImp::On_PageUnload(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose)
+{
+ IFDE_TxtEdtEngine *pEdtEngine = m_pEdtEngine;
+ IFDE_TxtEdtPage *pPage = pEdtEngine->GetPage(nPageIndex);
+ _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);
+ pPage->UnloadPage();
+ return TRUE;
+}
+void CFWL_EditImp::On_AddDoRecord(IFDE_TxtEdtEngine *pEdit, FX_BSTR bsDoRecord)
+{
+ AddDoRecord(bsDoRecord);
+ CFWL_WidgetImp *pSrcTarget = GetRootOuter();
+ if (!pSrcTarget) {
+ pSrcTarget = this;
+ }
+ CFWL_EvtEdtAddDoRecord evt;
+ evt.m_pSrcTarget = m_pInterface;
+ evt.m_wsDoRecord = bsDoRecord;
+ m_pDelegate->OnProcessEvent(&evt);
+}
+FX_BOOL CFWL_EditImp::On_ValidateField(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex, FX_INT32 nFieldIndex, \
+ const CFX_WideString &wsFieldText, FX_INT32 nCharIndex)
+{
+ return TRUE;
+}
+FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex)
+{
+ return TRUE;
+}
+FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex, CFX_WideString &wsBlockText)
+{
+ return FALSE;
+}
+FX_BOOL CFWL_EditImp::On_Validate(IFDE_TxtEdtEngine * pEdit, CFX_WideString &wsText)
+{
+ IFWL_Widget *pDst = GetOuter();
+ if (!pDst) {
+ pDst = (IFWL_Widget*)this;
+ }
+ CFWL_EvtEdtValidate event;
+ event.pDstWidget = pDst;
+ event.m_pSrcTarget = m_pInterface;
+ event.wsInsert = wsText;
+ event.bValidate = TRUE;
+ DispatchEvent(&event);
+ return event.bValidate;
+}
+FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color)
+{
+ m_backColor = color;
+ m_updateBackColor = TRUE;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImp::SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize)
+{
+ m_wsFont = wsFont;
+ m_fFontSize = fSize;
+ return FWL_ERR_Succeeded;
+}
+void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset)
+{
+ m_fScrollOffsetY = fScrollOffset;
+}
+void CFWL_EditImp::DrawTextBk(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix )
+{
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_EDT_Background;
+ param.m_dwData = FWL_PARTDATA_EDT_Background;
+ param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly ?
+ FWL_PARTSTATE_EDT_ReadOnly : FWL_PARTSTATE_EDT_Normal;
+ FX_DWORD dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled);
+ if ( dwStates) {
+ param.m_dwStates = FWL_PARTSTATE_EDT_Disable;
+ }
+ param.m_pGraphics = pGraphics;
+ param.m_matrix = *pMatrix;
+ param.m_rtPart = m_rtClient;
+ pTheme->DrawBackground(&param);
+ if (!IsShowScrollBar(TRUE) || !IsShowScrollBar(FALSE)) {
+ return;
+ }
+ CFX_RectF rtScorll;
+ m_pHorzScrollBar->GetWidgetRect(rtScorll);
+ FX_FLOAT fStaticWidth = rtScorll.height;
+ CFX_RectF rtStatic;
+ rtStatic.Set(m_rtClient.right() - rtScorll.height,
+ m_rtClient.bottom() - rtScorll.height,
+ rtScorll.height,
+ rtScorll.height);
+ param.m_dwData = FWL_PARTDATA_EDT_StaticBackground;
+ param.m_rtPart = rtStatic;
+ pTheme->DrawBackground(&param);
+}
+void CFWL_EditImp::DrawContent(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(m_pEdtEngine);
+ IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_IF_FAIL(pPage);
+ pGraphics->SaveGraphState();
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
+ pGraphics->SaveGraphState();
+ }
+ CFX_RectF rtClip = m_rtEngine;
+ FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
+ FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY);
+ if (pMatrix) {
+ pMatrix->TransformRect(rtClip);
+ mt.Concat(*pMatrix);
+ }
+ FX_BOOL bShowSel = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) || (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused);
+ if (bShowSel) {
+ IFWL_Widget *pForm = m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
+ if (pForm) {
+ bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) != FWL_WGTSTATE_Deactivated;
+ }
+ }
+ FX_INT32 nSelCount = m_pEdtEngine->CountSelRanges();
+ if (bShowSel && nSelCount > 0) {
+ FX_INT32 nPageCharStart = pPage->GetCharStart();
+ FX_INT32 nPageCharCount = pPage->GetCharCount();
+ FX_INT32 nPageCharEnd = nPageCharStart + nPageCharCount - 1;
+ FX_INT32 nCharCount;
+ FX_INT32 nCharStart;
+ CFX_RectFArray rectArr;
+ FX_INT32 i = 0;
+ for (i = 0; i < nSelCount; i ++) {
+ nCharCount = m_pEdtEngine->GetSelRange(i, nCharStart);
+ FX_INT32 nCharEnd = nCharStart + nCharCount - 1;
+ if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) {
+ continue;
+ }
+ FX_INT32 nBgn = FX_MAX(nCharStart, nPageCharStart);
+ FX_INT32 nEnd = FX_MIN(nCharEnd, nPageCharEnd);
+ pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1, rectArr);
+ }
+ FX_INT32 nCount = rectArr.GetSize();
+ CFX_Path path;
+ path.Create();
+ for (i = 0; i < nCount; i ++) {
+ rectArr[i].left += fOffSetX;
+ rectArr[i].top += fOffSetY;
+ path.AddRectangle(rectArr[i].left,
+ rectArr[i].top,
+ rectArr[i].width,
+ rectArr[i].height);
+ }
+ pGraphics->SetClipRect(rtClip);
+ CFWL_ThemeBackground param;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix = *pMatrix;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_EDT_Background;
+ param.m_pPath = &path;
+ pTheme->DrawBackground(&param);
+ }
+ CFX_RenderDevice *pRenderDev = pGraphics->GetRenderDevice();
+ _FWL_RETURN_IF_FAIL(pRenderDev);
+ IFDE_RenderDevice *pRenderDevice = IFDE_RenderDevice::Create(pRenderDev);
+ _FWL_RETURN_IF_FAIL(pRenderDevice);
+ IFDE_RenderContext *pRenderContext = IFDE_RenderContext::Create();
+ _FWL_RETURN_IF_FAIL(pRenderContext);
+ pRenderDevice->SetClipRect(rtClip);
+ pRenderContext->StartRender(pRenderDevice, (IFDE_CanvasSet*)pPage, mt);
+ pRenderContext->DoRender(NULL);
+ pRenderContext->Release();
+ pRenderDevice->Release();
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
+ pGraphics->RestoreGraphState();
+ CFX_Path path;
+ path.Create();
+ FX_INT32 iLimit = m_nLimit > 0 ? m_nLimit : 1;
+ FX_FLOAT fStep = m_rtEngine.width / iLimit;
+ FX_FLOAT fLeft = m_rtEngine.left + 1;
+ for (FX_INT32 i = 1; i < iLimit; i++) {
+ fLeft += fStep;
+ path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom());
+ }
+ CFWL_ThemeBackground param;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix = *pMatrix;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_EDT_CombTextLine;
+ param.m_pPath = &path;
+ pTheme->DrawBackground(&param);
+ }
+ pGraphics->RestoreGraphState();
+}
+void CFWL_EditImp::UpdateEditEngine()
+{
+ UpdateEditParams();
+ UpdateEditLayout();
+ if (m_nLimit > -1) {
+ m_pEdtEngine->SetLimit(m_nLimit);
+ }
+}
+void CFWL_EditImp::UpdateEditParams()
+{
+ FDE_TXTEDTPARAMS params;
+ params.nHorzScale = 100;
+ params.fPlateWidth = m_rtEngine.width;
+ params.fPlateHeight = m_rtEngine.height;
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) {
+ params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) {
+ params.dwMode |= FDE_TEXTEDITMODE_Validate;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) {
+ params.dwMode |= FDE_TEXTEDITMODE_Password;
+ }
+ switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) {
+ case FWL_STYLEEXT_EDT_HNear: {
+ params.dwAlignment |= FDE_TEXTEDITALIGN_Left;
+ break;
+ }
+ case FWL_STYLEEXT_EDT_HCenter: {
+ params.dwAlignment |= FDE_TEXTEDITALIGN_Center;
+ break;
+ }
+ case FWL_STYLEEXT_EDT_HFar: {
+ params.dwAlignment |= FDE_TEXTEDITALIGN_Right;
+ break;
+ }
+ default: {
+ }
+ }
+ switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) {
+ case FWL_STYLEEXT_EDT_Justified: {
+ params.dwAlignment |= FDE_TEXTEDITALIGN_Justified;
+ break;
+ }
+ case FWL_STYLEEXT_EDT_Distributed: {
+ params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed;
+ break;
+ }
+ default: {
+ params.dwAlignment |= FDE_TEXTEDITALIGN_Normal;
+ }
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) {
+ params.dwMode |= FDE_TEXTEDITMODE_MultiLines;
+ if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 && (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
+ params.dwMode |= FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz;
+ }
+ if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 && (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) {
+ params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert;
+ } else {
+ params.fPlateHeight = 0x00FFFFFF;
+ }
+ } else {
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) {
+ params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz;
+ }
+ }
+ if ( (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)
+ || (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ params.dwMode |= FDE_TEXTEDITMODE_ReadOnly;
+ }
+ FX_FLOAT *pFontSize = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_FontSize);
+ _FWL_RETURN_IF_FAIL(pFontSize);
+ m_fFontSize = *pFontSize;
+ FX_DWORD *pFontColor = (FX_DWORD*)GetThemeCapacity(FWL_WGTCAPACITY_TextColor);
+ _FWL_RETURN_IF_FAIL(pFontColor);
+ params.dwFontColor = *pFontColor;
+ FX_FLOAT *pLineHeight = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_LineHeight);
+ _FWL_RETURN_IF_FAIL(pLineHeight);
+ params.fLineSpace = *pLineHeight;
+ IFX_Font *pFont = (IFX_Font*)GetThemeCapacity(FWL_WGTCAPACITY_Font);
+ _FWL_RETURN_IF_FAIL(pFont);
+ params.pFont = pFont;
+ params.fFontSize = m_fFontSize;
+ params.nLineCount = (FX_INT32)(params.fPlateHeight / params.fLineSpace);
+ if (params.nLineCount <= 0) {
+ params.nLineCount = 1;
+ }
+ params.fTabWidth = params.fFontSize * 1;
+ params.bTabEquidistant = TRUE;
+ params.wLineBreakChar = L'\n';
+ params.nCharRotation = 0;
+ params.pEventSink = this;
+ m_pEdtEngine->SetEditParams(params);
+}
+void CFWL_EditImp::UpdateEditLayout()
+{
+ if (m_pEdtEngine->GetTextLength() <= 0) {
+ m_pEdtEngine->SetTextByStream(NULL);
+ }
+ IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);
+ if (pPage) {
+ pPage->UnloadPage();
+ pPage = NULL;
+ }
+ m_pEdtEngine->StartLayout();
+ m_pEdtEngine->DoLayout(NULL);
+ m_pEdtEngine->EndLayout();
+ pPage = m_pEdtEngine->GetPage(0);
+ if (pPage) {
+ pPage->LoadPage();
+ }
+}
+FX_BOOL CFWL_EditImp::UpdateOffset()
+{
+ CFX_RectF rtCaret;
+ m_pEdtEngine->GetCaretRect(rtCaret);
+ FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX;
+ FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset;
+ rtCaret.Offset(fOffSetX, fOffSetY);
+ const CFX_RectF& rtEidt = m_rtEngine;
+ if (rtEidt.Contains(rtCaret)) {
+ IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);
+ CFX_RectF rtFDE = pPage->GetContentsBox();
+ rtFDE.Offset(fOffSetX, fOffSetY);
+ if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) {
+ m_fScrollOffsetX += rtFDE.right() - rtEidt.right();
+ if (m_fScrollOffsetX < 0) {
+ m_fScrollOffsetX = 0;
+ }
+ }
+ if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) {
+ m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom();
+ if (m_fScrollOffsetY < 0) {
+ m_fScrollOffsetY = 0;
+ }
+ }
+ return FALSE;
+ } else {
+ FX_FLOAT offsetX = 0.0;
+ FX_FLOAT offsetY = 0.0;
+ if (rtCaret.left < rtEidt.left) {
+ offsetX = rtCaret.left - rtEidt.left;
+ }
+ if (rtCaret.right() > rtEidt.right()) {
+ offsetX = rtCaret.right() - rtEidt.right();
+ }
+ if (rtCaret.top < rtEidt.top) {
+ offsetY = rtCaret.top - rtEidt.top;
+ }
+ if (rtCaret.bottom() > rtEidt.bottom()) {
+ offsetY = rtCaret.bottom() - rtEidt.bottom();
+ }
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption)) {
+ m_fScrollOffsetX += offsetX;
+ }
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption)) {
+ m_fScrollOffsetY += offsetY;
+ }
+ if (m_fFontSize > m_rtEngine.height) {
+ m_fScrollOffsetY = 0;
+ }
+ return TRUE;
+ }
+}
+FX_BOOL CFWL_EditImp::UpdateOffset(IFWL_ScrollBar *pScrollBar, FX_FLOAT fPosChanged)
+{
+ if (pScrollBar == (IFWL_ScrollBar*)m_pHorzScrollBar) {
+ m_fScrollOffsetX += fPosChanged;
+ } else {
+ m_fScrollOffsetY += fPosChanged;
+ }
+ return TRUE;
+}
+void CFWL_EditImp::UpdateVAlignment()
+{
+ IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_IF_FAIL(pPage);
+ const CFX_RectF& rtFDE = pPage->GetContentsBox();
+ FX_FLOAT fOffsetY = 0.0f;
+ FX_FLOAT fSpaceAbove = 0.0f;
+ FX_FLOAT fSpaceBelow = 0.0f;
+ CFX_SizeF* pSpace = (CFX_SizeF*)GetThemeCapacity(FWL_WGTCAPACITY_SpaceAboveBelow);
+ if (pSpace) {
+ fSpaceAbove = pSpace->x;
+ fSpaceBelow = pSpace->y;
+ }
+ if (fSpaceAbove < 0.1f) {
+ fSpaceAbove = 0;
+ }
+ if (fSpaceBelow < 0.1f) {
+ fSpaceBelow = 0;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) {
+ fOffsetY = (m_rtEngine.height - rtFDE.height) / 2;
+ if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 && fSpaceAbove < fSpaceBelow) {
+ return;
+ }
+ fOffsetY += (fSpaceAbove - fSpaceBelow) / 2;
+ } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) {
+ fOffsetY = (m_rtEngine.height - rtFDE.height);
+ fOffsetY -= fSpaceBelow;
+ } else {
+ fOffsetY += fSpaceAbove;
+ }
+ m_fVAlignOffset = fOffsetY;
+ if (m_fVAlignOffset < 0) {
+ m_fVAlignOffset = 0;
+ }
+}
+void CFWL_EditImp::UpdateCaret()
+{
+ CFX_RectF rtFDE;
+ m_pEdtEngine->GetCaretRect(rtFDE);
+ rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX, m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset);
+ CFX_RectF rtCaret;
+ rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height);
+ CFX_RectF temp = rtCaret;
+ CFX_RectF rtClient;
+ GetClientRect(rtClient);
+ rtCaret.Intersect(rtClient);
+ if (rtCaret.left > rtClient.right()) {
+ FX_FLOAT right = rtCaret.right();
+ rtCaret.left = rtClient.right() - 1;
+ rtCaret.width = right - rtCaret.left;
+ }
+ FX_BOOL bIntersect = !rtCaret.IsEmpty();
+ FX_BOOL bShow = TRUE;
+ FX_BOOL bShowWhole = FALSE;
+ if (!(m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) || !bIntersect) {
+ bShow = FALSE;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption && temp.right() > m_rtEngine.right()) {
+ bShowWhole = TRUE;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption && temp.bottom() > m_rtEngine.bottom()) {
+ bShowWhole = TRUE;
+ } else {
+ bShow = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && bIntersect);
+ }
+ if (bShowWhole) {
+ rtCaret = temp;
+ }
+ ShowCaret(bShow, &rtCaret);
+}
+IFWL_ScrollBar* CFWL_EditImp::UpdateScroll()
+{
+ FX_BOOL bShowHorz = m_pHorzScrollBar && ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
+ FX_BOOL bShowVert = m_pVertScrollBar && ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0);
+ if (!bShowHorz && !bShowVert) {
+ return NULL;
+ }
+ IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_VALUE_IF_FAIL(pPage, NULL);
+ const CFX_RectF &rtFDE = pPage->GetContentsBox();
+ IFWL_ScrollBar *pRepaint = NULL;
+ if (bShowHorz) {
+ CFX_RectF rtScroll;
+ m_pHorzScrollBar->GetWidgetRect(rtScroll);
+ if (rtScroll.width < rtFDE.width) {
+ m_pHorzScrollBar->LockUpdate();
+ FX_FLOAT fRange = rtFDE.width - rtScroll.width;
+ m_pHorzScrollBar->SetRange(0.0f, fRange);
+ FX_FLOAT fPos = m_fScrollOffsetX;
+ if (fPos < 0.0f) {
+ fPos = 0.0f;
+ }
+ if (fPos > fRange) {
+ fPos = fRange;
+ }
+ m_pHorzScrollBar->SetPos(fPos);
+ m_pHorzScrollBar->SetTrackPos(fPos);
+ m_pHorzScrollBar->SetPageSize(rtScroll.width);
+ m_pHorzScrollBar->SetStepSize(rtScroll.width / 10);
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
+ m_pHorzScrollBar->UnlockUpdate();
+ m_pHorzScrollBar->Update();
+ pRepaint = (IFWL_ScrollBar*)m_pHorzScrollBar;
+ } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
+ m_pHorzScrollBar->LockUpdate();
+ m_pHorzScrollBar->SetRange(0, -1);
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
+ m_pHorzScrollBar->UnlockUpdate();
+ m_pHorzScrollBar->Update();
+ pRepaint = (IFWL_ScrollBar*)m_pHorzScrollBar;
+ }
+ }
+ if (bShowVert) {
+ CFX_RectF rtScroll;
+ m_pVertScrollBar->GetWidgetRect(rtScroll);
+ if (rtScroll.height < rtFDE.height) {
+ m_pVertScrollBar->LockUpdate();
+ FX_FLOAT fStep = m_pEdtEngine->GetEditParams()->fLineSpace;
+ FX_FLOAT fRange = rtFDE.height - m_rtEngine.height;
+ if (fRange < fStep) {
+ fRange = fStep;
+ }
+ m_pVertScrollBar->SetRange(0.0f, fRange);
+ FX_FLOAT fPos = m_fScrollOffsetY;
+ if (fPos < 0.0f) {
+ fPos = 0.0f;
+ }
+ if (fPos > fRange) {
+ fPos = fRange;
+ }
+ m_pVertScrollBar->SetPos(fPos);
+ m_pVertScrollBar->SetTrackPos(fPos);
+ m_pVertScrollBar->SetPageSize(rtScroll.height);
+ m_pVertScrollBar->SetStepSize(fStep);
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE);
+ m_pVertScrollBar->UnlockUpdate();
+ m_pVertScrollBar->Update();
+ pRepaint = (IFWL_ScrollBar*)m_pVertScrollBar;
+ } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) {
+ m_pVertScrollBar->LockUpdate();
+ m_pVertScrollBar->SetRange(0, -1);
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE);
+ m_pVertScrollBar->UnlockUpdate();
+ m_pVertScrollBar->Update();
+ pRepaint = (IFWL_ScrollBar*)m_pVertScrollBar;
+ }
+ }
+ return pRepaint;
+}
+FX_BOOL CFWL_EditImp::IsShowScrollBar(FX_BOOL bVert)
+{
+ FX_BOOL bShow = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == FWL_WGTSTATE_Focused : TRUE;
+ if (bVert) {
+ return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) &&
+ (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) && IsContentHeightOverflow();
+ }
+ return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) && (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine);
+}
+FX_BOOL CFWL_EditImp::IsContentHeightOverflow()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pEdtEngine, FALSE);
+ IFDE_TxtEdtPage *pPage = m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_VALUE_IF_FAIL(pPage, FALSE);
+ return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f;
+}
+FX_INT32 CFWL_EditImp::AddDoRecord(FX_BSTR bsDoRecord)
+{
+ FX_INT32 nCount = m_RecordArr.GetSize();
+ if (m_iCurRecord == nCount - 1) {
+ if (nCount == m_iMaxRecord) {
+ m_RecordArr.RemoveAt(0);
+ m_iCurRecord --;
+ }
+ } else {
+ for (FX_INT32 i = nCount - 1; i > m_iCurRecord; i --) {
+ m_RecordArr.RemoveAt(i);
+ }
+ }
+ m_RecordArr.Add(bsDoRecord);
+ return m_iCurRecord = m_RecordArr.GetSize() - 1;
+}
+void CFWL_EditImp::Layout()
+{
+ GetClientRect(m_rtClient);
+ m_rtEngine = m_rtClient;
+ FX_FLOAT *pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_IF_FAIL(pfWidth);
+ FX_FLOAT fWidth = *pfWidth;
+ if (!m_pOuter) {
+ CFX_RectF* pUIMargin = (CFX_RectF*)GetThemeCapacity(FWL_WGTCAPACITY_UIMargin);
+ if (pUIMargin) {
+ m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, pUIMargin->height);
+ }
+ } else if (m_pOuter->GetClassID() == FWL_CLASSHASH_DateTimePicker) {
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pOuter;
+ CFX_RectF* pUIMargin = (CFX_RectF*)m_pOuter->GetThemeProvider()->GetCapacity(&part, FWL_WGTCAPACITY_UIMargin);
+ if (pUIMargin) {
+ m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, pUIMargin->height);
+ }
+ }
+ FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
+ FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
+ if (bShowVertScrollbar) {
+ InitScrollBar();
+ CFX_RectF rtVertScr;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
+ rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin,
+ m_rtClient.top, fWidth, m_rtClient.height);
+ } else {
+ rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, m_rtClient.height);
+ if (bShowHorzScrollbar) {
+ rtVertScr.height -= fWidth;
+ }
+ m_rtEngine.width -= fWidth;
+ }
+ m_pVertScrollBar->SetWidgetRect(rtVertScr);
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ m_pVertScrollBar->Update();
+ } else if (m_pVertScrollBar) {
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+ if (bShowHorzScrollbar) {
+ InitScrollBar(FALSE);
+ CFX_RectF rtHoriScr;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
+ rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin, m_rtClient.width, fWidth);
+ } else {
+ rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, m_rtClient.width, fWidth);
+ if (bShowVertScrollbar) {
+ rtHoriScr.width -= fWidth;
+ }
+ m_rtEngine.height -= fWidth;
+ }
+ m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ m_pHorzScrollBar->Update();
+ } else if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+}
+void CFWL_EditImp::LayoutScrollBar()
+{
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) == 0) {
+ return;
+ }
+ FX_FLOAT* pfWidth = NULL;
+ FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE);
+ FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE);
+ if (bShowVertScrollbar) {
+ if (!m_pVertScrollBar) {
+ pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
+ InitScrollBar();
+ CFX_RectF rtVertScr;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
+ rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin,
+ m_rtClient.top, fWidth, m_rtClient.height);
+ } else {
+ rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, m_rtClient.height);
+ if (bShowHorzScrollbar) {
+ rtVertScr.height -= fWidth;
+ }
+ }
+ m_pVertScrollBar->SetWidgetRect(rtVertScr);
+ m_pVertScrollBar->Update();
+ }
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ } else if (m_pVertScrollBar) {
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+ if (bShowHorzScrollbar) {
+ if (!m_pHorzScrollBar) {
+ pfWidth = !pfWidth ? (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth) : pfWidth;
+ FX_FLOAT fWidth = pfWidth ? *pfWidth : 0;
+ InitScrollBar(FALSE);
+ CFX_RectF rtHoriScr;
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) {
+ rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin, m_rtClient.width, fWidth);
+ } else {
+ rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, m_rtClient.width, fWidth);
+ if (bShowVertScrollbar) {
+ rtHoriScr.width -= (fWidth);
+ }
+ }
+ m_pHorzScrollBar->SetWidgetRect(rtHoriScr);
+ m_pHorzScrollBar->Update();
+ }
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ } else if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+ if (bShowVertScrollbar || bShowHorzScrollbar) {
+ UpdateScroll();
+ }
+}
+void CFWL_EditImp::DeviceToEngine(CFX_PointF &pt)
+{
+ pt.x += -m_rtEngine.left + m_fScrollOffsetX;
+ pt.y += -m_rtEngine.top - m_fVAlignOffset + m_fScrollOffsetY;
+}
+void CFWL_EditImp::InitScrollBar(FX_BOOL bVert )
+{
+ if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {
+ return;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz;
+ prop.m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible;
+ prop.m_pParent = m_pInterface;
+ prop.m_pThemeProvider = m_pProperties->m_pThemeProvider;
+ IFWL_ScrollBar *pScrollBar = IFWL_ScrollBar::Create();
+ pScrollBar->Initialize(prop, m_pInterface);
+ bVert ? (m_pVertScrollBar = pScrollBar) : (m_pHorzScrollBar = pScrollBar);
+}
+void CFWL_EditImp::InitEngine()
+{
+ if (m_pEdtEngine) {
+ return;
+ }
+ m_pEdtEngine = IFDE_TxtEdtEngine::Create();
+}
+extern FX_BOOL FWL_ShowCaret(IFWL_Widget *pWidget, FX_BOOL bVisible, const CFX_RectF *pRtAnchor);
+void CFWL_EditImp::ShowCaret(FX_BOOL bVisible, CFX_RectF *pRect )
+{
+ if (m_pCaret) {
+ m_pCaret->ShowCaret(bVisible);
+ if (bVisible && !pRect->IsEmpty()) {
+ m_pCaret->SetWidgetRect(*pRect);
+ }
+ Repaint(&m_rtEngine);
+ } else {
+ IFWL_Widget *pOuter = (IFWL_Widget*)m_pInterface;
+ if (bVisible) {
+ pRect->Offset(m_pProperties->m_rtWidget.left, m_pProperties->m_rtWidget.top);
+ }
+ while (pOuter->GetOuter()) {
+ pOuter = pOuter->GetOuter();
+ if (bVisible) {
+ CFX_RectF rtOuter;
+ pOuter->GetWidgetRect(rtOuter);
+ pRect->Offset(rtOuter.left, rtOuter.top);
+ }
+ }
+ FWL_ShowCaret(pOuter, bVisible, pRect);
+ }
+}
+FX_BOOL CFWL_EditImp::ValidateNumberChar(FX_WCHAR cNum)
+{
+ if (!m_pEdtEngine) {
+ return FALSE;
+ }
+ if (!m_bSetRange) {
+ return TRUE;
+ }
+ CFX_WideString wsOld, wsText;
+ m_pEdtEngine->GetText(wsText, 0);
+ if (wsText.IsEmpty()) {
+ if (cNum == L'0') {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ FX_INT32 caretPos = m_pEdtEngine->GetCaretPos();
+ FX_INT32 iSel = CountSelRanges();
+ if (iSel == 0) {
+ if (cNum == L'0' && caretPos == 0) {
+ return FALSE;
+ }
+ FX_INT32 nLen = wsText.GetLength();
+ CFX_WideString l = wsText.Mid(0, caretPos);
+ CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos);
+ CFX_WideString wsNew = l + cNum + r;
+ if (wsNew.GetInteger() <= m_iMax) {
+ return TRUE;
+ }
+ } else {
+ if (wsText.GetInteger() <= m_iMax) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CFWL_EditImp::InitCaret()
+{
+ if (!m_pCaret) {
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) {
+ m_pCaret = IFWL_Caret::Create();
+ m_pCaret->Initialize(m_pInterface);
+ m_pCaret->SetParent(m_pInterface);
+ m_pCaret->SetStates(m_pProperties->m_dwStates);
+ }
+ } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) == 0) {
+ m_pCaret->Release();
+ m_pCaret = NULL;
+ }
+}
+void CFWL_EditImp::ClearRecord()
+{
+ m_iCurRecord = -1;
+ m_RecordArr.RemoveAll();
+}
+void CFWL_EditImp::ProcessInsertError(FX_INT32 iError)
+{
+ switch (iError) {
+ case -2: {
+ CFWL_EvtEdtTextFull textFullEvent;
+ textFullEvent.m_pSrcTarget = m_pInterface;
+ DispatchEvent(&textFullEvent);
+ break;
+ }
+ default: {
+ }
+ }
+}
+CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_EditImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_INT32 iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_Activate: {
+ DoActivate((CFWL_MsgActivate*)pMessage);
+ break;
+ }
+ case FWL_MSGHASH_Deactivate: {
+ DoDeactivate((CFWL_MsgDeactivate*)pMessage);
+ break;
+ }
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch(dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonDblClk: {
+ OnButtonDblClk(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_RButtonDown: {
+ DoButtonDown(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ CFWL_MsgKey *pKey = (CFWL_MsgKey*)pMessage;
+ FX_DWORD dwCmd = pKey->m_dwCmd;
+ if (dwCmd == FWL_MSGKEYCMD_KeyDown) {
+ OnKeyDown(pKey);
+ } else if (dwCmd == FWL_MSGKEYCMD_Char) {
+ OnChar(pKey);
+ }
+ break;
+ }
+ default: {
+ iRet = 0;
+ }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+ return iRet;
+}
+FWL_ERR CFWL_EditImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pEvent, FWL_ERR_Indefinite);
+ FX_DWORD dwHashCode = pEvent->GetClassID();
+ if (dwHashCode != FWL_EVTHASH_Scroll) {
+ return FWL_ERR_Succeeded;
+ }
+ IFWL_Widget *pSrcTarget = pEvent->m_pSrcTarget;
+ if ((pSrcTarget == (IFWL_Widget*)m_pOwner->m_pVertScrollBar && m_pOwner->m_pVertScrollBar) || (pSrcTarget == (IFWL_Widget*)m_pOwner->m_pHorzScrollBar && m_pOwner->m_pHorzScrollBar)) {
+ FX_DWORD dwScrollCode = ((CFWL_EvtScroll*)pEvent)->m_iScrollCode;
+ FX_FLOAT fPos = ((CFWL_EvtScroll*)pEvent)->m_fPos;
+ OnScroll((IFWL_ScrollBar*)pSrcTarget, dwScrollCode, fPos);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_EditImpDelegate::DoActivate(CFWL_MsgActivate *pMsg)
+{
+ m_pOwner->m_pProperties->m_dwStates |= ~FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_EditImpDelegate::DoDeactivate(CFWL_MsgDeactivate *pMsg)
+{
+ m_pOwner->m_pProperties->m_dwStates &= FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_EditImpDelegate::DoButtonDown(CFWL_MsgMouse *pMsg)
+{
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ if (!m_pOwner->m_pEdtEngine) {
+ m_pOwner->UpdateEditEngine();
+ }
+ IFDE_TxtEdtPage *pPage = m_pOwner->m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_IF_FAIL(pPage);
+ CFX_PointF pt;
+ pt.Set(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->DeviceToEngine(pt);
+ FX_BOOL bBefore = TRUE;
+ FX_INT32 nIndex = pPage->GetCharIndex(pt, bBefore);
+ if (nIndex < 0) {
+ nIndex = 0;
+ }
+ m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
+}
+void CFWL_EditImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)
+{
+ FX_DWORD dwStyleEx = m_pOwner->GetStylesEx();
+ FX_BOOL bRepaint = dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret;
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ if (!m_pOwner->m_pEdtEngine) {
+ m_pOwner->UpdateEditEngine();
+ }
+ m_pOwner->UpdateVAlignment();
+ m_pOwner->UpdateOffset();
+ m_pOwner->UpdateCaret();
+ } else if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ m_pOwner->ShowCaret(FALSE);
+ if (m_pOwner->m_pEdtEngine && (dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) {
+ FX_INT32 nSel = m_pOwner->CountSelRanges();
+ if (nSel > 0) {
+ m_pOwner->ClearSelections();
+ bRepaint = TRUE;
+ }
+ m_pOwner->SetCaretPos(0);
+ m_pOwner->UpdateOffset();
+ }
+ m_pOwner->ClearRecord();
+ }
+ m_pOwner->LayoutScrollBar();
+ if (bRepaint) {
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0,
+ 0,
+ m_pOwner->m_pProperties->m_rtWidget.width,
+ m_pOwner->m_pProperties->m_rtWidget.height);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+void CFWL_EditImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ DoCursor(pMsg);
+ if(m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ return;
+ }
+ m_pOwner->m_bLButtonDown = TRUE;
+ m_pOwner->SetGrab(TRUE);
+ DoButtonDown(pMsg);
+ FX_INT32 nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
+ FX_BOOL bRepaint = FALSE;
+ FX_INT32 iCount = m_pOwner->m_pEdtEngine->CountSelRanges();
+ if (iCount > 0) {
+ m_pOwner->m_pEdtEngine->ClearSelection();
+ bRepaint = TRUE;
+ }
+ FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
+ if (bShift && m_pOwner->m_nSelStart != nIndex) {
+ FX_INT32 iStart = FX_MIN(m_pOwner->m_nSelStart, nIndex);
+ FX_INT32 iEnd = FX_MAX(m_pOwner->m_nSelStart, nIndex);
+ m_pOwner->m_pEdtEngine->AddSelRange(iStart, iEnd - iStart);
+ bRepaint = TRUE;
+ } else {
+ m_pOwner->m_nSelStart = nIndex;
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&m_pOwner->m_rtEngine);
+ }
+}
+void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ DoCursor(pMsg);
+ m_pOwner->m_bLButtonDown = FALSE;
+ m_pOwner->SetGrab(FALSE);
+}
+void CFWL_EditImpDelegate::OnButtonDblClk(CFWL_MsgMouse *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);
+ DoCursor(pMsg);
+ IFDE_TxtEdtPage *pPage = m_pOwner->m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_IF_FAIL(pPage);
+ CFX_PointF pt;
+ pt.Set(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->DeviceToEngine(pt);
+ FX_INT32 nCount = 0;
+ FX_INT32 nIndex = pPage->SelectWord(pt, nCount);
+ if (nIndex < 0) {
+ return;
+ }
+ m_pOwner->m_pEdtEngine->AddSelRange(nIndex, nCount);
+ m_pOwner->m_pEdtEngine->SetCaretPos(nIndex + nCount - 1, FALSE);
+ m_pOwner->Repaint(&m_pOwner->m_rtEngine);
+}
+void CFWL_EditImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);
+ DoCursor(pMsg);
+ if (m_pOwner->m_nSelStart == -1 || !m_pOwner->m_bLButtonDown) {
+ return;
+ }
+ IFDE_TxtEdtPage *pPage = m_pOwner->m_pEdtEngine->GetPage(0);
+ _FWL_RETURN_IF_FAIL(pPage);
+ CFX_PointF pt;
+ pt.Set(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->DeviceToEngine(pt);
+ FX_BOOL bBefore = TRUE;
+ FX_INT32 nIndex = pPage->GetCharIndex(pt, bBefore);
+ m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore);
+ nIndex = m_pOwner->m_pEdtEngine->GetCaretPos();
+ m_pOwner->m_pEdtEngine->ClearSelection();
+ if (nIndex != m_pOwner->m_nSelStart) {
+ FX_INT32 nLen = m_pOwner->m_pEdtEngine->GetTextLength();
+ if (m_pOwner->m_nSelStart >= nLen) {
+ m_pOwner->m_nSelStart = nLen;
+ }
+ m_pOwner->m_pEdtEngine->AddSelRange(FX_MIN(m_pOwner->m_nSelStart, nIndex), FXSYS_abs(nIndex - m_pOwner->m_nSelStart));
+ }
+}
+void CFWL_EditImpDelegate::OnKeyDown(CFWL_MsgKey *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);
+ FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone;
+ FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
+ FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl;
+ FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
+ switch (dwKeyCode) {
+ case FWL_VKEY_Left: {
+ MoveCaret = MC_Left;
+ break;
+ }
+ case FWL_VKEY_Right: {
+ MoveCaret = MC_Right;
+ break;
+ }
+ case FWL_VKEY_Up: {
+ MoveCaret = MC_Up;
+ break;
+ }
+ case FWL_VKEY_Down: {
+ MoveCaret = MC_Down;
+ break;
+ }
+ case FWL_VKEY_Home: {
+ if (bCtrl) {
+ MoveCaret = MC_Home;
+ } else {
+ MoveCaret = MC_LineStart;
+ }
+ break;
+ }
+ case FWL_VKEY_End: {
+ if (bCtrl) {
+ MoveCaret = MC_End;
+ } else {
+ MoveCaret = MC_LineEnd;
+ }
+ break;
+ }
+ case FWL_VKEY_Insert: {
+ break;
+ }
+ case FWL_VKEY_Delete: {
+ if ( (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)
+ || (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ break;
+ }
+ FX_INT32 nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
+#if (_FX_OS_==_FX_MACOSX_)
+ m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
+#else
+ m_pOwner->m_pEdtEngine->Delete(nCaret);
+#endif
+ break;
+ }
+ case FWL_VKEY_F2: {
+ break;
+ }
+ case FWL_VKEY_Tab: {
+ m_pOwner->DispatchKeyEvent(pMsg);
+ break;
+ }
+ default: {
+#if (_FX_OS_==_FX_MACOSX_)
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
+#else
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
+#endif
+ {
+ if (dwKeyCode == 0x43 || dwKeyCode == 0x63) {
+ m_pOwner->DoClipboard(1);
+ return;
+ }
+ if (dwKeyCode == 0x58 || dwKeyCode == 0x78) {
+ m_pOwner->DoClipboard(2);
+ return;
+ }
+ if (dwKeyCode == 0x56 || dwKeyCode == 0x76) {
+ m_pOwner->DoClipboard(3);
+ return;
+ }
+ }
+ }
+ }
+ if (MoveCaret != MC_MoveNone) {
+ m_pOwner->m_pEdtEngine->MoveCaretPos(MoveCaret, bShift, bCtrl);
+ }
+}
+void CFWL_EditImpDelegate::OnChar(CFWL_MsgKey *pMsg)
+{
+ if ( (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)
+ || ( m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) {
+ return;
+ }
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pEdtEngine);
+ FX_INT32 iError = 0;
+ FX_WCHAR c = (FX_WCHAR)pMsg->m_dwKeyCode;
+ FX_INT32 nCaret = m_pOwner->m_pEdtEngine->GetCaretPos();
+ switch (c) {
+ case FWL_VKEY_Back: {
+ m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE);
+ break;
+ }
+ case 0x0A: {
+ break;
+ }
+ case FWL_VKEY_Escape: {
+ break;
+ }
+ case FWL_VKEY_Tab: {
+ iError = m_pOwner->m_pEdtEngine->Insert(nCaret, FX_LPCWSTR(L"\t"), 1);
+ break;
+ }
+ case FWL_VKEY_Return: {
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_WantReturn) {
+ iError = m_pOwner->m_pEdtEngine->Insert(nCaret, FX_LPCWSTR(L"\n"), 1);
+ }
+ break;
+ }
+ default: {
+ if (!m_pOwner->m_pWidgetMgr->IsFormDisabled()) {
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) {
+ if (((pMsg->m_dwKeyCode < FWL_VKEY_0) && (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) || pMsg->m_dwKeyCode > FWL_VKEY_9) {
+ break;
+ }
+ if (!m_pOwner->ValidateNumberChar(c)) {
+ break;
+ }
+ }
+ }
+#if (_FX_OS_==_FX_MACOSX_)
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Command)
+#else
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl)
+#endif
+ {
+ break;
+ }
+ iError = m_pOwner->m_pEdtEngine->Insert(nCaret, &c, 1);
+ break;
+ }
+ }
+ if (iError < 0) {
+ m_pOwner->ProcessInsertError(iError);
+ }
+}
+FX_BOOL CFWL_EditImpDelegate::OnScroll(IFWL_ScrollBar *pScrollBar, FX_DWORD dwCode, FX_FLOAT fPos)
+{
+ CFX_SizeF fs;
+ pScrollBar->GetRange(fs.x, fs.y);
+ FX_FLOAT iCurPos = pScrollBar->GetPos();
+ FX_FLOAT fStep = pScrollBar->GetStepSize();
+ switch (dwCode) {
+ case FWL_SCBCODE_Min: {
+ fPos = fs.x;
+ break;
+ }
+ case FWL_SCBCODE_Max: {
+ fPos = fs.y;
+ break;
+ }
+ case FWL_SCBCODE_StepBackward: {
+ fPos -= fStep;
+ if (fPos < fs.x + fStep / 2) {
+ fPos = fs.x;
+ }
+ break;
+ }
+ case FWL_SCBCODE_StepForward: {
+ fPos += fStep;
+ if (fPos > fs.y - fStep / 2) {
+ fPos = fs.y;
+ }
+ break;
+ }
+ case FWL_SCBCODE_PageBackward: {
+ fPos -= pScrollBar->GetPageSize();
+ if (fPos < fs.x) {
+ fPos = fs.x;
+ }
+ break;
+ }
+ case FWL_SCBCODE_PageForward: {
+ fPos += pScrollBar->GetPageSize();
+ if (fPos > fs.y) {
+ fPos = fs.y;
+ }
+ break;
+ }
+ case FWL_SCBCODE_Pos:
+ case FWL_SCBCODE_TrackPos: {
+ break;
+ }
+ case FWL_SCBCODE_EndScroll: {
+ return FALSE;
+ }
+ default: {
+ }
+ }
+ if (iCurPos != fPos) {
+ pScrollBar->SetPos(fPos);
+ pScrollBar->SetTrackPos(fPos);
+ m_pOwner->UpdateOffset(pScrollBar, fPos - iCurPos);
+ if (m_pOwner->m_pEdtEngine) {
+ m_pOwner->UpdateCaret();
+ }
+ CFX_RectF rect;
+ m_pOwner->GetWidgetRect(rect);
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+ return TRUE;
+}
+void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ IFWL_AdapterCursorMgr *pCursorMgr = pNative->GetCursorMgr();
+ if (NULL != pCursorMgr) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_InputBeam);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ }
+ }
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_formproxyimp.cpp b/xfa/src/fwl/src/basewidget/fwl_formproxyimp.cpp
new file mode 100644
index 0000000000..ced1fbe6f9
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_formproxyimp.cpp
@@ -0,0 +1,71 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_panelimp.h"
+#include "../core/include/fwl_formimp.h"
+#include "include/fwl_formproxyimp.h"
+CFWL_FormProxyImp::CFWL_FormProxyImp(IFWL_Widget *pOuter )
+ : CFWL_FormImp(pOuter)
+{
+}
+CFWL_FormProxyImp::CFWL_FormProxyImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_FormImp(properties, pOuter)
+{
+}
+CFWL_FormProxyImp::~CFWL_FormProxyImp()
+{
+}
+FWL_ERR CFWL_FormProxyImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_FormProxy;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_FormProxyImp::GetClassID() const
+{
+ return FWL_CLASSHASH_FormProxy;
+}
+FX_BOOL CFWL_FormProxyImp::IsInstance(FX_WSTR wsClass) const
+{
+ if (wsClass == CFX_WideStringC(FWL_CLASS_FormProxy)) {
+ return TRUE;
+ }
+ return CFWL_FormImp::IsInstance(wsClass);
+}
+FWL_ERR CFWL_FormProxyImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate *)FX_NEW CFWL_FormProxyImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_FormProxyImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_FormProxyImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_FormProxyImp::Update()
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_FormProxyImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return FWL_ERR_Succeeded;
+}
+CFWL_FormProxyImpDelegate::CFWL_FormProxyImpDelegate(CFWL_FormProxyImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_FormProxyImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pOuter->SetDelegate(NULL);
+ return pDelegate->OnProcessMessage(pMessage);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_listboximp.cpp b/xfa/src/fwl/src/basewidget/fwl_listboximp.cpp
new file mode 100644
index 0000000000..bafb964ee6
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_listboximp.cpp
@@ -0,0 +1,1255 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_scrollbarimp.h"
+#include "include/fwl_listboximp.h"
+#define FWL_LISTBOX_ItemTextMargin 2
+IFWL_ListBox* IFWL_ListBox::Create()
+{
+ return new IFWL_ListBox;
+}
+IFWL_ListBox::IFWL_ListBox()
+{
+ m_pData = NULL;
+}
+IFWL_ListBox::~IFWL_ListBox()
+{
+ if (m_pData) {
+ delete (CFWL_ListBoxImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_ListBox::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ListBoxImp(pOuter);
+ ((CFWL_ListBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ListBoxImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_ListBox::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ListBoxImp(properties, pOuter);
+ ((CFWL_ListBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ListBoxImp*)m_pData)->Initialize();
+}
+FX_INT32 IFWL_ListBox::CountSelItems()
+{
+ return ((CFWL_ListBoxImp*)m_pData)->CountSelItems();
+}
+FWL_HLISTITEM IFWL_ListBox::GetSelItem(FX_INT32 nIndexSel)
+{
+ return ((CFWL_ListBoxImp*)m_pData)->GetSelItem(nIndexSel);
+}
+FX_INT32 IFWL_ListBox::GetSelIndex(FX_INT32 nIndex)
+{
+ return ((CFWL_ListBoxImp*)m_pData)->GetSelIndex(nIndex);
+}
+FWL_ERR IFWL_ListBox::SetSelItem(FWL_HLISTITEM hItem, FX_BOOL bSelect)
+{
+ return ((CFWL_ListBoxImp*)m_pData)->SetSelItem(hItem, bSelect);
+}
+FWL_ERR IFWL_ListBox::GetItemText(FWL_HLISTITEM hItem, CFX_WideString &wsText)
+{
+ return ((CFWL_ListBoxImp*)m_pData)->GetItemText(hItem, wsText);
+}
+FWL_ERR IFWL_ListBox::GetScrollPos(FX_FLOAT &fPos, FX_BOOL bVert)
+{
+ return ((CFWL_ListBoxImp*)m_pData)->GetScrollPos(fPos, bVert);
+}
+FWL_ERR* IFWL_ListBox::Sort(IFWL_ListBoxCompare *pCom)
+{
+ return ((CFWL_ListBoxImp*)m_pData)->Sort(pCom);
+}
+CFWL_ListBoxImp::CFWL_ListBoxImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_pHorzScrollBar(NULL)
+ , m_pVertScrollBar(NULL)
+ , m_dwTTOStyles(0)
+ , m_iTTOAligns(0)
+ , m_hAnchor(NULL)
+ , m_fScorllBarWidth(0)
+ , m_bLButtonDown(FALSE)
+ , m_pScrollBarTP(NULL)
+{
+ m_rtClient.Reset();
+ m_rtConent.Reset();
+ m_rtStatic.Reset();
+}
+CFWL_ListBoxImp::CFWL_ListBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_pHorzScrollBar(NULL)
+ , m_pVertScrollBar(NULL)
+ , m_dwTTOStyles(0)
+ , m_iTTOAligns(0)
+ , m_hAnchor(NULL)
+ , m_fScorllBarWidth(0)
+ , m_bLButtonDown(FALSE)
+ , m_pScrollBarTP(NULL)
+{
+ m_rtClient.Reset();
+ m_rtConent.Reset();
+ m_rtStatic.Reset();
+}
+CFWL_ListBoxImp::~CFWL_ListBoxImp()
+{
+ if (m_pVertScrollBar) {
+ m_pVertScrollBar->Release();
+ m_pVertScrollBar = NULL;
+ }
+ if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->Release();
+ m_pHorzScrollBar = NULL;
+ }
+}
+FWL_ERR CFWL_ListBoxImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_ListBox;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ListBoxImp::GetClassID() const
+{
+ return FWL_CLASSHASH_ListBox;
+}
+FWL_ERR CFWL_ListBoxImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_ListBoxImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBoxImp::Finalize()
+{
+ if (m_pVertScrollBar) {
+ m_pVertScrollBar->Finalize();
+ }
+ if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->Finalize();
+ }
+ if (m_pDelegate) {
+ delete (CFWL_ListBoxImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_ListBoxImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ CFX_SizeF fs = CalcSize(TRUE);
+ rect.Set(0, 0, fs.x, fs.y);
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBoxImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ m_iTTOAligns = FDE_TTOALIGNMENT_Center;
+ switch(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_AlignMask) {
+ case FWL_STYLEEXT_LTB_LeftAlign: {
+ m_iTTOAligns = FDE_TTOALIGNMENT_CenterLeft;
+ break;
+ }
+ case FWL_STYLEEXT_LTB_RightAlign: {
+ m_iTTOAligns = FDE_TTOALIGNMENT_CenterRight;
+ break;
+ }
+ case FWL_STYLEEXT_LTB_CenterAlign:
+ default: {
+ m_iTTOAligns = FDE_TTOALIGNMENT_Center;
+ }
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
+ }
+ m_dwTTOStyles |= FDE_TTOSTYLE_SingleLine;
+ m_fScorllBarWidth = GetScrollWidth();
+ SortItem();
+ CalcSize();
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ListBoxImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (IsShowScrollBar(FALSE)) {
+ CFX_RectF rect;
+ m_pHorzScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_HScrollBar;
+ }
+ }
+ if (IsShowScrollBar(TRUE)) {
+ CFX_RectF rect;
+ m_pVertScrollBar->GetWidgetRect(rect);
+ if (rect.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_VScrollBar;
+ }
+ }
+ if (m_rtClient.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ return FWL_WGTHITTEST_Unknown;
+}
+FWL_ERR CFWL_ListBoxImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ pGraphics->SaveGraphState();
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_LTB_Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_LTB_Edge, pTheme, pMatrix);
+ }
+ CFX_RectF rtClip(m_rtConent);
+ if (IsShowScrollBar(FALSE)) {
+ rtClip.height -= m_fScorllBarWidth;
+ }
+ if (IsShowScrollBar(TRUE)) {
+ rtClip.width -= m_fScorllBarWidth;
+ }
+ if (pMatrix) {
+ pMatrix->TransformRect(rtClip);
+ }
+ pGraphics->SetClipRect(rtClip);
+ if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_NoBackground) == 0) {
+ DrawBkground(pGraphics, pTheme, pMatrix);
+ }
+ DrawItems(pGraphics, pTheme, pMatrix);
+ pGraphics->RestoreGraphState();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBoxImp::SetThemeProvider(IFWL_ThemeProvider *pThemeProvider)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pThemeProvider, FWL_ERR_Indefinite);
+ if (!pThemeProvider->IsValidWidget(m_pInterface)) {
+ m_pScrollBarTP = pThemeProvider;
+ return FWL_ERR_Succeeded;
+ }
+ m_pProperties->m_pThemeProvider = pThemeProvider;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ListBoxImp::CountSelItems()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, 0);
+ FX_INT32 iRet = 0;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ if (!hItem) {
+ continue;
+ }
+ FX_DWORD dwStyle = pData->GetItemStyles(m_pInterface, hItem);
+ if (dwStyle & FWL_ITEMSTATE_LTB_Selected) {
+ iRet ++;
+ }
+ }
+ return iRet;
+}
+FWL_HLISTITEM CFWL_ListBoxImp::GetSelItem(FX_INT32 nIndexSel)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, NULL);
+ FX_INT32 index = 0;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ if (!hItem) {
+ return NULL;
+ }
+ FX_DWORD dwStyle = pData->GetItemStyles(m_pInterface, hItem);
+ if (dwStyle & FWL_ITEMSTATE_LTB_Selected) {
+ if (index == nIndexSel) {
+ return hItem;
+ } else {
+ index ++;
+ }
+ }
+ }
+ return NULL;
+}
+FX_INT32 CFWL_ListBoxImp::GetSelIndex(FX_INT32 nIndex)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, -1);
+ FX_INT32 index = 0;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ if (!hItem) {
+ return -1;
+ }
+ FX_DWORD dwStyle = pData->GetItemStyles(m_pInterface, hItem);
+ if (dwStyle & FWL_ITEMSTATE_LTB_Selected) {
+ if (index == nIndex) {
+ return i;
+ } else {
+ index ++;
+ }
+ }
+ }
+ return -1;
+}
+FWL_ERR CFWL_ListBoxImp::SetSelItem(FWL_HLISTITEM hItem, FX_BOOL bSelect )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FWL_ERR_Indefinite);
+ if (!hItem) {
+ if (bSelect) {
+ SelectAll();
+ } else {
+ ClearSelection();
+ SetFocusItem(NULL);
+ }
+ return FWL_ERR_Indefinite;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) {
+ SetSelectionDirect(hItem, bSelect);
+ } else {
+ SetSelection(hItem, hItem, bSelect);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBoxImp::GetItemText(FWL_HLISTITEM hItem, CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FWL_ERR_Indefinite);
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ pData->GetItemText(m_pInterface, hItem, wsText);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBoxImp::GetScrollPos(FX_FLOAT &fPos, FX_BOOL bVert )
+{
+ if ((bVert && IsShowScrollBar(TRUE)) || (!bVert && IsShowScrollBar(FALSE))) {
+ IFWL_ScrollBar *pScrollBar = bVert ? m_pVertScrollBar : m_pHorzScrollBar;
+ fPos = pScrollBar->GetPos();
+ return FWL_ERR_Succeeded;
+ }
+ return FWL_ERR_Indefinite;
+}
+FWL_ERR* CFWL_ListBoxImp::Sort(IFWL_ListBoxCompare *pCom)
+{
+ FWL_HLISTITEM hTemp;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 sz = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < sz - 1; i++) {
+ for (FX_INT32 j = i + 1; j < sz; j++) {
+ if (pCom->Compare(pData->GetItem(m_pInterface, i), pData->GetItem(m_pInterface, j)) > 0) {
+ hTemp = pData->GetItem(m_pInterface, i);
+ pData->SetItemIndex(m_pInterface, pData->GetItem(m_pInterface, j), i);
+ pData->SetItemIndex(m_pInterface, hTemp, j);
+ }
+ }
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_HLISTITEM CFWL_ListBoxImp::GetItem(FWL_HLISTITEM hItem, FX_DWORD dwKeyCode)
+{
+ FWL_HLISTITEM hRet = NULL;
+ switch(dwKeyCode) {
+ case FWL_VKEY_Up:
+ case FWL_VKEY_Down:
+ case FWL_VKEY_Home:
+ case FWL_VKEY_End: {
+ FX_BOOL bUp = dwKeyCode == FWL_VKEY_Up;
+ FX_BOOL bDown = dwKeyCode == FWL_VKEY_Down;
+ FX_BOOL bHome = dwKeyCode == FWL_VKEY_Home;
+ FX_BOOL bEnd = dwKeyCode == FWL_VKEY_End;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iDstItem = -1;
+ if (bUp || bDown) {
+ FX_INT32 index = pData->GetItemIndex(m_pInterface, hItem);
+ iDstItem = dwKeyCode == FWL_VKEY_Up ? index - 1 : index + 1;
+ } else if (bHome) {
+ iDstItem = 0;
+ } else {
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ iDstItem = iCount - 1;
+ }
+ hRet = pData->GetItem(m_pInterface, iDstItem);
+ break;
+ }
+ default: {
+ }
+ }
+ return hRet;
+}
+void CFWL_ListBoxImp::SetSelection(FWL_HLISTITEM hStart, FWL_HLISTITEM hEnd, FX_BOOL bSelected)
+{
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iStart = pData->GetItemIndex(m_pInterface, hStart);
+ FX_INT32 iEnd = pData->GetItemIndex(m_pInterface, hEnd);
+ if (iStart > iEnd) {
+ FX_INT32 iTemp = iStart;
+ iStart = iEnd;
+ iEnd = iTemp;
+ }
+ if (bSelected) {
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i++ ) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ SetSelectionDirect(hItem, FALSE);
+ }
+ }
+ for (; iStart <= iEnd; iStart++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, iStart);
+ SetSelectionDirect(hItem, bSelected);
+ }
+}
+void CFWL_ListBoxImp::SetSelectionDirect(FWL_HLISTITEM hItem, FX_BOOL bSelect)
+{
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_DWORD dwOldStyle = pData->GetItemStyles(m_pInterface, hItem);
+ bSelect ? dwOldStyle |= FWL_ITEMSTATE_LTB_Selected
+ : dwOldStyle &= ~FWL_ITEMSTATE_LTB_Selected;
+ pData->SetItemStyles(m_pInterface, hItem, dwOldStyle);
+}
+FX_BOOL CFWL_ListBoxImp::IsItemSelected(FWL_HLISTITEM hItem)
+{
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_DWORD dwState = pData->GetItemStyles(m_pInterface, hItem);
+ return (dwState & FWL_ITEMSTATE_LTB_Selected) != 0;
+}
+void CFWL_ListBoxImp::ClearSelection()
+{
+ FX_BOOL bMulti = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i++ ) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ FX_DWORD dwState = pData->GetItemStyles(m_pInterface, hItem);
+ FX_BOOL bFindSel = dwState & FWL_ITEMSTATE_LTB_Selected;
+ if (!bFindSel) {
+ continue;
+ }
+ SetSelectionDirect(hItem, FALSE);
+ if (!bMulti) {
+ return;
+ }
+ }
+}
+void CFWL_ListBoxImp::SelectAll()
+{
+ FX_BOOL bMulti = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection;
+ if (!bMulti) {
+ return;
+ }
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ if (iCount > 0) {
+ FWL_HLISTITEM hItemStart = pData->GetItem(m_pInterface, 0);
+ FWL_HLISTITEM hItemEnd = pData->GetItem(m_pInterface, iCount - 1);
+ SetSelection(hItemStart, hItemEnd, FALSE);
+ }
+}
+FWL_HLISTITEM CFWL_ListBoxImp::GetFocusedItem()
+{
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, NULL);
+ if (pData->GetItemStyles(m_pInterface, hItem) & FWL_ITEMSTATE_LTB_Focused) {
+ return hItem;
+ }
+ }
+ return NULL;
+}
+void CFWL_ListBoxImp::SetFocusItem(FWL_HLISTITEM hItem)
+{
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FWL_HLISTITEM hFocus = GetFocusedItem();
+ if (hItem != hFocus) {
+ if (hFocus) {
+ FX_DWORD dwStyle = pData->GetItemStyles(m_pInterface, hFocus);
+ dwStyle &= ~FWL_ITEMSTATE_LTB_Focused;
+ pData->SetItemStyles(m_pInterface, hFocus, dwStyle);
+ }
+ if (hItem) {
+ FX_DWORD dwStyle = pData->GetItemStyles(m_pInterface, hItem);
+ dwStyle |= FWL_ITEMSTATE_LTB_Focused;
+ pData->SetItemStyles(m_pInterface, hItem, dwStyle);
+ }
+ }
+}
+FWL_HLISTITEM CFWL_ListBoxImp::GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy)
+{
+ fx -= m_rtConent.left, fy -= m_rtConent.top;
+ FX_FLOAT fPosX = 0.0f;
+ if (m_pHorzScrollBar) {
+ fPosX = m_pHorzScrollBar->GetPos();
+ }
+ FX_FLOAT fPosY = 0.0;
+ if (m_pVertScrollBar) {
+ fPosY = m_pVertScrollBar->GetPos();
+ }
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 nCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ if (!hItem) {
+ continue;
+ }
+ CFX_RectF rtItem;
+ pData->GetItemRect(m_pInterface, hItem, rtItem);
+ rtItem.Offset(-fPosX, -fPosY);
+ if (rtItem.Contains(fx, fy)) {
+ return hItem;
+ }
+ }
+ return NULL;
+}
+FX_BOOL CFWL_ListBoxImp::GetItemCheckRect(FWL_HLISTITEM hItem, CFX_RectF &rtCheck)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FALSE);
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) {
+ return FALSE;
+ }
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ pData->GetItemCheckRect(m_pInterface, hItem, rtCheck);
+ return TRUE;
+}
+FX_BOOL CFWL_ListBoxImp::GetItemChecked(FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FALSE);
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) {
+ return FALSE;
+ }
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ return (pData->GetItemCheckState(m_pInterface, hItem) & FWL_ITEMSTATE_LTB_Checked);
+}
+FX_BOOL CFWL_ListBoxImp::SetItemChecked(FWL_HLISTITEM hItem, FX_BOOL bChecked)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FALSE);
+ if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check)) {
+ return FALSE;
+ }
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_DWORD dwCheckState = pData->GetItemCheckState(m_pInterface, hItem);
+ if (bChecked) {
+ pData->SetItemCheckState(m_pInterface, hItem, FWL_ITEMSTATE_LTB_Checked);
+ } else {
+ pData->SetItemCheckState(m_pInterface, hItem, 0);
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_ListBoxImp::ScrollToVisible(FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pVertScrollBar, FALSE);
+ CFX_RectF rtItem;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ pData->GetItemRect(m_pInterface, hItem, rtItem);
+ FX_BOOL bScroll = FALSE;
+ FX_FLOAT fPosY = m_pVertScrollBar->GetPos();
+ rtItem.Offset(0, - fPosY + m_rtConent.top);
+ if (rtItem.top < m_rtConent.top) {
+ fPosY += rtItem.top - m_rtConent.top;
+ bScroll = TRUE;
+ } else if (rtItem.bottom() > m_rtConent.bottom()) {
+ fPosY += rtItem.bottom() - m_rtConent.bottom();
+ bScroll = TRUE;
+ }
+ if (!bScroll) {
+ return FALSE;
+ }
+ m_pVertScrollBar->SetPos(fPosY);
+ m_pVertScrollBar->SetTrackPos(fPosY);
+ Repaint(&m_rtClient);
+ return TRUE;
+}
+void CFWL_ListBoxImp::DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pTheme);
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_LTB_Background;
+ param.m_dwStates = 0;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = m_rtClient;
+ if (IsShowScrollBar(FALSE) && IsShowScrollBar(TRUE)) {
+ param.m_pData = &m_rtStatic;
+ }
+ if (!IsEnabled()) {
+ param.m_dwStates = FWL_PARTSTATE_LTB_Disabled;
+ }
+ pTheme->DrawBackground(&param);
+}
+void CFWL_ListBoxImp::DrawItems(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix )
+{
+ FX_FLOAT fPosX = 0.0f;
+ if (m_pHorzScrollBar) {
+ fPosX = m_pHorzScrollBar->GetPos();
+ }
+ FX_FLOAT fPosY = 0.0f;
+ if (m_pVertScrollBar) {
+ fPosY = m_pVertScrollBar->GetPos();
+ }
+ CFX_RectF rtView(m_rtConent);
+ if (m_pHorzScrollBar) {
+ rtView.height -= m_fScorllBarWidth;
+ }
+ if (m_pVertScrollBar) {
+ rtView.width -= m_fScorllBarWidth;
+ }
+ FX_BOOL bMultiCol = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ if (!hItem) {
+ continue;
+ }
+ CFX_RectF rtItem;
+ pData->GetItemRect(m_pInterface, hItem, rtItem);
+ rtItem.Offset(m_rtConent.left - fPosX, m_rtConent.top - fPosY);
+ if (rtItem.bottom() < m_rtConent.top) {
+ continue;
+ }
+ if (rtItem.top >= m_rtConent.bottom()) {
+ break;
+ }
+ if (bMultiCol && rtItem.left > m_rtConent.right()) {
+ break;
+ }
+ if (GetStylesEx() & FWL_STYLEEXT_LTB_OwnerDraw) {
+ CFWL_EvtLtbDrawItem ev;
+ ev.m_pSrcTarget = m_pInterface;
+ ev.m_pGraphics = pGraphics;
+ ev.m_matrix = *pMatrix;
+ ev.m_index = i;
+ ev.m_rect = rtItem;
+ DispatchEvent(&ev);
+ } else {
+ DrawItem(pGraphics, pTheme, hItem, i, rtItem, pMatrix);
+ }
+ }
+}
+void CFWL_ListBoxImp::DrawItem(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, FWL_HLISTITEM hItem, FX_INT32 Index, const CFX_RectF &rtItem, const CFX_Matrix *pMatrix )
+{
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_DWORD dwItemStyles = pData->GetItemStyles(m_pInterface, hItem);
+ FX_DWORD dwPartStates = FWL_PARTSTATE_LTB_Normal;
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ dwPartStates = FWL_PARTSTATE_LTB_Disabled;
+ } else if (dwItemStyles & FWL_ITEMSTATE_LTB_Selected) {
+ dwPartStates = FWL_PARTSTATE_LTB_Selected;
+ }
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && dwItemStyles & FWL_ITEMSTATE_LTB_Focused) {
+ dwPartStates |= FWL_PARTSTATE_LTB_Focused;
+ }
+ FWL_ListBoxItemData itemData;
+ itemData.pDataProvider = pData;
+ itemData.iIndex = Index;
+ {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_LTB_ListItem;
+ param.m_dwStates = dwPartStates;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = rtItem;
+ param.m_dwData = (FX_DWORD)(FX_UINTPTR)(&itemData);
+ CFX_RectF rtFocus(rtItem);
+ param.m_pData = &rtFocus;
+ if (m_pVertScrollBar && !m_pHorzScrollBar && (dwPartStates & FWL_PARTSTATE_LTB_Focused)) {
+ param.m_rtPart.left += 1;
+ param.m_rtPart.width -= (m_fScorllBarWidth + 1);
+ rtFocus.Deflate(0.5, 0.5, 1 + m_fScorllBarWidth, 1);
+ }
+ pTheme->DrawBackground(&param);
+ }
+ {
+ FX_BOOL bHasIcon = GetStylesEx() & FWL_STYLEEXT_LTB_Icon;
+ if (bHasIcon) {
+ CFX_RectF rtDIB;
+ CFX_DIBitmap *pDib = pData->GetItemIcon(m_pInterface, hItem);
+ rtDIB.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height);
+ if (pDib) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_LTB_Icon;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = rtDIB;
+ param.m_dwData = (FX_DWORD)(FX_UINTPTR)(&itemData);
+ param.m_pImage = pDib;
+ pTheme->DrawBackground(&param);
+ }
+ }
+ FX_BOOL bHasCheck = GetStylesEx() & FWL_STYLEEXT_LTB_Check;
+ if (bHasCheck) {
+ CFX_RectF rtCheck;
+ rtCheck.Set(rtItem.left, rtItem.top, rtItem.height, rtItem.height);
+ rtCheck.Deflate(2, 2, 2, 2);
+ pData->SetItemCheckRect(m_pInterface, hItem, rtCheck);
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_LTB_Check;
+ param.m_pGraphics = pGraphics;
+ if (GetItemChecked(hItem)) {
+ param.m_dwStates = FWL_PARTSTATE_LTB_Checked;
+ } else {
+ param.m_dwStates = FWL_PARTSTATE_LTB_UnChecked;
+ }
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = rtCheck;
+ param.m_dwData = (FX_DWORD)(FX_UINTPTR)(&itemData);
+ pTheme->DrawBackground(&param);
+ }
+ CFX_WideString wsText;
+ pData->GetItemText(m_pInterface, hItem, wsText);
+ if (wsText.GetLength() <= 0) {
+ return;
+ }
+ CFX_RectF rtText(rtItem);
+ rtText.Deflate(FWL_LISTBOX_ItemTextMargin, FWL_LISTBOX_ItemTextMargin);
+ if (bHasIcon || bHasCheck) {
+ rtText.Deflate(rtItem.height, 0, 0, 0);
+ }
+ CFWL_ThemeText textParam;
+ textParam.m_pWidget = m_pInterface;
+ textParam.m_iPart = FWL_PART_LTB_ListItem;
+ textParam.m_dwStates = dwPartStates;
+ textParam.m_pGraphics = pGraphics;
+ textParam.m_matrix.Concat(*pMatrix);
+ textParam.m_rtPart = rtText;
+ textParam.m_wsText = wsText;
+ textParam.m_dwTTOStyles = m_dwTTOStyles;
+ textParam.m_iTTOAlign = m_iTTOAligns;
+ textParam.m_dwData = (FX_DWORD)(FX_UINTPTR)(&itemData);
+ pTheme->DrawText(&textParam);
+ }
+}
+CFX_SizeF CFWL_ListBoxImp::CalcSize(FX_BOOL bAutoSize )
+{
+ CFX_SizeF fs;
+ fs.Set(0, 0);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, fs);
+ GetClientRect(m_rtClient);
+ m_rtConent = m_rtClient;
+ CFX_RectF rtUIMargin;
+ rtUIMargin.Set(0, 0, 0, 0);
+ if (!m_pOuter) {
+ CFX_RectF* pUIMargin = (CFX_RectF*)GetThemeCapacity(FWL_WGTCAPACITY_UIMargin);
+ if (pUIMargin) {
+ m_rtConent.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, pUIMargin->height);
+ }
+ }
+ FX_FLOAT fWidth = 0;
+ if (m_pProperties->m_pThemeProvider->IsCustomizedLayout(m_pInterface)) {
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ if (!bAutoSize) {
+ }
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ CFWL_ThemePart itemPart;
+ itemPart.m_pWidget = m_pInterface;
+ itemPart.m_iPart = FWL_PART_LTB_ListItem;
+ itemPart.m_pData = m_pProperties->m_pDataProvider;
+ itemPart.m_dwData = i;
+ CFX_RectF r;
+ m_pProperties->m_pThemeProvider->GetPartRect(&itemPart, r);
+ if (!bAutoSize) {
+ CFX_RectF rtItem;
+ rtItem.Set(m_rtClient.left, m_rtClient.top + fs.y, r.width, r.height);
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ pData->SetItemRect(m_pInterface, hItem, rtItem);
+ }
+ fs.y += r.height;
+ if (fs.x < r.width) {
+ fs.x = r.width;
+ fWidth = r.width;
+ }
+ }
+ } else {
+ fWidth = GetMaxTextWidth();
+ fWidth += 2 * FWL_LISTBOX_ItemTextMargin;
+ if (!bAutoSize) {
+ FX_FLOAT fActualWidth = m_rtClient.width - rtUIMargin.left - rtUIMargin.width;
+ if (fWidth < fActualWidth) {
+ fWidth = fActualWidth;
+ }
+ }
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ m_fItemHeight = GetItemHeigt();
+ FX_BOOL bHasIcon;
+ bHasIcon = GetStylesEx() & FWL_STYLEEXT_LTB_Icon;
+ if (bHasIcon) {
+ fWidth += m_fItemHeight;
+ }
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM htem = pData->GetItem(m_pInterface, i);
+ GetItemSize(fs, htem, fWidth, m_fItemHeight, bAutoSize);
+ }
+ }
+ if (bAutoSize) {
+ return fs;
+ }
+ FX_FLOAT iWidth = m_rtClient.width - rtUIMargin.left - rtUIMargin.width;
+ FX_FLOAT iHeight = m_rtClient.height;
+ FX_BOOL bShowVertScr = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) &&
+ (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll);
+ FX_BOOL bShowHorzScr = (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarAlaways) &&
+ (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll);
+ if (!bShowVertScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll &&
+ (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) == 0) {
+ bShowVertScr = (fs.y > iHeight);
+ }
+ if (!bShowHorzScr && m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) {
+ bShowHorzScr = (fs.x > iWidth);
+ }
+ CFX_SizeF szRange;
+ if (bShowVertScr) {
+ if (!m_pVertScrollBar) {
+ InitScrollBar();
+ }
+ CFX_RectF rtScrollBar;
+ rtScrollBar.Set(m_rtClient.right() - m_fScorllBarWidth,
+ m_rtClient.top,
+ m_fScorllBarWidth,
+ m_rtClient.height - 1);
+ if (bShowHorzScr) {
+ rtScrollBar.height -= m_fScorllBarWidth;
+ }
+ m_pVertScrollBar->SetWidgetRect(rtScrollBar);
+ szRange.x = 0, szRange.y = fs.y - m_rtConent.height;
+ if (szRange.y < m_fItemHeight) {
+ szRange.y = m_fItemHeight;
+ }
+ m_pVertScrollBar->SetRange(szRange.x, szRange.y);
+ m_pVertScrollBar->SetPageSize(rtScrollBar.height * 9 / 10);
+ m_pVertScrollBar->SetStepSize(m_fItemHeight);
+ FX_FLOAT fPos = m_pVertScrollBar->GetPos();
+ if (fPos < 0) {
+ fPos = 0;
+ }
+ if (fPos > szRange.y) {
+ fPos = szRange.y;
+ }
+ m_pVertScrollBar->SetPos(fPos);
+ m_pVertScrollBar->SetTrackPos(fPos);
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == 0 || (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) {
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ }
+ m_pVertScrollBar->Update();
+ } else if (m_pVertScrollBar) {
+ m_pVertScrollBar->SetPos(0);
+ m_pVertScrollBar->SetTrackPos(0);
+ m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+ if (bShowHorzScr) {
+ if (!m_pHorzScrollBar) {
+ InitScrollBar(FALSE);
+ }
+ CFX_RectF rtScrollBar;
+ rtScrollBar.Set(m_rtClient.left,
+ m_rtClient.bottom() - m_fScorllBarWidth,
+ m_rtClient.width,
+ m_fScorllBarWidth);
+ if (bShowVertScr) {
+ rtScrollBar.width -= m_fScorllBarWidth;
+ }
+ m_pHorzScrollBar->SetWidgetRect(rtScrollBar);
+ szRange.x = 0, szRange.y = fs.x - rtScrollBar.width;
+ m_pHorzScrollBar->SetRange(szRange.x, szRange.y);
+ m_pHorzScrollBar->SetPageSize(fWidth * 9 / 10);
+ m_pHorzScrollBar->SetStepSize(fWidth / 10);
+ FX_FLOAT fPos = m_pHorzScrollBar->GetPos();
+ if (fPos < 0) {
+ fPos = 0;
+ }
+ if (fPos > szRange.y) {
+ fPos = szRange.y;
+ }
+ m_pHorzScrollBar->SetPos(fPos);
+ m_pHorzScrollBar->SetTrackPos(fPos);
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) == 0 || (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused)) {
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ }
+ m_pHorzScrollBar->Update();
+ } else if (m_pHorzScrollBar) {
+ m_pHorzScrollBar->SetPos(0);
+ m_pHorzScrollBar->SetTrackPos(0);
+ m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ }
+ if (bShowVertScr && bShowHorzScr) {
+ m_rtStatic.Set(m_rtClient.right() - m_fScorllBarWidth,
+ m_rtClient.bottom() - m_fScorllBarWidth,
+ m_fScorllBarWidth,
+ m_fScorllBarWidth);
+ }
+ return fs;
+}
+void CFWL_ListBoxImp::GetItemSize(CFX_SizeF &size, FWL_HLISTITEM hItem, FX_FLOAT fWidth, FX_FLOAT m_fItemHeight, FX_BOOL bAutoSize)
+{
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiColumn) {
+ } else {
+ if (!bAutoSize) {
+ CFX_RectF rtItem;
+ rtItem.Set(0, size.y, fWidth, m_fItemHeight);
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ pData->SetItemRect(m_pInterface, hItem, rtItem);
+ }
+ size.x = fWidth;
+ size.y += m_fItemHeight;
+ }
+}
+FX_FLOAT CFWL_ListBoxImp::GetMaxTextWidth()
+{
+ FX_FLOAT fRet = 0.0f;
+ IFWL_ListBoxDP *pData = (IFWL_ListBoxDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 iCount = pData->CountItems(m_pInterface);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM hItem = pData->GetItem(m_pInterface, i);
+ if (!hItem) {
+ continue;
+ }
+ CFX_WideString wsText;
+ pData->GetItemText(m_pInterface, hItem, wsText);
+ CFX_SizeF sz = CalcTextSize(wsText, m_pProperties->m_pThemeProvider);
+ if (sz.x > fRet) {
+ fRet = sz.x;
+ }
+ }
+ return fRet;
+}
+FX_FLOAT CFWL_ListBoxImp::GetScrollWidth()
+{
+ FX_FLOAT *pfWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_VALUE_IF_FAIL(pfWidth, 0);
+ return *pfWidth;
+}
+FX_FLOAT CFWL_ListBoxImp::GetItemHeigt()
+{
+ FX_FLOAT *pfFont = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_FontSize);
+ _FWL_RETURN_VALUE_IF_FAIL(pfFont, 20);
+ return *pfFont + 2 * FWL_LISTBOX_ItemTextMargin;
+}
+void CFWL_ListBoxImp::InitScrollBar(FX_BOOL bVert )
+{
+ if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) {
+ return;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz;
+ prop.m_dwStates = FWL_WGTSTATE_Invisible;
+ prop.m_pParent = m_pInterface;
+ prop.m_pThemeProvider = m_pScrollBarTP;
+ IFWL_ScrollBar *pScrollBar = IFWL_ScrollBar::Create();
+ pScrollBar->Initialize(prop, m_pInterface);
+ bVert ? (m_pVertScrollBar = pScrollBar) : (m_pHorzScrollBar = pScrollBar);
+}
+void CFWL_ListBoxImp::SortItem()
+{
+}
+FX_BOOL CFWL_ListBoxImp::IsShowScrollBar(FX_BOOL bVert)
+{
+ IFWL_ScrollBar* pScrollbar = bVert ? m_pVertScrollBar : m_pHorzScrollBar;
+ if (!pScrollbar || (pScrollbar->GetStates() & FWL_WGTSTATE_Invisible)) {
+ return FALSE;
+ }
+ return !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_ShowScrollBarFocus) || (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused);
+}
+void CFWL_ListBoxImp::ProcessSelChanged()
+{
+ CFWL_EvtLtbSelChanged selEvent;
+ selEvent.m_pSrcTarget = m_pInterface;
+ CFX_Int32Array arrSels;
+ FX_INT32 iCount = CountSelItems();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FWL_HLISTITEM item = GetSelItem(i);
+ if (item == NULL) {
+ continue;
+ }
+ selEvent.iarraySels.Add(i);
+ }
+ DispatchEvent(&selEvent);
+}
+CFWL_ListBoxImpDelegate::CFWL_ListBoxImpDelegate(CFWL_ListBoxImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_ListBoxImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ if (!m_pOwner->IsEnabled()) {
+ return 1;
+ }
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_INT32 iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch (dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_MouseWheel: {
+ OnMouseWheel((CFWL_MsgMouseWheel*)pMessage);
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ CFWL_MsgKey *pMsg = (CFWL_MsgKey*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ if (dwCmd == FWL_MSGKEYCMD_KeyDown) {
+ OnKeyDown(pMsg);
+ }
+ break;
+ }
+ default: {
+ iRet = 0;
+ }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+ return iRet;
+}
+FWL_ERR CFWL_ListBoxImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pEvent, FWL_ERR_Indefinite);
+ FX_DWORD dwHashCode = pEvent->GetClassID();
+ if (pEvent->GetClassID() != FWL_EVTHASH_Scroll) {
+ return FWL_ERR_Succeeded;
+ }
+ IFWL_Widget *pSrcTarget = pEvent->m_pSrcTarget;
+ if ((pSrcTarget == (IFWL_Widget*)m_pOwner->m_pVertScrollBar && m_pOwner->m_pVertScrollBar) || (pSrcTarget == (IFWL_Widget*)m_pOwner->m_pHorzScrollBar && m_pOwner->m_pHorzScrollBar)) {
+ FX_DWORD dwScrollCode = ((CFWL_EvtScroll*)pEvent)->m_iScrollCode;
+ FX_FLOAT fPos = ((CFWL_EvtScroll*)pEvent)->m_fPos;
+ OnScroll((IFWL_ScrollBar*)pSrcTarget, dwScrollCode, fPos);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBoxImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_ListBoxImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)
+{
+ if (m_pOwner->GetStylesEx() & FWL_STYLEEXT_LTB_ShowScrollBarFocus) {
+ if (m_pOwner->m_pVertScrollBar) {
+ m_pOwner->m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet);
+ }
+ if (m_pOwner->m_pHorzScrollBar) {
+ m_pOwner->m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, !bSet);
+ }
+ }
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_ListBoxImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->m_bLButtonDown = TRUE;
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ FWL_HLISTITEM hItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (!hItem) {
+ return;
+ }
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) {
+ if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) {
+ FX_BOOL bSelected = m_pOwner->IsItemSelected(hItem);
+ m_pOwner->SetSelectionDirect(hItem, !bSelected);
+ m_pOwner->m_hAnchor = hItem;
+ } else if (pMsg->m_dwFlags & FWL_KEYFLAG_Shift) {
+ if (m_pOwner->m_hAnchor) {
+ m_pOwner->SetSelection(m_pOwner->m_hAnchor, hItem, TRUE);
+ } else {
+ m_pOwner->SetSelectionDirect(hItem, TRUE);
+ }
+ } else {
+ m_pOwner->SetSelection(hItem, hItem, TRUE);
+ m_pOwner->m_hAnchor = hItem;
+ }
+ } else {
+ m_pOwner->SetSelection(hItem, hItem, TRUE);
+ }
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_Check) {
+ FWL_HLISTITEM hSelectedItem = m_pOwner->GetItemAtPoint(pMsg->m_fx, pMsg->m_fy);
+ CFX_RectF rtCheck;
+ m_pOwner->GetItemCheckRect(hSelectedItem, rtCheck);
+ FX_BOOL bChecked = m_pOwner->GetItemChecked(hItem);
+ if (rtCheck.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (bChecked) {
+ m_pOwner->SetItemChecked(hItem, FALSE);
+ } else {
+ m_pOwner->SetItemChecked(hItem, TRUE);
+ }
+ m_pOwner->Update();
+ }
+ }
+ m_pOwner->SetFocusItem(hItem);
+ m_pOwner->ScrollToVisible(hItem);
+ m_pOwner->SetGrab(TRUE);
+ m_pOwner->ProcessSelChanged();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_ListBoxImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_bLButtonDown) {
+ m_pOwner->m_bLButtonDown = FALSE;
+ m_pOwner->SetGrab(FALSE);
+ DispatchSelChangedEv();
+ }
+}
+void CFWL_ListBoxImpDelegate::OnMouseWheel(CFWL_MsgMouseWheel *pMsg)
+{
+ if (!m_pOwner->IsShowScrollBar(TRUE)) {
+ return;
+ }
+ IFWL_WidgetDelegate *pDelegate = m_pOwner->m_pVertScrollBar->SetDelegate(NULL);
+ pDelegate->OnProcessMessage(pMsg);
+}
+void CFWL_ListBoxImpDelegate::OnKeyDown(CFWL_MsgKey *pMsg)
+{
+ FX_DWORD dwKeyCode = pMsg->m_dwKeyCode;
+ switch(dwKeyCode) {
+ case FWL_VKEY_Tab:
+ case FWL_VKEY_Up:
+ case FWL_VKEY_Down:
+ case FWL_VKEY_Home:
+ case FWL_VKEY_End: {
+ FWL_HLISTITEM hItem = m_pOwner->GetFocusedItem();
+ hItem = m_pOwner->GetItem(hItem, dwKeyCode);
+ FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift;
+ FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl;
+ OnVK(hItem, bShift, bCtrl);
+ DispatchSelChangedEv();
+ m_pOwner->ProcessSelChanged();
+ break;
+ }
+ default: {
+ }
+ }
+}
+void CFWL_ListBoxImpDelegate::OnVK(FWL_HLISTITEM hItem, FX_BOOL bShift, FX_BOOL bCtrl)
+{
+ if (!hItem) {
+ return;
+ }
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_LTB_MultiSelection) {
+ if (bCtrl) {
+ } else if (bShift) {
+ if (m_pOwner->m_hAnchor) {
+ m_pOwner->SetSelection(m_pOwner->m_hAnchor, hItem, TRUE);
+ } else {
+ m_pOwner->SetSelectionDirect(hItem, TRUE);
+ }
+ } else {
+ m_pOwner->SetSelection(hItem, hItem, TRUE);
+ m_pOwner->m_hAnchor = hItem;
+ }
+ } else {
+ m_pOwner->SetSelection(hItem, hItem, TRUE);
+ }
+ m_pOwner->SetFocusItem(hItem);
+ m_pOwner->ScrollToVisible(hItem);
+ {
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0,
+ 0,
+ m_pOwner->m_pProperties->m_rtWidget.width,
+ m_pOwner->m_pProperties->m_rtWidget.height);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+FX_BOOL CFWL_ListBoxImpDelegate::OnScroll(IFWL_ScrollBar *pScrollBar, FX_DWORD dwCode, FX_FLOAT fPos)
+{
+ CFX_SizeF fs;
+ pScrollBar->GetRange(fs.x, fs.y);
+ FX_FLOAT iCurPos = pScrollBar->GetPos();
+ FX_FLOAT fStep = pScrollBar->GetStepSize();
+ switch (dwCode) {
+ case FWL_SCBCODE_Min: {
+ fPos = fs.x;
+ break;
+ }
+ case FWL_SCBCODE_Max: {
+ fPos = fs.y;
+ break;
+ }
+ case FWL_SCBCODE_StepBackward: {
+ fPos -= fStep;
+ if (fPos < fs.x + fStep / 2) {
+ fPos = fs.x;
+ }
+ break;
+ }
+ case FWL_SCBCODE_StepForward: {
+ fPos += fStep;
+ if (fPos > fs.y - fStep / 2) {
+ fPos = fs.y;
+ }
+ break;
+ }
+ case FWL_SCBCODE_PageBackward: {
+ fPos -= pScrollBar->GetPageSize();
+ if (fPos < fs.x) {
+ fPos = fs.x;
+ }
+ break;
+ }
+ case FWL_SCBCODE_PageForward: {
+ fPos += pScrollBar->GetPageSize();
+ if (fPos > fs.y) {
+ fPos = fs.y;
+ }
+ break;
+ }
+ case FWL_SCBCODE_Pos:
+ case FWL_SCBCODE_TrackPos:
+ break;
+ case FWL_SCBCODE_EndScroll:
+ return FALSE;
+ }
+ if (iCurPos != fPos) {
+ pScrollBar->SetPos(fPos);
+ pScrollBar->SetTrackPos(fPos);
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ return TRUE;
+}
+void CFWL_ListBoxImpDelegate::DispatchSelChangedEv()
+{
+ CFWL_EvtLtbSelChanged ev;
+ ev.m_pSrcTarget = m_pOwner->m_pInterface;
+ m_pOwner->DispatchEvent(&ev);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_monthcalendarimp.cpp b/xfa/src/fwl/src/basewidget/fwl_monthcalendarimp.cpp
new file mode 100644
index 0000000000..fa8deb8d41
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_monthcalendarimp.cpp
@@ -0,0 +1,1113 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_monthcalendarimp.h"
+#define MONTHCAL_HSEP_HEIGHT 1
+#define MONTHCAL_VSEP_WIDTH 1
+#define MONTHCAL_HMARGIN 3
+#define MONTHCAL_VMARGIN 2
+#define MONTHCAL_ROWS 9
+#define MONTHCAL_COLUMNS 7
+#define MONTHCAL_HEADER_BTN_VMARGIN 7
+#define MONTHCAL_HEADER_BTN_HMARGIN 5
+IFWL_MonthCalendar* IFWL_MonthCalendar::Create()
+{
+ return new IFWL_MonthCalendar;
+}
+IFWL_MonthCalendar::IFWL_MonthCalendar()
+{
+ m_pData = NULL;
+}
+IFWL_MonthCalendar::~IFWL_MonthCalendar()
+{
+ if (m_pData) {
+ delete (CFWL_MonthCalendarImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_MonthCalendar::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_MonthCalendarImp(pOuter);
+ ((CFWL_MonthCalendarImp*)m_pData)->SetInterface(this);
+ return ((CFWL_MonthCalendarImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_MonthCalendar::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_MonthCalendarImp(properties, pOuter);
+ ((CFWL_MonthCalendarImp*)m_pData)->SetInterface(this);
+ return ((CFWL_MonthCalendarImp*)m_pData)->Initialize();
+}
+FX_INT32 IFWL_MonthCalendar::CountSelect()
+{
+ return ((CFWL_MonthCalendarImp*)m_pData)->CountSelect();
+}
+FX_BOOL IFWL_MonthCalendar::GetSelect(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay, FX_INT32 nIndex)
+{
+ return ((CFWL_MonthCalendarImp*)m_pData)->GetSelect(iYear, iMonth, iDay, nIndex);
+}
+FX_BOOL IFWL_MonthCalendar::SetSelect(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ return ((CFWL_MonthCalendarImp*)m_pData)->SetSelect(iYear, iMonth, iDay);
+}
+CFWL_MonthCalendarImp::CFWL_MonthCalendarImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_iLBtnPartStates(FWL_PARTSTATE_MCD_Normal)
+ , m_iRBtnPartStates(FWL_PARTSTATE_MCD_Normal)
+ , m_iCurMonth(1)
+ , m_iCurYear(2011)
+ , m_iYear(2011)
+ , m_iMonth(1)
+ , m_iDay(1)
+ , m_iHovered(-1)
+{
+ m_rtHead.Reset();
+ m_rtWeek.Reset();
+ m_rtLBtn.Reset();
+ m_rtRBtn.Reset();
+ m_rtDates.Reset();
+ m_rtHSep.Reset();
+ m_rtHeadText.Reset();
+ m_rtToday.Reset();
+ m_rtTodayFlag.Reset();
+ m_rtClient.Reset();
+ m_rtWeekNum.Reset();
+ m_rtWeekNumSep.Reset();
+ m_szHead.Reset();
+ m_szCell.Reset();
+ m_szToday.Reset();
+ m_pDateTime = new CFX_DateTime;
+ m_bInit = FALSE;
+ m_iMaxSel = 1;
+}
+CFWL_MonthCalendarImp::CFWL_MonthCalendarImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_iLBtnPartStates(FWL_PARTSTATE_MCD_Normal)
+ , m_iRBtnPartStates(FWL_PARTSTATE_MCD_Normal)
+ , m_iCurMonth(1)
+ , m_iCurYear(2011)
+ , m_iYear(2011)
+ , m_iMonth(1)
+ , m_iDay(1)
+ , m_iHovered(-1)
+{
+ m_rtHead.Reset();
+ m_rtWeek.Reset();
+ m_rtLBtn.Reset();
+ m_rtRBtn.Reset();
+ m_rtDates.Reset();
+ m_rtHSep.Reset();
+ m_rtHeadText.Reset();
+ m_rtToday.Reset();
+ m_rtTodayFlag.Reset();
+ m_rtClient.Reset();
+ m_rtWeekNum.Reset();
+ m_rtWeekNumSep.Reset();
+ m_szHead.Reset();
+ m_szCell.Reset();
+ m_szToday.Reset();
+ m_pDateTime = new CFX_DateTime;
+ m_bInit = FALSE;
+ m_iMaxSel = 1;
+}
+CFWL_MonthCalendarImp::~CFWL_MonthCalendarImp()
+{
+ ClearDateItem();
+ delete m_pDateTime;
+ m_arrSelDays.RemoveAll();
+}
+FWL_ERR CFWL_MonthCalendarImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_MonthCalendar;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_MonthCalendarImp::GetClassID() const
+{
+ return FWL_CLASSHASH_MonthCalendar;
+}
+FWL_ERR CFWL_MonthCalendarImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_MonthCalendarImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_MonthCalendarImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_MonthCalendarImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_MonthCalendarImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ CFX_SizeF fs = CalcSize(TRUE);
+ rect.Set(0, 0, fs.x, fs.y);
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_MonthCalendarImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ GetCapValue();
+ if (!m_bInit) {
+ m_bInit = InitDate();
+ }
+ ClearDateItem();
+ ReSetDateItem();
+ LayOut();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_MonthCalendarImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ if (m_pProperties->m_pThemeProvider == NULL) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_MCD_Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_MCD_Edge, pTheme, pMatrix);
+ }
+ DrawBkground(pGraphics, pTheme, pMatrix);
+ DrawHeadBK(pGraphics, pTheme, pMatrix);
+ DrawLButton(pGraphics, pTheme, pMatrix);
+ DrawRButton(pGraphics, pTheme, pMatrix);
+ DrawSeperator(pGraphics, pTheme, pMatrix);
+ DrawDatesInBK(pGraphics, pTheme, pMatrix);
+ DrawDatesInCircle(pGraphics, pTheme, pMatrix);
+ DrawCaption(pGraphics, pTheme, pMatrix);
+ DrawWeek(pGraphics, pTheme, pMatrix);
+ DrawDatesIn(pGraphics, pTheme, pMatrix);
+ DrawDatesOut(pGraphics, pTheme, pMatrix);
+ DrawToday(pGraphics, pTheme, pMatrix);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {
+ DrawWeekNumberSep(pGraphics, pTheme, pMatrix);
+ DrawWeekNumber(pGraphics, pTheme, pMatrix);
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_MonthCalendarImp::CountSelect()
+{
+ return m_arrSelDays.GetSize();
+}
+FX_BOOL CFWL_MonthCalendarImp::GetSelect(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay, FX_INT32 nIndex )
+{
+ if (nIndex >= m_arrSelDays.GetSize()) {
+ return FALSE;
+ }
+ iYear = m_iCurYear;
+ iMonth = m_iCurMonth;
+ iDay = m_arrSelDays[nIndex];
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::SetSelect(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ ChangeToMonth(iYear, iMonth);
+ return AddSelDay(iDay);
+}
+void CFWL_MonthCalendarImp::DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_Background;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_rtPart = m_rtClient;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+void CFWL_MonthCalendarImp::DrawHeadBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_Header;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_rtPart = m_rtHead;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+void CFWL_MonthCalendarImp::DrawLButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_LBtn;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_iLBtnPartStates;
+ params.m_rtPart = m_rtLBtn;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+void CFWL_MonthCalendarImp::DrawRButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_RBtn;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_iRBtnPartStates;
+ params.m_rtPart = m_rtRBtn;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+void CFWL_MonthCalendarImp::DrawCaption(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeText textParam;
+ textParam.m_pWidget = m_pInterface;
+ textParam.m_iPart = FWL_PART_MCD_Caption;
+ textParam.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ textParam.m_pGraphics = pGraphics;
+ FX_INT32 iYear;
+ FX_INT32 iMonth;
+ iYear = m_iCurYear;
+ iMonth = m_iCurMonth;
+ CFX_WideString wsCation;
+ GetHeadText(iYear, iMonth, wsCation);
+ textParam.m_wsText = wsCation;
+ m_szHead = CalcTextSize(textParam.m_wsText, m_pProperties->m_pThemeProvider);
+ CalcHeadSize();
+ textParam.m_rtPart = m_rtHeadText;
+ textParam.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ textParam.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ textParam.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawText(&textParam);
+}
+void CFWL_MonthCalendarImp::DrawSeperator(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_HSeparator;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_rtPart = m_rtHSep;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+void CFWL_MonthCalendarImp::DrawDatesInBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_DateInBK;
+ params.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ FX_INT32 iCount = m_arrDates.GetSize();
+ for (FX_INT32 j = 0; j < iCount; j ++) {
+ LPDATEINFO pDataInfo = (LPDATEINFO)m_arrDates.GetAt(j);
+ if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Selected) {
+ params.m_dwStates |= FWL_PARTSTATE_MCD_Selected;
+ if (((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) == 0) && pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {
+ params.m_dwStates |= FWL_PARTSTATE_MCD_Flagged;
+ }
+ if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Focused) {
+ params.m_dwStates |= FWL_PARTSTATE_MCD_Focused;
+ }
+ } else if (j == m_iHovered - 1) {
+ params.m_dwStates |= FWL_PARTSTATE_MCD_Hovered;
+ } else if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {
+ params.m_dwStates = FWL_PARTSTATE_MCD_Flagged;
+ pTheme->DrawBackground(&params);
+ }
+ params.m_rtPart = pDataInfo->rect;
+ pTheme->DrawBackground(&params);
+ params.m_dwStates = 0;
+ }
+}
+void CFWL_MonthCalendarImp::DrawWeek(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeText params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_Week;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ FX_INT32 iWeek;
+ iWeek = m_pDateTime->GetDayOfWeek();
+ CFX_RectF rtDayOfWeek;
+ const FX_WCHAR* pWeekDay[] = {
+ (FX_WCHAR *)L"Sun", (FX_WCHAR *)L"Mon", (FX_WCHAR *)L"Tue",
+ (FX_WCHAR *)L"Wed", (FX_WCHAR *)L"Thu", (FX_WCHAR *)L"Fri", (FX_WCHAR *)L"Sat"
+ };
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ for (FX_INT32 i = 0; i < 7; i++) {
+ rtDayOfWeek.Set(m_rtWeek.left + i * (m_szCell.x + MONTHCAL_HMARGIN * 2),
+ m_rtWeek.top,
+ m_szCell.x,
+ m_szCell.y);
+ CFX_WideString *wsWeekDay = NULL;
+ wsWeekDay = (CFX_WideString *)pTheme->GetCapacity(&params, i + FWL_MCCAPACITY_Sun);
+ params.m_rtPart = rtDayOfWeek;
+ params.m_wsText = *wsWeekDay;
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ pTheme->DrawText(&params);
+ }
+}
+void CFWL_MonthCalendarImp::DrawWeekNumber(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeText params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_WeekNum;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
+ CFX_WideString wsWeekNum;
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ FX_INT32 iWeekNum = 0;
+ FX_INT32 iMonthNum = m_pDateTime->GetMonth();
+ FX_INT32 iDayNum = FX_DaysInMonth(m_iCurYear, iMonthNum);
+ FX_INT32 iTemp = 0;
+ FX_FLOAT fVStartPos = m_rtClient.top + m_fHeadHei + m_fHSepHei;
+ FX_FLOAT fHStartPos = m_rtClient.left;
+ for (FX_INT32 i = 1; i <= iDayNum; i += 7) {
+ iTemp ++;
+ iWeekNum = CalWeekNumber(m_iCurYear, iMonthNum, i);
+ m_rtWeekNum.Set(fHStartPos, fVStartPos + m_fDateCellHei * iTemp, m_fWeekNumWid, m_fDateCellHei);
+ wsWeekNum.Format(FX_LPCWSTR(L"%d"), iWeekNum);
+ params.m_wsText = wsWeekNum;
+ params.m_rtPart = m_rtWeekNum;
+ pTheme->DrawText(&params);
+ }
+}
+void CFWL_MonthCalendarImp::DrawWeekNumberSep(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_WeekNumSep;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_rtPart = m_rtWeekNumSep;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+void CFWL_MonthCalendarImp::DrawToday(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) {
+ return;
+ }
+ CFWL_ThemeText params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_Today;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
+ CFX_WideString *wsDay = NULL;
+ wsDay = (CFX_WideString *)pTheme->GetCapacity(&params, FWL_MCCAPACITY_Today);
+ CFX_WideString wsText;
+ GetTodayText(m_iYear, m_iMonth, m_iDay, wsText);
+ params.m_wsText = *wsDay + wsText;
+ m_szToday = CalcTextSize(params.m_wsText, m_pProperties->m_pThemeProvider);
+ CalcTodaySize();
+ params.m_rtPart = m_rtToday;
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawText(&params);
+}
+void CFWL_MonthCalendarImp::DrawDatesIn(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeText params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_DatesIn;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ FX_INT32 iCount = m_arrDates.GetSize();
+ for (FX_INT32 j = 0; j < iCount; j ++) {
+ LPDATEINFO pDataInfo = (LPDATEINFO)m_arrDates.GetAt(j);
+ params.m_wsText = pDataInfo->wsDay;
+ params.m_rtPart = pDataInfo->rect;
+ params.m_dwStates = pDataInfo->dwStates;
+ if (j + 1 == m_iHovered) {
+ params.m_dwStates |= FWL_PARTSTATE_MCD_Hovered;
+ }
+ params.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ pTheme->DrawText(&params);
+ }
+}
+void CFWL_MonthCalendarImp::DrawDatesOut(CFX_Graphics *pGraphics, IFWL_ThemeProvider* pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeText params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_DatesOut;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawText(&params);
+}
+void CFWL_MonthCalendarImp::DrawDatesInCircle(CFX_Graphics *pGraphics, IFWL_ThemeProvider* pTheme, const CFX_Matrix *pMatrix)
+{
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) {
+ return;
+ }
+ if (m_iMonth != m_iCurMonth || m_iYear != m_iCurYear) {
+ return;
+ }
+ if (m_iDay < 1 || m_iDay > m_arrDates.GetSize()) {
+ return;
+ }
+ LPDATEINFO pDate = (LPDATEINFO)m_arrDates[m_iDay - 1];
+ _FWL_RETURN_IF_FAIL(pDate);
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_DateInCircle;
+ params.m_pGraphics = pGraphics;
+ params.m_rtPart = pDate->rect;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+void CFWL_MonthCalendarImp::DrawTodayCircle(CFX_Graphics *pGraphics, IFWL_ThemeProvider* pTheme, const CFX_Matrix *pMatrix)
+{
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday) {
+ return;
+ }
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoTodayCircle) {
+ return;
+ }
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_MCD_TodayCircle;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = FWL_PARTSTATE_MCD_Normal;
+ params.m_rtPart = m_rtTodayFlag;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&params);
+}
+CFX_SizeF CFWL_MonthCalendarImp::CalcSize(FX_BOOL bAutoSize)
+{
+ CFX_SizeF fs;
+ fs.Set(0, 0);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, fs);
+ if (bAutoSize) {
+ CFWL_ThemePart params;
+ params.m_pWidget = m_pInterface;
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ CFX_WideString *wsText = NULL;
+ FX_FLOAT fMaxWeekW = 0.0f;
+ FX_FLOAT fMaxWeekH = 0.0f;
+ for (FX_DWORD week = FWL_MCCAPACITY_Sun; week <= FWL_MCCAPACITY_Sat; week++) {
+ wsText = (CFX_WideString *)pTheme->GetCapacity(&params, week);
+ CFX_SizeF sz = CalcTextSize(*wsText, m_pProperties->m_pThemeProvider);
+ fMaxWeekW = (fMaxWeekW >= sz.x) ? fMaxWeekW : sz.x;
+ fMaxWeekH = (fMaxWeekH >= sz.y) ? fMaxWeekH : sz.y;
+ }
+ FX_FLOAT fDayMaxW = 0.0f;
+ FX_FLOAT fDayMaxH = 0.0f;
+ for (int day = 10; day <= 31; day++) {
+ CFX_WideString wsDay;
+ wsDay.Format((FX_LPCWSTR)L"%d", day);
+ CFX_SizeF sz = CalcTextSize(wsDay, m_pProperties->m_pThemeProvider);
+ fDayMaxW = (fDayMaxW >= sz.x) ? fDayMaxW : sz.x;
+ fDayMaxH = (fDayMaxH >= sz.y) ? fDayMaxH : sz.y;
+ }
+ m_szCell.x = FX_FLOAT((fMaxWeekW >= fDayMaxW) ? (int)(fMaxWeekW + 0.5) : (int)(fDayMaxW + 0.5));
+ m_szCell.y = (fMaxWeekH >= fDayMaxH) ? fMaxWeekH : fDayMaxH;
+ fs.x = m_szCell.x * MONTHCAL_COLUMNS + MONTHCAL_HMARGIN * MONTHCAL_COLUMNS * 2 + MONTHCAL_HEADER_BTN_HMARGIN * 2;
+ FX_FLOAT fMonthMaxW = 0.0f;
+ FX_FLOAT fMonthMaxH = 0.0f;
+ for (FX_DWORD month = FWL_MCCAPACITY_January; month <= FWL_MCCAPACITY_December; month++) {
+ wsText = (CFX_WideString *)pTheme->GetCapacity(&params, month);
+ CFX_SizeF sz = CalcTextSize(*wsText, m_pProperties->m_pThemeProvider);
+ fMonthMaxW = (fMonthMaxW >= sz.x) ? fMonthMaxW : sz.x;
+ fMonthMaxH = (fMonthMaxH >= sz.y) ? fMonthMaxH : sz.y;
+ }
+ CFX_WideString wsYear;
+ GetHeadText(m_iYear, m_iMonth, wsYear);
+ CFX_SizeF szYear = CalcTextSize(wsYear, m_pProperties->m_pThemeProvider);
+ fMonthMaxH = (fMonthMaxH >= szYear.y) ? fMonthMaxH : szYear.y;
+ m_szHead.Set(fMonthMaxW + szYear.x, fMonthMaxH);
+ fMonthMaxW = m_szHead.x + MONTHCAL_HEADER_BTN_HMARGIN * 2 + m_szCell.x * 2;
+ fs.x = (fs.x >= fMonthMaxW) ? fs.x : fMonthMaxW;
+ CFX_WideString wsToday;
+ GetTodayText(m_iYear, m_iMonth, m_iDay, wsToday);
+ wsText = (CFX_WideString *)pTheme->GetCapacity(&params, FWL_MCCAPACITY_Today);
+ m_wsToday = *wsText + wsToday;
+ m_szToday = CalcTextSize(wsToday, m_pProperties->m_pThemeProvider);
+ m_szToday.y = (m_szToday.y >= m_szCell.y) ? m_szToday.y : m_szCell.y;
+ fs.y = m_szCell.x + m_szCell.y * (MONTHCAL_ROWS - 2) + m_szToday.y + MONTHCAL_VMARGIN * MONTHCAL_ROWS * 2 + MONTHCAL_HEADER_BTN_VMARGIN * 4;
+ } else {
+ GetClientRect(m_rtClient);
+ fs.Set(m_rtClient.width, m_rtClient.height);
+ }
+ return fs;
+}
+void CFWL_MonthCalendarImp::CalcHeadSize()
+{
+ FX_FLOAT fHeadHMargin = (m_rtClient.width - m_szHead.x) / 2;
+ FX_FLOAT fHeadVMargin = (m_szCell.x - m_szHead.y) / 2;
+ m_rtHeadText.Set(m_rtClient.left + fHeadHMargin,
+ m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN + fHeadVMargin,
+ m_szHead.x,
+ m_szHead.y);
+}
+void CFWL_MonthCalendarImp::CalcTodaySize()
+{
+ m_rtTodayFlag.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
+ m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
+ m_szCell.x,
+ m_szToday.y);
+ m_rtToday.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + m_szCell.x + MONTHCAL_HMARGIN * 2 ,
+ m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
+ m_szToday.x,
+ m_szToday.y);
+}
+void CFWL_MonthCalendarImp::LayOut()
+{
+ GetClientRect(m_rtClient);
+ {
+ m_rtHead.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
+ m_rtClient.top,
+ m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
+ m_szCell.x + (MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN) * 2);
+ m_rtWeek.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
+ m_rtHead.bottom(),
+ m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
+ m_szCell.y + MONTHCAL_VMARGIN * 2);
+ m_rtLBtn.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
+ m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN,
+ m_szCell.x,
+ m_szCell.x);
+ m_rtRBtn.Set(m_rtClient.left + m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN - m_szCell.x,
+ m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN,
+ m_szCell.x,
+ m_szCell.x);
+ m_rtHSep.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
+ m_rtWeek.bottom() - MONTHCAL_VMARGIN,
+ m_rtClient.width - (MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN) * 2,
+ MONTHCAL_HSEP_HEIGHT);
+ m_rtDates.Set(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
+ m_rtWeek.bottom(),
+ m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
+ m_szCell.y * (MONTHCAL_ROWS - 3) + MONTHCAL_VMARGIN * (MONTHCAL_ROWS - 3) * 2);
+ }
+ CalDateItem();
+}
+void CFWL_MonthCalendarImp::CalDateItem()
+{
+ FX_BOOL bNewWeek = FALSE;
+ FX_INT32 iWeekOfMonth = 0;
+ FX_FLOAT fLeft = m_rtDates.left;
+ FX_FLOAT fTop = m_rtDates.top;
+ FX_INT32 iCount = m_arrDates.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(i);
+ if (bNewWeek) {
+ iWeekOfMonth ++;
+ bNewWeek = FALSE;
+ }
+ pDateInfo->rect.Set(fLeft + pDateInfo->iDayOfWeek * (m_szCell.x + (MONTHCAL_HMARGIN * 2)),
+ fTop + iWeekOfMonth * (m_szCell.y + (MONTHCAL_VMARGIN * 2)),
+ m_szCell.x + (MONTHCAL_HMARGIN * 2),
+ m_szCell.y + (MONTHCAL_VMARGIN * 2));
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {
+ pDateInfo->rect.Offset(m_fWeekNumWid, 0);
+ }
+ if (pDateInfo->iDayOfWeek >= 6) {
+ bNewWeek = TRUE;
+ }
+ }
+}
+void CFWL_MonthCalendarImp::GetCapValue()
+{
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pInterface;
+ m_fHeadWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_WIDTH);
+ m_fHeadHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_Height);
+ m_fHeadBtnWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_WIDTH);
+ m_fHeadBtnHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_HEIGHT);
+ m_fHeadBtnHMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_HMARGIN);
+ m_fHeadBtnVMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_BTN_VMARGIN);
+ m_fHeadTextWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXTWIDHT);
+ m_fHeadTextHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXTHEIGHT);
+ m_fHeadTextHMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXT_HMARGIN);
+ m_fHeadTextVMargin = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEADER_TEXT_VMARGIN);
+ m_fHSepWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HSEP_WIDTH);
+ m_fHSepHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HSEP_HEIGHT);
+ m_fWeekNumWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEKNUM_WIDTH);
+ m_fSepDOffset = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_SEP_DOFFSET);
+ m_fSepX = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_SEP_X);
+ m_fSepY = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_SEP_Y);
+ m_fWeekNumHeigh = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEKNUM_HEIGHT);
+ m_fWeekWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEK_WIDTH);
+ m_fWeekHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WEEK_HEIGHT);
+ m_fDateCellWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_DATES_CELL_WIDTH);
+ m_fDateCellHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_DATES_CELL_HEIGHT);
+ m_fTodayWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_TODAY_WIDHT);
+ m_fTodayHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_TODAY_HEIGHT);
+ m_fTodayFlagWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_TODAY_FLAG_WIDHT);
+ m_fMCWid = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_WIDTH);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_WeekNumbers) {
+ m_fMCWid += m_fWeekNumWid;
+ }
+ m_fMCHei = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_MC_HEIGHT);
+}
+FX_INT32 CFWL_MonthCalendarImp::CalWeekNumber(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ return 0;
+}
+FX_BOOL CFWL_MonthCalendarImp::GetMinDate(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay)
+{
+ iYear = m_dtMin.iYear;
+ iMonth = m_dtMin.iMonth;
+ iDay = m_dtMin.iDay;
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::SetMinDate(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ m_dtMin = DATE(iYear, iMonth, iDay);
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::GetMaxDate(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay)
+{
+ iYear = m_dtMax.iYear;
+ iMonth = m_dtMax.iMonth;
+ iDay = m_dtMax.iDay;
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::SetMaxDate(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ m_dtMax = DATE(iYear, iMonth, iDay);
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::InitDate()
+{
+ if (m_pProperties->m_pDataProvider) {
+ IFWL_MonthCalendarDP *pDateProv = (IFWL_MonthCalendarDP*)(m_pProperties->m_pDataProvider);
+ m_iYear = pDateProv->GetCurYear(m_pInterface);
+ m_iMonth = pDateProv->GetCurMonth(m_pInterface);
+ m_iDay = pDateProv->GetCurDay(m_pInterface);
+ m_iCurYear = m_iYear;
+ m_iCurMonth = m_iMonth;
+ } else {
+ m_iDay = 1;
+ m_iMonth = 1;
+ m_iYear = 1;
+ m_iCurYear = m_iYear;
+ m_iCurMonth = m_iMonth;
+ }
+ GetTodayText(m_iYear, m_iMonth, m_iDay, m_wsToday);
+ GetHeadText(m_iCurYear, m_iCurMonth, m_wsHead);
+ {
+ m_dtMin = DATE(1500, 12, 1);
+ m_dtMax = DATE(2200, 1, 1);
+ }
+ return TRUE;
+}
+void CFWL_MonthCalendarImp::ClearDateItem()
+{
+ FX_INT32 iCount = m_arrDates.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ LPDATEINFO pData = (LPDATEINFO)m_arrDates.GetAt(i);
+ delete pData;
+ }
+ m_arrDates.RemoveAll();
+}
+void CFWL_MonthCalendarImp::ReSetDateItem()
+{
+ m_pDateTime->Set(m_iCurYear, m_iCurMonth, 1);
+ FX_INT32 iDays = FX_DaysInMonth(m_iCurYear, m_iCurMonth);
+ FX_INT32 iDayOfWeek = m_pDateTime->GetDayOfWeek();
+ for (FX_INT32 i = 0; i < iDays; i ++) {
+ if (iDayOfWeek >= 7) {
+ iDayOfWeek = 0;
+ }
+ CFX_WideString wsDay;
+ wsDay.Format(FX_LPCWSTR(L"%d"), i + 1);
+ FX_DWORD dwStates = 0;
+ if (m_iYear == m_iCurYear && m_iMonth == m_iCurMonth && m_iDay == (i + 1)) {
+ dwStates |= FWL_ITEMSTATE_MCD_Flag;
+ }
+ if (m_arrSelDays.Find(i + 1) != -1) {
+ dwStates |= FWL_ITEMSTATE_MCD_Selected;
+ }
+ CFX_RectF rtDate;
+ rtDate.Set(0, 0, 0, 0);
+ LPDATEINFO pData = new DATEINFO(i + 1, iDayOfWeek, dwStates, rtDate, wsDay);
+ m_arrDates.Add(pData);
+ iDayOfWeek++;
+ }
+}
+FX_BOOL CFWL_MonthCalendarImp::NextMonth()
+{
+ FX_INT32 iYear = m_iCurYear, iMonth = m_iCurMonth;
+ if (iMonth >= 12) {
+ iMonth = 1;
+ iYear++;
+ } else {
+ iMonth ++;
+ }
+ DATE dt(m_iCurYear, m_iCurMonth, 1);
+ if (!(dt < m_dtMax)) {
+ return FALSE;
+ }
+ m_iCurYear = iYear, m_iCurMonth = iMonth;
+ ChangeToMonth(m_iCurYear, m_iCurMonth);
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::PrevMonth()
+{
+ FX_INT32 iYear = m_iCurYear, iMonth = m_iCurMonth;
+ if (iMonth <= 1) {
+ iMonth = 12;
+ iYear --;
+ } else {
+ iMonth --;
+ }
+ DATE dt(m_iCurYear, m_iCurMonth, 1);
+ if (!(dt > m_dtMin)) {
+ return FALSE;
+ }
+ m_iCurYear = iYear, m_iCurMonth = iMonth;
+ ChangeToMonth(m_iCurYear, m_iCurMonth);
+ return TRUE;
+}
+void CFWL_MonthCalendarImp::ChangeToMonth(FX_INT32 iYear, FX_INT32 iMonth)
+{
+ m_iCurYear = iYear;
+ m_iCurMonth = iMonth;
+ m_iHovered = -1;
+ ClearDateItem();
+ ReSetDateItem();
+ CalDateItem();
+ GetHeadText(m_iCurYear, m_iCurMonth, m_wsHead);
+}
+FX_BOOL CFWL_MonthCalendarImp::RemoveSelDay(FX_INT32 iDay, FX_BOOL bAll)
+{
+ if (iDay == -1 && !bAll) {
+ return FALSE;
+ }
+ if (bAll) {
+ FX_INT32 iCount = m_arrSelDays.GetSize();
+ FX_INT32 iDatesCount = m_arrDates.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ FX_INT32 iSelDay = m_arrSelDays.GetAt(i);
+ if (iSelDay <= iDatesCount) {
+ LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(iSelDay - 1);
+ pDateInfo->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;
+ }
+ }
+ m_arrSelDays.RemoveAll();
+ } else {
+ FX_INT32 index = m_arrSelDays.Find(iDay);
+ if (index == -1) {
+ return FALSE;
+ }
+ FX_INT32 iSelDay = m_arrSelDays.GetAt(iDay);
+ FX_INT32 iDatesCount = m_arrDates.GetSize();
+ if (iSelDay <= iDatesCount) {
+ LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(iSelDay - 1);
+ pDateInfo->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;
+ }
+ m_arrSelDays.RemoveAt(index);
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::AddSelDay(FX_INT32 iDay)
+{
+ FXSYS_assert(iDay > 0);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ } else {
+ if (m_arrSelDays.Find(iDay) == -1) {
+ RemoveSelDay(-1, TRUE);
+ if (iDay <= m_arrDates.GetSize()) {
+ LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(iDay - 1);
+ pDateInfo->dwStates |= FWL_ITEMSTATE_MCD_Selected;
+ }
+ m_arrSelDays.Add(iDay);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarImp::JumpToToday()
+{
+ if (m_iYear != m_iCurYear || m_iMonth != m_iCurMonth) {
+ m_iCurYear = m_iYear;
+ m_iCurMonth = m_iMonth;
+ ChangeToMonth(m_iYear, m_iMonth);
+ AddSelDay(m_iDay);
+ } else {
+ if (m_arrSelDays.Find(m_iDay) == -1) {
+ AddSelDay(m_iDay);
+ }
+ }
+ return TRUE;
+}
+void CFWL_MonthCalendarImp::GetHeadText(FX_INT32 iYear, FX_INT32 iMonth, CFX_WideString &wsHead)
+{
+ FXSYS_assert(iMonth > 0 && iMonth < 13);
+ static FX_LPWSTR pMonth[] = {
+ FX_LPWSTR(L"January"),
+ FX_LPWSTR(L"February"),
+ FX_LPWSTR(L"March"),
+ FX_LPWSTR(L"April"),
+ FX_LPWSTR(L"May"),
+ FX_LPWSTR(L"June"),
+ FX_LPWSTR(L"July"),
+ FX_LPWSTR(L"August"),
+ FX_LPWSTR(L"September"),
+ FX_LPWSTR(L"October"),
+ FX_LPWSTR(L"November"),
+ FX_LPWSTR(L"December")
+ };
+ wsHead.Format(FX_LPCWSTR(L"%s, %d"), pMonth[iMonth - 1], iYear);
+}
+void CFWL_MonthCalendarImp::GetTodayText(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay, CFX_WideString &wsToday)
+{
+ wsToday.Format(FX_LPCWSTR(L", %d/%d/%d"), iDay, iMonth, iYear);
+}
+FX_INT32 CFWL_MonthCalendarImp::GetDayAtPoint(FX_FLOAT x, FX_FLOAT y)
+{
+ FX_INT32 iCount = m_arrDates.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates.GetAt(i);
+ if (pDateInfo->rect.Contains(x, y)) {
+ return ++i;
+ }
+ }
+ return -1;
+}
+FX_BOOL CFWL_MonthCalendarImp::GetDayRect(FX_INT32 iDay, CFX_RectF &rtDay)
+{
+ if (iDay <= 0 || iDay > m_arrDates.GetSize()) {
+ return FALSE;
+ }
+ LPDATEINFO pDateInfo = (LPDATEINFO)m_arrDates[iDay - 1];
+ _FWL_RETURN_VALUE_IF_FAIL(pDateInfo, FALSE);
+ rtDay = pDateInfo->rect;
+ return TRUE;
+}
+CFWL_MonthCalendarImpDelegate::CFWL_MonthCalendarImpDelegate(CFWL_MonthCalendarImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_MonthCalendarImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_INT32 iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse* pMouse = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMouse->m_dwCmd;
+ switch(dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMouse);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMouse);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove((CFWL_MsgMouse*)pMouse);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave((CFWL_MsgMouse*)pMouse);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ break;
+ }
+ default: {
+ iRet = 0;
+ break;
+ }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+ return iRet;
+}
+FWL_ERR CFWL_MonthCalendarImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_MonthCalendarImpDelegate::OnActivate(CFWL_Message *pMsg)
+{
+ return;
+}
+void CFWL_MonthCalendarImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet)
+{
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_MonthCalendarImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = FWL_PARTSTATE_MCD_Pressed;
+ m_pOwner->PrevMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates |= FWL_PARTSTATE_MCD_Pressed;
+ m_pOwner->NextMonth();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ } else if (m_pOwner->m_rtToday.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_NoToday ) == 0) {
+ m_pOwner->JumpToToday();
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+ } else {
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ } else {
+ FX_INT32 iOldSel = 0;
+ if (m_pOwner->m_arrSelDays.GetSize() > 0) {
+ iOldSel = m_pOwner->m_arrSelDays[0];
+ } else {
+ return;
+ }
+ FX_INT32 iCurSel = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ FX_BOOL bSelChanged = iCurSel > 0 && iCurSel != iOldSel;
+ if (bSelChanged) {
+ LPDATEINFO lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iCurSel - 1);
+ CFX_RectF rtInvalidate(lpDatesInfo->rect);
+ if (iOldSel > 0) {
+ lpDatesInfo = (LPDATEINFO)m_pOwner->m_arrDates.GetAt(iOldSel - 1);
+ rtInvalidate.Union(lpDatesInfo->rect);
+ }
+ m_pOwner->AddSelDay(iCurSel);
+ CFWL_EvtClick wmClick;
+ wmClick.m_pSrcTarget = m_pOwner->m_pInterface;
+ m_pOwner->DispatchEvent(&wmClick);
+ CFWL_EventMcdDateChanged wmDateSelected;
+ wmDateSelected.m_iStartDay = iCurSel;
+ wmDateSelected.m_iEndDay = iCurSel;
+ wmDateSelected.m_iOldMonth = m_pOwner->m_iCurMonth;
+ wmDateSelected.m_iOldYear = m_pOwner->m_iCurYear;
+ wmDateSelected.m_pSrcTarget = (IFWL_MonthCalendar *)m_pOwner->m_pInterface;
+ m_pOwner->DispatchEvent(&wmDateSelected);
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+ }
+ }
+}
+void CFWL_MonthCalendarImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_rtLBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iLBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtLBtn);
+ } else if (m_pOwner->m_rtRBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_iRBtnPartStates = 0;
+ m_pOwner->Repaint(&m_pOwner->m_rtRBtn);
+ } else if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ FX_INT32 iDay = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ if (iDay != -1) {
+ m_pOwner->AddSelDay(iDay);
+ }
+ }
+}
+void CFWL_MonthCalendarImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_MCD_MultiSelect) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, 0, 0);
+ if (m_pOwner->m_rtDates.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ FX_INT32 iHover = m_pOwner->GetDayAtPoint(pMsg->m_fx, pMsg->m_fy);
+ bRepaint = m_pOwner->m_iHovered != iHover;
+ if (bRepaint) {
+ if (m_pOwner->m_iHovered > 0) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ if (iHover > 0) {
+ CFX_RectF rtDay;
+ m_pOwner->GetDayRect(iHover, rtDay);
+ if (rtInvalidate.IsEmpty()) {
+ rtInvalidate = rtDay;
+ } else {
+ rtInvalidate.Union(rtDay);
+ }
+ }
+ }
+ m_pOwner->m_iHovered = iHover;
+ } else {
+ bRepaint = m_pOwner->m_iHovered > 0;
+ if (bRepaint) {
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ }
+ m_pOwner->m_iHovered = -1;
+ }
+ if (bRepaint && !rtInvalidate.IsEmpty()) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+void CFWL_MonthCalendarImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_iHovered > 0) {
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Set(0, 0, 0, 0);
+ m_pOwner->GetDayRect(m_pOwner->m_iHovered, rtInvalidate);
+ m_pOwner->m_iHovered = -1;
+ if (!rtInvalidate.IsEmpty()) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+ }
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_pictureboximp.cpp b/xfa/src/fwl/src/basewidget/fwl_pictureboximp.cpp
new file mode 100644
index 0000000000..03f821518d
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_pictureboximp.cpp
@@ -0,0 +1,172 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_pictureboximp.h"
+IFWL_PictureBox* IFWL_PictureBox::Create()
+{
+ return new IFWL_PictureBox;
+}
+IFWL_PictureBox::IFWL_PictureBox()
+{
+ m_pData = NULL;
+}
+IFWL_PictureBox::~IFWL_PictureBox()
+{
+ if (m_pData) {
+ delete (CFWL_PictureBoxImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_PictureBox::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_PictureBoxImp(pOuter);
+ ((CFWL_PictureBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_PictureBoxImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_PictureBox::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_PictureBoxImp(properties, pOuter);
+ ((CFWL_PictureBoxImp*)m_pData)->SetInterface(this);
+ return ((CFWL_PictureBoxImp*)m_pData)->Initialize();
+}
+CFWL_PictureBoxImp::CFWL_PictureBoxImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_bTop(FALSE)
+ , m_bVCenter(FALSE)
+ , m_bButton(FALSE)
+{
+ m_rtClient.Reset();
+ m_rtImage.Reset();
+ m_matrix.Reset();
+}
+CFWL_PictureBoxImp::CFWL_PictureBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_bTop(FALSE)
+ , m_bVCenter(FALSE)
+ , m_bButton(FALSE)
+{
+ m_rtClient.Reset();
+ m_rtImage.Reset();
+ m_matrix.Reset();
+}
+CFWL_PictureBoxImp::~CFWL_PictureBoxImp()
+{
+}
+FWL_ERR CFWL_PictureBoxImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_PictureBox;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_PictureBoxImp::GetClassID() const
+{
+ return FWL_CLASSHASH_PictureBox;
+}
+FWL_ERR CFWL_PictureBoxImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_PictureBoxImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PictureBoxImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_PictureBoxImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_PictureBoxImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pDataProvider, FWL_ERR_Indefinite);
+ CFX_DIBitmap *pBitmap = ((IFWL_PictureBoxDP*)m_pProperties->m_pDataProvider)->GetPicture(m_pInterface);
+ if (pBitmap) {
+ rect.Set(0, 0, (FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)pBitmap->GetHeight());
+ }
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PictureBoxImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Succeeded;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ GetClientRect(m_rtClient);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PictureBoxImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = GetAvailableTheme();
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_PTB_Border, pTheme, pMatrix );
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_PTB_Edge, pTheme, pMatrix);
+ }
+ DrawBkground(pGraphics, pTheme, pMatrix);
+ return FWL_ERR_Succeeded;
+}
+void CFWL_PictureBoxImp::DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ _FWL_RETURN_IF_FAIL(m_pProperties->m_pDataProvider);
+ CFX_DIBitmap *pPicture = ((IFWL_PictureBoxDP*)m_pProperties->m_pDataProvider)->GetPicture(m_pInterface);
+ CFX_Matrix matrix;
+ ((IFWL_PictureBoxDP*)m_pProperties->m_pDataProvider)->GetMatrix(m_pInterface, matrix);
+ if (!pPicture) {
+ return;
+ }
+ matrix.Concat(*pMatrix);
+ FX_FLOAT fx = (FX_FLOAT)pPicture->GetWidth();
+ FX_FLOAT fy = (FX_FLOAT)pPicture->GetHeight();
+ if (fx > m_rtClient.width) {
+ fx = m_rtClient.width;
+ }
+ if (fy > m_rtClient.height) {
+ fy = m_rtClient.height;
+ }
+ CFX_PointF pt;
+ pt.Set((m_rtClient.width - fx) / 2, (m_rtClient.height - fy) / 2);
+ pGraphics->DrawImage(pPicture, pt, &matrix);
+}
+FX_BOOL CFWL_PictureBoxImp::VStyle(FX_BOOL dwStyle)
+{
+ switch(dwStyle & FWL_STYLEEXT_PTB_VAlignMask) {
+ case FWL_STYLEEXT_PTB_Top: {
+ return m_bTop = TRUE;
+ break;
+ }
+ case FWL_STYLEEXT_PTB_Vcenter: {
+ return m_bVCenter = TRUE;
+ break;
+ }
+ case FWL_STYLEEXT_PTB_Bottom: {
+ return m_bButton = TRUE;
+ break;
+ }
+ }
+ return FALSE;
+}
+CFWL_PictureBoxImpDelegate::CFWL_PictureBoxImpDelegate(CFWL_PictureBoxImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FWL_ERR CFWL_PictureBoxImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_pushbuttonimp.cpp b/xfa/src/fwl/src/basewidget/fwl_pushbuttonimp.cpp
new file mode 100644
index 0000000000..b3228e41f2
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_pushbuttonimp.cpp
@@ -0,0 +1,542 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_pushbuttonimp.h"
+IFWL_PushButton *IFWL_PushButton::Create()
+{
+ return new IFWL_PushButton;
+}
+FWL_ERR IFWL_PushButton::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_PushButtonImp(pOuter);
+ ((CFWL_PushButtonImp*)m_pData)->SetInterface(this);
+ return ((CFWL_PushButtonImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_PushButton::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_PushButtonImp(properties, pOuter);
+ ((CFWL_PushButtonImp*)m_pData)->SetInterface(this);
+ return ((CFWL_PushButtonImp*)m_pData)->Initialize();
+}
+IFWL_PushButton::IFWL_PushButton()
+{
+ m_pData = NULL;
+}
+IFWL_PushButton::~IFWL_PushButton()
+{
+ if (m_pData) {
+ delete (CFWL_PushButtonImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+CFWL_PushButtonImp::CFWL_PushButtonImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_bBtnDown(FALSE)
+ , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
+ , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
+{
+ m_rtClient.Set(0, 0, 0, 0);
+ m_rtCaption.Set(0, 0, 0, 0);
+}
+CFWL_PushButtonImp::CFWL_PushButtonImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_bBtnDown(FALSE)
+ , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
+ , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
+{
+ m_rtClient.Set(0, 0, 0, 0);
+ m_rtCaption.Set(0, 0, 0, 0);
+}
+CFWL_PushButtonImp::~CFWL_PushButtonImp()
+{
+}
+FWL_ERR CFWL_PushButtonImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_PushButton;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_PushButtonImp::GetClassID() const
+{
+ return FWL_CLASSHASH_PushButton;
+}
+FWL_ERR CFWL_PushButtonImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_PushButtonImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PushButtonImp::Finalize()
+{
+ if( m_pDelegate) {
+ delete (CFWL_PushButtonImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_PushButtonImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (m_pProperties->m_pThemeProvider == NULL) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ CFX_WideString wsCaption;
+ IFWL_PushButtonDP *pData = (IFWL_PushButtonDP*)m_pProperties->m_pDataProvider;
+ if (pData) {
+ pData->GetCaption(m_pInterface, wsCaption);
+ }
+ FX_INT32 iLen = wsCaption.GetLength();
+ if (iLen > 0) {
+ CFX_SizeF sz = CalcTextSize(wsCaption, m_pProperties->m_pThemeProvider);
+ rect.Set(0, 0, sz.x, sz.y);
+ }
+ FX_FLOAT *fcaption = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_PSB_Margin);
+ rect.Inflate(*fcaption, *fcaption);
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PushButtonImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
+{
+ if ((dwStates & FWL_WGTSTATE_Disabled) && bSet) {
+ m_pProperties->m_dwStates = FWL_WGTSTATE_Disabled;
+ return FWL_ERR_Succeeded;
+ }
+ return CFWL_WidgetImp::SetStates(dwStates, bSet);
+}
+FWL_ERR CFWL_PushButtonImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ UpdateTextOutStyles();
+ GetClientRect(m_rtClient);
+ m_rtCaption = m_rtClient;
+ FX_FLOAT *fcaption = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_PSB_Margin);
+ m_rtCaption.Inflate(-*fcaption, -*fcaption);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PushButtonImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_PushButtonDP *pData = (IFWL_PushButtonDP*)m_pProperties->m_pDataProvider;
+ CFX_DIBitmap *pPicture = NULL;
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_PSB_Border, m_pProperties->m_pThemeProvider, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_PSB_Edge, m_pProperties->m_pThemeProvider, pMatrix);
+ }
+ DrawBkground(pGraphics, m_pProperties->m_pThemeProvider, pMatrix);
+ CFX_Matrix matrix;
+ matrix.Concat(*pMatrix);
+ FX_FLOAT iPicwidth = 0;
+ FX_FLOAT ipicheight = 0;
+ CFX_WideString wsCaption;
+ if (pData) {
+ pData->GetCaption(m_pInterface, wsCaption);
+ }
+ CFX_RectF rtText;
+ rtText.Set(0, 0, 0 , 0);
+ if (!wsCaption.IsEmpty()) {
+ CalcTextRect(wsCaption, pTheme, 0, m_iTTOAlign, rtText);
+ }
+ switch(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_PSB_ModeMask) {
+ case FWL_STYLEEXT_PSB_TextOnly:
+ DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
+ break;
+ case FWL_STYLEEXT_PSB_IconOnly:
+ if (pData) {
+ pPicture = pData->GetPicture(m_pInterface);
+ }
+ if (pPicture) {
+ CFX_PointF point;
+ switch(m_iTTOAlign) {
+ case 0: {
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top;
+ break;
+ }
+ case 1: {
+ point.x = m_rtClient.left + (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
+ point.y = m_rtClient.top;
+ break;
+ }
+ case 2:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
+ point.y = m_rtClient.top;
+ break;
+ case 4:
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top + m_rtClient.height / 2 - pPicture->GetHeight() / 2;
+ break;
+ case 5:
+ point.x = m_rtClient.left + (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
+ point.y = m_rtClient.top + m_rtClient.height / 2 - pPicture->GetHeight() / 2;
+ break;
+ case 6:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
+ point.y = m_rtClient.top + m_rtClient.height / 2 - pPicture->GetHeight() / 2;
+ break;
+ case 8:
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ break;
+ case 9:
+ point.x = m_rtClient.left + (m_rtClient.width / 2 - pPicture->GetWidth() / 2);
+ point.y = m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ break;
+ case 10:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth();
+ point.y = m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ break;
+ }
+ pGraphics->DrawImage(pPicture, point, &matrix);
+ }
+ break;
+ case FWL_STYLEEXT_PSB_TextIcon:
+ if (pPicture) {
+ CFX_PointF point;
+ switch(m_iTTOAlign) {
+ case 0: {
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top;
+ iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
+ ipicheight = pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
+ break;
+ }
+ case 1: {
+ point.x = m_rtClient.left + (m_rtClient.width / 2 - (pPicture->GetWidth() + rtText.width) / 2);
+ point.y = m_rtClient.top;
+ iPicwidth = pPicture->GetWidth() - ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) + rtText.width / 2 - 7;
+ ipicheight = pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
+ break;
+ }
+ case 2:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth() - rtText.width;
+ point.y = m_rtClient.top;
+ iPicwidth = m_rtClient.left + m_rtClient.width - point.x - pPicture->GetWidth() - rtText.width + 7;
+ ipicheight = pPicture->GetHeight() / 2 - m_rtCaption.top - rtText.height / 2;
+ break;
+ case 4:
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top + m_rtClient.height / 2 - pPicture->GetHeight() / 2;
+ iPicwidth = m_rtClient.left + pPicture->GetWidth() - 7;
+ break;
+ case 5:
+ point.x = m_rtClient.left + (m_rtClient.width / 2 - (pPicture->GetWidth() + rtText.width) / 2);
+ point.y = m_rtClient.top + m_rtClient.height / 2 - pPicture->GetHeight() / 2;
+ iPicwidth = pPicture->GetWidth() - ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) + rtText.width / 2 - 7;
+ break;
+ case 6:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth() - rtText.width;
+ point.y = m_rtClient.top + m_rtClient.height / 2 - pPicture->GetHeight() / 2;
+ iPicwidth = m_rtClient.left + m_rtClient.width - point.x - pPicture->GetWidth() - rtText.width + 7;
+ break;
+ case 8:
+ point.x = m_rtClient.left;
+ point.y = m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ iPicwidth = (FX_FLOAT)(pPicture->GetWidth() - 7);
+ ipicheight -= rtText.height / 2;
+ break;
+ case 9:
+ point.x = m_rtClient.left + (m_rtClient.width / 2 - (pPicture->GetWidth() + rtText.width) / 2);
+ point.y = m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ iPicwidth = pPicture->GetWidth() - ((m_rtClient.width) / 2 - rtText.width / 2 - point.x) + rtText.width / 2 - 7;
+ ipicheight -= rtText.height / 2;
+ break;
+ case 10:
+ point.x = m_rtClient.left + m_rtClient.width - pPicture->GetWidth() - rtText.width;
+ point.y = m_rtClient.top + m_rtClient.height - pPicture->GetHeight();
+ iPicwidth = m_rtClient.left + m_rtClient.width - point.x - pPicture->GetWidth() - rtText.width + 7;
+ ipicheight -= rtText.height / 2;
+ break;
+ }
+ pGraphics->DrawImage(pPicture, point, &matrix);
+ }
+ matrix.e += m_rtClient.left + iPicwidth;
+ matrix.f += m_rtClient.top + ipicheight;
+ DrawText(pGraphics, m_pProperties->m_pThemeProvider, &matrix);
+ break;
+ }
+ return FWL_ERR_Succeeded;
+}
+void CFWL_PushButtonImp::DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_PSB_Background;
+ param.m_dwStates = GetPartStates();
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtClient;
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ param.m_pData = &m_rtCaption;
+ }
+ pTheme->DrawBackground(&param);
+}
+void CFWL_PushButtonImp::DrawText(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ _FWL_RETURN_IF_FAIL(m_pProperties->m_pDataProvider);
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption);
+ if (wsCaption.IsEmpty()) {
+ return;
+ }
+ CFWL_ThemeText param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_PSB_Caption;
+ param.m_dwStates = GetPartStates();
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtCaption;
+ param.m_wsText = wsCaption;
+ param.m_dwTTOStyles = m_dwTTOStyles;
+ param.m_iTTOAlign = m_iTTOAlign;
+ pTheme->DrawText(&param);
+}
+FX_DWORD CFWL_PushButtonImp::GetPartStates()
+{
+ FX_DWORD dwStates = FWL_PARTSTATE_PSB_Normal;
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ dwStates |= FWL_PARTSTATE_PSB_Focused;
+ }
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) {
+ dwStates = FWL_PARTSTATE_PSB_Disabled;
+ } else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) {
+ dwStates |= FWL_PARTSTATE_PSB_Pressed;
+ } else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) {
+ dwStates |= FWL_PARTSTATE_PSB_Hovered;
+ } else if (m_pProperties->m_dwStates & FWL_STATE_PSB_Default) {
+ dwStates |= FWL_PARTSTATE_PSB_Default;
+ }
+ return dwStates;
+}
+void CFWL_PushButtonImp::UpdateTextOutStyles()
+{
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ switch(m_pProperties->m_dwStyleExes & (FWL_STYLEEXT_PSB_HLayoutMask | FWL_STYLEEXT_PSB_VLayoutMask)) {
+ case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Top: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Top: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_TopCenter;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Top: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_TopRight;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_CenterLeft;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_VCenter: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_CenterRight;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Left | FWL_STYLEEXT_PSB_Bottom: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_BottomLeft;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Center | FWL_STYLEEXT_PSB_Bottom: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_BottomCenter;
+ break;
+ }
+ case FWL_STYLEEXT_PSB_Right | FWL_STYLEEXT_PSB_Bottom: {
+ m_iTTOAlign = FDE_TTOALIGNMENT_BottomRight;
+ break;
+ }
+ default: {
+ }
+ }
+ m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
+ }
+}
+CFWL_PushButtonImpDelegate::CFWL_PushButtonImpDelegate(CFWL_PushButtonImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_PushButtonImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ if (!m_pOwner->IsEnabled()) {
+ return 1;
+ }
+ FX_INT32 iRet = 1;
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch (dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ CFWL_MsgKey *pKey = (CFWL_MsgKey*)pMessage;
+ if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
+ OnKeyDown((CFWL_MsgKey*)pKey);
+ }
+ break;
+ }
+ default: {
+ iRet = 0;
+ break;
+ }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+ return iRet;
+}
+FWL_ERR CFWL_PushButtonImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PushButtonImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_PushButtonImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet )
+{
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_PushButtonImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) {
+ m_pOwner->SetFocus(TRUE);
+ }
+ m_pOwner->m_bBtnDown = TRUE;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_PushButtonImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->m_bBtnDown = FALSE;
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ }
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ CFWL_EvtClick wmClick;
+ wmClick.m_pSrcTarget = (IFWL_PushButton*)m_pOwner->m_pInterface;
+ m_pOwner->DispatchEvent(&wmClick);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_PushButtonImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ FX_BOOL bRepaint = FALSE;
+ if (m_pOwner->m_bBtnDown) {
+ if (m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Pressed;
+ bRepaint = TRUE;
+ }
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
+ bRepaint = TRUE;
+ }
+ } else {
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Pressed) {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ bRepaint = TRUE;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ bRepaint = TRUE;
+ }
+ }
+ } else {
+ if (!m_pOwner->m_rtClient.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ return;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStates & FWL_STATE_PSB_Hovered) == 0) {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_STATE_PSB_Hovered;
+ bRepaint = TRUE;
+ }
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+ }
+}
+void CFWL_PushButtonImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->m_bBtnDown = FALSE;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Hovered;
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_STATE_PSB_Pressed;
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_PushButtonImpDelegate::OnKeyDown(CFWL_MsgKey *pMsg)
+{
+ if (pMsg->m_dwKeyCode == FWL_VKEY_Return) {
+ CFWL_EvtMouse wmMouse;
+ wmMouse.m_pSrcTarget = m_pOwner->m_pInterface;
+ wmMouse.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
+ m_pOwner->DispatchEvent(&wmMouse);
+ CFWL_EvtClick wmClick;
+ wmClick.m_pSrcTarget = (IFWL_PushButton*)m_pOwner->m_pInterface;
+ m_pOwner->DispatchEvent(&wmClick);
+ return;
+ }
+ if (pMsg->m_dwKeyCode != FWL_VKEY_Tab) {
+ return;
+ }
+ m_pOwner->DispatchKeyEvent(pMsg);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_scrollbarimp.cpp b/xfa/src/fwl/src/basewidget/fwl_scrollbarimp.cpp
new file mode 100644
index 0000000000..8162c9d9e8
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_scrollbarimp.cpp
@@ -0,0 +1,852 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_scrollbarimp.h"
+#define FWL_SCROLLBAR_Elapse 500
+#define FWL_SCROLLBAR_MinThumb 5
+IFWL_ScrollBar* IFWL_ScrollBar::Create()
+{
+ return new IFWL_ScrollBar;
+}
+IFWL_ScrollBar::IFWL_ScrollBar()
+{
+ m_pData = NULL;
+}
+IFWL_ScrollBar::~IFWL_ScrollBar()
+{
+ if (m_pData) {
+ delete (CFWL_ScrollBarImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_ScrollBar::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ScrollBarImp(pOuter);
+ ((CFWL_ScrollBarImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ScrollBarImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_ScrollBar::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ScrollBarImp(properties, pOuter);
+ ((CFWL_ScrollBarImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ScrollBarImp*)m_pData)->Initialize();
+}
+FX_BOOL IFWL_ScrollBar::IsVertical()
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->IsVertical();
+}
+FWL_ERR IFWL_ScrollBar::GetRange(FX_FLOAT &fMin, FX_FLOAT &fMax)
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->GetRange(fMin, fMax);
+}
+FWL_ERR IFWL_ScrollBar::SetRange(FX_FLOAT fMin, FX_FLOAT fMax)
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->SetRange(fMin, fMax);
+}
+FX_FLOAT IFWL_ScrollBar::GetPageSize()
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->GetPageSize();
+}
+FWL_ERR IFWL_ScrollBar::SetPageSize(FX_FLOAT fPageSize)
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->SetPageSize(fPageSize);
+}
+FX_FLOAT IFWL_ScrollBar::GetStepSize()
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->GetStepSize();
+}
+FWL_ERR IFWL_ScrollBar::SetStepSize(FX_FLOAT fStepSize)
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->SetStepSize(fStepSize);
+}
+FX_FLOAT IFWL_ScrollBar::GetPos()
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->GetPos();
+}
+FWL_ERR IFWL_ScrollBar::SetPos(FX_FLOAT fPos)
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->SetPos(fPos);
+}
+FX_FLOAT IFWL_ScrollBar::GetTrackPos()
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->GetTrackPos();
+}
+FWL_ERR IFWL_ScrollBar::SetTrackPos(FX_FLOAT fTrackPos)
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->SetTrackPos(fTrackPos);
+}
+FX_BOOL IFWL_ScrollBar::DoScroll(FX_DWORD dwCode, FX_FLOAT fPos)
+{
+ return ((CFWL_ScrollBarImp*)m_pData)->DoScroll(dwCode, fPos);
+}
+CFWL_ScrollBarImp::CFWL_ScrollBarImp(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_hTimer(NULL)
+ , m_fRangeMin(0)
+ , m_fRangeMax(-1)
+ , m_fPageSize(0)
+ , m_fStepSize(0)
+ , m_fPos(0)
+ , m_fTrackPos(0)
+ , m_iMinButtonState(FWL_PARTSTATE_SCB_Normal)
+ , m_iMaxButtonState(FWL_PARTSTATE_SCB_Normal)
+ , m_iThumbButtonState(FWL_PARTSTATE_SCB_Normal)
+ , m_fLastTrackPos(0)
+ , m_cpTrackPointX(0)
+ , m_cpTrackPointY(0)
+ , m_iMinTrackState(FWL_PARTSTATE_SCB_Normal)
+ , m_iMaxTrackState(FWL_PARTSTATE_SCB_Normal)
+ , m_iMouseWheel(0)
+ , m_bTrackMouseLeave(FALSE)
+ , m_bMouseHover(FALSE)
+ , m_bRepaintThumb(FALSE)
+ , m_bMouseDown(FALSE)
+ , m_fButtonLen(0)
+ , m_bMinSize(FALSE)
+ , m_bCustomLayout(FALSE)
+ , m_fMinThumb(FWL_SCROLLBAR_MinThumb)
+{
+ m_rtClient.Reset();
+ m_rtThumb.Reset();
+ m_rtMinBtn.Reset();
+ m_rtMaxBtn.Reset();
+ m_rtMinTrack.Reset();
+ m_rtMaxTrack.Reset();
+}
+CFWL_ScrollBarImp::CFWL_ScrollBarImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget* pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_hTimer(NULL)
+ , m_fRangeMin(0)
+ , m_fRangeMax(-1)
+ , m_fPageSize(0)
+ , m_fStepSize(0)
+ , m_fPos(0)
+ , m_fTrackPos(0)
+ , m_iMinButtonState(FWL_PARTSTATE_SCB_Normal)
+ , m_iMaxButtonState(FWL_PARTSTATE_SCB_Normal)
+ , m_iThumbButtonState(FWL_PARTSTATE_SCB_Normal)
+ , m_fLastTrackPos(0)
+ , m_cpTrackPointX(0)
+ , m_cpTrackPointY(0)
+ , m_iMinTrackState(FWL_PARTSTATE_SCB_Normal)
+ , m_iMaxTrackState(FWL_PARTSTATE_SCB_Normal)
+ , m_iMouseWheel(0)
+ , m_bTrackMouseLeave(FALSE)
+ , m_bMouseHover(FALSE)
+ , m_bRepaintThumb(FALSE)
+ , m_bMouseDown(FALSE)
+ , m_fButtonLen(0)
+ , m_bMinSize(FALSE)
+ , m_bCustomLayout(FALSE)
+ , m_fMinThumb(FWL_SCROLLBAR_MinThumb)
+{
+ m_rtClient.Reset();
+ m_rtThumb.Reset();
+ m_rtMinBtn.Reset();
+ m_rtMaxBtn.Reset();
+ m_rtMinTrack.Reset();
+ m_rtMaxTrack.Reset();
+}
+CFWL_ScrollBarImp::~CFWL_ScrollBarImp()
+{
+}
+FWL_ERR CFWL_ScrollBarImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_ScrollBar;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ScrollBarImp::GetClassID() const
+{
+ return FWL_CLASSHASH_ScrollBar;
+}
+FWL_ERR CFWL_ScrollBarImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*)FX_NEW CFWL_ScrollBarImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ScrollBarImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_ScrollBarImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_ScrollBarImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ FX_FLOAT *pfMinWidth = (FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth);
+ _FWL_RETURN_VALUE_IF_FAIL(pfMinWidth, FWL_ERR_Indefinite);
+ if (IsVertical()) {
+ rect.Set(0, 0, (*pfMinWidth), (*pfMinWidth) * 3);
+ } else {
+ rect.Set(0, 0, (*pfMinWidth) * 3, (*pfMinWidth));
+ }
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ScrollBarImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ Layout();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ScrollBarImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_SCB_Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_SCB_Edge, pTheme, pMatrix);
+ }
+ DrawTrack(pGraphics, pTheme, TRUE, pMatrix);
+ DrawTrack(pGraphics, pTheme, FALSE, pMatrix);
+ DrawArrowBtn(pGraphics, pTheme, TRUE, pMatrix);
+ DrawArrowBtn(pGraphics, pTheme, FALSE, pMatrix);
+ DrawThumb(pGraphics, pTheme, pMatrix);
+ return FWL_ERR_Succeeded;
+}
+inline FX_BOOL CFWL_ScrollBarImp::IsVertical()
+{
+ return m_pProperties->m_dwStyleExes & FWL_STYLEEXT_SCB_Vert;
+}
+FWL_ERR CFWL_ScrollBarImp::GetRange(FX_FLOAT &fMin, FX_FLOAT &fMax)
+{
+ fMin = m_fRangeMin;
+ fMax = m_fRangeMax;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ScrollBarImp::SetRange(FX_FLOAT fMin, FX_FLOAT fMax)
+{
+ m_fRangeMin = fMin;
+ m_fRangeMax = fMax;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_ScrollBarImp::GetPageSize()
+{
+ return m_fPageSize;
+}
+FWL_ERR CFWL_ScrollBarImp::SetPageSize(FX_FLOAT fPageSize)
+{
+ m_fPageSize = fPageSize;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_ScrollBarImp::GetStepSize()
+{
+ return m_fStepSize;
+}
+FWL_ERR CFWL_ScrollBarImp::SetStepSize(FX_FLOAT fStepSize)
+{
+ m_fStepSize = fStepSize;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_ScrollBarImp::GetPos()
+{
+ return m_fPos;
+}
+FWL_ERR CFWL_ScrollBarImp::SetPos(FX_FLOAT fPos)
+{
+ m_fPos = fPos;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_ScrollBarImp::GetTrackPos()
+{
+ return m_fTrackPos;
+}
+FWL_ERR CFWL_ScrollBarImp::SetTrackPos(FX_FLOAT fTrackPos)
+{
+ m_fTrackPos = fTrackPos;
+ CalcThumbButtonRect(m_rtThumb);
+ CalcMinTrackRect(m_rtMinTrack);
+ CalcMaxTrackRect(m_rtMaxTrack);
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_ScrollBarImp::DoScroll(FX_DWORD dwCode, FX_FLOAT fPos )
+{
+ switch (dwCode) {
+ case FWL_SCBCODE_Min:
+ case FWL_SCBCODE_Max:
+ case FWL_SCBCODE_PageBackward:
+ case FWL_SCBCODE_PageForward:
+ case FWL_SCBCODE_StepBackward:
+ break;
+ case FWL_SCBCODE_StepForward:
+ break;
+ case FWL_SCBCODE_Pos:
+ case FWL_SCBCODE_TrackPos:
+ case FWL_SCBCODE_EndScroll:
+ break;
+ default: {
+ return FALSE;
+ }
+ }
+ return OnScroll(dwCode, fPos);
+}
+FX_INT32 CFWL_ScrollBarImp::Run(FWL_HTIMER hTimer)
+{
+ if (m_hTimer) {
+ FWL_StopTimer(m_hTimer);
+ }
+ if (!SendEvent()) {
+ m_hTimer = FWL_StartTimer(this, 0);
+ }
+ return 1;
+}
+FWL_ERR CFWL_ScrollBarImp::SetOuter(IFWL_Widget *pOuter)
+{
+ m_pOuter = pOuter;
+ return FWL_ERR_Succeeded;
+}
+void CFWL_ScrollBarImp::DrawTrack(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, FX_BOOL bLower , const CFX_Matrix *pMatrix )
+{
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = bLower ? FWL_PART_SCB_LowerTrack : FWL_PART_SCB_UpperTrack;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ?
+ FWL_PARTSTATE_SCB_Disabled : (bLower ? m_iMinTrackState : m_iMaxTrackState);
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = bLower ? m_rtMinTrack : m_rtMaxTrack;
+ pTheme->DrawBackground(&param);
+}
+void CFWL_ScrollBarImp::DrawArrowBtn(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, FX_BOOL bMinBtn , const CFX_Matrix *pMatrix )
+{
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = bMinBtn ? FWL_PART_SCB_ForeArrow : FWL_PART_SCB_BackArrow;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ?
+ FWL_PARTSTATE_SCB_Disabled : (bMinBtn ? m_iMinButtonState : m_iMaxButtonState);
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = bMinBtn ? m_rtMinBtn : m_rtMaxBtn;
+ if (param.m_rtPart.height > 0 && param.m_rtPart.width > 0) {
+ pTheme->DrawBackground(&param);
+ }
+}
+void CFWL_ScrollBarImp::DrawThumb(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix )
+{
+ if (!IsEnabled()) {
+ }
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_SCB_Thumb;
+ param.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ?
+ FWL_PARTSTATE_SCB_Disabled : m_iThumbButtonState;
+ param.m_pGraphics = pGraphics;
+ param.m_matrix.Concat(*pMatrix);
+ param.m_rtPart = m_rtThumb;
+ pTheme->DrawBackground(&param);
+}
+void CFWL_ScrollBarImp::Layout()
+{
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pInterface;
+ m_fMinThumb = *(FX_FLOAT*)pTheme->GetCapacity(&part, FWL_CAPACITY_SCB_Size);
+ m_bCustomLayout = pTheme->IsCustomizedLayout(m_pInterface);
+ GetClientRect(m_rtClient);
+ CalcButtonLen();
+ CalcMinButtonRect(m_rtMinBtn);
+ CalcMaxButtonRect(m_rtMaxBtn);
+ CalcThumbButtonRect(m_rtThumb);
+ CalcMinTrackRect(m_rtMinTrack);
+ CalcMaxTrackRect(m_rtMaxTrack);
+}
+void CFWL_ScrollBarImp::CalcButtonLen()
+{
+ m_fButtonLen = IsVertical() ? m_rtClient.width : m_rtClient.height;
+ FX_FLOAT fLength = IsVertical() ? m_rtClient.height : m_rtClient.width;
+ if (fLength < m_fButtonLen * 2) {
+ m_fButtonLen = fLength / 2;
+ m_bMinSize = TRUE;
+ } else {
+ m_bMinSize = FALSE;
+ }
+}
+void CFWL_ScrollBarImp::CalcMinButtonRect(CFX_RectF &rect)
+{
+ if (m_bCustomLayout) {
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ CFWL_ThemePart pPart;
+ pPart.m_rtPart = m_rtMinBtn;
+ pPart.m_pWidget = m_pInterface;
+ pPart.m_iPart = FWL_PART_SCB_ForeArrow;
+ pPart.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ? FWL_PARTSTATE_SCB_Disabled : m_iMinButtonState;
+ pTheme->GetPartRect(&pPart, rect);
+ } else {
+ rect.left = m_rtClient.left;
+ rect.top = m_rtClient.top;
+ rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen;
+ rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height;
+ }
+}
+void CFWL_ScrollBarImp::CalcMaxButtonRect(CFX_RectF &rect)
+{
+ if (m_bCustomLayout) {
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ CFWL_ThemePart pPart;
+ pPart.m_rtPart = m_rtMaxBtn;
+ pPart.m_pWidget = m_pInterface;
+ pPart.m_iPart = FWL_PART_SCB_BackArrow;
+ pPart.m_dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) ? FWL_PARTSTATE_SCB_Disabled : m_iMaxButtonState;
+ pTheme->GetPartRect(&pPart, rect);
+ } else {
+ rect.left = IsVertical() ? m_rtClient.left : m_rtClient.right() - m_fButtonLen;
+ rect.top = IsVertical() ? m_rtClient.bottom() - m_fButtonLen : m_rtClient.top;
+ rect.width = IsVertical() ? m_rtClient.width : m_fButtonLen;
+ rect.height = IsVertical() ? m_fButtonLen : m_rtClient.height;
+ }
+}
+void CFWL_ScrollBarImp::CalcThumbButtonRect(CFX_RectF &rect)
+{
+ if (!IsEnabled()) {
+ m_rtThumb.Reset();
+ return;
+ }
+ if (m_bMinSize) {
+ m_rtThumb.Empty();
+ return;
+ }
+ FX_FLOAT fRange = m_fRangeMax - m_fRangeMin;
+ memset(&rect, 0, sizeof(CFX_Rect));
+ if (fRange < 0) {
+ if (IsVertical()) {
+ rect.Set(m_rtClient.left, m_rtMaxBtn.bottom(), m_rtClient.width, 0);
+ } else {
+ rect.Set(m_rtMaxBtn.right(), m_rtClient.top, 0, m_rtClient.height);
+ }
+ return;
+ }
+ CFX_RectF rtClient = m_rtClient;
+ FX_FLOAT fLength = IsVertical() ? rtClient.height : rtClient.width;
+ FX_FLOAT fSize = m_fButtonLen;
+ if (m_bCustomLayout) {
+ if (IsVertical()) {
+ fLength = fLength - m_rtMinBtn.height - m_rtMaxBtn.height;
+ if (fLength < m_rtMinBtn.height || fLength < m_rtMaxBtn.height) {
+ fLength = 0.0f;
+ }
+ } else {
+ fLength = fLength - m_rtMinBtn.width - m_rtMaxBtn.width;
+ if (fLength < m_rtMinBtn.width || fLength < m_rtMaxBtn.width) {
+ fLength = 0.0f;
+ }
+ }
+ } else {
+ fLength -= fSize * 2.0f;
+ if (fLength < fSize) {
+ fLength = 0.0f;
+ }
+ }
+ FX_FLOAT fThumbSize = fLength * fLength / (fRange + fLength);
+ if (fThumbSize < m_fMinThumb) {
+ fThumbSize = m_fMinThumb;
+ }
+ FX_FLOAT fDiff = fLength - fThumbSize;
+ if (fDiff < 0.0f) {
+ fDiff = 0.0f;
+ }
+ FX_FLOAT fTrackPos = m_fTrackPos;
+ if (fTrackPos > m_fRangeMax) {
+ fTrackPos = m_fRangeMax;
+ }
+ if (fTrackPos < m_fRangeMin) {
+ fTrackPos = m_fRangeMin;
+ }
+ _FWL_RETURN_IF_FAIL(fRange);
+ if (m_bCustomLayout) {
+ FX_FLOAT iPos = fDiff * (fTrackPos - m_fRangeMin) / fRange;
+ rect.left = rtClient.left;
+ if (!IsVertical()) {
+ if ((m_rtMinBtn.right() == m_rtMaxBtn.left && m_rtMinBtn.width > 0 && m_rtMaxBtn.width > 0) || (0 == m_rtMinBtn.width && 0 == m_rtMaxBtn.width)) {
+ rect.left += iPos;
+ } else {
+ rect.left += m_rtMinBtn.right() + iPos;
+ }
+ }
+ rect.top = rtClient.top;
+ if (IsVertical()) {
+ if ((m_rtMinBtn.bottom() == m_rtMaxBtn.top && m_rtMinBtn.height > 0 && m_rtMaxBtn.height > 0) || (0 == m_rtMinBtn.height && 0 == m_rtMaxBtn.height)) {
+ rect.top += iPos;
+ } else {
+ rect.top += m_rtMinBtn.bottom() + iPos;
+ }
+ }
+ rect.width = IsVertical() ? rtClient.width : fThumbSize;
+ rect.height = IsVertical() ? fThumbSize : rtClient.height;
+ } else {
+ FX_FLOAT iPos = fSize + fDiff * (fTrackPos - m_fRangeMin) / fRange;
+ rect.left = rtClient.left;
+ if (!IsVertical()) {
+ rect.left += iPos;
+ }
+ rect.top = rtClient.top;
+ if (IsVertical()) {
+ rect.top += iPos;
+ }
+ rect.width = IsVertical() ? rtClient.width : fThumbSize;
+ rect.height = IsVertical() ? fThumbSize : rtClient.height;
+ }
+}
+void CFWL_ScrollBarImp::CalcMinTrackRect(CFX_RectF &rect)
+{
+ if (m_bMinSize) {
+ rect.Empty();
+ return;
+ }
+ FX_FLOAT fBottom = m_rtThumb.bottom();
+ FX_FLOAT fRight = m_rtThumb.right();
+ FX_FLOAT ix = (m_rtThumb.left + fRight) / 2;
+ FX_FLOAT iy = (m_rtThumb.top + fBottom) / 2;
+ rect.left = m_rtClient.left;
+ rect.top = m_rtClient.top;
+ FX_BOOL bVertical = IsVertical();
+ rect.width = bVertical ? m_rtClient.width : ix;
+ rect.height = bVertical ? iy : m_rtClient.height;
+ if (m_bCustomLayout) {
+ if (bVertical) {
+ if (0 == m_rtMinBtn.height && 0 == m_rtMaxBtn.height) {
+ rect.top = m_rtClient.top;
+ } else if (m_rtMinBtn.top < m_rtThumb.top) {
+ rect.top = m_rtMinBtn.bottom();
+ rect.height -= (m_rtMinBtn.bottom() - m_rtClient.top);
+ }
+ } else {
+ if (0 == m_rtMinBtn.width && 0 == m_rtMaxBtn.width) {
+ rect.left = m_rtClient.left;
+ } else if (m_rtMinBtn.left < m_rtThumb.left) {
+ rect.left = m_rtMinBtn.right();
+ rect.width -= (m_rtMinBtn.right() - m_rtClient.left);
+ }
+ }
+ }
+}
+void CFWL_ScrollBarImp::CalcMaxTrackRect(CFX_RectF &rect)
+{
+ if (m_bMinSize) {
+ rect.Empty();
+ return;
+ }
+ FX_FLOAT ix = (m_rtThumb.left + m_rtThumb.right()) / 2;
+ FX_FLOAT iy = (m_rtThumb.top + m_rtThumb.bottom()) / 2;
+ FX_BOOL bVertical = IsVertical();
+ rect.left = bVertical ? m_rtClient.left : ix;
+ rect.top = bVertical ? iy : m_rtClient.top;
+ rect.width = bVertical ? m_rtClient.width : m_rtClient.right() - ix;
+ rect.height = bVertical ? m_rtClient.bottom() - iy : m_rtClient.height;
+ if (m_bCustomLayout) {
+ if (bVertical) {
+ if (m_rtMinBtn.top > m_rtThumb.top && m_rtMinBtn.height > 0 && m_rtMaxBtn.height > 0) {
+ rect.height -= (m_rtClient.bottom() - m_rtMinBtn.top);
+ } else if (m_rtMinBtn.height > 0 && m_rtMaxBtn.height > 0) {
+ rect.height -= (m_rtClient.bottom() - m_rtMaxBtn.top);
+ }
+ } else {
+ if (m_rtMinBtn.left > m_rtThumb.left && m_rtMinBtn.width > 0 && m_rtMaxBtn.width > 0) {
+ rect.width -= (m_rtClient.right() - m_rtMinBtn.left);
+ } else if (m_rtMinBtn.width > 0 && m_rtMaxBtn.width > 0) {
+ rect.width -= (m_rtClient.right() - m_rtMaxBtn.left);
+ }
+ }
+ }
+}
+FX_FLOAT CFWL_ScrollBarImp::GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy)
+{
+ FX_FLOAT fDiffX = fx - m_cpTrackPointX;
+ FX_FLOAT fDiffY = fy - m_cpTrackPointY;
+ FX_FLOAT fRange = m_fRangeMax - m_fRangeMin;
+ FX_FLOAT fPos;
+ if (m_bCustomLayout) {
+ if (IsVertical()) {
+ if (0 == m_rtMinBtn.height && 0 == m_rtMaxBtn.height) {
+ fPos = fRange * fDiffY / (m_rtClient.height - m_rtThumb.height);
+ } else if (m_rtMinBtn.bottom() == m_rtMaxBtn.top) {
+ fPos = fRange * fDiffY / (m_rtMinBtn.top - m_rtClient.top - m_rtThumb.height);
+ } else {
+ fPos = fRange * fDiffY / (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height);
+ }
+ } else {
+ if (0 == m_rtMinBtn.width && 0 == m_rtMaxBtn.width) {
+ fPos = fRange * fDiffX / (m_rtClient.width - m_rtThumb.width);
+ } else if (m_rtMinBtn.right() == m_rtMaxBtn.left) {
+ fPos = fRange * fDiffX / (m_rtMinBtn.left - m_rtClient.left - m_rtThumb.width);
+ } else {
+ fPos = fRange * fDiffX / (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width);
+ }
+ }
+ } else {
+ if (IsVertical()) {
+ fPos = fRange * fDiffY / (m_rtMaxBtn.top - m_rtMinBtn.bottom() - m_rtThumb.height);
+ } else {
+ fPos = fRange * fDiffX / (m_rtMaxBtn.left - m_rtMinBtn.right() - m_rtThumb.width);
+ }
+ }
+ fPos += m_fLastTrackPos;
+ if (fPos < m_fRangeMin) {
+ fPos = m_fRangeMin;
+ }
+ if (fPos > m_fRangeMax) {
+ fPos = m_fRangeMax;
+ }
+ return fPos;
+}
+void CFWL_ScrollBarImp::GetTrackRect(CFX_RectF &rect, FX_BOOL bLower )
+{
+ FX_BOOL bDisabled = m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled;
+ if (bDisabled || m_bCustomLayout) {
+ rect = bLower ? m_rtMinTrack : m_rtMaxTrack;
+ } else {
+ FX_FLOAT fW = m_rtThumb.width / 2;
+ FX_FLOAT fH = m_rtThumb.height / 2;
+ FX_BOOL bVert = IsVertical();
+ if (bLower) {
+ if (bVert) {
+ FX_FLOAT fMinTrackHeight = m_rtMinTrack.height - fH - m_rtMinBtn.height;
+ fMinTrackHeight = (fMinTrackHeight >= 0.0f) ? fMinTrackHeight : 0.0f;
+ rect.Set(m_rtMinTrack.left,
+ m_rtMinTrack.top + m_rtMinBtn.height,
+ m_rtMinTrack.width,
+ fMinTrackHeight);
+ } else {
+ FX_FLOAT fMinTrackWidth = m_rtMinTrack.width - fW - m_rtMinBtn.width + 2;
+ fMinTrackWidth = (fMinTrackWidth >= 0.0f) ? fMinTrackWidth : 0.0f;
+ rect.Set(m_rtMinTrack.left + m_rtMinBtn.width - 1,
+ m_rtMinTrack.top,
+ fMinTrackWidth,
+ m_rtMinTrack.height);
+ }
+ } else {
+ if (bVert) {
+ FX_FLOAT fMaxTrackHeight = m_rtMaxTrack.height - fH - m_rtMaxBtn.height;
+ fMaxTrackHeight = (fMaxTrackHeight >= 0.0f) ? fMaxTrackHeight : 0.0f;
+ rect.Set(m_rtMaxTrack.left,
+ m_rtMaxTrack.top + fH,
+ m_rtMaxTrack.width,
+ fMaxTrackHeight);
+ } else {
+ FX_FLOAT fMaxTrackWidth = m_rtMaxTrack.width - fW - m_rtMaxBtn.width + 2;
+ fMaxTrackWidth = (fMaxTrackWidth >= 0.0f) ? fMaxTrackWidth : 0.0f;
+ rect.Set(m_rtMaxTrack.left + fW,
+ m_rtMaxTrack.top,
+ fMaxTrackWidth,
+ m_rtMaxTrack.height);
+ }
+ }
+ }
+}
+FX_BOOL CFWL_ScrollBarImp::SendEvent()
+{
+ if (m_iMinButtonState == FWL_PARTSTATE_SCB_Pressed) {
+ DoScroll(FWL_SCBCODE_StepBackward, m_fTrackPos);
+ return FALSE;
+ }
+ if (m_iMaxButtonState == FWL_PARTSTATE_SCB_Pressed) {
+ DoScroll(FWL_SCBCODE_StepForward, m_fTrackPos);
+ return FALSE;
+ }
+ if (m_iMinTrackState == FWL_PARTSTATE_SCB_Pressed) {
+ DoScroll(FWL_SCBCODE_PageBackward, m_fTrackPos);
+ return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY);
+ }
+ if (m_iMaxTrackState == FWL_PARTSTATE_SCB_Pressed) {
+ DoScroll(FWL_SCBCODE_PageForward, m_fTrackPos);
+ return m_rtThumb.Contains(m_cpTrackPointX, m_cpTrackPointY);
+ }
+ if (m_iMouseWheel) {
+ FX_WORD dwCode = m_iMouseWheel < 0 ? FWL_SCBCODE_StepForward : FWL_SCBCODE_StepBackward;
+ DoScroll(dwCode, m_fTrackPos);
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_ScrollBarImp::OnScroll(FX_DWORD dwCode, FX_FLOAT fPos)
+{
+ FX_BOOL bRet = TRUE;
+ CFWL_EvtScroll ev;
+ ev.m_iScrollCode = dwCode;
+ ev.m_pSrcTarget = m_pInterface;
+ ev.m_fPos = fPos;
+ ev.m_pRet = &bRet;
+ DispatchEvent(&ev);
+ return bRet;
+}
+CFWL_ScrollBarImpDelegate::CFWL_ScrollBarImpDelegate(CFWL_ScrollBarImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_ScrollBarImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_INT32 iRet = 1;
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ if (dwMsgCode == FWL_MSGHASH_Mouse) {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch (dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg->m_dwFlags, pMsg->m_fx, pMsg->m_fy);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave();
+ break;
+ }
+ default: {
+ iRet = 0;
+ }
+ }
+ } else if (dwMsgCode == FWL_MSGHASH_MouseWheel) {
+ CFWL_MsgMouseWheel *pMsg = (CFWL_MsgMouseWheel*)pMessage;
+ OnMouseWheel(pMsg->m_fx, pMsg->m_fy, pMsg->m_dwFlags, pMsg->m_fDeltaX, pMsg->m_fDeltaY);
+ } else {
+ iRet = 0;
+ }
+ return iRet;
+}
+FWL_ERR CFWL_ScrollBarImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_ScrollBarImpDelegate::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pOwner->IsEnabled()) {
+ return;
+ }
+ m_pOwner->m_bMouseDown = TRUE;
+ m_pOwner->SetGrab(TRUE);
+ m_pOwner->m_cpTrackPointX = fx;
+ m_pOwner->m_cpTrackPointY = fy;
+ m_pOwner->m_fLastTrackPos = m_pOwner->m_fTrackPos;
+ if (m_pOwner->m_rtMinBtn.Contains(fx, fy)) {
+ DoMouseDown(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState, fx, fy);
+ } else {
+ if (m_pOwner->m_rtThumb.Contains(fx, fy)) {
+ DoMouseDown(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState, fx, fy);
+ } else {
+ if (m_pOwner->m_rtMaxBtn.Contains(fx, fy)) {
+ DoMouseDown(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState, fx, fy);
+ } else {
+ if (m_pOwner->m_rtMinTrack.Contains(fx, fy)) {
+ DoMouseDown(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState, fx, fy);
+ } else {
+ DoMouseDown(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState, fx, fy);
+ }
+ }
+ }
+ }
+ if (!m_pOwner->SendEvent()) {
+ m_pOwner->m_hTimer = FWL_StartTimer(m_pOwner, FWL_SCROLLBAR_Elapse);
+ }
+}
+void CFWL_ScrollBarImpDelegate::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ FWL_StopTimer(m_pOwner->m_hTimer);
+ m_pOwner->m_bMouseDown = FALSE;
+ DoMouseUp(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState, fx, fy);
+ DoMouseUp(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState, fx, fy);
+ DoMouseUp(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState, fx, fy);
+ DoMouseUp(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState, fx, fy);
+ DoMouseUp(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState, fx, fy);
+ m_pOwner->SetGrab(FALSE);
+}
+void CFWL_ScrollBarImpDelegate::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ DoMouseMove(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState, fx, fy);
+ DoMouseMove(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState, fx, fy);
+ DoMouseMove(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState, fx, fy);
+ DoMouseMove(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState, fx, fy);
+ DoMouseMove(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState, fx, fy);
+}
+void CFWL_ScrollBarImpDelegate::OnMouseLeave()
+{
+ DoMouseLeave(0, m_pOwner->m_rtMinBtn, m_pOwner->m_iMinButtonState);
+ DoMouseLeave(1, m_pOwner->m_rtThumb, m_pOwner->m_iThumbButtonState);
+ DoMouseLeave(2, m_pOwner->m_rtMaxBtn, m_pOwner->m_iMaxButtonState);
+ DoMouseLeave(3, m_pOwner->m_rtMinTrack, m_pOwner->m_iMinTrackState);
+ DoMouseLeave(4, m_pOwner->m_rtMaxTrack, m_pOwner->m_iMaxTrackState);
+}
+void CFWL_ScrollBarImpDelegate::OnMouseWheel(FX_FLOAT fx, FX_FLOAT fy, FX_DWORD dwFlags, FX_FLOAT fDeltaX, FX_FLOAT fDeltaY)
+{
+ m_pOwner->m_iMouseWheel = (FX_INT32)fDeltaX;
+ m_pOwner->SendEvent();
+ m_pOwner->m_iMouseWheel = 0;
+}
+void CFWL_ScrollBarImpDelegate::DoMouseDown(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!rtItem.Contains(fx, fy)) {
+ return;
+ }
+ if (iState == FWL_PARTSTATE_SCB_Pressed) {
+ return;
+ }
+ iState = FWL_PARTSTATE_SCB_Pressed;
+ m_pOwner->Repaint(&rtItem);
+}
+void CFWL_ScrollBarImpDelegate::DoMouseUp(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState, FX_FLOAT fx, FX_FLOAT fy)
+{
+ FX_INT32 iNewState = rtItem.Contains(fx, fy) ? FWL_PARTSTATE_SCB_Hovered : FWL_PARTSTATE_SCB_Normal;
+ if (iState == iNewState) {
+ return;
+ }
+ iState = iNewState;
+ m_pOwner->Repaint(&rtItem);
+ m_pOwner->OnScroll(FWL_SCBCODE_EndScroll, m_pOwner->m_fTrackPos);
+}
+void CFWL_ScrollBarImpDelegate::DoMouseMove(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pOwner->m_bMouseDown) {
+ FX_INT32 iNewState = rtItem.Contains(fx, fy) ? FWL_PARTSTATE_SCB_Hovered : FWL_PARTSTATE_SCB_Normal;
+ if (iState == iNewState) {
+ return;
+ }
+ iState = iNewState;
+ m_pOwner->Repaint(&rtItem);
+ } else if ((2 == iItem) && (m_pOwner->m_iThumbButtonState == FWL_PARTSTATE_SCB_Pressed)) {
+ FX_FLOAT fPos = m_pOwner->GetTrackPointPos(fx, fy);
+ m_pOwner->m_fTrackPos = fPos;
+ m_pOwner->OnScroll(FWL_SCBCODE_TrackPos, fPos);
+ }
+}
+void CFWL_ScrollBarImpDelegate::DoMouseLeave(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState)
+{
+ if (iState == FWL_PARTSTATE_SCB_Normal) {
+ return;
+ }
+ iState = FWL_PARTSTATE_SCB_Normal;
+ m_pOwner->Repaint(&rtItem);
+}
+void CFWL_ScrollBarImpDelegate::DoMouseHover(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState)
+{
+ if (iState == FWL_PARTSTATE_SCB_Hovered) {
+ return;
+ }
+ iState = FWL_PARTSTATE_SCB_Hovered;
+ m_pOwner->Repaint(&rtItem);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_spinbuttonimp.cpp b/xfa/src/fwl/src/basewidget/fwl_spinbuttonimp.cpp
new file mode 100644
index 0000000000..f5f56955fa
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_spinbuttonimp.cpp
@@ -0,0 +1,450 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "include/fwl_spinbuttonimp.h"
+#define FWL_SPN_MinWidth 18
+#define FWL_SPN_MinHeight 32
+#define FWL_SPIN_Elapse 200
+IFWL_SpinButton* IFWL_SpinButton::Create()
+{
+ return new IFWL_SpinButton;
+}
+IFWL_SpinButton::IFWL_SpinButton()
+{
+ m_pData = NULL;
+}
+IFWL_SpinButton::~IFWL_SpinButton()
+{
+ if (m_pData) {
+ delete (CFWL_SpinButtonImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_SpinButton::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_SpinButtonImp;
+ ((CFWL_SpinButtonImp*)m_pData)->SetInterface(this);
+ return ((CFWL_SpinButtonImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_SpinButton::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_SpinButtonImp(properties);
+ ((CFWL_SpinButtonImp*)m_pData)->SetInterface(this);
+ return ((CFWL_SpinButtonImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_SpinButton::EnableButton(FX_BOOL bEnable, FX_BOOL bUp)
+{
+ return ((CFWL_SpinButtonImp*)m_pData)->EnableButton(bEnable, bUp);
+}
+FX_BOOL IFWL_SpinButton::IsButtonEnable(FX_BOOL bUp)
+{
+ return ((CFWL_SpinButtonImp*)m_pData)->IsButtonEnable(bUp);
+}
+CFWL_SpinButtonImp::CFWL_SpinButtonImp(IFWL_Widget* pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_dwUpState(FWL_PARTSTATE_SPB_Normal)
+ , m_dwDnState(FWL_PARTSTATE_SPB_Normal)
+ , m_bLButtonDwn(FALSE)
+ , m_iButtonIndex(0)
+ , m_hTimer(NULL)
+{
+ m_rtClient.Reset();
+ m_rtUpButton.Reset();
+ m_rtDnButton.Reset();
+ m_pProperties->m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert;
+}
+CFWL_SpinButtonImp::CFWL_SpinButtonImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_dwUpState(FWL_PARTSTATE_SPB_Normal)
+ , m_dwDnState(FWL_PARTSTATE_SPB_Normal)
+ , m_bLButtonDwn(FALSE)
+ , m_iButtonIndex(0)
+ , m_hTimer(NULL)
+{
+ m_rtClient.Reset();
+ m_rtUpButton.Reset();
+ m_rtDnButton.Reset();
+ m_pProperties->m_dwStyleExes |= FWL_STYLEEXE_SPB_Vert;
+}
+CFWL_SpinButtonImp::~CFWL_SpinButtonImp()
+{
+}
+FWL_ERR CFWL_SpinButtonImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_SpinButton;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_SpinButtonImp::GetClassID() const
+{
+ return FWL_CLASSHASH_SpinButton;
+}
+FWL_ERR CFWL_SpinButtonImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_SpinButtonImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SpinButtonImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_SpinButtonImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_SpinButtonImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize)
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, FWL_SPN_MinWidth, FWL_SPN_MinHeight);
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SpinButtonImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ GetClientRect(m_rtClient);
+ if (m_pProperties->m_dwStyleExes & FWL_STYLEEXE_SPB_Vert) {
+ m_rtUpButton.Set(m_rtClient.top, m_rtClient.left, m_rtClient.width, m_rtClient.height / 2);
+ m_rtDnButton.Set(m_rtClient.left, m_rtClient.top + m_rtClient.height / 2, m_rtClient.width, m_rtClient.height / 2);
+ } else {
+ m_rtUpButton.Set(m_rtClient.left, m_rtClient.top, m_rtClient.width / 2, m_rtClient.height);
+ m_rtDnButton.Set(m_rtClient.left + m_rtClient.width / 2, m_rtClient.top, m_rtClient.width / 2, m_rtClient.height);
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_SpinButtonImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_rtClient.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ if (HasBorder() && (m_rtClient.Contains(fx, fy))) {
+ return FWL_WGTHITTEST_Border;
+ }
+ if (HasEdge()) {
+ CFX_RectF rtEdge;
+ GetEdgeRect(rtEdge);
+ if (rtEdge.Contains(fx, fy)) {
+ return FWL_PART_SPB_Edge;
+ }
+ }
+ if (m_rtUpButton.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_SPB_UpButton;
+ }
+ if (m_rtDnButton.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_SPB_DownButton;
+ }
+ return FWL_WGTHITTEST_Unknown;
+}
+FWL_ERR CFWL_SpinButtonImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ CFX_RectF rtClip(m_rtClient);
+ if (pMatrix != NULL) {
+ pMatrix->TransformRect(rtClip);
+ }
+ IFWL_ThemeProvider *pTheme = GetAvailableTheme();
+ if (HasBorder()) {
+ DrawBorder(pGraphics, FWL_PART_SPB_Border, pTheme, pMatrix);
+ }
+ if (HasEdge()) {
+ DrawEdge(pGraphics, FWL_PART_SPB_Edge, pTheme, pMatrix);
+ }
+ DrawUpButton(pGraphics, pTheme, pMatrix);
+ DrawDownButton(pGraphics, pTheme, pMatrix);
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_SpinButtonImp::Run(FWL_HTIMER hTimer)
+{
+ if (m_hTimer) {
+ CFWL_EvtSpbClick wmPosChanged;
+ wmPosChanged.m_pSrcTarget = m_pInterface;
+ wmPosChanged.m_bUp = m_iButtonIndex == 0;
+ DispatchEvent(&wmPosChanged);
+ }
+ return 1;
+}
+FWL_ERR CFWL_SpinButtonImp::EnableButton(FX_BOOL bEnable, FX_BOOL bUp)
+{
+ if (bUp) {
+ if (bEnable) {
+ m_dwUpState = FWL_PARTSTATE_SPB_Normal;
+ } else {
+ m_dwUpState = FWL_PARTSTATE_SPB_Disabled;
+ }
+ } else {
+ if (bEnable) {
+ m_dwDnState = FWL_PARTSTATE_SPB_Normal;
+ } else {
+ m_dwDnState = FWL_PARTSTATE_SPB_Disabled;
+ }
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_SpinButtonImp::IsButtonEnable(FX_BOOL bUp)
+{
+ if (bUp) {
+ return (m_dwUpState != FWL_PARTSTATE_SPB_Disabled);
+ }
+ return (m_dwDnState != FWL_PARTSTATE_SPB_Disabled);
+}
+void CFWL_SpinButtonImp::DrawUpButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_SPB_UpButton;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_dwUpState + 1;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ params.m_rtPart = m_rtUpButton;
+ pTheme->DrawBackground(&params);
+}
+void CFWL_SpinButtonImp::DrawDownButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground params;
+ params.m_pWidget = m_pInterface;
+ params.m_iPart = FWL_PART_SPB_DownButton;
+ params.m_pGraphics = pGraphics;
+ params.m_dwStates = m_dwDnState + 1;
+ if (pMatrix) {
+ params.m_matrix.Concat(*pMatrix);
+ }
+ params.m_rtPart = m_rtDnButton;
+ pTheme->DrawBackground(&params);
+}
+CFWL_SpinButtonImpDelegate::CFWL_SpinButtonImpDelegate(CFWL_SpinButtonImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_SpinButtonImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_INT32 iRet = 1;
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_SetFocus:
+ case FWL_MSGHASH_KillFocus: {
+ OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ FX_DWORD dwCmd = pMsg->m_dwCmd;
+ switch (dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave(pMsg);
+ break;
+ }
+ default: {
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ CFWL_MsgKey *pKey = (CFWL_MsgKey*)pMessage;
+ if (pKey->m_dwCmd == FWL_MSGKEYCMD_KeyDown) {
+ OnKeyDown((CFWL_MsgKey*)pKey);
+ }
+ break;
+ }
+ default: {
+ iRet = 0;
+ break;
+ }
+ }
+ CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+ return iRet;
+}
+FWL_ERR CFWL_SpinButtonImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SpinButtonImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_SpinButtonImpDelegate::OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet )
+{
+ if (bSet) {
+ m_pOwner->m_pProperties->m_dwStates |= (FWL_WGTSTATE_Focused);
+ } else {
+ m_pOwner->m_pProperties->m_dwStates &= ~(FWL_WGTSTATE_Focused);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_SpinButtonImpDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->m_bLButtonDwn = TRUE;
+ m_pOwner->SetGrab(TRUE);
+ m_pOwner->SetFocus(TRUE);
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pProperties->m_pDataProvider);
+ FX_BOOL bUpPress = (m_pOwner->m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy) &&
+ m_pOwner->IsButtonEnable(TRUE));
+ FX_BOOL bDnPress = (m_pOwner->m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy) &&
+ m_pOwner->IsButtonEnable(FALSE));
+ if (!bUpPress && !bDnPress) {
+ return;
+ }
+ if (bUpPress) {
+ m_pOwner->m_iButtonIndex = 0;
+ m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Pressed;
+ }
+ if (bDnPress) {
+ m_pOwner->m_iButtonIndex = 1;
+ m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Pressed;
+ }
+ CFWL_EvtSpbClick wmPosChanged;
+ wmPosChanged.m_pSrcTarget = m_pOwner->m_pInterface;
+ wmPosChanged.m_bUp = bUpPress;
+ m_pOwner->DispatchEvent(&wmPosChanged);
+ m_pOwner->Repaint(bUpPress ? &m_pOwner->m_rtUpButton : &m_pOwner->m_rtDnButton);
+ m_pOwner->m_hTimer = FWL_StartTimer(m_pOwner, FWL_SPIN_Elapse);
+}
+void CFWL_SpinButtonImpDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ if (m_pOwner->m_pProperties->m_dwStates & FWL_PARTSTATE_SPB_Disabled) {
+ return;
+ }
+ m_pOwner->m_bLButtonDwn = FALSE;
+ m_pOwner->SetGrab(FALSE);
+ m_pOwner->SetFocus(FALSE);
+ if (m_pOwner->m_hTimer) {
+ FWL_StopTimer(m_pOwner->m_hTimer);
+ m_pOwner->m_hTimer = NULL;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvalidate;
+ if (m_pOwner->m_dwUpState == FWL_PARTSTATE_SPB_Pressed && m_pOwner->IsButtonEnable(TRUE)) {
+ m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;
+ bRepaint = TRUE;
+ rtInvalidate = m_pOwner->m_rtUpButton;
+ } else if (m_pOwner->m_dwDnState == FWL_PARTSTATE_SPB_Pressed && m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;
+ bRepaint = TRUE;
+ rtInvalidate = m_pOwner->m_rtDnButton;
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+void CFWL_SpinButtonImpDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pProperties->m_pDataProvider);
+ if (m_pOwner->m_bLButtonDwn) {
+ return;
+ }
+ FX_BOOL bRepaint = FALSE;
+ CFX_RectF rtInvlidate;
+ rtInvlidate.Reset();
+ if (m_pOwner->m_rtUpButton.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->IsButtonEnable(TRUE)) {
+ if (m_pOwner->m_dwUpState == FWL_PARTSTATE_SPB_Hovered) {
+ m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Hovered;
+ bRepaint = TRUE;
+ rtInvlidate = m_pOwner->m_rtUpButton;
+ }
+ if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;
+ if (bRepaint) {
+ rtInvlidate.Union(m_pOwner->m_rtDnButton);
+ } else {
+ rtInvlidate = m_pOwner->m_rtDnButton;
+ }
+ bRepaint = TRUE;
+ }
+ }
+ if (!m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->EnableButton(FALSE, FALSE);
+ }
+ } else if (m_pOwner->m_rtDnButton.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ if (m_pOwner->IsButtonEnable(FALSE)) {
+ if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Hovered) {
+ m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Hovered;
+ bRepaint = TRUE;
+ rtInvlidate = m_pOwner->m_rtDnButton;
+ }
+ if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(TRUE)) {
+ m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;
+ if (bRepaint) {
+ rtInvlidate.Union(m_pOwner->m_rtUpButton);
+ } else {
+ rtInvlidate = m_pOwner->m_rtUpButton;
+ }
+ bRepaint = TRUE;
+ }
+ }
+ } else if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal || m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal) {
+ if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal) {
+ m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;
+ bRepaint = TRUE;
+ rtInvlidate = m_pOwner->m_rtUpButton;
+ }
+ if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal) {
+ m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;
+ if (bRepaint) {
+ rtInvlidate.Union(m_pOwner->m_rtDnButton);
+ } else {
+ rtInvlidate = m_pOwner->m_rtDnButton;
+ }
+ bRepaint = TRUE;
+ }
+ }
+ if (bRepaint) {
+ m_pOwner->Repaint(&rtInvlidate);
+ }
+}
+void CFWL_SpinButtonImpDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(pMsg);
+ if (m_pOwner->m_dwUpState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(TRUE)) {
+ m_pOwner->m_dwUpState = FWL_PARTSTATE_SPB_Normal;
+ }
+ if (m_pOwner->m_dwDnState != FWL_PARTSTATE_SPB_Normal && m_pOwner->IsButtonEnable(FALSE)) {
+ m_pOwner->m_dwDnState = FWL_PARTSTATE_SPB_Normal;
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtClient);
+}
+void CFWL_SpinButtonImpDelegate::OnKeyDown(CFWL_MsgKey *pMsg)
+{
+ _FWL_RETURN_IF_FAIL(m_pOwner->m_pProperties->m_pDataProvider);
+ FX_BOOL bUp = pMsg->m_dwKeyCode == FWL_VKEY_Up || pMsg->m_dwKeyCode == FWL_VKEY_Left;
+ FX_BOOL bDown = pMsg->m_dwKeyCode == FWL_VKEY_Down || pMsg->m_dwKeyCode == FWL_VKEY_Right;
+ if (!bUp && !bDown) {
+ return;
+ }
+ FX_BOOL bUpEnable = m_pOwner->IsButtonEnable(TRUE);
+ FX_BOOL bDownEnable = m_pOwner->IsButtonEnable(FALSE);
+ if (!bUpEnable && !bDownEnable) {
+ return;
+ }
+ CFWL_EvtSpbClick wmPosChanged;
+ wmPosChanged.m_pSrcTarget = m_pOwner->m_pInterface;
+ wmPosChanged.m_bUp = bUpEnable;
+ m_pOwner->DispatchEvent(&wmPosChanged);
+ m_pOwner->Repaint(bUpEnable ? &m_pOwner->m_rtUpButton : &m_pOwner->m_rtDnButton);
+}
diff --git a/xfa/src/fwl/src/basewidget/fwl_tooltipctrlimp.cpp b/xfa/src/fwl/src/basewidget/fwl_tooltipctrlimp.cpp
new file mode 100644
index 0000000000..157d2fff73
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fwl_tooltipctrlimp.cpp
@@ -0,0 +1,338 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_panelimp.h"
+#include "../core/include/fwl_formimp.h"
+#include "include/fwl_tooltipctrlimp.h"
+IFWL_ToolTip *IFWL_ToolTip::Create()
+{
+ return new IFWL_ToolTip;
+}
+FWL_ERR IFWL_ToolTip::Initialize(IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ToolTipImp(pOuter);
+ ((CFWL_ToolTipImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ToolTipImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_ToolTip::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter)
+{
+ m_pData = FX_NEW CFWL_ToolTipImp(properties, pOuter);
+ ((CFWL_ToolTipImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ToolTipImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_ToolTip::SetAnchor(const CFX_RectF &rtAnchor)
+{
+ return ((CFWL_ToolTipImp*)m_pData)->SetAnchor( rtAnchor);
+}
+FWL_ERR IFWL_ToolTip::Show()
+{
+ return ((CFWL_ToolTipImp*)m_pData)->Show();
+}
+FWL_ERR IFWL_ToolTip::Hide()
+{
+ return ((CFWL_ToolTipImp*)m_pData)->Hide();
+}
+IFWL_ToolTip::IFWL_ToolTip()
+{
+ m_pData = NULL;
+}
+IFWL_ToolTip::~IFWL_ToolTip()
+{
+ if (m_pData) {
+ delete (CFWL_ToolTipImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+CFWL_ToolTipImp::CFWL_ToolTipImp(IFWL_Widget *pOuter )
+ : CFWL_FormImp(pOuter)
+ , m_bBtnDown(FALSE)
+ , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
+ , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
+ , m_hTimerShow(NULL)
+ , m_hTimerHide(NULL)
+ , m_pTimer(NULL)
+{
+ m_rtClient.Set(0, 0, 0, 0);
+ m_rtCaption.Set(0, 0, 0, 0);
+ m_pTimer = NULL;
+ m_TimerShow.m_pToolTip = this;
+ m_TimerHide.m_pToolTip = this;
+}
+CFWL_ToolTipImp::CFWL_ToolTipImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_FormImp(properties, pOuter)
+ , m_bBtnDown(FALSE)
+ , m_dwTTOStyles(FDE_TTOSTYLE_SingleLine)
+ , m_iTTOAlign(FDE_TTOALIGNMENT_Center)
+ , m_hTimerShow(NULL)
+ , m_hTimerHide(NULL)
+ , m_pTimer(NULL)
+{
+ m_rtClient.Set(0, 0, 0, 0);
+ m_rtCaption.Set(0, 0, 0, 0);
+ m_rtAnchor.Set(0, 0, 0, 0);
+ m_TimerShow.m_pToolTip = this;
+ m_TimerHide.m_pToolTip = this;
+}
+CFWL_ToolTipImp::~CFWL_ToolTipImp()
+{
+ if (m_pTimer) {
+ delete m_pTimer;
+ m_pTimer = NULL;
+ }
+}
+FWL_ERR CFWL_ToolTipImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_ToolTip;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ToolTipImp::GetClassID() const
+{
+ return FWL_CLASSHASH_ToolTip;
+}
+FWL_ERR CFWL_ToolTipImp::Initialize()
+{
+ m_pProperties->m_dwStyles |= FWL_WGTSTYLE_Popup;
+ m_pProperties->m_dwStyles &= ~FWL_WGTSTYLE_Child;
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_ToolTipImpDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ToolTipImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_ToolTipImpDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_ToolTipImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Set(0, 0, 0, 0);
+ if (m_pProperties->m_pThemeProvider == NULL) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ CFX_WideString wsCaption;
+ IFWL_ToolTipDP *pData = (IFWL_ToolTipDP*)m_pProperties->m_pDataProvider;
+ if (pData) {
+ pData->GetCaption(m_pInterface, wsCaption);
+ }
+ FX_INT32 iLen = wsCaption.GetLength();
+ if (iLen > 0) {
+ CFX_SizeF sz = CalcTextSize(wsCaption, m_pProperties->m_pThemeProvider);
+ rect.Set(0, 0, sz.x, sz.y);
+ rect.width += FWL_WGTCAPACITY_CXBorder * 25;
+ rect.height += FWL_WGTCAPACITY_CYBorder * 8;
+ }
+ CFWL_WidgetImp::GetWidgetRect(rect, TRUE);
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ToolTipImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+ UpdateTextOutStyles();
+ GetClientRect(m_rtClient);
+ m_rtCaption = m_rtClient;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ToolTipImp::GetClientRect(CFX_RectF &rect)
+{
+ FX_FLOAT x = 0;
+ FX_FLOAT y = 0;
+ FX_FLOAT t = 0;
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (pTheme) {
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pInterface;
+ FX_FLOAT * value = NULL;
+ value = (FX_FLOAT *) pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CXBorder);
+ x = *value;
+ value = (FX_FLOAT *) pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CYBorder);
+ y = *value;
+ }
+ rect = m_pProperties->m_rtWidget;
+ rect.Offset(-rect.left, -rect.top);
+ rect.Deflate(x, t, x, y);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ToolTipImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ IFWL_ToolTipTarget * toolTipTarget = CFWL_ToolTipContainer::getInstance()->GetCurrentToolTipTarget();
+ if (toolTipTarget && !toolTipTarget->UseDefaultTheme()) {
+ return toolTipTarget->DrawToolTip(pGraphics, pMatrix, m_pInterface);
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ DrawBkground(pGraphics, pTheme, pMatrix);
+ DrawText(pGraphics, pTheme, pMatrix);
+ return FWL_ERR_Succeeded;
+}
+void CFWL_ToolTipImp::DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_TTP_Background;
+ param.m_dwStates = m_pProperties->m_dwStates;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtClient;
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) {
+ param.m_pData = &m_rtCaption;
+ }
+ pTheme->DrawBackground(&param);
+}
+void CFWL_ToolTipImp::DrawText(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix)
+{
+ _FWL_RETURN_IF_FAIL(m_pProperties->m_pDataProvider);
+ CFX_WideString wsCaption;
+ m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsCaption);
+ if (wsCaption.IsEmpty()) {
+ return;
+ }
+ CFWL_ThemeText param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_TTP_Caption;
+ param.m_dwStates = m_pProperties->m_dwStates;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ param.m_rtPart = m_rtCaption;
+ param.m_wsText = wsCaption;
+ param.m_dwTTOStyles = m_dwTTOStyles;
+ param.m_iTTOAlign = m_iTTOAlign;
+ pTheme->DrawText(&param);
+}
+void CFWL_ToolTipImp::UpdateTextOutStyles()
+{
+ m_iTTOAlign = FDE_TTOALIGNMENT_Center;
+ m_dwTTOStyles = FDE_TTOSTYLE_SingleLine;
+ if (m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_RTLReading) {
+ m_dwTTOStyles |= FDE_TTOSTYLE_RTL;
+ }
+ if ( m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_Multiline) {
+ m_dwTTOStyles &= ~FDE_TTOSTYLE_SingleLine;
+ }
+}
+FWL_ERR CFWL_ToolTipImp::SetAnchor(const CFX_RectF &rtAnchor)
+{
+ m_rtAnchor = rtAnchor;
+ return TRUE;
+}
+FWL_ERR CFWL_ToolTipImp::Show()
+{
+ IFWL_ToolTipDP *pData = (IFWL_ToolTipDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 nInitDelay = pData->GetInitialDelay(m_pInterface);
+ if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible)) {
+ m_hTimerShow = FWL_StartTimer( &m_TimerShow, nInitDelay, FALSE);
+ }
+ return TRUE;
+}
+FWL_ERR CFWL_ToolTipImp::Hide()
+{
+ SetStates( FWL_WGTSTATE_Invisible, TRUE);
+ if ( m_hTimerHide) {
+ FWL_StopTimer(m_hTimerHide);
+ m_hTimerHide = NULL;
+ }
+ if ( m_hTimerShow) {
+ FWL_StopTimer(m_hTimerShow);
+ m_hTimerShow = NULL;
+ }
+ return TRUE;
+}
+FWL_ERR CFWL_ToolTipImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
+{
+ if ( (dwStates & FWL_WGTSTATE_Invisible) && !bSet) {
+ IFWL_ToolTipDP *pData = (IFWL_ToolTipDP*)m_pProperties->m_pDataProvider;
+ FX_INT32 nAutoPopDelay = pData->GetAutoPopDelay(m_pInterface);
+ m_hTimerHide = FWL_StartTimer( &m_TimerHide, nAutoPopDelay, FALSE);
+ }
+ return CFWL_WidgetImp::SetStates(dwStates, bSet);
+}
+void CFWL_ToolTipImp::RefreshToolTipPos()
+{
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_TTP_NoAnchor) == 0) {
+ CFX_RectF rtPopup;
+ CFX_RectF rtWidget(m_pProperties->m_rtWidget);
+ CFX_RectF rtAnchor(m_rtAnchor);
+ rtPopup.Set( 0, 0, 0, 0);
+ FX_FLOAT fx = rtAnchor.Center().x + 20;
+ FX_FLOAT fy = rtAnchor.Center().y + 20;
+ rtPopup.Set( fx, fy, rtWidget.Width(), rtWidget.Height());
+ FX_FLOAT fScreenWidth = 0;
+ FX_FLOAT fScreenHeight = 0;
+ GetScreenSize(fScreenWidth, fScreenHeight);
+ if (rtPopup.bottom() > fScreenHeight) {
+ rtPopup.Offset( 0, fScreenHeight - rtPopup.bottom());
+ }
+ if ( rtPopup.right() > fScreenWidth) {
+ rtPopup.Offset( fScreenWidth - rtPopup.right(), 0);
+ }
+ if ( rtPopup.left < 0) {
+ rtPopup.Offset(0 - rtPopup.left, 0);
+ }
+ if ( rtPopup.top < 0) {
+ rtPopup.Offset( 0, 0 - rtPopup.top);
+ }
+ SetWidgetRect(rtPopup);
+ Update();
+ }
+}
+CFWL_ToolTipImp::CFWL_ToolTipTimer::CFWL_ToolTipTimer(CFWL_ToolTipImp * pToolTip)
+ : m_pToolTip(pToolTip)
+{
+}
+FX_INT32 CFWL_ToolTipImp::CFWL_ToolTipTimer::Run(FWL_HTIMER hTimer)
+{
+ if (m_pToolTip->m_hTimerShow == hTimer && m_pToolTip->m_hTimerShow) {
+ if (m_pToolTip->GetStates() & FWL_WGTSTATE_Invisible) {
+ m_pToolTip->SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ m_pToolTip->RefreshToolTipPos();
+ FWL_StopTimer(m_pToolTip->m_hTimerShow);
+ m_pToolTip->m_hTimerShow = NULL;
+ return TRUE;
+ }
+ }
+ if (m_pToolTip->m_hTimerHide == hTimer && m_pToolTip->m_hTimerHide) {
+ m_pToolTip->SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ FWL_StopTimer(m_pToolTip->m_hTimerHide);
+ m_pToolTip->m_hTimerHide = NULL;
+ return TRUE;
+ }
+ return TRUE;
+}
+CFWL_ToolTipImpDelegate::CFWL_ToolTipImpDelegate(CFWL_ToolTipImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_ToolTipImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return CFWL_WidgetImpDelegate::OnProcessMessage(pMessage);
+}
+FWL_ERR CFWL_ToolTipImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ToolTipImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/src/fwl/src/basewidget/fxmath_barcodeimp.cpp b/xfa/src/fwl/src/basewidget/fxmath_barcodeimp.cpp
new file mode 100644
index 0000000000..c56932b4fa
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/fxmath_barcodeimp.cpp
@@ -0,0 +1,400 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fxmath_barcodeimp.h"
+static CBC_CodeBase* FX_Barcode_CreateBarCodeEngineObject(BC_TYPE type)
+{
+ switch(type) {
+ case BC_CODE39:
+ return FX_NEW CBC_Code39();
+ case BC_CODABAR:
+ return FX_NEW CBC_Codabar();
+ case BC_CODE128:
+ return FX_NEW CBC_Code128(BC_CODE128_B);
+ case BC_CODE128_B:
+ return FX_NEW CBC_Code128(BC_CODE128_B);
+ case BC_CODE128_C:
+ return FX_NEW CBC_Code128(BC_CODE128_C);
+ case BC_EAN8:
+ return FX_NEW CBC_EAN8();
+ case BC_UPCA:
+ return FX_NEW CBC_UPCA();
+ case BC_EAN13:
+ return FX_NEW CBC_EAN13();
+ case BC_QR_CODE:
+ return FX_NEW CBC_QRCode();
+ case BC_PDF417:
+ return FX_NEW CBC_PDF417I();
+ case BC_DATAMATRIX:
+ return FX_NEW CBC_DataMatrix();
+ case BC_UNKNOWN:
+ default:
+ return NULL;
+ }
+}
+CFX_Barcode::CFX_Barcode()
+{
+}
+CFX_Barcode::~CFX_Barcode()
+{
+ if(m_pBCEngine) {
+ delete m_pBCEngine;
+ m_pBCEngine = NULL;
+ }
+}
+FX_BOOL CFX_Barcode::Crreate(BC_TYPE type)
+{
+ m_pBCEngine = FX_Barcode_CreateBarCodeEngineObject(type);
+ return m_pBCEngine != NULL;
+}
+void CFX_Barcode::Release()
+{
+ delete this;
+}
+BC_TYPE CFX_Barcode::GetType()
+{
+ return m_pBCEngine ? m_pBCEngine->GetType() : BC_UNKNOWN;
+}
+FX_BOOL CFX_Barcode::SetCharEncoding(BC_CHAR_ENCODING encoding)
+{
+ return m_pBCEngine ? m_pBCEngine->SetCharEncoding(encoding) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetModuleHeight(FX_INT32 moduleHeight)
+{
+ return m_pBCEngine ? m_pBCEngine->SetModuleHeight(moduleHeight) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetModuleWidth(FX_INT32 moduleWidth)
+{
+ return m_pBCEngine ? m_pBCEngine->SetModuleWidth(moduleWidth) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetHeight(FX_INT32 height)
+{
+ return m_pBCEngine ? m_pBCEngine->SetHeight(height) : FALSE;
+}
+FX_BOOL CFX_Barcode::SetWidth(FX_INT32 width)
+{
+ return m_pBCEngine ? m_pBCEngine->SetWidth(width) : FALSE;
+}
+FX_BOOL CFX_Barcode::CheckContentValidity(FX_WSTR contents)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? ((CBC_OneCode*)m_pBCEngine)->CheckContentValidity(contents)
+ : TRUE;
+ default:
+ return TRUE;
+ }
+}
+FX_BOOL CFX_Barcode::SetPrintChecksum(FX_BOOL checksum)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (((CBC_OneCode*)m_pBCEngine)->SetPrintChecksum(checksum), TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetDataLength(FX_INT32 length)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (((CBC_OneCode*)m_pBCEngine)->SetDataLength(length), TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetCalChecksum(FX_INT32 state)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (((CBC_OneCode*)m_pBCEngine)->SetCalChecksum(state), TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFont(CFX_Font* pFont)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? ((CBC_OneCode*)m_pBCEngine)->SetFont(pFont)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFontSize(FX_FLOAT size)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (((CBC_OneCode*)m_pBCEngine)->SetFontSize(size), TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFontStyle(FX_INT32 style)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (((CBC_OneCode*)m_pBCEngine)->SetFontStyle(style), TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetFontColor(FX_ARGB color)
+{
+ switch(GetType()) {
+ case BC_CODE39:
+ case BC_CODABAR:
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ case BC_EAN8:
+ case BC_EAN13:
+ case BC_UPCA:
+ return m_pBCEngine ? (((CBC_OneCode*)m_pBCEngine)->SetFontColor(color), TRUE)
+ : FALSE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFX_Barcode::SetTextLocation(BC_TEXT_LOC location)
+{
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(BC_TEXT_LOC);
+ memptrtype memptr = NULL;
+ switch(GetType()) {
+ case BC_CODE39:
+ memptr = (memptrtype)&CBC_Code39::SetTextLocation;
+ break;
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetTextLocation;
+ break;
+ case BC_CODE128:
+ case BC_CODE128_B:
+ case BC_CODE128_C:
+ memptr = (memptrtype)&CBC_Code128::SetTextLocation;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine->*memptr)(location)
+ : FALSE;
+}
+FX_BOOL CFX_Barcode::SetWideNarrowRatio(FX_INT32 ratio)
+{
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(FX_INT32);
+ memptrtype memptr = NULL;
+ switch(GetType()) {
+ case BC_CODE39:
+ memptr = (memptrtype)&CBC_Code39::SetWideNarrowRatio;
+ break;
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetWideNarrowRatio;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine->*memptr)(ratio)
+ : FALSE;
+}
+FX_BOOL CFX_Barcode::SetStartChar(FX_CHAR start)
+{
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(FX_CHAR);
+ memptrtype memptr = NULL;
+ switch(GetType()) {
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetStartChar;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine->*memptr)(start)
+ : FALSE;
+}
+FX_BOOL CFX_Barcode::SetEndChar(FX_CHAR end)
+{
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(FX_CHAR);
+ memptrtype memptr = NULL;
+ switch(GetType()) {
+ case BC_CODABAR:
+ memptr = (memptrtype)&CBC_Codabar::SetEndChar;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine->*memptr)(end)
+ : FALSE;
+}
+FX_BOOL CFX_Barcode::SetVersion(FX_INT32 version)
+{
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(FX_INT32);
+ memptrtype memptr = NULL;
+ switch(GetType()) {
+ case BC_QR_CODE:
+ memptr = (memptrtype)&CBC_QRCode::SetVersion;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine->*memptr)(version)
+ : FALSE;
+}
+FX_BOOL CFX_Barcode::SetErrorCorrectionLevel(FX_INT32 level)
+{
+ typedef FX_BOOL (CBC_CodeBase::*memptrtype)(FX_INT32);
+ memptrtype memptr = NULL;
+ switch(GetType()) {
+ case BC_QR_CODE:
+ memptr = (memptrtype)&CBC_QRCode::SetErrorCorrectionLevel;
+ break;
+ case BC_PDF417:
+ memptr = (memptrtype)&CBC_PDF417I::SetErrorCorrectionLevel;
+ break;
+ default:
+ return FALSE;
+ }
+ return m_pBCEngine && memptr ? (m_pBCEngine->*memptr)(level)
+ : FALSE;
+}
+FX_BOOL CFX_Barcode::SetTruncated(FX_BOOL truncated)
+{
+ typedef void (CBC_CodeBase::*memptrtype)(FX_BOOL);
+ memptrtype memptr = NULL;
+ switch(GetType()) {
+ case BC_PDF417:
+ memptr = (memptrtype)&CBC_PDF417I::SetTruncated;
+ break;
+ default:
+ break;
+ }
+ return m_pBCEngine && memptr ? ((m_pBCEngine->*memptr)(truncated), TRUE)
+ : FALSE;
+}
+#ifndef BCExceptionNO
+#define BCExceptionNO 0
+#endif
+#ifndef BCExceptionFormatException
+#define BCExceptionFormatException 8
+#endif
+#ifndef BCExceptionUnSupportedBarcode
+#define BCExceptionUnSupportedBarcode 18
+#endif
+FX_BOOL CFX_Barcode::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if(!m_pBCEngine) {
+ return FALSE;
+ }
+ return m_pBCEngine->Encode(contents, isDevice, e);
+}
+FX_BOOL CFX_Barcode::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ if (!m_pBCEngine) {
+ return FALSE;
+ }
+ return m_pBCEngine->RenderDevice(device, matirx, e);
+}
+FX_BOOL CFX_Barcode::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ if (!m_pBCEngine) {
+ return FALSE;
+ }
+ return m_pBCEngine->RenderBitmap(pOutBitmap, e);
+}
+#define BC_TYPE_MIN BC_CODE39
+#define BC_TYPE_MAX BC_DATAMATRIX
+CFX_WideString CFX_Barcode::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 height, FX_INT32 &errorCode)
+{
+ for(BC_TYPE t = BC_TYPE_MIN; t <= BC_TYPE_MAX; t = (BC_TYPE)((FX_INT32)t + 1)) {
+ CBC_CodeBase* pTmpEngine = FX_Barcode_CreateBarCodeEngineObject(t);
+ if(!pTmpEngine) {
+ continue;
+ }
+ CFX_WideString ret = pTmpEngine->Decode(buf, width, height, errorCode);
+ if(errorCode == BCExceptionNO) {
+ return ret;
+ }
+ }
+ errorCode = BCExceptionUnSupportedBarcode;
+ return CFX_WideString();
+}
+CFX_WideString CFX_Barcode::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &errorCode)
+{
+ for(BC_TYPE t = BC_TYPE_MIN; t <= BC_TYPE_MAX; t = (BC_TYPE)((FX_INT32)t + 1)) {
+ CBC_CodeBase* pTmpEngine = FX_Barcode_CreateBarCodeEngineObject(t);
+ if(!pTmpEngine) {
+ continue;
+ }
+ CFX_WideString ret = pTmpEngine->Decode(pBitmap, errorCode);
+ if(errorCode == BCExceptionNO) {
+ return ret;
+ }
+ }
+ errorCode = BCExceptionUnSupportedBarcode;
+ return CFX_WideString();
+}
+IFX_Barcode* FX_Barcode_Create(BC_TYPE type)
+{
+ CFX_Barcode* pBarcode = FX_NEW CFX_Barcode;
+ if (pBarcode->Crreate(type)) {
+ return pBarcode;
+ }
+ pBarcode->Release();
+ return NULL;
+}
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_barcodeimp.h b/xfa/src/fwl/src/basewidget/include/fwl_barcodeimp.h
new file mode 100644
index 0000000000..7a4681b6f8
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_barcodeimp.h
@@ -0,0 +1,51 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_BARCODE_IMP_H
+#define _FWL_BARCODE_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class CFWL_EditImp;
+class CFWL_EditImpDelegate;
+class IFWL_Widget;
+class CFWL_BarcodeEdit;
+class CFWL_BarcodeEditDelegate;
+class CFWL_BarcodeImp;
+class CFWL_BarcodeImpDelegate;
+#define XFA_BCS_NeedUpdate 0x0001
+#define XFA_BCS_EncodeSuccess 0x0002
+class CFWL_BarcodeImp : public CFWL_EditImp
+{
+public:
+ CFWL_BarcodeImp(IFWL_Widget *pOuter = NULL);
+ CFWL_BarcodeImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_BarcodeImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FWL_ERR SetText(const CFX_WideString &wsText);
+ virtual void SetType(BC_TYPE type);
+ FX_BOOL IsProtectedType();
+protected:
+ void GenerateBarcodeImageCache();
+ void CreateBarcodeEngine();
+ void ReleaseBarcodeEngine();
+ IFX_Barcode *m_pBarcodeEngine;
+ FX_DWORD m_dwStatus;
+ BC_TYPE m_type;
+ friend class CFWL_BarcodeImpDelegate;
+};
+class CFWL_BarcodeImpDelegate : public CFWL_EditImpDelegate
+{
+public:
+ CFWL_BarcodeImpDelegate(CFWL_BarcodeImp *pOwner);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_caretimp.h b/xfa/src/fwl/src/basewidget/include/fwl_caretimp.h
new file mode 100644
index 0000000000..fcae080130
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_caretimp.h
@@ -0,0 +1,63 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CARET_IMP_H
+#define _FWL_CARET_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class CFWL_CaretImp;
+class CFWL_CaretImpDelegate;
+class CFWL_CaretImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_CaretImp(IFWL_Widget *pOuter = NULL);
+ CFWL_CaretImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_CaretImp();
+
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+
+ virtual FWL_ERR ShowCaret(FX_BOOL bFlag = TRUE);
+ virtual FWL_ERR GetFrequency(FX_DWORD &elapse);
+ virtual FWL_ERR SetFrequency(FX_DWORD elapse);
+ virtual FWL_ERR SetColor(CFX_Color crFill);
+protected:
+ FX_BOOL DrawCaretBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ class CFWL_CaretTimer : public CFX_Object
+ {
+ public:
+ CFWL_CaretTimer(CFWL_CaretImp *m_pCaret);
+ virtual FX_INT32 Run(FWL_HTIMER hTimer);
+ CFWL_CaretImp *m_pCaret;
+
+ };
+ CFWL_CaretTimer *m_pTimer;
+ FWL_HTIMER m_hTimer;
+ FX_DWORD m_dwElapse;
+ CFX_Color m_crFill;
+ FX_BOOL m_bSetColor;
+ friend class CFWL_CaretImpDelegate;
+ friend class CFWL_CaretTimer;
+
+};
+class CFWL_CaretImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_CaretImpDelegate(CFWL_CaretImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+
+protected:
+ CFWL_CaretImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_checkboximp.h b/xfa/src/fwl/src/basewidget/include/fwl_checkboximp.h
new file mode 100644
index 0000000000..0e538f32d6
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_checkboximp.h
@@ -0,0 +1,60 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CHECKBOX_IMP_H
+#define _FWL_CHECKBOX_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class CFWL_CheckBoxImp;
+class CFWL_CheckBoxImpDelegate;
+class CFWL_CheckBoxImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_CheckBoxImp(IFWL_Widget *pOuter = NULL);
+ CFWL_CheckBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ ~CFWL_CheckBoxImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_INT32 GetCheckState();
+ virtual FWL_ERR SetCheckState(FX_INT32 iCheck);
+protected:
+ void Layout();
+ FX_DWORD GetPartStates();
+ void UpdateTextOutStyles();
+ void NextStates();
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtBox;
+ CFX_RectF m_rtCaption;
+ CFX_RectF m_rtFocus;
+ FX_DWORD m_dwTTOStyles;
+ FX_INT32 m_iTTOAlign;
+ FX_BOOL m_bBtnDown;
+ friend class CFWL_CheckBoxImpDelegate;
+};
+class CFWL_CheckBoxImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_CheckBoxImpDelegate(CFWL_CheckBoxImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnActivate(CFWL_Message *pMsg);
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+ void OnKeyDown(CFWL_MsgKey *pMsg);
+ CFWL_CheckBoxImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h b/xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h
new file mode 100644
index 0000000000..250ef35e79
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_comboboximp.h
@@ -0,0 +1,227 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_COMBOBOX_IMP_H
+#define _FWL_COMBOBOX_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class CFWL_EditImp;
+class CFWL_EditImpDelegate;
+class CFWL_ListBoxImp;
+class CFWL_ListBoxImpDelegate;
+class CFWL_FormProxyImp;
+class IFWL_Widget;
+class CFWL_ComboEdit;
+class CFWL_ComboEditDelegate;
+class CFWL_ComboList;
+class CFWL_ComboListDelegate;
+class CFWL_ComboBoxImp;
+class CFWL_ComboBoxImpDelegate;
+class CFWL_ComboProxyImpDelegate;
+class CFWL_ComboEdit : public CFWL_EditImp
+{
+public:
+ CFWL_ComboEdit(IFWL_Widget *pOuter);
+ CFWL_ComboEdit(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+
+ void ClearSelected();
+ void SetSelected();
+ void EndCaret();
+ void FlagFocus(FX_BOOL bSet);
+protected:
+ void SetComboBoxFocus(FX_BOOL bSet);
+ CFWL_ComboBoxImp *m_pOuter;
+ friend class CFWL_ComboEditDelegate;
+};
+class CFWL_ComboEditDelegate : public CFWL_EditImpDelegate
+{
+public:
+ CFWL_ComboEditDelegate(CFWL_ComboEdit *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+protected:
+ CFWL_ComboEdit *m_pOwner;
+};
+class CFWL_ComboList : public CFWL_ListBoxImp
+{
+public:
+ CFWL_ComboList(IFWL_Widget *pOuter);
+ CFWL_ComboList(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ FX_INT32 MatchItem(const CFX_WideString &wsMatch);
+ void ChangeSelected(FX_INT32 iSel);
+ FX_INT32 CountItems();
+ void GetItemRect(FX_INT32 nIndex, CFX_RectF &rtItem);
+ void ClientToOuter(FX_FLOAT &fx, FX_FLOAT &fy);
+ void SetFocus(FX_BOOL bSet);
+ FX_BOOL m_bNotifyOwner;
+ friend class CFWL_ComboListDelegate;
+ friend class CFWL_ComboBoxImp;
+};
+class CFWL_ComboListDelegate : public CFWL_ListBoxImpDelegate
+{
+public:
+ CFWL_ComboListDelegate(CFWL_ComboList *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+protected:
+ void OnDropListFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ FX_INT32 OnDropListMouseMove(CFWL_MsgMouse *pMsg);
+ FX_INT32 OnDropListLButtonDown(CFWL_MsgMouse *pMsg);
+ FX_INT32 OnDropListLButtonUp(CFWL_MsgMouse *pMsg);
+ FX_INT32 OnDropListKey(CFWL_MsgKey *pKey);
+ void OnDropListKeyDown(CFWL_MsgKey *pKey);
+ CFWL_ComboList *m_pOwner;
+};
+class CFWL_ComboBoxImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_ComboBoxImp(IFWL_Widget *pOuter = NULL);
+ CFWL_ComboBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_ComboBoxImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+ virtual FWL_ERR SetStates(FX_DWORD dwStates, FX_BOOL bSet = TRUE);
+ virtual FWL_ERR Update();
+ virtual FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FWL_ERR SetThemeProvider(IFWL_ThemeProvider *pThemeProvider);
+ virtual FX_INT32 GetCurSel();
+ virtual FWL_ERR SetCurSel(FX_INT32 iSel);
+ virtual FWL_ERR SetEditText(const CFX_WideString &wsText);
+ virtual FX_INT32 GetEditTextLength() const;
+ virtual FWL_ERR GetEditText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const;
+ virtual FWL_ERR SetEditSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ virtual FX_INT32 GetEditSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ virtual FX_INT32 GetEditLimit();
+ virtual FWL_ERR SetEditLimit(FX_INT32 nLimit);
+ virtual FWL_ERR EditDoClipboard(FX_INT32 iCmd);
+ virtual FX_BOOL EditRedo(FX_BSTR bsRecord);
+ virtual FX_BOOL EditUndo(FX_BSTR bsRecord);
+ virtual IFWL_ListBox* GetListBoxt();
+ virtual FX_BOOL AfterFocusShowDropList();
+ virtual FX_ERR OpenDropDownList(FX_BOOL bActivate);
+ virtual FX_BOOL EditCanUndo();
+ virtual FX_BOOL EditCanRedo();
+ virtual FX_BOOL EditUndo();
+ virtual FX_BOOL EditRedo();
+ virtual FX_BOOL EditCanCopy();
+ virtual FX_BOOL EditCanCut();
+ virtual FX_BOOL EditCanSelectAll();
+ virtual FX_BOOL EditCopy(CFX_WideString &wsCopy);
+ virtual FX_BOOL EditCut(CFX_WideString &wsCut);
+ virtual FX_BOOL EditPaste(const CFX_WideString &wsPaste);
+ virtual FX_BOOL EditSelectAll();
+ virtual FX_BOOL EditDelete();
+ virtual FX_BOOL EditDeSelect();
+ virtual FWL_ERR GetBBox(CFX_RectF &rect);
+ virtual FWL_ERR EditModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+protected:
+ void DrawStretchHandler(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix);
+ FX_FLOAT GetListHeight();
+ void ShowDropList(FX_BOOL bActivate);
+ FX_BOOL IsDropListShowed();
+ FX_BOOL IsDropDownStyle() const;
+ void MatchEditText();
+ void SynchrEditText(FX_INT32 iListItem);
+ void Layout();
+ void ReSetTheme();
+ void ReSetEditAlignment();
+ void ReSetListItemAlignment();
+ void ProcessSelChanged(FX_BOOL bLButtonUp);
+ void InitProxyForm();
+protected:
+ FWL_ERR DisForm_Initialize();
+ void DisForm_InitComboList();
+ void DisForm_InitComboEdit();
+ void DisForm_ShowDropList(FX_BOOL bActivate);
+ FX_BOOL DisForm_IsDropListShowed();
+ FWL_ERR DisForm_ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+ FWL_ERR DisForm_Update();
+ FX_DWORD DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ FWL_ERR DisForm_DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ FWL_ERR DisForm_GetBBox(CFX_RectF &rect);
+ void DisForm_Layout();
+protected:
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtContent;
+ CFX_RectF m_rtBtn;
+ CFX_RectF m_rtList;
+ CFX_RectF m_rtProxy;
+ CFX_RectF m_rtHandler;
+ IFWL_Edit *m_pEdit;
+ IFWL_ListBox *m_pListBox;
+ IFWL_Form *m_pForm;
+ FX_BOOL m_bLButtonDown;
+ FX_BOOL m_bUpFormHandler;
+ FX_INT32 m_iCurSel;
+ FX_INT32 m_iBtnState;
+ FX_FLOAT m_fComboFormHandler;
+ FX_FLOAT m_fItemHeight;
+ FX_BOOL m_bNeedShowList;
+ CFWL_FormProxyImp *m_pProxy;
+ CFWL_ComboProxyImpDelegate *m_pListProxyDelegate;
+
+ friend class CFWL_ComboList;
+ friend class CFWL_ComboEdit;
+ friend class CFWL_ComboEditDelegate;
+ friend class CFWL_ComboListDelegate;
+ friend class CFWL_ComboBoxImpDelegate;
+ friend class CFWL_ComboProxyImpDelegate;
+};
+class CFWL_ComboBoxImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_ComboBoxImpDelegate(CFWL_ComboBoxImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+
+protected:
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+ void OnKey(CFWL_MsgKey *pMsg);
+ void DoSubCtrlKey(CFWL_MsgKey *pMsg);
+protected:
+ FX_INT32 DisForm_OnProcessMessage(CFWL_Message *pMessage);
+ void DisForm_OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void DisForm_OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void DisForm_OnKey(CFWL_MsgKey *pMsg);
+protected:
+ CFWL_ComboBoxImp *m_pOwner;
+ friend class CFWL_ComboEditDelegate;
+ friend class CFWL_ComboListDelegate;
+};
+class CFWL_ComboProxyImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_ComboProxyImpDelegate(IFWL_Form *pForm, CFWL_ComboBoxImp *pComboBox);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ void Reset()
+ {
+ m_bLButtonUpSelf = FALSE;
+ }
+protected:
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnDeactive(CFWL_MsgDeactivate *pMsg);
+ void OnFocusChanged(CFWL_MsgKillFocus *pMsg, FX_BOOL bSet );
+ FX_BOOL m_bLButtonDown;
+ FX_BOOL m_bLButtonUpSelf;
+ FX_FLOAT m_fStartPos;
+ IFWL_Form *m_pForm;
+ CFWL_ComboBoxImp *m_pComboBox;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_datetimepickerimp.h b/xfa/src/fwl/src/basewidget/include/fwl_datetimepickerimp.h
new file mode 100644
index 0000000000..cc8db6ada1
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_datetimepickerimp.h
@@ -0,0 +1,206 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_DATETIMEPICKER_IMP_H
+#define _FWL_DATETIMEPICKER_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class CFWL_EditImp;
+class CFWL_EditImpDelegate;
+class CFWL_MonthCalendarImp;
+class CFWL_MonthCalendarImpDelegate;
+class CFWL_FormProxyImp;
+class CFWL_DateTimeEdit;
+class CFWL_DateTimeEditDelegate;
+class CFWL_DateTimeCalendar;
+class CFWL_DateTimeCalendarDelegate;
+class CFWL_DateTimePickerImp;
+class CFWL_DateTimePickerImpDelegate;
+class IFWL_DateTimeForm : public IFWL_Form
+{
+public:
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+};
+class IFWL_DateTimeCalender : public IFWL_MonthCalendar
+{
+public:
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+};
+class IFWL_DateTimeEdit : public IFWL_Edit
+{
+public:
+ FWL_ERR Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+};
+class CFWL_DateTimeEdit : public CFWL_EditImp
+{
+public:
+ CFWL_DateTimeEdit(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+protected:
+ friend class CFWL_DateTimeEditDelegate;
+};
+class CFWL_DateTimeEditDelegate : public CFWL_EditImpDelegate
+{
+public:
+ CFWL_DateTimeEditDelegate(CFWL_DateTimeEdit *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+private:
+ FX_INT32 DisForm_OnProcessMessage(CFWL_Message *pMessage);
+
+protected:
+ CFWL_DateTimeEdit *m_pOwner;
+};
+class CFWL_DateTimeCalendar : public CFWL_MonthCalendarImp
+{
+public:
+ CFWL_DateTimeCalendar(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter);
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+protected:
+ friend class CFWL_DateTimeCalendarDelegate;
+};
+class CFWL_DateTimeCalendarDelegate : public CFWL_MonthCalendarImpDelegate
+{
+public:
+ CFWL_DateTimeCalendarDelegate(CFWL_DateTimeCalendar *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ void OnLButtonDownEx(CFWL_MsgMouse *pMsg);
+ void OnLButtonUpEx(CFWL_MsgMouse *pMsg);
+ void OnMouseMoveEx(CFWL_MsgMouse *pMsg);
+private:
+ FX_INT32 DisForm_OnProcessMessage(CFWL_Message *pMessage);
+ void DisForm_OnLButtonUpEx(CFWL_MsgMouse *pMsg);
+protected:
+ CFWL_DateTimeCalendar *m_pOwner;
+ FX_BOOL m_bFlag;
+};
+class CFWL_DateTimePickerImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_DateTimePickerImp(IFWL_Widget *pOuter = NULL);
+ CFWL_DateTimePickerImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_DateTimePickerImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FWL_ERR SetThemeProvider(IFWL_ThemeProvider *pTP);
+ virtual FWL_ERR GetCurSel(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay);
+ virtual FWL_ERR SetCurSel(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+ virtual FWL_ERR SetEditText(const CFX_WideString &wsText);
+ virtual FWL_ERR GetEditText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const;
+public:
+ virtual FX_BOOL CanUndo();
+ virtual FX_BOOL CanRedo();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual FX_BOOL CanCopy();
+ virtual FX_BOOL CanCut();
+ virtual FX_BOOL CanSelectAll();
+ virtual FX_BOOL Copy(CFX_WideString &wsCopy);
+ virtual FX_BOOL Cut(CFX_WideString &wsCut);
+ virtual FX_BOOL Paste(const CFX_WideString &wsPaste);
+ virtual FX_BOOL SelectAll();
+ virtual FX_BOOL Delete();
+ virtual FX_BOOL DeSelect();
+ virtual FWL_ERR GetBBox(CFX_RectF &rect);
+ virtual FWL_ERR SetEditLimit(FX_INT32 nLimit);
+ virtual FWL_ERR ModifyEditStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+public:
+ IFWL_DateTimeEdit* GetDataTimeEdit();
+protected:
+ void DrawDropDownButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void FormatDateString(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay, CFX_WideString &wsText);
+ void ShowMonthCalendar(FX_BOOL bActivate);
+ FX_BOOL IsMonthCalendarShowed();
+ void ReSetEditAlignment();
+ void InitProxyForm();
+ void ProcessSelChanged(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+private:
+ FWL_ERR DisForm_Initialize();
+ void DisForm_InitDateTimeCalendar();
+ void DisForm_InitDateTimeEdit();
+ FX_BOOL DisForm_IsMonthCalendarShowed();
+ void DisForm_ShowMonthCalendar(FX_BOOL bActivate);
+ FX_DWORD DisForm_HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ FX_BOOL DisForm_IsNeedShowButton();
+ FWL_ERR DisForm_Update();
+ FWL_ERR DisForm_GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ FWL_ERR DisForm_GetBBox(CFX_RectF &rect);
+ FWL_ERR DisForm_DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+
+ CFX_RectF m_rtBtn;
+ CFX_RectF m_rtClient;
+ FX_INT32 m_iBtnState;
+ FX_INT32 m_iYear;
+ FX_INT32 m_iMonth;
+ FX_INT32 m_iDay;
+ FX_BOOL m_bLBtnDown;
+ IFWL_DateTimeEdit *m_pEdit;
+ IFWL_DateTimeCalender *m_pMonthCal;
+ IFWL_DateTimeForm *m_pForm;
+ FX_FLOAT m_fBtn;
+ class CFWL_MonthCalendarImpDP : public IFWL_MonthCalendarDP
+ {
+ public:
+ CFWL_MonthCalendarImpDP()
+ {
+ m_iCurYear = 2010;
+ m_iCurMonth = 3;
+ m_iCurDay = 29;
+ }
+ virtual FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+ {
+ return FWL_ERR_Succeeded;
+ }
+ virtual FX_INT32 GetCurDay(IFWL_Widget *pWidget)
+ {
+ return m_iCurDay;
+ }
+ virtual FX_INT32 GetCurMonth(IFWL_Widget *pWidget)
+ {
+ return m_iCurMonth;
+ }
+ virtual FX_INT32 GetCurYear(IFWL_Widget *pWidget)
+ {
+ return m_iCurYear;
+ }
+ FX_INT32 m_iCurDay;
+ FX_INT32 m_iCurYear;
+ FX_INT32 m_iCurMonth;
+ };
+
+ CFWL_MonthCalendarImpDP m_MonthCalendarDP;
+ friend class CFWL_DateTimeEditDelegate;
+ friend class CFWL_DateTimeCalendar;
+ friend class CFWL_DateTimeCalendarDelegate;
+ friend class CFWL_DateTimePickerImpDelegate;
+};
+class CFWL_DateTimePickerImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_DateTimePickerImpDelegate(CFWL_DateTimePickerImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+
+ CFWL_DateTimePickerImp *m_pOwner;
+private:
+ void DisForm_OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_editimp.h b/xfa/src/fwl/src/basewidget/include/fwl_editimp.h
new file mode 100644
index 0000000000..b5671e659c
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_editimp.h
@@ -0,0 +1,169 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_EDIT_IMP_H
+#define _FWL_EDIT_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class CFWL_ScrollBarImp;
+class IFWL_Caret;
+class IFWL_AdapterTextField;
+class CFWL_EditImp;
+class CFWL_EditImpDelegate;
+class CFWL_EditImp : public CFWL_WidgetImp, public IFDE_TxtEdtEventSink
+{
+public:
+ CFWL_EditImp(IFWL_Widget *pOuter = NULL);
+ CFWL_EditImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ ~CFWL_EditImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR SetWidgetRect(const CFX_RectF &rect);
+ virtual FWL_ERR Update();
+ virtual FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR SetStates(FX_DWORD dwStates, FX_BOOL bSet = TRUE);
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FWL_ERR SetThemeProvider(IFWL_ThemeProvider *pThemeProvider);
+ virtual FWL_ERR SetText(const CFX_WideString &wsText);
+ virtual FX_INT32 GetTextLength() const;
+ virtual FWL_ERR GetText(CFX_WideString &wsText, FX_INT32 nStart = 0, FX_INT32 nCount = -1) const;
+ virtual FWL_ERR ClearText();
+ virtual FX_INT32 GetCaretPos() const;
+ virtual FX_INT32 SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore = TRUE);
+ virtual FWL_ERR AddSelRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ virtual FX_INT32 CountSelRanges();
+ virtual FX_INT32 GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart);
+ virtual FWL_ERR ClearSelections();
+ virtual FX_INT32 GetLimit();
+ virtual FWL_ERR SetLimit(FX_INT32 nLimit);
+ virtual FWL_ERR SetAliasChar(FX_WCHAR wAlias);
+ virtual FWL_ERR SetFormatString(const CFX_WideString &wsFormat);
+ virtual FWL_ERR Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen);
+ virtual FWL_ERR DeleteSelections();
+ virtual FWL_ERR DeleteRange(FX_INT32 nStart, FX_INT32 nCount = -1);
+ virtual FWL_ERR ReplaceSelections(const CFX_WideStringC &wsReplace);
+ virtual FWL_ERR Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace);
+ virtual FWL_ERR DoClipboard(FX_INT32 iCmd);
+ virtual FX_BOOL Copy(CFX_WideString &wsCopy);
+ virtual FX_BOOL Cut(CFX_WideString &wsCut);
+ virtual FX_BOOL Paste(const CFX_WideString &wsPaste);
+ virtual FX_BOOL Delete();
+ virtual FX_BOOL Redo(FX_BSTR bsRecord);
+ virtual FX_BOOL Undo(FX_BSTR bsRecord);
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual FX_BOOL CanUndo();
+ virtual FX_BOOL CanRedo();
+ virtual FWL_ERR SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant);
+ virtual FWL_ERR SetOuter(IFWL_Widget *pOuter);
+ virtual FWL_ERR SetNumberRange(FX_INT32 iMin, FX_INT32 iMax);
+ virtual void On_CaretChanged(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPage, FX_BOOL bVisible = TRUE);
+ virtual void On_TextChanged(IFDE_TxtEdtEngine * pEdit, FDE_TXTEDT_TEXTCHANGE_INFO &ChangeInfo);
+ virtual void On_PageCountChanged(IFDE_TxtEdtEngine *pEdit) {}
+ virtual void On_SelChanged(IFDE_TxtEdtEngine *pEdit);
+ virtual FX_BOOL On_PageLoad(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose);
+ virtual FX_BOOL On_PageUnload(IFDE_TxtEdtEngine *pEdit, FX_INT32 nPageIndex, FX_INT32 nPurpose);
+ virtual FX_BOOL On_PageChange(IFDE_TxtEdtEngine *pEdit, FX_BOOL bPageUp = TRUE)
+ {
+ return TRUE;
+ }
+ virtual void On_AddDoRecord(IFDE_TxtEdtEngine *pEdit, FX_BSTR bsDoRecord);
+ virtual FX_BOOL On_ValidateField(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex, FX_INT32 nFieldIndex, \
+ const CFX_WideString &wsFieldText, FX_INT32 nCharIndex);
+ virtual FX_BOOL On_ValidateBlock(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex);
+ virtual FX_BOOL On_GetBlockFormatText(IFDE_TxtEdtEngine *pEdit, FX_INT32 nBlockIndex, CFX_WideString &wsBlockText);
+ virtual FX_BOOL On_Validate(IFDE_TxtEdtEngine * pEdit, CFX_WideString &wsText);
+ virtual FWL_ERR SetBackgroundColor(FX_DWORD color);
+ virtual FWL_ERR SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize);
+ void SetScrollOffset(FX_FLOAT fScrollOffset);
+ FX_BOOL GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest);
+ FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace);
+protected:
+ void DrawTextBk(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void DrawContent(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void UpdateEditEngine();
+ void UpdateEditParams();
+ void UpdateEditLayout();
+ FX_BOOL UpdateOffset();
+ FX_BOOL UpdateOffset(IFWL_ScrollBar *pScrollBar, FX_FLOAT fPosChanged);
+ void UpdateVAlignment();
+ void UpdateCaret();
+ IFWL_ScrollBar* UpdateScroll();
+ void Layout();
+ void LayoutScrollBar();
+ void DeviceToEngine(CFX_PointF &pt);
+ void InitScrollBar(FX_BOOL bVert = TRUE);
+ void InitEngine();
+ virtual void ShowCaret(FX_BOOL bVisible, CFX_RectF *pRect = NULL);
+ FX_BOOL ValidateNumberChar(FX_WCHAR cNum);
+ void InitCaret();
+ void ClearRecord();
+ FX_BOOL IsShowScrollBar(FX_BOOL bVert);
+ FX_BOOL IsContentHeightOverflow();
+ FX_INT32 AddDoRecord(FX_BSTR bsDoRecord);
+ void ProcessInsertError(FX_INT32 iError);
+
+ void DrawSpellCheck(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ void AddSpellCheckObj(CFX_Path& PathData, FX_INT32 nStart, FX_INT32 nCount, FX_FLOAT fOffSetX, FX_FLOAT fOffSetY);
+ FX_INT32 GetWordAtPoint(CFX_PointF pointf, FX_INT32& nCount);
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtEngine;
+ CFX_RectF m_rtStatic;
+ FX_FLOAT m_fVAlignOffset;
+ FX_FLOAT m_fScrollOffsetX;
+ FX_FLOAT m_fScrollOffsetY;
+ IFDE_TxtEdtEngine* m_pEdtEngine;
+ FX_BOOL m_bLButtonDown;
+ FX_INT32 m_nSelStart;
+ FX_INT32 m_nLimit;
+ FX_FLOAT m_fSpaceAbove;
+ FX_FLOAT m_fSpaceBelow;
+ FX_FLOAT m_fFontSize;
+ FX_ARGB m_argbSel;
+ FX_BOOL m_bSetRange;
+ FX_INT32 m_iMin;
+ FX_INT32 m_iMax;
+ IFWL_ScrollBar* m_pVertScrollBar;
+ IFWL_ScrollBar* m_pHorzScrollBar;
+ IFWL_Caret* m_pCaret;
+ IFWL_AdapterTextField* m_pTextField;
+ CFX_WideString m_wsCache;
+ friend class CFWL_TxtEdtEventSink;
+ friend class CFWL_EditImpDelegate;
+ FX_DWORD m_backColor;
+ FX_BOOL m_updateBackColor;
+ CFX_WideString m_wsFont;
+ CFX_ByteStringArray m_RecordArr;
+ FX_INT32 m_iCurRecord;
+ FX_INT32 m_iMaxRecord;
+};
+class CFWL_EditImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_EditImpDelegate(CFWL_EditImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void DoActivate(CFWL_MsgActivate *pMsg);
+ void DoDeactivate(CFWL_MsgDeactivate *pMsg);
+ void DoButtonDown(CFWL_MsgMouse *pMsg);
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnButtonDblClk(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnKeyDown(CFWL_MsgKey *pMsg);
+ void OnChar(CFWL_MsgKey *pMsg);
+ FX_BOOL OnScroll(IFWL_ScrollBar *pScrollBar, FX_DWORD dwCode, FX_FLOAT fPos);
+ void DoCursor(CFWL_MsgMouse *pMsg);
+ CFWL_EditImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h b/xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h
new file mode 100644
index 0000000000..def7eb9650
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_formproxyimp.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_FORMPROXY_IMP_H
+#define _FWL_FORMPROXY_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class CFWL_FormImp;
+class CFWL_FormProxyImp;
+class CFWL_FormProxyImpDelegate;
+class CFWL_FormProxyImp : public CFWL_FormImp
+{
+public:
+ CFWL_FormProxyImp(IFWL_Widget *pOuter);
+ CFWL_FormProxyImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter);
+ ~CFWL_FormProxyImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FX_BOOL IsInstance(FX_WSTR wsClass) const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ friend class CFWL_FormProxyImpDelegate;
+};
+class CFWL_FormProxyImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_FormProxyImpDelegate(CFWL_FormProxyImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+protected:
+ CFWL_FormProxyImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_listboximp.h b/xfa/src/fwl/src/basewidget/include/fwl_listboximp.h
new file mode 100644
index 0000000000..51d605885f
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_listboximp.h
@@ -0,0 +1,98 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_LISTBOX_IMP_H
+#define _FWL_LISTBOX_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class CFWL_ScrollBarImp;
+class IFWL_Widget;
+class CFWL_ListBoxImp;
+class CFWL_ListBoxImpDelegate;
+class CFWL_ListBoxImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_ListBoxImp(IFWL_Widget *pOuter = NULL);
+ CFWL_ListBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ ~CFWL_ListBoxImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FWL_ERR SetThemeProvider(IFWL_ThemeProvider *pThemeProvider);
+ virtual FX_INT32 CountSelItems();
+ virtual FWL_HLISTITEM GetSelItem(FX_INT32 nIndexSel);
+ virtual FX_INT32 GetSelIndex(FX_INT32 nIndex);
+ virtual FWL_ERR SetSelItem(FWL_HLISTITEM hItem, FX_BOOL bSelect = TRUE);
+ virtual FWL_ERR GetItemText(FWL_HLISTITEM hItem, CFX_WideString &wsText);
+ virtual FWL_ERR GetScrollPos(FX_FLOAT &fPos, FX_BOOL bVert = TRUE);
+ virtual FWL_ERR* Sort(IFWL_ListBoxCompare *pCom);
+protected:
+ FWL_HLISTITEM GetItem(FWL_HLISTITEM hItem, FX_DWORD dwKeyCode);
+ void SetSelection(FWL_HLISTITEM hStart, FWL_HLISTITEM hEnd, FX_BOOL bSelected);
+ void SetSelectionDirect(FWL_HLISTITEM hItem, FX_BOOL bSelect);
+ FX_BOOL IsItemSelected(FWL_HLISTITEM hItem);
+ void ClearSelection();
+ void SelectAll();
+ FWL_HLISTITEM GetFocusedItem();
+ void SetFocusItem(FWL_HLISTITEM hItem);
+ FWL_HLISTITEM GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy);
+ FX_BOOL GetItemCheckRect(FWL_HLISTITEM hItem, CFX_RectF &rtCheck);
+ FX_BOOL SetItemChecked(FWL_HLISTITEM hItem, FX_BOOL bChecked);
+ FX_BOOL GetItemChecked(FWL_HLISTITEM hItem);
+ FX_BOOL ScrollToVisible(FWL_HLISTITEM hItem);
+ void DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void DrawItems(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void DrawItem(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, FWL_HLISTITEM hItem, FX_INT32 Index, const CFX_RectF &rtItem, const CFX_Matrix *pMatrix = NULL);
+ void DrawStatic(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme);
+ CFX_SizeF CalcSize(FX_BOOL bAutoSize = FALSE);
+ void GetItemSize(CFX_SizeF &size, FWL_HLISTITEM hItem, FX_FLOAT fWidth, FX_FLOAT fHeight, FX_BOOL bAutoSize = FALSE);
+ FX_FLOAT GetMaxTextWidth();
+ FX_FLOAT GetScrollWidth();
+ FX_FLOAT GetItemHeigt();
+ void InitScrollBar(FX_BOOL bVert = TRUE);
+ void SortItem();
+ FX_BOOL IsShowScrollBar(FX_BOOL bVert);
+ void ProcessSelChanged();
+protected:
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtStatic;
+ CFX_RectF m_rtConent;
+ IFWL_ScrollBar* m_pHorzScrollBar;
+ IFWL_ScrollBar* m_pVertScrollBar;
+ FX_DWORD m_dwTTOStyles;
+ FX_INT32 m_iTTOAligns;
+ FWL_HLISTITEM m_hAnchor;
+ FX_FLOAT m_fItemHeight;
+ FX_FLOAT m_fScorllBarWidth;
+ FX_BOOL m_bLButtonDown;
+ IFWL_ThemeProvider *m_pScrollBarTP;
+ friend class CFWL_ListBoxImpDelegate;
+};
+class CFWL_ListBoxImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_ListBoxImpDelegate(CFWL_ListBoxImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseWheel(CFWL_MsgMouseWheel *pMsg);
+ void OnKeyDown(CFWL_MsgKey *pMsg);
+ void OnVK(FWL_HLISTITEM hItem, FX_BOOL bShift, FX_BOOL bCtrl);
+ FX_BOOL OnScroll(IFWL_ScrollBar *pScrollBar, FX_DWORD dwCode, FX_FLOAT fPos);
+ void DispatchSelChangedEv();
+ CFWL_ListBoxImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_monthcalendarimp.h b/xfa/src/fwl/src/basewidget/include/fwl_monthcalendarimp.h
new file mode 100644
index 0000000000..fc4da5864f
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_monthcalendarimp.h
@@ -0,0 +1,203 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_MONTHCALENDAR_IMP_H
+#define _FWL_MONTHCALENDAR_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class IFDE_DateTime;
+class CFDE_DateTime;
+extern FX_BYTE FX_DaysInMonth(FX_INT32 iYear, FX_BYTE iMonth);
+class CFWL_MonthCalendarImp;
+class CFWL_MonthCalendarImpDelegate;
+class CFWL_MonthCalendarImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_MonthCalendarImp(IFWL_Widget *pOuter = NULL);
+ CFWL_MonthCalendarImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ ~CFWL_MonthCalendarImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_INT32 CountSelect();
+ virtual FX_BOOL GetSelect(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay, FX_INT32 nIndex = 0);
+ virtual FX_BOOL SetSelect(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+protected:
+ void DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawHeadBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawLButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawRButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawCaption(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawSeperator(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawDatesInBK(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawWeek(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawWeekNumber(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawWeekNumberSep(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawToday(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawDatesIn(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawDatesOut(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawDatesInCircle(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawTodayCircle(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ CFX_SizeF CalcSize(FX_BOOL bAutoSize = FALSE);
+ void LayOut();
+ void CalcHeadSize();
+ void CalcTodaySize();
+ void CalDateItem();
+ void GetCapValue();
+ FX_INT32 CalWeekNumber(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+
+ FX_BOOL GetMinDate(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay);
+ FX_BOOL SetMinDate(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+ FX_BOOL GetMaxDate(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay);
+ FX_BOOL SetMaxDate(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+ FX_BOOL InitDate();
+ void ClearDateItem();
+ void ReSetDateItem();
+ FX_BOOL NextMonth();
+ FX_BOOL PrevMonth();
+ void ChangeToMonth(FX_INT32 iYear, FX_INT32 iMonth);
+ FX_BOOL RemoveSelDay(FX_INT32 iDay, FX_BOOL bAll = FALSE);
+ FX_BOOL AddSelDay(FX_INT32 iDay);
+ FX_BOOL JumpToToday();
+ void GetHeadText(FX_INT32 iYear, FX_INT32 iMonth, CFX_WideString &wsHead);
+ void GetTodayText(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay, CFX_WideString &wsToday);
+ FX_INT32 GetDayAtPoint(FX_FLOAT x, FX_FLOAT y);
+ FX_BOOL GetDayRect(FX_INT32 iDay, CFX_RectF &rtDay);
+ typedef struct _DATE {
+ _DATE()
+ {
+ iYear = 0;
+ iMonth = 0;
+ iDay = 0;
+ }
+ _DATE(FX_INT32 year, FX_INT32 month, FX_INT32 day) : iYear(year), iMonth(month), iDay(day) {}
+ FX_BOOL operator < (const _DATE &right)
+ {
+ if (iYear < right.iYear) {
+ return TRUE;
+ } else if (iYear == right.iYear) {
+ if (iMonth < right.iMonth) {
+ return TRUE;
+ } else if (iMonth == right.iMonth) {
+ return iDay < right.iDay;
+ }
+ }
+ return FALSE;
+ }
+ FX_BOOL operator > (const _DATE &right)
+ {
+ if (iYear > right.iYear) {
+ return TRUE;
+ } else if (iYear == right.iYear) {
+ if (iMonth > right.iMonth) {
+ return TRUE;
+ } else if (iMonth == right.iMonth) {
+ return iDay > right.iDay;
+ }
+ }
+ return FALSE;
+ }
+ FX_INT32 iYear;
+ FX_INT32 iMonth;
+ FX_INT32 iDay;
+
+ } DATE, *LPDATE;
+ FX_BOOL m_bInit;
+ CFX_RectF m_rtHead;
+ CFX_RectF m_rtWeek;
+ CFX_RectF m_rtLBtn;
+ CFX_RectF m_rtRBtn;
+ CFX_RectF m_rtDates;
+ CFX_RectF m_rtHSep;
+ CFX_RectF m_rtHeadText;
+ CFX_RectF m_rtToday;
+ CFX_RectF m_rtTodayFlag;
+ CFX_RectF m_rtWeekNum;
+ CFX_RectF m_rtWeekNumSep;
+ CFX_RectF m_rtTemp;
+ CFX_WideString m_wsHead;
+ CFX_WideString m_wsToday;
+ CFX_DateTime *m_pDateTime;
+ CFX_PtrArray m_arrDates;
+ FX_INT32 m_iCurYear;
+ FX_INT32 m_iCurMonth;
+ FX_INT32 m_iYear;
+ FX_INT32 m_iMonth;
+ FX_INT32 m_iDay;
+ FX_INT32 m_iHovered;
+ FX_INT32 m_iLBtnPartStates;
+ FX_INT32 m_iRBtnPartStates;
+ DATE m_dtMin;
+ DATE m_dtMax;
+ CFX_SizeF m_szHead;
+ CFX_SizeF m_szCell;
+ CFX_SizeF m_szToday;
+ typedef CFX_ArrayTemplate<FX_INT32> CFWL_Int32Array;
+ CFWL_Int32Array m_arrSelDays;
+ FX_INT32 m_iMaxSel;
+ CFX_RectF m_rtClient;
+ FX_FLOAT m_fHeadWid;
+ FX_FLOAT m_fHeadHei;
+ FX_FLOAT m_fHeadBtnWid;
+ FX_FLOAT m_fHeadBtnHei;
+ FX_FLOAT m_fHeadBtnHMargin;
+ FX_FLOAT m_fHeadBtnVMargin;
+ FX_FLOAT m_fHeadTextWid;
+ FX_FLOAT m_fHeadTextHei;
+ FX_FLOAT m_fHeadTextHMargin;
+ FX_FLOAT m_fHeadTextVMargin;
+ FX_FLOAT m_fHSepWid;
+ FX_FLOAT m_fHSepHei;
+
+ FX_FLOAT m_fWeekNumWid;
+ FX_FLOAT m_fSepDOffset;
+ FX_FLOAT m_fSepX;
+ FX_FLOAT m_fSepY;
+
+ FX_FLOAT m_fWeekNumHeigh;
+ FX_FLOAT m_fWeekWid;
+ FX_FLOAT m_fWeekHei;
+ FX_FLOAT m_fDateCellWid;
+ FX_FLOAT m_fDateCellHei;
+
+ FX_FLOAT m_fTodayWid;
+ FX_FLOAT m_fTodayHei;
+ FX_FLOAT m_fTodayFlagWid;
+
+ FX_FLOAT m_fMCWid;
+ FX_FLOAT m_fMCHei;
+ friend class CFWL_MonthCalendarImpDelegate;
+};
+typedef struct _DATEINFO {
+ _DATEINFO(FX_INT32 day, FX_INT32 dayofweek, FX_DWORD dwSt, CFX_RectF rc, CFX_WideString &wsday) : iDay(day), iDayOfWeek(dayofweek), dwStates(dwSt), rect(rc), wsDay(wsday) {}
+ FX_INT32 iDay;
+ FX_INT32 iDayOfWeek;
+ FX_DWORD dwStates;
+ CFX_RectF rect;
+ CFX_WideString wsDay;
+} DATEINFO, *LPDATEINFO;
+class CFWL_MonthCalendarImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_MonthCalendarImpDelegate(CFWL_MonthCalendarImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnActivate(CFWL_Message *pMsg);
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+ CFWL_MonthCalendarImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_pictureboximp.h b/xfa/src/fwl/src/basewidget/include/fwl_pictureboximp.h
new file mode 100644
index 0000000000..038ebeb535
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_pictureboximp.h
@@ -0,0 +1,47 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PICTUREBOX_IMP_H
+#define _FWL_PICTUREBOX_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class CFWL_PictureBoxImp;
+class CFWL_PictureBoxImpDelegate;
+class CFWL_PictureBoxImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_PictureBoxImp(IFWL_Widget *pOuter = NULL);
+ CFWL_PictureBoxImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ ~CFWL_PictureBoxImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ FX_BOOL VStyle(FX_BOOL dwStyle);
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtImage;
+ CFX_Matrix m_matrix;
+ FX_BOOL m_bTop;
+ FX_BOOL m_bVCenter;
+ FX_BOOL m_bButton;
+ friend class CFWL_PictureBoxImpDelegate;
+};
+class CFWL_PictureBoxImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_PictureBoxImpDelegate(CFWL_PictureBoxImp *pOwner);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ CFWL_PictureBoxImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_pushbuttonimp.h b/xfa/src/fwl/src/basewidget/include/fwl_pushbuttonimp.h
new file mode 100644
index 0000000000..1688da887c
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_pushbuttonimp.h
@@ -0,0 +1,57 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PUSHBUTTON_IMP_H
+#define _FWL_PUSHBUTTON_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class CFWL_PushButtonImp;
+class CFWL_PushButtonImpDelegate;
+class CFWL_PushButtonImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_PushButtonImp(IFWL_Widget *pOuter = NULL);
+ CFWL_PushButtonImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_PushButtonImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR SetStates(FX_DWORD dwStates, FX_BOOL bSet = TRUE);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawText(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ FX_DWORD GetPartStates();
+ void UpdateTextOutStyles();
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtCaption;
+ FX_BOOL m_bBtnDown;
+ FX_DWORD m_dwTTOStyles;
+ FX_INT32 m_iTTOAlign;
+ friend class CFWL_PushButtonImpDelegate;
+};
+class CFWL_PushButtonImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_PushButtonImpDelegate(CFWL_PushButtonImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+ void OnKeyDown(CFWL_MsgKey *pMsg);
+ CFWL_PushButtonImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h b/xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h
new file mode 100644
index 0000000000..e4073b5fc7
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_scrollbarimp.h
@@ -0,0 +1,113 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_SCROLLBAR_IMP_H
+#define _FWL_SCROLLBAR_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class IFWL_Timer;
+class IFWL_TimerDelegate;
+class CFWL_ScrollBarImp;
+class CFWL_ScrollBarImpDelegate;
+class CFWL_ScrollBarImp : public CFWL_WidgetImp, public IFWL_Timer
+{
+public:
+ CFWL_ScrollBarImp(IFWL_Widget *pOuter = NULL);
+ CFWL_ScrollBarImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ ~CFWL_ScrollBarImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL IsVertical() ;
+ virtual FWL_ERR GetRange(FX_FLOAT &fMin, FX_FLOAT &fMax);
+ virtual FWL_ERR SetRange(FX_FLOAT fMin, FX_FLOAT fMax);
+ virtual FX_FLOAT GetPageSize();
+ virtual FWL_ERR SetPageSize(FX_FLOAT fPageSize);
+ virtual FX_FLOAT GetStepSize();
+ virtual FWL_ERR SetStepSize(FX_FLOAT fStepSize);
+ virtual FX_FLOAT GetPos();
+ virtual FWL_ERR SetPos(FX_FLOAT fPos);
+ virtual FX_FLOAT GetTrackPos();
+ virtual FWL_ERR SetTrackPos(FX_FLOAT fTrackPos);
+ virtual FX_BOOL DoScroll(FX_DWORD dwCode, FX_FLOAT fPos = 0.0f);
+ virtual FWL_ERR SetOuter(IFWL_Widget *pOuter);
+ virtual FX_INT32 Run(FWL_HTIMER hTimer);
+protected:
+ void DrawTrack(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, FX_BOOL bLower = TRUE, const CFX_Matrix *pMatrix = NULL);
+ void DrawArrowBtn(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, FX_BOOL bMinBtn = TRUE, const CFX_Matrix *pMatrix = NULL);
+ void DrawThumb(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void Layout();
+ void CalcButtonLen();
+ void CalcMinButtonRect(CFX_RectF &rect);
+ void CalcMaxButtonRect(CFX_RectF &rect);
+ void CalcThumbButtonRect(CFX_RectF &rect);
+ void CalcMinTrackRect(CFX_RectF &rect);
+ void CalcMaxTrackRect(CFX_RectF &rect);
+
+ FX_FLOAT GetTrackPointPos(FX_FLOAT fx, FX_FLOAT fy);
+ void GetTrackRect(CFX_RectF &rect, FX_BOOL bLower = TRUE);
+ FX_BOOL SendEvent();
+ FX_BOOL OnScroll(FX_DWORD dwCode, FX_FLOAT fPos);
+ FWL_HTIMER m_hTimer;
+ FX_FLOAT m_fRangeMin;
+ FX_FLOAT m_fRangeMax;
+ FX_FLOAT m_fPageSize;
+ FX_FLOAT m_fStepSize;
+ FX_FLOAT m_fPos;
+ FX_FLOAT m_fTrackPos;
+ FX_INT32 m_iMinButtonState;
+ FX_INT32 m_iMaxButtonState;
+ FX_INT32 m_iThumbButtonState;
+ FX_INT32 m_iMinTrackState;
+ FX_INT32 m_iMaxTrackState;
+ FX_FLOAT m_fLastTrackPos;
+ FX_FLOAT m_cpTrackPointX;
+ FX_FLOAT m_cpTrackPointY;
+ FX_INT32 m_iMouseWheel;
+ FX_BOOL m_bTrackMouseLeave;
+ FX_BOOL m_bMouseHover;
+ FX_BOOL m_bMouseDown;
+ FX_BOOL m_bRepaintThumb;
+
+ FX_FLOAT m_fButtonLen;
+ FX_BOOL m_bMinSize;
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtThumb;
+ CFX_RectF m_rtMinBtn;
+ CFX_RectF m_rtMaxBtn;
+ CFX_RectF m_rtMinTrack;
+ CFX_RectF m_rtMaxTrack;
+ FX_BOOL m_bCustomLayout;
+ FX_FLOAT m_fMinThumb;
+ friend class CFWL_ScrollBarImpDelegate;
+};
+class CFWL_ScrollBarImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_ScrollBarImpDelegate(CFWL_ScrollBarImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ void OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ void OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ void OnMouseLeave();
+ void OnMouseWheel(FX_FLOAT fx, FX_FLOAT fy, FX_DWORD dwFlags, FX_FLOAT fDeltaX, FX_FLOAT fDeltaY);
+ void DoMouseDown(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState, FX_FLOAT fx, FX_FLOAT fy);
+ void DoMouseUp(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState, FX_FLOAT fx, FX_FLOAT fy);
+ void DoMouseMove(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState, FX_FLOAT fx, FX_FLOAT fy);
+ void DoMouseLeave(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState);
+ void DoMouseHover(FX_INT32 iItem, const CFX_RectF &rtItem, FX_INT32 &iState);
+
+ CFWL_ScrollBarImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_spinbuttonimp.h b/xfa/src/fwl/src/basewidget/include/fwl_spinbuttonimp.h
new file mode 100644
index 0000000000..2275a40f90
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_spinbuttonimp.h
@@ -0,0 +1,62 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_SPINBUTTON_IMP_H
+#define _FWL_SPINBUTTON_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class IFWL_Timer;
+class CFWL_SpinButtonImp;
+class CFWL_SpinButtonImpDelegate;
+class CFWL_SpinButtonImp : public CFWL_WidgetImp, public IFWL_Timer
+{
+public:
+ CFWL_SpinButtonImp(IFWL_Widget *pOuter = NULL);
+ CFWL_SpinButtonImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ ~CFWL_SpinButtonImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_INT32 Run(FWL_HTIMER hTimer);
+ FWL_ERR EnableButton(FX_BOOL bEnable, FX_BOOL bUp = TRUE);
+ FX_BOOL IsButtonEnable(FX_BOOL bUp = TRUE);
+protected:
+ void DrawUpButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawDownButton(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtUpButton;
+ CFX_RectF m_rtDnButton;
+ FX_DWORD m_dwUpState;
+ FX_DWORD m_dwDnState;
+ FX_INT32 m_iButtonIndex;
+ FX_BOOL m_bLButtonDwn;
+ FWL_HTIMER m_hTimer;
+ friend class CFWL_SpinButtonImpDelegate;
+};
+class CFWL_SpinButtonImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_SpinButtonImpDelegate(CFWL_SpinButtonImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+ void OnKeyDown(CFWL_MsgKey *pMsg);
+ CFWL_SpinButtonImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fwl_tooltipctrlimp.h b/xfa/src/fwl/src/basewidget/include/fwl_tooltipctrlimp.h
new file mode 100644
index 0000000000..7317f3fe5b
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fwl_tooltipctrlimp.h
@@ -0,0 +1,78 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_ToolTip_IMP_H
+#define _FWL_ToolTip_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class IFWL_Widget;
+class IFWL_Timer;
+class CFWL_ToolTipImp;
+class CFWL_ToolTipImpDelegate;
+class CFWL_ToolTipImp : public CFWL_FormImp
+{
+public:
+ CFWL_ToolTipImp(IFWL_Widget *pOuter = NULL);
+ CFWL_ToolTipImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_ToolTipImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FWL_ERR SetStates(FX_DWORD dwStates, FX_BOOL bSet );
+ virtual FWL_ERR GetClientRect(CFX_RectF &rect);
+ FWL_ERR SetAnchor(const CFX_RectF &rtAnchor);
+ FWL_ERR Show();
+ FWL_ERR Hide();
+protected:
+ void DrawBkground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void DrawText(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix);
+ void UpdateTextOutStyles();
+ void RefreshToolTipPos();
+ class CFWL_ToolTipTimer : public IFWL_Timer
+ {
+ public:
+ CFWL_ToolTipTimer() {};
+ ~CFWL_ToolTipTimer() {};
+ CFWL_ToolTipTimer(CFWL_ToolTipImp * pToolTip);
+ virtual FX_INT32 Run(FWL_HTIMER hTimer);
+ CFWL_ToolTipImp *m_pToolTip;
+ };
+ CFX_RectF m_rtClient;
+ CFX_RectF m_rtCaption;
+ FX_BOOL m_bBtnDown;
+ FX_DWORD m_dwTTOStyles;
+ FX_INT32 m_iTTOAlign;
+ CFX_RectF m_rtAnchor;
+ FWL_HTIMER m_hTimerShow;
+ FWL_HTIMER m_hTimerHide;
+ CFWL_ToolTipTimer* m_pTimer;
+ CFWL_ToolTipTimer m_TimerShow;
+ CFWL_ToolTipTimer m_TimerHide;
+ friend class CFWL_ToolTipImpDelegate;
+ friend class CFWL_ToolTipTimer;
+};
+class CFWL_ToolTipImpDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_ToolTipImpDelegate(CFWL_ToolTipImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnFocusChanged(CFWL_Message *pMsg, FX_BOOL bSet = TRUE);
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+ void OnKeyDown(CFWL_MsgKey *pMsg);
+ CFWL_ToolTipImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/basewidget/include/fxmath_barcodeimp.h b/xfa/src/fwl/src/basewidget/include/fxmath_barcodeimp.h
new file mode 100644
index 0000000000..bb859968f2
--- /dev/null
+++ b/xfa/src/fwl/src/basewidget/include/fxmath_barcodeimp.h
@@ -0,0 +1,45 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXMATH_BARCODEIMP_H_
+#define _FXMATH_BARCODEIMP_H_
+class CFX_Barcode : public IFX_Barcode, public CFX_Object
+{
+public:
+ CFX_Barcode();
+ ~CFX_Barcode();
+ FX_BOOL Crreate(BC_TYPE type);
+ virtual void Release();
+ virtual BC_TYPE GetType();
+ virtual FX_BOOL Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e);
+ virtual FX_BOOL RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e);
+ virtual FX_BOOL RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e);
+ virtual CFX_WideString Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 height, FX_INT32 &errorCode);
+ virtual CFX_WideString Decode(CFX_DIBitmap *pBitmap, FX_INT32 &errorCode);
+ virtual FX_BOOL SetCharEncoding(BC_CHAR_ENCODING encoding);
+ virtual FX_BOOL SetModuleHeight(FX_INT32 moduleHeight);
+ virtual FX_BOOL SetModuleWidth(FX_INT32 moduleWidth);
+ virtual FX_BOOL SetHeight(FX_INT32 height);
+ virtual FX_BOOL SetWidth(FX_INT32 width);
+ virtual FX_BOOL CheckContentValidity(FX_WSTR contents);
+ virtual FX_BOOL SetPrintChecksum(FX_BOOL checksum);
+ virtual FX_BOOL SetDataLength(FX_INT32 length);
+ virtual FX_BOOL SetCalChecksum(FX_INT32 state);
+ virtual FX_BOOL SetFont(CFX_Font* pFont);
+ virtual FX_BOOL SetFontSize(FX_FLOAT size);
+ virtual FX_BOOL SetFontStyle(FX_INT32 style);
+ virtual FX_BOOL SetFontColor(FX_ARGB color);
+ virtual FX_BOOL SetTextLocation(BC_TEXT_LOC location);
+ virtual FX_BOOL SetWideNarrowRatio(FX_INT32 ratio);
+ virtual FX_BOOL SetStartChar(FX_CHAR start);
+ virtual FX_BOOL SetEndChar(FX_CHAR end);
+ virtual FX_BOOL SetVersion(FX_INT32 version);
+ virtual FX_BOOL SetErrorCorrectionLevel(FX_INT32 level);
+ virtual FX_BOOL SetTruncated(FX_BOOL truncated);
+protected:
+ CBC_CodeBase* m_pBCEngine;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/fwl_appimp.cpp b/xfa/src/fwl/src/core/fwl_appimp.cpp
new file mode 100644
index 0000000000..70e46e6a41
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_appimp.cpp
@@ -0,0 +1,110 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_widgetmgrimp.h"
+#include "include/fwl_appimp.h"
+IFWL_App* IFWL_App::Create(IFWL_AdapterNative *pAdapter)
+{
+ return (IFWL_App*) FX_NEW CFWL_AppImp(pAdapter);
+}
+CFWL_AppImp::CFWL_AppImp(IFWL_AdapterNative *pAdapter)
+ : m_pWidgetMgr(NULL)
+ , m_pThemeProvider(NULL)
+{
+ if (!pAdapter) {
+ pAdapter = FWL_CreateFuelAdapterNative();
+ m_bFuelAdapter = TRUE;
+ } else {
+ m_bFuelAdapter = FALSE;
+ }
+ m_pAdapterNative = pAdapter;
+}
+CFWL_AppImp::~CFWL_AppImp()
+{
+ delete CFWL_ToolTipContainer::getInstance();
+ if (m_bFuelAdapter) {
+ FWL_ReleaseFuelAdapterNative(m_pAdapterNative);
+ m_pAdapterNative = NULL;
+ }
+ if (m_pWidgetMgr) {
+ delete m_pWidgetMgr;
+ m_pWidgetMgr = NULL;
+ }
+}
+FWL_ERR CFWL_AppImp::Initialize()
+{
+ if (!m_pWidgetMgr) {
+ m_pWidgetMgr = FX_NEW CFWL_WidgetMgr(m_pAdapterNative);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_AppImp::Finalize()
+{
+ if (m_pWidgetMgr) {
+ delete m_pWidgetMgr;
+ m_pWidgetMgr = NULL;
+ }
+ return FWL_ERR_Succeeded;
+}
+IFWL_AdapterNative* CFWL_AppImp::GetAdapterNative()
+{
+ return m_pAdapterNative;
+}
+IFWL_AdapterWidgetMgr* FWL_GetAdapterWidgetMgr()
+{
+ return ((CFWL_WidgetMgr*)FWL_GetWidgetMgr())->GetAdapterWidgetMgr();
+}
+IFWL_WidgetMgr* CFWL_AppImp::GetWidgetMgr()
+{
+ return (IFWL_WidgetMgr*)m_pWidgetMgr;
+}
+FWL_ERR CFWL_AppImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider)
+{
+ m_pThemeProvider = pThemeProvider;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_AppImp::Exit(FX_INT32 iExitCode )
+{
+ while (m_pNoteDriver->PopNoteLoop());
+ return m_pWidgetMgr->GetAdapterWidgetMgr()->Exit(0);
+}
+IFWL_ThemeProvider* CFWL_AppImp::GetThemeProvider()
+{
+ return m_pThemeProvider;
+}
+IFWL_AdapterNative* FWL_GetAdapterNative()
+{
+ IFWL_App* pApp = FWL_GetApp();
+ _FWL_RETURN_VALUE_IF_FAIL(pApp, NULL);
+ return pApp->GetAdapterNative();
+}
+IFWL_ThemeProvider* FWL_GetThemeProvider()
+{
+ return NULL;
+}
+static IFWL_App *_theApp = NULL;
+IFWL_App* FWL_GetApp()
+{
+ return _theApp;
+}
+void FWL_SetApp(IFWL_App *pApp)
+{
+ _theApp = pApp;
+}
+FWL_ERR FWL_SetFullScreen(IFWL_Widget *pWidget, FX_BOOL bFullScreen)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FWL_ERR_Succeeded);
+ IFWL_NoteThread *pNoteTread = pWidget->GetOwnerThread();
+ _FWL_RETURN_VALUE_IF_FAIL(pNoteTread, FWL_ERR_Succeeded);
+ CFWL_NoteDriver *pNoteDriver = (CFWL_NoteDriver*)pNoteTread->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(pNoteTread, FWL_ERR_Succeeded);
+ pNoteDriver->NotifyFullScreenMode(pWidget, bFullScreen);
+ return FWL_GetAdapterWidgetMgr()->SetFullScreen(pWidget, bFullScreen);
+}
diff --git a/xfa/src/fwl/src/core/fwl_contentimp.cpp b/xfa/src/fwl/src/core/fwl_contentimp.cpp
new file mode 100644
index 0000000000..3093aebf74
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_contentimp.cpp
@@ -0,0 +1,131 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_widgetimp.h"
+#include "include/fwl_contentimp.h"
+#include "include/fwl_widgetmgrimp.h"
+IFWL_Content* IFWL_Content::Create()
+{
+ return new IFWL_Content;
+}
+FWL_ERR IFWL_Content::Initialize()
+{
+ m_pData = FX_NEW CFWL_ContentImp;
+ ((CFWL_ContentImp*)m_pData)->SetInterface(this);
+ return ((CFWL_ContentImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Content::InsertWidget(IFWL_Widget *pChild, FX_INT32 nIndex )
+{
+ return ((CFWL_ContentImp*)m_pData)->InsertWidget(pChild, nIndex);
+}
+FWL_ERR IFWL_Content::RemoveWidget(IFWL_Widget *pWidget)
+{
+ return ((CFWL_ContentImp*)m_pData)->RemoveWidget(pWidget);
+}
+FWL_ERR IFWL_Content::RemoveAllWidgets()
+{
+ return ((CFWL_ContentImp*)m_pData)->RemoveAllWidgets();
+}
+FWL_ERR IFWL_Content::GetMinSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight)
+{
+ return ((CFWL_ContentImp*)m_pData)->GetMinSize(fWidth, fHeight);
+}
+FWL_ERR IFWL_Content::SetMinSize(FX_FLOAT fWidth, FX_FLOAT fHeight)
+{
+ return ((CFWL_ContentImp*)m_pData)->SetMinSize(fWidth, fHeight);
+}
+FWL_ERR IFWL_Content::GetMaxSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight)
+{
+ return ((CFWL_ContentImp*)m_pData)->GetMaxSize(fWidth, fHeight);
+}
+FWL_ERR IFWL_Content::SetMaxSize(FX_FLOAT fWidth, FX_FLOAT fHeight)
+{
+ return ((CFWL_ContentImp*)m_pData)->SetMaxSize(fWidth, fHeight);
+}
+IFWL_Content::IFWL_Content()
+{
+ m_pData = NULL;
+}
+IFWL_Content::~IFWL_Content()
+{
+ if (m_pData) {
+ delete (CFWL_ContentImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+CFWL_ContentImp::CFWL_ContentImp()
+{
+ m_fWidthMin = 0;
+ m_fWidthMax = 10000;
+ m_fHeightMin = 0;
+ m_fHeightMax = 10000;
+}
+CFWL_ContentImp::CFWL_ContentImp(const CFWL_WidgetImpProperties &properties)
+ : CFWL_WidgetImp(properties)
+{
+ m_fWidthMin = 0;
+ m_fWidthMax = 10000;
+ m_fHeightMin = 0;
+ m_fHeightMax = 10000;
+}
+CFWL_ContentImp::~CFWL_ContentImp()
+{
+}
+FWL_ERR CFWL_ContentImp::InsertWidget(IFWL_Widget *pChild, FX_INT32 nIndex )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pChild, FWL_ERR_Indefinite);
+ pChild->SetParent(m_pInterface);
+ if (nIndex == -1) {
+ return FWL_ERR_Succeeded;
+ }
+ CFWL_WidgetMgr *pMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pMgr, FWL_ERR_Indefinite);
+ pMgr->SetWidgetIndex(pChild, nIndex);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ContentImp::RemoveWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FWL_ERR_Indefinite);
+ pWidget->SetParent(NULL);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ContentImp::RemoveAllWidgets()
+{
+ CFWL_WidgetMgr *pMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pMgr, FWL_ERR_Indefinite);
+ while (IFWL_Widget * widget = pMgr->GetWidget(m_pInterface, FWL_WGTRELATION_FirstChild)) {
+ pMgr->SetParent(NULL, widget);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ContentImp::GetMinSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight)
+{
+ fWidth = m_fWidthMin;
+ fHeight = m_fHeightMin;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ContentImp::SetMinSize(FX_FLOAT fWidth, FX_FLOAT fHeight)
+{
+ m_fWidthMin = fWidth;
+ m_fHeightMin = fHeight;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ContentImp::GetMaxSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight)
+{
+ fWidth = m_fWidthMax;
+ fHeight = m_fHeightMax;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ContentImp::SetMaxSize(FX_FLOAT fWidth, FX_FLOAT fHeight)
+{
+ m_fWidthMax = fWidth;
+ m_fHeightMax = fHeight;
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fwl/src/core/fwl_formimp.cpp b/xfa/src/fwl/src/core/fwl_formimp.cpp
new file mode 100644
index 0000000000..2491999484
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_formimp.cpp
@@ -0,0 +1,1434 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_widgetimp.h"
+#include "include/fwl_panelimp.h"
+#include "include/fwl_formimp.h"
+#include "include/fwl_widgetmgrimp.h"
+#include "include/fwl_appimp.h"
+#define FWL_SYSBTNSIZE 21
+#define FWL_SYSBTNMARGIN 5
+#define FWL_SYSBTNSPAN 2
+#define FWL_CornerEnlarge 10
+IFWL_Form* IFWL_Form::Create()
+{
+ return new IFWL_Form;
+}
+FWL_ERR IFWL_Form::Initialize(IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_FormImp(pOuter);
+ ((CFWL_FormImp*)m_pData)->SetInterface(this);
+ return ((CFWL_FormImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Form::Initialize(CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_FormImp(properties, pOuter);
+ ((CFWL_FormImp*)m_pData)->SetInterface(this);
+ return ((CFWL_FormImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Form::Initialize(CFWL_WidgetImpProperties &properties, CFX_WideString *classname, IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_FormImp(properties, pOuter);
+ ((CFWL_FormImp*)m_pData)->SetInterface(this);
+ ((CFWL_FormImp*)m_pData)->SetPrivateData(this, classname, NULL);
+ return ((CFWL_FormImp*)m_pData)->Initialize();
+}
+FWL_FORMSIZE IFWL_Form::GetFormSize()
+{
+ return ((CFWL_FormImp*)m_pData)->GetFormSize();
+}
+FWL_ERR IFWL_Form::SetFormSize(FWL_FORMSIZE eFormSize)
+{
+ return ((CFWL_FormImp*)m_pData)->SetFormSize(eFormSize);
+}
+IFWL_Widget* IFWL_Form::DoModal()
+{
+ return ((CFWL_FormImp*)m_pData)->DoModal();
+}
+IFWL_Widget* IFWL_Form::DoModal(FX_DWORD &dwCommandID)
+{
+ return ((CFWL_FormImp*)m_pData)->DoModal(dwCommandID);
+}
+FWL_ERR IFWL_Form::EndDoModal()
+{
+ return ((CFWL_FormImp*)m_pData)->EndDoModal();
+}
+FWL_ERR IFWL_Form::SetBorderRegion(CFX_Path *pPath)
+{
+ return ((CFWL_FormImp*)m_pData)->SetBorderRegion(pPath);
+}
+IFWL_Form::IFWL_Form()
+{
+ m_pData = NULL;
+}
+IFWL_Form::~IFWL_Form()
+{
+ if (m_pData) {
+ delete (CFWL_FormImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+CFWL_FormImp::CFWL_FormImp(IFWL_Widget *pOuter )
+ : CFWL_PanelImp(pOuter)
+ , m_pCloseBox(NULL)
+ , m_pMinBox(NULL)
+ , m_pMaxBox(NULL)
+ , m_pCaptionBox(NULL)
+ , m_pNoteLoop(NULL)
+ , m_pSubFocus(NULL)
+ , m_fCXBorder(0)
+ , m_fCYBorder(0)
+ , m_iCaptureBtn(-1)
+ , m_iSysBox(0)
+ , m_eResizeType(FORM_RESIZETYPE_None)
+ , m_bLButtonDown(FALSE)
+ , m_bMaximized(FALSE)
+ , m_bSetMaximize(FALSE)
+ , m_bCustomizeLayout(FALSE)
+ , m_eFormSize(FWL_FORMSIZE_Manual)
+ , m_bDoModalFlag(FALSE)
+ , m_pBigIcon(NULL)
+ , m_pSmallIcon(NULL)
+ , m_bMouseIn(FALSE)
+{
+ m_rtRelative.Reset();
+ m_rtCaption.Reset();
+ m_rtRestore.Reset();
+ m_rtCaptionText.Reset();
+ m_rtIcon.Reset();
+ m_InfoStart.m_ptStart.Reset();
+ m_InfoStart.m_szStart.Reset();
+}
+CFWL_FormImp::CFWL_FormImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_PanelImp(properties, pOuter)
+ , m_pCloseBox(NULL)
+ , m_pMinBox(NULL)
+ , m_pMaxBox(NULL)
+ , m_pCaptionBox(NULL)
+ , m_pNoteLoop(NULL)
+ , m_pSubFocus(NULL)
+ , m_fCXBorder(0)
+ , m_fCYBorder(0)
+ , m_iCaptureBtn(-1)
+ , m_iSysBox(0)
+ , m_eResizeType(FORM_RESIZETYPE_None)
+ , m_bLButtonDown(FALSE)
+ , m_bMaximized(FALSE)
+ , m_bSetMaximize(FALSE)
+ , m_bCustomizeLayout(FALSE)
+ , m_eFormSize(FWL_FORMSIZE_Manual)
+ , m_bDoModalFlag(FALSE)
+ , m_pBigIcon(NULL)
+ , m_pSmallIcon(NULL)
+ , m_bMouseIn(FALSE)
+{
+ m_rtRelative.Reset();
+ m_rtCaption.Reset();
+ m_rtRestore.Reset();
+ m_rtCaptionText.Reset();
+ m_rtIcon.Reset();
+ m_InfoStart.m_ptStart.Reset();
+ m_InfoStart.m_szStart.Reset();
+}
+CFWL_FormImp::~CFWL_FormImp()
+{
+ RemoveSysButtons();
+ if (m_pNoteLoop) {
+ delete m_pNoteLoop;
+ m_pNoteLoop = NULL;
+ }
+}
+FWL_ERR CFWL_FormImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_Form;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_FormImp::GetClassID() const
+{
+ return FWL_CLASSHASH_Form;
+}
+FX_BOOL CFWL_FormImp::IsInstance(FX_WSTR wsClass) const
+{
+ if (wsClass == CFX_WideStringC(FWL_CLASS_Form)) {
+ return TRUE;
+ }
+ return CFWL_PanelImp::IsInstance(wsClass);
+}
+FWL_ERR CFWL_FormImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_WidgetImp::Initialize(), FWL_ERR_Indefinite);
+ RegisterForm();
+ RegisterEventTarget();
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_FormDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_FormImp::Finalize()
+{
+ if ( m_pDelegate) {
+ delete (CFWL_FormDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ UnregisterEventTarget();
+ UnRegisterForm();
+ return CFWL_WidgetImp::Finalize();
+}
+FWL_ERR CFWL_FormImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.Reset();
+ FX_FLOAT fCapHeight = GetCaptionHeight();
+ FX_FLOAT fCXBorder = GetBorderSize(TRUE);
+ FX_FLOAT fCYBorder = GetBorderSize(FALSE);
+ FX_FLOAT fEdge = GetEdgeWidth();
+ if (m_pContent) {
+ m_pContent->GetWidgetRect(rect, TRUE);
+ }
+ rect.height += fCapHeight + fCYBorder + fEdge + fEdge;
+ rect.width += fCXBorder + fCXBorder + fEdge + fEdge;
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_FormImp::GetClientRect(CFX_RectF &rect)
+{
+ if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) == 0) {
+ rect = m_pProperties->m_rtWidget;
+ rect.Offset(-rect.left, -rect.top);
+ return FWL_ERR_Succeeded;
+ }
+#ifdef FWL_UseMacSystemBorder
+ rect = m_rtRelative;
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, FWL_ERR_Indefinite);
+ IFWL_AdapterWidgetMgr * adapterWidgetMgr = pWidgetMgr->GetAdapterWidgetMgr();
+ FX_FLOAT l, t, r, b;
+ l = t = r = b = 0;
+ adapterWidgetMgr->GetSystemBorder(l, t, r, b);
+ rect.Deflate(l, t, r, b);
+ rect.left = rect.top = 0;
+ return FWL_ERR_Succeeded;
+#else
+ FX_FLOAT x = 0;
+ FX_FLOAT y = 0;
+ FX_FLOAT t = 0;
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ if (pTheme) {
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pInterface;
+ FX_FLOAT * value = NULL;
+ value = (FX_FLOAT *) pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CXBorder);
+ x = *value;
+ value = (FX_FLOAT *) pTheme->GetCapacity(&part, FWL_WGTCAPACITY_CYBorder);
+ y = *value;
+ value = (FX_FLOAT*)pTheme->GetCapacity(&part, FWL_WGTCAPACITY_FRM_CYCaption);
+ t = *value;
+ }
+ rect = m_pProperties->m_rtWidget;
+ rect.Offset(-rect.left, -rect.top);
+ rect.Deflate(x, t, x, y);
+ return FWL_ERR_Succeeded;
+#endif
+}
+FWL_ERR CFWL_FormImp::Update()
+{
+ if (m_iLock > 0) {
+ return FWL_ERR_Succeeded;
+ }
+ if (!m_pProperties->m_pThemeProvider) {
+ m_pProperties->m_pThemeProvider = GetAvailableTheme();
+ }
+#ifdef FWL_UseMacSystemBorder
+#else
+ SetThemeData();
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Icon) {
+ UpdateIcon();
+ }
+#endif
+ UpdateCaption();
+ Layout();
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_FormImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ IFWL_ThemeProvider *pTheme = GetAvailableTheme();
+ if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_CloseBox;
+ }
+ if (m_pMaxBox && m_pMaxBox->m_rtBtn.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_MaxBox;
+ }
+ if (m_pMinBox && m_pMinBox->m_rtBtn.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_MinBox;
+ }
+ CFX_RectF rtCap;
+ rtCap.Set(m_rtCaption.left + m_fCYBorder,
+ m_rtCaption.top + m_fCXBorder,
+ m_rtCaption.width - FWL_SYSBTNSIZE * m_iSysBox - 2 * m_fCYBorder,
+ m_rtCaption.height - m_fCXBorder);
+ if (rtCap.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Titlebar;
+ }
+ if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) && (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize)) {
+ FX_FLOAT fWidth = m_rtRelative.width - 2 * (m_fCYBorder + FWL_CornerEnlarge);
+ FX_FLOAT fHeight = m_rtRelative.height - 2 * (m_fCXBorder + FWL_CornerEnlarge);
+ CFX_RectF rt;
+ rt.Set(0, m_fCXBorder + FWL_CornerEnlarge, m_fCYBorder, fHeight);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Left;
+ }
+ rt.Set(m_rtRelative.width - m_fCYBorder, m_fCXBorder + FWL_CornerEnlarge, m_fCYBorder, fHeight);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Right;
+ }
+ rt.Set(m_fCYBorder + FWL_CornerEnlarge, 0, fWidth, m_fCXBorder);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Top;
+ }
+ rt.Set(m_fCYBorder + FWL_CornerEnlarge, m_rtRelative.height - m_fCXBorder, fWidth, m_fCXBorder);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Bottom;
+ }
+ rt.Set(0, 0, m_fCYBorder + FWL_CornerEnlarge, m_fCXBorder + FWL_CornerEnlarge);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_LeftTop;
+ }
+ rt.Set(0, m_rtRelative.height - m_fCXBorder - FWL_CornerEnlarge,
+ m_fCYBorder + FWL_CornerEnlarge, m_fCXBorder + FWL_CornerEnlarge);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_LeftBottom;
+ }
+ rt.Set(m_rtRelative.width - m_fCYBorder - FWL_CornerEnlarge, 0,
+ m_fCYBorder + FWL_CornerEnlarge, m_fCXBorder + FWL_CornerEnlarge);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_RightTop;
+ }
+ rt.Set(m_rtRelative.width - m_fCYBorder - FWL_CornerEnlarge,
+ m_rtRelative.height - m_fCXBorder - FWL_CornerEnlarge,
+ m_fCYBorder + FWL_CornerEnlarge,
+ m_fCXBorder + FWL_CornerEnlarge);
+ if (rt.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_RightBottom;
+ }
+ }
+ return FWL_WGTHITTEST_Client;
+}
+FWL_ERR CFWL_FormImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties->m_pThemeProvider, FWL_ERR_Indefinite);
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ FX_BOOL bInactive = !IsActive();
+ FX_INT32 iState = bInactive ? FWL_PARTSTATE_FRM_Inactive : FWL_PARTSTATE_FRM_Normal;
+ if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_NoDrawClient) == 0) {
+ DrawBackground(pGraphics, pTheme);
+ }
+#ifdef FWL_UseMacSystemBorder
+ return FWL_ERR_Succeeded;
+#endif
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_dwStates = iState;
+ param.m_pGraphics = pGraphics;
+ param.m_rtPart = m_rtRelative;
+ if(pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) {
+ param.m_iPart = FWL_PART_FRM_Border;
+ pTheme->DrawBackground(&param);
+ }
+ if ((m_pProperties->m_dwStyleExes & FWL_WGTSTYLE_EdgeMask) != FWL_WGTSTYLE_EdgeNone) {
+ CFX_RectF rtEdge;
+ GetEdgeRect(rtEdge);
+ param.m_iPart = FWL_PART_FRM_Edge;
+ param.m_rtPart = rtEdge;
+ param.m_dwStates = iState;
+ pTheme->DrawBackground(&param);
+ }
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) {
+ param.m_iPart = FWL_PART_FRM_Caption;
+ param.m_dwStates = iState;
+ param.m_rtPart = m_rtCaption;
+ pTheme->DrawBackground(&param);
+ DrawCaptionText(pGraphics, pTheme, pMatrix);
+ } else if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_NarrowCaption) {
+ param.m_iPart = FWL_PART_FRM_NarrowCaption;
+ param.m_dwStates = iState;
+ param.m_rtPart = m_rtCaption;
+ pTheme->DrawBackground(&param);
+ DrawCaptionText(pGraphics, pTheme, pMatrix);
+ }
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Icon) {
+ param.m_iPart = FWL_PART_FRM_Icon;
+ if (HasIcon()) {
+ DrawIconImage(pGraphics, pTheme, pMatrix);
+ }
+ }
+#if (_FX_OS_==_FX_MACOSX_)
+ {
+ if (m_pCloseBox) {
+ param.m_iPart = FWL_PART_FRM_CloseBox;
+ param.m_dwStates = m_pCloseBox->GetPartState();
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) {
+ param.m_dwStates = FWL_PARTSTATE_FRM_Disabled;
+ } else if (FWL_PARTSTATE_FRM_Normal == param.m_dwStates && m_bMouseIn) {
+ param.m_dwStates = FWL_PARTSTATE_FRM_Hover;
+ }
+ param.m_rtPart = m_pCloseBox->m_rtBtn;
+ pTheme->DrawBackground(&param);
+ }
+ if (m_pMaxBox) {
+ param.m_iPart = FWL_PART_FRM_MaximizeBox;
+ param.m_dwStates = m_pMaxBox->GetPartState();
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) {
+ param.m_dwStates = FWL_PARTSTATE_FRM_Disabled;
+ } else if (FWL_PARTSTATE_FRM_Normal == param.m_dwStates && m_bMouseIn) {
+ param.m_dwStates = FWL_PARTSTATE_FRM_Hover;
+ }
+ param.m_rtPart = m_pMaxBox->m_rtBtn;
+ param.m_dwData = m_bMaximized;
+ pTheme->DrawBackground(&param);
+ }
+ if (m_pMinBox) {
+ param.m_iPart = FWL_PART_FRM_MinimizeBox;
+ param.m_dwStates = m_pMinBox->GetPartState();
+ if (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) {
+ param.m_dwStates = FWL_PARTSTATE_FRM_Disabled;
+ } else if (FWL_PARTSTATE_FRM_Normal == param.m_dwStates && m_bMouseIn) {
+ param.m_dwStates = FWL_PARTSTATE_FRM_Hover;
+ }
+ param.m_rtPart = m_pMinBox->m_rtBtn;
+ pTheme->DrawBackground(&param);
+ }
+ m_bMouseIn = FALSE;
+ }
+#else
+ {
+ if (m_pCloseBox) {
+ param.m_iPart = FWL_PART_FRM_CloseBox;
+ param.m_dwStates = m_pCloseBox->GetPartState();
+ param.m_rtPart = m_pCloseBox->m_rtBtn;
+ pTheme->DrawBackground(&param);
+ }
+ if (m_pMaxBox) {
+ param.m_iPart = FWL_PART_FRM_MaximizeBox;
+ param.m_dwStates = m_pMaxBox->GetPartState();
+ param.m_rtPart = m_pMaxBox->m_rtBtn;
+ param.m_dwData = m_bMaximized;
+ pTheme->DrawBackground(&param);
+ }
+ if (m_pMinBox) {
+ param.m_iPart = FWL_PART_FRM_MinimizeBox;
+ param.m_dwStates = m_pMinBox->GetPartState();
+ param.m_rtPart = m_pMinBox->m_rtBtn;
+ pTheme->DrawBackground(&param);
+ }
+ }
+#endif
+ return FWL_ERR_Succeeded;
+}
+FWL_FORMSIZE CFWL_FormImp::GetFormSize()
+{
+ return m_eFormSize;
+}
+FWL_ERR CFWL_FormImp::SetFormSize(FWL_FORMSIZE eFormSize)
+{
+ m_eFormSize = eFormSize;
+ return FWL_ERR_Succeeded;
+}
+IFWL_Widget* CFWL_FormImp::DoModal()
+{
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_VALUE_IF_FAIL(pThread, NULL);
+ IFWL_NoteDriver *pDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(pDriver, NULL);
+ m_pNoteLoop = FX_NEW CFWL_NoteLoop(this);
+ pDriver->PushNoteLoop((IFWL_NoteLoop*)m_pNoteLoop);
+ m_bDoModalFlag = TRUE;
+ SetStates(FWL_WGTSTATE_Invisible, FALSE);
+ pDriver->Run();
+#if (_FX_OS_==_FX_MACOSX_)
+#else
+ pDriver->PopNoteLoop();
+#endif
+ delete m_pNoteLoop;
+ m_pNoteLoop = NULL;
+ return NULL;
+}
+IFWL_Widget* CFWL_FormImp::DoModal(FX_DWORD &dwCommandID)
+{
+ return DoModal();
+}
+FWL_ERR CFWL_FormImp::EndDoModal()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pNoteLoop, FWL_ERR_Indefinite);
+ m_bDoModalFlag = FALSE;
+#if (_FX_OS_==_FX_MACOSX_)
+ m_pNoteLoop->EndModalLoop();
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_VALUE_IF_FAIL(pThread, NULL);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(pDriver, NULL);
+ pDriver->PopNoteLoop();
+ SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ return FWL_ERR_Succeeded;
+#else
+ SetStates(FWL_WGTSTATE_Invisible, TRUE);
+ return m_pNoteLoop->EndModalLoop();
+#endif
+}
+FWL_ERR CFWL_FormImp::SetBorderRegion(CFX_Path *pPath)
+{
+ return FWL_ERR_Succeeded;
+}
+void CFWL_FormImp::DrawBackground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme)
+{
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_FRM_Background;
+ param.m_pGraphics = pGraphics;
+ param.m_rtPart = m_rtRelative;
+ param.m_rtPart.Deflate(m_fCYBorder, m_rtCaption.height, m_fCYBorder, m_fCXBorder);
+ pTheme->DrawBackground(&param);
+}
+CFWL_WidgetImp* CFWL_FormImp::GetSubFocus()
+{
+ return m_pSubFocus;
+}
+void CFWL_FormImp::SetSubFocus(CFWL_WidgetImp *pWidget)
+{
+ m_pSubFocus = pWidget;
+}
+CFX_MapAccelerators& CFWL_FormImp::GetAccelerator()
+{
+ return m_mapAccelerators;
+}
+void CFWL_FormImp::SetAccelerator(CFX_MapAccelerators *pAccelerators)
+{
+ _FWL_RETURN_IF_FAIL(pAccelerators);
+ m_mapAccelerators.RemoveAll();
+ FX_DWORD vrKey, rValue;
+ FX_POSITION pos = pAccelerators->GetStartPosition();
+ while (pos) {
+ pAccelerators->GetNextAssoc(pos, vrKey, rValue);
+ m_mapAccelerators.SetAt(vrKey, rValue);
+ }
+}
+void CFWL_FormImp::ShowChildWidget(IFWL_Widget *pParent)
+{
+ IFWL_App *pApp = FWL_GetApp();
+ _FWL_RETURN_IF_FAIL(pApp);
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)pApp->GetWidgetMgr();
+ _FWL_RETURN_IF_FAIL(pWidgetMgr);
+ IFWL_Widget *pChild = pWidgetMgr->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
+ while (pChild) {
+ pWidgetMgr->ShowWidget_Native(pChild);
+ ShowChildWidget(pChild);
+ pChild = pWidgetMgr->GetWidget(pChild, FWL_WGTRELATION_NextSibling);
+ }
+}
+void CFWL_FormImp::RemoveSysButtons()
+{
+ m_rtCaption.Reset();
+ if (m_pCloseBox) {
+ delete m_pCloseBox;
+ m_pCloseBox = NULL;
+ }
+ if (m_pMinBox) {
+ delete m_pMinBox;
+ m_pMinBox = NULL;
+ }
+ if (m_pMaxBox) {
+ delete m_pMaxBox;
+ m_pMaxBox = NULL;
+ }
+ if (m_pCaptionBox) {
+ delete m_pCaptionBox;
+ m_pCaptionBox = NULL;
+ }
+}
+void CFWL_FormImp::CalcContentRect(CFX_RectF &rtContent)
+{
+#ifdef FWL_UseMacSystemBorder
+ rtContent = m_rtRelative;
+#else
+ GetEdgeRect(rtContent);
+ if (HasEdge()) {
+ FX_FLOAT fEdge = GetEdgeWidth();
+ rtContent.Deflate(fEdge, fEdge);
+ }
+#endif
+}
+CFWL_SysBtn* CFWL_FormImp::GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pCloseBox && m_pCloseBox->m_rtBtn.Contains(fx, fy)) {
+ return m_pCloseBox;
+ }
+ if (m_pMaxBox && m_pMaxBox->m_rtBtn.Contains(fx, fy)) {
+ return m_pMaxBox;
+ }
+ if (m_pMinBox && m_pMinBox->m_rtBtn.Contains(fx, fy)) {
+ return m_pMinBox;
+ }
+ if (m_pCaptionBox && m_pCaptionBox->m_rtBtn.Contains(fx, fy)) {
+ return m_pCaptionBox;
+ }
+ return NULL;
+}
+CFWL_SysBtn* CFWL_FormImp::GetSysBtnByState(FX_DWORD dwState)
+{
+ if (m_pCloseBox && (m_pCloseBox->m_dwState & dwState)) {
+ return m_pCloseBox;
+ }
+ if (m_pMaxBox && (m_pMaxBox->m_dwState & dwState)) {
+ return m_pMaxBox;
+ }
+ if (m_pMinBox && (m_pMinBox->m_dwState & dwState)) {
+ return m_pMinBox;
+ }
+ if (m_pCaptionBox && (m_pCaptionBox->m_dwState & dwState)) {
+ return m_pCaptionBox;
+ }
+ return NULL;
+}
+CFWL_SysBtn* CFWL_FormImp::GetSysBtnByIndex(FX_INT32 nIndex)
+{
+ if (nIndex < 0) {
+ return NULL;
+ }
+ CFX_PtrArray arrBtn;
+ if (m_pMinBox) {
+ arrBtn.Add(m_pMinBox);
+ }
+ if (m_pMaxBox) {
+ arrBtn.Add(m_pMaxBox);
+ }
+ if (m_pCloseBox) {
+ arrBtn.Add(m_pCloseBox);
+ }
+ return (CFWL_SysBtn*) arrBtn[nIndex];
+}
+FX_INT32 CFWL_FormImp::GetSysBtnIndex(CFWL_SysBtn *pBtn)
+{
+ CFX_PtrArray arrBtn;
+ if (m_pMinBox) {
+ arrBtn.Add(m_pMinBox);
+ }
+ if (m_pMaxBox) {
+ arrBtn.Add(m_pMaxBox);
+ }
+ if (m_pCloseBox) {
+ arrBtn.Add(m_pCloseBox);
+ }
+ return arrBtn.Find(pBtn);
+}
+FX_FLOAT CFWL_FormImp::GetCaptionHeight()
+{
+ FX_DWORD dwCapacity = 0;
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Caption) {
+ dwCapacity = FWL_WGTCAPACITY_FRM_CYCaption;
+ } else if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_NarrowCaption) {
+ dwCapacity = FWL_WGTCAPACITY_FRM_CYNarrowCaption;
+ }
+ if (dwCapacity > 0) {
+ FX_FLOAT *pfCapHeight = (FX_FLOAT*)GetThemeCapacity(dwCapacity);
+ _FWL_RETURN_VALUE_IF_FAIL(pfCapHeight, 0);
+ return *pfCapHeight;
+ }
+ return 0;
+}
+void CFWL_FormImp::DrawCaptionText(CFX_Graphics *pGs, IFWL_ThemeProvider *pTheme, const CFX_Matrix* pMatrix )
+{
+ CFX_WideString wsText;
+ IFWL_DataProvider *pData = m_pProperties->m_pDataProvider;
+ pData->GetCaption(m_pInterface, wsText);
+ if (wsText.IsEmpty()) {
+ return;
+ }
+ CFWL_ThemeText textParam;
+ textParam.m_pWidget = m_pInterface;
+ textParam.m_iPart = FWL_PART_FRM_Caption;
+ textParam.m_dwStates = FWL_PARTSTATE_FRM_Normal;
+ textParam.m_pGraphics = pGs;
+ if (pMatrix) {
+ textParam.m_matrix.Concat(*pMatrix);
+ }
+ CFX_RectF rtText;
+ if (m_bCustomizeLayout) {
+ rtText = m_rtCaptionText;
+ rtText.top -= 5;
+ } else {
+ rtText = m_rtCaption;
+ FX_FLOAT fpos;
+ fpos = HasIcon() ? 29.0f : 13.0f;
+ rtText.left += fpos;
+ }
+ textParam.m_rtPart = rtText;
+ textParam.m_wsText = wsText;
+ textParam.m_dwTTOStyles = FDE_TTOSTYLE_SingleLine | FDE_TTOSTYLE_Ellipsis;
+ textParam.m_iTTOAlign = m_bCustomizeLayout ? FDE_TTOALIGNMENT_Center : FDE_TTOALIGNMENT_CenterLeft;
+ pTheme->DrawText(&textParam);
+}
+void CFWL_FormImp::DrawIconImage(CFX_Graphics *pGs, IFWL_ThemeProvider *pTheme, const CFX_Matrix* pMatrix )
+{
+ IFWL_FormDP *pData = (IFWL_FormDP *)m_pProperties->m_pDataProvider;
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_FRM_Icon;
+ param.m_pGraphics = pGs;
+ param.m_pImage = pData->GetIcon(m_pInterface, FALSE);
+ param.m_rtPart = m_rtIcon;
+ if(pMatrix) {
+ param.m_matrix.Concat(*pMatrix);
+ }
+ pTheme->DrawBackground(&param);
+}
+void CFWL_FormImp::GetEdgeRect(CFX_RectF &rtEdge)
+{
+ rtEdge = m_rtRelative;
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) {
+ FX_FLOAT fCX = GetBorderSize();
+ FX_FLOAT fCY = GetBorderSize(FALSE);
+ rtEdge.Deflate(fCX, m_rtCaption.Height(), fCX, fCY);
+ }
+}
+void CFWL_FormImp::SetWorkAreaRect()
+{
+ m_rtRestore = m_pProperties->m_rtWidget;
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_IF_FAIL(pWidgetMgr);
+ m_bSetMaximize = TRUE;
+ pWidgetMgr->SetMaximize_Native(m_pInterface);
+ Repaint(&m_rtRelative);
+}
+void CFWL_FormImp::SetCursor(FX_FLOAT fx, FX_FLOAT fy)
+{
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ IFWL_AdapterCursorMgr *pCursorMgr = pNative->GetCursorMgr();
+ _FWL_RETURN_IF_FAIL(pCursorMgr);
+ FX_DWORD dwHitTest = HitTest(fx, fy);
+ switch (dwHitTest) {
+ case FWL_WGTHITTEST_Right: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_Right;
+ break;
+ }
+ case FWL_WGTHITTEST_Bottom: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_Bottom;
+ break;
+ }
+ case FWL_WGTHITTEST_Left: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_Left;
+ break;
+ }
+ case FWL_WGTHITTEST_Top: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_Top;
+ break;
+ }
+ case FWL_WGTHITTEST_LeftTop: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_LeftTop;
+ break;
+ }
+ case FWL_WGTHITTEST_LeftBottom: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_LeftBottom;
+ break;
+ }
+ case FWL_WGTHITTEST_RightTop: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_RightTop;
+ break;
+ }
+ case FWL_WGTHITTEST_RightBottom: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ m_eResizeType = FORM_RESIZETYPE_RightBottom;
+ break;
+ }
+ default: {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_Arrow);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ }
+ }
+}
+void CFWL_FormImp::Layout()
+{
+ GetRelativeRect(m_rtRelative);
+#ifndef FWL_UseMacSystemBorder
+ ReSetSysBtn();
+#endif
+ if (m_pContent) {
+ CFX_RectF rtClient;
+ GetClientRect(rtClient);
+ m_pContent->SetWidgetRect(rtClient);
+ m_pContent->Update();
+ }
+}
+void CFWL_FormImp::ReSetSysBtn()
+{
+ m_fCXBorder = *(FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_CXBorder);
+ m_fCYBorder = *(FX_FLOAT*)GetThemeCapacity(FWL_WGTCAPACITY_CYBorder);
+ RemoveSysButtons();
+ IFWL_ThemeProvider *pTheme = m_pProperties->m_pThemeProvider;
+ m_bCustomizeLayout = pTheme->IsCustomizedLayout(m_pInterface);
+ FX_FLOAT fCapHeight = GetCaptionHeight();
+ if (fCapHeight > 0) {
+ m_rtCaption = m_rtRelative;
+ m_rtCaption.height = fCapHeight;
+ }
+ m_iSysBox = 0;
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_CloseBox) {
+ m_pCloseBox = FX_NEW CFWL_SysBtn;
+ if (m_bCustomizeLayout) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_FRM_CloseBox;
+ pTheme->GetPartRect(&param, m_pCloseBox->m_rtBtn);
+ } else {
+ m_pCloseBox->m_rtBtn.Set(m_rtRelative.right() - FWL_SYSBTNMARGIN - FWL_SYSBTNSIZE,
+ FWL_SYSBTNMARGIN,
+ FWL_SYSBTNSIZE,
+ FWL_SYSBTNSIZE);
+ }
+ m_iSysBox ++;
+ }
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_MaximizeBox) {
+ m_pMaxBox = FX_NEW CFWL_SysBtn;
+ if (m_bCustomizeLayout) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_FRM_MaximizeBox;
+ pTheme->GetPartRect(&param, m_pMaxBox->m_rtBtn);
+ } else {
+ if (m_pCloseBox) {
+ m_pMaxBox->m_rtBtn.Set(m_pCloseBox->m_rtBtn.left - FWL_SYSBTNSPAN - FWL_SYSBTNSIZE,
+ m_pCloseBox->m_rtBtn.top,
+ FWL_SYSBTNSIZE,
+ FWL_SYSBTNSIZE);
+ } else {
+ m_pMaxBox->m_rtBtn.Set(m_rtRelative.right() - FWL_SYSBTNMARGIN - FWL_SYSBTNSIZE,
+ FWL_SYSBTNMARGIN,
+ FWL_SYSBTNSIZE,
+ FWL_SYSBTNSIZE);
+ }
+ }
+ m_iSysBox ++;
+ }
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_MinimizeBox) {
+ m_pMinBox = FX_NEW CFWL_SysBtn;
+ if (m_bCustomizeLayout) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_FRM_MinimizeBox;
+ pTheme->GetPartRect(&param, m_pMinBox->m_rtBtn);
+ } else {
+ if (m_pMaxBox) {
+ m_pMinBox->m_rtBtn.Set(m_pMaxBox->m_rtBtn.left - FWL_SYSBTNSPAN - FWL_SYSBTNSIZE,
+ m_pMaxBox->m_rtBtn.top,
+ FWL_SYSBTNSIZE,
+ FWL_SYSBTNSIZE);
+ } else if (m_pCloseBox) {
+ m_pMinBox->m_rtBtn.Set(m_pCloseBox->m_rtBtn.left - FWL_SYSBTNSPAN - FWL_SYSBTNSIZE,
+ m_pCloseBox->m_rtBtn.top,
+ FWL_SYSBTNSIZE,
+ FWL_SYSBTNSIZE);
+ } else {
+ m_pMinBox->m_rtBtn.Set(m_rtRelative.right() - FWL_SYSBTNMARGIN - FWL_SYSBTNSIZE,
+ FWL_SYSBTNMARGIN,
+ FWL_SYSBTNSIZE,
+ FWL_SYSBTNSIZE);
+ }
+ }
+ m_iSysBox ++;
+ }
+ IFWL_FormDP *pData = (IFWL_FormDP *)m_pProperties->m_pDataProvider;
+ if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_Icon && pData->GetIcon(m_pInterface, FALSE)) {
+ if (m_bCustomizeLayout) {
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = FWL_PART_FRM_Icon;
+ CFX_WideString wsText;
+ m_pProperties->m_pDataProvider->GetCaption(m_pInterface, wsText);
+ param.m_pData = &wsText;
+ pTheme->GetPartRect(&param, m_rtIcon);
+ } else {
+ m_rtIcon.Set(5, (m_rtCaption.height - m_fSmallIconSz) / 2, m_fSmallIconSz, m_fSmallIconSz);
+ }
+ }
+ if (m_bCustomizeLayout) {
+ CFWL_ThemeText parma;
+ parma.m_pWidget = m_pInterface;
+ parma.m_iPart = FWL_PART_FRM_HeadText;
+ m_pProperties->m_pDataProvider->GetCaption(m_pInterface, parma.m_wsText);
+ pTheme->GetPartRect(&parma, m_rtCaptionText);
+ }
+}
+void CFWL_FormImp::RegisterForm()
+{
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pDriver);
+ pDriver->RegisterForm(this);
+}
+void CFWL_FormImp::UnRegisterForm()
+{
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pDriver);
+ pDriver->UnRegisterForm(this);
+}
+FX_BOOL CFWL_FormImp::IsDoModal()
+{
+ return m_bDoModalFlag;
+}
+void CFWL_FormImp::SetThemeData()
+{
+ m_fSmallIconSz = *(FX_FLOAT *)GetThemeCapacity(FWL_WGTCAPACITY_FRM_SmallIcon);
+ m_fBigIconSz = *(FX_FLOAT *)GetThemeCapacity(FWL_WGTCAPACITY_FRM_BigIcon);
+}
+FX_BOOL CFWL_FormImp::HasIcon()
+{
+ IFWL_FormDP *pData = (IFWL_FormDP *)m_pProperties->m_pDataProvider;
+ return pData->GetIcon(m_pInterface, FALSE) ? TRUE : FALSE;
+}
+void CFWL_FormImp::UpdateIcon()
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_IF_FAIL(pWidgetMgr);
+ IFWL_FormDP *pData = (IFWL_FormDP *)m_pProperties->m_pDataProvider;
+ CFX_DIBitmap *pBigIcon = pData->GetIcon(m_pInterface, TRUE);
+ CFX_DIBitmap *pSmallIcon = pData->GetIcon(m_pInterface, FALSE);
+ if (pBigIcon && pBigIcon != m_pBigIcon) {
+ m_pBigIcon = pBigIcon;
+ pWidgetMgr->SetWidgetIcon_Native(m_pInterface, m_pBigIcon, TRUE);
+ }
+ if (pSmallIcon && pSmallIcon != m_pSmallIcon) {
+ m_pSmallIcon = pSmallIcon;
+ pWidgetMgr->SetWidgetIcon_Native(m_pInterface, m_pBigIcon, FALSE);
+ }
+}
+void CFWL_FormImp::UpdateCaption()
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_IF_FAIL(pWidgetMgr);
+ IFWL_FormDP *pData = (IFWL_FormDP *)m_pProperties->m_pDataProvider;
+ _FWL_RETURN_IF_FAIL(pData);
+ CFX_WideString text;
+ pData->GetCaption(m_pInterface, text);
+ pWidgetMgr->SetWidgetCaption_Native(m_pInterface, text);
+}
+void CFWL_FormImp::DoWidthLimit(FX_FLOAT &fLeft, FX_FLOAT &fWidth, FX_FLOAT fCurX, FX_FLOAT fSpace, FX_FLOAT fLimitMin, FX_FLOAT fLimitMax, FX_BOOL bLeft)
+{
+ FX_FLOAT fx = fCurX;
+ FX_FLOAT fy = 0 ;
+ TransformTo(NULL, fx, fy);
+ FX_FLOAT fTemp = bLeft ? (fWidth - fx + fLeft + fSpace ) : (fx - fLeft + fSpace);
+ if (fTemp >= fLimitMin && fTemp <= fLimitMax) {
+ fWidth = fTemp;
+ fLeft += bLeft ? (fx - fLeft - fSpace ) : 0;
+ } else {
+ if (fTemp < fLimitMin && fWidth > fLimitMin) {
+ fLeft += bLeft ? (fWidth - fLimitMin) : 0;
+ fWidth = fLimitMin;
+ } else if (fTemp > fLimitMax && fWidth < fLimitMax) {
+ fLeft -= bLeft ? (fLimitMax - fWidth) : 0;
+ fWidth = fLimitMax;
+ }
+ }
+}
+void CFWL_FormImp::DoHeightLimit(FX_FLOAT &fTop, FX_FLOAT &fHeight, FX_FLOAT fCurY, FX_FLOAT fSpace, FX_FLOAT fLimitMin, FX_FLOAT fLimitMax, FX_BOOL bTop)
+{
+ FX_FLOAT fx = 0;
+ FX_FLOAT fy = fCurY ;
+ TransformTo(NULL, fx, fy);
+ FX_FLOAT fTemp = bTop ? (fHeight - fy + fTop + fSpace ) : (fy - fTop + fSpace);
+ if (fTemp >= fLimitMin && fTemp <= fLimitMax) {
+ fHeight = fTemp;
+ fTop += bTop ? (fy - fTop - fSpace ) : 0;
+ } else {
+ if (fTemp < fLimitMin && fHeight > fLimitMin) {
+ fTop += bTop ? (fHeight - fLimitMin) : 0;
+ fHeight = fLimitMin;
+ } else if (fTemp > fLimitMax && fHeight < fLimitMax) {
+ fTop -= bTop ? (fLimitMax - fHeight) : 0;
+ fHeight = fLimitMax;
+ }
+ }
+}
+CFWL_FormDelegate::CFWL_FormDelegate(CFWL_FormImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_FormDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+#ifdef FWL_UseMacSystemBorder
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_INT32 iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_Activate: {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&m_pOwner->m_rtRelative);
+ break;
+ }
+ case FWL_MSGHASH_Deactivate: {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Deactivated;
+ m_pOwner->Repaint(&m_pOwner->m_rtRelative);
+ break;
+ }
+ }
+ return FWL_ERR_Succeeded;
+#else
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ FX_INT32 iRet = 1;
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_Activate: {
+ m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Deactivated;
+ IFWL_NoteThread *pThread = m_pOwner->GetOwnerThread();
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ CFWL_WidgetImp *pSubFocusImp = m_pOwner->GetSubFocus();
+ IFWL_Widget *pSubFocus = pSubFocusImp ? pSubFocusImp->GetInterface() : NULL;
+ if (pSubFocus && pSubFocus != pDriver->GetFocus()) {
+ pDriver->SetFocus(pSubFocus);
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtRelative);
+ break;
+ }
+ case FWL_MSGHASH_Deactivate: {
+ m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Deactivated;
+ IFWL_NoteThread *pThread = m_pOwner->GetOwnerThread();
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ CFWL_WidgetImp *pSubFocusImp = m_pOwner->GetSubFocus();
+ IFWL_Widget *pSubFocus = pSubFocusImp ? pSubFocusImp->GetInterface() : NULL;
+ if (pSubFocus) {
+ if (pSubFocus == pDriver->GetFocus()) {
+ pDriver->SetFocus(NULL);
+ } else if (pSubFocus->GetStates() & FWL_WGTSTATE_Focused) {
+ CFWL_MsgKillFocus ms;
+ IFWL_WidgetDelegate *pDelegate = pSubFocus->SetDelegate(NULL);
+ if (pDelegate) {
+ pDelegate->OnProcessMessage(&ms);
+ }
+ }
+ }
+ m_pOwner->Repaint(&m_pOwner->m_rtRelative);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ switch (pMsg->m_dwCmd) {
+ case FWL_MSGMOUSECMD_LButtonDown: {
+ OnLButtonDown(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonUp: {
+ OnLButtonUp(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseMove: {
+ OnMouseMove(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseHover: {
+ OnMouseHover(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_MouseLeave: {
+ OnMouseLeave(pMsg);
+ break;
+ }
+ case FWL_MSGMOUSECMD_LButtonDblClk: {
+ OnLButtonDblClk(pMsg);
+ break;
+ }
+ }
+ break;
+ }
+ case FWL_MSGHASH_Size: {
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, 0);
+ pWidgetMgr->AddRedrawCounts(m_pOwner->m_pInterface);
+ if (!m_pOwner->m_bSetMaximize) {
+ break;
+ }
+ m_pOwner->m_bSetMaximize = FALSE;
+ CFWL_MsgSize *pMsg = (CFWL_MsgSize*)pMessage;
+ CFX_RectF rt;
+ pWidgetMgr->GetWidgetRect_Native(m_pOwner->m_pInterface, rt);
+ m_pOwner->m_pProperties->m_rtWidget.left = rt.left;
+ m_pOwner->m_pProperties->m_rtWidget.top = rt.top;
+ m_pOwner->m_pProperties->m_rtWidget.width = (FX_FLOAT)pMsg->m_iWidth;
+ m_pOwner->m_pProperties->m_rtWidget.height = (FX_FLOAT)pMsg->m_iHeight;
+ m_pOwner->Update();
+ break;
+ }
+ case FWL_MSGHASH_WindowMove: {
+ OnWindowMove((CFWL_MsgWindowMove* )pMessage);
+ break;
+ }
+ case FWL_MSGHASH_Close: {
+ OnClose((CFWL_MsgClose* )pMessage);
+ break;
+ }
+ default: {
+ iRet = 0;
+ }
+ }
+ return iRet;
+#endif
+}
+FWL_ERR CFWL_FormDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pEvent, FWL_ERR_Indefinite);
+ if (pEvent->GetClassID() == FWL_EVTHASH_Close && pEvent->m_pSrcTarget == m_pOwner->m_pInterface) {
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_FormDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
+void CFWL_FormDelegate::OnLButtonDown(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->SetGrab(TRUE);
+ m_pOwner->m_bLButtonDown = TRUE;
+ m_pOwner->m_eResizeType = FORM_RESIZETYPE_None;
+ CFWL_SysBtn *pPressBtn = m_pOwner->GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->m_iCaptureBtn = m_pOwner->GetSysBtnIndex(pPressBtn);
+ CFX_RectF rtCap;
+ rtCap.Set(m_pOwner->m_rtCaption.left + m_pOwner->m_fCYBorder,
+ m_pOwner->m_rtCaption.top + m_pOwner->m_fCXBorder,
+ m_pOwner->m_rtCaption.width - FWL_SYSBTNSIZE * m_pOwner->m_iSysBox - 2 * m_pOwner->m_fCYBorder,
+ m_pOwner->m_rtCaption.height - m_pOwner->m_fCXBorder);
+ if (pPressBtn) {
+ pPressBtn->SetPressed();
+ m_pOwner->Repaint(&pPressBtn->m_rtBtn);
+ } else if (rtCap.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_eResizeType = FORM_RESIZETYPE_Cap;
+ } else if ((m_pOwner->m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) &&
+ (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize) &&
+ !m_pOwner->m_bMaximized) {
+ m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
+ }
+ m_pOwner->m_InfoStart.m_ptStart.Set(pMsg->m_fx, pMsg->m_fy);
+ m_pOwner->m_InfoStart.m_szStart.Set(m_pOwner->m_pProperties->m_rtWidget.width, m_pOwner->m_pProperties->m_rtWidget.height);
+}
+void CFWL_FormDelegate::OnLButtonUp(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->SetGrab(FALSE);
+ m_pOwner->m_bLButtonDown = FALSE;
+ CFWL_SysBtn *pPointBtn = m_pOwner->GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy);
+ CFWL_SysBtn *pPressedBtn = m_pOwner->GetSysBtnByIndex(m_pOwner->m_iCaptureBtn);
+ if (!pPressedBtn || pPointBtn != pPressedBtn) {
+ return;
+ }
+ if (pPressedBtn == m_pOwner->GetSysBtnByState(FWL_SYSBUTTONSTATE_Pressed)) {
+ pPressedBtn->SetNormal();
+ }
+ if (pPressedBtn == m_pOwner->m_pMaxBox) {
+ if (m_pOwner->m_bMaximized) {
+ m_pOwner->SetWidgetRect(m_pOwner->m_rtRestore);
+ m_pOwner->Update();
+ m_pOwner->Repaint();
+ } else {
+ m_pOwner->SetWorkAreaRect();
+ m_pOwner->Update();
+ }
+ m_pOwner->m_bMaximized = !m_pOwner->m_bMaximized;
+ } else if (pPressedBtn == m_pOwner->m_pMinBox) {
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_IF_FAIL(pWidgetMgr);
+ pWidgetMgr->SetMinimize_Native(m_pOwner->m_pInterface);
+ } else {
+ CFWL_EvtClose eClose;
+ eClose.m_pSrcTarget = m_pOwner->m_pInterface;
+ m_pOwner->DispatchEvent(&eClose);
+ }
+}
+void CFWL_FormDelegate::OnMouseMove(CFWL_MsgMouse *pMsg)
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ if (m_pOwner->m_bLButtonDown) {
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ IFWL_AdapterCursorMgr *pCursorMgr = pNative->GetCursorMgr();
+ _FWL_RETURN_IF_FAIL(pCursorMgr);
+ CFWL_SysBtn *pPressedBtn = m_pOwner->GetSysBtnByIndex(m_pOwner->m_iCaptureBtn);
+ FX_FLOAT fTop, fLeft, fWidth, fHeight;
+ fTop = m_pOwner->m_pProperties->m_rtWidget.top;
+ fLeft = m_pOwner->m_pProperties->m_rtWidget.left;
+ fWidth = m_pOwner->m_pProperties->m_rtWidget.width;
+ fHeight = m_pOwner->m_pProperties->m_rtWidget.height;
+ FX_FLOAT fWidthMax, fWidthMin, fHeightMax, fHeightMin;
+ if (m_pOwner->m_pContent) {
+ m_pOwner->GetContent()->GetMaxSize(fWidthMax, fHeightMax);
+ m_pOwner->GetContent()->GetMinSize(fWidthMin, fHeightMin);
+ } else {
+ fWidthMax = fHeightMax = 1024 * 4;
+ fWidthMin = fHeightMin = 0;
+ }
+ FX_BOOL bWidthlimit = (fWidthMin != 0 || fWidthMax != 0);
+ FX_BOOL bHeightlimit = (fHeightMin != 0 || fHeightMax != 0);
+ FX_BOOL bSizelimit = bWidthlimit || bHeightlimit;
+ if (fWidthMax != 0 || fHeightMax != 0 || fWidthMin != 0 || fHeightMin != 0) {
+ bSizelimit = TRUE;
+ }
+ if (pPressedBtn) {
+ if (!pPressedBtn->m_rtBtn.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ pPressedBtn->SetNormal();
+ } else {
+ pPressedBtn->SetPressed();
+ }
+ m_pOwner->Repaint(&pPressedBtn->m_rtBtn);
+ return;
+ } else if (m_pOwner->m_bMaximized) {
+ return;
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Cap) {
+ m_pOwner->m_pProperties->m_rtWidget.Offset(pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x, pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y);
+ pWidgetMgr->SetWidgetPosition_Native(m_pOwner->m_pInterface,
+ m_pOwner->m_pProperties->m_rtWidget.left,
+ m_pOwner->m_pProperties->m_rtWidget.top);
+ return;
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Right) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bWidthlimit) {
+ fWidth += pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x;
+ m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
+ } else {
+ m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx, m_pOwner->m_InfoStart.m_szStart.x - m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin, fWidthMax, FALSE);
+ }
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Left) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeWE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bWidthlimit) {
+ fLeft -= m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
+ fWidth += m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
+ } else {
+ m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx, m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin, fWidthMax, TRUE);
+ }
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Bottom) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bHeightlimit) {
+ fHeight += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
+ } else {
+ m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy, m_pOwner->m_InfoStart.m_szStart.y - m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin, fHeightMax, FALSE);
+ }
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_Top) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNS);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bHeightlimit) {
+ fTop += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ fHeight -= pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ } else {
+ m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy, m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin, fHeightMax, TRUE);
+ }
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_LeftTop) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bSizelimit) {
+ fLeft -= m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
+ fTop += pMsg->m_fy - m_pOwner-> m_InfoStart.m_ptStart.y;
+ fWidth += m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
+ fHeight -= pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
+ m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
+ } else {
+ m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx, m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin, fWidthMax, TRUE);
+ m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy, m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin, fHeightMax, TRUE);
+ }
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_LeftBottom) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bSizelimit) {
+ fLeft -= m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
+ fWidth += m_pOwner->m_InfoStart.m_ptStart.x - pMsg->m_fx;
+ fHeight += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
+ m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
+ } else {
+ m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx, m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin, fWidthMax, TRUE);
+ m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy, m_pOwner->m_InfoStart.m_szStart.y - m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin, fHeightMax, FALSE);
+ }
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_RightTop) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNESW);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bSizelimit) {
+ fTop += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ fWidth += pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x;
+ fHeight -= pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
+ m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
+ } else {
+ m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx, m_pOwner->m_InfoStart.m_szStart.x - m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin, fWidthMax, FALSE);
+ m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy, m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin, fHeightMax, TRUE);
+ }
+ } else if (m_pOwner->m_eResizeType == FORM_RESIZETYPE_RightBottom) {
+ FWL_HCURSOR hCursor = pCursorMgr->GetSystemCursor(FWL_CURSORTYPE_SizeNWSE);
+ pCursorMgr->SetCursor(hCursor);
+ pCursorMgr->ShowCursor(TRUE);
+ if (!bSizelimit) {
+ fWidth += pMsg->m_fx - m_pOwner->m_InfoStart.m_ptStart.x;
+ fHeight += pMsg->m_fy - m_pOwner->m_InfoStart.m_ptStart.y;
+ m_pOwner->m_InfoStart.m_ptStart.x = pMsg->m_fx;
+ m_pOwner->m_InfoStart.m_ptStart.y = pMsg->m_fy;
+ } else {
+ m_pOwner->DoWidthLimit(fLeft, fWidth, pMsg->m_fx, m_pOwner->m_InfoStart.m_szStart.x - m_pOwner->m_InfoStart.m_ptStart.x, fWidthMin, fWidthMax, FALSE);
+ m_pOwner->DoHeightLimit(fTop, fHeight, pMsg->m_fy, m_pOwner->m_InfoStart.m_szStart.y - m_pOwner->m_InfoStart.m_ptStart.y, fHeightMin, fHeightMax, FALSE);
+ }
+ }
+ if (m_pOwner->m_pContent) {
+ }
+ CFX_RectF rtForm;
+ rtForm.Set(fLeft, fTop, fWidth, fHeight);
+#if (_FX_OS_==_FX_MACOSX_)
+ m_pOwner->m_pProperties->m_rtWidget = rtForm;
+ m_pOwner->Update();
+ m_pOwner->SetWidgetRect(rtForm);
+#else
+ m_pOwner->SetWidgetRect(rtForm);
+ m_pOwner->Update();
+#endif
+ return;
+ }
+ if ((m_pOwner->m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border) &&
+ (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize) &&
+ !m_pOwner->m_bMaximized) {
+ m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
+ }
+ CFX_RectF rtInvalidate;
+ rtInvalidate.Reset();
+ CFWL_SysBtn *pPointBtn = m_pOwner->GetSysBtnAtPoint(pMsg->m_fx, pMsg->m_fy);
+ CFWL_SysBtn *pOldHover = m_pOwner->GetSysBtnByState(FWL_SYSBUTTONSTATE_Hover);
+#if (_FX_OS_==_FX_MACOSX_)
+ {
+ if (pOldHover && pPointBtn != pOldHover) {
+ pOldHover->SetNormal();
+ }
+ if (pPointBtn && pPointBtn != pOldHover) {
+ pPointBtn->SetHover();
+ }
+ if (m_pOwner->m_pCloseBox) {
+ rtInvalidate = m_pOwner->m_pCloseBox->m_rtBtn;
+ }
+ if (m_pOwner->m_pMaxBox) {
+ if (rtInvalidate.IsEmpty()) {
+ rtInvalidate = m_pOwner->m_pMaxBox->m_rtBtn;
+ } else {
+ rtInvalidate.Union(m_pOwner->m_pMaxBox->m_rtBtn);
+ }
+ }
+ if (m_pOwner->m_pMinBox) {
+ if (rtInvalidate.IsEmpty()) {
+ rtInvalidate = m_pOwner->m_pMinBox->m_rtBtn;
+ } else {
+ rtInvalidate.Union(m_pOwner->m_pMinBox->m_rtBtn);
+ }
+ }
+ if (!rtInvalidate.IsEmpty() && rtInvalidate.Contains(pMsg->m_fx, pMsg->m_fy)) {
+ m_pOwner->m_bMouseIn = TRUE;
+ }
+ }
+#else
+ {
+ if (pOldHover && pPointBtn != pOldHover) {
+ pOldHover->SetNormal();
+ rtInvalidate = pOldHover->m_rtBtn;
+ }
+ if (pPointBtn && pPointBtn != pOldHover) {
+ pPointBtn->SetHover();
+ if (rtInvalidate.IsEmpty()) {
+ rtInvalidate = pPointBtn->m_rtBtn;
+ } else {
+ rtInvalidate.Union(pPointBtn->m_rtBtn);
+ }
+ }
+ }
+#endif
+ if (!rtInvalidate.IsEmpty()) {
+ m_pOwner->Repaint(&rtInvalidate);
+ }
+}
+void CFWL_FormDelegate::OnMouseHover(CFWL_MsgMouse *pMsg)
+{
+ m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
+}
+void CFWL_FormDelegate::OnMouseLeave(CFWL_MsgMouse *pMsg)
+{
+ CFWL_SysBtn *pHover = m_pOwner->GetSysBtnByState(FWL_SYSBUTTONSTATE_Hover);
+ if (pHover) {
+ pHover->SetNormal();
+ m_pOwner->Repaint(&pHover->m_rtBtn);
+ }
+ if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseLeave && !m_pOwner->m_bLButtonDown) {
+ m_pOwner->SetCursor(pMsg->m_fx, pMsg->m_fy);
+ }
+}
+void CFWL_FormDelegate::OnLButtonDblClk(CFWL_MsgMouse *pMsg)
+{
+ if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_FRM_Resize) && m_pOwner->HitTest(pMsg->m_fx, pMsg->m_fy) == FWL_WGTHITTEST_Titlebar) {
+ if (m_pOwner->m_bMaximized) {
+ m_pOwner->SetWidgetRect(m_pOwner->m_rtRestore);
+ } else {
+ m_pOwner->SetWorkAreaRect();
+ }
+ m_pOwner->Update();
+ m_pOwner->m_bMaximized = !m_pOwner->m_bMaximized;
+ }
+}
+void CFWL_FormDelegate::OnWindowMove(CFWL_MsgWindowMove *pMsg)
+{
+ m_pOwner->m_pProperties->m_rtWidget.left = pMsg->m_fx;
+ m_pOwner->m_pProperties->m_rtWidget.top = pMsg->m_fy;
+}
+void CFWL_FormDelegate::OnClose(CFWL_MsgClose *pMsg)
+{
+ CFWL_EvtClose eClose;
+ eClose.m_pSrcTarget = m_pOwner->m_pInterface;
+ m_pOwner->DispatchEvent(&eClose);
+}
+FWL_ERR FWL_Accelerator_SetForm(IFWL_Form *pFrom, CFX_MapAccelerators *pMapAccel)
+{
+ CFWL_FormImp *pImp = (CFWL_FormImp*)((IFWL_TargetData*)pFrom)->GetData();
+ _FWL_RETURN_VALUE_IF_FAIL(pImp, FWL_ERR_Indefinite);
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fwl/src/core/fwl_gridimp.cpp b/xfa/src/fwl/src/core/fwl_gridimp.cpp
new file mode 100644
index 0000000000..18ade073a4
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_gridimp.cpp
@@ -0,0 +1,1359 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_widgetimp.h"
+#include "include/fwl_contentimp.h"
+#include "include/fwl_gridimp.h"
+IFWL_Grid* IFWL_Grid::Create()
+{
+ return new IFWL_Grid;
+}
+FWL_ERR IFWL_Grid::Initialize()
+{
+ m_pData = FX_NEW CFWL_GridImp;
+ ((CFWL_GridImp*)m_pData)->SetInterface(this);
+ return ((CFWL_GridImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Grid::Initialize(CFWL_WidgetImpProperties &properties)
+{
+ m_pData = FX_NEW CFWL_GridImp(properties);
+ ((CFWL_GridImp*)m_pData)->SetInterface(this);
+ return ((CFWL_GridImp*)m_pData)->Initialize();
+}
+FWL_HGRIDCOLROW IFWL_Grid::InsertColRow(FX_BOOL bColumn, FX_INT32 nIndex )
+{
+ return ((CFWL_GridImp*)m_pData)->InsertColRow(bColumn, nIndex);
+}
+FX_INT32 IFWL_Grid::CountColRows(FX_BOOL bColumn)
+{
+ return ((CFWL_GridImp*)m_pData)->CountColRows(bColumn);
+}
+FWL_HGRIDCOLROW IFWL_Grid::GetColRow(FX_BOOL bColumn, FX_INT32 nIndex)
+{
+ return ((CFWL_GridImp*)m_pData)->GetColRow(bColumn, nIndex);
+}
+FX_INT32 IFWL_Grid::GetIndex(FWL_HGRIDCOLROW hColRow)
+{
+ return ((CFWL_GridImp*)m_pData)->GetIndex(hColRow);
+}
+FX_FLOAT IFWL_Grid::GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->GetSize(hColRow, eUnit);
+}
+FWL_ERR IFWL_Grid::SetSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->SetSize(hColRow, fSize, eUnit);
+}
+FX_FLOAT IFWL_Grid::GetMinSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->GetMinSize(hColRow, eUnit);
+}
+FWL_ERR IFWL_Grid::SetMinSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->SetMinSize(hColRow, fSize, eUnit);
+}
+FX_FLOAT IFWL_Grid::GetMaxSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->GetMaxSize(hColRow, eUnit);
+}
+FWL_ERR IFWL_Grid::SetMaxSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->SetMaxSize(hColRow, fSize, eUnit);
+}
+FX_BOOL IFWL_Grid::DeleteColRow(FWL_HGRIDCOLROW hColRow)
+{
+ return ((CFWL_GridImp*)m_pData)->DeleteColRow(hColRow);
+}
+FX_BOOL IFWL_Grid::IsColumn(FWL_HGRIDCOLROW hColRow)
+{
+ return ((CFWL_GridImp*)m_pData)->IsColumn(hColRow);
+}
+FX_INT32 IFWL_Grid::GetWidgetPos(IFWL_Widget *pWidget, FX_BOOL bColumn)
+{
+ return ((CFWL_GridImp*)m_pData)->GetWidgetPos(pWidget, bColumn);
+}
+FWL_ERR IFWL_Grid::SetWidgetPos(IFWL_Widget *pWidget, FX_INT32 iPos, FX_BOOL bColumn)
+{
+ return ((CFWL_GridImp*)m_pData)->SetWidgetPos(pWidget, iPos, bColumn);
+}
+FX_INT32 IFWL_Grid::GetWidgetSpan(IFWL_Widget *pWidget, FX_BOOL bColumn)
+{
+ return ((CFWL_GridImp*)m_pData)->GetWidgetSpan(pWidget, bColumn);
+}
+FWL_ERR IFWL_Grid::SetWidgetSpan(IFWL_Widget *pWidget, FX_INT32 iSpan, FX_BOOL bColumn)
+{
+ return ((CFWL_GridImp*)m_pData)->SetWidgetSpan(pWidget, iSpan , bColumn);
+}
+FX_FLOAT IFWL_Grid::GetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->GetWidgetSize(pWidget, eSize, eUnit);
+}
+FWL_ERR IFWL_Grid::SetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)
+{
+ return ((CFWL_GridImp*)m_pData)->SetWidgetSize(pWidget, eSize, fSize, eUit);
+}
+FX_BOOL IFWL_Grid::GetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT &fMargin)
+{
+ return ((CFWL_GridImp*)m_pData)->GetWidgetMargin(pWidget, eMargin, fMargin);
+}
+FWL_ERR IFWL_Grid::SetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT fMargin)
+{
+ return ((CFWL_GridImp*)m_pData)->SetWidgetMargin(pWidget, eMargin, fMargin);
+}
+FWL_ERR IFWL_Grid::RemoveWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin)
+{
+ return ((CFWL_GridImp*)m_pData)->RemoveWidgetMargin(pWidget, eMargin);
+}
+FX_FLOAT IFWL_Grid::GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)
+{
+ return ((CFWL_GridImp*)m_pData)->GetGridSize(eSize, eUnit);
+}
+FWL_ERR IFWL_Grid::SetGridSize(FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)
+{
+ return ((CFWL_GridImp*)m_pData)->SetGridSize(eSize, fSize, eUit);
+}
+IFWL_Grid::IFWL_Grid()
+{
+ m_pData = NULL;
+}
+IFWL_Grid::~IFWL_Grid()
+{
+ if (m_pData) {
+ delete (CFWL_GridImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+CFWL_GridImp::CFWL_GridImp()
+{
+ m_Size[FWL_GRIDSIZE_Width].eUnit = FWL_GRIDUNIT_Auto;
+ m_Size[FWL_GRIDSIZE_Width].fLength = 0;
+ m_Size[FWL_GRIDSIZE_Height].eUnit = FWL_GRIDUNIT_Auto;
+ m_Size[FWL_GRIDSIZE_Height].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MinWidth].eUnit = FWL_GRIDUNIT_Fixed;
+ m_Size[FWL_GRIDSIZE_MinWidth].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MaxWidth].eUnit = FWL_GRIDUNIT_Infinity;
+ m_Size[FWL_GRIDSIZE_MaxWidth].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MinHeight].eUnit = FWL_GRIDUNIT_Fixed;
+ m_Size[FWL_GRIDSIZE_MinHeight].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MaxHeight].eUnit = FWL_GRIDUNIT_Infinity;
+ m_Size[FWL_GRIDSIZE_MaxHeight].fLength = 0;
+}
+CFWL_GridImp::CFWL_GridImp(const CFWL_WidgetImpProperties &properties)
+ : CFWL_ContentImp(properties)
+{
+ m_Size[FWL_GRIDSIZE_Width].eUnit = FWL_GRIDUNIT_Auto;
+ m_Size[FWL_GRIDSIZE_Width].fLength = 0;
+ m_Size[FWL_GRIDSIZE_Height].eUnit = FWL_GRIDUNIT_Auto;
+ m_Size[FWL_GRIDSIZE_Height].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MinWidth].eUnit = FWL_GRIDUNIT_Fixed;
+ m_Size[FWL_GRIDSIZE_MinWidth].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MaxWidth].eUnit = FWL_GRIDUNIT_Infinity;
+ m_Size[FWL_GRIDSIZE_MaxWidth].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MinHeight].eUnit = FWL_GRIDUNIT_Fixed;
+ m_Size[FWL_GRIDSIZE_MinHeight].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MaxHeight].eUnit = FWL_GRIDUNIT_Infinity;
+ m_Size[FWL_GRIDSIZE_MaxHeight].fLength = 0;
+}
+CFWL_GridImp::~CFWL_GridImp()
+{
+ FX_INT32 iCount = m_Columns.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ delete (CFWL_GridColRow *) m_Columns[i];
+ }
+ m_Columns.RemoveAll();
+ iCount = m_Rows.GetSize();
+ for (FX_INT32 j = 0; j < iCount; j++) {
+ delete (CFWL_GridColRow*) m_Rows[j];
+ }
+ m_Rows.RemoveAll();
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget *pWidget;
+ CFWL_GridWidgetInfo *pInfo;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ delete pInfo;
+ }
+ m_mapWidgetInfo.RemoveAll();
+ if (m_pDelegate) {
+ delete (CFWL_GridDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+}
+FWL_ERR CFWL_GridImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_Grid;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_GridImp::GetClassID() const
+{
+ return FWL_CLASSHASH_Grid;
+}
+FWL_ERR CFWL_GridImp::Initialize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_ContentImp::Initialize(), FWL_ERR_Indefinite);
+ m_pDelegate = (IFWL_WidgetDelegate*) FX_NEW CFWL_GridDelegate(this);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::Finalize()
+{
+ _FWL_ERR_CHECK_RETURN_VALUE_IF_FAIL(CFWL_ContentImp::Finalize(), FWL_ERR_Indefinite);
+ if (m_pDelegate) {
+ delete (CFWL_GridDelegate*)m_pDelegate;
+ m_pDelegate = NULL;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ rect.left = 0;
+ rect.top = 0;
+ rect.width = ProcessUnCertainColumns();
+ rect.height = ProcessUnCertainRows();
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::SetWidgetRect(const CFX_RectF &rect)
+{
+ CFWL_WidgetImp::SetWidgetRect(rect);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::Update()
+{
+ if (IsLocked()) {
+ return FWL_ERR_Indefinite;
+ }
+ ProcessColumns(m_pProperties->m_rtWidget.width);
+ ProcessRows(m_pProperties->m_rtWidget.height);
+ SetAllWidgetsRect();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ if ((m_pProperties->m_dwStyleExes & FWL_GRIDSTYLEEXT_ShowGridLines) == 0) {
+ return FWL_ERR_Succeeded;
+ }
+ pGraphics->SaveGraphState();
+ if (pMatrix) {
+ pGraphics->ConcatMatrix((CFX_Matrix*)pMatrix);
+ }
+ {
+ FX_BOOL bDrawLine = FALSE;
+ CFX_Path path;
+ path.Create();
+ FX_INT32 iColumns = m_Columns.GetSize();
+ for (FX_INT32 i = 1; i < iColumns; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];
+ if (!pColRow) {
+ continue;
+ }
+ if (!bDrawLine) {
+ bDrawLine = TRUE;
+ }
+ path.AddLine(pColRow->m_fActualPos,
+ 0,
+ pColRow->m_fActualPos,
+ m_pProperties->m_rtWidget.height);
+ }
+ FX_INT32 iRows = m_Rows.GetSize();
+ for (FX_INT32 j = 1; j < iRows; j++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[j];
+ if (!pColRow) {
+ continue;
+ }
+ if (!bDrawLine) {
+ bDrawLine = TRUE;
+ }
+ path.AddLine(0,
+ pColRow->m_fActualPos,
+ m_pProperties->m_rtWidget.width,
+ pColRow->m_fActualPos);
+ }
+ if (bDrawLine) {
+ CFX_Color cr(0xFFFF0000);
+ pGraphics->SetStrokeColor(&cr);
+ pGraphics->StrokePath(&path);
+ }
+ }
+ pGraphics->RestoreGraphState();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::InsertWidget(IFWL_Widget *pChild, FX_INT32 nIndex )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pChild, FWL_ERR_Indefinite);
+ CFWL_ContentImp::InsertWidget(pChild, nIndex);
+ if (!m_mapWidgetInfo.GetValueAt(pChild)) {
+ CFWL_GridWidgetInfo *pInfo = FX_NEW CFWL_GridWidgetInfo;
+ m_mapWidgetInfo.SetAt(pChild, pInfo);
+ m_Widgets.Add(pChild);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::RemoveWidget(IFWL_Widget* pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FWL_ERR_Indefinite);
+ CFWL_ContentImp::RemoveWidget(pWidget);
+ if (CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)m_mapWidgetInfo.GetValueAt(pWidget)) {
+ m_mapWidgetInfo.RemoveKey(pWidget);
+ delete pInfo;
+ FX_INT32 nIndex = m_Widgets.Find(pWidget);
+ m_Widgets.RemoveAt(nIndex, 1);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_HGRIDCOLROW CFWL_GridImp::InsertColRow(FX_BOOL bColumn, FX_INT32 nIndex )
+{
+ if (bColumn) {
+ if (nIndex < 0 || nIndex > m_Columns.GetSize()) {
+ nIndex = m_Columns.GetSize();
+ }
+ CFWL_GridColRow *pColumn = FX_NEW CFWL_GridColRow;
+ m_Columns.InsertAt(nIndex, pColumn, 1);
+ return (FWL_HGRIDCOLROW)pColumn;
+ }
+ if (nIndex < 0 || nIndex > m_Rows.GetSize()) {
+ nIndex = m_Rows.GetSize();
+ }
+ CFWL_GridColRow *pRow = FX_NEW CFWL_GridColRow;
+ m_Rows.InsertAt(nIndex, pRow, 1);
+ return (FWL_HGRIDCOLROW)pRow;
+}
+FX_INT32 CFWL_GridImp::CountColRows(FX_BOOL bColumn)
+{
+ if (bColumn) {
+ return m_Columns.GetSize();
+ }
+ return m_Rows.GetSize();
+}
+FWL_HGRIDCOLROW CFWL_GridImp::GetColRow(FX_BOOL bColumn, FX_INT32 nIndex)
+{
+ if (bColumn) {
+ if (nIndex < 0 || nIndex >= m_Columns.GetSize()) {
+ return NULL;
+ }
+ return (FWL_HGRIDCOLROW)m_Columns[nIndex];
+ }
+ if (nIndex < 0 || nIndex >= m_Rows.GetSize()) {
+ return NULL;
+ }
+ return (FWL_HGRIDCOLROW)m_Rows[nIndex];
+}
+FX_INT32 CFWL_GridImp::GetIndex(FWL_HGRIDCOLROW hColRow)
+{
+ if (IsColumn(hColRow)) {
+ return m_Columns.Find(hColRow);
+ }
+ return m_Rows.Find(hColRow);
+}
+FX_FLOAT CFWL_GridImp::GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hColRow, -1);
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;
+ eUnit = pColRow->m_Size.eUnit;
+ return pColRow->m_Size.fLength;
+}
+FWL_ERR CFWL_GridImp::SetSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hColRow, FWL_ERR_Indefinite);
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;
+ pColRow->m_Size.eUnit = eUnit;
+ pColRow->m_Size.fLength = fSize;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_GridImp::GetMinSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hColRow, -1);
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;
+ eUnit = pColRow->m_MinSize.eUnit;
+ return pColRow->m_MinSize.fLength;
+}
+FWL_ERR CFWL_GridImp::SetMinSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hColRow, FWL_ERR_Indefinite);
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;
+ pColRow->m_MinSize.eUnit = eUnit;
+ pColRow->m_MinSize.fLength = fSize;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_GridImp::GetMaxSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hColRow, -1);
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;
+ eUnit = pColRow->m_MaxSize.eUnit;
+ return pColRow->m_MaxSize.fLength;
+}
+FWL_ERR CFWL_GridImp::SetMaxSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hColRow, FWL_ERR_Indefinite);
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)hColRow;
+ pColRow->m_MaxSize.eUnit = eUnit;
+ pColRow->m_MaxSize.fLength = fSize;
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_GridImp::DeleteColRow(FWL_HGRIDCOLROW hColRow)
+{
+ FX_INT32 nIndex = m_Columns.Find(hColRow);
+ if (nIndex >= 0) {
+ m_Columns.RemoveAt(nIndex);
+ delete (CFWL_GridColRow*)hColRow;
+ return TRUE;
+ }
+ nIndex = m_Rows.Find(hColRow);
+ if (nIndex >= 0) {
+ delete (CFWL_GridColRow*)hColRow;
+ m_Rows.RemoveAt(nIndex);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_GridImp::IsColumn(FWL_HGRIDCOLROW hColRow)
+{
+ return m_Columns.Find(hColRow) != -1;
+}
+FX_INT32 CFWL_GridImp::GetWidgetPos(IFWL_Widget *pWidget, FX_BOOL bColumn)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ return bColumn ? pInfo->m_iColumn : pInfo->m_iRow;
+ }
+ return -1;
+}
+FWL_ERR CFWL_GridImp::SetWidgetPos(IFWL_Widget *pWidget, FX_INT32 iPos, FX_BOOL bColumn)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ bColumn ? pInfo->m_iColumn = iPos : pInfo->m_iRow = iPos;
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_GridImp::GetWidgetSpan(IFWL_Widget *pWidget, FX_BOOL bColumn)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ return bColumn ? pInfo->m_iColumnSpan : pInfo->m_iRowSpan;
+ }
+ return 0;
+}
+FWL_ERR CFWL_GridImp::SetWidgetSpan(IFWL_Widget *pWidget, FX_INT32 iSpan, FX_BOOL bColumn)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ bColumn ? pInfo->m_iColumnSpan = iSpan : pInfo->m_iRowSpan = iSpan;
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_GridImp::GetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ eUnit = pInfo->m_Size[eSize].eUnit;
+ return pInfo->m_Size[eSize].fLength;
+ }
+ return 0;
+}
+FWL_ERR CFWL_GridImp::SetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ pInfo->m_Size[eSize].fLength = fSize;
+ pInfo->m_Size[eSize].eUnit = eUit;
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_GridImp::GetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT &fMargin)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ fMargin = pInfo->m_Margin[eMargin];
+ return (pInfo->m_dwMarginFlag & (1 << eMargin)) != 0;
+ }
+ return FALSE;
+}
+FWL_ERR CFWL_GridImp::SetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT fMargin)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ pInfo->m_Margin[eMargin] = fMargin;
+ pInfo->m_dwMarginFlag |= (1 << eMargin);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_GridImp::RemoveWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin)
+{
+ CFWL_GridWidgetInfo *pInfo = (CFWL_GridWidgetInfo*)GetWidgetInfo(pWidget);
+ if (pInfo) {
+ pInfo->m_dwMarginFlag &= ~(1 << eMargin);
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_GridImp::GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit)
+{
+ eUnit = m_Size[eSize].eUnit;
+ return m_Size[eSize].fLength;
+}
+FWL_ERR CFWL_GridImp::SetGridSize(FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit)
+{
+ m_Size[eSize].fLength = fSize;
+ m_Size[eSize].eUnit = eUit;
+ return FWL_ERR_Succeeded;
+}
+CFWL_GridWidgetInfo* CFWL_GridImp::GetWidgetInfo(IFWL_Widget* pWidget)
+{
+ return (CFWL_GridWidgetInfo*)m_mapWidgetInfo.GetValueAt(pWidget);
+}
+void CFWL_GridImp::ProcFixedColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_FLOAT fColRowSize, FX_BOOL bColumn)
+{
+ pColRow->m_fActualSize = fColRowSize;
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget *pWidget = NULL;
+ CFWL_GridWidgetInfo *pInfo = NULL;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ if (bColumn) {
+ if (pInfo->m_iColumn == nIndex && pInfo->m_iColumnSpan == 1) {
+ CalcWidgetWidth(pWidget, pInfo, pColRow->m_fActualSize);
+ }
+ } else {
+ if (pInfo->m_iRow == nIndex && pInfo->m_iRowSpan == 1) {
+ CalcWidgetHeigt(pWidget, pInfo, pColRow->m_fActualSize);
+ }
+ }
+ }
+}
+void CFWL_GridImp::ProcAutoColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_BOOL bColumn)
+{
+ _FWL_RETURN_IF_FAIL(pColRow);
+ FX_FLOAT fMaxSize = 0, fWidgetSize = 0;
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget*pWidget = NULL;
+ CFWL_GridWidgetInfo *pInfo = NULL;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ if (!pWidget || !pInfo) {
+ continue;
+ }
+ if (bColumn) {
+ if (pInfo->m_iColumn != nIndex || pInfo->m_iColumnSpan != 1) {
+ continue;
+ }
+ fWidgetSize = CalcAutoColumnWidgetWidth(pWidget, pInfo);
+ if (fMaxSize < fWidgetSize) {
+ fMaxSize = fWidgetSize;
+ }
+ } else {
+ if (pInfo->m_iRow != nIndex || pInfo->m_iRowSpan != 1) {
+ continue;
+ }
+ fWidgetSize = CalcAutoColumnWidgetHeight(pWidget, pInfo);
+ if (fMaxSize < fWidgetSize) {
+ fMaxSize = fWidgetSize;
+ }
+ }
+ }
+ SetColRowActualSize(pColRow, fMaxSize);
+}
+void CFWL_GridImp::ProcScaledColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_FLOAT fColRowSize, FX_BOOL bColumn)
+{
+ if (fColRowSize > 0) {
+ ProcFixedColRow(pColRow, nIndex, fColRowSize, bColumn);
+ }
+}
+void CFWL_GridImp::CalcWidgetWidth(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo, FX_FLOAT fColunmWidth)
+{
+ if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {
+ SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength);
+ } else {
+ FX_FLOAT fWidth = 0;
+ FX_FLOAT fLeftMargin = 0, fRightMargin = 0;
+ FX_BOOL bLeftMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin);
+ FX_BOOL bRightMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin);
+ if (bLeftMargin && bRightMargin) {
+ fWidth = fColunmWidth - fLeftMargin - fRightMargin;
+ } else {
+ CFX_RectF rtAuto;
+ pWidget->GetWidgetRect(rtAuto, TRUE);
+ fWidth = rtAuto.Width();
+ }
+ SetWidgetActualWidth(pInfo, fWidth);
+ }
+}
+void CFWL_GridImp::CalcWidgetHeigt(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo, FX_FLOAT fRowHeigt)
+{
+ if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {
+ SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength);
+ } else {
+ FX_FLOAT fHeight = 0;
+ FX_FLOAT fTopMargin = 0, fBottomMargin = 0;
+ FX_BOOL bTopMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin);
+ FX_BOOL bBottomMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin);
+ if (bTopMargin && bBottomMargin) {
+ fHeight = fRowHeigt - fTopMargin - fBottomMargin;
+ } else {
+ CFX_RectF rtAuto;
+ pWidget->GetWidgetRect(rtAuto, TRUE);
+ fHeight = rtAuto.Height();
+ }
+ SetWidgetActualHeight(pInfo, fHeight);
+ }
+}
+FX_FLOAT CFWL_GridImp::CalcAutoColumnWidgetWidth(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo)
+{
+ FX_FLOAT fLeftMargin = 0, fRightMargin = 0;
+ FX_BOOL bLeftMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin);
+ FX_BOOL bRightMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin);
+ if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {
+ SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength);
+ } else {
+ CFX_RectF rtAuto;
+ pWidget->GetWidgetRect(rtAuto, TRUE);
+ FX_FLOAT fWidth = rtAuto.width;
+ SetWidgetActualWidth(pInfo, fWidth);
+ }
+ FX_FLOAT fTotal = pInfo->m_fActualWidth;
+ if (bLeftMargin) {
+ fTotal += fLeftMargin;
+ }
+ if (bRightMargin) {
+ fTotal += fRightMargin;
+ }
+ return fTotal;
+}
+FX_FLOAT CFWL_GridImp::CalcAutoColumnWidgetHeight(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo)
+{
+ FX_FLOAT fTopMargin = 0, fBottomMargin = 0;
+ FX_BOOL bTopMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin);
+ FX_BOOL bBottomMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin);
+ if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {
+ SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength);
+ } else {
+ CFX_RectF rtAuto;
+ pWidget->GetWidgetRect(rtAuto, TRUE);
+ FX_FLOAT fHeight = rtAuto.height;
+ SetWidgetActualHeight(pInfo, fHeight);
+ }
+ FX_FLOAT fTotal = pInfo->m_fActualHeight;
+ if (bTopMargin) {
+ fTotal += fTopMargin;
+ }
+ if (bBottomMargin) {
+ fTotal += fBottomMargin;
+ }
+ return fTotal;
+}
+FX_FLOAT CFWL_GridImp::ProcessColumns(FX_FLOAT fWidth)
+{
+ if (fWidth <= 0) {
+ return ProcessUnCertainColumns();
+ }
+ FX_INT32 iColumns = m_Columns.GetSize();
+ if (iColumns < 1) {
+ return fWidth;
+ }
+ FX_FLOAT fFixedWidth = 0;
+ FX_FLOAT fAutoWidth = 0;
+ CFX_PtrArray autoColumns;
+ CFX_PtrArray scaledColumns;
+ FX_FLOAT fScaledColumnNum = 0;
+ for (FX_INT32 i = 0; i < iColumns; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];
+ if (!pColRow) {
+ continue;
+ }
+ switch(pColRow->m_Size.eUnit) {
+ case FWL_GRIDUNIT_Fixed: {
+ SetColRowActualSize(pColRow, pColRow->m_Size.fLength);
+ fFixedWidth += pColRow->m_fActualSize;
+ break;
+ }
+ case FWL_GRIDUNIT_Auto: {
+ ProcAutoColRow(pColRow, i, TRUE);
+ autoColumns.Add(pColRow);
+ break;
+ }
+ case FWL_GRIDUNIT_Scaled:
+ default: {
+ fScaledColumnNum += pColRow->m_Size.fLength;
+ scaledColumns.Add(pColRow);
+ SetColRowActualSize(pColRow, 0);
+ }
+ }
+ }
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget *pWidget = NULL;
+ CFWL_GridWidgetInfo *pInfo = NULL;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ if (!pInfo || pInfo->m_iColumnSpan < 2) {
+ continue;
+ }
+ CFX_PtrArray spanAutoColumns;
+ FX_FLOAT fSpanSize = 0;
+ FX_INT32 iAutoColRows = 0;
+ FX_INT32 iScaledColRows = 0;
+ for (FX_INT32 i = 0; i < pInfo->m_iColumnSpan; i++) {
+ CFWL_GridColRow *pColumn = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn + i);
+ if (!pColumn) {
+ break;
+ }
+ fSpanSize += pColumn->m_fActualSize;
+ if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Auto) {
+ iAutoColRows++;
+ spanAutoColumns.Add(pColumn);
+ } else if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {
+ iScaledColRows++;
+ }
+ }
+ if (iAutoColRows < 1) {
+ continue;
+ }
+ FX_FLOAT fWidgetWidth = CalcAutoColumnWidgetWidth(pWidget, pInfo);
+ if (fWidgetWidth > fSpanSize) {
+ if (iScaledColRows > 0) {
+ } else {
+ SetSpanAutoColRowSize(spanAutoColumns, fWidgetWidth - fSpanSize);
+ }
+ }
+ }
+ FX_INT32 iAutoCols = autoColumns.GetSize();
+ for (FX_INT32 k = 0; k < iAutoCols; k++) {
+ fAutoWidth += ((CFWL_GridColRow*)autoColumns[k])->m_fActualSize;
+ }
+ FX_FLOAT fScaledWidth = fWidth - fFixedWidth - fAutoWidth;
+ if (fScaledWidth > 0 && fScaledColumnNum > 0) {
+ SetScaledColRowsSize(scaledColumns, fScaledWidth, fScaledColumnNum);
+ }
+ return fWidth;
+}
+FX_FLOAT CFWL_GridImp::ProcessRows(FX_FLOAT fHeight)
+{
+ if (fHeight <= 0) {
+ return ProcessUnCertainRows();
+ }
+ FX_INT32 iRows = m_Rows.GetSize();
+ if (iRows < 1) {
+ return fHeight;
+ }
+ FX_FLOAT fFixedHeight = 0;
+ FX_FLOAT fAutoHeigt = 0;
+ CFX_PtrArray autoRows;
+ CFX_PtrArray scaledRows;
+ FX_FLOAT fScaledRowNum = 0;
+ for (FX_INT32 i = 0; i < iRows; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[i];
+ if (!pColRow) {
+ continue;
+ }
+ switch(pColRow->m_Size.eUnit) {
+ case FWL_GRIDUNIT_Fixed: {
+ SetColRowActualSize(pColRow, pColRow->m_Size.fLength);
+ fFixedHeight += pColRow->m_fActualSize;
+ break;
+ }
+ case FWL_GRIDUNIT_Auto: {
+ ProcAutoColRow(pColRow, i, FALSE);
+ autoRows.Add(pColRow);
+ break;
+ }
+ case FWL_GRIDUNIT_Scaled:
+ default: {
+ fScaledRowNum += pColRow->m_Size.fLength;
+ scaledRows.Add(pColRow);
+ SetColRowActualSize(pColRow, 0);
+ break;
+ }
+ }
+ }
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget *pWidget = NULL;
+ CFWL_GridWidgetInfo *pInfo = NULL;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ if (!pInfo || pInfo->m_iRowSpan < 2) {
+ continue;
+ }
+ CFX_PtrArray spanAutoRows;
+ FX_FLOAT fSpanSize = 0;
+ FX_INT32 iAutoColRows = 0;
+ FX_INT32 iScaledColRows = 0;
+ for (FX_INT32 i = 0; i < pInfo->m_iRowSpan; i++) {
+ CFWL_GridColRow *pRow = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow + i);
+ if (!pRow) {
+ break;
+ }
+ fSpanSize += pRow->m_fActualSize;
+ if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Auto) {
+ iAutoColRows++;
+ spanAutoRows.Add(pRow);
+ } else if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {
+ iScaledColRows++;
+ }
+ }
+ if (iAutoColRows < 1) {
+ continue;
+ }
+ FX_FLOAT fWidgetHeight = CalcAutoColumnWidgetHeight(pWidget, pInfo);
+ if (fWidgetHeight > fSpanSize) {
+ if (iScaledColRows > 0) {
+ } else {
+ SetSpanAutoColRowSize(spanAutoRows, fWidgetHeight - fSpanSize);
+ }
+ }
+ }
+ FX_INT32 iAutoRows = autoRows.GetSize();
+ for (FX_INT32 k = 0; k < iAutoRows; k++) {
+ fAutoHeigt += ((CFWL_GridColRow*)autoRows[k])->m_fActualSize;
+ }
+ FX_FLOAT fScaledHeight = fHeight - fFixedHeight - fAutoHeigt;
+ if (fScaledHeight > 0 && fScaledRowNum > 0) {
+ SetScaledColRowsSize(scaledRows, fScaledHeight, fScaledRowNum);
+ }
+ return fHeight;
+}
+FX_FLOAT CFWL_GridImp::ProcessUnCertainColumns()
+{
+ FX_INT32 iColumns = m_Columns.GetSize();
+ if (iColumns < 1) {
+ CFWL_GridColRow *pColRow = new CFWL_GridColRow;
+ pColRow->m_Size.eUnit = FWL_GRIDUNIT_Auto;
+ ProcAutoColRow(pColRow, 0, TRUE);
+ FX_FLOAT fWidth = pColRow->m_fActualSize;
+ delete pColRow;
+ return fWidth;
+ }
+ FX_FLOAT fFixedWidth = 0;
+ CFX_PtrArray autoColumns;
+ CFX_PtrArray scaledColumns;
+ FX_FLOAT fScaledColumnNum = 0;
+ FX_FLOAT fScaledMaxPerWidth = 0;
+ for (FX_INT32 i = 0; i < iColumns; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];
+ if (!pColRow) {
+ continue;
+ }
+ switch(pColRow->m_Size.eUnit) {
+ case FWL_GRIDUNIT_Fixed: {
+ SetColRowActualSize(pColRow, pColRow->m_Size.fLength);
+ fFixedWidth += pColRow->m_fActualSize;
+ break;
+ }
+ case FWL_GRIDUNIT_Auto: {
+ ProcAutoColRow(pColRow, i, TRUE);
+ autoColumns.Add(pColRow);
+ break;
+ }
+ case FWL_GRIDUNIT_Scaled:
+ default: {
+ ProcAutoColRow(pColRow, i, TRUE);
+ fScaledColumnNum += pColRow->m_Size.fLength;
+ scaledColumns.Add(pColRow);
+ if (pColRow->m_Size.fLength <= 0) {
+ break;
+ }
+ FX_FLOAT fPerWidth = pColRow->m_fActualSize / pColRow->m_Size.fLength;
+ if (fPerWidth > fScaledMaxPerWidth) {
+ fScaledMaxPerWidth = fPerWidth;
+ }
+ }
+ }
+ }
+ iColumns = scaledColumns.GetSize();
+ for (FX_INT32 j = 0; j < iColumns; j++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)scaledColumns[j];
+ if (!pColRow) {
+ continue;
+ }
+ SetColRowActualSize(pColRow, fScaledMaxPerWidth * pColRow->m_Size.fLength);
+ }
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget *pWidget = NULL;
+ CFWL_GridWidgetInfo *pInfo = NULL;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ if (!pInfo || pInfo->m_iColumnSpan < 2) {
+ continue;
+ }
+ CFX_PtrArray spanAutoColumns;
+ CFX_PtrArray spanScaledColumns;
+ FX_FLOAT fSpanSize = 0;
+ FX_FLOAT fScaledSum = 0;
+ FX_INT32 iAutoColRows = 0;
+ FX_INT32 iScaledColRows = 0;
+ for (FX_INT32 i = 0; i < pInfo->m_iColumnSpan; i++) {
+ CFWL_GridColRow *pColumn = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn + i);
+ if (!pColumn) {
+ break;
+ }
+ fSpanSize += pColumn->m_fActualSize;
+ if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Auto) {
+ iAutoColRows++;
+ spanAutoColumns.Add(pColumn);
+ } else if (pColumn->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {
+ iScaledColRows++;
+ fScaledSum += pColumn->m_Size.fLength;
+ spanScaledColumns.Add(pColumn);
+ }
+ }
+ if (iAutoColRows < 1 && iScaledColRows < 1) {
+ continue;
+ }
+ FX_FLOAT fWidgetWidth = CalcAutoColumnWidgetWidth(pWidget, pInfo);
+ if (fWidgetWidth > fSpanSize) {
+ if (iScaledColRows > 0 ) {
+ if (fScaledSum <= 0) {
+ continue;
+ }
+ SetSpanScaledColRowSize(spanScaledColumns, fWidgetWidth - fSpanSize, fScaledSum);
+ } else {
+ SetSpanAutoColRowSize(spanAutoColumns, fWidgetWidth - fSpanSize);
+ }
+ }
+ }
+ FX_FLOAT fAutoWidth = 0;
+ FX_INT32 iAutoCols = autoColumns.GetSize();
+ for (FX_INT32 m = 0; m < iAutoCols; m++) {
+ fAutoWidth += ((CFWL_GridColRow*)autoColumns[m])->m_fActualSize;
+ }
+ FX_FLOAT fScaledWidth = 0;
+ iColumns = scaledColumns.GetSize();
+ for (FX_INT32 n = 0; n < iColumns; n++) {
+ fScaledWidth += ((CFWL_GridColRow*)scaledColumns[n])->m_fActualSize;
+ }
+ return fFixedWidth + fAutoWidth + fScaledWidth;
+}
+FX_FLOAT CFWL_GridImp::ProcessUnCertainRows()
+{
+ FX_INT32 iRows = m_Rows.GetSize();
+ if (iRows < 1) {
+ CFWL_GridColRow *pColRow = new CFWL_GridColRow;
+ pColRow->m_Size.eUnit = FWL_GRIDUNIT_Auto;
+ ProcAutoColRow(pColRow, 0, FALSE);
+ FX_FLOAT fWidth = pColRow->m_fActualSize;
+ delete pColRow;
+ return fWidth;
+ }
+ FX_FLOAT fFixedHeight = 0;
+ CFX_PtrArray autoRows;
+ CFX_PtrArray scaledRows;
+ FX_FLOAT fScaledRowNum = 0;
+ FX_FLOAT fScaledMaxPerHeight = 0;
+ for (FX_INT32 i = 0; i < iRows; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[i];
+ if (!pColRow) {
+ continue;
+ }
+ switch(pColRow->m_Size.eUnit) {
+ case FWL_GRIDUNIT_Fixed: {
+ SetColRowActualSize(pColRow, pColRow->m_Size.fLength);
+ fFixedHeight += pColRow->m_fActualSize;
+ break;
+ }
+ case FWL_GRIDUNIT_Auto: {
+ ProcAutoColRow(pColRow, i, FALSE);
+ autoRows.Add(pColRow);
+ break;
+ }
+ case FWL_GRIDUNIT_Scaled:
+ default: {
+ ProcAutoColRow(pColRow, i, FALSE);
+ fScaledRowNum += pColRow->m_Size.fLength;
+ scaledRows.Add(pColRow);
+ if (pColRow->m_Size.fLength > 0) {
+ FX_FLOAT fPerHeight = pColRow->m_fActualSize / pColRow->m_Size.fLength;
+ if (fPerHeight > fScaledMaxPerHeight) {
+ fScaledMaxPerHeight = fPerHeight;
+ }
+ }
+ break;
+ }
+ }
+ }
+ iRows = scaledRows.GetSize();
+ for (FX_INT32 j = 0; j < iRows; j++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)scaledRows[j];
+ if (!pColRow) {
+ continue;
+ }
+ SetColRowActualSize(pColRow, fScaledMaxPerHeight * pColRow->m_Size.fLength);
+ }
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget *pWidget = NULL;
+ CFWL_GridWidgetInfo *pInfo = NULL;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ if (pInfo->m_iRowSpan < 2) {
+ continue;
+ }
+ CFX_PtrArray spanAutoRows;
+ CFX_PtrArray spanScaledRows;
+ FX_FLOAT fSpanSize = 0;
+ FX_FLOAT fScaledSum = 0;
+ FX_INT32 iAutoColRows = 0;
+ FX_INT32 iScaledColRows = 0;
+ for (FX_INT32 i = 0; i < pInfo->m_iRowSpan; i++) {
+ CFWL_GridColRow *pRow = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow + i);
+ if (!pRow) {
+ break;
+ }
+ fSpanSize += pRow->m_fActualSize;
+ if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Auto) {
+ iAutoColRows++;
+ spanAutoRows.Add(pRow);
+ } else if (pRow->m_Size.eUnit == FWL_GRIDUNIT_Scaled) {
+ iScaledColRows++;
+ fScaledSum += pRow->m_Size.fLength;
+ spanScaledRows.Add(pRow);
+ }
+ }
+ if (iAutoColRows < 1 && iScaledColRows < 1) {
+ continue;
+ }
+ FX_FLOAT fWidgetHeight = CalcAutoColumnWidgetHeight(pWidget, pInfo);
+ if (fWidgetHeight > fSpanSize) {
+ if (iScaledColRows > 0) {
+ if (fScaledSum <= 0) {
+ continue;
+ }
+ SetSpanScaledColRowSize(spanScaledRows, fWidgetHeight - fSpanSize, fScaledSum);
+ } else {
+ SetSpanAutoColRowSize(spanAutoRows, fWidgetHeight - fSpanSize);
+ }
+ }
+ }
+ FX_FLOAT fAutoHeigt = 0;
+ FX_INT32 iAutoRows = autoRows.GetSize();
+ for (FX_INT32 m = 0; m < iAutoRows; m++) {
+ fAutoHeigt += ((CFWL_GridColRow*)autoRows[m])->m_fActualSize;
+ }
+ FX_FLOAT fScaledHeight = 0;
+ iRows = scaledRows.GetSize();
+ for (FX_INT32 n = 0; n < iRows; n++) {
+ fScaledHeight += ((CFWL_GridColRow*)scaledRows[n])->m_fActualSize;
+ }
+ return fFixedHeight + fAutoHeigt + fScaledHeight;
+}
+FX_BOOL CFWL_GridImp::SetColRowActualSize(CFWL_GridColRow* pColRow, FX_FLOAT fSize, FX_BOOL bSetBeyond )
+{
+ if (pColRow->m_MinSize.eUnit == FWL_GRIDUNIT_Fixed && fSize < pColRow->m_MinSize.fLength) {
+ pColRow->m_fActualSize = pColRow->m_MinSize.fLength;
+ return FALSE;
+ }
+ if (pColRow->m_MaxSize.eUnit == FWL_GRIDUNIT_Fixed && fSize > pColRow->m_MaxSize.fLength) {
+ pColRow->m_fActualSize = pColRow->m_MaxSize.fLength;
+ return FALSE;
+ }
+ if (bSetBeyond) {
+ return TRUE;
+ }
+ pColRow->m_fActualSize = fSize;
+ return TRUE;
+}
+FX_FLOAT CFWL_GridImp::SetWidgetActualWidth(CFWL_GridWidgetInfo* pInfo, FX_FLOAT fWidth)
+{
+ if (pInfo->m_Size[FWL_GRIDSIZE_MinWidth].eUnit == FWL_GRIDUNIT_Fixed &&
+ fWidth < pInfo->m_Size[FWL_GRIDSIZE_MinWidth].fLength) {
+ fWidth = pInfo->m_Size[FWL_GRIDSIZE_MinWidth].fLength;
+ }
+ if (pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].eUnit == FWL_GRIDUNIT_Fixed &&
+ fWidth > pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].fLength) {
+ fWidth = pInfo->m_Size[FWL_GRIDSIZE_MaxWidth].fLength;
+ }
+ pInfo->m_fActualWidth = fWidth;
+ return fWidth;
+}
+FX_FLOAT CFWL_GridImp::SetWidgetActualHeight(CFWL_GridWidgetInfo* pInfo, FX_FLOAT fHeight)
+{
+ if (pInfo->m_Size[FWL_GRIDSIZE_MinHeight].eUnit == FWL_GRIDUNIT_Fixed &&
+ fHeight < pInfo->m_Size[FWL_GRIDSIZE_MinHeight].fLength) {
+ fHeight = pInfo->m_Size[FWL_GRIDSIZE_MinHeight].fLength;
+ }
+ if (pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].eUnit == FWL_GRIDUNIT_Fixed &&
+ fHeight > pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].fLength) {
+ fHeight = pInfo->m_Size[FWL_GRIDSIZE_MaxHeight].fLength;
+ }
+ pInfo->m_fActualHeight = fHeight;
+ return fHeight;
+}
+void CFWL_GridImp::SetAllWidgetsRect()
+{
+ FX_FLOAT fStartLeft = 0;
+ FX_INT32 iColumns = m_Columns.GetSize();
+ for (FX_INT32 i = 0; i < iColumns; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Columns[i];
+ if (!pColRow) {
+ continue;
+ }
+ pColRow->m_fActualPos = fStartLeft;
+ fStartLeft += pColRow->m_fActualSize;
+ }
+ FX_FLOAT fStartTop = 0;
+ FX_INT32 iRows = m_Rows.GetSize();
+ for (FX_INT32 j = 0; j < iRows; j++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)m_Rows[j];
+ if (!pColRow) {
+ continue;
+ }
+ pColRow->m_fActualPos = fStartTop;
+ fStartTop += pColRow->m_fActualSize;
+ }
+ FX_POSITION ps = m_mapWidgetInfo.GetStartPosition();
+ while (ps) {
+ IFWL_Widget *pWidget = NULL;
+ CFWL_GridWidgetInfo *pInfo = NULL;
+ m_mapWidgetInfo.GetNextAssoc(ps, (void*&)pWidget, (void*&)pInfo);
+ if (!pWidget || !pInfo) {
+ continue;
+ }
+ FX_FLOAT fColumnStart = 0;
+ CFWL_GridColRow *pColumn = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn);
+ if (pColumn) {
+ fColumnStart = pColumn->m_fActualPos;
+ }
+ FX_FLOAT fRowStart = 0;
+ CFWL_GridColRow *pRow = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow);
+ if (pRow) {
+ fRowStart = pRow->m_fActualPos;
+ }
+ FX_FLOAT fColumnWidth = 0;
+ if (iColumns > 0) {
+ for (FX_INT32 j = 0; j < pInfo->m_iColumnSpan; j++) {
+ CFWL_GridColRow *pCol = (CFWL_GridColRow*)GetColRow(TRUE, pInfo->m_iColumn + j);
+ if (!pCol) {
+ break;
+ }
+ fColumnWidth += pCol->m_fActualSize;
+ }
+ } else {
+ fColumnWidth = m_pProperties->m_rtWidget.width;
+ }
+ FX_FLOAT fRowHeight = 0;
+ if (iRows > 0) {
+ for (FX_INT32 k = 0; k < pInfo->m_iRowSpan; k++) {
+ CFWL_GridColRow *pR = (CFWL_GridColRow*)GetColRow(FALSE, pInfo->m_iRow + k);
+ if (!pR) {
+ break;
+ }
+ fRowHeight += pR->m_fActualSize;
+ }
+ } else {
+ fRowHeight = m_pProperties->m_rtWidget.height;
+ }
+ FX_FLOAT fLeftMargin = 0, fRightMargin = 0;
+ FX_BOOL bLeftMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Left, fLeftMargin);
+ FX_BOOL bRightMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Right, fRightMargin);
+ FX_FLOAT fTopMargin = 0, fBottomMargin = 0;
+ FX_BOOL bTopMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Top, fTopMargin);
+ FX_BOOL bBottomMargin = GetWidgetMargin(pWidget, FWL_GRIDMARGIN_Bottom, fBottomMargin);
+ FWL_LAYOUTDATA ltd;
+ ltd.fWidth = 0;
+ ltd.fHeight = 0;
+ if (pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {
+ SetWidgetActualWidth(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Width].fLength);
+ ltd.fWidth = pInfo->m_fActualWidth;
+ } else {
+ if (bLeftMargin && bRightMargin) {
+ SetWidgetActualWidth(pInfo, fColumnWidth - fLeftMargin - fRightMargin);
+ ltd.fWidth = pInfo->m_fActualWidth;
+ } else {
+ CFX_RectF rtAuto;
+ pWidget->GetWidgetRect(rtAuto, TRUE);
+ SetWidgetActualWidth(pInfo, rtAuto.width);
+ }
+ }
+ if (pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {
+ SetWidgetActualHeight(pInfo, pInfo->m_Size[FWL_GRIDSIZE_Height].fLength);
+ ltd.fHeight = pInfo->m_fActualHeight;
+ } else {
+ if (bTopMargin && bBottomMargin) {
+ SetWidgetActualHeight(pInfo, fRowHeight - fTopMargin - fBottomMargin);
+ ltd.fHeight = pInfo->m_fActualHeight;
+ } else {
+ CFX_RectF rtAuto;
+ pWidget->GetWidgetRect(rtAuto, TRUE);
+ SetWidgetActualHeight(pInfo, rtAuto.height);
+ }
+ }
+ if (bLeftMargin && bRightMargin && pInfo->m_Size[FWL_GRIDSIZE_Width].eUnit == FWL_GRIDUNIT_Fixed) {
+ fLeftMargin = fColumnStart + fLeftMargin + (fColumnWidth - fLeftMargin - fRightMargin - pInfo->m_fActualWidth) / 2;
+ } else if (bLeftMargin) {
+ fLeftMargin = fColumnStart + fLeftMargin;
+ } else if (bRightMargin) {
+ fLeftMargin = fColumnStart + fColumnWidth - fRightMargin - pInfo->m_fActualWidth;
+ } else {
+ fLeftMargin = fColumnStart;
+ }
+ if (bTopMargin && bBottomMargin && pInfo->m_Size[FWL_GRIDSIZE_Height].eUnit == FWL_GRIDUNIT_Fixed) {
+ fTopMargin = fRowStart + fTopMargin + (fRowHeight - fTopMargin - fBottomMargin - pInfo->m_fActualHeight) / 2;
+ } else if (bTopMargin) {
+ fTopMargin = fRowStart + fTopMargin;
+ } else if (bBottomMargin) {
+ fTopMargin = fRowStart + fRowHeight - fBottomMargin - pInfo->m_fActualHeight;
+ } else {
+ fTopMargin = fRowStart;
+ }
+ CFX_RectF rtWidget, rtOld;
+ rtWidget.Set(fLeftMargin, fTopMargin, pInfo->m_fActualWidth, pInfo->m_fActualHeight);
+ pWidget->GetWidgetRect(rtOld);
+ if (rtWidget == rtOld) {
+ continue;
+ }
+ pWidget->SetWidgetRect(rtWidget);
+ if (rtWidget.width == rtOld.width && rtWidget.height == rtOld.height) {
+ continue;
+ }
+ pWidget->Update();
+ }
+}
+FX_BOOL CFWL_GridImp::IsGrid(IFWL_Widget* pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_Grid;
+}
+void CFWL_GridImp::SetSpanAutoColRowSize(const CFX_PtrArray &spanAutos, FX_FLOAT fTotalSize)
+{
+ FX_INT32 iAutoColRows = spanAutos.GetSize();
+ if (iAutoColRows < 1) {
+ return;
+ }
+ CFX_PtrArray autoNoMinMaxs;
+ FX_FLOAT fAutoPer = fTotalSize / iAutoColRows;
+ for (FX_INT32 j = 0; j < iAutoColRows; j++) {
+ CFWL_GridColRow *pColumn = (CFWL_GridColRow*)spanAutos[j];
+ FX_FLOAT fOrgSize = pColumn->m_fActualSize;
+ if (SetColRowActualSize(pColumn, pColumn->m_fActualSize + fAutoPer, TRUE)) {
+ autoNoMinMaxs.Add(pColumn);
+ } else {
+ fTotalSize -= pColumn->m_fActualSize - fOrgSize;
+ FX_INT32 iNoMinMax = iAutoColRows - (j + 1 - autoNoMinMaxs.GetSize());
+ if (iNoMinMax > 0 && fTotalSize > 0) {
+ fAutoPer = fTotalSize / iNoMinMax;
+ } else {
+ break;
+ }
+ }
+ }
+ FX_INT32 iNormals = autoNoMinMaxs.GetSize();
+ if (fTotalSize > 0) {
+ if (iNormals == iAutoColRows) {
+ fAutoPer = fTotalSize / iNormals;
+ for (FX_INT32 k = 0; k < iNormals; k++) {
+ CFWL_GridColRow *pColumn = (CFWL_GridColRow*)autoNoMinMaxs[k];
+ pColumn->m_fActualSize += fAutoPer;
+ }
+ } else {
+ SetSpanAutoColRowSize(autoNoMinMaxs, fTotalSize);
+ }
+ } else {
+ }
+}
+void CFWL_GridImp::SetSpanScaledColRowSize(const CFX_PtrArray &spanScaleds, FX_FLOAT fTotalSize, FX_FLOAT fTotalScaledNum)
+{
+ FX_INT32 iScaledColRows = spanScaleds.GetSize();
+ if (iScaledColRows < 1) {
+ return;
+ }
+ CFX_PtrArray autoNoMinMaxs;
+ FX_FLOAT fPerSize = fTotalSize / fTotalScaledNum;
+ for (FX_INT32 i = 0; i < iScaledColRows; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)spanScaleds[i];
+ if (SetColRowActualSize(pColRow, pColRow->m_fActualSize + fPerSize * pColRow->m_Size.fLength, TRUE)) {
+ autoNoMinMaxs.Add(pColRow);
+ } else {
+ fTotalSize -= pColRow->m_fActualSize;
+ fTotalScaledNum -= pColRow->m_Size.fLength;
+ FX_INT32 iNoMinMax = iScaledColRows - (i + 1 - autoNoMinMaxs.GetSize());
+ if (iNoMinMax > 0 && fTotalSize > 0) {
+ fPerSize = fTotalSize / fTotalScaledNum;
+ } else {
+ break;
+ }
+ }
+ }
+ FX_INT32 iNormals = autoNoMinMaxs.GetSize();
+ if (fTotalSize > 0) {
+ if (iNormals == iScaledColRows) {
+ fPerSize = fTotalSize / fTotalScaledNum;
+ for (FX_INT32 j = 0; j < iNormals; j++) {
+ CFWL_GridColRow *pColumn = (CFWL_GridColRow*)autoNoMinMaxs[j];
+ pColumn->m_fActualSize += fPerSize * pColumn->m_Size.fLength;
+ }
+ } else {
+ SetSpanScaledColRowSize(autoNoMinMaxs, fTotalSize, fTotalScaledNum);
+ }
+ } else {
+ }
+}
+void CFWL_GridImp::SetScaledColRowsSize(const CFX_PtrArray &spanScaleds, FX_FLOAT fTotalSize, FX_FLOAT fTotalScaledNum)
+{
+ FX_INT32 iScaledColRows = spanScaleds.GetSize();
+ if (iScaledColRows < 1) {
+ return;
+ }
+ CFX_PtrArray autoNoMinMaxs;
+ FX_FLOAT fPerSize = fTotalSize / fTotalScaledNum;
+ for (FX_INT32 i = 0; i < iScaledColRows; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)spanScaleds[i];
+ if (!pColRow) {
+ continue;
+ }
+ FX_FLOAT fSize = fPerSize * pColRow->m_Size.fLength;
+ FX_FLOAT fOrgSize = pColRow->m_fActualSize;
+ if (SetColRowActualSize(pColRow, fSize, TRUE)) {
+ autoNoMinMaxs.Add(pColRow);
+ } else {
+ fTotalSize -= pColRow->m_fActualSize - fOrgSize;
+ fTotalScaledNum -= pColRow->m_Size.fLength;
+ FX_INT32 iNoMinMax = iScaledColRows - (i + 1 - autoNoMinMaxs.GetSize());
+ if (iNoMinMax > 0 && fTotalSize > 0) {
+ fPerSize = fTotalSize / fTotalScaledNum;
+ } else {
+ break;
+ }
+ }
+ }
+ FX_INT32 iNormals = autoNoMinMaxs.GetSize();
+ if (fTotalSize > 0) {
+ if (iNormals == iScaledColRows) {
+ fPerSize = fTotalSize / fTotalScaledNum;
+ for (FX_INT32 i = 0; i < iNormals; i++) {
+ CFWL_GridColRow *pColRow = (CFWL_GridColRow*)autoNoMinMaxs[i];
+ if (!pColRow) {
+ continue;
+ }
+ FX_FLOAT fSize = fPerSize * pColRow->m_Size.fLength;
+ pColRow->m_fActualSize = fSize;
+ }
+ } else {
+ SetScaledColRowsSize(autoNoMinMaxs, fTotalSize, fTotalScaledNum);
+ }
+ } else {
+ }
+}
+CFWL_GridDelegate::CFWL_GridDelegate(CFWL_GridImp *pOwner)
+ : m_pOwner(pOwner)
+{
+}
+FX_INT32 CFWL_GridDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ if (pMessage->GetClassID() != FWL_MSGHASH_Mouse) {
+ return 0;
+ }
+ CFWL_MsgMouse *pMsg = (CFWL_MsgMouse*)pMessage;
+ if (pMsg->m_dwCmd != FWL_MSGMOUSECMD_LButtonDown) {
+ return 0;
+ }
+ return 1;
+}
+FWL_ERR CFWL_GridDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOwner->DrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/src/fwl/src/core/fwl_noteimp.cpp b/xfa/src/fwl/src/core/fwl_noteimp.cpp
new file mode 100644
index 0000000000..40f0c1137d
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_noteimp.cpp
@@ -0,0 +1,1116 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_widgetimp.h"
+#include "include/fwl_widgetmgrimp.h"
+#include "include/fwl_panelimp.h"
+#include "include/fwl_formimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_appimp.h"
+#include "../../src/basewidget/include/fwl_tooltipctrlimp.h"
+CFWL_NoteLoop::CFWL_NoteLoop(CFWL_WidgetImp *pForm )
+ : m_pForm(pForm)
+ , m_bContinueModal(TRUE)
+{
+}
+FX_BOOL CFWL_NoteLoop::PreProcessMessage(CFWL_Message *pMessage)
+{
+ if (!m_pForm) {
+ return FALSE;
+ }
+ return TranslateAccelerator(pMessage);
+}
+FWL_ERR CFWL_NoteLoop::Idle(FX_INT32 count)
+{
+#if (_FX_OS_==_FX_WIN32_DESKTOP_)
+ if (count <= 0)
+#endif
+ {
+ CFWL_EvtIdle ev;
+ IFWL_App *pApp = FWL_GetApp();
+ _FWL_RETURN_VALUE_IF_FAIL(pApp, FWL_ERR_Indefinite);
+ IFWL_NoteDriver *pDriver = pApp->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(pDriver, FWL_ERR_Indefinite);
+ pDriver->SendNote(&ev);
+ }
+ return FWL_ERR_Indefinite;
+}
+CFWL_WidgetImp* CFWL_NoteLoop::GetForm()
+{
+ return m_pForm;
+}
+FX_BOOL CFWL_NoteLoop::ContinueModal()
+{
+ return m_bContinueModal;
+}
+FWL_ERR CFWL_NoteLoop::EndModalLoop()
+{
+ m_bContinueModal = FALSE;
+#if (_FX_OS_==_FX_MACOSX_)
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ IFWL_AdapterWidgetMgr * adapterWidgetMgr = pWidgetMgr->GetAdapterWidgetMgr();
+ adapterWidgetMgr->EndLoop();
+#endif
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_NoteLoop::TranslateAccelerator(CFWL_Message *pMessage)
+{
+ if (pMessage->GetClassID() != FWL_MSGHASH_Key) {
+ return FALSE;
+ }
+ if (((CFWL_MsgKey*)pMessage)->m_dwCmd != FWL_MSGKEYCMD_KeyDown) {
+ return FALSE;
+ }
+ CFWL_MsgKey *pMsgKey = (CFWL_MsgKey*)pMessage;
+ CFX_MapAccelerators &accel = ((CFWL_FormImp*)m_pForm)->GetAccelerator();
+ FX_POSITION pos = accel.GetStartPosition();
+ if (!pos) {
+ return FALSE;
+ }
+ FX_DWORD vrKey, rValue;
+ while (pos) {
+ accel.GetNextAssoc(pos, vrKey, rValue);
+ FX_DWORD dwFlags = (vrKey & 0xFF00) >> 8;
+ FX_DWORD m_dwKeyCode = vrKey & 0x00FF;
+ if (pMsgKey->m_dwFlags == dwFlags && pMsgKey->m_dwKeyCode == m_dwKeyCode) {
+ GenerateCommondEvent(rValue);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FWL_ERR CFWL_NoteLoop::SetMainForm(CFWL_WidgetImp *pForm)
+{
+ m_pForm = pForm;
+ return FWL_ERR_Succeeded;
+}
+void CFWL_NoteLoop::GenerateCommondEvent(FX_DWORD dwCommand)
+{
+ CFWL_EvtMenuCommand ev;
+ ev.m_iCommand = dwCommand;
+ IFWL_NoteThread *pThread = m_pForm->GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ IFWL_NoteDriver *pDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pDriver);
+ pDriver->SendNote(&ev);
+}
+CFWL_NoteDriver::CFWL_NoteDriver()
+ : m_sendEventCalled(0)
+ , m_maxSize(500)
+ , m_bFullScreen(FALSE)
+ , m_pFocus(NULL)
+ , m_pHover(NULL)
+ , m_pGrab(NULL)
+ , m_hook(NULL)
+{
+ m_pNoteLoop = FX_NEW CFWL_NoteLoop;
+ PushNoteLoop((IFWL_NoteLoop*)m_pNoteLoop);
+}
+CFWL_NoteDriver::~CFWL_NoteDriver()
+{
+ if (m_pNoteLoop) {
+ delete m_pNoteLoop;
+ m_pNoteLoop = NULL;
+ }
+ ClearInvalidEventTargets(TRUE);
+}
+FX_BOOL CFWL_NoteDriver::SendNote(CFWL_Note *pNote)
+{
+ if (pNote->IsEvent()) {
+ FX_INT32 iCount = m_eventTargets.GetCount();
+ if (iCount < 1) {
+ return TRUE;
+ }
+ if (FWL_EVTHASH_Mouse == ((CFWL_Event*)pNote)->GetClassID()) {
+ CFWL_EvtMouse * pMouse = (CFWL_EvtMouse*)pNote;
+ if (FWL_MSGMOUSECMD_MouseHover == pMouse->m_dwCmd) {
+ if (m_pNoteLoop->GetForm() && CFWL_ToolTipContainer::getInstance()->ProcessEnter(pMouse, m_pNoteLoop->GetForm()->GetInterface())) {
+ }
+ } else if (FWL_MSGMOUSECMD_MouseLeave == pMouse->m_dwCmd) {
+ if (CFWL_ToolTipContainer::getInstance()->ProcessLeave(pMouse)) {
+ }
+ } else if ((FWL_MSGMOUSECMD_LButtonDown <= pMouse->m_dwCmd) && (FWL_MSGMOUSECMD_MButtonDblClk >= pMouse->m_dwCmd)) {
+ if (CFWL_ToolTipContainer::getInstance()->ProcessLeave(pMouse)) {
+ }
+ }
+ }
+ m_sendEventCalled ++;
+ FX_POSITION pos = m_eventTargets.GetStartPosition();
+ while (pos) {
+ FX_LPVOID key = NULL;
+ CFWL_EventTarget *pEventTarget;
+ m_eventTargets.GetNextAssoc(pos, key, (void*&)pEventTarget);
+ if (pEventTarget && !pEventTarget->IsInvalid()) {
+ pEventTarget->ProcessEvent((CFWL_Event*)pNote);
+ }
+ }
+ m_sendEventCalled --;
+ } else {
+ _FWL_RETURN_VALUE_IF_FAIL(pNote->m_pDstTarget, FALSE);
+ IFWL_WidgetDelegate *pDelegate = pNote->m_pDstTarget->SetDelegate(NULL);
+ if (pDelegate) {
+ pDelegate->OnProcessMessage((CFWL_Message*)pNote);
+ }
+ }
+ return TRUE;
+}
+extern void FWL_PostMessageToMainRoop(CFWL_Message *pMessage);
+FX_BOOL CFWL_NoteDriver::PostMessage(CFWL_Message *pMessage)
+{
+ FWL_PostMessageToMainRoop(pMessage);
+ return TRUE;
+}
+#define FWL_NoteDriver_EventKey 1100
+FWL_ERR CFWL_NoteDriver::RegisterEventTarget(IFWL_Widget *pListener, IFWL_Widget *pEventSource , FX_DWORD dwFilter )
+{
+ FX_DWORD dwkey = (FX_DWORD)(FX_UINTPTR)pListener->GetPrivateData((FX_LPVOID)(FX_UINTPTR)FWL_NoteDriver_EventKey);
+ if (dwkey == 0) {
+ FX_LPVOID random = FX_Random_MT_Start(0);
+ dwkey = rand();
+ FX_Random_MT_Close(random);
+ pListener->SetPrivateData((FX_LPVOID)(FX_UINTPTR)FWL_NoteDriver_EventKey, (FX_LPVOID)(FX_UINTPTR)dwkey, NULL);
+ }
+ CFWL_EventTarget *value = NULL;
+ if (!m_eventTargets.Lookup((void*)(FX_UINTPTR)dwkey, (FX_LPVOID&)value)) {
+ value = FX_NEW CFWL_EventTarget(this, pListener);
+ m_eventTargets.SetAt((void*)(FX_UINTPTR)dwkey, value);
+ }
+ value->SetEventSource(pEventSource, dwFilter);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_NoteDriver::UnregisterEventTarget(IFWL_Widget *pListener)
+{
+ FX_DWORD dwkey = (FX_DWORD)(FX_UINTPTR)pListener->GetPrivateData((FX_LPVOID)(FX_UINTPTR)FWL_NoteDriver_EventKey);
+ if (dwkey == 0) {
+ return FWL_ERR_Indefinite;
+ }
+ CFWL_EventTarget *value = NULL;
+ if (m_eventTargets.Lookup((void*)(FX_UINTPTR)dwkey, (FX_LPVOID&)value)) {
+ value->FlagInvalid();
+ }
+ return FWL_ERR_Succeeded;
+}
+void CFWL_NoteDriver::ClearEventTargets(FX_BOOL bRemoveAll)
+{
+ ClearInvalidEventTargets(bRemoveAll);
+}
+FX_INT32 CFWL_NoteDriver::GetQueueMaxSize() const
+{
+ return m_maxSize;
+}
+FWL_ERR CFWL_NoteDriver::SetQueueMaxSize(const FX_INT32 size)
+{
+ m_maxSize = size;
+ return FWL_ERR_Succeeded;
+}
+IFWL_NoteThread* CFWL_NoteDriver::GetOwnerThread() const
+{
+ return (IFWL_NoteThread *) FWL_GetApp();
+}
+FWL_ERR CFWL_NoteDriver::PushNoteLoop(IFWL_NoteLoop *pNoteLoop)
+{
+ m_noteLoopQueue.Add(pNoteLoop);
+ return FWL_ERR_Succeeded;
+}
+IFWL_NoteLoop* CFWL_NoteDriver::PopNoteLoop()
+{
+ FX_INT32 pos = m_noteLoopQueue.GetSize();
+ _FWL_RETURN_VALUE_IF_FAIL(pos > 0, NULL);
+ IFWL_NoteLoop * p = (IFWL_NoteLoop *) m_noteLoopQueue.GetAt(pos - 1);
+ m_noteLoopQueue.RemoveAt(pos - 1);
+ return p;
+}
+FX_BOOL CFWL_NoteDriver::SetFocus(IFWL_Widget *pFocus, FX_BOOL bNotify )
+{
+ if (m_pFocus == pFocus) {
+ return TRUE;
+ }
+ IFWL_Widget* pPrev = m_pFocus;
+ m_pFocus = pFocus;
+ if (pPrev) {
+ IFWL_Widget *pWidget = FWL_GetWidgetMgr()->GetWidget(m_pFocus, FWL_WGTRELATION_SystemForm);
+ CFWL_FormImp *pForm = pWidget ? (CFWL_FormImp*)((IFWL_TargetData*)pWidget)->GetData() : NULL;
+ CFWL_MsgKillFocus ms;
+ ms.m_pDstTarget = pPrev;
+ ms.m_pSrcTarget = pPrev;
+ if (bNotify) {
+ ms.m_dwExtend = 1;
+ }
+ IFWL_WidgetDelegate *pDelegate = pPrev->SetDelegate(NULL);
+ if (pDelegate) {
+ pDelegate->OnProcessMessage(&ms);
+ }
+ }
+ if (pFocus) {
+ IFWL_Widget *pWidget = FWL_GetWidgetMgr()->GetWidget(pFocus, FWL_WGTRELATION_SystemForm);
+ CFWL_FormImp *pForm = pWidget ? (CFWL_FormImp*)((IFWL_TargetData*)pWidget)->GetData() : NULL;
+ if (pForm) {
+ CFWL_WidgetImp *pNewFocus = (CFWL_WidgetImp*)((IFWL_TargetData*)pFocus)->GetData();
+ pForm->SetSubFocus(pNewFocus);
+ }
+ CFWL_MsgSetFocus ms;
+ ms.m_pDstTarget = pFocus;
+ if (bNotify) {
+ ms.m_dwExtend = 1;
+ }
+ IFWL_WidgetDelegate *pDelegate = pFocus->SetDelegate(NULL);
+ if (pDelegate) {
+ pDelegate->OnProcessMessage(&ms);
+ }
+ }
+ return TRUE;
+}
+FWL_ERR CFWL_NoteDriver::Run()
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, FWL_ERR_Indefinite);
+#if (_FX_OS_==_FX_MACOSX_)
+ IFWL_AdapterWidgetMgr * adapterWidgetMgr = pWidgetMgr->GetAdapterWidgetMgr();
+ CFWL_NoteLoop *pTopLoop = GetTopLoop();
+ if (pTopLoop) {
+ CFWL_WidgetImp *formImp = pTopLoop->GetForm();
+ if (formImp) {
+ IFWL_Widget *pForm = formImp->GetInterface();
+ adapterWidgetMgr->RunLoop(pForm);
+ }
+ }
+#elif (_FX_OS_==_FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_)
+ FX_BOOL bIdle = TRUE;
+ FX_INT32 iIdleCount = 0;
+ CFWL_NoteLoop *pTopLoop = NULL;
+ for (;;) {
+ pTopLoop = GetTopLoop();
+ if (!pTopLoop || !pTopLoop->ContinueModal()) {
+ break;
+ }
+ if (UnqueueMessage(pTopLoop)) {
+ continue;
+ }
+ while (bIdle && !(pWidgetMgr->CheckMessage_Native())) {
+ if (FWL_ERR_Indefinite == pTopLoop->Idle(iIdleCount++)) {
+ bIdle = FALSE;
+ }
+ }
+ do {
+ if (FWL_ERR_Indefinite == pWidgetMgr->DispatchMessage_Native()) {
+ break;
+ }
+ if (pWidgetMgr->IsIdleMessage_Native()) {
+ bIdle = TRUE;
+ iIdleCount = 0;
+ }
+ } while (pWidgetMgr->CheckMessage_Native());
+ }
+#elif (_FX_OS_==_FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_EMBEDDED_)
+ CFWL_NoteLoop *pTopLoop = NULL;
+ for (;;) {
+ pTopLoop = GetTopLoop();
+ if (!pTopLoop || !pTopLoop->ContinueModal()) {
+ break;
+ }
+ if (UnqueueMessage(pTopLoop)) {
+ continue;
+ }
+ if(pWidgetMgr->CheckMessage_Native()) {
+ pWidgetMgr->DispatchMessage_Native();
+ }
+ }
+#endif
+ return FWL_ERR_Succeeded;
+}
+IFWL_Widget* CFWL_NoteDriver::GetFocus()
+{
+ return m_pFocus;
+}
+IFWL_Widget* CFWL_NoteDriver::GetHover()
+{
+ return m_pHover;
+}
+void CFWL_NoteDriver::SetHover(IFWL_Widget *pHover)
+{
+ m_pHover = pHover;
+}
+void CFWL_NoteDriver::SetGrab(IFWL_Widget *pGrab, FX_BOOL bSet)
+{
+ m_pGrab = bSet ? pGrab : NULL;
+}
+void CFWL_NoteDriver::NotifyTargetHide(IFWL_Widget *pNoteTarget)
+{
+ if (m_pFocus == pNoteTarget) {
+ m_pFocus = NULL;
+ }
+ if (m_pHover == pNoteTarget) {
+ m_pHover = NULL;
+ }
+ if (m_pGrab == pNoteTarget) {
+ m_pGrab = NULL;
+ }
+}
+void CFWL_NoteDriver::NotifyTargetDestroy(IFWL_Widget *pNoteTarget)
+{
+ if (m_pFocus == pNoteTarget) {
+ m_pFocus = NULL;
+ }
+ if (m_pHover == pNoteTarget) {
+ m_pHover = NULL;
+ }
+ if (m_pGrab == pNoteTarget) {
+ m_pGrab = NULL;
+ }
+ UnregisterEventTarget(pNoteTarget);
+ FX_INT32 count = m_forms.GetSize();
+ for (FX_INT32 nIndex = 0; nIndex < count; nIndex ++) {
+ CFWL_FormImp *pForm = (CFWL_FormImp*)m_forms[nIndex];
+ if (!pForm) {
+ continue;
+ }
+ CFWL_WidgetImp *pSubFocus = pForm->GetSubFocus();
+ _FWL_RETURN_IF_FAIL(pSubFocus);
+ if (pSubFocus && pSubFocus->GetInterface() == pNoteTarget) {
+ pForm->SetSubFocus(NULL);
+ }
+ }
+}
+void CFWL_NoteDriver::NotifyFullScreenMode(IFWL_Widget *pNoteTarget, FX_BOOL bFullScreen)
+{
+ m_bFullScreen = bFullScreen;
+}
+FWL_ERR CFWL_NoteDriver::RegisterForm(CFWL_WidgetImp *pForm)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pForm, FWL_ERR_Indefinite);
+ if (m_forms.Find(pForm) >= 0) {
+ return FWL_ERR_Indefinite;
+ }
+ m_forms.Add(pForm);
+ if (m_forms.GetSize() == 1) {
+ CFWL_NoteLoop *pLoop = (CFWL_NoteLoop*)m_noteLoopQueue.GetAt(0);
+ _FWL_RETURN_VALUE_IF_FAIL(pLoop, FWL_ERR_Indefinite);
+ pLoop->SetMainForm(pForm);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_NoteDriver::UnRegisterForm(CFWL_WidgetImp *pForm)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pForm, FWL_ERR_Indefinite);
+ FX_INT32 nIndex = m_forms.Find(pForm);
+ if (nIndex < 0) {
+ return FWL_ERR_Indefinite;
+ }
+ m_forms.RemoveAt(nIndex);
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_NoteDriver::QueueMessage(CFWL_Message *pMessage)
+{
+ pMessage->Retain();
+ m_noteQueue.Add(pMessage);
+ return TRUE;
+}
+FX_BOOL CFWL_NoteDriver::UnqueueMessage(CFWL_NoteLoop *pNoteLoop)
+{
+ if (m_noteQueue.GetSize() < 1) {
+ return FALSE;
+ }
+ CFWL_Message *pMessage = (CFWL_Message*)m_noteQueue[0];
+ m_noteQueue.RemoveAt(0);
+ if (!IsValidMessage(pMessage)) {
+ pMessage->Release();
+ return TRUE;
+ }
+ FX_BOOL bHookMessage = FALSE;
+ if (m_hook) {
+ bHookMessage = (*m_hook)(pMessage, m_hookInfo);
+ }
+ if (!bHookMessage && !pNoteLoop->PreProcessMessage(pMessage)) {
+ ProcessMessage(pMessage);
+ }
+ pMessage->Release();
+ return TRUE;
+}
+CFWL_NoteLoop* CFWL_NoteDriver::GetTopLoop()
+{
+ FX_INT32 size = m_noteLoopQueue.GetSize();
+ _FWL_RETURN_VALUE_IF_FAIL(size > 0, NULL);
+ return (CFWL_NoteLoop*)m_noteLoopQueue[size - 1];
+}
+FX_INT32 CFWL_NoteDriver::CountLoop()
+{
+ return m_noteLoopQueue.GetSize();
+}
+void CFWL_NoteDriver::SetHook(FWLMessageHookCallback callback, FX_LPVOID info)
+{
+ m_hook = callback;
+ m_hookInfo = info;
+}
+FX_BOOL CFWL_NoteDriver::ProcessMessage(CFWL_Message *pMessage)
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ IFWL_Widget *pMessageForm = pWidgetMgr->IsFormDisabled() ? pMessage->m_pDstTarget : GetMessageForm(pMessage->m_pDstTarget);
+ _FWL_RETURN_VALUE_IF_FAIL(pMessageForm, FALSE);
+ if (DispatchMessage(pMessage, pMessageForm)) {
+ if (pMessage->GetClassID() == FWL_MSGHASH_Mouse) {
+ MouseSecondary((CFWL_MsgMouse*)pMessage);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_NoteDriver::DispatchMessage(CFWL_Message *pMessage, IFWL_Widget *pMessageForm)
+{
+ FX_BOOL bRet = FALSE;
+ switch (pMessage->GetClassID()) {
+ case FWL_MSGHASH_Activate: {
+ bRet = DoActivate((CFWL_MsgActivate*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_Deactivate: {
+ bRet = DoDeactivate((CFWL_MsgDeactivate*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_SetFocus: {
+ bRet = DoSetFocus((CFWL_MsgSetFocus*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_KillFocus: {
+ bRet = DoKillFocus((CFWL_MsgKillFocus*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ bRet = DoKey((CFWL_MsgKey*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_Mouse: {
+ bRet = DoMouse((CFWL_MsgMouse*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_MouseWheel: {
+ bRet = DoWheel((CFWL_MsgMouseWheel*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_Size: {
+ bRet = DoSize((CFWL_MsgSize*)pMessage);
+ break;
+ }
+ case FWL_MSGHASH_Cursor: {
+ bRet = TRUE;
+ break;
+ }
+ case FWL_MSGHASH_WindowMove: {
+ bRet = DoWindowMove((CFWL_MsgWindowMove*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_DropFiles: {
+ bRet = DoDragFiles((CFWL_MsgDropFiles*)pMessage, pMessageForm);
+ break;
+ }
+ case FWL_MSGHASH_TaskClicked: {
+ bRet = TRUE;
+ break;
+ }
+ case FWL_MSGHASH_Close: {
+ bRet = TRUE;
+ break;
+ }
+ default: {
+ bRet = TRUE;
+ break;
+ }
+ }
+ if (bRet) {
+ IFWL_WidgetDelegate *pDelegate = pMessage->m_pDstTarget->SetDelegate(NULL);
+ if (pDelegate) {
+ pDelegate->OnProcessMessage(pMessage);
+ }
+ }
+ return bRet;
+}
+FX_BOOL CFWL_NoteDriver::DoActivate(CFWL_MsgActivate *pMsg, IFWL_Widget *pMessageForm)
+{
+ if (m_bFullScreen) {
+ return FALSE;
+ }
+ pMsg->m_pDstTarget = pMessageForm;
+ return (pMsg->m_pDstTarget)->GetStates() & FWL_WGTSTATE_Deactivated;
+}
+FX_BOOL CFWL_NoteDriver::DoDeactivate(CFWL_MsgDeactivate *pMsg, IFWL_Widget *pMessageForm)
+{
+ if (m_bFullScreen) {
+ return FALSE;
+ }
+ FX_INT32 iTrackLoop = m_noteLoopQueue.GetSize();
+ _FWL_RETURN_VALUE_IF_FAIL(iTrackLoop > 0, FALSE);
+ if (iTrackLoop == 1) {
+ if (pMessageForm->IsInstance(FX_WSTRC(L"FWL_FORMPROXY"))) {
+ return FALSE;
+ }
+ if (pMsg->m_pSrcTarget && pMsg->m_pSrcTarget->IsInstance(FX_WSTRC(L"FWL_FORMPROXY"))) {
+ return FALSE;
+ }
+ if (pMsg->m_pSrcTarget && pMsg->m_pSrcTarget->GetClassID() == 1111984755) {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ IFWL_Widget *pDst = pMsg->m_pDstTarget;
+ _FWL_RETURN_VALUE_IF_FAIL(pDst, FALSE);
+#if (_FX_OS_==_FX_MACOSX_)
+ if (pDst == pMessageForm && pDst->IsInstance(L"FWL_FORMPROXY")) {
+ return TRUE;
+ }
+#endif
+ return pDst != pMessageForm &&
+ !pDst->IsInstance(FX_WSTRC(L"FWL_FORMPROXY")) &&
+ !pMessageForm->IsInstance(FX_WSTRC(L"FWL_FORMPROXY"));
+}
+FX_BOOL CFWL_NoteDriver::DoSetFocus(CFWL_MsgSetFocus *pMsg, IFWL_Widget *pMessageForm)
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ if (pWidgetMgr->IsFormDisabled()) {
+ m_pFocus = (IFWL_Widget*)pMsg->m_pDstTarget;
+ return TRUE;
+ } else {
+ IFWL_Widget* pWidget = pMsg->m_pDstTarget;
+ CFWL_FormImp *pForm = pWidget ? (CFWL_FormImp*)((IFWL_TargetData*)pWidget)->GetData() : NULL;
+ if(pForm) {
+ CFWL_WidgetImp *pSubFocus = pForm->GetSubFocus();
+ if (pSubFocus && ((pSubFocus->GetStates() & FWL_WGTSTATE_Focused) == 0)) {
+ pMsg->m_pDstTarget = pSubFocus->GetInterface();
+ if(m_pFocus != pMsg->m_pDstTarget) {
+ m_pFocus = pMsg->m_pDstTarget;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_NoteDriver::DoKillFocus(CFWL_MsgKillFocus *pMsg, IFWL_Widget *pMessageForm)
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ if (pWidgetMgr->IsFormDisabled()) {
+ if (m_pFocus == pMsg->m_pDstTarget) {
+ m_pFocus = NULL;
+ }
+ return TRUE;
+ } else {
+ IFWL_Widget* pWidget = pMsg->m_pDstTarget;
+ CFWL_FormImp *pForm = pWidget ? (CFWL_FormImp*)((IFWL_TargetData*)pWidget)->GetData() : NULL;
+ if(pForm) {
+ CFWL_WidgetImp *pSubFocus = pForm->GetSubFocus();
+ if (pSubFocus && (pSubFocus->GetStates() & FWL_WGTSTATE_Focused)) {
+ pMsg->m_pDstTarget = pSubFocus->GetInterface();
+ if (m_pFocus == pMsg->m_pDstTarget) {
+ m_pFocus = NULL;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_NoteDriver::DoKey(CFWL_MsgKey *pMsg, IFWL_Widget *pMessageForm)
+{
+#if(_FX_OS_ != _FX_MACOSX_)
+ if (pMsg->m_dwCmd == FWL_MSGKEYCMD_KeyDown && pMsg->m_dwKeyCode == FWL_VKEY_Tab) {
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ IFWL_Widget *pForm = GetMessageForm(pMsg->m_pDstTarget);
+ IFWL_Widget *pFocus = m_pFocus;
+ if (m_pFocus) {
+ if (pWidgetMgr->GetWidget(m_pFocus, FWL_WGTRELATION_SystemForm) != pForm) {
+ pFocus = NULL;
+ }
+ }
+ FX_BOOL bFind = FALSE;
+ IFWL_Widget *pNextTabStop = pWidgetMgr->nextTab(pForm, pFocus, bFind);
+ if (!pNextTabStop) {
+ bFind = FALSE;
+ pNextTabStop = pWidgetMgr->nextTab(pForm, NULL, bFind);
+ }
+ if (pNextTabStop == pFocus) {
+ return TRUE;
+ }
+ if (pNextTabStop) {
+ SetFocus(pNextTabStop);
+ }
+ return TRUE;
+ }
+#endif
+ if (!m_pFocus) {
+ if (pMsg->m_dwCmd == FWL_MSGKEYCMD_KeyDown && pMsg->m_dwKeyCode == FWL_VKEY_Return) {
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ IFWL_Widget *defButton = pWidgetMgr->GetDefaultButton(pMessageForm);
+ if (defButton) {
+ pMsg->m_pDstTarget = defButton;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ pMsg->m_pDstTarget = m_pFocus;
+ return TRUE;
+}
+FX_BOOL CFWL_NoteDriver::DoMouse(CFWL_MsgMouse *pMsg, IFWL_Widget *pMessageForm)
+{
+ if (pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseLeave ||
+ pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseHover ||
+ pMsg->m_dwCmd == FWL_MSGMOUSECMD_MouseEnter) {
+ return pMsg->m_pDstTarget != NULL;
+ }
+ if (pMsg->m_pDstTarget != pMessageForm) {
+ pMsg->m_pDstTarget->TransformTo(pMessageForm, pMsg->m_fx, pMsg->m_fy);
+ }
+ if (!DoMouseEx(pMsg, pMessageForm)) {
+ pMsg->m_pDstTarget = pMessageForm;
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_NoteDriver::DoWheel(CFWL_MsgMouseWheel *pMsg, IFWL_Widget *pMessageForm)
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, FALSE);
+ IFWL_Widget *pDst = pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy);
+ if (!pDst) {
+ return FALSE;
+ }
+ while (pDst && pDst->GetClassID() == FWL_CLASSHASH_Grid) {
+ pDst = pDst->GetParent();
+ }
+ pMessageForm->TransformTo(pDst, pMsg->m_fx, pMsg->m_fy);
+ pMsg->m_pDstTarget = pDst;
+ return TRUE;
+}
+FX_BOOL CFWL_NoteDriver::DoSize(CFWL_MsgSize *pMsg)
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, FALSE);
+ pWidgetMgr->NotifySizeChanged(pMsg->m_pDstTarget, (FX_FLOAT)pMsg->m_iWidth, (FX_FLOAT)pMsg->m_iHeight);
+ return TRUE;
+}
+FX_BOOL CFWL_NoteDriver::DoWindowMove(CFWL_MsgWindowMove *pMsg, IFWL_Widget *pMessageForm)
+{
+ return pMsg->m_pDstTarget == pMessageForm;
+}
+FX_BOOL CFWL_NoteDriver::DoDragFiles(CFWL_MsgDropFiles *pMsg, IFWL_Widget *pMessageForm)
+{
+ return pMsg->m_pDstTarget == pMessageForm;
+}
+FX_BOOL CFWL_NoteDriver::DoMouseEx(CFWL_MsgMouse *pMsg, IFWL_Widget *pMessageForm)
+{
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, FALSE);
+ IFWL_Widget *pTarget = NULL;
+ if (m_pGrab) {
+ {
+ pTarget = m_pGrab;
+ }
+ }
+ if (!pTarget) {
+ pTarget = pWidgetMgr->GetWidgetAtPoint(pMessageForm, pMsg->m_fx, pMsg->m_fy);
+ while (pTarget && pTarget->GetClassID() == FWL_CLASSHASH_Grid) {
+ pTarget = pTarget->GetParent();
+ }
+ }
+ if (pTarget) {
+ if (pMessageForm != pTarget) {
+ pMessageForm->TransformTo(pTarget, pMsg->m_fx, pMsg->m_fy);
+ }
+ }
+ if (!pTarget) {
+ return FALSE;
+ }
+ pMsg->m_pDstTarget = pTarget;
+ return TRUE;
+}
+void CFWL_NoteDriver::MouseSecondary(CFWL_MsgMouse *pMsg)
+{
+ IFWL_Widget *pTarget = pMsg->m_pDstTarget;
+ if (pTarget == m_pHover) {
+ return;
+ }
+ if (m_pHover) {
+ CFWL_MsgMouse msLeave;
+ msLeave.m_pDstTarget = m_pHover;
+ msLeave.m_fx = pMsg->m_fx;
+ msLeave.m_fy = pMsg->m_fy;
+ pTarget->TransformTo(m_pHover, msLeave.m_fx, msLeave.m_fy);
+ msLeave.m_dwFlags = 0;
+ msLeave.m_dwCmd = FWL_MSGMOUSECMD_MouseLeave;
+ DispatchMessage(&msLeave, NULL);
+ }
+ if (pTarget->GetClassID() == FWL_CLASSHASH_Form) {
+ m_pHover = NULL;
+ return;
+ }
+ m_pHover = pTarget;
+ CFWL_MsgMouse msHover;
+ msHover.m_pDstTarget = pTarget;
+ msHover.m_fx = pMsg->m_fx;
+ msHover.m_fy = pMsg->m_fy;
+ msHover.m_dwFlags = 0;
+ msHover.m_dwCmd = FWL_MSGMOUSECMD_MouseHover;
+ DispatchMessage(&msHover, NULL);
+}
+FX_BOOL CFWL_NoteDriver::IsValidMessage(CFWL_Message *pMessage)
+{
+ if (pMessage->GetClassID() == FWL_MSGHASH_Post) {
+ return TRUE;
+ }
+ FX_INT32 iCount = m_noteLoopQueue.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_NoteLoop *pNoteLoop = (CFWL_NoteLoop*)m_noteLoopQueue[i];
+ CFWL_WidgetImp *pForm = pNoteLoop->GetForm();
+ if (pForm && (pForm->GetInterface() == pMessage->m_pDstTarget)) {
+ return TRUE;
+ }
+ }
+ iCount = m_forms.GetSize();
+ for (FX_INT32 j = 0; j < iCount; j ++) {
+ CFWL_FormImp *pForm = (CFWL_FormImp*)m_forms[j];
+ if (pForm->GetInterface() == pMessage->m_pDstTarget) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+IFWL_Widget* CFWL_NoteDriver::GetMessageForm(IFWL_Widget *pDstTarget)
+{
+ FX_INT32 iTrackLoop = m_noteLoopQueue.GetSize();
+ _FWL_RETURN_VALUE_IF_FAIL(iTrackLoop > 0, NULL);
+ IFWL_Widget *pMessageForm = NULL;
+ if (iTrackLoop > 1) {
+ CFWL_NoteLoop *pNootLoop = (CFWL_NoteLoop*)m_noteLoopQueue[iTrackLoop - 1];
+ pMessageForm = pNootLoop->GetForm()->GetInterface();
+ } else {
+ pMessageForm = (m_forms.Find(pDstTarget) < 0) ? NULL : pDstTarget;
+ }
+ if (!pMessageForm && pDstTarget) {
+ CFWL_WidgetMgr *pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, NULL);
+ pMessageForm = pWidgetMgr->GetWidget(pDstTarget, FWL_WGTRELATION_SystemForm);
+ }
+ return pMessageForm;
+}
+void CFWL_NoteDriver::ClearInvalidEventTargets(FX_BOOL bRemoveAll)
+{
+ FX_POSITION pos = m_eventTargets.GetStartPosition();
+ while (pos) {
+ FX_LPVOID key = NULL;
+ CFWL_EventTarget *pEventTarget = NULL;
+ m_eventTargets.GetNextAssoc(pos, key, (void*&)pEventTarget);
+ if (pEventTarget && (bRemoveAll || pEventTarget->IsInvalid())) {
+ m_eventTargets.RemoveKey(key);
+ delete pEventTarget;
+ }
+ }
+}
+class CFWL_CoreToopTipDP : public IFWL_ToolTipDP, public CFX_Object
+{
+public:
+ FWL_ERR GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption);
+ FX_INT32 GetInitialDelay(IFWL_Widget *pWidget);
+ FX_INT32 GetAutoPopDelay(IFWL_Widget *pWidget);
+ CFX_DIBitmap* GetToolTipIcon(IFWL_Widget *pWidget);
+ CFX_SizeF GetToolTipIconSize(IFWL_Widget *pWidget);
+ CFX_RectF GetAnchor();
+ CFWL_CoreToopTipDP();
+
+ CFX_WideString m_wsCaption;
+ FX_INT32 m_nInitDelayTime;
+ FX_INT32 m_nAutoPopDelayTime;
+ CFX_RectF m_fAnchor;
+};
+CFWL_CoreToopTipDP::CFWL_CoreToopTipDP()
+{
+ m_nInitDelayTime = 500;
+ m_nAutoPopDelayTime = 50000;
+ m_fAnchor.Set( 0.0, 0.0, 0.0, 0.0);
+}
+FWL_ERR CFWL_CoreToopTipDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ wsCaption = m_wsCaption;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_CoreToopTipDP::GetInitialDelay(IFWL_Widget *pWidget)
+{
+ return m_nInitDelayTime;
+}
+FX_INT32 CFWL_CoreToopTipDP::GetAutoPopDelay(IFWL_Widget *pWidget)
+{
+ return m_nAutoPopDelayTime;
+}
+CFX_DIBitmap* CFWL_CoreToopTipDP::GetToolTipIcon(IFWL_Widget *pWidget)
+{
+ return NULL;
+}
+CFX_SizeF CFWL_CoreToopTipDP::GetToolTipIconSize(IFWL_Widget *pWidget)
+{
+ CFX_SizeF sz;
+ sz.Set(0, 0);
+ return sz;
+}
+CFX_RectF CFWL_CoreToopTipDP::GetAnchor()
+{
+ return m_fAnchor;
+}
+CFWL_EventTarget::~CFWL_EventTarget()
+{
+ m_eventSources.RemoveAll();
+}
+FX_INT32 CFWL_EventTarget::SetEventSource(IFWL_Widget *pSource, FX_DWORD dwFilter)
+{
+ if (pSource) {
+ m_eventSources.SetAt(pSource, dwFilter);
+ return m_eventSources.GetCount();
+ }
+ return 1;
+}
+FX_BOOL CFWL_EventTarget::ProcessEvent(CFWL_Event *pEvent)
+{
+ IFWL_WidgetDelegate *pDelegate = m_pListener->SetDelegate(NULL);
+ _FWL_RETURN_VALUE_IF_FAIL(pDelegate, FALSE);
+ if (m_eventSources.GetCount() == 0) {
+ pDelegate->OnProcessEvent(pEvent);
+ return TRUE;
+ }
+ FX_POSITION pos = m_eventSources.GetStartPosition();
+ while (pos) {
+ IFWL_Widget *pSource = NULL;
+ FX_DWORD dwFilter = 0;
+ m_eventSources.GetNextAssoc(pos, (void*&)pSource, dwFilter);
+ if (pSource == pEvent->m_pSrcTarget || pEvent->GetClassID() == FWL_EVTHASH_Idle) {
+ if (IsFilterEvent(pEvent, dwFilter)) {
+ pDelegate->OnProcessEvent(pEvent);
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_EventTarget::IsFilterEvent(CFWL_Event *pEvent, FX_DWORD dwFilter)
+{
+ if (dwFilter == FWL_EVENT_ALL_MASK) {
+ return TRUE;
+ }
+ FX_BOOL bRet = FALSE;
+ switch (pEvent->GetClassID()) {
+ case FWL_EVTHASH_Mouse: {
+ bRet = dwFilter & FWL_EVENT_MOUSE_MASK;
+ break;
+ }
+ case FWL_EVTHASH_MouseWheel: {
+ bRet = dwFilter & FWL_EVENT_MOUSEWHEEL_MASK;
+ break;
+ }
+ case FWL_EVTHASH_Key: {
+ bRet = dwFilter & FWL_EVENT_KEY_MASK;
+ break;
+ }
+ case FWL_EVTHASH_SetFocus:
+ case FWL_EVTHASH_KillFocus: {
+ bRet = dwFilter & FWL_EVENT_FOCUSCHANGED_MASK;
+ break;
+ }
+ case FWL_EVTHASH_Draw: {
+ bRet = dwFilter & FWL_EVENT_DRAW_MASK;
+ break;
+ }
+ case FWL_EVTHASH_Close: {
+ bRet = dwFilter & FWL_EVENT_CLOSE_MASK;
+ break;
+ }
+ case FWL_EVTHASH_SizeChanged: {
+ bRet = dwFilter & FWL_EVENT_SIZECHANGED_MASK;
+ break;
+ }
+ case FWL_EVTHASH_Idle: {
+ bRet = dwFilter & FWL_EVENT_IDLE_MASK;
+ break;
+ }
+ default: {
+ bRet = dwFilter & FWL_EVENT_CONTROL_MASK;
+ break;
+ }
+ }
+ return bRet;
+}
+CFWL_ToolTipContainer::CFWL_ToolTipContainer()
+ : pCurTarget(NULL)
+ , m_pToolTipImp(NULL)
+{
+ m_ToolTipDp = FX_NEW CFWL_CoreToopTipDP;
+ m_ToolTipDp->m_nInitDelayTime = 0;
+ m_ToolTipDp->m_nAutoPopDelayTime = 2000;
+}
+CFWL_ToolTipContainer::~CFWL_ToolTipContainer()
+{
+ if (m_pToolTipImp) {
+ IFWL_ToolTip *pToolTip = (IFWL_ToolTip*)m_pToolTipImp->GetInterface();
+ pToolTip->Finalize();
+ pToolTip->Release();
+ m_pToolTipImp = NULL;
+ }
+ if (m_ToolTipDp) {
+ delete m_ToolTipDp;
+ m_ToolTipDp = NULL;
+ }
+}
+CFWL_ToolTipContainer* CFWL_ToolTipContainer::getInstance()
+{
+ static CFWL_ToolTipContainer * _toolTipContainer = NULL;
+ if (!_toolTipContainer) {
+ _toolTipContainer = FX_NEW CFWL_ToolTipContainer;
+ }
+ return _toolTipContainer;
+}
+FX_ERR CFWL_ToolTipContainer::AddToolTipTarget(IFWL_ToolTipTarget *pTarget)
+{
+ if (m_arrWidget.Find((void *)pTarget) < 0) {
+ m_arrWidget.Add((void *)pTarget);
+ return FWL_ERR_Succeeded;
+ }
+ return FWL_ERR_Indefinite;
+}
+FX_ERR CFWL_ToolTipContainer::RemoveToolTipTarget(IFWL_ToolTipTarget *pTarget)
+{
+ int index = m_arrWidget.Find((void *)pTarget);
+ if (index >= 0) {
+ m_arrWidget.RemoveAt(index);
+ return FWL_ERR_Succeeded;
+ }
+ return FWL_ERR_Indefinite;
+}
+FX_BOOL CFWL_ToolTipContainer::HasToolTip(IFWL_Widget *pWedget)
+{
+ FX_INT32 iCount = m_arrWidget.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ IFWL_ToolTipTarget *p = (IFWL_ToolTipTarget *)m_arrWidget[i];
+ if (p->GetWidget() == pWedget) {
+ pCurTarget = p;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_ToolTipContainer::ProcessEnter(CFWL_EvtMouse *pEvt, IFWL_Widget *pOwner)
+{
+ if (HasToolTip(pEvt->m_pDstTarget)) {
+ if (NULL == m_pToolTipImp) {
+ CFWL_WidgetImpProperties prop;
+ prop.m_pDataProvider = m_ToolTipDp;
+ prop.m_pOwner = pOwner;
+ CFX_RectF rtTooltip;
+ rtTooltip.Set(150, 150, 100, 50);
+ prop.m_rtWidget = rtTooltip;
+ m_pToolTipImp = FX_NEW CFWL_ToolTipImp(prop);
+ IFWL_ToolTip *pToolTip = IFWL_ToolTip::Create();
+ m_pToolTipImp->SetInterface(pToolTip);
+ ((IFWL_TargetData*)pToolTip)->SetData(m_pToolTipImp);
+ m_pToolTipImp->Initialize();
+ m_pToolTipImp->ModifyStylesEx( FWL_STYLEEXT_TTP_Multiline, 0);
+ m_pToolTipImp->SetStates( FWL_WGTSTATE_Invisible, TRUE);
+ }
+ if (pCurTarget->IsShowed()) {
+ CFX_WideString wsCaption;
+ pCurTarget->GetCaption(wsCaption);
+ if (!wsCaption.IsEmpty()) {
+ m_ToolTipDp->m_wsCaption = wsCaption;
+ }
+ CFX_RectF rt;
+ rt.Reset();
+ CFX_SizeF sz;
+ sz.Reset();
+ pCurTarget->GetToolTipSize(sz);
+ if (sz.x > 0 && sz.y > 0) {
+ rt.width = sz.x;
+ rt.height = sz.y;
+ } else {
+ CFX_RectF r;
+ m_pToolTipImp->GetWidgetRect(r, TRUE);
+ rt.width = r.width;
+ rt.height = r.height;
+ }
+ CFX_PointF pt;
+ pt.Set(pEvt->m_fx, pEvt->m_fy);
+ if (pCurTarget->GetToolTipPos(pt) == FWL_ERR_Succeeded) {
+ rt.left = pt.x;
+ rt.top = pt.y;
+ m_pToolTipImp->ModifyStylesEx(FWL_STYLEEXT_TTP_NoAnchor, 0);
+ } else {
+ CFX_RectF rtAnchor;
+ pCurTarget->GetWidget()->GetClientRect(rtAnchor);
+ pCurTarget->GetWidget()->TransformTo(NULL, rtAnchor.left, rtAnchor.top);
+ m_pToolTipImp->SetAnchor(rtAnchor);
+ m_pToolTipImp->ModifyStylesEx(0, FWL_STYLEEXT_TTP_NoAnchor);
+ }
+ m_pToolTipImp->SetWidgetRect(rt);
+ m_pToolTipImp->Update();
+ m_pToolTipImp->Show();
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_ToolTipContainer::ProcessLeave(CFWL_EvtMouse *pEvt)
+{
+ if (HasToolTip(pEvt->m_pDstTarget) && NULL != m_pToolTipImp) {
+ m_pToolTipImp->Hide();
+ pCurTarget = NULL;
+ return TRUE;
+ }
+ return FALSE;
+}
+IFWL_ToolTipTarget* CFWL_ToolTipContainer::GetCurrentToolTipTarget()
+{
+ return pCurTarget;
+}
+FX_ERR CFWL_ToolTipContainer::SetToolTipInitialDelay(FX_INT32 nDelayTime)
+{
+ m_ToolTipDp->m_nInitDelayTime = nDelayTime;
+ return FWL_ERR_Succeeded;
+}
+FX_ERR CFWL_ToolTipContainer::SetToolTipAutoPopDelay(FX_INT32 nDelayTime)
+{
+ m_ToolTipDp->m_nAutoPopDelayTime = nDelayTime;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR FWL_AddToolTipTarget(IFWL_ToolTipTarget *pTarget)
+{
+ return CFWL_ToolTipContainer::getInstance()->AddToolTipTarget(pTarget);
+}
+FWL_ERR FWL_RemoveToolTipTarget(IFWL_ToolTipTarget *pTarget)
+{
+ return CFWL_ToolTipContainer::getInstance()->RemoveToolTipTarget(pTarget);
+}
+FWL_ERR FWL_SetToolTipInitialDelay(FX_INT32 nDelayTime)
+{
+ return CFWL_ToolTipContainer::getInstance()->SetToolTipInitialDelay(nDelayTime);
+}
+FWL_ERR FWL_SetToolTipAutoPopDelay(FX_INT32 nDelayTime)
+{
+ return CFWL_ToolTipContainer::getInstance()->SetToolTipAutoPopDelay(nDelayTime);
+}
+IFWL_Widget* FWL_GetCurrentThreadModalWidget(IFWL_NoteThread *pNoteThread)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pNoteThread, NULL);
+ CFWL_NoteDriver *noteDriver = (CFWL_NoteDriver*)pNoteThread->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(noteDriver, NULL);
+ if (noteDriver->CountLoop() == 1) {
+ return NULL;
+ }
+ CFWL_NoteLoop *topLoop = noteDriver->GetTopLoop();
+ _FWL_RETURN_VALUE_IF_FAIL(topLoop, NULL);
+ CFWL_WidgetImp *widget = topLoop->GetForm();
+ _FWL_RETURN_VALUE_IF_FAIL(widget, NULL);
+ return widget->GetInterface();
+}
+FWL_ERR FWL_SetHook(IFWL_NoteDriver *driver, FWLMessageHookCallback callback, FX_LPVOID info)
+{
+ CFWL_NoteDriver *noteDriver = (CFWL_NoteDriver*)driver;
+ noteDriver->SetHook(callback, info);
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fwl/src/core/fwl_panelimp.cpp b/xfa/src/fwl/src/core/fwl_panelimp.cpp
new file mode 100644
index 0000000000..de66a33491
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_panelimp.cpp
@@ -0,0 +1,208 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_widgetimp.h"
+#include "include/fwl_panelimp.h"
+IFWL_Panel* IFWL_Panel::Create()
+{
+ return new IFWL_Panel;
+}
+FWL_ERR IFWL_Panel::Initialize(IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_PanelImp(pOuter);
+ ((CFWL_PanelImp*)m_pData)->SetInterface(this);
+ return ((CFWL_PanelImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Panel::Initialize(CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_PanelImp(properties, pOuter);
+ ((CFWL_PanelImp*)m_pData)->SetInterface(this);
+ return ((CFWL_PanelImp*)m_pData)->Initialize();
+}
+IFWL_Content* IFWL_Panel::GetContent()
+{
+ return ((CFWL_PanelImp*)m_pData)->GetContent();
+}
+FWL_ERR IFWL_Panel::SetContent(IFWL_Content *pContent)
+{
+ return ((CFWL_PanelImp*)m_pData)->SetContent(pContent);
+}
+IFWL_Panel::IFWL_Panel()
+{
+ m_pData = NULL;
+}
+IFWL_Panel::~IFWL_Panel()
+{
+ if (m_pData) {
+ delete (CFWL_PanelImp*)m_pData;
+ m_pData = NULL;
+ }
+}
+CFWL_PanelImp::CFWL_PanelImp(IFWL_Widget* pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_pContent(NULL)
+{
+}
+CFWL_PanelImp::CFWL_PanelImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_pContent(NULL)
+{
+}
+CFWL_PanelImp::~CFWL_PanelImp()
+{
+}
+FWL_ERR CFWL_PanelImp::GetClassName(CFX_WideString &wsClass) const
+{
+ wsClass = FWL_CLASS_Panel;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_PanelImp::GetClassID() const
+{
+ return FWL_CLASSHASH_Panel;
+}
+FWL_ERR CFWL_PanelImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ if (m_pContent) {
+ m_pContent->GetWidgetRect(rect, TRUE);
+ }
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PanelImp::Update()
+{
+ if (m_pContent) {
+ CFX_RectF rtClient;
+ GetClientRect(rtClient);
+ FWL_GRIDUNIT eWidth = FWL_GRIDUNIT_Fixed, eHeight = FWL_GRIDUNIT_Fixed;
+ IFWL_WidgetMgr *pWidgetMgr = FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, FWL_ERR_Indefinite);
+ IFWL_Widget *pParent = pWidgetMgr->GetWidget((IFWL_Widget*)this, FWL_WGTRELATION_Parent);
+ if (pParent && pParent->GetClassID() == FWL_CLASSHASH_Grid) {
+ IFWL_Grid* pGrid = (IFWL_Grid*)pParent;
+ pGrid->GetWidgetSize((IFWL_Widget*)this, FWL_GRIDSIZE_Width, eWidth);
+ pGrid->GetWidgetSize((IFWL_Widget*)this, FWL_GRIDSIZE_Height, eHeight);
+ }
+ if (eWidth != FWL_GRIDUNIT_Auto || eHeight != FWL_GRIDUNIT_Auto) {
+ }
+ m_pContent->SetWidgetRect(rtClient);
+ m_pContent->Update();
+ }
+ return FWL_ERR_Succeeded;
+}
+IFWL_Content* CFWL_PanelImp::GetContent()
+{
+ return m_pContent;
+}
+FWL_ERR CFWL_PanelImp::SetContent(IFWL_Content *pContent)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pContent, FWL_ERR_Indefinite);
+ m_pContent = pContent;
+ return pContent->SetParent(m_pInterface);
+}
+class CFWL_CustomPanelImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_CustomPanelImp(IFWL_Widget *pOuter = NULL);
+ CFWL_CustomPanelImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_CustomPanelImp();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual IFWL_Content* GetContent();
+ virtual FWL_ERR SetContent(IFWL_Content *pContent);
+ FWL_ERR SetProxy(IFWL_Proxy *pProxy);
+protected:
+ IFWL_Content *m_pContent;
+ IFWL_Proxy *m_pProxy;
+};
+CFWL_CustomPanelImp::CFWL_CustomPanelImp(IFWL_Widget* pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_pContent(NULL)
+ , m_pProxy(NULL)
+{
+}
+CFWL_CustomPanelImp::CFWL_CustomPanelImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_pContent(NULL)
+ , m_pProxy(NULL)
+{
+}
+CFWL_CustomPanelImp::~CFWL_CustomPanelImp()
+{
+}
+FWL_ERR CFWL_CustomPanelImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize && m_pProxy && (m_pProxy->GetWidgetRect(rect, bAutoSize) == FWL_ERR_Succeeded)) {
+ return FWL_ERR_Succeeded;
+ }
+ return CFWL_WidgetImp::GetWidgetRect(rect, bAutoSize);
+}
+FWL_ERR CFWL_CustomPanelImp::Update()
+{
+ if (m_pProxy) {
+ return m_pProxy->Update();
+ }
+ return CFWL_WidgetImp::Update();
+}
+IFWL_Content* CFWL_CustomPanelImp::GetContent()
+{
+ return m_pContent;
+}
+FWL_ERR CFWL_CustomPanelImp::SetContent(IFWL_Content *pContent)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pContent, FWL_ERR_Indefinite);
+ m_pContent = pContent;
+ return pContent->SetParent(m_pInterface);
+}
+FWL_ERR CFWL_CustomPanelImp::SetProxy(IFWL_Proxy *pProxy)
+{
+ m_pProxy = pProxy;
+ return FWL_ERR_Succeeded;
+}
+IFWL_CustomPanel* IFWL_CustomPanel::Create()
+{
+ return new IFWL_CustomPanel;
+}
+FWL_ERR IFWL_CustomPanel::Initialize(IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_CustomPanelImp(pOuter);
+ ((CFWL_CustomPanelImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CustomPanelImp*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_CustomPanel::Initialize(CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_CustomPanelImp(properties, pOuter);
+ ((CFWL_CustomPanelImp*)m_pData)->SetInterface(this);
+ return ((CFWL_CustomPanelImp*)m_pData)->Initialize();
+}
+IFWL_Content* IFWL_CustomPanel::GetContent()
+{
+ return ((CFWL_CustomPanelImp*)m_pData)->GetContent();
+}
+FWL_ERR IFWL_CustomPanel::SetContent(IFWL_Content *pContent)
+{
+ return ((CFWL_CustomPanelImp*)m_pData)->SetContent(pContent);
+}
+FWL_ERR IFWL_CustomPanel::SetProxy(IFWL_Proxy *pProxy)
+{
+ return ((CFWL_CustomPanelImp*)m_pData)->SetProxy(pProxy);
+}
+IFWL_CustomPanel::IFWL_CustomPanel()
+{
+ m_pData = NULL;
+}
+IFWL_CustomPanel::~IFWL_CustomPanel()
+{
+ if (m_pData) {
+ delete (CFWL_CustomPanelImp*)m_pData;
+ m_pData = NULL;
+ }
+}
diff --git a/xfa/src/fwl/src/core/fwl_sdadapterimp.cpp b/xfa/src/fwl/src/core/fwl_sdadapterimp.cpp
new file mode 100644
index 0000000000..fae5a2a6db
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_sdadapterimp.cpp
@@ -0,0 +1,187 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_widgetmgrimp.h"
+CFWL_SDAdapterWidgetMgr::CFWL_SDAdapterWidgetMgr()
+{
+}
+CFWL_SDAdapterWidgetMgr::~CFWL_SDAdapterWidgetMgr()
+{
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::CreateWidget(IFWL_Widget *pWidget, IFWL_Widget *pParent )
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::DestroyWidget(IFWL_Widget *pWidget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetWidgetRect(IFWL_Widget *pWidget, const CFX_RectF &rect)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetWidgetPosition(IFWL_Widget *pWidget, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetParentWidget(IFWL_Widget *pWidget, IFWL_Widget *pParent)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::ShowWidget(IFWL_Widget *pWidget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::HideWidget(IFWL_Widget *pWidget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetNormal(IFWL_Widget *pWidget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetMaximize(IFWL_Widget *pWidget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetMinimize(IFWL_Widget *pWidget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::RunWidget(IFWL_Widget *pWidget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::Exit(FX_INT32 iExitCode)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::CreateWidgetWithNativeId(IFWL_Widget *pWidget, void *vp)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::GetWidgetRect(IFWL_Widget *pWidget, CFX_RectF &rect)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetWidgetIcon(IFWL_Widget *pWidget, const CFX_DIBitmap *pIcon, FX_BOOL bBig)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetWidgetCaption(IFWL_Widget *pWidget, FX_WSTR wsCaption)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetBorderRegion(IFWL_Widget *pWidget, CFX_Path *pPath)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetTransparent(IFWL_Widget *pWidget, FX_DWORD dwAlpha)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetFullScreen(IFWL_Widget *pWidget, FX_BOOL bFullScreen)
+{
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_SDAdapterWidgetMgr::CheckMessage()
+{
+ return TRUE;
+}
+FX_BOOL CFWL_SDAdapterWidgetMgr::IsIdleMessage()
+{
+ return TRUE;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::DispatchMessage()
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::GetWidgetDC(IFWL_Widget *pWidget, FX_LPVOID &pDC)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::ReleaseWidgetDC(IFWL_Widget *pWidget, FX_LPVOID pDC, CFX_RectF *pClip)
+{
+ return FWL_ERR_Succeeded;
+}
+FX_LPVOID CFWL_SDAdapterWidgetMgr::GetWindow(IFWL_Widget *pWidget)
+{
+ return NULL;
+}
+FX_DWORD CFWL_SDAdapterWidgetMgr::GetKeyState(FX_DWORD dwVirtKey)
+{
+ return 0;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::RunLoop(IFWL_Widget *widget)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::EndLoop()
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::InitMenu(IFWL_Menu *pMenu, IFWL_MenuDP *pMenuData)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::UpdateMenu(IFWL_Menu *pMenu, FX_LPCVOID hItem, FX_INT32 iType)
+{
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_SDAdapterWidgetMgr::TrackPopupMenu(IFWL_Menu *pMenu, IFWL_MenuDP *pMenuData)
+{
+ return 0;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::SetMessageHook(IFWL_AdapterMessageHook *hook)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterWidgetMgr::GetSystemBorder(FX_FLOAT &l, FX_FLOAT &t, FX_FLOAT &r, FX_FLOAT &b)
+{
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_SDAdapterWidgetMgr::GetPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ return FWL_ERR_Succeeded;
+}
+CFWL_SDAdapterThreadMgr::CFWL_SDAdapterThreadMgr()
+{
+}
+CFWL_SDAdapterThreadMgr::~CFWL_SDAdapterThreadMgr()
+{
+}
+FWL_ERR CFWL_SDAdapterThreadMgr::Start(IFWL_Thread *pThread, FWL_HTHREAD &hThread, FX_BOOL bSuspended)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterThreadMgr::Resume(FWL_HTHREAD hThread)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterThreadMgr::Suspend(FWL_HTHREAD hThread)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterThreadMgr::Kill(FWL_HTHREAD hThread, FX_INT32 iExitCode)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_SDAdapterThreadMgr::Stop(FWL_HTHREAD hThread, FX_INT32 iExitCode)
+{
+ return FWL_ERR_Succeeded;
+}
+IFWL_Thread* CFWL_SDAdapterThreadMgr::GetCurrentThread()
+{
+ return FWL_GetApp();
+}
diff --git a/xfa/src/fwl/src/core/fwl_targetimp.cpp b/xfa/src/fwl/src/core/fwl_targetimp.cpp
new file mode 100644
index 0000000000..75e40db15a
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_targetimp.cpp
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+FX_DWORD IFWL_Target::Release()
+{
+ FX_DWORD dwRef = ((CFWL_Target*)m_pData)->Release();
+ if (!dwRef) {
+ m_pData = NULL;
+ delete this;
+ }
+ return dwRef;
+}
+IFWL_Target* IFWL_Target::Retain()
+{
+ return ((CFWL_Target*)m_pData)->Retain();
+}
+FX_DWORD IFWL_Target::GetRefCount() const
+{
+ return ((CFWL_Target*)m_pData)->GetRefCount();
+}
+FWL_ERR IFWL_Target::GetClassName(CFX_WideString &wsClass) const
+{
+ return ((CFWL_Target*)m_pData)->GetClassName(wsClass);
+}
+FX_DWORD IFWL_Target::GetClassID() const
+{
+ return ((CFWL_Target*)m_pData)->GetClassID();
+}
+FX_BOOL IFWL_Target::IsInstance(FX_WSTR wsClass) const
+{
+ return ((CFWL_Target*)m_pData)->IsInstance(wsClass);
+}
+FWL_ERR IFWL_Target::Initialize()
+{
+ return ((CFWL_Target*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Target::Finalize()
+{
+ return ((CFWL_Target*)m_pData)->Finalize();
+}
+IFWL_Target::~IFWL_Target()
+{
+}
+CFWL_Target::CFWL_Target()
+ : m_dwRefCount(1)
+{
+}
+CFWL_Target::~CFWL_Target()
+{
+}
+FX_DWORD CFWL_Target::Release()
+{
+ m_dwRefCount--;
+ FX_DWORD dwRet = m_dwRefCount;
+ if (!m_dwRefCount) {
+ delete this;
+ }
+ return dwRet;
+}
+IFWL_Target* CFWL_Target::Retain()
+{
+ m_dwRefCount++;
+ return (IFWL_Target*)this;
+}
+FX_DWORD CFWL_Target::GetRefCount() const
+{
+ return m_dwRefCount;
+}
+FWL_ERR CFWL_Target::GetClassName(CFX_WideString &wsClass) const
+{
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_Target::GetClassID() const
+{
+ return 0;
+}
+FX_BOOL CFWL_Target::IsInstance(FX_WSTR wsClass) const
+{
+ return FALSE;
+}
+FWL_ERR CFWL_Target::Initialize()
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_Target::Finalize()
+{
+ return FWL_ERR_Succeeded;
+}
+FX_LPVOID IFWL_TargetData::GetData()
+{
+ return m_pData;
+}
+void IFWL_TargetData::SetData(FX_LPVOID pData)
+{
+ m_pData = pData;
+}
diff --git a/xfa/src/fwl/src/core/fwl_threadimp.cpp b/xfa/src/fwl/src/core/fwl_threadimp.cpp
new file mode 100644
index 0000000000..66f4144c71
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_threadimp.cpp
@@ -0,0 +1,158 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_appimp.h"
+CFWL_ControlThread::~CFWL_ControlThread()
+{
+}
+FWL_ERR CFWL_ControlThread::Run(FWL_HTHREAD hThread)
+{
+ static int count = 0;
+ while (TRUE) {
+ }
+ return FWL_ERR_Succeeded;
+}
+IFWL_Thread * IFWL_Thread::Create()
+{
+ return (IFWL_Thread *) FX_NEW CFWL_Thread;
+}
+CFWL_Thread::CFWL_Thread()
+{
+}
+CFWL_Thread::~CFWL_Thread()
+{
+}
+FWL_ERR CFWL_Thread::Run(FWL_HTHREAD hThread)
+{
+ return FWL_ERR_Succeeded;
+}
+CFWL_ControlThread * CFWL_NoteThread::_assistantThreadHandler = NULL;
+FWL_HTHREAD CFWL_NoteThread::_assistantThread = NULL;
+FX_INT32 CFWL_NoteThread::_refCount = 0;
+IFWL_NoteThread* IFWL_NoteThread::Create()
+{
+ return (IFWL_NoteThread*) FX_NEW CFWL_NoteThread;
+}
+CFWL_NoteThread::CFWL_NoteThread()
+ : m_hThread(NULL)
+{
+ m_pNoteDriver = FX_NEW CFWL_NoteDriver;
+}
+CFWL_NoteThread::~CFWL_NoteThread()
+{
+ if (m_hThread) {
+ FWL_StopThread(m_hThread, 0);
+ }
+ if (m_pNoteDriver) {
+ delete m_pNoteDriver;
+ m_pNoteDriver = NULL;
+ }
+}
+FWL_ERR CFWL_NoteThread::Run(FWL_HTHREAD hThread)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pNoteDriver, FWL_ERR_Indefinite);
+ FWL_ERR result = m_pNoteDriver->Run();
+ return result;
+}
+IFWL_NoteDriver* CFWL_NoteThread::GetNoteDriver()
+{
+ return (IFWL_NoteDriver*)m_pNoteDriver;
+}
+extern IFWL_AdapterNative* FWL_GetAdapterNative();
+FWL_HTHREAD FWL_StartThread(IFWL_Thread *pThread, FX_BOOL bSuspended )
+{
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(pNative, NULL);
+ IFWL_AdapterThreadMgr *pThreadMgr = pNative->GetThreadMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pThreadMgr, NULL);
+ FWL_HTHREAD hThread = NULL;
+ pThreadMgr->Start(pThread, hThread, bSuspended);
+ return hThread;
+}
+FWL_ERR FWL_ResumeThread(FWL_HTHREAD hThread)
+{
+ IFWL_AdapterNative * Native = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(Native, FWL_ERR_Indefinite);
+ IFWL_AdapterThreadMgr * ThreadMgr = Native->GetThreadMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(ThreadMgr, FWL_ERR_Indefinite);
+ return ThreadMgr->Resume(hThread);
+}
+FWL_ERR FWL_SuspendThread(FWL_HTHREAD hThread)
+{
+ IFWL_AdapterNative * Native = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(Native, FWL_ERR_Indefinite);
+ IFWL_AdapterThreadMgr * ThreadMgr = Native->GetThreadMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(ThreadMgr, FWL_ERR_Indefinite);
+ return ThreadMgr->Suspend(hThread);
+}
+FWL_ERR FWL_KillThread(FWL_HTHREAD hThread, FX_INT32 iExitCode)
+{
+ IFWL_AdapterNative * Native = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(Native, FWL_ERR_Indefinite);
+ IFWL_AdapterThreadMgr * ThreadMgr = Native->GetThreadMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(ThreadMgr, FWL_ERR_Indefinite);
+ return ThreadMgr->Kill(hThread, iExitCode);
+}
+FWL_ERR FWL_StopThread(FWL_HTHREAD hThread, FX_INT32 iExitCode)
+{
+ IFWL_AdapterNative * Native = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(Native, FWL_ERR_Indefinite);
+ IFWL_AdapterThreadMgr * ThreadMgr = Native->GetThreadMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(ThreadMgr, FWL_ERR_Indefinite);
+ return ThreadMgr->Stop(hThread, iExitCode);
+}
+FWL_HMUTEX FWL_CreateMutex()
+{
+ return NULL;
+}
+FWL_ERR FWL_DestroyMutex(FWL_HMUTEX hMutex)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR FWL_LockMutex(FWL_HMUTEX hMutex)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR FWL_TryLockMutex(FWL_HMUTEX hMutex)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR FWL_UnlockMutex(FWL_HMUTEX hMutex)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR FWL_IsLockedMutex(FWL_HMUTEX hMutex, FX_BOOL &bLocked)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_HSEMAPHORE FWL_CreateSemaphore()
+{
+ return (FWL_HSEMAPHORE) IFWL_AdapterSemaphore::Create();
+}
+FWL_ERR FWL_DestroySemaphore(FWL_HSEMAPHORE hSemaphore)
+{
+ return ((IFWL_AdapterSemaphore*)hSemaphore)->Destroy();
+}
+FWL_ERR FWL_WaitSemaphore(FWL_HSEMAPHORE hSemaphore)
+{
+ return ((IFWL_AdapterSemaphore*)hSemaphore)->Wait();
+}
+FWL_ERR FWL_PostSemaphore(FWL_HSEMAPHORE hSemaphore, FX_INT32 down )
+{
+ return ((IFWL_AdapterSemaphore*)hSemaphore)->Post();
+}
+FWL_ERR FWL_GetSemaphoreValue(FWL_HSEMAPHORE hSemaphore, FX_INT32 &value)
+{
+ return ((IFWL_AdapterSemaphore*)hSemaphore)->Value((FX_DWORD &)value);
+}
+FWL_ERR FWL_ResetSemaphore(FWL_HSEMAPHORE hSemaphore, FX_INT32 init)
+{
+ return ((IFWL_AdapterSemaphore*)hSemaphore)->Reset(init);
+}
diff --git a/xfa/src/fwl/src/core/fwl_timerimp.cpp b/xfa/src/fwl/src/core/fwl_timerimp.cpp
new file mode 100644
index 0000000000..e0300f4316
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_timerimp.cpp
@@ -0,0 +1,28 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_appimp.h"
+FWL_HTIMER FWL_StartTimer(IFWL_Timer *pTimer, FX_DWORD dwElapse, FX_BOOL bImmediately )
+{
+ IFWL_AdapterNative *pAdapterNative = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(pAdapterNative, NULL);
+ IFWL_AdapterTimerMgr *pAdapterTimerMgr = pAdapterNative->GetTimerMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pAdapterTimerMgr, NULL);
+ FWL_HTIMER hTimer = NULL;
+ pAdapterTimerMgr->Start(pTimer, dwElapse, hTimer, bImmediately);
+ return hTimer;
+}
+FX_INT32 FWL_StopTimer(FWL_HTIMER hTimer)
+{
+ IFWL_AdapterNative *pAdapterNative = FWL_GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(pAdapterNative, FWL_ERR_Indefinite);
+ IFWL_AdapterTimerMgr *pAdapterTimerMgr = pAdapterNative->GetTimerMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pAdapterTimerMgr, FWL_ERR_Indefinite);
+ return pAdapterTimerMgr->Stop(hTimer);
+}
diff --git a/xfa/src/fwl/src/core/fwl_widgetimp.cpp b/xfa/src/fwl/src/core/fwl_widgetimp.cpp
new file mode 100644
index 0000000000..61186a7ede
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_widgetimp.cpp
@@ -0,0 +1,1217 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_appimp.h"
+#include "include/fwl_widgetmgrimp.h"
+#include "include/fwl_widgetimp.h"
+FWL_ERR IFWL_Widget::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetWidgetRect(rect, bAutoSize);
+}
+FWL_ERR IFWL_Widget::GetGlobalRect(CFX_RectF &rect)
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetGlobalRect(rect);
+}
+FWL_ERR IFWL_Widget::SetWidgetRect(const CFX_RectF &rect)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetWidgetRect(rect);
+}
+FWL_ERR IFWL_Widget::GetClientRect(CFX_RectF &rect)
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetClientRect(rect);
+}
+IFWL_Widget* IFWL_Widget::GetParent()
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetParent();
+}
+FWL_ERR IFWL_Widget::SetParent(IFWL_Widget *pParent)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetParent(pParent);
+}
+IFWL_Widget* IFWL_Widget::GetOwner()
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetOwner();
+}
+FWL_ERR IFWL_Widget::SetOwner(IFWL_Widget *pOwner)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetOwner(pOwner);
+}
+IFWL_Widget* IFWL_Widget::GetOuter()
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetOuter();
+}
+FX_DWORD IFWL_Widget::GetStyles()
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetStyles();
+}
+FWL_ERR IFWL_Widget::ModifyStyles(FX_DWORD dwStylesAdded, FX_DWORD dwStylesRemoved)
+{
+ return ((CFWL_WidgetImp*)m_pData)->ModifyStyles(dwStylesAdded, dwStylesRemoved);
+}
+FX_DWORD IFWL_Widget::GetStylesEx()
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetStylesEx();
+}
+FWL_ERR IFWL_Widget::ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ return ((CFWL_WidgetImp*)m_pData)->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+FX_DWORD IFWL_Widget::GetStates()
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetStates();
+}
+FWL_ERR IFWL_Widget::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetStates(dwStates, bSet);
+}
+FWL_ERR IFWL_Widget::SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetPrivateData(module_id, pData, callback);
+}
+FX_LPVOID IFWL_Widget::GetPrivateData(FX_LPVOID module_id)
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetPrivateData(module_id);
+}
+FWL_ERR IFWL_Widget::Update()
+{
+ return ((CFWL_WidgetImp*)m_pData)->Update();
+}
+FWL_ERR IFWL_Widget::LockUpdate()
+{
+ return ((CFWL_WidgetImp*)m_pData)->LockUpdate();
+}
+FWL_ERR IFWL_Widget::UnlockUpdate()
+{
+ return ((CFWL_WidgetImp*)m_pData)->UnlockUpdate();
+}
+FX_DWORD IFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ return ((CFWL_WidgetImp*)m_pData)->HitTest(fx, fy);
+}
+FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget *pWidget, FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ return ((CFWL_WidgetImp*)m_pData)->TransformTo(pWidget, fx, fy);
+}
+FWL_ERR IFWL_Widget::TransformTo(IFWL_Widget *pWidget, CFX_RectF &rt)
+{
+ return ((CFWL_WidgetImp*)m_pData)->TransformTo(pWidget, rt);
+}
+FWL_ERR IFWL_Widget::GetMatrix(CFX_Matrix &matrix, FX_BOOL bGlobal )
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetMatrix(matrix, bGlobal);
+}
+FWL_ERR IFWL_Widget::SetMatrix(const CFX_Matrix &matrix)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetMatrix(matrix);
+}
+FWL_ERR IFWL_Widget::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return ((CFWL_WidgetImp*)m_pData)->DrawWidget(pGraphics, pMatrix);
+}
+IFWL_ThemeProvider* IFWL_Widget::GetThemeProvider()
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetThemeProvider();
+}
+FWL_ERR IFWL_Widget::SetThemeProvider(IFWL_ThemeProvider *pThemeProvider)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetThemeProvider(pThemeProvider);
+}
+FWL_ERR IFWL_Widget::SetDataProvider(IFWL_DataProvider *pDataProvider)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetDataProvider(pDataProvider);
+}
+IFWL_WidgetDelegate* IFWL_Widget::SetDelegate(IFWL_WidgetDelegate *pDelegate)
+{
+ return ((CFWL_WidgetImp*)m_pData)->SetDelegate(pDelegate);
+}
+IFWL_NoteThread* IFWL_Widget::GetOwnerThread() const
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetOwnerThread();
+}
+CFX_SizeF IFWL_Widget::GetOffsetFromParent(IFWL_Widget *pParent)
+{
+ return ((CFWL_WidgetImp*)m_pData)->GetOffsetFromParent(pParent);
+}
+FWL_ERR CFWL_WidgetImp::Initialize()
+{
+ IFWL_App *pApp = FWL_GetApp();
+ _FWL_RETURN_VALUE_IF_FAIL(pApp, FWL_ERR_Indefinite);
+ IFWL_AdapterNative *pAdapter = pApp->GetAdapterNative();
+ _FWL_RETURN_VALUE_IF_FAIL(pAdapter, FWL_ERR_Indefinite);
+ IFWL_AdapterThreadMgr *pAdapterThread = pAdapter->GetThreadMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pAdapterThread, FWL_ERR_Indefinite);
+ SetOwnerThread((CFWL_NoteThread*)pAdapterThread->GetCurrentThread());
+ IFWL_Widget *pParent = m_pProperties->m_pParent;
+ m_pWidgetMgr->InsertWidget(pParent, m_pInterface);
+ if (!IsChild()) {
+ {
+ IFWL_Widget *pOwner = m_pProperties->m_pOwner;
+ if (pOwner) {
+ m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
+ }
+ }
+ m_pWidgetMgr->CreateWidget_Native(m_pInterface);
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::Finalize()
+{
+ NotifyDriver();
+ IFWL_Form *pForm = (IFWL_Form *)FWL_GetWidgetMgr()->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
+ if (pForm && pForm != m_pInterface) {
+ IFWL_Content *pContent = pForm->GetContent();
+ if (pContent) {
+ pContent->RemoveWidget(m_pInterface);
+ }
+ }
+ if (!IsChild()) {
+ m_pWidgetMgr->DestroyWidget_Native(m_pInterface);
+ }
+ m_pWidgetMgr->RemoveWidget(m_pInterface);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (bAutoSize) {
+ if (HasEdge()) {
+ FX_FLOAT fEdge = GetEdgeWidth();
+ rect.Inflate(fEdge, fEdge);
+ }
+ if (HasBorder()) {
+ FX_FLOAT fBorder = GetBorderSize();
+ rect.Inflate(fBorder, fBorder);
+ }
+ } else {
+ rect = m_pProperties->m_rtWidget;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::GetGlobalRect(CFX_RectF &rect)
+{
+ IFWL_Widget *pForm = m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
+ _FWL_RETURN_VALUE_IF_FAIL(pForm, FWL_ERR_Indefinite);
+ rect.Set(0, 0, m_pProperties->m_rtWidget.width, m_pProperties->m_rtWidget.height);
+ if (pForm == m_pInterface) {
+ return FWL_ERR_Succeeded;
+ }
+ return TransformTo(pForm, rect);
+}
+FWL_ERR CFWL_WidgetImp::SetWidgetRect(const CFX_RectF &rect)
+{
+ CFX_RectF rtOld = m_pProperties->m_rtWidget;
+ m_pProperties->m_rtWidget = rect;
+ if (IsChild()) {
+ if (FXSYS_fabs(rtOld.width - rect.width) > 0.5f || FXSYS_fabs(rtOld.height - rect.height) > 0.5f) {
+ CFWL_EvtSizeChanged ev;
+ ev.m_pSrcTarget = m_pInterface;
+ ev.m_rtOld = rtOld;
+ ev.m_rtNew = rect;
+ IFWL_WidgetDelegate *pDelegate = SetDelegate(NULL);
+ if (pDelegate) {
+ pDelegate->OnProcessEvent(&ev);
+ }
+ }
+ return FWL_ERR_Succeeded;
+ }
+ m_pWidgetMgr->SetWidgetRect_Native(m_pInterface, rect);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::GetClientRect(CFX_RectF &rect)
+{
+ GetEdgeRect(rect);
+ if (HasEdge()) {
+ FX_FLOAT fEdge = GetEdgeWidth();
+ rect.Deflate(fEdge, fEdge);
+ }
+ return FWL_ERR_Succeeded;
+}
+IFWL_Widget* CFWL_WidgetImp::GetParent()
+{
+ return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Parent);
+}
+FWL_ERR CFWL_WidgetImp::SetParent(IFWL_Widget* pParent)
+{
+ m_pProperties->m_pParent = pParent;
+ m_pWidgetMgr->SetParent(pParent, m_pInterface);
+ return FWL_ERR_Succeeded;
+}
+IFWL_Widget* CFWL_WidgetImp::GetOwner()
+{
+ return m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_Owner);
+}
+FWL_ERR CFWL_WidgetImp::SetOwner(IFWL_Widget* pOwner)
+{
+ m_pProperties->m_pOwner = pOwner;
+ m_pWidgetMgr->SetOwner(pOwner, m_pInterface);
+ return FWL_ERR_Succeeded;
+}
+IFWL_Widget* CFWL_WidgetImp::GetOuter()
+{
+ return m_pOuter;
+}
+FX_DWORD CFWL_WidgetImp::GetStyles()
+{
+ return m_pProperties->m_dwStyles;
+}
+FWL_ERR CFWL_WidgetImp::ModifyStyles(FX_DWORD dwStylesAdded, FX_DWORD dwStylesRemoved)
+{
+ m_pProperties->m_dwStyles = (m_pProperties->m_dwStyles & ~dwStylesRemoved) | dwStylesAdded;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_WidgetImp::GetStylesEx()
+{
+ return m_pProperties->m_dwStyleExes;
+}
+FWL_ERR CFWL_WidgetImp::ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ m_pProperties->m_dwStyleExes = (m_pProperties->m_dwStyleExes & ~dwStylesExRemoved) | dwStylesExAdded;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_WidgetImp::GetStates()
+{
+ return m_pProperties->m_dwStates;
+}
+static void NotifyHideChildWidget(IFWL_WidgetMgr *widgetMgr, IFWL_Widget *widget, CFWL_NoteDriver *noteDriver)
+{
+ IFWL_Widget *child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
+ while (child) {
+ noteDriver->NotifyTargetHide(child);
+ NotifyHideChildWidget(widgetMgr, child, noteDriver);
+ child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ }
+}
+FWL_ERR CFWL_WidgetImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
+{
+ bSet ? (m_pProperties->m_dwStates |= dwStates) : (m_pProperties->m_dwStates &= ~dwStates);
+ FWL_ERR ret = FWL_ERR_Succeeded;
+ if (dwStates & FWL_WGTSTATE_Invisible) {
+ if (bSet) {
+ ret = m_pWidgetMgr->HideWidget_Native(m_pInterface);
+ CFWL_NoteDriver *noteDriver = (CFWL_NoteDriver*)GetOwnerThread()->GetNoteDriver();
+ IFWL_WidgetMgr *widgetMgr = FWL_GetWidgetMgr();
+ noteDriver->NotifyTargetHide(m_pInterface);
+ IFWL_Widget *child = widgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_FirstChild);
+ while (child) {
+ noteDriver->NotifyTargetHide(child);
+ NotifyHideChildWidget(widgetMgr, child, noteDriver);
+ child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ }
+ } else {
+ ret = m_pWidgetMgr->ShowWidget_Native(m_pInterface);
+ }
+ }
+ return ret;
+}
+FWL_ERR CFWL_WidgetImp::SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback)
+{
+ if (!m_pPrivateData) {
+ m_pPrivateData = new CFX_PrivateData;
+ }
+ m_pPrivateData->SetPrivateData(module_id, pData, callback);
+ return FWL_ERR_Succeeded;
+}
+FX_LPVOID CFWL_WidgetImp::GetPrivateData(FX_LPVOID module_id)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pPrivateData, NULL);
+ return m_pPrivateData->GetPrivateData(module_id);
+}
+FWL_ERR CFWL_WidgetImp::Update()
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::LockUpdate()
+{
+ m_iLock++;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::UnlockUpdate()
+{
+ if (IsLocked()) {
+ m_iLock--;
+ }
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_WidgetImp::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rtClient;
+ GetClientRect(rtClient);
+ if (rtClient.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Client;
+ }
+ if (HasEdge()) {
+ CFX_RectF rtEdge;
+ GetEdgeRect(rtEdge);
+ if (rtEdge.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Edge;
+ }
+ }
+ if (HasBorder()) {
+ CFX_RectF rtRelative;
+ GetRelativeRect(rtRelative);
+ if (rtRelative.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Border;
+ }
+ }
+ return FWL_WGTHITTEST_Unknown;
+}
+FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget *pWidget, FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ CFX_SizeF szOffset;
+ if (IsParent(pWidget)) {
+ szOffset = GetOffsetFromParent(pWidget);
+ } else {
+ szOffset = ((IFWL_Widget*)pWidget)->GetOffsetFromParent(m_pInterface);
+ szOffset.x = -szOffset.x;
+ szOffset.y = -szOffset.y;
+ }
+ fx += szOffset.x;
+ fy += szOffset.y;
+ return FWL_ERR_Succeeded;
+ }
+ CFX_RectF r;
+ CFX_Matrix m;
+ IFWL_Widget * parent = GetParent();
+ if (parent) {
+ GetWidgetRect(r);
+ fx += r.left;
+ fy += r.top;
+ GetMatrix(m, TRUE);
+ m.TransformPoint(fx, fy);
+ }
+ IFWL_Widget * form1 = m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm);
+ _FWL_RETURN_VALUE_IF_FAIL(form1, FWL_ERR_Indefinite);
+ if (!pWidget) {
+ form1->GetWidgetRect(r);
+ fx += r.left;
+ fy += r.top;
+#ifdef FWL_UseMacSystemBorder
+ if (form1->GetStyles() & FWL_WGTSTYLE_Caption) {
+ FX_FLOAT l, t, r, b;
+ l = t = r = b = 0;
+ FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
+ fy += t;
+ }
+#endif
+ return FWL_ERR_Succeeded;
+ }
+ IFWL_Widget * form2 = m_pWidgetMgr->GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
+ _FWL_RETURN_VALUE_IF_FAIL(form2, FWL_ERR_Indefinite);
+ if (form1 != form2) {
+ form1->GetWidgetRect(r);
+ fx += r.left;
+ fy += r.top;
+ form2->GetWidgetRect(r);
+ fx -= r.left;
+ fy -= r.top;
+#ifdef FWL_UseMacSystemBorder
+ if ((form1->GetStyles() & FWL_WGTSTYLE_Caption) != (form2->GetStyles() & FWL_WGTSTYLE_Caption)) {
+ FX_FLOAT l, t, r, b;
+ l = t = r = b = 0;
+ FWL_GetAdapterWidgetMgr()->GetSystemBorder(l, t, r, b);
+ (form1->GetStyles() & FWL_WGTSTYLE_Caption) ? (fy += t) : (fy -= t);
+ }
+#endif
+ }
+ parent = pWidget->GetParent();
+ if (parent) {
+ pWidget->GetMatrix(m, TRUE);
+ CFX_Matrix m1;
+ m1.Reset();
+ m1.SetReverse(m);
+ m1.TransformPoint(fx, fy);
+ pWidget->GetWidgetRect(r);
+ fx -= r.left;
+ fy -= r.top;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::TransformTo(IFWL_Widget *pWidget, CFX_RectF &rt)
+{
+ return TransformTo(pWidget, rt.left, rt.top);
+}
+FWL_ERR CFWL_WidgetImp::GetMatrix(CFX_Matrix &matrix, FX_BOOL bGlobal )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties, FWL_ERR_Indefinite);
+ if (bGlobal) {
+ IFWL_Widget * parent = GetParent();
+ CFX_PtrArray parents;
+ while (parent) {
+ parents.Add(parent);
+ parent = parent->GetParent();
+ }
+ matrix.Reset();
+ CFX_Matrix ctmOnParent;
+ CFX_RectF rect;
+ FX_INT32 count = parents.GetSize();
+ for (FX_INT32 i = count - 2; i >= 0; i--) {
+ parent = (IFWL_Widget *) parents.GetAt(i);
+ parent->GetMatrix(ctmOnParent, FALSE);
+ parent->GetWidgetRect(rect);
+ matrix.Concat(ctmOnParent, TRUE);
+ matrix.Translate(rect.left, rect.top, TRUE);
+ }
+ matrix.Concat(m_pProperties->m_ctmOnParent, TRUE);
+ parents.RemoveAll();
+ } else {
+ matrix = m_pProperties->m_ctmOnParent;
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::SetMatrix(const CFX_Matrix &matrix)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pProperties, FWL_ERR_Indefinite);
+ IFWL_Widget * parent = GetParent();
+ if (!parent) {
+ return FWL_ERR_Indefinite;
+ }
+ m_pProperties->m_ctmOnParent = matrix;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return FWL_ERR_Indefinite;
+}
+IFWL_ThemeProvider* CFWL_WidgetImp::GetThemeProvider()
+{
+ return m_pProperties->m_pThemeProvider;
+}
+FWL_ERR CFWL_WidgetImp::SetThemeProvider(IFWL_ThemeProvider *pThemeProvider)
+{
+ m_pProperties->m_pThemeProvider = pThemeProvider;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::SetDataProvider(IFWL_DataProvider *pDataProvider)
+{
+ m_pProperties->m_pDataProvider = pDataProvider;
+ return FWL_ERR_Succeeded;
+}
+IFWL_WidgetDelegate* CFWL_WidgetImp::SetDelegate(IFWL_WidgetDelegate *pDelegate)
+{
+ if (!m_pCurDelegate) {
+ m_pCurDelegate = m_pDelegate;
+ }
+ if (!pDelegate) {
+ return m_pCurDelegate;
+ }
+ IFWL_WidgetDelegate *pOldDelegate = m_pCurDelegate;
+ m_pCurDelegate = pDelegate;
+ return pOldDelegate;
+}
+IFWL_NoteThread* CFWL_WidgetImp::GetOwnerThread() const
+{
+ return (IFWL_NoteThread*)m_pOwnerThread;
+}
+FWL_ERR CFWL_WidgetImp::SetOwnerThread(CFWL_NoteThread *pOwnerThread)
+{
+ m_pOwnerThread = pOwnerThread;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::GetProperties(CFWL_WidgetImpProperties &properties)
+{
+ properties = *m_pProperties;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImp::SetProperties(const CFWL_WidgetImpProperties &properties)
+{
+ *m_pProperties = properties;
+ return FWL_ERR_Succeeded;
+}
+IFWL_Widget* CFWL_WidgetImp::GetInterface()
+{
+ return m_pInterface;
+}
+void CFWL_WidgetImp::SetInterface(IFWL_Widget *pInterface)
+{
+ m_pInterface = pInterface;
+}
+CFWL_WidgetImp::CFWL_WidgetImp(IFWL_Widget *pOuter )
+ : m_pProperties(NULL)
+ , m_pPrivateData(NULL)
+ , m_pDelegate(NULL)
+ , m_pCurDelegate(NULL)
+ , m_pOuter(pOuter)
+ , m_pInterface(NULL)
+ , m_iLock(0)
+{
+ m_pProperties = FX_NEW CFWL_WidgetImpProperties;
+ m_pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ FXSYS_assert(m_pWidgetMgr != NULL);
+}
+CFWL_WidgetImp::CFWL_WidgetImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : m_pProperties(NULL)
+ , m_pPrivateData(NULL)
+ , m_pDelegate(NULL)
+ , m_pCurDelegate(NULL)
+ , m_pOuter(pOuter)
+ , m_pInterface(NULL)
+ , m_iLock(0)
+{
+ if (!m_pProperties) {
+ m_pProperties = FX_NEW CFWL_WidgetImpProperties;
+ }
+ *m_pProperties = properties;
+ m_pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ FXSYS_assert(m_pWidgetMgr != NULL);
+}
+CFWL_WidgetImp::~CFWL_WidgetImp()
+{
+ if (m_pPrivateData) {
+ delete m_pPrivateData;
+ m_pPrivateData = NULL;
+ }
+ if (m_pProperties) {
+ delete m_pProperties;
+ m_pProperties = NULL;
+ }
+}
+FX_BOOL CFWL_WidgetImp::IsEnabled()
+{
+ return (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) == 0;
+}
+FX_BOOL CFWL_WidgetImp::IsVisible()
+{
+ return (m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) == 0;
+}
+FX_BOOL CFWL_WidgetImp::IsActive()
+{
+ return (m_pProperties->m_dwStates & FWL_WGTSTATE_Deactivated) == 0;
+}
+FX_BOOL CFWL_WidgetImp::IsOverLapper()
+{
+ return (m_pProperties->m_dwStyles & FWL_WGTSTYLE_WindowTypeMask) == FWL_WGTSTYLE_OverLapper;
+}
+FX_BOOL CFWL_WidgetImp::IsPopup()
+{
+ return m_pProperties->m_dwStyles & FWL_WGTSTYLE_Popup;
+}
+FX_BOOL CFWL_WidgetImp::IsChild()
+{
+ return m_pProperties->m_dwStyles & FWL_WGTSTYLE_Child;
+}
+FX_BOOL CFWL_WidgetImp::IsLocked()
+{
+ return m_iLock > 0;
+}
+FX_BOOL CFWL_WidgetImp::IsOffscreen()
+{
+ return m_pProperties->m_dwStyles & FWL_WGTSTYLE_Offscreen;
+}
+FX_BOOL CFWL_WidgetImp::HasBorder()
+{
+ return m_pProperties->m_dwStyles & FWL_WGTSTYLE_Border;
+}
+FX_BOOL CFWL_WidgetImp::HasEdge()
+{
+ return m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask;
+}
+void CFWL_WidgetImp::GetEdgeRect(CFX_RectF &rtEdge)
+{
+ rtEdge = m_pProperties->m_rtWidget;
+ rtEdge.left = rtEdge.top = 0;
+ if (HasBorder()) {
+ FX_FLOAT fCX = GetBorderSize();
+ FX_FLOAT fCY = GetBorderSize(FALSE);
+ rtEdge.Deflate(fCX, fCY);
+ }
+}
+FX_FLOAT CFWL_WidgetImp::GetBorderSize(FX_BOOL bCX )
+{
+ FX_FLOAT *pfBorder = (FX_FLOAT*)GetThemeCapacity(bCX ? FWL_WGTCAPACITY_CXBorder : FWL_WGTCAPACITY_CYBorder);
+ _FWL_RETURN_VALUE_IF_FAIL(pfBorder, 0);
+ return *pfBorder;
+}
+FX_FLOAT CFWL_WidgetImp::GetEdgeWidth()
+{
+ FX_DWORD dwCapacity = 0;
+ switch(m_pProperties->m_dwStyles & FWL_WGTSTYLE_EdgeMask) {
+ case FWL_WGTSTYLE_EdgeFlat: {
+ dwCapacity = FWL_WGTCAPACITY_EdgeFlat;
+ break;
+ }
+ case FWL_WGTSTYLE_EdgeRaised: {
+ dwCapacity = FWL_WGTCAPACITY_EdgeRaised;
+ break;
+ }
+ case FWL_WGTSTYLE_EdgeSunken: {
+ dwCapacity = FWL_WGTCAPACITY_EdgeSunken;
+ break;
+ }
+ }
+ if (dwCapacity > 0) {
+ FX_FLOAT *fRet = (FX_FLOAT*)GetThemeCapacity(dwCapacity);
+ _FWL_RETURN_VALUE_IF_FAIL(fRet, 0);
+ return *fRet;
+ }
+ return 0;
+}
+void CFWL_WidgetImp::GetRelativeRect(CFX_RectF &rect)
+{
+ rect = m_pProperties->m_rtWidget;
+ rect.left = rect.top = 0;
+}
+FX_LPVOID CFWL_WidgetImp::GetThemeCapacity(FX_DWORD dwCapacity)
+{
+ IFWL_ThemeProvider *pTheme = GetAvailableTheme();
+ _FWL_RETURN_VALUE_IF_FAIL(pTheme, NULL);
+ CFWL_ThemePart part;
+ part.m_pWidget = m_pInterface;
+ return pTheme->GetCapacity(&part, dwCapacity);
+}
+IFWL_ThemeProvider* CFWL_WidgetImp::GetAvailableTheme()
+{
+ if (m_pProperties->m_pThemeProvider) {
+ return m_pProperties->m_pThemeProvider;
+ }
+ IFWL_Widget *pUp = m_pInterface;
+ do {
+ FWL_WGTRELATION relation = (pUp->GetStyles() & FWL_WGTSTYLE_Popup)
+ ? FWL_WGTRELATION_Owner : FWL_WGTRELATION_Parent;
+ pUp = m_pWidgetMgr->GetWidget(pUp, relation);
+ if (pUp) {
+ IFWL_ThemeProvider *pRet = pUp->GetThemeProvider();
+ if (pRet && pRet->IsValidWidget(m_pInterface)) {
+ return pRet;
+ }
+ }
+ } while (pUp);
+ return ((CFWL_AppImp*)FWL_GetApp())->GetThemeProvider();
+}
+CFWL_WidgetImp* CFWL_WidgetImp::GetRootOuter()
+{
+ IFWL_Widget *pRet = m_pOuter;
+ IFWL_Widget *pOuter = pRet;
+ while (pOuter) {
+ pRet = pOuter;
+ pOuter = pOuter->GetOuter();
+ }
+ return (CFWL_WidgetImp*)pRet;
+}
+CFWL_WidgetImp* CFWL_WidgetImp::GetSameAncestor(CFWL_WidgetImp *pWidget)
+{
+ CFX_PtrArray arr1, arr2;
+ CFWL_WidgetImp *pAncestor = pWidget;
+ FWL_WGTRELATION relation;
+ do {
+ arr1.Add(pAncestor);
+ relation = pAncestor->IsPopup() ? FWL_WGTRELATION_Owner : FWL_WGTRELATION_Parent;
+ } while ((pAncestor = (CFWL_WidgetImp*)m_pWidgetMgr->GetWidget(pAncestor->m_pInterface, relation)) != NULL);
+ pAncestor = this;
+ do {
+ arr2.Add(pAncestor);
+ relation = pAncestor->IsPopup() ? FWL_WGTRELATION_Owner : FWL_WGTRELATION_Parent;
+ } while ((pAncestor = (CFWL_WidgetImp*)m_pWidgetMgr->GetWidget(pAncestor->m_pInterface, relation)) != NULL);
+ for (FX_INT32 i = 0; i < arr1.GetSize(); i ++) {
+ FX_LPVOID pVoid = arr1[i];
+ if (arr2.Find(pVoid) < 0) {
+ continue;
+ } else {
+ return (CFWL_WidgetImp*)pVoid;
+ }
+ }
+ return NULL;
+}
+CFX_SizeF CFWL_WidgetImp::GetOffsetFromAncestor(CFWL_WidgetImp *pAncestor)
+{
+ CFX_SizeF szRet;
+ szRet.Set(0, 0);
+ if (pAncestor == this) {
+ return szRet;
+ }
+ CFWL_WidgetImp *pWidget = this;
+ do {
+ CFX_RectF rect;
+ pWidget->GetWidgetRect(rect);
+ szRet.x += rect.left;
+ szRet.y += rect.top;
+ FWL_WGTRELATION relation = pWidget->IsPopup() ? FWL_WGTRELATION_Owner : FWL_WGTRELATION_Parent;
+ pWidget = (CFWL_WidgetImp*)m_pWidgetMgr->GetWidget((IFWL_Widget*)pWidget, relation);
+ } while(pWidget && pWidget != pAncestor);
+ return szRet;
+}
+FX_BOOL CFWL_WidgetImp::TransformToOuter(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pOuter, FALSE);
+ fx += m_pProperties->m_rtWidget.left;
+ fx += m_pProperties->m_rtWidget.top;
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetImp::TransformFromOuter(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pOuter, FALSE);
+ CFX_RectF rect;
+ m_pOuter->GetWidgetRect(rect);
+ fx -= rect.left;
+ fx -= rect.top;
+ return TRUE;
+}
+#define FWL_WGT_CalcHeight 2048
+#define FWL_WGT_CalcWidth 2048
+#define FWL_WGT_CalcMultiLineDefWidth 120.0f
+CFX_SizeF CFWL_WidgetImp::CalcTextSize(const CFX_WideString &wsText, IFWL_ThemeProvider *pTheme, FX_BOOL bMultiLine , FX_INT32 iLineWidth )
+{
+ CFX_SizeF sz;
+ sz.Set(0, 0);
+ _FWL_RETURN_VALUE_IF_FAIL(pTheme, sz);
+ CFWL_ThemeText calPart;
+ calPart.m_pWidget = m_pInterface;
+ calPart.m_wsText = wsText;
+ calPart.m_dwTTOStyles = bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
+ calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
+ CFX_RectF rect;
+ FX_FLOAT fWidth = bMultiLine ?
+ (iLineWidth > 0 ? (FX_FLOAT)iLineWidth : FWL_WGT_CalcMultiLineDefWidth) :
+ FWL_WGT_CalcWidth;
+ rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight);
+ pTheme->CalcTextRect(&calPart, rect);
+ sz.x = rect.width;
+ sz.y = rect.height;
+ return sz;
+}
+void CFWL_WidgetImp::CalcTextRect(const CFX_WideString &wsText, IFWL_ThemeProvider *pTheme, FX_DWORD dwTTOStyles, FX_INT32 iTTOAlign, CFX_RectF &rect)
+{
+ CFWL_ThemeText calPart;
+ calPart.m_pWidget = m_pInterface;
+ calPart.m_wsText = wsText;
+ calPart.m_dwTTOStyles = dwTTOStyles;
+ calPart.m_iTTOAlign = iTTOAlign;
+ pTheme->CalcTextRect(&calPart, rect);
+}
+void CFWL_WidgetImp::SetFocus(FX_BOOL bFocus)
+{
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return;
+ }
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ IFWL_NoteDriver *pDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pDriver);
+ IFWL_Widget *curFocus = ((CFWL_NoteDriver*)pDriver)->GetFocus();
+ if (bFocus && curFocus != m_pInterface) {
+ pDriver->SetFocus(m_pInterface);
+ } else if (!bFocus && curFocus == m_pInterface) {
+ pDriver->SetFocus(NULL);
+ }
+}
+void CFWL_WidgetImp::SetGrab(FX_BOOL bSet)
+{
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ pDriver->SetGrab(m_pInterface, bSet);
+}
+FX_BOOL CFWL_WidgetImp::GetPopupPos(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ if (GetClassID() == FWL_CLASSHASH_Menu) {
+ return GetPopupPosMenu(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
+ } else {
+ if (GetClassID() == FWL_CLASSHASH_ComboBox) {
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight, fMaxHeight, rtAnchor, rtPopup);
+ } else {
+ return GetPopupPosComboBox(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
+ }
+ } else if (GetClassID() == FWL_CLASSHASH_DateTimePicker && m_pWidgetMgr->IsFormDisabled()) {
+ return m_pWidgetMgr->GetAdapterPopupPos(m_pInterface, fMinHeight, fMaxHeight, rtAnchor, rtPopup);
+ } else {
+ return GetPopupPosGeneral(fMinHeight, fMaxHeight, rtAnchor, rtPopup);
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CFWL_WidgetImp::GetPopupPosMenu(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ FX_FLOAT fx = 0;
+ FX_FLOAT fy = 0;
+ FX_FLOAT fScreenWidth = 0;
+ FX_FLOAT fScreenHeight = 0;
+ GetScreenSize(fScreenWidth, fScreenHeight);
+ if (GetStylesEx() & FWL_STYLEEXT_MNU_Vert) {
+ FX_BOOL bLeft = m_pProperties->m_rtWidget.left < 0;
+ FX_FLOAT fRight = rtAnchor.right() + rtPopup.width;
+ TransformTo(NULL, fx, fy);
+ if (fRight + fx > fScreenWidth || bLeft) {
+ rtPopup.Set(rtAnchor.left - rtPopup.width, rtAnchor.top, rtPopup.width, rtPopup.height);
+ } else {
+ rtPopup.Set(rtAnchor.right(), rtAnchor.top, rtPopup.width, rtPopup.height);
+ }
+ } else {
+ FX_FLOAT fBottom = rtAnchor.bottom() + rtPopup.height;
+ TransformTo(NULL, fx, fy);
+ if (fBottom + fy > fScreenHeight) {
+ rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, rtPopup.height);
+ } else {
+ rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, rtPopup.height);
+ }
+ }
+ rtPopup.Offset(fx, fy);
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetImp::GetPopupPosComboBox(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ FX_FLOAT fx = 0;
+ FX_FLOAT fy = 0;
+ FX_FLOAT fScreenWidth = 0;
+ FX_FLOAT fScreenHeight = 0;
+ GetScreenSize(fScreenWidth, fScreenHeight);
+ FX_FLOAT fPopHeight = rtPopup.height;
+ if (rtPopup.height > fMaxHeight) {
+ fPopHeight = fMaxHeight;
+ } else if (rtPopup.height < fMinHeight) {
+ fPopHeight = fMinHeight;
+ }
+ FX_FLOAT fWidth = FX_MAX(rtAnchor.width, rtPopup.width);
+ FX_FLOAT fBottom = rtAnchor.bottom() + fPopHeight;
+ TransformTo(NULL, fx, fy);
+ if (fBottom + fy > fScreenHeight) {
+ rtPopup.Set(rtAnchor.left, rtAnchor.top - fPopHeight, fWidth, fPopHeight);
+ } else {
+ rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), fWidth, fPopHeight);
+ }
+ rtPopup.Offset(fx, fy);
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetImp::GetPopupPosGeneral(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ FX_FLOAT fx = 0;
+ FX_FLOAT fy = 0;
+ FX_FLOAT fScreenWidth = 0;
+ FX_FLOAT fScreenHeight = 0;
+ GetScreenSize(fScreenWidth, fScreenHeight);
+ TransformTo(NULL, fx, fy);
+ if (rtAnchor.bottom() + fy > fScreenHeight) {
+ rtPopup.Set(rtAnchor.left, rtAnchor.top - rtPopup.height, rtPopup.width, rtPopup.height);
+ } else {
+ rtPopup.Set(rtAnchor.left, rtAnchor.bottom(), rtPopup.width, rtPopup.height);
+ }
+ rtPopup.Offset(fx, fy);
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetImp::GetScreenSize(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ IFWL_AdapterNative *pNative = FWL_GetAdapterNative();
+ IFWL_AdapterMonitorMgr *pMonitorMgr = pNative->GetMonitorMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pMonitorMgr, FALSE);
+ FWL_HMONITOR hMonitor = pMonitorMgr->GetMonitorByPoint(fx, fy);
+ pMonitorMgr->GetMonitorSize(hMonitor, fx, fy);
+ return TRUE;
+}
+void CFWL_WidgetImp::RegisterEventTarget(IFWL_Widget *pEventSource , FX_DWORD dwFilter )
+{
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ IFWL_NoteDriver *pNoteDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pNoteDriver);
+ pNoteDriver->RegisterEventTarget(m_pInterface, pEventSource, dwFilter);
+}
+void CFWL_WidgetImp::UnregisterEventTarget()
+{
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ IFWL_NoteDriver *pNoteDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pNoteDriver);
+ pNoteDriver->UnregisterEventTarget(m_pInterface);
+}
+void CFWL_WidgetImp::DispatchKeyEvent(CFWL_MsgKey *pNote)
+{
+ _FWL_RETURN_IF_FAIL(pNote);
+ CFWL_MsgKey *pEvent = (CFWL_MsgKey*)pNote->CloneToEvent();
+ pEvent->m_pSrcTarget = m_pInterface;
+ pEvent->m_dwCmd = pNote->m_dwCmd;
+ pEvent->m_dwKeyCode = pNote->m_dwKeyCode;
+ pEvent->m_dwFlags = pNote->m_dwFlags;
+ DispatchEvent((CFWL_Event*)pEvent);
+ pEvent->Release();
+}
+void CFWL_WidgetImp::DispatchEvent(CFWL_Event *pEvent)
+{
+ if (m_pOuter) {
+ IFWL_WidgetDelegate *pDelegate = m_pOuter->SetDelegate(NULL);
+ pDelegate->OnProcessEvent(pEvent);
+ return;
+ }
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ IFWL_NoteDriver *pNoteDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pNoteDriver);
+ pNoteDriver->SendNote(pEvent);
+}
+void CFWL_WidgetImp::Repaint(const CFX_RectF *pRect )
+{
+ if (pRect) {
+ m_pWidgetMgr->RepaintWidget(m_pInterface, pRect);
+ return ;
+ }
+ CFX_RectF rect;
+ rect = m_pProperties->m_rtWidget;
+ rect.left = rect.top = 0;
+ m_pWidgetMgr->RepaintWidget(m_pInterface, &rect);
+}
+void CFWL_WidgetImp::DrawBackground(CFX_Graphics *pGraphics,
+ FX_INT32 iPartBk,
+ IFWL_ThemeProvider *pTheme,
+ const CFX_Matrix *pMatrix )
+{
+ CFX_RectF rtRelative;
+ GetRelativeRect(rtRelative);
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = iPartBk;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix, TRUE);
+ }
+ param.m_rtPart = rtRelative;
+ pTheme->DrawBackground(&param);
+}
+void CFWL_WidgetImp::DrawBorder(CFX_Graphics *pGraphics,
+ FX_INT32 iPartBorder,
+ IFWL_ThemeProvider *pTheme,
+ const CFX_Matrix *pMatrix )
+{
+ CFX_RectF rtRelative;
+ GetRelativeRect(rtRelative);
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = iPartBorder;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix, TRUE);
+ }
+ param.m_rtPart = rtRelative;
+ pTheme->DrawBackground(&param);
+}
+void CFWL_WidgetImp::DrawEdge(CFX_Graphics *pGraphics,
+ FX_INT32 iPartEdge,
+ IFWL_ThemeProvider *pTheme,
+ const CFX_Matrix *pMatrix )
+{
+ CFX_RectF rtEdge;
+ GetEdgeRect(rtEdge);
+ CFWL_ThemeBackground param;
+ param.m_pWidget = m_pInterface;
+ param.m_iPart = iPartEdge;
+ param.m_pGraphics = pGraphics;
+ if (pMatrix) {
+ param.m_matrix.Concat(*pMatrix, TRUE);
+ }
+ param.m_rtPart = rtEdge;
+ pTheme->DrawBackground(&param);
+}
+void CFWL_WidgetImp::NotifyDriver()
+{
+ IFWL_NoteThread *pThread = GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pDriver);
+ pDriver->NotifyTargetDestroy(m_pInterface);
+}
+CFX_SizeF CFWL_WidgetImp::GetOffsetFromParent(IFWL_Widget *pParent)
+{
+ CFX_SizeF szRet;
+ szRet.Set(0, 0);
+ if (pParent == (IFWL_Widget*)this) {
+ return szRet;
+ }
+ IFWL_WidgetMgr *pWidgetMgr = FWL_GetWidgetMgr();
+ _FWL_RETURN_VALUE_IF_FAIL(pWidgetMgr, szRet);
+ szRet.x += m_pProperties->m_rtWidget.left;
+ szRet.y += m_pProperties->m_rtWidget.top;
+ IFWL_Widget *pDstWidget = GetParent();
+ while (pDstWidget && pDstWidget != pParent) {
+ CFX_RectF rtDst;
+ pDstWidget->GetWidgetRect(rtDst);
+ szRet.x += rtDst.left;
+ szRet.y += rtDst.top;
+ pDstWidget = pWidgetMgr->GetWidget(pDstWidget, FWL_WGTRELATION_Parent);
+ }
+ return szRet;
+}
+FX_BOOL CFWL_WidgetImp::IsParent(IFWL_Widget *pParent)
+{
+ if (pParent == (IFWL_Widget*)this) {
+ return FALSE;
+ }
+ IFWL_Widget *pUpWidget = GetParent();
+ while (pUpWidget) {
+ if (pUpWidget == pParent) {
+ return TRUE;
+ }
+ pUpWidget = pUpWidget->GetParent();
+ }
+ return FALSE;
+}
+CFWL_WidgetImpDelegate::CFWL_WidgetImpDelegate()
+{
+}
+FX_INT32 CFWL_WidgetImpDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage->m_pDstTarget, 0);
+ CFWL_WidgetImp *pWidget = (CFWL_WidgetImp*)((IFWL_TargetData*)pMessage->m_pDstTarget)->GetData();
+ FX_DWORD dwMsgCode = pMessage->GetClassID();
+ switch (dwMsgCode) {
+ case FWL_MSGHASH_Mouse: {
+ CFWL_EvtMouse evt;
+ evt.m_pSrcTarget = pWidget->m_pInterface;
+ evt.m_pDstTarget = pWidget->m_pInterface;
+ evt.m_dwCmd = ((CFWL_MsgMouse*)pMessage)->m_dwCmd;
+ evt.m_dwFlags = ((CFWL_MsgMouse*)pMessage)->m_dwFlags;
+ evt.m_fx = ((CFWL_MsgMouse*)pMessage)->m_fx;
+ evt.m_fy = ((CFWL_MsgMouse*)pMessage)->m_fy;
+ pWidget->DispatchEvent(&evt);
+ break;
+ }
+ case FWL_MSGHASH_MouseWheel: {
+ CFWL_EvtMouseWheel evt;
+ evt.m_pSrcTarget = pWidget->m_pInterface;
+ evt.m_pDstTarget = pWidget->m_pInterface;
+ evt.m_dwFlags = ((CFWL_MsgMouseWheel*)pMessage)->m_dwFlags;
+ evt.m_fDeltaX = ((CFWL_MsgMouseWheel*)pMessage)->m_fDeltaX;
+ evt.m_fDeltaY = ((CFWL_MsgMouseWheel*)pMessage)->m_fDeltaY;
+ evt.m_fx = ((CFWL_MsgMouseWheel*)pMessage)->m_fx;
+ evt.m_fy = ((CFWL_MsgMouseWheel*)pMessage)->m_fy;
+ pWidget->DispatchEvent(&evt);
+ break;
+ }
+ case FWL_MSGHASH_Key: {
+ CFWL_EvtKey evt;
+ evt.m_pSrcTarget = pWidget->m_pInterface;;
+ evt.m_pDstTarget = pWidget->m_pInterface;;
+ evt.m_dwKeyCode = ((CFWL_MsgKey*)pMessage)->m_dwKeyCode;
+ evt.m_dwFlags = ((CFWL_MsgKey*)pMessage)->m_dwFlags;
+ evt.m_dwCmd = ((CFWL_MsgKey*)pMessage)->m_dwCmd;
+ pWidget->DispatchEvent(&evt);
+ break;
+ }
+ case FWL_MSGHASH_SetFocus: {
+ CFWL_EvtSetFocus evt;
+ evt.m_pSrcTarget = ((CFWL_MsgSetFocus*)pMessage)->m_pDstTarget;
+ evt.m_pDstTarget = ((CFWL_MsgSetFocus*)pMessage)->m_pDstTarget;
+ evt.m_pSetFocus = pWidget->m_pInterface;
+ pWidget->DispatchEvent(&evt);
+ break;
+ }
+ case FWL_MSGHASH_KillFocus: {
+ CFWL_EvtKillFocus evt;
+ evt.m_pSrcTarget = ((CFWL_MsgKillFocus*)pMessage)->m_pDstTarget;
+ evt.m_pDstTarget = ((CFWL_MsgKillFocus*)pMessage)->m_pDstTarget;
+ evt.m_pKillFocus = pWidget->m_pInterface;
+ pWidget->DispatchEvent(&evt);
+ break;
+ }
+ default: {
+ }
+ }
+ return 1;
+}
+FWL_ERR CFWL_WidgetImpDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetImpDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ CFWL_EvtDraw evt;
+ evt.m_pGraphics = pGraphics;
+ return FWL_ERR_Succeeded;
+}
+class CFWL_Custom : public CFWL_WidgetImp
+{
+public:
+ CFWL_Custom(IFWL_Widget *pOuter = NULL);
+ CFWL_Custom(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR SetProxy(IFWL_Proxy *pProxy);
+protected:
+ IFWL_Proxy *m_pProxy;
+};
+CFWL_Custom::CFWL_Custom(IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(pOuter)
+ , m_pProxy(NULL)
+{
+}
+CFWL_Custom::CFWL_Custom(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+ : CFWL_WidgetImp(properties, pOuter)
+ , m_pProxy(NULL)
+{
+}
+FWL_ERR CFWL_Custom::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ if (m_pProxy && (m_pProxy->GetWidgetRect(rect, bAutoSize) == FWL_ERR_Succeeded)) {
+ return FWL_ERR_Succeeded;
+ }
+ return CFWL_WidgetImp::GetWidgetRect(rect, bAutoSize);
+}
+FWL_ERR CFWL_Custom::Update()
+{
+ if (m_pProxy) {
+ return m_pProxy->Update();
+ }
+ return CFWL_WidgetImp::Update();
+}
+FWL_ERR CFWL_Custom::SetProxy(IFWL_Proxy *pProxy)
+{
+ m_pProxy = pProxy;
+ return FWL_ERR_Succeeded;
+}
+IFWL_Custom* IFWL_Custom::Create()
+{
+ return new IFWL_Custom;
+}
+IFWL_Custom::IFWL_Custom()
+{
+ m_pData = NULL;
+}
+IFWL_Custom::~IFWL_Custom()
+{
+ if (m_pData) {
+ delete (CFWL_Custom*)m_pData;
+ m_pData = NULL;
+ }
+}
+FWL_ERR IFWL_Custom::Initialize(IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_Custom(pOuter);
+ ((CFWL_Custom*)m_pData)->SetInterface(this);
+ return ((CFWL_Custom*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Custom::Initialize(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter )
+{
+ m_pData = FX_NEW CFWL_Custom(properties, pOuter);
+ ((CFWL_Custom*)m_pData)->SetInterface(this);
+ return ((CFWL_Custom*)m_pData)->Initialize();
+}
+FWL_ERR IFWL_Custom::SetProxy(IFWL_Proxy *pProxy)
+{
+ return ((CFWL_Custom*)m_pData)->SetProxy(pProxy);
+}
+void FWL_SetWidgetRect(IFWL_Widget *widget, const CFX_RectF &rect)
+{
+ ((CFWL_WidgetImp*)((IFWL_TargetData*)widget)->GetData())->m_pProperties->m_rtWidget = rect;
+}
+void FWL_SetWidgetStates(IFWL_Widget *widget, FX_DWORD dwStates)
+{
+ ((CFWL_WidgetImp*)((IFWL_TargetData*)widget)->GetData())->m_pProperties->m_dwStates = dwStates;
+}
+void FWL_SetWidgetStyles(IFWL_Widget *widget, FX_DWORD dwStyles)
+{
+ ((CFWL_WidgetImp*)((IFWL_TargetData*)widget)->GetData())->m_pProperties->m_dwStyles = dwStyles;
+}
+FWL_ERR FWL_EnabelWidget(IFWL_Widget *widget, FX_BOOL bEnable)
+{
+ widget->SetStates(FWL_WGTSTATE_Disabled, !bEnable);
+ IFWL_WidgetMgr *widgetMgr = FWL_GetWidgetMgr();
+ IFWL_Widget *child = widgetMgr->GetWidget(widget, FWL_WGTRELATION_FirstChild);
+ while (child) {
+ FWL_EnabelWidget(child, bEnable);
+ child = widgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ }
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fwl/src/core/fwl_widgetmgrimp.cpp b/xfa/src/fwl/src/core/fwl_widgetmgrimp.cpp
new file mode 100644
index 0000000000..b5e2547722
--- /dev/null
+++ b/xfa/src/fwl/src/core/fwl_widgetmgrimp.cpp
@@ -0,0 +1,1054 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "include/fwl_targetimp.h"
+#include "include/fwl_noteimp.h"
+#include "include/fwl_widgetmgrimp.h"
+#include "include/fwl_threadimp.h"
+#include "include/fwl_appimp.h"
+#define FWL_NORMALMATRIX
+FX_BOOL FWL_UseOffscreen(IFWL_Widget * pWidget)
+{
+#if (_FX_OS_==_FX_MACOSX_)
+ return FALSE;
+#else
+ return pWidget->GetStyles() & FWL_WGTSTYLE_Offscreen;
+#endif
+}
+IFWL_WidgetMgr* FWL_GetWidgetMgr()
+{
+ IFWL_App *pApp = FWL_GetApp();
+ _FWL_RETURN_VALUE_IF_FAIL(pApp, NULL);
+ return pApp->GetWidgetMgr();
+}
+CFWL_WidgetMgr::CFWL_WidgetMgr(IFWL_AdapterNative *pAdapterNative)
+ : m_dwCapability(0)
+{
+ m_pDelegate = FX_NEW CFWL_WidgetMgrDelegate(this);
+ m_pAdapter = pAdapterNative->GetWidgetMgr((IFWL_WidgetMgrDelegate*)m_pDelegate);
+ FXSYS_assert(m_pAdapter);
+ CFWL_WidgetMgrItem *pRoot = FX_NEW CFWL_WidgetMgrItem;
+ m_mapWidgetItem.SetAt(NULL, pRoot);
+#if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
+ m_rtScreen.Reset();
+ IFWL_AdapterMonitorMgr* pMonitorMgr = pAdapterNative->GetMonitorMgr();
+ if (pMonitorMgr) {
+ FWL_HMONITOR monitor = pMonitorMgr->GetCurrentMonitor();
+ if (monitor) {
+ pMonitorMgr->GetMonitorSize(monitor, m_rtScreen.width, m_rtScreen.height);
+ }
+ }
+#endif
+}
+CFWL_WidgetMgr::~CFWL_WidgetMgr()
+{
+ FX_POSITION ps = m_mapWidgetItem.GetStartPosition();
+ while (ps) {
+ FX_LPVOID pWidget;
+ CFWL_WidgetMgrItem *pItem;
+ m_mapWidgetItem.GetNextAssoc(ps, pWidget, (void*&)pItem);
+ delete pItem;
+ }
+ m_mapWidgetItem.RemoveAll();
+ if (m_pDelegate) {
+ delete m_pDelegate;
+ m_pDelegate = NULL;
+ }
+}
+FX_INT32 CFWL_WidgetMgr::CountWidgets(IFWL_Widget *pParent )
+{
+ CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
+ return TravelWidgetMgr(pParentItem, NULL, NULL);
+}
+IFWL_Widget* CFWL_WidgetMgr::GetWidget(FX_INT32 nIndex, IFWL_Widget *pParent )
+{
+ CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
+ IFWL_Widget *pWidget = NULL;
+ TravelWidgetMgr(pParentItem, &nIndex, NULL, &pWidget);
+ return pWidget;
+}
+IFWL_Widget* CFWL_WidgetMgr::GetWidget(IFWL_Widget *pWidget, FWL_WGTRELATION eRelation)
+{
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ if (!pItem) {
+ return NULL;
+ }
+ IFWL_Widget *pRet = NULL;
+ switch (eRelation) {
+ case FWL_WGTRELATION_Parent: {
+ pRet = pItem->pParent ? pItem->pParent->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_Owner: {
+ pRet = pItem->pOwner ? pItem->pOwner->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_FirstSibling: {
+ pItem = pItem->pPrevious;
+ while (pItem && pItem->pPrevious) {
+ pItem = pItem->pPrevious;
+ }
+ pRet = pItem ? pItem->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_PriorSibling: {
+ pRet = pItem->pPrevious ? pItem->pPrevious->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_NextSibling: {
+ pRet = pItem->pNext ? pItem->pNext->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_LastSibling: {
+ pItem = pItem->pNext;
+ while (pItem && pItem->pNext) {
+ pItem = pItem->pNext;
+ }
+ pRet = pItem ? pItem->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_FirstChild: {
+ pRet = pItem->pChild ? pItem->pChild->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_LastChild: {
+ pItem = pItem->pChild;
+ while (pItem && pItem->pNext) {
+ pItem = pItem->pNext;
+ }
+ pRet = pItem ? pItem->pWidget : NULL;
+ break;
+ }
+ case FWL_WGTRELATION_SystemForm: {
+ while (pItem) {
+ if (IsAbleNative(pItem->pWidget)) {
+ pRet = pItem->pWidget;
+ break;
+ }
+ pItem = pItem->pParent;
+ }
+ break;
+ }
+ default: {
+ }
+ }
+ return pRet;
+}
+FX_INT32 CFWL_WidgetMgr::GetWidgetIndex(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ _FWL_RETURN_VALUE_IF_FAIL(pItem, -1);
+ return TravelWidgetMgr(pItem->pParent, NULL, pItem);
+}
+FX_BOOL CFWL_WidgetMgr::SetWidgetIndex(IFWL_Widget *pWidget, FX_INT32 nIndex)
+{
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ _FWL_RETURN_VALUE_IF_FAIL(pItem, FALSE);
+ _FWL_RETURN_VALUE_IF_FAIL(pItem->pParent, FALSE);
+ CFWL_WidgetMgrItem *pChild = pItem->pParent->pChild;
+ FX_INT32 i = 0;
+ while (pChild) {
+ if (pChild == pItem) {
+ if (i == nIndex) {
+ return TRUE;
+ }
+ if (pChild->pPrevious) {
+ pChild->pPrevious->pNext = pChild->pNext;
+ }
+ if (pChild->pNext) {
+ pChild->pNext->pPrevious = pChild->pPrevious;
+ }
+ if (pItem->pParent->pChild == pItem) {
+ pItem->pParent->pChild = pItem->pNext;
+ }
+ pItem->pNext = NULL;
+ pItem->pPrevious = NULL;
+ break;
+ }
+ if(!pChild->pNext) {
+ break;
+ }
+ pChild = pChild->pNext;
+ ++i;
+ }
+ pChild = pItem->pParent->pChild;
+ if (pChild) {
+ if (nIndex < 0) {
+ while(pChild->pNext) {
+ pChild = pChild->pNext;
+ }
+ pChild->pNext = pItem;
+ pItem->pPrevious = pChild;
+ pItem->pNext = NULL;
+ return TRUE;
+ }
+ i = 0;
+ while(i < nIndex && pChild->pNext ) {
+ pChild = pChild->pNext;
+ ++i;
+ }
+ if (!pChild->pNext) {
+ pChild->pNext = pItem;
+ pItem->pPrevious = pChild;
+ pItem->pNext = NULL;
+ return TRUE;
+ }
+ if (pChild->pPrevious) {
+ pItem->pPrevious = pChild->pPrevious;
+ pChild->pPrevious->pNext = pItem;
+ }
+ pChild->pPrevious = pItem;
+ pItem->pNext = pChild;
+ if (pItem->pParent->pChild == pChild) {
+ pItem->pParent->pChild = pItem;
+ }
+ } else {
+ pItem->pParent->pChild = pItem;
+ pItem->pPrevious = NULL;
+ pItem->pNext = NULL;
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetMgr::IsWidget(FX_LPVOID pObj)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pObj, FALSE);
+ return GetWidgetMgrItem((IFWL_Widget*)pObj) != NULL;
+}
+FWL_ERR CFWL_WidgetMgr::RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pAdapter, FWL_ERR_Indefinite);
+ IFWL_Widget *pNative = pWidget;
+ CFX_RectF rect(*pRect);
+ if (IsFormDisabled()) {
+ IFWL_Widget *pOuter = pWidget->GetOuter();
+ while (pOuter) {
+ CFX_RectF rtTemp;
+ pNative->GetWidgetRect(rtTemp);
+ rect.left += rtTemp.left;
+ rect.top += rtTemp.top;
+ pNative = pOuter;
+ pOuter = pOuter->GetOuter();
+ }
+ } else if (!IsAbleNative(pWidget)) {
+ pNative = GetWidget(pWidget, FWL_WGTRELATION_SystemForm);
+ _FWL_RETURN_VALUE_IF_FAIL(pNative, FWL_ERR_Indefinite);
+ pWidget->TransformTo(pNative, rect.left, rect.top);
+ }
+ AddRedrawCounts(pNative);
+ return m_pAdapter->RepaintWidget(pNative, &rect);
+}
+void CFWL_WidgetMgr::AddWidget(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(NULL);
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ if (!pItem) {
+ pItem = FX_NEW CFWL_WidgetMgrItem;
+ pItem->pWidget = pWidget;
+ m_mapWidgetItem.SetAt(pWidget, pItem);
+ }
+ if (pItem->pParent && pItem->pParent != pParentItem) {
+ if (pItem->pPrevious) {
+ pItem->pPrevious->pNext = pItem->pNext;
+ }
+ if (pItem->pNext) {
+ pItem->pNext->pPrevious = pItem->pPrevious;
+ }
+ if (pItem->pParent->pChild == pItem) {
+ pItem->pParent->pChild = pItem->pNext;
+ }
+ }
+ pItem->pParent = pParentItem;
+ SetWidgetIndex(pWidget, -1);
+}
+void CFWL_WidgetMgr::InsertWidget(IFWL_Widget *pParent, IFWL_Widget *pChild, FX_INT32 nIndex )
+{
+ CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
+ if (!pParentItem) {
+ pParentItem = FX_NEW CFWL_WidgetMgrItem;
+ pParentItem->pWidget = pParent;
+ m_mapWidgetItem.SetAt(pParent, pParentItem);
+ CFWL_WidgetMgrItem *pRoot = GetWidgetMgrItem(NULL);
+ pParentItem->pParent = pRoot;
+ SetWidgetIndex(pParent, -1);
+ }
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pChild);
+ if (!pItem) {
+ pItem = FX_NEW CFWL_WidgetMgrItem;
+ pItem->pWidget = pChild;
+ m_mapWidgetItem.SetAt(pChild, pItem);
+ }
+ if (pItem->pParent && pItem->pParent != pParentItem) {
+ if (pItem->pPrevious) {
+ pItem->pPrevious->pNext = pItem->pNext;
+ }
+ if (pItem->pNext) {
+ pItem->pNext->pPrevious = pItem->pPrevious;
+ }
+ if (pItem->pParent->pChild == pItem) {
+ pItem->pParent->pChild = pItem->pNext;
+ }
+ }
+ pItem->pParent = pParentItem;
+ SetWidgetIndex(pChild, nIndex);
+}
+void CFWL_WidgetMgr::RemoveWidget(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ if (!pItem) {
+ return;
+ }
+ if (pItem->pPrevious) {
+ pItem->pPrevious->pNext = pItem->pNext;
+ }
+ if (pItem->pNext) {
+ pItem->pNext->pPrevious = pItem->pPrevious;
+ }
+ if (pItem->pParent && pItem->pParent->pChild == pItem) {
+ pItem->pParent->pChild = pItem->pNext;
+ }
+ CFWL_WidgetMgrItem *pChild = pItem->pChild;
+ while (pChild) {
+ CFWL_WidgetMgrItem *pNext = pChild->pNext;
+ RemoveWidget(pChild->pWidget);
+ pChild = pNext;
+ }
+ m_mapWidgetItem.RemoveKey(pWidget);
+ delete pItem;
+}
+void CFWL_WidgetMgr::SetOwner(IFWL_Widget *pOwner, IFWL_Widget *pOwned)
+{
+ CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pOwner);
+ if (!pParentItem) {
+ pParentItem = FX_NEW CFWL_WidgetMgrItem;
+ pParentItem->pWidget = pOwner;
+ m_mapWidgetItem.SetAt(pOwner, pParentItem);
+ CFWL_WidgetMgrItem *pRoot = GetWidgetMgrItem(NULL);
+ pParentItem->pParent = pRoot;
+ SetWidgetIndex(pOwner, -1);
+ }
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pOwned);
+ if (!pItem) {
+ pItem = FX_NEW CFWL_WidgetMgrItem;
+ pItem->pWidget = pOwned;
+ m_mapWidgetItem.SetAt(pOwned, pItem);
+ }
+ pItem->pOwner = pParentItem;
+}
+void CFWL_WidgetMgr::SetParent(IFWL_Widget *pParent, IFWL_Widget *pChild)
+{
+ CFWL_WidgetMgrItem *pParentItem = GetWidgetMgrItem(pParent);
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pChild);
+ _FWL_RETURN_IF_FAIL(pItem);
+ if (pItem->pParent && pItem->pParent != pParentItem) {
+ if (pItem->pPrevious) {
+ pItem->pPrevious->pNext = pItem->pNext;
+ }
+ if (pItem->pNext) {
+ pItem->pNext->pPrevious = pItem->pPrevious;
+ }
+ if (pItem->pParent->pChild == pItem) {
+ pItem->pParent->pChild = pItem->pNext;
+ }
+ pItem->pNext = NULL;
+ pItem->pPrevious = NULL;
+ }
+ pItem->pParent = pParentItem;
+ SetWidgetIndex(pChild, -1);
+ _FWL_RETURN_IF_FAIL(m_pAdapter);
+ m_pAdapter->SetParentWidget(pChild, pParent);
+}
+FX_BOOL CFWL_WidgetMgr::IsChild(IFWL_Widget *pChild, IFWL_Widget *pParent)
+{
+ IFWL_Widget *pTemp = pChild;
+ do {
+ if (pTemp == pParent) {
+ return TRUE;
+ }
+ pTemp = GetWidget(pTemp, FWL_WGTRELATION_Parent);
+ } while (pTemp);
+ return FALSE;
+}
+FWL_ERR CFWL_WidgetMgr::CreateWidget_Native(IFWL_Widget *pWidget)
+{
+ if (!IsAbleNative(pWidget)) {
+ return FWL_ERR_Succeeded;
+ }
+ return m_pAdapter->CreateWidget(pWidget, pWidget->GetOwner());
+}
+FWL_ERR CFWL_WidgetMgr::DestroyWidget_Native(IFWL_Widget *pWidget)
+{
+ if (!IsAbleNative(pWidget)) {
+ return FWL_ERR_Succeeded;
+ }
+ return m_pAdapter->DestroyWidget(pWidget);
+}
+FWL_ERR CFWL_WidgetMgr::GetWidgetRect_Native(IFWL_Widget *pWidget, CFX_RectF &rect)
+{
+ if (!IsAbleNative(pWidget)) {
+ return FWL_ERR_Succeeded;
+ }
+ return m_pAdapter->GetWidgetRect(pWidget, rect);
+}
+FWL_ERR CFWL_WidgetMgr::SetWidgetRect_Native(IFWL_Widget *pWidget, const CFX_RectF &rect)
+{
+ if (FWL_UseOffscreen(pWidget)) {
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ pItem->iRedrawCounter ++;
+ if (pItem->pOffscreen) {
+ CFX_RenderDevice *pDevice = pItem->pOffscreen->GetRenderDevice();
+ if (pDevice && pDevice->GetBitmap()) {
+ CFX_DIBitmap *pBitmap = pDevice->GetBitmap();
+ if (pBitmap->GetWidth() - rect.width > 1 || pBitmap->GetHeight() - rect.height > 1) {
+ delete pItem->pOffscreen;
+ pItem->pOffscreen = NULL;
+ }
+ }
+ }
+#if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
+ pItem->bOutsideChanged = !m_rtScreen.Contains(rect);
+#endif
+ }
+ return m_pAdapter->SetWidgetRect(pWidget, rect);
+}
+FWL_ERR CFWL_WidgetMgr::SetWidgetPosition_Native(IFWL_Widget *pWidget, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return m_pAdapter->SetWidgetPosition(pWidget, fx, fy);
+}
+FWL_ERR CFWL_WidgetMgr::SetWidgetIcon_Native(IFWL_Widget *pWidget, const CFX_DIBitmap *pIcon, FX_BOOL bBig)
+{
+ return m_pAdapter->SetWidgetIcon(pWidget, pIcon, bBig);
+}
+FWL_ERR CFWL_WidgetMgr::SetWidgetCaption_Native(IFWL_Widget *pWidget, FX_WSTR wsCaption)
+{
+ return m_pAdapter->SetWidgetCaption(pWidget, wsCaption);
+}
+FWL_ERR CFWL_WidgetMgr::SetBorderRegion_Native(IFWL_Widget *pWidget, CFX_Path *pPath)
+{
+ return m_pAdapter->SetBorderRegion(pWidget, pPath);
+}
+FWL_ERR CFWL_WidgetMgr::ShowWidget_Native(IFWL_Widget *pWidget)
+{
+ return m_pAdapter->ShowWidget(pWidget);
+}
+FWL_ERR CFWL_WidgetMgr::HideWidget_Native(IFWL_Widget *pWidget)
+{
+ return m_pAdapter->HideWidget(pWidget);
+}
+FWL_ERR CFWL_WidgetMgr::SetNormal_Native(IFWL_Widget *pWidget)
+{
+ return m_pAdapter->SetNormal(pWidget);
+}
+FWL_ERR CFWL_WidgetMgr::SetMaximize_Native(IFWL_Widget *pWidget)
+{
+ return m_pAdapter->SetMaximize(pWidget);
+}
+FWL_ERR CFWL_WidgetMgr::SetMinimize_Native(IFWL_Widget *pWidget)
+{
+ return m_pAdapter->SetMinimize(pWidget);
+}
+FX_BOOL CFWL_WidgetMgr::CheckMessage_Native()
+{
+ return m_pAdapter->CheckMessage();
+}
+FWL_ERR CFWL_WidgetMgr::DispatchMessage_Native()
+{
+ return m_pAdapter->DispatchMessage();
+}
+FX_BOOL CFWL_WidgetMgr::IsIdleMessage_Native()
+{
+ return m_pAdapter->IsIdleMessage();
+}
+FWL_ERR CFWL_WidgetMgr::Exit_Native(FX_INT32 iExitCode)
+{
+ return m_pAdapter->Exit(iExitCode);
+}
+FWL_ERR CFWL_WidgetMgr::CreateWidgetWithNativeId_Native(IFWL_Widget *pWidget, void *vp)
+{
+ return m_pAdapter->CreateWidgetWithNativeId(pWidget, vp);
+}
+IFWL_Widget* CFWL_WidgetMgr::GetWidgetAtPoint(IFWL_Widget * parent, FX_FLOAT x, FX_FLOAT y)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(parent, NULL);
+ FX_FLOAT x1;
+ FX_FLOAT y1;
+ IFWL_Widget * child = GetWidget(parent, FWL_WGTRELATION_LastChild);
+ while (child) {
+ if ((child->GetStates() & FWL_WGTSTATE_Invisible) == 0) {
+ x1 = x;
+ y1 = y;
+ CFX_Matrix matrixOnParent;
+ child->GetMatrix(matrixOnParent);
+ CFX_Matrix m;
+ m.Reset();
+ m.SetReverse(matrixOnParent);
+ m.TransformPoint(x1, y1);
+ CFX_RectF bounds;
+ child->GetWidgetRect(bounds);
+ if (bounds.Contains(x1, y1)) {
+ x1 -= bounds.left;
+ y1 -= bounds.top;
+ return GetWidgetAtPoint(child, x1, y1);
+ }
+ }
+ child = GetWidget(child, FWL_WGTRELATION_PriorSibling);
+ }
+ return parent;
+}
+void CFWL_WidgetMgr::NotifySizeChanged(IFWL_Widget *pForm, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!FWL_UseOffscreen(pForm)) {
+ return;
+ }
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pForm);
+ if (pItem->pOffscreen) {
+ delete pItem->pOffscreen;
+ pItem->pOffscreen = NULL;
+ }
+}
+IFWL_Widget* CFWL_WidgetMgr::nextTab(IFWL_Widget *parent, IFWL_Widget *focus, FX_BOOL &bFind)
+{
+ IFWL_Widget *child = FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
+ while (child) {
+ if (focus == child) {
+ bFind = TRUE;
+ }
+ if ((child->GetStyles() & FWL_WGTSTYLE_TabStop) && (!focus || (focus != child && bFind))) {
+ return child;
+ }
+ IFWL_Widget *bRet = nextTab(child, focus, bFind);
+ if (bRet) {
+ return bRet;
+ }
+ child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ }
+ return NULL;
+}
+FX_INT32 CFWL_WidgetMgr::CountRadioButtonGroup(IFWL_Widget *pFirst)
+{
+ FX_INT32 iRet = 0;
+ IFWL_Widget *pChild = pFirst;
+ while (pChild) {
+ if ((pChild->GetStyles() & FWL_WGTSTYLE_Group) && pChild->GetClassID() == 3811304691) {
+ iRet ++;
+ }
+ pChild = GetWidget(pChild, FWL_WGTRELATION_NextSibling);
+ }
+ return iRet;
+}
+IFWL_Widget* CFWL_WidgetMgr::GetSiblingRadioButton(IFWL_Widget *pWidget, FX_BOOL bNext)
+{
+ while ((pWidget = GetWidget(pWidget, bNext ? FWL_WGTRELATION_NextSibling : FWL_WGTRELATION_PriorSibling)) != NULL) {
+ if (pWidget->GetClassID() == 3811304691) {
+ return pWidget;
+ }
+ }
+ return NULL;
+}
+IFWL_Widget* CFWL_WidgetMgr::GetRadioButtonGroupHeader(IFWL_Widget *pRadioButton)
+{
+ if (pRadioButton->GetStyles() & FWL_WGTSTYLE_Group) {
+ return pRadioButton;
+ }
+ IFWL_Widget *pNext = pRadioButton;
+ while ((pNext = GetSiblingRadioButton(pNext, FALSE)) != NULL) {
+ if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
+ return pNext;
+ }
+ }
+ pNext = GetWidget(pRadioButton, FWL_WGTRELATION_LastSibling);
+ if ((pNext->GetStyles() & FWL_WGTSTYLE_Group) && pNext->GetClassID() == 3811304691) {
+ return pNext;
+ }
+ while ((pNext = GetSiblingRadioButton(pNext, FALSE)) && pNext && pNext != pRadioButton) {
+ if (pNext->GetStyles() & FWL_WGTSTYLE_Group) {
+ return pNext;
+ }
+ }
+ pNext = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
+ if (pNext && (pNext->GetStyles() == FWL_WGTSTYLE_Group) && pNext->GetClassID() == 3811304691) {
+ return pNext;
+ }
+ return GetSiblingRadioButton(pNext, TRUE);
+}
+void CFWL_WidgetMgr::GetSameGroupRadioButton(IFWL_Widget *pRadioButton, CFX_PtrArray &group)
+{
+ IFWL_Widget *pFirst = GetWidget(pRadioButton, FWL_WGTRELATION_FirstSibling);
+ if (!pFirst) {
+ pFirst = pRadioButton;
+ }
+ FX_INT32 iGroup = CountRadioButtonGroup(pFirst);
+ if (iGroup < 2) {
+ if (pFirst->GetClassID() == 3811304691) {
+ group.Add(pFirst);
+ }
+ IFWL_Widget *pNext = pFirst;
+ while ((pNext = GetSiblingRadioButton(pNext, TRUE)) != NULL) {
+ group.Add(pNext);
+ }
+ return;
+ }
+ IFWL_Widget *pNext = GetRadioButtonGroupHeader(pRadioButton);
+ do {
+ group.Add(pNext);
+ pNext = GetSiblingRadioButton(pNext, TRUE);
+ if (!pNext) {
+ if (pFirst->GetClassID() == 3811304691) {
+ pNext = pFirst;
+ } else {
+ pNext = GetSiblingRadioButton(pFirst, TRUE);
+ }
+ }
+ } while (pNext && ((pNext->GetStyles() & FWL_WGTSTYLE_Group) == 0));
+}
+IFWL_Widget* CFWL_WidgetMgr::GetDefaultButton(IFWL_Widget *pParent)
+{
+ if ((pParent->GetClassID() == 3521614244) && (pParent->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
+ return pParent;
+ }
+ IFWL_Widget *child = FWL_GetWidgetMgr()->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
+ while (child) {
+ if ((child->GetClassID() == 3521614244) && (child->GetStates() & (1 << (FWL_WGTSTATE_MAX + 2)))) {
+ return child;
+ }
+ IFWL_Widget *find = GetDefaultButton(child);
+ if (find) {
+ return find;
+ }
+ child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ }
+ return NULL;
+}
+void CFWL_WidgetMgr::AddRedrawCounts(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ (pItem->iRedrawCounter)++;
+}
+void CFWL_WidgetMgr::ResetRedrawCounts(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetMgrItem *pItem = GetWidgetMgrItem(pWidget);
+ pItem->iRedrawCounter = 0;
+}
+CFWL_WidgetMgrItem* CFWL_WidgetMgr::GetWidgetMgrItem(IFWL_Widget *pWidget)
+{
+ return (CFWL_WidgetMgrItem*)m_mapWidgetItem.GetValueAt(pWidget);
+}
+FX_INT32 CFWL_WidgetMgr::TravelWidgetMgr(CFWL_WidgetMgrItem *pParent, FX_INT32 *pIndex, CFWL_WidgetMgrItem *pItem, IFWL_Widget **pWidget )
+{
+ if (!pParent) {
+ return 0;
+ }
+ FX_INT32 iCount = 0;
+ CFWL_WidgetMgrItem *pChild = pParent->pChild;
+ while (pChild) {
+ iCount ++;
+ if (pIndex) {
+ if (*pIndex == 0) {
+ *pWidget = pChild->pWidget;
+ return iCount;
+ }
+ pIndex --;
+ }
+ if (pItem && pItem == pChild) {
+ return iCount - 1;
+ }
+ pChild = pChild->pNext;
+ }
+ if (pIndex) {
+ return 0;
+ } else if (pItem) {
+ return -1;
+ }
+ return iCount - 1;
+}
+FX_BOOL CFWL_WidgetMgr::IsAbleNative(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ if (!pWidget->IsInstance(FX_WSTRC(FWL_CLASS_Form))) {
+ return FALSE;
+ }
+ FX_DWORD dwStyles = pWidget->GetStyles();
+ return ((dwStyles & FWL_WGTSTYLE_WindowTypeMask) == FWL_WGTSTYLE_OverLapper) || (dwStyles & FWL_WGTSTYLE_Popup);
+}
+FX_BOOL CFWL_WidgetMgr::IsThreadEnabled()
+{
+ return !(m_dwCapability & FWL_WGTMGR_DisableThread);
+}
+FX_BOOL CFWL_WidgetMgr::IsFormDisabled()
+{
+ return m_dwCapability & FWL_WGTMGR_DisableForm;
+}
+FX_BOOL CFWL_WidgetMgr::GetAdapterPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ IFWL_AdapterWidgetMgr* pSDApapter = GetAdapterWidgetMgr();
+ return pSDApapter->GetPopupPos(pWidget, fMinHeight, fMaxHeight, rtAnchor, rtPopup);
+}
+CFWL_WidgetMgrDelegate::CFWL_WidgetMgrDelegate(CFWL_WidgetMgr *pWidgetMgr)
+ : m_pWidgetMgr(pWidgetMgr)
+{
+}
+FWL_ERR CFWL_WidgetMgrDelegate::OnSetCapability(FX_DWORD dwCapability )
+{
+ m_pWidgetMgr->m_dwCapability = dwCapability;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_WidgetMgrDelegate::OnProcessMessageToForm(CFWL_Message *pMessage)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage, 0);
+ _FWL_RETURN_VALUE_IF_FAIL(pMessage->m_pDstTarget, 0);
+ IFWL_Widget *pDstWidget = (IFWL_Widget*)pMessage->m_pDstTarget;
+ IFWL_NoteThread *pNoteThread = pDstWidget->GetOwnerThread();
+ _FWL_RETURN_VALUE_IF_FAIL(pNoteThread, 0);
+ CFWL_NoteDriver *pNoteDriver = (CFWL_NoteDriver*)pNoteThread->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(pNoteDriver, 0);
+ if (m_pWidgetMgr->IsThreadEnabled()) {
+ pMessage = (CFWL_Message*)pMessage->Clone();
+ }
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ pNoteDriver->ProcessMessage(pMessage);
+ } else {
+ pNoteDriver->QueueMessage(pMessage);
+ }
+#if (_FX_OS_==_FX_MACOSX_)
+ CFWL_NoteLoop *pTopLoop = pNoteDriver->GetTopLoop();
+ if (pTopLoop) {
+ pNoteDriver->UnqueueMessage(pTopLoop);
+ }
+#endif
+ if (m_pWidgetMgr->IsThreadEnabled()) {
+ pMessage->Release();
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetMgrDelegate::OnDrawWidget(IFWL_Widget * pWidget,
+ CFX_Graphics * pGraphics,
+ const CFX_Matrix * pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FWL_ERR_Indefinite);
+ _FWL_RETURN_VALUE_IF_FAIL(pGraphics, FWL_ERR_Indefinite);
+ CFX_Graphics *pTemp = DrawWidgetBefore(pWidget, pGraphics, pMatrix);
+ CFX_RectF clipCopy;
+ pWidget->GetWidgetRect(clipCopy);
+ clipCopy.left = clipCopy.top = 0;
+ if (bUseOffscreenDirect(pWidget)) {
+ DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
+ return FWL_ERR_Succeeded;
+ }
+ CFX_RectF clipBounds;
+#if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_) || (_FX_OS_ == _FX_LINUX_DESKTOP_) || (_FX_OS_ == _FX_LINUX_EMBEDDED_) || (_FX_OS_ == _FX_ANDROID_)
+ IFWL_WidgetDelegate *pDelegate = pWidget->SetDelegate(NULL);
+ pDelegate->OnDrawWidget(pTemp, pMatrix);
+ pGraphics->GetClipRect(clipBounds);
+ clipCopy = clipBounds;
+#elif (_FX_OS_==_FX_MACOSX_)
+ if (m_pWidgetMgr->IsFormDisabled()) {
+ IFWL_WidgetDelegate *pDelegate = pWidget->SetDelegate(NULL);
+ pDelegate->OnDrawWidget(pTemp, pMatrix);
+ pGraphics->GetClipRect(clipBounds);
+ clipCopy = clipBounds;
+ } else {
+ clipBounds.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d);
+ ((CFX_Matrix*)pMatrix)->Reset();
+#ifdef FWL_UseMacSystemBorder
+#else
+#endif
+ {
+ IFWL_WidgetDelegate *pDelegate = pWidget->SetDelegate(NULL);
+ pDelegate->OnDrawWidget(pTemp, pMatrix);
+ }
+ }
+#endif
+ if (!m_pWidgetMgr->IsFormDisabled()) {
+ CFX_RectF rtClient;
+ pWidget->GetClientRect(rtClient);
+ clipBounds.Intersect(rtClient);
+ }
+ if (!clipBounds.IsEmpty()) {
+ DrawChild(pWidget, clipBounds, pTemp, pMatrix);
+ }
+ DrawWidgetAfter(pWidget, pGraphics, clipCopy, pMatrix);
+ m_pWidgetMgr->ResetRedrawCounts(pWidget);
+ return FWL_ERR_Succeeded;
+}
+void CFWL_WidgetMgrDelegate::DrawChild(IFWL_Widget* parent,
+ const CFX_RectF& rtClip,
+ CFX_Graphics* pGraphics,
+ const CFX_Matrix* pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(parent);
+ FX_BOOL bFormDisable = m_pWidgetMgr->IsFormDisabled();
+ IFWL_Widget* pNextChild = m_pWidgetMgr->GetWidget(parent, FWL_WGTRELATION_FirstChild);
+ while (pNextChild) {
+ IFWL_Widget* child = pNextChild;
+ pNextChild = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ if (child->GetStates() & FWL_WGTSTATE_Invisible) {
+ continue;
+ }
+ CFX_RectF rtWidget;
+ child->GetWidgetRect(rtWidget);
+ if (rtWidget.IsEmpty()) {
+ continue;
+ }
+ CFX_Matrix widgetMatrix;
+ CFX_RectF clipBounds(rtWidget);
+ if(!bFormDisable) {
+ child->GetMatrix(widgetMatrix, TRUE);
+ }
+ if (pMatrix) {
+ widgetMatrix.Concat(*pMatrix);
+ }
+ if (!bFormDisable) {
+ widgetMatrix.TransformPoint(clipBounds.left, clipBounds.top);
+ clipBounds.Intersect(rtClip);
+ if (clipBounds.IsEmpty()) {
+ continue;
+ }
+ pGraphics->SaveGraphState();
+ pGraphics->SetClipRect(clipBounds);
+ }
+ widgetMatrix.Translate(rtWidget.left, rtWidget.top, TRUE);
+ IFWL_WidgetDelegate *pDelegate = child->SetDelegate(NULL);
+ if (pDelegate) {
+ if (m_pWidgetMgr->IsFormDisabled() || IsNeedRepaint(child, &widgetMatrix, rtClip)) {
+ pDelegate->OnDrawWidget(pGraphics, &widgetMatrix);
+ }
+ }
+ if (!bFormDisable) {
+ pGraphics->RestoreGraphState();
+ }
+ DrawChild(child, clipBounds, pGraphics, bFormDisable ? &widgetMatrix : pMatrix);
+ child = m_pWidgetMgr->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ }
+}
+CFX_Graphics* CFWL_WidgetMgrDelegate::DrawWidgetBefore(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix)
+{
+ if (!FWL_UseOffscreen(pWidget)) {
+ return pGraphics;
+ }
+ CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
+ if (!pItem->pOffscreen) {
+ pItem->pOffscreen = FX_NEW CFX_Graphics;
+ CFX_RectF rect;
+ pWidget->GetWidgetRect(rect);
+ pItem->pOffscreen->Create((FX_INT32)rect.width, (FX_INT32)rect.height, FXDIB_Argb);
+ }
+ CFX_RectF rect;
+ pGraphics->GetClipRect(rect);
+ pItem->pOffscreen->SetClipRect(rect);
+ return pItem->pOffscreen;
+}
+void CFWL_WidgetMgrDelegate::DrawWidgetAfter(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, CFX_RectF &rtClip, const CFX_Matrix *pMatrix)
+{
+ if (FWL_UseOffscreen(pWidget)) {
+ CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
+ pGraphics->Transfer(pItem->pOffscreen, rtClip.left, rtClip.top, rtClip, (CFX_Matrix*)pMatrix);
+#ifdef _WIN32
+ pItem->pOffscreen->ClearClip();
+#endif
+ }
+ CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
+ pItem->iRedrawCounter = 0;
+}
+#define FWL_NEEDREPAINTHIT_Point 12
+#define FWL_NEEDREPAINTHIT_Piece 3
+typedef struct _FWL_NeedRepaintHitData {
+ CFX_PointF hitPoint;
+ FX_BOOL bNotNeedRepaint;
+ FX_BOOL bNotContainByDirty;
+} FWL_NeedRepaintHitData;
+FX_BOOL CFWL_WidgetMgrDelegate::IsNeedRepaint(IFWL_Widget *pWidget, CFX_Matrix *pMatrix, const CFX_RectF &rtDirty)
+{
+ CFWL_WidgetMgrItem * pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
+ if (pItem && pItem->iRedrawCounter > 0) {
+ pItem->iRedrawCounter = 0;
+ return TRUE;
+ }
+ CFX_RectF rtWidget;
+ pWidget->GetWidgetRect(rtWidget);
+ rtWidget.left = rtWidget.top = 0;
+ pMatrix->TransformRect(rtWidget);
+ if (!rtWidget.IntersectWith(rtDirty)) {
+ return FALSE;
+ }
+ IFWL_Widget * pChild = FWL_GetWidgetMgr()->GetWidget(pWidget, FWL_WGTRELATION_FirstChild);
+ if (!pChild) {
+ return TRUE;
+ }
+ if (pChild->GetClassID() == 3150298670) {
+ CFX_RectF rtTemp;
+ pChild->GetWidgetRect(rtTemp);
+ if (rtTemp.width >= rtWidget.width && rtTemp.height >= rtWidget.height) {
+ pChild = FWL_GetWidgetMgr()->GetWidget(pChild, FWL_WGTRELATION_FirstChild);
+ if (!pChild) {
+ return TRUE;
+ }
+ }
+ }
+ CFX_RectF rtChilds;
+ rtChilds.Empty();
+ FX_BOOL bChildIntersectWithDirty = FALSE;
+ FX_BOOL bOrginPtIntersectWidthChild = FALSE;
+ FX_BOOL bOrginPtIntersectWidthDirty = rtDirty.Contains(rtWidget.left, rtWidget.top);
+ static FWL_NeedRepaintHitData hitPoint[FWL_NEEDREPAINTHIT_Point];
+ static FX_INT32 iSize = sizeof(FWL_NeedRepaintHitData);
+ FXSYS_memset(hitPoint, 0, iSize);
+ FX_FLOAT fxPiece = rtWidget.width / FWL_NEEDREPAINTHIT_Piece;
+ FX_FLOAT fyPiece = rtWidget.height / FWL_NEEDREPAINTHIT_Piece;
+ hitPoint[2].hitPoint.x = hitPoint[6].hitPoint.x = rtWidget.left;
+ hitPoint[0].hitPoint.x = hitPoint[3].hitPoint.x = hitPoint[7].hitPoint.x = hitPoint[10].hitPoint.x = fxPiece + rtWidget.left;
+ hitPoint[1].hitPoint.x = hitPoint[4].hitPoint.x = hitPoint[8].hitPoint.x = hitPoint[11].hitPoint.x = fxPiece * 2 + rtWidget.left;
+ hitPoint[5].hitPoint.x = hitPoint[9].hitPoint.x = rtWidget.width + rtWidget.left;
+ hitPoint[0].hitPoint.y = hitPoint[1].hitPoint.y = rtWidget.top;
+ hitPoint[2].hitPoint.y = hitPoint[3].hitPoint.y = hitPoint[4].hitPoint.y = hitPoint[5].hitPoint.y = fyPiece + rtWidget.top;
+ hitPoint[6].hitPoint.y = hitPoint[7].hitPoint.y = hitPoint[8].hitPoint.y = hitPoint[9].hitPoint.y = fyPiece * 2 + rtWidget.top;
+ hitPoint[10].hitPoint.y = hitPoint[11].hitPoint.y = rtWidget.height + rtWidget.top;
+ do {
+ CFX_RectF rect;
+ pChild->GetWidgetRect(rect);
+ CFX_RectF r = rect;
+ r.left += rtWidget.left;
+ r.top += rtWidget.top;
+ if (r.IsEmpty()) {
+ continue;
+ }
+ if (r.Contains(rtDirty)) {
+ return FALSE;
+ }
+ if (!bChildIntersectWithDirty && r.IntersectWith(rtDirty)) {
+ bChildIntersectWithDirty = TRUE;
+ }
+ if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) {
+ bOrginPtIntersectWidthChild = rect.Contains(0, 0);
+ }
+ if (rtChilds.IsEmpty()) {
+ rtChilds = rect;
+ } else if (!(pChild->GetStates() & FWL_WGTSTATE_Invisible)) {
+ rtChilds.Union(rect);
+ }
+ for (FX_INT32 i = 0; i < FWL_NEEDREPAINTHIT_Point; i ++) {
+ if (hitPoint[i].bNotContainByDirty || hitPoint[i].bNotNeedRepaint) {
+ continue;
+ }
+ if (!rtDirty.Contains(hitPoint[i].hitPoint)) {
+ hitPoint[i].bNotContainByDirty = TRUE;
+ continue;
+ }
+ if (r.Contains(hitPoint[i].hitPoint)) {
+ hitPoint[i].bNotNeedRepaint = TRUE;
+ }
+ }
+ } while ((pChild = FWL_GetWidgetMgr()->GetWidget(pChild, FWL_WGTRELATION_NextSibling)) != NULL);
+ if (!bChildIntersectWithDirty) {
+ return TRUE;
+ }
+ if (bOrginPtIntersectWidthDirty && !bOrginPtIntersectWidthChild) {
+ return TRUE;
+ }
+ if (rtChilds.IsEmpty()) {
+ return TRUE;
+ }
+ FX_INT32 repaintPoint = FWL_NEEDREPAINTHIT_Point;
+ for (FX_INT32 i = 0; i < FWL_NEEDREPAINTHIT_Point; i ++) {
+ if (hitPoint[i].bNotNeedRepaint) {
+ repaintPoint --;
+ }
+ }
+ if (repaintPoint > 0) {
+ return TRUE;
+ }
+ pMatrix->TransformRect(rtChilds);
+ if (rtChilds.Contains(rtDirty) || rtChilds.Contains(rtWidget)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetMgrDelegate::bUseOffscreenDirect(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetMgrItem *pItem = m_pWidgetMgr->GetWidgetMgrItem(pWidget);
+ if (!FWL_UseOffscreen(pWidget) || !(pItem->pOffscreen)) {
+ return FALSE;
+ }
+#if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
+ if (pItem->bOutsideChanged) {
+ CFX_RectF r;
+ pWidget->GetWidgetRect(r);
+ CFX_RectF temp(m_pWidgetMgr->m_rtScreen);
+ temp.Deflate(50, 50);
+ if (!temp.Contains(r)) {
+ return FALSE;
+ }
+ pItem->bOutsideChanged = FALSE;
+ }
+#endif
+ return pItem->iRedrawCounter == 0;
+}
+static void FWL_WriteBMP(CFX_DIBitmap* pBitmap, FX_LPCSTR filename)
+{
+ FILE* file = fopen(filename, "wb");
+ if (file == NULL) {
+ return;
+ }
+ int size = 14 + 40 + pBitmap->GetPitch() * pBitmap->GetHeight();
+ unsigned char buffer[40];
+ buffer[0] = 'B';
+ buffer[1] = 'M';
+ buffer[2] = (unsigned char)size;
+ buffer[3] = (unsigned char)(size >> 8);
+ buffer[4] = (unsigned char)(size >> 16);
+ buffer[5] = (unsigned char)(size >> 24);
+ buffer[6] = buffer[7] = buffer[8] = buffer[9] = 0;
+ buffer[10] = 54;
+ buffer[11] = buffer[12] = buffer[13] = 0;
+ fwrite(buffer, 14, 1, file);
+ memset(buffer, 0, 40);
+ buffer[0] = 40;
+ buffer[4] = (unsigned char)pBitmap->GetWidth();
+ buffer[5] = (unsigned char)(pBitmap->GetWidth() >> 8);
+ buffer[6] = (unsigned char)(pBitmap->GetWidth() >> 16);
+ buffer[7] = (unsigned char)(pBitmap->GetWidth() >> 24);
+ buffer[8] = (unsigned char)(-pBitmap->GetHeight());
+ buffer[9] = (unsigned char)((-pBitmap->GetHeight()) >> 8);
+ buffer[10] = (unsigned char)((-pBitmap->GetHeight()) >> 16);
+ buffer[11] = (unsigned char)((-pBitmap->GetHeight()) >> 24);
+ buffer[12] = 1;
+ buffer[14] = pBitmap->GetBPP();
+ fwrite(buffer, 40, 1, file);
+ for (int row = 0; row < pBitmap->GetHeight(); row ++) {
+ FX_LPBYTE scan_line = pBitmap->GetBuffer() + row * pBitmap->GetPitch();
+ fwrite(scan_line, pBitmap->GetPitch(), 1, file);
+ }
+ fclose(file);
+}
+FWL_ERR FWL_WidgetMgrSnapshot(IFWL_Widget *pWidget, const CFX_WideString *saveFile, const CFX_Matrix *pMatrix)
+{
+ CFX_RectF r;
+ pWidget->GetWidgetRect(r);
+ CFX_Graphics gs;
+ gs.Create((FX_INT32)r.width, (FX_INT32)r.height, FXDIB_Argb);
+ CFWL_WidgetMgr *widgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ CFWL_WidgetMgrDelegate *delegate = widgetMgr->GetDelegate();
+ delegate->OnDrawWidget(pWidget, &gs, pMatrix);
+ CFX_DIBitmap *dib = gs.GetRenderDevice()->GetBitmap();
+ FWL_WriteBMP(dib, saveFile->UTF8Encode());
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL FWL_WidgetIsChild(IFWL_Widget *parent, IFWL_Widget *find)
+{
+ if (!find) {
+ return FALSE;
+ }
+ IFWL_Widget *child = FWL_GetWidgetMgr()->GetWidget(parent, FWL_WGTRELATION_FirstChild);
+ while (child) {
+ if (child == find) {
+ return TRUE;
+ }
+ if (FWL_WidgetIsChild(child, find)) {
+ return TRUE;
+ }
+ child = FWL_GetWidgetMgr()->GetWidget(child, FWL_WGTRELATION_NextSibling);
+ }
+ return FALSE;
+}
diff --git a/xfa/src/fwl/src/core/include/fwl_appimp.h b/xfa/src/fwl/src/core/include/fwl_appimp.h
new file mode 100644
index 0000000000..edc2089252
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_appimp.h
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_APP_IMP_H
+#define _FWL_APP_IMP_H
+class CFWL_NoteThread;
+class CFWL_WidgetMgr;
+class IFWL_AdapterNative;
+class IFWL_WidgetMgr;
+class IFWL_ThemeProvider;
+class IFWL_App;
+class CFWL_AppImp;
+class CFWL_AppImp : public CFWL_NoteThread
+{
+public:
+ CFWL_AppImp(IFWL_AdapterNative *pAdapter);
+ virtual ~CFWL_AppImp();
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual IFWL_AdapterNative* GetAdapterNative();
+ virtual IFWL_WidgetMgr* GetWidgetMgr();
+ virtual FWL_ERR SetThemeProvider(IFWL_ThemeProvider* pThemeProvider);
+ virtual FWL_ERR Exit(FX_INT32 iExitCode = 0);
+ IFWL_ThemeProvider* GetThemeProvider();
+protected:
+ CFWL_WidgetMgr *m_pWidgetMgr;
+ IFWL_AdapterNative *m_pAdapterNative;
+ IFWL_ThemeProvider *m_pThemeProvider;
+ FX_BOOL m_bFuelAdapter;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_contentimp.h b/xfa/src/fwl/src/core/include/fwl_contentimp.h
new file mode 100644
index 0000000000..0aaaf0e1b8
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_contentimp.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_CONTENT_IMP_H
+#define _FWL_CONTENT_IMP_H
+class CFWL_WidgetImp;
+class IFWL_Widget;
+class CFWL_ContentImp;
+class CFWL_ContentImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_ContentImp();
+ CFWL_ContentImp(const CFWL_WidgetImpProperties &properties);
+ virtual ~CFWL_ContentImp();
+ virtual FWL_ERR InsertWidget(IFWL_Widget *pChild, FX_INT32 nIndex = -1);
+ virtual FWL_ERR RemoveWidget(IFWL_Widget *pWidget);
+ virtual FWL_ERR RemoveAllWidgets();
+ virtual FWL_ERR GetMinSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight);
+ virtual FWL_ERR SetMinSize(FX_FLOAT fWidth, FX_FLOAT fHeight);
+ virtual FWL_ERR GetMaxSize(FX_FLOAT &fWidth, FX_FLOAT &fHeight);
+ virtual FWL_ERR SetMaxSize(FX_FLOAT fWidth, FX_FLOAT fHeight);
+protected:
+ FX_FLOAT m_fWidthMin;
+ FX_FLOAT m_fWidthMax;
+ FX_FLOAT m_fHeightMax;
+ FX_FLOAT m_fHeightMin;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_formimp.h b/xfa/src/fwl/src/core/include/fwl_formimp.h
new file mode 100644
index 0000000000..357f8e86de
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_formimp.h
@@ -0,0 +1,187 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_FORM_IMP_H
+#define _FWL_FORM_IMP_H
+class CFWL_NoteLoop;
+class CFWL_PanelImp;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetImpDelegate;
+class CFWL_MsgMouse;
+class IFWL_Widget;
+class IFWL_ThemeProvider;
+class CFWL_SysBtn;
+class CFWL_FormImp;
+class CFWL_FormDelegate;
+#define FWL_SYSBUTTONSTATE_Hover 0x0001
+#define FWL_SYSBUTTONSTATE_Pressed 0x0002
+#define FWL_SYSBUTTONSTATE_Disabled 0x0010
+class CFWL_SysBtn : public CFX_Object
+{
+public:
+ CFWL_SysBtn()
+ {
+ m_rtBtn.Set(0, 0, 0, 0);
+ m_dwState = 0;
+ }
+
+ FX_BOOL IsHover()
+ {
+ return m_dwState & FWL_SYSBUTTONSTATE_Hover;
+ }
+ FX_BOOL IsPressed()
+ {
+ return m_dwState & FWL_SYSBUTTONSTATE_Pressed;
+ }
+ FX_BOOL IsDisabled()
+ {
+ return m_dwState & FWL_SYSBUTTONSTATE_Disabled;
+ }
+ void SetNormal()
+ {
+ m_dwState &= 0xFFF0;
+ }
+ void SetPressed()
+ {
+ SetNormal();
+ m_dwState |= FWL_SYSBUTTONSTATE_Pressed;
+ }
+ void SetHover()
+ {
+ SetNormal();
+ m_dwState |= FWL_SYSBUTTONSTATE_Hover;
+ }
+ void SetDisabled(FX_BOOL bDisabled)
+ {
+ bDisabled ? m_dwState |= FWL_SYSBUTTONSTATE_Disabled : m_dwState &= ~FWL_SYSBUTTONSTATE_Disabled;
+ }
+ FX_INT32 GetPartState()
+ {
+ return (IsDisabled() ? FWL_PARTSTATE_FRM_Disabled : (m_dwState + 1));
+ }
+
+ CFX_RectF m_rtBtn;
+ FX_DWORD m_dwState;
+};
+enum FORM_RESIZETYPE {
+ FORM_RESIZETYPE_None = 0,
+ FORM_RESIZETYPE_Cap,
+ FORM_RESIZETYPE_Left,
+ FORM_RESIZETYPE_Top,
+ FORM_RESIZETYPE_Right,
+ FORM_RESIZETYPE_Bottom,
+ FORM_RESIZETYPE_LeftTop,
+ FORM_RESIZETYPE_LeftBottom,
+ FORM_RESIZETYPE_RightTop,
+ FORM_RESIZETYPE_RightBottom
+};
+typedef struct RestoreResizeInfo {
+ CFX_PointF m_ptStart;
+ CFX_SizeF m_szStart;
+} RestoreInfo;
+class CFWL_FormImp : public CFWL_PanelImp
+{
+public:
+ CFWL_FormImp(IFWL_Widget *pOuter = NULL);
+ CFWL_FormImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_FormImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FX_BOOL IsInstance(FX_WSTR wsClass) const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR GetClientRect(CFX_RectF &rect);
+ virtual FWL_ERR Update();
+ virtual FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual FWL_FORMSIZE GetFormSize();
+ virtual FWL_ERR SetFormSize(FWL_FORMSIZE eFormSize);
+ virtual IFWL_Widget* DoModal();
+ virtual IFWL_Widget* DoModal(FX_DWORD &dwCommandID);
+ virtual FWL_ERR EndDoModal();
+ virtual FWL_ERR SetBorderRegion(CFX_Path *pPath);
+ virtual void DrawBackground(CFX_Graphics *pGraphics, IFWL_ThemeProvider *pTheme);
+ CFWL_WidgetImp* GetSubFocus();
+ void SetSubFocus(CFWL_WidgetImp *pWidget);
+ CFX_MapAccelerators& GetAccelerator();
+ void SetAccelerator(CFX_MapAccelerators *pAccelerators);
+protected:
+ void ShowChildWidget(IFWL_Widget *pParent);
+ void RemoveSysButtons();
+ void CalcContentRect(CFX_RectF &rtContent);
+ CFWL_SysBtn* GetSysBtnAtPoint(FX_FLOAT fx, FX_FLOAT fy);
+ CFWL_SysBtn* GetSysBtnByState(FX_DWORD dwState);
+ CFWL_SysBtn* GetSysBtnByIndex(FX_INT32 nIndex);
+ FX_INT32 GetSysBtnIndex(CFWL_SysBtn *pBtn);
+ FX_FLOAT GetCaptionHeight();
+ void DrawCaptionText(CFX_Graphics *pGs, IFWL_ThemeProvider *pTheme, const CFX_Matrix* pMatrix = NULL);
+ void DrawIconImage(CFX_Graphics *pGs, IFWL_ThemeProvider *pTheme, const CFX_Matrix* pMatrix = NULL);
+ void GetEdgeRect(CFX_RectF &rtEdge);
+ void SetWorkAreaRect();
+ void SetCursor(FX_FLOAT fx, FX_FLOAT fy);
+ void Layout();
+ void ReSetSysBtn();
+ void RegisterForm();
+ void UnRegisterForm();
+ FX_BOOL IsDoModal();
+ void SetThemeData();
+ FX_BOOL HasIcon();
+ void UpdateIcon();
+ void UpdateCaption();
+ void DoWidthLimit(FX_FLOAT &fLeft, FX_FLOAT &fWidth, FX_FLOAT fCurX, FX_FLOAT fSpace, FX_FLOAT fLimitMin, FX_FLOAT fLimitMax, FX_BOOL bLeft);
+ void DoHeightLimit(FX_FLOAT &fTop, FX_FLOAT &fHeight, FX_FLOAT fCurY, FX_FLOAT fSpace, FX_FLOAT fLimitMin, FX_FLOAT fLimitMax, FX_BOOL bTop);
+ CFX_MapAccelerators m_mapAccelerators;
+ CFX_RectF m_rtRestore;
+ CFX_RectF m_rtCaptionText;
+ CFX_RectF m_rtRelative;
+ CFX_RectF m_rtCaption;
+ CFX_RectF m_rtIcon;
+ CFWL_SysBtn *m_pCloseBox;
+ CFWL_SysBtn *m_pMinBox;
+ CFWL_SysBtn *m_pMaxBox;
+ CFWL_SysBtn *m_pCaptionBox;
+ CFWL_NoteLoop *m_pNoteLoop;
+ CFWL_WidgetImp *m_pSubFocus;
+ RestoreInfo m_InfoStart;
+ FX_FLOAT m_fCXBorder;
+ FX_FLOAT m_fCYBorder;
+ FX_INT32 m_iCaptureBtn;
+ FX_INT32 m_iSysBox;
+ FX_INT32 m_eResizeType;
+ FX_BOOL m_bLButtonDown;
+ FX_BOOL m_bMaximized;
+ FX_BOOL m_bSetMaximize;
+ FX_BOOL m_bCustomizeLayout;
+ FWL_FORMSIZE m_eFormSize;
+ FX_BOOL m_bDoModalFlag;
+ FX_FLOAT m_fSmallIconSz;
+ FX_FLOAT m_fBigIconSz;
+ CFX_DIBitmap *m_pBigIcon;
+ CFX_DIBitmap *m_pSmallIcon;
+ FX_BOOL m_bMouseIn;
+ friend class CFWL_FormDelegate;
+};
+class CFWL_FormDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_FormDelegate(CFWL_FormImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void OnLButtonDown(CFWL_MsgMouse *pMsg);
+ void OnLButtonUp(CFWL_MsgMouse *pMsg);
+ void OnMouseMove(CFWL_MsgMouse *pMsg);
+ void OnMouseHover(CFWL_MsgMouse *pMsg);
+ void OnMouseLeave(CFWL_MsgMouse *pMsg);
+ void OnLButtonDblClk(CFWL_MsgMouse *pMsg);
+ void OnWindowMove(CFWL_MsgWindowMove *pMsg);
+ void OnClose(CFWL_MsgClose *pMsg);
+ CFWL_FormImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_gridimp.h b/xfa/src/fwl/src/core/include/fwl_gridimp.h
new file mode 100644
index 0000000000..7538f1b048
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_gridimp.h
@@ -0,0 +1,161 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_GRID_IMP_H
+#define _FWL_GRID_IMP_H
+class CFWL_Content;
+class IFWL_Widget;
+class CFWL_GridLength;
+class CFWL_GridColRow;
+class CFWL_GridWidgetInfo;
+class CFWL_GridImp;
+class CFWL_GridLength : public CFX_Object
+{
+public:
+ CFWL_GridLength()
+ : fLength(0)
+ , eUnit(FWL_GRIDUNIT_Fixed)
+ {
+ }
+ CFWL_GridLength(FX_FLOAT fValue, FWL_GRIDUNIT e)
+ : fLength(fValue)
+ , eUnit(e)
+ {
+ }
+ FX_FLOAT fLength;
+ FWL_GRIDUNIT eUnit;
+};
+class CFWL_GridColRow : public CFX_Object
+{
+public:
+ CFWL_GridColRow()
+ : m_Size (1, FWL_GRIDUNIT_Scaled)
+ , m_MinSize(0, FWL_GRIDUNIT_Fixed)
+ , m_MaxSize(0, FWL_GRIDUNIT_Infinity)
+ , m_fActualSize(0)
+ , m_fActualPos(0)
+ {
+ }
+ CFWL_GridLength m_Size;
+ CFWL_GridLength m_MinSize;
+ CFWL_GridLength m_MaxSize;
+ FX_FLOAT m_fActualSize;
+ FX_FLOAT m_fActualPos;
+};
+class CFWL_GridWidgetInfo : public CFX_Object
+{
+public:
+ CFWL_GridWidgetInfo()
+ : m_iColumn (0)
+ , m_iColumnSpan(1)
+ , m_iRow(0)
+ , m_iRowSpan(1)
+ , m_dwMarginFlag(0)
+ , m_fActualWidth(0)
+ , m_fActualHeight(0)
+ {
+ m_Size[FWL_GRIDSIZE_Width].eUnit = FWL_GRIDUNIT_Auto;
+ m_Size[FWL_GRIDSIZE_Width].fLength = 0;
+ m_Size[FWL_GRIDSIZE_Height].eUnit = FWL_GRIDUNIT_Auto;
+ m_Size[FWL_GRIDSIZE_Height].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MinWidth].eUnit = FWL_GRIDUNIT_Fixed;
+ m_Size[FWL_GRIDSIZE_MinWidth].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MaxWidth].eUnit = FWL_GRIDUNIT_Infinity;
+ m_Size[FWL_GRIDSIZE_MaxWidth].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MinHeight].eUnit = FWL_GRIDUNIT_Fixed;
+ m_Size[FWL_GRIDSIZE_MinHeight].fLength = 0;
+ m_Size[FWL_GRIDSIZE_MaxHeight].eUnit = FWL_GRIDUNIT_Infinity;
+ m_Size[FWL_GRIDSIZE_MaxHeight].fLength = 0;
+ m_Margin[0] = m_Margin[1] = m_Margin[2] = m_Margin[3] = 0;
+ }
+ FX_INT32 m_iColumn;
+ FX_INT32 m_iColumnSpan;
+ FX_INT32 m_iRow;
+ FX_INT32 m_iRowSpan;
+ CFWL_GridLength m_Size[6];
+ FX_DWORD m_dwMarginFlag;
+ FX_FLOAT m_Margin[4];
+ FX_FLOAT m_fActualWidth;
+ FX_FLOAT m_fActualHeight;
+};
+class CFWL_GridImp : public CFWL_ContentImp
+{
+public:
+ CFWL_GridImp();
+ CFWL_GridImp(const CFWL_WidgetImpProperties &properties);
+ virtual ~CFWL_GridImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR SetWidgetRect(const CFX_RectF &rect);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+
+ virtual FWL_ERR InsertWidget(IFWL_Widget *pChild, FX_INT32 nIndex = -1);
+ virtual FWL_ERR RemoveWidget(IFWL_Widget *pWidget);
+ virtual FWL_HGRIDCOLROW InsertColRow(FX_BOOL bColumn, FX_INT32 nIndex = -1);
+ virtual FX_INT32 CountColRows(FX_BOOL bColumn);
+ virtual FWL_HGRIDCOLROW GetColRow(FX_BOOL bColumn, FX_INT32 nIndex);
+ virtual FX_INT32 GetIndex(FWL_HGRIDCOLROW hColRow);
+ virtual FX_FLOAT GetSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit);
+ virtual FWL_ERR SetSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit);
+ virtual FX_FLOAT GetMinSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit);
+ virtual FWL_ERR SetMinSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit);
+ virtual FX_FLOAT GetMaxSize(FWL_HGRIDCOLROW hColRow, FWL_GRIDUNIT &eUnit);
+ virtual FWL_ERR SetMaxSize(FWL_HGRIDCOLROW hColRow, FX_FLOAT fSize, FWL_GRIDUNIT eUnit);
+ virtual FX_BOOL DeleteColRow(FWL_HGRIDCOLROW hColRow);
+ virtual FX_BOOL IsColumn(FWL_HGRIDCOLROW hColRow);
+ virtual FX_INT32 GetWidgetPos(IFWL_Widget *pWidget, FX_BOOL bColumn);
+ virtual FWL_ERR SetWidgetPos(IFWL_Widget *pWidget, FX_INT32 iPos, FX_BOOL bColumn);
+ virtual FX_INT32 GetWidgetSpan(IFWL_Widget *pWidget, FX_BOOL bColumn);
+ virtual FWL_ERR SetWidgetSpan(IFWL_Widget *pWidget, FX_INT32 iSpan, FX_BOOL bColumn);
+ virtual FX_FLOAT GetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit);
+ virtual FWL_ERR SetWidgetSize(IFWL_Widget *pWidget, FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit);
+ virtual FX_BOOL GetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT &fMargin);
+ virtual FWL_ERR SetWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin, FX_FLOAT fMargin);
+ virtual FWL_ERR RemoveWidgetMargin(IFWL_Widget *pWidget, FWL_GRIDMARGIN eMargin);
+ virtual FX_FLOAT GetGridSize(FWL_GRIDSIZE eSize, FWL_GRIDUNIT &eUnit);
+ virtual FWL_ERR SetGridSize(FWL_GRIDSIZE eSize, FX_FLOAT fSize, FWL_GRIDUNIT eUit);
+protected:
+ CFWL_GridWidgetInfo* GetWidgetInfo(IFWL_Widget* pWidget);
+ void ProcFixedColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_FLOAT fColRowSize, FX_BOOL bColumn);
+ void ProcAutoColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_BOOL bColumn);
+ void ProcScaledColRow(CFWL_GridColRow *pColRow, FX_INT32 nIndex, FX_FLOAT fColRowSize, FX_BOOL bColumn);
+ void CalcWidgetWidth(IFWL_Widget *pWidget, CFWL_GridWidgetInfo *pInfo, FX_FLOAT fColunmWidth);
+ void CalcWidgetHeigt(IFWL_Widget *pWidget, CFWL_GridWidgetInfo *pInfo, FX_FLOAT fRowHeigt);
+ FX_FLOAT CalcAutoColumnWidgetWidth(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo);
+ FX_FLOAT CalcAutoColumnWidgetHeight(IFWL_Widget *pWidget, CFWL_GridWidgetInfo* pInfo);
+ FX_FLOAT ProcessColumns(FX_FLOAT fWidth);
+ FX_FLOAT ProcessRows(FX_FLOAT fHeight);
+ FX_FLOAT ProcessUnCertainColumns();
+ FX_FLOAT ProcessUnCertainRows();
+ FX_BOOL SetColRowActualSize(CFWL_GridColRow *pColRow, FX_FLOAT fSize, FX_BOOL bSetBeyond = FALSE);
+ FX_FLOAT SetWidgetActualWidth(CFWL_GridWidgetInfo *pInfo, FX_FLOAT fWidth);
+ FX_FLOAT SetWidgetActualHeight(CFWL_GridWidgetInfo *pInfo, FX_FLOAT fHeight);
+ void SetAllWidgetsRect();
+ FX_BOOL IsGrid(IFWL_Widget *pWidget);
+ void SetSpanAutoColRowSize(const CFX_PtrArray &spanAutos, FX_FLOAT fTotalSize);
+ void SetSpanScaledColRowSize(const CFX_PtrArray &spanScaleds, FX_FLOAT fTotalSize, FX_FLOAT fTotalScaledNum);
+ void SetScaledColRowsSize(const CFX_PtrArray &spanScaleds, FX_FLOAT fTotalSize, FX_FLOAT fTotalScaledNum);
+ CFX_PtrArray m_Rows;
+ CFX_PtrArray m_Columns;
+ CFX_PtrArray m_Widgets;
+ CFX_MapPtrToPtr m_mapWidgetInfo;
+ CFWL_GridLength m_Size[6];
+ friend class CFWL_GridDelegate;
+};
+class CFWL_GridDelegate : public CFWL_WidgetImpDelegate
+{
+public:
+ CFWL_GridDelegate(CFWL_GridImp *pOwner);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ CFWL_GridImp *m_pOwner;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_noteimp.h b/xfa/src/fwl/src/core/include/fwl_noteimp.h
new file mode 100644
index 0000000000..1e7239289b
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_noteimp.h
@@ -0,0 +1,152 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_NOTE_IMP_H
+#define _FWL_NOTE_IMP_H
+class CFWL_Target;
+class CFWL_WidgetImp;
+class CFWL_NoteThread;
+class CFWL_ToolTipImp;
+class IFWL_ToolTipTarget;
+class CFWL_CoreToopTipDP;
+class CFWL_NoteLoop;
+class CFWL_NoteDriver;
+class CFWL_EventTarget;
+class CFWL_ToolTipContainer;
+class CFWL_NoteLoop : public CFX_Object
+{
+public:
+ CFWL_NoteLoop(CFWL_WidgetImp *pForm = NULL);
+ virtual FX_BOOL PreProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR Idle(FX_INT32 count);
+ CFWL_WidgetImp* GetForm();
+ FX_BOOL ContinueModal();
+ FWL_ERR EndModalLoop();
+ FX_BOOL TranslateAccelerator(CFWL_Message *pMessage);
+ FWL_ERR SetMainForm(CFWL_WidgetImp *pForm);
+protected:
+ void GenerateCommondEvent(FX_DWORD dwCommand);
+
+ CFWL_WidgetImp *m_pForm;
+ FX_BOOL m_bContinueModal;
+};
+class CFWL_NoteDriver : public CFX_Object
+{
+public:
+ CFWL_NoteDriver();
+ ~CFWL_NoteDriver();
+ virtual FX_BOOL SendNote(CFWL_Note *pNote);
+ virtual FX_BOOL PostMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR RegisterEventTarget(IFWL_Widget *pListener, IFWL_Widget *pEventSource = NULL, FX_DWORD dwFilter = FWL_EVENT_ALL_MASK);
+ virtual FWL_ERR UnregisterEventTarget(IFWL_Widget *pListener);
+ virtual void ClearEventTargets(FX_BOOL bRemoveAll);
+ virtual FX_INT32 GetQueueMaxSize() const;
+ virtual FWL_ERR SetQueueMaxSize(const FX_INT32 size);
+ virtual IFWL_NoteThread* GetOwnerThread() const;
+ virtual FWL_ERR PushNoteLoop(IFWL_NoteLoop *pNoteLoop);
+ virtual IFWL_NoteLoop* PopNoteLoop();
+ virtual FX_BOOL SetFocus(IFWL_Widget *pFocus, FX_BOOL bNotify = FALSE);
+ virtual FWL_ERR Run();
+ IFWL_Widget* GetFocus();
+ IFWL_Widget* GetHover();
+ void SetHover(IFWL_Widget *pHover);
+ void SetGrab(IFWL_Widget *pGrab, FX_BOOL bSet);
+ void NotifyTargetHide(IFWL_Widget *pNoteTarget);
+ void NotifyTargetDestroy(IFWL_Widget *pNoteTarget);
+ void NotifyFullScreenMode(IFWL_Widget *pNoteTarget, FX_BOOL bFullScreen);
+ FWL_ERR RegisterForm(CFWL_WidgetImp *pForm);
+ FWL_ERR UnRegisterForm(CFWL_WidgetImp *pForm);
+ FX_BOOL QueueMessage(CFWL_Message *pMessage);
+ FX_BOOL UnqueueMessage(CFWL_NoteLoop *pNoteLoop);
+ CFWL_NoteLoop* GetTopLoop();
+ FX_INT32 CountLoop();
+ void SetHook(FWLMessageHookCallback callback, FX_LPVOID info);
+ FX_BOOL ProcessMessage(CFWL_Message *pMessage);
+protected:
+ FX_BOOL DispatchMessage(CFWL_Message *pMessage, IFWL_Widget *pMessageForm);
+ FX_BOOL DoActivate(CFWL_MsgActivate *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoDeactivate(CFWL_MsgDeactivate *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoSetFocus(CFWL_MsgSetFocus *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoKillFocus(CFWL_MsgKillFocus *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoKey(CFWL_MsgKey *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoMouse(CFWL_MsgMouse *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoWheel(CFWL_MsgMouseWheel *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoSize(CFWL_MsgSize *pMsg);
+ FX_BOOL DoWindowMove(CFWL_MsgWindowMove *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoDragFiles(CFWL_MsgDropFiles *pMsg, IFWL_Widget *pMessageForm);
+ FX_BOOL DoMouseEx(CFWL_MsgMouse *pMsg, IFWL_Widget *pMessageForm);
+ void MouseSecondary(CFWL_MsgMouse *pMsg);
+ FX_BOOL IsValidMessage(CFWL_Message *pMessage);
+ IFWL_Widget* GetMessageForm(IFWL_Widget *pDstTarget);
+ void ClearInvalidEventTargets(FX_BOOL bRemoveAll);
+ CFX_PtrArray m_forms;
+ CFX_PtrArray m_noteQueue;
+ CFX_PtrArray m_noteLoopQueue;
+ CFX_MapPtrToPtr m_eventTargets;
+ FX_INT32 m_sendEventCalled;
+ FX_INT32 m_maxSize;
+ FX_BOOL m_bFullScreen;
+ IFWL_Widget *m_pHover;
+ IFWL_Widget *m_pFocus;
+ IFWL_Widget *m_pGrab;
+ CFWL_NoteLoop *m_pNoteLoop;
+ FWLMessageHookCallback m_hook;
+ FX_LPVOID m_hookInfo;
+};
+typedef CFX_MapPtrTemplate<FX_LPVOID, FX_DWORD> CFWL_EventSource;
+class CFWL_EventTarget : public CFX_Object
+{
+public:
+ CFWL_EventTarget(CFWL_NoteDriver *pNoteDriver, IFWL_Widget *pListener)
+ : m_pNoteDriver(pNoteDriver)
+ , m_pListener(pListener)
+ , m_bInvalid(FALSE)
+ {
+ }
+ ~CFWL_EventTarget();
+ FX_INT32 SetEventSource(IFWL_Widget *pSource, FX_DWORD dwFilter = FWL_EVENT_ALL_MASK);
+ FX_BOOL ProcessEvent(CFWL_Event *pEvent);
+ FX_BOOL IsFilterEvent(CFWL_Event *pEvent, FX_DWORD dwFilter);
+ FX_BOOL IsInvalid()
+ {
+ return m_bInvalid;
+ }
+ void FlagInvalid()
+ {
+ m_bInvalid = TRUE;
+ }
+protected:
+ CFWL_EventSource m_eventSources;
+ IFWL_Widget *m_pListener;
+ CFWL_NoteDriver *m_pNoteDriver;
+ FX_BOOL m_bInvalid;
+};
+class CFWL_ToolTipContainer: public CFX_Object
+{
+public:
+ virtual ~CFWL_ToolTipContainer();
+ static CFWL_ToolTipContainer* getInstance();
+
+ FX_ERR AddToolTipTarget(IFWL_ToolTipTarget *pTarget);
+ FX_ERR RemoveToolTipTarget(IFWL_ToolTipTarget *pTarget);
+ IFWL_ToolTipTarget* GetCurrentToolTipTarget();
+
+ FX_BOOL HasToolTip(IFWL_Widget *pWidget);
+
+ FX_BOOL ProcessEnter(CFWL_EvtMouse *pEvt, IFWL_Widget *pOwner);
+ FX_BOOL ProcessLeave(CFWL_EvtMouse *pEvt);
+
+ FX_ERR SetToolTipInitialDelay(FX_INT32 iDelayTime);
+ FX_ERR SetToolTipAutoPopDelay(FX_INT32 iDelayTime);
+protected:
+ CFWL_ToolTipContainer();
+
+ IFWL_ToolTipTarget *pCurTarget;
+ CFWL_ToolTipImp *m_pToolTipImp;
+ CFWL_CoreToopTipDP *m_ToolTipDp;
+ CFX_PtrArray m_arrWidget;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_panelimp.h b/xfa/src/fwl/src/core/include/fwl_panelimp.h
new file mode 100644
index 0000000000..bdaf8bd2a8
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_panelimp.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_PANEL_IMP_H
+#define _FWL_PANEL_IMP_H
+class CFWL_WidgetImp;
+class CFWL_WidgetImpProperties;
+class IFWL_Widget;
+class IFWL_Content;
+class CFWL_PanelImp;
+class CFWL_PanelImp : public CFWL_WidgetImp
+{
+public:
+ CFWL_PanelImp(IFWL_Widget *pOuter = NULL);
+ CFWL_PanelImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_PanelImp();
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR Update();
+ virtual IFWL_Content* GetContent();
+ virtual FWL_ERR SetContent(IFWL_Content *pContent);
+protected:
+ IFWL_Content *m_pContent;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_targetimp.h b/xfa/src/fwl/src/core/include/fwl_targetimp.h
new file mode 100644
index 0000000000..14e54cdebc
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_targetimp.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_TARGET_IMP_H
+#define _FWL_TARGET_IMP_H
+class IFWL_Target;
+class CFWL_Target;
+class CFWL_Target : public CFX_Object
+{
+public:
+ virtual FX_DWORD Release();
+ virtual IFWL_Target* Retain();
+ virtual FX_DWORD GetRefCount() const;
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const;
+ virtual FX_DWORD GetClassID() const;
+ virtual FX_BOOL IsInstance(FX_WSTR wsClass) const;
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+protected:
+ CFWL_Target();
+ virtual ~CFWL_Target();
+ FX_DWORD m_dwRefCount;
+};
+class IFWL_TargetData : public IFWL_Target
+{
+public:
+ FX_LPVOID GetData();
+ void SetData(FX_LPVOID pData);
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_threadimp.h b/xfa/src/fwl/src/core/include/fwl_threadimp.h
new file mode 100644
index 0000000000..d7ac365c61
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_threadimp.h
@@ -0,0 +1,53 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_THREAD_IMP_H
+#define _FWL_THREAD_IMP_H
+class CFWL_Target;
+class CFWL_NoteDriver;
+class IFWL_NoteThread;
+class IFWL_NoteDriver;
+class CFWL_Thread;
+class CFWL_NoteThread;
+class CFWL_ControlThread;
+class CFWL_Thread : public CFX_Object
+{
+public:
+ CFWL_Thread();
+ virtual ~CFWL_Thread();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FWL_ERR Run(FWL_HTHREAD hThread);
+};
+class CFWL_ControlThread : public CFWL_Thread
+{
+public:
+ CFWL_ControlThread(IFWL_Thread * defHandler)
+ {
+ _defHandler = defHandler;
+ }
+ virtual ~CFWL_ControlThread();
+ virtual FWL_ERR Run(FWL_HTHREAD hThread);
+protected:
+ IFWL_Thread * _defHandler;
+};
+class CFWL_NoteThread : public CFWL_Thread
+{
+public:
+ CFWL_NoteThread();
+ virtual ~CFWL_NoteThread();
+ virtual FWL_ERR Run(FWL_HTHREAD hThread);
+ virtual IFWL_NoteDriver* GetNoteDriver();
+protected:
+ CFWL_NoteDriver *m_pNoteDriver;
+ FWL_HTHREAD m_hThread;
+ static CFWL_ControlThread * _assistantThreadHandler;
+ static FWL_HTHREAD _assistantThread;
+ static FX_INT32 _refCount;
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_widgetimp.h b/xfa/src/fwl/src/core/include/fwl_widgetimp.h
new file mode 100644
index 0000000000..439bdac956
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_widgetimp.h
@@ -0,0 +1,128 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_WIDGET_IMP_H
+#define _FWL_WIDGET_IMP_H
+class CFWL_NoteTarget;
+class CFWL_NoteThread;
+class CFWL_WidgetImpProperties;
+class CFWL_WidgetMgr;
+class IFWL_Widget;
+class IFWL_ThemeProvider;
+class IFWL_DataProvider;
+class IFWL_WidgetDelegate;
+class CFWL_WidgetImp;
+class CFWL_WidgetImp : public CFWL_Target
+{
+public:
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+
+ virtual FWL_ERR GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize = FALSE);
+ virtual FWL_ERR GetGlobalRect(CFX_RectF &rect);
+ virtual FWL_ERR SetWidgetRect(const CFX_RectF &rect);
+ virtual FWL_ERR GetClientRect(CFX_RectF &rect);
+ virtual IFWL_Widget* GetParent();
+ virtual FWL_ERR SetParent(IFWL_Widget *pParent);
+ virtual IFWL_Widget* GetOwner();
+ virtual FWL_ERR SetOwner(IFWL_Widget *pOwner);
+ virtual IFWL_Widget* GetOuter();
+ virtual FX_DWORD GetStyles();
+ virtual FWL_ERR ModifyStyles(FX_DWORD dwStylesAdded, FX_DWORD dwStylesRemoved);
+ virtual FX_DWORD GetStylesEx();
+ virtual FWL_ERR ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved);
+ virtual FX_DWORD GetStates();
+ virtual FWL_ERR SetStates(FX_DWORD dwStates, FX_BOOL bSet = TRUE);
+ virtual FWL_ERR SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback);
+ virtual FX_LPVOID GetPrivateData(FX_LPVOID module_id);
+ virtual FWL_ERR Update();
+ virtual FWL_ERR LockUpdate();
+ virtual FWL_ERR UnlockUpdate();
+ virtual FX_DWORD HitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FWL_ERR TransformTo(IFWL_Widget *pWidget, FX_FLOAT &fx, FX_FLOAT &fy);
+ virtual FWL_ERR TransformTo(IFWL_Widget *pWidget, CFX_RectF &rt);
+ virtual FWL_ERR GetMatrix(CFX_Matrix &matrix, FX_BOOL bGlobal = FALSE);
+ virtual FWL_ERR SetMatrix(const CFX_Matrix &matrix);
+ virtual FWL_ERR DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+ virtual IFWL_ThemeProvider* GetThemeProvider();
+ virtual FWL_ERR SetThemeProvider(IFWL_ThemeProvider *pThemeProvider);
+ virtual FWL_ERR SetDataProvider(IFWL_DataProvider *pDataProvider);
+ virtual IFWL_WidgetDelegate*SetDelegate(IFWL_WidgetDelegate *pDelegate);
+ virtual IFWL_NoteThread* GetOwnerThread() const;
+ FWL_ERR SetOwnerThread(CFWL_NoteThread *pOwnerThread);
+ FWL_ERR GetProperties(CFWL_WidgetImpProperties &properties);
+ FWL_ERR SetProperties(const CFWL_WidgetImpProperties &properties);
+ IFWL_Widget* GetInterface();
+ void SetInterface(IFWL_Widget *pInterface);
+ CFX_SizeF GetOffsetFromParent(IFWL_Widget *pParent);
+protected:
+ CFWL_WidgetImp(IFWL_Widget *pOuter = NULL);
+ CFWL_WidgetImp(const CFWL_WidgetImpProperties &properties, IFWL_Widget *pOuter = NULL);
+ virtual ~CFWL_WidgetImp();
+ FX_BOOL IsEnabled();
+ FX_BOOL IsVisible();
+ FX_BOOL IsActive();
+ FX_BOOL IsOverLapper();
+ FX_BOOL IsPopup();
+ FX_BOOL IsChild();
+ FX_BOOL IsLocked();
+ FX_BOOL IsOffscreen();
+ FX_BOOL HasBorder();
+ FX_BOOL HasEdge();
+ void GetEdgeRect(CFX_RectF &rtEdge);
+ FX_FLOAT GetBorderSize(FX_BOOL bCX = TRUE);
+ FX_FLOAT GetEdgeWidth();
+ void GetRelativeRect(CFX_RectF &rect);
+ FX_LPVOID GetThemeCapacity(FX_DWORD dwCapacity);
+ IFWL_ThemeProvider* GetAvailableTheme();
+ CFWL_WidgetImp* GetRootOuter();
+ CFWL_WidgetImp* GetSameAncestor(CFWL_WidgetImp *pWidget);
+ CFX_SizeF GetOffsetFromAncestor(CFWL_WidgetImp *pAncestor);
+ FX_BOOL TransformToOuter(FX_FLOAT &fx, FX_FLOAT &fy);
+ FX_BOOL TransformFromOuter(FX_FLOAT &fx, FX_FLOAT &fy);
+ CFX_SizeF CalcTextSize(const CFX_WideString &wsText, IFWL_ThemeProvider *pTheme, FX_BOOL bMultiLine = FALSE, FX_INT32 iLineWidth = -1);
+ void CalcTextRect(const CFX_WideString &wsText, IFWL_ThemeProvider *pTheme, FX_DWORD dwTTOStyles, FX_INT32 iTTOAlign, CFX_RectF &rect);
+ void SetFocus(FX_BOOL bFocus);
+ void SetGrab(FX_BOOL bSet);
+ FX_BOOL GetPopupPos(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+ FX_BOOL GetPopupPosMenu(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+ FX_BOOL GetPopupPosComboBox(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+ FX_BOOL GetPopupPosGeneral(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+ FX_BOOL GetScreenSize(FX_FLOAT &fx, FX_FLOAT &fy);
+ void RegisterEventTarget(IFWL_Widget *pEventSource = NULL, FX_DWORD dwFilter = FWL_EVENT_ALL_MASK);
+ void UnregisterEventTarget();
+ void DispatchKeyEvent(CFWL_MsgKey *pNote);
+ void DispatchEvent(CFWL_Event *pEvent);
+ void Repaint(const CFX_RectF *pRect = NULL);
+ void DrawBackground(CFX_Graphics *pGraphics, FX_INT32 iPartBk, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void DrawBorder(CFX_Graphics *pGraphics, FX_INT32 iPartBorder, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void DrawEdge(CFX_Graphics *pGraphics, FX_INT32 iPartEdge, IFWL_ThemeProvider *pTheme, const CFX_Matrix *pMatrix = NULL);
+ void NotifyDriver();
+
+ FX_BOOL IsParent(IFWL_Widget *pParent);
+ CFWL_WidgetMgr *m_pWidgetMgr;
+ CFWL_NoteThread *m_pOwnerThread;
+ CFWL_WidgetImpProperties *m_pProperties;
+ CFX_PrivateData *m_pPrivateData;
+ IFWL_WidgetDelegate *m_pDelegate;
+ IFWL_WidgetDelegate *m_pCurDelegate;
+ IFWL_Widget *m_pOuter;
+ IFWL_Widget *m_pInterface;
+ FX_INT32 m_iLock;
+ friend class CFWL_WidgetImpDelegate;
+ friend void FWL_SetWidgetRect(IFWL_Widget *widget, const CFX_RectF &rect);
+ friend void FWL_SetWidgetStates(IFWL_Widget *widget, FX_DWORD dwStates);
+ friend void FWL_SetWidgetStyles(IFWL_Widget *widget, FX_DWORD dwStyles);
+};
+class CFWL_WidgetImpDelegate : public CFX_Object
+{
+public:
+ CFWL_WidgetImpDelegate();
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+};
+#endif
diff --git a/xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h b/xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h
new file mode 100644
index 0000000000..3defb63f08
--- /dev/null
+++ b/xfa/src/fwl/src/core/include/fwl_widgetmgrimp.h
@@ -0,0 +1,142 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FWL_WIDGETMGR_IMP_H
+#define _FWL_WIDGETMGR_IMP_H
+class CFWL_Target;
+class IFWL_Widget;
+class IFWL_AdapterWidgetMgr;
+class CFWL_WidgetMgrItem;
+class CFWL_WidgetMgr;
+class CFWL_WidgetMgrDelegate;
+class IFWL_AdapterNative;
+class CFWL_WidgetMgrItem : public CFX_Object
+{
+public:
+ CFWL_WidgetMgrItem()
+ : pParent(NULL)
+ , pOwner(NULL)
+ , pChild(NULL)
+ , pPrevious(NULL)
+ , pNext(NULL)
+ , pWidget(NULL)
+ , pOffscreen(NULL)
+ , iRedrawCounter(0)
+#if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
+ , bOutsideChanged(FALSE)
+#endif
+ {
+ }
+ ~CFWL_WidgetMgrItem()
+ {
+ if (pOffscreen) {
+ delete pOffscreen;
+ pOffscreen = NULL;
+ }
+ }
+ CFWL_WidgetMgrItem *pParent;
+ CFWL_WidgetMgrItem *pOwner;
+ CFWL_WidgetMgrItem *pChild;
+ CFWL_WidgetMgrItem *pPrevious;
+ CFWL_WidgetMgrItem *pNext;
+ IFWL_Widget *pWidget;
+ CFX_Graphics *pOffscreen;
+ FX_INT32 iRedrawCounter;
+#if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
+ FX_BOOL bOutsideChanged;
+#endif
+};
+class CFWL_WidgetMgr : public CFX_Object
+{
+public:
+ CFWL_WidgetMgr(IFWL_AdapterNative *pAdapterNative);
+ ~CFWL_WidgetMgr();
+ virtual FX_INT32 CountWidgets(IFWL_Widget *pParent = NULL);
+ virtual IFWL_Widget* GetWidget(FX_INT32 nIndex, IFWL_Widget *pParent = NULL);
+ virtual IFWL_Widget* GetWidget(IFWL_Widget *pWidget, FWL_WGTRELATION eRelation);
+ virtual FX_INT32 GetWidgetIndex(IFWL_Widget *pWidget);
+ virtual FX_BOOL SetWidgetIndex(IFWL_Widget *pWidget, FX_INT32 nIndex);
+ virtual FX_BOOL IsWidget(FX_LPVOID pObj);
+ virtual FWL_ERR RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect = NULL);
+ virtual FX_DWORD GetCapability()
+ {
+ return m_dwCapability;
+ }
+ void AddWidget(IFWL_Widget *pWidget);
+ void InsertWidget(IFWL_Widget *pParent, IFWL_Widget *pChild, FX_INT32 nIndex = -1);
+ void RemoveWidget(IFWL_Widget *pWidget);
+ void SetOwner(IFWL_Widget *pOwner, IFWL_Widget *pOwned);
+ void SetParent(IFWL_Widget *pParent, IFWL_Widget *pChild);
+ FX_BOOL IsChild(IFWL_Widget *pChild, IFWL_Widget *pParent);
+ FWL_ERR CreateWidget_Native(IFWL_Widget *pWidget);
+ FWL_ERR DestroyWidget_Native(IFWL_Widget *pWidget);
+ FWL_ERR GetWidgetRect_Native(IFWL_Widget *pWidget, CFX_RectF &rect);
+ FWL_ERR SetWidgetRect_Native(IFWL_Widget *pWidget, const CFX_RectF &rect);
+ FWL_ERR SetWidgetPosition_Native(IFWL_Widget *pWidget, FX_FLOAT fx, FX_FLOAT fy);
+ FWL_ERR SetWidgetIcon_Native(IFWL_Widget *pWidget, const CFX_DIBitmap *pIcon, FX_BOOL bBig);
+ FWL_ERR SetWidgetCaption_Native(IFWL_Widget *pWidget, FX_WSTR wsCaption);
+ FWL_ERR SetBorderRegion_Native(IFWL_Widget *pWidget, CFX_Path *pPath);
+ FWL_ERR ShowWidget_Native(IFWL_Widget *pWidget);
+ FWL_ERR HideWidget_Native(IFWL_Widget *pWidget);
+ FWL_ERR SetNormal_Native(IFWL_Widget *pWidget);
+ FWL_ERR SetMaximize_Native(IFWL_Widget *pWidget);
+ FWL_ERR SetMinimize_Native(IFWL_Widget *pWidget);
+ FX_BOOL CheckMessage_Native();
+ FWL_ERR DispatchMessage_Native();
+ FX_BOOL IsIdleMessage_Native();
+ FWL_ERR Exit_Native(FX_INT32 iExitCode);
+ FWL_ERR CreateWidgetWithNativeId_Native(IFWL_Widget *pWidget, void *vp);
+ IFWL_Widget* GetWidgetAtPoint(IFWL_Widget *pParent, FX_FLOAT fx, FX_FLOAT fy);
+ void NotifySizeChanged(IFWL_Widget *pForm, FX_FLOAT fx, FX_FLOAT fy);
+ IFWL_Widget* nextTab(IFWL_Widget *parent, IFWL_Widget *focus, FX_BOOL &bFind);
+ FX_INT32 CountRadioButtonGroup(IFWL_Widget *pFirst);
+ IFWL_Widget* GetSiblingRadioButton(IFWL_Widget *pWidget, FX_BOOL bNext);
+ IFWL_Widget* GetRadioButtonGroupHeader(IFWL_Widget *pRadioButton);
+ void GetSameGroupRadioButton(IFWL_Widget *pRadioButton, CFX_PtrArray &group);
+ IFWL_Widget* GetDefaultButton(IFWL_Widget *pParent);
+ void AddRedrawCounts(IFWL_Widget *pWidget);
+ void ResetRedrawCounts(IFWL_Widget *pWidget);
+ IFWL_AdapterWidgetMgr* GetAdapterWidgetMgr()
+ {
+ return m_pAdapter;
+ }
+ CFWL_WidgetMgrDelegate* GetDelegate()
+ {
+ return m_pDelegate;
+ }
+ CFWL_WidgetMgrItem* GetWidgetMgrItem(IFWL_Widget *pWidget);
+ FX_BOOL IsThreadEnabled();
+ FX_BOOL IsFormDisabled();
+ FX_BOOL GetAdapterPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+protected:
+ FX_INT32 TravelWidgetMgr(CFWL_WidgetMgrItem *pParent, FX_INT32 *pIndex, CFWL_WidgetMgrItem *pItem, IFWL_Widget **pWidget = NULL);
+ FX_BOOL IsAbleNative(IFWL_Widget *pWidget);
+ CFX_MapPtrToPtr m_mapWidgetItem;
+ IFWL_AdapterWidgetMgr *m_pAdapter;
+ CFWL_WidgetMgrDelegate *m_pDelegate;
+ friend class CFWL_WidgetMgrDelegate;
+ FX_DWORD m_dwCapability;
+#if (_FX_OS_==_FX_WIN32_DESKTOP_) || (_FX_OS_==_FX_WIN64_)
+ CFX_RectF m_rtScreen;
+#endif
+};
+class CFWL_WidgetMgrDelegate : public CFX_Object
+{
+public:
+ CFWL_WidgetMgrDelegate(CFWL_WidgetMgr *pWidgetMgr);
+ virtual FWL_ERR OnSetCapability(FX_DWORD dwCapability = FWL_WGTMGR_DisableThread);
+ virtual FX_INT32 OnProcessMessageToForm(CFWL_Message *pMessage);
+ virtual FWL_ERR OnDrawWidget(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix );
+protected:
+ void DrawChild(IFWL_Widget *pParent, const CFX_RectF &rtClip, CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix );
+ CFX_Graphics* DrawWidgetBefore(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix);
+ void DrawWidgetAfter(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, CFX_RectF &rtClip, const CFX_Matrix *pMatrix);
+ FX_BOOL IsNeedRepaint(IFWL_Widget *pWidget, CFX_Matrix *pMatrix, const CFX_RectF &rtDirty);
+ FX_BOOL bUseOffscreenDirect(IFWL_Widget *pWidget);
+
+ CFWL_WidgetMgr *m_pWidgetMgr;
+};
+#endif
diff --git a/xfa/src/fwl/src/lightwidget/app.cpp b/xfa/src/fwl/src/lightwidget/app.cpp
new file mode 100644
index 0000000000..e89b6c86de
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/app.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_App::CFWL_App()
+ : m_pAppImp(NULL)
+ , m_pThemeProvider(NULL)
+{
+ m_pAppImp = IFWL_App::Create(NULL);
+}
+CFWL_App::~CFWL_App()
+{
+ if (m_pThemeProvider) {
+ m_pThemeProvider->Finalize();
+ delete m_pThemeProvider;
+ m_pThemeProvider = NULL;
+ }
+ m_pAppImp->Release();
+}
+FWL_ERR CFWL_App::Initialize()
+{
+ m_pThemeProvider = FX_NEW CFWL_Theme;
+ m_pThemeProvider->Initialize();
+ m_pAppImp->SetThemeProvider((IFWL_ThemeProvider*)m_pThemeProvider);
+ return m_pAppImp->Initialize();
+}
+CFWL_Theme* CFWL_App::GetTheme()
+{
+ return m_pThemeProvider;
+}
+FWL_ERR CFWL_App::Exit(FX_INT32 iExitCode )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pAppImp, FWL_ERR_Indefinite);
+ return m_pAppImp->Exit(iExitCode);
+}
+IFWL_App* CFWL_App::GetApp()
+{
+ return m_pAppImp;
+}
diff --git a/xfa/src/fwl/src/lightwidget/barcode.cpp b/xfa/src/fwl/src/lightwidget/barcode.cpp
new file mode 100644
index 0000000000..6c770c3b2c
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/barcode.cpp
@@ -0,0 +1,57 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_Barcode* CFWL_Barcode::Create()
+{
+ return FX_NEW CFWL_Barcode;
+}
+FWL_ERR CFWL_Barcode::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_pDataProvider = &m_barcodeData;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ m_pImp = IFWL_Barcode::Create();
+ FWL_ERR ret = ((IFWL_Barcode*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+CFWL_Barcode::CFWL_Barcode()
+{
+}
+CFWL_Barcode::~CFWL_Barcode()
+{
+}
+void CFWL_Barcode::SetType(BC_TYPE type)
+{
+ _FWL_RETURN_IF_FAIL(m_pImp);
+ ((IFWL_Barcode*)m_pImp)->SetType(type);
+}
+FX_BOOL CFWL_Barcode::IsProtectedType()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_Barcode*)m_pImp)->IsProtectedType();
+}
+FWL_ERR CFWL_Barcode::CFWL_BarcodeDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fwl/src/lightwidget/caret.cpp b/xfa/src/fwl/src/lightwidget/caret.cpp
new file mode 100644
index 0000000000..a93e5d9dc5
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/caret.cpp
@@ -0,0 +1,58 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_Caret* CFWL_Caret::Create()
+{
+ return FX_NEW CFWL_Caret;
+}
+FWL_ERR CFWL_Caret::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ m_pImp = IFWL_Caret::Create();
+ FWL_ERR ret = ((IFWL_Caret*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FWL_ERR CFWL_Caret::ShowCaret(FX_BOOL bFlag)
+{
+ return ((IFWL_Caret*)m_pImp)->ShowCaret(bFlag);
+}
+FWL_ERR CFWL_Caret::GetFrequency(FX_DWORD &elapse)
+{
+ return ((IFWL_Caret*)m_pImp)->GetFrequency(elapse);
+}
+FWL_ERR CFWL_Caret::SetFrequency(FX_DWORD elapse)
+{
+ return ((IFWL_Caret*)m_pImp)->SetFrequency(elapse);
+}
+FWL_ERR CFWL_Caret::SetColor(CFX_Color crFill)
+{
+ return ((IFWL_Caret*)m_pImp)->SetColor(crFill);
+}
+CFWL_Caret::CFWL_Caret()
+{
+}
+CFWL_Caret::~CFWL_Caret()
+{
+}
diff --git a/xfa/src/fwl/src/lightwidget/checkbox.cpp b/xfa/src/fwl/src/lightwidget/checkbox.cpp
new file mode 100644
index 0000000000..cb659fffa7
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/checkbox.cpp
@@ -0,0 +1,75 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_CheckBox* CFWL_CheckBox::Create()
+{
+ return FX_NEW CFWL_CheckBox;
+}
+FWL_ERR CFWL_CheckBox::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_pDataProvider = &m_checkboxData;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ m_pImp = IFWL_CheckBox::Create();
+ FWL_ERR ret = ((IFWL_CheckBox*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FWL_ERR CFWL_CheckBox::SetCaption(FX_WSTR wsCaption)
+{
+ m_checkboxData.m_wsCaption = wsCaption;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_CheckBox::SetBoxSize(FX_FLOAT fHeight)
+{
+ m_checkboxData.m_fBoxHeight = fHeight;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_CheckBox::GetCheckState()
+{
+ return ((IFWL_CheckBox*)m_pImp)->GetCheckState();
+}
+FWL_ERR CFWL_CheckBox::SetCheckState(FX_INT32 iCheck)
+{
+ return ((IFWL_CheckBox*)m_pImp)->SetCheckState(iCheck);
+}
+CFWL_CheckBox::CFWL_CheckBox()
+{
+}
+CFWL_CheckBox::~CFWL_CheckBox()
+{
+}
+CFWL_CheckBox::CFWL_CheckBoxDP::CFWL_CheckBoxDP()
+ : m_fBoxHeight(16.0f)
+ , m_wsCaption(L"Check box")
+{
+}
+FWL_ERR CFWL_CheckBox::CFWL_CheckBoxDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ wsCaption = m_wsCaption;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_CheckBox::CFWL_CheckBoxDP::GetBoxSize(IFWL_Widget *pWidget)
+{
+ return m_fBoxHeight;
+}
diff --git a/xfa/src/fwl/src/lightwidget/combobox.cpp b/xfa/src/fwl/src/lightwidget/combobox.cpp
new file mode 100644
index 0000000000..557dc2d2b5
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/combobox.cpp
@@ -0,0 +1,361 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_ComboBox* CFWL_ComboBox::Create()
+{
+ return FX_NEW CFWL_ComboBox;
+}
+FWL_ERR CFWL_ComboBox::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_pDataProvider = &m_comboBoxData;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ m_pImp = IFWL_ComboBox::Create();
+ FWL_ERR ret = ((IFWL_ComboBox*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FX_INT32 CFWL_ComboBox::AddString(FX_WSTR wsText)
+{
+ CFWL_ComboBoxItem *pItem = FX_NEW CFWL_ComboBoxItem;
+ pItem->m_wsText = wsText;
+ pItem->m_dwStyles = 0;
+ return m_comboBoxData.m_arrItem.Add(pItem);
+}
+FX_INT32 CFWL_ComboBox::AddString(FX_WSTR wsText, CFX_DIBitmap *pIcon)
+{
+ CFWL_ComboBoxItem *pItem = FX_NEW CFWL_ComboBoxItem;
+ pItem->m_wsText = wsText;
+ pItem->m_dwStyles = 0;
+ pItem->m_pDIB = pIcon;
+ return m_comboBoxData.m_arrItem.Add(pItem);
+}
+FX_INT32 CFWL_ComboBox::RemoveAt(FX_INT32 iIndex)
+{
+ return m_comboBoxData.m_arrItem.RemoveAt(iIndex);
+}
+FX_INT32 CFWL_ComboBox::RemoveAll()
+{
+ m_comboBoxData.m_arrItem.RemoveAll();
+ return 0;
+}
+FX_INT32 CFWL_ComboBox::CountItems()
+{
+ return m_comboBoxData.CountItems(GetWidget());
+}
+FWL_ERR CFWL_ComboBox::GetTextByIndex(FX_INT32 iIndex, CFX_WideString &wsText)
+{
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)(m_comboBoxData.GetItem((IFWL_Widget *)this, iIndex));
+ _FWL_RETURN_VALUE_IF_FAIL(pItem, FWL_ERR_Indefinite);
+ wsText = pItem->m_wsText;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ComboBox::GetCurSel()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, -1);
+ return ((IFWL_ComboBox*)m_pImp)->GetCurSel();
+}
+FWL_ERR CFWL_ComboBox::SetCurSel(FX_INT32 iSel)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ComboBox*)m_pImp)->SetCurSel(iSel);
+}
+FWL_ERR CFWL_ComboBox::SetEditText(FX_WSTR wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ComboBox*)m_pImp)->SetEditText(wsText);
+}
+FX_INT32 CFWL_ComboBox::GetEditTextLength() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_ComboBox*)m_pImp)->GetEditTextLength();
+}
+FWL_ERR CFWL_ComboBox::GetEditText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount) const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ComboBox*)m_pImp)->GetEditText(wsText, nStart, nCount);
+}
+FWL_ERR CFWL_ComboBox::SetEditSelRange(FX_INT32 nStart, FX_INT32 nCount)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ComboBox*)m_pImp)->SetEditSelRange(nStart, nCount);
+}
+FX_INT32 CFWL_ComboBox::GetEditSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_ComboBox*)m_pImp)->GetEditSelRange(nIndex, nStart);
+}
+FX_INT32 CFWL_ComboBox::GetEditLimit()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_ComboBox*)m_pImp)->GetEditLimit();
+}
+FWL_ERR CFWL_ComboBox::SetEditLimit(FX_INT32 nLimit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ComboBox*)m_pImp)->SetEditLimit(nLimit);
+}
+FWL_ERR CFWL_ComboBox::EditDoClipboard(FX_INT32 iCmd)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ComboBox*)m_pImp)->EditDoClipboard(iCmd);
+}
+FX_BOOL CFWL_ComboBox::EditRedo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditRedo(bsRecord);
+}
+FX_BOOL CFWL_ComboBox::EditUndo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditUndo(bsRecord);
+}
+FWL_ERR CFWL_ComboBox::SetMaxListHeight(FX_FLOAT fMaxHeight)
+{
+ m_comboBoxData.m_fMaxListHeight = fMaxHeight;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBox::SetItemData(FX_INT32 iIndex, FX_LPVOID pData)
+{
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)(m_comboBoxData.GetItem((IFWL_Widget *)this, iIndex));
+ _FWL_RETURN_VALUE_IF_FAIL(pItem, FWL_ERR_Indefinite);
+ pItem->m_pData = pData;
+ return FWL_ERR_Succeeded;
+}
+FX_LPVOID CFWL_ComboBox::GetItemData(FX_INT32 iIndex)
+{
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)(m_comboBoxData.GetItem((IFWL_Widget *)this, iIndex));
+ _FWL_RETURN_VALUE_IF_FAIL(pItem, NULL);
+ return pItem->m_pData;
+}
+FWL_ERR CFWL_ComboBox::SetListTheme(IFWL_ThemeProvider *pTheme)
+{
+ return ((IFWL_ComboBox*)m_pImp)->GetListBoxt()->SetThemeProvider(pTheme);
+}
+FX_BOOL CFWL_ComboBox::AfterFocusShowDropList()
+{
+ return ((IFWL_ComboBox*)m_pImp)->AfterFocusShowDropList();
+}
+FWL_ERR CFWL_ComboBox::OpenDropDownList(FX_BOOL bActivate)
+{
+ return ((IFWL_ComboBox*)m_pImp)->OpenDropDownList(bActivate);
+}
+FX_BOOL CFWL_ComboBox::EditCanUndo()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditCanUndo();
+}
+FX_BOOL CFWL_ComboBox::EditCanRedo()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditCanRedo();
+}
+FX_BOOL CFWL_ComboBox::EditUndo()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditUndo();
+}
+FX_BOOL CFWL_ComboBox::EditRedo()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditRedo();
+}
+FX_BOOL CFWL_ComboBox::EditCanCopy()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditCanCopy();
+}
+FX_BOOL CFWL_ComboBox::EditCanCut()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditCanCut();
+}
+FX_BOOL CFWL_ComboBox::EditCanSelectAll()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditCanSelectAll();
+}
+FX_BOOL CFWL_ComboBox::EditCopy(CFX_WideString &wsCopy)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditCopy(wsCopy);
+}
+FX_BOOL CFWL_ComboBox::EditCut(CFX_WideString &wsCut)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditCut(wsCut);
+}
+FX_BOOL CFWL_ComboBox::EditPaste(const CFX_WideString &wsPaste)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditPaste(wsPaste);
+}
+FX_BOOL CFWL_ComboBox::EditSelectAll()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditSelectAll();
+}
+FX_BOOL CFWL_ComboBox::EditDelete()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditDelete();
+}
+FX_BOOL CFWL_ComboBox::EditDeSelect()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditDeSelect();
+}
+FWL_ERR CFWL_ComboBox::GetBBox(CFX_RectF &rect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->GetBBox(rect);
+}
+FWL_ERR CFWL_ComboBox::EditModifyStylesEx(FX_DWORD dwStylesExAdded,
+ FX_DWORD dwStylesExRemoved)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ComboBox*)m_pImp)->EditModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+CFWL_ComboBox::CFWL_ComboBox()
+{
+}
+CFWL_ComboBox::~CFWL_ComboBox()
+{
+}
+CFWL_ComboBox::CFWL_ComboBoxDP::CFWL_ComboBoxDP()
+{
+ m_fItemHeight = 0;
+ m_fMaxListHeight = 0;
+}
+CFWL_ComboBox::CFWL_ComboBoxDP::~CFWL_ComboBoxDP()
+{
+ FX_INT32 nCount = m_arrItem.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)m_arrItem[i];
+ if (pItem) {
+ delete pItem;
+ }
+ }
+ m_arrItem.RemoveAll();
+}
+FX_INT32 CFWL_ComboBox::CFWL_ComboBoxDP::CountItems(IFWL_Widget *pWidget)
+{
+ return m_arrItem.GetSize();
+}
+FWL_HLISTITEM CFWL_ComboBox::CFWL_ComboBoxDP::GetItem(IFWL_Widget *pWidget, FX_INT32 nIndex)
+{
+ FX_INT32 iCount = m_arrItem.GetSize();
+ if (nIndex >= iCount || nIndex < 0) {
+ return NULL;
+ }
+ return (FWL_HLISTITEM)m_arrItem[nIndex];
+}
+FX_INT32 CFWL_ComboBox::CFWL_ComboBoxDP::GetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ return m_arrItem.Find(hItem);
+}
+FX_BOOL CFWL_ComboBox::CFWL_ComboBoxDP::SetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_INT32 nIndex)
+{
+ return m_arrItem.SetAt(nIndex, hItem);
+}
+FX_DWORD CFWL_ComboBox::CFWL_ComboBoxDP::GetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, 0);
+ return ((CFWL_ComboBoxItem*)hItem)->m_dwStyles;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::GetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ wsText = ((CFWL_ComboBoxItem*)hItem)->m_wsText;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::GetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF& rtItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)hItem;
+ rtItem.Set(pItem->m_rtItem.left,
+ pItem->m_rtItem.top,
+ pItem->m_rtItem.width,
+ pItem->m_rtItem.height);
+ return FWL_ERR_Succeeded;
+}
+FX_LPVOID CFWL_ComboBox::CFWL_ComboBoxDP::GetItemData(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, NULL);
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)hItem;
+ return pItem->m_pData;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwStyle)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ ((CFWL_ComboBoxItem*)hItem)->m_dwStyles = dwStyle;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_LPCWSTR pszText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ ((CFWL_ComboBoxItem*)hItem)->m_wsText = pszText;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF& rtItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ ((CFWL_ComboBoxItem*)hItem)->m_rtItem = rtItem;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_ComboBox::CFWL_ComboBoxDP::GetItemHeight(IFWL_Widget *pWidget)
+{
+ return m_fItemHeight;
+}
+CFX_DIBitmap* CFWL_ComboBox::CFWL_ComboBoxDP::GetItemIcon(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, NULL);
+ return ((CFWL_ComboBoxItem*)hItem)->m_pDIB;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::GetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF& rtCheck)
+{
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)hItem;
+ rtCheck = pItem->m_rtCheckBox;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF& rtCheck)
+{
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)hItem;
+ pItem->m_rtCheckBox = rtCheck;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ComboBox::CFWL_ComboBoxDP::GetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)hItem;
+ return pItem->m_dwCheckState;
+}
+FWL_ERR CFWL_ComboBox::CFWL_ComboBoxDP::SetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwCheckState)
+{
+ CFWL_ComboBoxItem *pItem = (CFWL_ComboBoxItem*)hItem;
+ pItem->m_dwCheckState = dwCheckState;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_ComboBox::CFWL_ComboBoxDP::GetListHeight(IFWL_Widget *pWidget)
+{
+ return m_fMaxListHeight;
+}
diff --git a/xfa/src/fwl/src/lightwidget/datetimepicker.cpp b/xfa/src/fwl/src/lightwidget/datetimepicker.cpp
new file mode 100644
index 0000000000..4a314c5079
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/datetimepicker.cpp
@@ -0,0 +1,156 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_DateTimePicker* CFWL_DateTimePicker::Create()
+{
+ return FX_NEW CFWL_DateTimePicker;
+}
+FWL_ERR CFWL_DateTimePicker::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_pDataProvider = &m_DateTimePickerDP;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ m_pImp = IFWL_DateTimePicker::Create();
+ FWL_ERR ret = ((IFWL_DateTimePicker*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FWL_ERR CFWL_DateTimePicker::SetToday(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ m_DateTimePickerDP.m_iYear = iYear;
+ m_DateTimePickerDP.m_iMonth = iMonth;
+ m_DateTimePickerDP.m_iDay = iDay;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_DateTimePicker::CountSelRanges()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->CountSelRanges();
+}
+FX_INT32 CFWL_DateTimePicker::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->GetSelRange(nIndex, nStart);
+}
+FWL_ERR CFWL_DateTimePicker::GetEditText(CFX_WideString &wsText)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->GetEditText(wsText);
+}
+FWL_ERR CFWL_DateTimePicker::SetEditText(FX_WSTR wsText)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->SetEditText(wsText);
+}
+FWL_ERR CFWL_DateTimePicker::GetCurSel(FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->GetCurSel(iYear, iMonth, iDay);
+}
+FWL_ERR CFWL_DateTimePicker::SetCurSel(FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->SetCurSel(iYear, iMonth, iDay);
+}
+CFWL_DateTimePicker::CFWL_DateTimePicker()
+{
+}
+CFWL_DateTimePicker::~CFWL_DateTimePicker()
+{
+}
+CFWL_DateTimePicker::CFWL_DateTimePickerDP::CFWL_DateTimePickerDP()
+{
+ m_iYear = 2011;
+ m_iMonth = 1;
+ m_iDay = 1;
+}
+FWL_ERR CFWL_DateTimePicker::CFWL_DateTimePickerDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ wsCaption = m_wsData;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_DateTimePicker::CFWL_DateTimePickerDP::GetToday(IFWL_Widget *pWidget, FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay)
+{
+ iYear = m_iYear;
+ iMonth = m_iMonth;
+ iDay = m_iDay;
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_DateTimePicker::CanUndo()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->CanUndo();
+}
+FX_BOOL CFWL_DateTimePicker::CanRedo()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->CanRedo();
+}
+FX_BOOL CFWL_DateTimePicker::Undo()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->Undo();
+}
+FX_BOOL CFWL_DateTimePicker::Redo()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->Redo();
+}
+FX_BOOL CFWL_DateTimePicker::CanCopy()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->CanCopy();
+}
+FX_BOOL CFWL_DateTimePicker::CanCut()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->CanCut();
+}
+FX_BOOL CFWL_DateTimePicker::CanSelectAll()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->CanSelectAll();
+}
+FX_BOOL CFWL_DateTimePicker::Copy(CFX_WideString &wsCopy)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->Copy(wsCopy);
+}
+FX_BOOL CFWL_DateTimePicker::Cut(CFX_WideString &wsCut)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->Copy(wsCut);
+}
+FX_BOOL CFWL_DateTimePicker::Paste(const CFX_WideString &wsPaste)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->Paste(wsPaste);
+}
+FX_BOOL CFWL_DateTimePicker::SelectAll()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->SelectAll();
+}
+FX_BOOL CFWL_DateTimePicker::Delete()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->Delete();
+}
+FX_BOOL CFWL_DateTimePicker::DeSelect()
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->DeSelect();
+}
+FWL_ERR CFWL_DateTimePicker::GetBBox(CFX_RectF &rect)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->GetBBox(rect);
+}
+FWL_ERR CFWL_DateTimePicker::SetEditLimit(FX_INT32 nLimit)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->SetEditLimit(nLimit);
+}
+FWL_ERR CFWL_DateTimePicker::ModifyEditStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ return ((IFWL_DateTimePicker*)m_pImp)->ModifyEditStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
diff --git a/xfa/src/fwl/src/lightwidget/edit.cpp b/xfa/src/fwl/src/lightwidget/edit.cpp
new file mode 100644
index 0000000000..c87f83fac6
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/edit.cpp
@@ -0,0 +1,226 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_Edit* CFWL_Edit::Create()
+{
+ return FX_NEW CFWL_Edit;
+}
+FWL_ERR CFWL_Edit::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ m_pImp = IFWL_Edit::Create();
+ FWL_ERR ret = ((IFWL_Edit*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FWL_ERR CFWL_Edit::SetText(const CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->SetText(wsText);
+}
+FX_INT32 CFWL_Edit::GetTextLength() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_Edit*)m_pImp)->GetTextLength();
+}
+FWL_ERR CFWL_Edit::GetText(CFX_WideString &wsText, FX_INT32 nStart, FX_INT32 nCount) const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->GetText(wsText, nStart, nCount);
+}
+FWL_ERR CFWL_Edit::ClearText()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->ClearText();
+}
+FX_INT32 CFWL_Edit::GetCaretPos() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, -1);
+ return ((IFWL_Edit*)m_pImp)->GetCaretPos();
+}
+FX_INT32 CFWL_Edit::SetCaretPos(FX_INT32 nIndex, FX_BOOL bBefore)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, -1);
+ return ((IFWL_Edit*)m_pImp)->SetCaretPos(nIndex, bBefore);
+}
+FWL_ERR CFWL_Edit::AddSelRange(FX_INT32 nStart, FX_INT32 nCount)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ ((IFWL_Edit*)m_pImp)->AddSelRange(nStart, nCount);
+ FX_INT32 pos = 0;
+ FX_INT32 sum = ((IFWL_Edit*)m_pImp)->GetTextLength();
+ if (nCount == -1) {
+ pos = sum;
+ } else {
+ pos = nStart + nCount;
+ }
+ return ((IFWL_Edit*)m_pImp)->SetCaretPos(pos);
+}
+FX_INT32 CFWL_Edit::CountSelRanges()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_Edit*)m_pImp)->CountSelRanges();
+}
+FX_INT32 CFWL_Edit::GetSelRange(FX_INT32 nIndex, FX_INT32 &nStart)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_Edit*)m_pImp)->GetSelRange(nIndex, nStart);
+}
+FWL_ERR CFWL_Edit::ClearSelections()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->ClearSelections();
+}
+FX_INT32 CFWL_Edit::GetLimit()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, -1);
+ return ((IFWL_Edit*)m_pImp)->GetLimit();
+}
+FWL_ERR CFWL_Edit::SetLimit(FX_INT32 nLimit)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->SetLimit(nLimit);
+}
+FWL_ERR CFWL_Edit::SetAliasChar(FX_WCHAR wAlias)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->SetAliasChar(wAlias);
+}
+FWL_ERR CFWL_Edit::SetFormatString(const CFX_WideString &wsFormat)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->SetFormatString(wsFormat);
+}
+FWL_ERR CFWL_Edit::Insert(FX_INT32 nStart, FX_LPCWSTR lpText, FX_INT32 nLen)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->Insert(nStart, lpText, nLen);
+}
+FWL_ERR CFWL_Edit::DeleteSelections()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->DeleteSelections();
+}
+FWL_ERR CFWL_Edit::DeleteRange(FX_INT32 nStart, FX_INT32 nCount)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->DeleteRange(nStart, nCount);
+}
+FWL_ERR CFWL_Edit::ReplaceSelections(const CFX_WideStringC &wsReplace)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->ReplaceSelections(wsReplace);
+}
+FWL_ERR CFWL_Edit::Replace(FX_INT32 nStart, FX_INT32 nLen, const CFX_WideStringC &wsReplace)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->Replace(nStart, nLen, wsReplace);
+}
+FWL_ERR CFWL_Edit::DoClipboard(FX_INT32 iCmd)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->DoClipboard(iCmd);
+}
+FX_BOOL CFWL_Edit::Redo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_Edit*)m_pImp)->Redo(bsRecord);
+}
+FX_BOOL CFWL_Edit::Undo(FX_BSTR bsRecord)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_Edit*)m_pImp)->Undo(bsRecord);
+}
+FWL_ERR CFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->SetTabWidth(fTabWidth, bEquidistant);
+}
+FWL_ERR CFWL_Edit::SetNumberRange(FX_INT32 iMin, FX_INT32 iMax)
+{
+ if (iMin > iMax) {
+ return FWL_ERR_Parameter_Invalid;
+ }
+ return ((IFWL_Edit*)m_pImp)->SetNumberRange(iMin, iMax);
+}
+FWL_ERR CFWL_Edit::SetBackColor(FX_DWORD dwColor)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->SetBackColor(dwColor);
+}
+FWL_ERR CFWL_Edit::SetFont(const CFX_WideString &wsFont, FX_FLOAT fSize)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_Edit*)m_pImp)->SetFont(wsFont, fSize);
+}
+FX_BOOL CFWL_Edit::CanUndo()
+{
+ return ((IFWL_Edit*)m_pImp)->CanUndo();
+}
+FX_BOOL CFWL_Edit::CanRedo()
+{
+ return ((IFWL_Edit*)m_pImp)->CanRedo();
+}
+FX_BOOL CFWL_Edit::Undo()
+{
+ return ((IFWL_Edit*)m_pImp)->Undo();
+}
+FX_BOOL CFWL_Edit::Redo()
+{
+ return ((IFWL_Edit*)m_pImp)->Undo();
+}
+FX_BOOL CFWL_Edit::Copy(CFX_WideString &wsCopy)
+{
+ return ((IFWL_Edit*)m_pImp)->Copy(wsCopy);
+}
+FX_BOOL CFWL_Edit::Cut(CFX_WideString &wsCut)
+{
+ return ((IFWL_Edit*)m_pImp)->Cut(wsCut);
+}
+FX_BOOL CFWL_Edit::Paste(const CFX_WideString &wsPaste)
+{
+ return ((IFWL_Edit*)m_pImp)->Paste(wsPaste);
+}
+FX_BOOL CFWL_Edit::Delete()
+{
+ return ((IFWL_Edit*)m_pImp)->Delete();
+}
+void CFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset)
+{
+ return ((IFWL_Edit*)m_pImp)->SetScrollOffset(fScrollOffset);
+}
+FX_BOOL CFWL_Edit::GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest)
+{
+ return ((IFWL_Edit*)m_pImp)->GetSuggestWords(pointf, sSuggest);
+}
+FX_BOOL CFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace)
+{
+ return ((IFWL_Edit*)m_pImp)->ReplaceSpellCheckWord(pointf, bsReplace);
+}
+CFWL_Edit::CFWL_Edit()
+{
+}
+CFWL_Edit::~CFWL_Edit()
+{
+}
diff --git a/xfa/src/fwl/src/lightwidget/listbox.cpp b/xfa/src/fwl/src/lightwidget/listbox.cpp
new file mode 100644
index 0000000000..7cc3878d3f
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/listbox.cpp
@@ -0,0 +1,327 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_ListBox* CFWL_ListBox::Create()
+{
+ return FX_NEW CFWL_ListBox;
+}
+FWL_ERR CFWL_ListBox::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_pDataProvider = &m_ListBoxDP;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ m_pImp = IFWL_ListBox::Create();
+ FWL_ERR ret = ((IFWL_ListBox*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FWL_ERR CFWL_ListBox::AddDIBitmap(CFX_DIBitmap *pDIB, FWL_HLISTITEM hItem)
+{
+ ((CFWL_ListItem*)hItem)->m_pDIB = pDIB;
+ return FWL_ERR_Succeeded;
+}
+FWL_HLISTITEM CFWL_ListBox::AddString(FX_WSTR wsAdd, FX_BOOL bSelect)
+{
+ CFWL_ListItem * pItem = FX_NEW CFWL_ListItem;
+ pItem->m_dwStates = 0;
+ pItem->m_wsText = wsAdd;
+ pItem->m_dwStates = bSelect ? FWL_ITEMSTATE_LTB_Selected : 0;
+ m_ListBoxDP.m_arrItem.Add(pItem);
+ return (FWL_HLISTITEM)pItem;
+}
+FX_BOOL CFWL_ListBox::DeleteString(FWL_HLISTITEM hItem)
+{
+ FX_INT32 nIndex = m_ListBoxDP.GetItemIndex(GetWidget(), hItem);
+ if (nIndex < 0 || nIndex >= m_ListBoxDP.m_arrItem.GetSize()) {
+ return FALSE;
+ }
+ CFWL_ListItem *pDelItem = (CFWL_ListItem*)m_ListBoxDP.GetItem((IFWL_ListBox*)this, nIndex);
+ FX_INT32 iCount = m_ListBoxDP.CountItems((IFWL_ListBox*)this);
+ FX_INT32 iSel = nIndex + 1;
+ if (iSel >= iCount) {
+ iSel = nIndex - 1;
+ if (iSel < 0) {
+ iSel = -1;
+ }
+ }
+ if (iSel >= 0) {
+ CFWL_ListItem *pSel = (CFWL_ListItem*)m_ListBoxDP.GetItem((IFWL_ListBox*)this, iSel);
+ pSel->m_dwStates |= FWL_ITEMSTATE_LTB_Selected;
+ }
+ m_ListBoxDP.m_arrItem.RemoveAt(nIndex);
+ delete pDelItem;
+ return TRUE;
+}
+FX_BOOL CFWL_ListBox::DeleteAll()
+{
+ FX_INT32 iCount = m_ListBoxDP.CountItems((IFWL_ListBox*)this);
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_ListItem *pItem = (CFWL_ListItem*)m_ListBoxDP.GetItem((IFWL_ListBox*)this, i);
+ delete pItem;
+ }
+ m_ListBoxDP.m_arrItem.RemoveAll();
+ return TRUE;
+}
+FX_INT32 CFWL_ListBox::CountSelItems()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_ListBox*)m_pImp)->CountSelItems();
+}
+FWL_HLISTITEM CFWL_ListBox::GetSelItem(FX_INT32 nIndexSel)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, NULL);
+ return ((IFWL_ListBox*)m_pImp)->GetSelItem(nIndexSel);
+}
+FX_INT32 CFWL_ListBox::GetSelIndex(FX_INT32 nIndex)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_ListBox*)m_pImp)->GetSelIndex(nIndex);
+}
+FWL_ERR CFWL_ListBox::SetSelItem(FWL_HLISTITEM hItem, FX_BOOL bSelect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ListBox*)m_pImp)->SetSelItem(hItem, bSelect);
+}
+FWL_ERR CFWL_ListBox::GetItemText(FWL_HLISTITEM hItem, CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ListBox*)m_pImp)->GetItemText(hItem, wsText);
+}
+FWL_ERR CFWL_ListBox::GetScrollPos(FX_FLOAT &fPos, FX_BOOL bVert)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ListBox*)m_pImp)->GetScrollPos(fPos, bVert);
+}
+FWL_ERR CFWL_ListBox::SetItemHeight(FX_FLOAT fItemHeight)
+{
+ m_ListBoxDP.m_fItemHeight = fItemHeight;
+ return FWL_ERR_Succeeded;
+}
+FWL_HLISTITEM CFWL_ListBox::GetFocusItem()
+{
+ for (FX_INT32 i = 0; i < m_ListBoxDP.m_arrItem.GetSize(); i++) {
+ CFWL_ListItem * hItem = (CFWL_ListItem *)(m_ListBoxDP.m_arrItem[i]);
+ if (hItem->m_dwStates & FWL_ITEMSTATE_LTB_Focused) {
+ return (FWL_HLISTITEM)hItem;
+ }
+ }
+ return NULL;
+}
+FWL_ERR CFWL_ListBox::SetFocusItem(FWL_HLISTITEM hItem)
+{
+ FX_INT32 nIndex = m_ListBoxDP.GetItemIndex(GetWidget(), hItem);
+ ((CFWL_ListItem *)(m_ListBoxDP.m_arrItem[nIndex]))->m_dwStates |= FWL_ITEMSTATE_LTB_Focused;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR* CFWL_ListBox::Sort(IFWL_ListBoxCompare *pCom)
+{
+ return ((IFWL_ListBox*)m_pImp)->Sort(pCom);
+}
+FX_INT32 CFWL_ListBox::CountItems()
+{
+ return m_ListBoxDP.m_arrItem.GetSize();
+}
+FWL_HLISTITEM CFWL_ListBox::GetItem(FX_INT32 nIndex)
+{
+ FX_INT32 nCount = m_ListBoxDP.m_arrItem.GetSize();
+ if (nIndex > nCount - 1 && nIndex < 0) {
+ return NULL;
+ }
+ return (FWL_HLISTITEM)m_ListBoxDP.m_arrItem[nIndex];
+}
+FWL_ERR CFWL_ListBox::SetItemString(FWL_HLISTITEM hItem, FX_WSTR wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ pItem->m_wsText = wsText;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBox::GetItemString(FWL_HLISTITEM hItem, CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ wsText = pItem->m_wsText;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBox::SetItemData(FWL_HLISTITEM hItem, FX_LPVOID pData)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ pItem->m_pData = pData;
+ return FWL_ERR_Succeeded;
+}
+FX_LPVOID CFWL_ListBox::GetItemData(FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, NULL);
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ return pItem->m_pData;
+}
+FWL_HLISTITEM CFWL_ListBox::GetItemAtPoint(FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rtClient;
+ m_pImp->GetClientRect(rtClient);
+ fx -= rtClient.left;
+ fy -= rtClient.top;
+ FX_FLOAT fPosX = 0;
+ FX_FLOAT fPosY = 0;
+ ((IFWL_ListBox*)m_pImp)->GetScrollPos(fx);
+ ((IFWL_ListBox*)m_pImp)->GetScrollPos(fy, FALSE);
+ FX_INT32 nCount = m_ListBoxDP.CountItems(NULL);
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ FWL_HLISTITEM hItem = m_ListBoxDP.GetItem(NULL, i);
+ if (!hItem) {
+ continue;
+ }
+ CFX_RectF rtItem;
+ m_ListBoxDP.GetItemRect(NULL, hItem, rtItem);
+ rtItem.Offset(-fPosX, -fPosY);
+ if (rtItem.Contains(fx, fy)) {
+ return hItem;
+ }
+ }
+ return NULL;
+}
+FX_DWORD CFWL_ListBox::GetItemStates(FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, 0);
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ return pItem->m_dwStates | pItem->m_dwCheckState;
+}
+CFWL_ListBox::CFWL_ListBox()
+{
+}
+CFWL_ListBox::~CFWL_ListBox()
+{
+}
+CFWL_ListBox::CFWL_ListBoxDP::CFWL_ListBoxDP()
+{
+}
+CFWL_ListBox::CFWL_ListBoxDP::~CFWL_ListBoxDP()
+{
+ FX_INT32 nCount = m_arrItem.GetSize();
+ for (FX_INT32 i = 0; i < nCount; i ++) {
+ CFWL_ListItem *pItem = (CFWL_ListItem*)m_arrItem[i];
+ if (pItem != NULL) {
+ delete pItem;
+ }
+ }
+ m_arrItem.RemoveAll();
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ wsCaption = m_wsData;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ListBox::CFWL_ListBoxDP::CountItems(IFWL_Widget *pWidget)
+{
+ return m_arrItem.GetSize();
+}
+FWL_HLISTITEM CFWL_ListBox::CFWL_ListBoxDP::GetItem(IFWL_Widget *pWidget, FX_INT32 nIndex)
+{
+ if (nIndex >= m_arrItem.GetSize() || nIndex < 0) {
+ return NULL;
+ } else {
+ return (FWL_HLISTITEM)m_arrItem[nIndex];
+ }
+}
+FX_INT32 CFWL_ListBox::CFWL_ListBoxDP::GetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ return m_arrItem.Find(hItem);
+}
+FX_BOOL CFWL_ListBox::CFWL_ListBoxDP::SetItemIndex(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_INT32 nIndex)
+{
+ return m_arrItem.SetAt(nIndex, hItem);
+}
+FX_DWORD CFWL_ListBox::CFWL_ListBoxDP::GetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, -1);
+ return ((CFWL_ListItem*)hItem)->m_dwStates;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::GetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_WideString &wsText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ wsText = ((CFWL_ListItem*)hItem)->m_wsText;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::GetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF &rtItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ rtItem = pItem->m_rtItem;
+ return FWL_ERR_Succeeded;
+}
+FX_LPVOID CFWL_ListBox::CFWL_ListBoxDP::GetItemData(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, NULL);
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ return pItem->m_pData;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::SetItemStyles(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwStyle)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ ((CFWL_ListItem*)hItem)->m_dwStates = dwStyle;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::SetItemText(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_LPCWSTR pszText)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ ((CFWL_ListItem*)hItem)->m_wsText = pszText;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::SetItemRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF &rtItem)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(hItem, FWL_ERR_Indefinite);
+ ((CFWL_ListItem*)hItem)->m_rtItem = rtItem;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_ListBox::CFWL_ListBoxDP::GetItemHeight(IFWL_Widget *pWidget)
+{
+ return m_fItemHeight;
+}
+CFX_DIBitmap* CFWL_ListBox::CFWL_ListBoxDP::GetItemIcon(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ return ((CFWL_ListItem*)hItem)->m_pDIB;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::GetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, CFX_RectF& rtCheck)
+{
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ rtCheck = pItem->m_rtCheckBox;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::SetItemCheckRect(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, const CFX_RectF& rtCheck)
+{
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ pItem->m_rtCheckBox = rtCheck;
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_ListBox::CFWL_ListBoxDP::GetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem)
+{
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ return pItem->m_dwCheckState;
+}
+FWL_ERR CFWL_ListBox::CFWL_ListBoxDP::SetItemCheckState(IFWL_Widget *pWidget, FWL_HLISTITEM hItem, FX_DWORD dwCheckState)
+{
+ CFWL_ListItem *pItem = (CFWL_ListItem*)hItem;
+ pItem->m_dwCheckState = dwCheckState;
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fwl/src/lightwidget/picturebox.cpp b/xfa/src/fwl/src/lightwidget/picturebox.cpp
new file mode 100644
index 0000000000..e7d21de90e
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/picturebox.cpp
@@ -0,0 +1,144 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_PictureBox* CFWL_PictureBox::Create()
+{
+ return FX_NEW CFWL_PictureBox;
+}
+FWL_ERR CFWL_PictureBox::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_pDataProvider = &m_PictureBoxDP;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ m_pImp = IFWL_PictureBox::Create();
+ FWL_ERR ret = ((IFWL_PictureBox*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+CFX_DIBitmap* CFWL_PictureBox::GetPicture()
+{
+ return m_PictureBoxDP.m_pBitmap;
+}
+FWL_ERR CFWL_PictureBox::SetPicture(CFX_DIBitmap *pBitmap)
+{
+ m_PictureBoxDP.m_pBitmap = pBitmap;
+ return FWL_ERR_Succeeded;
+}
+FX_FLOAT CFWL_PictureBox::GetRotation()
+{
+ return m_PictureBoxDP.m_fRotation;
+}
+FWL_ERR CFWL_PictureBox::SetRotation(FX_FLOAT fRotation)
+{
+ m_PictureBoxDP.m_fRotation = fRotation;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_PictureBox::GetFlipMode()
+{
+ return m_PictureBoxDP.GetFlipMode((IFWL_Widget*)this);
+}
+FWL_ERR CFWL_PictureBox::SetFlipMode(FX_INT32 iFlipMode)
+{
+ m_PictureBoxDP.m_iFlipMode = iFlipMode;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_PictureBox::GetOpacity()
+{
+ return m_PictureBoxDP.GetOpacity((IFWL_Widget*)this);
+}
+FWL_ERR CFWL_PictureBox::SetOpacity(FX_INT32 iOpacity)
+{
+ m_PictureBoxDP.m_iOpacity = iOpacity;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PictureBox::GetScale(FX_FLOAT &fScaleX, FX_FLOAT &fScaleY)
+{
+ CFX_Matrix matrix;
+ m_PictureBoxDP.GetMatrix((IFWL_Widget*)this, matrix);
+ matrix.Scale(fScaleX, fScaleY);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PictureBox::SetScale(FX_FLOAT fScaleX, FX_FLOAT fScaleY)
+{
+ m_PictureBoxDP.m_fScaleX = fScaleX;
+ m_PictureBoxDP.m_fScaleY = fScaleY;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PictureBox::GetOffset(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ CFX_Matrix matrix;
+ m_PictureBoxDP.GetMatrix((IFWL_Widget*)this, matrix);
+ fx = matrix.e;
+ fy = matrix.f;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PictureBox::SetOffset(FX_FLOAT fx, FX_FLOAT fy)
+{
+ m_PictureBoxDP.m_fOffSetX = fx;
+ m_PictureBoxDP.m_fOffSetY = fy;
+ return FWL_ERR_Succeeded;
+}
+CFWL_PictureBox::CFWL_PictureBox()
+{
+}
+CFWL_PictureBox::~CFWL_PictureBox()
+{
+}
+FWL_ERR CFWL_PictureBox::CFWL_PictureBoxDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ return FWL_ERR_Succeeded;
+}
+CFX_DIBitmap* CFWL_PictureBox::CFWL_PictureBoxDP::GetPicture(IFWL_Widget *pWidget)
+{
+ return m_pBitmap;
+}
+CFX_DIBitmap* CFWL_PictureBox::CFWL_PictureBoxDP::GetErrorPicture(IFWL_Widget *pWidget)
+{
+ return m_pBitmap;
+}
+CFX_DIBitmap* CFWL_PictureBox::CFWL_PictureBoxDP::GetInitialPicture(IFWL_Widget *pWidget)
+{
+ return m_pBitmap;
+}
+FX_INT32 CFWL_PictureBox::CFWL_PictureBoxDP::GetOpacity(IFWL_Widget *pWidget)
+{
+ return m_iOpacity;
+}
+FWL_ERR CFWL_PictureBox::CFWL_PictureBoxDP::GetMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix)
+{
+ CFX_RectF rect;
+ pWidget->GetClientRect(rect);
+ FX_FLOAT fLen = rect.width / 2;
+ FX_FLOAT fWid = rect.height / 2;
+ matrix.Reset();
+ matrix.Translate(-fLen, -fWid);
+ matrix.Rotate(m_fRotation);
+ matrix.Translate(fLen, fWid);
+ matrix.Scale(m_fScaleX, m_fScaleY);
+ matrix.Translate(m_fOffSetX, m_fOffSetY);
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_PictureBox::CFWL_PictureBoxDP::GetFlipMode(IFWL_Widget *pWidget)
+{
+ return m_iFlipMode;
+}
diff --git a/xfa/src/fwl/src/lightwidget/pushbutton.cpp b/xfa/src/fwl/src/lightwidget/pushbutton.cpp
new file mode 100644
index 0000000000..7e4cae2d18
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/pushbutton.cpp
@@ -0,0 +1,71 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_PushButton* CFWL_PushButton::Create()
+{
+ return FX_NEW CFWL_PushButton;
+}
+FWL_ERR CFWL_PushButton::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_pDataProvider = &m_buttonData;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ m_pImp = IFWL_PushButton::Create();
+ FWL_ERR ret = ((IFWL_PushButton*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FWL_ERR CFWL_PushButton::GetCaption(CFX_WideString &wsCaption)
+{
+ wsCaption = m_buttonData.m_wsCaption;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_PushButton::SetCaption(FX_WSTR wsCaption)
+{
+ m_buttonData.m_wsCaption = wsCaption;
+ return FWL_ERR_Succeeded;
+}
+CFX_DIBitmap* CFWL_PushButton::GetPicture()
+{
+ return m_buttonData.m_pBitmap;
+}
+FWL_ERR CFWL_PushButton::SetPicture(CFX_DIBitmap *pBitmap)
+{
+ m_buttonData.m_pBitmap = pBitmap;
+ return FWL_ERR_Succeeded;
+}
+CFWL_PushButton::CFWL_PushButton()
+{
+}
+CFWL_PushButton::~CFWL_PushButton()
+{
+}
+FWL_ERR CFWL_PushButton::CFWL_PushButtonDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ wsCaption = m_wsCaption;
+ return FWL_ERR_Succeeded;
+}
+CFX_DIBitmap* CFWL_PushButton::CFWL_PushButtonDP::GetPicture(IFWL_Widget *pWidget)
+{
+ return m_pBitmap;
+}
diff --git a/xfa/src/fwl/src/lightwidget/scrollbar.cpp b/xfa/src/fwl/src/lightwidget/scrollbar.cpp
new file mode 100644
index 0000000000..492b0f91f5
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/scrollbar.cpp
@@ -0,0 +1,102 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_ScrollBar* CFWL_ScrollBar::Create()
+{
+ return FX_NEW CFWL_ScrollBar;
+}
+FWL_ERR CFWL_ScrollBar::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ m_pImp = IFWL_ScrollBar::Create();
+ FWL_ERR ret = ((IFWL_ScrollBar*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FX_BOOL CFWL_ScrollBar::IsVertical()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ScrollBar*)m_pImp)->IsVertical();
+}
+FWL_ERR CFWL_ScrollBar::GetRange(FX_FLOAT &fMin, FX_FLOAT &fMax)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ScrollBar*)m_pImp)->GetRange(fMin, fMax);
+}
+FWL_ERR CFWL_ScrollBar::SetRange(FX_FLOAT fMin, FX_FLOAT fMax)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ScrollBar*)m_pImp)->SetRange(fMin, fMax);
+}
+FX_FLOAT CFWL_ScrollBar::GetPageSize()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_ScrollBar*)m_pImp)->GetPageSize();
+}
+FWL_ERR CFWL_ScrollBar::SetPageSize(FX_FLOAT fPageSize)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ScrollBar*)m_pImp)->SetPageSize(fPageSize);
+}
+FX_FLOAT CFWL_ScrollBar::GetStepSize()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return ((IFWL_ScrollBar*)m_pImp)->GetStepSize();
+}
+FWL_ERR CFWL_ScrollBar::SetStepSize(FX_FLOAT fStepSize)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ScrollBar*)m_pImp)->SetStepSize(fStepSize);
+}
+FX_FLOAT CFWL_ScrollBar::GetPos()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, -1);
+ return ((IFWL_ScrollBar*)m_pImp)->GetPos();
+}
+FWL_ERR CFWL_ScrollBar::SetPos(FX_FLOAT fPos)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ScrollBar*)m_pImp)->SetPos(fPos);
+}
+FX_FLOAT CFWL_ScrollBar::GetTrackPos()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, -1);
+ return ((IFWL_ScrollBar*)m_pImp)->GetTrackPos();
+}
+FWL_ERR CFWL_ScrollBar::SetTrackPos(FX_FLOAT fTrackPos)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return ((IFWL_ScrollBar*)m_pImp)->SetTrackPos(fTrackPos);
+}
+FX_BOOL CFWL_ScrollBar::DoScroll(FX_DWORD dwCode, FX_FLOAT fPos)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return ((IFWL_ScrollBar*)m_pImp)->DoScroll(dwCode, fPos);
+}
+CFWL_ScrollBar::CFWL_ScrollBar()
+{
+}
+CFWL_ScrollBar::~CFWL_ScrollBar()
+{
+}
diff --git a/xfa/src/fwl/src/lightwidget/theme.cpp b/xfa/src/fwl/src/lightwidget/theme.cpp
new file mode 100644
index 0000000000..a631b37f88
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/theme.cpp
@@ -0,0 +1,155 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+FX_BOOL CFWL_Theme::IsValidWidget(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pWidget);
+ return pTheme != NULL;
+}
+FX_DWORD CFWL_Theme::GetThemeID(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->GetThemeID(pWidget);
+}
+FX_DWORD CFWL_Theme::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ FX_INT32 iCount = m_arrThemes.GetSize();
+ FX_DWORD dwID;
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_WidgetTP *pTheme = (CFWL_WidgetTP*)m_arrThemes[i];
+ dwID = pTheme->GetThemeID(pWidget);
+ pTheme->SetThemeID(pWidget, dwThemeID, FALSE);
+ }
+ return dwID;
+}
+FWL_ERR CFWL_Theme::GetThemeMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_Theme::SetThemeMatrix(IFWL_Widget *pWidget, const CFX_Matrix &matrix)
+{
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_Theme::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pParams->m_pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->DrawBackground(pParams);
+}
+FX_BOOL CFWL_Theme::DrawText(CFWL_ThemeText *pParams)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pParams->m_pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->DrawText(pParams);
+}
+FX_LPVOID CFWL_Theme::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pThemePart->m_pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->GetCapacity(pThemePart, dwCapacity);
+}
+FX_BOOL CFWL_Theme::IsCustomizedLayout(IFWL_Widget *pWidget)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->IsCustomizedLayout(pWidget);
+}
+FWL_ERR CFWL_Theme::GetPartRect(CFWL_ThemePart* pThemePart, CFX_RectF &rtPart)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pThemePart->m_pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->GetPartRect(pThemePart, rtPart);
+}
+FX_BOOL CFWL_Theme::IsInPart(CFWL_ThemePart* pThemePart, FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pThemePart->m_pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->IsInPart(pThemePart, fx, fy);
+}
+FX_BOOL CFWL_Theme::CalcTextRect(CFWL_ThemeText *pParams, CFX_RectF &rect)
+{
+ CFWL_WidgetTP *pTheme = GetTheme(pParams->m_pWidget);
+ FXSYS_assert(pTheme);
+ return pTheme->CalcTextRect(pParams, rect);
+}
+FWL_ERR CFWL_Theme::Initialize()
+{
+ FX_INT32 iCount = m_arrThemes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_WidgetTP *pTheme = (CFWL_WidgetTP*)m_arrThemes[i];
+ pTheme->Initialize();
+ }
+ FWLTHEME_Init();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_Theme::Finalize()
+{
+ FX_INT32 iCount = m_arrThemes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_WidgetTP *pTheme = (CFWL_WidgetTP*)m_arrThemes[i];
+ pTheme->Finalize();
+ }
+ FWLTHEME_Release();
+ return FWL_ERR_Succeeded;
+}
+CFWL_Theme::CFWL_Theme()
+{
+ CFWL_FormTP *pFormTP = FX_NEW CFWL_FormTP;
+ CFWL_PushButtonTP *pPushButtonTP = FX_NEW CFWL_PushButtonTP;
+ CFWL_CheckBoxTP *pCheckBoxTP = FX_NEW CFWL_CheckBoxTP;
+ CFWL_ListBoxTP *pListBoxTP = FX_NEW CFWL_ListBoxTP;
+ CFWL_PictureBoxTP *pPictureBoxTP = FX_NEW CFWL_PictureBoxTP;
+ CFWL_ScrollBarTP *pSrollBarTP = FX_NEW CFWL_ScrollBarTP;
+ CFWL_EditTP *pEditTP = FX_NEW CFWL_EditTP;
+ CFWL_ComboBoxTP *pComboBoxTP = FX_NEW CFWL_ComboBoxTP;
+ CFWL_BarcodeTP *pBarcodeTP = FX_NEW CFWL_BarcodeTP;
+ CFWL_DateTimePickerTP *pDateTimePickerTP = FX_NEW CFWL_DateTimePickerTP;
+ CFWL_MonthCalendarTP *pMonthCalendarTP = FX_NEW CFWL_MonthCalendarTP;
+ CFWL_CaretTP *pCaretTP = FX_NEW CFWL_CaretTP;
+ m_arrThemes.Add(pFormTP);
+ m_arrThemes.Add(pPushButtonTP);
+ m_arrThemes.Add(pCheckBoxTP);
+ m_arrThemes.Add(pListBoxTP);
+ m_arrThemes.Add(pPictureBoxTP);
+ m_arrThemes.Add(pSrollBarTP);
+ m_arrThemes.Add(pEditTP);
+ m_arrThemes.Add(pComboBoxTP);
+ m_arrThemes.Add(pBarcodeTP);
+ m_arrThemes.Add(pDateTimePickerTP);
+ m_arrThemes.Add(pMonthCalendarTP);
+ m_arrThemes.Add(pCaretTP);
+}
+CFWL_Theme::~CFWL_Theme()
+{
+ FX_INT32 iCount = m_arrThemes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_WidgetTP *pTheme = (CFWL_WidgetTP*)m_arrThemes[i];
+ delete pTheme;
+ }
+ m_arrThemes.RemoveAll();
+}
+FWL_ERR CFWL_Theme::SetFont(IFWL_Widget *pWidget, FX_LPCWSTR strFont, FX_FLOAT fFontSize, FX_ARGB rgbFont)
+{
+ FX_INT32 iCount = m_arrThemes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_WidgetTP *pTheme = (CFWL_WidgetTP*)m_arrThemes[i];
+ pTheme->SetFont(pWidget, strFont, fFontSize, rgbFont);
+ }
+ return FWL_ERR_Succeeded;
+}
+CFWL_WidgetTP* CFWL_Theme::GetTheme(IFWL_Widget* pWidget)
+{
+ FX_INT32 iCount = m_arrThemes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i ++) {
+ CFWL_WidgetTP *pTheme = (CFWL_WidgetTP*)m_arrThemes[i];
+ if (pTheme->IsValidWidget(pWidget)) {
+ return pTheme;
+ }
+ }
+ return NULL;
+}
diff --git a/xfa/src/fwl/src/lightwidget/tooltipctrl.cpp b/xfa/src/fwl/src/lightwidget/tooltipctrl.cpp
new file mode 100644
index 0000000000..9397013c07
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/tooltipctrl.cpp
@@ -0,0 +1,141 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_panelimp.h"
+#include "../core/include/fwl_formimp.h"
+#include "../core/include/fwl_threadimp.h"
+CFWL_ToolTip* CFWL_ToolTip::Create()
+{
+ return FX_NEW CFWL_ToolTip;
+}
+FWL_ERR CFWL_ToolTip::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(!m_pImp, FWL_ERR_Indefinite);
+ if (pProperties) {
+ *m_pProperties = *pProperties;
+ }
+ CFWL_WidgetImpProperties prop;
+ prop.m_dwStyles = m_pProperties->m_dwStyles;
+ prop.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ prop.m_dwStates = m_pProperties->m_dwStates;
+ prop.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ prop.m_pDataProvider = &m_tooltipData;
+ if (m_pProperties->m_pParent) {
+ prop.m_pParent = m_pProperties->m_pParent->GetWidget();
+ }
+ if (m_pProperties->m_pOwner) {
+ prop.m_pOwner = m_pProperties->m_pOwner->GetWidget();
+ }
+ prop.m_rtWidget = m_pProperties->m_rtWidget;
+ m_pImp = IFWL_ToolTip::Create();
+ FWL_ERR ret = ((IFWL_ToolTip*)m_pImp)->Initialize(prop);
+ if (ret == FWL_ERR_Succeeded) {
+ CFWL_Widget::Initialize();
+ }
+ return ret;
+}
+FWL_ERR CFWL_ToolTip::GetCaption(CFX_WideString &wsCaption)
+{
+ wsCaption = m_tooltipData.m_wsCaption;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ToolTip::SetCaption(FX_WSTR wsCaption)
+{
+ m_tooltipData.m_wsCaption = wsCaption;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ToolTip::GetInitialDelay()
+{
+ return m_tooltipData.m_nInitDelayTime;
+}
+FX_INT32 CFWL_ToolTip::SetInitialDelay(FX_INT32 nDelayTime)
+{
+ m_tooltipData.m_nInitDelayTime = nDelayTime;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ToolTip::GetAutoPopDelay()
+{
+ return m_tooltipData.m_nAutoPopDelayTime;
+}
+FX_INT32 CFWL_ToolTip::SetAutoPopDelay(FX_INT32 nDelayTime)
+{
+ m_tooltipData.m_nAutoPopDelayTime = nDelayTime;
+ return FWL_ERR_Succeeded;
+}
+CFX_DIBitmap* CFWL_ToolTip::GetToolTipIcon()
+{
+ return m_tooltipData.m_pBitmap;
+}
+FWL_ERR CFWL_ToolTip::SetToolTipIcon(CFX_DIBitmap *pBitmap)
+{
+ m_tooltipData.m_pBitmap = pBitmap;
+ return FWL_ERR_Succeeded;
+}
+CFX_SizeF CFWL_ToolTip::GetToolTipIconSize()
+{
+ return m_tooltipData.m_fIconSize;
+}
+FWL_ERR CFWL_ToolTip::SetToolTipIconSize(CFX_SizeF fSize)
+{
+ m_tooltipData.m_fIconSize = fSize;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_ToolTip::SetAnchor(const CFX_RectF &rtAnchor)
+{
+ return ((IFWL_ToolTip*)m_pImp)->SetAnchor(rtAnchor);
+}
+FWL_ERR CFWL_ToolTip::Show()
+{
+ return ((IFWL_ToolTip*)m_pImp)->Show();
+}
+FWL_ERR CFWL_ToolTip::Hide()
+{
+ return ((IFWL_ToolTip*)m_pImp)->Hide();
+}
+CFWL_ToolTip::CFWL_ToolTip()
+{
+}
+CFWL_ToolTip::~CFWL_ToolTip()
+{
+}
+CFWL_ToolTip::CFWL_ToolTipDP::CFWL_ToolTipDP()
+ : m_pBitmap(NULL)
+{
+ m_wsCaption = L"";
+ m_nInitDelayTime = 500;
+ m_nAutoPopDelayTime = 50000;
+ m_fIconSize.Set( 0.0, 0.0);
+ m_fAnchor.Set( 0.0, 0.0, 0.0, 0.0);
+}
+FWL_ERR CFWL_ToolTip::CFWL_ToolTipDP::GetCaption(IFWL_Widget *pWidget, CFX_WideString &wsCaption)
+{
+ wsCaption = m_wsCaption;
+ return FWL_ERR_Succeeded;
+}
+FX_INT32 CFWL_ToolTip::CFWL_ToolTipDP::GetInitialDelay(IFWL_Widget *pWidget)
+{
+ return m_nInitDelayTime;
+}
+FX_INT32 CFWL_ToolTip::CFWL_ToolTipDP::GetAutoPopDelay(IFWL_Widget *pWidget)
+{
+ return m_nAutoPopDelayTime;
+}
+CFX_DIBitmap* CFWL_ToolTip::CFWL_ToolTipDP::GetToolTipIcon(IFWL_Widget *pWidget)
+{
+ return m_pBitmap;
+}
+CFX_SizeF CFWL_ToolTip::CFWL_ToolTipDP::GetToolTipIconSize(IFWL_Widget *pWidget)
+{
+ return m_fIconSize;
+}
+CFX_RectF CFWL_ToolTip::CFWL_ToolTipDP::GetAnchor()
+{
+ return m_fAnchor;
+}
diff --git a/xfa/src/fwl/src/lightwidget/widget.cpp b/xfa/src/fwl/src/lightwidget/widget.cpp
new file mode 100644
index 0000000000..f080d691bc
--- /dev/null
+++ b/xfa/src/fwl/src/lightwidget/widget.cpp
@@ -0,0 +1,344 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../../src/core/include/fwl_noteimp.h"
+#include "../core/include/fwl_targetimp.h"
+#include "../core/include/fwl_noteimp.h"
+#include "../core/include/fwl_widgetimp.h"
+#include "../core/include/fwl_widgetmgrimp.h"
+IFWL_Widget* CFWL_Widget::GetWidget()
+{
+ return m_pImp;
+}
+FX_DWORD CFWL_Widget::Release()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ FX_DWORD dwRef = m_pImp->GetRefCount();
+ if (dwRef == 1) {
+ m_pImp->Finalize();
+ }
+ m_pImp->Release();
+ if (dwRef == 1) {
+ m_pImp = NULL;
+ delete this;
+ }
+ return dwRef - 1;
+}
+CFWL_Widget* CFWL_Widget::Retain()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, NULL);
+ m_pImp->Retain();
+ return this;
+}
+FX_DWORD CFWL_Widget::GetRefCount() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 1);
+ return m_pImp->GetRefCount();
+}
+FWL_ERR CFWL_Widget::GetClassName(CFX_WideString &wsClass) const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->GetClassName(wsClass);
+}
+FX_DWORD CFWL_Widget::GetClassID() const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return m_pImp->GetClassID();
+}
+FX_BOOL CFWL_Widget::IsInstance(FX_WSTR wsClass) const
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FALSE);
+ return m_pImp->IsInstance(wsClass);
+}
+static FX_LPVOID gs_pFWLWidget = (FX_LPVOID)FXBSTR_ID('l', 'i', 'g', 't');
+FWL_ERR CFWL_Widget::Initialize(const CFWL_WidgetProperties *pProperties )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->SetPrivateData(gs_pFWLWidget, this, NULL);
+}
+FWL_ERR CFWL_Widget::GetWidgetRect(CFX_RectF &rect, FX_BOOL bAutoSize )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->GetWidgetRect(rect, bAutoSize);
+}
+FWL_ERR CFWL_Widget::GetGlobalRect(CFX_RectF &rect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->GetGlobalRect(rect);
+}
+FWL_ERR CFWL_Widget::SetWidgetRect(const CFX_RectF &rect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->SetWidgetRect(rect);
+}
+FWL_ERR CFWL_Widget::GetClientRect(CFX_RectF &rect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->GetClientRect(rect);
+}
+CFWL_Widget* CFWL_Widget::GetParent()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, NULL);
+ IFWL_Widget *parent = m_pImp->GetParent();
+ if (parent) {
+ return (CFWL_Widget*)parent->GetPrivateData(gs_pFWLWidget);
+ }
+ return NULL;
+}
+FWL_ERR CFWL_Widget::SetParent(CFWL_Widget *pParent)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->SetParent(pParent ? pParent->GetWidget() : NULL);
+}
+CFWL_Widget* CFWL_Widget::GetOwner()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, NULL);
+ return NULL;
+}
+FWL_ERR CFWL_Widget::SetOwner(CFWL_Widget *pOwner)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return FWL_ERR_Succeeded;
+}
+FX_DWORD CFWL_Widget::GetStyles()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return m_pImp->GetStyles();
+}
+FWL_ERR CFWL_Widget::ModifyStyles(FX_DWORD dwStylesAdded, FX_DWORD dwStylesRemoved)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->ModifyStyles(dwStylesAdded, dwStylesRemoved);
+}
+FX_DWORD CFWL_Widget::GetStylesEx()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return m_pImp->GetStylesEx();
+}
+FWL_ERR CFWL_Widget::ModifyStylesEx(FX_DWORD dwStylesExAdded, FX_DWORD dwStylesExRemoved)
+{
+ return m_pImp->ModifyStylesEx(dwStylesExAdded, dwStylesExRemoved);
+}
+FX_DWORD CFWL_Widget::GetStates()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->GetStates();
+}
+FWL_ERR CFWL_Widget::SetStates(FX_DWORD dwStates, FX_BOOL bSet )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->SetStates(dwStates, bSet);
+}
+FWL_ERR CFWL_Widget::SetPrivateData(FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->SetPrivateData(module_id, pData, callback);
+}
+FX_LPVOID CFWL_Widget::GetPrivateData(FX_LPVOID module_id)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, NULL);
+ return m_pImp->GetPrivateData(module_id);
+}
+FWL_ERR CFWL_Widget::Update()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->Update();
+}
+FWL_ERR CFWL_Widget::LockUpdate()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->LockUpdate();
+}
+FWL_ERR CFWL_Widget::UnlockUpdate()
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->UnlockUpdate();
+}
+FX_DWORD CFWL_Widget::HitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, 0);
+ return m_pImp->HitTest(fx, fy);
+}
+FWL_ERR CFWL_Widget::TransformTo(CFWL_Widget *pWidget, FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->TransformTo(pWidget ? pWidget->GetWidget() : NULL, fx, fy);
+}
+FWL_ERR CFWL_Widget::TransformTo(CFWL_Widget *pWidget, CFX_RectF &rt)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->TransformTo(pWidget ? pWidget->GetWidget() : NULL, rt);
+}
+FWL_ERR CFWL_Widget::GetMatrix(CFX_Matrix &matrix, FX_BOOL bGlobal )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->GetMatrix(matrix, bGlobal);
+}
+FWL_ERR CFWL_Widget::SetMatrix(const CFX_Matrix &matrix)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->SetMatrix(matrix);
+}
+FWL_ERR CFWL_Widget::DrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ return m_pImp->DrawWidget(pGraphics, pMatrix);
+}
+FWL_ERR CFWL_Widget::GetProperties(CFWL_WidgetProperties &properties)
+{
+ properties.m_ctmOnParent = m_pProperties->m_ctmOnParent;
+ properties.m_rtWidget = m_pProperties->m_rtWidget;
+ properties.m_dwStyles = m_pProperties->m_dwStyles;
+ properties.m_dwStyleExes = m_pProperties->m_dwStyleExes;
+ properties.m_dwStates = m_pProperties->m_dwStates;
+ properties.m_pParent = m_pProperties->m_pParent;
+ properties.m_pOwner = m_pProperties->m_pOwner;
+ properties.m_wsWindowclass = m_pProperties->m_wsWindowclass;
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_Widget::SetProperties(const CFWL_WidgetProperties &properties)
+{
+ m_pProperties->m_ctmOnParent = properties.m_ctmOnParent;
+ m_pProperties->m_rtWidget = properties.m_rtWidget;
+ m_pProperties->m_dwStyles = properties.m_dwStyles;
+ m_pProperties->m_dwStyleExes = properties.m_dwStyleExes;
+ m_pProperties->m_dwStates = properties.m_dwStates;
+ m_pProperties->m_pParent = properties.m_pParent;
+ m_pProperties->m_pOwner = properties.m_pOwner;
+ m_pProperties->m_wsWindowclass = properties.m_wsWindowclass;
+ return FWL_ERR_Succeeded;
+}
+IFWL_WidgetDelegate* CFWL_Widget::SetDelegate(IFWL_WidgetDelegate* pDelegate)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, NULL);
+ m_pDelegate = m_pImp->SetDelegate(pDelegate);
+ return m_pDelegate;
+}
+CFWL_Widget::CFWL_Widget()
+ : m_pImp(NULL)
+ , m_pDelegate(NULL)
+ , m_pProperties(NULL)
+{
+ m_pProperties = FX_NEW CFWL_WidgetProperties;
+ m_pWidgetMgr = (CFWL_WidgetMgr*)FWL_GetWidgetMgr();
+ FXSYS_assert(m_pWidgetMgr != NULL);
+}
+CFWL_Widget::~CFWL_Widget()
+{
+ if (m_pProperties) {
+ delete m_pProperties;
+ m_pProperties = NULL;
+ }
+ if (m_pImp) {
+ m_pImp->Finalize();
+ m_pImp->Release();
+ m_pImp = NULL;
+ }
+}
+FWL_ERR CFWL_Widget::Repaint(const CFX_RectF *pRect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ CFX_RectF rect;
+ if (pRect) {
+ rect = *pRect;
+ } else {
+ m_pImp->GetWidgetRect(rect);
+ rect.left = rect.top = 0;
+ }
+ return m_pWidgetMgr->RepaintWidget(m_pImp, &rect);
+}
+FWL_ERR CFWL_Widget::SetFocus(FX_BOOL bFocus)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ IFWL_NoteThread *pThread = m_pImp->GetOwnerThread();
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ IFWL_NoteDriver *pDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ if (bFocus) {
+ pDriver->SetFocus(m_pImp);
+ } else {
+ if (((CFWL_NoteDriver*)pDriver)->GetFocus() == m_pImp) {
+ pDriver->SetFocus(NULL);
+ }
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_Widget::SetGrab(FX_BOOL bSet)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ IFWL_NoteThread *pThread = m_pImp->GetOwnerThread();
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ CFWL_NoteDriver *pDriver = (CFWL_NoteDriver*)pThread->GetNoteDriver();
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, FWL_ERR_Indefinite);
+ pDriver->SetGrab(m_pImp, bSet);
+ return FWL_ERR_Succeeded;
+}
+void CFWL_Widget::RegisterEventTarget(CFWL_Widget *pEventSource , FX_DWORD dwFilter )
+{
+ _FWL_RETURN_IF_FAIL(m_pImp);
+ IFWL_NoteThread *pThread = m_pImp->GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ IFWL_NoteDriver *pNoteDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pNoteDriver);
+ IFWL_Widget *pEventSourceImp = !pEventSource ? NULL : pEventSource->GetWidget();
+ pNoteDriver->RegisterEventTarget(GetWidget(), pEventSourceImp, dwFilter);
+}
+void CFWL_Widget::DispatchEvent(CFWL_Event *pEvent)
+{
+ _FWL_RETURN_IF_FAIL(m_pImp);
+ if (m_pImp->GetOuter()) {
+ return;
+ }
+ IFWL_NoteThread *pThread = m_pImp->GetOwnerThread();
+ _FWL_RETURN_IF_FAIL(pThread);
+ IFWL_NoteDriver *pNoteDriver = pThread->GetNoteDriver();
+ _FWL_RETURN_IF_FAIL(pNoteDriver);
+ pNoteDriver->SendNote(pEvent);
+}
+#define FWL_WGT_CalcHeight 2048
+#define FWL_WGT_CalcWidth 2048
+#define FWL_WGT_CalcMultiLineDefWidth 120.0f
+CFX_SizeF CFWL_Widget::CalcTextSize(const CFX_WideString &wsText, FX_BOOL bMultiLine , FX_INT32 iLineWidth )
+{
+ CFX_SizeF sz;
+ sz.Set(0, 0);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pImp, sz);
+ IFWL_ThemeProvider *pTheme = m_pImp->GetThemeProvider();
+ _FWL_RETURN_VALUE_IF_FAIL(pTheme, sz);
+ CFWL_ThemeText calPart;
+ calPart.m_pWidget = m_pImp;
+ calPart.m_wsText = wsText;
+ calPart.m_dwTTOStyles = bMultiLine ? FDE_TTOSTYLE_LineWrap : FDE_TTOSTYLE_SingleLine;
+ calPart.m_iTTOAlign = FDE_TTOALIGNMENT_TopLeft;
+ CFX_RectF rect;
+ FX_FLOAT fWidth = bMultiLine ?
+ (iLineWidth > 0 ? (FX_FLOAT)iLineWidth : FWL_WGT_CalcMultiLineDefWidth) :
+ FWL_WGT_CalcWidth;
+ rect.Set(0, 0, fWidth, FWL_WGT_CalcHeight);
+ pTheme->CalcTextRect(&calPart, rect);
+ sz.x = rect.width;
+ sz.y = rect.height;
+ return sz;
+}
+CFWL_WidgetDelegate::CFWL_WidgetDelegate()
+{
+}
+CFWL_WidgetDelegate::~CFWL_WidgetDelegate()
+{
+}
+FX_INT32 CFWL_WidgetDelegate::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return 1;
+}
+FWL_ERR CFWL_WidgetDelegate::OnProcessEvent(CFWL_Event *pEvent)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetDelegate::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fwl/src/theme/barcodetp.cpp b/xfa/src/fwl/src/theme/barcodetp.cpp
new file mode 100644
index 0000000000..86bbf92c4a
--- /dev/null
+++ b/xfa/src/fwl/src/theme/barcodetp.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_BarcodeTP::CFWL_BarcodeTP()
+{
+}
+CFWL_BarcodeTP::~CFWL_BarcodeTP()
+{
+}
+FX_BOOL CFWL_BarcodeTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_Barcode;
+}
+FX_BOOL CFWL_BarcodeTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch(pParams->m_iPart) {
+ case FWL_PART_BCD_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_BCD_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_BCD_Background: {
+ FillBackground(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fwl/src/theme/carettp.cpp b/xfa/src/fwl/src/theme/carettp.cpp
new file mode 100644
index 0000000000..b33a97da25
--- /dev/null
+++ b/xfa/src/fwl/src/theme/carettp.cpp
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_CaretTP::CFWL_CaretTP()
+{
+}
+CFWL_CaretTP::~CFWL_CaretTP()
+{
+}
+FX_BOOL CFWL_CaretTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_Caret;
+}
+FX_BOOL CFWL_CaretTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch(pParams->m_iPart) {
+ case FWL_PART_CAT_Background: {
+ if (!(pParams->m_dwStates & FWL_PARTSTATE_CAT_HightLight)) {
+ return TRUE;
+ }
+ DrawCaretBK(pParams->m_pGraphics, pParams->m_dwStates, &(pParams->m_rtPart), (CFX_Color *)pParams->m_pData, &(pParams->m_matrix));
+ break;
+ }
+ }
+ return TRUE;
+}
+void CFWL_CaretTP::DrawCaretBK(CFX_Graphics *pGraphics, FX_DWORD dwStates, const CFX_RectF *pRect, CFX_Color *crFill, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_Color crFilltemp;
+ crFill ? crFilltemp = *crFill : crFilltemp = ArgbEncode(255, 0, 0, 0);
+ CFX_RectF rect = *pRect;
+ path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
+ pGraphics->SetFillColor(&crFilltemp);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+}
diff --git a/xfa/src/fwl/src/theme/checkboxtp.cpp b/xfa/src/fwl/src/theme/checkboxtp.cpp
new file mode 100644
index 0000000000..32e74e4a44
--- /dev/null
+++ b/xfa/src/fwl/src/theme/checkboxtp.cpp
@@ -0,0 +1,500 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#define CHECKBOX_SIZE_SIGNMARGIN 3
+#define CHECKBOX_SIZE_SIGNBORDER 2
+#define CHECKBOX_SIZE_SIGNPATH 100
+#define CHECKBOX_COLOR_BOXLT1 (ArgbEncode(255, 172, 168, 153))
+#define CHECKBOX_COLOR_BOXLT2 (ArgbEncode(255, 113, 111, 100))
+#define CHECKBOX_COLOR_BOXRB1 (ArgbEncode(255, 241, 239, 226))
+#define CHECKBOX_COLOR_BOXRB2 (ArgbEncode(255, 255, 255, 255))
+#define CHECKBOX_FXGE_CoordinatesAdjust
+CFWL_CheckBoxTP::CFWL_CheckBoxTP()
+ : m_pCheckPath(NULL)
+{
+ m_pThemeData = FX_NEW CKBThemeData;
+ SetThemeData(0);
+}
+CFWL_CheckBoxTP::~CFWL_CheckBoxTP()
+{
+ if (m_pThemeData) {
+ delete m_pThemeData;
+ m_pThemeData = NULL;
+ }
+ if (m_pCheckPath) {
+ m_pCheckPath->Clear();
+ delete m_pCheckPath;
+ m_pCheckPath = NULL;
+ }
+}
+FX_BOOL CFWL_CheckBoxTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ FX_DWORD dwHash = pWidget->GetClassID();
+ return dwHash == FWL_CLASSHASH_CheckBox || dwHash == FWL_CLASSHASH_RadioButton;
+}
+FX_DWORD CFWL_CheckBoxTP::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ if (m_pThemeData) {
+ SetThemeData(FWL_GetThemeColor(dwThemeID));
+ }
+ return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
+}
+FX_BOOL CFWL_CheckBoxTP::DrawText(CFWL_ThemeText *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pTextOut, FALSE);
+ FX_BOOL bDisable = (pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Disabled;
+ FX_ARGB argText = bDisable ? FWLTHEME_CAPACITY_TextDisColor : FWLTHEME_CAPACITY_TextColor;
+ m_pTextOut->SetTextColor(argText);
+ return CFWL_WidgetTP::DrawText(pParams);
+}
+FX_BOOL CFWL_CheckBoxTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch(pParams->m_iPart) {
+ case FWL_PART_CKB_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_CKB_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_CKB_Background: {
+ FillBackground(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ if (pParams->m_dwStates & FWL_PARTSTATE_CKB_Focused) {
+ pParams->m_rtPart = *(CFX_RectF*)pParams->m_pData;
+ DrawFocus(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ }
+ break;
+ }
+ case FWL_PART_CKB_CheckBox: {
+ DrawBoxBk(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart, pParams->m_dwStates, &pParams->m_matrix);
+ if (((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Checked) |
+ ((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral)) {
+ DrawSign(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart, pParams->m_dwStates, &pParams->m_matrix);
+ }
+ FX_BOOL bDisable = (pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Disabled;
+ DrawSignBorder(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart, bDisable, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FWL_ERR CFWL_CheckBoxTP::Initialize()
+{
+ InitTTO();
+ return CFWL_WidgetTP::Initialize();
+}
+FWL_ERR CFWL_CheckBoxTP::Finalize()
+{
+ FinalizeTTO();
+ return CFWL_WidgetTP::Finalize();
+}
+void CFWL_CheckBoxTP::DrawBoxBk(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_DWORD dwStates, CFX_Matrix *pMatrix )
+{
+ dwStates &= 0x03;
+ FX_INT32 fillMode = FXFILL_WINDING;
+ FX_DWORD dwStyleEx = pWidget->GetStylesEx();
+ dwStyleEx &= FWL_STYLEEXT_CKB_ShapeMask;
+ CFX_Path path;
+ path.Create();
+ FX_FLOAT fRight = pRect->right();
+ FX_FLOAT fBottom = pRect->bottom();
+ FX_BOOL bClipSign = (dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Hovered;
+ if ((dwStyleEx == FWL_STYLEEXT_CKB_ShapeSolidSquare) || (dwStyleEx == FWL_STYLEEXT_CKB_ShapeSunkenSquare)) {
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
+ if (bClipSign) {
+ fillMode = FXFILL_ALTERNATE;
+ path.AddRectangle(pRect->left + CHECKBOX_SIZE_SIGNMARGIN,
+ pRect->top + CHECKBOX_SIZE_SIGNMARGIN,
+ pRect->width - CHECKBOX_SIZE_SIGNMARGIN * 2,
+ pRect->height - CHECKBOX_SIZE_SIGNMARGIN * 2);
+ }
+ } else {
+#ifdef CHECKBOX_FXGE_CoordinatesAdjust
+ CFX_RectF rect(*pRect);
+ rect.Deflate(0, 0, 1, 1);
+ path.AddEllipse(rect);
+#else
+ path.AddEllipse(*pRect);
+#endif
+ if (bClipSign) {
+ fillMode = FXFILL_ALTERNATE;
+#ifdef CHECKBOX_FXGE_CoordinatesAdjust
+ CFX_RectF rtClip(rect);
+#else
+ CFX_RectF rtClip(*pRect);
+#endif
+ rtClip.Deflate(CHECKBOX_SIZE_SIGNMARGIN - 1, CHECKBOX_SIZE_SIGNMARGIN - 1);
+ path.AddEllipse(rtClip);
+ }
+ }
+ FX_INT32 iTheme = 1;
+ if ((dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Hovered) {
+ iTheme = 2;
+ } else if ((dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Pressed) {
+ iTheme = 3;
+ } else if ((dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Disabled) {
+ iTheme = 4;
+ }
+ if ((dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Checked) {
+ iTheme += 4;
+ } else if ((dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral) {
+ iTheme += 8;
+ }
+ DrawAxialShading(pGraphics, pRect->left - 1, pRect->top - 1, fRight,
+ fBottom, m_pThemeData->clrBoxBk[iTheme][0],
+ m_pThemeData->clrBoxBk[iTheme][1], &path, fillMode, pMatrix);
+}
+void CFWL_CheckBoxTP::DrawSign(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRtBox, FX_DWORD dwStates, CFX_Matrix *pMatrix )
+{
+ CFX_RectF rtSign(*pRtBox);
+ rtSign.Deflate(CHECKBOX_SIZE_SIGNMARGIN, CHECKBOX_SIZE_SIGNMARGIN);
+ FX_DWORD dwColor = m_pThemeData->clrSignCheck;
+ FX_BOOL bCheck = TRUE;
+ if (((dwStates & FWL_PARTSTATE_CKB_Mask1) == FWL_PARTSTATE_CKB_Disabled) &&
+ ((dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Checked)) {
+ dwColor = m_pThemeData->clrSignBorderDisable;
+ } else if ((dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral) {
+ switch (dwStates & FWL_PARTSTATE_CKB_Mask1) {
+ case FWL_PARTSTATE_CKB_Normal: {
+ bCheck = FALSE;
+ dwColor = m_pThemeData->clrSignNeutralNormal;
+ break;
+ }
+ case FWL_PARTSTATE_CKB_Hovered: {
+ bCheck = FALSE;
+ dwColor = m_pThemeData->clrSignNeutralHover;
+ break;
+ }
+ case FWL_PARTSTATE_CKB_Pressed: {
+ bCheck = FALSE, dwColor = m_pThemeData->clrSignNeutralPressed;
+ break;
+ }
+ case FWL_PARTSTATE_CKB_Disabled: {
+ bCheck = FALSE, dwColor = m_pThemeData->clrSignBorderDisable;
+ break;
+ }
+ }
+ }
+ if (bCheck) {
+ FX_DWORD dwStyle = pWidget->GetStylesEx();
+ switch(dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) {
+ case FWL_STYLEEXT_CKB_SignShapeCheck: {
+ DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_SignShapeCircle: {
+ rtSign.Deflate(1, 1);
+ DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_SignShapeCross: {
+ DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_SignShapeDiamond: {
+ DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_SignShapeSquare: {
+ DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_SignShapeStar: {
+ DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ }
+ }
+ } else {
+ FillSoildRect(pGraphics, ArgbEncode(255, 33, 161, 33), &rtSign, pMatrix);
+ }
+}
+void CFWL_CheckBoxTP::DrawSignNeutral(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, CFX_Matrix *pMatrix )
+{
+ ((CFX_RectF*)pRtSign)->Inflate(-3, -3);
+ FillSoildRect(pGraphics, m_pThemeData->clrSignNeutral, pRtSign, pMatrix);
+}
+void CFWL_CheckBoxTP::DrawSignCheck(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix )
+{
+ if (!m_pCheckPath) {
+ initCheckPath(pRtSign->width);
+ }
+ CFX_Matrix mt;
+ mt.Reset();
+ mt.Translate(pRtSign->left, pRtSign->top);
+ mt.Concat(*pMatrix);
+ CFX_Color crFill(argbFill);
+ pGraphics->SaveGraphState();
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(m_pCheckPath, FXFILL_WINDING, &mt);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_CheckBoxTP::DrawSignCircle(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix )
+{
+ CFX_Path path;
+ path.Create();
+ path.AddEllipse(*pRtSign);
+ CFX_Color crFill(argbFill);
+ pGraphics->SaveGraphState();
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_CheckBoxTP::DrawSignCross(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix )
+{
+ CFX_Path path;
+ path.Create();
+ FX_FLOAT fRight = pRtSign->right();
+ FX_FLOAT fBottom = pRtSign->bottom();
+ path.AddLine(pRtSign->left, pRtSign->top, fRight, fBottom);
+ path.AddLine(pRtSign->left, fBottom, fRight, pRtSign->top);
+ CFX_Color crFill(argbFill);
+ pGraphics->SaveGraphState();
+ pGraphics->SetStrokeColor(&crFill);
+ pGraphics->SetLineWidth(1.0f);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_CheckBoxTP::DrawSignDiamond(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix )
+{
+ CFX_Path path;
+ path.Create();
+ FX_FLOAT fWidth = pRtSign->width;
+ FX_FLOAT fHeight = pRtSign->height;
+ FX_FLOAT fBottom = pRtSign->bottom();
+ path.MoveTo(pRtSign->left + fWidth / 2, pRtSign->top);
+ path.LineTo(pRtSign->left, pRtSign->top + fHeight / 2);
+ path.LineTo(pRtSign->left + fWidth / 2, fBottom);
+ path.LineTo(pRtSign->right(), pRtSign->top + fHeight / 2);
+ path.LineTo(pRtSign->left + fWidth / 2, pRtSign->top);
+ CFX_Color crFill(argbFill);
+ pGraphics->SaveGraphState();
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_CheckBoxTP::DrawSignSquare(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix )
+{
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRtSign->left, pRtSign->top, pRtSign->width, pRtSign->height);
+ CFX_Color crFill(argbFill);
+ pGraphics->SaveGraphState();
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_CheckBoxTP::DrawSignStar(CFX_Graphics *pGraphics, const CFX_RectF *pRtSign, FX_ARGB argbFill, CFX_Matrix *pMatrix )
+{
+ CFX_Path path;
+ path.Create();
+ FX_FLOAT fBottom = pRtSign->bottom();
+ FX_FLOAT fRadius = (pRtSign->top - fBottom) / ( 1 + (FX_FLOAT)cos(FX_PI / 5.0f));
+ CFX_PointF ptCenter;
+ ptCenter.Set((pRtSign->left + pRtSign->right()) / 2.0f, (pRtSign->top + fBottom) / 2.0f);
+ FX_FLOAT px[5], py[5];
+ FX_FLOAT fAngel = FX_PI / 10.0f;
+ for (FX_INT32 i = 0; i < 5; i++) {
+ px[i] = ptCenter.x + fRadius * (FX_FLOAT)cos(fAngel);
+ py[i] = ptCenter.y + fRadius * (FX_FLOAT)sin(fAngel);
+ fAngel += FX_PI * 2 / 5.0f;
+ }
+ path.MoveTo(px[0], py[0]);
+ FX_INT32 nNext = 0;
+ for (FX_INT32 j = 0; j < 5; j++) {
+ nNext += 2;
+ if (nNext >= 5) {
+ nNext -= 5;
+ }
+ path.LineTo(px[nNext], py[nNext]);
+ }
+ CFX_Color crFill(argbFill);
+ pGraphics->SaveGraphState();
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_CheckBoxTP::DrawSignBorder(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRtBox, FX_BOOL bDisable , CFX_Matrix *pMatrix )
+{
+ switch(pWidget->GetStylesEx() & FWL_STYLEEXT_CKB_ShapeMask) {
+ case FWL_STYLEEXT_CKB_ShapeSolidSquare: {
+ DrawAnnulusRect(pGraphics,
+ bDisable ? m_pThemeData->clrSignBorderDisable : m_pThemeData->clrSignBorderNormal,
+ pRtBox,
+ 1,
+ pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_ShapeSunkenSquare: {
+ Draw3DRect(pGraphics,
+ FWLTHEME_EDGE_Sunken,
+ CHECKBOX_SIZE_SIGNBORDER,
+ pRtBox,
+ CHECKBOX_COLOR_BOXLT1,
+ CHECKBOX_COLOR_BOXLT2,
+ CHECKBOX_COLOR_BOXRB1,
+ CHECKBOX_COLOR_BOXRB2,
+ pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_ShapeSolidCircle: {
+ DrawAnnulusCircle(pGraphics,
+ bDisable ? m_pThemeData->clrSignBorderDisable : m_pThemeData->clrSignBorderNormal,
+ pRtBox,
+ 1,
+ pMatrix);
+ break;
+ }
+ case FWL_STYLEEXT_CKB_ShapeSunkenCircle: {
+ Draw3DCircle(pGraphics,
+ FWLTHEME_EDGE_Sunken,
+ CHECKBOX_SIZE_SIGNBORDER,
+ pRtBox,
+ CHECKBOX_COLOR_BOXLT1,
+ CHECKBOX_COLOR_BOXLT2,
+ CHECKBOX_COLOR_BOXRB1,
+ CHECKBOX_COLOR_BOXRB2,
+ pMatrix);
+ break;
+ }
+ }
+}
+void CFWL_CheckBoxTP::SetThemeData(FX_DWORD dwID)
+{
+ FX_DWORD *pData = (FX_DWORD*)&m_pThemeData->clrBoxBk;
+ if (dwID) {
+ *pData++ = 0, *pData++ = 0, \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrSignBorderNormal = ArgbEncode(255, 154, 167, 114);
+ m_pThemeData->clrSignBorderDisable = ArgbEncode(255, 202, 200, 187);
+ m_pThemeData->clrSignCheck = ArgbEncode(255, 164, 180, 138);
+ m_pThemeData->clrSignNeutral = ArgbEncode(2255, 28, 134, 26);
+ m_pThemeData->clrSignNeutralNormal = ArgbEncode(255, 114, 192, 113);
+ m_pThemeData->clrSignNeutralHover = ArgbEncode(255, 33, 161, 33);
+ m_pThemeData->clrSignNeutralPressed = ArgbEncode(255, 28, 134, 26);
+ } else {
+ *pData++ = 0, *pData++ = 0, \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrSignBorderNormal = ArgbEncode(255, 28, 81, 128);
+ m_pThemeData->clrSignBorderDisable = ArgbEncode(255, 202, 200, 187);
+ m_pThemeData->clrSignCheck = ArgbEncode(255, 28, 81, 128);
+ m_pThemeData->clrSignNeutral = ArgbEncode(255, 28, 134, 26);
+ m_pThemeData->clrSignNeutralNormal = ArgbEncode(255, 114, 192, 113);
+ m_pThemeData->clrSignNeutralHover = ArgbEncode(255, 33, 161, 33);
+ m_pThemeData->clrSignNeutralPressed = ArgbEncode(255, 28, 134, 26);
+ }
+}
+void CFWL_CheckBoxTP::initCheckPath(FX_FLOAT fCheckLen)
+{
+ if (!m_pCheckPath) {
+ m_pCheckPath = FX_NEW CFX_Path;
+ m_pCheckPath->Create();
+ FX_FLOAT fWidth = CHECKBOX_SIZE_SIGNPATH;
+ FX_FLOAT fHeight = -CHECKBOX_SIZE_SIGNPATH;
+ FX_FLOAT fBottom = CHECKBOX_SIZE_SIGNPATH;
+ FX_FLOAT px1, py1, px2, py2;
+ CFX_PointF pt1;
+ pt1.Set(fWidth / 15.0f, fBottom + fHeight * 2 / 5.0f);
+ CFX_PointF pt2;
+ pt2.Set(fWidth / 4.5f, fBottom + fHeight / 16.0f);
+ CFX_PointF pt3;
+ pt3.Set(fWidth / 3.0f, fBottom);
+ CFX_PointF pt4;
+ pt4.Set(fWidth * 14 / 15.0f, fBottom + fHeight * 15 / 16.0f);
+ CFX_PointF pt5;
+ pt5.Set(fWidth / 3.6f, fBottom + fHeight / 3.5f);
+ CFX_PointF pt12;
+ pt12.Set(fWidth / 7.0f, fBottom + fHeight * 2 / 7.0f);
+ CFX_PointF pt21;
+ pt21.Set(fWidth / 5.0f, fBottom + fHeight / 5.0f);
+ CFX_PointF pt23;
+ pt23.Set(fWidth / 4.4f, fBottom + fHeight * 0 / 16.0f);
+ CFX_PointF pt32;
+ pt32.Set(fWidth / 4.0f, fBottom);
+ CFX_PointF pt34;
+ pt34.Set(fWidth * (1 / 7.0f + 7 / 15.0f), fBottom + fHeight * 4 / 5.0f);
+ CFX_PointF pt43;
+ pt43.Set(fWidth * (1 / 7.0f + 7 / 15.0f), fBottom + fHeight * 4 / 5.0f);
+ CFX_PointF pt45;
+ pt45.Set(fWidth * 7 / 15.0f, fBottom + fHeight * 8 / 7.0f);
+ CFX_PointF pt54;
+ pt54.Set(fWidth / 3.4f, fBottom + fHeight / 3.5f);
+ CFX_PointF pt51;
+ pt51.Set(fWidth / 3.6f, fBottom + fHeight / 4.0f);
+ CFX_PointF pt15;
+ pt15.Set(fWidth / 3.5f, fBottom + fHeight * 3.5f / 5.0f);
+ m_pCheckPath->MoveTo(pt1.x, pt1.y);
+ px1 = pt12.x - pt1.x;
+ py1 = pt12.y - pt1.y;
+ px2 = pt21.x - pt2.x;
+ py2 = pt21.y - pt2.y;
+ m_pCheckPath->BezierTo(pt1.x + px1 * FWLTHEME_BEZIER, pt1.y + py1 * FWLTHEME_BEZIER,
+ pt2.x + px2 * FWLTHEME_BEZIER, pt2.y + py2 * FWLTHEME_BEZIER,
+ pt2.x, pt2.y);
+ px1 = pt23.x - pt2.x;
+ py1 = pt23.y - pt2.y;
+ px2 = pt32.x - pt3.x;
+ py2 = pt32.y - pt3.y;
+ m_pCheckPath->BezierTo(pt2.x + px1 * FWLTHEME_BEZIER, pt2.y + py1 * FWLTHEME_BEZIER,
+ pt3.x + px2 * FWLTHEME_BEZIER, pt3.y + py2 * FWLTHEME_BEZIER,
+ pt3.x, pt3.y);
+ px1 = pt34.x - pt3.x;
+ py1 = pt34.y - pt3.y;
+ px2 = pt43.x - pt4.x;
+ py2 = pt43.y - pt4.y;
+ m_pCheckPath->BezierTo(pt3.x + px1 * FWLTHEME_BEZIER, pt3.y + py1 * FWLTHEME_BEZIER,
+ pt4.x + px2 * FWLTHEME_BEZIER, pt4.y + py2 * FWLTHEME_BEZIER,
+ pt4.x, pt4.y);
+ px1 = pt45.x - pt4.x;
+ py1 = pt45.y - pt4.y;
+ px2 = pt54.x - pt5.x;
+ py2 = pt54.y - pt5.y;
+ m_pCheckPath->BezierTo(pt4.x + px1 * FWLTHEME_BEZIER, pt4.y + py1 * FWLTHEME_BEZIER,
+ pt5.x + px2 * FWLTHEME_BEZIER, pt5.y + py2 * FWLTHEME_BEZIER,
+ pt5.x, pt5.y);
+ px1 = pt51.x - pt5.x;
+ py1 = pt51.y - pt5.y;
+ px2 = pt15.x - pt1.x;
+ py2 = pt15.y - pt1.y;
+ m_pCheckPath->BezierTo(pt5.x + px1 * FWLTHEME_BEZIER, pt5.y + py1 * FWLTHEME_BEZIER,
+ pt1.x + px2 * FWLTHEME_BEZIER, pt1.y + py2 * FWLTHEME_BEZIER,
+ pt1.x, pt1.y);
+ FX_FLOAT fScale = fCheckLen / CHECKBOX_SIZE_SIGNPATH;
+ CFX_AffineMatrix mt;
+ mt.Set(1, 0, 0, 1, 0, 0);
+ mt.Scale(fScale, fScale);
+ CFX_PathData *pData = m_pCheckPath->GetPathData();
+ pData->Transform(&mt);
+ }
+}
diff --git a/xfa/src/fwl/src/theme/comboboxtp.cpp b/xfa/src/fwl/src/theme/comboboxtp.cpp
new file mode 100644
index 0000000000..c7218955c9
--- /dev/null
+++ b/xfa/src/fwl/src/theme/comboboxtp.cpp
@@ -0,0 +1,147 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#define FWLTHEME_CAPACITY_ComboFormHandler 8.0f
+CFWL_ComboBoxTP::CFWL_ComboBoxTP()
+{
+ m_dwThemeID = 0;
+}
+CFWL_ComboBoxTP::~CFWL_ComboBoxTP()
+{
+}
+FX_BOOL CFWL_ComboBoxTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_ComboBox;
+}
+FX_BOOL CFWL_ComboBoxTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch(pParams->m_iPart) {
+ case FWL_PART_CMB_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_CMB_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_CMB_Background: {
+ CFX_Path path;
+ path.Create();
+ CFX_RectF & rect = pParams->m_rtPart;
+ path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
+ CFX_Color cr;
+ switch(pParams->m_dwStates) {
+ case FWL_PARTSTATE_CMB_Selected:
+ cr = FWLTHEME_COLOR_BKSelected;
+ break;
+ case FWL_PARTSTATE_CMB_Disabled:
+ cr = FWLTHEME_COLOR_EDGERB1;
+ break;
+ default:
+ cr = 0xFFFFFFFF;
+ }
+ pParams->m_pGraphics->SaveGraphState();
+ pParams->m_pGraphics->SetFillColor(&cr);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, &pParams->m_matrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ break;
+ }
+ case FWL_PART_CMB_DropDownButton: {
+ DrawDropDownButton(pParams, pParams->m_dwStates, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_CMB_StretcgHandler: {
+ DrawStrethHandler(pParams, 0, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+void CFWL_ComboBoxTP::DrawStrethHandler(CFWL_ThemeBackground *pParams, FX_DWORD dwStates, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pParams->m_rtPart.left,
+ pParams->m_rtPart.top,
+ pParams->m_rtPart.width - 1,
+ pParams->m_rtPart.height);
+ CFX_Color cr(ArgbEncode(0xff, 0xff, 0, 0));
+ pParams->m_pGraphics->SetFillColor(&cr);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, &pParams->m_matrix);
+}
+FX_LPVOID CFWL_ComboBoxTP::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ if (dwCapacity == FWL_WGTCAPACITY_CMB_ComboFormHandler) {
+ m_fValue = FWLTHEME_CAPACITY_ComboFormHandler;
+ return &m_fValue;
+ }
+ return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
+}
+#ifdef THEME_XPSimilar
+void CFWL_ComboBoxTP::DrawDropDownButton(CFWL_ThemeBackground *pParams, FX_DWORD dwStates, CFX_Matrix *pMatrix)
+{
+ FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
+ switch ( dwStates) {
+ case FWL_PARTSTATE_CMB_Normal: {
+ eState = FWLTHEME_STATE_Normal;
+ break;
+ }
+ case FWL_PARTSTATE_CMB_Hovered: {
+ eState = FWLTHEME_STATE_Hover;
+ break;
+ }
+ case FWL_PARTSTATE_CMB_Pressed: {
+ eState = FWLTHEME_STATE_Pressed;
+ break;
+ }
+ case FWL_PARTSTATE_CMB_Disabled: {
+ eState = FWLTHEME_STATE_Disabale;
+ break;
+ }
+ default: {
+ }
+ }
+ DrawArrowBtn(pParams->m_pGraphics, &pParams->m_rtPart, FWLTHEME_DIRECTION_Down, eState, &pParams->m_matrix);
+}
+#else
+void CFWL_ComboBoxTP::DrawDropDownButton(CFWL_ThemeBackground *pParams, FX_DWORD dwStates, CFX_Matrix *pMatrix)
+{
+ FX_BOOL bPressed = ((pParams->m_dwStates & FWL_CMBPARTSTATE_Pressed) == FWL_CMBPARTSTATE_Pressed);
+ FX_FLOAT fWidth = bPressed ? 1.0f : 2.0f;
+ FWLTHEME_EDGE eType = bPressed ? FWLTHEME_EDGE_Flat : FWLTHEME_EDGE_Raised;
+ Draw3DRect(pParams->m_pGraphics, eType, fWidth, &pParams->m_rtPart, FWLTHEME_COLOR_EDGELT1, FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1, FWLTHEME_COLOR_EDGERB2, pMatrix);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pParams->m_rtPart.left + fWidth, pParams->m_rtPart.top + fWidth, pParams->m_rtPart.width - 2 * fWidth, pParams->m_rtPart.height - 2 * fWidth);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color crFill(FWLTHEME_COLOR_Background);
+ pParams->m_pGraphics->SetFillColor(&crFill);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, &pParams->m_matrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ FX_ARGB argbFill = ArgbEncode(255, 77, 97, 133);
+ switch(pParams->m_dwStates & 0x03) {
+ case FWL_CMBPARTSTATE_Normal: {
+ }
+ case FWL_CMBPARTSTATE_Hovered: {
+ }
+ case FWL_CMBPARTSTATE_Pressed: {
+ argbFill = 0xFF000000;
+ break;
+ }
+ case FWL_CMBPARTSTATE_Disabled: {
+ argbFill = 0xFFF0F0F0;
+ break;
+ }
+ }
+ DrawArrow(pParams->m_pGraphics, &pParams->m_rtPart, FWLTHEME_DIRECTION_Down, argbFill, bPressed, &pParams->m_matrix);
+}
+#endif
diff --git a/xfa/src/fwl/src/theme/datetimepickertp.cpp b/xfa/src/fwl/src/theme/datetimepickertp.cpp
new file mode 100644
index 0000000000..bc94ee9db1
--- /dev/null
+++ b/xfa/src/fwl/src/theme/datetimepickertp.cpp
@@ -0,0 +1,120 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_DateTimePickerTP::CFWL_DateTimePickerTP()
+{
+ m_pThemeData = FX_NEW DTPThemeData;
+ initThemeData();
+}
+CFWL_DateTimePickerTP::~CFWL_DateTimePickerTP()
+{
+ delete m_pThemeData;
+}
+FX_BOOL CFWL_DateTimePickerTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_DateTimePicker;
+}
+FX_BOOL CFWL_DateTimePickerTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch(pParams->m_iPart) {
+ case FWL_PART_DTP_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_DTP_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_DTP_DropDownButton: {
+ DrawDropDownButton(pParams, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
+#ifdef THEME_XPSimilar
+void CFWL_DateTimePickerTP::DrawDropDownButton(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ FX_DWORD dwStates = pParams->m_dwStates;
+ dwStates &= 0x03;
+ FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
+ switch (eState & dwStates) {
+ case FWL_PARTSTATE_DTP_Normal: {
+ eState = FWLTHEME_STATE_Normal;
+ break;
+ }
+ case FWL_PARTSTATE_DTP_Hovered: {
+ eState = FWLTHEME_STATE_Hover;
+ break;
+ }
+ case FWL_PARTSTATE_DTP_Pressed: {
+ eState = FWLTHEME_STATE_Pressed;
+ break;
+ }
+ case FWL_PARTSTATE_DTP_Disabled: {
+ eState = FWLTHEME_STATE_Disabale;
+ break;
+ }
+ default: {
+ }
+ }
+ DrawArrowBtn(pParams->m_pGraphics, &pParams->m_rtPart, FWLTHEME_DIRECTION_Down, eState, pMatrix);
+}
+#else
+void CFWL_DateTimePickerTP::DrawDropDownButton(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ FX_BOOL bPressed = ((pParams->m_dwStates & FWL_PARTSTATE_DTP_Pressed) == FWL_PARTSTATE_DTP_Pressed);
+ FX_FLOAT fWidth = bPressed ? 1.0f : 2.0f;
+ FWLTHEME_EDGE eType = bPressed ? FWLTHEME_EDGE_Flat : FWLTHEME_EDGE_Raised;
+ Draw3DRect(pParams->m_pGraphics, eType, fWidth, &pParams->m_rtPart, FWLTHEME_COLOR_EDGELT1, FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1, FWLTHEME_COLOR_EDGERB2, pMatrix);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pParams->m_rtPart.left + fWidth, pParams->m_rtPart.top + fWidth, pParams->m_rtPart.width - 2 * fWidth, pParams->m_rtPart.height - 2 * fWidth);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color crFill(FWLTHEME_COLOR_Background);
+ pParams->m_pGraphics->SetFillColor(&crFill);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ FX_ARGB argbFill = ArgbEncode(255, 77, 97, 133);
+ switch(pParams->m_dwStates & 0x03) {
+ case FWL_PARTSTATE_DTP_Normal: {
+ }
+ case FWL_PARTSTATE_DTP_Hovered: {
+ }
+ case FWL_PARTSTATE_DTP_Pressed: {
+ argbFill = 0xFF000000;
+ break;
+ }
+ case FWL_PARTSTATE_DTP_Disabled: {
+ argbFill = 0xFFF0F0F0;
+ break;
+ }
+ }
+ DrawArrow(pParams->m_pGraphics, &pParams->m_rtPart, FWLTHEME_DIRECTION_Down, argbFill, bPressed, pMatrix);
+}
+#endif
+void CFWL_DateTimePickerTP::initThemeData()
+{
+ FX_DWORD *pData = (FX_DWORD*)&m_pThemeData->BoxBkColor;
+ *pData++ = 0, *pData++ = 0, \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 220, 220, 215), *pData++ = ArgbEncode(255, 255, 255, 255), \
+ *pData++ = ArgbEncode(255, 255, 240, 207), *pData++ = ArgbEncode(255, 248, 179, 48), \
+ *pData++ = ArgbEncode(255, 176, 176, 167), *pData++ = ArgbEncode(255, 241, 239, 239), \
+ *pData++ = ArgbEncode(255, 255, 255, 255), *pData++ = ArgbEncode(255, 255, 255, 255);
+}
diff --git a/xfa/src/fwl/src/theme/edittp.cpp b/xfa/src/fwl/src/theme/edittp.cpp
new file mode 100644
index 0000000000..57a96bcb50
--- /dev/null
+++ b/xfa/src/fwl/src/theme/edittp.cpp
@@ -0,0 +1,84 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_EditTP::CFWL_EditTP()
+{
+}
+CFWL_EditTP::~CFWL_EditTP()
+{
+}
+FX_BOOL CFWL_EditTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_Edit;
+}
+FX_BOOL CFWL_EditTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ switch(pParams->m_iPart) {
+ case FWL_PART_EDT_Border: {
+ DrawBorder(pParams->m_pGraphics, & pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_EDT_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_EDT_Background: {
+ if (pParams->m_pPath) {
+ CFX_Graphics *pGraphics = pParams->m_pGraphics;
+ pGraphics->SaveGraphState();
+ CFX_Color crSelected(FWL_GetThemeColor(m_dwThemeID) == 0 ? FWLTHEME_COLOR_BKSelected : FWLTHEME_COLOR_Green_BKSelected);
+ pGraphics->SetFillColor(&crSelected);
+ pGraphics->FillPath(pParams->m_pPath, FXFILL_WINDING, &pParams->m_matrix);
+ pGraphics->RestoreGraphState();
+ } else {
+ FX_BOOL bStatic = pParams->m_dwData == FWL_PARTDATA_EDT_StaticBackground;
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pParams->m_rtPart.left, pParams->m_rtPart.top, pParams->m_rtPart.width, pParams->m_rtPart.height);
+ CFX_Color cr(FWLTHEME_COLOR_Background);
+ if (!bStatic) {
+ if ((pParams->m_dwStates & FWL_PARTSTATE_EDT_Disable) == FWL_PARTSTATE_EDT_Disable) {
+ cr.Set(FWLTHEME_COLOR_EDGERB1);
+ } else if((pParams->m_dwStates & FWL_PARTSTATE_EDT_ReadOnly) == FWL_PARTSTATE_EDT_ReadOnly) {
+ cr.Set(ArgbEncode(255, 236, 233, 216));
+ } else {
+ cr.Set(0xFFFFFFFF);
+ }
+ }
+ pParams->m_pGraphics->SaveGraphState();
+ pParams->m_pGraphics->SetFillColor(&cr);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, &pParams->m_matrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ }
+ break;
+ }
+ case FWL_PART_EDT_CombTextLine: {
+ FX_ARGB cr = 0xFF000000;
+ FX_FLOAT fWidth = 1.0f;
+ CFX_Color crLine(cr);
+ pParams->m_pGraphics->SetStrokeColor(&crLine);
+ pParams->m_pGraphics->SetLineWidth(fWidth);
+ pParams->m_pGraphics->StrokePath(pParams->m_pPath, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ return TRUE;
+}
+FWL_ERR CFWL_EditTP::Initialize()
+{
+ InitTTO();
+ return CFWL_WidgetTP::Initialize();
+}
+FWL_ERR CFWL_EditTP::Finalize()
+{
+ FinalizeTTO();
+ return CFWL_WidgetTP::Finalize();
+}
diff --git a/xfa/src/fwl/src/theme/formtp.cpp b/xfa/src/fwl/src/theme/formtp.cpp
new file mode 100644
index 0000000000..5a6633d3ea
--- /dev/null
+++ b/xfa/src/fwl/src/theme/formtp.cpp
@@ -0,0 +1,796 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#define FWLTHEME_CAPACITY_CXFormBorder 3
+#define FWLTHEME_CAPACITY_CYFormBorder 3
+#define FWLTHEME_CAPACITY_CYNarrowCaption 18
+#define FWLTHEME_CAPACITY_CYCaption 29
+#define FWLTHEME_CAPACITY_BigIconSize 32
+#define FWLTHEME_CAPACITY_SmallIconSize 16
+#define FWLTHEME_CAPACITY_FormTextColor 0xFFFFFFFF
+#define FWLTHEME_FORMBTN_Margin 5
+#define FWLTHEME_FORMBTN_Span 2
+#define FWLTHEME_FORMBTN_Size 21
+CFWL_FormTP::CFWL_FormTP()
+ : m_pActiveBitmap(NULL)
+ , m_pDeactivebitmap(NULL)
+{
+ m_pThemeData = FX_NEW SBThemeData;
+ SetThemeData(0);
+ m_rtDisLBorder.Reset();
+ m_rtDisRBorder.Reset();
+ m_rtDisBBorder.Reset();
+ m_rtDisCaption.Reset();
+}
+CFWL_FormTP::~CFWL_FormTP()
+{
+ if (m_pThemeData) {
+ delete m_pThemeData;
+ m_pThemeData = NULL;
+ }
+}
+FWL_ERR CFWL_FormTP::Initialize()
+{
+ InitTTO();
+ InitCaption(TRUE);
+ InitCaption(FALSE);
+ return CFWL_WidgetTP::Initialize();
+}
+FWL_ERR CFWL_FormTP::Finalize()
+{
+ FinalizeTTO();
+ if (m_pActiveBitmap) {
+ delete m_pActiveBitmap;
+ m_pActiveBitmap = NULL;
+ }
+ if (m_pDeactivebitmap) {
+ delete m_pDeactivebitmap;
+ m_pDeactivebitmap = NULL;
+ }
+ return CFWL_WidgetTP::Finalize();
+}
+FX_BOOL CFWL_FormTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ FX_DWORD dwHash = pWidget->GetClassID();
+ return dwHash == FWL_CLASSHASH_Form;
+}
+FX_DWORD CFWL_FormTP::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ if (m_pThemeData) {
+ SetThemeData(FWL_GetThemeColor(dwThemeID));
+ }
+ InitCaption(TRUE);
+ InitCaption(FALSE);
+ return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
+}
+FX_BOOL CFWL_FormTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ FX_INT32 iActive = 0;
+ if (pParams->m_dwStates & FWL_PARTSTATE_FRM_Inactive) {
+ iActive = 1;
+ }
+ FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
+ switch (pParams->m_dwStates & 0x03) {
+ case FWL_PARTSTATE_FRM_Hover: {
+ eState = FWLTHEME_STATE_Hover;
+ break;
+ }
+ case FWL_PARTSTATE_FRM_Pressed: {
+ eState = FWLTHEME_STATE_Pressed;
+ break;
+ }
+ case FWL_PARTSTATE_FRM_Disabled: {
+ eState = FWLTHEME_STATE_Disabale;
+ break;
+ }
+ default: {
+ }
+ }
+ switch(pParams->m_iPart) {
+ case FWL_PART_FRM_Border: {
+ DrawFormBorder(pParams->m_pGraphics, &pParams->m_rtPart, eState, &pParams->m_matrix, iActive);
+ break;
+ }
+ case FWL_PART_FRM_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_FRM_Background: {
+ FillBackground(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_FRM_Caption: {
+ DrawCaption(pParams->m_pGraphics, &pParams->m_rtPart, eState, &pParams->m_matrix, iActive);
+ break;
+ }
+ case FWL_PART_FRM_NarrowCaption: {
+ DrawNarrowCaption(pParams->m_pGraphics, &pParams->m_rtPart, eState, &pParams->m_matrix, iActive);
+ break;
+ }
+ case FWL_PART_FRM_CloseBox: {
+ DrawCloseBox(pParams->m_pGraphics, &pParams->m_rtPart, eState, &pParams->m_matrix, iActive);
+ break;
+ }
+ case FWL_PART_FRM_MinimizeBox: {
+ DrawMinimizeBox(pParams->m_pGraphics, &pParams->m_rtPart, eState, &pParams->m_matrix, iActive);
+ break;
+ }
+ case FWL_PART_FRM_MaximizeBox: {
+ DrawMaximizeBox(pParams->m_pGraphics, &pParams->m_rtPart, eState, pParams->m_dwData, &pParams->m_matrix, iActive);
+ break;
+ }
+ case FWL_PART_FRM_Icon: {
+ DrawIconImage(pParams->m_pGraphics, pParams->m_pImage, &pParams->m_rtPart, eState, &pParams->m_matrix, iActive);
+ break;
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_FormTP::DrawText(CFWL_ThemeText *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pTextOut, FALSE);
+ if (pParams->m_iPart == FWL_PART_FRM_Caption) {
+ m_pTextOut->SetTextColor(0xFFFFFFFF);
+ } else {
+ m_pTextOut->SetTextColor(0xFF000000);
+ }
+ return CFWL_WidgetTP::DrawText(pParams);
+}
+FX_LPVOID CFWL_FormTP::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ FX_BOOL bDefPro = FALSE;
+ FX_BOOL bDwordVal = FALSE;
+ switch(dwCapacity) {
+ case FWL_WGTCAPACITY_CXBorder: {
+ m_fValue = FWLTHEME_CAPACITY_CXFormBorder;
+ break;
+ }
+ case FWL_WGTCAPACITY_CYBorder: {
+ m_fValue = FWLTHEME_CAPACITY_CYFormBorder;
+ break;
+ }
+ case FWL_WGTCAPACITY_FRM_CYCaption: {
+ m_fValue = FWLTHEME_CAPACITY_CYCaption;
+ break;
+ }
+ case FWL_WGTCAPACITY_FRM_CYNarrowCaption: {
+ m_fValue = FWLTHEME_CAPACITY_CYCaption;
+ break;
+ }
+ case FWL_WGTCAPACITY_TextColor: {
+ bDwordVal = TRUE;
+ m_dwValue = FWLTHEME_CAPACITY_FormTextColor;
+ break;
+ }
+ case FWL_WGTCAPACITY_FRM_BigIcon: {
+ m_fValue = FWLTHEME_CAPACITY_BigIconSize;
+ break;
+ }
+ case FWL_WGTCAPACITY_FRM_SmallIcon: {
+ m_fValue = FWLTHEME_CAPACITY_SmallIconSize;
+ break;
+ }
+ default: {
+ bDefPro = TRUE;
+ }
+ }
+ if (!bDefPro) {
+ if (bDwordVal) {
+ return &m_dwValue;
+ }
+ return &m_fValue;
+ }
+ return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
+}
+FWL_ERR CFWL_FormTP::GetPartRect(CFWL_ThemePart *pThemePart, CFX_RectF& rtPart)
+{
+ switch(pThemePart->m_iPart) {
+ case FWL_PART_FRM_CloseBox: {
+ CalCloseBox(pThemePart->m_pWidget, rtPart);
+ break;
+ }
+ case FWL_PART_FRM_MaximizeBox: {
+ CalMaxBox(pThemePart->m_pWidget, rtPart);
+ break;
+ }
+ case FWL_PART_FRM_MinimizeBox: {
+ CalMinBox(pThemePart->m_pWidget, rtPart);
+ break;
+ }
+ case FWL_PART_FRM_HeadText: {
+ CalCaption(pThemePart->m_pWidget, rtPart);
+ break;
+ }
+ case FWL_PART_FRM_Icon: {
+ CalIcon(pThemePart->m_pWidget, rtPart);
+ break;
+ }
+ default: {
+ }
+ }
+ return FWL_ERR_Succeeded;
+}
+void CFWL_FormTP::CalCloseBox(IFWL_Widget *pWidget, CFX_RectF &rect)
+{
+ FX_DWORD dwStyles = pWidget->GetStyles();
+ CFX_RectF rtWidget;
+ pWidget->GetWidgetRect(rtWidget);
+ rtWidget.Offset(-rtWidget.left, -rtWidget.top);
+ if (dwStyles & FWL_WGTSTYLE_CloseBox) {
+ rect.Set(rtWidget.left + FWLTHEME_FORMBTN_Margin + FWLTHEME_FORMBTN_Span,
+ rtWidget.top + FWLTHEME_FORMBTN_Margin,
+ FWLTHEME_FORMBTN_Size,
+ FWLTHEME_FORMBTN_Size);
+ } else {
+ rect.Set(rtWidget.left + FWLTHEME_FORMBTN_Margin + FWLTHEME_FORMBTN_Span,
+ rtWidget.top + FWLTHEME_FORMBTN_Margin,
+ 0,
+ 0);
+ }
+}
+void CFWL_FormTP::CalMaxBox(IFWL_Widget *pWidget, CFX_RectF &rect)
+{
+ FX_DWORD dwStyles = pWidget->GetStyles();
+ CFX_RectF rtWidget;
+ pWidget->GetWidgetRect(rtWidget);
+ rtWidget.Offset(-rtWidget.left, -rtWidget.top);
+ if (dwStyles & FWL_WGTSTYLE_MaximizeBox) {
+ rect.Set(rtWidget.left + FWLTHEME_FORMBTN_Margin + FWLTHEME_FORMBTN_Size + FWLTHEME_FORMBTN_Span * 2,
+ rtWidget.top + FWLTHEME_FORMBTN_Margin,
+ FWLTHEME_FORMBTN_Size,
+ FWLTHEME_FORMBTN_Size);
+ } else {
+ rect.Set(rtWidget.left + FWLTHEME_FORMBTN_Margin + FWLTHEME_FORMBTN_Size + FWLTHEME_FORMBTN_Span * 2,
+ rtWidget.top + FWLTHEME_FORMBTN_Margin,
+ 0,
+ 0);
+ }
+}
+void CFWL_FormTP::CalMinBox(IFWL_Widget *pWidget, CFX_RectF &rect)
+{
+ FX_DWORD dwStyles = pWidget->GetStyles();
+ CFX_RectF rtWidget;
+ pWidget->GetWidgetRect(rtWidget);
+ rtWidget.Offset(-rtWidget.left, -rtWidget.top);
+ if (dwStyles & FWL_WGTSTYLE_MinimizeBox) {
+ rect.Set(rtWidget.left + FWLTHEME_FORMBTN_Margin + FWLTHEME_FORMBTN_Size * 2 + FWLTHEME_FORMBTN_Span * 3,
+ rtWidget.top + FWLTHEME_FORMBTN_Margin,
+ FWLTHEME_FORMBTN_Size,
+ FWLTHEME_FORMBTN_Size);
+ } else {
+ rect.Set(rtWidget.left + FWLTHEME_FORMBTN_Margin + FWLTHEME_FORMBTN_Size * 2 + FWLTHEME_FORMBTN_Span * 3,
+ rtWidget.top + FWLTHEME_FORMBTN_Margin,
+ 0,
+ 0);
+ }
+}
+void CFWL_FormTP::CalCaption(IFWL_Widget *pWidget, CFX_RectF &rect)
+{
+ CFX_RectF rtWidget;
+ pWidget->GetWidgetRect(rtWidget);
+ rtWidget.Offset(-rtWidget.left, -rtWidget.top);
+ rect.Set(rtWidget.left + FWLTHEME_FORMBTN_Margin,
+ rtWidget.top + FWLTHEME_FORMBTN_Margin - 2,
+ rtWidget.width - FWLTHEME_FORMBTN_Margin * 2,
+ FWLTHEME_FORMBTN_Size + 2 * FWLTHEME_FORMBTN_Margin + 4);
+}
+void CFWL_FormTP::CalIcon(IFWL_Widget *pWidget, CFX_RectF &rect)
+{
+}
+void CFWL_FormTP::DrawFormBorder(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+ CFX_RectF rt;
+ rt.Set(pRect->left, pRect->top, 1, pRect->height);
+ FX_FLOAT fBottom, fRight;
+ fBottom = pRect->bottom();
+ fRight = pRect->right();
+ CFX_Path path;
+ path.Create();
+ CFX_Color clrLine;
+ path.Clear();
+ path.MoveTo(pRect->left, pRect->top);
+ path.LineTo(pRect->left, fBottom - 1);
+ path.LineTo(fRight - 1, fBottom - 1);
+ path.LineTo(fRight - 1, pRect->top);
+ clrLine = m_pThemeData->clrFormBorder[iActive][2];
+ pGraphics->SetStrokeColor(&clrLine);
+ pGraphics->StrokePath(&path, pMatrix);
+ path.Clear();
+ path.MoveTo(pRect->left + 1, pRect->top);
+ path.LineTo(pRect->left + 1, fBottom - 2);
+ path.LineTo(fRight - 2, fBottom - 2);
+ path.LineTo(fRight - 2, pRect->top);
+ clrLine = m_pThemeData->clrFormBorder[iActive][1];
+ pGraphics->SetStrokeColor(&clrLine);
+ pGraphics->StrokePath(&path, pMatrix);
+ path.Clear();
+ path.MoveTo(pRect->left + 2, pRect->top);
+ path.LineTo(pRect->left + 2, fBottom - 3);
+ path.LineTo(fRight - 3, fBottom - 3);
+ path.LineTo(fRight - 3, pRect->top);
+ clrLine = m_pThemeData->clrFormBorder[iActive][0];
+ pGraphics->SetStrokeColor(&clrLine);
+ pGraphics->StrokePath(&path, pMatrix);
+ path.Clear();
+ path.MoveTo(pRect->left + 3, pRect->top);
+ path.LineTo(pRect->left + 3, fBottom - 4);
+ path.LineTo(fRight - 4, fBottom - 4);
+ path.LineTo(fRight - 4, pRect->top);
+ clrLine = m_pThemeData->clrFormBorder[iActive][4];
+ pGraphics->SetStrokeColor(&clrLine);
+ pGraphics->StrokePath(&path, pMatrix);
+ m_rtDisLBorder.Set(pRect->left, pRect->top + 29, 4, pRect->height - 29);
+ m_rtDisRBorder.Set(pRect->right() - 4, pRect->top + 29, 4, pRect->height - 29);
+ m_rtDisBBorder.Set(pRect->left, pRect->bottom() - 4, pRect->width, 4);
+ m_rtDisCaption.Set(pRect->left, pRect->top, pRect->width, 29);
+}
+void CFWL_FormTP::DrawCaption(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+ CFX_RectF rt;
+ FX_FLOAT fBottom, fRight;
+ fBottom = pRect->bottom();
+ fRight = pRect->right();
+ rt.Set(pRect->left, pRect->top, pRect->width, 1);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeTop[iActive][0], &rt, pMatrix);
+ rt.Offset(0, 1);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeTop[iActive][1], &rt, pMatrix);
+ rt.Offset(0, 1);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeTop[iActive][2], &rt, pMatrix);
+ rt.Set(pRect->left, pRect->bottom() - 1, pRect->width, 1);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeBottom[iActive][2], &rt, pMatrix);
+ rt.Offset(0, -1);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeBottom[iActive][1], &rt, pMatrix);
+ rt.Set(pRect->left, pRect->top, 1, pRect->height);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeLeft[iActive][2], &rt, pMatrix);
+ rt.Set(pRect->left + 1, pRect->top + 1, 1, fBottom - 1);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeLeft[iActive][1], &rt, pMatrix);
+ rt.Set(pRect->left + 2, pRect->top + 2, 1, fBottom - 2);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeLeft[iActive][0], &rt, pMatrix);
+ rt.Set(fRight - 1, pRect->top, pRect->width, pRect->height);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeRight[iActive][2], &rt, pMatrix);
+ rt.Set(fRight - 2, pRect->top + 1, 1, fBottom - 1);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeRight[iActive][1], &rt, pMatrix);
+ rt.Set(fRight - 3, pRect->top + 2, 1, fBottom - 2);
+ FillSoildRect(pGraphics, m_pThemeData->clrHeadEdgeRight[iActive][0], &rt, pMatrix);
+ CFX_RectF rect(*pRect);
+ rect.Set(rect.left + 3, rect.top + 3, rect.width - 6, rect.height - 5);
+ if (iActive == 0) {
+ pGraphics->StretchImage(m_pActiveBitmap, rect, pMatrix);
+ } else {
+ pGraphics->StretchImage(m_pDeactivebitmap, rect, pMatrix);
+ }
+}
+void CFWL_FormTP::DrawNarrowCaption(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+}
+void CFWL_FormTP::DrawCloseBox(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+ FX_FLOAT fRight = pRect->right();
+ FX_FLOAT fBottom = pRect->bottom();
+ FX_FLOAT fWidth = pRect->width;
+ FX_FLOAT fHeight = pRect->height;
+ pGraphics->SaveGraphState();
+ CFX_RectF rt(*pRect);
+ pGraphics->SetLineWidth(1.0f);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(rt.left + 1, rt.top, fWidth - 2, 1);
+ path.AddRectangle(rt.left, rt.top + 1, 1, fHeight - 2);
+ path.AddRectangle(fRight - 1, rt.top + 1, 1, fHeight - 2);
+ path.AddRectangle(rt.left + 1, fBottom - 1, fWidth - 2, 1);
+ CFX_Color crFill;
+ crFill = m_pThemeData->clrBtnEdgeOut[iActive];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(rt.left + 1, rt.top + 1, 1, 1);
+ path.AddRectangle(fRight - 2, rt.top + 1, 1, 1);
+ path.AddRectangle(rt.left + 1, fBottom - 2, 1, 1);
+ path.AddRectangle(fRight - 2, fBottom - 2, 1, 1);
+ crFill = m_pThemeData->clrBtnCornerLight[iActive][eState - 1];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(rt.left + 2, rt.top + 1, fWidth - 4, 1);
+ path.AddRectangle(rt.left + 1, rt.top + 2, 1, fHeight - 4);
+ crFill = m_pThemeData->clrCloseBtEdgeLight[iActive][eState - 1];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(fRight - 2, rt.top + 2, 1, fHeight - 4);
+ path.AddRectangle(rt.left + 2, fBottom - 2, fWidth - 4, 1);
+ crFill = m_pThemeData->clrCloseBtEdgeDark[iActive][eState - 1];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(pRect->left + 2, pRect->top + 2, fWidth - 4, fHeight - 4);
+ DrawAxialShading(pGraphics,
+ pRect->left + 2,
+ pRect->top + 2,
+ fRight - 2,
+ fBottom - 2,
+ m_pThemeData->clrCloseBtBKStart[iActive][eState - 1],
+ m_pThemeData->clrCloseBtBKEnd[iActive][eState - 1],
+ &path, FXFILL_WINDING, pMatrix);
+ CFX_RectF rtX(*pRect);
+ rtX.Inflate(-5, -5);
+ FX_FLOAT fR = rtX.right();
+ path.Clear();
+ FX_FLOAT frtXRight = rtX.right();
+ FX_FLOAT frtXBottom = rtX.bottom();
+ path.AddLine(rtX.left, rtX.top + 1, frtXRight - 1, frtXBottom);
+ path.AddLine(rtX.left, rtX.top, frtXRight, frtXBottom);
+ path.AddLine(rtX.left + 1, rtX.top, frtXRight, frtXBottom - 1);
+ path.AddLine(rtX.left, frtXBottom - 1, frtXRight - 1, rtX.top);
+ path.AddLine(rtX.left, frtXBottom, frtXRight, rtX.top);
+ path.AddLine(rtX.left + 1, frtXBottom, frtXRight, rtX.top + 1);
+ CFX_Color clrLine(0xffffffff);
+ pGraphics->SetLineWidth(1.0f);
+ pGraphics->SetStrokeColor(&clrLine);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_FormTP::DrawMinMaxBoxCommon(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+ pGraphics->SaveGraphState();
+ FX_FLOAT fRight = pRect->right();
+ FX_FLOAT fBottom = pRect->bottom();
+ FX_FLOAT fWidth = pRect->width;
+ FX_FLOAT fHeight = pRect->height;
+ CFX_RectF rt(*pRect);
+ pGraphics->SetLineWidth(1.0f);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(rt.left + 1, rt.top, fWidth - 2, 1);
+ path.AddRectangle(rt.left, rt.top + 1, 1, fHeight - 2);
+ path.AddRectangle(fRight - 1, rt.top + 1, 1, fHeight - 2);
+ path.AddRectangle(rt.left + 1, fBottom - 1, fWidth - 2, 1);
+ CFX_Color crFill;
+ crFill = m_pThemeData->clrBtnEdgeOut[iActive];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(rt.left + 1, rt.top + 1, 1, 1);
+ path.AddRectangle(fRight - 2, rt.top + 1, 1, 1);
+ path.AddRectangle(rt.left + 1, fBottom - 2, 1, 1);
+ path.AddRectangle(fRight - 2, fBottom - 2, 1, 1);
+ crFill = m_pThemeData->clrBtnCornerLight[iActive][eState - 1];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(rt.left + 2, rt.top + 1, fWidth - 4, 1);
+ path.AddRectangle(rt.left + 1, rt.top + 2, 1, fHeight - 4);
+ crFill = m_pThemeData->clrNormalBtEdgeLight[iActive][eState - 1];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(fRight - 2, rt.top + 2, 1, fHeight - 4);
+ path.AddRectangle(rt.left + 2, fBottom - 2, fWidth - 4, 1);
+ crFill = m_pThemeData->clrNormalBtEdgeDark[iActive][eState - 1];
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+ path.Clear();
+ path.AddRectangle(pRect->left + 2, pRect->top + 2, fWidth - 4, fHeight - 4);
+ DrawAxialShading(pGraphics,
+ pRect->left + 2,
+ pRect->top + 2,
+ fRight - 2,
+ fBottom - 2,
+ m_pThemeData->clrNormalBtBKStart[iActive][eState - 1],
+ m_pThemeData->clrNormalBtBKEnd[iActive][eState - 1],
+ &path, FXFILL_WINDING, pMatrix);
+}
+void CFWL_FormTP::DrawMinimizeBox(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+ DrawMinMaxBoxCommon(pGraphics, pRect, eState, pMatrix);
+ CFX_RectF rtMin;
+ rtMin.Set(pRect->left + 5, pRect->top + 13, pRect->width - 14, pRect->height - 18);
+ FillSoildRect(pGraphics, 0xFFFFFFFF, &rtMin, pMatrix);
+}
+void CFWL_FormTP::DrawMaximizeBox(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, FX_BOOL bMax, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+ DrawMinMaxBoxCommon(pGraphics, pRect, eState, pMatrix);
+ FX_FLOAT fWidth = pRect->width;
+ FX_FLOAT fHeight = pRect->height;
+ if (bMax) {
+ CFX_Path path;
+ path.Create();
+ path.AddLine(pRect->left + 7, pRect->top + 6, pRect->left + 14, pRect->top + 6);
+ path.AddLine(pRect->left + 4, pRect->top + 9, pRect->left + 11, pRect->top + 9);
+ pGraphics->SaveGraphState();
+ pGraphics->SetLineWidth(2);
+ CFX_Color crStroke(0xFFFFFFFF);
+ pGraphics->SetStrokeColor(&crStroke);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->SetLineWidth(1);
+ path.Clear();
+ path.AddLine(pRect->left + 4, pRect->top + 10, pRect->left + 4, pRect->top + 14);
+ path.AddLine(pRect->left + 10, pRect->top + 10, pRect->left + 10, pRect->top + 14);
+ path.AddLine(pRect->left + 13, pRect->top + 7, pRect->left + 13, pRect->top + 11);
+ path.AddLine(pRect->left + 4, pRect->top + 14, pRect->left + 10, pRect->top + 14);
+ path.AddLine(pRect->left + 12, pRect->top + 11, pRect->left + 12, pRect->top + 11);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+ } else {
+ CFX_RectF rtMax(*pRect);
+ rtMax.Inflate(-5, -5);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left + 5, pRect->top + 5, fWidth - 10, fHeight - 10);
+ path.AddRectangle(pRect->left + 6, pRect->top + 8, fWidth - 12, fHeight - 14);
+ pGraphics->SaveGraphState();
+ CFX_Color crFill(0xFFFFFFFF);
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+ pGraphics->RestoreGraphState();
+ }
+}
+void CFWL_FormTP::DrawIconImage(CFX_Graphics *pGraphics, CFX_DIBitmap *pDIBitmap, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix, FX_INT32 iActive)
+{
+ pGraphics->StretchImage(pDIBitmap, *pRect, pMatrix);
+}
+void CFWL_FormTP::SetThemeData(FX_DWORD dwID)
+{
+ m_pThemeData->clrTransWhite = ArgbEncode(0x65, 255, 255, 255);
+ m_pThemeData->clrCloseBtBKStart[0][0] = ArgbEncode(0xff, 240, 166, 148);
+ m_pThemeData->clrCloseBtBKEnd[0][0] = ArgbEncode(0xff, 228, 61, 5);
+ m_pThemeData->clrCloseBtBKStart[0][1] = ArgbEncode(0xff, 255, 184, 176);
+ m_pThemeData->clrCloseBtBKEnd[0][1] = ArgbEncode(0xff, 252, 107, 71);
+ m_pThemeData->clrCloseBtBKStart[0][2] = ArgbEncode(0xff, 141, 44, 20);
+ m_pThemeData->clrCloseBtBKEnd[0][2] = ArgbEncode(0xff, 202, 72, 33);
+ m_pThemeData->clrCloseBtEdgeLight[0][0] = ArgbEncode(0xff, 255, 122, 107);
+ m_pThemeData->clrCloseBtEdgeDark[0][0] = ArgbEncode(0xff, 218, 77, 54);
+ m_pThemeData->clrCloseBtEdgeLight[0][1] = ArgbEncode(0xff, 255, 93, 74);
+ m_pThemeData->clrCloseBtEdgeDark[0][1] = ArgbEncode(0xff, 218, 74, 51);
+ m_pThemeData->clrCloseBtEdgeLight[0][2] = ArgbEncode(0xff, 191, 61, 28);
+ m_pThemeData->clrCloseBtEdgeDark[0][2] = ArgbEncode(0xff, 93, 30, 13);
+ if (dwID) {
+ m_pThemeData->clrHeadBK[0][0] = ArgbEncode(0xff, 194, 205, 149);
+ m_pThemeData->clrHeadBK[0][1] = ArgbEncode(0xff, 170, 184, 131);
+ m_pThemeData->clrHeadBK[0][2] = ArgbEncode(0xff, 168, 182, 128);
+ m_pThemeData->clrHeadBK[0][3] = ArgbEncode(0xff, 194, 205, 149);
+ m_pThemeData->clrHeadEdgeLeft[0][0] = ArgbEncode(0xff, 117, 141, 94);
+ m_pThemeData->clrHeadEdgeLeft[0][1] = ArgbEncode(0xff, 139, 161, 105);
+ m_pThemeData->clrHeadEdgeLeft[0][2] = ArgbEncode(0xff, 171, 189, 133);
+ m_pThemeData->clrHeadEdgeRight[0][0] = ArgbEncode(0xff, 155, 175, 125);
+ m_pThemeData->clrHeadEdgeRight[0][1] = ArgbEncode(0xff, 128, 146, 103);
+ m_pThemeData->clrHeadEdgeRight[0][2] = ArgbEncode(0xff, 94, 118, 79);
+ m_pThemeData->clrHeadEdgeTop[0][0] = ArgbEncode(0xff, 139, 161, 105);
+ m_pThemeData->clrHeadEdgeTop[0][1] = ArgbEncode(0xff, 234, 245, 201);
+ m_pThemeData->clrHeadEdgeTop[0][2] = ArgbEncode(0xff, 194, 205, 149);
+ m_pThemeData->clrHeadEdgeBottom[0][0] = ArgbEncode(0xff, 175, 189, 133 );
+ m_pThemeData->clrHeadEdgeBottom[0][1] = ArgbEncode(0xff, 153, 168, 121);
+ m_pThemeData->clrHeadEdgeBottom[0][2] = ArgbEncode(0xff, 150, 168, 103);
+ m_pThemeData->clrNormalBtBKStart[0][0] = ArgbEncode(0xff, 182, 195, 162);
+ m_pThemeData->clrNormalBtBKEnd[0][0] = ArgbEncode(0xff, 128, 144, 84);
+ m_pThemeData->clrNormalBtBKStart[0][1] = ArgbEncode(0xff, 234, 241, 208);
+ m_pThemeData->clrNormalBtBKEnd[0][1] = ArgbEncode(0xff, 169, 186, 112);
+ m_pThemeData->clrNormalBtBKStart[0][2] = ArgbEncode(0xff, 199, 199, 190);
+ m_pThemeData->clrNormalBtBKEnd[0][2] = ArgbEncode(0xff, 133, 148, 88);
+ m_pThemeData->clrNormalBtEdgeLight[0][0] = ArgbEncode(0xff, 163, 176, 137);
+ m_pThemeData->clrNormalBtEdgeDark[0][0] = ArgbEncode(0xff, 118, 135, 83);
+ m_pThemeData->clrNormalBtEdgeLight[0][1] = ArgbEncode(0xff, 154, 174, 105);
+ m_pThemeData->clrNormalBtEdgeDark[0][1] = ArgbEncode(0xff, 154, 174, 105);
+ m_pThemeData->clrNormalBtEdgeLight[0][2] = ArgbEncode(0xff, 172, 193, 123);
+ m_pThemeData->clrNormalBtEdgeDark[0][2] = ArgbEncode(0xff, 154, 174, 105);
+ m_pThemeData->clrBtnCornerLight[0][0] = ArgbEncode(0xff, 220, 220, 220);
+ m_pThemeData->clrBtnCornerLight[0][1] = ArgbEncode(0xff, 255, 255, 255);
+ m_pThemeData->clrBtnCornerLight[0][2] = ArgbEncode(0xff, 225, 225, 225);
+ m_pThemeData->clrBtnEdgeOut[0] = ArgbEncode(0xff, 255, 255, 255);
+ m_pThemeData->clrFormBorder[0][0] = ArgbEncode(0xff, 117, 141, 94);
+ m_pThemeData->clrFormBorder[0][1] = ArgbEncode(0xff, 139, 161, 105);
+ m_pThemeData->clrFormBorder[0][2] = ArgbEncode(0xff, 171, 189, 133);
+ m_pThemeData->clrFormBorder[0][3] = ArgbEncode(0xff, 164, 178, 127);
+ m_pThemeData->clrFormBorder[0][4] = ArgbEncode(0xff, 255, 255, 255);
+ m_pThemeData->clrFormBorderLight[0] = ArgbEncode(0xff, 171, 189, 133);
+ } else {
+ m_pThemeData->clrHeadBK[0][0] = ArgbEncode(0xff, 3, 114, 255);
+ m_pThemeData->clrHeadBK[0][1] = ArgbEncode(0xff, 0, 85, 226);
+ m_pThemeData->clrHeadBK[0][2] = ArgbEncode(0xff, 0, 85, 226);
+ m_pThemeData->clrHeadBK[0][3] = ArgbEncode(0xff, 3, 114, 255);
+ m_pThemeData->clrHeadEdgeLeft[0][2] = ArgbEncode(0xff, 0, 32, 200);
+ m_pThemeData->clrHeadEdgeLeft[0][1] = ArgbEncode(0xff, 0, 61, 220);
+ m_pThemeData->clrHeadEdgeLeft[0][0] = ArgbEncode(0xff, 0, 54, 210);
+ m_pThemeData->clrHeadEdgeRight[0][0] = ArgbEncode(0xff, 0, 56, 234);
+ m_pThemeData->clrHeadEdgeRight[0][1] = ArgbEncode(0xff, 0, 50, 193);
+ m_pThemeData->clrHeadEdgeRight[0][2] = ArgbEncode(0xff, 0, 19, 139);
+ m_pThemeData->clrHeadEdgeTop[0][0] = ArgbEncode(0xff, 0, 88, 238);
+ m_pThemeData->clrHeadEdgeTop[0][1] = ArgbEncode(0xff, 63, 151, 255);
+ m_pThemeData->clrHeadEdgeTop[0][2] = ArgbEncode(0xff, 3, 114, 255);
+ m_pThemeData->clrHeadEdgeBottom[0][0] = ArgbEncode(0xff, 0, 96, 252);
+ m_pThemeData->clrHeadEdgeBottom[0][1] = ArgbEncode(0xff, 63, 151, 255);
+ m_pThemeData->clrHeadEdgeBottom[0][2] = ArgbEncode(0xff, 0, 67, 207);
+ m_pThemeData->clrNormalBtBKStart[0][2] = ArgbEncode(0xff, 0, 49, 112);
+ m_pThemeData->clrNormalBtBKEnd[0][2] = ArgbEncode(0xff, 0, 87, 188);
+ m_pThemeData->clrNormalBtBKStart[0][0] = ArgbEncode(0xff, 154, 183, 250 );
+ m_pThemeData->clrNormalBtBKEnd[0][0] = ArgbEncode(0xff, 17, 110, 248);
+ m_pThemeData->clrNormalBtBKStart[0][1] = ArgbEncode(0xff, 164, 194, 255);
+ m_pThemeData->clrNormalBtBKEnd[0][1] = ArgbEncode(0xff, 29, 158, 255);
+ m_pThemeData->clrNormalBtEdgeLight[0][0] = ArgbEncode(0xff, 68, 120, 245);
+ m_pThemeData->clrNormalBtEdgeDark[0][0] = ArgbEncode(0xff, 24, 72, 187);
+ m_pThemeData->clrNormalBtEdgeLight[0][1] = ArgbEncode(0xff, 72, 122, 245);
+ m_pThemeData->clrNormalBtEdgeDark[0][1] = ArgbEncode(0xff, 35, 87, 195);
+ m_pThemeData->clrNormalBtEdgeLight[0][2] = ArgbEncode(0xff, 60, 114, 244);
+ m_pThemeData->clrNormalBtEdgeDark[0][2] = ArgbEncode(0xff, 21, 70, 185);
+ m_pThemeData->clrBtnCornerLight[0][0] = ArgbEncode(0xff, 220, 220, 220);
+ m_pThemeData->clrBtnCornerLight[0][1] = ArgbEncode(0xff, 255, 255, 255);
+ m_pThemeData->clrBtnCornerLight[0][2] = ArgbEncode(0xff, 225, 225, 225);
+ m_pThemeData->clrBtnEdgeOut[0] = ArgbEncode(0xff, 255, 255, 255);
+ m_pThemeData->clrFormBorder[0][0] = ArgbEncode(0xff, 0, 72, 241);
+ m_pThemeData->clrFormBorder[0][1] = ArgbEncode(0xff, 0, 61, 220);
+ m_pThemeData->clrFormBorder[0][2] = ArgbEncode(0xff, 0, 30, 160);
+ m_pThemeData->clrFormBorder[0][3] = ArgbEncode(0xff, 0, 19, 140);
+ m_pThemeData->clrFormBorder[0][4] = ArgbEncode(0xff, 255, 255, 255);
+ m_pThemeData->clrFormBorderLight[0] = ArgbEncode(0xff, 22, 106, 239);
+ }
+ m_pThemeData->clrCloseBtBKStart[1][0] = m_pThemeData->clrCloseBtBKStart[0][0];
+ m_pThemeData->clrCloseBtBKEnd[1][0] = m_pThemeData->clrCloseBtBKEnd[0][0];
+ m_pThemeData->clrCloseBtBKStart[1][1] = m_pThemeData->clrCloseBtBKStart[0][1];
+ m_pThemeData->clrCloseBtBKEnd[1][1] = m_pThemeData->clrCloseBtBKEnd[0][1];
+ m_pThemeData->clrCloseBtBKStart[1][2] = m_pThemeData->clrCloseBtBKStart[0][2];
+ m_pThemeData->clrCloseBtBKEnd[1][2] = m_pThemeData->clrCloseBtBKEnd[0][2];
+ m_pThemeData->clrCloseBtEdgeLight[1][0] = m_pThemeData->clrCloseBtEdgeLight[0][0];
+ m_pThemeData->clrCloseBtEdgeDark[1][0] = m_pThemeData->clrCloseBtEdgeDark[0][0];
+ m_pThemeData->clrCloseBtEdgeLight[1][1] = m_pThemeData->clrCloseBtEdgeLight[0][1];
+ m_pThemeData->clrCloseBtEdgeDark[1][1] = m_pThemeData->clrCloseBtEdgeDark[0][1];
+ m_pThemeData->clrCloseBtEdgeLight[1][2] = m_pThemeData->clrCloseBtEdgeLight[0][2];
+ m_pThemeData->clrCloseBtEdgeDark[1][2] = m_pThemeData->clrCloseBtEdgeDark[0][2];
+ m_pThemeData->clrHeadBK[1][0] = m_pThemeData->clrHeadBK[0][0];
+ m_pThemeData->clrHeadBK[1][1] = m_pThemeData->clrHeadBK[0][1];
+ m_pThemeData->clrHeadBK[1][2] = m_pThemeData->clrHeadBK[0][2];
+ m_pThemeData->clrHeadBK[1][3] = m_pThemeData->clrHeadBK[0][3];
+ m_pThemeData->clrHeadEdgeLeft[1][2] = m_pThemeData->clrHeadEdgeLeft[0][2];
+ m_pThemeData->clrHeadEdgeLeft[1][1] = m_pThemeData->clrHeadEdgeLeft[0][1];
+ m_pThemeData->clrHeadEdgeLeft[1][0] = m_pThemeData->clrHeadEdgeLeft[0][0];
+ m_pThemeData->clrHeadEdgeRight[1][0] = m_pThemeData->clrHeadEdgeRight[0][0];
+ m_pThemeData->clrHeadEdgeRight[1][1] = m_pThemeData->clrHeadEdgeRight[0][1];
+ m_pThemeData->clrHeadEdgeRight[1][2] = m_pThemeData->clrHeadEdgeRight[0][2];
+ m_pThemeData->clrHeadEdgeTop[1][0] = m_pThemeData->clrHeadEdgeTop[0][0];
+ m_pThemeData->clrHeadEdgeTop[1][1] = m_pThemeData->clrHeadEdgeTop[0][1];
+ m_pThemeData->clrHeadEdgeTop[1][2] = m_pThemeData->clrHeadEdgeTop[0][2];
+ m_pThemeData->clrHeadEdgeBottom[1][0] = m_pThemeData->clrHeadEdgeBottom[0][0];
+ m_pThemeData->clrHeadEdgeBottom[1][1] = m_pThemeData->clrHeadEdgeBottom[0][1];
+ m_pThemeData->clrHeadEdgeBottom[1][2] = m_pThemeData->clrHeadEdgeBottom[0][2];
+ m_pThemeData->clrNormalBtBKStart[1][2] = m_pThemeData->clrNormalBtBKStart[0][2];
+ m_pThemeData->clrNormalBtBKEnd[1][2] = m_pThemeData->clrNormalBtBKEnd[0][2];
+ m_pThemeData->clrNormalBtBKStart[1][0] = m_pThemeData->clrNormalBtBKStart[0][0];
+ m_pThemeData->clrNormalBtBKEnd[1][0] = m_pThemeData->clrNormalBtBKEnd[1][0];
+ m_pThemeData->clrNormalBtBKStart[1][1] = m_pThemeData->clrNormalBtBKStart[0][1];
+ m_pThemeData->clrNormalBtBKEnd[1][1] = m_pThemeData->clrNormalBtBKEnd[0][1];
+ m_pThemeData->clrNormalBtEdgeLight[1][0] = m_pThemeData->clrNormalBtEdgeLight[0][0];
+ m_pThemeData->clrNormalBtEdgeDark[1][0] = m_pThemeData->clrNormalBtEdgeDark[0][0];
+ m_pThemeData->clrNormalBtEdgeLight[1][1] = m_pThemeData->clrNormalBtEdgeLight[0][1];
+ m_pThemeData->clrNormalBtEdgeDark[1][1] = m_pThemeData->clrNormalBtEdgeDark[0][1];
+ m_pThemeData->clrNormalBtEdgeLight[1][2] = m_pThemeData->clrNormalBtEdgeLight[0][2];
+ m_pThemeData->clrNormalBtEdgeDark[1][2] = m_pThemeData->clrNormalBtEdgeDark[0][2];
+ m_pThemeData->clrBtnCornerLight[1][0] = m_pThemeData->clrBtnCornerLight[0][0];
+ m_pThemeData->clrBtnCornerLight[1][1] = m_pThemeData->clrBtnCornerLight[0][1];
+ m_pThemeData->clrBtnCornerLight[1][2] = m_pThemeData->clrBtnCornerLight[0][2];
+ m_pThemeData->clrBtnEdgeOut[1] = m_pThemeData->clrBtnEdgeOut[0];
+ m_pThemeData->clrFormBorder[1][0] = m_pThemeData->clrFormBorder[0][0];
+ m_pThemeData->clrFormBorder[1][1] = m_pThemeData->clrFormBorder[0][1];
+ m_pThemeData->clrFormBorder[1][2] = m_pThemeData->clrFormBorder[0][2];
+ m_pThemeData->clrFormBorder[1][3] = m_pThemeData->clrFormBorder[0][3];
+ m_pThemeData->clrFormBorder[1][4] = m_pThemeData->clrFormBorder[0][4];
+ m_pThemeData->clrFormBorderLight[1] = m_pThemeData->clrFormBorderLight[0];
+ DeactiveForm();
+}
+void CFWL_FormTP::DeactiveForm()
+{
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadBK[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadBK[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadBK[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadBK[1][3]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeLeft[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeLeft[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeLeft[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeRight[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeRight[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeRight[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeTop[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeTop[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeTop[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeBottom[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeBottom[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrHeadEdgeBottom[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtBKStart[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtBKStart[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtBKStart[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtBKEnd[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtBKEnd[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtBKEnd[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtEdgeLight[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtEdgeLight[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtEdgeLight[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtEdgeDark[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtEdgeDark[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrNormalBtEdgeDark[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrBtnCornerLight[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrBtnCornerLight[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrBtnCornerLight[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrBtnEdgeOut[1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrFormBorder[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrFormBorder[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrFormBorder[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrFormBorder[1][3]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrFormBorder[1][4]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrFormBorderLight[1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtBKStart[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtBKStart[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtBKStart[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtBKEnd[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtBKEnd[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtBKEnd[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtEdgeLight[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtEdgeLight[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtEdgeLight[1][2]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtEdgeDark[1][0]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtEdgeDark[1][1]);
+ TransModeColor(m_pThemeData->clrTransWhite, m_pThemeData->clrCloseBtEdgeDark[1][2]);
+}
+void CFWL_FormTP::TransModeColor(FX_ARGB clrFore, FX_ARGB &clrBack)
+{
+ FX_INT32 iAlfaF, iRF, iGF, iBF;
+ FX_INT32 iAlfaB, iRB, iGB, iBB;
+ ArgbDecode(clrFore, iAlfaF, iRF, iGF, iBF);
+ ArgbDecode(clrBack, iAlfaB, iRB, iGB, iBB);
+ clrBack = ArgbEncode(0xff,
+ iRB + (iRF - iRB) * iAlfaF / 255,
+ iGB + (iGF - iGB) * iAlfaF / 255,
+ iBB + (iBF - iBB) * iAlfaF / 255);
+}
+void CFWL_FormTP::InitCaption(FX_BOOL bActive)
+{
+ if (bActive) {
+ CFX_FxgeDevice dev;
+ CFX_Graphics gs;
+ CFX_Path path;
+ path.Create();
+ if (m_pActiveBitmap) {
+ delete m_pActiveBitmap;
+ m_pActiveBitmap = NULL;
+ }
+ m_pActiveBitmap = FX_NEW CFX_DIBitmap;
+ m_pActiveBitmap->Create(1, FWLTHEME_CAPACITY_CYCaption, FXDIB_Argb);
+ dev.Attach(m_pActiveBitmap);
+ gs.Create(&dev);
+ path.AddRectangle(0, 0, 1, 5);
+ DrawAxialShading(&gs, 0, 0, 0, 5, m_pThemeData->clrHeadBK[0][0], m_pThemeData->clrHeadBK[0][1], &path);
+ path.Clear();
+ path.AddRectangle(0, 5, 1, 15);
+ DrawAxialShading(&gs, 0, 5, 0, 20, m_pThemeData->clrHeadBK[0][1], m_pThemeData->clrHeadBK[0][2], &path);
+ path.Clear();
+ path.AddRectangle(0, 20, 1, FWLTHEME_CAPACITY_CYCaption - 19);
+ DrawAxialShading(&gs, 0, 20, 0, FWLTHEME_CAPACITY_CYCaption, m_pThemeData->clrHeadBK[0][2], m_pThemeData->clrHeadBK[0][3], &path);
+ } else {
+ CFX_FxgeDevice dev;
+ CFX_Graphics gs;
+ CFX_Path path;
+ path.Create();
+ if (m_pDeactivebitmap) {
+ delete m_pDeactivebitmap;
+ m_pDeactivebitmap = NULL;
+ }
+ m_pDeactivebitmap = FX_NEW CFX_DIBitmap;
+ m_pDeactivebitmap->Create(1, FWLTHEME_CAPACITY_CYCaption, FXDIB_Argb);
+ dev.Attach(m_pDeactivebitmap);
+ gs.Create(&dev);
+ path.AddRectangle(0, 0, 1, 5);
+ DrawAxialShading(&gs, 0, 0, 0, 5, m_pThemeData->clrHeadBK[1][0], m_pThemeData->clrHeadBK[1][1], &path);
+ path.Clear();
+ path.AddRectangle(0, 5, 1, 15);
+ DrawAxialShading(&gs, 0, 5, 0, 20, m_pThemeData->clrHeadBK[1][1], m_pThemeData->clrHeadBK[1][2], &path);
+ path.Clear();
+ path.AddRectangle(0, 20, 1, FWLTHEME_CAPACITY_CYCaption - 19);
+ DrawAxialShading(&gs, 0, 20, 0, FWLTHEME_CAPACITY_CYCaption, m_pThemeData->clrHeadBK[1][2], m_pThemeData->clrHeadBK[1][3], &path);
+ }
+}
diff --git a/xfa/src/fwl/src/theme/listboxtp.cpp b/xfa/src/fwl/src/theme/listboxtp.cpp
new file mode 100644
index 0000000000..a623509973
--- /dev/null
+++ b/xfa/src/fwl/src/theme/listboxtp.cpp
@@ -0,0 +1,92 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_ListBoxTP::CFWL_ListBoxTP()
+{
+}
+CFWL_ListBoxTP::~CFWL_ListBoxTP()
+{
+}
+FX_BOOL CFWL_ListBoxTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_ListBox;
+}
+FX_BOOL CFWL_ListBoxTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch(pParams->m_iPart) {
+ case FWL_PART_LTB_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_LTB_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_LTB_Background: {
+ FillSoildRect(pParams->m_pGraphics, ArgbEncode(255, 255, 255, 255), &pParams->m_rtPart, &pParams->m_matrix);
+ if (pParams->m_pData) {
+ FillSoildRect(pParams->m_pGraphics, FWLTHEME_COLOR_Background, (CFX_RectF*)pParams->m_pData, &pParams->m_matrix);
+ }
+ break;
+ }
+ case FWL_PART_LTB_ListItem: {
+ DrawListBoxItem(pParams->m_pGraphics, pParams->m_dwStates, &pParams->m_rtPart, pParams->m_pData, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_LTB_Icon: {
+ pParams->m_pGraphics->StretchImage(pParams->m_pImage, pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_LTB_Check: {
+ FX_DWORD color = 0xFF000000;
+ if (pParams->m_dwStates == FWL_PARTSTATE_LTB_Checked) {
+ color = 0xFFFF0000;
+ } else if (pParams->m_dwStates == FWL_PARTSTATE_LTB_UnChecked) {
+ color = 0xFF0000FF;
+ }
+ FillSoildRect(pParams->m_pGraphics, color, &pParams->m_rtPart, &pParams->m_matrix);
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
+FWL_ERR CFWL_ListBoxTP::Initialize()
+{
+ InitTTO();
+ return CFWL_WidgetTP::Initialize();
+}
+FWL_ERR CFWL_ListBoxTP::Finalize()
+{
+ FinalizeTTO();
+ return CFWL_WidgetTP::Finalize();
+}
+void CFWL_ListBoxTP::DrawListBoxItem(CFX_Graphics *pGraphics, FX_DWORD dwStates, const CFX_RectF *prtItem, FX_LPVOID pData , CFX_Matrix *pMatrix )
+{
+ if (dwStates & FWL_PARTSTATE_LTB_Selected) {
+ pGraphics->SaveGraphState();
+ CFX_Color crFill(FWL_GetThemeColor(m_dwThemeID) == 0 ? FWLTHEME_COLOR_BKSelected : FWLTHEME_COLOR_Green_BKSelected);
+ pGraphics->SetFillColor(&crFill);
+ CFX_RectF rt(*prtItem);
+ CFX_Path path;
+ path.Create();
+#if (_FX_OS_==_FX_MACOSX_)
+ path.AddRectangle(rt.left, rt.top, rt.width - 1, rt.height - 1);
+#else
+ path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
+#endif
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+ }
+ if (dwStates & FWL_PARTSTATE_LTB_Focused) {
+ if (pData) {
+ DrawFocus(pGraphics, (CFX_RectF*)pData, pMatrix);
+ }
+ }
+}
diff --git a/xfa/src/fwl/src/theme/monthcalendartp.cpp b/xfa/src/fwl/src/theme/monthcalendartp.cpp
new file mode 100644
index 0000000000..2104d873f3
--- /dev/null
+++ b/xfa/src/fwl/src/theme/monthcalendartp.cpp
@@ -0,0 +1,554 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#define FWL_THEMECAPACITY_MC_HEADER_WIDTH 200
+#define FWL_THEMECAPACITY_MC_HEADER_HEIGHT 30
+#define FWL_THEMECAPACITY_MC_HEADER_BTN_WIDTH 18
+#define FWL_THEMECAPACITY_MC_HEADER_BTN_HEIGHT 16
+#define FWL_THEMECAPACITY_MC_HEADER_BTN_HMARGIN 5
+#define FWL_THEMECAPACITY_MC_HEADER_BTN_VMARGIN (FWL_THEMECAPACITY_MC_HEADER_HEIGHT - FWL_THEMECAPACITY_MC_HEADER_BTN_HEIGHT)/2
+#define FWL_THEMECAPACITY_MC_HEADER_TEXTWIDHT 100
+#define FWL_THEMECAPACITY_MC_HEADER_TEXTHEIGHT 20
+#define FWL_THEMECAPACITY_MC_HEADER_TEXT_HMARGIN (FWL_THEMECAPACITY_MC_HEADER_WIDTH - FWL_THEMECAPACITY_MC_HEADER_TEXTWIDHT)/2
+#define FWL_THEMECAPACITY_MC_HEADER_TEXT_VMARGIN (FWL_THEMECAPACITY_MC_HEADER_HEIGHT - FWL_THEMECAPACITY_MC_HEADER_TEXTHEIGHT)/2
+#define FWL_THEMECAPACITY_MC_HSEP_WIDTH (FWL_THEMECAPACITY_MC_WEEK_WIDTH - 10)
+#define FWL_THEMECAPACITY_MC_HSEP_HEIGHT 1
+#define FWL_THEMECAPACITY_MC_VSEP_WIDTH 1
+#define FWL_THEMECAPACITY_MC_VSEP_HEIGHT FWL_THEMECAPACITY_MC_WEEKNUM_HEIGHT
+#define FWL_THEMECAPACITY_MC_WEEKNUM_WIDTH 26
+#define FWL_THEMECAPACITY_MC_SEP_DOFFSET -4
+#define FWL_THEMECAPACITY_MC_SEP_X 3
+#define FWL_THEMECAPACITY_MC_SEP_Y (FWL_THEMECAPACITY_MC_HEADER_HEIGHT + FWL_THEMECAPACITY_MC_WEEK_HEIGHT + FWL_THEMECAPACITY_MC_SEP_DOFFSET)
+#define FWL_THEMECAPACITY_MC_WEEKNUM_HEIGHT (6*FWL_THEMECAPACITY_MC_DATES_CELL_HEIGHT)
+#define FWL_THEMECAPACITY_MC_WEEK_WIDTH (FWL_THEMECAPACITY_MC_DATES_CELL_WIDTH*7)
+#define FWL_THEMECAPACITY_MC_WEEK_HEIGHT FWL_THEMECAPACITY_MC_DATES_CELL_HEIGHT
+#define FWL_THEMECAPACITY_MC_DATES_CELL_WIDTH (FWL_THEMECAPACITY_MC_HEADER_WIDTH/7)
+#define FWL_THEMECAPACITY_MC_DATES_CELL_HEIGHT 16
+#define FWL_THEMECAPACITY_MC_TODAY_WIDHT FWL_THEMECAPACITY_MC_HEADER_WIDTH
+#define FWL_THEMECAPACITY_MC_TODAY_HEIGHT FWL_THEMECAPACITY_MC_DATES_CELL_HEIGHT
+#define FWL_THEMECAPACITY_MC_TODAY_FLAG_WIDHT FWL_THEMECAPACITY_MC_DATES_CELL_WIDTH
+#define FWL_MC_WIDTH 200
+#define FWL_MC_HEIGHT 160
+CFWL_MonthCalendarTP::CFWL_MonthCalendarTP()
+{
+ m_pThemeData = FX_NEW MCThemeData;
+ SetThemeData(0);
+}
+CFWL_MonthCalendarTP::~CFWL_MonthCalendarTP()
+{
+ delete m_pThemeData;
+}
+FX_BOOL CFWL_MonthCalendarTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar;
+}
+FX_DWORD CFWL_MonthCalendarTP::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ if (m_pThemeData) {
+ SetThemeData(FWL_GetThemeColor(dwThemeID));
+ }
+ return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch(pParams->m_iPart) {
+ case FWL_PART_MCD_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_Background: {
+ DrawTotalBK(pParams, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_Header: {
+ DrawHeadBk(pParams, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_LBtn: {
+#ifdef THEME_XPSimilar
+ FWLTHEME_STATE eState = GetState(pParams->m_dwStates);
+ DrawArrowBtn(pParams->m_pGraphics, &pParams->m_rtPart, FWLTHEME_DIRECTION_Left, eState, &pParams->m_matrix);
+#else
+ DrawLButton(pParams, &pParams->m_matrix);
+#endif
+ break;
+ }
+ case FWL_PART_MCD_RBtn: {
+#ifdef THEME_XPSimilar
+ FWLTHEME_STATE eState = GetState(pParams->m_dwStates);
+ DrawArrowBtn(pParams->m_pGraphics, &pParams->m_rtPart, FWLTHEME_DIRECTION_Right, eState, &pParams->m_matrix);
+#else
+ DrawRButton(pParams, &pParams->m_matrix);
+#endif
+ break;
+ }
+ case FWL_PART_MCD_HSeparator: {
+ DrawHSeperator(pParams, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_DatesIn: {
+ DrawDatesInBK(pParams, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_TodayCircle: {
+ DrawTodayCircle(pParams, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_DateInCircle: {
+ DrawDatesInCircle(pParams, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_MCD_WeekNumSep: {
+ DrawWeekNumSep(pParams, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawText(CFWL_ThemeText *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(m_pTextOut, FALSE);
+ if ((pParams->m_iPart == FWL_PART_MCD_DatesIn) && !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) &&
+ (pParams->m_dwStates & (FWL_PARTSTATE_MCD_Hovered | FWL_PARTSTATE_MCD_Selected))) {
+ m_pTextOut->SetTextColor(0xFFFFFFFF);
+ } else if (pParams->m_iPart == FWL_PART_MCD_Caption) {
+ m_pTextOut->SetTextColor(m_pThemeData->clrCaption);
+ } else {
+ m_pTextOut->SetTextColor(0xFF000000);
+ }
+ return CFWL_WidgetTP::DrawText(pParams);
+}
+FX_LPVOID CFWL_MonthCalendarTP::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ FX_BOOL bDefPro = FALSE;
+ FX_BOOL bDwordVal = FALSE;
+ switch(dwCapacity) {
+ case FWL_WGTCAPACITY_MC_HEADER_WIDTH: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_Height: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_BTN_WIDTH: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_BTN_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_BTN_HEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_BTN_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_BTN_HMARGIN: {
+ bDwordVal = TRUE;
+ m_dwValue = FWL_THEMECAPACITY_MC_HEADER_BTN_HMARGIN;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_BTN_VMARGIN: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_BTN_VMARGIN;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_TEXTWIDHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_TEXTWIDHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_TEXTHEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_TEXTHEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_TEXT_HMARGIN: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_TEXT_HMARGIN;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEADER_TEXT_VMARGIN: {
+ m_fValue = FWL_THEMECAPACITY_MC_HEADER_TEXT_VMARGIN;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HSEP_WIDTH: {
+ m_fValue = FWL_THEMECAPACITY_MC_HSEP_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HSEP_HEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_HSEP_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_VSEP_WIDTH: {
+ m_fValue = FWL_THEMECAPACITY_MC_VSEP_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_VSEP_HEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_VSEP_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_WEEKNUM_WIDTH: {
+ m_fValue = FWL_THEMECAPACITY_MC_WEEKNUM_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_WEEKNUM_HEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_WEEKNUM_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_WEEK_WIDTH: {
+ m_fValue = FWL_THEMECAPACITY_MC_WEEK_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_WEEK_HEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_WEEK_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_SEP_DOFFSET: {
+ m_fValue = FWL_THEMECAPACITY_MC_SEP_DOFFSET;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_SEP_X: {
+ m_fValue = FWL_THEMECAPACITY_MC_SEP_X;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_SEP_Y: {
+ m_fValue = FWL_THEMECAPACITY_MC_SEP_Y;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_DATES_CELL_WIDTH: {
+ m_fValue = FWL_THEMECAPACITY_MC_DATES_CELL_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_DATES_CELL_HEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_DATES_CELL_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_TODAY_WIDHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_TODAY_WIDHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_TODAY_HEIGHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_TODAY_HEIGHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_TODAY_FLAG_WIDHT: {
+ m_fValue = FWL_THEMECAPACITY_MC_TODAY_FLAG_WIDHT;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_WIDTH: {
+ m_fValue = FWL_MC_WIDTH;
+ break;
+ }
+ case FWL_WGTCAPACITY_MC_HEIGHT: {
+ m_fValue = FWL_MC_HEIGHT;
+ break;
+ }
+ case FWL_MCCAPACITY_Sun: {
+ wsResource = L"Sun";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_Mon: {
+ wsResource = L"Mon";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_Tue: {
+ wsResource = L"Tue";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_Wed: {
+ wsResource = L"Wed";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_Thu: {
+ wsResource = L"Thu";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_Fri: {
+ wsResource = L"Fri";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_Sat: {
+ wsResource = L"Sat";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_January: {
+ wsResource = L"January";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_February: {
+ wsResource = L"February";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_March: {
+ wsResource = L"March";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_April: {
+ wsResource = L"April";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_May: {
+ wsResource = L"May";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_June: {
+ wsResource = L"June";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_July: {
+ wsResource = L"July";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_August: {
+ wsResource = L"August";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_September: {
+ wsResource = L"September";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_October: {
+ wsResource = L"October";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_November: {
+ wsResource = L"November";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_December: {
+ wsResource = L"December";
+ return &wsResource;
+ }
+ case FWL_MCCAPACITY_Today: {
+ wsResource = L"Today";
+ return &wsResource;
+ }
+ default: {
+ bDefPro = TRUE;
+ }
+ }
+ if (!bDefPro) {
+ if (bDwordVal) {
+ return &m_dwValue;
+ }
+ return &m_fValue;
+ }
+ return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
+}
+FWL_ERR CFWL_MonthCalendarTP::Initialize()
+{
+ InitTTO();
+ return CFWL_WidgetTP::Initialize();
+}
+FWL_ERR CFWL_MonthCalendarTP::Finalize()
+{
+ FinalizeTTO();
+ return CFWL_WidgetTP::Finalize();
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawTotalBK(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtTotal(pParams->m_rtPart);
+ path.AddRectangle(rtTotal.left, rtTotal.top, rtTotal.width, rtTotal.height);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrBK(m_pThemeData->clrBK);
+ pParams->m_pGraphics->SetFillColor(&clrBK);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawHeadBk(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtHead = pParams->m_rtPart;
+ path.AddRectangle(rtHead.left, rtHead.top, rtHead.width, rtHead.height);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrHeadBK(m_pThemeData->clrBK);
+ pParams->m_pGraphics->SetFillColor(&clrHeadBK);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawLButton(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtLBtn;
+ rtLBtn = pParams->m_rtPart;
+ path.AddRectangle(rtLBtn.left, rtLBtn.top, rtLBtn.width, rtLBtn.height);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrLBtnEdge(ArgbEncode(0xff, 205, 219, 243));
+ pParams->m_pGraphics->SetStrokeColor(&clrLBtnEdge);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ if ((pParams->m_dwStates & FWL_PARTSTATE_MCD_Pressed) == FWL_PARTSTATE_MCD_Pressed) {
+ CFX_Color clrLBtnFill(ArgbEncode(0xff, 174, 198, 242));
+ pParams->m_pGraphics->SetFillColor(&clrLBtnFill);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ } else {
+ CFX_Color clrLBtnFill(ArgbEncode(0xff, 227, 235, 249));
+ pParams->m_pGraphics->SetFillColor(&clrLBtnFill);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ }
+ path.Clear();
+ path.MoveTo(rtLBtn.left + rtLBtn.Width() / 3 * 2, rtLBtn.top + rtLBtn.height / 4);
+ path.LineTo(rtLBtn.left + rtLBtn.Width() / 3, rtLBtn.top + rtLBtn.height / 2);
+ path.LineTo(rtLBtn.left + rtLBtn.Width() / 3 * 2, rtLBtn.bottom() - rtLBtn.height / 4);
+ CFX_Color clrFlag(ArgbEncode(0xff, 50, 104, 205));
+ pParams->m_pGraphics->SetStrokeColor(&clrFlag);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawRButton(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtRBtn;
+ rtRBtn = pParams->m_rtPart;
+ path.AddRectangle(rtRBtn.left, rtRBtn.top, rtRBtn.width, rtRBtn.height);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrRBtnEdge(ArgbEncode(0xff, 205, 219, 243));
+ pParams->m_pGraphics->SetStrokeColor(&clrRBtnEdge);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ if ((pParams->m_dwStates & FWL_PARTSTATE_MCD_Pressed) == FWL_PARTSTATE_MCD_Pressed) {
+ CFX_Color clrRBtnFill(ArgbEncode(0xff, 174, 198, 242));
+ pParams->m_pGraphics->SetFillColor(&clrRBtnFill);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ } else {
+ CFX_Color clrRBtnFill(ArgbEncode(0xff, 227, 235, 249));
+ pParams->m_pGraphics->SetFillColor(&clrRBtnFill);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ }
+ path.Clear();
+ path.MoveTo(rtRBtn.left + rtRBtn.Width() / 3, rtRBtn.top + rtRBtn.height / 4);
+ path.LineTo(rtRBtn.left + rtRBtn.Width() / 3 * 2, rtRBtn.top + rtRBtn.height / 2);
+ path.LineTo(rtRBtn.left + rtRBtn.Width() / 3, rtRBtn.bottom() - rtRBtn.height / 4);
+ CFX_Color clrFlag(ArgbEncode(0xff, 50, 104, 205));
+ pParams->m_pGraphics->SetStrokeColor(&clrFlag);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawHSeperator(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtHSep;
+ rtHSep = pParams->m_rtPart;
+ path.MoveTo(rtHSep.left, rtHSep.top + rtHSep.height / 2);
+ path.LineTo(rtHSep.right(), rtHSep.top + rtHSep.height / 2);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrHSep(m_pThemeData->clrSeperator);
+ pParams->m_pGraphics->SetStrokeColor(&clrHSep);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawWeekNumSep(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtWeekSep;
+ rtWeekSep = pParams->m_rtPart;
+ path.MoveTo(rtWeekSep.left, rtWeekSep.top);
+ path.LineTo(rtWeekSep.left, rtWeekSep.bottom());
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrHSep(m_pThemeData->clrSeperator);
+ pParams->m_pGraphics->SetStrokeColor(&clrHSep);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawDatesInBK(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ pParams->m_pGraphics->SaveGraphState();
+ if (pParams->m_dwStates & FWL_PARTSTATE_MCD_Selected) {
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtSelDay;
+ rtSelDay = pParams->m_rtPart;
+ path.AddRectangle(rtSelDay.left, rtSelDay.top, rtSelDay.width, rtSelDay.height);
+ CFX_Color clrSelDayBK;
+ clrSelDayBK = m_pThemeData->clrDatesSelectedBK;
+ pParams->m_pGraphics->SetFillColor(&clrSelDayBK);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ } else if (pParams->m_dwStates & FWL_PARTSTATE_MCD_Hovered) {
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtSelDay;
+ rtSelDay = pParams->m_rtPart;
+ path.AddRectangle(rtSelDay.left, rtSelDay.top, rtSelDay.width, rtSelDay.height);
+ CFX_Color clrSelDayBK;
+ clrSelDayBK = m_pThemeData->clrDatesHoverBK;
+ pParams->m_pGraphics->SetFillColor(&clrSelDayBK);
+ pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ }
+ pParams->m_pGraphics->RestoreGraphState();
+ return FALSE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawDatesInCircle(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtSelDay;
+ rtSelDay = pParams->m_rtPart;
+ path.AddRectangle(rtSelDay.left, rtSelDay.top, rtSelDay.width, rtSelDay.height);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrSelDayBK;
+ clrSelDayBK = m_pThemeData->clrDatesCircle;
+ pParams->m_pGraphics->SetStrokeColor(&clrSelDayBK);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FX_BOOL CFWL_MonthCalendarTP::DrawTodayCircle(CFWL_ThemeBackground *pParams, CFX_Matrix *pMatrix)
+{
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rtTodayCircle;
+ rtTodayCircle = pParams->m_rtPart;
+ path.AddRectangle(rtTodayCircle.left, rtTodayCircle.top, rtTodayCircle.width, rtTodayCircle.height);
+ pParams->m_pGraphics->SaveGraphState();
+ CFX_Color clrTodayCircle;
+ clrTodayCircle = m_pThemeData->clrDatesCircle;
+ pParams->m_pGraphics->SetStrokeColor(&clrTodayCircle);
+ pParams->m_pGraphics->StrokePath(&path, pMatrix);
+ pParams->m_pGraphics->RestoreGraphState();
+ return TRUE;
+}
+FWLTHEME_STATE CFWL_MonthCalendarTP::GetState(FX_DWORD dwFWLStates)
+{
+ if (dwFWLStates & FWL_PARTSTATE_MCD_Hovered) {
+ return FWLTHEME_STATE_Hover;
+ } else if (dwFWLStates & FWL_PARTSTATE_MCD_Pressed) {
+ return FWLTHEME_STATE_Pressed;
+ }
+ return FWLTHEME_STATE_Normal;
+}
+void CFWL_MonthCalendarTP::SetThemeData(FX_DWORD dwThemeID)
+{
+ if (dwThemeID == 0) {
+ m_pThemeData->clrCaption = ArgbEncode(0xff, 0, 153, 255);
+ m_pThemeData->clrSeperator = ArgbEncode(0xff, 141, 161, 239);
+ m_pThemeData->clrDatesHoverBK = ArgbEncode(0xff, 193, 211, 251);
+ m_pThemeData->clrDatesSelectedBK = ArgbEncode(0xff, 173, 188, 239);
+ m_pThemeData->clrDatesCircle = ArgbEncode(0xff, 103, 144, 209);
+ m_pThemeData->clrToday = ArgbEncode(0xff, 0, 0, 0);
+ m_pThemeData->clrBK = ArgbEncode(0xff, 255, 255, 255);
+ } else {
+ m_pThemeData->clrCaption = ArgbEncode(0xff, 128, 128, 0);
+ m_pThemeData->clrSeperator = ArgbEncode(0xff, 128, 128, 64);
+ m_pThemeData->clrDatesHoverBK = ArgbEncode(0xff, 217, 220, 191);
+ m_pThemeData->clrDatesSelectedBK = ArgbEncode(0xff, 204, 208, 183);
+ m_pThemeData->clrDatesCircle = ArgbEncode(0xff, 128, 128, 0);
+ m_pThemeData->clrToday = ArgbEncode(0xff, 0, 0, 0);
+ m_pThemeData->clrBK = ArgbEncode(0xff, 255, 255, 255);
+ }
+}
diff --git a/xfa/src/fwl/src/theme/pictureboxtp.cpp b/xfa/src/fwl/src/theme/pictureboxtp.cpp
new file mode 100644
index 0000000000..919e786e29
--- /dev/null
+++ b/xfa/src/fwl/src/theme/pictureboxtp.cpp
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+CFWL_PictureBoxTP::CFWL_PictureBoxTP()
+{
+}
+CFWL_PictureBoxTP::~CFWL_PictureBoxTP()
+{
+}
+FX_BOOL CFWL_PictureBoxTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_PictureBox;
+}
+FX_BOOL CFWL_PictureBoxTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ switch (pParams->m_iPart) {
+ case FWL_PART_PTB_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_PTB_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fwl/src/theme/pushbuttontp.cpp b/xfa/src/fwl/src/theme/pushbuttontp.cpp
new file mode 100644
index 0000000000..13c5eef567
--- /dev/null
+++ b/xfa/src/fwl/src/theme/pushbuttontp.cpp
@@ -0,0 +1,165 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#define PUSHBUTTON_SIZE_Corner 2
+CFWL_PushButtonTP::CFWL_PushButtonTP()
+{
+ m_pThemeData = FX_NEW PBThemeData;
+ SetThemeData(0);
+}
+CFWL_PushButtonTP::~CFWL_PushButtonTP()
+{
+ if (m_pThemeData) {
+ delete m_pThemeData;
+ }
+}
+FX_BOOL CFWL_PushButtonTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ return pWidget->GetClassID() == FWL_CLASSHASH_PushButton;
+}
+FX_DWORD CFWL_PushButtonTP::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ SetThemeData(FWL_GetThemeColor(dwThemeID));
+ return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
+}
+FX_BOOL CFWL_PushButtonTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ switch(pParams->m_iPart) {
+ case FWL_PART_PSB_Border: {
+ DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_PSB_Edge: {
+ DrawEdge(pParams->m_pGraphics, pParams->m_pWidget->GetStyles(), &pParams->m_rtPart, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_PSB_Background: {
+ CFX_RectF &rect = pParams->m_rtPart;
+ FX_FLOAT fRight = rect.right();
+ FX_FLOAT fBottom = rect.bottom();
+ CFX_Path strokePath;
+ strokePath.Create();
+ strokePath.MoveTo(rect.left + PUSHBUTTON_SIZE_Corner, rect.top);
+ strokePath.LineTo(fRight - PUSHBUTTON_SIZE_Corner, rect.top);
+ strokePath.LineTo(fRight, rect.top + PUSHBUTTON_SIZE_Corner);
+ strokePath.LineTo(fRight, fBottom - PUSHBUTTON_SIZE_Corner);
+ strokePath.LineTo(fRight - PUSHBUTTON_SIZE_Corner, fBottom);
+ strokePath.LineTo(rect.left + PUSHBUTTON_SIZE_Corner, fBottom);
+ strokePath.LineTo(rect.left, fBottom - PUSHBUTTON_SIZE_Corner);
+ strokePath.LineTo(rect.left, rect.top + PUSHBUTTON_SIZE_Corner);
+ strokePath.LineTo(rect.left + PUSHBUTTON_SIZE_Corner, rect.top);
+ CFX_Path fillPath;
+ fillPath.Create();
+ fillPath.AddSubpath(&strokePath);
+ CFX_Graphics *pGraphics = pParams->m_pGraphics;
+ pGraphics->SaveGraphState();
+ CFX_RectF rtInner(rect);
+ rtInner.Deflate(PUSHBUTTON_SIZE_Corner + 1,
+ PUSHBUTTON_SIZE_Corner + 1,
+ PUSHBUTTON_SIZE_Corner,
+ PUSHBUTTON_SIZE_Corner);
+ fillPath.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
+ FX_INT32 iColor = GetColorID(pParams->m_dwStates);
+ DrawAxialShading(pGraphics,
+ rect.left + PUSHBUTTON_SIZE_Corner,
+ rect.top,
+ rect.left + PUSHBUTTON_SIZE_Corner,
+ rect.bottom(),
+ m_pThemeData->clrStart[iColor],
+ m_pThemeData->clrEnd[iColor],
+ &fillPath,
+ FXFILL_ALTERNATE,
+ &pParams->m_matrix);
+ CFX_Color crStroke(m_pThemeData->clrBorder[iColor]);
+ pGraphics->SetStrokeColor(&crStroke);
+ pGraphics->StrokePath(&strokePath, &pParams->m_matrix);
+ fillPath.Clear();
+ fillPath.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
+ CFX_Color crFill(m_pThemeData->clrFill[iColor]);
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&fillPath, FXFILL_WINDING, &pParams->m_matrix);
+ if (pParams->m_dwStates & FWL_PARTSTATE_PSB_Focused) {
+ rtInner.Inflate(1, 1, 0, 0);
+ DrawFocus(pGraphics, &rtInner, &pParams->m_matrix);
+ }
+ pGraphics->RestoreGraphState();
+ break;
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
+FX_LPVOID CFWL_PushButtonTP::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ if (dwCapacity == FWL_WGTCAPACITY_PSB_Margin) {
+ m_fValue = 0;
+ return &m_fValue;
+ }
+ return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
+}
+FWL_ERR CFWL_PushButtonTP::Initialize()
+{
+ InitTTO();
+ return CFWL_WidgetTP::Initialize();
+}
+FWL_ERR CFWL_PushButtonTP::Finalize()
+{
+ FinalizeTTO();
+ return CFWL_WidgetTP::Finalize();
+}
+void CFWL_PushButtonTP::SetThemeData(FX_DWORD dwID)
+{
+ FX_ARGB *pData = (FX_ARGB*)&*m_pThemeData;
+ if (dwID) {
+ m_pThemeData->clrBorder[0] = ArgbEncode(255, 55, 98, 6);
+ m_pThemeData->clrBorder[1] = ArgbEncode(255, 55, 98, 6);
+ m_pThemeData->clrBorder[2] = ArgbEncode(255, 55, 98, 6);
+ m_pThemeData->clrBorder[3] = ArgbEncode(255, 55, 98, 6);
+ m_pThemeData->clrBorder[4] = ArgbEncode(255, 172, 168, 153);
+ m_pThemeData->clrStart[0] = ArgbEncode(255, 255, 255, 246);
+ m_pThemeData->clrStart[1] = ArgbEncode(255, 223, 205, 180);
+ m_pThemeData->clrStart[2] = ArgbEncode(255, 252, 197, 149);
+ m_pThemeData->clrStart[3] = ArgbEncode(255, 194, 209, 143);
+ m_pThemeData->clrStart[4] = ArgbEncode(255, 216, 216, 216);
+ m_pThemeData->clrEnd[0] = ArgbEncode(255, 227, 209, 184);
+ m_pThemeData->clrEnd[1] = ArgbEncode(255, 248, 244, 228);
+ m_pThemeData->clrEnd[2] = ArgbEncode(255, 207, 114, 37);
+ m_pThemeData->clrEnd[3] = ArgbEncode(255, 144, 193, 84);
+ m_pThemeData->clrEnd[4] = ArgbEncode(255, 172, 168, 153);
+ m_pThemeData->clrFill[0] = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrFill[1] = ArgbEncode(255, 226, 225, 218);
+ m_pThemeData->clrFill[2] = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrFill[3] = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrFill[4] = ArgbEncode(255, 245, 244, 234);
+ } else {
+ m_pThemeData->clrBorder[0] = ArgbEncode(255, 0, 60, 116);
+ m_pThemeData->clrBorder[1] = ArgbEncode(255, 0, 60, 116);
+ m_pThemeData->clrBorder[2] = ArgbEncode(255, 0, 60, 116);
+ m_pThemeData->clrBorder[3] = ArgbEncode(255, 0, 60, 116);
+ m_pThemeData->clrBorder[4] = ArgbEncode(255, 201, 199, 186);
+ m_pThemeData->clrStart[0] = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrStart[1] = ArgbEncode(255, 209, 204, 193);
+ m_pThemeData->clrStart[2] = ArgbEncode(255, 255, 240, 207);
+ m_pThemeData->clrStart[3] = ArgbEncode(255, 206, 231, 255);
+ m_pThemeData->clrStart[4] = ArgbEncode(255, 245, 244, 234);
+ m_pThemeData->clrEnd[0] = ArgbEncode(255, 214, 208, 197);
+ m_pThemeData->clrEnd[1] = ArgbEncode(255, 242, 241, 238);
+ m_pThemeData->clrEnd[2] = ArgbEncode(255, 229, 151, 0);
+ m_pThemeData->clrEnd[3] = ArgbEncode(255, 105, 130, 238);
+ m_pThemeData->clrEnd[4] = ArgbEncode(255, 245, 244, 234);
+ m_pThemeData->clrFill[0] = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrFill[1] = ArgbEncode(255, 226, 225, 218);
+ m_pThemeData->clrFill[2] = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrFill[3] = ArgbEncode(255, 255, 255, 255);
+ m_pThemeData->clrFill[4] = ArgbEncode(255, 245, 244, 234);
+ }
+}
+FX_INT32 CFWL_PushButtonTP::GetColorID(FX_DWORD dwStates)
+{
+ return dwStates &= FWL_PARTSTATE_PSB_Mask;
+}
diff --git a/xfa/src/fwl/src/theme/scrollbartp.cpp b/xfa/src/fwl/src/theme/scrollbartp.cpp
new file mode 100644
index 0000000000..a90dafa17e
--- /dev/null
+++ b/xfa/src/fwl/src/theme/scrollbartp.cpp
@@ -0,0 +1,362 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#define FWL_SCROLL_PawLen 12.5f
+CFWL_ScrollBarTP::CFWL_ScrollBarTP()
+{
+ m_pThemeData = FX_NEW SBThemeData;
+ SetThemeData(0);
+}
+CFWL_ScrollBarTP::~CFWL_ScrollBarTP()
+{
+ if (m_pThemeData) {
+ delete m_pThemeData;
+ m_pThemeData = NULL;
+ }
+}
+FX_BOOL CFWL_ScrollBarTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FALSE);
+ return pWidget->GetClassID() == FWL_CLASSHASH_ScrollBar;
+}
+FX_LPVOID CFWL_ScrollBarTP::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ if (dwCapacity == FWL_CAPACITY_SCB_Size) {
+ m_fValue = 5;
+ return &m_fValue;
+ }
+ return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
+}
+FX_DWORD CFWL_ScrollBarTP::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ if (m_pThemeData) {
+ SetThemeData(FWL_GetThemeColor(dwThemeID));
+ }
+ return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
+}
+FX_BOOL CFWL_ScrollBarTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ IFWL_Widget *pWidget = pParams->m_pWidget;
+ FX_DWORD dwStyleEx = pWidget->GetStylesEx();
+ FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
+ switch (pParams->m_dwStates & 0x03) {
+ case FWL_PARTSTATE_SCB_Hovered: {
+ eState = FWLTHEME_STATE_Hover;
+ break;
+ }
+ case FWL_PARTSTATE_SCB_Pressed: {
+ eState = FWLTHEME_STATE_Pressed;
+ break;
+ }
+ case FWL_PARTSTATE_SCB_Disabled: {
+ eState = FWLTHEME_STATE_Disabale;
+ break;
+ }
+ }
+ CFX_Graphics *pGraphics = pParams->m_pGraphics;
+ CFX_RectF *pRect = &pParams->m_rtPart;
+ FX_BOOL bVert = pWidget->GetStylesEx();
+ switch (pParams->m_iPart) {
+ case FWL_PART_SCB_ForeArrow: {
+ DrawMaxMinBtn(pGraphics, pRect, bVert ? FWLTHEME_DIRECTION_Up : FWLTHEME_DIRECTION_Left, eState, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_SCB_BackArrow: {
+ DrawMaxMinBtn(pGraphics, pRect, bVert ? FWLTHEME_DIRECTION_Down : FWLTHEME_DIRECTION_Right, eState, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_SCB_Thumb: {
+ DrawThumbBtn(pGraphics, pRect, bVert, eState, TRUE, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_SCB_LowerTrack: {
+ DrawTrack(pGraphics, pRect, bVert, eState, TRUE, &pParams->m_matrix);
+ break;
+ }
+ case FWL_PART_SCB_UpperTrack: {
+ DrawTrack(pGraphics, pRect, bVert, eState, FALSE, &pParams->m_matrix);
+ break;
+ }
+ default: {
+ }
+ }
+ return TRUE;
+}
+#ifdef THEME_XPSimilar
+void CFWL_ScrollBarTP::DrawThumbBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, FX_BOOL bPawButton, CFX_Matrix *pMatrix )
+{
+ if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disabale) {
+ return;
+ }
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rect(*pRect);
+ if (bVert) {
+ rect.Deflate(1, 0);
+ if (rect.IsEmpty(0.1f)) {
+ return;
+ }
+ path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
+ DrawAxialShading(pGraphics,
+ rect.left,
+ rect.top,
+ rect.right(),
+ rect.top,
+ m_pThemeData->clrBtnBK[eState - 1][0],
+ m_pThemeData->clrBtnBK[eState - 1][1],
+ &path,
+ FXFILL_WINDING,
+ pMatrix);
+ CFX_Color rcStroke;
+ rcStroke.Set(m_pThemeData->clrBtnBorder[eState - 1]);
+ pGraphics->SaveGraphState();
+ pGraphics->SetStrokeColor(&rcStroke);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+ } else {
+ rect.Deflate(0, 1);
+ if (rect.IsEmpty(0.1f)) {
+ return;
+ }
+ path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
+ DrawAxialShading(pGraphics,
+ rect.left,
+ rect.top,
+ rect.left,
+ rect.bottom(),
+ m_pThemeData->clrBtnBK[eState - 1][0],
+ m_pThemeData->clrBtnBK[eState - 1][1],
+ &path,
+ FXFILL_WINDING,
+ pMatrix);
+ CFX_Color rcStroke;
+ rcStroke.Set(m_pThemeData->clrBtnBorder[eState - 1]);
+ pGraphics->SaveGraphState();
+ pGraphics->SetStrokeColor(&rcStroke);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+ }
+}
+void CFWL_ScrollBarTP::DrawPaw(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, CFX_Matrix *pMatrix )
+{
+ CFX_Path path;
+ path.Create();
+ if (bVert) {
+ FX_FLOAT fPawLen = FWL_SCROLL_PawLen;
+ if (pRect->width / 2 <= fPawLen) {
+ fPawLen = (pRect->width - 6) / 2 ;
+ }
+ FX_FLOAT fX = pRect->left + pRect->width / 4;
+ FX_FLOAT fY = pRect->top + pRect->height / 2;
+ path.MoveTo(fX, fY - 4);
+ path.LineTo(fX + fPawLen, fY - 4);
+ path.MoveTo(fX, fY - 2);
+ path.LineTo(fX + fPawLen, fY - 2);
+ path.MoveTo(fX , fY);
+ path.LineTo(fX + fPawLen, fY);
+ path.MoveTo(fX, fY + 2);
+ path.LineTo(fX + fPawLen, fY + 2);
+ CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]);
+ pGraphics->SetLineWidth(1);
+ pGraphics->SetStrokeColor(&clrLight);
+ pGraphics->StrokePath(&path);
+ fX++;
+ path.Clear();
+ path.MoveTo(fX, fY - 3);
+ path.LineTo(fX + fPawLen, fY - 3);
+ path.MoveTo(fX, fY - 1);
+ path.LineTo(fX + fPawLen, fY - 1);
+ path.MoveTo(fX, fY + 1);
+ path.LineTo(fX + fPawLen, fY + 1);
+ path.MoveTo(fX, fY + 3);
+ path.LineTo(fX + fPawLen, fY + 3);
+ CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]);
+ pGraphics->SetLineWidth(1);
+ pGraphics->SetStrokeColor(&clrDark);
+ pGraphics->StrokePath(&path, pMatrix);
+ } else {
+ FX_FLOAT fPawLen = FWL_SCROLL_PawLen;
+ if (pRect->height / 2 <= fPawLen) {
+ fPawLen = (pRect->height - 6) / 2;
+ }
+ FX_FLOAT fX = pRect->left + pRect->width / 2;
+ FX_FLOAT fY = pRect->top + pRect->height / 4;
+ path.MoveTo(fX - 4, fY);
+ path.LineTo(fX - 4, fY + fPawLen);
+ path.MoveTo(fX - 2, fY);
+ path.LineTo(fX - 2, fY + fPawLen);
+ path.MoveTo(fX, fY);
+ path.LineTo(fX, fY + fPawLen);
+ path.MoveTo(fX + 2, fY);
+ path.LineTo(fX + 2, fY + fPawLen);
+ CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]);
+ pGraphics->SetLineWidth(1);
+ pGraphics->SetStrokeColor(&clrLight);
+ pGraphics->StrokePath(&path, pMatrix);
+ fY ++;
+ path.Clear();
+ path.MoveTo(fX - 3, fY);
+ path.LineTo(fX - 3, fY + fPawLen);
+ path.MoveTo(fX - 1, fY);
+ path.LineTo(fX - 1, fY + fPawLen);
+ path.MoveTo(fX + 1, fY);
+ path.LineTo(fX + 1, fY + fPawLen);
+ path.MoveTo(fX + 3, fY);
+ path.LineTo(fX + 3, fY + fPawLen);
+ CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]);
+ pGraphics->SetLineWidth(1);
+ pGraphics->SetStrokeColor(&clrDark);
+ pGraphics->StrokePath(&path, pMatrix);
+ }
+}
+void CFWL_ScrollBarTP::DrawTrack(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, FX_BOOL bLowerTrack, CFX_Matrix *pMatrix )
+{
+ if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disabale) {
+ return;
+ }
+ pGraphics->SaveGraphState();
+ CFX_Color colorLine(ArgbEncode(255, 238, 237, 229));
+ CFX_Path path;
+ path.Create();
+ FX_FLOAT fRight = pRect->right();
+ FX_FLOAT fBottom = pRect->bottom();
+ if (bVert) {
+ path.AddRectangle(pRect->left, pRect->top, 1, pRect->height);
+ path.AddRectangle(fRight - 1, pRect->top, 1, pRect->height);
+ } else {
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, 1);
+ path.AddRectangle(pRect->left, fBottom - 1, pRect->width, 1);
+ }
+ pGraphics->SetFillColor(&colorLine);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(pRect->left + 1, pRect->top, pRect->width - 2, pRect->height);
+ FX_FLOAT x1 = bVert ? pRect->left + 1 : pRect->left;
+ FX_FLOAT y1 = bVert ? pRect->top : pRect->top + 1;
+ FX_FLOAT x2 = bVert ? fRight - 1 : pRect->left;
+ FX_FLOAT y2 = bVert ? pRect->top : fBottom - 1;
+ pGraphics->RestoreGraphState();
+ DrawAxialShading(pGraphics,
+ x1, y1, x2, y2,
+ m_pThemeData->clrTrackBKStart,
+ m_pThemeData->clrTrackBKEnd,
+ &path,
+ FXFILL_WINDING,
+ pMatrix);
+}
+void CFWL_ScrollBarTP::DrawMaxMinBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FWLTHEME_STATE eState, CFX_Matrix *pMatrix )
+{
+ DrawTrack(pGraphics,
+ pRect,
+ eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down,
+ eState,
+ TRUE,
+ pMatrix);
+ CFX_RectF rtArrowBtn(*pRect);
+ rtArrowBtn.Deflate(1, 1, 1, 1);
+ DrawArrowBtn(pGraphics, &rtArrowBtn, eDict, eState, pMatrix);
+}
+#else
+void CFWL_ScrollBarTP::DrawThumbBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, FX_BOOL bPawButton, CFX_Matrix *pMatrix )
+{
+ if (pRect->IsEmpty()) {
+ return;
+ }
+ CFX_RectF rtThumb(*pRect);
+ FX_FLOAT fWidth = 2;
+ Draw3DRect(pGraphics, FWLTHEME_EDGE_Raised, fWidth, pRect, FWLTHEME_COLOR_EDGELT1, FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1, FWLTHEME_COLOR_EDGERB2, pMatrix);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left + fWidth, pRect->top + fWidth, pRect->width - 2 * fWidth, pRect->height - 2 * fWidth);
+ pGraphics->SaveGraphState();
+ CFX_Color crFill(FWLTHEME_COLOR_Background);
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_ScrollBarTP::DrawTrack(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FX_BOOL bVert, FWLTHEME_STATE eState, FX_BOOL bLowerTrack, CFX_Matrix *pMatrix )
+{
+ if (pRect->IsEmpty()) {
+ return;
+ }
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
+ pGraphics->SaveGraphState();
+ CFX_Color clrFill(0xFFF0F0F0);
+ pGraphics->SetFillColor(&clrFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_ScrollBarTP::DrawMaxMinBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FWLTHEME_STATE eState, CFX_Matrix *pMatrix )
+{
+ CFX_RectF rtThumb(*pRect);
+ FX_FLOAT fWidth = eState == FWLTHEME_STATE_Pressed ? 1.0f : 2.0f;
+ FWLTHEME_EDGE eType = eState == FWLTHEME_STATE_Pressed ? FWLTHEME_EDGE_Flat : FWLTHEME_EDGE_Raised;
+ Draw3DRect(pGraphics, eType, fWidth, pRect, FWLTHEME_COLOR_EDGELT1, FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1, FWLTHEME_COLOR_EDGERB2, pMatrix);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left + fWidth, pRect->top + fWidth, pRect->width - 2 * fWidth, pRect->height - 2 * fWidth);
+ pGraphics->SaveGraphState();
+ CFX_Color crFill(FWLTHEME_COLOR_Background);
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+ DrawArrow(pGraphics,
+ pRect,
+ eDict,
+ eState == FWLTHEME_STATE_Disabale ? 0xFFA0A0A0 : 0xFF000000,
+ eState == FWLTHEME_STATE_Pressed,
+ pMatrix);
+}
+#endif
+void CFWL_ScrollBarTP::SetThemeData(FX_DWORD dwID)
+{
+ m_pThemeData->clrPawColorLight[3] = ArgbEncode(0xff, 208, 223, 172);
+ m_pThemeData->clrPawColorDark[3] = ArgbEncode(0xff, 140, 157, 115);
+ m_pThemeData->clrBtnBK[3][0] = ArgbEncode(0xff, 164, 180, 139);
+ m_pThemeData->clrBtnBK[3][1] = ArgbEncode(0xff, 141, 157, 115);
+ m_pThemeData->clrBtnBorder[3] = ArgbEncode(0xff, 236, 233, 216);
+ if (dwID) {
+ m_pThemeData->clrPawColorLight[0] = ArgbEncode(0xff, 208, 223, 172);
+ m_pThemeData->clrPawColorDark[0] = ArgbEncode(0xff, 140, 157, 115);
+ m_pThemeData->clrBtnBK[0][0] = ArgbEncode(0xff, 162, 179, 141);
+ m_pThemeData->clrBtnBK[0][1] = ArgbEncode(0xff, 149, 167, 117);
+ m_pThemeData->clrBtnBorder[0] = ArgbEncode(0xff, 142, 153, 125);
+ m_pThemeData->clrPawColorLight[1] = ArgbEncode(0xff, 235, 245, 212);
+ m_pThemeData->clrPawColorDark[1] = ArgbEncode(0xff, 182, 198, 142);
+ m_pThemeData->clrBtnBK[1][0] = ArgbEncode(0xff, 200, 213, 170);
+ m_pThemeData->clrBtnBK[1][1] = ArgbEncode(0xff, 195, 208, 150);
+ m_pThemeData->clrBtnBorder[1] = ArgbEncode(0xff, 189, 203, 150);
+ m_pThemeData->clrPawColorLight[2] = ArgbEncode(0xff, 208, 223, 172);
+ m_pThemeData->clrPawColorDark[2] = ArgbEncode(0xff, 140, 157, 115);
+ m_pThemeData->clrBtnBK[2][0] = ArgbEncode(0xff, 164, 180, 139);
+ m_pThemeData->clrBtnBK[2][1] = ArgbEncode(0xff, 141, 157, 115);
+ m_pThemeData->clrBtnBorder[2] = ArgbEncode(0xff, 128, 146, 102);
+ m_pThemeData->clrTrackBKStart = ArgbEncode(0xff, 243, 241, 236);
+ m_pThemeData->clrTrackBKEnd = ArgbEncode(0xff, 254, 254, 251);
+ } else {
+ m_pThemeData->clrPawColorLight[0] = ArgbEncode(0xff, 238, 244, 254);
+ m_pThemeData->clrPawColorDark[0] = ArgbEncode(0xff, 140, 176, 248);
+ m_pThemeData->clrBtnBK[0][0] = ArgbEncode(0xff, 197, 213, 252);
+ m_pThemeData->clrBtnBK[0][1] = ArgbEncode(0xff, 182, 205, 251);
+ m_pThemeData->clrBtnBorder[0] = ArgbEncode(0xff, 148, 176, 221);
+ m_pThemeData->clrPawColorLight[1] = ArgbEncode(0xff, 252, 253, 255);
+ m_pThemeData->clrPawColorDark[1] = ArgbEncode(0xff, 156, 197, 255);
+ m_pThemeData->clrBtnBK[1][0] = ArgbEncode(0xff, 216, 232, 255);
+ m_pThemeData->clrBtnBK[1][1] = ArgbEncode(0xff, 204, 225, 255);
+ m_pThemeData->clrBtnBorder[1] = ArgbEncode(0xff, 218, 230, 254);
+ m_pThemeData->clrPawColorLight[2] = ArgbEncode(0xff, 207, 221, 253);
+ m_pThemeData->clrPawColorDark[2] = ArgbEncode(0xff, 131, 158, 216);
+ m_pThemeData->clrBtnBK[2][0] = ArgbEncode(0xff, 167, 190, 245);
+ m_pThemeData->clrBtnBK[2][1] = ArgbEncode(0xff, 146, 179, 249);
+ m_pThemeData->clrBtnBorder[2] = ArgbEncode(0xff, 124, 159, 211);
+ m_pThemeData->clrTrackBKStart = ArgbEncode(0xff, 243, 241, 236);
+ m_pThemeData->clrTrackBKEnd = ArgbEncode(0xff, 254, 254, 251);
+ }
+}
diff --git a/xfa/src/fwl/src/theme/widgettp.cpp b/xfa/src/fwl/src/theme/widgettp.cpp
new file mode 100644
index 0000000000..5e186b74ab
--- /dev/null
+++ b/xfa/src/fwl/src/theme/widgettp.cpp
@@ -0,0 +1,827 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+static void FWL_SetChildThemeID(IFWL_Widget *pParent, FX_DWORD dwThemeID)
+{
+ IFWL_WidgetMgr *pWidgetMgr = FWL_GetWidgetMgr();
+ IFWL_Widget *pChild = pWidgetMgr->GetWidget(pParent, FWL_WGTRELATION_FirstChild);
+ while (pChild) {
+ IFWL_ThemeProvider *pTheme = pChild->GetThemeProvider();
+ if (pTheme) {
+ pTheme->SetThemeID(pChild, dwThemeID, FALSE);
+ }
+ FWL_SetChildThemeID(pChild, dwThemeID);
+ pChild = pWidgetMgr->GetWidget(pChild, FWL_WGTRELATION_NextSibling);
+ }
+}
+FX_BOOL CFWL_WidgetTP::IsValidWidget(IFWL_Widget *pWidget)
+{
+ return FALSE;
+}
+FX_DWORD CFWL_WidgetTP::GetThemeID(IFWL_Widget *pWidget)
+{
+ return m_dwThemeID;
+}
+FX_DWORD CFWL_WidgetTP::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ FX_DWORD dwOld = m_dwThemeID;
+ m_dwThemeID = dwThemeID;
+ if (CFWL_ArrowData::IsInstance()) {
+ CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(dwThemeID));
+ }
+ if (bChildren) {
+ FWL_SetChildThemeID(pWidget, dwThemeID);
+ }
+ return dwOld;
+}
+FWL_ERR CFWL_WidgetTP::GetThemeMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix)
+{
+ matrix.Set(_ctm.a, _ctm.b, _ctm.c, _ctm.d, _ctm.e, _ctm.f);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetTP::SetThemeMatrix(IFWL_Widget *pWidget, const CFX_Matrix &matrix)
+{
+ _ctm.Set(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_WidgetTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetTP::DrawText(CFWL_ThemeText *pParams)
+{
+ if (!m_pTextOut) {
+ InitTTO();
+ }
+ FX_INT32 iLen = pParams->m_wsText.GetLength();
+ _FWL_RETURN_VALUE_IF_FAIL(iLen > 0, FALSE)
+ CFX_Graphics *pGraphics = pParams->m_pGraphics;
+ m_pTextOut->SetRenderDevice(pGraphics->GetRenderDevice());
+ m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+ m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+ CFX_Matrix *pMatrix = &pParams->m_matrix;
+ pMatrix->Concat(*pGraphics->GetMatrix());
+ m_pTextOut->SetMatrix(*pMatrix);
+ m_pTextOut->DrawLogicText(pParams->m_wsText, iLen, pParams->m_rtPart);
+ return TRUE;
+}
+FX_LPVOID CFWL_WidgetTP::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ switch(dwCapacity) {
+ case FWL_WGTCAPACITY_CXBorder: {
+ m_fValue = FWLTHEME_CAPACITY_CXBorder;
+ break;
+ }
+ case FWL_WGTCAPACITY_CYBorder: {
+ m_fValue = FWLTHEME_CAPACITY_CYBorder;
+ break;
+ }
+ case FWL_WGTCAPACITY_EdgeFlat: {
+ m_fValue = FWLTHEME_CAPACITY_EdgeFlat;
+ break;
+ }
+ case FWL_WGTCAPACITY_EdgeRaised: {
+ m_fValue = FWLTHEME_CAPACITY_EdgeRaised;
+ break;
+ }
+ case FWL_WGTCAPACITY_EdgeSunken: {
+ m_fValue = FWLTHEME_CAPACITY_EdgeSunken;
+ break;
+ }
+ case FWL_WGTCAPACITY_FontSize: {
+ m_fValue = FWLTHEME_CAPACITY_FontSize;
+ break;
+ }
+ case FWL_WGTCAPACITY_TextColor: {
+ m_dwValue = FWLTHEME_CAPACITY_TextColor;
+ return &m_dwValue;
+ }
+ case FWL_WGTCAPACITY_ScrollBarWidth: {
+ m_fValue = FWLTHEME_CAPACITY_ScrollBarWidth;
+ break;
+ }
+ case FWL_WGTCAPACITY_Font: {
+ return m_pFDEFont;
+ }
+ case FWL_WGTCAPACITY_TextSelColor: {
+ m_dwValue = (m_dwThemeID == 0) ? FWLTHEME_CAPACITY_TextSelColor : FWLTHEME_COLOR_Green_BKSelected;
+ return &m_dwValue;
+ }
+ case FWL_WGTCAPACITY_LineHeight: {
+ m_fValue = FWLTHEME_CAPACITY_LineHeight;
+ break;
+ }
+ case FWL_WGTCAPACITY_UIMargin: {
+ m_rtMargin.Set(0, 0, 0, 0);
+ return &m_rtMargin;
+ }
+ default: {
+ return NULL;
+ }
+ }
+ return &m_fValue;
+}
+FX_BOOL CFWL_WidgetTP::IsCustomizedLayout(IFWL_Widget *pWidget)
+{
+ return FWL_GetThemeLayout(m_dwThemeID);
+}
+FWL_ERR CFWL_WidgetTP::GetPartRect(CFWL_ThemePart *pThemePart, CFX_RectF &rect)
+{
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CFWL_WidgetTP::IsInPart(CFWL_ThemePart *pThemePart, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return TRUE;
+}
+FX_BOOL CFWL_WidgetTP::CalcTextRect(CFWL_ThemeText *pParams, CFX_RectF &rect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pTextOut, FALSE);
+ m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+ m_pTextOut->SetStyles(pParams->m_dwTTOStyles | FDE_TTOSTYLE_ArabicContext);
+ m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), rect);
+ return TRUE;
+}
+FWL_ERR CFWL_WidgetTP::Initialize()
+{
+ m_dwThemeID = 0;
+ _ctm.Reset();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetTP::Finalize()
+{
+ if(!m_pTextOut) {
+ FinalizeTTO();
+ }
+ return FWL_ERR_Succeeded;
+}
+CFWL_WidgetTP::~CFWL_WidgetTP()
+{
+}
+FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget *pWidget, FX_LPCWSTR strFont, FX_FLOAT fFontSize, FX_ARGB rgbFont)
+{
+ if (!m_pTextOut) {
+ return FWL_ERR_Succeeded;
+ }
+ m_pFDEFont = FWL_GetFontManager()->FindFont(strFont, 0, 0);
+ m_pTextOut->SetFont(m_pFDEFont);
+ m_pTextOut->SetFontSize(fFontSize);
+ m_pTextOut->SetTextColor(rgbFont);
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CFWL_WidgetTP::SetFont(IFWL_Widget *pWidget, IFX_Font *pFont, FX_FLOAT fFontSize, FX_ARGB rgbFont)
+{
+ if (!m_pTextOut) {
+ return FWL_ERR_Succeeded;
+ }
+ m_pTextOut->SetFont(pFont);
+ m_pTextOut->SetFontSize(fFontSize);
+ m_pTextOut->SetTextColor(rgbFont);
+ return FWL_ERR_Succeeded;
+}
+IFX_Font* CFWL_WidgetTP::GetFont(IFWL_Widget *pWidget)
+{
+ return m_pFDEFont;
+}
+CFWL_WidgetTP::CFWL_WidgetTP()
+ : m_dwRefCount(1)
+ , m_pTextOut(NULL)
+ , m_pFDEFont(NULL)
+ , m_dwThemeID(0)
+{
+}
+FX_ERR CFWL_WidgetTP::InitTTO()
+{
+ if (m_pTextOut) {
+ return FWL_ERR_Succeeded;
+ }
+ m_pFDEFont = FWL_GetFontManager()->FindFont(FX_WSTRC(L"Helvetica"), 0, 0);
+ m_pTextOut = IFDE_TextOut::Create();
+ m_pTextOut->SetFont(m_pFDEFont);
+ m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
+ m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
+ m_pTextOut->SetEllipsisString(L"...");
+ return FWL_ERR_Succeeded;
+}
+FX_ERR CFWL_WidgetTP::FinalizeTTO()
+{
+ if (m_pTextOut) {
+ m_pTextOut->Release();
+ m_pTextOut = NULL;
+ }
+ return FWL_ERR_Succeeded;
+}
+#ifdef THEME_XPSimilar
+void CFWL_WidgetTP::DrawEdge(CFX_Graphics *pGraphics, FX_DWORD dwStyles, const CFX_RectF *pRect, CFX_Matrix *pMatrix)
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ pGraphics->SaveGraphState();
+ CFX_Color crStroke(FWL_GetThemeColor(m_dwThemeID) == 0 ? ArgbEncode(255, 127, 157, 185) : FWLTHEME_COLOR_Green_BKSelected);
+ pGraphics->SetStrokeColor(&crStroke);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left, pRect->top, pRect->width - 1, pRect->height - 1);
+ pGraphics->StrokePath(&path, pMatrix);
+ path.Clear();
+ crStroke = ArgbEncode(255, 255, 255, 255);
+ pGraphics->SetStrokeColor(&crStroke);
+ path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 3, pRect->height - 3);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+#else
+void CFWL_WidgetTP::DrawEdge(CFX_Graphics *pGraphics, FX_DWORD dwStyles, const CFX_RectF *pRect, CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ FWLTHEME_EDGE eType;
+ FX_FLOAT fWidth;
+ switch(dwStyles & FWL_WGTSTYLE_EdgeMask) {
+ case FWL_WGTSTYLE_EdgeRaised: {
+ eType = FWLTHEME_EDGE_Raised, fWidth = FWLTHEME_CAPACITY_EdgeRaised;
+ break;
+ }
+ case FWL_WGTSTYLE_EdgeSunken: {
+ eType = FWLTHEME_EDGE_Sunken, fWidth = FWLTHEME_CAPACITY_EdgeSunken;
+ break;
+ }
+ case FWL_WGTSTYLE_EdgeFlat:
+ default: {
+ return;
+ }
+ }
+ Draw3DRect(pGraphics,
+ eType,
+ fWidth,
+ pRect,
+ FWLTHEME_COLOR_EDGELT1,
+ FWLTHEME_COLOR_EDGELT2,
+ FWLTHEME_COLOR_EDGERB1,
+ FWLTHEME_COLOR_EDGERB2,
+ pMatrix);
+}
+#endif
+void CFWL_WidgetTP::Draw3DRect(CFX_Graphics *pGraphics, FWLTHEME_EDGE eType, FX_FLOAT fWidth, const CFX_RectF *pRect, FX_ARGB cr1, FX_ARGB cr2, FX_ARGB cr3, FX_ARGB cr4, CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ pGraphics->SaveGraphState();
+ if (eType == FWLTHEME_EDGE_Flat) {
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left,
+ pRect->top,
+ pRect->width,
+ pRect->height);
+ path.AddRectangle(pRect->left + 1,
+ pRect->top + 1,
+ pRect->width - 2,
+ pRect->height - 2);
+ CFX_Color cr(ArgbEncode(255, 100, 100, 100));
+ pGraphics->SetFillColor(&cr);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ path.Clear();
+ path.AddRectangle(pRect->left + 1,
+ pRect->top + 1,
+ pRect->width - 2,
+ pRect->height - 2);
+ path.AddRectangle(pRect->left + 2,
+ pRect->top + 2,
+ pRect->width - 4,
+ pRect->height - 4);
+ cr.Set(0xFFFFFFFF);
+ pGraphics->SetFillColor(&cr);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ } else {
+ FX_FLOAT fLeft = pRect->left;
+ FX_FLOAT fRight = pRect->right();
+ FX_FLOAT fTop = pRect->top;
+ FX_FLOAT fBottom = pRect->bottom();
+ FX_FLOAT fHalfWidth = fWidth / 2.0f;
+ CFX_Color crLT(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1);
+ pGraphics->SetFillColor(&crLT);
+ CFX_Path pathLT;
+ pathLT.Create();
+ pathLT.MoveTo(fLeft, fBottom - fHalfWidth);
+ pathLT.LineTo(fLeft, fTop);
+ pathLT.LineTo(fRight - fHalfWidth, fTop);
+ pathLT.LineTo(fRight - fHalfWidth, fTop + fHalfWidth);
+ pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth);
+ pathLT.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth);
+ pathLT.LineTo(fLeft, fBottom - fHalfWidth);
+ pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
+ crLT = CFX_Color(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2);
+ pGraphics->SetFillColor(&crLT);
+ pathLT.Clear();
+ pathLT.MoveTo(fLeft + fHalfWidth, fBottom - fWidth);
+ pathLT.LineTo(fLeft + fHalfWidth, fTop + fHalfWidth);
+ pathLT.LineTo(fRight - fWidth, fTop + fHalfWidth);
+ pathLT.LineTo(fRight - fWidth, fTop + fWidth);
+ pathLT.LineTo(fLeft + fWidth, fTop + fWidth);
+ pathLT.LineTo(fLeft + fWidth, fBottom - fWidth);
+ pathLT.LineTo(fLeft + fHalfWidth, fBottom - fWidth);
+ pGraphics->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
+ CFX_Color crRB(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3);
+ pGraphics->SetFillColor(&crRB);
+ CFX_Path pathRB;
+ pathRB.Create();
+ pathRB.MoveTo(fRight - fHalfWidth, fTop + fHalfWidth);
+ pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth);
+ pathRB.LineTo(fLeft + fHalfWidth, fBottom - fHalfWidth);
+ pathRB.LineTo(fLeft + fHalfWidth, fBottom - fWidth);
+ pathRB.LineTo(fRight - fWidth, fBottom - fWidth);
+ pathRB.LineTo(fRight - fWidth, fTop + fHalfWidth);
+ pathRB.LineTo(fRight - fHalfWidth, fTop + fHalfWidth);
+ pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
+ crRB = CFX_Color(eType == FWLTHEME_EDGE_Raised
+ ? cr2 : cr4);
+ pGraphics->SetFillColor(&crRB);
+ pathRB.Clear();
+ pathRB.MoveTo(fRight, fTop);
+ pathRB.LineTo(fRight, fBottom);
+ pathRB.LineTo(fLeft, fBottom);
+ pathRB.LineTo(fLeft, fBottom - fHalfWidth);
+ pathRB.LineTo(fRight - fHalfWidth, fBottom - fHalfWidth);
+ pathRB.LineTo(fRight - fHalfWidth, fTop);
+ pathRB.LineTo(fRight, fTop);
+ pGraphics->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
+ }
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::Draw3DCircle(CFX_Graphics *pGraphics, FWLTHEME_EDGE eType, FX_FLOAT fWidth, const CFX_RectF *pRect, FX_ARGB cr1, FX_ARGB cr2, FX_ARGB cr3, FX_ARGB cr4, CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ pGraphics->SaveGraphState();
+ FX_FLOAT fRadius = pRect->width / 2;
+ CFX_Path path;
+ path.Create();
+ path.AddArc(pRect->left,
+ pRect->top,
+ pRect->width,
+ pRect->height,
+ FWLTHEME_PI * 3 / 4,
+ FWLTHEME_PI);
+ CFX_Color crFill1(eType == FWLTHEME_EDGE_Raised ? cr4 : cr1);
+ pGraphics->SetStrokeColor(&crFill1);
+ pGraphics->StrokePath(&path, pMatrix);
+ CFX_RectF rtInner(*pRect);
+ rtInner.Deflate(pRect->width / 4, pRect->height / 4);
+ path.Clear();
+ path.AddArc(rtInner.left,
+ rtInner.top,
+ rtInner.width,
+ rtInner.height,
+ FWLTHEME_PI * 3 / 4,
+ FWLTHEME_PI);
+ CFX_Color crFill2(eType == FWLTHEME_EDGE_Raised ? cr3 : cr2);
+ pGraphics->SetStrokeColor(&crFill2);
+ pGraphics->StrokePath(&path, pMatrix);
+ path.Clear();
+ path.AddArc(pRect->left,
+ pRect->top,
+ pRect->width,
+ pRect->height,
+ FWLTHEME_PI * 7 / 4,
+ FWLTHEME_PI);
+ CFX_Color crFill3(eType == FWLTHEME_EDGE_Raised ? cr1 : cr3);
+ pGraphics->SetStrokeColor(&crFill3);
+ pGraphics->StrokePath(&path, pMatrix);
+ path.AddArc(rtInner.left,
+ rtInner.top,
+ rtInner.width,
+ rtInner.height,
+ FWLTHEME_PI * 7 / 4,
+ FWLTHEME_PI);
+ CFX_Color crFill4(eType == FWLTHEME_EDGE_Raised ? cr2 : cr4);
+ pGraphics->SetStrokeColor(&crFill4);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::DrawBorder(CFX_Graphics *pGraphics, const CFX_RectF *pRect, CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
+ path.AddRectangle(pRect->left + 1, pRect->top + 1, pRect->width - 2, pRect->height - 2);
+ pGraphics->SaveGraphState();
+ CFX_Color crFill(ArgbEncode(255, 0, 0, 0));
+ pGraphics->SetFillColor(&crFill);
+ pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::FillBackground(CFX_Graphics *pGraphics, const CFX_RectF *pRect, CFX_Matrix *pMatrix )
+{
+ FillSoildRect(pGraphics, FWLTHEME_COLOR_Background, pRect, pMatrix);
+}
+void CFWL_WidgetTP::FillSoildRect(CFX_Graphics *pGraphics, FX_ARGB fillColor, const CFX_RectF *pRect, CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ pGraphics->SaveGraphState();
+ CFX_Color crFill(fillColor);
+ pGraphics->SetFillColor(&crFill);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::DrawAxialShading(CFX_Graphics *pGraphics, FX_FLOAT fx1, FX_FLOAT fy1, FX_FLOAT fx2, FX_FLOAT fy2, FX_ARGB beginColor, FX_ARGB endColor, CFX_Path *path, FX_INT32 fillMode, CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(path);
+ CFX_PointF begPoint, endPoint;
+ begPoint.Set(fx1, fy1);
+ endPoint.Set(fx2, fy2);
+ CFX_Shading shading;
+ shading.CreateAxial(begPoint, endPoint, FALSE, FALSE, beginColor, endColor);
+ pGraphics->SaveGraphState();
+ CFX_Color color1(&shading);
+ pGraphics->SetFillColor(&color1);
+ pGraphics->FillPath(path, fillMode, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::DrawAnnulusRect(CFX_Graphics *pGraphics, FX_ARGB fillColor, const CFX_RectF *pRect, FX_FLOAT fRingWidth , CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ pGraphics->SaveGraphState();
+ CFX_Color cr(fillColor);
+ pGraphics->SetFillColor(&cr);
+ CFX_Path path;
+ path.Create();
+ FX_FLOAT fRight = pRect->right();
+ FX_FLOAT fBottom = pRect->bottom();
+ CFX_RectF rtInner(*pRect);
+ rtInner.Deflate(fRingWidth, fRingWidth);
+ path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
+ pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::DrawAnnulusCircle(CFX_Graphics *pGraphics, FX_ARGB fillColor, const CFX_RectF *pRect, FX_FLOAT fWidth , CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ if (fWidth > pRect->width / 2) {
+ return;
+ }
+ pGraphics->SaveGraphState();
+ CFX_Color cr(fillColor);
+ pGraphics->SetFillColor(&cr);
+ CFX_Path path;
+ path.Create();
+ path.AddEllipse(*pRect);
+ CFX_RectF rtIn(*pRect);
+ rtIn.Inflate(-fWidth, -fWidth);
+ path.AddEllipse(rtIn);
+ pGraphics->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::DrawFocus(CFX_Graphics *pGraphics, const CFX_RectF *pRect, CFX_Matrix *pMatrix )
+{
+ _FWL_RETURN_IF_FAIL(pGraphics);
+ _FWL_RETURN_IF_FAIL(pRect);
+ pGraphics->SaveGraphState();
+ CFX_Color cr(0xFF000000);
+ pGraphics->SetStrokeColor(&cr);
+ FX_FLOAT DashPattern[2] = {1, 1};
+ pGraphics->SetLineDash(0.0f, DashPattern, 2);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
+ pGraphics->StrokePath(&path, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+#define FWLTHEME_ARROW_Denominator 3
+void CFWL_WidgetTP::DrawArrow(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FX_ARGB argbFill, FX_BOOL bPressed, CFX_Matrix *pMatrix )
+{
+ CFX_RectF rtArrow(*pRect);
+ CFX_Path path;
+ path.Create();
+ FX_FLOAT fBtn = FX_MIN(pRect->width, pRect->height) / FWLTHEME_ARROW_Denominator;
+ rtArrow.left = pRect->left + (pRect->width - fBtn) / 2;
+ rtArrow.top = pRect->top + (pRect->height - fBtn) / 2;
+ rtArrow.width = fBtn;
+ rtArrow.height = fBtn;
+ if (bPressed) {
+ rtArrow.Offset(1, 1);
+ }
+ switch (eDict) {
+ case FWLTHEME_DIRECTION_Up: {
+ path.MoveTo(rtArrow.left, rtArrow.bottom());
+ path.LineTo(rtArrow.right(), rtArrow.bottom());
+ path.LineTo(rtArrow.left + fBtn / 2, rtArrow.top);
+ path.LineTo(rtArrow.left, rtArrow.bottom());
+ break;
+ }
+ case FWLTHEME_DIRECTION_Left: {
+ path.MoveTo(rtArrow.right(), rtArrow.top);
+ path.LineTo(rtArrow.right(), rtArrow.bottom());
+ path.LineTo(rtArrow.left, rtArrow.top + fBtn / 2);
+ path.LineTo(rtArrow.right(), rtArrow.top);
+ break ;
+ }
+ case FWLTHEME_DIRECTION_Right: {
+ path.MoveTo(rtArrow.left, rtArrow.top);
+ path.LineTo(rtArrow.left, rtArrow.bottom());
+ path.LineTo(rtArrow.right(), rtArrow.top + fBtn / 2);
+ path.LineTo(rtArrow.left, rtArrow.top);
+ break;
+ }
+ case FWLTHEME_DIRECTION_Down:
+ default: {
+ path.MoveTo(rtArrow.left, rtArrow.top);
+ path.LineTo(rtArrow.right(), rtArrow.top);
+ path.LineTo(rtArrow.left + fBtn / 2, rtArrow.bottom());
+ path.LineTo(rtArrow.left, rtArrow.top);
+ }
+ }
+ pGraphics->SaveGraphState();
+ CFX_Color cr(argbFill);
+ pGraphics->SetFillColor(&cr);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+ pGraphics->RestoreGraphState();
+}
+void CFWL_WidgetTP::DrawArrow(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FX_ARGB argSign, CFX_Matrix *pMatrix )
+{
+ CFX_RectF rtArrow(*pRect);
+ FX_BOOL bVert = (eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down);
+ FX_FLOAT fLeft = (FX_FLOAT)(((pRect->width - (bVert ? 9 : 6)) / 2 + pRect->left) + 0.5);
+ FX_FLOAT fTop = (FX_FLOAT)(((pRect->height - (bVert ? 6 : 9)) / 2 + pRect->top) + 0.5);
+ CFX_Path path;
+ path.Create();
+ switch (eDict) {
+ case FWLTHEME_DIRECTION_Down: {
+ path.MoveTo(fLeft, fTop + 1);
+ path.LineTo(fLeft + 4, fTop + 5);
+ path.LineTo(fLeft + 8, fTop + 1);
+ path.LineTo(fLeft + 7, fTop);
+ path.LineTo(fLeft + 4, fTop + 3);
+ path.LineTo(fLeft + 1, fTop);
+ break;
+ }
+ case FWLTHEME_DIRECTION_Up: {
+ path.MoveTo(fLeft, fTop + 4);
+ path.LineTo(fLeft + 4, fTop);
+ path.LineTo(fLeft + 8, fTop + 4);
+ path.LineTo(fLeft + 7, fTop + 5);
+ path.LineTo(fLeft + 4, fTop + 2);
+ path.LineTo(fLeft + 1, fTop + 5);
+ break;
+ }
+ case FWLTHEME_DIRECTION_Right: {
+ path.MoveTo(fLeft + 1, fTop);
+ path.LineTo(fLeft + 5, fTop + 4);
+ path.LineTo(fLeft + 1, fTop + 8);
+ path.LineTo(fLeft, fTop + 7);
+ path.LineTo(fLeft + 3, fTop + 4);
+ path.LineTo(fLeft, fTop + 1);
+ break;
+ }
+ case FWLTHEME_DIRECTION_Left: {
+ path.MoveTo(fLeft, fTop + 4);
+ path.LineTo(fLeft + 4, fTop);
+ path.LineTo(fLeft + 5, fTop + 1);
+ path.LineTo(fLeft + 2, fTop + 4);
+ path.LineTo(fLeft + 5, fTop + 7);
+ path.LineTo(fLeft + 4, fTop + 8);
+ break;
+ }
+ }
+ CFX_Color cr(argSign);
+ pGraphics->SetFillColor(&cr);
+ pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
+}
+void CFWL_WidgetTP::DrawBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_STATE eState, CFX_Matrix *pMatrix )
+{
+ CFX_Path path;
+ path.Create();
+ if (!CFWL_ArrowData::IsInstance()) {
+ CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID));
+ }
+ CFWL_ArrowData::CColorData *pColorData = CFWL_ArrowData::GetInstance()->m_pColorData;
+ FX_FLOAT fRight = pRect->right();
+ FX_FLOAT fBottom = pRect->bottom();
+ path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
+ DrawAxialShading(pGraphics,
+ pRect->left,
+ pRect->top,
+ fRight,
+ fBottom,
+ pColorData->clrStart[eState - 1],
+ pColorData->clrEnd[eState - 1],
+ &path,
+ FXFILL_WINDING,
+ pMatrix);
+ CFX_Color rcStroke;
+ rcStroke.Set(pColorData->clrBorder[eState - 1]);
+ pGraphics->SetStrokeColor(&rcStroke);
+ pGraphics->StrokePath(&path, pMatrix);
+}
+void CFWL_WidgetTP::DrawArrowBtn(CFX_Graphics *pGraphics, const CFX_RectF *pRect, FWLTHEME_DIRECTION eDict, FWLTHEME_STATE eState, CFX_Matrix *pMatrix )
+{
+ DrawBtn(pGraphics, pRect, eState, pMatrix);
+ if (!CFWL_ArrowData::IsInstance()) {
+ CFWL_ArrowData::GetInstance()->SetColorData(FWL_GetThemeColor(m_dwThemeID));
+ }
+ CFWL_ArrowData::CColorData *pColorData = CFWL_ArrowData::GetInstance()->m_pColorData;
+ DrawArrow(pGraphics, pRect, eDict, pColorData->clrSign[eState - 1], pMatrix);
+}
+FWLCOLOR CFWL_WidgetTP::BlendColor(FWLCOLOR srcColor, FWLCOLOR renderColor, FX_BYTE scale)
+{
+ FWLCOLOR dstColor;
+ FX_BYTE n = 255 - scale;
+ dstColor.a = (FX_BYTE)(((FX_WORD)srcColor.a * n + (FX_WORD)renderColor.a * scale) >> 8);
+ dstColor.r = (FX_BYTE)(((FX_WORD)srcColor.r * n + (FX_WORD)renderColor.r * scale) >> 8);
+ dstColor.g = (FX_BYTE)(((FX_WORD)srcColor.g * n + (FX_WORD)renderColor.g * scale) >> 8);
+ dstColor.b = (FX_BYTE)(((FX_WORD)srcColor.b * n + (FX_WORD)renderColor.b * scale) >> 8);
+ return dstColor;
+}
+CFWL_ArrowData::CFWL_ArrowData()
+ : m_pColorData(NULL)
+{
+ SetColorData(0);
+}
+CFWL_FontManager *FWL_GetFontManager()
+{
+ static CFWL_FontManager * _fontManager = NULL;
+ if (_fontManager == NULL) {
+ _fontManager = FX_NEW CFWL_FontManager;
+ }
+ return _fontManager;
+}
+void FWL_ReleaseFontManager()
+{
+ CFWL_FontManager * fontManager = FWL_GetFontManager();
+ delete fontManager;
+}
+CFWL_FontData::CFWL_FontData()
+ : m_dwStyles(0)
+ , m_dwCodePage(0)
+ , m_pFont(0)
+ , m_pFontMgr(NULL)
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ , m_pFontSource(NULL)
+#endif
+{
+}
+CFWL_FontData::~CFWL_FontData()
+{
+ if (m_pFont) {
+ m_pFont->Release();
+ }
+ if (m_pFontMgr) {
+ m_pFontMgr->Release();
+ }
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if(m_pFontSource != NULL) {
+ m_pFontSource->Release();
+ }
+#endif
+}
+FX_BOOL CFWL_FontData::Equal(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ return m_wsFamily == wsFontFamily && m_dwStyles == dwFontStyles && m_dwCodePage == wCodePage;
+}
+FX_BOOL CFWL_FontData::LoadFont(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD dwCodePage)
+{
+ m_wsFamily = wsFontFamily;
+ m_dwStyles = dwFontStyles;
+ m_dwCodePage = dwCodePage;
+ if (!m_pFontMgr) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ m_pFontMgr = IFX_FontMgr::Create(FX_GetDefFontEnumerator());
+#else
+ m_pFontSource = FX_CreateDefaultFontSourceEnum();
+ m_pFontMgr = IFX_FontMgr::Create(m_pFontSource);
+#endif
+ }
+ m_pFont = IFX_Font::LoadFont(wsFontFamily.GetPtr(), dwFontStyles, dwCodePage, m_pFontMgr);
+ return m_pFont != NULL;
+}
+CFWL_FontManager::CFWL_FontManager()
+{
+}
+CFWL_FontManager::~CFWL_FontManager()
+{
+ FX_INT32 count = m_arrFonts.GetSize();
+ for (FX_INT32 i = 0; i < count; i ++) {
+ CFWL_FontData *data = (CFWL_FontData*)m_arrFonts[i];
+ delete data;
+ }
+ m_arrFonts.RemoveAll();
+}
+IFX_Font* CFWL_FontManager::FindFont(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ FX_INT32 count = m_arrFonts.GetSize();
+ for (FX_INT32 i = 0; i < count; i ++) {
+ CFWL_FontData *data = (CFWL_FontData*)m_arrFonts[i];
+ if (data->Equal(wsFontFamily, dwFontStyles, wCodePage)) {
+ return data->GetFont();
+ }
+ }
+ CFWL_FontData *fontData = FX_NEW CFWL_FontData;
+ if (!fontData->LoadFont(wsFontFamily, dwFontStyles, wCodePage)) {
+ delete fontData;
+ return NULL;
+ }
+ m_arrFonts.Add(fontData);
+ return fontData->GetFont();
+}
+FX_BOOL FWLTHEME_Init()
+{
+ return TRUE;
+}
+void FWLTHEME_Release()
+{
+ CFWL_ArrowData::DestroyInstance();
+ FWL_ReleaseFontManager();
+}
+FX_DWORD FWL_GetThemeLayout(FX_DWORD dwThemeID)
+{
+ return 0xffff0000 & dwThemeID;
+}
+FX_DWORD FWL_GetThemeColor(FX_DWORD dwThemeID)
+{
+ return 0x0000ffff & dwThemeID;
+}
+FX_DWORD FWL_MakeThemeID(FX_DWORD dwLayout, FX_DWORD dwColor)
+{
+ return (dwLayout << 16) | (0x0000FFFF & dwColor);
+}
+CFWL_ArrowData *CFWL_ArrowData::m_pInstance = NULL;
+CFWL_ArrowData* CFWL_ArrowData::GetInstance()
+{
+ if (!m_pInstance) {
+ m_pInstance = FX_NEW CFWL_ArrowData;
+ }
+ return m_pInstance;
+}
+FX_BOOL CFWL_ArrowData::IsInstance()
+{
+ return (m_pInstance != NULL);
+}
+void CFWL_ArrowData::DestroyInstance()
+{
+ if (m_pInstance) {
+ delete m_pInstance;
+ m_pInstance = NULL;
+ }
+}
+CFWL_ArrowData::~CFWL_ArrowData()
+{
+ if (m_pColorData) {
+ delete m_pColorData;
+ m_pColorData = NULL;
+ }
+}
+void CFWL_ArrowData::SetColorData(FX_DWORD dwID)
+{
+ if (!m_pColorData) {
+ m_pColorData = FX_NEW CColorData;
+ }
+ if (dwID) {
+ m_pColorData->clrBorder[0] = ArgbEncode(255, 142, 153, 125);
+ m_pColorData->clrBorder[1] = ArgbEncode(255, 157, 171, 119);
+ m_pColorData->clrBorder[2] = ArgbEncode(255, 118, 131, 97);
+ m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
+ m_pColorData->clrStart[0] = ArgbEncode(255, 203, 215, 186);
+ m_pColorData->clrStart[1] = ArgbEncode(255, 218, 232, 185);
+ m_pColorData->clrStart[2] = ArgbEncode(255, 203, 215, 186);
+ m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
+ m_pColorData->clrEnd[0] = ArgbEncode(255, 149, 167, 117);
+ m_pColorData->clrEnd[1] = ArgbEncode(255, 198, 211, 155);
+ m_pColorData->clrEnd[2] = ArgbEncode(255, 149, 167, 117);
+ m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
+ m_pColorData->clrSign[0] = ArgbEncode(255, 255, 255, 255);
+ m_pColorData->clrSign[1] = ArgbEncode(255, 255, 255, 255);
+ m_pColorData->clrSign[2] = ArgbEncode(255, 255, 255, 255);
+ m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
+ } else {
+ m_pColorData->clrBorder[0] = ArgbEncode(255, 202, 216, 249);
+ m_pColorData->clrBorder[1] = ArgbEncode(255, 171, 190, 233);
+ m_pColorData->clrBorder[2] = ArgbEncode(255, 135, 147, 219);
+ m_pColorData->clrBorder[3] = ArgbEncode(255, 172, 168, 153);
+ m_pColorData->clrStart[0] = ArgbEncode(255, 225, 234, 254);
+ m_pColorData->clrStart[1] = ArgbEncode(255, 253, 255, 255);
+ m_pColorData->clrStart[2] = ArgbEncode(255, 110, 142, 241);
+ m_pColorData->clrStart[3] = ArgbEncode(255, 254, 254, 251);
+ m_pColorData->clrEnd[0] = ArgbEncode(255, 175, 204, 251);
+ m_pColorData->clrEnd[1] = ArgbEncode(255, 185, 218, 251);
+ m_pColorData->clrEnd[2] = ArgbEncode(255, 210, 222, 235);
+ m_pColorData->clrEnd[3] = ArgbEncode(255, 243, 241, 236);
+ m_pColorData->clrSign[0] = ArgbEncode(255, 77, 97, 133);
+ m_pColorData->clrSign[1] = ArgbEncode(255, 77, 97, 133);
+ m_pColorData->clrSign[2] = ArgbEncode(255, 77, 97, 133);
+ m_pColorData->clrSign[3] = ArgbEncode(255, 128, 128, 128);
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_ASCIIEncoder.cpp b/xfa/src/fxbarcode/src/BC_ASCIIEncoder.cpp
new file mode 100644
index 0000000000..52fec37b36
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_ASCIIEncoder.cpp
@@ -0,0 +1,83 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_ASCIIEncoder.h"
+CBC_ASCIIEncoder::CBC_ASCIIEncoder()
+{
+}
+CBC_ASCIIEncoder::~CBC_ASCIIEncoder()
+{
+}
+FX_INT32 CBC_ASCIIEncoder::getEncodingMode()
+{
+ return ASCII_ENCODATION;
+}
+void CBC_ASCIIEncoder::Encode(CBC_EncoderContext &context, FX_INT32 &e)
+{
+ FX_INT32 n = CBC_HighLevelEncoder::determineConsecutiveDigitCount(context.m_msg, context.m_pos);
+ if (n >= 2) {
+ FX_WCHAR code = encodeASCIIDigits(context.m_msg.GetAt(context.m_pos), context.m_msg.GetAt(context.m_pos + 1), e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ context.writeCodeword(code);
+ context.m_pos += 2;
+ } else {
+ FX_WCHAR c = context.getCurrentChar();
+ FX_INT32 newMode = CBC_HighLevelEncoder::lookAheadTest(context.m_msg, context.m_pos, getEncodingMode());
+ if (newMode != getEncodingMode()) {
+ switch (newMode) {
+ case BASE256_ENCODATION:
+ context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_BASE256);
+ context.signalEncoderChange(BASE256_ENCODATION);
+ return;
+ case C40_ENCODATION:
+ context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_C40);
+ context.signalEncoderChange(C40_ENCODATION);
+ return;
+ case X12_ENCODATION:
+ context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_ANSIX12);
+ context.signalEncoderChange(X12_ENCODATION);
+ break;
+ case TEXT_ENCODATION:
+ context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_TEXT);
+ context.signalEncoderChange(TEXT_ENCODATION);
+ break;
+ case EDIFACT_ENCODATION:
+ context.writeCodeword(CBC_HighLevelEncoder::LATCH_TO_EDIFACT);
+ context.signalEncoderChange(EDIFACT_ENCODATION);
+ break;
+ default:
+ e = BCExceptionIllegalStateIllegalMode;
+ return;
+ }
+ } else if (CBC_HighLevelEncoder::isExtendedASCII(c)) {
+ context.writeCodeword(CBC_HighLevelEncoder::UPPER_SHIFT);
+ context.writeCodeword((FX_WCHAR) (c - 128 + 1));
+ context.m_pos++;
+ } else {
+ context.writeCodeword((FX_WCHAR) (c + 1));
+ context.m_pos++;
+ }
+ }
+}
+FX_WCHAR CBC_ASCIIEncoder::encodeASCIIDigits(FX_WCHAR digit1, FX_WCHAR digit2, FX_INT32 &e)
+{
+ if (CBC_HighLevelEncoder::isDigit(digit1) && CBC_HighLevelEncoder::isDigit(digit2)) {
+ FX_INT32 num = (digit1 - 48) * 10 + (digit2 - 48);
+ FX_WCHAR a = (FX_WCHAR) (num + 130);
+ return (FX_WCHAR) (num + 130);
+ }
+ e = BCExceptionIllegalArgumentNotGigits;
+ return 0;
+}
diff --git a/xfa/src/fxbarcode/src/BC_BarCode.cpp b/xfa/src/fxbarcode/src/BC_BarCode.cpp
new file mode 100644
index 0000000000..f22c10c6aa
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_BarCode.cpp
@@ -0,0 +1,856 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimReader.h"
+#include "include/BC_Writer.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OnedCode39Reader.h"
+#include "include/BC_OnedCode39Writer.h"
+#include "include/BC_OnedCodaBarReader.h"
+#include "include/BC_OnedCodaBarWriter.h"
+#include "include/BC_OnedCode128Reader.h"
+#include "include/BC_OnedCode128Writer.h"
+#include "include/BC_OnedEAN8Reader.h"
+#include "include/BC_OnedEAN8Writer.h"
+#include "include/BC_OnedEAN13Reader.h"
+#include "include/BC_OnedEAN13Writer.h"
+#include "include/BC_OnedUPCAReader.h"
+#include "include/BC_OnedUPCAWriter.h"
+#include "include/BC_QRCodeReader.h"
+#include "include/BC_QRCodeWriter.h"
+#include "include/BC_PDF417Compaction.h"
+#include "include/BC_PDF417.h"
+#include "include/BC_PDF417Writer.h"
+#include "include/BC_DataMatrixReader.h"
+#include "include/BC_DataMatrixWriter.h"
+#include "include/BC_LuminanceSource.h"
+#include "include/BC_BufferedImageLuminanceSource.h"
+#include "include/BC_Binarizer.h"
+#include "include/BC_GlobalHistogramBinarizer.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_UtilCodingConvert.h"
+#include "include/BC_PDF417HighLevelEncoder.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_PDF417DetectorResult.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_PDF417Detector.h"
+#include "include/BC_PDF417DetectorResult.h"
+#include "include/BC_DecoderResult.h"
+#include "include/BC_PDF417Codeword.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417BarcodeValue.h"
+#include "include/BC_PDF417BarcodeMetadata.h"
+#include "include/BC_PDF417BoundingBox.h"
+#include "include/BC_PDF417DetectionResultColumn.h"
+#include "include/BC_PDF417DetectionResultRowIndicatorColumn.h"
+#include "include/BC_PDF417DetectionResult.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417CodewordDecoder.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417ECModulusPoly.h"
+#include "include/BC_PDF417ECModulusGF.h"
+#include "include/BC_PDF417ECErrorCorrection.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_PDF417ScanningDecoder.h"
+#include "include/BC_PDF417Reader.h"
+CBC_CodeBase :: CBC_CodeBase()
+{
+}
+CBC_CodeBase :: ~CBC_CodeBase()
+{
+}
+FX_BOOL CBC_CodeBase::SetCharEncoding(FX_INT32 encoding)
+{
+ if (m_pBCWriter) {
+ return m_pBCWriter->SetCharEncoding(encoding);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_CodeBase::SetModuleHeight(FX_INT32 moduleHeight)
+{
+ if (m_pBCWriter) {
+ return m_pBCWriter->SetModuleHeight(moduleHeight);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_CodeBase::SetModuleWidth(FX_INT32 moduleWidth)
+{
+ if (m_pBCWriter) {
+ return m_pBCWriter->SetModuleWidth(moduleWidth);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_CodeBase::SetHeight(FX_INT32 height)
+{
+ if (m_pBCWriter) {
+ return m_pBCWriter->SetHeight(height);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_CodeBase::SetWidth(FX_INT32 width)
+{
+ if (m_pBCWriter) {
+ return m_pBCWriter->SetWidth(width);
+ }
+ return FALSE;
+}
+void CBC_CodeBase::SetBackgroundColor(FX_ARGB backgroundColor)
+{
+ if (m_pBCWriter) {
+ m_pBCWriter->SetBackgroundColor(backgroundColor);
+ }
+}
+void CBC_CodeBase::SetBarcodeColor(FX_ARGB foregroundColor)
+{
+ if (m_pBCWriter) {
+ m_pBCWriter->SetBarcodeColor(foregroundColor);
+ }
+}
+CBC_OneCode::CBC_OneCode()
+{
+};
+CBC_OneCode::~CBC_OneCode()
+{
+}
+FX_BOOL CBC_OneCode::CheckContentValidity(FX_WSTR contents)
+{
+ if (m_pBCWriter) {
+ return ((CBC_OneDimWriter*)m_pBCWriter)->CheckContentValidity(contents);
+ }
+ return FALSE;
+}
+CFX_WideString CBC_OneCode::FilterContents(FX_WSTR contents)
+{
+ CFX_WideString tmp;
+ if (m_pBCWriter == NULL) {
+ return tmp;
+ }
+ return ((CBC_OneDimWriter*)m_pBCWriter)->FilterContents(contents);
+}
+void CBC_OneCode::SetPrintChecksum(FX_BOOL checksum)
+{
+ if (m_pBCWriter) {
+ ((CBC_OneDimWriter*)m_pBCWriter)->SetPrintChecksum(checksum);
+ }
+}
+void CBC_OneCode::SetDataLength(FX_INT32 length)
+{
+ if (m_pBCWriter) {
+ ((CBC_OneDimWriter*)m_pBCWriter)->SetDataLength(length);
+ }
+}
+void CBC_OneCode::SetCalChecksum(FX_BOOL calc)
+{
+ if (m_pBCWriter) {
+ ((CBC_OneDimWriter*)m_pBCWriter)->SetCalcChecksum(calc);
+ }
+}
+FX_BOOL CBC_OneCode::SetFont(CFX_Font* cFont)
+{
+ if (m_pBCWriter) {
+ return ((CBC_OneDimWriter*)m_pBCWriter)->SetFont(cFont);
+ }
+ return FALSE;
+}
+void CBC_OneCode::SetFontSize(FX_FLOAT size)
+{
+ if (m_pBCWriter) {
+ ((CBC_OneDimWriter*)m_pBCWriter)->SetFontSize(size);
+ }
+}
+void CBC_OneCode::SetFontStyle(FX_INT32 style)
+{
+ if (m_pBCWriter) {
+ ((CBC_OneDimWriter*)m_pBCWriter)->SetFontStyle(style);
+ }
+}
+void CBC_OneCode::SetFontColor(FX_ARGB color)
+{
+ if (m_pBCWriter) {
+ ((CBC_OneDimWriter*)m_pBCWriter)->SetFontColor(color);
+ }
+}
+CBC_Code39::CBC_Code39()
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW (CBC_OnedCode39Reader);
+ m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_OnedCode39Writer);
+}
+CBC_Code39::CBC_Code39(FX_BOOL usingCheckDigit)
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW CBC_OnedCode39Reader(usingCheckDigit);
+ m_pBCWriter = (CBC_Writer*) FX_NEW CBC_OnedCode39Writer;
+}
+CBC_Code39::CBC_Code39(FX_BOOL usingCheckDigit, FX_BOOL extendedMode)
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW CBC_OnedCode39Reader(usingCheckDigit, extendedMode);
+ m_pBCWriter = (CBC_Writer*) FX_NEW CBC_OnedCode39Writer(extendedMode);
+}
+CBC_Code39::~CBC_Code39()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+FX_BOOL CBC_Code39::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if(contents.IsEmpty()) {
+ e = BCExceptionNoContents;
+ return FALSE;
+ }
+ BCFORMAT format = BCFORMAT_CODE_39;
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ CFX_WideString filtercontents = ((CBC_OnedCode39Writer*)m_pBCWriter)->FilterContents(contents);
+ CFX_WideString renderContents = ((CBC_OnedCode39Writer*)m_pBCWriter)->RenderTextContents(contents);
+ m_renderContents = renderContents;
+ CFX_ByteString byteString = filtercontents.UTF8Encode();
+ FX_BYTE *data = m_pBCWriter->Encode(byteString, format, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderResult(renderContents, data, outWidth, isDevice, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_Code39::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ CFX_WideString renderCon = ((CBC_OnedCode39Writer*)m_pBCWriter)->encodedContents(m_renderContents, e);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx, renderCon, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_Code39::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ CFX_WideString renderCon = ((CBC_OnedCode39Writer*)m_pBCWriter)->encodedContents(m_renderContents, e);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, renderCon, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_Code39::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_Code39::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(str, str.GetLength());
+}
+FX_BOOL CBC_Code39::SetTextLocation(BC_TEXT_LOC location)
+{
+ if (m_pBCWriter) {
+ return ((CBC_OnedCode39Writer*)m_pBCWriter)->SetTextLocation(location);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_Code39::SetWideNarrowRatio(FX_INT32 ratio)
+{
+ if (m_pBCWriter) {
+ return ((CBC_OnedCode39Writer*)m_pBCWriter)->SetWideNarrowRatio(ratio);
+ }
+ return FALSE;
+}
+CBC_Codabar::CBC_Codabar()
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW (CBC_OnedCodaBarReader);
+ m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_OnedCodaBarWriter);
+}
+CBC_Codabar::~CBC_Codabar()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+FX_BOOL CBC_Codabar::SetStartChar(FX_CHAR start)
+{
+ if (m_pBCWriter) {
+ return ((CBC_OnedCodaBarWriter*)m_pBCWriter)->SetStartChar(start);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_Codabar::SetEndChar(FX_CHAR end)
+{
+ if (m_pBCWriter) {
+ return ((CBC_OnedCodaBarWriter*)m_pBCWriter)->SetEndChar(end);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_Codabar::SetTextLocation(BC_TEXT_LOC location)
+{
+ return ((CBC_OnedCodaBarWriter*) m_pBCWriter)->SetTextLocation(location);
+}
+FX_BOOL CBC_Codabar::SetWideNarrowRatio(FX_INT32 ratio)
+{
+ if (m_pBCWriter) {
+ return ((CBC_OnedCodaBarWriter*) m_pBCWriter)->SetWideNarrowRatio(ratio);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_Codabar::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if(contents.IsEmpty()) {
+ e = BCExceptionNoContents;
+ return FALSE;
+ }
+ BCFORMAT format = BCFORMAT_CODABAR;
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ CFX_WideString filtercontents = ((CBC_OneDimWriter*)m_pBCWriter)->FilterContents(contents);
+ CFX_ByteString byteString = filtercontents.UTF8Encode();
+ m_renderContents = filtercontents;
+ FX_BYTE *data = m_pBCWriter->Encode(byteString, format, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderResult(filtercontents, data, outWidth, isDevice, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_Codabar::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ CFX_WideString renderCon = ((CBC_OnedCodaBarWriter*)m_pBCWriter)->encodedContents(m_renderContents);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx, renderCon, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_Codabar::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ CFX_WideString renderCon = ((CBC_OnedCodaBarWriter*)m_pBCWriter)->encodedContents(m_renderContents);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, renderCon, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_Codabar::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_Codabar::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(str, str.GetLength());
+}
+CBC_Code128::CBC_Code128(BC_TYPE type)
+{
+ m_pBCReader = (CBC_Reader *) FX_NEW (CBC_OnedCode128Reader);
+ m_pBCWriter = (CBC_Writer *) FX_NEW CBC_OnedCode128Writer(type);
+}
+CBC_Code128::~CBC_Code128()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+FX_BOOL CBC_Code128::SetTextLocation(BC_TEXT_LOC location)
+{
+ if (m_pBCWriter) {
+ return (( CBC_OnedCode128Writer*)m_pBCWriter)->SetTextLocation(location);
+ }
+ return FALSE;
+}
+FX_BOOL CBC_Code128::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if(contents.IsEmpty()) {
+ e = BCExceptionNoContents;
+ return FALSE;
+ }
+ BCFORMAT format = BCFORMAT_CODE_128;
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ CFX_WideString content = contents;
+ if (contents.GetLength() % 2 && ((CBC_OnedCode128Writer *)m_pBCWriter)->GetType() == BC_CODE128_C) {
+ content += '0';
+ }
+ CFX_WideString encodeContents = ((CBC_OnedCode128Writer*)m_pBCWriter)->FilterContents(content);
+ m_renderContents = encodeContents;
+ CFX_ByteString byteString = encodeContents.UTF8Encode();
+ FX_BYTE *data = m_pBCWriter->Encode(byteString, format, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderResult(encodeContents, data, outWidth, isDevice, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_Code128::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_Code128::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_Code128::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_Code128::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(str, str.GetLength());
+}
+CBC_EAN8::CBC_EAN8()
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW (CBC_OnedEAN8Reader);
+ m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_OnedEAN8Writer);
+}
+CBC_EAN8::~CBC_EAN8()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+CFX_WideString CBC_EAN8::Preprocess(FX_WSTR contents)
+{
+ CFX_WideString encodeContents = ((CBC_OnedEAN8Writer*)m_pBCWriter)->FilterContents(contents);
+ FX_INT32 length = encodeContents.GetLength();
+ if (length <= 7) {
+ for (FX_INT32 i = 0; i < 7 - length; i++) {
+ encodeContents = FX_WCHAR('0') + encodeContents;
+ }
+ CFX_ByteString byteString = encodeContents.UTF8Encode();
+ FX_INT32 checksum = ((CBC_OnedEAN8Writer *)m_pBCWriter)->CalcChecksum(byteString);
+ encodeContents += FX_WCHAR(checksum - 0 + '0');
+ }
+ if (length > 8) {
+ encodeContents = encodeContents.Mid(0, 8);
+ }
+ return encodeContents;
+}
+FX_BOOL CBC_EAN8::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if(contents.IsEmpty()) {
+ e = BCExceptionNoContents;
+ return FALSE;
+ }
+ BCFORMAT format = BCFORMAT_EAN_8;
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ CFX_WideString encodeContents = Preprocess(contents);
+ CFX_ByteString byteString = encodeContents.UTF8Encode();
+ m_renderContents = encodeContents;
+ FX_BYTE *data = m_pBCWriter->Encode(byteString, format, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderResult(encodeContents, data, outWidth, isDevice, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_EAN8::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_EAN8::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_EAN8::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_EAN8::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(str, str.GetLength());
+}
+CBC_EAN13::CBC_EAN13()
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW (CBC_OnedEAN13Reader);
+ m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_OnedEAN13Writer);
+}
+CBC_EAN13::~CBC_EAN13()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+CFX_WideString CBC_EAN13::Preprocess(FX_WSTR contents)
+{
+ CFX_WideString encodeContents = ((CBC_OnedEAN8Writer*)m_pBCWriter)->FilterContents(contents);
+ FX_INT32 length = encodeContents.GetLength();
+ if (length <= 12) {
+ for (FX_INT32 i = 0; i < 12 - length; i++) {
+ encodeContents = FX_WCHAR('0') + encodeContents;
+ }
+ CFX_ByteString byteString = encodeContents.UTF8Encode();
+ FX_INT32 checksum = ((CBC_OnedEAN13Writer *)m_pBCWriter)->CalcChecksum(byteString);
+ byteString += checksum - 0 + '0';
+ encodeContents = byteString.UTF8Decode();
+ }
+ if (length > 13) {
+ encodeContents = encodeContents.Mid(0, 13);
+ }
+ return encodeContents;
+}
+FX_BOOL CBC_EAN13::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if(contents.IsEmpty()) {
+ e = BCExceptionNoContents;
+ return FALSE;
+ }
+ BCFORMAT format = BCFORMAT_EAN_13;
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ CFX_WideString encodeContents = Preprocess(contents);
+ CFX_ByteString byteString = encodeContents.UTF8Encode();
+ m_renderContents = encodeContents;
+ FX_BYTE *data = m_pBCWriter->Encode(byteString, format, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderResult(encodeContents, data, outWidth, isDevice, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_EAN13::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_EAN13::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_EAN13::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_EAN13::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(str, str.GetLength());
+}
+CBC_UPCA::CBC_UPCA()
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW (CBC_OnedUPCAReader);
+ ((CBC_OnedUPCAReader *)m_pBCReader)->Init();
+ m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_OnedUPCAWriter);
+}
+CBC_UPCA::~CBC_UPCA()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+CFX_WideString CBC_UPCA::Preprocess(FX_WSTR contents)
+{
+ CFX_WideString encodeContents = ((CBC_OnedEAN8Writer*)m_pBCWriter)->FilterContents(contents);
+ FX_INT32 length = encodeContents.GetLength();
+ if (length <= 11) {
+ for (FX_INT32 i = 0; i < 11 - length; i++) {
+ encodeContents = FX_WCHAR('0') + encodeContents;
+ }
+ CFX_ByteString byteString = encodeContents.UTF8Encode();
+ FX_INT32 checksum = ((CBC_OnedUPCAWriter *)m_pBCWriter)->CalcChecksum(byteString);
+ byteString += checksum - 0 + '0';
+ encodeContents = byteString.UTF8Decode();
+ }
+ if (length > 12) {
+ encodeContents = encodeContents.Mid(0, 12);
+ }
+ return encodeContents;
+}
+FX_BOOL CBC_UPCA::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if(contents.IsEmpty()) {
+ e = BCExceptionNoContents;
+ return FALSE;
+ }
+ BCFORMAT format = BCFORMAT_UPC_A;
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ CFX_WideString encodeContents = Preprocess(contents);
+ CFX_ByteString byteString = encodeContents.UTF8Encode();
+ m_renderContents = encodeContents;
+ ((CBC_OnedUPCAWriter*)m_pBCWriter)->Init();
+ FX_BYTE *data = m_pBCWriter->Encode(byteString, format, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderResult(encodeContents, data, outWidth, isDevice, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_UPCA::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_UPCA::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ ((CBC_OneDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, m_renderContents, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_UPCA::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_UPCA::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString str = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(str, str.GetLength());
+}
+CBC_QRCode::CBC_QRCode()
+{
+ m_pBCReader = (CBC_Reader *) FX_NEW (CBC_QRCodeReader);
+ ((CBC_QRCodeReader*)m_pBCReader)->Init();
+ m_pBCWriter = (CBC_Writer *) FX_NEW (CBC_QRCodeWriter);
+}
+CBC_QRCode ::~CBC_QRCode()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+FX_BOOL CBC_QRCode::SetVersion(FX_INT32 version)
+{
+ if (version < 0 || version > 40) {
+ return FALSE;
+ }
+ if (m_pBCWriter == NULL) {
+ return FALSE;
+ }
+ return((CBC_QRCodeWriter*)m_pBCWriter)->SetVersion(version);
+}
+FX_BOOL CBC_QRCode::SetErrorCorrectionLevel (FX_INT32 level)
+{
+ if (level < 0 || level > 3) {
+ return FALSE;
+ }
+ if (m_pBCWriter == NULL) {
+ return FALSE;
+ }
+ return ((CBC_TwoDimWriter*)m_pBCWriter)->SetErrorCorrectionLevel(level);
+}
+FX_BOOL CBC_QRCode::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ FX_BYTE *data = ((CBC_QRCodeWriter*)m_pBCWriter)->Encode(contents, ((CBC_QRCodeWriter*)m_pBCWriter)->GetErrorCorrectionLevel(), outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderResult(data, outWidth, outHeight, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_QRCode::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx);
+ return TRUE;
+}
+FX_BOOL CBC_QRCode::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_QRCode::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_QRCode::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString retStr = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(retStr, retStr.GetLength());
+}
+CBC_PDF417I::CBC_PDF417I()
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW (CBC_PDF417Reader);
+ m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_PDF417Writer);
+}
+CBC_PDF417I::~CBC_PDF417I()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+FX_BOOL CBC_PDF417I::SetErrorCorrectionLevel (FX_INT32 level)
+{
+ ((CBC_PDF417Writer*)m_pBCWriter)->SetErrorCorrectionLevel(level);
+ return TRUE;
+}
+void CBC_PDF417I::SetTruncated(FX_BOOL truncated)
+{
+ ((CBC_PDF417Writer*)m_pBCWriter)->SetTruncated(truncated);
+}
+FX_BOOL CBC_PDF417I::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ BCFORMAT format = BCFORMAT_PDF_417;
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ FX_BYTE *data = ((CBC_PDF417Writer*)m_pBCWriter)->Encode(contents, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderResult(data, outWidth, outHeight, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_PDF417I::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx);
+ return TRUE;
+}
+FX_BOOL CBC_PDF417I::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_PDF417I::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_PDF417I::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString bytestring = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(bytestring, bytestring.GetLength());
+}
+CBC_DataMatrix::CBC_DataMatrix()
+{
+ m_pBCReader = (CBC_Reader*) FX_NEW (CBC_DataMatrixReader);
+ ((CBC_DataMatrixReader*)m_pBCReader)->Init();
+ m_pBCWriter = (CBC_Writer*) FX_NEW (CBC_DataMatrixWriter);
+}
+CBC_DataMatrix::~CBC_DataMatrix()
+{
+ if(m_pBCReader) {
+ delete(m_pBCReader);
+ m_pBCReader = NULL;
+ }
+ if(m_pBCWriter) {
+ delete(m_pBCWriter);
+ m_pBCWriter = NULL;
+ }
+}
+FX_BOOL CBC_DataMatrix::Encode(FX_WSTR contents, FX_BOOL isDevice, FX_INT32 &e)
+{
+ FX_INT32 outWidth = 0;
+ FX_INT32 outHeight = 0;
+ FX_BYTE *data = ((CBC_DataMatrixWriter *)m_pBCWriter)->Encode(contents, outWidth, outHeight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderResult(data, outWidth, outHeight, e);
+ FX_Free(data);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+FX_BOOL CBC_DataMatrix::RenderDevice(CFX_RenderDevice* device, const CFX_Matrix* matirx, FX_INT32 &e)
+{
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderDeviceResult(device, matirx);
+ return TRUE;
+}
+FX_BOOL CBC_DataMatrix::RenderBitmap(CFX_DIBitmap *&pOutBitmap, FX_INT32 &e)
+{
+ ((CBC_TwoDimWriter*)m_pBCWriter)->RenderBitmapResult(pOutBitmap, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return TRUE;
+}
+CFX_WideString CBC_DataMatrix::Decode(FX_BYTE* buf, FX_INT32 width, FX_INT32 hight, FX_INT32 &e)
+{
+ CFX_WideString str;
+ return str;
+}
+CFX_WideString CBC_DataMatrix::Decode(CFX_DIBitmap *pBitmap, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString retStr = m_pBCReader->Decode(&bitmap, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ return CFX_WideString::FromUTF8(retStr, retStr.GetLength());
+}
diff --git a/xfa/src/fxbarcode/src/BC_Base256Encoder.cpp b/xfa/src/fxbarcode/src/BC_Base256Encoder.cpp
new file mode 100644
index 0000000000..c0e1f46fd4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Base256Encoder.cpp
@@ -0,0 +1,79 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_Base256Encoder.h"
+CBC_Base256Encoder::CBC_Base256Encoder()
+{
+}
+CBC_Base256Encoder::~CBC_Base256Encoder()
+{
+}
+FX_INT32 CBC_Base256Encoder::getEncodingMode()
+{
+ return BASE256_ENCODATION;
+}
+void CBC_Base256Encoder::Encode(CBC_EncoderContext &context, FX_INT32 &e)
+{
+ CFX_WideString buffer;
+ buffer += (FX_WCHAR)'\0';
+ while (context.hasMoreCharacters()) {
+ FX_WCHAR c = context.getCurrentChar();
+ buffer += c;
+ context.m_pos++;
+ FX_INT32 newMode = CBC_HighLevelEncoder::lookAheadTest(context.m_msg, context.m_pos, getEncodingMode());
+ if (newMode != getEncodingMode()) {
+ context.signalEncoderChange(newMode);
+ break;
+ }
+ }
+ FX_INT32 dataCount = buffer.GetLength() - 1;
+ FX_CHAR buf[128];
+#if defined(_FX_WINAPI_PARTITION_APP_)
+ memset(buf, 0, sizeof(FX_CHAR) * 128);
+ _itoa_s(dataCount, buf, 128, 10);
+#else
+ FXSYS_itoa(dataCount, buf, 10);
+#endif
+ buffer.SetAt(0, FX_WCHAR(*buf) - '0');
+ FX_INT32 lengthFieldSize = 1;
+ FX_INT32 currentSize = context.getCodewordCount() + dataCount + lengthFieldSize;
+ context.updateSymbolInfo(currentSize, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_BOOL mustPad = (context.m_symbolInfo->m_dataCapacity - currentSize) > 0;
+ if (context.hasMoreCharacters() || mustPad) {
+ if (dataCount <= 249) {
+ buffer.SetAt(0, (FX_WCHAR) dataCount);
+ } else if (dataCount > 249 && dataCount <= 1555) {
+ buffer.SetAt(0, (FX_WCHAR) ((dataCount / 250) + 249));
+ buffer.Insert(1, (FX_WCHAR) (dataCount % 250));
+ } else {
+ e = BCExceptionIllegalStateMessageLengthInvalid;
+ return;
+ }
+ }
+ for (FX_INT32 i = 0, c = buffer.GetLength(); i < c; i++) {
+ context.writeCodeword(randomize255State(buffer.GetAt(i), context.getCodewordCount() + 1));
+ }
+}
+FX_WCHAR CBC_Base256Encoder::randomize255State(FX_WCHAR ch, FX_INT32 codewordPosition)
+{
+ FX_INT32 pseudoRandom = ((149 * codewordPosition) % 255) + 1;
+ FX_INT32 tempVariable = ch + pseudoRandom;
+ if (tempVariable <= 255) {
+ return (FX_WCHAR) tempVariable;
+ } else {
+ return (FX_WCHAR) (tempVariable - 256);
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_Binarizer.cpp b/xfa/src/fxbarcode/src/BC_Binarizer.cpp
new file mode 100644
index 0000000000..e18efe2e31
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Binarizer.cpp
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_LuminanceSource.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_Binarizer.h"
+CBC_Binarizer::CBC_Binarizer(CBC_LuminanceSource *source)
+{
+ m_source = source;
+}
+CBC_Binarizer::~CBC_Binarizer()
+{
+}
+CBC_LuminanceSource *CBC_Binarizer::GetLuminanceSource()
+{
+ return m_source;
+}
diff --git a/xfa/src/fxbarcode/src/BC_BinaryBitmap.cpp b/xfa/src/fxbarcode/src/BC_BinaryBitmap.cpp
new file mode 100644
index 0000000000..64f64bfe06
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_BinaryBitmap.cpp
@@ -0,0 +1,60 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Binarizer.h"
+#include "include/BC_LuminanceSource.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_BinaryBitmap.h"
+CBC_BinaryBitmap::CBC_BinaryBitmap(CBC_Binarizer *binarizer): m_binarizer(binarizer), m_matrix(NULL)
+{
+}
+CBC_BinaryBitmap::~CBC_BinaryBitmap()
+{
+ if (m_matrix != NULL) {
+ delete m_matrix;
+ }
+ m_matrix = NULL;
+}
+FX_INT32 CBC_BinaryBitmap::GetHeight()
+{
+ return m_binarizer->GetLuminanceSource()->GetHeight();
+}
+FX_INT32 CBC_BinaryBitmap::GetWidth()
+{
+ return m_binarizer->GetLuminanceSource()->GetWidth();
+}
+CBC_CommonBitMatrix *CBC_BinaryBitmap::GetMatrix(FX_INT32 &e)
+{
+ if (m_matrix == NULL) {
+ m_matrix = m_binarizer->GetBlackMatrix(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return m_matrix;
+}
+FX_BOOL CBC_BinaryBitmap::IsCropSupported()
+{
+ return m_binarizer->GetLuminanceSource()->IsCropSupported();
+}
+FX_BOOL CBC_BinaryBitmap::IsRotateSupported()
+{
+ return m_binarizer->GetLuminanceSource()->IsRotateSupported();
+}
+CBC_CommonBitArray *CBC_BinaryBitmap::GetBlackRow(FX_INT32 y, CBC_CommonBitArray *row, FX_INT32 &e)
+{
+ CBC_CommonBitArray *temp = m_binarizer->GetBlackRow(y, row, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+CBC_CommonBitMatrix *CBC_BinaryBitmap::GetBlackMatrix(FX_INT32 &e)
+{
+ if (m_matrix == NULL) {
+ m_matrix = m_binarizer->GetBlackMatrix(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return m_matrix;
+}
diff --git a/xfa/src/fxbarcode/src/BC_BufferedImageLuminanceSource.cpp b/xfa/src/fxbarcode/src/BC_BufferedImageLuminanceSource.cpp
new file mode 100644
index 0000000000..b0f5267d4d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_BufferedImageLuminanceSource.cpp
@@ -0,0 +1,188 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_LuminanceSource.h"
+#include "include/BC_BufferedImageLuminanceSource.h"
+class CBC_Pause : public IFX_Pause
+{
+public:
+ virtual FX_BOOL NeedToPauseNow()
+ {
+ return TRUE;
+ }
+};
+static CFX_DIBitmap* CreateDIBSource(IFX_FileRead* fileread)
+{
+ CFX_DIBitmap* bitmap = NULL;
+ CCodec_ModuleMgr* pCodecMgr = NULL;
+ ICodec_ProgressiveDecoder* pImageCodec = NULL;
+ pCodecMgr = CCodec_ModuleMgr::Create();
+ pImageCodec = pCodecMgr->CreateProgressiveDecoder();
+ FXCODEC_STATUS status = FXCODEC_STATUS_DECODE_FINISH;
+ status = pImageCodec->LoadImageInfo(fileread, FXCODEC_IMAGE_UNKNOWN);
+ if (status != FXCODEC_STATUS_FRAME_READY) {
+ return NULL;
+ }
+ bitmap = FX_NEW CFX_DIBitmap;
+ bitmap->Create(pImageCodec->GetWidth(), pImageCodec->GetHeight(), FXDIB_Argb);
+ bitmap->Clear(FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF));
+ CBC_Pause pause;
+ FX_INT32 frames;
+ status = pImageCodec->GetFrames(frames, &pause);
+ while (status == FXCODEC_STATUS_FRAME_TOBECONTINUE) {
+ status = pImageCodec->GetFrames(frames, &pause);
+ }
+ if (status != FXCODEC_STATUS_DECODE_READY) {
+ goto except;
+ }
+ status = pImageCodec->StartDecode(bitmap,
+ 0,
+ 0,
+ bitmap->GetWidth(),
+ bitmap->GetHeight(),
+ 0,
+ FALSE);
+ if (status == FXCODEC_STATUS_ERR_PARAMS) {
+ goto except;
+ }
+ if (status != FXCODEC_STATUS_DECODE_TOBECONTINUE) {
+ goto except;
+ }
+ while (status == FXCODEC_STATUS_DECODE_TOBECONTINUE) {
+ status = pImageCodec->ContinueDecode(&pause);
+ }
+ if (status != FXCODEC_STATUS_DECODE_FINISH) {
+ goto except;
+ }
+ if (pImageCodec) {
+ delete pImageCodec;
+ pImageCodec = NULL;
+ }
+ if (pCodecMgr) {
+ pCodecMgr->Destroy();
+ pCodecMgr = NULL;
+ }
+ return bitmap;
+except:
+ if (pImageCodec) {
+ delete pImageCodec;
+ pImageCodec = NULL;
+ }
+ if (pCodecMgr) {
+ pCodecMgr->Destroy();
+ pCodecMgr = NULL;
+ }
+ if (bitmap) {
+ delete bitmap;
+ }
+ return NULL;
+}
+CBC_BufferedImageLuminanceSource::CBC_BufferedImageLuminanceSource(const CFX_WideString &filename): CBC_LuminanceSource(0, 0), m_filename(filename)
+{
+ m_height = 0;
+ m_width = 0;
+ m_bytesPerLine = 0;
+ m_top = 0;
+ m_left = 0;
+}
+void CBC_BufferedImageLuminanceSource::Init(FX_INT32 &e)
+{
+ IFX_FileRead* fileread = FX_CreateFileRead(m_filename);
+ m_pBitmap = CreateDIBSource(fileread);
+ if (m_pBitmap == NULL) {
+ e = BCExceptionLoadFile;
+ return;
+ }
+ m_pBitmap->ConvertFormat(FXDIB_Argb);
+ m_height = m_pBitmap->GetHeight();
+ m_width = m_pBitmap->GetWidth();
+ m_rgbData.SetSize(m_height * m_width);
+ m_bytesPerLine = m_width * 4;
+ m_top = 0;
+ m_left = 0;
+}
+CBC_BufferedImageLuminanceSource::CBC_BufferedImageLuminanceSource(CFX_DIBitmap *pBitmap): CBC_LuminanceSource(0, 0)
+{
+ m_pBitmap = pBitmap->Clone();
+ m_pBitmap->ConvertFormat(FXDIB_Argb);
+ m_height = m_pBitmap->GetHeight();
+ m_width = m_pBitmap->GetWidth();
+ m_rgbData.SetSize(m_height * m_width);
+ m_bytesPerLine = m_width * 4;
+ m_top = 0;
+ m_left = 0;
+}
+CBC_BufferedImageLuminanceSource::~CBC_BufferedImageLuminanceSource()
+{
+ delete m_pBitmap;
+ m_pBitmap = NULL;
+}
+CFX_ByteArray *CBC_BufferedImageLuminanceSource::GetRow(FX_INT32 y, CFX_ByteArray &row, FX_INT32 &e)
+{
+ if (y < 0 || y >= m_height) {
+ e = BCExceptionRequestedRowIsOutSizeTheImage;
+ return NULL;
+ }
+ FX_INT32 width = m_width;
+ if(row.GetSize() == 0 || row.GetSize() < width) {
+ row.SetSize(width);
+ }
+ if(m_rgbData.GetSize() == 0 || m_rgbData.GetSize() < width) {
+ m_rgbData.SetSize(width);
+ }
+ FX_INT32* rowLine = (FX_INT32*)m_pBitmap->GetScanline(y);
+ FX_INT32 x;
+ for (x = 0; x < width; x++) {
+ FX_INT32 pixel = rowLine[x];
+ FX_INT32 luminance = (306 * ((pixel >> 16) & 0xFF) +
+ 601 * ((pixel >> 8) & 0xFF) +
+ 117 * (pixel & 0xFF)) >> 10;
+ row[x] = (FX_BYTE) luminance;
+ }
+ return &row;
+}
+CFX_ByteArray *CBC_BufferedImageLuminanceSource::GetMatrix()
+{
+ CFX_ByteArray *matirx = FX_NEW CFX_ByteArray();
+ matirx->SetSize(m_bytesPerLine * m_height);
+ FX_INT32 *rgb = (FX_INT32*)m_pBitmap->GetBuffer();
+ FX_INT32 y;
+ for(y = 0; y < m_height; y++) {
+ FX_INT32 offset = y * m_width;
+ FX_INT32 x;
+ for(x = 0; x < m_width; x++) {
+ FX_INT32 pixel = rgb[offset + x];
+ FX_INT32 luminance = (306 * ((pixel >> 16) & 0xFF) +
+ 601 * ((pixel >> 8) & 0xFF) +
+ 117 * (pixel & 0xFF)) >> 10;
+ (*matirx)[offset + x] = (FX_BYTE) luminance;
+ }
+ }
+ return matirx;
+}
+FX_BOOL CBC_BufferedImageLuminanceSource::IsCropSupported()
+{
+ return TRUE;
+}
+FX_BOOL CBC_BufferedImageLuminanceSource::IsRotateSupported()
+{
+ return TRUE;
+}
+CBC_LuminanceSource *CBC_BufferedImageLuminanceSource::Crop(FX_INT32 left, FX_INT32 top, FX_INT32 width, FX_INT32 height)
+{
+ return NULL;
+}
+CBC_LuminanceSource *CBC_BufferedImageLuminanceSource::RotateCounterClockwise(FX_INT32 &e)
+{
+ if (!IsRotateSupported()) {
+ e = BCExceptionRotateNotSupported;
+ return NULL;
+ }
+ FX_INT32 sourceWidth = m_width;
+ FX_INT32 sourceHeight = m_height;
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/src/BC_C40Encoder.cpp b/xfa/src/fxbarcode/src/BC_C40Encoder.cpp
new file mode 100644
index 0000000000..da3a8efaae
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_C40Encoder.cpp
@@ -0,0 +1,182 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_C40Encoder.h"
+CBC_C40Encoder::CBC_C40Encoder()
+{
+}
+CBC_C40Encoder::~CBC_C40Encoder()
+{
+}
+FX_INT32 CBC_C40Encoder::getEncodingMode()
+{
+ return C40_ENCODATION;
+}
+void CBC_C40Encoder::Encode(CBC_EncoderContext &context, FX_INT32 &e)
+{
+ CFX_WideString buffer;
+ while (context.hasMoreCharacters()) {
+ FX_WCHAR c = context.getCurrentChar();
+ context.m_pos++;
+ FX_INT32 lastCharSize = encodeChar(c, buffer, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_INT32 unwritten = (buffer.GetLength() / 3) * 2;
+ FX_INT32 curCodewordCount = context.getCodewordCount() + unwritten;
+ context.updateSymbolInfo(curCodewordCount, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_INT32 available = context.m_symbolInfo->m_dataCapacity - curCodewordCount;
+ if (!context.hasMoreCharacters()) {
+ CFX_WideString removed;
+ if ((buffer.GetLength() % 3) == 2) {
+ if (available < 2 || available > 2) {
+ lastCharSize = backtrackOneCharacter(context, buffer, removed, lastCharSize, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ }
+ }
+ while ((buffer.GetLength() % 3) == 1
+ && ((lastCharSize <= 3 && available != 1) || lastCharSize > 3)) {
+ lastCharSize = backtrackOneCharacter(context, buffer, removed, lastCharSize, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ }
+ break;
+ }
+ FX_INT32 count = buffer.GetLength();
+ if ((count % 3) == 0) {
+ FX_INT32 newMode = CBC_HighLevelEncoder::lookAheadTest(context.m_msg, context.m_pos, getEncodingMode());
+ if (newMode != getEncodingMode()) {
+ context.signalEncoderChange(newMode);
+ break;
+ }
+ }
+ }
+ handleEOD(context, buffer, e);
+}
+void CBC_C40Encoder::writeNextTriplet(CBC_EncoderContext &context, CFX_WideString &buffer)
+{
+ context.writeCodewords(encodeToCodewords(buffer, 0));
+ buffer.Delete(0, 3);
+}
+void CBC_C40Encoder::handleEOD(CBC_EncoderContext &context, CFX_WideString &buffer, FX_INT32 &e)
+{
+ FX_INT32 unwritten = (buffer.GetLength() / 3) * 2;
+ FX_INT32 rest = buffer.GetLength() % 3;
+ FX_INT32 curCodewordCount = context.getCodewordCount() + unwritten;
+ context.updateSymbolInfo(curCodewordCount, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_INT32 available = context.m_symbolInfo->m_dataCapacity - curCodewordCount;
+ if (rest == 2) {
+ buffer += (FX_WCHAR)'\0';
+ while (buffer.GetLength() >= 3) {
+ writeNextTriplet(context, buffer);
+ }
+ if (context.hasMoreCharacters()) {
+ context.writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH);
+ }
+ } else if (available == 1 && rest == 1) {
+ while (buffer.GetLength() >= 3) {
+ writeNextTriplet(context, buffer);
+ }
+ if (context.hasMoreCharacters()) {
+ context.writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH);
+ }
+ context.m_pos--;
+ } else if (rest == 0) {
+ while (buffer.GetLength() >= 3) {
+ writeNextTriplet(context, buffer);
+ }
+ if (available > 0 || context.hasMoreCharacters()) {
+ context.writeCodeword(CBC_HighLevelEncoder::C40_UNLATCH);
+ }
+ } else {
+ e = BCExceptionIllegalStateUnexpectedCase;
+ return;
+ }
+ context.signalEncoderChange(ASCII_ENCODATION);
+}
+FX_INT32 CBC_C40Encoder::encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e)
+{
+ if (c == ' ') {
+ sb += (FX_WCHAR)'\3';
+ return 1;
+ } else if ((c >= '0') && (c <= '9')) {
+ sb += (FX_WCHAR)(c - 48 + 4);
+ return 1;
+ } else if ((c >= 'A') && (c <= 'Z')) {
+ sb += (FX_WCHAR)(c - 65 + 14);
+ return 1;
+ } else if ((c >= '\0') && (c <= 0x1f)) {
+ sb += (FX_WCHAR)'\0';
+ sb += c;
+ return 2;
+ } else if ((c >= '!') && (c <= '/')) {
+ sb += (FX_WCHAR)'\1';
+ sb += (FX_WCHAR)(c - 33);
+ return 2;
+ } else if ((c >= ':') && (c <= '@')) {
+ sb += (FX_WCHAR)'\1';
+ sb += (FX_WCHAR)(c - 58 + 15);
+ return 2;
+ } else if ((c >= '[') && (c <= '_')) {
+ sb += (FX_WCHAR)'\1';
+ sb += (FX_WCHAR)(c - 91 + 22);
+ return 2;
+ } else if ((c >= 60) && (c <= 0x7f)) {
+ sb += (FX_WCHAR)'\2';
+ sb += (FX_WCHAR)(c - 96);
+ return 2;
+ } else if (c >= 80) {
+ sb += (FX_WCHAR)'\1';
+ sb += (FX_WCHAR)0x001e;
+ FX_INT32 len = 2;
+ len += encodeChar((c - 128), sb, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ return len;
+ } else {
+ e = BCExceptionIllegalArgument;
+ return 0;
+ }
+}
+FX_INT32 CBC_C40Encoder::backtrackOneCharacter(CBC_EncoderContext &context, CFX_WideString &buffer, CFX_WideString &removed, FX_INT32 lastCharSize, FX_INT32 &e)
+{
+ FX_INT32 count = buffer.GetLength();
+ buffer.Delete(count - lastCharSize, count);
+ context.m_pos--;
+ FX_WCHAR c = context.getCurrentChar();
+ lastCharSize = encodeChar(c, removed, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ context.resetSymbolInfo();
+ return lastCharSize;
+}
+CFX_WideString CBC_C40Encoder::encodeToCodewords(CFX_WideString sb, FX_INT32 startPos)
+{
+ FX_WCHAR c1 = sb.GetAt(startPos);
+ FX_WCHAR c2 = sb.GetAt(startPos + 1);
+ FX_WCHAR c3 = sb.GetAt(startPos + 2);
+ FX_INT32 v = (1600 * c1) + (40 * c2) + c3 + 1;
+ FX_WCHAR cw1 = (FX_WCHAR) (v / 256);
+ FX_WCHAR cw2 = (FX_WCHAR) (v % 256);
+ CFX_WideString b1(cw1);
+ CFX_WideString b2(cw2);
+ return b1 + b2;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonBitArray.cpp b/xfa/src/fxbarcode/src/BC_CommonBitArray.cpp
new file mode 100644
index 0000000000..a42f444399
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonBitArray.cpp
@@ -0,0 +1,108 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitArray.h"
+CBC_CommonBitArray::CBC_CommonBitArray(CBC_CommonBitArray* array)
+{
+ m_size = array->GetSize();
+ m_bits.Copy(array->GetBits());
+}
+CBC_CommonBitArray::CBC_CommonBitArray()
+{
+ m_bits.SetSize(1);
+ m_size = 0;
+}
+CBC_CommonBitArray::CBC_CommonBitArray(FX_INT32 size)
+{
+ m_bits.SetSize((size + 31) >> 5);
+ m_size = size;
+}
+CBC_CommonBitArray::~CBC_CommonBitArray()
+{
+ m_size = 0;
+}
+FX_INT32 CBC_CommonBitArray::GetSize()
+{
+ return m_size;
+}
+CFX_Int32Array& CBC_CommonBitArray::GetBits()
+{
+ return m_bits;
+}
+FX_INT32 CBC_CommonBitArray::GetSizeInBytes()
+{
+ return (m_size + 7) >> 3;
+}
+FX_BOOL CBC_CommonBitArray::Get(FX_INT32 i)
+{
+ return (m_bits[i >> 5] & (1 << (i & 0x1f))) != 0;
+}
+void CBC_CommonBitArray::Set(FX_INT32 i)
+{
+ m_bits[i >> 5] |= 1 << (i & 0x1F);
+}
+void CBC_CommonBitArray::Flip(FX_INT32 i)
+{
+ m_bits[i >> 5] ^= 1 << (i & 0x1F);
+}
+void CBC_CommonBitArray::SetBulk(FX_INT32 i, FX_INT32 newBits)
+{
+ m_bits[i >> 5] = newBits;
+}
+void CBC_CommonBitArray::Clear()
+{
+ FXSYS_memset32(&m_bits[0], 0x00, m_bits.GetSize() * sizeof(FX_INT32));
+}
+FX_BOOL CBC_CommonBitArray::IsRange(FX_INT32 start, FX_INT32 end, FX_BOOL value, FX_INT32 &e)
+{
+ if (end < start) {
+ e = BCExceptionEndLessThanStart;
+ return FALSE;
+ }
+ if (end == start) {
+ return TRUE;
+ }
+ end--;
+ FX_INT32 firstInt = start >> 5;
+ FX_INT32 lastInt = end >> 5;
+ FX_INT32 i;
+ for (i = firstInt; i <= lastInt; i++) {
+ FX_INT32 firstBit = i > firstInt ? 0 : start & 0x1F;
+ FX_INT32 lastBit = i < lastInt ? 31 : end & 0x1F;
+ FX_INT32 mask;
+ if (firstBit == 0 && lastBit == 31) {
+ mask = -1;
+ } else {
+ mask = 0;
+ for (FX_INT32 j = firstBit; j <= lastBit; j++) {
+ mask |= 1 << j;
+ }
+ }
+ if ((m_bits[i] & mask) != (value ? mask : 0)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FX_INT32* CBC_CommonBitArray::GetBitArray()
+{
+ return &m_bits[0];
+}
+void CBC_CommonBitArray::Reverse()
+{
+ FX_INT32* newBits = FX_Alloc(FX_INT32, m_bits.GetSize());
+ FXSYS_memset32(newBits, 0x00, m_bits.GetSize() * sizeof(FX_INT32));
+ FX_INT32 size = m_size;
+ FX_INT32 i;
+ for (i = 0; i < size; i++) {
+ if (Get(size - i - 1)) {
+ newBits[i >> 5] |= 1 << (i & 0x1F);
+ }
+ }
+ FXSYS_memcpy32(&m_bits[0], newBits, m_bits.GetSize() * sizeof(FX_INT32));
+ FX_Free(newBits);
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonBitMatrix.cpp b/xfa/src/fxbarcode/src/BC_CommonBitMatrix.cpp
new file mode 100644
index 0000000000..3437571fee
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonBitMatrix.cpp
@@ -0,0 +1,145 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_CommonBitMatrix.h"
+CBC_CommonBitMatrix::CBC_CommonBitMatrix()
+{
+ m_width = 0;
+ m_height = 0;
+ m_rowSize = 0;
+ m_bits = NULL;
+}
+void CBC_CommonBitMatrix::Init(FX_INT32 dimension)
+{
+ m_width = dimension;
+ m_height = dimension;
+ FX_INT32 rowSize = (m_height + 31) >> 5;
+ m_rowSize = rowSize;
+ m_bits = FX_Alloc(FX_INT32, m_rowSize * m_height);
+ FXSYS_memset32(m_bits, 0, m_rowSize * m_height * sizeof(FX_INT32));
+}
+void CBC_CommonBitMatrix::Init(FX_INT32 width, FX_INT32 height)
+{
+ m_width = width;
+ m_height = height;
+ FX_INT32 rowSize = (width + 31) >> 5;
+ m_rowSize = rowSize;
+ m_bits = FX_Alloc(FX_INT32, m_rowSize * m_height);
+ FXSYS_memset32(m_bits, 0, m_rowSize * m_height * sizeof(FX_INT32));
+}
+CBC_CommonBitMatrix::~CBC_CommonBitMatrix()
+{
+ if (m_bits != NULL) {
+ FX_Free(m_bits);
+ }
+ m_bits = NULL;
+ m_height = m_width = m_rowSize = 0;
+}
+FX_BOOL CBC_CommonBitMatrix::Get(FX_INT32 x, FX_INT32 y)
+{
+ FX_INT32 offset = y * m_rowSize + (x >> 5);
+ if (offset >= m_rowSize * m_height || offset < 0) {
+ return false;
+ }
+ return ((((FX_DWORD)m_bits[offset]) >> (x & 0x1f)) & 1) != 0;
+}
+FX_INT32* CBC_CommonBitMatrix::GetBits()
+{
+ return m_bits;
+}
+void CBC_CommonBitMatrix::Set(FX_INT32 x, FX_INT32 y)
+{
+ FX_INT32 offset = y * m_rowSize + (x >> 5);
+ if (offset >= m_rowSize * m_height || offset < 0) {
+ return;
+ }
+ m_bits[offset] |= 1 << (x & 0x1f);
+}
+void CBC_CommonBitMatrix::Flip(FX_INT32 x, FX_INT32 y)
+{
+ FX_INT32 offset = y * m_rowSize + (x >> 5);
+ m_bits[offset] ^= 1 << (x & 0x1f);
+}
+void CBC_CommonBitMatrix::Clear()
+{
+ FXSYS_memset32(m_bits, 0, m_rowSize * m_height * sizeof(FX_INT32));
+}
+void CBC_CommonBitMatrix::SetRegion(FX_INT32 left, FX_INT32 top, FX_INT32 width, FX_INT32 height, FX_INT32 &e)
+{
+ if (top < 0 || left < 0) {
+ e = BCExceptionLeftAndTopMustBeNonnegative;
+ return;
+ }
+ if (height < 1 || width < 1) {
+ e = BCExceptionHeightAndWidthMustBeAtLeast1;
+ return;
+ }
+ FX_INT32 right = left + width;
+ FX_INT32 bottom = top + height;
+ if (m_height < bottom || m_width < right) {
+ e = BCExceptionRegionMustFitInsideMatrix;
+ return;
+ }
+ FX_INT32 y;
+ for (y = top; y < bottom; y++) {
+ FX_INT32 offset = y * m_rowSize;
+ FX_INT32 x;
+ for (x = left; x < right; x++) {
+ m_bits[offset + (x >> 5)] |= 1 << (x & 0x1f);
+ }
+ }
+}
+CBC_CommonBitArray* CBC_CommonBitMatrix::GetRow(FX_INT32 y, CBC_CommonBitArray* row)
+{
+ CBC_CommonBitArray* rowArray = NULL;
+ if (row == NULL || row->GetSize() < m_width) {
+ rowArray = FX_NEW CBC_CommonBitArray(m_width);
+ } else {
+ rowArray = FX_NEW CBC_CommonBitArray(row);
+ }
+ FX_INT32 offset = y * m_rowSize;
+ FX_INT32 x;
+ for (x = 0; x < m_rowSize; x++) {
+ rowArray->SetBulk(x << 5, m_bits[offset + x]);
+ }
+ return rowArray;
+}
+void CBC_CommonBitMatrix::SetRow(FX_INT32 y, CBC_CommonBitArray* row)
+{
+ FX_INT32 l = y * m_rowSize;
+ for (FX_INT32 i = 0; i < m_rowSize; i++) {
+ m_bits[l] = row->GetBitArray()[i];
+ l++;
+ }
+}
+void CBC_CommonBitMatrix::SetCol(FX_INT32 y, CBC_CommonBitArray* col)
+{
+ for (FX_INT32 i = 0; i < col->GetBits().GetSize(); i++) {
+ m_bits[i * m_rowSize + y] = col->GetBitArray()[i];
+ }
+}
+FX_INT32 CBC_CommonBitMatrix::GetWidth()
+{
+ return m_width;
+}
+FX_INT32 CBC_CommonBitMatrix::GetHeight()
+{
+ return m_height;
+}
+FX_INT32 CBC_CommonBitMatrix::GetRowSize()
+{
+ return m_rowSize;
+}
+FX_INT32 CBC_CommonBitMatrix::GetDimension(FX_INT32 &e)
+{
+ if (m_width != m_height) {
+ e = BCExceptionCanNotCallGetDimensionOnNonSquareMatrix;
+ return 0;
+ }
+ return m_width;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonBitSource.cpp b/xfa/src/fxbarcode/src/BC_CommonBitSource.cpp
new file mode 100644
index 0000000000..de29002753
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonBitSource.cpp
@@ -0,0 +1,60 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitSource.h"
+CBC_CommonBitSource::CBC_CommonBitSource(CFX_ByteArray* bytes)
+{
+ m_bytes.Copy((*bytes));
+ m_bitOffset = 0;
+ m_byteOffset = 0;
+}
+CBC_CommonBitSource::~CBC_CommonBitSource()
+{
+}
+FX_INT32 CBC_CommonBitSource::ReadBits(FX_INT32 numBits, FX_INT32 &e)
+{
+ if (numBits < 1 || numBits > 32) {
+ e = BCExceptionIllegalArgument;
+ return 0;
+ }
+ FX_INT32 result = 0;
+ if (m_bitOffset > 0) {
+ FX_INT32 bitsLeft = 8 - m_bitOffset;
+ FX_INT32 toRead = numBits < bitsLeft ? numBits : bitsLeft;
+ FX_INT32 bitsToNotRead = bitsLeft - toRead;
+ FX_INT32 mask = (0xff >> (8 - toRead)) << bitsToNotRead;
+ result = (m_bytes[m_byteOffset] & mask) >> bitsToNotRead;
+ numBits -= toRead;
+ m_bitOffset += toRead;
+ if (m_bitOffset == 8) {
+ m_bitOffset = 0;
+ m_byteOffset++;
+ }
+ }
+ if (numBits > 0) {
+ while(numBits >= 8) {
+ result = (result << 8) | (m_bytes[m_byteOffset] & 0xff);
+ m_byteOffset++;
+ numBits -= 8;
+ }
+ if (numBits > 0) {
+ FX_INT32 bitsToNotRead = 8 - numBits;
+ FX_INT32 mask = (0xff >> bitsToNotRead) << bitsToNotRead;
+ result = (result << numBits) | ((m_bytes[m_byteOffset] & mask) >> bitsToNotRead);
+ m_bitOffset += numBits;
+ }
+ }
+ return result;
+}
+FX_INT32 CBC_CommonBitSource::Available()
+{
+ return 8 * (m_bytes.GetSize() - m_byteOffset) - m_bitOffset;
+}
+FX_INT32 CBC_CommonBitSource::getByteOffset()
+{
+ return m_byteOffset;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonByteArray.cpp b/xfa/src/fxbarcode/src/BC_CommonByteArray.cpp
new file mode 100644
index 0000000000..bdf9dd2405
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonByteArray.cpp
@@ -0,0 +1,98 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonByteArray.h"
+CBC_CommonByteArray::CBC_CommonByteArray()
+{
+ m_bytes = NULL;
+ m_size = 0;
+ m_index = 0;
+}
+CBC_CommonByteArray::CBC_CommonByteArray(FX_INT32 size)
+{
+ m_size = size;
+ m_bytes = FX_Alloc(FX_BYTE, size);
+ FXSYS_memset32(m_bytes, 0, size);
+ m_index = 0;
+}
+CBC_CommonByteArray::CBC_CommonByteArray(FX_BYTE* byteArray, FX_INT32 size)
+{
+ m_size = size;
+ m_bytes = FX_Alloc(FX_BYTE, size);
+ FXSYS_memcpy32(m_bytes, byteArray, size);
+ m_index = size;
+}
+CBC_CommonByteArray::~CBC_CommonByteArray()
+{
+ if ( m_bytes != NULL) {
+ FX_Free( m_bytes );
+ m_bytes = NULL;
+ }
+ m_index = 0;
+ m_size = 0;
+}
+FX_INT32 CBC_CommonByteArray::At(FX_INT32 index)
+{
+ return m_bytes[index] & 0xff;
+}
+void CBC_CommonByteArray::Set(FX_INT32 index, FX_INT32 value)
+{
+ m_bytes[index] = (FX_BYTE) value;
+}
+FX_INT32 CBC_CommonByteArray::Size()
+{
+ return m_size;
+}
+FX_BOOL CBC_CommonByteArray::IsEmpty()
+{
+ return m_size == 0;
+}
+void CBC_CommonByteArray::AppendByte(FX_INT32 value)
+{
+ if (m_size == 0 || m_index >= m_size) {
+ FX_INT32 newSize = FX_MAX(32, m_size << 1);
+ Reserve(newSize);
+ }
+ m_bytes[m_index] = (FX_BYTE)value;
+ m_index++;
+}
+void CBC_CommonByteArray::Reserve(FX_INT32 capacity)
+{
+ if (m_bytes == NULL || m_size < capacity) {
+ FX_BYTE *newArray = FX_Alloc(FX_BYTE, capacity);
+ FXSYS_memset32(newArray, 0, capacity);
+ if (m_bytes != NULL) {
+ FXSYS_memcpy32(newArray, m_bytes, m_size);
+ FX_Free( m_bytes );
+ }
+ m_bytes = newArray;
+ m_size = capacity;
+ }
+}
+void CBC_CommonByteArray::Set(FX_BYTE* source, FX_INT32 offset, FX_INT32 count)
+{
+ if (m_bytes != NULL) {
+ FX_Free( m_bytes );
+ }
+ m_bytes = FX_Alloc(FX_BYTE, count);
+ m_size = count;
+ FXSYS_memcpy32(m_bytes, source + offset, count);
+ m_index = count;
+}
+void CBC_CommonByteArray::Set(CFX_ByteArray* source, FX_INT32 offset, FX_INT32 count)
+{
+ if (m_bytes != NULL) {
+ FX_Free( m_bytes );
+ }
+ m_bytes = FX_Alloc(FX_BYTE, count);
+ m_size = count;
+ FX_INT32 i;
+ for(i = 0; i < count; i++) {
+ m_bytes[i] = source->operator [](i + offset);
+ }
+ m_index = m_size;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonByteMatrix.cpp b/xfa/src/fxbarcode/src/BC_CommonByteMatrix.cpp
new file mode 100644
index 0000000000..50e89e783b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonByteMatrix.cpp
@@ -0,0 +1,60 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonByteMatrix.h"
+CBC_CommonByteMatrix::CBC_CommonByteMatrix(FX_INT32 width, FX_INT32 height)
+{
+ m_height = height;
+ m_width = width;
+ m_bytes = NULL;
+}
+void CBC_CommonByteMatrix::Init()
+{
+ m_bytes = FX_Alloc(FX_BYTE, m_height * m_width);
+ FXSYS_memset8(m_bytes, 0xff, m_height * m_width);
+}
+CBC_CommonByteMatrix::~CBC_CommonByteMatrix()
+{
+ if(m_bytes != NULL) {
+ FX_Free(m_bytes);
+ m_bytes = NULL;
+ }
+}
+FX_INT32 CBC_CommonByteMatrix::GetHeight()
+{
+ return m_height;
+}
+FX_INT32 CBC_CommonByteMatrix::GetWidth()
+{
+ return m_width;
+}
+FX_BYTE CBC_CommonByteMatrix::Get(FX_INT32 x, FX_INT32 y)
+{
+ return m_bytes[y * m_width + x];
+}
+void CBC_CommonByteMatrix::Set(FX_INT32 x, FX_INT32 y, FX_INT32 value)
+{
+ m_bytes[y * m_width + x] = (FX_BYTE)value;
+}
+void CBC_CommonByteMatrix::Set(FX_INT32 x, FX_INT32 y, FX_BYTE value)
+{
+ m_bytes[y * m_width + x] = value;
+}
+void CBC_CommonByteMatrix::clear(FX_BYTE value)
+{
+ FX_INT32 y;
+ for(y = 0; y < m_height; y++) {
+ FX_INT32 x;
+ for(x = 0; x < m_width; x++) {
+ m_bytes[y * m_width + x] = value;
+ }
+ }
+}
+FX_BYTE* CBC_CommonByteMatrix::GetArray()
+{
+ return m_bytes;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonCharacterSetECI.cpp b/xfa/src/fxbarcode/src/BC_CommonCharacterSetECI.cpp
new file mode 100644
index 0000000000..8e10a7c700
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonCharacterSetECI.cpp
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonECI.h"
+#include "include/BC_CommonCharacterSetECI.h"
+void CBC_CommonCharacterSetECI::initialize()
+{
+}
+CBC_CommonCharacterSetECI::CBC_CommonCharacterSetECI(FX_INT32 value, CFX_ByteString encodingName):
+ CBC_CommonECI(value), m_encodingName(encodingName)
+{
+}
+CBC_CommonCharacterSetECI::~CBC_CommonCharacterSetECI()
+{
+}
+CFX_ByteString CBC_CommonCharacterSetECI::GetEncodingName()
+{
+ return m_encodingName;
+}
+void CBC_CommonCharacterSetECI::AddCharacterSet(FX_INT32 value, CFX_ByteString encodingName)
+{
+}
+CBC_CommonCharacterSetECI* CBC_CommonCharacterSetECI::GetCharacterSetECIByValue(FX_INT32 value)
+{
+ return NULL;
+}
+CBC_CommonCharacterSetECI* CBC_CommonCharacterSetECI::GetCharacterSetECIByName(const CFX_ByteString& name)
+{
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonDecoderResult.cpp b/xfa/src/fxbarcode/src/BC_CommonDecoderResult.cpp
new file mode 100644
index 0000000000..b61b23efd4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonDecoderResult.cpp
@@ -0,0 +1,63 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_PDF417ResultMetadata.h"
+#include "include/BC_CommonDecoderResult.h"
+CBC_CommonDecoderResult::CBC_CommonDecoderResult()
+{
+}
+void CBC_CommonDecoderResult::Init(const CFX_ByteArray &rawBytes, const CFX_ByteString &text, const CFX_Int32Array &byteSegments, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 &e)
+{
+ if(text.IsEmpty()) {
+ e = BCExceptionIllegalArgument;
+ return;
+ }
+ m_rawBytes.Copy(rawBytes);
+ m_text = text;
+ m_byteSegments.Copy(byteSegments);
+ m_ecLevel = ecLevel;
+ m_other = NULL;
+}
+void CBC_CommonDecoderResult::Init(const CFX_ByteArray &rawBytes, const CFX_ByteString &text, const CFX_PtrArray &byteSegments, const CFX_ByteString &ecLevel, FX_INT32 &e)
+{
+ if(text.IsEmpty()) {
+ e = BCExceptionIllegalArgument;
+ return;
+ }
+ m_rawBytes.Copy(rawBytes);
+ m_text = text;
+ m_pdf417byteSegments.Copy(byteSegments);
+ m_pdf417ecLevel = ecLevel;
+ m_other = NULL;
+}
+void CBC_CommonDecoderResult::setOther(CBC_PDF417ResultMetadata* other)
+{
+ m_other = other;
+}
+CBC_CommonDecoderResult::~CBC_CommonDecoderResult()
+{
+ if (m_other != NULL) {
+ delete m_other;
+ }
+}
+const CFX_ByteArray& CBC_CommonDecoderResult::GetRawBytes()
+{
+ return m_rawBytes;
+}
+const CFX_Int32Array& CBC_CommonDecoderResult::GetByteSegments()
+{
+ return m_byteSegments;
+}
+const CFX_ByteString& CBC_CommonDecoderResult::GetText()
+{
+ return m_text;
+}
+CBC_QRCoderErrorCorrectionLevel* CBC_CommonDecoderResult::GetECLevel()
+{
+ return m_ecLevel;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonECI.cpp b/xfa/src/fxbarcode/src/BC_CommonECI.cpp
new file mode 100644
index 0000000000..182a7fa4b4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonECI.cpp
@@ -0,0 +1,30 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonECI.h"
+#include "include/BC_CommonCharacterSetECI.h"
+CBC_CommonECI::CBC_CommonECI(FX_INT32 value)
+{
+ m_value = value;
+}
+CBC_CommonECI::~CBC_CommonECI()
+{
+}
+FX_INT32 CBC_CommonECI::GetValue()
+{
+ return m_value;
+}
+CBC_CommonECI* CBC_CommonECI::GetEICByValue(FX_INT32 value, FX_INT32 &e)
+{
+ if(value < 0 || value > 999999) {
+ e = BCExceptionBadECI;
+ return NULL;
+ }
+ if(value < 900) {
+ }
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/src/BC_CommonPerspectiveTransform.cpp b/xfa/src/fxbarcode/src/BC_CommonPerspectiveTransform.cpp
new file mode 100644
index 0000000000..98234729e5
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_CommonPerspectiveTransform.cpp
@@ -0,0 +1,109 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonPerspectiveTransform.h"
+CBC_CommonPerspectiveTransform::CBC_CommonPerspectiveTransform(FX_FLOAT a11, FX_FLOAT a21, FX_FLOAT a31,
+ FX_FLOAT a12, FX_FLOAT a22, FX_FLOAT a32,
+ FX_FLOAT a13, FX_FLOAT a23, FX_FLOAT a33) :
+ m_a11(a11), m_a21(a21), m_a31(a31),
+ m_a12(a12), m_a22(a22), m_a32(a32),
+ m_a13(a13), m_a23(a23), m_a33(a33)
+{
+}
+CBC_CommonPerspectiveTransform::~CBC_CommonPerspectiveTransform()
+{
+}
+CBC_CommonPerspectiveTransform *CBC_CommonPerspectiveTransform::QuadrilateralToQuadrilateral(FX_FLOAT x0, FX_FLOAT y0,
+ FX_FLOAT x1, FX_FLOAT y1,
+ FX_FLOAT x2, FX_FLOAT y2,
+ FX_FLOAT x3, FX_FLOAT y3,
+ FX_FLOAT x0p, FX_FLOAT y0p,
+ FX_FLOAT x1p, FX_FLOAT y1p,
+ FX_FLOAT x2p, FX_FLOAT y2p,
+ FX_FLOAT x3p, FX_FLOAT y3p)
+{
+ CBC_AutoPtr<CBC_CommonPerspectiveTransform> qToS(QuadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3));
+ CBC_AutoPtr<CBC_CommonPerspectiveTransform> sToQ(SquareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p));
+ return sToQ->Times(*(qToS.get()));
+}
+void CBC_CommonPerspectiveTransform::TransformPoints(CFX_FloatArray *points)
+{
+ FX_INT32 max = points->GetSize();
+ FX_FLOAT a11 = m_a11;
+ FX_FLOAT a12 = m_a12;
+ FX_FLOAT a13 = m_a13;
+ FX_FLOAT a21 = m_a21;
+ FX_FLOAT a22 = m_a22;
+ FX_FLOAT a23 = m_a23;
+ FX_FLOAT a31 = m_a31;
+ FX_FLOAT a32 = m_a32;
+ FX_FLOAT a33 = m_a33;
+ FX_INT32 i;
+ for (i = 0; i < max; i += 2) {
+ FX_FLOAT x = (*points)[i];
+ FX_FLOAT y = (*points)[i + 1];
+ FX_FLOAT denominator = a13 * x + a23 * y + a33;
+ (*points)[i] = (a11 * x + a21 * y + a31) / denominator;
+ (*points)[i + 1] = (a12 * x + a22 * y + a32) / denominator;
+ }
+}
+CBC_CommonPerspectiveTransform *CBC_CommonPerspectiveTransform::SquareToQuadrilateral(FX_FLOAT x0, FX_FLOAT y0,
+ FX_FLOAT x1, FX_FLOAT y1,
+ FX_FLOAT x2, FX_FLOAT y2,
+ FX_FLOAT x3, FX_FLOAT y3)
+{
+ FX_FLOAT dy2 = y3 - y2;
+ FX_FLOAT dy3 = y0 - y1 + y2 - y3;
+ if ((dy2 == 0.0f) && (dy3 == 0.0f)) {
+ return FX_NEW CBC_CommonPerspectiveTransform(x1 - x0, x2 - x1, x0,
+ y1 - y0, y2 - y1, y0,
+ 0.0f, 0.0f, 1.0f);
+ } else {
+ FX_FLOAT dx1 = x1 - x2;
+ FX_FLOAT dx2 = x3 - x2;
+ FX_FLOAT dx3 = x0 - x1 + x2 - x3;
+ FX_FLOAT dy1 = y1 - y2;
+ FX_FLOAT denominator = dx1 * dy2 - dx2 * dy1;
+ FX_FLOAT a13 = (dx3 * dy2 - dx2 * dy3) / denominator;
+ FX_FLOAT a23 = (dx1 * dy3 - dx3 * dy1) / denominator;
+ return FX_NEW CBC_CommonPerspectiveTransform(x1 - x0 + a13 * x1, x3 - x0 + a23 * x3, x0,
+ y1 - y0 + a13 * y1, y3 - y0 + a23 * y3, y0,
+ a13, a23, 1.0f);
+ }
+}
+CBC_CommonPerspectiveTransform *CBC_CommonPerspectiveTransform::QuadrilateralToSquare(FX_FLOAT x0, FX_FLOAT y0,
+ FX_FLOAT x1, FX_FLOAT y1,
+ FX_FLOAT x2, FX_FLOAT y2,
+ FX_FLOAT x3, FX_FLOAT y3)
+{
+ CBC_AutoPtr<CBC_CommonPerspectiveTransform> temp1(SquareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3));
+ return temp1->BuildAdjoint();
+}
+CBC_CommonPerspectiveTransform *CBC_CommonPerspectiveTransform::BuildAdjoint()
+{
+ return FX_NEW CBC_CommonPerspectiveTransform(m_a22 * m_a33 - m_a23 * m_a32,
+ m_a23 * m_a31 - m_a21 * m_a33,
+ m_a21 * m_a32 - m_a22 * m_a31,
+ m_a13 * m_a32 - m_a12 * m_a33,
+ m_a11 * m_a33 - m_a13 * m_a31,
+ m_a12 * m_a31 - m_a11 * m_a32,
+ m_a12 * m_a23 - m_a13 * m_a22,
+ m_a13 * m_a21 - m_a11 * m_a23,
+ m_a11 * m_a22 - m_a12 * m_a21);
+}
+CBC_CommonPerspectiveTransform *CBC_CommonPerspectiveTransform::Times(CBC_CommonPerspectiveTransform &other)
+{
+ return FX_NEW CBC_CommonPerspectiveTransform(m_a11 * other.m_a11 + m_a21 * other.m_a12 + m_a31 * other.m_a13,
+ m_a11 * other.m_a21 + m_a21 * other.m_a22 + m_a31 * other.m_a23,
+ m_a11 * other.m_a31 + m_a21 * other.m_a32 + m_a31 * other.m_a33,
+ m_a12 * other.m_a11 + m_a22 * other.m_a12 + m_a32 * other.m_a13,
+ m_a12 * other.m_a21 + m_a22 * other.m_a22 + m_a32 * other.m_a23,
+ m_a12 * other.m_a31 + m_a22 * other.m_a32 + m_a32 * other.m_a33,
+ m_a13 * other.m_a11 + m_a23 * other.m_a12 + m_a33 * other.m_a13,
+ m_a13 * other.m_a21 + m_a23 * other.m_a22 + m_a33 * other.m_a23,
+ m_a13 * other.m_a31 + m_a23 * other.m_a32 + m_a33 * other.m_a33);
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixBitMatrixParser.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixBitMatrixParser.cpp
new file mode 100644
index 0000000000..9fa79aad7d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixBitMatrixParser.cpp
@@ -0,0 +1,350 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_DataMatrixVersion.h"
+#include "include/BC_DataMatrixBitMatrixParser.h"
+CBC_DataMatrixBitMatrixParser::CBC_DataMatrixBitMatrixParser()
+{
+ m_mappingBitMatrix = NULL;
+ m_version = NULL;
+ m_readMappingMatrix = NULL;
+}
+void CBC_DataMatrixBitMatrixParser::Init(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e)
+{
+ FX_INT32 dimension = bitMatrix->GetHeight();
+ if (dimension < 8 || dimension > 144 || (dimension & 0x01) != 0) {
+ e = BCExceptionFormatException;
+ return;
+ }
+ m_version = ReadVersion(bitMatrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ m_mappingBitMatrix = ExtractDataRegion(bitMatrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ m_readMappingMatrix = FX_NEW CBC_CommonBitMatrix();
+ m_readMappingMatrix->Init(m_mappingBitMatrix->GetWidth(), m_mappingBitMatrix->GetHeight());
+}
+CBC_DataMatrixBitMatrixParser::~CBC_DataMatrixBitMatrixParser()
+{
+ if(m_mappingBitMatrix != NULL) {
+ delete m_mappingBitMatrix;
+ }
+ m_mappingBitMatrix = NULL;
+ if(m_readMappingMatrix != NULL) {
+ delete m_readMappingMatrix;
+ }
+ m_readMappingMatrix = NULL;
+}
+CBC_DataMatrixVersion *CBC_DataMatrixBitMatrixParser::GetVersion()
+{
+ return m_version;
+}
+CBC_DataMatrixVersion *CBC_DataMatrixBitMatrixParser::ReadVersion(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e)
+{
+ FX_INT32 rows = bitMatrix->GetHeight();
+ FX_INT32 columns = bitMatrix->GetWidth();
+ CBC_DataMatrixVersion *temp = CBC_DataMatrixVersion::GetVersionForDimensions(rows, columns, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+CFX_ByteArray *CBC_DataMatrixBitMatrixParser::ReadCodewords(FX_INT32 &e)
+{
+ CBC_AutoPtr<CFX_ByteArray> result(FX_NEW CFX_ByteArray());
+ result->SetSize(m_version->GetTotalCodewords());
+ FX_INT32 resultOffset = 0;
+ FX_INT32 row = 4;
+ FX_INT32 column = 0;
+ FX_INT32 numRows = m_mappingBitMatrix->GetHeight();
+ FX_INT32 numColumns = m_mappingBitMatrix->GetWidth();
+ FX_BOOL corner1Read = FALSE;
+ FX_BOOL corner2Read = FALSE;
+ FX_BOOL corner3Read = FALSE;
+ FX_BOOL corner4Read = FALSE;
+ do {
+ if ((row == numRows) && (column == 0) && !corner1Read) {
+ (*result)[resultOffset++] = (FX_BYTE) ReadCorner1(numRows, numColumns);
+ row -= 2;
+ column += 2;
+ corner1Read = TRUE;
+ } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x03) != 0) && !corner2Read) {
+ (*result)[resultOffset++] = (FX_BYTE) ReadCorner2(numRows, numColumns);
+ row -= 2;
+ column += 2;
+ corner2Read = TRUE;
+ } else if ((row == numRows + 4) && (column == 2) && ((numColumns & 0x07) == 0) && !corner3Read) {
+ (*result)[resultOffset++] = (FX_BYTE) ReadCorner3(numRows, numColumns);
+ row -= 2;
+ column += 2;
+ corner3Read = TRUE;
+ } else if ((row == numRows - 2) && (column == 0) && ((numColumns & 0x07) == 4) && !corner4Read) {
+ (*result)[resultOffset++] = (FX_BYTE) ReadCorner4(numRows, numColumns);
+ row -= 2;
+ column += 2;
+ corner4Read = TRUE;
+ } else {
+ do {
+ if ((row < numRows) && (column >= 0) && !m_readMappingMatrix->Get(column, row)) {
+ if (resultOffset < (*result).GetSize() ) {
+ (*result)[resultOffset++] = (FX_BYTE) ReadUtah(row, column, numRows, numColumns);
+ }
+ }
+ row -= 2;
+ column += 2;
+ } while ((row >= 0) && (column < numColumns));
+ row += 1;
+ column += 3;
+ do {
+ if ((row >= 0) && (column < numColumns) && !m_readMappingMatrix->Get(column, row)) {
+ if (resultOffset < (*result).GetSize() ) {
+ (*result)[resultOffset++] = (FX_BYTE) ReadUtah(row, column, numRows, numColumns);
+ }
+ }
+ row += 2;
+ column -= 2;
+ } while ((row < numRows) && (column >= 0));
+ row += 3;
+ column += 1;
+ }
+ } while ((row < numRows) || (column < numColumns));
+ if (resultOffset != m_version->GetTotalCodewords()) {
+ e = BCExceptionFormatException;
+ return NULL;
+ }
+ return result.release();
+}
+FX_BOOL CBC_DataMatrixBitMatrixParser::ReadModule(FX_INT32 row, FX_INT32 column, FX_INT32 numRows, FX_INT32 numColumns)
+{
+ if (row < 0) {
+ row += numRows;
+ column += 4 - ((numRows + 4) & 0x07);
+ }
+ if (column < 0) {
+ column += numColumns;
+ row += 4 - ((numColumns + 4) & 0x07);
+ }
+ m_readMappingMatrix->Set(column, row);
+ return m_mappingBitMatrix->Get(column, row);
+}
+FX_INT32 CBC_DataMatrixBitMatrixParser::ReadUtah(FX_INT32 row, FX_INT32 column, FX_INT32 numRows, FX_INT32 numColumns)
+{
+ FX_INT32 currentByte = 0;
+ if (ReadModule(row - 2, column - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(row - 2, column - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(row - 1, column - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(row - 1, column - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(row - 1, column, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(row, column - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(row, column - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(row, column, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+FX_INT32 CBC_DataMatrixBitMatrixParser::ReadCorner1(FX_INT32 numRows, FX_INT32 numColumns)
+{
+ FX_INT32 currentByte = 0;
+ if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(numRows - 1, 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(numRows - 1, 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(2, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(3, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+FX_INT32 CBC_DataMatrixBitMatrixParser::ReadCorner2(FX_INT32 numRows, FX_INT32 numColumns)
+{
+ FX_INT32 currentByte = 0;
+ if (ReadModule(numRows - 3, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(numRows - 2, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 4, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 3, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+FX_INT32 CBC_DataMatrixBitMatrixParser::ReadCorner3(FX_INT32 numRows, FX_INT32 numColumns)
+{
+ FX_INT32 currentByte = 0;
+ if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(numRows - 1, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 3, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(1, numColumns - 3, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(1, numColumns - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+FX_INT32 CBC_DataMatrixBitMatrixParser::ReadCorner4(FX_INT32 numRows, FX_INT32 numColumns)
+{
+ FX_INT32 currentByte = 0;
+ if (ReadModule(numRows - 3, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(numRows - 2, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(numRows - 1, 0, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 2, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(0, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(1, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(2, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ currentByte <<= 1;
+ if (ReadModule(3, numColumns - 1, numRows, numColumns)) {
+ currentByte |= 1;
+ }
+ return currentByte;
+}
+CBC_CommonBitMatrix *CBC_DataMatrixBitMatrixParser::ExtractDataRegion(CBC_CommonBitMatrix *bitMatrix , FX_INT32 &e)
+{
+ FX_INT32 symbolSizeRows = m_version->GetSymbolSizeRows();
+ FX_INT32 symbolSizeColumns = m_version->GetSymbolSizeColumns();
+ if (bitMatrix->GetHeight() != symbolSizeRows) {
+ e = BCExceptionCanNotCallGetDimensionOnNonSquareMatrix;
+ return NULL;
+ }
+ FX_INT32 dataRegionSizeRows = m_version->GetDataRegionSizeRows();
+ FX_INT32 dataRegionSizeColumns = m_version->GetDataRegionSizeColumns();
+ FX_INT32 numDataRegionsRow = symbolSizeRows / dataRegionSizeRows;
+ FX_INT32 numDataRegionsColumn = symbolSizeColumns / dataRegionSizeColumns;
+ FX_INT32 sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;
+ FX_INT32 sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;
+ CBC_CommonBitMatrix *bitMatrixWithoutAlignment = FX_NEW CBC_CommonBitMatrix();
+ bitMatrixWithoutAlignment->Init(sizeDataRegionColumn, sizeDataRegionRow);
+ FX_INT32 dataRegionRow;
+ for (dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {
+ FX_INT32 dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;
+ FX_INT32 dataRegionColumn;
+ for (dataRegionColumn = 0; dataRegionColumn < numDataRegionsColumn; ++dataRegionColumn) {
+ FX_INT32 dataRegionColumnOffset = dataRegionColumn * dataRegionSizeColumns;
+ FX_INT32 i;
+ for (i = 0; i < dataRegionSizeRows; ++i) {
+ FX_INT32 readRowOffset = dataRegionRow * (dataRegionSizeRows + 2) + 1 + i;
+ FX_INT32 writeRowOffset = dataRegionRowOffset + i;
+ FX_INT32 j;
+ for (j = 0; j < dataRegionSizeColumns; ++j) {
+ FX_INT32 readColumnOffset = dataRegionColumn * (dataRegionSizeColumns + 2) + 1 + j;
+ if (bitMatrix->Get(readColumnOffset, readRowOffset)) {
+ FX_INT32 writeColumnOffset = dataRegionColumnOffset + j;
+ bitMatrixWithoutAlignment->Set(writeColumnOffset, writeRowOffset);
+ }
+ }
+ }
+ }
+ }
+ return bitMatrixWithoutAlignment;
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixDataBlock.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixDataBlock.cpp
new file mode 100644
index 0000000000..55c61dedc9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixDataBlock.cpp
@@ -0,0 +1,83 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_DataMatrixVersion.h"
+#include "include/BC_DataMatrixDataBlock.h"
+CBC_DataMatrixDataBlock::~CBC_DataMatrixDataBlock()
+{
+}
+CBC_DataMatrixDataBlock::CBC_DataMatrixDataBlock(FX_INT32 numDataCodewords, CFX_ByteArray *codewords)
+{
+ m_codewords.Copy(*codewords);
+ m_numDataCodewords = numDataCodewords;
+}
+CFX_PtrArray *CBC_DataMatrixDataBlock::GetDataBlocks(CFX_ByteArray* rawCodewords, CBC_DataMatrixVersion *version, FX_INT32 &e)
+{
+ ECBlocks *ecBlocks = version->GetECBlocks();
+ FX_INT32 totalBlocks = 0;
+ const CFX_PtrArray &ecBlockArray = ecBlocks->GetECBlocks();
+ FX_INT32 i;
+ for (i = 0; i < ecBlockArray.GetSize(); i++) {
+ totalBlocks += ((ECB*)ecBlockArray[i])->GetCount();
+ }
+ CBC_AutoPtr<CFX_PtrArray>result(FX_NEW CFX_PtrArray());
+ result->SetSize(totalBlocks);
+ FX_INT32 numResultBlocks = 0;
+ FX_INT32 j;
+ for (j = 0; j < ecBlockArray.GetSize(); j++) {
+ for (i = 0; i < ((ECB*)ecBlockArray[j])->GetCount(); i++) {
+ FX_INT32 numDataCodewords = ((ECB*)ecBlockArray[j])->GetDataCodewords();
+ FX_INT32 numBlockCodewords = ecBlocks->GetECCodewords() + numDataCodewords;
+ CFX_ByteArray codewords;
+ codewords.SetSize(numBlockCodewords);
+ (*result)[numResultBlocks++] = FX_NEW CBC_DataMatrixDataBlock(numDataCodewords, &codewords);
+ codewords.SetSize(0);
+ }
+ }
+ FX_INT32 longerBlocksTotalCodewords = ((CBC_DataMatrixDataBlock*)(*result)[0])->GetCodewords()->GetSize();
+ FX_INT32 longerBlocksNumDataCodewords = longerBlocksTotalCodewords - ecBlocks->GetECCodewords();
+ FX_INT32 shorterBlocksNumDataCodewords = longerBlocksNumDataCodewords - 1;
+ FX_INT32 rawCodewordsOffset = 0;
+ for (i = 0; i < shorterBlocksNumDataCodewords; i++) {
+ FX_INT32 j;
+ for (j = 0; j < numResultBlocks; j++) {
+ if (rawCodewordsOffset < rawCodewords->GetSize()) {
+ ((CBC_DataMatrixDataBlock*)(*result)[j])->GetCodewords()->operator [](i) = (*rawCodewords)[rawCodewordsOffset++];
+ }
+ }
+ }
+ FX_BOOL specialVersion = version->GetVersionNumber() == 24;
+ FX_INT32 numLongerBlocks = specialVersion ? 8 : numResultBlocks;
+ for (j = 0; j < numLongerBlocks; j++) {
+ if (rawCodewordsOffset < rawCodewords->GetSize()) {
+ ((CBC_DataMatrixDataBlock*)(*result)[j])->GetCodewords()->operator [](longerBlocksNumDataCodewords - 1) = (*rawCodewords)[rawCodewordsOffset++];
+ }
+ }
+ FX_INT32 max = ((CBC_DataMatrixDataBlock*)(*result)[0])->GetCodewords()->GetSize();
+ for (i = longerBlocksNumDataCodewords; i < max; i++) {
+ FX_INT32 j;
+ for (j = 0; j < numResultBlocks; j++) {
+ FX_INT32 iOffset = specialVersion && j > 7 ? i - 1 : i;
+ if (rawCodewordsOffset < rawCodewords->GetSize()) {
+ ((CBC_DataMatrixDataBlock*)(*result)[j])->GetCodewords()->operator [](iOffset) = (*rawCodewords)[rawCodewordsOffset++];
+ }
+ }
+ }
+ if (rawCodewordsOffset != rawCodewords->GetSize()) {
+ e = BCExceptionIllegalArgument;
+ return NULL;
+ }
+ return result.release();
+}
+FX_INT32 CBC_DataMatrixDataBlock::GetNumDataCodewords()
+{
+ return m_numDataCodewords;
+}
+CFX_ByteArray *CBC_DataMatrixDataBlock::GetCodewords()
+{
+ return &m_codewords;
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixDecodedBitStreamParser.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixDecodedBitStreamParser.cpp
new file mode 100644
index 0000000000..6880f2487a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixDecodedBitStreamParser.cpp
@@ -0,0 +1,456 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_DataMatrixDecodedBitStreamParser.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_CommonBitSource.h"
+const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::C40_BASIC_SET_CHARS[] = {
+ '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
+};
+const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::C40_SHIFT2_SET_CHARS[] = {
+ '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.',
+ '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_'
+};
+const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::TEXT_BASIC_SET_CHARS[] = {
+ '*', '*', '*', ' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
+};
+const FX_CHAR CBC_DataMatrixDecodedBitStreamParser::TEXT_SHIFT3_SET_CHARS[] = {
+ '\'', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', (FX_CHAR) 127
+};
+const FX_INT32 CBC_DataMatrixDecodedBitStreamParser::PAD_ENCODE = 0;
+const FX_INT32 CBC_DataMatrixDecodedBitStreamParser::ASCII_ENCODE = 1;
+const FX_INT32 CBC_DataMatrixDecodedBitStreamParser::C40_ENCODE = 2;
+const FX_INT32 CBC_DataMatrixDecodedBitStreamParser::TEXT_ENCODE = 3;
+const FX_INT32 CBC_DataMatrixDecodedBitStreamParser::ANSIX12_ENCODE = 4;
+const FX_INT32 CBC_DataMatrixDecodedBitStreamParser::EDIFACT_ENCODE = 5;
+const FX_INT32 CBC_DataMatrixDecodedBitStreamParser::BASE256_ENCODE = 6;
+CBC_DataMatrixDecodedBitStreamParser::CBC_DataMatrixDecodedBitStreamParser()
+{
+}
+CBC_DataMatrixDecodedBitStreamParser::~CBC_DataMatrixDecodedBitStreamParser()
+{
+}
+CBC_CommonDecoderResult *CBC_DataMatrixDecodedBitStreamParser::Decode(CFX_ByteArray &bytes, FX_INT32 &e)
+{
+ CBC_CommonBitSource bits(&bytes);
+ CFX_ByteString result;
+ CFX_ByteString resultTrailer;
+ CFX_Int32Array byteSegments;
+ FX_INT32 mode = ASCII_ENCODE;
+ do {
+ if (mode == 1) {
+ mode = DecodeAsciiSegment(&bits, result, resultTrailer, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else {
+ switch (mode) {
+ case 2:
+ DecodeC40Segment(&bits, result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ break;
+ case 3:
+ DecodeTextSegment(&bits, result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ break;
+ case 4:
+ DecodeAnsiX12Segment(&bits, result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ break;
+ case 5:
+ DecodeEdifactSegment(&bits, result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ break;
+ case 6:
+ DecodeBase256Segment(&bits, result, byteSegments, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ break;
+ default:
+ NULL;
+ e = BCExceptionFormatException;
+ return NULL;
+ }
+ mode = ASCII_ENCODE;
+ }
+ } while (mode != PAD_ENCODE && bits.Available() > 0);
+ if (resultTrailer.GetLength() > 0) {
+ result += resultTrailer;
+ }
+ CBC_CommonDecoderResult *tempCp = FX_NEW CBC_CommonDecoderResult();
+ tempCp->Init(bytes, result, (byteSegments.GetSize() <= 0) ? CFX_Int32Array() : byteSegments, NULL, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return tempCp;
+}
+FX_INT32 CBC_DataMatrixDecodedBitStreamParser::DecodeAsciiSegment(CBC_CommonBitSource *bits, CFX_ByteString &result, CFX_ByteString &resultTrailer, FX_INT32 &e)
+{
+ FX_CHAR buffer[128];
+ FX_BOOL upperShift = FALSE;
+ do {
+ FX_INT32 oneByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ if (oneByte == 0) {
+ e = BCExceptionFormatException;
+ return 0;
+ } else if (oneByte <= 128) {
+ oneByte = upperShift ? oneByte + 128 : oneByte;
+ upperShift = FALSE;
+ result += ((FX_CHAR) (oneByte - 1));
+ return ASCII_ENCODE;
+ } else if (oneByte == 129) {
+ return PAD_ENCODE;
+ } else if (oneByte <= 229) {
+ FX_INT32 value = oneByte - 130;
+#if defined(_FX_WINAPI_PARTITION_APP_)
+ memset(buffer, 0, sizeof(FX_CHAR) * 128);
+ _itoa_s(value, buffer, 128, 10);
+#else
+ FXSYS_itoa(value, buffer, 10);
+#endif
+ if (value < 10) {
+ result += '0';
+ buffer[1] = '\0';
+ } else {
+ buffer[2] = '\0';
+ }
+ result += buffer;
+ } else if (oneByte == 230) {
+ return C40_ENCODE;
+ } else if (oneByte == 231) {
+ return BASE256_ENCODE;
+ } else if (oneByte == 232 || oneByte == 233 || oneByte == 234) {
+ } else if (oneByte == 235) {
+ upperShift = TRUE;
+ } else if (oneByte == 236) {
+ result += "[)>";
+ result += 0x1E;
+ result += "05";
+ result += 0x1D;
+ resultTrailer.Insert(0, 0x1E);
+ resultTrailer.Insert(0 + 1, 0x04);
+ } else if (oneByte == 237) {
+ result += "[)>";
+ result += 0x1E;
+ result += "06";
+ result += 0x1D;
+ resultTrailer.Insert(0, 0x1E);
+ resultTrailer.Insert(0 + 1, 0x04);
+ } else if (oneByte == 238) {
+ return ANSIX12_ENCODE;
+ } else if (oneByte == 239) {
+ return TEXT_ENCODE;
+ } else if (oneByte == 240) {
+ return EDIFACT_ENCODE;
+ } else if (oneByte == 241) {
+ } else if (oneByte >= 242) {
+ if (oneByte == 254 && bits->Available() == 0) {
+ } else {
+ e = BCExceptionFormatException;
+ return 0;
+ }
+ }
+ } while (bits->Available() > 0);
+ return ASCII_ENCODE;
+}
+void CBC_DataMatrixDecodedBitStreamParser::DecodeC40Segment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e)
+{
+ FX_BOOL upperShift = FALSE;
+ CFX_Int32Array cValues;
+ cValues.SetSize(3);
+ do {
+ if (bits->Available() == 8) {
+ return;
+ }
+ FX_INT32 firstByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if (firstByte == 254) {
+ return;
+ }
+ FX_INT32 tempp = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ ParseTwoBytes(firstByte, tempp, cValues);
+ FX_INT32 shift = 0;
+ FX_INT32 i;
+ for (i = 0; i < 3; i++) {
+ FX_INT32 cValue = cValues[i];
+ switch (shift) {
+ case 0:
+ if (cValue < 3) {
+ shift = cValue + 1;
+ } else if (cValue < 27) {
+ FX_CHAR c40char = C40_BASIC_SET_CHARS[cValue];
+ if (upperShift) {
+ result += (FX_CHAR) (c40char + 128);
+ upperShift = FALSE;
+ } else {
+ result += c40char;
+ }
+ } else {
+ e = BCExceptionFormatException;
+ return ;
+ }
+ break;
+ case 1:
+ if (upperShift) {
+ result += (FX_CHAR) (cValue + 128);
+ upperShift = FALSE;
+ } else {
+ result += cValue;
+ }
+ shift = 0;
+ break;
+ case 2:
+ if (cValue < 27) {
+ FX_CHAR c40char = C40_SHIFT2_SET_CHARS[cValue];
+ if (upperShift) {
+ result += (FX_CHAR) (c40char + 128);
+ upperShift = FALSE;
+ } else {
+ result += c40char;
+ }
+ } else if (cValue == 27) {
+ e = BCExceptionFormatException;
+ return;
+ } else if (cValue == 30) {
+ upperShift = TRUE;
+ } else {
+ e = BCExceptionFormatException;
+ return;
+ }
+ shift = 0;
+ break;
+ case 3:
+ if (upperShift) {
+ result += (FX_CHAR) (cValue + 224);
+ upperShift = FALSE;
+ } else {
+ result += (FX_CHAR) (cValue + 96);
+ }
+ shift = 0;
+ break;
+ default:
+ break;
+ e = BCExceptionFormatException;
+ return;
+ }
+ }
+ } while (bits->Available() > 0);
+}
+void CBC_DataMatrixDecodedBitStreamParser::DecodeTextSegment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e)
+{
+ FX_BOOL upperShift = FALSE;
+ CFX_Int32Array cValues;
+ cValues.SetSize(3);
+ FX_INT32 shift = 0;
+ do {
+ if (bits->Available() == 8) {
+ return;
+ }
+ FX_INT32 firstByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if (firstByte == 254) {
+ return;
+ }
+ FX_INT32 inTp = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ ParseTwoBytes(firstByte, inTp, cValues);
+ for (FX_INT32 i = 0; i < 3; i++) {
+ FX_INT32 cValue = cValues[i];
+ switch (shift) {
+ case 0:
+ if (cValue < 3) {
+ shift = cValue + 1;
+ } else if (cValue < 40) {
+ FX_CHAR textChar = TEXT_BASIC_SET_CHARS[cValue];
+ if (upperShift) {
+ result += (FX_CHAR) (textChar + 128);
+ upperShift = FALSE;
+ } else {
+ result += textChar;
+ }
+ } else {
+ e = BCExceptionFormatException;
+ return;
+ }
+ break;
+ case 1:
+ if (upperShift) {
+ result += (FX_CHAR) (cValue + 128);
+ upperShift = FALSE;
+ } else {
+ result += cValue;
+ }
+ shift = 0;
+ break;
+ case 2:
+ if (cValue < 27) {
+ FX_CHAR c40char = C40_SHIFT2_SET_CHARS[cValue];
+ if (upperShift) {
+ result += (FX_CHAR) (c40char + 128);
+ upperShift = FALSE;
+ } else {
+ result += c40char;
+ }
+ } else if (cValue == 27) {
+ e = BCExceptionFormatException;
+ return;
+ } else if (cValue == 30) {
+ upperShift = TRUE;
+ } else {
+ e = BCExceptionFormatException;
+ return;
+ }
+ shift = 0;
+ break;
+ case 3:
+ if (cValue < 19) {
+ FX_CHAR textChar = TEXT_SHIFT3_SET_CHARS[cValue];
+ if (upperShift) {
+ result += (FX_CHAR) (textChar + 128);
+ upperShift = FALSE;
+ } else {
+ result += textChar;
+ }
+ shift = 0;
+ } else {
+ e = BCExceptionFormatException;
+ return;
+ }
+ break;
+ default:
+ break;
+ e = BCExceptionFormatException;
+ return;
+ }
+ }
+ } while (bits->Available() > 0);
+}
+void CBC_DataMatrixDecodedBitStreamParser::DecodeAnsiX12Segment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e)
+{
+ CFX_Int32Array cValues;
+ cValues.SetSize(3);
+ do {
+ if (bits->Available() == 8) {
+ return;
+ }
+ FX_INT32 firstByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if (firstByte == 254) {
+ return;
+ }
+ FX_INT32 iTemp1 = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ ParseTwoBytes(firstByte, iTemp1, cValues);
+ FX_INT32 i;
+ for (i = 0; i < 3; i++) {
+ FX_INT32 cValue = cValues[i];
+ if (cValue == 0) {
+ BC_FX_ByteString_Append(result, 1, '\r');
+ } else if (cValue == 1) {
+ BC_FX_ByteString_Append(result, 1, '*');
+ } else if (cValue == 2) {
+ BC_FX_ByteString_Append(result, 1, '>');
+ } else if (cValue == 3) {
+ BC_FX_ByteString_Append(result, 1, ' ');
+ } else if (cValue < 14) {
+ BC_FX_ByteString_Append(result, 1, (FX_CHAR) (cValue + 44));
+ } else if (cValue < 40) {
+ BC_FX_ByteString_Append(result, 1, (FX_CHAR) (cValue + 51));
+ } else {
+ e = BCExceptionFormatException;
+ return;
+ }
+ }
+ } while (bits->Available() > 0);
+}
+void CBC_DataMatrixDecodedBitStreamParser::ParseTwoBytes(FX_INT32 firstByte, FX_INT32 secondByte, CFX_Int32Array &result)
+{
+ FX_INT32 fullBitValue = (firstByte << 8) + secondByte - 1;
+ FX_INT32 temp = fullBitValue / 1600;
+ result[0] = temp;
+ fullBitValue -= temp * 1600;
+ temp = fullBitValue / 40;
+ result[1] = temp;
+ result[2] = fullBitValue - temp * 40;
+}
+void CBC_DataMatrixDecodedBitStreamParser::DecodeEdifactSegment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e)
+{
+ FX_CHAR buffer[128];
+ FX_BOOL unlatch = FALSE;
+ do {
+ if (bits->Available() <= 16) {
+ return;
+ }
+ FX_INT32 i;
+ for (i = 0; i < 4; i++) {
+ FX_INT32 edifactValue = bits->ReadBits(6, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if (edifactValue == 0x1F) {
+ unlatch = TRUE;
+ }
+ if (!unlatch) {
+ if ((edifactValue & 32) == 0) {
+ edifactValue |= 64;
+ }
+#if defined(_FX_WINAPI_PARTITION_APP_)
+ memset(buffer, 0, sizeof(FX_CHAR) * 128);
+ _itoa_s(edifactValue, buffer, 128, 10);
+ result += buffer;
+#else
+ result += FXSYS_itoa(edifactValue, buffer, 10);
+#endif
+ }
+ }
+ } while (!unlatch && bits->Available() > 0);
+}
+void CBC_DataMatrixDecodedBitStreamParser::DecodeBase256Segment(CBC_CommonBitSource *bits, CFX_ByteString &result, CFX_Int32Array &byteSegments, FX_INT32 &e)
+{
+ FX_INT32 codewordPosition = 1 + bits->getByteOffset();
+ FX_INT32 iTmp = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 d1 = Unrandomize255State(iTmp, codewordPosition++);
+ FX_INT32 count;
+ if (d1 == 0) {
+ count = bits->Available() / 8;
+ } else if (d1 < 250) {
+ count = d1;
+ } else {
+ FX_INT32 iTmp3 = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ count = 250 * (d1 - 249) + Unrandomize255State(iTmp3, codewordPosition++);
+ }
+ if (count < 0) {
+ e = BCExceptionFormatException;
+ return;
+ }
+ CFX_ByteArray *bytes = FX_NEW CFX_ByteArray();
+ bytes->SetSize(count);
+ FX_INT32 i;
+ for (i = 0; i < count; i++) {
+ if (bits->Available() < 8) {
+ e = BCExceptionFormatException;
+ delete bytes;
+ return;
+ }
+ FX_INT32 iTemp5 = bits->ReadBits(8, e);
+ if (e != BCExceptionNO) {
+ delete bytes;
+ return;
+ }
+ bytes->SetAt(i, Unrandomize255State(iTemp5, codewordPosition++));
+ }
+ BC_FX_ByteString_Append(result, *bytes);
+ delete bytes;
+}
+FX_BYTE CBC_DataMatrixDecodedBitStreamParser::Unrandomize255State(FX_INT32 randomizedBase256Codeword, FX_INT32 base256CodewordPosition)
+{
+ FX_INT32 pseudoRandomNumber = ((149 * base256CodewordPosition) % 255) + 1;
+ FX_INT32 tempVariable = randomizedBase256Codeword - pseudoRandomNumber;
+ return (FX_BYTE) (tempVariable >= 0 ? tempVariable : tempVariable + 256);
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixDecoder.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixDecoder.cpp
new file mode 100644
index 0000000000..26c43201ae
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixDecoder.cpp
@@ -0,0 +1,94 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_DataMatrixDecoder.h"
+#include "include/BC_ReedSolomonDecoder.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_DataMatrixBitMatrixParser.h"
+#include "include/BC_DataMatrixVersion.h"
+#include "include/BC_DataMatrixDataBlock.h"
+#include "include/BC_DataMatrixDecodedBitStreamParser.h"
+CBC_DataMatrixDecoder::CBC_DataMatrixDecoder()
+{
+ m_rsDecoder = NULL;
+}
+void CBC_DataMatrixDecoder::Init()
+{
+ m_rsDecoder = FX_NEW CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::DataMatrixField);
+}
+CBC_DataMatrixDecoder::~CBC_DataMatrixDecoder()
+{
+ if(m_rsDecoder != NULL) {
+ delete m_rsDecoder;
+ }
+ m_rsDecoder = NULL;
+}
+CBC_CommonDecoderResult *CBC_DataMatrixDecoder::Decode(CBC_CommonBitMatrix *bits, FX_INT32 &e)
+{
+ CBC_DataMatrixBitMatrixParser parser;
+ parser.Init(bits, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_DataMatrixVersion *version = parser.GetVersion();
+ CFX_ByteArray* byteTemp = parser.ReadCodewords(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CFX_ByteArray> codewords(byteTemp);
+ CFX_PtrArray *dataBlocks = CBC_DataMatrixDataBlock::GetDataBlocks(codewords.get(), version, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 dataBlocksCount = dataBlocks->GetSize();
+ FX_INT32 totalBytes = 0;
+ FX_INT32 i, j;
+ for (i = 0; i < dataBlocksCount; i++) {
+ totalBytes += ((CBC_DataMatrixDataBlock*)(*dataBlocks)[i])->GetNumDataCodewords();
+ }
+ CFX_ByteArray resultBytes;
+ resultBytes.SetSize(totalBytes);
+ for (j = 0; j < dataBlocksCount; j++) {
+ CFX_ByteArray *codewordBytes = ((CBC_DataMatrixDataBlock*)(*dataBlocks)[j])->GetCodewords();
+ FX_INT32 numDataCodewords = ((CBC_DataMatrixDataBlock*)(*dataBlocks)[j])->GetNumDataCodewords();
+ CorrectErrors(*codewordBytes, numDataCodewords, e);
+ if (e != BCExceptionNO) {
+ for(FX_INT32 i = 0; i < dataBlocks->GetSize(); i++) {
+ delete (CBC_DataMatrixDataBlock*)(*dataBlocks)[i];
+ }
+ delete dataBlocks;
+ dataBlocks = NULL;
+ return NULL;
+ }
+ FX_INT32 i;
+ for (i = 0; i < numDataCodewords; i++) {
+ resultBytes[i * dataBlocksCount + j] = (*codewordBytes)[i];
+ }
+ }
+ for(i = 0; i < (dataBlocks->GetSize()); i++) {
+ delete (CBC_DataMatrixDataBlock*)(*dataBlocks)[i];
+ }
+ delete dataBlocks;
+ dataBlocks = NULL;
+ CBC_CommonDecoderResult *resultR = CBC_DataMatrixDecodedBitStreamParser::Decode(resultBytes, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return resultR;
+}
+void CBC_DataMatrixDecoder::CorrectErrors(CFX_ByteArray &codewordBytes, FX_INT32 numDataCodewords, FX_INT32 &e)
+{
+ FX_INT32 numCodewords = codewordBytes.GetSize();
+ CFX_Int32Array codewordsInts;
+ codewordsInts.SetSize(numCodewords);
+ FX_INT32 i;
+ for (i = 0; i < numCodewords; i++) {
+ codewordsInts[i] = codewordBytes[i] & 0xFF;
+ }
+ FX_INT32 numECCodewords = codewordBytes.GetSize() - numDataCodewords;
+ m_rsDecoder->Decode(&codewordsInts, numECCodewords, e);
+ if (e != BCExceptionNO) {
+ e = BCExceptionChecksumException;
+ return ;
+ }
+ for (i = 0; i < numDataCodewords; i++) {
+ codewordBytes[i] = (FX_BYTE) codewordsInts[i];
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixDetector.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixDetector.cpp
new file mode 100644
index 0000000000..086b7a3a50
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixDetector.cpp
@@ -0,0 +1,352 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_DataMatrixDetector.h"
+#include "include/BC_WhiteRectangleDetector.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRFinderPatternFinder.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRDetectorResult.h"
+#include "include/BC_QRGridSampler.h"
+const FX_INT32 CBC_DataMatrixDetector::INTEGERS[5] = {0, 1, 2, 3, 4};
+CBC_DataMatrixDetector::CBC_DataMatrixDetector(CBC_CommonBitMatrix *image):
+ m_image(image), m_rectangleDetector(NULL)
+{
+}
+void CBC_DataMatrixDetector::Init(FX_INT32 &e)
+{
+ m_rectangleDetector = FX_NEW CBC_WhiteRectangleDetector(m_image);
+ m_rectangleDetector->Init(e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+CBC_DataMatrixDetector::~CBC_DataMatrixDetector()
+{
+ if(m_rectangleDetector != NULL) {
+ delete m_rectangleDetector;
+ }
+ m_rectangleDetector = NULL;
+}
+inline FX_BOOL ResultPointsAndTransitionsComparator(FX_LPVOID a, FX_LPVOID b)
+{
+ return ((CBC_ResultPointsAndTransitions *)b)->GetTransitions() > ((CBC_ResultPointsAndTransitions *)a)->GetTransitions();
+}
+CBC_QRDetectorResult *CBC_DataMatrixDetector::Detect(FX_INT32 &e)
+{
+ CFX_PtrArray* cornerPoints = m_rectangleDetector->Detect(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_ResultPoint *pointA = (CBC_ResultPoint*)(*cornerPoints)[0];
+ CBC_ResultPoint *pointB = (CBC_ResultPoint*)(*cornerPoints)[1];
+ CBC_ResultPoint *pointC = (CBC_ResultPoint*)(*cornerPoints)[2];
+ CBC_ResultPoint *pointD = (CBC_ResultPoint*)(*cornerPoints)[3];
+ delete cornerPoints;
+ cornerPoints = NULL;
+ CFX_PtrArray transitions;
+ transitions.Add(TransitionsBetween(pointA, pointB));
+ transitions.Add(TransitionsBetween(pointA, pointC));
+ transitions.Add(TransitionsBetween(pointB, pointD));
+ transitions.Add(TransitionsBetween(pointC, pointD));
+ BC_FX_PtrArray_Sort(transitions, &ResultPointsAndTransitionsComparator);
+ delete ( (CBC_ResultPointsAndTransitions *)transitions[2] );
+ delete ( (CBC_ResultPointsAndTransitions *)transitions[3] );
+ CBC_ResultPointsAndTransitions *lSideOne = (CBC_ResultPointsAndTransitions*)transitions[0];
+ CBC_ResultPointsAndTransitions *lSideTwo = (CBC_ResultPointsAndTransitions*)transitions[1];
+ CFX_MapPtrTemplate<CBC_ResultPoint*, FX_INT32> pointCount;
+ Increment(pointCount, lSideOne->GetFrom());
+ Increment(pointCount, lSideOne->GetTo());
+ Increment(pointCount, lSideTwo->GetFrom());
+ Increment(pointCount, lSideTwo->GetTo());
+ delete ( (CBC_ResultPointsAndTransitions *)transitions[1] );
+ delete ( (CBC_ResultPointsAndTransitions *)transitions[0] );
+ transitions.RemoveAll();
+ CBC_ResultPoint *maybeTopLeft = NULL;
+ CBC_ResultPoint *bottomLeft = NULL;
+ CBC_ResultPoint *maybeBottomRight = NULL;
+ FX_POSITION itBegin = pointCount.GetStartPosition();
+ while(itBegin != NULL) {
+ CBC_ResultPoint *key = 0;
+ FX_INT32 value = 0;
+ pointCount.GetNextAssoc(itBegin, key, value);
+ if(value == 2) {
+ bottomLeft = key;
+ } else {
+ if (maybeBottomRight == NULL) {
+ maybeBottomRight = key;
+ } else {
+ maybeTopLeft = key;
+ }
+ }
+ }
+ if (maybeTopLeft == NULL || bottomLeft == NULL || maybeBottomRight == NULL) {
+ delete pointA;
+ delete pointB;
+ delete pointC;
+ delete pointD;
+ e = BCExceptionNotFound;
+ return NULL;
+ }
+ CFX_PtrArray corners;
+ corners.SetSize(3);
+ corners[0] = maybeTopLeft;
+ corners[1] = bottomLeft;
+ corners[2] = maybeBottomRight;
+ OrderBestPatterns(&corners);
+ CBC_ResultPoint *bottomRight = (CBC_ResultPoint*)corners[0];
+ bottomLeft = (CBC_ResultPoint*)corners[1];
+ CBC_ResultPoint *topLeft = (CBC_ResultPoint*)corners[2];
+ CBC_ResultPoint *topRight = NULL;
+ FX_INT32 value;
+ if (!pointCount.Lookup(pointA, value)) {
+ topRight = pointA;
+ } else if (!pointCount.Lookup(pointB, value)) {
+ topRight = pointB;
+ } else if (!pointCount.Lookup(pointC, value)) {
+ topRight = pointC;
+ } else {
+ topRight = pointD;
+ }
+ FX_INT32 dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(topLeft, topRight))->GetTransitions();
+ FX_INT32 dimensionRight = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(bottomRight, topRight))->GetTransitions();
+ if ((dimensionTop & 0x01) == 1) {
+ dimensionTop++;
+ }
+ dimensionTop += 2;
+ if ((dimensionRight & 0x01) == 1) {
+ dimensionRight++;
+ }
+ dimensionRight += 2;
+ CBC_AutoPtr<CBC_CommonBitMatrix> bits(NULL);
+ CBC_AutoPtr<CBC_ResultPoint> correctedTopRight(NULL);
+ if (4 * dimensionTop >= 7 * dimensionRight || 4 * dimensionRight >= 7 * dimensionTop) {
+ correctedTopRight =
+ CBC_AutoPtr<CBC_ResultPoint>(CorrectTopRightRectangular(bottomLeft, bottomRight, topLeft, topRight,
+ dimensionTop, dimensionRight));
+ if (correctedTopRight.get() == NULL) {
+ correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight);
+ } else {
+ delete topRight;
+ topRight = NULL;
+ }
+ dimensionTop = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(topLeft, correctedTopRight.get()))->GetTransitions();
+ dimensionRight = CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(bottomRight, correctedTopRight.get()))->GetTransitions();
+ if ((dimensionTop & 0x01) == 1) {
+ dimensionTop++;
+ }
+ if ((dimensionRight & 0x01) == 1) {
+ dimensionRight++;
+ }
+ bits = CBC_AutoPtr<CBC_CommonBitMatrix>(SampleGrid(m_image, topLeft, bottomLeft, bottomRight,
+ correctedTopRight.get(), dimensionTop, dimensionRight, e));
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else {
+ FX_INT32 dimension = FX_MIN(dimensionRight, dimensionTop);
+ correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(CorrectTopRight(bottomLeft, bottomRight,
+ topLeft, topRight, dimension));
+ if (correctedTopRight.get() == NULL) {
+ correctedTopRight = CBC_AutoPtr<CBC_ResultPoint>(topRight);
+ } else {
+ delete topRight;
+ topRight = NULL;
+ }
+ FX_INT32 dimensionCorrected = FX_MAX(CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(topLeft, correctedTopRight.get()))->GetTransitions(),
+ CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(bottomRight, correctedTopRight.get()))->GetTransitions());
+ dimensionCorrected++;
+ if ((dimensionCorrected & 0x01) == 1) {
+ dimensionCorrected++;
+ }
+ bits = CBC_AutoPtr<CBC_CommonBitMatrix>(SampleGrid(m_image,
+ topLeft,
+ bottomLeft,
+ bottomRight,
+ correctedTopRight.get(),
+ dimensionCorrected,
+ dimensionCorrected, e));
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CFX_PtrArray *result = FX_NEW CFX_PtrArray;
+ result->SetSize(4);
+ result->Add(topLeft);
+ result->Add(bottomLeft);
+ result->Add(bottomRight);
+ result->Add(correctedTopRight.release());
+ return FX_NEW CBC_QRDetectorResult(bits.release(), result);
+}
+CBC_ResultPoint *CBC_DataMatrixDetector::CorrectTopRightRectangular(CBC_ResultPoint *bottomLeft, CBC_ResultPoint *bottomRight, CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight, FX_INT32 dimensionTop, FX_INT32 dimensionRight)
+{
+ FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT)dimensionTop;
+ FX_INT32 norm = Distance(topLeft, topRight);
+ FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm;
+ FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm;
+ CBC_AutoPtr<CBC_ResultPoint> c1(FX_NEW CBC_ResultPoint(topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
+ corr = Distance(bottomLeft, topLeft) / (FX_FLOAT)dimensionRight;
+ norm = Distance(bottomRight, topRight);
+ cos = (topRight->GetX() - bottomRight->GetX()) / norm;
+ sin = (topRight->GetY() - bottomRight->GetY()) / norm;
+ CBC_AutoPtr<CBC_ResultPoint> c2(FX_NEW CBC_ResultPoint(topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
+ if (!IsValid(c1.get())) {
+ if (IsValid(c2.get())) {
+ return c2.release();
+ }
+ return NULL;
+ } else if (!IsValid(c2.get())) {
+ return c1.release();
+ }
+ FX_INT32 l1 = FXSYS_abs(dimensionTop - CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(topLeft, c1.get()))->GetTransitions()) +
+ FXSYS_abs(dimensionRight - CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(bottomRight, c1.get()))->GetTransitions());
+ FX_INT32 l2 = FXSYS_abs(dimensionTop - CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(topLeft, c2.get()))->GetTransitions()) +
+ FXSYS_abs(dimensionRight - CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(bottomRight, c2.get()))->GetTransitions());
+ if (l1 <= l2) {
+ return c1.release();
+ }
+ return c2.release();
+}
+CBC_ResultPoint *CBC_DataMatrixDetector::CorrectTopRight(CBC_ResultPoint *bottomLeft, CBC_ResultPoint *bottomRight, CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight, FX_INT32 dimension)
+{
+ FX_FLOAT corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT) dimension;
+ FX_INT32 norm = Distance(topLeft, topRight);
+ FX_FLOAT cos = (topRight->GetX() - topLeft->GetX()) / norm;
+ FX_FLOAT sin = (topRight->GetY() - topLeft->GetY()) / norm;
+ CBC_AutoPtr<CBC_ResultPoint> c1(FX_NEW CBC_ResultPoint(topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
+ corr = Distance(bottomLeft, bottomRight) / (FX_FLOAT) dimension;
+ norm = Distance(bottomRight, topRight);
+ cos = (topRight->GetX() - bottomRight->GetX()) / norm;
+ sin = (topRight->GetY() - bottomRight->GetY()) / norm;
+ CBC_AutoPtr<CBC_ResultPoint> c2(FX_NEW CBC_ResultPoint(topRight->GetX() + corr * cos, topRight->GetY() + corr * sin));
+ if (!IsValid(c1.get())) {
+ if (IsValid(c2.get())) {
+ return c2.release();
+ }
+ return NULL;
+ } else if (!IsValid(c2.get())) {
+ return c1.release();
+ }
+ FX_INT32 l1 = FXSYS_abs(CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(topLeft, c1.get()))->GetTransitions() -
+ CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(bottomRight, c1.get()))->GetTransitions());
+ FX_INT32 l2 = FXSYS_abs(CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(topLeft, c2.get()))->GetTransitions() -
+ CBC_AutoPtr<CBC_ResultPointsAndTransitions>(TransitionsBetween(bottomRight, c2.get()))->GetTransitions());
+ return l1 <= l2 ? c1.release() : c2.release();
+}
+FX_BOOL CBC_DataMatrixDetector::IsValid(CBC_ResultPoint *p)
+{
+ return p->GetX() >= 0 && p->GetX() < m_image->GetWidth() && p->GetY() > 0 && p->GetY() < m_image->GetHeight();
+}
+FX_INT32 CBC_DataMatrixDetector::Round(FX_FLOAT d)
+{
+ return (FX_INT32) (d + 0.5f);
+}
+FX_INT32 CBC_DataMatrixDetector::Distance(CBC_ResultPoint *a, CBC_ResultPoint *b)
+{
+ return Round((FX_FLOAT) sqrt((a->GetX() - b->GetX())
+ * (a->GetX() - b->GetX()) + (a->GetY() - b->GetY())
+ * (a->GetY() - b->GetY())));
+}
+void CBC_DataMatrixDetector::Increment(CFX_MapPtrTemplate<CBC_ResultPoint*, FX_INT32> &table, CBC_ResultPoint *key)
+{
+ FX_INT32 value;
+ if(table.Lookup(key, value)) {
+ table.SetAt(key, INTEGERS[value + 1]);
+ } else {
+ table.SetAt(key, INTEGERS[1]);
+ }
+}
+CBC_CommonBitMatrix *CBC_DataMatrixDetector::SampleGrid(CBC_CommonBitMatrix *image,
+ CBC_ResultPoint *topLeft,
+ CBC_ResultPoint *bottomLeft,
+ CBC_ResultPoint *bottomRight,
+ CBC_ResultPoint *topRight,
+ FX_INT32 dimensionX, FX_INT32 dimensionY, FX_INT32 &e)
+{
+ CBC_QRGridSampler &sampler = CBC_QRGridSampler::GetInstance();
+ CBC_CommonBitMatrix* cbm = sampler.SampleGrid(image,
+ dimensionX,
+ dimensionY,
+ 0.5f,
+ 0.5f,
+ dimensionX - 0.5f,
+ 0.5f,
+ dimensionX - 0.5f,
+ dimensionY - 0.5f,
+ 0.5f,
+ dimensionY - 0.5f,
+ topLeft->GetX(),
+ topLeft->GetY(),
+ topRight->GetX(),
+ topRight->GetY(),
+ bottomRight->GetX(),
+ bottomRight->GetY(),
+ bottomLeft->GetX(),
+ bottomLeft->GetY(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return cbm;
+}
+CBC_ResultPointsAndTransitions *CBC_DataMatrixDetector::TransitionsBetween(CBC_ResultPoint *from, CBC_ResultPoint *to)
+{
+ FX_INT32 fromX = (FX_INT32) from->GetX();
+ FX_INT32 fromY = (FX_INT32) from->GetY();
+ FX_INT32 toX = (FX_INT32) to->GetX();
+ FX_INT32 toY = (FX_INT32) to->GetY();
+ FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX);
+ if (steep) {
+ FX_INT32 temp = fromX;
+ fromX = fromY;
+ fromY = temp;
+ temp = toX;
+ toX = toY;
+ toY = temp;
+ }
+ FX_INT32 dx = FXSYS_abs(toX - fromX);
+ FX_INT32 dy = FXSYS_abs(toY - fromY);
+ FX_INT32 error = -dx >> 1;
+ FX_INT32 ystep = fromY < toY ? 1 : -1;
+ FX_INT32 xstep = fromX < toX ? 1 : -1;
+ FX_INT32 transitions = 0;
+ FX_BOOL inBlack = m_image->Get(steep ? fromY : fromX, steep ? fromX : fromY);
+ for (FX_INT32 x = fromX, y = fromY; x != toX; x += xstep) {
+ FX_BOOL isBlack = m_image->Get(steep ? y : x, steep ? x : y);
+ if (isBlack != inBlack) {
+ transitions++;
+ inBlack = isBlack;
+ }
+ error += dy;
+ if (error > 0) {
+ if (y == toY) {
+ break;
+ }
+ y += ystep;
+ error -= dx;
+ }
+ }
+ return FX_NEW CBC_ResultPointsAndTransitions(from, to, transitions);
+}
+void CBC_DataMatrixDetector::OrderBestPatterns(CFX_PtrArray *patterns)
+{
+ FX_FLOAT abDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[0], (CBC_ResultPoint*)(*patterns)[1]);
+ FX_FLOAT bcDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[1], (CBC_ResultPoint*)(*patterns)[2]);
+ FX_FLOAT acDistance = (FX_FLOAT)Distance((CBC_ResultPoint*)(*patterns)[0], (CBC_ResultPoint*)(*patterns)[2]);
+ CBC_ResultPoint *topLeft, *topRight, *bottomLeft;
+ if (bcDistance >= abDistance && bcDistance >= acDistance) {
+ topLeft = (CBC_ResultPoint*)(*patterns)[0];
+ topRight = (CBC_ResultPoint*)(*patterns)[1];
+ bottomLeft = (CBC_ResultPoint*)(*patterns)[2];
+ } else if (acDistance >= bcDistance && acDistance >= abDistance) {
+ topLeft = (CBC_ResultPoint*)(*patterns)[1];
+ topRight = (CBC_ResultPoint*)(*patterns)[0];
+ bottomLeft = (CBC_ResultPoint*)(*patterns)[2];
+ } else {
+ topLeft = (CBC_ResultPoint*)(*patterns)[2];
+ topRight = (CBC_ResultPoint*)(*patterns)[0];
+ bottomLeft = (CBC_ResultPoint*)(*patterns)[1];
+ }
+ if ((bottomLeft->GetY() - topLeft->GetY()) * (topRight->GetX() - topLeft->GetX()) < (bottomLeft->GetX()
+ - topLeft->GetX()) * (topRight->GetY() - topLeft->GetY())) {
+ CBC_ResultPoint *temp = topRight;
+ topRight = bottomLeft;
+ bottomLeft = temp;
+ }
+ (*patterns)[0] = bottomLeft;
+ (*patterns)[1] = topLeft;
+ (*patterns)[2] = topRight;
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixReader.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixReader.cpp
new file mode 100644
index 0000000000..ba03af0f1a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixReader.cpp
@@ -0,0 +1,51 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_DataMatrixDecoder.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_DataMatrixDetector.h"
+#include "include/BC_QRDetectorResult.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_Reader.h"
+#include "include/BC_DataMatrixReader.h"
+CBC_DataMatrixReader::CBC_DataMatrixReader()
+{
+ m_decoder = NULL;
+}
+void CBC_DataMatrixReader::Init()
+{
+ m_decoder = FX_NEW CBC_DataMatrixDecoder;
+ m_decoder->Init();
+}
+CBC_DataMatrixReader::~CBC_DataMatrixReader()
+{
+ if(m_decoder != NULL) {
+ delete m_decoder;
+ }
+ m_decoder = NULL;
+}
+CFX_ByteString CBC_DataMatrixReader::Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e)
+{
+ CBC_CommonBitMatrix *cdr = image->GetBlackMatrix(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_DataMatrixDetector detector(cdr);
+ detector.Init(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_QRDetectorResult* ddr = detector.Detect(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CBC_QRDetectorResult> detectorResult(ddr);
+ CBC_CommonDecoderResult* ResultTemp = m_decoder->Decode(detectorResult->GetBits(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CBC_CommonDecoderResult> decodeResult(ResultTemp);
+ return decodeResult->GetText();
+}
+CFX_ByteString CBC_DataMatrixReader::Decode(CBC_BinaryBitmap *image, FX_INT32 &e)
+{
+ CFX_ByteString bs = Decode(image, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return bs;
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixSymbolInfo144.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixSymbolInfo144.cpp
new file mode 100644
index 0000000000..09a22942f4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixSymbolInfo144.cpp
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_DataMatrixSymbolInfo144.h"
+CBC_DataMatrixSymbolInfo144::CBC_DataMatrixSymbolInfo144() : CBC_SymbolInfo(FALSE, 1558, 620, 22, 22, 36)
+{
+ m_rsBlockData = -1;
+ m_rsBlockError = 62;
+}
+CBC_DataMatrixSymbolInfo144::~CBC_DataMatrixSymbolInfo144()
+{
+}
+FX_INT32 CBC_DataMatrixSymbolInfo144::getInterleavedBlockCount()
+{
+ return 10;
+}
+FX_INT32 CBC_DataMatrixSymbolInfo144getDataLengthForInterleavedBlock(FX_INT32 index)
+{
+ return (index <= 8) ? 156 : 155;
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixVersion.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixVersion.cpp
new file mode 100644
index 0000000000..269861b5cd
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixVersion.cpp
@@ -0,0 +1,131 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_DataMatrixVersion.h"
+CFX_PtrArray* CBC_DataMatrixVersion::VERSIONS = NULL;
+void CBC_DataMatrixVersion::Initialize()
+{
+ VERSIONS = FX_NEW CFX_PtrArray();
+}
+void CBC_DataMatrixVersion::Finalize()
+{
+ for (FX_INT32 i = 0; i < VERSIONS->GetSize(); i++) {
+ delete ( (CBC_DataMatrixVersion*)(VERSIONS->GetAt(i)) );
+ }
+ VERSIONS->RemoveAll();
+ delete VERSIONS;
+}
+CBC_DataMatrixVersion::CBC_DataMatrixVersion(FX_INT32 versionNumber,
+ FX_INT32 symbolSizeRows,
+ FX_INT32 symbolSizeColumns,
+ FX_INT32 dataRegionSizeRows,
+ FX_INT32 dataRegionSizeColumns,
+ ECBlocks *ecBlocks)
+{
+ m_versionNumber = versionNumber;
+ m_symbolSizeRows = symbolSizeRows;
+ m_symbolSizeColumns = symbolSizeColumns;
+ m_dataRegionSizeRows = dataRegionSizeRows;
+ m_dataRegionSizeColumns = dataRegionSizeColumns;
+ m_ecBlocks = ecBlocks;
+ FX_INT32 total = 0;
+ FX_INT32 ecCodewords = ecBlocks->GetECCodewords();
+ const CFX_PtrArray &ecbArray = ecBlocks->GetECBlocks();
+ for (FX_INT32 i = 0; i < ecbArray.GetSize(); i++) {
+ total += ((ECB*)ecbArray[i])->GetCount() * (((ECB*)ecbArray[i])->GetDataCodewords() + ecCodewords);
+ }
+ m_totalCodewords = total;
+}
+CBC_DataMatrixVersion::~CBC_DataMatrixVersion()
+{
+ if(m_ecBlocks != NULL) {
+ delete m_ecBlocks;
+ }
+ m_ecBlocks = NULL;
+}
+FX_INT32 CBC_DataMatrixVersion::GetVersionNumber()
+{
+ return m_versionNumber;
+}
+FX_INT32 CBC_DataMatrixVersion::GetSymbolSizeRows()
+{
+ return m_symbolSizeRows;
+}
+FX_INT32 CBC_DataMatrixVersion::GetSymbolSizeColumns()
+{
+ return m_symbolSizeColumns;
+}
+FX_INT32 CBC_DataMatrixVersion::GetDataRegionSizeRows()
+{
+ return m_dataRegionSizeRows;
+}
+FX_INT32 CBC_DataMatrixVersion::GetDataRegionSizeColumns()
+{
+ return m_dataRegionSizeColumns;
+}
+FX_INT32 CBC_DataMatrixVersion::GetTotalCodewords()
+{
+ return m_totalCodewords;
+}
+ECBlocks *CBC_DataMatrixVersion::GetECBlocks()
+{
+ return m_ecBlocks;
+}
+void CBC_DataMatrixVersion::ReleaseAll()
+{
+ for (FX_INT32 i = 0; i < VERSIONS->GetSize(); i++) {
+ delete (CBC_DataMatrixVersion*)VERSIONS->GetAt(i);
+ }
+ VERSIONS->RemoveAll();
+}
+CBC_DataMatrixVersion *CBC_DataMatrixVersion::GetVersionForDimensions(FX_INT32 numRows, FX_INT32 numColumns, FX_INT32 &e)
+{
+ if ((numRows & 0x01) != 0 || (numColumns & 0x01) != 0) {
+ e = BCExceptionNotFound;
+ return NULL;
+ }
+ if(VERSIONS->GetSize() == 0) {
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(1, 10, 10, 8, 8, FX_NEW ECBlocks(5, FX_NEW ECB(1, 3))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(2, 12, 12, 10, 10, FX_NEW ECBlocks(7, FX_NEW ECB(1, 5))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(3, 14, 14, 12, 12, FX_NEW ECBlocks(10, FX_NEW ECB(1, 8))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(4, 16, 16, 14, 14, FX_NEW ECBlocks(12, FX_NEW ECB(1, 12))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(5, 18, 18, 16, 16, FX_NEW ECBlocks(14, FX_NEW ECB(1, 18))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(6, 20, 20, 18, 18, FX_NEW ECBlocks(18, FX_NEW ECB(1, 22))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(7, 22, 22, 20, 20, FX_NEW ECBlocks(20, FX_NEW ECB(1, 30))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(8, 24, 24, 22, 22, FX_NEW ECBlocks(24, FX_NEW ECB(1, 36))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(9, 26, 26, 24, 24, FX_NEW ECBlocks(28, FX_NEW ECB(1, 44))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(10, 32, 32, 14, 14, FX_NEW ECBlocks(36, FX_NEW ECB(1, 62))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(11, 36, 36, 16, 16, FX_NEW ECBlocks(42, FX_NEW ECB(1, 86))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(12, 40, 40, 18, 18, FX_NEW ECBlocks(48, FX_NEW ECB(1, 114))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(13, 44, 44, 20, 20, FX_NEW ECBlocks(56, FX_NEW ECB(1, 144))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(14, 48, 48, 22, 22, FX_NEW ECBlocks(68, FX_NEW ECB(1, 174))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(15, 52, 52, 24, 24, FX_NEW ECBlocks(42, FX_NEW ECB(2, 102))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(16, 64, 64, 14, 14, FX_NEW ECBlocks(56, FX_NEW ECB(2, 140))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(17, 72, 72, 16, 16, FX_NEW ECBlocks(36, FX_NEW ECB(4, 92))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(18, 80, 80, 18, 18, FX_NEW ECBlocks(48, FX_NEW ECB(4, 114))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(19, 88, 88, 20, 20, FX_NEW ECBlocks(56, FX_NEW ECB(4, 144))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(20, 96, 96, 22, 22, FX_NEW ECBlocks(68, FX_NEW ECB(4, 174))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(21, 104, 104, 24, 24, FX_NEW ECBlocks(56, FX_NEW ECB(6, 136))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(22, 120, 120, 18, 18, FX_NEW ECBlocks(68, FX_NEW ECB(6, 175))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(23, 132, 132, 20, 20, FX_NEW ECBlocks(62, FX_NEW ECB(8, 163))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(24, 144, 144, 22, 22, FX_NEW ECBlocks(62, FX_NEW ECB(8, 156), FX_NEW ECB(2, 155))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(25, 8, 18, 6, 16, FX_NEW ECBlocks(7, FX_NEW ECB(1, 5))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(26, 8, 32, 6, 14, FX_NEW ECBlocks(11, FX_NEW ECB(1, 10))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(27, 12, 26, 10, 24, FX_NEW ECBlocks(14, FX_NEW ECB(1, 16))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(28, 12, 36, 10, 16, FX_NEW ECBlocks(18, FX_NEW ECB(1, 22))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(29, 16, 36, 14, 16, FX_NEW ECBlocks(24, FX_NEW ECB(1, 32))));
+ VERSIONS->Add(FX_NEW CBC_DataMatrixVersion(30, 16, 48, 14, 22, FX_NEW ECBlocks(28, FX_NEW ECB(1, 49))));
+ }
+ FX_INT32 numVersions = VERSIONS->GetSize();
+ for (FX_INT32 i = 0; i < numVersions; ++i) {
+ if (((CBC_DataMatrixVersion*)((*VERSIONS)[i]))->m_symbolSizeRows == numRows && ((CBC_DataMatrixVersion*)((*VERSIONS)[i]))->m_symbolSizeColumns == numColumns) {
+ return (CBC_DataMatrixVersion*)(*VERSIONS)[i];
+ }
+ }
+ e = BCExceptionNotFound;
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/src/BC_DataMatrixWriter.cpp b/xfa/src/fxbarcode/src/BC_DataMatrixWriter.cpp
new file mode 100644
index 0000000000..de122035fe
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DataMatrixWriter.cpp
@@ -0,0 +1,122 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_TwoDimWriter.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_DefaultPlacement.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_DataMatrixSymbolInfo144.h"
+#include "include/BC_ErrorCorrection.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_C40Encoder.h"
+#include "include/BC_TextEncoder.h"
+#include "include/BC_X12Encoder.h"
+#include "include/BC_EdifactEncoder.h"
+#include "include/BC_Base256Encoder.h"
+#include "include/BC_ASCIIEncoder.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_CommonByteMatrix.h"
+#include "include/BC_DataMatrixWriter.h"
+#include "include/BC_UtilCodingConvert.h"
+CBC_DataMatrixWriter::CBC_DataMatrixWriter()
+{
+}
+CBC_DataMatrixWriter::~CBC_DataMatrixWriter()
+{
+}
+FX_BOOL CBC_DataMatrixWriter::SetErrorCorrectionLevel (FX_INT32 level)
+{
+ m_iCorrectLevel = level;
+ return TRUE;
+}
+FX_BYTE* CBC_DataMatrixWriter::Encode(const CFX_WideString &contents, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ if (outWidth < 0 || outHeight < 0) {
+ e = BCExceptionHeightAndWidthMustBeAtLeast1;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_SymbolShapeHint::SymbolShapeHint shape = CBC_SymbolShapeHint::FORCE_SQUARE;
+ CBC_Dimension* minSize = NULL;
+ CBC_Dimension* maxSize = NULL;
+ CFX_WideString ecLevel;
+ CFX_WideString encoded = CBC_HighLevelEncoder::encodeHighLevel(contents, ecLevel, shape, minSize, maxSize, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_SymbolInfo* symbolInfo = CBC_SymbolInfo::lookup(encoded.GetLength(), shape, minSize, maxSize, TRUE, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CFX_WideString codewords = CBC_ErrorCorrection::encodeECC200(encoded, symbolInfo, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_DefaultPlacement* placement = FX_NEW CBC_DefaultPlacement(codewords, symbolInfo->getSymbolDataWidth(e), symbolInfo->getSymbolDataHeight(e));
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ placement->place();
+ CBC_CommonByteMatrix* bytematrix = encodeLowLevel(placement, symbolInfo, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ outWidth = bytematrix->GetWidth();
+ outHeight = bytematrix->GetHeight();
+ FX_BYTE* result = FX_Alloc(FX_BYTE, outWidth * outHeight);
+ FXSYS_memcpy32(result, bytematrix->GetArray(), outWidth * outHeight);
+ delete bytematrix;
+ delete placement;
+ return result;
+}
+FX_BYTE *CBC_DataMatrixWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ return NULL;
+}
+FX_BYTE *CBC_DataMatrixWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ return NULL;
+}
+CBC_CommonByteMatrix* CBC_DataMatrixWriter::encodeLowLevel(CBC_DefaultPlacement* placement, CBC_SymbolInfo* symbolInfo, FX_INT32 &e)
+{
+ FX_INT32 symbolWidth = symbolInfo->getSymbolDataWidth(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 symbolHeight = symbolInfo->getSymbolDataHeight(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_CommonByteMatrix* matrix = FX_NEW CBC_CommonByteMatrix(symbolInfo->getSymbolWidth(e), symbolInfo->getSymbolHeight(e));
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ matrix->Init();
+ FX_INT32 matrixY = 0;
+ for (FX_INT32 y = 0; y < symbolHeight; y++) {
+ FX_INT32 matrixX;
+ if ((y % symbolInfo->m_matrixHeight) == 0) {
+ matrixX = 0;
+ for (FX_INT32 x = 0; x < symbolInfo->getSymbolWidth(e); x++) {
+ matrix->Set(matrixX, matrixY, (x % 2) == 0);
+ matrixX++;
+ }
+ matrixY++;
+ }
+ matrixX = 0;
+ for (FX_INT32 x = 0; x < symbolWidth; x++) {
+ if ((x % symbolInfo->m_matrixWidth) == 0) {
+ matrix->Set(matrixX, matrixY, TRUE);
+ matrixX++;
+ }
+ matrix->Set(matrixX, matrixY, placement->getBit(x, y));
+ matrixX++;
+ if ((x % symbolInfo->m_matrixWidth) == symbolInfo->m_matrixWidth - 1) {
+ matrix->Set(matrixX, matrixY, (y % 2) == 0);
+ matrixX++;
+ }
+ }
+ matrixY++;
+ if ((y % symbolInfo->m_matrixHeight) == symbolInfo->m_matrixHeight - 1) {
+ matrixX = 0;
+ for (FX_INT32 x = 0; x < symbolInfo->getSymbolWidth(e); x++) {
+ matrix->Set(matrixX, matrixY, TRUE);
+ matrixX++;
+ }
+ matrixY++;
+ }
+ }
+ return matrix;
+}
diff --git a/xfa/src/fxbarcode/src/BC_DefaultPlacement.cpp b/xfa/src/fxbarcode/src/BC_DefaultPlacement.cpp
new file mode 100644
index 0000000000..b543f08307
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_DefaultPlacement.cpp
@@ -0,0 +1,158 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_DefaultPlacement.h"
+CBC_DefaultPlacement::CBC_DefaultPlacement(CFX_WideString codewords, FX_INT32 numcols, FX_INT32 numrows)
+{
+ m_codewords = codewords;
+ m_numcols = numcols;
+ m_numrows = numrows;
+ m_bits.SetSize(numcols * numrows);
+ for (FX_INT32 i = 0; i < numcols * numrows; i++) {
+ m_bits[i] = (FX_BYTE) 2;
+ }
+}
+CBC_DefaultPlacement::~CBC_DefaultPlacement()
+{
+ m_bits.RemoveAll();
+}
+FX_INT32 CBC_DefaultPlacement::getNumrows()
+{
+ return m_numrows;
+}
+FX_INT32 CBC_DefaultPlacement::getNumcols()
+{
+ return m_numcols;
+}
+CFX_ByteArray& CBC_DefaultPlacement::getBits()
+{
+ return m_bits;
+}
+FX_BOOL CBC_DefaultPlacement::getBit(FX_INT32 col, FX_INT32 row)
+{
+ return m_bits[row * m_numcols + col] == 1;
+}
+void CBC_DefaultPlacement::setBit(FX_INT32 col, FX_INT32 row, FX_BOOL bit)
+{
+ m_bits[row * m_numcols + col] = bit ? (FX_BYTE) 1 : (FX_BYTE) 0;
+}
+FX_BOOL CBC_DefaultPlacement::hasBit(FX_INT32 col, FX_INT32 row)
+{
+ return m_bits[row * m_numcols + col] != 2;
+}
+void CBC_DefaultPlacement::place()
+{
+ FX_INT32 pos = 0;
+ FX_INT32 row = 4;
+ FX_INT32 col = 0;
+ do {
+ if ((row == m_numrows) && (col == 0)) {
+ corner1(pos++);
+ }
+ if ((row == m_numrows - 2) && (col == 0) && ((m_numcols % 4) != 0)) {
+ corner2(pos++);
+ }
+ if ((row == m_numrows - 2) && (col == 0) && (m_numcols % 8 == 4)) {
+ corner3(pos++);
+ }
+ if ((row == m_numrows + 4) && (col == 2) && ((m_numcols % 8) == 0)) {
+ corner4(pos++);
+ }
+ do {
+ if ((row < m_numrows) && (col >= 0) && !hasBit(col, row)) {
+ utah(row, col, pos++);
+ }
+ row -= 2;
+ col += 2;
+ } while (row >= 0 && (col < m_numcols));
+ row++;
+ col += 3;
+ do {
+ if ((row >= 0) && (col < m_numcols) && !hasBit(col, row)) {
+ utah(row, col, pos++);
+ }
+ row += 2;
+ col -= 2;
+ } while ((row < m_numrows) && (col >= 0));
+ row += 3;
+ col++;
+ } while ((row < m_numrows) || (col < m_numcols));
+ if (!hasBit(m_numcols - 1, m_numrows - 1)) {
+ setBit(m_numcols - 1, m_numrows - 1, TRUE);
+ setBit(m_numcols - 2, m_numrows - 2, TRUE);
+ }
+}
+void CBC_DefaultPlacement::module(FX_INT32 row, FX_INT32 col, FX_INT32 pos, FX_INT32 bit)
+{
+ if (row < 0) {
+ row += m_numrows;
+ col += 4 - ((m_numrows + 4) % 8);
+ }
+ if (col < 0) {
+ col += m_numcols;
+ row += 4 - ((m_numcols + 4) % 8);
+ }
+ FX_INT32 v = m_codewords.GetAt(pos);
+ v &= 1 << (8 - bit);
+ setBit(col, row, v != 0);
+}
+void CBC_DefaultPlacement::utah(FX_INT32 row, FX_INT32 col, FX_INT32 pos)
+{
+ module(row - 2, col - 2, pos, 1);
+ module(row - 2, col - 1, pos, 2);
+ module(row - 1, col - 2, pos, 3);
+ module(row - 1, col - 1, pos, 4);
+ module(row - 1, col, pos, 5);
+ module(row, col - 2, pos, 6);
+ module(row, col - 1, pos, 7);
+ module(row, col, pos, 8);
+}
+void CBC_DefaultPlacement::corner1(FX_INT32 pos)
+{
+ module(m_numrows - 1, 0, pos, 1);
+ module(m_numrows - 1, 1, pos, 2);
+ module(m_numrows - 1, 2, pos, 3);
+ module(0, m_numcols - 2, pos, 4);
+ module(0, m_numcols - 1, pos, 5);
+ module(1, m_numcols - 1, pos, 6);
+ module(2, m_numcols - 1, pos, 7);
+ module(3, m_numcols - 1, pos, 8);
+}
+void CBC_DefaultPlacement::corner2(FX_INT32 pos)
+{
+ module(m_numrows - 3, 0, pos, 1);
+ module(m_numrows - 2, 0, pos, 2);
+ module(m_numrows - 1, 0, pos, 3);
+ module(0, m_numcols - 4, pos, 4);
+ module(0, m_numcols - 3, pos, 5);
+ module(0, m_numcols - 2, pos, 6);
+ module(0, m_numcols - 1, pos, 7);
+ module(1, m_numcols - 1, pos, 8);
+}
+void CBC_DefaultPlacement::corner3(FX_INT32 pos)
+{
+ module(m_numrows - 3, 0, pos, 1);
+ module(m_numrows - 2, 0, pos, 2);
+ module(m_numrows - 1, 0, pos, 3);
+ module(0, m_numcols - 2, pos, 4);
+ module(0, m_numcols - 1, pos, 5);
+ module(1, m_numcols - 1, pos, 6);
+ module(2, m_numcols - 1, pos, 7);
+ module(3, m_numcols - 1, pos, 8);
+}
+void CBC_DefaultPlacement::corner4(FX_INT32 pos)
+{
+ module(m_numrows - 1, 0, pos, 1);
+ module(m_numrows - 1, m_numcols - 1, pos, 2);
+ module(0, m_numcols - 3, pos, 3);
+ module(0, m_numcols - 2, pos, 4);
+ module(0, m_numcols - 1, pos, 5);
+ module(1, m_numcols - 3, pos, 6);
+ module(1, m_numcols - 2, pos, 7);
+ module(1, m_numcols - 1, pos, 8);
+}
diff --git a/xfa/src/fxbarcode/src/BC_Dimension.cpp b/xfa/src/fxbarcode/src/BC_Dimension.cpp
new file mode 100644
index 0000000000..588b3aa961
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Dimension.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_Dimension.h"
+CBC_Dimension::CBC_Dimension()
+{
+}
+CBC_Dimension::CBC_Dimension(FX_INT32 width, FX_INT32 height, FX_INT32 &e)
+{
+ if (width < 0 || height < 0) {
+ e = BCExceptionHeightAndWidthMustBeAtLeast1;
+ }
+ m_width = width;
+ m_height = height;
+}
+CBC_Dimension::~CBC_Dimension()
+{
+}
+FX_INT32 CBC_Dimension::getWidth()
+{
+ return m_width;
+}
+FX_INT32 CBC_Dimension::getHeight()
+{
+ return m_height;
+}
+FX_INT32 CBC_Dimension::hashCode()
+{
+ return m_width * 32713 + m_height;
+}
+CFX_WideString CBC_Dimension::toString()
+{
+ return (FX_WCHAR)(m_width + (FX_WCHAR)'x' + m_height);
+}
diff --git a/xfa/src/fxbarcode/src/BC_EdifactEncoder.cpp b/xfa/src/fxbarcode/src/BC_EdifactEncoder.cpp
new file mode 100644
index 0000000000..134e484e25
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_EdifactEncoder.cpp
@@ -0,0 +1,137 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_EdifactEncoder.h"
+CBC_EdifactEncoder::CBC_EdifactEncoder()
+{
+}
+CBC_EdifactEncoder::~CBC_EdifactEncoder()
+{
+}
+FX_INT32 CBC_EdifactEncoder::getEncodingMode()
+{
+ return EDIFACT_ENCODATION;
+}
+void CBC_EdifactEncoder::Encode(CBC_EncoderContext &context, FX_INT32 &e)
+{
+ CFX_WideString buffer;
+ while (context.hasMoreCharacters()) {
+ FX_WCHAR c = context.getCurrentChar();
+ encodeChar(c, buffer, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ context.m_pos++;
+ FX_INT32 count = buffer.GetLength();
+ if (count >= 4) {
+ context.writeCodewords(encodeToCodewords(buffer, 0, e));
+ if (e != BCExceptionNO) {
+ return;
+ }
+ buffer.Delete(0, 4);
+ FX_INT32 newMode = CBC_HighLevelEncoder::lookAheadTest(context.m_msg, context.m_pos, getEncodingMode());
+ if (newMode != getEncodingMode()) {
+ context.signalEncoderChange(ASCII_ENCODATION);
+ break;
+ }
+ }
+ }
+ buffer += (FX_WCHAR)31;
+ handleEOD(context, buffer, e);
+}
+void CBC_EdifactEncoder::handleEOD(CBC_EncoderContext &context, CFX_WideString buffer, FX_INT32 &e)
+{
+ FX_INT32 count = buffer.GetLength();
+ if (count == 0) {
+ return;
+ }
+ if (count == 1) {
+ context.updateSymbolInfo(e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_INT32 available = context.m_symbolInfo->m_dataCapacity - context.getCodewordCount();
+ FX_INT32 remaining = context.getRemainingCharacters();
+ if (remaining == 0 && available <= 2) {
+ return;
+ }
+ }
+ if (count > 4) {
+ e = BCExceptionIllegalStateCountMustNotExceed4;
+ return;
+ }
+ FX_INT32 restChars = count - 1;
+ CFX_WideString encoded = encodeToCodewords(buffer, 0, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_BOOL endOfSymbolReached = !context.hasMoreCharacters();
+ FX_BOOL restInAscii = endOfSymbolReached && restChars <= 2;
+ if (restChars <= 2) {
+ context.updateSymbolInfo(context.getCodewordCount() + restChars, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_INT32 available = context.m_symbolInfo->m_dataCapacity - context.getCodewordCount();
+ if (available >= 3) {
+ restInAscii = FALSE;
+ context.updateSymbolInfo(context.getCodewordCount() + encoded.GetLength(), e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ }
+ }
+ if (restInAscii) {
+ context.resetSymbolInfo();
+ context.m_pos -= restChars;
+ } else {
+ context.writeCodewords(encoded);
+ }
+ context.signalEncoderChange(ASCII_ENCODATION);
+}
+void CBC_EdifactEncoder::encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e)
+{
+ if (c >= ' ' && c <= '?') {
+ sb += c;
+ } else if (c >= '@' && c <= '^') {
+ sb += (FX_WCHAR)(c - 64);
+ } else {
+ CBC_HighLevelEncoder::illegalCharacter(c, e);
+ }
+}
+CFX_WideString CBC_EdifactEncoder::encodeToCodewords(CFX_WideString sb, FX_INT32 startPos, FX_INT32 &e)
+{
+ FX_INT32 len = sb.GetLength() - startPos;
+ if (len == 0) {
+ e = BCExceptionNoContents;
+ return (FX_LPWSTR)"";
+ }
+ FX_WCHAR c1 = sb.GetAt(startPos);
+ FX_WCHAR c2 = len >= 2 ? sb.GetAt(startPos + 1) : 0;
+ FX_WCHAR c3 = len >= 3 ? sb.GetAt(startPos + 2) : 0;
+ FX_WCHAR c4 = len >= 4 ? sb.GetAt(startPos + 3) : 0;
+ FX_INT32 v = (c1 << 18) + (c2 << 12) + (c3 << 6) + c4;
+ FX_WCHAR cw1 = (FX_WCHAR) ((v >> 16) & 255);
+ FX_WCHAR cw2 = (FX_WCHAR) ((v >> 8) & 255);
+ FX_WCHAR cw3 = (FX_WCHAR) (v & 255);
+ CFX_WideString res;
+ res += cw1;
+ if (len >= 2) {
+ res += cw2;
+ }
+ if (len >= 3) {
+ res += cw3;
+ }
+ return res;
+}
diff --git a/xfa/src/fxbarcode/src/BC_Encoder.cpp b/xfa/src/fxbarcode/src/BC_Encoder.cpp
new file mode 100644
index 0000000000..f9b224e68e
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Encoder.cpp
@@ -0,0 +1,14 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+CBC_Encoder::CBC_Encoder()
+{
+}
+CBC_Encoder::~CBC_Encoder()
+{
+}
diff --git a/xfa/src/fxbarcode/src/BC_EncoderContext.cpp b/xfa/src/fxbarcode/src/BC_EncoderContext.cpp
new file mode 100644
index 0000000000..0ac7ebb53d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_EncoderContext.cpp
@@ -0,0 +1,111 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_UtilCodingConvert.h"
+CBC_EncoderContext::CBC_EncoderContext(const CFX_WideString msg, CFX_WideString ecLevel, FX_INT32 &e)
+{
+ CFX_ByteString dststr;
+ CBC_UtilCodingConvert::UnicodeToUTF8(msg, dststr);
+ CFX_WideString sb;
+ FX_INT32 c = dststr.GetLength();
+ for (FX_INT32 i = 0; i < c; i++) {
+ FX_WCHAR ch = (FX_WCHAR)(dststr.GetAt(i) & 0xff);
+ if (ch == '?' && dststr.GetAt(i) != '?') {
+ e = BCExceptionCharactersOutsideISO88591Encoding;
+ }
+ sb += ch;
+ }
+ m_msg = sb;
+ m_shape = FORCE_NONE;
+ m_newEncoding = -1;
+ m_pos = 0;
+ m_symbolInfo = NULL;
+ m_skipAtEnd = 0;
+ m_maxSize = NULL;
+ m_minSize = NULL;
+}
+CBC_EncoderContext::~CBC_EncoderContext()
+{
+}
+void CBC_EncoderContext::setSymbolShape(SymbolShapeHint shape)
+{
+ m_shape = shape;
+}
+void CBC_EncoderContext::setSizeConstraints(CBC_Dimension* minSize, CBC_Dimension* maxSize)
+{
+ m_maxSize = maxSize;
+ m_minSize = minSize;
+}
+CFX_WideString CBC_EncoderContext::getMessage()
+{
+ return m_msg;
+}
+void CBC_EncoderContext::setSkipAtEnd(FX_INT32 count)
+{
+ m_skipAtEnd = count;
+}
+FX_WCHAR CBC_EncoderContext::getCurrentChar()
+{
+ return m_msg.GetAt(m_pos);
+}
+FX_WCHAR CBC_EncoderContext::getCurrent()
+{
+ return m_msg.GetAt(m_pos);
+}
+void CBC_EncoderContext::writeCodewords(CFX_WideString codewords)
+{
+ m_codewords += codewords;
+}
+void CBC_EncoderContext::writeCodeword(FX_WCHAR codeword)
+{
+ m_codewords += codeword;
+}
+FX_INT32 CBC_EncoderContext::getCodewordCount()
+{
+ return m_codewords.GetLength();
+}
+void CBC_EncoderContext::signalEncoderChange(FX_INT32 encoding)
+{
+ m_newEncoding = encoding;
+}
+void CBC_EncoderContext::resetEncoderSignal()
+{
+ m_newEncoding = -1;
+}
+FX_BOOL CBC_EncoderContext::hasMoreCharacters()
+{
+ return m_pos < getTotalMessageCharCount();
+}
+FX_INT32 CBC_EncoderContext::getRemainingCharacters()
+{
+ return getTotalMessageCharCount() - m_pos;
+}
+void CBC_EncoderContext::updateSymbolInfo(FX_INT32 &e)
+{
+ updateSymbolInfo(getCodewordCount(), e);
+}
+void CBC_EncoderContext::updateSymbolInfo(FX_INT32 len, FX_INT32 &e)
+{
+ if (m_symbolInfo == NULL || len > m_symbolInfo->m_dataCapacity) {
+ m_symbolInfo = CBC_SymbolInfo::lookup(len, m_shape, m_minSize, m_maxSize, true, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_EncoderContext::resetSymbolInfo()
+{
+ m_shape = FORCE_NONE;
+}
+FX_INT32 CBC_EncoderContext::getTotalMessageCharCount()
+{
+ return m_msg.GetLength() - m_skipAtEnd;
+}
diff --git a/xfa/src/fxbarcode/src/BC_ErrorCorrection.cpp b/xfa/src/fxbarcode/src/BC_ErrorCorrection.cpp
new file mode 100644
index 0000000000..1e5738ff01
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_ErrorCorrection.cpp
@@ -0,0 +1,178 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_ErrorCorrection.h"
+FX_INT32 CBC_ErrorCorrection::FACTOR_SETS[] = {5, 7, 10, 11, 12, 14, 18, 20, 24, 28, 36, 42, 48, 56, 62, 68};
+FX_INT32 CBC_ErrorCorrection::FACTORS[][100] = {
+ {228, 48, 15, 111, 62},
+ {23, 68, 144, 134, 240, 92, 254},
+ {28, 24, 185, 166, 223, 248, 116, 255, 110, 61},
+ {175, 138, 205, 12, 194, 168, 39, 245, 60, 97, 120},
+ {41, 153, 158, 91, 61, 42, 142, 213, 97, 178, 100, 242},
+ {156, 97, 192, 252, 95, 9, 157, 119, 138, 45, 18, 186, 83, 185},
+ {83, 195, 100, 39, 188, 75, 66, 61, 241, 213, 109, 129, 94, 254, 225, 48, 90, 188},
+ {15, 195, 244, 9, 233, 71, 168, 2, 188, 160, 153, 145, 253, 79, 108, 82, 27, 174, 186, 172},
+ {
+ 52, 190, 88, 205, 109, 39, 176, 21, 155, 197, 251, 223, 155, 21, 5, 172,
+ 254, 124, 12, 181, 184, 96, 50, 193
+ },
+ {
+ 211, 231, 43, 97, 71, 96, 103, 174, 37, 151, 170, 53, 75, 34, 249, 121,
+ 17, 138, 110, 213, 141, 136, 120, 151, 233, 168, 93, 255
+ },
+ {
+ 245, 127, 242, 218, 130, 250, 162, 181, 102, 120, 84, 179, 220, 251, 80, 182,
+ 229, 18, 2, 4, 68, 33, 101, 137, 95, 119, 115, 44, 175, 184, 59, 25,
+ 225, 98, 81, 112
+ },
+ {
+ 77, 193, 137, 31, 19, 38, 22, 153, 247, 105, 122, 2, 245, 133, 242, 8,
+ 175, 95, 100, 9, 167, 105, 214, 111, 57, 121, 21, 1, 253, 57, 54, 101,
+ 248, 202, 69, 50, 150, 177, 226, 5, 9, 5
+ },
+ {
+ 245, 132, 172, 223, 96, 32, 117, 22, 238, 133, 238, 231, 205, 188, 237, 87,
+ 191, 106, 16, 147, 118, 23, 37, 90, 170, 205, 131, 88, 120, 100, 66, 138,
+ 186, 240, 82, 44, 176, 87, 187, 147, 160, 175, 69, 213, 92, 253, 225, 19
+ },
+ {
+ 175, 9, 223, 238, 12, 17, 220, 208, 100, 29, 175, 170, 230, 192, 215, 235,
+ 150, 159, 36, 223, 38, 200, 132, 54, 228, 146, 218, 234, 117, 203, 29, 232,
+ 144, 238, 22, 150, 201, 117, 62, 207, 164, 13, 137, 245, 127, 67, 247, 28,
+ 155, 43, 203, 107, 233, 53, 143, 46
+ },
+ {
+ 242, 93, 169, 50, 144, 210, 39, 118, 202, 188, 201, 189, 143, 108, 196, 37,
+ 185, 112, 134, 230, 245, 63, 197, 190, 250, 106, 185, 221, 175, 64, 114, 71,
+ 161, 44, 147, 6, 27, 218, 51, 63, 87, 10, 40, 130, 188, 17, 163, 31,
+ 176, 170, 4, 107, 232, 7, 94, 166, 224, 124, 86, 47, 11, 204
+ },
+ {
+ 220, 228, 173, 89, 251, 149, 159, 56, 89, 33, 147, 244, 154, 36, 73, 127,
+ 213, 136, 248, 180, 234, 197, 158, 177, 68, 122, 93, 213, 15, 160, 227, 236,
+ 66, 139, 153, 185, 202, 167, 179, 25, 220, 232, 96, 210, 231, 136, 223, 239,
+ 181, 241, 59, 52, 172, 25, 49, 232, 211, 189, 64, 54, 108, 153, 132, 63,
+ 96, 103, 82, 186
+ }
+};
+FX_INT32 CBC_ErrorCorrection::MODULO_VALUE = 0x12D;
+FX_INT32 CBC_ErrorCorrection::LOG[256] = {0};
+FX_INT32 CBC_ErrorCorrection::ALOG[256] = {0};
+void CBC_ErrorCorrection::Initialize()
+{
+ FX_INT32 p = 1;
+ for (FX_INT32 i = 0; i < 255; i++) {
+ ALOG[i] = p;
+ LOG[p] = i;
+ p <<= 1;
+ if (p >= 256) {
+ p ^= MODULO_VALUE;
+ }
+ }
+}
+void CBC_ErrorCorrection::Finalize()
+{
+}
+CBC_ErrorCorrection::CBC_ErrorCorrection()
+{
+}
+CBC_ErrorCorrection::~CBC_ErrorCorrection()
+{
+}
+CFX_WideString CBC_ErrorCorrection::encodeECC200(CFX_WideString codewords, CBC_SymbolInfo* symbolInfo, FX_INT32 &e)
+{
+ if (codewords.GetLength() != symbolInfo->m_dataCapacity) {
+ e = BCExceptionIllegalArgument;
+ return (FX_LPWSTR)"";
+ }
+ CFX_WideString sb;
+ sb += codewords;
+ FX_INT32 blockCount = symbolInfo->getInterleavedBlockCount();
+ if (blockCount == 1) {
+ CFX_WideString ecc = createECCBlock(codewords, symbolInfo->m_errorCodewords, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_LPWSTR)"");
+ sb += ecc;
+ } else {
+ CFX_Int32Array dataSizes;
+ dataSizes.SetSize(blockCount);
+ CFX_Int32Array errorSizes;
+ errorSizes.SetSize(blockCount);
+ CFX_Int32Array startPos;
+ startPos.SetSize(blockCount);
+ for (FX_INT32 i = 0; i < blockCount; i++) {
+ dataSizes[i] = symbolInfo->getDataLengthForInterleavedBlock(i + 1);
+ errorSizes[i] = symbolInfo->getErrorLengthForInterleavedBlock(i + 1);
+ startPos[i] = 0;
+ if (i > 0) {
+ startPos[i] = startPos[i - 1] + dataSizes[i];
+ }
+ }
+ for (FX_INT32 block = 0; block < blockCount; block++) {
+ CFX_WideString temp;
+ for (FX_INT32 d = block; d < symbolInfo->m_dataCapacity; d += blockCount) {
+ temp += (FX_WCHAR)codewords.GetAt(d);
+ }
+ CFX_WideString ecc = createECCBlock(temp, errorSizes[block], e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_LPWSTR)"");
+ FX_INT32 pos = 0;
+ for (FX_INT32 l = block; l < errorSizes[block] * blockCount; l += blockCount) {
+ sb.SetAt(symbolInfo->m_dataCapacity + l, ecc.GetAt(pos++));
+ }
+ }
+ }
+ return sb;
+}
+CFX_WideString CBC_ErrorCorrection::createECCBlock(CFX_WideString codewords, FX_INT32 numECWords, FX_INT32 &e)
+{
+ return createECCBlock(codewords, 0, codewords.GetLength(), numECWords, e);
+}
+CFX_WideString CBC_ErrorCorrection::createECCBlock(CFX_WideString codewords, FX_INT32 start, FX_INT32 len, FX_INT32 numECWords, FX_INT32 &e)
+{
+ FX_INT32 table = -1;
+ for (FX_INT32 i = 0; i < sizeof(FACTOR_SETS) / sizeof(FX_INT32); i++) {
+ if (FACTOR_SETS[i] == numECWords) {
+ table = i;
+ break;
+ }
+ }
+ if (table < 0) {
+ e = BCExceptionIllegalArgument;
+ return (FX_LPWSTR)"";
+ }
+ FX_WORD* ecc = FX_Alloc(FX_WORD, numECWords);
+ FXSYS_memset32(ecc, 0, numECWords * sizeof(FX_WORD));
+ for (FX_INT32 l = start; l < start + len; l++) {
+ FX_BYTE A = (FX_BYTE)codewords.GetAt(l);
+ FX_WORD B = ecc[numECWords - 1];
+ FX_WORD m = ecc[numECWords - 1] ^ codewords.GetAt(l);
+ for (FX_INT32 k = numECWords - 1; k > 0; k--) {
+ if (m != 0 && FACTORS[table][k] != 0) {
+ FX_INT32 a = LOG[FACTORS[table][k]];
+ FX_INT32 b = ALOG[(LOG[m] + LOG[FACTORS[table][k]]) % 255];
+ FX_WORD c = ecc[k - 1];
+ FX_WORD D = (ecc[k - 1] ^ ALOG[(LOG[m] + LOG[FACTORS[table][k]]) % 255]);
+ ecc[k] = (FX_WORD ) (ecc[k - 1] ^ ALOG[(LOG[m] + LOG[FACTORS[table][k]]) % 255]);
+ } else {
+ ecc[k] = ecc[k - 1];
+ }
+ }
+ if (m != 0 && FACTORS[table][0] != 0) {
+ ecc[0] = (FX_WORD) ALOG[(LOG[m] + LOG[FACTORS[table][0]]) % 255];
+ } else {
+ ecc[0] = 0;
+ }
+ }
+ CFX_WideString strecc;
+ for (FX_INT32 j = 0; j < numECWords; j++) {
+ strecc += (FX_WCHAR)ecc[numECWords - j - 1];
+ }
+ FX_Free(ecc);
+ return strecc;
+}
diff --git a/xfa/src/fxbarcode/src/BC_FinderPatternInfo.cpp b/xfa/src/fxbarcode/src/BC_FinderPatternInfo.cpp
new file mode 100644
index 0000000000..186ed063a8
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_FinderPatternInfo.cpp
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRFinderPattern.h"
+#include "include/BC_FinderPatternInfo.h"
+CBC_QRFinderPatternInfo::CBC_QRFinderPatternInfo(CFX_PtrArray *patternCenters)
+{
+ m_bottomLeft = (CBC_QRFinderPattern*)(*patternCenters)[0];
+ m_topLeft = (CBC_QRFinderPattern*)(*patternCenters)[1];
+ m_topRight = (CBC_QRFinderPattern*)(*patternCenters)[2];
+}
+CBC_QRFinderPatternInfo::~CBC_QRFinderPatternInfo()
+{
+}
+CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetBottomLeft()
+{
+ return m_bottomLeft;
+}
+CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetTopLeft()
+{
+ return m_topLeft;
+}
+CBC_QRFinderPattern* CBC_QRFinderPatternInfo::GetTopRight()
+{
+ return m_topRight;
+}
diff --git a/xfa/src/fxbarcode/src/BC_GlobalHistogramBinarizer.cpp b/xfa/src/fxbarcode/src/BC_GlobalHistogramBinarizer.cpp
new file mode 100644
index 0000000000..e20ad68e70
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_GlobalHistogramBinarizer.cpp
@@ -0,0 +1,153 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Binarizer.h"
+#include "include/BC_LuminanceSource.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_GlobalHistogramBinarizer.h"
+const FX_INT32 LUMINANCE_BITS = 5;
+const FX_INT32 LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
+const FX_INT32 LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
+CBC_GlobalHistogramBinarizer::CBC_GlobalHistogramBinarizer(CBC_LuminanceSource *source): CBC_Binarizer(source)
+{
+}
+CBC_GlobalHistogramBinarizer::~CBC_GlobalHistogramBinarizer()
+{
+}
+CBC_CommonBitArray *CBC_GlobalHistogramBinarizer::GetBlackRow(FX_INT32 y, CBC_CommonBitArray *row, FX_INT32 &e)
+{
+ CBC_LuminanceSource *source = GetLuminanceSource();
+ FX_INT32 width = source->GetWidth();
+ CBC_AutoPtr<CBC_CommonBitArray> result(FX_NEW CBC_CommonBitArray(width));
+ InitArrays(width);
+ CFX_ByteArray *localLuminances = source->GetRow(y, m_luminance, e);
+ if (e != BCExceptionNO) {
+ return result.release();
+ }
+ CFX_Int32Array localBuckets;
+ localBuckets.Copy(m_buckets);
+ FX_INT32 x;
+ for (x = 0; x < width; x++) {
+ FX_INT32 pixel = (*localLuminances)[x] & 0xff;
+ localBuckets[pixel >> LUMINANCE_SHIFT]++;
+ }
+ FX_INT32 blackPoint = EstimateBlackPoint(localBuckets, e);
+ if (e != BCExceptionNO) {
+ return result.release();
+ }
+ FX_INT32 left = (*localLuminances)[0] & 0xff;
+ FX_INT32 center = (*localLuminances)[1] & 0xff;
+ for (x = 1; x < width - 1; x++) {
+ FX_INT32 right = (*localLuminances)[x + 1] & 0xff;
+ FX_INT32 luminance = ((center << 2) - left - right) >> 1;
+ if (luminance < blackPoint) {
+ result->Set(x);
+ }
+ left = center;
+ center = right;
+ }
+ return result.release();
+}
+CBC_CommonBitMatrix *CBC_GlobalHistogramBinarizer::GetBlackMatrix(FX_INT32 &e)
+{
+ CBC_LuminanceSource *source = GetLuminanceSource();
+ FX_INT32 width = source->GetWidth();
+ FX_INT32 height = source->GetHeight();
+ CBC_CommonBitMatrix *BitMatrixTemp = FX_NEW CBC_CommonBitMatrix();
+ BitMatrixTemp->Init(width, height);
+ CBC_AutoPtr<CBC_CommonBitMatrix> matrix(BitMatrixTemp);
+ InitArrays(width);
+ CFX_Int32Array localBuckets;
+ localBuckets.Copy(m_buckets);
+ FX_INT32 y;
+ for (y = 1; y < 5; y++) {
+ FX_INT32 row = height * y / 5;
+ CFX_ByteArray *localLuminances = source->GetRow(row, m_luminance, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 right = (width << 2) / 5;
+ FX_INT32 x;
+ for (x = width / 5; x < right; x++) {
+ FX_INT32 pixel = (*localLuminances)[x] & 0xff;
+ localBuckets[pixel >> LUMINANCE_SHIFT]++;
+ }
+ }
+ FX_INT32 blackPoint = EstimateBlackPoint(localBuckets, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CFX_ByteArray> localLuminances(source->GetMatrix());
+ for (y = 0; y < height; y++) {
+ FX_INT32 offset = y * width;
+ for (FX_INT32 x = 0; x < width; x++) {
+ FX_INT32 pixel = (*localLuminances)[offset + x] & 0xff;
+ if (pixel < blackPoint) {
+ matrix->Set(x, y);
+ }
+ }
+ }
+ return matrix.release();
+}
+void CBC_GlobalHistogramBinarizer::InitArrays(FX_INT32 luminanceSize)
+{
+ if(m_luminance.GetSize() < luminanceSize) {
+ m_luminance.SetSize(luminanceSize);
+ }
+ if(m_buckets.GetSize() <= 0) {
+ m_buckets.SetSize(LUMINANCE_BUCKETS);
+ } else {
+ FX_INT32 x;
+ for(x = 0; x < LUMINANCE_BUCKETS; x++) {
+ m_buckets[x] = 0;
+ }
+ }
+}
+FX_INT32 CBC_GlobalHistogramBinarizer::EstimateBlackPoint(CFX_Int32Array &buckets, FX_INT32 &e)
+{
+ FX_INT32 numBuckets = buckets.GetSize();
+ FX_INT32 maxBucketCount = 0;
+ FX_INT32 firstPeak = 0;
+ FX_INT32 firstPeakSize = 0;
+ FX_INT32 x;
+ for (x = 0; x < numBuckets; x++) {
+ if (buckets[x] > firstPeakSize) {
+ firstPeak = x;
+ firstPeakSize = buckets[x];
+ }
+ if (buckets[x] > maxBucketCount) {
+ maxBucketCount = buckets[x];
+ }
+ }
+ FX_INT32 secondPeak = 0;
+ FX_INT32 secondPeakScore = 0;
+ for (x = 0; x < numBuckets; x++) {
+ FX_INT32 distanceToBiggest = x - firstPeak;
+ FX_INT32 score = buckets[x] * distanceToBiggest * distanceToBiggest;
+ if (score > secondPeakScore) {
+ secondPeak = x;
+ secondPeakScore = score;
+ }
+ }
+ if (firstPeak > secondPeak) {
+ FX_INT32 temp = firstPeak;
+ firstPeak = secondPeak;
+ secondPeak = temp;
+ }
+ if (secondPeak - firstPeak <= numBuckets >> 4) {
+ e = BCExceptionRead;
+ return 0;
+ }
+ FX_INT32 bestValley = secondPeak - 1;
+ FX_INT32 bestValleyScore = -1;
+ for (x = secondPeak - 1; x > firstPeak; x--) {
+ FX_INT32 fromFirst = x - firstPeak;
+ FX_INT32 score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - buckets[x]);
+ if (score > bestValleyScore) {
+ bestValley = x;
+ bestValleyScore = score;
+ }
+ }
+ return bestValley << LUMINANCE_SHIFT;
+}
diff --git a/xfa/src/fxbarcode/src/BC_HighLevelEncoder.cpp b/xfa/src/fxbarcode/src/BC_HighLevelEncoder.cpp
new file mode 100644
index 0000000000..d1bedb6478
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_HighLevelEncoder.cpp
@@ -0,0 +1,352 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_C40Encoder.h"
+#include "include/BC_TextEncoder.h"
+#include "include/BC_X12Encoder.h"
+#include "include/BC_EdifactEncoder.h"
+#include "include/BC_Base256Encoder.h"
+#include "include/BC_ASCIIEncoder.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_UtilCodingConvert.h"
+#define Integer_MAX_VALUE 2147483647
+FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_C40 = 230;
+FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_BASE256 = 231;
+FX_WCHAR CBC_HighLevelEncoder::UPPER_SHIFT = 235;
+FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_ANSIX12 = 238;
+FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_TEXT = 239;
+FX_WCHAR CBC_HighLevelEncoder::LATCH_TO_EDIFACT = 240;
+FX_WCHAR CBC_HighLevelEncoder::C40_UNLATCH = 254;
+FX_WCHAR CBC_HighLevelEncoder::X12_UNLATCH = 254;
+FX_WCHAR CBC_HighLevelEncoder::PAD = 129;
+FX_WCHAR CBC_HighLevelEncoder::MACRO_05 = 236;
+FX_WCHAR CBC_HighLevelEncoder::MACRO_06 = 237;
+const wchar_t* CBC_HighLevelEncoder::MACRO_05_HEADER = L"[)>05";
+const wchar_t* CBC_HighLevelEncoder::MACRO_06_HEADER = L"[)>06";
+const wchar_t CBC_HighLevelEncoder::MACRO_TRAILER = 0x0004;
+CBC_HighLevelEncoder::CBC_HighLevelEncoder()
+{
+}
+CBC_HighLevelEncoder::~CBC_HighLevelEncoder()
+{
+}
+CFX_ByteArray& CBC_HighLevelEncoder::getBytesForMessage(CFX_WideString msg)
+{
+ CFX_ByteString bytestr;
+ CBC_UtilCodingConvert::UnicodeToUTF8(msg, bytestr);
+ for (FX_INT32 i = 0; i < bytestr.GetLength(); i++) {
+ m_bytearray.Add(bytestr.GetAt(i));
+ }
+ return m_bytearray;
+}
+CFX_WideString CBC_HighLevelEncoder::encodeHighLevel(CFX_WideString msg, CFX_WideString ecLevel, FX_INT32 &e)
+{
+ return encodeHighLevel(msg, ecLevel, FORCE_NONE, NULL, NULL, e);
+}
+CFX_WideString CBC_HighLevelEncoder::encodeHighLevel(CFX_WideString msg, CFX_WideString ecLevel, SymbolShapeHint shape, CBC_Dimension* minSize, CBC_Dimension* maxSize, FX_INT32 &e)
+{
+ CBC_EncoderContext context(msg, ecLevel, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_LPWSTR)"");
+ context.setSymbolShape(shape);
+ context.setSizeConstraints(minSize, maxSize);
+ if ((msg.Mid(0, 6) == MACRO_05_HEADER) && (msg.Mid(msg.GetLength() - 1, 1) == MACRO_TRAILER)) {
+ context.writeCodeword(MACRO_05);
+ context.setSkipAtEnd(2);
+ context.m_pos += 6;
+ } else if ((msg.Mid(0, 6) == MACRO_06_HEADER) && (msg.Mid(msg.GetLength() - 1, 1) == MACRO_TRAILER)) {
+ context.writeCodeword(MACRO_06);
+ context.setSkipAtEnd(2);
+ context.m_pos += 6;
+ }
+ CFX_PtrArray encoders;
+ encoders.Add(FX_NEW CBC_ASCIIEncoder());
+ encoders.Add(FX_NEW CBC_C40Encoder());
+ encoders.Add(FX_NEW CBC_TextEncoder());
+ encoders.Add(FX_NEW CBC_X12Encoder());
+ encoders.Add(FX_NEW CBC_EdifactEncoder());
+ encoders.Add(FX_NEW CBC_Base256Encoder());
+ FX_INT32 encodingMode = ASCII_ENCODATION;
+ while (context.hasMoreCharacters()) {
+ ((CBC_Encoder*)encoders.GetAt(encodingMode))->Encode(context, e);
+ if (e != BCExceptionNO) {
+ for (FX_INT32 i = 0; i < encoders.GetSize(); i++) {
+ delete (CBC_Encoder*)encoders.GetAt(i);
+ }
+ encoders.RemoveAll();
+ return (FX_LPWSTR)"";
+ }
+ if (context.m_newEncoding >= 0) {
+ encodingMode = context.m_newEncoding;
+ context.resetEncoderSignal();
+ }
+ }
+ FX_INT32 len = context.m_codewords.GetLength();
+ context.updateSymbolInfo(e);
+ if (e != BCExceptionNO) {
+ for (FX_INT32 i = 0; i < encoders.GetSize(); i++) {
+ delete (CBC_Encoder*)encoders.GetAt(i);
+ }
+ encoders.RemoveAll();
+ return (FX_LPWSTR)"";
+ }
+ FX_INT32 capacity = context.m_symbolInfo->m_dataCapacity;
+ if (len < capacity) {
+ if (encodingMode != ASCII_ENCODATION && encodingMode != BASE256_ENCODATION) {
+ context.writeCodeword(0x00fe);
+ }
+ }
+ CFX_WideString codewords = context.m_codewords;
+ if (codewords.GetLength() < capacity) {
+ codewords += PAD;
+ }
+ while (codewords.GetLength() < capacity) {
+ codewords += (randomize253State(PAD, codewords.GetLength() + 1));
+ }
+ for (FX_INT32 i = 0; i < encoders.GetSize(); i++) {
+ delete (CBC_Encoder*)encoders.GetAt(i);
+ }
+ encoders.RemoveAll();
+ return codewords;
+}
+FX_INT32 CBC_HighLevelEncoder::lookAheadTest(CFX_WideString msg, FX_INT32 startpos, FX_INT32 currentMode)
+{
+ if (startpos >= msg.GetLength()) {
+ return currentMode;
+ }
+ CFX_FloatArray charCounts;
+ if (currentMode == ASCII_ENCODATION) {
+ charCounts.Add(0);
+ charCounts.Add(1);
+ charCounts.Add(1);
+ charCounts.Add(1);
+ charCounts.Add(1);
+ charCounts.Add(1.25f);
+ } else {
+ charCounts.Add(1);
+ charCounts.Add(2);
+ charCounts.Add(2);
+ charCounts.Add(2);
+ charCounts.Add(2);
+ charCounts.Add(2.25f);
+ charCounts[currentMode] = 0;
+ }
+ FX_INT32 charsProcessed = 0;
+ while (TRUE) {
+ if ((startpos + charsProcessed) == msg.GetLength()) {
+ FX_DWORD min = Integer_MAX_VALUE;
+ CFX_ByteArray mins;
+ mins.SetSize(6);
+ CFX_Int32Array intCharCounts;
+ intCharCounts.SetSize(6);
+ min = findMinimums(charCounts, intCharCounts, min, mins);
+ FX_INT32 minCount = getMinimumCount(mins);
+ if (intCharCounts[ASCII_ENCODATION] == min) {
+ return ASCII_ENCODATION;
+ }
+ if (minCount == 1 && mins[BASE256_ENCODATION] > 0) {
+ return BASE256_ENCODATION;
+ }
+ if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) {
+ return EDIFACT_ENCODATION;
+ }
+ if (minCount == 1 && mins[TEXT_ENCODATION] > 0) {
+ return TEXT_ENCODATION;
+ }
+ if (minCount == 1 && mins[X12_ENCODATION] > 0) {
+ return X12_ENCODATION;
+ }
+ return C40_ENCODATION;
+ }
+ FX_WCHAR c = msg.GetAt(startpos + charsProcessed);
+ charsProcessed++;
+ if (isDigit(c)) {
+ charCounts[ASCII_ENCODATION] += 0.5;
+ } else if (isExtendedASCII(c)) {
+ charCounts[ASCII_ENCODATION] = (FX_FLOAT) ceil(charCounts[ASCII_ENCODATION]);
+ charCounts[ASCII_ENCODATION] += 2;
+ } else {
+ charCounts[ASCII_ENCODATION] = (FX_FLOAT) ceil(charCounts[ASCII_ENCODATION]);
+ charCounts[ASCII_ENCODATION]++;
+ }
+ if (isNativeC40(c)) {
+ charCounts[C40_ENCODATION] += 2.0f / 3.0f;
+ } else if (isExtendedASCII(c)) {
+ charCounts[C40_ENCODATION] += 8.0f / 3.0f;
+ } else {
+ charCounts[C40_ENCODATION] += 4.0f / 3.0f;
+ }
+ if (isNativeText(c)) {
+ charCounts[TEXT_ENCODATION] += 2.0f / 3.0f;
+ } else if (isExtendedASCII(c)) {
+ charCounts[TEXT_ENCODATION] += 8.0f / 3.0f;
+ } else {
+ charCounts[TEXT_ENCODATION] += 4.0f / 3.0f;
+ }
+ if (isNativeX12(c)) {
+ charCounts[X12_ENCODATION] += 2.0f / 3.0f;
+ } else if (isExtendedASCII(c)) {
+ charCounts[X12_ENCODATION] += 13.0f / 3.0f;
+ } else {
+ charCounts[X12_ENCODATION] += 10.0f / 3.0f;
+ }
+ if (isNativeEDIFACT(c)) {
+ charCounts[EDIFACT_ENCODATION] += 3.0f / 4.0f;
+ } else if (isExtendedASCII(c)) {
+ charCounts[EDIFACT_ENCODATION] += 17.0f / 4.0f;
+ } else {
+ charCounts[EDIFACT_ENCODATION] += 13.0f / 4.0f;
+ }
+ if (isSpecialB256(c)) {
+ charCounts[BASE256_ENCODATION] += 4;
+ } else {
+ charCounts[BASE256_ENCODATION]++;
+ }
+ if (charsProcessed >= 4) {
+ CFX_Int32Array intCharCounts;
+ intCharCounts.SetSize(6);
+ CFX_ByteArray mins;
+ mins.SetSize(6);
+ findMinimums(charCounts, intCharCounts, Integer_MAX_VALUE, mins);
+ FX_INT32 minCount = getMinimumCount(mins);
+ if (intCharCounts[ASCII_ENCODATION] < intCharCounts[BASE256_ENCODATION]
+ && intCharCounts[ASCII_ENCODATION] < intCharCounts[C40_ENCODATION]
+ && intCharCounts[ASCII_ENCODATION] < intCharCounts[TEXT_ENCODATION]
+ && intCharCounts[ASCII_ENCODATION] < intCharCounts[X12_ENCODATION]
+ && intCharCounts[ASCII_ENCODATION] < intCharCounts[EDIFACT_ENCODATION]) {
+ return ASCII_ENCODATION;
+ }
+ if (intCharCounts[BASE256_ENCODATION] < intCharCounts[ASCII_ENCODATION]
+ || (mins[C40_ENCODATION] + mins[TEXT_ENCODATION] + mins[X12_ENCODATION] + mins[EDIFACT_ENCODATION]) == 0) {
+ return BASE256_ENCODATION;
+ }
+ if (minCount == 1 && mins[EDIFACT_ENCODATION] > 0) {
+ return EDIFACT_ENCODATION;
+ }
+ if (minCount == 1 && mins[TEXT_ENCODATION] > 0) {
+ return TEXT_ENCODATION;
+ }
+ if (minCount == 1 && mins[X12_ENCODATION] > 0) {
+ return X12_ENCODATION;
+ }
+ if (intCharCounts[C40_ENCODATION] + 1 < intCharCounts[ASCII_ENCODATION]
+ && intCharCounts[C40_ENCODATION] + 1 < intCharCounts[BASE256_ENCODATION]
+ && intCharCounts[C40_ENCODATION] + 1 < intCharCounts[EDIFACT_ENCODATION]
+ && intCharCounts[C40_ENCODATION] + 1 < intCharCounts[TEXT_ENCODATION]) {
+ if (intCharCounts[C40_ENCODATION] < intCharCounts[X12_ENCODATION]) {
+ return C40_ENCODATION;
+ }
+ if (intCharCounts[C40_ENCODATION] == intCharCounts[X12_ENCODATION]) {
+ FX_INT32 p = startpos + charsProcessed + 1;
+ while (p < msg.GetLength()) {
+ FX_WCHAR tc = msg.GetAt(p);
+ if (isX12TermSep(tc)) {
+ return X12_ENCODATION;
+ }
+ if (!isNativeX12(tc)) {
+ break;
+ }
+ p++;
+ }
+ return C40_ENCODATION;
+ }
+ }
+ }
+ }
+}
+FX_BOOL CBC_HighLevelEncoder::isDigit(FX_WCHAR ch)
+{
+ return ch >= '0' && ch <= '9';
+}
+FX_BOOL CBC_HighLevelEncoder::isExtendedASCII(FX_WCHAR ch)
+{
+ return ch >= 128 && ch <= 255;
+}
+FX_INT32 CBC_HighLevelEncoder::determineConsecutiveDigitCount(CFX_WideString msg, FX_INT32 startpos)
+{
+ FX_INT32 count = 0;
+ FX_INT32 len = msg.GetLength();
+ FX_INT32 idx = startpos;
+ if (idx < len) {
+ FX_WCHAR ch = msg.GetAt(idx);
+ while (isDigit(ch) && idx < len) {
+ count++;
+ idx++;
+ if (idx < len) {
+ ch = msg.GetAt(idx);
+ }
+ }
+ }
+ return count;
+}
+void CBC_HighLevelEncoder::illegalCharacter(FX_WCHAR c, FX_INT32 &e)
+{
+ e = BCExceptionIllegalArgument;
+}
+FX_WCHAR CBC_HighLevelEncoder::randomize253State(FX_WCHAR ch, FX_INT32 codewordPosition)
+{
+ FX_INT32 pseudoRandom = ((149 * codewordPosition) % 253) + 1;
+ FX_INT32 tempVariable = ch + pseudoRandom;
+ return tempVariable <= 254 ? (FX_WCHAR) tempVariable : (FX_WCHAR) (tempVariable - 254);
+}
+FX_INT32 CBC_HighLevelEncoder::findMinimums(CFX_FloatArray &charCounts, CFX_Int32Array &intCharCounts, FX_INT32 min, CFX_ByteArray &mins)
+{
+ for (FX_INT32 l = 0; l < mins.GetSize(); l++) {
+ mins[l] = (FX_BYTE)0;
+ }
+ for (FX_INT32 i = 0; i < 6; i++) {
+ intCharCounts[i] = (FX_INT32)ceil(charCounts[i]);
+ FX_INT32 current = intCharCounts[i];
+ if (min > current) {
+ min = current;
+ for (FX_INT32 j = 0; j < mins.GetSize(); j++) {
+ mins[j] = (FX_BYTE)0;
+ }
+ }
+ if (min == current) {
+ mins[i]++;
+ }
+ }
+ return min;
+}
+FX_INT32 CBC_HighLevelEncoder::getMinimumCount(CFX_ByteArray &mins)
+{
+ FX_INT32 minCount = 0;
+ for (FX_INT32 i = 0; i < 6; i++) {
+ minCount += mins[i];
+ }
+ return minCount;
+}
+FX_BOOL CBC_HighLevelEncoder::isNativeC40(FX_WCHAR ch)
+{
+ return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z');
+}
+FX_BOOL CBC_HighLevelEncoder::isNativeText(FX_WCHAR ch)
+{
+ return (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z');
+}
+FX_BOOL CBC_HighLevelEncoder::isNativeX12(FX_WCHAR ch)
+{
+ return isX12TermSep(ch) || (ch == ' ') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z');
+}
+FX_BOOL CBC_HighLevelEncoder::isX12TermSep(FX_WCHAR ch)
+{
+ return (ch == '\r') || (ch == '*') || (ch == '>');
+}
+FX_BOOL CBC_HighLevelEncoder::isNativeEDIFACT(FX_WCHAR ch)
+{
+ return ch >= ' ' && ch <= '^';
+}
+FX_BOOL CBC_HighLevelEncoder::isSpecialB256(FX_WCHAR ch)
+{
+ return FALSE;
+}
diff --git a/xfa/src/fxbarcode/src/BC_Library.cpp b/xfa/src/fxbarcode/src/BC_Library.cpp
new file mode 100644
index 0000000000..5b12609517
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Library.cpp
@@ -0,0 +1,122 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_UtilCodingConvert.h"
+#include "include/BC_DataMatrixVersion.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_LuminanceSource.h"
+#include "include/BC_BufferedImageLuminanceSource.h"
+#include "include/BC_Binarizer.h"
+#include "include/BC_GlobalHistogramBinarizer.h"
+#include "include/BC_OnedCode128Reader.h"
+#include "include/BC_OnedCode39Reader.h"
+#include "include/BC_OneDimReader.h"
+#include "include/BC_OnedEAN13Reader.h"
+#include "include/BC_OnedEAN8Reader.h"
+#include "include/BC_OnedUPCAReader.h"
+#include "include/BC_OnedCodaBarReader.h"
+#include "include/BC_DataMatrixReader.h"
+#include "include/BC_QRCodeReader.h"
+#include "include/BC_Writer.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OnedCode128Writer.h"
+#include "include/BC_OnedCode39Writer.h"
+#include "include/BC_OnedEAN13Writer.h"
+#include "include/BC_OnedEAN8Writer.h"
+#include "include/BC_OnedUPCAWriter.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRCodeWriter.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_QRCoderMode.h"
+#include "include/BC_QRCoderVersion.h"
+#include "include/BC_QRDataMask.h"
+#include "include/BC_QRDecodedBitStreamParser.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_DefaultPlacement.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_DataMatrixSymbolInfo144.h"
+#include "include/BC_ErrorCorrection.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_C40Encoder.h"
+#include "include/BC_TextEncoder.h"
+#include "include/BC_X12Encoder.h"
+#include "include/BC_EdifactEncoder.h"
+#include "include/BC_Base256Encoder.h"
+#include "include/BC_ASCIIEncoder.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_CommonByteMatrix.h"
+#include "include/BC_DataMatrixWriter.h"
+#include "include/BC_PDF417Compaction.h"
+#include "include/BC_UtilCodingConvert.h"
+#include "include/BC_PDF417HighLevelEncoder.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_PDF417DetectorResult.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_PDF417Detector.h"
+#include "include/BC_PDF417DetectorResult.h"
+#include "include/BC_DecoderResult.h"
+#include "include/BC_PDF417Codeword.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417BarcodeValue.h"
+#include "include/BC_PDF417BarcodeMetadata.h"
+#include "include/BC_PDF417BoundingBox.h"
+#include "include/BC_PDF417DetectionResultColumn.h"
+#include "include/BC_PDF417DetectionResultRowIndicatorColumn.h"
+#include "include/BC_PDF417DetectionResult.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417CodewordDecoder.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417ECModulusPoly.h"
+#include "include/BC_PDF417ECModulusGF.h"
+#include "include/BC_PDF417ECErrorCorrection.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_PDF417ScanningDecoder.h"
+#include "include/BC_PDF417Reader.h"
+void BC_Library_Init()
+{
+ CBC_QRCoderErrorCorrectionLevel::Initialize();
+ CBC_QRCoderMode::Initialize();
+ CBC_QRCoderVersion::Initialize();
+ CBC_QRDataMask::Initialize();
+ CBC_ReedSolomonGF256::Initialize();
+ CBC_DataMatrixVersion::Initialize();
+ CBC_SymbolInfo::Initialize();
+ CBC_ErrorCorrection::Initialize();
+ CBC_PDF417HighLevelEncoder::Initialize();
+ FX_INT32 e = 0;
+ CBC_PDF417ECModulusGF::Initialize(e);
+ CBC_DecodedBitStreamPaser::Initialize();
+ CBC_PDF417CodewordDecoder::Initialize();
+ CBC_PDF417ECErrorCorrection::Initialize(e);
+ CBC_PDF417ScanningDecoder::Initialize();
+}
+void BC_Library_Destory()
+{
+ CBC_QRCoderErrorCorrectionLevel::Finalize();
+ CBC_QRCoderMode::Finalize();
+ CBC_QRCoderVersion::Finalize();
+ CBC_QRDataMask::Finalize();
+ CBC_ReedSolomonGF256::Finalize();
+ CBC_DataMatrixVersion::Finalize();
+ CBC_SymbolInfo::Finalize();
+ CBC_ErrorCorrection::Finalize();
+ CBC_PDF417HighLevelEncoder::Finalize();
+ CBC_DecodedBitStreamPaser::Finalize();
+ CBC_PDF417CodewordDecoder::Finalize();
+ CBC_PDF417ECErrorCorrection::Finalize();
+ CBC_PDF417ECModulusGF::Finalize();
+ CBC_PDF417ScanningDecoder::Finalize();
+}
diff --git a/xfa/src/fxbarcode/src/BC_LuminanceSource.cpp b/xfa/src/fxbarcode/src/BC_LuminanceSource.cpp
new file mode 100644
index 0000000000..ba61c93cfb
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_LuminanceSource.cpp
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_LuminanceSource.h"
+CBC_LuminanceSource::CBC_LuminanceSource(FX_INT32 width, FX_INT32 height): m_width(width), m_height(height)
+{
+}
+CBC_LuminanceSource::~CBC_LuminanceSource()
+{
+}
+FX_INT32 CBC_LuminanceSource::GetWidth()
+{
+ return m_width;
+}
+FX_INT32 CBC_LuminanceSource::GetHeight()
+{
+ return m_height;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OneDReader.cpp b/xfa/src/fxbarcode/src/BC_OneDReader.cpp
new file mode 100644
index 0000000000..b49d0fd0bc
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OneDReader.cpp
@@ -0,0 +1,163 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_CommonBitArray.h"
+const FX_INT32 CBC_OneDReader::INTEGER_MATH_SHIFT = 8;
+const FX_INT32 CBC_OneDReader::PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << 8;
+CBC_OneDReader::CBC_OneDReader()
+{
+}
+CBC_OneDReader::~CBC_OneDReader()
+{
+}
+CFX_ByteString CBC_OneDReader::Decode(CBC_BinaryBitmap *image, FX_INT32 &e)
+{
+ CFX_ByteString strtemp = Decode(image, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return strtemp;
+}
+CFX_ByteString CBC_OneDReader::Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_ByteString strtemp = DeDecode(image, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return strtemp;
+}
+CFX_ByteString CBC_OneDReader::DeDecode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e)
+{
+ FX_INT32 width = image->GetWidth();
+ FX_INT32 height = image->GetHeight();
+ CBC_CommonBitArray *row = NULL;
+ FX_INT32 middle = height >> 1;
+ FX_BOOL tryHarder = FALSE;
+ FX_INT32 rowStep = FX_MAX(1, height >> (tryHarder ? 8 : 5));
+ FX_INT32 maxLines;
+ if (tryHarder) {
+ maxLines = height;
+ } else {
+ maxLines = 15;
+ }
+ for (FX_INT32 x = 0; x < maxLines; x++) {
+ FX_INT32 rowStepsAboveOrBelow = (x + 1) >> 1;
+ FX_BOOL isAbove = (x & 0x01) == 0;
+ FX_INT32 rowNumber = middle + rowStep * (isAbove ? rowStepsAboveOrBelow : -rowStepsAboveOrBelow);
+ if (rowNumber < 0 || rowNumber >= height) {
+ break;
+ }
+ row = image->GetBlackRow(rowNumber, NULL, e);
+ if (e != BCExceptionNO) {
+ e = BCExceptionNO;
+ if(row != NULL) {
+ delete row;
+ row = NULL;
+ }
+ continue;
+ }
+ for (FX_INT32 attempt = 0; attempt < 2; attempt++) {
+ if (attempt == 1) {
+ row->Reverse();
+ }
+ CFX_ByteString result = DecodeRow(rowNumber, row, hints, e);
+ if (e != BCExceptionNO) {
+ e = BCExceptionNO;
+ continue;
+ }
+ if(row != NULL) {
+ delete row;
+ row = NULL;
+ }
+ return result;
+ }
+ if(row != NULL) {
+ delete row;
+ row = NULL;
+ }
+ }
+ e = BCExceptionNotFound;
+ return "";
+}
+void CBC_OneDReader::RecordPattern(CBC_CommonBitArray *row, FX_INT32 start, CFX_Int32Array *counters, FX_INT32 &e)
+{
+ FX_INT32 numCounters = counters->GetSize();
+ for (FX_INT32 i = 0; i < numCounters; i++) {
+ (*counters)[i] = 0;
+ }
+ FX_INT32 end = row->GetSize();
+ if (start >= end) {
+ e = BCExceptionNotFound;
+ return;
+ }
+ FX_BOOL isWhite = !row->Get(start);
+ FX_INT32 counterPosition = 0;
+ FX_INT32 j = start;
+ while (j < end) {
+ FX_BOOL pixel = row->Get(j);
+ if (pixel ^ isWhite) {
+ (*counters)[counterPosition]++;
+ } else {
+ counterPosition++;
+ if (counterPosition == numCounters) {
+ break;
+ } else {
+ (*counters)[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ j++;
+ }
+ if (!(counterPosition == numCounters || (counterPosition == numCounters - 1 && j == end))) {
+ e = BCExceptionNotFound;
+ return;
+ }
+}
+void CBC_OneDReader::RecordPatternInReverse(CBC_CommonBitArray *row, FX_INT32 start, CFX_Int32Array *counters, FX_INT32 &e)
+{
+ FX_INT32 numTransitionsLeft = counters->GetSize();
+ FX_BOOL last = row->Get(start);
+ while (start > 0 && numTransitionsLeft >= 0) {
+ if (row->Get(--start) != last) {
+ numTransitionsLeft--;
+ last = !last;
+ }
+ }
+ if (numTransitionsLeft >= 0) {
+ e = BCExceptionNotFound;
+ return;
+ }
+ RecordPattern(row, start + 1, counters, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+FX_INT32 CBC_OneDReader::PatternMatchVariance(CFX_Int32Array *counters, const FX_INT32 *pattern, FX_INT32 maxIndividualVariance)
+{
+ FX_INT32 numCounters = counters->GetSize();
+ FX_INT32 total = 0;
+ FX_INT32 patternLength = 0;
+ for (FX_INT32 i = 0; i < numCounters; i++) {
+ total += (*counters)[i];
+ patternLength += pattern[i];
+ }
+ if (total < patternLength) {
+#undef max
+ return FXSYS_IntMax;
+ }
+ FX_INT32 unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;
+ maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT;
+ FX_INT32 totalVariance = 0;
+ for (FX_INT32 x = 0; x < numCounters; x++) {
+ FX_INT32 counter = (*counters)[x] << INTEGER_MATH_SHIFT;
+ FX_INT32 scaledPattern = pattern[x] * unitBarWidth;
+ FX_INT32 variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+#undef max
+ return FXSYS_IntMax;
+ }
+ totalVariance += variance;
+ }
+ return totalVariance / total;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OneDimReader.cpp b/xfa/src/fxbarcode/src/BC_OneDimReader.cpp
new file mode 100644
index 0000000000..3e440d9036
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OneDimReader.cpp
@@ -0,0 +1,219 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_OneDimReader.h"
+const FX_INT32 CBC_OneDimReader::MAX_AVG_VARIANCE = (FX_INT32)(256 * 0.48f);
+const FX_INT32 CBC_OneDimReader::MAX_INDIVIDUAL_VARIANCE = (FX_INT32)(256 * 0.7f);
+const FX_INT32 CBC_OneDimReader::START_END_PATTERN[3] = {1, 1, 1};
+const FX_INT32 CBC_OneDimReader::MIDDLE_PATTERN[5] = {1, 1, 1, 1, 1};
+const FX_INT32 CBC_OneDimReader::L_PATTERNS[10][4] = {
+ {3, 2, 1, 1},
+ {2, 2, 2, 1},
+ {2, 1, 2, 2},
+ {1, 4, 1, 1},
+ {1, 1, 3, 2},
+ {1, 2, 3, 1},
+ {1, 1, 1, 4},
+ {1, 3, 1, 2},
+ {1, 2, 1, 3},
+ {3, 1, 1, 2}
+};
+const FX_INT32 CBC_OneDimReader::L_AND_G_PATTERNS[20][4] = {
+ {3, 2, 1, 1},
+ {2, 2, 2, 1},
+ {2, 1, 2, 2},
+ {1, 4, 1, 1},
+ {1, 1, 3, 2},
+ {1, 2, 3, 1},
+ {1, 1, 1, 4},
+ {1, 3, 1, 2},
+ {1, 2, 1, 3},
+ {3, 1, 1, 2},
+ {1, 1, 2, 3},
+ {1, 2, 2, 2},
+ {2, 2, 1, 2},
+ {1, 1, 4, 1},
+ {2, 3, 1, 1},
+ {1, 3, 2, 1},
+ {4, 1, 1, 1},
+ {2, 1, 3, 1},
+ {3, 1, 2, 1},
+ {2, 1, 1, 3}
+};
+CBC_OneDimReader::CBC_OneDimReader()
+{
+}
+CBC_OneDimReader::~CBC_OneDimReader()
+{
+}
+CFX_Int32Array *CBC_OneDimReader::FindStartGuardPattern(CBC_CommonBitArray *row, FX_INT32 &e)
+{
+ FX_BOOL foundStart = FALSE;
+ CFX_Int32Array *startRange = NULL;
+ CFX_Int32Array startEndPattern;
+ startEndPattern.SetSize(3);
+ startEndPattern[0] = START_END_PATTERN[0];
+ startEndPattern[1] = START_END_PATTERN[1];
+ startEndPattern[2] = START_END_PATTERN[2];
+ FX_INT32 nextStart = 0;
+ while (!foundStart) {
+ if(startRange != NULL) {
+ delete startRange;
+ startRange = NULL;
+ }
+ startRange = FindGuardPattern(row, nextStart, FALSE, &startEndPattern, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 start = (*startRange)[0];
+ nextStart = (*startRange)[1];
+ if (start <= 1) {
+ break;
+ }
+ FX_INT32 quietStart = start - (nextStart - start);
+ if (quietStart >= 0) {
+ FX_BOOL booT = row->IsRange(quietStart, start, FALSE, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ foundStart = booT;
+ }
+ }
+ return startRange;
+}
+CFX_ByteString CBC_OneDimReader::DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_Int32Array* StartPattern = FindStartGuardPattern(row, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CFX_Int32Array > result(StartPattern);
+ CFX_ByteString temp = DecodeRow(rowNumber, row, result.get(), hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return temp;
+}
+CFX_ByteString CBC_OneDimReader::DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, CFX_Int32Array *startGuardRange, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_ByteString result;
+ FX_INT32 endStart = DecodeMiddle(row, startGuardRange, result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ FX_BOOL b = CheckChecksum(result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ if (!b) {
+ e = BCExceptionChecksumException;
+ return "";
+ }
+ return result;
+}
+FX_BOOL CBC_OneDimReader::CheckChecksum(CFX_ByteString &s, FX_INT32 &e)
+{
+ FX_BOOL temp = CheckStandardUPCEANChecksum(s, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ return temp;
+}
+FX_BOOL CBC_OneDimReader::CheckStandardUPCEANChecksum(CFX_ByteString &s, FX_INT32 &e)
+{
+ FX_INT32 length = s.GetLength();
+ if (length == 0) {
+ return FALSE;
+ }
+ FX_INT32 sum = 0;
+ for (FX_INT32 i = length - 2; i >= 0; i -= 2) {
+ FX_INT32 digit = (FX_INT32) s[i] - (FX_INT32) '0';
+ if (digit < 0 || digit > 9) {
+ e = BCExceptionFormatException;
+ return FALSE;
+ }
+ sum += digit;
+ }
+ sum *= 3;
+ for (FX_INT32 j = length - 1; j >= 0; j -= 2) {
+ FX_INT32 digit = (FX_INT32) s[j] - (FX_INT32) '0';
+ if (digit < 0 || digit > 9) {
+ e = BCExceptionFormatException;
+ return FALSE;
+ }
+ sum += digit;
+ }
+ return sum % 10 == 0;
+}
+CFX_Int32Array *CBC_OneDimReader::DecodeEnd(CBC_CommonBitArray* row, FX_INT32 endStart, FX_INT32 &e)
+{
+ CFX_Int32Array startEndPattern;
+ startEndPattern.Add(START_END_PATTERN[0]);
+ startEndPattern.Add(START_END_PATTERN[1]);
+ startEndPattern.Add(START_END_PATTERN[2]);
+ CFX_Int32Array* FindGuard = FindGuardPattern(row, endStart, FALSE, &startEndPattern, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return FindGuard;
+}
+CFX_Int32Array *CBC_OneDimReader::FindGuardPattern(CBC_CommonBitArray *row, FX_INT32 rowOffset, FX_BOOL whiteFirst, CFX_Int32Array *pattern, FX_INT32 &e)
+{
+ FX_INT32 patternLength = pattern->GetSize();
+ CFX_Int32Array counters;
+ counters.SetSize(patternLength);
+ FX_INT32 width = row->GetSize();
+ FX_BOOL isWhite = FALSE;
+ while (rowOffset < width) {
+ isWhite = !row->Get(rowOffset);
+ if (whiteFirst == isWhite) {
+ break;
+ }
+ rowOffset++;
+ }
+ FX_INT32 counterPosition = 0;
+ FX_INT32 patternStart = rowOffset;
+ for (FX_INT32 x = rowOffset; x < width; x++) {
+ FX_BOOL pixel = row->Get(x);
+ if (pixel ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if (PatternMatchVariance(&counters, &(*pattern)[0], MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
+ CFX_Int32Array *result = FX_NEW CFX_Int32Array();
+ result->SetSize(2);
+ (*result)[0] = patternStart;
+ (*result)[1] = x;
+ return result;
+ }
+ patternStart += counters[0] + counters[1];
+ for (FX_INT32 y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return NULL;
+}
+FX_INT32 CBC_OneDimReader::DecodeDigit(CBC_CommonBitArray *row, CFX_Int32Array *counters, FX_INT32 rowOffset, const FX_INT32* patterns, FX_INT32 patternLength, FX_INT32 &e)
+{
+ RecordPattern(row, rowOffset, counters, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ FX_INT32 bestVariance = MAX_AVG_VARIANCE;
+ FX_INT32 bestMatch = -1;
+ FX_INT32 max = patternLength;
+ for (FX_INT32 i = 0; i < max; i++) {
+ FX_INT32 variance = PatternMatchVariance(counters, &patterns[i * 4], MAX_INDIVIDUAL_VARIANCE);
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = i;
+ }
+ }
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ e = BCExceptionNotFound;
+ return 0;
+ }
+ return 0;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OneDimWriter.cpp b/xfa/src/fxbarcode/src/BC_OneDimWriter.cpp
new file mode 100644
index 0000000000..e60eb61aa0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OneDimWriter.cpp
@@ -0,0 +1,399 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_OneDimWriter.h"
+CBC_OneDimWriter::CBC_OneDimWriter()
+{
+ m_locTextLoc = BC_TEXT_LOC_BELOWEMBED;
+ m_bPrintChecksum = TRUE;
+ m_iDataLenth = 0;
+ m_bCalcChecksum = FALSE;
+ m_pFont = NULL;
+ m_fFontSize = 10; ;
+ m_iFontStyle = 0;
+ m_fontColor = 0xff000000;
+ m_iContentLen = 0;
+ m_bLeftPadding = FALSE;
+ m_bRightPadding = FALSE;
+ m_output = NULL;
+}
+CBC_OneDimWriter::~CBC_OneDimWriter()
+{
+ if (m_output != NULL) {
+ delete m_output;
+ m_output = NULL;
+ }
+}
+void CBC_OneDimWriter::SetPrintChecksum(FX_BOOL checksum)
+{
+ m_bPrintChecksum = checksum;
+}
+void CBC_OneDimWriter::SetDataLength(FX_INT32 length)
+{
+ m_iDataLenth = length;
+}
+void CBC_OneDimWriter::SetCalcChecksum(FX_INT32 state)
+{
+ m_bCalcChecksum = state;
+}
+FX_BOOL CBC_OneDimWriter::SetFont(CFX_Font * cFont)
+{
+ if (cFont == NULL) {
+ return FALSE;
+ }
+ m_pFont = cFont;
+ return TRUE;
+}
+void CBC_OneDimWriter::SetFontSize(FX_FLOAT size)
+{
+ m_fFontSize = size;
+}
+void CBC_OneDimWriter::SetFontStyle(FX_INT32 style)
+{
+ m_iFontStyle = style;
+}
+void CBC_OneDimWriter::SetFontColor(FX_ARGB color)
+{
+ m_fontColor = color;
+}
+FX_WCHAR CBC_OneDimWriter::Upper(FX_WCHAR ch)
+{
+ if(ch >= 'a' && ch <= 'z') {
+ ch = ch - ('a' - 'A');
+ }
+ return ch;
+}
+FX_BYTE* CBC_OneDimWriter::Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ FX_BYTE *ret = NULL;
+ outHeight = 1;
+ if (m_Width >= 20) {
+ ret = Encode(contents, outWidth, e);
+ } else {
+ ret = Encode(contents, outWidth, e);
+ }
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OneDimWriter::Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_INT32 CBC_OneDimWriter::AppendPattern(FX_BYTE* target, FX_INT32 pos, const FX_INT32* pattern , FX_INT32 patternLength, FX_INT32 startColor, FX_INT32 &e)
+{
+ if (startColor != 0 && startColor != 1) {
+ e = BCExceptionValueMustBeEither0or1;
+ return 0;
+ }
+ FX_BYTE color = (FX_BYTE) startColor;
+ FX_INT32 numAdded = 0;
+ for (FX_INT32 i = 0; i < patternLength; i++) {
+ for (FX_INT32 j = 0; j < pattern[i]; j++) {
+ target[pos] = color;
+ pos += 1;
+ numAdded += 1;
+ }
+ color ^= 1;
+ }
+ return numAdded;
+}
+void CBC_OneDimWriter::CalcTextInfo(const CFX_ByteString &text, FXTEXT_CHARPOS *charPos, CFX_Font *cFont, FX_FLOAT geWidth, FX_INT32 fontSize, FX_FLOAT &charsLen)
+{
+#ifdef FXFM_ENCODING_NONE
+ IFX_FontEncodingEx* encoding = FX_CreateFontEncodingEx(cFont);
+#else
+ IFX_FontEncoding * encoding = FXGE_CreateUnicodeEncoding(cFont);
+#endif
+ FX_INT32 length = text.GetLength();
+ FX_DWORD *pCharCode = FX_Alloc(FX_DWORD, text.GetLength());
+ FX_FLOAT charWidth = 0;
+ for (FX_INT32 j = 0; j < text.GetLength(); j++) {
+ pCharCode[j] = encoding->CharCodeFromUnicode(text[j]);
+ FX_INT32 glyp_code = encoding->GlyphFromCharCode(pCharCode[j]);
+ FX_INT32 glyp_value = cFont->GetGlyphWidth(glyp_code);
+ FX_FLOAT temp = (FX_FLOAT)((glyp_value) * fontSize / 1000.0);
+ charWidth += temp;
+ }
+ charsLen = charWidth;
+ FX_FLOAT leftPositon = (FX_FLOAT)(geWidth - charsLen) / 2.0f;
+ if (leftPositon < 0 && geWidth == 0) {
+ leftPositon = 0;
+ }
+ FX_FLOAT penX = 0.0;
+ FX_FLOAT penY = (FX_FLOAT)FXSYS_abs(cFont->GetDescent()) * (FX_FLOAT)fontSize / 1000.0f;
+ FX_FLOAT left = leftPositon;
+ FX_FLOAT top = 0.0;
+ charPos[0].m_OriginX = penX + left;
+ charPos[0].m_OriginY = penY + top;
+ charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(pCharCode[0]);
+ charPos[0].m_FontCharWidth = cFont->GetGlyphWidth(charPos[0].m_GlyphIndex);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ charPos[0].m_ExtGID = charPos[0].m_GlyphIndex;
+#endif
+ penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * (FX_FLOAT)fontSize / 1000.0f;
+ for (FX_INT32 i = 1; i < length; i++) {
+ charPos[i].m_OriginX = penX + left;
+ charPos[i].m_OriginY = penY + top;
+ charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(pCharCode[i]);
+ charPos[i].m_FontCharWidth = cFont->GetGlyphWidth(charPos[i].m_GlyphIndex);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ charPos[i].m_ExtGID = charPos[i].m_GlyphIndex;
+#endif
+ penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * (FX_FLOAT)fontSize / 1000.0f;
+ }
+ FX_Free (pCharCode);
+ delete encoding;
+ encoding = NULL;
+}
+void CBC_OneDimWriter::ShowDeviceChars(CFX_RenderDevice *device, const CFX_Matrix* matrix, const CFX_ByteString str, FX_FLOAT geWidth, FXTEXT_CHARPOS* pCharPos, FX_FLOAT locX, FX_FLOAT locY, FX_INT32 barWidth)
+{
+ FX_INT32 iFontSize = (FX_INT32)fabs(m_fFontSize);
+ FX_INT32 iTextHeight = iFontSize + 1;
+ CFX_FloatRect rect((FX_FLOAT)locX, (FX_FLOAT)locY, (FX_FLOAT)(locX + geWidth), (FX_FLOAT)(locY + iTextHeight));
+ if (geWidth != m_Width) {
+ rect.right -= 1;
+ }
+ matrix->TransformRect(rect);
+ FX_RECT re = rect.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ CFX_Matrix affine_matrix(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)locX, (FX_FLOAT)(locY + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix.Concat(*matrix);
+ }
+ FX_BOOL ret = device->DrawNormalText(str.GetLength(),
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+}
+void CBC_OneDimWriter::ShowBitmapChars(CFX_DIBitmap *pOutBitmap, const CFX_ByteString str, FX_FLOAT geWidth, FXTEXT_CHARPOS* pCharPos, FX_FLOAT locX, FX_FLOAT locY, FX_INT32 barWidth)
+{
+ FX_INT32 iFontSize = (FX_INT32)fabs(m_fFontSize);
+ FX_INT32 iTextHeight = iFontSize + 1;
+ CFX_FxgeDevice ge;
+ ge.Create((int)geWidth, iTextHeight , m_colorSpace);
+ FX_RECT geRect(0, 0, (int)geWidth, iTextHeight);
+ ge.FillRect(&geRect, m_backgroundColor);
+ CFX_AffineMatrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize);
+ FX_BOOL ret = ge.DrawNormalText(str.GetLength(),
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ CFX_FxgeDevice geBitmap;
+ geBitmap.Attach(pOutBitmap);
+ geBitmap.SetDIBits(ge.GetBitmap(), (int)locX, (int)locY);
+}
+void CBC_OneDimWriter::ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice *device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e)
+{
+ if (device == NULL && pOutBitmap == NULL) {
+ e = BCExceptionIllegalArgument;
+ return;
+ }
+ if (m_pFont == NULL) {
+ e = BCExceptionNullPointer;
+ return;
+ }
+ CFX_ByteString str = FX_UTF8Encode(contents);
+ FX_INT32 iLen = str.GetLength();
+ FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen);
+ if (!pCharPos) {
+ return;
+ }
+ FXSYS_memset32(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen);
+ FX_FLOAT charsLen = 0;
+ FX_FLOAT geWidth = 0;
+ if ( m_locTextLoc == BC_TEXT_LOC_ABOVEEMBED ||
+ m_locTextLoc == BC_TEXT_LOC_BELOWEMBED ) {
+ geWidth = 0;
+ } else if ( m_locTextLoc == BC_TEXT_LOC_ABOVE ||
+ m_locTextLoc == BC_TEXT_LOC_BELOW ) {
+ geWidth = (FX_FLOAT)barWidth;
+ }
+ FX_INT32 iFontSize = (FX_INT32)fabs(m_fFontSize);
+ FX_INT32 iTextHeight = iFontSize + 1;
+ CalcTextInfo(str, pCharPos, m_pFont, geWidth, iFontSize, charsLen);
+ if (charsLen < 1) {
+ return;
+ }
+ FX_INT32 locX = 0;
+ FX_INT32 locY = 0;
+ switch (m_locTextLoc) {
+ case BC_TEXT_LOC_ABOVEEMBED:
+ locX = (FX_INT32)(barWidth - charsLen) / 2;
+ locY = 0;
+ geWidth = charsLen;
+ break;
+ case BC_TEXT_LOC_ABOVE:
+ locX = 0;
+ locY = 0;
+ geWidth = (FX_FLOAT)barWidth;
+ break;
+ case BC_TEXT_LOC_BELOWEMBED:
+ locX = (FX_INT32)(barWidth - charsLen) / 2;
+ locY = m_Height - iTextHeight;
+ geWidth = charsLen;
+ break;
+ case BC_TEXT_LOC_BELOW:
+ default:
+ locX = 0;
+ locY = m_Height - iTextHeight;
+ geWidth = (FX_FLOAT)barWidth;
+ break;
+ }
+ if (device != NULL) {
+ ShowDeviceChars(device, matrix, str, geWidth, pCharPos, (FX_FLOAT)locX, (FX_FLOAT)locY, barWidth);
+ } else {
+ ShowBitmapChars(pOutBitmap, str, geWidth, pCharPos, (FX_FLOAT)locX, (FX_FLOAT)locY, barWidth);
+ }
+ FX_Free(pCharPos);
+}
+void CBC_OneDimWriter::RenderBitmapResult(CFX_DIBitmap *&pOutBitmap, FX_WSTR contents, FX_INT32 &e)
+{
+ if (m_output == NULL) {
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ pOutBitmap = CreateDIBitmap(m_output->GetWidth(), m_output->GetHeight());
+ pOutBitmap->Clear(m_backgroundColor);
+ if (!pOutBitmap) {
+ e = BCExceptionFailToCreateBitmap;
+ return;
+ }
+ for (FX_INT32 x = 0; x < m_output->GetWidth(); x++) {
+ for (FX_INT32 y = 0; y < m_output->GetHeight(); y++) {
+ if (m_output->Get(x, y)) {
+ pOutBitmap->SetPixel(x, y, m_barColor);
+ }
+ }
+ }
+ FX_INT32 i = 0;
+ for (; i < contents.GetLength(); i++)
+ if (contents.GetAt(i) != ' ') {
+ break;
+ }
+ if (m_locTextLoc != BC_TEXT_LOC_NONE && i < contents.GetLength()) {
+ ShowChars(contents, pOutBitmap, NULL, NULL, m_barWidth, m_multiple, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ CFX_DIBitmap * pStretchBitmap = pOutBitmap->StretchTo(m_Width, m_Height);
+ if (pOutBitmap) {
+ delete pOutBitmap;
+ }
+ pOutBitmap = pStretchBitmap;
+}
+void CBC_OneDimWriter::RenderDeviceResult(CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_WSTR contents, FX_INT32 &e)
+{
+ if (m_output == NULL) {
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ CFX_GraphStateData stateData;
+ CFX_PathData path;
+ path.AppendRect(0, 0, (FX_FLOAT)m_Width, (FX_FLOAT)m_Height);
+ device->DrawPath(&path, matrix, &stateData, m_backgroundColor, m_backgroundColor, FXFILL_ALTERNATE);
+ CFX_Matrix matri(m_outputHScale, 0.0, 0.0, (FX_FLOAT)m_Height, 0.0, 0.0);
+ matri.Concat(*matrix);
+ for (FX_INT32 x = 0; x < m_output->GetWidth(); x++) {
+ for (FX_INT32 y = 0; y < m_output->GetHeight(); y++) {
+ CFX_PathData rect;
+ rect.AppendRect((FX_FLOAT)x, (FX_FLOAT)y, (FX_FLOAT)(x + 1), (FX_FLOAT)(y + 1));
+ CFX_GraphStateData stateData;
+ if (m_output->Get(x, y)) {
+ device->DrawPath(&rect, &matri, &stateData, m_barColor, 0, FXFILL_WINDING);
+ }
+ }
+ }
+ FX_INT32 i = 0;
+ for (; i < contents.GetLength(); i++)
+ if (contents.GetAt(i) != ' ') {
+ break;
+ }
+ if (m_locTextLoc != BC_TEXT_LOC_NONE && i < contents.GetLength()) {
+ ShowChars(contents, NULL, device, matrix, m_barWidth, m_multiple, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_OneDimWriter::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e)
+{
+ if (codeLength < 1) {
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if (m_ModuleHeight < 20.0) {
+ m_ModuleHeight = 20;
+ }
+ FX_INT32 codeOldLength = codeLength;
+ FX_INT32 leftPadding = 0;
+ FX_INT32 rightPadding = 0;
+ if (m_bLeftPadding) {
+ leftPadding = 7;
+ }
+ if (m_bRightPadding) {
+ rightPadding = 7;
+ }
+ codeLength += leftPadding;
+ codeLength += rightPadding;
+ m_outputHScale = 1.0;
+ if (m_Width > 0) {
+ m_outputHScale = (FX_FLOAT)m_Width / (FX_FLOAT)codeLength;
+ }
+ if (!isDevice) {
+ m_outputHScale = FX_MAX(m_outputHScale, m_ModuleWidth);
+ }
+ FX_FLOAT dataLengthScale = 1.0;
+ if (m_iDataLenth > 0 && contents.GetLength() != 0) {
+ dataLengthScale = FX_FLOAT(contents.GetLength()) / FX_FLOAT(m_iDataLenth);
+ }
+ if (m_iDataLenth > 0 && contents.GetLength() == 0) {
+ dataLengthScale = FX_FLOAT(1) / FX_FLOAT(m_iDataLenth);
+ }
+ m_multiple = 1;
+ if (!isDevice) {
+ m_multiple = (FX_INT32)ceil(m_outputHScale * dataLengthScale);
+ }
+ FX_INT32 outputHeight = 1;
+ if (!isDevice) {
+ if (m_Height == 0) {
+ outputHeight = FX_MAX(20, m_ModuleHeight);
+ } else {
+ outputHeight = m_Height;
+ }
+ }
+ FX_INT32 outputWidth = codeLength;
+ if (!isDevice) {
+ outputWidth = (FX_INT32)(codeLength * m_multiple / dataLengthScale);
+ }
+ m_barWidth = m_Width;
+ if (!isDevice) {
+ m_barWidth = codeLength * m_multiple;
+ }
+ m_output = FX_NEW CBC_CommonBitMatrix;
+ m_output->Init(outputWidth, outputHeight);
+ FX_INT32 outputX = leftPadding * m_multiple;
+ for (FX_INT32 inputX = 0; inputX < codeOldLength; inputX++) {
+ if (code[inputX] == 1) {
+ if (outputX >= outputWidth ) {
+ break;
+ }
+ if (outputX + m_multiple > outputWidth && outputWidth - outputX > 0) {
+ m_output->SetRegion(outputX, 0, outputWidth - outputX , outputHeight, e);
+ break;
+ }
+ m_output->SetRegion(outputX, 0, m_multiple, outputHeight, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ outputX += m_multiple;
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedCodaBarReader.cpp b/xfa/src/fxbarcode/src/BC_OnedCodaBarReader.cpp
new file mode 100644
index 0000000000..592f938030
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedCodaBarReader.cpp
@@ -0,0 +1,190 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OnedCode39Reader.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_OnedCodaBarReader.h"
+FX_LPCSTR CBC_OnedCodaBarReader::ALPHABET_STRING = "0123456789-$:/.+ABCDTN";
+const FX_INT32 CBC_OnedCodaBarReader::CHARACTER_ENCODINGS[22] = {
+ 0x003, 0x006, 0x009, 0x060, 0x012, 0x042, 0x021, 0x024, 0x030, 0x048,
+ 0x00c, 0x018, 0x045, 0x051, 0x054, 0x015, 0x01A, 0x029, 0x00B, 0x00E,
+ 0x01A, 0x029
+};
+const FX_INT32 CBC_OnedCodaBarReader::minCharacterLength = 3;
+const FX_CHAR CBC_OnedCodaBarReader::STARTEND_ENCODING[8] = {'E', '*', 'A', 'B', 'C', 'D', 'T', 'N'};
+CBC_OnedCodaBarReader::CBC_OnedCodaBarReader()
+{
+}
+CBC_OnedCodaBarReader::~CBC_OnedCodaBarReader()
+{
+}
+CFX_ByteString CBC_OnedCodaBarReader::DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_Int32Array *int32Ptr = FindAsteriskPattern(row, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CFX_Int32Array> start(int32Ptr);
+ (*start)[1] = 0;
+ FX_INT32 nextStart = (*start)[1];
+ FX_INT32 end = row->GetSize();
+ while (nextStart < end && !row->Get(nextStart)) {
+ nextStart++;
+ }
+ CFX_ByteString result;
+ CFX_Int32Array counters;
+ counters.SetSize(7);
+ FX_CHAR decodedChar;
+ FX_INT32 lastStart;
+ do {
+ RecordPattern(row, nextStart, &counters, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ decodedChar = ToNarrowWidePattern(&counters);
+ if (decodedChar == '!') {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ result += decodedChar;
+ lastStart = nextStart;
+ for (FX_INT32 i = 0; i < counters.GetSize(); i++) {
+ nextStart += counters[i];
+ }
+ while (nextStart < end && !row->Get(nextStart)) {
+ nextStart++;
+ }
+ } while (nextStart < end);
+ FX_INT32 lastPatternSize = 0;
+ for (FX_INT32 j = 0; j < counters.GetSize(); j++) {
+ lastPatternSize += counters[j];
+ }
+ FX_INT32 whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
+ if (nextStart != end && (whiteSpaceAfterEnd / 2 < lastPatternSize)) {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ if (result.GetLength() < 2) {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ FX_CHAR startchar = result[0];
+ if (!ArrayContains(STARTEND_ENCODING, startchar)) {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ FX_INT32 len = result.GetLength();
+ CFX_ByteString temp = result;
+ for (FX_INT32 k = 1; k < result.GetLength(); k++) {
+ if (ArrayContains(STARTEND_ENCODING, result[k])) {
+ if ((k + 1) != result.GetLength()) {
+ result.Delete(1, k);
+ k = 1;
+ }
+ }
+ }
+ if (result.GetLength() < 5) {
+ FX_INT32 index = temp.Find(result.Mid(1, result.GetLength() - 1));
+ if (index == len - (result.GetLength() - 1)) {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ }
+ if (result.GetLength() > minCharacterLength) {
+ result = result.Mid(1, result.GetLength() - 2);
+ } else {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ return result;
+}
+CFX_Int32Array *CBC_OnedCodaBarReader::FindAsteriskPattern(CBC_CommonBitArray *row, FX_INT32 &e)
+{
+ FX_INT32 width = row->GetSize();
+ FX_INT32 rowOffset = 0;
+ while (rowOffset < width) {
+ if (row->Get(rowOffset)) {
+ break;
+ }
+ rowOffset++;
+ }
+ FX_INT32 counterPosition = 0;
+ CFX_Int32Array counters;
+ counters.SetSize(7);
+ FX_INT32 patternStart = rowOffset;
+ FX_BOOL isWhite = FALSE;
+ FX_INT32 patternLength = counters.GetSize();
+ for (FX_INT32 i = rowOffset; i < width; i++) {
+ FX_BOOL pixel = row->Get(i);
+ if (pixel ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if (ArrayContains(STARTEND_ENCODING, ToNarrowWidePattern(&counters))) {
+ FX_BOOL btemp3 = row->IsRange(FX_MAX(0, patternStart - (i - patternStart) / 2), patternStart, FALSE, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if (btemp3) {
+ CFX_Int32Array *result = FX_NEW CFX_Int32Array();
+ result->SetSize(2);
+ (*result)[0] = patternStart;
+ (*result)[1] = i;
+ return result;
+ }
+ }
+ patternStart += counters[0] + counters[1];
+ for (FX_INT32 y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ e = BCExceptionNotFound;
+ return NULL;
+}
+FX_BOOL CBC_OnedCodaBarReader::ArrayContains(const FX_CHAR array[], FX_CHAR key)
+{
+ for(FX_INT32 i = 0; i < 8; i++) {
+ if(array[i] == key) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_CHAR CBC_OnedCodaBarReader::ToNarrowWidePattern(CFX_Int32Array *counter)
+{
+ FX_INT32 numCounters = counter->GetSize();
+ if (numCounters < 1) {
+ return '!';
+ }
+ FX_INT32 averageCounter = 0;
+ FX_INT32 totalCounters = 0;
+ for (FX_INT32 i = 0; i < numCounters; i++) {
+ totalCounters += (*counter)[i];
+ }
+ averageCounter = totalCounters / numCounters;
+ FX_INT32 pattern = 0;
+ FX_INT32 wideCounters = 0;
+ for (FX_INT32 j = 0; j < numCounters; j++) {
+ if ((*counter)[j] > averageCounter) {
+ pattern |= 1 << (numCounters - 1 - j);
+ wideCounters++;
+ }
+ }
+ if ((wideCounters == 2) || (wideCounters == 3)) {
+ for (FX_INT32 k = 0; k < 22; k++) {
+ if (CHARACTER_ENCODINGS[k] == pattern) {
+ return (ALPHABET_STRING)[k];
+ }
+ }
+ }
+ return '!';
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedCodaBarWriter.cpp b/xfa/src/fxbarcode/src/BC_OnedCodaBarWriter.cpp
new file mode 100644
index 0000000000..80df7c840c
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedCodaBarWriter.cpp
@@ -0,0 +1,206 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OnedCodaBarReader.h"
+#include "include/BC_OnedCodaBarWriter.h"
+#include "include/BC_CommonBitMatrix.h"
+const FX_CHAR CBC_OnedCodaBarWriter::START_END_CHARS[] = {'A', 'B', 'C', 'D', 'T', 'N', '*', 'E', 'a', 'b', 'c', 'd', 't', 'n', 'e'};
+const FX_CHAR CBC_OnedCodaBarWriter::CONTENT_CHARS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '$', '/', ':', '+', '.'};
+CBC_OnedCodaBarWriter::CBC_OnedCodaBarWriter()
+{
+ m_chStart = 'A';
+ m_chEnd = 'B';
+ m_iWideNarrRatio = 2;
+}
+CBC_OnedCodaBarWriter::~CBC_OnedCodaBarWriter()
+{
+}
+FX_BOOL CBC_OnedCodaBarWriter::SetStartChar(FX_CHAR start)
+{
+ for (FX_INT32 i = 0; i < sizeof(START_END_CHARS) / sizeof(FX_CHAR); i++) {
+ if (START_END_CHARS[i] == start) {
+ m_chStart = start;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CBC_OnedCodaBarWriter::SetEndChar(FX_CHAR end)
+{
+ for (FX_INT32 i = 0; i < sizeof(START_END_CHARS) / sizeof(FX_CHAR); i++) {
+ if (START_END_CHARS[i] == end) {
+ m_chEnd = end;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CBC_OnedCodaBarWriter::SetDataLength(FX_INT32 length)
+{
+ m_iDataLenth = length + 2;
+}
+FX_BOOL CBC_OnedCodaBarWriter::SetTextLocation(BC_TEXT_LOC location)
+{
+ if ( location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {
+ return FALSE;
+ }
+ m_locTextLoc = location;
+ return TRUE;
+}
+FX_BOOL CBC_OnedCodaBarWriter::SetWideNarrowRatio(FX_INT32 ratio)
+{
+ if(ratio < 2 || ratio > 3) {
+ return FALSE;
+ }
+ m_iWideNarrRatio = ratio;
+ return TRUE;
+}
+FX_BOOL CBC_OnedCodaBarWriter::FindChar(FX_WCHAR ch, FX_BOOL isContent)
+{
+ if(isContent) {
+ for(FX_INT32 i = 0 ; i < sizeof(CONTENT_CHARS) / sizeof(FX_CHAR) ; i++) {
+ if(ch == (FX_WCHAR)CONTENT_CHARS[i]) {
+ return TRUE;
+ }
+ }
+ for(FX_INT32 j = 0 ; j < sizeof(START_END_CHARS) / sizeof(FX_CHAR) ; j++) {
+ if(ch == (FX_WCHAR)START_END_CHARS[j]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ } else {
+ for(FX_INT32 i = 0 ; i < sizeof(CONTENT_CHARS) / sizeof(FX_CHAR) ; i++) {
+ if(ch == (FX_WCHAR)CONTENT_CHARS[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+}
+FX_BOOL CBC_OnedCodaBarWriter::CheckContentValidity(FX_WSTR contents)
+{
+ FX_WCHAR ch;
+ FX_INT32 index = 0;
+ for (index = 0; index < contents.GetLength(); index++) {
+ ch = contents.GetAt(index);
+ if (FindChar(ch, FALSE)) {
+ continue;
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+CFX_WideString CBC_OnedCodaBarWriter::FilterContents(FX_WSTR contents)
+{
+ CFX_WideString filtercontents;
+ FX_WCHAR ch;
+ for (FX_INT32 index = 0; index < contents.GetLength(); index ++) {
+ ch = contents.GetAt(index);
+ if(ch > 175) {
+ index++;
+ continue;
+ }
+ if (FindChar(ch, TRUE)) {
+ filtercontents += ch;
+ } else {
+ continue;
+ }
+ }
+ return filtercontents;
+}
+FX_BYTE *CBC_OnedCodaBarWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0 , e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedCodaBarWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ if(format != BCFORMAT_CODABAR) {
+ e = BCExceptionOnlyEncodeCODEBAR;
+ return NULL;
+ }
+ FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE* CBC_OnedCodaBarWriter::Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e)
+{
+ CBC_OnedCodaBarReader CodaBarR;
+ CFX_ByteString data = m_chStart + contents + m_chEnd;
+ m_iContentLen = data.GetLength();
+ FX_BYTE *result = FX_Alloc(FX_BYTE, m_iWideNarrRatio * 7 * data.GetLength());
+ FX_CHAR ch;
+ FX_INT32 position = 0;
+ for (FX_INT32 index = 0; index < data.GetLength(); index++) {
+ ch = data.GetAt(index);
+ if (((ch >= 'a') && (ch <= 'z'))) {
+ ch = ch - 32;
+ }
+ switch (ch) {
+ case 'T':
+ ch = 'A';
+ break;
+ case 'N':
+ ch = 'B';
+ break;
+ case '*':
+ ch = 'C';
+ break;
+ case 'E':
+ ch = 'D';
+ break;
+ default:
+ break;
+ }
+ FX_INT32 code = 0;
+ FX_INT32 len = (FX_INT32)strlen(CodaBarR.ALPHABET_STRING);
+ for (FX_INT32 i = 0; i < len; i++) {
+ if (ch == CodaBarR.ALPHABET_STRING[i]) {
+ code = CodaBarR.CHARACTER_ENCODINGS[i];
+ break;
+ }
+ }
+ FX_BYTE color = 1;
+ FX_INT32 counter = 0;
+ FX_INT32 bit = 0;
+ while (bit < 7) {
+ result[position] = color;
+ position++;
+ if (((code >> (6 - bit)) & 1) == 0 || counter == m_iWideNarrRatio - 1) {
+ color = !color;
+ bit++;
+ counter = 0;
+ } else {
+ counter++;
+ }
+ }
+ if (index < data.GetLength() - 1) {
+ result[position] = 0;
+ position ++;
+ }
+ }
+ outLength = position;
+ return result;
+}
+CFX_WideString CBC_OnedCodaBarWriter::encodedContents(FX_WSTR contents)
+{
+ CFX_WideString strStart(m_chStart);
+ CFX_WideString strEnd(m_chEnd);
+ return strStart + contents + strEnd;
+}
+void CBC_OnedCodaBarWriter::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e)
+{
+ CBC_OneDimWriter::RenderResult(encodedContents(contents), code, codeLength, isDevice, e);
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedCode128Reader.cpp b/xfa/src/fxbarcode/src/BC_OnedCode128Reader.cpp
new file mode 100644
index 0000000000..173ce7ce4c
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedCode128Reader.cpp
@@ -0,0 +1,414 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_OnedCode128Reader.h"
+const FX_INT32 CBC_OnedCode128Reader::CODE_PATTERNS[107][7] = {
+ {2, 1, 2, 2, 2, 2, 0},
+ {2, 2, 2, 1, 2, 2, 0},
+ {2, 2, 2, 2, 2, 1, 0},
+ {1, 2, 1, 2, 2, 3, 0},
+ {1, 2, 1, 3, 2, 2, 0},
+ {1, 3, 1, 2, 2, 2, 0},
+ {1, 2, 2, 2, 1, 3, 0},
+ {1, 2, 2, 3, 1, 2, 0},
+ {1, 3, 2, 2, 1, 2, 0},
+ {2, 2, 1, 2, 1, 3, 0},
+ {2, 2, 1, 3, 1, 2, 0},
+ {2, 3, 1, 2, 1, 2, 0},
+ {1, 1, 2, 2, 3, 2, 0},
+ {1, 2, 2, 1, 3, 2, 0},
+ {1, 2, 2, 2, 3, 1, 0},
+ {1, 1, 3, 2, 2, 2, 0},
+ {1, 2, 3, 1, 2, 2, 0},
+ {1, 2, 3, 2, 2, 1, 0},
+ {2, 2, 3, 2, 1, 1, 0},
+ {2, 2, 1, 1, 3, 2, 0},
+ {2, 2, 1, 2, 3, 1, 0},
+ {2, 1, 3, 2, 1, 2, 0},
+ {2, 2, 3, 1, 1, 2, 0},
+ {3, 1, 2, 1, 3, 1, 0},
+ {3, 1, 1, 2, 2, 2, 0},
+ {3, 2, 1, 1, 2, 2, 0},
+ {3, 2, 1, 2, 2, 1, 0},
+ {3, 1, 2, 2, 1, 2, 0},
+ {3, 2, 2, 1, 1, 2, 0},
+ {3, 2, 2, 2, 1, 1, 0},
+ {2, 1, 2, 1, 2, 3, 0},
+ {2, 1, 2, 3, 2, 1, 0},
+ {2, 3, 2, 1, 2, 1, 0},
+ {1, 1, 1, 3, 2, 3, 0},
+ {1, 3, 1, 1, 2, 3, 0},
+ {1, 3, 1, 3, 2, 1, 0},
+ {1, 1, 2, 3, 1, 3, 0},
+ {1, 3, 2, 1, 1, 3, 0},
+ {1, 3, 2, 3, 1, 1, 0},
+ {2, 1, 1, 3, 1, 3, 0},
+ {2, 3, 1, 1, 1, 3, 0},
+ {2, 3, 1, 3, 1, 1, 0},
+ {1, 1, 2, 1, 3, 3, 0},
+ {1, 1, 2, 3, 3, 1, 0},
+ {1, 3, 2, 1, 3, 1, 0},
+ {1, 1, 3, 1, 2, 3, 0},
+ {1, 1, 3, 3, 2, 1, 0},
+ {1, 3, 3, 1, 2, 1, 0},
+ {3, 1, 3, 1, 2, 1, 0},
+ {2, 1, 1, 3, 3, 1, 0},
+ {2, 3, 1, 1, 3, 1, 0},
+ {2, 1, 3, 1, 1, 3, 0},
+ {2, 1, 3, 3, 1, 1, 0},
+ {2, 1, 3, 1, 3, 1, 0},
+ {3, 1, 1, 1, 2, 3, 0},
+ {3, 1, 1, 3, 2, 1, 0},
+ {3, 3, 1, 1, 2, 1, 0},
+ {3, 1, 2, 1, 1, 3, 0},
+ {3, 1, 2, 3, 1, 1, 0},
+ {3, 3, 2, 1, 1, 1, 0},
+ {3, 1, 4, 1, 1, 1, 0},
+ {2, 2, 1, 4, 1, 1, 0},
+ {4, 3, 1, 1, 1, 1, 0},
+ {1, 1, 1, 2, 2, 4, 0},
+ {1, 1, 1, 4, 2, 2, 0},
+ {1, 2, 1, 1, 2, 4, 0},
+ {1, 2, 1, 4, 2, 1, 0},
+ {1, 4, 1, 1, 2, 2, 0},
+ {1, 4, 1, 2, 2, 1, 0},
+ {1, 1, 2, 2, 1, 4, 0},
+ {1, 1, 2, 4, 1, 2, 0},
+ {1, 2, 2, 1, 1, 4, 0},
+ {1, 2, 2, 4, 1, 1, 0},
+ {1, 4, 2, 1, 1, 2, 0},
+ {1, 4, 2, 2, 1, 1, 0},
+ {2, 4, 1, 2, 1, 1, 0},
+ {2, 2, 1, 1, 1, 4, 0},
+ {4, 1, 3, 1, 1, 1, 0},
+ {2, 4, 1, 1, 1, 2, 0},
+ {1, 3, 4, 1, 1, 1, 0},
+ {1, 1, 1, 2, 4, 2, 0},
+ {1, 2, 1, 1, 4, 2, 0},
+ {1, 2, 1, 2, 4, 1, 0},
+ {1, 1, 4, 2, 1, 2, 0},
+ {1, 2, 4, 1, 1, 2, 0},
+ {1, 2, 4, 2, 1, 1, 0},
+ {4, 1, 1, 2, 1, 2, 0},
+ {4, 2, 1, 1, 1, 2, 0},
+ {4, 2, 1, 2, 1, 1, 0},
+ {2, 1, 2, 1, 4, 1, 0},
+ {2, 1, 4, 1, 2, 1, 0},
+ {4, 1, 2, 1, 2, 1, 0},
+ {1, 1, 1, 1, 4, 3, 0},
+ {1, 1, 1, 3, 4, 1, 0},
+ {1, 3, 1, 1, 4, 1, 0},
+ {1, 1, 4, 1, 1, 3, 0},
+ {1, 1, 4, 3, 1, 1, 0},
+ {4, 1, 1, 1, 1, 3, 0},
+ {4, 1, 1, 3, 1, 1, 0},
+ {1, 1, 3, 1, 4, 1, 0},
+ {1, 1, 4, 1, 3, 1, 0},
+ {3, 1, 1, 1, 4, 1, 0},
+ {4, 1, 1, 1, 3, 1, 0},
+ {2, 1, 1, 4, 1, 2, 0},
+ {2, 1, 1, 2, 1, 4, 0},
+ {2, 1, 1, 2, 3, 2, 0},
+ {2, 3, 3, 1, 1, 1, 2}
+};
+const FX_INT32 CBC_OnedCode128Reader::MAX_AVG_VARIANCE = (FX_INT32) (256 * 0.25f);
+const FX_INT32 CBC_OnedCode128Reader::MAX_INDIVIDUAL_VARIANCE = (FX_INT32) (256 * 0.7f);
+const FX_INT32 CBC_OnedCode128Reader::CODE_SHIFT = 98;
+const FX_INT32 CBC_OnedCode128Reader::CODE_CODE_C = 99;
+const FX_INT32 CBC_OnedCode128Reader::CODE_CODE_B = 100;
+const FX_INT32 CBC_OnedCode128Reader::CODE_CODE_A = 101;
+const FX_INT32 CBC_OnedCode128Reader::CODE_FNC_1 = 102;
+const FX_INT32 CBC_OnedCode128Reader::CODE_FNC_2 = 97;
+const FX_INT32 CBC_OnedCode128Reader::CODE_FNC_3 = 96;
+const FX_INT32 CBC_OnedCode128Reader::CODE_FNC_4_A = 101;
+const FX_INT32 CBC_OnedCode128Reader::CODE_FNC_4_B = 100;
+const FX_INT32 CBC_OnedCode128Reader::CODE_START_A = 103;
+const FX_INT32 CBC_OnedCode128Reader::CODE_START_B = 104;
+const FX_INT32 CBC_OnedCode128Reader::CODE_START_C = 105;
+const FX_INT32 CBC_OnedCode128Reader::CODE_STOP = 106;
+CBC_OnedCode128Reader::CBC_OnedCode128Reader()
+{
+}
+CBC_OnedCode128Reader::~CBC_OnedCode128Reader()
+{
+}
+CFX_Int32Array *CBC_OnedCode128Reader::FindStartPattern(CBC_CommonBitArray *row, FX_INT32 &e)
+{
+ FX_INT32 width = row->GetSize();
+ FX_INT32 rowOffset = 0;
+ while (rowOffset < width) {
+ if (row->Get(rowOffset)) {
+ break;
+ }
+ rowOffset++;
+ }
+ FX_INT32 counterPosition = 0;
+ CFX_Int32Array counters;
+ counters.SetSize(6);
+ FX_INT32 patternStart = rowOffset;
+ FX_BOOL isWhite = FALSE;
+ FX_INT32 patternLength = counters.GetSize();
+ for (FX_INT32 i = rowOffset; i < width; i++) {
+ FX_BOOL pixel = row->Get(i);
+ if (pixel ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ FX_INT32 bestVariance = MAX_AVG_VARIANCE;
+ FX_INT32 bestMatch = -1;
+ for (FX_INT32 startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) {
+ FX_INT32 variance = PatternMatchVariance(&counters, &CODE_PATTERNS[startCode][0], MAX_INDIVIDUAL_VARIANCE);
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = startCode;
+ }
+ }
+ if (bestMatch >= 0) {
+ FX_BOOL btemp2 = row->IsRange(FX_MAX(0, patternStart - (i - patternStart) / 2), patternStart, FALSE, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if (btemp2) {
+ CFX_Int32Array *result = FX_NEW CFX_Int32Array;
+ result->SetSize(3);
+ (*result)[0] = patternStart;
+ (*result)[1] = i;
+ (*result)[2] = bestMatch;
+ return result;
+ }
+ }
+ patternStart += counters[0] + counters[1];
+ for (FX_INT32 y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ e = BCExceptionNotFound;
+ return NULL;
+}
+FX_INT32 CBC_OnedCode128Reader::DecodeCode(CBC_CommonBitArray *row, CFX_Int32Array *counters, FX_INT32 rowOffset, FX_INT32 &e)
+{
+ RecordPattern(row, rowOffset, counters, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ FX_INT32 bestVariance = MAX_AVG_VARIANCE;
+ FX_INT32 bestMatch = -1;
+ for (FX_INT32 d = 0; d < 107; d++) {
+ FX_INT32 variance = PatternMatchVariance(counters, &CODE_PATTERNS[d][0], MAX_INDIVIDUAL_VARIANCE);
+ if (variance < bestVariance) {
+ bestVariance = variance;
+ bestMatch = d;
+ }
+ }
+ if (bestMatch >= 0) {
+ return bestMatch;
+ } else {
+ e = BCExceptionNotFound;
+ return 0;
+ }
+ return 0;
+}
+CFX_ByteString CBC_OnedCode128Reader::DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_Int32Array *startPatternInfo = FindStartPattern(row, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ FX_INT32 startCode = (*startPatternInfo)[2];
+ FX_INT32 codeSet;
+ switch (startCode) {
+ case 103:
+ codeSet = CODE_CODE_A;
+ break;
+ case 104:
+ codeSet = CODE_CODE_B;
+ break;
+ case 105:
+ codeSet = CODE_CODE_C;
+ break;
+ default:
+ if(startPatternInfo != NULL) {
+ startPatternInfo->RemoveAll();
+ delete startPatternInfo;
+ startPatternInfo = NULL;
+ }
+ e = BCExceptionFormatException;
+ return "";
+ }
+ FX_BOOL done = FALSE;
+ FX_BOOL isNextShifted = FALSE;
+ CFX_ByteString result;
+ FX_INT32 lastStart = (*startPatternInfo)[0];
+ FX_INT32 nextStart = (*startPatternInfo)[1];
+ if(startPatternInfo != NULL) {
+ startPatternInfo->RemoveAll();
+ delete startPatternInfo;
+ startPatternInfo = NULL;
+ }
+ CFX_Int32Array counters;
+ counters.SetSize(6);
+ FX_INT32 lastCode = 0;
+ FX_INT32 code = 0;
+ FX_INT32 checksumTotal = startCode;
+ FX_INT32 multiplier = 0;
+ FX_BOOL lastCharacterWasPrintable = TRUE;
+ while (!done) {
+ FX_BOOL unshift = isNextShifted;
+ isNextShifted = FALSE;
+ lastCode = code;
+ code = DecodeCode(row, &counters, nextStart, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = TRUE;
+ }
+ if (code != CODE_STOP) {
+ multiplier++;
+ checksumTotal += multiplier * code;
+ }
+ lastStart = nextStart;
+ for (FX_INT32 i = 0; i < counters.GetSize(); i++) {
+ nextStart += counters[i];
+ }
+ switch (code) {
+ case 103:
+ case 104:
+ case 105:
+ e = BCExceptionFormatException;
+ return "";
+ }
+ switch (codeSet) {
+ case 101:
+ if (code < 64) {
+ result += (FX_CHAR) (' ' + code);
+ } else if (code < 96) {
+ result += (FX_CHAR) (code - 64);
+ } else {
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = FALSE;
+ }
+ switch (code) {
+ case 102:
+ case 97:
+ case 96:
+ case 101:
+ break;
+ case 98:
+ isNextShifted = TRUE;
+ codeSet = CODE_CODE_B;
+ break;
+ case 100:
+ codeSet = CODE_CODE_B;
+ break;
+ case 99:
+ codeSet = CODE_CODE_C;
+ break;
+ case 106:
+ done = TRUE;
+ break;
+ }
+ }
+ break;
+ case 100:
+ if (code < 96) {
+ result += (FX_CHAR) (' ' + code);
+ } else {
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = FALSE;
+ }
+ switch (code) {
+ case 102:
+ case 97:
+ case 96:
+ case 100:
+ break;
+ case 98:
+ isNextShifted = TRUE;
+ codeSet = CODE_CODE_A;
+ break;
+ case 101:
+ codeSet = CODE_CODE_A;
+ break;
+ case 99:
+ codeSet = CODE_CODE_C;
+ break;
+ case 106:
+ done = TRUE;
+ break;
+ }
+ }
+ break;
+ case 99:
+ if (code < 100) {
+ if (code < 10) {
+ result += '0';
+ }
+ FX_CHAR temp[128];
+#if defined(_FX_WINAPI_PARTITION_APP_)
+ sprintf_s(temp, 128, "%d", code);
+#else
+ sprintf(temp, "%d", code);
+#endif
+ result += temp;
+ } else {
+ if (code != CODE_STOP) {
+ lastCharacterWasPrintable = FALSE;
+ }
+ switch (code) {
+ case 102:
+ break;
+ case 101:
+ codeSet = CODE_CODE_A;
+ break;
+ case 100:
+ codeSet = CODE_CODE_B;
+ break;
+ case 106:
+ done = TRUE;
+ break;
+ }
+ }
+ break;
+ }
+ if (unshift) {
+ codeSet = codeSet == CODE_CODE_A ? CODE_CODE_B : CODE_CODE_A;
+ }
+ }
+ FX_INT32 width = row->GetSize();
+ while (nextStart < width && row->Get(nextStart)) {
+ nextStart++;
+ }
+ FX_BOOL boolT1 = row->IsRange(nextStart, FX_MIN(width, nextStart + (nextStart - lastStart) / 2), FALSE, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ if (!boolT1) {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ checksumTotal -= multiplier * lastCode;
+ if (checksumTotal % 103 != lastCode) {
+ e = BCExceptionChecksumException;
+ return "";
+ }
+ FX_INT32 resultLength = result.GetLength();
+ if (resultLength > 0 && lastCharacterWasPrintable) {
+ if (codeSet == CODE_CODE_C) {
+ result = result.Mid(0, result.GetLength() - 2);
+ } else {
+ result = result.Mid(0, result.GetLength() - 1);
+ }
+ }
+ if (result.GetLength() == 0) {
+ e = BCExceptionFormatException;
+ return "";
+ }
+ return result;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedCode128Writer.cpp b/xfa/src/fxbarcode/src/BC_OnedCode128Writer.cpp
new file mode 100644
index 0000000000..217da22fbf
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedCode128Writer.cpp
@@ -0,0 +1,214 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OnedCode128Reader.h"
+#include "include/BC_OnedCode128Writer.h"
+const FX_INT32 CBC_OnedCode128Writer::CODE_CODE_B = 100;
+const FX_INT32 CBC_OnedCode128Writer::CODE_CODE_C = 99;
+const FX_INT32 CBC_OnedCode128Writer::CODE_START_B = 104;
+const FX_INT32 CBC_OnedCode128Writer::CODE_START_C = 105;
+const FX_INT32 CBC_OnedCode128Writer::CODE_STOP = 106;
+CBC_OnedCode128Writer::CBC_OnedCode128Writer()
+{
+ m_codeFormat = BC_CODE128_B;
+}
+CBC_OnedCode128Writer::CBC_OnedCode128Writer(BC_TYPE type)
+{
+ m_codeFormat = type;
+}
+CBC_OnedCode128Writer::~CBC_OnedCode128Writer()
+{
+}
+BC_TYPE CBC_OnedCode128Writer::GetType()
+{
+ return m_codeFormat;
+}
+FX_BOOL CBC_OnedCode128Writer::CheckContentValidity(FX_WSTR contents)
+{
+ FX_BOOL ret = TRUE;
+ FX_INT32 position = 0;
+ FX_INT32 patternIndex = -1;
+ if (m_codeFormat == BC_CODE128_B || m_codeFormat == BC_CODE128_C) {
+ while (position < contents.GetLength()) {
+ patternIndex = (FX_INT32)contents.GetAt(position);
+ if (patternIndex >= 32 && patternIndex <= 126 && patternIndex != 34) {
+ position++;
+ continue;
+ } else {
+ ret = FALSE;
+ break;
+ }
+ position ++;
+ }
+ } else {
+ ret = FALSE;
+ }
+ return ret;
+}
+CFX_WideString CBC_OnedCode128Writer::FilterContents(FX_WSTR contents)
+{
+ CFX_WideString filterChineseChar;
+ FX_WCHAR ch;
+ for (FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ ch = contents.GetAt(i);
+ if(ch > 175) {
+ i++;
+ continue;
+ }
+ filterChineseChar += ch;
+ }
+ CFX_WideString filtercontents;
+ if (m_codeFormat == BC_CODE128_B) {
+ for (FX_INT32 i = 0; i < filterChineseChar.GetLength(); i++) {
+ ch = filterChineseChar.GetAt(i);
+ if (ch >= 32 && ch <= 126) {
+ filtercontents += ch;
+ } else {
+ continue;
+ }
+ }
+ } else if (m_codeFormat == BC_CODE128_C) {
+ for (FX_INT32 i = 0; i < filterChineseChar.GetLength(); i++) {
+ ch = filterChineseChar.GetAt(i);
+ if (ch >= 32 && ch <= 106) {
+ filtercontents += ch;
+ } else {
+ continue;
+ }
+ }
+ } else {
+ filtercontents = contents;
+ }
+ return filtercontents;
+}
+FX_BOOL CBC_OnedCode128Writer::SetTextLocation(BC_TEXT_LOC location)
+{
+ if ( location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {
+ return FALSE;
+ }
+ m_locTextLoc = location;
+ return TRUE;
+}
+FX_BYTE *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ if(format != BCFORMAT_CODE_128) {
+ e = BCExceptionOnlyEncodeCODE_128;
+ return NULL;
+ }
+ FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BOOL CBC_OnedCode128Writer::IsDigits(const CFX_ByteString &contents, FX_INT32 start, FX_INT32 length)
+{
+ FX_INT32 end = start + length;
+ for (FX_INT32 i = start; i < end; i++) {
+ if (contents[i] < '0' || contents[i] > '9') {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FX_BYTE *CBC_OnedCode128Writer::Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e)
+{
+ FX_INT32 length = contents.GetLength();
+ if(contents.GetLength() < 1 || contents.GetLength() > 80) {
+ e = BCExceptionContentsLengthShouldBetween1and80;
+ return NULL;
+ }
+ CFX_PtrArray patterns;
+ FX_INT32 checkSum = 0;
+ if (m_codeFormat == BC_CODE128_B) {
+ checkSum = Encode128B(contents, patterns);
+ } else if (m_codeFormat == BC_CODE128_C) {
+ checkSum = Encode128C(contents, patterns);
+ } else {
+ e = BCExceptionFormatException;
+ return NULL;
+ }
+ checkSum %= 103;
+ patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[checkSum]);
+ patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_STOP]);
+ m_iContentLen = contents.GetLength() + 3;
+ FX_INT32 codeWidth = 0;
+ for(FX_INT32 k = 0; k < patterns.GetSize(); k++) {
+ FX_INT32 *pattern = (FX_INT32*)patterns[k];
+ for(FX_INT32 j = 0; j < 7; j++) {
+ codeWidth += pattern[j];
+ }
+ }
+ outLength = codeWidth;
+ FX_BYTE *result = FX_Alloc(FX_BYTE, outLength);
+ FX_INT32 pos = 0;
+ for(FX_INT32 j = 0; j < patterns.GetSize(); j++) {
+ FX_INT32* pattern = (FX_INT32*)patterns[j];
+ pos += AppendPattern(result, pos, pattern, 7, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ }
+ return result;
+}
+FX_INT32 CBC_OnedCode128Writer::Encode128B(const CFX_ByteString &contents, CFX_PtrArray &patterns)
+{
+ FX_INT32 checkSum = 0;
+ FX_INT32 checkWeight = 1;
+ FX_INT32 position = 0;
+ patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_B]);
+ checkSum += CODE_START_B * checkWeight;
+ while (position < contents.GetLength()) {
+ FX_INT32 patternIndex = 0;
+ patternIndex = contents[position] - ' ';
+ position += 1;
+ patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);
+ checkSum += patternIndex * checkWeight;
+ if (position != 0) {
+ checkWeight++;
+ }
+ }
+ return checkSum;
+}
+FX_INT32 CBC_OnedCode128Writer::Encode128C(const CFX_ByteString &contents, CFX_PtrArray &patterns)
+{
+ FX_INT32 checkSum = 0;
+ FX_INT32 checkWeight = 1;
+ FX_INT32 position = 0;
+ patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[CODE_START_C]);
+ checkSum += CODE_START_C * checkWeight;
+ while (position < contents.GetLength()) {
+ FX_INT32 patternIndex = 0;
+ FX_CHAR ch = contents.GetAt(position);
+ if (ch < '0' || ch > '9') {
+ patternIndex = (FX_INT32)ch;
+ position++;
+ } else {
+ patternIndex = FXSYS_atoi(contents.Mid(position, 2));
+ if (contents.GetAt(position + 1) < '0' || contents.GetAt(position + 1) > '9') {
+ position += 1;
+ } else {
+ position += 2;
+ }
+ }
+ patterns.Add((FX_INT32*)CBC_OnedCode128Reader::CODE_PATTERNS[patternIndex]);
+ checkSum += patternIndex * checkWeight;
+ if (position != 0) {
+ checkWeight++;
+ }
+ }
+ return checkSum;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedCode39Reader.cpp b/xfa/src/fxbarcode/src/BC_OnedCode39Reader.cpp
new file mode 100644
index 0000000000..7055a0368b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedCode39Reader.cpp
@@ -0,0 +1,277 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_OnedCode39Reader.h"
+FX_LPCSTR CBC_OnedCode39Reader::ALPHABET_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. *$/+%";
+FX_LPCSTR CBC_OnedCode39Reader::CHECKSUM_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%";
+const FX_INT32 CBC_OnedCode39Reader::CHARACTER_ENCODINGS[44] = {
+ 0x034, 0x121, 0x061, 0x160, 0x031, 0x130, 0x070, 0x025, 0x124, 0x064,
+ 0x109, 0x049, 0x148, 0x019, 0x118, 0x058, 0x00D, 0x10C, 0x04C, 0x01C,
+ 0x103, 0x043, 0x142, 0x013, 0x112, 0x052, 0x007, 0x106, 0x046, 0x016,
+ 0x181, 0x0C1, 0x1C0, 0x091, 0x190, 0x0D0, 0x085, 0x184, 0x0C4, 0x094,
+ 0x0A8, 0x0A2, 0x08A, 0x02A
+};
+const FX_INT32 CBC_OnedCode39Reader::ASTERISK_ENCODING = 0x094;
+CBC_OnedCode39Reader::CBC_OnedCode39Reader(): m_extendedMode(FALSE), m_usingCheckDigit(FALSE)
+{
+}
+CBC_OnedCode39Reader::CBC_OnedCode39Reader(FX_BOOL usingCheckDigit)
+{
+ m_usingCheckDigit = usingCheckDigit;
+ m_extendedMode = FALSE;
+}
+CBC_OnedCode39Reader::CBC_OnedCode39Reader(FX_BOOL usingCheckDigit, FX_BOOL extendedMode)
+{
+ m_extendedMode = extendedMode;
+ m_usingCheckDigit = usingCheckDigit;
+}
+CBC_OnedCode39Reader::~CBC_OnedCode39Reader()
+{
+}
+CFX_ByteString CBC_OnedCode39Reader::DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_Int32Array *start = FindAsteriskPattern(row, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ FX_INT32 nextStart = (*start)[1];
+ if(start != NULL) {
+ delete start;
+ start = NULL;
+ }
+ FX_INT32 end = row->GetSize();
+ while (nextStart < end && !row->Get(nextStart)) {
+ nextStart++;
+ }
+ CFX_ByteString result;
+ CFX_Int32Array counters;
+ counters.SetSize(9);
+ FX_CHAR decodedChar;
+ FX_INT32 lastStart;
+ do {
+ RecordPattern(row, nextStart, &counters, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ FX_INT32 pattern = ToNarrowWidePattern(&counters);
+ if (pattern < 0) {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ decodedChar = PatternToChar(pattern, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ result += decodedChar;
+ lastStart = nextStart;
+ for (FX_INT32 i = 0; i < counters.GetSize(); i++) {
+ nextStart += counters[i];
+ }
+ while (nextStart < end && !row->Get(nextStart)) {
+ nextStart++;
+ }
+ } while (decodedChar != '*');
+ result = result.Mid(0, result.GetLength() - 1);
+ FX_INT32 lastPatternSize = 0;
+ for (FX_INT32 j = 0; j < counters.GetSize(); j++) {
+ lastPatternSize += counters[j];
+ }
+ FX_INT32 whiteSpaceAfterEnd = nextStart - lastStart - lastPatternSize;
+ if(m_usingCheckDigit) {
+ FX_INT32 max = result.GetLength() - 1;
+ FX_INT32 total = 0;
+ FX_INT32 len = (FX_INT32)strlen(ALPHABET_STRING);
+ for (FX_INT32 k = 0; k < max; k++) {
+ for (FX_INT32 j = 0; j < len; j++)
+ if (ALPHABET_STRING[j] == result[k]) {
+ total += j;
+ }
+ }
+ if (result[max] != (ALPHABET_STRING)[total % 43]) {
+ e = BCExceptionChecksumException;
+ return "";
+ }
+ result = result.Mid(0, result.GetLength() - 1);
+ }
+ if (result.GetLength() == 0) {
+ e = BCExceptionNotFound;
+ return "";
+ }
+ if(m_extendedMode) {
+ CFX_ByteString bytestr = DecodeExtended(result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return bytestr;
+ } else {
+ return result;
+ }
+}
+CFX_Int32Array *CBC_OnedCode39Reader::FindAsteriskPattern(CBC_CommonBitArray *row, FX_INT32 &e)
+{
+ FX_INT32 width = row->GetSize();
+ FX_INT32 rowOffset = 0;
+ while (rowOffset < width) {
+ if (row->Get(rowOffset)) {
+ break;
+ }
+ rowOffset++;
+ }
+ FX_INT32 counterPosition = 0;
+ CFX_Int32Array counters;
+ counters.SetSize(9);
+ FX_INT32 patternStart = rowOffset;
+ FX_BOOL isWhite = FALSE;
+ FX_INT32 patternLength = counters.GetSize();
+ for (FX_INT32 i = rowOffset; i < width; i++) {
+ FX_BOOL pixel = row->Get(i);
+ if (pixel ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if (ToNarrowWidePattern(&counters) == ASTERISK_ENCODING) {
+ FX_BOOL bT1 = row->IsRange(FX_MAX(0, patternStart - (i - patternStart) / 2), patternStart, FALSE, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if (bT1) {
+ CFX_Int32Array *result = FX_NEW CFX_Int32Array;
+ result->SetSize(2);
+ (*result)[0] = patternStart;
+ (*result)[1] = i;
+ return result;
+ }
+ }
+ patternStart += counters[0] + counters[1];
+ for (FX_INT32 y = 2; y < patternLength; y++) {
+ counters[y - 2] = counters[y];
+ }
+ counters[patternLength - 2] = 0;
+ counters[patternLength - 1] = 0;
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ e = BCExceptionNotFound;
+ return NULL;
+}
+FX_INT32 CBC_OnedCode39Reader::ToNarrowWidePattern(CFX_Int32Array *counters)
+{
+ FX_INT32 numCounters = counters->GetSize();
+ FX_INT32 maxNarrowCounter = 0;
+ FX_INT32 wideCounters;
+ do {
+#undef max
+ FX_INT32 minCounter = FXSYS_IntMax;
+ for (FX_INT32 i = 0; i < numCounters; i++) {
+ FX_INT32 counter = (*counters)[i];
+ if (counter < minCounter && counter > maxNarrowCounter) {
+ minCounter = counter;
+ }
+ }
+ maxNarrowCounter = minCounter;
+ wideCounters = 0;
+ FX_INT32 totalWideCountersWidth = 0;
+ FX_INT32 pattern = 0;
+ for (FX_INT32 j = 0; j < numCounters; j++) {
+ FX_INT32 counter = (*counters)[j];
+ if ((*counters)[j] > maxNarrowCounter) {
+ pattern |= 1 << (numCounters - 1 - j);
+ wideCounters++;
+ totalWideCountersWidth += counter;
+ }
+ }
+ if (wideCounters == 3) {
+ for (FX_INT32 k = 0; k < numCounters && wideCounters > 0; k++) {
+ FX_INT32 counter = (*counters)[k];
+ if ((*counters)[k] > maxNarrowCounter) {
+ wideCounters--;
+ if ((counter << 1) >= totalWideCountersWidth) {
+ return -1;
+ }
+ }
+ }
+ return pattern;
+ }
+ } while (wideCounters > 3);
+ return -1;
+}
+FX_CHAR CBC_OnedCode39Reader::PatternToChar(FX_INT32 pattern, FX_INT32 &e)
+{
+ for (FX_INT32 i = 0; i < 44; i++) {
+ if (CHARACTER_ENCODINGS[i] == pattern) {
+ return (ALPHABET_STRING)[i];
+ }
+ }
+ e = BCExceptionNotFound;
+ return 0;
+}
+CFX_ByteString CBC_OnedCode39Reader::DecodeExtended(CFX_ByteString &encoded, FX_INT32 &e)
+{
+ FX_INT32 length = encoded.GetLength();
+ CFX_ByteString decoded;
+ FX_CHAR c, next;
+ for(FX_INT32 i = 0; i < length; i++) {
+ c = encoded[i];
+ if(c == '+' || c == '$' || c == '%' || c == '/') {
+ next = encoded[i + 1];
+ FX_CHAR decodedChar = '\0';
+ switch (c) {
+ case '+':
+ if (next >= 'A' && next <= 'Z') {
+ decodedChar = (FX_CHAR) (next + 32);
+ } else {
+ e = BCExceptionFormatException;
+ return "";
+ }
+ break;
+ case '$':
+ if (next >= 'A' && next <= 'Z') {
+ decodedChar = (FX_CHAR) (next - 64);
+ } else {
+ e = BCExceptionFormatException;
+ return "";
+ }
+ break;
+ case '%':
+ if (next >= 'A' && next <= 'E') {
+ decodedChar = (FX_CHAR) (next - 38);
+ } else if (next >= 'F' && next <= 'J') {
+ decodedChar = (FX_CHAR) (next - 11);
+ } else if (next >= 'K' && next <= 'O' && next != 'M' && next != 'N') {
+ decodedChar = (FX_CHAR) (next + 16);
+ } else if (next >= 'P' && next <= 'S') {
+ decodedChar = (FX_CHAR) (next + 43);
+ } else if (next == 'U') {
+ decodedChar = (FX_CHAR) 0;
+ } else if (next == 'V') {
+ decodedChar = (FX_CHAR) 64;
+ } else if (next == 'W') {
+ decodedChar = (FX_CHAR) 96;
+ } else if (next == 'T' || next == 'X' || next == 'Y' || next == 'Z') {
+ decodedChar = (FX_CHAR) 127;
+ } else {
+ e = BCExceptionFormatException;
+ return "";
+ }
+ break;
+ case '/':
+ if (next >= 'A' && next <= 'O') {
+ decodedChar = (FX_CHAR) (next - 32);
+ } else if (next == 'Z') {
+ decodedChar = ':';
+ } else {
+ e = BCExceptionFormatException;
+ return "";
+ }
+ break;
+ }
+ decoded += decodedChar;
+ i++;
+ } else {
+ decoded += c;
+ }
+ }
+ return decoded;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedCode39Writer.cpp b/xfa/src/fxbarcode/src/BC_OnedCode39Writer.cpp
new file mode 100644
index 0000000000..b65c6e9de0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedCode39Writer.cpp
@@ -0,0 +1,335 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OnedCode39Reader.h"
+#include "include/BC_OnedCode39Writer.h"
+#include "include/BC_CommonBitMatrix.h"
+CBC_OnedCode39Writer::CBC_OnedCode39Writer()
+{
+ m_extendedMode = FALSE;
+ m_iWideNarrRatio = 3;
+}
+CBC_OnedCode39Writer::CBC_OnedCode39Writer(FX_BOOL extendedMode)
+{
+ m_iWideNarrRatio = 3;
+ m_extendedMode = extendedMode;
+}
+CBC_OnedCode39Writer::~CBC_OnedCode39Writer()
+{
+}
+FX_BOOL CBC_OnedCode39Writer::CheckContentValidity(FX_WSTR contents)
+{
+ if (m_extendedMode) {
+ return CheckExtendedContentValidity(contents);
+ }
+ for(FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ FX_WCHAR ch = contents.GetAt(i);
+ if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z')
+ || ch == (FX_WCHAR)'-' || ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*'
+ || ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || ch == (FX_WCHAR)'%') {
+ continue;
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CBC_OnedCode39Writer::CheckExtendedContentValidity(FX_WSTR contents)
+{
+ for(FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ FX_WCHAR ch = contents.GetAt(i);
+ if (ch > 127) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+CFX_WideString CBC_OnedCode39Writer::FilterContents(FX_WSTR contents)
+{
+ if (m_extendedMode) {
+ return FilterExtendedContents(contents);
+ }
+ CFX_WideString filtercontents;
+ for(FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ FX_WCHAR ch = contents.GetAt(i);
+ if ( ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1) ) {
+ continue;
+ }
+ if(ch > 175) {
+ i++;
+ continue;
+ } else {
+ ch = Upper(ch);
+ }
+ if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z')
+ || ch == (FX_WCHAR)'-' || ch == (FX_WCHAR)'.' || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*'
+ || ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/' || ch == (FX_WCHAR)'+' || ch == (FX_WCHAR)'%') {
+ filtercontents += ch;
+ }
+ }
+ return filtercontents;
+}
+CFX_WideString CBC_OnedCode39Writer::FilterExtendedContents(FX_WSTR contents)
+{
+ CFX_WideString filtercontents;
+ for(FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ FX_WCHAR ch = contents.GetAt(i);
+ if ( ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1) ) {
+ continue;
+ }
+ if(ch > 175) {
+ i++;
+ continue;
+ }
+ if (ch > 127 && ch < 176) {
+ continue;
+ }
+ if (ch == 0) {
+ filtercontents += '%';
+ filtercontents += 'U';
+ } else if(ch >= 1 && ch <= 26) {
+ filtercontents += '$';
+ filtercontents += (ch + 64);
+ } else if (ch >= 27 && ch <= 31) {
+ filtercontents += '%';
+ filtercontents += (ch + 38);
+ } else if (ch >= 33 && ch <= 47 && ch != 45 && ch != 46) {
+ filtercontents += '/';
+ filtercontents += (ch + 32);
+ } else if (ch == 58) {
+ filtercontents += '/';
+ filtercontents += 'Z';
+ } else if (ch >= 59 && ch <= 63) {
+ filtercontents += '%';
+ filtercontents += ch + 11;
+ } else if (ch == 64) {
+ filtercontents += '%';
+ filtercontents += 'V';
+ } else if (ch >= 91 && ch <= 95) {
+ filtercontents += '%';
+ filtercontents += ch - 16;
+ } else if (ch == 96) {
+ filtercontents += '%';
+ filtercontents += 'W';
+ } else if (ch >= 97 && ch <= 122) {
+ filtercontents += '+';
+ filtercontents += ch - 32;
+ } else if (ch >= 123 && ch <= 126) {
+ filtercontents += '%';
+ filtercontents += ch - 43;
+ } else if (ch == 127) {
+ filtercontents += '%';
+ filtercontents += 'T';
+ } else {
+ filtercontents += ch;
+ }
+ }
+ return filtercontents;
+}
+CFX_WideString CBC_OnedCode39Writer::RenderTextContents(FX_WSTR contents)
+{
+ if (m_extendedMode) {
+ return RenderExtendedTextContents(contents);
+ }
+ CFX_WideString renderContents;
+ for(FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ FX_WCHAR ch = contents.GetAt(i);
+ if ( ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1) ) {
+ continue;
+ }
+ if(ch > 175) {
+ i++;
+ continue;
+ }
+ if ((ch >= (FX_WCHAR)'0' && ch <= (FX_WCHAR)'9') || (ch >= (FX_WCHAR)'A' && ch <= (FX_WCHAR)'Z')
+ || (ch >= (FX_WCHAR)'a' && ch <= (FX_WCHAR)'z') || ch == (FX_WCHAR)'-' || ch == (FX_WCHAR)'.'
+ || ch == (FX_WCHAR)' ' || ch == (FX_WCHAR)'*' || ch == (FX_WCHAR)'$' || ch == (FX_WCHAR)'/'
+ || ch == (FX_WCHAR)'+' || ch == (FX_WCHAR)'%') {
+ renderContents += ch;
+ }
+ }
+ return renderContents;
+}
+CFX_WideString CBC_OnedCode39Writer::RenderExtendedTextContents(FX_WSTR contents)
+{
+ CFX_WideString renderContents;
+ for(FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ FX_WCHAR ch = contents.GetAt(i);
+ if ( ch == (FX_WCHAR)'*' && (i == 0 || i == contents.GetLength() - 1) ) {
+ continue;
+ }
+ if(ch > 175) {
+ i++;
+ continue;
+ }
+ if (ch > 127 && ch < 176) {
+ continue;
+ }
+ renderContents += ch;
+ }
+ return renderContents;
+}
+FX_BOOL CBC_OnedCode39Writer::SetTextLocation(BC_TEXT_LOC location)
+{
+ if ( location < BC_TEXT_LOC_NONE || location > BC_TEXT_LOC_BELOWEMBED) {
+ return FALSE;
+ }
+ m_locTextLoc = location;
+ return TRUE;
+}
+FX_BOOL CBC_OnedCode39Writer::SetWideNarrowRatio(FX_INT32 ratio)
+{
+ if ( ratio < 2 || ratio > 3) {
+ return FALSE;
+ }
+ m_iWideNarrRatio = ratio;
+ return TRUE;
+}
+FX_BYTE *CBC_OnedCode39Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0 , e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedCode39Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ if(format != BCFORMAT_CODE_39) {
+ e = BCExceptionOnlyEncodeCODE_39;
+ return NULL;
+ }
+ FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+void CBC_OnedCode39Writer::ToIntArray(FX_INT32 a, FX_INT32 *toReturn)
+{
+ for(FX_INT32 i = 0; i < 9; i++) {
+ toReturn[i] = (a & (1 << i) ) == 0 ? 1 : m_iWideNarrRatio;
+ }
+}
+FX_CHAR CBC_OnedCode39Writer::CalcCheckSum(const CFX_ByteString &contents, FX_INT32 &e)
+{
+ FX_INT32 length = contents.GetLength();
+ if (length > 80) {
+ e = BCExceptionContentsLengthShouldBetween1and80;
+ return '*';
+ }
+ FX_INT32 checksum = 0;
+ FX_INT32 len = (FX_INT32)strlen(CBC_OnedCode39Reader::ALPHABET_STRING);
+ for(FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ FX_INT32 j = 0;
+ for (; j < len; j++) {
+ if (CBC_OnedCode39Reader::ALPHABET_STRING[j] == contents[i]) {
+ if(contents[i] != '*') {
+ checksum += j;
+ break;
+ } else {
+ break;
+ }
+ }
+ }
+ if (j >= len) {
+ e = BCExceptionUnSupportedString;
+ return '*';
+ }
+ }
+ checksum = checksum % 43;
+ return CBC_OnedCode39Reader::CHECKSUM_STRING[checksum];
+}
+FX_BYTE *CBC_OnedCode39Writer::Encode(const CFX_ByteString &contents, FX_INT32 &outlength , FX_INT32 &e)
+{
+ FX_CHAR checksum = CalcCheckSum(contents, e);
+ if (checksum == '*') {
+ return NULL;
+ }
+ FX_INT32 widths[9] = {0};
+ FX_INT32 wideStrideNum = 3;
+ FX_INT32 narrStrideNum = 9 - wideStrideNum;
+ CFX_ByteString encodedContents = contents;
+ if ( m_bCalcChecksum ) {
+ encodedContents += checksum;
+ }
+ m_iContentLen = encodedContents.GetLength();
+ FX_INT32 codeWidth = (wideStrideNum * m_iWideNarrRatio + narrStrideNum) * 2 + 1 + m_iContentLen;
+ FX_INT32 len = (FX_INT32)strlen(CBC_OnedCode39Reader::ALPHABET_STRING);
+ for (FX_INT32 j = 0; j < m_iContentLen; j++) {
+ for (FX_INT32 i = 0; i < len; i++) {
+ if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[j]) {
+ ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths);
+ for(FX_INT32 k = 0; k < 9; k++) {
+ codeWidth += widths[k];
+ }
+ }
+ }
+ }
+ outlength = codeWidth;
+ FX_BYTE *result = FX_Alloc(FX_BYTE, codeWidth);
+ ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths);
+ FX_INT32 pos = AppendPattern(result, 0, widths, 9, 1 , e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ FX_INT32 narrowWhite[] = {1};
+ pos += AppendPattern(result, pos, narrowWhite, 1, 0, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ for(FX_INT32 l = m_iContentLen - 1; l >= 0; l--) {
+ for (FX_INT32 i = 0; i < len; i++) {
+ if (CBC_OnedCode39Reader::ALPHABET_STRING[i] == encodedContents[l]) {
+ ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[i], widths);
+ pos += AppendPattern(result, pos, widths, 9, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ }
+ }
+ pos += AppendPattern(result, pos, narrowWhite, 1, 0, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ }
+ ToIntArray(CBC_OnedCode39Reader::CHARACTER_ENCODINGS[39], widths);
+ pos += AppendPattern(result, pos, widths, 9, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ for (FX_INT32 i = 0; i < codeWidth / 2; i++) {
+ result[i] ^= result[codeWidth - 1 - i];
+ result[codeWidth - 1 - i] ^= result[i];
+ result[i] ^= result[codeWidth - 1 - i];
+ }
+ return result;
+}
+CFX_WideString CBC_OnedCode39Writer::encodedContents(FX_WSTR contents, FX_INT32 &e)
+{
+ CFX_WideString encodedContents = contents;
+ if (m_bCalcChecksum && m_bPrintChecksum) {
+ CFX_WideString checksumContent = FilterContents(contents);
+ CFX_ByteString str = checksumContent.UTF8Encode();
+ FX_CHAR checksum;
+ checksum = CalcCheckSum(str, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FX_WSTRC(L""));
+ str += checksum;
+ encodedContents += checksum;
+ }
+ return encodedContents;
+}
+void CBC_OnedCode39Writer::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e)
+{
+ CFX_WideString encodedCon = encodedContents(contents, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_OneDimWriter::RenderResult(encodedCon, code, codeLength, isDevice, e);
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedEAN13Reader.cpp b/xfa/src/fxbarcode/src/BC_OnedEAN13Reader.cpp
new file mode 100644
index 0000000000..a02e936c5c
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedEAN13Reader.cpp
@@ -0,0 +1,78 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimReader.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_OnedEAN13Reader.h"
+const FX_INT32 CBC_OnedEAN13Reader::FIRST_DIGIT_ENCODINGS[10] = {
+ 0x00, 0x0B, 0x0D, 0xE, 0x13, 0x19, 0x1C, 0x15, 0x16, 0x1A
+};
+CBC_OnedEAN13Reader::CBC_OnedEAN13Reader()
+{
+}
+CBC_OnedEAN13Reader::~CBC_OnedEAN13Reader()
+{
+}
+void CBC_OnedEAN13Reader::DetermineFirstDigit(CFX_ByteString &result, FX_INT32 lgPatternFound, FX_INT32 &e)
+{
+ for (FX_INT32 d = 0; d < 10; d++) {
+ if (lgPatternFound == FIRST_DIGIT_ENCODINGS[d]) {
+ result.Insert(0, (FX_CHAR) ('0' + d));
+ return;
+ }
+ }
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+FX_INT32 CBC_OnedEAN13Reader::DecodeMiddle(CBC_CommonBitArray *row, CFX_Int32Array *startRange, CFX_ByteString &resultString, FX_INT32 &e)
+{
+ CFX_Int32Array counters;
+ counters.Add(0);
+ counters.Add(0);
+ counters.Add(0);
+ counters.Add(0);
+ FX_INT32 end = row->GetSize();
+ FX_INT32 rowOffset = (*startRange)[1];
+ FX_INT32 lgPatternFound = 0;
+ for (FX_INT32 x = 0; x < 6 && rowOffset < end; x++) {
+ FX_INT32 bestMatch = DecodeDigit(row, &counters, rowOffset, &(CBC_OneDimReader::L_AND_G_PATTERNS[0][0]), 20, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ resultString += (FX_CHAR) ('0' + bestMatch % 10);
+ for (FX_INT32 i = 0; i < counters.GetSize(); i++) {
+ rowOffset += counters[i];
+ }
+ if (bestMatch >= 10) {
+ lgPatternFound |= 1 << (5 - x);
+ }
+ }
+ DetermineFirstDigit(resultString, lgPatternFound, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ CFX_Int32Array result;
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[0]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[1]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[2]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[3]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[4]);
+ CFX_Int32Array *middleRange = FindGuardPattern(row, rowOffset, TRUE, &result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ rowOffset = (*middleRange)[1];
+ if(middleRange != NULL) {
+ delete middleRange;
+ middleRange = NULL;
+ }
+ for (FX_INT32 Y = 0; Y < 6 && rowOffset < end; Y++) {
+ FX_INT32 bestMatch = DecodeDigit(row, &counters, rowOffset, &(CBC_OneDimReader::L_PATTERNS[0][0]), 10, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ resultString += (FX_CHAR) ('0' + bestMatch);
+ for (FX_INT32 k = 0; k < counters.GetSize(); k++) {
+ rowOffset += counters[k];
+ }
+ }
+ return rowOffset;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedEAN13Writer.cpp b/xfa/src/fxbarcode/src/BC_OnedEAN13Writer.cpp
new file mode 100644
index 0000000000..e39a2dcad1
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedEAN13Writer.cpp
@@ -0,0 +1,278 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimReader.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OnedEAN13Reader.h"
+#include "include/BC_OnedEAN13Writer.h"
+CBC_OnedEAN13Writer::CBC_OnedEAN13Writer()
+{
+ m_bLeftPadding = TRUE;
+ m_codeWidth = 3 +
+ (7 * 6) +
+ 5 +
+ (7 * 6) +
+ 3;
+}
+CBC_OnedEAN13Writer::~CBC_OnedEAN13Writer()
+{
+}
+FX_BOOL CBC_OnedEAN13Writer::CheckContentValidity(FX_WSTR contents)
+{
+ for (FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') {
+ continue;
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+CFX_WideString CBC_OnedEAN13Writer::FilterContents(FX_WSTR contents)
+{
+ CFX_WideString filtercontents;
+ FX_WCHAR ch;
+ for (FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ ch = contents.GetAt(i);
+ if(ch > 175) {
+ i++;
+ continue;
+ }
+ if (ch >= '0' && ch <= '9') {
+ filtercontents += ch;
+ }
+ }
+ return filtercontents;
+}
+FX_INT32 CBC_OnedEAN13Writer::CalcChecksum(const CFX_ByteString &contents)
+{
+ FX_INT32 odd = 0;
+ FX_INT32 even = 0;
+ FX_INT32 j = 1;
+ for(FX_INT32 i = contents.GetLength() - 1; i >= 0; i--) {
+ if(j % 2) {
+ odd += FXSYS_atoi(contents.Mid(i, 1));
+ } else {
+ even += FXSYS_atoi(contents.Mid(i, 1));
+ }
+ j++;
+ }
+ FX_INT32 checksum = (odd * 3 + even) % 10;
+ checksum = (10 - checksum) % 10;
+ return (checksum);
+}
+FX_BYTE *CBC_OnedEAN13Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedEAN13Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ if(format != BCFORMAT_EAN_13) {
+ e = BCExceptionOnlyEncodeEAN_13;
+ }
+ FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedEAN13Writer::Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e)
+{
+ if (contents.GetLength() != 13) {
+ e = BCExceptionDigitLengthShould13;
+ return NULL;
+ }
+ m_iDataLenth = 13;
+ FX_INT32 firstDigit = FXSYS_atoi(contents.Mid(0, 1));
+ FX_INT32 parities = CBC_OnedEAN13Reader::FIRST_DIGIT_ENCODINGS[firstDigit];
+ outLength = m_codeWidth;
+ FX_BYTE *result = FX_Alloc(FX_BYTE, m_codeWidth);
+ FX_INT32 pos = 0;
+ pos += AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ FX_INT32 i = 0;
+ for ( i = 1; i <= 6; i++) {
+ FX_INT32 digit = FXSYS_atoi(contents.Mid(i, 1));
+ if ((parities >> (6 - i) & 1) == 1) {
+ digit += 10;
+ }
+ pos += AppendPattern(result, pos, CBC_OneDimReader::L_AND_G_PATTERNS[digit], 4, 0, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ }
+ pos += AppendPattern(result, pos, CBC_OneDimReader::MIDDLE_PATTERN, 5, 0, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ for (i = 7; i <= 12; i++) {
+ FX_INT32 digit = FXSYS_atoi(contents.Mid(i, 1));
+ pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ }
+ pos += AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ return result;
+}
+void CBC_OnedEAN13Writer::ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e)
+{
+ if (device == NULL && pOutBitmap == NULL) {
+ e = BCExceptionIllegalArgument;
+ return;
+ }
+ FX_INT32 leftPadding = 7 * multiple;
+ FX_INT32 leftPosition = 3 * multiple + leftPadding;
+ CFX_ByteString str = FX_UTF8Encode(contents);
+ FX_INT32 iLen = str.GetLength();
+ FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen);
+ if (!pCharPos) {
+ return;
+ }
+ FXSYS_memset32(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen);
+ CFX_FxgeDevice geBitmap;
+ if (pOutBitmap != NULL) {
+ geBitmap.Attach(pOutBitmap);
+ }
+ FX_INT32 iFontSize = (FX_INT32)fabs(m_fFontSize);
+ FX_INT32 iTextHeight = iFontSize + 1;
+ CFX_ByteString tempStr = str.Mid(1, 6);
+ FX_INT32 strWidth = multiple * 42;
+ if (pOutBitmap == NULL) {
+ CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ CFX_FloatRect rect((FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height);
+ matr.Concat(*matrix);
+ matr.TransformRect(rect);
+ FX_RECT re = rect.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ CFX_FloatRect rect1((FX_FLOAT)(leftPosition + 47 * multiple), (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)(leftPosition + 47 * multiple + strWidth - 0.5), (FX_FLOAT)m_Height);
+ CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ matr1.Concat(*matrix);
+ matr1.TransformRect(rect1);
+ re = rect1.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ FX_INT32 strWidth1 = multiple * 7;
+ CFX_Matrix matr2(m_outputHScale, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
+ CFX_FloatRect rect2(0.0f, (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)strWidth1 - 0.5f, (FX_FLOAT)m_Height);
+ matr2.Concat(*matrix);
+ matr2.TransformRect(rect2);
+ re = rect2.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ }
+ FX_FLOAT blank = 0.0;
+ FX_FLOAT charsWidth = 0;
+ iLen = tempStr.GetLength();
+ if (pOutBitmap == NULL) {
+ strWidth = (FX_INT32)(strWidth * m_outputHScale);
+ }
+ CalcTextInfo(tempStr, pCharPos + 1, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);
+ CFX_AffineMatrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize);
+ CFX_FxgeDevice ge;
+ if (pOutBitmap != NULL) {
+ ge.Create(strWidth, iTextHeight, FXDIB_Argb);
+ FX_RECT rect(0, 0, strWidth, iTextHeight);
+ ge.FillRect(&rect, m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos + 1,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)leftPosition * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight) + iFontSize);
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ device->DrawNormalText(iLen,
+ pCharPos + 1,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ tempStr = str.Mid(7, 6);
+ iLen = tempStr.GetLength();
+ charsWidth = 0.0f;
+ CalcTextInfo(tempStr, pCharPos + 7, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);
+ if(pOutBitmap != NULL) {
+ FX_RECT rect1(0, 0, strWidth, iTextHeight);
+ ge.FillRect(&rect1, m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos + 7,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 47 * multiple, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)(leftPosition + 47 * multiple) * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ device->DrawNormalText(iLen,
+ pCharPos + 7,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ tempStr = str.Mid(0, 1);
+ iLen = tempStr.GetLength();
+ strWidth = multiple * 7;
+ if (pOutBitmap == NULL) {
+ strWidth = (FX_INT32)(strWidth * m_outputHScale);
+ }
+ CalcTextInfo(tempStr, pCharPos, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);
+ if(pOutBitmap != NULL) {
+ delete ge.GetBitmap();
+ ge.Create(strWidth, iTextHeight, FXDIB_Argb);
+ ge.GetBitmap()->Clear(m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ device->DrawNormalText(iLen,
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ FX_Free(pCharPos);
+}
+void CBC_OnedEAN13Writer::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e)
+{
+ CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e);
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedEAN8Reader.cpp b/xfa/src/fxbarcode/src/BC_OnedEAN8Reader.cpp
new file mode 100644
index 0000000000..833ff6d522
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedEAN8Reader.cpp
@@ -0,0 +1,65 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimReader.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_OnedEAN8Reader.h"
+CBC_OnedEAN8Reader::CBC_OnedEAN8Reader()
+{
+}
+CBC_OnedEAN8Reader::~CBC_OnedEAN8Reader()
+{
+}
+FX_INT32 CBC_OnedEAN8Reader::DecodeMiddle(CBC_CommonBitArray *row, CFX_Int32Array *startRange, CFX_ByteString &resultResult, FX_INT32 &e)
+{
+ CFX_Int32Array counters;
+ counters.Add(0);
+ counters.Add(0);
+ counters.Add(0);
+ counters.Add(0);
+ FX_INT32 end = row->GetSize();
+ FX_INT32 rowOffset = (*startRange)[1];
+ FX_INT32 rowOffsetLeft = rowOffset;
+ for (FX_INT32 x = 0; x < 4 && rowOffset < end; x++) {
+ FX_INT32 bestMatch = DecodeDigit(row, &counters, rowOffset, &(CBC_OneDimReader::L_PATTERNS[0][0]), 10, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ resultResult += (FX_CHAR) ('0' + bestMatch);
+ for (FX_INT32 i = 0; i < counters.GetSize(); i++) {
+ rowOffset += counters[i];
+ }
+ }
+ FX_INT32 RowOffsetLen = (rowOffset - rowOffsetLeft) / 4;
+ CFX_Int32Array result;
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[0]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[1]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[2]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[3]);
+ result.Add(CBC_OneDimReader::MIDDLE_PATTERN[4]);
+ CFX_Int32Array *middleRange = FindGuardPattern(row, rowOffset, TRUE, &result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ FX_INT32 rowOffsetMid = rowOffset;
+ rowOffset = (*middleRange)[1];
+ if((rowOffset - rowOffsetMid) > RowOffsetLen) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ if(middleRange != NULL) {
+ delete middleRange;
+ middleRange = NULL;
+ }
+ for (FX_INT32 y = 0; y < 4 && rowOffset < end; y++) {
+ FX_INT32 bestMatch = DecodeDigit(row, & counters, rowOffset, &(CBC_OneDimReader::L_PATTERNS[0][0]), 10, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ resultResult += (FX_CHAR) ('0' + bestMatch);
+ for (FX_INT32 i = 0; i < counters.GetSize(); i++) {
+ rowOffset += counters[i];
+ }
+ }
+ return rowOffset;
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedEAN8Writer.cpp b/xfa/src/fxbarcode/src/BC_OnedEAN8Writer.cpp
new file mode 100644
index 0000000000..5c7a50b9b1
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedEAN8Writer.cpp
@@ -0,0 +1,245 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OneDimReader.h"
+#include "include/BC_OnedEAN8Writer.h"
+#include "include/BC_CommonBitMatrix.h"
+CBC_OnedEAN8Writer::CBC_OnedEAN8Writer()
+{
+ m_iDataLenth = 8;
+ m_codeWidth = 3 +
+ (7 * 4) +
+ 5 +
+ (7 * 4) +
+ 3;
+}
+CBC_OnedEAN8Writer::~CBC_OnedEAN8Writer()
+{
+}
+void CBC_OnedEAN8Writer::SetDataLength(FX_INT32 length)
+{
+ m_iDataLenth = 8;
+}
+FX_BOOL CBC_OnedEAN8Writer::SetTextLocation(BC_TEXT_LOC location)
+{
+ if ( location == BC_TEXT_LOC_BELOWEMBED) {
+ m_locTextLoc = location;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CBC_OnedEAN8Writer::CheckContentValidity(FX_WSTR contents)
+{
+ for (FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') {
+ continue;
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+CFX_WideString CBC_OnedEAN8Writer::FilterContents(FX_WSTR contents)
+{
+ CFX_WideString filtercontents;
+ FX_WCHAR ch;
+ for (FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ ch = contents.GetAt(i);
+ if(ch > 175) {
+ i++;
+ continue;
+ }
+ if (ch >= '0' && ch <= '9') {
+ filtercontents += ch;
+ }
+ }
+ return filtercontents;
+}
+FX_INT32 CBC_OnedEAN8Writer::CalcChecksum(const CFX_ByteString &contents)
+{
+ FX_INT32 odd = 0;
+ FX_INT32 even = 0;
+ FX_INT32 j = 1;
+ for(FX_INT32 i = contents.GetLength() - 1; i >= 0; i--) {
+ if(j % 2) {
+ odd += FXSYS_atoi(contents.Mid(i, 1));
+ } else {
+ even += FXSYS_atoi(contents.Mid(i, 1));
+ }
+ j++;
+ }
+ FX_INT32 checksum = (odd * 3 + even) % 10;
+ checksum = (10 - checksum) % 10;
+ return (checksum);
+}
+FX_BYTE *CBC_OnedEAN8Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight , FX_INT32 &e)
+{
+ FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedEAN8Writer::Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints , FX_INT32 &e)
+{
+ if (format != BCFORMAT_EAN_8) {
+ e = BCExceptionOnlyEncodeEAN_8;
+ return NULL;
+ }
+ FX_BYTE *ret = CBC_OneDimWriter::Encode(contents, format, outWidth, outHeight, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedEAN8Writer::Encode(const CFX_ByteString &contents, FX_INT32 &outLength , FX_INT32 &e)
+{
+ if (contents.GetLength() != 8) {
+ e = BCExceptionDigitLengthMustBe8;
+ return NULL;
+ }
+ outLength = m_codeWidth;
+ FX_BYTE *result = FX_Alloc(FX_BYTE, m_codeWidth);
+ FX_INT32 pos = 0;
+ pos += AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ FX_INT32 i = 0;
+ for (i = 0; i <= 3; i++) {
+ FX_INT32 digit = FXSYS_atoi(contents.Mid(i, 1));
+ pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 0, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ }
+ pos += AppendPattern(result, pos, CBC_OneDimReader::MIDDLE_PATTERN, 5, 0, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ for (i = 4; i <= 7; i++) {
+ FX_INT32 digit = FXSYS_atoi(contents.Mid(i, 1));
+ pos += AppendPattern(result, pos, CBC_OneDimReader::L_PATTERNS[digit], 4, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ }
+ pos += AppendPattern(result, pos, CBC_OneDimReader::START_END_PATTERN, 3, 1, e);
+ if (e != BCExceptionNO) {
+ FX_Free (result);
+ return NULL;
+ }
+ return result;
+}
+void CBC_OnedEAN8Writer::ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e)
+{
+ if (device == NULL && pOutBitmap == NULL) {
+ e = BCExceptionIllegalArgument;
+ return;
+ }
+ FX_INT32 leftPosition = 3 * multiple;
+ CFX_ByteString str = FX_UTF8Encode(contents);
+ FX_INT32 iLength = str.GetLength();
+ FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLength);
+ if (!pCharPos) {
+ return;
+ }
+ FXSYS_memset32(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLength);
+ CFX_ByteString tempStr = str.Mid(0, 4);
+ FX_INT32 iLen = tempStr.GetLength();
+ FX_INT32 strWidth = 7 * multiple * 4;
+ FX_FLOAT blank = 0.0;
+ CFX_FxgeDevice geBitmap;
+ if (pOutBitmap != NULL) {
+ geBitmap.Attach(pOutBitmap);
+ }
+ FX_FLOAT charsWidth = 0;
+ FX_INT32 iFontSize = (FX_INT32)fabs(m_fFontSize);
+ FX_INT32 iTextHeight = iFontSize + 1;
+ if (pOutBitmap == NULL) {
+ CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ CFX_FloatRect rect((FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height);
+ matr.Concat(*matrix);
+ matr.TransformRect(rect);
+ FX_RECT re = rect.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ CFX_FloatRect rect1((FX_FLOAT)(leftPosition + 33 * multiple), (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)(leftPosition + 33 * multiple + strWidth - 0.5), (FX_FLOAT)m_Height);
+ matr1.Concat(*matrix);
+ matr1.TransformRect(rect1);
+ re = rect1.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ }
+ if (pOutBitmap == NULL) {
+ strWidth = (FX_INT32)(strWidth * m_outputHScale);
+ }
+ CalcTextInfo(tempStr, pCharPos, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);
+ CFX_AffineMatrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize);
+ CFX_FxgeDevice ge;
+ if (pOutBitmap != NULL) {
+ delete ge.GetBitmap();
+ ge.Create(strWidth, iTextHeight, FXDIB_Argb);
+ ge.GetBitmap()->Clear(m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)leftPosition * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ affine_matrix1.Concat(*matrix);
+ FX_BOOL ret = device->DrawNormalText(iLen,
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ tempStr = str.Mid(4, 4);
+ iLen = tempStr.GetLength();
+ charsWidth = 0.0f;
+ CalcTextInfo(tempStr, pCharPos + 4, m_pFont, (FX_FLOAT)strWidth, iFontSize, blank);
+ if (pOutBitmap != NULL) {
+ delete ge.GetBitmap();
+ ge.Create(strWidth, iTextHeight, FXDIB_Argb);
+ ge.GetBitmap()->Clear(m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos + 4,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 33 * multiple, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)(leftPosition + 33 * multiple) * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ FX_BOOL ret = device->DrawNormalText(iLen,
+ pCharPos + 4,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ FX_Free(pCharPos);
+}
+void CBC_OnedEAN8Writer::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e)
+{
+ CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e);
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedUPCAReader.cpp b/xfa/src/fxbarcode/src/BC_OnedUPCAReader.cpp
new file mode 100644
index 0000000000..09c991668f
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedUPCAReader.cpp
@@ -0,0 +1,76 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_OneDReader.h"
+#include "include/BC_OneDimReader.h"
+#include "include/BC_OnedEAN13Reader.h"
+#include "include/BC_OnedUPCAReader.h"
+CBC_OnedUPCAReader::CBC_OnedUPCAReader()
+{
+ m_ean13Reader = NULL;
+}
+void CBC_OnedUPCAReader::Init()
+{
+ m_ean13Reader = FX_NEW CBC_OnedEAN13Reader;
+}
+CBC_OnedUPCAReader::~CBC_OnedUPCAReader()
+{
+ if(m_ean13Reader != NULL) {
+ delete m_ean13Reader;
+ }
+ m_ean13Reader = NULL;
+}
+CFX_ByteString CBC_OnedUPCAReader::DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_ByteString bytestring = m_ean13Reader->DecodeRow(rowNumber, row, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CFX_ByteString temp = MaybeReturnResult(bytestring, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return temp;
+}
+CFX_ByteString CBC_OnedUPCAReader::DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, CFX_Int32Array *startGuardRange, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_ByteString bytestring = m_ean13Reader->DecodeRow(rowNumber, row, startGuardRange, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CFX_ByteString temp = MaybeReturnResult(bytestring, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return temp;
+}
+CFX_ByteString CBC_OnedUPCAReader::Decode(CBC_BinaryBitmap *image, FX_INT32 &e)
+{
+ CFX_ByteString bytestring = m_ean13Reader->Decode(image, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CFX_ByteString temp = MaybeReturnResult(bytestring, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return temp;
+}
+CFX_ByteString CBC_OnedUPCAReader::Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_ByteString bytestring = m_ean13Reader->Decode(image, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CFX_ByteString temp = MaybeReturnResult(bytestring, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return temp;
+}
+FX_INT32 CBC_OnedUPCAReader::DecodeMiddle(CBC_CommonBitArray *row, CFX_Int32Array *startRange, CFX_ByteString &resultString, FX_INT32 &e)
+{
+ FX_INT32 temp = m_ean13Reader->DecodeMiddle(row, startRange, resultString, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ return temp;
+}
+CFX_ByteString CBC_OnedUPCAReader::MaybeReturnResult(CFX_ByteString &result, FX_INT32 &e)
+{
+ if(result[0] == '0') {
+ result.Delete(0);
+ return result;
+ } else {
+ e = BCExceptionFormatException;
+ return "";
+ }
+ return "";
+}
diff --git a/xfa/src/fxbarcode/src/BC_OnedUPCAWriter.cpp b/xfa/src/fxbarcode/src/BC_OnedUPCAWriter.cpp
new file mode 100644
index 0000000000..b28dee7237
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_OnedUPCAWriter.cpp
@@ -0,0 +1,269 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_OneDimWriter.h"
+#include "include/BC_OnedEAN13Writer.h"
+#include "include/BC_OnedUPCAWriter.h"
+CBC_OnedUPCAWriter::CBC_OnedUPCAWriter()
+{
+ m_subWriter = NULL;
+ m_bLeftPadding = TRUE;
+ m_bRightPadding = TRUE;
+}
+void CBC_OnedUPCAWriter::Init()
+{
+ m_subWriter = FX_NEW CBC_OnedEAN13Writer;
+}
+CBC_OnedUPCAWriter::~CBC_OnedUPCAWriter()
+{
+ if(m_subWriter != NULL) {
+ delete m_subWriter;
+ }
+ m_subWriter = NULL;
+}
+FX_BOOL CBC_OnedUPCAWriter::CheckContentValidity(FX_WSTR contents)
+{
+ FX_INT32 i = 0;
+ for (i = 0; i < contents.GetLength(); i++) {
+ if (contents.GetAt(i) >= '0' && contents.GetAt(i) <= '9') {
+ continue;
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+CFX_WideString CBC_OnedUPCAWriter::FilterContents(FX_WSTR contents)
+{
+ CFX_WideString filtercontents;
+ FX_WCHAR ch;
+ for (FX_INT32 i = 0; i < contents.GetLength(); i++) {
+ ch = contents.GetAt(i);
+ if(ch > 175) {
+ i++;
+ continue;
+ }
+ if (ch >= '0' && ch <= '9') {
+ filtercontents += ch;
+ }
+ }
+ return filtercontents;
+}
+FX_INT32 CBC_OnedUPCAWriter::CalcChecksum(const CFX_ByteString &contents)
+{
+ FX_INT32 odd = 0;
+ FX_INT32 even = 0;
+ FX_INT32 j = 1;
+ for(FX_INT32 i = contents.GetLength() - 1; i >= 0; i--) {
+ if(j % 2) {
+ odd += FXSYS_atoi(contents.Mid(i, 1));
+ } else {
+ even += FXSYS_atoi(contents.Mid(i, 1));
+ }
+ j++;
+ }
+ FX_INT32 checksum = (odd * 3 + even) % 10;
+ checksum = (10 - checksum) % 10;
+ return (checksum);
+}
+FX_BYTE *CBC_OnedUPCAWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ FX_BYTE *ret = Encode(contents, format, outWidth, outHeight, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+FX_BYTE *CBC_OnedUPCAWriter::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ if (format != BCFORMAT_UPC_A) {
+ e = BCExceptionOnlyEncodeUPC_A;
+ return NULL;
+ }
+ CFX_ByteString toEAN13String = '0' + contents;
+ m_iDataLenth = 13;
+ FX_BYTE *ret = m_subWriter->Encode(toEAN13String, BCFORMAT_EAN_13, outWidth, outHeight, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return ret;
+}
+void CBC_OnedUPCAWriter::ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e)
+{
+ if (device == NULL && pOutBitmap == NULL) {
+ e = BCExceptionIllegalArgument;
+ return;
+ }
+ FX_INT32 leftPadding = 7 * multiple;
+ FX_INT32 leftPosition = 10 * multiple + leftPadding;
+ CFX_ByteString str = FX_UTF8Encode(contents);
+ FX_INT32 iLen = str.GetLength();
+ FXTEXT_CHARPOS* pCharPos = FX_Alloc(FXTEXT_CHARPOS, iLen);
+ if (!pCharPos) {
+ return;
+ }
+ FXSYS_memset32(pCharPos, 0, sizeof(FXTEXT_CHARPOS) * iLen);
+ CFX_ByteString tempStr = str.Mid(1, 5);
+ FX_FLOAT strWidth = (FX_FLOAT)35 * multiple;
+ FX_FLOAT blank = 0.0;
+ CFX_FxgeDevice geBitmap;
+ if (pOutBitmap != NULL) {
+ geBitmap.Attach(pOutBitmap);
+ }
+ FX_FLOAT charsWidth = 0;
+ iLen = tempStr.GetLength();
+ FX_INT32 iFontSize = (FX_INT32)fabs(m_fFontSize);
+ FX_INT32 iTextHeight = iFontSize + 1;
+ if (pOutBitmap == NULL) {
+ CFX_Matrix matr(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ CFX_FloatRect rect((FX_FLOAT)leftPosition, (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)(leftPosition + strWidth - 0.5), (FX_FLOAT)m_Height);
+ matr.Concat(*matrix);
+ matr.TransformRect(rect);
+ FX_RECT re = rect.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ CFX_Matrix matr1(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ CFX_FloatRect rect1((FX_FLOAT)(leftPosition + 40 * multiple), (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)((leftPosition + 40 * multiple) + strWidth - 0.5), (FX_FLOAT)m_Height);
+ matr1.Concat(*matrix);
+ matr1.TransformRect(rect1);
+ re = rect1.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ FX_FLOAT strWidth1 = (FX_FLOAT)multiple * 7;
+ CFX_Matrix matr2(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ CFX_FloatRect rect2(0.0, (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)strWidth1 - 1, (FX_FLOAT)m_Height);
+ matr2.Concat(*matrix);
+ matr2.TransformRect(rect2);
+ re = rect2.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ CFX_Matrix matr3(m_outputHScale, 0.0, 0.0, 1.0, 0.0, 0.0);
+ CFX_FloatRect rect3((FX_FLOAT)(leftPosition + 85 * multiple), (FX_FLOAT)(m_Height - iTextHeight), (FX_FLOAT)((leftPosition + 85 * multiple) + strWidth1 - 0.5), (FX_FLOAT)m_Height);
+ matr3.Concat(*matrix);
+ matr3.TransformRect(rect3);
+ re = rect3.GetOutterRect();
+ device->FillRect(&re, m_backgroundColor);
+ }
+ if (pOutBitmap == NULL) {
+ strWidth = strWidth * m_outputHScale;
+ }
+ CalcTextInfo(tempStr, pCharPos + 1, m_pFont, strWidth, iFontSize, blank);
+ CFX_AffineMatrix affine_matrix(1.0, 0.0, 0.0, -1.0, 0.0, (FX_FLOAT)iFontSize);
+ CFX_FxgeDevice ge;
+ if(pOutBitmap != NULL) {
+ ge.Create((int)strWidth, iTextHeight, FXDIB_Argb);
+ ge.GetBitmap()->Clear(m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos + 1,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), leftPosition, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)leftPosition * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ device->DrawNormalText(iLen,
+ pCharPos + 1,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ tempStr = str.Mid(6, 5);
+ iLen = tempStr.GetLength();
+ charsWidth = 0.0f;
+ CalcTextInfo(tempStr, pCharPos + 6, m_pFont, strWidth, iFontSize, blank);
+ if(pOutBitmap != NULL) {
+ FX_RECT rect2(0, 0, (int)strWidth, iTextHeight);
+ ge.FillRect(&rect2, m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos + 6,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 40 * multiple, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)(leftPosition + 40 * multiple) * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ device->DrawNormalText(iLen,
+ pCharPos + 6,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ tempStr = str.Mid(0, 1);
+ iLen = tempStr.GetLength();
+ strWidth = (FX_FLOAT)multiple * 7;
+ if (pOutBitmap == NULL) {
+ strWidth = strWidth * m_outputHScale;
+ }
+ CalcTextInfo(tempStr, pCharPos, m_pFont, strWidth, iFontSize, blank);
+ if(pOutBitmap != NULL) {
+ delete ge.GetBitmap();
+ ge.Create((int)strWidth, iTextHeight, FXDIB_Argb);
+ ge.GetBitmap()->Clear(m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), 0, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, 0, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ device->DrawNormalText(iLen,
+ pCharPos,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ tempStr = str.Mid(11, 1);
+ iLen = tempStr.GetLength();
+ CalcTextInfo(tempStr, pCharPos + 11, m_pFont, strWidth, iFontSize, blank);
+ if (pOutBitmap != NULL) {
+ delete ge.GetBitmap();
+ ge.Create((int)strWidth, iTextHeight, FXDIB_Argb);
+ ge.GetBitmap()->Clear(m_backgroundColor);
+ ge.DrawNormalText(iLen,
+ pCharPos + 11,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ geBitmap.SetDIBits(ge.GetBitmap(), leftPosition + 85 * multiple, m_Height - iTextHeight);
+ } else {
+ CFX_AffineMatrix affine_matrix1(1.0, 0.0, 0.0, -1.0, (FX_FLOAT)(leftPosition + 85 * multiple) * m_outputHScale, (FX_FLOAT)(m_Height - iTextHeight + iFontSize));
+ if (matrix != NULL) {
+ affine_matrix1.Concat(*matrix);
+ }
+ device->DrawNormalText(iLen,
+ pCharPos + 11,
+ m_pFont,
+ CFX_GEModule::Get()->GetFontCache(),
+ (FX_FLOAT)iFontSize ,
+ (CFX_AffineMatrix *) &affine_matrix1,
+ m_fontColor, FXTEXT_CLEARTYPE);
+ }
+ FX_Free(pCharPos);
+}
+void CBC_OnedUPCAWriter::RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e)
+{
+ CBC_OneDimWriter::RenderResult(contents, code, codeLength, isDevice, e);
+}
+
diff --git a/xfa/src/fxbarcode/src/BC_PDF417.cpp b/xfa/src/fxbarcode/src/BC_PDF417.cpp
new file mode 100644
index 0000000000..af6cec7b7a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417.cpp
@@ -0,0 +1,676 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Compaction.h"
+#include "include/BC_PDF417BarcodeRow.h"
+#include "include/BC_PDF417BarcodeMatrix.h"
+#include "include/BC_PDF417ErrorCorrection.h"
+#include "include/BC_PDF417HighLevelEncoder.h"
+#include "include/BC_PDF417.h"
+FX_INT32 CBC_PDF417::START_PATTERN = 0x1fea8;
+FX_INT32 CBC_PDF417::STOP_PATTERN = 0x3fa29;
+FX_INT32 CBC_PDF417::CODEWORD_TABLE[][1000] = {
+ {
+ 0x1d5c0, 0x1eaf0, 0x1f57c, 0x1d4e0, 0x1ea78, 0x1f53e,
+ 0x1a8c0, 0x1d470, 0x1a860, 0x15040, 0x1a830, 0x15020,
+ 0x1adc0, 0x1d6f0, 0x1eb7c, 0x1ace0, 0x1d678, 0x1eb3e,
+ 0x158c0, 0x1ac70, 0x15860, 0x15dc0, 0x1aef0, 0x1d77c,
+ 0x15ce0, 0x1ae78, 0x1d73e, 0x15c70, 0x1ae3c, 0x15ef0,
+ 0x1af7c, 0x15e78, 0x1af3e, 0x15f7c, 0x1f5fa, 0x1d2e0,
+ 0x1e978, 0x1f4be, 0x1a4c0, 0x1d270, 0x1e93c, 0x1a460,
+ 0x1d238, 0x14840, 0x1a430, 0x1d21c, 0x14820, 0x1a418,
+ 0x14810, 0x1a6e0, 0x1d378, 0x1e9be, 0x14cc0, 0x1a670,
+ 0x1d33c, 0x14c60, 0x1a638, 0x1d31e, 0x14c30, 0x1a61c,
+ 0x14ee0, 0x1a778, 0x1d3be, 0x14e70, 0x1a73c, 0x14e38,
+ 0x1a71e, 0x14f78, 0x1a7be, 0x14f3c, 0x14f1e, 0x1a2c0,
+ 0x1d170, 0x1e8bc, 0x1a260, 0x1d138, 0x1e89e, 0x14440,
+ 0x1a230, 0x1d11c, 0x14420, 0x1a218, 0x14410, 0x14408,
+ 0x146c0, 0x1a370, 0x1d1bc, 0x14660, 0x1a338, 0x1d19e,
+ 0x14630, 0x1a31c, 0x14618, 0x1460c, 0x14770, 0x1a3bc,
+ 0x14738, 0x1a39e, 0x1471c, 0x147bc, 0x1a160, 0x1d0b8,
+ 0x1e85e, 0x14240, 0x1a130, 0x1d09c, 0x14220, 0x1a118,
+ 0x1d08e, 0x14210, 0x1a10c, 0x14208, 0x1a106, 0x14360,
+ 0x1a1b8, 0x1d0de, 0x14330, 0x1a19c, 0x14318, 0x1a18e,
+ 0x1430c, 0x14306, 0x1a1de, 0x1438e, 0x14140, 0x1a0b0,
+ 0x1d05c, 0x14120, 0x1a098, 0x1d04e, 0x14110, 0x1a08c,
+ 0x14108, 0x1a086, 0x14104, 0x141b0, 0x14198, 0x1418c,
+ 0x140a0, 0x1d02e, 0x1a04c, 0x1a046, 0x14082, 0x1cae0,
+ 0x1e578, 0x1f2be, 0x194c0, 0x1ca70, 0x1e53c, 0x19460,
+ 0x1ca38, 0x1e51e, 0x12840, 0x19430, 0x12820, 0x196e0,
+ 0x1cb78, 0x1e5be, 0x12cc0, 0x19670, 0x1cb3c, 0x12c60,
+ 0x19638, 0x12c30, 0x12c18, 0x12ee0, 0x19778, 0x1cbbe,
+ 0x12e70, 0x1973c, 0x12e38, 0x12e1c, 0x12f78, 0x197be,
+ 0x12f3c, 0x12fbe, 0x1dac0, 0x1ed70, 0x1f6bc, 0x1da60,
+ 0x1ed38, 0x1f69e, 0x1b440, 0x1da30, 0x1ed1c, 0x1b420,
+ 0x1da18, 0x1ed0e, 0x1b410, 0x1da0c, 0x192c0, 0x1c970,
+ 0x1e4bc, 0x1b6c0, 0x19260, 0x1c938, 0x1e49e, 0x1b660,
+ 0x1db38, 0x1ed9e, 0x16c40, 0x12420, 0x19218, 0x1c90e,
+ 0x16c20, 0x1b618, 0x16c10, 0x126c0, 0x19370, 0x1c9bc,
+ 0x16ec0, 0x12660, 0x19338, 0x1c99e, 0x16e60, 0x1b738,
+ 0x1db9e, 0x16e30, 0x12618, 0x16e18, 0x12770, 0x193bc,
+ 0x16f70, 0x12738, 0x1939e, 0x16f38, 0x1b79e, 0x16f1c,
+ 0x127bc, 0x16fbc, 0x1279e, 0x16f9e, 0x1d960, 0x1ecb8,
+ 0x1f65e, 0x1b240, 0x1d930, 0x1ec9c, 0x1b220, 0x1d918,
+ 0x1ec8e, 0x1b210, 0x1d90c, 0x1b208, 0x1b204, 0x19160,
+ 0x1c8b8, 0x1e45e, 0x1b360, 0x19130, 0x1c89c, 0x16640,
+ 0x12220, 0x1d99c, 0x1c88e, 0x16620, 0x12210, 0x1910c,
+ 0x16610, 0x1b30c, 0x19106, 0x12204, 0x12360, 0x191b8,
+ 0x1c8de, 0x16760, 0x12330, 0x1919c, 0x16730, 0x1b39c,
+ 0x1918e, 0x16718, 0x1230c, 0x12306, 0x123b8, 0x191de,
+ 0x167b8, 0x1239c, 0x1679c, 0x1238e, 0x1678e, 0x167de,
+ 0x1b140, 0x1d8b0, 0x1ec5c, 0x1b120, 0x1d898, 0x1ec4e,
+ 0x1b110, 0x1d88c, 0x1b108, 0x1d886, 0x1b104, 0x1b102,
+ 0x12140, 0x190b0, 0x1c85c, 0x16340, 0x12120, 0x19098,
+ 0x1c84e, 0x16320, 0x1b198, 0x1d8ce, 0x16310, 0x12108,
+ 0x19086, 0x16308, 0x1b186, 0x16304, 0x121b0, 0x190dc,
+ 0x163b0, 0x12198, 0x190ce, 0x16398, 0x1b1ce, 0x1638c,
+ 0x12186, 0x16386, 0x163dc, 0x163ce, 0x1b0a0, 0x1d858,
+ 0x1ec2e, 0x1b090, 0x1d84c, 0x1b088, 0x1d846, 0x1b084,
+ 0x1b082, 0x120a0, 0x19058, 0x1c82e, 0x161a0, 0x12090,
+ 0x1904c, 0x16190, 0x1b0cc, 0x19046, 0x16188, 0x12084,
+ 0x16184, 0x12082, 0x120d8, 0x161d8, 0x161cc, 0x161c6,
+ 0x1d82c, 0x1d826, 0x1b042, 0x1902c, 0x12048, 0x160c8,
+ 0x160c4, 0x160c2, 0x18ac0, 0x1c570, 0x1e2bc, 0x18a60,
+ 0x1c538, 0x11440, 0x18a30, 0x1c51c, 0x11420, 0x18a18,
+ 0x11410, 0x11408, 0x116c0, 0x18b70, 0x1c5bc, 0x11660,
+ 0x18b38, 0x1c59e, 0x11630, 0x18b1c, 0x11618, 0x1160c,
+ 0x11770, 0x18bbc, 0x11738, 0x18b9e, 0x1171c, 0x117bc,
+ 0x1179e, 0x1cd60, 0x1e6b8, 0x1f35e, 0x19a40, 0x1cd30,
+ 0x1e69c, 0x19a20, 0x1cd18, 0x1e68e, 0x19a10, 0x1cd0c,
+ 0x19a08, 0x1cd06, 0x18960, 0x1c4b8, 0x1e25e, 0x19b60,
+ 0x18930, 0x1c49c, 0x13640, 0x11220, 0x1cd9c, 0x1c48e,
+ 0x13620, 0x19b18, 0x1890c, 0x13610, 0x11208, 0x13608,
+ 0x11360, 0x189b8, 0x1c4de, 0x13760, 0x11330, 0x1cdde,
+ 0x13730, 0x19b9c, 0x1898e, 0x13718, 0x1130c, 0x1370c,
+ 0x113b8, 0x189de, 0x137b8, 0x1139c, 0x1379c, 0x1138e,
+ 0x113de, 0x137de, 0x1dd40, 0x1eeb0, 0x1f75c, 0x1dd20,
+ 0x1ee98, 0x1f74e, 0x1dd10, 0x1ee8c, 0x1dd08, 0x1ee86,
+ 0x1dd04, 0x19940, 0x1ccb0, 0x1e65c, 0x1bb40, 0x19920,
+ 0x1eedc, 0x1e64e, 0x1bb20, 0x1dd98, 0x1eece, 0x1bb10,
+ 0x19908, 0x1cc86, 0x1bb08, 0x1dd86, 0x19902, 0x11140,
+ 0x188b0, 0x1c45c, 0x13340, 0x11120, 0x18898, 0x1c44e,
+ 0x17740, 0x13320, 0x19998, 0x1ccce, 0x17720, 0x1bb98,
+ 0x1ddce, 0x18886, 0x17710, 0x13308, 0x19986, 0x17708,
+ 0x11102, 0x111b0, 0x188dc, 0x133b0, 0x11198, 0x188ce,
+ 0x177b0, 0x13398, 0x199ce, 0x17798, 0x1bbce, 0x11186,
+ 0x13386, 0x111dc, 0x133dc, 0x111ce, 0x177dc, 0x133ce,
+ 0x1dca0, 0x1ee58, 0x1f72e, 0x1dc90, 0x1ee4c, 0x1dc88,
+ 0x1ee46, 0x1dc84, 0x1dc82, 0x198a0, 0x1cc58, 0x1e62e,
+ 0x1b9a0, 0x19890, 0x1ee6e, 0x1b990, 0x1dccc, 0x1cc46,
+ 0x1b988, 0x19884, 0x1b984, 0x19882, 0x1b982, 0x110a0,
+ 0x18858, 0x1c42e, 0x131a0, 0x11090, 0x1884c, 0x173a0,
+ 0x13190, 0x198cc, 0x18846, 0x17390, 0x1b9cc, 0x11084,
+ 0x17388, 0x13184, 0x11082, 0x13182, 0x110d8, 0x1886e,
+ 0x131d8, 0x110cc, 0x173d8, 0x131cc, 0x110c6, 0x173cc,
+ 0x131c6, 0x110ee, 0x173ee, 0x1dc50, 0x1ee2c, 0x1dc48,
+ 0x1ee26, 0x1dc44, 0x1dc42, 0x19850, 0x1cc2c, 0x1b8d0,
+ 0x19848, 0x1cc26, 0x1b8c8, 0x1dc66, 0x1b8c4, 0x19842,
+ 0x1b8c2, 0x11050, 0x1882c, 0x130d0, 0x11048, 0x18826,
+ 0x171d0, 0x130c8, 0x19866, 0x171c8, 0x1b8e6, 0x11042,
+ 0x171c4, 0x130c2, 0x171c2, 0x130ec, 0x171ec, 0x171e6,
+ 0x1ee16, 0x1dc22, 0x1cc16, 0x19824, 0x19822, 0x11028,
+ 0x13068, 0x170e8, 0x11022, 0x13062, 0x18560, 0x10a40,
+ 0x18530, 0x10a20, 0x18518, 0x1c28e, 0x10a10, 0x1850c,
+ 0x10a08, 0x18506, 0x10b60, 0x185b8, 0x1c2de, 0x10b30,
+ 0x1859c, 0x10b18, 0x1858e, 0x10b0c, 0x10b06, 0x10bb8,
+ 0x185de, 0x10b9c, 0x10b8e, 0x10bde, 0x18d40, 0x1c6b0,
+ 0x1e35c, 0x18d20, 0x1c698, 0x18d10, 0x1c68c, 0x18d08,
+ 0x1c686, 0x18d04, 0x10940, 0x184b0, 0x1c25c, 0x11b40,
+ 0x10920, 0x1c6dc, 0x1c24e, 0x11b20, 0x18d98, 0x1c6ce,
+ 0x11b10, 0x10908, 0x18486, 0x11b08, 0x18d86, 0x10902,
+ 0x109b0, 0x184dc, 0x11bb0, 0x10998, 0x184ce, 0x11b98,
+ 0x18dce, 0x11b8c, 0x10986, 0x109dc, 0x11bdc, 0x109ce,
+ 0x11bce, 0x1cea0, 0x1e758, 0x1f3ae, 0x1ce90, 0x1e74c,
+ 0x1ce88, 0x1e746, 0x1ce84, 0x1ce82, 0x18ca0, 0x1c658,
+ 0x19da0, 0x18c90, 0x1c64c, 0x19d90, 0x1cecc, 0x1c646,
+ 0x19d88, 0x18c84, 0x19d84, 0x18c82, 0x19d82, 0x108a0,
+ 0x18458, 0x119a0, 0x10890, 0x1c66e, 0x13ba0, 0x11990,
+ 0x18ccc, 0x18446, 0x13b90, 0x19dcc, 0x10884, 0x13b88,
+ 0x11984, 0x10882, 0x11982, 0x108d8, 0x1846e, 0x119d8,
+ 0x108cc, 0x13bd8, 0x119cc, 0x108c6, 0x13bcc, 0x119c6,
+ 0x108ee, 0x119ee, 0x13bee, 0x1ef50, 0x1f7ac, 0x1ef48,
+ 0x1f7a6, 0x1ef44, 0x1ef42, 0x1ce50, 0x1e72c, 0x1ded0,
+ 0x1ef6c, 0x1e726, 0x1dec8, 0x1ef66, 0x1dec4, 0x1ce42,
+ 0x1dec2, 0x18c50, 0x1c62c, 0x19cd0, 0x18c48, 0x1c626,
+ 0x1bdd0, 0x19cc8, 0x1ce66, 0x1bdc8, 0x1dee6, 0x18c42,
+ 0x1bdc4, 0x19cc2, 0x1bdc2, 0x10850, 0x1842c, 0x118d0,
+ 0x10848, 0x18426, 0x139d0, 0x118c8, 0x18c66, 0x17bd0,
+ 0x139c8, 0x19ce6, 0x10842, 0x17bc8, 0x1bde6, 0x118c2,
+ 0x17bc4, 0x1086c, 0x118ec, 0x10866, 0x139ec, 0x118e6,
+ 0x17bec, 0x139e6, 0x17be6, 0x1ef28, 0x1f796, 0x1ef24,
+ 0x1ef22, 0x1ce28, 0x1e716, 0x1de68, 0x1ef36, 0x1de64,
+ 0x1ce22, 0x1de62, 0x18c28, 0x1c616, 0x19c68, 0x18c24,
+ 0x1bce8, 0x19c64, 0x18c22, 0x1bce4, 0x19c62, 0x1bce2,
+ 0x10828, 0x18416, 0x11868, 0x18c36, 0x138e8, 0x11864,
+ 0x10822, 0x179e8, 0x138e4, 0x11862, 0x179e4, 0x138e2,
+ 0x179e2, 0x11876, 0x179f6, 0x1ef12, 0x1de34, 0x1de32,
+ 0x19c34, 0x1bc74, 0x1bc72, 0x11834, 0x13874, 0x178f4,
+ 0x178f2, 0x10540, 0x10520, 0x18298, 0x10510, 0x10508,
+ 0x10504, 0x105b0, 0x10598, 0x1058c, 0x10586, 0x105dc,
+ 0x105ce, 0x186a0, 0x18690, 0x1c34c, 0x18688, 0x1c346,
+ 0x18684, 0x18682, 0x104a0, 0x18258, 0x10da0, 0x186d8,
+ 0x1824c, 0x10d90, 0x186cc, 0x10d88, 0x186c6, 0x10d84,
+ 0x10482, 0x10d82, 0x104d8, 0x1826e, 0x10dd8, 0x186ee,
+ 0x10dcc, 0x104c6, 0x10dc6, 0x104ee, 0x10dee, 0x1c750,
+ 0x1c748, 0x1c744, 0x1c742, 0x18650, 0x18ed0, 0x1c76c,
+ 0x1c326, 0x18ec8, 0x1c766, 0x18ec4, 0x18642, 0x18ec2,
+ 0x10450, 0x10cd0, 0x10448, 0x18226, 0x11dd0, 0x10cc8,
+ 0x10444, 0x11dc8, 0x10cc4, 0x10442, 0x11dc4, 0x10cc2,
+ 0x1046c, 0x10cec, 0x10466, 0x11dec, 0x10ce6, 0x11de6,
+ 0x1e7a8, 0x1e7a4, 0x1e7a2, 0x1c728, 0x1cf68, 0x1e7b6,
+ 0x1cf64, 0x1c722, 0x1cf62, 0x18628, 0x1c316, 0x18e68,
+ 0x1c736, 0x19ee8, 0x18e64, 0x18622, 0x19ee4, 0x18e62,
+ 0x19ee2, 0x10428, 0x18216, 0x10c68, 0x18636, 0x11ce8,
+ 0x10c64, 0x10422, 0x13de8, 0x11ce4, 0x10c62, 0x13de4,
+ 0x11ce2, 0x10436, 0x10c76, 0x11cf6, 0x13df6, 0x1f7d4,
+ 0x1f7d2, 0x1e794, 0x1efb4, 0x1e792, 0x1efb2, 0x1c714,
+ 0x1cf34, 0x1c712, 0x1df74, 0x1cf32, 0x1df72, 0x18614,
+ 0x18e34, 0x18612, 0x19e74, 0x18e32, 0x1bef4
+ },
+ {
+ 0x1f560, 0x1fab8, 0x1ea40, 0x1f530, 0x1fa9c, 0x1ea20,
+ 0x1f518, 0x1fa8e, 0x1ea10, 0x1f50c, 0x1ea08, 0x1f506,
+ 0x1ea04, 0x1eb60, 0x1f5b8, 0x1fade, 0x1d640, 0x1eb30,
+ 0x1f59c, 0x1d620, 0x1eb18, 0x1f58e, 0x1d610, 0x1eb0c,
+ 0x1d608, 0x1eb06, 0x1d604, 0x1d760, 0x1ebb8, 0x1f5de,
+ 0x1ae40, 0x1d730, 0x1eb9c, 0x1ae20, 0x1d718, 0x1eb8e,
+ 0x1ae10, 0x1d70c, 0x1ae08, 0x1d706, 0x1ae04, 0x1af60,
+ 0x1d7b8, 0x1ebde, 0x15e40, 0x1af30, 0x1d79c, 0x15e20,
+ 0x1af18, 0x1d78e, 0x15e10, 0x1af0c, 0x15e08, 0x1af06,
+ 0x15f60, 0x1afb8, 0x1d7de, 0x15f30, 0x1af9c, 0x15f18,
+ 0x1af8e, 0x15f0c, 0x15fb8, 0x1afde, 0x15f9c, 0x15f8e,
+ 0x1e940, 0x1f4b0, 0x1fa5c, 0x1e920, 0x1f498, 0x1fa4e,
+ 0x1e910, 0x1f48c, 0x1e908, 0x1f486, 0x1e904, 0x1e902,
+ 0x1d340, 0x1e9b0, 0x1f4dc, 0x1d320, 0x1e998, 0x1f4ce,
+ 0x1d310, 0x1e98c, 0x1d308, 0x1e986, 0x1d304, 0x1d302,
+ 0x1a740, 0x1d3b0, 0x1e9dc, 0x1a720, 0x1d398, 0x1e9ce,
+ 0x1a710, 0x1d38c, 0x1a708, 0x1d386, 0x1a704, 0x1a702,
+ 0x14f40, 0x1a7b0, 0x1d3dc, 0x14f20, 0x1a798, 0x1d3ce,
+ 0x14f10, 0x1a78c, 0x14f08, 0x1a786, 0x14f04, 0x14fb0,
+ 0x1a7dc, 0x14f98, 0x1a7ce, 0x14f8c, 0x14f86, 0x14fdc,
+ 0x14fce, 0x1e8a0, 0x1f458, 0x1fa2e, 0x1e890, 0x1f44c,
+ 0x1e888, 0x1f446, 0x1e884, 0x1e882, 0x1d1a0, 0x1e8d8,
+ 0x1f46e, 0x1d190, 0x1e8cc, 0x1d188, 0x1e8c6, 0x1d184,
+ 0x1d182, 0x1a3a0, 0x1d1d8, 0x1e8ee, 0x1a390, 0x1d1cc,
+ 0x1a388, 0x1d1c6, 0x1a384, 0x1a382, 0x147a0, 0x1a3d8,
+ 0x1d1ee, 0x14790, 0x1a3cc, 0x14788, 0x1a3c6, 0x14784,
+ 0x14782, 0x147d8, 0x1a3ee, 0x147cc, 0x147c6, 0x147ee,
+ 0x1e850, 0x1f42c, 0x1e848, 0x1f426, 0x1e844, 0x1e842,
+ 0x1d0d0, 0x1e86c, 0x1d0c8, 0x1e866, 0x1d0c4, 0x1d0c2,
+ 0x1a1d0, 0x1d0ec, 0x1a1c8, 0x1d0e6, 0x1a1c4, 0x1a1c2,
+ 0x143d0, 0x1a1ec, 0x143c8, 0x1a1e6, 0x143c4, 0x143c2,
+ 0x143ec, 0x143e6, 0x1e828, 0x1f416, 0x1e824, 0x1e822,
+ 0x1d068, 0x1e836, 0x1d064, 0x1d062, 0x1a0e8, 0x1d076,
+ 0x1a0e4, 0x1a0e2, 0x141e8, 0x1a0f6, 0x141e4, 0x141e2,
+ 0x1e814, 0x1e812, 0x1d034, 0x1d032, 0x1a074, 0x1a072,
+ 0x1e540, 0x1f2b0, 0x1f95c, 0x1e520, 0x1f298, 0x1f94e,
+ 0x1e510, 0x1f28c, 0x1e508, 0x1f286, 0x1e504, 0x1e502,
+ 0x1cb40, 0x1e5b0, 0x1f2dc, 0x1cb20, 0x1e598, 0x1f2ce,
+ 0x1cb10, 0x1e58c, 0x1cb08, 0x1e586, 0x1cb04, 0x1cb02,
+ 0x19740, 0x1cbb0, 0x1e5dc, 0x19720, 0x1cb98, 0x1e5ce,
+ 0x19710, 0x1cb8c, 0x19708, 0x1cb86, 0x19704, 0x19702,
+ 0x12f40, 0x197b0, 0x1cbdc, 0x12f20, 0x19798, 0x1cbce,
+ 0x12f10, 0x1978c, 0x12f08, 0x19786, 0x12f04, 0x12fb0,
+ 0x197dc, 0x12f98, 0x197ce, 0x12f8c, 0x12f86, 0x12fdc,
+ 0x12fce, 0x1f6a0, 0x1fb58, 0x16bf0, 0x1f690, 0x1fb4c,
+ 0x169f8, 0x1f688, 0x1fb46, 0x168fc, 0x1f684, 0x1f682,
+ 0x1e4a0, 0x1f258, 0x1f92e, 0x1eda0, 0x1e490, 0x1fb6e,
+ 0x1ed90, 0x1f6cc, 0x1f246, 0x1ed88, 0x1e484, 0x1ed84,
+ 0x1e482, 0x1ed82, 0x1c9a0, 0x1e4d8, 0x1f26e, 0x1dba0,
+ 0x1c990, 0x1e4cc, 0x1db90, 0x1edcc, 0x1e4c6, 0x1db88,
+ 0x1c984, 0x1db84, 0x1c982, 0x1db82, 0x193a0, 0x1c9d8,
+ 0x1e4ee, 0x1b7a0, 0x19390, 0x1c9cc, 0x1b790, 0x1dbcc,
+ 0x1c9c6, 0x1b788, 0x19384, 0x1b784, 0x19382, 0x1b782,
+ 0x127a0, 0x193d8, 0x1c9ee, 0x16fa0, 0x12790, 0x193cc,
+ 0x16f90, 0x1b7cc, 0x193c6, 0x16f88, 0x12784, 0x16f84,
+ 0x12782, 0x127d8, 0x193ee, 0x16fd8, 0x127cc, 0x16fcc,
+ 0x127c6, 0x16fc6, 0x127ee, 0x1f650, 0x1fb2c, 0x165f8,
+ 0x1f648, 0x1fb26, 0x164fc, 0x1f644, 0x1647e, 0x1f642,
+ 0x1e450, 0x1f22c, 0x1ecd0, 0x1e448, 0x1f226, 0x1ecc8,
+ 0x1f666, 0x1ecc4, 0x1e442, 0x1ecc2, 0x1c8d0, 0x1e46c,
+ 0x1d9d0, 0x1c8c8, 0x1e466, 0x1d9c8, 0x1ece6, 0x1d9c4,
+ 0x1c8c2, 0x1d9c2, 0x191d0, 0x1c8ec, 0x1b3d0, 0x191c8,
+ 0x1c8e6, 0x1b3c8, 0x1d9e6, 0x1b3c4, 0x191c2, 0x1b3c2,
+ 0x123d0, 0x191ec, 0x167d0, 0x123c8, 0x191e6, 0x167c8,
+ 0x1b3e6, 0x167c4, 0x123c2, 0x167c2, 0x123ec, 0x167ec,
+ 0x123e6, 0x167e6, 0x1f628, 0x1fb16, 0x162fc, 0x1f624,
+ 0x1627e, 0x1f622, 0x1e428, 0x1f216, 0x1ec68, 0x1f636,
+ 0x1ec64, 0x1e422, 0x1ec62, 0x1c868, 0x1e436, 0x1d8e8,
+ 0x1c864, 0x1d8e4, 0x1c862, 0x1d8e2, 0x190e8, 0x1c876,
+ 0x1b1e8, 0x1d8f6, 0x1b1e4, 0x190e2, 0x1b1e2, 0x121e8,
+ 0x190f6, 0x163e8, 0x121e4, 0x163e4, 0x121e2, 0x163e2,
+ 0x121f6, 0x163f6, 0x1f614, 0x1617e, 0x1f612, 0x1e414,
+ 0x1ec34, 0x1e412, 0x1ec32, 0x1c834, 0x1d874, 0x1c832,
+ 0x1d872, 0x19074, 0x1b0f4, 0x19072, 0x1b0f2, 0x120f4,
+ 0x161f4, 0x120f2, 0x161f2, 0x1f60a, 0x1e40a, 0x1ec1a,
+ 0x1c81a, 0x1d83a, 0x1903a, 0x1b07a, 0x1e2a0, 0x1f158,
+ 0x1f8ae, 0x1e290, 0x1f14c, 0x1e288, 0x1f146, 0x1e284,
+ 0x1e282, 0x1c5a0, 0x1e2d8, 0x1f16e, 0x1c590, 0x1e2cc,
+ 0x1c588, 0x1e2c6, 0x1c584, 0x1c582, 0x18ba0, 0x1c5d8,
+ 0x1e2ee, 0x18b90, 0x1c5cc, 0x18b88, 0x1c5c6, 0x18b84,
+ 0x18b82, 0x117a0, 0x18bd8, 0x1c5ee, 0x11790, 0x18bcc,
+ 0x11788, 0x18bc6, 0x11784, 0x11782, 0x117d8, 0x18bee,
+ 0x117cc, 0x117c6, 0x117ee, 0x1f350, 0x1f9ac, 0x135f8,
+ 0x1f348, 0x1f9a6, 0x134fc, 0x1f344, 0x1347e, 0x1f342,
+ 0x1e250, 0x1f12c, 0x1e6d0, 0x1e248, 0x1f126, 0x1e6c8,
+ 0x1f366, 0x1e6c4, 0x1e242, 0x1e6c2, 0x1c4d0, 0x1e26c,
+ 0x1cdd0, 0x1c4c8, 0x1e266, 0x1cdc8, 0x1e6e6, 0x1cdc4,
+ 0x1c4c2, 0x1cdc2, 0x189d0, 0x1c4ec, 0x19bd0, 0x189c8,
+ 0x1c4e6, 0x19bc8, 0x1cde6, 0x19bc4, 0x189c2, 0x19bc2,
+ 0x113d0, 0x189ec, 0x137d0, 0x113c8, 0x189e6, 0x137c8,
+ 0x19be6, 0x137c4, 0x113c2, 0x137c2, 0x113ec, 0x137ec,
+ 0x113e6, 0x137e6, 0x1fba8, 0x175f0, 0x1bafc, 0x1fba4,
+ 0x174f8, 0x1ba7e, 0x1fba2, 0x1747c, 0x1743e, 0x1f328,
+ 0x1f996, 0x132fc, 0x1f768, 0x1fbb6, 0x176fc, 0x1327e,
+ 0x1f764, 0x1f322, 0x1767e, 0x1f762, 0x1e228, 0x1f116,
+ 0x1e668, 0x1e224, 0x1eee8, 0x1f776, 0x1e222, 0x1eee4,
+ 0x1e662, 0x1eee2, 0x1c468, 0x1e236, 0x1cce8, 0x1c464,
+ 0x1dde8, 0x1cce4, 0x1c462, 0x1dde4, 0x1cce2, 0x1dde2,
+ 0x188e8, 0x1c476, 0x199e8, 0x188e4, 0x1bbe8, 0x199e4,
+ 0x188e2, 0x1bbe4, 0x199e2, 0x1bbe2, 0x111e8, 0x188f6,
+ 0x133e8, 0x111e4, 0x177e8, 0x133e4, 0x111e2, 0x177e4,
+ 0x133e2, 0x177e2, 0x111f6, 0x133f6, 0x1fb94, 0x172f8,
+ 0x1b97e, 0x1fb92, 0x1727c, 0x1723e, 0x1f314, 0x1317e,
+ 0x1f734, 0x1f312, 0x1737e, 0x1f732, 0x1e214, 0x1e634,
+ 0x1e212, 0x1ee74, 0x1e632, 0x1ee72, 0x1c434, 0x1cc74,
+ 0x1c432, 0x1dcf4, 0x1cc72, 0x1dcf2, 0x18874, 0x198f4,
+ 0x18872, 0x1b9f4, 0x198f2, 0x1b9f2, 0x110f4, 0x131f4,
+ 0x110f2, 0x173f4, 0x131f2, 0x173f2, 0x1fb8a, 0x1717c,
+ 0x1713e, 0x1f30a, 0x1f71a, 0x1e20a, 0x1e61a, 0x1ee3a,
+ 0x1c41a, 0x1cc3a, 0x1dc7a, 0x1883a, 0x1987a, 0x1b8fa,
+ 0x1107a, 0x130fa, 0x171fa, 0x170be, 0x1e150, 0x1f0ac,
+ 0x1e148, 0x1f0a6, 0x1e144, 0x1e142, 0x1c2d0, 0x1e16c,
+ 0x1c2c8, 0x1e166, 0x1c2c4, 0x1c2c2, 0x185d0, 0x1c2ec,
+ 0x185c8, 0x1c2e6, 0x185c4, 0x185c2, 0x10bd0, 0x185ec,
+ 0x10bc8, 0x185e6, 0x10bc4, 0x10bc2, 0x10bec, 0x10be6,
+ 0x1f1a8, 0x1f8d6, 0x11afc, 0x1f1a4, 0x11a7e, 0x1f1a2,
+ 0x1e128, 0x1f096, 0x1e368, 0x1e124, 0x1e364, 0x1e122,
+ 0x1e362, 0x1c268, 0x1e136, 0x1c6e8, 0x1c264, 0x1c6e4,
+ 0x1c262, 0x1c6e2, 0x184e8, 0x1c276, 0x18de8, 0x184e4,
+ 0x18de4, 0x184e2, 0x18de2, 0x109e8, 0x184f6, 0x11be8,
+ 0x109e4, 0x11be4, 0x109e2, 0x11be2, 0x109f6, 0x11bf6,
+ 0x1f9d4, 0x13af8, 0x19d7e, 0x1f9d2, 0x13a7c, 0x13a3e,
+ 0x1f194, 0x1197e, 0x1f3b4, 0x1f192, 0x13b7e, 0x1f3b2,
+ 0x1e114, 0x1e334, 0x1e112, 0x1e774, 0x1e332, 0x1e772,
+ 0x1c234, 0x1c674, 0x1c232, 0x1cef4, 0x1c672, 0x1cef2,
+ 0x18474, 0x18cf4, 0x18472, 0x19df4, 0x18cf2, 0x19df2,
+ 0x108f4, 0x119f4, 0x108f2, 0x13bf4, 0x119f2, 0x13bf2,
+ 0x17af0, 0x1bd7c, 0x17a78, 0x1bd3e, 0x17a3c, 0x17a1e,
+ 0x1f9ca, 0x1397c, 0x1fbda, 0x17b7c, 0x1393e, 0x17b3e,
+ 0x1f18a, 0x1f39a, 0x1f7ba, 0x1e10a, 0x1e31a, 0x1e73a,
+ 0x1ef7a, 0x1c21a, 0x1c63a, 0x1ce7a, 0x1defa, 0x1843a,
+ 0x18c7a, 0x19cfa, 0x1bdfa, 0x1087a, 0x118fa, 0x139fa,
+ 0x17978, 0x1bcbe, 0x1793c, 0x1791e, 0x138be, 0x179be,
+ 0x178bc, 0x1789e, 0x1785e, 0x1e0a8, 0x1e0a4, 0x1e0a2,
+ 0x1c168, 0x1e0b6, 0x1c164, 0x1c162, 0x182e8, 0x1c176,
+ 0x182e4, 0x182e2, 0x105e8, 0x182f6, 0x105e4, 0x105e2,
+ 0x105f6, 0x1f0d4, 0x10d7e, 0x1f0d2, 0x1e094, 0x1e1b4,
+ 0x1e092, 0x1e1b2, 0x1c134, 0x1c374, 0x1c132, 0x1c372,
+ 0x18274, 0x186f4, 0x18272, 0x186f2, 0x104f4, 0x10df4,
+ 0x104f2, 0x10df2, 0x1f8ea, 0x11d7c, 0x11d3e, 0x1f0ca,
+ 0x1f1da, 0x1e08a, 0x1e19a, 0x1e3ba, 0x1c11a, 0x1c33a,
+ 0x1c77a, 0x1823a, 0x1867a, 0x18efa, 0x1047a, 0x10cfa,
+ 0x11dfa, 0x13d78, 0x19ebe, 0x13d3c, 0x13d1e, 0x11cbe,
+ 0x13dbe, 0x17d70, 0x1bebc, 0x17d38, 0x1be9e, 0x17d1c,
+ 0x17d0e, 0x13cbc, 0x17dbc, 0x13c9e, 0x17d9e, 0x17cb8,
+ 0x1be5e, 0x17c9c, 0x17c8e, 0x13c5e, 0x17cde, 0x17c5c,
+ 0x17c4e, 0x17c2e, 0x1c0b4, 0x1c0b2, 0x18174, 0x18172,
+ 0x102f4, 0x102f2, 0x1e0da, 0x1c09a, 0x1c1ba, 0x1813a,
+ 0x1837a, 0x1027a, 0x106fa, 0x10ebe, 0x11ebc, 0x11e9e,
+ 0x13eb8, 0x19f5e, 0x13e9c, 0x13e8e, 0x11e5e, 0x13ede,
+ 0x17eb0, 0x1bf5c, 0x17e98, 0x1bf4e, 0x17e8c, 0x17e86,
+ 0x13e5c, 0x17edc, 0x13e4e, 0x17ece, 0x17e58, 0x1bf2e,
+ 0x17e4c, 0x17e46, 0x13e2e, 0x17e6e, 0x17e2c, 0x17e26,
+ 0x10f5e, 0x11f5c, 0x11f4e, 0x13f58, 0x19fae, 0x13f4c,
+ 0x13f46, 0x11f2e, 0x13f6e, 0x13f2c, 0x13f26
+ },
+ {
+ 0x1abe0, 0x1d5f8, 0x153c0, 0x1a9f0, 0x1d4fc, 0x151e0,
+ 0x1a8f8, 0x1d47e, 0x150f0, 0x1a87c, 0x15078, 0x1fad0,
+ 0x15be0, 0x1adf8, 0x1fac8, 0x159f0, 0x1acfc, 0x1fac4,
+ 0x158f8, 0x1ac7e, 0x1fac2, 0x1587c, 0x1f5d0, 0x1faec,
+ 0x15df8, 0x1f5c8, 0x1fae6, 0x15cfc, 0x1f5c4, 0x15c7e,
+ 0x1f5c2, 0x1ebd0, 0x1f5ec, 0x1ebc8, 0x1f5e6, 0x1ebc4,
+ 0x1ebc2, 0x1d7d0, 0x1ebec, 0x1d7c8, 0x1ebe6, 0x1d7c4,
+ 0x1d7c2, 0x1afd0, 0x1d7ec, 0x1afc8, 0x1d7e6, 0x1afc4,
+ 0x14bc0, 0x1a5f0, 0x1d2fc, 0x149e0, 0x1a4f8, 0x1d27e,
+ 0x148f0, 0x1a47c, 0x14878, 0x1a43e, 0x1483c, 0x1fa68,
+ 0x14df0, 0x1a6fc, 0x1fa64, 0x14cf8, 0x1a67e, 0x1fa62,
+ 0x14c7c, 0x14c3e, 0x1f4e8, 0x1fa76, 0x14efc, 0x1f4e4,
+ 0x14e7e, 0x1f4e2, 0x1e9e8, 0x1f4f6, 0x1e9e4, 0x1e9e2,
+ 0x1d3e8, 0x1e9f6, 0x1d3e4, 0x1d3e2, 0x1a7e8, 0x1d3f6,
+ 0x1a7e4, 0x1a7e2, 0x145e0, 0x1a2f8, 0x1d17e, 0x144f0,
+ 0x1a27c, 0x14478, 0x1a23e, 0x1443c, 0x1441e, 0x1fa34,
+ 0x146f8, 0x1a37e, 0x1fa32, 0x1467c, 0x1463e, 0x1f474,
+ 0x1477e, 0x1f472, 0x1e8f4, 0x1e8f2, 0x1d1f4, 0x1d1f2,
+ 0x1a3f4, 0x1a3f2, 0x142f0, 0x1a17c, 0x14278, 0x1a13e,
+ 0x1423c, 0x1421e, 0x1fa1a, 0x1437c, 0x1433e, 0x1f43a,
+ 0x1e87a, 0x1d0fa, 0x14178, 0x1a0be, 0x1413c, 0x1411e,
+ 0x141be, 0x140bc, 0x1409e, 0x12bc0, 0x195f0, 0x1cafc,
+ 0x129e0, 0x194f8, 0x1ca7e, 0x128f0, 0x1947c, 0x12878,
+ 0x1943e, 0x1283c, 0x1f968, 0x12df0, 0x196fc, 0x1f964,
+ 0x12cf8, 0x1967e, 0x1f962, 0x12c7c, 0x12c3e, 0x1f2e8,
+ 0x1f976, 0x12efc, 0x1f2e4, 0x12e7e, 0x1f2e2, 0x1e5e8,
+ 0x1f2f6, 0x1e5e4, 0x1e5e2, 0x1cbe8, 0x1e5f6, 0x1cbe4,
+ 0x1cbe2, 0x197e8, 0x1cbf6, 0x197e4, 0x197e2, 0x1b5e0,
+ 0x1daf8, 0x1ed7e, 0x169c0, 0x1b4f0, 0x1da7c, 0x168e0,
+ 0x1b478, 0x1da3e, 0x16870, 0x1b43c, 0x16838, 0x1b41e,
+ 0x1681c, 0x125e0, 0x192f8, 0x1c97e, 0x16de0, 0x124f0,
+ 0x1927c, 0x16cf0, 0x1b67c, 0x1923e, 0x16c78, 0x1243c,
+ 0x16c3c, 0x1241e, 0x16c1e, 0x1f934, 0x126f8, 0x1937e,
+ 0x1fb74, 0x1f932, 0x16ef8, 0x1267c, 0x1fb72, 0x16e7c,
+ 0x1263e, 0x16e3e, 0x1f274, 0x1277e, 0x1f6f4, 0x1f272,
+ 0x16f7e, 0x1f6f2, 0x1e4f4, 0x1edf4, 0x1e4f2, 0x1edf2,
+ 0x1c9f4, 0x1dbf4, 0x1c9f2, 0x1dbf2, 0x193f4, 0x193f2,
+ 0x165c0, 0x1b2f0, 0x1d97c, 0x164e0, 0x1b278, 0x1d93e,
+ 0x16470, 0x1b23c, 0x16438, 0x1b21e, 0x1641c, 0x1640e,
+ 0x122f0, 0x1917c, 0x166f0, 0x12278, 0x1913e, 0x16678,
+ 0x1b33e, 0x1663c, 0x1221e, 0x1661e, 0x1f91a, 0x1237c,
+ 0x1fb3a, 0x1677c, 0x1233e, 0x1673e, 0x1f23a, 0x1f67a,
+ 0x1e47a, 0x1ecfa, 0x1c8fa, 0x1d9fa, 0x191fa, 0x162e0,
+ 0x1b178, 0x1d8be, 0x16270, 0x1b13c, 0x16238, 0x1b11e,
+ 0x1621c, 0x1620e, 0x12178, 0x190be, 0x16378, 0x1213c,
+ 0x1633c, 0x1211e, 0x1631e, 0x121be, 0x163be, 0x16170,
+ 0x1b0bc, 0x16138, 0x1b09e, 0x1611c, 0x1610e, 0x120bc,
+ 0x161bc, 0x1209e, 0x1619e, 0x160b8, 0x1b05e, 0x1609c,
+ 0x1608e, 0x1205e, 0x160de, 0x1605c, 0x1604e, 0x115e0,
+ 0x18af8, 0x1c57e, 0x114f0, 0x18a7c, 0x11478, 0x18a3e,
+ 0x1143c, 0x1141e, 0x1f8b4, 0x116f8, 0x18b7e, 0x1f8b2,
+ 0x1167c, 0x1163e, 0x1f174, 0x1177e, 0x1f172, 0x1e2f4,
+ 0x1e2f2, 0x1c5f4, 0x1c5f2, 0x18bf4, 0x18bf2, 0x135c0,
+ 0x19af0, 0x1cd7c, 0x134e0, 0x19a78, 0x1cd3e, 0x13470,
+ 0x19a3c, 0x13438, 0x19a1e, 0x1341c, 0x1340e, 0x112f0,
+ 0x1897c, 0x136f0, 0x11278, 0x1893e, 0x13678, 0x19b3e,
+ 0x1363c, 0x1121e, 0x1361e, 0x1f89a, 0x1137c, 0x1f9ba,
+ 0x1377c, 0x1133e, 0x1373e, 0x1f13a, 0x1f37a, 0x1e27a,
+ 0x1e6fa, 0x1c4fa, 0x1cdfa, 0x189fa, 0x1bae0, 0x1dd78,
+ 0x1eebe, 0x174c0, 0x1ba70, 0x1dd3c, 0x17460, 0x1ba38,
+ 0x1dd1e, 0x17430, 0x1ba1c, 0x17418, 0x1ba0e, 0x1740c,
+ 0x132e0, 0x19978, 0x1ccbe, 0x176e0, 0x13270, 0x1993c,
+ 0x17670, 0x1bb3c, 0x1991e, 0x17638, 0x1321c, 0x1761c,
+ 0x1320e, 0x1760e, 0x11178, 0x188be, 0x13378, 0x1113c,
+ 0x17778, 0x1333c, 0x1111e, 0x1773c, 0x1331e, 0x1771e,
+ 0x111be, 0x133be, 0x177be, 0x172c0, 0x1b970, 0x1dcbc,
+ 0x17260, 0x1b938, 0x1dc9e, 0x17230, 0x1b91c, 0x17218,
+ 0x1b90e, 0x1720c, 0x17206, 0x13170, 0x198bc, 0x17370,
+ 0x13138, 0x1989e, 0x17338, 0x1b99e, 0x1731c, 0x1310e,
+ 0x1730e, 0x110bc, 0x131bc, 0x1109e, 0x173bc, 0x1319e,
+ 0x1739e, 0x17160, 0x1b8b8, 0x1dc5e, 0x17130, 0x1b89c,
+ 0x17118, 0x1b88e, 0x1710c, 0x17106, 0x130b8, 0x1985e,
+ 0x171b8, 0x1309c, 0x1719c, 0x1308e, 0x1718e, 0x1105e,
+ 0x130de, 0x171de, 0x170b0, 0x1b85c, 0x17098, 0x1b84e,
+ 0x1708c, 0x17086, 0x1305c, 0x170dc, 0x1304e, 0x170ce,
+ 0x17058, 0x1b82e, 0x1704c, 0x17046, 0x1302e, 0x1706e,
+ 0x1702c, 0x17026, 0x10af0, 0x1857c, 0x10a78, 0x1853e,
+ 0x10a3c, 0x10a1e, 0x10b7c, 0x10b3e, 0x1f0ba, 0x1e17a,
+ 0x1c2fa, 0x185fa, 0x11ae0, 0x18d78, 0x1c6be, 0x11a70,
+ 0x18d3c, 0x11a38, 0x18d1e, 0x11a1c, 0x11a0e, 0x10978,
+ 0x184be, 0x11b78, 0x1093c, 0x11b3c, 0x1091e, 0x11b1e,
+ 0x109be, 0x11bbe, 0x13ac0, 0x19d70, 0x1cebc, 0x13a60,
+ 0x19d38, 0x1ce9e, 0x13a30, 0x19d1c, 0x13a18, 0x19d0e,
+ 0x13a0c, 0x13a06, 0x11970, 0x18cbc, 0x13b70, 0x11938,
+ 0x18c9e, 0x13b38, 0x1191c, 0x13b1c, 0x1190e, 0x13b0e,
+ 0x108bc, 0x119bc, 0x1089e, 0x13bbc, 0x1199e, 0x13b9e,
+ 0x1bd60, 0x1deb8, 0x1ef5e, 0x17a40, 0x1bd30, 0x1de9c,
+ 0x17a20, 0x1bd18, 0x1de8e, 0x17a10, 0x1bd0c, 0x17a08,
+ 0x1bd06, 0x17a04, 0x13960, 0x19cb8, 0x1ce5e, 0x17b60,
+ 0x13930, 0x19c9c, 0x17b30, 0x1bd9c, 0x19c8e, 0x17b18,
+ 0x1390c, 0x17b0c, 0x13906, 0x17b06, 0x118b8, 0x18c5e,
+ 0x139b8, 0x1189c, 0x17bb8, 0x1399c, 0x1188e, 0x17b9c,
+ 0x1398e, 0x17b8e, 0x1085e, 0x118de, 0x139de, 0x17bde,
+ 0x17940, 0x1bcb0, 0x1de5c, 0x17920, 0x1bc98, 0x1de4e,
+ 0x17910, 0x1bc8c, 0x17908, 0x1bc86, 0x17904, 0x17902,
+ 0x138b0, 0x19c5c, 0x179b0, 0x13898, 0x19c4e, 0x17998,
+ 0x1bcce, 0x1798c, 0x13886, 0x17986, 0x1185c, 0x138dc,
+ 0x1184e, 0x179dc, 0x138ce, 0x179ce, 0x178a0, 0x1bc58,
+ 0x1de2e, 0x17890, 0x1bc4c, 0x17888, 0x1bc46, 0x17884,
+ 0x17882, 0x13858, 0x19c2e, 0x178d8, 0x1384c, 0x178cc,
+ 0x13846, 0x178c6, 0x1182e, 0x1386e, 0x178ee, 0x17850,
+ 0x1bc2c, 0x17848, 0x1bc26, 0x17844, 0x17842, 0x1382c,
+ 0x1786c, 0x13826, 0x17866, 0x17828, 0x1bc16, 0x17824,
+ 0x17822, 0x13816, 0x17836, 0x10578, 0x182be, 0x1053c,
+ 0x1051e, 0x105be, 0x10d70, 0x186bc, 0x10d38, 0x1869e,
+ 0x10d1c, 0x10d0e, 0x104bc, 0x10dbc, 0x1049e, 0x10d9e,
+ 0x11d60, 0x18eb8, 0x1c75e, 0x11d30, 0x18e9c, 0x11d18,
+ 0x18e8e, 0x11d0c, 0x11d06, 0x10cb8, 0x1865e, 0x11db8,
+ 0x10c9c, 0x11d9c, 0x10c8e, 0x11d8e, 0x1045e, 0x10cde,
+ 0x11dde, 0x13d40, 0x19eb0, 0x1cf5c, 0x13d20, 0x19e98,
+ 0x1cf4e, 0x13d10, 0x19e8c, 0x13d08, 0x19e86, 0x13d04,
+ 0x13d02, 0x11cb0, 0x18e5c, 0x13db0, 0x11c98, 0x18e4e,
+ 0x13d98, 0x19ece, 0x13d8c, 0x11c86, 0x13d86, 0x10c5c,
+ 0x11cdc, 0x10c4e, 0x13ddc, 0x11cce, 0x13dce, 0x1bea0,
+ 0x1df58, 0x1efae, 0x1be90, 0x1df4c, 0x1be88, 0x1df46,
+ 0x1be84, 0x1be82, 0x13ca0, 0x19e58, 0x1cf2e, 0x17da0,
+ 0x13c90, 0x19e4c, 0x17d90, 0x1becc, 0x19e46, 0x17d88,
+ 0x13c84, 0x17d84, 0x13c82, 0x17d82, 0x11c58, 0x18e2e,
+ 0x13cd8, 0x11c4c, 0x17dd8, 0x13ccc, 0x11c46, 0x17dcc,
+ 0x13cc6, 0x17dc6, 0x10c2e, 0x11c6e, 0x13cee, 0x17dee,
+ 0x1be50, 0x1df2c, 0x1be48, 0x1df26, 0x1be44, 0x1be42,
+ 0x13c50, 0x19e2c, 0x17cd0, 0x13c48, 0x19e26, 0x17cc8,
+ 0x1be66, 0x17cc4, 0x13c42, 0x17cc2, 0x11c2c, 0x13c6c,
+ 0x11c26, 0x17cec, 0x13c66, 0x17ce6, 0x1be28, 0x1df16,
+ 0x1be24, 0x1be22, 0x13c28, 0x19e16, 0x17c68, 0x13c24,
+ 0x17c64, 0x13c22, 0x17c62, 0x11c16, 0x13c36, 0x17c76,
+ 0x1be14, 0x1be12, 0x13c14, 0x17c34, 0x13c12, 0x17c32,
+ 0x102bc, 0x1029e, 0x106b8, 0x1835e, 0x1069c, 0x1068e,
+ 0x1025e, 0x106de, 0x10eb0, 0x1875c, 0x10e98, 0x1874e,
+ 0x10e8c, 0x10e86, 0x1065c, 0x10edc, 0x1064e, 0x10ece,
+ 0x11ea0, 0x18f58, 0x1c7ae, 0x11e90, 0x18f4c, 0x11e88,
+ 0x18f46, 0x11e84, 0x11e82, 0x10e58, 0x1872e, 0x11ed8,
+ 0x18f6e, 0x11ecc, 0x10e46, 0x11ec6, 0x1062e, 0x10e6e,
+ 0x11eee, 0x19f50, 0x1cfac, 0x19f48, 0x1cfa6, 0x19f44,
+ 0x19f42, 0x11e50, 0x18f2c, 0x13ed0, 0x19f6c, 0x18f26,
+ 0x13ec8, 0x11e44, 0x13ec4, 0x11e42, 0x13ec2, 0x10e2c,
+ 0x11e6c, 0x10e26, 0x13eec, 0x11e66, 0x13ee6, 0x1dfa8,
+ 0x1efd6, 0x1dfa4, 0x1dfa2, 0x19f28, 0x1cf96, 0x1bf68,
+ 0x19f24, 0x1bf64, 0x19f22, 0x1bf62, 0x11e28, 0x18f16,
+ 0x13e68, 0x11e24, 0x17ee8, 0x13e64, 0x11e22, 0x17ee4,
+ 0x13e62, 0x17ee2, 0x10e16, 0x11e36, 0x13e76, 0x17ef6,
+ 0x1df94, 0x1df92, 0x19f14, 0x1bf34, 0x19f12, 0x1bf32,
+ 0x11e14, 0x13e34, 0x11e12, 0x17e74, 0x13e32, 0x17e72,
+ 0x1df8a, 0x19f0a, 0x1bf1a, 0x11e0a, 0x13e1a, 0x17e3a,
+ 0x1035c, 0x1034e, 0x10758, 0x183ae, 0x1074c, 0x10746,
+ 0x1032e, 0x1076e, 0x10f50, 0x187ac, 0x10f48, 0x187a6,
+ 0x10f44, 0x10f42, 0x1072c, 0x10f6c, 0x10726, 0x10f66,
+ 0x18fa8, 0x1c7d6, 0x18fa4, 0x18fa2, 0x10f28, 0x18796,
+ 0x11f68, 0x18fb6, 0x11f64, 0x10f22, 0x11f62, 0x10716,
+ 0x10f36, 0x11f76, 0x1cfd4, 0x1cfd2, 0x18f94, 0x19fb4,
+ 0x18f92, 0x19fb2, 0x10f14, 0x11f34, 0x10f12, 0x13f74,
+ 0x11f32, 0x13f72, 0x1cfca, 0x18f8a, 0x19f9a, 0x10f0a,
+ 0x11f1a, 0x13f3a, 0x103ac, 0x103a6, 0x107a8, 0x183d6,
+ 0x107a4, 0x107a2, 0x10396, 0x107b6, 0x187d4, 0x187d2,
+ 0x10794, 0x10fb4, 0x10792, 0x10fb2, 0x1c7ea
+ }
+};
+FX_FLOAT CBC_PDF417::PREFERRED_RATIO = 3.0f;
+FX_FLOAT CBC_PDF417::DEFAULT_MODULE_WIDTH = 0.357f;
+FX_FLOAT CBC_PDF417::HEIGHT = 2.0f;
+CBC_PDF417::CBC_PDF417()
+{
+ m_compact = FALSE;
+ m_compaction = AUTO;
+ m_minCols = 1;
+ m_maxCols = 30;
+ m_maxRows = 90;
+ m_minRows = 3;
+ m_barcodeMatrix = NULL;
+}
+CBC_PDF417::CBC_PDF417(FX_BOOL compact)
+{
+ m_compact = compact;
+ m_compaction = AUTO;
+ m_minCols = 1;
+ m_maxCols = 30;
+ m_maxRows = 90;
+ m_minRows = 3;
+ m_barcodeMatrix = NULL;
+}
+CBC_PDF417::~CBC_PDF417()
+{
+ if (m_barcodeMatrix) {
+ delete m_barcodeMatrix;
+ }
+}
+CBC_BarcodeMatrix* CBC_PDF417::getBarcodeMatrix()
+{
+ return m_barcodeMatrix;
+}
+void CBC_PDF417::generateBarcodeLogic(CFX_WideString msg, FX_INT32 errorCorrectionLevel, FX_INT32 &e)
+{
+ FX_INT32 errorCorrectionCodeWords = CBC_PDF417ErrorCorrection::getErrorCorrectionCodewordCount(errorCorrectionLevel, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CFX_WideString highLevel = CBC_PDF417HighLevelEncoder::encodeHighLevel(msg, m_compaction, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 sourceCodeWords = highLevel.GetLength();
+ CFX_Int32Array* dimension = determineDimensions(sourceCodeWords, errorCorrectionCodeWords, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 cols = dimension->GetAt(0);
+ FX_INT32 rows = dimension->GetAt(1);
+ delete dimension;
+ FX_INT32 pad = getNumberOfPadCodewords(sourceCodeWords, errorCorrectionCodeWords, cols, rows);
+ if (sourceCodeWords + errorCorrectionCodeWords + 1 > 929) {
+ e = BCExceptionEncodedMessageContainsTooManyCodeWords;
+ return;
+ }
+ FX_INT32 n = sourceCodeWords + pad + 1;
+ CFX_WideString sb;
+ sb += (FX_WCHAR) n;
+ sb += highLevel;
+ for (FX_INT32 i = 0; i < pad; i++) {
+ sb += (FX_WCHAR) 900;
+ }
+ CFX_WideString dataCodewords(sb);
+ CFX_WideString ec = CBC_PDF417ErrorCorrection::generateErrorCorrection(dataCodewords, errorCorrectionLevel, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CFX_WideString fullCodewords = dataCodewords + ec;
+ m_barcodeMatrix = FX_NEW CBC_BarcodeMatrix(rows, cols);
+ encodeLowLevel(fullCodewords, cols, rows, errorCorrectionLevel, m_barcodeMatrix);
+}
+void CBC_PDF417::setDimensions(FX_INT32 maxCols, FX_INT32 minCols, FX_INT32 maxRows, FX_INT32 minRows)
+{
+ m_maxCols = maxCols;
+ m_minCols = minCols;
+ m_maxRows = maxRows;
+ m_minRows = minRows;
+}
+void CBC_PDF417::setCompaction(Compaction compaction)
+{
+ m_compaction = compaction;
+}
+void CBC_PDF417::setCompact(FX_BOOL compact)
+{
+ m_compact = compact;
+}
+FX_INT32 CBC_PDF417::calculateNumberOfRows(FX_INT32 m, FX_INT32 k, FX_INT32 c)
+{
+ FX_INT32 r = ((m + 1 + k) / c) + 1;
+ if (c * r >= (m + 1 + k + c)) {
+ r--;
+ }
+ return r;
+}
+FX_INT32 CBC_PDF417::getNumberOfPadCodewords(FX_INT32 m, FX_INT32 k, FX_INT32 c, FX_INT32 r)
+{
+ FX_INT32 n = c * r - k;
+ return n > m + 1 ? n - m - 1 : 0;
+}
+void CBC_PDF417::encodeChar(FX_INT32 pattern, FX_INT32 len, CBC_BarcodeRow* logic)
+{
+ FX_INT32 map = 1 << (len - 1);
+ FX_BOOL last = ((pattern & map) != 0);
+ FX_INT32 width = 0;
+ for (FX_INT32 i = 0; i < len; i++) {
+ FX_BOOL black = ((pattern & map) != 0);
+ if (last == black) {
+ width++;
+ } else {
+ logic->addBar(last, width);
+ last = black;
+ width = 1;
+ }
+ map >>= 1;
+ }
+ logic->addBar(last, width);
+}
+void CBC_PDF417::encodeLowLevel(CFX_WideString fullCodewords, FX_INT32 c, FX_INT32 r, FX_INT32 errorCorrectionLevel, CBC_BarcodeMatrix* logic)
+{
+ FX_INT32 idx = 0;
+ for (FX_INT32 y = 0; y < r; y++) {
+ FX_INT32 cluster = y % 3;
+ logic->startRow();
+ FX_INT32 a = START_PATTERN;
+ encodeChar(START_PATTERN, 17, logic->getCurrentRow());
+ FX_INT32 left;
+ FX_INT32 right;
+ if (cluster == 0) {
+ left = (30 * (y / 3)) + ((r - 1) / 3);
+ right = (30 * (y / 3)) + (c - 1);
+ } else if (cluster == 1) {
+ left = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3);
+ right = (30 * (y / 3)) + ((r - 1) / 3);
+ } else {
+ left = (30 * (y / 3)) + (c - 1);
+ right = (30 * (y / 3)) + (errorCorrectionLevel * 3) + ((r - 1) % 3);
+ }
+ FX_INT32 pattern = CODEWORD_TABLE[cluster][left];
+ encodeChar(pattern, 17, logic->getCurrentRow());
+ for (FX_INT32 x = 0; x < c; x++) {
+ pattern = CODEWORD_TABLE[cluster][fullCodewords.GetAt(idx)];
+ encodeChar(pattern, 17, logic->getCurrentRow());
+ idx++;
+ }
+ if (m_compact) {
+ encodeChar(STOP_PATTERN, 1, logic->getCurrentRow());
+ } else {
+ pattern = CODEWORD_TABLE[cluster][right];
+ encodeChar(pattern, 17, logic->getCurrentRow());
+ encodeChar(STOP_PATTERN, 18, logic->getCurrentRow());
+ }
+ }
+}
+CFX_Int32Array* CBC_PDF417::determineDimensions(FX_INT32 sourceCodeWords, FX_INT32 errorCorrectionCodeWords, FX_INT32 &e)
+{
+ FX_FLOAT ratio = 0.0f;
+ CFX_Int32Array* dimension = NULL;
+ for (FX_INT32 cols = m_minCols; cols <= m_maxCols; cols++) {
+ FX_INT32 rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, cols);
+ if (rows < m_minRows) {
+ break;
+ }
+ if (rows > m_maxRows) {
+ continue;
+ }
+ FX_FLOAT newRatio = ((17 * cols + 69) * DEFAULT_MODULE_WIDTH) / (rows * HEIGHT);
+ if (dimension != NULL && fabsf(newRatio - PREFERRED_RATIO) > fabsf(ratio - PREFERRED_RATIO)) {
+ continue;
+ }
+ ratio = newRatio;
+ if (dimension) {
+ delete dimension;
+ }
+ dimension = FX_NEW CFX_Int32Array;
+ dimension->Add(cols);
+ dimension->Add(rows);
+ }
+ if (dimension == NULL) {
+ FX_INT32 rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, m_minCols);
+ if (rows < m_minRows) {
+ dimension = FX_NEW CFX_Int32Array;
+ dimension->Add(m_minCols);
+ dimension->Add(m_minRows);
+ } else if (rows >= 3 && rows <= 90) {
+ dimension = FX_NEW CFX_Int32Array;
+ dimension->Add(m_minCols);
+ dimension->Add(rows);
+ }
+ }
+ if (dimension == NULL) {
+ e = BCExceptionUnableToFitMessageInColumns;
+ return NULL;
+ }
+ return dimension;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417BarcodeMatrix.cpp b/xfa/src/fxbarcode/src/BC_PDF417BarcodeMatrix.cpp
new file mode 100644
index 0000000000..4265881c0f
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417BarcodeMatrix.cpp
@@ -0,0 +1,82 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417BarcodeRow.h"
+#include "include/BC_PDF417BarcodeMatrix.h"
+CBC_BarcodeMatrix::CBC_BarcodeMatrix(FX_INT32 height, FX_INT32 width)
+{
+ m_matrix.SetSize(height + 2);
+ for (FX_INT32 i = 0, matrixLength = m_matrix.GetSize(); i < matrixLength; i++) {
+ m_matrix[i] = FX_NEW CBC_BarcodeRow((width + 4) * 17 + 1);
+ }
+ m_width = width * 17;
+ m_height = height + 2;
+ m_currentRow = 0;
+ m_outHeight = 0;
+ m_outWidth = 0;
+}
+CBC_BarcodeMatrix::~CBC_BarcodeMatrix()
+{
+ for (FX_INT32 i = 0; i < m_matrix.GetSize(); i++) {
+ delete (CBC_BarcodeRow*)m_matrix.GetAt(i);
+ }
+ m_matrix.RemoveAll();
+ m_matrixOut.RemoveAll();
+}
+void CBC_BarcodeMatrix::set(FX_INT32 x, FX_INT32 y, FX_BYTE value)
+{
+ ((CBC_BarcodeRow*)m_matrix[y])->set(x, value);
+}
+void CBC_BarcodeMatrix::setMatrix(FX_INT32 x, FX_INT32 y, FX_BOOL black)
+{
+ set(x, y, (FX_BYTE) (black ? 1 : 0));
+}
+void CBC_BarcodeMatrix::startRow()
+{
+ ++m_currentRow;
+}
+CBC_BarcodeRow* CBC_BarcodeMatrix::getCurrentRow()
+{
+ return (CBC_BarcodeRow*)m_matrix[m_currentRow];
+}
+FX_INT32 CBC_BarcodeMatrix::getWidth()
+{
+ return m_outWidth;
+}
+FX_INT32 CBC_BarcodeMatrix::getHeight()
+{
+ return m_outHeight;
+}
+CFX_ByteArray& CBC_BarcodeMatrix::getMatrix()
+{
+ return getScaledMatrix(1, 1);
+}
+CFX_ByteArray& CBC_BarcodeMatrix::getScaledMatrix(FX_INT32 scale)
+{
+ return getScaledMatrix(scale, scale);
+}
+CFX_ByteArray& CBC_BarcodeMatrix::getScaledMatrix(FX_INT32 xScale, FX_INT32 yScale)
+{
+ FX_INT32 yMax = m_height * yScale;
+ CFX_ByteArray bytearray;
+ bytearray.Copy(((CBC_BarcodeRow*)m_matrix[0])->getScaledRow(xScale));
+ FX_INT32 xMax = bytearray.GetSize();
+ m_matrixOut.SetSize(xMax * yMax);
+ m_outWidth = xMax;
+ m_outHeight = yMax;
+ FX_INT32 k = 0;
+ for (FX_INT32 i = 0; i < yMax; i++) {
+ if (i != 0) {
+ bytearray.Copy(((CBC_BarcodeRow*)m_matrix[i / yScale])->getScaledRow(xScale));
+ }
+ k = i * xMax;
+ for (FX_INT32 l = 0; l < xMax; l++) {
+ m_matrixOut[k + l] = bytearray.GetAt(l);
+ }
+ }
+ return m_matrixOut;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417BarcodeMetadata.cpp b/xfa/src/fxbarcode/src/BC_PDF417BarcodeMetadata.cpp
new file mode 100644
index 0000000000..a47deaf0fe
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417BarcodeMetadata.cpp
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417BarcodeMetadata.h"
+CBC_BarcodeMetadata::CBC_BarcodeMetadata(FX_INT32 columnCount, FX_INT32 rowCountUpperPart, FX_INT32 rowCountLowerPart, FX_INT32 errorCorrectionLevel)
+{
+ m_columnCount = columnCount;
+ m_rowCountUpperPart = rowCountUpperPart;
+ m_rowCountLowerPart = rowCountLowerPart;
+ m_errorCorrectionLevel = errorCorrectionLevel;
+ m_rowCount = m_rowCountUpperPart + m_rowCountLowerPart;
+}
+CBC_BarcodeMetadata::~CBC_BarcodeMetadata()
+{
+}
+FX_INT32 CBC_BarcodeMetadata::getColumnCount()
+{
+ return m_columnCount;
+}
+FX_INT32 CBC_BarcodeMetadata::getErrorCorrectionLevel()
+{
+ return m_errorCorrectionLevel;
+}
+FX_INT32 CBC_BarcodeMetadata::getRowCount()
+{
+ return m_rowCount;
+}
+FX_INT32 CBC_BarcodeMetadata::getRowCountUpperPart()
+{
+ return m_rowCountUpperPart;
+}
+FX_INT32 CBC_BarcodeMetadata::getRowCountLowerPart()
+{
+ return m_rowCountLowerPart;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417BarcodeRow.cpp b/xfa/src/fxbarcode/src/BC_PDF417BarcodeRow.cpp
new file mode 100644
index 0000000000..506256dd23
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417BarcodeRow.cpp
@@ -0,0 +1,44 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417BarcodeRow.h"
+CBC_BarcodeRow::CBC_BarcodeRow(FX_INT32 width)
+{
+ m_row.SetSize(width);
+ m_currentLocation = 0;
+}
+CBC_BarcodeRow::~CBC_BarcodeRow()
+{
+ m_output.RemoveAll();
+ m_row.RemoveAll();
+}
+void CBC_BarcodeRow::set(FX_INT32 x, FX_BYTE value)
+{
+ m_row.SetAt(x, value);
+}
+void CBC_BarcodeRow::set(FX_INT32 x, FX_BOOL black)
+{
+ m_row.SetAt(x, (FX_BYTE) (black ? 1 : 0));
+}
+void CBC_BarcodeRow::addBar(FX_BOOL black, FX_INT32 width)
+{
+ for (FX_INT32 ii = 0; ii < width; ii++) {
+ set(m_currentLocation++, black);
+ }
+}
+CFX_ByteArray& CBC_BarcodeRow::getRow()
+{
+ return m_row;
+}
+CFX_ByteArray& CBC_BarcodeRow::getScaledRow(FX_INT32 scale)
+{
+ m_output.SetSize(m_row.GetSize() * scale);
+ for (FX_INT32 i = 0; i < m_output.GetSize(); i++) {
+ m_output[i] = (m_row[i / scale]);
+ }
+ return m_output;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417BarcodeValue.cpp b/xfa/src/fxbarcode/src/BC_PDF417BarcodeValue.cpp
new file mode 100644
index 0000000000..725f15af10
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417BarcodeValue.cpp
@@ -0,0 +1,52 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417BarcodeValue.h"
+CBC_BarcodeValue::CBC_BarcodeValue()
+{
+}
+CBC_BarcodeValue::~CBC_BarcodeValue()
+{
+}
+void CBC_BarcodeValue::setValue(FX_INT32 value)
+{
+ FX_INT32 confidence = 0;
+ for (FX_INT32 i = 0; i < m_keys.GetSize(); i++) {
+ if (m_keys.GetAt(i) == value) {
+ confidence = m_values.GetAt(i);
+ m_values.SetAt(i, confidence + 1);
+ return;
+ }
+ }
+ confidence = 1;
+ m_keys.Add(value);
+ m_values.Add(confidence);
+}
+CFX_Int32Array* CBC_BarcodeValue::getValue()
+{
+ FX_INT32 maxConfidence = -1;
+ CFX_Int32Array* result = FX_NEW CFX_Int32Array;
+ for (FX_INT32 i = 0; i < m_keys.GetSize(); i++) {
+ if (m_values.GetAt(i) > maxConfidence) {
+ maxConfidence = m_values.GetAt(i);
+ result->RemoveAll();
+ result->Add(m_keys.GetAt(i));
+ } else if (m_values.GetAt(i) == maxConfidence) {
+ result->Add(m_keys.GetAt(i));
+ }
+ }
+ return result;
+}
+FX_INT32 CBC_BarcodeValue::getConfidence(FX_INT32 value)
+{
+ for (FX_INT32 i = 0; i < m_keys.GetSize(); i++)
+ if (m_keys.GetAt(i) == value) {
+ return m_values.GetAt(i);
+ }
+ return -1;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417BoundingBox.cpp b/xfa/src/fxbarcode/src/BC_PDF417BoundingBox.cpp
new file mode 100644
index 0000000000..3d0840d6d4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417BoundingBox.cpp
@@ -0,0 +1,178 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_PDF417BoundingBox.h"
+CBC_BoundingBox::CBC_BoundingBox(CBC_CommonBitMatrix* image, CBC_ResultPoint* topLeft, CBC_ResultPoint* bottomLeft, CBC_ResultPoint* topRight, CBC_ResultPoint* bottomRight, FX_INT32 &e)
+{
+ if ((topLeft == NULL && topRight == NULL) ||
+ (bottomLeft == NULL && bottomRight == NULL) ||
+ (topLeft != NULL && bottomLeft == NULL) ||
+ (topRight != NULL && bottomRight == NULL)) {
+ e = BCExceptionNotFoundInstance;
+ }
+ init(image, topLeft, bottomLeft, topRight, bottomRight);
+}
+CBC_BoundingBox::CBC_BoundingBox(CBC_BoundingBox* boundingBox)
+{
+ init(boundingBox->m_image, boundingBox->m_topLeft, boundingBox->m_bottomLeft, boundingBox->m_topRight, boundingBox->m_bottomRight);
+}
+CBC_BoundingBox::~CBC_BoundingBox()
+{
+ if (m_topLeft) {
+ delete m_topLeft;
+ }
+ if (m_bottomLeft) {
+ delete m_bottomLeft;
+ }
+ if (m_topRight) {
+ delete m_topRight;
+ }
+ if (m_bottomRight) {
+ delete m_bottomRight;
+ }
+}
+CBC_BoundingBox* CBC_BoundingBox::merge(CBC_BoundingBox* leftBox, CBC_BoundingBox* rightBox, FX_INT32 &e)
+{
+ CBC_BoundingBox* boundingBox = NULL;
+ if (leftBox == NULL) {
+ boundingBox = FX_NEW CBC_BoundingBox(rightBox);
+ return boundingBox;
+ }
+ if (rightBox == NULL) {
+ boundingBox = FX_NEW CBC_BoundingBox(leftBox);
+ return boundingBox;
+ }
+ boundingBox = FX_NEW CBC_BoundingBox(leftBox->m_image, leftBox->m_topLeft, leftBox->m_bottomLeft, rightBox->m_topRight, rightBox->m_bottomRight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return boundingBox;
+}
+CBC_BoundingBox* CBC_BoundingBox::addMissingRows(FX_INT32 missingStartRows, FX_INT32 missingEndRows, FX_BOOL isLeft, FX_INT32 &e)
+{
+ CBC_ResultPoint* newTopLeft = m_topLeft;
+ CBC_ResultPoint* newBottomLeft = m_bottomLeft;
+ CBC_ResultPoint* newTopRight = m_topRight;
+ CBC_ResultPoint* newBottomRight = m_bottomRight;
+ CBC_ResultPoint* newTop = NULL;
+ CBC_ResultPoint* newBottom = NULL;
+ if (missingStartRows > 0) {
+ CBC_ResultPoint* top = isLeft ? m_topLeft : m_topRight;
+ FX_INT32 newMinY = (FX_INT32) top->GetY() - missingStartRows;
+ if (newMinY < 0) {
+ newMinY = 0;
+ }
+ newTop = FX_NEW CBC_ResultPoint((FX_FLOAT)top->GetX(), (FX_FLOAT)newMinY);
+ if (isLeft) {
+ newTopLeft = newTop;
+ } else {
+ newTopRight = newTop;
+ }
+ }
+ if (missingEndRows > 0) {
+ CBC_ResultPoint* bottom = isLeft ? m_bottomLeft : m_bottomRight;
+ FX_INT32 newMaxY = (FX_INT32) bottom->GetY() + missingEndRows;
+ if (newMaxY >= m_image->GetHeight()) {
+ newMaxY = m_image->GetHeight() - 1;
+ }
+ newBottom = FX_NEW CBC_ResultPoint((FX_FLOAT)bottom->GetX(), (FX_FLOAT)newMaxY);
+ if (isLeft) {
+ newBottomLeft = newBottom;
+ } else {
+ newBottomRight = newBottom;
+ }
+ }
+ calculateMinMaxValues();
+ CBC_BoundingBox* boundingBox = FX_NEW CBC_BoundingBox(m_image, newTopLeft, newBottomLeft, newTopRight, newBottomRight, e);
+ delete newTop;
+ delete newBottom;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return boundingBox;
+}
+void CBC_BoundingBox::setTopRight(CBC_ResultPoint topRight)
+{
+ if (m_topRight) {
+ delete m_topRight;
+ }
+ m_topRight = FX_NEW CBC_ResultPoint(topRight.GetX(), topRight.GetY());
+ calculateMinMaxValues();
+}
+void CBC_BoundingBox::setBottomRight(CBC_ResultPoint bottomRight)
+{
+ if (m_bottomRight) {
+ delete m_bottomRight;
+ }
+ m_bottomRight = FX_NEW CBC_ResultPoint(bottomRight.GetX(), bottomRight.GetY());
+ calculateMinMaxValues();
+}
+FX_INT32 CBC_BoundingBox::getMinX()
+{
+ return m_minX;
+}
+FX_INT32 CBC_BoundingBox::getMaxX()
+{
+ return m_maxX;
+}
+FX_INT32 CBC_BoundingBox::getMinY()
+{
+ return m_minY;
+}
+FX_INT32 CBC_BoundingBox::getMaxY()
+{
+ return m_maxY;
+}
+CBC_ResultPoint* CBC_BoundingBox::getTopLeft()
+{
+ return m_topLeft;
+}
+CBC_ResultPoint* CBC_BoundingBox::getTopRight()
+{
+ return m_topRight;
+}
+CBC_ResultPoint* CBC_BoundingBox::getBottomLeft()
+{
+ return m_bottomLeft;
+}
+CBC_ResultPoint* CBC_BoundingBox::getBottomRight()
+{
+ return m_bottomRight;
+}
+void CBC_BoundingBox::init(CBC_CommonBitMatrix* image, CBC_ResultPoint* topLeft, CBC_ResultPoint* bottomLeft, CBC_ResultPoint* topRight, CBC_ResultPoint* bottomRight)
+{
+ m_topLeft = NULL;
+ m_bottomLeft = NULL;
+ m_topRight = NULL;
+ m_bottomRight = NULL;
+ m_image = image;
+ if (topLeft) {
+ m_topLeft = FX_NEW CBC_ResultPoint(topLeft->GetX(), topLeft->GetY());
+ }
+ if (bottomLeft) {
+ m_bottomLeft = FX_NEW CBC_ResultPoint(bottomLeft->GetX(), bottomLeft->GetY());
+ }
+ if (topRight) {
+ m_topRight = FX_NEW CBC_ResultPoint(topRight->GetX(), topRight->GetY());
+ }
+ if (bottomRight) {
+ m_bottomRight = FX_NEW CBC_ResultPoint(bottomRight->GetX(), bottomRight->GetY());
+ }
+ calculateMinMaxValues();
+}
+void CBC_BoundingBox::calculateMinMaxValues()
+{
+ if (m_topLeft == NULL) {
+ m_topLeft = FX_NEW CBC_ResultPoint(0, m_topRight->GetY());
+ m_bottomLeft = FX_NEW CBC_ResultPoint(0, m_bottomRight->GetY());
+ } else if (m_topRight == NULL) {
+ m_topRight = FX_NEW CBC_ResultPoint((FX_FLOAT)m_image->GetWidth() - 1, (FX_FLOAT)m_topLeft->GetY());
+ m_bottomRight = FX_NEW CBC_ResultPoint((FX_FLOAT)m_image->GetWidth() - 1, (FX_FLOAT)m_bottomLeft->GetY());
+ }
+ m_minX = (FX_INT32) (m_topLeft->GetX() < m_bottomLeft->GetX() ? m_topLeft->GetX() : m_bottomLeft->GetX());
+ m_maxX = (FX_INT32) (m_topRight->GetX() > m_bottomRight->GetX() ? m_topRight->GetX() : m_bottomRight->GetX());
+ m_minY = (FX_INT32) (m_topLeft->GetY() < m_topRight->GetY() ? m_topLeft->GetY() : m_topRight->GetY());
+ m_maxY = (FX_INT32) (m_bottomLeft->GetY() > m_bottomRight->GetY() ? m_bottomLeft->GetY() : m_bottomRight->GetY());
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417Codeword.cpp b/xfa/src/fxbarcode/src/BC_PDF417Codeword.cpp
new file mode 100644
index 0000000000..5bd69eb065
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417Codeword.cpp
@@ -0,0 +1,64 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Codeword.h"
+FX_INT32 CBC_Codeword::BARCODE_ROW_UNKNOWN = -1;
+CBC_Codeword::CBC_Codeword(FX_INT32 startX, FX_INT32 endX, FX_INT32 bucket, FX_INT32 cvalue)
+{
+ m_startX = startX;
+ m_endX = endX;
+ m_bucket = bucket;
+ m_value = cvalue;
+ m_rowNumber = BARCODE_ROW_UNKNOWN;
+}
+CBC_Codeword::~CBC_Codeword()
+{
+}
+FX_BOOL CBC_Codeword::hasValidRowNumber()
+{
+ return isValidRowNumber(m_rowNumber);
+}
+FX_BOOL CBC_Codeword::isValidRowNumber(FX_INT32 rowNumber)
+{
+ return m_rowNumber != BARCODE_ROW_UNKNOWN && m_bucket == (m_rowNumber % 3) * 3;
+}
+void CBC_Codeword::setRowNumberAsRowIndicatorColumn()
+{
+ m_rowNumber = (m_value / 30) * 3 + m_bucket / 3;
+}
+FX_INT32 CBC_Codeword::getWidth()
+{
+ return m_endX - m_startX;
+}
+FX_INT32 CBC_Codeword::getStartX()
+{
+ return m_startX;
+}
+FX_INT32 CBC_Codeword::getEndX()
+{
+ return m_endX;
+}
+FX_INT32 CBC_Codeword::getBucket()
+{
+ return m_bucket;
+}
+FX_INT32 CBC_Codeword::getValue()
+{
+ return m_value;
+}
+FX_INT32 CBC_Codeword::getRowNumber()
+{
+ return m_rowNumber;
+}
+void CBC_Codeword::setRowNumber(FX_INT32 rowNumber)
+{
+ m_rowNumber = rowNumber;
+}
+CFX_ByteString CBC_Codeword::toString()
+{
+ return m_rowNumber + (FX_CHAR)'|' + m_value;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417CodewordDecoder.cpp b/xfa/src/fxbarcode/src/BC_PDF417CodewordDecoder.cpp
new file mode 100644
index 0000000000..41a04d0238
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417CodewordDecoder.cpp
@@ -0,0 +1,102 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417CodewordDecoder.h"
+#define SYMBOL_TABLE_Length 2787
+#define Float_MAX_VALUE 2147483647
+FX_FLOAT CBC_PDF417CodewordDecoder::RATIOS_TABLE[2787][8] = {0};
+CBC_PDF417CodewordDecoder::CBC_PDF417CodewordDecoder()
+{
+}
+CBC_PDF417CodewordDecoder::~CBC_PDF417CodewordDecoder()
+{
+}
+void CBC_PDF417CodewordDecoder::Initialize()
+{
+ for (FX_INT32 i = 0; i < SYMBOL_TABLE_Length; i++) {
+ FX_INT32 currentSymbol = CBC_PDF417Common::SYMBOL_TABLE[i];
+ FX_INT32 currentBit = currentSymbol & 0x1;
+ for (FX_INT32 j = 0; j < CBC_PDF417Common::BARS_IN_MODULE; j++) {
+ FX_FLOAT size = 0.0f;
+ while ((currentSymbol & 0x1) == currentBit) {
+ size += 1.0f;
+ currentSymbol >>= 1;
+ }
+ currentBit = currentSymbol & 0x1;
+ RATIOS_TABLE[i][CBC_PDF417Common::BARS_IN_MODULE - j - 1] = size / CBC_PDF417Common::MODULES_IN_CODEWORD;
+ }
+ }
+}
+void CBC_PDF417CodewordDecoder::Finalize()
+{
+}
+FX_INT32 CBC_PDF417CodewordDecoder::getDecodedValue(CFX_Int32Array& moduleBitCount)
+{
+ CFX_Int32Array* array = sampleBitCounts(moduleBitCount);
+ FX_INT32 decodedValue = getDecodedCodewordValue(*array);
+ delete array;
+ if (decodedValue != -1) {
+ return decodedValue;
+ }
+ return getClosestDecodedValue(moduleBitCount);
+}
+CFX_Int32Array* CBC_PDF417CodewordDecoder::sampleBitCounts(CFX_Int32Array& moduleBitCount)
+{
+ FX_FLOAT bitCountSum = (FX_FLOAT)CBC_PDF417Common::getBitCountSum(moduleBitCount);
+ CFX_Int32Array* bitCount = FX_NEW CFX_Int32Array();
+ bitCount->SetSize(CBC_PDF417Common::BARS_IN_MODULE);
+ FX_INT32 bitCountIndex = 0;
+ FX_INT32 sumPreviousBits = 0;
+ for (FX_INT32 i = 0; i < CBC_PDF417Common::MODULES_IN_CODEWORD; i++) {
+ FX_FLOAT sampleIndex = bitCountSum / (2 * CBC_PDF417Common::MODULES_IN_CODEWORD) + (i * bitCountSum) / CBC_PDF417Common::MODULES_IN_CODEWORD;
+ if (sumPreviousBits + moduleBitCount.GetAt(bitCountIndex) <= sampleIndex) {
+ sumPreviousBits += moduleBitCount.GetAt(bitCountIndex);
+ bitCountIndex++;
+ }
+ bitCount->SetAt(bitCountIndex, bitCount->GetAt(bitCountIndex) + 1);
+ }
+ return bitCount;
+}
+FX_INT32 CBC_PDF417CodewordDecoder::getDecodedCodewordValue(CFX_Int32Array& moduleBitCount)
+{
+ FX_INT32 decodedValue = getBitValue(moduleBitCount);
+ return CBC_PDF417Common::getCodeword(decodedValue) == -1 ? -1 : decodedValue;
+}
+FX_INT32 CBC_PDF417CodewordDecoder::getBitValue(CFX_Int32Array& moduleBitCount)
+{
+ FX_INT64 result = 0;
+ for (FX_INT32 i = 0; i < moduleBitCount.GetSize(); i++) {
+ for (FX_INT32 bit = 0; bit < moduleBitCount.GetAt(i); bit++) {
+ result = (result << 1) | (i % 2 == 0 ? 1 : 0);
+ }
+ }
+ return (FX_INT32) result;
+}
+FX_INT32 CBC_PDF417CodewordDecoder::getClosestDecodedValue(CFX_Int32Array& moduleBitCount)
+{
+ FX_INT32 bitCountSum = CBC_PDF417Common::getBitCountSum(moduleBitCount);
+ CFX_FloatArray bitCountRatios;
+ bitCountRatios.SetSize(CBC_PDF417Common::BARS_IN_MODULE);
+ for (FX_INT32 i = 0; i < bitCountRatios.GetSize(); i++) {
+ bitCountRatios[i] = moduleBitCount.GetAt(i) / (FX_FLOAT) bitCountSum;
+ }
+ FX_FLOAT bestMatchError = (FX_FLOAT)Float_MAX_VALUE;
+ FX_INT32 bestMatch = -1;
+ for (FX_INT32 j = 0; j < SYMBOL_TABLE_Length; j++) {
+ FX_FLOAT error = 0.0f;
+ for (FX_INT32 k = 0; k < CBC_PDF417Common::BARS_IN_MODULE; k++) {
+ FX_FLOAT diff = RATIOS_TABLE[j][k] - bitCountRatios[k];
+ error += diff * diff;
+ }
+ if (error < bestMatchError) {
+ bestMatchError = error;
+ bestMatch = CBC_PDF417Common::SYMBOL_TABLE[j];
+ }
+ }
+ return bestMatch;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417Common.cpp b/xfa/src/fxbarcode/src/BC_PDF417Common.cpp
new file mode 100644
index 0000000000..697e07863c
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417Common.cpp
@@ -0,0 +1,434 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Common.h"
+FX_INT32 CBC_PDF417Common::NUMBER_OF_CODEWORDS = 929;
+FX_INT32 CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE = NUMBER_OF_CODEWORDS - 1;
+FX_INT32 CBC_PDF417Common::MIN_ROWS_IN_BARCODE = 3;
+FX_INT32 CBC_PDF417Common::MAX_ROWS_IN_BARCODE = 90;
+FX_INT32 CBC_PDF417Common::MAX_CODEWORDS_IN_ROW = 32;
+FX_INT32 CBC_PDF417Common::MODULES_IN_CODEWORD = 17;
+FX_INT32 CBC_PDF417Common::MODULES_IN_STOP_PATTERN = 18;
+FX_INT32 CBC_PDF417Common::BARS_IN_MODULE = 8;
+CFX_Int32Array* CBC_PDF417Common::EMPTY_INT_ARRAY = NULL;
+FX_INT32 CBC_PDF417Common::SYMBOL_TABLE[] = {
+ 0x1025e, 0x1027a, 0x1029e, 0x102bc, 0x102f2, 0x102f4, 0x1032e, 0x1034e, 0x1035c, 0x10396, 0x103a6, 0x103ac,
+ 0x10422, 0x10428, 0x10436, 0x10442, 0x10444, 0x10448, 0x10450, 0x1045e, 0x10466, 0x1046c, 0x1047a, 0x10482,
+ 0x1049e, 0x104a0, 0x104bc, 0x104c6, 0x104d8, 0x104ee, 0x104f2, 0x104f4, 0x10504, 0x10508, 0x10510, 0x1051e,
+ 0x10520, 0x1053c, 0x10540, 0x10578, 0x10586, 0x1058c, 0x10598, 0x105b0, 0x105be, 0x105ce, 0x105dc, 0x105e2,
+ 0x105e4, 0x105e8, 0x105f6, 0x1062e, 0x1064e, 0x1065c, 0x1068e, 0x1069c, 0x106b8, 0x106de, 0x106fa, 0x10716,
+ 0x10726, 0x1072c, 0x10746, 0x1074c, 0x10758, 0x1076e, 0x10792, 0x10794, 0x107a2, 0x107a4, 0x107a8, 0x107b6,
+ 0x10822, 0x10828, 0x10842, 0x10848, 0x10850, 0x1085e, 0x10866, 0x1086c, 0x1087a, 0x10882, 0x10884, 0x10890,
+ 0x1089e, 0x108a0, 0x108bc, 0x108c6, 0x108cc, 0x108d8, 0x108ee, 0x108f2, 0x108f4, 0x10902, 0x10908, 0x1091e,
+ 0x10920, 0x1093c, 0x10940, 0x10978, 0x10986, 0x10998, 0x109b0, 0x109be, 0x109ce, 0x109dc, 0x109e2, 0x109e4,
+ 0x109e8, 0x109f6, 0x10a08, 0x10a10, 0x10a1e, 0x10a20, 0x10a3c, 0x10a40, 0x10a78, 0x10af0, 0x10b06, 0x10b0c,
+ 0x10b18, 0x10b30, 0x10b3e, 0x10b60, 0x10b7c, 0x10b8e, 0x10b9c, 0x10bb8, 0x10bc2, 0x10bc4, 0x10bc8, 0x10bd0,
+ 0x10bde, 0x10be6, 0x10bec, 0x10c2e, 0x10c4e, 0x10c5c, 0x10c62, 0x10c64, 0x10c68, 0x10c76, 0x10c8e, 0x10c9c,
+ 0x10cb8, 0x10cc2, 0x10cc4, 0x10cc8, 0x10cd0, 0x10cde, 0x10ce6, 0x10cec, 0x10cfa, 0x10d0e, 0x10d1c, 0x10d38,
+ 0x10d70, 0x10d7e, 0x10d82, 0x10d84, 0x10d88, 0x10d90, 0x10d9e, 0x10da0, 0x10dbc, 0x10dc6, 0x10dcc, 0x10dd8,
+ 0x10dee, 0x10df2, 0x10df4, 0x10e16, 0x10e26, 0x10e2c, 0x10e46, 0x10e58, 0x10e6e, 0x10e86, 0x10e8c, 0x10e98,
+ 0x10eb0, 0x10ebe, 0x10ece, 0x10edc, 0x10f0a, 0x10f12, 0x10f14, 0x10f22, 0x10f28, 0x10f36, 0x10f42, 0x10f44,
+ 0x10f48, 0x10f50, 0x10f5e, 0x10f66, 0x10f6c, 0x10fb2, 0x10fb4, 0x11022, 0x11028, 0x11042, 0x11048, 0x11050,
+ 0x1105e, 0x1107a, 0x11082, 0x11084, 0x11090, 0x1109e, 0x110a0, 0x110bc, 0x110c6, 0x110cc, 0x110d8, 0x110ee,
+ 0x110f2, 0x110f4, 0x11102, 0x1111e, 0x11120, 0x1113c, 0x11140, 0x11178, 0x11186, 0x11198, 0x111b0, 0x111be,
+ 0x111ce, 0x111dc, 0x111e2, 0x111e4, 0x111e8, 0x111f6, 0x11208, 0x1121e, 0x11220, 0x11278, 0x112f0, 0x1130c,
+ 0x11330, 0x1133e, 0x11360, 0x1137c, 0x1138e, 0x1139c, 0x113b8, 0x113c2, 0x113c8, 0x113d0, 0x113de, 0x113e6,
+ 0x113ec, 0x11408, 0x11410, 0x1141e, 0x11420, 0x1143c, 0x11440, 0x11478, 0x114f0, 0x115e0, 0x1160c, 0x11618,
+ 0x11630, 0x1163e, 0x11660, 0x1167c, 0x116c0, 0x116f8, 0x1171c, 0x11738, 0x11770, 0x1177e, 0x11782, 0x11784,
+ 0x11788, 0x11790, 0x1179e, 0x117a0, 0x117bc, 0x117c6, 0x117cc, 0x117d8, 0x117ee, 0x1182e, 0x11834, 0x1184e,
+ 0x1185c, 0x11862, 0x11864, 0x11868, 0x11876, 0x1188e, 0x1189c, 0x118b8, 0x118c2, 0x118c8, 0x118d0, 0x118de,
+ 0x118e6, 0x118ec, 0x118fa, 0x1190e, 0x1191c, 0x11938, 0x11970, 0x1197e, 0x11982, 0x11984, 0x11990, 0x1199e,
+ 0x119a0, 0x119bc, 0x119c6, 0x119cc, 0x119d8, 0x119ee, 0x119f2, 0x119f4, 0x11a0e, 0x11a1c, 0x11a38, 0x11a70,
+ 0x11a7e, 0x11ae0, 0x11afc, 0x11b08, 0x11b10, 0x11b1e, 0x11b20, 0x11b3c, 0x11b40, 0x11b78, 0x11b8c, 0x11b98,
+ 0x11bb0, 0x11bbe, 0x11bce, 0x11bdc, 0x11be2, 0x11be4, 0x11be8, 0x11bf6, 0x11c16, 0x11c26, 0x11c2c, 0x11c46,
+ 0x11c4c, 0x11c58, 0x11c6e, 0x11c86, 0x11c98, 0x11cb0, 0x11cbe, 0x11cce, 0x11cdc, 0x11ce2, 0x11ce4, 0x11ce8,
+ 0x11cf6, 0x11d06, 0x11d0c, 0x11d18, 0x11d30, 0x11d3e, 0x11d60, 0x11d7c, 0x11d8e, 0x11d9c, 0x11db8, 0x11dc4,
+ 0x11dc8, 0x11dd0, 0x11dde, 0x11de6, 0x11dec, 0x11dfa, 0x11e0a, 0x11e12, 0x11e14, 0x11e22, 0x11e24, 0x11e28,
+ 0x11e36, 0x11e42, 0x11e44, 0x11e50, 0x11e5e, 0x11e66, 0x11e6c, 0x11e82, 0x11e84, 0x11e88, 0x11e90, 0x11e9e,
+ 0x11ea0, 0x11ebc, 0x11ec6, 0x11ecc, 0x11ed8, 0x11eee, 0x11f1a, 0x11f2e, 0x11f32, 0x11f34, 0x11f4e, 0x11f5c,
+ 0x11f62, 0x11f64, 0x11f68, 0x11f76, 0x12048, 0x1205e, 0x12082, 0x12084, 0x12090, 0x1209e, 0x120a0, 0x120bc,
+ 0x120d8, 0x120f2, 0x120f4, 0x12108, 0x1211e, 0x12120, 0x1213c, 0x12140, 0x12178, 0x12186, 0x12198, 0x121b0,
+ 0x121be, 0x121e2, 0x121e4, 0x121e8, 0x121f6, 0x12204, 0x12210, 0x1221e, 0x12220, 0x12278, 0x122f0, 0x12306,
+ 0x1230c, 0x12330, 0x1233e, 0x12360, 0x1237c, 0x1238e, 0x1239c, 0x123b8, 0x123c2, 0x123c8, 0x123d0, 0x123e6,
+ 0x123ec, 0x1241e, 0x12420, 0x1243c, 0x124f0, 0x125e0, 0x12618, 0x1263e, 0x12660, 0x1267c, 0x126c0, 0x126f8,
+ 0x12738, 0x12770, 0x1277e, 0x12782, 0x12784, 0x12790, 0x1279e, 0x127a0, 0x127bc, 0x127c6, 0x127cc, 0x127d8,
+ 0x127ee, 0x12820, 0x1283c, 0x12840, 0x12878, 0x128f0, 0x129e0, 0x12bc0, 0x12c18, 0x12c30, 0x12c3e, 0x12c60,
+ 0x12c7c, 0x12cc0, 0x12cf8, 0x12df0, 0x12e1c, 0x12e38, 0x12e70, 0x12e7e, 0x12ee0, 0x12efc, 0x12f04, 0x12f08,
+ 0x12f10, 0x12f20, 0x12f3c, 0x12f40, 0x12f78, 0x12f86, 0x12f8c, 0x12f98, 0x12fb0, 0x12fbe, 0x12fce, 0x12fdc,
+ 0x1302e, 0x1304e, 0x1305c, 0x13062, 0x13068, 0x1308e, 0x1309c, 0x130b8, 0x130c2, 0x130c8, 0x130d0, 0x130de,
+ 0x130ec, 0x130fa, 0x1310e, 0x13138, 0x13170, 0x1317e, 0x13182, 0x13184, 0x13190, 0x1319e, 0x131a0, 0x131bc,
+ 0x131c6, 0x131cc, 0x131d8, 0x131f2, 0x131f4, 0x1320e, 0x1321c, 0x13270, 0x1327e, 0x132e0, 0x132fc, 0x13308,
+ 0x1331e, 0x13320, 0x1333c, 0x13340, 0x13378, 0x13386, 0x13398, 0x133b0, 0x133be, 0x133ce, 0x133dc, 0x133e2,
+ 0x133e4, 0x133e8, 0x133f6, 0x1340e, 0x1341c, 0x13438, 0x13470, 0x1347e, 0x134e0, 0x134fc, 0x135c0, 0x135f8,
+ 0x13608, 0x13610, 0x1361e, 0x13620, 0x1363c, 0x13640, 0x13678, 0x136f0, 0x1370c, 0x13718, 0x13730, 0x1373e,
+ 0x13760, 0x1377c, 0x1379c, 0x137b8, 0x137c2, 0x137c4, 0x137c8, 0x137d0, 0x137de, 0x137e6, 0x137ec, 0x13816,
+ 0x13826, 0x1382c, 0x13846, 0x1384c, 0x13858, 0x1386e, 0x13874, 0x13886, 0x13898, 0x138b0, 0x138be, 0x138ce,
+ 0x138dc, 0x138e2, 0x138e4, 0x138e8, 0x13906, 0x1390c, 0x13930, 0x1393e, 0x13960, 0x1397c, 0x1398e, 0x1399c,
+ 0x139b8, 0x139c8, 0x139d0, 0x139de, 0x139e6, 0x139ec, 0x139fa, 0x13a06, 0x13a0c, 0x13a18, 0x13a30, 0x13a3e,
+ 0x13a60, 0x13a7c, 0x13ac0, 0x13af8, 0x13b0e, 0x13b1c, 0x13b38, 0x13b70, 0x13b7e, 0x13b88, 0x13b90, 0x13b9e,
+ 0x13ba0, 0x13bbc, 0x13bcc, 0x13bd8, 0x13bee, 0x13bf2, 0x13bf4, 0x13c12, 0x13c14, 0x13c22, 0x13c24, 0x13c28,
+ 0x13c36, 0x13c42, 0x13c48, 0x13c50, 0x13c5e, 0x13c66, 0x13c6c, 0x13c82, 0x13c84, 0x13c90, 0x13c9e, 0x13ca0,
+ 0x13cbc, 0x13cc6, 0x13ccc, 0x13cd8, 0x13cee, 0x13d02, 0x13d04, 0x13d08, 0x13d10, 0x13d1e, 0x13d20, 0x13d3c,
+ 0x13d40, 0x13d78, 0x13d86, 0x13d8c, 0x13d98, 0x13db0, 0x13dbe, 0x13dce, 0x13ddc, 0x13de4, 0x13de8, 0x13df6,
+ 0x13e1a, 0x13e2e, 0x13e32, 0x13e34, 0x13e4e, 0x13e5c, 0x13e62, 0x13e64, 0x13e68, 0x13e76, 0x13e8e, 0x13e9c,
+ 0x13eb8, 0x13ec2, 0x13ec4, 0x13ec8, 0x13ed0, 0x13ede, 0x13ee6, 0x13eec, 0x13f26, 0x13f2c, 0x13f3a, 0x13f46,
+ 0x13f4c, 0x13f58, 0x13f6e, 0x13f72, 0x13f74, 0x14082, 0x1409e, 0x140a0, 0x140bc, 0x14104, 0x14108, 0x14110,
+ 0x1411e, 0x14120, 0x1413c, 0x14140, 0x14178, 0x1418c, 0x14198, 0x141b0, 0x141be, 0x141e2, 0x141e4, 0x141e8,
+ 0x14208, 0x14210, 0x1421e, 0x14220, 0x1423c, 0x14240, 0x14278, 0x142f0, 0x14306, 0x1430c, 0x14318, 0x14330,
+ 0x1433e, 0x14360, 0x1437c, 0x1438e, 0x143c2, 0x143c4, 0x143c8, 0x143d0, 0x143e6, 0x143ec, 0x14408, 0x14410,
+ 0x1441e, 0x14420, 0x1443c, 0x14440, 0x14478, 0x144f0, 0x145e0, 0x1460c, 0x14618, 0x14630, 0x1463e, 0x14660,
+ 0x1467c, 0x146c0, 0x146f8, 0x1471c, 0x14738, 0x14770, 0x1477e, 0x14782, 0x14784, 0x14788, 0x14790, 0x147a0,
+ 0x147bc, 0x147c6, 0x147cc, 0x147d8, 0x147ee, 0x14810, 0x14820, 0x1483c, 0x14840, 0x14878, 0x148f0, 0x149e0,
+ 0x14bc0, 0x14c30, 0x14c3e, 0x14c60, 0x14c7c, 0x14cc0, 0x14cf8, 0x14df0, 0x14e38, 0x14e70, 0x14e7e, 0x14ee0,
+ 0x14efc, 0x14f04, 0x14f08, 0x14f10, 0x14f1e, 0x14f20, 0x14f3c, 0x14f40, 0x14f78, 0x14f86, 0x14f8c, 0x14f98,
+ 0x14fb0, 0x14fce, 0x14fdc, 0x15020, 0x15040, 0x15078, 0x150f0, 0x151e0, 0x153c0, 0x15860, 0x1587c, 0x158c0,
+ 0x158f8, 0x159f0, 0x15be0, 0x15c70, 0x15c7e, 0x15ce0, 0x15cfc, 0x15dc0, 0x15df8, 0x15e08, 0x15e10, 0x15e20,
+ 0x15e40, 0x15e78, 0x15ef0, 0x15f0c, 0x15f18, 0x15f30, 0x15f60, 0x15f7c, 0x15f8e, 0x15f9c, 0x15fb8, 0x1604e,
+ 0x1605c, 0x1608e, 0x1609c, 0x160b8, 0x160c2, 0x160c4, 0x160c8, 0x160de, 0x1610e, 0x1611c, 0x16138, 0x16170,
+ 0x1617e, 0x16184, 0x16188, 0x16190, 0x1619e, 0x161a0, 0x161bc, 0x161c6, 0x161cc, 0x161d8, 0x161f2, 0x161f4,
+ 0x1620e, 0x1621c, 0x16238, 0x16270, 0x1627e, 0x162e0, 0x162fc, 0x16304, 0x16308, 0x16310, 0x1631e, 0x16320,
+ 0x1633c, 0x16340, 0x16378, 0x16386, 0x1638c, 0x16398, 0x163b0, 0x163be, 0x163ce, 0x163dc, 0x163e2, 0x163e4,
+ 0x163e8, 0x163f6, 0x1640e, 0x1641c, 0x16438, 0x16470, 0x1647e, 0x164e0, 0x164fc, 0x165c0, 0x165f8, 0x16610,
+ 0x1661e, 0x16620, 0x1663c, 0x16640, 0x16678, 0x166f0, 0x16718, 0x16730, 0x1673e, 0x16760, 0x1677c, 0x1678e,
+ 0x1679c, 0x167b8, 0x167c2, 0x167c4, 0x167c8, 0x167d0, 0x167de, 0x167e6, 0x167ec, 0x1681c, 0x16838, 0x16870,
+ 0x168e0, 0x168fc, 0x169c0, 0x169f8, 0x16bf0, 0x16c10, 0x16c1e, 0x16c20, 0x16c3c, 0x16c40, 0x16c78, 0x16cf0,
+ 0x16de0, 0x16e18, 0x16e30, 0x16e3e, 0x16e60, 0x16e7c, 0x16ec0, 0x16ef8, 0x16f1c, 0x16f38, 0x16f70, 0x16f7e,
+ 0x16f84, 0x16f88, 0x16f90, 0x16f9e, 0x16fa0, 0x16fbc, 0x16fc6, 0x16fcc, 0x16fd8, 0x17026, 0x1702c, 0x17046,
+ 0x1704c, 0x17058, 0x1706e, 0x17086, 0x1708c, 0x17098, 0x170b0, 0x170be, 0x170ce, 0x170dc, 0x170e8, 0x17106,
+ 0x1710c, 0x17118, 0x17130, 0x1713e, 0x17160, 0x1717c, 0x1718e, 0x1719c, 0x171b8, 0x171c2, 0x171c4, 0x171c8,
+ 0x171d0, 0x171de, 0x171e6, 0x171ec, 0x171fa, 0x17206, 0x1720c, 0x17218, 0x17230, 0x1723e, 0x17260, 0x1727c,
+ 0x172c0, 0x172f8, 0x1730e, 0x1731c, 0x17338, 0x17370, 0x1737e, 0x17388, 0x17390, 0x1739e, 0x173a0, 0x173bc,
+ 0x173cc, 0x173d8, 0x173ee, 0x173f2, 0x173f4, 0x1740c, 0x17418, 0x17430, 0x1743e, 0x17460, 0x1747c, 0x174c0,
+ 0x174f8, 0x175f0, 0x1760e, 0x1761c, 0x17638, 0x17670, 0x1767e, 0x176e0, 0x176fc, 0x17708, 0x17710, 0x1771e,
+ 0x17720, 0x1773c, 0x17740, 0x17778, 0x17798, 0x177b0, 0x177be, 0x177dc, 0x177e2, 0x177e4, 0x177e8, 0x17822,
+ 0x17824, 0x17828, 0x17836, 0x17842, 0x17844, 0x17848, 0x17850, 0x1785e, 0x17866, 0x1786c, 0x17882, 0x17884,
+ 0x17888, 0x17890, 0x1789e, 0x178a0, 0x178bc, 0x178c6, 0x178cc, 0x178d8, 0x178ee, 0x178f2, 0x178f4, 0x17902,
+ 0x17904, 0x17908, 0x17910, 0x1791e, 0x17920, 0x1793c, 0x17940, 0x17978, 0x17986, 0x1798c, 0x17998, 0x179b0,
+ 0x179be, 0x179ce, 0x179dc, 0x179e2, 0x179e4, 0x179e8, 0x179f6, 0x17a04, 0x17a08, 0x17a10, 0x17a1e, 0x17a20,
+ 0x17a3c, 0x17a40, 0x17a78, 0x17af0, 0x17b06, 0x17b0c, 0x17b18, 0x17b30, 0x17b3e, 0x17b60, 0x17b7c, 0x17b8e,
+ 0x17b9c, 0x17bb8, 0x17bc4, 0x17bc8, 0x17bd0, 0x17bde, 0x17be6, 0x17bec, 0x17c2e, 0x17c32, 0x17c34, 0x17c4e,
+ 0x17c5c, 0x17c62, 0x17c64, 0x17c68, 0x17c76, 0x17c8e, 0x17c9c, 0x17cb8, 0x17cc2, 0x17cc4, 0x17cc8, 0x17cd0,
+ 0x17cde, 0x17ce6, 0x17cec, 0x17d0e, 0x17d1c, 0x17d38, 0x17d70, 0x17d82, 0x17d84, 0x17d88, 0x17d90, 0x17d9e,
+ 0x17da0, 0x17dbc, 0x17dc6, 0x17dcc, 0x17dd8, 0x17dee, 0x17e26, 0x17e2c, 0x17e3a, 0x17e46, 0x17e4c, 0x17e58,
+ 0x17e6e, 0x17e72, 0x17e74, 0x17e86, 0x17e8c, 0x17e98, 0x17eb0, 0x17ece, 0x17edc, 0x17ee2, 0x17ee4, 0x17ee8,
+ 0x17ef6, 0x1813a, 0x18172, 0x18174, 0x18216, 0x18226, 0x1823a, 0x1824c, 0x18258, 0x1826e, 0x18272, 0x18274,
+ 0x18298, 0x182be, 0x182e2, 0x182e4, 0x182e8, 0x182f6, 0x1835e, 0x1837a, 0x183ae, 0x183d6, 0x18416, 0x18426,
+ 0x1842c, 0x1843a, 0x18446, 0x18458, 0x1846e, 0x18472, 0x18474, 0x18486, 0x184b0, 0x184be, 0x184ce, 0x184dc,
+ 0x184e2, 0x184e4, 0x184e8, 0x184f6, 0x18506, 0x1850c, 0x18518, 0x18530, 0x1853e, 0x18560, 0x1857c, 0x1858e,
+ 0x1859c, 0x185b8, 0x185c2, 0x185c4, 0x185c8, 0x185d0, 0x185de, 0x185e6, 0x185ec, 0x185fa, 0x18612, 0x18614,
+ 0x18622, 0x18628, 0x18636, 0x18642, 0x18650, 0x1865e, 0x1867a, 0x18682, 0x18684, 0x18688, 0x18690, 0x1869e,
+ 0x186a0, 0x186bc, 0x186c6, 0x186cc, 0x186d8, 0x186ee, 0x186f2, 0x186f4, 0x1872e, 0x1874e, 0x1875c, 0x18796,
+ 0x187a6, 0x187ac, 0x187d2, 0x187d4, 0x18826, 0x1882c, 0x1883a, 0x18846, 0x1884c, 0x18858, 0x1886e, 0x18872,
+ 0x18874, 0x18886, 0x18898, 0x188b0, 0x188be, 0x188ce, 0x188dc, 0x188e2, 0x188e4, 0x188e8, 0x188f6, 0x1890c,
+ 0x18930, 0x1893e, 0x18960, 0x1897c, 0x1898e, 0x189b8, 0x189c2, 0x189c8, 0x189d0, 0x189de, 0x189e6, 0x189ec,
+ 0x189fa, 0x18a18, 0x18a30, 0x18a3e, 0x18a60, 0x18a7c, 0x18ac0, 0x18af8, 0x18b1c, 0x18b38, 0x18b70, 0x18b7e,
+ 0x18b82, 0x18b84, 0x18b88, 0x18b90, 0x18b9e, 0x18ba0, 0x18bbc, 0x18bc6, 0x18bcc, 0x18bd8, 0x18bee, 0x18bf2,
+ 0x18bf4, 0x18c22, 0x18c24, 0x18c28, 0x18c36, 0x18c42, 0x18c48, 0x18c50, 0x18c5e, 0x18c66, 0x18c7a, 0x18c82,
+ 0x18c84, 0x18c90, 0x18c9e, 0x18ca0, 0x18cbc, 0x18ccc, 0x18cf2, 0x18cf4, 0x18d04, 0x18d08, 0x18d10, 0x18d1e,
+ 0x18d20, 0x18d3c, 0x18d40, 0x18d78, 0x18d86, 0x18d98, 0x18dce, 0x18de2, 0x18de4, 0x18de8, 0x18e2e, 0x18e32,
+ 0x18e34, 0x18e4e, 0x18e5c, 0x18e62, 0x18e64, 0x18e68, 0x18e8e, 0x18e9c, 0x18eb8, 0x18ec2, 0x18ec4, 0x18ec8,
+ 0x18ed0, 0x18efa, 0x18f16, 0x18f26, 0x18f2c, 0x18f46, 0x18f4c, 0x18f58, 0x18f6e, 0x18f8a, 0x18f92, 0x18f94,
+ 0x18fa2, 0x18fa4, 0x18fa8, 0x18fb6, 0x1902c, 0x1903a, 0x19046, 0x1904c, 0x19058, 0x19072, 0x19074, 0x19086,
+ 0x19098, 0x190b0, 0x190be, 0x190ce, 0x190dc, 0x190e2, 0x190e8, 0x190f6, 0x19106, 0x1910c, 0x19130, 0x1913e,
+ 0x19160, 0x1917c, 0x1918e, 0x1919c, 0x191b8, 0x191c2, 0x191c8, 0x191d0, 0x191de, 0x191e6, 0x191ec, 0x191fa,
+ 0x19218, 0x1923e, 0x19260, 0x1927c, 0x192c0, 0x192f8, 0x19338, 0x19370, 0x1937e, 0x19382, 0x19384, 0x19390,
+ 0x1939e, 0x193a0, 0x193bc, 0x193c6, 0x193cc, 0x193d8, 0x193ee, 0x193f2, 0x193f4, 0x19430, 0x1943e, 0x19460,
+ 0x1947c, 0x194c0, 0x194f8, 0x195f0, 0x19638, 0x19670, 0x1967e, 0x196e0, 0x196fc, 0x19702, 0x19704, 0x19708,
+ 0x19710, 0x19720, 0x1973c, 0x19740, 0x19778, 0x19786, 0x1978c, 0x19798, 0x197b0, 0x197be, 0x197ce, 0x197dc,
+ 0x197e2, 0x197e4, 0x197e8, 0x19822, 0x19824, 0x19842, 0x19848, 0x19850, 0x1985e, 0x19866, 0x1987a, 0x19882,
+ 0x19884, 0x19890, 0x1989e, 0x198a0, 0x198bc, 0x198cc, 0x198f2, 0x198f4, 0x19902, 0x19908, 0x1991e, 0x19920,
+ 0x1993c, 0x19940, 0x19978, 0x19986, 0x19998, 0x199ce, 0x199e2, 0x199e4, 0x199e8, 0x19a08, 0x19a10, 0x19a1e,
+ 0x19a20, 0x19a3c, 0x19a40, 0x19a78, 0x19af0, 0x19b18, 0x19b3e, 0x19b60, 0x19b9c, 0x19bc2, 0x19bc4, 0x19bc8,
+ 0x19bd0, 0x19be6, 0x19c2e, 0x19c34, 0x19c4e, 0x19c5c, 0x19c62, 0x19c64, 0x19c68, 0x19c8e, 0x19c9c, 0x19cb8,
+ 0x19cc2, 0x19cc8, 0x19cd0, 0x19ce6, 0x19cfa, 0x19d0e, 0x19d1c, 0x19d38, 0x19d70, 0x19d7e, 0x19d82, 0x19d84,
+ 0x19d88, 0x19d90, 0x19da0, 0x19dcc, 0x19df2, 0x19df4, 0x19e16, 0x19e26, 0x19e2c, 0x19e46, 0x19e4c, 0x19e58,
+ 0x19e74, 0x19e86, 0x19e8c, 0x19e98, 0x19eb0, 0x19ebe, 0x19ece, 0x19ee2, 0x19ee4, 0x19ee8, 0x19f0a, 0x19f12,
+ 0x19f14, 0x19f22, 0x19f24, 0x19f28, 0x19f42, 0x19f44, 0x19f48, 0x19f50, 0x19f5e, 0x19f6c, 0x19f9a, 0x19fae,
+ 0x19fb2, 0x19fb4, 0x1a046, 0x1a04c, 0x1a072, 0x1a074, 0x1a086, 0x1a08c, 0x1a098, 0x1a0b0, 0x1a0be, 0x1a0e2,
+ 0x1a0e4, 0x1a0e8, 0x1a0f6, 0x1a106, 0x1a10c, 0x1a118, 0x1a130, 0x1a13e, 0x1a160, 0x1a17c, 0x1a18e, 0x1a19c,
+ 0x1a1b8, 0x1a1c2, 0x1a1c4, 0x1a1c8, 0x1a1d0, 0x1a1de, 0x1a1e6, 0x1a1ec, 0x1a218, 0x1a230, 0x1a23e, 0x1a260,
+ 0x1a27c, 0x1a2c0, 0x1a2f8, 0x1a31c, 0x1a338, 0x1a370, 0x1a37e, 0x1a382, 0x1a384, 0x1a388, 0x1a390, 0x1a39e,
+ 0x1a3a0, 0x1a3bc, 0x1a3c6, 0x1a3cc, 0x1a3d8, 0x1a3ee, 0x1a3f2, 0x1a3f4, 0x1a418, 0x1a430, 0x1a43e, 0x1a460,
+ 0x1a47c, 0x1a4c0, 0x1a4f8, 0x1a5f0, 0x1a61c, 0x1a638, 0x1a670, 0x1a67e, 0x1a6e0, 0x1a6fc, 0x1a702, 0x1a704,
+ 0x1a708, 0x1a710, 0x1a71e, 0x1a720, 0x1a73c, 0x1a740, 0x1a778, 0x1a786, 0x1a78c, 0x1a798, 0x1a7b0, 0x1a7be,
+ 0x1a7ce, 0x1a7dc, 0x1a7e2, 0x1a7e4, 0x1a7e8, 0x1a830, 0x1a860, 0x1a87c, 0x1a8c0, 0x1a8f8, 0x1a9f0, 0x1abe0,
+ 0x1ac70, 0x1ac7e, 0x1ace0, 0x1acfc, 0x1adc0, 0x1adf8, 0x1ae04, 0x1ae08, 0x1ae10, 0x1ae20, 0x1ae3c, 0x1ae40,
+ 0x1ae78, 0x1aef0, 0x1af06, 0x1af0c, 0x1af18, 0x1af30, 0x1af3e, 0x1af60, 0x1af7c, 0x1af8e, 0x1af9c, 0x1afb8,
+ 0x1afc4, 0x1afc8, 0x1afd0, 0x1afde, 0x1b042, 0x1b05e, 0x1b07a, 0x1b082, 0x1b084, 0x1b088, 0x1b090, 0x1b09e,
+ 0x1b0a0, 0x1b0bc, 0x1b0cc, 0x1b0f2, 0x1b0f4, 0x1b102, 0x1b104, 0x1b108, 0x1b110, 0x1b11e, 0x1b120, 0x1b13c,
+ 0x1b140, 0x1b178, 0x1b186, 0x1b198, 0x1b1ce, 0x1b1e2, 0x1b1e4, 0x1b1e8, 0x1b204, 0x1b208, 0x1b210, 0x1b21e,
+ 0x1b220, 0x1b23c, 0x1b240, 0x1b278, 0x1b2f0, 0x1b30c, 0x1b33e, 0x1b360, 0x1b39c, 0x1b3c2, 0x1b3c4, 0x1b3c8,
+ 0x1b3d0, 0x1b3e6, 0x1b410, 0x1b41e, 0x1b420, 0x1b43c, 0x1b440, 0x1b478, 0x1b4f0, 0x1b5e0, 0x1b618, 0x1b660,
+ 0x1b67c, 0x1b6c0, 0x1b738, 0x1b782, 0x1b784, 0x1b788, 0x1b790, 0x1b79e, 0x1b7a0, 0x1b7cc, 0x1b82e, 0x1b84e,
+ 0x1b85c, 0x1b88e, 0x1b89c, 0x1b8b8, 0x1b8c2, 0x1b8c4, 0x1b8c8, 0x1b8d0, 0x1b8e6, 0x1b8fa, 0x1b90e, 0x1b91c,
+ 0x1b938, 0x1b970, 0x1b97e, 0x1b982, 0x1b984, 0x1b988, 0x1b990, 0x1b99e, 0x1b9a0, 0x1b9cc, 0x1b9f2, 0x1b9f4,
+ 0x1ba0e, 0x1ba1c, 0x1ba38, 0x1ba70, 0x1ba7e, 0x1bae0, 0x1bafc, 0x1bb08, 0x1bb10, 0x1bb20, 0x1bb3c, 0x1bb40,
+ 0x1bb98, 0x1bbce, 0x1bbe2, 0x1bbe4, 0x1bbe8, 0x1bc16, 0x1bc26, 0x1bc2c, 0x1bc46, 0x1bc4c, 0x1bc58, 0x1bc72,
+ 0x1bc74, 0x1bc86, 0x1bc8c, 0x1bc98, 0x1bcb0, 0x1bcbe, 0x1bcce, 0x1bce2, 0x1bce4, 0x1bce8, 0x1bd06, 0x1bd0c,
+ 0x1bd18, 0x1bd30, 0x1bd3e, 0x1bd60, 0x1bd7c, 0x1bd9c, 0x1bdc2, 0x1bdc4, 0x1bdc8, 0x1bdd0, 0x1bde6, 0x1bdfa,
+ 0x1be12, 0x1be14, 0x1be22, 0x1be24, 0x1be28, 0x1be42, 0x1be44, 0x1be48, 0x1be50, 0x1be5e, 0x1be66, 0x1be82,
+ 0x1be84, 0x1be88, 0x1be90, 0x1be9e, 0x1bea0, 0x1bebc, 0x1becc, 0x1bef4, 0x1bf1a, 0x1bf2e, 0x1bf32, 0x1bf34,
+ 0x1bf4e, 0x1bf5c, 0x1bf62, 0x1bf64, 0x1bf68, 0x1c09a, 0x1c0b2, 0x1c0b4, 0x1c11a, 0x1c132, 0x1c134, 0x1c162,
+ 0x1c164, 0x1c168, 0x1c176, 0x1c1ba, 0x1c21a, 0x1c232, 0x1c234, 0x1c24e, 0x1c25c, 0x1c262, 0x1c264, 0x1c268,
+ 0x1c276, 0x1c28e, 0x1c2c2, 0x1c2c4, 0x1c2c8, 0x1c2d0, 0x1c2de, 0x1c2e6, 0x1c2ec, 0x1c2fa, 0x1c316, 0x1c326,
+ 0x1c33a, 0x1c346, 0x1c34c, 0x1c372, 0x1c374, 0x1c41a, 0x1c42e, 0x1c432, 0x1c434, 0x1c44e, 0x1c45c, 0x1c462,
+ 0x1c464, 0x1c468, 0x1c476, 0x1c48e, 0x1c49c, 0x1c4b8, 0x1c4c2, 0x1c4c8, 0x1c4d0, 0x1c4de, 0x1c4e6, 0x1c4ec,
+ 0x1c4fa, 0x1c51c, 0x1c538, 0x1c570, 0x1c57e, 0x1c582, 0x1c584, 0x1c588, 0x1c590, 0x1c59e, 0x1c5a0, 0x1c5bc,
+ 0x1c5c6, 0x1c5cc, 0x1c5d8, 0x1c5ee, 0x1c5f2, 0x1c5f4, 0x1c616, 0x1c626, 0x1c62c, 0x1c63a, 0x1c646, 0x1c64c,
+ 0x1c658, 0x1c66e, 0x1c672, 0x1c674, 0x1c686, 0x1c68c, 0x1c698, 0x1c6b0, 0x1c6be, 0x1c6ce, 0x1c6dc, 0x1c6e2,
+ 0x1c6e4, 0x1c6e8, 0x1c712, 0x1c714, 0x1c722, 0x1c728, 0x1c736, 0x1c742, 0x1c744, 0x1c748, 0x1c750, 0x1c75e,
+ 0x1c766, 0x1c76c, 0x1c77a, 0x1c7ae, 0x1c7d6, 0x1c7ea, 0x1c81a, 0x1c82e, 0x1c832, 0x1c834, 0x1c84e, 0x1c85c,
+ 0x1c862, 0x1c864, 0x1c868, 0x1c876, 0x1c88e, 0x1c89c, 0x1c8b8, 0x1c8c2, 0x1c8c8, 0x1c8d0, 0x1c8de, 0x1c8e6,
+ 0x1c8ec, 0x1c8fa, 0x1c90e, 0x1c938, 0x1c970, 0x1c97e, 0x1c982, 0x1c984, 0x1c990, 0x1c99e, 0x1c9a0, 0x1c9bc,
+ 0x1c9c6, 0x1c9cc, 0x1c9d8, 0x1c9ee, 0x1c9f2, 0x1c9f4, 0x1ca38, 0x1ca70, 0x1ca7e, 0x1cae0, 0x1cafc, 0x1cb02,
+ 0x1cb04, 0x1cb08, 0x1cb10, 0x1cb20, 0x1cb3c, 0x1cb40, 0x1cb78, 0x1cb86, 0x1cb8c, 0x1cb98, 0x1cbb0, 0x1cbbe,
+ 0x1cbce, 0x1cbdc, 0x1cbe2, 0x1cbe4, 0x1cbe8, 0x1cbf6, 0x1cc16, 0x1cc26, 0x1cc2c, 0x1cc3a, 0x1cc46, 0x1cc58,
+ 0x1cc72, 0x1cc74, 0x1cc86, 0x1ccb0, 0x1ccbe, 0x1ccce, 0x1cce2, 0x1cce4, 0x1cce8, 0x1cd06, 0x1cd0c, 0x1cd18,
+ 0x1cd30, 0x1cd3e, 0x1cd60, 0x1cd7c, 0x1cd9c, 0x1cdc2, 0x1cdc4, 0x1cdc8, 0x1cdd0, 0x1cdde, 0x1cde6, 0x1cdfa,
+ 0x1ce22, 0x1ce28, 0x1ce42, 0x1ce50, 0x1ce5e, 0x1ce66, 0x1ce7a, 0x1ce82, 0x1ce84, 0x1ce88, 0x1ce90, 0x1ce9e,
+ 0x1cea0, 0x1cebc, 0x1cecc, 0x1cef2, 0x1cef4, 0x1cf2e, 0x1cf32, 0x1cf34, 0x1cf4e, 0x1cf5c, 0x1cf62, 0x1cf64,
+ 0x1cf68, 0x1cf96, 0x1cfa6, 0x1cfac, 0x1cfca, 0x1cfd2, 0x1cfd4, 0x1d02e, 0x1d032, 0x1d034, 0x1d04e, 0x1d05c,
+ 0x1d062, 0x1d064, 0x1d068, 0x1d076, 0x1d08e, 0x1d09c, 0x1d0b8, 0x1d0c2, 0x1d0c4, 0x1d0c8, 0x1d0d0, 0x1d0de,
+ 0x1d0e6, 0x1d0ec, 0x1d0fa, 0x1d11c, 0x1d138, 0x1d170, 0x1d17e, 0x1d182, 0x1d184, 0x1d188, 0x1d190, 0x1d19e,
+ 0x1d1a0, 0x1d1bc, 0x1d1c6, 0x1d1cc, 0x1d1d8, 0x1d1ee, 0x1d1f2, 0x1d1f4, 0x1d21c, 0x1d238, 0x1d270, 0x1d27e,
+ 0x1d2e0, 0x1d2fc, 0x1d302, 0x1d304, 0x1d308, 0x1d310, 0x1d31e, 0x1d320, 0x1d33c, 0x1d340, 0x1d378, 0x1d386,
+ 0x1d38c, 0x1d398, 0x1d3b0, 0x1d3be, 0x1d3ce, 0x1d3dc, 0x1d3e2, 0x1d3e4, 0x1d3e8, 0x1d3f6, 0x1d470, 0x1d47e,
+ 0x1d4e0, 0x1d4fc, 0x1d5c0, 0x1d5f8, 0x1d604, 0x1d608, 0x1d610, 0x1d620, 0x1d640, 0x1d678, 0x1d6f0, 0x1d706,
+ 0x1d70c, 0x1d718, 0x1d730, 0x1d73e, 0x1d760, 0x1d77c, 0x1d78e, 0x1d79c, 0x1d7b8, 0x1d7c2, 0x1d7c4, 0x1d7c8,
+ 0x1d7d0, 0x1d7de, 0x1d7e6, 0x1d7ec, 0x1d826, 0x1d82c, 0x1d83a, 0x1d846, 0x1d84c, 0x1d858, 0x1d872, 0x1d874,
+ 0x1d886, 0x1d88c, 0x1d898, 0x1d8b0, 0x1d8be, 0x1d8ce, 0x1d8e2, 0x1d8e4, 0x1d8e8, 0x1d8f6, 0x1d90c, 0x1d918,
+ 0x1d930, 0x1d93e, 0x1d960, 0x1d97c, 0x1d99c, 0x1d9c2, 0x1d9c4, 0x1d9c8, 0x1d9d0, 0x1d9e6, 0x1d9fa, 0x1da0c,
+ 0x1da18, 0x1da30, 0x1da3e, 0x1da60, 0x1da7c, 0x1dac0, 0x1daf8, 0x1db38, 0x1db82, 0x1db84, 0x1db88, 0x1db90,
+ 0x1db9e, 0x1dba0, 0x1dbcc, 0x1dbf2, 0x1dbf4, 0x1dc22, 0x1dc42, 0x1dc44, 0x1dc48, 0x1dc50, 0x1dc5e, 0x1dc66,
+ 0x1dc7a, 0x1dc82, 0x1dc84, 0x1dc88, 0x1dc90, 0x1dc9e, 0x1dca0, 0x1dcbc, 0x1dccc, 0x1dcf2, 0x1dcf4, 0x1dd04,
+ 0x1dd08, 0x1dd10, 0x1dd1e, 0x1dd20, 0x1dd3c, 0x1dd40, 0x1dd78, 0x1dd86, 0x1dd98, 0x1ddce, 0x1dde2, 0x1dde4,
+ 0x1dde8, 0x1de2e, 0x1de32, 0x1de34, 0x1de4e, 0x1de5c, 0x1de62, 0x1de64, 0x1de68, 0x1de8e, 0x1de9c, 0x1deb8,
+ 0x1dec2, 0x1dec4, 0x1dec8, 0x1ded0, 0x1dee6, 0x1defa, 0x1df16, 0x1df26, 0x1df2c, 0x1df46, 0x1df4c, 0x1df58,
+ 0x1df72, 0x1df74, 0x1df8a, 0x1df92, 0x1df94, 0x1dfa2, 0x1dfa4, 0x1dfa8, 0x1e08a, 0x1e092, 0x1e094, 0x1e0a2,
+ 0x1e0a4, 0x1e0a8, 0x1e0b6, 0x1e0da, 0x1e10a, 0x1e112, 0x1e114, 0x1e122, 0x1e124, 0x1e128, 0x1e136, 0x1e142,
+ 0x1e144, 0x1e148, 0x1e150, 0x1e166, 0x1e16c, 0x1e17a, 0x1e19a, 0x1e1b2, 0x1e1b4, 0x1e20a, 0x1e212, 0x1e214,
+ 0x1e222, 0x1e224, 0x1e228, 0x1e236, 0x1e242, 0x1e248, 0x1e250, 0x1e25e, 0x1e266, 0x1e26c, 0x1e27a, 0x1e282,
+ 0x1e284, 0x1e288, 0x1e290, 0x1e2a0, 0x1e2bc, 0x1e2c6, 0x1e2cc, 0x1e2d8, 0x1e2ee, 0x1e2f2, 0x1e2f4, 0x1e31a,
+ 0x1e332, 0x1e334, 0x1e35c, 0x1e362, 0x1e364, 0x1e368, 0x1e3ba, 0x1e40a, 0x1e412, 0x1e414, 0x1e422, 0x1e428,
+ 0x1e436, 0x1e442, 0x1e448, 0x1e450, 0x1e45e, 0x1e466, 0x1e46c, 0x1e47a, 0x1e482, 0x1e484, 0x1e490, 0x1e49e,
+ 0x1e4a0, 0x1e4bc, 0x1e4c6, 0x1e4cc, 0x1e4d8, 0x1e4ee, 0x1e4f2, 0x1e4f4, 0x1e502, 0x1e504, 0x1e508, 0x1e510,
+ 0x1e51e, 0x1e520, 0x1e53c, 0x1e540, 0x1e578, 0x1e586, 0x1e58c, 0x1e598, 0x1e5b0, 0x1e5be, 0x1e5ce, 0x1e5dc,
+ 0x1e5e2, 0x1e5e4, 0x1e5e8, 0x1e5f6, 0x1e61a, 0x1e62e, 0x1e632, 0x1e634, 0x1e64e, 0x1e65c, 0x1e662, 0x1e668,
+ 0x1e68e, 0x1e69c, 0x1e6b8, 0x1e6c2, 0x1e6c4, 0x1e6c8, 0x1e6d0, 0x1e6e6, 0x1e6fa, 0x1e716, 0x1e726, 0x1e72c,
+ 0x1e73a, 0x1e746, 0x1e74c, 0x1e758, 0x1e772, 0x1e774, 0x1e792, 0x1e794, 0x1e7a2, 0x1e7a4, 0x1e7a8, 0x1e7b6,
+ 0x1e812, 0x1e814, 0x1e822, 0x1e824, 0x1e828, 0x1e836, 0x1e842, 0x1e844, 0x1e848, 0x1e850, 0x1e85e, 0x1e866,
+ 0x1e86c, 0x1e87a, 0x1e882, 0x1e884, 0x1e888, 0x1e890, 0x1e89e, 0x1e8a0, 0x1e8bc, 0x1e8c6, 0x1e8cc, 0x1e8d8,
+ 0x1e8ee, 0x1e8f2, 0x1e8f4, 0x1e902, 0x1e904, 0x1e908, 0x1e910, 0x1e920, 0x1e93c, 0x1e940, 0x1e978, 0x1e986,
+ 0x1e98c, 0x1e998, 0x1e9b0, 0x1e9be, 0x1e9ce, 0x1e9dc, 0x1e9e2, 0x1e9e4, 0x1e9e8, 0x1e9f6, 0x1ea04, 0x1ea08,
+ 0x1ea10, 0x1ea20, 0x1ea40, 0x1ea78, 0x1eaf0, 0x1eb06, 0x1eb0c, 0x1eb18, 0x1eb30, 0x1eb3e, 0x1eb60, 0x1eb7c,
+ 0x1eb8e, 0x1eb9c, 0x1ebb8, 0x1ebc2, 0x1ebc4, 0x1ebc8, 0x1ebd0, 0x1ebde, 0x1ebe6, 0x1ebec, 0x1ec1a, 0x1ec2e,
+ 0x1ec32, 0x1ec34, 0x1ec4e, 0x1ec5c, 0x1ec62, 0x1ec64, 0x1ec68, 0x1ec8e, 0x1ec9c, 0x1ecb8, 0x1ecc2, 0x1ecc4,
+ 0x1ecc8, 0x1ecd0, 0x1ece6, 0x1ecfa, 0x1ed0e, 0x1ed1c, 0x1ed38, 0x1ed70, 0x1ed7e, 0x1ed82, 0x1ed84, 0x1ed88,
+ 0x1ed90, 0x1ed9e, 0x1eda0, 0x1edcc, 0x1edf2, 0x1edf4, 0x1ee16, 0x1ee26, 0x1ee2c, 0x1ee3a, 0x1ee46, 0x1ee4c,
+ 0x1ee58, 0x1ee6e, 0x1ee72, 0x1ee74, 0x1ee86, 0x1ee8c, 0x1ee98, 0x1eeb0, 0x1eebe, 0x1eece, 0x1eedc, 0x1eee2,
+ 0x1eee4, 0x1eee8, 0x1ef12, 0x1ef22, 0x1ef24, 0x1ef28, 0x1ef36, 0x1ef42, 0x1ef44, 0x1ef48, 0x1ef50, 0x1ef5e,
+ 0x1ef66, 0x1ef6c, 0x1ef7a, 0x1efae, 0x1efb2, 0x1efb4, 0x1efd6, 0x1f096, 0x1f0a6, 0x1f0ac, 0x1f0ba, 0x1f0ca,
+ 0x1f0d2, 0x1f0d4, 0x1f116, 0x1f126, 0x1f12c, 0x1f13a, 0x1f146, 0x1f14c, 0x1f158, 0x1f16e, 0x1f172, 0x1f174,
+ 0x1f18a, 0x1f192, 0x1f194, 0x1f1a2, 0x1f1a4, 0x1f1a8, 0x1f1da, 0x1f216, 0x1f226, 0x1f22c, 0x1f23a, 0x1f246,
+ 0x1f258, 0x1f26e, 0x1f272, 0x1f274, 0x1f286, 0x1f28c, 0x1f298, 0x1f2b0, 0x1f2be, 0x1f2ce, 0x1f2dc, 0x1f2e2,
+ 0x1f2e4, 0x1f2e8, 0x1f2f6, 0x1f30a, 0x1f312, 0x1f314, 0x1f322, 0x1f328, 0x1f342, 0x1f344, 0x1f348, 0x1f350,
+ 0x1f35e, 0x1f366, 0x1f37a, 0x1f39a, 0x1f3ae, 0x1f3b2, 0x1f3b4, 0x1f416, 0x1f426, 0x1f42c, 0x1f43a, 0x1f446,
+ 0x1f44c, 0x1f458, 0x1f46e, 0x1f472, 0x1f474, 0x1f486, 0x1f48c, 0x1f498, 0x1f4b0, 0x1f4be, 0x1f4ce, 0x1f4dc,
+ 0x1f4e2, 0x1f4e4, 0x1f4e8, 0x1f4f6, 0x1f506, 0x1f50c, 0x1f518, 0x1f530, 0x1f53e, 0x1f560, 0x1f57c, 0x1f58e,
+ 0x1f59c, 0x1f5b8, 0x1f5c2, 0x1f5c4, 0x1f5c8, 0x1f5d0, 0x1f5de, 0x1f5e6, 0x1f5ec, 0x1f5fa, 0x1f60a, 0x1f612,
+ 0x1f614, 0x1f622, 0x1f624, 0x1f628, 0x1f636, 0x1f642, 0x1f644, 0x1f648, 0x1f650, 0x1f65e, 0x1f666, 0x1f67a,
+ 0x1f682, 0x1f684, 0x1f688, 0x1f690, 0x1f69e, 0x1f6a0, 0x1f6bc, 0x1f6cc, 0x1f6f2, 0x1f6f4, 0x1f71a, 0x1f72e,
+ 0x1f732, 0x1f734, 0x1f74e, 0x1f75c, 0x1f762, 0x1f764, 0x1f768, 0x1f776, 0x1f796, 0x1f7a6, 0x1f7ac, 0x1f7ba,
+ 0x1f7d2, 0x1f7d4, 0x1f89a, 0x1f8ae, 0x1f8b2, 0x1f8b4, 0x1f8d6, 0x1f8ea, 0x1f91a, 0x1f92e, 0x1f932, 0x1f934,
+ 0x1f94e, 0x1f95c, 0x1f962, 0x1f964, 0x1f968, 0x1f976, 0x1f996, 0x1f9a6, 0x1f9ac, 0x1f9ba, 0x1f9ca, 0x1f9d2,
+ 0x1f9d4, 0x1fa1a, 0x1fa2e, 0x1fa32, 0x1fa34, 0x1fa4e, 0x1fa5c, 0x1fa62, 0x1fa64, 0x1fa68, 0x1fa76, 0x1fa8e,
+ 0x1fa9c, 0x1fab8, 0x1fac2, 0x1fac4, 0x1fac8, 0x1fad0, 0x1fade, 0x1fae6, 0x1faec, 0x1fb16, 0x1fb26, 0x1fb2c,
+ 0x1fb3a, 0x1fb46, 0x1fb4c, 0x1fb58, 0x1fb6e, 0x1fb72, 0x1fb74, 0x1fb8a, 0x1fb92, 0x1fb94, 0x1fba2, 0x1fba4,
+ 0x1fba8, 0x1fbb6, 0x1fbda
+};
+FX_INT32 CBC_PDF417Common::CODEWORD_TABLE[] = {
+ 2627, 1819, 2622, 2621, 1813, 1812, 2729, 2724, 2723, 2779, 2774, 2773, 902, 896, 908, 868, 865, 861, 859, 2511,
+ 873, 871, 1780, 835, 2493, 825, 2491, 842, 837, 844, 1764, 1762, 811, 810, 809, 2483, 807, 2482, 806, 2480, 815,
+ 814, 813, 812, 2484, 817, 816, 1745, 1744, 1742, 1746, 2655, 2637, 2635, 2626, 2625, 2623, 2628, 1820, 2752,
+ 2739, 2737, 2728, 2727, 2725, 2730, 2785, 2783, 2778, 2777, 2775, 2780, 787, 781, 747, 739, 736, 2413, 754, 752,
+ 1719, 692, 689, 681, 2371, 678, 2369, 700, 697, 694, 703, 1688, 1686, 642, 638, 2343, 631, 2341, 627, 2338, 651,
+ 646, 643, 2345, 654, 652, 1652, 1650, 1647, 1654, 601, 599, 2322, 596, 2321, 594, 2319, 2317, 611, 610, 608, 606,
+ 2324, 603, 2323, 615, 614, 612, 1617, 1616, 1614, 1612, 616, 1619, 1618, 2575, 2538, 2536, 905, 901, 898, 909,
+ 2509, 2507, 2504, 870, 867, 864, 860, 2512, 875, 872, 1781, 2490, 2489, 2487, 2485, 1748, 836, 834, 832, 830,
+ 2494, 827, 2492, 843, 841, 839, 845, 1765, 1763, 2701, 2676, 2674, 2653, 2648, 2656, 2634, 2633, 2631, 2629,
+ 1821, 2638, 2636, 2770, 2763, 2761, 2750, 2745, 2753, 2736, 2735, 2733, 2731, 1848, 2740, 2738, 2786, 2784, 591,
+ 588, 576, 569, 566, 2296, 1590, 537, 534, 526, 2276, 522, 2274, 545, 542, 539, 548, 1572, 1570, 481, 2245, 466,
+ 2242, 462, 2239, 492, 485, 482, 2249, 496, 494, 1534, 1531, 1528, 1538, 413, 2196, 406, 2191, 2188, 425, 419,
+ 2202, 415, 2199, 432, 430, 427, 1472, 1467, 1464, 433, 1476, 1474, 368, 367, 2160, 365, 2159, 362, 2157, 2155,
+ 2152, 378, 377, 375, 2166, 372, 2165, 369, 2162, 383, 381, 379, 2168, 1419, 1418, 1416, 1414, 385, 1411, 384,
+ 1423, 1422, 1420, 1424, 2461, 802, 2441, 2439, 790, 786, 783, 794, 2409, 2406, 2403, 750, 742, 738, 2414, 756,
+ 753, 1720, 2367, 2365, 2362, 2359, 1663, 693, 691, 684, 2373, 680, 2370, 702, 699, 696, 704, 1690, 1687, 2337,
+ 2336, 2334, 2332, 1624, 2329, 1622, 640, 637, 2344, 634, 2342, 630, 2340, 650, 648, 645, 2346, 655, 653, 1653,
+ 1651, 1649, 1655, 2612, 2597, 2595, 2571, 2568, 2565, 2576, 2534, 2529, 2526, 1787, 2540, 2537, 907, 904, 900,
+ 910, 2503, 2502, 2500, 2498, 1768, 2495, 1767, 2510, 2508, 2506, 869, 866, 863, 2513, 876, 874, 1782, 2720, 2713,
+ 2711, 2697, 2694, 2691, 2702, 2672, 2670, 2664, 1828, 2678, 2675, 2647, 2646, 2644, 2642, 1823, 2639, 1822, 2654,
+ 2652, 2650, 2657, 2771, 1855, 2765, 2762, 1850, 1849, 2751, 2749, 2747, 2754, 353, 2148, 344, 342, 336, 2142,
+ 332, 2140, 345, 1375, 1373, 306, 2130, 299, 2128, 295, 2125, 319, 314, 311, 2132, 1354, 1352, 1349, 1356, 262,
+ 257, 2101, 253, 2096, 2093, 274, 273, 267, 2107, 263, 2104, 280, 278, 275, 1316, 1311, 1308, 1320, 1318, 2052,
+ 202, 2050, 2044, 2040, 219, 2063, 212, 2060, 208, 2055, 224, 221, 2066, 1260, 1258, 1252, 231, 1248, 229, 1266,
+ 1264, 1261, 1268, 155, 1998, 153, 1996, 1994, 1991, 1988, 165, 164, 2007, 162, 2006, 159, 2003, 2000, 172, 171,
+ 169, 2012, 166, 2010, 1186, 1184, 1182, 1179, 175, 1176, 173, 1192, 1191, 1189, 1187, 176, 1194, 1193, 2313,
+ 2307, 2305, 592, 589, 2294, 2292, 2289, 578, 572, 568, 2297, 580, 1591, 2272, 2267, 2264, 1547, 538, 536, 529,
+ 2278, 525, 2275, 547, 544, 541, 1574, 1571, 2237, 2235, 2229, 1493, 2225, 1489, 478, 2247, 470, 2244, 465, 2241,
+ 493, 488, 484, 2250, 498, 495, 1536, 1533, 1530, 1539, 2187, 2186, 2184, 2182, 1432, 2179, 1430, 2176, 1427, 414,
+ 412, 2197, 409, 2195, 405, 2193, 2190, 426, 424, 421, 2203, 418, 2201, 431, 429, 1473, 1471, 1469, 1466, 434,
+ 1477, 1475, 2478, 2472, 2470, 2459, 2457, 2454, 2462, 803, 2437, 2432, 2429, 1726, 2443, 2440, 792, 789, 785,
+ 2401, 2399, 2393, 1702, 2389, 1699, 2411, 2408, 2405, 745, 741, 2415, 758, 755, 1721, 2358, 2357, 2355, 2353,
+ 1661, 2350, 1660, 2347, 1657, 2368, 2366, 2364, 2361, 1666, 690, 687, 2374, 683, 2372, 701, 698, 705, 1691, 1689,
+ 2619, 2617, 2610, 2608, 2605, 2613, 2593, 2588, 2585, 1803, 2599, 2596, 2563, 2561, 2555, 1797, 2551, 1795, 2573,
+ 2570, 2567, 2577, 2525, 2524, 2522, 2520, 1786, 2517, 1785, 2514, 1783, 2535, 2533, 2531, 2528, 1788, 2541, 2539,
+ 906, 903, 911, 2721, 1844, 2715, 2712, 1838, 1836, 2699, 2696, 2693, 2703, 1827, 1826, 1824, 2673, 2671, 2669,
+ 2666, 1829, 2679, 2677, 1858, 1857, 2772, 1854, 1853, 1851, 1856, 2766, 2764, 143, 1987, 139, 1986, 135, 133,
+ 131, 1984, 128, 1983, 125, 1981, 138, 137, 136, 1985, 1133, 1132, 1130, 112, 110, 1974, 107, 1973, 104, 1971,
+ 1969, 122, 121, 119, 117, 1977, 114, 1976, 124, 1115, 1114, 1112, 1110, 1117, 1116, 84, 83, 1953, 81, 1952, 78,
+ 1950, 1948, 1945, 94, 93, 91, 1959, 88, 1958, 85, 1955, 99, 97, 95, 1961, 1086, 1085, 1083, 1081, 1078, 100,
+ 1090, 1089, 1087, 1091, 49, 47, 1917, 44, 1915, 1913, 1910, 1907, 59, 1926, 56, 1925, 53, 1922, 1919, 66, 64,
+ 1931, 61, 1929, 1042, 1040, 1038, 71, 1035, 70, 1032, 68, 1048, 1047, 1045, 1043, 1050, 1049, 12, 10, 1869, 1867,
+ 1864, 1861, 21, 1880, 19, 1877, 1874, 1871, 28, 1888, 25, 1886, 22, 1883, 982, 980, 977, 974, 32, 30, 991, 989,
+ 987, 984, 34, 995, 994, 992, 2151, 2150, 2147, 2146, 2144, 356, 355, 354, 2149, 2139, 2138, 2136, 2134, 1359,
+ 343, 341, 338, 2143, 335, 2141, 348, 347, 346, 1376, 1374, 2124, 2123, 2121, 2119, 1326, 2116, 1324, 310, 308,
+ 305, 2131, 302, 2129, 298, 2127, 320, 318, 316, 313, 2133, 322, 321, 1355, 1353, 1351, 1357, 2092, 2091, 2089,
+ 2087, 1276, 2084, 1274, 2081, 1271, 259, 2102, 256, 2100, 252, 2098, 2095, 272, 269, 2108, 266, 2106, 281, 279,
+ 277, 1317, 1315, 1313, 1310, 282, 1321, 1319, 2039, 2037, 2035, 2032, 1203, 2029, 1200, 1197, 207, 2053, 205,
+ 2051, 201, 2049, 2046, 2043, 220, 218, 2064, 215, 2062, 211, 2059, 228, 226, 223, 2069, 1259, 1257, 1254, 232,
+ 1251, 230, 1267, 1265, 1263, 2316, 2315, 2312, 2311, 2309, 2314, 2304, 2303, 2301, 2299, 1593, 2308, 2306, 590,
+ 2288, 2287, 2285, 2283, 1578, 2280, 1577, 2295, 2293, 2291, 579, 577, 574, 571, 2298, 582, 581, 1592, 2263, 2262,
+ 2260, 2258, 1545, 2255, 1544, 2252, 1541, 2273, 2271, 2269, 2266, 1550, 535, 532, 2279, 528, 2277, 546, 543, 549,
+ 1575, 1573, 2224, 2222, 2220, 1486, 2217, 1485, 2214, 1482, 1479, 2238, 2236, 2234, 2231, 1496, 2228, 1492, 480,
+ 477, 2248, 473, 2246, 469, 2243, 490, 487, 2251, 497, 1537, 1535, 1532, 2477, 2476, 2474, 2479, 2469, 2468, 2466,
+ 2464, 1730, 2473, 2471, 2453, 2452, 2450, 2448, 1729, 2445, 1728, 2460, 2458, 2456, 2463, 805, 804, 2428, 2427,
+ 2425, 2423, 1725, 2420, 1724, 2417, 1722, 2438, 2436, 2434, 2431, 1727, 2444, 2442, 793, 791, 788, 795, 2388,
+ 2386, 2384, 1697, 2381, 1696, 2378, 1694, 1692, 2402, 2400, 2398, 2395, 1703, 2392, 1701, 2412, 2410, 2407, 751,
+ 748, 744, 2416, 759, 757, 1807, 2620, 2618, 1806, 1805, 2611, 2609, 2607, 2614, 1802, 1801, 1799, 2594, 2592,
+ 2590, 2587, 1804, 2600, 2598, 1794, 1793, 1791, 1789, 2564, 2562, 2560, 2557, 1798, 2554, 1796, 2574, 2572, 2569,
+ 2578, 1847, 1846, 2722, 1843, 1842, 1840, 1845, 2716, 2714, 1835, 1834, 1832, 1830, 1839, 1837, 2700, 2698, 2695,
+ 2704, 1817, 1811, 1810, 897, 862, 1777, 829, 826, 838, 1760, 1758, 808, 2481, 1741, 1740, 1738, 1743, 2624, 1818,
+ 2726, 2776, 782, 740, 737, 1715, 686, 679, 695, 1682, 1680, 639, 628, 2339, 647, 644, 1645, 1643, 1640, 1648,
+ 602, 600, 597, 595, 2320, 593, 2318, 609, 607, 604, 1611, 1610, 1608, 1606, 613, 1615, 1613, 2328, 926, 924, 892,
+ 886, 899, 857, 850, 2505, 1778, 824, 823, 821, 819, 2488, 818, 2486, 833, 831, 828, 840, 1761, 1759, 2649, 2632,
+ 2630, 2746, 2734, 2732, 2782, 2781, 570, 567, 1587, 531, 527, 523, 540, 1566, 1564, 476, 467, 463, 2240, 486,
+ 483, 1524, 1521, 1518, 1529, 411, 403, 2192, 399, 2189, 423, 416, 1462, 1457, 1454, 428, 1468, 1465, 2210, 366,
+ 363, 2158, 360, 2156, 357, 2153, 376, 373, 370, 2163, 1410, 1409, 1407, 1405, 382, 1402, 380, 1417, 1415, 1412,
+ 1421, 2175, 2174, 777, 774, 771, 784, 732, 725, 722, 2404, 743, 1716, 676, 674, 668, 2363, 665, 2360, 685, 1684,
+ 1681, 626, 624, 622, 2335, 620, 2333, 617, 2330, 641, 635, 649, 1646, 1644, 1642, 2566, 928, 925, 2530, 2527,
+ 894, 891, 888, 2501, 2499, 2496, 858, 856, 854, 851, 1779, 2692, 2668, 2665, 2645, 2643, 2640, 2651, 2768, 2759,
+ 2757, 2744, 2743, 2741, 2748, 352, 1382, 340, 337, 333, 1371, 1369, 307, 300, 296, 2126, 315, 312, 1347, 1342,
+ 1350, 261, 258, 250, 2097, 246, 2094, 271, 268, 264, 1306, 1301, 1298, 276, 1312, 1309, 2115, 203, 2048, 195,
+ 2045, 191, 2041, 213, 209, 2056, 1246, 1244, 1238, 225, 1234, 222, 1256, 1253, 1249, 1262, 2080, 2079, 154, 1997,
+ 150, 1995, 147, 1992, 1989, 163, 160, 2004, 156, 2001, 1175, 1174, 1172, 1170, 1167, 170, 1164, 167, 1185, 1183,
+ 1180, 1177, 174, 1190, 1188, 2025, 2024, 2022, 587, 586, 564, 559, 556, 2290, 573, 1588, 520, 518, 512, 2268,
+ 508, 2265, 530, 1568, 1565, 461, 457, 2233, 450, 2230, 446, 2226, 479, 471, 489, 1526, 1523, 1520, 397, 395,
+ 2185, 392, 2183, 389, 2180, 2177, 410, 2194, 402, 422, 1463, 1461, 1459, 1456, 1470, 2455, 799, 2433, 2430, 779,
+ 776, 773, 2397, 2394, 2390, 734, 728, 724, 746, 1717, 2356, 2354, 2351, 2348, 1658, 677, 675, 673, 670, 667, 688,
+ 1685, 1683, 2606, 2589, 2586, 2559, 2556, 2552, 927, 2523, 2521, 2518, 2515, 1784, 2532, 895, 893, 890, 2718,
+ 2709, 2707, 2689, 2687, 2684, 2663, 2662, 2660, 2658, 1825, 2667, 2769, 1852, 2760, 2758, 142, 141, 1139, 1138,
+ 134, 132, 129, 126, 1982, 1129, 1128, 1126, 1131, 113, 111, 108, 105, 1972, 101, 1970, 120, 118, 115, 1109, 1108,
+ 1106, 1104, 123, 1113, 1111, 82, 79, 1951, 75, 1949, 72, 1946, 92, 89, 86, 1956, 1077, 1076, 1074, 1072, 98,
+ 1069, 96, 1084, 1082, 1079, 1088, 1968, 1967, 48, 45, 1916, 42, 1914, 39, 1911, 1908, 60, 57, 54, 1923, 50, 1920,
+ 1031, 1030, 1028, 1026, 67, 1023, 65, 1020, 62, 1041, 1039, 1036, 1033, 69, 1046, 1044, 1944, 1943, 1941, 11, 9,
+ 1868, 7, 1865, 1862, 1859, 20, 1878, 16, 1875, 13, 1872, 970, 968, 966, 963, 29, 960, 26, 23, 983, 981, 978, 975,
+ 33, 971, 31, 990, 988, 985, 1906, 1904, 1902, 993, 351, 2145, 1383, 331, 330, 328, 326, 2137, 323, 2135, 339,
+ 1372, 1370, 294, 293, 291, 289, 2122, 286, 2120, 283, 2117, 309, 303, 317, 1348, 1346, 1344, 245, 244, 242, 2090,
+ 239, 2088, 236, 2085, 2082, 260, 2099, 249, 270, 1307, 1305, 1303, 1300, 1314, 189, 2038, 186, 2036, 183, 2033,
+ 2030, 2026, 206, 198, 2047, 194, 216, 1247, 1245, 1243, 1240, 227, 1237, 1255, 2310, 2302, 2300, 2286, 2284,
+ 2281, 565, 563, 561, 558, 575, 1589, 2261, 2259, 2256, 2253, 1542, 521, 519, 517, 514, 2270, 511, 533, 1569,
+ 1567, 2223, 2221, 2218, 2215, 1483, 2211, 1480, 459, 456, 453, 2232, 449, 474, 491, 1527, 1525, 1522, 2475, 2467,
+ 2465, 2451, 2449, 2446, 801, 800, 2426, 2424, 2421, 2418, 1723, 2435, 780, 778, 775, 2387, 2385, 2382, 2379,
+ 1695, 2375, 1693, 2396, 735, 733, 730, 727, 749, 1718, 2616, 2615, 2604, 2603, 2601, 2584, 2583, 2581, 2579,
+ 1800, 2591, 2550, 2549, 2547, 2545, 1792, 2542, 1790, 2558, 929, 2719, 1841, 2710, 2708, 1833, 1831, 2690, 2688,
+ 2686, 1815, 1809, 1808, 1774, 1756, 1754, 1737, 1736, 1734, 1739, 1816, 1711, 1676, 1674, 633, 629, 1638, 1636,
+ 1633, 1641, 598, 1605, 1604, 1602, 1600, 605, 1609, 1607, 2327, 887, 853, 1775, 822, 820, 1757, 1755, 1584, 524,
+ 1560, 1558, 468, 464, 1514, 1511, 1508, 1519, 408, 404, 400, 1452, 1447, 1444, 417, 1458, 1455, 2208, 364, 361,
+ 358, 2154, 1401, 1400, 1398, 1396, 374, 1393, 371, 1408, 1406, 1403, 1413, 2173, 2172, 772, 726, 723, 1712, 672,
+ 669, 666, 682, 1678, 1675, 625, 623, 621, 618, 2331, 636, 632, 1639, 1637, 1635, 920, 918, 884, 880, 889, 849,
+ 848, 847, 846, 2497, 855, 852, 1776, 2641, 2742, 2787, 1380, 334, 1367, 1365, 301, 297, 1340, 1338, 1335, 1343,
+ 255, 251, 247, 1296, 1291, 1288, 265, 1302, 1299, 2113, 204, 196, 192, 2042, 1232, 1230, 1224, 214, 1220, 210,
+ 1242, 1239, 1235, 1250, 2077, 2075, 151, 148, 1993, 144, 1990, 1163, 1162, 1160, 1158, 1155, 161, 1152, 157,
+ 1173, 1171, 1168, 1165, 168, 1181, 1178, 2021, 2020, 2018, 2023, 585, 560, 557, 1585, 516, 509, 1562, 1559, 458,
+ 447, 2227, 472, 1516, 1513, 1510, 398, 396, 393, 390, 2181, 386, 2178, 407, 1453, 1451, 1449, 1446, 420, 1460,
+ 2209, 769, 764, 720, 712, 2391, 729, 1713, 664, 663, 661, 659, 2352, 656, 2349, 671, 1679, 1677, 2553, 922, 919,
+ 2519, 2516, 885, 883, 881, 2685, 2661, 2659, 2767, 2756, 2755, 140, 1137, 1136, 130, 127, 1125, 1124, 1122, 1127,
+ 109, 106, 102, 1103, 1102, 1100, 1098, 116, 1107, 1105, 1980, 80, 76, 73, 1947, 1068, 1067, 1065, 1063, 90, 1060,
+ 87, 1075, 1073, 1070, 1080, 1966, 1965, 46, 43, 40, 1912, 36, 1909, 1019, 1018, 1016, 1014, 58, 1011, 55, 1008,
+ 51, 1029, 1027, 1024, 1021, 63, 1037, 1034, 1940, 1939, 1937, 1942, 8, 1866, 4, 1863, 1, 1860, 956, 954, 952,
+ 949, 946, 17, 14, 969, 967, 964, 961, 27, 957, 24, 979, 976, 972, 1901, 1900, 1898, 1896, 986, 1905, 1903, 350,
+ 349, 1381, 329, 327, 324, 1368, 1366, 292, 290, 287, 284, 2118, 304, 1341, 1339, 1337, 1345, 243, 240, 237, 2086,
+ 233, 2083, 254, 1297, 1295, 1293, 1290, 1304, 2114, 190, 187, 184, 2034, 180, 2031, 177, 2027, 199, 1233, 1231,
+ 1229, 1226, 217, 1223, 1241, 2078, 2076, 584, 555, 554, 552, 550, 2282, 562, 1586, 507, 506, 504, 502, 2257, 499,
+ 2254, 515, 1563, 1561, 445, 443, 441, 2219, 438, 2216, 435, 2212, 460, 454, 475, 1517, 1515, 1512, 2447, 798,
+ 797, 2422, 2419, 770, 768, 766, 2383, 2380, 2376, 721, 719, 717, 714, 731, 1714, 2602, 2582, 2580, 2548, 2546,
+ 2543, 923, 921, 2717, 2706, 2705, 2683, 2682, 2680, 1771, 1752, 1750, 1733, 1732, 1731, 1735, 1814, 1707, 1670,
+ 1668, 1631, 1629, 1626, 1634, 1599, 1598, 1596, 1594, 1603, 1601, 2326, 1772, 1753, 1751, 1581, 1554, 1552, 1504,
+ 1501, 1498, 1509, 1442, 1437, 1434, 401, 1448, 1445, 2206, 1392, 1391, 1389, 1387, 1384, 359, 1399, 1397, 1394,
+ 1404, 2171, 2170, 1708, 1672, 1669, 619, 1632, 1630, 1628, 1773, 1378, 1363, 1361, 1333, 1328, 1336, 1286, 1281,
+ 1278, 248, 1292, 1289, 2111, 1218, 1216, 1210, 197, 1206, 193, 1228, 1225, 1221, 1236, 2073, 2071, 1151, 1150,
+ 1148, 1146, 152, 1143, 149, 1140, 145, 1161, 1159, 1156, 1153, 158, 1169, 1166, 2017, 2016, 2014, 2019, 1582,
+ 510, 1556, 1553, 452, 448, 1506, 1500, 394, 391, 387, 1443, 1441, 1439, 1436, 1450, 2207, 765, 716, 713, 1709,
+ 662, 660, 657, 1673, 1671, 916, 914, 879, 878, 877, 882, 1135, 1134, 1121, 1120, 1118, 1123, 1097, 1096, 1094,
+ 1092, 103, 1101, 1099, 1979, 1059, 1058, 1056, 1054, 77, 1051, 74, 1066, 1064, 1061, 1071, 1964, 1963, 1007,
+ 1006, 1004, 1002, 999, 41, 996, 37, 1017, 1015, 1012, 1009, 52, 1025, 1022, 1936, 1935, 1933, 1938, 942, 940,
+ 938, 935, 932, 5, 2, 955, 953, 950, 947, 18, 943, 15, 965, 962, 958, 1895, 1894, 1892, 1890, 973, 1899, 1897,
+ 1379, 325, 1364, 1362, 288, 285, 1334, 1332, 1330, 241, 238, 234, 1287, 1285, 1283, 1280, 1294, 2112, 188, 185,
+ 181, 178, 2028, 1219, 1217, 1215, 1212, 200, 1209, 1227, 2074, 2072, 583, 553, 551, 1583, 505, 503, 500, 513,
+ 1557, 1555, 444, 442, 439, 436, 2213, 455, 451, 1507, 1505, 1502, 796, 763, 762, 760, 767, 711, 710, 708, 706,
+ 2377, 718, 715, 1710, 2544, 917, 915, 2681, 1627, 1597, 1595, 2325, 1769, 1749, 1747, 1499, 1438, 1435, 2204,
+ 1390, 1388, 1385, 1395, 2169, 2167, 1704, 1665, 1662, 1625, 1623, 1620, 1770, 1329, 1282, 1279, 2109, 1214, 1207,
+ 1222, 2068, 2065, 1149, 1147, 1144, 1141, 146, 1157, 1154, 2013, 2011, 2008, 2015, 1579, 1549, 1546, 1495, 1487,
+ 1433, 1431, 1428, 1425, 388, 1440, 2205, 1705, 658, 1667, 1664, 1119, 1095, 1093, 1978, 1057, 1055, 1052, 1062,
+ 1962, 1960, 1005, 1003, 1000, 997, 38, 1013, 1010, 1932, 1930, 1927, 1934, 941, 939, 936, 933, 6, 930, 3, 951,
+ 948, 944, 1889, 1887, 1884, 1881, 959, 1893, 1891, 35, 1377, 1360, 1358, 1327, 1325, 1322, 1331, 1277, 1275,
+ 1272, 1269, 235, 1284, 2110, 1205, 1204, 1201, 1198, 182, 1195, 179, 1213, 2070, 2067, 1580, 501, 1551, 1548,
+ 440, 437, 1497, 1494, 1490, 1503, 761, 709, 707, 1706, 913, 912, 2198, 1386, 2164, 2161, 1621, 1766, 2103, 1208,
+ 2058, 2054, 1145, 1142, 2005, 2002, 1999, 2009, 1488, 1429, 1426, 2200, 1698, 1659, 1656, 1975, 1053, 1957, 1954,
+ 1001, 998, 1924, 1921, 1918, 1928, 937, 934, 931, 1879, 1876, 1873, 1870, 945, 1885, 1882, 1323, 1273, 1270,
+ 2105, 1202, 1199, 1196, 1211, 2061, 2057, 1576, 1543, 1540, 1484, 1481, 1478, 1491, 1700
+};
+CBC_PDF417Common::CBC_PDF417Common()
+{
+}
+CBC_PDF417Common::~CBC_PDF417Common()
+{
+}
+FX_INT32 CBC_PDF417Common::getBitCountSum(CFX_Int32Array& moduleBitCount)
+{
+ FX_INT32 bitCountSum = 0;
+ for (FX_INT32 i = 0; i < moduleBitCount.GetSize(); i++) {
+ FX_INT32 count = moduleBitCount.GetAt(i);
+ bitCountSum += count;
+ }
+ return bitCountSum;
+}
+FX_INT32 CBC_PDF417Common::getCodeword(FX_DWORD symbol)
+{
+ FX_DWORD sym = symbol & 0x3FFFF;
+ FX_INT32 i = findCodewordIndex(sym);
+ if (i == -1) {
+ return -1;
+ }
+ return (CODEWORD_TABLE[i] - 1) % NUMBER_OF_CODEWORDS;
+}
+FX_INT32 CBC_PDF417Common::findCodewordIndex(FX_DWORD symbol)
+{
+ FX_INT32 first = 0;
+ FX_INT32 upto = sizeof(SYMBOL_TABLE) / sizeof(SYMBOL_TABLE[0]);
+ while (first < upto) {
+ FX_INT32 mid = ((FX_DWORD)(first + upto)) >> 1;
+ if (symbol < (FX_DWORD)SYMBOL_TABLE[mid]) {
+ upto = mid;
+ } else if (symbol > (FX_DWORD)SYMBOL_TABLE[mid]) {
+ first = mid + 1;
+ } else {
+ return mid;
+ }
+ }
+ return -1;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417Compaction.cpp b/xfa/src/fxbarcode/src/BC_PDF417Compaction.cpp
new file mode 100644
index 0000000000..67a81b1178
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417Compaction.cpp
@@ -0,0 +1,14 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Compaction.h"
+CBC_Compaction::CBC_Compaction()
+{
+}
+CBC_Compaction::~CBC_Compaction()
+{
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417DecodedBitStreamParser.cpp b/xfa/src/fxbarcode/src/BC_PDF417DecodedBitStreamParser.cpp
new file mode 100644
index 0000000000..cf0a1490f4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417DecodedBitStreamParser.cpp
@@ -0,0 +1,474 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include <stdlib.h>
+#include "barcode.h"
+#include "include/BC_DecoderResult.h"
+#include "include/BC_PDF417ResultMetadata.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#define TEXT_COMPACTION_MODE_LATCH 900
+#define BYTE_COMPACTION_MODE_LATCH 901
+#define NUMERIC_COMPACTION_MODE_LATCH 902
+#define BYTE_COMPACTION_MODE_LATCH_6 924
+#define BEGIN_MACRO_PDF417_CONTROL_BLOCK 928
+#define BEGIN_MACRO_PDF417_OPTIONAL_FIELD 923
+#define MACRO_PDF417_TERMINATOR 922
+#define MODE_SHIFT_TO_BYTE_COMPACTION_MODE 913
+FX_INT32 CBC_DecodedBitStreamPaser::MAX_NUMERIC_CODEWORDS = 15;
+FX_INT32 CBC_DecodedBitStreamPaser::EXP900[16] = {0};
+FX_INT32 CBC_DecodedBitStreamPaser::NUMBER_OF_SEQUENCE_CODEWORDS = 2;
+FX_INT32 CBC_DecodedBitStreamPaser::PL = 25;
+FX_INT32 CBC_DecodedBitStreamPaser::LL = 27;
+FX_INT32 CBC_DecodedBitStreamPaser::AS = 27;
+FX_INT32 CBC_DecodedBitStreamPaser::ML = 28;
+FX_INT32 CBC_DecodedBitStreamPaser::AL = 28;
+FX_INT32 CBC_DecodedBitStreamPaser::PS = 29;
+FX_INT32 CBC_DecodedBitStreamPaser::PAL = 29;
+FX_CHAR CBC_DecodedBitStreamPaser::PUNCT_CHARS[29] = {
+ ';', '<', '>', '@', '[', '\\', '}', '_', '`', '~', '!',
+ '\r', '\t', ',', ':', '\n', '-', '.', '$', '/', '"', '|', '*',
+ '(', ')', '?', '{', '}', '\''
+};
+FX_CHAR CBC_DecodedBitStreamPaser::MIXED_CHARS[30] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '&',
+ '\r', '\t', ',', ':', '#', '-', '.', '$', '/', '+', '%', '*',
+ '=', '^'
+};
+void CBC_DecodedBitStreamPaser::Initialize()
+{
+ EXP900[0] = 1;
+ FX_INT32 nineHundred = 900;
+ EXP900[1] = nineHundred;
+ for (FX_INT32 i = 2; i < sizeof(EXP900) / sizeof(FX_INT32); i++) {
+ EXP900[i] = EXP900[i - 1] * nineHundred;
+ }
+}
+void CBC_DecodedBitStreamPaser::Finalize()
+{
+}
+CBC_DecodedBitStreamPaser::CBC_DecodedBitStreamPaser()
+{
+}
+CBC_DecodedBitStreamPaser::~CBC_DecodedBitStreamPaser()
+{
+}
+CBC_CommonDecoderResult* CBC_DecodedBitStreamPaser::decode(CFX_Int32Array &codewords, CFX_ByteString ecLevel, FX_INT32 &e)
+{
+ CFX_ByteString result;
+ FX_INT32 codeIndex = 1;
+ FX_INT32 code = codewords.GetAt(codeIndex);
+ codeIndex++;
+ CBC_PDF417ResultMetadata* resultMetadata = FX_NEW CBC_PDF417ResultMetadata;
+ while (codeIndex < codewords[0]) {
+ switch (code) {
+ case TEXT_COMPACTION_MODE_LATCH:
+ codeIndex = textCompaction(codewords, codeIndex, result);
+ break;
+ case BYTE_COMPACTION_MODE_LATCH:
+ codeIndex = byteCompaction(code, codewords, codeIndex, result);
+ break;
+ case NUMERIC_COMPACTION_MODE_LATCH:
+ codeIndex = numericCompaction(codewords, codeIndex, result, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ break;
+ case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
+ codeIndex = byteCompaction(code, codewords, codeIndex, result);
+ break;
+ case BYTE_COMPACTION_MODE_LATCH_6:
+ codeIndex = byteCompaction(code, codewords, codeIndex, result);
+ break;
+ case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
+ codeIndex = decodeMacroBlock(codewords, codeIndex, resultMetadata, e);
+ if (e != BCExceptionNO) {
+ delete resultMetadata;
+ return NULL;
+ }
+ break;
+ default:
+ codeIndex--;
+ codeIndex = textCompaction(codewords, codeIndex, result);
+ break;
+ }
+ if (codeIndex < codewords.GetSize()) {
+ code = codewords[codeIndex++];
+ } else {
+ e = BCExceptionFormatInstance;
+ delete resultMetadata;
+ return NULL;
+ }
+ }
+ if (result.GetLength() == 0) {
+ e = BCExceptionFormatInstance;
+ delete resultMetadata;
+ return NULL;
+ }
+ CFX_ByteArray rawBytes;
+ CFX_PtrArray byteSegments;
+ CBC_CommonDecoderResult *tempCd = FX_NEW CBC_CommonDecoderResult();
+ tempCd->Init(rawBytes, result, byteSegments, ecLevel, e);
+ if (e != BCExceptionNO) {
+ delete resultMetadata;
+ return NULL;
+ }
+ tempCd->setOther(resultMetadata);
+ return tempCd;
+}
+FX_INT32 CBC_DecodedBitStreamPaser::decodeMacroBlock(CFX_Int32Array &codewords, FX_INT32 codeIndex, CBC_PDF417ResultMetadata* resultMetadata, FX_INT32 &e)
+{
+ if (codeIndex + NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) {
+ e = BCExceptionFormatInstance;
+ return -1;
+ }
+ CFX_Int32Array segmentIndexArray;
+ segmentIndexArray.SetSize(NUMBER_OF_SEQUENCE_CODEWORDS);
+ for (FX_INT32 i = 0; i < NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
+ segmentIndexArray.SetAt(i, codewords[codeIndex]);
+ }
+ CFX_ByteString str = decodeBase900toBase10(segmentIndexArray, NUMBER_OF_SEQUENCE_CODEWORDS, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ resultMetadata->setSegmentIndex(atoi(str.GetBuffer(str.GetLength())));
+ CFX_ByteString fileId;
+ codeIndex = textCompaction(codewords, codeIndex, fileId);
+ resultMetadata->setFileId(fileId);
+ if (codewords[codeIndex] == BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
+ codeIndex++;
+ CFX_Int32Array additionalOptionCodeWords;
+ additionalOptionCodeWords.SetSize(codewords[0] - codeIndex);
+ FX_INT32 additionalOptionCodeWordsIndex = 0;
+ FX_BOOL end = FALSE;
+ while ((codeIndex < codewords[0]) && !end) {
+ FX_INT32 code = codewords[codeIndex++];
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ additionalOptionCodeWords[additionalOptionCodeWordsIndex++] = code;
+ } else {
+ switch (code) {
+ case MACRO_PDF417_TERMINATOR:
+ resultMetadata->setLastSegment(TRUE);
+ codeIndex++;
+ end = TRUE;
+ break;
+ default:
+ e = BCExceptionFormatInstance;
+ return -1;
+ }
+ }
+ }
+ CFX_Int32Array array;
+ array.SetSize(additionalOptionCodeWordsIndex);
+ array.Copy(additionalOptionCodeWords);
+ resultMetadata->setOptionalData(array);
+ } else if (codewords[codeIndex] == MACRO_PDF417_TERMINATOR) {
+ resultMetadata->setLastSegment(TRUE);
+ codeIndex++;
+ }
+ return codeIndex;
+}
+FX_INT32 CBC_DecodedBitStreamPaser::textCompaction(CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result)
+{
+ CFX_Int32Array textCompactionData;
+ textCompactionData.SetSize((codewords[0] - codeIndex) << 1);
+ CFX_Int32Array byteCompactionData;
+ byteCompactionData.SetSize((codewords[0] - codeIndex) << 1);
+ FX_INT32 index = 0;
+ FX_BOOL end = FALSE;
+ while ((codeIndex < codewords[0]) && !end) {
+ FX_INT32 code = codewords[codeIndex++];
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ textCompactionData[index] = code / 30;
+ textCompactionData[index + 1] = code % 30;
+ index += 2;
+ } else {
+ switch (code) {
+ case TEXT_COMPACTION_MODE_LATCH:
+ textCompactionData[index++] = TEXT_COMPACTION_MODE_LATCH;
+ break;
+ case BYTE_COMPACTION_MODE_LATCH:
+ codeIndex--;
+ end = TRUE;
+ break;
+ case NUMERIC_COMPACTION_MODE_LATCH:
+ codeIndex--;
+ end = TRUE;
+ break;
+ case BEGIN_MACRO_PDF417_CONTROL_BLOCK:
+ codeIndex--;
+ end = TRUE;
+ break;
+ case BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
+ codeIndex--;
+ end = TRUE;
+ break;
+ case MACRO_PDF417_TERMINATOR:
+ codeIndex--;
+ end = TRUE;
+ break;
+ case MODE_SHIFT_TO_BYTE_COMPACTION_MODE:
+ textCompactionData[index] = MODE_SHIFT_TO_BYTE_COMPACTION_MODE;
+ code = codewords[codeIndex++];
+ byteCompactionData[index] = code;
+ index++;
+ break;
+ case BYTE_COMPACTION_MODE_LATCH_6:
+ codeIndex--;
+ end = TRUE;
+ break;
+ }
+ }
+ }
+ decodeTextCompaction(textCompactionData, byteCompactionData, index, result);
+ return codeIndex;
+}
+void CBC_DecodedBitStreamPaser::decodeTextCompaction(CFX_Int32Array &textCompactionData, CFX_Int32Array &byteCompactionData, FX_INT32 length, CFX_ByteString &result)
+{
+ Mode subMode = ALPHA;
+ Mode priorToShiftMode = ALPHA;
+ FX_INT32 i = 0;
+ while (i < length) {
+ FX_INT32 subModeCh = textCompactionData[i];
+ FX_CHAR ch = 0;
+ switch (subMode) {
+ case ALPHA:
+ if (subModeCh < 26) {
+ ch = (FX_CHAR) ('A' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == LL) {
+ subMode = LOWER;
+ } else if (subModeCh == ML) {
+ subMode = MIXED;
+ } else if (subModeCh == PS) {
+ priorToShiftMode = subMode;
+ subMode = PUNCT_SHIFT;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ result += (FX_CHAR) byteCompactionData[i];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+ case LOWER:
+ if (subModeCh < 26) {
+ ch = (FX_CHAR) ('a' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == AS) {
+ priorToShiftMode = subMode;
+ subMode = ALPHA_SHIFT;
+ } else if (subModeCh == ML) {
+ subMode = MIXED;
+ } else if (subModeCh == PS) {
+ priorToShiftMode = subMode;
+ subMode = PUNCT_SHIFT;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ result += (FX_CHAR) byteCompactionData[i];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+ case MIXED:
+ if (subModeCh < PL) {
+ ch = MIXED_CHARS[subModeCh];
+ } else {
+ if (subModeCh == PL) {
+ subMode = PUNCT;
+ } else if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == LL) {
+ subMode = LOWER;
+ } else if (subModeCh == AL) {
+ subMode = ALPHA;
+ } else if (subModeCh == PS) {
+ priorToShiftMode = subMode;
+ subMode = PUNCT_SHIFT;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ result += (FX_CHAR) byteCompactionData[i];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+ case PUNCT:
+ if (subModeCh < PAL) {
+ ch = PUNCT_CHARS[subModeCh];
+ } else {
+ if (subModeCh == PAL) {
+ subMode = ALPHA;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ result += (FX_CHAR) byteCompactionData[i];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+ case ALPHA_SHIFT:
+ subMode = priorToShiftMode;
+ if (subModeCh < 26) {
+ ch = (FX_CHAR) ('A' + subModeCh);
+ } else {
+ if (subModeCh == 26) {
+ ch = ' ';
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+ case PUNCT_SHIFT:
+ subMode = priorToShiftMode;
+ if (subModeCh < PAL) {
+ ch = PUNCT_CHARS[subModeCh];
+ } else {
+ if (subModeCh == PAL) {
+ subMode = ALPHA;
+ } else if (subModeCh == MODE_SHIFT_TO_BYTE_COMPACTION_MODE) {
+ result += (FX_CHAR) byteCompactionData[i];
+ } else if (subModeCh == TEXT_COMPACTION_MODE_LATCH) {
+ subMode = ALPHA;
+ }
+ }
+ break;
+ }
+ if (ch != 0) {
+ result += ch;
+ }
+ i++;
+ }
+}
+FX_INT32 CBC_DecodedBitStreamPaser::byteCompaction(FX_INT32 mode, CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result)
+{
+ if (mode == BYTE_COMPACTION_MODE_LATCH) {
+ FX_INT32 count = 0;
+ FX_INT64 value = 0;
+ FX_WORD* decodedData = FX_Alloc(FX_WORD, 6 * sizeof(FX_WORD));
+ CFX_Int32Array byteCompactedCodewords;
+ byteCompactedCodewords.SetSize(6);
+ FX_BOOL end = FALSE;
+ FX_INT32 nextCode = codewords[codeIndex++];
+ while ((codeIndex < codewords[0]) && !end) {
+ byteCompactedCodewords[count++] = nextCode;
+ value = 900 * value + nextCode;
+ nextCode = codewords[codeIndex++];
+ if (nextCode == TEXT_COMPACTION_MODE_LATCH ||
+ nextCode == BYTE_COMPACTION_MODE_LATCH ||
+ nextCode == NUMERIC_COMPACTION_MODE_LATCH ||
+ nextCode == BYTE_COMPACTION_MODE_LATCH_6 ||
+ nextCode == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ nextCode == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ nextCode == MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = TRUE;
+ } else {
+ if ((count % 5 == 0) && (count > 0)) {
+ FX_INT32 j = 0;
+ for (; j < 6; ++j) {
+ decodedData[5 - j] = (FX_WORD) (value % 256);
+ value >>= 8;
+ }
+ for (j = 0; j < 6; ++j) {
+ result += (FX_CHAR)decodedData[j];
+ }
+ count = 0;
+ }
+ }
+ }
+ FX_Free(decodedData);
+ if (codeIndex == codewords[0] && nextCode < TEXT_COMPACTION_MODE_LATCH) {
+ byteCompactedCodewords[count++] = nextCode;
+ }
+ for (FX_INT32 i = 0; i < count; i++) {
+ result += (FX_CHAR)(FX_WORD) byteCompactedCodewords[i];
+ }
+ } else if (mode == BYTE_COMPACTION_MODE_LATCH_6) {
+ FX_INT32 count = 0;
+ FX_INT64 value = 0;
+ FX_BOOL end = FALSE;
+ while (codeIndex < codewords[0] && !end) {
+ FX_INT32 code = codewords[codeIndex++];
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ count++;
+ value = 900 * value + code;
+ } else {
+ if (code == TEXT_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH ||
+ code == NUMERIC_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH_6 ||
+ code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ code == MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = TRUE;
+ }
+ }
+ if ((count % 5 == 0) && (count > 0)) {
+ FX_WORD* decodedData = FX_Alloc(FX_WORD, 6 * sizeof(FX_WORD));
+ FX_INT32 j = 0;
+ for (; j < 6; ++j) {
+ decodedData[5 - j] = (FX_WORD) (value & 0xFF);
+ value >>= 8;
+ }
+ for (j = 0; j < 6; ++j) {
+ result += (FX_CHAR)decodedData[j];
+ }
+ count = 0;
+ FX_Free(decodedData);
+ }
+ }
+ }
+ return codeIndex;
+}
+FX_INT32 CBC_DecodedBitStreamPaser::numericCompaction(CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result, FX_INT32 &e)
+{
+ FX_INT32 count = 0;
+ FX_BOOL end = FALSE;
+ CFX_Int32Array numericCodewords;
+ numericCodewords.SetSize(MAX_NUMERIC_CODEWORDS);
+ while (codeIndex < codewords[0] && !end) {
+ FX_INT32 code = codewords[codeIndex++];
+ if (codeIndex == codewords[0]) {
+ end = TRUE;
+ }
+ if (code < TEXT_COMPACTION_MODE_LATCH) {
+ numericCodewords[count] = code;
+ count++;
+ } else {
+ if (code == TEXT_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH ||
+ code == BYTE_COMPACTION_MODE_LATCH_6 ||
+ code == BEGIN_MACRO_PDF417_CONTROL_BLOCK ||
+ code == BEGIN_MACRO_PDF417_OPTIONAL_FIELD ||
+ code == MACRO_PDF417_TERMINATOR) {
+ codeIndex--;
+ end = TRUE;
+ }
+ }
+ if (count % MAX_NUMERIC_CODEWORDS == 0 ||
+ code == NUMERIC_COMPACTION_MODE_LATCH ||
+ end) {
+ CFX_ByteString s = decodeBase900toBase10(numericCodewords, count, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ result += s;
+ count = 0;
+ }
+ }
+ return codeIndex;
+}
+CFX_ByteString CBC_DecodedBitStreamPaser::decodeBase900toBase10(CFX_Int32Array &codewords, FX_INT32 count, FX_INT32 &e)
+{
+ FX_INT32 result = 0;
+ for (FX_INT32 i = 0; i < count; i++) {
+ result += EXP900[count - i - 1] * codewords[i];
+ }
+ CFX_ByteString resultString;
+ resultString = resultString.FormatInteger(result);
+ if (resultString.GetAt(0) != '1') {
+ e = BCExceptionFormatInstance;
+ return ' ';
+ }
+ return resultString.Mid(1, resultString.GetLength() - 1);
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417DetectionResult.cpp b/xfa/src/fxbarcode/src/BC_PDF417DetectionResult.cpp
new file mode 100644
index 0000000000..3d5faed1f9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417DetectionResult.cpp
@@ -0,0 +1,267 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Codeword.h"
+#include "include/BC_PDF417BarcodeMetadata.h"
+#include "include/BC_PDF417BoundingBox.h"
+#include "include/BC_PDF417DetectionResultColumn.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417DetectionResultRowIndicatorColumn.h"
+#include "include/BC_PDF417DetectionResult.h"
+FX_INT32 CBC_DetectionResult::ADJUST_ROW_NUMBER_SKIP = 2;
+CBC_DetectionResult::CBC_DetectionResult(CBC_BarcodeMetadata* barcodeMetadata, CBC_BoundingBox* boundingBox)
+{
+ m_barcodeMetadata = barcodeMetadata;
+ m_barcodeColumnCount = barcodeMetadata->getColumnCount();
+ m_boundingBox = boundingBox;
+ m_detectionResultColumns.SetSize(m_barcodeColumnCount + 2);
+ for (FX_INT32 i = 0; i < m_barcodeColumnCount + 2; i++) {
+ m_detectionResultColumns[i] = NULL;
+ }
+}
+CBC_DetectionResult::~CBC_DetectionResult()
+{
+ delete m_boundingBox;
+ delete m_barcodeMetadata;
+ m_detectionResultColumns.RemoveAll();
+}
+CFX_PtrArray& CBC_DetectionResult::getDetectionResultColumns()
+{
+ adjustIndicatorColumnRowNumbers((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0));
+ adjustIndicatorColumnRowNumbers((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(m_barcodeColumnCount + 1));
+ FX_INT32 unadjustedCodewordCount = CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE;
+ FX_INT32 previousUnadjustedCount;
+ do {
+ previousUnadjustedCount = unadjustedCodewordCount;
+ unadjustedCodewordCount = adjustRowNumbers();
+ } while (unadjustedCodewordCount > 0 && unadjustedCodewordCount < previousUnadjustedCount);
+ return m_detectionResultColumns;
+}
+void CBC_DetectionResult::setBoundingBox(CBC_BoundingBox* boundingBox)
+{
+ m_boundingBox = boundingBox;
+}
+CBC_BoundingBox* CBC_DetectionResult::getBoundingBox()
+{
+ return m_boundingBox;
+}
+void CBC_DetectionResult::setDetectionResultColumn(FX_INT32 barcodeColumn, CBC_DetectionResultColumn* detectionResultColumn)
+{
+ m_detectionResultColumns[barcodeColumn] = detectionResultColumn;
+}
+CBC_DetectionResultColumn* CBC_DetectionResult::getDetectionResultColumn(FX_INT32 barcodeColumn)
+{
+ return (CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn];
+}
+CFX_ByteString CBC_DetectionResult::toString()
+{
+ CBC_DetectionResultColumn* rowIndicatorColumn = (CBC_DetectionResultColumn*)m_detectionResultColumns[0];
+ if (rowIndicatorColumn == NULL) {
+ rowIndicatorColumn = (CBC_DetectionResultColumn*)m_detectionResultColumns[m_barcodeColumnCount + 1];
+ }
+ CFX_ByteString result;
+ for (FX_INT32 codewordsRow = 0; codewordsRow < rowIndicatorColumn->getCodewords()->GetSize(); codewordsRow++) {
+ result += (FX_CHAR) codewordsRow;
+ for (FX_INT32 barcodeColumn = 0; barcodeColumn < m_barcodeColumnCount + 2; barcodeColumn++) {
+ if (m_detectionResultColumns[barcodeColumn] == NULL) {
+ result += " | ";
+ continue;
+ }
+ CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->GetAt(codewordsRow);
+ if (codeword == NULL) {
+ result += " | ";
+ continue;
+ }
+ result += codeword->getRowNumber();
+ result += codeword->getValue();
+ }
+ }
+ return result;
+}
+void CBC_DetectionResult::adjustIndicatorColumnRowNumbers(CBC_DetectionResultColumn* detectionResultColumn)
+{
+ if (detectionResultColumn != NULL) {
+ ((CBC_DetectionResultRowIndicatorColumn*)detectionResultColumn)->adjustCompleteIndicatorColumnRowNumbers(*m_barcodeMetadata);
+ }
+}
+FX_INT32 CBC_DetectionResult::adjustRowNumbers()
+{
+ FX_INT32 unadjustedCount = adjustRowNumbersByRow();
+ if (unadjustedCount == 0) {
+ return 0;
+ }
+ for (FX_INT32 barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1; barcodeColumn++) {
+ CFX_PtrArray* codewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords();
+ for (FX_INT32 codewordsRow = 0; codewordsRow < codewords->GetSize(); codewordsRow++) {
+ if (codewords->GetAt(codewordsRow) == NULL) {
+ continue;
+ }
+ if (!((CBC_Codeword*)codewords->GetAt(codewordsRow))->hasValidRowNumber()) {
+ adjustRowNumbers(barcodeColumn, codewordsRow, codewords);
+ }
+ }
+ }
+ return unadjustedCount;
+}
+FX_INT32 CBC_DetectionResult::adjustRowNumbersByRow()
+{
+ adjustRowNumbersFromBothRI();
+ FX_INT32 unadjustedCount = adjustRowNumbersFromLRI();
+ return unadjustedCount + adjustRowNumbersFromRRI();
+}
+FX_INT32 CBC_DetectionResult::adjustRowNumbersFromBothRI()
+{
+ if (m_detectionResultColumns[0] == NULL || m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) {
+ return 0;
+ }
+ CFX_PtrArray* LRIcodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[0])->getCodewords();
+ CFX_PtrArray* RRIcodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[m_barcodeColumnCount + 1])->getCodewords();
+ for (FX_INT32 codewordsRow = 0; codewordsRow < LRIcodewords->GetSize(); codewordsRow++) {
+ if (LRIcodewords->GetAt(codewordsRow) != NULL &&
+ RRIcodewords->GetAt(codewordsRow) != NULL &&
+ ((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber() == ((CBC_Codeword*)RRIcodewords->GetAt(codewordsRow))->getRowNumber()) {
+ for (FX_INT32 barcodeColumn = 1; barcodeColumn <= m_barcodeColumnCount; barcodeColumn++) {
+ CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->GetAt(codewordsRow);
+ if (codeword == NULL) {
+ continue;
+ }
+ codeword->setRowNumber(((CBC_Codeword*)LRIcodewords->GetAt(codewordsRow))->getRowNumber());
+ if (!codeword->hasValidRowNumber()) {
+ ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->SetAt(codewordsRow, NULL);
+ }
+ }
+ }
+ }
+ return 0;
+}
+FX_INT32 CBC_DetectionResult::adjustRowNumbersFromRRI()
+{
+ if (m_detectionResultColumns[m_barcodeColumnCount + 1] == NULL) {
+ return 0;
+ }
+ FX_INT32 unadjustedCount = 0;
+ CFX_PtrArray* codewords = ((CBC_DetectionResultColumn*) m_detectionResultColumns.GetAt(m_barcodeColumnCount + 1))->getCodewords();
+ for (FX_INT32 codewordsRow = 0; codewordsRow < codewords->GetSize(); codewordsRow++) {
+ if (codewords->GetAt(codewordsRow) == NULL) {
+ continue;
+ }
+ FX_INT32 rowIndicatorRowNumber = ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber();
+ FX_INT32 invalidRowCounts = 0;
+ for (FX_INT32 barcodeColumn = m_barcodeColumnCount + 1; barcodeColumn > 0 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn--) {
+ CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(barcodeColumn))->getCodewords()->GetAt(codewordsRow);
+ if (codeword != NULL) {
+ invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
+ if (!codeword->hasValidRowNumber()) {
+ unadjustedCount++;
+ }
+ }
+ }
+ }
+ return unadjustedCount;
+}
+FX_INT32 CBC_DetectionResult::adjustRowNumbersFromLRI()
+{
+ if (m_detectionResultColumns[0] == NULL) {
+ return 0;
+ }
+ FX_INT32 unadjustedCount = 0;
+ CFX_PtrArray* codewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(0))->getCodewords();
+ for (FX_INT32 codewordsRow = 0; codewordsRow < codewords->GetSize(); codewordsRow++) {
+ if (codewords->GetAt(codewordsRow) == NULL) {
+ continue;
+ }
+ FX_INT32 rowIndicatorRowNumber = ((CBC_Codeword*)codewords->GetAt(codewordsRow))->getRowNumber();
+ FX_INT32 invalidRowCounts = 0;
+ for (FX_INT32 barcodeColumn = 1; barcodeColumn < m_barcodeColumnCount + 1 && invalidRowCounts < ADJUST_ROW_NUMBER_SKIP; barcodeColumn++) {
+ CBC_Codeword* codeword = (CBC_Codeword*)((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn])->getCodewords()->GetAt(codewordsRow);
+ if (codeword != NULL) {
+ invalidRowCounts = adjustRowNumberIfValid(rowIndicatorRowNumber, invalidRowCounts, codeword);
+ if (!codeword->hasValidRowNumber()) {
+ unadjustedCount++;
+ }
+ }
+ }
+ }
+ return unadjustedCount;
+}
+FX_INT32 CBC_DetectionResult::adjustRowNumberIfValid(FX_INT32 rowIndicatorRowNumber, FX_INT32 invalidRowCounts, CBC_Codeword* codeword)
+{
+ if (codeword == NULL) {
+ return invalidRowCounts;
+ }
+ if (!codeword->hasValidRowNumber()) {
+ if (codeword->isValidRowNumber(rowIndicatorRowNumber)) {
+ codeword->setRowNumber(rowIndicatorRowNumber);
+ invalidRowCounts = 0;
+ } else {
+ ++invalidRowCounts;
+ }
+ }
+ return invalidRowCounts;
+}
+void CBC_DetectionResult::adjustRowNumbers(FX_INT32 barcodeColumn, FX_INT32 codewordsRow, CFX_PtrArray* codewords)
+{
+ CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow);
+ CFX_PtrArray* previousColumnCodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns.GetAt(barcodeColumn - 1))->getCodewords();
+ CFX_PtrArray* nextColumnCodewords = previousColumnCodewords;
+ if (m_detectionResultColumns[barcodeColumn + 1] != NULL) {
+ nextColumnCodewords = ((CBC_DetectionResultColumn*)m_detectionResultColumns[barcodeColumn + 1])->getCodewords();
+ }
+ CFX_PtrArray otherCodewords;
+ otherCodewords.SetSize(14);
+ otherCodewords[2] = previousColumnCodewords->GetAt(codewordsRow);
+ otherCodewords[3] = nextColumnCodewords->GetAt(codewordsRow);
+ if (codewordsRow > 0) {
+ otherCodewords[0] = codewords->GetAt(codewordsRow - 1);
+ otherCodewords[4] = previousColumnCodewords->GetAt(codewordsRow - 1);
+ otherCodewords[5] = nextColumnCodewords->GetAt(codewordsRow - 1);
+ }
+ if (codewordsRow > 1) {
+ otherCodewords[8] = codewords->GetAt(codewordsRow - 2);
+ otherCodewords[10] = previousColumnCodewords->GetAt(codewordsRow - 2);
+ otherCodewords[11] = nextColumnCodewords->GetAt(codewordsRow - 2);
+ }
+ if (codewordsRow < codewords->GetSize() - 1) {
+ otherCodewords[1] = codewords->GetAt(codewordsRow + 1);
+ otherCodewords[6] = previousColumnCodewords->GetAt(codewordsRow + 1);
+ otherCodewords[7] = nextColumnCodewords->GetAt(codewordsRow + 1);
+ }
+ if (codewordsRow < codewords->GetSize() - 2) {
+ otherCodewords[9] = codewords->GetAt(codewordsRow + 2);
+ otherCodewords[12] = previousColumnCodewords->GetAt(codewordsRow + 2);
+ otherCodewords[13] = nextColumnCodewords->GetAt(codewordsRow + 2);
+ }
+ for (FX_INT32 i = 0; i < otherCodewords.GetSize(); i++) {
+ CBC_Codeword* otherCodeword = (CBC_Codeword*)otherCodewords.GetAt(i);
+ if (adjustRowNumber(codeword, otherCodeword)) {
+ return;
+ }
+ }
+}
+FX_BOOL CBC_DetectionResult::adjustRowNumber(CBC_Codeword* codeword, CBC_Codeword* otherCodeword)
+{
+ if (otherCodeword == NULL) {
+ return FALSE;
+ }
+ if (otherCodeword->hasValidRowNumber() && otherCodeword->getBucket() == codeword->getBucket()) {
+ codeword->setRowNumber(otherCodeword->getRowNumber());
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_INT32 CBC_DetectionResult::getBarcodeColumnCount()
+{
+ return m_barcodeColumnCount;
+}
+FX_INT32 CBC_DetectionResult::getBarcodeRowCount()
+{
+ return m_barcodeMetadata->getRowCount();
+}
+FX_INT32 CBC_DetectionResult::getBarcodeECLevel()
+{
+ return m_barcodeMetadata->getErrorCorrectionLevel();
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417DetectionResultColumn.cpp b/xfa/src/fxbarcode/src/BC_PDF417DetectionResultColumn.cpp
new file mode 100644
index 0000000000..63cbc581cb
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417DetectionResultColumn.cpp
@@ -0,0 +1,91 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Codeword.h"
+#include "include/BC_PDF417BoundingBox.h"
+#include "include/BC_PDF417DetectionResultColumn.h"
+FX_INT32 CBC_DetectionResultColumn::MAX_NEARBY_DISTANCE = 5;
+CBC_DetectionResultColumn::CBC_DetectionResultColumn(CBC_BoundingBox* boundingBox)
+{
+ m_boundingBox = boundingBox;
+ m_codewords = FX_NEW CFX_PtrArray;
+ m_codewords->SetSize(boundingBox->getMaxY() - boundingBox->getMinY() + 1);
+}
+CBC_DetectionResultColumn::~CBC_DetectionResultColumn()
+{
+ for (FX_INT32 i = 0; i < m_codewords->GetSize(); i++) {
+ delete (CBC_Codeword*)m_codewords->GetAt(i);
+ }
+ m_codewords->RemoveAll();
+ delete m_codewords;
+}
+CBC_Codeword* CBC_DetectionResultColumn::getCodewordNearby(FX_INT32 imageRow)
+{
+ CBC_Codeword* codeword = getCodeword(imageRow);
+ if (codeword != NULL) {
+ return codeword;
+ }
+ for (FX_INT32 i = 1; i < MAX_NEARBY_DISTANCE; i++) {
+ FX_INT32 nearImageRow = imageRowToCodewordIndex(imageRow) - i;
+ if (nearImageRow >= 0) {
+ codeword = (CBC_Codeword*)m_codewords->GetAt(nearImageRow);
+ if (codeword != NULL) {
+ return codeword;
+ }
+ }
+ nearImageRow = imageRowToCodewordIndex(imageRow) + i;
+ if (nearImageRow < m_codewords->GetSize()) {
+ codeword = (CBC_Codeword*)m_codewords->GetAt(nearImageRow);
+ if (codeword != NULL) {
+ return codeword;
+ }
+ }
+ }
+ return NULL;
+}
+FX_INT32 CBC_DetectionResultColumn::imageRowToCodewordIndex(FX_INT32 imageRow)
+{
+ return imageRow - m_boundingBox->getMinY();
+}
+FX_INT32 CBC_DetectionResultColumn::codewordIndexToImageRow(FX_INT32 codewordIndex)
+{
+ return m_boundingBox->getMinY() + codewordIndex;
+}
+void CBC_DetectionResultColumn::setCodeword(FX_INT32 imageRow, CBC_Codeword* codeword)
+{
+ m_codewords->SetAt(imageRowToCodewordIndex(imageRow), codeword);
+}
+CBC_Codeword* CBC_DetectionResultColumn::getCodeword(FX_INT32 imageRow)
+{
+ return (CBC_Codeword*)m_codewords->GetAt(imageRowToCodewordIndex(imageRow));
+}
+CBC_BoundingBox* CBC_DetectionResultColumn::getBoundingBox()
+{
+ return m_boundingBox;
+}
+CFX_PtrArray* CBC_DetectionResultColumn::getCodewords()
+{
+ return m_codewords;
+}
+CFX_ByteString CBC_DetectionResultColumn::toString()
+{
+ CFX_ByteString result;
+ FX_INT32 row = 0;
+ for (FX_INT32 i = 0; i < m_codewords->GetSize(); i++) {
+ CBC_Codeword* codeword = (CBC_Codeword*)m_codewords->GetAt(i);
+ if (codeword == NULL) {
+ result += (FX_CHAR) row;
+ row++;
+ continue;
+ }
+ result += (FX_CHAR) row;
+ result += codeword->getRowNumber();
+ result += codeword->getValue();
+ row++;
+ }
+ return result;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417DetectionResultRowIndicatorColumn.cpp b/xfa/src/fxbarcode/src/BC_PDF417DetectionResultRowIndicatorColumn.cpp
new file mode 100644
index 0000000000..6220011ccf
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417DetectionResultRowIndicatorColumn.cpp
@@ -0,0 +1,225 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_PDF417BarcodeMetadata.h"
+#include "include/BC_PDF417BoundingBox.h"
+#include "include/BC_PDF417Codeword.h"
+#include "include/BC_PDF417BarcodeValue.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417DetectionResultColumn.h"
+#include "include/BC_PDF417DetectionResultRowIndicatorColumn.h"
+CBC_DetectionResultRowIndicatorColumn::CBC_DetectionResultRowIndicatorColumn(CBC_BoundingBox* boundingBox, FX_BOOL isLeft)
+ : CBC_DetectionResultColumn(boundingBox)
+{
+ m_isLeft = isLeft;
+}
+CBC_DetectionResultRowIndicatorColumn::~CBC_DetectionResultRowIndicatorColumn()
+{
+}
+void CBC_DetectionResultRowIndicatorColumn::setRowNumbers()
+{
+ for (FX_INT32 i = 0; i < m_codewords->GetSize(); i++) {
+ CBC_Codeword * codeword = (CBC_Codeword*)m_codewords->GetAt(i);
+ if (codeword != NULL) {
+ codeword->setRowNumberAsRowIndicatorColumn();
+ }
+ }
+}
+FX_INT32 CBC_DetectionResultRowIndicatorColumn::adjustCompleteIndicatorColumnRowNumbers(CBC_BarcodeMetadata barcodeMetadata)
+{
+ CFX_PtrArray* codewords = getCodewords();
+ setRowNumbers();
+ removeIncorrectCodewords(codewords, barcodeMetadata);
+ CBC_BoundingBox* boundingBox = getBoundingBox();
+ CBC_ResultPoint* top = m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight();
+ CBC_ResultPoint* bottom = m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight();
+ FX_INT32 firstRow = imageRowToCodewordIndex((FX_INT32) top->GetY());
+ FX_INT32 lastRow = imageRowToCodewordIndex((FX_INT32) bottom->GetY());
+ FX_FLOAT averageRowHeight = (lastRow - firstRow) / (FX_FLOAT) barcodeMetadata.getRowCount();
+ FX_INT32 barcodeRow = -1;
+ FX_INT32 maxRowHeight = 1;
+ FX_INT32 currentRowHeight = 0;
+ for (FX_INT32 codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
+ if (codewords->GetAt(codewordsRow) == NULL) {
+ continue;
+ }
+ CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow);
+ FX_INT32 rowDifference = codeword->getRowNumber() - barcodeRow;
+ if (rowDifference == 0) {
+ currentRowHeight++;
+ } else if (rowDifference == 1) {
+ maxRowHeight = maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight;
+ currentRowHeight = 1;
+ barcodeRow = codeword->getRowNumber();
+ } else if (rowDifference < 0) {
+ codewords->SetAt(codewordsRow, NULL);
+ } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) {
+ codewords->SetAt(codewordsRow, NULL);
+ } else if (rowDifference > codewordsRow) {
+ codewords->SetAt(codewordsRow, NULL);
+ } else {
+ FX_INT32 checkedRows;
+ if (maxRowHeight > 2) {
+ checkedRows = (maxRowHeight - 2) * rowDifference;
+ } else {
+ checkedRows = rowDifference;
+ }
+ FX_BOOL closePreviousCodewordFound = checkedRows >= codewordsRow;
+ for (FX_INT32 i = 1; i <= checkedRows && !closePreviousCodewordFound; i++) {
+ closePreviousCodewordFound = codewords->GetAt(codewordsRow - i) != NULL;
+ }
+ if (closePreviousCodewordFound) {
+ codewords->SetAt(codewordsRow, NULL);
+ } else {
+ barcodeRow = codeword->getRowNumber();
+ currentRowHeight = 1;
+ }
+ }
+ }
+ return (FX_INT32) (averageRowHeight + 0.5);
+}
+CFX_Int32Array* CBC_DetectionResultRowIndicatorColumn::getRowHeights(FX_INT32 &e)
+{
+ CBC_BarcodeMetadata* barcodeMetadata = getBarcodeMetadata();
+ if (barcodeMetadata == NULL) {
+ e = BCExceptionCannotMetadata;
+ return NULL;
+ }
+ adjustIncompleteIndicatorColumnRowNumbers(*barcodeMetadata);
+ CFX_Int32Array* result = FX_NEW CFX_Int32Array;
+ result->SetSize(barcodeMetadata->getRowCount());
+ for (FX_INT32 i = 0; i < getCodewords()->GetSize(); i++) {
+ CBC_Codeword* codeword = (CBC_Codeword*)getCodewords()->GetAt(i);
+ if (codeword != NULL) {
+ result->SetAt(codeword->getRowNumber(), result->GetAt(codeword->getRowNumber()) + 1);
+ }
+ }
+ return result;
+}
+FX_INT32 CBC_DetectionResultRowIndicatorColumn::adjustIncompleteIndicatorColumnRowNumbers(CBC_BarcodeMetadata barcodeMetadata)
+{
+ CBC_BoundingBox* boundingBox = getBoundingBox();
+ CBC_ResultPoint* top = m_isLeft ? boundingBox->getTopLeft() : boundingBox->getTopRight();
+ CBC_ResultPoint* bottom = m_isLeft ? boundingBox->getBottomLeft() : boundingBox->getBottomRight();
+ FX_INT32 firstRow = imageRowToCodewordIndex((FX_INT32) top->GetY());
+ FX_INT32 lastRow = imageRowToCodewordIndex((FX_INT32) bottom->GetY());
+ FX_FLOAT averageRowHeight = (lastRow - firstRow) / (FX_FLOAT) barcodeMetadata.getRowCount();
+ CFX_PtrArray* codewords = getCodewords();
+ FX_INT32 barcodeRow = -1;
+ FX_INT32 maxRowHeight = 1;
+ FX_INT32 currentRowHeight = 0;
+ for (FX_INT32 codewordsRow = firstRow; codewordsRow < lastRow; codewordsRow++) {
+ if (codewords->GetAt(codewordsRow) == NULL) {
+ continue;
+ }
+ CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordsRow);
+ codeword->setRowNumberAsRowIndicatorColumn();
+ FX_INT32 rowDifference = codeword->getRowNumber() - barcodeRow;
+ if (rowDifference == 0) {
+ currentRowHeight++;
+ } else if (rowDifference == 1) {
+ maxRowHeight = maxRowHeight > currentRowHeight ? maxRowHeight : currentRowHeight;
+ currentRowHeight = 1;
+ barcodeRow = codeword->getRowNumber();
+ } else if (codeword->getRowNumber() >= barcodeMetadata.getRowCount()) {
+ codewords->SetAt(codewordsRow, NULL);
+ } else {
+ barcodeRow = codeword->getRowNumber();
+ currentRowHeight = 1;
+ }
+ }
+ return (FX_INT32) (averageRowHeight + 0.5);
+}
+CBC_BarcodeMetadata* CBC_DetectionResultRowIndicatorColumn::getBarcodeMetadata()
+{
+ CFX_PtrArray* codewords = getCodewords();
+ CBC_BarcodeValue barcodeColumnCount;
+ CBC_BarcodeValue barcodeRowCountUpperPart;
+ CBC_BarcodeValue barcodeRowCountLowerPart;
+ CBC_BarcodeValue barcodeECLevel;
+ for (FX_INT32 i = 0; i < codewords->GetSize(); i++) {
+ CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(i);
+ if (codeword == NULL) {
+ continue;
+ }
+ codeword->setRowNumberAsRowIndicatorColumn();
+ FX_INT32 rowIndicatorValue = codeword->getValue() % 30;
+ FX_INT32 codewordRowNumber = codeword->getRowNumber();
+ if (!m_isLeft) {
+ codewordRowNumber += 2;
+ }
+ switch (codewordRowNumber % 3) {
+ case 0:
+ barcodeRowCountUpperPart.setValue(rowIndicatorValue * 3 + 1);
+ break;
+ case 1:
+ barcodeECLevel.setValue(rowIndicatorValue / 3);
+ barcodeRowCountLowerPart.setValue(rowIndicatorValue % 3);
+ break;
+ case 2:
+ barcodeColumnCount.setValue(rowIndicatorValue + 1);
+ break;
+ }
+ }
+ if ((barcodeColumnCount.getValue()->GetSize() == 0) ||
+ (barcodeRowCountUpperPart.getValue()->GetSize() == 0) ||
+ (barcodeRowCountLowerPart.getValue()->GetSize() == 0) ||
+ (barcodeECLevel.getValue()->GetSize() == 0) ||
+ barcodeColumnCount.getValue()->GetAt(0) < 1 ||
+ barcodeRowCountUpperPart.getValue()->GetAt(0) + barcodeRowCountLowerPart.getValue()->GetAt(0) < CBC_PDF417Common::MIN_ROWS_IN_BARCODE ||
+ barcodeRowCountUpperPart.getValue()->GetAt(0) + barcodeRowCountLowerPart.getValue()->GetAt(0) > CBC_PDF417Common::MAX_ROWS_IN_BARCODE) {
+ return NULL;
+ }
+ CBC_BarcodeMetadata* barcodeMetadata = FX_NEW CBC_BarcodeMetadata(barcodeColumnCount.getValue()->GetAt(0), barcodeRowCountUpperPart.getValue()->GetAt(0), barcodeRowCountLowerPart.getValue()->GetAt(0), barcodeECLevel.getValue()->GetAt(0));
+ removeIncorrectCodewords(codewords, *barcodeMetadata);
+ return barcodeMetadata;
+}
+FX_BOOL CBC_DetectionResultRowIndicatorColumn::isLeft()
+{
+ return m_isLeft;
+}
+CFX_ByteString CBC_DetectionResultRowIndicatorColumn::toString()
+{
+ return (CFX_ByteString)"IsLeft: " + (CFX_ByteString)m_isLeft + '\n' + CBC_DetectionResultColumn::toString();
+}
+void CBC_DetectionResultRowIndicatorColumn::removeIncorrectCodewords(CFX_PtrArray* codewords, CBC_BarcodeMetadata barcodeMetadata)
+{
+ for (FX_INT32 codewordRow = 0; codewordRow < codewords->GetSize(); codewordRow++) {
+ CBC_Codeword* codeword = (CBC_Codeword*)codewords->GetAt(codewordRow);
+ if (codeword == NULL) {
+ continue;
+ }
+ FX_INT32 rowIndicatorValue = codeword->getValue() % 30;
+ FX_INT32 codewordRowNumber = codeword->getRowNumber();
+ if (codewordRowNumber > barcodeMetadata.getRowCount()) {
+ codewords->SetAt(codewordRow, NULL);
+ continue;
+ }
+ if (!m_isLeft) {
+ codewordRowNumber += 2;
+ }
+ switch (codewordRowNumber % 3) {
+ case 0:
+ if (rowIndicatorValue * 3 + 1 != barcodeMetadata.getRowCountUpperPart()) {
+ codewords->SetAt(codewordRow, NULL);
+ }
+ break;
+ case 1:
+ if (rowIndicatorValue / 3 != barcodeMetadata.getErrorCorrectionLevel() ||
+ rowIndicatorValue % 3 != barcodeMetadata.getRowCountLowerPart()) {
+ codewords->SetAt(codewordRow, NULL);
+ }
+ break;
+ case 2:
+ if (rowIndicatorValue + 1 != barcodeMetadata.getColumnCount()) {
+ codewords->SetAt(codewordRow, NULL);
+ }
+ break;
+ }
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417Detector.cpp b/xfa/src/fxbarcode/src/BC_PDF417Detector.cpp
new file mode 100644
index 0000000000..c9f67b6d7e
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417Detector.cpp
@@ -0,0 +1,295 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_PDF417DetectorResult.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_PDF417Detector.h"
+#define INTERGER_MAX 2147483647
+FX_INT32 CBC_Detector::INDEXES_START_PATTERN[] = {0, 4, 1, 5};
+FX_INT32 CBC_Detector::INDEXES_STOP_PATTERN[] = {6, 2, 7, 3};
+FX_INT32 CBC_Detector::INTEGER_MATH_SHIFT = 8;
+FX_INT32 CBC_Detector::PATTERN_MATCH_RESULT_SCALE_FACTOR = 1 << INTEGER_MATH_SHIFT;
+FX_INT32 CBC_Detector::MAX_AVG_VARIANCE = (FX_INT32) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.42f);
+FX_INT32 CBC_Detector::MAX_INDIVIDUAL_VARIANCE = (FX_INT32) (PATTERN_MATCH_RESULT_SCALE_FACTOR * 0.8f);
+FX_INT32 CBC_Detector::START_PATTERN[] = {8, 1, 1, 1, 1, 1, 1, 3};
+FX_INT32 CBC_Detector::STOP_PATTERN[] = {7, 1, 1, 3, 1, 1, 1, 2, 1};
+FX_INT32 CBC_Detector::MAX_PIXEL_DRIFT = 3;
+FX_INT32 CBC_Detector::MAX_PATTERN_DRIFT = 5;
+FX_INT32 CBC_Detector::SKIPPED_ROW_COUNT_MAX = 25;
+FX_INT32 CBC_Detector::ROW_STEP = 5;
+FX_INT32 CBC_Detector::BARCODE_MIN_HEIGHT = 10;
+CBC_Detector::CBC_Detector()
+{
+}
+CBC_Detector::~CBC_Detector()
+{
+}
+CBC_PDF417DetectorResult* CBC_Detector::detect(CBC_BinaryBitmap* image, FX_INT32 hints, FX_BOOL multiple, FX_INT32 &e)
+{
+ CBC_CommonBitMatrix* bitMatrix = image->GetBlackMatrix(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CFX_PtrArray* barcodeCoordinates = detect(multiple, bitMatrix);
+ if (barcodeCoordinates->GetSize() == 0) {
+ rotate180(bitMatrix);
+ barcodeCoordinates = detect(multiple, bitMatrix);
+ }
+ if (barcodeCoordinates->GetSize() == 0) {
+ e = BCExceptionUnSupportedBarcode;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_PDF417DetectorResult* detectorResult = FX_NEW CBC_PDF417DetectorResult(bitMatrix, barcodeCoordinates);
+ return detectorResult;
+}
+void CBC_Detector::rotate180(CBC_CommonBitMatrix* bitMatrix)
+{
+ FX_INT32 width = bitMatrix->GetWidth();
+ FX_INT32 height = bitMatrix->GetHeight();
+ CBC_CommonBitArray* firstRowBitArray = FX_NEW CBC_CommonBitArray(width);
+ CBC_CommonBitArray* secondRowBitArray = FX_NEW CBC_CommonBitArray(width);
+ CBC_CommonBitArray* tmpBitArray = FX_NEW CBC_CommonBitArray(width);
+ for (FX_INT32 y = 0; y < (height + 1) >> 1; y++) {
+ CBC_CommonBitArray* temp = bitMatrix->GetRow(height - 1 - y, secondRowBitArray);
+ CBC_CommonBitArray* tempfirstRow = firstRowBitArray;
+ firstRowBitArray = bitMatrix->GetRow(y, tempfirstRow);
+ delete tempfirstRow;
+ CBC_CommonBitArray* row = mirror(temp, tmpBitArray);
+ delete temp;
+ bitMatrix->SetRow(y, row);
+ delete row;
+ CBC_CommonBitArray* rowfirstRow = mirror(firstRowBitArray, tmpBitArray);
+ bitMatrix->SetRow(height - 1 - y, rowfirstRow);
+ delete rowfirstRow;
+ }
+ delete tmpBitArray;
+ delete firstRowBitArray;
+ delete secondRowBitArray;
+}
+CBC_CommonBitArray* CBC_Detector::mirror(CBC_CommonBitArray* input, CBC_CommonBitArray* result)
+{
+ CBC_CommonBitArray* array = FX_NEW CBC_CommonBitArray(result->GetSize());
+ array->Clear();
+ FX_INT32 size = input->GetSize();
+ for (FX_INT32 i = 0; i < size; i++) {
+ if (input->Get(i)) {
+ array->Set(size - 1 - i);
+ }
+ }
+ return array;
+}
+CFX_PtrArray* CBC_Detector::detect(FX_BOOL multiple, CBC_CommonBitMatrix* bitMatrix)
+{
+ CFX_PtrArray* barcodeCoordinates = FX_NEW CFX_PtrArray;
+ FX_INT32 row = 0;
+ FX_INT32 column = 0;
+ FX_BOOL foundBarcodeInRow = FALSE;
+ while (row < bitMatrix->GetHeight()) {
+ CFX_PtrArray* vertices = findVertices(bitMatrix, row, column);
+ if (vertices->GetAt(0) == NULL && vertices->GetAt(3) == NULL) {
+ if (!foundBarcodeInRow) {
+ if (vertices) {
+ delete(vertices);
+ }
+ break;
+ }
+ foundBarcodeInRow = FALSE;
+ column = 0;
+ for (FX_INT32 i = 0; i < barcodeCoordinates->GetSize(); i++) {
+ CFX_PtrArray* barcodeCoordinate = (CFX_PtrArray*)barcodeCoordinates->GetAt(i);
+ if (barcodeCoordinate->GetAt(1) != NULL) {
+ row = row > ((CBC_ResultPoint*)barcodeCoordinate->GetAt(1))->GetY();
+ }
+ if (barcodeCoordinate->GetAt(3) != NULL) {
+ row = row > ((CBC_ResultPoint*)barcodeCoordinate->GetAt(3))->GetY();
+ }
+ }
+ row += ROW_STEP;
+ if (vertices) {
+ delete(vertices);
+ }
+ continue;
+ }
+ foundBarcodeInRow = TRUE;
+ barcodeCoordinates->Add(vertices);
+ if (!multiple) {
+ break;
+ }
+ if (vertices->GetAt(2) != NULL) {
+ column = (FX_INT32) ((CBC_ResultPoint*)vertices->GetAt(2))->GetX();
+ row = (FX_INT32) ((CBC_ResultPoint*)vertices->GetAt(2))->GetY();
+ } else {
+ column = (FX_INT32) ((CBC_ResultPoint*)vertices->GetAt(4))->GetX();
+ row = (FX_INT32) ((CBC_ResultPoint*)vertices->GetAt(4))->GetY();
+ }
+ }
+ return barcodeCoordinates;
+}
+CFX_PtrArray* CBC_Detector::findVertices(CBC_CommonBitMatrix* matrix, FX_INT32 startRow, FX_INT32 startColumn)
+{
+ FX_INT32 height = matrix->GetHeight();
+ FX_INT32 width = matrix->GetWidth();
+ CFX_PtrArray* result = FX_NEW CFX_PtrArray;
+ result->SetSize(8);
+ CFX_PtrArray* startptr = findRowsWithPattern(matrix, height, width, startRow, startColumn, START_PATTERN, sizeof(START_PATTERN) / sizeof(START_PATTERN[0]));
+ copyToResult(result, startptr, INDEXES_START_PATTERN, sizeof(INDEXES_START_PATTERN) / sizeof(INDEXES_START_PATTERN[0]));
+ startptr->RemoveAll();
+ delete startptr;
+ if (result->GetAt(4) != NULL) {
+ startColumn = (FX_INT32) ((CBC_ResultPoint*)result->GetAt(4))->GetX();
+ startRow = (FX_INT32) ((CBC_ResultPoint*)result->GetAt(4))->GetY();
+ }
+ CFX_PtrArray* stopptr = findRowsWithPattern(matrix, height, width, startRow, startColumn, STOP_PATTERN, sizeof(STOP_PATTERN) / sizeof(STOP_PATTERN[0]));
+ copyToResult(result, stopptr, INDEXES_STOP_PATTERN, sizeof(INDEXES_STOP_PATTERN) / sizeof(INDEXES_STOP_PATTERN[0]));
+ stopptr->RemoveAll();
+ delete stopptr;
+ return result;
+}
+void CBC_Detector::copyToResult(CFX_PtrArray *result, CFX_PtrArray* tmpResult, FX_INT32* destinationIndexes, FX_INT32 destinationLength)
+{
+ for (FX_INT32 i = 0; i < destinationLength; i++) {
+ result->SetAt(destinationIndexes[i], tmpResult->GetAt(i));
+ }
+}
+CFX_PtrArray* CBC_Detector::findRowsWithPattern(CBC_CommonBitMatrix* matrix, FX_INT32 height, FX_INT32 width, FX_INT32 startRow, FX_INT32 startColumn, FX_INT32* pattern, FX_INT32 patternLength)
+{
+ CFX_PtrArray* result = FX_NEW CFX_PtrArray;
+ result->SetSize(4);
+ FX_BOOL found = FALSE;
+ CFX_Int32Array counters;
+ counters.SetSize(patternLength);
+ for (; startRow < height; startRow += ROW_STEP) {
+ CFX_Int32Array* loc = findGuardPattern(matrix, startColumn, startRow, width, FALSE, pattern, patternLength, counters);
+ if (loc != NULL) {
+ while (startRow > 0) {
+ CFX_Int32Array* previousRowLoc = findGuardPattern(matrix, startColumn, --startRow, width, FALSE, pattern, patternLength, counters);
+ if (previousRowLoc != NULL) {
+ delete loc;
+ loc = previousRowLoc;
+ } else {
+ startRow++;
+ break;
+ }
+ }
+ result->SetAt(0, FX_NEW CBC_ResultPoint((FX_FLOAT)loc->GetAt(0), (FX_FLOAT)startRow));
+ result->SetAt(1, FX_NEW CBC_ResultPoint((FX_FLOAT)loc->GetAt(1), (FX_FLOAT)startRow));
+ found = TRUE;
+ delete loc;
+ break;
+ }
+ }
+ FX_INT32 stopRow = startRow + 1;
+ if (found) {
+ FX_INT32 skippedRowCount = 0;
+ CFX_Int32Array previousRowLoc;
+ previousRowLoc.Add((FX_INT32)((CBC_ResultPoint*)result->GetAt(0))->GetX());
+ previousRowLoc.Add((FX_INT32)((CBC_ResultPoint*)result->GetAt(1))->GetX());
+ for (; stopRow < height; stopRow++) {
+ CFX_Int32Array* loc = findGuardPattern(matrix, previousRowLoc[0], stopRow, width, FALSE, pattern, patternLength, counters);
+ if (loc != NULL &&
+ abs(previousRowLoc[0] - loc->GetAt(0)) < MAX_PATTERN_DRIFT &&
+ abs(previousRowLoc[1] - loc->GetAt(1)) < MAX_PATTERN_DRIFT) {
+ previousRowLoc.Copy(*loc);
+ skippedRowCount = 0;
+ } else {
+ if (skippedRowCount > SKIPPED_ROW_COUNT_MAX) {
+ delete loc;
+ break;
+ } else {
+ skippedRowCount++;
+ }
+ }
+ delete loc;
+ }
+ stopRow -= skippedRowCount + 1;
+ result->SetAt(2, FX_NEW CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(0), (FX_FLOAT)stopRow));
+ result->SetAt(3, FX_NEW CBC_ResultPoint((FX_FLOAT)previousRowLoc.GetAt(1), (FX_FLOAT)stopRow));
+ }
+ if (stopRow - startRow < BARCODE_MIN_HEIGHT) {
+ for (FX_INT32 i = 0; i < result->GetSize(); i++) {
+ result->SetAt(i, NULL);
+ }
+ }
+ return result;
+}
+CFX_Int32Array* CBC_Detector::findGuardPattern(CBC_CommonBitMatrix* matrix, FX_INT32 column, FX_INT32 row, FX_INT32 width, FX_BOOL whiteFirst, FX_INT32* pattern, FX_INT32 patternLength, CFX_Int32Array &counters)
+{
+ for (FX_INT32 i = 0; i < counters.GetSize(); i++) {
+ counters.SetAt(i, 0);
+ }
+ FX_BOOL isWhite = whiteFirst;
+ FX_INT32 patternStart = column;
+ FX_INT32 pixelDrift = 0;
+ CFX_Int32Array* intarray = FX_NEW CFX_Int32Array;
+ while (matrix->Get(patternStart, row) && patternStart > 0 && pixelDrift++ < MAX_PIXEL_DRIFT) {
+ patternStart--;
+ }
+ FX_INT32 x = patternStart;
+ FX_INT32 counterPosition = 0;
+ for (; x < width; x++) {
+ FX_BOOL pixel = matrix->Get(x, row);
+ if (pixel ^ isWhite) {
+ counters[counterPosition]++;
+ } else {
+ if (counterPosition == patternLength - 1) {
+ if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
+ intarray->Add(patternStart);
+ intarray->Add(x);
+ return intarray;
+ }
+ patternStart += counters[0] + counters[1];
+ for (FX_INT32 l = 2, k = 0; l < patternLength; l++, k++) {
+ counters.SetAt(k, counters.GetAt(l));
+ }
+ counters.SetAt(patternLength - 2, 0);
+ counters.SetAt(patternLength - 1, 0);
+ counterPosition--;
+ } else {
+ counterPosition++;
+ }
+ counters[counterPosition] = 1;
+ isWhite = !isWhite;
+ }
+ }
+ if (counterPosition == patternLength - 1) {
+ if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
+ intarray->Add(patternStart);
+ intarray->Add(x - 1);
+ return intarray;
+ }
+ }
+ delete intarray;
+ return NULL;
+}
+FX_INT32 CBC_Detector::patternMatchVariance(CFX_Int32Array &counters, FX_INT32* pattern, FX_INT32 maxIndividualVariance)
+{
+ FX_INT32 numCounters = counters.GetSize();
+ FX_INT32 total = 0;
+ FX_INT32 patternLength = 0;
+ for (FX_INT32 i = 0; i < numCounters; i++) {
+ total += counters[i];
+ patternLength += pattern[i];
+ }
+ if (total < patternLength) {
+ return INTERGER_MAX;
+ }
+ FX_INT32 unitBarWidth = (total << INTEGER_MATH_SHIFT) / patternLength;
+ maxIndividualVariance = (maxIndividualVariance * unitBarWidth) >> INTEGER_MATH_SHIFT;
+ FX_INT32 totalVariance = 0;
+ for (FX_INT32 x = 0; x < numCounters; x++) {
+ FX_INT32 counter = counters[x] << INTEGER_MATH_SHIFT;
+ FX_INT32 scaledPattern = pattern[x] * unitBarWidth;
+ FX_INT32 variance = counter > scaledPattern ? counter - scaledPattern : scaledPattern - counter;
+ if (variance > maxIndividualVariance) {
+ return INTERGER_MAX;
+ }
+ totalVariance += variance;
+ }
+ return totalVariance / total;
+}
+
diff --git a/xfa/src/fxbarcode/src/BC_PDF417DetectorResult.cpp b/xfa/src/fxbarcode/src/BC_PDF417DetectorResult.cpp
new file mode 100644
index 0000000000..cf51f9e38b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417DetectorResult.cpp
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_PDF417DetectorResult.h"
+CBC_PDF417DetectorResult::CBC_PDF417DetectorResult(CBC_CommonBitMatrix* bits, CFX_PtrArray* points)
+{
+ m_bits = bits;
+ m_points = points;
+}
+CBC_PDF417DetectorResult::~CBC_PDF417DetectorResult()
+{
+ for (FX_INT32 i = 0; i < m_points->GetSize(); i++) {
+ CFX_PtrArray* temp = (CFX_PtrArray*)m_points->GetAt(i);
+ for (FX_INT32 j = 0; j < temp->GetSize(); j++) {
+ delete (CBC_ResultPoint*)temp->GetAt(j);
+ }
+ temp->RemoveAll();
+ delete temp;
+ }
+ m_points->RemoveAll();
+ delete m_points;
+}
+CBC_CommonBitMatrix* CBC_PDF417DetectorResult::getBits()
+{
+ return m_bits;
+}
+
+CFX_PtrArray* CBC_PDF417DetectorResult::getPoints()
+{
+ return m_points;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417Dimensions.cpp b/xfa/src/fxbarcode/src/BC_PDF417Dimensions.cpp
new file mode 100644
index 0000000000..7f5400a8ec
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417Dimensions.cpp
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Dimensions.h"
+CBC_Dimensions::CBC_Dimensions(FX_INT32 minCols, FX_INT32 maxCols, FX_INT32 minRows, FX_INT32 maxRows)
+{
+ m_minCols = minCols;
+ m_maxCols = maxCols;
+ m_minRows = minRows;
+ m_maxRows = maxRows;
+}
+CBC_Dimensions::~CBC_Dimensions()
+{
+}
+FX_INT32 CBC_Dimensions::getMinCols()
+{
+ return m_minCols;
+}
+FX_INT32 CBC_Dimensions::getMaxCols()
+{
+ return m_maxCols;
+}
+FX_INT32 CBC_Dimensions::getMinRows()
+{
+ return m_minRows;
+}
+FX_INT32 CBC_Dimensions::getMaxRows()
+{
+ return m_maxRows;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417ECErrorCorrection.cpp b/xfa/src/fxbarcode/src/BC_PDF417ECErrorCorrection.cpp
new file mode 100644
index 0000000000..3d22d77c3d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417ECErrorCorrection.cpp
@@ -0,0 +1,353 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417ECModulusPoly.h"
+#include "include/BC_PDF417ECModulusGF.h"
+#include "include/BC_PDF417ECErrorCorrection.h"
+CBC_PDF417ECModulusGF* CBC_PDF417ECErrorCorrection::m_field = NULL;
+void CBC_PDF417ECErrorCorrection::Initialize(FX_INT32 &e)
+{
+ m_field = FX_NEW CBC_PDF417ECModulusGF(CBC_PDF417Common::NUMBER_OF_CODEWORDS, 3, e);
+}
+void CBC_PDF417ECErrorCorrection::Finalize()
+{
+ delete m_field;
+}
+CBC_PDF417ECErrorCorrection::CBC_PDF417ECErrorCorrection()
+{
+}
+CBC_PDF417ECErrorCorrection::~CBC_PDF417ECErrorCorrection()
+{
+}
+FX_INT32 CBC_PDF417ECErrorCorrection::decode(CFX_Int32Array &received, FX_INT32 numECCodewords, CFX_Int32Array &erasures, FX_INT32 &e)
+{
+ CBC_PDF417ECModulusPoly poly(m_field, received, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ CFX_Int32Array S;
+ S.SetSize(numECCodewords);
+ FX_BOOL error = FALSE;
+ for (FX_INT32 l = numECCodewords; l > 0; l--) {
+ FX_INT32 eval = poly.evaluateAt(m_field->exp(l));
+ S[numECCodewords - l] = eval;
+ if (eval != 0) {
+ error = TRUE;
+ }
+ }
+ if (!error) {
+ return 0;
+ }
+ CBC_PDF417ECModulusPoly* syndrome = FX_NEW CBC_PDF417ECModulusPoly(m_field, S, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ CBC_PDF417ECModulusPoly* buildmonomial = m_field->buildMonomial(numECCodewords, 1, e);
+ if (e != BCExceptionNO) {
+ delete syndrome;
+ return -1;
+ }
+ CFX_PtrArray* sigmaOmega = runEuclideanAlgorithm(buildmonomial, syndrome, numECCodewords, e);
+ delete buildmonomial;
+ delete syndrome;
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ CBC_PDF417ECModulusPoly* sigma = (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(0);
+ CBC_PDF417ECModulusPoly* omega = (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(1);
+ CFX_Int32Array* errorLocations = findErrorLocations(sigma, e);
+ if (e != BCExceptionNO) {
+ for (FX_INT32 i = 0; i < sigmaOmega->GetSize(); i++) {
+ delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(i);
+ }
+ sigmaOmega->RemoveAll();
+ delete sigmaOmega;
+ return -1;
+ }
+ CFX_Int32Array* errorMagnitudes = findErrorMagnitudes(omega, sigma, *errorLocations, e);
+ if (e != BCExceptionNO) {
+ delete errorLocations;
+ for (FX_INT32 i = 0; i < sigmaOmega->GetSize(); i++) {
+ delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(i);
+ }
+ sigmaOmega->RemoveAll();
+ delete sigmaOmega;
+ return -1;
+ }
+ for (FX_INT32 i = 0; i < errorLocations->GetSize(); i++) {
+ FX_INT32 log = m_field->log(errorLocations->GetAt(i), e);;
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ FX_INT32 position = received.GetSize() - 1 - log;
+ if (position < 0) {
+ e = BCExceptionChecksumException;
+ delete errorLocations;
+ delete errorMagnitudes;
+ for (FX_INT32 j = 0; j < sigmaOmega->GetSize(); j++) {
+ delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(j);
+ }
+ sigmaOmega->RemoveAll();
+ delete sigmaOmega;
+ return -1;
+ }
+ received[position] = m_field->subtract(received[position], errorMagnitudes->GetAt(i));
+ }
+ FX_INT32 result = errorLocations->GetSize();
+ delete errorLocations;
+ delete errorMagnitudes;
+ for (FX_INT32 k = 0; k < sigmaOmega->GetSize(); k++) {
+ delete (CBC_PDF417ECModulusPoly*)sigmaOmega->GetAt(k);
+ }
+ sigmaOmega->RemoveAll();
+ delete sigmaOmega;
+ return result;
+}
+CFX_PtrArray* CBC_PDF417ECErrorCorrection::runEuclideanAlgorithm(CBC_PDF417ECModulusPoly* a, CBC_PDF417ECModulusPoly* b, FX_INT32 R, FX_INT32 &e)
+{
+ if (a->getDegree() < b->getDegree()) {
+ CBC_PDF417ECModulusPoly* temp = a;
+ a = b;
+ b = temp;
+ }
+ CBC_PDF417ECModulusPoly* rLast = a;
+ CBC_PDF417ECModulusPoly* r = b;
+ CBC_PDF417ECModulusPoly* tLast = m_field->getZero();
+ CBC_PDF417ECModulusPoly* t = m_field->getOne();
+ CBC_PDF417ECModulusPoly* qtemp = NULL;
+ CBC_PDF417ECModulusPoly* rtemp = NULL;
+ CBC_PDF417ECModulusPoly* ttemp = NULL;
+ FX_INT32 i = 0;
+ FX_INT32 j = 0;
+ FX_INT32 m = 0;
+ FX_INT32 n = 0;
+ while (r->getDegree() >= R / 2) {
+ CBC_PDF417ECModulusPoly* rLastLast = rLast;
+ CBC_PDF417ECModulusPoly* tLastLast = tLast;
+ rLast = r;
+ tLast = t;
+ m = i;
+ n = j;
+ if (rLast->isZero()) {
+ e = BCExceptionChecksumException;
+ if (qtemp) {
+ delete qtemp;
+ }
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ r = rLastLast;
+ CBC_PDF417ECModulusPoly* q = m_field->getZero();
+ FX_INT32 denominatorLeadingTerm = rLast->getCoefficient(rLast->getDegree());
+ FX_INT32 dltInverse = m_field->inverse(denominatorLeadingTerm, e);
+ if (e != BCExceptionNO) {
+ if (qtemp) {
+ delete qtemp;
+ }
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ while (r->getDegree() >= rLast->getDegree() && !r->isZero()) {
+ FX_INT32 degreeDiff = r->getDegree() - rLast->getDegree();
+ FX_INT32 scale = m_field->multiply(r->getCoefficient(r->getDegree()), dltInverse);
+ CBC_PDF417ECModulusPoly* buildmonomial = m_field->buildMonomial(degreeDiff, scale, e);
+ if (e != BCExceptionNO) {
+ if (qtemp) {
+ delete qtemp;
+ }
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ q = q->add(buildmonomial, e);
+ delete buildmonomial;
+ if (qtemp) {
+ delete qtemp;
+ }
+ if (e != BCExceptionNO) {
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ qtemp = q;
+ CBC_PDF417ECModulusPoly* multiply = rLast->multiplyByMonomial(degreeDiff, scale, e);
+ if (e != BCExceptionNO) {
+ if (qtemp) {
+ delete qtemp;
+ }
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* temp = r;
+ r = temp->subtract(multiply, e);
+ delete multiply;
+ if (m > 1 && i > m) {
+ delete temp;
+ temp = NULL;
+ }
+ if (e != BCExceptionNO) {
+ if (qtemp) {
+ delete qtemp;
+ }
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ rtemp = r;
+ i = m + 1;
+ }
+ ttemp = q->multiply(tLast, e);
+ if (qtemp) {
+ delete qtemp;
+ qtemp = NULL;
+ }
+ if (e != BCExceptionNO) {
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ t = ttemp->subtract(tLastLast, e);
+ if (n > 1 && j > n) {
+ delete tLastLast;
+ }
+ delete ttemp;
+ if (e != BCExceptionNO) {
+ if (rtemp) {
+ delete rtemp;
+ }
+ return NULL;
+ }
+ ttemp = t;
+ t = ttemp->negative(e);
+ delete ttemp;
+ if (e != BCExceptionNO) {
+ if (rtemp) {
+ delete rtemp;
+ }
+ return NULL;
+ }
+ ttemp = t;
+ j++;
+ }
+ FX_INT32 aa = t->getCoefficient(1);
+ FX_INT32 sigmaTildeAtZero = t->getCoefficient(0);
+ if (sigmaTildeAtZero == 0) {
+ e = BCExceptionChecksumException;
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ FX_INT32 inverse = m_field->inverse(sigmaTildeAtZero, e);
+ if (e != BCExceptionNO) {
+ if (rtemp) {
+ delete rtemp;
+ }
+ if (ttemp) {
+ delete ttemp;
+ }
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* sigma = t->multiply(inverse, e);
+ if (ttemp) {
+ delete ttemp;
+ }
+ if (e != BCExceptionNO) {
+ if (rtemp) {
+ delete rtemp;
+ }
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* omega = r->multiply(inverse, e);
+ if (rtemp) {
+ delete rtemp;
+ }
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CFX_PtrArray* modulusPoly = FX_NEW CFX_PtrArray;
+ modulusPoly->Add(sigma);
+ modulusPoly->Add(omega);
+ return modulusPoly;
+}
+CFX_Int32Array* CBC_PDF417ECErrorCorrection::findErrorLocations(CBC_PDF417ECModulusPoly* errorLocator, FX_INT32 &e)
+{
+ FX_INT32 numErrors = errorLocator->getDegree();
+ CFX_Int32Array* result = FX_NEW CFX_Int32Array;
+ result->SetSize(numErrors);
+ FX_INT32 ee = 0;
+ for (FX_INT32 i = 1; i < m_field->getSize() && ee < numErrors; i++) {
+ if (errorLocator->evaluateAt(i) == 0) {
+ result->SetAt(ee, m_field->inverse(i, e));
+ if (e != BCExceptionNO) {
+ delete result;
+ return NULL;
+ }
+ ee++;
+ }
+ }
+ if (ee != numErrors) {
+ e = BCExceptionChecksumException;
+ delete result;
+ return NULL;
+ }
+ return result;
+}
+CFX_Int32Array* CBC_PDF417ECErrorCorrection::findErrorMagnitudes(CBC_PDF417ECModulusPoly* errorEvaluator, CBC_PDF417ECModulusPoly* errorLocator, CFX_Int32Array &errorLocations, FX_INT32 &e)
+{
+ FX_INT32 errorLocatorDegree = errorLocator->getDegree();
+ CFX_Int32Array formalDerivativeCoefficients;
+ formalDerivativeCoefficients.SetSize(errorLocatorDegree);
+ for (FX_INT32 l = 1; l <= errorLocatorDegree; l++) {
+ formalDerivativeCoefficients[errorLocatorDegree - l] = m_field->multiply(l, errorLocator->getCoefficient(l));
+ }
+ CBC_PDF417ECModulusPoly formalDerivative(m_field, formalDerivativeCoefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 s = errorLocations.GetSize();
+ CFX_Int32Array* result = FX_NEW CFX_Int32Array;
+ result->SetSize(s);
+ for (FX_INT32 i = 0; i < s; i++) {
+ FX_INT32 xiInverse = m_field->inverse(errorLocations[i], e);
+ if (e != BCExceptionNO) {
+ delete result;
+ return NULL;
+ }
+ FX_INT32 numerator = m_field->subtract(0, errorEvaluator->evaluateAt(xiInverse));
+ FX_INT32 denominator = m_field->inverse(formalDerivative.evaluateAt(xiInverse), e);
+ if (e != BCExceptionNO) {
+ delete result;
+ return NULL;
+ }
+ result->SetAt(i, m_field->multiply(numerator, denominator));
+ }
+ return result;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417ECModulusGF.cpp b/xfa/src/fxbarcode/src/BC_PDF417ECModulusGF.cpp
new file mode 100644
index 0000000000..d3c4f41170
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417ECModulusGF.cpp
@@ -0,0 +1,110 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417ECModulusPoly.h"
+#include "include/BC_PDF417ECModulusGF.h"
+CBC_PDF417ECModulusGF* CBC_PDF417ECModulusGF::PDF417_GF = NULL;
+void CBC_PDF417ECModulusGF::Initialize(FX_INT32 &e)
+{
+ PDF417_GF = FX_NEW CBC_PDF417ECModulusGF(CBC_PDF417Common::NUMBER_OF_CODEWORDS, 3, e);
+}
+void CBC_PDF417ECModulusGF::Finalize()
+{
+ delete PDF417_GF;
+}
+CBC_PDF417ECModulusGF::CBC_PDF417ECModulusGF(FX_INT32 modulus, FX_INT32 generator, FX_INT32 &e)
+{
+ m_modulus = modulus;
+ m_expTable.SetSize(modulus);
+ m_logTable.SetSize(modulus);
+ FX_INT32 x = 1;
+ for (FX_INT32 i = 0; i < modulus; i++) {
+ m_expTable[i] = x;
+ x = (x * generator) % modulus;
+ }
+ for (FX_INT32 j = 0; j < modulus - 1; j++) {
+ m_logTable[m_expTable[j]] = j;
+ }
+ CFX_Int32Array zero;
+ zero.Add(0);
+ m_zero = FX_NEW CBC_PDF417ECModulusPoly(this, zero, e);
+ CFX_Int32Array one;
+ one.Add(1);
+ m_one = FX_NEW CBC_PDF417ECModulusPoly(this, one, e);
+}
+CBC_PDF417ECModulusGF::~CBC_PDF417ECModulusGF()
+{
+ delete m_zero;
+ delete m_one;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusGF::getZero()
+{
+ return m_zero;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusGF::getOne()
+{
+ return m_one;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusGF::buildMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e)
+{
+ if (degree < 0) {
+ e = BCExceptionIllegalArgument;
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* modulusPoly = NULL;
+ if (coefficient == 0) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_zero->getField(), m_zero->getCoefficients(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ CFX_Int32Array coefficients;
+ coefficients.SetSize(degree + 1);
+ coefficients[0] = coefficient;
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(this, coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+}
+FX_INT32 CBC_PDF417ECModulusGF::add(FX_INT32 a, FX_INT32 b)
+{
+ return (a + b) % m_modulus;
+}
+FX_INT32 CBC_PDF417ECModulusGF::subtract(FX_INT32 a, FX_INT32 b)
+{
+ return (m_modulus + a - b) % m_modulus;
+}
+FX_INT32 CBC_PDF417ECModulusGF::exp(FX_INT32 a)
+{
+ return m_expTable[a];
+}
+FX_INT32 CBC_PDF417ECModulusGF::log(FX_INT32 a, FX_INT32 &e)
+{
+ if (a == 0) {
+ e = BCExceptionIllegalArgument;
+ return -1;
+ }
+ return m_logTable[a];
+}
+FX_INT32 CBC_PDF417ECModulusGF::inverse(FX_INT32 a, FX_INT32 &e)
+{
+ if (a == 0) {
+ e = BCExceptionIllegalArgument;
+ return -1;
+ }
+ return m_expTable[m_modulus - m_logTable[a] - 1];
+}
+FX_INT32 CBC_PDF417ECModulusGF::multiply(FX_INT32 a, FX_INT32 b)
+{
+ if (a == 0 || b == 0) {
+ return 0;
+ }
+ return m_expTable[(m_logTable[a] + m_logTable[b]) % (m_modulus - 1)];
+}
+FX_INT32 CBC_PDF417ECModulusGF::getSize()
+{
+ return m_modulus;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417ECModulusPoly.cpp b/xfa/src/fxbarcode/src/BC_PDF417ECModulusPoly.cpp
new file mode 100644
index 0000000000..b57dcc008f
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417ECModulusPoly.cpp
@@ -0,0 +1,300 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417ECModulusGF.h"
+#include "include/BC_PDF417ECModulusPoly.h"
+CBC_PDF417ECModulusPoly::CBC_PDF417ECModulusPoly(CBC_PDF417ECModulusGF* field, CFX_Int32Array &coefficients, FX_INT32 &e)
+{
+ if (coefficients.GetSize() == 0) {
+ e = BCExceptionIllegalArgument;
+ }
+ m_field = field;
+ FX_INT32 coefficientsLength = coefficients.GetSize();
+ if (coefficientsLength > 1 && coefficients[0] == 0) {
+ FX_INT32 firstNonZero = 1;
+ while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0) {
+ firstNonZero++;
+ }
+ if (firstNonZero == coefficientsLength) {
+ m_coefficients = field->getZero()->m_coefficients;
+ } else {
+ m_coefficients.SetSize(coefficientsLength - firstNonZero);
+ FX_INT32 l = 0;
+ for (FX_INT32 i = firstNonZero; i < firstNonZero + m_coefficients.GetSize(); i++) {
+ m_coefficients.SetAt(l, coefficients.GetAt(i));
+ l++;
+ }
+ }
+ } else {
+ m_coefficients.Copy(coefficients);
+ }
+}
+CBC_PDF417ECModulusPoly::~CBC_PDF417ECModulusPoly()
+{
+}
+CFX_Int32Array& CBC_PDF417ECModulusPoly::getCoefficients()
+{
+ return m_coefficients;
+}
+CBC_PDF417ECModulusGF* CBC_PDF417ECModulusPoly::getField()
+{
+ return m_field;
+}
+FX_INT32 CBC_PDF417ECModulusPoly::getDegree()
+{
+ return m_coefficients.GetSize() - 1;
+}
+FX_BOOL CBC_PDF417ECModulusPoly::isZero()
+{
+ return m_coefficients[0] == 0;
+}
+FX_INT32 CBC_PDF417ECModulusPoly::getCoefficient(FX_INT32 degree)
+{
+ return m_coefficients[m_coefficients.GetSize() - 1 - degree];
+}
+FX_INT32 CBC_PDF417ECModulusPoly::evaluateAt(FX_INT32 a)
+{
+ if (a == 0) {
+ return getCoefficient(0);
+ }
+ FX_INT32 size = m_coefficients.GetSize();
+ if (a == 1) {
+ FX_INT32 result = 0;
+ for (FX_INT32 l = 0; l < m_coefficients.GetSize(); l++) {
+ FX_INT32 coefficient = m_coefficients.GetAt(l);
+ result = m_field->add(result, coefficient);
+ }
+ return result;
+ }
+ FX_INT32 result = m_coefficients[0];
+ for (FX_INT32 i = 1; i < size; i++) {
+ result = m_field->add(m_field->multiply(a, result), m_coefficients[i]);
+ }
+ return result;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::add(CBC_PDF417ECModulusPoly* other, FX_INT32 &e)
+{
+ CBC_PDF417ECModulusPoly* modulusPoly = NULL;
+ if (isZero()) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(other->getField(), other->getCoefficients(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ if (other->isZero()) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, m_coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ CFX_Int32Array smallerCoefficients;
+ smallerCoefficients.Copy(m_coefficients);
+ CFX_Int32Array largerCoefficients;
+ largerCoefficients.Copy(other->m_coefficients);
+ if (smallerCoefficients.GetSize() > largerCoefficients.GetSize()) {
+ CFX_Int32Array temp;
+ temp.Copy(smallerCoefficients);
+ smallerCoefficients.Copy(largerCoefficients);
+ largerCoefficients.Copy(temp);
+ }
+ CFX_Int32Array sumDiff;
+ sumDiff.SetSize(largerCoefficients.GetSize());
+ FX_INT32 lengthDiff = largerCoefficients.GetSize() - smallerCoefficients.GetSize();
+ for (FX_INT32 l = 0; l < lengthDiff; l++) {
+ sumDiff.SetAt(l, largerCoefficients.GetAt(l));
+ }
+ for (FX_INT32 i = lengthDiff; i < largerCoefficients.GetSize(); i++) {
+ sumDiff[i] = m_field->add(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
+ }
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, sumDiff, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::subtract(CBC_PDF417ECModulusPoly* other, FX_INT32 &e)
+{
+ CBC_PDF417ECModulusPoly* modulusPoly = NULL;
+ if (other->isZero()) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, m_coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ CBC_PDF417ECModulusPoly* poly = other->negative(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ modulusPoly = add(poly, e);
+ delete poly;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiply(CBC_PDF417ECModulusPoly* other, FX_INT32 &e)
+{
+ CBC_PDF417ECModulusPoly* modulusPoly = NULL;
+ if (isZero() || other->isZero()) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field->getZero()->getField(), m_field->getZero()->getCoefficients(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ CFX_Int32Array aCoefficients;
+ aCoefficients.Copy(m_coefficients);
+ FX_INT32 aLength = aCoefficients.GetSize();
+ CFX_Int32Array bCoefficients;
+ bCoefficients.Copy(other->m_coefficients);
+ FX_INT32 bLength = bCoefficients.GetSize();
+ CFX_Int32Array product;
+ product.SetSize(aLength + bLength - 1);
+ for (FX_INT32 i = 0; i < aLength; i++) {
+ FX_INT32 aCoeff = aCoefficients[i];
+ for (FX_INT32 j = 0; j < bLength; j++) {
+ product[i + j] = m_field->add(product[i + j], m_field->multiply(aCoeff, bCoefficients[j]));
+ }
+ }
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, product, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::negative(FX_INT32 &e)
+{
+ FX_INT32 size = m_coefficients.GetSize();
+ CFX_Int32Array negativeCoefficients;
+ negativeCoefficients.SetSize(size);
+ for (FX_INT32 i = 0; i < size; i++) {
+ negativeCoefficients[i] = m_field->subtract(0, m_coefficients[i]);
+ }
+ CBC_PDF417ECModulusPoly* modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, negativeCoefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiply(FX_INT32 scalar, FX_INT32 &e)
+{
+ CBC_PDF417ECModulusPoly* modulusPoly = NULL;
+ if (scalar == 0) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field->getZero()->getField(), m_field->getZero()->getCoefficients(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ if (scalar == 1) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, m_coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ FX_INT32 size = m_coefficients.GetSize();
+ CFX_Int32Array product;
+ product.SetSize(size);
+ for (FX_INT32 i = 0; i < size; i++) {
+ product[i] = m_field->multiply(m_coefficients[i], scalar);
+ }
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, product, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+}
+CBC_PDF417ECModulusPoly* CBC_PDF417ECModulusPoly::multiplyByMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e)
+{
+ if (degree < 0) {
+ e = BCExceptionIllegalArgument;
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* modulusPoly = NULL;
+ if (coefficient == 0) {
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field->getZero()->m_field, m_field->getZero()->m_coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+ }
+ FX_INT32 size = m_coefficients.GetSize();
+ CFX_Int32Array product;
+ product.SetSize(size + degree);
+ for (FX_INT32 i = 0; i < size; i++) {
+ product[i] = m_field->multiply(m_coefficients[i], coefficient);
+ }
+ modulusPoly = FX_NEW CBC_PDF417ECModulusPoly(m_field, product, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return modulusPoly;
+}
+CFX_PtrArray* CBC_PDF417ECModulusPoly::divide(CBC_PDF417ECModulusPoly* other, FX_INT32 &e)
+{
+ if (other->isZero()) {
+ e = BCExceptionDivideByZero;
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* quotient = FX_NEW CBC_PDF417ECModulusPoly(m_field->getZero()->m_field, m_field->getZero()->m_coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_PDF417ECModulusPoly* remainder = FX_NEW CBC_PDF417ECModulusPoly(m_field, m_coefficients, e);
+ if (e != BCExceptionNO) {
+ delete quotient;
+ return NULL;
+ }
+ FX_INT32 denominatorLeadingTerm = other->getCoefficient(other->getDegree());
+ FX_INT32 inverseDenominatorLeadingTerm = m_field->inverse(denominatorLeadingTerm, e);
+ if (e != BCExceptionNO) {
+ delete quotient;
+ delete remainder;
+ return NULL;
+ }
+ while (remainder->getDegree() >= other->getDegree() && !remainder->isZero()) {
+ FX_INT32 degreeDifference = remainder->getDegree() - other->getDegree();
+ FX_INT32 scale = m_field->multiply(remainder->getCoefficient(remainder->getDegree()), inverseDenominatorLeadingTerm);
+ CBC_PDF417ECModulusPoly* term = other->multiplyByMonomial(degreeDifference, scale, e);
+ if (e != BCExceptionNO) {
+ delete quotient;
+ delete remainder;
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* iterationQuotient = m_field->buildMonomial(degreeDifference, scale, e);
+ if (e != BCExceptionNO) {
+ delete quotient;
+ delete remainder;
+ delete term;
+ return NULL;
+ }
+ CBC_PDF417ECModulusPoly* temp = quotient;
+ quotient = temp->add(iterationQuotient, e);
+ delete iterationQuotient;
+ delete temp;
+ if (e != BCExceptionNO) {
+ delete remainder;
+ return NULL;
+ }
+ temp = remainder;
+ remainder = temp->subtract(term, e);
+ delete term;
+ delete temp;
+ if (e != BCExceptionNO) {
+ delete quotient;
+ return NULL;
+ }
+ }
+ CFX_PtrArray* modulusPoly = FX_NEW CFX_PtrArray;
+ modulusPoly->Add(quotient);
+ modulusPoly->Add(remainder);
+ return modulusPoly;
+}
+CFX_ByteString CBC_PDF417ECModulusPoly::toString()
+{
+ CFX_ByteString result;
+ for (FX_INT32 degree = getDegree(); degree >= 0; degree--) {
+ FX_INT32 coefficient = getCoefficient(degree);
+ if (coefficient != 0) {
+ if (coefficient < 0) {
+ result += " - ";
+ coefficient = -coefficient;
+ } else {
+ if (result.GetLength() > 0) {
+ result += " + ";
+ }
+ }
+ if (degree == 0 || coefficient != 1) {
+ result += coefficient;
+ }
+ if (degree != 0) {
+ if (degree == 1) {
+ result += 'x';
+ } else {
+ result += "x^";
+ result += degree;
+ }
+ }
+ }
+ }
+ return result;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417ErrorCorrection.cpp b/xfa/src/fxbarcode/src/BC_PDF417ErrorCorrection.cpp
new file mode 100644
index 0000000000..1fe1512f44
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417ErrorCorrection.cpp
@@ -0,0 +1,177 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417ErrorCorrection.h"
+FX_INT32 CBC_PDF417ErrorCorrection::EC_COEFFICIENTS[][2500] = {
+ {27, 917},
+ {522, 568, 723, 809},
+ {237, 308, 436, 284, 646, 653, 428, 379},
+ {
+ 274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295,
+ 42, 176, 65
+ },
+ {
+ 361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687,
+ 284, 193, 517, 273, 494, 263, 147, 593, 800, 571, 320, 803,
+ 133, 231, 390, 685, 330, 63, 410
+ },
+ {
+ 539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733,
+ 877, 381, 612, 723, 476, 462, 172, 430, 609, 858, 822, 543,
+ 376, 511, 400, 672, 762, 283, 184, 440, 35, 519, 31, 460,
+ 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502, 648,
+ 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843,
+ 623, 264, 543
+ },
+ {
+ 521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400,
+ 925, 749, 415, 822, 93, 217, 208, 928, 244, 583, 620, 246,
+ 148, 447, 631, 292, 908, 490, 704, 516, 258, 457, 907, 594,
+ 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569, 193,
+ 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712,
+ 463, 646, 776, 171, 491, 297, 763, 156, 732, 95, 270, 447,
+ 90, 507, 48, 228, 821, 808, 898, 784, 663, 627, 378, 382,
+ 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616, 157,
+ 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814,
+ 587, 804, 34, 211, 330, 539, 297, 827, 865, 37, 517, 834,
+ 315, 550, 86, 801, 4, 108, 539
+ },
+ {
+ 524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905,
+ 786, 138, 720, 858, 194, 311, 913, 275, 190, 375, 850, 438,
+ 733, 194, 280, 201, 280, 828, 757, 710, 814, 919, 89, 68,
+ 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137, 439,
+ 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284,
+ 549, 209, 884, 315, 70, 329, 793, 490, 274, 877, 162, 749,
+ 812, 684, 461, 334, 376, 849, 521, 307, 291, 803, 712, 19,
+ 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470, 637,
+ 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136,
+ 538, 906, 90, 2, 290, 743, 199, 655, 903, 329, 49, 802,
+ 580, 355, 588, 188, 462, 10, 134, 628, 320, 479, 130, 739,
+ 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234, 722,
+ 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48,
+ 60, 732, 621, 895, 544, 261, 852, 655, 309, 697, 755, 756,
+ 60, 231, 773, 434, 421, 726, 528, 503, 118, 49, 795, 32,
+ 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550, 73,
+ 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180,
+ 791, 893, 754, 605, 383, 228, 749, 760, 213, 54, 297, 134,
+ 54, 834, 299, 922, 191, 910, 532, 609, 829, 189, 20, 167,
+ 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173, 404,
+ 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648,
+ 55, 497, 10
+ },
+ {
+ 352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285,
+ 380, 350, 492, 197, 265, 920, 155, 914, 299, 229, 643, 294,
+ 871, 306, 88, 87, 193, 352, 781, 846, 75, 327, 520, 435,
+ 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534, 539,
+ 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858,
+ 916, 552, 41, 542, 289, 122, 272, 383, 800, 485, 98, 752,
+ 472, 761, 107, 784, 860, 658, 741, 290, 204, 681, 407, 855,
+ 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142, 808,
+ 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513,
+ 192, 516, 258, 240, 518, 794, 395, 768, 848, 51, 610, 384,
+ 168, 190, 826, 328, 596, 786, 303, 570, 381, 415, 641, 156,
+ 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402, 40,
+ 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221,
+ 92, 358, 785, 288, 357, 850, 836, 827, 736, 707, 94, 8,
+ 494, 114, 521, 2, 499, 851, 543, 152, 729, 771, 95, 248,
+ 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820, 669,
+ 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699,
+ 591, 452, 578, 37, 124, 298, 332, 552, 43, 427, 119, 662,
+ 777, 475, 850, 764, 364, 578, 911, 283, 711, 472, 420, 245,
+ 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408, 842,
+ 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713,
+ 159, 672, 729, 624, 59, 193, 417, 158, 209, 563, 564, 343,
+ 693, 109, 608, 563, 365, 181, 772, 677, 310, 248, 353, 708,
+ 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777, 618,
+ 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331,
+ 247, 184, 45, 787, 680, 18, 66, 407, 369, 54, 492, 228,
+ 613, 830, 922, 437, 519, 644, 905, 789, 420, 305, 441, 207,
+ 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341, 242,
+ 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756,
+ 665, 397, 808, 851, 309, 473, 795, 378, 31, 647, 915, 459,
+ 806, 590, 731, 425, 216, 548, 249, 321, 881, 699, 535, 673,
+ 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791, 660,
+ 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535,
+ 336, 286, 437, 375, 273, 610, 296, 183, 923, 116, 667, 751,
+ 353, 62, 366, 691, 379, 687, 842, 37, 357, 720, 742, 330,
+ 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316, 342,
+ 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721,
+ 610, 46, 656, 447, 171, 616, 464, 190, 531, 297, 321, 762,
+ 752, 533, 175, 134, 14, 381, 433, 717, 45, 111, 20, 596,
+ 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780, 407,
+ 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768,
+ 223, 849, 647, 63, 310, 863, 251, 366, 304, 282, 738, 675,
+ 410, 389, 244, 31, 121, 303, 263
+ }
+};
+CBC_PDF417ErrorCorrection::CBC_PDF417ErrorCorrection()
+{
+}
+CBC_PDF417ErrorCorrection::~CBC_PDF417ErrorCorrection()
+{
+}
+FX_INT32 CBC_PDF417ErrorCorrection::getErrorCorrectionCodewordCount(FX_INT32 errorCorrectionLevel, FX_INT32 &e)
+{
+ if (errorCorrectionLevel < 0 || errorCorrectionLevel > 8) {
+ e = BCExceptionErrorCorrectionLevelMustBeBetween0And8;
+ return -1;
+ }
+ return 1 << (errorCorrectionLevel + 1);
+}
+FX_INT32 CBC_PDF417ErrorCorrection::getRecommendedMinimumErrorCorrectionLevel(FX_INT32 n, FX_INT32 &e)
+{
+ if (n <= 0) {
+ e = BCExceptionIllegalArgumentnMustBeAbove0;
+ return -1;
+ }
+ if (n <= 40) {
+ return 2;
+ }
+ if (n <= 160) {
+ return 3;
+ }
+ if (n <= 320) {
+ return 4;
+ }
+ if (n <= 863) {
+ return 5;
+ }
+ e = BCExceptionNoRecommendationPossible;
+ return -1;
+}
+CFX_WideString CBC_PDF417ErrorCorrection::generateErrorCorrection(CFX_WideString dataCodewords, FX_INT32 errorCorrectionLevel, FX_INT32 &e)
+{
+ FX_INT32 k = getErrorCorrectionCodewordCount(errorCorrectionLevel, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR)' ');
+ FX_WCHAR* ech = FX_Alloc(FX_WCHAR, k * sizeof(FX_WCHAR));
+ FXSYS_memset32(ech, 0, k * sizeof(FX_WCHAR));
+ FX_INT32 sld = dataCodewords.GetLength();
+ for (FX_INT32 i = 0; i < sld; i++) {
+ FX_INT32 t1 = (dataCodewords.GetAt(i) + ech[k - 1]) % 929;
+ FX_INT32 t2;
+ FX_INT32 t3;
+ for (FX_INT32 j = k - 1; j >= 1; j--) {
+ t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][j]) % 929;
+ t3 = 929 - t2;
+ ech[j] = (FX_WCHAR) ((ech[j - 1] + t3) % 929);
+ }
+ t2 = (t1 * EC_COEFFICIENTS[errorCorrectionLevel][0]) % 929;
+ t3 = 929 - t2;
+ ech[0] = (FX_WCHAR) (t3 % 929);
+ }
+ CFX_WideString sb;
+ for (FX_INT32 j = k - 1; j >= 0; j--) {
+ if (ech[j] != 0) {
+ ech[j] = (FX_WCHAR) (929 - ech[j]);
+ }
+ sb += (FX_WCHAR)ech[j];
+ }
+ FX_Free (ech);
+ return sb;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417HighLevelEncoder.cpp b/xfa/src/fxbarcode/src/BC_PDF417HighLevelEncoder.cpp
new file mode 100644
index 0000000000..ade6977a50
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417HighLevelEncoder.cpp
@@ -0,0 +1,420 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417Compaction.h"
+#include "include/BC_UtilCodingConvert.h"
+#include "include/BC_PDF417HighLevelEncoder.h"
+#define SUBMODE_ALPHA 0
+#define SUBMODE_LOWER 1
+#define SUBMODE_MIXED 2
+FX_INT32 CBC_PDF417HighLevelEncoder::TEXT_COMPACTION = 0;
+FX_INT32 CBC_PDF417HighLevelEncoder::BYTE_COMPACTION = 1;
+FX_INT32 CBC_PDF417HighLevelEncoder::NUMERIC_COMPACTION = 2;
+FX_INT32 CBC_PDF417HighLevelEncoder::SUBMODE_PUNCTUATION = 3;
+FX_INT32 CBC_PDF417HighLevelEncoder::LATCH_TO_TEXT = 900;
+FX_INT32 CBC_PDF417HighLevelEncoder::LATCH_TO_BYTE_PADDED = 901;
+FX_INT32 CBC_PDF417HighLevelEncoder::LATCH_TO_NUMERIC = 902;
+FX_INT32 CBC_PDF417HighLevelEncoder::SHIFT_TO_BYTE = 913;
+FX_INT32 CBC_PDF417HighLevelEncoder::LATCH_TO_BYTE = 924;
+FX_BYTE CBC_PDF417HighLevelEncoder::TEXT_MIXED_RAW[] = {48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 38, 13, 9, 44, 58,
+ 35, 45, 46, 36, 47, 43, 37, 42, 61, 94, 0, 32, 0, 0, 0
+ };
+FX_BYTE CBC_PDF417HighLevelEncoder::TEXT_PUNCTUATION_RAW[] = {59, 60, 62, 64, 91, 92, 93, 95, 96, 126, 33, 13, 9, 44, 58,
+ 10, 45, 46, 36, 47, 34, 124, 42, 40, 41, 63, 123, 125, 39, 0
+ };
+FX_INT32 CBC_PDF417HighLevelEncoder::MIXED[128] = {0};
+FX_INT32 CBC_PDF417HighLevelEncoder::PUNCTUATION[128] = {0};
+void CBC_PDF417HighLevelEncoder::Initialize()
+{
+ Inverse();
+}
+void CBC_PDF417HighLevelEncoder::Finalize()
+{
+}
+CBC_PDF417HighLevelEncoder::CBC_PDF417HighLevelEncoder()
+{
+}
+CBC_PDF417HighLevelEncoder::~CBC_PDF417HighLevelEncoder()
+{
+}
+CFX_WideString CBC_PDF417HighLevelEncoder::encodeHighLevel(CFX_WideString wideMsg, Compaction compaction, FX_INT32 &e)
+{
+ CFX_ByteString bytes;
+ CBC_UtilCodingConvert::UnicodeToUTF8(wideMsg, bytes);
+ CFX_WideString msg;
+ FX_INT32 len = bytes.GetLength();
+ for (FX_INT32 i = 0; i < len; i++) {
+ FX_WCHAR ch = (FX_WCHAR)(bytes.GetAt(i) & 0xff);
+ if (ch == '?' && bytes.GetAt(i) != '?') {
+ e = BCExceptionCharactersOutsideISO88591Encoding;
+ return (FX_LPWSTR)"";
+ }
+ msg += ch;
+ }
+ CFX_ByteArray byteArr;
+ for (FX_INT32 k = 0; k < bytes.GetLength(); k++) {
+ byteArr.Add(bytes.GetAt(k));
+ }
+ CFX_WideString sb;
+ len = msg.GetLength();
+ FX_INT32 p = 0;
+ FX_INT32 textSubMode = SUBMODE_ALPHA;
+ if (compaction == TEXT) {
+ encodeText(msg, p, len, sb, textSubMode);
+ } else if (compaction == BYTES) {
+ encodeBinary(&byteArr, p, byteArr.GetSize(), BYTE_COMPACTION, sb);
+ } else if (compaction == NUMERIC) {
+ sb += (FX_WCHAR) LATCH_TO_NUMERIC;
+ encodeNumeric(msg, p, len, sb);
+ } else {
+ FX_INT32 encodingMode = LATCH_TO_TEXT;
+ while (p < len) {
+ FX_INT32 n = determineConsecutiveDigitCount(msg, p);
+ if (n >= 13) {
+ sb += (FX_WCHAR) LATCH_TO_NUMERIC;
+ encodingMode = NUMERIC_COMPACTION;
+ textSubMode = SUBMODE_ALPHA;
+ encodeNumeric(msg, p, n, sb);
+ p += n;
+ } else {
+ FX_INT32 t = determineConsecutiveTextCount(msg, p);
+ if (t >= 5 || n == len) {
+ if (encodingMode != TEXT_COMPACTION) {
+ sb += (FX_WCHAR) LATCH_TO_TEXT;
+ encodingMode = TEXT_COMPACTION;
+ textSubMode = SUBMODE_ALPHA;
+ }
+ textSubMode = encodeText(msg, p, t, sb, textSubMode);
+ p += t;
+ } else {
+ FX_INT32 b = determineConsecutiveBinaryCount(msg, &byteArr, p, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_WCHAR)' ');
+ if (b == 0) {
+ b = 1;
+ }
+ if (b == 1 && encodingMode == TEXT_COMPACTION) {
+ encodeBinary(&byteArr, p, 1, TEXT_COMPACTION, sb);
+ } else {
+ encodeBinary(&byteArr, p, b, encodingMode, sb);
+ encodingMode = BYTE_COMPACTION;
+ textSubMode = SUBMODE_ALPHA;
+ }
+ p += b;
+ }
+ }
+ }
+ }
+ return sb;
+}
+void CBC_PDF417HighLevelEncoder::Inverse()
+{
+ FX_BYTE i = 0;
+ FX_INT32 l = 0;
+ for (l = 0; l < sizeof(MIXED) / sizeof(MIXED[0]); l++) {
+ MIXED[l] = -1;
+ }
+ for (i = 0; i < sizeof(TEXT_MIXED_RAW) / sizeof(TEXT_MIXED_RAW[0]); i++) {
+ FX_BYTE b = TEXT_MIXED_RAW[i];
+ if (b > 0) {
+ MIXED[b] = i;
+ }
+ }
+ for (l = 0; l < sizeof(PUNCTUATION) / sizeof(PUNCTUATION[0]); l++) {
+ PUNCTUATION[l] = -1;
+ }
+ for (i = 0; i < sizeof(TEXT_PUNCTUATION_RAW) / sizeof(TEXT_PUNCTUATION_RAW[0]); i++) {
+ FX_BYTE b = TEXT_PUNCTUATION_RAW[i];
+ if (b > 0) {
+ PUNCTUATION[b] = i;
+ }
+ }
+}
+CFX_ByteArray* CBC_PDF417HighLevelEncoder::getBytesForMessage(CFX_WideString msg)
+{
+ CFX_ByteString bytestring;
+ CBC_UtilCodingConvert::UnicodeToUTF8(msg, bytestring);
+ CFX_ByteArray* bytearray = FX_NEW CFX_ByteArray;
+ for (FX_INT32 i = 0; i < bytestring.GetLength(); i++) {
+ bytearray->Add(bytestring.GetAt(i));
+ }
+ return bytearray;
+}
+FX_INT32 CBC_PDF417HighLevelEncoder::encodeText(CFX_WideString msg, FX_INT32 startpos, FX_INT32 count, CFX_WideString &sb, FX_INT32 initialSubmode)
+{
+ CFX_WideString tmp;
+ FX_INT32 submode = initialSubmode;
+ FX_INT32 idx = 0;
+ while (TRUE) {
+ FX_WCHAR ch = msg.GetAt(startpos + idx);
+ switch (submode) {
+ case SUBMODE_ALPHA:
+ if (isAlphaUpper(ch)) {
+ if (ch == ' ') {
+ tmp += (FX_WCHAR) 26;
+ } else {
+ tmp += (FX_WCHAR) (ch - 65);
+ }
+ } else {
+ if (isAlphaLower(ch)) {
+ submode = SUBMODE_LOWER;
+ tmp += (FX_WCHAR) 27;
+ continue;
+ } else if (isMixed(ch)) {
+ submode = SUBMODE_MIXED;
+ tmp += (FX_WCHAR) 28;
+ continue;
+ } else {
+ tmp += (FX_WCHAR) 29;
+ tmp += PUNCTUATION[ch];
+ break;
+ }
+ }
+ break;
+ case SUBMODE_LOWER:
+ if (isAlphaLower(ch)) {
+ if (ch == ' ') {
+ tmp += (FX_WCHAR) 26;
+ } else {
+ tmp += (FX_WCHAR) (ch - 97);
+ }
+ } else {
+ if (isAlphaUpper(ch)) {
+ tmp += (FX_WCHAR) 27;
+ tmp += (FX_WCHAR) (ch - 65);
+ break;
+ } else if (isMixed(ch)) {
+ submode = SUBMODE_MIXED;
+ tmp += (FX_WCHAR) 28;
+ continue;
+ } else {
+ tmp += (FX_WCHAR) 29;
+ tmp += PUNCTUATION[ch];
+ break;
+ }
+ }
+ break;
+ case SUBMODE_MIXED:
+ if (isMixed(ch)) {
+ FX_WCHAR a = MIXED[ch];
+ FX_INT32 b = (FX_INT32)a;
+ tmp += MIXED[ch];
+ } else {
+ if (isAlphaUpper(ch)) {
+ submode = SUBMODE_ALPHA;
+ tmp += (FX_WCHAR) 28;
+ continue;
+ } else if (isAlphaLower(ch)) {
+ submode = SUBMODE_LOWER;
+ tmp += (FX_WCHAR) 27;
+ continue;
+ } else {
+ if (startpos + idx + 1 < count) {
+ FX_WCHAR next = msg.GetAt(startpos + idx + 1);
+ if (isPunctuation(next)) {
+ submode = SUBMODE_PUNCTUATION;
+ tmp += (FX_WCHAR) 25;
+ continue;
+ }
+ }
+ tmp += (FX_WCHAR) 29;
+ tmp += PUNCTUATION[ch];
+ }
+ }
+ break;
+ default:
+ if (isPunctuation(ch)) {
+ tmp += PUNCTUATION[ch];
+ } else {
+ submode = SUBMODE_ALPHA;
+ tmp += (FX_WCHAR) 29;
+ continue;
+ }
+ }
+ idx++;
+ if (idx >= count) {
+ break;
+ }
+ }
+ FX_WCHAR h = 0;
+ FX_INT32 len = tmp.GetLength();
+ for (FX_INT32 i = 0; i < len; i++) {
+ FX_BOOL odd = (i % 2) != 0;
+ if (odd) {
+ h = (FX_WCHAR) ((h * 30) + tmp.GetAt(i));
+ sb += h;
+ } else {
+ h = tmp.GetAt(i);
+ }
+ }
+ if ((len % 2) != 0) {
+ sb += (FX_WCHAR) ((h * 30) + 29);
+ }
+ return submode;
+}
+void CBC_PDF417HighLevelEncoder::encodeBinary(CFX_ByteArray* bytes, FX_INT32 startpos, FX_INT32 count, FX_INT32 startmode, CFX_WideString &sb)
+{
+ if (count == 1 && startmode == TEXT_COMPACTION) {
+ sb += (FX_WCHAR) SHIFT_TO_BYTE;
+ }
+ FX_INT32 idx = startpos;
+ FX_INT32 i = 0;
+ if (count >= 6) {
+ sb += (FX_WCHAR) LATCH_TO_BYTE;
+ FX_WCHAR chars[5];
+ while ((startpos + count - idx) >= 6) {
+ FX_INT64 t = 0;
+ for (i = 0; i < 6; i++) {
+ t <<= 8;
+ t += bytes->GetAt(idx + i) & 0xff;
+ }
+ for (i = 0; i < 5; i++) {
+ chars[i] = (FX_WCHAR) (t % 900);
+ t /= 900;
+ }
+ for (i = 4; i >= 0; i--) {
+ sb += (chars[i]);
+ }
+ idx += 6;
+ }
+ }
+ if (idx < startpos + count) {
+ sb += (FX_WCHAR) LATCH_TO_BYTE_PADDED;
+ }
+ for (i = idx; i < startpos + count; i++) {
+ FX_INT32 ch = bytes->GetAt(i) & 0xff;
+ sb += (FX_WCHAR) ch;
+ }
+}
+void CBC_PDF417HighLevelEncoder::encodeNumeric(CFX_WideString msg, FX_INT32 startpos, FX_INT32 count, CFX_WideString &sb)
+{
+ FX_INT32 idx = 0;
+ CFX_WideString tmp;
+ FX_INT32 num900 = 900;
+ FX_INT32 num0 = 0;
+ while (idx < count - 1) {
+ FX_INT32 len = 44 < count - idx ? 44 : count - idx;
+ CFX_WideString part = (FX_WCHAR)'1' + msg.Mid(startpos + idx, len);
+ FX_INT32 bigint = part.GetInteger();
+ do {
+ FX_INT32 c = bigint % num900;
+ tmp += (FX_WCHAR) (c);
+ bigint = bigint / num900;
+ } while (bigint != num0);
+ for (FX_INT32 i = tmp.GetLength() - 1; i >= 0; i--) {
+ sb += (tmp.GetAt(i));
+ }
+ idx += len;
+ }
+}
+FX_BOOL CBC_PDF417HighLevelEncoder::isDigit(FX_WCHAR ch)
+{
+ return ch >= '0' && ch <= '9';
+}
+FX_BOOL CBC_PDF417HighLevelEncoder::isAlphaUpper(FX_WCHAR ch)
+{
+ return ch == ' ' || (ch >= 'A' && ch <= 'Z');
+}
+FX_BOOL CBC_PDF417HighLevelEncoder::isAlphaLower(FX_WCHAR ch)
+{
+ return ch == ' ' || (ch >= 'a' && ch <= 'z');
+}
+FX_BOOL CBC_PDF417HighLevelEncoder::isMixed(FX_WCHAR ch)
+{
+ return MIXED[ch] != -1;
+}
+FX_BOOL CBC_PDF417HighLevelEncoder::isPunctuation(FX_WCHAR ch)
+{
+ return PUNCTUATION[ch] != -1;
+}
+FX_BOOL CBC_PDF417HighLevelEncoder::isText(FX_WCHAR ch)
+{
+ return ch == '\t' || ch == '\n' || ch == '\r' || (ch >= 32 && ch <= 126);
+}
+FX_INT32 CBC_PDF417HighLevelEncoder::determineConsecutiveDigitCount(CFX_WideString msg, FX_INT32 startpos)
+{
+ FX_INT32 count = 0;
+ FX_INT32 len = msg.GetLength();
+ FX_INT32 idx = startpos;
+ if (idx < len) {
+ FX_WCHAR ch = msg.GetAt(idx);
+ while (isDigit(ch) && idx < len) {
+ count++;
+ idx++;
+ if (idx < len) {
+ ch = msg.GetAt(idx);
+ }
+ }
+ }
+ return count;
+}
+FX_INT32 CBC_PDF417HighLevelEncoder::determineConsecutiveTextCount(CFX_WideString msg, FX_INT32 startpos)
+{
+ FX_INT32 len = msg.GetLength();
+ FX_INT32 idx = startpos;
+ while (idx < len) {
+ FX_WCHAR ch = msg.GetAt(idx);
+ FX_INT32 numericCount = 0;
+ while (numericCount < 13 && isDigit(ch) && idx < len) {
+ numericCount++;
+ idx++;
+ if (idx < len) {
+ ch = msg.GetAt(idx);
+ }
+ }
+ if (numericCount >= 13) {
+ return idx - startpos - numericCount;
+ }
+ if (numericCount > 0) {
+ continue;
+ }
+ ch = msg.GetAt(idx);
+ if (!isText(ch)) {
+ break;
+ }
+ idx++;
+ }
+ return idx - startpos;
+}
+FX_INT32 CBC_PDF417HighLevelEncoder::determineConsecutiveBinaryCount(CFX_WideString msg, CFX_ByteArray* bytes, FX_INT32 startpos, FX_INT32 &e)
+{
+ FX_INT32 len = msg.GetLength();
+ FX_INT32 idx = startpos;
+ while (idx < len) {
+ FX_WCHAR ch = msg.GetAt(idx);
+ FX_INT32 numericCount = 0;
+ while (numericCount < 13 && isDigit(ch)) {
+ numericCount++;
+ FX_INT32 i = idx + numericCount;
+ if (i >= len) {
+ break;
+ }
+ ch = msg.GetAt(i);
+ }
+ if (numericCount >= 13) {
+ return idx - startpos;
+ }
+ FX_INT32 textCount = 0;
+ while (textCount < 5 && isText(ch)) {
+ textCount++;
+ FX_INT32 i = idx + textCount;
+ if (i >= len) {
+ break;
+ }
+ ch = msg.GetAt(i);
+ }
+ if (textCount >= 5) {
+ return idx - startpos;
+ }
+ ch = msg.GetAt(idx);
+ if (bytes->GetAt(idx) == 63 && ch != '?') {
+ e = BCExceptionNonEncodableCharacterDetected;
+ return -1;
+ }
+ idx++;
+ }
+ return idx - startpos;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417Reader.cpp b/xfa/src/fxbarcode/src/BC_PDF417Reader.cpp
new file mode 100644
index 0000000000..91599baf50
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417Reader.cpp
@@ -0,0 +1,103 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_PDF417DetectorResult.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_PDF417Detector.h"
+#include "include/BC_PDF417DetectorResult.h"
+#include "include/BC_DecoderResult.h"
+#include "include/BC_PDF417Codeword.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417BarcodeValue.h"
+#include "include/BC_PDF417BarcodeMetadata.h"
+#include "include/BC_PDF417BoundingBox.h"
+#include "include/BC_PDF417DetectionResultColumn.h"
+#include "include/BC_PDF417DetectionResultRowIndicatorColumn.h"
+#include "include/BC_PDF417DetectionResult.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417CodewordDecoder.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417ECModulusPoly.h"
+#include "include/BC_PDF417ECModulusGF.h"
+#include "include/BC_PDF417ECErrorCorrection.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_PDF417ScanningDecoder.h"
+#include "include/BC_PDF417Reader.h"
+#define Integer_MAX_VALUE 2147483647
+CBC_PDF417Reader::CBC_PDF417Reader()
+{
+}
+CBC_PDF417Reader::~CBC_PDF417Reader()
+{
+}
+CFX_ByteString CBC_PDF417Reader::Decode(CBC_BinaryBitmap *image, FX_INT32 &e)
+{
+ return Decode(image, 0, e);
+}
+CFX_ByteString CBC_PDF417Reader::Decode(CBC_BinaryBitmap *image, FX_BOOL multiple, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_ByteString results;
+ CBC_PDF417DetectorResult* detectorResult = CBC_Detector::detect(image, hints, multiple, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ for (FX_INT32 i = 0; i < detectorResult->getPoints()->GetSize(); i++) {
+ CFX_PtrArray* points = (CFX_PtrArray*)detectorResult->getPoints()->GetAt(i);
+ CBC_CommonDecoderResult* ResultTemp = CBC_PDF417ScanningDecoder::decode(detectorResult->getBits(), (CBC_ResultPoint*)points->GetAt(4), (CBC_ResultPoint*)points->GetAt(5),
+ (CBC_ResultPoint*)points->GetAt(6), (CBC_ResultPoint*)points->GetAt(7), getMinCodewordWidth(*points), getMaxCodewordWidth(*points), e);
+ if (ResultTemp == NULL) {
+ delete detectorResult;
+ e = BCExceptiontNotFoundInstance;
+ return "";
+ }
+ results += ResultTemp->GetText();
+ delete ResultTemp;
+ }
+ delete detectorResult;
+ return results;
+}
+CFX_ByteString CBC_PDF417Reader::Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e)
+{
+ CFX_ByteString bs = Decode(image, FALSE, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return bs;
+}
+FX_INT32 CBC_PDF417Reader::getMaxWidth(CBC_ResultPoint* p1, CBC_ResultPoint* p2)
+{
+ if (p1 == NULL || p2 == NULL) {
+ return 0;
+ }
+ return (FX_INT32) FXSYS_fabs(p1->GetX() - p2->GetX());
+}
+FX_INT32 CBC_PDF417Reader::getMinWidth(CBC_ResultPoint* p1, CBC_ResultPoint* p2)
+{
+ if (p1 == NULL || p2 == NULL) {
+ return Integer_MAX_VALUE;
+ }
+ return (FX_INT32) FXSYS_fabs(p1->GetX() - p2->GetX());
+}
+FX_INT32 CBC_PDF417Reader::getMaxCodewordWidth(CFX_PtrArray& p)
+{
+ FX_INT32 a = getMaxWidth((CBC_ResultPoint*)p.GetAt(6), (CBC_ResultPoint*)p.GetAt(2)) * CBC_PDF417Common::MODULES_IN_CODEWORD / CBC_PDF417Common::MODULES_IN_STOP_PATTERN;
+ FX_INT32 b = getMaxWidth((CBC_ResultPoint*)p.GetAt(7), (CBC_ResultPoint*)p.GetAt(3)) * CBC_PDF417Common::MODULES_IN_CODEWORD / CBC_PDF417Common::MODULES_IN_STOP_PATTERN;
+ FX_INT32 c = getMaxWidth((CBC_ResultPoint*)p.GetAt(0), (CBC_ResultPoint*)p.GetAt(4)) < a ? getMaxWidth((CBC_ResultPoint*)p.GetAt(0), (CBC_ResultPoint*)p.GetAt(4)) : a;
+ FX_INT32 d = getMaxWidth((CBC_ResultPoint*)p.GetAt(1), (CBC_ResultPoint*)p.GetAt(5)) < b ? getMaxWidth((CBC_ResultPoint*)p.GetAt(1), (CBC_ResultPoint*)p.GetAt(5)) : b;
+ return c < d ? c : d;
+}
+FX_INT32 CBC_PDF417Reader::getMinCodewordWidth(CFX_PtrArray& p)
+{
+ FX_INT32 a = getMinWidth((CBC_ResultPoint*)p.GetAt(6), (CBC_ResultPoint*)p.GetAt(2)) * CBC_PDF417Common::MODULES_IN_CODEWORD / CBC_PDF417Common::MODULES_IN_STOP_PATTERN;
+ FX_INT32 b = getMinWidth((CBC_ResultPoint*)p.GetAt(7), (CBC_ResultPoint*)p.GetAt(3)) * CBC_PDF417Common::MODULES_IN_CODEWORD / CBC_PDF417Common::MODULES_IN_STOP_PATTERN;
+ FX_INT32 c = getMinWidth((CBC_ResultPoint*)p.GetAt(0), (CBC_ResultPoint*)p.GetAt(4)) < a ? getMinWidth((CBC_ResultPoint*)p.GetAt(0), (CBC_ResultPoint*)p.GetAt(4)) : a;
+ FX_INT32 d = getMinWidth((CBC_ResultPoint*)p.GetAt(1), (CBC_ResultPoint*)p.GetAt(5)) < b ? getMinWidth((CBC_ResultPoint*)p.GetAt(1), (CBC_ResultPoint*)p.GetAt(5)) : b;
+ return c < d ? c : d;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417ResultMetadata.cpp b/xfa/src/fxbarcode/src/BC_PDF417ResultMetadata.cpp
new file mode 100644
index 0000000000..4728ba7d74
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417ResultMetadata.cpp
@@ -0,0 +1,46 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_PDF417ResultMetadata.h"
+CBC_PDF417ResultMetadata::CBC_PDF417ResultMetadata()
+{
+}
+CBC_PDF417ResultMetadata::~CBC_PDF417ResultMetadata()
+{
+}
+FX_INT32 CBC_PDF417ResultMetadata::getSegmentIndex()
+{
+ return m_segmentIndex;
+}
+void CBC_PDF417ResultMetadata::setSegmentIndex(FX_INT32 segmentIndex)
+{
+ m_segmentIndex = segmentIndex;
+}
+CFX_ByteString CBC_PDF417ResultMetadata::getFileId()
+{
+ return m_fileId;
+}
+void CBC_PDF417ResultMetadata::setFileId(CFX_ByteString fileId)
+{
+ m_fileId = fileId;
+}
+CFX_Int32Array& CBC_PDF417ResultMetadata::getOptionalData()
+{
+ return m_optionalData;
+}
+void CBC_PDF417ResultMetadata::setOptionalData(CFX_Int32Array &optionalData)
+{
+ m_optionalData.Copy(optionalData);
+}
+FX_BOOL CBC_PDF417ResultMetadata::isLastSegment()
+{
+ return m_lastSegment;
+}
+void CBC_PDF417ResultMetadata::setLastSegment(FX_BOOL lastSegment)
+{
+ m_lastSegment = lastSegment;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417ScanningDecoder.cpp b/xfa/src/fxbarcode/src/BC_PDF417ScanningDecoder.cpp
new file mode 100644
index 0000000000..f5467a6ea9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417ScanningDecoder.cpp
@@ -0,0 +1,580 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_DecoderResult.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_PDF417Codeword.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_PDF417Common.h"
+#include "include/BC_PDF417BarcodeValue.h"
+#include "include/BC_PDF417BarcodeMetadata.h"
+#include "include/BC_PDF417BoundingBox.h"
+#include "include/BC_PDF417DetectionResultColumn.h"
+#include "include/BC_PDF417DetectionResultRowIndicatorColumn.h"
+#include "include/BC_PDF417DetectionResult.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417CodewordDecoder.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417ECModulusPoly.h"
+#include "include/BC_PDF417ECModulusGF.h"
+#include "include/BC_PDF417ECErrorCorrection.h"
+#include "include/BC_PDF417DecodedBitStreamParser.h"
+#include "include/BC_PDF417ScanningDecoder.h"
+FX_INT32 CBC_PDF417ScanningDecoder::CODEWORD_SKEW_SIZE = 2;
+FX_INT32 CBC_PDF417ScanningDecoder::MAX_ERRORS = 3;
+FX_INT32 CBC_PDF417ScanningDecoder::MAX_EC_CODEWORDS = 512;
+CBC_PDF417ECErrorCorrection* CBC_PDF417ScanningDecoder::errorCorrection = NULL;
+CBC_PDF417ScanningDecoder::CBC_PDF417ScanningDecoder()
+{
+}
+CBC_PDF417ScanningDecoder::~CBC_PDF417ScanningDecoder()
+{
+}
+void CBC_PDF417ScanningDecoder::Initialize()
+{
+ errorCorrection = FX_NEW CBC_PDF417ECErrorCorrection;
+}
+void CBC_PDF417ScanningDecoder::Finalize()
+{
+ delete errorCorrection;
+}
+CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::decode(CBC_CommonBitMatrix* image, CBC_ResultPoint* imageTopLeft, CBC_ResultPoint* imageBottomLeft, CBC_ResultPoint* imageTopRight,
+ CBC_ResultPoint* imageBottomRight, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth, FX_INT32 &e)
+{
+ CBC_BoundingBox* boundingBox = FX_NEW CBC_BoundingBox(image, imageTopLeft, imageBottomLeft, imageTopRight, imageBottomRight, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn = NULL;
+ CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn = NULL;
+ CBC_DetectionResult* detectionResult = NULL;
+ for (FX_INT32 i = 0; i < 2; i++) {
+ if (imageTopLeft != NULL) {
+ leftRowIndicatorColumn = getRowIndicatorColumn(image, boundingBox, *imageTopLeft, TRUE, minCodewordWidth, maxCodewordWidth);
+ }
+ if (imageTopRight != NULL) {
+ rightRowIndicatorColumn = getRowIndicatorColumn(image, boundingBox, *imageTopRight, FALSE, minCodewordWidth, maxCodewordWidth);
+ }
+ detectionResult = merge(leftRowIndicatorColumn, rightRowIndicatorColumn, e);
+ if (e != BCExceptionNO) {
+ e = BCExceptiontNotFoundInstance;
+ delete leftRowIndicatorColumn;
+ delete rightRowIndicatorColumn;
+ delete boundingBox;
+ return NULL;
+ }
+ if (i == 0 && (detectionResult->getBoundingBox()->getMinY() < boundingBox->getMinY() || detectionResult->getBoundingBox()->getMaxY() > boundingBox->getMaxY())) {
+ delete boundingBox;
+ boundingBox = detectionResult->getBoundingBox();
+ } else {
+ detectionResult->setBoundingBox(boundingBox);
+ break;
+ }
+ }
+ FX_INT32 maxBarcodeColumn = detectionResult->getBarcodeColumnCount() + 1;
+ detectionResult->setDetectionResultColumn(0, leftRowIndicatorColumn);
+ detectionResult->setDetectionResultColumn(maxBarcodeColumn, rightRowIndicatorColumn);
+ FX_BOOL leftToRight = leftRowIndicatorColumn != NULL;
+ for (FX_INT32 barcodeColumnCount = 1; barcodeColumnCount <= maxBarcodeColumn; barcodeColumnCount++) {
+ FX_INT32 barcodeColumn = leftToRight ? barcodeColumnCount : maxBarcodeColumn - barcodeColumnCount;
+ if (detectionResult->getDetectionResultColumn(barcodeColumn) != NULL) {
+ continue;
+ }
+ CBC_DetectionResultColumn* detectionResultColumn = NULL;
+ if (barcodeColumn == 0 || barcodeColumn == maxBarcodeColumn) {
+ detectionResultColumn = FX_NEW CBC_DetectionResultRowIndicatorColumn(boundingBox, barcodeColumn == 0);
+ } else {
+ detectionResultColumn = FX_NEW CBC_DetectionResultColumn(boundingBox);
+ }
+ detectionResult->setDetectionResultColumn(barcodeColumn, detectionResultColumn);
+ FX_INT32 startColumn = -1;
+ FX_INT32 previousStartColumn = startColumn;
+ for (FX_INT32 imageRow = boundingBox->getMinY(); imageRow <= boundingBox->getMaxY(); imageRow++) {
+ startColumn = getStartColumn(detectionResult, barcodeColumn, imageRow, leftToRight);
+ if (startColumn < 0 || startColumn > boundingBox->getMaxX()) {
+ if (previousStartColumn == -1) {
+ continue;
+ }
+ startColumn = previousStartColumn;
+ }
+ CBC_Codeword* codeword = detectCodeword(image, boundingBox->getMinX(), boundingBox->getMaxX(), leftToRight, startColumn, imageRow, minCodewordWidth, maxCodewordWidth);
+ if (codeword != NULL) {
+ detectionResultColumn->setCodeword(imageRow, codeword);
+ previousStartColumn = startColumn;
+ minCodewordWidth = minCodewordWidth < codeword->getWidth() ? minCodewordWidth : codeword->getWidth();
+ maxCodewordWidth = maxCodewordWidth > codeword->getWidth() ? maxCodewordWidth : codeword->getWidth();
+ }
+ }
+ }
+ CBC_CommonDecoderResult* decoderresult = createDecoderResult(detectionResult, e);
+ if (e != BCExceptionNO) {
+ delete detectionResult;
+ return NULL;
+ }
+ return decoderresult;
+}
+CFX_ByteString CBC_PDF417ScanningDecoder::toString(CFX_PtrArray* barcodeMatrix)
+{
+ CFX_ByteString result;
+ for (FX_INT32 row = 0; row < barcodeMatrix->GetSize(); row++) {
+ result += row;
+ FX_INT32 l = 0;
+ for (; l < ((CFX_PtrArray*)barcodeMatrix->GetAt(row))->GetSize(); l++) {
+ CBC_BarcodeValue* barcodeValue = (CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(row))->GetAt(l);
+ if (barcodeValue->getValue()->GetSize() == 0) {
+ result += "";
+ } else {
+ result += barcodeValue->getValue()->GetAt(0);
+ result += barcodeValue->getConfidence(barcodeValue->getValue()->GetAt(0));
+ }
+ }
+ }
+ return result;
+}
+CBC_DetectionResult* CBC_PDF417ScanningDecoder::merge(CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn, CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn, FX_INT32 &e)
+{
+ if (leftRowIndicatorColumn == NULL && rightRowIndicatorColumn == NULL) {
+ e = BCExceptionIllegalArgument;
+ return NULL;
+ }
+ CBC_BarcodeMetadata* barcodeMetadata = getBarcodeMetadata(leftRowIndicatorColumn, rightRowIndicatorColumn);
+ if (barcodeMetadata == NULL) {
+ e = BCExceptionCannotMetadata;
+ return NULL;
+ }
+ CBC_BoundingBox* leftboundingBox = adjustBoundingBox(leftRowIndicatorColumn, e);
+ if (e != BCExceptionNO) {
+ delete barcodeMetadata;
+ return NULL;
+ }
+ CBC_BoundingBox* rightboundingBox = adjustBoundingBox(rightRowIndicatorColumn, e);
+ if (e != BCExceptionNO) {
+ delete barcodeMetadata;
+ return NULL;
+ }
+ CBC_BoundingBox* boundingBox = CBC_BoundingBox::merge(leftboundingBox, rightboundingBox, e);
+ if (e != BCExceptionNO) {
+ delete barcodeMetadata;
+ return NULL;
+ }
+ CBC_DetectionResult* detectionresult = FX_NEW CBC_DetectionResult(barcodeMetadata, boundingBox);
+ return detectionresult;
+}
+CBC_BoundingBox* CBC_PDF417ScanningDecoder::adjustBoundingBox(CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn, FX_INT32 &e)
+{
+ if (rowIndicatorColumn == NULL) {
+ return NULL;
+ }
+ CFX_Int32Array* rowHeights = rowIndicatorColumn->getRowHeights(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 maxRowHeight = getMax(*rowHeights);
+ FX_INT32 missingStartRows = 0;
+ for (FX_INT32 i = 0; i < rowHeights->GetSize(); i++) {
+ FX_INT32 rowHeight = rowHeights->GetAt(i);
+ missingStartRows += maxRowHeight - rowHeight;
+ if (rowHeight > 0) {
+ break;
+ }
+ }
+ CFX_PtrArray* codewords = rowIndicatorColumn->getCodewords();
+ for (FX_INT32 row = 0; missingStartRows > 0 && codewords->GetAt(row) == NULL; row++) {
+ missingStartRows--;
+ }
+ FX_INT32 missingEndRows = 0;
+ for (FX_INT32 row1 = rowHeights->GetSize() - 1; row1 >= 0; row1--) {
+ missingEndRows += maxRowHeight - rowHeights->GetAt(row1);
+ if (rowHeights->GetAt(row1) > 0) {
+ break;
+ }
+ }
+ for (FX_INT32 row2 = codewords->GetSize() - 1; missingEndRows > 0 && codewords->GetAt(row2) == NULL; row2--) {
+ missingEndRows--;
+ }
+ CBC_BoundingBox* boundingBox = rowIndicatorColumn->getBoundingBox()->addMissingRows(missingStartRows, missingEndRows, rowIndicatorColumn->isLeft(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return boundingBox;
+}
+FX_INT32 CBC_PDF417ScanningDecoder::getMax(CFX_Int32Array& values)
+{
+ FX_INT32 maxValue = -1;
+ for (FX_INT32 i = 0; i < values.GetSize(); i++) {
+ FX_INT32 value = values.GetAt(i);
+ maxValue = maxValue > value ? maxValue : value;
+ }
+ return maxValue;
+}
+CBC_BarcodeMetadata* CBC_PDF417ScanningDecoder::getBarcodeMetadata(CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn,
+ CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn)
+{
+ CBC_BarcodeMetadata* leftBarcodeMetadata = NULL;
+ CBC_BarcodeMetadata* rightBarcodeMetadata = NULL;
+ if (leftRowIndicatorColumn == NULL || (leftBarcodeMetadata = leftRowIndicatorColumn->getBarcodeMetadata()) == NULL) {
+ return rightRowIndicatorColumn == NULL ? NULL : rightRowIndicatorColumn->getBarcodeMetadata();
+ }
+ if (rightRowIndicatorColumn == NULL || (rightBarcodeMetadata = rightRowIndicatorColumn->getBarcodeMetadata()) == NULL) {
+ return leftRowIndicatorColumn == NULL ? NULL : leftRowIndicatorColumn->getBarcodeMetadata();
+ }
+ if (leftBarcodeMetadata->getColumnCount() != rightBarcodeMetadata->getColumnCount() &&
+ leftBarcodeMetadata->getErrorCorrectionLevel() != rightBarcodeMetadata->getErrorCorrectionLevel() &&
+ leftBarcodeMetadata->getRowCount() != rightBarcodeMetadata->getRowCount()) {
+ delete leftBarcodeMetadata;
+ delete rightBarcodeMetadata;
+ return NULL;
+ }
+ delete rightBarcodeMetadata;
+ return leftBarcodeMetadata;
+}
+CBC_DetectionResultRowIndicatorColumn* CBC_PDF417ScanningDecoder::getRowIndicatorColumn(CBC_CommonBitMatrix* image, CBC_BoundingBox* boundingBox, CBC_ResultPoint startPoint,
+ FX_BOOL leftToRight, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth)
+{
+ CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn = FX_NEW CBC_DetectionResultRowIndicatorColumn(boundingBox, leftToRight);
+ for (FX_INT32 i = 0; i < 2; i++) {
+ FX_INT32 increment = i == 0 ? 1 : -1;
+ FX_INT32 startColumn = (FX_INT32) startPoint.GetX();
+ for (FX_INT32 imageRow = (FX_INT32) startPoint.GetY(); imageRow <= boundingBox->getMaxY() && imageRow >= boundingBox->getMinY(); imageRow += increment) {
+ CBC_Codeword* codeword = detectCodeword(image, 0, image->GetWidth(), leftToRight, startColumn, imageRow, minCodewordWidth, maxCodewordWidth);
+ if (codeword != NULL) {
+ rowIndicatorColumn->setCodeword(imageRow, codeword);
+ if (leftToRight) {
+ startColumn = codeword->getStartX();
+ } else {
+ startColumn = codeword->getEndX();
+ }
+ }
+ }
+ }
+ return rowIndicatorColumn;
+}
+void CBC_PDF417ScanningDecoder::adjustCodewordCount(CBC_DetectionResult* detectionResult, CFX_PtrArray* barcodeMatrix, FX_INT32 &e)
+{
+ CFX_Int32Array* numberOfCodewords = ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1))->getValue();
+ FX_INT32 calculatedNumberOfCodewords = detectionResult->getBarcodeColumnCount() * detectionResult->getBarcodeRowCount() - getNumberOfECCodeWords(detectionResult->getBarcodeECLevel());
+ if (numberOfCodewords->GetSize() == 0) {
+ if (calculatedNumberOfCodewords < 1 || calculatedNumberOfCodewords > CBC_PDF417Common::MAX_CODEWORDS_IN_BARCODE) {
+ e = BCExceptiontNotFoundInstance;
+ delete numberOfCodewords;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1))->setValue(calculatedNumberOfCodewords);
+ } else if (numberOfCodewords->GetAt(0) != calculatedNumberOfCodewords) {
+ ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(0))->GetAt(1))->setValue(calculatedNumberOfCodewords);
+ }
+ delete numberOfCodewords;
+}
+CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::createDecoderResult(CBC_DetectionResult* detectionResult, FX_INT32 &e)
+{
+ CFX_PtrArray* barcodeMatrix = createBarcodeMatrix(detectionResult);
+ adjustCodewordCount(detectionResult, barcodeMatrix, e);
+ if (e != BCExceptionNO) {
+ for (FX_INT32 i = 0; i < barcodeMatrix->GetSize(); i++) {
+ CFX_PtrArray* temp = (CFX_PtrArray*)barcodeMatrix->GetAt(i);
+ for (FX_INT32 j = 0; j < temp->GetSize(); j++) {
+ delete (CBC_BarcodeValue*)temp->GetAt(j);
+ }
+ temp->RemoveAll();
+ delete temp;
+ }
+ barcodeMatrix->RemoveAll();
+ delete barcodeMatrix;
+ return NULL;
+ }
+ CFX_Int32Array erasures;
+ CFX_Int32Array codewords;
+ codewords.SetSize(detectionResult->getBarcodeRowCount() * detectionResult->getBarcodeColumnCount());
+ CFX_PtrArray ambiguousIndexValuesList;
+ CFX_Int32Array ambiguousIndexesList;
+ for (FX_INT32 row = 0; row < detectionResult->getBarcodeRowCount(); row++) {
+ for (FX_INT32 l = 0; l < detectionResult->getBarcodeColumnCount(); l++) {
+ CFX_Int32Array* values = ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(row))->GetAt(l + 1))->getValue();
+ FX_INT32 codewordIndex = row * detectionResult->getBarcodeColumnCount() + l;
+ if (values->GetSize() == 0) {
+ erasures.Add(codewordIndex);
+ } else if (values->GetSize() == 1) {
+ codewords[codewordIndex] = values->GetAt(0);
+ } else {
+ ambiguousIndexesList.Add(codewordIndex);
+ ambiguousIndexValuesList.Add(values);
+ }
+ }
+ }
+ CFX_PtrArray ambiguousIndexValues;
+ ambiguousIndexValues.SetSize(ambiguousIndexValuesList.GetSize());
+ for (FX_INT32 i = 0; i < ambiguousIndexValues.GetSize(); i++) {
+ ambiguousIndexValues.SetAt(i, ambiguousIndexValuesList.GetAt(i));
+ }
+ for (FX_INT32 l = 0; l < barcodeMatrix->GetSize(); l++) {
+ CFX_PtrArray* temp = (CFX_PtrArray*)barcodeMatrix->GetAt(l);
+ for (FX_INT32 j = 0; j < temp->GetSize(); j++) {
+ delete (CBC_BarcodeValue*)temp->GetAt(j);
+ }
+ temp->RemoveAll();
+ delete temp;
+ }
+ barcodeMatrix->RemoveAll();
+ delete barcodeMatrix;
+ CBC_CommonDecoderResult* decoderResult = createDecoderResultFromAmbiguousValues(detectionResult->getBarcodeECLevel(), codewords, erasures, ambiguousIndexesList, ambiguousIndexValues, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return decoderResult;
+}
+CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::createDecoderResultFromAmbiguousValues(FX_INT32 ecLevel, CFX_Int32Array &codewords, CFX_Int32Array &erasureArray, CFX_Int32Array &ambiguousIndexes,
+ CFX_PtrArray& ambiguousIndexValues, FX_INT32 &e)
+{
+ CFX_Int32Array ambiguousIndexCount;
+ ambiguousIndexCount.SetSize(ambiguousIndexes.GetSize());
+ FX_INT32 tries = 100;
+ while (tries-- > 0) {
+ for (FX_INT32 l = 0; l < ambiguousIndexCount.GetSize(); l++) {
+ codewords[ambiguousIndexes[l]] = ((CFX_Int32Array*)ambiguousIndexValues.GetAt(l))->GetAt(ambiguousIndexCount[l]);
+ }
+ CBC_CommonDecoderResult* decoderResult = decodeCodewords(codewords, ecLevel, erasureArray, e);
+ if (e != BCExceptionNO) {
+ e = BCExceptionNO;
+ continue;
+ } else {
+ return decoderResult;
+ }
+ if (ambiguousIndexCount.GetSize() == 0) {
+ e = BCExceptionChecksumInstance;
+ return NULL;
+ }
+ for (FX_INT32 i = 0; i < ambiguousIndexCount.GetSize(); i++) {
+ if (ambiguousIndexCount[i] < ((CFX_Int32Array*)(ambiguousIndexValues.GetAt(i)))->GetSize() - 1) {
+ ambiguousIndexCount[i]++;
+ break;
+ } else {
+ ambiguousIndexCount[i] = 0;
+ if (i == ambiguousIndexCount.GetSize() - 1) {
+ e = BCExceptionChecksumInstance;
+ return NULL;
+ }
+ }
+ }
+ }
+ e = BCExceptionChecksumInstance;
+ return NULL;
+}
+CFX_PtrArray* CBC_PDF417ScanningDecoder::createBarcodeMatrix(CBC_DetectionResult* detectionResult)
+{
+ CFX_PtrArray* barcodeMatrix = FX_NEW CFX_PtrArray;
+ barcodeMatrix->SetSize(detectionResult->getBarcodeRowCount());
+ CFX_PtrArray* temp = NULL;
+ FX_INT32 colume = 0;
+ for (FX_INT32 row = 0; row < barcodeMatrix->GetSize(); row++) {
+ temp = FX_NEW CFX_PtrArray;
+ temp->SetSize(detectionResult->getBarcodeColumnCount() + 2);
+ for (colume = 0; colume < detectionResult->getBarcodeColumnCount() + 2; colume++) {
+ temp->SetAt(colume, FX_NEW CBC_BarcodeValue());
+ }
+ barcodeMatrix->SetAt(row, temp);
+ }
+ colume = -1;
+ for (FX_INT32 i = 0; i < detectionResult->getDetectionResultColumns().GetSize(); i++) {
+ CBC_DetectionResultColumn* detectionResultColumn = (CBC_DetectionResultColumn*) detectionResult->getDetectionResultColumns().GetAt(i);
+ colume++;
+ if (detectionResultColumn == NULL) {
+ continue;
+ }
+ CFX_PtrArray* temp = detectionResultColumn->getCodewords();
+ for (FX_INT32 l = 0; l < temp->GetSize(); l++) {
+ CBC_Codeword* codeword = (CBC_Codeword*) temp->GetAt(l);
+ if (codeword == NULL || codeword->getRowNumber() == -1) {
+ continue;
+ }
+ ((CBC_BarcodeValue*)((CFX_PtrArray*)barcodeMatrix->GetAt(codeword->getRowNumber()))->GetAt(colume))->setValue(codeword->getValue());
+ }
+ }
+ return barcodeMatrix;
+}
+FX_BOOL CBC_PDF417ScanningDecoder::isValidBarcodeColumn(CBC_DetectionResult* detectionResult, FX_INT32 barcodeColumn)
+{
+ return barcodeColumn >= 0 && barcodeColumn <= detectionResult->getBarcodeColumnCount() + 1;
+}
+FX_INT32 CBC_PDF417ScanningDecoder::getStartColumn(CBC_DetectionResult* detectionResult, FX_INT32 barcodeColumn, FX_INT32 imageRow, FX_BOOL leftToRight)
+{
+ FX_INT32 offset = leftToRight ? 1 : -1;
+ CBC_Codeword* codeword = NULL;
+ if (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
+ codeword = detectionResult->getDetectionResultColumn(barcodeColumn - offset)->getCodeword(imageRow);
+ }
+ if (codeword != NULL) {
+ return leftToRight ? codeword->getEndX() : codeword->getStartX();
+ }
+ codeword = detectionResult->getDetectionResultColumn(barcodeColumn)->getCodewordNearby(imageRow);
+ if (codeword != NULL) {
+ return leftToRight ? codeword->getStartX() : codeword->getEndX();
+ }
+ if (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
+ codeword = detectionResult->getDetectionResultColumn(barcodeColumn - offset)->getCodewordNearby(imageRow);
+ }
+ if (codeword != NULL) {
+ return leftToRight ? codeword->getEndX() : codeword->getStartX();
+ }
+ FX_INT32 skippedColumns = 0;
+ while (isValidBarcodeColumn(detectionResult, barcodeColumn - offset)) {
+ barcodeColumn -= offset;
+ for (FX_INT32 i = 0; i < detectionResult->getDetectionResultColumn(barcodeColumn)->getCodewords()->GetSize(); i++) {
+ CBC_Codeword* previousRowCodeword = (CBC_Codeword*) detectionResult->getDetectionResultColumn(barcodeColumn)->getCodewords()->GetAt(i);
+ if (previousRowCodeword != NULL) {
+ return (leftToRight ? previousRowCodeword->getEndX() : previousRowCodeword->getStartX()) +
+ offset * skippedColumns * (previousRowCodeword->getEndX() - previousRowCodeword->getStartX());
+ }
+ }
+ skippedColumns++;
+ }
+ return leftToRight ? detectionResult->getBoundingBox()->getMinX() : detectionResult->getBoundingBox()->getMaxX();
+}
+CBC_Codeword* CBC_PDF417ScanningDecoder::detectCodeword(CBC_CommonBitMatrix* image, FX_INT32 minColumn, FX_INT32 maxColumn, FX_BOOL leftToRight, FX_INT32 startColumn,
+ FX_INT32 imageRow, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth)
+{
+ startColumn = adjustCodewordStartColumn(image, minColumn, maxColumn, leftToRight, startColumn, imageRow);
+ CFX_Int32Array* moduleBitCount = getModuleBitCount(image, minColumn, maxColumn, leftToRight, startColumn, imageRow);
+ if (moduleBitCount == NULL) {
+ return NULL;
+ }
+ FX_INT32 endColumn;
+ FX_INT32 codewordBitCount = CBC_PDF417Common::getBitCountSum(*moduleBitCount);
+ if (leftToRight) {
+ endColumn = startColumn + codewordBitCount;
+ } else {
+ for (FX_INT32 i = 0; i < moduleBitCount->GetSize() >> 1; i++) {
+ FX_INT32 tmpCount = moduleBitCount->GetAt(i);
+ moduleBitCount->SetAt(i, moduleBitCount->GetAt(moduleBitCount->GetSize() - 1 - i));
+ moduleBitCount->SetAt(moduleBitCount->GetSize() - 1 - i, tmpCount);
+ }
+ endColumn = startColumn;
+ startColumn = endColumn - codewordBitCount;
+ }
+ FX_INT32 decodedValue = CBC_PDF417CodewordDecoder::getDecodedValue(*moduleBitCount);
+ FX_INT32 codeword = CBC_PDF417Common::getCodeword(decodedValue);
+ delete moduleBitCount;
+ if (codeword == -1) {
+ return NULL;
+ }
+ return FX_NEW CBC_Codeword(startColumn, endColumn, getCodewordBucketNumber(decodedValue), codeword);
+}
+CFX_Int32Array* CBC_PDF417ScanningDecoder::getModuleBitCount(CBC_CommonBitMatrix* image, FX_INT32 minColumn, FX_INT32 maxColumn, FX_BOOL leftToRight, FX_INT32 startColumn, FX_INT32 imageRow)
+{
+ FX_INT32 imageColumn = startColumn;
+ CFX_Int32Array* moduleBitCount = FX_NEW CFX_Int32Array;
+ moduleBitCount->SetSize(8);
+ FX_INT32 moduleNumber = 0;
+ FX_INT32 increment = leftToRight ? 1 : -1;
+ FX_BOOL previousPixelValue = leftToRight;
+ while (((leftToRight && imageColumn < maxColumn) || (!leftToRight && imageColumn >= minColumn)) && moduleNumber < moduleBitCount->GetSize()) {
+ if (image->Get(imageColumn, imageRow) == previousPixelValue) {
+ moduleBitCount->SetAt(moduleNumber, moduleBitCount->GetAt(moduleNumber) + 1);
+ imageColumn += increment;
+ } else {
+ moduleNumber++;
+ previousPixelValue = !previousPixelValue;
+ }
+ }
+ if (moduleNumber == moduleBitCount->GetSize() || (((leftToRight && imageColumn == maxColumn) || (!leftToRight && imageColumn == minColumn)) && moduleNumber == moduleBitCount->GetSize() - 1)) {
+ return moduleBitCount;
+ }
+ delete moduleBitCount;
+ return NULL;
+}
+FX_INT32 CBC_PDF417ScanningDecoder::getNumberOfECCodeWords(FX_INT32 barcodeECLevel)
+{
+ return 2 << barcodeECLevel;
+}
+FX_INT32 CBC_PDF417ScanningDecoder::adjustCodewordStartColumn(CBC_CommonBitMatrix* image, FX_INT32 minColumn, FX_INT32 maxColumn, FX_BOOL leftToRight, FX_INT32 codewordStartColumn, FX_INT32 imageRow)
+{
+ FX_INT32 correctedStartColumn = codewordStartColumn;
+ FX_INT32 increment = leftToRight ? -1 : 1;
+ for (FX_INT32 i = 0; i < 2; i++) {
+ FX_BOOL l = image->Get(correctedStartColumn, imageRow);
+ while (((leftToRight && correctedStartColumn >= minColumn) || (!leftToRight && correctedStartColumn < maxColumn)) && leftToRight == image->Get(correctedStartColumn, imageRow)) {
+ if (abs(codewordStartColumn - correctedStartColumn) > CODEWORD_SKEW_SIZE) {
+ return codewordStartColumn;
+ }
+ correctedStartColumn += increment;
+ }
+ increment = -increment;
+ leftToRight = !leftToRight;
+ }
+ return correctedStartColumn;
+}
+FX_BOOL CBC_PDF417ScanningDecoder::checkCodewordSkew(FX_INT32 codewordSize, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth)
+{
+ return minCodewordWidth - CODEWORD_SKEW_SIZE <= codewordSize && codewordSize <= maxCodewordWidth + CODEWORD_SKEW_SIZE;
+}
+CBC_CommonDecoderResult* CBC_PDF417ScanningDecoder::decodeCodewords(CFX_Int32Array &codewords, FX_INT32 ecLevel, CFX_Int32Array &erasures, FX_INT32 &e)
+{
+ if (codewords.GetSize() == 0) {
+ e = BCExceptionFormatInstance;
+ return NULL;
+ }
+ FX_INT32 numECCodewords = 1 << (ecLevel + 1);
+ FX_INT32 correctedErrorsCount = correctErrors(codewords, erasures, numECCodewords, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e , NULL);
+ verifyCodewordCount(codewords, numECCodewords, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CFX_ByteString bytestring;
+ CBC_CommonDecoderResult* decoderResult = CBC_DecodedBitStreamPaser::decode(codewords, bytestring.FormatInteger(ecLevel), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return decoderResult;
+}
+FX_INT32 CBC_PDF417ScanningDecoder::correctErrors(CFX_Int32Array &codewords, CFX_Int32Array &erasures, FX_INT32 numECCodewords, FX_INT32 &e)
+{
+ if ((erasures.GetSize() != 0 && erasures.GetSize() > (numECCodewords / 2 + MAX_ERRORS)) || numECCodewords < 0 || numECCodewords > MAX_EC_CODEWORDS) {
+ e = BCExceptionChecksumInstance;
+ return -1;
+ }
+ FX_INT32 result = CBC_PDF417ECErrorCorrection::decode(codewords, numECCodewords, erasures, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ return result;
+}
+void CBC_PDF417ScanningDecoder::verifyCodewordCount(CFX_Int32Array &codewords, FX_INT32 numECCodewords, FX_INT32 &e)
+{
+ if (codewords.GetSize() < 4) {
+ e = BCExceptionFormatInstance;
+ return;
+ }
+ FX_INT32 numberOfCodewords = codewords.GetAt(0);
+ if (numberOfCodewords > codewords.GetSize()) {
+ e = BCExceptionFormatInstance;
+ return;
+ }
+ if (numberOfCodewords == 0) {
+ if (numECCodewords < codewords.GetSize()) {
+ codewords[0] = codewords.GetSize() - numECCodewords;
+ } else {
+ e = BCExceptionFormatInstance;
+ return;
+ }
+ }
+}
+CFX_Int32Array* CBC_PDF417ScanningDecoder::getBitCountForCodeword(FX_INT32 codeword)
+{
+ CFX_Int32Array* result = FX_NEW CFX_Int32Array;
+ result->SetSize(8);
+ FX_INT32 previousValue = 0;
+ FX_INT32 i = result->GetSize() - 1;
+ while (TRUE) {
+ if ((codeword & 0x1) != previousValue) {
+ previousValue = codeword & 0x1;
+ i--;
+ if (i < 0) {
+ break;
+ }
+ }
+ result->SetAt(i, result->GetAt(i) + 1);
+ codeword >>= 1;
+ }
+ return result;
+}
+FX_INT32 CBC_PDF417ScanningDecoder::getCodewordBucketNumber(FX_INT32 codeword)
+{
+ CFX_Int32Array* array = getBitCountForCodeword(codeword);
+ FX_INT32 result = getCodewordBucketNumber(*array);
+ delete array;
+ return result;
+}
+FX_INT32 CBC_PDF417ScanningDecoder::getCodewordBucketNumber(CFX_Int32Array& moduleBitCount)
+{
+ return (moduleBitCount.GetAt(0) - moduleBitCount.GetAt(2) + moduleBitCount.GetAt(4) - moduleBitCount.GetAt(6) + 9) % 9;
+}
diff --git a/xfa/src/fxbarcode/src/BC_PDF417Writer.cpp b/xfa/src/fxbarcode/src/BC_PDF417Writer.cpp
new file mode 100644
index 0000000000..319279c92b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_PDF417Writer.cpp
@@ -0,0 +1,110 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_TwoDimWriter.h"
+#include "include/BC_PDF417Compaction.h"
+#include "include/BC_PDF417.h"
+#include "include/BC_PDF417BarcodeMatrix.h"
+#include "include/BC_CommonBitArray.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_PDF417Writer.h"
+CBC_PDF417Writer::CBC_PDF417Writer()
+{
+ m_bFixedSize = FALSE;
+}
+CBC_PDF417Writer::~CBC_PDF417Writer()
+{
+ m_bTruncated = TRUE;
+}
+FX_BOOL CBC_PDF417Writer:: SetErrorCorrectionLevel(FX_INT32 level)
+{
+ if (level < 0 || level > 8) {
+ return FALSE;
+ }
+ m_iCorrectLevel = level;
+ return TRUE;
+}
+void CBC_PDF417Writer::SetTruncated(FX_BOOL truncated)
+{
+ m_bTruncated = truncated;
+}
+FX_BYTE* CBC_PDF417Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ if ( format != BCFORMAT_PDF_417) {
+ return NULL;
+ }
+ CFX_WideString encodeContents = contents.UTF8Decode();
+ return Encode(encodeContents, outWidth, outHeight, e );
+}
+FX_BYTE* CBC_PDF417Writer::Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ return NULL;
+}
+FX_BYTE* CBC_PDF417Writer::Encode(const CFX_WideString &contents, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ CBC_PDF417 encoder;
+ FX_INT32 col = (m_Width / m_ModuleWidth - 69) / 17;
+ FX_INT32 row = m_Height / (m_ModuleWidth * 20);
+ if (row >= 3 && row <= 90 && col >= 1 && col <= 30) {
+ encoder.setDimensions(col, col, row, row);
+ } else if (col >= 1 && col <= 30) {
+ encoder.setDimensions(col, col, 90, 3);
+ } else if (row >= 3 && row <= 90) {
+ encoder.setDimensions(30, 1, row, row);
+ }
+ encoder.generateBarcodeLogic(contents, m_iCorrectLevel, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 lineThickness = 2;
+ FX_INT32 aspectRatio = 4;
+ CBC_BarcodeMatrix* barcodeMatrix = encoder.getBarcodeMatrix();
+ CFX_ByteArray originalScale;
+ originalScale.Copy(barcodeMatrix->getScaledMatrix(lineThickness, aspectRatio * lineThickness));
+ FX_INT32 width = outWidth;
+ FX_INT32 height = outHeight;
+ outWidth = barcodeMatrix->getWidth();
+ outHeight = barcodeMatrix->getHeight();
+ FX_BOOL rotated = FALSE;
+ if ((height > width) ^ (outWidth < outHeight)) {
+ rotateArray(originalScale, outHeight, outWidth);
+ rotated = TRUE;
+ FX_INT32 temp = outHeight;
+ outHeight = outWidth;
+ outWidth = temp;
+ }
+ FX_INT32 scaleX = width / outWidth;
+ FX_INT32 scaleY = height / outHeight;
+ FX_INT32 scale;
+ if (scaleX < scaleY) {
+ scale = scaleX;
+ } else {
+ scale = scaleY;
+ }
+ if (scale > 1) {
+ originalScale.RemoveAll();
+ originalScale.Copy(barcodeMatrix->getScaledMatrix(scale * lineThickness, scale * aspectRatio * lineThickness));
+ if (rotated) {
+ rotateArray(originalScale, outHeight, outWidth);
+ FX_INT32 temp = outHeight;
+ outHeight = outWidth;
+ outWidth = temp;
+ }
+ }
+ FX_BYTE* result = (FX_BYTE*)FX_Alloc(FX_BYTE, outHeight * outWidth);
+ FXSYS_memcpy32(result, originalScale.GetData(), outHeight * outWidth);
+ return result;
+}
+void CBC_PDF417Writer::rotateArray(CFX_ByteArray& bitarray, FX_INT32 height, FX_INT32 width)
+{
+ CFX_ByteArray temp;
+ temp.Copy(bitarray);
+ for (FX_INT32 ii = 0; ii < height; ii++) {
+ FX_INT32 inverseii = height - ii - 1;
+ for (FX_INT32 jj = 0; jj < width; jj++) {
+ bitarray[jj * height + inverseii] = temp[ii * width + jj];
+ }
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRAlignmentPattern.cpp b/xfa/src/fxbarcode/src/BC_QRAlignmentPattern.cpp
new file mode 100644
index 0000000000..25948cb12b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRAlignmentPattern.cpp
@@ -0,0 +1,36 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRAlignmentPattern.h"
+CBC_QRAlignmentPattern::CBC_QRAlignmentPattern(FX_FLOAT posX, FX_FLOAT posY, FX_FLOAT estimateModuleSize):
+ CBC_ResultPoint(posX, posY), m_moduleSize(estimateModuleSize)
+{
+}
+CBC_QRAlignmentPattern::~CBC_QRAlignmentPattern()
+{
+}
+FX_FLOAT CBC_QRAlignmentPattern::GetX()
+{
+ return m_x;
+}
+FX_FLOAT CBC_QRAlignmentPattern::GetY()
+{
+ return m_y;
+}
+FX_BOOL CBC_QRAlignmentPattern::AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j)
+{
+ if ((FXSYS_fabs(i - GetY()) <= moduleSize) && (FXSYS_fabs(j - GetX()) <= moduleSize)) {
+ FX_FLOAT moduleSizeDiff = FXSYS_fabs(moduleSize - m_moduleSize);
+ return (moduleSizeDiff <= 1.0f) || (moduleSizeDiff / m_moduleSize <= 1.0f);
+ }
+ return FALSE;
+}
+CBC_QRAlignmentPattern *CBC_QRAlignmentPattern::Clone()
+{
+ return FX_NEW CBC_QRAlignmentPattern(m_x, m_y, m_moduleSize);
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRAlignmentPatternFinder.cpp b/xfa/src/fxbarcode/src/BC_QRAlignmentPatternFinder.cpp
new file mode 100644
index 0000000000..0adabd018e
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRAlignmentPatternFinder.cpp
@@ -0,0 +1,171 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRAlignmentPattern.h"
+#include "include/BC_QRAlignmentPatternFinder.h"
+#include "include/BC_CommonBitMatrix.h"
+CBC_QRAlignmentPatternFinder::CBC_QRAlignmentPatternFinder(CBC_CommonBitMatrix *image,
+ FX_INT32 startX,
+ FX_INT32 startY,
+ FX_INT32 width,
+ FX_INT32 height,
+ FX_FLOAT moduleSize): m_image(image),
+ m_startX(startX),
+ m_startY(startY),
+ m_width(width),
+ m_height(height),
+ m_moduleSize(moduleSize)
+
+{
+ m_crossCheckStateCount.SetSize(3);
+}
+CBC_QRAlignmentPatternFinder::~CBC_QRAlignmentPatternFinder()
+{
+ for (FX_INT32 i = 0; i < m_possibleCenters.GetSize(); i++) {
+ delete (CBC_QRAlignmentPattern*)m_possibleCenters[i];
+ }
+ m_possibleCenters.RemoveAll();
+}
+CBC_QRAlignmentPattern *CBC_QRAlignmentPatternFinder::Find(FX_INT32 &e)
+{
+ FX_INT32 startX = m_startX;
+ FX_INT32 height = m_height;
+ FX_INT32 maxJ = startX + m_width;
+ FX_INT32 middleI = m_startY + (height >> 1);
+ CFX_Int32Array stateCount;
+ stateCount.SetSize(3);
+ for (FX_INT32 iGen = 0; iGen < height; iGen++) {
+ FX_INT32 i = middleI + ((iGen & 0x01) == 0 ? ((iGen + 1) >> 1) : -((iGen + 1) >> 1));
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ FX_INT32 j = startX;
+ while (j < maxJ && !m_image->Get(j, i)) {
+ j++;
+ }
+ FX_INT32 currentState = 0;
+ while (j < maxJ) {
+ if (m_image->Get(j, i)) {
+ if (currentState == 1) {
+ stateCount[currentState]++;
+ } else {
+ if (currentState == 2) {
+ if (FoundPatternCross(stateCount)) {
+ CBC_QRAlignmentPattern *confirmed = HandlePossibleCenter(stateCount, i, j);
+ if (confirmed != NULL) {
+ return confirmed;
+ }
+ }
+ stateCount[0] = stateCount[2];
+ stateCount[1] = 1;
+ stateCount[2] = 0;
+ currentState = 1;
+ } else {
+ stateCount[++currentState]++;
+ }
+ }
+ } else {
+ if (currentState == 1) {
+ currentState++;
+ }
+ stateCount[currentState]++;
+ }
+ j++;
+ }
+ if (FoundPatternCross(stateCount)) {
+ CBC_QRAlignmentPattern *confirmed = HandlePossibleCenter(stateCount, i, maxJ);
+ if (confirmed != NULL) {
+ return confirmed;
+ }
+ }
+ }
+ if (m_possibleCenters.GetSize() != 0) {
+ return ((CBC_QRAlignmentPattern*) (m_possibleCenters[0]) )->Clone();
+ }
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return NULL;
+}
+FX_FLOAT CBC_QRAlignmentPatternFinder::CenterFromEnd(const CFX_Int32Array &stateCount, FX_INT32 end)
+{
+ return (FX_FLOAT) (end - stateCount[2]) - stateCount[1] / 2.0f;
+}
+FX_BOOL CBC_QRAlignmentPatternFinder::FoundPatternCross(const CFX_Int32Array &stateCount)
+{
+ FX_FLOAT moduleSize = m_moduleSize;
+ FX_FLOAT maxVariance = moduleSize / 2.0f;
+ for (FX_INT32 i = 0; i < 3; i++) {
+ if (fabs(moduleSize - stateCount[i]) >= maxVariance) {
+ return false;
+ }
+ }
+ return TRUE;
+}
+FX_FLOAT CBC_QRAlignmentPatternFinder::CrossCheckVertical(FX_INT32 startI, FX_INT32 centerJ, FX_INT32 maxCount, FX_INT32 originalStateCountTotal)
+{
+ CBC_CommonBitMatrix *image = m_image;
+ FX_INT32 maxI = m_image->GetHeight();
+ CFX_Int32Array stateCount;
+ stateCount.Copy(m_crossCheckStateCount);
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ FX_INT32 i = startI;
+ while (i >= 0 && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ i--;
+ }
+ if (i < 0 || stateCount[1] > maxCount) {
+ return FXSYS_nan();
+ }
+ while (i >= 0 && !m_image->Get(centerJ, i) && stateCount[0] <= maxCount) {
+ stateCount[0]++;
+ i--;
+ }
+ if (stateCount[0] > maxCount) {
+ return FXSYS_nan();
+ }
+ i = startI + 1;
+ while (i < maxI && m_image->Get(centerJ, i) && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ i++;
+ }
+ if (i == maxI || stateCount[1] > maxCount) {
+ return FXSYS_nan();
+ }
+ while (i < maxI && !m_image->Get(centerJ, i) && stateCount[2] <= maxCount) {
+ stateCount[2]++;
+ i++;
+ }
+ if (stateCount[2] > maxCount) {
+ return FXSYS_nan();
+ }
+ FX_INT32 stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
+ if (5 * abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
+ return FXSYS_nan();
+ }
+ return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i) : FXSYS_nan();
+}
+CBC_QRAlignmentPattern *CBC_QRAlignmentPatternFinder::HandlePossibleCenter(const CFX_Int32Array &stateCount, FX_INT32 i, FX_INT32 j)
+{
+ FX_INT32 stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
+ FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
+ FX_FLOAT centerI = CrossCheckVertical(i, (FX_INT32) centerJ, 2 * stateCount[1], stateCountTotal);
+ if (!FXSYS_isnan(centerI)) {
+ FX_FLOAT estimatedModuleSize = (FX_FLOAT) (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;
+ FX_INT32 max = m_possibleCenters.GetSize();
+ for (FX_INT32 index = 0; index < max; index++) {
+ CBC_QRAlignmentPattern *center = (CBC_QRAlignmentPattern *)(m_possibleCenters[index]);
+ if (center->AboutEquals(estimatedModuleSize, centerI, centerJ)) {
+ return FX_NEW CBC_QRAlignmentPattern(centerJ, centerI, estimatedModuleSize);
+ }
+ }
+ m_possibleCenters.Add(FX_NEW CBC_QRAlignmentPattern(centerJ, centerI, estimatedModuleSize));
+ }
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRBitMatrixParser.cpp b/xfa/src/fxbarcode/src/BC_QRBitMatrixParser.cpp
new file mode 100644
index 0000000000..2bfb000201
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRBitMatrixParser.cpp
@@ -0,0 +1,169 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRCoderVersion.h"
+#include "include/BC_QRCoderFormatInformation.h"
+#include "include/BC_QRDataMask.h"
+#include "include/BC_QRBitMatrixParser.h"
+CBC_QRBitMatrixParser::CBC_QRBitMatrixParser()
+{
+}
+void CBC_QRBitMatrixParser::Init(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e)
+{
+ m_dimension = bitMatrix->GetDimension(e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ m_tempBitMatrix = bitMatrix;
+ if(m_dimension < 21 || (m_dimension & 0x03) != 1) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ m_bitMatrix = m_tempBitMatrix;
+ m_parsedFormatInfo = NULL;
+ m_version = NULL;
+}
+CBC_QRBitMatrixParser::~CBC_QRBitMatrixParser()
+{
+ if(m_parsedFormatInfo != NULL) {
+ delete m_parsedFormatInfo;
+ m_parsedFormatInfo = NULL;
+ }
+ m_version = NULL;
+}
+CBC_QRCoderFormatInformation* CBC_QRBitMatrixParser::ReadFormatInformation(FX_INT32 &e)
+{
+ if(m_parsedFormatInfo != NULL) {
+ return m_parsedFormatInfo;
+ }
+ FX_INT32 formatInfoBits = 0;
+ FX_INT32 j;
+ for( j = 0; j < 6; j++) {
+ formatInfoBits = CopyBit(8, j, formatInfoBits);
+ }
+ formatInfoBits = CopyBit(8, 7, formatInfoBits);
+ formatInfoBits = CopyBit(8, 8, formatInfoBits);
+ formatInfoBits = CopyBit(7, 8, formatInfoBits);
+ for(FX_INT32 i = 5; i >= 0; i--) {
+ formatInfoBits = CopyBit(i, 8, formatInfoBits);
+ }
+ m_parsedFormatInfo = CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits);
+ if(m_parsedFormatInfo != NULL) {
+ return m_parsedFormatInfo;
+ }
+ FX_INT32 dimension = m_bitMatrix->GetDimension(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ formatInfoBits = 0;
+ FX_INT32 iMin = dimension - 8;
+ for(j = dimension - 1; j >= iMin; j--) {
+ formatInfoBits = CopyBit(j, 8, formatInfoBits);
+ }
+ for(FX_INT32 k = dimension - 7; k < dimension; k++) {
+ formatInfoBits = CopyBit(8, k , formatInfoBits);
+ }
+ m_parsedFormatInfo = CBC_QRCoderFormatInformation::DecodeFormatInformation(formatInfoBits);
+ if(m_parsedFormatInfo != NULL) {
+ return m_parsedFormatInfo;
+ }
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return NULL;
+}
+CBC_QRCoderVersion* CBC_QRBitMatrixParser::ReadVersion(FX_INT32 &e)
+{
+ if(m_version != NULL) {
+ return m_version;
+ }
+ FX_INT32 dimension = m_bitMatrix->GetDimension(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 provisionVersion = (dimension - 17) >> 2;
+ if(provisionVersion <= 6) {
+ CBC_QRCoderVersion* qrv = CBC_QRCoderVersion::GetVersionForNumber(provisionVersion, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qrv;
+ }
+ FX_INT32 versionBits = 0;
+ for (FX_INT32 i = 5; i >= 0; i--) {
+ FX_INT32 jMin = dimension - 11;
+ for (FX_INT32 j = dimension - 9; j >= jMin; j--) {
+ versionBits = CopyBit(i, j, versionBits);
+ }
+ }
+ m_version = CBC_QRCoderVersion::DecodeVersionInformation(versionBits, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if (m_version != NULL && m_version->GetDimensionForVersion() == dimension) {
+ return m_version;
+ }
+ versionBits = 0;
+ for (FX_INT32 j = 5; j >= 0; j--) {
+ FX_INT32 iMin = dimension - 11;
+ for (FX_INT32 i = dimension - 9; i >= iMin; i--) {
+ versionBits = CopyBit(i, j, versionBits);
+ }
+ }
+ m_version = CBC_QRCoderVersion::DecodeVersionInformation(versionBits, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if (m_version != NULL && m_version->GetDimensionForVersion() == dimension) {
+ return m_version;
+ }
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return NULL;
+}
+FX_INT32 CBC_QRBitMatrixParser::CopyBit(FX_INT32 i, FX_INT32 j, FX_INT32 versionBits)
+{
+ return m_bitMatrix->Get(j, i) ? (versionBits << 1) | 0x1 : versionBits << 1;
+}
+CFX_ByteArray* CBC_QRBitMatrixParser::ReadCodewords(FX_INT32 &e)
+{
+ CBC_QRCoderFormatInformation *formatInfo = ReadFormatInformation(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL)
+ CBC_QRCoderVersion *version = ReadVersion(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_QRDataMask *dataMask = CBC_QRDataMask::ForReference((FX_INT32)(formatInfo->GetDataMask()), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 dimension = m_bitMatrix->GetDimension(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ dataMask->UnmaskBitMatirx(m_bitMatrix, dimension);
+ CBC_CommonBitMatrix* cbm = version->BuildFunctionPattern(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_CommonBitMatrix > functionPattern(cbm);
+ FX_BOOL readingUp = TRUE;
+ CFX_ByteArray * temp = FX_NEW CFX_ByteArray;
+ temp->SetSize(version->GetTotalCodeWords());
+ CBC_AutoPtr<CFX_ByteArray> result(temp);
+ FX_INT32 resultOffset = 0;
+ FX_INT32 currentByte = 0;
+ FX_INT32 bitsRead = 0;
+ for(FX_INT32 j = dimension - 1; j > 0; j -= 2) {
+ if(j == 6) {
+ j--;
+ }
+ for(FX_INT32 count = 0; count < dimension; count++) {
+ FX_INT32 i = readingUp ? dimension - 1 - count : count;
+ for(FX_INT32 col = 0; col < 2; col++) {
+ if(!functionPattern->Get(j - col, i)) {
+ bitsRead++;
+ currentByte <<= 1;
+ if(m_bitMatrix->Get(j - col, i)) {
+ currentByte |= 1;
+ }
+ if(bitsRead == 8) {
+ (*result)[resultOffset++] = (FX_BYTE) currentByte;
+ bitsRead = 0;
+ currentByte = 0;
+ }
+ }
+ }
+ }
+ readingUp ^= TRUE;
+ }
+ if(resultOffset != version->GetTotalCodeWords()) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return result.release();
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCodeReader.cpp b/xfa/src/fxbarcode/src/BC_QRCodeReader.cpp
new file mode 100644
index 0000000000..798d549271
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCodeReader.cpp
@@ -0,0 +1,95 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+#include "include/BC_QRCodeReader.h"
+#include "include/BC_LuminanceSource.h"
+#include "include/BC_BufferedImageLuminanceSource.h"
+#include "include/BC_Binarizer.h"
+#include "include/BC_GlobalHistogramBinarizer.h"
+#include "include/BC_BinaryBitmap.h"
+#include "include/BC_QRCodeReader.h"
+#include "include/BC_QRCoderMode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRCoderDecoder.h"
+#include "include/BC_QRDetector.h"
+#include "include/BC_QRDetectorResult.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_QRDataMask.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_QRCoderVersion.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_QRCodeReader.h"
+CBC_QRCodeReader::CBC_QRCodeReader(): m_decoder(NULL)
+{
+}
+void CBC_QRCodeReader::Init()
+{
+ m_decoder = FX_NEW CBC_QRCoderDecoder;
+ m_decoder->Init();
+}
+CBC_QRCodeReader::~CBC_QRCodeReader()
+{
+ if(m_decoder != NULL) {
+ delete m_decoder;
+ }
+ m_decoder = NULL;
+}
+CFX_ByteString CBC_QRCodeReader::Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e)
+{
+ CBC_CommonBitMatrix *matrix = image->GetMatrix(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_QRDetector detector(matrix);
+ CBC_QRDetectorResult* qdr = detector.Detect(hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CBC_QRDetectorResult> detectorResult(qdr);
+ CBC_CommonDecoderResult* qdr2 = m_decoder->Decode(detectorResult->GetBits(), 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_AutoPtr<CBC_CommonDecoderResult> decodeResult(qdr2);
+ return (decodeResult->GetText());
+}
+CFX_ByteString CBC_QRCodeReader::Decode(const CFX_WideString &filename, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(filename);
+ source.Init(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString bs = Decode(&bitmap, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return bs;
+}
+CFX_ByteString CBC_QRCodeReader::Decode(CFX_DIBitmap *pBitmap, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &e)
+{
+ CBC_BufferedImageLuminanceSource source(pBitmap);
+ CBC_GlobalHistogramBinarizer binarizer(&source);
+ CBC_BinaryBitmap bitmap(&binarizer);
+ CFX_ByteString bs = Decode(&bitmap, hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return bs;
+}
+CFX_ByteString CBC_QRCodeReader::Decode(CBC_BinaryBitmap *image, FX_INT32 &e)
+{
+ CFX_ByteString bs = Decode(image, 0, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, "");
+ return bs;
+}
+void CBC_QRCodeReader::ReleaseAll()
+{
+ if(CBC_ReedSolomonGF256 ::QRCodeFild) {
+ delete CBC_ReedSolomonGF256 ::QRCodeFild;
+ CBC_ReedSolomonGF256 ::QRCodeFild = NULL;
+ }
+ if(CBC_ReedSolomonGF256 ::DataMatrixField) {
+ delete CBC_ReedSolomonGF256 ::DataMatrixField;
+ CBC_ReedSolomonGF256 ::DataMatrixField = NULL;
+ }
+ CBC_QRCoderMode::Destroy();
+ CBC_QRCoderErrorCorrectionLevel::Destroy();
+ CBC_QRDataMask::Destroy();
+ CBC_QRCoderVersion::Destroy();
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCodeWriter.cpp b/xfa/src/fxbarcode/src/BC_QRCodeWriter.cpp
new file mode 100644
index 0000000000..d12e08c34a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCodeWriter.cpp
@@ -0,0 +1,87 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_TwoDimWriter.h"
+#include "include/BC_Reader.h"
+#include "include/BC_QRCodeWriter.h"
+#include "include/BC_QRCoderEncoder.h"
+#include "include/BC_QRCoder.h"
+#include "include/BC_CommonByteMatrix.h"
+#include "include/BC_QRCodeReader.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+CBC_QRCodeWriter::CBC_QRCodeWriter()
+{
+ m_bFixedSize = TRUE;
+ m_iCorrectLevel = 1;
+ m_iVersion = 0;
+}
+CBC_QRCodeWriter::~CBC_QRCodeWriter()
+{
+}
+void CBC_QRCodeWriter::ReleaseAll()
+{
+ CBC_QRCodeReader::ReleaseAll();
+}
+FX_BOOL CBC_QRCodeWriter::SetVersion(FX_INT32 version)
+{
+ if (version < 0 || version > 40) {
+ return FALSE;
+ }
+ m_iVersion = version;
+ return TRUE;
+}
+FX_BOOL CBC_QRCodeWriter::SetErrorCorrectionLevel(FX_INT32 level)
+{
+ if (level < 0 || level > 3) {
+ return FALSE;
+ }
+ m_iCorrectLevel = level;
+ return TRUE;
+}
+FX_BYTE* CBC_QRCodeWriter::Encode(const CFX_WideString& contents, FX_INT32 ecLevel, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ CBC_QRCoderErrorCorrectionLevel *ec = NULL;
+ switch(ecLevel) {
+ case 0:
+ ec = CBC_QRCoderErrorCorrectionLevel::L;
+ break;
+ case 1:
+ ec = CBC_QRCoderErrorCorrectionLevel::M;
+ break;
+ case 2:
+ ec = CBC_QRCoderErrorCorrectionLevel::Q;
+ break;
+ case 3:
+ ec = CBC_QRCoderErrorCorrectionLevel::H;
+ break;
+ default: {
+ e = BCExceptionUnSupportEclevel;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ }
+ CBC_QRCoder qr;
+ if (m_iVersion > 0 && m_iVersion < 41) {
+ CFX_ByteString byteStr = contents.UTF8Encode();
+ CBC_QRCoderEncoder::Encode(byteStr, ec, &qr, e, m_iVersion);
+ } else {
+ CBC_QRCoderEncoder::Encode(contents, ec, &qr, e);
+ }
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ outWidth = qr.GetMatrixWidth();
+ outHeight = qr.GetMatrixWidth();
+ FX_BYTE* result = FX_Alloc(FX_BYTE, outWidth * outWidth);
+ FXSYS_memcpy32(result, qr.GetMatrix()->GetArray(), outWidth * outHeight);
+ return result;
+}
+FX_BYTE *CBC_QRCodeWriter::Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+{
+ return NULL;
+}
+FX_BYTE* CBC_QRCodeWriter::Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+{
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoder.cpp b/xfa/src/fxbarcode/src/BC_QRCoder.cpp
new file mode 100644
index 0000000000..51429202c6
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoder.cpp
@@ -0,0 +1,152 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_QRCoderMode.h"
+#include "include/BC_CommonByteMatrix.h"
+#include "include/BC_QRCoder.h"
+CBC_QRCoder::CBC_QRCoder()
+{
+ m_mode = NULL;
+ m_ecLevel = NULL;
+ m_version = -1;
+ m_matrixWidth = -1;
+ m_maskPattern = -1;
+ m_numTotalBytes = -1;
+ m_numDataBytes = -1;
+ m_numECBytes = -1;
+ m_numRSBlocks = -1;
+ m_matrix = NULL;
+}
+CBC_QRCoder::~CBC_QRCoder()
+{
+ if(m_matrix != NULL) {
+ delete m_matrix;
+ m_matrix = NULL;
+ }
+ m_mode = NULL;
+ m_ecLevel = NULL;
+ m_version = -1;
+ m_matrixWidth = -1;
+ m_maskPattern = -1;
+ m_numTotalBytes = -1;
+ m_numDataBytes = -1;
+ m_numECBytes = -1;
+ m_numRSBlocks = -1;
+}
+CBC_QRCoderMode* CBC_QRCoder::GetMode()
+{
+ return m_mode;
+}
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoder::GetECLevel()
+{
+ return m_ecLevel;
+}
+FX_INT32 CBC_QRCoder::GetVersion()
+{
+ return m_version;
+}
+FX_INT32 CBC_QRCoder::GetMatrixWidth()
+{
+ return m_matrixWidth;
+}
+FX_INT32 CBC_QRCoder::GetMaskPattern()
+{
+ return m_maskPattern;
+}
+FX_INT32 CBC_QRCoder::GetNumTotalBytes()
+{
+ return m_numTotalBytes;
+}
+FX_INT32 CBC_QRCoder::GetNumDataBytes()
+{
+ return m_numDataBytes;
+}
+FX_INT32 CBC_QRCoder::GetNumECBytes()
+{
+ return m_numECBytes;
+}
+FX_INT32 CBC_QRCoder::GetNumRSBlocks()
+{
+ return m_numRSBlocks;
+}
+CBC_CommonByteMatrix* CBC_QRCoder::GetMatrix()
+{
+ return m_matrix;
+}
+FX_INT32 CBC_QRCoder::At(FX_INT32 x, FX_INT32 y, FX_INT32 &e)
+{
+ FX_INT32 value = m_matrix->Get(x, y);
+ if(!(value == 0 || value == 1)) {
+ e = BCExceptionValueMustBeEither0or1;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ return value;
+}
+FX_BOOL CBC_QRCoder::IsValid()
+{
+ return
+ m_mode != NULL &&
+ m_ecLevel != NULL &&
+ m_version != -1 &&
+ m_matrixWidth != -1 &&
+ m_maskPattern != -1 &&
+ m_numTotalBytes != -1 &&
+ m_numDataBytes != -1 &&
+ m_numECBytes != -1 &&
+ m_numRSBlocks != -1 &&
+ IsValidMaskPattern(m_maskPattern) &&
+ m_numTotalBytes == m_numDataBytes + m_numECBytes &&
+ m_matrix != NULL &&
+ m_matrixWidth == m_matrix->GetWidth() &&
+ m_matrix->GetWidth() == m_matrix->GetHeight();
+}
+void CBC_QRCoder::SetMode(CBC_QRCoderMode* value)
+{
+ m_mode = value;
+}
+void CBC_QRCoder::SetECLevel(CBC_QRCoderErrorCorrectionLevel* ecLevel)
+{
+ m_ecLevel = ecLevel;
+}
+void CBC_QRCoder::SetVersion(FX_INT32 version)
+{
+ m_version = version;
+}
+void CBC_QRCoder::SetMatrixWidth(FX_INT32 width)
+{
+ m_matrixWidth = width;
+}
+void CBC_QRCoder::SetMaskPattern(FX_INT32 pattern)
+{
+ m_maskPattern = pattern;
+}
+void CBC_QRCoder::SetNumDataBytes(FX_INT32 bytes)
+{
+ m_numDataBytes = bytes;
+}
+void CBC_QRCoder::SetNumTotalBytes(FX_INT32 value)
+{
+ m_numTotalBytes = value;
+}
+void CBC_QRCoder::SetNumRSBlocks(FX_INT32 block)
+{
+ m_numRSBlocks = block;
+}
+void CBC_QRCoder::SetNumECBytes(FX_INT32 value)
+{
+ m_numECBytes = value;
+}
+FX_BOOL CBC_QRCoder::IsValidMaskPattern(FX_INT32 maskPattern)
+{
+ return maskPattern >= 0 && maskPattern < NUM_MASK_PATTERNS;
+}
+void CBC_QRCoder::SetMatrix(CBC_CommonByteMatrix* value)
+{
+ m_matrix = value;
+}
+const FX_INT32 CBC_QRCoder::NUM_MASK_PATTERNS = 8;
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderBitVector.cpp b/xfa/src/fxbarcode/src/BC_QRCoderBitVector.cpp
new file mode 100644
index 0000000000..26be81cc9b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderBitVector.cpp
@@ -0,0 +1,125 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderBitVector.h"
+CBC_QRCoderBitVector::CBC_QRCoderBitVector()
+{
+ m_sizeInBits = 0;
+ m_size = 32;
+}
+void CBC_QRCoderBitVector::Init()
+{
+ m_array = FX_Alloc(FX_BYTE, m_size);
+}
+CBC_QRCoderBitVector::~CBC_QRCoderBitVector()
+{
+ if(m_array != NULL) {
+ FX_Free(m_array);
+ }
+ m_size = 0;
+ m_sizeInBits = 0;
+}
+void CBC_QRCoderBitVector::Clear()
+{
+ if(m_array != NULL) {
+ FX_Free(m_array);
+ m_array = NULL;
+ }
+ m_sizeInBits = 0;
+ m_size = 32;
+ m_array = FX_Alloc(FX_BYTE, m_size);
+}
+FX_INT32 CBC_QRCoderBitVector::At(FX_INT32 index, FX_INT32 &e)
+{
+ if(index < 0 || index >= m_sizeInBits) {
+ e = BCExceptionBadIndexException;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ FX_INT32 value = m_array[index >> 3] & 0xff;
+ return (value >> (7 - (index & 0x7))) & 1;
+}
+FX_INT32 CBC_QRCoderBitVector::sizeInBytes()
+{
+ return (m_sizeInBits + 7) >> 3;
+}
+FX_INT32 CBC_QRCoderBitVector::Size()
+{
+ return m_sizeInBits;
+}
+void CBC_QRCoderBitVector::AppendBit(FX_INT32 bit, FX_INT32 &e)
+{
+ if(!(bit == 0 || bit == 1)) {
+ e = BCExceptionBadValueException;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 numBitsInLastByte = m_sizeInBits & 0x7;
+ if(numBitsInLastByte == 0) {
+ AppendByte(0);
+ m_sizeInBits -= 8;
+ }
+ m_array[m_sizeInBits >> 3] |= (bit << (7 - numBitsInLastByte));
+ ++m_sizeInBits;
+}
+void CBC_QRCoderBitVector::AppendBits(FX_INT32 value, FX_INT32 numBits, FX_INT32 &e)
+{
+ if (numBits < 0 || numBits > 32) {
+ e = BCExceptionBadNumBitsException;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 numBitsLeft = numBits;
+ while (numBitsLeft > 0) {
+ if ((m_sizeInBits & 0x7) == 0 && numBitsLeft >= 8) {
+ FX_INT32 newByte = (value >> (numBitsLeft - 8)) & 0xff;
+ AppendByte(newByte);
+ numBitsLeft -= 8;
+ } else {
+ FX_INT32 bit = (value >> (numBitsLeft - 1)) & 1;
+ AppendBit(bit, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ --numBitsLeft;
+ }
+ }
+}
+void CBC_QRCoderBitVector::AppendBitVector(CBC_QRCoderBitVector *bits, FX_INT32 &e)
+{
+ FX_INT32 size = bits->Size();
+ for(FX_INT32 i = 0; i < size; i++) {
+ FX_INT32 num = bits->At(i, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendBit(num, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ }
+}
+void CBC_QRCoderBitVector::XOR(CBC_QRCoderBitVector *other, FX_INT32 &e)
+{
+ if(m_sizeInBits != other->Size()) {
+ e = BCExceptioncanNotOperatexorOperator;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 sizeInBytes = (m_sizeInBits + 7) >> 3;
+ for(FX_INT32 i = 0; i < sizeInBytes; ++i) {
+ m_array[i] ^= (other->GetArray())[i];
+ }
+}
+FX_BYTE* CBC_QRCoderBitVector::GetArray()
+{
+ return m_array;
+}
+void CBC_QRCoderBitVector::AppendByte(FX_INT32 value)
+{
+ if((m_sizeInBits >> 3) == m_size) {
+ FX_BYTE* newArray = FX_Alloc(FX_BYTE, m_size << 1);
+ FXSYS_memcpy32(newArray, m_array, m_size);
+ if(m_array != NULL) {
+ FX_Free(m_array);
+ }
+ m_array = newArray;
+ m_size = m_size << 1;
+ }
+ m_array[m_sizeInBits >> 3] = (FX_BYTE) value;
+ m_sizeInBits += 8;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderBlockPair.cpp b/xfa/src/fxbarcode/src/BC_QRCoderBlockPair.cpp
new file mode 100644
index 0000000000..751ff0a85d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderBlockPair.cpp
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonByteArray.h"
+#include "include/BC_QRCoderBlockPair.h"
+CBC_QRCoderBlockPair::CBC_QRCoderBlockPair(CBC_CommonByteArray* data, CBC_CommonByteArray* errorCorrection)
+{
+ m_dataBytes = data;
+ m_errorCorrectionBytes = errorCorrection;
+}
+CBC_QRCoderBlockPair::~CBC_QRCoderBlockPair()
+{
+ if(m_dataBytes != NULL) {
+ delete m_dataBytes;
+ m_dataBytes = NULL;
+ }
+ if(m_errorCorrectionBytes != NULL) {
+ delete m_errorCorrectionBytes;
+ m_errorCorrectionBytes = NULL;
+ }
+}
+CBC_CommonByteArray* CBC_QRCoderBlockPair::GetDataBytes()
+{
+ return m_dataBytes;
+}
+CBC_CommonByteArray* CBC_QRCoderBlockPair::GetErrorCorrectionBytes()
+{
+ return m_errorCorrectionBytes;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderDecoder.cpp b/xfa/src/fxbarcode/src/BC_QRCoderDecoder.cpp
new file mode 100644
index 0000000000..7a3613137d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderDecoder.cpp
@@ -0,0 +1,112 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ReedSolomonDecoder.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_QRBitMatrixParser.h"
+#include "include/BC_QRDataBlock.h"
+#include "include/BC_QRDecodedBitStreamParser.h"
+#include "include/BC_QRCoderVersion.h"
+#include "include/BC_QRCoderFormatInformation.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_QRCoderDecoder.h"
+CBC_QRCoderDecoder::CBC_QRCoderDecoder()
+{
+ m_rsDecoder = NULL;
+}
+
+void CBC_QRCoderDecoder::Init()
+{
+ m_rsDecoder = FX_NEW CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256::QRCodeFild);
+}
+CBC_QRCoderDecoder::~CBC_QRCoderDecoder()
+{
+ if(m_rsDecoder != NULL) {
+ delete m_rsDecoder;
+ }
+ m_rsDecoder = NULL;
+}
+CBC_CommonDecoderResult* CBC_QRCoderDecoder::Decode(FX_BOOL* image, FX_INT32 width, FX_INT32 height, FX_INT32 &e)
+{
+ CBC_CommonBitMatrix bits;
+ bits.Init(width);
+ for(FX_INT32 i = 0; i < width; i++) {
+ for(FX_INT32 j = 0; j < height; j++) {
+ if(image[i * width + j]) {
+ bits.Set(j, i);
+ }
+ }
+ }
+ CBC_CommonDecoderResult* cdr = Decode(&bits, height, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return cdr;
+}
+CBC_CommonDecoderResult* CBC_QRCoderDecoder::Decode(CBC_CommonBitMatrix* bits, FX_INT32 byteModeDecode, FX_INT32 &e)
+{
+ CBC_QRBitMatrixParser parser;
+ parser.Init(bits, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_QRCoderVersion *version = parser.ReadVersion(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_QRCoderFormatInformation* temp = parser.ReadFormatInformation(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_QRCoderErrorCorrectionLevel* ecLevel = temp->GetErrorCorrectionLevel();
+ CFX_ByteArray* ba = parser.ReadCodewords(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CFX_ByteArray > codewords(ba);
+ CFX_PtrArray *dataBlocks = CBC_QRDataBlock::GetDataBlocks(codewords.get(), version, ecLevel, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 totalBytes = 0;
+ for (FX_INT32 i = 0; i < dataBlocks->GetSize(); i++) {
+ totalBytes += ((CBC_QRDataBlock*) ((*dataBlocks)[i]))->GetNumDataCodewords();
+ }
+ CFX_ByteArray resultBytes;
+ FX_INT32 resultOffset = 0;
+ for (FX_INT32 j = 0; j < dataBlocks->GetSize(); j++) {
+ CBC_QRDataBlock *dataBlock = (CBC_QRDataBlock *)((*dataBlocks)[j]);
+ CFX_ByteArray* codewordBytes = dataBlock->GetCodewords();
+ FX_INT32 numDataCodewords = dataBlock->GetNumDataCodewords();
+ CorrectErrors(codewordBytes, numDataCodewords, e);
+ if (e != BCExceptionNO) {
+ for(FX_INT32 k = 0; k < dataBlocks->GetSize(); k++) {
+ delete (CBC_QRDataBlock*)(*dataBlocks)[k];
+ }
+ dataBlocks->RemoveAll();
+ delete dataBlocks;
+ dataBlocks = NULL;
+ return NULL;
+ }
+ for(FX_INT32 i = 0; i < numDataCodewords; i++) {
+ resultBytes.Add((*codewordBytes)[i]);
+ }
+ }
+ for(FX_INT32 k = 0; k < dataBlocks->GetSize(); k++) {
+ delete (CBC_QRDataBlock*)(*dataBlocks)[k] ;
+ }
+ dataBlocks->RemoveAll();
+ delete dataBlocks;
+ dataBlocks = NULL;
+ CBC_CommonDecoderResult* cdr = CBC_QRDecodedBitStreamParser::Decode(&resultBytes, version, ecLevel, byteModeDecode, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return cdr;
+}
+void CBC_QRCoderDecoder::CorrectErrors(CFX_ByteArray* codewordBytes, FX_INT32 numDataCodewords, FX_INT32 &e)
+{
+ FX_INT32 numCodewords = codewordBytes->GetSize();
+ CFX_Int32Array codewordsInts;
+ codewordsInts.SetSize(numCodewords);
+ for(FX_INT32 i = 0; i < numCodewords; i++) {
+ codewordsInts[i] = (FX_INT32)((*codewordBytes)[i] & 0xff);
+ }
+ FX_INT32 numECCodewords = codewordBytes->GetSize() - numDataCodewords;
+ m_rsDecoder->Decode(&codewordsInts, numECCodewords, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ for(FX_INT32 k = 0; k < numDataCodewords; k++) {
+ (*codewordBytes)[k] = (FX_BYTE) codewordsInts[k];
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderECB.cpp b/xfa/src/fxbarcode/src/BC_QRCoderECB.cpp
new file mode 100644
index 0000000000..e7e971f299
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderECB.cpp
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderECB.h"
+CBC_QRCoderECB::CBC_QRCoderECB(FX_INT32 count, FX_INT32 dataCodeWords)
+{
+ m_dataCodeWords = dataCodeWords;
+ m_count = count;
+}
+CBC_QRCoderECB::~CBC_QRCoderECB()
+{
+}
+FX_INT32 CBC_QRCoderECB::GetCount()
+{
+ return m_count;
+}
+FX_INT32 CBC_QRCoderECB::GetDataCodeWords()
+{
+ return m_dataCodeWords;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderECBlocks.cpp b/xfa/src/fxbarcode/src/BC_QRCoderECBlocks.cpp
new file mode 100644
index 0000000000..ad8997343b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderECBlocks.cpp
@@ -0,0 +1,49 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderECB.h"
+#include "include/BC_QRCoderECBlocks.h"
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks)
+{
+ m_ecCodeWordsPerBlock = ecCodeWordsPerBlock;
+ m_ecBlocks.Add(ecBlocks);
+}
+CBC_QRCoderECBlocks::CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock,
+ CBC_QRCoderECB* ecBlocks1,
+ CBC_QRCoderECB* ecBlocks2)
+{
+ m_ecCodeWordsPerBlock = ecCodeWordsPerBlock;
+ m_ecBlocks.Add(ecBlocks1);
+ m_ecBlocks.Add(ecBlocks2);
+}
+CBC_QRCoderECBlocks::~CBC_QRCoderECBlocks()
+{
+ for (FX_INT32 i = 0 ; i < m_ecBlocks.GetSize(); i++) {
+ delete ( (CBC_QRCoderECB*)(m_ecBlocks[i]) ) ;
+ }
+ m_ecBlocks.RemoveAll();
+}
+FX_INT32 CBC_QRCoderECBlocks::GetECCodeWordsPerBlock()
+{
+ return m_ecCodeWordsPerBlock;
+}
+FX_INT32 CBC_QRCoderECBlocks::GetNumBlocks()
+{
+ FX_INT32 total = 0;
+ for(FX_INT32 i = 0; i < m_ecBlocks.GetSize(); i++) {
+ total += ( (CBC_QRCoderECB*)(m_ecBlocks[i]) )->GetCount();
+ }
+ return total;
+}
+FX_INT32 CBC_QRCoderECBlocks::GetTotalECCodeWords()
+{
+ return m_ecCodeWordsPerBlock * GetNumBlocks();
+}
+CFX_PtrArray* CBC_QRCoderECBlocks::GetECBlocks()
+{
+ return &m_ecBlocks;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderEncoder.cpp b/xfa/src/fxbarcode/src/BC_QRCoderEncoder.cpp
new file mode 100644
index 0000000000..b6e3fb8cfc
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderEncoder.cpp
@@ -0,0 +1,860 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoder.h"
+#include "include/BC_QRCoderEncoder.h"
+#include "include/BC_CommonByteArray.h"
+#include "include/BC_QRCoderMode.h"
+#include "include/BC_QRCoderEncoder.h"
+#include "include/BC_QRCoderECBlocks.h"
+#include "include/BC_QRCoderVersion.h"
+#include "include/BC_QRCoderBlockPair.h"
+#include "include/BC_QRCoderMaskUtil.h"
+#include "include/BC_QRCoderMatrixUtil.h"
+#include "include/BC_ReedSolomon.h"
+#include "include/BC_CommonByteMatrix.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_UtilCodingConvert.h"
+#include "include/BC_QRCoderBitVector.h"
+const FX_INT32 CBC_QRCoderEncoder::m_alphaNumbericTable[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 36, -1, -1, -1, 37, 38, -1, -1, -1, -1, 39, 40, -1, 41, 42, 43,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 44, -1, -1, -1, -1, -1,
+ -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1
+};
+CBC_QRCoderEncoder::CBC_QRCoderEncoder()
+{
+}
+CBC_QRCoderEncoder::~CBC_QRCoderEncoder()
+{
+}
+class Make_Pair : public CFX_Object
+{
+public:
+ CBC_QRCoderMode* m_mode;
+ CFX_ByteString m_string;
+private:
+ Make_Pair(const Make_Pair &mode_string) {}
+ Make_Pair &operator = (Make_Pair &mode_string)
+ {
+ if (this == &mode_string) {
+ return *this;
+ }
+ m_mode = mode_string.m_mode;
+ m_string = mode_string.m_string;
+ return *this;
+ }
+public:
+ Make_Pair(CBC_QRCoderMode *mode, const CFX_ByteString &str): m_mode(mode), m_string(str) {}
+ ~Make_Pair() {}
+};
+void CBC_QRCoderEncoder::Encode(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder *qrCode, FX_INT32 &e, FX_INT32 versionSpecify)
+{
+ if(versionSpecify == 0) {
+ EncodeWithAutoVersion(content, ecLevel, qrCode, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ } else if(versionSpecify > 0 && versionSpecify <= 40) {
+ EncodeWithSpecifyVersion(content, ecLevel, qrCode, versionSpecify, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else {
+ e = BCExceptionVersionMust1_40;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::AppendECI(CBC_QRCoderBitVector* bits)
+{
+}
+void CBC_QRCoderEncoder::AppendDataModeLenghInfo(CFX_PtrArray &splitResult, CBC_QRCoderBitVector &headerAndDataBits,
+ CBC_QRCoderMode *tempMode, CBC_QRCoder *qrCode, CFX_ByteString &encoding, FX_INT32 &e)
+{
+ for(FX_INT32 i = 0; i < splitResult.GetSize(); i++) {
+ tempMode = ((Make_Pair*)splitResult[i])->m_mode;
+ if(tempMode == CBC_QRCoderMode::sGBK) {
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode, &headerAndDataBits, encoding, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else if(tempMode == CBC_QRCoderMode::sBYTE) {
+ CFX_ByteArray bytes;
+ CBC_UtilCodingConvert::LocaleToUtf8(((Make_Pair*)splitResult[i])->m_string, bytes);
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendLengthInfo(bytes.GetSize(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ Append8BitBytes(bytes, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else if(tempMode == CBC_QRCoderMode::sALPHANUMERIC) {
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode, &headerAndDataBits, encoding, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else if(tempMode == CBC_QRCoderMode::sNUMERIC) {
+ AppendModeInfo(tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendLengthInfo(((Make_Pair*)splitResult[i])->m_string.GetLength(), qrCode->GetVersion(), tempMode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ AppendBytes(((Make_Pair*)splitResult[i])->m_string, tempMode, &headerAndDataBits, encoding, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else {
+ e = BCExceptionUnknown;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ }
+}
+void CBC_QRCoderEncoder::SplitString(const CFX_ByteString &content, CFX_PtrArray &result)
+{
+ FX_INT32 index = 0, flag = 0;
+ while((((FX_BYTE)content[index] >= 0xA1 && (FX_BYTE)content[index] <= 0xAA) ||
+ ((FX_BYTE)content[index] >= 0xB0 && (FX_BYTE)content[index] <= 0xFA)) && (index < content.GetLength())) {
+ index += 2;
+ }
+ if(index != flag) {
+ result.Add(FX_NEW Make_Pair(CBC_QRCoderMode::sGBK, content.Mid(flag, index - flag)));
+ }
+ flag = index;
+ if(index >= content.GetLength()) {
+ return;
+ }
+ while(GetAlphaNumericCode((FX_BYTE)content[index]) == -1
+ && !(((FX_BYTE)content[index] >= 0xA1 && (FX_BYTE)content[index] <= 0xAA) ||
+ ((FX_BYTE)content[index] >= 0xB0 && (FX_BYTE)content[index] <= 0xFA))
+ && (index < content.GetLength())) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ if(IsDBCSLeadByte((FX_BYTE)content[index]))
+#else
+ if((FX_BYTE)content[index] > 127)
+#endif
+ {
+ index += 2;
+ } else {
+ index++;
+ }
+ }
+ if(index != flag) {
+ result.Add(FX_NEW Make_Pair(CBC_QRCoderMode::sBYTE, content.Mid(flag, index - flag)));
+ }
+ flag = index;
+ if(index >= content.GetLength()) {
+ return;
+ }
+ while(FXSYS_Isdigit((FX_BYTE)content[index]) && (index < content.GetLength())) {
+ index++;
+ }
+ if(index != flag) {
+ result.Add(FX_NEW Make_Pair(CBC_QRCoderMode::sNUMERIC, content.Mid(flag, index - flag)));
+ }
+ flag = index;
+ if(index >= content.GetLength()) {
+ return;
+ }
+ while(GetAlphaNumericCode((FX_BYTE)content[index]) != -1 && (index < content.GetLength())) {
+ index++;
+ }
+ if(index != flag) {
+ result.Add(FX_NEW Make_Pair(CBC_QRCoderMode::sALPHANUMERIC, content.Mid(flag, index - flag)));
+ }
+ flag = index;
+ if(index >= content.GetLength()) {
+ return;
+ }
+ SplitString(content.Mid(index, content.GetLength() - index), result);
+}
+FX_INT32 CBC_QRCoderEncoder::GetSpanByVersion(CBC_QRCoderMode *modeFirst, CBC_QRCoderMode *modeSecond, FX_INT32 versionNum, FX_INT32 &e)
+{
+ if(versionNum == 0) {
+ return 0;
+ }
+ if((modeFirst == CBC_QRCoderMode::sALPHANUMERIC)
+ && (modeSecond == CBC_QRCoderMode::sBYTE)) {
+ if(versionNum >= 1 && versionNum <= 9) {
+ return 11;
+ } else if(versionNum >= 10 && versionNum <= 26) {
+ return 15;
+ } else if(versionNum >= 27 && versionNum <= 40) {
+ return 16;
+ } else {
+ e = BCExceptionNoSuchVersion;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ } else if((modeSecond == CBC_QRCoderMode::sALPHANUMERIC)
+ && (modeFirst == CBC_QRCoderMode::sNUMERIC)) {
+ if(versionNum >= 1 && versionNum <= 9) {
+ return 13;
+ } else if(versionNum >= 10 && versionNum <= 26) {
+ return 15;
+ } else if(versionNum >= 27 && versionNum <= 40) {
+ return 17;
+ } else {
+ e = BCExceptionNoSuchVersion;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ } else if((modeSecond == CBC_QRCoderMode::sBYTE)
+ && (modeFirst == CBC_QRCoderMode::sNUMERIC)) {
+ if(versionNum >= 1 && versionNum <= 9) {
+ return 6;
+ } else if(versionNum >= 10 && versionNum <= 26) {
+ return 8;
+ } else if(versionNum >= 27 && versionNum <= 40) {
+ return 9;
+ } else {
+ e = BCExceptionNoSuchVersion;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ }
+ return -1;
+}
+void CBC_QRCoderEncoder::MergeString(CFX_PtrArray &result, FX_INT32 versionNum, FX_INT32 &e)
+{
+ Make_Pair *first = NULL;
+ Make_Pair *second = NULL;
+ size_t mergeNum = 0;
+ FX_INT32 i;
+ for(i = 0; ((i < result.GetSize()) && (i + 1 < result.GetSize())); i++) {
+ first = (Make_Pair*)result[i];
+ second = (Make_Pair*)result[i + 1];
+ if(first->m_mode == CBC_QRCoderMode::sALPHANUMERIC) {
+ FX_INT32 tmp = GetSpanByVersion(CBC_QRCoderMode::sALPHANUMERIC, CBC_QRCoderMode::sBYTE, versionNum, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if((second->m_mode == CBC_QRCoderMode::sBYTE)
+ && (first->m_string.GetLength() < tmp)) {
+ CFX_ByteString str = first->m_string + second->m_string;
+ second->m_string = str;
+ delete first;
+ result.RemoveAt(i);
+ i--;
+ mergeNum++;
+ }
+ } else if(first->m_mode == CBC_QRCoderMode::sBYTE) {
+ if(second->m_mode == CBC_QRCoderMode::sBYTE) {
+ first->m_string += second->m_string;
+ delete second;
+ result.RemoveAt(i + 1);
+ i--;
+ mergeNum++;
+ }
+ } else if(first->m_mode == CBC_QRCoderMode::sNUMERIC) {
+ FX_INT32 tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC, CBC_QRCoderMode::sBYTE, versionNum, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if((second->m_mode == CBC_QRCoderMode::sBYTE)
+ && (first->m_string.GetLength() < tmp)) {
+ CFX_ByteString str = first->m_string + second->m_string;
+ second->m_string = str;
+ delete first;
+ result.RemoveAt(i);
+ i--;
+ mergeNum++;
+ }
+ tmp = GetSpanByVersion(CBC_QRCoderMode::sNUMERIC, CBC_QRCoderMode::sALPHANUMERIC, versionNum, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if((second->m_mode == CBC_QRCoderMode::sALPHANUMERIC)
+ && (first->m_string.GetLength() < tmp)) {
+ CFX_ByteString str = first->m_string + second->m_string;
+ second->m_string = str;
+ delete first;
+ result.RemoveAt(i);
+ i--;
+ mergeNum++;
+ }
+ }
+ }
+ if(mergeNum == 0) {
+ return;
+ }
+ MergeString(result, versionNum, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderEncoder::InitQRCode(FX_INT32 numInputBytes, FX_INT32 versionNumber,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e)
+{
+ qrCode->SetECLevel(ecLevel);
+ qrCode->SetMode(mode);
+ CBC_QRCoderVersion* version = CBC_QRCoderVersion::GetVersionForNumber(versionNumber, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 numBytes = version->GetTotalCodeWords();
+ CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
+ FX_INT32 numEcBytes = ecBlocks->GetTotalECCodeWords();
+ FX_INT32 numRSBlocks = ecBlocks->GetNumBlocks();
+ FX_INT32 numDataBytes = numBytes - numEcBytes;
+ if(numDataBytes >= numInputBytes + 3) {
+ qrCode->SetVersion(versionNumber);
+ qrCode->SetNumTotalBytes(numBytes);
+ qrCode->SetNumDataBytes(numDataBytes);
+ qrCode->SetNumRSBlocks(numRSBlocks);
+ qrCode->SetNumECBytes(numEcBytes);
+ qrCode->SetMatrixWidth(version->GetDimensionForVersion());
+ return;
+ }
+ e = BCExceptionCannotFindBlockInfo;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderEncoder::EncodeWithSpecifyVersion(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder *qrCode, FX_INT32 versionSpecify, FX_INT32 &e)
+{
+ CFX_ByteString encoding = "utf8";
+ CBC_QRCoderMode *mode = CBC_QRCoderMode::sBYTE;
+ CFX_PtrArray splitResult;
+ CBC_QRCoderBitVector dataBits;
+ dataBits.Init();
+ SplitString(content, splitResult);
+ MergeString(splitResult, versionSpecify, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ CBC_QRCoderMode *tempMode = NULL;
+ for(FX_INT32 i = 0; i < splitResult.GetSize(); i++) {
+ AppendBytes(((Make_Pair*)splitResult[i])->m_string, ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e);
+ if(e != BCExceptionNO) {
+ for(FX_INT32 y = 0; y < splitResult.GetSize(); y++) {
+ delete (Make_Pair*)splitResult[y];
+ }
+ splitResult.RemoveAll();
+ return;
+ }
+ }
+ FX_INT32 numInputBytes = dataBits.sizeInBytes();
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ InitQRCode(numInputBytes, versionSpecify, ecLevel, mode, qrCode, e);
+ if(e != BCExceptionNO) {
+ for(FX_INT32 k = 0; k < splitResult.GetSize(); k++) {
+ delete (Make_Pair*)splitResult[k];
+ }
+ splitResult.RemoveAll();
+ return ;
+ }
+ AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode, encoding, e);
+ if(e != BCExceptionNO) {
+ for(FX_INT32 k = 0; k < splitResult.GetSize(); k++) {
+ delete (Make_Pair*)splitResult[k];
+ }
+ splitResult.RemoveAll();
+ return ;
+ }
+ numInputBytes = headerAndDataBits.sizeInBytes();
+ TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+ if(e != BCExceptionNO) {
+ for(FX_INT32 k = 0; k < splitResult.GetSize(); k++) {
+ delete (Make_Pair*)splitResult[k];
+ }
+ splitResult.RemoveAll();
+ return ;
+ }
+ for(FX_INT32 j = 0; j < splitResult.GetSize(); j++) {
+ delete (Make_Pair*)splitResult[j];
+ }
+ splitResult.RemoveAll();
+ CBC_QRCoderBitVector finalBits ;
+ finalBits.Init();
+ InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), qrCode->GetNumDataBytes(),
+ qrCode->GetNumRSBlocks(), &finalBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_CommonByteMatrix* pDecoder = FX_NEW CBC_CommonByteMatrix(qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
+ pDecoder->Init();
+ CBC_AutoPtr<CBC_CommonByteMatrix> matrix(pDecoder);
+ FX_INT32 maskPattern = ChooseMaskPattern(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ qrCode->SetMaskPattern(maskPattern);
+ CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), qrCode->GetMaskPattern(), matrix.get(), e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ qrCode->SetMatrix(matrix.release());
+ if(!qrCode->IsValid()) {
+ e = BCExceptionInvalidQRCode;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::EncodeWithAutoVersion(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e)
+{
+ CFX_ByteString encoding = "utf8";
+ CBC_QRCoderMode *mode = CBC_QRCoderMode::sBYTE;
+ CFX_PtrArray splitResult;
+ CBC_QRCoderBitVector dataBits;
+ dataBits.Init();
+ SplitString(content, splitResult);
+ MergeString(splitResult, 8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_QRCoderMode *tempMode = NULL;
+ for(FX_INT32 i = 0; i < splitResult.GetSize(); i++) {
+ AppendBytes(((Make_Pair*)splitResult[i])->m_string, ((Make_Pair*)splitResult[i])->m_mode, &dataBits, encoding, e);
+ if(e != BCExceptionNO) {
+ for(FX_INT32 l = 0; l < splitResult.GetSize(); l++) {
+ delete (Make_Pair*)splitResult[l];
+ }
+ splitResult.RemoveAll();
+ return;
+ }
+ }
+ FX_INT32 numInputBytes = dataBits.sizeInBytes();
+ InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ tempMode = NULL;
+ FX_INT32 versionNum = qrCode->GetVersion();
+sign:
+ AppendDataModeLenghInfo(splitResult, headerAndDataBits, tempMode, qrCode, encoding, e);
+ if (e != BCExceptionNO) {
+ goto catchException;
+ }
+ numInputBytes = headerAndDataBits.sizeInBytes();
+ TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+ if (e != BCExceptionNO) {
+ goto catchException;
+ }
+catchException:
+ if (e != BCExceptionNO) {
+ FX_INT32 e1 = BCExceptionNO;
+ InitQRCode(numInputBytes, ecLevel, mode, qrCode, e1);
+ if (e1 != BCExceptionNO) {
+ e = e1;
+ return;
+ }
+ versionNum++;
+ if (versionNum <= 40) {
+ headerAndDataBits.Clear();
+ e = BCExceptionNO;
+ goto sign;
+ } else {
+ for (FX_INT32 j = 0; j < splitResult.GetSize(); j++) {
+ delete (Make_Pair*)splitResult[j];
+ }
+ splitResult.RemoveAll();
+ return;
+ }
+ }
+ for (FX_INT32 k = 0; k < splitResult.GetSize(); k++) {
+ delete (Make_Pair*)splitResult[k];
+ }
+ splitResult.RemoveAll();
+ CBC_QRCoderBitVector finalBits ;
+ finalBits.Init();
+ InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), qrCode->GetNumDataBytes(),
+ qrCode->GetNumRSBlocks(), &finalBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_CommonByteMatrix* pDecoder = FX_NEW CBC_CommonByteMatrix(qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
+ pDecoder->Init();
+ CBC_AutoPtr<CBC_CommonByteMatrix> matrix(pDecoder);
+ FX_INT32 maskPattern = ChooseMaskPattern(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ qrCode->SetMaskPattern(maskPattern);
+ CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), qrCode->GetMaskPattern(), matrix.get(), e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ qrCode->SetMatrix(matrix.release());
+ if(!qrCode->IsValid()) {
+ e = BCExceptionInvalidQRCode;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::Encode(const CFX_WideString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e)
+{
+ CFX_ByteString encoding = "utf8";
+ CFX_ByteString utf8Data;
+ CBC_UtilCodingConvert::UnicodeToUTF8(content, utf8Data);
+ CBC_QRCoderMode* mode = ChooseMode(utf8Data, encoding);
+ CBC_QRCoderBitVector dataBits;
+ dataBits.Init();
+ AppendBytes(utf8Data, mode, &dataBits, encoding, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 numInputBytes = dataBits.sizeInBytes();
+ InitQRCode(numInputBytes, ecLevel, mode, qrCode, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_QRCoderBitVector headerAndDataBits;
+ headerAndDataBits.Init();
+ AppendModeInfo(mode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 numLetters = mode == CBC_QRCoderMode::sBYTE ? dataBits.sizeInBytes() : content.GetLength();
+ AppendLengthInfo(numLetters, qrCode->GetVersion(), mode, &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ headerAndDataBits.AppendBitVector(&dataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ TerminateBits(qrCode->GetNumDataBytes(), &headerAndDataBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_QRCoderBitVector finalBits ;
+ finalBits.Init();
+ InterleaveWithECBytes(&headerAndDataBits, qrCode->GetNumTotalBytes(), qrCode->GetNumDataBytes(),
+ qrCode->GetNumRSBlocks(), &finalBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_CommonByteMatrix* pDecoder = FX_NEW CBC_CommonByteMatrix(qrCode->GetMatrixWidth(), qrCode->GetMatrixWidth());
+ pDecoder->Init();
+ CBC_AutoPtr<CBC_CommonByteMatrix> matrix(pDecoder);
+ FX_INT32 maskPattern = ChooseMaskPattern(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), matrix.get(), e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ qrCode->SetMaskPattern(maskPattern);
+ CBC_QRCoderMatrixUtil::BuildMatrix(&finalBits, qrCode->GetECLevel(), qrCode->GetVersion(), qrCode->GetMaskPattern(), matrix.get(), e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ qrCode->SetMatrix(matrix.release());
+ if(!qrCode->IsValid()) {
+ e = BCExceptionInvalidQRCode;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::TerminateBits(FX_INT32 numDataBytes, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ FX_INT32 capacity = numDataBytes << 3;
+ if(bits->Size() > capacity) {
+ e = BCExceptionDataTooMany;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for (FX_INT32 i = 0; i < 4 && bits->Size() < capacity; ++i) {
+ bits->AppendBit(0, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 numBitsInLastByte = bits->Size() % 8;
+ if (numBitsInLastByte > 0) {
+ FX_INT32 numPaddingBits = 8 - numBitsInLastByte;
+ for (FX_INT32 j = 0; j < numPaddingBits; ++j) {
+ bits->AppendBit(0, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ }
+ }
+ if (bits->Size() % 8 != 0) {
+ e = BCExceptionDigitLengthMustBe8;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 numPaddingBytes = numDataBytes - bits->sizeInBytes();
+ for (FX_INT32 k = 0; k < numPaddingBytes; ++k) {
+ if (k % 2 == 0) {
+ bits->AppendBits(0xec, 8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else {
+ bits->AppendBits(0x11, 8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ }
+ if (bits->Size() != capacity) {
+ e = BCExceptionBitsNotEqualCacity;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+FX_INT32 CBC_QRCoderEncoder::ChooseMaskPattern(CBC_QRCoderBitVector* bits, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ FX_INT32 minPenalty = 65535;
+ FX_INT32 bestMaskPattern = -1;
+ for(FX_INT32 maskPattern = 0; maskPattern < CBC_QRCoder::NUM_MASK_PATTERNS; maskPattern++) {
+ CBC_QRCoderMatrixUtil::BuildMatrix(bits, ecLevel, version, maskPattern, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ FX_INT32 penalty = CalculateMaskPenalty(matrix);
+ if(penalty < minPenalty) {
+ minPenalty = penalty;
+ bestMaskPattern = maskPattern;
+ }
+ }
+ return bestMaskPattern;
+}
+FX_INT32 CBC_QRCoderEncoder::CalculateMaskPenalty(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 penalty = 0;
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(matrix);
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(matrix);
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(matrix);
+ penalty += CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(matrix);
+ return penalty;
+}
+CBC_QRCoderMode *CBC_QRCoderEncoder::ChooseMode(const CFX_ByteString &content, CFX_ByteString encoding)
+{
+ if(encoding.Compare("SHIFT_JIS") == 0) {
+ return CBC_QRCoderMode::sKANJI;
+ }
+ FX_BOOL hasNumeric = FALSE;
+ FX_BOOL hasAlphaNumeric = FALSE;
+ for(FX_INT32 i = 0; i < content.GetLength(); i++) {
+ if(isdigit((FX_BYTE)content[i])) {
+ hasNumeric = TRUE;
+ } else if(GetAlphaNumericCode((FX_BYTE)content[i]) != -1) {
+ hasAlphaNumeric = TRUE;
+ } else {
+ return CBC_QRCoderMode::sBYTE;
+ }
+ }
+ if(hasAlphaNumeric) {
+ return CBC_QRCoderMode::sALPHANUMERIC;
+ } else if(hasNumeric) {
+ return CBC_QRCoderMode::sNUMERIC;
+ }
+ return CBC_QRCoderMode::sBYTE;
+}
+FX_INT32 CBC_QRCoderEncoder::GetAlphaNumericCode(FX_INT32 code)
+{
+ if(code < 96 && code >= 0) {
+ return m_alphaNumbericTable[code];
+ }
+ return -1;
+}
+void CBC_QRCoderEncoder::AppendBytes(const CFX_ByteString &content, CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, CFX_ByteString encoding, FX_INT32 &e)
+{
+ if(mode == CBC_QRCoderMode::sNUMERIC) {
+ AppendNumericBytes(content, bits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else if(mode == CBC_QRCoderMode::sALPHANUMERIC) {
+ AppendAlphaNumericBytes(content, bits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else if(mode == CBC_QRCoderMode::sBYTE) {
+ Append8BitBytes(content, bits, encoding, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else if(mode == CBC_QRCoderMode::sKANJI) {
+ AppendKanjiBytes(content, bits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else if(mode == CBC_QRCoderMode::sGBK) {
+ AppendGBKBytes(content, bits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ } else {
+ e = BCExceptionUnsupportedMode;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::AppendNumericBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ FX_INT32 length = content.GetLength();
+ FX_INT32 i = 0;
+ while(i < length) {
+ FX_INT32 num1 = content[i] - '0';
+ if(i + 2 < length) {
+ FX_INT32 num2 = content[i + 1] - '0';
+ FX_INT32 num3 = content[i + 2] - '0';
+ bits->AppendBits(num1 * 100 + num2 * 10 + num3, 10, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ i += 3;
+ } else if(i + 1 < length) {
+ FX_INT32 num2 = content[i + 1] - '0';
+ bits->AppendBits(num1 * 10 + num2, 7, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ i += 2;
+ } else {
+ bits->AppendBits(num1, 4, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ i++;
+ }
+ }
+}
+void CBC_QRCoderEncoder::AppendAlphaNumericBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ FX_INT32 length = content.GetLength();
+ FX_INT32 i = 0;
+ while(i < length) {
+ FX_INT32 code1 = GetAlphaNumericCode(content[i]);
+ if(code1 == -1) {
+ e = BCExceptionInvalidateCharacter;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(i + 1 < length) {
+ FX_INT32 code2 = GetAlphaNumericCode(content[i + 1]);
+ if(code2 == -1) {
+ e = BCExceptionInvalidateCharacter;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ bits->AppendBits(code1 * 45 + code2, 11, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ i += 2;
+ } else {
+ bits->AppendBits(code1, 6, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ i++;
+ }
+ }
+}
+void CBC_QRCoderEncoder::AppendGBKBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ FX_INT32 length = content.GetLength();
+ FX_DWORD value = 0;
+ for(FX_INT32 i = 0; i < length; i += 2) {
+ value = (FX_DWORD)((FX_BYTE)content[i] << 8 | (FX_BYTE)content[i + 1]);
+ if(value <= 0xAAFE && value >= 0xA1A1) {
+ value -= 0xA1A1;
+ } else if(value <= 0xFAFE && value >= 0xB0A1) {
+ value -= 0xA6A1;
+ } else {
+ e = BCExceptionInvalidateCharacter;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ value = (FX_DWORD)((value >> 8 ) * 0x60) + (FX_DWORD)(value & 0xff);
+ bits->AppendBits(value, 13, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::Append8BitBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, CFX_ByteString encoding, FX_INT32 &e)
+{
+ for(FX_INT32 i = 0; i < content.GetLength(); i++) {
+ bits->AppendBits(content[i], 8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::Append8BitBytes(CFX_ByteArray &bytes, CBC_QRCoderBitVector *bits, FX_INT32 &e)
+{
+ for(FX_INT32 i = 0; i < bytes.GetSize(); i++) {
+ bits->AppendBits(bytes[i], 8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::AppendKanjiBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ CFX_ByteArray bytes;
+ FX_DWORD value = 0, h = 0;
+ for(FX_INT32 i = 0; i < bytes.GetSize(); i += 2) {
+ value = (FX_DWORD)((FX_BYTE)(content[i] << 8) | (FX_BYTE)content[i + 1]);
+ if(value <= 0x9ffc && value >= 0x8140) {
+ value -= 0x8140;
+ } else if(value <= 0xebbf && value >= 0xe040) {
+ value -= 0xc140;
+ } else {
+ e = BCExceptionInvalidateCharacter;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ value = (FX_DWORD)((value >> 8 ) * 0xc0) + (FX_DWORD)(value & 0xff);
+ bits->AppendBits(value, 13, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::InitQRCode(FX_INT32 numInputBytes, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e)
+{
+ qrCode->SetECLevel(ecLevel);
+ qrCode->SetMode(mode);
+ for(FX_INT32 versionNum = 1; versionNum <= 40; versionNum++) {
+ CBC_QRCoderVersion* version = CBC_QRCoderVersion::GetVersionForNumber(versionNum, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 numBytes = version->GetTotalCodeWords();
+ CBC_QRCoderECBlocks* ecBlocks = version->GetECBlocksForLevel(ecLevel);
+ FX_INT32 numEcBytes = ecBlocks->GetTotalECCodeWords();
+ FX_INT32 numRSBlocks = ecBlocks->GetNumBlocks();
+ FX_INT32 numDataBytes = numBytes - numEcBytes;
+ if(numDataBytes >= numInputBytes + 3) {
+ qrCode->SetVersion(versionNum);
+ qrCode->SetNumTotalBytes(numBytes);
+ qrCode->SetNumDataBytes(numDataBytes);
+ qrCode->SetNumRSBlocks(numRSBlocks);
+ qrCode->SetNumECBytes(numEcBytes);
+ qrCode->SetMatrixWidth(version->GetDimensionForVersion());
+ return;
+ }
+ }
+ e = BCExceptionCannotFindBlockInfo;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderEncoder::AppendModeInfo(CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ bits->AppendBits(mode->GetBits(), 4, e);
+ if(mode == CBC_QRCoderMode::sGBK) {
+ bits->AppendBits(1, 4, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::AppendLengthInfo(FX_INT32 numLetters, FX_INT32 version, CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ CBC_QRCoderVersion* qcv = CBC_QRCoderVersion::GetVersionForNumber(version, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 numBits = mode->GetCharacterCountBits(qcv, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(numBits > ((1 << numBits) - 1)) {
+ return;
+ }
+ if(mode == CBC_QRCoderMode::sGBK) {
+ bits->AppendBits(numLetters / 2, numBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ bits->AppendBits(numLetters, numBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderEncoder::InterleaveWithECBytes(CBC_QRCoderBitVector* bits, FX_INT32 numTotalBytes, FX_INT32 numDataBytes, FX_INT32 numRSBlocks, CBC_QRCoderBitVector* result, FX_INT32 &e)
+{
+ if(bits->sizeInBytes() != numDataBytes) {
+ e = BCExceptionBitsBytesNotMatch;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 dataBytesOffset = 0;
+ FX_INT32 maxNumDataBytes = 0;
+ FX_INT32 maxNumEcBytes = 0;
+ CFX_PtrArray blocks;
+ FX_INT32 i;
+ for(i = 0; i < numRSBlocks; i++) {
+ FX_INT32 numDataBytesInBlock;
+ FX_INT32 numEcBytesInBlosk;
+ GetNumDataBytesAndNumECBytesForBlockID(numTotalBytes, numDataBytes, numRSBlocks, i,
+ numDataBytesInBlock, numEcBytesInBlosk);
+ CBC_CommonByteArray* dataBytes = FX_NEW CBC_CommonByteArray;
+ dataBytes->Set(bits->GetArray(), dataBytesOffset, numDataBytesInBlock);
+ CBC_CommonByteArray* ecBytes = GenerateECBytes(dataBytes, numEcBytesInBlosk, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ blocks.Add(FX_NEW CBC_QRCoderBlockPair(dataBytes, ecBytes));
+ maxNumDataBytes = FX_MAX(maxNumDataBytes, dataBytes->Size());
+ maxNumEcBytes = FX_MAX(maxNumEcBytes, ecBytes->Size());
+ dataBytesOffset += numDataBytesInBlock;
+ }
+ if(numDataBytes != dataBytesOffset) {
+ e = BCExceptionBytesNotMatchOffset;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 x = 0; x < maxNumDataBytes; x++) {
+ for(FX_INT32 j = 0; j < blocks.GetSize(); j++) {
+ CBC_CommonByteArray* dataBytes = ((CBC_QRCoderBlockPair*)blocks[j])->GetDataBytes();
+ if(x < dataBytes->Size()) {
+ result->AppendBits(dataBytes->At(x), 8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ }
+ }
+ for(FX_INT32 y = 0; y < maxNumEcBytes; y++) {
+ for(FX_INT32 l = 0; l < blocks.GetSize(); l++) {
+ CBC_CommonByteArray* ecBytes = ((CBC_QRCoderBlockPair*)blocks[l])->GetErrorCorrectionBytes();
+ if(y < ecBytes->Size()) {
+ result->AppendBits(ecBytes->At(y), 8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ }
+ }
+ for(FX_INT32 k = 0; k < blocks.GetSize(); k++) {
+ delete (CBC_QRCoderBlockPair*)blocks[k];
+ }
+ if(numTotalBytes != result->sizeInBytes()) {
+ e = BCExceptionSizeInBytesDiffer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderEncoder::GetNumDataBytesAndNumECBytesForBlockID(FX_INT32 numTotalBytes, FX_INT32 numDataBytes,
+ FX_INT32 numRSBlocks, FX_INT32 blockID,
+ FX_INT32 &numDataBytesInBlock, FX_INT32& numECBytesInBlock)
+{
+ if(blockID >= numRSBlocks) {
+ return;
+ }
+ FX_INT32 numRsBlocksInGroup2 = numTotalBytes % numRSBlocks;
+ FX_INT32 numRsBlocksInGroup1 = numRSBlocks - numRsBlocksInGroup2;
+ FX_INT32 numTotalBytesInGroup1 = numTotalBytes / numRSBlocks;
+ FX_INT32 numTotalBytesInGroup2 = numTotalBytesInGroup1 + 1;
+ FX_INT32 numDataBytesInGroup1 = numDataBytes / numRSBlocks;
+ FX_INT32 numDataBytesInGroup2 = numDataBytesInGroup1 + 1;
+ FX_INT32 numEcBytesInGroup1 = numTotalBytesInGroup1 - numDataBytesInGroup1;
+ FX_INT32 numEcBytesInGroup2 = numTotalBytesInGroup2 - numDataBytesInGroup2;
+ if (blockID < numRsBlocksInGroup1) {
+ numDataBytesInBlock = numDataBytesInGroup1;
+ numECBytesInBlock = numEcBytesInGroup1;
+ } else {
+ numDataBytesInBlock = numDataBytesInGroup2;
+ numECBytesInBlock = numEcBytesInGroup2;
+ }
+}
+CBC_CommonByteArray* CBC_QRCoderEncoder::GenerateECBytes(CBC_CommonByteArray* dataBytes, FX_INT32 numEcBytesInBlock, FX_INT32 &e)
+{
+ FX_INT32 numDataBytes = dataBytes->Size();
+ CFX_Int32Array toEncode;
+ toEncode.SetSize(numDataBytes + numEcBytesInBlock);
+ for(FX_INT32 i = 0; i < numDataBytes; i++) {
+ toEncode[i] = (dataBytes->At(i));
+ }
+ CBC_ReedSolomonEncoder encode(CBC_ReedSolomonGF256::QRCodeFild);
+ encode.Init();
+ encode.Encode(&toEncode, numEcBytesInBlock, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_CommonByteArray* ecBytes = FX_NEW CBC_CommonByteArray(numEcBytesInBlock);
+ for(FX_INT32 j = 0; j < numEcBytesInBlock; j++) {
+ ecBytes->Set(j, toEncode[numDataBytes + j]);
+ }
+ return ecBytes;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderErrorCorrectionLevel.cpp b/xfa/src/fxbarcode/src/BC_QRCoderErrorCorrectionLevel.cpp
new file mode 100644
index 0000000000..333aa2d50e
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderErrorCorrectionLevel.cpp
@@ -0,0 +1,81 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::L = NULL;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::M = NULL;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::Q = NULL;
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::H = NULL;
+CBC_QRCoderErrorCorrectionLevel::CBC_QRCoderErrorCorrectionLevel(FX_INT32 ordinal, FX_INT32 bits, FX_CHAR* name)
+{
+ m_name += name;
+ m_ordinal = ordinal;
+ m_bits = bits;
+}
+CBC_QRCoderErrorCorrectionLevel::~CBC_QRCoderErrorCorrectionLevel()
+{
+}
+void CBC_QRCoderErrorCorrectionLevel::Initialize()
+{
+ L = FX_NEW CBC_QRCoderErrorCorrectionLevel(0, 0x01, (FX_CHAR*)"L");
+ M = FX_NEW CBC_QRCoderErrorCorrectionLevel(1, 0x00, (FX_CHAR*)"M");
+ Q = FX_NEW CBC_QRCoderErrorCorrectionLevel(2, 0x03, (FX_CHAR*)"Q");
+ H = FX_NEW CBC_QRCoderErrorCorrectionLevel(3, 0x02, (FX_CHAR*)"H");
+}
+void CBC_QRCoderErrorCorrectionLevel::Finalize()
+{
+ delete L;
+ delete M;
+ delete Q;
+ delete H;
+}
+FX_INT32 CBC_QRCoderErrorCorrectionLevel::Ordinal()
+{
+ return m_ordinal;
+}
+FX_INT32 CBC_QRCoderErrorCorrectionLevel::GetBits()
+{
+ return m_bits;
+}
+CFX_ByteString CBC_QRCoderErrorCorrectionLevel::GetName()
+{
+ return m_name;
+}
+CBC_QRCoderErrorCorrectionLevel* CBC_QRCoderErrorCorrectionLevel::ForBits(FX_INT32 bits)
+{
+ switch(bits) {
+ case 0x00:
+ return M;
+ case 0x01:
+ return L;
+ case 0x02:
+ return H;
+ case 0x03:
+ return Q;
+ default:
+ return NULL;
+ }
+}
+void CBC_QRCoderErrorCorrectionLevel::Destroy()
+{
+ if(L) {
+ delete CBC_QRCoderErrorCorrectionLevel::L;
+ L = NULL;
+ }
+ if(M) {
+ delete CBC_QRCoderErrorCorrectionLevel::M;
+ M = NULL;
+ }
+ if(H) {
+ delete CBC_QRCoderErrorCorrectionLevel::H;
+ H = NULL;
+ }
+ if(Q) {
+ delete CBC_QRCoderErrorCorrectionLevel::Q;
+ Q = NULL;
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderFormatInformation.cpp b/xfa/src/fxbarcode/src/BC_QRCoderFormatInformation.cpp
new file mode 100644
index 0000000000..baa2ec19b0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderFormatInformation.cpp
@@ -0,0 +1,103 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_QRCoderFormatInformation.h"
+const FX_INT32 CBC_QRCoderFormatInformation::FORMAT_INFO_MASK_QR = 0X5412;
+const FX_INT32 CBC_QRCoderFormatInformation::FORMAT_INFO_DECODE_LOOKUP[32][2] = {
+ {0x5412, 0x00},
+ {0x5125, 0x01},
+ {0x5E7C, 0x02},
+ {0x5B4B, 0x03},
+ {0x45F9, 0x04},
+ {0x40CE, 0x05},
+ {0x4F97, 0x06},
+ {0x4AA0, 0x07},
+ {0x77C4, 0x08},
+ {0x72F3, 0x09},
+ {0x7DAA, 0x0A},
+ {0x789D, 0x0B},
+ {0x662F, 0x0C},
+ {0x6318, 0x0D},
+ {0x6C41, 0x0E},
+ {0x6976, 0x0F},
+ {0x1689, 0x10},
+ {0x13BE, 0x11},
+ {0x1CE7, 0x12},
+ {0x19D0, 0x13},
+ {0x0762, 0x14},
+ {0x0255, 0x15},
+ {0x0D0C, 0x16},
+ {0x083B, 0x17},
+ {0x355F, 0x18},
+ {0x3068, 0x19},
+ {0x3F31, 0x1A},
+ {0x3A06, 0x1B},
+ {0x24B4, 0x1C},
+ {0x2183, 0x1D},
+ {0x2EDA, 0x1E},
+ {0x2BED, 0x1F},
+};
+const FX_INT32 CBC_QRCoderFormatInformation::BITS_SET_IN_HALF_BYTE[] =
+{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
+CBC_QRCoderFormatInformation::CBC_QRCoderFormatInformation(FX_INT32 formatInfo)
+{
+ m_errorCorrectLevl = CBC_QRCoderErrorCorrectionLevel::ForBits((formatInfo >> 3) & 0x03);
+ m_dataMask = (FX_BYTE) (formatInfo & 0x07);
+}
+CBC_QRCoderFormatInformation::~CBC_QRCoderFormatInformation()
+{
+}
+FX_INT32 CBC_QRCoderFormatInformation::NumBitsDiffering(FX_INT32 a, FX_INT32 b)
+{
+ a ^= b;
+ return BITS_SET_IN_HALF_BYTE[a & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 4) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 8) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 12) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 16) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 20) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 24) & 0x0F] +
+ BITS_SET_IN_HALF_BYTE[(a >> 28) & 0x0F];
+}
+FX_BYTE CBC_QRCoderFormatInformation::GetDataMask()
+{
+ return m_dataMask;
+}
+CBC_QRCoderErrorCorrectionLevel *CBC_QRCoderFormatInformation::GetErrorCorrectionLevel()
+{
+ return m_errorCorrectLevl;
+}
+CBC_QRCoderFormatInformation* CBC_QRCoderFormatInformation::DecodeFormatInformation(FX_INT32 maskedFormatInfo)
+{
+ CBC_QRCoderFormatInformation* formatInfo = DoDecodeFormatInformation(maskedFormatInfo);
+ if(formatInfo != NULL) {
+ return formatInfo;
+ }
+ return DoDecodeFormatInformation(maskedFormatInfo ^ FORMAT_INFO_MASK_QR);
+}
+CBC_QRCoderFormatInformation* CBC_QRCoderFormatInformation::DoDecodeFormatInformation(FX_INT32 maskedFormatInfo)
+{
+ FX_INT32 bestDifference = (FX_INT32)FXSYS_nan();
+ FX_INT32 bestFormatInfo = 0;
+ for(FX_INT32 i = 0; i < 32; i++) {
+ FX_INT32 const* decodeInfo = &FORMAT_INFO_DECODE_LOOKUP[i][0];
+ FX_INT32 targetInfo = decodeInfo[0];
+ if(targetInfo == maskedFormatInfo) {
+ return FX_NEW CBC_QRCoderFormatInformation(decodeInfo[1]);
+ }
+ FX_INT32 bitsDifference = NumBitsDiffering(maskedFormatInfo, targetInfo);
+ if(bitsDifference < bestDifference) {
+ bestFormatInfo = decodeInfo[1];
+ bestDifference = bitsDifference;
+ }
+ }
+ if(bestDifference <= 3) {
+ return FX_NEW CBC_QRCoderFormatInformation(bestFormatInfo);
+ }
+ return NULL;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderMaskUtil.cpp b/xfa/src/fxbarcode/src/BC_QRCoderMaskUtil.cpp
new file mode 100644
index 0000000000..e7a4a8bba8
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderMaskUtil.cpp
@@ -0,0 +1,192 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonByteMatrix.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_QRCoder.h"
+#include "include/BC_QRCoderMaskUtil.h"
+CBC_QRCoderMaskUtil::CBC_QRCoderMaskUtil()
+{
+}
+CBC_QRCoderMaskUtil::~CBC_QRCoderMaskUtil()
+{
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(CBC_CommonByteMatrix* matrix)
+{
+ return ApplyMaskPenaltyRule1Internal(matrix, TRUE) +
+ ApplyMaskPenaltyRule1Internal(matrix, FALSE);
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 penalty = 0;
+ FX_BYTE* array = matrix->GetArray();
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ for(FX_INT32 y = 0; y < height - 1; y++) {
+ for(FX_INT32 x = 0; x < width - 1; x++) {
+ FX_INT32 value = array[y * width + x];
+ if(value == array[y * width + x + 1] &&
+ value == array[(y + 1) * width + x] &&
+ value == array[(y + 1) * width + x + 1]) {
+ penalty ++;
+ }
+ }
+ }
+ return 3 * penalty;
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 penalty = 0;
+ FX_BYTE* array = matrix->GetArray();
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ for (FX_INT32 y = 0; y < height; ++y) {
+ for (FX_INT32 x = 0; x < width; ++x) {
+ if (x == 0 && ((y >= 0 && y <= 6) || (y >= height - 7 && y <= height - 1))) {
+ continue;
+ }
+ if (x == width - 7 && (y >= 0 && y <= 6)) {
+ continue;
+ }
+ if (y == 0 && ((x >= 0 && x <= 6) || (x >= width - 7 && x <= width - 1))) {
+ continue;
+ }
+ if (y == height - 7 && (x >= 0 && x <= 6)) {
+ continue;
+ }
+ if (x + 6 < width &&
+ array[y * width + x] == 1 &&
+ array[y * width + x + 1] == 0 &&
+ array[y * width + x + 2] == 1 &&
+ array[y * width + x + 3] == 1 &&
+ array[y * width + x + 4] == 1 &&
+ array[y * width + x + 5] == 0 &&
+ array[y * width + x + 6] == 1 &&
+ ((x + 10 < width &&
+ array[y * width + x + 7] == 0 &&
+ array[y * width + x + 8] == 0 &&
+ array[y * width + x + 9] == 0 &&
+ array[y * width + x + 10] == 0) ||
+ (x - 4 >= 0 &&
+ array[y * width + x - 1] == 0 &&
+ array[y * width + x - 2] == 0 &&
+ array[y * width + x - 3] == 0 &&
+ array[y * width + x - 4] == 0))) {
+ penalty += 40;
+ }
+ if (y + 6 < height &&
+ array[y * width + x] == 1 &&
+ array[(y + 1) * width + x] == 0 &&
+ array[(y + 2) * width + x] == 1 &&
+ array[(y + 3) * width + x] == 1 &&
+ array[(y + 4) * width + x] == 1 &&
+ array[(y + 5) * width + x] == 0 &&
+ array[(y + 6) * width + x] == 1 &&
+ ((y + 10 < height &&
+ array[(y + 7) * width + x] == 0 &&
+ array[(y + 8) * width + x] == 0 &&
+ array[(y + 9) * width + x] == 0 &&
+ array[(y + 10) * width + x] == 0) ||
+ (y - 4 >= 0 &&
+ array[(y - 1) * width + x] == 0 &&
+ array[(y - 2) * width + x] == 0 &&
+ array[(y - 3) * width + x] == 0 &&
+ array[(y - 4) * width + x] == 0))) {
+ penalty += 40;
+ }
+ }
+ }
+ return penalty;
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(CBC_CommonByteMatrix* matrix)
+{
+ FX_INT32 numDarkCells = 0;
+ FX_BYTE* array = matrix->GetArray();
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ for (FX_INT32 y = 0; y < height; ++y) {
+ for (FX_INT32 x = 0; x < width; ++x) {
+ if (array[y * width + x] == 1) {
+ numDarkCells += 1;
+ }
+ }
+ }
+ FX_INT32 numTotalCells = matrix->GetHeight() * matrix->GetWidth();
+ double darkRatio = (double) numDarkCells / numTotalCells;
+ return abs( (FX_INT32) (darkRatio * 100 - 50) / 5 ) * 5 * 10;
+}
+FX_BOOL CBC_QRCoderMaskUtil::GetDataMaskBit(FX_INT32 maskPattern, FX_INT32 x, FX_INT32 y, FX_INT32 &e)
+{
+ if(!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+ e = (BCExceptionInvalidateMaskPattern);
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ }
+ FX_INT32 intermediate = 0, temp = 0;
+ switch(maskPattern) {
+ case 0:
+ intermediate = (y + x) & 0x1;
+ break;
+ case 1:
+ intermediate = y & 0x1;
+ break;
+ case 2:
+ intermediate = x % 3;
+ break;
+ case 3:
+ intermediate = (y + x) % 3;
+ break;
+ case 4:
+ intermediate = ((y >> 1) + (x / 3)) & 0x1;
+ break;
+ case 5:
+ temp = y * x;
+ intermediate = (temp & 0x1) + (temp % 3);
+ break;
+ case 6:
+ temp = y * x;
+ intermediate = (((temp & 0x1) + (temp % 3)) & 0x1);
+ break;
+ case 7:
+ temp = y * x;
+ intermediate = (((temp % 3) + ((y + x) & 0x1)) & 0x1);
+ break;
+ default: {
+ e = BCExceptionInvalidateMaskPattern;
+ BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
+ }
+ }
+ return intermediate == 0;
+}
+FX_INT32 CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1Internal(CBC_CommonByteMatrix* matrix, FX_BOOL isHorizontal)
+{
+ FX_INT32 penalty = 0;
+ FX_INT32 numSameBitCells = 0;
+ FX_INT32 prevBit = -1;
+ FX_INT32 width = matrix->GetWidth();
+ FX_INT32 height = matrix->GetHeight();
+ FX_INT32 iLimit = isHorizontal ? height : width;
+ FX_INT32 jLimit = isHorizontal ? width : height;
+ FX_BYTE* array = matrix->GetArray();
+ for (FX_INT32 i = 0; i < iLimit; ++i) {
+ for (FX_INT32 j = 0; j < jLimit; ++j) {
+ FX_INT32 bit = isHorizontal ? array[i * width + j] : array[j * width + i];
+ if (bit == prevBit) {
+ numSameBitCells += 1;
+ if (numSameBitCells == 5) {
+ penalty += 3;
+ } else if (numSameBitCells > 5) {
+ penalty += 1;
+ }
+ } else {
+ numSameBitCells = 1;
+ prevBit = bit;
+ }
+ }
+ numSameBitCells = 0;
+ }
+ return penalty;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderMatrixUtil.cpp b/xfa/src/fxbarcode/src/BC_QRCoderMatrixUtil.cpp
new file mode 100644
index 0000000000..6f56e445f9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderMatrixUtil.cpp
@@ -0,0 +1,474 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonByteMatrix.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_QRCoder.h"
+#include "include/BC_QRCoderMaskUtil.h"
+#include "include/BC_QRCoderMatrixUtil.h"
+#include "include/BC_QRCoderBitVector.h"
+const FX_INT32 CBC_QRCoderMatrixUtil::POSITION_DETECTION_PATTERN[7][7] = {
+ 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, 1,
+ 1, 0, 1, 1, 1, 0, 1,
+ 1, 0, 1, 1, 1, 0, 1,
+ 1, 0, 1, 1, 1, 0, 1,
+ 1, 0, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 1
+};
+const FX_INT32 CBC_QRCoderMatrixUtil::HORIZONTAL_SEPARATION_PATTERN[1][8] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+const FX_INT32 CBC_QRCoderMatrixUtil::VERTICAL_SEPARATION_PATTERN[7][1] = {
+ 0, 0, 0, 0, 0, 0, 0
+};
+const FX_INT32 CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN[5][5] = {
+ 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 1,
+ 1, 0, 1, 0, 1,
+ 1, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1
+};
+const FX_INT32 CBC_QRCoderMatrixUtil::POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7] = {
+ { -1, -1, -1, -1, -1, -1, -1},
+ { 6, 18, -1, -1, -1, -1, -1},
+ { 6, 22, -1, -1, -1, -1, -1},
+ { 6, 26, -1, -1, -1, -1, -1},
+ { 6, 30, -1, -1, -1, -1, -1},
+ { 6, 34, -1, -1, -1, -1, -1},
+ { 6, 22, 38, -1, -1, -1, -1},
+ { 6, 24, 42, -1, -1, -1, -1},
+ { 6, 26, 46, -1, -1, -1, -1},
+ { 6, 28, 50, -1, -1, -1, -1},
+ { 6, 30, 54, -1, -1, -1, -1},
+ { 6, 32, 58, -1, -1, -1, -1},
+ { 6, 34, 62, -1, -1, -1, -1},
+ { 6, 26, 46, 66, -1, -1, -1},
+ { 6, 26, 48, 70, -1, -1, -1},
+ { 6, 26, 50, 74, -1, -1, -1},
+ { 6, 30, 54, 78, -1, -1, -1},
+ { 6, 30, 56, 82, -1, -1, -1},
+ { 6, 30, 58, 86, -1, -1, -1},
+ { 6, 34, 62, 90, -1, -1, -1},
+ { 6, 28, 50, 72, 94, -1, -1},
+ { 6, 26, 50, 74, 98, -1, -1},
+ { 6, 30, 54, 78, 102, -1, -1},
+ { 6, 28, 54, 80, 106, -1, -1},
+ { 6, 32, 58, 84, 110, -1, -1},
+ { 6, 30, 58, 86, 114, -1, -1},
+ { 6, 34, 62, 90, 118, -1, -1},
+ { 6, 26, 50, 74, 98, 122, -1},
+ { 6, 30, 54, 78, 102, 126, -1},
+ { 6, 26, 52, 78, 104, 130, -1},
+ { 6, 30, 56, 82, 108, 134, -1},
+ { 6, 34, 60, 86, 112, 138, -1},
+ { 6, 30, 58, 86, 114, 142, -1},
+ { 6, 34, 62, 90, 118, 146, -1},
+ { 6, 30, 54, 78, 102, 126, 150},
+ { 6, 24, 50, 76, 102, 128, 154},
+ { 6, 28, 54, 80, 106, 132, 158},
+ { 6, 32, 58, 84, 110, 136, 162},
+ { 6, 26, 54, 82, 110, 138, 166},
+ { 6, 30, 58, 86, 114, 142, 170},
+};
+const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_COORDINATES[15][2] = {
+ {8, 0},
+ {8, 1},
+ {8, 2},
+ {8, 3},
+ {8, 4},
+ {8, 5},
+ {8, 7},
+ {8, 8},
+ {7, 8},
+ {5, 8},
+ {4, 8},
+ {3, 8},
+ {2, 8},
+ {1, 8},
+ {0, 8},
+};
+const FX_INT32 CBC_QRCoderMatrixUtil::VERSION_INFO_POLY = 0x1f25;
+const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_POLY = 0x0537;
+const FX_INT32 CBC_QRCoderMatrixUtil::TYPE_INFO_MASK_PATTERN = 0x5412;
+void CBC_QRCoderMatrixUtil::ClearMatrix(CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ matrix->clear((FX_BYTE) - 1);
+}
+void CBC_QRCoderMatrixUtil::BuildMatrix(CBC_QRCoderBitVector* dataBits,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 version, FX_INT32 maskPattern,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ ClearMatrix(matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedBasicPatterns(version, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedTypeInfo(ecLevel, maskPattern, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ MaybeEmbedVersionInfo(version, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedDataBits(dataBits, maskPattern, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderMatrixUtil::EmbedBasicPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ EmbedPositionDetectionPatternsAndSeparators(matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedDarkDotAtLeftBottomCorner(matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ MaybeEmbedPositionAdjustmentPatterns(version, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedTimingPatterns(matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderMatrixUtil::EmbedTypeInfo(CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 maskPattern, CBC_CommonByteMatrix *matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ CBC_QRCoderBitVector typeInfoBits;
+ typeInfoBits.Init();
+ MakeTypeInfoBits(ecLevel, maskPattern, &typeInfoBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ for(FX_INT32 i = 0; i < typeInfoBits.Size(); i++) {
+ FX_INT32 bit = typeInfoBits.At(typeInfoBits.Size() - 1 - i, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 x1 = TYPE_INFO_COORDINATES[i][0];
+ FX_INT32 y1 = TYPE_INFO_COORDINATES[i][1];
+ matrix->Set(x1, y1, bit);
+ if(i < 8) {
+ FX_INT32 x2 = matrix->GetWidth() - i - 1;
+ FX_INT32 y2 = 8;
+ matrix->Set(x2, y2, bit);
+ } else {
+ FX_INT32 x2 = 8;
+ FX_INT32 y2 = matrix->GetHeight() - 7 + (i - 8);
+ matrix->Set(x2, y2, bit);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::MaybeEmbedVersionInfo(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(version < 7) {
+ return;
+ }
+ CBC_QRCoderBitVector versionInfoBits;
+ versionInfoBits.Init();
+ MakeVersionInfoBits(version, &versionInfoBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 bitIndex = 6 * 3 - 1;
+ for(FX_INT32 i = 0; i < 6; i++) {
+ for(FX_INT32 j = 0; j < 3; j++) {
+ FX_INT32 bit = versionInfoBits.At(bitIndex, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ bitIndex--;
+ matrix->Set(i, matrix->GetHeight() - 11 + j, bit);
+ matrix->Set(matrix->GetHeight() - 11 + j, i, bit);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedDataBits(CBC_QRCoderBitVector* dataBits,
+ FX_INT32 maskPattern, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL || dataBits == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 bitIndex = 0;
+ FX_INT32 direction = -1;
+ FX_INT32 x = matrix->GetWidth() - 1;
+ FX_INT32 y = matrix->GetHeight() - 1;
+ while(x > 0) {
+ if (x == 6) {
+ x -= 1;
+ }
+ while(y >= 0 && y < matrix->GetHeight()) {
+ if (y == 6) {
+ y += direction;
+ continue;
+ }
+ for(FX_INT32 i = 0; i < 2; i++) {
+ FX_INT32 xx = x - i;
+ if(!IsEmpty(matrix->Get(xx, y))) {
+ continue;
+ }
+ FX_INT32 bit;
+ if(bitIndex < dataBits->Size()) {
+ bit = dataBits->At(bitIndex, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ bitIndex++;
+ } else {
+ bit = 0;
+ }
+ if( maskPattern != -1) {
+ FX_BOOL bol = CBC_QRCoderMaskUtil::GetDataMaskBit(maskPattern, xx, y, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(bol) {
+ bit ^= 0x01;
+ }
+ }
+ matrix->Set(xx, y, bit);
+ }
+ y += direction;
+ }
+ direction = -direction;
+ y += direction;
+ x -= 2;
+ }
+ if(bitIndex != dataBits->Size()) {
+ return;
+ }
+}
+FX_INT32 CBC_QRCoderMatrixUtil::CalculateBCHCode(FX_INT32 value, FX_INT32 poly)
+{
+ FX_INT32 msbSetInPoly = FindMSBSet(poly);
+ value <<= msbSetInPoly - 1;
+ while(FindMSBSet(value) >= msbSetInPoly) {
+ value ^= poly << (FindMSBSet(value) - msbSetInPoly);
+ }
+ return value;
+}
+void CBC_QRCoderMatrixUtil::MakeTypeInfoBits(CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 maskPattern, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ if(bits == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
+ e = BCExceptionBadMask;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 typeInfo = (ecLevel->GetBits() << 3) | maskPattern;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ bits->AppendBits(typeInfo, 5, e);
+ FX_INT32 bchCode = CalculateBCHCode(typeInfo, TYPE_INFO_POLY);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ bits->AppendBits(bchCode, 10, e);
+ CBC_QRCoderBitVector maskBits;
+ maskBits.Init();
+ maskBits.AppendBits(TYPE_INFO_MASK_PATTERN, 15, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ bits->XOR(&maskBits, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(bits->Size() != 15) {
+ e = BCExceptionBitSizeNot15;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+void CBC_QRCoderMatrixUtil::MakeVersionInfoBits(FX_INT32 version, CBC_QRCoderBitVector* bits, FX_INT32 &e)
+{
+ if(bits == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ bits->AppendBits(version, 6, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 bchCode = CalculateBCHCode(version, VERSION_INFO_POLY);
+ bits->AppendBits(bchCode, 12, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(bits->Size() != 18) {
+ e = BCExceptionBitSizeNot18;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+FX_BOOL CBC_QRCoderMatrixUtil::IsEmpty(FX_INT32 value)
+{
+ return (FX_BYTE)value == 0xff;
+}
+FX_BOOL CBC_QRCoderMatrixUtil::IsValidValue(FX_INT32 value)
+{
+ return ((FX_BYTE)value == 0xff || (FX_BYTE)value == 0x00 || (FX_BYTE)value == 0x01);
+}
+void CBC_QRCoderMatrixUtil::EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 i = 8; i < matrix->GetWidth() - 8; i++) {
+ FX_INT32 bit = (i + 1) % 2;
+ if(!IsValidValue(matrix->Get(i, 6))) {
+ e = BCExceptionInvalidateImageData;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(IsEmpty(matrix->Get(i , 6))) {
+ matrix->Set(i, 6, bit);
+ }
+ if(!IsValidValue(matrix->Get(6, i))) {
+ e = BCExceptionInvalidateImageData;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(IsEmpty(matrix->Get(6, i))) {
+ matrix->Set(6, i, bit);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedDarkDotAtLeftBottomCorner(CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(matrix->Get(8, matrix->GetHeight() - 8) == 0) {
+ e = BCExceptionHeight_8BeZero;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ matrix->Set(8, matrix->GetHeight() - 8, 1);
+}
+void CBC_QRCoderMatrixUtil::EmbedHorizontalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 x = 0; x < 8; x++) {
+ if(!IsEmpty(matrix->Get(xStart + x, yStart))) {
+ e = BCExceptionInvalidateData;
+ BC_EXCEPTION_CHECK_ReturnVoid(e)
+ }
+ matrix->Set(xStart + x, yStart, HORIZONTAL_SEPARATION_PATTERN[0][x]);
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedVerticalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 y = 0; y < 7; y++) {
+ if(!IsEmpty(matrix->Get(xStart, yStart + y))) {
+ e = BCExceptionInvalidateData;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ matrix->Set(xStart, yStart + y, VERTICAL_SEPARATION_PATTERN[y][0]);
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedPositionAdjustmentPattern(FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 y = 0; y < 5; y++) {
+ for(FX_INT32 x = 0; x < 5; x++) {
+ if(!IsEmpty(matrix->Get(xStart + x, y + yStart))) {
+ e = BCExceptionInvalidateData;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ matrix->Set(xStart + x, yStart + y, POSITION_ADJUSTMENT_PATTERN[y][x]);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPattern (FX_INT32 xStart, FX_INT32 yStart,
+ CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ for(FX_INT32 y = 0; y < 7; y++) {
+ for(FX_INT32 x = 0; x < 7; x++) {
+ if(!IsEmpty(matrix->Get(xStart + x, yStart + y))) {
+ e = BCExceptionInvalidateData;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ matrix->Set(xStart + x, yStart + y, POSITION_DETECTION_PATTERN[y][x]);
+ }
+ }
+}
+void CBC_QRCoderMatrixUtil::EmbedPositionDetectionPatternsAndSeparators(CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 pdpWidth = 7;
+ EmbedPositionDetectionPattern(0, 0, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedPositionDetectionPattern(matrix->GetWidth() - pdpWidth, 0, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedPositionDetectionPattern(0, matrix->GetWidth() - pdpWidth, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 hspWidth = 8;
+ EmbedHorizontalSeparationPattern(0, hspWidth - 1, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedHorizontalSeparationPattern(matrix->GetWidth() - hspWidth, hspWidth - 1, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedHorizontalSeparationPattern(0, matrix->GetWidth() - hspWidth, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 vspSize = 7;
+ EmbedVerticalSeparationPattern(vspSize, 0, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedVerticalSeparationPattern(matrix->GetHeight() - vspSize - 1, 0, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ EmbedVerticalSeparationPattern(vspSize, matrix->GetHeight() - vspSize, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+}
+void CBC_QRCoderMatrixUtil::MaybeEmbedPositionAdjustmentPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e)
+{
+ if(matrix == NULL) {
+ e = BCExceptionNullPointer;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if(version < 2) {
+ return;
+ }
+ FX_INT32 index = version - 1;
+ FX_INT32 const* coordinates = &(POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[index][0]);
+ FX_INT32 numCoordinate = 7;
+ for(FX_INT32 i = 0; i < numCoordinate; i++) {
+ for(FX_INT32 j = 0; j < numCoordinate; j++) {
+ FX_INT32 y = coordinates[i];
+ FX_INT32 x = coordinates[j];
+ if(x == -1 || y == -1) {
+ continue;
+ }
+ if(IsEmpty(matrix->Get(x, y))) {
+ EmbedPositionAdjustmentPattern(x - 2, y - 2, matrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ }
+ }
+}
+FX_INT32 CBC_QRCoderMatrixUtil::FindMSBSet(FX_INT32 value)
+{
+ FX_INT32 numDigits = 0;
+ while(value != 0) {
+ value >>= 1;
+ ++numDigits;
+ }
+ return numDigits;
+}
+CBC_QRCoderMatrixUtil::CBC_QRCoderMatrixUtil()
+{
+}
+CBC_QRCoderMatrixUtil::~CBC_QRCoderMatrixUtil()
+{
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderMode.cpp b/xfa/src/fxbarcode/src/BC_QRCoderMode.cpp
new file mode 100644
index 0000000000..a4a5610fc4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderMode.cpp
@@ -0,0 +1,162 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderVersion.h"
+#include "include/BC_QRCoderMode.h"
+CBC_QRCoderMode* CBC_QRCoderMode::sBYTE = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sNUMERIC = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sALPHANUMERIC = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sKANJI = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sECI = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sGBK = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sTERMINATOR = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_FIRST_POSITION = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sFNC1_SECOND_POSITION = NULL;
+CBC_QRCoderMode* CBC_QRCoderMode::sSTRUCTURED_APPEND = NULL;
+CBC_QRCoderMode::CBC_QRCoderMode(FX_INT32 *characterCountBitsForVersions,
+ FX_INT32 x1, FX_INT32 x2, FX_INT32 x3,
+ FX_INT32 bits, CFX_ByteString name)
+{
+ m_characterCountBitsForVersions = characterCountBitsForVersions;
+ if (m_characterCountBitsForVersions != NULL) {
+ m_characterCountBitsForVersions[0] = x1;
+ m_characterCountBitsForVersions[1] = x2;
+ m_characterCountBitsForVersions[2] = x3;
+ }
+ m_name += name;
+ m_bits = bits;
+}
+CBC_QRCoderMode::~CBC_QRCoderMode()
+{
+ if(m_characterCountBitsForVersions != NULL) {
+ FX_Free(m_characterCountBitsForVersions);
+ }
+}
+void CBC_QRCoderMode::Initialize()
+{
+ sBYTE = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 8, 16, 16, 0x4, "BYTE");
+ sALPHANUMERIC = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 9, 11, 13, 0x2, "ALPHANUMERIC");
+ sECI = FX_NEW CBC_QRCoderMode(NULL, 0, 0, 0, 0x7, "ECI");
+ sKANJI = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 8, 10, 12, 0x8, "KANJI");
+ sNUMERIC = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 10, 12, 14, 0x1, "NUMERIC");
+ sGBK = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 8, 10, 12, 0x0D, "GBK");
+ sTERMINATOR = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 0, 0, 0, 0x00, "TERMINATOR");
+ sFNC1_FIRST_POSITION = FX_NEW CBC_QRCoderMode(NULL, 0, 0, 0, 0x05, "FNC1_FIRST_POSITION");
+ sFNC1_SECOND_POSITION = FX_NEW CBC_QRCoderMode(NULL, 0, 0, 0, 0x09, "FNC1_SECOND_POSITION");
+ sSTRUCTURED_APPEND = FX_NEW CBC_QRCoderMode(FX_Alloc(FX_INT32, 3), 0, 0, 0, 0x03, "STRUCTURED_APPEND");
+}
+void CBC_QRCoderMode::Finalize()
+{
+ delete sBYTE;
+ delete sALPHANUMERIC;
+ delete sECI;
+ delete sKANJI;
+ delete sNUMERIC;
+ delete sGBK;
+ delete sTERMINATOR;
+ delete sFNC1_FIRST_POSITION;
+ delete sFNC1_SECOND_POSITION;
+ delete sSTRUCTURED_APPEND;
+}
+CBC_QRCoderMode* CBC_QRCoderMode::ForBits(FX_INT32 bits, FX_INT32 &e)
+{
+ switch (bits) {
+ case 0x0:
+ return sTERMINATOR;
+ case 0x1:
+ return sNUMERIC;
+ case 0x2:
+ return sALPHANUMERIC;
+ case 0x3:
+ return sSTRUCTURED_APPEND;
+ case 0x4:
+ return sBYTE;
+ case 0x5:
+ return sFNC1_FIRST_POSITION;
+ case 0x7:
+ return sECI;
+ case 0x8:
+ return sKANJI;
+ case 0x9:
+ return sFNC1_SECOND_POSITION;
+ case 0x0D:
+ return sGBK;
+ default: {
+ e = BCExceptionUnsupportedMode;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ }
+ return NULL;
+}
+FX_INT32 CBC_QRCoderMode::GetBits()
+{
+ return m_bits;
+}
+CFX_ByteString CBC_QRCoderMode::GetName()
+{
+ return m_name;
+}
+FX_INT32 CBC_QRCoderMode::GetCharacterCountBits(CBC_QRCoderVersion* version, FX_INT32 &e)
+{
+ if(m_characterCountBitsForVersions == NULL) {
+ e = BCExceptionCharacterNotThisMode;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ FX_INT32 number = version->GetVersionNumber();
+ FX_INT32 offset;
+ if(number <= 9) {
+ offset = 0;
+ } else if(number <= 26) {
+ offset = 1;
+ } else {
+ offset = 2;
+ }
+ return m_characterCountBitsForVersions[offset];
+}
+void CBC_QRCoderMode::Destroy()
+{
+ if(sBYTE) {
+ delete CBC_QRCoderMode::sBYTE;
+ sBYTE = NULL;
+ }
+ if(sNUMERIC) {
+ delete CBC_QRCoderMode::sNUMERIC;
+ sNUMERIC = NULL;
+ }
+ if(sALPHANUMERIC) {
+ delete CBC_QRCoderMode::sALPHANUMERIC;
+ sALPHANUMERIC = NULL;
+ }
+ if(sKANJI) {
+ delete CBC_QRCoderMode::sKANJI;
+ sKANJI = NULL;
+ }
+ if(sECI) {
+ delete CBC_QRCoderMode::sECI;
+ sECI = NULL;
+ }
+ if(sGBK) {
+ delete CBC_QRCoderMode::sGBK;
+ sGBK = NULL;
+ }
+ if(sTERMINATOR) {
+ delete CBC_QRCoderMode::sTERMINATOR;
+ sTERMINATOR = NULL;
+ }
+ if(sFNC1_FIRST_POSITION) {
+ delete CBC_QRCoderMode::sFNC1_FIRST_POSITION;
+ sFNC1_FIRST_POSITION = NULL;
+ }
+ if(sFNC1_SECOND_POSITION) {
+ delete CBC_QRCoderMode::sFNC1_SECOND_POSITION;
+ sFNC1_SECOND_POSITION = NULL;
+ }
+ if(sSTRUCTURED_APPEND) {
+ delete CBC_QRCoderMode::sSTRUCTURED_APPEND;
+ sSTRUCTURED_APPEND = NULL;
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRCoderVersion.cpp b/xfa/src/fxbarcode/src/BC_QRCoderVersion.cpp
new file mode 100644
index 0000000000..6e1e39e316
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRCoderVersion.cpp
@@ -0,0 +1,761 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/utils.h"
+#include "include/BC_QRCoderECB.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRCoderFormatInformation.h"
+#include "include/BC_QRCoderErrorCorrectionLevel.h"
+#include "include/BC_QRCoderBitVector.h"
+#include "include/BC_QRCoderECBlocks.h"
+#include "include/BC_QRCoderVersion.h"
+const FX_INT32 CBC_QRCoderVersion::VERSION_DECODE_INFO[] = {
+ 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6,
+ 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78,
+ 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683,
+ 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB,
+ 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250,
+ 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B,
+ 0x2542E, 0x26A64, 0x27541, 0x28C69
+};
+CFX_PtrArray *CBC_QRCoderVersion::VERSION = NULL;
+void CBC_QRCoderVersion::Initialize()
+{
+ VERSION = FX_NEW CFX_PtrArray();
+}
+void CBC_QRCoderVersion::Finalize()
+{
+ for(FX_INT32 i = 0 ; i < VERSION->GetSize(); i++) {
+ CBC_QRCoderVersion* v = (CBC_QRCoderVersion*)(VERSION->GetAt(i));
+ delete v;
+ }
+ delete VERSION;
+}
+CBC_QRCoderVersion::CBC_QRCoderVersion(FX_INT32 versionNumber,
+ CBC_QRCoderECBlocks* ecBlocks1,
+ CBC_QRCoderECBlocks* ecBlocks2,
+ CBC_QRCoderECBlocks* ecBlocks3,
+ CBC_QRCoderECBlocks* ecBlocks4)
+{
+ m_versionNumber = versionNumber;
+ m_ecBlocks.Add(ecBlocks1);
+ m_ecBlocks.Add(ecBlocks2);
+ m_ecBlocks.Add(ecBlocks3);
+ m_ecBlocks.Add(ecBlocks4);
+ FX_INT32 total = 0;
+ FX_INT32 ecCodeWords = ecBlocks1->GetECCodeWordsPerBlock();
+ CFX_PtrArray* ecbArray = ecBlocks1->GetECBlocks();
+ for(FX_INT32 i = 0; i < ecbArray->GetSize(); i++) {
+ CBC_QRCoderECB* ecBlock = (CBC_QRCoderECB*)((*ecbArray)[i]);
+ total += ecBlock->GetCount() * (ecBlock->GetDataCodeWords() + ecCodeWords);
+ }
+ m_totalCodeWords = total;
+ switch(versionNumber) {
+ case 1:
+ break;
+ case 2:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(18);
+ break;
+ case 3:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(22);
+ break;
+ case 4:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ break;
+ case 5:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ break;
+ case 6:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(34);
+ break;
+ case 7:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(22);
+ m_alignmentPatternCenters.Add(38);
+ break;
+ case 8:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(24);
+ m_alignmentPatternCenters.Add(42);
+ break;
+ case 9:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(46);
+ break;
+ case 10:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(28);
+ m_alignmentPatternCenters.Add(50);
+ break;
+ case 11:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(54);
+ break;
+ case 12:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(32);
+ m_alignmentPatternCenters.Add(58);
+ break;
+ case 13:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(34);
+ m_alignmentPatternCenters.Add(62);
+ break;
+ case 14:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(46);
+ m_alignmentPatternCenters.Add(66);
+ break;
+ case 15:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(48);
+ m_alignmentPatternCenters.Add(70);
+ break;
+ case 16:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(50);
+ m_alignmentPatternCenters.Add(74);
+ break;
+ case 17:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(54);
+ m_alignmentPatternCenters.Add(78);
+ break;
+ case 18:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(56);
+ m_alignmentPatternCenters.Add(82);
+ break;
+ case 19:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(58);
+ m_alignmentPatternCenters.Add(86);
+ break;
+ case 20:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(34);
+ m_alignmentPatternCenters.Add(62);
+ m_alignmentPatternCenters.Add(90);
+ break;
+ case 21:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(28);
+ m_alignmentPatternCenters.Add(50);
+ m_alignmentPatternCenters.Add(72);
+ m_alignmentPatternCenters.Add(94);
+ break;
+ case 22:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(50);
+ m_alignmentPatternCenters.Add(74);
+ m_alignmentPatternCenters.Add(98);
+ break;
+ case 23:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(54);
+ m_alignmentPatternCenters.Add(74);
+ m_alignmentPatternCenters.Add(102);
+ break;
+ case 24:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(28);
+ m_alignmentPatternCenters.Add(54);
+ m_alignmentPatternCenters.Add(80);
+ m_alignmentPatternCenters.Add(106);
+ break;
+ case 25:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(32);
+ m_alignmentPatternCenters.Add(58);
+ m_alignmentPatternCenters.Add(84);
+ m_alignmentPatternCenters.Add(110);
+ break;
+ case 26:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(58);
+ m_alignmentPatternCenters.Add(86);
+ m_alignmentPatternCenters.Add(114);
+ break;
+ case 27:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(34);
+ m_alignmentPatternCenters.Add(62);
+ m_alignmentPatternCenters.Add(90);
+ m_alignmentPatternCenters.Add(118);
+ break;
+ case 28:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(50);
+ m_alignmentPatternCenters.Add(74);
+ m_alignmentPatternCenters.Add(98);
+ m_alignmentPatternCenters.Add(122);
+ break;
+ case 29:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(54);
+ m_alignmentPatternCenters.Add(78);
+ m_alignmentPatternCenters.Add(102);
+ m_alignmentPatternCenters.Add(126);
+ break;
+ case 30:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(52);
+ m_alignmentPatternCenters.Add(78);
+ m_alignmentPatternCenters.Add(104);
+ m_alignmentPatternCenters.Add(130);
+ break;
+ case 31:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(56);
+ m_alignmentPatternCenters.Add(82);
+ m_alignmentPatternCenters.Add(108);
+ m_alignmentPatternCenters.Add(134);
+ break;
+ case 32:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(34);
+ m_alignmentPatternCenters.Add(60);
+ m_alignmentPatternCenters.Add(86);
+ m_alignmentPatternCenters.Add(112);
+ m_alignmentPatternCenters.Add(138);
+ break;
+ case 33:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(58);
+ m_alignmentPatternCenters.Add(86);
+ m_alignmentPatternCenters.Add(114);
+ m_alignmentPatternCenters.Add(142);
+ break;
+ case 34:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(34);
+ m_alignmentPatternCenters.Add(62);
+ m_alignmentPatternCenters.Add(90);
+ m_alignmentPatternCenters.Add(118);
+ m_alignmentPatternCenters.Add(146);
+ break;
+ case 35:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(54);
+ m_alignmentPatternCenters.Add(78);
+ m_alignmentPatternCenters.Add(102);
+ m_alignmentPatternCenters.Add(126);
+ m_alignmentPatternCenters.Add(150);
+ break;
+ case 36:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(24);
+ m_alignmentPatternCenters.Add(50);
+ m_alignmentPatternCenters.Add(76);
+ m_alignmentPatternCenters.Add(102);
+ m_alignmentPatternCenters.Add(128);
+ m_alignmentPatternCenters.Add(154);
+ break;
+ case 37:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(28);
+ m_alignmentPatternCenters.Add(54);
+ m_alignmentPatternCenters.Add(80);
+ m_alignmentPatternCenters.Add(106);
+ m_alignmentPatternCenters.Add(132);
+ m_alignmentPatternCenters.Add(158);
+ break;
+ case 38:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(32);
+ m_alignmentPatternCenters.Add(58);
+ m_alignmentPatternCenters.Add(84);
+ m_alignmentPatternCenters.Add(110);
+ m_alignmentPatternCenters.Add(136);
+ m_alignmentPatternCenters.Add(162);
+ break;
+ case 39:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(26);
+ m_alignmentPatternCenters.Add(54);
+ m_alignmentPatternCenters.Add(82);
+ m_alignmentPatternCenters.Add(110);
+ m_alignmentPatternCenters.Add(138);
+ m_alignmentPatternCenters.Add(166);
+ break;
+ case 40:
+ m_alignmentPatternCenters.Add(6);
+ m_alignmentPatternCenters.Add(30);
+ m_alignmentPatternCenters.Add(58);
+ m_alignmentPatternCenters.Add(86);
+ m_alignmentPatternCenters.Add(114);
+ m_alignmentPatternCenters.Add(142);
+ m_alignmentPatternCenters.Add(170);
+ break;
+ }
+}
+CBC_QRCoderVersion::~CBC_QRCoderVersion()
+{
+ if(m_ecBlocks.GetSize() != 0) {
+ FX_INT32 itBeg = 0;
+ FX_INT32 itEnd = m_ecBlocks.GetSize();
+ while(itBeg != itEnd) {
+ delete ( (CBC_QRCoderECBlocks*)(m_ecBlocks[itBeg]) );
+ itBeg++;
+ }
+ }
+}
+FX_INT32 CBC_QRCoderVersion::GetVersionNumber()
+{
+ return m_versionNumber;
+}
+CFX_Int32Array* CBC_QRCoderVersion::GetAlignmentPatternCenters()
+{
+ return &m_alignmentPatternCenters;
+}
+FX_INT32 CBC_QRCoderVersion::GetTotalCodeWords()
+{
+ return m_totalCodeWords;
+}
+FX_INT32 CBC_QRCoderVersion::GetDimensionForVersion()
+{
+ return 17 + 4 * m_versionNumber;
+}
+CBC_QRCoderECBlocks* CBC_QRCoderVersion::GetECBlocksForLevel(CBC_QRCoderErrorCorrectionLevel *ecLevel)
+{
+ return (CBC_QRCoderECBlocks*)m_ecBlocks[ecLevel->Ordinal()];
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::GetProvisionalVersionForDimension(FX_INT32 dimension, FX_INT32 &e)
+{
+ if((dimension % 4) != 1) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_QRCoderVersion* qcv = GetVersionForNumber((dimension - 17) >> 2, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qcv;
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::DecodeVersionInformation(FX_INT32 versionBits, FX_INT32 &e)
+{
+ FX_INT32 bestDifference = FXSYS_IntMax;
+ FX_INT32 bestVersion = 0;
+ for (FX_INT32 i = 0; i < 34; i++) {
+ FX_INT32 targetVersion = VERSION_DECODE_INFO[i];
+ if(targetVersion == versionBits) {
+ CBC_QRCoderVersion* qcv = GetVersionForNumber(i + 7, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qcv;
+ }
+ FX_INT32 bitsDifference = CBC_QRCoderFormatInformation::NumBitsDiffering(versionBits, targetVersion);
+ if(bitsDifference < bestDifference) {
+ bestVersion = i + 7;
+ bestDifference = bitsDifference;
+ }
+ }
+ if(bestDifference <= 3) {
+ CBC_QRCoderVersion* qcv = GetVersionForNumber(bestVersion, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qcv;
+ }
+ return NULL;
+}
+CBC_CommonBitMatrix* CBC_QRCoderVersion::BuildFunctionPattern(FX_INT32 &e)
+{
+ FX_INT32 dimension = GetDimensionForVersion();
+ CBC_CommonBitMatrix* bitMatrix = FX_NEW CBC_CommonBitMatrix();
+ bitMatrix->Init(dimension);
+ bitMatrix->SetRegion(0, 0 , 9, 9, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ bitMatrix->SetRegion(dimension - 8, 0, 8, 9, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ bitMatrix->SetRegion(0, dimension - 8, 9, 8, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 max = m_alignmentPatternCenters.GetSize();
+ for (FX_INT32 x = 0; x < max; x++) {
+ FX_INT32 i = m_alignmentPatternCenters[x] - 2;
+ for (FX_INT32 y = 0; y < max; y++) {
+ if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) {
+ continue;
+ }
+ bitMatrix->SetRegion(m_alignmentPatternCenters[y] - 2, i, 5, 5, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ }
+ bitMatrix->SetRegion(6, 9, 1, dimension - 17, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ bitMatrix->SetRegion(9, 6, dimension - 17, 1, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if (m_versionNumber > 6) {
+ bitMatrix->SetRegion(dimension - 11, 0, 3, 6, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ bitMatrix->SetRegion(0, dimension - 11, 6, 3, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return bitMatrix;
+}
+CBC_QRCoderVersion* CBC_QRCoderVersion::GetVersionForNumber(FX_INT32 versionNumber, FX_INT32 &e)
+{
+ if(VERSION->GetSize() == 0) {
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(1,
+ FX_NEW CBC_QRCoderECBlocks(7, FX_NEW CBC_QRCoderECB(1, 19)),
+ FX_NEW CBC_QRCoderECBlocks(10, FX_NEW CBC_QRCoderECB(1, 16)),
+ FX_NEW CBC_QRCoderECBlocks(13, FX_NEW CBC_QRCoderECB(1, 13)),
+ FX_NEW CBC_QRCoderECBlocks(17, FX_NEW CBC_QRCoderECB(1, 9))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(2,
+ FX_NEW CBC_QRCoderECBlocks(10, FX_NEW CBC_QRCoderECB(1, 34)),
+ FX_NEW CBC_QRCoderECBlocks(16, FX_NEW CBC_QRCoderECB(1, 28)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(1, 22)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(1, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(3,
+ FX_NEW CBC_QRCoderECBlocks(15, FX_NEW CBC_QRCoderECB(1, 55)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(1, 44)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 17)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(2, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(4,
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(1, 80)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 32)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(2, 24)),
+ FX_NEW CBC_QRCoderECBlocks(16, FX_NEW CBC_QRCoderECB(4, 9))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(5,
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(1, 108)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(2, 43)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 15),
+ FX_NEW CBC_QRCoderECB(2, 16)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(2, 11),
+ FX_NEW CBC_QRCoderECB(2, 12))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(6,
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 68)),
+ FX_NEW CBC_QRCoderECBlocks(16, FX_NEW CBC_QRCoderECB(4, 27)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(4, 19)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(7,
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(2, 78)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(4, 31)),
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 14),
+ FX_NEW CBC_QRCoderECB(4, 15)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 13),
+ FX_NEW CBC_QRCoderECB(1, 14))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(8,
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(2, 97)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(2, 38),
+ FX_NEW CBC_QRCoderECB(2, 39)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(4, 18),
+ FX_NEW CBC_QRCoderECB(2, 19)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 14),
+ FX_NEW CBC_QRCoderECB(2, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(9,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(2, 116)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(3, 36),
+ FX_NEW CBC_QRCoderECB(2, 37)),
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(4, 16),
+ FX_NEW CBC_QRCoderECB(4, 17)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(4, 12),
+ FX_NEW CBC_QRCoderECB(4, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(10,
+ FX_NEW CBC_QRCoderECBlocks(18, FX_NEW CBC_QRCoderECB(2, 68),
+ FX_NEW CBC_QRCoderECB(2, 69)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 43),
+ FX_NEW CBC_QRCoderECB(1, 44)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(6, 19),
+ FX_NEW CBC_QRCoderECB(2, 20)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(6, 15),
+ FX_NEW CBC_QRCoderECB(2, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(11,
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(4, 81)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(1, 50),
+ FX_NEW CBC_QRCoderECB(4, 51)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 22),
+ FX_NEW CBC_QRCoderECB(4, 23)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(3, 12),
+ FX_NEW CBC_QRCoderECB(8, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(12,
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(2, 92),
+ FX_NEW CBC_QRCoderECB(2, 93)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(6, 36),
+ FX_NEW CBC_QRCoderECB(2, 37)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 20),
+ FX_NEW CBC_QRCoderECB(6, 21)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(7, 14),
+ FX_NEW CBC_QRCoderECB(4, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(13,
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(4, 107)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(8, 37),
+ FX_NEW CBC_QRCoderECB(1, 38)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(8, 20),
+ FX_NEW CBC_QRCoderECB(4, 21)),
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(12, 11),
+ FX_NEW CBC_QRCoderECB(4, 12))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(14,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(3, 115),
+ FX_NEW CBC_QRCoderECB(1, 116)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(4, 40),
+ FX_NEW CBC_QRCoderECB(5, 41)),
+ FX_NEW CBC_QRCoderECBlocks(20, FX_NEW CBC_QRCoderECB(11, 16),
+ FX_NEW CBC_QRCoderECB(5, 17)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(11, 12),
+ FX_NEW CBC_QRCoderECB(5, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(15,
+ FX_NEW CBC_QRCoderECBlocks(22, FX_NEW CBC_QRCoderECB(5, 87),
+ FX_NEW CBC_QRCoderECB(1, 88)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(5, 41),
+ FX_NEW CBC_QRCoderECB(5, 42)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(5, 24),
+ FX_NEW CBC_QRCoderECB(7, 25)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(11, 12),
+ FX_NEW CBC_QRCoderECB(7, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(16,
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(5, 98),
+ FX_NEW CBC_QRCoderECB(1, 99)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(7, 45),
+ FX_NEW CBC_QRCoderECB(3, 46)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(15, 19),
+ FX_NEW CBC_QRCoderECB(2, 20)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(3, 15),
+ FX_NEW CBC_QRCoderECB(13, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(17,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(1, 107),
+ FX_NEW CBC_QRCoderECB(5, 108)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(10, 46),
+ FX_NEW CBC_QRCoderECB(1, 47)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(1, 22),
+ FX_NEW CBC_QRCoderECB(15, 23)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 14),
+ FX_NEW CBC_QRCoderECB(17, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(18,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(5, 120),
+ FX_NEW CBC_QRCoderECB(1, 121)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(9, 43),
+ FX_NEW CBC_QRCoderECB(4, 44)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(17, 22),
+ FX_NEW CBC_QRCoderECB(1, 23)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 14),
+ FX_NEW CBC_QRCoderECB(19, 15))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(19,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(3, 113),
+ FX_NEW CBC_QRCoderECB(4, 114)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(3, 44),
+ FX_NEW CBC_QRCoderECB(11, 45)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(17, 21),
+ FX_NEW CBC_QRCoderECB(4, 22)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(9, 13),
+ FX_NEW CBC_QRCoderECB(16, 14))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(20,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(3, 107),
+ FX_NEW CBC_QRCoderECB(5, 108)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(3, 41),
+ FX_NEW CBC_QRCoderECB(13, 42)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(15, 24),
+ FX_NEW CBC_QRCoderECB(5, 25)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(15, 15),
+ FX_NEW CBC_QRCoderECB(10, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(21,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 116),
+ FX_NEW CBC_QRCoderECB(4, 117)),
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(17, 42)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(17, 22),
+ FX_NEW CBC_QRCoderECB(6, 23)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 16),
+ FX_NEW CBC_QRCoderECB(6, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(22,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 111),
+ FX_NEW CBC_QRCoderECB(7, 112)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(17, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(7, 24),
+ FX_NEW CBC_QRCoderECB(16, 25)),
+ FX_NEW CBC_QRCoderECBlocks(24, FX_NEW CBC_QRCoderECB(34, 13))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(23,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(4, 121),
+ FX_NEW CBC_QRCoderECB(5, 122)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(4, 47),
+ FX_NEW CBC_QRCoderECB(14, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 24),
+ FX_NEW CBC_QRCoderECB(14, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(16, 15),
+ FX_NEW CBC_QRCoderECB(14, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(24,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(6, 117),
+ FX_NEW CBC_QRCoderECB(4, 118)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(6, 45),
+ FX_NEW CBC_QRCoderECB(14, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 24),
+ FX_NEW CBC_QRCoderECB(16, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(30, 16),
+ FX_NEW CBC_QRCoderECB(2, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(25,
+ FX_NEW CBC_QRCoderECBlocks(26, FX_NEW CBC_QRCoderECB(8, 106),
+ FX_NEW CBC_QRCoderECB(4, 107)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(8, 47),
+ FX_NEW CBC_QRCoderECB(13, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(7, 24),
+ FX_NEW CBC_QRCoderECB(22, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(22, 15),
+ FX_NEW CBC_QRCoderECB(13, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(26,
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(10, 114),
+ FX_NEW CBC_QRCoderECB(2, 115)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(19, 46),
+ FX_NEW CBC_QRCoderECB(4, 47)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(28, 22),
+ FX_NEW CBC_QRCoderECB(6, 23)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(33, 16),
+ FX_NEW CBC_QRCoderECB(4, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(27,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(8, 122),
+ FX_NEW CBC_QRCoderECB(4, 123)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(22, 45),
+ FX_NEW CBC_QRCoderECB(3, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(8, 23),
+ FX_NEW CBC_QRCoderECB(26, 24)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(12, 15),
+ FX_NEW CBC_QRCoderECB(28, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(28,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(3, 117),
+ FX_NEW CBC_QRCoderECB(10, 118)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(3, 45),
+ FX_NEW CBC_QRCoderECB(23, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(4, 24),
+ FX_NEW CBC_QRCoderECB(31, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 15),
+ FX_NEW CBC_QRCoderECB(31, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(29,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(7, 116),
+ FX_NEW CBC_QRCoderECB(7, 117)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(21, 45),
+ FX_NEW CBC_QRCoderECB(7, 46)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(1, 23),
+ FX_NEW CBC_QRCoderECB(37, 24)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 15),
+ FX_NEW CBC_QRCoderECB(26, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(30,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(5, 115),
+ FX_NEW CBC_QRCoderECB(10, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(19, 47),
+ FX_NEW CBC_QRCoderECB(10, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(15, 24),
+ FX_NEW CBC_QRCoderECB(25, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(23, 15),
+ FX_NEW CBC_QRCoderECB(25, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(31,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(13, 115),
+ FX_NEW CBC_QRCoderECB(3, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(2, 46),
+ FX_NEW CBC_QRCoderECB(29, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(42, 24),
+ FX_NEW CBC_QRCoderECB(1, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(23, 15),
+ FX_NEW CBC_QRCoderECB(28, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(32,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(17, 115)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(10, 46),
+ FX_NEW CBC_QRCoderECB(23, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(10, 24),
+ FX_NEW CBC_QRCoderECB(35, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 15),
+ FX_NEW CBC_QRCoderECB(35, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(33,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(17, 115),
+ FX_NEW CBC_QRCoderECB(1, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(14, 46),
+ FX_NEW CBC_QRCoderECB(21, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(29, 24),
+ FX_NEW CBC_QRCoderECB(19, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(11, 15),
+ FX_NEW CBC_QRCoderECB(46, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(34,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(13, 115),
+ FX_NEW CBC_QRCoderECB(6, 116)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(14, 46),
+ FX_NEW CBC_QRCoderECB(23, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(44, 24),
+ FX_NEW CBC_QRCoderECB(7, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(59, 16),
+ FX_NEW CBC_QRCoderECB(1, 17))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(35,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(12, 121),
+ FX_NEW CBC_QRCoderECB(7, 122)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(12, 47),
+ FX_NEW CBC_QRCoderECB(26, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(39, 24),
+ FX_NEW CBC_QRCoderECB(14, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(22, 15),
+ FX_NEW CBC_QRCoderECB(41, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(36,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(6, 121),
+ FX_NEW CBC_QRCoderECB(14, 122)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(6, 47),
+ FX_NEW CBC_QRCoderECB(34, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(46, 24),
+ FX_NEW CBC_QRCoderECB(10, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(2, 15),
+ FX_NEW CBC_QRCoderECB(64, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(37,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(17, 122),
+ FX_NEW CBC_QRCoderECB(4, 123)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(29, 46),
+ FX_NEW CBC_QRCoderECB(14, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(49, 24),
+ FX_NEW CBC_QRCoderECB(10, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(24, 15),
+ FX_NEW CBC_QRCoderECB(46, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(38,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(4, 122),
+ FX_NEW CBC_QRCoderECB(18, 123)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(13, 46),
+ FX_NEW CBC_QRCoderECB(32, 47)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(48, 24),
+ FX_NEW CBC_QRCoderECB(14, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(42, 15),
+ FX_NEW CBC_QRCoderECB(32, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(39,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(20, 117),
+ FX_NEW CBC_QRCoderECB(4, 118)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(40, 47),
+ FX_NEW CBC_QRCoderECB(7, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(43, 24),
+ FX_NEW CBC_QRCoderECB(22, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(10, 15),
+ FX_NEW CBC_QRCoderECB(67, 16))));
+ VERSION->Add(FX_NEW CBC_QRCoderVersion(40,
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(19, 118),
+ FX_NEW CBC_QRCoderECB(6, 119)),
+ FX_NEW CBC_QRCoderECBlocks(28, FX_NEW CBC_QRCoderECB(18, 47),
+ FX_NEW CBC_QRCoderECB(31, 48)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(34, 24),
+ FX_NEW CBC_QRCoderECB(34, 25)),
+ FX_NEW CBC_QRCoderECBlocks(30, FX_NEW CBC_QRCoderECB(20, 15),
+ FX_NEW CBC_QRCoderECB(61, 16))));
+ }
+ if(versionNumber < 1 || versionNumber > 40) {
+ e = BCExceptionIllegalArgument;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return (CBC_QRCoderVersion*)(*VERSION)[versionNumber - 1];
+}
+void CBC_QRCoderVersion::Destroy()
+{
+ FX_INT32 i;
+ for(i = 0; i < VERSION->GetSize(); i++) {
+ delete ( (CBC_QRCoderVersion*)(*VERSION)[i] );
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRDataBlock.cpp b/xfa/src/fxbarcode/src/BC_QRDataBlock.cpp
new file mode 100644
index 0000000000..4dbe91b3cf
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRDataBlock.cpp
@@ -0,0 +1,88 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderECBlocks.h"
+#include "include/BC_QRCoderECB.h"
+#include "include/BC_QRDataBlock.h"
+#include "include/BC_QRCoderVersion.h"
+CBC_QRDataBlock::CBC_QRDataBlock(FX_INT32 numDataCodewords, CFX_ByteArray *codewords)
+ : m_numDataCodewords(numDataCodewords)
+ , m_codewords(codewords)
+{
+}
+CBC_QRDataBlock::~CBC_QRDataBlock()
+{
+ if(m_codewords != NULL) {
+ delete m_codewords;
+ m_codewords = NULL;
+ }
+}
+FX_INT32 CBC_QRDataBlock::GetNumDataCodewords()
+{
+ return m_numDataCodewords;
+}
+CFX_ByteArray *CBC_QRDataBlock::GetCodewords()
+{
+ return m_codewords;
+}
+CFX_PtrArray *CBC_QRDataBlock::GetDataBlocks(CFX_ByteArray* rawCodewords, CBC_QRCoderVersion *version, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 &e)
+{
+ if(rawCodewords->GetSize() != version->GetTotalCodeWords()) {
+ e = BCExceptionIllegalArgument;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_QRCoderECBlocks *ecBlocks = version->GetECBlocksForLevel(ecLevel);
+ FX_INT32 totalBlocks = 0;
+ CFX_PtrArray* ecBlockArray = ecBlocks->GetECBlocks();
+ FX_INT32 i = 0;
+ for(i = 0; i < ecBlockArray->GetSize(); i++) {
+ totalBlocks += ((CBC_QRCoderECB*)(*ecBlockArray)[i])->GetCount();
+ }
+ CFX_PtrArray *datablock = FX_NEW CFX_PtrArray();
+ datablock->SetSize(totalBlocks);
+ CBC_AutoPtr<CFX_PtrArray > result(datablock);
+ FX_INT32 numResultBlocks = 0;
+ for(FX_INT32 j = 0; j < ecBlockArray->GetSize(); j++) {
+ CBC_QRCoderECB *ecBlock = (CBC_QRCoderECB*)(*ecBlockArray)[j];
+ for(FX_INT32 k = 0; k < ecBlock->GetCount(); k++) {
+ FX_INT32 numDataCodewords = ecBlock->GetDataCodeWords();
+ FX_INT32 numBlockCodewords = ecBlocks->GetECCodeWordsPerBlock() + numDataCodewords;
+ CFX_ByteArray *bytearray = FX_NEW CFX_ByteArray();
+ bytearray->SetSize(numBlockCodewords);
+ (*result)[numResultBlocks++] = FX_NEW CBC_QRDataBlock(numDataCodewords, bytearray);
+ }
+ }
+ FX_INT32 shorterBlocksTotalCodewords = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
+ FX_INT32 longerBlocksStartAt = result->GetSize() - 1;
+ while(longerBlocksStartAt >= 0) {
+ FX_INT32 numCodewords = ((CBC_QRDataBlock*)(*result)[longerBlocksStartAt])->m_codewords->GetSize();
+ if(numCodewords == shorterBlocksTotalCodewords) {
+ break;
+ }
+ longerBlocksStartAt--;
+ }
+ longerBlocksStartAt++;
+ FX_INT32 shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks->GetECCodeWordsPerBlock();
+ FX_INT32 rawCodewordsOffset = 0;
+ FX_INT32 x = 0;
+ for(FX_INT32 k = 0; k < shorterBlocksNumDataCodewords; k++) {
+ for(x = 0; x < numResultBlocks; x++) {
+ (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[k] = (*rawCodewords)[rawCodewordsOffset++];
+ }
+ }
+ for(x = longerBlocksStartAt; x < numResultBlocks; x++) {
+ (*(((CBC_QRDataBlock*)(*result)[x])->m_codewords))[shorterBlocksNumDataCodewords] = (*rawCodewords)[rawCodewordsOffset++];
+ }
+ FX_INT32 max = ((CBC_QRDataBlock*)(*result)[0])->m_codewords->GetSize();
+ for(i = shorterBlocksNumDataCodewords; i < max; i++) {
+ for(FX_INT32 y = 0; y < numResultBlocks; y++) {
+ FX_INT32 iOffset = y < longerBlocksStartAt ? i : i + 1;
+ (*(((CBC_QRDataBlock*)(*result)[y])->m_codewords))[iOffset] = (*rawCodewords)[rawCodewordsOffset++];
+ }
+ }
+ return result.release();
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRDataMask.cpp b/xfa/src/fxbarcode/src/BC_QRDataMask.cpp
new file mode 100644
index 0000000000..ae0807d271
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRDataMask.cpp
@@ -0,0 +1,133 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRDataMask.h"
+static FX_INT32 N_DATA_MASKS = 0;
+CFX_PtrArray* CBC_QRDataMask::DATA_MASKS = NULL;
+void CBC_QRDataMask::Initialize()
+{
+ DATA_MASKS = FX_NEW CFX_PtrArray();
+ N_DATA_MASKS = BuildDataMasks();
+}
+void CBC_QRDataMask::Finalize()
+{
+ Destroy();
+ delete DATA_MASKS;
+}
+void CBC_QRDataMask::Destroy()
+{
+ FX_INT32 i;
+ for(i = 0; i < N_DATA_MASKS; i++) {
+ CBC_QRDataMask* p = (CBC_QRDataMask*)(*DATA_MASKS)[i];
+ if (p) {
+ delete p;
+ }
+ }
+}
+void CBC_QRDataMask::UnmaskBitMatirx(CBC_CommonBitMatrix *bits, FX_INT32 dimension)
+{
+ for(FX_INT32 i = 0; i < dimension; i++) {
+ for(FX_INT32 j = 0; j < dimension; j++) {
+ if(IsMasked(i, j)) {
+ bits->Flip(j, i);
+ }
+ }
+ }
+}
+CBC_QRDataMask* CBC_QRDataMask::ForReference(FX_INT32 reference, FX_INT32 &e)
+{
+ if(reference < 0 || reference > 7) {
+ e = BCExceptionReferenceMustBeBetween0And7;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return (CBC_QRDataMask*)(*DATA_MASKS)[reference];
+}
+class DataMask000 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return ((x + y) % 2) == 0;
+ }
+};
+class DataMask001 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return (x % 2) == 0;
+ }
+};
+class DataMask010 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return y % 3 == 0;
+ }
+};
+class DataMask011 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return (x + y) % 3 == 0;
+ }
+};
+class DataMask100 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return (((x >> 1) + (y / 3)) % 2) == 0;
+ }
+};
+class DataMask101 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ size_t temp = x * y;
+ return (temp % 2) + (temp % 3) == 0;
+ }
+};
+class DataMask110 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ size_t temp = x * y;
+ return (((temp % 2) + (temp % 3)) % 2) == 0;
+ }
+};
+class DataMask111 : public CBC_QRDataMask
+{
+public:
+ FX_BOOL IsMasked(FX_INT32 x, FX_INT32 y)
+ {
+ return ((((x + y) % 2) + ((x * y) % 3)) % 2) == 0;
+ }
+};
+FX_INT32 CBC_QRDataMask::BuildDataMasks()
+{
+ DATA_MASKS->Add(FX_NEW DataMask000);
+ DATA_MASKS->Add(FX_NEW DataMask001);
+ DATA_MASKS->Add(FX_NEW DataMask010);
+ DATA_MASKS->Add(FX_NEW DataMask011);
+ DATA_MASKS->Add(FX_NEW DataMask100);
+ DATA_MASKS->Add(FX_NEW DataMask101);
+ DATA_MASKS->Add(FX_NEW DataMask110);
+ DATA_MASKS->Add(FX_NEW DataMask111);
+ return DATA_MASKS->GetSize();
+}
+CBC_QRDataMask::CBC_QRDataMask()
+{
+}
+CBC_QRDataMask::~CBC_QRDataMask()
+{
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRDecodedBitStreamParser.cpp b/xfa/src/fxbarcode/src/BC_QRDecodedBitStreamParser.cpp
new file mode 100644
index 0000000000..cb1cfb09e7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRDecodedBitStreamParser.cpp
@@ -0,0 +1,238 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_QRCoderMode.h"
+#include "include/BC_CommonBitSource.h"
+#include "include/BC_CommonECI.h"
+#include "include/BC_QRDecodedBitStreamParser.h"
+#include "include/BC_CommonCharacterSetECI.h"
+#include "include/BC_CommonDecoderResult.h"
+#include "include/BC_UtilCodingConvert.h"
+FX_LPCSTR CBC_QRDecodedBitStreamParser::UTF_8 = "utf8";
+const FX_CHAR CBC_QRDecodedBitStreamParser::ALPHANUMERIC_CHARS[45] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
+ 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+ 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ ' ', '$', '%', '*', '+', '-', '.', '/', ':'
+};
+CBC_QRDecodedBitStreamParser::CBC_QRDecodedBitStreamParser()
+{
+}
+CBC_QRDecodedBitStreamParser::~CBC_QRDecodedBitStreamParser()
+{
+}
+CBC_CommonDecoderResult* CBC_QRDecodedBitStreamParser::Decode(CFX_ByteArray *bytes, CBC_QRCoderVersion *version,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 byteModeDecode, FX_INT32 &e)
+{
+ CBC_CommonBitSource bits(bytes);
+ CFX_ByteString result;
+ CBC_CommonCharacterSetECI* currentCharacterSetECI = NULL;
+ FX_BOOL fc1Infact = FALSE;
+ CFX_Int32Array byteSegments;
+ CBC_QRCoderMode* mode = NULL;
+ do {
+ if(bits.Available() < 4) {
+ mode = CBC_QRCoderMode::sTERMINATOR;
+ } else {
+ FX_INT32 iTemp1 = bits.ReadBits(4, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ mode = CBC_QRCoderMode::ForBits(iTemp1, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if(mode == NULL) {
+ e = BCExceptionUnSupportMode;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ }
+ if(!(mode == CBC_QRCoderMode::sTERMINATOR)) {
+ if(mode == CBC_QRCoderMode::sFNC1_FIRST_POSITION || mode == CBC_QRCoderMode::sFNC1_SECOND_POSITION) {
+ fc1Infact = TRUE;
+ } else if(mode == CBC_QRCoderMode::sSTRUCTURED_APPEND) {
+ bits.ReadBits(16, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else if(mode == CBC_QRCoderMode::sECI) {
+ FX_INT32 value = ParseECIValue(&bits, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ currentCharacterSetECI = CBC_CommonCharacterSetECI::GetCharacterSetECIByValue(value);
+ } else {
+ if(mode == CBC_QRCoderMode::sGBK) {
+ bits.ReadBits(4, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ FX_INT32 numBits = mode->GetCharacterCountBits(version, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 count = bits.ReadBits(numBits, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ if(mode == CBC_QRCoderMode::sNUMERIC) {
+ DecodeNumericSegment(&bits, result, count, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else if(mode == CBC_QRCoderMode::sALPHANUMERIC) {
+ DecodeAlphanumericSegment(&bits, result, count, fc1Infact, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else if(mode == CBC_QRCoderMode::sBYTE) {
+ DecodeByteSegment(&bits, result, count, currentCharacterSetECI, &byteSegments, byteModeDecode, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else if(mode == CBC_QRCoderMode::sGBK) {
+ DecodeGBKSegment(&bits, result, count, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else if(mode == CBC_QRCoderMode::sKANJI) {
+ DecodeKanjiSegment(&bits, result, count, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ } else {
+ e = BCExceptionUnSupportMode;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ }
+ }
+ } while (!(mode == CBC_QRCoderMode::sTERMINATOR));
+ CBC_CommonDecoderResult *tempCd = FX_NEW CBC_CommonDecoderResult();
+ tempCd->Init(*bytes, result, byteSegments, ecLevel, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return tempCd;
+}
+void CBC_QRDecodedBitStreamParser::DecodeGBKSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e)
+{
+ CFX_ByteString buffer;
+ FX_INT32 offset = 0;
+ while (count > 0) {
+ FX_INT32 twoBytes = bits->ReadBits(13, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 assembledTwoBytes = ((twoBytes / 0x060) << 8) | (twoBytes % 0x060);
+ if (assembledTwoBytes <= 0x0095d) {
+ assembledTwoBytes += 0x0a1a1;
+ } else {
+ assembledTwoBytes += 0x0a6a1;
+ }
+ buffer += (FX_BYTE) (assembledTwoBytes >> 8);
+ buffer += (FX_BYTE) assembledTwoBytes;
+ count--;
+ }
+ CBC_UtilCodingConvert::LocaleToUtf8(buffer, result);
+}
+void CBC_QRDecodedBitStreamParser::DecodeKanjiSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e)
+{
+ CFX_ByteString buffer;
+ while (count > 0) {
+ FX_INT32 twoBytes = bits->ReadBits(13, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ FX_INT32 assembledTwoBytes = ((twoBytes / 0x0c0) << 8) | (twoBytes % 0x0c0);
+ if (assembledTwoBytes <= 0x01f00) {
+ assembledTwoBytes += 0x08140;
+ } else {
+ assembledTwoBytes += 0x0c140;
+ }
+ buffer += (FX_BYTE) (assembledTwoBytes >> 8);
+ buffer += (FX_BYTE) assembledTwoBytes;
+ count--;
+ }
+ CBC_UtilCodingConvert::LocaleToUtf8(buffer, result);
+}
+void CBC_QRDecodedBitStreamParser::DecodeByteSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count,
+ CBC_CommonCharacterSetECI *currentCharacterSetECI,
+ CFX_Int32Array *byteSegments, FX_INT32 byteModeDecode, FX_INT32 &e)
+{
+ if(count < 0) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ if((count << 3) > bits->Available()) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_BYTE *readBytes = FX_Alloc(FX_BYTE, count);
+ FXSYS_memset32(readBytes, 0x00, count);
+ for(FX_INT32 i = 0; i < count; i++) {
+ readBytes[i] = (FX_BYTE) bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ CFX_ByteString bs(readBytes, count);
+ result += bs;
+ FX_Free(readBytes);
+}
+void CBC_QRDecodedBitStreamParser::DecodeAlphanumericSegment(CBC_CommonBitSource* bits,
+ CFX_ByteString &result, FX_INT32 count, FX_BOOL fac1InEffect, FX_INT32 &e)
+{
+ FX_INT32 start = result.GetLength();
+ while(count > 1) {
+ FX_INT32 nextTwoCharsBits = bits->ReadBits(11, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[nextTwoCharsBits / 45]);
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[nextTwoCharsBits % 45]);
+ count -= 2;
+ }
+ if(count == 1) {
+ FX_INT32 itemp = bits->ReadBits(6, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[itemp]);
+ }
+ if(fac1InEffect) {
+ for(FX_INT32 i = start; i < result.GetLength(); i++) {
+ if(result[i] == '%') {
+ if((i < result.GetLength() - 1) && result[i + 1] == '%') {
+ result.Delete(i + 1, 1);
+ } else {
+ result.SetAt(i, (FX_CHAR)0x1d);
+ }
+ }
+ }
+ }
+}
+void CBC_QRDecodedBitStreamParser::DecodeNumericSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e)
+{
+ while(count >= 3) {
+ FX_INT32 threeDigitsBits = bits->ReadBits(10, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(threeDigitsBits >= 1000) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[threeDigitsBits / 100]);
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[(threeDigitsBits / 10) % 10]);
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[threeDigitsBits % 10]);
+ count -= 3;
+ }
+ if(count == 2) {
+ FX_INT32 twoDigitBits = bits->ReadBits(7, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(twoDigitBits >= 100) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[twoDigitBits / 10]);
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[twoDigitBits % 10]);
+ } else if(count == 1) {
+ FX_INT32 digitBits = bits->ReadBits(4, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(digitBits >= 10) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ BC_FX_ByteString_Append(result, 1, ALPHANUMERIC_CHARS[digitBits]);
+ }
+}
+const CFX_ByteString CBC_QRDecodedBitStreamParser::GuessEncoding(CFX_ByteArray *bytes)
+{
+ return *UTF_8;
+}
+FX_INT32 CBC_QRDecodedBitStreamParser::ParseECIValue(CBC_CommonBitSource* bits, FX_INT32 &e)
+{
+ FX_INT32 firstByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ if((firstByte & 0x80) == 0) {
+ return firstByte & 0x7f;
+ } else if((firstByte & 0xc0) == 0x80) {
+ FX_INT32 secondByte = bits->ReadBits(8, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ return ((firstByte & 0x3f) << 8) | secondByte;
+ } else if((firstByte & 0xe0) == 0xc0) {
+ FX_INT32 secondThirdByte = bits->ReadBits(16, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ return ((firstByte & 0x1f) << 16) | secondThirdByte;
+ }
+ e = BCExceptionBadECI;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ return 0;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRDetector.cpp b/xfa/src/fxbarcode/src/BC_QRDetector.cpp
new file mode 100644
index 0000000000..54abaaef30
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRDetector.cpp
@@ -0,0 +1,248 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRFinderPattern.h"
+#include "include/BC_QRCoderVersion.h"
+#include "include/BC_FinderPatternInfo.h"
+#include "include/BC_QRGridSampler.h"
+#include "include/BC_QRAlignmentPatternFinder.h"
+#include "include/BC_QRFinderPatternFinder.h"
+#include "include/BC_QRDetectorResult.h"
+#include "include/BC_QRDetector.h"
+CBC_QRDetector::CBC_QRDetector(CBC_CommonBitMatrix *image): m_image(image)
+{
+}
+CBC_QRDetector::~CBC_QRDetector()
+{
+}
+CBC_QRDetectorResult *CBC_QRDetector::Detect(FX_INT32 hints, FX_INT32 &e)
+{
+ CBC_QRFinderPatternFinder finder(m_image);
+ CBC_QRFinderPatternInfo* qpi = finder.Find(hints, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_QRFinderPatternInfo> info(qpi);
+ CBC_QRDetectorResult* qdr = ProcessFinderPatternInfo(info.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qdr;
+}
+CBC_QRDetectorResult* CBC_QRDetector::ProcessFinderPatternInfo(CBC_QRFinderPatternInfo *info, FX_INT32 &e)
+{
+ CBC_AutoPtr<CBC_QRFinderPattern> topLeft(info->GetTopLeft());
+ CBC_AutoPtr<CBC_QRFinderPattern> topRight(info->GetTopRight());
+ CBC_AutoPtr<CBC_QRFinderPattern> bottomLeft(info->GetBottomLeft());
+ FX_FLOAT moduleSize = CalculateModuleSize(topLeft.get(), topRight.get(), bottomLeft.get());
+ if(moduleSize < 1.0f) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ FX_INT32 dimension = ComputeDimension(topLeft.get(), topRight.get(), bottomLeft.get(), moduleSize, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_QRCoderVersion *provisionalVersion = CBC_QRCoderVersion::GetProvisionalVersionForDimension(dimension, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 modulesBetweenFPCenters = provisionalVersion->GetDimensionForVersion() - 7;
+ CBC_QRAlignmentPattern * alignmentPattern = NULL;
+ if(provisionalVersion->GetAlignmentPatternCenters()->GetSize() > 0) {
+ FX_FLOAT bottomRightX = topRight->GetX() - topLeft->GetX() + bottomLeft->GetX();
+ FX_FLOAT bottomRightY = topRight->GetY() - topLeft->GetY() + bottomLeft->GetY();
+ FX_FLOAT correctionToTopLeft = 1.0f - 3.0f / (FX_FLOAT) modulesBetweenFPCenters;
+ FX_FLOAT xtemp = (topLeft->GetX() + correctionToTopLeft * (bottomRightX - topLeft->GetX()));
+ FX_INT32 estAlignmentX = (FX_INT32)xtemp ;
+ FX_FLOAT ytemp = (topLeft->GetY() + correctionToTopLeft * (bottomRightY - topLeft->GetY()));
+ FX_INT32 estAlignmentY = (FX_INT32)ytemp;
+ for(FX_INT32 i = 4; i <= 16; i <<= 1) {
+ CBC_QRAlignmentPattern *temp = FindAlignmentInRegion(moduleSize, estAlignmentX, estAlignmentY, (FX_FLOAT) i, e);
+ alignmentPattern = temp;
+ break;
+ }
+ }
+ CBC_CommonBitMatrix *bits = SampleGrid(m_image, topLeft.get(), topRight.get(), bottomLeft.get(), (CBC_ResultPoint*)(alignmentPattern), dimension, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CFX_PtrArray *points = FX_NEW CFX_PtrArray;
+ if(alignmentPattern == NULL) {
+ points->Add(bottomLeft.release());
+ points->Add(topLeft.release());
+ points->Add(topRight.release());
+ } else {
+ points->Add(bottomLeft.release());
+ points->Add(topLeft.release());
+ points->Add(topRight.release());
+ points->Add(alignmentPattern);
+ }
+ return FX_NEW CBC_QRDetectorResult(bits, points);
+}
+CBC_CommonBitMatrix *CBC_QRDetector::SampleGrid(CBC_CommonBitMatrix *image, CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight,
+ CBC_ResultPoint *bottomLeft, CBC_ResultPoint* alignmentPattern,
+ FX_INT32 dimension, FX_INT32 &e)
+{
+ FX_FLOAT dimMinusThree = (FX_FLOAT) dimension - 3.5f;
+ FX_FLOAT bottomRightX;
+ FX_FLOAT bottomRightY;
+ FX_FLOAT sourceBottomRightX;
+ FX_FLOAT sourceBottomRightY;
+ if (alignmentPattern != NULL) {
+ bottomRightX = alignmentPattern->GetX();
+ bottomRightY = alignmentPattern->GetY();
+ sourceBottomRightX = sourceBottomRightY = dimMinusThree - 3.0f;
+ } else {
+ bottomRightX = (topRight->GetX() - topLeft->GetX()) + bottomLeft->GetX();
+ bottomRightY = (topRight->GetY() - topLeft->GetY()) + bottomLeft->GetY();
+ sourceBottomRightX = sourceBottomRightY = dimMinusThree;
+ }
+ CBC_QRGridSampler &sampler = CBC_QRGridSampler::GetInstance();
+ CBC_CommonBitMatrix* cbm = sampler.SampleGrid(image,
+ dimension, dimension,
+ 3.5f,
+ 3.5f,
+ dimMinusThree,
+ 3.5f,
+ sourceBottomRightX,
+ sourceBottomRightY,
+ 3.5f,
+ dimMinusThree,
+ topLeft->GetX(),
+ topLeft->GetY(),
+ topRight->GetX(),
+ topRight->GetY(),
+ bottomRightX,
+ bottomRightY,
+ bottomLeft->GetX(),
+ bottomLeft->GetY(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return cbm;
+}
+FX_INT32 CBC_QRDetector::ComputeDimension(CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight,
+ CBC_ResultPoint *bottomLeft, FX_FLOAT moduleSize, FX_INT32 &e)
+{
+ FX_INT32 tltrCentersDimension = Round(CBC_QRFinderPatternFinder::Distance(topLeft, topRight) / moduleSize);
+ FX_INT32 tlblCentersDimension = Round(CBC_QRFinderPatternFinder::Distance(topLeft, bottomLeft) / moduleSize);
+ FX_INT32 dimension = ((tltrCentersDimension + tlblCentersDimension) >> 1) + 7;
+ switch(dimension & 0x03) {
+ case 0:
+ dimension++;
+ break;
+ case 2:
+ dimension--;
+ break;
+ case 3: {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ }
+ return dimension;
+}
+FX_FLOAT CBC_QRDetector::CalculateModuleSize(CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight, CBC_ResultPoint *bottomLeft)
+{
+ return (CalculateModuleSizeOneWay(topLeft, topRight) + CalculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
+}
+FX_FLOAT CBC_QRDetector::CalculateModuleSizeOneWay(CBC_ResultPoint *pattern, CBC_ResultPoint *otherPattern)
+{
+ FX_FLOAT moduleSizeEst1 = SizeOfBlackWhiteBlackRunBothWays((FX_INT32) pattern->GetX(),
+ (FX_INT32) pattern->GetY(),
+ (FX_INT32) otherPattern->GetX(),
+ (FX_INT32) otherPattern->GetY());
+ FX_FLOAT moduleSizeEst2 = SizeOfBlackWhiteBlackRunBothWays((FX_INT32) otherPattern->GetX(),
+ (FX_INT32) otherPattern->GetY(),
+ (FX_INT32) pattern->GetX(),
+ (FX_INT32) pattern->GetY());
+ if (FXSYS_isnan(moduleSizeEst1)) {
+ return moduleSizeEst2;
+ }
+ if (FXSYS_isnan(moduleSizeEst2)) {
+ return moduleSizeEst1;
+ }
+ return (moduleSizeEst1 + moduleSizeEst2) / 14.0f;
+}
+FX_INT32 CBC_QRDetector::Round(FX_FLOAT d)
+{
+ return (FX_INT32)(d + 0.5f);
+}
+FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRunBothWays(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY)
+{
+ FX_FLOAT result = SizeOfBlackWhiteBlackRun(fromX, fromY, toX, toY);
+ FX_INT32 otherToX = fromX - (toX - fromX);
+ if (otherToX < 0) {
+ otherToX = -1;
+ } else if (otherToX >= m_image->GetWidth()) {
+ otherToX = m_image->GetWidth();
+ }
+ FX_INT32 otherToY = fromY - (toY - fromY);
+ if (otherToY < 0) {
+ otherToY = -1;
+ } else if (otherToY >= m_image->GetHeight()) {
+ otherToY = m_image->GetHeight();
+ }
+ result += SizeOfBlackWhiteBlackRun(fromX, fromY, otherToX, otherToY);
+ return result - 1.0f;
+}
+FX_FLOAT CBC_QRDetector::SizeOfBlackWhiteBlackRun(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY)
+{
+ FX_BOOL steep = FXSYS_abs(toY - fromY) > FXSYS_abs(toX - fromX);
+ if (steep) {
+ FX_INT32 temp = fromX;
+ fromX = fromY;
+ fromY = temp;
+ temp = toX;
+ toX = toY;
+ toY = temp;
+ }
+ FX_INT32 dx = FXSYS_abs(toX - fromX);
+ FX_INT32 dy = FXSYS_abs(toY - fromY);
+ FX_INT32 error = -dx >> 1;
+ FX_INT32 ystep = fromY < toY ? 1 : -1;
+ FX_INT32 xstep = fromX < toX ? 1 : -1;
+ FX_INT32 state = 0;
+ for (FX_INT32 x = fromX, y = fromY; x != toX; x += xstep) {
+ FX_INT32 realX = steep ? y : x;
+ FX_INT32 realY = steep ? x : y;
+ if (state == 1) {
+ if (m_image->Get(realX, realY)) {
+ state++;
+ }
+ } else {
+ if (!m_image->Get(realX, realY)) {
+ state++;
+ }
+ }
+ if (state == 3) {
+ FX_INT32 diffX = x - fromX;
+ FX_INT32 diffY = y - fromY;
+ return (FX_FLOAT) sqrt((double) (diffX * diffX + diffY * diffY));
+ }
+ error += dy;
+ if (error > 0) {
+ y += ystep;
+ error -= dx;
+ }
+ }
+ FX_INT32 diffX = toX - fromX;
+ FX_INT32 diffY = toY - fromY;
+ return (FX_FLOAT) sqrt((double) (diffX * diffX + diffY * diffY));
+}
+CBC_QRAlignmentPattern *CBC_QRDetector::FindAlignmentInRegion(FX_FLOAT overallEstModuleSize, FX_INT32 estAlignmentX,
+ FX_INT32 estAlignmentY, FX_FLOAT allowanceFactor, FX_INT32 &e)
+{
+ FX_INT32 allowance = (FX_INT32) (allowanceFactor * overallEstModuleSize);
+ FX_INT32 alignmentAreaLeftX = FX_MAX(0, estAlignmentX - allowance);
+ FX_INT32 alignmentAreaRightX = FX_MIN(m_image->GetWidth() - 1, estAlignmentX + allowance);
+ if (alignmentAreaRightX - alignmentAreaLeftX < overallEstModuleSize * 3) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ FX_INT32 alignmentAreaTopY = FX_MAX(0, estAlignmentY - allowance);
+ FX_INT32 alignmentAreaBottomY = FX_MIN(m_image->GetHeight() - 1, estAlignmentY + allowance);
+ CBC_QRAlignmentPatternFinder alignmentFinder(m_image,
+ alignmentAreaLeftX,
+ alignmentAreaTopY,
+ alignmentAreaRightX - alignmentAreaLeftX,
+ alignmentAreaBottomY - alignmentAreaTopY,
+ overallEstModuleSize);
+ CBC_QRAlignmentPattern *qap = alignmentFinder.Find(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return qap;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRDetectorResult.cpp b/xfa/src/fxbarcode/src/BC_QRDetectorResult.cpp
new file mode 100644
index 0000000000..1b7b03814d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRDetectorResult.cpp
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRDetectorResult.h"
+CBC_QRDetectorResult::CBC_QRDetectorResult(CBC_CommonBitMatrix *bits, CFX_PtrArray *points):
+ m_bits(bits), m_points(points)
+{
+}
+CBC_QRDetectorResult::~CBC_QRDetectorResult()
+{
+ for(FX_INT32 i = 0; i < m_points->GetSize(); i++) {
+ delete (CBC_ResultPoint*) (*m_points)[i];
+ }
+ m_points->RemoveAll();
+ delete m_points;
+ m_points = NULL;
+ if(m_bits != NULL) {
+ delete m_bits;
+ }
+ m_bits = NULL;
+}
+CBC_CommonBitMatrix* CBC_QRDetectorResult::GetBits()
+{
+ return m_bits;
+}
+CFX_PtrArray *CBC_QRDetectorResult::GetPoints()
+{
+ return m_points;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRFinderPattern.cpp b/xfa/src/fxbarcode/src/BC_QRFinderPattern.cpp
new file mode 100644
index 0000000000..90222d301a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRFinderPattern.cpp
@@ -0,0 +1,55 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRFinderPattern.h"
+CBC_QRFinderPattern::CBC_QRFinderPattern(FX_FLOAT x, FX_FLOAT posY, FX_FLOAT estimatedModuleSize):
+ CBC_ResultPoint(x, posY),
+ m_estimatedModuleSize(estimatedModuleSize), m_count(1)
+{
+}
+CBC_QRFinderPattern::~CBC_QRFinderPattern()
+{
+ m_count = 0;
+ m_x = 0.0f;
+ m_y = 0.0f;
+ m_estimatedModuleSize = 0.0f;
+}
+CBC_QRFinderPattern *CBC_QRFinderPattern::Clone()
+{
+ CBC_QRFinderPattern *temp = FX_NEW CBC_QRFinderPattern(m_x, m_y, m_estimatedModuleSize);
+ temp->m_count = m_count;
+ return temp;
+}
+FX_FLOAT CBC_QRFinderPattern::GetEstimatedModuleSize()
+{
+ return m_estimatedModuleSize;
+}
+FX_INT32 CBC_QRFinderPattern::GetCount()
+{
+ return m_count;
+}
+void CBC_QRFinderPattern::IncrementCount()
+{
+ m_count++;
+}
+FX_BOOL CBC_QRFinderPattern::AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j)
+{
+ if((fabs(i - GetY()) <= moduleSize) && (fabs(j - GetX()) <= moduleSize)) {
+ FX_FLOAT moduleSizeDiff = fabs(moduleSize - m_estimatedModuleSize);
+ return (moduleSizeDiff <= 1.0f) || (moduleSizeDiff / m_estimatedModuleSize <= 1.0f);
+ }
+ return false;
+}
+FX_FLOAT CBC_QRFinderPattern::GetX()
+{
+ return m_x;
+}
+FX_FLOAT CBC_QRFinderPattern::GetY()
+{
+ return m_y;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRFinderPatternFinder.cpp b/xfa/src/fxbarcode/src/BC_QRFinderPatternFinder.cpp
new file mode 100644
index 0000000000..1f5f05a2a6
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRFinderPatternFinder.cpp
@@ -0,0 +1,435 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+#include "include/BC_QRFinderPatternFinder.h"
+#include "include/BC_FinderPatternInfo.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRFinderPattern.h"
+const FX_INT32 CBC_QRFinderPatternFinder::CENTER_QUORUM = 2;
+const FX_INT32 CBC_QRFinderPatternFinder::MIN_SKIP = 3;
+const FX_INT32 CBC_QRFinderPatternFinder::MAX_MODULES = 57;
+const FX_INT32 CBC_QRFinderPatternFinder::INTEGER_MATH_SHIFT = 8;
+CBC_QRFinderPatternFinder::CBC_QRFinderPatternFinder(CBC_CommonBitMatrix* image)
+{
+ m_image = image;
+ m_crossCheckStateCount.SetSize(5);
+ m_hasSkipped = FALSE;
+}
+CBC_QRFinderPatternFinder::~CBC_QRFinderPatternFinder()
+{
+ for(FX_INT32 i = 0; i < m_possibleCenters.GetSize(); i++) {
+ delete (CBC_QRFinderPattern*)m_possibleCenters[i];
+ }
+ m_possibleCenters.RemoveAll();
+}
+class ClosestToAverageComparator
+{
+private:
+ FX_FLOAT m_averageModuleSize;
+public:
+ ClosestToAverageComparator(FX_FLOAT averageModuleSize) : m_averageModuleSize(averageModuleSize)
+ {
+ }
+ FX_INT32 operator()(FinderPattern *a, FinderPattern *b)
+ {
+ FX_FLOAT dA = (FX_FLOAT)fabs(a->GetEstimatedModuleSize() - m_averageModuleSize);
+ FX_FLOAT dB = (FX_FLOAT)fabs(b->GetEstimatedModuleSize() - m_averageModuleSize);
+ return dA < dB ? -1 : dA > dB ? 1 : 0;
+ }
+};
+class CenterComparator
+{
+public:
+ FX_INT32 operator()(FinderPattern *a, FinderPattern *b)
+ {
+ return b->GetCount() - a->GetCount();
+ }
+};
+CBC_CommonBitMatrix *CBC_QRFinderPatternFinder::GetImage()
+{
+ return m_image;
+}
+CFX_Int32Array &CBC_QRFinderPatternFinder::GetCrossCheckStateCount()
+{
+ m_crossCheckStateCount[0] = 0;
+ m_crossCheckStateCount[1] = 0;
+ m_crossCheckStateCount[2] = 0;
+ m_crossCheckStateCount[3] = 0;
+ m_crossCheckStateCount[4] = 0;
+ return m_crossCheckStateCount;
+}
+CFX_PtrArray *CBC_QRFinderPatternFinder::GetPossibleCenters()
+{
+ return &m_possibleCenters;
+}
+CBC_QRFinderPatternInfo* CBC_QRFinderPatternFinder::Find(FX_INT32 hint, FX_INT32 &e)
+{
+ FX_INT32 maxI = m_image->GetHeight();
+ FX_INT32 maxJ = m_image->GetWidth();
+ FX_INT32 iSkip = (3 * maxI) / (4 * MAX_MODULES);
+ if(iSkip < MIN_SKIP || 0) {
+ iSkip = MIN_SKIP;
+ }
+ FX_BOOL done = FALSE;
+ CFX_Int32Array stateCount;
+ stateCount.SetSize(5);
+ for(FX_INT32 i = iSkip - 1; i < maxI && !done; i += iSkip) {
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ stateCount[3] = 0;
+ stateCount[4] = 0;
+ FX_INT32 currentState = 0;
+ for(FX_INT32 j = 0; j < maxJ; j++) {
+ if(m_image->Get(j, i)) {
+ if((currentState & 1) == 1) {
+ currentState++;
+ }
+ stateCount[currentState]++;
+ } else {
+ if((currentState & 1) == 0) {
+ if(currentState == 4) {
+ if(FoundPatternCross(stateCount)) {
+ FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, j);
+ if(confirmed) {
+ iSkip = 2;
+ if(m_hasSkipped) {
+ done = HaveMultiplyConfirmedCenters();
+ } else {
+ FX_INT32 rowSkip = FindRowSkip();
+ if(rowSkip > stateCount[2]) {
+ i += rowSkip - stateCount[2] - iSkip;
+ j = maxJ - 1;
+ }
+ }
+ } else {
+ do {
+ j++;
+ } while (j < maxJ && !m_image->Get(j, i));
+ j--;
+ }
+ currentState = 0;
+ stateCount[0] = 0;
+ stateCount[1] = 0;
+ stateCount[2] = 0;
+ stateCount[3] = 0;
+ stateCount[4] = 0;
+ } else {
+ stateCount[0] = stateCount[2];
+ stateCount[1] = stateCount[3];
+ stateCount[2] = stateCount[4];
+ stateCount[3] = 1;
+ stateCount[4] = 0;
+ currentState = 3;
+ }
+ } else {
+ stateCount[++currentState]++;
+ }
+ } else {
+ stateCount[currentState]++;
+ }
+ }
+ }
+ if(FoundPatternCross(stateCount)) {
+ FX_BOOL confirmed = HandlePossibleCenter(stateCount, i, maxJ);
+ if(confirmed) {
+ iSkip = stateCount[0];
+ if(m_hasSkipped) {
+ done = HaveMultiplyConfirmedCenters();
+ }
+ }
+ }
+ }
+ CFX_PtrArray* ptr = SelectBestpatterns(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CFX_PtrArray > patternInfo(ptr);
+ OrderBestPatterns(patternInfo.get());
+ return new CBC_QRFinderPatternInfo(patternInfo.get());
+}
+void CBC_QRFinderPatternFinder::OrderBestPatterns(CFX_PtrArray *patterns)
+{
+ FX_FLOAT abDistance = Distance((CBC_ResultPoint*)(*patterns)[0], (CBC_ResultPoint*)(*patterns)[1]);
+ FX_FLOAT bcDistance = Distance((CBC_ResultPoint*)(*patterns)[1], (CBC_ResultPoint*)(*patterns)[2]);
+ FX_FLOAT acDistance = Distance((CBC_ResultPoint*)(*patterns)[0], (CBC_ResultPoint*)(*patterns)[2]);
+ CBC_QRFinderPattern *topLeft, *topRight, *bottomLeft;
+ if (bcDistance >= abDistance && bcDistance >= acDistance) {
+ topLeft = (CBC_QRFinderPattern *)(*patterns)[0];
+ topRight = (CBC_QRFinderPattern *)(*patterns)[1];
+ bottomLeft = (CBC_QRFinderPattern *)(*patterns)[2];
+ } else if (acDistance >= bcDistance && acDistance >= abDistance) {
+ topLeft = (CBC_QRFinderPattern *)(*patterns)[1];
+ topRight = (CBC_QRFinderPattern *)(*patterns)[0];
+ bottomLeft = (CBC_QRFinderPattern *)(*patterns)[2];
+ } else {
+ topLeft = (CBC_QRFinderPattern *)(*patterns)[2];
+ topRight = (CBC_QRFinderPattern *)(*patterns)[0];
+ bottomLeft = (CBC_QRFinderPattern *)(*patterns)[1];
+ }
+ if ((bottomLeft->GetY() - topLeft->GetY()) * (topRight->GetX() - topLeft->GetX()) < (bottomLeft->GetX()
+ - topLeft->GetX()) * (topRight->GetY() - topLeft->GetY())) {
+ CBC_QRFinderPattern* temp = topRight;
+ topRight = bottomLeft;
+ bottomLeft = temp;
+ }
+ (*patterns)[0] = bottomLeft;
+ (*patterns)[1] = topLeft;
+ (*patterns)[2] = topRight;
+}
+FX_FLOAT CBC_QRFinderPatternFinder::Distance(CBC_ResultPoint* point1, CBC_ResultPoint* point2)
+{
+ FX_FLOAT dx = point1->GetX() - point2->GetX();
+ FX_FLOAT dy = point1->GetY() - point2->GetY();
+ return (FX_FLOAT)FXSYS_sqrt(dx * dx + dy * dy);
+}
+FX_FLOAT CBC_QRFinderPatternFinder::CenterFromEnd(const CFX_Int32Array &stateCount, FX_INT32 end)
+{
+ return (FX_FLOAT)(end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0f;
+}
+FX_BOOL CBC_QRFinderPatternFinder::FoundPatternCross(const CFX_Int32Array &stateCount)
+{
+ FX_INT32 totalModuleSize = 0;
+ for (FX_INT32 i = 0; i < 5; i++) {
+ FX_INT32 count = stateCount[i];
+ if (count == 0) {
+ return FALSE;
+ }
+ totalModuleSize += count;
+ }
+ if (totalModuleSize < 7) {
+ return FALSE;
+ }
+ FX_INT32 moduleSize = (totalModuleSize << INTEGER_MATH_SHIFT) / 7;
+ FX_INT32 maxVariance = moduleSize / 2;
+ return FXSYS_abs(moduleSize - (stateCount[0] << INTEGER_MATH_SHIFT)) < maxVariance &&
+ FXSYS_abs(moduleSize - (stateCount[1] << INTEGER_MATH_SHIFT)) < maxVariance &&
+ FXSYS_abs(3 * moduleSize - (stateCount[2] << INTEGER_MATH_SHIFT)) < 3 * maxVariance &&
+ FXSYS_abs(moduleSize - (stateCount[3] << INTEGER_MATH_SHIFT)) < maxVariance &&
+ FXSYS_abs(moduleSize - (stateCount[4] << INTEGER_MATH_SHIFT)) < maxVariance;
+}
+FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckVertical(FX_INT32 startI, FX_INT32 centerJ, FX_INT32 maxCount,
+ FX_INT32 originalStateCountTotal)
+{
+ CBC_CommonBitMatrix *image = m_image;
+ FX_INT32 maxI = image->GetHeight();
+ CFX_Int32Array &stateCount = GetCrossCheckStateCount();
+ FX_INT32 i = startI;
+ while(i >= 0 && image->Get(centerJ, i)) {
+ stateCount[2]++;
+ i--;
+ }
+ if(i < 0) {
+ return FXSYS_nan();
+ }
+ while(i >= 0 && !image->Get(centerJ, i) && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ i--;
+ }
+ if(i < 0 || stateCount[1] > maxCount) {
+ return FXSYS_nan();
+ }
+ while(i >= 0 && image->Get(centerJ, i) && stateCount[0] <= maxCount) {
+ stateCount[0]++;
+ i--;
+ }
+ if(stateCount[0] > maxCount) {
+ return FXSYS_nan();
+ }
+ i = startI + 1;
+ while(i < maxI && image->Get(centerJ, i)) {
+ stateCount[2]++;
+ i++;
+ }
+ if(i == maxI) {
+ return FXSYS_nan();
+ }
+ while (i < maxI && !image->Get(centerJ, i) && stateCount[3] < maxCount) {
+ stateCount[3]++;
+ i++;
+ }
+ if (i == maxI || stateCount[3] >= maxCount) {
+ return FXSYS_nan();
+ }
+ while (i < maxI && image->Get(centerJ, i) && stateCount[4] < maxCount) {
+ stateCount[4]++;
+ i++;
+ }
+ if (stateCount[4] >= maxCount) {
+ return FXSYS_nan();
+ }
+ FX_INT32 stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
+ if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
+ return FXSYS_nan();
+ }
+ return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, i) : FXSYS_nan();
+}
+FX_FLOAT CBC_QRFinderPatternFinder::CrossCheckHorizontal(FX_INT32 startJ, FX_INT32 centerI, FX_INT32 maxCount, FX_INT32 originalStateCountTotal)
+{
+ CBC_CommonBitMatrix *image = m_image;
+ FX_INT32 maxJ = image->GetWidth();
+ CFX_Int32Array &stateCount = GetCrossCheckStateCount();
+ FX_INT32 j = startJ;
+ while (j >= 0 && image->Get(j, centerI)) {
+ stateCount[2]++;
+ j--;
+ }
+ if (j < 0) {
+ return FXSYS_nan();
+ }
+ while (j >= 0 && !image->Get(j, centerI) && stateCount[1] <= maxCount) {
+ stateCount[1]++;
+ j--;
+ }
+ if (j < 0 || stateCount[1] > maxCount) {
+ return FXSYS_nan();
+ }
+ while (j >= 0 && image->Get(j, centerI) && stateCount[0] <= maxCount) {
+ stateCount[0]++;
+ j--;
+ }
+ if (stateCount[0] > maxCount) {
+ return FXSYS_nan();
+ }
+ j = startJ + 1;
+ while (j < maxJ && image->Get(j, centerI)) {
+ stateCount[2]++;
+ j++;
+ }
+ if (j == maxJ) {
+ return FXSYS_nan();
+ }
+ while (j < maxJ && !image->Get(j, centerI) && stateCount[3] < maxCount) {
+ stateCount[3]++;
+ j++;
+ }
+ if (j == maxJ || stateCount[3] >= maxCount) {
+ return FXSYS_nan();
+ }
+ while (j < maxJ && image->Get(j, centerI) && stateCount[4] < maxCount) {
+ stateCount[4]++;
+ j++;
+ }
+ if (stateCount[4] >= maxCount) {
+ return FXSYS_nan();
+ }
+ FX_INT32 stateCountTotal = stateCount[0] + stateCount[1] +
+ stateCount[2] + stateCount[3] +
+ stateCount[4];
+ if (5 * FXSYS_abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
+ return FXSYS_nan();
+ }
+ return FoundPatternCross(stateCount) ? CenterFromEnd(stateCount, j) : FXSYS_nan();
+}
+FX_BOOL CBC_QRFinderPatternFinder::HandlePossibleCenter(const CFX_Int32Array &stateCount, FX_INT32 i, FX_INT32 j)
+{
+ FX_INT32 stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
+ FX_FLOAT centerJ = CenterFromEnd(stateCount, j);
+ FX_FLOAT centerI = CrossCheckVertical(i, (FX_INT32) centerJ, stateCount[2], stateCountTotal);
+ if(!FXSYS_isnan(centerI)) {
+ centerJ = CrossCheckHorizontal((FX_INT32) centerJ, (FX_INT32) centerI, stateCount[2], stateCountTotal);
+ if(!FXSYS_isnan(centerJ)) {
+ FX_FLOAT estimatedModuleSize = (FX_FLOAT) stateCountTotal / 7.0f;
+ FX_BOOL found = FALSE;
+ FX_INT32 max = m_possibleCenters.GetSize();
+ for(FX_INT32 index = 0; index < max; index++) {
+ CBC_QRFinderPattern *center = (CBC_QRFinderPattern*)(m_possibleCenters[index]);
+ if(center->AboutEquals(estimatedModuleSize, centerI, centerJ)) {
+ center->IncrementCount();
+ found = TRUE;
+ break;
+ }
+ }
+ if(!found) {
+ m_possibleCenters.Add(FX_NEW CBC_QRFinderPattern(centerJ, centerI, estimatedModuleSize));
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_INT32 CBC_QRFinderPatternFinder::FindRowSkip()
+{
+ FX_INT32 max = m_possibleCenters.GetSize();
+ if (max <= 1) {
+ return 0;
+ }
+ FinderPattern *firstConfirmedCenter = NULL;
+ for (FX_INT32 i = 0; i < max; i++) {
+ CBC_QRFinderPattern *center = (CBC_QRFinderPattern*)m_possibleCenters[i];
+ if (center->GetCount() >= CENTER_QUORUM) {
+ if (firstConfirmedCenter == NULL) {
+ firstConfirmedCenter = center;
+ } else {
+ m_hasSkipped = TRUE;
+ return (FX_INT32) ((fabs(firstConfirmedCenter->GetX() - center->GetX()) -
+ fabs(firstConfirmedCenter->GetY() - center->GetY())) / 2);
+ }
+ }
+ }
+ return 0;
+}
+FX_BOOL CBC_QRFinderPatternFinder::HaveMultiplyConfirmedCenters()
+{
+ FX_INT32 confirmedCount = 0;
+ FX_FLOAT totalModuleSize = 0.0f;
+ FX_INT32 max = m_possibleCenters.GetSize();
+ FX_INT32 i;
+ for (i = 0; i < max; i++) {
+ CBC_QRFinderPattern *pattern = (CBC_QRFinderPattern*)m_possibleCenters[i];
+ if (pattern->GetCount() >= CENTER_QUORUM) {
+ confirmedCount++;
+ totalModuleSize += pattern->GetEstimatedModuleSize();
+ }
+ }
+ if (confirmedCount < 3) {
+ return FALSE;
+ }
+ FX_FLOAT average = totalModuleSize / (FX_FLOAT) max;
+ FX_FLOAT totalDeviation = 0.0f;
+ for (i = 0; i < max; i++) {
+ CBC_QRFinderPattern *pattern = (CBC_QRFinderPattern*)m_possibleCenters[i];
+ totalDeviation += fabs(pattern->GetEstimatedModuleSize() - average);
+ }
+ return totalDeviation <= 0.05f * totalModuleSize;
+}
+inline FX_BOOL centerComparator(FX_LPVOID a, FX_LPVOID b)
+{
+ return ((CBC_QRFinderPattern*)b)->GetCount() < ((CBC_QRFinderPattern*)a)->GetCount();
+}
+CFX_PtrArray *CBC_QRFinderPatternFinder::SelectBestpatterns(FX_INT32 &e)
+{
+ FX_INT32 startSize = m_possibleCenters.GetSize();
+ if(m_possibleCenters.GetSize() < 3) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ FX_FLOAT average = 0.0f;
+ if(startSize > 3) {
+ FX_FLOAT totalModuleSize = 0.0f;
+ for(FX_INT32 i = 0; i < startSize; i++) {
+ totalModuleSize += ((CBC_QRFinderPattern*)m_possibleCenters[i])->GetEstimatedModuleSize();
+ }
+ average = totalModuleSize / (FX_FLOAT)startSize;
+ for(FX_INT32 j = 0; j < m_possibleCenters.GetSize() && m_possibleCenters.GetSize() > 3; j++) {
+ CBC_QRFinderPattern *pattern = (CBC_QRFinderPattern*)m_possibleCenters[j];
+ if(fabs(pattern->GetEstimatedModuleSize() - average) > 0.2f * average) {
+ delete pattern;
+ m_possibleCenters.RemoveAt(j);
+ j--;
+ }
+ }
+ }
+ if(m_possibleCenters.GetSize() > 3) {
+ BC_FX_PtrArray_Sort(m_possibleCenters, centerComparator);
+ }
+ CFX_PtrArray *vec = FX_NEW CFX_PtrArray();
+ vec->SetSize(3);
+ (*vec)[0] = ((CBC_QRFinderPattern*)m_possibleCenters[0])->Clone();
+ (*vec)[1] = ((CBC_QRFinderPattern*)m_possibleCenters[1])->Clone();
+ (*vec)[2] = ((CBC_QRFinderPattern*)m_possibleCenters[2])->Clone();
+ return vec;
+}
diff --git a/xfa/src/fxbarcode/src/BC_QRGridSampler.cpp b/xfa/src/fxbarcode/src/BC_QRGridSampler.cpp
new file mode 100644
index 0000000000..03cf6a3e2f
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_QRGridSampler.cpp
@@ -0,0 +1,112 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_CommonPerspectiveTransform.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_QRGridSampler.h"
+CBC_QRGridSampler CBC_QRGridSampler::m_gridSampler;
+CBC_QRGridSampler::CBC_QRGridSampler()
+{
+}
+CBC_QRGridSampler::~CBC_QRGridSampler()
+{
+}
+CBC_QRGridSampler &CBC_QRGridSampler::GetInstance()
+{
+ return m_gridSampler;
+}
+void CBC_QRGridSampler::CheckAndNudgePoints(CBC_CommonBitMatrix *image, CFX_FloatArray *points, FX_INT32 &e)
+{
+ FX_INT32 width = image->GetWidth();
+ FX_INT32 height = image->GetHeight();
+ FX_BOOL nudged = TRUE;
+ FX_INT32 offset;
+ for (offset = 0; offset < points->GetSize() && nudged; offset += 2) {
+ FX_INT32 x = (FX_INT32) (*points)[offset];
+ FX_INT32 y = (FX_INT32) (*points)[offset + 1];
+ if (x < -1 || x > width || y < -1 || y > height) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ nudged = FALSE;
+ if (x == -1) {
+ (*points)[offset] = 0.0f;
+ nudged = TRUE;
+ } else if (x == width) {
+ (*points)[offset] = (FX_FLOAT)(width - 1);
+ nudged = TRUE;
+ }
+ if (y == -1) {
+ (*points)[offset + 1] = 0.0f;
+ nudged = TRUE;
+ } else if (y == height) {
+ (*points)[offset + 1] = (FX_FLOAT)(height - 1);
+ nudged = TRUE;
+ }
+ }
+ nudged = TRUE;
+ for (offset = (*points).GetSize() - 2; offset >= 0 && nudged; offset -= 2) {
+ FX_INT32 x = (FX_INT32) (*points)[offset];
+ FX_INT32 y = (FX_INT32) (*points)[offset + 1];
+ if (x < -1 || x > width || y < -1 || y > height) {
+ e = BCExceptionRead;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ nudged = FALSE;
+ if (x == -1) {
+ (*points)[offset] = 0.0f;
+ nudged = TRUE;
+ } else if (x == width) {
+ (*points)[offset] = (FX_FLOAT)(width - 1);
+ nudged = TRUE;
+ }
+ if (y == -1) {
+ (*points)[offset + 1] = 0.0f;
+ nudged = TRUE;
+ } else if (y == height) {
+ (*points)[offset + 1] = (FX_FLOAT)(height - 1);
+ nudged = TRUE;
+ }
+ }
+}
+CBC_CommonBitMatrix *CBC_QRGridSampler::SampleGrid(CBC_CommonBitMatrix *image, FX_INT32 dimensionX, FX_INT32 dimensionY,
+ FX_FLOAT p1ToX, FX_FLOAT p1ToY,
+ FX_FLOAT p2ToX, FX_FLOAT p2ToY,
+ FX_FLOAT p3ToX, FX_FLOAT p3ToY,
+ FX_FLOAT p4ToX, FX_FLOAT p4ToY,
+ FX_FLOAT p1FromX, FX_FLOAT p1FromY,
+ FX_FLOAT p2FromX, FX_FLOAT p2FromY,
+ FX_FLOAT p3FromX, FX_FLOAT p3FromY,
+ FX_FLOAT p4FromX, FX_FLOAT p4FromY, FX_INT32 &e)
+{
+ CBC_AutoPtr<CBC_CommonPerspectiveTransform> transform(CBC_CommonPerspectiveTransform::QuadrilateralToQuadrilateral(
+ p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
+ p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY));
+ CBC_CommonBitMatrix *tempBitM = FX_NEW CBC_CommonBitMatrix();
+ tempBitM->Init(dimensionX, dimensionY);
+ CBC_AutoPtr<CBC_CommonBitMatrix> bits(tempBitM);
+ CFX_FloatArray points;
+ points.SetSize(dimensionX << 1);
+ for (FX_INT32 y = 0; y < dimensionY; y++) {
+ FX_INT32 max = points.GetSize();
+ FX_FLOAT iValue = (FX_FLOAT) (y + 0.5f);
+ FX_INT32 x;
+ for (x = 0; x < max; x += 2) {
+ points[x] = (FX_FLOAT) ((x >> 1) + 0.5f);
+ points[x + 1] = iValue;
+ }
+ transform->TransformPoints(&points);
+ CheckAndNudgePoints(image, &points, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ for (x = 0; x < max; x += 2) {
+ if (image->Get((FX_INT32) points[x], (FX_INT32) points[x + 1])) {
+ bits->Set(x >> 1, y);
+ }
+ }
+ }
+ return bits.release();
+}
diff --git a/xfa/src/fxbarcode/src/BC_Reader.cpp b/xfa/src/fxbarcode/src/BC_Reader.cpp
new file mode 100644
index 0000000000..51f7188b50
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Reader.cpp
@@ -0,0 +1,14 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Reader.h"
+CBC_Reader::CBC_Reader()
+{
+}
+CBC_Reader::~CBC_Reader()
+{
+}
diff --git a/xfa/src/fxbarcode/src/BC_ReedSolomon.cpp b/xfa/src/fxbarcode/src/BC_ReedSolomon.cpp
new file mode 100644
index 0000000000..69a4ddde87
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_ReedSolomon.cpp
@@ -0,0 +1,84 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_ReedSolomonGF256Poly.h"
+#include "include/BC_ReedSolomon.h"
+CBC_ReedSolomonEncoder::CBC_ReedSolomonEncoder(CBC_ReedSolomonGF256* field)
+{
+ m_field = field;
+}
+void CBC_ReedSolomonEncoder::Init()
+{
+ m_cachedGenerators.Add(FX_NEW CBC_ReedSolomonGF256Poly(m_field, 1));
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonEncoder::BuildGenerator(FX_INT32 degree, FX_INT32 &e)
+{
+ if(degree >= m_cachedGenerators.GetSize()) {
+ CBC_ReedSolomonGF256Poly* lastGenerator = (CBC_ReedSolomonGF256Poly*)(m_cachedGenerators[m_cachedGenerators.GetSize() - 1]);
+ for(FX_INT32 d = m_cachedGenerators.GetSize(); d <= degree; d++) {
+ CFX_Int32Array temp;
+ temp.Add(1);
+ temp.Add(m_field->Exp(d - 1));
+ CBC_ReedSolomonGF256Poly temp_poly;
+ temp_poly.Init(m_field, &temp, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_ReedSolomonGF256Poly* nextGenerator = lastGenerator->Multiply(&temp_poly, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ m_cachedGenerators.Add(nextGenerator);
+ lastGenerator = nextGenerator;
+ }
+ }
+ return (CBC_ReedSolomonGF256Poly*)(m_cachedGenerators[degree]);
+}
+void CBC_ReedSolomonEncoder::Encode(CFX_Int32Array *toEncode, FX_INT32 ecBytes, FX_INT32 &e)
+{
+ if(ecBytes == 0) {
+ e = BCExceptionNoCorrectionBytes;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ FX_INT32 dataBytes = toEncode->GetSize() - ecBytes;
+ if(dataBytes <= 0) {
+ e = BCExceptionNoDataBytesProvided;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ CBC_ReedSolomonGF256Poly* generator = BuildGenerator(ecBytes, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CFX_Int32Array infoCoefficients;
+ infoCoefficients.SetSize(dataBytes);
+ for(FX_INT32 x = 0; x < dataBytes; x++) {
+ infoCoefficients[x] = toEncode->operator [](x);
+ }
+ CBC_ReedSolomonGF256Poly info;
+ info.Init(m_field, &infoCoefficients, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_ReedSolomonGF256Poly* rsg = info.MultiplyByMonomial(ecBytes, 1, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> infoTemp(rsg);
+ CFX_PtrArray *pa = infoTemp->Divide(generator, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_AutoPtr<CFX_PtrArray > temp(pa);
+ CBC_ReedSolomonGF256Poly* remainder = (CBC_ReedSolomonGF256Poly*)(temp->operator [](1));
+ CFX_Int32Array* coefficients = remainder->GetCoefficients();
+ FX_INT32 numZeroCoefficients = ecBytes - coefficients->GetSize();
+ for(FX_INT32 i = 0; i < numZeroCoefficients; i++) {
+ (*toEncode)[dataBytes + i] = 0;
+ }
+ for(FX_INT32 y = 0; y < coefficients->GetSize(); y++) {
+ (*toEncode)[dataBytes + numZeroCoefficients + y] =
+ coefficients->operator [](y);
+ }
+ for (FX_INT32 k = 0; k < temp->GetSize(); k++) {
+ delete (CBC_ReedSolomonGF256Poly*)(*temp)[k];
+ }
+}
+CBC_ReedSolomonEncoder::~CBC_ReedSolomonEncoder()
+{
+ for (FX_INT32 i = 0; i < m_cachedGenerators.GetSize(); i++) {
+ delete (CBC_ReedSolomonGF256Poly*)m_cachedGenerators[i];
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_ReedSolomonDecoder.cpp b/xfa/src/fxbarcode/src/BC_ReedSolomonDecoder.cpp
new file mode 100644
index 0000000000..36013053a0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_ReedSolomonDecoder.cpp
@@ -0,0 +1,208 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_ReedSolomonGF256Poly.h"
+#include "include/BC_ReedSolomonDecoder.h"
+CBC_ReedSolomonDecoder::CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256* field)
+{
+ m_field = field;
+}
+CBC_ReedSolomonDecoder::~CBC_ReedSolomonDecoder()
+{
+}
+void CBC_ReedSolomonDecoder::Decode(CFX_Int32Array* received, FX_INT32 twoS, FX_INT32 &e)
+{
+ CBC_ReedSolomonGF256Poly poly;
+ poly.Init(m_field, received, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CFX_Int32Array syndromeCoefficients;
+ syndromeCoefficients.SetSize(twoS);
+ FX_BOOL dataMatrix = FALSE;
+ FX_BOOL noError = TRUE;
+ for (FX_INT32 i = 0; i < twoS; i++) {
+ FX_INT32 eval = poly.EvaluateAt(m_field->Exp(dataMatrix ? i + 1 : i));
+ syndromeCoefficients[twoS - 1 - i] = eval;
+ if (eval != 0) {
+ noError = FALSE;
+ }
+ }
+ if(noError) {
+ return;
+ }
+ CBC_ReedSolomonGF256Poly syndrome;
+ syndrome.Init(m_field, &syndromeCoefficients, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_ReedSolomonGF256Poly* rsg = m_field->BuildMonomial(twoS, 1, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp(rsg);
+ CFX_PtrArray* pa = RunEuclideanAlgorithm(temp.get(), &syndrome, twoS, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_AutoPtr<CFX_PtrArray > sigmaOmega(pa);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> sigma((CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[0]);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> omega((CBC_ReedSolomonGF256Poly*)(*sigmaOmega)[1]);
+ CFX_Int32Array* ia1 = FindErrorLocations(sigma.get(), e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_AutoPtr<CFX_Int32Array > errorLocations(ia1);
+ CFX_Int32Array* ia2 = FindErrorMagnitudes(omega.get(), errorLocations.get(), dataMatrix, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ CBC_AutoPtr<CFX_Int32Array > errorMagnitudes(ia2);
+ for (FX_INT32 k = 0; k < errorLocations->GetSize(); k++) {
+ FX_INT32 position = received->GetSize() - 1 - m_field->Log((*errorLocations)[k], e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ if(position < 0) {
+ e = BCExceptionBadErrorLocation;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ (*received)[position] = CBC_ReedSolomonGF256::AddOrSubtract((*received)[position], (*errorMagnitudes)[k]);
+ }
+}
+CFX_PtrArray *CBC_ReedSolomonDecoder::RunEuclideanAlgorithm(CBC_ReedSolomonGF256Poly* a, CBC_ReedSolomonGF256Poly* b, FX_INT32 R, FX_INT32 &e)
+{
+ if (a->GetDegree() < b->GetDegree()) {
+ CBC_ReedSolomonGF256Poly* temp = a;
+ a = b;
+ b = temp;
+ }
+ CBC_ReedSolomonGF256Poly* rsg1 = a->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> rLast(rsg1);
+ CBC_ReedSolomonGF256Poly* rsg2 = b->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> r(rsg2);
+ CBC_ReedSolomonGF256Poly* rsg3 = m_field->GetOne()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> sLast(rsg3);
+ CBC_ReedSolomonGF256Poly* rsg4 = m_field->GetZero()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> s(rsg4);
+ CBC_ReedSolomonGF256Poly* rsg5 = m_field->GetZero()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> tLast(rsg5);
+ CBC_ReedSolomonGF256Poly* rsg6 = m_field->GetOne()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> t(rsg6);
+ while (r->GetDegree() >= R / 2) {
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> rLastLast = rLast;
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> sLastLast = sLast;
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> tLastlast = tLast;
+ rLast = r;
+ sLast = s;
+ tLast = t;
+ if (rLast->IsZero()) {
+ e = BCExceptionR_I_1IsZero;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_ReedSolomonGF256Poly* rsg7 = rLastLast->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> rTemp(rsg7);
+ r = rTemp;
+ CBC_ReedSolomonGF256Poly* rsg8 = m_field->GetZero()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> q(rsg8);
+ FX_INT32 denominatorLeadingTerm = rLast->GetCoefficients(rLast->GetDegree());
+ FX_INT32 dltInverse = m_field->Inverse(denominatorLeadingTerm, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ while (r->GetDegree() >= rLast->GetDegree() && !(r->IsZero())) {
+ FX_INT32 degreeDiff = r->GetDegree() - rLast->GetDegree();
+ FX_INT32 scale = m_field->Multiply(r->GetCoefficients(r->GetDegree()), dltInverse);
+ CBC_ReedSolomonGF256Poly* rsgp1 = m_field->BuildMonomial(degreeDiff, scale, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> build(rsgp1);
+ CBC_ReedSolomonGF256Poly* rsgp2 = q->AddOrSubtract(build.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp(rsgp2);
+ q = temp;
+ CBC_ReedSolomonGF256Poly* rsgp3 = rLast->MultiplyByMonomial(degreeDiff, scale, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> multiply(rsgp3);
+ CBC_ReedSolomonGF256Poly* rsgp4 = r->AddOrSubtract(multiply.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp3(rsgp4);
+ r = temp3;
+ }
+ CBC_ReedSolomonGF256Poly* rsg9 = q->Multiply(sLast.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp1(rsg9);
+ CBC_ReedSolomonGF256Poly* rsg10 = temp1->AddOrSubtract(sLastLast.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp2(rsg10);
+ s = temp2;
+ CBC_ReedSolomonGF256Poly* rsg11 = q->Multiply(tLast.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp5(rsg11);
+ CBC_ReedSolomonGF256Poly* rsg12 = temp5->AddOrSubtract(tLastlast.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp6(rsg12);
+ t = temp6;
+ }
+ FX_INT32 sigmaTildeAtZero = t->GetCoefficients(0);
+ if (sigmaTildeAtZero == 0) {
+ e = BCExceptionIsZero;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ FX_INT32 inverse = m_field->Inverse(sigmaTildeAtZero, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_ReedSolomonGF256Poly* rsg13 = t->Multiply(inverse, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> sigma(rsg13);
+ CBC_ReedSolomonGF256Poly* rsg14 = r->Multiply(inverse, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> omega(rsg14);
+ CFX_PtrArray *temp = FX_NEW CFX_PtrArray;
+ temp->Add(sigma.release());
+ temp->Add(omega.release());
+ return temp;
+}
+CFX_Int32Array *CBC_ReedSolomonDecoder::FindErrorLocations(CBC_ReedSolomonGF256Poly* errorLocator, FX_INT32 &e)
+{
+ FX_INT32 numErrors = errorLocator->GetDegree();
+ if (numErrors == 1) {
+ CBC_AutoPtr<CFX_Int32Array > temp(FX_NEW CFX_Int32Array);
+ temp->Add(errorLocator->GetCoefficients(1));
+ return temp.release();
+ }
+ CFX_Int32Array *tempT = FX_NEW CFX_Int32Array;
+ tempT->SetSize(numErrors);
+ CBC_AutoPtr<CFX_Int32Array > result(tempT);
+ FX_INT32 ie = 0;
+ for (FX_INT32 i = 1; i < 256 && ie < numErrors; i++) {
+ if(errorLocator->EvaluateAt(i) == 0) {
+ (*result)[ie] = m_field->Inverse(i, ie);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ ie++;
+ }
+ }
+ if (ie != numErrors) {
+ e = BCExceptionDegreeNotMatchRoots;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return result.release();
+}
+CFX_Int32Array *CBC_ReedSolomonDecoder::FindErrorMagnitudes(CBC_ReedSolomonGF256Poly* errorEvaluator, CFX_Int32Array* errorLocations, FX_BOOL dataMatrix, FX_INT32 &e)
+{
+ FX_INT32 s = errorLocations->GetSize();
+ CFX_Int32Array * temp = FX_NEW CFX_Int32Array;
+ temp->SetSize(s);
+ CBC_AutoPtr<CFX_Int32Array > result(temp);
+ for (FX_INT32 i = 0; i < s; i++) {
+ FX_INT32 xiInverse = m_field->Inverse(errorLocations->operator [](i), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_INT32 denominator = 1;
+ for(FX_INT32 j = 0; j < s; j++) {
+ if(i != j) {
+ denominator = m_field->Multiply(denominator,
+ CBC_ReedSolomonGF256::AddOrSubtract(1, m_field->Multiply(errorLocations->operator [](j), xiInverse)));
+ }
+ }
+ FX_INT32 temp = m_field->Inverse(denominator, temp);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ (*result)[i] = m_field->Multiply(errorEvaluator->EvaluateAt(xiInverse),
+ temp);
+ }
+ return result.release();
+}
diff --git a/xfa/src/fxbarcode/src/BC_ReedSolomonGF256.cpp b/xfa/src/fxbarcode/src/BC_ReedSolomonGF256.cpp
new file mode 100644
index 0000000000..ac856b0678
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_ReedSolomonGF256.cpp
@@ -0,0 +1,124 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ReedSolomonGF256Poly.h"
+#include "include/BC_ReedSolomonGF256.h"
+CBC_ReedSolomonGF256 *CBC_ReedSolomonGF256::QRCodeFild = NULL;
+CBC_ReedSolomonGF256 *CBC_ReedSolomonGF256::DataMatrixField = NULL;
+void CBC_ReedSolomonGF256::Initialize()
+{
+ QRCodeFild = FX_NEW CBC_ReedSolomonGF256(0x011D);
+ QRCodeFild->Init();
+ DataMatrixField = FX_NEW CBC_ReedSolomonGF256(0x012D);
+ DataMatrixField->Init();
+}
+void CBC_ReedSolomonGF256::Finalize()
+{
+ if (QRCodeFild) {
+ delete QRCodeFild;
+ }
+ QRCodeFild = NULL;
+ if (DataMatrixField) {
+ delete DataMatrixField;
+ }
+ DataMatrixField = NULL;
+}
+CBC_ReedSolomonGF256::CBC_ReedSolomonGF256(FX_INT32 primitive)
+{
+ FX_INT32 x = 1;
+ for(FX_INT32 j = 0; j < 256; j++) {
+ m_expTable[j] = x;
+ x <<= 1;
+ if(x >= 0x100) {
+ x ^= primitive;
+ }
+ }
+ for(FX_INT32 i = 0; i < 255; i++) {
+ m_logTable[m_expTable[i]] = i;
+ }
+ m_logTable[0] = 0;
+}
+void CBC_ReedSolomonGF256::Init()
+{
+ m_zero = FX_NEW CBC_ReedSolomonGF256Poly(this, 0);
+ m_one = FX_NEW CBC_ReedSolomonGF256Poly(this, 1);
+}
+CBC_ReedSolomonGF256::~CBC_ReedSolomonGF256()
+{
+ if(m_zero != NULL) {
+ delete m_zero;
+ m_zero = NULL;
+ }
+ if(m_one != NULL) {
+ delete m_one;
+ m_one = NULL;
+ }
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256::GetZero()
+{
+ return m_zero;
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256::GetOne()
+{
+ return m_one;
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256::BuildMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e)
+{
+ if(degree < 0) {
+ e = BCExceptionDegreeIsNegative;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ if(coefficient == 0) {
+ CBC_ReedSolomonGF256Poly* temp = m_zero->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+ }
+ CFX_Int32Array coefficients;
+ coefficients.SetSize(degree + 1);
+ coefficients[0] = coefficient;
+ CBC_ReedSolomonGF256Poly *temp = FX_NEW CBC_ReedSolomonGF256Poly();
+ temp->Init(this, &coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+FX_INT32 CBC_ReedSolomonGF256::AddOrSubtract(FX_INT32 a, FX_INT32 b)
+{
+ return a ^ b;
+}
+FX_INT32 CBC_ReedSolomonGF256::Exp(FX_INT32 a)
+{
+ return m_expTable[a];
+}
+FX_INT32 CBC_ReedSolomonGF256::Log(FX_INT32 a, FX_INT32 &e)
+{
+ if(a == 0) {
+ e = BCExceptionAIsZero;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ return m_logTable[a];
+}
+FX_INT32 CBC_ReedSolomonGF256::Inverse(FX_INT32 a, FX_INT32 &e)
+{
+ if(a == 0) {
+ e = BCExceptionAIsZero;
+ BC_EXCEPTION_CHECK_ReturnValue(e, 0);
+ }
+ return m_expTable[255 - m_logTable[a]];
+}
+FX_INT32 CBC_ReedSolomonGF256::Multiply(FX_INT32 a, FX_INT32 b)
+{
+ if(a == 0 || b == 0) {
+ return 0;
+ }
+ if(a == 1) {
+ return b;
+ }
+ if(b == 1) {
+ return a;
+ }
+ return m_expTable[(m_logTable[a] + m_logTable[b]) % 255];
+}
diff --git a/xfa/src/fxbarcode/src/BC_ReedSolomonGF256Poly.cpp b/xfa/src/fxbarcode/src/BC_ReedSolomonGF256Poly.cpp
new file mode 100644
index 0000000000..85c1b5a5bf
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_ReedSolomonGF256Poly.cpp
@@ -0,0 +1,241 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ReedSolomonGF256.h"
+#include "include/BC_ReedSolomonGF256Poly.h"
+CBC_ReedSolomonGF256Poly::CBC_ReedSolomonGF256Poly(CBC_ReedSolomonGF256* field, FX_INT32 coefficients)
+{
+ if(field == NULL) {
+ return;
+ }
+ m_field = field;
+ m_coefficients.Add(coefficients);
+}
+CBC_ReedSolomonGF256Poly::CBC_ReedSolomonGF256Poly()
+{
+ m_field = NULL;
+}
+void CBC_ReedSolomonGF256Poly::Init(CBC_ReedSolomonGF256* field, CFX_Int32Array* coefficients, FX_INT32 &e)
+{
+ if(coefficients == NULL || coefficients->GetSize() == 0) {
+ e = BCExceptionCoefficientsSizeIsNull;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ m_field = field;
+ FX_INT32 coefficientsLength = coefficients->GetSize();
+ if((coefficientsLength > 1 && (*coefficients)[0] == 0)) {
+ FX_INT32 firstNonZero = 1;
+ while((firstNonZero < coefficientsLength) && ((*coefficients)[firstNonZero] == 0)) {
+ firstNonZero++;
+ }
+ if(firstNonZero == coefficientsLength) {
+ m_coefficients.Copy( *(m_field->GetZero()->GetCoefficients()));
+ } else {
+ m_coefficients.SetSize(coefficientsLength - firstNonZero);
+ for(FX_INT32 i = firstNonZero, j = 0; i < coefficientsLength; i++, j++) {
+ m_coefficients[j] = coefficients->operator [](i);
+ }
+ }
+ } else {
+ m_coefficients.Copy(*coefficients);
+ }
+}
+CFX_Int32Array* CBC_ReedSolomonGF256Poly::GetCoefficients()
+{
+ return &m_coefficients;
+}
+FX_INT32 CBC_ReedSolomonGF256Poly::GetDegree()
+{
+ return m_coefficients.GetSize() - 1;
+}
+FX_BOOL CBC_ReedSolomonGF256Poly::IsZero()
+{
+ return m_coefficients[0] == 0;
+}
+FX_INT32 CBC_ReedSolomonGF256Poly::GetCoefficients(FX_INT32 degree)
+{
+ return m_coefficients[m_coefficients.GetSize() - 1 - degree];
+}
+FX_INT32 CBC_ReedSolomonGF256Poly::EvaluateAt(FX_INT32 a)
+{
+ if(a == 0) {
+ return GetCoefficients(0);
+ }
+ FX_INT32 size = m_coefficients.GetSize();
+ if(a == 1) {
+ FX_INT32 result = 0;
+ for(FX_INT32 i = 0; i < size; i++) {
+ result = CBC_ReedSolomonGF256::AddOrSubtract(result, m_coefficients[i]);
+ }
+ return result;
+ }
+ FX_INT32 result = m_coefficients[0];
+ for(FX_INT32 j = 1; j < size; j++) {
+ result = CBC_ReedSolomonGF256::AddOrSubtract(
+ m_field->Multiply(a, result),
+ m_coefficients[j]);
+ }
+ return result;
+}
+CBC_ReedSolomonGF256Poly *CBC_ReedSolomonGF256Poly::Clone(FX_INT32 &e)
+{
+ CBC_ReedSolomonGF256Poly *temp = FX_NEW CBC_ReedSolomonGF256Poly();
+ temp->Init(m_field, &m_coefficients, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::AddOrSubtract(CBC_ReedSolomonGF256Poly* other, FX_INT32 &e)
+{
+ if(IsZero()) {
+ return other->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ if(other->IsZero()) {
+ return this->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CFX_Int32Array smallerCoefficients;
+ smallerCoefficients.Copy(m_coefficients);
+ CFX_Int32Array largerCoefficients;
+ largerCoefficients.Copy( *(other->GetCoefficients()));
+ if(smallerCoefficients.GetSize() > largerCoefficients.GetSize()) {
+ CFX_Int32Array temp;
+ temp.Copy(smallerCoefficients);
+ smallerCoefficients.Copy(largerCoefficients);
+ largerCoefficients.Copy(temp);
+ }
+ CFX_Int32Array sumDiff;
+ sumDiff.SetSize(largerCoefficients.GetSize() );
+ FX_INT32 lengthDiff = largerCoefficients.GetSize() - smallerCoefficients.GetSize();
+ for(FX_INT32 i = 0; i < lengthDiff; i++) {
+ sumDiff[i] = largerCoefficients[i];
+ }
+ for(FX_INT32 j = lengthDiff; j < largerCoefficients.GetSize(); j++) {
+ sumDiff[j] = (CBC_ReedSolomonGF256::AddOrSubtract(smallerCoefficients[j - lengthDiff],
+ largerCoefficients[j]));
+ }
+ CBC_ReedSolomonGF256Poly *temp = FX_NEW CBC_ReedSolomonGF256Poly();
+ temp->Init(m_field, &sumDiff, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(CBC_ReedSolomonGF256Poly* other, FX_INT32 &e)
+{
+ if(IsZero() || other->IsZero()) {
+ CBC_ReedSolomonGF256Poly *temp = m_field->GetZero()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+ }
+ CFX_Int32Array aCoefficients ;
+ aCoefficients.Copy(m_coefficients);
+ FX_INT32 aLength = m_coefficients.GetSize();
+ CFX_Int32Array bCoefficients;
+ bCoefficients.Copy(*(other->GetCoefficients()));
+ FX_INT32 bLength = other->GetCoefficients()->GetSize();
+ CFX_Int32Array product;
+ product.SetSize(aLength + bLength - 1);
+ for(FX_INT32 i = 0; i < aLength; i++) {
+ FX_INT32 aCoeff = m_coefficients[i];
+ for(FX_INT32 j = 0; j < bLength; j++) {
+ product[i + j] = CBC_ReedSolomonGF256::AddOrSubtract(
+ product[i + j],
+ m_field->Multiply(aCoeff, other->GetCoefficients()->operator [](j)));
+ }
+ }
+ CBC_ReedSolomonGF256Poly *temp = FX_NEW CBC_ReedSolomonGF256Poly();
+ temp->Init(m_field, &product, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::Multiply(FX_INT32 scalar, FX_INT32 &e)
+{
+ if(scalar == 0) {
+ CBC_ReedSolomonGF256Poly *temp = m_field->GetZero()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+ }
+ if(scalar == 1) {
+ return this->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ FX_INT32 size = m_coefficients.GetSize();
+ CFX_Int32Array product;
+ product.SetSize(size);
+ for(FX_INT32 i = 0; i < size; i++) {
+ product[i] = m_field->Multiply(m_coefficients[i], scalar);
+ }
+ CBC_ReedSolomonGF256Poly *temp = FX_NEW CBC_ReedSolomonGF256Poly();
+ temp->Init(m_field, &product, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+CBC_ReedSolomonGF256Poly* CBC_ReedSolomonGF256Poly::MultiplyByMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e)
+{
+ if(degree < 0) {
+ e = BCExceptionDegreeIsNegative;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ if(coefficient == 0) {
+ CBC_ReedSolomonGF256Poly *temp = m_field->GetZero()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+ }
+ FX_INT32 size = m_coefficients.GetSize();
+ CFX_Int32Array product;
+ product.SetSize(size + degree);
+ for(FX_INT32 i = 0; i < size; i++) {
+ product[i] = (m_field->Multiply(m_coefficients[i], coefficient));
+ }
+ CBC_ReedSolomonGF256Poly *temp = FX_NEW CBC_ReedSolomonGF256Poly();
+ temp->Init(m_field, &product, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ return temp;
+}
+CFX_PtrArray* CBC_ReedSolomonGF256Poly::Divide(CBC_ReedSolomonGF256Poly *other, FX_INT32 &e)
+{
+ if(other->IsZero()) {
+ e = BCExceptionDivideByZero;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_ReedSolomonGF256Poly* rsg1 = m_field->GetZero()->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> quotient(rsg1);
+ CBC_ReedSolomonGF256Poly* rsg2 = this->Clone(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> remainder(rsg2);
+ FX_INT32 denominatorLeadingTerm = other->GetCoefficients(other->GetDegree());
+ FX_INT32 inverseDenominatorLeadingTeam = m_field->Inverse(denominatorLeadingTerm, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ FX_BOOL bFirst = TRUE;
+ while(remainder->GetDegree() >= other->GetDegree() && !remainder->IsZero()) {
+ FX_INT32 degreeDifference = remainder->GetDegree() - other->GetDegree();
+ FX_INT32 scale = m_field->Multiply(remainder->GetCoefficients((remainder->GetDegree())),
+ inverseDenominatorLeadingTeam);
+ CBC_ReedSolomonGF256Poly* rsg3 = other->MultiplyByMonomial(degreeDifference, scale, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> term(rsg3);
+ CBC_ReedSolomonGF256Poly* rsg4 = m_field->BuildMonomial(degreeDifference, scale, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> iteratorQuotient(rsg4);
+ CBC_ReedSolomonGF256Poly* rsg5 = quotient->AddOrSubtract(iteratorQuotient.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp(rsg5);
+ quotient = temp;
+ CBC_ReedSolomonGF256Poly* rsg6 = remainder->AddOrSubtract(term.get(), e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ CBC_AutoPtr<CBC_ReedSolomonGF256Poly> temp1(rsg6);
+ remainder = temp1;
+ }
+ CFX_PtrArray* tempPtrA = FX_NEW CFX_PtrArray;
+ tempPtrA->Add(quotient.release());
+ tempPtrA->Add(remainder.release());
+ return tempPtrA;
+}
+CBC_ReedSolomonGF256Poly::~CBC_ReedSolomonGF256Poly()
+{
+ m_coefficients.RemoveAll();
+}
diff --git a/xfa/src/fxbarcode/src/BC_ResultPoint.cpp b/xfa/src/fxbarcode/src/BC_ResultPoint.cpp
new file mode 100644
index 0000000000..1e9b72ae5c
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_ResultPoint.cpp
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_ResultPoint.h"
+CBC_ResultPoint::CBC_ResultPoint(FX_FLOAT x, FX_FLOAT y): m_x(x), m_y(y)
+{
+}
+FX_FLOAT CBC_ResultPoint::GetX()
+{
+ return m_x;
+}
+FX_FLOAT CBC_ResultPoint::GetY()
+{
+ return m_y;
+}
diff --git a/xfa/src/fxbarcode/src/BC_SymbolInfo.cpp b/xfa/src/fxbarcode/src/BC_SymbolInfo.cpp
new file mode 100644
index 0000000000..360da8dc1a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_SymbolInfo.cpp
@@ -0,0 +1,226 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_DataMatrixSymbolInfo144.h"
+#define SYMBOLS_COUNT 30
+CBC_SymbolInfo* CBC_SymbolInfo::m_PROD_SYMBOLS[30] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+CBC_SymbolInfo* CBC_SymbolInfo::m_symbols[30] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+void CBC_SymbolInfo::Initialize()
+{
+ m_PROD_SYMBOLS[0] = FX_NEW CBC_SymbolInfo(FALSE, 3, 5, 8, 8, 1);
+ m_PROD_SYMBOLS[1] = FX_NEW CBC_SymbolInfo(FALSE, 5, 7, 10, 10, 1);
+ m_PROD_SYMBOLS[2] = FX_NEW CBC_SymbolInfo(TRUE, 5, 7, 16, 6, 1);
+ m_PROD_SYMBOLS[3] = FX_NEW CBC_SymbolInfo(FALSE, 8, 10, 12, 12, 1);
+ m_PROD_SYMBOLS[4] = FX_NEW CBC_SymbolInfo(TRUE, 10, 11, 14, 6, 2);
+ m_PROD_SYMBOLS[5] = FX_NEW CBC_SymbolInfo(FALSE, 12, 12, 14, 14, 1);
+ m_PROD_SYMBOLS[6] = FX_NEW CBC_SymbolInfo(TRUE, 16, 14, 24, 10, 1);
+ m_PROD_SYMBOLS[7] = FX_NEW CBC_SymbolInfo(FALSE, 18, 14, 16, 16, 1);
+ m_PROD_SYMBOLS[8] = FX_NEW CBC_SymbolInfo(FALSE, 22, 18, 18, 18, 1);
+ m_PROD_SYMBOLS[9] = FX_NEW CBC_SymbolInfo(TRUE, 22, 18, 16, 10, 2);
+ m_PROD_SYMBOLS[10] = FX_NEW CBC_SymbolInfo(FALSE, 30, 20, 20, 20, 1);
+ m_PROD_SYMBOLS[11] = FX_NEW CBC_SymbolInfo(TRUE, 32, 24, 16, 14, 2);
+ m_PROD_SYMBOLS[12] = FX_NEW CBC_SymbolInfo(FALSE, 36, 24, 22, 22, 1);
+ m_PROD_SYMBOLS[13] = FX_NEW CBC_SymbolInfo(FALSE, 44, 28, 24, 24, 1);
+ m_PROD_SYMBOLS[14] = FX_NEW CBC_SymbolInfo(TRUE, 49, 28, 22, 14, 2);
+ m_PROD_SYMBOLS[15] = FX_NEW CBC_SymbolInfo(FALSE, 62, 36, 14, 14, 4);
+ m_PROD_SYMBOLS[16] = FX_NEW CBC_SymbolInfo(FALSE, 86, 42, 16, 16, 4);
+ m_PROD_SYMBOLS[17] = FX_NEW CBC_SymbolInfo(FALSE, 114, 48, 18, 18, 4);
+ m_PROD_SYMBOLS[18] = FX_NEW CBC_SymbolInfo(FALSE, 144, 56, 20, 20, 4);
+ m_PROD_SYMBOLS[19] = FX_NEW CBC_SymbolInfo(FALSE, 174, 68, 22, 22, 4);
+ m_PROD_SYMBOLS[20] = FX_NEW CBC_SymbolInfo(FALSE, 204, 84, 24, 24, 4, 102, 42);
+ m_PROD_SYMBOLS[21] = FX_NEW CBC_SymbolInfo(FALSE, 280, 112, 14, 14, 16, 140, 56);
+ m_PROD_SYMBOLS[22] = FX_NEW CBC_SymbolInfo(FALSE, 368, 144, 16, 16, 16, 92, 36);
+ m_PROD_SYMBOLS[23] = FX_NEW CBC_SymbolInfo(FALSE, 456, 192, 18, 18, 16, 114, 48);
+ m_PROD_SYMBOLS[24] = FX_NEW CBC_SymbolInfo(FALSE, 576, 224, 20, 20, 16, 144, 56);
+ m_PROD_SYMBOLS[25] = FX_NEW CBC_SymbolInfo(FALSE, 696, 272, 22, 22, 16, 174, 68);
+ m_PROD_SYMBOLS[26] = FX_NEW CBC_SymbolInfo(FALSE, 816, 336, 24, 24, 16, 136, 56);
+ m_PROD_SYMBOLS[27] = FX_NEW CBC_SymbolInfo(FALSE, 1050, 408, 18, 18, 36, 175, 68);
+ m_PROD_SYMBOLS[28] = FX_NEW CBC_SymbolInfo(FALSE, 1304, 496, 20, 20, 36, 163, 62);
+ m_PROD_SYMBOLS[29] = FX_NEW CBC_DataMatrixSymbolInfo144();
+ for (FX_INT32 i = 0; i < SYMBOLS_COUNT; i++) {
+ m_symbols[i] = m_PROD_SYMBOLS[i];
+ }
+}
+void CBC_SymbolInfo::Finalize()
+{
+ for (FX_INT32 i = 0; i < SYMBOLS_COUNT; i++) {
+ delete m_PROD_SYMBOLS[i];
+ m_PROD_SYMBOLS[i] = NULL;
+ m_symbols[i] = NULL;
+ }
+}
+CBC_SymbolInfo::CBC_SymbolInfo(FX_BOOL rectangular, FX_INT32 dataCapacity, FX_INT32 errorCodewords, FX_INT32 matrixWidth, FX_INT32 matrixHeight, FX_INT32 dataRegions)
+{
+ m_rectangular = rectangular;
+ m_dataCapacity = dataCapacity;
+ m_errorCodewords = errorCodewords;
+ m_matrixWidth = matrixWidth;
+ m_matrixHeight = matrixHeight;
+ m_dataRegions = dataRegions;
+ m_rsBlockData = dataCapacity;
+ m_rsBlockError = errorCodewords;
+}
+CBC_SymbolInfo::CBC_SymbolInfo(FX_BOOL rectangular, FX_INT32 dataCapacity, FX_INT32 errorCodewords, FX_INT32 matrixWidth, FX_INT32 matrixHeight, FX_INT32 dataRegions,
+ FX_INT32 rsBlockData, FX_INT32 rsBlockError)
+{
+ m_rectangular = rectangular;
+ m_dataCapacity = dataCapacity;
+ m_errorCodewords = errorCodewords;
+ m_matrixWidth = matrixWidth;
+ m_matrixHeight = matrixHeight;
+ m_dataRegions = dataRegions;
+ m_rsBlockData = rsBlockData;
+ m_rsBlockError = rsBlockError;
+}
+CBC_SymbolInfo::~CBC_SymbolInfo()
+{
+}
+
+CBC_SymbolInfo* CBC_SymbolInfo::lookup(FX_INT32 dataCodewords, FX_INT32 &e)
+{
+ return lookup(dataCodewords, FORCE_NONE, TRUE, e);
+}
+CBC_SymbolInfo* CBC_SymbolInfo::lookup(FX_INT32 dataCodewords, SymbolShapeHint shape, FX_INT32 &e)
+{
+ return lookup(dataCodewords, shape, TRUE, e);
+}
+CBC_SymbolInfo* CBC_SymbolInfo::lookup(FX_INT32 dataCodewords, FX_BOOL allowRectangular, FX_BOOL fail, FX_INT32 &e)
+{
+ SymbolShapeHint shape = allowRectangular ? FORCE_NONE : FORCE_SQUARE;
+ return lookup(dataCodewords, shape, fail, e);
+}
+CBC_SymbolInfo* CBC_SymbolInfo::lookup(FX_INT32 dataCodewords, SymbolShapeHint shape, FX_BOOL fail, FX_INT32 &e)
+{
+ return lookup(dataCodewords, shape, NULL, NULL, fail, e);
+}
+CBC_SymbolInfo* CBC_SymbolInfo::lookup(FX_INT32 dataCodewords, SymbolShapeHint shape, CBC_Dimension* minSize, CBC_Dimension* maxSize, FX_BOOL fail, FX_INT32 &e)
+{
+ for (FX_INT32 i = 0; i < SYMBOLS_COUNT; i++) {
+ CBC_SymbolInfo* symbol = m_symbols[i];
+ if (shape == FORCE_SQUARE && symbol->m_rectangular) {
+ continue;
+ }
+ if (shape == FORCE_RECTANGLE && !symbol->m_rectangular) {
+ continue;
+ }
+ if (minSize != NULL && (symbol->getSymbolWidth(e) < minSize->getWidth() || symbol->getSymbolHeight(e) < minSize->getHeight())) {
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ continue;
+ }
+ if (maxSize != NULL && (symbol->getSymbolWidth(e) > maxSize->getWidth() || symbol->getSymbolHeight(e) > maxSize->getHeight())) {
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ continue;
+ }
+ if (dataCodewords <= symbol->m_dataCapacity) {
+ return symbol;
+ }
+ }
+ if (fail) {
+ e = BCExceptionIllegalDataCodewords;
+ return NULL;
+ }
+ return NULL;
+}
+FX_INT32 CBC_SymbolInfo::getHorizontalDataRegions(FX_INT32 &e)
+{
+ switch (m_dataRegions) {
+ case 1:
+ return 1;
+ case 2:
+ return 2;
+ case 4:
+ return 2;
+ case 16:
+ return 4;
+ case 36:
+ return 6;
+ default:
+ e = BCExceptionCannotHandleThisNumberOfDataRegions;
+ return 0;
+ }
+}
+FX_INT32 CBC_SymbolInfo::getVerticalDataRegions(FX_INT32 &e)
+{
+ switch (m_dataRegions) {
+ case 1:
+ return 1;
+ case 2:
+ return 1;
+ case 4:
+ return 2;
+ case 16:
+ return 4;
+ case 36:
+ return 6;
+ default:
+ e = BCExceptionCannotHandleThisNumberOfDataRegions;
+ return 0;
+ }
+}
+FX_INT32 CBC_SymbolInfo::getSymbolDataWidth(FX_INT32 &e)
+{
+ return getHorizontalDataRegions(e) * m_matrixWidth;
+}
+FX_INT32 CBC_SymbolInfo::getSymbolDataHeight(FX_INT32 &e)
+{
+ return getVerticalDataRegions(e) * m_matrixHeight;
+}
+FX_INT32 CBC_SymbolInfo::getSymbolWidth(FX_INT32 &e)
+{
+ return getSymbolDataWidth(e) + (getHorizontalDataRegions(e) * 2);
+}
+FX_INT32 CBC_SymbolInfo::getSymbolHeight(FX_INT32 &e)
+{
+ return getSymbolDataHeight(e) + (getVerticalDataRegions(e) * 2);
+}
+FX_INT32 CBC_SymbolInfo::getCodewordCount()
+{
+ return m_dataCapacity + m_errorCodewords;
+}
+FX_INT32 CBC_SymbolInfo::getInterleavedBlockCount()
+{
+ return m_dataCapacity / m_rsBlockData;
+}
+FX_INT32 CBC_SymbolInfo::getDataLengthForInterleavedBlock(FX_INT32 index)
+{
+ return m_rsBlockData;
+}
+FX_INT32 CBC_SymbolInfo::getErrorLengthForInterleavedBlock(FX_INT32 index)
+{
+ return m_rsBlockError;
+}
+CFX_WideString CBC_SymbolInfo::toString(FX_INT32 &e)
+{
+ CFX_WideString sb;
+ sb += (FX_LPWSTR)(m_rectangular ? "Rectangular Symbol:" : "Square Symbol:");
+ sb += (FX_LPWSTR)" data region ";
+ sb += m_matrixWidth;
+ sb += (FX_WCHAR)'x';
+ sb += m_matrixHeight;
+ sb += (FX_LPWSTR)", symbol size ";
+ sb += getSymbolWidth(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_LPWSTR)"");
+ sb += (FX_WCHAR)'x';
+ sb += getSymbolHeight(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_LPWSTR)"");
+ sb += (FX_LPWSTR)", symbol data size ";
+ sb += getSymbolDataWidth(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_LPWSTR)"");
+ sb += (FX_WCHAR)'x';
+ sb += getSymbolDataHeight(e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, (FX_LPWSTR)"");
+ sb += (FX_LPWSTR)", codewords ";
+ sb += m_dataCapacity;
+ sb += (FX_WCHAR)'+';
+ sb += m_errorCodewords;
+ return sb;
+}
diff --git a/xfa/src/fxbarcode/src/BC_SymbolShapeHint.cpp b/xfa/src/fxbarcode/src/BC_SymbolShapeHint.cpp
new file mode 100644
index 0000000000..104acbf519
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_SymbolShapeHint.cpp
@@ -0,0 +1,14 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_SymbolShapeHint.h"
+CBC_SymbolShapeHint::CBC_SymbolShapeHint()
+{
+}
+CBC_SymbolShapeHint::~CBC_SymbolShapeHint()
+{
+}
diff --git a/xfa/src/fxbarcode/src/BC_TextEncoder.cpp b/xfa/src/fxbarcode/src/BC_TextEncoder.cpp
new file mode 100644
index 0000000000..737a84d7ca
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_TextEncoder.cpp
@@ -0,0 +1,86 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_C40Encoder.h"
+#include "include/BC_TextEncoder.h"
+CBC_TextEncoder::CBC_TextEncoder()
+{
+}
+CBC_TextEncoder::~CBC_TextEncoder()
+{
+}
+FX_INT32 CBC_TextEncoder::getEncodingMode()
+{
+ return TEXT_ENCODATION;
+}
+FX_INT32 CBC_TextEncoder::encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e)
+{
+ if (c == ' ') {
+ sb += (FX_WCHAR)'\3';
+ return 1;
+ }
+ if (c >= '0' && c <= '9') {
+ sb += (FX_WCHAR) (c - 48 + 4);
+ return 1;
+ }
+ if (c >= 'a' && c <= 'z') {
+ sb += (FX_WCHAR) (c - 97 + 14);
+ return 1;
+ }
+ if (c >= '\0' && c <= 0x1f) {
+ sb += (FX_WCHAR)'\0';
+ sb += c;
+ return 2;
+ }
+ if (c >= '!' && c <= '/') {
+ sb += (FX_WCHAR) '\1';
+ sb += (FX_WCHAR) (c - 33);
+ return 2;
+ }
+ if (c >= ':' && c <= '@') {
+ sb += (FX_WCHAR)'\1';
+ sb += (FX_WCHAR) (c - 58 + 15);
+ return 2;
+ }
+ if (c >= '[' && c <= '_') {
+ sb += (FX_WCHAR) '\1';
+ sb += (FX_WCHAR) (c - 91 + 22);
+ return 2;
+ }
+ if (c == 0x0060) {
+ sb += (FX_WCHAR) '\2';
+ sb += (FX_WCHAR) (c - 96);
+ return 2;
+ }
+ if (c >= 'A' && c <= 'Z') {
+ sb += (FX_WCHAR)'\2';
+ sb += (FX_WCHAR) (c - 65 + 1);
+ return 2;
+ }
+ if (c >= '{' && c <= 0x007f) {
+ sb += (FX_WCHAR)'\2';
+ sb += (FX_WCHAR) (c - 123 + 27);
+ return 2;
+ }
+ if (c >= 0x0080) {
+ sb += (FX_WCHAR)'\1';
+ sb += (FX_WCHAR)0x001e;
+ FX_INT32 len = 2;
+ len += encodeChar((FX_WCHAR) (c - 128), sb, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ return len;
+ }
+ CBC_HighLevelEncoder::illegalCharacter(c, e);
+ return -1;
+}
diff --git a/xfa/src/fxbarcode/src/BC_TwoDimWriter.cpp b/xfa/src/fxbarcode/src/BC_TwoDimWriter.cpp
new file mode 100644
index 0000000000..b23802b784
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_TwoDimWriter.cpp
@@ -0,0 +1,137 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_TwoDimWriter.h"
+CBC_TwoDimWriter::CBC_TwoDimWriter()
+{
+ m_iCorrectLevel = 1;
+ m_bFixedSize = TRUE;
+ m_output = NULL;
+}
+CBC_TwoDimWriter::~CBC_TwoDimWriter()
+{
+ if (m_output != NULL) {
+ delete m_output;
+ m_output = NULL;
+ }
+}
+void CBC_TwoDimWriter::RenderDeviceResult(CFX_RenderDevice* device, const CFX_Matrix* matrix)
+{
+ CFX_GraphStateData stateData;
+ CFX_PathData path;
+ path.AppendRect(0, 0, (FX_FLOAT)m_Width, (FX_FLOAT)m_Height);
+ device->DrawPath(&path, matrix, &stateData, m_backgroundColor, m_backgroundColor, FXFILL_ALTERNATE);
+ FX_INT32 leftPos = 0;
+ FX_INT32 topPos = 0;
+ if ( m_bFixedSize) {
+ leftPos = (m_Width - m_output->GetWidth()) / 2;
+ topPos = (m_Height - m_output->GetHeight()) / 2;
+ }
+ CFX_Matrix matri = *matrix;
+ if (m_Width < m_output->GetWidth() && m_Height < m_output->GetHeight()) {
+ CFX_Matrix matriScale((FX_FLOAT)m_Width / (FX_FLOAT)m_output->GetWidth(), 0.0, 0.0, (FX_FLOAT)m_Height / (FX_FLOAT)m_output->GetHeight(), 0.0, 0.0);
+ matriScale.Concat(*matrix);
+ matri = matriScale;
+ }
+ for (FX_INT32 x = 0; x < m_output->GetWidth(); x++) {
+ for (FX_INT32 y = 0; y < m_output->GetHeight(); y++) {
+ CFX_PathData rect;
+ rect.AppendRect((FX_FLOAT)leftPos + x, (FX_FLOAT)topPos + y, (FX_FLOAT)(leftPos + x + 1), (FX_FLOAT)(topPos + y + 1));
+ CFX_GraphStateData stateData;
+ if(m_output->Get(x, y)) {
+ device->DrawPath(&rect, &matri, &stateData, m_barColor, 0, FXFILL_WINDING);
+ }
+ }
+ }
+}
+void CBC_TwoDimWriter::RenderBitmapResult(CFX_DIBitmap *&pOutBitmap, FX_INT32& e)
+{
+ if (m_bFixedSize) {
+ pOutBitmap = CreateDIBitmap(m_Width, m_Height);
+ } else {
+ pOutBitmap = CreateDIBitmap(m_output->GetWidth(), m_output->GetHeight());
+ }
+ if (!pOutBitmap) {
+ e = BCExceptionFailToCreateBitmap;
+ return;
+ }
+ pOutBitmap->Clear(m_backgroundColor);
+ FX_INT32 leftPos = 0;
+ FX_INT32 topPos = 0;
+ if ( m_bFixedSize) {
+ leftPos = (m_Width - m_output->GetWidth()) / 2;
+ topPos = (m_Height - m_output->GetHeight()) / 2;
+ }
+ for (FX_INT32 x = 0; x < m_output->GetWidth(); x++) {
+ for (FX_INT32 y = 0; y < m_output->GetHeight(); y++) {
+ if (m_output->Get(x, y)) {
+ pOutBitmap->SetPixel(leftPos + x, topPos + y, m_barColor);
+ }
+ }
+ }
+ if (!m_bFixedSize) {
+ CFX_DIBitmap * pStretchBitmap = pOutBitmap->StretchTo(m_Width, m_Height);
+ if (pOutBitmap) {
+ delete pOutBitmap;
+ }
+ pOutBitmap = pStretchBitmap;
+ }
+}
+void CBC_TwoDimWriter::RenderResult(FX_BYTE *code, FX_INT32 codeWidth, FX_INT32 codeHeight, FX_INT32 &e)
+{
+ FX_INT32 inputWidth = codeWidth;
+ FX_INT32 inputHeight = codeHeight;
+ FX_INT32 tempWidth = inputWidth + (1 << 1);
+ FX_INT32 tempHeight = inputHeight + (1 << 1);
+ FX_FLOAT moduleHSize = (FX_FLOAT)FX_MIN(m_ModuleWidth, m_ModuleHeight);
+ if (moduleHSize > 8) {
+ moduleHSize = 8;
+ } else if (moduleHSize < 1) {
+ moduleHSize = 1;
+ }
+ FX_INT32 outputWidth = (FX_INT32)FX_MAX(tempWidth * moduleHSize, tempWidth);
+ FX_INT32 outputHeight = (FX_INT32)FX_MAX(tempHeight * moduleHSize, tempHeight);
+ FX_INT32 multiX = 1;
+ FX_INT32 multiY = 1;
+ if (m_bFixedSize) {
+ if (m_Width < outputWidth || m_Height < outputHeight) {
+ e = BCExceptionBitmapSizeError;
+ return;
+ }
+ } else {
+ if (m_Width > outputWidth || m_Height > outputHeight) {
+ outputWidth = (FX_INT32)(outputWidth * ceil ( (FX_FLOAT)m_Width / (FX_FLOAT)outputWidth));
+ outputHeight = (FX_INT32)(outputHeight * ceil ( (FX_FLOAT)m_Height / (FX_FLOAT)outputHeight));
+ }
+ }
+ multiX = (FX_INT32)ceil((FX_FLOAT)outputWidth / (FX_FLOAT)tempWidth);
+ multiY = (FX_INT32)ceil((FX_FLOAT)outputHeight / (FX_FLOAT) tempHeight);
+ if (m_bFixedSize) {
+ multiX = FX_MIN(multiX, multiY);
+ multiY = multiX;
+ }
+ FX_INT32 leftPadding = (outputWidth - (inputWidth * multiX)) / 2;
+ FX_INT32 topPadding = (outputHeight - (inputHeight * multiY)) / 2;
+ if (leftPadding < 0) {
+ leftPadding = 0;
+ }
+ if (topPadding < 0) {
+ topPadding = 0;
+ }
+ m_output = FX_NEW CBC_CommonBitMatrix;
+ m_output->Init(outputWidth, outputHeight);
+ for (FX_INT32 inputY = 0, outputY = topPadding; (inputY < inputHeight) && (outputY < outputHeight - multiY); inputY++, outputY += multiY) {
+ for (FX_INT32 inputX = 0, outputX = leftPadding; (inputX < inputWidth) && (outputX < outputWidth - multiX); inputX++, outputX += multiX) {
+ if (code[inputX + inputY * inputWidth] == 1) {
+ m_output->SetRegion(outputX, outputY, multiX, multiY, e);
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+ }
+ }
+}
diff --git a/xfa/src/fxbarcode/src/BC_UtilCodingConvert.cpp b/xfa/src/fxbarcode/src/BC_UtilCodingConvert.cpp
new file mode 100644
index 0000000000..993fc79689
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_UtilCodingConvert.cpp
@@ -0,0 +1,49 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_UtilCodingConvert.h"
+CBC_UtilCodingConvert::CBC_UtilCodingConvert()
+{
+}
+CBC_UtilCodingConvert::~CBC_UtilCodingConvert()
+{
+}
+void CBC_UtilCodingConvert::UnicodeToLocale(const CFX_WideString &src, CFX_ByteString &dst)
+{
+ dst.ConvertFrom(src);
+}
+void CBC_UtilCodingConvert::LocaleToUtf8(const CFX_ByteString &src, CFX_ByteString &dst)
+{
+ CFX_WideString unicode = CFX_WideString::FromLocal(src, src.GetLength());
+ dst = unicode.UTF8Encode();
+}
+void CBC_UtilCodingConvert::LocaleToUtf8(const CFX_ByteString &src, CFX_ByteArray &dst)
+{
+ CFX_WideString unicode = CFX_WideString::FromLocal(src, src.GetLength());
+ CFX_ByteString utf8 = unicode.UTF8Encode();
+ for (FX_INT32 i = 0; i < utf8.GetLength(); i ++) {
+ dst.Add(utf8[i]);
+ }
+}
+void CBC_UtilCodingConvert::Utf8ToLocale(const CFX_ByteArray &src, CFX_ByteString &dst)
+{
+ CFX_ByteString utf8;
+ for (FX_INT32 i = 0; i < src.GetSize(); i ++) {
+ utf8 += src[i];
+ }
+ CFX_WideString unicode = CFX_WideString::FromUTF8(utf8, utf8.GetLength());
+ dst.ConvertFrom(unicode);
+}
+void CBC_UtilCodingConvert::Utf8ToLocale(const FX_BYTE *src, FX_INT32 count, CFX_ByteString &dst)
+{
+ CFX_WideString unicode = CFX_WideString::FromUTF8((const char*)src, count);
+ dst.ConvertFrom(unicode);
+}
+void CBC_UtilCodingConvert::UnicodeToUTF8(const CFX_WideString &src, CFX_ByteString &dst)
+{
+ dst = src.UTF8Encode();
+}
diff --git a/xfa/src/fxbarcode/src/BC_UtilRSS.cpp b/xfa/src/fxbarcode/src/BC_UtilRSS.cpp
new file mode 100644
index 0000000000..539068ace7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_UtilRSS.cpp
@@ -0,0 +1,148 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_UtilRSS.h"
+CBC_UtilRSS::CBC_UtilRSS()
+{
+}
+CBC_UtilRSS::~CBC_UtilRSS()
+{
+}
+CFX_Int32Array *CBC_UtilRSS::GetRssWidths(FX_INT32 val, FX_INT32 n, FX_INT32 elements, FX_INT32 maxWidth, FX_BOOL noNarrow)
+{
+ CFX_Int32Array *iTemp = FX_NEW CFX_Int32Array;
+ iTemp->SetSize(elements);
+ CBC_AutoPtr<CFX_Int32Array > widths(iTemp);
+ FX_INT32 bar;
+ FX_INT32 narrowMask = 0;
+ for (bar = 0; bar < elements - 1; bar++) {
+ narrowMask |= (1 << bar);
+ FX_INT32 elmWidth = 1;
+ FX_INT32 subVal;
+ while (TRUE) {
+ subVal = Combins(n - elmWidth - 1, elements - bar - 2);
+ if (noNarrow && (narrowMask == 0) &&
+ (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
+ subVal -= Combins(n - elmWidth - (elements - bar), elements - bar - 2);
+ }
+ if (elements - bar - 1 > 1) {
+ FX_INT32 lessVal = 0;
+ for (FX_INT32 mxwElement = n - elmWidth - (elements - bar - 2);
+ mxwElement > maxWidth;
+ mxwElement--) {
+ lessVal += Combins(n - elmWidth - mxwElement - 1, elements - bar - 3);
+ }
+ subVal -= lessVal * (elements - 1 - bar);
+ } else if (n - elmWidth > maxWidth) {
+ subVal--;
+ }
+ val -= subVal;
+ if (val < 0) {
+ break;
+ }
+ elmWidth++;
+ narrowMask &= ~(1 << bar);
+ }
+ val += subVal;
+ n -= elmWidth;
+ (*widths)[bar] = elmWidth;
+ }
+ (*widths)[bar] = n;
+ return widths.release();
+}
+FX_INT32 CBC_UtilRSS::GetRSSvalue(CFX_Int32Array &widths, FX_INT32 maxWidth, FX_BOOL noNarrow)
+{
+ FX_INT32 elements = widths.GetSize();
+ FX_INT32 n = 0;
+ for (FX_INT32 i = 0; i < elements; i++) {
+ n += widths[i];
+ }
+ FX_INT32 val = 0;
+ FX_INT32 narrowMask = 0;
+ for (FX_INT32 bar = 0; bar < elements - 1; bar++) {
+ FX_INT32 elmWidth;
+ for (elmWidth = 1, narrowMask |= (1 << bar);
+ elmWidth < widths[bar];
+ elmWidth++, narrowMask &= ~(1 << bar)) {
+ FX_INT32 subVal = Combins(n - elmWidth - 1, elements - bar - 2);
+ if (noNarrow && (narrowMask == 0) &&
+ (n - elmWidth - (elements - bar - 1) >= elements - bar - 1)) {
+ subVal -= Combins(n - elmWidth - (elements - bar),
+ elements - bar - 2);
+ }
+ if (elements - bar - 1 > 1) {
+ FX_INT32 lessVal = 0;
+ for (FX_INT32 mxwElement = n - elmWidth - (elements - bar - 2);
+ mxwElement > maxWidth; mxwElement--) {
+ lessVal += Combins(n - elmWidth - mxwElement - 1,
+ elements - bar - 3);
+ }
+ subVal -= lessVal * (elements - 1 - bar);
+ } else if (n - elmWidth > maxWidth) {
+ subVal--;
+ }
+ val += subVal;
+ }
+ n -= elmWidth;
+ }
+ return val;
+}
+FX_INT32 CBC_UtilRSS::Combins(FX_INT32 n, FX_INT32 r)
+{
+ FX_INT32 maxDenom;
+ FX_INT32 minDenom;
+ if (n - r > r) {
+ minDenom = r;
+ maxDenom = n - r;
+ } else {
+ minDenom = n - r;
+ maxDenom = r;
+ }
+ FX_INT32 val = 1;
+ FX_INT32 j = 1;
+ for (FX_INT32 i = n; i > maxDenom; i--) {
+ val *= i;
+ if (j <= minDenom) {
+ val /= j;
+ j++;
+ }
+ }
+ while (j <= minDenom) {
+ val /= j;
+ j++;
+ }
+ return val;
+}
+CFX_Int32Array *CBC_UtilRSS::Elements(CFX_Int32Array &eDist, FX_INT32 N, FX_INT32 K)
+{
+ CFX_Int32Array *widths = FX_NEW CFX_Int32Array;
+ widths->SetSize(eDist.GetSize() + 2);
+ FX_INT32 twoK = K << 1;
+ (*widths)[0] = 1;
+ FX_INT32 i;
+ FX_INT32 minEven = 10;
+ FX_INT32 barSum = 1;
+ for (i = 1; i < twoK - 2; i += 2) {
+ (*widths)[i] = eDist[i - 1] - (*widths)[i - 1];
+ (*widths)[i + 1] = eDist[i] - (*widths)[i];
+ barSum += (*widths)[i] + (*widths)[i + 1];
+ if ((*widths)[i] < minEven) {
+ minEven = (*widths)[i];
+ }
+ }
+ (*widths)[twoK - 1] = N - barSum;
+ if ((*widths)[twoK - 1] < minEven) {
+ minEven = (*widths)[twoK - 1];
+ }
+ if (minEven > 1) {
+ for (i = 0; i < twoK; i += 2) {
+ (*widths)[i] += minEven - 1;
+ (*widths)[i + 1] -= minEven - 1;
+ }
+ }
+ return widths;
+}
diff --git a/xfa/src/fxbarcode/src/BC_Utils.cpp b/xfa/src/fxbarcode/src/BC_Utils.cpp
new file mode 100644
index 0000000000..3a04ebda2b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Utils.cpp
@@ -0,0 +1,46 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+FX_BOOL BC_FX_ByteString_Replace(CFX_ByteString &dst, FX_DWORD first, FX_DWORD last, FX_INT32 count, FX_CHAR c)
+{
+ if (first > last || count <= 0) {
+ return FALSE;
+ }
+ dst.Delete(first, last - first);
+ for (FX_INT32 i = 0; i < count; i ++) {
+ dst.Insert(0, c);
+ }
+ return TRUE;
+}
+void BC_FX_ByteString_Append(CFX_ByteString &dst, FX_INT32 count, FX_CHAR c)
+{
+ for (FX_INT32 i = 0; i < count; i ++) {
+ dst += c;
+ }
+}
+void BC_FX_ByteString_Append(CFX_ByteString &dst, const CFX_ByteArray &ba)
+{
+ for (FX_INT32 i = 0; i < ba.GetSize(); i ++) {
+ dst += ba[i];
+ }
+}
+void BC_FX_PtrArray_Sort(CFX_PtrArray &src, BC_PtrArrayCompareCallback fun)
+{
+ FX_INT32 nLength = src.GetSize();
+ FX_BOOL changed = true;
+ do {
+ changed = false;
+ for (FX_INT32 i = 0; i < nLength - 1; i++) {
+ if ( fun(src[i + 1], src[i]) ) {
+ void *temp = src[i];
+ src.SetAt(i, src[i + 1]);
+ src.SetAt(i + 1, temp);
+ changed = true;
+ }
+ }
+ } while (changed);
+}
diff --git a/xfa/src/fxbarcode/src/BC_WhiteRectangleDetector.cpp b/xfa/src/fxbarcode/src/BC_WhiteRectangleDetector.cpp
new file mode 100644
index 0000000000..8ed6f98232
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_WhiteRectangleDetector.cpp
@@ -0,0 +1,228 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_WhiteRectangleDetector.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_ResultPoint.h"
+const FX_INT32 CBC_WhiteRectangleDetector::INIT_SIZE = 30;
+const FX_INT32 CBC_WhiteRectangleDetector::CORR = 1;
+CBC_WhiteRectangleDetector::CBC_WhiteRectangleDetector(CBC_CommonBitMatrix *image)
+{
+ m_image = image;
+ m_height = image->GetHeight();
+ m_width = image->GetWidth();
+ m_leftInit = (m_width - INIT_SIZE) >> 1;
+ m_rightInit = (m_width + INIT_SIZE) >> 1;
+ m_upInit = (m_height - INIT_SIZE) >> 1;
+ m_downInit = (m_height + INIT_SIZE) >> 1;
+}
+void CBC_WhiteRectangleDetector::Init(FX_INT32 &e)
+{
+ if (m_upInit < 0 || m_leftInit < 0 || m_downInit >= m_height || m_rightInit >= m_width) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnVoid(e);
+ }
+}
+CBC_WhiteRectangleDetector::CBC_WhiteRectangleDetector(CBC_CommonBitMatrix *image, FX_INT32 initSize, FX_INT32 x, FX_INT32 y)
+{
+ m_image = image;
+ m_height = image->GetHeight();
+ m_width = image->GetWidth();
+ FX_INT32 halfsize = initSize >> 1;
+ m_leftInit = x - halfsize;
+ m_rightInit = x + halfsize;
+ m_upInit = y - halfsize;
+ m_downInit = y + halfsize;
+}
+CBC_WhiteRectangleDetector::~CBC_WhiteRectangleDetector()
+{
+}
+CFX_PtrArray *CBC_WhiteRectangleDetector::Detect(FX_INT32 &e)
+{
+ FX_INT32 left = m_leftInit;
+ FX_INT32 right = m_rightInit;
+ FX_INT32 up = m_upInit;
+ FX_INT32 down = m_downInit;
+ FX_BOOL sizeExceeded = FALSE;
+ FX_BOOL aBlackPointFoundOnBorder = TRUE;
+ FX_BOOL atLeastOneBlackPointFoundOnBorder = FALSE;
+ while (aBlackPointFoundOnBorder) {
+ aBlackPointFoundOnBorder = FALSE;
+ FX_BOOL rightBorderNotWhite = TRUE;
+ while (rightBorderNotWhite && right < m_width) {
+ rightBorderNotWhite = ContainsBlackPoint(up, down, right, FALSE);
+ if (rightBorderNotWhite) {
+ right++;
+ aBlackPointFoundOnBorder = TRUE;
+ }
+ }
+ if (right >= m_width) {
+ sizeExceeded = TRUE;
+ break;
+ }
+ FX_BOOL bottomBorderNotWhite = TRUE;
+ while (bottomBorderNotWhite && down < m_height) {
+ bottomBorderNotWhite = ContainsBlackPoint(left, right, down, TRUE);
+ if (bottomBorderNotWhite) {
+ down++;
+ aBlackPointFoundOnBorder = TRUE;
+ }
+ }
+ if (down >= m_height) {
+ sizeExceeded = TRUE;
+ break;
+ }
+ FX_BOOL leftBorderNotWhite = TRUE;
+ while (leftBorderNotWhite && left >= 0) {
+ leftBorderNotWhite = ContainsBlackPoint(up, down, left, FALSE);
+ if (leftBorderNotWhite) {
+ left--;
+ aBlackPointFoundOnBorder = TRUE;
+ }
+ }
+ if (left < 0) {
+ sizeExceeded = TRUE;
+ break;
+ }
+ FX_BOOL topBorderNotWhite = TRUE;
+ while (topBorderNotWhite && up >= 0) {
+ topBorderNotWhite = ContainsBlackPoint(left, right, up, TRUE);
+ if (topBorderNotWhite) {
+ up--;
+ aBlackPointFoundOnBorder = TRUE;
+ }
+ }
+ if (up < 0) {
+ sizeExceeded = TRUE;
+ break;
+ }
+ if (aBlackPointFoundOnBorder) {
+ atLeastOneBlackPointFoundOnBorder = TRUE;
+ }
+ }
+ if (!sizeExceeded && atLeastOneBlackPointFoundOnBorder) {
+ FX_INT32 maxSize = right - left;
+ CBC_AutoPtr<CBC_ResultPoint> z(NULL);
+ for (FX_INT32 i = 1; i < maxSize; i++) {
+ z = CBC_AutoPtr<CBC_ResultPoint>(GetBlackPointOnSegment((FX_FLOAT)left, (FX_FLOAT)(down - i), (FX_FLOAT)(left + i), (FX_FLOAT)(down)) );
+ if (z.get() != NULL) {
+ break;
+ }
+ }
+ if (z.get() == NULL) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_AutoPtr<CBC_ResultPoint> t(NULL);
+ for (FX_INT32 j = 1; j < maxSize; j++) {
+ t = CBC_AutoPtr<CBC_ResultPoint>(GetBlackPointOnSegment((FX_FLOAT)left, (FX_FLOAT)(up + j), (FX_FLOAT)(left + j), (FX_FLOAT)up));
+ if (t.get() != NULL) {
+ break;
+ }
+ }
+ if (t.get() == NULL) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_AutoPtr<CBC_ResultPoint> x(NULL);
+ for (FX_INT32 k = 1; k < maxSize; k++) {
+ x = CBC_AutoPtr<CBC_ResultPoint>(GetBlackPointOnSegment((FX_FLOAT)right, (FX_FLOAT)(up + k), (FX_FLOAT)(right - k), (FX_FLOAT)up));
+ if (x.get() != NULL) {
+ break;
+ }
+ }
+ if (x.get() == NULL) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ CBC_AutoPtr<CBC_ResultPoint> y(NULL);
+ for (FX_INT32 m = 1; m < maxSize; m++) {
+ y = CBC_AutoPtr<CBC_ResultPoint>(GetBlackPointOnSegment((FX_FLOAT)right, (FX_FLOAT)(down - m), (FX_FLOAT)(right - m), (FX_FLOAT) down));
+ if (y.get() != NULL) {
+ break;
+ }
+ }
+ if (y.get() == NULL) {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return CenterEdges(y.get(), z.get(), x.get(), t.get());
+ } else {
+ e = BCExceptionNotFound;
+ BC_EXCEPTION_CHECK_ReturnValue(e, NULL);
+ }
+ return NULL;
+}
+FX_INT32 CBC_WhiteRectangleDetector::Round(FX_FLOAT d)
+{
+ return (FX_INT32) (d + 0.5f);
+}
+CBC_ResultPoint *CBC_WhiteRectangleDetector::GetBlackPointOnSegment(FX_FLOAT aX, FX_FLOAT aY, FX_FLOAT bX, FX_FLOAT bY)
+{
+ FX_INT32 dist = DistanceL2(aX, aY, bX, bY);
+ float xStep = (bX - aX) / dist;
+ float yStep = (bY - aY) / dist;
+ for (FX_INT32 i = 0; i < dist; i++) {
+ FX_INT32 x = Round(aX + i * xStep);
+ FX_INT32 y = Round(aY + i * yStep);
+ if (m_image->Get(x, y)) {
+ return FX_NEW CBC_ResultPoint((FX_FLOAT)x, (FX_FLOAT) y);
+ }
+ }
+ return NULL;
+}
+FX_INT32 CBC_WhiteRectangleDetector::DistanceL2(FX_FLOAT aX, FX_FLOAT aY, FX_FLOAT bX, FX_FLOAT bY)
+{
+ float xDiff = aX - bX;
+ float yDiff = aY - bY;
+ return Round((float)sqrt(xDiff * xDiff + yDiff * yDiff));
+}
+CFX_PtrArray *CBC_WhiteRectangleDetector::CenterEdges(CBC_ResultPoint *y, CBC_ResultPoint *z, CBC_ResultPoint *x, CBC_ResultPoint *t)
+{
+ float yi = y->GetX();
+ float yj = y->GetY();
+ float zi = z->GetX();
+ float zj = z->GetY();
+ float xi = x->GetX();
+ float xj = x->GetY();
+ float ti = t->GetX();
+ float tj = t->GetY();
+ if (yi < m_width / 2) {
+ CFX_PtrArray *result = FX_NEW CFX_PtrArray;
+ result->SetSize(4);
+ (*result)[0] = FX_NEW CBC_ResultPoint(ti - CORR, tj + CORR);
+ (*result)[1] = FX_NEW CBC_ResultPoint(zi + CORR, zj + CORR);
+ (*result)[2] = FX_NEW CBC_ResultPoint(xi - CORR, xj - CORR);
+ (*result)[3] = FX_NEW CBC_ResultPoint(yi + CORR, yj - CORR);
+ return result;
+ } else {
+ CFX_PtrArray *result = FX_NEW CFX_PtrArray;
+ result->SetSize(4);
+ (*result)[0] = FX_NEW CBC_ResultPoint(ti + CORR, tj + CORR);
+ (*result)[1] = FX_NEW CBC_ResultPoint(zi + CORR, zj - CORR);
+ (*result)[2] = FX_NEW CBC_ResultPoint(xi - CORR, xj + CORR);
+ (*result)[3] = FX_NEW CBC_ResultPoint(yi - CORR, yj - CORR);
+ return result;
+ }
+}
+FX_BOOL CBC_WhiteRectangleDetector::ContainsBlackPoint(FX_INT32 a, FX_INT32 b, FX_INT32 fixed, FX_BOOL horizontal)
+{
+ if (horizontal) {
+ for (FX_INT32 x = a; x <= b; x++) {
+ if (m_image->Get(x, fixed)) {
+ return TRUE;
+ }
+ }
+ } else {
+ for (FX_INT32 y = a; y <= b; y++) {
+ if (m_image->Get(fixed, y)) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
diff --git a/xfa/src/fxbarcode/src/BC_Writer.cpp b/xfa/src/fxbarcode/src/BC_Writer.cpp
new file mode 100644
index 0000000000..c372c97097
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_Writer.cpp
@@ -0,0 +1,70 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Writer.h"
+CBC_Writer::CBC_Writer()
+{
+ m_CharEncoding = 0;
+ m_ModuleHeight = 1;
+ m_ModuleWidth = 1;
+ m_Height = 320;
+ m_Width = 640;
+ m_colorSpace = FXDIB_Argb;
+ m_barColor = 0xff000000;
+ m_backgroundColor = 0xffffffff;
+}
+CBC_Writer::~CBC_Writer()
+{
+}
+FX_BOOL CBC_Writer::SetCharEncoding(FX_INT32 encoding)
+{
+ m_CharEncoding = encoding;
+ return TRUE;
+}
+FX_BOOL CBC_Writer::SetModuleHeight(FX_INT32 moduleHeight)
+{
+ if (moduleHeight > 10 || moduleHeight < 1) {
+ return FALSE;
+ }
+ m_ModuleHeight = moduleHeight;
+ return TRUE;
+}
+FX_BOOL CBC_Writer::SetModuleWidth(FX_INT32 moduleWidth)
+{
+ if ( moduleWidth > 10 || moduleWidth < 1) {
+ return FALSE;
+ }
+ m_ModuleWidth = moduleWidth;
+ return TRUE;
+}
+FX_BOOL CBC_Writer::SetHeight(FX_INT32 height)
+{
+ m_Height = height;
+ return TRUE;
+}
+FX_BOOL CBC_Writer::SetWidth(FX_INT32 width)
+{
+ m_Width = width;
+ return TRUE;
+}
+void CBC_Writer::SetBackgroundColor(FX_ARGB backgroundColor)
+{
+ m_backgroundColor = backgroundColor;
+}
+void CBC_Writer::SetBarcodeColor(FX_ARGB foregroundColor)
+{
+ m_barColor = foregroundColor;
+}
+CFX_DIBitmap* CBC_Writer::CreateDIBitmap(FX_INT32 width, FX_INT32 height)
+{
+ CFX_DIBitmap *pDIBitmap = NULL;
+ pDIBitmap = FX_NEW CFX_DIBitmap;
+ if(pDIBitmap != NULL) {
+ pDIBitmap->Create(width, height, m_colorSpace);
+ }
+ return pDIBitmap;
+}
diff --git a/xfa/src/fxbarcode/src/BC_X12Encoder.cpp b/xfa/src/fxbarcode/src/BC_X12Encoder.cpp
new file mode 100644
index 0000000000..45e87c3ebf
--- /dev/null
+++ b/xfa/src/fxbarcode/src/BC_X12Encoder.cpp
@@ -0,0 +1,88 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "barcode.h"
+#include "include/BC_Encoder.h"
+#include "include/BC_CommonBitMatrix.h"
+#include "include/BC_Dimension.h"
+#include "include/BC_SymbolShapeHint.h"
+#include "include/BC_SymbolInfo.h"
+#include "include/BC_EncoderContext.h"
+#include "include/BC_HighLevelEncoder.h"
+#include "include/BC_C40Encoder.h"
+#include "include/BC_X12Encoder.h"
+CBC_X12Encoder::CBC_X12Encoder()
+{
+}
+CBC_X12Encoder::~CBC_X12Encoder()
+{
+}
+FX_INT32 CBC_X12Encoder::getEncodingMode()
+{
+ return X12_ENCODATION;
+}
+void CBC_X12Encoder::Encode(CBC_EncoderContext &context, FX_INT32 &e)
+{
+ CFX_WideString buffer;
+ while (context.hasMoreCharacters()) {
+ FX_WCHAR c = context.getCurrentChar();
+ context.m_pos++;
+ encodeChar(c, buffer, e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_INT32 count = buffer.GetLength();
+ if ((count % 3) == 0) {
+ writeNextTriplet(context, buffer);
+ FX_INT32 newMode = CBC_HighLevelEncoder::lookAheadTest(context.m_msg, context.m_pos, getEncodingMode());
+ if (newMode != getEncodingMode()) {
+ context.signalEncoderChange(newMode);
+ break;
+ }
+ }
+ }
+ handleEOD(context, buffer, e);
+}
+void CBC_X12Encoder::handleEOD(CBC_EncoderContext &context, CFX_WideString &buffer, FX_INT32 &e)
+{
+ context.updateSymbolInfo(e);
+ if (e != BCExceptionNO) {
+ return;
+ }
+ FX_INT32 available = context.m_symbolInfo->m_dataCapacity - context.getCodewordCount();
+ FX_INT32 count = buffer.GetLength();
+ if (count == 2) {
+ context.writeCodeword(CBC_HighLevelEncoder::X12_UNLATCH);
+ context.m_pos -= 2;
+ context.signalEncoderChange(ASCII_ENCODATION);
+ } else if (count == 1) {
+ context.m_pos--;
+ if (available > 1) {
+ context.writeCodeword(CBC_HighLevelEncoder::X12_UNLATCH);
+ }
+ context.signalEncoderChange(ASCII_ENCODATION);
+ }
+}
+FX_INT32 CBC_X12Encoder::encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e)
+{
+ if (c == '\r') {
+ sb += (FX_WCHAR)'\0';
+ } else if (c == '*') {
+ sb += (FX_WCHAR)'\1';
+ } else if (c == '>') {
+ sb += (FX_WCHAR)'\2';
+ } else if (c == ' ') {
+ sb += (FX_WCHAR)'\3';
+ } else if (c >= '0' && c <= '9') {
+ sb += (FX_WCHAR) (c - 48 + 4);
+ } else if (c >= 'A' && c <= 'Z') {
+ sb += (FX_WCHAR) (c - 65 + 14);
+ } else {
+ CBC_HighLevelEncoder::illegalCharacter(c, e);
+ BC_EXCEPTION_CHECK_ReturnValue(e, -1);
+ }
+ return 1;
+}
diff --git a/xfa/src/fxbarcode/src/barcode.h b/xfa/src/fxbarcode/src/barcode.h
new file mode 100644
index 0000000000..e2ad2126a0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/barcode.h
@@ -0,0 +1,8 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../foxitlib.h"
+#include "include/utils.h"
diff --git a/xfa/src/fxbarcode/src/include/BC_ASCIIEncoder.h b/xfa/src/fxbarcode/src/include/BC_ASCIIEncoder.h
new file mode 100644
index 0000000000..9a48b8762f
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_ASCIIEncoder.h
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ASCIIENCODER_H_
+#define _BC_ASCIIENCODER_H_
+class CBC_Encoder;
+class CBC_EncoderContext;
+class CBC_ASCIIEncoder;
+class CBC_ASCIIEncoder : public CBC_Encoder
+{
+public:
+ CBC_ASCIIEncoder();
+ virtual ~CBC_ASCIIEncoder();
+ FX_INT32 getEncodingMode();
+ void Encode(CBC_EncoderContext &context, FX_INT32 &e);
+private:
+ static FX_WCHAR encodeASCIIDigits(FX_WCHAR digit1, FX_WCHAR digit2, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_Base256Encoder.h b/xfa/src/fxbarcode/src/include/BC_Base256Encoder.h
new file mode 100644
index 0000000000..96110b1d08
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_Base256Encoder.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BASE256ENCODER_H_
+#define _BC_BASE256ENCODER_H_
+class CBC_Encoder;
+class CBC_Base256Encoder;
+class CBC_Base256Encoder : public CBC_Encoder
+{
+public:
+ CBC_Base256Encoder();
+ virtual ~CBC_Base256Encoder();
+ FX_INT32 getEncodingMode();
+ void Encode(CBC_EncoderContext &context, FX_INT32 &e);
+private:
+ static FX_WCHAR randomize255State(FX_WCHAR ch, FX_INT32 codewordPosition);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_Binarizer.h b/xfa/src/fxbarcode/src/include/BC_Binarizer.h
new file mode 100644
index 0000000000..357aef67c2
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_Binarizer.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BINARIZER_H_
+#define _BC_BINARIZER_H_
+class CBC_LuminanceSource;
+class CBC_CommonBitMatrix;
+class CBC_CommonBitArray;
+class CBC_BinaryBitmap;
+class CBC_Binarizer : public CFX_Object
+{
+public:
+ CBC_Binarizer(CBC_LuminanceSource *source);
+ virtual ~CBC_Binarizer();
+ CBC_LuminanceSource *GetLuminanceSource();
+ virtual CBC_CommonBitMatrix *GetBlackMatrix(FX_INT32 &e) = 0;
+ virtual CBC_CommonBitArray *GetBlackRow(FX_INT32 y, CBC_CommonBitArray *row, FX_INT32 &e) = 0;
+private:
+ CBC_LuminanceSource *m_source;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_BinaryBitmap.h b/xfa/src/fxbarcode/src/include/BC_BinaryBitmap.h
new file mode 100644
index 0000000000..638d16f5a9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_BinaryBitmap.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BINARYBITMAP_H_
+#define _BC_BINARYBITMAP_H_
+class CBC_Binarizer;
+class CBC_CommonBitMatrix;
+class CBC_CommonBitArray;
+class CBC_BinaryBitmap;
+class CBC_BinaryBitmap : public CFX_Object
+{
+public:
+ CBC_BinaryBitmap(CBC_Binarizer *binarizer);
+ virtual ~CBC_BinaryBitmap();
+ FX_INT32 GetWidth();
+ FX_INT32 GetHeight();
+ CBC_CommonBitMatrix * GetMatrix(FX_INT32 &e);
+ CBC_CommonBitArray * GetBlackRow(FX_INT32 y, CBC_CommonBitArray *row, FX_INT32 &e);
+ CBC_CommonBitMatrix * GetBlackMatrix(FX_INT32 &e);
+ FX_BOOL IsCropSupported();
+ FX_BOOL IsRotateSupported();
+private:
+ CBC_Binarizer * m_binarizer;
+ CBC_CommonBitMatrix * m_matrix;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_BufferedImageLuminanceSource.h b/xfa/src/fxbarcode/src/include/BC_BufferedImageLuminanceSource.h
new file mode 100644
index 0000000000..4bff1756d5
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_BufferedImageLuminanceSource.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BUFFEREDIMAGELUMINANCESOURCE_H_
+#define _BC_BUFFEREDIMAGELUMINANCESOURCE_H_
+class CBC_LuminanceSource;
+class CBC_BufferedImageLuminanceSource;
+class CBC_BufferedImageLuminanceSource : public CBC_LuminanceSource
+{
+public:
+ CBC_BufferedImageLuminanceSource(const CFX_WideString &filename);
+ CBC_BufferedImageLuminanceSource(CFX_DIBitmap *pBitmap);
+ virtual ~CBC_BufferedImageLuminanceSource();
+ CBC_LuminanceSource *RotateCounterClockwise(FX_INT32 &e);
+ CBC_LuminanceSource *Crop(FX_INT32 left, FX_INT32 top, FX_INT32 width, FX_INT32 height);
+
+ CFX_ByteArray *GetRow(FX_INT32 y, CFX_ByteArray &row, FX_INT32 &e);
+ CFX_ByteArray *GetMatrix();
+ FX_BOOL IsCropSupported();
+ FX_BOOL IsRotateSupported();
+ virtual void Init(FX_INT32 &e);
+private:
+ FX_INT32 m_bytesPerLine;
+ FX_INT32 m_left;
+ FX_INT32 m_top;
+ CFX_Int32Array m_rgbData;
+ CFX_DIBitmap *m_pBitmap;
+ const CFX_WideString m_filename;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_C40Encoder.h b/xfa/src/fxbarcode/src/include/BC_C40Encoder.h
new file mode 100644
index 0000000000..7f2d2f7e79
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_C40Encoder.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_C40ENCODER_H_
+#define _BC_C40ENCODER_H_
+class CBC_C40Encoder;
+class CBC_C40Encoder : public CBC_Encoder
+{
+public:
+ CBC_C40Encoder();
+ virtual ~CBC_C40Encoder();
+ virtual FX_INT32 getEncodingMode();
+ virtual void Encode(CBC_EncoderContext &context, FX_INT32 &e);
+ static void writeNextTriplet(CBC_EncoderContext &context, CFX_WideString &buffer);
+ virtual void handleEOD(CBC_EncoderContext &context, CFX_WideString &buffer, FX_INT32 &e);
+ virtual FX_INT32 encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e);
+private:
+ FX_INT32 backtrackOneCharacter(CBC_EncoderContext &context, CFX_WideString &buffer, CFX_WideString &removed, FX_INT32 lastCharSize, FX_INT32 &e);
+ static CFX_WideString encodeToCodewords(CFX_WideString sb, FX_INT32 startPos);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonBitArray.h b/xfa/src/fxbarcode/src/include/BC_CommonBitArray.h
new file mode 100644
index 0000000000..484d87d5a7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonBitArray.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONBITARRAY_H_
+#define _BC_COMMONBITARRAY_H_
+class CBC_CommonBitArray;
+class CBC_CommonBitArray : public CFX_Object
+{
+public:
+ CBC_CommonBitArray(CBC_CommonBitArray* array);
+ CBC_CommonBitArray(FX_INT32 size);
+ CBC_CommonBitArray();
+ virtual ~CBC_CommonBitArray();
+ FX_INT32 GetSize();
+ CFX_Int32Array& GetBits();
+ FX_INT32 GetSizeInBytes();
+ FX_BOOL Get(FX_INT32 i);
+ void Set(FX_INT32 i);
+ void Flip(FX_INT32 i);
+ void SetBulk(FX_INT32 i, FX_INT32 newBits);
+ FX_BOOL IsRange(FX_INT32 start, FX_INT32 end, FX_BOOL value, FX_INT32 &e);
+ FX_INT32 *GetBitArray();
+ void Reverse();
+ void Clear();
+private:
+ FX_INT32 m_size;
+ CFX_Int32Array m_bits;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonBitMatrix.h b/xfa/src/fxbarcode/src/include/BC_CommonBitMatrix.h
new file mode 100644
index 0000000000..f69d7a0e33
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonBitMatrix.h
@@ -0,0 +1,38 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONBITMATRIX_H_
+#define _BC_COMMONBITMATRIX_H_
+class CBC_CommonBitArray;
+class CBC_CommonBitMatrix;
+class CBC_CommonBitMatrix : public CFX_Object
+{
+public:
+ CBC_CommonBitMatrix();
+ virtual ~CBC_CommonBitMatrix();
+ FX_BOOL Get(FX_INT32 x, FX_INT32 y);
+ void Set(FX_INT32 x, FX_INT32 y);
+ void Flip(FX_INT32 x, FX_INT32 y);
+ void Clear();
+ void SetRegion(FX_INT32 left, FX_INT32 top, FX_INT32 width, FX_INT32 height, FX_INT32 &e);
+ CBC_CommonBitArray* GetRow(FX_INT32 y, CBC_CommonBitArray* row);
+ void SetRow(FX_INT32 y, CBC_CommonBitArray* row);
+ CBC_CommonBitArray* GetCol(FX_INT32 y, CBC_CommonBitArray* row);
+ void SetCol(FX_INT32 y, CBC_CommonBitArray* col);
+ FX_INT32 GetWidth();
+ FX_INT32 GetHeight();
+ FX_INT32 GetRowSize();
+ FX_INT32 GetDimension(FX_INT32 &e);
+ virtual void Init(FX_INT32 dimension);
+ virtual void Init(FX_INT32 width, FX_INT32 height);
+ FX_INT32* GetBits();
+private:
+ FX_INT32 m_width;
+ FX_INT32 m_height;
+ FX_INT32 m_rowSize;
+ FX_INT32* m_bits;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonBitSource.h b/xfa/src/fxbarcode/src/include/BC_CommonBitSource.h
new file mode 100644
index 0000000000..53891cf671
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonBitSource.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONBITSOURCE_H_
+#define _BC_COMMONBITSOURCE_H_
+class CBC_CommonBitSource;
+class CBC_CommonBitSource : public CFX_Object
+{
+public:
+ CBC_CommonBitSource(CFX_ByteArray *bytes);
+ virtual ~CBC_CommonBitSource();
+ FX_INT32 ReadBits(FX_INT32 numBits, FX_INT32 &e);
+ FX_INT32 Available();
+ FX_INT32 getByteOffset();
+private:
+ CFX_ByteArray m_bytes;
+ FX_INT32 m_byteOffset;
+ FX_INT32 m_bitOffset;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonByteArray.h b/xfa/src/fxbarcode/src/include/BC_CommonByteArray.h
new file mode 100644
index 0000000000..fe0a67ffd1
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonByteArray.h
@@ -0,0 +1,30 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONBYTEARRAY_H_
+#define _BC_COMMONBYTEARRAY_H_
+class CBC_CommonByteArray;
+class CBC_CommonByteArray : public CFX_Object
+{
+private:
+ FX_INT32 m_size;
+ FX_INT32 m_index;
+ FX_BYTE* m_bytes;
+public:
+ CBC_CommonByteArray();
+ CBC_CommonByteArray(FX_INT32 size);
+ CBC_CommonByteArray(FX_BYTE* byteArray, FX_INT32 size);
+ virtual ~CBC_CommonByteArray();
+ FX_INT32 At(FX_INT32 index);
+ void Set(FX_INT32 index, FX_INT32 value);
+ FX_INT32 Size();
+ FX_BOOL IsEmpty();
+ void AppendByte(FX_INT32 value);
+ void Reserve(FX_INT32 capacity);
+ void Set(FX_BYTE* source, FX_INT32 offset, FX_INT32 count);
+ void Set(CFX_ByteArray* source, FX_INT32 offset, FX_INT32 count);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonByteMatrix.h b/xfa/src/fxbarcode/src/include/BC_CommonByteMatrix.h
new file mode 100644
index 0000000000..3d831d1911
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonByteMatrix.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONBYTEMATRIX_H_
+#define _BC_COMMONBYTEMATRIX_H_
+class CBC_CommonByteMatrix;
+class CBC_CommonByteMatrix : public CFX_Object
+{
+public:
+ CBC_CommonByteMatrix(FX_INT32 width, FX_INT32 height);
+ virtual ~CBC_CommonByteMatrix();
+ FX_INT32 GetHeight();
+ FX_INT32 GetWidth();
+ FX_BYTE Get(FX_INT32 x, FX_INT32 y);
+ FX_BYTE* GetArray();
+
+ void Set(FX_INT32 x, FX_INT32 y, FX_INT32 value);
+ void Set(FX_INT32 x, FX_INT32 y, FX_BYTE value);
+ void clear(FX_BYTE value);
+ virtual void Init();
+private:
+ FX_BYTE *m_bytes;
+ FX_INT32 m_width;
+ FX_INT32 m_height;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonCharacterSetECI.h b/xfa/src/fxbarcode/src/include/BC_CommonCharacterSetECI.h
new file mode 100644
index 0000000000..1e9f9a433f
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonCharacterSetECI.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONCHARACTERSETECI_H_
+#define _BC_COMMONCHARACTERSETECI_H_
+class CBC_CommonECI;
+class CBC_CommonCharacterSetECI;
+class CBC_CommonCharacterSetECI : public CBC_CommonECI
+{
+public:
+ CBC_CommonCharacterSetECI(FX_INT32 value, CFX_ByteString encodingName);
+ virtual ~CBC_CommonCharacterSetECI();
+ CFX_ByteString GetEncodingName();
+ static void AddCharacterSet(FX_INT32 value, CFX_ByteString encodingName);
+ FX_INT32 GetValue();
+ static CBC_CommonCharacterSetECI* GetCharacterSetECIByValue(FX_INT32 value);
+ static CBC_CommonCharacterSetECI* GetCharacterSetECIByName(const CFX_ByteString& name);
+private:
+ CFX_ByteString m_encodingName;
+ static void initialize();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonDecoderResult.h b/xfa/src/fxbarcode/src/include/BC_CommonDecoderResult.h
new file mode 100644
index 0000000000..808203bd01
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonDecoderResult.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONDECODERRESULT_H_
+#define _BC_COMMONDECODERRESULT_H_
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_PDF417ResultMetadata;
+class CBC_CommonDecoderResult;
+class CBC_CommonDecoderResult : public CFX_Object
+{
+public:
+ CBC_CommonDecoderResult();
+ virtual ~CBC_CommonDecoderResult();
+ const CFX_ByteArray& GetRawBytes();
+ const CFX_ByteString& GetText();
+ const CFX_Int32Array& GetByteSegments();
+ CBC_QRCoderErrorCorrectionLevel* GetECLevel();
+ virtual void Init(const CFX_ByteArray &rawBytes, const CFX_ByteString &text, const CFX_Int32Array &byteSegments, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 &e);
+ virtual void Init(const CFX_ByteArray &rawBytes, const CFX_ByteString &text, const CFX_PtrArray &byteSegments, const CFX_ByteString &ecLevel, FX_INT32 &e);
+ void setOther(CBC_PDF417ResultMetadata* other);
+private:
+ CFX_ByteArray m_rawBytes;
+ CFX_ByteString m_text;
+ CFX_Int32Array m_byteSegments;
+ CFX_PtrArray m_pdf417byteSegments;
+ CBC_QRCoderErrorCorrectionLevel* m_ecLevel;
+ CFX_ByteString m_pdf417ecLevel;
+ CBC_PDF417ResultMetadata* m_other;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonECI.h b/xfa/src/fxbarcode/src/include/BC_CommonECI.h
new file mode 100644
index 0000000000..3907066066
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonECI.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONECI_H_
+#define _BC_COMMONECI_H_
+class CBC_CommonECI;
+class CBC_CommonECI : public CFX_Object
+{
+public:
+ CBC_CommonECI(FX_INT32 value);
+ virtual ~CBC_CommonECI();
+
+ FX_INT32 GetValue();
+ static CBC_CommonECI* GetEICByValue(FX_INT32 value, FX_INT32 &e);
+private:
+ FX_INT32 m_value;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_CommonPerspectiveTransform.h b/xfa/src/fxbarcode/src/include/BC_CommonPerspectiveTransform.h
new file mode 100644
index 0000000000..5c42a1a6a7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_CommonPerspectiveTransform.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMMONPERSPECTIVETRANSFORM_H_
+#define _BC_COMMONPERSPECTIVETRANSFORM_H_
+class CBC_CommonPerspectiveTransform;
+class CBC_CommonPerspectiveTransform : public CFX_Object
+{
+public:
+ CBC_CommonPerspectiveTransform(FX_FLOAT a11, FX_FLOAT a21, FX_FLOAT a31,
+ FX_FLOAT a12, FX_FLOAT a22, FX_FLOAT a32,
+ FX_FLOAT a13, FX_FLOAT a23, FX_FLOAT a33);
+ virtual ~CBC_CommonPerspectiveTransform();
+ static CBC_CommonPerspectiveTransform *QuadrilateralToQuadrilateral(FX_FLOAT x0, FX_FLOAT y0,
+ FX_FLOAT x1, FX_FLOAT y1,
+ FX_FLOAT x2, FX_FLOAT y2,
+ FX_FLOAT x3, FX_FLOAT y3,
+ FX_FLOAT x0p, FX_FLOAT y0p,
+ FX_FLOAT x1p, FX_FLOAT y1p,
+ FX_FLOAT x2p, FX_FLOAT y2p,
+ FX_FLOAT x3p, FX_FLOAT y3p);
+ static CBC_CommonPerspectiveTransform *SquareToQuadrilateral(FX_FLOAT x0, FX_FLOAT y0,
+ FX_FLOAT x1, FX_FLOAT y1,
+ FX_FLOAT x2, FX_FLOAT y2,
+ FX_FLOAT x3, FX_FLOAT y3);
+ static CBC_CommonPerspectiveTransform *QuadrilateralToSquare(FX_FLOAT x0, FX_FLOAT y0,
+ FX_FLOAT x1, FX_FLOAT y1,
+ FX_FLOAT x2, FX_FLOAT y2,
+ FX_FLOAT x3, FX_FLOAT y3);
+ CBC_CommonPerspectiveTransform *BuildAdjoint();
+ CBC_CommonPerspectiveTransform *Times(CBC_CommonPerspectiveTransform &other);
+ void TransformPoints(CFX_FloatArray *points);
+private:
+ FX_FLOAT m_a11, m_a12, m_a13, m_a21, m_a22, m_a23, m_a31, m_a32, m_a33;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixBitMatrixParser.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixBitMatrixParser.h
new file mode 100644
index 0000000000..c5f1f3f7a0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixBitMatrixParser.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXBITMATRIXPARSER_H_
+#define _BC_DATAMATRIXBITMATRIXPARSER_H_
+class CBC_CommonBitMatrix;
+class CBC_DataMatrixVersion;
+class CBC_DataMatrixBitMatrixParser;
+class CBC_DataMatrixBitMatrixParser : public CFX_Object
+{
+public:
+ CBC_DataMatrixBitMatrixParser();
+ virtual ~CBC_DataMatrixBitMatrixParser();
+ CBC_DataMatrixVersion *GetVersion();
+ CFX_ByteArray *ReadCodewords(FX_INT32 &e);
+ FX_BOOL ReadModule(FX_INT32 row, FX_INT32 column, FX_INT32 numRows, FX_INT32 numColumns);
+ FX_INT32 ReadUtah(FX_INT32 row, FX_INT32 column, FX_INT32 numRows, FX_INT32 numColumns);
+ FX_INT32 ReadCorner1(FX_INT32 numRows, FX_INT32 numColumns);
+ FX_INT32 ReadCorner2(FX_INT32 numRows, FX_INT32 numColumns);
+ FX_INT32 ReadCorner3(FX_INT32 numRows, FX_INT32 numColumns);
+ FX_INT32 ReadCorner4(FX_INT32 numRows, FX_INT32 numColumns);
+ CBC_CommonBitMatrix *ExtractDataRegion(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e);
+ virtual void Init(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e);
+private:
+ static CBC_DataMatrixVersion* ReadVersion(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e);
+ CBC_CommonBitMatrix *m_mappingBitMatrix;
+ CBC_CommonBitMatrix *m_readMappingMatrix;
+ CBC_DataMatrixVersion *m_version;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixDataBlock.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixDataBlock.h
new file mode 100644
index 0000000000..1dd62fe1fe
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixDataBlock.h
@@ -0,0 +1,26 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXDATABLOCK_H_
+#define _BC_DATAMATRIXDATABLOCK_H_
+class CBC_DataMatrixVersion;
+class CBC_DataMatrixDataBlock;
+class CBC_DataMatrixDataBlock : public CFX_Object
+{
+public:
+ virtual ~CBC_DataMatrixDataBlock();
+
+ FX_INT32 GetNumDataCodewords();
+ CFX_ByteArray* GetCodewords();
+
+ static CFX_PtrArray *GetDataBlocks(CFX_ByteArray* rawCodewords, CBC_DataMatrixVersion *version, FX_INT32 &e);
+private:
+ FX_INT32 m_numDataCodewords;
+ CFX_ByteArray m_codewords;
+
+ CBC_DataMatrixDataBlock(FX_INT32 numDataCodewords, CFX_ByteArray *codewords);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixDecodedBitStreamParser.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixDecodedBitStreamParser.h
new file mode 100644
index 0000000000..060972d53a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixDecodedBitStreamParser.h
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXDECODEDBITSTREAMPARSER_H_
+#define _BC_DATAMATRIXDECODEDBITSTREAMPARSER_H_
+class CBC_CommonDecoderResult;
+class CBC_CommonBitSource;
+class CBC_DataMatrixDecodedBitStreamParser;
+class CBC_DataMatrixDecodedBitStreamParser : public CFX_Object
+{
+public:
+ CBC_DataMatrixDecodedBitStreamParser();
+ virtual ~CBC_DataMatrixDecodedBitStreamParser();
+ static CBC_CommonDecoderResult *Decode(CFX_ByteArray &bytes, FX_INT32 &e);
+
+private:
+ static FX_INT32 DecodeAsciiSegment(CBC_CommonBitSource *bits, CFX_ByteString &result, CFX_ByteString &resultTrailer, FX_INT32 &e);
+ static void DecodeC40Segment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e);
+ static void DecodeTextSegment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e);
+ static void DecodeAnsiX12Segment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e);
+ static void ParseTwoBytes(FX_INT32 firstByte, FX_INT32 secondByte, CFX_Int32Array &result);
+ static void DecodeEdifactSegment(CBC_CommonBitSource *bits, CFX_ByteString &result, FX_INT32 &e);
+ static void DecodeBase256Segment(CBC_CommonBitSource *bits, CFX_ByteString &result, CFX_Int32Array &byteSegments, FX_INT32 &e);
+ static FX_BYTE Unrandomize255State(FX_INT32 randomizedBase256Codeword, FX_INT32 base256CodewordPosition);
+
+ const static FX_CHAR C40_BASIC_SET_CHARS[];
+ const static FX_CHAR C40_SHIFT2_SET_CHARS[];
+
+
+ const static FX_CHAR TEXT_BASIC_SET_CHARS[];
+ const static FX_CHAR TEXT_SHIFT3_SET_CHARS[];
+ const static FX_INT32 PAD_ENCODE;
+ const static FX_INT32 ASCII_ENCODE;
+ const static FX_INT32 C40_ENCODE;
+ const static FX_INT32 TEXT_ENCODE;
+ const static FX_INT32 ANSIX12_ENCODE;
+ const static FX_INT32 EDIFACT_ENCODE;
+ const static FX_INT32 BASE256_ENCODE;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixDecoder.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixDecoder.h
new file mode 100644
index 0000000000..44f7efc7b7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixDecoder.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXDECODER_H_
+#define _BC_DATAMATRIXDECODER_H_
+class CBC_ReedSolomonDecoder;
+class CBC_CommonDecoderResult;
+class CBC_CommonBitMatrix;
+class CBC_DataMatrixDecoder;
+class CBC_DataMatrixDecoder : public CFX_Object
+{
+public:
+ CBC_DataMatrixDecoder();
+ virtual ~CBC_DataMatrixDecoder();
+ CBC_CommonDecoderResult *Decode(CBC_CommonBitMatrix *bits, FX_INT32 &e);
+ virtual void Init();
+private:
+ void CorrectErrors(CFX_ByteArray &codewordBytes, FX_INT32 numDataCodewords, FX_INT32 &e);
+ CBC_ReedSolomonDecoder *m_rsDecoder;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixDetector.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixDetector.h
new file mode 100644
index 0000000000..2d3ca744fe
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixDetector.h
@@ -0,0 +1,78 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXDETECTOR_H_
+#define _BC_DATAMATRIXDETECTOR_H_
+class CBC_CommonBitMatrix;
+class CBC_WhiteRectangleDetector;
+class CBC_ResultPoint;
+class CBC_QRDetectorResult;
+class CBC_DataMatrixDetector;
+class ResultPointsAndTransitions;
+class CBC_ResultPointsAndTransitions : public CFX_Object
+{
+public:
+ CBC_ResultPointsAndTransitions(CBC_ResultPoint *from, CBC_ResultPoint *to, FX_INT32 transitions)
+ {
+ m_from = from;
+ m_to = to;
+ m_transitions = transitions;
+ }
+ ~CBC_ResultPointsAndTransitions()
+ {
+ }
+ CBC_ResultPoint *GetFrom()
+ {
+ return m_from;
+ }
+ CBC_ResultPoint *GetTo()
+ {
+ return m_to;
+ }
+ FX_INT32 GetTransitions()
+ {
+ return m_transitions;
+ }
+private:
+ CBC_ResultPoint *m_from;
+ CBC_ResultPoint *m_to;
+ FX_INT32 m_transitions;
+};
+class CBC_DataMatrixDetector
+{
+public:
+ CBC_DataMatrixDetector(CBC_CommonBitMatrix *image);
+ virtual ~CBC_DataMatrixDetector();
+ CBC_QRDetectorResult *Detect(FX_INT32 &e);
+ CBC_ResultPoint *CorrectTopRightRectangular(CBC_ResultPoint *bottomLeft,
+ CBC_ResultPoint *bottomRight,
+ CBC_ResultPoint *topLeft,
+ CBC_ResultPoint *topRight,
+ FX_INT32 dimensionTop, FX_INT32 dimensionRight);
+ CBC_ResultPoint *CorrectTopRight(CBC_ResultPoint *bottomLeft,
+ CBC_ResultPoint *bottomRight,
+ CBC_ResultPoint *topLeft,
+ CBC_ResultPoint *topRight,
+ FX_INT32 dimension);
+ CBC_CommonBitMatrix *SampleGrid(CBC_CommonBitMatrix *image,
+ CBC_ResultPoint *topLeft,
+ CBC_ResultPoint *bottomLeft,
+ CBC_ResultPoint *bottomRight,
+ CBC_ResultPoint *topRight,
+ FX_INT32 dimensionX, FX_INT32 dimensionY, FX_INT32 &e);
+ CBC_ResultPointsAndTransitions *TransitionsBetween(CBC_ResultPoint *from, CBC_ResultPoint *to);
+ FX_BOOL IsValid(CBC_ResultPoint *p);
+ FX_INT32 Distance(CBC_ResultPoint *a, CBC_ResultPoint *b);
+ void Increment(CFX_MapPtrTemplate<CBC_ResultPoint*, FX_INT32> &table, CBC_ResultPoint *key);
+ FX_INT32 Round(FX_FLOAT d);
+ void OrderBestPatterns(CFX_PtrArray *patterns);
+ virtual void Init(FX_INT32 &e);
+private:
+ CBC_CommonBitMatrix *m_image;
+ CBC_WhiteRectangleDetector *m_rectangleDetector;
+ const static FX_INT32 INTEGERS[5];
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixReader.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixReader.h
new file mode 100644
index 0000000000..4301512d70
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixReader.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXREADER_H_
+#define _BC_DATAMATRIXREADER_H_
+class CBC_BinaryBitmap;
+class CBC_DataMatrixDecoder;
+class CBC_Reader;
+class CBC_DataMatrixReader;
+class CBC_DataMatrixReader : public CBC_Reader
+{
+public:
+ CBC_DataMatrixReader();
+ virtual ~CBC_DataMatrixReader();
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 &e);
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, int hints, FX_INT32 &e);
+
+ virtual void Init();
+private:
+ CBC_DataMatrixDecoder *m_decoder;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixSymbolInfo144.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixSymbolInfo144.h
new file mode 100644
index 0000000000..e749b27d86
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixSymbolInfo144.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXSYMBOLINFO144_H_
+#define _BC_DATAMATRIXSYMBOLINFO144_H_
+class CBC_SymbolInfo;
+class CBC_DataMatrixSymbolInfo144;
+class CBC_DataMatrixSymbolInfo144 : public CBC_SymbolInfo
+{
+public:
+ CBC_DataMatrixSymbolInfo144();
+ virtual ~CBC_DataMatrixSymbolInfo144();
+ FX_INT32 getInterleavedBlockCount();
+ FX_INT32 getDataLengthForInterleavedBlock(FX_INT32 index);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixVersion.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixVersion.h
new file mode 100644
index 0000000000..41d2f23db6
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixVersion.h
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXVERSION_H_
+#define _BC_DATAMATRIXVERSION_H_
+class ECB;
+class ECBlocks;
+class CBC_DataMatrixVersion;
+class ECB : public CFX_Object
+{
+public:
+ ECB(FX_INT32 count, FX_INT32 dataCodewords)
+ {
+ m_count = count;
+ m_dataCodewords = dataCodewords;
+ }
+
+ FX_INT32 GetCount()
+ {
+ return m_count;
+ }
+
+ FX_INT32 GetDataCodewords()
+ {
+ return m_dataCodewords;
+ }
+private:
+ FX_INT32 m_count;
+ FX_INT32 m_dataCodewords;
+};
+class ECBlocks : public CFX_Object
+{
+public:
+ ECBlocks(FX_INT32 ecCodewords, ECB *ecBlocks)
+ {
+ m_ecCodewords = ecCodewords;
+ m_ecBlocks.Add(ecBlocks);
+ }
+
+ ECBlocks(FX_INT32 ecCodewords, ECB *ecBlocks1, ECB *ecBlocks2)
+ {
+ m_ecCodewords = ecCodewords;
+ m_ecBlocks.Add(ecBlocks1);
+ m_ecBlocks.Add(ecBlocks2);
+ }
+ ~ECBlocks()
+ {
+ for(FX_INT32 i = 0; i < m_ecBlocks.GetSize(); i++) {
+ delete (ECB*)m_ecBlocks[i];
+ }
+ m_ecBlocks.RemoveAll();
+ }
+
+ FX_INT32 GetECCodewords()
+ {
+ return m_ecCodewords;
+ }
+
+ const CFX_PtrArray &GetECBlocks()
+ {
+ return m_ecBlocks;
+ }
+private:
+ FX_INT32 m_ecCodewords;
+ CFX_PtrArray m_ecBlocks;
+};
+class CBC_DataMatrixVersion : public CFX_Object
+{
+public:
+ CBC_DataMatrixVersion(FX_INT32 versionNumber,
+ FX_INT32 symbolSizeRows,
+ FX_INT32 symbolSizeColumns,
+ FX_INT32 dataRegionSizeRows,
+ FX_INT32 dataRegionSizeColumns,
+ ECBlocks *ecBlocks);
+ virtual ~CBC_DataMatrixVersion();
+ static void Initialize();
+ static void Finalize();
+ FX_INT32 GetVersionNumber();
+ FX_INT32 GetSymbolSizeRows();
+ FX_INT32 GetSymbolSizeColumns();
+ FX_INT32 GetDataRegionSizeRows();
+ FX_INT32 GetDataRegionSizeColumns();
+ FX_INT32 GetTotalCodewords();
+ ECBlocks *GetECBlocks();
+ static CBC_DataMatrixVersion *GetVersionForDimensions(FX_INT32 numRows, FX_INT32 numColumns, FX_INT32 &e);
+ static void ReleaseAll();
+private:
+ FX_INT32 m_versionNumber;
+ FX_INT32 m_symbolSizeRows;
+ FX_INT32 m_symbolSizeColumns;
+ FX_INT32 m_dataRegionSizeRows;
+ FX_INT32 m_dataRegionSizeColumns;
+ ECBlocks *m_ecBlocks;
+ FX_INT32 m_totalCodewords;
+ static CFX_PtrArray* VERSIONS;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DataMatrixWriter.h b/xfa/src/fxbarcode/src/include/BC_DataMatrixWriter.h
new file mode 100644
index 0000000000..c8a6bdd823
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DataMatrixWriter.h
@@ -0,0 +1,30 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DATAMATRIXWRITER_H_
+#define _BC_DATAMATRIXWRITER_H_
+class CBC_CommonByteMatrix;
+class CBC_CommonBitMatrix;
+class CBC_DefaultPlacement;
+class CBC_SymbolShapeHint;
+class CBC_SymbolInfo;
+class CBC_TwoDimWriter;
+class CBC_DataMatrixWriter;
+class CBC_DataMatrixWriter : public CBC_TwoDimWriter
+{
+public:
+ CBC_DataMatrixWriter();
+ virtual ~CBC_DataMatrixWriter();
+ FX_BYTE* Encode(const CFX_WideString &contents, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ FX_BOOL SetErrorCorrectionLevel (FX_INT32 level);
+
+private:
+ static CBC_CommonByteMatrix* encodeLowLevel(CBC_DefaultPlacement* placement, CBC_SymbolInfo* symbolInfo, FX_INT32 &e);
+ FX_INT32 m_iCorrectLevel;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DecoderResult.h b/xfa/src/fxbarcode/src/include/BC_DecoderResult.h
new file mode 100644
index 0000000000..ff98b2c407
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DecoderResult.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DECODERRESULT_H_
+#define _BC_DECODERRESULT_H_
+class CBC_DecoderResult;
+class CBC_DecoderResult : public CFX_Object
+{
+public:
+ CBC_DecoderResult(CFX_ByteArray* rawBytes, CFX_ByteString text, CFX_ByteString ecLevel);
+ virtual ~CBC_DecoderResult();
+ CFX_ByteArray* getRawBytes();
+ CFX_ByteString getText();
+ CFX_ByteString getECLevel();
+ FX_INT32 getErrorsCorrected();
+ void setErrorsCorrected(FX_INT32 errorsCorrected);
+ FX_INT32 getErasures();
+ void setErasures(FX_INT32 erasures);
+ CFX_Object* getOther();
+ void setOther(CFX_Object* other);
+private:
+ CFX_ByteArray* m_rawBytes;
+ CFX_ByteString m_text;
+ CFX_ByteString m_ecLevel;
+ FX_INT32 m_errorsCorrected;
+ FX_INT32 m_erasures;
+ CFX_Object* m_other;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_DefaultPlacement.h b/xfa/src/fxbarcode/src/include/BC_DefaultPlacement.h
new file mode 100644
index 0000000000..ba2da03408
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_DefaultPlacement.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DEFAULTPLACEMENT_H_
+#define _BC_DEFAULTPLACEMENT_H_
+class CBC_DefaultPlacement;
+class CBC_DefaultPlacement : public CFX_Object
+{
+public:
+ CBC_DefaultPlacement(CFX_WideString codewords, FX_INT32 numcols, FX_INT32 numrows);
+ virtual ~CBC_DefaultPlacement();
+
+ FX_INT32 getNumrows();
+ FX_INT32 getNumcols();
+ CFX_ByteArray& getBits();
+ FX_BOOL getBit(FX_INT32 col, FX_INT32 row);
+ void setBit(FX_INT32 col, FX_INT32 row, FX_BOOL bit);
+ FX_BOOL hasBit(FX_INT32 col, FX_INT32 row);
+ void place();
+private:
+ CFX_WideString m_codewords;
+ FX_INT32 m_numrows;
+ FX_INT32 m_numcols;
+ CFX_ByteArray m_bits;
+ void module(FX_INT32 row, FX_INT32 col, FX_INT32 pos, FX_INT32 bit);
+ void utah(FX_INT32 row, FX_INT32 col, FX_INT32 pos);
+ void corner1(FX_INT32 pos);
+ void corner2(FX_INT32 pos);
+ void corner3(FX_INT32 pos);
+ void corner4(FX_INT32 pos);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_Dimension.h b/xfa/src/fxbarcode/src/include/BC_Dimension.h
new file mode 100644
index 0000000000..ff4aecace4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_Dimension.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DIMENSION_H_
+#define _BC_DIMENSION_H_
+class CBC_Dimension;
+class CBC_Dimension : public CFX_Object
+{
+public:
+ CBC_Dimension();
+ CBC_Dimension(FX_INT32 width, FX_INT32 height, FX_INT32 &e);
+ virtual ~CBC_Dimension();
+ FX_INT32 getWidth();
+ FX_INT32 getHeight();
+ FX_INT32 hashCode();
+ CFX_WideString toString();
+private:
+ FX_INT32 m_width;
+ FX_INT32 m_height;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_EdifactEncoder.h b/xfa/src/fxbarcode/src/include/BC_EdifactEncoder.h
new file mode 100644
index 0000000000..7e2453a71d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_EdifactEncoder.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_EDIFACTENCODER_H_
+#define _BC_EDIFACTENCODER_H_
+class CBC_EncoderContext;
+class CBC_EdifactEncoder;
+class CBC_EdifactEncoder : public CBC_Encoder
+{
+public:
+ CBC_EdifactEncoder();
+ virtual ~CBC_EdifactEncoder();
+ FX_INT32 getEncodingMode();
+ void Encode(CBC_EncoderContext &context, FX_INT32 &e);
+private:
+ static void handleEOD(CBC_EncoderContext &context, CFX_WideString buffer, FX_INT32 &e);
+ static void encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e);
+ static CFX_WideString encodeToCodewords(CFX_WideString sb, FX_INT32 startPos, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_Encoder.h b/xfa/src/fxbarcode/src/include/BC_Encoder.h
new file mode 100644
index 0000000000..10ac8763e5
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_Encoder.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ENCODER_H_
+#define _BC_ENCODER_H_
+class CBC_EncoderContext;
+class CBC_Encoder;
+class CBC_Encoder : public CFX_Object
+{
+public:
+ CBC_Encoder();
+ virtual ~CBC_Encoder();
+ virtual FX_INT32 getEncodingMode() = 0;
+ virtual void Encode(CBC_EncoderContext &context, FX_INT32 &e) = 0;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_EncoderContext.h b/xfa/src/fxbarcode/src/include/BC_EncoderContext.h
new file mode 100644
index 0000000000..0099dbc9f0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_EncoderContext.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ENCODERCONTEXT_H_
+#define _BC_ENCODERCONTEXT_H_
+class CBC_SymbolShapeHint;
+class CBC_SymbolInfo;
+class CBC_Dimension;
+class CBC_EncoderContext;
+class CBC_EncoderContext : public CBC_SymbolShapeHint
+{
+public:
+ CBC_EncoderContext(const CFX_WideString msg, CFX_WideString ecLevel, FX_INT32 &e);
+ virtual ~CBC_EncoderContext();
+ void setSymbolShape(SymbolShapeHint shape);
+ void setSizeConstraints(CBC_Dimension* minSize, CBC_Dimension* maxSize);
+ CFX_WideString getMessage();
+ void setSkipAtEnd(FX_INT32 count);
+ FX_WCHAR getCurrentChar();
+ FX_WCHAR getCurrent();
+ void writeCodewords(CFX_WideString codewords);
+ void writeCodeword(FX_WCHAR codeword);
+ FX_INT32 getCodewordCount();
+ void signalEncoderChange(FX_INT32 encoding);
+ void resetEncoderSignal();
+ FX_BOOL hasMoreCharacters();
+ FX_INT32 getRemainingCharacters();
+ void updateSymbolInfo(FX_INT32 &e);
+ void updateSymbolInfo(FX_INT32 len, FX_INT32 &e);
+ void resetSymbolInfo();
+public:
+ CFX_WideString m_msg;
+ CFX_WideString m_codewords;
+ FX_INT32 m_pos;
+ FX_INT32 m_newEncoding;
+ CBC_SymbolInfo* m_symbolInfo;
+private:
+ FX_INT32 getTotalMessageCharCount();
+private:
+ SymbolShapeHint m_shape;
+ CBC_Dimension* m_minSize;
+ CBC_Dimension* m_maxSize;
+ FX_INT32 m_skipAtEnd;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_ErrorCorrection.h b/xfa/src/fxbarcode/src/include/BC_ErrorCorrection.h
new file mode 100644
index 0000000000..973ff33b8e
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_ErrorCorrection.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ERRORCORRECTION_H_
+#define _BC_ERRORCORRECTION_H_
+class CBC_SymbolInfo;
+class CBC_ErrorCorrection;
+class CBC_ErrorCorrection : public CFX_Object
+{
+public:
+ CBC_ErrorCorrection();
+ virtual ~CBC_ErrorCorrection();
+ static void Initialize();
+ static void Finalize();
+ static CFX_WideString encodeECC200(CFX_WideString codewords, CBC_SymbolInfo* symbolInfo, FX_INT32 &e);
+private:
+ static FX_INT32 FACTOR_SETS[];
+ static FX_INT32 FACTORS[][100];
+ static FX_INT32 MODULO_VALUE;
+ static FX_INT32 LOG[256];
+ static FX_INT32 ALOG[256];
+private:
+ static CFX_WideString createECCBlock(CFX_WideString codewords, FX_INT32 numECWords, FX_INT32 &e);
+ static CFX_WideString createECCBlock(CFX_WideString codewords, FX_INT32 start, FX_INT32 len, FX_INT32 numECWords, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_FinderPatternInfo.h b/xfa/src/fxbarcode/src/include/BC_FinderPatternInfo.h
new file mode 100644
index 0000000000..bac9291947
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_FinderPatternInfo.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_FINDERPATTERNINFO_H_
+#define _BC_FINDERPATTERNINFO_H_
+class CBC_QRFinderPattern;
+class CBC_QRFinderPatternInfo;
+class CBC_QRFinderPatternInfo : public CFX_Object
+{
+private:
+ CBC_QRFinderPattern *m_bottomLeft;
+ CBC_QRFinderPattern *m_topLeft;
+ CBC_QRFinderPattern *m_topRight;
+public:
+ CBC_QRFinderPatternInfo(CFX_PtrArray *patternCenters);
+ virtual ~CBC_QRFinderPatternInfo();
+ CBC_QRFinderPattern* GetBottomLeft();
+ CBC_QRFinderPattern* GetTopLeft();
+ CBC_QRFinderPattern* GetTopRight();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_GlobalHistogramBinarizer.h b/xfa/src/fxbarcode/src/include/BC_GlobalHistogramBinarizer.h
new file mode 100644
index 0000000000..ef084c075e
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_GlobalHistogramBinarizer.h
@@ -0,0 +1,28 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_GLOBALHISTOGRAMBINARIZER_H_
+#define _BC_GLOBALHISTOGRAMBINARIZER_H_
+class CBC_CommonBinarizer;
+class CBC_CommonBitArray;
+class CBC_CommonBitMatrix;
+class CBC_LuminanceSource;
+class CBC_GlobalHistogramBinarizer;
+class CBC_GlobalHistogramBinarizer : public CBC_Binarizer
+{
+public:
+ CBC_GlobalHistogramBinarizer(CBC_LuminanceSource *source);
+ virtual ~CBC_GlobalHistogramBinarizer();
+
+ void InitArrays(FX_INT32 luminanceSize);
+ CBC_CommonBitMatrix *GetBlackMatrix(FX_INT32 &e);
+ CBC_CommonBitArray *GetBlackRow(FX_INT32 y, CBC_CommonBitArray *row, FX_INT32 &e);
+ static FX_INT32 EstimateBlackPoint(CFX_Int32Array &buckets, FX_INT32 &e);
+private:
+ CFX_ByteArray m_luminance;
+ CFX_Int32Array m_buckets;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_HighLevelEncoder.h b/xfa/src/fxbarcode/src/include/BC_HighLevelEncoder.h
new file mode 100644
index 0000000000..170ca9f8fa
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_HighLevelEncoder.h
@@ -0,0 +1,60 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_HIGHLEVALENCODER_H_
+#define _BC_HIGHLEVALENCODER_H_
+class CBC_SymbolShapeHint;
+class CBC_HighLevelEncoder;
+#define ASCII_ENCODATION 0
+#define C40_ENCODATION 1
+#define TEXT_ENCODATION 2
+#define X12_ENCODATION 3
+#define EDIFACT_ENCODATION 4
+#define BASE256_ENCODATION 5
+class CBC_HighLevelEncoder : public CBC_SymbolShapeHint
+{
+public:
+ CBC_HighLevelEncoder();
+ virtual ~CBC_HighLevelEncoder();
+ CFX_ByteArray& getBytesForMessage(CFX_WideString msg);
+ static CFX_WideString encodeHighLevel(CFX_WideString msg, CFX_WideString ecLevel, FX_INT32 &e);
+ static CFX_WideString encodeHighLevel(CFX_WideString msg, CFX_WideString ecLevel, SymbolShapeHint shape, CBC_Dimension* minSize, CBC_Dimension* maxSize, FX_INT32 &e);
+ static FX_INT32 lookAheadTest(CFX_WideString msg, FX_INT32 startpos, FX_INT32 currentMode);
+ static FX_BOOL isDigit(FX_WCHAR ch);
+ static FX_BOOL isExtendedASCII(FX_WCHAR ch);
+ static FX_INT32 determineConsecutiveDigitCount(CFX_WideString msg, FX_INT32 startpos);
+ static void illegalCharacter(FX_WCHAR c, FX_INT32 &e);
+
+public:
+ static FX_WCHAR LATCH_TO_C40;
+ static FX_WCHAR LATCH_TO_BASE256;
+ static FX_WCHAR UPPER_SHIFT;
+ static FX_WCHAR LATCH_TO_ANSIX12;
+ static FX_WCHAR LATCH_TO_TEXT;
+ static FX_WCHAR LATCH_TO_EDIFACT;
+ static FX_WCHAR C40_UNLATCH;
+ static FX_WCHAR X12_UNLATCH;
+private:
+ static FX_WCHAR PAD;
+ static FX_WCHAR MACRO_05;
+ static FX_WCHAR MACRO_06;
+ static const wchar_t* MACRO_05_HEADER;
+ static const wchar_t* MACRO_06_HEADER;
+ static const wchar_t MACRO_TRAILER;
+ CFX_ByteArray m_bytearray;
+private:
+ static FX_WCHAR randomize253State(FX_WCHAR ch, FX_INT32 codewordPosition);
+ static FX_INT32 findMinimums(CFX_FloatArray &charCounts, CFX_Int32Array &intCharCounts, FX_INT32 min, CFX_ByteArray &mins);
+ static FX_INT32 getMinimumCount(CFX_ByteArray &mins);
+ static FX_BOOL isNativeC40(FX_WCHAR ch);
+ static FX_BOOL isNativeText(FX_WCHAR ch);
+ static FX_BOOL isNativeX12(FX_WCHAR ch);
+ static FX_BOOL isX12TermSep(FX_WCHAR ch);
+ static FX_BOOL isNativeEDIFACT(FX_WCHAR ch);
+ static FX_BOOL isSpecialB256(FX_WCHAR ch);
+
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_LuminanceSource.h b/xfa/src/fxbarcode/src/include/BC_LuminanceSource.h
new file mode 100644
index 0000000000..6aa85101c9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_LuminanceSource.h
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_LUMINANCESOURCE_H
+#define _BC_LUMINANCESOURCE_H
+class CBC_LuminanceSource;
+class CBC_LuminanceSource : public CFX_Object
+{
+public:
+ CBC_LuminanceSource(FX_INT32 width, FX_INT32 height);
+ virtual ~CBC_LuminanceSource();
+ FX_INT32 GetWidth();
+ FX_INT32 GetHeight();
+
+ virtual CFX_ByteArray *GetRow(FX_INT32 y, CFX_ByteArray &row, FX_INT32 &e) = 0;
+ virtual CFX_ByteArray *GetMatrix() = 0;
+ virtual FX_BOOL IsCropSupported()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL IsRotateSupported()
+ {
+ return FALSE;
+ }
+
+ virtual CBC_LuminanceSource *RotateCounterClockwise(FX_INT32 &e) = 0;
+protected:
+ FX_INT32 m_width;
+ FX_INT32 m_height;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OneDReader.h b/xfa/src/fxbarcode/src/include/BC_OneDReader.h
new file mode 100644
index 0000000000..8645c9edf9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OneDReader.h
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDREADER_H_
+#define _BC_ONEDREADER_H_
+class CBC_Reader;
+class CBC_BinaryBitmap;
+class CBC_CommonBitArray;
+class CBC_OneDReader;
+class CBC_OneDReader : public CBC_Reader
+{
+public:
+ CBC_OneDReader();
+ virtual ~CBC_OneDReader();
+ virtual CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 &e);
+ virtual CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e);
+ virtual CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e)
+ {
+ return "";
+ }
+private:
+ CFX_ByteString DeDecode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e);
+
+protected:
+ const static FX_INT32 INTEGER_MATH_SHIFT;
+ const static FX_INT32 PATTERN_MATCH_RESULT_SCALE_FACTOR;
+ void RecordPattern(CBC_CommonBitArray *row, FX_INT32 start, CFX_Int32Array *counters, FX_INT32 &e);
+ void RecordPatternInReverse(CBC_CommonBitArray *row, FX_INT32 start, CFX_Int32Array *counters, FX_INT32 &e);
+ FX_INT32 PatternMatchVariance(CFX_Int32Array *counters, const FX_INT32 *pattern, FX_INT32 maxIndividualVariance);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OneDimReader.h b/xfa/src/fxbarcode/src/include/BC_OneDimReader.h
new file mode 100644
index 0000000000..bb10060ba3
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OneDimReader.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDUPCEANREADER_H_
+#define _BC_ONEDUPCEANREADER_H_
+class CBC_OneDReader;
+class CBC_CommonBitArray;
+class CBC_OneDimReader;
+class CBC_OneDimReader : public CBC_OneDReader
+{
+private:
+ const static FX_INT32 MAX_AVG_VARIANCE;
+ const static FX_INT32 MAX_INDIVIDUAL_VARIANCE;
+
+ FX_BOOL CheckStandardUPCEANChecksum(CFX_ByteString &s, FX_INT32 &e);
+public:
+ const static FX_INT32 START_END_PATTERN[3];
+ const static FX_INT32 MIDDLE_PATTERN[5];
+ const static FX_INT32 L_PATTERNS[10][4];
+ const static FX_INT32 L_AND_G_PATTERNS[20][4];
+ CBC_OneDimReader();
+ virtual ~CBC_OneDimReader();
+ CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e);
+ CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, CFX_Int32Array *startGuardRange, FX_INT32 hints, FX_INT32 &e);
+protected:
+ CFX_Int32Array *FindStartGuardPattern(CBC_CommonBitArray *row, FX_INT32 &e);
+ virtual FX_BOOL CheckChecksum(CFX_ByteString &s, FX_INT32 &e);
+ CFX_Int32Array *FindGuardPattern(CBC_CommonBitArray *row, FX_INT32 rowOffset, FX_BOOL whiteFirst, CFX_Int32Array *pattern, FX_INT32 &e);
+ FX_INT32 DecodeDigit(CBC_CommonBitArray *row, CFX_Int32Array *counters, FX_INT32 rowOffset, const FX_INT32* patterns, FX_INT32 patternLength, FX_INT32 &e);
+ virtual FX_INT32 DecodeMiddle(CBC_CommonBitArray *row, CFX_Int32Array *startRange, CFX_ByteString &resultResult, FX_INT32 &e)
+ {
+ return 0;
+ }
+ virtual CFX_Int32Array *DecodeEnd(CBC_CommonBitArray *row, FX_INT32 endStart, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OneDimWriter.h b/xfa/src/fxbarcode/src/include/BC_OneDimWriter.h
new file mode 100644
index 0000000000..cd5d937aca
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OneDimWriter.h
@@ -0,0 +1,70 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDIMWRITER_H_
+#define _BC_ONEDIMWRITER_H_
+class CBC_Writer;
+class CBC_CommonBitMatrix;
+class CBC_OneDimWriter;
+class CBC_OneDimWriter : public CBC_Writer
+{
+public:
+ CBC_OneDimWriter();
+ virtual ~CBC_OneDimWriter();
+ FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ virtual FX_BYTE *Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e)
+ {
+ return NULL;
+ };
+ virtual void RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e);
+ virtual void RenderBitmapResult(CFX_DIBitmap *&pOutBitmap, FX_WSTR contents, FX_INT32 &e);
+ virtual void RenderDeviceResult(CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_WSTR contents, FX_INT32 &e);
+ virtual FX_BOOL CheckContentValidity(FX_WSTR contents)
+ {
+ return TRUE;
+ };
+ virtual CFX_WideString FilterContents(FX_WSTR contents)
+ {
+ return CFX_WideString();
+ }
+ virtual CFX_WideString RenderTextContents(FX_WSTR contents)
+ {
+ return CFX_WideString();
+ }
+ virtual void SetPrintChecksum(FX_BOOL checksum);
+ virtual void SetDataLength(FX_INT32 length);
+ virtual void SetCalcChecksum(FX_INT32 state);
+ virtual void SetFontSize(FX_FLOAT size);
+ virtual void SetFontStyle(FX_INT32 style);
+ virtual void SetFontColor(FX_ARGB color);
+ virtual FX_BOOL SetFont(CFX_Font * cFont);
+protected:
+ FX_BOOL m_bPrintChecksum;
+ FX_INT32 m_iDataLenth;
+ FX_BOOL m_bCalcChecksum;
+ CFX_Font* m_pFont;
+ FX_FLOAT m_fFontSize;
+ FX_INT32 m_iFontStyle;
+ FX_DWORD m_fontColor;
+ BC_TEXT_LOC m_locTextLoc;
+ FX_INT32 m_iContentLen;
+ FX_BOOL m_bLeftPadding;
+ FX_BOOL m_bRightPadding;
+ CBC_CommonBitMatrix* m_output;
+ FX_INT32 m_barWidth;
+ FX_INT32 m_multiple;
+ FX_FLOAT m_outputHScale;
+ void CalcTextInfo(const CFX_ByteString &text, FXTEXT_CHARPOS *charPos, CFX_Font *cFont, FX_FLOAT geWidth, FX_INT32 fontSize, FX_FLOAT &charsLen);
+ virtual void ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice *device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e);
+ virtual void ShowBitmapChars(CFX_DIBitmap *pOutBitmap, const CFX_ByteString str, FX_FLOAT geWidth, FXTEXT_CHARPOS* pCharPos, FX_FLOAT locX, FX_FLOAT locY, FX_INT32 barWidth);
+ virtual void ShowDeviceChars(CFX_RenderDevice *device, const CFX_Matrix* matrix, const CFX_ByteString str, FX_FLOAT geWidth, FXTEXT_CHARPOS* pCharPos, FX_FLOAT locX, FX_FLOAT locY, FX_INT32 barWidth);
+ FX_INT32 AppendPattern(FX_BYTE* target, FX_INT32 pos, const FX_INT32* pattern, FX_INT32 patternLength, FX_INT32 startColor, FX_INT32 &e);
+ FX_WCHAR Upper(FX_WCHAR ch);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedCodaBarReader.h b/xfa/src/fxbarcode/src/include/BC_OnedCodaBarReader.h
new file mode 100644
index 0000000000..1d03491841
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedCodaBarReader.h
@@ -0,0 +1,30 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDCODABARREADER_H_
+#define _BC_ONEDCODABARREADER_H_
+class CBC_CommonBitArray;
+class CBC_OneDReader;
+class CBC_OnedCodaBarReader;
+class CBC_OnedCodaBarReader : public CBC_OneDReader
+{
+public:
+ CBC_OnedCodaBarReader();
+ virtual ~CBC_OnedCodaBarReader();
+ CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e);
+ CFX_Int32Array *FindAsteriskPattern(CBC_CommonBitArray *row, FX_INT32 &e);
+ FX_BOOL ArrayContains(const FX_CHAR array[], FX_CHAR key);
+ FX_CHAR ToNarrowWidePattern(CFX_Int32Array *counter);
+ static FX_LPCSTR ALPHABET_STRING;
+
+
+ const static FX_INT32 CHARACTER_ENCODINGS[22];
+
+ const static FX_INT32 minCharacterLength;
+
+ const static FX_CHAR STARTEND_ENCODING[8];
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedCodaBarWriter.h b/xfa/src/fxbarcode/src/include/BC_OnedCodaBarWriter.h
new file mode 100644
index 0000000000..b81839ca4a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedCodaBarWriter.h
@@ -0,0 +1,38 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDCODABARWRITER_H_
+#define _BC_ONEDCODABARWRITER_H_
+enum BC_TEXT_LOC;
+class CBC_OneDimWriter;
+class CBC_OnedCodaBarWriter;
+class CBC_OnedCodaBarWriter : public CBC_OneDimWriter
+{
+public:
+ CBC_OnedCodaBarWriter();
+ virtual ~CBC_OnedCodaBarWriter();
+ FX_BYTE* Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e);
+ FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ CFX_WideString encodedContents(FX_WSTR contents);
+ FX_BOOL CheckContentValidity(FX_WSTR contents);
+ CFX_WideString FilterContents(FX_WSTR contents);
+ FX_BOOL SetStartChar(FX_CHAR start);
+ FX_BOOL SetEndChar(FX_CHAR end);
+ void SetDataLength(FX_INT32 length);
+ FX_BOOL SetTextLocation(BC_TEXT_LOC location);
+ FX_BOOL SetWideNarrowRatio(FX_INT32 ratio);
+ FX_BOOL FindChar(FX_WCHAR ch, FX_BOOL isContent);
+private:
+ void RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e);
+ const static FX_CHAR START_END_CHARS[];
+ const static FX_CHAR CONTENT_CHARS[];
+ FX_CHAR m_chStart;
+ FX_CHAR m_chEnd;
+ FX_INT32 m_iWideNarrRatio;
+
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedCode128Reader.h b/xfa/src/fxbarcode/src/include/BC_OnedCode128Reader.h
new file mode 100644
index 0000000000..94e1a6388b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedCode128Reader.h
@@ -0,0 +1,40 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDCODA128READER_H_
+#define _BC_ONEDCODA128READER_H_
+class CBC_OneDReader;
+class CBC_CommonBitArray;
+class CBC_OnedCoda128Reader;
+class CBC_OnedCode128Reader : public CBC_OneDReader
+{
+public:
+ CBC_OnedCode128Reader();
+ virtual ~CBC_OnedCode128Reader();
+ virtual CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e);
+ const static FX_INT32 CODE_PATTERNS[107][7];
+ const static FX_INT32 MAX_AVG_VARIANCE;
+ const static FX_INT32 MAX_INDIVIDUAL_VARIANCE;
+
+ const static FX_INT32 CODE_SHIFT;
+ const static FX_INT32 CODE_CODE_C;
+ const static FX_INT32 CODE_CODE_B;
+ const static FX_INT32 CODE_CODE_A;
+ const static FX_INT32 CODE_FNC_1;
+ const static FX_INT32 CODE_FNC_2;
+ const static FX_INT32 CODE_FNC_3;
+ const static FX_INT32 CODE_FNC_4_A;
+ const static FX_INT32 CODE_FNC_4_B ;
+
+ const static FX_INT32 CODE_START_A;
+ const static FX_INT32 CODE_START_B;
+ const static FX_INT32 CODE_START_C;
+ const static FX_INT32 CODE_STOP;
+private:
+ CFX_Int32Array *FindStartPattern(CBC_CommonBitArray *row, FX_INT32 &e);
+ FX_INT32 DecodeCode(CBC_CommonBitArray *row, CFX_Int32Array *counters, FX_INT32 rowOffset, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedCode128Writer.h b/xfa/src/fxbarcode/src/include/BC_OnedCode128Writer.h
new file mode 100644
index 0000000000..daa48eca51
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedCode128Writer.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDCODA128WRITER_H_
+#define _BC_ONEDCODA128WRITER_H_
+class CBC_OneDimWriter;
+class CBC_OnedCoda128Writer;
+class CBC_OnedCode128Writer : public CBC_OneDimWriter
+{
+public:
+ CBC_OnedCode128Writer();
+ CBC_OnedCode128Writer(BC_TYPE type);
+ virtual ~CBC_OnedCode128Writer();
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE * Encode(const CFX_ByteString &contents, FX_INT32 &outLength , FX_INT32 &e);
+ FX_BOOL CheckContentValidity(FX_WSTR contents);
+ CFX_WideString FilterContents(FX_WSTR contents);
+ FX_BOOL SetTextLocation(BC_TEXT_LOC location);
+ BC_TYPE GetType();
+private:
+ FX_BOOL IsDigits(const CFX_ByteString &contents, FX_INT32 start, FX_INT32 length);
+ FX_INT32 Encode128B(const CFX_ByteString &contents, CFX_PtrArray &patterns);
+ FX_INT32 Encode128C(const CFX_ByteString &contents, CFX_PtrArray &patterns);
+ BC_TYPE m_codeFormat;
+ const static FX_INT32 CODE_START_B;
+ const static FX_INT32 CODE_START_C;
+ const static FX_INT32 CODE_CODE_B;
+ const static FX_INT32 CODE_CODE_C;
+ const static FX_INT32 CODE_STOP;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedCode39Reader.h b/xfa/src/fxbarcode/src/include/BC_OnedCode39Reader.h
new file mode 100644
index 0000000000..81fd6b79e9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedCode39Reader.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDCODA39READER_H_
+#define _BC_ONEDCODA39READER_H_
+class CBC_OneDReader;
+class CBC_CommonBitArray;
+class CBC_OnedCoda39Reader;
+class CBC_OnedCode39Reader : public CBC_OneDReader
+{
+public:
+ static FX_LPCSTR ALPHABET_STRING;
+ static FX_LPCSTR CHECKSUM_STRING;
+ const static FX_INT32 CHARACTER_ENCODINGS[44];
+ const static FX_INT32 ASTERISK_ENCODING;
+ CBC_OnedCode39Reader();
+ CBC_OnedCode39Reader(FX_BOOL usingCheckDigit);
+ CBC_OnedCode39Reader(FX_BOOL usingCheckDigit, FX_BOOL extendedMode);
+ virtual ~CBC_OnedCode39Reader();
+ CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e);
+private:
+ FX_BOOL m_usingCheckDigit;
+ FX_BOOL m_extendedMode;
+ CFX_Int32Array *FindAsteriskPattern(CBC_CommonBitArray *row, FX_INT32 &e);
+ FX_INT32 ToNarrowWidePattern(CFX_Int32Array *counters);
+ FX_CHAR PatternToChar(FX_INT32 pattern, FX_INT32 &e);
+ CFX_ByteString DecodeExtended(CFX_ByteString &encoded, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedCode39Writer.h b/xfa/src/fxbarcode/src/include/BC_OnedCode39Writer.h
new file mode 100644
index 0000000000..b37d9d8e19
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedCode39Writer.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDCODA39WRITER_H_
+#define _BC_ONEDCODA39WRITER_H_
+enum BC_TEXT_LOC;
+class CBC_OneDimWriter;
+class CBC_OnedCoda39Writer;
+class CBC_OnedCode39Writer : public CBC_OneDimWriter
+{
+public:
+ CBC_OnedCode39Writer();
+ CBC_OnedCode39Writer(FX_BOOL extendedMode);
+ virtual ~CBC_OnedCode39Writer();
+ FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ FX_BYTE *Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e);
+ void RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e);
+ CFX_WideString encodedContents(FX_WSTR contents, FX_INT32 &e);
+ FX_BOOL CheckContentValidity(FX_WSTR contents);
+ FX_BOOL CheckExtendedContentValidity(FX_WSTR contents);
+ CFX_WideString FilterContents(FX_WSTR contents);
+ CFX_WideString FilterExtendedContents(FX_WSTR contents);
+ CFX_WideString RenderTextContents(FX_WSTR contents);
+ CFX_WideString RenderExtendedTextContents(FX_WSTR contents);
+ FX_BOOL SetTextLocation(BC_TEXT_LOC loction);
+ FX_BOOL SetWideNarrowRatio(FX_INT32 ratio);
+private:
+ void ToIntArray(FX_INT32 a, FX_INT32 *toReturn);
+ FX_CHAR CalcCheckSum(const CFX_ByteString &contents, FX_INT32 &e);
+ FX_INT32 m_iWideNarrRatio;
+ FX_BOOL m_extendedMode;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedEAN13Reader.h b/xfa/src/fxbarcode/src/include/BC_OnedEAN13Reader.h
new file mode 100644
index 0000000000..9afb9b6418
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedEAN13Reader.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDEAN13READER_H_
+#define _BC_ONEDEAN13READER_H_
+class CBC_OneDimReader;
+class CBC_CommonBitArray;
+class CBC_OnedEAN13Reader;
+class CBC_OnedEAN13Reader : public CBC_OneDimReader
+{
+public:
+ const static FX_INT32 FIRST_DIGIT_ENCODINGS[10];
+ CBC_OnedEAN13Reader();
+ virtual ~CBC_OnedEAN13Reader();
+private:
+ void DetermineFirstDigit(CFX_ByteString &result, FX_INT32 lgPatternFound, FX_INT32 &e);
+protected:
+ FX_INT32 DecodeMiddle(CBC_CommonBitArray *row, CFX_Int32Array *startRange, CFX_ByteString &resultString, FX_INT32 &e);
+ friend class CBC_OnedUPCAReader;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedEAN13Writer.h b/xfa/src/fxbarcode/src/include/BC_OnedEAN13Writer.h
new file mode 100644
index 0000000000..2353cfda95
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedEAN13Writer.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDEAN13WRITER_H_
+#define _BC_ONEDEAN13WRITER_H_
+class CBC_OneDimWriter;
+class CBC_OnedEAN13Writer;
+class CBC_OnedEAN13Writer : public CBC_OneDimWriter
+{
+private:
+ FX_INT32 m_codeWidth;
+public:
+ CBC_OnedEAN13Writer();
+ virtual ~CBC_OnedEAN13Writer();
+
+ FX_BYTE* Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE* Encode(const CFX_ByteString &contents, BCFORMAT format,
+ FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ FX_BYTE* Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e);
+ void RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL CheckContentValidity(FX_WSTR contents);
+ CFX_WideString FilterContents(FX_WSTR contents);
+ FX_INT32 CalcChecksum(const CFX_ByteString &contents);
+protected:
+ void ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedEAN8Reader.h b/xfa/src/fxbarcode/src/include/BC_OnedEAN8Reader.h
new file mode 100644
index 0000000000..a32bb63083
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedEAN8Reader.h
@@ -0,0 +1,20 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDEAN8READER_H_
+#define _BC_ONEDEAN8READER_H_
+class CBC_OneDimReader;
+class CBC_CommonBitArray;
+class CBC_OnedEAN8Reader;
+class CBC_OnedEAN8Reader : public CBC_OneDimReader
+{
+public:
+ CBC_OnedEAN8Reader();
+ virtual ~CBC_OnedEAN8Reader();
+protected:
+ FX_INT32 DecodeMiddle(CBC_CommonBitArray*, CFX_Int32Array *startRange, CFX_ByteString &result, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedEAN8Writer.h b/xfa/src/fxbarcode/src/include/BC_OnedEAN8Writer.h
new file mode 100644
index 0000000000..2b55734538
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedEAN8Writer.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDEAN8WRITER_H_
+#define _BC_ONEDEAN8WRITER_H_
+enum BC_TEXT_LOC;
+class CBC_OneDimWriter;
+class CBC_OnedEAN8Writer;
+class CBC_OnedEAN8Writer : public CBC_OneDimWriter
+{
+private:
+ FX_INT32 m_codeWidth;
+public:
+ CBC_OnedEAN8Writer();
+ virtual ~CBC_OnedEAN8Writer();
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight , FX_INT32 &e);
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints , FX_INT32 &e);
+ FX_BYTE * Encode(const CFX_ByteString &contents, FX_INT32 &outLength, FX_INT32 &e);
+ void RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL CheckContentValidity(FX_WSTR contents);
+ CFX_WideString FilterContents(FX_WSTR contents);
+ void SetDataLength(FX_INT32 length);
+ FX_BOOL SetTextLocation(BC_TEXT_LOC location);
+ FX_INT32 CalcChecksum(const CFX_ByteString &contents);
+protected:
+
+ void ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedUPCAReader.h b/xfa/src/fxbarcode/src/include/BC_OnedUPCAReader.h
new file mode 100644
index 0000000000..5df6c739ff
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedUPCAReader.h
@@ -0,0 +1,30 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDUPCAREADER_H_
+#define _BC_ONEDUPCAREADER_H_
+class CBC_BinaryBitmap;
+class CBC_CommonBitArray;
+class CBC_OneDimReader;
+class CBC_OnedEAN13Reader;
+class CBC_OnedUPCAReader;
+class CBC_OnedUPCAReader : public CBC_OneDimReader
+{
+private:
+ CBC_OnedEAN13Reader *m_ean13Reader;
+public:
+ CBC_OnedUPCAReader();
+ virtual ~CBC_OnedUPCAReader();
+ CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, FX_INT32 hints, FX_INT32 &e);
+ CFX_ByteString DecodeRow(FX_INT32 rowNumber, CBC_CommonBitArray *row, CFX_Int32Array *startGuardRange, FX_INT32 hints, FX_INT32 &e);
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 &e);
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e);
+ virtual void Init();
+protected:
+ FX_INT32 DecodeMiddle(CBC_CommonBitArray *row, CFX_Int32Array *startRange, CFX_ByteString &resultString, FX_INT32 &e);
+ CFX_ByteString MaybeReturnResult(CFX_ByteString &result, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_OnedUPCAWriter.h b/xfa/src/fxbarcode/src/include/BC_OnedUPCAWriter.h
new file mode 100644
index 0000000000..4174ceb36e
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_OnedUPCAWriter.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_ONEDUPCAWRITER_H_
+#define _BC_ONEDUPCAWRITER_H_
+class CBC_Writer;
+class CBC_OnedEAN13Writer;
+class CBC_OnedUPCAWriter;
+class CBC_OnedUPCAWriter : public CBC_OneDimWriter
+{
+private:
+ CBC_OnedEAN13Writer *m_subWriter;
+public:
+ CBC_OnedUPCAWriter();
+ virtual ~CBC_OnedUPCAWriter();
+ virtual void Init();
+ FX_BYTE* Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE* Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ void RenderResult(FX_WSTR contents, FX_BYTE* code, FX_INT32 codeLength, FX_BOOL isDevice, FX_INT32 &e);
+ FX_BOOL CheckContentValidity(FX_WSTR contents);
+ CFX_WideString FilterContents(FX_WSTR contents);
+ FX_INT32 CalcChecksum(const CFX_ByteString &contents);
+
+protected:
+
+ void ShowChars(FX_WSTR contents, CFX_DIBitmap *pOutBitmap, CFX_RenderDevice* device, const CFX_Matrix* matrix, FX_INT32 barWidth, FX_INT32 multiple, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417.h b/xfa/src/fxbarcode/src/include/BC_PDF417.h
new file mode 100644
index 0000000000..ab31244add
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417.h
@@ -0,0 +1,45 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417_H_
+#define _BC_PDF417_H_
+class CBC_Compaction;
+class CBC_BarcodeRow;
+class CBC_BarcodeMatrix;
+class CBC_PDF417;
+class CBC_PDF417 : public CFX_Object
+{
+public:
+ CBC_PDF417();
+ CBC_PDF417(FX_BOOL compact);
+ virtual ~CBC_PDF417();
+ CBC_BarcodeMatrix* getBarcodeMatrix();
+ void generateBarcodeLogic(CFX_WideString msg, FX_INT32 errorCorrectionLevel, FX_INT32 &e);
+ void setDimensions(FX_INT32 maxCols, FX_INT32 minCols, FX_INT32 maxRows, FX_INT32 minRows);
+ void setCompaction(Compaction compaction);
+ void setCompact(FX_BOOL compact);
+private:
+ static FX_INT32 START_PATTERN;
+ static FX_INT32 STOP_PATTERN;
+ static FX_INT32 CODEWORD_TABLE[][1000];
+ static FX_FLOAT PREFERRED_RATIO;
+ static FX_FLOAT DEFAULT_MODULE_WIDTH;
+ static FX_FLOAT HEIGHT;
+ CBC_BarcodeMatrix* m_barcodeMatrix;
+ FX_BOOL m_compact;
+ Compaction m_compaction;
+ FX_INT32 m_minCols;
+ FX_INT32 m_maxCols;
+ FX_INT32 m_maxRows;
+ FX_INT32 m_minRows;
+private:
+ static FX_INT32 calculateNumberOfRows(FX_INT32 m, FX_INT32 k, FX_INT32 c);
+ static FX_INT32 getNumberOfPadCodewords(FX_INT32 m, FX_INT32 k, FX_INT32 c, FX_INT32 r);
+ static void encodeChar(FX_INT32 pattern, FX_INT32 len, CBC_BarcodeRow* logic);
+ void encodeLowLevel(CFX_WideString fullCodewords, FX_INT32 c, FX_INT32 r, FX_INT32 errorCorrectionLevel, CBC_BarcodeMatrix* logic);
+ CFX_Int32Array* determineDimensions(FX_INT32 sourceCodeWords, FX_INT32 errorCorrectionCodeWords, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMatrix.h b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMatrix.h
new file mode 100644
index 0000000000..d8a0c5d0ae
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMatrix.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BARCODEMATRIX_H_
+#define _BC_BARCODEMATRIX_H_
+class CBC_BarcodeRow;
+class CBC_BarcodeMatrix;
+class CBC_BarcodeMatrix : public CFX_Object
+{
+public:
+ CBC_BarcodeMatrix();
+ CBC_BarcodeMatrix(FX_INT32 height, FX_INT32 width);
+ virtual ~CBC_BarcodeMatrix();
+ void set(FX_INT32 x, FX_INT32 y, FX_BYTE value);
+ void setMatrix(FX_INT32 x, FX_INT32 y, FX_BOOL black);
+ void startRow();
+ CBC_BarcodeRow* getCurrentRow();
+ CFX_ByteArray& getMatrix();
+ CFX_ByteArray& getScaledMatrix(FX_INT32 scale);
+ CFX_ByteArray& getScaledMatrix(FX_INT32 xScale, FX_INT32 yScale);
+ FX_INT32 getWidth();
+ FX_INT32 getHeight();
+private:
+ CFX_PtrArray m_matrix;
+ CFX_ByteArray m_matrixOut;
+ FX_INT32 m_currentRow;
+ FX_INT32 m_height;
+ FX_INT32 m_width;
+ FX_INT32 m_outWidth;
+ FX_INT32 m_outHeight;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMetadata.h b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMetadata.h
new file mode 100644
index 0000000000..62b1282827
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeMetadata.h
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BARCODEMETADATA_H_
+#define _BC_BARCODEMETADATA_H_
+class CBC_BarcodeMetadata;
+class CBC_BarcodeMetadata : public CFX_Object
+{
+public:
+ CBC_BarcodeMetadata(FX_INT32 columnCount, FX_INT32 rowCountUpperPart, FX_INT32 rowCountLowerPart, FX_INT32 errorCorrectionLevel);
+ virtual ~CBC_BarcodeMetadata();
+ FX_INT32 getColumnCount();
+ FX_INT32 getErrorCorrectionLevel();
+ FX_INT32 getRowCount();
+ FX_INT32 getRowCountUpperPart();
+ FX_INT32 getRowCountLowerPart();
+private:
+ FX_INT32 m_columnCount;
+ FX_INT32 m_errorCorrectionLevel;
+ FX_INT32 m_rowCountUpperPart;
+ FX_INT32 m_rowCountLowerPart;
+ FX_INT32 m_rowCount;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeRow.h b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeRow.h
new file mode 100644
index 0000000000..75fd15b653
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeRow.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BARCODEROW_H_
+#define _BC_BARCODEROW_H_
+class CBC_BarcodeRow;
+class CBC_BarcodeRow : public CFX_Object
+{
+public:
+ CBC_BarcodeRow(FX_INT32 width);
+ virtual ~CBC_BarcodeRow();
+ void set(FX_INT32 x, FX_BYTE value);
+ void set(FX_INT32 x, FX_BOOL black);
+ void addBar(FX_BOOL black, FX_INT32 width);
+ CFX_ByteArray& getRow();
+ CFX_ByteArray& getScaledRow(FX_INT32 scale);
+private:
+ CFX_ByteArray m_row;
+ CFX_ByteArray m_output;
+ FX_INT32 m_currentLocation;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeValue.h b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeValue.h
new file mode 100644
index 0000000000..1695c8ac5a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417BarcodeValue.h
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BARCODEVALUE_H_
+#define _BC_BARCODEVALUE_H_
+class CBC_BarcodeValue;
+class CBC_BarcodeValue : public CFX_Object
+{
+public:
+ CBC_BarcodeValue();
+ virtual ~CBC_BarcodeValue();
+ void setValue(FX_INT32 value);
+ CFX_Int32Array* getValue();
+ FX_INT32 getConfidence(FX_INT32 value);
+private:
+ CFX_Int32Array m_keys;
+ CFX_Int32Array m_values;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417BoundingBox.h b/xfa/src/fxbarcode/src/include/BC_PDF417BoundingBox.h
new file mode 100644
index 0000000000..efae2b706f
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417BoundingBox.h
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_BOUNDINGBOX_H_
+#define _BC_BOUNDINGBOX_H_
+class CBC_CommonBitMatrix;
+class CBC_ResultPoint;
+class CBC_BoundingBox;
+class CBC_BoundingBox : public CFX_Object
+{
+public:
+ CBC_BoundingBox(CBC_CommonBitMatrix* image, CBC_ResultPoint* topLeft, CBC_ResultPoint* bottomLeft, CBC_ResultPoint* topRight, CBC_ResultPoint* bottomRight, FX_INT32 &e);
+ CBC_BoundingBox(CBC_BoundingBox* boundingBox);
+ virtual ~CBC_BoundingBox();
+ static CBC_BoundingBox* merge(CBC_BoundingBox* leftBox, CBC_BoundingBox* rightBox, FX_INT32 &e);
+ CBC_BoundingBox* addMissingRows(FX_INT32 missingStartRows, FX_INT32 missingEndRows, FX_BOOL isLeft, FX_INT32 &e);
+ void setTopRight(CBC_ResultPoint topRight);
+ void setBottomRight(CBC_ResultPoint bottomRight);
+ FX_INT32 getMinX();
+ FX_INT32 getMaxX();
+ FX_INT32 getMinY();
+ FX_INT32 getMaxY();
+ CBC_ResultPoint* getTopLeft();
+ CBC_ResultPoint* getTopRight();
+ CBC_ResultPoint* getBottomLeft();
+ CBC_ResultPoint* getBottomRight();
+private:
+ CBC_CommonBitMatrix* m_image;
+ CBC_ResultPoint* m_topLeft;
+ CBC_ResultPoint* m_bottomLeft;
+ CBC_ResultPoint* m_topRight;
+ CBC_ResultPoint* m_bottomRight;
+ FX_INT32 m_minX;
+ FX_INT32 m_maxX;
+ FX_INT32 m_minY;
+ FX_INT32 m_maxY;
+ void init(CBC_CommonBitMatrix* image, CBC_ResultPoint* topLeft, CBC_ResultPoint* bottomLeft, CBC_ResultPoint* topRight, CBC_ResultPoint* bottomRight);
+ void calculateMinMaxValues();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417Codeword.h b/xfa/src/fxbarcode/src/include/BC_PDF417Codeword.h
new file mode 100644
index 0000000000..93b3cf6bb3
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417Codeword.h
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_CODEWORD_H_
+#define _BC_CODEWORD_H_
+class CBC_Codeword;
+class CBC_Codeword : public CFX_Object
+{
+public:
+ CBC_Codeword(FX_INT32 startX, FX_INT32 endX, FX_INT32 bucket, FX_INT32 value);
+ virtual ~CBC_Codeword();
+ FX_BOOL hasValidRowNumber() ;
+ FX_BOOL isValidRowNumber(FX_INT32 rowNumber);
+ void setRowNumberAsRowIndicatorColumn();
+ FX_INT32 getWidth();
+ FX_INT32 getStartX();
+ FX_INT32 getEndX();
+ FX_INT32 getBucket();
+ FX_INT32 getValue();
+ FX_INT32 getRowNumber();
+ void setRowNumber(FX_INT32 rowNumber);
+ CFX_ByteString toString();
+private:
+ static FX_INT32 BARCODE_ROW_UNKNOWN;
+ FX_INT32 m_startX;
+ FX_INT32 m_endX;
+ FX_INT32 m_bucket;
+ FX_INT32 m_value;
+ FX_INT32 m_rowNumber;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417CodewordDecoder.h b/xfa/src/fxbarcode/src/include/BC_PDF417CodewordDecoder.h
new file mode 100644
index 0000000000..da22683bfa
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417CodewordDecoder.h
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417CODEWORDDECODER_H_
+#define _BC_PDF417CODEWORDDECODER_H_
+class CBC_PDF417Common;
+class CBC_PDF417CodewordDecoder;
+#define column 8
+class CBC_PDF417CodewordDecoder : public CFX_Object
+{
+public:
+ CBC_PDF417CodewordDecoder();
+ virtual ~CBC_PDF417CodewordDecoder();
+ static void Initialize();
+ static void Finalize();
+ static FX_INT32 getDecodedValue(CFX_Int32Array& moduleBitCount);
+private:
+ static FX_FLOAT RATIOS_TABLE[][8];
+ static CFX_Int32Array* sampleBitCounts(CFX_Int32Array& moduleBitCount);
+ static FX_INT32 getDecodedCodewordValue(CFX_Int32Array& moduleBitCount);
+ static FX_INT32 getBitValue(CFX_Int32Array& moduleBitCount);
+ static FX_INT32 getClosestDecodedValue(CFX_Int32Array& moduleBitCount);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417Common.h b/xfa/src/fxbarcode/src/include/BC_PDF417Common.h
new file mode 100644
index 0000000000..19e3fe57da
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417Common.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417COMMON_H_
+#define _BC_PDF417COMMON_H_
+class CBC_PDF417Common;
+class CBC_PDF417Common : public CFX_Object
+{
+public:
+ CBC_PDF417Common();
+ virtual ~CBC_PDF417Common();
+ static FX_INT32 getBitCountSum(CFX_Int32Array& moduleBitCount);
+ static FX_INT32 getCodeword(FX_DWORD symbol);
+ static FX_INT32 NUMBER_OF_CODEWORDS;
+ static FX_INT32 MAX_CODEWORDS_IN_BARCODE;
+ static FX_INT32 MIN_ROWS_IN_BARCODE;
+ static FX_INT32 MAX_ROWS_IN_BARCODE;
+ static FX_INT32 MAX_CODEWORDS_IN_ROW;
+ static FX_INT32 MODULES_IN_CODEWORD;
+ static FX_INT32 MODULES_IN_STOP_PATTERN;
+ static FX_INT32 BARS_IN_MODULE;
+ static FX_INT32 SYMBOL_TABLE[];
+ static FX_INT32 CODEWORD_TABLE[];
+private:
+ static CFX_Int32Array* EMPTY_INT_ARRAY;
+ static FX_INT32 findCodewordIndex(FX_DWORD symbol);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417Compaction.h b/xfa/src/fxbarcode/src/include/BC_PDF417Compaction.h
new file mode 100644
index 0000000000..774a23fbdf
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417Compaction.h
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_COMPACTION_H_
+#define _BC_COMPACTION_H_
+class CBC_Compaction;
+enum Compaction {
+ AUTO,
+ TEXT,
+ BYTES,
+ NUMERIC
+};
+class CBC_Compaction : public CFX_Object
+{
+public:
+ CBC_Compaction();
+ virtual ~CBC_Compaction();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417DecodedBitStreamParser.h b/xfa/src/fxbarcode/src/include/BC_PDF417DecodedBitStreamParser.h
new file mode 100644
index 0000000000..a612769106
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417DecodedBitStreamParser.h
@@ -0,0 +1,49 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DECODEDBITSTREAMPARSER_H_
+#define _BC_DECODEDBITSTREAMPARSER_H_
+class CBC_CommonDecoderResult;
+class CBC_PDF417ResultMetadata;
+class CBC_DecodedBitStreamPaser;
+class CBC_DecodedBitStreamPaser : public CFX_Object
+{
+public:
+ CBC_DecodedBitStreamPaser();
+ virtual ~CBC_DecodedBitStreamPaser();
+ static void Initialize();
+ static void Finalize();
+ static CBC_CommonDecoderResult* decode(CFX_Int32Array &codewords, CFX_ByteString ecLevel, FX_INT32 &e);
+
+private:
+ enum Mode {
+ ALPHA,
+ LOWER,
+ MIXED,
+ PUNCT,
+ ALPHA_SHIFT,
+ PUNCT_SHIFT
+ };
+ static FX_INT32 MAX_NUMERIC_CODEWORDS;
+ static FX_INT32 PL;
+ static FX_INT32 LL;
+ static FX_INT32 AS;
+ static FX_INT32 ML;
+ static FX_INT32 AL;
+ static FX_INT32 PS;
+ static FX_INT32 PAL;
+ static FX_CHAR PUNCT_CHARS[29];
+ static FX_CHAR MIXED_CHARS[30];
+ static FX_INT32 EXP900[16];
+ static FX_INT32 NUMBER_OF_SEQUENCE_CODEWORDS;
+ static FX_INT32 decodeMacroBlock(CFX_Int32Array &codewords, FX_INT32 codeIndex, CBC_PDF417ResultMetadata* resultMetadata, FX_INT32 &e);
+ static FX_INT32 textCompaction(CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result);
+ static void decodeTextCompaction(CFX_Int32Array &textCompactionData, CFX_Int32Array &byteCompactionData, FX_INT32 length, CFX_ByteString &result);
+ static FX_INT32 byteCompaction(FX_INT32 mode, CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result);
+ static FX_INT32 numericCompaction(CFX_Int32Array &codewords, FX_INT32 codeIndex, CFX_ByteString &result, FX_INT32 &e);
+ static CFX_ByteString decodeBase900toBase10(CFX_Int32Array &codewords, FX_INT32 count, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResult.h b/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResult.h
new file mode 100644
index 0000000000..9c3401459b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResult.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_EDTECTIONRESULT_H_
+#define _BC_EDTECTIONRESULT_H_
+class CBC_BarcodeMetadata;
+class CBC_BoundingBox;
+class CBC_Codeword;
+class CBC_DetectionResultColumn;
+class CBC_DetectionResult;
+class CBC_DetectionResult : public CFX_Object
+{
+public:
+ CBC_DetectionResult(CBC_BarcodeMetadata* barcodeMetadata, CBC_BoundingBox* boundingBox);
+ virtual ~CBC_DetectionResult();
+ CFX_PtrArray& getDetectionResultColumns();
+ void setBoundingBox(CBC_BoundingBox* boundingBox);
+ CBC_BoundingBox* getBoundingBox();
+ void setDetectionResultColumn(FX_INT32 barcodeColumn, CBC_DetectionResultColumn* detectionResultColumn);
+ CBC_DetectionResultColumn* getDetectionResultColumn(FX_INT32 barcodeColumn);
+ CFX_ByteString toString();
+
+ FX_INT32 getBarcodeColumnCount();
+ FX_INT32 getBarcodeRowCount();
+ FX_INT32 getBarcodeECLevel();
+private:
+ static FX_INT32 ADJUST_ROW_NUMBER_SKIP;
+ CBC_BarcodeMetadata* m_barcodeMetadata;
+ CFX_PtrArray m_detectionResultColumns;
+ CBC_BoundingBox* m_boundingBox;
+ FX_INT32 m_barcodeColumnCount;
+private:
+ void adjustIndicatorColumnRowNumbers(CBC_DetectionResultColumn* detectionResultColumn);
+ FX_INT32 adjustRowNumbers();
+ FX_INT32 adjustRowNumbersByRow();
+ FX_INT32 adjustRowNumbersFromBothRI();
+ FX_INT32 adjustRowNumbersFromRRI();
+ FX_INT32 adjustRowNumbersFromLRI();
+ static FX_INT32 adjustRowNumberIfValid(FX_INT32 rowIndicatorRowNumber, FX_INT32 invalidRowCounts, CBC_Codeword* codeword);
+ void adjustRowNumbers(FX_INT32 barcodeColumn, FX_INT32 codewordsRow, CFX_PtrArray* codewords);
+ static FX_BOOL adjustRowNumber(CBC_Codeword* codeword, CBC_Codeword* otherCodeword);
+
+
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultColumn.h b/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultColumn.h
new file mode 100644
index 0000000000..eddc3bce6d
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultColumn.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DETECTIONRESULTCOLUMN_H_
+#define _BC_DETECTIONRESULTCOLUMN_H_
+class CBC_Codeword;
+class CBC_BoundingBox;
+class CBC_DetectionResultColumn;
+class CBC_DetectionResultColumn : public CFX_Object
+{
+public:
+ CBC_DetectionResultColumn(CBC_BoundingBox* boundingBox);
+ virtual ~CBC_DetectionResultColumn();
+ CBC_Codeword* getCodewordNearby(FX_INT32 imageRow);
+ FX_INT32 imageRowToCodewordIndex(FX_INT32 imageRow);
+ FX_INT32 codewordIndexToImageRow(FX_INT32 codewordIndex);
+ void setCodeword(FX_INT32 imageRow, CBC_Codeword* codeword);
+ CBC_Codeword* getCodeword(FX_INT32 imageRow);
+ CBC_BoundingBox* getBoundingBox();
+ CFX_PtrArray* getCodewords();
+ CFX_ByteString toString();
+public:
+ CBC_BoundingBox* m_boundingBox;
+ CFX_PtrArray* m_codewords;
+private:
+ static FX_INT32 MAX_NEARBY_DISTANCE;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultRowIndicatorColumn.h b/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultRowIndicatorColumn.h
new file mode 100644
index 0000000000..fbdd0f0ec4
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417DetectionResultRowIndicatorColumn.h
@@ -0,0 +1,28 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DETECTIONRESULTROWINDICATORCOLUMN_H_
+#define _BC_DETECTIONRESULTROWINDICATORCOLUMN_H_
+class CBC_BarcodeMetadata;
+class CBC_BoundingBox;
+class CBC_DetectionResultRowIndicatorColumn;
+class CBC_DetectionResultRowIndicatorColumn : public CBC_DetectionResultColumn
+{
+public:
+ CBC_DetectionResultRowIndicatorColumn(CBC_BoundingBox* boundingBox, FX_BOOL isLeft);
+ virtual ~CBC_DetectionResultRowIndicatorColumn();
+ void setRowNumbers();
+ FX_INT32 adjustCompleteIndicatorColumnRowNumbers(CBC_BarcodeMetadata barcodeMetadata);
+ CFX_Int32Array* getRowHeights(FX_INT32 &e);
+ FX_INT32 adjustIncompleteIndicatorColumnRowNumbers(CBC_BarcodeMetadata barcodeMetadata);
+ CBC_BarcodeMetadata* getBarcodeMetadata();
+ FX_BOOL isLeft();
+ CFX_ByteString toString();
+private:
+ FX_BOOL m_isLeft;
+ void removeIncorrectCodewords(CFX_PtrArray* codewords, CBC_BarcodeMetadata barcodeMetadata);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417Detector.h b/xfa/src/fxbarcode/src/include/BC_PDF417Detector.h
new file mode 100644
index 0000000000..557559e1f7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417Detector.h
@@ -0,0 +1,43 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DETECTOR_H_
+#define _BC_DETECTOR_H_
+class CBC_PDF417DetectorResult;
+class CBC_BinaryBitmap;
+class CBC_CommonBitMatrix;
+class CBC_CommonBitArray;
+class CBC_Detector;
+class CBC_Detector : public CFX_Object
+{
+public:
+ CBC_Detector();
+ virtual ~CBC_Detector();
+ static CBC_PDF417DetectorResult* detect(CBC_BinaryBitmap* image, FX_INT32 hints, FX_BOOL multiple, FX_INT32 &e);
+ static void rotate180(CBC_CommonBitMatrix* bitMatrix);
+ static CBC_CommonBitArray* mirror(CBC_CommonBitArray* input, CBC_CommonBitArray* result);
+private:
+ static FX_INT32 INDEXES_START_PATTERN[];
+ static FX_INT32 INDEXES_STOP_PATTERN[];
+ static FX_INT32 INTEGER_MATH_SHIFT;
+ static FX_INT32 PATTERN_MATCH_RESULT_SCALE_FACTOR;
+ static FX_INT32 MAX_AVG_VARIANCE;
+ static FX_INT32 MAX_INDIVIDUAL_VARIANCE;
+ static FX_INT32 START_PATTERN[];
+ static FX_INT32 STOP_PATTERN[];
+ static FX_INT32 MAX_PIXEL_DRIFT;
+ static FX_INT32 MAX_PATTERN_DRIFT;
+ static FX_INT32 SKIPPED_ROW_COUNT_MAX;
+ static FX_INT32 ROW_STEP;
+ static FX_INT32 BARCODE_MIN_HEIGHT;
+ static CFX_PtrArray* detect(FX_BOOL multiple, CBC_CommonBitMatrix* bitMatrix);
+ static CFX_PtrArray* findVertices(CBC_CommonBitMatrix* matrix, FX_INT32 startRow, FX_INT32 startColumn);
+ static void copyToResult(CFX_PtrArray* result, CFX_PtrArray* tmpResult, FX_INT32* destinationIndexes, FX_INT32 destinationLength);
+ static CFX_PtrArray* findRowsWithPattern(CBC_CommonBitMatrix* matrix, FX_INT32 height, FX_INT32 width, FX_INT32 startRow, FX_INT32 startColumn, FX_INT32* pattern, FX_INT32 patternLength);
+ static CFX_Int32Array* findGuardPattern(CBC_CommonBitMatrix* matrix, FX_INT32 column, FX_INT32 row, FX_INT32 width, FX_BOOL whiteFirst, FX_INT32* pattern, FX_INT32 patternLength, CFX_Int32Array &counters);
+ static FX_INT32 patternMatchVariance(CFX_Int32Array &counters, FX_INT32* pattern, FX_INT32 maxIndividualVariance);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417DetectorResult.h b/xfa/src/fxbarcode/src/include/BC_PDF417DetectorResult.h
new file mode 100644
index 0000000000..ba557f1541
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417DetectorResult.h
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417DETECTORRESULT_H_
+#define _BC_PDF417DETECTORRESULT_H_
+class CBC_CommonBitMatrix;
+class CBC_PDF417DetectorResult;
+class CBC_PDF417DetectorResult : public CFX_Object
+{
+public:
+ CBC_PDF417DetectorResult(CBC_CommonBitMatrix* bits, CFX_PtrArray* points);
+ virtual ~CBC_PDF417DetectorResult();
+ CBC_CommonBitMatrix* getBits() ;
+ CFX_PtrArray* getPoints();
+private:
+ CBC_CommonBitMatrix* m_bits;
+ CFX_PtrArray* m_points;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417Dimensions.h b/xfa/src/fxbarcode/src/include/BC_PDF417Dimensions.h
new file mode 100644
index 0000000000..6f8eaffed7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417Dimensions.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_DIMENSIONS_H_
+#define _BC_DIMENSIONS_H_
+class CBC_Dimensions;
+class CBC_Dimensions : public CFX_Object
+{
+public:
+ CBC_Dimensions(FX_INT32 minCols, FX_INT32 maxCols, FX_INT32 minRows, FX_INT32 maxRows);
+ virtual ~CBC_Dimensions();
+ FX_INT32 getMinCols();
+ FX_INT32 getMaxCols();
+ FX_INT32 getMinRows();
+ FX_INT32 getMaxRows();
+private:
+ FX_INT32 m_minCols;
+ FX_INT32 m_maxCols;
+ FX_INT32 m_minRows;
+ FX_INT32 m_maxRows;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417ECErrorCorrection.h b/xfa/src/fxbarcode/src/include/BC_PDF417ECErrorCorrection.h
new file mode 100644
index 0000000000..4ce8eda7d6
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417ECErrorCorrection.h
@@ -0,0 +1,26 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417ECERRORCORRECTION_H_
+#define _BC_PDF417ECERRORCORRECTION_H_
+class CBC_PDF417ECModulusGF;
+class CBC_PDF417ECModulusPoly;
+class CBC_PDF417ECErrorCorrection;
+class CBC_PDF417ECErrorCorrection : public CFX_Object
+{
+public:
+ CBC_PDF417ECErrorCorrection();
+ virtual ~CBC_PDF417ECErrorCorrection();
+ static void Initialize(FX_INT32 &e);
+ static void Finalize();
+ static FX_INT32 decode(CFX_Int32Array &received, FX_INT32 numECCodewords, CFX_Int32Array &erasures, FX_INT32 &e);
+private:
+ static CBC_PDF417ECModulusGF* m_field;
+ static CFX_PtrArray* runEuclideanAlgorithm(CBC_PDF417ECModulusPoly* a, CBC_PDF417ECModulusPoly* b, FX_INT32 R, FX_INT32 &e);
+ static CFX_Int32Array* findErrorLocations(CBC_PDF417ECModulusPoly* errorLocator, FX_INT32 &e);
+ static CFX_Int32Array* findErrorMagnitudes(CBC_PDF417ECModulusPoly* errorEvaluator, CBC_PDF417ECModulusPoly* errorLocator, CFX_Int32Array &errorLocations, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417ECModulusGF.h b/xfa/src/fxbarcode/src/include/BC_PDF417ECModulusGF.h
new file mode 100644
index 0000000000..7ebe33ecfd
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417ECModulusGF.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417ECMODULUSGF_H_
+#define _BC_PDF417ECMODULUSGF_H_
+class CBC_PDF417ECModulusPoly;
+class CBC_PDF417Common;
+class CBC_PDF417ECModulusGF;
+class CBC_PDF417ECModulusGF : public CFX_Object
+{
+public:
+ CBC_PDF417ECModulusGF(FX_INT32 modulus, FX_INT32 generator, FX_INT32 &e);
+ virtual ~CBC_PDF417ECModulusGF();
+ static void Initialize(FX_INT32 &e);
+ static void Finalize();
+ CBC_PDF417ECModulusPoly* getZero();
+ CBC_PDF417ECModulusPoly* getOne();
+ CBC_PDF417ECModulusPoly* buildMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e);
+ FX_INT32 add(FX_INT32 a, FX_INT32 b);
+ FX_INT32 subtract(FX_INT32 a, FX_INT32 b);
+ FX_INT32 exp(FX_INT32 a);
+ FX_INT32 log(FX_INT32 a, FX_INT32 &e);
+ FX_INT32 inverse(FX_INT32 a, FX_INT32 &e);
+ FX_INT32 multiply(FX_INT32 a, FX_INT32 b);
+ FX_INT32 getSize();
+ static CBC_PDF417ECModulusGF* PDF417_GF;
+private:
+ CFX_Int32Array m_expTable;
+ CFX_Int32Array m_logTable;
+ CBC_PDF417ECModulusPoly* m_zero;
+ CBC_PDF417ECModulusPoly* m_one;
+ FX_INT32 m_modulus;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417ECModulusPoly.h b/xfa/src/fxbarcode/src/include/BC_PDF417ECModulusPoly.h
new file mode 100644
index 0000000000..9a9d6c16f2
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417ECModulusPoly.h
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417ECMODULUSPOLY_H_
+#define _BC_PDF417ECMODULUSPOLY_H_
+class CBC_PDF417ECModulusGF;
+class CBC_PDF417ECModulusPoly;
+class CBC_PDF417ECModulusPoly : public CFX_Object
+{
+public:
+ CBC_PDF417ECModulusPoly(CBC_PDF417ECModulusGF* field, CFX_Int32Array &coefficients, FX_INT32 &e);
+ virtual ~CBC_PDF417ECModulusPoly();
+ CFX_Int32Array& getCoefficients();
+ CBC_PDF417ECModulusGF* getField();
+ FX_INT32 getDegree();
+ FX_BOOL isZero();
+ FX_INT32 getCoefficient(FX_INT32 degree);
+ FX_INT32 evaluateAt(FX_INT32 a);
+ CBC_PDF417ECModulusPoly* add(CBC_PDF417ECModulusPoly* other, FX_INT32 &e);
+ CBC_PDF417ECModulusPoly* subtract(CBC_PDF417ECModulusPoly* other, FX_INT32 &e);
+ CBC_PDF417ECModulusPoly* multiply(CBC_PDF417ECModulusPoly* other, FX_INT32 &e);
+ CBC_PDF417ECModulusPoly* negative(FX_INT32 &e);
+ CBC_PDF417ECModulusPoly* multiply(FX_INT32 scalar, FX_INT32 &e);
+ CBC_PDF417ECModulusPoly* multiplyByMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e);
+ CFX_PtrArray* divide(CBC_PDF417ECModulusPoly* other, FX_INT32 &e);
+ CFX_ByteString toString();
+private:
+ CBC_PDF417ECModulusGF* m_field;
+ CFX_Int32Array m_coefficients;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417ErrorCorrection.h b/xfa/src/fxbarcode/src/include/BC_PDF417ErrorCorrection.h
new file mode 100644
index 0000000000..4e3aee8d26
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417ErrorCorrection.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417ERRORCORRECTION_H_
+#define _BC_PDF417ERRORCORRECTION_H_
+class CBC_PDF417ErrorCorrection;
+class CBC_PDF417ErrorCorrection : public CFX_Object
+{
+public:
+ CBC_PDF417ErrorCorrection();
+ virtual ~CBC_PDF417ErrorCorrection();
+ static FX_INT32 getErrorCorrectionCodewordCount(FX_INT32 errorCorrectionLevel, FX_INT32 &e);
+ static FX_INT32 getRecommendedMinimumErrorCorrectionLevel(FX_INT32 n, FX_INT32 &e);
+ static CFX_WideString generateErrorCorrection(CFX_WideString dataCodewords, FX_INT32 errorCorrectionLevel, FX_INT32 &e);
+private:
+ static FX_INT32 EC_COEFFICIENTS[][2500];
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417HighLevelEncoder.h b/xfa/src/fxbarcode/src/include/BC_PDF417HighLevelEncoder.h
new file mode 100644
index 0000000000..4bca174bb2
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417HighLevelEncoder.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417HIGHLEVELENCODER_H_
+#define _BC_PDF417HIGHLEVELENCODER_H_
+class CBC_Compaction;
+class CBC_PDF417HighLevelEncoder;
+class CBC_PDF417HighLevelEncoder : public CFX_Object
+{
+public:
+ CBC_PDF417HighLevelEncoder();
+ virtual ~CBC_PDF417HighLevelEncoder();
+ static CFX_WideString encodeHighLevel(CFX_WideString msg, Compaction compaction, FX_INT32 &e);
+ static void Inverse();
+ static void Initialize();
+ static void Finalize();
+private:
+ static FX_INT32 TEXT_COMPACTION;
+ static FX_INT32 BYTE_COMPACTION;
+ static FX_INT32 NUMERIC_COMPACTION;
+ static FX_INT32 SUBMODE_PUNCTUATION;
+ static FX_INT32 LATCH_TO_TEXT;
+ static FX_INT32 LATCH_TO_BYTE_PADDED;
+ static FX_INT32 LATCH_TO_NUMERIC;
+ static FX_INT32 SHIFT_TO_BYTE;
+ static FX_INT32 LATCH_TO_BYTE;
+ static FX_BYTE TEXT_MIXED_RAW[];
+ static FX_BYTE TEXT_PUNCTUATION_RAW[];
+ static FX_INT32 MIXED[128];
+ static FX_INT32 PUNCTUATION[128];
+ static CFX_ByteArray* getBytesForMessage(CFX_WideString msg);
+ static FX_INT32 encodeText(CFX_WideString msg, FX_INT32 startpos, FX_INT32 count, CFX_WideString &sb, FX_INT32 initialSubmode);
+ static void encodeBinary(CFX_ByteArray* bytes, FX_INT32 startpos, FX_INT32 count, FX_INT32 startmode, CFX_WideString &sb);
+ static void encodeNumeric(CFX_WideString msg, FX_INT32 startpos, FX_INT32 count, CFX_WideString &sb);
+ static FX_BOOL isDigit(FX_WCHAR ch);
+ static FX_BOOL isAlphaUpper(FX_WCHAR ch);
+ static FX_BOOL isAlphaLower(FX_WCHAR ch);
+ static FX_BOOL isMixed(FX_WCHAR ch);
+ static FX_BOOL isPunctuation(FX_WCHAR ch);
+ static FX_BOOL isText(FX_WCHAR ch);
+ static FX_INT32 determineConsecutiveDigitCount(CFX_WideString msg, FX_INT32 startpos);
+ static FX_INT32 determineConsecutiveTextCount(CFX_WideString msg, FX_INT32 startpos);
+ static FX_INT32 determineConsecutiveBinaryCount(CFX_WideString msg, CFX_ByteArray* bytes, FX_INT32 startpos, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417Reader.h b/xfa/src/fxbarcode/src/include/BC_PDF417Reader.h
new file mode 100644
index 0000000000..e6c0236cf7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417Reader.h
@@ -0,0 +1,26 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417READER_H_
+#define _BC_PDF417READER_H_
+class CBC_BinaryBitmap;
+class CBC_ResultPoint;
+class CBC_PDF417Reader;
+class CBC_PDF417Reader : public CBC_Reader
+{
+public:
+ CBC_PDF417Reader();
+ virtual ~CBC_PDF417Reader();
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 &e);
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_BOOL multiple, FX_INT32 hints, FX_INT32 &e);
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e);
+private:
+ static FX_INT32 getMaxWidth(CBC_ResultPoint* p1, CBC_ResultPoint* p2);
+ static FX_INT32 getMinWidth(CBC_ResultPoint* p1, CBC_ResultPoint* p2);
+ static FX_INT32 getMaxCodewordWidth(CFX_PtrArray& p);
+ static FX_INT32 getMinCodewordWidth(CFX_PtrArray& p);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417ResultMetadata.h b/xfa/src/fxbarcode/src/include/BC_PDF417ResultMetadata.h
new file mode 100644
index 0000000000..e6c7780304
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417ResultMetadata.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417READER_H_
+#define _BC_PDF417READER_H_
+class CBC_PDF417ResultMetadata;
+class CBC_PDF417ResultMetadata : public CFX_Object
+{
+public:
+ CBC_PDF417ResultMetadata();
+ virtual ~CBC_PDF417ResultMetadata();
+ FX_INT32 getSegmentIndex();
+ void setSegmentIndex(FX_INT32 segmentIndex);
+ CFX_ByteString getFileId();
+ void setFileId(CFX_ByteString fileId);
+ CFX_Int32Array& getOptionalData();
+ void setOptionalData(CFX_Int32Array &optionalData);
+ FX_BOOL isLastSegment();
+ void setLastSegment(FX_BOOL lastSegment);
+private:
+ FX_INT32 m_segmentIndex;
+ CFX_ByteString m_fileId;
+ CFX_Int32Array m_optionalData;
+ FX_BOOL m_lastSegment;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417ScanningDecoder.h b/xfa/src/fxbarcode/src/include/BC_PDF417ScanningDecoder.h
new file mode 100644
index 0000000000..924e5f798a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417ScanningDecoder.h
@@ -0,0 +1,61 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417SCANNINGDECODER_H_
+#define _BC_PDF417SCANNINGDECODER_H_
+class CBC_CommonDecoderResult;
+class CBC_CommonBitMatrix;
+class CBC_ErrorCorrection;
+class CBC_Codeword;
+class CBC_BoundingBox;
+class CBC_ResultPoint;
+class CBC_BarcodeMetadata;
+class CBC_BarcodeValue;
+class CBC_DetectionResult;
+class CBC_DetectionResultRowIndicatorColumn;
+class CBC_PDF417ScanningDecoder;
+class CBC_PDF417ScanningDecoder : public CFX_Object
+{
+public:
+ CBC_PDF417ScanningDecoder();
+ virtual ~CBC_PDF417ScanningDecoder();
+ static void Initialize();
+ static void Finalize();
+ static CBC_CommonDecoderResult* decode(CBC_CommonBitMatrix* image, CBC_ResultPoint* imageTopLeft, CBC_ResultPoint* imageBottomLeft, CBC_ResultPoint* imageTopRight,
+ CBC_ResultPoint* imageBottomRight, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth, FX_INT32 &e);
+ static CFX_ByteString toString(CFX_PtrArray* barcodeMatrix);
+private:
+ static FX_INT32 CODEWORD_SKEW_SIZE;
+ static FX_INT32 MAX_ERRORS;
+ static FX_INT32 MAX_EC_CODEWORDS;
+ static CBC_PDF417ECErrorCorrection* errorCorrection;
+ static CBC_DetectionResult* merge(CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn, CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn, FX_INT32 &e);
+ static CBC_BoundingBox* adjustBoundingBox(CBC_DetectionResultRowIndicatorColumn* rowIndicatorColumn, FX_INT32 &e);
+ static FX_INT32 getMax(CFX_Int32Array& values);
+ static CBC_BarcodeMetadata* getBarcodeMetadata(CBC_DetectionResultRowIndicatorColumn* leftRowIndicatorColumn, CBC_DetectionResultRowIndicatorColumn* rightRowIndicatorColumn);
+ static CBC_DetectionResultRowIndicatorColumn* getRowIndicatorColumn(CBC_CommonBitMatrix* image, CBC_BoundingBox* boundingBox, CBC_ResultPoint startPoint,
+ FX_BOOL leftToRight, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth);
+ static void adjustCodewordCount(CBC_DetectionResult* detectionResult, CFX_PtrArray* barcodeMatrix, FX_INT32 &e);
+ static CBC_CommonDecoderResult* createDecoderResult(CBC_DetectionResult* detectionResult, FX_INT32 &e);
+ static CBC_CommonDecoderResult* createDecoderResultFromAmbiguousValues(FX_INT32 ecLevel, CFX_Int32Array &codewords, CFX_Int32Array &erasureArray, CFX_Int32Array &ambiguousIndexes,
+ CFX_PtrArray& ambiguousIndexValues, FX_INT32 &e);
+ static CFX_PtrArray* createBarcodeMatrix(CBC_DetectionResult* detectionResult);
+ static FX_BOOL isValidBarcodeColumn(CBC_DetectionResult* detectionResult, FX_INT32 barcodeColumn);
+ static FX_INT32 getStartColumn(CBC_DetectionResult* detectionResult, FX_INT32 barcodeColumn, FX_INT32 imageRow, FX_BOOL leftToRight);
+ static CBC_Codeword* detectCodeword(CBC_CommonBitMatrix* image, FX_INT32 minColumn, FX_INT32 maxColumn, FX_BOOL leftToRight, FX_INT32 startColumn,
+ FX_INT32 imageRow, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth);
+ static CFX_Int32Array* getModuleBitCount(CBC_CommonBitMatrix* image, FX_INT32 minColumn, FX_INT32 maxColumn, FX_BOOL leftToRight, FX_INT32 startColumn, FX_INT32 imageRow);
+ static FX_INT32 getNumberOfECCodeWords(FX_INT32 barcodeECLevel);
+ static FX_INT32 adjustCodewordStartColumn(CBC_CommonBitMatrix* image, FX_INT32 minColumn, FX_INT32 maxColumn, FX_BOOL leftToRight, FX_INT32 codewordStartColumn, FX_INT32 imageRow);
+ static FX_BOOL checkCodewordSkew(FX_INT32 codewordSize, FX_INT32 minCodewordWidth, FX_INT32 maxCodewordWidth);
+ static CBC_CommonDecoderResult* decodeCodewords(CFX_Int32Array &codewords, FX_INT32 ecLevel, CFX_Int32Array &erasures, FX_INT32 &e);
+ static FX_INT32 correctErrors(CFX_Int32Array &codewords, CFX_Int32Array &erasures, FX_INT32 numECCodewords, FX_INT32 &e);
+ static void verifyCodewordCount(CFX_Int32Array &codewords, FX_INT32 numECCodewords, FX_INT32 &e);
+ static CFX_Int32Array* getBitCountForCodeword(FX_INT32 codeword);
+ static FX_INT32 getCodewordBucketNumber(FX_INT32 codeword);
+ static FX_INT32 getCodewordBucketNumber(CFX_Int32Array& moduleBitCount);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_PDF417Writer.h b/xfa/src/fxbarcode/src/include/BC_PDF417Writer.h
new file mode 100644
index 0000000000..5d974f9377
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_PDF417Writer.h
@@ -0,0 +1,26 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_PDF417WRITER_H_
+#define _BC_PDF417WRITER_H_
+class CBC_TwoDimWriter;
+class CBC_PDF417Writer;
+class CBC_PDF417Writer : public CBC_TwoDimWriter
+{
+public:
+ CBC_PDF417Writer();
+ virtual ~CBC_PDF417Writer();
+ FX_BYTE * Encode(const CFX_WideString &contents, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE * Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ FX_BOOL SetErrorCorrectionLevel(FX_INT32 level);
+ void SetTruncated(FX_BOOL truncated);
+private:
+ void rotateArray(CFX_ByteArray& bitarray, FX_INT32 width, FX_INT32 height);
+ FX_BOOL m_bTruncated;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRAlignmentPattern.h b/xfa/src/fxbarcode/src/include/BC_QRAlignmentPattern.h
new file mode 100644
index 0000000000..a52687b6b7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRAlignmentPattern.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRALIGNMENTPATTERN_H_
+#define _BC_QRALIGNMENTPATTERN_H_
+class CBC_CommonBitArray;
+class CBC_ResultPoint;
+class CBC_REAI013x0x1xDecoder;
+class CBC_QRAlignmentPattern : public CBC_ResultPoint
+{
+private:
+ FX_FLOAT m_moduleSize;
+public:
+ CBC_QRAlignmentPattern(FX_FLOAT posX, FX_FLOAT posY, FX_FLOAT estimateModuleSize);
+ virtual ~CBC_QRAlignmentPattern();
+ FX_BOOL AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j);
+ FX_FLOAT GetX();
+ FX_FLOAT GetY();
+ CBC_QRAlignmentPattern *Clone();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRAlignmentPatternFinder.h b/xfa/src/fxbarcode/src/include/BC_QRAlignmentPatternFinder.h
new file mode 100644
index 0000000000..5471c4e62a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRAlignmentPatternFinder.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRALIGNMENTPATTERNFINDER_H_
+#define _BC_QRALIGNMENTPATTERNFINDER_H_
+class CBC_CommonBitMatrix;
+class CBC_QRAlignmentPattern;
+class CBC_QRAlignmentPatternFinder;
+class CBC_QRAlignmentPatternFinder : public CFX_Object
+{
+private:
+ CBC_CommonBitMatrix *m_image;
+ CFX_PtrArray m_possibleCenters;
+ FX_INT32 m_startX;
+ FX_INT32 m_startY;
+ FX_INT32 m_width;
+ FX_INT32 m_height;
+ FX_FLOAT m_moduleSize;
+ CFX_Int32Array m_crossCheckStateCount;
+public:
+ CBC_QRAlignmentPatternFinder(CBC_CommonBitMatrix *image, FX_INT32 startX, FX_INT32 startY, FX_INT32 width, FX_INT32 height, FX_FLOAT moduleSize);
+ virtual ~CBC_QRAlignmentPatternFinder();
+ FX_BOOL FoundPatternCross(const CFX_Int32Array &stateCount);
+ FX_FLOAT CrossCheckVertical(FX_INT32 startI, FX_INT32 startJ, FX_INT32 maxCount, FX_INT32 originalStateCountTotal);
+ CBC_QRAlignmentPattern* Find(FX_INT32 &e);
+ CBC_QRAlignmentPattern *HandlePossibleCenter(const CFX_Int32Array &stateCount, FX_INT32 i, FX_INT32 j);
+ static FX_FLOAT CenterFromEnd(const CFX_Int32Array &stateCount, FX_INT32 end);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRBitMatrixParser.h b/xfa/src/fxbarcode/src/include/BC_QRBitMatrixParser.h
new file mode 100644
index 0000000000..2e176f63d3
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRBitMatrixParser.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRABITMATRIXPARSER_H_
+#define _BC_QRABITMATRIXPARSER_H_
+class CBC_CommonBitMatrix ;
+class CBC_QRCoderVersion;
+class CBC_QRCoderFormatInformation;
+class CBC_QRDataMask;
+class CBC_QRBitMatrixParser;
+class CBC_QRBitMatrixParser : public CFX_Object
+{
+private:
+ CBC_CommonBitMatrix *m_bitMatrix;
+ CBC_CommonBitMatrix *m_tempBitMatrix;
+ CBC_QRCoderVersion *m_version;
+ CBC_QRCoderFormatInformation *m_parsedFormatInfo;
+ FX_INT32 m_dimension;
+public:
+ CBC_QRBitMatrixParser();
+ virtual ~CBC_QRBitMatrixParser();
+ CBC_QRCoderFormatInformation *ReadFormatInformation(FX_INT32 &e);
+ CBC_QRCoderVersion *ReadVersion(FX_INT32 &e);
+ FX_INT32 CopyBit(FX_INT32 i, FX_INT32 j, FX_INT32 versionBits);
+ CFX_ByteArray *ReadCodewords(FX_INT32 &e);
+ virtual void Init(CBC_CommonBitMatrix *bitMatrix, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCodeReader.h b/xfa/src/fxbarcode/src/include/BC_QRCodeReader.h
new file mode 100644
index 0000000000..71a1ad3dd6
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCodeReader.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODEREADER_H_
+#define _BC_QRCODEREADER_H_
+class CBC_QRDetector;
+class CBC_BinaryBitmap;
+class CBC_QRCoderDecoder;
+class CBC_ResultPoint;
+class CBC_ReedSolomonGF256;
+class CBC_QRCoderVersion;
+class CBC_QRDetector;
+class CBC_QRDetectorResult;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderMode;
+class CBC_QRDataMask;
+class CBC_QRCodeReader;
+class CBC_QRCodeReader : public CBC_Reader
+{
+private:
+ CBC_QRCoderDecoder *m_decoder;
+public:
+ CBC_QRCodeReader();
+ virtual ~CBC_QRCodeReader();
+ CFX_ByteString Decode(CFX_DIBitmap *pBitmap, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &e);
+ CFX_ByteString Decode(const CFX_WideString &filename, FX_INT32 hints, FX_INT32 byteModeDecode, FX_INT32 &e);
+ static void ReleaseAll();
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e);
+ CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 &e);
+ virtual void Init();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCodeWriter.h b/xfa/src/fxbarcode/src/include/BC_QRCodeWriter.h
new file mode 100644
index 0000000000..a4a4cbe048
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCodeWriter.h
@@ -0,0 +1,28 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERWRITER_H_
+#define _BC_QRCODERWRITER_H_
+#include "BC_TwoDimWriter.h"
+class CBC_TwoDimWriter;
+class CBC_MultiBarCodes;
+class CBC_QRCoderWriter;
+class CBC_QRCodeWriter : public CBC_TwoDimWriter
+{
+public:
+ CBC_QRCodeWriter();
+ virtual ~CBC_QRCodeWriter();
+ FX_BYTE* Encode(const CFX_WideString& contents, FX_INT32 ecLevel, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BYTE* Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e);
+ FX_BYTE* Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e);
+ FX_BOOL SetVersion(FX_INT32 version);
+ FX_BOOL SetErrorCorrectionLevel(FX_INT32 level);
+ static void ReleaseAll();
+private:
+
+ FX_INT32 m_iVersion;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoder.h b/xfa/src/fxbarcode/src/include/BC_QRCoder.h
new file mode 100644
index 0000000000..89ce140fbd
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoder.h
@@ -0,0 +1,55 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODER_H_
+#define _BC_QRCODER_H_
+class CBC_QRCoderErrorCorrectionLevel ;
+class CBC_QRCoderMode;
+class CBC_CommonByteMatrix;
+class CBC_QRCoder;
+class CBC_QRCoder : public CFX_Object
+{
+private:
+ CBC_QRCoderMode* m_mode;
+ CBC_QRCoderErrorCorrectionLevel* m_ecLevel;
+ FX_INT32 m_version;
+ FX_INT32 m_matrixWidth;
+ FX_INT32 m_maskPattern;
+ FX_INT32 m_numTotalBytes;
+ FX_INT32 m_numDataBytes;
+ FX_INT32 m_numECBytes;
+ FX_INT32 m_numRSBlocks;
+ CBC_CommonByteMatrix* m_matrix;
+public:
+ const static FX_INT32 NUM_MASK_PATTERNS;
+ CBC_QRCoder();
+ virtual ~CBC_QRCoder();
+ CBC_QRCoderMode* GetMode();
+ CBC_QRCoderErrorCorrectionLevel* GetECLevel();
+ FX_INT32 GetVersion();
+ FX_INT32 GetMatrixWidth();
+ FX_INT32 GetMaskPattern();
+ FX_INT32 GetNumTotalBytes();
+ FX_INT32 GetNumDataBytes();
+ FX_INT32 GetNumECBytes();
+ FX_INT32 GetNumRSBlocks();
+ CBC_CommonByteMatrix* GetMatrix();
+ FX_INT32 At(FX_INT32 x, FX_INT32 y, FX_INT32 &e);
+ FX_BOOL IsValid();
+
+ void SetMode(CBC_QRCoderMode* value);
+ void SetECLevel(CBC_QRCoderErrorCorrectionLevel* ecLevel);
+ void SetVersion(FX_INT32 version);
+ void SetMatrixWidth(FX_INT32 width);
+ void SetMaskPattern(FX_INT32 pattern);
+ void SetNumDataBytes(FX_INT32 bytes);
+ void SetNumTotalBytes(FX_INT32 value);
+ void SetNumECBytes(FX_INT32 value);
+ void SetNumRSBlocks(FX_INT32 block);
+ void SetMatrix(CBC_CommonByteMatrix* value);
+ static FX_BOOL IsValidMaskPattern(FX_INT32 maskPattern);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderBitVector.h b/xfa/src/fxbarcode/src/include/BC_QRCoderBitVector.h
new file mode 100644
index 0000000000..6e9abba6c9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderBitVector.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRECODERBITVECTOR_H_
+#define _BC_QRECODERBITVECTOR_H_
+class CBC_QRCoderBitVector;
+class CBC_QRCoderBitVector : public CFX_Object
+{
+private:
+ FX_INT32 m_sizeInBits;
+ FX_BYTE *m_array;
+ FX_INT32 m_size;
+
+ void AppendByte(FX_INT32 value);
+public:
+ CBC_QRCoderBitVector();
+ virtual ~CBC_QRCoderBitVector();
+ FX_INT32 At(FX_INT32 index, FX_INT32 &e);
+ FX_INT32 Size();
+ FX_INT32 sizeInBytes();
+ void AppendBit(FX_INT32 bit, FX_INT32 &e);
+ void AppendBits(FX_INT32 value, FX_INT32 numBits, FX_INT32 &e);
+ void AppendBitVector(CBC_QRCoderBitVector *bits, FX_INT32 &e);
+ void XOR(CBC_QRCoderBitVector *other, FX_INT32 &e);
+ FX_BYTE* GetArray();
+ void Clear();
+ virtual void Init();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderBlockPair.h b/xfa/src/fxbarcode/src/include/BC_QRCoderBlockPair.h
new file mode 100644
index 0000000000..234ac1a776
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderBlockPair.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERBLOCKPAIR_H_
+#define _BC_QRCODERBLOCKPAIR_H_
+class CBC_CommonByteArray;
+class CBC_QRCoderBlockPair;
+class CBC_QRCoderBlockPair : public CFX_Object
+{
+private:
+ CBC_CommonByteArray* m_dataBytes;
+ CBC_CommonByteArray* m_errorCorrectionBytes;
+public:
+ CBC_QRCoderBlockPair(CBC_CommonByteArray* data, CBC_CommonByteArray* errorCorrection);
+ virtual ~CBC_QRCoderBlockPair();
+
+ CBC_CommonByteArray* GetDataBytes();
+ CBC_CommonByteArray* GetErrorCorrectionBytes();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderDecoder.h b/xfa/src/fxbarcode/src/include/BC_QRCoderDecoder.h
new file mode 100644
index 0000000000..355af78180
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderDecoder.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERDECODER_H_
+#define _BC_QRCODERDECODER_H_
+class CBC_CommonBitMatrix;
+class CBC_ReedSolomonDecoder;
+class CBC_CommonDecoderResult;
+class CBC_QRBitMatrixParser;
+class CBC_QRCoderVersion;
+class CBC_QRDataBlock;
+class CBC_QRCoderDecoder;
+class CBC_QRCoderDecoder : public CFX_Object
+{
+private:
+ CBC_ReedSolomonDecoder *m_rsDecoder;
+public:
+ CBC_QRCoderDecoder();
+ virtual ~CBC_QRCoderDecoder();
+
+ CBC_CommonDecoderResult* Decode(FX_BOOL* image, FX_INT32 width, FX_INT32 height, FX_INT32 &e);
+ CBC_CommonDecoderResult* Decode(CBC_CommonBitMatrix* bits, FX_INT32 byteModeDecode, FX_INT32 &e);
+ void CorrectErrors(CFX_ByteArray* codewordBytes, FX_INT32 numDataCodewords, FX_INT32 &e);
+ virtual void Init();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderECB.h b/xfa/src/fxbarcode/src/include/BC_QRCoderECB.h
new file mode 100644
index 0000000000..c6494b75cd
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderECB.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERECB_H_
+#define _BC_QRCODERECB_H_
+class CBC_QRCoderECB;
+class CBC_QRCoderECB : public CFX_Object
+{
+private:
+ FX_INT32 m_count;
+ FX_INT32 m_dataCodeWords;
+public:
+ CBC_QRCoderECB(FX_INT32 count, FX_INT32 dataCodeWords);
+ virtual ~CBC_QRCoderECB();
+ FX_INT32 GetCount();
+ FX_INT32 GetDataCodeWords();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderECBlocks.h b/xfa/src/fxbarcode/src/include/BC_QRCoderECBlocks.h
new file mode 100644
index 0000000000..385837510a
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderECBlocks.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERECBLOCKS_H_
+#define _BC_QRCODERECBLOCKS_H_
+class CBC_QRCoderECB;
+class CBC_QRCoderECBlocks;
+class CBC_QRCoderECBlocks : public CFX_Object
+{
+private:
+ FX_INT32 m_ecCodeWordsPerBlock;
+ CFX_PtrArray m_ecBlocks;
+public:
+ CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks);
+ CBC_QRCoderECBlocks(FX_INT32 ecCodeWordsPerBlock, CBC_QRCoderECB* ecBlocks1, CBC_QRCoderECB* ecBlocks2);
+ virtual ~CBC_QRCoderECBlocks();
+ FX_INT32 GetECCodeWordsPerBlock();
+ FX_INT32 GetNumBlocks();
+ FX_INT32 GetTotalECCodeWords();
+ CFX_PtrArray* GetECBlocks();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderEncoder.h b/xfa/src/fxbarcode/src/include/BC_QRCoderEncoder.h
new file mode 100644
index 0000000000..8dea2a6477
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderEncoder.h
@@ -0,0 +1,60 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERENCODER_H_
+#define _BC_QRCODERENCODER_H_
+class Make_Pair;
+class CBC_QRCoder;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderMode;
+class CBC_QRCoderBitVector;
+class CBC_CommonByteArray;
+class CBC_CommonByteMatrix;
+class CBC_QRCoderEncoder;
+class CBC_QRCoderEncoder : public CFX_Object
+{
+private:
+ const static FX_INT32 m_alphaNumbericTable[96];
+public:
+ CBC_QRCoderEncoder();
+ virtual ~CBC_QRCoderEncoder();
+
+ static void Encode(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e, FX_INT32 versionSpecify = 0);
+ static void Encode(const CFX_WideString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e);
+ static void EncodeWithSpecifyVersion(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ CBC_QRCoder *qrCode, FX_INT32 versionSpecify, FX_INT32 &e);
+ static void EncodeWithAutoVersion(const CFX_ByteString &content, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoder *qrCode, FX_INT32 &e);
+ static CBC_QRCoderMode* ChooseMode(const CFX_ByteString & content, CFX_ByteString encoding);
+ static FX_INT32 GetAlphaNumericCode(FX_INT32 code);
+ static void AppendECI(CBC_QRCoderBitVector* bits);
+ static void AppendBytes(const CFX_ByteString &content, CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, CFX_ByteString encoding, FX_INT32 &e);
+ static void AppendNumericBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void AppendAlphaNumericBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void Append8BitBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, CFX_ByteString encoding, FX_INT32 &e);
+ static void Append8BitBytes(CFX_ByteArray &bytes, CBC_QRCoderBitVector *bits, FX_INT32 &e);
+ static void AppendKanjiBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void AppendGBKBytes(const CFX_ByteString &content, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void InitQRCode(FX_INT32 numInputBytes, FX_INT32 versionNumber,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e);
+ static void InitQRCode(FX_INT32 numInputBytes, CBC_QRCoderErrorCorrectionLevel* ecLevel, CBC_QRCoderMode* mode, CBC_QRCoder* qrCode, FX_INT32 &e);
+ static void AppendModeInfo(CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void AppendLengthInfo(FX_INT32 numLetters, FX_INT32 version, CBC_QRCoderMode* mode, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+
+ static void InterleaveWithECBytes(CBC_QRCoderBitVector* bits, FX_INT32 numTotalBytes, FX_INT32 numDataBytes, FX_INT32 numRSBlocks, CBC_QRCoderBitVector* result, FX_INT32 &e);
+ static void GetNumDataBytesAndNumECBytesForBlockID(FX_INT32 numTotalBytes, FX_INT32 numDataBytes,
+ FX_INT32 numRSBlocks, FX_INT32 blockID,
+ FX_INT32 &numDataBytesInBlock, FX_INT32& numECBytesInBlocks);
+ static CBC_CommonByteArray* GenerateECBytes(CBC_CommonByteArray* dataBytes, FX_INT32 numEcBytesInBlock, FX_INT32 &e);
+ static FX_INT32 ChooseMaskPattern(CBC_QRCoderBitVector* bits, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static FX_INT32 CalculateMaskPenalty(CBC_CommonByteMatrix* matrix);
+ static void TerminateBits(FX_INT32 numDataBytes, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static FX_INT32 GetSpanByVersion(CBC_QRCoderMode *modeFirst, CBC_QRCoderMode *modeSecond, FX_INT32 versionNum, FX_INT32 &e);
+ static void MergeString(CFX_PtrArray &result, FX_INT32 versionNum, FX_INT32 &e);
+ static void SplitString(const CFX_ByteString &content, CFX_PtrArray &result);
+ static void AppendDataModeLenghInfo(CFX_PtrArray &splitResult, CBC_QRCoderBitVector &headerAndDataBits, CBC_QRCoderMode *tempMode, CBC_QRCoder *qrCode, CFX_ByteString &encoding, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderErrorCorrectionLevel.h b/xfa/src/fxbarcode/src/include/BC_QRCoderErrorCorrectionLevel.h
new file mode 100644
index 0000000000..2c0ad7b0b7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderErrorCorrectionLevel.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERERRORCORRECTIONLEVEL_H_
+#define _BC_QRCODERERRORCORRECTIONLEVEL_H_
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderErrorCorrectionLevel : public CFX_Object
+{
+private:
+ FX_INT32 m_ordinal;
+ FX_INT32 m_bits;
+ CFX_ByteString m_name;
+ CBC_QRCoderErrorCorrectionLevel(FX_INT32 ordinal, FX_INT32 bits, FX_CHAR* name);
+ CBC_QRCoderErrorCorrectionLevel();
+public:
+ static CBC_QRCoderErrorCorrectionLevel* L;
+ static CBC_QRCoderErrorCorrectionLevel* M;
+ static CBC_QRCoderErrorCorrectionLevel* Q;
+ static CBC_QRCoderErrorCorrectionLevel* H;
+ virtual ~CBC_QRCoderErrorCorrectionLevel();
+ static void Initialize();
+ static void Finalize();
+ FX_INT32 Ordinal();
+ FX_INT32 GetBits();
+ CFX_ByteString GetName();
+ static void Destroy();
+ static CBC_QRCoderErrorCorrectionLevel* ForBits(FX_INT32 bits);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderFormatInformation.h b/xfa/src/fxbarcode/src/include/BC_QRCoderFormatInformation.h
new file mode 100644
index 0000000000..9d828c8380
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderFormatInformation.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERFORMATINFORMATION_H_
+#define _BC_QRCODERFORMATINFORMATION_H_
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderFormatInformation;
+class CBC_QRCoderFormatInformation : public CFX_Object
+{
+private:
+ const static FX_INT32 FORMAT_INFO_MASK_QR;
+ const static FX_INT32 FORMAT_INFO_DECODE_LOOKUP[32][2];
+ const static FX_INT32 BITS_SET_IN_HALF_BYTE[16];
+ CBC_QRCoderErrorCorrectionLevel* m_errorCorrectLevl;
+ FX_BYTE m_dataMask;
+public:
+ CBC_QRCoderFormatInformation(FX_INT32 formatInfo);
+ virtual ~CBC_QRCoderFormatInformation();
+ FX_BYTE GetDataMask();
+ CBC_QRCoderErrorCorrectionLevel* GetErrorCorrectionLevel();
+
+ static FX_INT32 NumBitsDiffering(FX_INT32 a, FX_INT32 b);
+ static CBC_QRCoderFormatInformation* DecodeFormatInformation(FX_INT32 maskedFormatInfo);
+ static CBC_QRCoderFormatInformation* DoDecodeFormatInformation(FX_INT32 maskedFormatInfo);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderMaskUtil.h b/xfa/src/fxbarcode/src/include/BC_QRCoderMaskUtil.h
new file mode 100644
index 0000000000..134d344e72
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderMaskUtil.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERMASKUTIL_H_
+#define _BC_QRCODERMASKUTIL_H_
+class CBC_CommonByteMatrix;
+class CBC_QRCoderMaskUtil;
+class CBC_QRCoderMaskUtil : public CFX_Object
+{
+public:
+ CBC_QRCoderMaskUtil();
+ virtual ~CBC_QRCoderMaskUtil();
+ static FX_BOOL GetDataMaskBit(FX_INT32 maskPattern, FX_INT32 x, FX_INT32 y, FX_INT32 &e);
+
+ static FX_INT32 ApplyMaskPenaltyRule1(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule2(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule3(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule4(CBC_CommonByteMatrix* matrix);
+ static FX_INT32 ApplyMaskPenaltyRule1Internal(CBC_CommonByteMatrix* matrix, FX_BOOL isHorizontal);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderMatrixUtil.h b/xfa/src/fxbarcode/src/include/BC_QRCoderMatrixUtil.h
new file mode 100644
index 0000000000..23a9d88128
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderMatrixUtil.h
@@ -0,0 +1,50 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERMATRIXUTIL_H_
+#define _BC_QRCODERMATRIXUTIL_H_
+class CBC_CommonByteMatrix;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderBitVector;
+class CBC_QRCoderMatrixUtil;
+class CBC_QRCoderMatrixUtil : public CFX_Object
+{
+private:
+ const static FX_INT32 POSITION_DETECTION_PATTERN[7][7];
+ const static FX_INT32 VERTICAL_SEPARATION_PATTERN[7][1];
+ const static FX_INT32 HORIZONTAL_SEPARATION_PATTERN[1][8];
+ const static FX_INT32 POSITION_ADJUSTMENT_PATTERN[5][5];
+ const static FX_INT32 POSITION_ADJUSTMENT_PATTERN_COORDINATE_TABLE[40][7];
+ const static FX_INT32 TYPE_INFO_COORDINATES[15][2];
+ const static FX_INT32 VERSION_INFO_POLY;
+ const static FX_INT32 TYPE_INFO_POLY;
+ const static FX_INT32 TYPE_INFO_MASK_PATTERN;
+public:
+ CBC_QRCoderMatrixUtil();
+ virtual ~CBC_QRCoderMatrixUtil();
+ static void ClearMatrix(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void BuildMatrix(CBC_QRCoderBitVector* dataBits, CBC_QRCoderErrorCorrectionLevel* ecLevel,
+ FX_INT32 version, FX_INT32 maskPattern, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedBasicPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedTypeInfo(CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 maskPattern, CBC_CommonByteMatrix *matrix, FX_INT32 &e);
+ static void EmbedDataBits(CBC_QRCoderBitVector* dataBits, FX_INT32 maskPattern, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void MaybeEmbedVersionInfo(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static FX_INT32 FindMSBSet(FX_INT32 value);
+ static FX_INT32 CalculateBCHCode(FX_INT32 code, FX_INT32 poly);
+ static void MakeTypeInfoBits(CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 maskPattern, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static void MakeVersionInfoBits(FX_INT32 version, CBC_QRCoderBitVector* bits, FX_INT32 &e);
+ static FX_BOOL IsEmpty(FX_INT32 value);
+ static FX_BOOL IsValidValue(FX_INT32 value);
+ static void EmbedTimingPatterns(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedDarkDotAtLeftBottomCorner(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedHorizontalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedVerticalSeparationPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedPositionAdjustmentPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedPositionDetectionPattern(FX_INT32 xStart, FX_INT32 yStart, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void EmbedPositionDetectionPatternsAndSeparators(CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+ static void MaybeEmbedPositionAdjustmentPatterns(FX_INT32 version, CBC_CommonByteMatrix* matrix, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderMode.h b/xfa/src/fxbarcode/src/include/BC_QRCoderMode.h
new file mode 100644
index 0000000000..71cea9fc78
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderMode.h
@@ -0,0 +1,40 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERMODE_H_
+#define _BC_QRCODERMODE_H_
+class CBC_QRCoderVersion;
+class CBC_QRCoderMode;
+class CBC_QRCoderMode : public CFX_Object
+{
+private:
+ FX_INT32* m_characterCountBitsForVersions;
+ FX_INT32 m_bits;
+ CFX_ByteString m_name;
+ CBC_QRCoderMode(FX_INT32 *characterCountBitsForVersions, FX_INT32 x1, FX_INT32 x2, FX_INT32 x3, FX_INT32 bits, CFX_ByteString name);
+ CBC_QRCoderMode();
+public:
+ static CBC_QRCoderMode* sBYTE;
+ static CBC_QRCoderMode* sNUMERIC;
+ static CBC_QRCoderMode* sALPHANUMERIC;
+ static CBC_QRCoderMode* sKANJI;
+ static CBC_QRCoderMode* sECI;
+ static CBC_QRCoderMode* sGBK;
+ static CBC_QRCoderMode* sTERMINATOR;
+ static CBC_QRCoderMode* sFNC1_FIRST_POSITION;
+ static CBC_QRCoderMode* sFNC1_SECOND_POSITION;
+ static CBC_QRCoderMode* sSTRUCTURED_APPEND;
+ virtual ~CBC_QRCoderMode();
+
+ static void Initialize();
+ static void Finalize();
+ static CBC_QRCoderMode* ForBits(FX_INT32 bits, FX_INT32 &e);
+ FX_INT32 GetCharacterCountBits(CBC_QRCoderVersion* version, FX_INT32 &e);
+ FX_INT32 GetBits();
+ CFX_ByteString GetName();
+ static void Destroy();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRCoderVersion.h b/xfa/src/fxbarcode/src/include/BC_QRCoderVersion.h
new file mode 100644
index 0000000000..b693dd6dd7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRCoderVersion.h
@@ -0,0 +1,42 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRCODERVERSION_H_
+#define _BC_QRCODERVERSION_H_
+class CBC_QRCoderECBlocks;
+class CBC_CommonBitMatrix;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRCoderVersion;
+class CBC_QRCoderVersion : public CFX_Object
+{
+private:
+ const static FX_INT32 VERSION_DECODE_INFO[34];
+ static CFX_PtrArray *VERSION;
+ FX_INT32 m_versionNumber;
+ FX_INT32 m_totalCodeWords;
+ CFX_Int32Array m_alignmentPatternCenters;
+ CFX_PtrArray m_ecBlocks;
+
+ CBC_QRCoderVersion();
+ CBC_QRCoderVersion(FX_INT32 versionNumber, CBC_QRCoderECBlocks* ecBlocks1, CBC_QRCoderECBlocks* ecBlocks2,
+ CBC_QRCoderECBlocks* ecBlocks3, CBC_QRCoderECBlocks* ecBlocks4);
+public:
+ virtual ~CBC_QRCoderVersion();
+ static void Initialize();
+ static void Finalize();
+
+ FX_INT32 GetVersionNumber();
+ FX_INT32 GetTotalCodeWords();
+ FX_INT32 GetDimensionForVersion();
+ CBC_CommonBitMatrix *BuildFunctionPattern(FX_INT32 &e);
+ CFX_Int32Array* GetAlignmentPatternCenters();
+ CBC_QRCoderECBlocks* GetECBlocksForLevel(CBC_QRCoderErrorCorrectionLevel *ecLevel);
+ static CBC_QRCoderVersion* GetVersionForNumber(FX_INT32 versionNumber, FX_INT32 &e);
+ static CBC_QRCoderVersion* GetProvisionalVersionForDimension(FX_INT32 dimension, FX_INT32 &e);
+ static CBC_QRCoderVersion* DecodeVersionInformation(FX_INT32 versionBits, FX_INT32 &e);
+ static void Destroy();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRDataBlock.h b/xfa/src/fxbarcode/src/include/BC_QRDataBlock.h
new file mode 100644
index 0000000000..4f68c7a9f3
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRDataBlock.h
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRDATABLOCK_H_
+#define _BC_QRDATABLOCK_H_
+class CBC_QRCoderVersion;
+class CBC_QRCoderECBlocks;
+class CBC_QRCoderECB;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_QRDataBlock;
+class CBC_QRDataBlock : public CFX_Object
+{
+private:
+ FX_INT32 m_numDataCodewords;
+ CFX_ByteArray *m_codewords;
+ CBC_QRDataBlock(FX_INT32 numDataCodewords, CFX_ByteArray *codewords);
+public:
+ virtual ~CBC_QRDataBlock();
+ FX_INT32 GetNumDataCodewords();
+ CFX_ByteArray* GetCodewords();
+ static CFX_PtrArray *GetDataBlocks(CFX_ByteArray* rawCodewords,
+ CBC_QRCoderVersion *version, CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRDataMask.h b/xfa/src/fxbarcode/src/include/BC_QRDataMask.h
new file mode 100644
index 0000000000..6fcc09d556
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRDataMask.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRDATAMASK_H_
+#define _BC_QRDATAMASK_H_
+class CBC_CommonBitMatrix;
+class CBC_QRDataMask;
+class CBC_QRDataMask : public CFX_Object
+{
+public:
+ static CFX_PtrArray *DATA_MASKS;
+ CBC_QRDataMask();
+ virtual ~CBC_QRDataMask();
+ static void Initialize();
+ static void Finalize();
+ virtual FX_BOOL IsMasked(FX_INT32 i, FX_INT32 j) = 0;
+ void UnmaskBitMatirx(CBC_CommonBitMatrix *bits, FX_INT32 dimension);
+ static CBC_QRDataMask* ForReference(FX_INT32 reference, FX_INT32 &e);
+ static FX_INT32 BuildDataMasks();
+ static void Destroy();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRDecodedBitStreamParser.h b/xfa/src/fxbarcode/src/include/BC_QRDecodedBitStreamParser.h
new file mode 100644
index 0000000000..b64485f788
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRDecodedBitStreamParser.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRDECODEDBITSTREAMPARSER_H_
+#define _BC_QRDECODEDBITSTREAMPARSER_H_
+class CBC_CommonDecoderResult;
+class CBC_QRCoderErrorCorrectionLevel;
+class CBC_CommonBitSource;
+class CBC_QRCoderVersion;
+class CBC_CommonCharacterSetECI;
+class CBC_QRDecodedBitStreamParser;
+class CBC_QRDecodedBitStreamParser : public CFX_Object
+{
+private:
+ const static FX_CHAR ALPHANUMERIC_CHARS[45];
+ static FX_LPCSTR UTF_8;
+ CBC_QRDecodedBitStreamParser();
+public:
+ virtual ~CBC_QRDecodedBitStreamParser();
+ static CBC_CommonDecoderResult* Decode(CFX_ByteArray *bytes, CBC_QRCoderVersion *version,
+ CBC_QRCoderErrorCorrectionLevel* ecLevel, FX_INT32 byteModeDecode, FX_INT32 &e);
+
+ static const CFX_ByteString GuessEncoding(CFX_ByteArray* bytes);
+ static FX_INT32 ParseECIValue(CBC_CommonBitSource* bits, FX_INT32 &e);
+ static void DecodeGBKSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e);
+ static void DecodeKanjiSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e);
+ static void DecodeNumericSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_INT32 &e);
+ static void DecodeAlphanumericSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, FX_BOOL fac1InEffect, FX_INT32 &e);
+ static void DecodeByteSegment(CBC_CommonBitSource* bits, CFX_ByteString &result, FX_INT32 count, CBC_CommonCharacterSetECI *currentCharacterSetECI,
+ CFX_Int32Array *byteSegments, FX_INT32 byteModeDecode, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRDetector.h b/xfa/src/fxbarcode/src/include/BC_QRDetector.h
new file mode 100644
index 0000000000..60c301cb7b
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRDetector.h
@@ -0,0 +1,41 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRDETECTOR_H_
+#define _BC_QRDETECTOR_H_
+class CBC_ResultPoint;
+class CBC_CommonBitMatrix;
+class CBC_QRDetectorResult;
+class CBC_QRFinderPatternInfo;
+class CBC_QRAlignmentPattern;
+class CBC_QRFinderPatternFinder;
+class CBC_QRCoderVersion;
+class CBC_QRGridSampler;
+class CBC_QRAlignmentPatternFinder;
+class CBC_QRAlignmentPattern;
+class CBC_QRDetector;
+class CBC_QRDetector
+{
+private:
+ CBC_CommonBitMatrix *m_image;
+public:
+ CBC_QRDetector(CBC_CommonBitMatrix *image);
+ virtual ~CBC_QRDetector();
+
+ CBC_CommonBitMatrix* GetImage();
+ CBC_QRDetectorResult* Detect(FX_INT32 hints, FX_INT32 &e);
+ CBC_QRDetectorResult* ProcessFinderPatternInfo(CBC_QRFinderPatternInfo *info, FX_INT32 &e);
+ FX_FLOAT CalculateModuleSize(CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight, CBC_ResultPoint *bottomLeft);
+ FX_FLOAT CalculateModuleSizeOneWay(CBC_ResultPoint *pattern, CBC_ResultPoint *otherPattern);
+ FX_FLOAT SizeOfBlackWhiteBlackRunBothWays(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY);
+ FX_FLOAT SizeOfBlackWhiteBlackRun(FX_INT32 fromX, FX_INT32 fromY, FX_INT32 toX, FX_INT32 toY);
+ CBC_QRAlignmentPattern* FindAlignmentInRegion(FX_FLOAT overallEstModuleSize, FX_INT32 estAlignmentX, FX_INT32 estAlignmentY, FX_FLOAT allowanceFactor, FX_INT32 &e);
+ static FX_INT32 Round(FX_FLOAT d);
+ static FX_INT32 ComputeDimension(CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight, CBC_ResultPoint *bottomLeft, FX_FLOAT moduleSize, FX_INT32 &e);
+ static CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix *image, CBC_ResultPoint *topLeft, CBC_ResultPoint *topRight,
+ CBC_ResultPoint *bottomLeft, CBC_ResultPoint* alignmentPattern, FX_INT32 dimension, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRDetectorResult.h b/xfa/src/fxbarcode/src/include/BC_QRDetectorResult.h
new file mode 100644
index 0000000000..13f6d3dc46
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRDetectorResult.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRDETECTORRESULT_H_
+#define _BC_QRDETECTORRESULT_H_
+class CBC_CommonBitMatrix;
+class CBC_ResultPoint;
+class CBC_QRDetectorResult;
+class CBC_QRDetectorResult : public CFX_Object
+{
+private:
+ CBC_CommonBitMatrix *m_bits;
+ CFX_PtrArray *m_points;
+public:
+ CBC_QRDetectorResult(CBC_CommonBitMatrix *bits, CFX_PtrArray *points);
+ virtual ~CBC_QRDetectorResult();
+ CBC_CommonBitMatrix *GetBits();
+ CFX_PtrArray *GetPoints();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRFinderPattern.h b/xfa/src/fxbarcode/src/include/BC_QRFinderPattern.h
new file mode 100644
index 0000000000..af88a727d9
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRFinderPattern.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRFINDERPATTERN_H_
+#define _BC_QRFINDERPATTERN_H_
+class CBC_ResultPoint;
+class CBC_QRFinderPattern;
+class CBC_QRFinderPattern : public CBC_ResultPoint
+{
+private:
+ FX_FLOAT m_estimatedModuleSize;
+ FX_INT32 m_count;
+public:
+ CBC_QRFinderPattern(FX_FLOAT x, FX_FLOAT posY, FX_FLOAT estimatedModuleSize);
+ virtual ~CBC_QRFinderPattern();
+
+ FX_INT32 GetCount();
+ FX_FLOAT GetX();
+ FX_FLOAT GetY();
+ FX_FLOAT GetEstimatedModuleSize();
+ void IncrementCount();
+ FX_BOOL AboutEquals(FX_FLOAT moduleSize, FX_FLOAT i, FX_FLOAT j);
+ CBC_QRFinderPattern *Clone();
+};
+typedef CBC_QRFinderPattern FinderPattern;
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRFinderPatternFinder.h b/xfa/src/fxbarcode/src/include/BC_QRFinderPatternFinder.h
new file mode 100644
index 0000000000..7470b553ee
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRFinderPatternFinder.h
@@ -0,0 +1,45 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRFINDERPATTERNFINDER_H_
+#define _BC_QRFINDERPATTERNFINDER_H_
+class CBC_CommonBitMatrix;
+class CBC_QRFinderPattern;
+class CBC_ResultPoint;
+class CBC_QRFinderPatternInfo;
+class CBC_QRFinderPatternFinder;
+class CBC_QRFinderPatternFinder : public CFX_Object
+{
+private:
+ const static FX_INT32 CENTER_QUORUM;
+ const static FX_INT32 MIN_SKIP;
+ const static FX_INT32 MAX_MODULES;
+ const static FX_INT32 INTEGER_MATH_SHIFT;
+ FX_BOOL m_hasSkipped;
+ CBC_CommonBitMatrix* m_image;
+ CFX_Int32Array m_crossCheckStateCount;
+ CFX_PtrArray m_possibleCenters;
+public:
+ CBC_QRFinderPatternFinder(CBC_CommonBitMatrix *image);
+ virtual ~CBC_QRFinderPatternFinder();
+ FX_INT32 FindRowSkip();
+ CBC_CommonBitMatrix* GetImage();
+ CBC_QRFinderPatternInfo* Find(FX_INT32 hint, FX_INT32 &e);
+
+ CFX_Int32Array &GetCrossCheckStateCount();
+ CFX_PtrArray *GetPossibleCenters();
+ CFX_PtrArray *SelectBestpatterns(FX_INT32 &e);
+
+ FX_BOOL HandlePossibleCenter(const CFX_Int32Array &stateCount, FX_INT32 i, FX_INT32 j);
+ FX_BOOL HaveMultiplyConfirmedCenters();
+ FX_FLOAT CenterFromEnd(const CFX_Int32Array &stateCount, FX_INT32 end);
+ FX_FLOAT CrossCheckVertical(FX_INT32 startI, FX_INT32 centerJ, FX_INT32 maxCount, FX_INT32 originalStateCountTotal);
+ FX_FLOAT CrossCheckHorizontal(FX_INT32 startJ, FX_INT32 CenterI, FX_INT32 maxCOunt, FX_INT32 originalStateCountTotal);
+ static void OrderBestPatterns(CFX_PtrArray *patterns);
+ static FX_BOOL FoundPatternCross(const CFX_Int32Array &stateCount);
+ static FX_FLOAT Distance(CBC_ResultPoint* point1, CBC_ResultPoint* point2);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_QRGridSampler.h b/xfa/src/fxbarcode/src/include/BC_QRGridSampler.h
new file mode 100644
index 0000000000..0b8c7d3ab7
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_QRGridSampler.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_QRGRIDSAMPLER_H_
+#define _BC_QRGRIDSAMPLER_H_
+class CBC_CommonBitMatrix;
+class CBC_CommonPerspectiveTransform;
+class CBC_CommonDefaultGridSampler;
+class CBC_QRGridSampler;
+class CBC_QRGridSampler
+{
+private:
+ static CBC_QRGridSampler m_gridSampler;
+public:
+ CBC_QRGridSampler();
+ virtual ~CBC_QRGridSampler();
+ virtual CBC_CommonBitMatrix* SampleGrid(CBC_CommonBitMatrix *image, FX_INT32 dimensionX, FX_INT32 dimensionY,
+ FX_FLOAT p1ToX, FX_FLOAT p1ToY,
+ FX_FLOAT p2ToX, FX_FLOAT p2ToY,
+ FX_FLOAT p3ToX, FX_FLOAT p3ToY,
+ FX_FLOAT p4ToX, FX_FLOAT p4ToY,
+ FX_FLOAT p1FromX, FX_FLOAT p1FromY,
+ FX_FLOAT p2FromX, FX_FLOAT p2FromY,
+ FX_FLOAT p3FromX, FX_FLOAT p3FromY,
+ FX_FLOAT p4FromX, FX_FLOAT p4FromY, FX_INT32 &e);
+
+ static CBC_QRGridSampler &GetInstance();
+ static void CheckAndNudgePoints(CBC_CommonBitMatrix *image, CFX_FloatArray *points, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_Reader.h b/xfa/src/fxbarcode/src/include/BC_Reader.h
new file mode 100644
index 0000000000..42b2aa11f5
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_Reader.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_READER_H_
+#define _BC_READER_H_
+class CBC_BinaryBitmap;
+class CBC_Reader;
+class CBC_Reader : public CFX_Object
+{
+public:
+ CBC_Reader();
+ virtual ~CBC_Reader();
+ virtual CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 &e) = 0;
+ virtual CFX_ByteString Decode(CBC_BinaryBitmap *image, FX_INT32 hints, FX_INT32 &e) = 0;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_ReedSolomon.h b/xfa/src/fxbarcode/src/include/BC_ReedSolomon.h
new file mode 100644
index 0000000000..2950b8f315
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_ReedSolomon.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_READSOLOMON_H_
+#define _BC_READSOLOMON_H_
+class CBC_ReedSolomonGF256;
+class CBC_ReedSolomonGF256Poly;
+class CBC_ReedSolomonEncoder;
+class CBC_ReedSolomonEncoder : public CFX_Object
+{
+private:
+ CBC_ReedSolomonGF256* m_field;
+ CFX_PtrArray m_cachedGenerators;
+ CBC_ReedSolomonGF256Poly* BuildGenerator(FX_INT32 degree, FX_INT32 &e);
+public:
+ CBC_ReedSolomonEncoder(CBC_ReedSolomonGF256 * field);
+ virtual ~CBC_ReedSolomonEncoder();
+
+ void Encode(CFX_Int32Array *toEncode, FX_INT32 ecBytes, FX_INT32 &e);
+ virtual void Init();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_ReedSolomonDecoder.h b/xfa/src/fxbarcode/src/include/BC_ReedSolomonDecoder.h
new file mode 100644
index 0000000000..c1dd0f03f5
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_ReedSolomonDecoder.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_REEDSOLOMONDECODER_H_
+#define _BC_REEDSOLOMONDECODER_H_
+class CBC_ReedSolomonGF256;
+class CBC_ReedSolomonGF256Poly;
+class CBC_ReedSolomonDecoder;
+class CBC_ReedSolomonDecoder : public CFX_Object
+{
+private:
+ CBC_ReedSolomonGF256 * m_field;
+public:
+ CBC_ReedSolomonDecoder(CBC_ReedSolomonGF256 * field);
+ virtual ~CBC_ReedSolomonDecoder();
+ void Decode(CFX_Int32Array* received, FX_INT32 twoS, FX_INT32 &e);
+ CFX_PtrArray* RunEuclideanAlgorithm(CBC_ReedSolomonGF256Poly* a, CBC_ReedSolomonGF256Poly* b, FX_INT32 R, FX_INT32 &e);
+ CFX_Int32Array* FindErrorLocations(CBC_ReedSolomonGF256Poly* errorLocator, FX_INT32 &e);
+ CFX_Int32Array* FindErrorMagnitudes(CBC_ReedSolomonGF256Poly* errorEvaluator, CFX_Int32Array* errorLocations, FX_BOOL dataMatrix, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256.h b/xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256.h
new file mode 100644
index 0000000000..1687b95e09
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_REEDSOLOMONGF256_H_
+#define _BC_REEDSOLOMONGF256_H_
+class CBC_ReedSolomonGF256Poly;
+class CBC_ReedSolomonGF256;
+class CBC_ReedSolomonGF256 : public CFX_Object
+{
+public:
+ static void Initialize();
+ static void Finalize();
+ static CBC_ReedSolomonGF256 *QRCodeFild;
+ static CBC_ReedSolomonGF256 *DataMatrixField;
+ CBC_ReedSolomonGF256(FX_INT32 primitive);
+ virtual ~CBC_ReedSolomonGF256();
+ CBC_ReedSolomonGF256Poly* GetZero();
+ CBC_ReedSolomonGF256Poly* GetOne();
+ CBC_ReedSolomonGF256Poly* BuildMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e);
+ static FX_INT32 AddOrSubtract(FX_INT32 a, FX_INT32 b);
+ FX_INT32 Exp(FX_INT32 a);
+ FX_INT32 Log(FX_INT32 a, FX_INT32 &e);
+ FX_INT32 Inverse(FX_INT32 a, FX_INT32 &e);
+ FX_INT32 Multiply(FX_INT32 a, FX_INT32 b);
+ virtual void Init();
+private:
+ FX_INT32 m_expTable[256];
+ FX_INT32 m_logTable[256];
+ CBC_ReedSolomonGF256Poly *m_zero;
+ CBC_ReedSolomonGF256Poly *m_one;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256Poly.h b/xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256Poly.h
new file mode 100644
index 0000000000..a6db24e231
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_ReedSolomonGF256Poly.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_READSOLOMONGF256POLY_H_
+#define _BC_READSOLOMONGF256POLY_H_
+class CBC_ReedSolomonGF256;
+class CBC_ReedSolomonGF256Poly;
+class CBC_ReedSolomonGF256Poly : public CFX_Object
+{
+public:
+ CBC_ReedSolomonGF256Poly(CBC_ReedSolomonGF256* field, FX_INT32 coefficients);
+ CBC_ReedSolomonGF256Poly();
+ virtual ~CBC_ReedSolomonGF256Poly();
+ FX_INT32 GetCoefficients(FX_INT32 degree);
+ CFX_Int32Array* GetCoefficients();
+ FX_INT32 GetDegree();
+ FX_BOOL IsZero();
+ FX_INT32 EvaluateAt(FX_INT32 a);
+ CBC_ReedSolomonGF256Poly* AddOrSubtract(CBC_ReedSolomonGF256Poly* other, FX_INT32 &e);
+ CBC_ReedSolomonGF256Poly* Multiply(CBC_ReedSolomonGF256Poly* other, FX_INT32 &e);
+ CBC_ReedSolomonGF256Poly* Multiply(FX_INT32 scalar, FX_INT32 &e);
+ CBC_ReedSolomonGF256Poly* MultiplyByMonomial(FX_INT32 degree, FX_INT32 coefficient, FX_INT32 &e);
+ CFX_PtrArray* Divide(CBC_ReedSolomonGF256Poly *other, FX_INT32 &e);
+ CBC_ReedSolomonGF256Poly* Clone(FX_INT32 &e);
+ virtual void Init(CBC_ReedSolomonGF256* field, CFX_Int32Array* coefficients, FX_INT32 &e);
+private:
+ CBC_ReedSolomonGF256* m_field;
+ CFX_Int32Array m_coefficients;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_ResultPoint.h b/xfa/src/fxbarcode/src/include/BC_ResultPoint.h
new file mode 100644
index 0000000000..7001cfa2a5
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_ResultPoint.h
@@ -0,0 +1,24 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_RESULTPOINT_H_
+#define _BC_RESULTPOINT_H_
+class CBC_ResultPoint;
+class CBC_ResultPoint : public CFX_Object
+{
+public:
+ CBC_ResultPoint();
+ CBC_ResultPoint(FX_FLOAT x, FX_FLOAT y);
+ virtual ~CBC_ResultPoint()
+ {
+ }
+ virtual FX_FLOAT GetX();
+ virtual FX_FLOAT GetY();
+protected:
+ FX_FLOAT m_x;
+ FX_FLOAT m_y;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_SymbolInfo.h b/xfa/src/fxbarcode/src/include/BC_SymbolInfo.h
new file mode 100644
index 0000000000..0450a28725
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_SymbolInfo.h
@@ -0,0 +1,53 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_SYMBOLINFO_H_
+#define _BC_SYMBOLINFO_H_
+class CBC_SymbolShapeHint;
+class CBC_Dimension;
+class CBC_SymbolInfo;
+class CBC_SymbolInfo : public CBC_SymbolShapeHint
+{
+public:
+ CBC_SymbolInfo(FX_BOOL rectangular, FX_INT32 dataCapacity, FX_INT32 errorCodewords,
+ FX_INT32 matrixWidth, FX_INT32 matrixHeight, FX_INT32 dataRegions);
+ virtual ~CBC_SymbolInfo();
+ static void Initialize();
+ static void Finalize();
+ static void overrideSymbolSet(CBC_SymbolInfo* override);
+ static CBC_SymbolInfo* lookup(FX_INT32 dataCodewords, FX_INT32 &e);
+ static CBC_SymbolInfo* lookup(FX_INT32 dataCodewords, SymbolShapeHint shape, FX_INT32 &e);
+ static CBC_SymbolInfo* lookup(FX_INT32 dataCodewords, FX_BOOL allowRectangular, FX_BOOL fail, FX_INT32 &e);
+ static CBC_SymbolInfo* lookup(FX_INT32 dataCodewords, SymbolShapeHint shape, FX_BOOL fail, FX_INT32 &e);
+ static CBC_SymbolInfo* lookup(FX_INT32 dataCodewords, SymbolShapeHint shape, CBC_Dimension* minSize, CBC_Dimension* maxSize, FX_BOOL fail, FX_INT32 &e);
+ FX_INT32 getHorizontalDataRegions(FX_INT32 &e);
+ FX_INT32 getVerticalDataRegions(FX_INT32 &e);
+ FX_INT32 getSymbolDataWidth(FX_INT32 &e);
+ FX_INT32 getSymbolDataHeight(FX_INT32 &e);
+ FX_INT32 getSymbolWidth(FX_INT32 &e);
+ FX_INT32 getSymbolHeight(FX_INT32 &e);
+ FX_INT32 getCodewordCount();
+ FX_INT32 getInterleavedBlockCount();
+ FX_INT32 getDataLengthForInterleavedBlock(FX_INT32 index);
+ FX_INT32 getErrorLengthForInterleavedBlock(FX_INT32 index);
+ CFX_WideString toString(FX_INT32 &e);
+public:
+ FX_INT32 m_dataCapacity;
+ FX_INT32 m_errorCodewords;
+ FX_INT32 m_matrixWidth;
+ FX_INT32 m_matrixHeight;
+ FX_INT32 m_rsBlockData;
+ FX_INT32 m_rsBlockError;
+ static CBC_SymbolInfo* m_PROD_SYMBOLS[30];
+private:
+ static CBC_SymbolInfo* m_symbols[30];
+ FX_BOOL m_rectangular;
+ FX_INT32 m_dataRegions;
+private:
+ CBC_SymbolInfo(FX_BOOL rectangular, FX_INT32 dataCapacity, FX_INT32 errorCodewords, FX_INT32 matrixWidth, FX_INT32 matrixHeight, FX_INT32 dataRegions,
+ FX_INT32 rsBlockData, FX_INT32 rsBlockError);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_SymbolShapeHint.h b/xfa/src/fxbarcode/src/include/BC_SymbolShapeHint.h
new file mode 100644
index 0000000000..2b030012a3
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_SymbolShapeHint.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_SYMBOLSHAPEHINT_H_
+#define _BC_SYMBOLSHAPEHINT_H_
+class CBC_SymbolShapeHint;
+class CBC_SymbolShapeHint : public CFX_Object
+{
+public:
+ CBC_SymbolShapeHint();
+ virtual ~CBC_SymbolShapeHint();
+ enum SymbolShapeHint {
+ FORCE_NONE,
+ FORCE_SQUARE,
+ FORCE_RECTANGLE,
+ };
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_TextEncoder.h b/xfa/src/fxbarcode/src/include/BC_TextEncoder.h
new file mode 100644
index 0000000000..f1168679a6
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_TextEncoder.h
@@ -0,0 +1,18 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_TEXTENCODER_H_
+#define _BC_TEXTENCODER_H_
+class CBC_TextEncoder;
+class CBC_TextEncoder : public CBC_C40Encoder
+{
+public:
+ CBC_TextEncoder();
+ virtual ~CBC_TextEncoder();
+ FX_INT32 getEncodingMode();
+ FX_INT32 encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_TwoDimWriter.h b/xfa/src/fxbarcode/src/include/BC_TwoDimWriter.h
new file mode 100644
index 0000000000..369d494c08
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_TwoDimWriter.h
@@ -0,0 +1,44 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_TWODIMWRITER_H_
+#define _BC_TWODIMWRITER_H_
+#include "BC_Writer.h"
+class CBC_Writer;
+class CBC_CommonBitMatrix;
+class CBC_TwoDimWriter;
+class CBC_TwoDimWriter : public CBC_Writer
+{
+public:
+ CBC_TwoDimWriter();
+ virtual ~CBC_TwoDimWriter();
+ virtual FX_BYTE* Encode(const CFX_WideString& contents, FX_INT32 ecLevel, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+ {
+ return NULL;
+ };
+ virtual FX_BYTE* Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e)
+ {
+ return NULL;
+ };
+ virtual FX_BYTE* Encode(const CFX_ByteString& contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e)
+ {
+ return NULL;
+ };
+ virtual void RenderResult(FX_BYTE *code, FX_INT32 codeWidth, FX_INT32 codeHeight, FX_INT32 &e);
+ virtual void RenderBitmapResult(CFX_DIBitmap *&pOutBitmap, FX_INT32& e);
+ virtual void RenderDeviceResult(CFX_RenderDevice* device, const CFX_Matrix* matrix);
+ virtual FX_BOOL SetErrorCorrectionLevel (FX_INT32 level) = 0;
+ virtual FX_INT32 GetErrorCorrectionLevel()
+ {
+ return m_iCorrectLevel;
+ };
+
+protected:
+ FX_INT32 m_iCorrectLevel;
+ FX_BOOL m_bFixedSize;
+ CBC_CommonBitMatrix* m_output;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_UtilCodingConvert.h b/xfa/src/fxbarcode/src/include/BC_UtilCodingConvert.h
new file mode 100644
index 0000000000..1ee3a8c64c
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_UtilCodingConvert.h
@@ -0,0 +1,22 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_UTILCODINGCONVERT_H_
+#define _BC_UTILCODINGCONVERT_H_
+class CBC_UtilCodingConvert;
+class CBC_UtilCodingConvert : public CFX_Object
+{
+public:
+ CBC_UtilCodingConvert();
+ virtual ~CBC_UtilCodingConvert();
+ static void UnicodeToLocale(const CFX_WideString &source, CFX_ByteString &result);
+ static void LocaleToUtf8(const CFX_ByteString &source, CFX_ByteString &result);
+ static void LocaleToUtf8(const CFX_ByteString &source, CFX_ByteArray &result);
+ static void Utf8ToLocale(const CFX_ByteArray &source, CFX_ByteString &result);
+ static void Utf8ToLocale(const FX_BYTE *source, FX_INT32 count, CFX_ByteString &result);
+ static void UnicodeToUTF8(const CFX_WideString &source, CFX_ByteString &result);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_UtilRSS.h b/xfa/src/fxbarcode/src/include/BC_UtilRSS.h
new file mode 100644
index 0000000000..37834eaa76
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_UtilRSS.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_UTILRESS_H_
+#define _BC_UTILRESS_H_
+class CBC_RssPair;
+class CBC_UtilRSS : public CFX_Object
+{
+public:
+ virtual ~CBC_UtilRSS();
+ static FX_INT32 GetRSSvalue(CFX_Int32Array &widths, FX_INT32 maxWidth, FX_BOOL noNarrow);
+
+protected:
+ static CFX_Int32Array *GetRssWidths(FX_INT32 val, FX_INT32 n, FX_INT32 elements, FX_INT32 maxWidth, FX_BOOL noNarrow);
+ static FX_INT32 Combins(FX_INT32 n, FX_INT32 r);
+ static CFX_Int32Array *Elements(CFX_Int32Array &eDist, FX_INT32 N, FX_INT32 K);
+private:
+ CBC_UtilRSS();
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_WhiteRectangleDetector.h b/xfa/src/fxbarcode/src/include/BC_WhiteRectangleDetector.h
new file mode 100644
index 0000000000..83d91ced92
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_WhiteRectangleDetector.h
@@ -0,0 +1,38 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_WHITERECTANLEDETECTOR_H_
+#define _BC_WHITERECTANLEDETECTOR_H_
+class CBC_CommonBitMatrix;
+class CBC_ResultPoint;
+class CBC_WhiteRectangleDetector;
+class CBC_WhiteRectangleDetector : public CFX_Object
+{
+public:
+ CBC_WhiteRectangleDetector(CBC_CommonBitMatrix *image);
+ CBC_WhiteRectangleDetector(CBC_CommonBitMatrix *image, FX_INT32 initSize, FX_INT32 x, FX_INT32 y);
+ virtual ~CBC_WhiteRectangleDetector();
+ CFX_PtrArray *Detect(FX_INT32 &e);
+ virtual void Init(FX_INT32 &e);
+private:
+ FX_INT32 Round(float d);
+ CBC_ResultPoint *GetBlackPointOnSegment(FX_FLOAT aX, FX_FLOAT aY, FX_FLOAT bX, FX_FLOAT bY);
+ FX_INT32 DistanceL2(FX_FLOAT aX, FX_FLOAT aY, FX_FLOAT bX, FX_FLOAT bY);
+ CFX_PtrArray *CenterEdges(CBC_ResultPoint *y, CBC_ResultPoint *z,
+ CBC_ResultPoint *x, CBC_ResultPoint *t);
+ FX_BOOL ContainsBlackPoint(FX_INT32 a, FX_INT32 b, FX_INT32 fixed, FX_BOOL horizontal);
+ const static FX_INT32 INIT_SIZE;
+ const static FX_INT32 CORR;
+
+ CBC_CommonBitMatrix *m_image;
+ FX_INT32 m_height;
+ FX_INT32 m_width;
+ FX_INT32 m_leftInit;
+ FX_INT32 m_rightInit;
+ FX_INT32 m_downInit;
+ FX_INT32 m_upInit;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_Writer.h b/xfa/src/fxbarcode/src/include/BC_Writer.h
new file mode 100644
index 0000000000..deb68c07be
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_Writer.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_WRITER_H_
+#define _BC_WRITER_H_
+class CBC_Writer;
+class CBC_Writer : public CFX_Object
+{
+public:
+ CBC_Writer();
+ virtual ~CBC_Writer();
+ virtual FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 &e) = 0;
+ virtual FX_BYTE *Encode(const CFX_ByteString &contents, BCFORMAT format, FX_INT32 &outWidth, FX_INT32 &outHeight, FX_INT32 hints, FX_INT32 &e) = 0;
+ virtual FX_BOOL SetCharEncoding(FX_INT32 encoding);
+ virtual FX_BOOL SetModuleHeight(FX_INT32 moduleHeight);
+ virtual FX_BOOL SetModuleWidth(FX_INT32 moduleWidth);
+ virtual FX_BOOL SetHeight(FX_INT32 height);
+ virtual FX_BOOL SetWidth(FX_INT32 width);
+ virtual void SetBackgroundColor(FX_ARGB backgroundColor);
+ virtual void SetBarcodeColor(FX_ARGB foregroundColor);
+protected:
+ CFX_DIBitmap* CreateDIBitmap(FX_INT32 width, FX_INT32 height);
+ FX_INT32 m_CharEncoding;
+ FX_INT32 m_ModuleHeight;
+ FX_INT32 m_ModuleWidth;
+ FX_INT32 m_Height;
+ FX_INT32 m_Width;
+ FXDIB_Format m_colorSpace;
+ FX_ARGB m_barColor;
+ FX_ARGB m_backgroundColor;
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/BC_X12Encoder.h b/xfa/src/fxbarcode/src/include/BC_X12Encoder.h
new file mode 100644
index 0000000000..21111bc5cc
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/BC_X12Encoder.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_X12ENCODER_H_
+#define _BC_X12ENCODER_H_
+class CBC_C40Encoder;
+class CBC_X12Encoder;
+class CBC_X12Encoder : public CBC_C40Encoder
+{
+public:
+ CBC_X12Encoder();
+ virtual ~CBC_X12Encoder();
+ FX_INT32 getEncodingMode();
+ void Encode(CBC_EncoderContext &context, FX_INT32 &e);
+ void handleEOD(CBC_EncoderContext &context, CFX_WideString &buffer, FX_INT32 &e);
+ FX_INT32 encodeChar(FX_WCHAR c, CFX_WideString &sb, FX_INT32 &e);
+};
+#endif
diff --git a/xfa/src/fxbarcode/src/include/utils.h b/xfa/src/fxbarcode/src/include/utils.h
new file mode 100644
index 0000000000..ecaadccef0
--- /dev/null
+++ b/xfa/src/fxbarcode/src/include/utils.h
@@ -0,0 +1,219 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _BC_UTILS_H_
+#define _BC_UTILS_H_
+typedef CFX_MapPtrTemplate<FX_LPVOID, FX_INT32> CFX_PtrToInt32;
+FX_BOOL BC_FX_ByteString_Replace(CFX_ByteString &dst, FX_DWORD first, FX_DWORD last, FX_INT32 count, FX_CHAR c);
+void BC_FX_ByteString_Append(CFX_ByteString &dst, FX_INT32 count, FX_CHAR c);
+void BC_FX_ByteString_Append(CFX_ByteString &dst, const CFX_ByteArray &ba);
+typedef FX_BOOL (*BC_PtrArrayCompareCallback)(FX_LPVOID l, FX_LPVOID r);
+void BC_FX_PtrArray_Sort(CFX_PtrArray &src, BC_PtrArrayCompareCallback fun);
+template<class _Ty>
+class CBC_AutoPtr
+{
+public:
+ typedef _Ty element_type;
+ explicit CBC_AutoPtr(_Ty *_P = 0)
+ : _Owns(_P != 0), _Ptr(_P) {}
+ CBC_AutoPtr(const CBC_AutoPtr<_Ty>& _Y)
+ : _Owns(_Y._Owns), _Ptr(_Y.release()) {}
+ CBC_AutoPtr<_Ty>& operator=(const CBC_AutoPtr<_Ty>& _Y)
+ {
+ if (this != &_Y) {
+ if (_Ptr != _Y.get()) {
+ if (_Owns) {
+ delete _Ptr;
+ }
+ _Owns = _Y._Owns;
+ } else if (_Y._Owns) {
+ _Owns = TRUE;
+ }
+ _Ptr = _Y.release();
+ }
+ return (*this);
+ }
+ ~CBC_AutoPtr()
+ {
+ if (_Owns) {
+ delete _Ptr;
+ }
+ }
+ _Ty& operator*() const
+ {
+ return (*get());
+ }
+ _Ty *operator->() const
+ {
+ return (get());
+ }
+ _Ty *get() const
+ {
+ return (_Ptr);
+ }
+ _Ty *release() const
+ {
+ ((CBC_AutoPtr<_Ty> *)this)->_Owns = FALSE;
+ return (_Ptr);
+ }
+private:
+ FX_BOOL _Owns;
+ _Ty *_Ptr;
+};
+#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_)
+#include <limits>
+#elif (_FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_IOS_)
+#include <limits.h>
+#endif
+#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_)
+#define FXSYS_isnan(x) _isnan(x)
+#elif (_FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_IOS_)
+#include <math.h>
+#define FXSYS_isnan(x) std::isnan(x)
+#elif (_FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_ANDROID_)
+#include <math.h>
+#define FXSYS_isnan(x) isnan(x)
+#endif
+#if (_FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_)
+#define FXSYS_nan() (std::numeric_limits<float>::quiet_NaN())
+#elif (_FX_OS_ == _FX_MACOSX_ || _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_IOS_ || _FX_OS_ == _FX_ANDROID_)
+#define FXSYS_nan() NAN
+#endif
+enum BCFORMAT {
+ BCFORMAT_UNSPECIFY = -1,
+ BCFORMAT_CODABAR,
+ BCFORMAT_CODE_39,
+ BCFORMAT_CODE_128,
+ BCFORMAT_CODE_128B,
+ BCFORMAT_CODE_128C,
+ BCFORMAT_EAN_8,
+ BCFORMAT_UPC_A,
+ BCFORMAT_EAN_13,
+ BCFORMAT_PDF_417,
+ BCFORMAT_DATAMATRIX,
+ BCFORMAT_QR_CODE
+};
+#define BCFORMAT_ECLEVEL_L 0
+#define BCFORMAT_ECLEVEL_M 1
+#define BCFORMAT_ECLEVEL_Q 2
+#define BCFORMAT_ECLEVEL_H 3
+#include <ctype.h>
+#define FXSYS_IntMax INT_MAX
+#define FXSYS_Isdigit isdigit
+#define BCExceptionNO 0
+#define BCExceptionNotFound 1
+#define BCExceptionEndLessThanStart 2
+#define BCExceptionUnknownDecoder 3
+#define BCExceptionRotateNotSupported 4
+#define BCExceptionHeightAndWidthMustBeAtLeast1 5
+#define BCExceptionRegionMustFitInsideMatrix 6
+#define BCExceptionCanNotCallGetDimensionOnNonSquareMatrix 7
+#define BCExceptionFormatException 8
+#define BCExceptionIllegalArgumentMustMatchVersionSize 9
+#define BCExceptionChecksumException 10
+#define BCExceptionIllegalArgumentInvalidFirstDigit 11
+#define BCExceptionIllegalArgumentInvalidSecondDigit 12
+#define BCExceptionRuntimeDecodingInvalidISO_IEC 13
+#define BCExceptionRuntimeDecodingInvalidAlphanumeric 14
+#define BCExceptionLeftAndTopMustBeNonnegative 15
+#define BCExceptionIllegalArgument 16
+#define BCExceptionBadECI 17
+#define BCExceptionUnSupportedBarcode 18
+#define BCExceptionUnSupportedString 19
+#define BCExceptionDigitLengthMustBe8 20
+#define BCExceptionDataCheckException 21
+#define BCExceptionExtractNumberValueFromBitArray 22
+#define BCExceptionRead 23
+#define BCExceptionRequestedRowIsOutSizeTheImage 24
+#define BCExceptionNoContents 26
+#define BCExceptionUnSupportEclevel 27
+#define BCExceptionUnSupportMode 28
+#define BCExceptionReferenceMustBeBetween0And7 29
+#define BCExceptionBadErrorLocation 30
+#define BCExceptionDegreeIsNegative 31
+#define BCExceptionDivideByZero 32
+#define BCExceptionCoefficientsSizeIsNull 33
+#define BCExceptionNoCorrectionBytes 34
+#define BCExceptionNoDataBytesProvided 35
+#define BCExceptionR_I_1IsZero 36
+#define BCExceptionAIsZero 37
+#define BCExceptionIsZero 38
+#define BCExceptionDegreeNotMatchRoots 39
+#define BCExceptionContentsLengthShouldBetween1and80 40
+#define BCExceptionOnlyEncodeCODE_128 41
+#define BCExceptionOnlyEncodeCODE_39 42
+#define BCExceptionOnlyEncodeEAN_13 43
+#define BCExceptionOnlyEncodeEAN_8 44
+#define BCExceptionOnlyEncodeITF 45
+#define BCExceptionDigitLengthShould13 46
+#define BCExceptionDigitLengthMustBe6or8or10or12or14or16or20or24or44 47
+#define BCExceptionOnlyEncodeUPC_A 48
+#define BCExceptionDigitLengthShouldBe12 49
+#define BCExceptionValueMustBeEither0or1 50
+#define BCExceptionReedsolomnDecodeException 51
+#define BCExceptionBadIndexException 52
+#define BCExceptionBadValueException 53
+#define BCExceptionBadNumBitsException 54
+#define BCExceptioncanNotOperatexorOperator 55
+#define BCExceptionVersionMust1_40 56
+#define BCExceptionUnknown 57
+#define BCExceptionNoSuchVersion 58
+#define BCExceptionCannotFindBlockInfo 59
+#define BCExceptionDataTooBig 60
+#define BCExceptionInvalidQRCode 61
+#define BCExceptionDataTooMany 62
+#define BCExceptionBitsNotEqualCacity 63
+#define BCExceptionUnsupportedMode 64
+#define BCExceptionInvalidateCharacter 65
+#define BCExceptionBytesNotMatchOffset 66
+#define BCExceptionSizeInBytesDiffer 67
+#define BCExceptionInvalidateMaskPattern 68
+#define BCExceptionNullPointer 69
+#define BCExceptionBadMask 70
+#define BCExceptionBitSizeNot15 71
+#define BCExceptionBitSizeNot18 72
+#define BCExceptionInvalidateImageData 73
+#define BCExceptionHeight_8BeZero 74
+#define BCExceptionCharacterNotThisMode 75
+#define BCExceptionBitsBytesNotMatch 76
+#define BCExceptionInvalidateData 77
+#define BCExceptionLoadFile 78
+#define BCExceptionPDF417EncodeFail 79
+#define BCExceptionFailToCreateBitmap 80
+#define BCExceptionLoadFontFail 81
+#define BCExceptionOnlyEncodeCODEBAR 82
+#define BCExceptionCodabarShouldStartWithOneOfABCD 83
+#define BCExceptionCodabarShouldEndWithOneOfTNE 84
+#define BCExceptionCodabarEncodeCharsInvalid 85
+#define BCExceptionOnlyEncodeDATAMATRIX 86
+#define BCExceptionCharactersOutsideISO88591Encoding 87
+#define BCExceptionIllegalDataCodewords 88
+#define BCExceptionCannotHandleThisNumberOfDataRegions 89
+#define BCExceptionIllegalStateUnexpectedCase 90
+#define BCExceptionIllegalStateCountMustNotExceed4 91
+#define BCExceptionIllegalStateMessageLengthInvalid 92
+#define BCExceptionIllegalArgumentNotGigits 93
+#define BCExceptionIllegalStateIllegalMode 94
+#define BCExceptionOnlyEncodePDF417 95
+#define BCExceptionNonEncodableCharacterDetected 96
+#define BCExceptionErrorCorrectionLevelMustBeBetween0And8 97
+#define BCExceptionNoRecommendationPossible 98
+#define BCExceptionIllegalArgumentnMustBeAbove0 99
+#define BCExceptionUnableToFitMessageInColumns 100
+#define BCExceptionEncodedMessageContainsTooManyCodeWords 101
+#define BCExceptionBitmapSizeError 102
+#define BCExceptionFormatInstance 102
+#define BCExceptionChecksumInstance 103
+#define BCExceptiontNotFoundInstance 104
+#define BCExceptionNotFoundInstance 105
+#define BCExceptionCannotMetadata 106
+#define TWO_DIGIT_DATA_LENGTH_SIZE 24
+#define THREE_DIGIT_DATA_LENGTH_SIZE 23
+#define THREE_DIGIT_PLUS_DIGIT_DATA_LENGTH_SIZE 57
+#define FOUR_DIGIT_DATA_LENGTH_SIZE 17
+#define BC_EXCEPTION_CHECK_ReturnVoid(e) if (e != BCExceptionNO) return;
+#define BC_EXCEPTION_CHECK_ReturnValue(e, v) if (e != BCExceptionNO) return v;
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_checksum.cpp b/xfa/src/fxfa/src/app/xfa_checksum.cpp
new file mode 100644
index 0000000000..0ed07bb579
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_checksum.cpp
@@ -0,0 +1,203 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_checksum.h"
+CXFA_SAXReaderHandler::CXFA_SAXReaderHandler(CXFA_ChecksumContext *pContext)
+ : m_pContext(pContext)
+{
+ FXSYS_assert(m_pContext);
+}
+CXFA_SAXReaderHandler::~CXFA_SAXReaderHandler()
+{
+}
+FX_LPVOID CXFA_SAXReaderHandler::OnTagEnter(FX_BSTR bsTagName, FX_SAXNODE eType, FX_DWORD dwStartPos)
+{
+ UpdateChecksum(TRUE);
+ if (eType != FX_SAXNODE_Tag && eType != FX_SAXNODE_Instruction) {
+ return NULL;
+ }
+ m_SAXContext.m_eNode = eType;
+ CFX_ByteTextBuf &textBuf = m_SAXContext.m_TextBuf;
+ textBuf << FX_BSTRC("<");
+ if (eType == FX_SAXNODE_Instruction) {
+ textBuf << FX_BSTRC("?");
+ }
+ textBuf << bsTagName;
+ m_SAXContext.m_bsTagName = bsTagName;
+ return &m_SAXContext;
+}
+void CXFA_SAXReaderHandler::OnTagAttribute(FX_LPVOID pTag, FX_BSTR bsAttri, FX_BSTR bsValue)
+{
+ if (pTag == NULL) {
+ return;
+ }
+ CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+ textBuf << FX_BSTRC(" ");
+ textBuf << bsAttri;
+ textBuf << FX_BSTRC("=\"");
+ textBuf << bsValue;
+ textBuf << FX_BSTRC("\"");
+}
+void CXFA_SAXReaderHandler::OnTagBreak(FX_LPVOID pTag)
+{
+ if (pTag == NULL) {
+ return;
+ }
+ CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+ textBuf << FX_BSTRC(">");
+ UpdateChecksum(FALSE);
+}
+void CXFA_SAXReaderHandler::OnTagData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos)
+{
+ if (pTag == NULL) {
+ return;
+ }
+ CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+ if (eType == FX_SAXNODE_CharData) {
+ textBuf << FX_BSTRC("<![CDATA[");
+ }
+ textBuf << bsData;
+ if (eType == FX_SAXNODE_CharData) {
+ textBuf << FX_BSTRC("]]>");
+ }
+}
+void CXFA_SAXReaderHandler::OnTagClose(FX_LPVOID pTag, FX_DWORD dwEndPos)
+{
+ if (pTag == NULL) {
+ return;
+ }
+ CXFA_SAXContext *pSAXContext = (CXFA_SAXContext*)pTag;
+ CFX_ByteTextBuf &textBuf = pSAXContext->m_TextBuf;
+ if (pSAXContext->m_eNode == FX_SAXNODE_Instruction) {
+ textBuf << FX_BSTRC("?>");
+ } else if (pSAXContext->m_eNode == FX_SAXNODE_Tag) {
+ textBuf << FX_BSTRC("></");
+ textBuf << pSAXContext->m_bsTagName;
+ textBuf << FX_BSTRC(">");
+ }
+ UpdateChecksum(FALSE);
+}
+void CXFA_SAXReaderHandler::OnTagEnd(FX_LPVOID pTag, FX_BSTR bsTagName, FX_DWORD dwEndPos)
+{
+ if (pTag == NULL) {
+ return;
+ }
+ CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+ textBuf << FX_BSTRC("</");
+ textBuf << bsTagName;
+ textBuf << FX_BSTRC(">");
+ UpdateChecksum(FALSE);
+}
+void CXFA_SAXReaderHandler::OnTargetData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos)
+{
+ if (pTag == NULL && eType != FX_SAXNODE_Comment) {
+ return;
+ }
+ if (eType == FX_SAXNODE_Comment) {
+ CFX_ByteTextBuf &textBuf = m_SAXContext.m_TextBuf;
+ textBuf << FX_BSTRC("<!--");
+ textBuf << bsData;
+ textBuf << FX_BSTRC("-->");
+ UpdateChecksum(FALSE);
+ } else {
+ CFX_ByteTextBuf &textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
+ textBuf << FX_BSTRC(" ");
+ textBuf << bsData;
+ }
+}
+void CXFA_SAXReaderHandler::UpdateChecksum(FX_BOOL bCheckSpace)
+{
+ FX_INT32 iLength = m_SAXContext.m_TextBuf.GetLength();
+ if (iLength < 1) {
+ return;
+ }
+ FX_LPBYTE pBuffer = m_SAXContext.m_TextBuf.GetBuffer();
+ FX_BOOL bUpdata = TRUE;
+ if (bCheckSpace) {
+ bUpdata = FALSE;
+ for (FX_INT32 i = 0; i < iLength; i++) {
+ bUpdata = (pBuffer[i] > 0x20);
+ if (bUpdata) {
+ break;
+ }
+ }
+ }
+ if (bUpdata) {
+ m_pContext->Update(CFX_ByteStringC(pBuffer, iLength));
+ }
+ m_SAXContext.m_TextBuf.Clear();
+}
+IXFA_ChecksumContext* XFA_Checksum_Create()
+{
+ return FX_NEW CXFA_ChecksumContext;
+}
+CXFA_ChecksumContext::CXFA_ChecksumContext()
+ : m_pSAXReader(NULL)
+ , m_pByteContext(NULL)
+{
+}
+CXFA_ChecksumContext::~CXFA_ChecksumContext()
+{
+ FinishChecksum();
+}
+FX_BOOL CXFA_ChecksumContext::StartChecksum()
+{
+ FinishChecksum();
+ m_pByteContext = FX_Alloc(FX_BYTE, 128);
+ FXSYS_assert(m_pByteContext != NULL);
+ CRYPT_SHA1Start(m_pByteContext);
+ m_bsChecksum.Empty();
+ m_pSAXReader = FX_SAXReader_Create();
+ return m_pSAXReader != NULL;
+}
+FX_BOOL CXFA_ChecksumContext::UpdateChecksum(IFX_FileRead *pSrcFile, FX_FILESIZE offset, size_t size)
+{
+ if (m_pSAXReader == NULL) {
+ return FALSE;
+ }
+ if (pSrcFile == NULL) {
+ return FALSE;
+ }
+ if (size < 1) {
+ size = pSrcFile->GetSize();
+ }
+ CXFA_SAXReaderHandler handler(this);
+ m_pSAXReader->SetHandler(&handler);
+ if (m_pSAXReader->StartParse(pSrcFile, (FX_DWORD)offset, (FX_DWORD)size, FX_SAXPARSEMODE_NotSkipSpace | FX_SAXPARSEMODE_NotConvert_amp | FX_SAXPARSEMODE_NotConvert_lt | FX_SAXPARSEMODE_NotConvert_gt | FX_SAXPARSEMODE_NotConvert_sharp) < 0) {
+ return FALSE;
+ }
+ return m_pSAXReader->ContinueParse(NULL) > 99;
+}
+void CXFA_ChecksumContext::FinishChecksum()
+{
+ if (m_pSAXReader != NULL) {
+ m_pSAXReader->Release();
+ m_pSAXReader = NULL;
+ }
+ if (m_pByteContext) {
+ FX_BYTE digest[20];
+ FXSYS_memset(digest, 0, 20);
+ CRYPT_SHA1Finish(m_pByteContext, digest);
+ FX_INT32 nLen = FX_Base64EncodeA(digest, 20, NULL);
+ FX_LPSTR pBuffer = m_bsChecksum.GetBuffer(nLen);
+ FX_Base64EncodeA(digest, 20, pBuffer);
+ m_bsChecksum.ReleaseBuffer(nLen);
+ FX_Free(m_pByteContext);
+ m_pByteContext = NULL;
+ }
+}
+void CXFA_ChecksumContext::GetChecksum(CFX_ByteString &bsChecksum)
+{
+ bsChecksum = m_bsChecksum;
+}
+void CXFA_ChecksumContext::Update(FX_BSTR bsText)
+{
+ if (m_pByteContext != NULL) {
+ CRYPT_SHA1Update(m_pByteContext, bsText.GetPtr(), bsText.GetLength());
+ }
+}
diff --git a/xfa/src/fxfa/src/app/xfa_checksum.h b/xfa/src/fxfa/src/app/xfa_checksum.h
new file mode 100644
index 0000000000..5e2eca72f0
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_checksum.h
@@ -0,0 +1,58 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_CHECKSUM_IMP_H
+#define _FXFA_FORMFILLER_CHECKSUM_IMP_H
+class CXFA_SAXReaderHandler;
+class CXFA_ChecksumContext;
+class CXFA_SAXContext : public CFX_Object
+{
+public:
+ CXFA_SAXContext() : m_eNode(FX_SAXNODE_Unknown)
+ {
+ }
+ CFX_ByteTextBuf m_TextBuf;
+ CFX_ByteString m_bsTagName;
+ FX_SAXNODE m_eNode;
+};
+class CXFA_SAXReaderHandler : public IFX_SAXReaderHandler, public CFX_Object
+{
+public:
+ CXFA_SAXReaderHandler(CXFA_ChecksumContext *pContext);
+ virtual ~CXFA_SAXReaderHandler();
+ virtual FX_LPVOID OnTagEnter(FX_BSTR bsTagName, FX_SAXNODE eType, FX_DWORD dwStartPos);
+ virtual void OnTagAttribute(FX_LPVOID pTag, FX_BSTR bsAttri, FX_BSTR bsValue);
+ virtual void OnTagBreak(FX_LPVOID pTag);
+ virtual void OnTagData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos);
+ virtual void OnTagClose(FX_LPVOID pTag, FX_DWORD dwEndPos);
+ virtual void OnTagEnd(FX_LPVOID pTag, FX_BSTR bsTagName, FX_DWORD dwEndPos);
+
+ virtual void OnTargetData(FX_LPVOID pTag, FX_SAXNODE eType, FX_BSTR bsData, FX_DWORD dwStartPos);
+protected:
+ void UpdateChecksum(FX_BOOL bCheckSpace);
+ CXFA_ChecksumContext *m_pContext;
+ CXFA_SAXContext m_SAXContext;
+};
+class CXFA_ChecksumContext : public IXFA_ChecksumContext, public CFX_Object
+{
+public:
+ CXFA_ChecksumContext();
+ ~CXFA_ChecksumContext();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_BOOL StartChecksum();
+ virtual FX_BOOL UpdateChecksum(IFX_FileRead *pSrcFile, FX_FILESIZE offset = 0, size_t size = 0);
+ virtual void FinishChecksum();
+ virtual void GetChecksum(CFX_ByteString &bsChecksum);
+ void Update(FX_BSTR bsText);
+protected:
+ IFX_SAXReader *m_pSAXReader;
+ FX_LPBYTE m_pByteContext;
+ CFX_ByteString m_bsChecksum;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffConfigAcc.cpp b/xfa/src/fxfa/src/app/xfa_ffConfigAcc.cpp
new file mode 100644
index 0000000000..de46a33b32
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffConfigAcc.cpp
@@ -0,0 +1,65 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffConfigAcc.h"
+CXFA_FFConfigAcc::CXFA_FFConfigAcc(CXFA_Node *pNode)
+ : m_pNode(pNode)
+ , m_pPsMapNode(NULL)
+{
+}
+CXFA_FFConfigAcc::~CXFA_FFConfigAcc()
+{
+}
+FX_INT32 CXFA_FFConfigAcc::CountChildren()
+{
+ GetPsMapNode();
+ if (m_pPsMapNode == NULL) {
+ return 0;
+ }
+ FX_INT32 iCount = 0;
+ CXFA_Node* pNode = m_pPsMapNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ iCount++;
+ }
+ return iCount;
+}
+FX_BOOL CXFA_FFConfigAcc::GetFontInfo(FX_INT32 index, CFX_WideString &wsFontFamily, CFX_WideString &wsPsName, FX_BOOL bBold, FX_BOOL bItalic)
+{
+ if (index < 0 || index >= CountChildren()) {
+ return FALSE;
+ }
+ CXFA_Node *pFontNode = m_pPsMapNode->GetChild(index, XFA_ELEMENT_Font);
+ if (pFontNode == NULL) {
+ return FALSE;
+ }
+ wsFontFamily.Empty();
+ wsPsName.Empty();
+ bBold = FALSE;
+ bItalic = FALSE;
+ pFontNode->GetAttribute(XFA_ATTRIBUTE_Typeface, wsFontFamily);
+ pFontNode->GetAttribute(XFA_ATTRIBUTE_PsName, wsPsName);
+ CFX_WideString wsValue;
+ pFontNode->GetAttribute(XFA_ATTRIBUTE_Weight, wsValue);
+ wsValue.MakeLower();
+ if (wsValue == FX_WSTRC(L"bold")) {
+ bBold = TRUE;
+ }
+ pFontNode->GetAttribute(XFA_ATTRIBUTE_Posture, wsValue);
+ wsValue.MakeLower();
+ if (wsValue == FX_WSTRC(L"italic")) {
+ bItalic = TRUE;
+ }
+ return wsFontFamily.GetLength() > 0;
+}
+void CXFA_FFConfigAcc::GetPsMapNode()
+{
+ if (m_pNode == NULL) {
+ return;
+ }
+ m_pPsMapNode = m_pNode->GetChild(0, XFA_ELEMENT_PsMap);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffConfigAcc.h b/xfa/src/fxfa/src/app/xfa_ffConfigAcc.h
new file mode 100644
index 0000000000..9cd7fc345a
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffConfigAcc.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLERCONFIGACC_IMP_H
+#define _FXFA_FORMFILLERCONFIGACC_IMP_H
+class CXFA_FFConfigAcc : public CFX_Object
+{
+public:
+ CXFA_FFConfigAcc(CXFA_Node *pNode);
+ ~CXFA_FFConfigAcc();
+ FX_INT32 CountChildren();
+ FX_BOOL GetFontInfo(FX_INT32 index, CFX_WideString &wsFontFamily, CFX_WideString &wsPsName, FX_BOOL bBold, FX_BOOL bItalic);
+private:
+ void GetPsMapNode();
+ CXFA_Node *m_pNode;
+ CXFA_Node *m_pPsMapNode;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffapp.cpp b/xfa/src/fxfa/src/app/xfa_ffapp.cpp
new file mode 100644
index 0000000000..67ec95b009
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffapp.cpp
@@ -0,0 +1,301 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffdochandler.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffapp.h"
+#include "xfa_fwltheme.h"
+#include "xfa_fontmgr.h"
+#include "xfa_ffwidgethandler.h"
+CXFA_FileRead::CXFA_FileRead(const CFX_ArrayTemplate<CPDF_Stream*> &streams)
+ : m_dwSize(0)
+{
+ m_Streams.Copy(streams);
+}
+CXFA_FileRead::~CXFA_FileRead()
+{
+ m_Streams.RemoveAll();
+ m_StreamSize.RemoveAll();
+}
+FX_FILESIZE CXFA_FileRead::GetSize()
+{
+ if (m_StreamSize.GetSize() > 0) {
+ return m_dwSize;
+ }
+ FX_INT32 iCount = m_Streams.GetSize();
+ FX_DWORD iBufferSize = 4096;
+ FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, iBufferSize);
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CPDF_StreamFilter* pStreamFilter = m_Streams[i]->GetStreamFilter(FALSE);
+ FX_DWORD dwCurSize = 0;
+ while (TRUE) {
+ FX_DWORD dwRead = pStreamFilter->ReadBlock(pBuf, iBufferSize);
+ dwCurSize += dwRead;
+ if (dwRead < iBufferSize) {
+ break;
+ }
+ }
+ m_dwSize += dwCurSize;
+ m_StreamSize.Add(dwCurSize);
+ delete pStreamFilter;
+ }
+ FX_Free(pBuf);
+ return m_dwSize;
+}
+FX_BOOL CXFA_FileRead::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
+{
+ FX_FILESIZE dwLen = 0;
+ FX_INT32 iCount = m_Streams.GetSize();
+ FX_INT32 i = 0;
+ for (; i < iCount; i++) {
+ dwLen += m_StreamSize[i];
+ if (dwLen > offset) {
+ dwLen -= m_StreamSize[i];
+ break;
+ }
+ }
+ if (i >= iCount) {
+ return FALSE;
+ }
+ CPDF_StreamFilter* pStreamFilter = m_Streams[i]->GetStreamFilter(FALSE);
+ if ((offset -= dwLen) > 0) {
+ FX_LPBYTE pBuf = FX_Alloc(FX_BYTE, offset);
+ FX_DWORD dwRead = pStreamFilter->ReadBlock(pBuf, offset);
+ FX_Free(pBuf);
+ }
+ FX_DWORD dwHadRead = pStreamFilter->ReadBlock((FX_LPBYTE)buffer, size);
+ delete pStreamFilter;
+ size -= dwHadRead;
+ if (size <= 0) {
+ return TRUE;
+ }
+ FX_DWORD dwReadSize = dwHadRead;
+ for (FX_INT32 iStart = i + 1; iStart < iCount; iStart++) {
+ CPDF_StreamFilter* pStreamFilter = m_Streams[iStart]->GetStreamFilter(FALSE);
+ FX_DWORD dwHadRead = pStreamFilter->ReadBlock(((FX_LPBYTE)buffer) + dwReadSize, size);
+ delete pStreamFilter;
+ size -= dwHadRead;
+ if (size <= 0) {
+ return TRUE;
+ }
+ dwReadSize += dwHadRead;
+ }
+ return FALSE;
+}
+CXFA_FileRead2::CXFA_FileRead2(const CFX_ArrayTemplate<CPDF_Stream*> &streams)
+{
+ FX_INT32 iCount = streams.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CPDF_StreamAcc &acc = m_Data.Add();
+ acc.LoadAllData(streams[i]);
+ }
+}
+FX_FILESIZE CXFA_FileRead2::GetSize()
+{
+ FX_DWORD dwSize = 0;
+ FX_INT32 iCount = m_Data.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CPDF_StreamAcc &acc = m_Data[i];
+ dwSize += acc.GetSize();
+ }
+ return dwSize;
+}
+FX_BOOL CXFA_FileRead2::ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
+{
+ FX_INT32 iCount = m_Data.GetSize();
+ FX_INT32 index = 0;
+ while (index < iCount) {
+ CPDF_StreamAcc &acc = m_Data[index];
+ FX_FILESIZE dwSize = acc.GetSize();
+ if (offset < dwSize) {
+ break;
+ }
+ offset -= dwSize;
+ index++;
+ }
+ while (index < iCount) {
+ CPDF_StreamAcc &acc = m_Data[index];
+ FX_DWORD dwSize = acc.GetSize();
+ FX_DWORD dwRead = FX_MIN(size, dwSize - offset);
+ FXSYS_memcpy(buffer, acc.GetData() + offset, dwRead);
+ size -= dwRead;
+ if (size == 0) {
+ return TRUE;
+ }
+ buffer = (FX_LPBYTE)buffer + dwRead;
+ offset = 0;
+ index++;
+ }
+ return FALSE;
+}
+IXFA_App* IXFA_App::Create(IXFA_AppProvider* pProvider)
+{
+ return FX_NEW CXFA_FFApp(pProvider);
+}
+CXFA_FFApp::CXFA_FFApp(IXFA_AppProvider* pProvider)
+ : m_pDocHandler(NULL)
+ , m_pFWLTheme(NULL)
+ , m_pProvider(pProvider)
+ , m_pFontMgr(NULL)
+ , m_pAdapterWidgetMgr(NULL)
+ , m_pFDEFontMgr(NULL)
+ , m_pMenuHandler(NULL)
+ , m_pAdapterThreadMgr(NULL)
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ , m_pFontSource(NULL)
+#endif
+{
+ m_pFWLApp = IFWL_App::Create(this);
+ FWL_SetApp(m_pFWLApp);
+ m_pFWLApp->Initialize();
+ IXFA_TimeZoneProvider::Create();
+}
+CXFA_FFApp::~CXFA_FFApp()
+{
+ if (m_pDocHandler) {
+ delete m_pDocHandler;
+ }
+ if (m_pFWLApp) {
+ m_pFWLApp->Finalize();
+ m_pFWLApp->Release();
+ }
+ if (m_pFWLTheme) {
+ m_pFWLTheme->Release();
+ }
+ if (m_pAdapterWidgetMgr) {
+ delete m_pAdapterWidgetMgr;
+ }
+ if (m_pAdapterThreadMgr) {
+ delete m_pAdapterThreadMgr;
+ m_pAdapterThreadMgr = NULL;
+ }
+ if (m_pMenuHandler) {
+ delete m_pMenuHandler;
+ m_pMenuHandler = NULL;
+ }
+ IXFA_TimeZoneProvider::Destroy();
+ if (m_pFontMgr != NULL) {
+ delete m_pFontMgr;
+ m_pFontMgr = NULL;
+ }
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ if(m_pFontSource != NULL) {
+ m_pFontSource->Release();
+ }
+#endif
+ if (m_pFDEFontMgr) {
+ m_pFDEFontMgr->Release();
+ }
+}
+IXFA_MenuHandler* CXFA_FFApp::GetMenuHandler()
+{
+ if (!m_pMenuHandler) {
+ m_pMenuHandler = FX_NEW CXFA_FFMenuHandler;
+ }
+ return m_pMenuHandler;
+}
+IXFA_DocHandler* CXFA_FFApp::GetDocHandler()
+{
+ if (!m_pDocHandler) {
+ m_pDocHandler = FX_NEW CXFA_FFDocHandler;
+ }
+ return m_pDocHandler;
+}
+XFA_HDOC CXFA_FFApp::CreateDoc(IXFA_DocProvider* pProvider, IFX_FileRead* pStream, FX_BOOL bTakeOverFile)
+{
+ CXFA_FFDoc* pDoc = FX_NEW CXFA_FFDoc(this, pProvider);
+ if (!pDoc) {
+ return NULL;
+ }
+ FX_BOOL bSuccess = pDoc->OpenDoc(pStream, bTakeOverFile);
+ if (!bSuccess) {
+ delete pDoc;
+ pDoc = NULL;
+ }
+ return (XFA_HDOC)pDoc;
+}
+XFA_HDOC CXFA_FFApp::CreateDoc(IXFA_DocProvider* pProvider, CPDF_Document *pPDFDoc)
+{
+ if (pPDFDoc == NULL) {
+ return NULL;
+ }
+ CXFA_FFDoc* pDoc = FX_NEW CXFA_FFDoc(this, pProvider);
+ if (!pDoc) {
+ return NULL;
+ }
+ FX_BOOL bSuccess = pDoc->OpenDoc(pPDFDoc);
+ if (!bSuccess) {
+ delete pDoc;
+ pDoc = NULL;
+ }
+ return (XFA_HDOC)pDoc;
+}
+
+void CXFA_FFApp::SetDefaultFontMgr(IXFA_FontMgr* pFontMgr)
+{
+ if (!m_pFontMgr) {
+ m_pFontMgr = FX_NEW CXFA_FontMgr();
+ }
+ m_pFontMgr->SetDefFontMgr(pFontMgr);
+}
+CXFA_FontMgr* CXFA_FFApp::GetXFAFontMgr()
+{
+ return m_pFontMgr;
+}
+IFX_FontMgr* CXFA_FFApp::GetFDEFontMgr()
+{
+ if (!m_pFDEFontMgr) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ m_pFDEFontMgr = IFX_FontMgr::Create(FX_GetDefFontEnumerator());
+#else
+ m_pFontSource = FX_CreateDefaultFontSourceEnum();
+ m_pFDEFontMgr = IFX_FontMgr::Create(m_pFontSource);
+#endif
+ }
+ return m_pFDEFontMgr;
+}
+CXFA_FWLTheme* CXFA_FFApp::GetFWLTheme()
+{
+ if (!m_pFWLTheme) {
+ m_pFWLTheme = FX_NEW CXFA_FWLTheme(this);
+ }
+ return m_pFWLTheme;
+}
+IFWL_AdapterWidgetMgr* CXFA_FFApp::GetWidgetMgr(IFWL_WidgetMgrDelegate *pDelegate)
+{
+ if (!m_pAdapterWidgetMgr) {
+ m_pAdapterWidgetMgr = FX_NEW CXFA_FWLAdapterWidgetMgr;
+ pDelegate->OnSetCapability(FWL_WGTMGR_DisableThread | FWL_WGTMGR_DisableForm);
+ m_pWidgetMgrDelegate = pDelegate;
+ }
+ return m_pAdapterWidgetMgr;
+}
+IFWL_AdapterThreadMgr* CXFA_FFApp::GetThreadMgr()
+{
+ if (!m_pAdapterThreadMgr) {
+ m_pAdapterThreadMgr = FX_NEW CFWL_SDAdapterThreadMgr;
+ }
+ return m_pAdapterThreadMgr;
+}
+IFWL_AdapterTimerMgr* CXFA_FFApp::GetTimerMgr()
+{
+ return m_pProvider->GetTimerMgr();
+}
+IFWL_AdapterCursorMgr* CXFA_FFApp::GetCursorMgr()
+{
+ return NULL;
+}
+IFWL_AdapterMonitorMgr* CXFA_FFApp::GetMonitorMgr()
+{
+ return NULL;
+}
+IFWL_AdapterClipboardMgr* CXFA_FFApp::GetClipboardMgr()
+{
+ return NULL;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffapp.h b/xfa/src/fxfa/src/app/xfa_ffapp.h
new file mode 100644
index 0000000000..8df5fcde65
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffapp.h
@@ -0,0 +1,92 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_APP_IMP_H
+#define _FXFA_FORMFILLER_APP_IMP_H
+class CXFA_FileRead : public IFX_FileRead, public CFX_Object
+{
+public:
+ CXFA_FileRead(const CFX_ArrayTemplate<CPDF_Stream*> &streams);
+ ~CXFA_FileRead();
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+ virtual void Release()
+ {
+ delete this;
+ }
+protected:
+ CFX_ArrayTemplate<CPDF_Stream*> m_Streams;
+ CFX_DWordArray m_StreamSize;
+ FX_DWORD m_dwSize;
+};
+class CXFA_FileRead2 : public IFX_FileRead, public CFX_Object
+{
+public:
+ CXFA_FileRead2(const CFX_ArrayTemplate<CPDF_Stream*> &streams);
+
+ virtual FX_FILESIZE GetSize();
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+
+ virtual void Release()
+ {
+ delete this;
+ }
+
+protected:
+ CFX_ObjectArray<CPDF_StreamAcc> m_Data;
+};
+class CXFA_FWLAdapterWidgetMgr;
+class CXFA_FWLTheme;
+class CXFA_FFDocHandler;
+class CXFA_FFMenuHandler;
+class CXFA_FontMgr;
+class CXFA_FFApp : public IXFA_App, public IFWL_AdapterNative, public CFX_Object
+{
+public:
+ CXFA_FFApp(IXFA_AppProvider* pProvider);
+ ~CXFA_FFApp();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual IXFA_DocHandler* GetDocHandler();
+ virtual XFA_HDOC CreateDoc(IXFA_DocProvider* pProvider, IFX_FileRead* pStream, FX_BOOL bTakeOverFile);
+ virtual XFA_HDOC CreateDoc(IXFA_DocProvider* pProvider, CPDF_Document* pPDFDoc);
+ virtual IXFA_AppProvider* GetAppProvider()
+ {
+ return m_pProvider;
+ }
+ virtual void SetDefaultFontMgr(IXFA_FontMgr* pFontMgr);
+ virtual IXFA_MenuHandler* GetMenuHandler();
+ virtual IFWL_AdapterWidgetMgr* GetWidgetMgr(IFWL_WidgetMgrDelegate* pDelegate);
+ virtual IFWL_AdapterThreadMgr* GetThreadMgr();
+ virtual IFWL_AdapterTimerMgr* GetTimerMgr();
+ virtual IFWL_AdapterCursorMgr* GetCursorMgr();
+ virtual IFWL_AdapterMonitorMgr* GetMonitorMgr();
+ virtual IFWL_AdapterClipboardMgr* GetClipboardMgr();
+ CXFA_FontMgr* GetXFAFontMgr();
+ IFX_FontMgr* GetFDEFontMgr();
+ CXFA_FWLTheme* GetFWLTheme();
+ IFWL_WidgetMgrDelegate* GetWidgetMgrDelegate()
+ {
+ return m_pWidgetMgrDelegate;
+ }
+protected:
+ CXFA_FFDocHandler* m_pDocHandler;
+ IFWL_App* m_pFWLApp;
+ CXFA_FWLTheme* m_pFWLTheme;
+ IXFA_AppProvider* m_pProvider;
+ CXFA_FontMgr* m_pFontMgr;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ IFX_FontSourceEnum* m_pFontSource;
+#endif
+ CXFA_FWLAdapterWidgetMgr* m_pAdapterWidgetMgr;
+ IFWL_WidgetMgrDelegate* m_pWidgetMgrDelegate;
+ IFX_FontMgr* m_pFDEFontMgr;
+ CXFA_FFMenuHandler* m_pMenuHandler;
+ CFWL_SDAdapterThreadMgr* m_pAdapterThreadMgr;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffbarcode.cpp b/xfa/src/fxfa/src/app/xfa_ffbarcode.cpp
new file mode 100644
index 0000000000..44fe252d4f
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffbarcode.cpp
@@ -0,0 +1,223 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_fftextedit.h"
+#include "xfa_ffbarcode.h"
+static XFA_LPCBARCODETYPEENUMINFO XFA_GetBarcodeTypeByName(FX_WSTR wsName);
+CXFA_FFBarcode::CXFA_FFBarcode(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFTextEdit(pPageView, pDataAcc)
+{
+}
+CXFA_FFBarcode::~CXFA_FFBarcode()
+{
+}
+FX_BOOL CXFA_FFBarcode::LoadWidget()
+{
+ CFWL_Barcode* pFWLBarcode = CFWL_Barcode::Create();
+ if(pFWLBarcode) {
+ pFWLBarcode->Initialize();
+ }
+ m_pNormalWidget = pFWLBarcode;
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ m_pNormalWidget->LockUpdate();
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+ pFWLBarcode->SetText(wsText);
+ UpdateWidgetProperty();
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFBarcode::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+ RenderCaption(pGS, &mtRotate);
+ CFX_RectF rtWidget;
+ m_pNormalWidget->GetWidgetRect(rtWidget);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
+ mt.Concat(mtRotate);
+ m_pNormalWidget->DrawWidget(pGS, &mt);
+}
+void CXFA_FFBarcode::UpdateWidgetProperty()
+{
+ CXFA_FFTextEdit::UpdateWidgetProperty();
+ CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget;
+ CFX_WideString wsType = GetDataAcc()->GetBarcodeType();
+ XFA_LPCBARCODETYPEENUMINFO pBarcodeTypeInfo = XFA_GetBarcodeTypeByName(wsType);
+ pBarCodeWidget->SetType(pBarcodeTypeInfo->eBCType);
+ CXFA_WidgetAcc *pAcc = GetDataAcc();
+ FX_INT32 intVal;
+ FX_CHAR charVal;
+ FX_BOOL boolVal;
+ FX_FLOAT floatVal;
+ if (pAcc->GetBarcodeAttribute_CharEncoding(intVal)) {
+ pBarCodeWidget->SetCharEncoding((BC_CHAR_ENCODING)intVal);
+ }
+ if (pAcc->GetBarcodeAttribute_Checksum(intVal)) {
+ pBarCodeWidget->SetCalChecksum(intVal);
+ }
+ if (pAcc->GetBarcodeAttribute_DataLength(intVal)) {
+ pBarCodeWidget->SetDataLength(intVal);
+ }
+ if (pAcc->GetBarcodeAttribute_StartChar(charVal)) {
+ pBarCodeWidget->SetStartChar(charVal);
+ }
+ if (pAcc->GetBarcodeAttribute_EndChar(charVal)) {
+ pBarCodeWidget->SetEndChar(charVal);
+ }
+ if (pAcc->GetBarcodeAttribute_ECLevel(intVal)) {
+ pBarCodeWidget->SetErrorCorrectionLevel(intVal);
+ }
+ if (pAcc->GetBarcodeAttribute_ModuleWidth(intVal)) {
+ pBarCodeWidget->SetModuleWidth(intVal);
+ }
+ if (pAcc->GetBarcodeAttribute_ModuleHeight(intVal)) {
+ pBarCodeWidget->SetModuleHeight(intVal);
+ }
+ if (pAcc->GetBarcodeAttribute_PrintChecksum(boolVal)) {
+ pBarCodeWidget->SetPrintChecksum(boolVal);
+ }
+ if (pAcc->GetBarcodeAttribute_TextLocation(intVal)) {
+ pBarCodeWidget->SetTextLocation((BC_TEXT_LOC)intVal);
+ }
+ if (pAcc->GetBarcodeAttribute_Truncate(boolVal)) {
+ pBarCodeWidget->SetTruncated(boolVal);
+ }
+ if (pAcc->GetBarcodeAttribute_WideNarrowRatio(floatVal)) {
+ pBarCodeWidget->SetWideNarrowRatio((FX_INT32)floatVal);
+ }
+ if (pBarcodeTypeInfo->eName == XFA_BARCODETYPE_code3Of9
+ || pBarcodeTypeInfo->eName == XFA_BARCODETYPE_ean8
+ || pBarcodeTypeInfo->eName == XFA_BARCODETYPE_ean13
+ || pBarcodeTypeInfo->eName == XFA_BARCODETYPE_upcA) {
+ pBarCodeWidget->SetPrintChecksum(TRUE);
+ }
+}
+FX_BOOL CXFA_FFBarcode::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget;
+ if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) {
+ return FALSE;
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+ return FALSE;
+ }
+ return CXFA_FFTextEdit::OnLButtonDown(dwFlags, fx, fy);
+}
+FX_BOOL CXFA_FFBarcode::OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFWL_Barcode* pBarCodeWidget = (CFWL_Barcode*)m_pNormalWidget;
+ if (!pBarCodeWidget || pBarCodeWidget->IsProtectedType()) {
+ return FALSE;
+ }
+ return CXFA_FFTextEdit::OnRButtonDown(dwFlags, fx, fy);
+}
+extern const XFA_BARCODETYPEENUMINFO g_XFABarCodeTypeEnumData[] = {
+ {0x7fb4a18, (FX_LPCWSTR)L"ean13", XFA_BARCODETYPE_ean13, BC_EAN13},
+ {0x8d13a3d, (FX_LPCWSTR)L"code11", XFA_BARCODETYPE_code11, BC_UNKNOWN},
+ {0x8d149a8, (FX_LPCWSTR)L"code49", XFA_BARCODETYPE_code49, BC_UNKNOWN},
+ {0x8d16347, (FX_LPCWSTR)L"code93", XFA_BARCODETYPE_code93, BC_UNKNOWN},
+ {0x91a92e2, (FX_LPCWSTR)L"upsMaxicode", XFA_BARCODETYPE_upsMaxicode, BC_UNKNOWN},
+ {0xa7d48dc, (FX_LPCWSTR)L"fim", XFA_BARCODETYPE_fim, BC_UNKNOWN},
+ {0xb359fe9, (FX_LPCWSTR)L"msi", XFA_BARCODETYPE_msi, BC_UNKNOWN},
+ {0x121f738c, (FX_LPCWSTR)L"code2Of5Matrix", XFA_BARCODETYPE_code2Of5Matrix, BC_UNKNOWN},
+ {0x15358616, (FX_LPCWSTR)L"ucc128", XFA_BARCODETYPE_ucc128, BC_UNKNOWN},
+ {0x1f4bfa05, (FX_LPCWSTR)L"rfid", XFA_BARCODETYPE_rfid, BC_UNKNOWN},
+ {0x1fda71bc, (FX_LPCWSTR)L"rss14Stacked", XFA_BARCODETYPE_rss14Stacked, BC_UNKNOWN},
+ {0x22065087, (FX_LPCWSTR)L"ean8add2", XFA_BARCODETYPE_ean8add2, BC_UNKNOWN},
+ {0x2206508a, (FX_LPCWSTR)L"ean8add5", XFA_BARCODETYPE_ean8add5, BC_UNKNOWN},
+ {0x2278366c, (FX_LPCWSTR)L"codabar", XFA_BARCODETYPE_codabar, BC_CODABAR},
+ {0x2a039a8d, (FX_LPCWSTR)L"telepen", XFA_BARCODETYPE_telepen, BC_UNKNOWN},
+ {0x323ed337, (FX_LPCWSTR)L"upcApwcd", XFA_BARCODETYPE_upcApwcd, BC_UNKNOWN},
+ {0x347a1846, (FX_LPCWSTR)L"postUSIMB", XFA_BARCODETYPE_postUSIMB, BC_UNKNOWN},
+ {0x391bb836, (FX_LPCWSTR)L"code128", XFA_BARCODETYPE_code128, BC_CODE128},
+ {0x398eddaf, (FX_LPCWSTR)L"dataMatrix", XFA_BARCODETYPE_dataMatrix, BC_DATAMATRIX},
+ {0x3cff60a8, (FX_LPCWSTR)L"upcEadd2", XFA_BARCODETYPE_upcEadd2, BC_UNKNOWN},
+ {0x3cff60ab, (FX_LPCWSTR)L"upcEadd5", XFA_BARCODETYPE_upcEadd5, BC_UNKNOWN},
+ {0x402cb188, (FX_LPCWSTR)L"code2Of5Standard", XFA_BARCODETYPE_code2Of5Standard, BC_UNKNOWN},
+ {0x411764f7, (FX_LPCWSTR)L"aztec", XFA_BARCODETYPE_aztec, BC_UNKNOWN},
+ {0x44d4e84c, (FX_LPCWSTR)L"ean8", XFA_BARCODETYPE_ean8, BC_EAN8},
+ {0x48468902, (FX_LPCWSTR)L"ucc128sscc", XFA_BARCODETYPE_ucc128sscc, BC_UNKNOWN},
+ {0x4880aea4, (FX_LPCWSTR)L"upcAadd2", XFA_BARCODETYPE_upcAadd2, BC_UNKNOWN},
+ {0x4880aea7, (FX_LPCWSTR)L"upcAadd5", XFA_BARCODETYPE_upcAadd5, BC_UNKNOWN},
+ {0x54f18256, (FX_LPCWSTR)L"code2Of5Industrial", XFA_BARCODETYPE_code2Of5Industrial, BC_UNKNOWN},
+ {0x58e15f25, (FX_LPCWSTR)L"rss14Limited", XFA_BARCODETYPE_rss14Limited, BC_UNKNOWN},
+ {0x5c08d1b9, (FX_LPCWSTR)L"postAUSReplyPaid", XFA_BARCODETYPE_postAUSReplyPaid, BC_UNKNOWN},
+ {0x5fa700bd, (FX_LPCWSTR)L"rss14", XFA_BARCODETYPE_rss14, BC_UNKNOWN},
+ {0x631a7e35, (FX_LPCWSTR)L"logmars", XFA_BARCODETYPE_logmars, BC_UNKNOWN},
+ {0x6a236236, (FX_LPCWSTR)L"pdf417", XFA_BARCODETYPE_pdf417, BC_PDF417},
+ {0x6d098ece, (FX_LPCWSTR)L"upcean2", XFA_BARCODETYPE_upcean2, BC_UNKNOWN},
+ {0x6d098ed1, (FX_LPCWSTR)L"upcean5", XFA_BARCODETYPE_upcean5, BC_UNKNOWN},
+ {0x76b04eed, (FX_LPCWSTR)L"code3Of9extended", XFA_BARCODETYPE_code3Of9extended, BC_UNKNOWN},
+ {0x7c7db84a, (FX_LPCWSTR)L"maxicode", XFA_BARCODETYPE_maxicode, BC_UNKNOWN},
+ {0x8266f7f7, (FX_LPCWSTR)L"ucc128random", XFA_BARCODETYPE_ucc128random, BC_UNKNOWN},
+ {0x83eca147, (FX_LPCWSTR)L"postUSDPBC", XFA_BARCODETYPE_postUSDPBC, BC_UNKNOWN},
+ {0x8dd71de0, (FX_LPCWSTR)L"postAUSStandard", XFA_BARCODETYPE_postAUSStandard, BC_UNKNOWN},
+ {0x98adad85, (FX_LPCWSTR)L"plessey", XFA_BARCODETYPE_plessey, BC_UNKNOWN},
+ {0x9f84cce6, (FX_LPCWSTR)L"ean13pwcd", XFA_BARCODETYPE_ean13pwcd, BC_UNKNOWN},
+ {0xb514fbe9, (FX_LPCWSTR)L"upcA", XFA_BARCODETYPE_upcA, BC_UPCA},
+ {0xb514fbed, (FX_LPCWSTR)L"upcE", XFA_BARCODETYPE_upcE, BC_UNKNOWN},
+ {0xb5c6a853, (FX_LPCWSTR)L"ean13add2", XFA_BARCODETYPE_ean13add2, BC_UNKNOWN},
+ {0xb5c6a856, (FX_LPCWSTR)L"ean13add5", XFA_BARCODETYPE_ean13add5, BC_UNKNOWN},
+ {0xb81fc512, (FX_LPCWSTR)L"postUKRM4SCC", XFA_BARCODETYPE_postUKRM4SCC, BC_UNKNOWN},
+ {0xbad34b22, (FX_LPCWSTR)L"code128SSCC", XFA_BARCODETYPE_code128SSCC, BC_UNKNOWN},
+ {0xbfbe0cf6, (FX_LPCWSTR)L"postUS5Zip", XFA_BARCODETYPE_postUS5Zip, BC_UNKNOWN},
+ {0xc56618e8, (FX_LPCWSTR)L"pdf417macro", XFA_BARCODETYPE_pdf417macro, BC_UNKNOWN},
+ {0xca730f8a, (FX_LPCWSTR)L"code2Of5Interleaved", XFA_BARCODETYPE_code2Of5Interleaved, BC_UNKNOWN},
+ {0xd0097ac6, (FX_LPCWSTR)L"rss14Expanded", XFA_BARCODETYPE_rss14Expanded, BC_UNKNOWN},
+ {0xd25a0240, (FX_LPCWSTR)L"postAUSCust2", XFA_BARCODETYPE_postAUSCust2, BC_UNKNOWN},
+ {0xd25a0241, (FX_LPCWSTR)L"postAUSCust3", XFA_BARCODETYPE_postAUSCust3, BC_UNKNOWN},
+ {0xd53ed3e7, (FX_LPCWSTR)L"rss14Truncated", XFA_BARCODETYPE_rss14Truncated, BC_UNKNOWN},
+ {0xe72bcd57, (FX_LPCWSTR)L"code128A", XFA_BARCODETYPE_code128A, BC_UNKNOWN},
+ {0xe72bcd58, (FX_LPCWSTR)L"code128B", XFA_BARCODETYPE_code128B, BC_CODE128_B},
+ {0xe72bcd59, (FX_LPCWSTR)L"code128C", XFA_BARCODETYPE_code128C, BC_CODE128_C},
+ {0xee83c50f, (FX_LPCWSTR)L"rss14StackedOmni", XFA_BARCODETYPE_rss14StackedOmni, BC_UNKNOWN},
+ {0xf2a18f7e, (FX_LPCWSTR)L"QRCode", XFA_BARCODETYPE_QRCode, BC_QR_CODE},
+ {0xfaeaf37f, (FX_LPCWSTR)L"postUSStandard", XFA_BARCODETYPE_postUSStandard, BC_UNKNOWN},
+ {0xfb48155c, (FX_LPCWSTR)L"code3Of9", XFA_BARCODETYPE_code3Of9, BC_CODE39},
+};
+extern const FX_INT32 g_iXFABarcodeTypeCount = sizeof(g_XFABarCodeTypeEnumData) / sizeof(XFA_BARCODETYPEENUMINFO);
+static XFA_LPCBARCODETYPEENUMINFO XFA_GetBarcodeTypeByName(FX_WSTR wsName)
+{
+ FX_INT32 iLength = wsName.GetLength();
+ if (iLength == 0) {
+ return NULL;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength, TRUE);
+ FX_INT32 iStart = 0, iEnd = g_iXFABarcodeTypeCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCBARCODETYPEENUMINFO pInfo = g_XFABarCodeTypeEnumData + iMid;
+ if (uHash == pInfo->uHash) {
+ return pInfo;
+ } else if (uHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffbarcode.h b/xfa/src/fxfa/src/app/xfa_ffbarcode.h
new file mode 100644
index 0000000000..35b4212efa
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffbarcode.h
@@ -0,0 +1,93 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_BARCODE_IMP_H
+#define _FXFA_FORMFILLER_BARCODE_IMP_H
+class CXFA_FFTextEdit;
+class CXFA_FFBarcode : public CXFA_FFTextEdit
+{
+public:
+ CXFA_FFBarcode(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFBarcode();
+ virtual FX_BOOL LoadWidget();
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+ virtual void UpdateWidgetProperty();
+ virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+};
+enum XFA_BARCODETYPEENUM {
+ XFA_BARCODETYPE_aztec,
+ XFA_BARCODETYPE_codabar,
+ XFA_BARCODETYPE_code11,
+ XFA_BARCODETYPE_code128,
+ XFA_BARCODETYPE_code128A,
+ XFA_BARCODETYPE_code128B,
+ XFA_BARCODETYPE_code128C,
+ XFA_BARCODETYPE_code128SSCC,
+ XFA_BARCODETYPE_code2Of5Industrial,
+ XFA_BARCODETYPE_code2Of5Interleaved,
+ XFA_BARCODETYPE_code2Of5Matrix,
+ XFA_BARCODETYPE_code2Of5Standard,
+ XFA_BARCODETYPE_code3Of9,
+ XFA_BARCODETYPE_code3Of9extended,
+ XFA_BARCODETYPE_code49,
+ XFA_BARCODETYPE_code93,
+ XFA_BARCODETYPE_dataMatrix,
+ XFA_BARCODETYPE_ean13,
+ XFA_BARCODETYPE_ean13add2,
+ XFA_BARCODETYPE_ean13add5,
+ XFA_BARCODETYPE_ean13pwcd,
+ XFA_BARCODETYPE_ean8,
+ XFA_BARCODETYPE_ean8add2,
+ XFA_BARCODETYPE_ean8add5,
+ XFA_BARCODETYPE_fim,
+ XFA_BARCODETYPE_logmars,
+ XFA_BARCODETYPE_maxicode,
+ XFA_BARCODETYPE_msi,
+ XFA_BARCODETYPE_pdf417,
+ XFA_BARCODETYPE_pdf417macro,
+ XFA_BARCODETYPE_plessey,
+ XFA_BARCODETYPE_postAUSCust2,
+ XFA_BARCODETYPE_postAUSCust3,
+ XFA_BARCODETYPE_postAUSReplyPaid,
+ XFA_BARCODETYPE_postAUSStandard,
+ XFA_BARCODETYPE_postUKRM4SCC,
+ XFA_BARCODETYPE_postUS5Zip,
+ XFA_BARCODETYPE_postUSDPBC,
+ XFA_BARCODETYPE_postUSIMB,
+ XFA_BARCODETYPE_postUSStandard,
+ XFA_BARCODETYPE_QRCode,
+ XFA_BARCODETYPE_rfid,
+ XFA_BARCODETYPE_rss14,
+ XFA_BARCODETYPE_rss14Expanded,
+ XFA_BARCODETYPE_rss14Limited,
+ XFA_BARCODETYPE_rss14Stacked,
+ XFA_BARCODETYPE_rss14StackedOmni,
+ XFA_BARCODETYPE_rss14Truncated,
+ XFA_BARCODETYPE_telepen,
+ XFA_BARCODETYPE_ucc128,
+ XFA_BARCODETYPE_ucc128random,
+ XFA_BARCODETYPE_ucc128sscc,
+ XFA_BARCODETYPE_upcA,
+ XFA_BARCODETYPE_upcAadd2,
+ XFA_BARCODETYPE_upcAadd5,
+ XFA_BARCODETYPE_upcApwcd,
+ XFA_BARCODETYPE_upcE,
+ XFA_BARCODETYPE_upcEadd2,
+ XFA_BARCODETYPE_upcEadd5,
+ XFA_BARCODETYPE_upcean2,
+ XFA_BARCODETYPE_upcean5,
+ XFA_BARCODETYPE_upsMaxicode
+};
+struct XFA_BARCODETYPEENUMINFO {
+ FX_UINT32 uHash;
+ FX_LPCWSTR pName;
+ XFA_BARCODETYPEENUM eName;
+ BC_TYPE eBCType;
+};
+typedef XFA_BARCODETYPEENUMINFO const * XFA_LPCBARCODETYPEENUMINFO;
+extern const XFA_BARCODETYPEENUMINFO g_XFABarCodeTypeEnumData[];
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffcheckbutton.cpp b/xfa/src/fxfa/src/app/xfa_ffcheckbutton.cpp
new file mode 100644
index 0000000000..6115d61bcd
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffcheckbutton.cpp
@@ -0,0 +1,341 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffcheckbutton.h"
+#include "xfa_ffexclgroup.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+CXFA_FFCheckButton::CXFA_FFCheckButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pPageView, pDataAcc)
+ , m_pOldDelegate(NULL)
+{
+ m_rtCheckBox.Set(0, 0, 0, 0);
+}
+CXFA_FFCheckButton::~CXFA_FFCheckButton()
+{
+}
+FX_BOOL CXFA_FFCheckButton::LoadWidget()
+{
+ CFWL_CheckBox* pCheckBox = CFWL_CheckBox::Create();
+ pCheckBox->Initialize();
+ m_pNormalWidget = pCheckBox;
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ if (m_pDataAcc->IsRadioButton()) {
+ pCheckBox->ModifyStylesEx(FWL_STYLEEXT_CKB_RadioButton, 0xFFFFFFFF);
+ }
+ m_pNormalWidget = (CFWL_Widget*)pCheckBox;
+ m_pNormalWidget->SetPrivateData(m_pNormalWidget->GetWidget(), this, NULL);
+ m_pNormalWidget->LockUpdate();
+ UpdateWidgetProperty();
+ XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
+ SetFWLCheckState(eState);
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFCheckButton::UpdateWidgetProperty()
+{
+ CFWL_CheckBox* pCheckBox = (CFWL_CheckBox*)m_pNormalWidget;
+ if (!m_pNormalWidget) {
+ return;
+ }
+ FX_FLOAT fSize = m_pDataAcc->GetCheckButtonSize();
+ pCheckBox->SetBoxSize(fSize);
+ FX_DWORD dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCross;
+ FX_INT32 iCheckMark = m_pDataAcc->GetCheckButtonMark();
+ switch(iCheckMark) {
+ case XFA_ATTRIBUTEENUM_Check:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCheck;
+ break;
+ case XFA_ATTRIBUTEENUM_Circle:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
+ break;
+ case XFA_ATTRIBUTEENUM_Cross:
+ break;
+ case XFA_ATTRIBUTEENUM_Diamond:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeDiamond;
+ break;
+ case XFA_ATTRIBUTEENUM_Square:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeSquare;
+ break;
+ case XFA_ATTRIBUTEENUM_Star:
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeStar;
+ break;
+ default: {
+ FX_INT32 iShape = m_pDataAcc->GetCheckButtonShape();
+ if (iShape == XFA_ATTRIBUTEENUM_Round) {
+ dwStyleEx = FWL_STYLEEXT_CKB_SignShapeCircle;
+ }
+ }
+ break;
+ }
+ if (m_pDataAcc->IsAllowNeutral()) {
+ dwStyleEx |= FWL_STYLEEXT_CKB_3State;
+ }
+ pCheckBox->ModifyStylesEx(dwStyleEx, FWL_STYLEEXT_CKB_SignShapeMask | FWL_STYLEEXT_CKB_3State);
+}
+FX_BOOL CXFA_FFCheckButton::LayoutWidget()
+{
+ CXFA_FFWidget::LayoutWidget();
+ FX_FLOAT fCheckSize = m_pDataAcc->GetCheckButtonSize();
+ CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
+ CFX_RectF rtWidget;
+ GetRectWithoutRotate(rtWidget);
+ if (mgWidget.IsExistInXML()) {
+ XFA_RectWidthoutMargin(rtWidget, mgWidget);
+ }
+ FX_INT32 iCapPlacement = -1;
+ FX_FLOAT fCapReserve = 0;
+ CXFA_Caption caption = m_pDataAcc->GetCaption();
+ if (caption.IsExistInXML() && caption.GetPresence()) {
+ m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);
+ iCapPlacement = caption.GetPlacementType();
+ fCapReserve = caption.GetReserve();
+ if (fCapReserve <= 0) {
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Top || iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
+ fCapReserve = rtWidget.height - fCheckSize;
+ } else {
+ fCapReserve = rtWidget.width - fCheckSize;
+ }
+ }
+ }
+ FX_INT32 iHorzAlign = XFA_ATTRIBUTEENUM_Left;
+ FX_INT32 iVertAlign = XFA_ATTRIBUTEENUM_Top;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ iHorzAlign = para.GetHorizontalAlign();
+ iVertAlign = para.GetVerticalAlign();
+ }
+ m_rtUI = rtWidget;
+ CXFA_Margin mgCap = caption.GetMargin();
+ switch(iCapPlacement) {
+ case XFA_ATTRIBUTEENUM_Left: {
+ m_rtCaption.width = fCapReserve;
+ CapLeftRightPlacement(mgCap);
+ m_rtUI.width -= fCapReserve;
+ m_rtUI.left += fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Top: {
+ m_rtCaption.height = fCapReserve;
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ m_rtUI.height -= fCapReserve;
+ m_rtUI.top += fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Right: {
+ m_rtCaption.left = m_rtCaption.right() - fCapReserve;
+ m_rtCaption.width = fCapReserve;
+ CapLeftRightPlacement(mgCap);
+ m_rtUI.width -= fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom: {
+ m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
+ m_rtCaption.height = fCapReserve;
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ m_rtUI.height -= fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Inline:
+ break;
+ default:
+ iHorzAlign = XFA_ATTRIBUTEENUM_Right;
+ break;
+ }
+ if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
+ m_rtUI.left += (m_rtUI.width - fCheckSize) / 2;
+ } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
+ m_rtUI.left = m_rtUI.right() - fCheckSize;
+ }
+ if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
+ m_rtUI.top += (m_rtUI.height - fCheckSize) / 2;
+ } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
+ m_rtUI.top = m_rtUI.bottom() - fCheckSize;
+ }
+ m_rtUI.width = fCheckSize;
+ m_rtUI.height = fCheckSize;
+ AddUIMargin(iCapPlacement);
+ m_rtCheckBox = m_rtUI;
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ if (borderUI) {
+ CXFA_Margin margin = borderUI.GetMargin();
+ if (margin.IsExistInXML()) {
+ XFA_RectWidthoutMargin(m_rtUI, margin);
+ }
+ }
+ m_rtUI.Normalize();
+ LayoutCaption();
+ SetFWLRect();
+ if (m_pNormalWidget) {
+ m_pNormalWidget->Update();
+ }
+ return TRUE;
+}
+void CXFA_FFCheckButton::CapLeftRightPlacement(CXFA_Margin mgCap)
+{
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ if (m_rtCaption.height < 0) {
+ m_rtCaption.top += m_rtCaption.height;
+ }
+ if (m_rtCaption.width < 0) {
+ m_rtCaption.left += m_rtCaption.width;
+ m_rtCaption.width = -m_rtCaption.width;
+ }
+}
+void CXFA_FFCheckButton::AddUIMargin(FX_INT32 iCapPlacement)
+{
+ CFX_RectF rtUIMargin;
+ m_pDataAcc->GetUIMargin(rtUIMargin);
+ m_rtUI.top -= rtUIMargin.top / 2 - rtUIMargin.height / 2;
+ FX_FLOAT fLeftAddRight = rtUIMargin.left + rtUIMargin.width;
+ FX_FLOAT fTopAddBottom = rtUIMargin.top + rtUIMargin.height;
+ if (m_rtUI.width < fLeftAddRight) {
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Right || iCapPlacement == XFA_ATTRIBUTEENUM_Left) {
+ m_rtUI.left -= fLeftAddRight - m_rtUI.width;
+ } else {
+ m_rtUI.left -= 2 * (fLeftAddRight - m_rtUI.width);
+ }
+ m_rtUI.width += 2 * (fLeftAddRight - m_rtUI.width);
+ }
+ if (m_rtUI.height < fTopAddBottom) {
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) {
+ m_rtUI.left -= fTopAddBottom - m_rtUI.height;
+ }
+ m_rtUI.top -= fTopAddBottom - m_rtUI.height;
+ m_rtUI.height += 2 * (fTopAddBottom - m_rtUI.height);
+ }
+}
+void CXFA_FFCheckButton::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ DrawBorder(pGS, borderUI, m_rtUI, &mtRotate, m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round ? XFA_DRAWBOX_ForceRound : 0);
+ RenderCaption(pGS, &mtRotate);
+ DrawHighlight(pGS, &mtRotate, dwStatus, m_pDataAcc->GetCheckButtonShape() == XFA_ATTRIBUTEENUM_Round);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, m_rtCheckBox.left, m_rtCheckBox.top);
+ mt.Concat(mtRotate);
+ GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(), pGS, &mt);
+}
+FX_BOOL CXFA_FFCheckButton::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ if (!IsButtonDown()) {
+ return FALSE;
+ }
+ SetButtonDown(FALSE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+XFA_CHECKSTATE CXFA_FFCheckButton::FWLState2XFAState()
+{
+ XFA_CHECKSTATE eCheckState = XFA_CHECKSTATE_Off;
+ FX_DWORD dwState = m_pNormalWidget->GetStates();
+ if (dwState & FWL_STATE_CKB_Checked) {
+ eCheckState = XFA_CHECKSTATE_On;
+ } else if (dwState & FWL_STATE_CKB_Neutral) {
+ eCheckState = XFA_CHECKSTATE_Neutral;
+ }
+ return eCheckState;
+}
+FX_BOOL CXFA_FFCheckButton::CommitData()
+{
+ XFA_CHECKSTATE eCheckState = FWLState2XFAState();
+ m_pDataAcc->SetCheckState(eCheckState, TRUE);
+ return TRUE;
+}
+FX_BOOL CXFA_FFCheckButton::IsDataChanged()
+{
+ XFA_CHECKSTATE eCheckState = FWLState2XFAState();
+ return m_pDataAcc->GetCheckState() != eCheckState;
+}
+void CXFA_FFCheckButton::SetFWLCheckState(XFA_CHECKSTATE eCheckState)
+{
+ if (eCheckState == XFA_CHECKSTATE_Neutral) {
+ m_pNormalWidget->SetStates(FWL_STATE_CKB_Neutral, TRUE);
+ } else {
+ m_pNormalWidget->SetStates(FWL_STATE_CKB_Checked, eCheckState == XFA_CHECKSTATE_On);
+ }
+}
+FX_BOOL CXFA_FFCheckButton::UpdateFWLData()
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ XFA_CHECKSTATE eState = m_pDataAcc->GetCheckState();
+ SetFWLCheckState(eState);
+ m_pNormalWidget->Update();
+ return TRUE;
+}
+FX_INT32 CXFA_FFCheckButton::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFCheckButton::OnProcessEvent(CFWL_Event *pEvent)
+{
+ CXFA_FFField::OnProcessEvent(pEvent);
+ FX_DWORD dwEventID = pEvent->GetClassID();
+ switch (dwEventID) {
+ case FWL_EVTHASH_CKB_CheckStateChanged: {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Change;
+ m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
+ CXFA_WidgetAcc* pFFExclGroup = m_pDataAcc->GetExclGroup();
+ if (ProcessCommittedData()) {
+ eParam.m_pTarget = pFFExclGroup;
+ if (pFFExclGroup) {
+ m_pDocView->AddValidateWidget(pFFExclGroup);
+ m_pDocView->AddCalculateWidgetAcc(pFFExclGroup);
+ pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+ }
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+ } else {
+ SetFWLCheckState(m_pDataAcc->GetCheckState());
+ }
+ if (pFFExclGroup) {
+ eParam.m_pTarget = pFFExclGroup;
+ pFFExclGroup->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+ }
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+ break;
+ }
+ default: {
+ }
+ }
+ return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFCheckButton::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffcheckbutton.h b/xfa/src/fxfa/src/app/xfa_ffcheckbutton.h
new file mode 100644
index 0000000000..5c32a6d966
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffcheckbutton.h
@@ -0,0 +1,36 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_CHECKBUTTON_IMP_H
+#define _FXFA_FORMFILLER_CHECKBUTTON_IMP_H
+class CXFA_FFExclGroup;
+class CXFA_FFCheckButton : public CXFA_FFField
+{
+public:
+ CXFA_FFCheckButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFCheckButton();
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+
+ virtual FX_BOOL LoadWidget();
+ virtual FX_BOOL LayoutWidget();
+ virtual FX_BOOL UpdateFWLData();
+ virtual void UpdateWidgetProperty();
+ virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ void SetFWLCheckState(XFA_CHECKSTATE eCheckState);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+
+protected:
+ virtual FX_BOOL CommitData();
+ virtual FX_BOOL IsDataChanged();
+ void CapLeftRightPlacement(CXFA_Margin mgCap);
+ void AddUIMargin(FX_INT32 iCapPlacement);
+ XFA_CHECKSTATE FWLState2XFAState();
+ IFWL_WidgetDelegate* m_pOldDelegate;
+ CFX_RectF m_rtCheckBox;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffchoicelist.cpp b/xfa/src/fxfa/src/app/xfa_ffchoicelist.cpp
new file mode 100644
index 0000000000..d7faedc45a
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffchoicelist.cpp
@@ -0,0 +1,571 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffchoicelist.h"
+#include "xfa_ffdoc.h"
+CXFA_FFListBox::CXFA_FFListBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pPageView, pDataAcc)
+ , m_pOldDelegate(NULL)
+{
+}
+CXFA_FFListBox::~CXFA_FFListBox()
+{
+ if (m_pNormalWidget) {
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->UnregisterEventTarget(pWidget);
+ }
+}
+FX_BOOL CXFA_FFListBox::LoadWidget()
+{
+ CFWL_ListBox* pListBox = CFWL_ListBox::Create();
+ pListBox->Initialize();
+ pListBox->ModifyStyles(FWL_WGTSTYLE_VScroll | FWL_WGTSTYLE_NoBackground, 0xFFFFFFFF);
+ m_pNormalWidget = (CFWL_Widget*)pListBox;
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ m_pNormalWidget->LockUpdate();
+ CFX_WideStringArray wsLabelArray;
+ m_pDataAcc->GetChoiceListItems(wsLabelArray, FALSE);
+ FX_INT32 iItems = wsLabelArray.GetSize();
+ for (FX_INT32 i = 0; i < iItems; i++) {
+ pListBox->AddString(wsLabelArray[i]);
+ }
+ FX_DWORD dwExtendedStyle = FWL_STYLEEXT_LTB_ShowScrollBarFocus;
+ if (m_pDataAcc->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+ dwExtendedStyle |= FWL_STYLEEXT_LTB_MultiSelection;
+ }
+ dwExtendedStyle |= GetAlignment();
+ m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+ CFX_Int32Array iSelArray;
+ m_pDataAcc->GetSelectedItems(iSelArray);
+ FX_INT32 iSelCount = iSelArray.GetSize();
+ for (FX_INT32 j = 0; j < iSelCount; j++) {
+ FWL_HLISTITEM item = pListBox->GetItem(iSelArray[j]);
+ pListBox->SetSelItem(item, TRUE);
+ }
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+FX_BOOL CXFA_FFListBox::OnKillFocus(CXFA_FFWidget* pNewFocus)
+{
+ FX_BOOL flag = ProcessCommittedData();
+ if (!flag) {
+ UpdateFWLData();
+ }
+ CXFA_FFField::OnKillFocus(pNewFocus);
+ return TRUE;
+}
+FX_BOOL CXFA_FFListBox::CommitData()
+{
+ FXSYS_assert(m_pNormalWidget != NULL);
+ CFWL_ListBox* pListBox = (CFWL_ListBox*)m_pNormalWidget;
+ FX_INT32 iSels = pListBox->CountSelItems();
+ CFX_Int32Array iSelArray;
+ for (FX_INT32 i = 0; i < iSels; i++) {
+ iSelArray.Add(pListBox->GetSelIndex(i));
+ }
+ m_pDataAcc->SetSelectdItems(iSelArray, TRUE);
+ return TRUE;
+}
+FX_BOOL CXFA_FFListBox::IsDataChanged()
+{
+ CFX_Int32Array iSelArray;
+ m_pDataAcc->GetSelectedItems(iSelArray);
+ FX_INT32 iOldSels = iSelArray.GetSize();
+ CFWL_ListBox* pListBox = (CFWL_ListBox*)m_pNormalWidget;
+ FX_INT32 iSels = pListBox->CountSelItems();
+ if (iOldSels == iSels) {
+ FX_INT32 iIndex = 0;
+ for (; iIndex < iSels; iIndex++) {
+ FWL_HLISTITEM hlistItem = pListBox->GetItem(iSelArray[iIndex]);
+ if(!(pListBox->GetItemStates(hlistItem) && FWL_ITEMSTATE_LTB_Selected)) {
+ break;
+ }
+ }
+ if (iIndex == iSels) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FX_DWORD CXFA_FFListBox::GetAlignment()
+{
+ FX_DWORD dwExtendedStyle = 0;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ FX_INT32 iHorz = para.GetHorizontalAlign();
+ switch(iHorz) {
+ case XFA_ATTRIBUTEENUM_Center:
+ dwExtendedStyle |= FWL_STYLEEXT_LTB_CenterAlign;
+ break;
+ case XFA_ATTRIBUTEENUM_Justify:
+ break;
+ case XFA_ATTRIBUTEENUM_JustifyAll:
+ break;
+ case XFA_ATTRIBUTEENUM_Radix:
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ dwExtendedStyle |= FWL_STYLEEXT_LTB_RightAlign;
+ break;
+ default:
+ dwExtendedStyle |= FWL_STYLEEXT_LTB_LeftAlign;
+ break;
+ }
+ }
+ return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFListBox::UpdateFWLData()
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_ListBox* pListBox = ((CFWL_ListBox*)m_pNormalWidget);
+ CFX_ArrayTemplate<FWL_HLISTITEM> selItemArray;
+ CFX_Int32Array iSelArray;
+ m_pDataAcc->GetSelectedItems(iSelArray);
+ FX_INT32 iSelCount = iSelArray.GetSize();
+ for (FX_INT32 j = 0; j < iSelCount; j++) {
+ FWL_HLISTITEM lpItemSel = pListBox->GetSelItem(iSelArray[j]);
+ selItemArray.Add(lpItemSel);
+ }
+ pListBox->SetSelItem(pListBox->GetSelItem(-1), FALSE);
+ for(FX_INT32 i = 0; i < iSelCount; i++) {
+ ((CFWL_ListBox*)m_pNormalWidget)->SetSelItem(selItemArray[i], TRUE);
+ }
+ m_pNormalWidget->Update();
+ return TRUE;
+}
+void CXFA_FFListBox::OnSelectChanged(IFWL_Widget *pWidget, const CFX_Int32Array &arrSels)
+{
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Change;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
+ CFWL_ListBox* pListBox = (CFWL_ListBox*)m_pNormalWidget;
+ FX_INT32 iSels = pListBox->CountSelItems();
+ if (iSels > 0) {
+ pListBox->GetItemText(pListBox->GetSelItem(0), eParam.m_wsNewText);
+ }
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+}
+void CXFA_FFListBox::SetItemState(FX_INT32 nIndex, FX_BOOL bSelected)
+{
+ FWL_HLISTITEM item = ((CFWL_ListBox*)m_pNormalWidget)->GetSelItem(nIndex);
+ ((CFWL_ListBox*)m_pNormalWidget)->SetSelItem(item, bSelected);
+ m_pNormalWidget->Update();
+ AddInvalidateRect();
+}
+void CXFA_FFListBox::InsertItem(FX_WSTR wsLabel, FX_INT32 nIndex )
+{
+ CFX_WideString wsTemp(wsLabel);
+ ((CFWL_ListBox*)m_pNormalWidget)->AddString(wsTemp);
+ m_pNormalWidget->Update();
+ AddInvalidateRect();
+}
+void CXFA_FFListBox::DeleteItem(FX_INT32 nIndex)
+{
+ if (nIndex < 0) {
+ ((CFWL_ListBox*)m_pNormalWidget)->DeleteAll();
+ } else {
+ ((CFWL_ListBox*)m_pNormalWidget)->DeleteString(((CFWL_ListBox*)m_pNormalWidget)->GetItem(nIndex));
+ }
+ m_pNormalWidget->Update();
+ AddInvalidateRect();
+}
+FX_INT32 CXFA_FFListBox::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFListBox::OnProcessEvent(CFWL_Event *pEvent)
+{
+ CXFA_FFField::OnProcessEvent(pEvent);
+ FX_DWORD dwEventID = pEvent->GetClassID();
+ switch (dwEventID) {
+ case FWL_EVTHASH_LTB_SelChanged: {
+ CFX_Int32Array arrSels;
+ OnSelectChanged(m_pNormalWidget->GetWidget(), arrSels);
+ break;
+ }
+ default: {
+ }
+ }
+ return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFListBox::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
+CXFA_FFComboBox::CXFA_FFComboBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pPageView, pDataAcc)
+ , m_pOldDelegate(NULL)
+{
+}
+CXFA_FFComboBox::~CXFA_FFComboBox()
+{
+}
+FX_BOOL CXFA_FFComboBox::GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus)
+{
+ if (bDrawFocus) {
+ return FALSE;
+ }
+#ifndef _XFA_EMB
+ return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
+#endif
+ GetRectWithoutRotate(rtBox);
+ if (m_pNormalWidget) {
+ CFX_RectF rtWidget;
+ ((CFWL_ComboBox*)m_pNormalWidget)->GetBBox(rtWidget);
+ rtBox.Union(rtWidget);
+ }
+ CFX_Matrix mt;
+ GetRotateMatrix(mt);
+ mt.TransformRect(rtBox);
+ return TRUE;
+}
+FX_BOOL CXFA_FFComboBox::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFX_RectF rtWidget;
+ ((CFWL_ComboBox*)m_pNormalWidget)->GetBBox(rtWidget);
+ if (rtWidget.Contains(fx, fy)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_FFComboBox::LoadWidget()
+{
+ CFWL_ComboBox* pComboBox = CFWL_ComboBox::Create();
+ pComboBox->Initialize();
+ m_pNormalWidget = (CFWL_Widget*)pComboBox;
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ m_pNormalWidget->LockUpdate();
+ CFX_WideStringArray wsLabelArray;
+ m_pDataAcc->GetChoiceListItems(wsLabelArray, FALSE);
+ FX_INT32 iItems = wsLabelArray.GetSize();
+ for (FX_INT32 i = 0; i < iItems; i++) {
+ pComboBox->AddString(wsLabelArray[i]);
+ }
+ CFX_Int32Array iSelArray;
+ m_pDataAcc->GetSelectedItems(iSelArray);
+ FX_INT32 iSelCount = iSelArray.GetSize();
+ if (iSelCount > 0) {
+ pComboBox->SetCurSel(iSelArray[0]);
+ } else {
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Raw);
+ pComboBox->SetEditText(wsText);
+ }
+ UpdateWidgetProperty();
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFComboBox::UpdateWidgetProperty()
+{
+ CFWL_ComboBox* pComboBox = (CFWL_ComboBox*)m_pNormalWidget;
+ if (!pComboBox) {
+ return;
+ }
+ FX_DWORD dwExtendedStyle = 0;
+ FX_DWORD dwEditStyles = FWL_STYLEEXT_EDT_ReadOnly | FWL_STYLEEXT_EDT_LastLineHeight;
+ dwExtendedStyle |= UpdateUIProperty();
+ if (m_pDataAcc->IsChoiceListAllowTextEntry()) {
+ dwEditStyles &= ~FWL_STYLEEXT_EDT_ReadOnly;
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_DropDown;
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_ReadOnly;
+ }
+ dwExtendedStyle |= GetAlignment();
+ m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+ if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+ dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
+ }
+ pComboBox->EditModifyStylesEx(dwEditStyles, 0xFFFFFFFF);
+}
+FX_BOOL CXFA_FFComboBox::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!CXFA_FFField::OnRButtonUp(dwFlags, fx, fy)) {
+ return FALSE;
+ }
+ CFX_PointF pt;
+ pt.Set(fx, fy);
+ GetDoc()->GetDocProvider()->PopupMenu((XFA_HWIDGET)this, pt, NULL);
+ return TRUE;
+}
+FX_BOOL CXFA_FFComboBox::OnKillFocus(CXFA_FFWidget* pNewWidget)
+{
+ FX_BOOL flag = ProcessCommittedData();
+ if (!flag) {
+ UpdateFWLData();
+ }
+ CXFA_FFField::OnKillFocus(pNewWidget);
+ return TRUE;
+}
+void CXFA_FFComboBox::OpenDropDownList()
+{
+ ((CFWL_ComboBox*)m_pNormalWidget)->OpenDropDownList(TRUE);
+}
+FX_BOOL CXFA_FFComboBox::CommitData()
+{
+ return m_pDataAcc->SetValue(m_wsNewValue, XFA_VALUEPICTURE_Raw);
+}
+FX_BOOL CXFA_FFComboBox::IsDataChanged()
+{
+ CFWL_ComboBox* pFWLcombobox = ((CFWL_ComboBox*)m_pNormalWidget);
+ CFX_WideString wsText;
+ pFWLcombobox->GetEditText(wsText);
+ FX_INT32 iCursel = pFWLcombobox->GetCurSel();
+ if (iCursel >= 0) {
+ CFX_WideString wsSel;
+ pFWLcombobox->GetTextByIndex(iCursel, wsSel);
+ if (wsSel == wsText) {
+ m_pDataAcc->GetChoiceListItem(wsText, iCursel, TRUE);
+ }
+ }
+ CFX_WideString wsOldValue;
+ m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Raw);
+ if (wsOldValue != wsText) {
+ m_wsNewValue = wsText;
+ return TRUE;
+ }
+ return FALSE;
+}
+void CXFA_FFComboBox::FWLEventSelChange(CXFA_EventParam* pParam)
+{
+ pParam->m_eType = XFA_EVENT_Change;
+ pParam->m_pTarget = m_pDataAcc;
+ CFWL_ComboBox* pFWLcombobox = ((CFWL_ComboBox*)m_pNormalWidget);
+ pFWLcombobox->GetEditText(pParam->m_wsNewText);
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, pParam);
+}
+FX_DWORD CXFA_FFComboBox::GetAlignment()
+{
+ FX_DWORD dwExtendedStyle = 0;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ FX_INT32 iHorz = para.GetHorizontalAlign();
+ switch(iHorz) {
+ case XFA_ATTRIBUTEENUM_Center:
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_EditHCenter | FWL_STYLEEXT_CMB_ListItemCenterAlign;
+ break;
+ case XFA_ATTRIBUTEENUM_Justify:
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_EditJustified;
+ break;
+ case XFA_ATTRIBUTEENUM_JustifyAll:
+ break;
+ case XFA_ATTRIBUTEENUM_Radix:
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ break;
+ default:
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_EditHNear | FWL_STYLEEXT_CMB_ListItemLeftAlign;
+ break;
+ }
+ FX_INT32 iVert = para.GetVerticalAlign();
+ switch(iVert) {
+ case XFA_ATTRIBUTEENUM_Middle:
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVCenter;
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom:
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVFar;
+ break;
+ default:
+ dwExtendedStyle |= FWL_STYLEEXT_CMB_EditVNear;
+ break;
+ }
+ }
+ return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFComboBox::UpdateFWLData()
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFX_Int32Array iSelArray;
+ m_pDataAcc->GetSelectedItems(iSelArray);
+ FX_INT32 iSelCount = iSelArray.GetSize();
+ if (iSelCount > 0) {
+ ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(iSelArray[0]);
+ } else {
+ CFX_WideString wsText;
+ ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(-1);
+ m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Raw);
+ ((CFWL_ComboBox*)m_pNormalWidget)->SetEditText(wsText);
+ }
+ m_pNormalWidget->Update();
+ return TRUE;
+}
+FX_BOOL CXFA_FFComboBox::CanUndo()
+{
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && ((CFWL_ComboBox*)m_pNormalWidget)->EditCanUndo();
+}
+FX_BOOL CXFA_FFComboBox::CanRedo()
+{
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && ((CFWL_ComboBox*)m_pNormalWidget)->EditCanRedo();
+}
+FX_BOOL CXFA_FFComboBox::Undo()
+{
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && ((CFWL_ComboBox*)m_pNormalWidget)->EditUndo();
+}
+FX_BOOL CXFA_FFComboBox::Redo()
+{
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && ((CFWL_ComboBox*)m_pNormalWidget)->EditRedo();
+}
+FX_BOOL CXFA_FFComboBox::CanCopy()
+{
+ return ((CFWL_ComboBox*)m_pNormalWidget)->EditCanCopy();
+}
+FX_BOOL CXFA_FFComboBox::CanCut()
+{
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+ return FALSE;
+ }
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && ((CFWL_ComboBox*)m_pNormalWidget)->EditCanCut();
+}
+FX_BOOL CXFA_FFComboBox::CanPaste()
+{
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && (m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open);
+}
+FX_BOOL CXFA_FFComboBox::CanSelectAll()
+{
+ return ((CFWL_ComboBox*)m_pNormalWidget)->EditCanSelectAll();
+}
+FX_BOOL CXFA_FFComboBox::Copy(CFX_WideString &wsCopy)
+{
+ return ((CFWL_ComboBox*)m_pNormalWidget)->EditCopy(wsCopy);
+}
+FX_BOOL CXFA_FFComboBox::Cut(CFX_WideString &wsCut)
+{
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && ((CFWL_ComboBox*)m_pNormalWidget)->EditCut(wsCut);
+}
+FX_BOOL CXFA_FFComboBox::Paste(const CFX_WideString &wsPaste)
+{
+ return m_pDataAcc->IsChoiceListAllowTextEntry() && ((CFWL_ComboBox*)m_pNormalWidget)->EditPaste(wsPaste);
+}
+FX_BOOL CXFA_FFComboBox::SelectAll()
+{
+ return ((CFWL_ComboBox*)m_pNormalWidget)->EditSelectAll();
+}
+FX_BOOL CXFA_FFComboBox::Delete()
+{
+ return ((CFWL_ComboBox*)m_pNormalWidget)->EditDelete();
+}
+FX_BOOL CXFA_FFComboBox::DeSelect()
+{
+ return ((CFWL_ComboBox*)m_pNormalWidget)->EditDeSelect();
+}
+void CXFA_FFComboBox::SetItemState(FX_INT32 nIndex, FX_BOOL bSelected)
+{
+ if (bSelected) {
+ ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(nIndex);
+ } else {
+ ((CFWL_ComboBox*)m_pNormalWidget)->SetCurSel(-1);
+ }
+ m_pNormalWidget->Update();
+ AddInvalidateRect();
+}
+void CXFA_FFComboBox::InsertItem(FX_WSTR wsLabel, FX_INT32 nIndex )
+{
+ ((CFWL_ComboBox*)m_pNormalWidget)->AddString(wsLabel);
+ m_pNormalWidget->Update();
+ AddInvalidateRect();
+}
+void CXFA_FFComboBox::DeleteItem(FX_INT32 nIndex)
+{
+ if (nIndex < 0) {
+ ((CFWL_ComboBox*)m_pNormalWidget)->RemoveAll();
+ } else {
+ ((CFWL_ComboBox*)m_pNormalWidget)->RemoveAt(nIndex);
+ }
+ m_pNormalWidget->Update();
+ AddInvalidateRect();
+}
+void CXFA_FFComboBox::OnTextChanged(IFWL_Widget *pWidget, const CFX_WideString &wsChanged)
+{
+ CXFA_EventParam eParam;
+ m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
+ eParam.m_wsChange = wsChanged;
+ FWLEventSelChange(&eParam);
+}
+void CXFA_FFComboBox::OnSelectChanged(IFWL_Widget *pWidget, const CFX_Int32Array &arrSels, FX_BOOL bLButtonUp)
+{
+ CXFA_EventParam eParam;
+ m_pDataAcc->GetValue(eParam.m_wsPrevText, XFA_VALUEPICTURE_Raw);
+ FWLEventSelChange(&eParam);
+ if (m_pDataAcc->GetChoiceListCommitOn() == XFA_ATTRIBUTEENUM_Select && bLButtonUp) {
+ m_pDocView->SetFocusWidgetAcc(NULL);
+ }
+}
+void CXFA_FFComboBox::OnPreOpen(IFWL_Widget *pWidget)
+{
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_PreOpen;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_PreOpen, &eParam);
+}
+void CXFA_FFComboBox::OnPostOpen(IFWL_Widget *pWidget)
+{
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_PostOpen;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_PostOpen, &eParam);
+}
+void CXFA_FFComboBox::OnAddDoRecord(IFWL_Widget *pWidget)
+{
+ GetDoc()->GetDocProvider()->AddDoRecord((XFA_HWIDGET)this);
+}
+FX_INT32 CXFA_FFComboBox::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFComboBox::OnProcessEvent(CFWL_Event *pEvent)
+{
+ CXFA_FFField::OnProcessEvent(pEvent);
+ FX_DWORD dwEventID = pEvent->GetClassID();
+ switch (dwEventID) {
+ case FWL_EVTHASH_CMB_SelChanged: {
+ CFWL_EvtCmbSelChanged *postEvent = (CFWL_EvtCmbSelChanged*)pEvent;
+ OnSelectChanged(m_pNormalWidget->GetWidget(), postEvent->iArraySels, postEvent->bLButtonUp);
+ break;
+ }
+ case FWL_EVTHASH_CMB_EditChanged: {
+ CFX_WideString wsChanged;
+ OnTextChanged(m_pNormalWidget->GetWidget(), wsChanged);
+ break;
+ }
+ case FWL_EVTHASH_CMB_PreDropDown: {
+ OnPreOpen(m_pNormalWidget->GetWidget());
+ break;
+ }
+ case FWL_EVTHASH_CMB_PostDropDown: {
+ OnPostOpen(m_pNormalWidget->GetWidget());
+ break;
+ }
+ default: {
+ }
+ }
+ return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFComboBox::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffchoicelist.h b/xfa/src/fxfa/src/app/xfa_ffchoicelist.h
new file mode 100644
index 0000000000..72463ec513
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffchoicelist.h
@@ -0,0 +1,82 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_CHOICELIST_IMP_H
+#define _FXFA_FORMFILLER_CHOICELIST_IMP_H
+class CXFA_FFListBox : public CXFA_FFField
+{
+public:
+ CXFA_FFListBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFListBox();
+ virtual FX_BOOL LoadWidget();
+ virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+protected:
+ virtual FX_BOOL CommitData();
+ virtual FX_BOOL UpdateFWLData();
+ virtual FX_BOOL IsDataChanged();
+ FX_DWORD GetAlignment();
+public:
+ void OnSelectChanged(IFWL_Widget *pWidget, const CFX_Int32Array &arrSels);
+ void SetItemState(FX_INT32 nIndex, FX_BOOL bSelected);
+ void InsertItem(FX_WSTR wsLabel, FX_INT32 nIndex = -1);
+ void DeleteItem(FX_INT32 nIndex);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ IFWL_WidgetDelegate* m_pOldDelegate;
+};
+class CXFA_FFComboBox : public CXFA_FFField
+{
+public:
+ CXFA_FFComboBox(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFComboBox();
+ virtual FX_BOOL GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus = FALSE);
+ virtual FX_BOOL LoadWidget();
+ virtual void UpdateWidgetProperty();
+ virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+ virtual FX_BOOL CanUndo();
+ virtual FX_BOOL CanRedo();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+
+ virtual FX_BOOL CanCopy();
+ virtual FX_BOOL CanCut();
+ virtual FX_BOOL CanPaste();
+ virtual FX_BOOL CanSelectAll();
+ virtual FX_BOOL Copy(CFX_WideString &wsCopy);
+ virtual FX_BOOL Cut(CFX_WideString &wsCut);
+ virtual FX_BOOL Paste(const CFX_WideString &wsPaste);
+ virtual FX_BOOL SelectAll();
+ virtual FX_BOOL Delete();
+ virtual FX_BOOL DeSelect();
+ void OpenDropDownList();
+protected:
+ virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL CommitData();
+ virtual FX_BOOL UpdateFWLData();
+ virtual FX_BOOL IsDataChanged();
+ FX_DWORD GetAlignment();
+ void FWLEventSelChange(CXFA_EventParam* pParam);
+
+ CFX_WideString m_wsNewValue;
+public:
+ void OnTextChanged(IFWL_Widget *pWidget, const CFX_WideString &wsChanged);
+ void OnSelectChanged(IFWL_Widget *pWidget, const CFX_Int32Array &arrSels, FX_BOOL bLButtonUp);
+ void OnPreOpen(IFWL_Widget *pWidget);
+ void OnPostOpen(IFWL_Widget *pWidget);
+ void OnAddDoRecord(IFWL_Widget *pWidget);
+ void SetItemState(FX_INT32 nIndex, FX_BOOL bSelected);
+ void InsertItem(FX_WSTR wsLabel, FX_INT32 nIndex = -1);
+ void DeleteItem(FX_INT32 nIndex);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ IFWL_WidgetDelegate* m_pOldDelegate;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffdoc.cpp b/xfa/src/fxfa/src/app/xfa_ffdoc.cpp
new file mode 100644
index 0000000000..9c686036c0
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdoc.cpp
@@ -0,0 +1,453 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffnotify.h"
+#include "xfa_fontmgr.h"
+CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocProvider* pDocProvider)
+ : m_pDocProvider(pDocProvider)
+ , m_dwDocType(XFA_DOCTYPE_Static)
+ , m_pDocument(NULL)
+ , m_pStream(NULL)
+ , m_pApp(pApp)
+ , m_pNotify(NULL)
+ , m_pPDFDoc(NULL)
+ , m_bOwnStream(TRUE)
+{
+}
+CXFA_FFDoc::~CXFA_FFDoc()
+{
+ CloseDoc();
+}
+FX_DWORD CXFA_FFDoc::GetDocType()
+{
+ return m_dwDocType;
+}
+FX_INT32 CXFA_FFDoc::StartLoad()
+{
+ m_pNotify = FX_NEW CXFA_FFNotify(this);
+ IXFA_DocParser* pDocParser = IXFA_DocParser::Create(m_pNotify);
+ FX_INT32 iStatus = pDocParser->StartParse(m_pStream);
+ m_pDocument = pDocParser->GetDocument();
+ return iStatus;
+}
+FX_BOOL XFA_GetPDFContentsFromPDFXML(IFDE_XMLNode *pPDFElement, FX_LPBYTE &pByteBuffer, FX_INT32& iBufferSize)
+{
+ IFDE_XMLElement* pDocumentElement = NULL;
+ for (IFDE_XMLNode *pXMLNode = pPDFElement->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ CFX_WideString wsTagName;
+ IFDE_XMLElement * pXMLElement = (IFDE_XMLElement *)pXMLNode;
+ pXMLElement->GetTagName(wsTagName);
+ if (wsTagName.Equal(FX_WSTRC(L"document"))) {
+ pDocumentElement = pXMLElement;
+ break;
+ }
+ }
+ }
+ if (!pDocumentElement) {
+ return FALSE;
+ }
+ IFDE_XMLElement* pChunkElement = NULL;
+ for (IFDE_XMLNode *pXMLNode = pDocumentElement->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ CFX_WideString wsTagName;
+ IFDE_XMLElement * pXMLElement = (IFDE_XMLElement *)pXMLNode;
+ pXMLElement->GetTagName(wsTagName);
+ if (wsTagName.Equal(FX_WSTRC(L"chunk"))) {
+ pChunkElement = pXMLElement;
+ break;
+ }
+ }
+ }
+ if (!pChunkElement) {
+ return FALSE;
+ }
+ CFX_WideString wsPDFContent;
+ pChunkElement->GetTextData(wsPDFContent);
+ iBufferSize = FX_Base64DecodeW(wsPDFContent, wsPDFContent.GetLength(), NULL);
+ pByteBuffer = FX_Alloc(FX_BYTE, iBufferSize + 1);
+ if (!pByteBuffer) {
+ return FALSE;
+ }
+ pByteBuffer[iBufferSize] = '0';
+ FX_Base64DecodeW(wsPDFContent, wsPDFContent.GetLength(), pByteBuffer);
+ return TRUE;
+}
+void XFA_XPDPacket_MergeRootNode(CXFA_Node *pOriginRoot, CXFA_Node* pNewRoot)
+{
+ CXFA_Node* pChildNode = pNewRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChildNode) {
+ CXFA_Node* pOriginChild = pOriginRoot->GetFirstChildByName(pChildNode->GetNameHash());
+ if (pOriginChild) {
+ pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ } else {
+ CXFA_Node *pNextSibling = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pNewRoot->RemoveChild(pChildNode);
+ pOriginRoot->InsertChild(pChildNode);
+ pChildNode = pNextSibling;
+ pNextSibling = NULL;
+ }
+ }
+}
+FX_INT32 CXFA_FFDoc::DoLoad(IFX_Pause *pPause )
+{
+ FX_INT32 iStatus = m_pDocument->GetParser()->DoParse(pPause);
+ if (iStatus == XFA_PARSESTATUS_Done && !m_pPDFDoc) {
+ CXFA_Node* pPDFNode = (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Pdf);
+ if (!pPDFNode) {
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ IFDE_XMLNode *pPDFXML = pPDFNode->GetXMLMappingNode();
+ if (pPDFXML->GetType() != FDE_XMLNODE_Element) {
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ FX_INT32 iBufferSize = 0;
+ FX_LPBYTE pByteBuffer = NULL;
+ IFX_FileRead* pXFAReader = NULL;
+ if (XFA_GetPDFContentsFromPDFXML(pPDFXML, pByteBuffer, iBufferSize)) {
+ pXFAReader = FX_CreateMemoryStream(pByteBuffer, iBufferSize, TRUE);
+ if (!pXFAReader) {
+ if (pByteBuffer) {
+ FX_Free(pByteBuffer);
+ pByteBuffer = NULL;
+ }
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ } else {
+ CFX_WideString wsHref;
+ ((IFDE_XMLElement*)pPDFXML)->GetString((FX_LPCWSTR)L"href", wsHref);
+ if (!wsHref.IsEmpty()) {
+ pXFAReader = GetDocProvider()->OpenLinkedFile((XFA_HDOC)this, wsHref);
+ }
+ }
+ if (!pXFAReader) {
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ CPDF_Document* pPDFDocument = GetDocProvider()->OpenPDF(reinterpret_cast<XFA_HDOC>(this), pXFAReader, TRUE);
+ FXSYS_assert(!m_pPDFDoc);
+ if (!OpenDoc(pPDFDocument)) {
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ IXFA_Parser* pParser = IXFA_Parser::Create(m_pDocument, TRUE);
+ if (!pParser) {
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ CXFA_Node* pRootNode = NULL;
+ if (pParser->StartParse(m_pStream) == XFA_PARSESTATUS_Ready && pParser->DoParse(NULL) == XFA_PARSESTATUS_Done) {
+ pRootNode = pParser->GetRootNode();
+ }
+ if (pRootNode && m_pDocument->GetRoot()) {
+ XFA_XPDPacket_MergeRootNode(m_pDocument->GetRoot(), pRootNode);
+ iStatus = XFA_PARSESTATUS_Done;
+ } else {
+ iStatus = XFA_PARSESTATUS_StatusErr;
+ }
+ pParser->Release();
+ pParser = NULL;
+ }
+ return iStatus;
+}
+void CXFA_FFDoc::StopLoad()
+{
+ m_pApp->GetXFAFontMgr()->LoadDocFonts((XFA_HDOC)this);
+ m_dwDocType = XFA_DOCTYPE_Static;
+ CXFA_Node* pConfig = (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Config);
+ if (!pConfig) {
+ return;
+ }
+ CXFA_Node* pAcrobat = pConfig->GetFirstChildByClass(XFA_ELEMENT_Acrobat);
+ if (!pAcrobat) {
+ return;
+ }
+ CXFA_Node* pAcrobat7 = pAcrobat->GetFirstChildByClass(XFA_ELEMENT_Acrobat7);
+ if (!pAcrobat7) {
+ return;
+ }
+ CXFA_Node* pDynamicRender = pAcrobat7->GetFirstChildByClass(XFA_ELEMENT_DynamicRender);
+ if (!pDynamicRender) {
+ return;
+ }
+ CFX_WideString wsType;
+ if (pDynamicRender->TryContent(wsType) && wsType == FX_WSTRC(L"required")) {
+ m_dwDocType = XFA_DOCTYPE_Dynamic;
+ }
+}
+IXFA_DocView* CXFA_FFDoc::CreateDocView(FX_DWORD dwView )
+{
+ CXFA_FFDocView* pDocView = (CXFA_FFDocView*)m_mapTypeToDocView.GetValueAt((FX_LPVOID)(FX_UINTPTR)dwView);
+ if (!pDocView) {
+ pDocView = FX_NEW CXFA_FFDocView(this);
+ m_mapTypeToDocView.SetAt((FX_LPVOID)(FX_UINTPTR)dwView, pDocView);
+ }
+ return pDocView;
+}
+CXFA_FFDocView* CXFA_FFDoc::GetDocView(IXFA_DocLayout* pLayout)
+{
+ FX_POSITION ps = m_mapTypeToDocView.GetStartPosition();
+ while (ps) {
+ FX_LPVOID pType;
+ CXFA_FFDocView* pDocView;
+ m_mapTypeToDocView.GetNextAssoc(ps, pType, (void*&)pDocView);
+ if (pDocView->GetXFALayout() == pLayout) {
+ return pDocView;
+ }
+ }
+ return NULL;
+}
+CXFA_FFDocView* CXFA_FFDoc::GetDocView()
+{
+ FX_POSITION ps = m_mapTypeToDocView.GetStartPosition();
+ if (ps) {
+ FX_LPVOID pType;
+ CXFA_FFDocView* pDocView;
+ m_mapTypeToDocView.GetNextAssoc(ps, pType, (void*&)pDocView);
+ return pDocView;
+ }
+ return NULL;
+}
+FX_BOOL CXFA_FFDoc::OpenDoc(IFX_FileRead* pStream, FX_BOOL bTakeOverFile)
+{
+ m_bOwnStream = bTakeOverFile;
+ m_pStream = pStream;
+ return TRUE;
+}
+FX_BOOL CXFA_FFDoc::OpenDoc(CPDF_Document* pPDFDoc)
+{
+ if (pPDFDoc == NULL) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pRoot = pPDFDoc->GetRoot();
+ if (pRoot == NULL) {
+ return FALSE;
+ }
+ CPDF_Dictionary* pAcroForm = pRoot->GetDict(FX_BSTRC("AcroForm"));
+ if (pAcroForm == NULL) {
+ return FALSE;
+ }
+ CPDF_Object* pElementXFA = pAcroForm->GetElement(FX_BSTRC("XFA"));
+ if (pElementXFA == NULL) {
+ return FALSE;
+ }
+ FX_INT32 iObjType = pElementXFA->GetType();
+ if (iObjType == PDFOBJ_REFERENCE) {
+ pElementXFA = pElementXFA->GetDirect();
+ iObjType = pElementXFA->GetType();
+ }
+ CFX_ArrayTemplate<CPDF_Stream*> xfaStreams;
+ if (iObjType == PDFOBJ_ARRAY) {
+ CPDF_Array* pXFAArray = (CPDF_Array*)pElementXFA;
+ FX_DWORD count = pXFAArray->GetCount() / 2;
+ for (FX_DWORD i = 0; i < count; i++) {
+ CPDF_Stream* pStream = pXFAArray->GetStream(i * 2 + 1);
+ if (pStream != NULL) {
+ xfaStreams.Add(pStream);
+ }
+ }
+ } else if (iObjType == PDFOBJ_STREAM) {
+ xfaStreams.Add((CPDF_Stream*)pElementXFA);
+ }
+ if (xfaStreams.GetSize() < 1) {
+ return FALSE;
+ }
+ IFX_FileRead* pFileRead = FX_NEW CXFA_FileRead2(xfaStreams);
+ if (!pFileRead) {
+ return FALSE;
+ }
+ m_pPDFDoc = pPDFDoc;
+ if (m_pStream) {
+ m_pStream->Release();
+ m_pStream = NULL;
+ }
+ m_pStream = pFileRead;
+ m_bOwnStream = TRUE;
+ return TRUE;
+}
+FX_BOOL CXFA_FFDoc::CloseDoc()
+{
+ FX_POSITION psClose = m_mapTypeToDocView.GetStartPosition();
+ while (psClose) {
+ FX_LPVOID pType;
+ CXFA_FFDocView* pDocView;
+ m_mapTypeToDocView.GetNextAssoc(psClose, pType, (void*&)pDocView);
+ pDocView->RunDocClose();
+ }
+ if (m_pDocument) {
+ m_pDocument->ClearLayoutData();
+ }
+ FX_POSITION ps = m_mapTypeToDocView.GetStartPosition();
+ while (ps) {
+ FX_LPVOID pType;
+ CXFA_FFDocView* pDocView;
+ m_mapTypeToDocView.GetNextAssoc(ps, pType, (void*&)pDocView);
+ delete pDocView;
+ }
+ m_mapTypeToDocView.RemoveAll();
+ if (m_pDocument) {
+ IXFA_Parser* pParser = m_pDocument->GetParser();
+ pParser->Release();
+ m_pDocument = NULL;
+ }
+ if (m_pNotify) {
+ delete m_pNotify;
+ m_pNotify = NULL;
+ }
+ m_pApp->GetXFAFontMgr()->ReleaseDocFonts((XFA_HDOC)this);
+ if (m_dwDocType != XFA_DOCTYPE_XDP && m_pStream && m_bOwnStream) {
+ m_pStream->Release();
+ m_pStream = NULL;
+ }
+ ps = m_mapNamedImages.GetStartPosition();
+ while (ps) {
+ FX_LPVOID pName;
+ FX_IMAGEDIB_AND_DPI* pImage = NULL;
+ m_mapNamedImages.GetNextAssoc(ps, pName, (void*&)pImage);
+ if (pImage) {
+ delete pImage->pDibSource;
+ pImage->pDibSource = NULL;
+ FX_Free(pImage);
+ pImage = NULL;
+ }
+ }
+ m_mapNamedImages.RemoveAll();
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->ClearEventTargets(FALSE);
+ return TRUE;
+}
+void CXFA_FFDoc::SetDocType(FX_DWORD dwType)
+{
+ m_dwDocType = dwType;
+}
+CPDF_Document* CXFA_FFDoc::GetPDFDoc()
+{
+ return m_pPDFDoc;
+}
+#define _FXLIB_NEW_VERSION_
+CFX_DIBitmap* CXFA_FFDoc::GetPDFNamedImage(FX_WSTR wsName, FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi)
+{
+ if (!m_pPDFDoc) {
+ return NULL;
+ }
+ FX_DWORD dwHash = FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), FALSE);
+ FX_IMAGEDIB_AND_DPI *imageDIBDpi = NULL;
+ if (m_mapNamedImages.Lookup((void*)(FX_UINTPTR)dwHash, (void*&)imageDIBDpi)) {
+ iImageXDpi = imageDIBDpi->iImageXDpi;
+ iImageYDpi = imageDIBDpi->iImageYDpi;
+ return (CFX_DIBitmap*)imageDIBDpi->pDibSource;
+ }
+ CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();
+ if (pRoot == NULL) {
+ return NULL;
+ }
+ CPDF_Dictionary* pNames = pRoot->GetDict("Names");
+ if (!pNames) {
+ return NULL;
+ }
+ CPDF_Dictionary* pXFAImages = pNames->GetDict("XFAImages");
+ if (!pXFAImages) {
+ return NULL;
+ }
+ CPDF_NameTree nametree(pXFAImages);
+#ifdef _FXLIB_NEW_VERSION_
+ CFX_ByteString bsName = PDF_EncodeText(wsName.GetPtr(), wsName.GetLength());
+ CPDF_Object* pObject = nametree.LookupValue(bsName);
+ if (!pObject) {
+ FX_INT32 iCount = nametree.GetCount();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CFX_ByteString bsTemp;
+ CPDF_Object* pTempObject = nametree.LookupValue(i, bsTemp);
+ if (bsTemp == bsName) {
+ pObject = pTempObject;
+ break;
+ }
+ }
+ }
+#else
+ CPDF_Object* pObject = nametree.LookupValue(wsName);
+ if (!pObject) {
+ FX_INT32 iCount = nametree.GetCount();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CFX_WideString wsTemp;
+ CPDF_Object* pTempObject = nametree.LookupValue(i, wsTemp);
+ if (wsTemp == wsName) {
+ pObject = pTempObject;
+ break;
+ }
+ }
+ }
+#endif
+ if (!pObject || pObject->GetType() != PDFOBJ_STREAM) {
+ return NULL;
+ }
+ if (!imageDIBDpi) {
+ imageDIBDpi = FX_Alloc(FX_IMAGEDIB_AND_DPI, 1);
+ imageDIBDpi->pDibSource = NULL;
+ imageDIBDpi->iImageXDpi = 0;
+ imageDIBDpi->iImageYDpi = 0;
+ CPDF_StreamAcc streamAcc;
+ streamAcc.LoadAllData((CPDF_Stream*)pObject);
+ IFX_FileRead* pImageFileRead = FX_CreateMemoryStream((FX_LPBYTE)streamAcc.GetData(), streamAcc.GetSize());
+ imageDIBDpi->pDibSource = XFA_LoadImageFromBuffer(pImageFileRead, FXCODEC_IMAGE_UNKNOWN, iImageXDpi, iImageYDpi);
+ imageDIBDpi->iImageXDpi = iImageXDpi;
+ imageDIBDpi->iImageYDpi = iImageYDpi;
+ pImageFileRead->Release();
+ }
+ m_mapNamedImages.SetAt((void*)(FX_UINTPTR)dwHash, imageDIBDpi);
+ return (CFX_DIBitmap*)imageDIBDpi->pDibSource;
+}
+IFDE_XMLElement* CXFA_FFDoc::GetPackageData(FX_WSTR wsPackage)
+{
+ FX_DWORD packetHash = FX_HashCode_String_GetW(wsPackage.GetPtr(), wsPackage.GetLength());
+ CXFA_Object* pObject = m_pDocument->GetXFANode(packetHash);
+ CXFA_Node *pNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;
+ if (!pNode) {
+ return NULL;
+ }
+ IFDE_XMLNode *pXMLNode = pNode->GetXMLMappingNode();
+ return (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) ? (IFDE_XMLElement *)pXMLNode : NULL;
+}
+FX_BOOL CXFA_FFDoc::SavePackage(FX_WSTR wsPackage, IFX_FileWrite* pFile, IXFA_ChecksumContext *pCSContext )
+{
+ IXFA_PacketExport *pExport = IXFA_PacketExport::Create(m_pDocument);
+ if (!pExport) {
+ return FALSE;
+ }
+ FX_DWORD packetHash = FX_HashCode_String_GetW(wsPackage.GetPtr(), wsPackage.GetLength());
+ CXFA_Node *pNode = NULL;
+ if (packetHash == XFA_HASHCODE_Xfa) {
+ pNode = m_pDocument->GetRoot();
+ } else {
+ CXFA_Object *pObject = m_pDocument->GetXFANode(packetHash);
+ pNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;
+ }
+ FX_BOOL bFlags = FALSE;
+ if (pNode) {
+ CFX_ByteString bsChecksum;
+ if (pCSContext) {
+ pCSContext->GetChecksum(bsChecksum);
+ }
+ bFlags = pExport->Export(pFile, pNode, 0, bsChecksum.GetLength() ? (FX_LPCSTR)bsChecksum : NULL);
+ } else {
+ bFlags = pExport->Export(pFile);
+ }
+ pExport->Release();
+ return bFlags;
+}
+FX_BOOL CXFA_FFDoc::ImportData(IFX_FileRead* pStream, FX_BOOL bXDP )
+{
+ FX_BOOL bRet = FALSE;
+ IXFA_PacketImport *pImport = IXFA_PacketImport::Create(m_pDocument);
+ if (pImport) {
+ bRet = pImport->ImportData(pStream);
+ pImport->Release();
+ }
+ return bRet;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffdoc.h b/xfa/src/fxfa/src/app/xfa_ffdoc.h
new file mode 100644
index 0000000000..c11c675ea6
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdoc.h
@@ -0,0 +1,63 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_DOC_IMP_H
+#define _FXFA_FORMFILLER_DOC_IMP_H
+class CXFA_FFApp;
+class CXFA_FFNotify;
+class CXFA_FFDocView;
+class IXFA_Locale;
+typedef struct _FX_IMAGEDIB_AND_DPI {
+ CFX_DIBSource* pDibSource;
+ FX_INT32 iImageXDpi;
+ FX_INT32 iImageYDpi;
+} FX_IMAGEDIB_AND_DPI;
+class CXFA_FFDoc : public CFX_Object
+{
+public:
+ CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocProvider* pDocProvider);
+ ~CXFA_FFDoc();
+ IXFA_DocProvider* GetDocProvider()
+ {
+ return m_pDocProvider;
+ }
+ FX_DWORD GetDocType();
+ FX_INT32 StartLoad();
+ FX_INT32 DoLoad(IFX_Pause *pPause = NULL);
+ void StopLoad();
+ IXFA_DocView* CreateDocView(FX_DWORD dwView = 0);
+ FX_BOOL OpenDoc(IFX_FileRead* pStream, FX_BOOL bTakeOverFile);
+ FX_BOOL OpenDoc(CPDF_Document* pPDFDoc);
+ FX_BOOL CloseDoc();
+ void SetDocType(FX_DWORD dwType);
+ CXFA_Document* GetXFADoc()
+ {
+ return m_pDocument;
+ }
+ CXFA_FFApp* GetApp()
+ {
+ return m_pApp;
+ }
+ CXFA_FFDocView* GetDocView(IXFA_DocLayout* pLayout);
+ CXFA_FFDocView* GetDocView();
+ CPDF_Document* GetPDFDoc();
+ CFX_DIBitmap* GetPDFNamedImage(FX_WSTR wsName, FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi);
+ IFDE_XMLElement* GetPackageData(FX_WSTR wsPackage);
+ FX_BOOL SavePackage(FX_WSTR wsPackage, IFX_FileWrite* pFile, IXFA_ChecksumContext *pCSContext = NULL);
+ FX_BOOL ImportData(IFX_FileRead* pStream, FX_BOOL bXDP = TRUE);
+protected:
+ IXFA_DocProvider* m_pDocProvider;
+ CXFA_Document* m_pDocument;
+ IFX_FileRead* m_pStream;
+ CXFA_FFApp* m_pApp;
+ CXFA_FFNotify* m_pNotify;
+ CPDF_Document* m_pPDFDoc;
+ CFX_MapPtrToPtr m_mapNamedImages;
+ CFX_MapPtrToPtr m_mapTypeToDocView;
+ FX_DWORD m_dwDocType;
+ FX_BOOL m_bOwnStream;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffdochandler.cpp b/xfa/src/fxfa/src/app/xfa_ffdochandler.cpp
new file mode 100644
index 0000000000..426a455d4f
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdochandler.cpp
@@ -0,0 +1,113 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffdochandler.h"
+#include "xfa_ffdoc.h"
+CXFA_FFDocHandler::CXFA_FFDocHandler()
+{
+}
+CXFA_FFDocHandler::~CXFA_FFDocHandler()
+{
+}
+void CXFA_FFDocHandler::ReleaseDoc(XFA_HDOC hDoc)
+{
+ delete (CXFA_FFDoc*)hDoc;
+}
+IXFA_DocProvider* CXFA_FFDocHandler::GetDocProvider(XFA_HDOC hDoc)
+{
+ return ((CXFA_FFDoc*)hDoc)->GetDocProvider();
+}
+FX_DWORD CXFA_FFDocHandler::GetDocType(XFA_HDOC hDoc)
+{
+ return ((CXFA_FFDoc*)hDoc)->GetDocType();
+}
+FX_INT32 CXFA_FFDocHandler::StartLoad(XFA_HDOC hDoc)
+{
+ return ((CXFA_FFDoc*)hDoc)->StartLoad();
+}
+FX_INT32 CXFA_FFDocHandler::DoLoad(XFA_HDOC hDoc, IFX_Pause *pPause )
+{
+ return ((CXFA_FFDoc*)hDoc)->DoLoad(pPause);
+}
+void CXFA_FFDocHandler::StopLoad(XFA_HDOC hDoc)
+{
+ ((CXFA_FFDoc*)hDoc)->StopLoad();
+}
+
+IXFA_DocView* CXFA_FFDocHandler::CreateDocView(XFA_HDOC hDoc, FX_DWORD dwView )
+{
+ return ((CXFA_FFDoc*)hDoc)->CreateDocView(dwView);
+}
+FX_INT32 CXFA_FFDocHandler::CountPackages(XFA_HDOC hDoc)
+{
+ return 0;
+}
+void CXFA_FFDocHandler::GetPackageName(XFA_HDOC hDoc, FX_INT32 iPackage, CFX_WideStringC &wsPackage)
+{
+}
+IFDE_XMLElement* CXFA_FFDocHandler::GetPackageData(XFA_HDOC hDoc, FX_WSTR wsPackage)
+{
+ return ((CXFA_FFDoc*)hDoc)->GetPackageData(wsPackage);
+}
+FX_BOOL CXFA_FFDocHandler::SavePackage(XFA_HDOC hDoc, FX_WSTR wsPackage, IFX_FileWrite* pFile, IXFA_ChecksumContext *pCSContext )
+{
+ return ((CXFA_FFDoc*)hDoc)->SavePackage(wsPackage, pFile, pCSContext);
+}
+FX_BOOL CXFA_FFDocHandler::CloseDoc(XFA_HDOC hDoc)
+{
+ return ((CXFA_FFDoc*)hDoc)->CloseDoc();
+}
+
+FX_BOOL CXFA_FFDocHandler::ImportData(XFA_HDOC hDoc, IFX_FileRead* pStream, FX_BOOL bXDP )
+{
+ return ((CXFA_FFDoc*)hDoc)->ImportData(pStream, bXDP);
+}
+void CXFA_FFDocHandler::SetJSERuntime(XFA_HDOC hDoc, FXJSE_HRUNTIME hRuntime)
+{
+ ((CXFA_FFDoc*)hDoc)->GetXFADoc()->InitScriptContext(hRuntime);
+}
+FXJSE_HVALUE CXFA_FFDocHandler::GetXFAScriptObject(XFA_HDOC hDoc)
+{
+ CXFA_Document* pXFADoc = ((CXFA_FFDoc*)hDoc)->GetXFADoc();
+ if (!pXFADoc) {
+ return NULL;
+ }
+ IXFA_ScriptContext* pScriptContext = pXFADoc->GetScriptContext();
+ if (!pScriptContext) {
+ return NULL;
+ }
+ return pScriptContext->GetJSValueFromMap(pXFADoc->GetRoot());
+}
+XFA_ATTRIBUTEENUM CXFA_FFDocHandler::GetRestoreState(XFA_HDOC hDoc)
+{
+ CXFA_Document* pXFADoc = ((CXFA_FFDoc*)hDoc)->GetXFADoc();
+ if (!pXFADoc) {
+ return XFA_ATTRIBUTEENUM_Unknown;
+ }
+ CXFA_Node* pForm = (CXFA_Node*)pXFADoc->GetXFANode(XFA_HASHCODE_Form);
+ if (!pForm) {
+ return XFA_ATTRIBUTEENUM_Unknown;
+ }
+ CXFA_Node* pSubForm = pForm->GetFirstChildByClass(XFA_ELEMENT_Subform);
+ if (!pSubForm) {
+ return XFA_ATTRIBUTEENUM_Unknown;
+ }
+ return pSubForm->GetEnum(XFA_ATTRIBUTE_RestoreState);
+}
+FX_BOOL CXFA_FFDocHandler::RunDocScript(XFA_HDOC hDoc, XFA_SCRIPTTYPE eScriptType, FX_WSTR wsScript, FXJSE_HVALUE hRetValue, FXJSE_HVALUE hThisObject)
+{
+ CXFA_Document* pXFADoc = ((CXFA_FFDoc*)hDoc)->GetXFADoc();
+ if (!pXFADoc) {
+ return FALSE;
+ }
+ IXFA_ScriptContext* pScriptContext = pXFADoc->GetScriptContext();
+ if (!pScriptContext) {
+ return FALSE;
+ }
+ return pScriptContext->RunScript((XFA_SCRIPTLANGTYPE)eScriptType, wsScript, hRetValue, hThisObject ? (CXFA_Object*)FXJSE_Value_ToObject(hThisObject, NULL) : NULL);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffdochandler.h b/xfa/src/fxfa/src/app/xfa_ffdochandler.h
new file mode 100644
index 0000000000..c4c0853f12
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdochandler.h
@@ -0,0 +1,34 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_DOCHANDLER_IMP_H
+#define _FXFA_FORMFILLER_DOCHANDLER_IMP_H
+class CXFA_FFDocHandler : public IXFA_DocHandler, public CFX_Object
+{
+public:
+ CXFA_FFDocHandler();
+ ~CXFA_FFDocHandler();
+ virtual void ReleaseDoc(XFA_HDOC hDoc);
+ virtual IXFA_DocProvider* GetDocProvider(XFA_HDOC hDoc);
+ virtual FX_DWORD GetDocType(XFA_HDOC hDoc);
+ virtual FX_INT32 StartLoad(XFA_HDOC hDoc);
+ virtual FX_INT32 DoLoad(XFA_HDOC hDoc, IFX_Pause *pPause = NULL);
+ virtual void StopLoad(XFA_HDOC hDoc);
+
+ virtual IXFA_DocView* CreateDocView(XFA_HDOC hDoc, FX_DWORD dwView = 0);
+ virtual FX_INT32 CountPackages(XFA_HDOC hDoc);
+ virtual void GetPackageName(XFA_HDOC hDoc, FX_INT32 iPackage, CFX_WideStringC &wsPackage);
+ virtual IFDE_XMLElement* GetPackageData(XFA_HDOC hDoc, FX_WSTR wsPackage);
+ virtual FX_BOOL SavePackage(XFA_HDOC hDoc, FX_WSTR wsPackage, IFX_FileWrite* pFile, IXFA_ChecksumContext *pCSContext = NULL);
+ virtual FX_BOOL CloseDoc(XFA_HDOC hDoc);
+ virtual FX_BOOL ImportData(XFA_HDOC hDoc, IFX_FileRead* pStream, FX_BOOL bXDP = TRUE);
+ virtual void SetJSERuntime(XFA_HDOC hDoc, FXJSE_HRUNTIME hRuntime);
+ virtual FXJSE_HVALUE GetXFAScriptObject(XFA_HDOC hDoc);
+ virtual XFA_ATTRIBUTEENUM GetRestoreState(XFA_HDOC hDoc);
+ virtual FX_BOOL RunDocScript(XFA_HDOC hDoc, XFA_SCRIPTTYPE eScriptType, FX_WSTR wsScript, FXJSE_HVALUE hRetValue, FXJSE_HVALUE hThisObject);
+protected:
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffdocview.cpp b/xfa/src/fxfa/src/app/xfa_ffdocview.cpp
new file mode 100644
index 0000000000..bb6a5ce2a9
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdocview.cpp
@@ -0,0 +1,960 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffwidgethandler.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpushbutton.h"
+#include "xfa_ffcheckbutton.h"
+#include "xfa_ffchoicelist.h"
+#include "xfa_ffimageedit.h"
+#include "xfa_fftextedit.h"
+#include "xfa_ffbarcode.h"
+#include "xfa_ffdraw.h"
+#include "xfa_fftext.h"
+#include "xfa_ffpath.h"
+#include "xfa_ffimage.h"
+#include "xfa_ffexclgroup.h"
+#include "xfa_ffsubform.h"
+#include "xfa_ffsignature.h"
+#include "xfa_ffapp.h"
+#include "xfa_textlayout.h"
+#include "xfa_ffwidgetacc.h"
+extern const XFA_ATTRIBUTEENUM gs_EventActivity[] = {
+ XFA_ATTRIBUTEENUM_Click,
+ XFA_ATTRIBUTEENUM_Change,
+ XFA_ATTRIBUTEENUM_DocClose,
+ XFA_ATTRIBUTEENUM_DocReady,
+ XFA_ATTRIBUTEENUM_Enter,
+ XFA_ATTRIBUTEENUM_Exit,
+ XFA_ATTRIBUTEENUM_Full,
+ XFA_ATTRIBUTEENUM_IndexChange,
+ XFA_ATTRIBUTEENUM_Initialize,
+ XFA_ATTRIBUTEENUM_MouseDown,
+ XFA_ATTRIBUTEENUM_MouseEnter,
+ XFA_ATTRIBUTEENUM_MouseExit,
+ XFA_ATTRIBUTEENUM_MouseUp,
+ XFA_ATTRIBUTEENUM_PostExecute,
+ XFA_ATTRIBUTEENUM_PostOpen,
+ XFA_ATTRIBUTEENUM_PostPrint,
+ XFA_ATTRIBUTEENUM_PostSave,
+ XFA_ATTRIBUTEENUM_PostSign,
+ XFA_ATTRIBUTEENUM_PostSubmit,
+ XFA_ATTRIBUTEENUM_PreExecute,
+ XFA_ATTRIBUTEENUM_PreOpen,
+ XFA_ATTRIBUTEENUM_PrePrint,
+ XFA_ATTRIBUTEENUM_PreSave,
+ XFA_ATTRIBUTEENUM_PreSign,
+ XFA_ATTRIBUTEENUM_PreSubmit,
+ XFA_ATTRIBUTEENUM_Ready,
+ XFA_ATTRIBUTEENUM_Unknown,
+};
+CXFA_FFDocView::CXFA_FFDocView(CXFA_FFDoc* pDoc)
+ : m_pDoc(pDoc)
+ , m_pWidgetHandler(NULL)
+ , m_pXFADocLayout(NULL)
+ , m_iStatus(XFA_DOCVIEW_LAYOUTSTATUS_None)
+ , m_iLock(0)
+ , m_bLayoutEvent(FALSE)
+ , m_pFocusAcc(NULL)
+ , m_pFocusWidget(NULL)
+ , m_pListFocusWidget(NULL)
+ , m_pOldFocusWidget(NULL)
+ , m_bInLayoutStatus(FALSE)
+{
+}
+CXFA_FFDocView::~CXFA_FFDocView()
+{
+ DestroyDocView();
+ if (m_pWidgetHandler) {
+ delete m_pWidgetHandler;
+ }
+ m_pWidgetHandler = NULL;
+}
+void CXFA_FFDocView::InitLayout(CXFA_Node* pNode)
+{
+ RunBindItems();
+ ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Initialize);
+ ExecEventActivityByDeepFirst(pNode, XFA_EVENT_IndexChange);
+}
+FX_INT32 CXFA_FFDocView::StartLayout(FX_INT32 iStartPage )
+{
+ m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start;
+ m_pDoc->GetXFADoc()->DoProtoMerge();
+ m_pDoc->GetXFADoc()->DoDataMerge();
+ m_pXFADocLayout = GetXFALayout();
+ FX_INT32 iStatus = m_pXFADocLayout->StartLayout();
+ if (iStatus < 0) {
+ return iStatus;
+ }
+ CXFA_Node* pRootItem = (CXFA_Node*)m_pDoc->GetXFADoc()->GetXFANode(XFA_HASHCODE_Form);
+ if (!pRootItem) {
+ return iStatus;
+ }
+ InitLayout(pRootItem);
+ InitCalculate(pRootItem);
+ InitValidate(pRootItem);
+ ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready, TRUE);
+ m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Start;
+ return iStatus;
+}
+FX_INT32 CXFA_FFDocView::DoLayout(IFX_Pause *pPause )
+{
+ FX_INT32 iStatus = 100;
+ iStatus = m_pXFADocLayout->DoLayout(pPause);
+ if (iStatus != 100) {
+ return iStatus;
+ }
+ m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Doing;
+ return iStatus;
+}
+void CXFA_FFDocView::StopLayout()
+{
+ CXFA_Node* pRootItem = (CXFA_Node*)m_pDoc->GetXFADoc()->GetXFANode(XFA_HASHCODE_Form);
+ if (!pRootItem) {
+ return;
+ }
+ CXFA_Node* pSubformNode = pRootItem->GetChild(0, XFA_ELEMENT_Subform);
+ if (!pSubformNode) {
+ return;
+ }
+ CXFA_Node* pPageSetNode = pSubformNode->GetFirstChildByClass(XFA_ELEMENT_PageSet);
+ if(!pPageSetNode) {
+ return;
+ }
+ RunCalculateWidgets();
+ RunValidate();
+ InitLayout(pPageSetNode);
+ InitCalculate(pPageSetNode);
+ InitValidate(pPageSetNode);
+ ExecEventActivityByDeepFirst(pPageSetNode, XFA_EVENT_Ready, TRUE);
+ ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
+ ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocReady);
+ RunCalculateWidgets();
+ RunValidate();
+ if(RunLayout()) {
+ ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
+ }
+ m_CalculateAccs.RemoveAll();
+ if (m_pFocusAcc && !m_pFocusWidget) {
+ SetFocusWidgetAcc(m_pFocusAcc);
+ }
+ m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_End;
+}
+FX_INT32 CXFA_FFDocView::GetLayoutStatus()
+{
+ return m_iStatus;
+}
+void CXFA_FFDocView::ShowNullTestMsg()
+{
+ FX_INT32 iCount = m_arrNullTestMsg.GetSize();
+ CXFA_FFApp* pApp = m_pDoc->GetApp();
+ IXFA_AppProvider* pAppProvider = pApp->GetAppProvider();
+ if (pAppProvider && iCount) {
+ FX_INT32 iRemain = iCount > 7 ? iCount - 7 : 0;
+ iCount -= iRemain;
+ CFX_WideString wsMsg;
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ wsMsg += m_arrNullTestMsg[i] + FX_WSTRC(L"\n");
+ }
+ if (iRemain > 0) {
+ CFX_WideString wsLimit;
+ pAppProvider->LoadString(XFA_IDS_ValidateLimit, wsLimit);
+ if (!wsLimit.IsEmpty()) {
+ CFX_WideString wsTemp;
+ wsTemp.Format((FX_LPCWSTR)wsLimit, iRemain);
+ wsMsg += FX_WSTRC(L"\n") + wsTemp;
+ }
+ }
+ CFX_WideString wsTitle;
+ pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+ pAppProvider->MsgBox(wsMsg, wsTitle, XFA_MBICON_Status, XFA_MB_OK);
+ }
+ m_arrNullTestMsg.RemoveAll();
+}
+void CXFA_FFDocView::UpdateDocView()
+{
+ if (IsUpdateLocked()) {
+ return;
+ }
+ LockUpdate();
+ FX_INT32 iNewAdds = m_NewAddedNodes.GetSize();
+ for (FX_INT32 i = 0; i < iNewAdds; i++) {
+ CXFA_Node* pNode = (CXFA_Node*)m_NewAddedNodes[i];
+ InitCalculate(pNode);
+ InitValidate(pNode);
+ ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Ready, TRUE);
+ }
+ m_NewAddedNodes.RemoveAll();
+ this->RunSubformIndexChange();
+ this->RunCalculateWidgets();
+ this->RunValidate();
+ ShowNullTestMsg();
+ m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_Next;
+ if (RunLayout() && m_bLayoutEvent) {
+ RunEventLayoutReady();
+ }
+ m_bLayoutEvent = FALSE;
+ m_CalculateAccs.RemoveAll();
+ this->RunInvalidate();
+ UnlockUpdate();
+}
+FX_INT32 CXFA_FFDocView::CountPageViews()
+{
+ if (!m_pXFADocLayout) {
+ return 0;
+ }
+ return m_pXFADocLayout->CountPages();
+}
+IXFA_PageView* CXFA_FFDocView::GetPageView(FX_INT32 nIndex)
+{
+ if (!m_pXFADocLayout) {
+ return NULL;
+ }
+ return (CXFA_FFPageView*)m_pXFADocLayout->GetPage(nIndex);
+}
+XFA_HWIDGET CXFA_FFDocView::GetWidgetByName(FX_WSTR wsName)
+{
+ return (XFA_HWIDGET)GetWidgetByName(wsName, NULL);
+}
+CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName(FX_WSTR wsName)
+{
+ return GetWidgetAccByName(wsName, NULL);
+}
+IXFA_DocLayout* CXFA_FFDocView::GetXFALayout() const
+{
+ return m_pDoc->GetXFADoc()->GetDocLayout();
+}
+FX_BOOL CXFA_FFDocView::ResetSingleWidgetAccData(CXFA_WidgetAcc* pWidgetAcc)
+{
+ CXFA_Node* pNode = pWidgetAcc->GetNode();
+ XFA_ELEMENT eType = pNode->GetClassID();
+ if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_ExclGroup) {
+ return FALSE;
+ }
+ FX_BOOL bNotify = IsStaticNotify();
+ pWidgetAcc->ResetData();
+ pWidgetAcc->UpdateUIDisplay();
+ if (bNotify) {
+ pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL, NULL);
+ }
+ if (CXFA_Validate validate = pWidgetAcc->GetValidate()) {
+ AddValidateWidget(pWidgetAcc);
+ ((CXFA_Node*)validate)->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE);
+ }
+ return TRUE;
+}
+void CXFA_FFDocView::ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc )
+{
+ m_bLayoutEvent = TRUE;
+ FX_BOOL bChanged = FALSE;
+ CXFA_Node* pFormNode = NULL;
+ if (pWidgetAcc) {
+ bChanged = ResetSingleWidgetAccData(pWidgetAcc);
+ pFormNode = pWidgetAcc->GetNode();
+ } else {
+ pFormNode = GetRootSubform();
+ }
+ if (!pFormNode) {
+ return;
+ }
+ if (pFormNode->GetClassID() != XFA_ELEMENT_Field && pFormNode->GetClassID() != XFA_ELEMENT_ExclGroup) {
+ CXFA_WidgetAccIterator Iterator(this, pFormNode);
+ while (CXFA_WidgetAcc* pAcc = Iterator.MoveToNext()) {
+ bChanged |= ResetSingleWidgetAccData(pAcc);
+ if (pAcc->GetNode()->GetClassID() == XFA_ELEMENT_ExclGroup) {
+ Iterator.SkipTree();
+ }
+ }
+ }
+ if (bChanged) {
+ m_pDoc->GetDocProvider()->SetChangeMark((XFA_HDOC)m_pDoc);
+ }
+}
+FX_INT32 CXFA_FFDocView::ProcessWidgetEvent(CXFA_EventParam* pParam, CXFA_WidgetAcc* pWidgetAcc )
+{
+ if (pParam == NULL) {
+ return XFA_EVENTERROR_Error;
+ }
+ if (pParam->m_eType == XFA_EVENT_Validate) {
+ CFX_WideString wsValidateStr = FX_WSTRC(L"preSubmit");
+ CXFA_Node* pConfigItem = (CXFA_Node*)m_pDoc->GetXFADoc()->GetXFANode(XFA_HASHCODE_Config);
+ if (pConfigItem) {
+ CXFA_Node* pValidateNode = NULL;
+ CXFA_Node* pAcrobatNode = pConfigItem->GetChild(0, XFA_ELEMENT_Acrobat);
+ pValidateNode = pAcrobatNode ? pAcrobatNode->GetChild(0, XFA_ELEMENT_Validate) : NULL;
+ if (!pValidateNode) {
+ CXFA_Node* pPresentNode = pConfigItem->GetChild(0, XFA_ELEMENT_Present);
+ pValidateNode = pPresentNode ? pPresentNode->GetChild(0, XFA_ELEMENT_Validate) : NULL;
+ }
+ if (pValidateNode) {
+ wsValidateStr = pValidateNode->GetContent();
+ }
+ }
+ FX_BOOL bValidate = FALSE;
+ switch (pParam->m_iValidateActivities) {
+ case XFA_VALIDATE_preSubmit:
+ bValidate = wsValidateStr.Find(L"preSubmit") != -1;
+ break;
+ case XFA_VALIDATE_prePrint:
+ bValidate = wsValidateStr.Find(L"prePrint") != -1;
+ break;
+ case XFA_VALIDATE_preExecute:
+ bValidate = wsValidateStr.Find(L"preExecute") != -1;
+ break;
+ case XFA_VALIDATE_preSave:
+ bValidate = wsValidateStr.Find(L"preSave") != -1;
+ break;
+ }
+ if (!bValidate) {
+ return XFA_EVENTERROR_Sucess;
+ }
+ }
+ CXFA_Node* pNode = pWidgetAcc ? pWidgetAcc->GetNode() : NULL;
+ if (!pNode) {
+ CXFA_Node* pRootItem = (CXFA_Node*)m_pDoc->GetXFADoc()->GetXFANode(XFA_HASHCODE_Form);
+ if (!pRootItem) {
+ return XFA_EVENTERROR_Error;
+ }
+ pNode = pRootItem->GetChild(0, XFA_ELEMENT_Subform);
+ }
+ ExecEventActivityByDeepFirst(pNode, pParam->m_eType, pParam->m_bIsFormReady);
+ return XFA_EVENTERROR_Sucess;
+}
+IXFA_WidgetHandler* CXFA_FFDocView::GetWidgetHandler()
+{
+ if (!m_pWidgetHandler) {
+ m_pWidgetHandler = FX_NEW CXFA_FFWidgetHandler(this);
+ }
+ return m_pWidgetHandler;
+}
+IXFA_WidgetIterator* CXFA_FFDocView::CreateWidgetIterator()
+{
+ CXFA_Node* pFormRoot = GetRootSubform();
+ if (!pFormRoot) {
+ return NULL;
+ }
+ return FX_NEW CXFA_FFDocWidgetIterator(this, pFormRoot);
+}
+IXFA_WidgetAccIterator* CXFA_FFDocView::CreateWidgetAccIterator(XFA_WIDGETORDER eOrder )
+{
+ CXFA_Node* pFormRoot = GetRootSubform();
+ if (!pFormRoot) {
+ return NULL;
+ }
+ return FX_NEW CXFA_WidgetAccIterator(this, pFormRoot);
+}
+XFA_HWIDGET CXFA_FFDocView::GetFocusWidget()
+{
+ return (XFA_HWIDGET)m_pFocusWidget;
+}
+void CXFA_FFDocView::KillFocus()
+{
+ if (m_pFocusWidget && (m_pFocusWidget->GetStatus() & XFA_WIDGETSTATUS_Focused)) {
+ (m_pFocusWidget)->OnKillFocus(NULL);
+ }
+ m_pFocusAcc = NULL;
+ m_pFocusWidget = NULL;
+ m_pOldFocusWidget = NULL;
+}
+FX_BOOL CXFA_FFDocView::SetFocus(XFA_HWIDGET hWidget)
+{
+ CXFA_FFWidget* pNewFocus = (CXFA_FFWidget*)hWidget;
+ if (m_pOldFocusWidget == pNewFocus) {
+ return FALSE;
+ }
+ CXFA_FFWidget* pOldFocus = m_pOldFocusWidget;
+ m_pOldFocusWidget = pNewFocus;
+ if (pOldFocus) {
+ if (m_pFocusWidget != m_pOldFocusWidget && (pOldFocus->GetStatus() & XFA_WIDGETSTATUS_Focused)) {
+ m_pFocusWidget = pOldFocus;
+ pOldFocus->OnKillFocus(pNewFocus);
+ } else if ((pOldFocus->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ if (!pOldFocus->IsLoaded()) {
+ pOldFocus->LoadWidget();
+ }
+ pOldFocus->OnSetFocus(m_pFocusWidget);
+ m_pFocusWidget = pOldFocus;
+ pOldFocus->OnKillFocus(pNewFocus);
+ }
+ }
+ if (m_pFocusWidget == m_pOldFocusWidget) {
+ return FALSE;
+ }
+ pNewFocus = m_pOldFocusWidget;
+ if (m_pListFocusWidget && pNewFocus == m_pListFocusWidget) {
+ m_pFocusAcc = NULL;
+ m_pFocusWidget = NULL;
+ m_pListFocusWidget = NULL;
+ m_pOldFocusWidget = NULL;
+ return FALSE;
+ }
+ if (pNewFocus && (pNewFocus->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ if (!pNewFocus->IsLoaded()) {
+ pNewFocus->LoadWidget();
+ }
+ pNewFocus->OnSetFocus(m_pFocusWidget);
+ }
+ m_pFocusAcc = pNewFocus ? pNewFocus->GetDataAcc() : NULL;
+ m_pFocusWidget = pNewFocus;
+ m_pOldFocusWidget = m_pFocusWidget;
+ return TRUE;
+}
+CXFA_WidgetAcc* CXFA_FFDocView::GetFocusWidgetAcc()
+{
+ return m_pFocusAcc;
+}
+void CXFA_FFDocView::SetFocusWidgetAcc(CXFA_WidgetAcc* pWidgetAcc)
+{
+ CXFA_FFWidget* pNewFocus = pWidgetAcc ? pWidgetAcc->GetNextWidget(NULL) : NULL;
+ if (SetFocus((XFA_HWIDGET)pNewFocus)) {
+ m_pFocusAcc = pWidgetAcc;
+ if (m_iStatus >= XFA_DOCVIEW_LAYOUTSTATUS_End) {
+ m_pDoc->GetDocProvider()->SetFocusWidget((XFA_HDOC)m_pDoc, (XFA_HWIDGET)m_pFocusWidget);
+ }
+ }
+}
+void CXFA_FFDocView::DeleteLayoutItem(CXFA_FFWidget* pWidget)
+{
+ if (m_pFocusAcc == pWidget->GetDataAcc()) {
+ m_pFocusAcc = NULL;
+ m_pFocusWidget = NULL;
+ m_pOldFocusWidget = NULL;
+ }
+}
+static FX_INT32 XFA_ProcessEvent(CXFA_FFDocView* pDocView, CXFA_WidgetAcc* pWidgetAcc, CXFA_EventParam* pParam)
+{
+ if (!pParam || pParam->m_eType == XFA_EVENT_Unknown) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ if (!pWidgetAcc || pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ switch (pParam->m_eType) {
+ case XFA_EVENT_Calculate:
+ return pWidgetAcc->ProcessCalculate();
+ case XFA_EVENT_Validate:
+ if (((CXFA_FFDoc*)pDocView->GetDoc())->GetDocProvider()->IsValidationsEnabled(pDocView->GetDoc())) {
+ return pWidgetAcc->ProcessValidate(0x01);
+ }
+ return XFA_EVENTERROR_Disabled;
+ case XFA_EVENT_InitCalculate: {
+ CXFA_Calculate calc = pWidgetAcc->GetCalculate();
+ if (!calc) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ if (pWidgetAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+ return XFA_EVENTERROR_Disabled;
+ }
+ CXFA_Script script = calc.GetScript();
+ return pWidgetAcc->ExecuteScript(script, pParam);
+ }
+ default:
+ break;
+ }
+ FX_INT32 iRet = pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
+ return iRet;
+}
+FX_INT32 CXFA_FFDocView::ExecEventActivityByDeepFirst(CXFA_Node* pFormNode, XFA_EVENTTYPE eEventType, FX_BOOL bIsFormReady, FX_BOOL bRecursive, CXFA_Node* pExclude)
+{
+ FX_INT32 iRet = XFA_EVENTERROR_NotExist;
+ if (pFormNode == pExclude) {
+ return iRet;
+ }
+ XFA_ELEMENT elementType = pFormNode->GetClassID();
+ if (elementType == XFA_ELEMENT_Field) {
+ if (eEventType == XFA_EVENT_IndexChange) {
+ return iRet;
+ }
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
+ if (pWidgetAcc == NULL) {
+ return iRet;
+ }
+ CXFA_EventParam eParam;
+ eParam.m_eType = eEventType;
+ eParam.m_pTarget = pWidgetAcc;
+ eParam.m_bIsFormReady = bIsFormReady;
+ return XFA_ProcessEvent(this, pWidgetAcc, &eParam);
+ }
+ if (bRecursive) {
+ for(CXFA_Node* pNode = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode)) {
+ elementType = pNode->GetClassID();
+ if (elementType != XFA_ELEMENT_Variables && elementType != XFA_ELEMENT_Draw) {
+ iRet |= ExecEventActivityByDeepFirst(pNode, eEventType, bIsFormReady, bRecursive, pExclude);
+ }
+ }
+ }
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormNode->GetWidgetData();
+ if (pWidgetAcc == NULL) {
+ return iRet;
+ }
+ CXFA_EventParam eParam;
+ eParam.m_eType = eEventType;
+ eParam.m_pTarget = pWidgetAcc;
+ eParam.m_bIsFormReady = bIsFormReady;
+ iRet |= XFA_ProcessEvent(this, pWidgetAcc, &eParam);
+ return iRet;
+}
+CXFA_FFWidget* CXFA_FFDocView::GetWidgetByName(FX_WSTR wsName, CXFA_FFWidget* pRefWidget )
+{
+ CXFA_WidgetAcc* pRefAcc = pRefWidget ? pRefWidget->GetDataAcc() : NULL;
+ if (CXFA_WidgetAcc* pAcc = GetWidgetAccByName(wsName, pRefAcc)) {
+ return pAcc->GetNextWidget(NULL);
+ }
+ return NULL;
+}
+CXFA_WidgetAcc* CXFA_FFDocView::GetWidgetAccByName(FX_WSTR wsName, CXFA_WidgetAcc* pRefWidgetAcc )
+{
+ CFX_WideString wsExpression;
+ FX_DWORD dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
+ IXFA_ScriptContext* pScriptContext = m_pDoc->GetXFADoc()->GetScriptContext();
+ if (!pScriptContext) {
+ return NULL;
+ }
+ CXFA_Node* refNode = NULL;
+ if(pRefWidgetAcc != NULL) {
+ refNode = pRefWidgetAcc->GetNode();
+ wsExpression = wsName;
+ } else {
+ wsExpression = L"$form." + wsName;
+ }
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = pScriptContext->ResolveObjects(refNode, wsExpression, resoveNodeRS, dwStyle);
+ if (iRet < 1) {
+ return NULL;
+ }
+ if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+ CXFA_Object* pNode = resoveNodeRS.nodes[0];
+ if(pNode->IsNode()) {
+ return (CXFA_WidgetAcc*)((CXFA_Node*)pNode)->GetWidgetData();
+ }
+ }
+ return NULL;
+}
+void CXFA_FFDocView::OnPageEvent(IXFA_LayoutPage *pSender, XFA_PAGEEVENT eEvent, FX_INT32 iPageIndex)
+{
+ FX_BOOL bNofify = m_iStatus >= XFA_DOCVIEW_LAYOUTSTATUS_End;
+ if (eEvent == XFA_PAGEEVENT_PageRemoved) {
+ if (bNofify) {
+ m_pDoc->GetDocProvider()->PageViewEvent((CXFA_FFPageView*)pSender, XFA_PAGEVIEWEVENT_PostRemoved);
+ }
+ } else if (eEvent == XFA_PAGEEVENT_PageAdded) {
+ if (bNofify) {
+ m_pDoc->GetDocProvider()->PageViewEvent((CXFA_FFPageView*)pSender, XFA_PAGEVIEWEVENT_PostAdded);
+ ((CXFA_FFPageView*)pSender)->LoadPageView();
+ }
+ }
+}
+void CXFA_FFDocView::LockUpdate()
+{
+ m_iLock++;
+}
+void CXFA_FFDocView::UnlockUpdate()
+{
+ m_iLock--;
+}
+FX_BOOL CXFA_FFDocView::IsUpdateLocked()
+{
+ return m_iLock;
+}
+void CXFA_FFDocView::ClearInvalidateList()
+{
+ FX_POSITION ps = m_mapPageInvalidate.GetStartPosition();
+ while (ps) {
+ void* pPageView = NULL;
+ CFX_RectF* pRect = NULL;
+ m_mapPageInvalidate.GetNextAssoc(ps, pPageView, (void*&)pRect);
+ delete pRect;
+ }
+ m_mapPageInvalidate.RemoveAll();
+}
+void CXFA_FFDocView::AddInvalidateRect(CXFA_FFWidget* pWidget, const CFX_RectF &rtInvalidate)
+{
+ AddInvalidateRect(pWidget->GetPageView(), rtInvalidate);
+}
+void CXFA_FFDocView::AddInvalidateRect(IXFA_PageView* pPageView, const CFX_RectF &rtInvalidate)
+{
+ CFX_RectF* pRect = (CFX_RectF*)m_mapPageInvalidate.GetValueAt(pPageView);
+ if (!pRect) {
+ pRect = FX_NEW CFX_RectF;
+ pRect->Set(rtInvalidate.left, rtInvalidate.top, rtInvalidate.width, rtInvalidate.height);
+ m_mapPageInvalidate.SetAt(pPageView, pRect);
+ } else {
+ pRect->Union(rtInvalidate);
+ }
+}
+void CXFA_FFDocView::RunInvalidate()
+{
+ FX_POSITION ps = m_mapPageInvalidate.GetStartPosition();
+ while (ps) {
+ IXFA_PageView* pPageView = NULL;
+ CFX_RectF* pRect = NULL;
+ m_mapPageInvalidate.GetNextAssoc(ps, (void*&)pPageView, (void*&)pRect);
+ m_pDoc->GetDocProvider()->InvalidateRect(pPageView, *pRect);
+ delete pRect;
+ }
+ m_mapPageInvalidate.RemoveAll();
+}
+FX_BOOL CXFA_FFDocView::RunLayout()
+{
+ LockUpdate();
+ m_bInLayoutStatus = TRUE;
+ if (!m_pXFADocLayout->IncrementLayout() && m_pXFADocLayout->StartLayout() < 100) {
+ m_pXFADocLayout->DoLayout();
+ UnlockUpdate();
+ m_bInLayoutStatus = FALSE;
+ return TRUE;
+ }
+ m_bInLayoutStatus = FALSE;
+ UnlockUpdate();
+ return FALSE;
+}
+void CXFA_FFDocView::RunSubformIndexChange()
+{
+ FX_INT32 iSubforms = m_IndexChangedSubforms.GetSize();
+ for (FX_INT32 i = 0; i < iSubforms; i++) {
+ CXFA_Node* pSubformNode = (CXFA_Node*)m_IndexChangedSubforms[i];
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pSubformNode->GetWidgetData();
+ if (!pWidgetAcc) {
+ continue;
+ }
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_IndexChange;
+ eParam.m_pTarget = pWidgetAcc;
+ pWidgetAcc->ProcessEvent(XFA_ATTRIBUTEENUM_IndexChange, &eParam);
+ }
+ m_IndexChangedSubforms.RemoveAll();
+}
+void CXFA_FFDocView::AddNewFormNode(CXFA_Node* pNode)
+{
+ m_NewAddedNodes.Add(pNode);
+ this->InitLayout(pNode);
+}
+void CXFA_FFDocView::AddIndexChangedSubform(CXFA_Node* pNode)
+{
+ FXSYS_assert(pNode->GetClassID() == XFA_ELEMENT_Subform );
+ m_IndexChangedSubforms.Add(pNode);
+}
+void CXFA_FFDocView::RunDocClose()
+{
+ CXFA_Node* pRootItem = (CXFA_Node*)m_pDoc->GetXFADoc()->GetXFANode(XFA_HASHCODE_Form);
+ if (!pRootItem) {
+ return;
+ }
+ ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_DocClose);
+}
+void CXFA_FFDocView::DestroyDocView()
+{
+ ClearInvalidateList();
+ m_iStatus = XFA_DOCVIEW_LAYOUTSTATUS_None;
+ m_iLock = 0;
+ m_ValidateAccs.RemoveAll();
+ m_bindItems.RemoveAll();
+ m_CalculateAccs.RemoveAll();
+}
+FX_BOOL CXFA_FFDocView::IsStaticNotify()
+{
+ return m_pDoc->GetDocType() == XFA_DOCTYPE_Static;
+}
+void CXFA_FFDocView::AddCalculateWidgetAcc(CXFA_WidgetAcc* pWidgetAcc)
+{
+ FX_INT32 iAccs = m_CalculateAccs.GetSize();
+ CXFA_WidgetAcc* pCurrentAcc = (iAccs < 1) ? (CXFA_WidgetAcc*)NULL : (CXFA_WidgetAcc*)m_CalculateAccs[iAccs - 1];
+ if (pCurrentAcc != pWidgetAcc) {
+ m_CalculateAccs.Add(pWidgetAcc);
+ }
+}
+void CXFA_FFDocView::AddCalculateNodeNotify(CXFA_Node* pNodeChange)
+{
+ CXFA_CalcData* pGlobalData = (CXFA_CalcData*)pNodeChange->GetUserData(XFA_CalcData);
+ FX_INT32 iCount = pGlobalData ? pGlobalData->m_Globals.GetSize() : 0;
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXFA_WidgetAcc* pResultAcc = (CXFA_WidgetAcc*)pGlobalData->m_Globals[i];
+ if (pResultAcc->GetNode()->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+ continue;
+ }
+ FX_INT32 iAccs = m_CalculateAccs.GetSize();
+ CXFA_WidgetAcc* pCurrentAcc = (iAccs < 1) ? (CXFA_WidgetAcc*)NULL : (CXFA_WidgetAcc*)m_CalculateAccs[iAccs - 1];
+ if (pCurrentAcc != pResultAcc) {
+ m_CalculateAccs.Add(pResultAcc);
+ }
+ }
+}
+void CXFA_FFDocView::RunCalculateRecursive(FX_INT32& iIndex)
+{
+ while (iIndex < m_CalculateAccs.GetSize()) {
+ CXFA_WidgetAcc* pCurAcc = (CXFA_WidgetAcc*)m_CalculateAccs[iIndex];
+ AddCalculateNodeNotify(pCurAcc->GetNode());
+ FX_INT32 iRefCount = (FX_INT32)(FX_UINTPTR)pCurAcc->GetNode()->GetUserData(XFA_CalcRefCount);
+ iRefCount++;
+ pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount, (FX_LPVOID)(FX_UINTPTR)iRefCount);
+ if (iRefCount > 11) {
+ break;
+ }
+ if ((pCurAcc->ProcessCalculate()) == XFA_EVENTERROR_Sucess) {
+ AddValidateWidget(pCurAcc);
+ }
+ iIndex++;
+ RunCalculateRecursive(iIndex);
+ }
+}
+FX_INT32 CXFA_FFDocView::RunCalculateWidgets()
+{
+ if (!m_pDoc->GetDocProvider()->IsCalculationsEnabled((XFA_HDOC)m_pDoc)) {
+ return XFA_EVENTERROR_Disabled;
+ }
+ FX_INT32 iCounts = m_CalculateAccs.GetSize();
+ FX_INT32 iIndex = 0;
+ if (iCounts > 0) {
+ RunCalculateRecursive(iIndex);
+ }
+ for (FX_INT32 i = 0; i < m_CalculateAccs.GetSize(); i++) {
+ CXFA_WidgetAcc* pCurAcc = (CXFA_WidgetAcc*)m_CalculateAccs[i];
+ pCurAcc->GetNode()->SetUserData(XFA_CalcRefCount, (FX_LPVOID)(FX_UINTPTR)0);
+ }
+ m_CalculateAccs.RemoveAll();
+ return XFA_EVENTERROR_Sucess;
+}
+void CXFA_FFDocView::AddValidateWidget(CXFA_WidgetAcc* pWidget)
+{
+ if (m_ValidateAccs.Find(pWidget) < 0) {
+ m_ValidateAccs.Add(pWidget);
+ }
+}
+FX_BOOL CXFA_FFDocView::InitCalculate(CXFA_Node* pNode)
+{
+ ExecEventActivityByDeepFirst(pNode, XFA_EVENT_InitCalculate);
+ return TRUE;
+}
+FX_BOOL CXFA_FFDocView::InitValidate(CXFA_Node* pNode)
+{
+ if (!m_pDoc->GetDocProvider()->IsValidationsEnabled((XFA_HDOC)m_pDoc)) {
+ return FALSE;
+ }
+ ExecEventActivityByDeepFirst(pNode, XFA_EVENT_Validate);
+ m_ValidateAccs.RemoveAll();
+ return TRUE;
+}
+FX_BOOL CXFA_FFDocView::RunValidate()
+{
+ if (!m_pDoc->GetDocProvider()->IsValidationsEnabled((XFA_HDOC)m_pDoc)) {
+ return FALSE;
+ }
+ FX_INT32 iCounts = m_ValidateAccs.GetSize();
+ for (FX_INT32 i = 0; i < iCounts; i++) {
+ CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)m_ValidateAccs[i];
+ if (pAcc->GetNode()->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+ continue;
+ }
+ pAcc->ProcessValidate();
+ }
+ m_ValidateAccs.RemoveAll();
+ return TRUE;
+}
+FX_BOOL CXFA_FFDocView::RunEventLayoutReady()
+{
+ CXFA_Node* pRootItem = (CXFA_Node*)m_pDoc->GetXFADoc()->GetXFANode(XFA_HASHCODE_Form);
+ if (!pRootItem) {
+ return FALSE;
+ }
+ ExecEventActivityByDeepFirst(pRootItem, XFA_EVENT_Ready);
+ RunLayout();
+ return TRUE;
+}
+void CXFA_FFDocView::RunBindItems()
+{
+ FX_INT32 iCount = m_bindItems.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ if (((CXFA_Node*)m_bindItems[i])->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+ continue;
+ }
+ CXFA_Node* pWidgetNode = ((CXFA_Node*)m_bindItems[i])->GetNodeItem(XFA_NODEITEM_Parent);
+ CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pWidgetNode->GetWidgetData();
+ if (!pAcc) {
+ continue;
+ }
+ CXFA_BindItems binditems((CXFA_Node*)m_bindItems[i]);
+ IXFA_ScriptContext* pScriptContext = pWidgetNode->GetDocument()->GetScriptContext();
+ CFX_WideStringC wsRef;
+ binditems.GetRef(wsRef);
+ FX_DWORD dwStyle = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_ALL;
+ XFA_RESOLVENODE_RS rs;
+ pScriptContext->ResolveObjects(pWidgetNode, wsRef, rs, dwStyle);
+ FX_INT32 iCount = rs.nodes.GetSize();
+ pAcc->DeleteItem(-1);
+ if (rs.dwFlags != XFA_RESOVENODE_RSTYPE_Nodes || iCount < 1) {
+ continue;
+ }
+ CFX_WideStringC wsValueRef, wsLabelRef;
+ binditems.GetValueRef(wsValueRef);
+ binditems.GetLabelRef(wsLabelRef);
+ FX_BOOL bUseValue = wsLabelRef.IsEmpty() || wsLabelRef == wsValueRef;
+ FX_BOOL bLabelUseContent = wsLabelRef.IsEmpty() || wsLabelRef == FX_WSTRC(L"$");
+ FX_BOOL bValueUseContent = wsValueRef.IsEmpty() || wsValueRef == FX_WSTRC(L"$");
+ CFX_WideString wsValue, wsLabel;
+ FX_DWORD uValueHash = FX_HashCode_String_GetW(CFX_WideString(wsValueRef), wsValueRef.GetLength());
+ FX_DWORD uLableHash = FX_HashCode_String_GetW(CFX_WideString(wsLabelRef), wsLabelRef.GetLength());
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXFA_Object* refObj = rs.nodes[i];
+ if(!refObj->IsNode()) {
+ continue;
+ }
+ CXFA_Node* refNode = (CXFA_Node*)refObj;
+ if (bValueUseContent) {
+ wsValue = refNode->GetContent();
+ } else {
+ CXFA_Node* nodeValue = refNode->GetFirstChildByName(uValueHash);
+ if (nodeValue == NULL) {
+ wsValue = refNode->GetContent();
+ } else {
+ wsValue = nodeValue->GetContent();
+ }
+ }
+ if (!bUseValue) {
+ if (bLabelUseContent) {
+ wsLabel = refNode->GetContent();
+ } else {
+ CXFA_Node* nodeLabel = refNode->GetFirstChildByName(wsLabelRef);
+ if (nodeLabel != NULL) {
+ wsLabel = nodeLabel->GetContent();
+ }
+ }
+ } else {
+ wsLabel = wsValue;
+ }
+ pAcc->InsertItem(wsLabel, wsValue);
+ }
+ }
+ m_bindItems.RemoveAll();
+}
+void CXFA_FFDocView::SetChangeMark()
+{
+ if (m_iStatus < XFA_DOCVIEW_LAYOUTSTATUS_End) {
+ return;
+ }
+ m_pDoc->GetDocProvider()->SetChangeMark((XFA_HDOC)m_pDoc);
+}
+CXFA_Node* CXFA_FFDocView::GetRootSubform()
+{
+ CXFA_Node* pFormPacketNode = (CXFA_Node*)m_pDoc->GetXFADoc()->GetXFANode(XFA_HASHCODE_Form);
+ if (!pFormPacketNode) {
+ return NULL;
+ }
+ return pFormPacketNode->GetFirstChildByClass(XFA_ELEMENT_Subform);
+}
+CXFA_FFDocWidgetIterator::CXFA_FFDocWidgetIterator(CXFA_FFDocView* pDocView, CXFA_Node* pTravelRoot)
+ : m_ContentIterator(pTravelRoot)
+{
+ m_pDocView = pDocView;
+ m_pCurWidget = NULL;
+}
+CXFA_FFDocWidgetIterator::~CXFA_FFDocWidgetIterator()
+{
+}
+void CXFA_FFDocWidgetIterator::Reset()
+{
+ m_ContentIterator.Reset();
+ m_pCurWidget = NULL;
+}
+XFA_HWIDGET CXFA_FFDocWidgetIterator::MoveToFirst()
+{
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFDocWidgetIterator::MoveToLast()
+{
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFDocWidgetIterator::MoveToNext()
+{
+ CXFA_Node* pItem = m_pCurWidget ? m_ContentIterator.MoveToNext() : m_ContentIterator.GetCurrent();
+ while (pItem) {
+ if (CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData()) {
+ while ((m_pCurWidget = pAcc->GetNextWidget(NULL)) != NULL) {
+ if (!m_pCurWidget->IsLoaded() && (m_pCurWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ m_pCurWidget->LoadWidget();
+ }
+ return (XFA_HWIDGET)m_pCurWidget;
+ }
+ }
+ pItem = m_ContentIterator.MoveToNext();
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFDocWidgetIterator::MoveToPrevious()
+{
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFDocWidgetIterator::GetCurrentWidget()
+{
+ return NULL;
+}
+FX_BOOL CXFA_FFDocWidgetIterator::SetCurrentWidget(XFA_HWIDGET hWidget)
+{
+ return FALSE;
+}
+IXFA_WidgetAccIterator* XFA_WidgetAccIterator_Create(CXFA_WidgetAcc* pTravelRoot, XFA_WIDGETORDER eOrder)
+{
+ if (!pTravelRoot) {
+ return NULL;
+ }
+ return FX_NEW CXFA_WidgetAccIterator(pTravelRoot->GetDocView(), pTravelRoot->GetNode());
+}
+CXFA_WidgetAccIterator::CXFA_WidgetAccIterator(CXFA_FFDocView* pDocView, CXFA_Node* pTravelRoot)
+ : m_ContentIterator(pTravelRoot)
+{
+ m_pDocView = pDocView;
+ m_pCurWidgetAcc = NULL;
+}
+CXFA_WidgetAccIterator::~CXFA_WidgetAccIterator()
+{
+}
+void CXFA_WidgetAccIterator::Reset()
+{
+ m_pCurWidgetAcc = NULL;
+ m_ContentIterator.Reset();
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToFirst()
+{
+ return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToLast()
+{
+ return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToNext()
+{
+ CXFA_Node* pItem = m_pCurWidgetAcc ? m_ContentIterator.MoveToNext() : m_ContentIterator.GetCurrent();
+ while (pItem) {
+ if ((m_pCurWidgetAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData()) != NULL) {
+ return m_pCurWidgetAcc;
+ }
+ pItem = m_ContentIterator.MoveToNext();
+ }
+ return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::MoveToPrevious()
+{
+ return NULL;
+}
+CXFA_WidgetAcc* CXFA_WidgetAccIterator::GetCurrentWidgetAcc()
+{
+ return NULL;
+}
+FX_BOOL CXFA_WidgetAccIterator::SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget)
+{
+ return FALSE;
+}
+void CXFA_WidgetAccIterator::SkipTree()
+{
+ m_ContentIterator.SkipChildrenAndMoveToNext();
+ m_pCurWidgetAcc = NULL;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffdocview.h b/xfa/src/fxfa/src/app/xfa_ffdocview.h
new file mode 100644
index 0000000000..1e73499032
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdocview.h
@@ -0,0 +1,164 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_DOCVIEW_IMP_H
+#define _FXFA_FORMFILLER_DOCVIEW_IMP_H
+class CXFA_FFPageView;
+class CXFA_FFWidgetHandler;
+class CXFA_FFDoc;
+class CXFA_FFWidget;
+extern const XFA_ATTRIBUTEENUM gs_EventActivity[];
+enum XFA_DOCVIEW_LAYOUTSTATUS {
+ XFA_DOCVIEW_LAYOUTSTATUS_None,
+ XFA_DOCVIEW_LAYOUTSTATUS_Start,
+ XFA_DOCVIEW_LAYOUTSTATUS_FormInitialize,
+ XFA_DOCVIEW_LAYOUTSTATUS_FormInitCalculate,
+ XFA_DOCVIEW_LAYOUTSTATUS_FormInitValidate,
+ XFA_DOCVIEW_LAYOUTSTATUS_FormFormReady,
+ XFA_DOCVIEW_LAYOUTSTATUS_Doing,
+ XFA_DOCVIEW_LAYOUTSTATUS_PagesetInitialize,
+ XFA_DOCVIEW_LAYOUTSTATUS_PagesetInitCalculate,
+ XFA_DOCVIEW_LAYOUTSTATUS_PagesetInitValidate,
+ XFA_DOCVIEW_LAYOUTSTATUS_PagesetFormReady,
+ XFA_DOCVIEW_LAYOUTSTATUS_LayoutReady,
+ XFA_DOCVIEW_LAYOUTSTATUS_DocReady,
+ XFA_DOCVIEW_LAYOUTSTATUS_End,
+ XFA_DOCVIEW_LAYOUTSTATUS_Next,
+};
+class CXFA_FFDocView : public IXFA_DocView, public CFX_Object
+{
+public:
+ CXFA_FFDocView(CXFA_FFDoc* pDoc);
+ ~CXFA_FFDocView();
+ virtual XFA_HDOC GetDoc()
+ {
+ return (XFA_HDOC)m_pDoc;
+ }
+ virtual FX_INT32 StartLayout(FX_INT32 iStartPage = 0);
+ virtual FX_INT32 DoLayout(IFX_Pause *pPause = NULL);
+ virtual void StopLayout();
+ virtual FX_INT32 GetLayoutStatus();
+ virtual void UpdateDocView();
+ virtual FX_INT32 CountPageViews();
+ virtual IXFA_PageView* GetPageView(FX_INT32 nIndex);
+ virtual XFA_HWIDGET GetWidgetByName(FX_WSTR wsName);
+ virtual CXFA_WidgetAcc* GetWidgetAccByName(FX_WSTR wsName);
+ virtual void ResetWidgetData(CXFA_WidgetAcc* pWidgetAcc = NULL);
+ virtual FX_INT32 ProcessWidgetEvent(CXFA_EventParam* pParam, CXFA_WidgetAcc* pWidgetAcc = NULL);
+ virtual IXFA_WidgetHandler* GetWidgetHandler();
+ virtual IXFA_WidgetIterator* CreateWidgetIterator();
+ virtual IXFA_WidgetAccIterator* CreateWidgetAccIterator(XFA_WIDGETORDER eOrder = XFA_WIDGETORDER_PreOrder);
+ virtual XFA_HWIDGET GetFocusWidget();
+ virtual void KillFocus();
+ virtual FX_BOOL SetFocus(XFA_HWIDGET hWidget);
+ CXFA_FFWidget* GetWidgetByName(FX_WSTR wsName, CXFA_FFWidget* pRefWidget = NULL);
+ CXFA_WidgetAcc* GetWidgetAccByName(FX_WSTR wsName, CXFA_WidgetAcc* pRefWidgetAcc = NULL);
+ IXFA_DocLayout* GetXFALayout() const;
+ void OnPageEvent(IXFA_LayoutPage *pSender, XFA_PAGEEVENT eEvent, FX_INT32 iPageIndex);
+ void LockUpdate();
+ void UnlockUpdate();
+ FX_BOOL IsUpdateLocked();
+ void ClearInvalidateList();
+ void AddInvalidateRect(CXFA_FFWidget* pWidget, const CFX_RectF &rtInvalidate);
+ void AddInvalidateRect(IXFA_PageView* pPageView, const CFX_RectF &rtInvalidate);
+ void RunInvalidate();
+ void RunDocClose();
+ void DestroyDocView();
+
+ FX_BOOL InitValidate(CXFA_Node* pNode);
+ FX_BOOL RunValidate();
+
+ void SetChangeMark();
+
+ void AddValidateWidget(CXFA_WidgetAcc* pWidget);
+ void AddCalculateNodeNotify(CXFA_Node* pNodeChange);
+ void AddCalculateWidgetAcc(CXFA_WidgetAcc* pWidgetAcc);
+ FX_INT32 RunCalculateWidgets();
+ FX_BOOL IsStaticNotify();
+ FX_BOOL RunLayout();
+ void RunSubformIndexChange();
+ void AddNewFormNode(CXFA_Node* pNode);
+ void AddIndexChangedSubform(CXFA_Node* pNode);
+ CXFA_WidgetAcc* GetFocusWidgetAcc();
+ void SetFocusWidgetAcc(CXFA_WidgetAcc* pWidgetAcc);
+ void DeleteLayoutItem(CXFA_FFWidget* pWidget);
+ FX_INT32 ExecEventActivityByDeepFirst(CXFA_Node* pFormNode, XFA_EVENTTYPE eEventType, FX_BOOL bIsFormReady = FALSE, FX_BOOL bRecursive = TRUE, CXFA_Node* pExclude = NULL);
+ FX_BOOL m_bLayoutEvent;
+ CFX_WideStringArray m_arrNullTestMsg;
+ CXFA_FFWidget* m_pListFocusWidget;
+ FX_BOOL m_bInLayoutStatus;
+protected:
+ FX_BOOL RunEventLayoutReady();
+ void RunBindItems();
+ FX_BOOL InitCalculate(CXFA_Node* pNode);
+ void InitLayout(CXFA_Node* pNode);
+ void RunCalculateRecursive(FX_INT32& iIndex);
+ void ShowNullTestMsg();
+ FX_BOOL ResetSingleWidgetAccData(CXFA_WidgetAcc* pWidgetAcc);
+ CXFA_Node* GetRootSubform();
+ CXFA_FFDoc* m_pDoc;
+ CXFA_FFWidgetHandler* m_pWidgetHandler;
+ IXFA_DocLayout* m_pXFADocLayout;
+ CXFA_WidgetAcc* m_pFocusAcc;
+ CXFA_FFWidget* m_pFocusWidget;
+ CXFA_FFWidget* m_pOldFocusWidget;
+ CFX_MapPtrToPtr m_mapPageInvalidate;
+ CFX_PtrArray m_ValidateAccs;
+ CFX_PtrArray m_bindItems;
+ CFX_PtrArray m_CalculateAccs;
+
+ CFX_PtrArray m_NewAddedNodes;
+ CFX_PtrArray m_IndexChangedSubforms;
+ XFA_DOCVIEW_LAYOUTSTATUS m_iStatus;
+ FX_INT32 m_iLock;
+ friend class CXFA_FFNotify;
+};
+class CXFA_FFDocWidgetIterator : public IXFA_WidgetIterator, public CFX_Object
+{
+public:
+ CXFA_FFDocWidgetIterator(CXFA_FFDocView* pDocView, CXFA_Node* pTravelRoot);
+ ~CXFA_FFDocWidgetIterator();
+
+ virtual void Release()
+ {
+ delete this;
+ }
+
+ virtual void Reset();
+ virtual XFA_HWIDGET MoveToFirst();
+ virtual XFA_HWIDGET MoveToLast();
+ virtual XFA_HWIDGET MoveToNext();
+ virtual XFA_HWIDGET MoveToPrevious();
+ virtual XFA_HWIDGET GetCurrentWidget();
+ virtual FX_BOOL SetCurrentWidget(XFA_HWIDGET hWidget);
+protected:
+ CXFA_ContainerIterator m_ContentIterator;
+ CXFA_FFDocView* m_pDocView;
+ CXFA_FFWidget* m_pCurWidget;
+};
+class CXFA_WidgetAccIterator : public IXFA_WidgetAccIterator, public CFX_Object
+{
+public:
+ CXFA_WidgetAccIterator(CXFA_FFDocView* pDocView, CXFA_Node* pTravelRoot);
+ ~CXFA_WidgetAccIterator();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual void Reset();
+ virtual CXFA_WidgetAcc* MoveToFirst();
+ virtual CXFA_WidgetAcc* MoveToLast();
+ virtual CXFA_WidgetAcc* MoveToNext();
+ virtual CXFA_WidgetAcc* MoveToPrevious();
+ virtual CXFA_WidgetAcc* GetCurrentWidgetAcc();
+ virtual FX_BOOL SetCurrentWidgetAcc(CXFA_WidgetAcc* hWidget);
+ virtual void SkipTree();
+protected:
+ CXFA_ContainerIterator m_ContentIterator;
+ CXFA_FFDocView* m_pDocView;
+ CXFA_WidgetAcc* m_pCurWidgetAcc;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffdraw.cpp b/xfa/src/fxfa/src/app/xfa_ffdraw.cpp
new file mode 100644
index 0000000000..a681c14516
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdraw.cpp
@@ -0,0 +1,20 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffdraw.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+CXFA_FFDraw::CXFA_FFDraw(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFWidget(pPageView, pDataAcc)
+{
+}
+CXFA_FFDraw::~CXFA_FFDraw()
+{
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffdraw.h b/xfa/src/fxfa/src/app/xfa_ffdraw.h
new file mode 100644
index 0000000000..28b41083ed
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffdraw.h
@@ -0,0 +1,16 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_DRAW_IMP_H
+#define _FXFA_FORMFILLER_DRAW_IMP_H
+class CXFA_FFDraw : public CXFA_FFWidget
+{
+public:
+ CXFA_FFDraw(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFDraw();
+protected:
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffexclgroup.cpp b/xfa/src/fxfa/src/app/xfa_ffexclgroup.cpp
new file mode 100644
index 0000000000..75d5f7e5c4
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffexclgroup.cpp
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffexclgroup.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+CXFA_FFExclGroup::CXFA_FFExclGroup(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFWidget(pPageView, pDataAcc)
+{
+}
+CXFA_FFExclGroup::~CXFA_FFExclGroup()
+{
+}
+void CXFA_FFExclGroup::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffexclgroup.h b/xfa/src/fxfa/src/app/xfa_ffexclgroup.h
new file mode 100644
index 0000000000..bc8acd6789
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffexclgroup.h
@@ -0,0 +1,18 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_EXCLGROUP_IMP_H
+#define _FXFA_FORMFILLER_EXCLGROUP_IMP_H
+class CXFA_FFExclGroup : public CXFA_FFWidget
+{
+public:
+ CXFA_FFExclGroup(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFExclGroup();
+
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+protected:
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_fffield.cpp b/xfa/src/fxfa/src/app/xfa_fffield.cpp
new file mode 100644
index 0000000000..5f32db5bb3
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fffield.cpp
@@ -0,0 +1,874 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+#include "xfa_fwltheme.h"
+#include "xfa_textlayout.h"
+#include "xfa_ffdocview.h"
+CXFA_FFField::CXFA_FFField(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFWidget(pPageView, pDataAcc)
+ , m_pNormalWidget(NULL)
+{
+ m_rtUI.Set(0, 0, 0, 0);
+ m_rtCaption.Set(0, 0, 0, 0);
+}
+CXFA_FFField::~CXFA_FFField()
+{
+ CXFA_FFField::UnloadWidget();
+}
+FX_BOOL CXFA_FFField::GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus)
+{
+ if (bDrawFocus) {
+ XFA_ELEMENT type = (XFA_ELEMENT)m_pDataAcc->GetUIType();
+ if (type == XFA_ELEMENT_Button || type == XFA_ELEMENT_CheckButton || type == XFA_ELEMENT_ImageEdit
+ || type == XFA_ELEMENT_Signature || type == XFA_ELEMENT_ChoiceList) {
+ rtBox = m_rtUI;
+ CFX_Matrix mt;
+ GetRotateMatrix(mt);
+ mt.TransformRect(rtBox);
+ return TRUE;
+ }
+ return FALSE;
+ }
+#ifndef _XFA_EMB
+ return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
+#endif
+ GetRectWithoutRotate(rtBox);
+ if (m_pNormalWidget) {
+ CFX_RectF rtWidget;
+ m_pNormalWidget->GetWidgetRect(rtWidget);
+ rtBox.Union(rtWidget);
+ }
+ CFX_Matrix mt;
+ GetRotateMatrix(mt);
+ mt.TransformRect(rtBox);
+ return TRUE;
+}
+void CXFA_FFField::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+ RenderCaption(pGS, &mtRotate);
+ DrawHighlight(pGS, &mtRotate, dwStatus, FALSE);
+ CFX_RectF rtWidget;
+ m_pNormalWidget->GetWidgetRect(rtWidget);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
+ mt.Concat(mtRotate);
+ GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(), pGS, &mt);
+}
+void CXFA_FFField::DrawHighlight(CFX_Graphics* pGS, CFX_Matrix* pMatrix, FX_DWORD dwStatus, FX_BOOL bEllipse)
+{
+ if (m_rtUI.IsEmpty() || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ return;
+ }
+ if ((dwStatus & XFA_WIDGETSTATUS_Highlight) && m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open) {
+ CXFA_FFDoc* pDoc = GetDoc();
+ CFX_Color crHighlight(pDoc->GetDocProvider()->GetHighlightColor((XFA_HDOC)pDoc));
+ pGS->SetFillColor(&crHighlight);
+ CFX_Path path;
+ path.Create();
+ if (bEllipse) {
+ path.AddEllipse(m_rtUI);
+ } else {
+ path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
+ }
+ pGS->FillPath(&path, FXFILL_WINDING, pMatrix);
+ }
+}
+void CXFA_FFField::DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix)
+{
+ if (m_dwStatus & XFA_WIDGETSTATUS_Focused) {
+ CFX_Color cr(0xFF000000);
+ pGS->SetStrokeColor(&cr);
+ FX_FLOAT DashPattern[2] = {1, 1};
+ pGS->SetLineDash(0.0f, DashPattern, 2);
+ pGS->SetLineWidth(0, FALSE);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(m_rtUI.left, m_rtUI.top, m_rtUI.width, m_rtUI.height);
+ pGS->StrokePath(&path, pMatrix);
+ }
+}
+void CXFA_FFField::SetFWLThemeProvider()
+{
+ if (m_pNormalWidget) {
+ m_pNormalWidget->m_pImp->SetThemeProvider(GetApp()->GetFWLTheme());
+ }
+}
+FX_BOOL CXFA_FFField::IsLoaded()
+{
+ return m_pNormalWidget != NULL && CXFA_FFWidget::IsLoaded();
+}
+FX_BOOL CXFA_FFField::LoadWidget()
+{
+ SetFWLThemeProvider();
+ m_pDataAcc->LoadCaption();
+ LayoutWidget();
+ return TRUE;
+}
+void CXFA_FFField::UnloadWidget()
+{
+ if (m_pNormalWidget) {
+ m_pNormalWidget->Release();
+ m_pNormalWidget = NULL;
+ }
+}
+void CXFA_FFField::SetEditScrollOffset()
+{
+ XFA_ELEMENT eType = m_pDataAcc->GetUIType();
+ if (eType == XFA_ELEMENT_TextEdit || eType == XFA_ELEMENT_NumericEdit || eType == XFA_ELEMENT_PasswordEdit) {
+ FX_FLOAT fScrollOffset = 0;
+ CXFA_FFField* pPrev = (CXFA_FFField*)GetLayoutItem()->GetPrev();
+ if (pPrev) {
+ CFX_RectF rtMargin;
+ m_pDataAcc->GetUIMargin(rtMargin);
+ fScrollOffset = -rtMargin.top;
+ }
+ while(pPrev) {
+ fScrollOffset += pPrev->m_rtUI.height;
+ pPrev = (CXFA_FFField*)pPrev->GetLayoutItem()->GetPrev();
+ }
+ ((CFWL_Edit*)m_pNormalWidget)->SetScrollOffset(fScrollOffset);
+ }
+}
+FX_BOOL CXFA_FFField::LayoutWidget()
+{
+ CXFA_FFWidget::LayoutWidget();
+ CapPlacement();
+ LayoutCaption();
+ SetFWLRect();
+ SetEditScrollOffset();
+ if (m_pNormalWidget) {
+ m_pNormalWidget->Update();
+ }
+ return TRUE;
+}
+void CXFA_FFField::CapPlacement()
+{
+ CFX_RectF rtWidget;
+ GetRectWithoutRotate(rtWidget);
+ CXFA_Margin mgWidget = m_pDataAcc->GetMargin();
+ if (mgWidget) {
+ CXFA_LayoutItem* pItem = this->GetLayoutItem();
+ if (!pItem) {
+ return;
+ }
+ FX_FLOAT fLeftInset = 0, fRightInset = 0, fTopInset = 0, fBottomInset = 0;
+ mgWidget.GetLeftInset(fLeftInset);
+ mgWidget.GetRightInset(fRightInset);
+ mgWidget.GetTopInset(fTopInset);
+ mgWidget.GetBottomInset(fBottomInset);
+ if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+ rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
+ } else {
+ if (pItem->GetPrev() == NULL) {
+ rtWidget.Deflate(fLeftInset, fTopInset, fRightInset, 0);
+ } else if (pItem->GetNext() == NULL) {
+ rtWidget.Deflate(fLeftInset, 0, fRightInset, fBottomInset);
+ } else {
+ rtWidget.Deflate(fLeftInset, 0, fRightInset, 0);
+ }
+ }
+ }
+ XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
+ FX_FLOAT fCapReserve = 0;
+ CXFA_Caption caption = m_pDataAcc->GetCaption();
+ if (caption.IsExistInXML() && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+ iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Top && (GetLayoutItem()->GetPrev())) {
+ m_rtCaption.Set(0, 0, 0, 0);
+ } else if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom && (GetLayoutItem()->GetNext())) {
+ m_rtCaption.Set(0, 0, 0, 0);
+ } else {
+ fCapReserve = caption.GetReserve();
+ CXFA_LayoutItem* pItem = this->GetLayoutItem();
+ if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+ m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);
+ } else {
+ pItem = pItem->GetFirst();
+ pItem->GetRect(m_rtCaption);
+ pItem = pItem->GetNext();
+ while (pItem) {
+ CFX_RectF rtRect;
+ pItem->GetRect(rtRect);
+ m_rtCaption.height += rtRect.Height();
+ pItem = pItem->GetNext();
+ }
+ XFA_RectWidthoutMargin(m_rtCaption, mgWidget);
+ }
+ CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+ if (fCapReserve <= 0 && pCapTextLayout) {
+ CFX_SizeF size;
+ size.Set(0, 0);
+ CFX_SizeF minSize;
+ minSize.Set(0, 0);
+ CFX_SizeF maxSize;
+ maxSize.Set(0, 0);
+ pCapTextLayout->CalcSize(minSize, maxSize, size);
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Top || iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
+ fCapReserve = size.y;
+ } else {
+ fCapReserve = size.x;
+ }
+ }
+ }
+ }
+ m_rtUI = rtWidget;
+ switch(iCapPlacement) {
+ case XFA_ATTRIBUTEENUM_Left: {
+ m_rtCaption.width = fCapReserve;
+ CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
+ m_rtUI.width -= fCapReserve;
+ m_rtUI.left += fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Top: {
+ m_rtCaption.height = fCapReserve;
+ CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
+ m_rtUI.top += fCapReserve;
+ m_rtUI.height -= fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Right: {
+ m_rtCaption.left = m_rtCaption.right() - fCapReserve;
+ m_rtCaption.width = fCapReserve;
+ CapLeftRightPlacement(caption, rtWidget, iCapPlacement);
+ m_rtUI.width -= fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom: {
+ m_rtCaption.top = m_rtCaption.bottom() - fCapReserve;
+ m_rtCaption.height = fCapReserve;
+ CapTopBottomPlacement(caption, rtWidget, iCapPlacement);
+ m_rtUI.height -= fCapReserve;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Inline:
+ break;
+ default:
+ break;
+ }
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ if (borderUI) {
+ CXFA_Margin margin = borderUI.GetMargin();
+ if (margin.IsExistInXML()) {
+ XFA_RectWidthoutMargin(m_rtUI, margin);
+ }
+ }
+ m_rtUI.Normalize();
+}
+void CXFA_FFField::CapTopBottomPlacement(CXFA_Caption caption, const CFX_RectF &rtWidget, FX_INT32 iCapPlacement)
+{
+ CFX_RectF rtUIMargin;
+ m_pDataAcc->GetUIMargin(rtUIMargin);
+ m_rtCaption.left += rtUIMargin.left;
+ if (CXFA_Margin mgCap = caption.GetMargin()) {
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ if (m_rtCaption.height < 0) {
+ m_rtCaption.top += m_rtCaption.height;
+ }
+ }
+ FX_FLOAT fWidth = rtUIMargin.left + rtUIMargin.width;
+ FX_FLOAT fHeight = m_rtCaption.height + rtUIMargin.top + rtUIMargin.height;
+ if (fWidth > rtWidget.width) {
+ m_rtUI.width += fWidth - rtWidget.width;
+ }
+ if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
+ m_rtUI.height = XFA_MINUI_HEIGHT;
+ m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
+ } else if (fHeight > rtWidget.height) {
+ m_rtUI.height += fHeight - rtWidget.height;
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom) {
+ m_rtCaption.top += fHeight - rtWidget.height;
+ }
+ }
+}
+void CXFA_FFField::CapLeftRightPlacement(CXFA_Caption caption, const CFX_RectF &rtWidget, FX_INT32 iCapPlacement)
+{
+ CFX_RectF rtUIMargin;
+ m_pDataAcc->GetUIMargin(rtUIMargin);
+ m_rtCaption.top += rtUIMargin.top;
+ m_rtCaption.height -= rtUIMargin.top;
+ if (CXFA_Margin mgCap = caption.GetMargin()) {
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ if (m_rtCaption.height < 0) {
+ m_rtCaption.top += m_rtCaption.height;
+ }
+ }
+ FX_FLOAT fWidth = m_rtCaption.width + rtUIMargin.left + rtUIMargin.width;
+ FX_FLOAT fHeight = rtUIMargin.top + rtUIMargin.height;
+ if (fWidth > rtWidget.width) {
+ m_rtUI.width += fWidth - rtWidget.width;
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Right) {
+ m_rtCaption.left += fWidth - rtWidget.width;
+ }
+ }
+ if (fHeight == XFA_DEFAULTUI_HEIGHT && m_rtUI.height < XFA_MINUI_HEIGHT) {
+ m_rtUI.height = XFA_MINUI_HEIGHT;
+ m_rtCaption.top += rtUIMargin.top + rtUIMargin.height;
+ } else if (fHeight > rtWidget.height) {
+ m_rtUI.height += fHeight - rtWidget.height;
+ }
+}
+void CXFA_FFField::UpdateFWL()
+{
+ if (m_pNormalWidget) {
+ m_pNormalWidget->Update();
+ }
+}
+FX_DWORD CXFA_FFField::UpdateUIProperty()
+{
+ CXFA_Node* pUiNode = m_pDataAcc->GetUIChild();
+ FX_DWORD dwStyle = 0;
+ if (pUiNode && pUiNode->GetClassID() == XFA_ELEMENT_DefaultUi) {
+ dwStyle = FWL_STYLEEXT_EDT_ReadOnly;
+ }
+ return dwStyle;
+}
+void CXFA_FFField::SetFWLRect()
+{
+ if (!m_pNormalWidget) {
+ return;
+ }
+ CFX_RectF rtUi = m_rtUI;
+ if (rtUi.width < 1.0) {
+ FXSYS_assert(rtUi.width < 1.0);
+ rtUi.width = 1.0;
+ }
+ if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ FX_FLOAT fFontSize = m_pDataAcc->GetFontSize();
+ if (rtUi.height < fFontSize) {
+ rtUi.height = fFontSize;
+ }
+ }
+ m_pNormalWidget->SetWidgetRect(rtUi);
+}
+FX_BOOL CXFA_FFField::OnMouseEnter()
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_MouseEnter;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnMouseExit()
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_MouseLeave;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+void CXFA_FFField::FWLToClient(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ if (!m_pNormalWidget) {
+ return;
+ }
+ CFX_RectF rtWidget;
+ m_pNormalWidget->GetWidgetRect(rtWidget);
+ fx -= rtWidget.left;
+ fy -= rtWidget.top;
+}
+FX_BOOL CXFA_FFField::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ return FALSE;
+ }
+ if (!PtInActiveRect(fx, fy)) {
+ return FALSE;
+ }
+ SetButtonDown(TRUE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ if (!IsButtonDown()) {
+ return FALSE;
+ }
+ SetButtonDown(FALSE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonUp;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDblClk;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_MouseMove;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnMouseWheel(FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_MsgMouseWheel ms;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_fDeltaX = zDelta;
+ ms.m_fDeltaY = 0;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ return FALSE;
+ }
+ if (!PtInActiveRect(fx, fy)) {
+ return FALSE;
+ }
+ SetButtonDown(TRUE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDown;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ if (!IsButtonDown()) {
+ return FALSE;
+ }
+ SetButtonDown(FALSE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonUp;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDblClk;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+
+FX_BOOL CXFA_FFField::OnSetFocus(CXFA_FFWidget* pOldWidget)
+{
+ CXFA_FFWidget::OnSetFocus(pOldWidget);
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFWL_MsgSetFocus ms;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+ AddInvalidateRect();
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnKillFocus(CXFA_FFWidget* pNewWidget)
+{
+ if (!m_pNormalWidget) {
+ return CXFA_FFWidget::OnKillFocus(pNewWidget);
+ }
+ CFWL_MsgKillFocus ms;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
+ AddInvalidateRect();
+ CXFA_FFWidget::OnKillFocus(pNewWidget);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ return FALSE;
+ }
+ CFWL_MsgKey ms;
+ ms.m_dwCmd = FWL_MSGKEYCMD_KeyDown;
+ ms.m_dwFlags = dwFlags;
+ ms.m_dwKeyCode = dwKeyCode;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ if (!m_pNormalWidget || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ return FALSE;
+ }
+ CFWL_MsgKey ms;
+ ms.m_dwCmd = FWL_MSGKEYCMD_KeyUp;
+ ms.m_dwFlags = dwFlags;
+ ms.m_dwKeyCode = dwKeyCode;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags)
+{
+ if (!m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ return FALSE;
+ }
+ if (dwChar == FWL_VKEY_Tab) {
+ return TRUE;
+ }
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+ return FALSE;
+ }
+ CFWL_MsgKey ms;
+ ms.m_dwCmd = FWL_MSGKEYCMD_Char;
+ ms.m_dwFlags = dwFlags;
+ ms.m_dwKeyCode = dwChar;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_DWORD CXFA_FFField::OnHitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pNormalWidget) {
+ FX_FLOAT ffx = fx, ffy = fy;
+ FWLToClient(ffx, ffy);
+ FX_DWORD dwWidgetHit = m_pNormalWidget->HitTest(ffx, ffy);
+ if (dwWidgetHit != FWL_WGTHITTEST_Unknown) {
+ return FWL_WGTHITTEST_Client;
+ }
+ }
+ CFX_RectF rtBox;
+ GetRectWithoutRotate(rtBox);
+ if (!rtBox.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Unknown;
+ }
+ if (m_rtCaption.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Titlebar;
+ }
+ return FWL_WGTHITTEST_Border;
+}
+FX_BOOL CXFA_FFField::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy)
+{
+ return TRUE;
+}
+FX_BOOL CXFA_FFField::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFX_RectF rtWidget;
+ m_pNormalWidget->GetWidgetRect(rtWidget);
+ if (rtWidget.Contains(fx, fy)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+void CXFA_FFField::LayoutCaption()
+{
+ CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+ if (!pCapTextLayout) {
+ return;
+ }
+ CFX_SizeF size;
+ size.Set(m_rtCaption.width, m_rtCaption.height);
+ FX_FLOAT fHeight = 0;
+ pCapTextLayout->Layout(size, &fHeight);
+ if (m_rtCaption.height < fHeight) {
+ m_rtCaption.height = fHeight;
+ }
+}
+void CXFA_FFField::RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix )
+{
+ CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+ if (!pCapTextLayout) {
+ return;
+ }
+ CXFA_Caption caption = m_pDataAcc->GetCaption();
+ if (caption.IsExistInXML() && caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
+ if (!pCapTextLayout->IsLoaded()) {
+ CFX_SizeF size;
+ size.Set(m_rtCaption.width, m_rtCaption.height);
+ pCapTextLayout->Layout(size);
+ }
+ CFX_RectF rtWidget;
+ GetRectWithoutRotate(rtWidget);
+ CFX_RectF rtClip = m_rtCaption;
+ rtClip.Intersect(rtWidget);
+ CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);
+ if (pMatrix) {
+ pMatrix->TransformRect(rtClip);
+ mt.Concat(*pMatrix);
+ }
+ pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);
+ }
+}
+FX_BOOL CXFA_FFField::ProcessCommittedData()
+{
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+ return FALSE;
+ }
+ if (!IsDataChanged()) {
+ return FALSE;
+ }
+ if (CalculateOverride() != 1) {
+ return FALSE;
+ }
+ if (!CommitData()) {
+ return FALSE;
+ }
+ m_pDocView->SetChangeMark();
+ m_pDocView->AddValidateWidget(m_pDataAcc);
+ return TRUE;
+}
+FX_INT32 CXFA_FFField::CalculateOverride()
+{
+ CXFA_WidgetAcc* pAcc = m_pDataAcc->GetExclGroup();
+ if (!pAcc) {
+ return CalculateWidgetAcc(m_pDataAcc);
+ }
+ FX_INT32 iOverride = 0;
+ if (CalculateWidgetAcc(pAcc) == 0) {
+ return 0;
+ }
+ CXFA_Node* pNode = pAcc->GetExclGroupFirstMember();
+ if (!pNode) {
+ return 1;
+ }
+ CXFA_WidgetAcc* pWidgetAcc = NULL;
+ while (pNode) {
+ pWidgetAcc = (CXFA_WidgetAcc*)pNode->GetWidgetData();
+ if (!pWidgetAcc) {
+ return 1;
+ }
+ if (CalculateWidgetAcc(pWidgetAcc) == 0) {
+ return 0;
+ }
+ pNode = pWidgetAcc->GetExclGroupNextMember(pNode);
+ }
+ return 1;
+}
+FX_INT32 CXFA_FFField::CalculateWidgetAcc(CXFA_WidgetAcc* pAcc)
+{
+ CXFA_Calculate calc = pAcc->GetCalculate();
+ if (!calc) {
+ return 1;
+ }
+ XFA_VERSION version = pAcc->GetDoc()->GetXFADoc()->GetCurVersionMode();
+ if (calc) {
+ FX_INT32 iOverride = calc.GetOverride();
+ switch (iOverride) {
+ case XFA_ATTRIBUTEENUM_Error: {
+ if (version <= XFA_VERSION_204) {
+ return 1;
+ }
+ IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
+ if (pAppProvider) {
+ CFX_WideString wsMessage;
+ CFX_WideString wsWarning;
+ pAppProvider->LoadString(XFA_IDS_NotModifyField, wsWarning);
+ wsMessage += wsWarning;
+ CFX_WideString wsTitle;
+ pAppProvider->LoadString(XFA_IDS_CalcOverride, wsTitle);
+ pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Warning, XFA_MB_OK);
+ }
+ }
+ return 0;
+ case XFA_ATTRIBUTEENUM_Warning: {
+ if (version <= XFA_VERSION_204) {
+ CXFA_Script script = calc.GetScript();
+ if (!script) {
+ return 1;
+ }
+ CFX_WideString wsExpression;
+ script.GetExpression(wsExpression);
+ if (wsExpression.IsEmpty()) {
+ return 1;
+ }
+ }
+ if (pAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+ return 1;
+ }
+ IXFA_AppProvider* pAppProvider = GetApp()->GetAppProvider();
+ if (pAppProvider) {
+ CFX_WideString wsMessage;
+ calc.GetMessageText(wsMessage);
+ if (!wsMessage.IsEmpty()) {
+ wsMessage += L"\r\n";
+ }
+ CFX_WideString wsWarning;
+ pAppProvider->LoadString(XFA_IDS_ModifyField, wsWarning);
+ wsMessage += wsWarning;
+ CFX_WideString wsTitle;
+ pAppProvider->LoadString(XFA_IDS_CalcOverride, wsTitle);
+ if (pAppProvider->MsgBox(wsMessage, wsTitle, XFA_MBICON_Warning, XFA_MB_YesNo) == XFA_IDYes) {
+ pAcc->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+ return 1;
+ }
+ }
+ return 0;
+ }
+ case XFA_ATTRIBUTEENUM_Ignore:
+ return 0;
+ case XFA_ATTRIBUTEENUM_Disabled:
+ pAcc->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+ default:
+ return 1;
+ }
+ }
+ return 1;
+}
+FX_BOOL CXFA_FFField::CommitData()
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFField::IsDataChanged()
+{
+ return FALSE;
+}
+void CXFA_FFField::TranslateFWLMessage(CFWL_Message* pMessage)
+{
+ GetApp()->GetWidgetMgrDelegate()->OnProcessMessageToForm(pMessage);
+}
+FX_INT32 CXFA_FFField::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CXFA_FFField::OnProcessEvent(CFWL_Event *pEvent)
+{
+ FX_DWORD dwEventID = pEvent->GetClassID();
+ switch (dwEventID) {
+ case FWL_EVTHASH_Mouse: {
+ CFWL_EvtMouse *event = (CFWL_EvtMouse*)pEvent;
+ if (event->m_dwCmd == FWL_MSGMOUSECMD_MouseEnter) {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_MouseEnter;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseEnter, &eParam);
+ } else if (event->m_dwCmd == FWL_MSGMOUSECMD_MouseLeave) {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_MouseExit;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseExit, &eParam);
+ } else if (event->m_dwCmd == FWL_MSGMOUSECMD_LButtonDown) {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_MouseDown;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseDown, &eParam);
+ } else if (event->m_dwCmd == FWL_MSGMOUSECMD_LButtonUp) {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_MouseUp;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_MouseUp, &eParam);
+ }
+ break;
+ }
+ case FWL_EVTHASH_Click: {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Click;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Click, &eParam);
+ break;
+ }
+ default: {
+ }
+ }
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CXFA_FFField::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_fffield.h b/xfa/src/fxfa/src/app/xfa_fffield.h
new file mode 100644
index 0000000000..c2f7e680e2
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fffield.h
@@ -0,0 +1,77 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_FIELD_IMP_H
+#define _FXFA_FORMFILLER_FIELD_IMP_H
+#define XFA_MINUI_HEIGHT 4.32f
+#define XFA_DEFAULTUI_HEIGHT 2.0f
+class CXFA_TextLayout;
+class CXFA_FFField : public CXFA_FFWidget, public IFWL_WidgetDelegate
+{
+public:
+ CXFA_FFField(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFField();
+
+ virtual FX_BOOL GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus = FALSE);
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+ virtual FX_BOOL IsLoaded();
+ virtual FX_BOOL LoadWidget();
+ virtual void UnloadWidget();
+ virtual FX_BOOL LayoutWidget();
+ virtual void UpdateFWL();
+ FX_DWORD UpdateUIProperty();
+ virtual FX_BOOL OnMouseEnter();
+ virtual FX_BOOL OnMouseExit();
+ virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseWheel(FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+
+ virtual FX_BOOL OnSetFocus(CXFA_FFWidget* pOldWidget);
+ virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+ virtual FX_BOOL OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnChar(FX_DWORD dwChar, FX_DWORD dwFlags);
+ virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnSetCursor(FX_FLOAT fx, FX_FLOAT fy);
+protected:
+ virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+ virtual void SetFWLRect();
+ void SetFWLThemeProvider();
+ CFWL_Widget* GetNormalWidget()
+ {
+ return m_pNormalWidget;
+ }
+ void FWLToClient(FX_FLOAT &fx, FX_FLOAT &fy);
+ void LayoutCaption();
+ void RenderCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL);
+
+ FX_INT32 CalculateOverride();
+ FX_INT32 CalculateWidgetAcc(CXFA_WidgetAcc* pAcc);
+ FX_BOOL ProcessCommittedData();
+ virtual FX_BOOL CommitData();
+ virtual FX_BOOL IsDataChanged();
+ void DrawHighlight(CFX_Graphics* pGS, CFX_Matrix* pMatrix, FX_DWORD dwStatus, FX_BOOL bEllipse = FALSE);
+ void DrawFocus(CFX_Graphics* pGS, CFX_Matrix* pMatrix);
+ void TranslateFWLMessage(CFWL_Message* pMessage);
+ void CapPlacement();
+ void CapTopBottomPlacement(CXFA_Caption caption, const CFX_RectF &rtWidget, FX_INT32 iCapPlacement);
+ void CapLeftRightPlacement(CXFA_Caption caption, const CFX_RectF &rtWidget, FX_INT32 iCapPlacement);
+ void SetEditScrollOffset();
+public:
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ CFWL_Widget* m_pNormalWidget;
+ CFX_RectF m_rtUI;
+ CFX_RectF m_rtCaption;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffimage.cpp b/xfa/src/fxfa/src/app/xfa_ffimage.cpp
new file mode 100644
index 0000000000..a12b1ff9dc
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffimage.cpp
@@ -0,0 +1,70 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffdraw.h"
+#include "xfa_ffimage.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffapp.h"
+CXFA_FFImage::CXFA_FFImage(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFDraw(pPageView, pDataAcc)
+{
+}
+CXFA_FFImage::~CXFA_FFImage()
+{
+ CXFA_FFImage::UnloadWidget();
+}
+FX_BOOL CXFA_FFImage::IsLoaded()
+{
+ return GetDataAcc()->GetImageImage() != NULL;
+}
+FX_BOOL CXFA_FFImage::LoadWidget()
+{
+ if (GetDataAcc()->GetImageImage()) {
+ return TRUE;
+ }
+ GetDataAcc()->LoadImageImage();
+ return CXFA_FFDraw::LoadWidget();
+}
+void CXFA_FFImage::UnloadWidget()
+{
+ GetDataAcc()->SetImageImage(NULL);
+}
+void CXFA_FFImage::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ if (CFX_DIBitmap* pDIBitmap = GetDataAcc()->GetImageImage()) {
+ CFX_RectF rtImage;
+ GetRectWithoutRotate(rtImage);
+ if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+ XFA_RectWidthoutMargin(rtImage, mgWidget);
+ }
+ FX_INT32 iHorzAlign = XFA_ATTRIBUTEENUM_Left;
+ FX_INT32 iVertAlign = XFA_ATTRIBUTEENUM_Top;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ iHorzAlign = para.GetHorizontalAlign();
+ iVertAlign = para.GetVerticalAlign();
+ }
+ CXFA_Value value = m_pDataAcc->GetFormValue();
+ CXFA_Image imageObj = value.GetImage();
+ FX_INT32 iAspect = imageObj.GetAspect();
+ FX_INT32 iImageXDpi = 0;
+ FX_INT32 iImageYDpi = 0;
+ m_pDataAcc->GetImageDpi(iImageXDpi, iImageYDpi);
+ XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi, iImageYDpi, iHorzAlign, iVertAlign);
+ }
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffimage.h b/xfa/src/fxfa/src/app/xfa_ffimage.h
new file mode 100644
index 0000000000..f6b985c304
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffimage.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DRAW_IMAGE_IMP_H
+#define _XFA_DRAW_IMAGE_IMP_H
+class CXFA_FFImage : public CXFA_FFDraw
+{
+public:
+ CXFA_FFImage(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFImage();
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+ virtual FX_BOOL IsLoaded();
+ virtual FX_BOOL LoadWidget();
+ virtual void UnloadWidget();
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffimageedit.cpp b/xfa/src/fxfa/src/app/xfa_ffimageedit.cpp
new file mode 100644
index 0000000000..2075d90d21
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffimageedit.cpp
@@ -0,0 +1,188 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffimageedit.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffdoc.h"
+CXFA_FFImageEdit::CXFA_FFImageEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pPageView, pDataAcc)
+ , m_pOldDelegate(NULL)
+{
+}
+CXFA_FFImageEdit::~CXFA_FFImageEdit()
+{
+ CXFA_FFImageEdit::UnloadWidget();
+}
+FX_BOOL CXFA_FFImageEdit::LoadWidget()
+{
+ CFWL_PictureBox* pPictureBox = FX_NEW CFWL_PictureBox;
+ if (pPictureBox) {
+ pPictureBox->Initialize();
+ }
+ m_pNormalWidget = (CFWL_Widget*)pPictureBox;
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+ m_pOldDelegate = pPictureBox->SetDelegate(this);
+ CXFA_FFField::LoadWidget();
+ if (m_pDataAcc->GetImageEditImage() != NULL) {
+ return TRUE;
+ }
+ UpdateFWLData();
+ return TRUE;
+}
+void CXFA_FFImageEdit::UnloadWidget()
+{
+ m_pDataAcc->SetImageEditImage(NULL);
+ CXFA_FFField::UnloadWidget();
+}
+void CXFA_FFImageEdit::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+ RenderCaption(pGS, &mtRotate);
+ if (CFX_DIBitmap* pDIBitmap = m_pDataAcc->GetImageEditImage()) {
+ CFX_RectF rtImage;
+ m_pNormalWidget->GetWidgetRect(rtImage);
+ FX_INT32 iHorzAlign = XFA_ATTRIBUTEENUM_Left;
+ FX_INT32 iVertAlign = XFA_ATTRIBUTEENUM_Top;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ iHorzAlign = para.GetHorizontalAlign();
+ iVertAlign = para.GetVerticalAlign();
+ }
+ FX_INT32 iAspect = XFA_ATTRIBUTEENUM_Fit;
+ if (CXFA_Value value = m_pDataAcc->GetFormValue()) {
+ if (CXFA_Image imageObj = value.GetImage()) {
+ iAspect = imageObj.GetAspect();
+ }
+ }
+ FX_INT32 iImageXDpi = 0;
+ FX_INT32 iImageYDpi = 0;
+ m_pDataAcc->GetImageEditDpi(iImageXDpi, iImageYDpi);
+ XFA_DrawImage(pGS, rtImage, &mtRotate, pDIBitmap, iAspect, iImageXDpi, iImageYDpi, iHorzAlign, iVertAlign);
+ }
+}
+FX_BOOL CXFA_FFImageEdit::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+ return FALSE;
+ }
+ if (!PtInActiveRect(fx, fy)) {
+ return FALSE;
+ }
+ SetButtonDown(TRUE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ TranslateFWLMessage(&ms);
+ IXFA_AppProvider* pAppProvider = GetAppProvider();
+ if (!pAppProvider) {
+ return TRUE;
+ }
+ CFX_WideString wsTitle;
+ CFX_WideString wsFilter;
+ pAppProvider->LoadString(XFA_IDS_ImageFilter, wsFilter);
+ CFX_WideStringArray wsPathArray;
+ pAppProvider->ShowFileDialog(wsTitle, wsFilter, wsPathArray);
+ FX_INT32 iSize = wsPathArray.GetSize();
+ if (iSize < 1) {
+ return TRUE;
+ }
+ CFX_WideString wsFilePath = wsPathArray[0];
+ FX_STRSIZE nLen = wsFilePath.GetLength();
+ FX_STRSIZE nIndex = nLen - 1;
+ while (nIndex > 0 && wsFilePath[nIndex] != '.') {
+ nIndex--;
+ }
+ if (nIndex <= 0) {
+ return TRUE;
+ }
+ CFX_WideString wsContentType(L"image/");
+ wsContentType += wsFilePath.Right(nLen - nIndex - 1);
+ wsContentType.MakeLower();
+ FXCODEC_IMAGE_TYPE eImageType = XFA_GetImageType(wsContentType);
+ if (eImageType == FXCODEC_IMAGE_UNKNOWN) {
+ return TRUE;
+ }
+ CFX_WideString wsImage;
+ IFX_FileRead* pFileRead = FX_CreateFileRead(wsFilePath);
+ if (pFileRead != NULL) {
+ FX_INT32 nDataSize = pFileRead->GetSize();
+ if (nDataSize > 0) {
+ CFX_ByteString bsBuf;
+ FX_LPSTR pImageBuffer = bsBuf.GetBuffer(nDataSize);
+ pFileRead->ReadBlock(pImageBuffer, 0, nDataSize);
+ bsBuf.ReleaseBuffer();
+ if (!bsBuf.IsEmpty()) {
+ FX_LPSTR pData = XFA_Base64Encode(bsBuf, nDataSize);
+ wsImage = CFX_WideString::FromLocal(pData);
+ if (pData != NULL) {
+ FX_Free(pData);
+ }
+ }
+ }
+ m_pDataAcc->SetImageEditImage(NULL);
+ pFileRead->Release();
+ }
+ m_pDataAcc->SetImageEdit(wsContentType, CFX_WideStringC(), wsImage);
+ m_pDataAcc->LoadImageEditImage();
+ AddInvalidateRect();
+ m_pDocView->SetChangeMark();
+ return TRUE;
+}
+void CXFA_FFImageEdit::SetFWLRect()
+{
+ if (!m_pNormalWidget) {
+ return;
+ }
+ CFX_RectF rtUIMargin;
+ m_pDataAcc->GetUIMargin(rtUIMargin);
+ CFX_RectF rtImage(m_rtUI);
+ rtImage.Deflate(rtUIMargin.left, rtUIMargin.top, rtUIMargin.width, rtUIMargin.height);
+ m_pNormalWidget->SetWidgetRect(rtImage);
+}
+FX_BOOL CXFA_FFImageEdit::CommitData()
+{
+ return TRUE;
+}
+FX_BOOL CXFA_FFImageEdit::UpdateFWLData()
+{
+ m_pDataAcc->SetImageEditImage(NULL);
+ m_pDataAcc->LoadImageEditImage();
+ return TRUE;
+}
+FX_INT32 CXFA_FFImageEdit::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFImageEdit::OnProcessEvent(CFWL_Event *pEvent)
+{
+ CXFA_FFField::OnProcessEvent(pEvent);
+ return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFImageEdit::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffimageedit.h b/xfa/src/fxfa/src/app/xfa_ffimageedit.h
new file mode 100644
index 0000000000..7ba8333103
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffimageedit.h
@@ -0,0 +1,28 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_IMAGEEDIT_IMP_H
+#define _FXFA_FORMFILLER_IMAGEEDIT_IMP_H
+class CXFA_FFImageEdit : public CXFA_FFField
+{
+public:
+ CXFA_FFImageEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFImageEdit();
+
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+ virtual FX_BOOL LoadWidget();
+ virtual void UnloadWidget();
+ virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ virtual void SetFWLRect();
+ virtual FX_BOOL UpdateFWLData();
+ virtual FX_BOOL CommitData();
+ IFWL_WidgetDelegate *m_pOldDelegate;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffnotify.cpp b/xfa/src/fxfa/src/app/xfa_ffnotify.cpp
new file mode 100644
index 0000000000..e4e4cd30a8
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffnotify.cpp
@@ -0,0 +1,611 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffwidgethandler.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpushbutton.h"
+#include "xfa_ffcheckbutton.h"
+#include "xfa_ffchoicelist.h"
+#include "xfa_ffimageedit.h"
+#include "xfa_fftextedit.h"
+#include "xfa_ffbarcode.h"
+#include "xfa_ffdraw.h"
+#include "xfa_fftext.h"
+#include "xfa_ffpath.h"
+#include "xfa_ffimage.h"
+#include "xfa_ffexclgroup.h"
+#include "xfa_ffsubform.h"
+#include "xfa_ffsignature.h"
+#include "xfa_ffapp.h"
+#include "xfa_textlayout.h"
+#include "xfa_ffwidgetacc.h"
+#include "xfa_ffnotify.h"
+static void XFA_FFDeleteWidgetAcc(FX_LPVOID pData)
+{
+ if (pData) {
+ delete (CXFA_WidgetAcc*)pData;
+ }
+}
+static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteWidgetAcc = {XFA_FFDeleteWidgetAcc, NULL};
+CXFA_FFNotify::CXFA_FFNotify(CXFA_FFDoc* pDoc)
+ : m_pDoc(pDoc)
+{
+}
+CXFA_FFNotify::~CXFA_FFNotify()
+{
+}
+void CXFA_FFNotify::OnPageEvent(IXFA_LayoutPage *pSender, XFA_PAGEEVENT eEvent, FX_LPVOID pParam)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pSender->GetLayout());
+ if (!pDocView) {
+ return;
+ }
+ pDocView->OnPageEvent(pSender, eEvent, (FX_INT32)(FX_UINTPTR)pParam);
+}
+void CXFA_FFNotify::OnNodeEvent(CXFA_Node *pSender, XFA_NODEEVENT eEvent, FX_LPVOID pParam , FX_LPVOID pParam2 , FX_LPVOID pParam3, FX_LPVOID pParam4)
+{
+ switch (eEvent) {
+ case XFA_NODEEVENT_Ready:
+ OnNodeReady(pSender);
+ break;
+ case XFA_NODEEVENT_ValueChanging:
+ OnValueChanging(pSender, pParam, pParam2);
+ break;
+ case XFA_NODEEVENT_ValueChanged:
+ OnValueChanged(pSender, pParam, pParam2, pParam3, pParam4);
+ break;
+ case XFA_NODEEVENT_ChildAdded:
+ OnChildAdded(pSender, pParam, pParam2);
+ break;
+ case XFA_NODEEVENT_ChildRemoved:
+ OnChildRemoved(pSender, pParam, pParam2);
+ break;
+ }
+}
+void CXFA_FFNotify::OnWidgetDataEvent(CXFA_WidgetData* pSender, FX_DWORD dwEvent, FX_LPVOID pParam , FX_LPVOID pAdditional , FX_LPVOID pAdditional2 )
+{
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pSender;
+ switch (dwEvent) {
+ case XFA_WIDGETEVENT_ListItemAdded: {
+ if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {
+ return;
+ }
+ FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();
+ CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);
+ if (!pWidget) {
+ if (bStaticNotify) {
+ pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam, pAdditional);
+ }
+ return;
+ }
+ while (pWidget) {
+ if (pWidget->IsLoaded()) {
+ if (pWidgetAcc->IsListBox()) {
+ ((CXFA_FFListBox*)pWidget)->InsertItem((FX_WSTR)(FX_LPCWSTR)pParam, (FX_INT32)(FX_UINTPTR)pAdditional2);
+ } else {
+ ((CXFA_FFComboBox*)pWidget)->InsertItem((FX_WSTR)(FX_LPCWSTR)pParam, (FX_INT32)(FX_UINTPTR)pAdditional2);
+ }
+ }
+ if (bStaticNotify) {
+ pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemAdded, pParam, pAdditional);
+ }
+ pWidget = pWidgetAcc->GetNextWidget(pWidget);
+ }
+ }
+ break;
+ case XFA_WIDGETEVENT_ListItemRemoved: {
+ if (pWidgetAcc->GetUIType() != XFA_ELEMENT_ChoiceList) {
+ return;
+ }
+ FX_BOOL bStaticNotify = pWidgetAcc->GetDocView()->IsStaticNotify();
+ CXFA_FFWidget* pWidget = pWidgetAcc->GetNextWidget(NULL);
+ if (!pWidget) {
+ if (bStaticNotify) {
+ pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam, pAdditional);
+ }
+ return;
+ }
+ while (pWidget) {
+ if (pWidget->IsLoaded()) {
+ if (pWidgetAcc->IsListBox()) {
+ ((CXFA_FFListBox*)pWidget)->DeleteItem((FX_INT32)(FX_UINTPTR)pParam);
+ } else {
+ ((CXFA_FFComboBox*)pWidget)->DeleteItem((FX_INT32)(FX_UINTPTR)pParam);
+ }
+ }
+ if (bStaticNotify) {
+ pWidgetAcc->GetDoc()->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidgetAcc, XFA_WIDGETEVENT_ListItemRemoved, pParam, pAdditional);
+ }
+ pWidget = pWidgetAcc->GetNextWidget(pWidget);
+ }
+ }
+ break;
+ }
+}
+CXFA_LayoutItem* CXFA_FFNotify::OnCreateLayoutItem(CXFA_Node* pNode)
+{
+ IXFA_DocLayout* pLayout = m_pDoc->GetXFADoc()->GetDocLayout();
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
+ XFA_ELEMENT eType = pNode->GetClassID();
+ if (eType == XFA_ELEMENT_PageArea) {
+ return (CXFA_LayoutItem*)(FX_NEW CXFA_FFPageView(pDocView, pNode));
+ } else if (eType == XFA_ELEMENT_ContentArea) {
+ return (CXFA_LayoutItem*)(FX_NEW CXFA_ContainerLayoutItemImpl(pNode));
+ }
+ CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pNode->GetWidgetData();
+ if (!pAcc) {
+ return (CXFA_LayoutItem*)(FX_NEW CXFA_ContentLayoutItemImpl(pNode));
+ }
+ CXFA_FFPageView* pPageView = NULL;
+ CXFA_FFWidget* pWidget = NULL;
+ switch(pAcc->GetUIType()) {
+ case XFA_ELEMENT_Barcode:
+ pWidget = FX_NEW CXFA_FFBarcode(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Button:
+ pWidget = FX_NEW CXFA_FFPushButton(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_CheckButton:
+ pWidget = FX_NEW CXFA_FFCheckButton(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_ChoiceList: {
+ if (pAcc->IsListBox()) {
+ pWidget = FX_NEW CXFA_FFListBox(pPageView, pAcc);
+ } else {
+ pWidget = FX_NEW CXFA_FFComboBox(pPageView, pAcc);
+ }
+ }
+ break;
+ case XFA_ELEMENT_DateTimeEdit:
+ pWidget = FX_NEW CXFA_FFDateTimeEdit(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_ImageEdit:
+ pWidget = FX_NEW CXFA_FFImageEdit(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_NumericEdit:
+ pWidget = FX_NEW CXFA_FFNumericEdit(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_PasswordEdit:
+ pWidget = FX_NEW CXFA_FFPasswordEdit(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Signature:
+ pWidget = FX_NEW CXFA_FFSignature(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_TextEdit:
+ pWidget = FX_NEW CXFA_FFTextEdit(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Arc:
+ pWidget = FX_NEW CXFA_FFArc(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Line:
+ pWidget = FX_NEW CXFA_FFLine(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Rectangle:
+ pWidget = FX_NEW CXFA_FFRectangle(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Text:
+ pWidget = FX_NEW CXFA_FFText(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Image:
+ pWidget = FX_NEW CXFA_FFImage(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Draw:
+ pWidget = FX_NEW CXFA_FFDraw(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_Subform:
+ pWidget = FX_NEW CXFA_FFSubForm(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_ExclGroup:
+ pWidget = FX_NEW CXFA_FFExclGroup(pPageView, pAcc);
+ break;
+ case XFA_ELEMENT_DefaultUi:
+ default:
+ pWidget = NULL;
+ break;
+ }
+ if (!pWidget) {
+ return NULL;
+ }
+ pWidget->SetDocView(pDocView);
+ return pWidget->GetLayoutItem();
+}
+void CXFA_FFNotify::OnLayoutEvent(IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, XFA_LAYOUTEVENT eEvent, FX_LPVOID pParam , FX_LPVOID pParam2 )
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView(pLayout);
+ if (!pDocView || !XFA_GetWidgetFromLayoutItem(pSender)) {
+ return;
+ }
+ switch (eEvent) {
+ case XFA_LAYOUTEVENT_ItemAdded:
+ OnLayoutItemAdd(pDocView, pLayout, pSender, pParam, pParam2);
+ break;
+ case XFA_LAYOUTEVENT_ItemRemoving:
+ OnLayoutItemRemoving(pDocView, pLayout, pSender, pParam, pParam2);
+ break;
+ case XFA_LAYOUTEVENT_RectChanged:
+ OnLayoutItemRectChanged(pDocView, pLayout, pSender, pParam, pParam2);
+ break;
+ case XFA_LAYOUTEVENT_StatusChanged:
+ OnLayoutItemStatustChanged(pDocView, pLayout, pSender, pParam, pParam2);
+ break;
+ }
+}
+void CXFA_FFNotify::StartFieldDrawLayout(CXFA_Node *pItem, FX_FLOAT &fCalcWidth, FX_FLOAT &fCalcHeight)
+{
+ CXFA_WidgetAcc *pAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData();
+ if (!pAcc) {
+ return;
+ }
+ pAcc->StartWidgetLayout(fCalcWidth, fCalcHeight);
+}
+FX_BOOL CXFA_FFNotify::FindSplitPos(CXFA_Node *pItem, FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeightPos)
+{
+ CXFA_WidgetAcc *pAcc = (CXFA_WidgetAcc*)pItem->GetWidgetData();
+ if (!pAcc) {
+ return FALSE;
+ }
+ return (XFA_LAYOUTRESULT)pAcc->FindSplitPos(iBlockIndex, fCalcHeightPos);
+}
+FX_BOOL CXFA_FFNotify::RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem)
+{
+ FX_BOOL bRet = FALSE;
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return bRet;
+ }
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pFormItem->GetWidgetData();
+ if (!pWidgetAcc) {
+ return bRet;
+ }
+ CXFA_EventParam EventParam;
+ EventParam.m_eType = XFA_EVENT_Unknown;
+ FXJSE_HVALUE pRetValue = NULL;
+ FX_INT32 iRet = pWidgetAcc->ExecuteScript(CXFA_Script(pScript), &EventParam, &pRetValue);
+ if (iRet == XFA_EVENTERROR_Sucess && pRetValue) {
+ bRet = FXJSE_Value_ToBoolean(pRetValue);
+ FXJSE_Value_Release(pRetValue);
+ }
+ return bRet;
+}
+FX_INT32 CXFA_FFNotify::ExecEventByDeepFirst(CXFA_Node* pFormNode, XFA_EVENTTYPE eEventType, FX_BOOL bIsFormReady, FX_BOOL bRecursive, CXFA_WidgetAcc* pExclude)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ return pDocView->ExecEventActivityByDeepFirst(pFormNode, eEventType, bIsFormReady, bRecursive, pExclude ? pExclude->GetNode() : NULL);
+}
+void CXFA_FFNotify::AddCalcValidate(CXFA_Node* pNode)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pNode->GetWidgetData();
+ if (!pWidgetAcc) {
+ return;
+ }
+ pDocView->AddCalculateWidgetAcc(pWidgetAcc);
+ pDocView->AddValidateWidget(pWidgetAcc);
+}
+XFA_HDOC CXFA_FFNotify::GetHDOC()
+{
+ return (XFA_HDOC)m_pDoc;
+}
+IXFA_DocProvider* CXFA_FFNotify::GetDocProvider()
+{
+ return m_pDoc->GetDocProvider();
+}
+IXFA_AppProvider* CXFA_FFNotify::GetAppProvider()
+{
+ return m_pDoc->GetApp()->GetAppProvider();
+}
+IXFA_WidgetHandler* CXFA_FFNotify::GetWidgetHandler()
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ return pDocView ? pDocView->GetWidgetHandler() : NULL;
+}
+XFA_HWIDGET CXFA_FFNotify::GetHWidget(CXFA_LayoutItem* pLayoutItem)
+{
+ return (XFA_HWIDGET)XFA_GetWidgetFromLayoutItem(pLayoutItem);
+}
+void CXFA_FFNotify::OpenDropDownList(XFA_HWIDGET hWidget)
+{
+ CXFA_FFWidget* pWidget = (CXFA_FFWidget*)hWidget;
+ if (pWidget->GetDataAcc()->GetUIType() != XFA_ELEMENT_ChoiceList) {
+ return;
+ }
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ pDocView->LockUpdate();
+ ((CXFA_FFComboBox*)pWidget)->OpenDropDownList();
+ pDocView->UnlockUpdate();
+ pDocView->UpdateDocView();
+}
+CFX_WideString CXFA_FFNotify::GetCurrentDateTime()
+{
+ CFX_Unitime dataTime;
+ dataTime.Now();
+ CFX_WideString wsDateTime;
+ wsDateTime.Format((FX_LPCWSTR)L"%d%02d%02dT%02d%02d%02d", dataTime.GetYear(), dataTime.GetMonth(), dataTime.GetDay(), dataTime.GetHour(), dataTime.GetMinute(), dataTime.GetSecond());
+ return wsDateTime;
+}
+void CXFA_FFNotify::ResetData(CXFA_WidgetData* pWidgetData)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ pDocView->ResetWidgetData((CXFA_WidgetAcc*)pWidgetData);
+}
+FX_INT32 CXFA_FFNotify::GetLayoutStatus()
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ return pDocView ? pDocView->GetLayoutStatus() : 0;
+}
+void CXFA_FFNotify::RunNodeInitialize(CXFA_Node* pNode)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ pDocView->AddNewFormNode(pNode);
+}
+void CXFA_FFNotify::RunSubformIndexChange(CXFA_Node* pSubformNode)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ pDocView->AddIndexChangedSubform(pSubformNode);
+}
+CXFA_Node* CXFA_FFNotify::GetFocusWidgetNode()
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return NULL;
+ }
+ CXFA_WidgetAcc* pAcc = pDocView->GetFocusWidgetAcc();
+ return pAcc ? pAcc->GetNode() : NULL;
+}
+void CXFA_FFNotify::SetFocusWidgetNode(CXFA_Node* pNode)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ CXFA_WidgetAcc* pAcc = pNode ? (CXFA_WidgetAcc*)pNode->GetWidgetData() : NULL;
+ pDocView->SetFocusWidgetAcc(pAcc);
+}
+void CXFA_FFNotify::OnNodeReady(CXFA_Node *pNode)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ XFA_ELEMENT iType = pNode->GetClassID();
+ if (XFA_IsCreateWidget(iType)) {
+ CXFA_WidgetAcc* pAcc = FX_NEW CXFA_WidgetAcc(pDocView, (CXFA_Node*)pNode);
+ pNode->SetObject(XFA_ATTRIBUTE_WidgetData, pAcc, &gs_XFADeleteWidgetAcc);
+ return;
+ }
+ switch (iType) {
+ case XFA_ELEMENT_BindItems:
+ pDocView->m_bindItems.Add(pNode);
+ break;
+ case XFA_ELEMENT_Validate: {
+ pNode->SetFlag(XFA_NODEFLAG_NeedsInitApp, TRUE, FALSE);
+ }
+ break;
+ default:
+ break;
+ }
+}
+void CXFA_FFNotify::OnValueChanging(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) {
+ return;
+ }
+ FX_DWORD dwPacket = pSender->GetPacketID();
+ if (dwPacket & XFA_XDPPACKET_Datasets) {
+ } else if (pSender->IsFormContainer()) {
+ XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(FX_UINTPTR)pParam;
+ if (eAttr == XFA_ATTRIBUTE_Presence) {
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pSender->GetWidgetData();
+ if (!pWidgetAcc) {
+ return;
+ }
+ CXFA_FFWidget* pWidget = NULL;
+ while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != NULL) {
+ if (pWidget->IsLoaded()) {
+ pWidget->AddInvalidateRect();
+ }
+ }
+ }
+ }
+}
+void CXFA_FFNotify::OnValueChanged(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2, FX_LPVOID pParam3, FX_LPVOID pParam4)
+{
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ FX_DWORD dwPacket = pSender->GetPacketID();
+ XFA_ATTRIBUTE eAttr = (XFA_ATTRIBUTE)(FX_UINTPTR)pParam;
+ if (dwPacket & XFA_XDPPACKET_Form) {
+ CXFA_Node* pParentNode = (CXFA_Node*)pParam3;
+ CXFA_Node* pWidgetNode = (CXFA_Node*)pParam4;
+ XFA_ELEMENT ePType = pParentNode->GetClassID();
+ FX_BOOL bIsContainerNode = pParentNode->IsContainerNode();
+ CXFA_WidgetAcc* pWidgetAcc = (CXFA_WidgetAcc*)pWidgetNode->GetWidgetData();
+ if (!pWidgetAcc) {
+ return;
+ }
+ FX_BOOL bUpdateProperty = FALSE;
+ pDocView->SetChangeMark();
+ switch (ePType) {
+ case XFA_ELEMENT_Caption: {
+ CXFA_TextLayout* pCapOut = pWidgetAcc->GetCaptionTextLayout();
+ if (!pCapOut) {
+ return;
+ }
+ pCapOut->Unload();
+ }
+ break;
+ case XFA_ELEMENT_Ui:
+ case XFA_ELEMENT_Para:
+ bUpdateProperty = TRUE;
+ break;
+ case XFA_ELEMENT_Font:
+ case XFA_ELEMENT_Margin:
+ case XFA_ELEMENT_Value:
+ case XFA_ELEMENT_Items:
+ break;
+ default:
+ break;
+ }
+ if (bIsContainerNode && eAttr == XFA_ATTRIBUTE_Access) {
+ bUpdateProperty = TRUE;
+ FX_BOOL bNotify = pDocView->IsStaticNotify();
+ if (bNotify) {
+ pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_AccessChanged, NULL, pParam2, NULL);
+ }
+ }
+ if (eAttr == XFA_ATTRIBUTE_Value) {
+ pDocView->AddCalculateNodeNotify(pSender);
+ if (ePType == XFA_ELEMENT_Value || bIsContainerNode) {
+ FX_BOOL bNotify = pDocView->IsStaticNotify();
+ if (bIsContainerNode) {
+ pWidgetAcc->UpdateUIDisplay();
+ pDocView->AddCalculateWidgetAcc(pWidgetAcc);
+ pDocView->AddValidateWidget(pWidgetAcc);
+ } else if (pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() == XFA_ELEMENT_ExclGroup) {
+ pWidgetAcc->UpdateUIDisplay();
+ }
+ if (bNotify) {
+ pWidgetAcc->NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL, NULL);
+ }
+ return;
+ }
+ }
+ CXFA_FFWidget* pWidget = NULL;
+ while ((pWidget = pWidgetAcc->GetNextWidget(pWidget)) != NULL) {
+ if (!pWidget->IsLoaded()) {
+ continue;
+ }
+ if (bUpdateProperty) {
+ pWidget->UpdateWidgetProperty();
+ }
+ pWidget->LayoutWidget();
+ pWidget->AddInvalidateRect();
+ }
+ } else {
+ if (eAttr == XFA_ATTRIBUTE_Value) {
+ pDocView->AddCalculateNodeNotify(pSender);
+ }
+ }
+}
+void CXFA_FFNotify::OnChildAdded(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)
+{
+ if (!pSender->IsFormContainer()) {
+ return;
+ }
+ CXFA_FFDocView* pDocView = m_pDoc->GetDocView();
+ if (!pDocView) {
+ return;
+ }
+ FX_BOOL bLayoutReady = !(pDocView->m_bInLayoutStatus) && (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End);
+ if (bLayoutReady) {
+ m_pDoc->GetDocProvider()->SetChangeMark((XFA_HDOC)m_pDoc);
+ }
+}
+void CXFA_FFNotify::OnChildRemoved(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)
+{
+ if (CXFA_FFDocView* pDocView = m_pDoc->GetDocView()) {
+ FX_BOOL bLayoutReady = !(pDocView->m_bInLayoutStatus) && (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End);
+ if (bLayoutReady) {
+ m_pDoc->GetDocProvider()->SetChangeMark((XFA_HDOC)m_pDoc);
+ }
+ }
+}
+void CXFA_FFNotify::OnLayoutItemAdd(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)
+{
+ CXFA_FFWidget* pWidget = (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pSender;
+ FX_INT32 iPageIdx = (FX_INT32)(FX_UINTPTR)pParam;
+ IXFA_PageView* pNewPageView = pDocView->GetPageView(iPageIdx);
+ FX_DWORD dwStatus = (FX_DWORD)(FX_UINTPTR)pParam2;
+ FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable | XFA_WIDGETSTATUS_Printable;
+ pWidget->ModifyStatus(dwStatus, dwFilter);
+ if (pDocView->GetLayoutStatus() >= XFA_DOCVIEW_LAYOUTSTATUS_End) {
+ IXFA_PageView* pPrePageView = pWidget->GetPageView();
+ if (pPrePageView != pNewPageView || (dwStatus & (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) == (XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable)) {
+ pWidget->SetPageView(pNewPageView);
+ m_pDoc->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidget->GetDataAcc(), XFA_WIDGETEVENT_PostAdded, pNewPageView, pPrePageView);
+ }
+ if ((dwStatus & XFA_WIDGETSTATUS_Visible) == 0) {
+ return;
+ }
+ if (pWidget->IsLoaded()) {
+ CFX_RectF rtOld;
+ pWidget->GetWidgetRect(rtOld);
+ CFX_RectF rtNew = pWidget->ReCacheWidgetRect();
+ if(rtOld != rtNew) {
+ pWidget->LayoutWidget();
+ }
+ } else {
+ pWidget->LoadWidget();
+ }
+ pWidget->AddInvalidateRect(NULL);
+ } else {
+ pWidget->SetPageView(pNewPageView);
+ }
+}
+void CXFA_FFNotify::OnLayoutItemRemoving(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)
+{
+ CXFA_FFWidget* pWidget = (CXFA_FFWidget*)pSender;
+ pDocView->DeleteLayoutItem(pWidget);
+ if (pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End) {
+ return;
+ }
+ m_pDoc->GetDocProvider()->WidgetEvent((XFA_HWIDGET)pWidget, pWidget->GetDataAcc(), XFA_WIDGETEVENT_PreRemoved, NULL, NULL);
+ pWidget->AddInvalidateRect(NULL);
+}
+void CXFA_FFNotify::OnLayoutItemRectChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)
+{
+}
+void CXFA_FFNotify::OnLayoutItemStatustChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2)
+{
+ CXFA_FFWidget* pWidget = (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pSender;
+ if (!pWidget) {
+ return;
+ }
+ FX_DWORD dwStatus = (FX_DWORD)(FX_UINTPTR)pParam;
+ if (dwStatus == 0) {
+ CXFA_LayoutItem* pPreItem = pSender->GetPrev();
+ if (pPreItem) {
+ CXFA_FFWidget* pPreWidget = (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pPreItem;
+ if (pPreWidget) {
+ dwStatus = pPreWidget->GetStatus();
+ }
+ }
+ }
+ FX_DWORD dwOldStatus = pWidget->GetStatus();
+ FX_DWORD dwFilter = XFA_WIDGETSTATUS_Visible | XFA_WIDGETSTATUS_Viewable | XFA_WIDGETSTATUS_Printable;
+ if ((dwOldStatus & dwFilter) == dwStatus) {
+ return;
+ }
+ pWidget->ModifyStatus(dwStatus, dwFilter);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffnotify.h b/xfa/src/fxfa/src/app/xfa_ffnotify.h
new file mode 100644
index 0000000000..dd2b80ed29
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffnotify.h
@@ -0,0 +1,52 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FFNOTIFY_H_
+#define _FXFA_FFNOTIFY_H_
+class CXFA_FFNotify : public IXFA_Notify, public CFX_Object
+{
+public:
+ CXFA_FFNotify(CXFA_FFDoc* pDoc);
+ ~CXFA_FFNotify();
+
+ virtual void OnPageEvent(IXFA_LayoutPage *pSender, XFA_PAGEEVENT eEvent, FX_LPVOID pParam = NULL);
+
+ virtual void OnNodeEvent(CXFA_Node *pSender, XFA_NODEEVENT eEvent, FX_LPVOID pParam = NULL, FX_LPVOID pParam2 = NULL, FX_LPVOID pParam3 = NULL, FX_LPVOID pParam4 = NULL);
+ virtual void OnWidgetDataEvent(CXFA_WidgetData* pSender, FX_DWORD dwEvent, FX_LPVOID pParam = NULL, FX_LPVOID pAdditional = NULL, FX_LPVOID pAdditional2 = NULL);
+ virtual CXFA_LayoutItem* OnCreateLayoutItem(CXFA_Node *pNode);
+ virtual void OnLayoutEvent(IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, XFA_LAYOUTEVENT eEvent, FX_LPVOID pParam = NULL, FX_LPVOID pParam2 = NULL);
+
+ virtual void StartFieldDrawLayout(CXFA_Node *pItem, FX_FLOAT &fCalcWidth, FX_FLOAT &fCalcHeight);
+ virtual FX_BOOL FindSplitPos(CXFA_Node *pItem, FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeightPos);
+ virtual FX_BOOL RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem);
+ virtual FX_INT32 ExecEventByDeepFirst(CXFA_Node* pFormNode, XFA_EVENTTYPE eEventType, FX_BOOL bIsFormReady = FALSE, FX_BOOL bRecursive = TRUE, CXFA_WidgetAcc * pExclude = NULL);
+ virtual void AddCalcValidate(CXFA_Node* pNode);
+ virtual XFA_HDOC GetHDOC();
+ virtual IXFA_DocProvider* GetDocProvider();
+ virtual IXFA_AppProvider* GetAppProvider();
+ virtual IXFA_WidgetHandler* GetWidgetHandler();
+ virtual XFA_HWIDGET GetHWidget(CXFA_LayoutItem* pLayoutItem);
+ virtual void OpenDropDownList(XFA_HWIDGET hWidget);
+ virtual CFX_WideString GetCurrentDateTime();
+ virtual void ResetData(CXFA_WidgetData* pWidgetData = NULL);
+ virtual FX_INT32 GetLayoutStatus();
+ virtual void RunNodeInitialize(CXFA_Node* pNode);
+ virtual void RunSubformIndexChange(CXFA_Node* pSubformNode);
+ virtual CXFA_Node* GetFocusWidgetNode();
+ virtual void SetFocusWidgetNode(CXFA_Node* pNode);
+protected:
+ void OnNodeReady(CXFA_Node *pNode);
+ void OnValueChanging(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2);
+ void OnValueChanged(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2, FX_LPVOID pParam3, FX_LPVOID pParam4);
+ void OnChildAdded(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2);
+ void OnChildRemoved(CXFA_Node *pSender, FX_LPVOID pParam, FX_LPVOID pParam2);
+ void OnLayoutItemAdd(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2);
+ void OnLayoutItemRemoving(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2);
+ void OnLayoutItemRectChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2);
+ void OnLayoutItemStatustChanged(CXFA_FFDocView* pDocView, IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, FX_LPVOID pParam, FX_LPVOID pParam2);
+ CXFA_FFDoc* m_pDoc;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffpageview.cpp b/xfa/src/fxfa/src/app/xfa_ffpageview.cpp
new file mode 100644
index 0000000000..ec591adb72
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffpageview.cpp
@@ -0,0 +1,428 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffdocview.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpushbutton.h"
+#include "xfa_ffcheckbutton.h"
+#include "xfa_ffchoicelist.h"
+#include "xfa_ffimageedit.h"
+#include "xfa_fftextedit.h"
+CXFA_FFPageView::CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea)
+ : CXFA_ContainerLayoutItemImpl(pPageArea)
+ , m_pDocView(pDocView)
+ , m_bLoaded(FALSE)
+{
+}
+CXFA_FFPageView::~CXFA_FFPageView()
+{
+}
+IXFA_DocView* CXFA_FFPageView::GetDocView()
+{
+ return m_pDocView;
+}
+FX_INT32 CXFA_FFPageView::GetPageViewIndex()
+{
+ return GetLayoutPage()->GetPageIndex();
+}
+void CXFA_FFPageView::GetPageViewRect(CFX_RectF &rtPage)
+{
+ CFX_SizeF sz;
+ GetLayoutPage()->GetPageSize(sz);
+ rtPage.Set(0, 0, sz);
+}
+void CXFA_FFPageView::GetDisplayMatrix(CFX_Matrix &mt, const CFX_Rect &rtDisp, FX_INT32 iRotate)
+{
+ CFX_SizeF sz;
+ GetLayoutPage()->GetPageSize(sz);
+ CFX_RectF fdePage;
+ fdePage.Set(0, 0, sz.x, sz.y);
+ FDE_GetPageMatrix(mt, fdePage, rtDisp, iRotate, 0);
+}
+FX_INT32 CXFA_FFPageView::LoadPageView(IFX_Pause *pPause )
+{
+ if (m_bLoaded) {
+ return 100;
+ }
+ m_bLoaded = TRUE;
+ return 100;
+}
+void CXFA_FFPageView::UnloadPageView()
+{
+ if (!m_bLoaded) {
+ return;
+ }
+}
+FX_BOOL CXFA_FFPageView::IsPageViewLoaded()
+{
+ return m_bLoaded;
+}
+XFA_HWIDGET CXFA_FFPageView::GetWidgetByPos(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_bLoaded) {
+ return NULL;
+ }
+ IXFA_WidgetIterator* pIterator = CreateWidgetIterator();
+ while (CXFA_FFWidget* pWidget = (CXFA_FFWidget*)pIterator->MoveToNext()) {
+ if (!(pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ continue;
+ }
+ CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+ FX_INT32 type = pAcc->GetClassID();
+ if (type != XFA_ELEMENT_Field && type != XFA_ELEMENT_Draw) {
+ continue;
+ }
+ FX_FLOAT fWidgetx = fx, fWidgety = fy;
+ pWidget->Rotate2Normal(fWidgetx, fWidgety);
+ FX_DWORD dwFlag = pWidget->OnHitTest(fWidgetx, fWidgety);
+ if (( FWL_WGTHITTEST_Client == dwFlag
+ || FWL_WGTHITTEST_Transparent == dwFlag)) {
+ pIterator->Release();
+ return (XFA_HWIDGET)pWidget;
+ }
+ }
+ pIterator->Release();
+ return NULL;
+}
+IXFA_WidgetIterator* CXFA_FFPageView::CreateWidgetIterator(FX_DWORD dwTraverseWay ,
+ FX_DWORD dwWidgetFilter )
+{
+ switch (dwTraverseWay) {
+ case XFA_TRAVERSEWAY_Tranvalse:
+ return FX_NEW CXFA_FFTabOrderPageWidgetIterator(this, dwWidgetFilter);
+ case XFA_TRAVERSEWAY_Form:
+ return FX_NEW CXFA_FFPageWidgetIterator(this, dwWidgetFilter);
+ }
+ return NULL;
+}
+static FX_BOOL XFA_PageWidgetFilter(CXFA_FFWidget* pWidget, FX_DWORD dwFilter, FX_BOOL bTraversal, FX_BOOL bIgnorerelevant)
+{
+ CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
+ FX_DWORD dwType = dwFilter & XFA_WIDGETFILTER_AllType;
+ if ((dwType == XFA_WIDGETFILTER_Field) && (pWidgetAcc->GetClassID() != XFA_ELEMENT_Field)) {
+ return FALSE;
+ }
+ FX_DWORD dwStatus = pWidget->GetStatus();
+ if (bTraversal && (dwStatus & XFA_WIDGETSTATUS_Disabled)) {
+ return FALSE;
+ }
+ if (bIgnorerelevant) {
+ return (dwStatus & XFA_WIDGETFILTER_Visible) != 0;
+ }
+ dwFilter &= (XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_Viewable | XFA_WIDGETFILTER_Printable);
+ return (dwFilter & dwStatus) == dwFilter;
+}
+CXFA_FFPageWidgetIterator::CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView, FX_DWORD dwFilter)
+{
+ m_pPageView = pPageView;
+ m_dwFilter = dwFilter;
+ m_sIterator.Init((CXFA_LayoutItem*)pPageView->GetLayoutPage());
+ m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())->GetXFADoc()->GetCurVersionMode() < XFA_VERSION_205;
+}
+CXFA_FFPageWidgetIterator::~CXFA_FFPageWidgetIterator()
+{
+}
+void CXFA_FFPageWidgetIterator::Reset()
+{
+ m_sIterator.Reset();
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToFirst()
+{
+ m_sIterator.Reset();
+ for(CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent(); pLayoutItem; pLayoutItem = m_sIterator.MoveToNext()) {
+ if (XFA_HWIDGET hWidget = GetWidget(pLayoutItem)) {
+ return hWidget;
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToLast()
+{
+ m_sIterator.SetCurrent(NULL);
+ return MoveToPrevious();
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToNext()
+{
+ for(CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToNext(); pLayoutItem; pLayoutItem = m_sIterator.MoveToNext()) {
+ if (XFA_HWIDGET hWidget = GetWidget(pLayoutItem)) {
+ return hWidget;
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::MoveToPrevious()
+{
+ for(CXFA_LayoutItem* pLayoutItem = m_sIterator.MoveToPrev(); pLayoutItem; pLayoutItem = m_sIterator.MoveToPrev()) {
+ if (XFA_HWIDGET hWidget = GetWidget(pLayoutItem)) {
+ return hWidget;
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::GetCurrentWidget()
+{
+ CXFA_LayoutItem* pLayoutItem = m_sIterator.GetCurrent();
+ return pLayoutItem ? (XFA_HWIDGET)XFA_GetWidgetFromLayoutItem(pLayoutItem) : NULL;
+}
+FX_BOOL CXFA_FFPageWidgetIterator::SetCurrentWidget(XFA_HWIDGET hWidget)
+{
+ if(hWidget && m_sIterator.SetCurrent(((CXFA_FFWidget*)hWidget)->GetLayoutItem())) {
+ return TRUE;
+ }
+ return FALSE;
+}
+XFA_HWIDGET CXFA_FFPageWidgetIterator::GetWidget(CXFA_LayoutItem* pLayoutItem)
+{
+ if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
+ if (!XFA_PageWidgetFilter(pWidget, m_dwFilter, FALSE, m_bIgnorerelevant)) {
+ return NULL;
+ }
+ if (!pWidget->IsLoaded() && (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible) != 0) {
+ pWidget->LoadWidget();
+ }
+ return (XFA_HWIDGET)pWidget;
+ }
+ return NULL;
+}
+CXFA_FFTabOrderPageWidgetIterator::CXFA_FFTabOrderPageWidgetIterator(CXFA_FFPageView* pPageView, FX_DWORD dwFilter)
+ : m_pPageView(pPageView)
+ , m_dwFilter(dwFilter)
+ , m_iCurWidget(-1)
+{
+ m_bIgnorerelevant = ((CXFA_FFDoc*)m_pPageView->GetDocView()->GetDoc())->GetXFADoc()->GetCurVersionMode() < XFA_VERSION_205;
+ Reset();
+}
+CXFA_FFTabOrderPageWidgetIterator::~CXFA_FFTabOrderPageWidgetIterator()
+{
+}
+void CXFA_FFTabOrderPageWidgetIterator::Release()
+{
+ delete this;
+}
+void CXFA_FFTabOrderPageWidgetIterator::Reset()
+{
+ CreateTabOrderWidgetArray();
+ m_iCurWidget = -1;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToFirst()
+{
+ if (m_TabOrderWidgetArray.GetSize() > 0) {
+ for (FX_INT32 i = 0; i < m_TabOrderWidgetArray.GetSize(); i++) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToLast()
+{
+ if (m_TabOrderWidgetArray.GetSize() > 0) {
+ for (FX_INT32 i = m_TabOrderWidgetArray.GetSize() - 1; i >= 0; i--) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ }
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToNext()
+{
+ for (FX_INT32 i = m_iCurWidget + 1; i < m_TabOrderWidgetArray.GetSize(); i++) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ m_iCurWidget = -1;
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::MoveToPrevious()
+{
+ for (FX_INT32 i = m_iCurWidget - 1; i >= 0; i--) {
+ if (XFA_PageWidgetFilter(m_TabOrderWidgetArray[i], m_dwFilter, TRUE, m_bIgnorerelevant)) {
+ m_iCurWidget = i;
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ }
+ m_iCurWidget = -1;
+ return NULL;
+}
+XFA_HWIDGET CXFA_FFTabOrderPageWidgetIterator::GetCurrentWidget()
+{
+ if (m_iCurWidget >= 0) {
+ return (XFA_HWIDGET)m_TabOrderWidgetArray[m_iCurWidget];
+ }
+ return NULL;
+}
+FX_BOOL CXFA_FFTabOrderPageWidgetIterator::SetCurrentWidget(XFA_HWIDGET hWidget)
+{
+ FX_INT32 iWidgetIndex = m_TabOrderWidgetArray.Find((CXFA_FFWidget*)hWidget);
+ if (iWidgetIndex >= 0) {
+ m_iCurWidget = iWidgetIndex;
+ return TRUE;
+ }
+ return FALSE;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetTraverseWidget(CXFA_FFWidget* pWidget)
+{
+ CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+ CXFA_Node* pTraversal = pAcc->GetNode()->GetChild(0, XFA_ELEMENT_Traversal);
+ if (pTraversal != NULL) {
+ CXFA_Node* pTraverse = pTraversal->GetChild(0, XFA_ELEMENT_Traverse);
+ if (pTraverse != NULL) {
+ CFX_WideString wsTraverseWidgetName;
+ if (pTraverse->GetAttribute(XFA_ATTRIBUTE_Ref, wsTraverseWidgetName)) {
+ return FindWidgetByName(wsTraverseWidgetName, pWidget);
+ }
+ }
+ }
+ return NULL;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::FindWidgetByName(FX_WSTR wsWidgetName, CXFA_FFWidget* pRefWidget)
+{
+ return pRefWidget->GetDocView()->GetWidgetByName(wsWidgetName, pRefWidget);
+}
+void CXFA_FFTabOrderPageWidgetIterator::CreateTabOrderWidgetArray()
+{
+ m_TabOrderWidgetArray.RemoveAll();
+ CXFA_WidgetArray SpaceOrderWidgetArray;
+ CreateSpaceOrderWidgetArray(SpaceOrderWidgetArray);
+ FX_INT32 nWidgetCount = SpaceOrderWidgetArray.GetSize();
+ if (nWidgetCount < 1) {
+ return;
+ }
+ CXFA_FFWidget* hWidget = SpaceOrderWidgetArray[0];
+ for (; m_TabOrderWidgetArray.GetSize() < nWidgetCount; ) {
+ if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
+ m_TabOrderWidgetArray.Add(hWidget);
+ CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
+ if (pWidgetAcc->GetUIType() == XFA_ELEMENT_ExclGroup) {
+ FX_INT32 iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget) + 1;
+ while (TRUE) {
+ CXFA_FFWidget* pRadio = SpaceOrderWidgetArray[(iWidgetIndex) % nWidgetCount];
+ if (pRadio->GetDataAcc()->GetExclGroup() != pWidgetAcc) {
+ break;
+ }
+ if (m_TabOrderWidgetArray.Find(hWidget) < 0) {
+ m_TabOrderWidgetArray.Add(pRadio);
+ }
+ iWidgetIndex++;
+ }
+ }
+ if (CXFA_FFWidget* hTraverseWidget = GetTraverseWidget(hWidget)) {
+ hWidget = hTraverseWidget;
+ continue;
+ }
+ }
+ FX_INT32 iWidgetIndex = SpaceOrderWidgetArray.Find(hWidget);
+ hWidget = SpaceOrderWidgetArray[(iWidgetIndex + 1) % nWidgetCount];
+ }
+}
+static FX_INT32 XFA_TabOrderWidgetComparator(const void* phWidget1, const void* phWidget2)
+{
+ CXFA_FFWidget* pWidget1 = (*(CXFA_TabParam**)phWidget1)->m_pWidget;
+ CXFA_FFWidget* pWidget2 = (*(CXFA_TabParam**)phWidget2)->m_pWidget;
+ CFX_RectF rt1, rt2;
+ pWidget1->GetWidgetRect(rt1);
+ pWidget2->GetWidgetRect(rt2);
+ FX_FLOAT x1 = rt1.left, y1 = rt1.top, x2 = rt2.left, y2 = rt2.top;
+ if (y1 < y2 || (y1 - y2 < XFA_FLOAT_PERCISION && x1 < x2)) {
+ return -1;
+ }
+ return 1;
+}
+void CXFA_FFTabOrderPageWidgetIterator::OrderContainer(CXFA_LayoutItemIterator* sIterator, CXFA_LayoutItem* pContainerItem, CXFA_TabParam* pContainer, FX_BOOL &bCurrentItem, FX_BOOL& bContentArea, FX_BOOL bMarsterPage)
+{
+ CFX_PtrArray tabParams;
+ CXFA_LayoutItem* pSearchItem = sIterator->MoveToNext();
+ while(pSearchItem) {
+ FX_BOOL bIsContentLayoutItem = ((CXFA_LayoutItemImpl*)pSearchItem)->IsContentLayoutItem();
+ if(!bIsContentLayoutItem) {
+ bContentArea = TRUE;
+ pSearchItem = sIterator->MoveToNext();
+ continue;
+ }
+ if (bMarsterPage && bContentArea) {
+ break;
+ }
+ if (bMarsterPage || bContentArea) {
+ CXFA_FFWidget* hWidget = GetWidget(pSearchItem);
+ if (!hWidget) {
+ pSearchItem = sIterator->MoveToNext();
+ continue;
+ }
+ if (pContainerItem && (pSearchItem->GetParent() != pContainerItem)) {
+ bCurrentItem = TRUE;
+ break;
+ }
+ CXFA_TabParam* pParam = FX_NEW CXFA_TabParam;
+ pParam->m_pWidget = hWidget;
+ tabParams.Add(pParam);
+ if (XFA_IsLayoutElement(pSearchItem->GetFormNode()->GetClassID(), TRUE)) {
+ OrderContainer(sIterator, pSearchItem, pParam, bCurrentItem, bContentArea, bMarsterPage);
+ }
+ }
+ if (bCurrentItem) {
+ pSearchItem = sIterator->GetCurrent();
+ bCurrentItem = FALSE;
+ } else {
+ pSearchItem = sIterator->MoveToNext();
+ }
+ }
+ FX_INT32 iChildren = tabParams.GetSize();
+ if (iChildren > 1) {
+ FXSYS_qsort(tabParams.GetData(), iChildren, sizeof(FX_LPVOID), XFA_TabOrderWidgetComparator);
+ }
+ for (FX_INT32 iStart = 0; iStart < iChildren; iStart++) {
+ CXFA_TabParam* pParam = (CXFA_TabParam*)tabParams[iStart];
+ pContainer->m_Children.Add(pParam->m_pWidget);
+ if (pParam->m_Children.GetSize() > 0) {
+ pContainer->m_Children.Append(pParam->m_Children);
+ }
+ delete pParam;
+ }
+ tabParams.RemoveAll();
+}
+void CXFA_FFTabOrderPageWidgetIterator::CreateSpaceOrderWidgetArray(CXFA_WidgetArray& WidgetArray)
+{
+ CXFA_LayoutItemIterator sIterator;
+ sIterator.Init((CXFA_LayoutItem*)m_pPageView->GetLayoutPage());
+ CXFA_TabParam* pParam = FX_NEW CXFA_TabParam;
+ FX_BOOL bCurrentItem = FALSE;
+ FX_BOOL bContentArea = FALSE;
+ OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea);
+ if (pParam->m_Children.GetSize() > 0) {
+ WidgetArray.Append(pParam->m_Children);
+ }
+ sIterator.Reset();
+ bCurrentItem = FALSE;
+ bContentArea = FALSE;
+ pParam->m_Children.RemoveAll();
+ OrderContainer(&sIterator, NULL, pParam, bCurrentItem, bContentArea, TRUE);
+ if (pParam->m_Children.GetSize() > 0) {
+ WidgetArray.Append(pParam->m_Children);
+ }
+ delete pParam;
+}
+CXFA_FFWidget* CXFA_FFTabOrderPageWidgetIterator::GetWidget(CXFA_LayoutItem* pLayoutItem)
+{
+ if (CXFA_FFWidget* pWidget = XFA_GetWidgetFromLayoutItem(pLayoutItem)) {
+ if (!pWidget->IsLoaded() && (pWidget->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ pWidget->LoadWidget();
+ }
+ return pWidget;
+ }
+ return NULL;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffpageview.h b/xfa/src/fxfa/src/app/xfa_ffpageview.h
new file mode 100644
index 0000000000..3ebe1b9d31
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffpageview.h
@@ -0,0 +1,99 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_PAGEVIEW_IMP_H
+#define _FXFA_FORMFILLER_PAGEVIEW_IMP_H
+class CXFA_FFWidget;
+class CXFA_FFDocView;
+class CXFA_FFPageView : public CXFA_ContainerLayoutItemImpl, public IXFA_PageView
+{
+public:
+ CXFA_FFPageView(CXFA_FFDocView* pDocView, CXFA_Node* pPageArea);
+ ~CXFA_FFPageView();
+ virtual IXFA_DocView* GetDocView();
+ virtual FX_INT32 GetPageViewIndex();
+ virtual void GetPageViewRect(CFX_RectF &rtPage);
+ virtual void GetDisplayMatrix(CFX_Matrix &mt, const CFX_Rect &rtDisp, FX_INT32 iRotate);
+ virtual FX_INT32 LoadPageView(IFX_Pause *pPause = NULL);
+ virtual void UnloadPageView();
+ FX_BOOL IsPageViewLoaded();
+
+ virtual XFA_HWIDGET GetWidgetByPos(FX_FLOAT fx, FX_FLOAT fy);
+ virtual IXFA_WidgetIterator* CreateWidgetIterator(FX_DWORD dwTraverseWay = XFA_TRAVERSEWAY_Form,
+ FX_DWORD dwWidgetFilter = XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_Viewable | XFA_WIDGETFILTER_AllType);
+ IXFA_LayoutPage* GetLayoutPage()
+ {
+ return (IXFA_LayoutPage*)this;
+ }
+protected:
+ CXFA_FFDocView* m_pDocView;
+ FX_BOOL m_bLoaded;
+};
+typedef CXFA_NodeIteratorTemplate<CXFA_LayoutItem, CXFA_TraverseStrategy_LayoutItem> CXFA_LayoutItemIterator;
+class CXFA_FFPageWidgetIterator : public IXFA_WidgetIterator, public CFX_Object
+{
+public:
+ CXFA_FFPageWidgetIterator(CXFA_FFPageView* pPageView, FX_DWORD dwFilter);
+ virtual ~CXFA_FFPageWidgetIterator();
+ virtual void Release()
+ {
+ delete this;
+ }
+
+ virtual void Reset();
+ virtual XFA_HWIDGET MoveToFirst();
+ virtual XFA_HWIDGET MoveToLast();
+ virtual XFA_HWIDGET MoveToNext();
+ virtual XFA_HWIDGET MoveToPrevious();
+ virtual XFA_HWIDGET GetCurrentWidget();
+ virtual FX_BOOL SetCurrentWidget(XFA_HWIDGET hWidget);
+protected:
+ XFA_HWIDGET GetWidget(CXFA_LayoutItem* pLayoutItem);
+ CXFA_FFPageView* m_pPageView;
+ XFA_HWIDGET m_hCurWidget;
+ FX_DWORD m_dwFilter;
+ FX_BOOL m_bIgnorerelevant;
+ CXFA_LayoutItemIterator m_sIterator;
+};
+typedef CFX_ArrayTemplate<CXFA_FFWidget*> CXFA_WidgetArray;
+class CXFA_TabParam : public CFX_Object
+{
+public:
+ CXFA_TabParam() : m_pWidget(NULL) {}
+ ~CXFA_TabParam() {}
+
+ CXFA_FFWidget* m_pWidget;
+ CXFA_WidgetArray m_Children;
+};
+class CXFA_FFTabOrderPageWidgetIterator : public IXFA_WidgetIterator, public CFX_Object
+{
+public:
+ CXFA_FFTabOrderPageWidgetIterator(CXFA_FFPageView* pPageView, FX_DWORD dwFilter);
+ virtual ~CXFA_FFTabOrderPageWidgetIterator();
+
+ virtual void Release();
+
+ virtual void Reset();
+ virtual XFA_HWIDGET MoveToFirst();
+ virtual XFA_HWIDGET MoveToLast();
+ virtual XFA_HWIDGET MoveToNext();
+ virtual XFA_HWIDGET MoveToPrevious();
+ virtual XFA_HWIDGET GetCurrentWidget();
+ virtual FX_BOOL SetCurrentWidget(XFA_HWIDGET hWidget);
+protected:
+ CXFA_WidgetArray m_TabOrderWidgetArray;
+ CXFA_FFPageView* m_pPageView;
+ FX_DWORD m_dwFilter;
+ FX_INT32 m_iCurWidget;
+ FX_BOOL m_bIgnorerelevant;
+ CXFA_FFWidget* GetTraverseWidget(CXFA_FFWidget* pWidget);
+ CXFA_FFWidget* FindWidgetByName(FX_WSTR wsWidgetName, CXFA_FFWidget* pRefWidget);
+ void CreateTabOrderWidgetArray();
+ void CreateSpaceOrderWidgetArray(CXFA_WidgetArray& WidgetArray);
+ CXFA_FFWidget* GetWidget(CXFA_LayoutItem* pLayoutItem);
+ void OrderContainer(CXFA_LayoutItemIterator* sIterator, CXFA_LayoutItem* pContainerItem, CXFA_TabParam* pContainer, FX_BOOL &bCurrentItem, FX_BOOL& bContentArea, FX_BOOL bMarsterPage = FALSE);
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffpath.cpp b/xfa/src/fxfa/src/app/xfa_ffpath.cpp
new file mode 100644
index 0000000000..2f8b71a50a
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffpath.cpp
@@ -0,0 +1,162 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffdraw.h"
+#include "xfa_ffpath.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffapp.h"
+CXFA_FFLine::CXFA_FFLine(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFDraw(pPageView, pDataAcc)
+{
+}
+CXFA_FFLine::~CXFA_FFLine()
+{
+}
+void CXFA_FFLine::GetRectFromHand(CFX_RectF &rect, FX_INT32 iHand, FX_FLOAT fLineWidth)
+{
+ FX_FLOAT fHalfWidth = fLineWidth / 2.0f;
+ if (rect.height < 1.0f) {
+ switch (iHand) {
+ case XFA_ATTRIBUTEENUM_Left:
+ rect.top -= fHalfWidth;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ rect.top += fHalfWidth;
+ }
+ } else if (rect.width < 1.0f) {
+ switch (iHand) {
+ case XFA_ATTRIBUTEENUM_Left:
+ rect.left += fHalfWidth;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ rect.left += fHalfWidth;
+ break;
+ }
+ } else {
+ switch (iHand) {
+ case XFA_ATTRIBUTEENUM_Left:
+ rect.Inflate(fHalfWidth, fHalfWidth);
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ rect.Deflate(fHalfWidth, fHalfWidth);
+ break;
+ }
+ }
+}
+void CXFA_FFLine::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CXFA_Value value = m_pDataAcc->GetFormValue();
+ if (!value) {
+ return;
+ }
+ CXFA_Line lineObj = value.GetLine();
+ FX_ARGB lineColor = 0xFF000000;
+ FX_INT32 iStrokeType = 0;
+ FX_FLOAT fLineWidth = 1.0f;
+ FX_BOOL bSlope = lineObj.GetSlop();
+ FX_INT32 iCap = 0;
+ CXFA_Edge edge = lineObj.GetEdge();
+ if (edge.IsExistInXML()) {
+ if (edge.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+ return;
+ }
+ lineColor = edge.GetColor();
+ iStrokeType = edge.GetStrokeType();
+ fLineWidth = edge.GetThickness();
+ iCap = edge.GetCapType();
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CFX_RectF rtLine;
+ GetRectWithoutRotate(rtLine);
+ if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+ XFA_RectWidthoutMargin(rtLine, mgWidget);
+ }
+ GetRectFromHand(rtLine, lineObj.GetHand(), fLineWidth);
+ CFX_Path linePath;
+ linePath.Create();
+ if (bSlope && rtLine.right() > 0.0f && rtLine.bottom() > 0.0f) {
+ linePath.AddLine(rtLine.right(), rtLine.top, rtLine.left, rtLine.bottom());
+ } else {
+ linePath.AddLine(rtLine.left, rtLine.top, rtLine.right(), rtLine.bottom());
+ }
+ CFX_Color color(lineColor);
+ pGS->SaveGraphState();
+ pGS->SetLineWidth(fLineWidth, TRUE);
+ XFA_StrokeTypeSetLineDash(pGS, iStrokeType, iCap);
+ pGS->SetStrokeColor(&color);
+ pGS->SetLineCap(XFA_LineCapToFXGE(iCap));
+ pGS->StrokePath(&linePath, &mtRotate);
+ pGS->RestoreGraphState();
+}
+CXFA_FFArc::CXFA_FFArc(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFDraw(pPageView, pDataAcc)
+{
+}
+CXFA_FFArc::~CXFA_FFArc()
+{
+}
+void CXFA_FFArc::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CXFA_Value value = m_pDataAcc->GetFormValue();
+ if (!value) {
+ return;
+ }
+ CXFA_Arc arcObj = value.GetArc();
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CFX_RectF rtArc;
+ GetRectWithoutRotate(rtArc);
+ if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+ XFA_RectWidthoutMargin(rtArc, mgWidget);
+ }
+ DrawBorder(pGS, arcObj, rtArc, &mtRotate);
+}
+CXFA_FFRectangle::CXFA_FFRectangle(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFDraw(pPageView, pDataAcc)
+{
+}
+CXFA_FFRectangle::~CXFA_FFRectangle()
+{
+}
+void CXFA_FFRectangle::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CXFA_Value value = m_pDataAcc->GetFormValue();
+ if (!value) {
+ return;
+ }
+ CXFA_Rectangle rtObj = value.GetRectangle();
+ CFX_RectF rect;
+ GetRectWithoutRotate(rect);
+ if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+ XFA_RectWidthoutMargin(rect, mgWidget);
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ DrawBorder(pGS, rtObj, rect, &mtRotate);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffpath.h b/xfa/src/fxfa/src/app/xfa_ffpath.h
new file mode 100644
index 0000000000..08828f3b84
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffpath.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DRAW_PATH_IMP_H
+#define _XFA_DRAW_PATH_IMP_H
+class CXFA_FFLine : public CXFA_FFDraw
+{
+public:
+ CXFA_FFLine(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFLine();
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+private:
+ void GetRectFromHand(CFX_RectF &rect, FX_INT32 iHand, FX_FLOAT fLineWidth);
+};
+class CXFA_FFArc : public CXFA_FFDraw
+{
+public:
+ CXFA_FFArc(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFArc();
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+};
+class CXFA_FFRectangle : public CXFA_FFDraw
+{
+public:
+ CXFA_FFRectangle(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFRectangle();
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffpushbutton.cpp b/xfa/src/fxfa/src/app/xfa_ffpushbutton.cpp
new file mode 100644
index 0000000000..125cb4f5b7
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffpushbutton.cpp
@@ -0,0 +1,252 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffwidgetacc.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffpushbutton.h"
+#include "xfa_textlayout.h"
+#include "xfa_ffapp.h"
+CXFA_FFPushButton::CXFA_FFPushButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pPageView, pDataAcc)
+ , m_pRolloverTextLayout(NULL)
+ , m_pDownTextLayout(NULL)
+ , m_pDownProvider(NULL)
+ , m_pRollProvider(NULL)
+ , m_pOldDelegate(NULL)
+{
+}
+CXFA_FFPushButton::~CXFA_FFPushButton()
+{
+ CXFA_FFPushButton::UnloadWidget();
+}
+void CXFA_FFPushButton::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ RenderHighlightCaption(pGS, &mtRotate);
+ CFX_RectF rtWidget;
+ GetRectWithoutRotate(rtWidget);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtWidget.left, rtWidget.top);
+ mt.Concat(mtRotate);
+ GetApp()->GetWidgetMgrDelegate()->OnDrawWidget(m_pNormalWidget->GetWidget(), pGS, &mt);
+}
+FX_BOOL CXFA_FFPushButton::LoadWidget()
+{
+ FXSYS_assert(m_pNormalWidget == NULL);
+ CFWL_PushButton* pPushButton = CFWL_PushButton::Create();
+ if (pPushButton) {
+ pPushButton->Initialize();
+ }
+ m_pOldDelegate = pPushButton->SetDelegate(this);
+ m_pNormalWidget = (CFWL_Widget*)pPushButton;
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+ m_pNormalWidget->LockUpdate();
+ UpdateWidgetProperty();
+ LoadHighlightCaption();
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFPushButton::UpdateWidgetProperty()
+{
+ FX_DWORD dwStyleEx = 0;
+ switch(m_pDataAcc->GetButtonHighlight()) {
+ case XFA_ATTRIBUTEENUM_Inverted:
+ dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteInverted;
+ break;
+ case XFA_ATTRIBUTEENUM_Outline:
+ dwStyleEx = XFA_FWL_PSBSTYLEEXT_HiliteOutLine;
+ break;
+ case XFA_ATTRIBUTEENUM_Push:
+ dwStyleEx = XFA_FWL_PSBSTYLEEXT_HilitePush;
+ break;
+ default:
+ break;
+ }
+ m_pNormalWidget->ModifyStylesEx(dwStyleEx, 0xFFFFFFFF);
+}
+void CXFA_FFPushButton::UnloadWidget()
+{
+ if (m_pRolloverTextLayout) {
+ delete m_pRolloverTextLayout;
+ m_pRolloverTextLayout = NULL;
+ }
+ if (m_pDownTextLayout) {
+ delete m_pDownTextLayout;
+ m_pDownTextLayout = NULL;
+ }
+ if (m_pDownProvider) {
+ delete m_pDownProvider;
+ m_pDownProvider = NULL;
+ }
+ if (m_pRollProvider) {
+ delete m_pRollProvider;
+ m_pRollProvider = NULL;
+ }
+ CXFA_FFField::UnloadWidget();
+}
+FX_BOOL CXFA_FFPushButton::LayoutWidget()
+{
+ CXFA_FFWidget::LayoutWidget();
+ CFX_RectF rtWidget;
+ GetRectWithoutRotate(rtWidget);
+ m_rtUI = rtWidget;
+ if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+ XFA_RectWidthoutMargin(rtWidget, mgWidget);
+ }
+ CXFA_Caption caption = m_pDataAcc->GetCaption();
+ m_rtCaption.Set(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);
+ if (CXFA_Margin mgCap = caption.GetMargin()) {
+ XFA_RectWidthoutMargin(m_rtCaption, mgCap);
+ }
+ LayoutHighlightCaption();
+ SetFWLRect();
+ if (m_pNormalWidget) {
+ m_pNormalWidget->Update();
+ }
+ return TRUE;
+}
+FX_FLOAT CXFA_FFPushButton::GetLineWidth()
+{
+ CXFA_Border border = m_pDataAcc->GetBorder();
+ if (border.IsExistInXML() && (border.GetPresence() == XFA_ATTRIBUTEENUM_Visible)) {
+ CXFA_Edge edge = border.GetEdge(0);
+ return edge.GetThickness();
+ }
+ return 0;
+}
+FX_ARGB CXFA_FFPushButton::GetLineColor()
+{
+ return 0xFF000000;
+}
+FX_ARGB CXFA_FFPushButton::GetFillColor()
+{
+ return 0xFFFFFFFF;
+}
+void CXFA_FFPushButton::LoadHighlightCaption()
+{
+ CXFA_Caption caption = m_pDataAcc->GetCaption();
+ if (caption.IsExistInXML() && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+ {
+ CFX_WideString wsRollover;
+ FX_BOOL bRichText;
+ if (m_pDataAcc->GetButtonRollover(wsRollover, bRichText)) {
+ if (m_pRollProvider == NULL) {
+ m_pRollProvider = FX_NEW CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Rollover);
+ }
+ m_pRolloverTextLayout = FX_NEW CXFA_TextLayout(m_pRollProvider);
+ }
+ CFX_WideString wsDown;
+ if (m_pDataAcc->GetButtonDown(wsDown, bRichText)) {
+ if (m_pDownProvider == NULL) {
+ m_pDownProvider = FX_NEW CXFA_TextProvider(m_pDataAcc, XFA_TEXTPROVIDERTYPE_Down);
+ }
+ m_pDownTextLayout = FX_NEW CXFA_TextLayout(m_pDownProvider);
+ }
+ }
+ }
+}
+void CXFA_FFPushButton::LayoutHighlightCaption()
+{
+ CFX_SizeF sz;
+ sz.Set(m_rtCaption.width, m_rtCaption.height);
+ LayoutCaption();
+ if (m_pRolloverTextLayout) {
+ m_pRolloverTextLayout->Layout(sz);
+ }
+ if (m_pDownTextLayout) {
+ m_pDownTextLayout->Layout(sz);
+ }
+}
+void CXFA_FFPushButton::RenderHighlightCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix )
+{
+ CXFA_TextLayout* pCapTextLayout = m_pDataAcc->GetCaptionTextLayout();
+ CXFA_Caption caption = m_pDataAcc->GetCaption();
+ if (caption.IsExistInXML() && caption.GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
+ CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+ CFX_RectF rtWidget;
+ GetRectWithoutRotate(rtWidget);
+ CFX_RectF rtClip = m_rtCaption;
+ rtClip.Intersect(rtWidget);
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, m_rtCaption.left, m_rtCaption.top);
+ if (pMatrix) {
+ pMatrix->TransformRect(rtClip);
+ mt.Concat(*pMatrix);
+ }
+ {
+ FX_DWORD dwState = m_pNormalWidget->GetStates();
+ if (m_pDownTextLayout && (dwState & FWL_STATE_PSB_Pressed) && (dwState & FWL_STATE_PSB_Hovered)) {
+ if (m_pDownTextLayout->DrawString(pRenderDevice, mt, rtClip)) {
+ return;
+ }
+ } else if (m_pRolloverTextLayout && (dwState & FWL_STATE_PSB_Hovered)) {
+ if (m_pRolloverTextLayout->DrawString(pRenderDevice, mt, rtClip)) {
+ return;
+ }
+ }
+ }
+ if (pCapTextLayout) {
+ pCapTextLayout->DrawString(pRenderDevice, mt, rtClip);
+ }
+ }
+}
+FX_INT32 CXFA_FFPushButton::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFPushButton::OnProcessEvent(CFWL_Event *pEvent)
+{
+ m_pOldDelegate->OnProcessEvent(pEvent);
+ return CXFA_FFField::OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFPushButton::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteInverted) {
+ if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {
+ CFX_RectF rtFill;
+ m_pNormalWidget->GetWidgetRect(rtFill);
+ rtFill.left = rtFill.top = 0;
+ FX_FLOAT fLineWith = GetLineWidth();
+ rtFill.Deflate(fLineWith, fLineWith);
+ CFX_Color cr(FXARGB_MAKE(128, 128, 255, 255));
+ pGraphics->SetFillColor(&cr);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(rtFill.left, rtFill.top, rtFill.width, rtFill.height);
+ pGraphics->FillPath(&path, FXFILL_WINDING, (CFX_Matrix*)pMatrix);
+ }
+ } else if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HiliteOutLine) {
+ if ((m_pNormalWidget->GetStates() & FWL_STATE_PSB_Pressed) && (m_pNormalWidget->GetStates() & FWL_STATE_PSB_Hovered)) {
+ FX_FLOAT fLineWidth = GetLineWidth();
+ CFX_Color cr(FXARGB_MAKE(255, 128, 255, 255));
+ pGraphics->SetStrokeColor(&cr);
+ pGraphics->SetLineWidth(fLineWidth);
+ CFX_Path path;
+ path.Create();
+ CFX_RectF rect;
+ m_pNormalWidget->GetWidgetRect(rect);
+ path.AddRectangle(0, 0, rect.width, rect.height);
+ pGraphics->StrokePath(&path, (CFX_Matrix*)pMatrix);
+ }
+ } else if (m_pNormalWidget->GetStylesEx() & XFA_FWL_PSBSTYLEEXT_HilitePush) {
+ }
+ return FWL_ERR_Succeeded;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffpushbutton.h b/xfa/src/fxfa/src/app/xfa_ffpushbutton.h
new file mode 100644
index 0000000000..07503292f5
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffpushbutton.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_PUSHBUTTON_IMP_H
+#define _FXFA_FORMFILLER_PUSHBUTTON_IMP_H
+#define XFA_FWL_PSBSTYLEEXT_HiliteNone (0L << 0)
+#define XFA_FWL_PSBSTYLEEXT_HiliteInverted (1L << 0)
+#define XFA_FWL_PSBSTYLEEXT_HilitePush (2L << 0)
+#define XFA_FWL_PSBSTYLEEXT_HiliteOutLine (4L << 0)
+class CXFA_FFPushButton : public CXFA_FFField
+{
+public:
+ CXFA_FFPushButton(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFPushButton();
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+ virtual FX_BOOL LoadWidget();
+ virtual void UnloadWidget();
+ virtual FX_BOOL LayoutWidget();
+ virtual void UpdateWidgetProperty();
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+protected:
+ void LoadHighlightCaption();
+ void LayoutHighlightCaption();
+ void RenderHighlightCaption(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL);
+ FX_FLOAT GetLineWidth();
+ FX_ARGB GetLineColor();
+ FX_ARGB GetFillColor();
+ CXFA_TextLayout *m_pRolloverTextLayout;
+ CXFA_TextLayout *m_pDownTextLayout;
+ CXFA_TextProvider *m_pDownProvider;
+ CXFA_TextProvider *m_pRollProvider;
+ IFWL_WidgetDelegate *m_pOldDelegate;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffsignature.cpp b/xfa/src/fxfa/src/app/xfa_ffsignature.cpp
new file mode 100644
index 0000000000..42b75d60c6
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffsignature.cpp
@@ -0,0 +1,129 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffsignature.h"
+#include "xfa_ffdoc.h"
+CXFA_FFSignature::CXFA_FFSignature(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pPageView, pDataAcc)
+{
+}
+CXFA_FFSignature::~CXFA_FFSignature()
+{
+}
+FX_BOOL CXFA_FFSignature::LoadWidget()
+{
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFSignature::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ CXFA_Border borderUI = m_pDataAcc->GetUIBorder();
+ DrawBorder(pGS, borderUI, m_rtUI, &mtRotate);
+ RenderCaption(pGS, &mtRotate);
+ DrawHighlight(pGS, &mtRotate, dwStatus, FALSE);
+ CFX_RectF rtWidget = m_rtUI;
+ IXFA_DocProvider* pDocProvider = m_pDataAcc->GetDoc()->GetDocProvider();
+ FXSYS_assert(pDocProvider);
+ pDocProvider->RenderCustomWidget((XFA_HWIDGET)this, pGS, &mtRotate, rtWidget);
+}
+FX_BOOL CXFA_FFSignature::OnMouseEnter()
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnMouseExit()
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnMouseWheel(FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+
+FX_BOOL CXFA_FFSignature::OnSetFocus()
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnKillFocus()
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFSignature::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags)
+{
+ return FALSE;
+}
+FX_DWORD CXFA_FFSignature::OnHitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pNormalWidget) {
+ FX_FLOAT ffx = fx, ffy = fy;
+ FWLToClient(ffx, ffy);
+ FX_DWORD dwWidgetHit = m_pNormalWidget->HitTest(ffx, ffy);
+ if (dwWidgetHit != FWL_WGTHITTEST_Unknown) {
+ return FWL_WGTHITTEST_Client;
+ }
+ }
+ CFX_RectF rtBox;
+ GetRectWithoutRotate(rtBox);
+ if (!rtBox.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Unknown;
+ }
+ if (m_rtCaption.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Titlebar;
+ }
+ return FWL_WGTHITTEST_Client;
+}
+FX_BOOL CXFA_FFSignature::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffsignature.h b/xfa/src/fxfa/src/app/xfa_ffsignature.h
new file mode 100644
index 0000000000..f7848d8b32
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffsignature.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_SIGNATURE_IMP_H
+#define _FXFA_FORMFILLER_SIGNATURE_IMP_H
+class CXFA_FFSignature : public CXFA_FFField
+{
+public:
+ CXFA_FFSignature(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFSignature();
+
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+ virtual FX_BOOL LoadWidget();
+ virtual FX_BOOL OnMouseEnter();
+ virtual FX_BOOL OnMouseExit();
+ virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseWheel(FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+
+ virtual FX_BOOL OnSetFocus();
+ virtual FX_BOOL OnKillFocus();
+ virtual FX_BOOL OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnChar(FX_DWORD dwChar, FX_DWORD dwFlags);
+ virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnSetCursor(FX_FLOAT fx, FX_FLOAT fy);
+protected:
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffsubform.cpp b/xfa/src/fxfa/src/app/xfa_ffsubform.cpp
new file mode 100644
index 0000000000..c7bfbfbc54
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffsubform.cpp
@@ -0,0 +1,20 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffsubform.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+CXFA_FFSubForm::CXFA_FFSubForm(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFWidget(pPageView, pDataAcc)
+{
+}
+CXFA_FFSubForm::~CXFA_FFSubForm()
+{
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffsubform.h b/xfa/src/fxfa/src/app/xfa_ffsubform.h
new file mode 100644
index 0000000000..09deef4e31
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffsubform.h
@@ -0,0 +1,17 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_SUBFORM_IMP_H
+#define _FXFA_FORMFILLER_SUBFORM_IMP_H
+class CXFA_FFSubForm : public CXFA_FFWidget
+{
+public:
+ CXFA_FFSubForm(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFSubForm();
+
+protected:
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_fftext.cpp b/xfa/src/fxfa/src/app/xfa_fftext.cpp
new file mode 100644
index 0000000000..8b90a180cd
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fftext.cpp
@@ -0,0 +1,188 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffdraw.h"
+#include "xfa_fftext.h"
+#include "xfa_textlayout.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffapp.h"
+CXFA_FFText::CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFDraw(pPageView, pDataAcc)
+{
+}
+CXFA_FFText::~CXFA_FFText()
+{
+}
+void CXFA_FFText::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ {
+ CFX_Matrix mtRotate;
+ GetRotateMatrix(mtRotate);
+ if (pMatrix) {
+ mtRotate.Concat(*pMatrix);
+ }
+ CXFA_FFWidget::RenderWidget(pGS, &mtRotate, dwStatus);
+ CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+ if (pTextLayout) {
+ CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+ CFX_RectF rtText;
+ GetRectWithoutRotate(rtText);
+ if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+ CXFA_LayoutItem* pItem = this->GetLayoutItem();
+ if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+ XFA_RectWidthoutMargin(rtText, mgWidget);
+ } else {
+ FX_FLOAT fLeftInset, fRightInset, fTopInset = 0, fBottomInset = 0;
+ mgWidget.GetLeftInset(fLeftInset);
+ mgWidget.GetRightInset(fRightInset);
+ if (pItem->GetPrev() == NULL) {
+ mgWidget.GetTopInset(fTopInset);
+ } else if (pItem->GetNext() == NULL) {
+ mgWidget.GetBottomInset(fBottomInset);
+ }
+ rtText.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
+ }
+ }
+ CFX_Matrix mt;
+ mt.Set(1, 0, 0, 1, rtText.left, rtText.top);
+ CFX_RectF rtClip = rtText;
+ mtRotate.TransformRect(rtClip);
+ mt.Concat(mtRotate);
+ pTextLayout->DrawString(pRenderDevice, mt, rtClip, this->GetLayoutItem()->GetIndex());
+ }
+ }
+}
+FX_BOOL CXFA_FFText::IsLoaded()
+{
+ CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+ return pTextLayout != NULL && !pTextLayout->m_bHasBlock;
+}
+FX_BOOL CXFA_FFText::LayoutWidget()
+{
+ CXFA_FFDraw::LayoutWidget();
+ CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+ if (!pTextLayout) {
+ return FALSE;
+ }
+ if (!pTextLayout->m_bHasBlock) {
+ return TRUE;
+ }
+ pTextLayout->m_Blocks.RemoveAll();
+ CXFA_LayoutItem* pItem = this->GetLayoutItem();
+ if (pItem->GetPrev() == NULL && pItem->GetNext() == NULL) {
+ return TRUE;
+ }
+ pItem = pItem->GetFirst();
+ while (pItem) {
+ CFX_RectF rtText;
+ pItem->GetRect(rtText);
+ if (CXFA_Margin mgWidget = m_pDataAcc->GetMargin()) {
+ if (pItem->GetPrev() == NULL) {
+ FX_FLOAT fTopInset;
+ mgWidget.GetTopInset(fTopInset);
+ rtText.height -= fTopInset;
+ } else if (pItem->GetNext() == NULL) {
+ FX_FLOAT fBottomInset;
+ mgWidget.GetBottomInset(fBottomInset);
+ rtText.height -= fBottomInset;
+ }
+ }
+ pTextLayout->ItemBlocks(rtText, pItem->GetIndex());
+ pItem = pItem->GetNext();
+ }
+ pTextLayout->m_bHasBlock = FALSE;
+ return TRUE;
+}
+FX_BOOL CXFA_FFText::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rtBox;
+ GetRectWithoutRotate(rtBox);
+ if (!rtBox.Contains(fx, fy)) {
+ return FALSE;
+ }
+ FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);
+ if (NULL == wsURLContent) {
+ return FALSE;
+ }
+ SetButtonDown(TRUE);
+ return TRUE;
+}
+FX_BOOL CXFA_FFText::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rtBox;
+ GetRectWithoutRotate(rtBox);
+ if (!rtBox.Contains(fx, fy)) {
+ return FALSE;
+ }
+ FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);
+ if (NULL == wsURLContent) {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_FFText::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!IsButtonDown()) {
+ return FALSE;
+ }
+ SetButtonDown(FALSE);
+ FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);
+ if (NULL == wsURLContent) {
+ return FALSE;
+ }
+ CXFA_FFDoc* pDoc = GetDoc();
+ pDoc->GetDocProvider()->GotoURL((XFA_HDOC)pDoc, FX_WSTRC(wsURLContent), FALSE);
+ return TRUE;
+}
+FX_DWORD CXFA_FFText::OnHitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rtBox;
+ GetRectWithoutRotate(rtBox);
+ if (!rtBox.Contains(fx, fy)) {
+ return FWL_WGTHITTEST_Unknown;
+ }
+ FX_LPCWSTR wsURLContent = GetLinkURLAtPoint(fx, fy);
+ if (NULL == wsURLContent) {
+ return FWL_WGTHITTEST_Unknown;
+ }
+ return FWL_WGTHITTEST_Transparent;
+}
+FX_LPCWSTR CXFA_FFText::GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy)
+{
+ CXFA_TextLayout* pTextLayout = m_pDataAcc->GetTextLayout();
+ if ( NULL == pTextLayout) {
+ return NULL;
+ }
+ FX_FLOAT x(fx), y(fy);
+ FWLToClient(x, y);
+ const CXFA_PieceLineArray* pPieceLines = pTextLayout->GetPieceLines();
+ FX_INT32 iCount = pPieceLines->GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXFA_PieceLine *pPieceLine = pPieceLines->GetAt(i);
+ FX_INT32 iPieces = pPieceLine->m_textPieces.GetSize();
+ for (FX_INT32 j = 0; j < iPieces; j++) {
+ XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j);
+ if (pPiece->pLinkData && pPiece->rtPiece.Contains(x, y)) {
+ return pPiece->pLinkData->GetLinkURL();
+ }
+ }
+ }
+ return NULL;
+}
+void CXFA_FFText::FWLToClient(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ CFX_RectF rtWidget;
+ GetRectWithoutRotate(rtWidget);
+ fx -= rtWidget.left;
+ fy -= rtWidget.top;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_fftext.h b/xfa/src/fxfa/src/app/xfa_fftext.h
new file mode 100644
index 0000000000..d686a97f4c
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fftext.h
@@ -0,0 +1,26 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_DRAWTEXT_IMP_H
+#define _FXFA_FORMFILLER_DRAWTEXT_IMP_H
+class CXFA_TextLayout;
+class CXFA_FFText : public CXFA_FFDraw
+{
+public:
+ CXFA_FFText(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFText();
+ virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+ virtual FX_BOOL IsLoaded();
+ virtual FX_BOOL LayoutWidget();
+private:
+ virtual FX_LPCWSTR GetLinkURLAtPoint(FX_FLOAT fx, FX_FLOAT fy);
+ void FWLToClient(FX_FLOAT &fx, FX_FLOAT &fy);
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_fftextedit.cpp b/xfa/src/fxfa/src/app/xfa_fftextedit.cpp
new file mode 100644
index 0000000000..a046f25611
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fftextedit.cpp
@@ -0,0 +1,830 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffpageview.h"
+#include "xfa_fftextedit.h"
+#include "xfa_textlayout.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffdoc.h"
+CXFA_FFTextEdit::CXFA_FFTextEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFField(pPageView, pDataAcc)
+ , m_pOldDelegate(NULL)
+{
+}
+CXFA_FFTextEdit::~CXFA_FFTextEdit()
+{
+ if (m_pNormalWidget) {
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->UnregisterEventTarget(pWidget);
+ }
+}
+FX_BOOL CXFA_FFTextEdit::LoadWidget()
+{
+ CFWL_Edit* pFWLEdit = CFWL_Edit::Create();
+ pFWLEdit->Initialize();
+ m_pNormalWidget = pFWLEdit;
+ IFWL_Widget* pWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pWidget, pWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ m_pNormalWidget->LockUpdate();
+ UpdateWidgetProperty();
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+ pFWLEdit->SetText(wsText);
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFTextEdit::UpdateWidgetProperty()
+{
+ CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
+ if (!pWidget) {
+ return;
+ }
+ FX_DWORD dwStyle = 0;
+ FX_DWORD dwExtendedStyle = FWL_STYLEEXT_EDT_ShowScrollbarFocus | FWL_STYLEEXT_EDT_OuterScrollbar | FWL_STYLEEXT_EDT_LastLineHeight;
+ dwExtendedStyle |= UpdateUIProperty();
+ if (m_pDataAcc->IsMultiLine()) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine | FWL_STYLEEXT_EDT_WantReturn;
+ if (m_pDataAcc->GetVerticalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+ dwStyle |= FWL_WGTSTYLE_VScroll;
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoVScroll;
+ }
+ } else if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_MultiLine;
+ }
+ XFA_ELEMENT eType = XFA_ELEMENT_UNKNOWN;
+ FX_INT32 iMaxChars = m_pDataAcc->GetMaxChars(eType);
+ if (eType == XFA_ELEMENT_ExData) {
+ iMaxChars = 0;
+ }
+ FX_INT32 iNumCells = m_pDataAcc->GetNumberOfCells();
+ if (iNumCells == 0) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
+ pWidget->SetLimit(iMaxChars > 0 ? iMaxChars : 1);
+ } else if (iNumCells > 0) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
+ pWidget->SetLimit(iNumCells);
+ } else {
+ pWidget->SetLimit(iMaxChars);
+ }
+ dwExtendedStyle |= GetAlignment();
+ m_pNormalWidget->ModifyStyles(dwStyle, 0xFFFFFFFF);
+ m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+}
+FX_BOOL CXFA_FFTextEdit::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!PtInActiveRect(fx, fy)) {
+ return FALSE;
+ }
+ if (!IsFocused()) {
+ m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+ UpdateFWLData();
+ AddInvalidateRect();
+ }
+ SetButtonDown(TRUE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_LButtonDown;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+ return FALSE;
+ }
+ if (!PtInActiveRect(fx, fy)) {
+ return FALSE;
+ }
+ if (!IsFocused()) {
+ m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+ UpdateFWLData();
+ AddInvalidateRect();
+ }
+ SetButtonDown(TRUE);
+ CFWL_MsgMouse ms;
+ ms.m_dwCmd = FWL_MSGMOUSECMD_RButtonDown;
+ ms.m_dwFlags = dwFlags;
+ ms.m_fx = fx;
+ ms.m_fy = fy;
+ FWLToClient(ms.m_fx, ms.m_fy);
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!CXFA_FFField::OnRButtonUp(dwFlags, fx, fy)) {
+ return FALSE;
+ }
+ CFX_PointF pt;
+ pt.Set(fx, fy);
+ GetDoc()->GetDocProvider()->PopupMenu((XFA_HWIDGET)this, pt, NULL);
+ return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnSetFocus(CXFA_FFWidget* pOldWidget)
+{
+ m_dwStatus &= ~XFA_WIDGETSTATUS_TextEditValueChanged;
+ if (!IsFocused()) {
+ m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+ UpdateFWLData();
+ AddInvalidateRect();
+ }
+ CXFA_FFWidget::OnSetFocus(pOldWidget);
+ CFWL_MsgSetFocus ms;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::OnKillFocus(CXFA_FFWidget* pNewWidget)
+{
+ CFWL_MsgKillFocus ms;
+ ms.m_pDstTarget = m_pNormalWidget->m_pImp;
+ ms.m_pSrcTarget = NULL;
+ TranslateFWLMessage(&ms);
+ m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
+ SetEditScrollOffset();
+ ProcessCommittedData();
+ UpdateFWLData();
+ AddInvalidateRect();
+ CXFA_FFWidget::OnKillFocus(pNewWidget);
+ m_dwStatus &= ~XFA_WIDGETSTATUS_TextEditValueChanged;
+ return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::CommitData()
+{
+ CFX_WideString wsText;
+ ((CFWL_Edit*)m_pNormalWidget)->GetText(wsText);
+ if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
+ m_pDataAcc->UpdateUIDisplay(this);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_FFTextEdit::IsDataChanged()
+{
+ return (m_dwStatus & XFA_WIDGETSTATUS_TextEditValueChanged) != 0;
+}
+FX_DWORD CXFA_FFTextEdit::GetAlignment()
+{
+ FX_DWORD dwExtendedStyle = 0;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ FX_INT32 iHorz = para.GetHorizontalAlign();
+ switch(iHorz) {
+ case XFA_ATTRIBUTEENUM_Center:
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_HCenter;
+ break;
+ case XFA_ATTRIBUTEENUM_Justify:
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_Justified;
+ break;
+ case XFA_ATTRIBUTEENUM_JustifyAll:
+ break;
+ case XFA_ATTRIBUTEENUM_Radix:
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_HFar;
+ break;
+ default:
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_HNear;
+ break;
+ }
+ FX_INT32 iVert = para.GetVerticalAlign();
+ switch(iVert) {
+ case XFA_ATTRIBUTEENUM_Middle:
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_VCenter;
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom:
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_VFar;
+ break;
+ default:
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_VNear;
+ break;
+ }
+ }
+ return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFTextEdit::UpdateFWLData()
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
+ if (IsFocused()) {
+ eType = XFA_VALUEPICTURE_Edit;
+ }
+ FX_BOOL bUpdate = FALSE;
+ if (m_pDataAcc->GetUIType() == XFA_ELEMENT_TextEdit && m_pDataAcc->GetNumberOfCells() < 0) {
+ XFA_ELEMENT elementType = XFA_ELEMENT_UNKNOWN;
+ FX_INT32 iMaxChars = m_pDataAcc->GetMaxChars(elementType);
+ if (elementType == XFA_ELEMENT_ExData) {
+ iMaxChars = eType == XFA_VALUEPICTURE_Edit ? iMaxChars : 0;
+ }
+ if (((CFWL_Edit*)m_pNormalWidget)->GetLimit() != iMaxChars) {
+ ((CFWL_Edit*)m_pNormalWidget)->SetLimit(iMaxChars);
+ bUpdate = TRUE;
+ }
+ }
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, eType);
+ CFX_WideString wsOldText;
+ ((CFWL_Edit*)m_pNormalWidget)->GetText(wsOldText);
+ if (wsText != wsOldText || (eType == XFA_VALUEPICTURE_Edit && bUpdate)) {
+ ((CFWL_Edit*)m_pNormalWidget)->SetText(wsText);
+ bUpdate = TRUE;
+ }
+ if (bUpdate) {
+ m_pNormalWidget->Update();
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_FFTextEdit::CanUndo()
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->CanUndo();
+}
+FX_BOOL CXFA_FFTextEdit::CanRedo()
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->CanRedo();
+}
+FX_BOOL CXFA_FFTextEdit::Undo()
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->Undo();
+}
+FX_BOOL CXFA_FFTextEdit::Redo()
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->Redo();
+}
+FX_BOOL CXFA_FFTextEdit::CanCopy()
+{
+ FX_INT32 nCount = ((CFWL_Edit*)m_pNormalWidget)->CountSelRanges();
+ return nCount > 0;
+}
+FX_BOOL CXFA_FFTextEdit::CanCut()
+{
+ if (m_pNormalWidget->GetStylesEx() & FWL_STYLEEXT_EDT_ReadOnly) {
+ return FALSE;
+ }
+ FX_INT32 nCount = ((CFWL_Edit*)m_pNormalWidget)->CountSelRanges();
+ return nCount > 0;
+}
+FX_BOOL CXFA_FFTextEdit::CanPaste()
+{
+ return m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open;
+}
+FX_BOOL CXFA_FFTextEdit::CanSelectAll()
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->GetTextLength() > 0;
+}
+FX_BOOL CXFA_FFTextEdit::Copy(CFX_WideString &wsCopy)
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->Copy(wsCopy);
+}
+FX_BOOL CXFA_FFTextEdit::Cut(CFX_WideString &wsCut)
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->Cut(wsCut);
+}
+FX_BOOL CXFA_FFTextEdit::Paste(const CFX_WideString &wsPaste)
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->Paste(wsPaste);
+}
+FX_BOOL CXFA_FFTextEdit::SelectAll()
+{
+ FX_INT32 nCount = ((CFWL_Edit*)m_pNormalWidget)->GetTextLength();
+ return ((CFWL_Edit*)m_pNormalWidget)->AddSelRange(0, nCount);
+}
+FX_BOOL CXFA_FFTextEdit::Delete()
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->Delete();
+}
+FX_BOOL CXFA_FFTextEdit::DeSelect()
+{
+ return ((CFWL_Edit*)m_pNormalWidget)->ClearSelections();
+}
+FX_BOOL CXFA_FFTextEdit::GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest)
+{
+ if (m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+ return FALSE;
+ }
+ FWLToClient(pointf.x, pointf.y);
+ return ((CFWL_Edit*)m_pNormalWidget)->GetSuggestWords(pointf, sSuggest);
+}
+FX_BOOL CXFA_FFTextEdit::ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace)
+{
+ if (m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+ return FALSE;
+ }
+ FWLToClient(pointf.x, pointf.y);
+ return ((CFWL_Edit*)m_pNormalWidget)->ReplaceSpellCheckWord(pointf, bsReplace);
+}
+void CXFA_FFTextEdit::OnTextChanged(IFWL_Widget *pWidget, const CFX_WideString &wsChanged, const CFX_WideString &wsPrevText)
+{
+ m_dwStatus |= XFA_WIDGETSTATUS_TextEditValueChanged;
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Change;
+ eParam.m_wsChange = wsChanged;
+ eParam.m_pTarget = m_pDataAcc;
+ eParam.m_wsPrevText = wsPrevText;
+ CFWL_Edit* pEdit = ((CFWL_Edit*)m_pNormalWidget);
+ if (m_pDataAcc->GetUIType() == XFA_ELEMENT_DateTimeEdit) {
+ CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)pEdit;
+ pDateTime->GetEditText(eParam.m_wsNewText);
+ FX_INT32 iSels = pDateTime->CountSelRanges();
+ if (iSels ) {
+ eParam.m_iSelEnd = pDateTime->GetSelRange(0, eParam.m_iSelStart);
+ }
+ } else {
+ pEdit->GetText(eParam.m_wsNewText);
+ FX_INT32 iSels = pEdit->CountSelRanges();
+ if (iSels ) {
+ eParam.m_iSelEnd = pEdit->GetSelRange(0, eParam.m_iSelStart);
+ }
+ }
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+}
+void CXFA_FFTextEdit::OnTextFull(IFWL_Widget *pWidget)
+{
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Full;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Full, &eParam);
+}
+void CXFA_FFTextEdit::OnAddDoRecord(IFWL_Widget *pWidget)
+{
+ GetDoc()->GetDocProvider()->AddDoRecord((XFA_HWIDGET)this);
+}
+FX_BOOL CXFA_FFTextEdit::CheckWord(FX_BSTR sWord)
+{
+ if (sWord.IsEmpty() || m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+ return TRUE;
+ }
+ return GetDoc()->GetDocProvider()->CheckWord((XFA_HDOC)GetDoc(), sWord);
+}
+FX_BOOL CXFA_FFTextEdit::GetSuggestWords(FX_BSTR sWord, CFX_ByteStringArray &sSuggest)
+{
+ if (m_pDataAcc->GetUIType() != XFA_ELEMENT_TextEdit) {
+ return FALSE;
+ }
+ return GetDoc()->GetDocProvider()->GetSuggestWords((XFA_HDOC)GetDoc(), sWord, sSuggest);
+}
+FX_INT32 CXFA_FFTextEdit::OnProcessMessage(CFWL_Message *pMessage)
+{
+ return m_pOldDelegate->OnProcessMessage(pMessage);
+}
+FWL_ERR CXFA_FFTextEdit::OnProcessEvent(CFWL_Event *pEvent)
+{
+ CXFA_FFField::OnProcessEvent(pEvent);
+ FX_DWORD dwEventID = pEvent->GetClassID();
+ switch (dwEventID) {
+ case FWL_EVTHASH_EDT_TextChanged: {
+ CFWL_EvtEdtTextChanged *event = (CFWL_EvtEdtTextChanged*)pEvent;
+ CFX_WideString wsChange;
+ OnTextChanged(m_pNormalWidget->GetWidget(), wsChange, event->wsPrevText);
+ break;
+ }
+ case FWL_EVTHASH_EDT_AddDoRecord: {
+ OnAddDoRecord(m_pNormalWidget->GetWidget());
+ break;
+ }
+ case FWL_EVTHASH_EDT_TextFull: {
+ OnTextFull(m_pNormalWidget->GetWidget());
+ break;
+ }
+ case FWL_EVTHASH_EDT_CheckWord: {
+ CFX_WideString wstr(L"FWL_EVENT_DTP_SelectChanged");
+ FX_DWORD hashcode = FX_HashCode_String_GetW(wstr, wstr.GetLength());
+ CFWL_EvtEdtCheckWord *event = (CFWL_EvtEdtCheckWord*)pEvent;
+ event->bCheckWord = CheckWord(event->bsWord);
+ break;
+ }
+ case FWL_EVTHASH_EDT_GetSuggestWords: {
+ CFWL_EvtEdtGetSuggestWords *event = (CFWL_EvtEdtGetSuggestWords*)pEvent;
+ event->bSuggestWords = GetSuggestWords(event->bsWord, event->bsArraySuggestWords);
+ break;
+ }
+ default: {
+ }
+ }
+ return m_pOldDelegate->OnProcessEvent(pEvent);
+}
+FWL_ERR CXFA_FFTextEdit::OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix )
+{
+ return m_pOldDelegate->OnDrawWidget(pGraphics, pMatrix);
+}
+CXFA_FFNumericEdit::CXFA_FFNumericEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFTextEdit(pPageView, pDataAcc)
+{
+}
+CXFA_FFNumericEdit::~CXFA_FFNumericEdit()
+{
+}
+FX_BOOL CXFA_FFNumericEdit::LoadWidget()
+{
+ CFWL_Edit* pWidget = CFWL_Edit::Create();
+ pWidget->Initialize();
+ m_pNormalWidget = (CFWL_Widget*)pWidget;
+ IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pIWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ m_pNormalWidget->LockUpdate();
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+ pWidget->SetText(wsText);
+ UpdateWidgetProperty();
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFNumericEdit::UpdateWidgetProperty()
+{
+ CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
+ if (!pWidget) {
+ return;
+ }
+ FX_DWORD dwExtendedStyle = FWL_STYLEEXT_EDT_ShowScrollbarFocus |
+ FWL_STYLEEXT_EDT_OuterScrollbar | FWL_STYLEEXT_EDT_Validate | FWL_STYLEEXT_EDT_Number | FWL_STYLEEXT_EDT_LastLineHeight;
+ dwExtendedStyle |= UpdateUIProperty();
+ if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
+ }
+ FX_INT32 iNumCells = m_pDataAcc->GetNumberOfCells();
+ if (iNumCells > 0) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_CombText;
+ pWidget->SetLimit(iNumCells);
+ }
+ dwExtendedStyle |= GetAlignment();
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
+ }
+ m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+}
+FWL_ERR CXFA_FFNumericEdit::OnProcessEvent(CFWL_Event *pEvent)
+{
+ FX_DWORD dwEventID = pEvent->GetClassID();
+ if (dwEventID == FWL_EVTHASH_EDT_Validate) {
+ CFWL_EvtEdtValidate *event = (CFWL_EvtEdtValidate*)pEvent;
+ CFX_WideString wsChange = event->wsInsert;
+ event->bValidate = OnValidate(m_pNormalWidget->GetWidget(), wsChange);
+ return event->bValidate;
+ } else {
+ return CXFA_FFTextEdit::OnProcessEvent(pEvent);
+ }
+}
+FX_BOOL CXFA_FFNumericEdit::OnValidate(IFWL_Widget *pWidget, CFX_WideString &wsText)
+{
+ CFX_WideString wsPattern;
+ m_pDataAcc->GetPictureContent(wsPattern, XFA_VALUEPICTURE_Edit);
+ if (!wsPattern.IsEmpty()) {
+ return TRUE;
+ }
+ FX_INT32 iLeads = 0;
+ m_pDataAcc->GetLeadDigits(iLeads);
+ FX_INT32 iFracs = 0;
+ m_pDataAcc->GetFracDigits(iFracs);
+ CFX_WideString wsFormat;
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(m_pDataAcc);
+ widgetValue.GetNumbericFormat(wsFormat, iLeads, iFracs);
+ return widgetValue.ValidateNumericTemp(wsText, wsFormat, m_pDataAcc->GetLocal());
+}
+CXFA_FFPasswordEdit::CXFA_FFPasswordEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFTextEdit(pPageView, pDataAcc)
+{
+}
+CXFA_FFPasswordEdit::~CXFA_FFPasswordEdit()
+{
+}
+FX_BOOL CXFA_FFPasswordEdit::LoadWidget()
+{
+ CFWL_Edit* pWidget = CFWL_Edit::Create();
+ pWidget->Initialize();
+ m_pNormalWidget = (CFWL_Widget*)pWidget;
+ IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pIWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ m_pNormalWidget->LockUpdate();
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+ pWidget->SetText(wsText);
+ UpdateWidgetProperty();
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFPasswordEdit::UpdateWidgetProperty()
+{
+ CFWL_Edit* pWidget = (CFWL_Edit*)m_pNormalWidget;
+ if (!pWidget) {
+ return;
+ }
+ FX_DWORD dwExtendedStyle = FWL_STYLEEXT_EDT_ShowScrollbarFocus |
+ FWL_STYLEEXT_EDT_OuterScrollbar | FWL_STYLEEXT_EDT_Password | FWL_STYLEEXT_EDT_LastLineHeight;
+ dwExtendedStyle |= UpdateUIProperty();
+ CFX_WideString wsPassWord;
+ m_pDataAcc->GetPasswordChar(wsPassWord);
+ if (!wsPassWord.IsEmpty()) {
+ pWidget->SetAliasChar(wsPassWord.GetAt(0));
+ }
+ if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_AutoHScroll;
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ dwExtendedStyle |= FWL_STYLEEXT_EDT_ReadOnly;
+ }
+ dwExtendedStyle |= GetAlignment();
+ m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+}
+CXFA_FFDateTimeEdit::CXFA_FFDateTimeEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_FFTextEdit(pPageView, pDataAcc)
+{
+}
+CXFA_FFDateTimeEdit::~CXFA_FFDateTimeEdit()
+{
+}
+FX_BOOL CXFA_FFDateTimeEdit::GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus)
+{
+ if (bDrawFocus) {
+ return FALSE;
+ }
+#ifndef _XFA_EMB
+ return CXFA_FFWidget::GetBBox(rtBox, dwStatus);
+#endif
+ GetRectWithoutRotate(rtBox);
+ if (m_pNormalWidget) {
+ CFX_RectF rtWidget;
+ ((CFWL_DateTimePicker*)m_pNormalWidget)->GetBBox(rtWidget);
+ rtBox.Union(rtWidget);
+ }
+ CFX_Matrix mt;
+ GetRotateMatrix(mt);
+ mt.TransformRect(rtBox);
+ return TRUE;
+}
+FX_BOOL CXFA_FFDateTimeEdit::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ CFX_RectF rtWidget;
+ ((CFWL_DateTimePicker*)m_pNormalWidget)->GetBBox(rtWidget);
+ if (rtWidget.Contains(fx, fy)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_FFDateTimeEdit::LoadWidget()
+{
+ CFWL_DateTimePicker *pWidget = CFWL_DateTimePicker::Create();
+ pWidget->Initialize();
+ m_pNormalWidget = (CFWL_Widget*)pWidget;
+ IFWL_Widget* pIWidget = m_pNormalWidget->GetWidget();
+ m_pNormalWidget->SetPrivateData(pIWidget, this, NULL);
+ IFWL_NoteDriver *pNoteDriver = FWL_GetApp()->GetNoteDriver();
+ pNoteDriver->RegisterEventTarget(pIWidget, pIWidget);
+ m_pOldDelegate = m_pNormalWidget->SetDelegate(this);
+ m_pNormalWidget->LockUpdate();
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, XFA_VALUEPICTURE_Display);
+ pWidget->SetEditText(wsText);
+ XFA_DATETIMETYPE eType = XFA_DATETIMETYPE_DateAndTime;
+ if (CXFA_Value value = m_pDataAcc->GetFormValue()) {
+ switch(value.GetChildValueClassID()) {
+ case XFA_ELEMENT_Date: {
+ eType = XFA_DATETIMETYPE_Date;
+ if (!wsText.IsEmpty()) {
+ CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
+ CFX_Unitime date = lcValue.GetDate();
+ if ((FX_UNITIME)date != 0) {
+ pWidget->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
+ }
+ }
+ }
+ break;
+ case XFA_ELEMENT_Time:
+ eType = XFA_DATETIMETYPE_Time;
+ break;
+ default:
+ eType = XFA_DATETIMETYPE_DateAndTime;
+ break;
+ }
+ }
+ UpdateWidgetProperty();
+ m_pNormalWidget->UnlockUpdate();
+ return CXFA_FFField::LoadWidget();
+}
+void CXFA_FFDateTimeEdit::UpdateWidgetProperty()
+{
+ CFWL_DateTimePicker* pWidget = (CFWL_DateTimePicker*)m_pNormalWidget;
+ if (!pWidget) {
+ return;
+ }
+ FX_DWORD dwExtendedStyle = FWL_STYLEEXT_DTP_ShortDateFormat;
+ dwExtendedStyle |= UpdateUIProperty();
+ dwExtendedStyle |= GetAlignment();
+ m_pNormalWidget->ModifyStylesEx(dwExtendedStyle, 0xFFFFFFFF);
+ FX_DWORD dwEditStyles = FWL_STYLEEXT_EDT_LastLineHeight;
+ FX_INT32 iNumCells = m_pDataAcc->GetNumberOfCells();
+ if (iNumCells > 0) {
+ dwEditStyles |= FWL_STYLEEXT_EDT_CombText;
+ pWidget->SetEditLimit(iNumCells);
+ }
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open || !m_pDataAcc->GetDoc()->GetXFADoc()->IsInteractive()) {
+ dwEditStyles |= FWL_STYLEEXT_EDT_ReadOnly;
+ }
+ if (m_pDataAcc->GetHorizontalScrollPolicy() != XFA_ATTRIBUTEENUM_Off) {
+ dwEditStyles |= FWL_STYLEEXT_EDT_AutoHScroll;
+ }
+ pWidget->ModifyEditStylesEx(dwEditStyles, 0xFFFFFFFF);
+}
+FX_DWORD CXFA_FFDateTimeEdit::GetAlignment()
+{
+ FX_DWORD dwExtendedStyle = 0;
+ if (CXFA_Para para = m_pDataAcc->GetPara()) {
+ FX_INT32 iHorz = para.GetHorizontalAlign();
+ switch(iHorz) {
+ case XFA_ATTRIBUTEENUM_Center:
+ dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHCenter;
+ break;
+ case XFA_ATTRIBUTEENUM_Justify:
+ dwExtendedStyle |= FWL_STYLEEXT_DTP_EditJustified;
+ break;
+ case XFA_ATTRIBUTEENUM_JustifyAll:
+ break;
+ case XFA_ATTRIBUTEENUM_Radix:
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHFar;
+ break;
+ default:
+ dwExtendedStyle |= FWL_STYLEEXT_DTP_EditHNear;
+ break;
+ }
+ FX_INT32 iVert = para.GetVerticalAlign();
+ switch(iVert) {
+ case XFA_ATTRIBUTEENUM_Middle:
+ dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVCenter;
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom:
+ dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVFar;
+ break;
+ default:
+ dwExtendedStyle |= FWL_STYLEEXT_DTP_EditVNear;
+ break;
+ }
+ }
+ return dwExtendedStyle;
+}
+FX_BOOL CXFA_FFDateTimeEdit::CommitData()
+{
+ CFX_WideString wsText;
+ ((CFWL_DateTimePicker*)m_pNormalWidget)->GetEditText(wsText);
+ if (m_pDataAcc->SetValue(wsText, XFA_VALUEPICTURE_Edit)) {
+ m_pDataAcc->UpdateUIDisplay(this);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_FFDateTimeEdit::UpdateFWLData()
+{
+ if (!m_pNormalWidget) {
+ return FALSE;
+ }
+ XFA_VALUEPICTURE eType = XFA_VALUEPICTURE_Display;
+ if (IsFocused()) {
+ eType = XFA_VALUEPICTURE_Edit;
+ }
+ CFX_WideString wsText;
+ m_pDataAcc->GetValue(wsText, eType);
+ ((CFWL_DateTimePicker*)m_pNormalWidget)->SetEditText(wsText);
+ if (IsFocused() && !wsText.IsEmpty()) {
+ CXFA_LocaleValue lcValue = XFA_GetLocaleValue(m_pDataAcc);
+ CFX_Unitime date = lcValue.GetDate();
+ if (lcValue.IsValid()) {
+ if ((FX_UNITIME)date != 0) {
+ ((CFWL_DateTimePicker*)m_pNormalWidget)->SetCurSel(date.GetYear(), date.GetMonth(), date.GetDay());
+ }
+ }
+ }
+ m_pNormalWidget->Update();
+ return TRUE;
+}
+FX_BOOL CXFA_FFDateTimeEdit::IsDataChanged()
+{
+ if (m_dwStatus & XFA_WIDGETSTATUS_TextEditValueChanged) {
+ return TRUE;
+ }
+ CFX_WideString wsText;
+ ((CFWL_DateTimePicker*)m_pNormalWidget)->GetEditText(wsText);
+ CFX_WideString wsOldValue;
+ m_pDataAcc->GetValue(wsOldValue, XFA_VALUEPICTURE_Edit);
+ return wsOldValue != wsText;
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanUndo()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanUndo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanRedo()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanRedo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Undo()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->Undo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Redo()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->Redo();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanCopy()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanCopy();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanCut()
+{
+ if (m_pDataAcc->GetAccess() != XFA_ATTRIBUTEENUM_Open) {
+ return FALSE;
+ }
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanCut();
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanPaste()
+{
+ return m_pDataAcc->GetAccess() == XFA_ATTRIBUTEENUM_Open;
+}
+FX_BOOL CXFA_FFDateTimeEdit::CanSelectAll()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->CanSelectAll();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Copy(CFX_WideString &wsCopy)
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->Copy(wsCopy);
+}
+FX_BOOL CXFA_FFDateTimeEdit::Cut(CFX_WideString &wsCut)
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->Cut(wsCut);
+}
+FX_BOOL CXFA_FFDateTimeEdit::Paste(const CFX_WideString &wsPaste)
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->Paste(wsPaste);
+}
+FX_BOOL CXFA_FFDateTimeEdit::SelectAll()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->SelectAll();
+}
+FX_BOOL CXFA_FFDateTimeEdit::Delete()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->Delete();
+}
+FX_BOOL CXFA_FFDateTimeEdit::DeSelect()
+{
+ return ((CFWL_DateTimePicker*)m_pNormalWidget)->DeSelect();
+}
+void CXFA_FFDateTimeEdit::OnSelectChanged(IFWL_Widget *pWidget, FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay)
+{
+ CFX_WideString wsPicture;
+ m_pDataAcc->GetPictureContent(wsPicture, XFA_VALUEPICTURE_Edit);
+ CXFA_LocaleValue date(XFA_VT_DATE, this->GetDoc()->GetXFADoc()->GetLocalMgr());
+ CFX_Unitime dt;
+ dt.Set(iYear, iMonth, iDay);
+ date.SetDate(dt);
+ CFX_WideString wsDate;
+ date.FormatPatterns(wsDate, wsPicture, m_pDataAcc->GetLocal(), XFA_VALUEPICTURE_Edit);
+ CFWL_DateTimePicker* pDateTime = (CFWL_DateTimePicker*)m_pNormalWidget;
+ pDateTime->SetEditText(wsDate);
+ pDateTime->Update();
+ GetDoc()->GetDocProvider()->SetFocusWidget((XFA_HDOC)GetDoc(), NULL);
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Change;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->GetValue(eParam.m_wsNewText, XFA_VALUEPICTURE_Raw);
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Change, &eParam);
+}
+FWL_ERR CXFA_FFDateTimeEdit::OnProcessEvent(CFWL_Event *pEvent)
+{
+ FX_DWORD dwEventID = pEvent->GetClassID();
+ if (dwEventID == FWL_EVTHASH_DTP_SelectChanged) {
+ CFWL_Event_DtpSelectChanged *event = (CFWL_Event_DtpSelectChanged*)pEvent;
+ OnSelectChanged(m_pNormalWidget->GetWidget(), event->iYear, event->iMonth, event->iDay);
+ return TRUE;
+ } else {
+ return CXFA_FFTextEdit::OnProcessEvent(pEvent);
+ }
+}
diff --git a/xfa/src/fxfa/src/app/xfa_fftextedit.h b/xfa/src/fxfa/src/app/xfa_fftextedit.h
new file mode 100644
index 0000000000..a6c2b507c9
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fftextedit.h
@@ -0,0 +1,116 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_TEXTEDIT_IMP_H
+#define _FXFA_FORMFILLER_TEXTEDIT_IMP_H
+class CXFA_FFTextEdit : public CXFA_FFField
+{
+public:
+ CXFA_FFTextEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFTextEdit();
+ virtual FX_BOOL LoadWidget();
+ virtual void UpdateWidgetProperty();
+ virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnSetFocus(CXFA_FFWidget* pOldWidget);
+ virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+ virtual FX_BOOL CanUndo();
+ virtual FX_BOOL CanRedo();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+ virtual FX_BOOL CanCopy();
+ virtual FX_BOOL CanCut();
+ virtual FX_BOOL CanPaste();
+ virtual FX_BOOL CanSelectAll();
+ virtual FX_BOOL Copy(CFX_WideString &wsCopy);
+ virtual FX_BOOL Cut(CFX_WideString &wsCut);
+ virtual FX_BOOL Paste(const CFX_WideString &wsPaste);
+ virtual FX_BOOL SelectAll();
+ virtual FX_BOOL Delete();
+ virtual FX_BOOL DeSelect();
+ FX_BOOL GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest);
+ FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace);
+protected:
+ FX_DWORD GetAlignment();
+ virtual FX_BOOL CommitData();
+ virtual FX_BOOL UpdateFWLData();
+ virtual FX_BOOL IsDataChanged();
+ IFWL_WidgetDelegate* m_pOldDelegate;
+public:
+ void OnTextChanged(IFWL_Widget *pWidget, const CFX_WideString &wsChanged, const CFX_WideString &wsPrevText);
+ void OnTextFull(IFWL_Widget *pWidget);
+ void OnAddDoRecord(IFWL_Widget *pWidget);
+ FX_BOOL CheckWord(FX_BSTR sWord);
+ FX_BOOL GetSuggestWords(FX_BSTR sWord, CFX_ByteStringArray &sSuggest);
+ virtual FX_INT32 OnProcessMessage(CFWL_Message *pMessage);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+ virtual FWL_ERR OnDrawWidget(CFX_Graphics *pGraphics, const CFX_Matrix *pMatrix = NULL);
+};
+class CXFA_FFNumericEdit : public CXFA_FFTextEdit
+{
+public:
+ CXFA_FFNumericEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFNumericEdit();
+ virtual FX_BOOL LoadWidget();
+ virtual void UpdateWidgetProperty();
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+public:
+ FX_BOOL OnValidate(IFWL_Widget *pWidget, CFX_WideString &wsText);
+};
+class CXFA_FFPasswordEdit : public CXFA_FFTextEdit
+{
+public:
+ CXFA_FFPasswordEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFPasswordEdit();
+ virtual FX_BOOL LoadWidget();
+ virtual void UpdateWidgetProperty();
+protected:
+};
+enum XFA_DATETIMETYPE {
+ XFA_DATETIMETYPE_Date = 0,
+ XFA_DATETIMETYPE_Time,
+ XFA_DATETIMETYPE_DateAndTime
+};
+class CXFA_FFDateTimeEdit : public CXFA_FFTextEdit
+{
+public:
+ CXFA_FFDateTimeEdit(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFDateTimeEdit();
+
+ virtual FX_BOOL GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus = FALSE);
+ virtual FX_BOOL LoadWidget();
+ virtual void UpdateWidgetProperty();
+
+
+ virtual FX_BOOL CanUndo();
+ virtual FX_BOOL CanRedo();
+ virtual FX_BOOL Undo();
+ virtual FX_BOOL Redo();
+
+ virtual FX_BOOL CanCopy();
+ virtual FX_BOOL CanCut();
+ virtual FX_BOOL CanPaste();
+ virtual FX_BOOL CanSelectAll();
+ virtual FX_BOOL Copy(CFX_WideString &wsCopy);
+ virtual FX_BOOL Cut(CFX_WideString &wsCut);
+ virtual FX_BOOL Paste(const CFX_WideString &wsPaste);
+ virtual FX_BOOL SelectAll();
+ virtual FX_BOOL Delete();
+ virtual FX_BOOL DeSelect();
+
+protected:
+ FX_DWORD GetAlignment();
+
+ virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL CommitData();
+ virtual FX_BOOL UpdateFWLData();
+ virtual FX_BOOL IsDataChanged();
+public:
+ void OnSelectChanged(IFWL_Widget *pWidget, FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay);
+ virtual FWL_ERR OnProcessEvent(CFWL_Event *pEvent);
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffwidget.cpp b/xfa/src/fxfa/src/app/xfa_ffwidget.cpp
new file mode 100644
index 0000000000..46e1d94662
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffwidget.cpp
@@ -0,0 +1,1876 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffpageview.h"
+#include "xfa_textlayout.h"
+CXFA_FFWidget::CXFA_FFWidget(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc)
+ : CXFA_ContentLayoutItemImpl(pDataAcc->GetNode())
+ , m_pPageView(pPageView)
+ , m_pDataAcc(pDataAcc)
+{
+ m_rtWidget.Set(0, 0, 0, 0);
+}
+CXFA_FFWidget::~CXFA_FFWidget()
+{
+}
+IXFA_PageView* CXFA_FFWidget::GetPageView()
+{
+ return m_pPageView;
+}
+void CXFA_FFWidget::SetPageView(IXFA_PageView* pPageView)
+{
+ m_pPageView = (CXFA_FFPageView*)pPageView;
+}
+void CXFA_FFWidget::GetWidgetRect(CFX_RectF &rtWidget)
+{
+ if ((m_dwStatus & XFA_WIDGETSTATUS_RectCached) == 0) {
+ m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
+ this->GetLayoutItem()->GetRect(m_rtWidget);
+ }
+ rtWidget = m_rtWidget;
+}
+CFX_RectF CXFA_FFWidget::ReCacheWidgetRect()
+{
+ m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
+ this->GetLayoutItem()->GetRect(m_rtWidget);
+ return m_rtWidget;
+}
+void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF &rtWidget)
+{
+ GetWidgetRect(rtWidget);
+ FX_FLOAT fValue = 0;
+ switch (m_pDataAcc->GetRotate()) {
+ case 90:
+ rtWidget.top = rtWidget.bottom();
+ fValue = rtWidget.width;
+ rtWidget.width = rtWidget.height;
+ rtWidget.height = fValue;
+ break;
+ case 180:
+ rtWidget.left = rtWidget.right();
+ rtWidget.top = rtWidget.bottom();
+ break;
+ case 270:
+ rtWidget.left = rtWidget.right();
+ fValue = rtWidget.width;
+ rtWidget.width = rtWidget.height;
+ rtWidget.height = fValue;
+ break;
+ }
+}
+FX_DWORD CXFA_FFWidget::GetStatus()
+{
+ return m_dwStatus;
+}
+void CXFA_FFWidget::ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved)
+{
+ m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded;
+}
+FX_BOOL CXFA_FFWidget::GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus)
+{
+ if (bDrawFocus) {
+ return FALSE;
+ }
+#ifndef _XFA_EMB
+ if(m_pPageView) {
+ m_pPageView->GetPageViewRect(rtBox);
+ }
+ return TRUE;
+#endif
+ GetWidgetRect(rtBox);
+ return TRUE;
+}
+CXFA_WidgetAcc* CXFA_FFWidget::GetDataAcc()
+{
+ return m_pDataAcc;
+}
+FX_BOOL CXFA_FFWidget::GetToolTip(CFX_WideString &wsToolTip)
+{
+ if (CXFA_Assist assist = m_pDataAcc->GetAssist()) {
+ if (CXFA_ToolTip toolTip = assist.GetToolTip()) {
+ return toolTip.GetTip(wsToolTip);
+ }
+ }
+ return GetCaptionText(wsToolTip);
+}
+void CXFA_FFWidget::RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_DWORD dwStatus , FX_INT32 iRotate )
+{
+ if (!IsMatchVisibleStatus(dwStatus)) {
+ return;
+ }
+ CXFA_Border border = m_pDataAcc->GetBorder();
+ if (border) {
+ CFX_RectF rtBorder;
+ GetRectWithoutRotate(rtBorder);
+ CXFA_Margin margin = border.GetMargin();
+ if (margin.IsExistInXML()) {
+ XFA_RectWidthoutMargin(rtBorder, margin);
+ }
+ rtBorder.Normalize();
+ DrawBorder(pGS, border, rtBorder, pMatrix);
+ }
+}
+FX_BOOL CXFA_FFWidget::IsLoaded()
+{
+ return m_pPageView != NULL;
+}
+FX_BOOL CXFA_FFWidget::LoadWidget()
+{
+ LayoutWidget();;
+ return TRUE;
+}
+void CXFA_FFWidget::UnloadWidget()
+{
+}
+FX_BOOL CXFA_FFWidget::LayoutWidget()
+{
+ ReCacheWidgetRect();
+ return TRUE;
+}
+FX_BOOL CXFA_FFWidget::UpdateFWLData()
+{
+ return FALSE;
+}
+void CXFA_FFWidget::UpdateWidgetProperty()
+{
+}
+void CXFA_FFWidget::DrawBorder(CFX_Graphics* pGS, CXFA_Box box, const CFX_RectF& rtBorder, CFX_Matrix* pMatrix, FX_DWORD dwFlags)
+{
+ XFA_DrawBox(box, pGS, rtBorder, pMatrix, dwFlags);
+}
+void CXFA_FFWidget::InvalidateWidget(const CFX_RectF* pRect )
+{
+ if (!pRect) {
+ CFX_RectF rtWidget;
+ GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
+ rtWidget.Inflate(2, 2);
+ GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, rtWidget, XFA_INVALIDATE_CurrentPage);
+ } else {
+ GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, *pRect, XFA_INVALIDATE_CurrentPage);
+ }
+}
+void CXFA_FFWidget::AddInvalidateRect(const CFX_RectF* pRect )
+{
+ CFX_RectF rtWidget;
+ if (pRect) {
+ rtWidget = *pRect;
+ } else {
+ GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
+ rtWidget.Inflate(2, 2);
+ }
+ m_pDocView->AddInvalidateRect(m_pPageView, rtWidget);
+}
+FX_BOOL CXFA_FFWidget::GetCaptionText(CFX_WideString &wsCap)
+{
+ CXFA_TextLayout* pCapTextlayout = m_pDataAcc->GetCaptionTextLayout();
+ if (!pCapTextlayout) {
+ return FALSE;
+ }
+ pCapTextlayout->GetText(wsCap);
+ return TRUE;
+}
+FX_BOOL CXFA_FFWidget::IsFocused()
+{
+ return m_dwStatus & XFA_WIDGETSTATUS_Focused;
+}
+FX_BOOL CXFA_FFWidget::OnMouseEnter()
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnMouseExit()
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnMouseWheel(FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+
+FX_BOOL CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget)
+{
+ CXFA_FFWidget* pParent = GetParent();
+ if (pParent != NULL && !pParent->IsAncestorOf(pOldWidget)) {
+ pParent->OnSetFocus(pOldWidget);
+ }
+ m_dwStatus |= XFA_WIDGETSTATUS_Focused;
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Enter;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Enter, &eParam);
+ return TRUE;
+}
+FX_BOOL CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget)
+{
+ m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
+ EventKillFocus();
+ if (pNewWidget != NULL) {
+ CXFA_FFWidget* pParent = GetParent();
+ if (pParent != NULL && !pParent->IsAncestorOf(pNewWidget)) {
+ pParent->OnKillFocus(pNewWidget);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_FFWidget::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags)
+{
+ return FALSE;
+}
+FX_DWORD CXFA_FFWidget::OnHitTest(FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy)
+{
+ return FALSE;
+}
+void CXFA_FFWidget::Rotate2Normal(FX_FLOAT &fx, FX_FLOAT &fy)
+{
+ CFX_Matrix mt;
+ GetRotateMatrix(mt);
+ if (mt.IsIdentity()) {
+ return;
+ }
+ CFX_Matrix mtReverse;
+ mtReverse.SetReverse(mt);
+ mtReverse.TransformPoint(fx, fy);
+}
+static void XFA_GetMatrix(CFX_Matrix &m, FX_INT32 iRotate, FX_INT32 at, const CFX_RectF& rt)
+{
+ if (!iRotate) {
+ return;
+ }
+ FX_FLOAT fAnchorX, fAnchorY;
+ switch (at) {
+ case XFA_ATTRIBUTEENUM_TopLeft:
+ fAnchorX = rt.left, fAnchorY = rt.top;
+ break;
+ case XFA_ATTRIBUTEENUM_TopCenter:
+ fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.top;
+ break;
+ case XFA_ATTRIBUTEENUM_TopRight:
+ fAnchorX = rt.right(), fAnchorY = rt.top;
+ break;
+ case XFA_ATTRIBUTEENUM_MiddleLeft:
+ fAnchorX = rt.left, fAnchorY = (rt.top + rt.bottom()) / 2;
+ break;
+ case XFA_ATTRIBUTEENUM_MiddleCenter:
+ fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = (rt.top + rt.bottom()) / 2;
+ break;
+ case XFA_ATTRIBUTEENUM_MiddleRight:
+ fAnchorX = rt.right(), fAnchorY = (rt.top + rt.bottom()) / 2;
+ break;
+ case XFA_ATTRIBUTEENUM_BottomLeft:
+ fAnchorX = rt.left, fAnchorY = rt.bottom();
+ break;
+ case XFA_ATTRIBUTEENUM_BottomCenter:
+ fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.bottom();
+ break;
+ case XFA_ATTRIBUTEENUM_BottomRight:
+ fAnchorX = rt.right(), fAnchorY = rt.bottom();
+ break;
+ }
+ switch (iRotate) {
+ case 90:
+ m.a = 0, m.b = -1, m.c = 1, m.d = 0, m.e = fAnchorX - fAnchorY, m.f = fAnchorX + fAnchorY;
+ break;
+ case 180:
+ m.a = -1, m.b = 0, m.c = 0, m.d = -1, m.e = fAnchorX * 2, m.f = fAnchorY * 2;
+ break;
+ case 270:
+ m.a = 0, m.b = 1, m.c = -1, m.d = 0, m.e = fAnchorX + fAnchorY, m.f = fAnchorY - fAnchorX;
+ break;
+ }
+}
+void CXFA_FFWidget::GetRotateMatrix(CFX_Matrix &mt)
+{
+ mt.Set(1, 0, 0, 1, 0, 0);
+ FX_INT32 iRotate = m_pDataAcc->GetRotate();
+ if (!iRotate) {
+ return;
+ }
+ CFX_RectF rcWidget;
+ GetRectWithoutRotate(rcWidget);
+ XFA_ATTRIBUTEENUM at = XFA_ATTRIBUTEENUM_TopLeft;
+ XFA_GetMatrix(mt, iRotate, at, rcWidget);
+}
+FX_BOOL CXFA_FFWidget::IsLayoutRectEmpty()
+{
+ CFX_RectF rtLayout;
+ GetRectWithoutRotate(rtLayout);
+ return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
+}
+CXFA_FFWidget* CXFA_FFWidget::GetParent()
+{
+ CXFA_Node* pParentNode = m_pDataAcc->GetNode()->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParentNode != NULL) {
+ CXFA_WidgetAcc* pParentWidgetAcc = (CXFA_WidgetAcc*)pParentNode->GetWidgetData();
+ if (pParentWidgetAcc != NULL) {
+ return pParentWidgetAcc->GetNextWidget(NULL);
+ }
+ }
+ return NULL;
+}
+FX_BOOL CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget)
+{
+ if (!pWidget) {
+ return FALSE;
+ }
+ CXFA_Node* pNode = m_pDataAcc->GetNode();
+ CXFA_Node* pChildNode = pWidget->GetDataAcc()->GetNode();
+ while (pChildNode) {
+ if (pChildNode == pNode) {
+ return TRUE;
+ }
+ pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_FFWidget::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy)
+{
+ CFX_RectF rtWidget;
+ GetWidgetRect(rtWidget);
+ if (rtWidget.Contains(fx, fy)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+CXFA_FFDocView* CXFA_FFWidget::GetDocView()
+{
+ return m_pDocView;
+}
+CXFA_FFDoc* CXFA_FFWidget::GetDoc()
+{
+ return (CXFA_FFDoc*)m_pDocView->GetDoc();
+}
+CXFA_FFApp* CXFA_FFWidget::GetApp()
+{
+ return GetDoc()->GetApp();
+}
+IXFA_AppProvider* CXFA_FFWidget::GetAppProvider()
+{
+ return GetApp()->GetAppProvider();
+}
+void CXFA_FFWidget::GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth)
+{
+ fMinWidth = fMaxWidth = 0;
+ FX_FLOAT fWidth = 0;
+ if (m_pDataAcc->GetWidth(fWidth)) {
+ fMinWidth = fMaxWidth = fWidth;
+ } else {
+ m_pDataAcc->GetMinWidth(fMinWidth);
+ m_pDataAcc->GetMaxWidth(fMaxWidth);
+ }
+}
+void CXFA_FFWidget::GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight)
+{
+ fMinHeight = fMaxHeight = 0;
+ FX_FLOAT fHeight = 0;
+ if (m_pDataAcc->GetHeight(fHeight)) {
+ fMinHeight = fMaxHeight = fHeight;
+ } else {
+ m_pDataAcc->GetMinHeight(fMinHeight);
+ m_pDataAcc->GetMaxHeight(fMaxHeight);
+ }
+}
+FX_BOOL CXFA_FFWidget::IsMatchVisibleStatus(FX_DWORD dwStatus)
+{
+ return m_dwStatus & XFA_WIDGETSTATUS_Visible;
+}
+void CXFA_FFWidget::EventKillFocus()
+{
+ if (m_dwStatus & XFA_WIDGETSTATUS_Access) {
+ m_dwStatus &= ~XFA_WIDGETSTATUS_Access;
+ return;
+ }
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Exit;
+ eParam.m_pTarget = m_pDataAcc;
+ m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Exit, &eParam);
+}
+FX_BOOL CXFA_FFWidget::IsButtonDown()
+{
+ return (m_dwStatus & XFA_WIDGETSTATUS_ButtonDown) != 0;
+}
+void CXFA_FFWidget::SetButtonDown(FX_BOOL bSet)
+{
+ bSet ? m_dwStatus |= XFA_WIDGETSTATUS_ButtonDown : m_dwStatus &= ~XFA_WIDGETSTATUS_ButtonDown;
+}
+FX_INT32 XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics, FX_INT32 iStrokeType, FX_INT32 iCapType)
+{
+ switch(iStrokeType) {
+ case XFA_ATTRIBUTEENUM_DashDot: {
+ FX_FLOAT dashArray[] = {4, 1, 2, 1};
+ if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+ dashArray[1] = 2;
+ dashArray[3] = 2;
+ }
+ pGraphics->SetLineDash(0, dashArray, 4);
+ return FX_DASHSTYLE_DashDot;
+ }
+ case XFA_ATTRIBUTEENUM_DashDotDot: {
+ FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
+ if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+ dashArray[1] = 2;
+ dashArray[3] = 2;
+ dashArray[5] = 2;
+ }
+ pGraphics->SetLineDash(0, dashArray, 6);
+ return FX_DASHSTYLE_DashDotDot;
+ }
+ case XFA_ATTRIBUTEENUM_Dashed: {
+ FX_FLOAT dashArray[] = {5, 1};
+ if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+ dashArray[1] = 2;
+ }
+ pGraphics->SetLineDash(0, dashArray, 2);
+ return FX_DASHSTYLE_Dash;
+ }
+ case XFA_ATTRIBUTEENUM_Dotted: {
+ FX_FLOAT dashArray[] = {2, 1};
+ if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
+ dashArray[1] = 2;
+ }
+ pGraphics->SetLineDash(0, dashArray, 2);
+ return FX_DASHSTYLE_Dot;
+ }
+ default:
+ break;
+ }
+ pGraphics->SetLineDash(FX_DASHSTYLE_Solid);
+ return FX_DASHSTYLE_Solid;
+}
+CFX_GraphStateData::LineCap XFA_LineCapToFXGE(FX_INT32 iLineCap)
+{
+ switch(iLineCap) {
+ case XFA_ATTRIBUTEENUM_Round:
+ return CFX_GraphStateData::LineCapRound;
+ case XFA_ATTRIBUTEENUM_Butt:
+ return CFX_GraphStateData::LineCapButt;
+ default:
+ break;
+ }
+ return CFX_GraphStateData::LineCapSquare;
+}
+class CXFA_ImageRenderer
+{
+public:
+ CXFA_ImageRenderer();
+ ~CXFA_ImageRenderer();
+ FX_BOOL Start(CFX_RenderDevice* pDevice, CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb,
+ int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, int blendType = FXDIB_BLEND_NORMAL);
+ FX_BOOL Continue(IFX_Pause* pPause);
+protected:
+ CFX_RenderDevice* m_pDevice;
+ int m_Status;
+ CFX_AffineMatrix m_ImageMatrix;
+ CFX_DIBSource* m_pDIBSource;
+ CFX_DIBitmap* m_pCloneConvert;
+ int m_BitmapAlpha;
+ FX_ARGB m_FillArgb;
+ FX_DWORD m_Flags;
+ CFX_ImageTransformer* m_pTransformer;
+ FX_LPVOID m_DeviceHandle;
+ FX_INT32 m_BlendType;
+ FX_BOOL m_Result;
+ FX_BOOL m_bPrint;
+ FX_BOOL StartDIBSource();
+ void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb,
+ int bitmap_alpha, int blend_mode, int Transparency);
+};
+CXFA_ImageRenderer::CXFA_ImageRenderer()
+{
+ m_pDevice = NULL;
+ m_Status = 0;
+ m_pDIBSource = NULL;
+ m_pCloneConvert = NULL;
+ m_BitmapAlpha = 255;
+ m_FillArgb = 0;
+ m_Flags = 0;
+ m_pTransformer = NULL;
+ m_DeviceHandle = NULL;
+ m_BlendType = FXDIB_BLEND_NORMAL;
+ m_Result = TRUE;
+ m_bPrint = FALSE;
+}
+CXFA_ImageRenderer::~CXFA_ImageRenderer()
+{
+ if (m_pCloneConvert) {
+ delete m_pCloneConvert;
+ }
+ if (m_pTransformer) {
+ delete m_pTransformer;
+ }
+ if (m_DeviceHandle) {
+ m_pDevice->CancelDIBits(m_DeviceHandle);
+ }
+}
+FX_BOOL CXFA_ImageRenderer::Start(CFX_RenderDevice* pDevice, CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb,
+ int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, int blendType)
+{
+ m_pDevice = pDevice;
+ m_pDIBSource = pDIBSource;
+ m_FillArgb = bitmap_argb;
+ m_BitmapAlpha = bitmap_alpha;
+ m_ImageMatrix = *pImage2Device;
+ m_Flags = flags;
+ m_BlendType = blendType;
+ return StartDIBSource();
+}
+FX_BOOL CXFA_ImageRenderer::StartDIBSource()
+{
+ if (m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
+ &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL, m_BlendType)) {
+ if (m_DeviceHandle != NULL) {
+ m_Status = 3;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
+ FX_RECT image_rect = image_rect_f.GetOutterRect();
+ int dest_width = image_rect.Width();
+ int dest_height = image_rect.Height();
+ if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
+ (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0) ) {
+ if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
+ m_Result = FALSE;
+ return FALSE;
+ }
+ CFX_DIBSource* pDib = m_pDIBSource;
+ if (m_pDIBSource->HasAlpha() && !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE) && !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
+ m_pCloneConvert = m_pDIBSource->CloneConvert(FXDIB_Rgb);
+ if (!m_pCloneConvert) {
+ m_Result = FALSE;
+ return FALSE;
+ }
+ pDib = m_pCloneConvert;
+ }
+ FX_RECT clip_box = m_pDevice->GetClipBox();
+ clip_box.Intersect(image_rect);
+ m_Status = 2;
+ m_pTransformer = FX_NEW CFX_ImageTransformer;
+ m_pTransformer->Start(pDib, &m_ImageMatrix, m_Flags, &clip_box);
+ return TRUE;
+ }
+ if (m_ImageMatrix.a < 0) {
+ dest_width = -dest_width;
+ }
+ if (m_ImageMatrix.d > 0) {
+ dest_height = -dest_height;
+ }
+ int dest_left, dest_top;
+ dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
+ dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
+ if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
+ if (m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top,
+ dest_width, dest_height, m_Flags, NULL, m_BlendType)) {
+ return FALSE;
+ }
+ }
+ if (m_pDIBSource->IsAlphaMask()) {
+ if (m_BitmapAlpha != 255) {
+ m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
+ }
+ if (m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width, dest_height, m_FillArgb, m_Flags)) {
+ return FALSE;
+ }
+ }
+ if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
+ m_Result = FALSE;
+ return TRUE;
+ }
+ FX_RECT clip_box = m_pDevice->GetClipBox();
+ FX_RECT dest_rect = clip_box;
+ dest_rect.Intersect(image_rect);
+ FX_RECT dest_clip(dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
+ dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
+ CFX_DIBitmap* pStretched = m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
+ if (pStretched) {
+ CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb, m_BitmapAlpha, m_BlendType, FALSE);
+ delete pStretched;
+ pStretched = NULL;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_ImageRenderer::Continue(IFX_Pause* pPause)
+{
+ if (m_Status == 2) {
+ if (m_pTransformer->Continue(pPause)) {
+ return TRUE;
+ }
+ CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ if (pBitmap->IsAlphaMask()) {
+ if (m_BitmapAlpha != 255) {
+ m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
+ }
+ m_Result = m_pDevice->SetBitMask(pBitmap,
+ m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_FillArgb);
+ } else {
+ if (m_BitmapAlpha != 255) {
+ pBitmap->MultiplyAlpha(m_BitmapAlpha);
+ }
+ m_Result = m_pDevice->SetDIBits(pBitmap,
+ m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_BlendType);
+ }
+ delete pBitmap;
+ return FALSE;
+ } else if (m_Status == 3) {
+ return m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
+ }
+ return FALSE;
+}
+void CXFA_ImageRenderer::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb,
+ int bitmap_alpha, int blend_mode, int Transparency)
+{
+ if (pDIBitmap == NULL) {
+ return;
+ }
+ FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
+ FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
+ if (blend_mode == FXDIB_BLEND_NORMAL) {
+ if (!pDIBitmap->IsAlphaMask()) {
+ if (bitmap_alpha < 255) {
+ pDIBitmap->MultiplyAlpha(bitmap_alpha);
+ }
+ if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
+ return;
+ }
+ } else {
+ FX_DWORD fill_argb = (mask_argb);
+ if (bitmap_alpha < 255) {
+ ((FX_BYTE*)&fill_argb)[3] = ((FX_BYTE*)&fill_argb)[3] * bitmap_alpha / 255;
+ }
+ if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
+ return;
+ }
+ }
+ }
+ FX_BOOL bBackAlphaRequired = blend_mode && bIsolated;
+ FX_BOOL bGetBackGround = ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
+ (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) && (m_pDevice->GetRenderCaps()
+ & FXRC_GET_BITS) && !bBackAlphaRequired);
+ if (bGetBackGround) {
+ if (bIsolated || !bGroup) {
+ if (pDIBitmap->IsAlphaMask()) {
+ return;
+ }
+ m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
+ } else {
+ FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight());
+ rect.Intersect(m_pDevice->GetClipBox());
+ CFX_DIBitmap* pClone = NULL;
+ FX_BOOL bClone = FALSE;
+ if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
+ bClone = TRUE;
+ pClone = m_pDevice->GetBackDrop()->Clone(&rect);
+ CFX_DIBitmap *pForeBitmap = m_pDevice->GetBitmap();
+ pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pForeBitmap, rect.left, rect.top);
+ left = left >= 0 ? 0 : left;
+ top = top >= 0 ? 0 : top;
+ if (!pDIBitmap->IsAlphaMask())
+ pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap,
+ left, top, blend_mode);
+ else
+ pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap,
+ mask_argb, left, top, blend_mode);
+ } else {
+ pClone = pDIBitmap;
+ }
+ if (m_pDevice->GetBackDrop()) {
+ m_pDevice->SetDIBits(pClone, rect.left, rect.top);
+ } else {
+ if (pDIBitmap->IsAlphaMask()) {
+ return;
+ }
+ m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
+ }
+ if (bClone) {
+ delete pClone;
+ }
+ }
+ return;
+ }
+ if (pDIBitmap->HasAlpha() && !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE)) {
+ CFX_DIBitmap* pCloneConvert = pDIBitmap->CloneConvert(FXDIB_Rgb);
+ if (!pCloneConvert) {
+ return;
+ }
+ CXFA_ImageRenderer imageRender;
+ FX_BOOL bRet = imageRender.Start(m_pDevice, pCloneConvert, m_FillArgb, m_BitmapAlpha, &m_ImageMatrix, m_Flags);
+ while (bRet) {
+ bRet = imageRender.Continue(NULL);
+ }
+ delete pCloneConvert;
+ return;
+ }
+}
+void XFA_DrawImage(CFX_Graphics* pGS, const CFX_RectF &rtImage, CFX_Matrix* pMatrix, CFX_DIBitmap* pDIBitmap, FX_INT32 iAspect, FX_INT32 iImageXDpi, FX_INT32 iImageYDpi, FX_INT32 iHorzAlign, FX_INT32 iVertAlign)
+{
+ if (rtImage.IsEmpty()) {
+ return;
+ }
+ if (!pDIBitmap || !pDIBitmap->GetBuffer()) {
+ return;
+ }
+ FX_FLOAT fWidth = XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
+ FX_FLOAT fHeight = XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
+ CFX_RectF rtFit;
+ rtFit.Set(rtImage.left, rtImage.top, fWidth, fHeight);
+ switch (iAspect) {
+ case XFA_ATTRIBUTEENUM_Fit: {
+ FX_FLOAT f1 = rtImage.height / rtFit.height;
+ FX_FLOAT f2 = rtImage.width / rtFit.width;
+ f1 = FX_MIN(f1, f2);
+ rtFit.height = rtFit.height * f1;
+ rtFit.width = rtFit.width * f1;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Actual:
+ break;
+ case XFA_ATTRIBUTEENUM_Height: {
+ FX_FLOAT f1 = rtImage.height / rtFit.height;
+ rtFit.height = rtImage.height;
+ rtFit.width = f1 * rtFit.width;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_None:
+ rtFit.height = rtImage.height;
+ rtFit.width = rtImage.width;
+ break;
+ case XFA_ATTRIBUTEENUM_Width: {
+ FX_FLOAT f1 = rtImage.width / rtFit.width;
+ rtFit.width = rtImage.width;
+ rtFit.height = rtFit.height * f1;
+ }
+ break;
+ }
+ if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
+ rtFit.left += (rtImage.width - rtFit.width) / 2;
+ } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
+ rtFit.left = rtImage.right() - rtFit.width;
+ }
+ if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
+ rtFit.top += (rtImage.height - rtFit.height) / 2;
+ } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
+ rtFit.top = rtImage.bottom() - rtImage.height;
+ }
+ CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
+ pRenderDevice->SaveState();
+ CFX_PathData path;
+ path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
+ pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING);
+ CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
+ mtImage.Concat(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top);
+ mtImage.Concat(*pMatrix);
+ CXFA_ImageRenderer imageRender;
+ FX_BOOL bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage, FXDIB_INTERPOL);
+ while (bRet) {
+ bRet = imageRender.Continue(NULL);
+ }
+ pRenderDevice->RestoreState();
+}
+const static FX_BYTE g_inv_base64[128] = {
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 62, 255, 255, 255, 63,
+ 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 255, 255, 255, 255, 255, 255,
+ 255, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 255, 255, 255, 255, 255,
+ 255, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 255, 255, 255, 255, 255,
+};
+static FX_LPBYTE XFA_RemoveBase64Whitespace(FX_LPCBYTE pStr, FX_INT32 iLen)
+{
+ FX_LPBYTE pCP;
+ FX_INT32 i = 0, j = 0;
+ if (iLen == 0) {
+ iLen = FXSYS_strlen((FX_CHAR*)pStr);
+ }
+ pCP = (FX_LPBYTE)FDE_Alloc(iLen + 1);
+ for (; i < iLen; i++) {
+ if ((pStr[i] & 128) == 0) {
+ if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
+ pCP[j++] = pStr[i];
+ }
+ }
+ }
+ pCP[j] = '\0';
+ return pCP;
+}
+static FX_INT32 XFA_Base64Decode(FX_LPCSTR pStr, FX_LPBYTE pOutBuffer)
+{
+ if (pStr == NULL) {
+ return 0;
+ }
+ FX_LPBYTE pBuffer = XFA_RemoveBase64Whitespace((FX_LPBYTE)pStr, FXSYS_strlen((FX_CHAR*)pStr));
+ if (pBuffer == NULL) {
+ return 0;
+ }
+ FX_INT32 iLen = FXSYS_strlen((FX_CHAR*)pBuffer);
+ FX_INT32 i = 0, j = 0;
+ FX_DWORD dwLimb = 0;
+ for (; i + 3 < iLen; i += 4) {
+ if (pBuffer[i] == '=' || pBuffer[i + 1] == '='
+ || pBuffer[i + 2] == '=' || pBuffer[i + 3] == '=') {
+ if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
+ break;
+ }
+ if (pBuffer[i + 2] == '=') {
+ dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 6)
+ | ((FX_DWORD)g_inv_base64[pBuffer[i + 1]]);
+ pOutBuffer[j] = (FX_BYTE)(dwLimb >> 4) & 0xFF;
+ j++;
+ } else {
+ dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 12) |
+ ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 6) |
+ ((FX_DWORD)g_inv_base64[pBuffer[i + 2]]);
+ pOutBuffer[j] = (FX_BYTE)(dwLimb >> 10) & 0xFF;
+ pOutBuffer[j + 1] = (FX_BYTE)(dwLimb >> 2) & 0xFF;
+ j += 2;
+ }
+ } else {
+ dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 18) |
+ ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 12) |
+ ((FX_DWORD)g_inv_base64[pBuffer[i + 2]] << 6) |
+ ((FX_DWORD)g_inv_base64[pBuffer[i + 3]]);
+ pOutBuffer[j] = (FX_BYTE)(dwLimb >> 16) & 0xff;
+ pOutBuffer[j + 1] = (FX_BYTE)(dwLimb >> 8) & 0xff;
+ pOutBuffer[j + 2] = (FX_BYTE)(dwLimb) & 0xff;
+ j += 3;
+ }
+ }
+ FDE_Free(pBuffer);
+ return j;
+}
+static FX_CHAR g_base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+FX_LPSTR XFA_Base64Encode(FX_LPCBYTE buf, FX_INT32 buf_len)
+{
+ FX_LPSTR out = NULL;
+ int i, j;
+ FX_DWORD limb;
+ out = (FX_LPSTR)FX_Alloc(FX_CHAR, ((buf_len * 8 + 5) / 6) + 5);
+ for (i = 0, j = 0, limb = 0; i + 2 < buf_len; i += 3, j += 4) {
+ limb =
+ ((FX_DWORD)buf[i] << 16) |
+ ((FX_DWORD)buf[i + 1] << 8) |
+ ((FX_DWORD)buf[i + 2]);
+ out[j] = g_base64_chars[(limb >> 18) & 63];
+ out[j + 1] = g_base64_chars[(limb >> 12) & 63];
+ out[j + 2] = g_base64_chars[(limb >> 6) & 63];
+ out[j + 3] = g_base64_chars[(limb) & 63];
+ }
+ switch (buf_len - i) {
+ case 0:
+ break;
+ case 1:
+ limb = ((FX_DWORD)buf[i]);
+ out[j++] = g_base64_chars[(limb >> 2) & 63];
+ out[j++] = g_base64_chars[(limb << 4) & 63];
+ out[j++] = '=';
+ out[j++] = '=';
+ break;
+ case 2:
+ limb = ((FX_DWORD)buf[i] << 8) | ((FX_DWORD)buf[i + 1]);
+ out[j++] = g_base64_chars[(limb >> 10) & 63];
+ out[j++] = g_base64_chars[(limb >> 4) & 63];
+ out[j++] = g_base64_chars[(limb << 2) & 63];
+ out[j++] = '=';
+ break;
+ default:
+ break;
+ }
+ out[j] = '\0';
+ return out;
+}
+FXCODEC_IMAGE_TYPE XFA_GetImageType(FX_WSTR wsType)
+{
+ CFX_WideString wsContentType(wsType);
+ wsContentType.MakeLower();
+ if (wsContentType == FX_WSTRC(L"image/jpg")) {
+ return FXCODEC_IMAGE_JPG;
+ }
+ if (wsContentType == FX_WSTRC(L"image/png")) {
+ return FXCODEC_IMAGE_PNG;
+ }
+ if (wsContentType == FX_WSTRC(L"image/gif")) {
+ return FXCODEC_IMAGE_GIF;
+ }
+ if (wsContentType == FX_WSTRC(L"image/bmp")) {
+ return FXCODEC_IMAGE_BMP;
+ }
+ if (wsContentType == FX_WSTRC(L"image/tif")) {
+ return FXCODEC_IMAGE_TIF;
+ }
+ return FXCODEC_IMAGE_UNKNOWN;
+}
+CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc *pDoc, CXFA_Image *pImage, FX_BOOL &bNameImage, FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi)
+{
+ CFX_WideString wsHref;
+ pImage->GetHref(wsHref);
+ CFX_WideString wsImage;
+ pImage->GetContent(wsImage);
+ if (wsHref.IsEmpty() && wsImage.IsEmpty()) {
+ return NULL;
+ }
+ CFX_WideString wsContentType;
+ pImage->GetContentType(wsContentType);
+ FXCODEC_IMAGE_TYPE type = XFA_GetImageType(wsContentType);
+ CFX_ByteString bsContent;
+ FX_LPBYTE pImageBuffer = NULL;
+ IFX_FileRead* pImageFileRead = NULL;
+ if (wsImage.GetLength() > 0) {
+ XFA_ATTRIBUTEENUM iEncoding = (XFA_ATTRIBUTEENUM)pImage->GetTransferEncoding();
+ if (iEncoding == XFA_ATTRIBUTEENUM_Base64) {
+ CFX_ByteString bsData = wsImage.UTF8Encode();
+ FX_INT32 iLength = bsData.GetLength();
+ pImageBuffer = FDE_Alloc(iLength);
+ FX_INT32 iRead = XFA_Base64Decode((FX_LPCSTR)bsData, pImageBuffer);
+ if (iRead > 0) {
+ pImageFileRead = FX_CreateMemoryStream(pImageBuffer, iRead);
+ }
+ } else {
+ bsContent = CFX_ByteString::FromUnicode(wsImage);
+ pImageFileRead = FX_CreateMemoryStream((FX_LPBYTE)(FX_LPCBYTE)bsContent, bsContent.GetLength());
+ }
+ } else {
+ CFX_WideString wsURL = wsHref;
+ if (wsURL.Left(7) != FX_WSTRC(L"http://") && wsURL.Left(6) != FX_WSTRC(L"ftp://")) {
+ CFX_DIBitmap *pBitmap = pDoc->GetPDFNamedImage(wsURL, iImageXDpi, iImageYDpi);
+ if (pBitmap != NULL) {
+ bNameImage = TRUE;
+ return pBitmap;
+ }
+ }
+ pImageFileRead = pDoc->GetDocProvider()->OpenLinkedFile((XFA_HDOC)pDoc, wsURL);
+ }
+ if (!pImageFileRead) {
+ if (pImageBuffer) {
+ FDE_Free(pImageBuffer);
+ }
+ return NULL;
+ }
+ bNameImage = FALSE;
+ CFX_DIBitmap* pBitmap = XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
+ if (pImageBuffer) {
+ FDE_Free(pImageBuffer);
+ }
+ pImageFileRead->Release();
+ return pBitmap;
+}
+static FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type, FX_INT32 iComponents, FX_INT32 iBitsPerComponent)
+{
+ FXDIB_Format dibFormat = FXDIB_Argb;
+ switch (type) {
+ case FXCODEC_IMAGE_BMP:
+ case FXCODEC_IMAGE_JPG:
+ case FXCODEC_IMAGE_TIF: {
+ dibFormat = FXDIB_Rgb32;
+ FX_INT32 bpp = iComponents * iBitsPerComponent;
+ if (bpp <= 24) {
+ dibFormat = FXDIB_Rgb;
+ }
+ }
+ break;
+ case FXCODEC_IMAGE_PNG:
+ default:
+ break;
+ }
+ return dibFormat;
+}
+CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead, FXCODEC_IMAGE_TYPE type, FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi)
+{
+ CFX_GEModule* pGeModule = CFX_GEModule::Get();
+ if (!pGeModule) {
+ return NULL;
+ }
+ CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
+ if (!pCodecMgr) {
+ return NULL;
+ }
+ CFX_DIBAttribute dibAttr;
+ CFX_DIBitmap* pBitmap = NULL;
+ ICodec_ProgressiveDecoder* pProgressiveDecoder = pCodecMgr->CreateProgressiveDecoder();
+ FXCODEC_STATUS status = pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr);
+ switch (dibAttr.m_wDPIUnit) {
+ case FXCODEC_RESUNIT_CENTIMETER:
+ dibAttr.m_nXDPI = (FX_INT32)(dibAttr.m_nXDPI * 2.54f);
+ dibAttr.m_nYDPI = (FX_INT32)(dibAttr.m_nYDPI * 2.54f);
+ break;
+ case FXCODEC_RESUNIT_METER:
+ dibAttr.m_nXDPI = (FX_INT32)(dibAttr.m_nXDPI / (FX_FLOAT)100 * 2.54f);
+ dibAttr.m_nYDPI = (FX_INT32)(dibAttr.m_nYDPI / (FX_FLOAT)100 * 2.54f);
+ break;;
+ default:
+ break;
+ }
+ iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
+ iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
+ if (pProgressiveDecoder->GetWidth() > 0 && pProgressiveDecoder->GetHeight() > 0) {
+ type = pProgressiveDecoder->GetType();
+ FX_INT32 iComponents = pProgressiveDecoder->GetNumComponents();
+ FX_INT32 iBpc = pProgressiveDecoder->GetBPC();
+ FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
+ pBitmap = FX_NEW CFX_DIBitmap();
+ pBitmap->Create(pProgressiveDecoder->GetWidth(), pProgressiveDecoder->GetHeight(), dibFormat);
+ pBitmap->Clear(0xffffffff);
+ FX_INT32 nFrames;
+ if ((pProgressiveDecoder->GetFrames(nFrames) == FXCODEC_STATUS_DECODE_READY) && (nFrames > 0)) {
+ pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
+ pProgressiveDecoder->ContinueDecode();
+ }
+ }
+ delete pProgressiveDecoder;
+ return pBitmap;
+}
+void XFA_RectWidthoutMargin(CFX_RectF &rt, const CXFA_Margin &mg, FX_BOOL bUI )
+{
+ if (!mg) {
+ return;
+ }
+ FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+ mg.GetLeftInset(fLeftInset);
+ mg.GetTopInset(fTopInset);
+ mg.GetRightInset(fRightInset);
+ mg.GetBottomInset(fBottomInset);
+ rt.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
+}
+CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem)
+{
+ XFA_ELEMENT iType = pLayoutItem->GetFormNode()->GetClassID();
+ if (XFA_IsCreateWidget(iType)) {
+ return (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pLayoutItem;
+ }
+ return NULL;
+}
+FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType)
+{
+ return iType == XFA_ELEMENT_Field || iType == XFA_ELEMENT_Draw || iType == XFA_ELEMENT_Subform || iType == XFA_ELEMENT_ExclGroup;
+}
+static void XFA_BOX_GetPath_Arc(CXFA_Box box, CFX_RectF rtDraw, CFX_Path &fillPath, FX_DWORD dwFlags)
+{
+ FX_FLOAT a, b;
+ a = rtDraw.width / 2.0f;
+ b = rtDraw.height / 2.0f;
+ if (box.IsCircular() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
+ a = b = FX_MIN(a, b);
+ }
+ CFX_PointF center = rtDraw.Center();
+ rtDraw.left = center.x - a;
+ rtDraw.top = center.y - b;
+ rtDraw.width = a + a;
+ rtDraw.height = b + b;
+ FX_FLOAT startAngle = 0, sweepAngle = 360;
+ FX_BOOL bStart = box.GetStartAngle(startAngle);
+ FX_BOOL bEnd = box.GetSweepAngle(sweepAngle);
+ if (!bStart && !bEnd) {
+ fillPath.AddEllipse(rtDraw);
+ return;
+ }
+ startAngle = -startAngle * FX_PI / 180.0f;
+ sweepAngle = -sweepAngle * FX_PI / 180.0f;
+ fillPath.AddArc(rtDraw.left, rtDraw.top, rtDraw.width, rtDraw.height, startAngle, sweepAngle);
+}
+static void XFA_BOX_GetPath(CXFA_Box box, const CXFA_StrokeArray &strokes, CFX_RectF rtWidget, CFX_Path &path, FX_INT32 nIndex, FX_BOOL bStart, FX_BOOL bCorner)
+{
+ FXSYS_assert(nIndex >= 0 && nIndex < 8);
+ FX_BOOL bInverted, bRound;
+ FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny, offsetY, offsetX, offsetEX, offsetEY;
+ CFX_PointF cpStart, cp, cp1, cp2;
+ CFX_RectF rtRadius;
+ FX_INT32 n = (nIndex & 1) ? nIndex - 1 : nIndex;
+ CXFA_Corner corner1 = (CXFA_Node*)strokes[n];
+ CXFA_Corner corner2 = (CXFA_Node*)strokes[(n + 2) % 8];
+ fRadius1 = bCorner ? corner1.GetRadius() : 0;
+ fRadius2 = bCorner ? corner2.GetRadius() : 0;
+ bInverted = corner1.IsInverted();
+ offsetY = 0.0f;
+ offsetX = 0.0f;
+ bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
+ FX_FLOAT halfAfter = 0.0f;
+ FX_FLOAT halfBefore = 0.0f;
+ CXFA_Stroke stroke = strokes[nIndex];
+ if(stroke.IsCorner()) {
+ CXFA_Stroke edgeBefore = strokes[(nIndex + 1 * 8 - 1) % 8];
+ CXFA_Stroke edgeAfter = strokes[nIndex + 1];
+ if( stroke.IsInverted()) {
+ if(!stroke.SameStyles(edgeBefore)) {
+ halfBefore = edgeBefore.GetThickness() / 2;
+ }
+ if(!stroke.SameStyles(edgeAfter)) {
+ halfAfter = edgeAfter.GetThickness() / 2;
+ }
+ }
+ } else {
+ CXFA_Stroke edgeBefore = strokes[(nIndex + 8 - 2) % 8];
+ CXFA_Stroke edgeAfter = strokes[(nIndex + 2) % 8];
+ if(!bRound && !bInverted) {
+ {
+ halfBefore = edgeBefore.GetThickness() / 2;
+ }
+ {
+ halfAfter = edgeAfter.GetThickness() / 2;
+ }
+ }
+ }
+ offsetEX = 0.0f;
+ offsetEY = 0.0f;
+ if (bRound) {
+ sy = FX_PI / 2;
+ }
+ switch (nIndex) {
+ case 0:
+ case 1:
+ cp1 = rtWidget.TopLeft();
+ cp2 = rtWidget.TopRight();
+ if (nIndex == 0) {
+ cpStart.x = cp1.x - halfBefore;
+ cpStart.y = cp1.y + fRadius1, offsetY = - halfAfter;
+ } else {
+ cpStart.x = cp1.x + fRadius1 - halfBefore, cpStart.y = cp1.y, offsetEX = halfAfter;
+ }
+ vx = 1, vy = 1;
+ nx = -1, ny = 0;
+ if (bRound) {
+ sx = bInverted ? FX_PI / 2 : FX_PI;
+ } else {
+ sx = 1, sy = 0;
+ }
+ break;
+ case 2:
+ case 3:
+ cp1 = rtWidget.TopRight();
+ cp2 = rtWidget.BottomRight();
+ if (nIndex == 2) {
+ cpStart.x = cp1.x - fRadius1, cpStart.y = cp1.y - halfBefore, offsetX = halfAfter;
+ } else {
+ cpStart.x = cp1.x, cpStart.y = cp1.y + fRadius1 - halfBefore, offsetEY = halfAfter;
+ }
+ vx = -1, vy = 1;
+ nx = 0, ny = -1;
+ if (bRound) {
+ sx = bInverted ? FX_PI : FX_PI * 3 / 2;
+ } else {
+ sx = 0, sy = 1;
+ }
+ break;
+ case 4:
+ case 5:
+ cp1 = rtWidget.BottomRight();
+ cp2 = rtWidget.BottomLeft();
+ if (nIndex == 4) {
+ cpStart.x = cp1.x + halfBefore , cpStart.y = cp1.y - fRadius1, offsetY = halfAfter;
+ } else {
+ cpStart.x = cp1.x - fRadius1 + halfBefore, cpStart.y = cp1.y, offsetEX = -halfAfter ;
+ }
+ vx = -1, vy = -1;
+ nx = 1, ny = 0;
+ if (bRound) {
+ sx = bInverted ? FX_PI * 3 / 2 : 0;
+ } else {
+ sx = -1, sy = 0;
+ }
+ break;
+ case 6:
+ case 7:
+ cp1 = rtWidget.BottomLeft();
+ cp2 = rtWidget.TopLeft();
+ if (nIndex == 6) {
+ cpStart.x = cp1.x + fRadius1, cpStart.y = cp1.y + halfBefore, offsetX = -halfAfter;
+ } else {
+ cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore, offsetEY = -halfAfter;
+ }
+ vx = 1, vy = -1;
+ nx = 0, ny = 1;
+ if (bRound) {
+ sx = bInverted ? 0 : FX_PI / 2;
+ } else {
+ sx = 0, sy = -1;
+ }
+ break;
+ }
+ if (bStart) {
+ path.MoveTo(cpStart.x, cpStart.y);
+ }
+ if (nIndex & 1) {
+ path.LineTo(cp2.x + fRadius2 * nx + offsetEX, cp2.y + fRadius2 * ny + offsetEY);
+ return;
+ }
+ if (bRound) {
+ if (fRadius1 < 0) {
+ sx -= FX_PI;
+ }
+ if (bInverted) {
+ sy *= -1;
+ }
+ rtRadius.Set(cp1.x + offsetX * 2, cp1.y + offsetY * 2 , fRadius1 * 2 * vx - offsetX * 2, fRadius1 * 2 * vy - offsetY * 2);
+ rtRadius.Normalize();
+ if (bInverted) {
+ rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
+ }
+ path.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx, sy);
+ } else {
+ if (bInverted) {
+ cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
+ } else {
+ cp = cp1;
+ }
+ path.LineTo(cp.x, cp.y);
+ path.LineTo(cp1.x + fRadius1 * sx + offsetX, cp1.y + fRadius1 * sy + offsetY);
+ }
+}
+static void XFA_BOX_GetFillPath(CXFA_Box box, const CXFA_StrokeArray &strokes, CFX_RectF rtWidget, CFX_Path &fillPath, FX_WORD dwFlags)
+{
+ if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
+ CXFA_Edge edge = box.GetEdge(0);
+ FX_FLOAT fThickness = edge.GetThickness();
+ if (fThickness < 0) {
+ fThickness = 0;
+ }
+ FX_FLOAT fHalf = fThickness / 2;
+ FX_INT32 iHand = box.GetHand();
+ if (iHand == XFA_ATTRIBUTEENUM_Left) {
+ rtWidget.Inflate(fHalf, fHalf);
+ } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+ rtWidget.Deflate(fHalf, fHalf);
+ }
+ XFA_BOX_GetPath_Arc(box, rtWidget, fillPath, dwFlags);
+ return;
+ }
+ FX_BOOL bSameStyles = TRUE;
+ FX_INT32 i;
+ CXFA_Stroke stroke1 = strokes[0];
+ for (i = 1; i < 8; i ++) {
+ CXFA_Stroke stroke2 = strokes[i];
+ if (!stroke1.SameStyles(stroke2)) {
+ bSameStyles = FALSE;
+ break;
+ }
+ stroke1 = stroke2;
+ }
+ if (bSameStyles) {
+ stroke1 = strokes[0];
+ for (i = 2; i < 8; i += 2) {
+ CXFA_Stroke stroke2 = strokes[i];
+ if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence | XFA_STROKE_SAMESTYLE_Corner)) {
+ bSameStyles = FALSE;
+ break;
+ }
+ stroke1 = stroke2;
+ }
+ if (bSameStyles) {
+ stroke1 = strokes[0];
+ if (stroke1.IsInverted()) {
+ bSameStyles = FALSE;
+ }
+ if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
+ bSameStyles = FALSE;
+ }
+ }
+ }
+ if (bSameStyles) {
+ fillPath.AddRectangle(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height);
+ return;
+ }
+ FX_BOOL bInverted, bRound;
+ FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny;
+ CFX_PointF cp, cp1, cp2;
+ CFX_RectF rtRadius;
+ for (FX_INT32 i = 0; i < 8; i += 2) {
+ CXFA_Corner corner1 = (CXFA_Node*)strokes[i];
+ CXFA_Corner corner2 = (CXFA_Node*)strokes[(i + 2) % 8];
+ fRadius1 = corner1.GetRadius();
+ fRadius2 = corner2.GetRadius();
+ bInverted = corner1.IsInverted();
+ bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
+ if (bRound) {
+ sy = FX_PI / 2;
+ }
+ switch (i) {
+ case 0:
+ cp1 = rtWidget.TopLeft();
+ cp2 = rtWidget.TopRight();
+ vx = 1, vy = 1;
+ nx = -1, ny = 0;
+ if (bRound) {
+ sx = bInverted ? FX_PI / 2 : FX_PI;
+ } else {
+ sx = 1, sy = 0;
+ }
+ break;
+ case 2:
+ cp1 = rtWidget.TopRight();
+ cp2 = rtWidget.BottomRight();
+ vx = -1, vy = 1;
+ nx = 0, ny = -1;
+ if (bRound) {
+ sx = bInverted ? FX_PI : FX_PI * 3 / 2;
+ } else {
+ sx = 0, sy = 1;
+ }
+ break;
+ case 4:
+ cp1 = rtWidget.BottomRight();
+ cp2 = rtWidget.BottomLeft();
+ vx = -1, vy = -1;
+ nx = 1, ny = 0;
+ if (bRound) {
+ sx = bInverted ? FX_PI * 3 / 2 : 0;
+ } else {
+ sx = -1, sy = 0;
+ }
+ break;
+ case 6:
+ cp1 = rtWidget.BottomLeft();
+ cp2 = rtWidget.TopLeft();
+ vx = 1, vy = -1;
+ nx = 0, ny = 1;
+ if (bRound) {
+ sx = bInverted ? 0 : FX_PI / 2;
+ } else {
+ sx = 0, sy = -1;
+ }
+ break;
+ }
+ if (i == 0) {
+ fillPath.MoveTo(cp1.x, cp1.y + fRadius1);
+ }
+ if (bRound) {
+ if (fRadius1 < 0) {
+ sx -= FX_PI;
+ }
+ if (bInverted) {
+ sy *= -1;
+ }
+ rtRadius.Set(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy);
+ rtRadius.Normalize();
+ if (bInverted) {
+ rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
+ }
+ fillPath.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx, sy);
+ } else {
+ if (bInverted) {
+ cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
+ } else {
+ cp = cp1;
+ }
+ fillPath.LineTo(cp.x, cp.y);
+ fillPath.LineTo(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy);
+ }
+ fillPath.LineTo(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny);
+ }
+}
+static void XFA_BOX_Fill_Radial(CXFA_Box box, CFX_Graphics* pGS, CFX_Path &fillPath, CFX_RectF rtFill, CFX_Matrix* pMatrix)
+{
+ CXFA_Fill fill = box.GetFill();
+ FX_ARGB crStart, crEnd;
+ crStart = fill.GetColor();
+ FX_INT32 iType = fill.GetRadial(crEnd);
+ CFX_Shading shading;
+ if (iType != XFA_ATTRIBUTEENUM_ToEdge) {
+ FX_ARGB temp = crEnd;
+ crEnd = crStart;
+ crStart = temp;
+ }
+ shading.CreateRadial(rtFill.Center(), rtFill.Center(), 0, FXSYS_sqrt(rtFill.Width()*rtFill.Width() + rtFill.Height()*rtFill.Height()) / 2, TRUE, TRUE, crStart, crEnd);
+ CFX_Color cr(&shading);
+ pGS->SetFillColor(&cr);
+ pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Fill_Pattern(CXFA_Box box, CFX_Graphics* pGS, CFX_Path &fillPath, CFX_RectF rtFill, CFX_Matrix* pMatrix)
+{
+ CXFA_Fill fill = box.GetFill();
+ FX_ARGB crStart, crEnd;
+ crStart = fill.GetColor();
+ FX_INT32 iType = fill.GetPattern(crEnd);
+ FX_INT32 iHatch = FX_HATCHSTYLE_Cross;
+ switch(iType) {
+ case XFA_ATTRIBUTEENUM_CrossDiagonal:
+ iHatch = FX_HATCHSTYLE_DiagonalCross;
+ break;
+ case XFA_ATTRIBUTEENUM_DiagonalLeft:
+ iHatch = FX_HATCHSTYLE_ForwardDiagonal;
+ break;
+ case XFA_ATTRIBUTEENUM_DiagonalRight:
+ iHatch = FX_HATCHSTYLE_BackwardDiagonal;
+ break;
+ case XFA_ATTRIBUTEENUM_Horizontal:
+ iHatch = FX_HATCHSTYLE_Horizontal;
+ break;
+ case XFA_ATTRIBUTEENUM_Vertical:
+ iHatch = FX_HATCHSTYLE_Vertical;
+ break;
+ default:
+ break;
+ }
+ CFX_Pattern pattern;
+ pattern.Create(iHatch, crEnd, crStart);
+ CFX_Color cr(&pattern);
+ pGS->SetFillColor(&cr);
+ pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Fill_Linear(CXFA_Box box, CFX_Graphics* pGS, CFX_Path &fillPath, CFX_RectF rtFill, CFX_Matrix* pMatrix)
+{
+ CXFA_Fill fill = box.GetFill();
+ FX_ARGB crStart, crEnd;
+ crStart = fill.GetColor();
+ FX_INT32 iType = fill.GetLinear(crEnd);
+ CFX_PointF ptStart, ptEnd;
+ switch(iType) {
+ case XFA_ATTRIBUTEENUM_ToRight:
+ ptStart.Set(rtFill.left, rtFill.top);
+ ptEnd.Set(rtFill.right(), rtFill.top);
+ break;
+ case XFA_ATTRIBUTEENUM_ToBottom:
+ ptStart.Set(rtFill.left, rtFill.top);
+ ptEnd.Set(rtFill.left, rtFill.bottom());
+ break;
+ case XFA_ATTRIBUTEENUM_ToLeft:
+ ptStart.Set(rtFill.right(), rtFill.top);
+ ptEnd.Set(rtFill.left, rtFill.top);
+ break;
+ case XFA_ATTRIBUTEENUM_ToTop:
+ ptStart.Set(rtFill.left, rtFill.bottom());
+ ptEnd.Set(rtFill.left, rtFill.top);
+ break;
+ default:
+ break;
+ }
+ CFX_Shading shading;
+ shading.CreateAxial(ptStart, ptEnd, FALSE, FALSE, crStart, crEnd);
+ CFX_Color cr(&shading);
+ pGS->SetFillColor(&cr);
+ pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Fill(CXFA_Box box, const CXFA_StrokeArray &strokes, CFX_Graphics* pGS, const CFX_RectF &rtWidget, CFX_Matrix* pMatrix, FX_DWORD dwFlags)
+{
+ CXFA_Fill fill = box.GetFill();
+ if (!fill.IsExistInXML() || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+ return;
+ }
+ pGS->SaveGraphState();
+ CFX_Path fillPath;
+ fillPath.Create();
+ XFA_BOX_GetFillPath(box, strokes, rtWidget, fillPath, (dwFlags & XFA_DRAWBOX_ForceRound) != 0);
+ fillPath.Close();
+ FX_INT32 eType = fill.GetFillType();
+ switch(eType) {
+ case XFA_ELEMENT_Radial:
+ XFA_BOX_Fill_Radial(box, pGS, fillPath, rtWidget, pMatrix);
+ break;
+ case XFA_ELEMENT_Pattern:
+ XFA_BOX_Fill_Pattern(box, pGS, fillPath, rtWidget, pMatrix);
+ break;
+ case XFA_ELEMENT_Linear:
+ XFA_BOX_Fill_Linear(box, pGS, fillPath, rtWidget, pMatrix);
+ break;
+ default: {
+ FX_ARGB cr;
+ if (eType == XFA_ELEMENT_Stipple) {
+ FX_INT32 iRate = fill.GetStipple(cr);
+ if (iRate == 0) {
+ iRate = 100;
+ }
+ FX_INT32 a = 0;
+ FX_COLORREF rgb;
+ ArgbDecode(cr, a, rgb);
+ cr = ArgbEncode(iRate * a / 100, rgb);
+ } else {
+ cr = fill.GetColor();
+ }
+ CFX_Color fillColor(cr);
+ pGS->SetFillColor(&fillColor);
+ pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
+ }
+ break;
+ }
+ pGS->RestoreGraphState();
+}
+static void XFA_BOX_StrokePath(CXFA_Stroke stroke, CFX_Path *pPath, CFX_Graphics* pGS, CFX_Matrix* pMatrix)
+{
+ if (!stroke.IsExistInXML() || !stroke.IsVisible()) {
+ return;
+ }
+ FX_FLOAT fThickness = stroke.GetThickness();
+ if (fThickness < 0.001f) {
+ return;
+ }
+ pGS->SaveGraphState();
+ if(stroke.IsCorner() && fThickness > 2 * stroke.GetRadius()) {
+ fThickness = 2 * stroke.GetRadius();
+ }
+ pGS->SetLineWidth(fThickness, TRUE);
+ pGS->SetLineCap(CFX_GraphStateData::LineCapButt);
+ XFA_StrokeTypeSetLineDash(pGS, stroke.GetStrokeType(), XFA_ATTRIBUTEENUM_Butt);
+ CFX_Color fxColor(stroke.GetColor());
+ pGS->SetStrokeColor(&fxColor);
+ pGS->StrokePath(pPath, pMatrix);
+ pGS->RestoreGraphState();
+}
+static void XFA_BOX_StrokeArc(CXFA_Box box, CFX_Graphics* pGS, CFX_RectF rtWidget, CFX_Matrix* pMatrix, FX_DWORD dwFlags)
+{
+ CXFA_Edge edge = box.GetEdge(0);
+ if (!edge.IsExistInXML() || !edge.IsVisible()) {
+ return;
+ }
+ FX_BOOL bVisible = FALSE;
+ FX_FLOAT fThickness = 0;
+ FX_INT32 i3DType = box.Get3DStyle(bVisible, fThickness);
+ if (i3DType) {
+ if (bVisible && fThickness >= 0.001f) {
+ dwFlags |= XFA_DRAWBOX_Lowered3D;
+ }
+ }
+ FX_FLOAT fHalf = edge.GetThickness() / 2;
+ if (fHalf < 0) {
+ fHalf = 0;
+ }
+ FX_INT32 iHand = box.GetHand();
+ if (iHand == XFA_ATTRIBUTEENUM_Left) {
+ rtWidget.Inflate(fHalf, fHalf);
+ } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+ rtWidget.Deflate(fHalf, fHalf);
+ }
+ if ((dwFlags & XFA_DRAWBOX_ForceRound) == 0 || (dwFlags & XFA_DRAWBOX_Lowered3D) == 0) {
+ if (fHalf < 0.001f) {
+ return;
+ }
+ CFX_Path arcPath;
+ arcPath.Create();
+ XFA_BOX_GetPath_Arc(box, rtWidget, arcPath, dwFlags);
+ XFA_BOX_StrokePath(edge, &arcPath, pGS, pMatrix);
+ return;
+ }
+ pGS->SaveGraphState();
+ pGS->SetLineWidth(fHalf);
+ FX_FLOAT a, b;
+ a = rtWidget.width / 2.0f;
+ b = rtWidget.height / 2.0f;
+ if (dwFlags & XFA_DRAWBOX_ForceRound) {
+ a = b = FX_MIN(a, b);
+ }
+ CFX_PointF center = rtWidget.Center();
+ rtWidget.left = center.x - a;
+ rtWidget.top = center.y - b;
+ rtWidget.width = a + a;
+ rtWidget.height = b + b;
+ FX_FLOAT startAngle = 0, sweepAngle = 360;
+ startAngle = startAngle * FX_PI / 180.0f;
+ sweepAngle = -sweepAngle * FX_PI / 180.0f;
+ CFX_Path arcPath;
+ arcPath.Create();
+ arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, 3.0f * FX_PI / 4.0f, FX_PI);
+ CFX_Color cr(0xFF808080);
+ pGS->SetStrokeColor(&cr);
+ pGS->StrokePath(&arcPath, pMatrix);
+ arcPath.Clear();
+ arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, -1.0f * FX_PI / 4.0f, FX_PI);
+ cr.Set(0xFFFFFFFF);
+ pGS->SetStrokeColor(&cr);
+ pGS->StrokePath(&arcPath, pMatrix);
+ rtWidget.Deflate(fHalf, fHalf);
+ arcPath.Clear();
+ arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, 3.0f * FX_PI / 4.0f, FX_PI);
+ cr.Set(0xFF404040);
+ pGS->SetStrokeColor(&cr);
+ pGS->StrokePath(&arcPath, pMatrix);
+ arcPath.Clear();
+ arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height, -1.0f * FX_PI / 4.0f, FX_PI);
+ cr.Set(0xFFC0C0C0);
+ pGS->SetStrokeColor(&cr);
+ pGS->StrokePath(&arcPath, pMatrix);
+ pGS->RestoreGraphState();
+}
+static void XFA_Draw3DRect(CFX_Graphics* pGraphic, const CFX_RectF& rt, FX_FLOAT fLineWidth, CFX_Matrix* pMatrix, FX_ARGB argbTopLeft, FX_ARGB argbBottomRight)
+{
+ CFX_Color crLT(argbTopLeft);
+ pGraphic->SetFillColor(&crLT);
+ FX_FLOAT fBottom = rt.bottom();
+ FX_FLOAT fRight = rt.right();
+ CFX_Path pathLT;
+ pathLT.Create();
+ pathLT.MoveTo(rt.left, fBottom);
+ pathLT.LineTo(rt.left, rt.top);
+ pathLT.LineTo(fRight, rt.top);
+ pathLT.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
+ pathLT.LineTo(rt.left + fLineWidth, rt.top + fLineWidth);
+ pathLT.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
+ pathLT.LineTo(rt.left, fBottom);
+ pGraphic->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
+ CFX_Color crRB(argbBottomRight);
+ pGraphic->SetFillColor(&crRB);
+ CFX_Path pathRB;
+ pathRB.Create();
+ pathRB.MoveTo(fRight, rt.top);
+ pathRB.LineTo(fRight, fBottom);
+ pathRB.LineTo(rt.left, fBottom);
+ pathRB.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
+ pathRB.LineTo(fRight - fLineWidth, fBottom - fLineWidth);
+ pathRB.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
+ pathRB.LineTo(fRight, rt.top);
+ pGraphic->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
+}
+static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS, CFX_RectF rt, FX_FLOAT fThickness, CFX_Matrix* pMatrix)
+{
+ FX_FLOAT fHalfWidth = fThickness / 2.0f;
+ CFX_RectF rtInner(rt);
+ rtInner.Deflate(fHalfWidth, fHalfWidth);
+ CFX_Color cr(0xFF000000);
+ pGS->SetFillColor(&cr);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
+ path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
+ pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+ XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF808080, 0xFFC0C0C0);
+}
+static void XFA_BOX_Stroke_3DRect_Raised(CFX_Graphics* pGS, CFX_RectF rt, FX_FLOAT fThickness, CFX_Matrix* pMatrix)
+{
+ FX_FLOAT fHalfWidth = fThickness / 2.0f;
+ CFX_RectF rtInner(rt);
+ rtInner.Deflate(fHalfWidth, fHalfWidth);
+ CFX_Color cr(0xFF000000);
+ pGS->SetFillColor(&cr);
+ CFX_Path path;
+ path.Create();
+ path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
+ path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
+ pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
+ XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
+}
+static void XFA_BOX_Stroke_3DRect_Etched(CFX_Graphics* pGS, CFX_RectF rt, FX_FLOAT fThickness, CFX_Matrix* pMatrix)
+{
+ FX_FLOAT fHalfWidth = fThickness / 2.0f;
+ XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFFFFFFFF);
+ CFX_RectF rtInner(rt);
+ rtInner.Deflate(fHalfWidth, fHalfWidth);
+ XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
+}
+static void XFA_BOX_Stroke_3DRect_Embossed(CFX_Graphics* pGS, CFX_RectF rt, FX_FLOAT fThickness, CFX_Matrix* pMatrix)
+{
+ FX_FLOAT fHalfWidth = fThickness / 2.0f;
+ XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFF000000);
+ CFX_RectF rtInner(rt);
+ rtInner.Deflate(fHalfWidth, fHalfWidth);
+ XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF000000, 0xFF808080);
+}
+static void XFA_BOX_Stroke_Rect(CXFA_Box box, const CXFA_StrokeArray &strokes, CFX_Graphics* pGS, CFX_RectF rtWidget, CFX_Matrix* pMatrix)
+{
+ FX_BOOL bVisible = FALSE;
+ FX_FLOAT fThickness = 0;
+ FX_INT32 i3DType = box.Get3DStyle(bVisible, fThickness);
+ if (i3DType) {
+ if (!bVisible || fThickness < 0.001f) {
+ return;
+ }
+ switch (i3DType) {
+ case XFA_ATTRIBUTEENUM_Lowered:
+ XFA_BOX_Stroke_3DRect_Lowered(pGS, rtWidget, fThickness, pMatrix);
+ break;
+ case XFA_ATTRIBUTEENUM_Raised:
+ XFA_BOX_Stroke_3DRect_Raised(pGS, rtWidget, fThickness, pMatrix);
+ break;
+ case XFA_ATTRIBUTEENUM_Etched:
+ XFA_BOX_Stroke_3DRect_Etched(pGS, rtWidget, fThickness, pMatrix);
+ break;
+ case XFA_ATTRIBUTEENUM_Embossed:
+ XFA_BOX_Stroke_3DRect_Embossed(pGS, rtWidget, fThickness, pMatrix);
+ break;
+ }
+ return;
+ }
+ FX_BOOL bClose = FALSE;
+ FX_BOOL bSameStyles = TRUE;
+ FX_INT32 i;
+ CXFA_Stroke stroke1 = strokes[0];
+ for (i = 1; i < 8; i ++) {
+ CXFA_Stroke stroke2 = strokes[i];
+ if (!stroke1.SameStyles(stroke2)) {
+ bSameStyles = FALSE;
+ break;
+ }
+ stroke1 = stroke2;
+ }
+ if (bSameStyles) {
+ stroke1 = strokes[0];
+ bClose = TRUE;
+ for (i = 2; i < 8; i += 2) {
+ CXFA_Stroke stroke2 = strokes[i];
+ if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence | XFA_STROKE_SAMESTYLE_Corner)) {
+ bSameStyles = FALSE;
+ break;
+ }
+ stroke1 = stroke2;
+ }
+ if (bSameStyles) {
+ stroke1 = strokes[0];
+ if (stroke1.IsInverted()) {
+ bSameStyles = FALSE;
+ }
+ if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
+ bSameStyles = FALSE;
+ }
+ }
+ }
+ FX_BOOL bStart = TRUE;
+ CFX_Path path;
+ path.Create();
+ for (i = 0; i < 8; i ++) {
+ CXFA_Stroke stroke1 = strokes[i];
+ if ((i % 1) == 0 && stroke1.GetRadius() < 0) {
+ FX_BOOL bEmpty = path.IsEmpty();
+ if (!bEmpty) {
+ XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
+ path.Clear();
+ }
+ bStart = TRUE;
+ continue;
+ }
+ XFA_BOX_GetPath(box, strokes, rtWidget, path, i, bStart, !bSameStyles);
+ CXFA_Stroke stroke2 = strokes[(i + 1) % 8];
+ bStart = !stroke1.SameStyles(stroke2);
+ if (bStart) {
+ XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
+ path.Clear();
+ }
+ }
+ FX_BOOL bEmpty = path.IsEmpty();
+ if (!bEmpty) {
+ if(bClose) {
+ path.Close();
+ }
+ XFA_BOX_StrokePath(strokes[7], &path, pGS, pMatrix);
+ }
+}
+static void XFA_BOX_Stroke(CXFA_Box box, const CXFA_StrokeArray &strokes, CFX_Graphics* pGS, CFX_RectF rtWidget, CFX_Matrix* pMatrix, FX_DWORD dwFlags)
+{
+ if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
+ XFA_BOX_StrokeArc(box, pGS, rtWidget, pMatrix, dwFlags);
+ return;
+ }
+ FX_BOOL bVisible = FALSE;
+ for (FX_INT32 j = 0; j < 4; j ++) {
+ bVisible |= strokes[j * 2 + 1].IsVisible();
+ if (bVisible) {
+ break;
+ }
+ }
+ if (!bVisible) {
+ return;
+ }
+ for (FX_INT32 i = 1; i < 8; i += 2) {
+ CXFA_Edge edge = (CXFA_Node*)strokes[i];
+ FX_FLOAT fThickness = edge.GetThickness();
+ if (fThickness < 0) {
+ fThickness = 0;
+ }
+ FX_FLOAT fHalf = fThickness / 2;
+ FX_INT32 iHand = box.GetHand();
+ switch (i) {
+ case 1:
+ if (iHand == XFA_ATTRIBUTEENUM_Left) {
+ rtWidget.top -= fHalf;
+ rtWidget.height += fHalf;
+ } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+ rtWidget.top += fHalf;
+ rtWidget.height -= fHalf;
+ }
+ break;
+ case 3:
+ if (iHand == XFA_ATTRIBUTEENUM_Left) {
+ rtWidget.width += fHalf;
+ } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+ rtWidget.width -= fHalf;
+ }
+ break;
+ case 5:
+ if (iHand == XFA_ATTRIBUTEENUM_Left) {
+ rtWidget.height += fHalf;
+ } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+ rtWidget.height -= fHalf;
+ }
+ break;
+ case 7:
+ if (iHand == XFA_ATTRIBUTEENUM_Left) {
+ rtWidget.left -= fHalf;
+ rtWidget.width += fHalf;
+ } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
+ rtWidget.left += fHalf;
+ rtWidget.width -= fHalf;
+ }
+ break;
+ }
+ }
+ XFA_BOX_Stroke_Rect(box, strokes, pGS, rtWidget, pMatrix);
+}
+void XFA_DrawBox(CXFA_Box box, CFX_Graphics* pGS, const CFX_RectF &rtWidget, CFX_Matrix* pMatrix, FX_DWORD dwFlags)
+{
+ if (!box || box.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+ return;
+ }
+ FX_INT32 iType = box.GetClassID();
+ if (iType != XFA_ELEMENT_Arc && iType != XFA_ELEMENT_Border && iType != XFA_ELEMENT_Rectangle) {
+ return;
+ }
+ CXFA_StrokeArray strokes;
+ if (!(dwFlags & XFA_DRAWBOX_ForceRound) && iType != XFA_ELEMENT_Arc) {
+ box.GetStrokes(strokes);
+ }
+ XFA_BOX_Fill(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
+ XFA_BOX_Stroke(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffwidget.h b/xfa/src/fxfa/src/app/xfa_ffwidget.h
new file mode 100644
index 0000000000..bfac36e398
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffwidget.h
@@ -0,0 +1,201 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_WIDGET_IMP_H
+#define _FXFA_FORMFILLER_WIDGET_IMP_H
+class CXFA_FFPageView;
+class CXFA_FFDocView;
+class CXFA_FFDoc;
+class CXFA_FFApp;
+class CXFA_LayoutItem;
+#define XFA_GOTO_POSITION_IF_FAIL(arg, pos) { if (!(arg)) goto pos; }
+inline FX_FLOAT XFA_UnitPx2Pt(FX_FLOAT fPx, FX_FLOAT fDpi)
+{
+ return fPx * 72.0f / fDpi;
+}
+#define XFA_FLOAT_PERCISION 0.001f
+enum XFA_WIDGETITEM {
+ XFA_WIDGETITEM_Parent,
+ XFA_WIDGETITEM_FirstChild,
+ XFA_WIDGETITEM_NextSibling,
+ XFA_WIDGETITEM_PrevSibling,
+};
+class CXFA_CalcData : public CFX_Object
+{
+public:
+ CXFA_CalcData() : m_iRefCount(0) {}
+ ~CXFA_CalcData()
+ {
+ m_Globals.RemoveAll();
+ }
+ CFX_PtrArray m_Globals;
+ FX_INT32 m_iRefCount;
+};
+class CXFA_FFWidget : public CFX_PrivateData, public CXFA_ContentLayoutItemImpl
+{
+public:
+ CXFA_FFWidget(CXFA_FFPageView* pPageView, CXFA_WidgetAcc* pDataAcc);
+ virtual ~CXFA_FFWidget();
+ IXFA_PageView* GetPageView();
+ void SetPageView(IXFA_PageView* pPageView);
+ void GetWidgetRect(CFX_RectF &rtWidget);
+ CFX_RectF ReCacheWidgetRect();
+ FX_DWORD GetStatus();
+ void ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved);
+ virtual FX_BOOL GetBBox(CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus = FALSE);
+ CXFA_WidgetAcc* GetDataAcc();
+ FX_BOOL GetToolTip(CFX_WideString &wsToolTip);
+ virtual void RenderWidget(CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_DWORD dwStatus = 0, FX_INT32 iRotate = 0);
+
+ virtual FX_BOOL IsLoaded();
+ virtual FX_BOOL LoadWidget();
+ virtual void UnloadWidget();
+ virtual FX_BOOL LayoutWidget();
+ virtual FX_BOOL UpdateFWLData();
+ virtual void UpdateWidgetProperty();
+ virtual FX_BOOL OnMouseEnter();
+ virtual FX_BOOL OnMouseExit();
+ virtual FX_BOOL OnLButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseWheel(FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDown(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDblClk(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+
+ virtual FX_BOOL OnSetFocus(CXFA_FFWidget* pOldWidget);
+ virtual FX_BOOL OnKillFocus(CXFA_FFWidget* pNewWidget);
+ virtual FX_BOOL OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnChar(FX_DWORD dwChar, FX_DWORD dwFlags);
+ virtual FX_DWORD OnHitTest(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnSetCursor(FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL CanUndo()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL CanRedo()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL Undo()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL Redo()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL CanCopy()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL CanCut()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL CanPaste()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL CanSelectAll()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL CanDelete()
+ {
+ return CanCut();
+ }
+ virtual FX_BOOL CanDeSelect()
+ {
+ return CanCopy();
+ }
+ virtual FX_BOOL Copy(CFX_WideString &wsCopy)
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL Cut(CFX_WideString &wsCut)
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL Paste(const CFX_WideString &wsPaste)
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL SelectAll()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL Delete()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL DeSelect()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL GetSuggestWords(CFX_PointF pointf, CFX_ByteStringArray &sSuggest)
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL ReplaceSpellCheckWord(CFX_PointF pointf, FX_BSTR bsReplace)
+ {
+ return FALSE;
+ }
+ CXFA_FFDocView* GetDocView();
+ void SetDocView(CXFA_FFDocView* pDocView)
+ {
+ m_pDocView = pDocView;
+ }
+ CXFA_FFDoc* GetDoc();
+ CXFA_FFApp* GetApp();
+ IXFA_AppProvider* GetAppProvider();
+ void InvalidateWidget(const CFX_RectF* pRect = NULL);
+ void AddInvalidateRect(const CFX_RectF* pRect = NULL);
+ FX_BOOL GetCaptionText(CFX_WideString &wsCap);
+ FX_BOOL IsFocused();
+ CXFA_LayoutItem* GetLayoutItem()
+ {
+ return (CXFA_LayoutItem*)(CXFA_ContentLayoutItemImpl*)this;
+ }
+ void Rotate2Normal(FX_FLOAT &fx, FX_FLOAT &fy);
+ void GetRotateMatrix(CFX_Matrix &mt);
+ FX_BOOL IsLayoutRectEmpty();
+ CXFA_FFWidget* GetParent();
+ FX_BOOL IsAncestorOf(CXFA_FFWidget* pWidget);
+
+protected:
+ virtual FX_BOOL PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy);
+ void DrawBorder(CFX_Graphics* pGS, CXFA_Box box, const CFX_RectF& rtBorder, CFX_Matrix* pMatrix, FX_DWORD dwFlags = 0);
+ void GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth);
+ void GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight);
+ void GetRectWithoutRotate(CFX_RectF &rtWidget);
+ FX_BOOL IsMatchVisibleStatus(FX_DWORD dwStatus);
+
+ void EventKillFocus();
+ FX_BOOL IsButtonDown();
+ void SetButtonDown(FX_BOOL bSet);
+ CXFA_FFDocView* m_pDocView;
+ CXFA_FFPageView* m_pPageView;
+ CXFA_WidgetAcc* m_pDataAcc;
+ CFX_RectF m_rtWidget;
+};
+FX_INT32 XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics, FX_INT32 iStrokeType, FX_INT32 iCapType);
+CFX_GraphStateData::LineCap XFA_LineCapToFXGE(FX_INT32 iLineCap);
+void XFA_DrawImage(CFX_Graphics* pGS, const CFX_RectF &rtImage, CFX_Matrix* pMatrix, CFX_DIBitmap* pDIBitmap, FX_INT32 iAspect, FX_INT32 iImageXDpi, FX_INT32 iImageYDpi, FX_INT32 iHorzAlign = XFA_ATTRIBUTEENUM_Left, FX_INT32 iVertAlign = XFA_ATTRIBUTEENUM_Top);
+CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc *pDoc, CXFA_Image *pImage, FX_BOOL &bNameImage, FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi);
+CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead, FXCODEC_IMAGE_TYPE type, FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi);
+FXCODEC_IMAGE_TYPE XFA_GetImageType(FX_WSTR wsType);
+FX_LPSTR XFA_Base64Encode(FX_LPCBYTE buf, FX_INT32 buf_len);
+void XFA_RectWidthoutMargin(CFX_RectF &rt, const CXFA_Margin &mg, FX_BOOL bUI = FALSE);
+FX_FLOAT XFA_GetEdgeThickness(const CXFA_StrokeArray &strokes, FX_BOOL b3DStyle, FX_INT32 nIndex);
+CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem);
+FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType);
+#define XFA_DRAWBOX_ForceRound 1
+#define XFA_DRAWBOX_Lowered3D 2
+void XFA_DrawBox(CXFA_Box box, CFX_Graphics* pGS, const CFX_RectF &rtWidget, CFX_Matrix* pMatrix, FX_DWORD dwFlags = 0);
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffwidgetacc.cpp b/xfa/src/fxfa/src/app/xfa_ffwidgetacc.cpp
new file mode 100644
index 0000000000..df9ad9f466
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffwidgetacc.cpp
@@ -0,0 +1,1713 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffdocview.h"
+#include "xfa_ffpageview.h"
+#include "xfa_ffapp.h"
+#include "xfa_textlayout.h"
+#include "xfa_fwladapter.h"
+#include "xfa_fffield.h"
+#include "xfa_ffchoicelist.h"
+#include "xfa_ffcheckbutton.h"
+#include "xfa_ffwidgetacc.h"
+#include "xfa_fontmgr.h"
+static void XFA_FFDeleteCalcData(FX_LPVOID pData)
+{
+ if (pData) {
+ delete ((CXFA_CalcData*)pData);
+ }
+}
+static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADeleteCalcData = {XFA_FFDeleteCalcData, NULL};
+class CXFA_WidgetLayoutData : public CFX_Object
+{
+public:
+ CXFA_WidgetLayoutData()
+ : m_fWidgetHeight(-1)
+ {
+ }
+ virtual ~CXFA_WidgetLayoutData() {}
+ virtual void Release()
+ {
+ delete this;
+ }
+ FX_FLOAT m_fWidgetHeight;
+};
+class CXFA_TextLayoutData : public CXFA_WidgetLayoutData
+{
+public:
+ CXFA_TextLayoutData()
+ : m_pTextLayout(NULL)
+ , m_pTextProvider(NULL)
+ {
+ }
+ ~CXFA_TextLayoutData()
+ {
+ if (m_pTextLayout) {
+ delete m_pTextLayout;
+ }
+ m_pTextLayout = NULL;
+ if (m_pTextProvider) {
+ delete m_pTextProvider;
+ }
+ m_pTextProvider = NULL;
+ }
+ FX_BOOL LoadText(CXFA_WidgetAcc* pAcc)
+ {
+ if (m_pTextLayout) {
+ return TRUE;
+ }
+ m_pTextProvider = FX_NEW CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Text);
+ m_pTextLayout = FX_NEW CXFA_TextLayout(m_pTextProvider);
+ return m_pTextLayout != NULL;
+ }
+ CXFA_TextLayout* m_pTextLayout;
+ CXFA_TextProvider *m_pTextProvider;
+};
+class CXFA_ImageLayoutData : public CXFA_WidgetLayoutData
+{
+public:
+ CXFA_ImageLayoutData()
+ : m_pDIBitmap(NULL)
+ , m_bNamedImage(FALSE)
+ , m_iImageXDpi(0)
+ , m_iImageYDpi(0)
+ {
+ }
+
+ ~CXFA_ImageLayoutData()
+ {
+ if(m_pDIBitmap && !m_bNamedImage) {
+ delete m_pDIBitmap;
+ }
+ m_pDIBitmap = NULL;
+ }
+
+ FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc)
+ {
+ if(m_pDIBitmap) {
+ return TRUE;
+ }
+ CXFA_Value value = pAcc->GetFormValue();
+ if (!value) {
+ return FALSE;
+ }
+ CXFA_Image imageObj = value.GetImage();
+ if (!imageObj) {
+ return FALSE;
+ }
+ CXFA_FFDoc *pFFDoc = pAcc->GetDoc();
+ pAcc->SetImageImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage, m_iImageXDpi, m_iImageYDpi));
+ return m_pDIBitmap != NULL;
+ }
+
+ CFX_DIBitmap* m_pDIBitmap;
+ FX_BOOL m_bNamedImage;
+ FX_INT32 m_iImageXDpi;
+ FX_INT32 m_iImageYDpi;
+};
+class CXFA_FieldLayoutData : public CXFA_WidgetLayoutData
+{
+public:
+ CXFA_FieldLayoutData()
+ : m_pCapTextLayout(NULL)
+ , m_pCapTextProvider(NULL)
+ , m_pTextOut(NULL)
+ , m_pFieldSplitArray(NULL)
+ {
+ }
+ ~CXFA_FieldLayoutData()
+ {
+ if (m_pCapTextLayout) {
+ delete m_pCapTextLayout;
+ }
+ m_pCapTextLayout = NULL;
+ if (m_pCapTextProvider) {
+ delete m_pCapTextProvider;
+ }
+ m_pCapTextProvider = NULL;
+ if (m_pTextOut) {
+ m_pTextOut->Release();
+ }
+ m_pTextOut = NULL;
+ if (m_pFieldSplitArray) {
+ m_pFieldSplitArray->RemoveAll();
+ delete m_pFieldSplitArray;
+ m_pFieldSplitArray = NULL;
+ }
+ }
+ FX_BOOL LoadCaption(CXFA_WidgetAcc* pAcc)
+ {
+ if (m_pCapTextLayout) {
+ return TRUE;
+ }
+ CXFA_Caption caption = pAcc->GetCaption();
+ if (caption.IsExistInXML() && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+ m_pCapTextProvider = FX_NEW CXFA_TextProvider(pAcc, XFA_TEXTPROVIDERTYPE_Caption);
+ m_pCapTextLayout = FX_NEW CXFA_TextLayout(m_pCapTextProvider);
+ return m_pCapTextLayout != NULL;
+ }
+ return FALSE;
+ }
+ CXFA_TextLayout *m_pCapTextLayout;
+ CXFA_TextProvider *m_pCapTextProvider;
+ IFDE_TextOut *m_pTextOut;
+ CFX_FloatArray *m_pFieldSplitArray;
+};
+class CXFA_TextEditData : public CXFA_FieldLayoutData
+{
+public:
+};
+class CXFA_ImageEditData : public CXFA_FieldLayoutData
+{
+public:
+ CXFA_ImageEditData()
+ : m_pDIBitmap(NULL)
+ , m_bNamedImage(FALSE)
+ , m_iImageXDpi(0)
+ , m_iImageYDpi(0)
+ {
+ }
+
+ ~CXFA_ImageEditData()
+ {
+ if(m_pDIBitmap && !m_bNamedImage) {
+ delete m_pDIBitmap;
+ }
+ m_pDIBitmap = NULL;
+ }
+ FX_BOOL LoadImageData(CXFA_WidgetAcc* pAcc)
+ {
+ if(m_pDIBitmap) {
+ return TRUE;
+ }
+ CXFA_Value value = pAcc->GetFormValue();
+ if (!value) {
+ return FALSE;
+ }
+ CXFA_Image imageObj = value.GetImage();
+ CXFA_FFDoc *pFFDoc = pAcc->GetDoc();
+ pAcc->SetImageEditImage(XFA_LoadImageData(pFFDoc, &imageObj, m_bNamedImage, m_iImageXDpi, m_iImageYDpi));
+ return m_pDIBitmap != NULL;
+ }
+ CFX_DIBitmap* m_pDIBitmap;
+ FX_BOOL m_bNamedImage;
+ FX_INT32 m_iImageXDpi;
+ FX_INT32 m_iImageYDpi;
+};
+CXFA_WidgetAcc::CXFA_WidgetAcc(CXFA_FFDocView* pDocView, CXFA_Node* pNode)
+ : CXFA_WidgetData(pNode)
+ , m_pDocView(pDocView)
+ , m_pLayoutData(NULL)
+{
+}
+CXFA_WidgetAcc::~CXFA_WidgetAcc()
+{
+ if (m_pLayoutData) {
+ m_pLayoutData->Release();
+ m_pLayoutData = NULL;
+ }
+}
+FX_BOOL CXFA_WidgetAcc::GetName(CFX_WideString &wsName, FX_INT32 iNameType )
+{
+ if (iNameType == 0) {
+ m_pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+ return !wsName.IsEmpty();
+ }
+ m_pNode->GetSOMExpression(wsName);
+ if (iNameType == 2 && wsName.GetLength() >= 15) {
+ CFX_WideStringC wsPre = FX_WSTRC(L"xfa[0].form[0].");
+ if (wsPre == CFX_WideStringC(wsName, wsPre.GetLength())) {
+ wsName.Delete(0, wsPre.GetLength());
+ }
+ }
+ return TRUE;
+}
+CXFA_Node* CXFA_WidgetAcc::GetDatasets()
+{
+ return m_pNode->GetBindData();
+}
+FX_BOOL CXFA_WidgetAcc::ProcessValueChanged()
+{
+ m_pDocView->AddValidateWidget(this);
+ m_pDocView->AddCalculateWidgetAcc(this);
+ m_pDocView->RunCalculateWidgets();
+ m_pDocView->RunValidate();
+ return TRUE;
+}
+void CXFA_WidgetAcc::ResetData()
+{
+ CFX_WideString wsValue;
+ XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
+ switch (eUIType) {
+ case XFA_ELEMENT_ImageEdit: {
+ CXFA_Value imageValue = GetDefaultValue();
+ CXFA_Image image = imageValue.GetImage();
+ CFX_WideString wsContentType, wsHref;
+ if (image) {
+ image.GetContent(wsValue);
+ image.GetContentType(wsContentType);
+ image.GetHref(wsHref);
+ }
+ SetImageEdit(wsContentType, wsHref, wsValue);
+ }
+ break;
+ case XFA_ELEMENT_ExclGroup: {
+ CXFA_Node* pNextChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
+ while (pNextChild) {
+ CXFA_Node* pChild = pNextChild;
+ CXFA_WidgetAcc* pAcc = (CXFA_WidgetAcc*)pChild->GetWidgetData();
+ if (!pAcc) {
+ continue;
+ }
+ CXFA_Value defValue(NULL);
+ if (wsValue.IsEmpty() && (defValue = pAcc->GetDefaultValue())) {
+ defValue.GetChildValueContent(wsValue);
+ this->SetValue(wsValue, XFA_VALUEPICTURE_Raw);
+ pAcc->SetValue(wsValue, XFA_VALUEPICTURE_Raw);
+ } else {
+ CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
+ if (!pItems) {
+ continue;
+ }
+ CFX_WideString itemText;
+ if (pItems->CountChildren(XFA_ELEMENT_UNKNOWN) > 1) {
+ itemText = pItems->GetChild(1, XFA_ELEMENT_UNKNOWN)->GetContent();
+ }
+ pAcc->SetValue(itemText, XFA_VALUEPICTURE_Raw);
+ }
+ pNextChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);
+ }
+ }
+ break;
+ case XFA_ELEMENT_ChoiceList:
+ ClearAllSelections();
+ default:
+ if (CXFA_Value defValue = GetDefaultValue()) {
+ defValue.GetChildValueContent(wsValue);
+ }
+ SetValue(wsValue, XFA_VALUEPICTURE_Raw);
+ break;
+ }
+}
+void CXFA_WidgetAcc::SetImageEdit(FX_WSTR wsContentType, FX_WSTR wsHref, FX_WSTR wsData)
+{
+ CXFA_Image image = GetFormValue().GetImage();
+ if (image) {
+ image.SetContentType(wsContentType);
+ image.SetHref(wsHref);
+ }
+ CFX_WideString wsFormatValue(wsData);
+ this->GetFormatDataValue(wsData, wsFormatValue);
+ m_pNode->SetContent(wsData, wsFormatValue, TRUE);
+ CXFA_Node* pBind = GetDatasets();
+ if (!pBind) {
+ image.SetTransferEncoding(XFA_ATTRIBUTEENUM_Base64);
+ return;
+ }
+ pBind->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+ CXFA_Node *pHrefNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pHrefNode) {
+ pHrefNode->SetCData(XFA_ATTRIBUTE_Value, wsHref);
+ } else {
+ IFDE_XMLNode *pXMLNode = pBind->GetXMLMappingNode();
+ FXSYS_assert(pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element);
+ ((IFDE_XMLElement*)pXMLNode)->SetString(FX_WSTRC(L"href"), wsHref);
+ }
+}
+
+CXFA_WidgetAcc* CXFA_WidgetAcc::GetExclGroup()
+{
+ CXFA_Node* pExcl = m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
+ return NULL;
+ }
+ return (CXFA_WidgetAcc*)pExcl->GetWidgetData();
+}
+CXFA_FFDocView* CXFA_WidgetAcc::GetDocView()
+{
+ return m_pDocView;
+}
+CXFA_FFDoc* CXFA_WidgetAcc::GetDoc()
+{
+ return (CXFA_FFDoc*)m_pDocView->GetDoc();
+}
+CXFA_FFApp* CXFA_WidgetAcc::GetApp()
+{
+ return GetDoc()->GetApp();
+}
+IXFA_AppProvider* CXFA_WidgetAcc::GetAppProvider()
+{
+ return GetApp()->GetAppProvider();
+}
+FX_INT32 CXFA_WidgetAcc::ProcessEvent(FX_INT32 iActivity, CXFA_EventParam* pEventParam)
+{
+ if (this->GetClassID() == XFA_ELEMENT_Draw) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ FX_INT32 iRet = XFA_EVENTERROR_NotExist;
+ CXFA_NodeArray eventArray;
+ FX_INT32 iCounts = GetEventByActivity(iActivity, eventArray, pEventParam->m_bIsFormReady);
+ for (FX_INT32 i = 0; i < iCounts; i++) {
+ CXFA_Event event(eventArray[i]);
+ FX_INT32 result = ProcessEvent(event, pEventParam);
+ if (i == 0) {
+ iRet = result;
+ } else if (result == XFA_EVENTERROR_Sucess) {
+ iRet = result;
+ }
+ }
+ return iRet;
+}
+FX_INT32 CXFA_WidgetAcc::ProcessEvent(CXFA_Event& event, CXFA_EventParam* pEventParam)
+{
+ if (!event) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ switch(event.GetEventType()) {
+ case XFA_ELEMENT_Execute:
+ break;
+ case XFA_ELEMENT_Script: {
+ CXFA_Script script = event.GetScript();
+ return ExecuteScript(script, pEventParam);
+ }
+ break;
+ case XFA_ELEMENT_SignData:
+ break;
+ case XFA_ELEMENT_Submit: {
+ CXFA_Submit submit = event.GetSubmit();
+ return GetDoc()->GetDocProvider()->SubmitData((XFA_HDOC)GetDoc(), submit);
+ }
+ default:
+ break;
+ }
+ return XFA_EVENTERROR_NotExist;
+}
+FX_INT32 CXFA_WidgetAcc::ProcessCalculate()
+{
+ if (this->GetClassID() == XFA_ELEMENT_Draw) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ CXFA_Calculate calc = this->GetCalculate();
+ if (!calc) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+ return XFA_EVENTERROR_Disabled;
+ }
+ CXFA_EventParam EventParam;
+ EventParam.m_eType = XFA_EVENT_Calculate;
+ CXFA_Script script = calc.GetScript();
+ FX_INT32 iRet = ExecuteScript(script, &EventParam);
+ if (iRet == XFA_EVENTERROR_Sucess) {
+ if (GetRawValue() != EventParam.m_wsResult) {
+ FX_BOOL bNotify = GetDoc()->GetDocType() == XFA_DOCTYPE_Static;
+ SetValue(EventParam.m_wsResult, XFA_VALUEPICTURE_Raw);
+ UpdateUIDisplay();
+ if (bNotify) {
+ NotifyEvent(XFA_WIDGETEVENT_PostContentChanged, NULL, NULL, NULL);
+ }
+ iRet = XFA_EVENTERROR_Sucess;
+ }
+ }
+ return iRet;
+}
+void CXFA_WidgetAcc::ProcessScriptTestValidate(CXFA_Validate validate, FX_INT32 iRet, FXJSE_HVALUE pRetValue, FX_BOOL bVersionFlag)
+{
+ if (iRet == XFA_EVENTERROR_Sucess && pRetValue) {
+ if (FXJSE_Value_IsBoolean(pRetValue) && !FXJSE_Value_ToBoolean(pRetValue)) {
+ IXFA_AppProvider* pAppProvider = GetAppProvider();
+ if (!pAppProvider) {
+ return;
+ }
+ CFX_WideString wsTitle;
+ pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+ CFX_WideString wsScriptMsg;
+ validate.GetScriptMessageText(wsScriptMsg);
+ FX_INT32 eScriptTest = validate.GetScriptTest();
+ if (eScriptTest == XFA_ATTRIBUTEENUM_Warning) {
+ if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+ return;
+ }
+ if (wsScriptMsg.IsEmpty()) {
+ GetValidateMessage(pAppProvider, wsScriptMsg, FALSE, bVersionFlag);
+ }
+ if (bVersionFlag) {
+ pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning, XFA_MB_OK);
+ return;
+ }
+ if (pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Warning, XFA_MB_YesNo) == XFA_IDYes) {
+ this->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+ }
+ } else {
+ if (wsScriptMsg.IsEmpty()) {
+ GetValidateMessage(pAppProvider, wsScriptMsg, TRUE, bVersionFlag);
+ }
+ pAppProvider->MsgBox(wsScriptMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
+ }
+ }
+ }
+}
+FX_INT32 CXFA_WidgetAcc::ProcessFormatTestValidate(CXFA_Validate validate, FX_BOOL bVersionFlag)
+{
+ CFX_WideString wsRawValue = GetRawValue();
+ if (!wsRawValue.IsEmpty()) {
+ CFX_WideString wsPicture;
+ validate.GetPicture(wsPicture);
+ if (wsPicture.IsEmpty()) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ IFX_Locale* pLocale = GetLocal();
+ if (!pLocale) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ CXFA_LocaleValue lcValue = XFA_GetLocaleValue(this);
+ if (!lcValue.ValidateValue(lcValue.GetValue(), wsPicture, pLocale)) {
+ IXFA_AppProvider* pAppProvider = GetAppProvider();
+ if (!pAppProvider) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ CFX_WideString wsFormatMsg;
+ validate.GetFormatMessageText(wsFormatMsg);
+ CFX_WideString wsTitle;
+ pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+ FX_INT32 eFormatTest = validate.GetFormatTest();
+ if (eFormatTest == XFA_ATTRIBUTEENUM_Error) {
+ if (wsFormatMsg.IsEmpty()) {
+ GetValidateMessage(pAppProvider, wsFormatMsg, TRUE, bVersionFlag);
+ }
+ pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Error, XFA_MB_OK);
+ return XFA_EVENTERROR_Sucess;
+ }
+ if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ if (wsFormatMsg.IsEmpty()) {
+ GetValidateMessage(pAppProvider, wsFormatMsg, FALSE, bVersionFlag);
+ }
+ if (bVersionFlag) {
+ pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning, XFA_MB_OK);
+ return XFA_EVENTERROR_Sucess;
+ }
+ if (pAppProvider->MsgBox(wsFormatMsg, wsTitle, XFA_MBICON_Warning, XFA_MB_YesNo) == XFA_IDYes) {
+ this->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+ }
+ return XFA_EVENTERROR_Sucess;
+ }
+ }
+ return XFA_EVENTERROR_NotExist;
+}
+FX_INT32 CXFA_WidgetAcc::ProcessNullTestValidate(CXFA_Validate validate, FX_INT32 iFlags, FX_BOOL bVersionFlag)
+{
+ CFX_WideString wsValue;
+ this->GetValue(wsValue, XFA_VALUEPICTURE_Raw);
+ if (!wsValue.IsEmpty()) {
+ return XFA_EVENTERROR_Sucess;
+ }
+ if (this->m_bIsNull && (this->m_bPreNull == this->m_bIsNull)) {
+ return XFA_EVENTERROR_Sucess;
+ }
+ FX_INT32 eNullTest = validate.GetNullTest();
+ CFX_WideString wsNullMsg;
+ validate.GetNullMessageText(wsNullMsg);
+ if (iFlags & 0x01) {
+ FX_INT32 iRet = XFA_EVENTERROR_Sucess;
+ if (eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
+ iRet = XFA_EVENTERROR_Error;
+ }
+ if (!wsNullMsg.IsEmpty()) {
+ if (eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
+ m_pDocView->m_arrNullTestMsg.Add(wsNullMsg);
+ return XFA_EVENTERROR_Error;
+ }
+ return XFA_EVENTERROR_Sucess;
+ }
+ return iRet;
+ }
+ if (wsNullMsg.IsEmpty() && bVersionFlag && eNullTest != XFA_ATTRIBUTEENUM_Disabled) {
+ return XFA_EVENTERROR_Error;
+ }
+ IXFA_AppProvider* pAppProvider = GetAppProvider();
+ if (!pAppProvider) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ CFX_WideString wsCaptionName;
+ CFX_WideString wsTitle;
+ pAppProvider->LoadString(XFA_IDS_AppName, wsTitle);
+ switch (eNullTest) {
+ case XFA_ATTRIBUTEENUM_Error: {
+ if (wsNullMsg.IsEmpty()) {
+ GetValidateCaptionName(wsCaptionName, bVersionFlag);
+ CFX_WideString wsError;
+ pAppProvider->LoadString(XFA_IDS_ValidateNullError, wsError);
+ wsNullMsg.Format(wsError, (FX_LPCWSTR)wsCaptionName);
+ }
+ pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Status, XFA_MB_OK);
+ return XFA_EVENTERROR_Error;
+ }
+ case XFA_ATTRIBUTEENUM_Warning: {
+ if (this->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+ return TRUE;
+ }
+ if (wsNullMsg.IsEmpty()) {
+ GetValidateCaptionName(wsCaptionName, bVersionFlag);
+ CFX_WideString wsWarning;
+ pAppProvider->LoadString(XFA_IDS_ValidateNullWarning, wsWarning);
+ wsNullMsg.Format(wsWarning, (FX_LPCWSTR)wsCaptionName, (FX_LPCWSTR)wsCaptionName);
+ }
+ if (pAppProvider->MsgBox(wsNullMsg, wsTitle, XFA_MBICON_Warning, XFA_MB_YesNo) == XFA_IDYes) {
+ this->GetNode()->SetFlag(XFA_NODEFLAG_UserInteractive, TRUE, FALSE);
+ }
+ return XFA_EVENTERROR_Error;
+ }
+ case XFA_ATTRIBUTEENUM_Disabled:
+ default:
+ break;
+ }
+ return XFA_EVENTERROR_Sucess;
+}
+void CXFA_WidgetAcc::GetValidateCaptionName(CFX_WideString& wsCaptionName, FX_BOOL bVersionFlag)
+{
+ if (!bVersionFlag) {
+ CXFA_Caption caption = GetCaption();
+ if (caption) {
+ CXFA_Value capValue = caption.GetValue();
+ if (capValue) {
+ CXFA_Text capText = capValue.GetText();
+ if (capText) {
+ capText.GetContent(wsCaptionName);
+ }
+ }
+ }
+ }
+ if (wsCaptionName.IsEmpty()) {
+ GetName(wsCaptionName);
+ }
+}
+void CXFA_WidgetAcc::GetValidateMessage(IXFA_AppProvider* pAppProvider, CFX_WideString& wsMessage, FX_BOOL bError, FX_BOOL bVersionFlag)
+{
+ CFX_WideString wsCaptionName;
+ GetValidateCaptionName(wsCaptionName, bVersionFlag);
+ CFX_WideString wsError;
+ if (bVersionFlag) {
+ pAppProvider->LoadString(XFA_IDS_ValidateFailed, wsError);
+ wsMessage.Format(wsError, (FX_LPCWSTR)wsCaptionName);
+ return;
+ }
+ if (bError) {
+ pAppProvider->LoadString(XFA_IDS_ValidateError, wsError);
+ wsMessage.Format(wsError, (FX_LPCWSTR)wsCaptionName);
+ return;
+ }
+ CFX_WideString wsWarning;
+ pAppProvider->LoadString(XFA_IDS_ValidateWarning, wsWarning);
+ wsMessage.Format(wsWarning, (FX_LPCWSTR)wsCaptionName, (FX_LPCWSTR)wsCaptionName);
+}
+FX_INT32 CXFA_WidgetAcc::ProcessValidate(FX_INT32 iFlags)
+{
+ if (this->GetClassID() == XFA_ELEMENT_Draw) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ CXFA_Validate validate = this->GetValidate();
+ if (!validate) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ FX_BOOL bInitDoc = ((CXFA_Node*)validate)->HasFlag(XFA_NODEFLAG_NeedsInitApp);
+ FX_BOOL bStatus = m_pDocView->GetLayoutStatus() < XFA_DOCVIEW_LAYOUTSTATUS_End;
+ FX_INT32 iFormat = 0;
+ FXJSE_HVALUE pRetValue = NULL;
+ FX_INT32 iRet = XFA_EVENTERROR_NotExist;
+ CXFA_Script script = validate.GetScript();
+ if (script) {
+ CXFA_EventParam eParam;
+ eParam.m_eType = XFA_EVENT_Validate;
+ eParam.m_pTarget = this;
+ iRet = ExecuteScript(script, &eParam, ((bInitDoc || bStatus) && this->GetRawValue().IsEmpty()) ? NULL : &pRetValue);
+ }
+ XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
+ FX_BOOL bVersionFlag = FALSE;
+ if (version < XFA_VERSION_208) {
+ bVersionFlag = TRUE;
+ }
+ if (bInitDoc) {
+ ((CXFA_Node*)validate)->SetFlag(XFA_NODEFLAG_NeedsInitApp, FALSE, FALSE);
+ } else {
+ iFormat = ProcessFormatTestValidate(validate, bVersionFlag);
+ if (!bVersionFlag) {
+ bVersionFlag = GetDoc()->GetXFADoc()->HasFlag(XFA_DOCFLAG_Scripting);
+ }
+ iRet |= ProcessNullTestValidate(validate, iFlags, bVersionFlag);
+ }
+ if (iFormat != XFA_EVENTERROR_Sucess) {
+ ProcessScriptTestValidate(validate, iRet, pRetValue, bVersionFlag);
+ }
+ if (pRetValue) {
+ FXJSE_Value_Release(pRetValue);
+ }
+ return iRet | iFormat;
+}
+FX_INT32 CXFA_WidgetAcc::ExecuteScript(CXFA_Script script, CXFA_EventParam* pEventParam, FXJSE_HVALUE* pRetValue)
+{
+ FXSYS_assert(pEventParam);
+ if (!script) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ if(script.GetRunAt() == XFA_ATTRIBUTEENUM_Server) {
+ return XFA_EVENTERROR_Disabled;
+ }
+ CFX_WideString wsExpression;
+ script.GetExpression(wsExpression);
+ if (wsExpression.IsEmpty()) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ XFA_SCRIPTTYPE eScriptType = script.GetContentType();
+ if (eScriptType == XFA_SCRIPTTYPE_Unkown) {
+ return XFA_EVENTERROR_Sucess;
+ }
+ CXFA_FFDoc* pDoc = GetDoc();
+ IXFA_ScriptContext* pContext = pDoc->GetXFADoc()->GetScriptContext();
+ pContext->SetEventParam(pEventParam);
+ pContext->SetRunAtType((XFA_ATTRIBUTEENUM)script.GetRunAt());
+ CXFA_NodeArray refNodes;
+ if (pEventParam->m_eType == XFA_EVENT_InitCalculate || pEventParam->m_eType == XFA_EVENT_Calculate) {
+ pContext->SetNodesOfRunScript(&refNodes);
+ }
+ FXJSE_HVALUE hRetValue = FXJSE_Value_Create(pContext->GetRuntime());
+ FX_BOOL bRet = FALSE;
+ bRet = pContext->RunScript((XFA_SCRIPTLANGTYPE)eScriptType, wsExpression, hRetValue, m_pNode);
+ FX_INT32 iRet = XFA_EVENTERROR_Error;
+ if (bRet) {
+ iRet = XFA_EVENTERROR_Sucess;
+ if (pEventParam->m_eType == XFA_EVENT_Calculate || pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+ if (!FXJSE_Value_IsUndefined(hRetValue)) {
+ if (!FXJSE_Value_IsNull(hRetValue)) {
+ CFX_ByteString bsString;
+ FXJSE_Value_ToUTF8String(hRetValue, bsString);
+ pEventParam->m_wsResult = CFX_WideString::FromUTF8(bsString, bsString.GetLength());
+ }
+ iRet = XFA_EVENTERROR_Sucess;
+ } else {
+ iRet = XFA_EVENTERROR_Error;
+ }
+ if (pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+ if ((iRet == XFA_EVENTERROR_Sucess) && (GetRawValue() != pEventParam->m_wsResult)) {
+ SetValue(pEventParam->m_wsResult, XFA_VALUEPICTURE_Raw);
+ m_pDocView->AddValidateWidget(this);
+ }
+ }
+ FX_INT32 iRefs = refNodes.GetSize();
+ for (FX_INT32 r = 0; r < iRefs; r++) {
+ CXFA_WidgetAcc* pRefAcc = (CXFA_WidgetAcc*)refNodes[r]->GetWidgetData();
+ if (pRefAcc && pRefAcc == this) {
+ continue;
+ }
+ CXFA_Node* pRefNode = refNodes[r];
+ CXFA_CalcData* pGlobalData = (CXFA_CalcData*)pRefNode->GetUserData(XFA_CalcData);
+ if (!pGlobalData) {
+ pGlobalData = FX_NEW CXFA_CalcData;
+ pRefNode->SetUserData(XFA_CalcData, pGlobalData, &gs_XFADeleteCalcData);
+ }
+ if (pGlobalData->m_Globals.Find(this) < 0) {
+ pGlobalData->m_Globals.Add(this);
+ }
+ }
+ }
+ }
+ if (pRetValue) {
+ *pRetValue = hRetValue;
+ } else {
+ FXJSE_Value_Release(hRetValue);
+ }
+ pContext->SetNodesOfRunScript(NULL);
+ return iRet;
+}
+CXFA_FFWidget* CXFA_WidgetAcc::GetNextWidget(CXFA_FFWidget* pWidget)
+{
+ CXFA_LayoutItem* pLayout = NULL;
+ if (pWidget) {
+ pLayout = pWidget->GetLayoutItem()->GetNext();
+ } else {
+ pLayout = m_pDocView->GetXFALayout()->GetLayoutItem(m_pNode);
+ }
+ return (CXFA_FFWidget*)(CXFA_ContentLayoutItemImpl*)pLayout;
+}
+void CXFA_WidgetAcc::UpdateUIDisplay(CXFA_FFWidget* pExcept )
+{
+ CXFA_FFWidget* pWidget = NULL;
+ while ((pWidget = this->GetNextWidget(pWidget)) != NULL) {
+ if (pWidget == pExcept || !pWidget->IsLoaded() || (GetUIType() != XFA_ELEMENT_CheckButton && pWidget->IsFocused())) {
+ continue;
+ }
+ pWidget->UpdateFWLData();
+ pWidget->AddInvalidateRect();
+ }
+}
+void CXFA_WidgetAcc::NotifyEvent(FX_DWORD dwEvent, CXFA_FFWidget* pWidget , FX_LPVOID pParam , FX_LPVOID pAdditional )
+{
+ IXFA_DocProvider* pDocProvider = GetDoc()->GetDocProvider();
+ if (pWidget) {
+ pDocProvider->WidgetEvent((XFA_HWIDGET)pWidget, this, dwEvent, pParam, pAdditional);
+ } else {
+ pWidget = GetNextWidget(pWidget);
+ if (pWidget == NULL) {
+ pDocProvider->WidgetEvent(NULL, this, dwEvent, pParam, pAdditional);
+ return;
+ }
+ while (pWidget) {
+ pDocProvider->WidgetEvent((XFA_HWIDGET)pWidget, this, dwEvent, pParam, pAdditional);
+ pWidget = GetNextWidget(pWidget);
+ }
+ }
+}
+void CXFA_WidgetAcc::CalcCaptionSize(CFX_SizeF &szCap)
+{
+ CXFA_Caption caption = this->GetCaption();
+ if (!caption.IsExistInXML() || caption.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+ return;
+ }
+ LoadCaption();
+ XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
+ FX_INT32 iCapPlacement = caption.GetPlacementType();
+ FX_FLOAT fCapReserve = caption.GetReserve();
+ FX_BOOL bVert = iCapPlacement == XFA_ATTRIBUTEENUM_Top || iCapPlacement == XFA_ATTRIBUTEENUM_Bottom;
+ FX_BOOL bReserveExit = fCapReserve > 0.01;
+ CXFA_TextLayout* pCapTextLayout = ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout;
+ if (pCapTextLayout) {
+ if (!bVert && eUIType != XFA_ELEMENT_Button) {
+ szCap.x = fCapReserve;
+ }
+ CFX_SizeF minSize;
+ minSize.Set(0, 0);
+ pCapTextLayout->CalcSize(minSize, szCap, szCap);
+ if (bReserveExit) {
+ bVert ? szCap.y = fCapReserve : szCap.x = fCapReserve;
+ }
+ } else {
+ FX_FLOAT fFontSize = 10.0f;
+ if (CXFA_Font font = caption.GetFont()) {
+ fFontSize = font.GetFontSize();
+ } else if (CXFA_Font widgetfont = GetFont()) {
+ fFontSize = widgetfont.GetFontSize();
+ }
+ if (bVert) {
+ szCap.y = fCapReserve > 0 ? fCapReserve : fFontSize;
+ } else {
+ szCap.x = fCapReserve > 0 ? fCapReserve : 0;
+ szCap.y = fFontSize;
+ }
+ }
+ if (CXFA_Margin mgCap = caption.GetMargin()) {
+ FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+ mgCap.GetLeftInset(fLeftInset);
+ mgCap.GetTopInset(fTopInset);
+ mgCap.GetRightInset(fRightInset);
+ mgCap.GetBottomInset(fBottomInset);
+ if (bReserveExit) {
+ bVert ? (szCap.x += fLeftInset + fRightInset) : (szCap.y += fTopInset + fBottomInset);
+ } else {
+ szCap.x += fLeftInset + fRightInset;
+ szCap.y += fTopInset + fBottomInset;
+ }
+ }
+}
+FX_BOOL CXFA_WidgetAcc::CalculateFieldAutoSize(CFX_SizeF &size)
+{
+ CFX_SizeF szCap;
+ szCap.Set(0, 0);
+ CalcCaptionSize(szCap);
+ CFX_RectF rtUIMargin;
+ GetUIMargin(rtUIMargin);
+ size.x += rtUIMargin.left + rtUIMargin.width;
+ size.y += rtUIMargin.top + rtUIMargin.height;
+ if (szCap.x > 0 && szCap.y > 0) {
+ FX_INT32 iCapPlacement = this->GetCaption().GetPlacementType();
+ switch(iCapPlacement) {
+ case XFA_ATTRIBUTEENUM_Left:
+ case XFA_ATTRIBUTEENUM_Right:
+ case XFA_ATTRIBUTEENUM_Inline: {
+ size.x += szCap.x;
+ size.y = FX_MAX(size.y, szCap.y);
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Top:
+ case XFA_ATTRIBUTEENUM_Bottom: {
+ size.y += szCap.y;
+ size.x = FX_MAX(size.x, szCap.x);
+ }
+ default:
+ break;
+ }
+ }
+ return CalculateWidgetAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateWidgetAutoSize(CFX_SizeF &size)
+{
+ CXFA_Margin mgWidget = this->GetMargin();
+ if (mgWidget.IsExistInXML()) {
+ FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+ mgWidget.GetLeftInset(fLeftInset);
+ mgWidget.GetTopInset(fTopInset);
+ mgWidget.GetRightInset(fRightInset);
+ mgWidget.GetBottomInset(fBottomInset);
+ size.x += fLeftInset + fRightInset;
+ size.y += fTopInset + fBottomInset;
+ }
+ CXFA_Para para = this->GetPara();
+ if (para.IsExistInXML()) {
+ size.x += para.GetMarginLeft();
+ size.x += para.GetTextIndent();
+ }
+ FX_FLOAT fVal = 0, fMin = 0, fMax = 0;
+ if (this->GetWidth(fVal)) {
+ size.x = fVal;
+ } else {
+ if (this->GetMinWidth(fMin)) {
+ size.x = FX_MAX(size.x, fMin);
+ }
+ if (this->GetMaxWidth(fMax) && fMax > 0) {
+ size.x = FX_MIN(size.x, fMax);
+ }
+ }
+ fVal = 0, fMin = 0, fMax = 0;
+ if (this->GetHeight(fVal)) {
+ size.y = fVal;
+ } else {
+ if (this->GetMinHeight(fMin)) {
+ size.y = FX_MAX(size.y, fMin);
+ }
+ if (this->GetMaxHeight(fMax) && fMax > 0) {
+ size.y = FX_MIN(size.y, fMax);
+ }
+ }
+ return TRUE;
+}
+void CXFA_WidgetAcc::CalculateTextContentSize(CFX_SizeF &size)
+{
+ FX_FLOAT fFontSize = GetFontSize();
+ CFX_WideString wsText;
+ this->GetValue(wsText, XFA_VALUEPICTURE_Display);
+ if (wsText.IsEmpty()) {
+ size.y += fFontSize;
+ return;
+ }
+ FX_WCHAR wcEnter = '\n';
+ FX_WCHAR wsLast = wsText.GetAt(wsText.GetLength() - 1);
+ if(wsLast == wcEnter) {
+ wsText = wsText + wcEnter;
+ }
+ if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut) {
+ ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut = IFDE_TextOut::Create();
+ IFDE_TextOut* pTextOut = ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut;
+ pTextOut->SetFont(GetFDEFont());
+ pTextOut->SetFontSize(fFontSize);
+ pTextOut->SetLineBreakTolerance(fFontSize * 0.2f);
+ pTextOut->SetLineSpace(GetLineHeight());
+ FX_DWORD dwStyles = FDE_TTOSTYLE_LastLineHeight;
+ if (GetUIType() == XFA_ELEMENT_TextEdit && IsMultiLine()) {
+ dwStyles |= FDE_TTOSTYLE_LineWrap;
+ }
+ pTextOut->SetStyles(dwStyles);
+ }
+ ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut->CalcLogicSize(wsText, wsText.GetLength(), size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateTextEditAutoSize(CFX_SizeF &size)
+{
+ if (size.x > 0) {
+ CFX_SizeF szOrz = size;
+ CFX_SizeF szCap;
+ szCap.Set(0, 0);
+ CalcCaptionSize(szCap);
+ FX_BOOL bCapExit = szCap.x > 0.01 && szCap.y > 0.01;
+ FX_INT32 iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
+ if (bCapExit) {
+ iCapPlacement = this->GetCaption().GetPlacementType();
+ switch(iCapPlacement) {
+ case XFA_ATTRIBUTEENUM_Left:
+ case XFA_ATTRIBUTEENUM_Right:
+ case XFA_ATTRIBUTEENUM_Inline: {
+ size.x -= szCap.x;
+ }
+ default:
+ break;
+ }
+ }
+ CFX_RectF rtUIMargin;
+ GetUIMargin(rtUIMargin);
+ size.x -= rtUIMargin.left + rtUIMargin.width;
+ CXFA_Margin mgWidget = this->GetMargin();
+ if (mgWidget.IsExistInXML()) {
+ FX_FLOAT fLeftInset, fRightInset;
+ mgWidget.GetLeftInset(fLeftInset);
+ mgWidget.GetRightInset(fRightInset);
+ size.x -= fLeftInset + fRightInset;
+ }
+ CalculateTextContentSize(size);
+ size.y += rtUIMargin.top + rtUIMargin.height;
+ if (bCapExit) {
+ switch(iCapPlacement) {
+ case XFA_ATTRIBUTEENUM_Left:
+ case XFA_ATTRIBUTEENUM_Right:
+ case XFA_ATTRIBUTEENUM_Inline: {
+ size.y = FX_MAX(size.y, szCap.y);
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Top:
+ case XFA_ATTRIBUTEENUM_Bottom: {
+ size.y += szCap.y;
+ }
+ default:
+ break;
+ }
+ }
+ size.x = szOrz.x;
+ return CalculateWidgetAutoSize(size);
+ }
+ CalculateTextContentSize(size);
+ return CalculateFieldAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateCheckButtonAutoSize(CFX_SizeF &size)
+{
+ FX_FLOAT fCheckSize = this->GetCheckButtonSize();
+ size.x = size.y = fCheckSize;
+ return CalculateFieldAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculatePushButtonAutoSize(CFX_SizeF &size)
+{
+ CalcCaptionSize(size);
+ return CalculateWidgetAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateImageAutoSize(CFX_SizeF &size)
+{
+ if (!GetImageImage()) {
+ LoadImageImage();
+ }
+ size.Set(0, 0);
+ if (CFX_DIBitmap* pBitmap = GetImageImage()) {
+ CXFA_Image imageObj = GetFormValue().GetImage();
+ CFX_RectF rtImage, rtFit;
+ rtImage.Set(0, 0, 0, 0);
+ rtFit.Set(0, 0, 0, 0);
+ FX_INT32 iImageXDpi = 0;
+ FX_INT32 iImageYDpi = 0;
+ GetImageDpi(iImageXDpi, iImageYDpi);
+ rtImage.width = XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
+ rtImage.height = XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
+ if(GetWidth(rtFit.width)) {
+ GetWidthWithoutMargin(rtFit.width);
+ } else {
+ rtFit.width = rtImage.width;
+ }
+ if(GetHeight(rtFit.height)) {
+ GetHeightWithoutMargin(rtFit.height);
+ } else {
+ rtFit.height = rtImage.height;
+ }
+ size.x = rtFit.width;
+ size.y = rtFit.height;
+ }
+ return CalculateWidgetAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::CalculateImageEditAutoSize(CFX_SizeF &size)
+{
+ if (!GetImageEditImage()) {
+ LoadImageEditImage();
+ }
+ size.Set(0, 0);
+ if (CFX_DIBitmap* pBitmap = GetImageEditImage()) {
+ CFX_RectF rtImage, rtFit;
+ rtImage.Set(0, 0, 0, 0);
+ rtFit.Set(0, 0, 0, 0);
+ FX_INT32 iImageXDpi = 0;
+ FX_INT32 iImageYDpi = 0;
+ GetImageEditDpi(iImageXDpi, iImageYDpi);
+ rtImage.width = XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
+ rtImage.height = XFA_UnitPx2Pt((FX_FLOAT)pBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
+ if(GetWidth(rtFit.width)) {
+ GetWidthWithoutMargin(rtFit.width);
+ } else {
+ rtFit.width = rtImage.width;
+ }
+ if(GetHeight(rtFit.height)) {
+ GetHeightWithoutMargin(rtFit.height);
+ } else {
+ rtFit.height = rtImage.height;
+ }
+ size.x = rtFit.width;
+ size.y = rtFit.height;
+ }
+ return CalculateFieldAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::LoadImageImage()
+{
+ InitLayoutData();
+ return ((CXFA_ImageLayoutData*)m_pLayoutData)->LoadImageData(this);
+}
+FX_BOOL CXFA_WidgetAcc::LoadImageEditImage()
+{
+ InitLayoutData();
+ return ((CXFA_ImageEditData*)m_pLayoutData)->LoadImageData(this);
+}
+void CXFA_WidgetAcc::GetImageDpi(FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi)
+{
+ iImageXDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageXDpi;
+ iImageYDpi = ((CXFA_ImageLayoutData*)m_pLayoutData)->m_iImageYDpi;
+}
+void CXFA_WidgetAcc::GetImageEditDpi(FX_INT32 &iImageXDpi, FX_INT32 &iImageYDpi)
+{
+ iImageXDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageXDpi;
+ iImageYDpi = ((CXFA_ImageEditData*)m_pLayoutData)->m_iImageYDpi;
+}
+FX_BOOL CXFA_WidgetAcc::CalculateTextAutoSize(CFX_SizeF &size)
+{
+ if (!LoadText()) {
+ return FALSE;
+ }
+ CXFA_TextLayout* pTextLayout = ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
+ if (pTextLayout) {
+ size.x = pTextLayout->StartLayout(size.x);
+ size.y = pTextLayout->GetLayoutHeight();
+ }
+ return CalculateWidgetAutoSize(size);
+}
+FX_BOOL CXFA_WidgetAcc::LoadText()
+{
+ InitLayoutData();
+ return ((CXFA_TextLayoutData*)m_pLayoutData)->LoadText(this);
+}
+FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoWidth(FX_FLOAT fWidthCalc)
+{
+ CXFA_Margin mgWidget = this->GetMargin();
+ if (mgWidget.IsExistInXML()) {
+ FX_FLOAT fLeftInset, fRightInset;
+ mgWidget.GetLeftInset(fLeftInset);
+ mgWidget.GetRightInset(fRightInset);
+ fWidthCalc += fLeftInset + fRightInset;
+ }
+ FX_FLOAT fMin = 0, fMax = 0;
+ if (this->GetMinWidth(fMin)) {
+ fWidthCalc = FX_MAX(fWidthCalc, fMin);
+ }
+ if (this->GetMaxWidth(fMax) && fMax > 0) {
+ fWidthCalc = FX_MIN(fWidthCalc, fMax);
+ }
+ return fWidthCalc;
+}
+FX_FLOAT CXFA_WidgetAcc::GetWidthWithoutMargin(FX_FLOAT fWidthCalc)
+{
+ CXFA_Margin mgWidget = this->GetMargin();
+ if (mgWidget.IsExistInXML()) {
+ FX_FLOAT fLeftInset, fRightInset;
+ mgWidget.GetLeftInset(fLeftInset);
+ mgWidget.GetRightInset(fRightInset);
+ fWidthCalc -= fLeftInset + fRightInset;
+ }
+ return fWidthCalc;
+}
+FX_FLOAT CXFA_WidgetAcc::CalculateWidgetAutoHeight(FX_FLOAT fHeightCalc)
+{
+ CXFA_Margin mgWidget = this->GetMargin();
+ if (mgWidget.IsExistInXML()) {
+ FX_FLOAT fTopInset, fBottomInset;
+ mgWidget.GetTopInset(fTopInset);
+ mgWidget.GetBottomInset(fBottomInset);
+ fHeightCalc += fTopInset + fBottomInset;
+ }
+ FX_FLOAT fMin = 0, fMax = 0;
+ if (this->GetMinHeight(fMin)) {
+ fHeightCalc = FX_MAX(fHeightCalc, fMin);
+ }
+ if (this->GetMaxHeight(fMax) && fMax > 0) {
+ fHeightCalc = FX_MIN(fHeightCalc, fMax);
+ }
+ return fHeightCalc;
+}
+FX_FLOAT CXFA_WidgetAcc::GetHeightWithoutMargin(FX_FLOAT fHeightCalc)
+{
+ CXFA_Margin mgWidget = this->GetMargin();
+ if (mgWidget.IsExistInXML()) {
+ FX_FLOAT fTopInset, fBottomInset;
+ mgWidget.GetTopInset(fTopInset);
+ mgWidget.GetBottomInset(fBottomInset);
+ fHeightCalc -= fTopInset + fBottomInset;
+ }
+ return fHeightCalc;
+}
+void CXFA_WidgetAcc::StartWidgetLayout(FX_FLOAT &fCalcWidth, FX_FLOAT& fCalcHeight)
+{
+ InitLayoutData();
+ XFA_ELEMENT eUIType = GetUIType();
+ if (eUIType == XFA_ELEMENT_Text) {
+ m_pLayoutData->m_fWidgetHeight = -1;
+ GetHeight(m_pLayoutData->m_fWidgetHeight);
+ StartTextLayout(fCalcWidth, fCalcHeight);
+ return;
+ }
+ if (fCalcWidth > 0 && fCalcHeight > 0) {
+ return;
+ }
+ m_pLayoutData->m_fWidgetHeight = -1;
+ FX_FLOAT fWidth = 0;
+ if (fCalcWidth > 0 && fCalcHeight < 0) {
+ if (!GetHeight(fCalcHeight)) {
+ CalculateAccWidthAndHeight(eUIType, fCalcWidth, fCalcHeight);
+ }
+ m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+ return;
+ }
+ if (fCalcWidth < 0 && fCalcHeight < 0) {
+ if (!GetWidth(fWidth) || !GetHeight(fCalcHeight)) {
+ CalculateAccWidthAndHeight(eUIType, fWidth, fCalcHeight);
+ }
+ fCalcWidth = fWidth;
+ }
+ m_pLayoutData->m_fWidgetHeight = fCalcHeight;
+}
+void CXFA_WidgetAcc::CalculateAccWidthAndHeight(XFA_ELEMENT eUIType, FX_FLOAT& fWidth, FX_FLOAT& fCalcHeight)
+{
+ CFX_SizeF sz;
+ sz.Set(fWidth, m_pLayoutData->m_fWidgetHeight);
+ switch(eUIType) {
+ case XFA_ELEMENT_Barcode:
+ case XFA_ELEMENT_ChoiceList:
+ case XFA_ELEMENT_Signature:
+ CalculateFieldAutoSize(sz);
+ break;
+ case XFA_ELEMENT_ImageEdit:
+ CalculateImageEditAutoSize(sz);
+ break;
+ case XFA_ELEMENT_Button:
+ CalculatePushButtonAutoSize(sz);
+ break;
+ case XFA_ELEMENT_CheckButton:
+ CalculateCheckButtonAutoSize(sz);
+ break;
+ case XFA_ELEMENT_DateTimeEdit:
+ case XFA_ELEMENT_NumericEdit:
+ case XFA_ELEMENT_PasswordEdit:
+ case XFA_ELEMENT_TextEdit:
+ CalculateTextEditAutoSize(sz);
+ break;
+ case XFA_ELEMENT_Image:
+ CalculateImageAutoSize(sz);
+ break;
+ case XFA_ELEMENT_Arc:
+ case XFA_ELEMENT_Line:
+ case XFA_ELEMENT_Rectangle:
+ case XFA_ELEMENT_Subform:
+ case XFA_ELEMENT_ExclGroup:
+ CalculateWidgetAutoSize(sz);
+ break;
+ default:
+ break;
+ }
+ fWidth = sz.x;
+ m_pLayoutData->m_fWidgetHeight = sz.y;
+ fCalcHeight = sz.y;
+}
+FX_BOOL CXFA_WidgetAcc::FindSplitPos(FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeight)
+{
+ XFA_ELEMENT eUIType = (XFA_ELEMENT)GetUIType();
+ if (eUIType == XFA_ELEMENT_Subform) {
+ return FALSE;
+ }
+ if (eUIType != XFA_ELEMENT_Text && eUIType != XFA_ELEMENT_TextEdit && eUIType != XFA_ELEMENT_NumericEdit && eUIType != XFA_ELEMENT_PasswordEdit) {
+ fCalcHeight = 0;
+ return TRUE;
+ }
+ FX_FLOAT fTopInset = 0;
+ FX_FLOAT fBottomInset = 0;
+ if (iBlockIndex == 0) {
+ CXFA_Margin mgWidget = this->GetMargin();
+ if (mgWidget.IsExistInXML()) {
+ mgWidget.GetTopInset(fTopInset);
+ mgWidget.GetBottomInset(fBottomInset);
+ }
+ CFX_RectF rtUIMargin;
+ this->GetUIMargin(rtUIMargin);
+ fTopInset += rtUIMargin.top;
+ fBottomInset += rtUIMargin.width;
+ }
+ if (eUIType == XFA_ELEMENT_Text) {
+ FX_FLOAT fHeight = fCalcHeight;
+ if (iBlockIndex == 0) {
+ fCalcHeight = fCalcHeight - fTopInset;
+ if (fCalcHeight < 0) {
+ fCalcHeight = 0;
+ }
+ }
+ CXFA_TextLayout* pTextLayout = ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
+ pTextLayout->DoLayout(iBlockIndex, fCalcHeight, fCalcHeight, m_pLayoutData->m_fWidgetHeight - fTopInset);
+ if (fCalcHeight != 0) {
+ if (iBlockIndex == 0) {
+ fCalcHeight = fCalcHeight + fTopInset;
+ }
+ if (fabs(fHeight - fCalcHeight) < XFA_FLOAT_PERCISION) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ XFA_ATTRIBUTEENUM iCapPlacement = XFA_ATTRIBUTEENUM_Unknown;
+ FX_FLOAT fCapReserve = 0;
+ if (iBlockIndex == 0) {
+ CXFA_Caption caption = GetCaption();
+ if (caption.IsExistInXML() && caption.GetPresence() != XFA_ATTRIBUTEENUM_Hidden) {
+ iCapPlacement = (XFA_ATTRIBUTEENUM)caption.GetPlacementType();
+ fCapReserve = caption.GetReserve();
+ }
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Top && fCalcHeight < fCapReserve + fTopInset) {
+ fCalcHeight = 0;
+ return TRUE;
+ }
+ if (iCapPlacement == XFA_ATTRIBUTEENUM_Bottom && m_pLayoutData->m_fWidgetHeight - fCapReserve - fBottomInset) {
+ fCalcHeight = 0;
+ return TRUE;
+ }
+ if (iCapPlacement != XFA_ATTRIBUTEENUM_Top) {
+ fCapReserve = 0;
+ }
+ }
+ FX_INT32 iLinesCount = 0;
+ FX_FLOAT fHeight = m_pLayoutData->m_fWidgetHeight;
+ CFX_WideString wsText;
+ this->GetValue(wsText, XFA_VALUEPICTURE_Display);
+ if (wsText.IsEmpty()) {
+ iLinesCount = 1;
+ } else {
+ if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut) {
+ FX_FLOAT fWidth = 0;
+ GetWidth(fWidth);
+ CalculateAccWidthAndHeight(eUIType, fWidth, fHeight);
+ }
+ iLinesCount = ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pTextOut->GetTotalLines();
+ }
+ if (!((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray) {
+ ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray = FX_NEW CFX_FloatArray;
+ }
+ CFX_FloatArray* pFieldArray = ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pFieldSplitArray;
+ FX_INT32 iFieldSplitCount = pFieldArray->GetSize();
+ for (FX_INT32 i = 0; i < iBlockIndex * 3; i += 3) {
+ iLinesCount -= (FX_INT32)pFieldArray->GetAt(i + 1);
+ fHeight -= pFieldArray->GetAt(i + 2);
+ }
+ if (iLinesCount == 0) {
+ return FALSE;
+ }
+ FX_FLOAT fLineHeight = GetLineHeight();
+ FX_FLOAT fFontSize = GetFontSize();
+ FX_FLOAT fTextHeight = iLinesCount * fLineHeight - fLineHeight + fFontSize;
+ FX_FLOAT fSpaceAbove = 0;
+ FX_FLOAT fStartOffset = 0;
+ if (fHeight > 0.1f && iBlockIndex == 0) {
+ fStartOffset = fTopInset;
+ fHeight -= (fTopInset + fBottomInset);
+ if (CXFA_Para para = this->GetPara()) {
+ fSpaceAbove = para.GetSpaceAbove();
+ FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
+ fHeight -= (fSpaceAbove + fSpaceBelow);
+ switch (para.GetVerticalAlign()) {
+ case XFA_ATTRIBUTEENUM_Top:
+ fStartOffset += fSpaceAbove;
+ break;
+ case XFA_ATTRIBUTEENUM_Middle:
+ fStartOffset += ((fHeight - fTextHeight) / 2 + fSpaceAbove);
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom:
+ fStartOffset += (fHeight - fTextHeight + fSpaceAbove);
+ break;
+ }
+ }
+ if (fStartOffset < 0.1f) {
+ fStartOffset = 0;
+ }
+ }
+ for (FX_INT32 i = iBlockIndex - 1; iBlockIndex > 0 && i < iBlockIndex; i++) {
+ fStartOffset = pFieldArray->GetAt(i * 3) - pFieldArray->GetAt(i * 3 + 2);
+ if (fStartOffset < 0.1f) {
+ fStartOffset = 0;
+ }
+ }
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ pFieldArray->SetAt(0, fStartOffset);
+ } else {
+ pFieldArray->Add(fStartOffset);
+ }
+ XFA_VERSION version = GetDoc()->GetXFADoc()->GetCurVersionMode();
+ FX_BOOL bCanSplitNoContent = FALSE;
+ XFA_ATTRIBUTEENUM eLayoutMode;
+ this->GetNode()->GetNodeItem(XFA_NODEITEM_Parent)->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, TRUE);
+ if ((eLayoutMode == XFA_ATTRIBUTEENUM_Position || eLayoutMode == XFA_ATTRIBUTEENUM_Tb || eLayoutMode == XFA_ATTRIBUTEENUM_Row || eLayoutMode == XFA_ATTRIBUTEENUM_Table) && version > XFA_VERSION_208) {
+ bCanSplitNoContent = TRUE;
+ }
+ if ((eLayoutMode == XFA_ATTRIBUTEENUM_Tb || eLayoutMode == XFA_ATTRIBUTEENUM_Row || eLayoutMode == XFA_ATTRIBUTEENUM_Table) && version <= XFA_VERSION_208) {
+ if (fStartOffset < fCalcHeight) {
+ bCanSplitNoContent = TRUE;
+ } else {
+ fCalcHeight = 0;
+ return TRUE;
+ }
+ }
+ if (bCanSplitNoContent) {
+ if ((fCalcHeight - fTopInset - fSpaceAbove < fLineHeight)) {
+ fCalcHeight = 0;
+ return TRUE;
+ }
+ if (fStartOffset + XFA_FLOAT_PERCISION >= fCalcHeight) {
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ pFieldArray->SetAt(iBlockIndex * 3 + 1, 0);
+ pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
+ } else {
+ pFieldArray->Add(0);
+ pFieldArray->Add(fCalcHeight);
+ }
+ return FALSE;
+ }
+ if (fCalcHeight - fStartOffset < fLineHeight) {
+ fCalcHeight = fStartOffset;
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ pFieldArray->SetAt(iBlockIndex * 3 + 1, 0);
+ pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
+ } else {
+ pFieldArray->Add(0);
+ pFieldArray->Add(fCalcHeight);
+ }
+ return TRUE;
+ }
+ FX_FLOAT fTextNum = fCalcHeight + XFA_FLOAT_PERCISION - fCapReserve - fStartOffset;
+ FX_INT32 iLineNum = (FX_INT32)((fTextNum + (fLineHeight - fFontSize)) / fLineHeight);
+ if (iLineNum >= iLinesCount) {
+ if (fCalcHeight - fStartOffset - fTextHeight >= fFontSize) {
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ pFieldArray->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLinesCount);
+ pFieldArray->SetAt(iBlockIndex * 3 + 2, fCalcHeight);
+ } else {
+ pFieldArray->Add((FX_FLOAT)iLinesCount);
+ pFieldArray->Add(fCalcHeight);
+ }
+ return FALSE;
+ }
+ if (fHeight - fStartOffset - fTextHeight < fFontSize) {
+ iLineNum -= 1;
+ if (iLineNum == 0) {
+ fCalcHeight = 0;
+ return TRUE;
+ }
+ } else {
+ iLineNum = (FX_INT32)(fTextNum / fLineHeight);
+ }
+ }
+ if (iLineNum > 0) {
+ FX_FLOAT fSplitHeight = iLineNum * fLineHeight + fCapReserve + fStartOffset;
+ if (iFieldSplitCount / 3 == (iBlockIndex + 1)) {
+ pFieldArray->SetAt(iBlockIndex * 3 + 1, (FX_FLOAT)iLineNum);
+ pFieldArray->SetAt(iBlockIndex * 3 + 2, fSplitHeight);
+ } else {
+ pFieldArray->Add((FX_FLOAT)iLineNum);
+ pFieldArray->Add(fSplitHeight);
+ }
+ if (fabs(fSplitHeight - fCalcHeight) < XFA_FLOAT_PERCISION) {
+ return FALSE;
+ }
+ fCalcHeight = fSplitHeight;
+ return TRUE;
+ }
+ }
+ fCalcHeight = 0;
+ return TRUE;
+}
+void CXFA_WidgetAcc::InitLayoutData()
+{
+ if (m_pLayoutData) {
+ return;
+ }
+ switch (GetUIType()) {
+ case XFA_ELEMENT_Text:
+ m_pLayoutData = FX_NEW CXFA_TextLayoutData;
+ return;
+ case XFA_ELEMENT_TextEdit:
+ m_pLayoutData = FX_NEW CXFA_TextEditData;
+ return;
+ case XFA_ELEMENT_Image:
+ m_pLayoutData = FX_NEW CXFA_ImageLayoutData;
+ return;
+ case XFA_ELEMENT_ImageEdit:
+ m_pLayoutData = FX_NEW CXFA_ImageEditData;
+ return;
+ default:
+ break;
+ }
+ if (GetClassID() == XFA_ELEMENT_Field) {
+ m_pLayoutData = FX_NEW CXFA_FieldLayoutData;
+ } else {
+ m_pLayoutData = FX_NEW CXFA_WidgetLayoutData;
+ }
+}
+void CXFA_WidgetAcc::StartTextLayout(FX_FLOAT& fCalcWidth, FX_FLOAT& fCalcHeight)
+{
+ LoadText();
+ CXFA_TextLayout* pTextLayout = ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout;
+ FX_FLOAT fTextHeight = 0;
+ if (fCalcWidth > 0 && fCalcHeight > 0) {
+ FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
+ pTextLayout->StartLayout(fWidth);
+ fTextHeight = fCalcHeight;
+ fTextHeight = GetHeightWithoutMargin(fTextHeight);
+ pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+ return;
+ }
+ if (fCalcWidth > 0 && fCalcHeight < 0) {
+ FX_FLOAT fWidth = GetWidthWithoutMargin(fCalcWidth);
+ pTextLayout->StartLayout(fWidth);
+ }
+ if (fCalcWidth < 0 && fCalcHeight < 0) {
+ FX_FLOAT fMaxWidth = -1;
+ FX_BOOL bRet = GetWidth(fMaxWidth);
+ if (bRet) {
+ FX_FLOAT fWidth = GetWidthWithoutMargin(fMaxWidth);
+ pTextLayout->StartLayout(fWidth);
+ } else {
+ FX_FLOAT fWidth = pTextLayout->StartLayout(fMaxWidth);
+ fMaxWidth = CalculateWidgetAutoWidth(fWidth);
+ fWidth = GetWidthWithoutMargin(fMaxWidth);
+ pTextLayout->StartLayout(fWidth);
+ }
+ fCalcWidth = fMaxWidth;
+ }
+ if (m_pLayoutData->m_fWidgetHeight < 0) {
+ m_pLayoutData->m_fWidgetHeight = pTextLayout->GetLayoutHeight();
+ m_pLayoutData->m_fWidgetHeight = CalculateWidgetAutoHeight(m_pLayoutData->m_fWidgetHeight);
+ }
+ fTextHeight = m_pLayoutData->m_fWidgetHeight;
+ fTextHeight = GetHeightWithoutMargin(fTextHeight);
+ pTextLayout->DoLayout(0, fTextHeight, -1, fTextHeight);
+ fCalcHeight = m_pLayoutData->m_fWidgetHeight;
+}
+FX_BOOL CXFA_WidgetAcc::LoadCaption()
+{
+ InitLayoutData();
+ return ((CXFA_FieldLayoutData*)m_pLayoutData)->LoadCaption(this);
+}
+CXFA_TextLayout* CXFA_WidgetAcc::GetCaptionTextLayout()
+{
+ return m_pLayoutData ? ((CXFA_FieldLayoutData*)m_pLayoutData)->m_pCapTextLayout : NULL;
+}
+CXFA_TextLayout* CXFA_WidgetAcc::GetTextLayout()
+{
+ return m_pLayoutData ? ((CXFA_TextLayoutData*)m_pLayoutData)->m_pTextLayout : NULL;
+}
+CFX_DIBitmap* CXFA_WidgetAcc::GetImageImage()
+{
+ return m_pLayoutData ? ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap : NULL;
+}
+CFX_DIBitmap* CXFA_WidgetAcc::GetImageEditImage()
+{
+ return m_pLayoutData ? ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap : NULL;
+}
+void CXFA_WidgetAcc::SetImageImage(CFX_DIBitmap* newImage)
+{
+ if(((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap == newImage) {
+ return;
+ }
+ if(((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap && !((CXFA_ImageLayoutData*)m_pLayoutData)->m_bNamedImage) {
+ delete ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap;
+ ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = NULL;
+ }
+ ((CXFA_ImageLayoutData*)m_pLayoutData)->m_pDIBitmap = newImage;
+}
+void CXFA_WidgetAcc::SetImageEditImage(CFX_DIBitmap* newImage)
+{
+ if(((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap == newImage) {
+ return;
+ }
+ if(((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap && !((CXFA_ImageEditData*)m_pLayoutData)->m_bNamedImage) {
+ delete ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap;
+ ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = NULL;
+ }
+ ((CXFA_ImageEditData*)m_pLayoutData)->m_pDIBitmap = newImage;
+}
+CXFA_WidgetLayoutData* CXFA_WidgetAcc::GetWidgetLayoutData()
+{
+ return m_pLayoutData;
+}
+IFX_Font* CXFA_WidgetAcc::GetFDEFont()
+{
+ CFX_WideStringC wsFontName = FX_WSTRC(L"Courier");
+ FX_DWORD dwFontStyle = 0;
+ if (CXFA_Font font = this->GetFont()) {
+ if (font.IsBold()) {
+ dwFontStyle |= FX_FONTSTYLE_Bold;
+ }
+ if (font.IsItalic()) {
+ dwFontStyle |= FX_FONTSTYLE_Italic;
+ }
+ font.GetTypeface(wsFontName);
+ }
+ CXFA_FFDoc* pDoc = GetDoc();
+ return pDoc->GetApp()->GetXFAFontMgr()->GetFont((XFA_HDOC)pDoc, wsFontName, dwFontStyle);
+}
+FX_FLOAT CXFA_WidgetAcc::GetFontSize()
+{
+ FX_FLOAT fFontSize = 10.0f;
+ if (CXFA_Font font = this->GetFont()) {
+ fFontSize = font.GetFontSize();
+ }
+ return fFontSize < 0.1f ? 10.0f : fFontSize;
+}
+FX_FLOAT CXFA_WidgetAcc::GetLineHeight()
+{
+ FX_FLOAT fLineHeight = 0;
+ if (CXFA_Para para = this->GetPara()) {
+ fLineHeight = para.GetLineHeight();
+ }
+ if (fLineHeight < 1) {
+ fLineHeight = GetFontSize() * 1.2f;
+ }
+ return fLineHeight;
+}
+FX_ARGB CXFA_WidgetAcc::GetTextColor()
+{
+ if (CXFA_Font font = this->GetFont()) {
+ return font.GetColor();
+ }
+ return 0xFF000000;
+}
+CXFA_Node* CXFA_TextProvider::GetTextNode(FX_BOOL &bRichText)
+{
+ bRichText = FALSE;
+ if (m_pTextNode) {
+ if (m_pTextNode->GetClassID() == XFA_ELEMENT_ExData) {
+ CFX_WideString wsContentType;
+ m_pTextNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+ bRichText = TRUE;
+ }
+ }
+ return m_pTextNode;
+ }
+ if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
+ CXFA_Node* pElementNode = m_pWidgetAcc->GetNode();
+ CXFA_Node *pValueNode = pElementNode->GetChild(0, XFA_ELEMENT_Value);
+ if (!pValueNode) {
+ return NULL;
+ }
+ CXFA_Node *pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
+ CFX_WideString wsContentType;
+ pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+ bRichText = TRUE;
+ }
+ }
+ return pChildNode;
+ } else if (m_eType == XFA_TEXTPROVIDERTYPE_Datasets) {
+ CXFA_Node* pBind = m_pWidgetAcc->GetDatasets();
+ IFDE_XMLNode *pXMLNode = pBind->GetXMLMappingNode();
+ FXSYS_assert(pXMLNode);
+ for(IFDE_XMLNode *pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement *pElement = (IFDE_XMLElement *)pXMLChild;
+ if(XFA_RecognizeRichText(pElement)) {
+ bRichText = TRUE;
+ }
+ }
+ }
+ return pBind;
+ } else if (m_eType == XFA_TEXTPROVIDERTYPE_Caption) {
+ CXFA_Node *pCaptionNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
+ if (pCaptionNode == NULL) {
+ return NULL;
+ }
+ CXFA_Node *pValueNode = pCaptionNode->GetChild(0, XFA_ELEMENT_Value);
+ if (pValueNode == NULL) {
+ return NULL;
+ }
+ CXFA_Node *pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pChildNode && pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
+ CFX_WideString wsContentType;
+ pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+ bRichText = TRUE;
+ }
+ }
+ return pChildNode;
+ }
+ CXFA_Node *pItemNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Items);
+ if (pItemNode == NULL) {
+ return NULL;
+ }
+ CXFA_Node* pNode = pItemNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while(pNode) {
+ CFX_WideStringC wsName;
+ pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+ if (m_eType == XFA_TEXTPROVIDERTYPE_Rollover && wsName == FX_WSTRC(L"rollover")) {
+ return pNode;
+ }
+ if (m_eType == XFA_TEXTPROVIDERTYPE_Down && wsName == FX_WSTRC(L"down")) {
+ return pNode;
+ }
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return NULL;
+}
+CXFA_Para CXFA_TextProvider::GetParaNode()
+{
+ if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
+ return m_pWidgetAcc->GetPara();
+ }
+ CXFA_Node *pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
+ return pNode->GetChild(0, XFA_ELEMENT_Para);
+}
+CXFA_Font CXFA_TextProvider::GetFontNode()
+{
+ if (m_eType == XFA_TEXTPROVIDERTYPE_Text) {
+ return m_pWidgetAcc->GetFont();
+ }
+ CXFA_Node *pNode = m_pWidgetAcc->GetNode()->GetChild(0, XFA_ELEMENT_Caption);
+ pNode = pNode->GetChild(0, XFA_ELEMENT_Font);
+ if (pNode) {
+ return pNode;
+ }
+ return m_pWidgetAcc->GetFont();
+}
+FX_BOOL CXFA_TextProvider::IsCheckButtonAndAutoWidth()
+{
+ XFA_ELEMENT eType = m_pWidgetAcc->GetUIType();
+ if (eType == XFA_ELEMENT_CheckButton) {
+ FX_FLOAT fWidth = 0;
+ return !m_pWidgetAcc->GetWidth(fWidth);
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_TextProvider::GetEmbbedObj(FX_BOOL bURI, FX_BOOL bRaw, const CFX_WideString &wsAttr, CFX_WideString &wsValue)
+{
+ if (m_eType != XFA_TEXTPROVIDERTYPE_Text) {
+ return FALSE;
+ }
+ if (bURI) {
+ CXFA_Node* pWidgetNode = m_pWidgetAcc->GetNode();
+ CXFA_Node* pParent = pWidgetNode->GetNodeItem(XFA_NODEITEM_Parent);
+ CXFA_Document* pDocument = pWidgetNode->GetDocument();
+ CXFA_Node* pIDNode = NULL;
+ CXFA_WidgetAcc* pEmbAcc = NULL;
+ if (pParent) {
+ pIDNode = pDocument->GetNodeByID(pParent, wsAttr);
+ }
+ if (!pIDNode) {
+ pIDNode = pDocument->GetNodeByID((CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Form), wsAttr);
+ }
+ if (pIDNode) {
+ pEmbAcc = (CXFA_WidgetAcc*)pIDNode->GetWidgetData();
+ }
+ if (pEmbAcc) {
+ pEmbAcc->GetValue(wsValue, XFA_VALUEPICTURE_Display);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffwidgetacc.h b/xfa/src/fxfa/src/app/xfa_ffwidgetacc.h
new file mode 100644
index 0000000000..38f9678140
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffwidgetacc.h
@@ -0,0 +1,40 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_WIDGETACC_IMP_H
+#define _FXFA_FORMFILLER_WIDGETACC_IMP_H
+#include "xfa_textlayout.h"
+enum XFA_TEXTPROVIDERTYPE {
+ XFA_TEXTPROVIDERTYPE_Text,
+ XFA_TEXTPROVIDERTYPE_Datasets,
+ XFA_TEXTPROVIDERTYPE_Caption,
+ XFA_TEXTPROVIDERTYPE_Rollover,
+ XFA_TEXTPROVIDERTYPE_Down,
+};
+class CXFA_TextProvider : public IXFA_TextProvider, public CFX_Object
+{
+public:
+ CXFA_TextProvider(CXFA_WidgetAcc *pWidgetAcc, XFA_TEXTPROVIDERTYPE eType, CXFA_Node* pTextNode = NULL)
+ : m_pWidgetAcc(pWidgetAcc), m_eType(eType), m_pTextNode(pTextNode)
+ {
+ FXSYS_assert(m_pWidgetAcc != NULL);
+ }
+ virtual ~CXFA_TextProvider() {}
+ virtual CXFA_Node* GetTextNode(FX_BOOL &bRichText);
+ virtual CXFA_Para GetParaNode();
+ virtual CXFA_Font GetFontNode();
+ virtual FX_BOOL IsCheckButtonAndAutoWidth();
+ virtual CXFA_FFDoc* GetDocNode()
+ {
+ return m_pWidgetAcc->GetDoc();
+ }
+ virtual FX_BOOL GetEmbbedObj(FX_BOOL bURI, FX_BOOL bRaw, const CFX_WideString &wsAttr, CFX_WideString &wsValue);
+protected:
+ CXFA_WidgetAcc *m_pWidgetAcc;
+ XFA_TEXTPROVIDERTYPE m_eType;
+ CXFA_Node* m_pTextNode;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_ffwidgethandler.cpp b/xfa/src/fxfa/src/app/xfa_ffwidgethandler.cpp
new file mode 100644
index 0000000000..12df3a096a
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffwidgethandler.cpp
@@ -0,0 +1,591 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffwidgethandler.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffchoicelist.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffdocview.h"
+CXFA_FFWidgetHandler::CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView)
+ : m_pDocView(pDocView)
+{
+}
+CXFA_FFWidgetHandler::~CXFA_FFWidgetHandler()
+{
+}
+IXFA_PageView* CXFA_FFWidgetHandler::GetPageView(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->GetPageView();
+}
+void CXFA_FFWidgetHandler::GetRect(XFA_HWIDGET hWidget, CFX_RectF &rt)
+{
+ ((CXFA_FFWidget*)hWidget)->GetWidgetRect(rt);
+}
+FX_DWORD CXFA_FFWidgetHandler::GetStatus(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->GetStatus();
+}
+FX_BOOL CXFA_FFWidgetHandler::GetBBox(XFA_HWIDGET hWidget, CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus)
+{
+ return ((CXFA_FFWidget*)hWidget)->GetBBox(rtBox, dwStatus, bDrawFocus);
+}
+CXFA_WidgetAcc* CXFA_FFWidgetHandler::GetDataAcc(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->GetDataAcc();
+}
+void CXFA_FFWidgetHandler::GetName(XFA_HWIDGET hWidget, CFX_WideString &wsName, FX_INT32 iNameType )
+{
+ ((CXFA_FFWidget*)hWidget)->GetDataAcc()->GetName(wsName, iNameType);
+}
+FX_BOOL CXFA_FFWidgetHandler::GetToolTip(XFA_HWIDGET hWidget, CFX_WideString &wsToolTip)
+{
+ return ((CXFA_FFWidget*)hWidget)->GetToolTip(wsToolTip);
+}
+void CXFA_FFWidgetHandler::SetPrivateData(XFA_HWIDGET hWidget, FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback)
+{
+ ((CXFA_FFWidget*)hWidget)->SetPrivateData(module_id, pData, callback);
+}
+FX_LPVOID CXFA_FFWidgetHandler::GetPrivateData(XFA_HWIDGET hWidget, FX_LPVOID module_id)
+{
+ return ((CXFA_FFWidget*)hWidget)->GetPrivateData(module_id);
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseEnter(XFA_HWIDGET hWidget)
+{
+ m_pDocView->LockUpdate();
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnMouseEnter();
+ m_pDocView->UnlockUpdate();
+ m_pDocView->UpdateDocView();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseExit(XFA_HWIDGET hWidget)
+{
+ m_pDocView->LockUpdate();
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnMouseExit();
+ m_pDocView->UnlockUpdate();
+ m_pDocView->UpdateDocView();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnLButtonDown(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ m_pDocView->LockUpdate();
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnLButtonDown(dwFlags, fx, fy);
+ if (bRet && m_pDocView->SetFocus(hWidget)) {
+ ((CXFA_FFDoc*)m_pDocView->GetDoc())->GetDocProvider()->SetFocusWidget((XFA_HDOC)m_pDocView->GetDoc(), (XFA_HWIDGET)hWidget);
+ }
+ m_pDocView->UnlockUpdate();
+ m_pDocView->UpdateDocView();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnLButtonUp(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ m_pDocView->LockUpdate();
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ m_pDocView->m_bLayoutEvent = TRUE;
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnLButtonUp(dwFlags, fx, fy);
+ m_pDocView->UnlockUpdate();
+ m_pDocView->UpdateDocView();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnLButtonDblClk(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnLButtonDblClk(dwFlags, fx, fy);
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseMove(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnMouseMove(dwFlags, fx, fy);
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnMouseWheel(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy)
+{
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnMouseWheel(dwFlags, zDelta, fx, fy);
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnRButtonDown(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnRButtonDown(dwFlags, fx, fy);
+ if (bRet && m_pDocView->SetFocus(hWidget)) {
+ ((CXFA_FFDoc*)m_pDocView->GetDoc())->GetDocProvider()->SetFocusWidget((XFA_HDOC)m_pDocView->GetDoc(), (XFA_HWIDGET)hWidget);
+ }
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnRButtonUp(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnRButtonUp(dwFlags, fx, fy);
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnRButtonDblClk(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy)
+{
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnRButtonDblClk(dwFlags, fx, fy);
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnKeyDown(XFA_HWIDGET hWidget, FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnKeyDown(dwKeyCode, dwFlags);
+ m_pDocView->RunInvalidate();
+ m_pDocView->UpdateDocView();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnKeyUp(XFA_HWIDGET hWidget, FX_DWORD dwKeyCode, FX_DWORD dwFlags)
+{
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnKeyUp(dwKeyCode, dwFlags);
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_BOOL CXFA_FFWidgetHandler::OnChar(XFA_HWIDGET hWidget, FX_DWORD dwChar, FX_DWORD dwFlags)
+{
+ FX_BOOL bRet = ((CXFA_FFWidget*)hWidget)->OnChar(dwChar, dwFlags);
+ m_pDocView->RunInvalidate();
+ return bRet;
+}
+FX_DWORD CXFA_FFWidgetHandler::OnHitTest(XFA_HWIDGET hWidget, FX_FLOAT fx, FX_FLOAT fy)
+{
+ if (!(((CXFA_FFWidget*)hWidget)->GetStatus() & XFA_WIDGETSTATUS_Visible)) {
+ return FWL_WGTHITTEST_Unknown;
+ }
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ return ((CXFA_FFWidget*)hWidget)->OnHitTest(fx, fy);
+}
+FX_BOOL CXFA_FFWidgetHandler::OnSetCursor(XFA_HWIDGET hWidget, FX_FLOAT fx, FX_FLOAT fy)
+{
+ ((CXFA_FFWidget*)hWidget)->Rotate2Normal(fx, fy);
+ return ((CXFA_FFWidget*)hWidget)->OnSetCursor(fx, fy);
+}
+void CXFA_FFWidgetHandler::RenderWidget(XFA_HWIDGET hWidget, CFX_Graphics* pGS, CFX_Matrix* pMatrix , FX_BOOL bHighlight)
+{
+ ((CXFA_FFWidget*)hWidget)->RenderWidget(pGS, pMatrix, bHighlight ? XFA_WIDGETSTATUS_Highlight : 0, 0);
+}
+FX_BOOL CXFA_FFWidgetHandler::HasEvent(CXFA_WidgetAcc* pWidgetAcc, XFA_EVENTTYPE eEventType)
+{
+ if (!pWidgetAcc || eEventType == XFA_EVENT_Unknown) {
+ return FALSE;
+ }
+ if (pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
+ return FALSE;
+ }
+ switch (eEventType) {
+ case XFA_EVENT_Calculate: {
+ CXFA_Calculate calc = pWidgetAcc->GetCalculate();
+ if (!calc) {
+ return FALSE;
+ }
+ if (CXFA_Script script = calc.GetScript()) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ case XFA_EVENT_Validate: {
+ CXFA_Validate val = pWidgetAcc->GetValidate();
+ if (!val) {
+ return FALSE;
+ }
+ if (val.GetScript()) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ default:
+ break;
+ }
+ CXFA_NodeArray eventArray;
+ return pWidgetAcc->GetEventByActivity(gs_EventActivity[eEventType], eventArray);
+}
+FX_INT32 CXFA_FFWidgetHandler::ProcessEvent(CXFA_WidgetAcc* pWidgetAcc, CXFA_EventParam* pParam)
+{
+ if (!pParam || pParam->m_eType == XFA_EVENT_Unknown) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ if (!pWidgetAcc || pWidgetAcc->GetClassID() == XFA_ELEMENT_Draw) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ switch (pParam->m_eType) {
+ case XFA_EVENT_Calculate:
+ return pWidgetAcc->ProcessCalculate();
+ case XFA_EVENT_Validate:
+ if (((CXFA_FFDoc*)m_pDocView->GetDoc())->GetDocProvider()->IsValidationsEnabled(m_pDocView->GetDoc())) {
+ return pWidgetAcc->ProcessValidate();
+ }
+ return XFA_EVENTERROR_Disabled;
+ case XFA_EVENT_InitCalculate: {
+ CXFA_Calculate calc = pWidgetAcc->GetCalculate();
+ if (!calc) {
+ return XFA_EVENTERROR_NotExist;
+ }
+ if (pWidgetAcc->GetNode()->HasFlag(XFA_NODEFLAG_UserInteractive)) {
+ return XFA_EVENTERROR_Disabled;
+ }
+ CXFA_Script script = calc.GetScript();
+ return pWidgetAcc->ExecuteScript(script, pParam);
+ }
+ default:
+ break;
+ }
+ FX_INT32 iRet = pWidgetAcc->ProcessEvent(gs_EventActivity[pParam->m_eType], pParam);
+ return iRet;
+}
+XFA_HWIDGET CXFA_FFWidgetHandler::CreateWidget(XFA_HWIDGET hParent, XFA_WIDGETTYPE eType, XFA_HWIDGET hBefore )
+{
+ CXFA_Node* pParentFormItem = hParent ? ((CXFA_FFWidget*)hParent)->GetDataAcc()->GetNode() : NULL;
+ CXFA_Node* pBeforeFormItem = hBefore ? ((CXFA_FFWidget*)hBefore)->GetDataAcc()->GetNode() : NULL;
+ CXFA_Node* pNewFormItem = CreateWidgetFormItem(eType, pParentFormItem, pBeforeFormItem);
+ if (pNewFormItem == NULL) {
+ return NULL;
+ }
+ pNewFormItem->GetTemplateNode()->SetFlag(XFA_NODEFLAG_Initialized);
+ pNewFormItem->SetFlag(XFA_NODEFLAG_Initialized);
+ m_pDocView->RunLayout();
+ CXFA_LayoutItem* pLayout = m_pDocView->GetXFALayout()->GetLayoutItem(pNewFormItem);
+ return (XFA_HWIDGET)pLayout;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateWidgetFormItem(XFA_WIDGETTYPE eType, CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ switch (eType) {
+ case XFA_WIDGETTYPE_Barcode:
+ return NULL;
+ case XFA_WIDGETTYPE_PushButton:
+ return CreatePushButton(pParent, pBefore);
+ case XFA_WIDGETTYPE_CheckButton:
+ return CreateCheckButton(pParent, pBefore);
+ case XFA_WIDGETTYPE_ExcludeGroup:
+ return CreateExclGroup(pParent, pBefore);
+ case XFA_WIDGETTYPE_RadioButton:
+ return CreateRadioButton(pParent, pBefore);
+ case XFA_WIDGETTYPE_Arc:
+ return CreateArc(pParent, pBefore);
+ case XFA_WIDGETTYPE_Rectangle:
+ return CreateRectangle(pParent, pBefore);
+ case XFA_WIDGETTYPE_Image:
+ return CreateImage(pParent, pBefore);
+ case XFA_WIDGETTYPE_Line:
+ return CreateLine(pParent, pBefore);
+ case XFA_WIDGETTYPE_Text:
+ return CreateText(pParent, pBefore);
+ case XFA_WIDGETTYPE_DatetimeEdit:
+ return CreateDatetimeEdit(pParent, pBefore);
+ case XFA_WIDGETTYPE_DecimalField:
+ return CreateDecimalField(pParent, pBefore);
+ case XFA_WIDGETTYPE_NumericField:
+ return CreateNumericField(pParent, pBefore);
+ case XFA_WIDGETTYPE_Signature:
+ return CreateSignature(pParent, pBefore);
+ case XFA_WIDGETTYPE_TextEdit:
+ return CreateTextEdit(pParent, pBefore);
+ case XFA_WIDGETTYPE_DropdownList:
+ return CreateDropdownList(pParent, pBefore);
+ case XFA_WIDGETTYPE_ListBox:
+ return CreateListBox(pParent, pBefore);
+ case XFA_WIDGETTYPE_ImageField:
+ return CreateImageField(pParent, pBefore);
+ case XFA_WIDGETTYPE_PasswordEdit:
+ return CreatePasswordEdit(pParent, pBefore);
+ case XFA_WIDGETTYPE_Subform:
+ return CreateSubform(pParent, pBefore);
+ default:
+ break;
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreatePushButton(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_Button, pParent, pBefore);
+ CXFA_Node* pCaption = CreateCopyNode(XFA_ELEMENT_Caption, pField);
+ CXFA_Node* pValue = CreateCopyNode(XFA_ELEMENT_Value, pCaption);
+ CXFA_Node* pText = CreateCopyNode(XFA_ELEMENT_Text, pValue);
+ pText->SetContent(FX_WSTRC(L"Button"), FX_WSTRC(L"Button"), FALSE);
+ CXFA_Node* pPara = CreateCopyNode(XFA_ELEMENT_Para, pCaption);
+ pPara->SetEnum(XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTEENUM_Middle, FALSE);
+ pPara->SetEnum(XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTEENUM_Center, FALSE);
+ CreateFontNode(pCaption);
+ CXFA_Node* pBorder = CreateCopyNode(XFA_ELEMENT_Border, pField);
+ pBorder->SetEnum(XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTEENUM_Right, FALSE);
+ CXFA_Node* pEdge = CreateCopyNode(XFA_ELEMENT_Edge, pBorder);
+ pEdge->SetEnum(XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTEENUM_Raised, FALSE);
+ CXFA_Node* pFill = CreateCopyNode(XFA_ELEMENT_Fill, pBorder);
+ CXFA_Node* pColor = CreateCopyNode(XFA_ELEMENT_Color, pFill);
+ pColor->SetCData(XFA_ATTRIBUTE_Value, FX_WSTRC(L"212, 208, 200"), FALSE);
+ CXFA_Node* pBind = CreateCopyNode(XFA_ELEMENT_Bind, pField);
+ pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateCheckButton(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_CheckButton, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateExclGroup(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ return CreateFormItem(XFA_ELEMENT_ExclGroup, pParent, pBefore);
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateRadioButton(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_CheckButton, pParent, pBefore);
+ CXFA_Node* pUi = pField->GetFirstChildByClass(XFA_ELEMENT_Ui);
+ CXFA_Node* pWidget = pUi->GetFirstChildByClass(XFA_ELEMENT_CheckButton);
+ pWidget->SetEnum(XFA_ATTRIBUTE_Shape, XFA_ATTRIBUTEENUM_Round);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDatetimeEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_DateTimeEdit, pParent, pBefore);
+ CreateValueNode(XFA_ELEMENT_Date, pField);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDecimalField(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateNumericField(pParent, pBefore);
+ CreateValueNode(XFA_ELEMENT_Decimal, pField);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateNumericField(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_NumericEdit, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateSignature(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_Signature, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateTextEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_TextEdit, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDropdownList(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_ChoiceList, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateListBox(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateDropdownList(pParent, pBefore);
+ CXFA_Node* pUi = pField->GetNodeItem(XFA_NODEITEM_FirstChild);
+ CXFA_Node* pListBox = pUi->GetNodeItem(XFA_NODEITEM_FirstChild);
+ pListBox->SetEnum(XFA_ATTRIBUTE_Open, XFA_ATTRIBUTEENUM_Always);
+ pListBox->SetEnum(XFA_ATTRIBUTE_CommitOn, XFA_ATTRIBUTEENUM_Exit);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateImageField(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_ImageEdit, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreatePasswordEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateField(XFA_ELEMENT_PasswordEdit, pParent, pBefore);
+ CXFA_Node* pBind = CreateCopyNode(XFA_ELEMENT_Bind, pField);
+ pBind->SetEnum(XFA_ATTRIBUTE_Match, XFA_ATTRIBUTEENUM_None, FALSE);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateField(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateFormItem(XFA_ELEMENT_Field, pParent, pBefore);
+ CXFA_Node* pUi = CreateCopyNode(XFA_ELEMENT_Ui, pField);
+ CXFA_Node* pCheckButton = CreateCopyNode(eElement, pUi);
+ CreateFontNode(pField);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateArc(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Arc, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateRectangle(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Rectangle, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateImage(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Image, pParent, pBefore);
+ CXFA_Node* pUi = CreateCopyNode(XFA_ELEMENT_Ui, pField);
+ CXFA_Node* pImage = CreateCopyNode(XFA_ELEMENT_ImageEdit, pUi);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateLine(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Line, pParent, pBefore);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateText(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pField = CreateDraw(XFA_ELEMENT_Text, pParent, pBefore);
+ CXFA_Node* pUi = CreateCopyNode(XFA_ELEMENT_Ui, pField);
+ CXFA_Node* pTextEdit = CreateCopyNode(XFA_ELEMENT_TextEdit, pUi);
+ CreateFontNode(pField);
+ return pField;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateDraw(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pDraw = CreateFormItem(XFA_ELEMENT_Draw, pParent, pBefore);
+ CreateValueNode(eElement, pDraw);
+ return pDraw;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateSubform(CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pSubform = CreateFormItem(XFA_ELEMENT_Subform, pParent, pBefore);
+ return pSubform;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateFormItem(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pTemplateParent = pParent != NULL ? pParent->GetTemplateNode() : NULL;
+ CXFA_Node* pNewFormItem = pTemplateParent->CloneTemplateToForm(FALSE);
+ if (pParent != NULL) {
+ pParent->InsertChild(pNewFormItem, pBefore);
+ }
+ return pNewFormItem;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateCopyNode(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Node* pTemplateParent = pParent != NULL ? pParent->GetTemplateNode() : NULL;
+ CXFA_Node* pNewNode = CreateTemplateNode(eElement, pTemplateParent, pBefore ? pBefore->GetTemplateNode() : NULL)->Clone(FALSE);
+ if (pParent != NULL) {
+ pParent->InsertChild(pNewNode, pBefore);
+ }
+ return pNewNode;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateTemplateNode(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const
+{
+ CXFA_Document* pXFADoc = GetXFADoc();
+ CXFA_Node* pNewTemplateNode = pXFADoc->GetParser()->GetFactory()->CreateNode(XFA_XDPPACKET_Template, eElement);
+ if (pParent != NULL) {
+ pParent->InsertChild(pNewTemplateNode, pBefore);
+ }
+ return pNewTemplateNode;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateFontNode(CXFA_Node* pParent) const
+{
+ CXFA_Node* pFont = CreateCopyNode(XFA_ELEMENT_Font, pParent);
+ pFont->SetCData(XFA_ATTRIBUTE_Typeface, FX_WSTRC(L"Myriad Pro"), FALSE);
+ return pFont;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateMarginNode(CXFA_Node* pParent, FX_DWORD dwFlags, FX_FLOAT fInsets[4]) const
+{
+ CXFA_Node* pMargin = CreateCopyNode(XFA_ELEMENT_Margin, pParent);
+ if (dwFlags & 0x01) {
+ pMargin->SetMeasure(XFA_ATTRIBUTE_LeftInset, CXFA_Measurement(fInsets[0], XFA_UNIT_Pt), FALSE);
+ }
+ if (dwFlags & 0x02) {
+ pMargin->SetMeasure(XFA_ATTRIBUTE_TopInset, CXFA_Measurement(fInsets[1], XFA_UNIT_Pt), FALSE);
+ }
+ if (dwFlags & 0x04) {
+ pMargin->SetMeasure(XFA_ATTRIBUTE_RightInset, CXFA_Measurement(fInsets[2], XFA_UNIT_Pt), FALSE);
+ }
+ if (dwFlags & 0x08) {
+ pMargin->SetMeasure(XFA_ATTRIBUTE_BottomInset, CXFA_Measurement(fInsets[3], XFA_UNIT_Pt), FALSE);
+ }
+ return pMargin;
+}
+CXFA_Node* CXFA_FFWidgetHandler::CreateValueNode(XFA_ELEMENT eValue, CXFA_Node* pParent) const
+{
+ CXFA_Node* pValue = CreateCopyNode(XFA_ELEMENT_Value, pParent);
+ CXFA_Node* pDate = CreateCopyNode(eValue, pValue);
+ return pValue;
+}
+IXFA_ObjFactory* CXFA_FFWidgetHandler::GetObjFactory() const
+{
+ return GetXFADoc()->GetParser()->GetFactory();
+}
+CXFA_Document* CXFA_FFWidgetHandler::GetXFADoc() const
+{
+ return ((CXFA_FFDoc*)(m_pDocView->GetDoc()))->GetXFADoc();
+}
+CXFA_FFMenuHandler::CXFA_FFMenuHandler()
+{
+}
+CXFA_FFMenuHandler::~CXFA_FFMenuHandler()
+{
+}
+FX_BOOL CXFA_FFMenuHandler::CanCopy(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanCopy();
+}
+FX_BOOL CXFA_FFMenuHandler::CanCut(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanCut();
+}
+FX_BOOL CXFA_FFMenuHandler::CanPaste(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanPaste();
+}
+FX_BOOL CXFA_FFMenuHandler::CanSelectAll(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanSelectAll();
+}
+FX_BOOL CXFA_FFMenuHandler::CanDelete(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanDelete();
+}
+FX_BOOL CXFA_FFMenuHandler::CanDeSelect(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanDeSelect();
+}
+FX_BOOL CXFA_FFMenuHandler::Copy(XFA_HWIDGET hWidget, CFX_WideString &wsText)
+{
+ return ((CXFA_FFWidget*)hWidget)->Copy(wsText);
+}
+FX_BOOL CXFA_FFMenuHandler::Cut(XFA_HWIDGET hWidget, CFX_WideString &wsText)
+{
+ return ((CXFA_FFWidget*)hWidget)->Cut(wsText);
+}
+FX_BOOL CXFA_FFMenuHandler::Paste(XFA_HWIDGET hWidget, const CFX_WideString &wsText)
+{
+ return ((CXFA_FFWidget*)hWidget)->Paste(wsText);
+}
+FX_BOOL CXFA_FFMenuHandler::SelectAll(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->SelectAll();
+}
+FX_BOOL CXFA_FFMenuHandler::Delete(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->Delete();
+}
+FX_BOOL CXFA_FFMenuHandler::DeSelect(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->DeSelect();
+}
+FX_BOOL CXFA_FFMenuHandler::CanUndo(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanUndo();
+}
+FX_BOOL CXFA_FFMenuHandler::CanRedo(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->CanRedo();
+}
+FX_BOOL CXFA_FFMenuHandler::Undo(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->Undo();
+}
+FX_BOOL CXFA_FFMenuHandler::Redo(XFA_HWIDGET hWidget)
+{
+ return ((CXFA_FFWidget*)hWidget)->Redo();
+}
+#define FX_EDIT_ISLATINWORD(u) (u == 0x2D || (u <= 0x005A && u >= 0x0041) || (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || u == 0x0027)
+FX_BOOL CXFA_FFMenuHandler::GetSuggestWords(XFA_HWIDGET hWidget, CFX_PointF pointf, CFX_ByteStringArray &sSuggest)
+{
+ return ((CXFA_FFWidget*)hWidget)->GetSuggestWords(pointf, sSuggest);
+}
+FX_BOOL CXFA_FFMenuHandler::ReplaceSpellCheckWord(XFA_HWIDGET hWidget, CFX_PointF pointf, FX_BSTR bsReplace)
+{
+ return ((CXFA_FFWidget*)hWidget)->ReplaceSpellCheckWord(pointf, bsReplace);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_ffwidgethandler.h b/xfa/src/fxfa/src/app/xfa_ffwidgethandler.h
new file mode 100644
index 0000000000..1d58790a02
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_ffwidgethandler.h
@@ -0,0 +1,104 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_ANNOTHANDLER_IMP_H
+#define _FXFA_FORMFILLER_ANNOTHANDLER_IMP_H
+class CXFA_FFDocView;
+class CXFA_FFWidgetHandler : public IXFA_WidgetHandler, public CFX_Object
+{
+public:
+ CXFA_FFWidgetHandler(CXFA_FFDocView* pDocView);
+ ~CXFA_FFWidgetHandler();
+ virtual XFA_HWIDGET CreateWidget(XFA_HWIDGET hParent, XFA_WIDGETTYPE eType, XFA_HWIDGET hBefore = NULL);
+ virtual IXFA_PageView* GetPageView(XFA_HWIDGET hWidget);
+ virtual void GetRect(XFA_HWIDGET hWidget, CFX_RectF &rt);
+ virtual FX_DWORD GetStatus(XFA_HWIDGET hWidget);
+ virtual FX_BOOL GetBBox(XFA_HWIDGET hWidget, CFX_RectF &rtBox, FX_DWORD dwStatus, FX_BOOL bDrawFocus = FALSE);
+ virtual CXFA_WidgetAcc* GetDataAcc(XFA_HWIDGET hWidget);
+ virtual void GetName(XFA_HWIDGET hWidget, CFX_WideString &wsName, FX_INT32 iNameType = 0);
+ virtual FX_BOOL GetToolTip(XFA_HWIDGET hWidget, CFX_WideString &wsToolTip);
+ virtual void SetPrivateData(XFA_HWIDGET hWidget, FX_LPVOID module_id, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback);
+ virtual FX_LPVOID GetPrivateData(XFA_HWIDGET hWidget, FX_LPVOID module_id);
+ virtual FX_BOOL OnMouseEnter(XFA_HWIDGET hWidget);
+ virtual FX_BOOL OnMouseExit(XFA_HWIDGET hWidget);
+ virtual FX_BOOL OnLButtonDown(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonUp(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnLButtonDblClk(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseMove(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnMouseWheel(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_SHORT zDelta, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDown(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonUp(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnRButtonDblClk(XFA_HWIDGET hWidget, FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy);
+
+ virtual FX_BOOL OnKeyDown(XFA_HWIDGET hWidget, FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnKeyUp(XFA_HWIDGET hWidget, FX_DWORD dwKeyCode, FX_DWORD dwFlags);
+ virtual FX_BOOL OnChar(XFA_HWIDGET hWidget, FX_DWORD dwChar, FX_DWORD dwFlags);
+ virtual FX_DWORD OnHitTest(XFA_HWIDGET hWidget, FX_FLOAT fx, FX_FLOAT fy);
+ virtual FX_BOOL OnSetCursor(XFA_HWIDGET hWidget, FX_FLOAT fx, FX_FLOAT fy);
+ virtual void RenderWidget(XFA_HWIDGET hWidget, CFX_Graphics* pGS, CFX_Matrix* pMatrix = NULL, FX_BOOL bHighlight = FALSE);
+ virtual FX_BOOL HasEvent(CXFA_WidgetAcc* pWidgetAcc, XFA_EVENTTYPE eEventType);
+ virtual FX_INT32 ProcessEvent(CXFA_WidgetAcc* pWidgetAcc, CXFA_EventParam* pParam);
+protected:
+ CXFA_Node* CreateWidgetFormItem(XFA_WIDGETTYPE eType, CXFA_Node* pParent, CXFA_Node* pBefore) const;
+
+ CXFA_Node* CreatePushButton(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateCheckButton(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateExclGroup(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateRadioButton(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateDatetimeEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateDecimalField(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateNumericField(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateSignature(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateTextEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateDropdownList(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateListBox(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateImageField(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreatePasswordEdit(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateField(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateArc(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateRectangle(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateImage(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateLine(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateText(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateDraw(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const;
+
+ CXFA_Node* CreateSubform(CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateFormItem(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateCopyNode(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore = NULL) const;
+ CXFA_Node* CreateTemplateNode(XFA_ELEMENT eElement, CXFA_Node* pParent, CXFA_Node* pBefore) const;
+ CXFA_Node* CreateFontNode(CXFA_Node* pParent) const;
+ CXFA_Node* CreateMarginNode(CXFA_Node* pParent, FX_DWORD dwFlags, FX_FLOAT fInsets[4]) const;
+ CXFA_Node* CreateValueNode(XFA_ELEMENT eValue, CXFA_Node* pParent) const;
+ IXFA_ObjFactory* GetObjFactory() const;
+ CXFA_Document* GetXFADoc() const;
+
+ CXFA_FFDocView* m_pDocView;
+};
+class CXFA_FFMenuHandler : public IXFA_MenuHandler, public CFX_Object
+{
+public:
+ CXFA_FFMenuHandler();
+ ~CXFA_FFMenuHandler();
+ virtual FX_BOOL CanCopy(XFA_HWIDGET hWidget);
+ virtual FX_BOOL CanCut(XFA_HWIDGET hWidget);
+ virtual FX_BOOL CanPaste(XFA_HWIDGET hWidget);
+ virtual FX_BOOL CanSelectAll(XFA_HWIDGET hWidget);
+ virtual FX_BOOL CanDelete(XFA_HWIDGET hWidget);
+ virtual FX_BOOL CanDeSelect(XFA_HWIDGET hWidget);
+ virtual FX_BOOL Copy(XFA_HWIDGET hWidget, CFX_WideString &wsText);
+ virtual FX_BOOL Cut(XFA_HWIDGET hWidget, CFX_WideString &wsText);
+ virtual FX_BOOL Paste(XFA_HWIDGET hWidget, const CFX_WideString &wsText);
+ virtual FX_BOOL SelectAll(XFA_HWIDGET hWidget);
+ virtual FX_BOOL Delete(XFA_HWIDGET hWidget);
+ virtual FX_BOOL DeSelect(XFA_HWIDGET hWidget);
+ virtual FX_BOOL CanUndo(XFA_HWIDGET hWidget);
+ virtual FX_BOOL CanRedo(XFA_HWIDGET hWidget);
+ virtual FX_BOOL Undo(XFA_HWIDGET hWidget);
+ virtual FX_BOOL Redo(XFA_HWIDGET hWidget);
+ virtual FX_BOOL GetSuggestWords(XFA_HWIDGET hWidget, CFX_PointF pointf, CFX_ByteStringArray &sSuggest);
+ virtual FX_BOOL ReplaceSpellCheckWord(XFA_HWIDGET hWidget, CFX_PointF pointf, FX_BSTR bsReplace);
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_fontmgr.cpp b/xfa/src/fxfa/src/app/xfa_fontmgr.cpp
new file mode 100644
index 0000000000..f3e4fff810
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fontmgr.cpp
@@ -0,0 +1,1379 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fontmgr.h"
+#include "xfa_ffdoc.h"
+#include "xfa_ffConfigAcc.h"
+#include "xfa_ffapp.h"
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+ {0x01d5d33e, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x01e4f102, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0x030549dc, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0x032edd44, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0x03eac6fc, (FX_LPCWSTR)L"PoorRichard-Regular", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x03ed90e6, (FX_LPCWSTR)L"Nina", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x077b56b3, (FX_LPCWSTR)L"KingsoftPhoneticPlain", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x078ed524, (FX_LPCWSTR)L"MicrosoftSansSerif", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x089b18a9, (FX_LPCWSTR)L"Arial", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x0b2cad72, (FX_LPCWSTR)L"MonotypeCorsiva", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x0bb003e7, (FX_LPCWSTR)L"Kartika", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x0bb469df, (FX_LPCWSTR)L"VinerHandITC", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x0bc1a851, (FX_LPCWSTR)L"SegoeUI", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x0c112ebd, (FX_LPCWSTR)L"KozukaGothicPro-VIM", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x0cfcb9c1, (FX_LPCWSTR)L"AdobeThai", (FX_LPCWSTR)L"Kokila,Arial Narrow", 0, 847},
+ {0x0e7de0f9, (FX_LPCWSTR)L"Playbill", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x0eff47c3, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x107ad374, (FX_LPCWSTR)L"Constantia", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x12194c2d, (FX_LPCWSTR)L"KunstlerScript", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x135ef6a1, (FX_LPCWSTR)L"MinionProSmBd", (FX_LPCWSTR)L"Bell MT,Corbel,Times New Roman,Cambria,Berlin Sans FB", 0, 1252},
+ {0x158c4049, (FX_LPCWSTR)L"Garamond", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x160ecb24, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x161ed07e, (FX_LPCWSTR)L"MSGothic", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0x171d1ed1, (FX_LPCWSTR)L"SnapITC-Regular", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x18d1188f, (FX_LPCWSTR)L"Cambria", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x18eaf350, (FX_LPCWSTR)L"ArialUnicodeMS", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x1a92d115, (FX_LPCWSTR)L"MingLiU", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0x1cc217c6, (FX_LPCWSTR)L"TrebuchetMS", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x1d649596, (FX_LPCWSTR)L"BasemicTimes", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x1e34ee60, (FX_LPCWSTR)L"BellMT", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x1eb36945, (FX_LPCWSTR)L"CooperBlack", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x1ef7787d, (FX_LPCWSTR)L"BatangChe", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0x20b3bd3a, (FX_LPCWSTR)L"BrushScriptMT", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x220877aa, (FX_LPCWSTR)L"Candara", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x22135007, (FX_LPCWSTR)L"FreestyleScript-Regular", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x251059c3, (FX_LPCWSTR)L"Chiller", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x25bed6dd, (FX_LPCWSTR)L"MSReferenceSansSerif", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x28154c81, (FX_LPCWSTR)L"Parchment-Regular", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x29711eb9, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x2b1993b4, (FX_LPCWSTR)L"Basemic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x2b316339, (FX_LPCWSTR)L"NiagaraSolid-Reg", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x2c147529, (FX_LPCWSTR)L"FootlightMTLight", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x2c198928, (FX_LPCWSTR)L"HarlowSolid", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x2c6ac6b2, (FX_LPCWSTR)L"LucidaBright", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x2c9f38e2, (FX_LPCWSTR)L"KozukaMinchoPro-VIR", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x2d5a47b0, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x2def26bf, (FX_LPCWSTR)L"BernardMT-Condensed", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x2fd8930b, (FX_LPCWSTR)L"KozukaMinchoPr6NR", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x3115525a, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x31327817, (FX_LPCWSTR)L"MyriadPro", (FX_LPCWSTR)L"Calibri,Corbel,Candara,Cambria Math,Franklin Gothic Medium,Arial Narrow,Times New Roman", 0, 1252},
+ {0x32244975, (FX_LPCWSTR)L"Helvetica", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x32ac995c, (FX_LPCWSTR)L"Terminal", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x338d648a, (FX_LPCWSTR)L"NiagaraEngraved-Reg", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x33bb65f2, (FX_LPCWSTR)L"Sylfaen", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x3402c30e, (FX_LPCWSTR)L"MSPMincho", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x3412bf31, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x36eb39b9, (FX_LPCWSTR)L"BerlinSansFB", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x36f42055, (FX_LPCWSTR)L"UniversATT", (FX_LPCWSTR)L"Microsoft Sans Serif", 0, 1252},
+ {0x3864c4f6, (FX_LPCWSTR)L"HighTowerText", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x3a257d03, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x3cdae668, (FX_LPCWSTR)L"FreestyleScript", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x3d55aed7, (FX_LPCWSTR)L"Jokerman", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x3d5b4385, (FX_LPCWSTR)L"PMingLiU", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x3d9b7669, (FX_LPCWSTR)L"EstrangeloEdessa", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x3e532d74, (FX_LPCWSTR)L"FranklinGothicMedium", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x3e6aa32d, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0x3f6c36a8, (FX_LPCWSTR)L"Gautami", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x3ff32662, (FX_LPCWSTR)L"Chiller-Regular", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x409de312, (FX_LPCWSTR)L"ModernNo.20", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x41443c5e, (FX_LPCWSTR)L"Georgia", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x4160ade5, (FX_LPCWSTR)L"BellGothicStdBlack", (FX_LPCWSTR)L"Arial,Arial Unicode MS,Book Antiqua,Dotum,Georgia", 0, 1252},
+ {0x421976c4, (FX_LPCWSTR)L"Modern-Regular", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x422a7252, (FX_LPCWSTR)L"Stencil", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x42c8554f, (FX_LPCWSTR)L"Fixedsys", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x435cb41d, (FX_LPCWSTR)L"Roman", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x47882383, (FX_LPCWSTR)L"CourierNew", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0x480a2338, (FX_LPCWSTR)L"BerlinSansFBDemi", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x480bf7a4, (FX_LPCWSTR)L"CourierStd", (FX_LPCWSTR)L"Courier New,Verdana", 0, 1252},
+ {0x481ad6ed, (FX_LPCWSTR)L"VladimirScript", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0x4911577a, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0x4a788d72, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x4bf88566, (FX_LPCWSTR)L"SegoeCondensed", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x4ccf51a4, (FX_LPCWSTR)L"BerlinSansFB-Reg", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x4ea967ce, (FX_LPCWSTR)L"GulimChe", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0x4f68bd79, (FX_LPCWSTR)L"LetterGothicStd", (FX_LPCWSTR)L"Courier New,Verdana", 0, 1252},
+ {0x51a0d0e6, (FX_LPCWSTR)L"KozukaGothicPr6NM", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x531b3dea, (FX_LPCWSTR)L"BasemicSymbol", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x5333fd39, (FX_LPCWSTR)L"CalifornianFB-Reg", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x53561a54, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x55e0dde6, (FX_LPCWSTR)L"LucidaSansTypewriter", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x574d4d3d, (FX_LPCWSTR)L"AdobeArabic", (FX_LPCWSTR)L"Arial Narrow", 0, 1252},
+ {0x5792e759, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x5921978e, (FX_LPCWSTR)L"LucidaSansUnicode", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x594e2da4, (FX_LPCWSTR)L"Vrinda", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x59baa9a2, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x5cfedf4f, (FX_LPCWSTR)L"BaskOldFace", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x5f97921c, (FX_LPCWSTR)L"AdobeMyungjoStdM", (FX_LPCWSTR)L"Batang,Bookman Old Style,Consolas,STZhongsong", 0, 936},
+ {0x5fefbfad, (FX_LPCWSTR)L"Batang", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x605342b9, (FX_LPCWSTR)L"DotumChe", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0x608c5f9a, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x61efd0d1, (FX_LPCWSTR)L"MaturaMTScriptCapitals", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x626608a9, (FX_LPCWSTR)L"MVBoli", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x630501a3, (FX_LPCWSTR)L"SmallFonts", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x65d0e2a9, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x669f29e1, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x673a9e5f, (FX_LPCWSTR)L"Tunga", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x691aa4ce, (FX_LPCWSTR)L"NiagaraSolid", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x696259b7, (FX_LPCWSTR)L"Corbel", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x696ee9be, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0x6c59cf69, (FX_LPCWSTR)L"Dotum", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x707fa561, (FX_LPCWSTR)L"Gungsuh", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x71416bb2, (FX_LPCWSTR)L"ZWAdobeF", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x71b41801, (FX_LPCWSTR)L"Verdana", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x73f25e4c, (FX_LPCWSTR)L"PalatinoLinotype", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x73f4d19f, (FX_LPCWSTR)L"NiagaraEngraved", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x74001694, (FX_LPCWSTR)L"MyriadProBlack", (FX_LPCWSTR)L"Book Antiqua,Constantia,Dotum,Georgia", 0, 1252},
+ {0x74b14d8f, (FX_LPCWSTR)L"Haettenschweiler", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x74cb44ee, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0x76b4d7ff, (FX_LPCWSTR)L"Shruti", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x788b3533, (FX_LPCWSTR)L"Webdings", (FX_LPCWSTR)L"Arial", 6, 42},
+ {0x797dde99, (FX_LPCWSTR)L"MSSerif", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x7a0f9e9e, (FX_LPCWSTR)L"MSMincho", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0x7b439caf, (FX_LPCWSTR)L"OldEnglishTextMT", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x8213a433, (FX_LPCWSTR)L"LucidaSans-Typewriter", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x82fec929, (FX_LPCWSTR)L"AdobeSongStdL", (FX_LPCWSTR)L"Centaur,Calibri,STSong,Bell MT,Garamond,Times New Roman", 0, 936},
+ {0x83581825, (FX_LPCWSTR)L"Modern", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x835a2823, (FX_LPCWSTR)L"Algerian", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x83dab9f5, (FX_LPCWSTR)L"Script", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x847b56da, (FX_LPCWSTR)L"Tahoma", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x8a783cb2, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x8b5cac0e, (FX_LPCWSTR)L"Onyx", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x8c6a499e, (FX_LPCWSTR)L"Gulim", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x8e0af790, (FX_LPCWSTR)L"JuiceITC", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x8e8d43b2, (FX_LPCWSTR)L"Centaur", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x8ee4dcca, (FX_LPCWSTR)L"BookshelfSymbol7", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x90794800, (FX_LPCWSTR)L"BellGothicStdLight", (FX_LPCWSTR)L"Bell MT,Calibri,Times New Roman", 0, 1252},
+ {0x909b516a, (FX_LPCWSTR)L"Century", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x92ae370d, (FX_LPCWSTR)L"MSOutlook", (FX_LPCWSTR)L"Arial", 4, 42},
+ {0x93c9fbf1, (FX_LPCWSTR)L"LucidaFax", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x9565085e, (FX_LPCWSTR)L"BookAntiqua", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0x9856d95d, (FX_LPCWSTR)L"AdobeMingStdL", (FX_LPCWSTR)L"Arial,Arial Unicode MS,Cambria,BatangChe", 0, 949},
+ {0x9bbadd6b, (FX_LPCWSTR)L"ColonnaMT", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x9cbd16a4, (FX_LPCWSTR)L"ShowcardGothic-Reg", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0x9d73008e, (FX_LPCWSTR)L"MSSansSerif", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xa0607db1, (FX_LPCWSTR)L"GungsuhChe", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0xa0bcf6a1, (FX_LPCWSTR)L"LatinWide", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xa1429b36, (FX_LPCWSTR)L"Symbol", (FX_LPCWSTR)L"Arial", 6, 42},
+ {0xa1fa5abc, (FX_LPCWSTR)L"Wingdings2", (FX_LPCWSTR)L"Arial", 6, 42},
+ {0xa1fa5abd, (FX_LPCWSTR)L"Wingdings3", (FX_LPCWSTR)L"Arial", 6, 42},
+ {0xa427bad4, (FX_LPCWSTR)L"InformalRoman-Regular", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xa8b92ece, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xa8d83ece, (FX_LPCWSTR)L"CalifornianFB", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xaa3e082c, (FX_LPCWSTR)L"Kingsoft-Phonetic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xaa6bcabe, (FX_LPCWSTR)L"HarlowSolidItalic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xade5337c, (FX_LPCWSTR)L"MSUIGothic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xb08dd941, (FX_LPCWSTR)L"WideLatin", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xb207f05d, (FX_LPCWSTR)L"PoorRichard", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xb3bc492f, (FX_LPCWSTR)L"JuiceITC-Regular", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xb5545399, (FX_LPCWSTR)L"Marlett", (FX_LPCWSTR)L"Arial", 4, 42},
+ {0xb5dd1ebb, (FX_LPCWSTR)L"BritannicBold", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xb699c1c5, (FX_LPCWSTR)L"LucidaCalligraphy-Italic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xb725d629, (FX_LPCWSTR)L"TimesNewRoman", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xb7eaebeb, (FX_LPCWSTR)L"AdobeHeitiStdR", (FX_LPCWSTR)L"Batang,Century,Dotum", 0, 936},
+ {0xbd29c486, (FX_LPCWSTR)L"BerlinSansFBDemi-Bold", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xbe8a8db4, (FX_LPCWSTR)L"BookshelfSymbolSeven", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xc16c0118, (FX_LPCWSTR)L"AdobeHebrew", (FX_LPCWSTR)L"Bell MT,Berlin Sans FB,Calibri", 0, 1252},
+ {0xc318b0af, (FX_LPCWSTR)L"MyriadProLight", (FX_LPCWSTR)L"Calibri,STFangsong,Times New Roman", 0, 1252},
+ {0xc65e5659, (FX_LPCWSTR)L"CambriaMath", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xc75c8f05, (FX_LPCWSTR)L"LucidaConsole", (FX_LPCWSTR)L"Arial", 1, 1252},
+ {0xca7c35d6, (FX_LPCWSTR)L"Calibri", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xcb053f53, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xcb7190f9, (FX_LPCWSTR)L"Magneto-Bold", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xcca00cc5, (FX_LPCWSTR)L"System", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xccad6f76, (FX_LPCWSTR)L"Jokerman-Regular", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xccc5818c, (FX_LPCWSTR)L"EuroSign", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xcf3d7234, (FX_LPCWSTR)L"LucidaHandwriting-Italic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xcf7b8fdb, (FX_LPCWSTR)L"MinionPro", (FX_LPCWSTR)L"Bell MT,Corbel,Times New Roman,Cambria,Berlin Sans FB", 0, 1252},
+ {0xcfe5755f, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0xd011f4ee, (FX_LPCWSTR)L"MSPGothic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xd060e7ef, (FX_LPCWSTR)L"Vivaldi", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xd07edec1, (FX_LPCWSTR)L"FranklinGothic-Medium", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xd107243f, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xd1881562, (FX_LPCWSTR)L"ArialNarrow", (FX_LPCWSTR)L"Arial Narrow", 0, 1252},
+ {0xd22b7dce, (FX_LPCWSTR)L"BodoniMTPosterCompressed", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xd22bfa60, (FX_LPCWSTR)L"ComicSansMS", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xd3bd0e35, (FX_LPCWSTR)L"Bauhaus93", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xd429ee7a, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xd6679c12, (FX_LPCWSTR)L"BernardMTCondensed", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xd8e8a027, (FX_LPCWSTR)L"LucidaSans", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xd9fe7761, (FX_LPCWSTR)L"HighTowerText-Reg", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xda7e551e, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdaa6842d, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdaaab93f, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdaeb0713, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdafedbef, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdb00a3d9, (FX_LPCWSTR)L"Broadway", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xdb1f5ad4, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdb326e7f, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdb69595a, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdba0082c, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdbd0ab18, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdc1a7db1, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xdc33075f, (FX_LPCWSTR)L"KristenITC-Regular", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xdcc7009c, (FX_LPCWSTR)L"Harrington", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xdd712466, (FX_LPCWSTR)L"ArialBlack", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xdde87b3e, (FX_LPCWSTR)L"Impact", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xdf69fb32, (FX_LPCWSTR)L"SnapITC", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xdf8b25e8, (FX_LPCWSTR)L"CenturyGothic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xe0f705c0, (FX_LPCWSTR)L"KristenITC", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xe1427573, (FX_LPCWSTR)L"Raavi", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xe2cea0cb, (FX_LPCWSTR)L"Magneto", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xe36a9e17, (FX_LPCWSTR)L"Ravie", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xe433f8e2, (FX_LPCWSTR)L"Parchment", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xe43dff4a, (FX_LPCWSTR)L"Wingdings", (FX_LPCWSTR)L"Arial", 4, 42},
+ {0xe4e2c405, (FX_LPCWSTR)L"MTExtra", (FX_LPCWSTR)L"Arial", 6, 42},
+ {0xe618cc35, (FX_LPCWSTR)L"InformalRoman", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xe6c27ffc, (FX_LPCWSTR)L"Mistral", (FX_LPCWSTR)L"Arial", 8, 1252},
+ {0xe7ebf4b9, (FX_LPCWSTR)L"Courier", (FX_LPCWSTR)L"Courier New", 0, 1252},
+ {0xe8bc4a9d, (FX_LPCWSTR)L"MSReferenceSpecialty", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xe90fb013, (FX_LPCWSTR)L"TempusSansITC", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xec637b42, (FX_LPCWSTR)L"Consolas", (FX_LPCWSTR)L"Verdana", 1, 1252},
+ {0xed3a683b, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xef264cd1, (FX_LPCWSTR)L"LucidaHandwriting", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xf086bca2, (FX_LPCWSTR)L"BaskervilleOldFace", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xf1028030, (FX_LPCWSTR)L"Mangal", (FX_LPCWSTR)L"Arial", 2, 1252},
+ {0xf1da7eb9, (FX_LPCWSTR)L"ShowcardGothic", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xf210f06a, (FX_LPCWSTR)L"ArialMT", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xf477f16a, (FX_LPCWSTR)L"Latha", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xf616f3dd, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"Arial", 1, 936},
+ {0xfa479aa6, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"Arial", 0, 936},
+ {0xfcd19697, (FX_LPCWSTR)L"BookmanOldStyle", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xfe209a82, (FX_LPCWSTR)L"LucidaCalligraphy", (FX_LPCWSTR)L"Arial", 0, 1252},
+ {0xfef135f8, (FX_LPCWSTR)L"AdobeHeitiStd-Regular", (FX_LPCWSTR)L"Batang,Century,Dotum", 0, 936},
+};
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+ {0x01d5d33e, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x01e4f102, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,WenQuanYi Zen Hei Sharp,WenQuanYi Zen Hei,WenQuanYi Micro Hei", 1, 936},
+ {0x030549dc, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Zen Hei Mono,WenQuanYi Micro Hei", 1, 936},
+ {0x032edd44, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Zen Hei Mono,WenQuanYi Micro Hei", 1, 936},
+ {0x03eac6fc, (FX_LPCWSTR)L"PoorRichard-Regular", (FX_LPCWSTR)L"FreeSerif", 2, 1252},
+ {0x03ed90e6, (FX_LPCWSTR)L"Nina", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x077b56b3, (FX_LPCWSTR)L"KingsoftPhoneticPlain", (FX_LPCWSTR)L"utkal,Kedage,Mallige,Kedage,AR PL UKai CN,AR PL UKai HK", 0, 1252},
+ {0x078ed524, (FX_LPCWSTR)L"MicrosoftSansSerif", (FX_LPCWSTR)L"FreeSerif,WenQuanYi Micro Hei", 0, 1252},
+ {0x089b18a9, (FX_LPCWSTR)L"Arial", (FX_LPCWSTR)L"DejaVu Sans Condensed,FreeSerif,WenQuanYi Micro Hei", 0, 1252},
+ {0x0b2cad72, (FX_LPCWSTR)L"MonotypeCorsiva", (FX_LPCWSTR)L"FreeSerif", 8, 1252},
+ {0x0bb003e7, (FX_LPCWSTR)L"Kartika", (FX_LPCWSTR)L"FreeSans,Liberation Sans,Nimbus Sans L,Garuda,FreeSerif,WenQuanYi Micro Hei", 2, 1252},
+ {0x0bb469df, (FX_LPCWSTR)L"VinerHandITC", (FX_LPCWSTR)L"Ubuntu,Liberation Sans,Liberation Serif", 8, 1252},
+ {0x0bc1a851, (FX_LPCWSTR)L"SegoeUI", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x0c112ebd, (FX_LPCWSTR)L"KozukaGothicPro-VIM", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x0cfcb9c1, (FX_LPCWSTR)L"AdobeThai", (FX_LPCWSTR)L" Waree", 0, 847},
+ {0x0e7de0f9, (FX_LPCWSTR)L"Playbill", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x0eff47c3, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 936},
+ {0x107ad374, (FX_LPCWSTR)L"Constantia", (FX_LPCWSTR)L"FreeSerif,WenQuanYi Micro Hei,Ubuntu", 2, 1252},
+ {0x12194c2d, (FX_LPCWSTR)L"KunstlerScript", (FX_LPCWSTR)L"Liberation Serif", 8, 1252},
+ {0x135ef6a1, (FX_LPCWSTR)L"MinionProSmBd", (FX_LPCWSTR)L"Liberation Serif", 0, 1252},
+ {0x158c4049, (FX_LPCWSTR)L"Garamond", (FX_LPCWSTR)L"Liberation Serif,Ubuntu,FreeSerif", 2, 1252},
+ {0x160ecb24, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x161ed07e, (FX_LPCWSTR)L"MSGothic", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp", 1, 1252},
+ {0x171d1ed1, (FX_LPCWSTR)L"SnapITC-Regular", (FX_LPCWSTR)L"Nimbus Sans L,DejaVu Sans", 0, 1252},
+ {0x18d1188f, (FX_LPCWSTR)L"Cambria", (FX_LPCWSTR)L"FreeSerif,FreeMono", 2, 1252},
+ {0x18eaf350, (FX_LPCWSTR)L"ArialUnicodeMS", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x1a92d115, (FX_LPCWSTR)L"MingLiU", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 1252},
+ {0x1cc217c6, (FX_LPCWSTR)L"TrebuchetMS", (FX_LPCWSTR)L"Liberation Serif,FreeSerif,Ubuntu", 0, 1252},
+ {0x1d649596, (FX_LPCWSTR)L"BasemicTimes", (FX_LPCWSTR)L"Liberation Serif,FreeSerif,Ubuntu", 0, 1252},
+ {0x1e34ee60, (FX_LPCWSTR)L"BellMT", (FX_LPCWSTR)L"Ubuntu,Liberation Serif", 2, 1252},
+ {0x1eb36945, (FX_LPCWSTR)L"CooperBlack", (FX_LPCWSTR)L"FreeMono,Liberation Mono, WenQuanYi Micro Hei Mono", 2, 1252},
+ {0x1ef7787d, (FX_LPCWSTR)L"BatangChe", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 1252},
+ {0x20b3bd3a, (FX_LPCWSTR)L"BrushScriptMT", (FX_LPCWSTR)L"URW Chancery L,Liberation Sans", 8, 1252},
+ {0x220877aa, (FX_LPCWSTR)L"Candara", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x22135007, (FX_LPCWSTR)L"FreestyleScript-Regular", (FX_LPCWSTR)L"Liberation Sans", 8, 1252},
+ {0x251059c3, (FX_LPCWSTR)L"Chiller", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x25bed6dd, (FX_LPCWSTR)L"MSReferenceSansSerif", (FX_LPCWSTR)L"DejaVu Sans Condensed,AR PL UKai HK", 0, 1252},
+ {0x28154c81, (FX_LPCWSTR)L"Parchment-Regular", (FX_LPCWSTR)L"Liberation Sans", 8, 1252},
+ {0x29711eb9, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"AR PL UKai HK", 0, 936},
+ {0x2b1993b4, (FX_LPCWSTR)L"Basemic", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x2b316339, (FX_LPCWSTR)L"NiagaraSolid-Reg", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x2c147529, (FX_LPCWSTR)L"FootlightMTLight", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x2c198928, (FX_LPCWSTR)L"HarlowSolid", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x2c6ac6b2, (FX_LPCWSTR)L"LucidaBright", (FX_LPCWSTR)L"Liberation Sans", 2, 1252},
+ {0x2c9f38e2, (FX_LPCWSTR)L"KozukaMinchoPro-VIR", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x2d5a47b0, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"AR PL UKai HK", 0, 936},
+ {0x2def26bf, (FX_LPCWSTR)L"BernardMT-Condensed", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x2fd8930b, (FX_LPCWSTR)L"KozukaMinchoPr6NR", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x3115525a, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0x31327817, (FX_LPCWSTR)L"MyriadPro", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x32244975, (FX_LPCWSTR)L"Helvetica", (FX_LPCWSTR)L"Ubuntu,DejaVu Sans Condensed,Liberation Sans", 0, 1252},
+ {0x32ac995c, (FX_LPCWSTR)L"Terminal", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x338d648a, (FX_LPCWSTR)L"NiagaraEngraved-Reg", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x33bb65f2, (FX_LPCWSTR)L"Sylfaen", (FX_LPCWSTR)L"DejaVu Sans", 2, 1252},
+ {0x3402c30e, (FX_LPCWSTR)L"MSPMincho", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 2, 1252},
+ {0x3412bf31, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x36eb39b9, (FX_LPCWSTR)L"BerlinSansFB", (FX_LPCWSTR)L"Liberation Serif,Ubuntu,FreeSerif", 0, 1252},
+ {0x36f42055, (FX_LPCWSTR)L"UniversATT", (FX_LPCWSTR)L"Microsoft Sans Serif", 0, 1252},
+ {0x3864c4f6, (FX_LPCWSTR)L"HighTowerText", (FX_LPCWSTR)L"DejaVu Serif", 2, 1252},
+ {0x3a257d03, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0x3c7d1d07, (FX_LPCWSTR)L"Garamond3LTStd", (FX_LPCWSTR)L"Ubuntu Condensed,DejaVu Sans Condensed,Liberation Serif,Ubuntu,FreeSerif", 2, 1252},
+ {0x3cdae668, (FX_LPCWSTR)L"FreestyleScript", (FX_LPCWSTR)L"DejaVu Sans", 8, 1252},
+ {0x3d55aed7, (FX_LPCWSTR)L"Jokerman", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x3d5b4385, (FX_LPCWSTR)L"PMingLiU", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 2, 1252},
+ {0x3d9b7669, (FX_LPCWSTR)L"EstrangeloEdessa", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x3e532d74, (FX_LPCWSTR)L"FranklinGothicMedium", (FX_LPCWSTR)L"Ubuntu", 0, 1252},
+ {0x3e6aa32d, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 936},
+ {0x3f6c36a8, (FX_LPCWSTR)L"Gautami", (FX_LPCWSTR)L"FreeSans", 0, 1252},
+ {0x3ff32662, (FX_LPCWSTR)L"Chiller-Regular", (FX_LPCWSTR)L"FreeSans", 0, 1252},
+ {0x409de312, (FX_LPCWSTR)L"ModernNo.20", (FX_LPCWSTR)L"Nimbus Sans L,Nimbus Sans L,FreeSans", 2, 1252},
+ {0x41443c5e, (FX_LPCWSTR)L"Georgia", (FX_LPCWSTR)L"FreeSans", 2, 1252},
+ {0x4160ade5, (FX_LPCWSTR)L"BellGothicStdBlack", (FX_LPCWSTR)L"FreeSans", 0, 1252},
+ {0x421976c4, (FX_LPCWSTR)L"Modern-Regular", (FX_LPCWSTR)L"FreeSans", 2, 1252},
+ {0x422a7252, (FX_LPCWSTR)L"Stencil", (FX_LPCWSTR)L"FreeSans,Liberation Sans", 0, 1252},
+ {0x42c8554f, (FX_LPCWSTR)L"Fixedsys", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x435cb41d, (FX_LPCWSTR)L"Roman", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x47882383, (FX_LPCWSTR)L"CourierNew", (FX_LPCWSTR)L"FreeMono,WenQuanYi Micro Hei Mono,AR PL UKai CN,AR PL UKai HK,AR PL UKai TW,AR PL UKai TW MBE,DejaVu Sans", 1, 1252},
+ {0x480a2338, (FX_LPCWSTR)L"BerlinSansFBDemi", (FX_LPCWSTR)L" Liberation Serif", 0, 1252},
+ {0x480bf7a4, (FX_LPCWSTR)L"CourierStd", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x481ad6ed, (FX_LPCWSTR)L"VladimirScript", (FX_LPCWSTR)L"DejaVu Serif", 8, 1252},
+ {0x4911577a, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 936},
+ {0x4a788d72, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 936},
+ {0x4bf88566, (FX_LPCWSTR)L"SegoeCondensed", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x4ccf51a4, (FX_LPCWSTR)L"BerlinSansFB-Reg", (FX_LPCWSTR)L"Liberation Serif", 0, 1252},
+ {0x4ea967ce, (FX_LPCWSTR)L"GulimChe", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UKai CN,AR PL UKai HK,AR PL UKai TW,AR PL UKai TW MBE,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 1252},
+ {0x4f68bd79, (FX_LPCWSTR)L"LetterGothicStd", (FX_LPCWSTR)L"FreeMono,Liberation Mono,WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,AR PL UKai CN,AR PL UKai HK,AR PL UKai TW,AR PL UKai TW MBE", 0, 1252},
+ {0x51a0d0e6, (FX_LPCWSTR)L"KozukaGothicPr6NM", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x531b3dea, (FX_LPCWSTR)L"BasemicSymbol", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x5333fd39, (FX_LPCWSTR)L"CalifornianFB-Reg", (FX_LPCWSTR)L"URW Chancery L,FreeSerif", 2, 1252},
+ {0x53561a54, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x55e0dde6, (FX_LPCWSTR)L"LucidaSansTypewriter", (FX_LPCWSTR)L"DejaVu Sans Mono,Nimbus Mono L,Liberation Mono,Courier 10 Pitch,FreeMono", 0, 1252},
+ {0x574d4d3d, (FX_LPCWSTR)L"AdobeArabic", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x5792e759, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono", 0, 936},
+ {0x5921978e, (FX_LPCWSTR)L"LucidaSansUnicode", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x594e2da4, (FX_LPCWSTR)L"Vrinda", (FX_LPCWSTR)L"FreeSans,FreeSerif", 0, 1252},
+ {0x59baa9a2, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0x5cfedf4f, (FX_LPCWSTR)L"BaskOldFace", (FX_LPCWSTR)L"Ubuntu,Liberation Serif", 0, 1252},
+ {0x5e16ac91, (FX_LPCWSTR)L"TrajanPro", (FX_LPCWSTR)L"Nimbus Sans L,AR PL UMing HK,AR PL UKai HK,AR PL UMing TW,AR PL UMing TW MBE,DejaVu Sans,DejaVu Serif", 0, 1252},
+ {0x5f388196, (FX_LPCWSTR)L"ITCLegacySansStdMedium", (FX_LPCWSTR)L"Liberation Serif,FreeSerif,FreeSans,Ubuntu", 0, 1252},
+ {0x5f97921c, (FX_LPCWSTR)L"AdobeMyungjoStdM", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x5fefbfad, (FX_LPCWSTR)L"Batang", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 2, 1252},
+ {0x605342b9, (FX_LPCWSTR)L"DotumChe", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UKai CN,AR PL UKai HK,AR PL UKai TW,AR PL UKai TW MBE,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 1252},
+ {0x608c5f9a, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x61efd0d1, (FX_LPCWSTR)L"MaturaMTScriptCapitals", (FX_LPCWSTR)L"DejaVu Serif,DejaVu Sans", 0, 1252},
+ {0x626608a9, (FX_LPCWSTR)L"MVBoli", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x630501a3, (FX_LPCWSTR)L"SmallFonts", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x65d0e2a9, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x669f29e1, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"AR PL UMing CN,AR PL UKai CN, AR PL UMing HK", 0, 936},
+ {0x673a9e5f, (FX_LPCWSTR)L"Tunga", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x691aa4ce, (FX_LPCWSTR)L"NiagaraSolid", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x696259b7, (FX_LPCWSTR)L"Corbel", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0x696ee9be, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono", 0, 936},
+ {0x6c59cf69, (FX_LPCWSTR)L"Dotum", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0x707fa561, (FX_LPCWSTR)L"Gungsuh", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 2, 1252},
+ {0x71416bb2, (FX_LPCWSTR)L"ZWAdobeF", (FX_LPCWSTR)L"Dingbats,FreeSerif", 0, 1252},
+ {0x71b41801, (FX_LPCWSTR)L"Verdana", (FX_LPCWSTR)L"DejaVu Sans Condensed,DejaVu Sans", 0, 1252},
+ {0x73f25e4c, (FX_LPCWSTR)L"PalatinoLinotype", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x73f4d19f, (FX_LPCWSTR)L"NiagaraEngraved", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0x74001694, (FX_LPCWSTR)L"MyriadProBlack", (FX_LPCWSTR)L"AR PL UKai HK", 0, 1252},
+ {0x74b14d8f, (FX_LPCWSTR)L"Haettenschweiler", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0x74cb44ee, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 936},
+ {0x76b4d7ff, (FX_LPCWSTR)L"Shruti", (FX_LPCWSTR)L"FreeSans", 0, 1252},
+ {0x788b3533, (FX_LPCWSTR)L"Webdings", (FX_LPCWSTR)L"FreeSans", 6, 42},
+ {0x797dde99, (FX_LPCWSTR)L"MSSerif", (FX_LPCWSTR)L"FreeSans", 0, 1252},
+ {0x7a0f9e9e, (FX_LPCWSTR)L"MSMincho", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono", 1, 1252},
+ {0x7b439caf, (FX_LPCWSTR)L"OldEnglishTextMT", (FX_LPCWSTR)L"Liberation Sans,Ubuntu", 0, 1252},
+ {0x8213a433, (FX_LPCWSTR)L"LucidaSans-Typewriter", (FX_LPCWSTR)L"Liberation Mono", 0, 1252},
+ {0x82fec929, (FX_LPCWSTR)L"AdobeSongStdL", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0x83581825, (FX_LPCWSTR)L"Modern", (FX_LPCWSTR)L"FreeSans", 0, 1252},
+ {0x835a2823, (FX_LPCWSTR)L"Algerian", (FX_LPCWSTR)L"FreeSans,Liberation Sans,Ubuntu", 0, 1252},
+ {0x83dab9f5, (FX_LPCWSTR)L"Script", (FX_LPCWSTR)L"FreeSans", 0, 1252},
+ {0x847b56da, (FX_LPCWSTR)L"Tahoma", (FX_LPCWSTR)L"DejaVu Sans Condensed,FreeSerif", 0, 1252},
+ {0x8a783cb2, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0x8b5cac0e, (FX_LPCWSTR)L"Onyx", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x8c6a499e, (FX_LPCWSTR)L"Gulim", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0x8e0af790, (FX_LPCWSTR)L"JuiceITC", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x8e8d43b2, (FX_LPCWSTR)L"Centaur", (FX_LPCWSTR)L"Khmer OS,Khmer OS System", 2, 1252},
+ {0x8ee4dcca, (FX_LPCWSTR)L"BookshelfSymbol7", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x90794800, (FX_LPCWSTR)L"BellGothicStdLight", (FX_LPCWSTR)L"Liberation Sans", 0, 1252},
+ {0x909b516a, (FX_LPCWSTR)L"Century", (FX_LPCWSTR)L"Liberation Sans,Liberation Mono,Liberation Serif", 2, 1252},
+ {0x92ae370d, (FX_LPCWSTR)L"MSOutlook", (FX_LPCWSTR)L"Liberation Sans", 4, 42},
+ {0x93c9fbf1, (FX_LPCWSTR)L"LucidaFax", (FX_LPCWSTR)L"Liberation Sans", 2, 1252},
+ {0x9565085e, (FX_LPCWSTR)L"BookAntiqua", (FX_LPCWSTR)L"Liberation Sans,Liberation Serif", 2, 1252},
+ {0x9856d95d, (FX_LPCWSTR)L"AdobeMingStdL", (FX_LPCWSTR)L"AR PL UMing HK", 0, 949},
+ {0x9bbadd6b, (FX_LPCWSTR)L"ColonnaMT", (FX_LPCWSTR)L"Khmer OS,Khmer OS System", 0, 1252},
+ {0x9cbd16a4, (FX_LPCWSTR)L"ShowcardGothic-Reg", (FX_LPCWSTR)L"Liberation Sans,Ubuntu", 0, 1252},
+ {0x9d73008e, (FX_LPCWSTR)L"MSSansSerif", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0xa0607db1, (FX_LPCWSTR)L"GungsuhChe", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 1252},
+ {0xa0bcf6a1, (FX_LPCWSTR)L"LatinWide", (FX_LPCWSTR)L"FreeSerif", 2, 1252},
+ {0xa1429b36, (FX_LPCWSTR)L"Symbol", (FX_LPCWSTR)L"FreeSerif", 6, 42},
+ {0xa1fa5abc, (FX_LPCWSTR)L"Wingdings2", (FX_LPCWSTR)L"FreeSerif", 6, 42},
+ {0xa1fa5abd, (FX_LPCWSTR)L"Wingdings3", (FX_LPCWSTR)L"FreeSerif", 6, 42},
+ {0xa427bad4, (FX_LPCWSTR)L"InformalRoman-Regular", (FX_LPCWSTR)L"FreeSerif", 8, 1252},
+ {0xa8b92ece, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"AR PL UMing CN", 0, 936},
+ {0xa8d83ece, (FX_LPCWSTR)L"CalifornianFB", (FX_LPCWSTR)L"FreeSerif", 2, 1252},
+ {0xaa3e082c, (FX_LPCWSTR)L"Kingsoft-Phonetic", (FX_LPCWSTR)L"utkal,Kedage,Mallige,AR PL UKai CN", 0, 1252},
+ {0xaa6bcabe, (FX_LPCWSTR)L"HarlowSolidItalic", (FX_LPCWSTR)L"Liberation Serif", 0, 1252},
+ {0xade5337c, (FX_LPCWSTR)L"MSUIGothic", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0xb08dd941, (FX_LPCWSTR)L"WideLatin", (FX_LPCWSTR)L"Liberation Serif", 2, 1252},
+ {0xb12765e0, (FX_LPCWSTR)L"ITCLegacySansStdBook", (FX_LPCWSTR)L"AR PL UMing HK,AR PL UKai HK,FreeSerif,Ubuntu,FreeSans", 0, 1252},
+ {0xb207f05d, (FX_LPCWSTR)L"PoorRichard", (FX_LPCWSTR)L"Liberation Serif", 2, 1252},
+ {0xb3bc492f, (FX_LPCWSTR)L"JuiceITC-Regular", (FX_LPCWSTR)L"Liberation Serif", 0, 1252},
+ {0xb5545399, (FX_LPCWSTR)L"Marlett", (FX_LPCWSTR)L"Liberation Serif", 4, 42},
+ {0xb5dd1ebb, (FX_LPCWSTR)L"BritannicBold", (FX_LPCWSTR)L"Liberation Serif", 0, 1252},
+ {0xb699c1c5, (FX_LPCWSTR)L"LucidaCalligraphy-Italic", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0xb725d629, (FX_LPCWSTR)L"TimesNewRoman", (FX_LPCWSTR)L"Liberation Sans", 2, 1252},
+ {0xb7eaebeb, (FX_LPCWSTR)L"AdobeHeitiStdR", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0xbd29c486, (FX_LPCWSTR)L"BerlinSansFBDemi-Bold", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0xbe8a8db4, (FX_LPCWSTR)L"BookshelfSymbolSeven", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0xc16c0118, (FX_LPCWSTR)L"AdobeHebrew", (FX_LPCWSTR)L"Ubuntu,Liberation Serif", 0, 1252},
+ {0xc318b0af, (FX_LPCWSTR)L"MyriadProLight", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 1252},
+ {0xc65e5659, (FX_LPCWSTR)L"CambriaMath", (FX_LPCWSTR)L"FreeSerif,FreeMono", 2, 1252},
+ {0xc75c8f05, (FX_LPCWSTR)L"LucidaConsole", (FX_LPCWSTR)L"DejaVu Sans Mono,FreeMono,Liberation Mono,WenQuanYi Micro Hei Mono", 1, 1252},
+ {0xca7c35d6, (FX_LPCWSTR)L"Calibri", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0xcb053f53, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0xcb7190f9, (FX_LPCWSTR)L"Magneto-Bold", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0xcca00cc5, (FX_LPCWSTR)L"System", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0xccad6f76, (FX_LPCWSTR)L"Jokerman-Regular", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0xccc5818c, (FX_LPCWSTR)L"EuroSign", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0xcf3d7234, (FX_LPCWSTR)L"LucidaHandwriting-Italic", (FX_LPCWSTR)L"Nimbus Sans L,DejaVu Serif", 0, 1252},
+ {0xcf7b8fdb, (FX_LPCWSTR)L"MinionPro", (FX_LPCWSTR)L"DejaVu Sans", 0, 1252},
+ {0xcfe5755f, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 936},
+ {0xd011f4ee, (FX_LPCWSTR)L"MSPGothic", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 1252},
+ {0xd060e7ef, (FX_LPCWSTR)L"Vivaldi", (FX_LPCWSTR)L"Liberation Sans,Ubuntu", 8, 1252},
+ {0xd07edec1, (FX_LPCWSTR)L"FranklinGothic-Medium", (FX_LPCWSTR)L"Ubuntu", 0, 1252},
+ {0xd107243f, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0xd1881562, (FX_LPCWSTR)L"ArialNarrow", (FX_LPCWSTR)L"FreeSerif", 0, 1252},
+ {0xd22b7dce, (FX_LPCWSTR)L"BodoniMTPosterCompressed", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0xd22bfa60, (FX_LPCWSTR)L"ComicSansMS", (FX_LPCWSTR)L"FreeMono,Liberation Mono", 8, 1252},
+ {0xd3bd0e35, (FX_LPCWSTR)L"Bauhaus93", (FX_LPCWSTR)L"Liberation Sans,Ubuntu", 0, 1252},
+ {0xd429ee7a, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono", 0, 936},
+ {0xd6679c12, (FX_LPCWSTR)L"BernardMTCondensed", (FX_LPCWSTR)L"Nimbus Sans L,URW Chancery L,KacstOne,Liberation Sans", 0, 1252},
+ {0xd8e8a027, (FX_LPCWSTR)L"LucidaSans", (FX_LPCWSTR)L"Nimbus Sans L,DejaVu Serif Condensed,Liberation Mono,Ubuntu", 0, 1252},
+ {0xd9fe7761, (FX_LPCWSTR)L"HighTowerText-Reg", (FX_LPCWSTR)L"Ubuntu,Liberation Serif", 2, 1252},
+ {0xda7e551e, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono", 0, 936},
+ {0xdaa6842d, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0xdaaab93f, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp", 0, 936},
+ {0xdaeb0713, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp", 0, 936},
+ {0xdafedbef, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 936},
+ {0xdb00a3d9, (FX_LPCWSTR)L"Broadway", (FX_LPCWSTR)L"DejaVu Sans,FreeMono,Liberation Mono", 0, 1252},
+ {0xdb1f5ad4, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 936},
+ {0xdb326e7f, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp", 0, 936},
+ {0xdb69595a, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp", 0, 936},
+ {0xdba0082c, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L" WenQuanYi Micro Hei Mono,WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp", 0, 936},
+ {0xdbd0ab18, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 936},
+ {0xdc1a7db1, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 936},
+ {0xdc33075f, (FX_LPCWSTR)L"KristenITC-Regular", (FX_LPCWSTR)L"DejaVu Sans Condensed,Ubuntu,Liberation Sans", 8, 1252},
+ {0xdcc7009c, (FX_LPCWSTR)L"Harrington", (FX_LPCWSTR)L"Liberation Serif,FreeSerif,Ubuntu", 0, 1252},
+ {0xdd712466, (FX_LPCWSTR)L"ArialBlack", (FX_LPCWSTR)L"DejaVu Sans,DejaVu Serif,FreeMono", 0, 1252},
+ {0xdde87b3e, (FX_LPCWSTR)L"Impact", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0xdf69fb32, (FX_LPCWSTR)L"SnapITC", (FX_LPCWSTR)L"DejaVu Sans,DejaVu Serif,FreeMono", 0, 1252},
+ {0xdf8b25e8, (FX_LPCWSTR)L"CenturyGothic", (FX_LPCWSTR)L"Liberation Mono,Liberation Sans,Liberation Serif", 0, 1252},
+ {0xe0f705c0, (FX_LPCWSTR)L"KristenITC", (FX_LPCWSTR)L"DejaVu Sans Condensed,Ubuntu,Liberation Sans", 8, 1252},
+ {0xe1427573, (FX_LPCWSTR)L"Raavi", (FX_LPCWSTR)L"FreeSerif,Liberation Serif,Khmer OS", 0, 1252},
+ {0xe2cea0cb, (FX_LPCWSTR)L"Magneto", (FX_LPCWSTR)L"DejaVu Serif,DejaVu Serif Condensed,DejaVu Sans", 0, 1252},
+ {0xe36a9e17, (FX_LPCWSTR)L"Ravie", (FX_LPCWSTR)L"DejaVu Serif,DejaVu Sans,FreeMono", 0, 1252},
+ {0xe433f8e2, (FX_LPCWSTR)L"Parchment", (FX_LPCWSTR)L"DejaVu Serif", 8, 1252},
+ {0xe43dff4a, (FX_LPCWSTR)L"Wingdings", (FX_LPCWSTR)L"DejaVu Serif", 4, 42},
+ {0xe4e2c405, (FX_LPCWSTR)L"MTExtra", (FX_LPCWSTR)L"DejaVu Serif", 6, 42},
+ {0xe618cc35, (FX_LPCWSTR)L"InformalRoman", (FX_LPCWSTR)L"Nimbus Sans L,DejaVu Sans Condensed,Ubuntu,Liberation Sans", 8, 1252},
+ {0xe6c27ffc, (FX_LPCWSTR)L"Mistral", (FX_LPCWSTR)L"DejaVu Serif", 8, 1252},
+ {0xe7ebf4b9, (FX_LPCWSTR)L"Courier", (FX_LPCWSTR)L"DejaVu Sans,DejaVu Sans Condensed,FreeSerif", 0, 1252},
+ {0xe8bc4a9d, (FX_LPCWSTR)L"MSReferenceSpecialty", (FX_LPCWSTR)L"DejaVu Serif", 0, 1252},
+ {0xe90fb013, (FX_LPCWSTR)L"TempusSansITC", (FX_LPCWSTR)L"Ubuntu,Liberation Serif,FreeSerif", 0, 1252},
+ {0xec637b42, (FX_LPCWSTR)L"Consolas", (FX_LPCWSTR)L"DejaVu Sans Condensed,FreeSerif,FreeSans", 1, 1252},
+ {0xed3a683b, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"AR PL UKai HK,AR PL UMing HK,AR PL UKai CN", 0, 936},
+ {0xef264cd1, (FX_LPCWSTR)L"LucidaHandwriting", (FX_LPCWSTR)L"DejaVu Serif,DejaVu Sans,FreeMono,Liberation Mono", 0, 1252},
+ {0xf086bca2, (FX_LPCWSTR)L"BaskervilleOldFace", (FX_LPCWSTR)L"Liberation Serif,Ubuntu,FreeSerif", 0, 1252},
+ {0xf1028030, (FX_LPCWSTR)L"Mangal", (FX_LPCWSTR)L"FreeSans,Garuda,Liberation Sans,Nimbus Sans L,FreeSerif,WenQuanYi Micro Hei", 2, 1252},
+ {0xf1da7eb9, (FX_LPCWSTR)L"ShowcardGothic", (FX_LPCWSTR)L"DejaVu Serif Condensed,DejaVu Sans Condensed,Liberation Sans,Ubuntu", 0, 1252},
+ {0xf210f06a, (FX_LPCWSTR)L"ArialMT", (FX_LPCWSTR)L"Liberation Sans,FreeSans,Nimbus Sans L,Khmer OS System,Khmer OS", 0, 1252},
+ {0xf477f16a, (FX_LPCWSTR)L"Latha", (FX_LPCWSTR)L"Nimbus Sans L,FreeSerif,Nimbus Sans L", 0, 1252},
+ {0xf616f3dd, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 1, 936},
+ {0xfa479aa6, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+ {0xfcd19697, (FX_LPCWSTR)L"BookmanOldStyle", (FX_LPCWSTR)L"Liberation Mono,Liberation Sans,Liberation Serif", 0, 1252},
+ {0xfe209a82, (FX_LPCWSTR)L"LucidaCalligraphy", (FX_LPCWSTR)L"DejaVu Serif,DejaVu Sans,FreeMono", 0, 1252},
+ {0xfef135f8, (FX_LPCWSTR)L"AdobeHeitiStd-Regular", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,WenQuanYi Zen Hei,WenQuanYi Zen Hei Sharp,WenQuanYi Micro Hei", 0, 936},
+};
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+ {0x01d5d33e, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 0, 936},
+ {0x01e4f102, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 1, 936},
+ {0x030549dc, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 1, 936},
+ {0x032edd44, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 1, 936},
+ {0x03eac6fc, (FX_LPCWSTR)L"PoorRichard-Regular", (FX_LPCWSTR)L"Noteworthy,Avenir Next Condensed,Impact", 2, 1252},
+ {0x03ed90e6, (FX_LPCWSTR)L"Nina", (FX_LPCWSTR)L"Microsoft Sans Serif", 0, 1252},
+ {0x077b56b3, (FX_LPCWSTR)L"KingsoftPhoneticPlain", (FX_LPCWSTR)L"LastResort,Apple Chancery,STIXVariants,STIXSizeOneSym,STIXSizeOneSym,Apple Braille", 0, 1252},
+ {0x078ed524, (FX_LPCWSTR)L"MicrosoftSansSerif", (FX_LPCWSTR)L"Songti SC,Apple Symbols", 0, 1252},
+ {0x089b18a9, (FX_LPCWSTR)L"Arial", (FX_LPCWSTR)L"Arial Unicode MS,Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x0b2cad72, (FX_LPCWSTR)L"MonotypeCorsiva", (FX_LPCWSTR)L"Arial Narrow,Impact", 8, 1252},
+ {0x0bb003e7, (FX_LPCWSTR)L"Kartika", (FX_LPCWSTR)L"Arial Unicode MS,Microsoft Sans Serif,Arial Narrow,Damascus", 2, 1252},
+ {0x0bb469df, (FX_LPCWSTR)L"VinerHandITC", (FX_LPCWSTR)L"Comic Sans MS,Songti SC,STSong", 8, 1252},
+ {0x0bc1a851, (FX_LPCWSTR)L"SegoeUI", (FX_LPCWSTR)L"Apple Symbols", 0, 1252},
+ {0x0c112ebd, (FX_LPCWSTR)L"KozukaGothicPro-VIM", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x0cfcb9c1, (FX_LPCWSTR)L"AdobeThai", (FX_LPCWSTR)L"Avenir Next Condensed Ultra Light", 0, 847},
+ {0x0e7de0f9, (FX_LPCWSTR)L"Playbill", (FX_LPCWSTR)L"STIXNonUnicode", 0, 1252},
+ {0x0eff47c3, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+ {0x107ad374, (FX_LPCWSTR)L"Constantia", (FX_LPCWSTR)L"Arial Unicode MS,Palatino,Baskerville", 2, 1252},
+ {0x12194c2d, (FX_LPCWSTR)L"KunstlerScript", (FX_LPCWSTR)L"Avenir Next Condensed Demi Bold,Arial Narrow", 8, 1252},
+ {0x135ef6a1, (FX_LPCWSTR)L"MinionProSmBd", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x158c4049, (FX_LPCWSTR)L"Garamond", (FX_LPCWSTR)L"Impact,Arial Narrow", 2, 1252},
+ {0x160ecb24, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"STFangsong,Songti SC", 0, 936},
+ {0x161ed07e, (FX_LPCWSTR)L"MSGothic", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,Microsoft Sans Serif,Apple Symbols", 1, 1252},
+ {0x171d1ed1, (FX_LPCWSTR)L"SnapITC-Regular", (FX_LPCWSTR)L"STHeiti,Arial Black", 0, 1252},
+ {0x18d1188f, (FX_LPCWSTR)L"Cambria", (FX_LPCWSTR)L"Arial Unicode MS", 2, 1252},
+ {0x18eaf350, (FX_LPCWSTR)L"ArialUnicodeMS", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 936},
+ {0x1a92d115, (FX_LPCWSTR)L"MingLiU", (FX_LPCWSTR)L"Heiti SC,STHeiti", 1, 1252},
+ {0x1cc217c6, (FX_LPCWSTR)L"TrebuchetMS", (FX_LPCWSTR)L"Damascus,Impact,Arial Narrow", 0, 1252},
+ {0x1d649596, (FX_LPCWSTR)L"BasemicTimes", (FX_LPCWSTR)L"Liberation Serif,Impact,Arial Narrow", 0, 1252},
+ {0x1e34ee60, (FX_LPCWSTR)L"BellMT", (FX_LPCWSTR)L"Papyrus,STIXNonUnicode,Microsoft Sans Serif,Avenir Light", 2, 1252},
+ {0x1eb36945, (FX_LPCWSTR)L"CooperBlack", (FX_LPCWSTR)L"Marion,STIXNonUnicode,Arial Rounded MT Bold,Lucida Grande", 2, 1252},
+ {0x1ef7787d, (FX_LPCWSTR)L"BatangChe", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UMing CN,,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,Arial Unicode MS,Heiti TC", 1, 1252},
+ {0x20b3bd3a, (FX_LPCWSTR)L"BrushScriptMT", (FX_LPCWSTR)L"STIXNonUnicode,Damascus,Arial Narrow,Avenir Next Condensed,Cochin", 8, 1252},
+ {0x220877aa, (FX_LPCWSTR)L"Candara", (FX_LPCWSTR)L"Cochin,Baskerville,Marion", 0, 1252},
+ {0x22135007, (FX_LPCWSTR)L"FreestyleScript-Regular", (FX_LPCWSTR)L"STIXNonUnicode,Nadeem,Zapf Dingbats", 8, 1252},
+ {0x251059c3, (FX_LPCWSTR)L"Chiller", (FX_LPCWSTR)L"Zapf Dingbats,Damascus,STIXNonUnicode,Papyrus,KufiStandardGK,Baghdad", 0, 1252},
+ {0x25bed6dd, (FX_LPCWSTR)L"MSReferenceSansSerif", (FX_LPCWSTR)L"Tahoma,Apple Symbols,Apple LiGothic,Arial Unicode MS,Lucida Grande,Microsoft Sans Serif", 0, 1252},
+ {0x28154c81, (FX_LPCWSTR)L"Parchment-Regular", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 8, 1252},
+ {0x29711eb9, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"Kaiti SC,Songti SC", 0, 936},
+ {0x2b1993b4, (FX_LPCWSTR)L"Basemic", (FX_LPCWSTR)L"Impact,Arial Narrow", 0, 1252},
+ {0x2b316339, (FX_LPCWSTR)L"NiagaraSolid-Reg", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x2c147529, (FX_LPCWSTR)L"FootlightMTLight", (FX_LPCWSTR)L"STIXNonUnicode,Avenir Next Condensed Heavy,PT Sans,Noteworthy", 0, 1252},
+ {0x2c198928, (FX_LPCWSTR)L"HarlowSolid", (FX_LPCWSTR)L"Avenir Medium,Avenir Next Medium,Arial Unicode MS", 0, 1252},
+ {0x2c6ac6b2, (FX_LPCWSTR)L"LucidaBright", (FX_LPCWSTR)L"PT Sans Narrow,Papyrus,Damascus,STIXNonUnicode,Arial Rounded MT Bold,Comic Sans MS,Avenir Next", 2, 1252},
+ {0x2c9f38e2, (FX_LPCWSTR)L"KozukaMinchoPro-VIR", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x2d5a47b0, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"Kaiti SC,Songti SC", 0, 936},
+ {0x2def26bf, (FX_LPCWSTR)L"BernardMT-Condensed", (FX_LPCWSTR)L"Impact,Avenir Next Condensed Demi Bold,American Typewriter", 0, 1252},
+ {0x2fd8930b, (FX_LPCWSTR)L"KozukaMinchoPr6NR", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x3115525a, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"Hiragino Sans GB,STHeiti", 0, 1252},
+ {0x31327817, (FX_LPCWSTR)L"MyriadPro", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x32244975, (FX_LPCWSTR)L"Helvetica", (FX_LPCWSTR)L"Arial Narrow,Arial Unicode MS,Damascus,STIXNonUnicode,Liberation Sans,Nimbus Sans L,Avenir Next Medium", 0, 1252},
+ {0x32ac995c, (FX_LPCWSTR)L"Terminal", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x338d648a, (FX_LPCWSTR)L"NiagaraEngraved-Reg", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x33bb65f2, (FX_LPCWSTR)L"Sylfaen", (FX_LPCWSTR)L"Arial Unicode MS,Marion", 2, 1252},
+ {0x3402c30e, (FX_LPCWSTR)L"MSPMincho", (FX_LPCWSTR)L"Arial Unicode MS,Apple SD Gothic Neo", 2, 1252},
+ {0x3412bf31, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 0, 936},
+ {0x36eb39b9, (FX_LPCWSTR)L"BerlinSansFB", (FX_LPCWSTR)L"American Typewriter,Impact", 0, 1252},
+ {0x36f42055, (FX_LPCWSTR)L"UniversATT", (FX_LPCWSTR)L"Microsoft Sans Serif", 0, 1252},
+ {0x3864c4f6, (FX_LPCWSTR)L"HighTowerText", (FX_LPCWSTR)L"STIXGeneral,.Helvetica Neue Desk UI", 2, 1252},
+ {0x3a257d03, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"Hiragino Sans GB,STHeiti", 0, 1252},
+ {0x3cdae668, (FX_LPCWSTR)L"FreestyleScript", (FX_LPCWSTR)L"Nadeem,Zapf Dingbats,STIXNonUnicode", 8, 1252},
+ {0x3d55aed7, (FX_LPCWSTR)L"Jokerman", (FX_LPCWSTR)L"Papyrus,Lucida Grande,Heiti TC,American Typewriter", 0, 1252},
+ {0x3d5b4385, (FX_LPCWSTR)L"PMingLiU", (FX_LPCWSTR)L"Heiti SC,STHeiti", 2, 1252},
+ {0x3d9b7669, (FX_LPCWSTR)L"EstrangeloEdessa", (FX_LPCWSTR)L"American Typewriter,Marion", 0, 1252},
+ {0x3e532d74, (FX_LPCWSTR)L"FranklinGothicMedium", (FX_LPCWSTR)L"Impact,Arial Narrow", 0, 1252},
+ {0x3e6aa32d, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"STHeiti,STFangsong", 1, 936},
+ {0x3f6c36a8, (FX_LPCWSTR)L"Gautami", (FX_LPCWSTR)L"Damascus,STIXNonUnicode,STIXGeneral,American Typewriter", 0, 1252},
+ {0x3ff32662, (FX_LPCWSTR)L"Chiller-Regular", (FX_LPCWSTR)L"Papyrus,KufiStandardGK,Baghdad", 0, 1252},
+ {0x409de312, (FX_LPCWSTR)L"ModernNo.20", (FX_LPCWSTR)L"Avenir Next Condensed,Impact", 2, 1252},
+ {0x41443c5e, (FX_LPCWSTR)L"Georgia", (FX_LPCWSTR)L".Helvetica Neue Desk UI,Arial Unicode MS", 2, 1252},
+ {0x4160ade5, (FX_LPCWSTR)L"BellGothicStdBlack", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x421976c4, (FX_LPCWSTR)L"Modern-Regular", (FX_LPCWSTR)L"Impact", 2, 1252},
+ {0x422a7252, (FX_LPCWSTR)L"Stencil", (FX_LPCWSTR)L"STIXNonUnicode,Songti SC,Georgia,Baskerville", 0, 1252},
+ {0x42c8554f, (FX_LPCWSTR)L"Fixedsys", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x435cb41d, (FX_LPCWSTR)L"Roman", (FX_LPCWSTR)L"Arial Narrow", 0, 1252},
+ {0x47882383, (FX_LPCWSTR)L"CourierNew", (FX_LPCWSTR)L"PCMyungjo,Osaka,Arial Unicode MS,Songti SC", 1, 1252},
+ {0x480a2338, (FX_LPCWSTR)L"BerlinSansFBDemi", (FX_LPCWSTR)L"STIXNonUnicode,American Typewriter,Avenir Next Condensed Heavy", 0, 1252},
+ {0x480bf7a4, (FX_LPCWSTR)L"CourierStd", (FX_LPCWSTR)L"Courier New", 0, 1252},
+ {0x481ad6ed, (FX_LPCWSTR)L"VladimirScript", (FX_LPCWSTR)L"STIXNonUnicode,Avenir Next Condensed,Impact", 8, 1252},
+ {0x4911577a, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"STHeiti,Heiti TC", 1, 936},
+ {0x4a788d72, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"Kaiti SC,Songti SC", 0, 936},
+ {0x4bf88566, (FX_LPCWSTR)L"SegoeCondensed", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x4ccf51a4, (FX_LPCWSTR)L"BerlinSansFB-Reg", (FX_LPCWSTR)L"STIXNonUnicode,American Typewriter,Impact", 0, 1252},
+ {0x4ea967ce, (FX_LPCWSTR)L"GulimChe", (FX_LPCWSTR)L"Arial Unicode MS,Heiti TC,STFangsong", 1, 1252},
+ {0x4f68bd79, (FX_LPCWSTR)L"LetterGothicStd", (FX_LPCWSTR)L"Courier New,Andale Mono,Ayuthaya,PCMyungjo,Osaka", 0, 1252},
+ {0x51a0d0e6, (FX_LPCWSTR)L"KozukaGothicPr6NM", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x531b3dea, (FX_LPCWSTR)L"BasemicSymbol", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x5333fd39, (FX_LPCWSTR)L"CalifornianFB-Reg", (FX_LPCWSTR)L"American Typewriter,Avenir Next Condensed,Impact", 2, 1252},
+ {0x53561a54, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"STFangsong,Songti SC,STSong", 0, 936},
+ {0x55e0dde6, (FX_LPCWSTR)L"LucidaSansTypewriter", (FX_LPCWSTR)L"Menlo,Courier New,Andale Mono", 0, 1252},
+ {0x574d4d3d, (FX_LPCWSTR)L"AdobeArabic", (FX_LPCWSTR)L"Arial Narrow", 0, 1252},
+ {0x5792e759, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"Songti SC,Arial Unicode MS", 0, 936},
+ {0x5921978e, (FX_LPCWSTR)L"LucidaSansUnicode", (FX_LPCWSTR)L"Lucida Grande,Arial Unicode MS,Menlo", 0, 1252},
+ {0x594e2da4, (FX_LPCWSTR)L"Vrinda", (FX_LPCWSTR)L"Geeza Pro,Damascus,STIXGeneral,Gill Sans", 0, 1252},
+ {0x59baa9a2, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"Hiragino Sans GB,STHeiti", 0, 1252},
+ {0x5cfedf4f, (FX_LPCWSTR)L"BaskOldFace", (FX_LPCWSTR)L"Avenir Next Condensed Heavy,PT Sans,Avenir Next Condensed", 0, 1252},
+ {0x5e16ac91, (FX_LPCWSTR)L"TrajanPro", (FX_LPCWSTR)L"Arial Narrow,PT Sans Narrow,Damascus", 0, 1252},
+ {0x5f97921c, (FX_LPCWSTR)L"AdobeMyungjoStdM", (FX_LPCWSTR)L"AppleMyungjo,AppleGothic,Arial Unicode MS", 0, 936},
+ {0x5fefbfad, (FX_LPCWSTR)L"Batang", (FX_LPCWSTR)L"Arial Unicode MS,Songti SC", 2, 1252},
+ {0x605342b9, (FX_LPCWSTR)L"DotumChe", (FX_LPCWSTR)L"Arial Unicode MS,Heiti TC", 1, 1252},
+ {0x608c5f9a, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"Hiragino Sans GB,STHeiti,Heiti TC", 0, 936},
+ {0x61efd0d1, (FX_LPCWSTR)L"MaturaMTScriptCapitals", (FX_LPCWSTR)L"Kokonor,Damascus,STIXNonUnicode,STHeiti,Arial Black,Avenir Next Heavy", 0, 1252},
+ {0x626608a9, (FX_LPCWSTR)L"MVBoli", (FX_LPCWSTR)L"Apple Braille,Geeza Pro,Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x630501a3, (FX_LPCWSTR)L"SmallFonts", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x65d0e2a9, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"STFangsong,Songti SC,STSong", 0, 936},
+ {0x669f29e1, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"STHeiti,Heiti TC", 0, 936},
+ {0x673a9e5f, (FX_LPCWSTR)L"Tunga", (FX_LPCWSTR)L"Damascus,STIXNonUnicode,Avenir Next Condensed,Avenir Next Condensed Ultra Light,Futura", 0, 1252},
+ {0x691aa4ce, (FX_LPCWSTR)L"NiagaraSolid", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x696259b7, (FX_LPCWSTR)L"Corbel", (FX_LPCWSTR)L"Cochin,Baskerville,Marion", 0, 1252},
+ {0x696ee9be, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L"STHeiti,Heiti TC,Songti SC,Arial Unicode MS", 0, 936},
+ {0x6c59cf69, (FX_LPCWSTR)L"Dotum", (FX_LPCWSTR)L"Arial Unicode MS,Songti SC", 0, 1252},
+ {0x707fa561, (FX_LPCWSTR)L"Gungsuh", (FX_LPCWSTR)L"Arial Unicode MS,Heiti TC", 2, 1252},
+ {0x71416bb2, (FX_LPCWSTR)L"ZWAdobeF", (FX_LPCWSTR)L"STIXSizeFourSym,STIXSizeThreeSym,STIXSizeTwoSym,STIXSizeOneSym", 0, 1252},
+ {0x71b41801, (FX_LPCWSTR)L"Verdana", (FX_LPCWSTR)L"Tahoma,Marion,Apple Symbols,.Helvetica Neue Desk UI,Lucida Grande,Courier New", 0, 1252},
+ {0x73f25e4c, (FX_LPCWSTR)L"PalatinoLinotype", (FX_LPCWSTR)L"Palatino,Arial Unicode MS", 0, 1252},
+ {0x73f4d19f, (FX_LPCWSTR)L"NiagaraEngraved", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x74001694, (FX_LPCWSTR)L"MyriadProBlack", (FX_LPCWSTR)L"Palatino,Baskerville,Marion,Cochin", 0, 1252},
+ {0x74b14d8f, (FX_LPCWSTR)L"Haettenschweiler", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x74cb44ee, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 1, 936},
+ {0x76b4d7ff, (FX_LPCWSTR)L"Shruti", (FX_LPCWSTR)L"Damascus,STIXNonUnicode,Arial Unicode MS,American Typewriter", 0, 1252},
+ {0x788b3533, (FX_LPCWSTR)L"Webdings", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+ {0x797dde99, (FX_LPCWSTR)L"MSSerif", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x7a0f9e9e, (FX_LPCWSTR)L"MSMincho", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,Arial Unicode MS,Apple SD Gothic Neo", 1, 1252},
+ {0x7b439caf, (FX_LPCWSTR)L"OldEnglishTextMT", (FX_LPCWSTR)L"STIXNonUnicode,Arial Unicode MS,Baskerville,Avenir Next Medium", 0, 1252},
+ {0x8213a433, (FX_LPCWSTR)L"LucidaSans-Typewriter", (FX_LPCWSTR)L"Comic Sans MS,Avenir Next,Arial Rounded MT Bold", 0, 1252},
+ {0x82fec929, (FX_LPCWSTR)L"AdobeSongStdL", (FX_LPCWSTR)L"Heiti TC,STHeiti", 0, 936},
+ {0x83581825, (FX_LPCWSTR)L"Modern", (FX_LPCWSTR)L"Avenir Next Condensed,Impact", 0, 1252},
+ {0x835a2823, (FX_LPCWSTR)L"Algerian", (FX_LPCWSTR)L"STIXNonUnicode,Baskerville,Avenir Next Medium,American Typewriter", 0, 1252},
+ {0x83dab9f5, (FX_LPCWSTR)L"Script", (FX_LPCWSTR)L"Arial Narrow", 0, 1252},
+ {0x847b56da, (FX_LPCWSTR)L"Tahoma", (FX_LPCWSTR)L"Songti SC,Apple Symbols", 0, 1252},
+ {0x8a783cb2, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 0, 1252},
+ {0x8b5cac0e, (FX_LPCWSTR)L"Onyx", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x8c6a499e, (FX_LPCWSTR)L"Gulim", (FX_LPCWSTR)L"Arial Unicode MS,Songti SC", 0, 1252},
+ {0x8e0af790, (FX_LPCWSTR)L"JuiceITC", (FX_LPCWSTR)L"Nadeem,Al Bayan", 0, 1252},
+ {0x8e8d43b2, (FX_LPCWSTR)L"Centaur", (FX_LPCWSTR)L"Avenir Next Condensed,Noteworthy,Impact", 2, 1252},
+ {0x8ee4dcca, (FX_LPCWSTR)L"BookshelfSymbol7", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x90794800, (FX_LPCWSTR)L"BellGothicStdLight", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0x909b516a, (FX_LPCWSTR)L"Century", (FX_LPCWSTR)L"Damascus,Andale Mono,Songti SC,Arial Unicode MS", 2, 1252},
+ {0x92ae370d, (FX_LPCWSTR)L"MSOutlook", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 4, 42},
+ {0x93c9fbf1, (FX_LPCWSTR)L"LucidaFax", (FX_LPCWSTR)L"PT Sans Narrow,Papyrus,Kokonor,Geeza Pro,Arial Rounded MT Bold,Lucida Grande,Futura", 2, 1252},
+ {0x9565085e, (FX_LPCWSTR)L"BookAntiqua", (FX_LPCWSTR)L"Palatino,Microsoft Sans Serif,Apple Symbols", 2, 1252},
+ {0x9856d95d, (FX_LPCWSTR)L"AdobeMingStdL", (FX_LPCWSTR)L"AHiragino Sans GB,Heiti TC,STHeiti", 0, 949},
+ {0x9bbadd6b, (FX_LPCWSTR)L"ColonnaMT", (FX_LPCWSTR)L"Noteworthy,Avenir Next Condensed,Impact", 0, 1252},
+ {0x9cbd16a4, (FX_LPCWSTR)L"ShowcardGothic-Reg", (FX_LPCWSTR)L"Arial Unicode MS,Georgia,American Typewriter", 0, 1252},
+ {0x9d73008e, (FX_LPCWSTR)L"MSSansSerif", (FX_LPCWSTR)L"Songti SC,Apple Symbols", 0, 1252},
+ {0xa0607db1, (FX_LPCWSTR)L"GungsuhChe", (FX_LPCWSTR)L"WenQuanYi Zen Hei Mono,AR PL UMing CN,AR PL UMing HK,AR PL UMing TW,AR PL UMing TW MBE,Arial Unicode MS,Heiti TC,STFangsong", 1, 1252},
+ {0xa0bcf6a1, (FX_LPCWSTR)L"LatinWide", (FX_LPCWSTR)L"Zapfino,Arial Black,STHeiti", 2, 1252},
+ {0xa1429b36, (FX_LPCWSTR)L"Symbol", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+ {0xa1fa5abc, (FX_LPCWSTR)L"Wingdings2", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+ {0xa1fa5abd, (FX_LPCWSTR)L"Wingdings3", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+ {0xa427bad4, (FX_LPCWSTR)L"InformalRoman-Regular", (FX_LPCWSTR)L"STIXNonUnicode,Arial Narrow,Avenir Next Condensed Demi Bold", 8, 1252},
+ {0xa8b92ece, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 0, 936},
+ {0xa8d83ece, (FX_LPCWSTR)L"CalifornianFB", (FX_LPCWSTR)L"American Typewriter,Avenir Next Condensed,Impact", 2, 1252},
+ {0xaa3e082c, (FX_LPCWSTR)L"Kingsoft-Phonetic", (FX_LPCWSTR)L"STIXVariants,STIXSizeOneSym,Apple Braille", 0, 1252},
+ {0xaa6bcabe, (FX_LPCWSTR)L"HarlowSolidItalic", (FX_LPCWSTR)L"STIXNonUnicode,Avenir Medium,Avenir Next Medium,Arial Unicode MS", 0, 1252},
+ {0xade5337c, (FX_LPCWSTR)L"MSUIGothic", (FX_LPCWSTR)L"Arial Unicode MS,Apple SD Gothic Neo", 0, 1252},
+ {0xb08dd941, (FX_LPCWSTR)L"WideLatin", (FX_LPCWSTR)L"Marion,Papyrus,Nanum Pen Script,Zapf Dingbats,Damascus,Zapfino,Arial Black,STHeiti", 2, 1252},
+ {0xb12765e0, (FX_LPCWSTR)L"ITCLegacySansStdBook", (FX_LPCWSTR)L"LastResort,.Helvetica Neue Desk UI,Arial Unicode MS,Palatino", 0, 1252},
+ {0xb207f05d, (FX_LPCWSTR)L"PoorRichard", (FX_LPCWSTR)L"Noteworthy,Avenir Next Condensed,Impact", 2, 1252},
+ {0xb3bc492f, (FX_LPCWSTR)L"JuiceITC-Regular", (FX_LPCWSTR)L"Nadeem,Al Bayan,STIXNonUnicode", 0, 1252},
+ {0xb5545399, (FX_LPCWSTR)L"Marlett", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 4, 42},
+ {0xb5dd1ebb, (FX_LPCWSTR)L"BritannicBold", (FX_LPCWSTR)L"Damascus,STIXNonUnicode,Avenir Next Condensed Heavy,PT Sans", 0, 1252},
+ {0xb699c1c5, (FX_LPCWSTR)L"LucidaCalligraphy-Italic", (FX_LPCWSTR)L"STHeiti,Arial Black", 0, 1252},
+ {0xb725d629, (FX_LPCWSTR)L"TimesNewRoman", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 2, 1252},
+ {0xb7eaebeb, (FX_LPCWSTR)L"AdobeHeitiStdR", (FX_LPCWSTR)L"Heiti TC,STHeiti", 0, 936},
+ {0xbd29c486, (FX_LPCWSTR)L"BerlinSansFBDemi-Bold", (FX_LPCWSTR)L"American Typewriter,Avenir Next Condensed Heavy", 0, 1252},
+ {0xbe8a8db4, (FX_LPCWSTR)L"BookshelfSymbolSeven", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0xc16c0118, (FX_LPCWSTR)L"AdobeHebrew", (FX_LPCWSTR)L".Helvetica Neue Desk UI,Palatino,American Typewriter", 0, 1252},
+ {0xc318b0af, (FX_LPCWSTR)L"MyriadProLight", (FX_LPCWSTR)L"Palatino,Baskerville,Marion", 0, 1252},
+ {0xc65e5659, (FX_LPCWSTR)L"CambriaMath", (FX_LPCWSTR)L"Arial Unicode MS", 2, 1252},
+ {0xc75c8f05, (FX_LPCWSTR)L"LucidaConsole", (FX_LPCWSTR)L"Courier New,Menlo,Andale Mono", 1, 1252},
+ {0xca7c35d6, (FX_LPCWSTR)L"Calibri", (FX_LPCWSTR)L"Apple Symbols,HeadLineA", 0, 1252},
+ {0xcb053f53, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"Arial Unicode MS", 0, 936},
+ {0xcb7190f9, (FX_LPCWSTR)L"Magneto-Bold", (FX_LPCWSTR)L"Lucida Grande", 0, 1252},
+ {0xcca00cc5, (FX_LPCWSTR)L"System", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0xccad6f76, (FX_LPCWSTR)L"Jokerman-Regular", (FX_LPCWSTR)L"Lucida Grande", 0, 1252},
+ {0xccc5818c, (FX_LPCWSTR)L"EuroSign", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0xcf3d7234, (FX_LPCWSTR)L"LucidaHandwriting-Italic", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0xcf7b8fdb, (FX_LPCWSTR)L"MinionPro", (FX_LPCWSTR)L"Bell MT,Corbel,Times New Roman,Cambria,Berlin Sans FB", 0, 1252},
+ {0xcfe5755f, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 1, 936},
+ {0xd011f4ee, (FX_LPCWSTR)L"MSPGothic", (FX_LPCWSTR)L"Arial Unicode MS,Apple SD Gothic Neo", 0, 1252},
+ {0xd060e7ef, (FX_LPCWSTR)L"Vivaldi", (FX_LPCWSTR)L"STIXNonUnicode,Arial Unicode MS,Avenir Medium,Avenir Next Medium", 8, 1252},
+ {0xd07edec1, (FX_LPCWSTR)L"FranklinGothic-Medium", (FX_LPCWSTR)L"Impact,Arial Narrow", 0, 1252},
+ {0xd107243f, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 0, 936},
+ {0xd1881562, (FX_LPCWSTR)L"ArialNarrow", (FX_LPCWSTR)L"PT Sans Narrow,Apple Symbols", 0, 1252},
+ {0xd22b7dce, (FX_LPCWSTR)L"BodoniMTPosterCompressed", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0xd22bfa60, (FX_LPCWSTR)L"ComicSansMS", (FX_LPCWSTR)L"Damascus,Georgia,.Helvetica Neue Desk UI,Lucida Grande,Arial Unicode MS", 8, 1252},
+ {0xd3bd0e35, (FX_LPCWSTR)L"Bauhaus93", (FX_LPCWSTR)L"STIXNonUnicode,Arial Unicode MS,Avenir Next,Avenir", 0, 1252},
+ {0xd429ee7a, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"Songti SC,Arial Unicode MS", 0, 936},
+ {0xd6679c12, (FX_LPCWSTR)L"BernardMTCondensed", (FX_LPCWSTR)L"Impact,Avenir Next Condensed Demi Bold", 0, 1252},
+ {0xd8e8a027, (FX_LPCWSTR)L"LucidaSans", (FX_LPCWSTR)L"Arial Narrow,Khmer MN,Kokonor,Damascus,Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0xd9fe7761, (FX_LPCWSTR)L"HighTowerText-Reg", (FX_LPCWSTR)L"STIXGeneral,.Helvetica Neue Desk UI,Trebuchet MS", 2, 1252},
+ {0xda7e551e, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"Arial Unicode MS", 0, 936},
+ {0xdaa6842d, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"STFangsong,Songti SC,STSong", 0, 936},
+ {0xdaaab93f, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"Songti SC,Arial Unicode MS", 0, 936},
+ {0xdaeb0713, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"Songti SC,Arial Unicode MS", 0, 936},
+ {0xdafedbef, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+ {0xdb00a3d9, (FX_LPCWSTR)L"Broadway", (FX_LPCWSTR)L"Papyrus,STIXNonUnicode,Arial Black,Avenir Next Heavy,Heiti TC", 0, 1252},
+ {0xdb1f5ad4, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+ {0xdb326e7f, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"Songti SC,Arial Unicode MS", 0, 936},
+ {0xdb69595a, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"Kaiti SC,Songti SC,STHeiti", 0, 936},
+ {0xdba0082c, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L"Songti SC,Arial Unicode MS", 0, 936},
+ {0xdbd0ab18, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"Kaiti SC,Songti SC", 0, 936},
+ {0xdc1a7db1, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"Kaiti SC,Songti SC", 0, 936},
+ {0xdc33075f, (FX_LPCWSTR)L"KristenITC-Regular", (FX_LPCWSTR)L"STIXNonUnicode,Damascus,Songti SC,STSong", 8, 1252},
+ {0xdcc7009c, (FX_LPCWSTR)L"Harrington", (FX_LPCWSTR)L"STIXNonUnicode,Avenir Next Condensed Heavy,Noteworthy", 0, 1252},
+ {0xdd712466, (FX_LPCWSTR)L"ArialBlack", (FX_LPCWSTR)L"Geeza Pro,Damascus,Songti SC,STSong", 0, 1252},
+ {0xdde87b3e, (FX_LPCWSTR)L"Impact", (FX_LPCWSTR)L"Arial Narrow,Marion", 0, 1252},
+ {0xdf69fb32, (FX_LPCWSTR)L"SnapITC", (FX_LPCWSTR)L"Arial Narrow,PT Sans Narrow,Marion,STHeiti,Arial Black", 0, 1252},
+ {0xdf8b25e8, (FX_LPCWSTR)L"CenturyGothic", (FX_LPCWSTR)L"Damascus,Andale Mono,Songti SC,Arial Unicode MS", 0, 1252},
+ {0xe0f705c0, (FX_LPCWSTR)L"KristenITC", (FX_LPCWSTR)L"Songti SC,STSong", 8, 1252},
+ {0xe1427573, (FX_LPCWSTR)L"Raavi", (FX_LPCWSTR)L"Damascus,STIXNonUnicode,Marion,Papyrus,Avenir Next Condensed Heavy,American Typewriter", 0, 1252},
+ {0xe2cea0cb, (FX_LPCWSTR)L"Magneto", (FX_LPCWSTR)L"STIXNonUnicode,Damascus,Geeza Pro,Lucida Grande,Georgia,Heiti TC", 0, 1252},
+ {0xe36a9e17, (FX_LPCWSTR)L"Ravie", (FX_LPCWSTR)L"STHeiti,Arial Black", 0, 1252},
+ {0xe433f8e2, (FX_LPCWSTR)L"Parchment", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 8, 1252},
+ {0xe43dff4a, (FX_LPCWSTR)L"Wingdings", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 4, 42},
+ {0xe4e2c405, (FX_LPCWSTR)L"MTExtra", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 6, 42},
+ {0xe618cc35, (FX_LPCWSTR)L"InformalRoman", (FX_LPCWSTR)L"Arial Narrow", 8, 1252},
+ {0xe6c27ffc, (FX_LPCWSTR)L"Mistral", (FX_LPCWSTR)L"Apple Symbols", 8, 1252},
+ {0xe7ebf4b9, (FX_LPCWSTR)L"Courier", (FX_LPCWSTR)L"Courier New", 0, 1252},
+ {0xe8bc4a9d, (FX_LPCWSTR)L"MSReferenceSpecialty", (FX_LPCWSTR)L"Microsoft Sans Serif,Apple Symbols", 0, 1252},
+ {0xe90fb013, (FX_LPCWSTR)L"TempusSansITC", (FX_LPCWSTR)L"STIXNonUnicode,Microsoft Sans Serif,Avenir Light", 0, 1252},
+ {0xec637b42, (FX_LPCWSTR)L"Consolas", (FX_LPCWSTR)L"AR PL UKai CN,AR PL UKai HK,AR PL UKai TW,AR PL UKai TW MBE,AR PL UMing CN,AR PL UMing HK,Microsoft Sans Serif,Tahoma", 1, 1252},
+ {0xed3a683b, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"Kaiti SC,Songti SC,", 0, 936},
+ {0xef264cd1, (FX_LPCWSTR)L"LucidaHandwriting", (FX_LPCWSTR)L"Arial Narrow,Avenir Next Condensed Demi Bold,Avenir Next Condensed,Avenir Next Condensed Medium,STHeiti,Arial Black", 0, 1252},
+ {0xf086bca2, (FX_LPCWSTR)L"BaskervilleOldFace", (FX_LPCWSTR)L"STIXNonUnicode,Avenir Next Condensed Heavy,PT Sans", 0, 1252},
+ {0xf1028030, (FX_LPCWSTR)L"Mangal", (FX_LPCWSTR)L"Arial Unicode MS,Microsoft Sans Serif,Arial Narrow,Tahoma", 2, 1252},
+ {0xf1da7eb9, (FX_LPCWSTR)L"ShowcardGothic", (FX_LPCWSTR)L"Papyrus,Arial Unicode MS,Georgia,American Typewriter", 0, 1252},
+ {0xf210f06a, (FX_LPCWSTR)L"ArialMT", (FX_LPCWSTR)L"Arial Unicode MS,Arial Narrow,STIXNonUnicode,Damascus,Avenir Next Condensed Demi Bold,Avenir Next Condensed Medium,Avenir Next Condensed", 0, 1252},
+ {0xf477f16a, (FX_LPCWSTR)L"Latha", (FX_LPCWSTR)L"Arial Narrow,Damascus,STIXNonUnicode,American Typewriter", 0, 1252},
+ {0xf616f3dd, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"STHeiti,Heiti TC,STFangsong", 1, 936},
+ {0xfa479aa6, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"Arial Unicode MS", 0, 936},
+ {0xfcd19697, (FX_LPCWSTR)L"BookmanOldStyle", (FX_LPCWSTR)L"Geeza Pro,Damascus,Andale Mono,Songti SC,Arial Unicode MS", 0, 1252},
+ {0xfe209a82, (FX_LPCWSTR)L"LucidaCalligraphy", (FX_LPCWSTR)L"Kokonor,Damascus,STIXNonUnicode,STHeiti,Arial Black", 0, 1252},
+ {0xfef135f8, (FX_LPCWSTR)L"AdobeHeitiStd-Regular", (FX_LPCWSTR)L"Heiti TC,STHeiti", 0, 936},
+};
+#elif _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+static const XFA_FONTINFO g_XFAFontsMap[] = {
+ {0x01d5d33e, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x01e4f102, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0x030549dc, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0x032edd44, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0x03eac6fc, (FX_LPCWSTR)L"PoorRichard-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback,Droid Arabic Naskh,Droid Sans Ethiopic", 2, 1252},
+ {0x03ed90e6, (FX_LPCWSTR)L"Nina", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x077b56b3, (FX_LPCWSTR)L"KingsoftPhoneticPlain", (FX_LPCWSTR)L"Droid Sans Thai,Droid Sans Armenian,Droid Arabic Naskh,Droid Sans Ethiopic,Droid Sans Fallback", 0, 1252},
+ {0x078ed524, (FX_LPCWSTR)L"MicrosoftSansSerif", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x089b18a9, (FX_LPCWSTR)L"Arial", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x0b2cad72, (FX_LPCWSTR)L"MonotypeCorsiva", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0x0bb003e7, (FX_LPCWSTR)L"Kartika", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono", 2, 1252},
+ {0x0bb469df, (FX_LPCWSTR)L"VinerHandITC", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0x0bc1a851, (FX_LPCWSTR)L"SegoeUI", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x0c112ebd, (FX_LPCWSTR)L"KozukaGothicPro-VIM", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x0cfcb9c1, (FX_LPCWSTR)L"AdobeThai", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 847},
+ {0x0e7de0f9, (FX_LPCWSTR)L"Playbill", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+ {0x0eff47c3, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x107ad374, (FX_LPCWSTR)L"Constantia", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x12194c2d, (FX_LPCWSTR)L"KunstlerScript", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0x135ef6a1, (FX_LPCWSTR)L"MinionProSmBd", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x158c4049, (FX_LPCWSTR)L"Garamond", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x160ecb24, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x161ed07e, (FX_LPCWSTR)L"MSGothic", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0x171d1ed1, (FX_LPCWSTR)L"SnapITC-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x18d1188f, (FX_LPCWSTR)L"Cambria", (FX_LPCWSTR)L"Droid Sans Fallback", 2, 1252},
+ {0x18eaf350, (FX_LPCWSTR)L"ArialUnicodeMS", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x1a92d115, (FX_LPCWSTR)L"MingLiU", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0x1cc217c6, (FX_LPCWSTR)L"TrebuchetMS", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x1d649596, (FX_LPCWSTR)L"BasemicTimes", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x1e34ee60, (FX_LPCWSTR)L"BellMT", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x1eb36945, (FX_LPCWSTR)L"CooperBlack", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x1ef7787d, (FX_LPCWSTR)L"BatangChe", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0x20b3bd3a, (FX_LPCWSTR)L"BrushScriptMT", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic", 8, 1252},
+ {0x220877aa, (FX_LPCWSTR)L"Candara", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x22135007, (FX_LPCWSTR)L"FreestyleScript-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0x251059c3, (FX_LPCWSTR)L"Chiller", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif", 0, 1252},
+ {0x25bed6dd, (FX_LPCWSTR)L"MSReferenceSansSerif", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x28154c81, (FX_LPCWSTR)L"Parchment-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0x29711eb9, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x2b1993b4, (FX_LPCWSTR)L"Basemic", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x2b316339, (FX_LPCWSTR)L"NiagaraSolid-Reg", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x2c147529, (FX_LPCWSTR)L"FootlightMTLight", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x2c198928, (FX_LPCWSTR)L"HarlowSolid", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x2c6ac6b2, (FX_LPCWSTR)L"LucidaBright", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 2, 1252},
+ {0x2c9f38e2, (FX_LPCWSTR)L"KozukaMinchoPro-VIR", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x2d5a47b0, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x2def26bf, (FX_LPCWSTR)L"BernardMT-Condensed", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x2fd8930b, (FX_LPCWSTR)L"KozukaMinchoPr6NR", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x3115525a, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x31327817, (FX_LPCWSTR)L"MyriadPro", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x32244975, (FX_LPCWSTR)L"Helvetica", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 0, 1252},
+ {0x32ac995c, (FX_LPCWSTR)L"Terminal", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x338d648a, (FX_LPCWSTR)L"NiagaraEngraved-Reg", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x33bb65f2, (FX_LPCWSTR)L"Sylfaen", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x3402c30e, (FX_LPCWSTR)L"MSPMincho", (FX_LPCWSTR)L"Droid Sans Fallback", 2, 1252},
+ {0x3412bf31, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x36eb39b9, (FX_LPCWSTR)L"BerlinSansFB", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x36f42055, (FX_LPCWSTR)L"UniversATT", (FX_LPCWSTR)L"Microsoft Sans Serif", 0, 1252},
+ {0x3864c4f6, (FX_LPCWSTR)L"HighTowerText", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x3a257d03, (FX_LPCWSTR)L"FangSong_GB2312", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x3cdae668, (FX_LPCWSTR)L"FreestyleScript", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0x3d55aed7, (FX_LPCWSTR)L"Jokerman", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x3d5b4385, (FX_LPCWSTR)L"PMingLiU", (FX_LPCWSTR)L"Droid Sans Fallback", 2, 1252},
+ {0x3d9b7669, (FX_LPCWSTR)L"EstrangeloEdessa", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x3e532d74, (FX_LPCWSTR)L"FranklinGothicMedium", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x3e6aa32d, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0x3f6c36a8, (FX_LPCWSTR)L"Gautami", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x3ff32662, (FX_LPCWSTR)L"Chiller-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x409de312, (FX_LPCWSTR)L"ModernNo.20", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x41443c5e, (FX_LPCWSTR)L"Georgia", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x4160ade5, (FX_LPCWSTR)L"BellGothicStdBlack", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x421976c4, (FX_LPCWSTR)L"Modern-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x422a7252, (FX_LPCWSTR)L"Stencil", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x42c8554f, (FX_LPCWSTR)L"Fixedsys", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x435cb41d, (FX_LPCWSTR)L"Roman", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x47882383, (FX_LPCWSTR)L"CourierNew", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0x480a2338, (FX_LPCWSTR)L"BerlinSansFBDemi", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x480bf7a4, (FX_LPCWSTR)L"CourierStd", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x481ad6ed, (FX_LPCWSTR)L"VladimirScript", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0x4911577a, (FX_LPCWSTR)L"YouYuan", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0x4a788d72, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x4bf88566, (FX_LPCWSTR)L"SegoeCondensed", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x4ccf51a4, (FX_LPCWSTR)L"BerlinSansFB-Reg", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x4ea967ce, (FX_LPCWSTR)L"GulimChe", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0x4f68bd79, (FX_LPCWSTR)L"LetterGothicStd", (FX_LPCWSTR)L"Droid Sans Mono,Droid Arabic Naskh,Droid Sans Ethiopic,Droid Sans Mono,Droid Serif,Droid Sans Fallback", 0, 1252},
+ {0x51a0d0e6, (FX_LPCWSTR)L"KozukaGothicPr6NM", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x531b3dea, (FX_LPCWSTR)L"BasemicSymbol", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x5333fd39, (FX_LPCWSTR)L"CalifornianFB-Reg", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x53561a54, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x55e0dde6, (FX_LPCWSTR)L"LucidaSansTypewriter", (FX_LPCWSTR)L"Droid Sans Mono,Droid Arabic Naskh,Droid Sans Ethiopic", 0, 1252},
+ {0x574d4d3d, (FX_LPCWSTR)L"AdobeArabic", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x5792e759, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x5921978e, (FX_LPCWSTR)L"LucidaSansUnicode", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x594e2da4, (FX_LPCWSTR)L"Vrinda", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+ {0x59baa9a2, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x5cfedf4f, (FX_LPCWSTR)L"BaskOldFace", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x5f97921c, (FX_LPCWSTR)L"AdobeMyungjoStdM", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x5fefbfad, (FX_LPCWSTR)L"Batang", (FX_LPCWSTR)L"Droid Sans Fallback", 2, 1252},
+ {0x605342b9, (FX_LPCWSTR)L"DotumChe", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0x608c5f9a, (FX_LPCWSTR)L"KaiTi_GB2312", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x61efd0d1, (FX_LPCWSTR)L"MaturaMTScriptCapitals", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 0, 1252},
+ {0x626608a9, (FX_LPCWSTR)L"MVBoli", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 0, 1252},
+ {0x630501a3, (FX_LPCWSTR)L"SmallFonts", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x65d0e2a9, (FX_LPCWSTR)L"FZYTK--GBK1-0", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x669f29e1, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x673a9e5f, (FX_LPCWSTR)L"Tunga", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x691aa4ce, (FX_LPCWSTR)L"NiagaraSolid", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x696259b7, (FX_LPCWSTR)L"Corbel", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x696ee9be, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x6c59cf69, (FX_LPCWSTR)L"Dotum", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x707fa561, (FX_LPCWSTR)L"Gungsuh", (FX_LPCWSTR)L"Droid Sans Fallback", 2, 1252},
+ {0x71416bb2, (FX_LPCWSTR)L"ZWAdobeF", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Armenian,Droid Sans Ethiopic,Droid Sans Georgian,Droid Sans Hebrew,Droid Sans Thai", 0, 1252},
+ {0x71b41801, (FX_LPCWSTR)L"Verdana", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x73f25e4c, (FX_LPCWSTR)L"PalatinoLinotype", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x73f4d19f, (FX_LPCWSTR)L"NiagaraEngraved", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x74001694, (FX_LPCWSTR)L"MyriadProBlack", (FX_LPCWSTR)L"Book Antiqua,Constantia,Dotum,Georgia", 0, 1252},
+ {0x74b14d8f, (FX_LPCWSTR)L"Haettenschweiler", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x74cb44ee, (FX_LPCWSTR)L"NSimSun", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0x76b4d7ff, (FX_LPCWSTR)L"Shruti", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+ {0x788b3533, (FX_LPCWSTR)L"Webdings", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+ {0x797dde99, (FX_LPCWSTR)L"MSSerif", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x7a0f9e9e, (FX_LPCWSTR)L"MSMincho", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0x7b439caf, (FX_LPCWSTR)L"OldEnglishTextMT", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x8213a433, (FX_LPCWSTR)L"LucidaSans-Typewriter", (FX_LPCWSTR)L"Droid Sans Mono,Droid Serif,Roboto,Droid Sans Fallback", 0, 1252},
+ {0x82fec929, (FX_LPCWSTR)L"AdobeSongStdL", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0x83581825, (FX_LPCWSTR)L"Modern", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x835a2823, (FX_LPCWSTR)L"Algerian", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x83dab9f5, (FX_LPCWSTR)L"Script", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x847b56da, (FX_LPCWSTR)L"Tahoma", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x8a783cb2, (FX_LPCWSTR)L"SimSun-PUA", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x8b5cac0e, (FX_LPCWSTR)L"Onyx", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x8c6a499e, (FX_LPCWSTR)L"Gulim", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0x8e0af790, (FX_LPCWSTR)L"JuiceITC", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x8e8d43b2, (FX_LPCWSTR)L"Centaur", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x8ee4dcca, (FX_LPCWSTR)L"BookshelfSymbol7", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x90794800, (FX_LPCWSTR)L"BellGothicStdLight", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x909b516a, (FX_LPCWSTR)L"Century", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x92ae370d, (FX_LPCWSTR)L"MSOutlook", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 4, 42},
+ {0x93c9fbf1, (FX_LPCWSTR)L"LucidaFax", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 2, 1252},
+ {0x9565085e, (FX_LPCWSTR)L"BookAntiqua", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0x9856d95d, (FX_LPCWSTR)L"AdobeMingStdL", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 949},
+ {0x9bbadd6b, (FX_LPCWSTR)L"ColonnaMT", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0x9cbd16a4, (FX_LPCWSTR)L"ShowcardGothic-Reg", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallbac", 0, 1252},
+ {0x9d73008e, (FX_LPCWSTR)L"MSSansSerif", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xa0607db1, (FX_LPCWSTR)L"GungsuhChe", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0xa0bcf6a1, (FX_LPCWSTR)L"LatinWide", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0xa1429b36, (FX_LPCWSTR)L"Symbol", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+ {0xa1fa5abc, (FX_LPCWSTR)L"Wingdings2", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+ {0xa1fa5abd, (FX_LPCWSTR)L"Wingdings3", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+ {0xa427bad4, (FX_LPCWSTR)L"InformalRoman-Regular", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic", 8, 1252},
+ {0xa8b92ece, (FX_LPCWSTR)L"FZSTK--GBK1-0", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xa8d83ece, (FX_LPCWSTR)L"CalifornianFB", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0xaa3e082c, (FX_LPCWSTR)L"Kingsoft-Phonetic", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xaa6bcabe, (FX_LPCWSTR)L"HarlowSolidItalic", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xade5337c, (FX_LPCWSTR)L"MSUIGothic", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xb08dd941, (FX_LPCWSTR)L"WideLatin", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 2, 1252},
+ {0xb207f05d, (FX_LPCWSTR)L"PoorRichard", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0xb3bc492f, (FX_LPCWSTR)L"JuiceITC-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xb5545399, (FX_LPCWSTR)L"Marlett", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 4, 42},
+ {0xb5dd1ebb, (FX_LPCWSTR)L"BritannicBold", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic", 0, 1252},
+ {0xb699c1c5, (FX_LPCWSTR)L"LucidaCalligraphy-Italic", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xb725d629, (FX_LPCWSTR)L"TimesNewRoman", (FX_LPCWSTR)L"Droid Sans Fallback", 2, 1252},
+ {0xb7eaebeb, (FX_LPCWSTR)L"AdobeHeitiStdR", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xbd29c486, (FX_LPCWSTR)L"BerlinSansFBDemi-Bold", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xbe8a8db4, (FX_LPCWSTR)L"BookshelfSymbolSeven", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xc16c0118, (FX_LPCWSTR)L"AdobeHebrew", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback,Droid Arabic Naskh,Droid Sans Ethiopic", 0, 1252},
+ {0xc318b0af, (FX_LPCWSTR)L"MyriadProLight", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xc65e5659, (FX_LPCWSTR)L"CambriaMath", (FX_LPCWSTR)L"Droid Sans Fallback", 2, 1252},
+ {0xc75c8f05, (FX_LPCWSTR)L"LucidaConsole", (FX_LPCWSTR)L"Droid Sans Mono,Droid Serif,Roboto,Droid Sans Fallback", 1, 1252},
+ {0xca7c35d6, (FX_LPCWSTR)L"Calibri", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0xcb053f53, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xcb7190f9, (FX_LPCWSTR)L"Magneto-Bold", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xcca00cc5, (FX_LPCWSTR)L"System", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xccad6f76, (FX_LPCWSTR)L"Jokerman-Regular", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xccc5818c, (FX_LPCWSTR)L"EuroSign", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xcf3d7234, (FX_LPCWSTR)L"LucidaHandwriting-Italic", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xcf7b8fdb, (FX_LPCWSTR)L"MinionPro", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xcfe5755f, (FX_LPCWSTR)L"Simhei", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0xd011f4ee, (FX_LPCWSTR)L"MSPGothic", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0xd060e7ef, (FX_LPCWSTR)L"Vivaldi", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0xd07edec1, (FX_LPCWSTR)L"FranklinGothic-Medium", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xd107243f, (FX_LPCWSTR)L"SimSun", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xd1881562, (FX_LPCWSTR)L"ArialNarrow", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xd22b7dce, (FX_LPCWSTR)L"BodoniMTPosterCompressed", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xd22bfa60, (FX_LPCWSTR)L"ComicSansMS", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Fallback", 8, 1252},
+ {0xd3bd0e35, (FX_LPCWSTR)L"Bauhaus93", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xd429ee7a, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xd6679c12, (FX_LPCWSTR)L"BernardMTCondensed", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xd8e8a027, (FX_LPCWSTR)L"LucidaSans", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 0, 1252},
+ {0xd9fe7761, (FX_LPCWSTR)L"HighTowerText-Reg", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 2, 1252},
+ {0xda7e551e, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdaa6842d, (FX_LPCWSTR)L"STZhongsong", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdaaab93f, (FX_LPCWSTR)L"STFangsong", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdaeb0713, (FX_LPCWSTR)L"STSong", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 936},
+ {0xdafedbef, (FX_LPCWSTR)L"STCaiyun", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdb00a3d9, (FX_LPCWSTR)L"Broadway", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xdb1f5ad4, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdb326e7f, (FX_LPCWSTR)L"STKaiti", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdb69595a, (FX_LPCWSTR)L"STHupo", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdba0082c, (FX_LPCWSTR)L"STXihei", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdbd0ab18, (FX_LPCWSTR)L"STXingkai", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdc1a7db1, (FX_LPCWSTR)L"STLiti", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xdc33075f, (FX_LPCWSTR)L"KristenITC-Regular", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 8, 1252},
+ {0xdcc7009c, (FX_LPCWSTR)L"Harrington", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xdd712466, (FX_LPCWSTR)L"ArialBlack", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xdde87b3e, (FX_LPCWSTR)L"Impact", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xdf69fb32, (FX_LPCWSTR)L"SnapITC", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 0, 1252},
+ {0xdf8b25e8, (FX_LPCWSTR)L"CenturyGothic", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+ {0xe0f705c0, (FX_LPCWSTR)L"KristenITC", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto", 8, 1252},
+ {0xe1427573, (FX_LPCWSTR)L"Raavi", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+ {0xe2cea0cb, (FX_LPCWSTR)L"Magneto", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 0, 1252},
+ {0xe36a9e17, (FX_LPCWSTR)L"Ravie", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+ {0xe433f8e2, (FX_LPCWSTR)L"Parchment", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0xe43dff4a, (FX_LPCWSTR)L"Wingdings", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 4, 42},
+ {0xe4e2c405, (FX_LPCWSTR)L"MTExtra", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 6, 42},
+ {0xe618cc35, (FX_LPCWSTR)L"InformalRoman", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif", 8, 1252},
+ {0xe6c27ffc, (FX_LPCWSTR)L"Mistral", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 8, 1252},
+ {0xe7ebf4b9, (FX_LPCWSTR)L"Courier", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 1252},
+ {0xe8bc4a9d, (FX_LPCWSTR)L"MSReferenceSpecialty", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xe90fb013, (FX_LPCWSTR)L"TempusSansITC", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xec637b42, (FX_LPCWSTR)L"Consolas", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 1252},
+ {0xed3a683b, (FX_LPCWSTR)L"STXinwei", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xef264cd1, (FX_LPCWSTR)L"LucidaHandwriting", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 0, 1252},
+ {0xf086bca2, (FX_LPCWSTR)L"BaskervilleOldFace", (FX_LPCWSTR)L"Roboto,Droid Serif,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xf1028030, (FX_LPCWSTR)L"Mangal", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 2, 1252},
+ {0xf1da7eb9, (FX_LPCWSTR)L"ShowcardGothic", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallbac", 0, 1252},
+ {0xf210f06a, (FX_LPCWSTR)L"ArialMT", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif", 0, 1252},
+ {0xf477f16a, (FX_LPCWSTR)L"Latha", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Roboto,Droid Serif,Droid Sans Mono", 0, 1252},
+ {0xf616f3dd, (FX_LPCWSTR)L"LiSu", (FX_LPCWSTR)L"Droid Sans Fallback", 1, 936},
+ {0xfa479aa6, (FX_LPCWSTR)L"MicrosoftYaHei", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+ {0xfcd19697, (FX_LPCWSTR)L"BookmanOldStyle", (FX_LPCWSTR)L"Droid Serif,Roboto,Droid Sans Mono,Droid Sans Fallback", 0, 1252},
+ {0xfe209a82, (FX_LPCWSTR)L"LucidaCalligraphy", (FX_LPCWSTR)L"Droid Arabic Naskh,Droid Sans Ethiopic,Droid Serif,Roboto,Droid Sans Mono", 0, 1252},
+ {0xfef135f8, (FX_LPCWSTR)L"AdobeHeitiStd-Regular", (FX_LPCWSTR)L"Droid Sans Fallback", 0, 936},
+};
+#endif
+void XFA_LocalFontNameToEnglishName(FX_WSTR wsLocalName, CFX_WideString &wsEnglishName)
+{
+ wsEnglishName = wsLocalName;
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+ FX_DWORD dwLocalNameHash = FX_HashCode_String_GetW(wsLocalName.GetPtr(), wsLocalName.GetLength(), TRUE);
+ FX_INT32 iStart = 0;
+ FX_INT32 iEnd = sizeof(g_XFAFontsMap) / sizeof(XFA_FONTINFO) - 1;
+ FX_INT32 iMid = 0;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ FX_DWORD dwFontNameHash = g_XFAFontsMap[iMid].dwFontNameHash;
+ if (dwFontNameHash == dwLocalNameHash) {
+ wsEnglishName = g_XFAFontsMap[iMid].pPsName;
+ break;
+ } else if (dwFontNameHash < dwLocalNameHash) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iEnd >= iStart);
+#endif
+}
+const XFA_FONTINFO* XFA_GetFontINFOByFontName(FX_WSTR wsFontName)
+{
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ || _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_ || _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+ CFX_WideString wsFontNameTemp = wsFontName;
+ wsFontNameTemp.Remove(L' ');
+ FX_DWORD dwCurFontNameHash = FX_HashCode_String_GetW(wsFontNameTemp, wsFontNameTemp.GetLength(), TRUE);
+ FX_INT32 iStart = 0;
+ FX_INT32 iEnd = sizeof(g_XFAFontsMap) / sizeof(XFA_FONTINFO) - 1;
+ FX_INT32 iMid = 0;
+ const XFA_FONTINFO *pFontInfo = NULL;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ FX_DWORD dwFontNameHash = g_XFAFontsMap[iMid].dwFontNameHash;
+ if (dwFontNameHash == dwCurFontNameHash) {
+ pFontInfo = &g_XFAFontsMap[iMid];
+ break;
+ } else if (dwFontNameHash < dwCurFontNameHash) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iEnd >= iStart);
+ return pFontInfo;
+#else
+ return NULL;
+#endif
+}
+IXFA_FontMgr* XFA_GetDefaultFontMgr()
+{
+ return FX_NEW CXFA_DefFontMgr;
+}
+CXFA_DefFontMgr::~CXFA_DefFontMgr()
+{
+ FX_INT32 iCounts = m_CacheFonts.GetSize();
+ for (FX_INT32 i = 0; i < iCounts; i++) {
+ ((IFX_Font*)m_CacheFonts[i])->Release();
+ }
+ m_CacheFonts.RemoveAll();
+}
+#define _FXFA_USEGASFONTMGR_
+IFX_Font* CXFA_DefFontMgr::GetFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage )
+{
+ CFX_WideString wsFontName = wsFontFamily;
+ IFX_FontMgr* pFDEFontMgr = ((CXFA_FFDoc*)hDoc)->GetApp()->GetFDEFontMgr();
+#ifdef _FXFA_USEGASFONTMGR_
+ const XFA_FONTINFO *pCurFont = NULL;
+ FX_BOOL bGetFontInfo = TRUE;
+ IFX_Font* pFont = pFDEFontMgr->LoadFont((FX_LPCWSTR)wsFontName, dwFontStyles, wCodePage);
+#else
+ const XFA_FONTINFO *pCurFont = XFA_GetFontINFOByFontName(wsFontName);
+ FX_BOOL bGetFontInfo = FALSE;
+ IFX_Font* pFont = IFX_Font::LoadFont((FX_LPCWSTR)wsFontName, dwFontStyles | FX_FONTSTYLE_ExactMatch, pCurFont ? pCurFont->wCodePage : wCodePage, pFDEFontMgr);
+#endif
+ if (!pFont && hDoc) {
+ if (bGetFontInfo) {
+ pCurFont = XFA_GetFontINFOByFontName(wsFontName);
+ }
+ if (pCurFont != NULL && pCurFont->pReplaceFont != NULL) {
+ FX_DWORD dwStyle = 0;
+ if (dwFontStyles & FX_FONTSTYLE_Bold) {
+ dwStyle |= FX_FONTSTYLE_Bold;
+ }
+ if (dwFontStyles & FX_FONTSTYLE_Italic) {
+ dwStyle |= FX_FONTSTYLE_Italic;
+ }
+ FX_LPCWSTR pReplace = pCurFont->pReplaceFont;
+ FX_INT32 iLength = FXSYS_wcslen(pReplace);
+ while (iLength > 0) {
+ FX_LPCWSTR pNameText = pReplace;
+ while (*pNameText != L',' && iLength > 0) {
+ pNameText++;
+ iLength--;
+ }
+ CFX_WideString wsReplace = CFX_WideString(pReplace, pNameText - pReplace);
+#ifdef _FXFA_USEGASFONTMGR_
+ pFont = pFDEFontMgr->LoadFont(wsReplace, dwStyle, wCodePage);
+#else
+ pFont = IFX_Font::LoadFont((FX_LPCWSTR)wsReplace, dwStyle | FX_FONTSTYLE_ExactMatch, pCurFont->wCodePage, pFDEFontMgr);
+#endif
+ if (pFont != NULL) {
+ break;
+ }
+ iLength--;
+ pNameText++;
+ pReplace = pNameText;
+ }
+ }
+ }
+ if (pFont) {
+ m_CacheFonts.Add(pFont);
+ }
+ return pFont;
+}
+IFX_Font* CXFA_DefFontMgr::GetDefaultFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage)
+{
+ IFX_FontMgr* pFDEFontMgr = ((CXFA_FFDoc*)hDoc)->GetApp()->GetFDEFontMgr();
+#ifdef _FXFA_USEGASFONTMGR_
+ IFX_Font* pFont = pFDEFontMgr->LoadFont((FX_LPCWSTR)L"Arial Narrow", dwFontStyles, wCodePage);
+#else
+ const XFA_FONTINFO *pCurFont = XFA_GetFontINFOByFontName(wsFontFamily);
+ IFX_Font* pFont = IFX_Font::LoadFont((FX_LPCWSTR)L"Arial Narrow", dwFontStyles, pCurFont ? pCurFont->wCodePage : 1252, pFDEFontMgr);
+#endif
+ if (!pFont)
+#ifdef _FXFA_USEGASFONTMGR_
+ pFont = pFDEFontMgr->LoadFont((FX_LPCWSTR)NULL, dwFontStyles, wCodePage);
+#else
+ pFont = IFX_Font::LoadFont((FX_LPCWSTR)NULL, dwFontStyles, pCurFont ? pCurFont->wCodePage : 1252, pFDEFontMgr);
+#endif
+ FXSYS_assert(pFont != NULL);
+ if (pFont) {
+ m_CacheFonts.Add(pFont);
+ }
+ return pFont;
+}
+struct XFA_PDFFONTNAME {
+ FX_LPCSTR lpPsName;
+ FX_LPCSTR lpNormal;
+ FX_LPCSTR lpBold;
+ FX_LPCSTR lpItalic;
+ FX_LPCSTR lpBoldItalic;
+};
+const XFA_PDFFONTNAME g_XFAPDFFontName[] = {
+ {"Adobe PI Std", "AdobePIStd", "AdobePIStd", "AdobePIStd", "AdobePIStd"},
+ {"Myriad Pro Light", "MyriadPro-Light", "MyriadPro-Semibold", "MyriadPro-LightIt", "MyriadPro-SemiboldIt"},
+};
+CXFA_PDFFontMgr::CXFA_PDFFontMgr(CXFA_FFDoc* pDoc)
+{
+ m_pDoc = pDoc;
+}
+CXFA_PDFFontMgr::~CXFA_PDFFontMgr()
+{
+ FX_POSITION ps = m_FDE2PDFFont.GetStartPosition();
+ while (ps) {
+ IFX_Font* pFDEFont;
+ void* pPDFFont;
+ m_FDE2PDFFont.GetNextAssoc(ps, (void*&)pFDEFont, pPDFFont);
+ pFDEFont->SetFontProvider(NULL);
+ }
+ m_FDE2PDFFont.RemoveAll();
+ ps = m_FontArray.GetStartPosition();
+ while (ps) {
+ CFX_ByteString strKey;
+ IFX_Font* pFont = NULL;
+ m_FontArray.GetNextAssoc(ps, strKey, (void*&)pFont);
+ if (pFont != NULL) {
+ pFont->Release();
+ }
+ }
+ m_FontArray.RemoveAll();
+}
+IFX_Font* CXFA_PDFFontMgr::FindFont(CFX_ByteString strPsName, FX_BOOL bBold, FX_BOOL bItalic, CPDF_Font** pDstPDFFont, FX_BOOL bStrictMatch)
+{
+ CPDF_Document* pDoc = m_pDoc->GetPDFDoc();
+ if (pDoc == NULL) {
+ return NULL;
+ }
+ CPDF_Dictionary* pFontSetDict = pDoc->GetRoot()->GetDict(FX_BSTRC("AcroForm"))->GetDict(FX_BSTRC("DR"));
+ if (!pFontSetDict) {
+ return NULL;
+ }
+ pFontSetDict = (CPDF_Dictionary*)pFontSetDict->GetDict(FX_BSTRC("Font"));
+ if (!pFontSetDict) {
+ return NULL;
+ }
+ strPsName.Remove(' ');
+ IFX_FontMgr* pFDEFontMgr = m_pDoc->GetApp()->GetFDEFontMgr();
+ FX_POSITION pos = pFontSetDict->GetStartPos();
+ while (pos) {
+ CFX_ByteString key;
+ CPDF_Object* pObj = pFontSetDict->GetNextElement(pos, key);
+ if (!PsNameMatchDRFontName(strPsName, bBold, bItalic, key, bStrictMatch)) {
+ continue;
+ }
+ CPDF_Object* pDirect = pObj->GetDirect();
+ if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) {
+ return NULL;
+ }
+ CPDF_Dictionary* pFontDict = (CPDF_Dictionary*)pDirect;
+ if (pFontDict->GetString("Type") != FX_BSTRC("Font")) {
+ return NULL;
+ }
+ CPDF_Font* pPDFFont = pDoc->LoadFont(pFontDict);
+ if (!pPDFFont) {
+ return NULL;
+ }
+ if (!pPDFFont->IsEmbedded()) {
+ *pDstPDFFont = pPDFFont;
+ return NULL;
+ }
+ return IFX_Font::LoadFont(&pPDFFont->m_Font, pFDEFontMgr);
+ }
+ return NULL;
+}
+IFX_Font* CXFA_PDFFontMgr::GetFont(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, CPDF_Font** pPDFFont, FX_BOOL bStrictMatch )
+{
+ FX_DWORD dwHashCode = FX_HashCode_String_GetW(wsFontFamily.GetPtr(), wsFontFamily.GetLength());
+ CFX_ByteString strKey;
+ IFX_Font* pFont = NULL;
+ strKey.Format("%u%u", dwHashCode, dwFontStyles);
+ if (m_FontArray.Lookup(strKey, (void*&)pFont)) {
+ return pFont;
+ }
+ CFX_ByteString bsPsName;
+ bsPsName = CFX_ByteString::FromUnicode(wsFontFamily);
+ FX_BOOL bBold = (dwFontStyles & FX_FONTSTYLE_Bold) == FX_FONTSTYLE_Bold;
+ FX_BOOL bItalic = (dwFontStyles & FX_FONTSTYLE_Italic) == FX_FONTSTYLE_Italic;
+ CFX_ByteString strFontName = PsNameToFontName(bsPsName, bBold, bItalic);
+ pFont = FindFont(strFontName, bBold, bItalic, pPDFFont, bStrictMatch);
+ if (pFont) {
+ m_FontArray.SetAt(strKey, pFont);
+ }
+ return pFont;
+}
+CFX_ByteString CXFA_PDFFontMgr::PsNameToFontName(const CFX_ByteString& strPsName,
+ FX_BOOL bBold, FX_BOOL bItalic)
+{
+ FX_INT32 nCount = sizeof(g_XFAPDFFontName) / sizeof(XFA_PDFFONTNAME);
+ for (FX_INT32 i = 0; i < nCount; i++) {
+ if (strPsName == g_XFAPDFFontName[i].lpPsName) {
+ FX_INT32 index = 1 + ((bItalic << 1) | bBold);
+ return *(&g_XFAPDFFontName[i].lpPsName + index);
+ }
+ }
+ return strPsName;
+}
+FX_BOOL CXFA_PDFFontMgr::PsNameMatchDRFontName(FX_BSTR bsPsName, FX_BOOL bBold, FX_BOOL bItalic, const CFX_ByteString& bsDRFontName, FX_BOOL bStrictMatch)
+{
+ CFX_ByteString bsDRName = bsDRFontName;
+ bsDRName.Remove('-');
+ FX_INT32 iPsLen = bsPsName.GetLength();
+ FX_INT32 nIndex = bsDRName.Find(bsPsName);
+ if (nIndex != -1 && !bStrictMatch) {
+ return TRUE;
+ }
+ if (nIndex != 0) {
+ return FALSE;
+ }
+ FX_INT32 iDifferLength = bsDRName.GetLength() - iPsLen;
+ if (iDifferLength > 1 || (bBold || bItalic)) {
+ FX_INT32 iBoldIndex = bsDRName.Find(FX_BSTRC("Bold"));
+ FX_BOOL bBoldFont = iBoldIndex > 0;
+ if (bBold ^ bBoldFont) {
+ return FALSE;
+ }
+ if (bBoldFont) {
+ iDifferLength = FX_MIN(iDifferLength - 4, bsDRName.GetLength() - iBoldIndex - 4);
+ }
+ FX_BOOL bItalicFont = TRUE;
+ if (bsDRName.Find(FX_BSTRC("Italic")) > 0) {
+ iDifferLength -= 6;
+ } else if (bsDRName.Find(FX_BSTRC("It")) > 0) {
+ iDifferLength -= 2;
+ } else if (bsDRName.Find(FX_BSTRC("Oblique")) > 0) {
+ iDifferLength -= 7;
+ } else {
+ bItalicFont = FALSE;
+ }
+ if (bItalic ^ bItalicFont) {
+ return FALSE;
+ }
+ if (iDifferLength > 1) {
+ CFX_ByteString bsDRTailer = bsDRName.Right(iDifferLength);
+ if (bsDRTailer.Equal(FX_BSTRC("MT")) || bsDRTailer.Equal(FX_BSTRC("PSMT")) || bsDRTailer.Equal(FX_BSTRC("Regular")) || bsDRTailer.Equal(FX_BSTRC("Reg"))) {
+ return TRUE;
+ }
+ if (bBoldFont || bItalicFont) {
+ return FALSE;
+ }
+ FX_BOOL bMatch = FALSE;
+ switch (bsPsName.GetAt(iPsLen - 1)) {
+ case 'L': {
+ if (bsDRName.Right(5).Equal(FX_BSTRC("Light"))) {
+ bMatch = TRUE;
+ }
+ }
+ break;
+ case 'R': {
+ if ( bsDRName.Right(7).Equal(FX_BSTRC("Regular")) || bsDRName.Right(3).Equal(FX_BSTRC("Reg"))) {
+ bMatch = TRUE;
+ }
+ }
+ break;
+ case 'M': {
+ if (bsDRName.Right(5).Equal(FX_BSTRC("Medium"))) {
+ bMatch = TRUE;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return bMatch;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_PDFFontMgr::GetCharWidth(IFX_Font* pFont, FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode)
+{
+ if (wUnicode != 0x20 || bCharCode) {
+ return FALSE;
+ }
+ CPDF_Font* pPDFFont = (CPDF_Font*)m_FDE2PDFFont.GetValueAt(pFont);
+ if (!pPDFFont) {
+ return FALSE;
+ }
+ wUnicode = (FX_WCHAR)pPDFFont->CharCodeFromUnicode(wUnicode);
+ iWidth = pPDFFont->GetCharWidthF(wUnicode);
+ return TRUE;
+}
+CXFA_FontMgr::CXFA_FontMgr()
+ : m_pDefFontMgr(NULL)
+{
+}
+CXFA_FontMgr::~CXFA_FontMgr()
+{
+ DelAllMgrMap();
+}
+IFX_Font* CXFA_FontMgr::GetFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles,
+ FX_WORD wCodePage )
+{
+ FX_DWORD dwHash = FX_HashCode_String_GetW(wsFontFamily.GetPtr(), wsFontFamily.GetLength(), FALSE);
+ CFX_ByteString bsKey;
+ bsKey.Format("%u%u%u", dwHash, dwFontStyles, wCodePage);
+ IFX_Font* pFont = NULL;
+ if (m_FontArray.Lookup(bsKey, (void*&)pFont)) {
+ return pFont;
+ }
+ CFX_WideString wsEnglishName;
+ XFA_LocalFontNameToEnglishName(wsFontFamily, wsEnglishName);
+ CXFA_PDFFontMgr* pMgr = (CXFA_PDFFontMgr*)m_PDFFontMgrArray.GetValueAt(hDoc);
+ CPDF_Font* pPDFFont = NULL;
+ if (pMgr != NULL) {
+ pFont = pMgr->GetFont(wsEnglishName, dwFontStyles, &pPDFFont);
+ if (pFont) {
+ return pFont;
+ }
+ }
+ if (pFont == NULL && m_pDefFontMgr != NULL) {
+ pFont = m_pDefFontMgr->GetFont(hDoc, wsFontFamily, dwFontStyles, wCodePage);
+ }
+ if (pFont == NULL && pMgr != NULL) {
+ pPDFFont = NULL;
+ pFont = pMgr->GetFont(wsEnglishName, dwFontStyles, &pPDFFont, FALSE);
+ if (pFont) {
+ return pFont;
+ }
+ }
+ if (pFont == NULL && m_pDefFontMgr != NULL) {
+ pFont = m_pDefFontMgr->GetDefaultFont(hDoc, wsFontFamily, dwFontStyles, wCodePage);
+ }
+ FXSYS_assert(pFont != NULL);
+ if (pFont) {
+ if (pPDFFont) {
+ pMgr->m_FDE2PDFFont.SetAt(pFont, pPDFFont);
+ pFont->SetFontProvider(pMgr);
+ }
+ m_FontArray.SetAt(bsKey, pFont);
+ }
+ return pFont;
+}
+void CXFA_FontMgr::LoadDocFonts(XFA_HDOC hDoc)
+{
+ if (!m_PDFFontMgrArray.GetValueAt(hDoc)) {
+ m_PDFFontMgrArray.SetAt(hDoc, FX_NEW CXFA_PDFFontMgr((CXFA_FFDoc*)hDoc));
+ }
+}
+void CXFA_FontMgr::ReleaseDocFonts(XFA_HDOC hDoc)
+{
+ CXFA_PDFFontMgr* pMgr = NULL;
+ if (m_PDFFontMgrArray.Lookup(hDoc, (void*&)pMgr)) {
+ if (pMgr != NULL) {
+ delete pMgr;
+ }
+ m_PDFFontMgrArray.RemoveKey(hDoc);
+ }
+}
+void CXFA_FontMgr::DelAllMgrMap()
+{
+ FX_POSITION ps = m_PDFFontMgrArray.GetStartPosition();
+ while (ps) {
+ XFA_HDOC hDoc = NULL;
+ CXFA_PDFFontMgr* pMgr = NULL;
+ m_PDFFontMgrArray.GetNextAssoc(ps, (void*&)hDoc, (void*&)pMgr);
+ if (pMgr != NULL) {
+ delete pMgr;
+ }
+ }
+ m_PDFFontMgrArray.RemoveAll();
+ m_FontArray.RemoveAll();
+}
+void CXFA_FontMgr::SetDefFontMgr(IXFA_FontMgr* pFontMgr)
+{
+ m_pDefFontMgr = pFontMgr;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_fontmgr.h b/xfa/src/fxfa/src/app/xfa_fontmgr.h
new file mode 100644
index 0000000000..b5781c4954
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fontmgr.h
@@ -0,0 +1,62 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_FONTMGR_IMP_H
+#define _FXFA_FORMFILLER_FONTMGR_IMP_H
+struct XFA_FONTINFO {
+ FX_DWORD dwFontNameHash;
+ FX_LPCWSTR pPsName;
+ FX_LPCWSTR pReplaceFont;
+ FX_WORD dwStyles;
+ FX_WORD wCodePage;
+};
+class CXFA_DefFontMgr : public IXFA_FontMgr, public CFX_Object
+{
+public:
+ CXFA_DefFontMgr() {}
+ virtual ~CXFA_DefFontMgr();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual IFX_Font* GetFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF);
+ virtual IFX_Font* GetDefaultFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, FX_WORD wCodePage = 0xFFFF);
+protected:
+ CFX_PtrArray m_CacheFonts;
+};
+class CXFA_PDFFontMgr : public IFX_FontProvider, public CFX_Object
+{
+public:
+ CXFA_PDFFontMgr(CXFA_FFDoc* pDoc);
+ ~CXFA_PDFFontMgr();
+ IFX_Font* GetFont(FX_WSTR wsFontFamily, FX_DWORD dwFontStyles, CPDF_Font** pPDFFont, FX_BOOL bStrictMatch = TRUE);
+ FX_BOOL GetCharWidth(IFX_Font* pFont, FX_WCHAR wUnicode, FX_INT32 &iWidth, FX_BOOL bCharCode);
+ CFX_MapPtrToPtr m_FDE2PDFFont;
+protected:
+ IFX_Font* FindFont(CFX_ByteString strFamilyName, FX_BOOL bBold, FX_BOOL bItalic, CPDF_Font** pPDFFont, FX_BOOL bStrictMatch = TRUE);
+ CFX_ByteString PsNameToFontName(const CFX_ByteString& strPsName, FX_BOOL bBold, FX_BOOL bItalic);
+ FX_BOOL PsNameMatchDRFontName(FX_BSTR bsPsName, FX_BOOL bBold, FX_BOOL bItalic, const CFX_ByteString& bsDRFontName, FX_BOOL bStrictMatch = TRUE);
+ CXFA_FFDoc* m_pDoc;
+ CFX_CMapByteStringToPtr m_FontArray;
+};
+class CXFA_FontMgr : public CFX_Object
+{
+public:
+ CXFA_FontMgr();
+ ~CXFA_FontMgr();
+ IFX_Font* GetFont(XFA_HDOC hDoc, FX_WSTR wsFontFamily, FX_DWORD dwFontStyles,
+ FX_WORD wCodePage = 0xFFFF);
+ void LoadDocFonts(XFA_HDOC hDoc);
+ void ReleaseDocFonts(XFA_HDOC hDoc);
+
+ void SetDefFontMgr(IXFA_FontMgr* pFontMgr);
+protected:
+ void DelAllMgrMap();
+ CFX_MapPtrToPtr m_PDFFontMgrArray;
+ IXFA_FontMgr* m_pDefFontMgr;
+ CFX_CMapByteStringToPtr m_FontArray;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_fwladapter.cpp b/xfa/src/fxfa/src/app/xfa_fwladapter.cpp
new file mode 100644
index 0000000000..035fa02310
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fwladapter.cpp
@@ -0,0 +1,80 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwladapter.h"
+#include "xfa_ffwidget.h"
+#include "xfa_fffield.h"
+#include "xfa_ffdoc.h"
+IFWL_AdapterNative * FWL_CreateFuelAdapterNative()
+{
+ return NULL;
+}
+void FWL_ReleaseFuelAdapterNative(IFWL_AdapterNative * native)
+{
+}
+void FWL_PostMessageToMainRoop(CFWL_Message *pMessage)
+{
+}
+IFWL_AdapterSemaphore * IFWL_AdapterSemaphore::Create()
+{
+ return NULL;
+}
+FX_BOOL FWL_ShowCaret(IFWL_Widget *pWidget, FX_BOOL bVisible, const CFX_RectF *pRtAnchor)
+{
+ CXFA_FFWidget* pXFAWidget = (CXFA_FFWidget*)pWidget->GetPrivateData(pWidget);
+ if (!pXFAWidget) {
+ return FALSE;
+ }
+ IXFA_DocProvider* pDocProvider = pXFAWidget->GetDoc()->GetDocProvider();
+ if (!pDocProvider) {
+ return FALSE;
+ }
+ if (bVisible) {
+ CFX_Matrix mt;
+ pXFAWidget->GetRotateMatrix(mt);
+ CFX_RectF rt(*pRtAnchor);
+ mt.TransformRect(rt);
+ pDocProvider->DisplayCaret((XFA_HWIDGET)pXFAWidget, bVisible, &rt);
+ return TRUE;
+ }
+ pDocProvider->DisplayCaret((XFA_HWIDGET)pXFAWidget, bVisible, pRtAnchor);
+ return TRUE;
+}
+FWL_ERR CXFA_FWLAdapterWidgetMgr::RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect)
+{
+ _FWL_RETURN_VALUE_IF_FAIL(pWidget, FWL_ERR_Indefinite);
+ CXFA_FFField *pField = (CXFA_FFField*)pWidget->GetPrivateData(pWidget);
+ _FWL_RETURN_VALUE_IF_FAIL(pField, FWL_ERR_Indefinite);
+#ifdef _XFA_EMB
+ CFX_RectF rtInvalidate;
+ pWidget->GetWidgetRect(rtInvalidate);
+ if (pRect) {
+ rtInvalidate.left += pRect->left;
+ rtInvalidate.top += pRect->top;
+ rtInvalidate.width = pRect->width;
+ rtInvalidate.height = pRect->height;
+ }
+ CFX_Matrix mt;
+ pField->GetRotateMatrix(mt);
+ mt.TransformRect(rtInvalidate);
+ pField->AddInvalidateRect(&rtInvalidate);
+#else
+ pField->AddInvalidateRect(NULL);
+#endif
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CXFA_FWLAdapterWidgetMgr::GetPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup)
+{
+ CXFA_FFWidget* pFFWidget = (CXFA_FFWidget*)(pWidget->GetPrivateData(pWidget));
+ CFX_Matrix mt;
+ pFFWidget->GetRotateMatrix(mt);
+ CFX_RectF rtRotateAnchor(rtAnchor);
+ mt.TransformRect(rtRotateAnchor);
+ pFFWidget->GetDoc()->GetDocProvider()->GetPopupPos((XFA_HWIDGET)pFFWidget, fMinHeight, fMaxHeight, rtRotateAnchor, rtPopup);
+ return TRUE;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_fwladapter.h b/xfa/src/fxfa/src/app/xfa_fwladapter.h
new file mode 100644
index 0000000000..8e830142c4
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fwladapter.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FWL_ADAPTER_IMP_H
+#define _XFA_FWL_ADAPTER_IMP_H
+class CXFA_FWLAdapterWidgetMgr : public CFWL_SDAdapterWidgetMgr
+{
+public:
+ virtual FWL_ERR RepaintWidget(IFWL_Widget *pWidget, const CFX_RectF *pRect);
+ virtual FX_BOOL GetPopupPos(IFWL_Widget* pWidget, FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight, const CFX_RectF &rtAnchor, CFX_RectF &rtPopup);
+};
+class IXFA_FWLEventHandler
+{
+public:
+ virtual FX_BOOL GetPopupPos(IFWL_Widget *pWidget, FX_FLOAT fMinPopup, FX_FLOAT fMaxPopup,
+ const CFX_RectF &rtAnchor, CFX_RectF& rtPopup)
+ {
+ return FALSE;
+ }
+ virtual void OnPreOpen(IFWL_Widget *pWidget) {}
+ virtual void OnPostOpen(IFWL_Widget *pWidget) {}
+ virtual void OnSelectChanged(IFWL_Widget *pWidget, FX_INT32 iYear, FX_INT32 iMonth, FX_INT32 iDay) {}
+ virtual void OnTextChanged(IFWL_Widget *pWidget, const CFX_WideString &wsChanged) {}
+ virtual void OnTextFull(IFWL_Widget *pWidget) {}
+ virtual FX_BOOL OnValidate(IFWL_Widget *pWidget, CFX_WideString &wsText)
+ {
+ return FALSE;
+ }
+ virtual void OnSelectChanged(IFWL_Widget *pWidget, const CFX_Int32Array &arrSels) {}
+ virtual void OnAddDoRecord(IFWL_Widget *pWidget) {}
+ virtual CXFA_Edge GetComboSplitColor(IFWL_Widget *pWidget)
+ {
+ return CXFA_Edge(NULL);
+ }
+ virtual void GetUIMargin(CFX_RectF &rtMargin) {}
+ virtual FX_BOOL CheckWord(FX_BSTR sWord)
+ {
+ return TRUE;
+ }
+ virtual FX_BOOL GetSuggestWords(FX_BSTR sWord, CFX_ByteStringArray &sSuggest)
+ {
+ return FALSE;
+ }
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_fwltheme.cpp b/xfa/src/fxfa/src/app/xfa_fwltheme.cpp
new file mode 100644
index 0000000000..7456e892db
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fwltheme.cpp
@@ -0,0 +1,412 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_fwltheme.h"
+#include "xfa_ffwidget.h"
+#include "xfa_ffapp.h"
+CXFA_FFWidget* XFA_ThemeGetOuterWidget(IFWL_Widget* pWidget)
+{
+ IFWL_Widget* pOuter = pWidget;
+ while (pOuter->GetOuter()) {
+ pOuter = pOuter->GetOuter();
+ }
+ if (pOuter) {
+ return (CXFA_FFWidget*)pOuter->GetPrivateData(pOuter);
+ }
+ return NULL;
+}
+CXFA_FWLTheme::CXFA_FWLTheme(CXFA_FFApp *pApp)
+ : m_pApp(pApp)
+{
+ m_pTextOut = NULL;
+ m_dwCapacity = 0;
+ m_fCapacity = 0;
+ m_pCalendarFont = NULL;
+ m_Rect.Set(0, 0, 0, 0);
+ m_SizeAboveBelow.Set(0, 0);
+ m_pCheckBoxTP = FX_NEW CXFA_FWLCheckBoxTP;
+ m_pListBoxTP = FX_NEW CFWL_ListBoxTP;
+ m_pPictureBoxTP = FX_NEW CFWL_PictureBoxTP;
+ m_pSrollBarTP = FX_NEW CFWL_ScrollBarTP;
+ m_pEditTP = FX_NEW CXFA_FWLEditTP;
+ m_pComboBoxTP = FX_NEW CFWL_ComboBoxTP;
+ m_pMonthCalendarTP = FX_NEW CFWL_MonthCalendarTP;
+ m_pDateTimePickerTP = FX_NEW CFWL_DateTimePickerTP;
+ m_pPushButtonTP = FX_NEW CFWL_PushButtonTP;
+ m_pCaretTP = FX_NEW CFWL_CaretTP;
+ m_pBarcodeTP = FX_NEW CFWL_BarcodeTP;
+ Initialize();
+}
+CXFA_FWLTheme::~CXFA_FWLTheme()
+{
+ Finalize();
+ delete m_pCheckBoxTP;
+ delete m_pListBoxTP;
+ delete m_pPictureBoxTP;
+ delete m_pSrollBarTP;
+ delete m_pEditTP;
+ delete m_pComboBoxTP;
+ delete m_pMonthCalendarTP;
+ delete m_pDateTimePickerTP;
+ delete m_pPushButtonTP;
+ delete m_pCaretTP;
+ delete m_pBarcodeTP;
+}
+static FX_LPCWSTR g_FWLTheme_CalFonts[] = {
+ (FX_LPCWSTR)L"Arial",
+ (FX_LPCWSTR)L"Courier New",
+ (FX_LPCWSTR)L"DejaVu Sans",
+};
+FWL_ERR CXFA_FWLTheme::Initialize()
+{
+ m_pTextOut = IFDE_TextOut::Create();
+ for (FX_INT32 i = 0; NULL == m_pCalendarFont && i < sizeof(g_FWLTheme_CalFonts) / sizeof(FX_LPCWSTR); i++) {
+ m_pCalendarFont = IFX_Font::LoadFont(g_FWLTheme_CalFonts[i], 0, 0, m_pApp->GetFDEFontMgr());
+ }
+ if (NULL == m_pCalendarFont)
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetDefFontByCodePage(FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL);
+#else
+ m_pCalendarFont = m_pApp->GetFDEFontMgr()->GetFontByCodePage(FX_CODEPAGE_MSWin_WesternEuropean, 0, NULL);
+#endif
+ FXSYS_assert(NULL != m_pCalendarFont);
+ FWLTHEME_Init();
+ return FWL_ERR_Succeeded;
+}
+FWL_ERR CXFA_FWLTheme::Finalize()
+{
+ if (m_pTextOut) {
+ m_pTextOut->Release();
+ m_pTextOut = NULL;
+ }
+ if (m_pCalendarFont) {
+ m_pCalendarFont->Release();
+ m_pCalendarFont = NULL;
+ }
+ FWLTHEME_Release();
+ return FWL_ERR_Succeeded;
+}
+FX_BOOL CXFA_FWLTheme::IsValidWidget(IFWL_Widget *pWidget)
+{
+ return TRUE;
+}
+FX_DWORD CXFA_FWLTheme::GetThemeID(IFWL_Widget *pWidget)
+{
+ return 0;
+}
+FX_DWORD CXFA_FWLTheme::SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren )
+{
+ return 0;
+}
+FX_BOOL CXFA_FWLTheme::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ return GetTheme(pParams->m_pWidget)->DrawBackground(pParams);
+}
+FX_BOOL CXFA_FWLTheme::DrawText(CFWL_ThemeText *pParams)
+{
+ if (pParams->m_wsText.IsEmpty()) {
+ return FWL_ERR_Indefinite;
+ }
+ if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) {
+ CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+ if (!pWidget) {
+ return FWL_ERR_Indefinite;
+ }
+ m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+ m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+ m_pTextOut->SetFont(m_pCalendarFont);
+ m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
+ m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
+ if ((pParams->m_iPart == FWL_PART_MCD_DatesIn) && !(pParams->m_dwStates & FWL_ITEMSTATE_MCD_Flag) &&
+ (pParams->m_dwStates & (FWL_PARTSTATE_MCD_Hovered | FWL_PARTSTATE_MCD_Selected))) {
+ m_pTextOut->SetTextColor(0xFFFFFFFF);
+ }
+ if (pParams->m_iPart == FWL_PART_MCD_Caption) {
+ if (m_pMonthCalendarTP->GetThemeID(pParams->m_pWidget) == 0 ) {
+ m_pTextOut->SetTextColor(ArgbEncode(0xff, 0, 153, 255));
+ } else {
+ m_pTextOut->SetTextColor(ArgbEncode(0xff, 128, 128, 0));
+ }
+ }
+ CFX_Graphics *pGraphics = pParams->m_pGraphics;
+ CFX_RenderDevice *pRenderDevice = pGraphics->GetRenderDevice();
+ _FWL_RETURN_VALUE_IF_FAIL(pRenderDevice, FALSE);
+ m_pTextOut->SetRenderDevice(pRenderDevice);
+ CFX_Matrix mtPart = pParams->m_matrix;
+ CFX_Matrix *pMatrix = pGraphics->GetMatrix();
+ if (pMatrix) {
+ mtPart.Concat(*pMatrix);
+ }
+ m_pTextOut->SetMatrix(mtPart);
+ m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(), pParams->m_rtPart);
+ return TRUE;
+ }
+ CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+ if (!pWidget) {
+ return FWL_ERR_Indefinite;
+ }
+ CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+ CFX_Graphics *pGraphics = pParams->m_pGraphics;
+ CFX_RenderDevice *pRenderDevice = pGraphics->GetRenderDevice();
+ _FWL_RETURN_VALUE_IF_FAIL(pRenderDevice, FALSE);
+ m_pTextOut->SetRenderDevice(pRenderDevice);
+ m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+ m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+ m_pTextOut->SetFont(pAcc->GetFDEFont());
+ m_pTextOut->SetFontSize(pAcc->GetFontSize());
+ m_pTextOut->SetTextColor(pAcc->GetTextColor());
+ CFX_Matrix mtPart = pParams->m_matrix;
+ CFX_Matrix *pMatrix = pGraphics->GetMatrix();
+ if (pMatrix) {
+ mtPart.Concat(*pMatrix);
+ }
+ m_pTextOut->SetMatrix(mtPart);
+ m_pTextOut->DrawLogicText(pParams->m_wsText, pParams->m_wsText.GetLength(), pParams->m_rtPart);
+ return TRUE;
+}
+FX_LPVOID CXFA_FWLTheme::GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity)
+{
+ switch(dwCapacity) {
+ case FWL_WGTCAPACITY_Font: {
+ if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+ return pWidget->GetDataAcc()->GetFDEFont();
+ }
+ }
+ break;
+ case FWL_WGTCAPACITY_FontSize: {
+ if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+ m_fCapacity = pWidget->GetDataAcc()->GetFontSize();
+ return &m_fCapacity;
+ }
+ }
+ break;
+ case FWL_WGTCAPACITY_TextColor: {
+ if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+ m_dwCapacity = pWidget->GetDataAcc()->GetTextColor();
+ return &m_dwCapacity;
+ }
+ }
+ break;
+ case FWL_WGTCAPACITY_LineHeight: {
+ if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+ m_fCapacity = pWidget->GetDataAcc()->GetLineHeight();
+ return &m_fCapacity;
+ }
+ }
+ break;
+ case FWL_WGTCAPACITY_ScrollBarWidth: {
+ m_fCapacity = 9;
+ return &m_fCapacity;
+ }
+ break;
+ case FWL_WGTCAPACITY_UIMargin: {
+ CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
+ if (pWidget) {
+ CXFA_LayoutItem* pItem = pWidget->GetLayoutItem();
+ if (!pItem) {
+ return &m_Rect;
+ }
+ CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
+ pWidgetAcc->GetUIMargin(m_Rect);
+ if (CXFA_Para para = pWidgetAcc->GetPara()) {
+ m_Rect.left += para.GetMarginLeft();
+ if (pWidgetAcc->IsMultiLine()) {
+ m_Rect.width += para.GetMarginRight();
+ }
+ }
+ if (pItem->GetPrev() == NULL) {
+ if (pItem->GetNext() != NULL) {
+ m_Rect.height = 0;
+ }
+ } else if (pItem->GetNext() == NULL) {
+ m_Rect.top = 0;
+ } else {
+ m_Rect.top = 0;
+ m_Rect.height = 0;
+ }
+ }
+ return &m_Rect;
+ }
+ break;
+ case FWL_WGTCAPACITY_SpaceAboveBelow: {
+ CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget);
+ if (pWidget) {
+ CXFA_WidgetAcc* pWidgetAcc = pWidget->GetDataAcc();
+ if (CXFA_Para para = pWidgetAcc->GetPara()) {
+ m_SizeAboveBelow.x = para.GetSpaceAbove();
+ m_SizeAboveBelow.y = para.GetSpaceBelow();
+ }
+ }
+ return &m_SizeAboveBelow;
+ }
+ break;
+ default:
+ break;
+ }
+ if (pThemePart->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar && dwCapacity >= FWL_MCCAPACITY_Sun && dwCapacity <= FWL_MCCAPACITY_Today) {
+ if (CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pThemePart->m_pWidget)) {
+ IXFA_AppProvider *pAppProvider = pWidget->GetAppProvider();
+ m_wsResource.Empty();
+ pAppProvider->LoadString(XFA_IDS_StringWeekDay_Sun + dwCapacity - FWL_WGTCAPACITY_MAX - 5, m_wsResource);
+ if (!m_wsResource.IsEmpty()) {
+ return &m_wsResource;
+ }
+ }
+ }
+ return GetTheme(pThemePart->m_pWidget)->GetCapacity(pThemePart, dwCapacity);
+}
+FX_BOOL CXFA_FWLTheme::IsCustomizedLayout(IFWL_Widget *pWidget)
+{
+ return GetTheme(pWidget)->IsCustomizedLayout(pWidget);
+}
+FWL_ERR CXFA_FWLTheme::GetPartRect(CFWL_ThemePart* pThemePart)
+{
+ CFX_RectF rect;
+ return GetTheme(pThemePart->m_pWidget)->GetPartRect(pThemePart, rect);
+}
+FX_BOOL CXFA_FWLTheme::IsInPart(CFWL_ThemePart* pThemePart, FX_FLOAT fx, FX_FLOAT fy)
+{
+ return GetTheme(pThemePart->m_pWidget)->IsInPart(pThemePart, fx, fy);
+}
+FX_BOOL CXFA_FWLTheme::CalcTextRect(CFWL_ThemeText *pParams, CFX_RectF &rect)
+{
+ if (pParams->m_pWidget->GetClassID() == FWL_CLASSHASH_MonthCalendar) {
+ CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+ if (!pWidget) {
+ return FWL_ERR_Indefinite;
+ }
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pTextOut, FALSE);
+ m_pTextOut->SetFont(m_pCalendarFont);
+ m_pTextOut->SetFontSize(FWLTHEME_CAPACITY_FontSize);
+ m_pTextOut->SetTextColor(FWLTHEME_CAPACITY_TextColor);
+ m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+ m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+ m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), rect);
+ return TRUE;
+ }
+ CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+ if (!pWidget) {
+ return FWL_ERR_Indefinite;
+ }
+ CXFA_WidgetAcc* pAcc = pWidget->GetDataAcc();
+ m_pTextOut->SetFont(pAcc->GetFDEFont());
+ m_pTextOut->SetFontSize(pAcc->GetFontSize());
+ m_pTextOut->SetTextColor(pAcc->GetTextColor());
+ _FWL_RETURN_VALUE_IF_FAIL(pParams, FALSE);
+ _FWL_RETURN_VALUE_IF_FAIL(m_pTextOut, FALSE);
+ m_pTextOut->SetAlignment(pParams->m_iTTOAlign);
+ m_pTextOut->SetStyles(pParams->m_dwTTOStyles);
+ m_pTextOut->CalcLogicSize(pParams->m_wsText, pParams->m_wsText.GetLength(), rect);
+ return TRUE;
+}
+CFWL_WidgetTP* CXFA_FWLTheme::GetTheme(IFWL_Widget* pWidget)
+{
+ switch(pWidget->GetClassID()) {
+ case FWL_CLASSHASH_CheckBox:
+ case FWL_CLASSHASH_RadioButton:
+ return m_pCheckBoxTP;
+ case FWL_CLASSHASH_ListBox:
+ return m_pListBoxTP;
+ case FWL_CLASSHASH_PictureBox:
+ return m_pPictureBoxTP;
+ case FWL_CLASSHASH_ScrollBar:
+ return m_pSrollBarTP;
+ case FWL_CLASSHASH_Edit:
+ return m_pEditTP;
+ case FWL_CLASSHASH_ComboBox:
+ return m_pComboBoxTP;
+ case FWL_CLASSHASH_MonthCalendar:
+ return m_pMonthCalendarTP;
+ case FWL_CLASSHASH_DateTimePicker:
+ return m_pDateTimePickerTP;
+ case FWL_CLASSHASH_PushButton:
+ return m_pPushButtonTP;
+ case FWL_CLASSHASH_Caret:
+ return m_pCaretTP;
+ case FWL_CLASSHASH_Barcode:
+ return m_pBarcodeTP;
+ default:
+ break;
+ }
+ return NULL;
+}
+CXFA_FWLCheckBoxTP::CXFA_FWLCheckBoxTP()
+{
+}
+FX_BOOL CXFA_FWLCheckBoxTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ if (pParams->m_iPart != FWL_PART_CKB_CheckBox) {
+ return TRUE;
+ }
+ if (((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Checked) || ((pParams->m_dwStates & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral)) {
+ DrawCheckSign(pParams->m_pWidget, pParams->m_pGraphics, &pParams->m_rtPart, pParams->m_dwStates, &pParams->m_matrix);
+ }
+ return TRUE;
+}
+void CXFA_FWLCheckBoxTP::DrawCheckSign(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRtBox, FX_INT32 iState, CFX_Matrix* pMatrix)
+{
+ CFX_RectF rtSign(*pRtBox);
+ FX_DWORD dwColor = 0xFF000000;
+ if ((iState & FWL_PARTSTATE_CKB_Mask2) == FWL_PARTSTATE_CKB_Neutral) {
+ dwColor = 0xFFA9A9A9;
+ }
+ {
+ FX_DWORD dwStyle = pWidget->GetStylesEx();
+ rtSign.Deflate(rtSign.width / 4, rtSign.height / 4);
+ switch(dwStyle & FWL_STYLEEXT_CKB_SignShapeMask) {
+ case FWL_STYLEEXT_CKB_SignShapeCheck:
+ DrawSignCheck(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ case FWL_STYLEEXT_CKB_SignShapeCircle:
+ DrawSignCircle(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ case FWL_STYLEEXT_CKB_SignShapeCross:
+ DrawSignCross(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ case FWL_STYLEEXT_CKB_SignShapeDiamond:
+ DrawSignDiamond(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ case FWL_STYLEEXT_CKB_SignShapeSquare:
+ DrawSignSquare(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ case FWL_STYLEEXT_CKB_SignShapeStar:
+ DrawSignStar(pGraphics, &rtSign, dwColor, pMatrix);
+ break;
+ default:
+ break;
+ }
+ }
+}
+CXFA_FWLEditTP::CXFA_FWLEditTP()
+{
+}
+CXFA_FWLEditTP::~CXFA_FWLEditTP()
+{
+}
+FX_BOOL CXFA_FWLEditTP::DrawBackground(CFWL_ThemeBackground *pParams)
+{
+ if (FWL_PART_EDT_CombTextLine == pParams->m_iPart) {
+ CXFA_FFWidget* pWidget = XFA_ThemeGetOuterWidget(pParams->m_pWidget);
+ FX_ARGB cr = 0xFF000000;
+ FX_FLOAT fWidth = 1.0f;
+ if (CXFA_Border borderUI = pWidget->GetDataAcc()->GetUIBorder()) {
+ CXFA_Edge edge = borderUI.GetEdge(0);
+ if (edge) {
+ cr = edge.GetColor();
+ fWidth = edge.GetThickness();
+ }
+ }
+ CFX_Color crLine(cr);
+ pParams->m_pGraphics->SetStrokeColor(&crLine);
+ pParams->m_pGraphics->SetLineWidth(fWidth);
+ pParams->m_pGraphics->StrokePath(pParams->m_pPath, &pParams->m_matrix);
+ return TRUE;
+ }
+ return CFWL_EditTP::DrawBackground(pParams);
+}
diff --git a/xfa/src/fxfa/src/app/xfa_fwltheme.h b/xfa/src/fxfa/src/app/xfa_fwltheme.h
new file mode 100644
index 0000000000..beb5e6abf6
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_fwltheme.h
@@ -0,0 +1,94 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FWL_THEME_IMP_H
+#define _XFA_FWL_THEME_IMP_H
+class CXFA_FWLTheme : public IFWL_ThemeProvider, public CFX_Object
+{
+public:
+ CXFA_FWLTheme(CXFA_FFApp *pApp);
+ virtual~CXFA_FWLTheme();
+ virtual FWL_ERR Release()
+ {
+ delete this;
+ return FWL_ERR_Succeeded;
+ }
+ virtual IFWL_Target* Retain()
+ {
+ return NULL;
+ }
+ virtual FWL_ERR GetClassName(CFX_WideString &wsClass) const
+ {
+ return FWL_ERR_Succeeded;
+ }
+ virtual FX_DWORD GetHashCode() const
+ {
+ return 0;
+ }
+ virtual FWL_ERR Initialize();
+ virtual FWL_ERR Finalize();
+ virtual FX_BOOL IsValidWidget(IFWL_Widget *pWidget);
+ virtual FX_DWORD GetThemeID(IFWL_Widget *pWidget);
+ virtual FX_DWORD SetThemeID(IFWL_Widget *pWidget, FX_DWORD dwThemeID, FX_BOOL bChildren = TRUE);
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+ virtual FX_BOOL DrawText(CFWL_ThemeText *pParams);
+ virtual FX_LPVOID GetCapacity(CFWL_ThemePart *pThemePart, FX_DWORD dwCapacity);
+ virtual FX_BOOL IsCustomizedLayout(IFWL_Widget *pWidget);
+ virtual FWL_ERR GetPartRect(CFWL_ThemePart* pThemePart);
+ virtual FX_BOOL IsInPart(CFWL_ThemePart* pThemePart, FX_FLOAT fx, FX_FLOAT fy);
+
+ virtual FX_BOOL CalcTextRect(CFWL_ThemeText *pParams, CFX_RectF &rect);
+ virtual FWL_ERR GetThemeMatrix(IFWL_Widget *pWidget, CFX_Matrix &matrix)
+ {
+ return FWL_ERR_Succeeded;
+ }
+ virtual FWL_ERR SetThemeMatrix(IFWL_Widget *pWidget, const CFX_Matrix &matrix)
+ {
+ return FWL_ERR_Succeeded;
+ }
+ virtual FWL_ERR GetPartRect(CFWL_ThemePart *pThemePart, CFX_RectF &rtPart)
+ {
+ return FWL_ERR_Succeeded;
+ }
+protected:
+ CFWL_WidgetTP* GetTheme(IFWL_Widget* pWidget);
+ CFWL_CheckBoxTP* m_pCheckBoxTP;
+ CFWL_ListBoxTP* m_pListBoxTP;
+ CFWL_PictureBoxTP* m_pPictureBoxTP;
+ CFWL_ScrollBarTP* m_pSrollBarTP;
+ CFWL_EditTP* m_pEditTP;
+ CFWL_ComboBoxTP* m_pComboBoxTP;
+ CFWL_MonthCalendarTP* m_pMonthCalendarTP;
+ CFWL_DateTimePickerTP* m_pDateTimePickerTP;
+ CFWL_PushButtonTP* m_pPushButtonTP;
+ CFWL_CaretTP* m_pCaretTP;
+ CFWL_BarcodeTP* m_pBarcodeTP;
+ IFDE_TextOut* m_pTextOut;
+ FX_FLOAT m_fCapacity;
+ FX_DWORD m_dwCapacity;
+ IFX_Font* m_pCalendarFont;
+ CFX_WideString m_wsResource;
+ CXFA_FFApp* m_pApp;
+ CFX_RectF m_Rect;
+ CFX_SizeF m_SizeAboveBelow;
+};
+class CXFA_FWLCheckBoxTP : public CFWL_CheckBoxTP
+{
+public:
+ CXFA_FWLCheckBoxTP();
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+protected:
+ void DrawCheckSign(IFWL_Widget *pWidget, CFX_Graphics *pGraphics, const CFX_RectF *pRtBox, FX_INT32 iState, CFX_Matrix* pMatrix);
+};
+class CXFA_FWLEditTP : public CFWL_EditTP
+{
+public:
+ CXFA_FWLEditTP();
+ virtual ~CXFA_FWLEditTP();
+public:
+ virtual FX_BOOL DrawBackground(CFWL_ThemeBackground *pParams);
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_rendercontext.cpp b/xfa/src/fxfa/src/app/xfa_rendercontext.cpp
new file mode 100644
index 0000000000..5447506b24
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_rendercontext.cpp
@@ -0,0 +1,74 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_rendercontext.h"
+#include "xfa_ffwidget.h"
+#define XFA_RENDERCONTEXT_MaxCount 30
+IXFA_RenderContext* XFA_RenderContext_Create()
+{
+ return FX_NEW CXFA_RenderContext;
+}
+CXFA_RenderContext::CXFA_RenderContext()
+{
+ m_pWidgetIterator = NULL;
+ m_pWidget = NULL;
+ m_pPageView = NULL;
+ m_pGS = NULL;
+ m_dwStatus = 0;
+ m_matrix.Reset();
+ m_rtClipRect.Reset();
+}
+CXFA_RenderContext::~CXFA_RenderContext()
+{
+ StopRender();
+}
+FX_INT32 CXFA_RenderContext::StartRender(IXFA_PageView* pPageView, CFX_Graphics* pGS, const CFX_Matrix& matrix, const CXFA_RenderOptions& options)
+{
+ m_pPageView = pPageView;
+ m_pGS = pGS;
+ m_matrix = matrix;
+ m_options = options;
+ CFX_RectF rtPage;
+ pGS->GetClipRect(rtPage);
+ CFX_Matrix mtRes;
+ mtRes.SetReverse(matrix);
+ m_rtClipRect.Set(rtPage.left, rtPage.top, rtPage.width, rtPage.height);
+ mtRes.TransformRect(m_rtClipRect);
+ m_dwStatus = m_options.m_bHighlight ? XFA_WIDGETSTATUS_Highlight : 0;
+ FX_DWORD dwFilterType = XFA_WIDGETFILTER_Visible | XFA_WIDGETFILTER_AllType | (m_options.m_bPrint ? XFA_WIDGETSTATUS_Printable : XFA_WIDGETSTATUS_Viewable);
+ m_pWidgetIterator = m_pPageView->CreateWidgetIterator(XFA_TRAVERSEWAY_Form, dwFilterType);
+ m_pWidget = m_pWidgetIterator->MoveToNext();
+ return XFA_RENDERSTATUS_Ready;
+}
+FX_INT32 CXFA_RenderContext::DoRender(IFX_Pause* pPause)
+{
+ FX_INT32 iCount = 0;
+ while(m_pWidget) {
+ CXFA_FFWidget* pWidget = (CXFA_FFWidget*)m_pWidget;
+ CFX_RectF rtWidgetBox;
+ pWidget->GetBBox(rtWidgetBox, XFA_WIDGETSTATUS_Visible);
+ rtWidgetBox.width += 1;
+ rtWidgetBox.height += 1;
+ if (rtWidgetBox.IntersectWith(m_rtClipRect)) {
+ pWidget->RenderWidget(m_pGS, &m_matrix, m_dwStatus);
+ }
+ m_pWidget = m_pWidgetIterator->MoveToNext();
+ iCount++;
+ if (iCount > XFA_RENDERCONTEXT_MaxCount && pPause && pPause->NeedToPauseNow()) {
+ return XFA_RENDERSTATUS_ToBeContinued;
+ }
+ }
+ return XFA_RENDERSTATUS_Done;
+}
+void CXFA_RenderContext::StopRender()
+{
+ if (m_pWidgetIterator) {
+ m_pWidgetIterator->Release();
+ m_pWidgetIterator = NULL;
+ }
+}
diff --git a/xfa/src/fxfa/src/app/xfa_rendercontext.h b/xfa/src/fxfa/src/app/xfa_rendercontext.h
new file mode 100644
index 0000000000..f50adddec1
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_rendercontext.h
@@ -0,0 +1,31 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_FORMFILLER_RENDERCONTEXT_IMP_H
+#define _FXFA_FORMFILLER_RENDERCONTEXT_IMP_H
+class CXFA_RenderContext : public IXFA_RenderContext, public CFX_Object
+{
+public:
+ CXFA_RenderContext();
+ virtual ~CXFA_RenderContext();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_INT32 StartRender(IXFA_PageView* pPageView, CFX_Graphics* pGS, const CFX_Matrix& matrix, const CXFA_RenderOptions& options);
+ virtual FX_INT32 DoRender(IFX_Pause* pPause = NULL);
+ virtual void StopRender();
+protected:
+ IXFA_WidgetIterator* m_pWidgetIterator;
+ XFA_HWIDGET m_pWidget;
+ IXFA_PageView* m_pPageView;
+ CFX_Graphics* m_pGS;
+ CFX_Matrix m_matrix;
+ CXFA_RenderOptions m_options;
+ FX_DWORD m_dwStatus;
+ CFX_RectF m_rtClipRect;
+};
+#endif
diff --git a/xfa/src/fxfa/src/app/xfa_textlayout.cpp b/xfa/src/fxfa/src/app/xfa_textlayout.cpp
new file mode 100644
index 0000000000..5a4eee48f5
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_textlayout.cpp
@@ -0,0 +1,1927 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_common.h"
+#include "xfa_textlayout.h"
+#include "xfa_ffapp.h"
+#include "xfa_ffdoc.h"
+#include "xfa_fontmgr.h"
+CXFA_CSSTagProvider::~CXFA_CSSTagProvider()
+{
+ FX_POSITION pos = m_Attributes.GetStartPosition();
+ while (pos) {
+ CFX_WideString* pName = NULL, *pValue = NULL;
+ m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
+ if (pName != NULL) {
+ delete pName;
+ }
+ if (pValue != NULL) {
+ delete pValue;
+ }
+ }
+}
+void CXFA_CSSTagProvider::GetNextAttribute(FX_POSITION &pos, CFX_WideStringC &wsAttr, CFX_WideStringC &wsValue)
+{
+ if (pos == NULL) {
+ return;
+ }
+ CFX_WideString *pName = NULL;
+ CFX_WideString *pValue = NULL;
+ m_Attributes.GetNextAssoc(pos, (void*&)pName, (void*&)pValue);
+ wsAttr = *pName;
+ wsValue = *pValue;
+}
+void CXFA_CSSTagProvider::SetAttribute(const CFX_WideString &wsAttr, const CFX_WideString &wsValue)
+{
+ CFX_WideString *pName = FX_NEW CFX_WideString();
+ CFX_WideString *pValue = FX_NEW CFX_WideString();
+ *pName = wsAttr;
+ *pValue = wsValue;
+ m_Attributes.SetAt(pName, pValue);
+}
+void CXFA_TextParseContext::SetDecls(const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount)
+{
+ if (iDeclCount <= 0 || ppDeclArray == NULL) {
+ return;
+ }
+ m_dwMatchedDecls = iDeclCount;
+ FX_INT32 iBytes = iDeclCount * sizeof(IFDE_CSSDeclaration*);
+ m_ppMatchedDecls = (IFDE_CSSDeclaration**)FDE_Alloc(iBytes);
+ FX_memcpy(m_ppMatchedDecls, ppDeclArray, iBytes);
+}
+CXFA_TextParser::~CXFA_TextParser()
+{
+ if (m_pUASheet != NULL) {
+ m_pUASheet->Release();
+ }
+ if (m_pSelector != NULL) {
+ m_pSelector->Release();
+ }
+ if (m_pAllocator != NULL) {
+ m_pAllocator->Release();
+ }
+ FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
+ while (ps) {
+ IFDE_XMLNode *pXMLNode;
+ CXFA_TextParseContext *pParseContext;
+ m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
+ if (pParseContext != NULL) {
+ FDE_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
+ }
+ }
+ m_mapXMLNodeToParseContext.RemoveAll();
+}
+void CXFA_TextParser::Reset()
+{
+ FX_POSITION ps = m_mapXMLNodeToParseContext.GetStartPosition();
+ while (ps) {
+ IFDE_XMLNode *pXMLNode;
+ CXFA_TextParseContext *pParseContext;
+ m_mapXMLNodeToParseContext.GetNextAssoc(ps, pXMLNode, pParseContext);
+ if (pParseContext != NULL) {
+ FDE_DeleteWith(CXFA_TextParseContext, m_pAllocator, pParseContext);
+ }
+ }
+ m_mapXMLNodeToParseContext.RemoveAll();
+ if (m_pAllocator != NULL) {
+ m_pAllocator->Release();
+ m_pAllocator = NULL;
+ }
+}
+void CXFA_TextParser::InitCSSData(IXFA_TextProvider *pTextProvider)
+{
+ if (pTextProvider == NULL) {
+ return;
+ }
+ if (m_pSelector == NULL) {
+ CXFA_FFDoc *pDoc = pTextProvider->GetDocNode();
+ IFX_FontMgr *pFontMgr = pDoc->GetApp()->GetFDEFontMgr();
+ FXSYS_assert(pFontMgr != NULL);
+ m_pSelector = IFDE_CSSStyleSelector::Create();
+ m_pSelector->SetFontMgr(pFontMgr);
+ FX_FLOAT fFontSize = 10;
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font.IsExistInXML()) {
+ fFontSize = font.GetFontSize();
+ }
+ m_pSelector->SetDefFontSize(fFontSize);
+ }
+ if (m_pUASheet == NULL) {
+ m_pUASheet = LoadDefaultSheetStyle();
+ m_pSelector->SetStyleSheet(FDE_CSSSTYLESHEETGROUP_UserAgent, m_pUASheet);
+ m_pSelector->UpdateStyleIndex(FDE_CSSMEDIATYPE_ALL);
+ }
+}
+IFDE_CSSStyleSheet* CXFA_TextParser::LoadDefaultSheetStyle()
+{
+ static const FX_LPCWSTR s_pStyle = (FX_LPCWSTR)L"html,body,ol,p,ul{display:block}"
+ L"li{display:list-item}"
+ L"ol,ul{padding-left:33px}ol{list-style-type:decimal}ol,ul{margin-top:0;margin-bottom:0}ul,ol{margin:1.12em 0}"
+ L"a{color:#0000ff;text-decoration:underline}b{font-weight:bolder}i{font-style:italic}"
+ L"sup{vertical-align:+15em;font-size:.66em}sub{vertical-align:-15em;font-size:.66em}";
+ return IFDE_CSSStyleSheet::LoadFromBuffer(CFX_WideString(), s_pStyle, FXSYS_wcslen(s_pStyle), FX_CODEPAGE_UTF8);
+}
+IFDE_CSSComputedStyle* CXFA_TextParser::CreateRootStyle(IXFA_TextProvider *pTextProvider)
+{
+ CXFA_Font font = pTextProvider->GetFontNode();
+ CXFA_Para para = pTextProvider->GetParaNode();
+ IFDE_CSSComputedStyle *pStyle = m_pSelector->CreateComputedStyle(NULL);
+ IFDE_CSSFontStyle *pFontStyle = pStyle->GetFontStyles();
+ IFDE_CSSParagraphStyle *pParaStyle = pStyle->GetParagraphStyles();
+ FX_FLOAT fLineHeight = 0, fFontSize = 10;
+ if (para.IsExistInXML()) {
+ fLineHeight = para.GetLineHeight();
+ FDE_CSSLENGTH indent;
+ indent.Set(FDE_CSSLENGTHUNIT_Point, para.GetTextIndent());
+ pParaStyle->SetTextIndent(indent);
+ FDE_CSSTEXTALIGN hAlgin = FDE_CSSTEXTALIGN_Left;
+ switch (para.GetHorizontalAlign()) {
+ case XFA_ATTRIBUTEENUM_Center:
+ hAlgin = FDE_CSSTEXTALIGN_Center;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ hAlgin = FDE_CSSTEXTALIGN_Right;
+ break;
+ case XFA_ATTRIBUTEENUM_Justify:
+ hAlgin = FDE_CSSTEXTALIGN_Justify;
+ break;
+ case XFA_ATTRIBUTEENUM_JustifyAll:
+ hAlgin = FDE_CSSTEXTALIGN_JustifyAll;
+ break;
+ }
+ pParaStyle->SetTextAlign(hAlgin);
+ FDE_CSSRECT rtMarginWidth;
+ rtMarginWidth.left.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginLeft());
+ rtMarginWidth.top.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceAbove());
+ rtMarginWidth.right.Set(FDE_CSSLENGTHUNIT_Point, para.GetMarginRight());
+ rtMarginWidth.bottom.Set(FDE_CSSLENGTHUNIT_Point, para.GetSpaceBelow());
+ pStyle->GetBoundaryStyles()->SetMarginWidth(rtMarginWidth);
+ }
+ if (font.IsExistInXML()) {
+ pFontStyle->SetColor(font.GetColor());
+ pFontStyle->SetFontStyle(font.IsItalic() ? FDE_CSSFONTSTYLE_Italic : FDE_CSSFONTSTYLE_Normal);
+ pFontStyle->SetFontWeight(font.IsBold() ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
+ pParaStyle->SetNumberVerticalAlign(-font.GetBaselineShift());
+ fFontSize = font.GetFontSize();
+ FDE_CSSLENGTH letterSpacing;
+ letterSpacing.Set(FDE_CSSLENGTHUNIT_Point, font.GetLetterSpacing());
+ pParaStyle->SetLetterSpacing(letterSpacing);
+ FX_DWORD dwDecoration = 0;
+ if (font.GetLineThrough() > 0) {
+ dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
+ }
+ if (font.GetUnderline() > 1) {
+ dwDecoration |= FDE_CSSTEXTDECORATION_Double;
+ } else if (font.GetUnderline() > 0) {
+ dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
+ }
+ pParaStyle->SetTextDecoration(dwDecoration);
+ }
+ pParaStyle->SetLineHeight(fLineHeight);
+ pFontStyle->SetFontSize(fFontSize);
+ return pStyle;
+}
+IFDE_CSSComputedStyle* CXFA_TextParser::CreateStyle(IFDE_CSSComputedStyle *pParentStyle)
+{
+ IFDE_CSSComputedStyle *pNewStyle = m_pSelector->CreateComputedStyle(pParentStyle);
+ FXSYS_assert(pNewStyle != NULL);
+ if (pParentStyle) {
+ IFDE_CSSParagraphStyle *pParaStyle = pParentStyle->GetParagraphStyles();
+ FX_DWORD dwDecoration = pParaStyle->GetTextDecoration();
+ FX_FLOAT fBaseLine = 0;
+ if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
+ fBaseLine = pParaStyle->GetNumberVerticalAlign();
+ }
+ pParaStyle = pNewStyle->GetParagraphStyles();
+ pParaStyle->SetTextDecoration(dwDecoration);
+ pParaStyle->SetNumberVerticalAlign(fBaseLine);
+ IFDE_CSSBoundaryStyle *pBoundarytyle = pParentStyle->GetBoundaryStyles();
+ const FDE_CSSRECT *pRect = pBoundarytyle->GetMarginWidth();
+ if (pRect != NULL) {
+ pBoundarytyle = pNewStyle->GetBoundaryStyles();
+ pBoundarytyle->SetMarginWidth(*pRect);
+ }
+ }
+ return pNewStyle;
+}
+IFDE_CSSComputedStyle* CXFA_TextParser::ComputeStyle(IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle)
+{
+ CXFA_TextParseContext *pContext = (CXFA_TextParseContext*)m_mapXMLNodeToParseContext.GetValueAt(pXMLNode);
+ if (pContext == NULL) {
+ return NULL;
+ }
+ pContext->m_pParentStyle = pParentStyle;
+ CXFA_CSSTagProvider tagProvider;
+ ParseTagInfo(pXMLNode, tagProvider);
+ if (tagProvider.m_bContent) {
+ return NULL;
+ }
+ IFDE_CSSComputedStyle *pStyle = CreateStyle(pParentStyle);
+ IFDE_CSSAccelerator *pCSSAccel = m_pSelector->InitAccelerator();
+ pCSSAccel->OnEnterTag(&tagProvider);
+ m_pSelector->ComputeStyle(&tagProvider, pContext->GetDecls(), pContext->CountDecls(), pStyle);
+ pCSSAccel->OnLeaveTag(&tagProvider);
+ return pStyle;
+}
+void CXFA_TextParser::DoParse(IFDE_XMLNode *pXMLContainer, IXFA_TextProvider *pTextProvider)
+{
+ if (pXMLContainer == NULL || pTextProvider == NULL || m_pAllocator != NULL) {
+ return;
+ }
+ m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 32, sizeof(CXFA_CSSTagProvider));
+ InitCSSData(pTextProvider);
+ IFDE_CSSComputedStyle *pRootStyle = CreateRootStyle(pTextProvider);
+ ParseRichText(pXMLContainer, pRootStyle);
+ pRootStyle->Release();
+}
+void CXFA_TextParser::ParseRichText(IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle)
+{
+ if (pXMLNode == NULL) {
+ return;
+ }
+ CXFA_CSSTagProvider tagProvider;
+ ParseTagInfo(pXMLNode, tagProvider);
+ if (!tagProvider.m_bTagAviliable) {
+ return;
+ }
+ IFDE_CSSComputedStyle *pNewStyle = NULL;
+ if ((tagProvider.GetTagName() != FX_WSTRC(L"body")) || (tagProvider.GetTagName() != FX_WSTRC(L"html")) ) {
+ CXFA_TextParseContext *pTextContext = FDE_NewWith(m_pAllocator)CXFA_TextParseContext;
+ FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_Inline;
+ if (!tagProvider.m_bContent) {
+ pNewStyle = CreateStyle(pParentStyle);
+ IFDE_CSSAccelerator *pCSSAccel = m_pSelector->InitAccelerator();
+ pCSSAccel->OnEnterTag(&tagProvider);
+ CFDE_CSSDeclarationArray DeclArray;
+ FX_INT32 iMatchedDecls = m_pSelector->MatchDeclarations(&tagProvider, DeclArray);
+ const IFDE_CSSDeclaration **ppMatchDecls = (const IFDE_CSSDeclaration **)DeclArray.GetData();
+ m_pSelector->ComputeStyle(&tagProvider, ppMatchDecls, iMatchedDecls, pNewStyle);
+ pCSSAccel->OnLeaveTag(&tagProvider);
+ if (iMatchedDecls > 0) {
+ pTextContext->SetDecls(ppMatchDecls, iMatchedDecls);
+ }
+ eDisplay = pNewStyle->GetPositionStyles()->GetDisplay();
+ }
+ pTextContext->SetDisplay(eDisplay);
+ m_mapXMLNodeToParseContext.SetAt(pXMLNode, pTextContext);
+ }
+ for(IFDE_XMLNode *pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ ParseRichText(pXMLChild, pNewStyle);
+ }
+ if (pNewStyle != NULL) {
+ pNewStyle->Release();
+ }
+}
+void CXFA_TextParser::ParseTagInfo(IFDE_XMLNode *pXMLNode, CXFA_CSSTagProvider &tagProvider)
+{
+ static const FX_DWORD s_XFATagName[] = {
+ 0x61,
+ 0x62,
+ 0x69,
+ 0x70,
+ 0x0001f714,
+ 0x00022a55,
+ 0x000239bb,
+ 0x00025881,
+ 0x0bd37faa,
+ 0x0bd37fb8,
+ 0xa73e3af2,
+ 0xb182eaae,
+ 0xdb8ac455,
+ };
+ CFX_WideString wsName;
+ if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement *)pXMLNode;
+ pXMLElement->GetLocalTagName(wsName);
+ tagProvider.SetTagNameObj(wsName);
+ FX_DWORD dwHashCode = FX_HashCode_String_GetW(wsName, wsName.GetLength(), TRUE);
+ static const FX_INT32 s_iCount = sizeof(s_XFATagName) / sizeof(FX_DWORD);
+ CFX_DSPATemplate<FX_DWORD> lookup;
+ tagProvider.m_bTagAviliable = lookup.Lookup(dwHashCode, s_XFATagName, s_iCount) > -1;
+ CFX_WideString wsValue;
+ pXMLElement->GetString(FX_WSTRC(L"style").GetPtr(), wsValue);
+ if (!wsValue.IsEmpty()) {
+ tagProvider.SetAttribute(FX_WSTRC(L"style"), wsValue);
+ }
+ } else if (pXMLNode->GetType() == FDE_XMLNODE_Text) {
+ tagProvider.m_bTagAviliable = TRUE;
+ tagProvider.m_bContent = TRUE;
+ }
+}
+FX_INT32 CXFA_TextParser::GetVAlgin(IXFA_TextProvider *pTextProvider) const
+{
+ FX_INT32 iAlign = XFA_ATTRIBUTEENUM_Top;
+ CXFA_Para para = pTextProvider->GetParaNode();
+ if (para.IsExistInXML()) {
+ iAlign = para.GetVerticalAlign();
+ }
+ return iAlign;
+}
+FX_FLOAT CXFA_TextParser::GetTabInterval(IFDE_CSSComputedStyle *pStyle) const
+{
+ CFX_WideString wsValue;
+ if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"tab-interval"), wsValue)) {
+ CXFA_Measurement ms(wsValue);
+ return ms.ToUnit(XFA_UNIT_Pt);
+ }
+ return 36;
+}
+FX_INT32 CXFA_TextParser::CountTabs(IFDE_CSSComputedStyle *pStyle) const
+{
+ CFX_WideString wsValue;
+ if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-count"), wsValue)) {
+ return wsValue.GetInteger();
+ }
+ return 0;
+}
+FX_BOOL CXFA_TextParser::IsSpaceRun(IFDE_CSSComputedStyle *pStyle) const
+{
+ CFX_WideString wsValue;
+ if (pStyle && pStyle->GetCustomStyle(FX_WSTRC(L"xfa-spacerun"), wsValue)) {
+ wsValue.MakeLower();
+ return wsValue == FX_WSTRC(L"yes");
+ }
+ return FALSE;
+}
+IFX_Font* CXFA_TextParser::GetFont(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const
+{
+ CFX_WideStringC wsFamily = FX_WSTRC(L"Courier");
+ FX_DWORD dwStyle = 0;
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font.IsExistInXML()) {
+ font.GetTypeface(wsFamily);
+ if (font.IsBold()) {
+ dwStyle |= FX_FONTSTYLE_Bold;
+ }
+ if (font.IsItalic()) {
+ dwStyle |= FX_FONTSTYLE_Italic;
+ }
+ }
+ if (pStyle) {
+ IFDE_CSSFontStyle *pFontStyle = pStyle->GetFontStyles();
+ FX_INT32 iCount = pFontStyle->CountFontFamilies();
+ if (iCount > 0) {
+ wsFamily = pFontStyle->GetFontFamily(iCount - 1);
+ }
+ dwStyle = 0;
+ if (pFontStyle->GetFontWeight() > FXFONT_FW_NORMAL) {
+ dwStyle |= FX_FONTSTYLE_Bold;
+ }
+ if (pFontStyle->GetFontStyle() == FDE_CSSFONTSTYLE_Italic) {
+ dwStyle |= FX_FONTSTYLE_Italic;
+ }
+ }
+ CXFA_FFDoc *pDoc = pTextProvider->GetDocNode();
+ FXSYS_assert(pDoc != NULL);
+ CXFA_FontMgr *pFontMgr = pDoc->GetApp()->GetXFAFontMgr();
+ return pFontMgr->GetFont((XFA_HDOC)pDoc, wsFamily, dwStyle);
+}
+FX_FLOAT CXFA_TextParser::GetFontSize(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const
+{
+ if (pStyle != NULL) {
+ return pStyle->GetFontStyles()->GetFontSize();
+ }
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font.IsExistInXML()) {
+ return font.GetFontSize();
+ }
+ return 10;
+}
+FX_INT32 CXFA_TextParser::GetHorScale(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, IFDE_XMLNode *pXMLNode) const
+{
+ if (pStyle != NULL) {
+ CFX_WideString wsValue;
+ if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-horizontal-scale"), wsValue)) {
+ return wsValue.GetInteger();
+ }
+ while (pXMLNode) {
+ CXFA_TextParseContext *pContext = (CXFA_TextParseContext*)m_mapXMLNodeToParseContext.GetValueAt(pXMLNode);
+ if (pContext && pContext->m_pParentStyle && pContext->m_pParentStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-horizontal-scale"), wsValue)) {
+ return wsValue.GetInteger();
+ }
+ pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+ }
+ }
+ if (CXFA_Font font = pTextProvider->GetFontNode()) {
+ return (FX_INT32)font.GetHorizontalScale();
+ }
+ return 100;
+}
+FX_INT32 CXFA_TextParser::GetVerScale(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const
+{
+ if (pStyle != NULL) {
+ CFX_WideString wsValue;
+ if (pStyle->GetCustomStyle(FX_WSTRC(L"xfa-font-vertical-scale"), wsValue)) {
+ return wsValue.GetInteger();
+ }
+ }
+ if (CXFA_Font font = pTextProvider->GetFontNode()) {
+ return (FX_INT32)font.GetVerticalScale();
+ }
+ return 100;
+}
+void CXFA_TextParser::GetUnderline(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_INT32 &iUnderline, FX_INT32 &iPeriod) const
+{
+ iUnderline = 0;
+ iPeriod = XFA_ATTRIBUTEENUM_All;
+ if (pStyle) {
+ FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
+ if (dwDecoration & FDE_CSSTEXTDECORATION_Double) {
+ iUnderline = 2;
+ } else if (dwDecoration & FDE_CSSTEXTDECORATION_Underline) {
+ iUnderline = 1;
+ }
+ CFX_WideString wsValue;
+ if (pStyle->GetCustomStyle(FX_WSTRC(L"underlinePeriod"), wsValue)) {
+ if (wsValue == FX_WSTRC(L"word")) {
+ iPeriod = XFA_ATTRIBUTEENUM_Word;
+ }
+ } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
+ iPeriod = font.GetUnderlinePeriod();
+ }
+ } else {
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font.IsExistInXML()) {
+ iUnderline = font.GetUnderline();
+ iPeriod = font.GetUnderlinePeriod();
+ }
+ }
+}
+void CXFA_TextParser::GetLinethrough(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_INT32 &iLinethrough) const
+{
+ if (pStyle) {
+ FX_DWORD dwDecoration = pStyle->GetParagraphStyles()->GetTextDecoration();
+ iLinethrough = (dwDecoration & FDE_CSSTEXTDECORATION_LineThrough) ? 1 : 0;
+ } else {
+ CXFA_Font font = pTextProvider->GetFontNode();
+ if (font.IsExistInXML()) {
+ iLinethrough = font.GetLineThrough();
+ }
+ }
+}
+FX_ARGB CXFA_TextParser::GetColor(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const
+{
+ if (pStyle != NULL) {
+ return pStyle->GetFontStyles()->GetColor();
+ }
+ if (CXFA_Font font = pTextProvider->GetFontNode()) {
+ return font.GetColor();
+ }
+ return 0xFF000000;
+}
+FX_FLOAT CXFA_TextParser::GetBaseline(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const
+{
+ if (pStyle != NULL) {
+ IFDE_CSSParagraphStyle *pParaStyle = pStyle->GetParagraphStyles();
+ if (pParaStyle->GetVerticalAlign() == FDE_CSSVERTICALALIGN_Number) {
+ return pParaStyle->GetNumberVerticalAlign();
+ }
+ } else if (CXFA_Font font = pTextProvider->GetFontNode()) {
+ return font.GetBaselineShift();
+ }
+ return 0;
+}
+FX_FLOAT CXFA_TextParser::GetLineHeight(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_BOOL bFirst, FX_FLOAT fVerScale) const
+{
+ FX_FLOAT fLineHeight = 0;
+ if (pStyle != NULL) {
+ fLineHeight = pStyle->GetParagraphStyles()->GetLineHeight();
+ } else if (CXFA_Para para = pTextProvider->GetParaNode()) {
+ fLineHeight = para.GetLineHeight();
+ }
+ if (bFirst) {
+ FX_FLOAT fFontSize = GetFontSize(pTextProvider, pStyle);
+ if (fLineHeight < 0.1f) {
+ fLineHeight = fFontSize;
+ } else {
+ fLineHeight = FX_MIN(fLineHeight, fFontSize);
+ }
+ } else if (fLineHeight < 0.1f) {
+ fLineHeight = GetFontSize(pTextProvider, pStyle) * 1.2f;
+ }
+ fLineHeight *= fVerScale;
+ return fLineHeight;
+}
+FX_BOOL CXFA_TextParser::GetEmbbedObj(IXFA_TextProvider *pTextProvider, IFDE_XMLNode *pXMLNode, CFX_WideString &wsValue)
+{
+ wsValue.Empty();
+ if (pXMLNode == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = FALSE;
+ if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement* pElement = (IFDE_XMLElement *)pXMLNode;
+ CFX_WideString wsAttr;
+ pElement->GetString(FX_WSTRC(L"xfa:embed").GetPtr(), wsAttr);
+ if (wsAttr.IsEmpty()) {
+ return FALSE;
+ }
+ if (wsAttr.GetAt(0) == FX_WSTRC(L"#")) {
+ wsAttr.Delete(0);
+ }
+ CFX_WideString ws;
+ pElement->GetString(FX_WSTRC(L"xfa:embedType").GetPtr(), ws);
+ if (ws.IsEmpty()) {
+ ws = L"som";
+ } else {
+ ws.MakeLower();
+ }
+ FX_BOOL bURI = (ws == FX_WSTRC(L"uri"));
+ if (!bURI && ws != FX_WSTRC(L"som")) {
+ return FALSE;
+ }
+ ws.Empty();
+ pElement->GetString(FX_WSTRC(L"xfa:embedMode").GetPtr(), ws);
+ if (ws.IsEmpty()) {
+ ws = L"formatted";
+ } else {
+ ws.MakeLower();
+ }
+ FX_BOOL bRaw = (ws == FX_WSTRC(L"raw"));
+ if (!bRaw && ws != FX_WSTRC(L"formatted")) {
+ return FALSE;
+ }
+ bRet = pTextProvider->GetEmbbedObj(bURI, bRaw, wsAttr, wsValue);
+ }
+ return bRet;
+}
+CXFA_TextParseContext* CXFA_TextParser::GetParseContextFromMap(IFDE_XMLNode *pXMLNode)
+{
+ return (CXFA_TextParseContext*)m_mapXMLNodeToParseContext.GetValueAt(pXMLNode);
+}
+enum XFA_TABSTOPSSTATUS {
+ XFA_TABSTOPSSTATUS_Error,
+ XFA_TABSTOPSSTATUS_EOS,
+ XFA_TABSTOPSSTATUS_None,
+ XFA_TABSTOPSSTATUS_Alignment,
+ XFA_TABSTOPSSTATUS_StartLeader,
+ XFA_TABSTOPSSTATUS_Leader,
+ XFA_TABSTOPSSTATUS_Location,
+};
+FX_BOOL CXFA_TextParser::GetTabstops(IFDE_CSSComputedStyle *pStyle, CXFA_TextTabstopsContext *pTabstopContext)
+{
+ if (pStyle == NULL || pTabstopContext == NULL) {
+ return FALSE;
+ }
+ CFX_WideString wsValue;
+ if (!pStyle->GetCustomStyle(FX_WSTRC(L"xfa-tab-stops"), wsValue)
+ && !pStyle->GetCustomStyle(FX_WSTRC(L"tab-stops"), wsValue)) {
+ return FALSE;
+ }
+ FX_INT32 iLength = wsValue.GetLength();
+ FX_LPCWSTR pTabStops = wsValue;
+ FX_INT32 iCur = 0;
+ FX_INT32 iLast = 0;
+ CFX_WideString wsAlign;
+ XFA_TABSTOPSSTATUS eStatus = XFA_TABSTOPSSTATUS_None;
+ FX_WCHAR ch;
+ while (iCur < iLength) {
+ ch = pTabStops[iCur];
+ switch (eStatus) {
+ case XFA_TABSTOPSSTATUS_None:
+ if (ch <= ' ') {
+ iCur++;
+ } else {
+ eStatus = XFA_TABSTOPSSTATUS_Alignment;
+ iLast = iCur;
+ }
+ break;
+ case XFA_TABSTOPSSTATUS_Alignment:
+ if (ch == ' ') {
+ wsAlign = CFX_WideStringC(pTabStops + iLast, iCur - iLast);
+ eStatus = XFA_TABSTOPSSTATUS_StartLeader;
+ iCur++;
+ while (iCur < iLength && pTabStops[iCur] <= ' ') {
+ iCur++;
+ }
+ iLast = iCur;
+ } else {
+ iCur++;
+ }
+ break;
+ case XFA_TABSTOPSSTATUS_StartLeader:
+ if (ch != 'l') {
+ eStatus = XFA_TABSTOPSSTATUS_Location;
+ } else {
+ FX_INT32 iCount = 0;
+ while (iCur < iLength) {
+ ch = pTabStops[iCur];
+ iCur++;
+ if (ch == '(') {
+ iCount++;
+ } else if (ch == ')') {
+ iCount--;
+ if (iCount == 0) {
+ break;
+ }
+ }
+ }
+ while (iCur < iLength && pTabStops[iCur] <= ' ') {
+ iCur++;
+ }
+ iLast = iCur;
+ eStatus = XFA_TABSTOPSSTATUS_Location;
+ }
+ break;
+ case XFA_TABSTOPSSTATUS_Location:
+ if (ch == ' ') {
+ FX_DWORD dwHashCode = FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE);
+ CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
+ FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
+ pTabstopContext->Append(dwHashCode, fPos);
+ wsAlign.Empty();
+ eStatus = XFA_TABSTOPSSTATUS_None;
+ }
+ iCur++;
+ break;
+ default:
+ break;
+ }
+ }
+ if (!wsAlign.IsEmpty()) {
+ FX_DWORD dwHashCode = FX_HashCode_String_GetW(wsAlign, wsAlign.GetLength(), TRUE);
+ CXFA_Measurement ms(CFX_WideStringC(pTabStops + iLast, iCur - iLast));
+ FX_FLOAT fPos = ms.ToUnit(XFA_UNIT_Pt);
+ pTabstopContext->Append(dwHashCode, fPos);
+ }
+ return TRUE;
+}
+CXFA_TextLayout::CXFA_TextLayout(IXFA_TextProvider *pTextProvider)
+ : m_pTextProvider(pTextProvider)
+ , m_pTextDataNode(NULL)
+ , m_pAllocator(NULL)
+ , m_pBreak(NULL)
+ , m_dwTextData(0)
+ , m_pLoader(NULL)
+ , m_iLines(0)
+ , m_fMaxWidth(0)
+ , m_pTabstopContext(NULL)
+ , m_bBlockContinue(TRUE)
+ , m_bRichText(FALSE)
+ , m_bHasBlock(FALSE)
+{
+ FXSYS_assert(m_pTextProvider != NULL);
+}
+CXFA_TextLayout::~CXFA_TextLayout()
+{
+ m_textParser.Reset();
+ if (m_pLoader != NULL) {
+ delete m_pLoader;
+ }
+ if (m_pTabstopContext != NULL) {
+ delete m_pTabstopContext;
+ }
+ Unload();
+}
+void CXFA_TextLayout::Unload()
+{
+ FX_INT32 iCount = m_pieceLines.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXFA_PieceLine *pLine = m_pieceLines.GetAt(i);
+ FDE_DeleteWith(CXFA_PieceLine, m_pAllocator, pLine);
+ }
+ m_pieceLines.RemoveAll();
+ if (m_pBreak != NULL) {
+ m_pBreak->Release();
+ m_pBreak = NULL;
+ }
+ if (m_pAllocator != NULL) {
+ m_pAllocator->Release();
+ m_pAllocator = NULL;
+ }
+}
+const CXFA_PieceLineArray* CXFA_TextLayout::GetPieceLines()
+{
+ return &m_pieceLines;
+}
+void CXFA_TextLayout::GetTextDataNode()
+{
+ if (m_pTextProvider == NULL) {
+ return;
+ }
+ CXFA_Node *pNode = m_pTextProvider->GetTextNode(m_bRichText);
+ if (pNode && m_bRichText) {
+ m_textParser.Reset();
+ }
+ m_pTextDataNode = pNode;
+}
+IFDE_XMLNode* CXFA_TextLayout::GetXMLContainerNode()
+{
+ IFDE_XMLNode* pXMLContainer = NULL;
+ if (m_bRichText) {
+ IFDE_XMLNode *pXMLRoot = m_pTextDataNode->GetXMLMappingNode();
+ if (!pXMLRoot) {
+ return pXMLContainer;
+ }
+ for (IFDE_XMLNode *pXMLChild = pXMLRoot->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if (pXMLChild->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement*)pXMLChild;
+ CFX_WideString wsTag;
+ pXMLElement->GetLocalTagName(wsTag);
+ if (wsTag.Equal(FX_WSTRC(L"body")) || wsTag.Equal(FX_WSTRC(L"html"))) {
+ pXMLContainer = pXMLChild;
+ break;
+ }
+ }
+ }
+ }
+ return pXMLContainer;
+}
+IFX_RTFBreak* CXFA_TextLayout::CreateBreak(FX_BOOL bDefault)
+{
+ FX_DWORD dwStyle = FX_RTFLAYOUTSTYLE_ExpandTab;
+ if (!bDefault) {
+ dwStyle |= FX_RTFLAYOUTSTYLE_Pagination;
+ }
+ IFX_RTFBreak *pBreak = IFX_RTFBreak::Create(0);
+ pBreak->SetLayoutStyles(dwStyle);
+ pBreak->SetLineBreakChar(L'\n');
+ pBreak->SetLineBreakTolerance(1);
+ pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
+ pBreak->SetFontSize(m_textParser.GetFontSize(m_pTextProvider, NULL));
+ return pBreak;
+}
+void CXFA_TextLayout::InitBreak(FX_FLOAT fLineWidth)
+{
+ CXFA_Font font = m_pTextProvider->GetFontNode();
+ CXFA_Para para = m_pTextProvider->GetParaNode();
+ FX_FLOAT fStart = 0;
+ FX_FLOAT fStartPos = 0;
+ if (para.IsExistInXML()) {
+ FX_INT32 iAlign = FX_RTFLINEALIGNMENT_Left;
+ switch (para.GetHorizontalAlign()) {
+ case XFA_ATTRIBUTEENUM_Center:
+ iAlign = FX_RTFLINEALIGNMENT_Center;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ iAlign = FX_RTFLINEALIGNMENT_Right;
+ break;
+ case XFA_ATTRIBUTEENUM_Justify:
+ iAlign = FX_RTFLINEALIGNMENT_Justified;
+ break;
+ case XFA_ATTRIBUTEENUM_JustifyAll:
+ iAlign = FX_RTFLINEALIGNMENT_Distributed;
+ break;
+ }
+ m_pBreak->SetAlignment(iAlign);
+ fStart = para.GetMarginLeft();
+ if (m_pTextProvider->IsCheckButtonAndAutoWidth()) {
+ if (iAlign != FX_RTFLINEALIGNMENT_Left) {
+ fLineWidth -= para.GetMarginRight();
+ }
+ } else {
+ fLineWidth -= para.GetMarginRight();
+ }
+ if (fLineWidth < 0) {
+ fLineWidth = fStart;
+ }
+ fStartPos = fStart;
+ FX_FLOAT fIndent = para.GetTextIndent();
+ if (fIndent > 0) {
+ fStartPos += fIndent;
+ }
+ }
+ m_pBreak->SetLineWidth(fStart, fLineWidth);
+ m_pBreak->SetLinePos(fStartPos);
+ if (font.IsExistInXML()) {
+ m_pBreak->SetHorizontalScale((FX_INT32)font.GetHorizontalScale());
+ m_pBreak->SetVerticalScale((FX_INT32)font.GetVerticalScale());
+ m_pBreak->SetCharSpace(font.GetLetterSpacing());
+ }
+ FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, NULL);
+ m_pBreak->SetFontSize(fFontSize);
+ m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, NULL));
+ m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
+}
+void CXFA_TextLayout::InitBreak(IFDE_CSSComputedStyle *pStyle, FDE_CSSDISPLAY eDisplay, FX_FLOAT fLineWidth, IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle)
+{
+ if (pStyle == NULL) {
+ InitBreak(fLineWidth);
+ return;
+ }
+ IFDE_CSSParagraphStyle *pParaStyle = pStyle->GetParagraphStyles();
+ if (eDisplay == FDE_CSSDISPLAY_Block || eDisplay == FDE_CSSDISPLAY_ListItem) {
+ FX_INT32 iAlign = FX_RTFLINEALIGNMENT_Left;
+ switch (pParaStyle->GetTextAlign()) {
+ case FDE_CSSTEXTALIGN_Right:
+ iAlign = FX_RTFLINEALIGNMENT_Right;
+ break;
+ case FDE_CSSTEXTALIGN_Center:
+ iAlign = FX_RTFLINEALIGNMENT_Center;
+ break;
+ case FDE_CSSTEXTALIGN_Justify:
+ iAlign = FX_RTFLINEALIGNMENT_Justified;
+ break;
+ case FDE_CSSTEXTALIGN_JustifyAll:
+ iAlign = FX_RTFLINEALIGNMENT_Distributed;
+ break;
+ default:
+ break;
+ }
+ m_pBreak->SetAlignment(iAlign);
+ FX_FLOAT fStart = 0;
+ const FDE_CSSRECT *pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
+ const FDE_CSSRECT *pPaddingRect = pStyle->GetBoundaryStyles()->GetPaddingWidth();
+ if (pRect != NULL) {
+ fStart = pRect->left.GetValue();
+ fLineWidth -= pRect->right.GetValue();
+ if (pPaddingRect != NULL) {
+ fStart += pPaddingRect->left.GetValue();
+ fLineWidth -= pPaddingRect->right.GetValue();
+ }
+ if (eDisplay == FDE_CSSDISPLAY_ListItem) {
+ const FDE_CSSRECT *pParRect = pParentStyle->GetBoundaryStyles()->GetMarginWidth();
+ const FDE_CSSRECT *pParPaddingRect = pParentStyle->GetBoundaryStyles()->GetPaddingWidth();
+ if (pParRect != NULL) {
+ fStart += pParRect->left.GetValue();
+ fLineWidth -= pParRect->right.GetValue();
+ if (pParPaddingRect != NULL) {
+ fStart += pParPaddingRect->left.GetValue();
+ fLineWidth -= pParPaddingRect->right.GetValue();
+ }
+ }
+ FDE_CSSRECT pNewRect;
+ pNewRect.left.Set(FDE_CSSLENGTHUNIT_Point, fStart);
+ pNewRect.right.Set(FDE_CSSLENGTHUNIT_Point, pRect->right.GetValue());
+ pNewRect.top.Set(FDE_CSSLENGTHUNIT_Point, pRect->top.GetValue());
+ pNewRect.bottom.Set(FDE_CSSLENGTHUNIT_Point, pRect->bottom.GetValue());
+ pStyle->GetBoundaryStyles()->SetMarginWidth(pNewRect);
+ }
+ }
+ m_pBreak->SetLineWidth(fStart, fLineWidth);
+ FX_FLOAT fIndent = pParaStyle->GetTextIndent().GetValue();
+ if (fIndent > 0) {
+ fStart += fIndent;
+ }
+ m_pBreak->SetLinePos(fStart);
+ m_pBreak->SetTabWidth(m_textParser.GetTabInterval(pStyle));
+ if (m_pTabstopContext == NULL) {
+ m_pTabstopContext = FX_NEW CXFA_TextTabstopsContext;
+ }
+ m_textParser.GetTabstops(pStyle, m_pTabstopContext);
+ for (FX_INT32 i = 0; i < m_pTabstopContext->m_iTabCount; i++) {
+ XFA_TABSTOPS *pTab = m_pTabstopContext->m_tabstops.GetDataPtr(i);
+ m_pBreak->AddPositionedTab(pTab->fTabstops);
+ }
+ }
+ FX_FLOAT fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
+ m_pBreak->SetFontSize(fFontSize);
+ m_pBreak->SetLineBreakTolerance(fFontSize * 0.2f);
+ m_pBreak->SetFont(m_textParser.GetFont(m_pTextProvider, pStyle));
+ m_pBreak->SetHorizontalScale(m_textParser.GetHorScale(m_pTextProvider, pStyle, pXMLNode));
+ m_pBreak->SetVerticalScale(m_textParser.GetVerScale(m_pTextProvider, pStyle));
+ m_pBreak->SetCharSpace(pParaStyle->GetLetterSpacing().GetValue());
+}
+FX_INT32 CXFA_TextLayout::GetText(CFX_WideString &wsText)
+{
+ GetTextDataNode();
+ wsText.Empty();
+ if (m_bRichText) {
+ } else {
+ wsText = m_pTextDataNode->GetContent();
+ }
+ return wsText.GetLength();
+}
+FX_FLOAT CXFA_TextLayout::GetLayoutHeight()
+{
+ if (m_pLoader == NULL) {
+ return 0;
+ }
+ FX_INT32 iCount = m_pLoader->m_lineHeights.GetSize();
+ if (iCount == 0 && m_pLoader->m_fWidth > 0) {
+ CFX_SizeF szMax, szDef;
+ szMax.Set(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
+ szDef.Set(0, 0);
+ m_pLoader->m_bSaveLineHeight = TRUE;
+ m_pLoader->m_fLastPos = 0;
+ CalcSize(szMax, szMax, szDef);
+ m_pLoader->m_bSaveLineHeight = FALSE;
+ return szDef.y;
+ }
+ FX_FLOAT fHeight = m_pLoader->m_fHeight;
+ if (fHeight < 0.1f) {
+ fHeight = 0;
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ fHeight += m_pLoader->m_lineHeights.ElementAt(i);
+ }
+ }
+ return fHeight;
+}
+FX_FLOAT CXFA_TextLayout::StartLayout(FX_FLOAT fWidth )
+{
+ if (m_pLoader == NULL) {
+ m_pLoader = FX_NEW CXFA_LoaderContext;
+ }
+ if (fWidth < 0 || (m_pLoader->m_fWidth > -1 && FXSYS_fabs(fWidth - m_pLoader->m_fWidth) > 0)) {
+ m_pLoader->m_lineHeights.RemoveAll();
+ m_Blocks.RemoveAll();
+ Unload();
+ m_pLoader->m_fStartLineOffset = 0;
+ }
+ m_pLoader->m_fWidth = fWidth;
+ if (fWidth < 0) {
+ CFX_SizeF szMax, szDef;
+ szMax.Set(0, 0);
+ szDef.Set(0, 0);
+ m_pLoader->m_bSaveLineHeight = TRUE;
+ m_pLoader->m_fLastPos = 0;
+ CalcSize(szMax, szMax, szDef);
+ m_pLoader->m_bSaveLineHeight = FALSE;
+ fWidth = szDef.x;
+ }
+ return fWidth;
+}
+FX_BOOL CXFA_TextLayout::DoLayout(FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeight, FX_FLOAT fContentAreaHeight , FX_FLOAT fTextHeight )
+{
+ if (m_pLoader == NULL) {
+ return FALSE;
+ }
+ FX_INT32 iBlockCount = m_Blocks.GetSize();
+ FX_FLOAT fHeight = fTextHeight;
+ if (fHeight < 0) {
+ fHeight = GetLayoutHeight();
+ }
+ m_pLoader->m_fHeight = fHeight;
+ if (fContentAreaHeight < 0) {
+ return FALSE;
+ }
+ m_bHasBlock = TRUE;
+ if (iBlockCount == 0 && fHeight > 0) {
+ fHeight = fTextHeight - GetLayoutHeight();
+ if (fHeight > 0) {
+ FX_INT32 iAlign = m_textParser.GetVAlgin(m_pTextProvider);
+ if (iAlign == XFA_ATTRIBUTEENUM_Middle) {
+ fHeight /= 2.0f;
+ } else if (iAlign != XFA_ATTRIBUTEENUM_Bottom) {
+ fHeight = 0;
+ }
+ m_pLoader->m_fStartLineOffset = fHeight;
+ }
+ }
+ FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
+ FX_INT32 iLineIndex = 0;
+ if (iBlockCount > 1) {
+ if (iBlockCount >= (iBlockIndex + 1) * 2) {
+ iLineIndex = m_Blocks.ElementAt(iBlockIndex * 2);
+ } else {
+ iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) + m_Blocks.ElementAt(iBlockCount - 2);
+ }
+ if (m_pLoader->m_BlocksHeight.GetSize() > 0) {
+ for (FX_INT32 i = 0; i < iBlockIndex; i++) {
+ fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
+ }
+ }
+ }
+ FX_INT32 iCount = m_pLoader->m_lineHeights.GetSize();
+ FX_INT32 i = 0;
+ for (i = iLineIndex; i < iCount; i++) {
+ FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
+ if ((i == iLineIndex) && (fLineHeight - fContentAreaHeight > 0.001)) {
+ fCalcHeight = 0;
+ return TRUE;
+ }
+ if (fLinePos + fLineHeight - fContentAreaHeight > 0.001) {
+ if (iBlockCount >= (iBlockIndex + 1) * 2) {
+ m_Blocks.SetAt(iBlockIndex * 2, iLineIndex);
+ m_Blocks.SetAt(iBlockIndex * 2 + 1, i - iLineIndex);
+ } else {
+ m_Blocks.Add(iLineIndex);
+ m_Blocks.Add(i - iLineIndex);
+ }
+ if (i == iLineIndex) {
+ if (fCalcHeight <= fLinePos) {
+ if (m_pLoader->m_BlocksHeight.GetSize() > iBlockIndex * 2 && (m_pLoader->m_BlocksHeight.GetAt(iBlockIndex * 2) == iBlockIndex)) {
+ m_pLoader->m_BlocksHeight.SetAt(iBlockIndex * 2 + 1, fCalcHeight);
+ } else {
+ m_pLoader->m_BlocksHeight.Add((FX_FLOAT)iBlockIndex);
+ m_pLoader->m_BlocksHeight.Add(fCalcHeight);
+ }
+ }
+ return TRUE;
+ }
+ fCalcHeight = fLinePos;
+ return TRUE;
+ }
+ fLinePos += fLineHeight;
+ }
+ return FALSE;
+}
+FX_INT32 CXFA_TextLayout::CountBlocks() const
+{
+ FX_INT32 iCount = m_Blocks.GetSize() / 2;
+ return iCount > 0 ? iCount : 1;
+}
+FX_BOOL CXFA_TextLayout::CalcSize(const CFX_SizeF &minSize, const CFX_SizeF &maxSize, CFX_SizeF &defaultSize)
+{
+ defaultSize.x = maxSize.x;
+ if (defaultSize.x < 1) {
+ defaultSize.x = 0xFFFF;
+ }
+ if (m_pBreak != NULL) {
+ m_pBreak->Release();
+ }
+ m_pBreak = CreateBreak(FALSE);
+ FX_FLOAT fLinePos = 0;
+ m_iLines = 0;
+ m_fMaxWidth = 0;
+ Loader(defaultSize, fLinePos, FALSE);
+ if (fLinePos < 0.1f) {
+ fLinePos = m_textParser.GetFontSize(m_pTextProvider, NULL);
+ }
+ if (m_pTabstopContext) {
+ delete m_pTabstopContext;
+ m_pTabstopContext = NULL;
+ }
+ defaultSize.Set(m_fMaxWidth, fLinePos);
+ return TRUE;
+}
+FX_BOOL CXFA_TextLayout::Layout(const CFX_SizeF &size, FX_FLOAT* fHeight)
+{
+ if (size.x < 1) {
+ return FALSE;
+ }
+ Unload();
+ m_pBreak = CreateBreak(TRUE);
+ if (m_pLoader != NULL) {
+ m_pLoader->m_iTotalLines = -1;
+ m_pLoader->m_iChar = 0;
+ }
+ m_iLines = 0;
+ FX_FLOAT fLinePos = 0;
+ Loader(size, fLinePos, TRUE);
+ UpdateAlign(size.y, fLinePos);
+ if (m_pTabstopContext) {
+ delete m_pTabstopContext;
+ m_pTabstopContext = NULL;
+ }
+ if (fHeight) {
+ *fHeight = fLinePos;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_TextLayout::Layout(FX_INT32 iBlock)
+{
+ if (m_pLoader == NULL || iBlock < 0 || iBlock >= CountBlocks()) {
+ return FALSE;
+ }
+ if (m_pLoader->m_fWidth < 1) {
+ return FALSE;
+ }
+ m_pLoader->m_iTotalLines = -1;
+ m_iLines = 0;
+ FX_FLOAT fLinePos = 0;
+ CXFA_Node *pNode = NULL;
+ CFX_SizeF szText;
+ szText.Set(m_pLoader->m_fWidth, m_pLoader->m_fHeight);
+ FX_INT32 iCount = m_Blocks.GetSize();
+ FX_INT32 iBlocksHeightCount = m_pLoader->m_BlocksHeight.GetSize();
+ iBlocksHeightCount /= 2;
+ if (iBlock < iBlocksHeightCount) {
+ return TRUE;
+ }
+ if (iBlock == iBlocksHeightCount) {
+ Unload();
+ m_pBreak = CreateBreak(TRUE);
+ fLinePos = m_pLoader->m_fStartLineOffset;
+ for (FX_INT32 i = 0; i < iBlocksHeightCount; i++) {
+ fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
+ }
+ m_pLoader->m_iChar = 0;
+ if (iCount > 1) {
+ m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock * 2 + 1);
+ }
+ Loader(szText, fLinePos, TRUE);
+ if (iCount == 0 && m_pLoader->m_fStartLineOffset < 0.1f) {
+ UpdateAlign(szText.y, fLinePos);
+ }
+ } else if (m_pTextDataNode != NULL) {
+ iBlock *= 2;
+ if (iBlock < iCount - 2) {
+ m_pLoader->m_iTotalLines = m_Blocks.ElementAt(iBlock + 1);
+ }
+ m_pBreak->Reset();
+ if (m_bRichText) {
+ IFDE_XMLNode* pContainerNode = GetXMLContainerNode();
+ if (!pContainerNode) {
+ return TRUE;
+ }
+ IFDE_XMLNode *pXMLNode = m_pLoader->m_pXMLNode;
+ if (pXMLNode == NULL) {
+ return TRUE;
+ }
+ IFDE_XMLNode* pSaveXMLNode = m_pLoader->m_pXMLNode;
+ for (; pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle, TRUE);
+ if (!bFlag) {
+ break;
+ }
+ }
+ while (pXMLNode == NULL) {
+ pXMLNode = pSaveXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+ if (pXMLNode == pContainerNode) {
+ break;
+ }
+ FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle, TRUE, NULL , FALSE);
+ if (!bFlag) {
+ break;
+ }
+ pSaveXMLNode = pXMLNode;
+ pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
+ if (!pXMLNode) {
+ continue;
+ }
+ for (; pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ FX_BOOL bFlag = LoadRichText(pXMLNode, szText, fLinePos, m_pLoader->m_pParentStyle, TRUE);
+ if (!bFlag) {
+ break;
+ }
+ }
+ }
+ } else {
+ pNode = m_pLoader->m_pNode;
+ if (pNode == NULL) {
+ return TRUE;
+ }
+ LoadText(pNode, szText, fLinePos, TRUE);
+ }
+ }
+ if (iBlock == iCount) {
+ if (m_pTabstopContext != NULL) {
+ delete m_pTabstopContext;
+ m_pTabstopContext = NULL;
+ }
+ if (m_pLoader != NULL) {
+ delete m_pLoader;
+ m_pLoader = NULL;
+ }
+ }
+ return TRUE;
+}
+void CXFA_TextLayout::ItemBlocks(const CFX_RectF& rtText, FX_INT32 iBlockIndex)
+{
+ if (!m_pLoader) {
+ return;
+ }
+ FX_INT32 iCountHeight = m_pLoader->m_lineHeights.GetSize();
+ if (iCountHeight == 0) {
+ return;
+ }
+ FX_BOOL bEndItem = TRUE;
+ FX_INT32 iBlockCount = m_Blocks.GetSize();
+ FX_FLOAT fLinePos = m_pLoader->m_fStartLineOffset;
+ FX_INT32 iLineIndex = 0;
+ if (iBlockIndex > 0) {
+ FX_INT32 iBlockHeightCount = m_pLoader->m_BlocksHeight.GetSize();
+ iBlockHeightCount /= 2;
+ if (iBlockHeightCount >= iBlockIndex) {
+ for (FX_INT32 i = 0; i < iBlockIndex; i++) {
+ fLinePos -= m_pLoader->m_BlocksHeight.ElementAt(i * 2 + 1);
+ }
+ } else {
+ fLinePos = 0;
+ }
+ iLineIndex = m_Blocks.ElementAt(iBlockCount - 1) + m_Blocks.ElementAt(iBlockCount - 2);
+ }
+ FX_INT32 i = 0;
+ for (i = iLineIndex; i < iCountHeight; i++) {
+ FX_FLOAT fLineHeight = m_pLoader->m_lineHeights.ElementAt(i);
+ if (fLinePos + fLineHeight - rtText.height > 0.001) {
+ m_Blocks.Add(iLineIndex);
+ m_Blocks.Add(i - iLineIndex);
+ bEndItem = FALSE;
+ break;
+ }
+ fLinePos += fLineHeight;
+ }
+ if (iCountHeight > 0 && (i - iLineIndex) > 0 && bEndItem) {
+ m_Blocks.Add(iLineIndex);
+ m_Blocks.Add(i - iLineIndex);
+ }
+}
+FX_BOOL CXFA_TextLayout::DrawString(CFX_RenderDevice *pFxDevice, const CFX_Matrix &tmDoc2Device, const CFX_RectF &rtClip, FX_INT32 iBlock )
+{
+ IFDE_RenderDevice *pDevice = IFDE_RenderDevice::Create(pFxDevice);
+ if (pDevice == NULL) {
+ return FALSE;
+ }
+ FDE_HDEVICESTATE state = pDevice->SaveState();
+ pDevice->SetClipRect(rtClip);
+ IFDE_SolidBrush *pSolidBrush = (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
+ IFDE_Pen *pPen = IFDE_Pen::Create();
+ FXSYS_assert(pDevice != NULL && pSolidBrush != NULL && pPen != NULL);
+ if (m_pieceLines.GetSize() == 0) {
+ FX_INT32 iBlockCount = CountBlocks();
+ for (FX_INT32 i = 0; i < iBlockCount; i++) {
+ Layout(i);
+ }
+ }
+ FXTEXT_CHARPOS *pCharPos = NULL;
+ FX_INT32 iCharCount = 0;
+ FX_INT32 iLineStart = 0;
+ FX_INT32 iPieceLines = m_pieceLines.GetSize();
+ FX_INT32 iCount = m_Blocks.GetSize();
+ if (iCount > 0) {
+ iBlock *= 2;
+ if (iBlock < iCount) {
+ iLineStart = m_Blocks.ElementAt(iBlock);
+ iPieceLines = m_Blocks.ElementAt(iBlock + 1);
+ } else {
+ iPieceLines = 0;
+ }
+ }
+ for (FX_INT32 i = 0; i < iPieceLines; i++) {
+ if(i + iLineStart >= m_pieceLines.GetSize()) {
+ break;
+ }
+ CXFA_PieceLine *pPieceLine = m_pieceLines.GetAt(i + iLineStart);
+ FX_INT32 iPieces = pPieceLine->m_textPieces.GetSize();
+ FX_INT32 j = 0;
+ for (j = 0; j < iPieces; j++) {
+ XFA_LPCTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j);
+ FX_INT32 iChars = pPiece->iChars;
+ if (iCharCount < iChars) {
+ if (pCharPos != NULL) {
+ FDE_Free(pCharPos);
+ }
+ pCharPos = (FXTEXT_CHARPOS*)FDE_Alloc(iChars * sizeof(FXTEXT_CHARPOS));
+ iCharCount = iChars;
+ }
+ FXSYS_memset(pCharPos, 0, iCharCount * sizeof(FXTEXT_CHARPOS));
+ RenderString(pDevice, pSolidBrush, pPieceLine, j, pCharPos, tmDoc2Device);
+ }
+ for (j = 0; j < iPieces; j++) {
+ RenderPath(pDevice, pPen, pPieceLine, j, pCharPos, tmDoc2Device);
+ }
+ }
+ pDevice->RestoreState(state);
+ if (pCharPos != NULL) {
+ FDE_Free(pCharPos);
+ }
+ pSolidBrush->Release();
+ pPen->Release();
+ pDevice->Release();
+ return iPieceLines;
+}
+void CXFA_TextLayout::UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom)
+{
+ fHeight -= fBottom;
+ if (fHeight < 0.1f) {
+ return;
+ }
+ switch (m_textParser.GetVAlgin(m_pTextProvider)) {
+ case XFA_ATTRIBUTEENUM_Middle:
+ fHeight /= 2.0f;
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom:
+ break;
+ default:
+ return;
+ }
+ FX_INT32 iCount = m_pieceLines.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXFA_PieceLine *pPieceLine = m_pieceLines.GetAt(i);
+ FX_INT32 iPieces = pPieceLine->m_textPieces.GetSize();
+ for (FX_INT32 j = 0; j < iPieces; j++) {
+ XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(j);
+ CFX_RectF &rect = pPiece->rtPiece;
+ rect.top += fHeight;
+ }
+ }
+}
+FX_BOOL CXFA_TextLayout::Loader(const CFX_SizeF &szText, FX_FLOAT &fLinePos, FX_BOOL bSavePieces )
+{
+ if (m_pAllocator == NULL) {
+ m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Static, 256, 0);
+ }
+ GetTextDataNode();
+ if (m_pTextDataNode == NULL) {
+ return TRUE;
+ }
+ if (m_bRichText) {
+ IFDE_XMLNode *pXMLContainer = GetXMLContainerNode();
+ if (pXMLContainer) {
+ if (!m_textParser.IsParsed()) {
+ m_textParser.DoParse(pXMLContainer, m_pTextProvider);
+ }
+ IFDE_CSSComputedStyle *pRootStyle = m_textParser.CreateRootStyle(m_pTextProvider);
+ LoadRichText(pXMLContainer, szText, fLinePos, pRootStyle, bSavePieces);
+ pRootStyle->Release();
+ }
+ } else {
+ LoadText(m_pTextDataNode, szText, fLinePos, bSavePieces);
+ }
+ return TRUE;
+}
+void CXFA_TextLayout::LoadText(CXFA_Node *pNode, const CFX_SizeF &szText, FX_FLOAT &fLinePos, FX_BOOL bSavePieces)
+{
+ InitBreak(szText.x);
+ CXFA_Para para = m_pTextProvider->GetParaNode();
+ FX_FLOAT fSpaceAbove = 0;
+ if (para.IsExistInXML()) {
+ fSpaceAbove = para.GetSpaceAbove();
+ if (fSpaceAbove < 0.1f) {
+ fSpaceAbove = 0;
+ }
+ FX_INT32 verAlign = para.GetVerticalAlign();
+ switch (verAlign) {
+ case XFA_ATTRIBUTEENUM_Top:
+ case XFA_ATTRIBUTEENUM_Middle:
+ case XFA_ATTRIBUTEENUM_Bottom: {
+ fLinePos += fSpaceAbove;
+ break;
+ }
+ }
+ }
+ CFX_WideString wsText = pNode->GetContent();
+ wsText.TrimRight(L" ");
+ FX_BOOL bRet = AppendChar(wsText, fLinePos, fSpaceAbove, bSavePieces);
+ if (bRet && m_pLoader != NULL) {
+ m_pLoader->m_pNode = pNode;
+ } else {
+ EndBreak(FX_RTFBREAK_ParagraphBreak, fLinePos, bSavePieces);
+ }
+}
+FX_BOOL CXFA_TextLayout::LoadRichText(IFDE_XMLNode *pXMLNode, const CFX_SizeF &szText, FX_FLOAT &fLinePos, IFDE_CSSComputedStyle *pParentStyle, FX_BOOL bSavePieces, CXFA_LinkUserData* pLinkData, FX_BOOL bEndBreak, FX_BOOL bIsOl, FX_INT32 iLiCount)
+{
+ if (pXMLNode == NULL) {
+ return FALSE;
+ }
+ CXFA_TextParseContext *pContext = m_textParser.GetParseContextFromMap(pXMLNode);
+ FDE_CSSDISPLAY eDisplay = FDE_CSSDISPLAY_None;
+ FX_BOOL bContentNode = FALSE;
+ FX_FLOAT fSpaceBelow = 0;
+ IFDE_CSSComputedStyle *pStyle = NULL;
+ CFX_WideString wsName;
+ if (bEndBreak) {
+ FX_BOOL bCurOl = FALSE;
+ FX_BOOL bCurLi = FALSE;
+ IFDE_XMLElement *pElement = NULL;
+ if (pContext != NULL) {
+ if(m_bBlockContinue || (m_pLoader && pXMLNode == m_pLoader->m_pXMLNode)) {
+ m_bBlockContinue = TRUE;
+ }
+ if(pXMLNode->GetType() == FDE_XMLNODE_Text) {
+ bContentNode = TRUE;
+ } else if (pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ pElement = (IFDE_XMLElement *)pXMLNode;
+ pElement->GetLocalTagName(wsName);
+ }
+ if (wsName == FX_WSTRC(L"ol")) {
+ bIsOl = TRUE;
+ bCurOl = TRUE;
+ }
+ if(m_bBlockContinue || bContentNode == FALSE) {
+ eDisplay = pContext->GetDisplay();
+ if (eDisplay != FDE_CSSDISPLAY_Block && eDisplay != FDE_CSSDISPLAY_Inline && eDisplay != FDE_CSSDISPLAY_ListItem) {
+ return TRUE;
+ }
+ pStyle = m_textParser.ComputeStyle(pXMLNode, pParentStyle);
+ InitBreak(bContentNode ? pParentStyle : pStyle, eDisplay, szText.x, pXMLNode, pParentStyle);
+ if ((eDisplay == FDE_CSSDISPLAY_Block || eDisplay == FDE_CSSDISPLAY_ListItem) && (pStyle != NULL)
+ && (wsName.IsEmpty() || (wsName != FX_WSTRC(L"body") && wsName != FX_WSTRC(L"html") && wsName != FX_WSTRC(L"ol") && wsName != FX_WSTRC(L"ul")))) {
+ const FDE_CSSRECT *pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
+ if (pRect) {
+ fLinePos += pRect->top.GetValue();
+ fSpaceBelow = pRect->bottom.GetValue();
+ }
+ }
+ if (wsName == FX_WSTRC(L"a")) {
+ CFX_WideString wsLinkContent;
+ FXSYS_assert(pElement);
+ pElement->GetString(FX_WSTRC(L"href").GetPtr(), wsLinkContent);
+ if (!wsLinkContent.IsEmpty()) {
+ pLinkData = FDE_NewWith(m_pAllocator)CXFA_LinkUserData(m_pAllocator, wsLinkContent.GetBuffer(wsLinkContent.GetLength()));
+ wsLinkContent.ReleaseBuffer(wsLinkContent.GetLength());
+ }
+ }
+ FX_INT32 iTabCount = m_textParser.CountTabs(bContentNode ? pParentStyle : pStyle);
+ FX_BOOL bSpaceRun = m_textParser.IsSpaceRun(bContentNode ? pParentStyle : pStyle);
+ CFX_WideString wsText;
+ if (bContentNode && iTabCount == 0) {
+ ((IFDE_XMLText *)pXMLNode)->GetText(wsText);
+ } else if (wsName == FX_WSTRC(L"br")) {
+ wsText = L'\n';
+ } else if (wsName == FX_WSTRC(L"li")) {
+ bCurLi = TRUE;
+ if (bIsOl) {
+ wsText.Format(FX_LPCWSTR(L"%d. "), iLiCount);
+ } else {
+ wsText = 0x00B7 + FX_WSTRC(L" ");
+ }
+ } else if (!bContentNode) {
+ if (iTabCount > 0)
+ while (iTabCount-- > 0) {
+ wsText += L'\t';
+ }
+ else {
+ m_textParser.GetEmbbedObj(m_pTextProvider, pXMLNode, wsText);
+ }
+ }
+ FX_INT32 iLength = wsText.GetLength();
+ if (iLength > 0 && bContentNode && !bSpaceRun) {
+ ProcessText(wsText);
+ }
+ if (m_pLoader) {
+ if (wsText.GetLength() > 0 && (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) {
+ wsText.TrimLeft(0x20);
+ }
+ if (FDE_CSSDISPLAY_Block == eDisplay) {
+ m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
+ } else if (FDE_CSSDISPLAY_Inline == eDisplay && (m_pLoader->m_dwFlags & XFA_LOADERCNTXTFLG_FILTERSPACE)) {
+ m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
+ } else if (wsText.GetLength() > 0 && (0x20 == wsText.GetAt(wsText.GetLength() - 1))) {
+ m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
+ } else if (wsText.GetLength() == 0)
+ ;
+ else {
+ m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
+ }
+ }
+ if (wsText.GetLength() > 0) {
+ if (m_pLoader == NULL || m_pLoader->m_iChar == 0) {
+ if (pLinkData) {
+ pLinkData->AddRef();
+ }
+ CXFA_TextUserData *pUserData = FDE_NewWith(m_pAllocator)CXFA_TextUserData(m_pAllocator, bContentNode ? pParentStyle : pStyle, pLinkData);
+ m_pBreak->SetUserData(pUserData);
+ }
+ if (AppendChar(wsText, fLinePos, 0, bSavePieces)) {
+ if ( m_pLoader) {
+ m_pLoader->m_dwFlags &= ~XFA_LOADERCNTXTFLG_FILTERSPACE;
+ }
+ if (IsEnd(bSavePieces)) {
+ if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
+ m_pLoader->m_pXMLNode = pXMLNode;
+ m_pLoader->m_pParentStyle = pParentStyle;
+ }
+ if (pStyle != NULL) {
+ pStyle->Release();
+ }
+ return FALSE;
+ }
+ return TRUE;
+ }
+ }
+ }
+ }
+ FX_BOOL ret = TRUE;
+ for (IFDE_XMLNode *pChildNode = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if (bCurOl) {
+ iLiCount++;
+ }
+ ret = LoadRichText(pChildNode, szText, fLinePos, pContext ? pStyle : pParentStyle, bSavePieces, pLinkData, TRUE, bIsOl, iLiCount);
+ if(ret == FALSE) {
+ return FALSE;
+ }
+ }
+ if (m_pLoader) {
+ if (FDE_CSSDISPLAY_Block == eDisplay) {
+ m_pLoader->m_dwFlags |= XFA_LOADERCNTXTFLG_FILTERSPACE;
+ }
+ }
+ if (bCurLi) {
+ EndBreak(FX_RTFBREAK_LineBreak, fLinePos, bSavePieces);
+ }
+ } else {
+ if (pContext != NULL) {
+ eDisplay = pContext->GetDisplay();
+ }
+ }
+ if(m_bBlockContinue) {
+ if (pContext != NULL && !bContentNode) {
+ FX_DWORD dwStatus = (eDisplay == FDE_CSSDISPLAY_Block) ? FX_RTFBREAK_ParagraphBreak : FX_RTFBREAK_PieceBreak;
+ EndBreak(dwStatus, fLinePos, bSavePieces);
+ if (eDisplay == FDE_CSSDISPLAY_Block) {
+ fLinePos += fSpaceBelow;
+ if (m_pTabstopContext) {
+ m_pTabstopContext->RemoveAll();
+ }
+ }
+ if ( wsName == FX_WSTRC(L"a")) {
+ if (pLinkData != NULL) {
+ FX_DWORD dwRefCount = pLinkData->Release();
+ pLinkData = NULL;
+ }
+ }
+ if (IsEnd(bSavePieces)) {
+ if (pStyle) {
+ pStyle->Release();
+ }
+ if (m_pLoader && m_pLoader->m_iTotalLines > -1) {
+ m_pLoader->m_pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling);
+ m_pLoader->m_pParentStyle = pParentStyle;
+ }
+ return FALSE;
+ }
+ }
+ }
+ if (pStyle != NULL) {
+ pStyle->Release();
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_TextLayout::AppendChar(const CFX_WideString &wsText, FX_FLOAT &fLinePos, FX_FLOAT fSpaceAbove, FX_BOOL bSavePieces)
+{
+ FX_DWORD dwStatus = 0;
+ FX_INT32 iChar = 0;
+ if (m_pLoader) {
+ iChar = m_pLoader->m_iChar;
+ }
+ FX_INT32 iLength = wsText.GetLength();
+ for (FX_INT32 i = iChar; i < iLength; i++) {
+ FX_WCHAR wch = wsText.GetAt(i);
+ if (wch == 0xA0) {
+ wch = 0x20;
+ }
+ if ((dwStatus = m_pBreak->AppendChar(wch)) > FX_RTFBREAK_PieceBreak) {
+ AppendTextLine(dwStatus, fLinePos, bSavePieces);
+ if (IsEnd(bSavePieces)) {
+ if (m_pLoader != NULL) {
+ m_pLoader->m_iChar = i;
+ }
+ return TRUE;
+ }
+ if (dwStatus == FX_RTFBREAK_ParagraphBreak && m_bRichText) {
+ fLinePos += fSpaceAbove;
+ }
+ }
+ }
+ if(m_pLoader) {
+ m_pLoader->m_iChar = 0;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_TextLayout::IsEnd(FX_BOOL bSavePieces)
+{
+ if (!bSavePieces) {
+ return FALSE;
+ }
+ if (m_pLoader && m_pLoader->m_iTotalLines > 0) {
+ return m_iLines >= m_pLoader->m_iTotalLines;
+ }
+ return FALSE;
+}
+void CXFA_TextLayout::ProcessText(CFX_WideString &wsText)
+{
+ FX_INT32 iLen = wsText.GetLength();
+ if (iLen == 0) {
+ return;
+ }
+ FX_LPWSTR psz = wsText.GetBuffer(iLen);
+ FX_INT32 iTrimLeft = 0;
+ FX_WCHAR wch = 0, wPrev = 0;
+ for (FX_INT32 i = 0; i < iLen; i++) {
+ wch = psz[i];
+ if (wch < 0x20) {
+ wch = 0x20;
+ }
+ if (wch == 0x20 && wPrev == 0x20) {
+ continue;
+ }
+ wPrev = wch;
+ psz[iTrimLeft++] = wch;
+ }
+ wsText.ReleaseBuffer(iLen);
+ wsText = wsText.Left(iTrimLeft);
+}
+void CXFA_TextLayout::EndBreak(FX_DWORD dwStatus, FX_FLOAT &fLinePos, FX_BOOL bSavePieces)
+{
+ dwStatus = m_pBreak->EndBreak(dwStatus);
+ if (dwStatus > FX_RTFBREAK_PieceBreak) {
+ AppendTextLine(dwStatus, fLinePos, bSavePieces, TRUE);
+ }
+}
+void CXFA_TextLayout::DoTabstops(IFDE_CSSComputedStyle *pStyle, CXFA_PieceLine *pPieceLine)
+{
+ if (m_pTabstopContext == NULL || m_pTabstopContext->m_iTabCount == 0) {
+ return;
+ }
+ if (pStyle == NULL || pPieceLine == NULL) {
+ return;
+ }
+ FX_INT32 iPieces = pPieceLine->m_textPieces.GetSize();
+ if (iPieces == 0) {
+ return;
+ }
+ XFA_LPTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(iPieces - 1);
+ FX_INT32 &iTabstopsIndex = m_pTabstopContext->m_iTabIndex;
+ FX_INT32 iCount = m_textParser.CountTabs(pStyle);
+ if (iTabstopsIndex > m_pTabstopContext->m_iTabCount - 1) {
+ return;
+ }
+ if (iCount > 0) {
+ iTabstopsIndex++;
+ m_pTabstopContext->m_bTabstops = TRUE;
+ FX_FLOAT fRight = 0;
+ if (iPieces > 1) {
+ XFA_LPTEXTPIECE p = pPieceLine->m_textPieces.GetAt(iPieces - 2);
+ fRight = p->rtPiece.right();
+ }
+ m_pTabstopContext->m_fTabWidth = pPiece->rtPiece.width + pPiece->rtPiece.left - fRight;
+ } else if (iTabstopsIndex > -1) {
+ FX_FLOAT fLeft = 0;
+ if (m_pTabstopContext->m_bTabstops) {
+ XFA_TABSTOPS *pTabstops = m_pTabstopContext->m_tabstops.GetDataPtr(iTabstopsIndex);
+ FX_DWORD dwAlgin = pTabstops->dwAlign;
+ if (dwAlgin == FX_HashCode_String_GetW((FX_LPCWSTR)L"center", 6)) {
+ fLeft = pPiece->rtPiece.width / 2.0f;
+ } else if (dwAlgin == FX_HashCode_String_GetW((FX_LPCWSTR)L"right", 5)
+ || dwAlgin == FX_HashCode_String_GetW((FX_LPCWSTR)L"before", 6)) {
+ fLeft = pPiece->rtPiece.width;
+ } else if (dwAlgin == FX_HashCode_String_GetW((FX_LPCWSTR)L"decimal", 7)) {
+ FX_INT32 iChars = pPiece->iChars;
+ for (FX_INT32 i = 0; i < iChars; i++) {
+ if (pPiece->pszText[i] == L'.') {
+ break;
+ }
+ fLeft += pPiece->pWidths[i] / 20000.0f;
+ }
+ }
+ m_pTabstopContext->m_fLeft = FX_MIN(fLeft, m_pTabstopContext->m_fTabWidth);
+ m_pTabstopContext->m_bTabstops = FALSE;
+ m_pTabstopContext->m_fTabWidth = 0;
+ }
+ pPiece->rtPiece.left -= m_pTabstopContext->m_fLeft;
+ }
+}
+void CXFA_TextLayout::AppendTextLine(FX_DWORD dwStatus, FX_FLOAT &fLinePos, FX_BOOL bSavePieces, FX_BOOL bEndBreak)
+{
+ FX_INT32 iPieces = m_pBreak->CountBreakPieces();
+ if (iPieces < 1) {
+ return;
+ }
+ IFDE_CSSComputedStyle *pStyle = NULL;
+ if (bSavePieces) {
+ CXFA_PieceLine *pPieceLine = FDE_NewWith(m_pAllocator)CXFA_PieceLine;
+ m_pieceLines.Add(pPieceLine);
+ if (m_pTabstopContext) {
+ m_pTabstopContext->Reset();
+ }
+ FX_FLOAT fLineStep = 0, fBaseLine = 0;
+ FX_INT32 i = 0;
+ for (i = 0; i < iPieces; i++) {
+ const CFX_RTFPiece *pPiece = m_pBreak->GetBreakPiece(i);
+ CXFA_TextUserData *pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
+ if (pUserData != NULL) {
+ pStyle = pUserData->m_pStyle;
+ }
+ FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
+ XFA_LPTEXTPIECE pTP = (XFA_LPTEXTPIECE)m_pAllocator->Alloc(sizeof(XFA_TEXTPIECE));
+ pTP->pszText = (FX_LPWSTR)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(FX_WCHAR));
+ pTP->pWidths = (FX_INT32*)m_pAllocator->Alloc(pPiece->m_iChars * sizeof(FX_INT32));
+ pTP->iChars = pPiece->m_iChars;
+ pPiece->GetString(pTP->pszText);
+ pPiece->GetWidths(pTP->pWidths);
+ pTP->iBidiLevel = pPiece->m_iBidiLevel;
+ pTP->iHorScale = pPiece->m_iHorizontalScale;
+ pTP->iVerScale = pPiece->m_iVerticalScale;
+ m_textParser.GetUnderline(m_pTextProvider, pStyle, pTP->iUnderline, pTP->iPeriod);
+ m_textParser.GetLinethrough(m_pTextProvider, pStyle, pTP->iLineThrough);
+ pTP->dwColor = m_textParser.GetColor(m_pTextProvider, pStyle);
+ pTP->pFont = m_textParser.GetFont(m_pTextProvider, pStyle);
+ pTP->fFontSize = m_textParser.GetFontSize(m_pTextProvider, pStyle);
+ pTP->rtPiece.left = pPiece->m_iStartPos / 20000.0f;
+ pTP->rtPiece.width = pPiece->m_iWidth / 20000.0f;
+ pTP->rtPiece.height = (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f;
+ FX_FLOAT fBaseLineTemp = m_textParser.GetBaseline(m_pTextProvider, pStyle);
+ pTP->rtPiece.top = fBaseLineTemp;
+ pPieceLine->m_textPieces.Add(pTP);
+ FX_FLOAT fLineHeight = m_textParser.GetLineHeight(m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
+ if (fBaseLineTemp > 0) {
+ FX_FLOAT fLineHeightTmp = fBaseLineTemp + pTP->rtPiece.height;
+ if (fLineHeight < fLineHeightTmp) {
+ fLineHeight = fLineHeightTmp;
+ } else {
+ fBaseLineTemp = 0;
+ }
+ } else if (fBaseLine < -fBaseLineTemp) {
+ fBaseLine = -fBaseLineTemp;
+ }
+ fLineStep = FX_MAX(fLineStep, fLineHeight);
+ if ( pUserData != NULL && pUserData->m_pLinkData != NULL) {
+ pUserData->m_pLinkData->AddRef();
+ pTP->pLinkData = pUserData->m_pLinkData;
+ } else {
+ pTP->pLinkData = NULL;
+ }
+ DoTabstops(pStyle, pPieceLine);
+ }
+ for (i = 0; i < iPieces; i++) {
+ XFA_LPTEXTPIECE pTP = pPieceLine->m_textPieces.GetAt(i);
+ FX_FLOAT &fTop = pTP->rtPiece.top;
+ FX_FLOAT fBaseLineTemp = fTop;
+ fTop = fLinePos + fLineStep - pTP->rtPiece.height - fBaseLineTemp;
+ fTop = FX_MAX(0, fTop);
+ }
+ fLinePos += fLineStep + fBaseLine;
+ } else {
+ FX_FLOAT fLineStep = 0;
+ FX_FLOAT fLineWidth = 0;
+ for (FX_INT32 i = 0; i < iPieces; i++) {
+ const CFX_RTFPiece *pPiece = m_pBreak->GetBreakPiece(i);
+ CXFA_TextUserData *pUserData = (CXFA_TextUserData*)pPiece->m_pUserData;
+ if (pUserData != NULL) {
+ pStyle = pUserData->m_pStyle;
+ }
+ FX_FLOAT fVerScale = pPiece->m_iVerticalScale / 100.0f;
+ FX_FLOAT fBaseLine = m_textParser.GetBaseline(m_pTextProvider, pStyle);
+ FX_FLOAT fLineHeight = m_textParser.GetLineHeight(m_pTextProvider, pStyle, m_iLines == 0, fVerScale);
+ if (fBaseLine > 0) {
+ FX_FLOAT fLineHeightTmp = fBaseLine + (FX_FLOAT)pPiece->m_iFontSize * fVerScale / 20.0f;
+ if (fLineHeight < fLineHeightTmp) {
+ fLineHeight = fLineHeightTmp;
+ }
+ }
+ fLineStep = FX_MAX(fLineStep, fLineHeight);
+ fLineWidth += pPiece->m_iWidth / 20000.0f;
+ }
+ fLinePos += fLineStep;
+ m_fMaxWidth = FX_MAX(m_fMaxWidth, fLineWidth);
+ if (m_pLoader && m_pLoader->m_bSaveLineHeight) {
+ FX_FLOAT fHeight = fLinePos - m_pLoader->m_fLastPos;
+ m_pLoader->m_fLastPos = fLinePos;
+ m_pLoader->m_lineHeights.Add(fHeight);
+ }
+ }
+ m_pBreak->ClearBreakPieces();
+ if (dwStatus == FX_RTFBREAK_ParagraphBreak) {
+ m_pBreak->Reset();
+ if (pStyle == NULL && bEndBreak) {
+ CXFA_Para para = m_pTextProvider->GetParaNode();
+ if (para.IsExistInXML()) {
+ FX_FLOAT fStartPos = para.GetMarginLeft();
+ FX_FLOAT fIndent = para.GetTextIndent();
+ if (fIndent > 0) {
+ fStartPos += fIndent;
+ }
+ FX_FLOAT fSpaceBelow = para.GetSpaceBelow();
+ if (fSpaceBelow < 0.1f) {
+ fSpaceBelow = 0;
+ }
+ m_pBreak->SetLinePos(fStartPos);
+ fLinePos += fSpaceBelow;
+ }
+ }
+ }
+ if (pStyle != NULL) {
+ FX_FLOAT fStart = 0;
+ const FDE_CSSRECT *pRect = pStyle->GetBoundaryStyles()->GetMarginWidth();
+ if (pRect) {
+ fStart = pRect->left.GetValue();
+ }
+ FX_FLOAT fTextIndent = pStyle->GetParagraphStyles()->GetTextIndent().GetValue();
+ if (fTextIndent < 0) {
+ fStart -= fTextIndent;
+ }
+ m_pBreak->SetLinePos(fStart);
+ }
+ m_iLines++;
+}
+void CXFA_TextLayout::RenderString(IFDE_RenderDevice *pDevice, IFDE_SolidBrush *pBrush, CXFA_PieceLine *pPieceLine, FX_INT32 iPiece, FXTEXT_CHARPOS *pCharPos, const CFX_Matrix &tmDoc2Device)
+{
+ XFA_LPCTEXTPIECE pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
+ FX_INT32 iCount = GetDisplayPos(pPiece, pCharPos);
+ if (iCount > 0) {
+ pBrush->SetColor(pPiece->dwColor);
+ pDevice->DrawString(pBrush, pPiece->pFont, pCharPos, iCount, pPiece->fFontSize, &tmDoc2Device);
+ }
+ pPieceLine->m_charCounts.Add(iCount);
+}
+void CXFA_TextLayout::RenderPath(IFDE_RenderDevice *pDevice, IFDE_Pen *pPen, CXFA_PieceLine *pPieceLine, FX_INT32 iPiece, FXTEXT_CHARPOS *pCharPos, const CFX_Matrix &tmDoc2Device)
+{
+ XFA_TEXTPIECE *pPiece = pPieceLine->m_textPieces.GetAt(iPiece);
+ FX_BOOL bNoUnderline = pPiece->iUnderline < 1 || pPiece->iUnderline > 2;
+ FX_BOOL bNoLineThrough = pPiece->iLineThrough < 1 || pPiece->iLineThrough > 2;
+ if (bNoUnderline && bNoLineThrough) {
+ return;
+ }
+ pPen->SetColor(pPiece->dwColor);
+ IFDE_Path *pPath = IFDE_Path::Create();
+ FX_INT32 iChars = GetDisplayPos(pPiece, pCharPos);
+ if (iChars > 0) {
+ CFX_PointF pt1, pt2;
+ FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
+ FX_INT32 i = 0;
+ if (pPiece->iPeriod == XFA_ATTRIBUTEENUM_Word) {
+ for (FX_INT32 i = 0; i < pPiece->iUnderline; i++) {
+ for (FX_INT32 j = 0; j < iChars; j++) {
+ pt1.x = pCharPos[j].m_OriginX;
+ pt2.x = pt1.x + pCharPos[j].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+ pt1.y = pt2.y = fEndY;
+ pPath->AddLine(pt1, pt2);
+ }
+ fEndY += 2.0f;
+ }
+ } else {
+ pt1.x = pCharPos[0].m_OriginX;
+ pt2.x = pCharPos[iChars - 1].m_OriginX + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+ for (FX_INT32 i = 0; i < pPiece->iUnderline; i++) {
+ pt1.y = pt2.y = fEndY;
+ pPath->AddLine(pt1, pt2);
+ fEndY += 2.0f;
+ }
+ }
+ fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f;
+ pt1.x = pCharPos[0].m_OriginX;
+ pt2.x = pCharPos[iChars - 1].m_OriginX + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+ for (i = 0; i < pPiece->iLineThrough; i++) {
+ pt1.y = pt2.y = fEndY;
+ pPath->AddLine(pt1, pt2);
+ fEndY += 2.0f;
+ }
+ } else {
+ if (bNoLineThrough && (bNoUnderline || pPiece->iPeriod != XFA_ATTRIBUTEENUM_All)) {
+ goto XFA_RenderPathRet;
+ }
+ FX_INT32 iCharsTmp = 0;
+ FX_INT32 iPiecePrev = iPiece, iPieceNext = iPiece;
+ while (iPiecePrev > 0) {
+ iPiecePrev--;
+ iCharsTmp = pPieceLine->m_charCounts.GetAt(iPiecePrev);
+ if (iCharsTmp > 0) {
+ break;
+ }
+ }
+ if (iCharsTmp == 0) {
+ goto XFA_RenderPathRet;
+ }
+ iCharsTmp = 0;
+ FX_INT32 iPieces = pPieceLine->m_textPieces.GetSize();
+ while (iPieceNext < iPieces - 1) {
+ iPieceNext++;
+ iCharsTmp = pPieceLine->m_charCounts.GetAt(iPieceNext);
+ if (iCharsTmp > 0) {
+ break;
+ }
+ }
+ if (iCharsTmp == 0) {
+ goto XFA_RenderPathRet;
+ }
+ FX_FLOAT fOrgX = 0.0f, fEndX = 0.0f;
+ pPiece = pPieceLine->m_textPieces.GetAt(iPiecePrev);
+ iChars = GetDisplayPos(pPiece, pCharPos);
+ if (iChars < 1) {
+ goto XFA_RenderPathRet;
+ }
+ fOrgX = pCharPos[iChars - 1].m_OriginX + pCharPos[iChars - 1].m_FontCharWidth * pPiece->fFontSize / 1000.0f;
+ pPiece = pPieceLine->m_textPieces.GetAt(iPieceNext);
+ iChars = GetDisplayPos(pPiece, pCharPos);
+ if (iChars < 1) {
+ goto XFA_RenderPathRet;
+ }
+ fEndX = pCharPos[0].m_OriginX;
+ CFX_PointF pt1, pt2;
+ pt1.x = fOrgX, pt2.x = fEndX;
+ FX_FLOAT fEndY = pCharPos[0].m_OriginY + 1.05f;
+ FX_INT32 i = 0;
+ for (i = 0; i < pPiece->iUnderline; i++) {
+ pt1.y = pt2.y = fEndY;
+ pPath->AddLine(pt1, pt2);
+ fEndY += 2.0f;
+ }
+ fEndY = pCharPos[0].m_OriginY - pPiece->rtPiece.height * 0.25f;
+ for (i = 0; i < pPiece->iLineThrough; i++) {
+ pt1.y = pt2.y = fEndY;
+ pPath->AddLine(pt1, pt2);
+ fEndY += 2.0f;
+ }
+ }
+ pDevice->DrawPath(pPen, 1, pPath, &tmDoc2Device);
+XFA_RenderPathRet:
+ pPath->Release();
+}
+FX_INT32 CXFA_TextLayout::GetDisplayPos(XFA_LPCTEXTPIECE pPiece, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode )
+{
+ if (pPiece == NULL) {
+ return 0;
+ }
+ FX_RTFTEXTOBJ tr;
+ if (!ToRun(pPiece, tr)) {
+ return 0;
+ }
+ return m_pBreak->GetDisplayPos(&tr, pCharPos, bCharCode);
+}
+FX_BOOL CXFA_TextLayout::ToRun(XFA_LPCTEXTPIECE pPiece, FX_RTFTEXTOBJ &tr)
+{
+ FX_INT32 iLength = pPiece->iChars;
+ if (iLength < 1) {
+ return FALSE;
+ }
+ tr.pStr = pPiece->pszText;
+ tr.pFont = pPiece->pFont;
+ tr.pRect = &pPiece->rtPiece;
+ tr.pWidths = pPiece->pWidths;
+ tr.iLength = iLength;
+ tr.fFontSize = pPiece->fFontSize;
+ tr.iBidiLevel = pPiece->iBidiLevel;
+ tr.iCharRotation = 0;
+ tr.wLineBreakChar = L'\n';
+ tr.iVerticalScale = pPiece->iVerScale;
+ tr.dwLayoutStyles = FX_RTFLAYOUTSTYLE_ExpandTab;
+ tr.iHorizontalScale = pPiece->iHorScale;
+ return TRUE;
+}
diff --git a/xfa/src/fxfa/src/app/xfa_textlayout.h b/xfa/src/fxfa/src/app/xfa_textlayout.h
new file mode 100644
index 0000000000..47b37720ed
--- /dev/null
+++ b/xfa/src/fxfa/src/app/xfa_textlayout.h
@@ -0,0 +1,391 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_TEXTLAYOUT_H
+#define _FXFA_TEXTLAYOUT_H
+#define XFA_LOADERCNTXTFLG_FILTERSPACE 0x001
+class CXFA_TextTabstopsContext;
+class IXFA_TextProvider
+{
+public:
+ virtual CXFA_Node* GetTextNode(FX_BOOL &bRichText) = 0;
+ virtual CXFA_Para GetParaNode() = 0;
+ virtual CXFA_Font GetFontNode() = 0;
+ virtual FX_BOOL IsCheckButtonAndAutoWidth() = 0;
+ virtual CXFA_FFDoc* GetDocNode() = 0;
+ virtual FX_BOOL GetEmbbedObj(FX_BOOL bURI, FX_BOOL bRaw, const CFX_WideString &wsAttr, CFX_WideString &wsValue) = 0;
+};
+class CXFA_CSSTagProvider : public IFDE_CSSTagProvider, public CFX_Object
+{
+public:
+ CXFA_CSSTagProvider ()
+ : m_bTagAviliable(FALSE),
+ m_bContent(FALSE)
+ {}
+ virtual ~CXFA_CSSTagProvider();
+ virtual CFX_WideStringC GetTagName()
+ {
+ return m_wsTagName;
+ }
+ virtual FX_POSITION GetFirstAttribute()
+ {
+ return m_Attributes.GetStartPosition();
+ }
+ virtual void GetNextAttribute(FX_POSITION &pos, CFX_WideStringC &wsAttr, CFX_WideStringC &wsValue);
+ void SetTagNameObj(const CFX_WideString &wsName)
+ {
+ m_wsTagName = wsName;
+ }
+ void SetAttribute(const CFX_WideString &wsAttr, const CFX_WideString &wsValue);
+ FX_BOOL m_bTagAviliable;
+ FX_BOOL m_bContent;
+protected:
+ CFX_WideString m_wsTagName;
+ CFX_MapPtrToPtr m_Attributes;
+};
+class CXFA_TextParseContext : public CFX_Target
+{
+public:
+ CXFA_TextParseContext() : m_ppMatchedDecls(NULL), m_dwMatchedDecls(0), m_eDisplay(FDE_CSSDISPLAY_None), m_pParentStyle(NULL) {}
+ ~CXFA_TextParseContext()
+ {
+ if (m_ppMatchedDecls != NULL) {
+ FDE_Free(m_ppMatchedDecls);
+ }
+ }
+ void SetDisplay(FDE_CSSDISPLAY eDisplay)
+ {
+ m_eDisplay = eDisplay;
+ }
+ FDE_CSSDISPLAY GetDisplay() const
+ {
+ return m_eDisplay;
+ }
+ void SetDecls(const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount);
+ const IFDE_CSSDeclaration** GetDecls()
+ {
+ return (const IFDE_CSSDeclaration**)m_ppMatchedDecls;
+ }
+ FX_DWORD CountDecls() const
+ {
+ return m_dwMatchedDecls;
+ }
+ IFDE_CSSComputedStyle * m_pParentStyle;
+protected:
+ IFDE_CSSDeclaration **m_ppMatchedDecls;
+ FX_DWORD m_dwMatchedDecls : 28;
+ FDE_CSSDISPLAY m_eDisplay : 4;
+};
+class CXFA_TextParser : public CFX_Object
+{
+public:
+ CXFA_TextParser() : m_pAllocator(NULL), m_pSelector(NULL), m_pUASheet(NULL) {}
+ virtual ~CXFA_TextParser();
+ void Reset();
+ void DoParse(IFDE_XMLNode *pXMLContainer, IXFA_TextProvider *pTextProvider);
+ IFDE_CSSComputedStyle* CreateRootStyle(IXFA_TextProvider *pTextProvider);
+ IFDE_CSSComputedStyle* ComputeStyle(IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle);
+ FX_BOOL IsParsed() const
+ {
+ return m_pAllocator != NULL;
+ }
+
+ FX_INT32 GetVAlgin(IXFA_TextProvider *pTextProvider) const;
+ FX_FLOAT GetTabInterval(IFDE_CSSComputedStyle *pStyle) const;
+ FX_INT32 CountTabs(IFDE_CSSComputedStyle *pStyle) const;
+ FX_BOOL IsSpaceRun(IFDE_CSSComputedStyle *pStyle) const;
+ FX_BOOL GetTabstops(IFDE_CSSComputedStyle *pStyle, CXFA_TextTabstopsContext *pTabstopContext);
+ IFX_Font* GetFont(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;
+ FX_FLOAT GetFontSize(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;
+ FX_INT32 GetHorScale(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, IFDE_XMLNode *pXMLNode) const;
+ FX_INT32 GetVerScale(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;
+ void GetUnderline(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_INT32 &iUnderline, FX_INT32 &iPeriod) const;
+ void GetLinethrough(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_INT32 &iLinethrough) const;
+ FX_ARGB GetColor(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;
+ FX_FLOAT GetBaseline(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle) const;
+ FX_FLOAT GetLineHeight(IXFA_TextProvider *pTextProvider, IFDE_CSSComputedStyle *pStyle, FX_BOOL bFirst, FX_FLOAT fVerScale) const;
+ FX_BOOL GetEmbbedObj(IXFA_TextProvider *pTextProvider, IFDE_XMLNode *pXMLNode, CFX_WideString &wsValue);
+ CXFA_TextParseContext* GetParseContextFromMap(IFDE_XMLNode *pXMLNode);
+private:
+ void InitCSSData(IXFA_TextProvider *pTextProvider);
+ void ParseRichText(IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle);
+ void ParseTagInfo(IFDE_XMLNode *pXMLNode, CXFA_CSSTagProvider &tagProvider);
+ IFDE_CSSStyleSheet* LoadDefaultSheetStyle();
+ IFDE_CSSComputedStyle* CreateStyle(IFDE_CSSComputedStyle *pParentStyle);
+ IFX_MEMAllocator *m_pAllocator;
+ IFDE_CSSStyleSelector *m_pSelector;
+ IFDE_CSSStyleSheet *m_pUASheet;
+ CFX_MapPtrTemplate<IFDE_XMLNode*, CXFA_TextParseContext*> m_mapXMLNodeToParseContext;
+};
+class CXFA_LoaderContext : public CFX_Object
+{
+public:
+ CXFA_LoaderContext() : m_bSaveLineHeight(FALSE)
+ , m_fWidth(0)
+ , m_fHeight(0)
+ , m_fLastPos(0)
+ , m_fStartLineOffset(0)
+ , m_iChar(0)
+ , m_iTotalLines(-1)
+ , m_pXMLNode(NULL)
+ , m_pNode(NULL)
+ , m_pParentStyle(NULL)
+ , m_dwFlags(0)
+ {}
+ FX_BOOL m_bSaveLineHeight;
+ FX_FLOAT m_fWidth;
+ FX_FLOAT m_fHeight;
+ FX_FLOAT m_fLastPos;
+ FX_FLOAT m_fStartLineOffset;
+ FX_INT32 m_iChar;
+ FX_INT32 m_iLines;
+ FX_INT32 m_iTotalLines;
+ IFDE_XMLNode *m_pXMLNode;
+ CXFA_Node *m_pNode;
+ IFDE_CSSComputedStyle *m_pParentStyle;
+ CFX_ArrayTemplate<FX_FLOAT> m_lineHeights;
+ FX_DWORD m_dwFlags;
+ CFX_FloatArray m_BlocksHeight;
+};
+class CXFA_LinkUserData : public IFX_Unknown, public CFX_Target
+{
+public:
+ CXFA_LinkUserData(IFX_MEMAllocator *pAllocator, FX_LPWSTR pszText)
+ : m_pAllocator(pAllocator)
+ , m_dwRefCount(1)
+ {
+ m_pszURLContent = pszText;
+ }
+ ~CXFA_LinkUserData() { }
+ virtual FX_DWORD Release()
+ {
+ FX_DWORD dwRefCount = --m_dwRefCount;
+ if (dwRefCount <= 0) {
+ FDE_DeleteWith(CXFA_LinkUserData, m_pAllocator, this);
+ }
+ return dwRefCount;
+ }
+ virtual FX_DWORD AddRef()
+ {
+ return ++m_dwRefCount;
+ }
+public:
+ FX_LPCWSTR GetLinkURL()
+ {
+ return m_pszURLContent;
+ };
+protected:
+ IFX_MEMAllocator *m_pAllocator;
+ FX_DWORD m_dwRefCount;
+ CFX_WideString m_pszURLContent;
+};
+class CXFA_TextUserData : public IFX_Unknown, public CFX_Target
+{
+public:
+ CXFA_TextUserData(IFX_MEMAllocator *pAllocator, IFDE_CSSComputedStyle *pStyle)
+ : m_pStyle(pStyle)
+ , m_pAllocator(pAllocator)
+ , m_dwRefCount(0)
+ , m_pLinkData(NULL)
+ {
+ FXSYS_assert(m_pAllocator != NULL);
+ if (m_pStyle != NULL) {
+ m_pStyle->AddRef();
+ }
+ }
+ CXFA_TextUserData(IFX_MEMAllocator *pAllocator, IFDE_CSSComputedStyle *pStyle, CXFA_LinkUserData* pLinkData)
+ : m_pStyle(pStyle)
+ , m_pAllocator(pAllocator)
+ , m_dwRefCount(0)
+ , m_pLinkData(pLinkData)
+ {
+ FXSYS_assert(m_pAllocator != NULL);
+ if (m_pStyle != NULL) {
+ m_pStyle->AddRef();
+ }
+ }
+ ~CXFA_TextUserData()
+ {
+ if (m_pStyle != NULL) {
+ m_pStyle->Release();
+ }
+ if (m_pLinkData != NULL) {
+ m_pLinkData->Release();
+ }
+ }
+ virtual FX_DWORD Release()
+ {
+ FX_DWORD dwRefCount = --m_dwRefCount;
+ if (dwRefCount == 0) {
+ FDE_DeleteWith(CXFA_TextUserData, m_pAllocator, this);
+ }
+ return dwRefCount;
+ }
+ virtual FX_DWORD AddRef()
+ {
+ return ++m_dwRefCount;
+ }
+
+ IFDE_CSSComputedStyle *m_pStyle;
+ CXFA_LinkUserData *m_pLinkData;
+protected:
+ IFX_MEMAllocator *m_pAllocator;
+ FX_DWORD m_dwRefCount;
+};
+typedef struct _XFA_TEXTPIECE : public CFX_Target {
+ FX_LPWSTR pszText;
+ FX_INT32 iChars;
+ FX_INT32 *pWidths;
+ FX_INT32 iHorScale;
+ FX_INT32 iVerScale;
+ FX_INT32 iBidiLevel;
+ FX_INT32 iUnderline;
+ FX_INT32 iPeriod;
+ FX_INT32 iLineThrough;
+ IFX_Font *pFont;
+ FX_ARGB dwColor;
+ FX_FLOAT fFontSize;
+ CFX_RectF rtPiece;
+ CXFA_LinkUserData* pLinkData;
+
+ _XFA_TEXTPIECE() : pszText(NULL), pFont(NULL), pLinkData(NULL)
+ {
+ pszText = NULL;
+ }
+ ~_XFA_TEXTPIECE()
+ {
+ pszText = NULL;
+ if (NULL != pLinkData) {
+ pLinkData->Release();
+ pLinkData = NULL;
+ }
+ }
+} XFA_TEXTPIECE, * XFA_LPTEXTPIECE;
+typedef XFA_TEXTPIECE const * XFA_LPCTEXTPIECE;
+typedef CFX_ArrayTemplate<XFA_LPTEXTPIECE> CXFA_PieceArray;
+class CXFA_PieceLine : public CFX_Target
+{
+public:
+ CXFA_PieceLine() {}
+ CXFA_PieceArray m_textPieces;
+ CFX_Int32Array m_charCounts;
+};
+typedef CFX_ArrayTemplate<CXFA_PieceLine*> CXFA_PieceLineArray;
+struct XFA_TABSTOPS {
+ FX_DWORD dwAlign;
+ FX_FLOAT fTabstops;
+};
+class CXFA_TextTabstopsContext : public CFX_Object
+{
+public:
+ CXFA_TextTabstopsContext() : m_iTabCount(0), m_iTabIndex(-1), m_bTabstops(FALSE), m_fTabWidth(0), m_fLeft(0) {}
+ void Append(FX_DWORD dwAlign, FX_FLOAT fTabstops)
+ {
+ FX_INT32 i = 0;
+ for (i = 0; i < m_iTabCount; i++) {
+ XFA_TABSTOPS *pTabstop = m_tabstops.GetDataPtr(i);
+ if (fTabstops < pTabstop->fTabstops) {
+ break;
+ }
+ }
+ m_tabstops.InsertSpaceAt(i, 1);
+ XFA_TABSTOPS tabstop;
+ tabstop.dwAlign = dwAlign;
+ tabstop.fTabstops = fTabstops;
+ m_tabstops.SetAt(i, tabstop);
+ m_iTabCount++;
+ }
+ void RemoveAll()
+ {
+ m_tabstops.RemoveAll();
+ m_iTabCount = 0;
+ }
+ void Reset()
+ {
+ m_iTabIndex = -1;
+ m_bTabstops = FALSE;
+ m_fTabWidth = 0;
+ m_fLeft = 0;
+ }
+ CFX_ArrayTemplate<XFA_TABSTOPS> m_tabstops;
+ FX_INT32 m_iTabCount;
+ FX_INT32 m_iTabIndex;
+ FX_BOOL m_bTabstops;
+ FX_FLOAT m_fTabWidth;
+ FX_FLOAT m_fLeft;
+};
+class CXFA_TextLayout : public CFX_Object
+{
+public:
+ CXFA_TextLayout(IXFA_TextProvider *pTextProvider);
+ virtual ~CXFA_TextLayout();
+ FX_INT32 GetText(CFX_WideString &wsText);
+ FX_FLOAT GetLayoutHeight();
+ FX_FLOAT StartLayout(FX_FLOAT fWidth = -1);
+ FX_BOOL DoLayout(FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeight, FX_FLOAT fContentAreaHeight = -1, FX_FLOAT fTextHeight = -1);
+
+ FX_BOOL CalcSize(const CFX_SizeF &minSize, const CFX_SizeF &maxSize, CFX_SizeF &defaultSize);
+ FX_BOOL Layout(const CFX_SizeF &size, FX_FLOAT* fHeight = NULL);
+ void ItemBlocks(const CFX_RectF& rtText, FX_INT32 iBlockIndex);
+ FX_BOOL DrawString(CFX_RenderDevice *pFxDevice, const CFX_Matrix &tmDoc2Device, const CFX_RectF &rtClip, FX_INT32 iBlock = 0);
+
+ FX_BOOL IsLoaded() const
+ {
+ return m_pieceLines.GetSize() > 0;
+ }
+ void Unload();
+ const CXFA_PieceLineArray* GetPieceLines();
+private:
+ void GetTextDataNode();
+ IFDE_XMLNode* GetXMLContainerNode();
+ IFX_RTFBreak* CreateBreak(FX_BOOL bDefault);
+ void InitBreak(FX_FLOAT fLineWidth);
+ void InitBreak(IFDE_CSSComputedStyle *pStyle, FDE_CSSDISPLAY eDisplay, FX_FLOAT fLineWidth, IFDE_XMLNode *pXMLNode, IFDE_CSSComputedStyle *pParentStyle = NULL);
+ FX_BOOL Loader(const CFX_SizeF &szText, FX_FLOAT &fLinePos, FX_BOOL bSavePieces = TRUE);
+
+ void LoadText(CXFA_Node *pNode, const CFX_SizeF &szText, FX_FLOAT &fLinePos, FX_BOOL bSavePieces);
+ FX_BOOL LoadRichText(IFDE_XMLNode *pXMLNode, const CFX_SizeF &szText, FX_FLOAT &fLinePos, IFDE_CSSComputedStyle *pParentStyle, FX_BOOL bSavePieces, CXFA_LinkUserData* pLinkData = NULL, FX_BOOL bEndBreak = TRUE, FX_BOOL bIsOl = FALSE, FX_INT32 iLiCount = 0);
+
+ FX_BOOL AppendChar(const CFX_WideString &wsText, FX_FLOAT &fLinePos, FX_FLOAT fSpaceAbove, FX_BOOL bSavePieces);
+
+ void AppendTextLine(FX_DWORD dwStatus, FX_FLOAT &fLinePos, FX_BOOL bSavePieces, FX_BOOL bEndBreak = FALSE);
+ void EndBreak(FX_DWORD dwStatus, FX_FLOAT &fLinePos, FX_BOOL bDefault);
+ FX_BOOL IsEnd(FX_BOOL bSavePieces);
+
+ void ProcessText(CFX_WideString &wsText);
+ void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);
+
+ void RenderString(IFDE_RenderDevice *pDevice, IFDE_SolidBrush *pBrush, CXFA_PieceLine *pPieceLine,
+ FX_INT32 iPiece, FXTEXT_CHARPOS *pCharPos, const CFX_Matrix &tmDoc2Device);
+ void RenderPath(IFDE_RenderDevice *pDevice, IFDE_Pen *pPen, CXFA_PieceLine *pPieceLine, FX_INT32 iPiece,
+ FXTEXT_CHARPOS *pCharPos, const CFX_Matrix &tmDoc2Device);
+
+ FX_INT32 GetDisplayPos(XFA_LPCTEXTPIECE pPiece, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE);
+ FX_BOOL ToRun(XFA_LPCTEXTPIECE pPiece, FX_RTFTEXTOBJ &tr);
+
+ void DoTabstops(IFDE_CSSComputedStyle *pStyle, CXFA_PieceLine *pPieceLine);
+ FX_BOOL Layout(FX_INT32 iBlock);
+ FX_INT32 CountBlocks() const;
+ IXFA_TextProvider *m_pTextProvider;
+ CXFA_Node *m_pTextDataNode;
+ FX_BOOL m_bRichText;
+ IFX_MEMAllocator *m_pAllocator;
+ IFX_RTFBreak *m_pBreak;
+ FX_DWORD m_dwTextData;
+
+ CXFA_LoaderContext *m_pLoader;
+ FX_INT32 m_iLines;
+ FX_FLOAT m_fMaxWidth;
+
+ CXFA_TextParser m_textParser;
+ CXFA_PieceLineArray m_pieceLines;
+ CXFA_TextTabstopsContext *m_pTabstopContext;
+ FX_BOOL m_bBlockContinue;
+public:
+ FX_BOOL m_bHasBlock;
+ CFX_Int32Array m_Blocks;
+};
+#endif
diff --git a/xfa/src/fxfa/src/common/fxfa_localevalue.h b/xfa/src/fxfa/src/common/fxfa_localevalue.h
new file mode 100644
index 0000000000..7e4ceed134
--- /dev/null
+++ b/xfa/src/fxfa/src/common/fxfa_localevalue.h
@@ -0,0 +1,81 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_WIDGETVALUE_H
+#define _FXFA_WIDGETVALUE_H
+class IFX_Locale;
+class CFX_Unitime;
+class CXFA_LocaleMgr;
+#define XFA_VT_NULL 0
+#define XFA_VT_BOOLEAN 1
+#define XFA_VT_INTEGER 2
+#define XFA_VT_DECIMAL 4
+#define XFA_VT_FLOAT 8
+#define XFA_VT_TEXT 16
+#define XFA_VT_DATE 32
+#define XFA_VT_TIME 64
+#define XFA_VT_DATETIME 128
+class CXFA_LocaleValue : public CFX_Object
+{
+public:
+ CXFA_LocaleValue();
+ CXFA_LocaleValue(const CXFA_LocaleValue& value);
+ CXFA_LocaleValue(FX_DWORD dwType, CXFA_LocaleMgr* pLocaleMgr);
+ CXFA_LocaleValue(FX_DWORD dwType, const CFX_WideString& wsValue, CXFA_LocaleMgr* pLocaleMgr);
+ CXFA_LocaleValue(FX_DWORD dwType, const CFX_WideString& wsValue,
+ const CFX_WideString& wsFormat, IFX_Locale* pLocale, CXFA_LocaleMgr* pLocaleMgr);
+ ~CXFA_LocaleValue();
+ CXFA_LocaleValue& operator = (const CXFA_LocaleValue& value);
+
+ FX_BOOL ValidateValue(const CFX_WideString& wsValue, const CFX_WideString& wsPattern, IFX_Locale* pLocale, CFX_WideString* pMatchFormat = NULL);
+ FX_BOOL FormatPatterns(CFX_WideString& wsResult, const CFX_WideString& wsFormat, IFX_Locale* pLocale, XFA_VALUEPICTURE eValueType) const;
+ FX_BOOL FormatSinglePattern(CFX_WideString& wsResult, const CFX_WideString& wsFormat, IFX_Locale* pLocale, XFA_VALUEPICTURE eValueType) const;
+ FX_BOOL ValidateCanonicalValue(const CFX_WideString& wsValue, FX_DWORD dwVType);
+ FX_BOOL ValidateCanonicalDate(const CFX_WideString& wsDate, CFX_Unitime& unDate);
+ FX_BOOL ValidateCanonicalTime(const CFX_WideString& wsTime);
+ FX_BOOL ValidateCanonicalDateTime(const CFX_WideString& wsDateTime);
+ void GetNumbericFormat(CFX_WideString &wsFormat, FX_INT32 nIntLen, FX_INT32 nDecLen, FX_BOOL bSign = TRUE);
+ FX_BOOL ValidateNumericTemp(CFX_WideString& wsNumeric, CFX_WideString& wsFormat, IFX_Locale* pLocale = NULL, FX_INT32* pos = NULL);
+
+ CFX_WideString GetValue() const;
+ FX_DWORD GetType() const;
+ void SetValue(const CFX_WideString& wsValue, FX_DWORD dwType);
+ CFX_WideString GetText() const;
+ FX_FLOAT GetNum() const;
+ FX_DOUBLE GetDoubleNum() const;
+ CFX_Unitime GetDate() const;
+ CFX_Unitime GetTime() const;
+ CFX_Unitime GetDateTime() const;
+ FX_BOOL SetText(const CFX_WideString& wsText);
+ FX_BOOL SetText(const CFX_WideString& wsText, const CFX_WideString& wsFormat, IFX_Locale* pLocale);
+ FX_BOOL SetNum(FX_FLOAT fNum);
+ FX_BOOL SetNum(const CFX_WideString& wsNum, const CFX_WideString& wsFormat, IFX_Locale* pLocale);
+ FX_BOOL SetDate(const CFX_Unitime& d);
+ FX_BOOL SetDate(const CFX_WideString& wsDate, const CFX_WideString& wsFormat, IFX_Locale* pLocale);
+ FX_BOOL SetTime(const CFX_Unitime& t);
+ FX_BOOL SetTime(const CFX_WideString& wsTime, const CFX_WideString& wsFormat, IFX_Locale* pLocale);
+ FX_BOOL SetDateTime(const CFX_Unitime& dt);
+ FX_BOOL SetDateTime(const CFX_WideString& wsDateTime, const CFX_WideString& wsFormat, IFX_Locale* pLocale);
+ inline FX_BOOL IsNull() const
+ {
+ return m_dwType == XFA_VT_NULL;
+ }
+ inline FX_BOOL IsEmpty() const
+ {
+ return m_wsValue.IsEmpty();
+ }
+ inline FX_BOOL IsValid() const
+ {
+ return m_bValid;
+ }
+protected:
+ FX_BOOL ParsePatternValue(const CFX_WideString& wsValue, const CFX_WideString& wsPattern, IFX_Locale* pLocale);
+ CXFA_LocaleMgr* m_pLocaleMgr;
+ CFX_WideString m_wsValue;
+ FX_DWORD m_dwType;
+ FX_BOOL m_bValid;
+};
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_common.h b/xfa/src/fxfa/src/common/xfa_common.h
new file mode 100644
index 0000000000..b7bafa7505
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_common.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_COMMON_H_
+#define _XFA_COMMON_H_
+#include "xfa_utils.h"
+#include "xfa_object.h"
+#include "xfa_document.h"
+#include "xfa_parser.h"
+#include "xfa_script.h"
+#include "xfa_docdata.h"
+#include "xfa_doclayout.h"
+#include "xfa_debug.h"
+#include "xfa_localemgr.h"
+#include "xfa_fm2jsapi.h"
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_debug.h b/xfa/src/fxfa/src/common/xfa_debug.h
new file mode 100644
index 0000000000..dee70a688e
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_debug.h
@@ -0,0 +1,9 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_COMMON_DEBUG_H_
+#define _XFA_COMMON_DEBUG_H_
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_docdata.h b/xfa/src/fxfa/src/common/xfa_docdata.h
new file mode 100644
index 0000000000..9e9c8d1a12
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_docdata.h
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCDATA_H
+#define _XFA_DOCDATA_H
+enum XFA_DATAFORMAT {
+ XFA_DATAFORMAT_XDP,
+};
+class IXFA_PacketExport
+{
+public:
+ static IXFA_PacketExport* Create(CXFA_Document *pDocument, XFA_DATAFORMAT eFormat = XFA_DATAFORMAT_XDP);
+ virtual void Release() = 0;
+ virtual FX_BOOL Export(IFX_FileWrite *pWrite) = 0;
+ virtual FX_BOOL Export(IFX_FileWrite *pWrite, CXFA_Node *pNode, FX_DWORD dwFlag = 0, FX_LPCSTR pChecksum = NULL) = 0;
+};
+class IXFA_PacketImport
+{
+public:
+ static IXFA_PacketImport* Create(CXFA_Document *pDstDoc);
+ virtual void Release() = 0;
+ virtual FX_BOOL ImportData(IFX_FileRead* pDataDocument) = 0;
+};
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_doclayout.h b/xfa/src/fxfa/src/common/xfa_doclayout.h
new file mode 100644
index 0000000000..3d6df9f199
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_doclayout.h
@@ -0,0 +1,107 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCLAYOUT_H_
+#define _XFA_DOCLAYOUT_H_
+#define _XFA_LAYOUTITEM_ProcessCACHE_
+class CXFA_LayoutItem;
+class IXFA_LayoutPage;
+class CXFA_LayoutItem
+{
+public:
+ IXFA_LayoutPage* GetPage() const;
+ CXFA_Node* GetFormNode() const;
+ void GetRect(CFX_RectF &rtLayout, FX_BOOL bRelative = FALSE) const;
+ FX_INT32 GetIndex() const;
+ FX_INT32 GetCount() const;
+ CXFA_LayoutItem* GetParent() const;
+ CXFA_LayoutItem* GetFirst() const;
+ CXFA_LayoutItem* GetPrev() const;
+ CXFA_LayoutItem* GetNext() const;
+ CXFA_LayoutItem* GetLast() const;
+};
+class CXFA_LayoutItemImpl : public CFX_Object
+{
+public:
+ CXFA_LayoutItemImpl(CXFA_Node *pNode, FX_BOOL bIsContentLayoutItem);
+ virtual ~CXFA_LayoutItemImpl();
+ FX_BOOL IsContentLayoutItem()
+ {
+ return m_bIsContentLayoutItem;
+ }
+ void AddChild(CXFA_LayoutItemImpl *pChildItem);
+ void AddHeadChild(CXFA_LayoutItemImpl *pChildItem);
+ void RemoveChild(CXFA_LayoutItemImpl *pChildItem);
+ void InsertChild(CXFA_LayoutItemImpl *pBeforeItem, CXFA_LayoutItemImpl *pChildItem);
+public:
+ CXFA_Node* m_pFormNode;
+ CXFA_LayoutItemImpl* m_pParent;
+ CXFA_LayoutItemImpl* m_pNextSibling;
+ CXFA_LayoutItemImpl* m_pFirstChild;
+ FX_BOOL m_bIsContentLayoutItem;
+};
+class CXFA_ContainerLayoutItemImpl : public CXFA_LayoutItemImpl
+{
+public:
+ CXFA_ContainerLayoutItemImpl(CXFA_Node *pNode);
+public:
+ CXFA_Node* m_pOldSubform;
+};
+#define XFA_WIDGETSTATUS_Access 0x80000000
+#define XFA_WIDGETSTATUS_Disabled 0x40000000
+#define XFA_WIDGETSTATUS_RectCached 0x20000000
+#define XFA_WIDGETSTATUS_ButtonDown 0x10000000
+#define XFA_WIDGETSTATUS_Highlight 0x08000000
+#define XFA_WIDGETSTATUS_TextEditValueChanged 0x04000000
+class CXFA_ContentLayoutItemImpl : public CXFA_LayoutItemImpl
+{
+public:
+ CXFA_ContentLayoutItemImpl(CXFA_Node *pNode);
+ virtual ~CXFA_ContentLayoutItemImpl();
+public:
+ CXFA_ContentLayoutItemImpl* m_pPrev;
+ CXFA_ContentLayoutItemImpl* m_pNext;
+ CFX_PointF m_sPos;
+ CFX_SizeF m_sSize;
+ FX_DWORD m_dwStatus;
+};
+class CXFA_TraverseStrategy_LayoutItem
+{
+public:
+ static inline CXFA_LayoutItem* GetFirstChild(CXFA_LayoutItem* pLayoutItem)
+ {
+ return (CXFA_LayoutItem*)((CXFA_LayoutItemImpl*)pLayoutItem)->m_pFirstChild;
+ }
+ static inline CXFA_LayoutItem* GetNextSibling(CXFA_LayoutItem* pLayoutItem)
+ {
+ return (CXFA_LayoutItem*)((CXFA_LayoutItemImpl*)pLayoutItem)->m_pNextSibling;
+ }
+ static inline CXFA_LayoutItem* GetParent(CXFA_LayoutItem* pLayoutItem)
+ {
+ return (CXFA_LayoutItem*)((CXFA_LayoutItemImpl*)pLayoutItem)->m_pParent;
+ }
+};
+class IXFA_LayoutPage
+{
+public:
+ IXFA_DocLayout* GetLayout() const;
+ FX_INT32 GetPageIndex() const;
+ void GetPageSize(CFX_SizeF &size);
+ CXFA_Node* GetMasterPage() const;
+};
+class IXFA_DocLayout
+{
+public:
+ virtual CXFA_Document* GetDocument() const = 0;
+ virtual FX_INT32 StartLayout(FX_BOOL bForceRestart = FALSE) = 0;
+ virtual FX_INT32 DoLayout(IFX_Pause *pPause = NULL) = 0;
+ virtual FX_BOOL IncrementLayout() = 0;
+ virtual FX_INT32 CountPages() const = 0;
+ virtual IXFA_LayoutPage* GetPage(FX_INT32 index) const = 0;
+
+ virtual CXFA_LayoutItem* GetLayoutItem(CXFA_Node *pFormItem) = 0;
+};
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_document.h b/xfa/src/fxfa/src/common/xfa_document.h
new file mode 100644
index 0000000000..502aa2591a
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_document.h
@@ -0,0 +1,177 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCUMENT_H
+#define _XFA_DOCUMENT_H
+class IXFA_DocParser;
+class CXFA_LayoutProcessor;
+class IXFA_DocLayout;
+class IXFA_LayoutPage;
+class CXFA_LayoutItem;
+class IXFA_PageContent;
+class IXFA_ScriptContext;
+class CXFA_Node;
+class IXFA_Notify;
+class IXFA_ObjFactory;
+class CXFA_Document;
+enum XFA_VERSION {
+ XFA_VERSION_UNKNOWN = 0,
+ XFA_VERSION_200 = 200,
+ XFA_VERSION_202 = 202,
+ XFA_VERSION_204 = 204,
+ XFA_VERSION_205 = 205,
+ XFA_VERSION_206 = 206,
+ XFA_VERSION_207 = 207,
+ XFA_VERSION_208 = 208,
+ XFA_VERSION_300 = 300,
+ XFA_VERSION_301 = 301,
+ XFA_VERSION_303 = 303,
+ XFA_VERSION_306 = 306,
+ XFA_VERSION_DEFAULT = XFA_VERSION_303,
+ XFA_VERSION_MIN = 200,
+ XFA_VERSION_MAX = 400,
+};
+#define XFA_LAYOUTSTATUS_Visible 0x0001
+#define XFA_LAYOUTSTATUS_Viewable 0x0010
+#define XFA_LAYOUTSTATUS_Printable 0x0020
+enum XFA_NODEEVENT {
+ XFA_NODEEVENT_Ready,
+ XFA_NODEEVENT_ValueChanging,
+ XFA_NODEEVENT_ValueChanged,
+ XFA_NODEEVENT_ChildAdded,
+ XFA_NODEEVENT_ChildRemoved,
+};
+enum XFA_PAGEEVENT {
+ XFA_PAGEEVENT_PageAdded,
+ XFA_PAGEEVENT_PageRemoved,
+};
+enum XFA_LAYOUTEVENT {
+ XFA_LAYOUTEVENT_ItemAdded,
+ XFA_LAYOUTEVENT_ItemRemoving,
+ XFA_LAYOUTEVENT_RectChanged,
+ XFA_LAYOUTEVENT_StatusChanged,
+};
+enum XFA_LAYOUTRESULT {
+ XFA_LAYOUTRESULT_Continue,
+ XFA_LAYOUTRESULT_Done,
+ XFA_LAYOUTRESULT_NextContent,
+};
+#define XFA_LAYOUTNOTIFY_StrictHeight 0x0001
+#define XFA_LAYOUTNOTIFY_NoParentBreak 0x0002
+class IXFA_Notify
+{
+public:
+ virtual void OnPageEvent(IXFA_LayoutPage *pSender, XFA_PAGEEVENT eEvent, FX_LPVOID pParam = NULL) = 0;
+
+ virtual void OnNodeEvent(CXFA_Node *pSender, XFA_NODEEVENT eEvent, FX_LPVOID pParam = NULL, FX_LPVOID pParam2 = NULL, FX_LPVOID pParam3 = NULL, FX_LPVOID pParam4 = NULL) = 0;
+ virtual void OnWidgetDataEvent(CXFA_WidgetData* pSender, FX_DWORD dwEvent, FX_LPVOID pParam = NULL, FX_LPVOID pAdditional = NULL, FX_LPVOID pAdditional2 = NULL) = 0;
+
+ virtual CXFA_LayoutItem* OnCreateLayoutItem(CXFA_Node *pNode) = 0;
+ virtual void OnLayoutEvent(IXFA_DocLayout *pLayout, CXFA_LayoutItem *pSender, XFA_LAYOUTEVENT eEvent, FX_LPVOID pParam = NULL, FX_LPVOID pParam2 = NULL) = 0;
+ virtual void StartFieldDrawLayout(CXFA_Node *pItem, FX_FLOAT &fCalcWidth, FX_FLOAT &fCalcHeight) = 0;
+ virtual FX_BOOL FindSplitPos(CXFA_Node *pItem, FX_INT32 iBlockIndex, FX_FLOAT &fCalcHeightPos) = 0;
+ virtual FX_BOOL RunScript(CXFA_Node* pScript, CXFA_Node* pFormItem) = 0;
+ virtual FX_INT32 ExecEventByDeepFirst(CXFA_Node* pFormNode, XFA_EVENTTYPE eEventType, FX_BOOL bIsFormReady = FALSE, FX_BOOL bRecursive = TRUE, CXFA_WidgetAcc* pExclude = NULL) = 0;
+ virtual void AddCalcValidate(CXFA_Node* pNode) = 0;
+ virtual XFA_HDOC GetHDOC() = 0;
+ virtual IXFA_DocProvider* GetDocProvider() = 0;
+ virtual IXFA_AppProvider* GetAppProvider() = 0;
+ virtual IXFA_WidgetHandler* GetWidgetHandler() = 0;
+ virtual XFA_HWIDGET GetHWidget(CXFA_LayoutItem* pLayoutItem) = 0;
+ virtual void OpenDropDownList(XFA_HWIDGET hWidget) = 0;
+ virtual CFX_WideString GetCurrentDateTime() = 0;
+ virtual void ResetData(CXFA_WidgetData* pWidgetData = NULL) = 0;
+ virtual FX_INT32 GetLayoutStatus() = 0;
+ virtual void RunNodeInitialize(CXFA_Node* pNode) = 0;
+ virtual void RunSubformIndexChange(CXFA_Node* pSubformNode) = 0;
+ virtual CXFA_Node* GetFocusWidgetNode() = 0;
+ virtual void SetFocusWidgetNode(CXFA_Node* pNode) = 0;
+};
+class IXFA_ObjFactory
+{
+public:
+ virtual CXFA_Node* CreateNode(FX_DWORD dwPacket, XFA_ELEMENT eElement) = 0;
+ virtual CXFA_Node* CreateNode(XFA_LPCPACKETINFO pPacket, XFA_ELEMENT eElement) = 0;
+};
+#define XFA_DOCFLAG_StrictScoping 0x0001
+#define XFA_DOCFLAG_HasInteractive 0x0002
+#define XFA_DOCFLAG_Interactive 0x0004
+#define XFA_DOCFLAG_Scripting 0x0008
+class CScript_DataWindow;
+class CScript_EventPseudoModel;
+class CScript_HostPseudoModel;
+class CScript_LogPseudoModel;
+class CScript_LayoutPseudoModel;
+class CScript_SignaturePseudoModel;
+class CXFA_Document : public IXFA_ObjFactory, public CFX_Object
+{
+public:
+ CXFA_Document(IXFA_DocParser *pParser);
+ ~CXFA_Document();
+ CXFA_Node* GetRoot() const
+ {
+ return m_pRootNode;
+ }
+ IXFA_DocParser* GetParser() const
+ {
+ return m_pParser;
+ }
+ IXFA_Notify* GetNotify() const;
+ void SetRoot(CXFA_Node* pNewRoot);
+ CXFA_Object* GetXFANode(FX_WSTR wsNodeName);
+ CXFA_Object* GetXFANode(FX_DWORD wsNodeNameHash);
+ void AddPurgeNode(CXFA_Node *pNode);
+ FX_BOOL RemovePurgeNode(CXFA_Node *pNode);
+ void PurgeNodes();
+ FX_BOOL HasFlag(FX_DWORD dwFlag)
+ {
+ return (m_dwDocFlags & dwFlag) == dwFlag;
+ }
+ void SetFlag(FX_DWORD dwFlag, FX_BOOL bOn = TRUE);
+ FX_BOOL IsInteractive();
+ XFA_VERSION GetCurVersionMode()
+ {
+ return m_eCurVersionMode;
+ }
+ XFA_VERSION RecognizeXFAVersionNumber(CFX_WideString& wsTemplateNS);
+ CXFA_LocaleMgr* GetLocalMgr();
+ virtual CXFA_Node* CreateNode(FX_DWORD dwPacket, XFA_ELEMENT eElement);
+ virtual CXFA_Node* CreateNode(XFA_LPCPACKETINFO pPacket, XFA_ELEMENT eElement);
+ void DoProtoMerge();
+ CXFA_Node* GetNodeByID(CXFA_Node* pRoot, FX_WSTR wsID);
+
+ void DoDataMerge();
+ void DoDataRemerge(FX_BOOL bDoDataMerge);
+ CXFA_Node* DataMerge_CopyContainer(CXFA_Node* pTemplateNode, CXFA_Node* pFormNode, CXFA_Node* pDataScope, FX_BOOL bOneInstance = FALSE, FX_BOOL bDataMerge = TRUE, FX_BOOL bUpLevel = TRUE);
+ void DataMerge_UpdateBindingRelations(CXFA_Node* pFormUpdateRoot);
+ CXFA_Node* GetNotBindNode(CXFA_ObjArray& arrayNodes);
+ CXFA_LayoutProcessor* GetLayoutProcessor();
+ IXFA_DocLayout* GetDocLayout();
+ IXFA_ScriptContext* InitScriptContext(FXJSE_HRUNTIME hRuntime);
+ IXFA_ScriptContext* GetScriptContext();
+ void ClearLayoutData();
+public:
+ CFX_MapPtrTemplate<FX_DWORD, CXFA_Node*> m_rgGlobalBinding;
+ CXFA_NodeArray m_pPendingPageSet;
+protected:
+ IXFA_DocParser* m_pParser;
+ IXFA_ScriptContext* m_pScriptContext;
+ CXFA_LayoutProcessor* m_pLayoutProcessor;
+ CXFA_Node* m_pRootNode;
+
+ CXFA_LocaleMgr* m_pLocalMgr;
+ CScript_DataWindow* m_pScriptDataWindow;
+ CScript_EventPseudoModel* m_pScriptEvent;
+ CScript_HostPseudoModel* m_pScriptHost;
+ CScript_LogPseudoModel* m_pScriptLog;
+ CScript_LayoutPseudoModel* m_pScriptLayout;
+ CScript_SignaturePseudoModel* m_pScriptSignature;
+ CXFA_NodeSet m_rgPurgeNodes;
+ XFA_VERSION m_eCurVersionMode;
+ FX_DWORD m_dwDocFlags;
+ friend class CXFA_SimpleParser;
+};
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_fm2jsapi.h b/xfa/src/fxfa/src/common/xfa_fm2jsapi.h
new file mode 100644
index 0000000000..499ceca4e3
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_fm2jsapi.h
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM2JS_API_H
+#define _XFA_FM2JS_API_H
+#define FOXIT_XFA_FM2JS_FORMCALC_RUNTIME "foxit_xfa_formcalc_runtime"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+FX_DEFINEHANDLE(XFA_HFM2JSCONTEXT)
+FX_INT32 XFA_FM2JS_Translate(FX_WSTR wsFormcalc, CFX_WideTextBuf& wsJavascript, CFX_WideString& wsError);
+XFA_HFM2JSCONTEXT XFA_FM2JS_ContextCreate();
+void XFA_FM2JS_ContextInitialize(XFA_HFM2JSCONTEXT hFM2JSContext, FXJSE_HRUNTIME hScriptRuntime,
+ FXJSE_HCONTEXT hScriptContext,
+ CXFA_Document* pDocument);
+void XFA_FM2JS_GlobalPropertyGetter(XFA_HFM2JSCONTEXT hFM2JSContext, FXJSE_HVALUE hValue);
+void XFA_FM2JS_ContextRelease(XFA_HFM2JSCONTEXT hFM2JSContext);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_localemgr.h b/xfa/src/fxfa/src/common/xfa_localemgr.h
new file mode 100644
index 0000000000..f425a903fc
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_localemgr.h
@@ -0,0 +1,69 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_LOCALEMGR_H
+#define _FXFA_LOCALEMGR_H
+class CXFA_Node;
+class IFX_Locale;
+class IFX_LocaleMgr;
+class CXFA_LocaleMgr;
+#define XFA_LANGID_zh_CN 0x0804
+#define XFA_LANGID_zh_TW 0x0404
+#define XFA_LANGID_zh_HK 0x0c04
+#define XFA_LANGID_ja_JP 0x0411
+#define XFA_LANGID_ko_KR 0x0412
+#define XFA_LANGID_en_US 0x0409
+#define XFA_LANGID_en_GB 0x0809
+#define XFA_LANGID_es_ES 0x0c0a
+#define XFA_LANGID_es_LA 0x080a
+#define XFA_LANGID_de_DE 0x0407
+#define XFA_LANGID_fr_FR 0x040c
+#define XFA_LANGID_it_IT 0x0410
+#define XFA_LANGID_pt_BR 0x0416
+#define XFA_LANGID_nl_NL 0x0413
+#define XFA_LANGID_ru_RU 0x0419
+class CXFA_LocaleMgr : public IFX_LocaleMgr, public CFX_Object
+{
+public:
+ CXFA_LocaleMgr(CXFA_Node* pLocaleSet, CFX_WideString wsDeflcid);
+ virtual void Release();
+ virtual FX_WORD GetDefLocaleID();
+ virtual IFX_Locale* GetDefLocale();
+ virtual IFX_Locale* GetLocale(FX_WORD lcid);
+ virtual IFX_Locale* GetLocaleByName(FX_WSTR wsLocaleName);
+ ~CXFA_LocaleMgr();
+ void SetDefLocale(IFX_Locale* pLocale);
+ CFX_WideStringC GetConfigLocaleName(CXFA_Node* pConfig);
+protected:
+ CFX_PtrArray m_LocaleArray;
+ CFX_PtrArray m_XMLLocaleArray;
+ IFX_Locale* m_pDefLocale;
+ CFX_WideString m_wsConfigLocale;
+ FX_WORD m_dwDeflcid;
+ FX_WORD m_dwLocaleFlags;
+};
+class IXFA_TimeZoneProvider
+{
+public:
+ static IXFA_TimeZoneProvider* Create();
+ static IXFA_TimeZoneProvider* Get();
+ static void Destroy();
+
+ virtual void SetTimeZone(FX_TIMEZONE& tz) = 0;
+
+ virtual void GetTimeZone(FX_TIMEZONE& tz) = 0;
+};
+class CXFA_TimeZoneProvider : public IXFA_TimeZoneProvider, public CFX_Object
+{
+public:
+ CXFA_TimeZoneProvider();
+ ~CXFA_TimeZoneProvider();
+ virtual void SetTimeZone(FX_TIMEZONE& tz);
+ virtual void GetTimeZone(FX_TIMEZONE& tz);
+private:
+ FX_TIMEZONE m_tz;
+};
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_object.h b/xfa/src/fxfa/src/common/xfa_object.h
new file mode 100644
index 0000000000..c285b9d902
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_object.h
@@ -0,0 +1,588 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_OBJECT_H_
+#define _XFA_OBJECT_H_
+class CXFA_Document;
+class IXFA_ObjFactory;
+class IXFA_Notify;
+class CXFA_Object;
+class CXFA_OrdinaryObject;
+class CXFA_Node;
+class CXFA_NodeList;
+class CXFA_ArrayNodeList;
+class CXFA_AttachNodeList;
+enum XFA_OBJECTTYPE {
+ XFA_OBJECTTYPE_OrdinaryObject = 0x0,
+ XFA_OBJECTTYPE_OrdinaryList = 0x1,
+ XFA_OBJECTTYPE_NodeList = 0x2,
+ XFA_OBJECTTYPE_Node = 0x4,
+ XFA_OBJECTTYPE_NodeC = 0x5,
+ XFA_OBJECTTYPE_NodeV = 0x6,
+ XFA_OBJECTTYPE_ModelNode = 0x8,
+ XFA_OBJECTTYPE_TextNode = 0x9,
+ XFA_OBJECTTYPE_ContainerNode = 0xA,
+ XFA_OBJECTTYPE_ContentNode = 0xB,
+ XFA_OBJECTTYPE_VariablesThis = 0xC,
+ XFA_OBJECTTYPEMASK = 0xF,
+ XFA_NODEFLAG_Initialized = 0x00020,
+ XFA_NODEFLAG_HasRemoved = 0x00200,
+ XFA_NODEFLAG_NeedsInitApp = 0x00400,
+ XFA_NODEFLAG_BindFormItems = 0x00800,
+ XFA_NODEFLAG_UserInteractive = 0x01000,
+ XFA_NODEFLAG_SkipDataBinding = 0x02000,
+ XFA_NODEFLAG_OwnXMLNode = 0x04000,
+ XFA_NODEFLAG_UnusedNode = 0x08000,
+ XFA_NODEFLAG_LayoutGeneratedNode = 0x10000,
+};
+class CXFA_Object : public CFX_Object
+{
+public:
+ CXFA_Object(CXFA_Document* pDocument, FX_DWORD uFlags);
+ inline CXFA_Document* GetDocument() const
+ {
+ return m_pDocument;
+ }
+ inline FX_DWORD GetFlag() const
+ {
+ return m_uFlags;
+ }
+ inline XFA_OBJECTTYPE GetObjectType() const
+ {
+ return (XFA_OBJECTTYPE)(m_uFlags & XFA_OBJECTTYPEMASK);
+ }
+ inline FX_BOOL IsNode() const
+ {
+ return (m_uFlags & XFA_OBJECTTYPEMASK) >= XFA_OBJECTTYPE_Node;
+ }
+ inline FX_BOOL IsOrdinaryObject() const
+ {
+ return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_OrdinaryObject;
+ }
+ inline FX_BOOL IsNodeList() const
+ {
+ return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_NodeList;
+ }
+ inline FX_BOOL IsOrdinaryList() const
+ {
+ return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_OrdinaryList;
+ }
+ FX_BOOL IsContentNode() const
+ {
+ return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_ContentNode;
+ }
+ FX_BOOL IsContainerNode() const
+ {
+ return (m_uFlags & XFA_OBJECTTYPEMASK) == XFA_OBJECTTYPE_ContainerNode;
+ }
+ XFA_ELEMENT GetClassID() const;
+ void GetClassName(CFX_WideStringC &wsName) const;
+ FX_UINT32 GetClassHashCode() const;
+ void Script_ObjectClass_ClassName(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void ThrowScriptErrorMessage(FX_INT32 iStringID, ...);
+protected:
+ CXFA_Document *m_pDocument;
+ FX_DWORD m_uFlags;
+};
+#define XFA_NODEFILTER_Children 0x01
+#define XFA_NODEFILTER_Properties 0x02
+#define XFA_NODEFILTER_OneOfProperty 0x04
+#define XFA_CLONEFLAG_Content 0x01
+enum XFA_NODEITEM {
+ XFA_NODEITEM_Parent,
+ XFA_NODEITEM_FirstChild,
+ XFA_NODEITEM_NextSibling,
+ XFA_NODEITEM_PrevSibling,
+};
+enum XFA_SOM_MESSAGETYPE {
+ XFA_SOM_ValidationMessage,
+ XFA_SOM_FormatMessage,
+ XFA_SOM_MandatoryMessage
+};
+typedef CFX_StackTemplate<CXFA_Node*> CXFA_NodeStack;
+typedef CXFA_PtrSetTemplate<CXFA_Node*> CXFA_NodeSet;
+typedef void (*PD_CALLBACK_DUPLICATEDATA)(FX_LPVOID& pData);
+typedef struct _XFA_MAPDATABLOCKCALLBACKINFO {
+ PD_CALLBACK_FREEDATA pFree;
+ PD_CALLBACK_DUPLICATEDATA pCopy;
+} XFA_MAPDATABLOCKCALLBACKINFO;
+typedef struct _XFA_MAPDATABLOCK : public CFX_Object {
+ FX_LPBYTE GetData() const
+ {
+ return (FX_LPBYTE)this + sizeof(_XFA_MAPDATABLOCK);
+ }
+ XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo;
+ FX_INT32 iBytes;
+} XFA_MAPDATABLOCK, * XFA_LPMAPDATABLOCK;
+typedef struct _XFA_MAPMODULEDATA : public CFX_Object {
+ CFX_MapPtrToPtr m_ValueMap;
+ CFX_MapPtrTemplate<FX_LPVOID, XFA_LPMAPDATABLOCK> m_BufferMap;
+} XFA_MAPMODULEDATA, * XFA_LPMAPMODULEDATA;
+#define XFA_CalcRefCount (FX_LPVOID)(FX_UINTPTR)FXBSTR_ID('X', 'F', 'A', 'R')
+#define XFA_CalcData (FX_LPVOID)(FX_UINTPTR)FXBSTR_ID('X', 'F', 'A', 'C')
+#define XFA_LAYOUTITEMKEY (FX_LPVOID)(FX_UINTPTR)FXBSTR_ID('L', 'Y', 'I', 'M')
+class CXFA_Node : public CXFA_Object
+{
+public:
+ XFA_ELEMENT GetClassID() const
+ {
+ return (XFA_ELEMENT)m_eNodeClass;
+ }
+ FX_DWORD GetPacketID() const
+ {
+ return m_ePacket;
+ }
+ FX_BOOL HasFlag(FX_DWORD dwFlag) const;
+ void SetFlag(FX_DWORD dwFlag, FX_BOOL bOn = TRUE, FX_BOOL bNotify = TRUE);
+ FX_BOOL IsAttributeInXML();
+ FX_BOOL IsFormContainer()
+ {
+ return m_ePacket == XFA_XDPPACKET_Form && IsContainerNode();
+ }
+ void SetXMLMappingNode(IFDE_XMLNode* pXMLNode)
+ {
+ m_pXMLNode = pXMLNode;
+ }
+ IFDE_XMLNode* GetXMLMappingNode() const
+ {
+ return m_pXMLNode;
+ }
+ IFDE_XMLNode* CreateXMLMappingNode();
+ FX_BOOL IsNeedSavingXMLNode();
+ inline FX_DWORD GetNameHash() const
+ {
+ return m_dwNameHash;
+ }
+ inline FX_BOOL IsUnnamed() const
+ {
+ return m_dwNameHash == 0;
+ }
+ CXFA_Node* GetModelNode();
+ void UpdateNameHash();
+ FX_BOOL HasAttribute(XFA_ATTRIBUTE eAttr, FX_BOOL bCanInherit = FALSE);
+ FX_BOOL SetAttribute(XFA_ATTRIBUTE eAttr, FX_WSTR wsValue, FX_BOOL bNotify = FALSE);
+ FX_BOOL GetAttribute(XFA_ATTRIBUTE eAttr, CFX_WideString &wsValue, FX_BOOL bUseDefault = TRUE);
+ FX_BOOL SetAttribute(FX_WSTR wsAttr, FX_WSTR wsValue, FX_BOOL bNotify = FALSE);
+ FX_BOOL GetAttribute(FX_WSTR wsAttr, CFX_WideString &wsValue, FX_BOOL bUseDefault = TRUE);
+ FX_BOOL RemoveAttribute(FX_WSTR wsAttr);
+ FX_BOOL SetContent(const CFX_WideString& wsContent, const CFX_WideString& wsXMLValue, FX_BOOL bNotify = FALSE, FX_BOOL bScriptModify = FALSE, FX_BOOL bSyncData = TRUE);
+ FX_BOOL TryContent(CFX_WideString& wsContent, FX_BOOL bScriptModify = FALSE, FX_BOOL bProto = TRUE);
+ CFX_WideString GetContent();
+
+ FX_BOOL TryNamespace(CFX_WideString& wsNamespace);
+
+ FX_BOOL SetBoolean(XFA_ATTRIBUTE eAttr, FX_BOOL bValue, FX_BOOL bNotify = FALSE)
+ {
+ return SetValue(eAttr, XFA_ATTRIBUTETYPE_Boolean, (FX_LPVOID)(FX_UINTPTR)bValue, bNotify);
+ }
+ FX_BOOL TryBoolean(XFA_ATTRIBUTE eAttr, FX_BOOL &bValue, FX_BOOL bUseDefault = TRUE);
+ FX_BOOL GetBoolean(XFA_ATTRIBUTE eAttr)
+ {
+ FX_BOOL bValue;
+ return TryBoolean(eAttr, bValue, TRUE) ? bValue : FALSE;
+ }
+ FX_BOOL SetInteger(XFA_ATTRIBUTE eAttr, FX_INT32 iValue, FX_BOOL bNotify = FALSE)
+ {
+ return SetValue(eAttr, XFA_ATTRIBUTETYPE_Integer, (FX_LPVOID)(FX_UINTPTR)iValue, bNotify);
+ }
+ FX_BOOL TryInteger(XFA_ATTRIBUTE eAttr, FX_INT32 &iValue, FX_BOOL bUseDefault = TRUE);
+ FX_INT32 GetInteger(XFA_ATTRIBUTE eAttr)
+ {
+ FX_INT32 iValue;
+ return TryInteger(eAttr, iValue, TRUE) ? iValue : 0;
+ }
+ FX_BOOL SetEnum(XFA_ATTRIBUTE eAttr, XFA_ATTRIBUTEENUM eValue, FX_BOOL bNotify = FALSE)
+ {
+ return SetValue(eAttr, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)(FX_UINTPTR)eValue, bNotify);
+ }
+ FX_BOOL TryEnum(XFA_ATTRIBUTE eAttr, XFA_ATTRIBUTEENUM &eValue, FX_BOOL bUseDefault = TRUE);
+ XFA_ATTRIBUTEENUM GetEnum(XFA_ATTRIBUTE eAttr)
+ {
+ XFA_ATTRIBUTEENUM eValue;
+ return TryEnum(eAttr, eValue, TRUE) ? eValue : XFA_ATTRIBUTEENUM_Unknown;
+ }
+ FX_BOOL SetCData(XFA_ATTRIBUTE eAttr, const CFX_WideString& wsValue, FX_BOOL bNotify = FALSE, FX_BOOL bScriptModify = FALSE);
+ FX_BOOL SetAttributeValue(const CFX_WideString& wsValue, const CFX_WideString& wsXMLValue, FX_BOOL bNotify = FALSE, FX_BOOL bScriptModify = FALSE);
+ FX_BOOL TryCData(XFA_ATTRIBUTE eAttr, CFX_WideString &wsValue, FX_BOOL bUseDefault = TRUE, FX_BOOL bProto = TRUE);
+ FX_BOOL TryCData(XFA_ATTRIBUTE eAttr, CFX_WideStringC &wsValue, FX_BOOL bUseDefault = TRUE, FX_BOOL bProto = TRUE);
+ CFX_WideStringC GetCData(XFA_ATTRIBUTE eAttr)
+ {
+ CFX_WideStringC wsValue;
+ return TryCData(eAttr, wsValue) ? wsValue : CFX_WideStringC();
+ }
+ FX_BOOL SetMeasure(XFA_ATTRIBUTE eAttr, CXFA_Measurement mValue, FX_BOOL bNotify = FALSE);
+ FX_BOOL TryMeasure(XFA_ATTRIBUTE eAttr, CXFA_Measurement &mValue, FX_BOOL bUseDefault = TRUE);
+ CXFA_Measurement GetMeasure(XFA_ATTRIBUTE eAttr)
+ {
+ CXFA_Measurement mValue;
+ return TryMeasure(eAttr, mValue, TRUE) ? mValue : CXFA_Measurement();
+ }
+ FX_BOOL SetObject(XFA_ATTRIBUTE eAttr, FX_LPVOID pData, XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo = NULL);
+ FX_BOOL TryObject(XFA_ATTRIBUTE eAttr, FX_LPVOID &pData);
+ FX_LPVOID GetObject(XFA_ATTRIBUTE eAttr)
+ {
+ FX_LPVOID pData;
+ return TryObject(eAttr, pData) ? pData : NULL;
+ }
+ FX_BOOL SetUserData(FX_LPVOID pKey, FX_LPVOID pData, XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo = NULL);
+ FX_BOOL TryUserData(FX_LPVOID pKey, FX_LPVOID &pData, FX_BOOL bProtoAlso = FALSE);
+ FX_LPVOID GetUserData(FX_LPVOID pKey, FX_BOOL bProtoAlso = FALSE)
+ {
+ FX_LPVOID pData;
+ return TryUserData(pKey, pData, bProtoAlso) ? pData : NULL;
+ }
+ CXFA_Node* GetProperty(FX_INT32 index, XFA_ELEMENT eProperty, FX_BOOL bCreateProperty = TRUE);
+ FX_INT32 CountChildren(XFA_ELEMENT eElement, FX_BOOL bOnlyChild = FALSE);
+ CXFA_Node* GetChild(FX_INT32 index, XFA_ELEMENT eElement, FX_BOOL bOnlyChild = FALSE);
+ FX_INT32 InsertChild(FX_INT32 index, CXFA_Node *pNode);
+ FX_BOOL InsertChild(CXFA_Node *pNode, CXFA_Node* pBeforeNode = NULL);
+ FX_BOOL RemoveChild(CXFA_Node *pNode, FX_BOOL bNotify = TRUE);
+ CXFA_Node* Clone(FX_BOOL bRecursive);
+ CXFA_Node* GetNodeItem(XFA_NODEITEM eItem) const;
+ CXFA_Node* GetNodeItem(XFA_NODEITEM eItem, XFA_OBJECTTYPE eType) const;
+ FX_INT32 GetNodeList(CXFA_NodeArray &nodes, FX_DWORD dwTypeFilter = XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties, XFA_ELEMENT eElementFilter = XFA_ELEMENT_UNKNOWN, FX_INT32 iLevel = 1);
+ CXFA_Node* CreateSamePacketNode(XFA_ELEMENT eElement, FX_DWORD dwFlags = XFA_NODEFLAG_Initialized);
+ CXFA_Node* CloneTemplateToForm(FX_BOOL bRecursive);
+ CXFA_Node* GetTemplateNode();
+ void SetTemplateNode(CXFA_Node* pTemplateNode);
+ CXFA_Node* GetDataDescriptionNode();
+ void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode);
+ CXFA_Node* GetBindData();
+ FX_INT32 GetBindItems(CXFA_NodeArray& formItems);
+ FX_INT32 AddBindItem(CXFA_Node* pFormNode);
+ FX_INT32 RemoveBindItem(CXFA_Node* pFormNode);
+ FX_BOOL HasBindItem();
+ CXFA_WidgetData* GetWidgetData();
+ CXFA_WidgetData* GetContainerWidgetData();
+ FX_BOOL GetLocaleName(CFX_WideString& wsLocaleName);
+ XFA_ATTRIBUTEENUM GetIntact();
+ CXFA_Node* GetFirstChildByName(FX_WSTR wsNodeName) const;
+ CXFA_Node* GetFirstChildByName(FX_DWORD dwNodeNameHash) const;
+ CXFA_Node* GetFirstChildByClass(XFA_ELEMENT eNodeClass) const;
+ CXFA_Node* GetNextSameNameSibling(FX_DWORD dwNodeNameHash) const;
+ CXFA_Node* GetNextSameNameSibling(FX_WSTR wsNodeName) const;
+ CXFA_Node* GetNextSameClassSibling(XFA_ELEMENT eNodeClass) const;
+ FX_INT32 GetNodeSameNameIndex() const;
+ FX_INT32 GetNodeSameClassIndex() const;
+ void GetSOMExpression(CFX_WideString& wsSOMExpression);
+ CXFA_Node* GetInstanceMgrOfSubform();
+
+
+ CXFA_Node* GetOccurNode();
+ void Script_TreeClass_ResolveNode(CFXJSE_Arguments* pArguments);
+ void Script_TreeClass_ResolveNodes(CFXJSE_Arguments* pArguments);
+ void Script_Som_ResolveNodeList(FXJSE_HVALUE hValue, CFX_WideString wsExpression, FX_DWORD dwFlag, CXFA_Node* refNode = NULL);
+ void Script_TreeClass_All(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_TreeClass_Nodes(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_TreeClass_ClassAll(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_TreeClass_Parent(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_TreeClass_Index(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_TreeClass_ClassIndex(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_TreeClass_SomExpression(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_NodeClass_ApplyXSL(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_AssignNode(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_Clone(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_GetAttribute(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_GetElement(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_IsPropertySpecified(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_LoadXML(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_SaveXML(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_SetAttribute(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_SetElement(CFXJSE_Arguments* pArguments);
+ void Script_NodeClass_Ns(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_NodeClass_Model(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_NodeClass_IsContainer(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_NodeClass_IsNull(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_NodeClass_OneOfChild(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_ContainerClass_GetDelta(CFXJSE_Arguments* pArguments);
+ void Script_ContainerClass_GetDeltas(CFXJSE_Arguments* pArguments);
+ void Script_ModelClass_ClearErrorList(CFXJSE_Arguments* pArguments);
+ void Script_ModelClass_CreateNode(CFXJSE_Arguments* pArguments);
+ void Script_ModelClass_IsCompatibleNS(CFXJSE_Arguments* pArguments);
+ void Script_ModelClass_Context(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_ModelClass_AliasNode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_WsdlConnection_Execute(CFXJSE_Arguments* pArguments);
+ void Script_Delta_Restore(CFXJSE_Arguments* pArguments);
+ void Script_Delta_CurrentValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Delta_SavedValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Delta_Target(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Attribute_SendAttributeChangeMessage(FX_LPVOID eAttribute, FX_LPVOID eValue, FX_BOOL bScriptModify);
+ void Script_Attribute_Integer(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Attribute_IntegerRead(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Attribute_BOOL(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Attribute_BOOLRead(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Attribute_String(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Attribute_StringRead(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_ValidationMessage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_Length(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_DefaultValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_DefaultValue_Read(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Boolean_Value(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_Message(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_SOM_MESSAGETYPE iMessageType);
+ void Script_Som_BorderColor(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_BorderWidth(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_FillColor(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_DataNode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_FontColor(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_Mandatory(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_MandatoryMessage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Som_InstanceIndex(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Draw_DefaultValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_DefaultValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_EditValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_FormatMessage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_FormattedValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_ParentSubform(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_SelectedIndex(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Field_ClearItems(CFXJSE_Arguments* pArguments);
+ void Script_Field_ExecEvent(CFXJSE_Arguments* pArguments);
+ void Script_Field_ExecInitialize(CFXJSE_Arguments* pArguments);
+ void Script_Field_DeleteItem(CFXJSE_Arguments* pArguments);
+ void Script_Field_GetSaveItem(CFXJSE_Arguments* pArguments);
+ void Script_Field_BoundItem(CFXJSE_Arguments* pArguments);
+ void Script_Field_GetItemState(CFXJSE_Arguments* pArguments);
+ void Script_Field_ExecCalculate(CFXJSE_Arguments* pArguments);
+ void Script_Field_SetItems(CFXJSE_Arguments* pArguments);
+ void Script_Field_GetDisplayItem(CFXJSE_Arguments* pArguments);
+ void Script_Field_SetItemState(CFXJSE_Arguments* pArguments);
+ void Script_Field_AddItem(CFXJSE_Arguments* pArguments);
+ void Script_Field_ExecValidate(CFXJSE_Arguments* pArguments);
+ void Script_ExclGroup_DefaultAndRawValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_ExclGroup_ErrorText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_ExclGroup_Transient(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_ExclGroup_ExecEvent(CFXJSE_Arguments* pArguments);
+ void Script_ExclGroup_SelectedMember(CFXJSE_Arguments* pArguments);
+ void Script_ExclGroup_ExecInitialize(CFXJSE_Arguments* pArguments);
+ void Script_ExclGroup_ExecCalculate(CFXJSE_Arguments* pArguments);
+ void Script_ExclGroup_ExecValidate(CFXJSE_Arguments* pArguments);
+ void Script_Subform_InstanceManager(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Subform_Locale(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Subform_ExecEvent(CFXJSE_Arguments* pArguments);
+ void Script_Subform_ExecInitialize(CFXJSE_Arguments* pArguments);
+ void Script_Subform_ExecCalculate(CFXJSE_Arguments* pArguments);
+ void Script_Subform_ExecValidate(CFXJSE_Arguments* pArguments);
+ void Script_Subform_GetInvalidObjects(CFXJSE_Arguments* pArguments);
+
+ FX_INT32 Subform_and_SubformSet_InstanceIndex();
+ void Script_Template_FormNodes(CFXJSE_Arguments* pArguments);
+ void Script_Template_Remerge(CFXJSE_Arguments* pArguments);
+ void Script_Template_ExecInitialize(CFXJSE_Arguments* pArguments);
+ void Script_Template_CreateNode(CFXJSE_Arguments* pArguments);
+ void Script_Template_Recalculate(CFXJSE_Arguments* pArguments);
+ void Script_Template_ExecCalculate(CFXJSE_Arguments* pArguments);
+ void Script_Template_ExecValidate(CFXJSE_Arguments* pArguments);
+ void Script_Manifest_Evaluate(CFXJSE_Arguments* pArguments);
+ void Script_InstanceManager_Count(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_InstanceManager_Max(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_InstanceManager_Min(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_InstanceManager_MoveInstance(CFXJSE_Arguments* pArguments);
+ void Script_InstanceManager_RemoveInstance(CFXJSE_Arguments* pArguments);
+ void Script_InstanceManager_SetInstances(CFXJSE_Arguments* pArguments);
+ void Script_InstanceManager_AddInstance(CFXJSE_Arguments* pArguments);
+ void Script_InstanceManager_InsertInstance(CFXJSE_Arguments* pArguments);
+ FX_INT32 InstanceManager_SetInstances(FX_INT32 iCount);
+ FX_INT32 InstanceManager_MoveInstance(FX_INT32 iTo, FX_INT32 iFrom);
+ void Script_Occur_Max(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Occur_Min(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Desc_Metadata(CFXJSE_Arguments* pArguments);
+ void Script_Form_FormNodes(CFXJSE_Arguments* pArguments);
+ void Script_Form_Remerge(CFXJSE_Arguments* pArguments);
+ void Script_Form_ExecInitialize(CFXJSE_Arguments* pArguments);
+ void Script_Form_Recalculate(CFXJSE_Arguments* pArguments);
+ void Script_Form_ExecCalculate(CFXJSE_Arguments* pArguments);
+ void Script_Form_ExecValidate(CFXJSE_Arguments* pArguments);
+ void Script_Form_Checksum(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments);
+ void Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments);
+ void Script_Packet_RemoveAttribute(CFXJSE_Arguments* pArguments);
+ void Script_Packet_Content(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Source_Next(CFXJSE_Arguments* pArguments);
+ void Script_Source_CancelBatch(CFXJSE_Arguments* pArguments);
+ void Script_Source_First(CFXJSE_Arguments* pArguments);
+ void Script_Source_UpdateBatch(CFXJSE_Arguments* pArguments);
+ void Script_Source_Previous(CFXJSE_Arguments* pArguments);
+ void Script_Source_IsBOF(CFXJSE_Arguments* pArguments);
+ void Script_Source_IsEOF(CFXJSE_Arguments* pArguments);
+ void Script_Source_Cancel(CFXJSE_Arguments* pArguments);
+ void Script_Source_Update(CFXJSE_Arguments* pArguments);
+ void Script_Source_Open(CFXJSE_Arguments* pArguments);
+ void Script_Source_Delete(CFXJSE_Arguments* pArguments);
+ void Script_Source_AddNew(CFXJSE_Arguments* pArguments);
+ void Script_Source_Requery(CFXJSE_Arguments* pArguments);
+ void Script_Source_Resync(CFXJSE_Arguments* pArguments);
+ void Script_Source_Close(CFXJSE_Arguments* pArguments);
+ void Script_Source_Last(CFXJSE_Arguments* pArguments);
+ void Script_Source_HasDataChanged(CFXJSE_Arguments* pArguments);
+ void Script_Source_Db(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Xfa_This(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Handler_Version(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_SubmitFormat_Mode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Extras_Type(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Encrypt_Format(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_Script_Stateless(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+protected:
+ CXFA_Node(CXFA_Document *pDoc, FX_WORD ePacket, XFA_ELEMENT eElement);
+ ~CXFA_Node();
+ friend class CXFA_Document;
+ CXFA_Node* Deprecated_GetPrevSibling();
+ FX_BOOL SetValue(XFA_ATTRIBUTE eAttr, XFA_ATTRIBUTETYPE eType, FX_LPVOID pValue, FX_BOOL bNotify);
+ FX_BOOL GetValue(XFA_ATTRIBUTE eAttr, XFA_ATTRIBUTETYPE eType, FX_BOOL bUseDefault, FX_LPVOID &pValue);
+ void OnRemoved(CXFA_Node *pParent, CXFA_Node *pRemoved, FX_BOOL bNotify);
+ void OnChanging(XFA_ATTRIBUTE eAttr, FX_LPVOID pNewValue, FX_BOOL bNotify);
+ void OnChanged(XFA_ATTRIBUTE eAttr, FX_LPVOID pNewValue, FX_BOOL bNotify, FX_BOOL bScriptModify = FALSE);
+ FX_INT32 execSingleEventByName(FX_WSTR wsEventName, XFA_ELEMENT eElementType);
+ FX_BOOL SetScriptContent(const CFX_WideString& wsContent, const CFX_WideString& wsXMLValue, FX_BOOL bNotify = TRUE, FX_BOOL bScriptModify = FALSE, FX_BOOL bSyncData = TRUE);
+ CFX_WideString GetScriptContent(FX_BOOL bScriptModify = FALSE);
+ XFA_LPMAPMODULEDATA GetMapModuleData(FX_BOOL bCreateNew);
+ void SetMapModuleValue(FX_LPVOID pKey, FX_LPVOID pValue);
+ FX_BOOL GetMapModuleValue(FX_LPVOID pKey, FX_LPVOID &pValue);
+ void SetMapModuleString(FX_LPVOID pKey, FX_WSTR wsValue);
+ FX_BOOL GetMapModuleString(FX_LPVOID pKey, CFX_WideStringC &wsValue);
+ void SetMapModuleBuffer(FX_LPVOID pKey, FX_LPVOID pValue, FX_INT32 iBytes, XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo = NULL);
+ FX_BOOL GetMapModuleBuffer(FX_LPVOID pKey, FX_LPVOID &pValue, FX_INT32 &iBytes, FX_BOOL bProtoAlso = TRUE);
+ FX_BOOL HasMapModuleKey(FX_LPVOID pKey, FX_BOOL bProtoAlso = FALSE);
+ void RemoveMapModuleKey(FX_LPVOID pKey = NULL);
+ void MergeAllData(FX_LPVOID pDstModule, FX_BOOL bUseSrcAttr = TRUE);
+ void MoveBufferMapData(CXFA_Node* pDstModule, FX_LPVOID pKey);
+ void MoveBufferMapData(CXFA_Node* pSrcModule, CXFA_Node* pDstModule, FX_LPVOID pKey, FX_BOOL bRecursive = FALSE);
+protected:
+ CXFA_Node *m_pNext;
+ CXFA_Node *m_pChild;
+ CXFA_Node *m_pLastChild;
+ CXFA_Node *m_pParent;
+ IFDE_XMLNode *m_pXMLNode;
+ XFA_ELEMENT m_eNodeClass;
+ FX_WORD m_ePacket;
+ FX_DWORD m_dwNameHash;
+ CXFA_Node *m_pAuxNode;
+ XFA_LPMAPMODULEDATA m_pMapModuleData;
+};
+class CXFA_OrdinaryObject : public CXFA_Object
+{
+public:
+ CXFA_OrdinaryObject(CXFA_Document* pDocument, XFA_ELEMENT eElement) : CXFA_Object(pDocument, XFA_OBJECTTYPE_OrdinaryObject), m_uScriptHash(0)
+ {
+ m_eNodeClass = eElement;
+ }
+ XFA_ELEMENT GetClassID() const
+ {
+ return (XFA_ELEMENT)m_eNodeClass;
+ }
+ FX_UINT32 GetScriptObjHash()
+ {
+ return m_uScriptHash;
+ }
+protected:
+ XFA_ELEMENT m_eNodeClass;
+ FX_UINT32 m_uScriptHash;
+};
+class CXFA_ThisProxy : public CXFA_Object
+{
+public :
+ CXFA_ThisProxy(CXFA_Node* pThisNode, CXFA_Node* pScriptNode): CXFA_Object(pThisNode->GetDocument(), XFA_OBJECTTYPE_VariablesThis), m_pThisNode(NULL), m_pScriptNode(NULL)
+ {
+ m_pThisNode = pThisNode;
+ m_pScriptNode = pScriptNode;
+ }
+ virtual ~CXFA_ThisProxy() {}
+ CXFA_Node* GetThisNode()
+ {
+ return m_pThisNode;
+ }
+ CXFA_Node* GetScriptNode()
+ {
+ return m_pScriptNode;
+ }
+private:
+ CXFA_Node* m_pThisNode;
+ CXFA_Node* m_pScriptNode;
+};
+class CXFA_NodeList : public CXFA_Object
+{
+public:
+ CXFA_NodeList(CXFA_Document* pDocument);
+ virtual ~CXFA_NodeList() {}
+ XFA_ELEMENT GetClassID() const
+ {
+ return XFA_ELEMENT_NodeList;
+ }
+ CXFA_Node* NamedItem(FX_WSTR wsName);
+ virtual FX_INT32 GetLength() = 0;
+ virtual FX_BOOL Append(CXFA_Node* pNode) = 0;
+ virtual FX_BOOL Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode) = 0;
+ virtual FX_BOOL Remove(CXFA_Node* pNode) = 0;
+ virtual CXFA_Node* Item(FX_INT32 iIndex) = 0;
+
+ void Script_ListClass_Append(CFXJSE_Arguments* pArguments);
+ void Script_ListClass_Insert(CFXJSE_Arguments* pArguments);
+ void Script_ListClass_Remove(CFXJSE_Arguments* pArguments);
+ void Script_ListClass_Item(CFXJSE_Arguments* pArguments);
+
+ void Script_TreelistClass_NamedItem(CFXJSE_Arguments* pArguments);
+ void Script_ListClass_Length(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+};
+class CXFA_ArrayNodeList : public CXFA_NodeList
+{
+public:
+ CXFA_ArrayNodeList(CXFA_Document* pDocument);
+ void SetArrayNodeList(const CXFA_NodeArray &srcArray);
+ virtual FX_INT32 GetLength();
+ virtual FX_BOOL Append(CXFA_Node* pNode);
+ virtual FX_BOOL Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode);
+ virtual FX_BOOL Remove(CXFA_Node* pNode);
+ virtual CXFA_Node* Item(FX_INT32 iIndex);
+protected:
+ CXFA_NodeArray m_array;
+};
+class CXFA_AttachNodeList : public CXFA_NodeList
+{
+public:
+ CXFA_AttachNodeList(CXFA_Document* pDocument, CXFA_Node* pAttachNode);
+
+ virtual FX_INT32 GetLength();
+ virtual FX_BOOL Append(CXFA_Node* pNode);
+ virtual FX_BOOL Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode);
+ virtual FX_BOOL Remove(CXFA_Node* pNode);
+ virtual CXFA_Node* Item(FX_INT32 iIndex);
+protected:
+ CXFA_Node* m_pAttachNode;
+};
+class CXFA_TraverseStrategy_XFAContainerNode
+{
+public:
+ static CXFA_Node* GetFirstChild(CXFA_Node* pTemplateNode, FX_LPVOID pUserData = NULL)
+ {
+ return pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
+ }
+ static CXFA_Node* GetNextSibling(CXFA_Node* pTemplateNode, FX_LPVOID pUserData = NULL)
+ {
+ return pTemplateNode->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);
+ }
+ static CXFA_Node* GetParent(CXFA_Node* pTemplateNode, FX_LPVOID pUserData = NULL)
+ {
+ return pTemplateNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ }
+};
+typedef CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> CXFA_ContainerIterator;
+class CXFA_TraverseStrategy_XFANode
+{
+public:
+ static inline CXFA_Node* GetFirstChild(CXFA_Node* pTemplateNode)
+ {
+ return pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ }
+ static inline CXFA_Node* GetNextSibling(CXFA_Node* pTemplateNode)
+ {
+ return pTemplateNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ static inline CXFA_Node* GetParent(CXFA_Node* pTemplateNode)
+ {
+ return pTemplateNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+};
+typedef CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> CXFA_NodeIterator;
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_parser.h b/xfa/src/fxfa/src/common/xfa_parser.h
new file mode 100644
index 0000000000..2b1f1e62a8
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_parser.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_PARSER_H
+#define _XFA_PARSER_H
+class IFX_Stream;
+class IXFA_Parser
+{
+public:
+ static IXFA_Parser* Create(IXFA_ObjFactory *pFactory, FX_BOOL bDocumentParser = FALSE);
+ virtual void Release() = 0;
+ virtual FX_INT32 StartParse(IFX_FileRead *pStream, XFA_XDPPACKET ePacketID = XFA_XDPPACKET_XDP) = 0;
+ virtual FX_INT32 DoParse(IFX_Pause *pPause = NULL) = 0;
+ virtual FX_INT32 ParseXMLData(const CFX_WideString &wsXML, IFDE_XMLNode* &pXMLNode, IFX_Pause *pPause = NULL) = 0;
+ virtual void ConstructXFANode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode) = 0;
+ virtual IXFA_ObjFactory* GetFactory() const = 0;
+ virtual CXFA_Node* GetRootNode() const = 0;
+ virtual IFDE_XMLDoc* GetXMLDoc() const = 0;
+ virtual void CloseParser() = 0;
+};
+class IXFA_DocParser : public IXFA_Parser
+{
+public:
+ static IXFA_DocParser* Create(IXFA_Notify *pNotify);
+ virtual CXFA_Document* GetDocument() const = 0;
+ virtual IXFA_Notify* GetNotify() const = 0;
+};
+class IXFA_DataLoaderOptionsProvider
+{
+public:
+ static IXFA_DataLoaderOptionsProvider* Create(CXFA_Node* pConfigurationDOM);
+ virtual void Release() = 0;
+};
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_script.h b/xfa/src/fxfa/src/common/xfa_script.h
new file mode 100644
index 0000000000..eb3b8472d4
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_script.h
@@ -0,0 +1,107 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_SCRIPT_H
+#define _FXFA_SCRIPT_H
+#define XFA_RESOLVENODE_Children 0x0001
+#define XFA_RESOLVENODE_Attributes 0x0004
+#define XFA_RESOLVENODE_Properties 0x0008
+#define XFA_RESOLVENODE_Siblings 0x0020
+#define XFA_RESOLVENODE_Parent 0x0040
+#define XFA_RESOLVENODE_AnyChild 0x0080
+#define XFA_RESOLVENODE_ALL 0x0100
+#define XFA_RESOLVENODE_CreateNode 0x0400
+#define XFA_RESOLVENODE_Bind 0x0800
+#define XFA_RESOLVENODE_BindNew 0x1000
+enum XFA_SCRIPTLANGTYPE {
+ XFA_SCRIPTLANGTYPE_Formcalc = XFA_SCRIPTTYPE_Formcalc,
+ XFA_SCRIPTLANGTYPE_Javascript = XFA_SCRIPTTYPE_Javascript,
+ XFA_SCRIPTLANGTYPE_Unkown = XFA_SCRIPTTYPE_Unkown,
+};
+enum XFA_RESOVENODE_RSTYPE {
+ XFA_RESOVENODE_RSTYPE_Nodes,
+ XFA_RESOVENODE_RSTYPE_Attribute,
+ XFA_RESOLVENODE_RSTYPE_CreateNodeOne,
+ XFA_RESOLVENODE_RSTYPE_CreateNodeAll,
+ XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll,
+ XFA_RESOVENODE_RSTYPE_ExistNodes,
+};
+class CXFA_HVALUEArray : public CFX_ArrayTemplate<FXJSE_HVALUE>
+{
+public:
+ CXFA_HVALUEArray(FXJSE_HRUNTIME hRunTime) : m_hRunTime(hRunTime) {};
+ ~CXFA_HVALUEArray()
+ {
+ for (FX_INT32 i = 0; i < GetSize(); i++) {
+ FXJSE_Value_Release(GetAt(i));
+ }
+ }
+ void GetAttributeObject(CXFA_ObjArray& objArray)
+ {
+ for (FX_INT32 i = 0; i < GetSize(); i++) {
+ CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(GetAt(i), NULL);
+ objArray.Add(pObject);
+ }
+ }
+ FXJSE_HRUNTIME m_hRunTime;
+};
+typedef struct _XFA_RESOLVENODE_RS : public CFX_Object {
+ _XFA_RESOLVENODE_RS() : dwFlags(XFA_RESOVENODE_RSTYPE_Nodes), pScriptAttribute(NULL) { }
+ ~_XFA_RESOLVENODE_RS()
+ {
+ nodes.RemoveAll();
+ }
+ FX_INT32 GetAttributeResult(CXFA_HVALUEArray& hValueArray) const
+ {
+ if (pScriptAttribute && pScriptAttribute->eValueType == XFA_SCRIPT_Object) {
+ FXJSE_HRUNTIME hRunTime = hValueArray.m_hRunTime;
+ for (FX_INT32 i = 0; i < nodes.GetSize(); i++) {
+ FXJSE_HVALUE hValue = FXJSE_Value_Create(hRunTime);
+ (nodes[i]->*(pScriptAttribute->lpfnCallback))(hValue, FALSE, (XFA_ATTRIBUTE)pScriptAttribute->eAttribute);
+ hValueArray.Add(hValue);
+ }
+ }
+ return hValueArray.GetSize();
+ }
+ CXFA_ObjArray nodes;
+ XFA_LPCSCRIPTATTRIBUTEINFO pScriptAttribute;
+ XFA_RESOVENODE_RSTYPE dwFlags;
+} XFA_RESOLVENODE_RS, * XFA_LPRESOLVENODE_RS;
+typedef struct _XFA_JSBUILTININFO {
+ FX_UINT32 uUnicodeHash;
+ FX_LPCSTR pName;
+} XFA_JSBUILTININFO, * XFA_LPJSBUILTININFO;
+typedef XFA_JSBUILTININFO const * XFA_LPCJSBUILTININFO;
+XFA_LPCJSBUILTININFO XFA_GetJSBuiltinByHash(FX_UINT32 uHashCode);
+class IXFA_ScriptContext
+{
+public:
+ virtual void Release() = 0;
+ virtual void Initialize(FXJSE_HRUNTIME hRuntime) = 0;
+
+ virtual void SetEventParam(CXFA_EventParam* pEventParam) = 0;
+ virtual CXFA_EventParam* GetEventParam() = 0;
+ virtual FX_BOOL RunScript(XFA_SCRIPTLANGTYPE eScriptType, FX_WSTR wsScript, FXJSE_HVALUE hRetValue, CXFA_Object* pThisObject = NULL) = 0;
+ virtual FX_INT32 ResolveObjects(CXFA_Object* refNode, FX_WSTR wsExpression, XFA_RESOLVENODE_RS& resolveNodeRS, FX_DWORD dwStyles = XFA_RESOLVENODE_Children, CXFA_Node* bindNode = NULL) = 0;
+ virtual FXJSE_HVALUE GetJSValueFromMap(CXFA_Object* pObject) = 0;
+ virtual void CacheList(CXFA_NodeList* pList) = 0;
+ virtual CXFA_Object* GetThisObject() const = 0;
+ virtual FXJSE_HRUNTIME GetRuntime() const = 0;
+ virtual FX_INT32 GetIndexByName(CXFA_Node* refNode) = 0;
+ virtual FX_INT32 GetIndexByClassName(CXFA_Node* refNode) = 0;
+ virtual void GetSomExpression(CXFA_Node* refNode, CFX_WideString &wsExpression) = 0;
+
+ virtual void SetNodesOfRunScript(CXFA_NodeArray *pArray) = 0;
+ virtual void AddNodesOfRunScript(const CXFA_NodeArray& nodes) = 0;
+ virtual void AddNodesOfRunScript(CXFA_Node* pNode) = 0;
+ virtual FXJSE_HCLASS GetJseNormalClass() = 0;
+ virtual XFA_SCRIPTLANGTYPE GetType() = 0;
+ virtual void AddJSBuiltinObject(XFA_LPCJSBUILTININFO pBuitinObject) = 0;
+ virtual void SetRunAtType(XFA_ATTRIBUTEENUM eRunAt) = 0;
+ virtual FX_BOOL IsRunAtClient() = 0;
+};
+IXFA_ScriptContext* XFA_ScriptContext_Create(CXFA_Document* pDocument);
+#endif
diff --git a/xfa/src/fxfa/src/common/xfa_utils.h b/xfa/src/fxfa/src/common/xfa_utils.h
new file mode 100644
index 0000000000..df51ff6baa
--- /dev/null
+++ b/xfa/src/fxfa/src/common/xfa_utils.h
@@ -0,0 +1,237 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_UTILS_H_
+#define _XFA_UTILS_H_
+FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier(IFDE_XMLElement* pNode, FX_WSTR wsQualifier, CFX_WideString& wsNamespaceURI);
+template <class NodeType, class TraverseStrategy>
+class CXFA_NodeIteratorTemplate : public CFX_Object
+{
+public:
+ CXFA_NodeIteratorTemplate(NodeType* pRootNode = NULL)
+ : m_pRoot(pRootNode)
+ {
+ if(pRootNode) {
+ m_NodeStack.Push(pRootNode);
+ }
+ }
+ FX_BOOL Init(NodeType* pRootNode)
+ {
+ if(!pRootNode) {
+ return FALSE;
+ }
+ m_pRoot = pRootNode;
+ m_NodeStack.RemoveAll();
+ m_NodeStack.Push(pRootNode);
+ return TRUE;
+ }
+ void Clear()
+ {
+ m_NodeStack.RemoveAll();
+ }
+ void Reset()
+ {
+ Clear();
+ if (m_pRoot) {
+ m_NodeStack.Push(m_pRoot);
+ }
+ }
+ FX_BOOL SetCurrent(NodeType* pCurNode)
+ {
+ m_NodeStack.RemoveAll();
+ if(pCurNode) {
+ CFX_StackTemplate<NodeType*> revStack;
+ NodeType* pNode;
+ for(pNode = pCurNode; pNode && pNode != m_pRoot; pNode = TraverseStrategy::GetParent(pNode)) {
+ revStack.Push(pNode);
+ }
+ if(!pNode) {
+ return FALSE;
+ }
+ revStack.Push(m_pRoot);
+ while(revStack.GetSize()) {
+ m_NodeStack.Push(*revStack.GetTopElement());
+ revStack.Pop();
+ }
+ }
+ return TRUE;
+ }
+ NodeType* GetCurrent()
+ {
+ return m_NodeStack.GetSize() ? *m_NodeStack.GetTopElement() : NULL;
+ }
+ NodeType* GetRoot()
+ {
+ return m_pRoot;
+ }
+ NodeType* MoveToPrev()
+ {
+ NodeType *pCurrent = GetCurrent();
+ FX_INT32 nStackLength = m_NodeStack.GetSize();
+ if(nStackLength == 1) {
+ return NULL;
+ } else if(nStackLength > 1) {
+ NodeType *pCurItem = *m_NodeStack.GetTopElement();
+ m_NodeStack.Pop();
+ NodeType *pParentItem = *m_NodeStack.GetTopElement();
+ NodeType *pParentFirstChildItem = TraverseStrategy::GetFirstChild(pParentItem);
+ if(pCurItem == pParentFirstChildItem) {
+ return pParentItem;
+ }
+ NodeType *pPrevItem = pParentFirstChildItem, *pPrevItemNext = NULL;
+ for(; pPrevItem; pPrevItem = pPrevItemNext) {
+ pPrevItemNext = TraverseStrategy::GetNextSibling(pPrevItem);
+ if(!pPrevItemNext || pPrevItemNext == pCurItem) {
+ break;
+ }
+ }
+ m_NodeStack.Push(pPrevItem);
+ } else {
+ m_NodeStack.RemoveAll();
+ if(m_pRoot) {
+ m_NodeStack.Push(m_pRoot);
+ }
+ }
+ if(m_NodeStack.GetSize() > 0) {
+ NodeType *pChildItem = *m_NodeStack.GetTopElement();
+ while((pChildItem = TraverseStrategy::GetFirstChild(pChildItem)) != NULL) {
+ while(NodeType *pNextItem = TraverseStrategy::GetNextSibling(pChildItem)) {
+ pChildItem = pNextItem;
+ }
+ m_NodeStack.Push(pChildItem);
+ }
+ return *m_NodeStack.GetTopElement();
+ }
+ return NULL;
+ }
+ NodeType* MoveToNext()
+ {
+ NodeType **ppNode = NULL;
+ NodeType *pCurrent = GetCurrent();
+ while (m_NodeStack.GetSize() > 0) {
+ while ((ppNode = m_NodeStack.GetTopElement()) != NULL) {
+ if (pCurrent != *ppNode) {
+ return *ppNode;
+ }
+ NodeType *pChild = TraverseStrategy::GetFirstChild(*ppNode);
+ if (pChild == NULL) {
+ break;
+ }
+ m_NodeStack.Push(pChild);
+ }
+ while ((ppNode = m_NodeStack.GetTopElement()) != NULL) {
+ NodeType *pNext = TraverseStrategy::GetNextSibling(*ppNode);
+ m_NodeStack.Pop();
+ if (m_NodeStack.GetSize() == 0) {
+ break;
+ }
+ if (pNext) {
+ m_NodeStack.Push(pNext);
+ break;
+ }
+ }
+ }
+ return NULL;
+ }
+ NodeType* SkipChildrenAndMoveToNext()
+ {
+ NodeType **ppNode = NULL;
+ while ((ppNode = m_NodeStack.GetTopElement()) != NULL) {
+ NodeType *pNext = TraverseStrategy::GetNextSibling(*ppNode);
+ m_NodeStack.Pop();
+ if (m_NodeStack.GetSize() == 0) {
+ break;
+ }
+ if (pNext) {
+ m_NodeStack.Push(pNext);
+ break;
+ }
+ }
+ return GetCurrent();
+ }
+protected:
+ NodeType *m_pRoot;
+ CFX_StackTemplate<NodeType*> m_NodeStack;
+};
+template <class KeyType>
+class CXFA_PtrSetTemplate : private CFX_MapPtrToPtr
+{
+public:
+
+ CXFA_PtrSetTemplate() : CFX_MapPtrToPtr(10) {}
+
+ int GetCount() const
+ {
+ return CFX_MapPtrToPtr::GetCount();
+ }
+
+
+ FX_BOOL IsEmpty() const
+ {
+ return CFX_MapPtrToPtr::IsEmpty();
+ }
+
+ FX_BOOL Lookup(KeyType key) const
+ {
+ FX_LPVOID pValue = NULL;
+ return CFX_MapPtrToPtr::Lookup((void*)key, pValue);
+ }
+
+ FX_BOOL operator[](KeyType key)
+ {
+ return Lookup(key);
+ }
+
+ void Add(KeyType key)
+ {
+ CFX_MapPtrToPtr::SetAt((void*)key, (void*)key);
+ }
+
+ FX_BOOL RemoveKey(KeyType key)
+ {
+ return CFX_MapPtrToPtr::RemoveKey((void*)key);
+ }
+
+ void RemoveAll()
+ {
+ CFX_MapPtrToPtr::RemoveAll();
+ }
+
+ FX_POSITION GetStartPosition() const
+ {
+ return CFX_MapPtrToPtr::GetStartPosition();
+ }
+
+ void GetNextAssoc(FX_POSITION& rNextPosition, KeyType& rKey) const
+ {
+ void* pKey = NULL;
+ void* pValue = NULL;
+ CFX_MapPtrToPtr::GetNextAssoc(rNextPosition, pKey, pValue);
+ rKey = (KeyType)(FX_UINTPTR)pKey;
+ }
+};
+class CXFA_Node;
+class CXFA_WidgetData;
+#include "fxfa_localevalue.h"
+CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType);
+CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData);
+CFX_WideString XFA_NumericLimit(const CFX_WideString &wsValue, FX_INT32 iLead, FX_INT32 iTread);
+FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal);
+FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal);
+#ifndef XFA_PARSE_HAS_LINEIDENTIFIER
+#define XFA_PARSE_HAS_LINEIDENTIFIER
+#endif
+FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode);
+void XFA_GetPlainTextFromRichText(IFDE_XMLNode *pXMLNode, CFX_WideString &wsPlainText);
+FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode);
+IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString &wsBuffer);
+FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer = FALSE);
+FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence);
+FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout);
+FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout);
+void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node *pDataNode);
+void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, IFX_Stream* pStream, FX_LPCSTR pChecksum = NULL, FX_BOOL bSaveXML = FALSE);
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_error.cpp b/xfa/src/fxfa/src/fm2js/xfa_error.cpp
new file mode 100644
index 0000000000..6d5f253e5a
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_error.cpp
@@ -0,0 +1,25 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+static FX_LPCWSTR gs_lpStrErrorMsgInfo[] = {
+ (FX_LPCWSTR)(L"unsupported char '%c'"),
+ (FX_LPCWSTR)(L"bad suffix on number"),
+ (FX_LPCWSTR)(L"invalidate char '%c'"),
+ (FX_LPCWSTR)(L"expected identifier instead of '%s'"),
+ (FX_LPCWSTR)(L"expected '%s' instead of '%s'"),
+ (FX_LPCWSTR)(L"expected 'endif' instead of '%s'"),
+ (FX_LPCWSTR)(L"unexpected expression '%s'"),
+ (FX_LPCWSTR)(L"expected operator '%s' instead of '%s'"),
+};
+FX_LPCWSTR XFA_FM_ErrorMsg(XFA_FM_ERRMSG msg)
+{
+ if(msg < FMERR_MAXIMUM) {
+ return gs_lpStrErrorMsgInfo[msg];
+ } else {
+ return (FX_LPCWSTR)(L"");
+ }
+}
diff --git a/xfa/src/fxfa/src/fm2js/xfa_error.h b/xfa/src/fxfa/src/fm2js/xfa_error.h
new file mode 100644
index 0000000000..8ec0250b22
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_error.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM_ERROR_H
+#define _XFA_FM_ERROR_H
+enum XFA_FM_ERRMSG {
+ FMERR_UNSUPPORTED_CHAR,
+ FMERR_BAD_SUFFIX_NUMBER,
+ FMERR_INVALIDATE_CHAR,
+ FMERR_EXPECTED_IDENTIFIER,
+ FMERR_EXPECTED_TOKEN,
+ FMERR_EXPECTED_IFEND,
+ FMERR_UNEXPECTED_EXPRESSION,
+ FMERR_EXPTECTED_OPERATOR,
+ FMERR_MAXIMUM
+};
+class CXFA_FMErrorInfo : public CFX_Object
+{
+public:
+ CXFA_FMErrorInfo() : linenum(0) {};
+ ~CXFA_FMErrorInfo() {};
+ FX_DWORD linenum;
+ CFX_WideString message;
+};
+FX_LPCWSTR XFA_FM_ErrorMsg( XFA_FM_ERRMSG msg);
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_expression.cpp b/xfa/src/fxfa/src/fm2js/xfa_expression.cpp
new file mode 100644
index 0000000000..7b230de528
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_expression.cpp
@@ -0,0 +1,715 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+static CFX_WideStringC RUNTIMEBLOCKTEMPARRAY = FX_WSTRC(L"foxit_xfa_formcalc_runtime_block_temp_array");
+static CFX_WideStringC RUNTIMEBLOCKTEMPARRAYINDEX = FX_WSTRC(L"foxit_xfa_formcalc_runtime_block_temp_array_index");
+CXFA_FMExpression::CXFA_FMExpression( FX_DWORD line )
+ : m_line(line), m_type(XFA_FM_EXPTYPE_UNKNOWN)
+{
+}
+CXFA_FMExpression::CXFA_FMExpression(FX_DWORD line, XFA_FM_EXPTYPE type)
+ : m_line(line), m_type(type)
+{
+}
+void CXFA_FMExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{}
+void CXFA_FMExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{}
+CXFA_FMFunctionDefinition::CXFA_FMFunctionDefinition( FX_DWORD line, FX_BOOL isGlobal, FX_WSTR wsName, CFX_WideStringCArray *pArguments, CFX_PtrArray *pExpressions )
+ : CXFA_FMExpression(line, XFA_FM_EXPTYPE_FUNC),
+ m_isGlobal(isGlobal),
+ m_wsName(wsName),
+ m_pArguments(pArguments),
+ m_pExpressions(pExpressions)
+{
+}
+CXFA_FMFunctionDefinition::~CXFA_FMFunctionDefinition()
+{
+ if (m_pArguments) {
+ m_pArguments->RemoveAll();
+ delete m_pArguments;
+ m_pArguments = 0;
+ }
+ if (m_pExpressions) {
+ FX_INT32 expc = m_pExpressions->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMExpression *e = 0;
+ while (index < expc) {
+ e = (CXFA_FMExpression *)m_pExpressions->GetAt(index);
+ delete e;
+ index++;
+ }
+ m_pExpressions->RemoveAll();
+ delete m_pExpressions;
+ m_pExpressions = 0;
+ }
+}
+void CXFA_FMFunctionDefinition::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ if (m_isGlobal && (!m_pExpressions || m_pExpressions->GetSize() == 0)) {
+ javascript << FX_WSTRC(L"// comments only");
+ return;
+ }
+ if(m_isGlobal) {
+ javascript << FX_WSTRC(L"(\n");
+ }
+ javascript << FX_WSTRC(L"function ");
+ if (m_wsName.GetAt(0) == L'!') {
+ CFX_WideString tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
+ javascript << tempName;
+ } else {
+ javascript << m_wsName;
+ }
+ javascript << FX_WSTRC(L"(");
+ if (m_pArguments != 0) {
+ FX_INT32 argc = m_pArguments->GetSize();
+ FX_INT32 index = 0;
+ CFX_WideStringC identifier = 0;
+ while (index < argc) {
+ identifier = m_pArguments->GetAt(index);
+ if (identifier.GetAt(0) == L'!') {
+ CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + identifier.Mid(1);
+ javascript << tempIdentifier;
+ } else {
+ javascript << identifier;
+ }
+ if (index + 1 < argc) {
+ javascript << FX_WSTRC(L", ");
+ }
+ index++;
+ }
+ }
+ javascript << FX_WSTRC(L")\n{\n");
+ javascript << FX_WSTRC(L"var ");
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = null;\n");
+ if (m_pExpressions) {
+ FX_INT32 expc = m_pExpressions->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMExpression *e = 0;
+ while (index < expc) {
+ e = (CXFA_FMExpression *)m_pExpressions->GetAt(index);
+ if (index + 1 < expc) {
+ e->ToJavaScript(javascript);
+ } else {
+ e->ToImpliedReturnJS(javascript);
+ }
+ index++;
+ }
+ }
+ javascript << FX_WSTRC(L"return ");
+ if (m_isGlobal) {
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L")");
+ } else {
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ }
+ javascript << FX_WSTRC(L";\n}\n");
+ if(m_isGlobal) {
+ javascript << FX_WSTRC(L").call(this);\n");
+ }
+}
+void CXFA_FMFunctionDefinition::ToImpliedReturnJS(CFX_WideTextBuf&)
+{}
+CXFA_FMVarExpression::CXFA_FMVarExpression( FX_DWORD line, FX_WSTR wsName, CXFA_FMExpression *pInit )
+ : CXFA_FMExpression(line, XFA_FM_EXPTYPE_VAR),
+ m_wsName(wsName),
+ m_pInit(pInit)
+{
+}
+CXFA_FMVarExpression::~CXFA_FMVarExpression()
+{
+ if (m_pInit) {
+ delete m_pInit;
+ m_pInit = 0;
+ }
+}
+void CXFA_FMVarExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"var ");
+ CFX_WideString tempName = m_wsName;
+ if (m_wsName.GetAt(0) == L'!') {
+ tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
+ }
+ javascript << tempName;
+ javascript << FX_WSTRC(L" = ");
+ if (m_pInit) {
+ m_pInit->ToJavaScript(javascript);
+ javascript << tempName;
+ javascript << FX_WSTRC(L" = ");
+ javascript << XFA_FM_EXPTypeToString(VARFILTER);
+ javascript << FX_WSTRC(L"(");
+ javascript << tempName;
+ javascript << FX_WSTRC(L");\n");
+ } else {
+ javascript << FX_WSTRC(L"\"\";\n");
+ }
+}
+void CXFA_FMVarExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"var ");
+ CFX_WideString tempName = m_wsName;
+ if (m_wsName.GetAt(0) == L'!') {
+ tempName = EXCLAMATION_IN_IDENTIFIER + m_wsName.Mid(1);
+ }
+ javascript << tempName;
+ javascript << FX_WSTRC(L" = ");
+ if (m_pInit) {
+ m_pInit->ToJavaScript(javascript);
+ javascript << tempName;
+ javascript << FX_WSTRC(L" = ");
+ javascript << XFA_FM_EXPTypeToString(VARFILTER);
+ javascript << FX_WSTRC(L"(");
+ javascript << tempName;
+ javascript << FX_WSTRC(L");\n");
+ } else {
+ javascript << FX_WSTRC(L"\"\";\n");
+ }
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = ");
+ javascript << tempName;
+ javascript << FX_WSTRC(L";\n");
+}
+CXFA_FMExpExpression::CXFA_FMExpExpression( FX_DWORD line, CXFA_FMSimpleExpression *pExpression )
+ : CXFA_FMExpression(line, XFA_FM_EXPTYPE_EXP), m_pExpression(pExpression)
+{
+}
+CXFA_FMExpExpression::~CXFA_FMExpExpression()
+{
+ if (m_pExpression) {
+ delete m_pExpression;
+ m_pExpression = 0;
+ }
+}
+void CXFA_FMExpExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ if (m_pExpression->GetOperatorToken() == TOKassign) {
+ m_pExpression->ToJavaScript(javascript);
+ } else {
+ m_pExpression->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L";\n");
+ }
+}
+void CXFA_FMExpExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ if (m_pExpression->GetOperatorToken() == TOKassign) {
+ m_pExpression->ToImpliedReturnJS(javascript);
+ } else {
+ if( m_pExpression->GetOperatorToken() == TOKstar ||
+ m_pExpression->GetOperatorToken() == TOKdotstar ||
+ m_pExpression->GetOperatorToken() == TOKdotscream ||
+ m_pExpression->GetOperatorToken() == TOKdotdot ||
+ m_pExpression->GetOperatorToken() == TOKdot
+ ) {
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = ");
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pExpression->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L");\n");
+ } else {
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = ");
+ m_pExpression->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L";\n");
+ }
+ }
+}
+CXFA_FMBlockExpression::CXFA_FMBlockExpression(FX_DWORD line, CFX_PtrArray *pExpressionList )
+ : CXFA_FMExpression(line, XFA_FM_EXPTYPE_BLOCK),
+ m_pExpressionList(pExpressionList)
+{
+}
+CXFA_FMBlockExpression::~CXFA_FMBlockExpression()
+{
+ if (m_pExpressionList) {
+ FX_INT32 expc = m_pExpressionList->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMExpression *e = 0;
+ while (index < expc) {
+ e = (CXFA_FMExpression *)m_pExpressionList->GetAt(index);
+ delete e;
+ index++;
+ }
+ m_pExpressionList->RemoveAll();
+ delete m_pExpressionList;
+ m_pExpressionList = 0;
+ }
+}
+void CXFA_FMBlockExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"{\n");
+ if (m_pExpressionList) {
+ FX_INT32 expc = m_pExpressionList->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMExpression *e = 0;
+ while (index < expc) {
+ e = (CXFA_FMExpression *)m_pExpressionList->GetAt(index);
+ e->ToJavaScript(javascript);
+ index++;
+ }
+ }
+ javascript << FX_WSTRC(L"}\n");
+}
+void CXFA_FMBlockExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"{\n");
+ if (m_pExpressionList) {
+ FX_INT32 expc = m_pExpressionList->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMExpression *e = 0;
+ while (index < expc) {
+ e = (CXFA_FMExpression *)m_pExpressionList->GetAt(index);
+ if (index + 1 == expc) {
+ e->ToImpliedReturnJS(javascript);
+ } else {
+ e->ToJavaScript(javascript);
+ }
+ index++;
+ }
+ }
+ javascript << FX_WSTRC(L"}\n");
+}
+CXFA_FMDoExpression::CXFA_FMDoExpression( FX_DWORD line, CXFA_FMExpression *pList )
+ : CXFA_FMExpression(line),
+ m_pList(pList)
+{
+}
+CXFA_FMDoExpression::~CXFA_FMDoExpression()
+{
+ if (m_pList) {
+ delete m_pList;
+ m_pList = 0;
+ }
+}
+void CXFA_FMDoExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ m_pList->ToJavaScript(javascript);
+}
+void CXFA_FMDoExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ m_pList->ToImpliedReturnJS(javascript);
+}
+CXFA_FMIfExpression::CXFA_FMIfExpression( FX_DWORD line, CXFA_FMSimpleExpression *pExpression, CXFA_FMExpression *pIfExpression, CXFA_FMExpression *pElseExpression )
+ : CXFA_FMExpression(line, XFA_FM_EXPTYPE_IF),
+ m_pExpression(pExpression),
+ m_pIfExpression(pIfExpression),
+ m_pElseExpression(pElseExpression)
+{
+}
+CXFA_FMIfExpression::~CXFA_FMIfExpression()
+{
+ if (m_pExpression) {
+ delete m_pExpression;
+ m_pExpression = 0;
+ }
+ if (m_pIfExpression) {
+ delete m_pIfExpression;
+ m_pIfExpression = 0;
+ }
+ if (m_pElseExpression) {
+ delete m_pElseExpression;
+ m_pElseExpression = 0;
+ }
+}
+void CXFA_FMIfExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"if (");
+ if (m_pExpression) {
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pExpression->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+ }
+ javascript << FX_WSTRC(L")\n");
+ if (m_pIfExpression) {
+ m_pIfExpression->ToJavaScript(javascript);
+ }
+ if (m_pElseExpression) {
+ if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) {
+ javascript << FX_WSTRC(L"else\n");
+ javascript << FX_WSTRC(L"{\n");
+ m_pElseExpression->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"}\n");
+ } else {
+ javascript << FX_WSTRC(L"else\n");
+ m_pElseExpression->ToJavaScript(javascript);
+ }
+ }
+}
+void CXFA_FMIfExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"if (");
+ if (m_pExpression) {
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pExpression->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+ }
+ javascript << FX_WSTRC(L")\n");
+ if (m_pIfExpression) {
+ m_pIfExpression->ToImpliedReturnJS(javascript);
+ }
+ if (m_pElseExpression) {
+ if (m_pElseExpression->GetExpType() == XFA_FM_EXPTYPE_IF) {
+ javascript << FX_WSTRC(L"else\n");
+ javascript << FX_WSTRC(L"{\n");
+ m_pElseExpression->ToImpliedReturnJS(javascript);
+ javascript << FX_WSTRC(L"}\n");
+ } else {
+ javascript << FX_WSTRC(L"else\n");
+ m_pElseExpression->ToImpliedReturnJS(javascript);
+ }
+ }
+}
+CXFA_FMLoopExpression::~CXFA_FMLoopExpression()
+{
+}
+void CXFA_FMLoopExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+}
+void CXFA_FMLoopExpression::ToImpliedReturnJS(CFX_WideTextBuf&)
+{}
+CXFA_FMWhileExpression::CXFA_FMWhileExpression( FX_DWORD line, CXFA_FMSimpleExpression *pCondition, CXFA_FMExpression *pExpression )
+ : CXFA_FMLoopExpression(line),
+ m_pCondition(pCondition),
+ m_pExpression(pExpression)
+{
+}
+CXFA_FMWhileExpression::~CXFA_FMWhileExpression()
+{
+ if (m_pCondition) {
+ delete m_pCondition;
+ m_pCondition = 0;
+ }
+ if (m_pExpression) {
+ delete m_pExpression;
+ m_pExpression = 0;
+ }
+}
+void CXFA_FMWhileExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"while (");
+ m_pCondition->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")\n");
+ m_pExpression->ToJavaScript(javascript);
+}
+void CXFA_FMWhileExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"while (");
+ m_pCondition->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")\n");
+ m_pExpression->ToImpliedReturnJS(javascript);
+}
+CXFA_FMBreakExpression::CXFA_FMBreakExpression(FX_DWORD line)
+ : CXFA_FMExpression(line, XFA_FM_EXPTYPE_BREAK),
+ m_pExpression(0)
+{
+}
+CXFA_FMBreakExpression::~CXFA_FMBreakExpression()
+{
+}
+void CXFA_FMBreakExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"break;\n");
+}
+void CXFA_FMBreakExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"break;\n");
+}
+CXFA_FMContinueExpression::CXFA_FMContinueExpression( FX_DWORD line )
+ : CXFA_FMExpression(line, XFA_FM_EXPTYPE_CONTINUE),
+ m_pExpression(0)
+{
+}
+CXFA_FMContinueExpression::~CXFA_FMContinueExpression()
+{
+}
+void CXFA_FMContinueExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"continue;\n");
+}
+void CXFA_FMContinueExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"continue;\n");
+}
+CXFA_FMForExpression::CXFA_FMForExpression(FX_DWORD line, FX_WSTR wsVariant, CXFA_FMSimpleExpression *pAssignment, CXFA_FMSimpleExpression *pAccessor, FX_INT32 iDirection, CXFA_FMSimpleExpression *pStep, CXFA_FMExpression *pList)
+ : CXFA_FMLoopExpression(line),
+ m_wsVariant(wsVariant),
+ m_pAssignment(pAssignment),
+ m_pAccessor(pAccessor),
+ m_iDirection(iDirection),
+ m_pStep(pStep),
+ m_pList(pList)
+{
+}
+CXFA_FMForExpression::~CXFA_FMForExpression()
+{
+ if (m_pAssignment) {
+ delete m_pAssignment;
+ m_pAssignment = 0;
+ }
+ if (m_pAccessor) {
+ delete m_pAccessor;
+ m_pAccessor = 0;
+ }
+ if (m_pStep) {
+ delete m_pStep;
+ m_pStep = 0;
+ }
+ if (m_pList) {
+ delete m_pList;
+ m_pList = 0;
+ }
+}
+void CXFA_FMForExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"{\nvar ");
+ CFX_WideString tempVariant;
+ if (m_wsVariant.GetAt(0) == L'!') {
+ tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1);
+ javascript << tempVariant;
+ } else {
+ tempVariant = m_wsVariant;
+ javascript << m_wsVariant;
+ }
+ javascript << FX_WSTRC(L" = null;\n");
+ javascript << FX_WSTRC(L"for (");
+ javascript << tempVariant;
+ javascript << FX_WSTRC(L" = ");
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pAssignment->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"); ");
+ javascript << tempVariant;
+ if (m_iDirection == 1) {
+ javascript << FX_WSTRC(L" <= ");
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pAccessor->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"); ");
+ javascript << tempVariant;
+ javascript << FX_WSTRC(L" += ");
+ } else {
+ javascript << FX_WSTRC(L" >= ");
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pAccessor->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"); ");
+ javascript << tempVariant;
+ javascript << FX_WSTRC(L" -= ");
+ }
+ if (m_pStep) {
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pStep->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+ } else {
+ javascript << FX_WSTRC(L"1");
+ }
+ javascript << FX_WSTRC(L")\n");
+ m_pList->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"}\n");
+}
+void CXFA_FMForExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"{\nvar ");
+ CFX_WideString tempVariant;
+ if (m_wsVariant.GetAt(0) == L'!') {
+ tempVariant = EXCLAMATION_IN_IDENTIFIER + m_wsVariant.Mid(1);
+ javascript << tempVariant;
+ } else {
+ tempVariant = m_wsVariant;
+ javascript << m_wsVariant;
+ }
+ javascript << FX_WSTRC(L" = null;\n");
+ javascript << FX_WSTRC(L"for (");
+ javascript << tempVariant;
+ javascript << FX_WSTRC(L" = ");
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pAssignment->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"); ");
+ javascript << tempVariant;
+ if (m_iDirection == 1) {
+ javascript << FX_WSTRC(L" <= ");
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pAccessor->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"); ");
+ javascript << tempVariant;
+ javascript << FX_WSTRC(L" += ");
+ } else {
+ javascript << FX_WSTRC(L" >= ");
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pAccessor->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"); ");
+ javascript << tempVariant;
+ javascript << FX_WSTRC(L" -= ");
+ }
+ if (m_pStep) {
+ javascript << XFA_FM_EXPTypeToString(GETFMVALUE);
+ javascript << FX_WSTRC(L"(");
+ m_pStep->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+ } else {
+ javascript << FX_WSTRC(L"1");
+ }
+ javascript << FX_WSTRC(L")\n");
+ m_pList->ToImpliedReturnJS(javascript);
+ javascript << FX_WSTRC(L"}\n");
+}
+CXFA_FMForeachExpression::CXFA_FMForeachExpression( FX_DWORD line, FX_WSTR wsIdentifier, CFX_PtrArray *pAccessors, CXFA_FMExpression *pList )
+ : CXFA_FMLoopExpression(line),
+ m_wsIdentifier(wsIdentifier),
+ m_pAccessors(pAccessors),
+ m_pList(pList)
+{
+}
+CXFA_FMForeachExpression::~CXFA_FMForeachExpression()
+{
+ if (m_pList) {
+ delete m_pList;
+ m_pList = 0;
+ }
+ if (m_pAccessors) {
+ FX_INT32 size = m_pAccessors->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMSimpleExpression *e = 0;
+ while (index < size) {
+ e = (CXFA_FMSimpleExpression *)m_pAccessors->GetAt(index);
+ delete e;
+ index++;
+ }
+ m_pAccessors->RemoveAll();
+ delete m_pAccessors;
+ m_pAccessors = 0;
+ }
+}
+void CXFA_FMForeachExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"{\n");
+ javascript << FX_WSTRC(L"var ");
+ if (m_wsIdentifier.GetAt(0) == L'!') {
+ CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+ javascript << tempIdentifier;
+ } else {
+ javascript << m_wsIdentifier;
+ }
+ javascript << FX_WSTRC(L" = null;\n");
+ javascript << FX_WSTRC(L"var ");
+ javascript << RUNTIMEBLOCKTEMPARRAY;
+ javascript << FX_WSTRC(L" = ");
+ javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT);
+ javascript << FX_WSTRC(L"(");
+ FX_INT32 iSize = m_pAccessors->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMSimpleExpression *s = 0;
+ while(index < iSize) {
+ s = (CXFA_FMSimpleExpression *)m_pAccessors->GetAt(index);
+ s->ToJavaScript(javascript);
+ if (index + 1 < iSize) {
+ javascript << FX_WSTRC(L", ");
+ }
+ index++;
+ }
+ s = 0;
+ javascript << FX_WSTRC(L");\n");
+ javascript << FX_WSTRC(L"var ");
+ javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"while(");
+ javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+ javascript << FX_WSTRC(L" < ");
+ javascript << RUNTIMEBLOCKTEMPARRAY;
+ javascript << FX_WSTRC(L".length)\n{\n");
+ if (m_wsIdentifier.GetAt(0) == L'!') {
+ CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+ javascript << tempIdentifier;
+ } else {
+ javascript << m_wsIdentifier;
+ }
+ javascript << FX_WSTRC(L" = ");
+ javascript << RUNTIMEBLOCKTEMPARRAY;
+ javascript << FX_WSTRC(L"[");
+ javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+ javascript << FX_WSTRC(L"++];\n");
+ m_pList->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"}\n");
+ javascript << FX_WSTRC(L"}\n");
+}
+void CXFA_FMForeachExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"{\n");
+ javascript << FX_WSTRC(L"var ");
+ if (m_wsIdentifier.GetAt(0) == L'!') {
+ CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+ javascript << tempIdentifier;
+ } else {
+ javascript << m_wsIdentifier;
+ }
+ javascript << FX_WSTRC(L" = null;\n");
+ javascript << FX_WSTRC(L"var ");
+ javascript << RUNTIMEBLOCKTEMPARRAY;
+ javascript << FX_WSTRC(L" = ");
+ javascript << XFA_FM_EXPTypeToString(CONCATFMOBJECT);
+ javascript << FX_WSTRC(L"(");
+ FX_INT32 iSize = m_pAccessors->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMSimpleExpression *s = 0;
+ while(index < iSize) {
+ s = (CXFA_FMSimpleExpression *)m_pAccessors->GetAt(index);
+ s->ToJavaScript(javascript);
+ if (index + 1 < iSize) {
+ javascript << FX_WSTRC(L", ");
+ }
+ index++;
+ }
+ s = 0;
+ javascript << FX_WSTRC(L");\n");
+ javascript << FX_WSTRC(L"var ");
+ javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+ javascript << FX_WSTRC(L" = 0;\n");
+ javascript << FX_WSTRC(L"while(");
+ javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+ javascript << FX_WSTRC(L" < ");
+ javascript << RUNTIMEBLOCKTEMPARRAY;
+ javascript << FX_WSTRC(L".length)\n{\n");
+ if (m_wsIdentifier.GetAt(0) == L'!') {
+ CFX_WideString tempIdentifier = EXCLAMATION_IN_IDENTIFIER + m_wsIdentifier.Mid(1);
+ javascript << tempIdentifier;
+ } else {
+ javascript << m_wsIdentifier;
+ }
+ javascript << FX_WSTRC(L" = ");
+ javascript << RUNTIMEBLOCKTEMPARRAY;
+ javascript << FX_WSTRC(L"[");
+ javascript << RUNTIMEBLOCKTEMPARRAYINDEX;
+ javascript << FX_WSTRC(L"++];\n");
+ m_pList->ToImpliedReturnJS(javascript);
+ javascript << FX_WSTRC(L"}\n");
+ javascript << FX_WSTRC(L"}\n");
+}
diff --git a/xfa/src/fxfa/src/fm2js/xfa_expression.h b/xfa/src/fxfa/src/fm2js/xfa_expression.h
new file mode 100644
index 0000000000..ffd7cf2442
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_expression.h
@@ -0,0 +1,172 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM_EXPRESSION_H
+#define _XFA_FM_EXPRESSION_H
+enum XFA_FM_EXPTYPE {
+ XFA_FM_EXPTYPE_UNKNOWN,
+ XFA_FM_EXPTYPE_FUNC,
+ XFA_FM_EXPTYPE_VAR,
+ XFA_FM_EXPTYPE_EXP,
+ XFA_FM_EXPTYPE_BLOCK,
+ XFA_FM_EXPTYPE_IF,
+ XFA_FM_EXPTYPE_BREAK,
+ XFA_FM_EXPTYPE_CONTINUE,
+};
+class CXFA_FMExpression : public CFX_Object
+{
+public:
+ CXFA_FMExpression(FX_DWORD line);
+ CXFA_FMExpression(FX_DWORD line, XFA_FM_EXPTYPE type);
+ virtual ~CXFA_FMExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+ FX_DWORD GetLine()
+ {
+ return m_line;
+ }
+ XFA_FM_EXPTYPE GetExpType() const
+ {
+ return m_type;
+ }
+protected:
+ XFA_FM_EXPTYPE m_type;
+ FX_DWORD m_line;
+};
+class CXFA_FMFunctionDefinition : public CXFA_FMExpression
+{
+public:
+ CXFA_FMFunctionDefinition(FX_DWORD line, FX_BOOL isGlobal, FX_WSTR wsName, CFX_WideStringCArray *pArguments, CFX_PtrArray *pExpressions);
+ virtual ~CXFA_FMFunctionDefinition();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CFX_WideStringC m_wsName;
+ CFX_WideStringCArray *m_pArguments;
+ CFX_PtrArray *m_pExpressions;
+ FX_BOOL m_isGlobal;
+};
+class CXFA_FMVarExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMVarExpression(FX_DWORD line, FX_WSTR wsName, CXFA_FMExpression *pInit);
+ virtual ~CXFA_FMVarExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CFX_WideStringC m_wsName;
+ CXFA_FMExpression *m_pInit;
+};
+class CXFA_FMExpExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMExpExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExpression);
+ virtual ~CXFA_FMExpExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CXFA_FMSimpleExpression *m_pExpression;
+};
+class CXFA_FMBlockExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMBlockExpression(FX_DWORD line, CFX_PtrArray *pExpressionList);
+ virtual ~CXFA_FMBlockExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CFX_PtrArray *m_pExpressionList;
+};
+class CXFA_FMDoExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMDoExpression(FX_DWORD line, CXFA_FMExpression *pList);
+ virtual ~CXFA_FMDoExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CXFA_FMExpression *m_pList;
+};
+class CXFA_FMIfExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMIfExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExpression, CXFA_FMExpression *pIfExpression, CXFA_FMExpression *pElseExpression);
+ virtual ~CXFA_FMIfExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CXFA_FMSimpleExpression *m_pExpression;
+ CXFA_FMExpression *m_pIfExpression;
+ CXFA_FMExpression *m_pElseExpression;
+};
+class CXFA_FMLoopExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMLoopExpression(FX_DWORD line) : CXFA_FMExpression(line) {}
+ virtual ~CXFA_FMLoopExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+};
+class CXFA_FMWhileExpression : public CXFA_FMLoopExpression
+{
+public:
+ CXFA_FMWhileExpression(FX_DWORD line, CXFA_FMSimpleExpression *pCodition, CXFA_FMExpression *pExpression);
+ virtual ~CXFA_FMWhileExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CXFA_FMSimpleExpression *m_pCondition;
+ CXFA_FMExpression *m_pExpression;
+};
+class CXFA_FMBreakExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMBreakExpression(FX_DWORD line);
+ virtual ~CXFA_FMBreakExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CXFA_FMLoopExpression *m_pExpression;
+};
+class CXFA_FMContinueExpression : public CXFA_FMExpression
+{
+public:
+ CXFA_FMContinueExpression(FX_DWORD line);
+ virtual ~CXFA_FMContinueExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CXFA_FMLoopExpression *m_pExpression;
+};
+class CXFA_FMForExpression : public CXFA_FMLoopExpression
+{
+public:
+ CXFA_FMForExpression(FX_DWORD line, FX_WSTR wsVariant, CXFA_FMSimpleExpression *pAssignment,
+ CXFA_FMSimpleExpression *pAccessor, FX_INT32 iDirection, CXFA_FMSimpleExpression *pStep, CXFA_FMExpression *pList);
+ virtual ~CXFA_FMForExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CFX_WideStringC m_wsVariant;
+ CXFA_FMSimpleExpression * m_pAssignment;
+ CXFA_FMSimpleExpression *m_pAccessor;
+ FX_INT32 m_iDirection;
+ CXFA_FMSimpleExpression *m_pStep;
+ CXFA_FMExpression *m_pList;
+};
+class CXFA_FMForeachExpression : public CXFA_FMLoopExpression
+{
+public:
+ CXFA_FMForeachExpression(FX_DWORD line, FX_WSTR wsIdentifier, CFX_PtrArray *pAccessors, CXFA_FMExpression *pList);
+ virtual ~CXFA_FMForeachExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf&);
+private:
+ CFX_WideStringC m_wsIdentifier;
+ CFX_PtrArray *m_pAccessors;
+ CXFA_FMExpression *m_pList;
+};
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fm2js.cpp b/xfa/src/fxfa/src/fm2js/xfa_fm2js.cpp
new file mode 100644
index 0000000000..3cf1330277
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_fm2js.cpp
@@ -0,0 +1,7 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fm2js.h b/xfa/src/fxfa/src/fm2js/xfa_fm2js.h
new file mode 100644
index 0000000000..abbf491589
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_fm2js.h
@@ -0,0 +1,30 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM2JS_H
+#define _XFA_FM2JS_H
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#define RUNTIMEFUNCTIONRETURNVALUE (FX_WSTRC(L"foxit_xfa_formcalc_runtime_func_return_value"))
+#define EXCLAMATION_IN_IDENTIFIER (FX_WSTRC(L"foxit_xfa_formcalc__exclamation__"))
+typedef CFX_ArrayTemplate<CFX_WideStringC> CFX_WideStringCArray;
+#include "xfa_error.h"
+#include "xfa_lexer.h"
+#include "xfa_simpleexpression.h"
+#include "xfa_expression.h"
+#include "xfa_fmparse.h"
+#include "xfa_program.h"
+#include "xfa_fm2jscontext.h"
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fm2jsapi.cpp b/xfa/src/fxfa/src/fm2js/xfa_fm2jsapi.cpp
new file mode 100644
index 0000000000..8a1b1226f4
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_fm2jsapi.cpp
@@ -0,0 +1,57 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+FX_INT32 XFA_FM2JS_Translate(FX_WSTR wsFormcalc, CFX_WideTextBuf& wsJavascript, CFX_WideString& wsError)
+{
+ if (wsFormcalc.IsEmpty()) {
+ wsJavascript.Clear();
+ wsError.Empty();
+ return 0;
+ }
+ FX_INT32 status = 0;
+ CXFA_FMProgram program;
+ status = program.Init(wsFormcalc);
+ if(status) {
+ wsError = program.GetError().message;
+ return status;
+ }
+ status = program.ParseProgram();
+ if(status) {
+ wsError = program.GetError().message;
+ return status;
+ }
+ program.TranslateProgram(wsJavascript);
+ return 0;
+}
+XFA_HFM2JSCONTEXT XFA_FM2JS_ContextCreate()
+{
+ return (XFA_HFM2JSCONTEXT)CXFA_FM2JSContext::Create();
+}
+void XFA_FM2JS_ContextInitialize(XFA_HFM2JSCONTEXT hFM2JSContext, FXJSE_HRUNTIME hScriptRuntime,
+ FXJSE_HCONTEXT hScriptContext,
+ CXFA_Document* pDocument)
+{
+ CXFA_FM2JSContext *pContext = reinterpret_cast<CXFA_FM2JSContext*>(hFM2JSContext);
+ pContext->Initialize(hScriptRuntime, hScriptContext, pDocument);
+}
+void XFA_FM2JS_GlobalPropertyGetter(XFA_HFM2JSCONTEXT hFM2JSContext, FXJSE_HVALUE hValue)
+{
+ CXFA_FM2JSContext *pContext = reinterpret_cast<CXFA_FM2JSContext*>(hFM2JSContext);
+ pContext->GlobalPropertyGetter(hValue);
+}
+void XFA_FM2JS_ContextRelease(XFA_HFM2JSCONTEXT hFM2JSContext)
+{
+ CXFA_FM2JSContext *pContext = reinterpret_cast<CXFA_FM2JSContext*>(hFM2JSContext);
+ pContext->Release();
+}
+#ifdef __cplusplus
+}
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.cpp b/xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.cpp
new file mode 100644
index 0000000000..b43c900480
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.cpp
@@ -0,0 +1,7185 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+#include <time.h>
+#define FINANCIAL_PRECISION 0.00000001
+struct XFA_FMHtmlReserveCode {
+ FX_UINT32 m_uCode;
+ FX_LPCWSTR m_htmlReserve;
+};
+struct XFA_FMHtmlHashedReserveCode {
+ FX_UINT32 m_uHash;
+ FX_LPCWSTR m_htmlReserve;
+ FX_UINT32 m_uCode;
+};
+static XFA_FMHtmlHashedReserveCode reservesForDecode [] = {
+ {0x00018b62, (FX_LPCWSTR)L"Mu", 924},
+ {0x00019083, (FX_LPCWSTR)L"Nu", 925},
+ {0x00019ab9, (FX_LPCWSTR)L"Pi", 928},
+ {0x0001c3c1, (FX_LPCWSTR)L"Xi", 926},
+ {0x000210ac, (FX_LPCWSTR)L"ge", 8805},
+ {0x000210bb, (FX_LPCWSTR)L"gt", 62},
+ {0x00022a51, (FX_LPCWSTR)L"le", 8804},
+ {0x00022a60, (FX_LPCWSTR)L"lt", 60},
+ {0x00022f82, (FX_LPCWSTR)L"mu", 956},
+ {0x00023493, (FX_LPCWSTR)L"ne", 8800},
+ {0x00023497, (FX_LPCWSTR)L"ni", 8715},
+ {0x000234a3, (FX_LPCWSTR)L"nu", 957},
+ {0x000239c1, (FX_LPCWSTR)L"or", 8744},
+ {0x00023ed9, (FX_LPCWSTR)L"pi", 960},
+ {0x000267e1, (FX_LPCWSTR)L"xi", 958},
+ {0x00c41789, (FX_LPCWSTR)L"lceil", 8968},
+ {0x00eef34f, (FX_LPCWSTR)L"thetasym", 977},
+ {0x012d7ead, (FX_LPCWSTR)L"lcirc", 206},
+ {0x01637b56, (FX_LPCWSTR)L"agrave", 224},
+ {0x020856da, (FX_LPCWSTR)L"crarr", 8629},
+ {0x022188c3, (FX_LPCWSTR)L"gamma", 947},
+ {0x033586d3, (FX_LPCWSTR)L"nbsp", 160},
+ {0x04f4c358, (FX_LPCWSTR)L"nsub", 8836},
+ {0x0581466a, (FX_LPCWSTR)L"dagger", 8224},
+ {0x06b1f790, (FX_LPCWSTR)L"oelig", 339},
+ {0x06e490d4, (FX_LPCWSTR)L"Chi", 935},
+ {0x0718c6a1, (FX_LPCWSTR)L"ETH", 208},
+ {0x07196ada, (FX_LPCWSTR)L"Eta", 919},
+ {0x07f667ca, (FX_LPCWSTR)L"Ugrave", 217},
+ {0x083a8a21, (FX_LPCWSTR)L"Phi", 934},
+ {0x083ac28c, (FX_LPCWSTR)L"Psi", 936},
+ {0x086f26a9, (FX_LPCWSTR)L"Rho", 929},
+ {0x089b5b51, (FX_LPCWSTR)L"aring", 229},
+ {0x08a39f4a, (FX_LPCWSTR)L"Tau", 932},
+ {0x08b6188b, (FX_LPCWSTR)L"THORN", 222},
+ {0x09ce792a, (FX_LPCWSTR)L"icirc", 238},
+ {0x09f9d61e, (FX_LPCWSTR)L"amp", 38},
+ {0x09f9db33, (FX_LPCWSTR)L"and", 8743},
+ {0x09f9db36, (FX_LPCWSTR)L"ang", 8736},
+ {0x0a2e3514, (FX_LPCWSTR)L"cap", 8745},
+ {0x0a2e58f4, (FX_LPCWSTR)L"chi", 967},
+ {0x0a2e9ba8, (FX_LPCWSTR)L"cup", 8746},
+ {0x0a4897d0, (FX_LPCWSTR)L"deg", 176},
+ {0x0a6332fa, (FX_LPCWSTR)L"eta", 951},
+ {0x0a633301, (FX_LPCWSTR)L"eth", 240},
+ {0x0acc4d4b, (FX_LPCWSTR)L"int", 8747},
+ {0x0b1b3d35, (FX_LPCWSTR)L"loz", 9674},
+ {0x0b1b4c8b, (FX_LPCWSTR)L"lrm", 8206},
+ {0x0b4fd9b1, (FX_LPCWSTR)L"not", 172},
+ {0x0b845241, (FX_LPCWSTR)L"phi", 966},
+ {0x0b84576f, (FX_LPCWSTR)L"piv", 982},
+ {0x0b848aac, (FX_LPCWSTR)L"psi", 968},
+ {0x0bb8df5e, (FX_LPCWSTR)L"reg", 174},
+ {0x0bb8eec9, (FX_LPCWSTR)L"rho", 961},
+ {0x0bb9034b, (FX_LPCWSTR)L"rlm", 8207},
+ {0x0bd33d14, (FX_LPCWSTR)L"shy", 173},
+ {0x0bd34229, (FX_LPCWSTR)L"sim", 8764},
+ {0x0bd37faa, (FX_LPCWSTR)L"sub", 8834},
+ {0x0bd37fb5, (FX_LPCWSTR)L"sum", 8721},
+ {0x0bd37fb8, (FX_LPCWSTR)L"sup", 8835},
+ {0x0bed676a, (FX_LPCWSTR)L"tau", 964},
+ {0x0c07f32e, (FX_LPCWSTR)L"uml", 168},
+ {0x0c71032c, (FX_LPCWSTR)L"yen", 165},
+ {0x0c7f2889, (FX_LPCWSTR)L"szlig", 223},
+ {0x0c8badbb, (FX_LPCWSTR)L"zwj", 8205},
+ {0x10ba4dba, (FX_LPCWSTR)L"Egrave", 200},
+ {0x10f1ea24, (FX_LPCWSTR)L"para", 182},
+ {0x10f1ea37, (FX_LPCWSTR)L"part", 8706},
+ {0x115b2337, (FX_LPCWSTR)L"perp", 8869},
+ {0x12b10d15, (FX_LPCWSTR)L"prod", 8719},
+ {0x12b10d21, (FX_LPCWSTR)L"prop", 8733},
+ {0x12dfa9f4, (FX_LPCWSTR)L"rfloor", 8971},
+ {0x12eb4736, (FX_LPCWSTR)L"Agrave", 192},
+ {0x12fff2b7, (FX_LPCWSTR)L"pund", 163},
+ {0x13fda9f2, (FX_LPCWSTR)L"tilde", 732},
+ {0x1417fd62, (FX_LPCWSTR)L"times", 215},
+ {0x154fc726, (FX_LPCWSTR)L"ecirc", 234},
+ {0x165aa451, (FX_LPCWSTR)L"sigma", 963},
+ {0x1709124a, (FX_LPCWSTR)L"Dagger", 8225},
+ {0x192f78d5, (FX_LPCWSTR)L"iexcl", 161},
+ {0x1b7ed8d7, (FX_LPCWSTR)L"rArr", 8658},
+ {0x1ec88c68, (FX_LPCWSTR)L"rang", 9002},
+ {0x1ec8a0f7, (FX_LPCWSTR)L"rarr", 8594},
+ {0x1eda07f3, (FX_LPCWSTR)L"atilde", 227},
+ {0x1f3182c4, (FX_LPCWSTR)L"real", 8476},
+ {0x1fc34f8b, (FX_LPCWSTR)L"yacute", 253},
+ {0x20d11522, (FX_LPCWSTR)L"acirc", 226},
+ {0x21933a9b, (FX_LPCWSTR)L"rsaquo", 8250},
+ {0x21f44907, (FX_LPCWSTR)L"uacute", 250},
+ {0x220cca72, (FX_LPCWSTR)L"acute", 180},
+ {0x242cded1, (FX_LPCWSTR)L"alefsym", 8501},
+ {0x2655c66a, (FX_LPCWSTR)L"delta", 948},
+ {0x269e4b4d, (FX_LPCWSTR)L"exist", 8707},
+ {0x273379fa, (FX_LPCWSTR)L"micro", 181},
+ {0x27a37440, (FX_LPCWSTR)L"forall", 8704},
+ {0x2854e62c, (FX_LPCWSTR)L"minus", 8722},
+ {0x28636f81, (FX_LPCWSTR)L"cedil", 184},
+ {0x2887357b, (FX_LPCWSTR)L"iacute", 237},
+ {0x2994d5ff, (FX_LPCWSTR)L"frac12", 189},
+ {0x2994d601, (FX_LPCWSTR)L"frac14", 188},
+ {0x2994e043, (FX_LPCWSTR)L"frac34", 190},
+ {0x2a1feb41, (FX_LPCWSTR)L"lambda", 955},
+ {0x2ab215f3, (FX_LPCWSTR)L"apos", 39},
+ {0x2ab82ef7, (FX_LPCWSTR)L"eacute", 233},
+ {0x2b3592ef, (FX_LPCWSTR)L"auml", 228},
+ {0x2ce92873, (FX_LPCWSTR)L"aacute", 225},
+ {0x2daff48a, (FX_LPCWSTR)L"oslash", 248},
+ {0x2ef68882, (FX_LPCWSTR)L"aelig", 230},
+ {0x3061d3d3, (FX_LPCWSTR)L"Atilde", 195},
+ {0x314b1b6b, (FX_LPCWSTR)L"Yacute", 221},
+ {0x337c14e7, (FX_LPCWSTR)L"Uacute", 218},
+ {0x37676aca, (FX_LPCWSTR)L"cent", 162},
+ {0x37d0b841, (FX_LPCWSTR)L"circ", 710},
+ {0x386e7947, (FX_LPCWSTR)L"cong", 8773},
+ {0x386e839b, (FX_LPCWSTR)L"copy", 169},
+ {0x3a0e225a, (FX_LPCWSTR)L"Epsilon", 917},
+ {0x3ba7b721, (FX_LPCWSTR)L"Lambda", 923},
+ {0x3bd9abe6, (FX_LPCWSTR)L"Alpha", 913},
+ {0x3c3ffad7, (FX_LPCWSTR)L"Eacute", 201},
+ {0x3cfaf69f, (FX_LPCWSTR)L"brvbar", 166},
+ {0x3d54a489, (FX_LPCWSTR)L"omega", 969},
+ {0x3e70f453, (FX_LPCWSTR)L"Aacute", 193},
+ {0x3f37c06a, (FX_LPCWSTR)L"Oslash", 216},
+ {0x40e1b34e, (FX_LPCWSTR)L"diams", 9830},
+ {0x416596df, (FX_LPCWSTR)L"plusmn", 177},
+ {0x4354ff16, (FX_LPCWSTR)L"Ucirc", 219},
+ {0x454fce6a, (FX_LPCWSTR)L"Upsilon", 933},
+ {0x4610ad35, (FX_LPCWSTR)L"emsp", 8195},
+ {0x462afb76, (FX_LPCWSTR)L"ensp", 8194},
+ {0x46e30073, (FX_LPCWSTR)L"euml", 235},
+ {0x46e31a1b, (FX_LPCWSTR)L"euro", 8364},
+ {0x46f2eada, (FX_LPCWSTR)L"lowast", 8727},
+ {0x4dca26cf, (FX_LPCWSTR)L"Auml", 196},
+ {0x4e2d6083, (FX_LPCWSTR)L"image", 8465},
+ {0x4f964ee8, (FX_LPCWSTR)L"notin", 8713},
+ {0x50917a7a, (FX_LPCWSTR)L"epsilon", 949},
+ {0x52f9a4cd, (FX_LPCWSTR)L"Kappa", 922},
+ {0x5496f410, (FX_LPCWSTR)L"Ocirc", 212},
+ {0x568cbf34, (FX_LPCWSTR)L"zeta", 950},
+ {0x57badd20, (FX_LPCWSTR)L"ntilde", 241},
+ {0x58662109, (FX_LPCWSTR)L"zwnj", 8204},
+ {0x5b39870f, (FX_LPCWSTR)L"empty", 8709},
+ {0x5bd3268a, (FX_LPCWSTR)L"upsilon", 965},
+ {0x5e2bf8a3, (FX_LPCWSTR)L"Gamma", 915},
+ {0x5f73c13a, (FX_LPCWSTR)L"rsquo", 8217},
+ {0x61f2bc4d, (FX_LPCWSTR)L"iota", 953},
+ {0x625bbcf3, (FX_LPCWSTR)L"isin", 8712},
+ {0x62906df7, (FX_LPCWSTR)L"iuml", 239},
+ {0x64a5cb31, (FX_LPCWSTR)L"Aring", 197},
+ {0x66f25c4a, (FX_LPCWSTR)L"sbquo", 8218},
+ {0x6851ab60, (FX_LPCWSTR)L"spades", 9824},
+ {0x6942a900, (FX_LPCWSTR)L"Ntilde", 209},
+ {0x69779453, (FX_LPCWSTR)L"Euml", 203},
+ {0x6cda6e23, (FX_LPCWSTR)L"current", 164},
+ {0x70b5b634, (FX_LPCWSTR)L"lsquo", 8216},
+ {0x715a3706, (FX_LPCWSTR)L"Ecirc", 202},
+ {0x71e8bf8d, (FX_LPCWSTR)L"tdquo", 8221},
+ {0x72651431, (FX_LPCWSTR)L"Sigma", 931},
+ {0x7569813b, (FX_LPCWSTR)L"iquest", 191},
+ {0x776a436a, (FX_LPCWSTR)L"equiv", 8801},
+ {0x79215314, (FX_LPCWSTR)L"Zeta", 918},
+ {0x79b81224, (FX_LPCWSTR)L"ograve", 242},
+ {0x7c2f8b23, (FX_LPCWSTR)L"macr", 175},
+ {0x7cdb8502, (FX_LPCWSTR)L"Acirc", 194},
+ {0x8185c62e, (FX_LPCWSTR)L"ndash", 8211},
+ {0x8260364a, (FX_LPCWSTR)L"Delta", 916},
+ {0x846619ad, (FX_LPCWSTR)L"mdash", 8212},
+ {0x8550fb50, (FX_LPCWSTR)L"OElig", 338},
+ {0x88eb5b85, (FX_LPCWSTR)L"ldquo", 8220},
+ {0x8b3fde04, (FX_LPCWSTR)L"Ograve", 210},
+ {0x8bc5794b, (FX_LPCWSTR)L"ordf", 170},
+ {0x8bc57952, (FX_LPCWSTR)L"ordm", 186},
+ {0x8c14923d, (FX_LPCWSTR)L"ouml", 246},
+ {0x8c5a7cd6, (FX_LPCWSTR)L"theta", 952},
+ {0x8d61812b, (FX_LPCWSTR)L"thorn", 254},
+ {0x912b95aa, (FX_LPCWSTR)L"asymp", 8776},
+ {0x947faf81, (FX_LPCWSTR)L"middot", 183},
+ {0x9629202e, (FX_LPCWSTR)L"lfloor", 8970},
+ {0x972e9ec1, (FX_LPCWSTR)L"otilde", 245},
+ {0x9748f231, (FX_LPCWSTR)L"otimes", 8855},
+ {0x995f1469, (FX_LPCWSTR)L"Omega", 937},
+ {0x99eb5349, (FX_LPCWSTR)L"quot", 34},
+ {0x9aeb639e, (FX_LPCWSTR)L"hellip", 8230},
+ {0xa0ae2f86, (FX_LPCWSTR)L"Scaron", 352},
+ {0xa4dcb0d5, (FX_LPCWSTR)L"lsaquo", 8249},
+ {0xa53dbf41, (FX_LPCWSTR)L"oacute", 243},
+ {0xa5ae9e7b, (FX_LPCWSTR)L"bdquo", 8222},
+ {0xa602d7ba, (FX_LPCWSTR)L"sdot", 8901},
+ {0xa61ce86f, (FX_LPCWSTR)L"sect", 167},
+ {0xa6e4c3d7, (FX_LPCWSTR)L"sigmaf", 962},
+ {0xa7c1c74f, (FX_LPCWSTR)L"sube", 8838},
+ {0xa7c20ee9, (FX_LPCWSTR)L"sup1", 185},
+ {0xa7c20eea, (FX_LPCWSTR)L"sup2", 178},
+ {0xa7c20eeb, (FX_LPCWSTR)L"sup3", 179},
+ {0xa7c20f1d, (FX_LPCWSTR)L"supe", 8839},
+ {0xa8b66aa1, (FX_LPCWSTR)L"Otilde", 213},
+ {0xad958c42, (FX_LPCWSTR)L"AElig", 198},
+ {0xaea9261d, (FX_LPCWSTR)L"Ouml", 214},
+ {0xb040eafa, (FX_LPCWSTR)L"uArr", 8657},
+ {0xb07c2e1c, (FX_LPCWSTR)L"beta", 946},
+ {0xb220e92f, (FX_LPCWSTR)L"bull", 8226},
+ {0xb22750c4, (FX_LPCWSTR)L"ccedil", 231},
+ {0xb38ab31a, (FX_LPCWSTR)L"uarr", 8593},
+ {0xb598b683, (FX_LPCWSTR)L"uuml", 252},
+ {0xb6c58b21, (FX_LPCWSTR)L"Oacute", 211},
+ {0xb6d2a617, (FX_LPCWSTR)L"oline", 8254},
+ {0xba9fd989, (FX_LPCWSTR)L"dArr", 8659},
+ {0xbb5ccd41, (FX_LPCWSTR)L"lgrave", 204},
+ {0xbd39b44c, (FX_LPCWSTR)L"weierp", 8472},
+ {0xbde9a1a9, (FX_LPCWSTR)L"darr", 8595},
+ {0xc027e329, (FX_LPCWSTR)L"permil", 8240},
+ {0xc2451389, (FX_LPCWSTR)L"upsih", 978},
+ {0xc3af1ca4, (FX_LPCWSTR)L"Ccedil", 199},
+ {0xcd164249, (FX_LPCWSTR)L"fnof", 402},
+ {0xcf6c8467, (FX_LPCWSTR)L"hearts", 9829},
+ {0xd1228390, (FX_LPCWSTR)L"trade", 8482},
+ {0xd1462407, (FX_LPCWSTR)L"yuml", 255},
+ {0xd2cf2253, (FX_LPCWSTR)L"oplus", 8853},
+ {0xd310c1fc, (FX_LPCWSTR)L"Beta", 914},
+ {0xd59c4d74, (FX_LPCWSTR)L"infin", 8734},
+ {0xd64d470d, (FX_LPCWSTR)L"hArr", 8660},
+ {0xd67d9c75, (FX_LPCWSTR)L"divide", 247},
+ {0xd698dd37, (FX_LPCWSTR)L"Omicron", 927},
+ {0xd82d4a63, (FX_LPCWSTR)L"Uuml", 220},
+ {0xd9970f2d, (FX_LPCWSTR)L"harr", 8596},
+ {0xda91fd99, (FX_LPCWSTR)L"clubs", 9827},
+ {0xdbe5bdcc, (FX_LPCWSTR)L"there4", 8756},
+ {0xdd7671bd, (FX_LPCWSTR)L"prime", 8242},
+ {0xdfcf3c06, (FX_LPCWSTR)L"alpha", 945},
+ {0xe0213063, (FX_LPCWSTR)L"saron", 353},
+ {0xe1911d83, (FX_LPCWSTR)L"radic", 8730},
+ {0xe2e75468, (FX_LPCWSTR)L"raquo", 187},
+ {0xe6e27a5e, (FX_LPCWSTR)L"lacute", 205},
+ {0xe74a8f36, (FX_LPCWSTR)L"ucirc", 251},
+ {0xe864ecb6, (FX_LPCWSTR)L"Theta", 920},
+ {0xecddde5e, (FX_LPCWSTR)L"nabla", 8711},
+ {0xed1c3557, (FX_LPCWSTR)L"omicron", 959},
+ {0xef82228f, (FX_LPCWSTR)L"rceil", 8969},
+ {0xf1fab491, (FX_LPCWSTR)L"lArr", 8656},
+ {0xf3dab7e7, (FX_LPCWSTR)L"Yuml", 376},
+ {0xf4294962, (FX_LPCWSTR)L"laquo", 171},
+ {0xf5446822, (FX_LPCWSTR)L"lang", 9001},
+ {0xf5447cb1, (FX_LPCWSTR)L"larr", 8592},
+ {0xf66e9bea, (FX_LPCWSTR)L"ugrave", 249},
+ {0xf6b4ce70, (FX_LPCWSTR)L"lota", 921},
+ {0xf6ef34ed, (FX_LPCWSTR)L"kappa", 954},
+ {0xf72a3a56, (FX_LPCWSTR)L"thinsp", 8201},
+ {0xf752801a, (FX_LPCWSTR)L"luml", 207},
+ {0xf88c8430, (FX_LPCWSTR)L"ocirc", 244},
+ {0xf9676178, (FX_LPCWSTR)L"frasl", 8260},
+ {0xfd01885e, (FX_LPCWSTR)L"igrave", 236},
+ {0xff3281da, (FX_LPCWSTR)L"egrave", 232},
+};
+static XFA_FMHtmlReserveCode reservesForEncode [] = {
+ {34, (FX_LPCWSTR)(L"quot")},
+ {38, (FX_LPCWSTR)(L"amp")},
+ {39, (FX_LPCWSTR)(L"apos")},
+ {60, (FX_LPCWSTR)(L"lt")},
+ {62, (FX_LPCWSTR)(L"gt")},
+ {160, (FX_LPCWSTR)(L"nbsp")},
+ {161, (FX_LPCWSTR)(L"iexcl")},
+ {162, (FX_LPCWSTR)(L"cent")},
+ {163, (FX_LPCWSTR)(L"pund")},
+ {164, (FX_LPCWSTR)(L"current")},
+ {165, (FX_LPCWSTR)(L"yen")},
+ {166, (FX_LPCWSTR)(L"brvbar")},
+ {167, (FX_LPCWSTR)(L"sect")},
+ {168, (FX_LPCWSTR)(L"uml")},
+ {169, (FX_LPCWSTR)(L"copy")},
+ {170, (FX_LPCWSTR)(L"ordf")},
+ {171, (FX_LPCWSTR)(L"laquo")},
+ {172, (FX_LPCWSTR)(L"not")},
+ {173, (FX_LPCWSTR)(L"shy")},
+ {174, (FX_LPCWSTR)(L"reg")},
+ {175, (FX_LPCWSTR)(L"macr")},
+ {176, (FX_LPCWSTR)(L"deg")},
+ {177, (FX_LPCWSTR)(L"plusmn")},
+ {178, (FX_LPCWSTR)(L"sup2")},
+ {179, (FX_LPCWSTR)(L"sup3")},
+ {180, (FX_LPCWSTR)(L"acute")},
+ {181, (FX_LPCWSTR)(L"micro")},
+ {182, (FX_LPCWSTR)(L"para")},
+ {183, (FX_LPCWSTR)(L"middot")},
+ {184, (FX_LPCWSTR)(L"cedil")},
+ {185, (FX_LPCWSTR)(L"sup1")},
+ {186, (FX_LPCWSTR)(L"ordm")},
+ {187, (FX_LPCWSTR)(L"raquo")},
+ {188, (FX_LPCWSTR)(L"frac14")},
+ {189, (FX_LPCWSTR)(L"frac12")},
+ {190, (FX_LPCWSTR)(L"frac34")},
+ {191, (FX_LPCWSTR)(L"iquest")},
+ {192, (FX_LPCWSTR)(L"Agrave")},
+ {193, (FX_LPCWSTR)(L"Aacute")},
+ {194, (FX_LPCWSTR)(L"Acirc")},
+ {195, (FX_LPCWSTR)(L"Atilde")},
+ {196, (FX_LPCWSTR)(L"Auml")},
+ {197, (FX_LPCWSTR)(L"Aring")},
+ {198, (FX_LPCWSTR)(L"AElig")},
+ {199, (FX_LPCWSTR)(L"Ccedil")},
+ {200, (FX_LPCWSTR)(L"Egrave")},
+ {201, (FX_LPCWSTR)(L"Eacute")},
+ {202, (FX_LPCWSTR)(L"Ecirc")},
+ {203, (FX_LPCWSTR)(L"Euml")},
+ {204, (FX_LPCWSTR)(L"lgrave")},
+ {205, (FX_LPCWSTR)(L"lacute")},
+ {206, (FX_LPCWSTR)(L"lcirc")},
+ {207, (FX_LPCWSTR)(L"luml")},
+ {208, (FX_LPCWSTR)(L"ETH")},
+ {209, (FX_LPCWSTR)(L"Ntilde")},
+ {210, (FX_LPCWSTR)(L"Ograve")},
+ {211, (FX_LPCWSTR)(L"Oacute")},
+ {212, (FX_LPCWSTR)(L"Ocirc")},
+ {213, (FX_LPCWSTR)(L"Otilde")},
+ {214, (FX_LPCWSTR)(L"Ouml")},
+ {215, (FX_LPCWSTR)(L"times")},
+ {216, (FX_LPCWSTR)(L"Oslash")},
+ {217, (FX_LPCWSTR)(L"Ugrave")},
+ {218, (FX_LPCWSTR)(L"Uacute")},
+ {219, (FX_LPCWSTR)(L"Ucirc")},
+ {220, (FX_LPCWSTR)(L"Uuml")},
+ {221, (FX_LPCWSTR)(L"Yacute")},
+ {222, (FX_LPCWSTR)(L"THORN")},
+ {223, (FX_LPCWSTR)(L"szlig")},
+ {224, (FX_LPCWSTR)(L"agrave")},
+ {225, (FX_LPCWSTR)(L"aacute")},
+ {226, (FX_LPCWSTR)(L"acirc")},
+ {227, (FX_LPCWSTR)(L"atilde")},
+ {228, (FX_LPCWSTR)(L"auml")},
+ {229, (FX_LPCWSTR)(L"aring")},
+ {230, (FX_LPCWSTR)(L"aelig") },
+ {231, (FX_LPCWSTR)(L"ccedil") },
+ {232, (FX_LPCWSTR)(L"egrave") },
+ {233, (FX_LPCWSTR)(L"eacute") },
+ {234, (FX_LPCWSTR)(L"ecirc") },
+ {235, (FX_LPCWSTR)(L"euml") },
+ {236, (FX_LPCWSTR)(L"igrave") },
+ {237, (FX_LPCWSTR)(L"iacute") },
+ {238, (FX_LPCWSTR)(L"icirc") },
+ {239, (FX_LPCWSTR)(L"iuml") },
+ {240, (FX_LPCWSTR)(L"eth") },
+ {241, (FX_LPCWSTR)(L"ntilde") },
+ {242, (FX_LPCWSTR)(L"ograve") },
+ {243, (FX_LPCWSTR)(L"oacute") },
+ {244, (FX_LPCWSTR)(L"ocirc") },
+ {245, (FX_LPCWSTR)(L"otilde") },
+ {246, (FX_LPCWSTR)(L"ouml") },
+ {247, (FX_LPCWSTR)(L"divide") },
+ {248, (FX_LPCWSTR)(L"oslash") },
+ {249, (FX_LPCWSTR)(L"ugrave") },
+ {250, (FX_LPCWSTR)(L"uacute") },
+ {251, (FX_LPCWSTR)(L"ucirc") },
+ {252, (FX_LPCWSTR)(L"uuml") },
+ {253, (FX_LPCWSTR)(L"yacute") },
+ {254, (FX_LPCWSTR)(L"thorn") },
+ {255, (FX_LPCWSTR)(L"yuml") },
+ {338, (FX_LPCWSTR)(L"OElig") },
+ {339, (FX_LPCWSTR)(L"oelig") },
+ {352, (FX_LPCWSTR)(L"Scaron") },
+ {353, (FX_LPCWSTR)(L"saron") },
+ {376, (FX_LPCWSTR)(L"Yuml") },
+ {402, (FX_LPCWSTR)(L"fnof") },
+ {710, (FX_LPCWSTR)(L"circ") },
+ {732, (FX_LPCWSTR)(L"tilde") },
+ {913, (FX_LPCWSTR)(L"Alpha") },
+ {914, (FX_LPCWSTR)(L"Beta") },
+ {915, (FX_LPCWSTR)(L"Gamma") },
+ {916, (FX_LPCWSTR)(L"Delta") },
+ {917, (FX_LPCWSTR)(L"Epsilon") },
+ {918, (FX_LPCWSTR)(L"Zeta") },
+ {919, (FX_LPCWSTR)(L"Eta") },
+ {920, (FX_LPCWSTR)(L"Theta") },
+ {921, (FX_LPCWSTR)(L"lota") },
+ {922, (FX_LPCWSTR)(L"Kappa") },
+ {923, (FX_LPCWSTR)(L"Lambda") },
+ {924, (FX_LPCWSTR)(L"Mu") },
+ {925, (FX_LPCWSTR)(L"Nu") },
+ {926, (FX_LPCWSTR)(L"Xi") },
+ {927, (FX_LPCWSTR)(L"Omicron") },
+ {928, (FX_LPCWSTR)(L"Pi") },
+ {929, (FX_LPCWSTR)(L"Rho") },
+ {931, (FX_LPCWSTR)(L"Sigma") },
+ {932, (FX_LPCWSTR)(L"Tau") },
+ {933, (FX_LPCWSTR)(L"Upsilon") },
+ {934, (FX_LPCWSTR)(L"Phi") },
+ {935, (FX_LPCWSTR)(L"Chi") },
+ {936, (FX_LPCWSTR)(L"Psi") },
+ {937, (FX_LPCWSTR)(L"Omega") },
+ {945, (FX_LPCWSTR)(L"alpha") },
+ {946, (FX_LPCWSTR)(L"beta") },
+ {947, (FX_LPCWSTR)(L"gamma") },
+ {948, (FX_LPCWSTR)(L"delta") },
+ {949, (FX_LPCWSTR)(L"epsilon") },
+ {950, (FX_LPCWSTR)(L"zeta") },
+ {951, (FX_LPCWSTR)(L"eta") },
+ {952, (FX_LPCWSTR)(L"theta") },
+ {953, (FX_LPCWSTR)(L"iota") },
+ {954, (FX_LPCWSTR)(L"kappa") },
+ {955, (FX_LPCWSTR)(L"lambda") },
+ {956, (FX_LPCWSTR)(L"mu") },
+ {957, (FX_LPCWSTR)(L"nu") },
+ {958, (FX_LPCWSTR)(L"xi") },
+ {959, (FX_LPCWSTR)(L"omicron") },
+ {960, (FX_LPCWSTR)(L"pi") },
+ {961, (FX_LPCWSTR)(L"rho") },
+ {962, (FX_LPCWSTR)(L"sigmaf") },
+ {963, (FX_LPCWSTR)(L"sigma") },
+ {964, (FX_LPCWSTR)(L"tau") },
+ {965, (FX_LPCWSTR)(L"upsilon") },
+ {966, (FX_LPCWSTR)(L"phi") },
+ {967, (FX_LPCWSTR)(L"chi") },
+ {968, (FX_LPCWSTR)(L"psi") },
+ {969, (FX_LPCWSTR)(L"omega") },
+ {977, (FX_LPCWSTR)(L"thetasym") },
+ {978, (FX_LPCWSTR)(L"upsih") },
+ {982, (FX_LPCWSTR)(L"piv") },
+ {8194, (FX_LPCWSTR)(L"ensp") },
+ {8195, (FX_LPCWSTR)(L"emsp") },
+ {8201, (FX_LPCWSTR)(L"thinsp") },
+ {8204, (FX_LPCWSTR)(L"zwnj") },
+ {8205, (FX_LPCWSTR)(L"zwj") },
+ {8206, (FX_LPCWSTR)(L"lrm") },
+ {8207, (FX_LPCWSTR)(L"rlm") },
+ {8211, (FX_LPCWSTR)(L"ndash") },
+ {8212, (FX_LPCWSTR)(L"mdash") },
+ {8216, (FX_LPCWSTR)(L"lsquo") },
+ {8217, (FX_LPCWSTR)(L"rsquo") },
+ {8218, (FX_LPCWSTR)(L"sbquo") },
+ {8220, (FX_LPCWSTR)(L"ldquo") },
+ {8221, (FX_LPCWSTR)(L"tdquo") },
+ {8222, (FX_LPCWSTR)(L"bdquo") },
+ {8224, (FX_LPCWSTR)(L"dagger") },
+ {8225, (FX_LPCWSTR)(L"Dagger") },
+ {8226, (FX_LPCWSTR)(L"bull") },
+ {8230, (FX_LPCWSTR)(L"hellip") },
+ {8240, (FX_LPCWSTR)(L"permil") },
+ {8242, (FX_LPCWSTR)(L"prime") },
+ {8249, (FX_LPCWSTR)(L"lsaquo") },
+ {8250, (FX_LPCWSTR)(L"rsaquo") },
+ {8254, (FX_LPCWSTR)(L"oline") },
+ {8260, (FX_LPCWSTR)(L"frasl") },
+ {8364, (FX_LPCWSTR)(L"euro") },
+ {8465, (FX_LPCWSTR)(L"image") },
+ {8472, (FX_LPCWSTR)(L"weierp") },
+ {8476, (FX_LPCWSTR)(L"real") },
+ {8482, (FX_LPCWSTR)(L"trade") },
+ {8501, (FX_LPCWSTR)(L"alefsym") },
+ {8592, (FX_LPCWSTR)(L"larr") },
+ {8593, (FX_LPCWSTR)(L"uarr") },
+ {8594, (FX_LPCWSTR)(L"rarr") },
+ {8595, (FX_LPCWSTR)(L"darr") },
+ {8596, (FX_LPCWSTR)(L"harr") },
+ {8629, (FX_LPCWSTR)(L"crarr") },
+ {8656, (FX_LPCWSTR)(L"lArr") },
+ {8657, (FX_LPCWSTR)(L"uArr") },
+ {8658, (FX_LPCWSTR)(L"rArr") },
+ {8659, (FX_LPCWSTR)(L"dArr") },
+ {8660, (FX_LPCWSTR)(L"hArr") },
+ {8704, (FX_LPCWSTR)(L"forall") },
+ {8706, (FX_LPCWSTR)(L"part") },
+ {8707, (FX_LPCWSTR)(L"exist") },
+ {8709, (FX_LPCWSTR)(L"empty") },
+ {8711, (FX_LPCWSTR)(L"nabla") },
+ {8712, (FX_LPCWSTR)(L"isin") },
+ {8713, (FX_LPCWSTR)(L"notin") },
+ {8715, (FX_LPCWSTR)(L"ni") },
+ {8719, (FX_LPCWSTR)(L"prod") },
+ {8721, (FX_LPCWSTR)(L"sum") },
+ {8722, (FX_LPCWSTR)(L"minus") },
+ {8727, (FX_LPCWSTR)(L"lowast") },
+ {8730, (FX_LPCWSTR)(L"radic") },
+ {8733, (FX_LPCWSTR)(L"prop") },
+ {8734, (FX_LPCWSTR)(L"infin") },
+ {8736, (FX_LPCWSTR)(L"ang") },
+ {8743, (FX_LPCWSTR)(L"and") },
+ {8744, (FX_LPCWSTR)(L"or") },
+ {8745, (FX_LPCWSTR)(L"cap") },
+ {8746, (FX_LPCWSTR)(L"cup") },
+ {8747, (FX_LPCWSTR)(L"int") },
+ {8756, (FX_LPCWSTR)(L"there4") },
+ {8764, (FX_LPCWSTR)(L"sim") },
+ {8773, (FX_LPCWSTR)(L"cong") },
+ {8776, (FX_LPCWSTR)(L"asymp") },
+ {8800, (FX_LPCWSTR)(L"ne") },
+ {8801, (FX_LPCWSTR)(L"equiv") },
+ {8804, (FX_LPCWSTR)(L"le") },
+ {8805, (FX_LPCWSTR)(L"ge") },
+ {8834, (FX_LPCWSTR)(L"sub") },
+ {8835, (FX_LPCWSTR)(L"sup") },
+ {8836, (FX_LPCWSTR)(L"nsub") },
+ {8838, (FX_LPCWSTR)(L"sube") },
+ {8839, (FX_LPCWSTR)(L"supe") },
+ {8853, (FX_LPCWSTR)(L"oplus") },
+ {8855, (FX_LPCWSTR)(L"otimes") },
+ {8869, (FX_LPCWSTR)(L"perp") },
+ {8901, (FX_LPCWSTR)(L"sdot") },
+ {8968, (FX_LPCWSTR)(L"lceil") },
+ {8969, (FX_LPCWSTR)(L"rceil") },
+ {8970, (FX_LPCWSTR)(L"lfloor") },
+ {8971, (FX_LPCWSTR)(L"rfloor") },
+ {9001, (FX_LPCWSTR)(L"lang") },
+ {9002, (FX_LPCWSTR)(L"rang") },
+ {9674, (FX_LPCWSTR)(L"loz") },
+ {9824, (FX_LPCWSTR)(L"spades") },
+ {9827, (FX_LPCWSTR)(L"clubs") },
+ {9829, (FX_LPCWSTR)(L"hearts") },
+ {9830, (FX_LPCWSTR)(L"diams") },
+};
+void CXFA_FM2JSContext::Abs(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if(args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ if(HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, argOne);
+ if(dValue < 0) {
+ dValue = -dValue;
+ }
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dValue);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Abs"));
+ }
+}
+void CXFA_FM2JSContext::Avg(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ FX_UINT32 uCount = 0;
+ FX_DOUBLE dSum = 0.0;
+ if(argc >= 1) {
+ FXJSE_HVALUE argValue = 0;
+ for(FX_INT32 i = 0; i < argc; i++) {
+ argValue = args.GetValue(i);
+ if(FXJSE_Value_IsNull(argValue)) {
+ FXJSE_Value_Release(argValue);
+ continue;
+ } else if(FXJSE_Value_IsArray(argValue)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argValue, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if(iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ for(FX_INT32 j = 2; j < iLength; j++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+ FXJSE_HVALUE defaultPropValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(jsObjectValue, defaultPropValue);
+ if (!FXJSE_Value_IsNull(defaultPropValue)) {
+ dSum += HValueToDouble(hThis, defaultPropValue);
+ uCount++;
+ }
+ FXJSE_Value_Release(defaultPropValue);
+ }
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ for(FX_INT32 j = 2; j < iLength; j++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ if (!FXJSE_Value_IsNull(newPropertyValue)) {
+ dSum += HValueToDouble(hThis, newPropertyValue);
+ uCount++;
+ }
+ }
+ FXJSE_Value_Release(newPropertyValue);
+ }
+ FXJSE_Value_Release(jsObjectValue);
+ FXJSE_Value_Release(propertyValue);
+ }
+ } else {
+ dSum += HValueToDouble(hThis, argValue);
+ uCount++;
+ }
+ FXJSE_Value_Release(argValue);
+ }
+ argValue = 0;
+ }
+ if(0 == uCount) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dSum / uCount);
+ }
+}
+void CXFA_FM2JSContext::Ceil(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if(args.GetLength() == 1) {
+ FXJSE_HVALUE argValue = GetSimpleHValue(hThis, args, 0);
+ if (HValueIsNull(hThis, argValue)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FXJSE_Value_SetFloat(args.GetReturnValue(), FXSYS_ceil(HValueToFloat(hThis, argValue)));
+ }
+ FXJSE_Value_Release(argValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Ceil"));
+ }
+}
+void CXFA_FM2JSContext::Count(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ FX_UINT32 uCount = 0;
+ FXJSE_HVALUE argValue = 0;
+ for(FX_INT32 i = 0; i < argc; i++) {
+ argValue = args.GetValue(i);
+ if(FXJSE_Value_IsNull(argValue)) {
+ FXJSE_Value_Release(argValue);
+ continue;
+ } else if(FXJSE_Value_IsArray(argValue)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argValue, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if(iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+ GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+ if (!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ }
+ }
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ uCount += (FXJSE_Value_IsNull(newPropertyValue) ? 0 : 1);
+ }
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ FXJSE_Value_Release(newPropertyValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else if(FXJSE_Value_IsObject(argValue)) {
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(argValue, newPropertyValue);
+ if (!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ }
+ FXJSE_Value_Release(newPropertyValue);
+ } else {
+ uCount++;
+ }
+ FXJSE_Value_Release(argValue);
+ }
+ argValue = 0;
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (FX_INT32)uCount);
+}
+void CXFA_FM2JSContext::Floor(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if(args.GetLength() == 1) {
+ FXJSE_HVALUE argValue = GetSimpleHValue(hThis, args, 0);
+ if (HValueIsNull(hThis, argValue)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FXJSE_Value_SetFloat(args.GetReturnValue(), FXSYS_floor(HValueToFloat(hThis, argValue)));
+ }
+ FXJSE_Value_Release(argValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Floor"));
+ }
+}
+void CXFA_FM2JSContext::Max(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ FX_UINT32 uCount = 0;
+ FX_DOUBLE dMaxValue = 0.0;
+ FXJSE_HVALUE argValue = 0;
+ for(FX_INT32 i = 0; i < argc; i++) {
+ argValue = args.GetValue(i);
+ if(FXJSE_Value_IsNull(argValue)) {
+ FXJSE_Value_Release(argValue);
+ continue;
+ } else if(FXJSE_Value_IsArray(argValue)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argValue, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if(iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+ GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+ if(!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ if(uCount == 1) {
+ dMaxValue = HValueToDouble(hThis, newPropertyValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+ if(dMaxValue < dValue) {
+ dMaxValue = dValue;
+ }
+ }
+ }
+ }
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ if(!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ if(uCount == 1) {
+ dMaxValue = HValueToDouble(hThis, newPropertyValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+ if(dMaxValue < dValue) {
+ dMaxValue = dValue;
+ }
+ }
+ }
+ }
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ FXJSE_Value_Release(newPropertyValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else if(FXJSE_Value_IsObject(argValue)) {
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(argValue, newPropertyValue);
+ if(!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ if(uCount == 1) {
+ dMaxValue = HValueToDouble(hThis, newPropertyValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+ if(dMaxValue < dValue) {
+ dMaxValue = dValue;
+ }
+ }
+ }
+ FXJSE_Value_Release(newPropertyValue);
+ } else {
+ uCount++;
+ if(uCount == 1) {
+ dMaxValue = HValueToDouble(hThis, argValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, argValue);
+ if(dMaxValue < dValue) {
+ dMaxValue = dValue;
+ }
+ }
+ }
+ FXJSE_Value_Release(argValue);
+ }
+ argValue = 0;
+ if(uCount) {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dMaxValue);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+}
+void CXFA_FM2JSContext::Min(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ FX_UINT32 uCount = 0;
+ FX_DOUBLE dMinValue = 0.0;
+ FXJSE_HVALUE argValue = 0;
+ for(FX_INT32 i = 0; i < argc; i++) {
+ argValue = args.GetValue(i);
+ if(FXJSE_Value_IsNull(argValue)) {
+ FXJSE_Value_Release(argValue);
+ continue;
+ } else if(FXJSE_Value_IsArray(argValue)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argValue, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if(iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+ GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+ if(!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ if(uCount == 1) {
+ dMinValue = HValueToDouble(hThis, newPropertyValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+ if(dMinValue > dValue) {
+ dMinValue = dValue;
+ }
+ }
+ }
+ }
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, i, jsObjectValue);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ if(!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ if(uCount == 1) {
+ dMinValue = HValueToDouble(hThis, newPropertyValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+ if(dMinValue > dValue) {
+ dMinValue = dValue;
+ }
+ }
+ }
+ }
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ FXJSE_Value_Release(newPropertyValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else if(FXJSE_Value_IsObject(argValue)) {
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(argValue, newPropertyValue);
+ if(!FXJSE_Value_IsNull(newPropertyValue)) {
+ uCount++;
+ if(uCount == 1) {
+ dMinValue = HValueToDouble(hThis, newPropertyValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, newPropertyValue);
+ if(dMinValue > dValue) {
+ dMinValue = dValue;
+ }
+ }
+ }
+ FXJSE_Value_Release(newPropertyValue);
+ } else {
+ uCount++;
+ if(uCount == 1) {
+ dMinValue = HValueToDouble(hThis, argValue);
+ } else {
+ FX_DOUBLE dValue = HValueToDouble(hThis, argValue);
+ if(dMinValue > dValue) {
+ dMinValue = dValue;
+ }
+ }
+ }
+ FXJSE_Value_Release(argValue);
+ }
+ argValue = 0;
+ if(uCount) {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dMinValue);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+}
+void CXFA_FM2JSContext::Mod(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if(args.GetLength() == 2) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ FXJSE_HVALUE argTwo = args.GetValue(1);
+ if(FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE dDividend = 0.0;
+ FX_DOUBLE dDividor = 0.0;
+ if(FXJSE_Value_IsArray(argOne)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argOne, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if(iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ dDividend = HValueToDouble(hThis, jsObjectValue);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ dDividend = HValueToDouble(hThis, newPropertyValue);
+ FXJSE_Value_Release(newPropertyValue);
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else {
+ dDividend = HValueToDouble(hThis, argOne);
+ }
+ if(FXJSE_Value_IsArray(argTwo)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argTwo, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if(iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argTwo, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argTwo, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ dDividor = HValueToDouble(hThis, jsObjectValue);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ dDividor = HValueToDouble(hThis, newPropertyValue);
+ FXJSE_Value_Release(newPropertyValue);
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else {
+ dDividor = HValueToDouble(hThis, argTwo);
+ }
+ if(dDividor) {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dDividend - dDividor * (FX_INT32)(dDividend / dDividor));
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_DIVIDE_ZERO);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Mod"));
+ }
+}
+void CXFA_FM2JSContext::Round(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ FX_UINT8 uPrecision = 0;
+ if(argc == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ if(FXJSE_Value_IsNull(argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE dValue = 0.0;
+ if(FXJSE_Value_IsArray(argOne)) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ dValue = HValueToDouble(hThis, jsObjectValue);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ dValue = HValueToDouble(hThis, newPropertyValue);
+ FXJSE_Value_Release(newPropertyValue);
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ } else {
+ dValue = HValueToDouble(hThis, argOne);
+ }
+ CFX_Decimal decimalValue((FX_FLOAT)dValue, uPrecision);
+ CFX_WideString wsValue = decimalValue;
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), wsValue.UTF8Encode());
+ }
+ FXJSE_Value_Release(argOne);
+ } else if(argc == 2) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ FXJSE_HVALUE argTwo = args.GetValue(1);
+ if(FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE dValue = 0.0;
+ if(FXJSE_Value_IsArray(argOne)) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ dValue = HValueToDouble(hThis, jsObjectValue);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ dValue = HValueToDouble(hThis, newPropertyValue);
+ FXJSE_Value_Release(newPropertyValue);
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ } else {
+ dValue = HValueToDouble(hThis, argOne);
+ }
+ FX_DOUBLE dPrecision = 0.0;
+ if(FXJSE_Value_IsArray(argTwo)) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argTwo, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argTwo, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ dPrecision = HValueToDouble(hThis, jsObjectValue);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ dPrecision = HValueToDouble(hThis, newPropertyValue);
+ FXJSE_Value_Release(newPropertyValue);
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ } else {
+ dPrecision = HValueToDouble(hThis, argTwo);
+ }
+ if(dPrecision < 0) {
+ uPrecision = 0;
+ } else if(dPrecision > 12.0) {
+ uPrecision = 12;
+ } else {
+ uPrecision = (FX_UINT8)dPrecision;
+ }
+ CFX_Decimal decimalValue((FX_FLOAT)dValue, uPrecision);
+ CFX_WideString wsValue = decimalValue;
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), wsValue.UTF8Encode());
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Round"));
+ }
+}
+void CXFA_FM2JSContext::Sum(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ FX_UINT32 uCount = 0;
+ FX_DOUBLE dSum = 0.0;
+ if(argc) {
+ FXJSE_HVALUE argValue = 0;
+ for(FX_INT32 i = 0; i < argc; i++) {
+ argValue = args.GetValue(i);
+ if(FXJSE_Value_IsNull(argValue)) {
+ FXJSE_Value_Release(argValue);
+ continue;
+ } else if(FXJSE_Value_IsArray(argValue)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argValue, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if(iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argValue, 1, propertyValue);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ for(FX_INT32 j = 2; j < iLength; j++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+ GetObjectDefaultValue(jsObjectValue, newPropertyValue);
+ if (!FXJSE_Value_IsNull(newPropertyValue)) {
+ dSum += HValueToDouble(hThis, jsObjectValue);
+ uCount++;
+ }
+ }
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ for(FX_INT32 j = 2; j < iLength; j++) {
+ FXJSE_Value_GetObjectPropByIdx(argValue, j, jsObjectValue);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ if (!FXJSE_Value_IsNull(newPropertyValue)) {
+ dSum += HValueToDouble(hThis, newPropertyValue);
+ uCount++;
+ }
+ }
+ }
+ FXJSE_Value_Release(newPropertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ FXJSE_Value_Release(propertyValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else if (FXJSE_Value_IsObject(argValue)) {
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(argValue, newPropertyValue);
+ if (!FXJSE_Value_IsNull(newPropertyValue)) {
+ dSum += HValueToDouble(hThis, argValue);
+ uCount++;
+ }
+ FXJSE_Value_Release(newPropertyValue);
+ } else {
+ dSum += HValueToDouble(hThis, argValue);
+ uCount++;
+ }
+ FXJSE_Value_Release(argValue);
+ }
+ argValue = 0;
+ }
+ if(uCount < 1) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dSum);
+ }
+}
+void CXFA_FM2JSContext::Date(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 0) {
+ struct tm *pTmStruct = 0;
+ time_t currentTime;
+ time(&currentTime);
+ pTmStruct = gmtime(&currentTime);
+ CFX_ByteString bufferYear;
+ CFX_ByteString bufferMon;
+ CFX_ByteString bufferDay;
+ bufferYear.Format("%d", pTmStruct->tm_year + 1900);
+ bufferMon.Format("%02d", pTmStruct->tm_mon + 1);
+ bufferDay.Format("%02d", pTmStruct->tm_mday);
+ CFX_ByteString bufferCurrent = bufferYear + bufferMon + bufferDay;
+ FX_INT32 dDays = DateString2Num(bufferCurrent);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), dDays);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Date"));
+ }
+}
+void CXFA_FM2JSContext::Date2Num(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ FX_BOOL bFlags = FALSE;
+ CFX_ByteString dateString;
+ CFX_ByteString formatString;
+ CFX_ByteString localString;
+ FXJSE_HVALUE dateValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE formatValue = 0;
+ FXJSE_HVALUE localValue = 0;
+ if(HValueIsNull(hThis, dateValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(dateValue, dateString);
+ }
+ if(argc > 1) {
+ formatValue = GetSimpleHValue(hThis, args, 1);
+ if (HValueIsNull(hThis, formatValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(formatValue, formatString);
+ }
+ }
+ if (argc == 3) {
+ localValue = GetSimpleHValue(hThis, args, 2);
+ if (HValueIsNull(hThis, localValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(localValue, localString);
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString szIsoDateString;
+ FX_BOOL bRet = Local2IsoDate(hThis, dateString, formatString, localString, szIsoDateString);
+ if (bRet) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), DateString2Num(szIsoDateString));
+ } else {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ }
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ FXJSE_Value_Release(dateValue);
+ if (argc > 1) {
+ FXJSE_Value_Release(formatValue);
+ if (argc == 3) {
+ FXJSE_Value_Release(localValue);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Date2Num"));
+ }
+}
+void CXFA_FM2JSContext::DateFmt(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if (argc < 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_INT32 iStyle = 0;
+ CFX_ByteString szLocal;
+ FXJSE_HVALUE argStyle = 0;
+ FXJSE_HVALUE argLocal = 0;
+ if (argc > 0) {
+ argStyle = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argStyle)) {
+ bFlags = TRUE;
+ }
+ iStyle = (FX_INT32)HValueToFloat(hThis, argStyle);
+ if (iStyle > 4 || iStyle < 0) {
+ iStyle = 0;
+ }
+ }
+ if (argc == 2) {
+ argLocal = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argLocal)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(argLocal, szLocal);
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString formatStr;
+ GetStandardDateFormat(hThis, iStyle, szLocal, formatStr);
+ if (formatStr.IsEmpty()) {
+ formatStr = FX_BSTRC("");
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ if (argc > 0) {
+ FXJSE_Value_Release(argStyle);
+ if (argc == 2) {
+ FXJSE_Value_Release(argLocal);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Date2Num"));
+ }
+}
+void CXFA_FM2JSContext::IsoDate2Num(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if(args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if(FXJSE_Value_IsNull(argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString szArgString;
+ HValueToUTF8String(argOne, szArgString);
+ FX_INT32 dDays = DateString2Num(szArgString);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (FX_INT32)dDays);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"IsoDate2Num"));
+ }
+}
+void CXFA_FM2JSContext::IsoTime2Num(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if(HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CXFA_Document *pDoc = pContext->GetDocument();
+ FXSYS_assert(pDoc);
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ CFX_ByteString szArgString;
+ HValueToUTF8String(argOne, szArgString);
+ szArgString = szArgString.Mid(szArgString.Find('T', 0) + 1);
+ if (szArgString.IsEmpty()) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ FXJSE_Value_Release(argOne);
+ return;
+ }
+ CXFA_LocaleValue timeValue(XFA_VT_TIME, CFX_WideString::FromUTF8(szArgString, szArgString.GetLength()), (CXFA_LocaleMgr*)pMgr);
+ if (timeValue.IsValid()) {
+ CFX_Unitime uniTime = timeValue.GetTime();
+ FX_INT32 hour = uniTime.GetHour();
+ FX_INT32 min = uniTime.GetMinute();
+ FX_INT32 second = uniTime.GetSecond();
+ FX_INT32 milSecond = uniTime.GetMillisecond();
+ IFX_Locale* pDefLocale = pMgr->GetDefLocale();
+ FXSYS_assert(pDefLocale);
+ FX_TIMEZONE tzLocale;
+ pDefLocale->GetTimeZone(tzLocale);
+ FX_INT32 mins = hour * 60 + min;
+ mins -= (tzLocale.tzHour * 60);
+ while (mins > 1440) {
+ mins -= 1440;
+ }
+ while (mins < 0) {
+ mins += 1440;
+ }
+ hour = mins / 60;
+ min = mins % 60;
+ FX_INT32 iResult = hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
+ FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
+ } else {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"IsoTime2Num"));
+ }
+}
+void CXFA_FM2JSContext::LocalDateFmt(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if (argc < 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_INT32 iStyle = 0;
+ CFX_ByteString szLocal;
+ FXJSE_HVALUE argStyle = 0;
+ FXJSE_HVALUE argLocal = 0;
+ if (argc > 0) {
+ argStyle = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argStyle)) {
+ bFlags = TRUE;
+ }
+ iStyle = (FX_INT32)HValueToFloat(hThis, argStyle);
+ if (iStyle > 4 || iStyle < 0) {
+ iStyle = 0;
+ }
+ }
+ if (argc == 2) {
+ argLocal = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argLocal)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(argLocal, szLocal);
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString formatStr;
+ GetLocalDateFormat(hThis, iStyle, szLocal, formatStr, FALSE);
+ if (formatStr.IsEmpty()) {
+ formatStr = FX_BSTRC("");
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ if (argc > 0) {
+ FXJSE_Value_Release(argStyle);
+ if (argc == 2) {
+ FXJSE_Value_Release(argLocal);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"LocalDateFmt"));
+ }
+}
+void CXFA_FM2JSContext::LocalTimeFmt(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if (argc < 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_INT32 iStyle = 0;
+ CFX_ByteString szLocal;
+ FXJSE_HVALUE argStyle = 0;
+ FXJSE_HVALUE argLocal = 0;
+ if (argc > 0) {
+ argStyle = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argStyle)) {
+ bFlags = TRUE;
+ }
+ iStyle = (FX_INT32)HValueToFloat(hThis, argStyle);
+ if (iStyle > 4 || iStyle < 0) {
+ iStyle = 0;
+ }
+ }
+ if (argc == 2) {
+ argLocal = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argLocal)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(argLocal, szLocal);
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString formatStr;
+ GetLocalTimeFormat(hThis, iStyle, szLocal, formatStr, FALSE);
+ if (formatStr.IsEmpty()) {
+ formatStr = FX_BSTRC("");
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ if (argc > 0) {
+ FXJSE_Value_Release(argStyle);
+ if (argc == 2) {
+ FXJSE_Value_Release(argLocal);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"LocalTimeFmt"));
+ }
+}
+void CXFA_FM2JSContext::Num2Date(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ FX_BOOL bFlags = FALSE;
+ FX_INT32 dDate;
+ CFX_ByteString formatString;
+ CFX_ByteString localString;
+ FXJSE_HVALUE dateValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE formatValue = 0;
+ FXJSE_HVALUE localValue = 0;
+ if(HValueIsNull(hThis, dateValue)) {
+ bFlags = TRUE;
+ } else {
+ dDate = (FX_INT32)HValueToFloat(hThis, dateValue);
+ bFlags = dDate < 1;
+ }
+ if(argc > 1) {
+ formatValue = GetSimpleHValue(hThis, args, 1);
+ if (HValueIsNull(hThis, formatValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(formatValue, formatString);
+ }
+ }
+ if (argc == 3) {
+ localValue = GetSimpleHValue(hThis, args, 2);
+ if (HValueIsNull(hThis, localValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(localValue, localString);
+ }
+ }
+ if (!bFlags) {
+ FX_INT32 iYear = 1900;
+ FX_INT32 iMonth = 1;
+ FX_INT32 iDay = 1;
+ FX_INT32 i = 0;
+ while (dDate > 0) {
+ if (iMonth == 2) {
+ if ((!((iYear + i) % 4) && ((iYear + i) % 100)) || !((iYear + i) % 400)) {
+ if (dDate > 29) {
+ ++iMonth;
+ if (iMonth > 12) {
+ iMonth = 1;
+ ++i;
+ }
+ iDay = 1;
+ dDate -= 29;
+ } else {
+ iDay += static_cast<FX_INT32>(dDate) - 1;
+ dDate = 0;
+ }
+ } else {
+ if (dDate > 28) {
+ ++iMonth;
+ if (iMonth > 12) {
+ iMonth = 1;
+ ++i;
+ }
+ iDay = 1;
+ dDate -= 28;
+ } else {
+ iDay += static_cast<FX_INT32>(dDate) - 1;
+ dDate = 0;
+ }
+ }
+ } else if (iMonth < 8) {
+ if ((iMonth % 2 == 0)) {
+ if (dDate > 30) {
+ ++iMonth;
+ if (iMonth > 12) {
+ iMonth = 1;
+ ++i;
+ }
+ iDay = 1;
+ dDate -= 30;
+ } else {
+ iDay += static_cast<FX_INT32>(dDate) - 1;
+ dDate = 0;
+ }
+ } else {
+ if (dDate > 31) {
+ ++iMonth;
+ if (iMonth > 12) {
+ iMonth = 1;
+ ++i;
+ }
+ iDay = 1;
+ dDate -= 31;
+ } else {
+ iDay += static_cast<FX_INT32>(dDate) - 1;
+ dDate = 0;
+ }
+ }
+ } else {
+ if (iMonth % 2 != 0) {
+ if (dDate > 30) {
+ ++iMonth;
+ if (iMonth > 12) {
+ iMonth = 1;
+ ++i;
+ }
+ iDay = 1;
+ dDate -= 30;
+ } else {
+ iDay += static_cast<FX_INT32>(dDate) - 1;
+ dDate = 0;
+ }
+ } else {
+ if (dDate > 31) {
+ ++iMonth;
+ if (iMonth > 12) {
+ iMonth = 1;
+ ++i;
+ }
+ iDay = 1;
+ dDate -= 31;
+ } else {
+ iDay += static_cast<FX_INT32>(dDate) - 1;
+ dDate = 0;
+ }
+ }
+ }
+ }
+ CFX_ByteString szIsoDateString;
+ szIsoDateString.Format("%d%02d%02d", iYear + i, iMonth, iDay);
+ CFX_ByteString szLocalDateString;
+ FX_BOOL bRet = IsoDate2Local(hThis, szIsoDateString, formatString, localString, szLocalDateString);
+ if (szLocalDateString.IsEmpty()) {
+ szLocalDateString = FX_BSTRC("");
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szLocalDateString);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ FXJSE_Value_Release(dateValue);
+ if (argc > 1) {
+ FXJSE_Value_Release(formatValue);
+ if (argc == 3) {
+ FXJSE_Value_Release(localValue);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Num2Date"));
+ }
+}
+void CXFA_FM2JSContext::Num2GMTime(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ FX_BOOL bFlags = FALSE;
+ FX_INT32 iTime;
+ CFX_ByteString formatString;
+ CFX_ByteString localString;
+ FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE formatValue = 0;
+ FXJSE_HVALUE localValue = 0;
+ if(FXJSE_Value_IsNull(timeValue)) {
+ bFlags = TRUE;
+ } else {
+ iTime = (FX_INT32)HValueToFloat(hThis, timeValue);
+ if (FXSYS_abs(iTime) < 1.0) {
+ bFlags = TRUE;
+ }
+ }
+ if(argc > 1) {
+ formatValue = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(formatValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(formatValue, formatString);
+ }
+ }
+ if (argc == 3) {
+ localValue = GetSimpleHValue(hThis, args, 2);
+ if (FXJSE_Value_IsNull(localValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(localValue, localString);
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString szGMTTimeString;
+ Num2AllTime(hThis, iTime, formatString, localString, TRUE, szGMTTimeString);
+ if (szGMTTimeString.IsEmpty()) {
+ szGMTTimeString = FX_BSTRC("");
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szGMTTimeString);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ FXJSE_Value_Release(timeValue);
+ if (argc > 1) {
+ FXJSE_Value_Release(formatValue);
+ if (argc == 3) {
+ FXJSE_Value_Release(localValue);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Num2GMTime"));
+ }
+}
+void CXFA_FM2JSContext::Num2Time(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT fTime;
+ CFX_ByteString formatString;
+ CFX_ByteString localString;
+ FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE formatValue = 0;
+ FXJSE_HVALUE localValue = 0;
+ if(FXJSE_Value_IsNull(timeValue)) {
+ bFlags = TRUE;
+ } else {
+ fTime = HValueToFloat(hThis, timeValue);
+ if (FXSYS_fabs(fTime) < 1.0) {
+ bFlags = TRUE;
+ }
+ }
+ if(argc > 1) {
+ formatValue = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(formatValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(formatValue, formatString);
+ }
+ }
+ if (argc == 3) {
+ localValue = GetSimpleHValue(hThis, args, 2);
+ if (FXJSE_Value_IsNull(localValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(localValue, localString);
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString szLocalTimeString;
+ Num2AllTime(hThis, (FX_INT32)fTime, formatString, localString, FALSE, szLocalTimeString);
+ if (szLocalTimeString.IsEmpty()) {
+ szLocalTimeString = FX_BSTRC("");
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szLocalTimeString);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ FXJSE_Value_Release(timeValue);
+ if (argc > 1) {
+ FXJSE_Value_Release(formatValue);
+ if (argc == 3) {
+ FXJSE_Value_Release(localValue);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Num2Time"));
+ }
+}
+void CXFA_FM2JSContext::Time(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 0) {
+ time_t now;
+ time(&now);
+ struct tm *pGmt = gmtime(&now);
+ FX_INT32 iGMHour = pGmt->tm_hour;
+ FX_INT32 iGMMin = pGmt->tm_min;
+ FX_INT32 iGMSec = pGmt->tm_sec;
+ FXJSE_Value_SetInteger(args.GetReturnValue(), ((iGMHour * 3600 + iGMMin * 60 + iGMSec) * 1000));
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Time"));
+ }
+}
+void CXFA_FM2JSContext::Time2Num(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ FX_BOOL bFlags = FALSE;
+ CFX_ByteString timeString;
+ CFX_ByteString formatString;
+ CFX_ByteString localString;
+ FXJSE_HVALUE timeValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE formatValue = 0;
+ FXJSE_HVALUE localValue = 0;
+ if(HValueIsNull(hThis, timeValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(timeValue, timeString);
+ }
+ if(argc > 1) {
+ formatValue = GetSimpleHValue(hThis, args, 1);
+ if (HValueIsNull(hThis, formatValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(formatValue, formatString);
+ }
+ }
+ if (argc == 3) {
+ localValue = GetSimpleHValue(hThis, args, 2);
+ if (HValueIsNull(hThis, localValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(localValue, localString);
+ }
+ }
+ if (!bFlags) {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (localString.IsEmpty()) {
+ CXFA_Object * pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node *)pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(localString, localString.GetLength()));
+ }
+ CFX_WideString wsFormat;
+ if (formatString.IsEmpty()) {
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+ } else {
+ wsFormat = CFX_WideString::FromUTF8(formatString, formatString.GetLength());
+ }
+ wsFormat = FX_WSTRC(L"time{") + wsFormat;
+ wsFormat += FX_WSTRC(L"}");
+ CXFA_LocaleValue timeValue(XFA_VT_TIME, CFX_WideString::FromUTF8(timeString, timeString.GetLength()),
+ wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
+ if (timeValue.IsValid()) {
+ CFX_Unitime uniTime = timeValue.GetTime();
+ FX_INT32 hour = uniTime.GetHour();
+ FX_INT32 min = uniTime.GetMinute();
+ FX_INT32 second = uniTime.GetSecond();
+ FX_INT32 milSecond = uniTime.GetMillisecond();
+ FX_INT32 mins = hour * 60 + min;
+ IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get();
+ if (pProvider != NULL) {
+ FX_TIMEZONE tz;
+ pProvider->GetTimeZone(tz);
+ mins -= (tz.tzHour * 60);
+ while (mins > 1440) {
+ mins -= 1440;
+ }
+ while (mins < 0) {
+ mins += 1440;
+ }
+ hour = mins / 60;
+ min = mins % 60;
+ }
+ FX_INT32 iResult = hour * 3600000 + min * 60000 + second * 1000 + milSecond + 1;
+ FXJSE_Value_SetInteger(args.GetReturnValue(), iResult);
+ } else {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ }
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ FXJSE_Value_Release(timeValue);
+ if (argc > 1) {
+ FXJSE_Value_Release(formatValue);
+ if (argc == 3) {
+ FXJSE_Value_Release(localValue);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Time2Num"));
+ }
+}
+void CXFA_FM2JSContext::TimeFmt(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if (argc < 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_INT32 iStyle = 0;
+ CFX_ByteString szLocal;
+ FXJSE_HVALUE argStyle = 0;
+ FXJSE_HVALUE argLocal = 0;
+ if (argc > 0) {
+ argStyle = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argStyle)) {
+ bFlags = TRUE;
+ }
+ iStyle = (FX_INT32)HValueToFloat(hThis, argStyle);
+ if (iStyle > 4 || iStyle < 0) {
+ iStyle = 0;
+ }
+ }
+ if (argc == 2) {
+ argLocal = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argLocal)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(argLocal, szLocal);
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString formatStr;
+ GetStandardTimeFormat(hThis, iStyle, szLocal, formatStr);
+ if (formatStr.IsEmpty()) {
+ formatStr = FX_BSTRC("");
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), formatStr);
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ if (argc > 0) {
+ FXJSE_Value_Release(argStyle);
+ if (argc == 2) {
+ FXJSE_Value_Release(argLocal);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"TimeFmt"));
+ }
+}
+FX_BOOL CXFA_FM2JSContext::IsIsoDateFormat(FX_LPCSTR pData, FX_INT32 iLength, FX_INT32 &iStyle, FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay)
+{
+ iYear = 0;
+ iMonth = 1;
+ iDay = 1;
+ FX_BOOL iRet = FALSE;
+ if (iLength < 4) {
+ return iRet;
+ }
+ FX_CHAR strYear[5];
+ strYear[4] = '\0';
+ for (FX_INT32 i = 0; i < 4; ++i) {
+ if (*(pData + i) <= '9' && *(pData + i) >= '0') {
+ strYear[i] = *(pData + i);
+ } else {
+ return iRet;
+ }
+ }
+ iYear = FXSYS_atoi(strYear);
+ iStyle = 0;
+ if (iLength > 4) {
+ if (*(pData + 4) == '-') {
+ iStyle = 1;
+ } else {
+ iStyle = 0;
+ }
+ } else {
+ iRet = TRUE;
+ return iRet;
+ }
+ FX_CHAR strTemp[3];
+ strTemp[2] = '\0';
+ FX_INT32 iPosOff = 0;
+ if (iStyle == 0) {
+ iPosOff = 4;
+ if (iLength == 4) {
+ iRet = TRUE;
+ return iRet;
+ }
+ } else {
+ iPosOff = 5;
+ if (iLength == 4) {
+ iRet = TRUE;
+ return iRet;
+ }
+ }
+ if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') || (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
+ return iRet;
+ }
+ strTemp[0] = *(pData + iPosOff);
+ strTemp[1] = *(pData + iPosOff + 1);
+ iMonth = FXSYS_atoi(strTemp);
+ if (iMonth > 12 || iMonth < 1) {
+ return iRet;
+ }
+ if (iStyle == 0) {
+ iPosOff += 2;
+ if (iLength == 6) {
+ iRet = 1;
+ return iRet;
+ }
+ } else {
+ iPosOff += 3;
+ if (iLength == 7) {
+ iRet = 1;
+ return iRet;
+ }
+ }
+ if ((*(pData + iPosOff) > '9' || *(pData + iPosOff) < '0') || (*(pData + iPosOff + 1) > '9' || *(pData + iPosOff + 1) < '0')) {
+ return iRet;
+ }
+ strTemp[0] = *(pData + iPosOff);
+ strTemp[1] = *(pData + iPosOff + 1);
+ iDay = FXSYS_atoi(strTemp);
+ if (iPosOff + 2 < iLength) {
+ return iRet;
+ }
+ if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
+ if (iMonth == 2) {
+ if (iDay > 29) {
+ return iRet;
+ }
+ } else {
+ if (iMonth < 8) {
+ if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
+ return iRet;
+ }
+ } else {
+ if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
+ return iRet;
+ }
+ }
+ }
+ } else {
+ if (iMonth == 2) {
+ if (iDay > 28) {
+ return iRet;
+ }
+ } else {
+ if (iMonth < 8) {
+ if (iDay > (iMonth % 2 == 0 ? 30 : 31)) {
+ return iRet;
+ }
+ } else {
+ if (iDay > (iMonth % 2 == 0 ? 31 : 30)) {
+ return iRet;
+ }
+ }
+ }
+ }
+ iRet = TRUE;
+ return iRet;
+}
+FX_BOOL CXFA_FM2JSContext::IsIsoTimeFormat(FX_LPCSTR pData, FX_INT32 iLength, FX_INT32 &iHour, FX_INT32 &iMinute, FX_INT32 &iSecond, FX_INT32 &iMilliSecond, FX_INT32 &iZoneHour, FX_INT32 &iZoneMinute)
+{
+ iHour = 0;
+ iMinute = 0;
+ iSecond = 0;
+ iMilliSecond = 0;
+ iZoneHour = 0;
+ iZoneMinute = 0;
+ if (!pData) {
+ return FALSE;
+ }
+ FX_INT32 iRet = FALSE;
+ FX_CHAR strTemp[3];
+ strTemp[2] = '\0';
+ FX_INT32 iIndex = 0;
+ FX_INT32 iZone = 0;
+ FX_INT32 i = iIndex;
+ while (i < iLength) {
+ if ((*(pData + i) > '9' || *(pData + i) < '0') && *(pData + i) != ':' ) {
+ iZone = i;
+ break;
+ }
+ ++i;
+ }
+ if (i == iLength) {
+ iZone = iLength;
+ }
+ FX_INT32 iPos = 0;
+ while (iIndex < iZone) {
+ if (iIndex >= iZone) {
+ break;
+ }
+ if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
+ return iRet;
+ }
+ strTemp[0] = *(pData + iIndex);
+ if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
+ return iRet;
+ }
+ strTemp[1] = *(pData + iIndex + 1);
+ if (FXSYS_atoi(strTemp) > 60) {
+ return iRet;
+ }
+ if (*(pData + 2) == ':') {
+ if (iPos == 0) {
+ iHour = FXSYS_atoi(strTemp);
+ ++iPos;
+ } else if (iPos == 1) {
+ iMinute = FXSYS_atoi(strTemp);
+ ++iPos;
+ } else {
+ iSecond = FXSYS_atoi(strTemp);
+ }
+ iIndex += 3;
+ } else {
+ if (iPos == 0) {
+ iHour = FXSYS_atoi(strTemp);
+ ++iPos;
+ } else if (iPos == 1) {
+ iMinute = FXSYS_atoi(strTemp);
+ ++iPos;
+ } else if (iPos == 2) {
+ iSecond = FXSYS_atoi(strTemp);
+ ++iPos;
+ }
+ iIndex += 2;
+ }
+ }
+ if (*(pData + iIndex) == '.') {
+ ++iIndex;
+ FX_CHAR strTemp[4];
+ strTemp[3] = '\0';
+ if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
+ return iRet;
+ }
+ strTemp[0] = *(pData + iIndex);
+ if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
+ return iRet;
+ }
+ strTemp[1] = *(pData + iIndex + 1);
+ if (*(pData + iIndex + 2) > '9' || *(pData + iIndex + 2) < '0') {
+ return iRet;
+ }
+ strTemp[2] = *(pData + iIndex + 2);
+ iMilliSecond = FXSYS_atoi(strTemp);
+ if (iMilliSecond > 100) {
+ iMilliSecond = 0;
+ return iRet;
+ }
+ iIndex += 3;
+ }
+ FX_INT32 iSign = 1;
+ if (*(pData + iIndex) == 'z' || *(pData + iIndex) == 'Z') {
+ iRet = 1;
+ return iRet;
+ } else if (*(pData + iIndex) == '+') {
+ ++iIndex;
+ } else if (*(pData + iIndex) == '-') {
+ iSign = -1;
+ ++iIndex;
+ }
+ iPos = 0;
+ while (iIndex < iLength) {
+ if (iIndex >= iLength) {
+ return iRet;
+ }
+ if (*(pData + iIndex) > '9' || *(pData + iIndex) < '0') {
+ return iRet;
+ }
+ strTemp[0] = *(pData + iIndex);
+ if (*(pData + iIndex + 1) > '9' || *(pData + iIndex + 1) < '0') {
+ return iRet;
+ }
+ strTemp[1] = *(pData + iIndex + 1);
+ if (FXSYS_atoi(strTemp) > 60) {
+ return iRet;
+ }
+ if (*(pData + 2) == ':') {
+ if (iPos == 0) {
+ iZoneHour = FXSYS_atoi(strTemp);
+ } else if (iPos == 1) {
+ iZoneMinute = FXSYS_atoi(strTemp);
+ }
+ iIndex += 3;
+ } else {
+ if (!iPos) {
+ iZoneHour = FXSYS_atoi(strTemp);
+ ++iPos;
+ } else if (iPos == 1) {
+ iZoneMinute = FXSYS_atoi(strTemp);
+ ++iPos;
+ }
+ iIndex += 2;
+ }
+ }
+ if (iIndex < iLength) {
+ return iRet;
+ }
+ iZoneHour *= iSign;
+ iRet = TRUE;
+ return iRet;
+}
+FX_BOOL CXFA_FM2JSContext::IsIsoDateTimeFormat(FX_LPCSTR pData, FX_INT32 iLength, FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay, FX_INT32 &iHour, FX_INT32 &iMinute, FX_INT32 &iSecond, FX_INT32 &iMillionSecond, FX_INT32 &iZoneHour, FX_INT32 &iZoneMinute)
+{
+ iYear = 0;
+ iMonth = 0;
+ iDay = 0;
+ iHour = 0;
+ iMinute = 0;
+ iSecond = 0;
+ if (!pData) {
+ return FALSE;
+ }
+ FX_INT32 iRet = FALSE;
+ FX_INT32 iIndex = 0;
+ while (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
+ if (iIndex >= iLength) {
+ return iRet;
+ }
+ ++iIndex;
+ }
+ if (iIndex != 8 && iIndex != 10) {
+ return iRet;
+ }
+ FX_INT32 iStyle = -1;
+ iRet = IsIsoDateFormat(pData, iIndex , iStyle, iYear, iMonth, iDay);
+ if (!iRet) {
+ return iRet;
+ }
+ if (*(pData + iIndex) != 'T' && *(pData + iIndex) != 't') {
+ return iRet;
+ }
+ ++iIndex;
+ if (((iLength - iIndex > 13) && (iLength - iIndex < 6)) && (iLength - iIndex != 15)) {
+ return iRet;
+ }
+ iRet = IsIsoTimeFormat(pData + iIndex, iLength - iIndex, iHour, iMinute, iSecond, iMillionSecond, iZoneHour, iZoneMinute);
+ if (!iRet) {
+ return iRet;
+ }
+ iRet = TRUE;
+ return iRet;
+}
+FX_BOOL CXFA_FM2JSContext::Local2IsoDate(FXJSE_HOBJECT hThis, FX_BSTR szDate, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strIsoDate)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return FALSE;
+ }
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (szLocale.IsEmpty()) {
+ CXFA_Object * pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node *)pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+ }
+ if (!pLocale) {
+ return FALSE;
+ }
+ CFX_WideString wsFormat;
+ if (szFormat.IsEmpty()) {
+ pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+ } else {
+ wsFormat = CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+ }
+ CXFA_LocaleValue widgetValue(XFA_VT_DATE, CFX_WideString::FromUTF8(szDate.GetCStr(), szDate.GetLength()),
+ wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
+ CFX_Unitime dt = widgetValue.GetDate();
+ strIsoDate.Format("%4d-%02d-%02d", dt.GetYear(), dt.GetMonth(), dt.GetDay());
+ return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::Local2IsoTime(FXJSE_HOBJECT hThis, FX_BSTR szTime, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strIsoTime)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return FALSE;
+ }
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (szLocale.IsEmpty()) {
+ CXFA_Object * pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node *)pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+ }
+ if (!pLocale) {
+ return FALSE;
+ }
+ CFX_WideString wsFormat;
+ if (szFormat.IsEmpty()) {
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+ } else {
+ wsFormat = CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+ }
+ wsFormat = FX_WSTRC(L"time{") + wsFormat;
+ wsFormat += FX_WSTRC(L"}");
+ CXFA_LocaleValue widgetValue(XFA_VT_TIME, CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()),
+ wsFormat, pLocale, (CXFA_LocaleMgr*)pMgr);
+ CFX_Unitime utime = widgetValue.GetTime();
+ strIsoTime.Format("%02d:%02d:%02d.%03d", utime.GetHour(), utime.GetMinute(), utime.GetSecond(), utime.GetMillisecond());
+ return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::IsoDate2Local(FXJSE_HOBJECT hThis, FX_BSTR szDate, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strLocalDate)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return FALSE;
+ }
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (szLocale.IsEmpty()) {
+ CXFA_Object * pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node *)pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+ }
+ if (!pLocale) {
+ return FALSE;
+ }
+ CFX_WideString wsFormat;
+ if (szFormat.IsEmpty()) {
+ pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+ } else {
+ wsFormat = CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+ }
+ CXFA_LocaleValue widgetValue(XFA_VT_DATE, CFX_WideString::FromUTF8(szDate.GetCStr(), szDate.GetLength()), (CXFA_LocaleMgr*)pMgr);
+ CFX_WideString wsRet;
+ widgetValue.FormatPatterns(wsRet, wsFormat, pLocale, XFA_VALUEPICTURE_Display);
+ strLocalDate = FX_UTF8Encode(wsRet, wsRet.GetLength());
+ return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::IsoTime2Local(FXJSE_HOBJECT hThis, FX_BSTR szTime, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strLocalTime)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return FALSE;
+ }
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (szLocale.IsEmpty()) {
+ CXFA_Object * pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node *)pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+ }
+ if (!pLocale) {
+ return FALSE;
+ }
+ CFX_WideString wsFormat;
+ if (szFormat.IsEmpty()) {
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+ } else {
+ wsFormat = CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+ }
+ wsFormat = FX_WSTRC(L"time{") + wsFormat;
+ wsFormat += FX_WSTRC(L"}");
+ CXFA_LocaleValue widgetValue(XFA_VT_TIME, CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()), (CXFA_LocaleMgr*)pMgr);
+ CFX_WideString wsRet;
+ widgetValue.FormatPatterns(wsRet, wsFormat, pLocale, XFA_VALUEPICTURE_Display);
+ strLocalTime = FX_UTF8Encode(wsRet, wsRet.GetLength());
+ return TRUE;
+}
+FX_BOOL CXFA_FM2JSContext::GetGMTTime(FXJSE_HOBJECT hThis, FX_BSTR szTime, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strGMTTime)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return FALSE;
+ }
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (szLocale.IsEmpty()) {
+ CXFA_Object * pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node *)pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocale.GetCStr(), szLocale.GetLength()));
+ }
+ if (!pLocale) {
+ return FALSE;
+ }
+ CFX_WideString wsFormat;
+ if (szFormat.IsEmpty()) {
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Default, wsFormat);
+ } else {
+ wsFormat = CFX_WideString::FromUTF8(szFormat.GetCStr(), szFormat.GetLength());
+ }
+ wsFormat = FX_WSTRC(L"time{") + wsFormat;
+ wsFormat += FX_WSTRC(L"}");
+ CXFA_LocaleValue widgetValue(XFA_VT_TIME, CFX_WideString::FromUTF8(szTime.GetCStr(), szTime.GetLength()), (CXFA_LocaleMgr*)pMgr);
+ CFX_WideString wsRet;
+ widgetValue.FormatPatterns(wsRet, wsFormat, pLocale, XFA_VALUEPICTURE_Display);
+ strGMTTime = FX_UTF8Encode(wsRet, wsRet.GetLength());
+ return TRUE;
+}
+FX_INT32 CXFA_FM2JSContext::DateString2Num(FX_BSTR szDateString)
+{
+ FX_BOOL bFlags = FALSE;
+ FX_INT32 iLength = szDateString.GetLength();
+ FX_BOOL iRet = FALSE;
+ FX_INT32 iStyle = -1;
+ FX_INT32 iYear = 0;
+ FX_INT32 iMonth = 0;
+ FX_INT32 iDay = 0;
+ FX_INT32 iHour = 0;
+ FX_INT32 iMinute = 0;
+ FX_INT32 iSecond = 0;
+ FX_INT32 iMillionSecond = 0;
+ FX_INT32 iZoneHour = 0;
+ FX_INT32 iZoneMinute = 0;
+ if (iLength <= 10) {
+ iRet = IsIsoDateFormat(szDateString.GetCStr(), iLength, iStyle, iYear, iMonth, iDay);
+ } else {
+ iRet = IsIsoDateTimeFormat(szDateString.GetCStr(), iLength, iYear, iMonth, iDay, iHour, iMinute, iSecond, iMillionSecond, iZoneHour, iZoneMinute);
+ }
+ if (!iRet) {
+ bFlags = TRUE;
+ }
+ FX_FLOAT dDays = 0;
+ FX_INT32 i = 1;
+ if (iYear < 1900) {
+ bFlags = TRUE;
+ }
+ if(!bFlags) {
+ while (iYear - i >= 1900) {
+ if ((!((iYear - i) % 4) && ((iYear - i) % 100)) || !((iYear - i) % 400)) {
+ dDays += 366;
+ } else {
+ dDays += 365;
+ }
+ ++i;
+ }
+ i = 1;
+ while (i < iMonth) {
+ if (i == 2) {
+ if ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) {
+ dDays += 29;
+ } else {
+ dDays += 28;
+ }
+ } else if (i <= 7) {
+ if (i % 2 == 0) {
+ dDays += 30;
+ } else {
+ dDays += 31;
+ }
+ } else {
+ if (i % 2 == 0) {
+ dDays += 31;
+ } else {
+ dDays += 30;
+ }
+ }
+ ++i;
+ }
+ i = 0;
+ while (iDay - i > 0) {
+ dDays += 1;
+ ++i;
+ }
+ } else {
+ dDays = 0;
+ }
+ return (FX_INT32)dDays;
+}
+#define XFA_N 19
+static FX_BYTE g_sAltTable_Date[] = {
+ XFA_N, XFA_N, XFA_N, 3, 9, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, 2, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ 1, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+};
+static FX_BYTE g_sAltTable_Time[] = {
+ 14, XFA_N, XFA_N, 3, 9, XFA_N, XFA_N, 15,
+ XFA_N, XFA_N, XFA_N, XFA_N, 6, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, 7, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ 1, 17, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, 15,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+ XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N, XFA_N,
+};
+static void XFA_FM_AlternateDateTimeSymbols(CFX_WideString &wsPattern, const CFX_WideString &wsAltSymbols, FX_BYTE *pAltTable)
+{
+ FX_INT32 nLength = wsPattern.GetLength();
+ FX_BOOL bInConstRange = FALSE;
+ FX_BOOL bEscape = FALSE;
+ FX_INT32 i = 0, n = 0;
+ while (i < nLength) {
+ FX_WCHAR wc = wsPattern[i];
+ if (wc == L'\'') {
+ bInConstRange = !bInConstRange;
+ if (bEscape) {
+ i ++;
+ } else {
+ wsPattern.Delete(i);
+ nLength --;
+ }
+ bEscape = !bEscape;
+ continue;
+ }
+ if (!bInConstRange && (n = wc - L'A') >= 0 && n <= (L'a' - L'A')) {
+ FX_INT32 nAlt = (FX_INT32)pAltTable[n];
+ if (nAlt != XFA_N) {
+ wsPattern.SetAt(i, wsAltSymbols[nAlt]);
+ }
+ }
+ i ++;
+ bEscape = FALSE;
+ }
+}
+#undef XFA_N
+void CXFA_FM2JSContext::GetLocalDateFormat(FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat, FX_BOOL bStandard)
+{
+ FX_LOCALEDATETIMESUBCATEGORY strStyle;
+ switch (iStyle) {
+ case 0:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ break;
+ case 1:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
+ break;
+ case 2:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ break;
+ case 3:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
+ break;
+ case 4:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
+ break;
+ default:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ break;
+ }
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return;
+ }
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (szLocalStr.IsEmpty()) {
+ CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocalStr.GetCStr(), szLocalStr.GetLength()));
+ }
+ if (!pLocale) {
+ return;
+ }
+ CFX_WideString strRet;
+ pLocale->GetDatePattern(strStyle, strRet);
+ if (!bStandard) {
+ CFX_WideString wsSymbols;
+ pLocale->GetDateTimeSymbols(wsSymbols);
+ XFA_FM_AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Date);
+ }
+ strFormat = FX_UTF8Encode(strRet, strRet.GetLength());
+}
+void CXFA_FM2JSContext::GetLocalTimeFormat(FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat, FX_BOOL bStandard)
+{
+ FX_LOCALEDATETIMESUBCATEGORY strStyle;
+ switch (iStyle) {
+ case 0:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ break;
+ case 1:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Short;
+ break;
+ case 2:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ break;
+ case 3:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Long;
+ break;
+ case 4:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Full;
+ break;
+ default:
+ strStyle = FX_LOCALEDATETIMESUBCATEGORY_Medium;
+ break;
+ }
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return;
+ }
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ IFX_Locale *pLocale = NULL;
+ if (szLocalStr.IsEmpty()) {
+ CXFA_Object *pThisObject = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisObject->IsNode());
+ CXFA_Node* pThisNode = (CXFA_Node *)pThisObject;
+ CXFA_WidgetData widgetData(pThisNode);
+ pLocale = widgetData.GetLocal();
+ } else {
+ pLocale = pMgr->GetLocaleByName(CFX_WideString::FromUTF8(szLocalStr.GetCStr(), szLocalStr.GetLength()));
+ }
+ if (!pLocale) {
+ return;
+ }
+ CFX_WideString strRet;
+ pLocale->GetTimePattern(strStyle, strRet);
+ if (!bStandard) {
+ CFX_WideString wsSymbols;
+ pLocale->GetDateTimeSymbols(wsSymbols);
+ XFA_FM_AlternateDateTimeSymbols(strRet, wsSymbols, g_sAltTable_Time);
+ }
+ strFormat = FX_UTF8Encode(strRet, strRet.GetLength());
+}
+void CXFA_FM2JSContext::GetStandardDateFormat(FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat)
+{
+ GetLocalDateFormat(hThis, iStyle, szLocalStr, strFormat, TRUE);
+}
+void CXFA_FM2JSContext::GetStandardTimeFormat(FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat)
+{
+ GetLocalTimeFormat(hThis, iStyle, szLocalStr, strFormat, TRUE);
+}
+void CXFA_FM2JSContext::Num2AllTime(FXJSE_HOBJECT hThis, FX_INT32 iTime, FX_BSTR szFormat, FX_BSTR szLocale, FX_BOOL bGM, CFX_ByteString &strTime)
+{
+ FX_INT32 iHour = 0;
+ FX_INT32 iMin = 0;
+ FX_INT32 iSec = 0;
+ FX_INT32 iZoneHour = 0;
+ FX_INT32 iZoneMin = 0;
+ FX_INT32 iZoneSec = 0;
+ iHour = static_cast<int>(iTime) / 3600000;
+ iMin = (static_cast<int>(iTime) - iHour * 3600000) / 60000;
+ iSec = (static_cast<int>(iTime) - iHour * 3600000 - iMin * 60000) / 1000;
+ if (!bGM) {
+ GetLocalTimeZone(iZoneHour, iZoneMin, iZoneSec);
+ iHour += iZoneHour;
+ iMin += iZoneMin;
+ iSec += iZoneSec;
+ }
+ FX_INT32 iRet = 0;
+ CFX_ByteString strIsoTime;
+ strIsoTime.Format("%02d:%02d:%02d", iHour, iMin, iSec);
+ if (bGM) {
+ iRet = GetGMTTime(hThis, strIsoTime, szFormat, szLocale, strTime);
+ } else {
+ iRet = IsoTime2Local(hThis, strIsoTime, szFormat, szLocale, strTime);
+ }
+ if (!iRet) {
+ strTime = FX_BSTRC("");
+ }
+ return;
+}
+void CXFA_FM2JSContext::GetLocalTimeZone(FX_INT32 &iHour, FX_INT32 &iMin, FX_INT32 &iSec)
+{
+ time_t now;
+ time(&now);
+ struct tm *pGmt = gmtime(&now);
+ FX_INT32 iGMHour = pGmt->tm_hour;
+ FX_INT32 iGMMin = pGmt->tm_min;
+ FX_INT32 iGMSec = pGmt->tm_sec;
+ struct tm *pLocal = localtime(&now);
+ FX_INT32 iLocalHour = pLocal->tm_hour;
+ FX_INT32 iLocalMin = pLocal->tm_min;
+ FX_INT32 iLocalSec = pLocal->tm_sec;
+ iHour = iLocalHour - iGMHour;
+ iMin = iLocalMin - iGMMin;
+ iSec = iLocalSec - iGMSec;
+}
+void CXFA_FM2JSContext::Apr(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_DOUBLE nPrincipal = 0;
+ FX_DOUBLE nPayment = 0;
+ FX_DOUBLE nPeriods = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nPrincipal = HValueToDouble(hThis, argOne);
+ nPayment = HValueToDouble(hThis, argTwo);
+ nPeriods = HValueToDouble(hThis, argThree);
+ bFlags = ((nPrincipal <= 0) || (nPayment <= 0) || (nPeriods <= 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FX_DOUBLE r = 2 * (nPeriods * nPayment - nPrincipal) / (nPeriods * nPrincipal);
+ FX_DOUBLE nTemp = 1;
+ for (FX_INT32 i = 0; i < nPeriods; ++i) {
+ nTemp *= (1 + r);
+ }
+ FX_DOUBLE nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
+ while ( (nRet > FINANCIAL_PRECISION || nRet < -FINANCIAL_PRECISION) && (!bFlags) ) {
+ FX_DOUBLE nDerivative = 0;
+ nDerivative = ((nTemp + r * nPeriods * (nTemp / (1 + r))) * (nTemp - 1) - (r * nTemp * nPeriods * (nTemp / (1 + r)))) / ((nTemp - 1) * (nTemp - 1));
+ if (nDerivative == 0) {
+ bFlags = TRUE;
+ continue;
+ }
+ r = r - nRet / nDerivative;
+ nTemp = 1;
+ for (FX_INT32 i = 0; i < nPeriods; ++i) {
+ nTemp *= (1 + r);
+ }
+ nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
+ }
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ r = r * 12;
+ FXJSE_Value_SetDouble(args.GetReturnValue(), r);
+ }
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Apr"));
+ }
+}
+void CXFA_FM2JSContext::CTerm(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT nRate = 0;
+ FX_FLOAT nFutureValue = 0;
+ FX_FLOAT nInitAmount = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nRate = HValueToFloat(hThis, argOne);
+ nFutureValue = HValueToFloat(hThis, argTwo);
+ nInitAmount = HValueToFloat(hThis, argThree);
+ bFlags = ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FXJSE_Value_SetFloat(args.GetReturnValue(), FXSYS_log((FX_FLOAT)(nFutureValue / nInitAmount)) / FXSYS_log((FX_FLOAT)(1 + nRate)) );
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"CTerm"));
+ }
+}
+void CXFA_FM2JSContext::FV(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_DOUBLE nAmount = 0;
+ FX_DOUBLE nRate = 0;
+ FX_DOUBLE nPeriod = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nAmount = HValueToDouble(hThis, argOne);
+ nRate = HValueToDouble(hThis, argTwo);
+ nPeriod = HValueToDouble(hThis, argThree);
+ bFlags = ((nRate < 0) || (nPeriod <= 0) || (nAmount <= 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FX_DOUBLE dResult = 0;
+ if (!nRate) {
+ dResult = nAmount * nPeriod;
+ } else {
+ FX_DOUBLE nTemp = 1;
+ for (int i = 0; i < nPeriod; ++i) {
+ nTemp *= 1 + nRate;
+ }
+ dResult = nAmount * (nTemp - 1) / nRate;
+ }
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"FV"));
+ }
+}
+void CXFA_FM2JSContext::IPmt(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 5) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT nPrincpalAmount = 0;
+ FX_FLOAT nRate = 0;
+ FX_FLOAT nPayment = 0;
+ FX_FLOAT nFirstMonth = 0;
+ FX_FLOAT nNumberOfMonths = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ FXJSE_HVALUE argFour = GetSimpleHValue(hThis, args, 3);
+ FXJSE_HVALUE argFive = GetSimpleHValue(hThis, args, 4);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree) ||
+ HValueIsNull(hThis, argFour) || HValueIsNull(hThis, argFive));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nPrincpalAmount = HValueToFloat(hThis, argOne);
+ nRate = HValueToFloat(hThis, argTwo);
+ nPayment = HValueToFloat(hThis, argThree);
+ nFirstMonth = HValueToFloat(hThis, argFour);
+ nNumberOfMonths = HValueToFloat(hThis, argFive);
+ bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) || (nFirstMonth < 0) || (nNumberOfMonths < 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FX_FLOAT fResult = 0;
+ FX_FLOAT nRateOfMonth = nRate / 12;
+ FX_INT32 iNums = (FX_INT32)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) - FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount - nRateOfMonth))) / FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
+ FX_INT32 iEnd = (FX_INT32)(nFirstMonth + nNumberOfMonths - 1);
+ if (iEnd > iNums) {
+ iEnd = iNums;
+ }
+ FX_FLOAT nSum = 0;
+ if (nPayment < nPrincpalAmount * nRateOfMonth) {
+ bFlags = TRUE;
+ fResult = 0;
+ }
+ if(!bFlags) {
+ FX_INT32 i = 0;
+ for (i = 0; i < nFirstMonth - 1; ++i) {
+ nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
+ }
+ for (; i < iEnd; ++i) {
+ nSum += nPrincpalAmount * nRateOfMonth;
+ nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
+ }
+ fResult = nSum;
+ }
+ FXJSE_Value_SetFloat(args.GetReturnValue(), fResult);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ FXJSE_Value_Release(argFour);
+ FXJSE_Value_Release(argFive);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"IPmt"));
+ }
+}
+void CXFA_FM2JSContext::NPV(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FX_INT32 argc = args.GetLength();
+ if (argc > 2) {
+ FX_BOOL bFlags = FALSE;
+ FXJSE_HVALUE *argValues = FX_Alloc(FXJSE_HVALUE, argc);
+ for (FX_INT32 i = 0; i < argc; i++) {
+ argValues[i] = GetSimpleHValue(hThis, args, i);
+ if (HValueIsNull(hThis, argValues[i])) {
+ bFlags = TRUE;
+ }
+ }
+ if (!bFlags) {
+ FX_DOUBLE nRate = 0;
+ nRate = HValueToDouble(hThis, argValues[0]);
+ if (nRate <= 0) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FX_DOUBLE *pData = FX_Alloc(FX_DOUBLE, argc - 1);
+ for (FX_INT32 i = 1; i < argc; i++) {
+ pData[i - 1] = HValueToDouble(hThis, argValues[i]);
+ }
+ FX_DOUBLE nSum = 0;
+ FX_INT32 iIndex = 0;
+ for (FX_INT32 i = 0; i < argc - 1; i++) {
+ FX_DOUBLE nTemp = 1;
+ for (FX_INT32 j = 0; j <= i; j++) {
+ nTemp *= 1 + nRate;
+ }
+ FX_DOUBLE nNum = *(pData + iIndex++);
+ nSum += nNum / nTemp;
+ }
+ FXJSE_Value_SetDouble(args.GetReturnValue(), nSum);
+ FX_Free(pData);
+ pData = 0;
+ }
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ for (FX_INT32 i = 0; i < argc; i++) {
+ FXJSE_Value_Release(argValues[i]);
+ }
+ FX_Free(argValues);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"NPV"));
+ }
+}
+void CXFA_FM2JSContext::Pmt(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT nPrincipal = 0;
+ FX_FLOAT nRate = 0;
+ FX_FLOAT nPeriods = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nPrincipal = HValueToFloat(hThis, argOne);
+ nRate = HValueToFloat(hThis, argTwo);
+ nPeriods = HValueToFloat(hThis, argThree);
+ bFlags = ((nPrincipal <= 0) || (nRate <= 0) || (nPeriods <= 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FX_FLOAT nSum = 0;
+ FX_FLOAT nTmp = 1 + nRate;
+ nSum = nTmp;
+ for (FX_INT32 i = 0; i < nPeriods - 1; ++i) {
+ nSum *= nTmp;
+ }
+ FXJSE_Value_SetFloat(args.GetReturnValue(), (nPrincipal * nRate * nSum) / (nSum - 1));
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Pmt"));
+ }
+}
+void CXFA_FM2JSContext::PPmt(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 5) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT nPrincpalAmount = 0;
+ FX_FLOAT nRate = 0;
+ FX_FLOAT nPayment = 0;
+ FX_FLOAT nFirstMonth = 0;
+ FX_FLOAT nNumberOfMonths = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ FXJSE_HVALUE argFour = GetSimpleHValue(hThis, args, 3);
+ FXJSE_HVALUE argFive = GetSimpleHValue(hThis, args, 4);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree) ||
+ HValueIsNull(hThis, argFour) || HValueIsNull(hThis, argFive));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nPrincpalAmount = HValueToFloat(hThis, argOne);
+ nRate = HValueToFloat(hThis, argTwo);
+ nPayment = HValueToFloat(hThis, argThree);
+ nFirstMonth = HValueToFloat(hThis, argFour);
+ nNumberOfMonths = HValueToFloat(hThis, argFive);
+ bFlags = ((nPrincpalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) || (nFirstMonth < 0) || (nNumberOfMonths < 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FX_INT32 iEnd = (FX_INT32)(nFirstMonth + nNumberOfMonths - 1);
+ FX_FLOAT nSum = 0;
+ FX_FLOAT nRateOfMonth = nRate / 12;
+ FX_INT32 iNums = (FX_INT32)((FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount)) - FXSYS_log10((FX_FLOAT)(nPayment / nPrincpalAmount - nRateOfMonth))) / FXSYS_log10((FX_FLOAT)(1 + nRateOfMonth)));
+ if (iEnd > iNums) {
+ iEnd = iNums;
+ }
+ if (nPayment < nPrincpalAmount * nRateOfMonth) {
+ bFlags = TRUE;
+ }
+ if(!bFlags) {
+ FX_INT32 i = 0;
+ for (i = 0; i < nFirstMonth - 1; ++i) {
+ nPrincpalAmount -= nPayment - nPrincpalAmount * nRateOfMonth;
+ }
+ FX_FLOAT nTemp = 0;
+ for (; i < iEnd; ++i) {
+ nTemp = nPayment - nPrincpalAmount * nRateOfMonth;
+ nSum += nTemp;
+ nPrincpalAmount -= nTemp;
+ }
+ FXJSE_Value_SetFloat(args.GetReturnValue(), nSum);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ FXJSE_Value_Release(argFour);
+ FXJSE_Value_Release(argFive);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"PPmt"));
+ }
+}
+void CXFA_FM2JSContext::PV(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_DOUBLE nAmount = 0;
+ FX_DOUBLE nRate = 0;
+ FX_DOUBLE nPeriod = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nAmount = HValueToDouble(hThis, argOne);
+ nRate = HValueToDouble(hThis, argTwo);
+ nPeriod = HValueToDouble(hThis, argThree);
+ bFlags = ((nAmount <= 0) || (nRate < 0) || (nPeriod <= 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FX_DOUBLE nTemp = 1;
+ for (FX_INT32 i = 0; i < nPeriod; ++i) {
+ nTemp *= 1 + nRate;
+ }
+ nTemp = 1 / nTemp;
+ FXJSE_Value_SetDouble(args.GetReturnValue(), nAmount * ((1 - nTemp) / nRate));
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"PV"));
+ }
+}
+void CXFA_FM2JSContext::Rate(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT nFuture = 0;
+ FX_FLOAT nPresent = 0;
+ FX_FLOAT nTotalNumber = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ bFlags = (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo) || HValueIsNull(hThis, argThree));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nFuture = HValueToFloat(hThis, argOne);
+ nPresent = HValueToFloat(hThis, argTwo);
+ nTotalNumber = HValueToFloat(hThis, argThree);
+ bFlags = ((nFuture <= 0) || (nPresent < 0) || (nTotalNumber <= 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FXJSE_Value_SetFloat(args.GetReturnValue(), (FXSYS_pow((FX_FLOAT)(nFuture / nPresent) , (FX_FLOAT)(1 / nTotalNumber)) - 1));
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Rate"));
+ }
+}
+void CXFA_FM2JSContext::Term(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if(args.GetLength() == 3) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT nMount = 0;
+ FX_FLOAT nRate = 0;
+ FX_FLOAT nFuture = 0;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = GetSimpleHValue(hThis, args, 2);
+ bFlags = (FXJSE_Value_IsNull(argOne) || FXJSE_Value_IsNull(argTwo) || FXJSE_Value_IsNull(argThree));
+ if(bFlags) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ nMount = HValueToFloat(hThis, argOne);
+ nRate = HValueToFloat(hThis, argTwo);
+ nFuture = HValueToFloat(hThis, argThree);
+ bFlags = ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0));
+ if(bFlags) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ FXJSE_Value_SetFloat(args.GetReturnValue(), (FXSYS_log((FX_FLOAT)(nFuture / nMount * nRate) + 1) / FXSYS_log((FX_FLOAT)(1 + nRate))));
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ FXJSE_Value_Release(argThree);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Term"));
+ }
+}
+void CXFA_FM2JSContext::Choose(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if (argc > 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ FX_BOOL argOneIsNull = FALSE;
+ FX_INT32 iIndex = 0;
+ argOneIsNull = HValueIsNull(hThis, argOne);
+ if (!argOneIsNull) {
+ iIndex = (FX_INT32)HValueToFloat(hThis, argOne);
+ }
+ FXJSE_Value_Release(argOne);
+ if (argOneIsNull) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else if (iIndex < 1) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ } else {
+ FX_BOOL bFound = FALSE;
+ FX_BOOL bStopCounterFlags = FALSE;
+ FX_INT32 iArgIndex = 1;
+ FX_INT32 iValueIndex = 0;
+ while(!bFound && !bStopCounterFlags && (iArgIndex < argc)) {
+ FXJSE_HVALUE argIndexValue = args.GetValue(iArgIndex);
+ if (FXJSE_Value_IsArray(argIndexValue)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argIndexValue, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if (iLength > 3) {
+ bStopCounterFlags = TRUE;
+ }
+ iValueIndex += (iLength - 2);
+ if (iValueIndex >= iIndex) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argIndexValue, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argIndexValue, ((iLength - 1) - (iValueIndex - iIndex)), jsobjectValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ GetObjectDefaultValue(jsobjectValue, newProperty);
+ } else {
+ CFX_ByteString propStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propStr);
+ FXJSE_Value_GetObjectProp(jsobjectValue, propStr, newProperty);
+ }
+ CFX_ByteString bsChoosed;
+ HValueToUTF8String(newProperty, bsChoosed);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed);
+ FXJSE_Value_Release(newProperty);
+ FXJSE_Value_Release(jsobjectValue);
+ FXJSE_Value_Release(propertyValue);
+ bFound = TRUE;
+ }
+ } else {
+ iValueIndex ++;
+ if (iValueIndex == iIndex) {
+ CFX_ByteString bsChoosed;
+ HValueToUTF8String(argIndexValue, bsChoosed);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsChoosed);
+ bFound = TRUE;
+ }
+ }
+ FXJSE_Value_Release(argIndexValue);
+ iArgIndex++;
+ }
+ if (!bFound) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Choose"));
+ }
+}
+void CXFA_FM2JSContext::Exists(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), FXJSE_Value_IsObject(argOne));
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Exists"));
+ }
+}
+void CXFA_FM2JSContext::HasValue(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsUTF8String(argOne)) {
+ CFX_ByteString valueStr;
+ FXJSE_Value_ToUTF8String(argOne, valueStr);
+ valueStr.TrimLeft();
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (!valueStr.IsEmpty()));
+ } else if (FXJSE_Value_IsNumber(argOne) || FXJSE_Value_IsBoolean(argOne)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), TRUE);
+ } else {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), FALSE);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"HasValue"));
+ }
+}
+void CXFA_FM2JSContext::Oneof(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if(argc > 1) {
+ FX_BOOL bFlags = FALSE;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE *parametersValue = 0;
+ FX_INT32 iCount = 0;
+ unfoldArgs(hThis, args, parametersValue, iCount, 1);
+ for(FX_INT32 i = 0; i < iCount; i++) {
+ if(simpleValueCompare(hThis, argOne, parametersValue[i])) {
+ bFlags = TRUE;
+ break;
+ }
+ }
+ FXJSE_Value_SetInteger(args.GetReturnValue(), bFlags);
+ FXJSE_Value_Release(argOne);
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ FXJSE_Value_Release(parametersValue[i]);
+ }
+ FX_Free(parametersValue);
+ parametersValue = 0;
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Oneof"));
+ }
+}
+void CXFA_FM2JSContext::Within(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if(argc == 3) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if(FXJSE_Value_IsNull(argOne)) {
+ FXJSE_Value_SetUndefined(args.GetReturnValue());
+ } else {
+ FXJSE_HVALUE argLow = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argHeight = GetSimpleHValue(hThis, args, 2);
+ if(FXJSE_Value_IsNumber(argOne)) {
+ FX_FLOAT oneNumber = HValueToFloat(hThis, argOne);
+ FX_FLOAT lowNumber = HValueToFloat(hThis, argLow);
+ FX_FLOAT heightNumber = HValueToFloat(hThis, argHeight);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), ((oneNumber >= lowNumber) && (oneNumber <= heightNumber)) );
+ } else {
+ CFX_ByteString oneString;
+ CFX_ByteString lowString;
+ CFX_ByteString heightString;
+ HValueToUTF8String(argOne, oneString);
+ HValueToUTF8String(argLow, lowString);
+ HValueToUTF8String(argHeight, heightString);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), ((oneString.Compare(lowString) >= 0) && (oneString.Compare(heightString) <= 0)));
+ }
+ FXJSE_Value_Release(argLow);
+ FXJSE_Value_Release(argHeight);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Within"));
+ }
+}
+void CXFA_FM2JSContext::If(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if (args.GetLength() == 3) {
+ FXJSE_HVALUE argCondition = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argFirstValue = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argSecondValue = GetSimpleHValue(hThis, args, 2);
+ FX_BOOL bCondition = FXJSE_Value_ToBoolean(argCondition);
+ FXJSE_Value_Set(args.GetReturnValue(), bCondition ? argFirstValue : argSecondValue);
+ FXJSE_Value_Release(argSecondValue);
+ FXJSE_Value_Release(argFirstValue);
+ FXJSE_Value_Release(argCondition);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"If"));
+ }
+}
+void CXFA_FM2JSContext::Eval(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE scriptValue = GetSimpleHValue(hThis, args, 0);
+ CFX_ByteString utf8ScriptString;
+ HValueToUTF8String(scriptValue, utf8ScriptString);
+ if (utf8ScriptString.IsEmpty()) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_WideTextBuf wsJavaScriptBuf;
+ CFX_WideString javaScript;
+ CFX_WideString wsError;
+ XFA_FM2JS_Translate(CFX_WideString::FromUTF8(utf8ScriptString, utf8ScriptString.GetLength()), wsJavaScriptBuf, wsError);
+ FXJSE_HCONTEXT hContext = FXJSE_Context_Create(hruntime);
+ FXJSE_HVALUE returnValue = FXJSE_Value_Create(hruntime);
+ javaScript = wsJavaScriptBuf.GetWideString();
+ FXJSE_ExecuteScript(hContext, FX_UTF8Encode(javaScript, javaScript.GetLength()), returnValue);
+ FXJSE_Value_Set(args.GetReturnValue(), returnValue);
+ FXJSE_Value_Release(returnValue);
+ FXJSE_Context_Release(hContext);
+ }
+ FXJSE_Value_Release(scriptValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Eval"));
+ }
+}
+void CXFA_FM2JSContext::Ref(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ if (FXJSE_Value_IsNull(argOne)) {
+ FXJSE_HVALUE rgValues[3];
+ for (FX_INT32 i = 0; i < 3; i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 4);
+ FXJSE_Value_SetNull(rgValues[1]);
+ FXJSE_Value_SetNull(rgValues[2]);
+ FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+ for (FX_INT32 i = 0; i < 3; i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ } else if (FXJSE_Value_IsArray(argOne)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argOne, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ FXSYS_assert(iLength >= 3);
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsObjectValue);
+ if(FXJSE_Value_IsNull(jsObjectValue)) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else if(FXJSE_Value_IsNull(propertyValue) && (!FXJSE_Value_IsNull(jsObjectValue))) {
+ FXJSE_HVALUE rgValues[3];
+ for (FX_INT32 i = 0; i < 3; i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 3);
+ FXJSE_Value_SetNull(rgValues[1]);
+ FXJSE_Value_Set(rgValues[2], jsObjectValue);
+ FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+ for (FX_INT32 i = 0; i < 3; i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ FXJSE_Value_Release(jsObjectValue);
+ FXJSE_Value_Release(propertyValue);
+ } else if(FXJSE_Value_IsObject(argOne)) {
+ FXJSE_HVALUE rgValues[3];
+ for (FX_INT32 i = 0; i < 3; i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 3);
+ FXJSE_Value_SetNull(rgValues[1]);
+ FXJSE_Value_Set(rgValues[2], argOne);
+ FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+ for (FX_INT32 i = 0; i < 3; i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ } else if(FXJSE_Value_IsBoolean(argOne) || FXJSE_Value_IsUTF8String(argOne) || FXJSE_Value_IsNumber(argOne)) {
+ FXJSE_Value_Set(args.GetReturnValue(), argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Ref"));
+ }
+}
+void CXFA_FM2JSContext::UnitType(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE unitspanValue = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(unitspanValue)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ FXJSE_Value_Release(unitspanValue);
+ return;
+ }
+ CFX_ByteString unitspanString;
+ HValueToUTF8String(unitspanValue, unitspanString);
+ if (unitspanString.IsEmpty()) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC("in"));
+ } else {
+ enum XFA_FM2JS_VALUETYPE_ParserStatus {
+ VALUETYPE_START,
+ VALUETYPE_HAVEINVALIDCHAR,
+ VALUETYPE_HAVEDIGIT,
+ VALUETYPE_HAVEDIGITWHITE,
+ VALUETYPE_ISCM,
+ VALUETYPE_ISMM,
+ VALUETYPE_ISPT,
+ VALUETYPE_ISMP,
+ VALUETYPE_ISIN,
+ };
+ unitspanString.MakeLower();
+ CFX_WideString wsTypeString = CFX_WideString::FromUTF8(unitspanString, unitspanString.GetLength());
+ FX_LPCWSTR pData = wsTypeString;
+ FX_INT32 u = 0;
+ FX_INT32 uLen = wsTypeString.GetLength();
+ while (*(pData + u) == 0x20 || *(pData + u) == 0x09 || *(pData + u) == 0x0B || *(pData + u) == 0x0C || *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+ u++;
+ }
+ XFA_FM2JS_VALUETYPE_ParserStatus eParserStatus = VALUETYPE_START;
+ FX_WCHAR typeChar;
+ while (u < uLen) {
+ typeChar = *(pData + u);
+ if (typeChar == 0x20 || typeChar == 0x09 || typeChar == 0x0B || typeChar == 0x0C || typeChar == 0x0A || typeChar == 0x0D) {
+ if(eParserStatus == VALUETYPE_HAVEDIGIT || eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
+ eParserStatus = VALUETYPE_HAVEDIGITWHITE;
+ } else {
+ eParserStatus = VALUETYPE_ISIN;
+ break;
+ }
+ } else if ((typeChar >= '0' && typeChar <= '9') || typeChar == '-' || typeChar == '.') {
+ if (eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
+ eParserStatus = VALUETYPE_ISIN;
+ break;
+ } else {
+ eParserStatus = VALUETYPE_HAVEDIGIT;
+ }
+ } else if ((typeChar == 'c' || typeChar == 'p') && (u + 1 < uLen)) {
+ FX_WCHAR nextChar = *(pData + u + 1);
+ if ((eParserStatus == VALUETYPE_START || eParserStatus == VALUETYPE_HAVEDIGIT || eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
+ (nextChar > '9' || nextChar < '0') && nextChar != '.' && nextChar != '-' ) {
+ eParserStatus = (typeChar == 'c') ? VALUETYPE_ISCM : VALUETYPE_ISPT;
+ break;
+ } else {
+ eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
+ }
+ } else if (typeChar == 'm' && (u + 1 < uLen)) {
+ FX_WCHAR nextChar = *(pData + u + 1);
+ if ((eParserStatus == VALUETYPE_START || eParserStatus == VALUETYPE_HAVEDIGIT || eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
+ (nextChar > '9' || nextChar < '0') && nextChar != '.' && nextChar != '-' ) {
+ eParserStatus = VALUETYPE_ISMM;
+ if (nextChar == 'p' ||
+ ((u + 5 < uLen) && *(pData + u + 1) == 'i' && *(pData + u + 2) == 'l' && *(pData + u + 3) == 'l' && *(pData + u + 4) == 'i' && *(pData + u + 5) == 'p')
+ ) {
+ eParserStatus = VALUETYPE_ISMP;
+ }
+ break;
+ }
+ } else {
+ eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
+ }
+ u++;
+ }
+ switch (eParserStatus) {
+ case VALUETYPE_ISCM:
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC("cm"));
+ break;
+ case VALUETYPE_ISMM:
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC("mm"));
+ break;
+ case VALUETYPE_ISPT:
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC("pt"));
+ break;
+ case VALUETYPE_ISMP:
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC("mp"));
+ break;
+ default:
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC("in"));
+ break;
+ }
+ }
+ FXJSE_Value_Release(unitspanValue);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"UnitType"));
+ }
+}
+void CXFA_FM2JSContext::UnitValue(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc == 1) || (argc == 2)) {
+ FXJSE_HVALUE unitspanValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE unitValue = 0;
+ CFX_ByteString unitspanString;
+ FX_DOUBLE dFirstNumber = 0;
+ CFX_ByteString strFirstUnit;
+ CFX_ByteString strUnit;
+ if (FXJSE_Value_IsNull(unitspanValue)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ HValueToUTF8String(unitspanValue, unitspanString);
+ FX_LPCSTR pData = unitspanString;
+ if (pData) {
+ FX_INT32 u = 0;
+ while (*(pData + u) == 0x20 || *(pData + u) == 0x09 || *(pData + u) == 0x0B || *(pData + u) == 0x0C || *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+ FX_CHAR ch = *(pData + u);
+ ++u;
+ }
+ FX_INT32 uStart = u;
+ while (u < unitspanString.GetLength()) {
+ if ((*(pData + u) > '9' || *(pData + u) < '0') && *(pData + u) != '.' && *(pData + u) != '-') {
+ break;
+ }
+ ++u;
+ }
+ FX_CHAR * pTemp = NULL;
+ dFirstNumber = strtod(pData, &pTemp);
+ while (*(pData + u) == ' ' || *(pData + u) == 0x09 || *(pData + u) == 0x0B || *(pData + u) == 0x0C || *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+ ++u;
+ }
+ FX_INT32 uLen = unitspanString.GetLength();
+ while (u < uLen) {
+ if (*(pData + u) == ' ') {
+ break;
+ }
+ strFirstUnit += (*(pData + u));
+ ++u;
+ }
+ strFirstUnit.MakeLower();
+ if (argc == 2) {
+ unitValue = GetSimpleHValue(hThis, args, 1);
+ CFX_ByteString unitTempString;
+ HValueToUTF8String(unitValue, unitTempString);
+ FX_LPCSTR pData = unitTempString;
+ FX_INT32 u = 0;
+ while (*(pData + u) == ' ' || *(pData + u) == 0x09 || *(pData + u) == 0x0B || *(pData + u) == 0x0C || *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+ ++u;
+ }
+ while (u < unitTempString.GetLength()) {
+ if ((*(pData + u) > '9' || *(pData + u) < '0') && *(pData + u) != '.') {
+ break;
+ }
+ ++u;
+ }
+ while (*(pData + u) == ' ' || *(pData + u) == 0x09 || *(pData + u) == 0x0B || *(pData + u) == 0x0C || *(pData + u) == 0x0A || *(pData + u) == 0x0D) {
+ ++u;
+ }
+ FX_INT32 uLen = unitTempString.GetLength();
+ while (u < uLen) {
+ if (*(pData + u) == ' ') {
+ break;
+ }
+ strUnit += (*(pData + u));
+ ++u;
+ }
+ strUnit.MakeLower();
+ } else {
+ strUnit = strFirstUnit;
+ }
+ FX_DOUBLE dResult = 0;
+ if (strFirstUnit.Equal("in") || strFirstUnit.Equal("inches")) {
+ if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+ dResult = dFirstNumber * 25.4;
+ } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+ dResult = dFirstNumber * 2.54;
+ } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+ dResult = dFirstNumber / 72;
+ } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+ dResult = dFirstNumber / 72000;
+ } else {
+ dResult = dFirstNumber;
+ }
+ } else if (strFirstUnit.Equal("mm") || strFirstUnit.Equal("millimeters")) {
+ if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+ dResult = dFirstNumber;
+ } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+ dResult = dFirstNumber / 10;
+ } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+ dResult = dFirstNumber / 25.4 / 72;
+ } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+ dResult = dFirstNumber / 25.4 / 72000;
+ } else {
+ dResult = dFirstNumber / 25.4;
+ }
+ } else if (strFirstUnit.Equal("cm") || strFirstUnit.Equal("centimeters")) {
+ if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+ dResult = dFirstNumber * 10;
+ } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+ dResult = dFirstNumber;
+ } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+ dResult = dFirstNumber / 2.54 / 72;
+ } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+ dResult = dFirstNumber / 2.54 / 72000;
+ } else {
+ dResult = dFirstNumber / 2.54;
+ }
+ } else if (strFirstUnit.Equal("pt") || strFirstUnit.Equal("points")) {
+ if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+ dResult = dFirstNumber / 72 * 25.4;
+ } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+ dResult = dFirstNumber / 72 * 2.54;
+ } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+ dResult = dFirstNumber;
+ } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+ dResult = dFirstNumber * 1000;
+ } else {
+ dResult = dFirstNumber / 72;
+ }
+ } else if (strFirstUnit.Equal("mp") || strFirstUnit.Equal("millipoints")) {
+ if (strUnit.Equal("mm") || strUnit.Equal("millimeters")) {
+ dResult = dFirstNumber / 72000 * 25.4;
+ } else if (strUnit.Equal("cm") || strUnit.Equal("centimeters")) {
+ dResult = dFirstNumber / 72000 * 2.54;
+ } else if (strUnit.Equal("pt") || strUnit.Equal("points")) {
+ dResult = dFirstNumber / 1000;
+ } else if (strUnit.Equal("mp") || strUnit.Equal("millipoints")) {
+ dResult = dFirstNumber;
+ } else {
+ dResult = dFirstNumber / 72000;
+ }
+ }
+ FXJSE_Value_SetDouble(args.GetReturnValue(), dResult);
+ } else {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ }
+ }
+ FXJSE_Value_Release(unitspanValue);
+ if (argc == 2) {
+ FXJSE_Value_Release(unitValue);
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"UnitValue"));
+ }
+}
+void CXFA_FM2JSContext::At(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString stringTwo;
+ HValueToUTF8String(argTwo, stringTwo);
+ if (stringTwo.IsEmpty()) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
+ } else {
+ CFX_ByteString stringOne;
+ HValueToUTF8String(argOne, stringOne);
+ FX_STRSIZE iPosition = stringOne.Find(stringTwo);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), iPosition + 1);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"At"));
+ }
+}
+void CXFA_FM2JSContext::Concat(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if (argc >= 1) {
+ CFX_ByteString resultString;
+ FX_BOOL bAllNull = TRUE;
+ FXJSE_HVALUE *argValues = FX_Alloc(FXJSE_HVALUE, argc);
+ for (FX_INT32 i = 0; i < argc; i++) {
+ argValues[i] = GetSimpleHValue(hThis, args, i);
+ if(!HValueIsNull(hThis, argValues[i])) {
+ CFX_ByteString valueStr;
+ HValueToUTF8String(argValues[i], valueStr);
+ resultString += valueStr;
+ bAllNull = FALSE;
+ }
+ }
+ for(FX_INT32 i = 0; i < argc; i++) {
+ FXJSE_Value_Release(argValues[i]);
+ }
+ FX_Free(argValues);
+ if (bAllNull) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultString);
+ }
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Concat"));
+ }
+}
+void CXFA_FM2JSContext::Decode(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if(argc == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString toDecodeString;
+ HValueToUTF8String(argOne, toDecodeString);
+ CFX_ByteTextBuf resultBuf;
+ DecodeURL(toDecodeString, resultBuf);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.GetByteString());
+ }
+ FXJSE_Value_Release(argOne);
+ } else if (argc == 2) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString toDecodeString;
+ HValueToUTF8String(argOne, toDecodeString);
+ CFX_ByteString identifyString;
+ HValueToUTF8String(argTwo, identifyString);
+ CFX_ByteTextBuf resultBuf;
+ if (identifyString.EqualNoCase(FX_BSTRC("html"))) {
+ DecodeHTML(toDecodeString, resultBuf);
+ } else if (identifyString.EqualNoCase(FX_BSTRC("xml"))) {
+ DecodeXML(toDecodeString, resultBuf);
+ } else {
+ DecodeURL(toDecodeString, resultBuf);
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.GetByteString());
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Decode"));
+ }
+}
+void CXFA_FM2JSContext::DecodeURL (FX_BSTR szURLString, CFX_ByteTextBuf &szResultString)
+{
+ CFX_WideString wsURLString = CFX_WideString::FromUTF8(szURLString.GetCStr(), szURLString.GetLength());
+ FX_LPCWSTR pData = wsURLString;
+ FX_INT32 iLen = wsURLString.GetLength();
+ FX_INT32 i = 0;
+ FX_WCHAR ch = 0;
+ FX_WCHAR chTemp = 0;
+ CFX_WideTextBuf wsResultBuf;
+ while (i < iLen) {
+ ch = *(pData + i);
+ if ('%' == ch) {
+ chTemp = 0;
+ FX_INT32 iCount = 0;
+ while (iCount < 2) {
+ ++i;
+ ch = *(pData + i);
+ if (ch <= '9' && ch >= '0') {
+ if (!iCount) {
+ chTemp += (ch - '0') * 16;
+ } else {
+ chTemp += (ch - '0');
+ }
+ } else {
+ if (ch <= 'F' && ch >= 'A') {
+ if (!iCount) {
+ chTemp += (ch - 'A' + 10) * 16;
+ } else {
+ chTemp += (ch - 'A' + 10);
+ }
+ } else if (ch <= 'f' && ch >= 'a') {
+ if (!iCount) {
+ chTemp += (ch - 'a' + 10) * 16;
+ } else {
+ chTemp += (ch - 'a' + 10);
+ }
+ } else {
+ wsResultBuf.Clear();
+ return;
+ }
+ }
+ ++iCount;
+ }
+ wsResultBuf.AppendChar(chTemp);
+ } else {
+ wsResultBuf.AppendChar(ch);
+ }
+ ++i;
+ }
+ wsResultBuf.AppendChar(0);
+ szResultString = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::DecodeHTML(FX_BSTR szHTMLString, CFX_ByteTextBuf &szResultString)
+{
+ CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(szHTMLString.GetCStr(), szHTMLString.GetLength());
+ FX_WCHAR strString[9];
+ FX_INT32 iStrIndex = 0;
+ FX_INT32 iLen = wsHTMLString.GetLength();
+ FX_INT32 i = 0;
+ FX_INT32 iCode = 0;
+ FX_WCHAR ch = 0;
+ FX_LPCWSTR pData = wsHTMLString;
+ CFX_WideTextBuf wsResultBuf;
+ while (i < iLen) {
+ ch = *(pData + i);
+ if (ch == '&') {
+ ++i;
+ ch = *(pData + i);
+ if (ch == '#') {
+ ++i;
+ ch = *(pData + i);
+ if (ch == 'x' || ch == 'X') {
+ ++i;
+ ch = *(pData + i);
+ if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') || (ch <= 'F' && ch >= 'A')) {
+ while (ch != ';' && i < iLen) {
+ if (ch >= '0' && ch <= '9') {
+ iCode += ch - '0';
+ } else if (ch <= 'f' && ch >= 'a') {
+ iCode += ch - 'a' + 10;
+ } else if (ch <= 'F' && ch >= 'A') {
+ iCode += ch - 'A' + 10;
+ } else {
+ wsResultBuf.Clear();
+ return;
+ }
+ ++i;
+ iCode *= 16;
+ ch = *(pData + i);
+ }
+ iCode /= 16;
+ }
+ } else {
+ wsResultBuf.Clear();
+ return;
+ }
+ } else {
+ while (ch != ';' && i < iLen) {
+ strString[iStrIndex++] = ch;
+ ++i;
+ ch = *(pData + i);
+ }
+ strString[iStrIndex] = 0;
+ }
+ } else {
+ wsResultBuf.AppendChar(ch);
+ ++i;
+ continue;
+ }
+ FX_UINT32 iData = 0;
+ if (HTMLSTR2Code(strString, iData)) {
+ wsResultBuf.AppendChar((FX_WCHAR)iData);
+ } else {
+ wsResultBuf.AppendChar(iCode);
+ }
+ iStrIndex = 0;
+ strString[iStrIndex] = 0;
+ ++i;
+ }
+ wsResultBuf.AppendChar(0);
+ szResultString = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::DecodeXML (FX_BSTR szXMLString, CFX_ByteTextBuf &szResultString)
+{
+ CFX_WideString wsXMLString = CFX_WideString::FromUTF8(szXMLString.GetCStr(), szXMLString.GetLength());
+ FX_WCHAR strString[9];
+ FX_INT32 iStrIndex = 0;
+ FX_INT32 iLen = wsXMLString.GetLength();
+ FX_INT32 i = 0;
+ FX_INT32 iCode = 0;
+ FX_WCHAR ch = 0;
+ FX_LPCWSTR pData = wsXMLString;
+ CFX_WideTextBuf wsXMLBuf;
+ while (i < iLen) {
+ ch = *(pData + i);
+ if (ch == '&') {
+ ++i;
+ ch = *(pData + i);
+ if (ch == '#') {
+ ++i;
+ ch = *(pData + i);
+ if (ch == 'x' || ch == 'X') {
+ ++i;
+ ch = *(pData + i);
+ if ((ch >= '0' && ch <= '9') || (ch <= 'f' && ch >= 'a') || (ch <= 'F' && ch >= 'A')) {
+ while (ch != ';') {
+ if (ch >= '0' && ch <= '9') {
+ iCode += ch - '0';
+ } else if (ch <= 'f' && ch >= 'a') {
+ iCode += ch - 'a' + 10;
+ } else if (ch <= 'F' && ch >= 'A') {
+ iCode += ch - 'A' + 10;
+ } else {
+ wsXMLBuf.Clear();
+ return;
+ }
+ ++i;
+ iCode *= 16;
+ ch = *(pData + i);
+ }
+ iCode /= 16;
+ }
+ } else {
+ wsXMLBuf.Clear();
+ return;
+ }
+ } else {
+ while (ch != ';' && i < iLen) {
+ strString[iStrIndex++] = ch;
+ ++i;
+ ch = *(pData + i);
+ }
+ strString[iStrIndex] = 0;
+ }
+ } else {
+ wsXMLBuf.AppendChar(ch);
+ ++i;
+ continue;
+ }
+ FX_WCHAR *strName[] = {
+ (FX_WCHAR *)L"quot",
+ (FX_WCHAR *)L"amp",
+ (FX_WCHAR *)L"apos",
+ (FX_WCHAR *)L"lt",
+ (FX_WCHAR *)L"gt"
+ };
+ FX_INT32 iIndex = 0;
+ while (iIndex < 5) {
+ if (FXSYS_memcmp(strString, strName[iIndex], FXSYS_wcslen(strName[iIndex])) == 0) {
+ break;
+ }
+ ++iIndex;
+ }
+ switch (iIndex) {
+ case 0:
+ wsXMLBuf.AppendChar('"');
+ break;
+ case 1:
+ wsXMLBuf.AppendChar('&');
+ break;
+ case 2:
+ wsXMLBuf.AppendChar('\'');
+ break;
+ case 3:
+ wsXMLBuf.AppendChar('<');
+ break;
+ case 4:
+ wsXMLBuf.AppendChar('>');
+ break;
+ default:
+ wsXMLBuf.AppendChar(iCode);
+ break;
+ }
+ iStrIndex = 0;
+ strString[iStrIndex] = 0;
+ ++i;
+ iCode = 0;
+ }
+ wsXMLBuf.AppendChar(0);
+ szResultString = FX_UTF8Encode(wsXMLBuf.GetBuffer(), wsXMLBuf.GetLength());
+}
+void CXFA_FM2JSContext::Encode(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if(argc == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString toEncodeString;
+ HValueToUTF8String(argOne, toEncodeString);
+ CFX_ByteTextBuf resultBuf;
+ EncodeURL(toEncodeString, resultBuf);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.GetByteString());
+ }
+ FXJSE_Value_Release(argOne);
+ } else if (argc == 2) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ if (HValueIsNull(hThis, argOne) || HValueIsNull(hThis, argTwo)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString toEncodeString;
+ HValueToUTF8String(argOne, toEncodeString);
+ CFX_ByteString identifyString;
+ HValueToUTF8String(argTwo, identifyString);
+ CFX_ByteTextBuf resultBuf;
+ if (identifyString.EqualNoCase(FX_BSTRC("html"))) {
+ EncodeHTML(toEncodeString, resultBuf);
+ } else if (identifyString.EqualNoCase(FX_BSTRC("xml"))) {
+ EncodeXML(toEncodeString, resultBuf);
+ } else {
+ EncodeURL(toEncodeString, resultBuf);
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.GetByteString());
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Encode"));
+ }
+}
+void CXFA_FM2JSContext::EncodeURL (FX_BSTR szURLString, CFX_ByteTextBuf &szResultBuf)
+{
+ CFX_WideString wsURLString = CFX_WideString::FromUTF8(szURLString.GetCStr(), szURLString.GetLength());
+ CFX_WideTextBuf wsResultBuf;
+ FX_WCHAR ch = 0;
+ FX_INT32 iLength = wsURLString.GetLength();
+ FX_WCHAR strEncode[4];
+ strEncode[0] = '%';
+ strEncode[3] = 0;
+ FX_WCHAR strUnsafe[] = { ' ', '<', '>', '"', '#', '%', '{', '}', '|', '\\', '^', '~', '[', ']', '`' };
+ FX_WCHAR strReserved[] = {';', '/', '?', ':', '@', '=', '&'};
+ FX_WCHAR strSpecial[] = {'$', '-', '+', '!', '*', '\'', '(', ')', ','};
+ FX_WCHAR* strCode = (FX_WCHAR *)L"0123456789abcdef";
+ for (FX_INT32 u = 0; u < iLength; ++u) {
+ ch = wsURLString.GetAt(u);
+ FX_INT32 i = 0;
+ FX_INT32 iCount = sizeof(strUnsafe) / sizeof(strUnsafe[0]);
+ while (i < iCount) {
+ if (ch == strUnsafe[i]) {
+ FX_INT32 iIndex = ch / 16;
+ strEncode[1] = strCode[iIndex];
+ strEncode[2] = strCode[ch - iIndex * 16];
+ wsResultBuf << FX_WSTRC(strEncode);
+ break;
+ }
+ ++i;
+ }
+ if (i < iCount) {
+ continue;
+ }
+ i = 0;
+ iCount = sizeof(strReserved) / sizeof(strReserved[0]);
+ while (i < iCount) {
+ if (ch == strReserved[i]) {
+ FX_INT32 iIndex = ch / 16;
+ strEncode[1] = strCode[iIndex];
+ strEncode[2] = strCode[ch - iIndex * 16];
+ wsResultBuf << FX_WSTRC(strEncode);
+ break;
+ }
+ ++i;
+ }
+ if (i < iCount) {
+ continue;
+ }
+ i = 0;
+ iCount = sizeof(strSpecial) / sizeof(strSpecial[0]);
+ while (i < iCount) {
+ if (ch == strSpecial[i]) {
+ wsResultBuf.AppendChar(ch);
+ break;
+ }
+ ++i;
+ }
+ if (i < iCount) {
+ continue;
+ }
+ if (ch >= 0x80 && ch <= 0xff) {
+ FX_INT32 iIndex = ch / 16;
+ strEncode[1] = strCode[iIndex];
+ strEncode[2] = strCode[ch - iIndex * 16];
+ wsResultBuf << FX_WSTRC(strEncode);
+ } else if ((ch >= 0x0 && ch <= 0x1f) || ch == 0x7f) {
+ FX_INT32 iIndex = ch / 16;
+ strEncode[1] = strCode[iIndex];
+ strEncode[2] = strCode[ch - iIndex * 16];
+ wsResultBuf << FX_WSTRC(strEncode);
+ } else if (ch >= 0x20 && ch <= 0x7e) {
+ wsResultBuf.AppendChar(ch);
+ } else {
+ FX_INT32 iRadix = 16;
+ CFX_WideString strTmp;
+ while (ch >= iRadix) {
+ FX_WCHAR tmp = strCode[ch % iRadix];
+ ch /= iRadix;
+ strTmp += tmp;
+ }
+ strTmp += strCode[ch];
+ FX_INT32 iLen = strTmp.GetLength();
+ if (iLen < 2) {
+ break;
+ }
+ FX_INT32 iIndex = 0;
+ if (iLen % 2 != 0) {
+ strEncode[1] = '0';
+ strEncode[2] = strTmp.GetAt(iLen - 1);
+ iIndex = iLen - 2;
+ } else {
+ strEncode[1] = strTmp.GetAt(iLen - 1);
+ strEncode[2] = strTmp.GetAt(iLen - 2);
+ iIndex = iLen - 3;
+ }
+ wsResultBuf << FX_WSTRC(strEncode);
+ while (iIndex > 0) {
+ strEncode[1] = strTmp.GetAt(iIndex);
+ strEncode[2] = strTmp.GetAt(iIndex - 1);
+ iIndex -= 2;
+ wsResultBuf << FX_WSTRC(strEncode);
+ }
+ }
+ }
+ wsResultBuf.AppendChar(0);
+ szResultBuf = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::EncodeHTML(FX_BSTR szHTMLString, CFX_ByteTextBuf &szResultBuf)
+{
+ CFX_ByteString str = szHTMLString.GetCStr();
+ CFX_WideString wsHTMLString = CFX_WideString::FromUTF8(str, str.GetLength());
+ FX_LPCWSTR strCode = (FX_LPCWSTR)L"0123456789abcdef";
+ FX_WCHAR strEncode[9];
+ strEncode[0] = '&';
+ strEncode[1] = '#';
+ strEncode[2] = 'x';
+ strEncode[5] = ';';
+ strEncode[6] = 0;
+ strEncode[7] = ';';
+ strEncode[8] = 0;
+ CFX_WideTextBuf wsResultBuf;
+ FX_UINT32 ch = 0;
+ FX_INT32 iLen = wsHTMLString.GetLength();
+ FX_INT32 i = 0;
+ FX_LPCWSTR pData = wsHTMLString;
+ FX_INT32 iIndex = 0;
+ CFX_WideString htmlReserve;
+ while (i < iLen) {
+ ch = *(pData + i);
+ htmlReserve.Empty();
+ if (HTMLCode2STR(ch, htmlReserve)) {
+ wsResultBuf.AppendChar(L'&');
+ wsResultBuf << htmlReserve;
+ wsResultBuf.AppendChar(L';');
+ } else {
+ if (ch >= 32 && ch <= 126) {
+ wsResultBuf.AppendChar((FX_WCHAR)ch);
+ } else if (ch < 256) {
+ iIndex = ch / 16;
+ strEncode[3] = strCode[iIndex];
+ strEncode[4] = strCode[ch - iIndex * 16];
+ strEncode[5] = ';';
+ strEncode[6] = 0;
+ wsResultBuf << FX_WSTRC(strEncode);
+ } else {
+ FX_INT32 iBigByte = ch / 256;
+ FX_INT32 iLittleByte = ch % 256;
+ strEncode[3] = strCode[iBigByte / 16];
+ strEncode[4] = strCode[iBigByte % 16];
+ strEncode[5] = strCode[iLittleByte / 16];
+ strEncode[6] = strCode[iLittleByte % 16];
+ wsResultBuf << FX_WSTRC(strEncode);
+ }
+ }
+ ++i;
+ }
+ wsResultBuf.AppendChar(0);
+ szResultBuf = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
+}
+void CXFA_FM2JSContext::EncodeXML (FX_BSTR szXMLString, CFX_ByteTextBuf &szResultBuf)
+{
+ CFX_WideString wsXMLString = CFX_WideString::FromUTF8(szXMLString.GetCStr(), szXMLString.GetLength());
+ CFX_WideTextBuf wsResultBuf;
+ enum {
+ QUOT,
+ AMP,
+ APOS,
+ LT,
+ GT,
+ };
+ FX_WCHAR strEncode[9];
+ strEncode[0] = '&';
+ strEncode[1] = '#';
+ strEncode[2] = 'x';
+ strEncode[5] = ';';
+ strEncode[6] = 0;
+ strEncode[7] = ';';
+ strEncode[8] = 0;
+ FX_WCHAR *strName[] = {
+ (FX_WCHAR *)L"quot",
+ (FX_WCHAR *)L"amp",
+ (FX_WCHAR *)L"apos",
+ (FX_WCHAR *)L"lt",
+ (FX_WCHAR *)L"gt"
+ };
+ FX_WCHAR* strCode = (FX_WCHAR *)L"0123456789abcdef";
+ FX_WCHAR ch = 0;
+ FX_INT32 iLength = wsXMLString.GetLength();
+ FX_INT32 iIndex = 0;
+ FX_INT32 u = 0;
+ FX_LPCWSTR pData = wsXMLString;
+ for (u = 0; u < iLength; ++u) {
+ ch = *(pData + u);
+ switch (ch) {
+ case '"':
+ wsResultBuf.AppendChar('&');
+ wsResultBuf << FX_WSTRC(strName[QUOT]);
+ wsResultBuf.AppendChar(';');
+ break;
+ case '&':
+ wsResultBuf.AppendChar('&');
+ wsResultBuf << FX_WSTRC(strName[AMP]);
+ wsResultBuf.AppendChar(';');
+ break;
+ case '\'':
+ wsResultBuf.AppendChar('&');
+ wsResultBuf << FX_WSTRC(strName[APOS]);
+ wsResultBuf.AppendChar(';');
+ break;
+ case '<':
+ wsResultBuf.AppendChar('&');
+ wsResultBuf << FX_WSTRC(strName[LT]);
+ wsResultBuf.AppendChar(';');
+ break;
+ case '>':
+ wsResultBuf.AppendChar('&');
+ wsResultBuf << FX_WSTRC(strName[GT]);
+ wsResultBuf.AppendChar(';');
+ break;
+ default: {
+ if (ch >= 32 && ch <= 126) {
+ wsResultBuf.AppendChar(ch);
+ } else if (ch < 256) {
+ iIndex = ch / 16;
+ strEncode[3] = strCode[iIndex];
+ strEncode[4] = strCode[ch - iIndex * 16];
+ strEncode[5] = ';';
+ strEncode[6] = 0;
+ wsResultBuf << FX_WSTRC(strEncode);
+ } else {
+ FX_INT32 iBigByte = ch / 256;
+ FX_INT32 iLittleByte = ch % 256;
+ strEncode[3] = strCode[iBigByte / 16];
+ strEncode[4] = strCode[iBigByte % 16];
+ strEncode[5] = strCode[iLittleByte / 16];
+ strEncode[6] = strCode[iLittleByte % 16];
+ wsResultBuf << FX_WSTRC(strEncode);
+ }
+ }
+ break;
+ }
+ }
+ wsResultBuf.AppendChar(0);
+ szResultBuf = FX_UTF8Encode(wsResultBuf.GetBuffer(), wsResultBuf.GetLength());
+}
+FX_BOOL CXFA_FM2JSContext::HTMLSTR2Code(FX_WSTR pData, FX_UINT32 &iCode)
+{
+ FX_INT32 iLength = pData.GetLength();
+ FX_UINT32 uHash = FX_HashCode_String_GetW(pData.GetPtr(), iLength);
+ XFA_FMHtmlHashedReserveCode htmlhashedreservecode;
+ FX_INT32 iStart = 0, iEnd = (sizeof(reservesForDecode) / sizeof(reservesForDecode[0])) - 1;
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ htmlhashedreservecode = reservesForDecode[iMid];
+ if (uHash == htmlhashedreservecode.m_uHash) {
+ iCode = htmlhashedreservecode.m_uCode;
+ return TRUE;
+ } else if (uHash < htmlhashedreservecode.m_uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return FALSE;
+}
+FX_BOOL CXFA_FM2JSContext::HTMLCode2STR(FX_UINT32 iCode, CFX_WideString &wsHTMLReserve)
+{
+ XFA_FMHtmlReserveCode htmlreservecode;
+ FX_INT32 iStart = 0, iEnd = (sizeof(reservesForEncode) / sizeof(reservesForEncode[0])) - 1;
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ htmlreservecode = reservesForEncode[iMid];
+ if (iCode == htmlreservecode.m_uCode) {
+ wsHTMLReserve = htmlreservecode.m_htmlReserve;
+ return TRUE;
+ } else if (iCode < htmlreservecode.m_uCode) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return FALSE;
+}
+static FX_BOOL XFA_PATTERN_STRING_Type(FX_BSTR szPattern, FX_DWORD& patternType)
+{
+ CFX_WideString wsPattern = CFX_WideString::FromUTF8(szPattern.GetCStr(), szPattern.GetLength());
+ if (FX_WSTRC(L"datetime") == wsPattern.Left(8)) {
+ patternType = XFA_VT_DATETIME;
+ return TRUE;
+ } else if (FX_WSTRC(L"date") == wsPattern.Left(4)) {
+ patternType = wsPattern.Find(L"time") > 0 ? XFA_VT_DATETIME : XFA_VT_DATE;
+ return TRUE;
+ } else if (FX_WSTRC(L"time") == wsPattern.Left(4)) {
+ patternType = XFA_VT_TIME;
+ return TRUE;
+ } else if (FX_WSTRC(L"text") == wsPattern.Left(4)) {
+ patternType = XFA_VT_TEXT;
+ return TRUE;
+ } else if (FX_WSTRC(L"num") == wsPattern.Left(3)) {
+ if (FX_WSTRC(L"integer") == wsPattern.Mid(4, 7)) {
+ patternType = XFA_VT_INTEGER;
+ } else if (FX_WSTRC(L"decimal") == wsPattern.Mid(4, 7)) {
+ patternType = XFA_VT_DECIMAL;
+ } else if (FX_WSTRC(L"currency") == wsPattern.Mid(4, 8)) {
+ patternType = XFA_VT_FLOAT;
+ } else if (FX_WSTRC(L"percent") == wsPattern.Mid(4, 7)) {
+ patternType = XFA_VT_FLOAT;
+ } else {
+ patternType = XFA_VT_FLOAT;
+ }
+ return TRUE;
+ }
+ patternType = XFA_VT_NULL;
+ wsPattern.MakeLower();
+ FX_LPCWSTR pData = wsPattern;
+ FX_INT32 iLength = wsPattern.GetLength();
+ FX_INT32 iIndex = 0;
+ FX_BOOL bSingleQuotation = FALSE;
+ FX_WCHAR patternChar;
+ while (iIndex < iLength) {
+ patternChar = *(pData + iIndex);
+ if (patternChar == 0x27) {
+ bSingleQuotation = !bSingleQuotation;
+ } else if (!bSingleQuotation && (patternChar == 'y' || patternChar == 'j')) {
+ patternType = XFA_VT_DATE;
+ iIndex++;
+ FX_WCHAR timePatternChar;
+ while (iIndex < iLength) {
+ timePatternChar = *(pData + iIndex);
+ if (timePatternChar == 0x27) {
+ bSingleQuotation = !bSingleQuotation;
+ } else if (!bSingleQuotation && timePatternChar == 't') {
+ patternType = XFA_VT_DATETIME;
+ break;
+ }
+ iIndex++;
+ }
+ break;
+ } else if (!bSingleQuotation && (patternChar == 'h' || patternChar == 'k')) {
+ patternType = XFA_VT_TIME;
+ break;
+ } else if (!bSingleQuotation && (patternChar == 'a' || patternChar == 'x' || patternChar == 'o' || patternChar == '0')) {
+ patternType = XFA_VT_TEXT;
+ if (patternChar == 'x' || patternChar == 'o' || patternChar == '0') {
+ break;
+ }
+ } else if (!bSingleQuotation && (patternChar == 'z' || patternChar == 's' || patternChar == 'e' ||
+ patternChar == 'v' || patternChar == '8' || patternChar == ',' || patternChar == '.' || patternChar == '$')) {
+ patternType = XFA_VT_FLOAT;
+ if (patternChar == 'v' || patternChar == '8' || patternChar == '$' ) {
+ break;
+ }
+ }
+ iIndex++;
+ }
+ if (patternType == XFA_VT_NULL) {
+ patternType = XFA_VT_TEXT | XFA_VT_FLOAT;
+ }
+ return FALSE;
+}
+void CXFA_FM2JSContext::Format(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FX_INT32 argc = args.GetLength();
+ if (argc >= 2) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ CFX_ByteString szPattern;
+ HValueToUTF8String(argOne, szPattern);
+ CFX_ByteString szValue;
+ HValueToUTF8String(argTwo, szValue);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
+ IFX_Locale *pLocale = widgetData.GetLocal();
+ FX_DWORD patternType;
+ FX_BOOL bCompelte = XFA_PATTERN_STRING_Type(szPattern, patternType);
+ CFX_WideString wsPattern = CFX_WideString::FromUTF8(szPattern, szPattern.GetLength());
+ CFX_WideString wsValue = CFX_WideString::FromUTF8(szValue, szValue.GetLength());
+ if (!bCompelte) {
+ switch (patternType) {
+ case XFA_VT_DATETIME: {
+ FX_STRSIZE iTChar = wsPattern.Find(L'T');
+ CFX_WideString wsDatePattern = FX_WSTRC(L"date{");
+ wsDatePattern += wsPattern.Left(iTChar);
+ wsDatePattern += FX_WSTRC(L"} ");
+ CFX_WideString wsTimePattern = FX_WSTRC(L"time{");
+ wsTimePattern += wsPattern.Mid(iTChar + 1);
+ wsTimePattern += FX_WSTRC(L"}");
+ wsPattern = wsDatePattern + wsTimePattern;
+ }
+ break;
+ case XFA_VT_DATE: {
+ wsPattern = FX_WSTRC(L"date{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ }
+ break;
+ case XFA_VT_TIME: {
+ wsPattern = FX_WSTRC(L"time{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ }
+ break;
+ case XFA_VT_TEXT: {
+ wsPattern = FX_WSTRC(L"text{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ }
+ break;
+ case XFA_VT_FLOAT: {
+ wsPattern = FX_WSTRC(L"num{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ }
+ break;
+ default: {
+ CFX_WideString wsTestPattern;
+ wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
+ wsTestPattern += FX_WSTRC(L"}");
+ CXFA_LocaleValue tempLocaleValue(XFA_VT_FLOAT, wsValue, wsTestPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (tempLocaleValue.IsValid()) {
+ wsPattern = wsTestPattern;
+ patternType = XFA_VT_FLOAT;
+ } else {
+ wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
+ wsTestPattern += FX_WSTRC(L"}");
+ wsPattern = wsTestPattern;
+ patternType = XFA_VT_TEXT;
+ }
+ }
+ break;
+ }
+ }
+ CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ CFX_WideString wsRet;
+ if (localeValue.FormatPatterns(wsRet, wsPattern, pLocale, XFA_VALUEPICTURE_Display)) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_UTF8Encode(wsRet, wsRet.GetLength()));
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Format"));
+ }
+}
+void CXFA_FM2JSContext::Left(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FX_BOOL argIsNull = FALSE;
+ if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
+ argIsNull = TRUE;
+ }
+ if (argIsNull) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString sourceString;
+ HValueToUTF8String(argOne, sourceString);
+ FX_INT32 count = HValueToInteger(hThis, argTwo);
+ if (count < 0) {
+ count = 0;
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString.Left(count));
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Left"));
+ }
+}
+void CXFA_FM2JSContext::Len(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString sourceString;
+ HValueToUTF8String(argOne, sourceString);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), sourceString.GetLength());
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Len"));
+ }
+}
+void CXFA_FM2JSContext::Lower(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 3)) {
+ CFX_ByteString argString;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE localeValue = 0;
+ if(HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ if(argc == 2) {
+ localeValue = GetSimpleHValue(hThis, args, 1);
+ }
+ HValueToUTF8String(argOne, argString);
+ CFX_WideTextBuf lowStringBuf;
+ CFX_WideString wsArgString = CFX_WideString::FromUTF8(argString, argString.GetLength());
+ FX_LPCWSTR pData = wsArgString;
+ FX_INT32 iLen = argString.GetLength();
+ FX_INT32 i = 0;
+ FX_INT32 ch = 0;
+ while (i < iLen) {
+ ch = *(pData + i);
+ if (ch >= 0x41 && ch <= 0x5A) {
+ ch += 32;
+ } else if (ch >= 0xC0 && ch <= 0xDE) {
+ ch += 32;
+ } else if (ch == 0x100 || ch == 0x102 || ch == 0x104) {
+ ch += 1;
+ }
+ lowStringBuf.AppendChar(ch);
+ ++i;
+ }
+ lowStringBuf.AppendChar(0);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_UTF8Encode(lowStringBuf.GetBuffer(), lowStringBuf.GetLength()));
+ if(argc == 2) {
+ FXJSE_Value_Release(localeValue);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Lower"));
+ }
+}
+void CXFA_FM2JSContext::Ltrim(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString sourceString;
+ HValueToUTF8String(argOne, sourceString);
+ sourceString.TrimLeft();
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Ltrim"));
+ }
+}
+void CXFA_FM2JSContext::Parse(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ if (HValueIsNull(hThis, argTwo)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString szPattern;
+ HValueToUTF8String(argOne, szPattern);
+ CFX_ByteString szValue;
+ HValueToUTF8String(argTwo, szValue);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ IFX_LocaleMgr *pMgr = (IFX_LocaleMgr *)pDoc->GetLocalMgr();
+ CXFA_Object* pThisNode = pDoc->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThisNode->IsNode());
+ CXFA_WidgetData widgetData((CXFA_Node*)pThisNode);
+ IFX_Locale *pLocale = widgetData.GetLocal();
+ FX_DWORD patternType;
+ FX_BOOL bCompletePattern = XFA_PATTERN_STRING_Type(szPattern, patternType);
+ CFX_WideString wsPattern = CFX_WideString::FromUTF8(szPattern, szPattern.GetLength());
+ CFX_WideString wsValue = CFX_WideString::FromUTF8(szValue, szValue.GetLength());
+ CFX_ByteString szParsedValue;
+ if (bCompletePattern) {
+ CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ } else {
+ switch (patternType) {
+ case XFA_VT_DATETIME: {
+ FX_STRSIZE iTChar = wsPattern.Find(L'T');
+ CFX_WideString wsDatePattern = FX_WSTRC(L"date{");
+ wsDatePattern += wsPattern.Left(iTChar);
+ wsDatePattern += FX_WSTRC(L"} ");
+ CFX_WideString wsTimePattern = FX_WSTRC(L"time{");
+ wsTimePattern += wsPattern.Mid(iTChar + 1);
+ wsTimePattern += FX_WSTRC(L"}");
+ wsPattern = wsDatePattern + wsTimePattern;
+ CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ }
+ break;
+ case XFA_VT_DATE: {
+ wsPattern = FX_WSTRC(L"date{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ }
+ break;
+ case XFA_VT_TIME: {
+ wsPattern = FX_WSTRC(L"time{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ CXFA_LocaleValue localeValue(patternType, wsValue, wsPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ }
+ break;
+ case XFA_VT_TEXT: {
+ wsPattern = FX_WSTRC(L"text{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ }
+ break;
+ case XFA_VT_FLOAT: {
+ wsPattern = FX_WSTRC(L"num{") + wsPattern;
+ wsPattern += FX_WSTRC(L"}");
+ CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), localeValue.GetDoubleNum());
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ }
+ break;
+ default: {
+ CFX_WideString wsTestPattern;
+ wsTestPattern = FX_WSTRC(L"num{") + wsPattern;
+ wsTestPattern += FX_WSTRC(L"}");
+ CXFA_LocaleValue localeValue(XFA_VT_FLOAT, wsValue, wsTestPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), localeValue.GetDoubleNum());
+ } else {
+ wsTestPattern = FX_WSTRC(L"text{") + wsPattern;
+ wsTestPattern += FX_WSTRC(L"}");
+ CXFA_LocaleValue localeValue(XFA_VT_TEXT, wsValue, wsTestPattern, pLocale, (CXFA_LocaleMgr *)pMgr);
+ if (localeValue.IsValid()) {
+ szParsedValue = FX_UTF8Encode(localeValue.GetValue());
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szParsedValue);
+ } else {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Parse"));
+ }
+}
+void CXFA_FM2JSContext::Replace(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc == 2) || (argc == 3)) {
+ FX_BOOL bFlags = FALSE;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE argThree = 0;
+ CFX_ByteString oneString;
+ CFX_ByteString twoString;
+ CFX_ByteString threeString;
+ if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(argOne, oneString);
+ HValueToUTF8String(argTwo, twoString);
+ }
+ if (argc == 3) {
+ argThree = GetSimpleHValue(hThis, args, 2);
+ HValueToUTF8String(argThree, threeString);
+ }
+ FX_INT32 iSrcLen = oneString.GetLength();
+ FX_INT32 iFindLen = twoString.GetLength();
+ CFX_ByteTextBuf resultString;
+ FX_INT32 iFindIndex = 0;
+ FX_BYTE ch = 0;
+ for (FX_INT32 u = 0; u < iSrcLen; ++u) {
+ ch = oneString.GetAt(u);
+ if (ch == twoString.GetAt(iFindIndex)) {
+ FX_INT32 iTemp = u + 1;
+ ++iFindIndex;
+ FX_BYTE chTemp = 0;
+ while (iFindIndex < iFindLen) {
+ chTemp = oneString.GetAt(iTemp);
+ if (chTemp == twoString.GetAt(iFindIndex)) {
+ ++iTemp;
+ ++iFindIndex;
+ } else {
+ iFindIndex = 0;
+ break;
+ }
+ }
+ if (iFindIndex == iFindLen) {
+ resultString << threeString;
+ u += iFindLen - 1;
+ iFindIndex = 0;
+ } else {
+ resultString.AppendChar(ch);
+ }
+ } else {
+ resultString.AppendChar(ch);
+ }
+ }
+ resultString.AppendChar(0);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultString.GetByteString());
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ if(argc == 3) {
+ FXJSE_Value_Release(argThree);
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Replace"));
+ }
+}
+void CXFA_FM2JSContext::Right(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argTwo = GetSimpleHValue(hThis, args, 1);
+ FX_BOOL argIsNull = FALSE;
+ if ((HValueIsNull(hThis, argOne)) || (HValueIsNull(hThis, argTwo))) {
+ argIsNull = TRUE;
+ }
+ if (argIsNull) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString sourceString;
+ HValueToUTF8String(argOne, sourceString);
+ FX_INT32 count = HValueToInteger(hThis, argTwo);
+ if (count < 0) {
+ count = 0;
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString.Right(count));
+ }
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Right"));
+ }
+}
+void CXFA_FM2JSContext::Rtrim(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString sourceString;
+ HValueToUTF8String(argOne, sourceString);
+ sourceString.TrimRight();
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), sourceString);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Rtrim"));
+ }
+}
+void CXFA_FM2JSContext::Space(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if (args.GetLength() == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_INT32 count = 0;
+ count = HValueToInteger(hThis, argOne);
+ count = (count < 0) ? 0 : count;
+ CFX_ByteTextBuf spaceString;
+ FX_INT32 index = 0;
+ while (index < count) {
+ spaceString.AppendByte(' ');
+ index++;
+ }
+ spaceString.AppendByte(0);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), spaceString.GetByteString());
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Space"));
+ }
+}
+void CXFA_FM2JSContext::Str(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT fNumber;
+ FX_INT32 iWidth = 10;
+ FX_INT32 iPrecision = 0;
+ FXJSE_HVALUE numberValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE widthValue = 0;
+ FXJSE_HVALUE precisionValue = 0;
+ if(FXJSE_Value_IsNull(numberValue)) {
+ bFlags = TRUE;
+ } else {
+ fNumber = HValueToFloat(hThis, numberValue);
+ }
+ if(argc > 1) {
+ widthValue = GetSimpleHValue(hThis, args, 1);
+ iWidth = (FX_INT32)HValueToFloat(hThis, widthValue);
+ }
+ if (argc == 3) {
+ precisionValue = GetSimpleHValue(hThis, args, 2);
+ iPrecision = (FX_INT32)HValueToFloat(hThis, precisionValue);
+ if (iPrecision < 0) {
+ iPrecision = 0;
+ }
+ }
+ if (!bFlags) {
+ CFX_ByteString numberString;
+ CFX_ByteString formatStr = "%";
+ if (iPrecision) {
+ formatStr += ".";
+ formatStr += CFX_ByteString::FormatInteger(iPrecision);
+ }
+ formatStr += "f";
+ numberString.Format(formatStr, fNumber);
+ FX_LPCSTR pData = numberString;
+ FX_INT32 iLength = numberString.GetLength();
+ FX_INT32 u = 0;
+ while (u < iLength) {
+ if (*(pData + u) == '.') {
+ break;
+ }
+ ++u;
+ }
+ CFX_ByteTextBuf resultBuf;
+ if (u > iWidth || (iPrecision + u) >= iWidth) {
+ FX_INT32 i = 0;
+ while (i < iWidth) {
+ resultBuf.AppendChar('*');
+ ++i;
+ }
+ resultBuf.AppendChar(0);
+ } else {
+ if (u == iLength) {
+ if (iLength > iWidth) {
+ FX_INT32 i = 0;
+ while (i < iWidth) {
+ resultBuf.AppendChar('*');
+ ++i;
+ }
+ } else {
+ FX_INT32 i = 0;
+ FX_INT32 iSpace = iWidth - iLength;
+ while (i < iSpace) {
+ resultBuf.AppendChar(' ');
+ ++i;
+ }
+ resultBuf << pData;
+ }
+ } else {
+ FX_INT32 iLeavingSpace = 0;
+ if (iPrecision == 0) {
+ iLeavingSpace = iWidth - (u + iPrecision);
+ } else {
+ iLeavingSpace = iWidth - (u + iPrecision + 1);
+ }
+ FX_INT32 i = 0;
+ while (i < iLeavingSpace) {
+ resultBuf.AppendChar(' ');
+ ++i;
+ }
+ i = 0;
+ while (i < u) {
+ resultBuf.AppendChar(*(pData + i));
+ ++i;
+ }
+ if (iPrecision != 0) {
+ resultBuf.AppendChar('.');
+ }
+ u++;
+ i = 0;
+ while (u < iLength) {
+ if (i >= iPrecision) {
+ break;
+ }
+ resultBuf.AppendChar(*(pData + u));
+ ++i;
+ ++u;
+ }
+ while (i < iPrecision) {
+ resultBuf.AppendChar('0');
+ ++i;
+ }
+ resultBuf.AppendChar(0);
+ }
+ }
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.GetByteString());
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ FXJSE_Value_Release(numberValue);
+ if (argc > 1) {
+ FXJSE_Value_Release(widthValue);
+ if (argc == 3) {
+ FXJSE_Value_Release(precisionValue);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Str"));
+ }
+}
+void CXFA_FM2JSContext::Stuff(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc == 3) || (argc == 4)) {
+ FX_BOOL bFlags = FALSE;
+ CFX_ByteString sourceString;
+ CFX_ByteString insertString;
+ FX_INT32 iLength = 0;
+ FX_INT32 iStart = 0;
+ FX_INT32 iDelete = 0;
+ FXJSE_HVALUE sourceValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE startValue = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE deleteValue = GetSimpleHValue(hThis, args, 2);
+ FXJSE_HVALUE insertValue = 0;
+ if ((FXJSE_Value_IsNull(sourceValue)) || (FXJSE_Value_IsNull(startValue)) || (FXJSE_Value_IsNull(deleteValue))) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(sourceValue, sourceString);
+ iLength = sourceString.GetLength();
+ iStart = (FX_INT32)HValueToFloat(hThis, startValue);
+ if (iStart < 1) {
+ iStart = 1;
+ }
+ if (iStart > iLength) {
+ iStart = iLength;
+ }
+ iDelete = (FX_INT32)HValueToFloat(hThis, deleteValue);
+ if (iDelete <= 0) {
+ iDelete = 0;
+ }
+ }
+ if (argc == 4) {
+ insertValue = GetSimpleHValue(hThis, args, 3);
+ HValueToUTF8String(insertValue, insertString);
+ }
+ iStart -= 1;
+ CFX_ByteTextBuf resultString;
+ FX_INT32 i = 0;
+ while (i < iStart) {
+ resultString.AppendChar(sourceString.GetAt(i));
+ ++i;
+ }
+ resultString << insertString;
+ i = iStart + iDelete;
+ while (i < iLength) {
+ resultString.AppendChar(sourceString.GetAt(i));
+ ++i;
+ }
+ resultString.AppendChar(0);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultString.GetByteString());
+ FXJSE_Value_Release(sourceValue);
+ FXJSE_Value_Release(startValue);
+ FXJSE_Value_Release(deleteValue);
+ if (argc == 4) {
+ FXJSE_Value_Release(insertValue);
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Stuff"));
+ }
+}
+void CXFA_FM2JSContext::Substr(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if(argc == 3) {
+ FXJSE_HVALUE stringValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE startValue = GetSimpleHValue(hThis, args, 1);
+ FXJSE_HVALUE endValue = GetSimpleHValue(hThis, args, 2);
+ if (HValueIsNull(hThis, stringValue) || (HValueIsNull(hThis, startValue)) || (HValueIsNull(hThis, endValue))) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ CFX_ByteString szSourceStr;
+ FX_INT32 iStart = 0;
+ FX_INT32 iCount = 0;
+ HValueToUTF8String(stringValue, szSourceStr);
+ FX_INT32 iLength = szSourceStr.GetLength();
+ if (iLength == 0) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ } else {
+ iStart = (FX_INT32)HValueToFloat(hThis, startValue);
+ iCount = (FX_INT32)HValueToFloat(hThis, endValue);
+ if (iStart < 1) {
+ iStart = 1;
+ }
+ if (iStart > iLength) {
+ iStart = iLength;
+ }
+ if (iCount <= 0) {
+ iCount = 0;
+ }
+ iStart -= 1;
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), szSourceStr.Mid(iStart, iCount));
+ }
+ }
+ FXJSE_Value_Release(stringValue);
+ FXJSE_Value_Release(startValue);
+ FXJSE_Value_Release(endValue);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Substr"));
+ }
+}
+void CXFA_FM2JSContext::Uuid(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if((argc == 0) || (argc == 1)) {
+ FX_INT32 iNum = 0;
+ FXJSE_HVALUE argOne = 0;
+ if(argc == 1) {
+ argOne = GetSimpleHValue(hThis, args, 0);
+ iNum = (FX_INT32)HValueToFloat(hThis, argOne);
+ }
+ FX_GUID guid;
+ FX_GUID_CreateV4(&guid);
+ CFX_ByteString bsUId;
+ FX_GUID_ToString(&guid, bsUId, iNum);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), bsUId);
+ if(argc == 1) {
+ FXJSE_Value_Release(argOne);
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Uuid"));
+ }
+}
+void CXFA_FM2JSContext::Upper(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 3)) {
+ CFX_ByteString argString;
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE localeValue = 0;
+ if(HValueIsNull(hThis, argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ if(argc == 2) {
+ localeValue = GetSimpleHValue(hThis, args, 1);
+ }
+ HValueToUTF8String(argOne, argString);
+ CFX_WideTextBuf upperStringBuf;
+ CFX_WideString wsArgString = CFX_WideString::FromUTF8(argString, argString.GetLength());
+ FX_LPCWSTR pData = wsArgString;
+ FX_INT32 iLen = wsArgString.GetLength();
+ FX_INT32 i = 0;
+ FX_INT32 ch = 0;
+ while (i < iLen) {
+ ch = *(pData + i);
+ if (ch >= 0x61 && ch <= 0x7A) {
+ ch -= 32;
+ } else if (ch >= 0xE0 && ch <= 0xFE) {
+ ch -= 32;
+ } else if (ch == 0x101 || ch == 0x103 || ch == 0x105) {
+ ch -= 1;
+ }
+ upperStringBuf.AppendChar(ch);
+ ++i;
+ }
+ upperStringBuf.AppendChar(0);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_UTF8Encode(upperStringBuf.GetBuffer(), upperStringBuf.GetLength()));
+ if(argc == 2) {
+ FXJSE_Value_Release(localeValue);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Upper"));
+ }
+}
+void CXFA_FM2JSContext::WordNum(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 argc = args.GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ FX_BOOL bFlags = FALSE;
+ FX_FLOAT fNumber;
+ FX_INT32 iIdentifier = 0;
+ CFX_ByteString localeString;
+ FXJSE_HVALUE numberValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE identifierValue = 0;
+ FXJSE_HVALUE localeValue = 0;
+ if(FXJSE_Value_IsNull(numberValue)) {
+ bFlags = TRUE;
+ } else {
+ fNumber = HValueToFloat(hThis, numberValue);
+ }
+ if(argc > 1) {
+ identifierValue = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(identifierValue)) {
+ bFlags = TRUE;
+ } else {
+ iIdentifier = (FX_INT32)HValueToFloat(hThis, identifierValue);
+ }
+ }
+ if (argc == 3) {
+ localeValue = GetSimpleHValue(hThis, args, 2);
+ if (FXJSE_Value_IsNull(localeValue)) {
+ bFlags = TRUE;
+ } else {
+ HValueToUTF8String(localeValue, localeString);
+ }
+ }
+ if (!bFlags) {
+ if ((fNumber < 0) || (fNumber > 922337203685477550)) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC("*"));
+ } else {
+ CFX_ByteTextBuf resultBuf;
+ CFX_ByteString numberString;
+ numberString.Format("%.2f", fNumber);
+ WordUS(numberString, iIdentifier, resultBuf);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), resultBuf.GetByteString());
+ }
+ } else {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ }
+ FXJSE_Value_Release(numberValue);
+ if (argc > 1) {
+ FXJSE_Value_Release(identifierValue);
+ if (argc == 3) {
+ FXJSE_Value_Release(localeValue);
+ }
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"WordNum"));
+ }
+}
+void CXFA_FM2JSContext::TrillionUS(FX_BSTR szData, CFX_ByteTextBuf &strBuf)
+{
+ CFX_ByteStringC pUnits[] = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
+ CFX_ByteStringC pCapUnits[] = { "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"};
+ CFX_ByteStringC pTens[] = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
+ CFX_ByteStringC pLastTens[] = {"Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
+ CFX_ByteStringC pComm[] = {" Hundred ", " Thousand ", " Million ", " Billion ", "Trillion"};
+ FX_INT32 iComm = 0;
+ FX_LPCSTR pData = szData.GetCStr();
+ FX_INT32 iLength = szData.GetLength();
+ if (iLength > 12) {
+ iComm = 4;
+ } else if (iLength > 9) {
+ iComm = 3;
+ } else if (iLength > 6) {
+ iComm = 2;
+ } else if (iLength > 3) {
+ iComm = 1;
+ }
+ FX_INT32 iIndex = 0;
+ FX_INT32 iFirstCount = iLength % 3;
+ if (iFirstCount == 0) {
+ iFirstCount = 3;
+ }
+ if (iFirstCount == 3) {
+ if (*(pData + iIndex) != '0') {
+ strBuf << pCapUnits[*(pData + iIndex) - '0'];
+ strBuf << pComm[0];
+ }
+ if (*(pData + iIndex + 1) == '0') {
+ strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+ } else {
+ if (*(pData + iIndex + 1) > '1') {
+ strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
+ strBuf << FX_BSTRC("-");
+ strBuf << pUnits[*(pData + iIndex + 2) - '0'];
+ } else if (*(pData + iIndex + 1) == '1') {
+ strBuf << pTens[*(pData + iIndex + 2) - '0'];
+ } else if (*(pData + iIndex + 1) == '0') {
+ strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+ }
+ }
+ iIndex += 3;
+ } else if (iFirstCount == 2) {
+ if (*(pData + iIndex) == '0') {
+ strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
+ } else {
+ if (*(pData + iIndex) > '1') {
+ strBuf << pLastTens[*(pData + iIndex) - '2'];
+ strBuf << FX_BSTRC("-");
+ strBuf << pUnits[*(pData + iIndex + 1) - '0'];
+ } else if (*(pData + iIndex) == '1') {
+ strBuf << pTens[*(pData + iIndex + 1) - '0'];
+ } else if (*(pData + iIndex) == '0') {
+ strBuf << pCapUnits[*(pData + iIndex + 1) - '0'];
+ }
+ }
+ iIndex += 2;
+ } else if (iFirstCount == 1) {
+ strBuf << pCapUnits[*(pData + iIndex) - '0'];
+ iIndex += 1;
+ }
+ if (iLength > 3 && iFirstCount > 0) {
+ strBuf << pComm[iComm];
+ --iComm;
+ }
+ while (iIndex < iLength) {
+ if (*(pData + iIndex) != '0') {
+ strBuf << pCapUnits[*(pData + iIndex) - '0'];
+ strBuf << pComm[0];
+ }
+ if (*(pData + iIndex + 1) == '0') {
+ strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+ } else {
+ if (*(pData + iIndex + 1) > '1') {
+ strBuf << pLastTens[*(pData + iIndex + 1) - '2'];
+ strBuf << FX_BSTRC("-");
+ strBuf << pUnits[*(pData + iIndex + 2) - '0'];
+ } else if (*(pData + iIndex + 1) == '1') {
+ strBuf << pTens[*(pData + iIndex + 2) - '0'];
+ } else if (*(pData + iIndex + 1) == '0') {
+ strBuf << pCapUnits[*(pData + iIndex + 2) - '0'];
+ }
+ }
+ if (iIndex < iLength - 3) {
+ strBuf << pComm[iComm];
+ --iComm;
+ }
+ iIndex += 3;
+ }
+}
+void CXFA_FM2JSContext::WordUS(FX_BSTR szData, FX_INT32 iStyle, CFX_ByteTextBuf &strBuf)
+{
+ FX_LPCSTR pData = szData.GetCStr();
+ FX_INT32 iLength = szData.GetLength();
+ switch (iStyle) {
+ case 0: {
+ FX_INT32 iIndex = 0;
+ while (iIndex < iLength) {
+ if (*(pData + iIndex) == '.') {
+ break;
+ }
+ ++iIndex;
+ }
+ iLength = iIndex;
+ iIndex = 0;
+ FX_INT32 iCount = 0;
+ while (iIndex < iLength) {
+ iCount = (iLength - iIndex) % 12;
+ if (!iCount && iLength - iIndex > 0) {
+ iCount = 12;
+ }
+ TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+ iIndex += iCount;
+ if (iIndex < iLength) {
+ strBuf << FX_BSTRC(" Trillion ");
+ }
+ }
+ }
+ break;
+ case 1: {
+ FX_INT32 iIndex = 0;
+ while (iIndex < iLength) {
+ if (*(pData + iIndex) == '.') {
+ break;
+ }
+ ++iIndex;
+ }
+ iLength = iIndex;
+ iIndex = 0;
+ FX_INT32 iCount = 0;
+ while (iIndex < iLength) {
+ iCount = (iLength - iIndex) % 12;
+ if (!iCount && iLength - iIndex > 0) {
+ iCount = 12;
+ }
+ TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+ iIndex += iCount;
+ if (iIndex < iLength) {
+ strBuf << FX_BSTRC(" Trillion ");
+ }
+ }
+ strBuf << FX_BSTRC(" Dollars");
+ }
+ break;
+ case 2: {
+ FX_INT32 iIndex = 0;
+ while (iIndex < iLength) {
+ if (*(pData + iIndex) == '.') {
+ break;
+ }
+ ++iIndex;
+ }
+ FX_INT32 iInteger = iIndex;
+ iIndex = 0;
+ FX_INT32 iCount = 0;
+ while (iIndex < iInteger) {
+ iCount = (iInteger - iIndex) % 12;
+ if (!iCount && iLength - iIndex > 0) {
+ iCount = 12;
+ }
+ TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+ iIndex += iCount;
+ if (iIndex < iInteger) {
+ strBuf << FX_BSTRC(" Trillion ");
+ }
+ }
+ strBuf << FX_BSTRC(" Dollars");
+ if (iInteger < iLength) {
+ strBuf << FX_BSTRC(" And ");
+ iIndex = iInteger + 1;
+ FX_INT32 iCount = 0;
+ while (iIndex < iLength) {
+ iCount = (iLength - iIndex) % 12;
+ if (!iCount && iLength - iIndex > 0) {
+ iCount = 12;
+ }
+ TrillionUS(CFX_ByteStringC(pData + iIndex, iCount), strBuf);
+ iIndex += iCount;
+ if (iIndex < iLength) {
+ strBuf << FX_BSTRC(" Trillion ");
+ }
+ }
+ strBuf << FX_BSTRC(" Cents");
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+void CXFA_FM2JSContext::Get(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FX_INT32 argc = args.GetLength();
+ if (argc == 1) {
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return;
+ }
+ IXFA_AppProvider* pAppProvider = pDoc->GetParser()->GetNotify()->GetAppProvider();
+ if(!pAppProvider) {
+ return;
+ }
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ CFX_ByteString urlString;
+ HValueToUTF8String(argOne, urlString);
+ IFX_FileRead* pFile = pAppProvider->DownloadURL(CFX_WideString::FromUTF8(urlString, urlString.GetLength()));
+ if (pFile) {
+ FX_INT32 size = pFile->GetSize();
+ FX_LPBYTE pData = FX_Alloc(FX_BYTE, size);
+ if(pData) {
+ pFile->ReadBlock(pData, size);
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), CFX_ByteStringC(pData, size));
+ FX_Free(pData);
+ }
+ pFile->Release();
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Get"));
+ }
+}
+void CXFA_FM2JSContext::Post(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FX_INT32 argc = args.GetLength();
+ if((argc >= 2) && (argc <= 5)) {
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return;
+ }
+ IXFA_AppProvider* pAppProvider = pDoc->GetParser()->GetNotify()->GetAppProvider();
+ if(!pAppProvider) {
+ return;
+ }
+ CFX_ByteString bsURL;
+ CFX_ByteString bsData;
+ CFX_ByteString bsContentType;
+ CFX_ByteString bsEncode;
+ CFX_ByteString bsHeader;
+ FXJSE_HVALUE argOne;
+ FXJSE_HVALUE argTwo;
+ FXJSE_HVALUE argThree;
+ FXJSE_HVALUE argFour;
+ FXJSE_HVALUE argFive;
+ argOne = GetSimpleHValue(hThis, args, 0);
+ HValueToUTF8String(argOne, bsURL);
+ argTwo = GetSimpleHValue(hThis, args, 1);
+ HValueToUTF8String(argTwo, bsData);
+ if(argc > 2) {
+ argThree = GetSimpleHValue(hThis, args, 2);
+ HValueToUTF8String(argThree, bsContentType);
+ }
+ if(argc > 3) {
+ argFour = GetSimpleHValue(hThis, args, 3);
+ HValueToUTF8String(argFour, bsEncode);
+ }
+ if(argc > 4) {
+ argFive = GetSimpleHValue(hThis, args, 4);
+ HValueToUTF8String(argFive, bsHeader);
+ }
+ CFX_WideString decodedResponse;
+ FX_BOOL bFlags = pAppProvider->PostRequestURL(CFX_WideString::FromUTF8(bsURL, bsURL.GetLength()), CFX_WideString::FromUTF8(bsData, bsData.GetLength()),
+ CFX_WideString::FromUTF8(bsContentType, bsContentType.GetLength()), CFX_WideString::FromUTF8(bsEncode, bsEncode.GetLength()),
+ CFX_WideString::FromUTF8(bsHeader, bsHeader.GetLength()), decodedResponse);
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ if(argc > 2) {
+ FXJSE_Value_Release(argThree);
+ }
+ if(argc > 3) {
+ FXJSE_Value_Release(argFour);
+ }
+ if(argc > 4) {
+ FXJSE_Value_Release(argFive);
+ }
+ if(bFlags) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_UTF8Encode(decodedResponse, decodedResponse.GetLength()));
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_SERVER_DENY);
+ }
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Post"));
+ }
+}
+void CXFA_FM2JSContext::Put(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FX_INT32 argc = args.GetLength();
+ if((argc == 2) || (argc == 3)) {
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return;
+ }
+ IXFA_AppProvider* pAppProvider = pDoc->GetParser()->GetNotify()->GetAppProvider();
+ if(!pAppProvider) {
+ return;
+ }
+ CFX_ByteString bsURL;
+ CFX_ByteString bsData;
+ CFX_ByteString bsEncode;
+ FXJSE_HVALUE argOne;
+ FXJSE_HVALUE argTwo;
+ FXJSE_HVALUE argThree;
+ argOne = GetSimpleHValue(hThis, args, 0);
+ HValueToUTF8String(argOne, bsURL);
+ argTwo = GetSimpleHValue(hThis, args, 1);
+ HValueToUTF8String(argTwo, bsData);
+ if(argc > 2) {
+ argThree = GetSimpleHValue(hThis, args, 2);
+ HValueToUTF8String(argThree, bsEncode);
+ }
+ FX_BOOL bFlags = pAppProvider->PutRequestURL(CFX_WideString::FromUTF8(bsURL, bsURL.GetLength()), CFX_WideString::FromUTF8(bsData, bsData.GetLength()),
+ CFX_WideString::FromUTF8(bsEncode, bsEncode.GetLength()));
+ FXJSE_Value_Release(argOne);
+ FXJSE_Value_Release(argTwo);
+ if(argc > 2) {
+ FXJSE_Value_Release(argThree);
+ }
+ if(bFlags) {
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_BSTRC(""));
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_SERVER_DENY);
+ }
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Put"));
+ }
+}
+void CXFA_FM2JSContext::assign_value_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ if(args.GetLength() == 2 ) {
+ FXJSE_HVALUE lValue = args.GetValue(0);
+ FXJSE_HVALUE rValue = GetSimpleHValue(hThis, args, 1);
+ FX_BOOL bSetStatus = TRUE;
+ if (FXJSE_Value_IsArray(lValue)) {
+ FXJSE_HVALUE leftLengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(lValue, FX_BSTRC("length"), leftLengthValue);
+ FX_INT32 iLeftLength = FXJSE_Value_ToInteger(leftLengthValue);
+ FXJSE_Value_Release(leftLengthValue);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(lValue, 1, propertyValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ for (FX_INT32 i = 2; i < iLeftLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(lValue, i, jsObjectValue);
+ bSetStatus = SetObjectDefaultValue(jsObjectValue, rValue);
+ if (!bSetStatus) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_NOT_DEFAUL_VALUE);
+ break;
+ }
+ }
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ for (FX_INT32 i = 2; i < iLeftLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(lValue, i, jsObjectValue);
+ FXJSE_Value_SetObjectProp(jsObjectValue, propertyStr, rValue);
+ }
+ }
+ FXJSE_Value_Release(jsObjectValue);
+ FXJSE_Value_Release(propertyValue);
+ } else if (FXJSE_Value_IsObject(lValue)) {
+ bSetStatus = SetObjectDefaultValue(lValue, rValue);
+ if (!bSetStatus) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_NOT_DEFAUL_VALUE);
+ }
+ }
+ FXJSE_Value_Set(args.GetReturnValue(), rValue);
+ FXJSE_Value_Release(lValue);
+ FXJSE_Value_Release(rValue);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::logical_or_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_FLOAT first = HValueToFloat(hThis, argFirst);
+ FX_FLOAT second = HValueToFloat(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first || second) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::logical_and_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_FLOAT first = HValueToFloat(hThis, argFirst);
+ FX_FLOAT second = HValueToFloat(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first && second) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::equality_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ if (fm_ref_equal(hThis, args)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 1);
+ } else {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 1 : 0);
+ } else if (FXJSE_Value_IsUTF8String(argFirst) && FXJSE_Value_IsUTF8String(argSecond)) {
+ CFX_ByteString firstOutput;
+ CFX_ByteString secondOutput;
+ FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+ FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), firstOutput.Equal(secondOutput) ? 1 : 0);
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first == second) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::notequality_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ if (fm_ref_equal(hThis, args)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ } else {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 0 : 1);
+ } else if (FXJSE_Value_IsUTF8String(argFirst) && FXJSE_Value_IsUTF8String(argSecond)) {
+ CFX_ByteString firstOutput;
+ CFX_ByteString secondOutput;
+ FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+ FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), firstOutput.Equal(secondOutput) ? 0 : 1);
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first == second) ? 0 : 1);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ }
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+FX_BOOL CXFA_FM2JSContext::fm_ref_equal(FXJSE_HOBJECT hThis, CFXJSE_Arguments &args)
+{
+ FX_BOOL bRet = FALSE;
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FXJSE_HVALUE argFirst = args.GetValue(0);
+ FXJSE_HVALUE argSecond = args.GetValue(0);
+ if (FXJSE_Value_IsArray(argFirst) && FXJSE_Value_IsArray(argSecond)) {
+ FXJSE_HVALUE firstFlagValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE secondFlagValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argFirst, 0, firstFlagValue);
+ FXJSE_Value_GetObjectPropByIdx(argSecond, 0, secondFlagValue);
+ if ((FXJSE_Value_ToInteger(firstFlagValue) == 3) && (FXJSE_Value_ToInteger(secondFlagValue) == 3)) {
+ FXJSE_HVALUE firstJSObject = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE secondJSObject = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argFirst, 2, firstJSObject);
+ FXJSE_Value_GetObjectPropByIdx(argSecond, 2, secondJSObject);
+ if (!FXJSE_Value_IsNull(firstJSObject) && !FXJSE_Value_IsNull(secondJSObject)) {
+ bRet = (FXJSE_Value_ToObject(firstJSObject, NULL) == FXJSE_Value_ToObject(secondJSObject, NULL));
+ }
+ FXJSE_Value_Release(firstJSObject);
+ FXJSE_Value_Release(secondJSObject);
+ }
+ FXJSE_Value_Release(firstFlagValue);
+ FXJSE_Value_Release(secondFlagValue);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ return bRet;
+}
+void CXFA_FM2JSContext::less_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ } else if (FXJSE_Value_IsUTF8String(argFirst) && FXJSE_Value_IsUTF8String(argSecond)) {
+ CFX_ByteString firstOutput;
+ CFX_ByteString secondOutput;
+ FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+ FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (firstOutput.Compare(secondOutput) == -1) ? 1 : 0);
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first < second) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::lessequal_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 1 : 0);
+ } else if (FXJSE_Value_IsUTF8String(argFirst) && FXJSE_Value_IsUTF8String(argSecond)) {
+ CFX_ByteString firstOutput;
+ CFX_ByteString secondOutput;
+ FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+ FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (firstOutput.Compare(secondOutput) != 1) ? 1 : 0);
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first <= second) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::greater_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), 0);
+ } else if (FXJSE_Value_IsUTF8String(argFirst) && FXJSE_Value_IsUTF8String(argSecond)) {
+ CFX_ByteString firstOutput;
+ CFX_ByteString secondOutput;
+ FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+ FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (firstOutput.Compare(secondOutput) == 1) ? 1 : 0);
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first > second) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::greaterequal_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) || FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) ? 1 : 0);
+ } else if (FXJSE_Value_IsUTF8String(argFirst) && FXJSE_Value_IsUTF8String(argSecond)) {
+ CFX_ByteString firstOutput;
+ CFX_ByteString secondOutput;
+ FXJSE_Value_ToUTF8String(argFirst, firstOutput);
+ FXJSE_Value_ToUTF8String(argSecond, secondOutput);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (firstOutput.Compare(secondOutput) != -1) ? 1 : 0);
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first >= second) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::plus_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = args.GetValue(0);
+ FXJSE_HVALUE argSecond = args.GetValue(1);
+ if (HValueIsNull(hThis, argFirst) && HValueIsNull(hThis, argSecond)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetDouble(args.GetReturnValue(), first + second);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::minus_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetDouble(args.GetReturnValue(), first - second);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::multiple_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ FXJSE_Value_SetDouble(args.GetReturnValue(), first * second);
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::divide_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ if (args.GetLength() == 2) {
+ FXJSE_HVALUE argFirst = GetSimpleHValue(hThis, args, 0);
+ FXJSE_HVALUE argSecond = GetSimpleHValue(hThis, args, 1);
+ if (FXJSE_Value_IsNull(argFirst) && FXJSE_Value_IsNull(argSecond)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argFirst);
+ FX_DOUBLE second = HValueToDouble(hThis, argSecond);
+ if (second == 0.0) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_DIVIDE_ZERO);
+ } else {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), first / second);
+ }
+ }
+ FXJSE_Value_Release(argFirst);
+ FXJSE_Value_Release(argSecond);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::positive_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 iLength = args.GetLength();
+ if (iLength == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), 0.0 + HValueToDouble(hThis, argOne));
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::negative_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 iLength = args.GetLength();
+ if (iLength == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FXJSE_Value_SetDouble(args.GetReturnValue(), 0.0 - HValueToDouble(hThis, argOne));
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::logical_not_operator(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 iLength = args.GetLength();
+ if (iLength == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ if (FXJSE_Value_IsNull(argOne)) {
+ FXJSE_Value_SetNull(args.GetReturnValue());
+ } else {
+ FX_DOUBLE first = HValueToDouble(hThis, argOne);
+ FXJSE_Value_SetInteger(args.GetReturnValue(), (first == 0.0) ? 1 : 0);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::dot_accessor(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if((argc == 4) || (argc == 5)) {
+ FX_BOOL bIsStar = TRUE;
+ FXJSE_HVALUE argAccessor = args.GetValue(0);
+ CFX_ByteString bsAccessorName = args.GetUTF8String(1);
+ CFX_ByteString szName = args.GetUTF8String(2);
+ FX_INT32 iIndexFlags = args.GetInt32(3);
+ FX_INT32 iIndexValue = 0;
+ FXJSE_HVALUE argIndex = NULL;
+ if(argc == 5) {
+ bIsStar = FALSE;
+ argIndex = args.GetValue(4);
+ iIndexValue = HValueToInteger(hThis, argIndex);
+ }
+ CFX_ByteString szSomExp;
+ GenerateSomExpression(szName, iIndexFlags, iIndexValue, bIsStar, szSomExp);
+ if(FXJSE_Value_IsArray(argAccessor)) {
+ FXJSE_HVALUE hLengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argAccessor, FX_BSTRC("length"), hLengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(hLengthValue);
+ FXJSE_Value_Release(hLengthValue);
+ FX_INT32 iCounter = 0;
+ FXJSE_HVALUE **hResolveValues = FX_Alloc(FXJSE_HVALUE*, iLength - 2);
+ FX_INT32 *iSizes = FX_Alloc(FX_INT32, iLength - 2);
+ for (FX_INT32 i = 0; i < (iLength - 2); i++) {
+ iSizes[i] = 0;
+ }
+ FXJSE_HVALUE hJSObjValue = FXJSE_Value_Create(hruntime);
+ FX_BOOL bAttribute = FALSE;
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argAccessor, i, hJSObjValue);
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = ResolveObjects(hThis, hJSObjValue, szSomExp, resoveNodeRS, TRUE, szName.IsEmpty());
+ if(iRet > 0) {
+ ParseResolveResult(hThis, resoveNodeRS, hJSObjValue, hResolveValues[i - 2], iSizes[i - 2], bAttribute);
+ iCounter += iSizes[i - 2];
+ }
+ }
+ FXJSE_Value_Release(hJSObjValue);
+ if (iCounter > 0) {
+ FXJSE_HVALUE *rgValues = FX_Alloc(FXJSE_HVALUE, iCounter + 2);
+ for(FX_INT32 i = 0; i < (iCounter + 2); i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 1);
+ if (bAttribute) {
+ FXJSE_Value_SetUTF8String(rgValues[1], szName);
+ } else {
+ FXJSE_Value_SetNull(rgValues[1]);
+ }
+ FX_INT32 iIndex = 2;
+ for(FX_INT32 i = 0; i < iLength - 2; i++) {
+ for(FX_INT32 j = 0; j < iSizes[i]; j++) {
+ FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
+ iIndex++;
+ }
+ }
+ FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
+ for(FX_INT32 i = 0; i < (iCounter + 2); i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ FX_Free(rgValues);
+ } else {
+ CFX_WideString wsPropertyName = CFX_WideString::FromUTF8(szName, szName.GetLength());
+ CFX_WideString wsSomExpression = CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT, (FX_LPCWSTR)wsPropertyName, (FX_LPCWSTR)wsSomExpression);
+ }
+ for(FX_INT32 i = 0; i < iLength - 2; i++) {
+ for(FX_INT32 j = 0; j < iSizes[i]; j++) {
+ FXJSE_Value_Release(hResolveValues[i][j]);
+ }
+ if (iSizes[i] > 0) {
+ FX_Free(hResolveValues[i]);
+ }
+ }
+ FX_Free(hResolveValues);
+ FX_Free(iSizes);
+ } else {
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = 0;
+ if (FXJSE_Value_IsObject(argAccessor) || (FXJSE_Value_IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
+ iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, TRUE, szName.IsEmpty());
+ } else if (!FXJSE_Value_IsObject(argAccessor) && !bsAccessorName.IsEmpty()) {
+ FX_BOOL bGetObject = GetObjectByName(hThis, argAccessor, bsAccessorName);
+ if (bGetObject) {
+ iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, TRUE, szName.IsEmpty());
+ }
+ }
+ if(iRet > 0) {
+ FXJSE_HVALUE *hResolveValues;
+ FX_INT32 iSize = 0;
+ FX_BOOL bAttribute = FALSE;
+ ParseResolveResult(hThis, resoveNodeRS, argAccessor, hResolveValues, iSize, bAttribute);
+ FXJSE_HVALUE *rgValues = FX_Alloc(FXJSE_HVALUE, iSize + 2);
+ for(FX_INT32 i = 0; i < (iSize + 2); i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 1);
+ if (bAttribute) {
+ FXJSE_Value_SetUTF8String(rgValues[1], szName);
+ } else {
+ FXJSE_Value_SetNull(rgValues[1]);
+ }
+ for(FX_INT32 i = 0; i < iSize; i++) {
+ FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
+ }
+ FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
+ for(FX_INT32 i = 0; i < (iSize + 2); i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ FX_Free(rgValues);
+ for(FX_INT32 i = 0; i < iSize; i++) {
+ FXJSE_Value_Release(hResolveValues[i]);
+ }
+ FX_Free(hResolveValues);
+ } else {
+ CFX_WideString wsPropertyName = CFX_WideString::FromUTF8(szName, szName.GetLength());
+ CFX_WideString wsSomExpression = CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT, (FX_LPCWSTR)wsPropertyName, (FX_LPCWSTR)wsSomExpression);
+ }
+ }
+ if(argc == 5) {
+ FXJSE_Value_Release(argIndex);
+ }
+ FXJSE_Value_Release(argAccessor);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::dotdot_accessor(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if((argc == 4) || (argc == 5)) {
+ FX_BOOL bIsStar = TRUE;
+ FXJSE_HVALUE argAccessor = args.GetValue(0);
+ CFX_ByteString bsAccessorName = args.GetUTF8String(1);
+ CFX_ByteString szName = args.GetUTF8String(2);
+ FX_INT32 iIndexFlags = args.GetInt32(3);
+ FX_INT32 iIndexValue = 0;
+ FXJSE_HVALUE argIndex = NULL;
+ if(argc == 5) {
+ bIsStar = FALSE;
+ argIndex = args.GetValue(4);
+ iIndexValue = HValueToInteger(hThis, argIndex);
+ }
+ CFX_ByteString szSomExp;
+ GenerateSomExpression(szName, iIndexFlags, iIndexValue, bIsStar, szSomExp);
+ if(FXJSE_Value_IsArray(argAccessor)) {
+ FXJSE_HVALUE hLengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argAccessor, FX_BSTRC("length"), hLengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(hLengthValue);
+ FX_INT32 iCounter = 0;
+ FXJSE_HVALUE **hResolveValues = FX_Alloc(FXJSE_HVALUE*, iLength - 2);
+ FX_INT32 *iSizes = FX_Alloc(FX_INT32, iLength - 2);
+ FXJSE_HVALUE hJSObjValue = FXJSE_Value_Create(hruntime);
+ FX_BOOL bAttribute = FALSE;
+ for(FX_INT32 i = 2; i < iLength; i++) {
+ FXJSE_Value_GetObjectPropByIdx(argAccessor, i, hJSObjValue);
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = ResolveObjects(hThis, hJSObjValue, szSomExp, resoveNodeRS, FALSE);
+ if(iRet > 0) {
+ ParseResolveResult(hThis, resoveNodeRS, hJSObjValue, hResolveValues[i - 2], iSizes[i - 2], bAttribute);
+ iCounter += iSizes[i - 2];
+ }
+ }
+ FXJSE_Value_Release(hJSObjValue);
+ if (iCounter > 0) {
+ FXJSE_HVALUE *rgValues = FX_Alloc(FXJSE_HVALUE, iCounter + 2);
+ for(FX_INT32 i = 0; i < (iCounter + 2); i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 1);
+ if (bAttribute) {
+ FXJSE_Value_SetUTF8String(rgValues[1], szName);
+ } else {
+ FXJSE_Value_SetNull(rgValues[1]);
+ }
+ FX_INT32 iIndex = 2;
+ for(FX_INT32 i = 0; i < iLength - 2; i++) {
+ for(FX_INT32 j = 0; j < iSizes[i]; j++) {
+ FXJSE_Value_Set(rgValues[iIndex], hResolveValues[i][j]);
+ iIndex++;
+ }
+ }
+ FXJSE_Value_SetArray(args.GetReturnValue(), (iCounter + 2), rgValues);
+ for(FX_INT32 i = 0; i < (iCounter + 2); i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ FX_Free(rgValues);
+ } else {
+ CFX_WideString wsPropertyName = CFX_WideString::FromUTF8(szName, szName.GetLength());
+ CFX_WideString wsSomExpression = CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT, (FX_LPCWSTR)wsPropertyName, (FX_LPCWSTR)wsSomExpression);
+ }
+ for(FX_INT32 i = 0; i < iLength - 2; i++) {
+ for(FX_INT32 j = 0; j < iSizes[i]; j++) {
+ FXJSE_Value_Release(hResolveValues[i][j]);
+ }
+ FX_Free(hResolveValues[i]);
+ }
+ FX_Free(hResolveValues);
+ FX_Free(iSizes);
+ FXJSE_Value_Release(hLengthValue);
+ } else {
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = 0;
+ if (FXJSE_Value_IsObject(argAccessor) || (FXJSE_Value_IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
+ iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, FALSE);
+ } else if (!FXJSE_Value_IsObject(argAccessor) && !bsAccessorName.IsEmpty()) {
+ FX_BOOL bGetObject = GetObjectByName(hThis, argAccessor, bsAccessorName);
+ if (bGetObject) {
+ iRet = ResolveObjects(hThis, argAccessor, szSomExp, resoveNodeRS, FALSE);
+ }
+ }
+ if(iRet > 0) {
+ FXJSE_HVALUE *hResolveValues;
+ FX_INT32 iSize = 0;
+ FX_BOOL bAttribute = FALSE;
+ ParseResolveResult(hThis, resoveNodeRS, argAccessor, hResolveValues, iSize, bAttribute);
+ FXJSE_HVALUE *rgValues = FX_Alloc(FXJSE_HVALUE, iSize + 2);
+ for(FX_INT32 i = 0; i < (iSize + 2); i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 1);
+ if (bAttribute) {
+ FXJSE_Value_SetUTF8String(rgValues[1], szName);
+ } else {
+ FXJSE_Value_SetNull(rgValues[1]);
+ }
+ for(FX_INT32 i = 0; i < iSize; i++) {
+ FXJSE_Value_Set(rgValues[i + 2], hResolveValues[i]);
+ }
+ FXJSE_Value_SetArray(args.GetReturnValue(), (iSize + 2), rgValues);
+ for(FX_INT32 i = 0; i < (iSize + 2); i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ FX_Free(rgValues);
+ for(FX_INT32 i = 0; i < iSize; i++) {
+ FXJSE_Value_Release(hResolveValues[i]);
+ }
+ FX_Free(hResolveValues);
+ } else {
+ CFX_WideString wsPropertyName = CFX_WideString::FromUTF8(szName, szName.GetLength());
+ CFX_WideString wsSomExpression = CFX_WideString::FromUTF8(szSomExp, szSomExp.GetLength());
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ACCESS_PROPERTY_IN_NOT_OBJECT, (FX_LPCWSTR)wsPropertyName, (FX_LPCWSTR)wsSomExpression);
+ }
+ }
+ if(argc == 5) {
+ FXJSE_Value_Release(argIndex);
+ }
+ FXJSE_Value_Release(argAccessor);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::eval_translation (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if (argc == 1) {
+ FXJSE_HVALUE argOne = GetSimpleHValue(hThis, args, 0);
+ CFX_ByteString argString;
+ HValueToUTF8String(argOne, argString);
+ if (argString.IsEmpty()) {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ } else {
+ CFX_WideString scriptString = CFX_WideString::FromUTF8(argString, argString.GetLength());
+ CFX_WideTextBuf wsJavaScriptBuf;
+ CFX_WideString wsError;
+ XFA_FM2JS_Translate(scriptString, wsJavaScriptBuf, wsError);
+ if (wsError.IsEmpty()) {
+ CFX_WideString javaScript = wsJavaScriptBuf.GetWideString();
+ FXJSE_Value_SetUTF8String(args.GetReturnValue(), FX_UTF8Encode(javaScript, javaScript.GetLength()));
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"Eval"));
+ }
+}
+void CXFA_FM2JSContext::is_fm_object(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 iLength = args.GetLength();
+ if (iLength == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ FXJSE_Value_SetBoolean(args.GetReturnValue(), FXJSE_Value_IsObject(argOne));
+ FXJSE_Value_Release(argOne);
+ } else {
+ FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
+ }
+}
+void CXFA_FM2JSContext::is_fm_array(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ FX_INT32 iLength = args.GetLength();
+ if (iLength == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ FX_BOOL bIsArray = FXJSE_Value_IsArray(argOne);
+ FXJSE_Value_SetBoolean(args.GetReturnValue(), bIsArray);
+ FXJSE_Value_Release(argOne);
+ } else {
+ FXJSE_Value_SetBoolean(args.GetReturnValue(), FALSE);
+ }
+}
+void CXFA_FM2JSContext::get_fm_value(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 iLength = args.GetLength();
+ if (iLength == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ if(FXJSE_Value_IsArray(argOne)) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 2, jsobjectValue);
+ if(FXJSE_Value_IsNull(propertyValue)) {
+ GetObjectDefaultValue(jsobjectValue, args.GetReturnValue());
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, args.GetReturnValue());
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsobjectValue);
+ } else if(FXJSE_Value_IsObject(argOne)) {
+ GetObjectDefaultValue(argOne, args.GetReturnValue());
+ } else {
+ FXJSE_Value_Set(args.GetReturnValue(), argOne);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::get_fm_jsobj(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if (argc == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ if(FXJSE_Value_IsArray(argOne)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argOne, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXSYS_assert(iLength >= 3);
+ FXJSE_Value_Release(lengthValue);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 2, args.GetReturnValue());
+ } else {
+ FXJSE_Value_Set(args.GetReturnValue(), argOne);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::fm_var_filter(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 argc = args.GetLength();
+ if (argc == 1) {
+ FXJSE_HVALUE argOne = args.GetValue(0);
+ if(FXJSE_Value_IsArray(argOne)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argOne, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXSYS_assert(iLength >= 3);
+ FXJSE_Value_Release(lengthValue);
+ FXJSE_HVALUE flagsValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 0, flagsValue);
+ FX_INT32 iFlags = FXJSE_Value_ToInteger(flagsValue);
+ FXJSE_Value_Release(flagsValue);
+ if(iFlags == 4) {
+ FXJSE_HVALUE rgValues[3];
+ for(FX_INT32 i = 0; i < 3; i++) {
+ rgValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FXJSE_Value_SetInteger(rgValues[0], 3);
+ FXJSE_Value_SetNull(rgValues[1]);
+ FXJSE_Value_SetNull(rgValues[2]);
+ FXJSE_Value_SetArray(args.GetReturnValue(), 3, rgValues);
+ for(FX_INT32 i = 0; i < 3; i++) {
+ FXJSE_Value_Release(rgValues[i]);
+ }
+ } else if(iFlags == 3) {
+ FXJSE_HVALUE objectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argOne, 2, objectValue);
+ if(!FXJSE_Value_IsNull(objectValue)) {
+ FXJSE_Value_Set(args.GetReturnValue(), argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+ FXJSE_Value_Release(objectValue);
+ } else {
+ FXJSE_HVALUE simpleValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_Value_Set(args.GetReturnValue(), simpleValue);
+ FXJSE_Value_Release(simpleValue);
+ }
+ } else {
+ FXJSE_HVALUE simpleValue = GetSimpleHValue(hThis, args, 0);
+ FXJSE_Value_Set(args.GetReturnValue(), simpleValue);
+ FXJSE_Value_Release(simpleValue);
+ }
+ FXJSE_Value_Release(argOne);
+ } else {
+ pContext->ThrowScriptErrorMessage(XFA_IDS_COMPILER_ERROR);
+ }
+}
+void CXFA_FM2JSContext::concat_fm_object(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_UINT32 iLength = 0;
+ FX_INT32 argCount = args.GetLength();
+ FXJSE_HVALUE *argValues = FX_Alloc(FXJSE_HVALUE, argCount);
+ for(FX_INT32 i = 0; i < argCount; i++) {
+ argValues[i] = args.GetValue(i);
+ if(FXJSE_Value_IsArray(argValues[i])) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argValues[i], FX_BSTRC("length"), lengthValue);
+ FX_INT32 length = FXJSE_Value_ToInteger(lengthValue);
+ iLength = iLength + ((length > 2) ? (length - 2) : 0);
+ FXJSE_Value_Release(lengthValue);
+ }
+ iLength += 1;
+ }
+ FXJSE_HVALUE *returnValues = FX_Alloc(FXJSE_HVALUE, iLength);
+ for(FX_INT32 i = 0; i < (FX_INT32)iLength; i++) {
+ returnValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FX_INT32 index = 0;
+ for(FX_INT32 i = 0; i < argCount; i++) {
+ if(FXJSE_Value_IsArray(argValues[i])) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argValues[i], FX_BSTRC("length"), lengthValue);
+ FX_INT32 length = FXJSE_Value_ToInteger(lengthValue);
+ for(FX_INT32 j = 2; j < length; j++) {
+ FXJSE_Value_GetObjectPropByIdx(argValues[i], j, returnValues[index]);
+ index++;
+ }
+ FXJSE_Value_Release(lengthValue);
+ }
+ FXJSE_Value_Set(returnValues[index], argValues[i]);
+ index++;
+ }
+ FXJSE_Value_SetArray(args.GetReturnValue(), iLength, returnValues);
+ for(FX_INT32 i = 0; i < argCount; i++) {
+ FXJSE_Value_Release(argValues[i]);
+ }
+ FX_Free(argValues);
+ for(FX_INT32 i = 0; i < (FX_INT32)iLength; i++) {
+ FXJSE_Value_Release(returnValues[i]);
+ }
+ FX_Free(returnValues);
+}
+FXJSE_HVALUE CXFA_FM2JSContext::GetSimpleHValue(FXJSE_HOBJECT hThis, CFXJSE_Arguments &args, FX_UINT32 index)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FXSYS_assert(index < (FX_UINT32)args.GetLength());
+ FXJSE_HVALUE argIndex = args.GetValue(index);
+ if (FXJSE_Value_IsArray(argIndex)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argIndex, FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ FXJSE_HVALUE simpleValue = FXJSE_Value_Create(hruntime);
+ if (iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argIndex, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(argIndex, 2, jsobjectValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ GetObjectDefaultValue(jsobjectValue, simpleValue);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, simpleValue);
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsobjectValue);
+ } else {
+ FXJSE_Value_SetUndefined(simpleValue);
+ }
+ FXJSE_Value_Release(argIndex);
+ return simpleValue;
+ } else if (FXJSE_Value_IsObject(argIndex)) {
+ FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(argIndex, defaultValue);
+ FXJSE_Value_Release(argIndex);
+ return defaultValue;
+ } else {
+ return argIndex;
+ }
+}
+FX_BOOL CXFA_FM2JSContext::HValueIsNull(FXJSE_HOBJECT hThis, FXJSE_HVALUE arg)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_BOOL isNull = FALSE;
+ if (FXJSE_Value_IsNull(arg)) {
+ isNull = TRUE;
+ } else if (FXJSE_Value_IsArray(arg)) {
+ FX_INT32 iLength = hvalue_get_array_length(hThis, arg);
+ if (iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(arg, 2, jsObjectValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(jsObjectValue, defaultValue);
+ if (FXJSE_Value_IsNull(defaultValue)) {
+ isNull = TRUE;
+ }
+ FXJSE_Value_Release(defaultValue);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_HVALUE newPropertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyStr, newPropertyValue);
+ if (FXJSE_Value_IsNull(newPropertyValue)) {
+ isNull = TRUE;
+ }
+ FXJSE_Value_Release(newPropertyValue);
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ } else {
+ isNull = TRUE;
+ }
+ } else if (FXJSE_Value_IsObject(arg)) {
+ FXJSE_HVALUE defaultValue = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(arg, defaultValue);
+ if (FXJSE_Value_IsNull(defaultValue)) {
+ isNull = TRUE;
+ }
+ FXJSE_Value_Release(defaultValue);
+ }
+ return isNull;
+}
+FX_INT32 CXFA_FM2JSContext::hvalue_get_array_length(FXJSE_HOBJECT hThis, FXJSE_HVALUE arg)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 iLength = 0;
+ if (FXJSE_Value_IsArray(arg)) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(arg, FX_BSTRC("length"), lengthValue);
+ iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ }
+ return iLength;
+}
+FX_BOOL CXFA_FM2JSContext::simpleValueCompare(FXJSE_HOBJECT hThis, FXJSE_HVALUE firstValue, FXJSE_HVALUE secondValue)
+{
+ FX_BOOL bReturn = FALSE;
+ if(FXJSE_Value_IsUTF8String(firstValue)) {
+ CFX_ByteString firstString, secondString;
+ HValueToUTF8String(firstValue, firstString);
+ HValueToUTF8String(secondValue, secondString);
+ bReturn = firstString.Equal(secondString);
+ } else if (FXJSE_Value_IsNumber(firstValue)) {
+ FX_FLOAT first = HValueToFloat(hThis, firstValue);
+ FX_FLOAT second = HValueToFloat(hThis, secondValue);
+ bReturn = (first == second);
+ } else if (FXJSE_Value_IsBoolean(firstValue)) {
+ bReturn = (FXJSE_Value_ToBoolean(firstValue) == FXJSE_Value_ToBoolean(secondValue));
+ } else if (FXJSE_Value_IsNull(firstValue) && FXJSE_Value_IsNull(secondValue)) {
+ bReturn = TRUE;
+ }
+ return bReturn;
+}
+void CXFA_FM2JSContext::unfoldArgs(FXJSE_HOBJECT hThis, CFXJSE_Arguments &args, FXJSE_HVALUE *&resultValues, FX_INT32 &iCount, FX_INT32 iStart)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ iCount = 0;
+ FX_INT32 argc = args.GetLength();
+ FXJSE_HVALUE *argsValue = FX_Alloc(FXJSE_HVALUE, argc);
+ for (FX_INT32 i = iStart; i < argc; i++) {
+ argsValue[i] = args.GetValue(i);
+ if (FXJSE_Value_IsArray(argsValue[i])) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argsValue[i], FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ iCount += ((iLength > 2) ? (iLength - 2) : 0);
+ } else {
+ iCount += 1;
+ }
+ }
+ resultValues = FX_Alloc(FXJSE_HVALUE, iCount);
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ resultValues[i] = FXJSE_Value_Create(hruntime);
+ }
+ FX_INT32 index = 0;
+ for (FX_INT32 i = iStart; i < argc; i++) {
+ if (FXJSE_Value_IsArray(argsValue[i])) {
+ FXJSE_HVALUE lengthValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectProp(argsValue[i], FX_BSTRC("length"), lengthValue);
+ FX_INT32 iLength = FXJSE_Value_ToInteger(lengthValue);
+ FXJSE_Value_Release(lengthValue);
+ if (iLength > 2) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsObjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(argsValue[i], 1, propertyValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ for (FX_INT32 j = 2; j < iLength; j++) {
+ FXJSE_Value_GetObjectPropByIdx(argsValue[i], j, jsObjectValue);
+ GetObjectDefaultValue(jsObjectValue, resultValues[index]);
+ index++;
+ }
+ } else {
+ CFX_ByteString propertyString;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyString);
+ for (FX_INT32 j = 2; j < iLength; j++) {
+ FXJSE_Value_GetObjectPropByIdx(argsValue[i], j, jsObjectValue);
+ FXJSE_Value_GetObjectProp(jsObjectValue, propertyString, resultValues[index]);
+ index++;
+ }
+ }
+ FXJSE_Value_Release(propertyValue);
+ FXJSE_Value_Release(jsObjectValue);
+ }
+ } else if(FXJSE_Value_IsObject(argsValue[i])) {
+ GetObjectDefaultValue(argsValue[i], resultValues[index]);
+ index++;
+ } else {
+ FXJSE_Value_Set(resultValues[index], argsValue[i]);
+ index++;
+ }
+ }
+ for (FX_INT32 i = iStart; i < argc; i++) {
+ FXJSE_Value_Release(argsValue[i]);
+ }
+ FX_Free(argsValue);
+}
+void CXFA_FM2JSContext::GetObjectDefaultValue(FXJSE_HVALUE hObjectValue, FXJSE_HVALUE hDefaultValue)
+{
+ CXFA_Object* pNode = (CXFA_Object*)FXJSE_Value_ToObject(hObjectValue, NULL);
+ if (pNode && pNode->IsNode()) {
+ ((CXFA_Node*)pNode)->Script_Som_DefaultValue(hDefaultValue, FALSE, (XFA_ATTRIBUTE) - 1);
+ } else {
+ FXJSE_Value_SetNull(hDefaultValue);
+ }
+}
+FX_BOOL CXFA_FM2JSContext::SetObjectDefaultValue(FXJSE_HVALUE hObjectValue, FXJSE_HVALUE hNewValue)
+{
+ FX_BOOL bSuccess = FALSE;
+ CXFA_Object* pNode = (CXFA_Object*)FXJSE_Value_ToObject(hObjectValue, NULL);
+ if (pNode && pNode->IsNode()) {
+ ((CXFA_Node*)pNode)->Script_Som_DefaultValue(hNewValue, TRUE, (XFA_ATTRIBUTE) - 1);
+ bSuccess = TRUE;
+ }
+ return bSuccess;
+}
+void CXFA_FM2JSContext::GenerateSomExpression(FX_BSTR szName, FX_INT32 iIndexFlags, FX_INT32 iIndexValue, FX_BOOL bIsStar, CFX_ByteString& szSomExp)
+{
+ if(bIsStar) {
+ szSomExp = szName + FX_BSTRC("[*]");
+ return;
+ }
+ if(iIndexFlags == 0) {
+ szSomExp = szName;
+ return;
+ }
+ if(iIndexFlags == 1 || iIndexValue == 0) {
+ szSomExp = szName + FX_BSTRC("[") + CFX_ByteString::FormatInteger(iIndexValue, FXFORMAT_SIGNED) + FX_BSTRC("]");
+ } else if(iIndexFlags == 2) {
+ szSomExp = (iIndexValue < 0) ? (szName + FX_BSTRC("[-")) : (szName + FX_BSTRC("[+"));
+ iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
+ szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
+ szSomExp += FX_BSTRC("]");
+ } else {
+ szSomExp = (iIndexValue < 0) ? (szName + FX_BSTRC("[")) : (szName + FX_BSTRC("[-"));
+ iIndexValue = (iIndexValue < 0) ? (0 - iIndexValue) : iIndexValue;
+ szSomExp += CFX_ByteString::FormatInteger(iIndexValue);
+ szSomExp += FX_BSTRC("]");
+ }
+}
+FX_BOOL CXFA_FM2JSContext::GetObjectByName(FXJSE_HOBJECT hThis, FXJSE_HVALUE accessorValue, FX_BSTR szAccessorName)
+{
+ FX_BOOL bFlags = FALSE;
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return bFlags;
+ }
+ IXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_DWORD dwFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
+ FX_INT32 iRet = pScriptContext->ResolveObjects(pScriptContext->GetThisObject(), CFX_WideString::FromUTF8(szAccessorName.GetCStr(), szAccessorName.GetLength()), resoveNodeRS, dwFlags);
+ if (iRet >= 1 && resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+ FXJSE_Value_Set(accessorValue, pScriptContext->GetJSValueFromMap(resoveNodeRS.nodes.GetAt(0)));
+ bFlags = TRUE;
+ }
+ return bFlags;
+}
+FX_INT32 CXFA_FM2JSContext::ResolveObjects(FXJSE_HOBJECT hThis, FXJSE_HVALUE hRefValue, FX_BSTR bsSomExp, XFA_RESOLVENODE_RS &resoveNodeRS, FX_BOOL bdotAccessor , FX_BOOL bHasNoResolveName )
+{
+ CFX_WideString wsSomExpression = CFX_WideString::FromUTF8(bsSomExp.GetCStr(), bsSomExp.GetLength());
+ FX_INT32 iRet = -1;
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ CXFA_Document *pDoc = pContext->GetDocument();
+ if(!pDoc) {
+ return iRet;
+ }
+ IXFA_ScriptContext* pScriptContext = pDoc->GetScriptContext();
+ CXFA_Object *pNode = NULL;
+ FX_DWORD dFlags = 0UL;
+ if (bdotAccessor) {
+ if (FXJSE_Value_IsNull(hRefValue)) {
+ pNode = pScriptContext->GetThisObject();
+ dFlags = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent;
+ } else {
+ pNode = (CXFA_Object *)FXJSE_Value_ToObject(hRefValue, NULL);
+ FXSYS_assert(pNode);
+ if (bHasNoResolveName) {
+ CFX_WideString wsName;
+ if (pNode->IsNode()) {
+ CXFA_Node* pXFANode = (CXFA_Node*)pNode;
+ pXFANode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+ }
+ if (wsName.IsEmpty()) {
+ CFX_WideStringC className;
+ pNode->GetClassName(className);
+ wsName = FX_WSTRC(L"#") + className;
+ }
+ wsSomExpression = wsName + wsSomExpression;
+ dFlags = XFA_RESOLVENODE_Siblings;
+ } else {
+ dFlags = (bsSomExp == "*") ? (XFA_RESOLVENODE_Children) : (XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Properties);
+ }
+ }
+ } else {
+ pNode = (CXFA_Object *)FXJSE_Value_ToObject(hRefValue, NULL);
+ dFlags = XFA_RESOLVENODE_AnyChild;
+ }
+ iRet = pScriptContext->ResolveObjects(pNode, wsSomExpression, resoveNodeRS, dFlags);
+ return iRet;
+}
+void CXFA_FM2JSContext::ParseResolveResult(FXJSE_HOBJECT hThis, const XFA_RESOLVENODE_RS &resoveNodeRS, FXJSE_HVALUE hParentValue, FXJSE_HVALUE *&resultValues, FX_INT32 &iSize, FX_BOOL &bAttribute)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hRuntime = pContext->GetScriptRuntime();
+ iSize = 0;
+ resultValues = NULL;
+ if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+ bAttribute = FALSE;
+ iSize = resoveNodeRS.nodes.GetSize();
+ resultValues = FX_Alloc(FXJSE_HVALUE, iSize);
+ for (FX_INT32 i = 0; i < iSize; i++) {
+ resultValues[i] = FXJSE_Value_Create(hRuntime);
+ FXJSE_Value_Set(resultValues[i], pContext->GetDocument()->GetScriptContext()->GetJSValueFromMap(resoveNodeRS.nodes.GetAt(i)));
+ }
+ } else {
+ CXFA_HVALUEArray objectProperties(hRuntime);
+ FX_INT32 iRet = resoveNodeRS.GetAttributeResult(objectProperties);
+ bAttribute = (iRet == 0);
+ if (bAttribute) {
+ if (FXJSE_Value_IsObject(hParentValue)) {
+ iSize = 1;
+ resultValues = FX_Alloc(FXJSE_HVALUE, 1);
+ resultValues[0] = FXJSE_Value_Create(hRuntime);
+ FXJSE_Value_Set(resultValues[0], hParentValue);
+ }
+ } else {
+ iSize = iRet;
+ resultValues = FX_Alloc(FXJSE_HVALUE, iSize);
+ for (FX_INT32 i = 0; i < iSize; i++) {
+ resultValues[i] = FXJSE_Value_Create(hRuntime);
+ FXJSE_Value_Set(resultValues[i], objectProperties[i]);
+ }
+ }
+ }
+}
+FX_INT32 CXFA_FM2JSContext::HValueToInteger(FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_INT32 iValue = 0;
+ if(FXJSE_Value_IsArray(hValue)) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(hValue, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(hValue, 2, jsobjectValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ GetObjectDefaultValue(jsobjectValue, newProperty);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
+ }
+ iValue = HValueToInteger(hThis, newProperty);
+ FXJSE_Value_Release(newProperty);
+ FXJSE_Value_Release(jsobjectValue);
+ FXJSE_Value_Release(propertyValue);
+ return iValue;
+ } else if(FXJSE_Value_IsObject(hValue)) {
+ FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(hValue, newProperty);
+ iValue = HValueToInteger(hThis, newProperty);
+ FXJSE_Value_Release(newProperty);
+ return iValue;
+ } else if(FXJSE_Value_IsUTF8String(hValue)) {
+ CFX_ByteString szValue;
+ FXJSE_Value_ToUTF8String(hValue, szValue);
+ iValue = FXSYS_atoi(szValue);
+ } else {
+ iValue = FXJSE_Value_ToInteger(hValue);
+ }
+ return iValue;
+}
+FX_DOUBLE CXFA_FM2JSContext::StringToDouble(FX_BSTR szStringVal)
+{
+ return XFA_ByteStringToDouble(szStringVal);
+}
+FX_FLOAT CXFA_FM2JSContext::HValueToFloat(FXJSE_HOBJECT hThis, FXJSE_HVALUE arg)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_FLOAT fRet = 0.0f;
+ if (FXJSE_Value_IsArray(arg)) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(arg, 2, jsobjectValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ GetObjectDefaultValue(jsobjectValue, newProperty);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
+ }
+ fRet = HValueToFloat(hThis, newProperty);
+ FXJSE_Value_Release(newProperty);
+ FXJSE_Value_Release(jsobjectValue);
+ FXJSE_Value_Release(propertyValue);
+ } else if (FXJSE_Value_IsObject(arg)) {
+ FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(arg, newProperty);
+ fRet = HValueToFloat(hThis, newProperty);
+ FXJSE_Value_Release(newProperty);
+ } else if (FXJSE_Value_IsUTF8String(arg)) {
+ CFX_ByteString bsOutput;
+ FXJSE_Value_ToUTF8String(arg, bsOutput);
+ fRet = (FX_FLOAT)StringToDouble(bsOutput);
+ } else if (FXJSE_Value_IsUndefined(arg)) {
+ fRet = 0;
+ } else {
+ fRet = FXJSE_Value_ToFloat(arg);
+ }
+ return fRet;
+}
+FX_DOUBLE CXFA_FM2JSContext::HValueToDouble(FXJSE_HOBJECT hThis, FXJSE_HVALUE arg)
+{
+ CXFA_FM2JSContext* pContext = (CXFA_FM2JSContext*)FXJSE_Value_ToObject(hThis, NULL);
+ FXJSE_HRUNTIME hruntime = pContext->GetScriptRuntime();
+ FX_DOUBLE dRet = 0;
+ if (FXJSE_Value_IsArray(arg)) {
+ FXJSE_HVALUE propertyValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE jsobjectValue = FXJSE_Value_Create(hruntime);
+ FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+ FXJSE_Value_GetObjectPropByIdx(arg, 1, propertyValue);
+ FXJSE_Value_GetObjectPropByIdx(arg, 2, jsobjectValue);
+ if (FXJSE_Value_IsNull(propertyValue)) {
+ GetObjectDefaultValue(jsobjectValue, newProperty);
+ } else {
+ CFX_ByteString propertyStr;
+ FXJSE_Value_ToUTF8String(propertyValue, propertyStr);
+ FXJSE_Value_GetObjectProp(jsobjectValue, propertyStr, newProperty);
+ }
+ dRet = HValueToDouble(hThis, newProperty);
+ FXJSE_Value_Release(newProperty);
+ FXJSE_Value_Release(jsobjectValue);
+ FXJSE_Value_Release(propertyValue);
+ } else if (FXJSE_Value_IsObject(arg)) {
+ FXJSE_HVALUE newProperty = FXJSE_Value_Create(hruntime);
+ GetObjectDefaultValue(arg, newProperty);
+ dRet = HValueToDouble(hThis, newProperty);
+ FXJSE_Value_Release(newProperty);
+ } else if (FXJSE_Value_IsUTF8String(arg)) {
+ CFX_ByteString bsOutput;
+ FXJSE_Value_ToUTF8String(arg, bsOutput);
+ dRet = StringToDouble(bsOutput);
+ } else if (FXJSE_Value_IsUndefined(arg)) {
+ dRet = 0;
+ } else {
+ dRet = FXJSE_Value_ToDouble(arg);
+ }
+ return dRet;
+}
+void CXFA_FM2JSContext::HValueToUTF8String(FXJSE_HVALUE arg, CFX_ByteString& szOutputString)
+{
+ if(FXJSE_Value_IsNull(arg) || FXJSE_Value_IsUndefined(arg)) {
+ szOutputString = "";
+ } else if(FXJSE_Value_IsBoolean(arg)) {
+ szOutputString = FXJSE_Value_ToBoolean(arg) ? "1" : "0";
+ } else {
+ szOutputString = "";
+ FXJSE_Value_ToUTF8String(arg, szOutputString);
+ }
+}
+static FXJSE_FUNCTION formcalc_fm2js_functions[] = {
+ {
+ "Abs",
+ CXFA_FM2JSContext::Abs
+ },
+ {
+ "Avg",
+ CXFA_FM2JSContext::Avg
+ },
+ {
+ "Ceil",
+ CXFA_FM2JSContext::Ceil
+ },
+ {
+ "Count",
+ CXFA_FM2JSContext::Count
+ },
+ {
+ "Floor",
+ CXFA_FM2JSContext::Floor
+ },
+ {
+ "Max",
+ CXFA_FM2JSContext::Max
+ },
+ {
+ "Min",
+ CXFA_FM2JSContext::Min
+ },
+ {
+ "Mod",
+ CXFA_FM2JSContext::Mod
+ },
+ {
+ "Round",
+ CXFA_FM2JSContext::Round
+ },
+ {
+ "Sum",
+ CXFA_FM2JSContext::Sum
+ },
+ {
+ "Date",
+ CXFA_FM2JSContext::Date
+ },
+ {
+ "Date2Num",
+ CXFA_FM2JSContext::Date2Num
+ },
+ {
+ "DateFmt",
+ CXFA_FM2JSContext::DateFmt
+ },
+ {
+ "IsoDate2Num",
+ CXFA_FM2JSContext::IsoDate2Num
+ },
+ {
+ "IsoTime2Num",
+ CXFA_FM2JSContext::IsoTime2Num
+ },
+ {
+ "LocalDateFmt",
+ CXFA_FM2JSContext::LocalDateFmt
+ },
+ {
+ "LocalTimeFmt",
+ CXFA_FM2JSContext::LocalTimeFmt
+ },
+ {
+ "Num2Date",
+ CXFA_FM2JSContext::Num2Date
+ },
+ {
+ "Num2GMTime",
+ CXFA_FM2JSContext::Num2GMTime
+ },
+ {
+ "Num2Time",
+ CXFA_FM2JSContext::Num2Time
+ },
+ {
+ "Time",
+ CXFA_FM2JSContext::Time
+ },
+ {
+ "Time2Num",
+ CXFA_FM2JSContext::Time2Num
+ },
+ {
+ "TimeFmt",
+ CXFA_FM2JSContext::TimeFmt
+ },
+ {
+ "Apr",
+ CXFA_FM2JSContext::Apr
+ },
+ {
+ "Cterm",
+ CXFA_FM2JSContext::CTerm
+ },
+ {
+ "FV",
+ CXFA_FM2JSContext::FV
+ },
+ {
+ "Ipmt",
+ CXFA_FM2JSContext::IPmt
+ },
+ {
+ "NPV",
+ CXFA_FM2JSContext::NPV
+ },
+ {
+ "Pmt",
+ CXFA_FM2JSContext::Pmt
+ },
+ {
+ "PPmt",
+ CXFA_FM2JSContext::PPmt
+ },
+ {
+ "PV",
+ CXFA_FM2JSContext::PV
+ },
+ {
+ "Rate",
+ CXFA_FM2JSContext::Rate
+ },
+ {
+ "Term",
+ CXFA_FM2JSContext::Term
+ },
+ {
+ "Choose",
+ CXFA_FM2JSContext::Choose
+ },
+ {
+ "Exists",
+ CXFA_FM2JSContext::Exists
+ },
+ {
+ "HasValue",
+ CXFA_FM2JSContext::HasValue
+ },
+ {
+ "Oneof",
+ CXFA_FM2JSContext::Oneof
+ },
+ {
+ "Within",
+ CXFA_FM2JSContext::Within
+ },
+ {
+ "If",
+ CXFA_FM2JSContext::If
+ },
+ {
+ "Eval",
+ CXFA_FM2JSContext::Eval
+ },
+ {
+ "Translate",
+ CXFA_FM2JSContext::eval_translation
+ },
+ {
+ "Ref",
+ CXFA_FM2JSContext::Ref
+ },
+ {
+ "UnitType",
+ CXFA_FM2JSContext::UnitType
+ },
+ {
+ "UnitValue",
+ CXFA_FM2JSContext::UnitValue
+ },
+ {
+ "At",
+ CXFA_FM2JSContext::At
+ },
+ {
+ "Concat",
+ CXFA_FM2JSContext::Concat
+ },
+ {
+ "Decode",
+ CXFA_FM2JSContext::Decode
+ },
+ {
+ "Encode",
+ CXFA_FM2JSContext::Encode
+ },
+ {
+ "Format",
+ CXFA_FM2JSContext::Format
+ },
+ {
+ "Left",
+ CXFA_FM2JSContext::Left
+ },
+ {
+ "Len",
+ CXFA_FM2JSContext::Len
+ },
+ {
+ "Lower",
+ CXFA_FM2JSContext::Lower
+ },
+ {
+ "Ltrim",
+ CXFA_FM2JSContext::Ltrim
+ },
+ {
+ "Parse",
+ CXFA_FM2JSContext::Parse
+ },
+ {
+ "Replace",
+ CXFA_FM2JSContext::Replace
+ },
+ {
+ "Right",
+ CXFA_FM2JSContext::Right
+ },
+ {
+ "Rtrim",
+ CXFA_FM2JSContext::Rtrim
+ },
+ {
+ "Space",
+ CXFA_FM2JSContext::Space
+ },
+ {
+ "Str",
+ CXFA_FM2JSContext::Str
+ },
+ {
+ "Stuff",
+ CXFA_FM2JSContext::Stuff
+ },
+ {
+ "Substr",
+ CXFA_FM2JSContext::Substr
+ },
+ {
+ "Uuid",
+ CXFA_FM2JSContext::Uuid
+ },
+ {
+ "Upper",
+ CXFA_FM2JSContext::Upper
+ },
+ {
+ "WordNum",
+ CXFA_FM2JSContext::WordNum
+ },
+ {
+ "Get",
+ CXFA_FM2JSContext::Get
+ },
+ {
+ "Post",
+ CXFA_FM2JSContext::Post
+ },
+ {
+ "Put",
+ CXFA_FM2JSContext::Put
+ },
+ {
+ "positive_operator",
+ CXFA_FM2JSContext::positive_operator
+ },
+ {
+ "negative_operator",
+ CXFA_FM2JSContext::negative_operator
+ },
+ {
+ "logical_or_operator",
+ CXFA_FM2JSContext::logical_or_operator
+ },
+ {
+ "logical_and_operator",
+ CXFA_FM2JSContext::logical_and_operator
+ },
+ {
+ "logical_not_operator",
+ CXFA_FM2JSContext::logical_not_operator
+ },
+ {
+ "equality_operator",
+ CXFA_FM2JSContext::equality_operator
+ },
+ {
+ "notequality_operator",
+ CXFA_FM2JSContext::notequality_operator
+ },
+ {
+ "less_operator",
+ CXFA_FM2JSContext::less_operator
+ },
+ {
+ "lessequal_operator",
+ CXFA_FM2JSContext::lessequal_operator
+ },
+ {
+ "greater_operator",
+ CXFA_FM2JSContext::greater_operator
+ },
+ {
+ "greaterequal_operator",
+ CXFA_FM2JSContext::greaterequal_operator
+ },
+ {
+ "plus_operator",
+ CXFA_FM2JSContext::plus_operator
+ },
+ {
+ "minus_operator",
+ CXFA_FM2JSContext::minus_operator
+ },
+ {
+ "multiple_operator",
+ CXFA_FM2JSContext::multiple_operator
+ },
+ {
+ "divide_operator",
+ CXFA_FM2JSContext::divide_operator
+ },
+ {
+ "assign_value_operator",
+ CXFA_FM2JSContext::assign_value_operator
+ },
+ {
+ "dot_accessor",
+ CXFA_FM2JSContext::dot_accessor
+ },
+ {
+ "dotdot_accessor",
+ CXFA_FM2JSContext::dotdot_accessor
+ },
+ {
+ "concat_fm_object",
+ CXFA_FM2JSContext::concat_fm_object
+ },
+ {
+ "is_fm_object",
+ CXFA_FM2JSContext::is_fm_object
+ },
+ {
+ "is_fm_array",
+ CXFA_FM2JSContext::is_fm_array
+ },
+ {
+ "get_fm_value",
+ CXFA_FM2JSContext::get_fm_value
+ },
+ {
+ "get_fm_jsobj",
+ CXFA_FM2JSContext::get_fm_jsobj
+ },
+ {
+ "fm_var_filter",
+ CXFA_FM2JSContext::fm_var_filter
+ },
+};
+CXFA_FM2JSContext::CXFA_FM2JSContext() :
+ m_pDocument(NULL),
+ m_hFMClass(NULL)
+{
+ FX_memset(&m_fmClass, 0, sizeof(FXJSE_CLASS));
+}
+CXFA_FM2JSContext::~CXFA_FM2JSContext()
+{
+ m_pDocument = NULL;
+ if(m_hValue) {
+ FXJSE_Value_Release(m_hValue);
+ m_hValue = NULL;
+ }
+ m_hScriptRuntime = NULL;
+}
+CXFA_FM2JSContext* CXFA_FM2JSContext::Create()
+{
+ return FX_NEW CXFA_FM2JSContext;
+}
+void CXFA_FM2JSContext::Initialize(FXJSE_HRUNTIME hScriptRuntime, FXJSE_HCONTEXT hScriptContext, CXFA_Document* pDoc)
+{
+ m_pDocument = pDoc;
+ m_hScriptRuntime = hScriptRuntime;
+ m_fmClass.name = "XFA_FM2JS_FormCalcClass";
+ m_fmClass.constructor = NULL;
+ m_fmClass.properties = NULL;
+ m_fmClass.methods = formcalc_fm2js_functions;
+ m_fmClass.propNum = 0;
+ m_fmClass.methNum = sizeof(formcalc_fm2js_functions) / sizeof(formcalc_fm2js_functions[0]);
+ m_hFMClass = FXJSE_DefineClass(hScriptContext, &m_fmClass);
+ m_hValue = FXJSE_Value_Create(hScriptRuntime);
+ FXJSE_Value_SetNull(m_hValue);
+ FXJSE_Value_SetObject(m_hValue, this, m_hFMClass);
+}
+void CXFA_FM2JSContext::GlobalPropertyGetter(FXJSE_HVALUE hValue)
+{
+ FXJSE_Value_Set(hValue, m_hValue);
+}
+void CXFA_FM2JSContext::Release()
+{
+ delete this;
+}
+void CXFA_FM2JSContext::ThrowScriptErrorMessage(FX_INT32 iStringID, ...)
+{
+ IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
+ FXSYS_assert(pAppProvider);
+ CFX_WideString wsFormat;
+ pAppProvider->LoadString(iStringID, wsFormat);
+ CFX_WideString wsMessage;
+ va_list arg_ptr;
+ va_start(arg_ptr, iStringID);
+ wsMessage.FormatV((FX_LPCWSTR)wsFormat, arg_ptr);
+ va_end(arg_ptr);
+ FXJSE_ThrowMessage(FX_BSTRC(""), FX_UTF8Encode(wsMessage, wsMessage.GetLength()));
+}
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.h b/xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.h
new file mode 100644
index 0000000000..95451bbd7b
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_fm2jscontext.h
@@ -0,0 +1,174 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM2JS_CONTEXT_H
+#define _XFA_FM2JS_CONTEXT_H
+class CXFA_FM2JSContext : public CFX_Object
+{
+public:
+ static void Abs (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Avg (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Ceil (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Count (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Floor (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Max (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Min (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Mod (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Round (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Sum (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Date (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Date2Num (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void DateFmt (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void IsoDate2Num (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void IsoTime2Num (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void LocalDateFmt (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void LocalTimeFmt (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Num2Date (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Num2GMTime (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Num2Time (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Time (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Time2Num (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void TimeFmt (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+
+ static FX_BOOL IsIsoDateFormat (FX_LPCSTR pData, FX_INT32 iLength, FX_INT32 &iStyle, FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay);
+ static FX_BOOL IsIsoTimeFormat (FX_LPCSTR pData, FX_INT32 iLength, FX_INT32 &iHour, FX_INT32 &iMinute, FX_INT32 &iSecond, FX_INT32 &iMilliSecond, FX_INT32 &iZoneHour, FX_INT32 &iZoneMinute);
+ static FX_BOOL IsIsoDateTimeFormat (FX_LPCSTR pData, FX_INT32 iLength, FX_INT32 &iYear, FX_INT32 &iMonth, FX_INT32 &iDay, FX_INT32 &iHour, FX_INT32 &iMinute, FX_INT32 &iSecond, FX_INT32 &iMillionSecond, FX_INT32 &iZoneHour, FX_INT32 &iZoneMinute);
+ static FX_BOOL Local2IsoDate (FXJSE_HOBJECT hThis, FX_BSTR szDate, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strIsoDate);
+ static FX_BOOL Local2IsoTime (FXJSE_HOBJECT hThis, FX_BSTR szTime, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strIsoTime);
+ static FX_BOOL IsoDate2Local (FXJSE_HOBJECT hThis, FX_BSTR szDate, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strLocalDate);
+ static FX_BOOL IsoTime2Local (FXJSE_HOBJECT hThis, FX_BSTR szTime, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strLocalTime);
+ static FX_BOOL GetGMTTime (FXJSE_HOBJECT hThis, FX_BSTR szTime, FX_BSTR szFormat, FX_BSTR szLocale, CFX_ByteString &strGMTTime);
+ static FX_INT32 DateString2Num (FX_BSTR szDateString);
+ static void GetLocalDateFormat (FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat, FX_BOOL bStandard);
+ static void GetLocalTimeFormat (FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat, FX_BOOL bStandard);
+ static void GetStandardDateFormat (FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat);
+ static void GetStandardTimeFormat (FXJSE_HOBJECT hThis, FX_INT32 iStyle, FX_BSTR szLocalStr, CFX_ByteString &strFormat);
+
+ static void Num2AllTime (FXJSE_HOBJECT hThis, FX_INT32 iTime, FX_BSTR szFormat, FX_BSTR szLocale, FX_BOOL bGM, CFX_ByteString &strTime);
+ static void GetLocalTimeZone (FX_INT32 &iHour, FX_INT32 &iMin, FX_INT32 &iSec);
+
+ static void Apr (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void CTerm (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void FV (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void IPmt (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void NPV (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Pmt (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void PPmt (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void PV (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Rate (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Term (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Choose (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Exists (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void HasValue (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Oneof (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Within (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void If (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Eval (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Ref (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void UnitType (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void UnitValue (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+
+ static void At (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Concat (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Decode (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void DecodeURL (FX_BSTR szURLString, CFX_ByteTextBuf &szResultBuf);
+ static void DecodeHTML (FX_BSTR szHTMLString, CFX_ByteTextBuf &szResultBuf);
+ static void DecodeXML (FX_BSTR szXMLString, CFX_ByteTextBuf &szResultBuf);
+ static void Encode (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void EncodeURL (FX_BSTR szURLString, CFX_ByteTextBuf &szResultBuf);
+ static void EncodeHTML (FX_BSTR szHTMLString, CFX_ByteTextBuf &szResultBuf);
+ static void EncodeXML (FX_BSTR szXMLString, CFX_ByteTextBuf &szResultBuf);
+ static FX_BOOL HTMLSTR2Code (FX_WSTR pData, FX_UINT32 &iCode);
+ static FX_BOOL HTMLCode2STR (FX_UINT32 iCode, CFX_WideString &wsHTMLReserve);
+ static void Format (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Left (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Len (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Lower (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Ltrim (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Parse (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Replace (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Right (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Rtrim (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Space (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Str (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Stuff (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Substr (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Uuid (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Upper (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void WordNum (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void TrillionUS (FX_BSTR szData, CFX_ByteTextBuf &strBuf);
+ static void WordUS (FX_BSTR szData, FX_INT32 iStyle, CFX_ByteTextBuf &strBuf);
+
+ static void Get (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Post (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void Put (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void assign_value_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void logical_or_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void logical_and_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void equality_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void notequality_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static FX_BOOL fm_ref_equal (FXJSE_HOBJECT hThis, CFXJSE_Arguments &args);
+ static void less_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void lessequal_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void greater_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void greaterequal_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void plus_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void minus_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void multiple_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void divide_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void positive_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void negative_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void logical_not_operator (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void dot_accessor (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void dotdot_accessor (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void eval_translation (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void is_fm_object (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void is_fm_array (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void get_fm_value (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void get_fm_jsobj (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void fm_var_filter (FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static void concat_fm_object(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+
+ static FX_INT32 hvalue_get_array_length (FXJSE_HOBJECT hThis, FXJSE_HVALUE arg);
+ static FX_BOOL simpleValueCompare (FXJSE_HOBJECT hThis, FXJSE_HVALUE firstValue, FXJSE_HVALUE secondValue);
+ static void unfoldArgs (FXJSE_HOBJECT hThis, CFXJSE_Arguments &args, FXJSE_HVALUE *&resultValues, FX_INT32 &iCount, FX_INT32 iStart = 0);
+ static void GetObjectDefaultValue(FXJSE_HVALUE hObjectValue, FXJSE_HVALUE hDefaultValue);
+ static FX_BOOL SetObjectDefaultValue(FXJSE_HVALUE hObjectValue, FXJSE_HVALUE hNewValue);
+ static void GenerateSomExpression(FX_BSTR szName, FX_INT32 iIndexFlags, FX_INT32 iIndexValue, FX_BOOL bIsStar, CFX_ByteString& szSomExp);
+ static FX_BOOL GetObjectByName(FXJSE_HOBJECT hThis, FXJSE_HVALUE accessorValue, FX_BSTR szAccessorName);
+ static FX_INT32 ResolveObjects(FXJSE_HOBJECT hThis, FXJSE_HVALUE hParentValue, FX_BSTR bsSomExp, XFA_RESOLVENODE_RS &resoveNodeRS, FX_BOOL bdotAccessor = TRUE, FX_BOOL bHasNoResolveName = FALSE);
+ static void ParseResolveResult(FXJSE_HOBJECT hThis, const XFA_RESOLVENODE_RS& resoveNodeRS, FXJSE_HVALUE hParentValue, FXJSE_HVALUE *&resultValues, FX_INT32 &iSize, FX_BOOL &bAttribute);
+
+ static FXJSE_HVALUE GetSimpleHValue (FXJSE_HOBJECT hThis, CFXJSE_Arguments &args, FX_UINT32 index);
+ static FX_BOOL HValueIsNull (FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+ static FX_INT32 HValueToInteger (FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+ static FX_DOUBLE StringToDouble(FX_BSTR szStringVal);
+ static FX_FLOAT HValueToFloat (FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+ static FX_DOUBLE HValueToDouble (FXJSE_HOBJECT hThis, FXJSE_HVALUE hValue);
+ static void HValueToUTF8String (FXJSE_HVALUE hValue, CFX_ByteString& outputValue);
+ CXFA_FM2JSContext();
+ ~CXFA_FM2JSContext();
+ static CXFA_FM2JSContext* Create();
+ void Initialize(FXJSE_HRUNTIME hScriptRuntime, FXJSE_HCONTEXT hScriptContext, CXFA_Document* pDoc);
+ void GlobalPropertyGetter(FXJSE_HVALUE hValue);
+ void Release();
+ FXJSE_HRUNTIME GetScriptRuntime() const
+ {
+ return m_hScriptRuntime;
+ }
+ CXFA_Document* GetDocument() const
+ {
+ return m_pDocument;
+ }
+ void ThrowScriptErrorMessage(FX_INT32 iStringID, ...);
+private:
+ FXJSE_HRUNTIME m_hScriptRuntime;
+ FXJSE_CLASS m_fmClass;
+ FXJSE_HCLASS m_hFMClass;
+ FXJSE_HVALUE m_hValue;
+ CXFA_Document* m_pDocument;
+};
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp b/xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp
new file mode 100644
index 0000000000..69de9f29da
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_fmparse.cpp
@@ -0,0 +1,1146 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+CXFA_FMParse::CXFA_FMParse()
+{
+ m_pScript = 0;
+ m_uLength = 0;
+ m_pErrorInfo = 0;
+ m_lexer = 0;
+ m_pToken = 0;
+}
+CXFA_FMParse::~CXFA_FMParse()
+{
+ if (m_lexer) {
+ delete m_lexer;
+ }
+ m_lexer = 0;
+ m_pErrorInfo = 0;
+ m_pScript = 0;
+ m_pToken = 0;
+}
+FX_INT32 CXFA_FMParse::Init(FX_WSTR wsFormcalc, CXFA_FMErrorInfo *pErrorInfo)
+{
+ m_pScript = wsFormcalc.GetPtr();
+ m_uLength = wsFormcalc.GetLength();
+ m_pErrorInfo = pErrorInfo;
+ m_lexer = FX_NEW CXFA_FMLexer(wsFormcalc, m_pErrorInfo);
+ if (m_lexer == 0) {
+ return -1;
+ }
+ return 0;
+}
+void CXFA_FMParse::NextToken()
+{
+ m_pToken = m_lexer->NextToken();
+ while (m_pToken->m_type == TOKreserver) {
+ if (m_lexer->HasError()) {
+ break;
+ }
+ m_pToken = m_lexer->NextToken();
+ }
+}
+void CXFA_FMParse::Check( XFA_FM_TOKEN op )
+{
+ if (m_pToken->m_type != op) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(op), FX_LPCWSTR(ws_TempString));
+ }
+ NextToken();
+}
+void CXFA_FMParse::Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...)
+{
+ m_pErrorInfo->linenum = lineNum;
+ FX_LPCWSTR lpMessageInfo = XFA_FM_ErrorMsg(msg);
+ va_list ap;
+ va_start(ap, msg);
+ m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
+ va_end(ap);
+}
+CFX_PtrArray * CXFA_FMParse::ParseTopExpression()
+{
+ CXFA_FMExpression *e = 0;
+ CFX_PtrArray * expression = FX_NEW CFX_PtrArray();
+ while (1) {
+ if (m_pToken->m_type == TOKeof) {
+ return expression;
+ }
+ if (m_pToken->m_type == TOKendfunc) {
+ return expression;
+ }
+ if (m_pToken->m_type == TOKendif) {
+ return expression;
+ }
+ if (m_pToken->m_type == TOKelseif) {
+ return expression;
+ }
+ if (m_pToken->m_type == TOKelse) {
+ return expression;
+ }
+ if (m_pToken->m_type == TOKfunc) {
+ e = ParseFunction();
+ if (e) {
+ expression->Add(e);
+ } else {
+ break;
+ }
+ } else {
+ e = ParseExpression();
+ if (e) {
+ expression->Add(e);
+ } else {
+ break;
+ }
+ }
+ }
+ return expression;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseFunction()
+{
+ CXFA_FMExpression *e = 0;
+ CFX_WideStringC ident;
+ CFX_WideStringCArray * pArguments = 0;
+ CFX_PtrArray * pExpressions = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, FX_LPCWSTR(ws_TempString));
+ } else {
+ ident = m_pToken->m_wstring;
+ NextToken();
+ }
+ Check(TOKlparen);
+ if (m_pToken->m_type == TOKrparen) {
+ NextToken();
+ } else {
+ pArguments = FX_NEW CFX_WideStringCArray();
+ CFX_WideStringC p;
+ while (1) {
+ if (m_pToken->m_type == TOKidentifier) {
+ p = m_pToken->m_wstring;
+ pArguments->Add(p);
+ NextToken();
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ continue;
+ } else if (m_pToken->m_type == TOKrparen) {
+ NextToken();
+ break;
+ } else {
+ Check(TOKrparen);
+ break;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, FX_LPCWSTR(ws_TempString));
+ NextToken();
+ break;
+ }
+ }
+ }
+ Check(TOKdo);
+ if (m_pToken->m_type == TOKendfunc) {
+ NextToken();
+ } else {
+ pExpressions = ParseTopExpression();
+ Check(TOKendfunc);
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMFunctionDefinition(line, 0, ident, pArguments, pExpressions);
+ } else {
+ FX_INT32 size = 0;
+ FX_INT32 index = 0;
+ if (pArguments) {
+ pArguments->RemoveAll();
+ delete pArguments;
+ pArguments = 0;
+ }
+ index = 0;
+ if (pExpressions) {
+ CXFA_FMExpression *e1 = 0;
+ size = pExpressions->GetSize();
+ while(index < size) {
+ e1 = (CXFA_FMExpression *)pExpressions->GetAt(index);
+ delete e1;
+ index++;
+ }
+ pExpressions->RemoveAll();
+ delete pExpressions;
+ pExpressions = 0;
+ }
+ }
+ return e;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseExpression()
+{
+ CXFA_FMExpression *e = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ switch (m_pToken->m_type) {
+ case TOKvar:
+ e = ParseVarExpression();
+ break;
+ case TOKnull:
+ case TOKnumber:
+ case TOKstring:
+ case TOKplus:
+ case TOKminus:
+ case TOKksnot:
+ case TOKidentifier:
+ case TOKlparen:
+ e = ParseExpExpression();
+ break;
+ case TOKif:
+ e = ParseIfExpression();
+ break;
+ case TOKwhile:
+ e = ParseWhileExpression();
+ break;
+ case TOKfor:
+ e = ParseForExpression();
+ break;
+ case TOKforeach:
+ e = ParseForeachExpression();
+ break;
+ case TOKdo:
+ e = ParseDoExpression();
+ break;
+ case TOKbreak:
+ e = FX_NEW CXFA_FMBreakExpression(line);
+ NextToken();
+ break;
+ case TOKcontinue:
+ e = FX_NEW CXFA_FMContinueExpression(line);
+ NextToken();
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, FX_LPCWSTR(ws_TempString));
+ NextToken();
+ break;
+ }
+ return e;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseVarExpression()
+{
+ CXFA_FMExpression * e = 0;
+ CFX_WideStringC ident;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, FX_LPCWSTR(ws_TempString));
+ } else {
+ ident = m_pToken->m_wstring;
+ NextToken();
+ }
+ if( m_pToken->m_type == TOKassign) {
+ NextToken();
+ e = ParseExpExpression();
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMVarExpression(line, ident, e);
+ } else {
+ delete e;
+ e = 0;
+ }
+ return e;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseSimpleExpression()
+{
+ FX_DWORD line = m_pToken->m_uLinenum;
+ CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
+ pExp1 = ParseLogicalOrExpression();
+ while (m_pToken->m_type == TOKassign) {
+ NextToken();
+ pExp2 = ParseLogicalOrExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp1 = FX_NEW CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);
+ } else {
+ delete pExp1;
+ pExp1 = 0;
+ }
+ }
+ return pExp1;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseExpExpression()
+{
+ CXFA_FMExpression *e = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ CXFA_FMSimpleExpression *pExp1 = 0 ;
+ pExp1 = ParseSimpleExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMExpExpression(line, pExp1);
+ } else {
+ delete pExp1;
+ e = 0;
+ }
+ return e;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseLogicalOrExpression()
+{
+ CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ e1 = ParseLogicalAndExpression();
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKor:
+ case TOKksor:
+ NextToken();
+ e2 = ParseLogicalAndExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMLogicalOrExpression(line, TOKor, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseLogicalAndExpression()
+{
+ CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ e1 = ParseEqualityExpression();
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKand:
+ case TOKksand:
+ NextToken();
+ e2 = ParseEqualityExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMLogicalAndExpression(line, TOKand, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseEqualityExpression()
+{
+ CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ e1 = ParseRelationalExpression();
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKeq:
+ case TOKkseq:
+ NextToken();
+ e2 = ParseRelationalExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMEqualityExpression(line, TOKeq, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ case TOKne:
+ case TOKksne:
+ NextToken();
+ e2 = ParseRelationalExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMEqualityExpression(line, TOKne, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseRelationalExpression()
+{
+ CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ e1 = ParseAddtiveExpression();
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKlt:
+ case TOKkslt:
+ NextToken();
+ e2 = ParseAddtiveExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKlt, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ case TOKgt:
+ case TOKksgt:
+ NextToken();
+ e2 = ParseAddtiveExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKgt, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ case TOKle:
+ case TOKksle:
+ NextToken();
+ e2 = ParseAddtiveExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKle, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ case TOKge:
+ case TOKksge:
+ NextToken();
+ e2 = ParseAddtiveExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMRelationalExpression(line, TOKge, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseAddtiveExpression()
+{
+ CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ e1 = ParseMultiplicativeExpression();
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKplus:
+ NextToken();
+ e2 = ParseMultiplicativeExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMAdditiveExpression(line, TOKplus, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ case TOKminus:
+ NextToken();
+ e2 = ParseMultiplicativeExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMAdditiveExpression(line, TOKminus, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseMultiplicativeExpression()
+{
+ CXFA_FMSimpleExpression *e1 = 0, *e2 = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ e1 = ParseUnaryExpression();
+ for (;;) {
+ switch (m_pToken->m_type) {
+ case TOKmul:
+ NextToken();
+ e2 = ParseUnaryExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMMultiplicativeExpression(line, TOKmul, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ case TOKdiv:
+ NextToken();
+ e2 = ParseUnaryExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e1 = FX_NEW CXFA_FMMultiplicativeExpression(line, TOKdiv, e1, e2);
+ } else {
+ delete e1;
+ e1 = 0;
+ }
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return e1;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseUnaryExpression()
+{
+ CXFA_FMSimpleExpression *e = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ switch (m_pToken->m_type) {
+ case TOKplus:
+ NextToken();
+ e = ParseUnaryExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMPosExpression(line, e);
+ } else {
+ e = 0;
+ }
+ break;
+ case TOKminus:
+ NextToken();
+ e = ParseUnaryExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMNegExpression(line, e);
+ } else {
+ e = 0;
+ }
+ break;
+ case TOKksnot:
+ NextToken();
+ e = ParseUnaryExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMNotExpression(line, e);
+ } else {
+ e = 0;
+ }
+ break;
+ default:
+ e = ParsePrimaryExpression();
+ break;
+ }
+ return e;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParsePrimaryExpression()
+{
+ CXFA_FMSimpleExpression *e = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ switch (m_pToken->m_type) {
+ case TOKnumber:
+ e = FX_NEW CXFA_FMNumberExpression(line, m_pToken->m_wstring);
+ NextToken();
+ break;
+ case TOKstring:
+ e = FX_NEW CXFA_FMStringExpression(line, m_pToken->m_wstring);
+ NextToken();
+ break;
+ case TOKidentifier: {
+ CFX_WideStringC wsIdentifier(m_pToken->m_wstring);
+ NextToken();
+ if (m_pToken->m_type == TOKlbracket) {
+ CXFA_FMSimpleExpression *s = ParseIndexExpression();
+ if(s) {
+ e = FX_NEW CXFA_FMDotAccessorExpression(line, NULL, TOKdot, wsIdentifier, s);
+ }
+ NextToken();
+ } else {
+ e = FX_NEW CXFA_FMIdentifierExpressionn(line, wsIdentifier);
+ }
+ }
+ break;
+ case TOKif:
+ e = FX_NEW CXFA_FMIdentifierExpressionn(line, m_pToken->m_wstring);
+ NextToken();
+ break;
+ case TOKnull:
+ e = FX_NEW CXFA_FMNullExpression(line);
+ NextToken();
+ break;
+ case TOKlparen:
+ e = ParseParenExpression();
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, FX_LPCWSTR(ws_TempString));
+ NextToken();
+ break;
+ }
+ e = ParsePostExpression(e);
+ if (!(m_pErrorInfo->message.IsEmpty())) {
+ delete e;
+ e = 0;
+ }
+ return e;
+}
+CXFA_FMSimpleExpression *CXFA_FMParse::ParsePostExpression(CXFA_FMSimpleExpression *e)
+{
+ FX_DWORD line = m_pToken->m_uLinenum;
+ while (1) {
+ switch (m_pToken->m_type) {
+ case TOKlparen: {
+ NextToken();
+ CFX_PtrArray *pArray = 0;
+ if (m_pToken->m_type != TOKrparen) {
+ pArray = FX_NEW CFX_PtrArray();
+ while (m_pToken->m_type != TOKrparen) {
+ CXFA_FMSimpleExpression *e = ParseSimpleExpression();
+ if (e) {
+ pArray->Add(e);
+ }
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ } else if (m_pToken->m_type == TOKeof) {
+ break;
+ }
+ }
+ if (m_pToken->m_type != TOKrparen) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), FX_LPCWSTR(ws_TempString));
+ }
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMCallExpression(line, e, pArray, FALSE);
+ NextToken();
+ if (m_pToken->m_type != TOKlbracket) {
+ continue;
+ }
+ CXFA_FMSimpleExpression *s = ParseIndexExpression();
+ if(s) {
+ e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKcall, FX_WSTRC(L""), s);
+ } else {
+ delete e;
+ e = 0;
+ }
+ } else {
+ FX_INT32 iSize = pArray->GetSize();
+ for (FX_INT32 i = 0; i < iSize; ++i) {
+ CXFA_FMSimpleExpression *pTemp = (CXFA_FMSimpleExpression *)pArray->GetAt(i);
+ delete pTemp;
+ }
+ delete pArray;
+ delete e;
+ e = 0;
+ }
+ }
+ break;
+ case TOKdot:
+ NextToken();
+ if (m_pToken->m_type == TOKidentifier) {
+ CFX_WideStringC tempStr = m_pToken->m_wstring;
+ FX_DWORD tempLine = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type == TOKlparen) {
+ CXFA_FMSimpleExpression *pExpAccessor;
+ CXFA_FMSimpleExpression *pExpCall;
+ pExpAccessor = e;
+ NextToken();
+ CFX_PtrArray *pArray = 0;
+ if (m_pToken->m_type != TOKrparen) {
+ pArray = FX_NEW CFX_PtrArray();
+ while (m_pToken->m_type != TOKrparen) {
+ CXFA_FMSimpleExpression *exp = ParseSimpleExpression();
+ pArray->Add(exp);
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ } else if (m_pToken->m_type == TOKeof) {
+ break;
+ }
+ }
+ if (m_pToken->m_type != TOKrparen) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), FX_LPCWSTR(ws_TempString));
+ }
+ }
+ if (m_pErrorInfo->message.IsEmpty()) {
+ CXFA_FMSimpleExpression *pIdentifier = FX_NEW CXFA_FMIdentifierExpressionn(tempLine, tempStr);
+ pExpCall = FX_NEW CXFA_FMCallExpression(line, pIdentifier, pArray, TRUE);
+ e = FX_NEW CXFA_FMMethodCallExpression(line, pExpAccessor, pExpCall);
+ NextToken();
+ if (m_pToken->m_type != TOKlbracket) {
+ continue;
+ }
+ CXFA_FMSimpleExpression *s = ParseIndexExpression();
+ if(s) {
+ e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKcall, FX_WSTRC(L""), s);
+ } else {
+ delete e;
+ e = 0;
+ }
+ } else {
+ FX_INT32 iSize = pArray->GetSize();
+ for (FX_INT32 i = 0; i < iSize; ++i) {
+ CXFA_FMSimpleExpression *pTemp = (CXFA_FMSimpleExpression *)pArray->GetAt(i);
+ delete pTemp;
+ }
+ delete pArray;
+ delete e;
+ e = 0;
+ }
+ } else if (m_pToken->m_type == TOKlbracket) {
+ CXFA_FMSimpleExpression *s = ParseIndexExpression();
+ if(!(m_pErrorInfo->message.IsEmpty())) {
+ if (s) {
+ delete s;
+ s = 0;
+ }
+ if (e) {
+ delete e;
+ e = 0;
+ }
+ return e;
+ }
+ e = FX_NEW CXFA_FMDotAccessorExpression(tempLine, e, TOKdot, tempStr, s);
+ } else {
+ CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKdot, tempStr, s);
+ continue;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, FX_LPCWSTR(ws_TempString));
+ return e;
+ }
+ break;
+ case TOKdotdot:
+ NextToken();
+ if (m_pToken->m_type == TOKidentifier) {
+ CFX_WideStringC tempStr = m_pToken->m_wstring;
+ FX_DWORD tempLine = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type == TOKlbracket) {
+ CXFA_FMSimpleExpression *s = ParseIndexExpression();
+ if(!(m_pErrorInfo->message.IsEmpty())) {
+ if (s) {
+ delete s;
+ s = 0;
+ }
+ if (e) {
+ delete e;
+ e = 0;
+ }
+ return e;
+ }
+ e = FX_NEW CXFA_FMDotDotAccessorExpression(tempLine, e, TOKdotdot, tempStr, s);
+ } else {
+ CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = FX_NEW CXFA_FMDotDotAccessorExpression(line, e, TOKdotdot, tempStr, s);
+ continue;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, FX_LPCWSTR(ws_TempString));
+ return e;
+ }
+ break;
+ case TOKdotscream:
+ NextToken();
+ if (m_pToken->m_type == TOKidentifier) {
+ CFX_WideStringC tempStr = m_pToken->m_wstring;
+ FX_DWORD tempLine = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type == TOKlbracket) {
+ CXFA_FMSimpleExpression *s = ParseIndexExpression();
+ if(!(m_pErrorInfo->message.IsEmpty())) {
+ if (s) {
+ delete s;
+ s = 0;
+ }
+ if (e) {
+ delete e;
+ e = 0;
+ }
+ return e;
+ }
+ e = FX_NEW CXFA_FMDotAccessorExpression(tempLine, e, TOKdotscream, tempStr, s);
+ } else {
+ CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(tempLine, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKdotscream, tempStr, s);
+ continue;
+ }
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IDENTIFIER, FX_LPCWSTR(ws_TempString));
+ return e;
+ }
+ break;
+ case TOKdotstar: {
+ CXFA_FMSimpleExpression *s = FX_NEW CXFA_FMIndexExpression(line, ACCESSOR_NO_INDEX, NULL, FALSE);
+ e = FX_NEW CXFA_FMDotAccessorExpression(line, e, TOKdotstar, FX_WSTRC(L"*"), s);
+ }
+ break;
+ default:
+ return e;
+ }
+ NextToken();
+ }
+ return e;
+}
+CXFA_FMSimpleExpression *CXFA_FMParse::ParseIndexExpression()
+{
+ CXFA_FMSimpleExpression *pExp = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ CXFA_FMSimpleExpression *s = 0;
+ XFA_FM_AccessorIndex accessorIndex = ACCESSOR_NO_RELATIVEINDEX;
+ if (m_pToken->m_type == TOKmul) {
+ pExp = FX_NEW CXFA_FMIndexExpression(line, accessorIndex, s, TRUE);
+ NextToken();
+ if (m_pToken->m_type != TOKrbracket) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), FX_LPCWSTR(ws_TempString));
+ if (pExp) {
+ delete pExp;
+ pExp = 0;
+ }
+ }
+ return pExp;
+ }
+ if(m_pToken->m_type == TOKplus) {
+ accessorIndex = ACCESSOR_POSITIVE_INDEX;
+ NextToken();
+ } else if(m_pToken->m_type == TOKminus) {
+ accessorIndex = ACCESSOR_NEGATIVE_INDEX;
+ NextToken();
+ }
+ s = ParseSimpleExpression();
+ if (m_pToken->m_type != TOKrbracket) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(TOKrparen), FX_LPCWSTR(ws_TempString));
+ if (s) {
+ delete s;
+ }
+ } else {
+ pExp = FX_NEW CXFA_FMIndexExpression(line, accessorIndex, s, FALSE);
+ }
+ return pExp;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseParenExpression()
+{
+ CXFA_FMSimpleExpression *pExp1 = 0, *pExp2 = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ Check(TOKlparen);
+ if (m_pToken->m_type != TOKrparen) {
+ pExp1 = ParseLogicalOrExpression();
+ while (m_pToken->m_type == TOKassign) {
+ NextToken();
+ pExp2 = ParseLogicalOrExpression();
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp1 = FX_NEW CXFA_FMAssignExpression(line, TOKassign, pExp1, pExp2);
+ } else {
+ delete pExp1;
+ pExp1 = 0;
+ }
+ }
+ Check(TOKrparen);
+ } else {
+ NextToken();
+ }
+ return pExp1;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseBlockExpression()
+{
+ FX_DWORD line = m_pToken->m_uLinenum;
+ CXFA_FMExpression *e = 0;
+ CFX_PtrArray * expression = FX_NEW CFX_PtrArray();
+ while (1) {
+ switch (m_pToken->m_type) {
+ case TOKeof:
+ case TOKendif:
+ case TOKelseif:
+ case TOKelse:
+ case TOKendwhile:
+ case TOKendfor:
+ case TOKend:
+ case TOKendfunc:
+ break;
+ case TOKfunc:
+ e = ParseFunction();
+ if (e) {
+ expression->Add(e);
+ }
+ continue;
+ default:
+ e = ParseExpression();
+ if (e) {
+ expression->Add(e);
+ }
+ continue;
+ }
+ break;
+ }
+ CXFA_FMBlockExpression *pExp = 0;
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp = FX_NEW CXFA_FMBlockExpression(line, expression);
+ } else {
+ FX_INT32 size = expression->GetSize();
+ FX_INT32 index = 0;
+ while(index < size) {
+ e = (CXFA_FMExpression *)expression->GetAt(index);
+ delete e;
+ index++;
+ }
+ expression->RemoveAll();
+ delete expression;
+ expression = 0;
+ }
+ return pExp;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseIfExpression()
+{
+ CXFA_FMSimpleExpression *pExpression = 0;
+ CXFA_FMExpression *pIfExpression = 0;
+ CXFA_FMExpression *pElseExpression = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ FX_LPCWSTR pStartPos = m_lexer->SavePos();
+ NextToken();
+ Check(TOKlparen);
+ while (m_pToken->m_type != TOKrparen) {
+ if (pExpression) {
+ delete pExpression;
+ }
+ pExpression = ParseSimpleExpression();
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ } else {
+ break;
+ }
+ }
+ Check(TOKrparen);
+ if (m_pToken->m_type != TOKthen) {
+ if (pExpression) {
+ delete pExpression;
+ }
+ m_lexer->SetCurrentLine(line);
+ m_pToken = FX_NEW CXFA_FMToken(line);
+ m_pToken->m_type = TOKidentifier;
+ m_pToken->m_wstring = FX_WSTRC(L"if");
+ m_lexer->SetToken(m_pToken);
+ m_lexer->RestorePos(pStartPos);
+ return ParseExpExpression();
+ }
+ Check(TOKthen);
+ pIfExpression = ParseBlockExpression();
+ switch (m_pToken->m_type) {
+ case TOKeof:
+ case TOKendif:
+ Check(TOKendif);
+ break;
+ case TOKif:
+ pElseExpression = ParseIfExpression();
+ Check(TOKendif);
+ break;
+ case TOKelseif:
+ pElseExpression = ParseIfExpression();
+ break;
+ case TOKelse:
+ NextToken();
+ pElseExpression = ParseBlockExpression();
+ Check(TOKendif);
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_IFEND, FX_LPCWSTR(ws_TempString));
+ NextToken();
+ break;
+ }
+ CXFA_FMIfExpression *pExp = 0;
+ if (m_pErrorInfo->message.IsEmpty()) {
+ pExp = FX_NEW CXFA_FMIfExpression(line, pExpression, pIfExpression, pElseExpression);
+ } else {
+ if (pExpression) {
+ delete pExpression;
+ }
+ if (pIfExpression) {
+ delete pIfExpression;
+ }
+ if (pElseExpression) {
+ delete pElseExpression;
+ }
+ }
+ return pExp;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseWhileExpression()
+{
+ CXFA_FMExpression *e = 0;
+ CXFA_FMSimpleExpression *pCondition = 0;
+ CXFA_FMExpression *pExpression = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ pCondition = ParseParenExpression();
+ Check(TOKdo);
+ pExpression = ParseBlockExpression();
+ Check(TOKendwhile);
+ if (!m_pErrorInfo->message.IsEmpty()) {
+ if (pCondition) {
+ delete pCondition;
+ }
+ if (pExpression) {
+ delete pExpression;
+ }
+ delete e;
+ e = 0;
+ } else {
+ e = FX_NEW CXFA_FMWhileExpression(line, pCondition, pExpression);
+ }
+ return e;
+}
+CXFA_FMSimpleExpression * CXFA_FMParse::ParseSubassignmentInForExpression()
+{
+ CXFA_FMSimpleExpression *e = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ switch (m_pToken->m_type) {
+ case TOKidentifier:
+ e = ParseSimpleExpression();
+ break;
+ default:
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, FX_LPCWSTR(ws_TempString));
+ NextToken();
+ break;
+ }
+ return e;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseForExpression()
+{
+ CXFA_FMExpression *e = 0;
+ CFX_WideStringC wsVariant;
+ CXFA_FMSimpleExpression *pAssignment = 0;
+ CXFA_FMSimpleExpression *pAccessor = 0;
+ CXFA_FMSimpleExpression *pStep = 0;
+ CXFA_FMExpression *pList = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(m_pToken->m_type), FX_LPCWSTR(ws_TempString));
+ }
+ wsVariant = m_pToken->m_wstring;
+ NextToken();
+ if( m_pToken->m_type == TOKassign) {
+ NextToken();
+ pAssignment = ParseSimpleExpression();
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(m_pToken->m_type), FX_LPCWSTR(ws_TempString));
+ }
+ FX_INT32 iDirection = 0;
+ if (m_pToken->m_type == TOKupto) {
+ iDirection = 1;
+ } else if (m_pToken->m_type == TOKdownto) {
+ iDirection = -1;
+ } else {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, (FX_LPCWSTR)(L"upto or downto"), (FX_LPCWSTR)ws_TempString);
+ }
+ NextToken();
+ pAccessor = ParseSimpleExpression();
+ if (m_pToken->m_type == TOKstep) {
+ NextToken();
+ pStep = ParseSimpleExpression();
+ }
+ Check(TOKdo);
+ pList = ParseBlockExpression();
+ Check(TOKendfor);
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMForExpression(line, wsVariant, pAssignment, pAccessor, iDirection, pStep, pList);
+ } else {
+ if (pAssignment) {
+ delete pAssignment;
+ }
+ if (pAccessor) {
+ delete pAccessor;
+ }
+ if (pStep) {
+ delete pStep;
+ }
+ if (pList) {
+ delete pList;
+ }
+ }
+ return e;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseForeachExpression()
+{
+ CXFA_FMExpression *e = 0;
+ CFX_WideStringC wsIdentifier;
+ CFX_PtrArray *pAccessors = 0;
+ CXFA_FMExpression *pList = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ if (m_pToken->m_type != TOKidentifier) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_EXPECTED_TOKEN, XFA_FM_KeywordToString(m_pToken->m_type), FX_LPCWSTR(ws_TempString));
+ }
+ wsIdentifier = m_pToken->m_wstring;
+ NextToken();
+ Check(TOKin);
+ Check(TOKlparen);
+ if (m_pToken->m_type == TOKrparen) {
+ CFX_WideString ws_TempString = m_pToken->m_wstring;
+ Error(m_pToken->m_uLinenum, FMERR_UNEXPECTED_EXPRESSION, FX_LPCWSTR(ws_TempString));
+ NextToken();
+ } else {
+ pAccessors = FX_NEW CFX_PtrArray();
+ while (m_pToken->m_type != TOKrparen) {
+ CXFA_FMSimpleExpression *s = ParseSimpleExpression();
+ if (s) {
+ pAccessors->Add(s);
+ }
+ if (m_pToken->m_type == TOKcomma) {
+ NextToken();
+ } else {
+ break;
+ }
+ }
+ Check(TOKrparen);
+ }
+ Check(TOKdo);
+ pList = ParseBlockExpression();
+ Check(TOKendfor);
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMForeachExpression(line, wsIdentifier, pAccessors, pList);
+ } else {
+ if (pAccessors) {
+ CXFA_FMSimpleExpression *s = 0;
+ FX_INT32 size = pAccessors->GetSize();
+ FX_INT32 index = 0;
+ while(index < size) {
+ s = (CXFA_FMSimpleExpression *)pAccessors->GetAt(index);
+ delete s;
+ index++;
+ }
+ pAccessors->RemoveAll();
+ delete pAccessors;
+ pAccessors = 0;
+ }
+ if (pList) {
+ delete pList;
+ }
+ }
+ return e;
+}
+CXFA_FMExpression * CXFA_FMParse::ParseDoExpression()
+{
+ CXFA_FMExpression *e = 0;
+ FX_DWORD line = m_pToken->m_uLinenum;
+ NextToken();
+ e = ParseBlockExpression();
+ Check(TOKend);
+ if (m_pErrorInfo->message.IsEmpty()) {
+ e = FX_NEW CXFA_FMDoExpression(line, e);
+ } else {
+ delete e;
+ e = 0;
+ }
+ return e;
+}
diff --git a/xfa/src/fxfa/src/fm2js/xfa_fmparse.h b/xfa/src/fxfa/src/fm2js/xfa_fmparse.h
new file mode 100644
index 0000000000..06df65135f
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_fmparse.h
@@ -0,0 +1,49 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM_PARSE_H
+#define _XFA_FM_PARSE_H
+class CXFA_FMParse : public CFX_Object
+{
+public:
+ CXFA_FMParse();
+ ~CXFA_FMParse();
+ FX_INT32 Init(FX_WSTR wsFormcalc, CXFA_FMErrorInfo *pErrorInfo);
+ void NextToken();
+ void Check(XFA_FM_TOKEN op);
+ void Error(FX_DWORD lineNum, XFA_FM_ERRMSG msg, ...);
+ CFX_PtrArray * ParseTopExpression();
+ CXFA_FMExpression *ParseFunction();
+ CXFA_FMExpression *ParseExpression();
+ CXFA_FMExpression *ParseVarExpression();
+ CXFA_FMExpression *ParseExpExpression();
+ CXFA_FMExpression *ParseBlockExpression();
+ CXFA_FMExpression *ParseIfExpression();
+ CXFA_FMExpression *ParseWhileExpression();
+ CXFA_FMExpression *ParseForExpression();
+ CXFA_FMExpression *ParseForeachExpression();
+ CXFA_FMExpression *ParseDoExpression();
+ CXFA_FMSimpleExpression *ParseParenExpression();
+ CXFA_FMSimpleExpression *ParseSimpleExpression();
+ CXFA_FMSimpleExpression *ParseSubassignmentInForExpression();
+ CXFA_FMSimpleExpression *ParseLogicalOrExpression();
+ CXFA_FMSimpleExpression *ParseLogicalAndExpression();
+ CXFA_FMSimpleExpression *ParseEqualityExpression();
+ CXFA_FMSimpleExpression *ParseRelationalExpression();
+ CXFA_FMSimpleExpression *ParseAddtiveExpression();
+ CXFA_FMSimpleExpression *ParseMultiplicativeExpression();
+ CXFA_FMSimpleExpression *ParseUnaryExpression();
+ CXFA_FMSimpleExpression *ParsePrimaryExpression();
+ CXFA_FMSimpleExpression *ParsePostExpression(CXFA_FMSimpleExpression *e);
+ CXFA_FMSimpleExpression *ParseIndexExpression();
+private:
+ FX_LPCWSTR m_pScript;
+ FX_STRSIZE m_uLength;
+ CXFA_FMLexer *m_lexer;
+ CXFA_FMToken *m_pToken;
+ CXFA_FMErrorInfo *m_pErrorInfo;
+};
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp b/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
new file mode 100644
index 0000000000..448d734f3a
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_lexer.cpp
@@ -0,0 +1,589 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+struct XFA_FMDChar {
+ static FX_LPCWSTR inc(FX_LPCWSTR &p)
+ {
+ ++p;
+ return p;
+ }
+ static FX_LPCWSTR dec(FX_LPCWSTR &p)
+ {
+ --p;
+ return p;
+ }
+ static FX_UINT16 get(FX_LPCWSTR p)
+ {
+ return *p;
+ }
+ static FX_BOOL isWhiteSpace(FX_LPCWSTR p)
+ {
+ return (*p) == 0x09 || (*p) == 0x0b || (*p) == 0x0c || (*p) == 0x20;
+ }
+ static FX_BOOL isLineTerminator(FX_LPCWSTR p)
+ {
+ return *p == 0x0A || *p == 0x0D;
+ }
+ static FX_BOOL isBinary(FX_LPCWSTR p)
+ {
+ return (*p) >= '0' && (*p) <= '1';
+ }
+ static FX_BOOL isOctal(FX_LPCWSTR p)
+ {
+ return (*p) >= '0' && (*p) <= '7';
+ }
+ static FX_BOOL isDigital(FX_LPCWSTR p)
+ {
+ return (*p) >= '0' && (*p) <= '9';
+ }
+ static FX_BOOL isHex(FX_LPCWSTR p)
+ {
+ return isDigital(p) || ((*p) >= 'a' && (*p) <= 'f') || ((*p) >= 'A' && (*p) <= 'F');
+ }
+ static FX_BOOL isAlpha(FX_LPCWSTR p)
+ {
+ return ((*p) <= 'z' && (*p) >= 'a') || ((*p) <= 'Z' && (*p) >= 'A');
+ }
+ static FX_BOOL isAvalid(FX_LPCWSTR p, FX_BOOL flag = 0);
+ static FX_BOOL string2number(FX_LPCWSTR s, FX_DOUBLE *pValue, FX_LPCWSTR &pEnd);
+ static FX_BOOL isUnicodeAlpha(FX_UINT16 ch);
+};
+inline FX_BOOL XFA_FMDChar::isAvalid(FX_LPCWSTR p, FX_BOOL flag)
+{
+ if (*p == 0) {
+ return 1;
+ }
+ if ((*p <= 0x0A && *p >= 0x09) || *p == 0x0D || (*p <= 0xd7ff && *p >= 0x20) || (*p <= 0xfffd && *p >= 0xe000)) {
+ return 1;
+ }
+ if (!flag) {
+ if (*p == 0x0B || *p == 0x0C) {
+ return 1;
+ }
+ }
+ return 0;
+}
+inline FX_BOOL XFA_FMDChar::string2number(FX_LPCWSTR s, FX_DOUBLE *pValue, FX_LPCWSTR &pEnd)
+{
+ if (s) {
+ *pValue = wcstod((wchar_t *)s, (wchar_t **)&pEnd);
+ }
+ return 0;
+}
+inline FX_BOOL XFA_FMDChar::isUnicodeAlpha(FX_UINT16 ch)
+{
+ if (ch == 0 || ch == 0x0A || ch == 0x0D || ch == 0x09 || ch == 0x0B || ch == 0x0C || ch == 0x20 || ch == '.'
+ || ch == ';' || ch == '"' || ch == '=' || ch == '<' || ch == '>' || ch == ',' || ch == '(' || ch == ')'
+ || ch == ']' || ch == '[' || ch == '&' || ch == '|' || ch == '+' || ch == '-' || ch == '*' || ch == '/') {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+static XFA_FMKeyword keyWords[] = {
+ {TOKand, 0x00000026, (FX_LPCWSTR)(L"&")},
+ {TOKlparen, 0x00000028, (FX_LPCWSTR)(L"(")},
+ {TOKrparen, 0x00000029, (FX_LPCWSTR)(L")")},
+ {TOKmul, 0x0000002a, (FX_LPCWSTR)(L"*")},
+ {TOKplus, 0x0000002b, (FX_LPCWSTR)(L"+")},
+ {TOKcomma, 0x0000002c, (FX_LPCWSTR)(L",")},
+ {TOKminus, 0x0000002d, (FX_LPCWSTR)(L"-")},
+ {TOKdot, 0x0000002e, (FX_LPCWSTR)(L".")},
+ {TOKdiv, 0x0000002f, (FX_LPCWSTR)(L"/")},
+ {TOKlt, 0x0000003c, (FX_LPCWSTR)(L"<")},
+ {TOKassign, 0x0000003d, (FX_LPCWSTR)(L"=")},
+ {TOKgt, 0x0000003e, (FX_LPCWSTR)(L">")},
+ {TOKlbracket, 0x0000005b, (FX_LPCWSTR)(L"[")},
+ {TOKrbracket, 0x0000005d, (FX_LPCWSTR)(L"]")},
+ {TOKor, 0x0000007c, (FX_LPCWSTR)(L"|")},
+ {TOKdotscream, 0x0000ec11, (FX_LPCWSTR)(L".#")},
+ {TOKdotstar, 0x0000ec18, (FX_LPCWSTR)(L".*")},
+ {TOKdotdot, 0x0000ec1c, (FX_LPCWSTR)(L"..")},
+ {TOKle, 0x000133f9, (FX_LPCWSTR)(L"<=")},
+ {TOKne, 0x000133fa, (FX_LPCWSTR)(L"<>")},
+ {TOKeq, 0x0001391a, (FX_LPCWSTR)(L"==")},
+ {TOKge, 0x00013e3b, (FX_LPCWSTR)(L">=")},
+ {TOKdo, 0x00020153, (FX_LPCWSTR)(L"do")},
+ {TOKkseq, 0x00020676, (FX_LPCWSTR)(L"eq")},
+ {TOKksge, 0x000210ac, (FX_LPCWSTR)(L"ge")},
+ {TOKksgt, 0x000210bb, (FX_LPCWSTR)(L"gt")},
+ {TOKif, 0x00021aef, (FX_LPCWSTR)(L"if")},
+ {TOKin, 0x00021af7, (FX_LPCWSTR)(L"in")},
+ {TOKksle, 0x00022a51, (FX_LPCWSTR)(L"le")},
+ {TOKkslt, 0x00022a60, (FX_LPCWSTR)(L"lt")},
+ {TOKksne, 0x00023493, (FX_LPCWSTR)(L"ne")},
+ {TOKksor, 0x000239c1, (FX_LPCWSTR)(L"or")},
+ {TOKnull, 0x052931bb, (FX_LPCWSTR)(L"null")},
+ {TOKbreak, 0x05518c25, (FX_LPCWSTR)(L"break")},
+ {TOKksand, 0x09f9db33, (FX_LPCWSTR)(L"and")},
+ {TOKend, 0x0a631437, (FX_LPCWSTR)(L"end")},
+ {TOKeof, 0x0a63195a, (FX_LPCWSTR)(L"eof")},
+ {TOKfor, 0x0a7d67a7, (FX_LPCWSTR)(L"for")},
+ {TOKnan, 0x0b4f91dd, (FX_LPCWSTR)(L"nan")},
+ {TOKksnot, 0x0b4fd9b1, (FX_LPCWSTR)(L"not")},
+ {TOKvar, 0x0c2203e9, (FX_LPCWSTR)(L"var")},
+ {TOKthen, 0x2d5738cf, (FX_LPCWSTR)(L"then")},
+ {TOKelse, 0x45f65ee9, (FX_LPCWSTR)(L"else")},
+ {TOKexit, 0x4731d6ba, (FX_LPCWSTR)(L"exit")},
+ {TOKdownto, 0x4caadc3b, (FX_LPCWSTR)(L"downto")},
+ {TOKreturn, 0x4db8bd60, (FX_LPCWSTR)(L"return")},
+ {TOKinfinity, 0x5c0a010a, (FX_LPCWSTR)(L"infinity")},
+ {TOKendwhile, 0x5c64bff0, (FX_LPCWSTR)(L"endwhile")},
+ {TOKforeach, 0x67e31f38, (FX_LPCWSTR)(L"foreach")},
+ {TOKendfunc, 0x68f984a3, (FX_LPCWSTR)(L"endfunc")},
+ {TOKelseif, 0x78253218, (FX_LPCWSTR)(L"elseif")},
+ {TOKwhile, 0x84229259, (FX_LPCWSTR)(L"while")},
+ {TOKendfor, 0x8ab49d7e, (FX_LPCWSTR)(L"endfor")},
+ {TOKthrow, 0x8db05c94, (FX_LPCWSTR)(L"throw")},
+ {TOKstep, 0xa7a7887c, (FX_LPCWSTR)(L"step")},
+ {TOKupto, 0xb5155328, (FX_LPCWSTR)(L"upto")},
+ {TOKcontinue, 0xc0340685, (FX_LPCWSTR)(L"continue")},
+ {TOKfunc, 0xcdce60ec, (FX_LPCWSTR)(L"func")},
+ {TOKendif, 0xe0e8fee6, (FX_LPCWSTR)(L"endif")},
+};
+static const FX_WORD KEYWORD_START = TOKdo;
+static const FX_WORD KEYWORD_END = TOKendif;
+FX_LPCWSTR XFA_FM_KeywordToString(XFA_FM_TOKEN op)
+{
+ return keyWords[op].m_keword;
+}
+CXFA_FMToken::CXFA_FMToken()
+{
+ m_type = TOKreserver;
+ m_uLinenum = 1;
+ m_pNext = 0;
+}
+CXFA_FMToken::CXFA_FMToken( FX_DWORD uLineNum )
+{
+ m_type = TOKreserver;
+ m_uLinenum = uLineNum;
+ m_pNext = 0;
+}
+CXFA_FMToken::~CXFA_FMToken()
+{
+}
+CXFA_FMLexer::CXFA_FMLexer(FX_WSTR wsFormCalc, CXFA_FMErrorInfo *pErrorInfo)
+{
+ m_pScript = wsFormCalc.GetPtr();
+ m_uLength = wsFormCalc.GetLength();
+ m_uCurrentLine = 1;
+ m_ptr = m_pScript;
+ m_pToken = 0;
+ m_pErrorInfo = pErrorInfo;
+}
+CXFA_FMToken *CXFA_FMLexer::NextToken()
+{
+ CXFA_FMToken *t = 0;
+ if (!m_pToken) {
+ m_pToken = Scan();
+ } else {
+ if (m_pToken->m_pNext) {
+ t = m_pToken->m_pNext;
+ delete m_pToken;
+ m_pToken = t;
+ } else {
+ t = m_pToken;
+ m_pToken = Scan();
+ delete t;
+ }
+ }
+ return m_pToken;
+}
+CXFA_FMToken * CXFA_FMLexer::Scan()
+{
+ FX_UINT16 ch = 0;
+ CXFA_FMToken * p = FX_NEW CXFA_FMToken(m_uCurrentLine);
+ if (!XFA_FMDChar::isAvalid(m_ptr)) {
+ ch = XFA_FMDChar::get(m_ptr);
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return p;
+ }
+ int iRet = 0;
+ while (1) {
+ if (!XFA_FMDChar::isAvalid(m_ptr)) {
+ ch = XFA_FMDChar::get(m_ptr);
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return p;
+ }
+ ch = XFA_FMDChar::get(m_ptr);
+ switch (ch) {
+ case 0:
+ p->m_type = TOKeof;
+ return p;
+ case 0x0A:
+ ++m_uCurrentLine;
+ p->m_uLinenum = m_uCurrentLine;
+ XFA_FMDChar::inc(m_ptr);
+ break;
+ case 0x0D:
+ XFA_FMDChar::inc(m_ptr);
+ break;
+ case ';': {
+ FX_LPCWSTR pTemp = 0;
+ Comment(m_ptr, pTemp);
+ m_ptr = pTemp;
+ }
+ break;
+ case '"': {
+ FX_LPCWSTR pTemp = 0;
+ p->m_type = TOKstring;
+ iRet = String(p, m_ptr, pTemp);
+ if (iRet) {
+ return p;
+ }
+ m_ptr = pTemp;
+ }
+ return p;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ p->m_type = TOKnumber;
+ FX_LPCWSTR pTemp = 0;
+ iRet = Number(p, m_ptr, pTemp);
+ m_ptr = pTemp;
+ if (iRet) {
+ Error(FMERR_BAD_SUFFIX_NUMBER);
+ return p;
+ }
+ }
+ return p;
+ case '=':
+ XFA_FMDChar::inc(m_ptr);
+ if (XFA_FMDChar::isAvalid(m_ptr)) {
+ ch = XFA_FMDChar::get(m_ptr);
+ if (ch == '=') {
+ p->m_type = TOKeq;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ } else {
+ p->m_type = TOKassign;
+ return p;
+ }
+ } else {
+ ch = XFA_FMDChar::get(m_ptr);
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return p;
+ }
+ break;
+ case '<':
+ XFA_FMDChar::inc(m_ptr);
+ if (XFA_FMDChar::isAvalid(m_ptr)) {
+ ch = XFA_FMDChar::get(m_ptr);
+ if (ch == '=') {
+ p->m_type = TOKle;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ } else if (ch == '>') {
+ p->m_type = TOKne;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ } else {
+ p->m_type = TOKlt;
+ return p;
+ }
+ } else {
+ ch = XFA_FMDChar::get(m_ptr);
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return p;
+ }
+ break;
+ case '>':
+ XFA_FMDChar::inc(m_ptr);
+ if (XFA_FMDChar::isAvalid(m_ptr)) {
+ ch = XFA_FMDChar::get(m_ptr);
+ if (ch == '=') {
+ p->m_type = TOKge;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ } else {
+ p->m_type = TOKgt;
+ return p;
+ }
+ } else {
+ ch = XFA_FMDChar::get(m_ptr);
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return p;
+ }
+ break;
+ case ',':
+ p->m_type = TOKcomma;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ case '(':
+ p->m_type = TOKlparen;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ case ')':
+ p->m_type = TOKrparen;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ case '[':
+ p->m_type = TOKlbracket;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ case ']':
+ p->m_type = TOKrbracket;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ case '&':
+ XFA_FMDChar::inc(m_ptr);
+ p->m_type = TOKand;
+ return p;
+ case '|':
+ XFA_FMDChar::inc(m_ptr);
+ p->m_type = TOKor;
+ return p;
+ case '+':
+ XFA_FMDChar::inc(m_ptr);
+ p->m_type = TOKplus;
+ return p;
+ case '-':
+ XFA_FMDChar::inc(m_ptr);
+ p->m_type = TOKminus;
+ return p;
+ case '*':
+ XFA_FMDChar::inc(m_ptr);
+ p->m_type = TOKmul;
+ return p;
+ case '/':
+ XFA_FMDChar::inc(m_ptr);
+ if (XFA_FMDChar::isAvalid(m_ptr)) {
+ ch = XFA_FMDChar::get(m_ptr);
+ if (ch == '/') {
+ FX_LPCWSTR pTemp = 0;
+ Comment(m_ptr, pTemp);
+ m_ptr = pTemp;
+ break;
+ } else {
+ p->m_type = TOKdiv;
+ return p;
+ }
+ } else {
+ ch = XFA_FMDChar::get(m_ptr);
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return p;
+ }
+ break;
+ case '.':
+ XFA_FMDChar::inc(m_ptr);
+ if (XFA_FMDChar::isAvalid(m_ptr)) {
+ ch = XFA_FMDChar::get(m_ptr);
+ if (ch == '.') {
+ p->m_type = TOKdotdot;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ } else if (ch == '*') {
+ p->m_type = TOKdotstar;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ } else if (ch == '#') {
+ p->m_type = TOKdotscream;
+ XFA_FMDChar::inc(m_ptr);
+ return p;
+ } else if (ch <= '9' && ch >= '0') {
+ p->m_type = TOKnumber;
+ FX_LPCWSTR pTemp = 0;
+ XFA_FMDChar::dec(m_ptr);
+ iRet = Number(p, m_ptr, pTemp);
+ m_ptr = pTemp;
+ if (iRet) {
+ Error(FMERR_BAD_SUFFIX_NUMBER);
+ }
+ return p;
+ } else {
+ p->m_type = TOKdot;
+ return p;
+ }
+ } else {
+ ch = XFA_FMDChar::get(m_ptr);
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return p;
+ }
+ case 0x09:
+ case 0x0B:
+ case 0x0C:
+ case 0x20:
+ XFA_FMDChar::inc(m_ptr);
+ break;
+ default: {
+ FX_LPCWSTR pTemp = 0;
+ iRet = Identifiers(p, m_ptr, pTemp);
+ m_ptr = pTemp;
+ if (iRet) {
+ return p;
+ }
+ p->m_type = IsKeyword(p->m_wstring);
+ }
+ return p;
+ }
+ }
+}
+FX_DWORD CXFA_FMLexer::Number(CXFA_FMToken *t, FX_LPCWSTR p, FX_LPCWSTR &pEnd)
+{
+ FX_DOUBLE number = 0;
+ if (XFA_FMDChar::string2number(p, &number, pEnd)) {
+ return 1;
+ }
+ if (pEnd && XFA_FMDChar::isAlpha(pEnd)) {
+ return 1;
+ }
+ t->m_wstring = CFX_WideStringC(p, (pEnd - p));
+ return 0;
+}
+FX_DWORD CXFA_FMLexer::String(CXFA_FMToken *t, FX_LPCWSTR p, FX_LPCWSTR &pEnd)
+{
+ FX_LPCWSTR pStart = p;
+ FX_UINT16 ch = 0;
+ XFA_FMDChar::inc(p);
+ ch = XFA_FMDChar::get(p);
+ while (ch) {
+ if (!XFA_FMDChar::isAvalid(p)) {
+ ch = XFA_FMDChar::get(p);
+ pEnd = p;
+ t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return 1;
+ }
+ if (ch == '"') {
+ XFA_FMDChar::inc(p);
+ if (!XFA_FMDChar::isAvalid(p)) {
+ ch = XFA_FMDChar::get(p);
+ pEnd = p;
+ t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return 1;
+ }
+ ch = XFA_FMDChar::get(p);
+ if (ch == '"') {
+ goto NEXT;
+ } else {
+ break;
+ }
+ }
+NEXT:
+ XFA_FMDChar::inc(p);
+ ch = XFA_FMDChar::get(p);
+ }
+ pEnd = p;
+ t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+ return 0;
+}
+FX_DWORD CXFA_FMLexer::Identifiers(CXFA_FMToken *t, FX_LPCWSTR p, FX_LPCWSTR &pEnd)
+{
+ FX_LPCWSTR pStart = p;
+ FX_UINT16 ch = 0;
+ ch = XFA_FMDChar::get(p);
+ XFA_FMDChar::inc(p);
+ if (!XFA_FMDChar::isAvalid(p)) {
+ pEnd = p;
+ t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return 1;
+ }
+ ch = XFA_FMDChar::get(p);
+ while (ch) {
+ if (!XFA_FMDChar::isAvalid(p)) {
+ pEnd = p;
+ t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+ Error(FMERR_UNSUPPORTED_CHAR, ch);
+ return 1;
+ }
+ ch = XFA_FMDChar::get(p);
+ if (XFA_FMDChar::isUnicodeAlpha(ch)) {
+ XFA_FMDChar::inc(p);
+ } else {
+ pEnd = p;
+ t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+ return 0;
+ }
+ }
+ pEnd = p;
+ t->m_wstring = CFX_WideStringC(pStart, (pEnd - pStart));
+ return 0;
+}
+void CXFA_FMLexer::Comment( FX_LPCWSTR p, FX_LPCWSTR &pEnd )
+{
+ unsigned ch = 0;
+ XFA_FMDChar::inc(p);
+ ch = XFA_FMDChar::get(p);
+ while (ch) {
+ if (ch == 0x0D) {
+ XFA_FMDChar::inc(p);
+ pEnd = p;
+ return;
+ }
+ if (ch == 0x0A) {
+ ++m_uCurrentLine;
+ XFA_FMDChar::inc(p);
+ pEnd = p;
+ return;
+ }
+ XFA_FMDChar::inc(p);
+ ch = XFA_FMDChar::get(p);
+ }
+ pEnd = p;
+}
+XFA_FM_TOKEN CXFA_FMLexer::IsKeyword(FX_WSTR str)
+{
+ FX_INT32 iLength = str.GetLength();
+ FX_UINT32 uHash = FX_HashCode_String_GetW(str.GetPtr(), iLength, TRUE);
+ FX_INT32 iStart = KEYWORD_START, iEnd = KEYWORD_END;
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_FMKeyword keyword;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ keyword = keyWords[iMid];
+ if (uHash == keyword.m_uHash) {
+ return keyword.m_type;
+ } else if (uHash < keyword.m_uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return TOKidentifier;
+}
+CXFA_FMLexer::~CXFA_FMLexer()
+{
+ m_pScript = 0;
+ m_ptr = m_pScript;
+ if (m_pToken) {
+ CXFA_FMToken *t1 = m_pToken;
+ CXFA_FMToken *t2 = t1->m_pNext;
+ while (t2) {
+ delete t1;
+ t1 = t2;
+ t2 = t2->m_pNext;
+ }
+ delete m_pToken;
+ m_pToken = 0;
+ }
+ m_pErrorInfo = 0;
+}
+void CXFA_FMLexer::Error(XFA_FM_ERRMSG msg, ...)
+{
+ m_pErrorInfo->linenum = m_uCurrentLine;
+ FX_LPCWSTR lpMessageInfo = XFA_FM_ErrorMsg(msg);
+ va_list ap;
+ va_start(ap, msg);
+ m_pErrorInfo->message.FormatV(lpMessageInfo, ap);
+ va_end(ap);
+}
+FX_BOOL CXFA_FMLexer::HasError() const
+{
+ if (m_pErrorInfo->message.IsEmpty()) {
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fxfa/src/fm2js/xfa_lexer.h b/xfa/src/fxfa/src/fm2js/xfa_lexer.h
new file mode 100644
index 0000000000..b073ceb047
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_lexer.h
@@ -0,0 +1,82 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM_LEXER_H
+#define _XFA_FM_LEXER_H
+enum XFA_FM_TOKEN {
+ TOKand, TOKlparen, TOKrparen, TOKmul, TOKplus, TOKcomma, TOKminus, TOKdot, TOKdiv, TOKlt,
+ TOKassign, TOKgt, TOKlbracket, TOKrbracket, TOKor, TOKdotscream, TOKdotstar, TOKdotdot,
+ TOKle, TOKne, TOKeq, TOKge,
+ TOKdo, TOKkseq, TOKksge, TOKksgt, TOKif, TOKin, TOKksle, TOKkslt, TOKksne, TOKksor, TOKnull,
+ TOKbreak, TOKksand, TOKend, TOKeof, TOKfor, TOKnan, TOKksnot, TOKvar, TOKthen, TOKelse, TOKexit,
+ TOKdownto, TOKreturn, TOKinfinity, TOKendwhile, TOKforeach, TOKendfunc, TOKelseif, TOKwhile,
+ TOKendfor, TOKthrow, TOKstep, TOKupto, TOKcontinue, TOKfunc, TOKendif,
+ TOKstar,
+ TOKidentifier, TOKunderscore, TOKdollar, TOKexclamation,
+ TOKcall,
+ TOKstring,
+ TOKnumber,
+ TOKreserver
+};
+struct XFA_FMKeyword {
+ XFA_FM_TOKEN m_type;
+ FX_UINT32 m_uHash;
+ FX_LPCWSTR m_keword;
+};
+FX_LPCWSTR XFA_FM_KeywordToString(XFA_FM_TOKEN op);
+class CXFA_FMToken : public CFX_Object
+{
+public:
+ CXFA_FMToken();
+ CXFA_FMToken(FX_DWORD uLineNum);
+ ~CXFA_FMToken();
+ CFX_WideStringC m_wstring;
+ XFA_FM_TOKEN m_type;
+ FX_DWORD m_uLinenum;
+ CXFA_FMToken* m_pNext;
+};
+class CXFA_FMLexer : public CFX_Object
+{
+public:
+ CXFA_FMLexer(FX_WSTR wsFormcalc, CXFA_FMErrorInfo *pErrorInfo);
+ ~CXFA_FMLexer();
+ CXFA_FMToken* NextToken();
+ FX_DWORD Number(CXFA_FMToken *t, FX_LPCWSTR p, FX_LPCWSTR &pEnd);
+ FX_DWORD String(CXFA_FMToken *t, FX_LPCWSTR p, FX_LPCWSTR &pEnd);
+ FX_DWORD Identifiers(CXFA_FMToken *t, FX_LPCWSTR p, FX_LPCWSTR &pEnd);
+ void Comment(FX_LPCWSTR p, FX_LPCWSTR &pEnd);
+ XFA_FM_TOKEN IsKeyword(FX_WSTR p);
+ void SetCurrentLine(FX_DWORD line)
+ {
+ m_uCurrentLine = line;
+ }
+ void SetToken(CXFA_FMToken *pToken)
+ {
+ if (m_pToken) {
+ delete m_pToken;
+ }
+ m_pToken = pToken;
+ }
+ FX_LPCWSTR SavePos()
+ {
+ return m_ptr;
+ }
+ void RestorePos(FX_LPCWSTR pPos)
+ {
+ m_ptr = pPos;
+ }
+ void Error(XFA_FM_ERRMSG msg, ...);
+ FX_BOOL HasError() const;
+protected:
+ CXFA_FMToken* Scan();
+ FX_LPCWSTR m_pScript;
+ FX_LPCWSTR m_ptr;
+ FX_STRSIZE m_uLength;
+ FX_DWORD m_uCurrentLine;
+ CXFA_FMToken* m_pToken;
+ CXFA_FMErrorInfo* m_pErrorInfo;
+};
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_program.cpp b/xfa/src/fxfa/src/fm2js/xfa_program.cpp
new file mode 100644
index 0000000000..d291e7a614
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_program.cpp
@@ -0,0 +1,50 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+CXFA_FMProgram::CXFA_FMProgram()
+ : m_globalFunction(0)
+{
+}
+CXFA_FMProgram::~CXFA_FMProgram()
+{
+ if (m_globalFunction != 0) {
+ delete m_globalFunction;
+ m_globalFunction = 0;
+ }
+}
+FX_INT32 CXFA_FMProgram::Init(FX_WSTR wsFormcalc)
+{
+ return m_parse.Init(wsFormcalc, &m_pErrorInfo);
+}
+FX_INT32 CXFA_FMProgram::ParseProgram()
+{
+ CFX_PtrArray * expressions = 0;
+ m_parse.NextToken();
+ if (!m_pErrorInfo.message.IsEmpty()) {
+ return -1;
+ }
+ expressions = m_parse.ParseTopExpression();
+ if (!m_pErrorInfo.message.IsEmpty()) {
+ CXFA_FMExpression *e = 0;
+ for (FX_INT32 u = 0; u < expressions->GetSize(); ++u) {
+ e = (CXFA_FMExpression *)expressions->GetAt(u);
+ if (e) {
+ delete e;
+ }
+ }
+ delete expressions;
+ return -1;
+ }
+ m_globalFunction = FX_NEW CXFA_FMFunctionDefinition(1, 1, FX_WSTRC(L""), 0, expressions);
+ return 0;
+}
+FX_INT32 CXFA_FMProgram::TranslateProgram(CFX_WideTextBuf &wsJavaScript)
+{
+ m_globalFunction->ToJavaScript(wsJavaScript);
+ wsJavaScript.AppendChar(0);
+ return 0;
+}
diff --git a/xfa/src/fxfa/src/fm2js/xfa_program.h b/xfa/src/fxfa/src/fm2js/xfa_program.h
new file mode 100644
index 0000000000..a90af5e32f
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_program.h
@@ -0,0 +1,26 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM_PROGRAM_H
+#define _XFA_FM_PROGRAM_H
+class CXFA_FMProgram : public CFX_Object
+{
+public:
+ CXFA_FMProgram();
+ ~CXFA_FMProgram();
+ FX_INT32 Init(FX_WSTR wsFormcalc);
+ FX_INT32 ParseProgram();
+ FX_INT32 TranslateProgram(CFX_WideTextBuf &wsJavaScript);
+ CXFA_FMErrorInfo& GetError()
+ {
+ return m_pErrorInfo;
+ }
+private:
+ CXFA_FMErrorInfo m_pErrorInfo;
+ CXFA_FMParse m_parse;
+ CXFA_FMFunctionDefinition *m_globalFunction;
+};
+#endif
diff --git a/xfa/src/fxfa/src/fm2js/xfa_simpleexpression.cpp b/xfa/src/fxfa/src/fm2js/xfa_simpleexpression.cpp
new file mode 100644
index 0000000000..c309f129ee
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_simpleexpression.cpp
@@ -0,0 +1,758 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "xfa_fm2js.h"
+static CFX_WideStringC gs_lpStrExpFuncName[] = {
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.assign_value_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_or_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_and_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.equality_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.notequality_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.less_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.lessequal_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.greater_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.greaterequal_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.plus_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.minus_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.multiple_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.divide_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.positive_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.negative_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.logical_not_operator"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime."),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.dot_accessor"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.dotdot_accessor"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.concat_fm_object"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.is_fm_object"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.is_fm_array"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.get_fm_value"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.get_fm_jsobj"),
+ FX_WSTRC(L"foxit_xfa_formcalc_runtime.fm_var_filter"),
+};
+CFX_WideStringC XFA_FM_EXPTypeToString(XFA_FM_SimpleExpressionType simpleExpType)
+{
+ return gs_lpStrExpFuncName[simpleExpType];
+}
+static XFA_FMBuildInFunc buildInFuncs[] = {
+ {0x0001f1f5, (FX_LPCWSTR)L"At"},
+ {0x00020b9c, (FX_LPCWSTR)L"FV"},
+ {0x00021aef, (FX_LPCWSTR)L"If"},
+ {0x00023ee6, (FX_LPCWSTR)L"PV"},
+ {0x04b5c9ee, (FX_LPCWSTR)L"Encode"},
+ {0x08e96685, (FX_LPCWSTR)L"DateFmt"},
+ {0x09f99db6, (FX_LPCWSTR)L"Abs"},
+ {0x09f9e583, (FX_LPCWSTR)L"Apr"},
+ {0x09fa043e, (FX_LPCWSTR)L"Avg"},
+ {0x0a9782a0, (FX_LPCWSTR)L"Get"},
+ {0x0b1b09df, (FX_LPCWSTR)L"Len"},
+ {0x0b3543a6, (FX_LPCWSTR)L"Max"},
+ {0x0b356ca4, (FX_LPCWSTR)L"Min"},
+ {0x0b358b60, (FX_LPCWSTR)L"Mod"},
+ {0x0b4fded4, (FX_LPCWSTR)L"NPV"},
+ {0x0b846bf1, (FX_LPCWSTR)L"Pmt"},
+ {0x0b8494f9, (FX_LPCWSTR)L"Put"},
+ {0x0bb8df5d, (FX_LPCWSTR)L"Ref"},
+ {0x0bd37a99, (FX_LPCWSTR)L"Str"},
+ {0x0bd37fb5, (FX_LPCWSTR)L"Sum"},
+ {0x1048469b, (FX_LPCWSTR)L"Cterm"},
+ {0x11e03660, (FX_LPCWSTR)L"Exists"},
+ {0x126236e6, (FX_LPCWSTR)L"Post"},
+ {0x127c6661, (FX_LPCWSTR)L"PPmt"},
+ {0x193ade3e, (FX_LPCWSTR)L"Right"},
+ {0x1ec8ab2c, (FX_LPCWSTR)L"Rate"},
+ {0x20e476dc, (FX_LPCWSTR)L"IsoTime2Num"},
+ {0x23eb6816, (FX_LPCWSTR)L"TimeFmt"},
+ {0x24fb17b0, (FX_LPCWSTR)L"LocalDateFmt"},
+ {0x28dee6e9, (FX_LPCWSTR)L"Format"},
+ {0x2d0890b8, (FX_LPCWSTR)L"Term"},
+ {0x2d71b00f, (FX_LPCWSTR)L"Time"},
+ {0x2f890fb1, (FX_LPCWSTR)L"Num2Time"},
+ {0x3767511d, (FX_LPCWSTR)L"Ceil"},
+ {0x3ffd1941, (FX_LPCWSTR)L"LocalTimeFmt"},
+ {0x442f68c8, (FX_LPCWSTR)L"Round"},
+ {0x46fd1128, (FX_LPCWSTR)L"Eval"},
+ {0x4d629440, (FX_LPCWSTR)L"Date2Num"},
+ {0x4dcf25f8, (FX_LPCWSTR)L"Concat"},
+ {0x4e00255d, (FX_LPCWSTR)L"UnitValue"},
+ {0x55a5cc29, (FX_LPCWSTR)L"Lower"},
+ {0x5e43e04c, (FX_LPCWSTR)L"WordNum"},
+ {0x620ce6ba, (FX_LPCWSTR)L"Ipmt"},
+ {0x6f544d49, (FX_LPCWSTR)L"Count"},
+ {0x7e241013, (FX_LPCWSTR)L"Within"},
+ {0x9b9a6e2b, (FX_LPCWSTR)L"IsoDate2Num"},
+ {0xb2c941c2, (FX_LPCWSTR)L"UnitType"},
+ {0xb598a1f7, (FX_LPCWSTR)L"Uuid"},
+ {0xbde9abde, (FX_LPCWSTR)L"Date"},
+ {0xc0010b80, (FX_LPCWSTR)L"Num2Date"},
+ {0xc1f6144c, (FX_LPCWSTR)L"Upper"},
+ {0xc44028f7, (FX_LPCWSTR)L"Oneof"},
+ {0xc62c1b2c, (FX_LPCWSTR)L"Space"},
+ {0xd0ff50f9, (FX_LPCWSTR)L"HasValue"},
+ {0xd1537042, (FX_LPCWSTR)L"Floor"},
+ {0xd2ac9cf1, (FX_LPCWSTR)L"Time2Num"},
+ {0xd907aee5, (FX_LPCWSTR)L"Num2GMTime"},
+ {0xdf24f7c4, (FX_LPCWSTR)L"Decode"},
+ {0xe2664803, (FX_LPCWSTR)L"Substr"},
+ {0xe3e7b528, (FX_LPCWSTR)L"Stuff"},
+ {0xe6792d4e, (FX_LPCWSTR)L"Rtrim"},
+ {0xe8c23f5b, (FX_LPCWSTR)L"Parse"},
+ {0xea18d121, (FX_LPCWSTR)L"Choose"},
+ {0xebfef69c, (FX_LPCWSTR)L"Replace"},
+ {0xf5ad782b, (FX_LPCWSTR)L"Left"},
+ {0xf7bb2248, (FX_LPCWSTR)L"Ltrim"},
+};
+static const XFA_FMSOMMethod gs_FMSomMethods[] = {
+ {0x00000068, (FX_LPCWSTR)L"h", 0x01},
+ {0x00000077, (FX_LPCWSTR)L"w", 0x01},
+ {0x00000078, (FX_LPCWSTR)L"x", 0x01},
+ {0x00000079, (FX_LPCWSTR)L"y", 0x01},
+ {0x05eb5b0f, (FX_LPCWSTR)L"pageSpan", 0x01},
+ {0x10f1b1bd, (FX_LPCWSTR)L"page", 0x01},
+ {0x3bf1c2a5, (FX_LPCWSTR)L"absPageSpan", 0x01},
+ {0x3c752495, (FX_LPCWSTR)L"verify", 0x0d},
+ {0x44c352ad, (FX_LPCWSTR)L"formNodes", 0x01},
+ {0x5775c2cc, (FX_LPCWSTR)L"absPageInBatch", 0x01},
+ {0x5ee00996, (FX_LPCWSTR)L"setElement", 0x01},
+ {0x7033bfd5, (FX_LPCWSTR)L"insert", 0x03},
+ {0x8c5feb32, (FX_LPCWSTR)L"sheetInBatch", 0x01},
+ {0x8f3a8379, (FX_LPCWSTR)L"sheet", 0x01},
+ {0x92dada4f, (FX_LPCWSTR)L"saveFilteredXML", 0x01},
+ {0x9cab7cae, (FX_LPCWSTR)L"remove", 0x01},
+ {0xa68635f1, (FX_LPCWSTR)L"sign", 0x61},
+ {0xaac241c8, (FX_LPCWSTR)L"isRecordGroup", 0x01},
+ {0xd8ed1467, (FX_LPCWSTR)L"clear", 0x01},
+ {0xda12e518, (FX_LPCWSTR)L"append", 0x01},
+ {0xe74f0653, (FX_LPCWSTR)L"absPage", 0x01},
+};
+CXFA_FMSimpleExpression::CXFA_FMSimpleExpression(FX_DWORD line, XFA_FM_TOKEN op)
+ : m_line(line),
+ m_op(op)
+{
+}
+void CXFA_FMSimpleExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+}
+void CXFA_FMSimpleExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{}
+XFA_FM_TOKEN CXFA_FMSimpleExpression::GetOperatorToken()const
+{
+ return m_op;
+}
+CXFA_FMNullExpression::CXFA_FMNullExpression(FX_DWORD line)
+ : CXFA_FMSimpleExpression(line, TOKnull)
+{
+}
+void CXFA_FMNullExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"null");
+}
+CXFA_FMNumberExpression::CXFA_FMNumberExpression(FX_DWORD line, CFX_WideStringC wsNumber)
+ : CXFA_FMSimpleExpression(line, TOKnumber), m_wsNumber(wsNumber)
+{
+}
+void CXFA_FMNumberExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << m_wsNumber;
+}
+CXFA_FMStringExpression::CXFA_FMStringExpression(FX_DWORD line, CFX_WideStringC wsString)
+ : CXFA_FMSimpleExpression(line, TOKstring),
+ m_wsString(wsString)
+{
+}
+void CXFA_FMStringExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ CFX_WideString tempStr = m_wsString;
+ if (tempStr.GetLength() > 2) {
+ javascript.AppendChar(L'\"');
+ FX_WCHAR oneChar;
+ for (FX_INT16 i = 1; i < tempStr.GetLength() - 1; i++) {
+ oneChar = tempStr[i];
+ switch (oneChar) {
+ case L'\"': {
+ i++;
+ javascript << FX_WSTRC(L"\\\"");
+ }
+ break;
+ case 0x0d:
+ break;
+ case 0x0a: {
+ javascript << FX_WSTRC(L"\\n");
+ }
+ break;
+ default: {
+ javascript.AppendChar(oneChar);
+ }
+ break;
+ }
+ }
+ javascript.AppendChar(L'\"');
+ } else {
+ javascript << tempStr;
+ }
+}
+CXFA_FMIdentifierExpressionn::CXFA_FMIdentifierExpressionn(FX_DWORD line, CFX_WideStringC wsIdentifier)
+ : CXFA_FMSimpleExpression(line, TOKidentifier), m_wsIdentifier(wsIdentifier)
+{
+}
+void CXFA_FMIdentifierExpressionn::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ CFX_WideString tempStr = m_wsIdentifier;
+ if (tempStr.Equal(FX_WSTRC(L"$"))) {
+ tempStr = FX_WSTRC(L"this");
+ } else if (tempStr.Equal(FX_WSTRC(L"!"))) {
+ tempStr = FX_WSTRC(L"xfa.datasets");
+ } else if (tempStr.Equal(FX_WSTRC(L"$data"))) {
+ tempStr = FX_WSTRC(L"xfa.datasets.data");
+ } else if (tempStr.Equal(FX_WSTRC(L"$event"))) {
+ tempStr = FX_WSTRC(L"xfa.event");
+ } else if (tempStr.Equal(FX_WSTRC(L"$form"))) {
+ tempStr = FX_WSTRC(L"xfa.form");
+ } else if (tempStr.Equal(FX_WSTRC(L"$host"))) {
+ tempStr = FX_WSTRC(L"xfa.host");
+ } else if (tempStr.Equal(FX_WSTRC(L"$layout"))) {
+ tempStr = FX_WSTRC(L"xfa.layout");
+ } else if (tempStr.Equal(FX_WSTRC(L"$template"))) {
+ tempStr = FX_WSTRC(L"xfa.template");
+ } else if (tempStr[0] == L'!') {
+ tempStr = EXCLAMATION_IN_IDENTIFIER + tempStr.Mid(1);
+ }
+ javascript << tempStr;
+ return;
+}
+CXFA_FMUnaryExpression::CXFA_FMUnaryExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp)
+ : CXFA_FMSimpleExpression(line, op), m_pExp(pExp)
+{
+}
+CXFA_FMUnaryExpression::~CXFA_FMUnaryExpression()
+{
+ if (m_pExp != 0) {
+ delete m_pExp;
+ m_pExp = 0;
+ }
+}
+void CXFA_FMUnaryExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+}
+CXFA_FMBinExpression::CXFA_FMBinExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )
+ : CXFA_FMSimpleExpression(line, op),
+ m_pExp1(pExp1),
+ m_pExp2(pExp2)
+{
+}
+CXFA_FMBinExpression::~CXFA_FMBinExpression()
+{
+ if (m_pExp1 != 0) {
+ delete m_pExp1;
+ m_pExp1 = 0;
+ }
+ if (m_pExp2 != 0) {
+ delete m_pExp2;
+ m_pExp2 = 0;
+ }
+}
+void CXFA_FMBinExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+}
+CXFA_FMAssignExpression::CXFA_FMAssignExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )
+ : CXFA_FMBinExpression(line, op, pExp1, pExp2)
+{
+}
+void CXFA_FMAssignExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"if (");
+ javascript << gs_lpStrExpFuncName[ISFMOBJECT];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"))\n{\n");
+ javascript << gs_lpStrExpFuncName[ASSIGN];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L");\n}\n");
+ CFX_WideTextBuf tempExp1;
+ m_pExp1->ToJavaScript(tempExp1);
+ if (m_pExp1->GetOperatorToken() == TOKidentifier && tempExp1.GetWideString() != FX_WSTRC(L"this")) {
+ javascript << FX_WSTRC(L"else\n{\n");
+ javascript << tempExp1;
+ javascript << FX_WSTRC(L" = ");
+ javascript << gs_lpStrExpFuncName[ASSIGN];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L");\n}\n");
+ }
+}
+void CXFA_FMAssignExpression::ToImpliedReturnJS(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"if (");
+ javascript << gs_lpStrExpFuncName[ISFMOBJECT];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L"))\n{\n");
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = ");
+ javascript << gs_lpStrExpFuncName[ASSIGN];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L");\n}\n");
+ CFX_WideTextBuf tempExp1;
+ m_pExp1->ToJavaScript(tempExp1);
+ if (m_pExp1->GetOperatorToken() == TOKidentifier && tempExp1.GetWideString() != FX_WSTRC(L"this")) {
+ javascript << FX_WSTRC(L"else\n{\n");
+ javascript << RUNTIMEFUNCTIONRETURNVALUE;
+ javascript << FX_WSTRC(L" = ");
+ javascript << tempExp1;
+ javascript << FX_WSTRC(L" = ");
+ javascript << gs_lpStrExpFuncName[ASSIGN];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L");\n}\n");
+ }
+}
+CXFA_FMLogicalOrExpression::CXFA_FMLogicalOrExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2)
+ : CXFA_FMBinExpression(line, op, pExp1, pExp2)
+{
+}
+void CXFA_FMLogicalOrExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << gs_lpStrExpFuncName[LOGICALOR];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMLogicalAndExpression::CXFA_FMLogicalAndExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )
+ : CXFA_FMBinExpression(line, op, pExp1, pExp2)
+{
+}
+void CXFA_FMLogicalAndExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << gs_lpStrExpFuncName[LOGICALAND];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMEqualityExpression::CXFA_FMEqualityExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )
+ : CXFA_FMBinExpression(line, op, pExp1, pExp2)
+{
+}
+void CXFA_FMEqualityExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ switch(m_op) {
+ case TOKeq:
+ case TOKkseq:
+ javascript << gs_lpStrExpFuncName[EQUALITY];
+ break;
+ case TOKne:
+ case TOKksne:
+ javascript << gs_lpStrExpFuncName[NOTEQUALITY];
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMRelationalExpression::CXFA_FMRelationalExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )
+ : CXFA_FMBinExpression(line, op, pExp1, pExp2)
+{
+}
+void CXFA_FMRelationalExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ switch (m_op) {
+ case TOKlt:
+ case TOKkslt:
+ javascript << gs_lpStrExpFuncName[LESS];
+ break;
+ case TOKgt:
+ case TOKksgt:
+ javascript << gs_lpStrExpFuncName[GREATER];
+ break;
+ case TOKle:
+ case TOKksle:
+ javascript << gs_lpStrExpFuncName[LESSEQUAL];
+ break;
+ case TOKge:
+ case TOKksge:
+ javascript << gs_lpStrExpFuncName[GREATEREQUAL];
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMAdditiveExpression::CXFA_FMAdditiveExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )
+ : CXFA_FMBinExpression(line, op, pExp1, pExp2)
+{
+}
+void CXFA_FMAdditiveExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ switch (m_op) {
+ case TOKplus:
+ javascript << gs_lpStrExpFuncName[PLUS];
+ break;
+ case TOKminus:
+ javascript << gs_lpStrExpFuncName[MINUS];
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMMultiplicativeExpression::CXFA_FMMultiplicativeExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2 )
+ : CXFA_FMBinExpression(line, op, pExp1, pExp2)
+{
+}
+void CXFA_FMMultiplicativeExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ switch (m_op) {
+ case TOKmul:
+ javascript << gs_lpStrExpFuncName[MULTIPLE];
+ break;
+ case TOKdiv:
+ javascript << gs_lpStrExpFuncName[DIVIDE];
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMPosExpression::CXFA_FMPosExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp ) : CXFA_FMUnaryExpression(line, TOKplus, pExp)
+{
+}
+void CXFA_FMPosExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << gs_lpStrExpFuncName[POSITIVE];
+ javascript << FX_WSTRC(L"(");
+ m_pExp->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMNegExpression::CXFA_FMNegExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp )
+ : CXFA_FMUnaryExpression(line, TOKminus, pExp)
+{
+}
+void CXFA_FMNegExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << gs_lpStrExpFuncName[NEGATIVE];
+ javascript << FX_WSTRC(L"(");
+ m_pExp->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMNotExpression::CXFA_FMNotExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp )
+ : CXFA_FMUnaryExpression(line, TOKksnot, pExp)
+{
+}
+void CXFA_FMNotExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << gs_lpStrExpFuncName[NOT];
+ javascript << FX_WSTRC(L"(");
+ m_pExp->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMCallExpression::CXFA_FMCallExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp, CFX_PtrArray *pArguments, FX_BOOL bIsSomMethod)
+ : CXFA_FMUnaryExpression(line, TOKcall, pExp),
+ m_pArguments(pArguments),
+ m_bIsSomMethod(bIsSomMethod)
+{
+}
+CXFA_FMCallExpression::~CXFA_FMCallExpression()
+{
+ if (m_pArguments) {
+ FX_INT32 argc = m_pArguments->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMSimpleExpression *e = 0;
+ while (index < argc) {
+ e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);
+ delete e;
+ index++;
+ }
+ m_pArguments->RemoveAll();
+ delete m_pArguments;
+ m_pArguments = 0;
+ }
+}
+FX_BOOL CXFA_FMCallExpression::IsBuildInFunc(CFX_WideTextBuf& funcName)
+{
+ FX_INT32 iLength = funcName.GetLength();
+ FX_UINT32 uHash = FX_HashCode_String_GetW(funcName.GetBuffer(), iLength, TRUE);
+ XFA_FMBuildInFunc buildinfunction;
+ FX_INT32 iStart = 0, iEnd = (sizeof(buildInFuncs) / sizeof(buildInFuncs[0])) - 1;
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ buildinfunction = buildInFuncs[iMid];
+ if (uHash == buildinfunction.m_uHash) {
+ funcName.Clear();
+ funcName << buildinfunction.m_buildinfunc;
+ return TRUE;
+ } else if (uHash < buildinfunction.m_uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return FALSE;
+}
+FX_DWORD CXFA_FMCallExpression::IsSomMethodWithObjPara(FX_WSTR methodName)
+{
+ FX_INT32 iLength = methodName.GetLength();
+ FX_UINT32 uHash = FX_HashCode_String_GetW(methodName.GetPtr(), iLength);
+ XFA_FMSOMMethod somMethodWithObjPara;
+ FX_DWORD parameters = 0x00;
+ FX_INT32 iStart = 0, iEnd = (sizeof(gs_FMSomMethods) / sizeof(gs_FMSomMethods[0])) - 1;
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ somMethodWithObjPara = gs_FMSomMethods[iMid];
+ if (uHash == somMethodWithObjPara.m_uHash) {
+ parameters = somMethodWithObjPara.m_dParameters;
+ break;
+ } else if (uHash < somMethodWithObjPara.m_uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return parameters;
+}
+void CXFA_FMCallExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ CFX_WideTextBuf funcName;
+ m_pExp->ToJavaScript(funcName);
+ if (m_bIsSomMethod) {
+ javascript << funcName;
+ javascript << FX_WSTRC(L"(");
+ if (m_pArguments) {
+ FX_INT32 argc = m_pArguments->GetSize();
+ FX_INT32 index = 0;
+ FX_DWORD methodPara = IsSomMethodWithObjPara(funcName.GetWideString());
+ if (methodPara > 0) {
+ CXFA_FMSimpleExpression *e = 0;
+ while (index < argc) {
+ if ((methodPara & (0x01 << index)) > 0) {
+ javascript << gs_lpStrExpFuncName[GETFMJSOBJ];
+ } else {
+ javascript << gs_lpStrExpFuncName[GETFMVALUE];
+ }
+ javascript << FX_WSTRC(L"(");
+ e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);
+ e->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+ if (index + 1 < argc) {
+ javascript << FX_WSTRC(L", ");
+ }
+ index++;
+ }
+ } else {
+ CXFA_FMSimpleExpression *e = 0;
+ while (index < argc) {
+ javascript << gs_lpStrExpFuncName[GETFMVALUE];
+ javascript << FX_WSTRC(L"(");
+ e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);
+ e->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+ if (index + 1 < argc) {
+ javascript << FX_WSTRC(L", ");
+ }
+ index++;
+ }
+ }
+ }
+ javascript << FX_WSTRC(L")");
+ } else {
+ FX_BOOL isEvalFunc = FALSE;
+ FX_BOOL isExistsFunc = FALSE;
+ if (IsBuildInFunc(funcName)) {
+ if (funcName.GetWideString() == FX_WSTRC(L"Eval")) {
+ isEvalFunc = TRUE;
+ javascript << FX_WSTRC(L"eval.call(this, ");
+ javascript << gs_lpStrExpFuncName[CALL];
+ javascript << FX_WSTRC(L"Translate");
+ } else if (funcName.GetWideString() == FX_WSTRC(L"Exists")) {
+ isExistsFunc = TRUE;
+ javascript << gs_lpStrExpFuncName[CALL];
+ javascript << funcName;
+ } else {
+ javascript << gs_lpStrExpFuncName[CALL];
+ javascript << funcName;
+ }
+ } else {
+ javascript << funcName;
+ }
+ javascript << FX_WSTRC(L"(");
+ if (isExistsFunc) {
+ javascript << FX_WSTRC(L"\n(\nfunction ()\n{\ntry\n{\n");
+ if (m_pArguments && m_pArguments->GetSize() > 0) {
+ CXFA_FMSimpleExpression *e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(0);
+ javascript << FX_WSTRC(L"return ");
+ e->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L";\n}\n");
+ } else {
+ javascript << FX_WSTRC(L"return 0;\n}\n");
+ }
+ javascript << FX_WSTRC(L"catch(accessExceptions)\n{\nreturn 0;\n}\n}\n).call(this)\n");
+ } else if (m_pArguments) {
+ FX_INT32 argc = m_pArguments->GetSize();
+ FX_INT32 index = 0;
+ CXFA_FMSimpleExpression *e = 0;
+ while (index < argc) {
+ e = (CXFA_FMSimpleExpression *)m_pArguments->GetAt(index);
+ e->ToJavaScript(javascript);
+ if (index + 1 < argc) {
+ javascript << FX_WSTRC(L", ");
+ }
+ index++;
+ }
+ }
+ javascript << FX_WSTRC(L")");
+ if (isEvalFunc) {
+ javascript << FX_WSTRC(L")");
+ }
+ }
+}
+CXFA_FMDotAccessorExpression::CXFA_FMDotAccessorExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessor, XFA_FM_TOKEN op,
+ CFX_WideStringC wsIdentifier, CXFA_FMSimpleExpression *pIndexExp)
+ : CXFA_FMBinExpression(line, op, pAccessor, pIndexExp),
+ m_wsIdentifier(wsIdentifier)
+{}
+void CXFA_FMDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << gs_lpStrExpFuncName[DOT];
+ javascript << FX_WSTRC(L"(");
+ if(m_pExp1) {
+ m_pExp1->ToJavaScript(javascript);
+ } else {
+ javascript << FX_WSTRC(L"null");
+ }
+ javascript << FX_WSTRC(L", ");
+ javascript << FX_WSTRC(L"\"");
+ if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) {
+ m_pExp1->ToJavaScript(javascript);
+ }
+ javascript << FX_WSTRC(L"\", ");
+ if (m_op == TOKdotscream) {
+ javascript << FX_WSTRC(L"\"#");
+ javascript << m_wsIdentifier;
+ javascript << FX_WSTRC(L"\", ");
+ } else if (m_op == TOKdotstar) {
+ javascript << FX_WSTRC(L"\"*\", ");
+ } else if (m_op == TOKcall) {
+ javascript << FX_WSTRC(L"\"\", ");
+ } else {
+ javascript << FX_WSTRC(L"\"");
+ javascript << m_wsIdentifier;
+ javascript << FX_WSTRC(L"\", ");
+ }
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMIndexExpression::CXFA_FMIndexExpression(FX_DWORD line, XFA_FM_AccessorIndex accessorIndex,
+ CXFA_FMSimpleExpression *pIndexExp, FX_BOOL bIsStarIndex)
+ : CXFA_FMUnaryExpression(line, TOKlbracket, pIndexExp),
+ m_accessorIndex(accessorIndex),
+ m_bIsStarIndex(bIsStarIndex)
+{}
+void CXFA_FMIndexExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ switch(m_accessorIndex) {
+ case ACCESSOR_NO_INDEX:
+ javascript << FX_WSTRC(L"0");
+ break;
+ case ACCESSOR_NO_RELATIVEINDEX:
+ javascript << FX_WSTRC(L"1");
+ break;
+ case ACCESSOR_POSITIVE_INDEX:
+ javascript << FX_WSTRC(L"2");
+ break;
+ case ACCESSOR_NEGATIVE_INDEX:
+ javascript << FX_WSTRC(L"3");
+ break;
+ default:
+ javascript << FX_WSTRC(L"0");
+ }
+ if (!m_bIsStarIndex) {
+ javascript << FX_WSTRC(L", ");
+ if (m_pExp) {
+ m_pExp->ToJavaScript(javascript);
+ } else {
+ javascript << FX_WSTRC(L"0");
+ }
+ }
+}
+CXFA_FMDotDotAccessorExpression::CXFA_FMDotDotAccessorExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessor, XFA_FM_TOKEN op,
+ CFX_WideStringC wsIdentifier, CXFA_FMSimpleExpression *pIndexExp)
+ : CXFA_FMBinExpression(line, op, pAccessor, pIndexExp),
+ m_wsIdentifier(wsIdentifier)
+{}
+void CXFA_FMDotDotAccessorExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << gs_lpStrExpFuncName[DOTDOT];
+ javascript << FX_WSTRC(L"(");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L", ");
+ javascript << FX_WSTRC(L"\"");
+ if (m_pExp1 && m_pExp1->GetOperatorToken() == TOKidentifier) {
+ m_pExp1->ToJavaScript(javascript);
+ }
+ javascript << FX_WSTRC(L"\", ");
+ javascript << FX_WSTRC(L"\"");
+ javascript << m_wsIdentifier;
+ javascript << FX_WSTRC(L"\", ");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L")");
+}
+CXFA_FMMethodCallExpression::CXFA_FMMethodCallExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessorExp1, CXFA_FMSimpleExpression *pCallExp)
+ : CXFA_FMBinExpression(line, TOKdot, pAccessorExp1, pCallExp)
+{
+}
+void CXFA_FMMethodCallExpression::ToJavaScript(CFX_WideTextBuf& javascript)
+{
+ javascript << FX_WSTRC(L"(\nfunction ()\n{\n");
+ javascript << FX_WSTRC(L"var method_return_value = null;\n");
+ javascript << FX_WSTRC(L"var accessor_object = ");
+ m_pExp1->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L";\n");
+ javascript << FX_WSTRC(L"if (");
+ javascript << gs_lpStrExpFuncName[ISFMARRAY];
+ javascript << FX_WSTRC(L"(accessor_object))\n{\n");
+ javascript << FX_WSTRC(L"for(var index = accessor_object.length - 1; index > 1; index--)\n{\n");
+ javascript << FX_WSTRC(L"method_return_value = accessor_object[index].");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L";\n}\n}\n");
+ javascript << FX_WSTRC(L"else\n{\nmethod_return_value = accessor_object.");
+ m_pExp2->ToJavaScript(javascript);
+ javascript << FX_WSTRC(L";\n}\n");
+ javascript << FX_WSTRC(L"return method_return_value;\n");
+ javascript << FX_WSTRC(L"}\n).call(this)");
+}
diff --git a/xfa/src/fxfa/src/fm2js/xfa_simpleexpression.h b/xfa/src/fxfa/src/fm2js/xfa_simpleexpression.h
new file mode 100644
index 0000000000..2a6245d348
--- /dev/null
+++ b/xfa/src/fxfa/src/fm2js/xfa_simpleexpression.h
@@ -0,0 +1,239 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_FM_SIMPLEEXPRESSION_H
+#define _XFA_FM_SIMPLEEXPRESSION_H
+enum XFA_FM_SimpleExpressionType {
+ ASSIGN,
+ LOGICALOR,
+ LOGICALAND,
+ EQUALITY,
+ NOTEQUALITY,
+ LESS,
+ LESSEQUAL,
+ GREATER,
+ GREATEREQUAL,
+ PLUS,
+ MINUS,
+ MULTIPLE,
+ DIVIDE,
+ POSITIVE,
+ NEGATIVE,
+ NOT,
+ CALL,
+ DOT,
+ DOTDOT,
+ CONCATFMOBJECT,
+ ISFMOBJECT,
+ ISFMARRAY,
+ GETFMVALUE,
+ GETFMJSOBJ,
+ VARFILTER
+};
+CFX_WideStringC XFA_FM_EXPTypeToString(XFA_FM_SimpleExpressionType simpleExpType);
+struct XFA_FMBuildInFunc {
+ FX_UINT32 m_uHash;
+ FX_LPCWSTR m_buildinfunc;
+};
+struct XFA_FMSOMMethod {
+ FX_UINT32 m_uHash;
+ FX_LPCWSTR m_wsSomMethodName;
+ FX_DWORD m_dParameters;
+};
+enum XFA_FM_AccessorIndex {
+ ACCESSOR_NO_INDEX,
+ ACCESSOR_NO_RELATIVEINDEX,
+ ACCESSOR_POSITIVE_INDEX,
+ ACCESSOR_NEGATIVE_INDEX
+};
+class CXFA_FMSimpleExpression : public CFX_Object
+{
+public:
+ CXFA_FMSimpleExpression(FX_DWORD line, XFA_FM_TOKEN op);
+ virtual ~CXFA_FMSimpleExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf& javascript);
+
+ XFA_FM_TOKEN GetOperatorToken() const;
+protected:
+ FX_DWORD m_line;
+ XFA_FM_TOKEN m_op;
+};
+class CXFA_FMNullExpression : public CXFA_FMSimpleExpression
+{
+public:
+ CXFA_FMNullExpression(FX_DWORD line);
+ virtual ~CXFA_FMNullExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMNumberExpression : public CXFA_FMSimpleExpression
+{
+public:
+ CXFA_FMNumberExpression(FX_DWORD line, CFX_WideStringC wsNumber);
+ virtual ~CXFA_FMNumberExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ CFX_WideStringC m_wsNumber;
+};
+class CXFA_FMStringExpression : public CXFA_FMSimpleExpression
+{
+public:
+ CXFA_FMStringExpression(FX_DWORD line, CFX_WideStringC wsString);
+ virtual ~CXFA_FMStringExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ CFX_WideStringC m_wsString;
+};
+class CXFA_FMIdentifierExpressionn : public CXFA_FMSimpleExpression
+{
+public:
+ CXFA_FMIdentifierExpressionn(FX_DWORD line, CFX_WideStringC wsIdentifier);
+ virtual ~CXFA_FMIdentifierExpressionn() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ CFX_WideStringC m_wsIdentifier;
+};
+class CXFA_FMUnaryExpression : public CXFA_FMSimpleExpression
+{
+public:
+ CXFA_FMUnaryExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp);
+ virtual ~CXFA_FMUnaryExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ CXFA_FMSimpleExpression *m_pExp;
+};
+class CXFA_FMBinExpression : public CXFA_FMSimpleExpression
+{
+public:
+ CXFA_FMBinExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMBinExpression();
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ CXFA_FMSimpleExpression *m_pExp1;
+ CXFA_FMSimpleExpression *m_pExp2;
+};
+class CXFA_FMAssignExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMAssignExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMAssignExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+ virtual void ToImpliedReturnJS(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMLogicalOrExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMLogicalOrExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMLogicalOrExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMLogicalAndExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMLogicalAndExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMLogicalAndExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMEqualityExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMEqualityExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMEqualityExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMRelationalExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMRelationalExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMRelationalExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMAdditiveExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMAdditiveExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMAdditiveExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMMultiplicativeExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMMultiplicativeExpression(FX_DWORD line, XFA_FM_TOKEN op, CXFA_FMSimpleExpression *pExp1, CXFA_FMSimpleExpression *pExp2);
+ virtual ~CXFA_FMMultiplicativeExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMPosExpression : public CXFA_FMUnaryExpression
+{
+public:
+ CXFA_FMPosExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp);
+ virtual ~CXFA_FMPosExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMNegExpression : public CXFA_FMUnaryExpression
+{
+public:
+ CXFA_FMNegExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp);
+ virtual ~CXFA_FMNegExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMNotExpression : public CXFA_FMUnaryExpression
+{
+public:
+ CXFA_FMNotExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp);
+ virtual ~CXFA_FMNotExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+};
+class CXFA_FMCallExpression : public CXFA_FMUnaryExpression
+{
+public:
+ CXFA_FMCallExpression(FX_DWORD line, CXFA_FMSimpleExpression *pExp, CFX_PtrArray *pArguments, FX_BOOL bIsSomMethod);
+ virtual ~CXFA_FMCallExpression();
+ virtual FX_BOOL IsBuildInFunc(CFX_WideTextBuf& funcName);
+ virtual FX_DWORD IsSomMethodWithObjPara(FX_WSTR methodName);
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+private:
+ FX_BOOL m_bIsSomMethod;
+ CFX_PtrArray *m_pArguments;
+};
+class CXFA_FMDotAccessorExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMDotAccessorExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessor, XFA_FM_TOKEN op,
+ CFX_WideStringC wsIdentifier, CXFA_FMSimpleExpression *pIndexExp);
+ virtual ~CXFA_FMDotAccessorExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ CFX_WideStringC m_wsIdentifier;
+};
+class CXFA_FMIndexExpression : public CXFA_FMUnaryExpression
+{
+public:
+ CXFA_FMIndexExpression(FX_DWORD line, XFA_FM_AccessorIndex accessorIndex, CXFA_FMSimpleExpression *pIndexExp, FX_BOOL bIsStarIndex);
+ virtual ~CXFA_FMIndexExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ XFA_FM_AccessorIndex m_accessorIndex;
+ FX_BOOL m_bIsStarIndex;
+};
+class CXFA_FMDotDotAccessorExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMDotDotAccessorExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessor, XFA_FM_TOKEN op,
+ CFX_WideStringC wsIdentifier, CXFA_FMSimpleExpression *pIndexExp);
+ virtual ~CXFA_FMDotDotAccessorExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+ CFX_WideStringC m_wsIdentifier;
+};
+class CXFA_FMMethodCallExpression : public CXFA_FMBinExpression
+{
+public:
+ CXFA_FMMethodCallExpression(FX_DWORD line, CXFA_FMSimpleExpression *pAccessorExp1, CXFA_FMSimpleExpression *pCallExp);
+ virtual ~CXFA_FMMethodCallExpression() {};
+ virtual void ToJavaScript(CFX_WideTextBuf& javascript);
+protected:
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_basic_data.cpp b/xfa/src/fxfa/src/parser/xfa_basic_data.cpp
new file mode 100644
index 0000000000..c7508cbe99
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_basic_data.cpp
@@ -0,0 +1,1429 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_basic_imp.h"
+#include "xfa_script_datawindow.h"
+#include "xfa_script_eventpseudomodel.h"
+#include "xfa_script_hostpseudomodel.h"
+#include "xfa_script_logpseudomodel.h"
+#include "xfa_script_layoutpseudomodel.h"
+#include "xfa_script_signaturepseudomodel.h"
+extern const XFA_ATTRIBUTEENUMINFO g_XFAEnumData[] = {
+ {0x2a, (FX_LPCWSTR)L"*", XFA_ATTRIBUTEENUM_Asterisk}, {0x2f, (FX_LPCWSTR)L"/", XFA_ATTRIBUTEENUM_Slash}, {0x5c, (FX_LPCWSTR)L"\\", XFA_ATTRIBUTEENUM_Backslash},
+ {0x239bd, (FX_LPCWSTR)L"on", XFA_ATTRIBUTEENUM_On}, {0x25356, (FX_LPCWSTR)L"tb", XFA_ATTRIBUTEENUM_Tb}, {0x25885, (FX_LPCWSTR)L"up", XFA_ATTRIBUTEENUM_Up},
+ {0x91b281, (FX_LPCWSTR)L"metaData", XFA_ATTRIBUTEENUM_MetaData}, {0x1f8dedb, (FX_LPCWSTR)L"delegate", XFA_ATTRIBUTEENUM_Delegate}, {0x2a6c55a, (FX_LPCWSTR)L"postSubmit", XFA_ATTRIBUTEENUM_PostSubmit},
+ {0x31b19c1, (FX_LPCWSTR)L"name", XFA_ATTRIBUTEENUM_Name}, {0x378a38a, (FX_LPCWSTR)L"cross", XFA_ATTRIBUTEENUM_Cross}, {0x3848b3f, (FX_LPCWSTR)L"next", XFA_ATTRIBUTEENUM_Next},
+ {0x48b6670, (FX_LPCWSTR)L"none", XFA_ATTRIBUTEENUM_None}, {0x51aafe5, (FX_LPCWSTR)L"shortEdge", XFA_ATTRIBUTEENUM_ShortEdge}, {0x55264c4, (FX_LPCWSTR)L"1mod10_1mod11", XFA_ATTRIBUTEENUM_1mod10_1mod11},
+ {0x5a5c519, (FX_LPCWSTR)L"height", XFA_ATTRIBUTEENUM_Height}, {0x89ce549, (FX_LPCWSTR)L"crossDiagonal", XFA_ATTRIBUTEENUM_CrossDiagonal}, {0x9f9d0f9, (FX_LPCWSTR)L"all", XFA_ATTRIBUTEENUM_All},
+ {0x9f9db48, (FX_LPCWSTR)L"any", XFA_ATTRIBUTEENUM_Any}, {0xa126261, (FX_LPCWSTR)L"toRight", XFA_ATTRIBUTEENUM_ToRight}, {0xa36de29, (FX_LPCWSTR)L"matchTemplate", XFA_ATTRIBUTEENUM_MatchTemplate},
+ {0xa48d040, (FX_LPCWSTR)L"dpl", XFA_ATTRIBUTEENUM_Dpl}, {0xa559c05, (FX_LPCWSTR)L"invisible", XFA_ATTRIBUTEENUM_Invisible}, {0xa7d48e3, (FX_LPCWSTR)L"fit", XFA_ATTRIBUTEENUM_Fit},
+ {0xa8a8f80, (FX_LPCWSTR)L"width", XFA_ATTRIBUTEENUM_Width}, {0xab466bb, (FX_LPCWSTR)L"preSubmit", XFA_ATTRIBUTEENUM_PreSubmit}, {0xacc5785, (FX_LPCWSTR)L"ipl", XFA_ATTRIBUTEENUM_Ipl},
+ {0xafab0f8, (FX_LPCWSTR)L"flateCompress", XFA_ATTRIBUTEENUM_FlateCompress}, {0xb355816, (FX_LPCWSTR)L"med", XFA_ATTRIBUTEENUM_Med}, {0xb69ef77, (FX_LPCWSTR)L"odd", XFA_ATTRIBUTEENUM_Odd},
+ {0xb69f9bb, (FX_LPCWSTR)L"off", XFA_ATTRIBUTEENUM_Off}, {0xb843dba, (FX_LPCWSTR)L"pdf", XFA_ATTRIBUTEENUM_Pdf}, {0xbb912b8, (FX_LPCWSTR)L"row", XFA_ATTRIBUTEENUM_Row},
+ {0xbedaf33, (FX_LPCWSTR)L"top", XFA_ATTRIBUTEENUM_Top}, {0xc56afcc, (FX_LPCWSTR)L"xdp", XFA_ATTRIBUTEENUM_Xdp}, {0xc56ba02, (FX_LPCWSTR)L"xfd", XFA_ATTRIBUTEENUM_Xfd},
+ {0xc56ddf1, (FX_LPCWSTR)L"xml", XFA_ATTRIBUTEENUM_Xml}, {0xc8b65f3, (FX_LPCWSTR)L"zip", XFA_ATTRIBUTEENUM_Zip}, {0xc8b89d6, (FX_LPCWSTR)L"zpl", XFA_ATTRIBUTEENUM_Zpl},
+ {0xf55d7ee, (FX_LPCWSTR)L"visible", XFA_ATTRIBUTEENUM_Visible}, {0xfe3596a, (FX_LPCWSTR)L"exclude", XFA_ATTRIBUTEENUM_Exclude}, {0x109d7ce7, (FX_LPCWSTR)L"mouseEnter", XFA_ATTRIBUTEENUM_MouseEnter},
+ {0x10f1bc0c, (FX_LPCWSTR)L"pair", XFA_ATTRIBUTEENUM_Pair}, {0x1154efe6, (FX_LPCWSTR)L"filter", XFA_ATTRIBUTEENUM_Filter}, {0x125bc94b, (FX_LPCWSTR)L"moveLast", XFA_ATTRIBUTEENUM_MoveLast},
+ {0x12e1f1f0, (FX_LPCWSTR)L"exportAndImport", XFA_ATTRIBUTEENUM_ExportAndImport}, {0x13000c60, (FX_LPCWSTR)L"push", XFA_ATTRIBUTEENUM_Push}, {0x138ee315, (FX_LPCWSTR)L"portrait", XFA_ATTRIBUTEENUM_Portrait},
+ {0x14da2125, (FX_LPCWSTR)L"default", XFA_ATTRIBUTEENUM_Default}, {0x157749a5, (FX_LPCWSTR)L"storedProc", XFA_ATTRIBUTEENUM_StoredProc}, {0x16641198, (FX_LPCWSTR)L"stayBOF", XFA_ATTRIBUTEENUM_StayBOF},
+ {0x16b2fc5b, (FX_LPCWSTR)L"stayEOF", XFA_ATTRIBUTEENUM_StayEOF}, {0x17fad373, (FX_LPCWSTR)L"postPrint", XFA_ATTRIBUTEENUM_PostPrint}, {0x193207d0, (FX_LPCWSTR)L"usCarrier", XFA_ATTRIBUTEENUM_UsCarrier},
+ {0x193ade3e, (FX_LPCWSTR)L"right", XFA_ATTRIBUTEENUM_Right}, {0x1bfc72d9, (FX_LPCWSTR)L"preOpen", XFA_ATTRIBUTEENUM_PreOpen}, {0x1cc9317a, (FX_LPCWSTR)L"actual", XFA_ATTRIBUTEENUM_Actual},
+ {0x1f31df1e, (FX_LPCWSTR)L"rest", XFA_ATTRIBUTEENUM_Rest}, {0x1fb1bf14, (FX_LPCWSTR)L"topCenter", XFA_ATTRIBUTEENUM_TopCenter}, {0x207de667, (FX_LPCWSTR)L"standardSymbol", XFA_ATTRIBUTEENUM_StandardSymbol},
+ {0x2196a452, (FX_LPCWSTR)L"initialize", XFA_ATTRIBUTEENUM_Initialize}, {0x23bd40c7, (FX_LPCWSTR)L"justifyAll", XFA_ATTRIBUTEENUM_JustifyAll}, {0x247cf3e9, (FX_LPCWSTR)L"normal", XFA_ATTRIBUTEENUM_Normal},
+ {0x25aa946b, (FX_LPCWSTR)L"landscape", XFA_ATTRIBUTEENUM_Landscape}, {0x2739b5c9, (FX_LPCWSTR)L"nonInteractive", XFA_ATTRIBUTEENUM_NonInteractive}, {0x27410f03, (FX_LPCWSTR)L"mouseExit", XFA_ATTRIBUTEENUM_MouseExit},
+ {0x2854e62c, (FX_LPCWSTR)L"minus", XFA_ATTRIBUTEENUM_Minus}, {0x287e936a, (FX_LPCWSTR)L"diagonalLeft", XFA_ATTRIBUTEENUM_DiagonalLeft}, {0x2972a98f, (FX_LPCWSTR)L"simplexPaginated", XFA_ATTRIBUTEENUM_SimplexPaginated},
+ {0x29d8225f, (FX_LPCWSTR)L"document", XFA_ATTRIBUTEENUM_Document}, {0x2a9d3016, (FX_LPCWSTR)L"warning", XFA_ATTRIBUTEENUM_Warning}, {0x2b35b6d9, (FX_LPCWSTR)L"auto", XFA_ATTRIBUTEENUM_Auto},
+ {0x2c1653d9, (FX_LPCWSTR)L"below", XFA_ATTRIBUTEENUM_Below}, {0x2c1f0540, (FX_LPCWSTR)L"bottomLeft", XFA_ATTRIBUTEENUM_BottomLeft}, {0x2c44e816, (FX_LPCWSTR)L"bottomCenter", XFA_ATTRIBUTEENUM_BottomCenter},
+ {0x2cd3e9f3, (FX_LPCWSTR)L"tcpl", XFA_ATTRIBUTEENUM_Tcpl}, {0x2d08af85, (FX_LPCWSTR)L"text", XFA_ATTRIBUTEENUM_Text}, {0x2dc478eb, (FX_LPCWSTR)L"grouping", XFA_ATTRIBUTEENUM_Grouping},
+ {0x2ef3afdd, (FX_LPCWSTR)L"secureSymbol", XFA_ATTRIBUTEENUM_SecureSymbol}, {0x2f2dd29a, (FX_LPCWSTR)L"preExecute", XFA_ATTRIBUTEENUM_PreExecute}, {0x33c43dec, (FX_LPCWSTR)L"docClose", XFA_ATTRIBUTEENUM_DocClose},
+ {0x33f25bb5, (FX_LPCWSTR)L"keyset", XFA_ATTRIBUTEENUM_Keyset}, {0x34e363da, (FX_LPCWSTR)L"vertical", XFA_ATTRIBUTEENUM_Vertical}, {0x361fa1b6, (FX_LPCWSTR)L"preSave", XFA_ATTRIBUTEENUM_PreSave},
+ {0x36f1c6d8, (FX_LPCWSTR)L"preSign", XFA_ATTRIBUTEENUM_PreSign}, {0x399f02b5, (FX_LPCWSTR)L"bottom", XFA_ATTRIBUTEENUM_Bottom}, {0x3b0ab096, (FX_LPCWSTR)L"toTop", XFA_ATTRIBUTEENUM_ToTop},
+ {0x3c752495, (FX_LPCWSTR)L"verify", XFA_ATTRIBUTEENUM_Verify}, {0x3ce05d68, (FX_LPCWSTR)L"first", XFA_ATTRIBUTEENUM_First}, {0x3ecead94, (FX_LPCWSTR)L"contentArea", XFA_ATTRIBUTEENUM_ContentArea},
+ {0x40623b5b, (FX_LPCWSTR)L"solid", XFA_ATTRIBUTEENUM_Solid}, {0x42c6cd8d, (FX_LPCWSTR)L"pessimistic", XFA_ATTRIBUTEENUM_Pessimistic}, {0x43ddc6bf, (FX_LPCWSTR)L"duplexPaginated", XFA_ATTRIBUTEENUM_DuplexPaginated},
+ {0x442f68c8, (FX_LPCWSTR)L"round", XFA_ATTRIBUTEENUM_Round}, {0x45efb847, (FX_LPCWSTR)L"remerge", XFA_ATTRIBUTEENUM_Remerge}, {0x46972265, (FX_LPCWSTR)L"ordered", XFA_ATTRIBUTEENUM_Ordered},
+ {0x46f95531, (FX_LPCWSTR)L"percent", XFA_ATTRIBUTEENUM_Percent}, {0x46fd25ae, (FX_LPCWSTR)L"even", XFA_ATTRIBUTEENUM_Even}, {0x4731d6ba, (FX_LPCWSTR)L"exit", XFA_ATTRIBUTEENUM_Exit},
+ {0x4977356b, (FX_LPCWSTR)L"toolTip", XFA_ATTRIBUTEENUM_ToolTip}, {0x49b980ee, (FX_LPCWSTR)L"orderedOccurrence", XFA_ATTRIBUTEENUM_OrderedOccurrence}, {0x4a7e2dfe, (FX_LPCWSTR)L"readOnly", XFA_ATTRIBUTEENUM_ReadOnly},
+ {0x4c4e8acb, (FX_LPCWSTR)L"currency", XFA_ATTRIBUTEENUM_Currency}, {0x4dcf25f8, (FX_LPCWSTR)L"concat", XFA_ATTRIBUTEENUM_Concat}, {0x4febb826, (FX_LPCWSTR)L"Thai", XFA_ATTRIBUTEENUM_Thai},
+ {0x50ef95b2, (FX_LPCWSTR)L"embossed", XFA_ATTRIBUTEENUM_Embossed}, {0x516e35ce, (FX_LPCWSTR)L"formdata", XFA_ATTRIBUTEENUM_Formdata}, {0x52fa6f0e, (FX_LPCWSTR)L"Greek", XFA_ATTRIBUTEENUM_Greek},
+ {0x54034c2f, (FX_LPCWSTR)L"decimal", XFA_ATTRIBUTEENUM_Decimal}, {0x542c7300, (FX_LPCWSTR)L"select", XFA_ATTRIBUTEENUM_Select}, {0x551f0ae5, (FX_LPCWSTR)L"longEdge", XFA_ATTRIBUTEENUM_LongEdge},
+ {0x55520a8a, (FX_LPCWSTR)L"protected", XFA_ATTRIBUTEENUM_Protected}, {0x559f76f3, (FX_LPCWSTR)L"bottomRight", XFA_ATTRIBUTEENUM_BottomRight}, {0x568cb500, (FX_LPCWSTR)L"zero", XFA_ATTRIBUTEENUM_Zero},
+ {0x56bcecb7, (FX_LPCWSTR)L"forwardOnly", XFA_ATTRIBUTEENUM_ForwardOnly}, {0x56bf456b, (FX_LPCWSTR)L"docReady", XFA_ATTRIBUTEENUM_DocReady}, {0x573cb40c, (FX_LPCWSTR)L"hidden", XFA_ATTRIBUTEENUM_Hidden},
+ {0x582e3424, (FX_LPCWSTR)L"include", XFA_ATTRIBUTEENUM_Include}, {0x58a3dd29, (FX_LPCWSTR)L"dashed", XFA_ATTRIBUTEENUM_Dashed}, {0x5955b22b, (FX_LPCWSTR)L"multiSelect", XFA_ATTRIBUTEENUM_MultiSelect},
+ {0x598d5c53, (FX_LPCWSTR)L"inactive", XFA_ATTRIBUTEENUM_Inactive}, {0x59c8f27d, (FX_LPCWSTR)L"embed", XFA_ATTRIBUTEENUM_Embed}, {0x5e7555e8, (FX_LPCWSTR)L"static", XFA_ATTRIBUTEENUM_Static},
+ {0x606d4def, (FX_LPCWSTR)L"onEntry", XFA_ATTRIBUTEENUM_OnEntry}, {0x6195eafb, (FX_LPCWSTR)L"Cyrillic", XFA_ATTRIBUTEENUM_Cyrillic}, {0x6491b0f3, (FX_LPCWSTR)L"nonBlank", XFA_ATTRIBUTEENUM_NonBlank},
+ {0x67bef031, (FX_LPCWSTR)L"topRight", XFA_ATTRIBUTEENUM_TopRight}, {0x67df5ebd, (FX_LPCWSTR)L"Hebrew", XFA_ATTRIBUTEENUM_Hebrew}, {0x6aea98be, (FX_LPCWSTR)L"topLeft", XFA_ATTRIBUTEENUM_TopLeft},
+ {0x6c51afc1, (FX_LPCWSTR)L"center", XFA_ATTRIBUTEENUM_Center}, {0x7145e6bf, (FX_LPCWSTR)L"moveFirst", XFA_ATTRIBUTEENUM_MoveFirst}, {0x7375465c, (FX_LPCWSTR)L"diamond", XFA_ATTRIBUTEENUM_Diamond},
+ {0x7461aef4, (FX_LPCWSTR)L"pageOdd", XFA_ATTRIBUTEENUM_PageOdd}, {0x75f8aeb2, (FX_LPCWSTR)L"1mod10", XFA_ATTRIBUTEENUM_1mod10}, {0x76d708e0, (FX_LPCWSTR)L"Korean", XFA_ATTRIBUTEENUM_Korean},
+ {0x789f14d7, (FX_LPCWSTR)L"aboveEmbedded", XFA_ATTRIBUTEENUM_AboveEmbedded}, {0x792ea39f, (FX_LPCWSTR)L"zipCompress", XFA_ATTRIBUTEENUM_ZipCompress}, {0x7a5b7193, (FX_LPCWSTR)L"numeric", XFA_ATTRIBUTEENUM_Numeric},
+ {0x7abec0d2, (FX_LPCWSTR)L"circle", XFA_ATTRIBUTEENUM_Circle}, {0x7afbba38, (FX_LPCWSTR)L"toBottom", XFA_ATTRIBUTEENUM_ToBottom}, {0x7b95e661, (FX_LPCWSTR)L"inverted", XFA_ATTRIBUTEENUM_Inverted},
+ {0x7baca2e3, (FX_LPCWSTR)L"update", XFA_ATTRIBUTEENUM_Update}, {0x7eb5da2c, (FX_LPCWSTR)L"isoname", XFA_ATTRIBUTEENUM_Isoname}, {0x7f6fd3d7, (FX_LPCWSTR)L"server", XFA_ATTRIBUTEENUM_Server},
+ {0x814f82b5, (FX_LPCWSTR)L"position", XFA_ATTRIBUTEENUM_Position}, {0x82deacf0, (FX_LPCWSTR)L"middleCenter", XFA_ATTRIBUTEENUM_MiddleCenter}, {0x83a49dc6, (FX_LPCWSTR)L"optional", XFA_ATTRIBUTEENUM_Optional},
+ {0x861a116f, (FX_LPCWSTR)L"usePrinterSetting", XFA_ATTRIBUTEENUM_UsePrinterSetting}, {0x86701ce0, (FX_LPCWSTR)L"outline", XFA_ATTRIBUTEENUM_Outline}, {0x8808385e, (FX_LPCWSTR)L"indexChange", XFA_ATTRIBUTEENUM_IndexChange},
+ {0x891f4606, (FX_LPCWSTR)L"change", XFA_ATTRIBUTEENUM_Change}, {0x89939f36, (FX_LPCWSTR)L"pageArea", XFA_ATTRIBUTEENUM_PageArea}, {0x8b5c3b25, (FX_LPCWSTR)L"once", XFA_ATTRIBUTEENUM_Once},
+ {0x8b5c6962, (FX_LPCWSTR)L"only", XFA_ATTRIBUTEENUM_Only}, {0x8b90e1f2, (FX_LPCWSTR)L"open", XFA_ATTRIBUTEENUM_Open}, {0x8bcfe96e, (FX_LPCWSTR)L"caption", XFA_ATTRIBUTEENUM_Caption},
+ {0x8ce83ef8, (FX_LPCWSTR)L"raised", XFA_ATTRIBUTEENUM_Raised}, {0x8d269cae, (FX_LPCWSTR)L"justify", XFA_ATTRIBUTEENUM_Justify}, {0x8fd520dc, (FX_LPCWSTR)L"refAndDescendants", XFA_ATTRIBUTEENUM_RefAndDescendants},
+ {0x9041d4b0, (FX_LPCWSTR)L"short", XFA_ATTRIBUTEENUM_Short}, {0x90c94426, (FX_LPCWSTR)L"pageFront", XFA_ATTRIBUTEENUM_PageFront}, {0x936beee5, (FX_LPCWSTR)L"monospace", XFA_ATTRIBUTEENUM_Monospace},
+ {0x947fa00f, (FX_LPCWSTR)L"middle", XFA_ATTRIBUTEENUM_Middle}, {0x9528a7b4, (FX_LPCWSTR)L"prePrint", XFA_ATTRIBUTEENUM_PrePrint}, {0x959ab231, (FX_LPCWSTR)L"always", XFA_ATTRIBUTEENUM_Always},
+ {0x96d61bf0, (FX_LPCWSTR)L"unknown", XFA_ATTRIBUTEENUM_Unknown}, {0x997194ee, (FX_LPCWSTR)L"toLeft", XFA_ATTRIBUTEENUM_ToLeft}, {0x9a83a3cd, (FX_LPCWSTR)L"above", XFA_ATTRIBUTEENUM_Above},
+ {0x9d0d71c7, (FX_LPCWSTR)L"dashDot", XFA_ATTRIBUTEENUM_DashDot}, {0x9df56f3e, (FX_LPCWSTR)L"gregorian", XFA_ATTRIBUTEENUM_Gregorian}, {0x9f6723fd, (FX_LPCWSTR)L"Roman", XFA_ATTRIBUTEENUM_Roman},
+ {0x9f693b21, (FX_LPCWSTR)L"mouseDown", XFA_ATTRIBUTEENUM_MouseDown}, {0xa1429b36, (FX_LPCWSTR)L"symbol", XFA_ATTRIBUTEENUM_Symbol}, {0xa5aa45cb, (FX_LPCWSTR)L"pageEven", XFA_ATTRIBUTEENUM_PageEven},
+ {0xa68635f1, (FX_LPCWSTR)L"sign", XFA_ATTRIBUTEENUM_Sign}, {0xa7315093, (FX_LPCWSTR)L"addNew", XFA_ATTRIBUTEENUM_AddNew}, {0xa7a773fa, (FX_LPCWSTR)L"star", XFA_ATTRIBUTEENUM_Star},
+ {0xa7d57b45, (FX_LPCWSTR)L"optimistic", XFA_ATTRIBUTEENUM_Optimistic}, {0xa8077321, (FX_LPCWSTR)L"rl-tb", XFA_ATTRIBUTEENUM_Rl_tb}, {0xa8f1468d, (FX_LPCWSTR)L"middleRight", XFA_ATTRIBUTEENUM_MiddleRight},
+ {0xaa84a1f1, (FX_LPCWSTR)L"maintain", XFA_ATTRIBUTEENUM_Maintain}, {0xab40b12c, (FX_LPCWSTR)L"package", XFA_ATTRIBUTEENUM_Package}, {0xac8b4d85, (FX_LPCWSTR)L"SimplifiedChinese", XFA_ATTRIBUTEENUM_SimplifiedChinese},
+ {0xadae6744, (FX_LPCWSTR)L"toCenter", XFA_ATTRIBUTEENUM_ToCenter}, {0xb0129df1, (FX_LPCWSTR)L"back", XFA_ATTRIBUTEENUM_Back}, {0xb0f088cf, (FX_LPCWSTR)L"unspecified", XFA_ATTRIBUTEENUM_Unspecified},
+ {0xb1271067, (FX_LPCWSTR)L"batchOptimistic", XFA_ATTRIBUTEENUM_BatchOptimistic}, {0xb18313a1, (FX_LPCWSTR)L"bold", XFA_ATTRIBUTEENUM_Bold}, {0xb1833cad, (FX_LPCWSTR)L"both", XFA_ATTRIBUTEENUM_Both},
+ {0xb221123f, (FX_LPCWSTR)L"butt", XFA_ATTRIBUTEENUM_Butt}, {0xb40c36bf, (FX_LPCWSTR)L"client", XFA_ATTRIBUTEENUM_Client}, {0xb56c7053, (FX_LPCWSTR)L"2mod10", XFA_ATTRIBUTEENUM_2mod10},
+ {0xb683a345, (FX_LPCWSTR)L"imageOnly", XFA_ATTRIBUTEENUM_ImageOnly}, {0xb7732dea, (FX_LPCWSTR)L"horizontal", XFA_ATTRIBUTEENUM_Horizontal}, {0xb88652a4, (FX_LPCWSTR)L"dotted", XFA_ATTRIBUTEENUM_Dotted},
+ {0xbb2f2880, (FX_LPCWSTR)L"userControl", XFA_ATTRIBUTEENUM_UserControl}, {0xbbb79c5d, (FX_LPCWSTR)L"diagonalRight", XFA_ATTRIBUTEENUM_DiagonalRight}, {0xbd077154, (FX_LPCWSTR)L"consumeData", XFA_ATTRIBUTEENUM_ConsumeData},
+ {0xbd3fb11e, (FX_LPCWSTR)L"check", XFA_ATTRIBUTEENUM_Check}, {0xbde9abda, (FX_LPCWSTR)L"data", XFA_ATTRIBUTEENUM_Data}, {0xbf5a02d8, (FX_LPCWSTR)L"down", XFA_ATTRIBUTEENUM_Down},
+ {0xbf7450ee, (FX_LPCWSTR)L"sansSerif", XFA_ATTRIBUTEENUM_SansSerif}, {0xc02d649f, (FX_LPCWSTR)L"inline", XFA_ATTRIBUTEENUM_Inline}, {0xc11a9e3a, (FX_LPCWSTR)L"TraditionalChinese", XFA_ATTRIBUTEENUM_TraditionalChinese},
+ {0xc16169d8, (FX_LPCWSTR)L"warn", XFA_ATTRIBUTEENUM_Warn}, {0xc16f071f, (FX_LPCWSTR)L"refOnly", XFA_ATTRIBUTEENUM_RefOnly}, {0xc27c8ba5, (FX_LPCWSTR)L"interactiveForms", XFA_ATTRIBUTEENUM_InteractiveForms},
+ {0xc2d1b15c, (FX_LPCWSTR)L"word", XFA_ATTRIBUTEENUM_Word}, {0xc3621288, (FX_LPCWSTR)L"unordered", XFA_ATTRIBUTEENUM_Unordered}, {0xc5251981, (FX_LPCWSTR)L"required", XFA_ATTRIBUTEENUM_Required},
+ {0xc7088e7d, (FX_LPCWSTR)L"importOnly", XFA_ATTRIBUTEENUM_ImportOnly}, {0xc72cf0e3, (FX_LPCWSTR)L"belowEmbedded", XFA_ATTRIBUTEENUM_BelowEmbedded}, {0xc819cf07, (FX_LPCWSTR)L"Japanese", XFA_ATTRIBUTEENUM_Japanese},
+ {0xcdce56b3, (FX_LPCWSTR)L"full", XFA_ATTRIBUTEENUM_Full}, {0xce0122e3, (FX_LPCWSTR)L"rl-row", XFA_ATTRIBUTEENUM_Rl_row}, {0xcf7d71f1, (FX_LPCWSTR)L"Vietnamese", XFA_ATTRIBUTEENUM_Vietnamese},
+ {0xcfde3e09, (FX_LPCWSTR)L"EastEuropeanRoman", XFA_ATTRIBUTEENUM_EastEuropeanRoman}, {0xd576d08e, (FX_LPCWSTR)L"mouseUp", XFA_ATTRIBUTEENUM_MouseUp}, {0xd7a92904, (FX_LPCWSTR)L"exportOnly", XFA_ATTRIBUTEENUM_ExportOnly},
+ {0xd8ed1467, (FX_LPCWSTR)L"clear", XFA_ATTRIBUTEENUM_Clear}, {0xd95657a6, (FX_LPCWSTR)L"click", XFA_ATTRIBUTEENUM_Click}, {0xd96c7de5, (FX_LPCWSTR)L"base64", XFA_ATTRIBUTEENUM_Base64},
+ {0xd9f47f36, (FX_LPCWSTR)L"close", XFA_ATTRIBUTEENUM_Close}, {0xdb075bde, (FX_LPCWSTR)L"host", XFA_ATTRIBUTEENUM_Host}, {0xdb103411, (FX_LPCWSTR)L"global", XFA_ATTRIBUTEENUM_Global},
+ {0xdb647188, (FX_LPCWSTR)L"blank", XFA_ATTRIBUTEENUM_Blank}, {0xdb9be968, (FX_LPCWSTR)L"table", XFA_ATTRIBUTEENUM_Table}, {0xdf590fbb, (FX_LPCWSTR)L"import", XFA_ATTRIBUTEENUM_Import},
+ {0xe0e573fb, (FX_LPCWSTR)L"custom", XFA_ATTRIBUTEENUM_Custom}, {0xe0ecc79a, (FX_LPCWSTR)L"middleLeft", XFA_ATTRIBUTEENUM_MiddleLeft}, {0xe1452019, (FX_LPCWSTR)L"postExecute", XFA_ATTRIBUTEENUM_PostExecute},
+ {0xe1911d98, (FX_LPCWSTR)L"radix", XFA_ATTRIBUTEENUM_Radix}, {0xe25fa7b8, (FX_LPCWSTR)L"postOpen", XFA_ATTRIBUTEENUM_PostOpen}, {0xe28dce7e, (FX_LPCWSTR)L"enter", XFA_ATTRIBUTEENUM_Enter},
+ {0xe2c44de4, (FX_LPCWSTR)L"ignore", XFA_ATTRIBUTEENUM_Ignore}, {0xe2cd8c61, (FX_LPCWSTR)L"lr-tb", XFA_ATTRIBUTEENUM_Lr_tb}, {0xe2da8336, (FX_LPCWSTR)L"fantasy", XFA_ATTRIBUTEENUM_Fantasy},
+ {0xe31d5396, (FX_LPCWSTR)L"italic", XFA_ATTRIBUTEENUM_Italic}, {0xe7ada113, (FX_LPCWSTR)L"author", XFA_ATTRIBUTEENUM_Author}, {0xe8e7cc18, (FX_LPCWSTR)L"toEdge", XFA_ATTRIBUTEENUM_ToEdge},
+ {0xe97aa98b, (FX_LPCWSTR)L"choice", XFA_ATTRIBUTEENUM_Choice}, {0xeafd2a38, (FX_LPCWSTR)L"disabled", XFA_ATTRIBUTEENUM_Disabled}, {0xeb2b7972, (FX_LPCWSTR)L"crossHatch", XFA_ATTRIBUTEENUM_CrossHatch},
+ {0xeb2db2d7, (FX_LPCWSTR)L"dataRef", XFA_ATTRIBUTEENUM_DataRef}, {0xec35dc6e, (FX_LPCWSTR)L"dashDotDot", XFA_ATTRIBUTEENUM_DashDotDot}, {0xef85d351, (FX_LPCWSTR)L"square", XFA_ATTRIBUTEENUM_Square},
+ {0xf2102445, (FX_LPCWSTR)L"dynamic", XFA_ATTRIBUTEENUM_Dynamic}, {0xf272c7be, (FX_LPCWSTR)L"manual", XFA_ATTRIBUTEENUM_Manual}, {0xf2bbb64d, (FX_LPCWSTR)L"etched", XFA_ATTRIBUTEENUM_Etched},
+ {0xf3b8fc6c, (FX_LPCWSTR)L"validationState", XFA_ATTRIBUTEENUM_ValidationState}, {0xf42f2b81, (FX_LPCWSTR)L"cursive", XFA_ATTRIBUTEENUM_Cursive}, {0xf54481d4, (FX_LPCWSTR)L"last", XFA_ATTRIBUTEENUM_Last},
+ {0xf5ad782b, (FX_LPCWSTR)L"left", XFA_ATTRIBUTEENUM_Left}, {0xf616da2e, (FX_LPCWSTR)L"link", XFA_ATTRIBUTEENUM_Link}, {0xf6b4afb0, (FX_LPCWSTR)L"long", XFA_ATTRIBUTEENUM_Long},
+ {0xf8636460, (FX_LPCWSTR)L"internationalCarrier", XFA_ATTRIBUTEENUM_InternationalCarrier}, {0xf9fb37ac, (FX_LPCWSTR)L"PDF1.3", XFA_ATTRIBUTEENUM_PDF1_3}, {0xf9fb37af, (FX_LPCWSTR)L"PDF1.6", XFA_ATTRIBUTEENUM_PDF1_6},
+ {0xfbce7f19, (FX_LPCWSTR)L"serif", XFA_ATTRIBUTEENUM_Serif}, {0xfc82d695, (FX_LPCWSTR)L"postSave", XFA_ATTRIBUTEENUM_PostSave}, {0xfcef86b5, (FX_LPCWSTR)L"ready", XFA_ATTRIBUTEENUM_Ready},
+ {0xfd54fbb7, (FX_LPCWSTR)L"postSign", XFA_ATTRIBUTEENUM_PostSign}, {0xfdc0aae2, (FX_LPCWSTR)L"Arabic", XFA_ATTRIBUTEENUM_Arabic}, {0xfe06d2ca, (FX_LPCWSTR)L"error", XFA_ATTRIBUTEENUM_Error},
+ {0xfefc4885, (FX_LPCWSTR)L"urlencoded", XFA_ATTRIBUTEENUM_Urlencoded}, {0xff795ad2, (FX_LPCWSTR)L"lowered", XFA_ATTRIBUTEENUM_Lowered},
+};
+extern const FX_INT32 g_iXFAEnumCount = sizeof(g_XFAEnumData) / sizeof(XFA_ATTRIBUTEENUMINFO);
+static const CXFA_Measurement g_XFAMeasurementData[] = {
+ CXFA_Measurement(0, XFA_UNIT_In),
+ CXFA_Measurement(0, XFA_UNIT_Pt),
+ CXFA_Measurement(5, XFA_UNIT_Mm),
+ CXFA_Measurement(0.25, XFA_UNIT_Mm),
+ CXFA_Measurement(-1, XFA_UNIT_Unknown),
+ CXFA_Measurement(0, XFA_UNIT_Angle),
+ CXFA_Measurement(10, XFA_UNIT_Pt),
+ CXFA_Measurement(360, XFA_UNIT_Angle),
+ CXFA_Measurement(0.5, XFA_UNIT_Pt),
+};
+extern const XFA_ATTRIBUTEINFO g_XFAAttributeData[] = {
+ {0x68, (FX_LPCWSTR)L"h", XFA_ATTRIBUTE_H, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x77, (FX_LPCWSTR)L"w", XFA_ATTRIBUTE_W, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x78, (FX_LPCWSTR)L"x", XFA_ATTRIBUTE_X, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x79, (FX_LPCWSTR)L"y", XFA_ATTRIBUTE_Y, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x21aed, (FX_LPCWSTR)L"id", XFA_ATTRIBUTE_Id, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x25363, (FX_LPCWSTR)L"to", XFA_ATTRIBUTE_To, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Config, (FX_LPVOID)NULL},
+ {0xcb0ac9, (FX_LPCWSTR)L"lineThrough", XFA_ATTRIBUTE_LineThrough, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x2282c73, (FX_LPCWSTR)L"hAlign", XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Left},
+ {0x2c1c7f1, (FX_LPCWSTR)L"typeface", XFA_ATTRIBUTE_Typeface, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"Courier"},
+ {0x3106c3a, (FX_LPCWSTR)L"beforeTarget", XFA_ATTRIBUTE_BeforeTarget, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x31b19c1, (FX_LPCWSTR)L"name", XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Datasets | XFA_XDPPACKET_Form | XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x3848b3f, (FX_LPCWSTR)L"next", XFA_ATTRIBUTE_Next, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {0x43e349b, (FX_LPCWSTR)L"dataRowCount", XFA_ATTRIBUTE_DataRowCount, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x5518c25, (FX_LPCWSTR)L"break", XFA_ATTRIBUTE_Break, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Close},
+ {0x5ce6195, (FX_LPCWSTR)L"vScrollPolicy", XFA_ATTRIBUTE_VScrollPolicy, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Auto},
+ {0x8c74ae9, (FX_LPCWSTR)L"fontHorizontalScale", XFA_ATTRIBUTE_FontHorizontalScale, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"100%"},
+ {0x8d4f1c7, (FX_LPCWSTR)L"textIndent", XFA_ATTRIBUTE_TextIndent, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x97c1c65, (FX_LPCWSTR)L"context", XFA_ATTRIBUTE_Context, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_UNKNOWN, (FX_LPVOID)0},
+ {0x9876578, (FX_LPCWSTR)L"trayOut", XFA_ATTRIBUTE_TrayOut, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Auto},
+ {0xa2e3514, (FX_LPCWSTR)L"cap", XFA_ATTRIBUTE_Cap, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Square},
+ {0xb3543a6, (FX_LPCWSTR)L"max", XFA_ATTRIBUTE_Max, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xb356ca4, (FX_LPCWSTR)L"min", XFA_ATTRIBUTE_Min, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)1},
+ {0xbb8df5d, (FX_LPCWSTR)L"ref", XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xbb8f3df, (FX_LPCWSTR)L"rid", XFA_ATTRIBUTE_Rid, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xc080cd3, (FX_LPCWSTR)L"url", XFA_ATTRIBUTE_Url, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xc0811ed, (FX_LPCWSTR)L"use", XFA_ATTRIBUTE_Use, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xcfea02e, (FX_LPCWSTR)L"leftInset", XFA_ATTRIBUTE_LeftInset, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x1026c59d, (FX_LPCWSTR)L"widows", XFA_ATTRIBUTE_Widows, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x1059ec18, (FX_LPCWSTR)L"level", XFA_ATTRIBUTE_Level, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Config, (FX_LPVOID)0},
+ {0x1356caf8, (FX_LPCWSTR)L"bottomInset", XFA_ATTRIBUTE_BottomInset, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x13a08bdb, (FX_LPCWSTR)L"overflowTarget", XFA_ATTRIBUTE_OverflowTarget, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x1414d431, (FX_LPCWSTR)L"allowMacro", XFA_ATTRIBUTE_AllowMacro, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x14a32d52, (FX_LPCWSTR)L"pagePosition", XFA_ATTRIBUTE_PagePosition, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Any},
+ {0x1517dfa1, (FX_LPCWSTR)L"columnWidths", XFA_ATTRIBUTE_ColumnWidths, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x169134a1, (FX_LPCWSTR)L"overflowLeader", XFA_ATTRIBUTE_OverflowLeader, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x1b8dce3e, (FX_LPCWSTR)L"action", XFA_ATTRIBUTE_Action, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Include},
+ {0x1e459b8f, (FX_LPCWSTR)L"nonRepudiation", XFA_ATTRIBUTE_NonRepudiation, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x1ec8ab2c, (FX_LPCWSTR)L"rate", XFA_ATTRIBUTE_Rate, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)50},
+ {0x1ef3a64a, (FX_LPCWSTR)L"allowRichText", XFA_ATTRIBUTE_AllowRichText, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x2038c9b2, (FX_LPCWSTR)L"role", XFA_ATTRIBUTE_Role, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x20914367, (FX_LPCWSTR)L"overflowTrailer", XFA_ATTRIBUTE_OverflowTrailer, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x226ca8f1, (FX_LPCWSTR)L"operation", XFA_ATTRIBUTE_Operation, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x24d85167, (FX_LPCWSTR)L"timeout", XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_SourceSet, (FX_LPVOID)NULL},
+ {0x25764436, (FX_LPCWSTR)L"topInset", XFA_ATTRIBUTE_TopInset, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x25839852, (FX_LPCWSTR)L"access", XFA_ATTRIBUTE_Access, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Open},
+ {0x268b7ec1, (FX_LPCWSTR)L"commandType", XFA_ATTRIBUTE_CommandType, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet, (FX_LPVOID)XFA_ATTRIBUTEENUM_Unknown},
+ {0x28dee6e9, (FX_LPCWSTR)L"format", XFA_ATTRIBUTE_Format, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x28e17e91, (FX_LPCWSTR)L"dataPrep", XFA_ATTRIBUTE_DataPrep, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {0x292b88fe, (FX_LPCWSTR)L"widgetData", XFA_ATTRIBUTE_WidgetData, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_UNKNOWN, (FX_LPVOID)0},
+ {0x29418bb7, (FX_LPCWSTR)L"abbr", XFA_ATTRIBUTE_Abbr, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_LocaleSet, (FX_LPVOID)0},
+ {0x2a82d99c, (FX_LPCWSTR)L"marginRight", XFA_ATTRIBUTE_MarginRight, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x2b5df51e, (FX_LPCWSTR)L"dataDescription", XFA_ATTRIBUTE_DataDescription, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_ConnectionSet, (FX_LPVOID)NULL},
+ {0x2bb3f470, (FX_LPCWSTR)L"encipherOnly", XFA_ATTRIBUTE_EncipherOnly, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x2cd79033, (FX_LPCWSTR)L"kerningMode", XFA_ATTRIBUTE_KerningMode, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {0x2ee7678f, (FX_LPCWSTR)L"rotate", XFA_ATTRIBUTE_Rotate, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 5)},
+ {0x2f105f72, (FX_LPCWSTR)L"wordCharacterCount", XFA_ATTRIBUTE_WordCharacterCount, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)7},
+ {0x2f16a382, (FX_LPCWSTR)L"type", XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x34ae103c, (FX_LPCWSTR)L"reserve", XFA_ATTRIBUTE_Reserve, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 4)},
+ {0x3650557e, (FX_LPCWSTR)L"textLocation", XFA_ATTRIBUTE_TextLocation, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Below},
+ {0x39cdb0a2, (FX_LPCWSTR)L"priority", XFA_ATTRIBUTE_Priority, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Custom},
+ {0x3a0273a6, (FX_LPCWSTR)L"underline", XFA_ATTRIBUTE_Underline, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x3b582286, (FX_LPCWSTR)L"moduleWidth", XFA_ATTRIBUTE_ModuleWidth, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 3)},
+ {0x3d123c26, (FX_LPCWSTR)L"hyphenate", XFA_ATTRIBUTE_Hyphenate, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x3e7af94f, (FX_LPCWSTR)L"listen", XFA_ATTRIBUTE_Listen, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_RefOnly},
+ {0x4156ee3f, (FX_LPCWSTR)L"delimiter", XFA_ATTRIBUTE_Delimiter, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x42fed1fd, (FX_LPCWSTR)L"contentType", XFA_ATTRIBUTE_ContentType, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Datasets | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x453eaf38, (FX_LPCWSTR)L"startNew", XFA_ATTRIBUTE_StartNew, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x45a6daf8, (FX_LPCWSTR)L"eofAction", XFA_ATTRIBUTE_EofAction, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet, (FX_LPVOID)XFA_ATTRIBUTEENUM_MoveLast},
+ {0x47cfa43a, (FX_LPCWSTR)L"allowNeutral", XFA_ATTRIBUTE_AllowNeutral, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x47d03490, (FX_LPCWSTR)L"connection", XFA_ATTRIBUTE_Connection, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x4873c601, (FX_LPCWSTR)L"baselineShift", XFA_ATTRIBUTE_BaselineShift, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x4b319767, (FX_LPCWSTR)L"overlinePeriod", XFA_ATTRIBUTE_OverlinePeriod, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_All},
+ {0x4b8bc840, (FX_LPCWSTR)L"fracDigits", XFA_ATTRIBUTE_FracDigits, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)2},
+ {0x4ef3d02c, (FX_LPCWSTR)L"orientation", XFA_ATTRIBUTE_Orientation, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Portrait},
+ {0x4fdc3454, (FX_LPCWSTR)L"timeStamp", XFA_ATTRIBUTE_TimeStamp, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_XDP, (FX_LPVOID)NULL},
+ {0x52666f1c, (FX_LPCWSTR)L"printCheckDigit", XFA_ATTRIBUTE_PrintCheckDigit, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x534729c9, (FX_LPCWSTR)L"marginLeft", XFA_ATTRIBUTE_MarginLeft, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x5392ea58, (FX_LPCWSTR)L"stroke", XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Solid},
+ {0x5404d6df, (FX_LPCWSTR)L"moduleHeight", XFA_ATTRIBUTE_ModuleHeight, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 2)},
+ {0x54fa722c, (FX_LPCWSTR)L"transferEncoding", XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x552d9ad5, (FX_LPCWSTR)L"usage", XFA_ATTRIBUTE_Usage, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_ExportAndImport},
+ {0x570ce835, (FX_LPCWSTR)L"presence", XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Visible},
+ {0x5739d1ff, (FX_LPCWSTR)L"radixOffset", XFA_ATTRIBUTE_RadixOffset, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x577682ac, (FX_LPCWSTR)L"preserve", XFA_ATTRIBUTE_Preserve, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x58be2870, (FX_LPCWSTR)L"aliasNode", XFA_ATTRIBUTE_AliasNode, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_UNKNOWN, (FX_LPVOID)0},
+ {0x5a32e493, (FX_LPCWSTR)L"multiLine", XFA_ATTRIBUTE_MultiLine, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x5a50e9e6, (FX_LPCWSTR)L"version", XFA_ATTRIBUTE_Version, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x5ab23b6c, (FX_LPCWSTR)L"startChar", XFA_ATTRIBUTE_StartChar, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x5b707a35, (FX_LPCWSTR)L"scriptTest", XFA_ATTRIBUTE_ScriptTest, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Error},
+ {0x5c054755, (FX_LPCWSTR)L"startAngle", XFA_ATTRIBUTE_StartAngle, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 5)},
+ {0x5ec958c0, (FX_LPCWSTR)L"cursorType", XFA_ATTRIBUTE_CursorType, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet, (FX_LPVOID)XFA_ATTRIBUTEENUM_ForwardOnly},
+ {0x5f760b50, (FX_LPCWSTR)L"digitalSignature", XFA_ATTRIBUTE_DigitalSignature, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x60a61edd, (FX_LPCWSTR)L"codeType", XFA_ATTRIBUTE_CodeType, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x60d4c8b1, (FX_LPCWSTR)L"output", XFA_ATTRIBUTE_Output, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_ConnectionSet, (FX_LPVOID)NULL},
+ {0x64110ab5, (FX_LPCWSTR)L"bookendTrailer", XFA_ATTRIBUTE_BookendTrailer, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x65e30c67, (FX_LPCWSTR)L"imagingBBox", XFA_ATTRIBUTE_ImagingBBox, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"none"},
+ {0x66539c48, (FX_LPCWSTR)L"excludeInitialCap", XFA_ATTRIBUTE_ExcludeInitialCap, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x66642f8f, (FX_LPCWSTR)L"force", XFA_ATTRIBUTE_Force, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Config, (FX_LPVOID)NULL},
+ {0x69aa2292, (FX_LPCWSTR)L"crlSign", XFA_ATTRIBUTE_CrlSign, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x6a3405dd, (FX_LPCWSTR)L"previous", XFA_ATTRIBUTE_Previous, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {0x6a95c976, (FX_LPCWSTR)L"pushCharacterCount", XFA_ATTRIBUTE_PushCharacterCount, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)3},
+ {0x6b6ddcfb, (FX_LPCWSTR)L"nullTest", XFA_ATTRIBUTE_NullTest, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Disabled},
+ {0x6cfa828a, (FX_LPCWSTR)L"runAt", XFA_ATTRIBUTE_RunAt, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Client},
+ {0x731e0665, (FX_LPCWSTR)L"spaceBelow", XFA_ATTRIBUTE_SpaceBelow, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x74788f8b, (FX_LPCWSTR)L"sweepAngle", XFA_ATTRIBUTE_SweepAngle, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 7)},
+ {0x78bff531, (FX_LPCWSTR)L"numberOfCells", XFA_ATTRIBUTE_NumberOfCells, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x79543055, (FX_LPCWSTR)L"letterSpacing", XFA_ATTRIBUTE_LetterSpacing, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x79975f2b, (FX_LPCWSTR)L"lockType", XFA_ATTRIBUTE_LockType, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet, (FX_LPVOID)XFA_ATTRIBUTEENUM_ReadOnly},
+ {0x7a0cc471, (FX_LPCWSTR)L"passwordChar", XFA_ATTRIBUTE_PasswordChar, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"*"},
+ {0x7a7cc341, (FX_LPCWSTR)L"vAlign", XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Top},
+ {0x7b29630a, (FX_LPCWSTR)L"sourceBelow", XFA_ATTRIBUTE_SourceBelow, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config, (FX_LPVOID)XFA_ATTRIBUTEENUM_Update},
+ {0x7b95e661, (FX_LPCWSTR)L"inverted", XFA_ATTRIBUTE_Inverted, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x7c2fd80b, (FX_LPCWSTR)L"mark", XFA_ATTRIBUTE_Mark, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Default},
+ {0x7c2ff6ae, (FX_LPCWSTR)L"maxH", XFA_ATTRIBUTE_MaxH, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x7c2ff6bd, (FX_LPCWSTR)L"maxW", XFA_ATTRIBUTE_MaxW, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x7c732a66, (FX_LPCWSTR)L"truncate", XFA_ATTRIBUTE_Truncate, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x7d02356c, (FX_LPCWSTR)L"minH", XFA_ATTRIBUTE_MinH, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x7d02357b, (FX_LPCWSTR)L"minW", XFA_ATTRIBUTE_MinW, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x7d0b5fca, (FX_LPCWSTR)L"initial", XFA_ATTRIBUTE_Initial, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)1},
+ {0x7d9fd7c5, (FX_LPCWSTR)L"mode", XFA_ATTRIBUTE_Mode, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config, (FX_LPVOID)XFA_ATTRIBUTEENUM_UsePrinterSetting},
+ {0x7e7e845e, (FX_LPCWSTR)L"layout", XFA_ATTRIBUTE_Layout, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Position},
+ {0x7f6fd3d7, (FX_LPCWSTR)L"server", XFA_ATTRIBUTE_Server, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x824f21b7, (FX_LPCWSTR)L"embedPDF", XFA_ATTRIBUTE_EmbedPDF, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x8340ea66, (FX_LPCWSTR)L"oddOrEven", XFA_ATTRIBUTE_OddOrEven, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Any},
+ {0x836d4d7c, (FX_LPCWSTR)L"tabDefault", XFA_ATTRIBUTE_TabDefault, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x8855805f, (FX_LPCWSTR)L"contains", XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Datasets, (FX_LPVOID)XFA_ATTRIBUTEENUM_Data},
+ {0x8a692521, (FX_LPCWSTR)L"rightInset", XFA_ATTRIBUTE_RightInset, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x8af2e657, (FX_LPCWSTR)L"maxChars", XFA_ATTRIBUTE_MaxChars, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x8b90e1f2, (FX_LPCWSTR)L"open", XFA_ATTRIBUTE_Open, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_UserControl},
+ {0x8c99377e, (FX_LPCWSTR)L"relation", XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x8d181d61, (FX_LPCWSTR)L"wideNarrowRatio", XFA_ATTRIBUTE_WideNarrowRatio, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"3:1"},
+ {0x8e1c2921, (FX_LPCWSTR)L"relevant", XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x8e29d794, (FX_LPCWSTR)L"signatureType", XFA_ATTRIBUTE_SignatureType, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Filter},
+ {0x8ec6204c, (FX_LPCWSTR)L"lineThroughPeriod", XFA_ATTRIBUTE_LineThroughPeriod, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_All},
+ {0x8ed182d1, (FX_LPCWSTR)L"shape", XFA_ATTRIBUTE_Shape, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Square},
+ {0x8fa01790, (FX_LPCWSTR)L"tabStops", XFA_ATTRIBUTE_TabStops, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x8fc36c0a, (FX_LPCWSTR)L"outputBelow", XFA_ATTRIBUTE_OutputBelow, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config, (FX_LPVOID)XFA_ATTRIBUTEENUM_Warn},
+ {0x9041d4b0, (FX_LPCWSTR)L"short", XFA_ATTRIBUTE_Short, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0x907c7719, (FX_LPCWSTR)L"fontVerticalScale", XFA_ATTRIBUTE_FontVerticalScale, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"100%"},
+ {0x94446dcc, (FX_LPCWSTR)L"thickness", XFA_ATTRIBUTE_Thickness, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 8)},
+ {0x957fa006, (FX_LPCWSTR)L"commitOn", XFA_ATTRIBUTE_CommitOn, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Select},
+ {0x982bd892, (FX_LPCWSTR)L"remainCharacterCount", XFA_ATTRIBUTE_RemainCharacterCount, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)3},
+ {0x98fd4d81, (FX_LPCWSTR)L"keyAgreement", XFA_ATTRIBUTE_KeyAgreement, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x99800d7a, (FX_LPCWSTR)L"errorCorrectionLevel", XFA_ATTRIBUTE_ErrorCorrectionLevel, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0x9a63da3d, (FX_LPCWSTR)L"upsMode", XFA_ATTRIBUTE_UpsMode, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_UsCarrier},
+ {0x9cc17d75, (FX_LPCWSTR)L"mergeMode", XFA_ATTRIBUTE_MergeMode, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_ConsumeData},
+ {0x9d833d75, (FX_LPCWSTR)L"circular", XFA_ATTRIBUTE_Circular, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0x9d8ee204, (FX_LPCWSTR)L"psName", XFA_ATTRIBUTE_PsName, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Config, (FX_LPVOID)NULL},
+ {0x9dcc3ab3, (FX_LPCWSTR)L"trailer", XFA_ATTRIBUTE_Trailer, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xa0933954, (FX_LPCWSTR)L"unicodeRange", XFA_ATTRIBUTE_UnicodeRange, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Config, (FX_LPVOID)NULL},
+ {0xa1b0d2f5, (FX_LPCWSTR)L"executeType", XFA_ATTRIBUTE_ExecuteType, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Import},
+ {0xa25a883d, (FX_LPCWSTR)L"duplexImposition", XFA_ATTRIBUTE_DuplexImposition, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_LongEdge},
+ {0xa42ca1b7, (FX_LPCWSTR)L"trayIn", XFA_ATTRIBUTE_TrayIn, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Auto},
+ {0xa433f001, (FX_LPCWSTR)L"bindingNode", XFA_ATTRIBUTE_BindingNode, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_UNKNOWN, (FX_LPVOID)0},
+ {0xa5340ff5, (FX_LPCWSTR)L"bofAction", XFA_ATTRIBUTE_BofAction, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet, (FX_LPVOID)XFA_ATTRIBUTEENUM_MoveFirst},
+ {0xa5b410cf, (FX_LPCWSTR)L"save", XFA_ATTRIBUTE_Save, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0xa6118c89, (FX_LPCWSTR)L"targetType", XFA_ATTRIBUTE_TargetType, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Auto},
+ {0xa66404cb, (FX_LPCWSTR)L"keyEncipherment", XFA_ATTRIBUTE_KeyEncipherment, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xa6710262, (FX_LPCWSTR)L"credentialServerPolicy", XFA_ATTRIBUTE_CredentialServerPolicy, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {0xa686975b, (FX_LPCWSTR)L"size", XFA_ATTRIBUTE_Size, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 6)},
+ {0xa85e74f3, (FX_LPCWSTR)L"initialNumber", XFA_ATTRIBUTE_InitialNumber, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)1},
+ {0xabef37e3, (FX_LPCWSTR)L"slope", XFA_ATTRIBUTE_Slope, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Backslash},
+ {0xabfa6c4f, (FX_LPCWSTR)L"cSpace", XFA_ATTRIBUTE_CSpace, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"SRGB"},
+ {0xac06e2b0, (FX_LPCWSTR)L"colSpan", XFA_ATTRIBUTE_ColSpan, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)1},
+ {0xadc4c77b, (FX_LPCWSTR)L"binding", XFA_ATTRIBUTE_Binding, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xaf754613, (FX_LPCWSTR)L"checksum", XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xb045fbc5, (FX_LPCWSTR)L"charEncoding", XFA_ATTRIBUTE_CharEncoding, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(FX_LPCWSTR)L"UTF-8"},
+ {0xb0e5485d, (FX_LPCWSTR)L"bind", XFA_ATTRIBUTE_Bind, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet, (FX_LPVOID)NULL},
+ {0xb12128b7, (FX_LPCWSTR)L"textEntry", XFA_ATTRIBUTE_TextEntry, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0xb373a862, (FX_LPCWSTR)L"archive", XFA_ATTRIBUTE_Archive, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xb598a1f7, (FX_LPCWSTR)L"uuid", XFA_ATTRIBUTE_Uuid, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_XDP, (FX_LPVOID)NULL},
+ {0xb5e49bf2, (FX_LPCWSTR)L"posture", XFA_ATTRIBUTE_Posture, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Normal},
+ {0xb6b44172, (FX_LPCWSTR)L"after", XFA_ATTRIBUTE_After, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Auto},
+ {0xb716467b, (FX_LPCWSTR)L"orphans", XFA_ATTRIBUTE_Orphans, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0xbc0c4695, (FX_LPCWSTR)L"qualifiedName", XFA_ATTRIBUTE_QualifiedName, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_UNKNOWN, (FX_LPVOID)NULL},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xbc8fa350, (FX_LPCWSTR)L"locale", XFA_ATTRIBUTE_Locale, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xbd6e1d88, (FX_LPCWSTR)L"weight", XFA_ATTRIBUTE_Weight, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Normal},
+ {0xbd96a0e9, (FX_LPCWSTR)L"underlinePeriod", XFA_ATTRIBUTE_UnderlinePeriod, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_All},
+ {0xbde9abda, (FX_LPCWSTR)L"data", XFA_ATTRIBUTE_Data, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Link},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet, (FX_LPVOID)NULL},
+ {0xbe9ba472, (FX_LPCWSTR)L"numbered", XFA_ATTRIBUTE_Numbered, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)1},
+ {0xc035c6b1, (FX_LPCWSTR)L"dataColumnCount", XFA_ATTRIBUTE_DataColumnCount, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xc0ec9fa4, (FX_LPCWSTR)L"overline", XFA_ATTRIBUTE_Overline, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0xc2ba0923, (FX_LPCWSTR)L"urlPolicy", XFA_ATTRIBUTE_UrlPolicy, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xc2bd40fd, (FX_LPCWSTR)L"anchorType", XFA_ATTRIBUTE_AnchorType, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_TopLeft},
+ {0xc39a88bd, (FX_LPCWSTR)L"labelRef", XFA_ATTRIBUTE_LabelRef, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xc3c1442f, (FX_LPCWSTR)L"bookendLeader", XFA_ATTRIBUTE_BookendLeader, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xc4547a08, (FX_LPCWSTR)L"maxLength", XFA_ATTRIBUTE_MaxLength, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID) - 1},
+ {0xc4fed09b, (FX_LPCWSTR)L"accessKey", XFA_ATTRIBUTE_AccessKey, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xc5762157, (FX_LPCWSTR)L"cursorLocation", XFA_ATTRIBUTE_CursorLocation, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_SourceSet, (FX_LPVOID)XFA_ATTRIBUTEENUM_Client},
+ {0xc860f30a, (FX_LPCWSTR)L"delayedOpen", XFA_ATTRIBUTE_DelayedOpen, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet, (FX_LPVOID)NULL},
+ {0xc8da4da7, (FX_LPCWSTR)L"target", XFA_ATTRIBUTE_Target, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xca5dc27c, (FX_LPCWSTR)L"dataEncipherment", XFA_ATTRIBUTE_DataEncipherment, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xcb150479, (FX_LPCWSTR)L"afterTarget", XFA_ATTRIBUTE_AfterTarget, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xcbcaf66d, (FX_LPCWSTR)L"leader", XFA_ATTRIBUTE_Leader, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xcca7897e, (FX_LPCWSTR)L"picker", XFA_ATTRIBUTE_Picker, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Host},
+ {0xcd7f7b54, (FX_LPCWSTR)L"from", XFA_ATTRIBUTE_From, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config, (FX_LPVOID)NULL},
+ {0xcea5e62c, (FX_LPCWSTR)L"baseProfile", XFA_ATTRIBUTE_BaseProfile, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Full},
+ {0xd171b240, (FX_LPCWSTR)L"aspect", XFA_ATTRIBUTE_Aspect, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Fit},
+ {0xd3c84d25, (FX_LPCWSTR)L"rowColumnRatio", XFA_ATTRIBUTE_RowColumnRatio, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xd4b01921, (FX_LPCWSTR)L"lineHeight", XFA_ATTRIBUTE_LineHeight, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 1)},
+ {0xd4cc53f8, (FX_LPCWSTR)L"highlight", XFA_ATTRIBUTE_Highlight, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Inverted},
+ {0xd50f903a, (FX_LPCWSTR)L"valueRef", XFA_ATTRIBUTE_ValueRef, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xd52482e0, (FX_LPCWSTR)L"maxEntries", XFA_ATTRIBUTE_MaxEntries, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Config, (FX_LPVOID)5},
+ {0xd57c513c, (FX_LPCWSTR)L"dataLength", XFA_ATTRIBUTE_DataLength, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xd6128d8d, (FX_LPCWSTR)L"activity", XFA_ATTRIBUTE_Activity, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Click},
+ {0xd6a39990, (FX_LPCWSTR)L"input", XFA_ATTRIBUTE_Input, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_ConnectionSet, (FX_LPVOID)NULL},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", XFA_ATTRIBUTE_Value, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Datasets | XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xd70798c2, (FX_LPCWSTR)L"blankOrNotBlank", XFA_ATTRIBUTE_BlankOrNotBlank, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Any},
+ {0xd861f8af, (FX_LPCWSTR)L"addRevocationInfo", XFA_ATTRIBUTE_AddRevocationInfo, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xd8f982bf, (FX_LPCWSTR)L"genericFamily", XFA_ATTRIBUTE_GenericFamily, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config, (FX_LPVOID)XFA_ATTRIBUTEENUM_Serif},
+ {0xd996fa9b, (FX_LPCWSTR)L"hand", XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Even},
+ {0xdb55fec5, (FX_LPCWSTR)L"href", XFA_ATTRIBUTE_Href, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xdc75676c, (FX_LPCWSTR)L"textEncoding", XFA_ATTRIBUTE_TextEncoding, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xde7f92ba, (FX_LPCWSTR)L"leadDigits", XFA_ATTRIBUTE_LeadDigits, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID) - 1},
+ {0xe11a2cbc, (FX_LPCWSTR)L"permissions", XFA_ATTRIBUTE_Permissions, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)2},
+ {0xe18b5659, (FX_LPCWSTR)L"spaceAbove", XFA_ATTRIBUTE_SpaceAbove, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0xe1a26b56, (FX_LPCWSTR)L"codeBase", XFA_ATTRIBUTE_CodeBase, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xe349d044, (FX_LPCWSTR)L"stock", XFA_ATTRIBUTE_Stock, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xe372ae97, (FX_LPCWSTR)L"isNull", XFA_ATTRIBUTE_IsNull, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Datasets, (FX_LPVOID)0},
+ {0xe4c3a5e5, (FX_LPCWSTR)L"restoreState", XFA_ATTRIBUTE_RestoreState, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Manual},
+ {0xe5c96d6a, (FX_LPCWSTR)L"excludeAllCaps", XFA_ATTRIBUTE_ExcludeAllCaps, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0xe64b1129, (FX_LPCWSTR)L"formatTest", XFA_ATTRIBUTE_FormatTest, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Warning},
+ {0xe6f99487, (FX_LPCWSTR)L"hScrollPolicy", XFA_ATTRIBUTE_HScrollPolicy, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Auto},
+ {0xe8dddf50, (FX_LPCWSTR)L"join", XFA_ATTRIBUTE_Join, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Square},
+ {0xe8f118a8, (FX_LPCWSTR)L"keyCertSign", XFA_ATTRIBUTE_KeyCertSign, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xe948b9a8, (FX_LPCWSTR)L"radius", XFA_ATTRIBUTE_Radius, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0xe996b2fe, (FX_LPCWSTR)L"sourceAbove", XFA_ATTRIBUTE_SourceAbove, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config, (FX_LPVOID)XFA_ATTRIBUTEENUM_Warn},
+ {0xea7090a0, (FX_LPCWSTR)L"override", XFA_ATTRIBUTE_Override, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xeb091003, (FX_LPCWSTR)L"classId", XFA_ATTRIBUTE_ClassId, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xeb511b54, (FX_LPCWSTR)L"disable", XFA_ATTRIBUTE_Disable, XFA_ATTRIBUTETYPE_Boolean, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)0},
+ {0xeda9017a, (FX_LPCWSTR)L"scope", XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTETYPE_NOTSURE, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xf197844d, (FX_LPCWSTR)L"match", XFA_ATTRIBUTE_Match, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Once},
+ {0xf2009339, (FX_LPCWSTR)L"placement", XFA_ATTRIBUTE_Placement, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Left},
+ {0xf4ffce73, (FX_LPCWSTR)L"before", XFA_ATTRIBUTE_Before, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_Auto},
+ {0xf531b059, (FX_LPCWSTR)L"writingScript", XFA_ATTRIBUTE_WritingScript, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Config, (FX_LPVOID)XFA_ATTRIBUTEENUM_Asterisk},
+ {0xf575ca75, (FX_LPCWSTR)L"endChar", XFA_ATTRIBUTE_EndChar, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTETYPE_Integer, XFA_XDPPACKET_Config, (FX_LPVOID)0},
+ {0xf6b4afb0, (FX_LPCWSTR)L"long", XFA_ATTRIBUTE_Long, XFA_ATTRIBUTETYPE_Measure, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)(g_XFAMeasurementData + 0)},
+ {0xf6b59543, (FX_LPCWSTR)L"intact", XFA_ATTRIBUTE_Intact, XFA_ATTRIBUTETYPE_Enum, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {0xf889e747, (FX_LPCWSTR)L"xdpContent", XFA_ATTRIBUTE_XdpContent, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+ {0xfea53ec6, (FX_LPCWSTR)L"decipherOnly", XFA_ATTRIBUTE_DecipherOnly, XFA_ATTRIBUTETYPE_Cdata, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, (FX_LPVOID)NULL},
+};
+extern const FX_INT32 g_iXFAAttributeCount = sizeof(g_XFAAttributeData) / sizeof(XFA_ATTRIBUTEINFO);
+extern const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[] = {
+ {XFA_ELEMENT_SubformSet, XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Ordered},
+ {XFA_ELEMENT_NumberPattern, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Numeric},
+ {XFA_ELEMENT_KeyUsage, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_LabelPrinter, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Zpl},
+ {XFA_ELEMENT_CalendarSymbols, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Gregorian},
+ {XFA_ELEMENT_Barcode, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Cdata, (FX_LPVOID)NULL},
+ {XFA_ELEMENT_Barcode, XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {XFA_ELEMENT_TimePattern, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Med},
+ {XFA_ELEMENT_BatchOutput, XFA_ATTRIBUTE_Format, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {XFA_ELEMENT_SubjectDNs, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Issuers, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_EncryptionMethods, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Pattern, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_CrossHatch},
+ {XFA_ELEMENT_Compress, XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_ImageOnly},
+ {XFA_ELEMENT_Image, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Base64},
+ {XFA_ELEMENT_TimeStamp, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Subform, XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Name},
+ {XFA_ELEMENT_Handler, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Record, XFA_ATTRIBUTE_Max, XFA_ATTRIBUTETYPE_Integer, (FX_LPVOID)0},
+ {XFA_ELEMENT_Command, XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTETYPE_Integer, (FX_LPVOID)30},
+ {XFA_ELEMENT_DigestMethods, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_PageSet, XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_OrderedOccurrence},
+ {XFA_ELEMENT_Equate, XFA_ATTRIBUTE_From, XFA_ATTRIBUTETYPE_Cdata, (FX_LPVOID)NULL},
+ {XFA_ELEMENT_Equate, XFA_ATTRIBUTE_To, XFA_ATTRIBUTETYPE_Cdata, (FX_LPVOID)NULL},
+ {XFA_ELEMENT_Traverse, XFA_ATTRIBUTE_Operation, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Next},
+ {XFA_ELEMENT_Encodings, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Signing, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Oids, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Signature, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_PDF1_3},
+ {XFA_ELEMENT_ExData, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {XFA_ELEMENT_Linear, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_ToRight},
+ {XFA_ELEMENT_CurrencySymbol, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Symbol},
+ {XFA_ELEMENT_EquateRange, XFA_ATTRIBUTE_From, XFA_ATTRIBUTETYPE_Cdata, (FX_LPVOID)NULL},
+ {XFA_ELEMENT_EquateRange, XFA_ATTRIBUTE_To, XFA_ATTRIBUTETYPE_Cdata, (FX_LPVOID)NULL},
+ {XFA_ELEMENT_SignData, XFA_ATTRIBUTE_Operation, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Sign},
+ {XFA_ELEMENT_DatePattern, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Med},
+ {XFA_ELEMENT_Bind, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_None},
+ {XFA_ELEMENT_Reasons, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_AppearanceFilter, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Form, XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTETYPE_Cdata, (FX_LPVOID)NULL},
+ {XFA_ELEMENT_Value, XFA_ATTRIBUTE_Override, XFA_ATTRIBUTETYPE_Boolean, (FX_LPVOID)0},
+ {XFA_ELEMENT_Calculate, XFA_ATTRIBUTE_Override, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Error},
+ {XFA_ELEMENT_Connect, XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTETYPE_Integer, (FX_LPVOID)15},
+ {XFA_ELEMENT_Submit, XFA_ATTRIBUTE_Format, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Xdp},
+ {XFA_ELEMENT_Radial, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_ToEdge},
+ {XFA_ELEMENT_LockDocument, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Optional},
+ {XFA_ELEMENT_Occur, XFA_ATTRIBUTE_Max, XFA_ATTRIBUTETYPE_Integer, (FX_LPVOID)1},
+ {XFA_ELEMENT_NumberSymbol, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTETYPE_Enum, (FX_LPVOID)XFA_ATTRIBUTEENUM_Decimal},
+};
+extern const FX_INT32 g_iXFANotsureCount = sizeof(g_XFANotsureAttributes) / sizeof(XFA_NOTSUREATTRIBUTE);
+extern const XFA_ELEMENTINFO g_XFAElementData[] = {
+ {0x23ee3, (FX_LPCWSTR)L"ps", XFA_ELEMENT_Ps, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x25363, (FX_LPCWSTR)L"to", XFA_ELEMENT_To, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x2587e, (FX_LPCWSTR)L"ui", XFA_ELEMENT_Ui, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x1c648b, (FX_LPCWSTR)L"recordSet", XFA_ELEMENT_RecordSet, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_Node},
+ {0x171428f, (FX_LPCWSTR)L"subsetBelow", XFA_ELEMENT_SubsetBelow, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x1a0776a, (FX_LPCWSTR)L"subformSet", XFA_ELEMENT_SubformSet, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x2340d70, (FX_LPCWSTR)L"adobeExtensionLevel", XFA_ELEMENT_AdobeExtensionLevel, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x2c1c7f1, (FX_LPCWSTR)L"typeface", XFA_ELEMENT_Typeface, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x5518c25, (FX_LPCWSTR)L"break", XFA_ELEMENT_Break, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x5fff523, (FX_LPCWSTR)L"fontInfo", XFA_ELEMENT_FontInfo, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x653a227, (FX_LPCWSTR)L"numberPattern", XFA_ELEMENT_NumberPattern, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0x65b4a05, (FX_LPCWSTR)L"dynamicRender", XFA_ELEMENT_DynamicRender, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x7e4362e, (FX_LPCWSTR)L"printScaling", XFA_ELEMENT_PrintScaling, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x7fe6d3a, (FX_LPCWSTR)L"checkButton", XFA_ELEMENT_CheckButton, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x80cf58f, (FX_LPCWSTR)L"datePatterns", XFA_ELEMENT_DatePatterns, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x811929d, (FX_LPCWSTR)L"sourceSet", XFA_ELEMENT_SourceSet, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_ModelNode},
+ {0x9f9d612, (FX_LPCWSTR)L"amd", XFA_ELEMENT_Amd, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x9f9efb6, (FX_LPCWSTR)L"arc", XFA_ELEMENT_Arc, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xa48835e, (FX_LPCWSTR)L"day", XFA_ELEMENT_Day, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0xa6328b8, (FX_LPCWSTR)L"era", XFA_ELEMENT_Era, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0xae6a0a0, (FX_LPCWSTR)L"jog", XFA_ELEMENT_Jog, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xb1b3d22, (FX_LPCWSTR)L"log", XFA_ELEMENT_Log, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xb35439e, (FX_LPCWSTR)L"map", XFA_ELEMENT_Map, XFA_XDPPACKET_Config | XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_Node},
+ {0xb355301, (FX_LPCWSTR)L"mdp", XFA_ELEMENT_Mdp, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xb420438, (FX_LPCWSTR)L"breakBefore", XFA_ELEMENT_BreakBefore, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xb6a091c, (FX_LPCWSTR)L"oid", XFA_ELEMENT_Oid, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+ {0xb84389f, (FX_LPCWSTR)L"pcl", XFA_ELEMENT_Pcl, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xb843dba, (FX_LPCWSTR)L"pdf", XFA_ELEMENT_Pdf, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xbb8df5d, (FX_LPCWSTR)L"ref", XFA_ELEMENT_Ref, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+ {0xc080cd0, (FX_LPCWSTR)L"uri", XFA_ELEMENT_Uri, XFA_XDPPACKET_Config | XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+ {0xc56afbf, (FX_LPCWSTR)L"xdc", XFA_ELEMENT_Xdc, XFA_XDPPACKET_Config | XFA_XDPPACKET_Xdc, XFA_OBJECTTYPE_ModelNode},
+ {0xc56afcc, (FX_LPCWSTR)L"xdp", XFA_ELEMENT_Xdp, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xc56b9ff, (FX_LPCWSTR)L"xfa", XFA_ELEMENT_Xfa, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_ModelNode},
+ {0xc56fcb7, (FX_LPCWSTR)L"xsl", XFA_ELEMENT_Xsl, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xc8b89d6, (FX_LPCWSTR)L"zpl", XFA_ELEMENT_Zpl, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xc9bae94, (FX_LPCWSTR)L"cache", XFA_ELEMENT_Cache, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xcb016be, (FX_LPCWSTR)L"margin", XFA_ELEMENT_Margin, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xe1378fe, (FX_LPCWSTR)L"keyUsage", XFA_ELEMENT_KeyUsage, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xfe3596a, (FX_LPCWSTR)L"exclude", XFA_ELEMENT_Exclude, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x10395ac7, (FX_LPCWSTR)L"choiceList", XFA_ELEMENT_ChoiceList, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x1059ec18, (FX_LPCWSTR)L"level", XFA_ELEMENT_Level, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x10874804, (FX_LPCWSTR)L"labelPrinter", XFA_ELEMENT_LabelPrinter, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x10c40e03, (FX_LPCWSTR)L"calendarSymbols", XFA_ELEMENT_CalendarSymbols, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x10f1ea24, (FX_LPCWSTR)L"para", XFA_ELEMENT_Para, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x10f1ea37, (FX_LPCWSTR)L"part", XFA_ELEMENT_Part, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x1140975b, (FX_LPCWSTR)L"pdfa", XFA_ELEMENT_Pdfa, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x1154efe6, (FX_LPCWSTR)L"filter", XFA_ELEMENT_Filter, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x13f41de1, (FX_LPCWSTR)L"present", XFA_ELEMENT_Present, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x1827e6ea, (FX_LPCWSTR)L"pagination", XFA_ELEMENT_Pagination, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x18463707, (FX_LPCWSTR)L"encoding", XFA_ELEMENT_Encoding, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+ {0x185e41e2, (FX_LPCWSTR)L"event", XFA_ELEMENT_Event, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x1adb142d, (FX_LPCWSTR)L"whitespace", XFA_ELEMENT_Whitespace, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x1f3f64c3, (FX_LPCWSTR)L"defaultUi", XFA_ELEMENT_DefaultUi, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x204e87cb, (FX_LPCWSTR)L"dataModel", XFA_ELEMENT_DataModel, XFA_XDPPACKET_Datasets, XFA_OBJECTTYPE_ModelNode},
+ {0x2057b350, (FX_LPCWSTR)L"barcode", XFA_ELEMENT_Barcode, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x20596bad, (FX_LPCWSTR)L"timePattern", XFA_ELEMENT_TimePattern, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0x210b74d3, (FX_LPCWSTR)L"batchOutput", XFA_ELEMENT_BatchOutput, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x212ff0e2, (FX_LPCWSTR)L"enforce", XFA_ELEMENT_Enforce, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x21d351b4, (FX_LPCWSTR)L"currencySymbols", XFA_ELEMENT_CurrencySymbols, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x21db83c5, (FX_LPCWSTR)L"addSilentPrint", XFA_ELEMENT_AddSilentPrint, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x22266258, (FX_LPCWSTR)L"rename", XFA_ELEMENT_Rename, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x226ca8f1, (FX_LPCWSTR)L"operation", XFA_ELEMENT_Operation, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+ {0x23e27b84, (FX_LPCWSTR)L"typefaces", XFA_ELEMENT_Typefaces, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x23f4aa75, (FX_LPCWSTR)L"subjectDNs", XFA_ELEMENT_SubjectDNs, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x240d5e8e, (FX_LPCWSTR)L"issuers", XFA_ELEMENT_Issuers, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x2457a033, (FX_LPCWSTR)L"signaturePseudoModel", XFA_ELEMENT_SignaturePseudoModel, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+ {0x24a52f8a, (FX_LPCWSTR)L"wsdlConnection", XFA_ELEMENT_WsdlConnection, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+ {0x254ebd07, (FX_LPCWSTR)L"debug", XFA_ELEMENT_Debug, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x2655c66a, (FX_LPCWSTR)L"delta", XFA_ELEMENT_Delta, XFA_XDPPACKET_Form, XFA_OBJECTTYPE_OrdinaryObject},
+ {0x26c0daec, (FX_LPCWSTR)L"eraNames", XFA_ELEMENT_EraNames, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x273ab03b, (FX_LPCWSTR)L"modifyAnnots", XFA_ELEMENT_ModifyAnnots, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x27875bb4, (FX_LPCWSTR)L"startNode", XFA_ELEMENT_StartNode, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x285d0dbc, (FX_LPCWSTR)L"button", XFA_ELEMENT_Button, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x28dee6e9, (FX_LPCWSTR)L"format", XFA_ELEMENT_Format, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x2a23349e, (FX_LPCWSTR)L"border", XFA_ELEMENT_Border, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x2ae67f19, (FX_LPCWSTR)L"area", XFA_ELEMENT_Area, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x2c3c4c67, (FX_LPCWSTR)L"hyphenation", XFA_ELEMENT_Hyphenation, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x2d08af85, (FX_LPCWSTR)L"text", XFA_ELEMENT_Text, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x2d71b00f, (FX_LPCWSTR)L"time", XFA_ELEMENT_Time, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x2f16a382, (FX_LPCWSTR)L"type", XFA_ELEMENT_Type, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x2fe057e9, (FX_LPCWSTR)L"overprint", XFA_ELEMENT_Overprint, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x302aee16, (FX_LPCWSTR)L"certificates", XFA_ELEMENT_Certificates, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x30b227df, (FX_LPCWSTR)L"encryptionMethods", XFA_ELEMENT_EncryptionMethods, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x32b900d1, (FX_LPCWSTR)L"setProperty", XFA_ELEMENT_SetProperty, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x337d9e45, (FX_LPCWSTR)L"printerName", XFA_ELEMENT_PrinterName, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x33edda4b, (FX_LPCWSTR)L"startPage", XFA_ELEMENT_StartPage, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x381943e4, (FX_LPCWSTR)L"pageOffset", XFA_ELEMENT_PageOffset, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x382106cd, (FX_LPCWSTR)L"dateTime", XFA_ELEMENT_DateTime, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x386e7421, (FX_LPCWSTR)L"comb", XFA_ELEMENT_Comb, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x390acd9e, (FX_LPCWSTR)L"pattern", XFA_ELEMENT_Pattern, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x3942163e, (FX_LPCWSTR)L"ifEmpty", XFA_ELEMENT_IfEmpty, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x39944a7b, (FX_LPCWSTR)L"suppressBanner", XFA_ELEMENT_SuppressBanner, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x3b3c3dca, (FX_LPCWSTR)L"outputBin", XFA_ELEMENT_OutputBin, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x3b8a4024, (FX_LPCWSTR)L"field", XFA_ELEMENT_Field, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x3c15352f, (FX_LPCWSTR)L"agent", XFA_ELEMENT_Agent, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x3d7e8668, (FX_LPCWSTR)L"outputXSL", XFA_ELEMENT_OutputXSL, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x3e1c91c5, (FX_LPCWSTR)L"adjustData", XFA_ELEMENT_AdjustData, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x3e7a9408, (FX_LPCWSTR)L"autoSave", XFA_ELEMENT_AutoSave, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x3ecead94, (FX_LPCWSTR)L"contentArea", XFA_ELEMENT_ContentArea, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x3ef334e3, (FX_LPCWSTR)L"eventPseudoModel", XFA_ELEMENT_EventPseudoModel, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+ {0x3fadaec0, (FX_LPCWSTR)L"wsdlAddress", XFA_ELEMENT_WsdlAddress, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+ {0x40623b5b, (FX_LPCWSTR)L"solid", XFA_ELEMENT_Solid, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x41f0bd76, (FX_LPCWSTR)L"dateTimeSymbols", XFA_ELEMENT_DateTimeSymbols, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0x444e7523, (FX_LPCWSTR)L"encryptionLevel", XFA_ELEMENT_EncryptionLevel, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x4523af55, (FX_LPCWSTR)L"edge", XFA_ELEMENT_Edge, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x45d5e3c1, (FX_LPCWSTR)L"stipple", XFA_ELEMENT_Stipple, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x475e4e87, (FX_LPCWSTR)L"attributes", XFA_ELEMENT_Attributes, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x487a8c87, (FX_LPCWSTR)L"versionControl", XFA_ELEMENT_VersionControl, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x48e5248c, (FX_LPCWSTR)L"meridiem", XFA_ELEMENT_Meridiem, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0x48f36719, (FX_LPCWSTR)L"exclGroup", XFA_ELEMENT_ExclGroup, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x4977356b, (FX_LPCWSTR)L"toolTip", XFA_ELEMENT_ToolTip, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+ {0x499afecc, (FX_LPCWSTR)L"compress", XFA_ELEMENT_Compress, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x4a0c4948, (FX_LPCWSTR)L"reason", XFA_ELEMENT_Reason, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+ {0x4bdcce13, (FX_LPCWSTR)L"execute", XFA_ELEMENT_Execute, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x4c56b216, (FX_LPCWSTR)L"contentCopy", XFA_ELEMENT_ContentCopy, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x4cc176d3, (FX_LPCWSTR)L"dateTimeEdit", XFA_ELEMENT_DateTimeEdit, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x4e1e39b6, (FX_LPCWSTR)L"config", XFA_ELEMENT_Config, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ModelNode},
+ {0x4e2d6083, (FX_LPCWSTR)L"image", XFA_ELEMENT_Image, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x4e814150, (FX_LPCWSTR)L"#xHTML", XFA_ELEMENT_SharpxHTML, XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet | XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeV},
+ {0x4f2388c1, (FX_LPCWSTR)L"numberOfCopies", XFA_ELEMENT_NumberOfCopies, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x4f512e30, (FX_LPCWSTR)L"behaviorOverride", XFA_ELEMENT_BehaviorOverride, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x4fdc3454, (FX_LPCWSTR)L"timeStamp", XFA_ELEMENT_TimeStamp, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x51d90546, (FX_LPCWSTR)L"month", XFA_ELEMENT_Month, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0x523437e4, (FX_LPCWSTR)L"viewerPreferences", XFA_ELEMENT_ViewerPreferences, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x53abc1c6, (FX_LPCWSTR)L"scriptModel", XFA_ELEMENT_ScriptModel, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x54034c2f, (FX_LPCWSTR)L"decimal", XFA_ELEMENT_Decimal, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x54202c9e, (FX_LPCWSTR)L"subform", XFA_ELEMENT_Subform, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x542c7300, (FX_LPCWSTR)L"select", XFA_ELEMENT_Select, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+ {0x5436d198, (FX_LPCWSTR)L"window", XFA_ELEMENT_Window, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x5473b6dc, (FX_LPCWSTR)L"localeSet", XFA_ELEMENT_LocaleSet, XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ModelNode},
+ {0x56ae179e, (FX_LPCWSTR)L"handler", XFA_ELEMENT_Handler, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+ {0x5700bd5f, (FX_LPCWSTR)L"hostPseudoModel", XFA_ELEMENT_HostPseudoModel, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+ {0x570ce835, (FX_LPCWSTR)L"presence", XFA_ELEMENT_Presence, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x5779d65f, (FX_LPCWSTR)L"record", XFA_ELEMENT_Record, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x59c8f27d, (FX_LPCWSTR)L"embed", XFA_ELEMENT_Embed, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x5a50e9e6, (FX_LPCWSTR)L"version", XFA_ELEMENT_Version, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x5b8383df, (FX_LPCWSTR)L"command", XFA_ELEMENT_Command, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_Node},
+ {0x5c43c6c3, (FX_LPCWSTR)L"copies", XFA_ELEMENT_Copies, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x5e0c2c49, (FX_LPCWSTR)L"staple", XFA_ELEMENT_Staple, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x5e5083dd, (FX_LPCWSTR)L"submitFormat", XFA_ELEMENT_SubmitFormat, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x5e8c5d20, (FX_LPCWSTR)L"boolean", XFA_ELEMENT_Boolean, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x60490a85, (FX_LPCWSTR)L"message", XFA_ELEMENT_Message, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x60d4c8b1, (FX_LPCWSTR)L"output", XFA_ELEMENT_Output, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x61810081, (FX_LPCWSTR)L"psMap", XFA_ELEMENT_PsMap, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x62bd904b, (FX_LPCWSTR)L"excludeNS", XFA_ELEMENT_ExcludeNS, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x669d4f77, (FX_LPCWSTR)L"assist", XFA_ELEMENT_Assist, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x67334a1c, (FX_LPCWSTR)L"picture", XFA_ELEMENT_Picture, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x67fe7334, (FX_LPCWSTR)L"traversal", XFA_ELEMENT_Traversal, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x6894589c, (FX_LPCWSTR)L"silentPrint", XFA_ELEMENT_SilentPrint, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x68a16bbd, (FX_LPCWSTR)L"webClient", XFA_ELEMENT_WebClient, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x69f115df, (FX_LPCWSTR)L"layoutPseudoModel", XFA_ELEMENT_LayoutPseudoModel, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+ {0x6a4bc084, (FX_LPCWSTR)L"producer", XFA_ELEMENT_Producer, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x6a9e04c9, (FX_LPCWSTR)L"corner", XFA_ELEMENT_Corner, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x6ccd7274, (FX_LPCWSTR)L"msgId", XFA_ELEMENT_MsgId, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x6e67921f, (FX_LPCWSTR)L"color", XFA_ELEMENT_Color, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x6ec217a5, (FX_LPCWSTR)L"keep", XFA_ELEMENT_Keep, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x6eef1116, (FX_LPCWSTR)L"query", XFA_ELEMENT_Query, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_Node},
+ {0x7033bfd5, (FX_LPCWSTR)L"insert", XFA_ELEMENT_Insert, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+ {0x704af389, (FX_LPCWSTR)L"imageEdit", XFA_ELEMENT_ImageEdit, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x7233018a, (FX_LPCWSTR)L"validate", XFA_ELEMENT_Validate, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x72ba47b4, (FX_LPCWSTR)L"digestMethods", XFA_ELEMENT_DigestMethods, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x72f2aa7a, (FX_LPCWSTR)L"numberPatterns", XFA_ELEMENT_NumberPatterns, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x74caed29, (FX_LPCWSTR)L"pageSet", XFA_ELEMENT_PageSet, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x7568e6ae, (FX_LPCWSTR)L"integer", XFA_ELEMENT_Integer, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x76182db9, (FX_LPCWSTR)L"soapAddress", XFA_ELEMENT_SoapAddress, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+ {0x773146c5, (FX_LPCWSTR)L"equate", XFA_ELEMENT_Equate, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x77d449dd, (FX_LPCWSTR)L"formFieldFilling", XFA_ELEMENT_FormFieldFilling, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x7889d68a, (FX_LPCWSTR)L"pageRange", XFA_ELEMENT_PageRange, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x7baca2e3, (FX_LPCWSTR)L"update", XFA_ELEMENT_Update, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+ {0x7ce89001, (FX_LPCWSTR)L"connectString", XFA_ELEMENT_ConnectString, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+ {0x7d9fd7c5, (FX_LPCWSTR)L"mode", XFA_ELEMENT_Mode, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x7e7e845e, (FX_LPCWSTR)L"layout", XFA_ELEMENT_Layout, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x7e845c34, (FX_LPCWSTR)L"#xml", XFA_ELEMENT_Sharpxml, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeV},
+ {0x7fb341df, (FX_LPCWSTR)L"xsdConnection", XFA_ELEMENT_XsdConnection, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+ {0x7ffb51cc, (FX_LPCWSTR)L"traverse", XFA_ELEMENT_Traverse, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x80203b5a, (FX_LPCWSTR)L"encodings", XFA_ELEMENT_Encodings, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x803550fc, (FX_LPCWSTR)L"template", XFA_ELEMENT_Template, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ModelNode},
+ {0x803d5bbc, (FX_LPCWSTR)L"acrobat", XFA_ELEMENT_Acrobat, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0x821d6569, (FX_LPCWSTR)L"validationMessaging", XFA_ELEMENT_ValidationMessaging, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x830e688f, (FX_LPCWSTR)L"signing", XFA_ELEMENT_Signing, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x83a550d2, (FX_LPCWSTR)L"dataWindow", XFA_ELEMENT_DataWindow, XFA_XDPPACKET_Datasets, XFA_OBJECTTYPE_OrdinaryObject},
+ {0x83dab9f5, (FX_LPCWSTR)L"script", XFA_ELEMENT_Script, XFA_XDPPACKET_Config | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x8411ebcd, (FX_LPCWSTR)L"addViewerPreferences", XFA_ELEMENT_AddViewerPreferences, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x8777642e, (FX_LPCWSTR)L"alwaysEmbed", XFA_ELEMENT_AlwaysEmbed, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x877a6b39, (FX_LPCWSTR)L"passwordEdit", XFA_ELEMENT_PasswordEdit, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x87e84c99, (FX_LPCWSTR)L"numericEdit", XFA_ELEMENT_NumericEdit, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x8852cdec, (FX_LPCWSTR)L"encryptionMethod", XFA_ELEMENT_EncryptionMethod, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+ {0x891f4606, (FX_LPCWSTR)L"change", XFA_ELEMENT_Change, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x89939f36, (FX_LPCWSTR)L"pageArea", XFA_ELEMENT_PageArea, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0x8a9d6247, (FX_LPCWSTR)L"submitUrl", XFA_ELEMENT_SubmitUrl, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x8ad8b90f, (FX_LPCWSTR)L"oids", XFA_ELEMENT_Oids, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x8b036f32, (FX_LPCWSTR)L"signature", XFA_ELEMENT_Signature, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x8b128efb, (FX_LPCWSTR)L"ADBE_JSConsole", XFA_ELEMENT_ADBE_JSConsole, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0x8bcfe96e, (FX_LPCWSTR)L"caption", XFA_ELEMENT_Caption, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x8e1c2921, (FX_LPCWSTR)L"relevant", XFA_ELEMENT_Relevant, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x8e3f0a4b, (FX_LPCWSTR)L"flipLabel", XFA_ELEMENT_FlipLabel, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x900280b7, (FX_LPCWSTR)L"exData", XFA_ELEMENT_ExData, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0x91e80352, (FX_LPCWSTR)L"dayNames", XFA_ELEMENT_DayNames, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0x93113b11, (FX_LPCWSTR)L"soapAction", XFA_ELEMENT_SoapAction, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+ {0x938b09f6, (FX_LPCWSTR)L"defaultTypeface", XFA_ELEMENT_DefaultTypeface, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0x95b37897, (FX_LPCWSTR)L"manifest", XFA_ELEMENT_Manifest, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x97b76b54, (FX_LPCWSTR)L"overflow", XFA_ELEMENT_Overflow, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x9a57861b, (FX_LPCWSTR)L"linear", XFA_ELEMENT_Linear, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0x9ad5a821, (FX_LPCWSTR)L"currencySymbol", XFA_ELEMENT_CurrencySymbol, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0x9c6471b3, (FX_LPCWSTR)L"delete", XFA_ELEMENT_Delete, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+ {0x9deea61d, (FX_LPCWSTR)L"deltas", XFA_ELEMENT_Deltas, XFA_XDPPACKET_Form, XFA_OBJECTTYPE_OrdinaryObject},
+ {0x9e67de21, (FX_LPCWSTR)L"digestMethod", XFA_ELEMENT_DigestMethod, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+ {0x9f3e9510, (FX_LPCWSTR)L"instanceManager", XFA_ELEMENT_InstanceManager, XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xa0799892, (FX_LPCWSTR)L"equateRange", XFA_ELEMENT_EquateRange, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xa084a381, (FX_LPCWSTR)L"medium", XFA_ELEMENT_Medium, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xa1211b8b, (FX_LPCWSTR)L"textEdit", XFA_ELEMENT_TextEdit, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xa17008f0, (FX_LPCWSTR)L"templateCache", XFA_ELEMENT_TemplateCache, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xa4f7b88f, (FX_LPCWSTR)L"compressObjectStream", XFA_ELEMENT_CompressObjectStream, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xa65f5d17, (FX_LPCWSTR)L"dataValue", XFA_ELEMENT_DataValue, XFA_XDPPACKET_Datasets, XFA_OBJECTTYPE_Node},
+ {0xa6caaa89, (FX_LPCWSTR)L"accessibleContent", XFA_ELEMENT_AccessibleContent, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xa8c7d5e2, (FX_LPCWSTR)L"nodeList", XFA_ELEMENT_NodeList, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_NodeList},
+ {0xa94cc00b, (FX_LPCWSTR)L"includeXDPContent", XFA_ELEMENT_IncludeXDPContent, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xa9b081a1, (FX_LPCWSTR)L"xmlConnection", XFA_ELEMENT_XmlConnection, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+ {0xab2a3b74, (FX_LPCWSTR)L"validateApprovalSignatures", XFA_ELEMENT_ValidateApprovalSignatures, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xab8c5a2b, (FX_LPCWSTR)L"signData", XFA_ELEMENT_SignData, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xabaa2ceb, (FX_LPCWSTR)L"packets", XFA_ELEMENT_Packets, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xadba359c, (FX_LPCWSTR)L"datePattern", XFA_ELEMENT_DatePattern, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0xae222b2b, (FX_LPCWSTR)L"duplexOption", XFA_ELEMENT_DuplexOption, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xb012effb, (FX_LPCWSTR)L"base", XFA_ELEMENT_Base, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xb0e5485d, (FX_LPCWSTR)L"bind", XFA_ELEMENT_Bind, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xb45d61b2, (FX_LPCWSTR)L"compression", XFA_ELEMENT_Compression, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xb563f0ff, (FX_LPCWSTR)L"user", XFA_ELEMENT_User, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+ {0xb5848ad5, (FX_LPCWSTR)L"rectangle", XFA_ELEMENT_Rectangle, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xb6dacb72, (FX_LPCWSTR)L"effectiveOutputPolicy", XFA_ELEMENT_EffectiveOutputPolicy, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+ {0xb7d7654d, (FX_LPCWSTR)L"ADBE_JSDebugger", XFA_ELEMENT_ADBE_JSDebugger, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xbab37f73, (FX_LPCWSTR)L"acrobat7", XFA_ELEMENT_Acrobat7, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xbc70081e, (FX_LPCWSTR)L"interactive", XFA_ELEMENT_Interactive, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xbc8fa350, (FX_LPCWSTR)L"locale", XFA_ELEMENT_Locale, XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0xbcd44940, (FX_LPCWSTR)L"currentPage", XFA_ELEMENT_CurrentPage, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xbde9abda, (FX_LPCWSTR)L"data", XFA_ELEMENT_Data, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xbde9abde, (FX_LPCWSTR)L"date", XFA_ELEMENT_Date, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", XFA_ELEMENT_Desc, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xbf4b6405, (FX_LPCWSTR)L"encrypt", XFA_ELEMENT_Encrypt, XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0xbfa87cce, (FX_LPCWSTR)L"draw", XFA_ELEMENT_Draw, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0xc181ff4b, (FX_LPCWSTR)L"encryption", XFA_ELEMENT_Encryption, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xc1970f40, (FX_LPCWSTR)L"meridiemNames", XFA_ELEMENT_MeridiemNames, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0xc5ad9f5e, (FX_LPCWSTR)L"messaging", XFA_ELEMENT_Messaging, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xc69549f4, (FX_LPCWSTR)L"speak", XFA_ELEMENT_Speak, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+ {0xc7743dc7, (FX_LPCWSTR)L"dataGroup", XFA_ELEMENT_DataGroup, XFA_XDPPACKET_Datasets, XFA_OBJECTTYPE_Node},
+ {0xc7eb20e9, (FX_LPCWSTR)L"common", XFA_ELEMENT_Common, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xc85d4528, (FX_LPCWSTR)L"#text", XFA_ELEMENT_Sharptext, XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_LocaleSet | XFA_XDPPACKET_ConnectionSet | XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeV},
+ {0xc861556a, (FX_LPCWSTR)L"paginationOverride", XFA_ELEMENT_PaginationOverride, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xc903dabb, (FX_LPCWSTR)L"reasons", XFA_ELEMENT_Reasons, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xc9a8127f, (FX_LPCWSTR)L"signatureProperties", XFA_ELEMENT_SignatureProperties, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xca010c2d, (FX_LPCWSTR)L"threshold", XFA_ELEMENT_Threshold, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xcb4c5e96, (FX_LPCWSTR)L"appearanceFilter", XFA_ELEMENT_AppearanceFilter, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+ {0xcc92aba7, (FX_LPCWSTR)L"fill", XFA_ELEMENT_Fill, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xcd308b77, (FX_LPCWSTR)L"font", XFA_ELEMENT_Font, XFA_XDPPACKET_Template | XFA_XDPPACKET_Config | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xcd309ff4, (FX_LPCWSTR)L"form", XFA_ELEMENT_Form, XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ModelNode},
+ {0xcebcca2d, (FX_LPCWSTR)L"mediumInfo", XFA_ELEMENT_MediumInfo, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xcfe0d643, (FX_LPCWSTR)L"certificate", XFA_ELEMENT_Certificate, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_TextNode},
+ {0xd012c033, (FX_LPCWSTR)L"password", XFA_ELEMENT_Password, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_TextNode},
+ {0xd01604bd, (FX_LPCWSTR)L"runScripts", XFA_ELEMENT_RunScripts, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xd1227e6f, (FX_LPCWSTR)L"trace", XFA_ELEMENT_Trace, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xd1532876, (FX_LPCWSTR)L"float", XFA_ELEMENT_Float, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0xd17a6c30, (FX_LPCWSTR)L"renderPolicy", XFA_ELEMENT_RenderPolicy, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xd4bf6823, (FX_LPCWSTR)L"logPseudoModel", XFA_ELEMENT_LogPseudoModel, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryObject},
+ {0xd58aa962, (FX_LPCWSTR)L"destination", XFA_ELEMENT_Destination, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", XFA_ELEMENT_Value, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xd7a14462, (FX_LPCWSTR)L"bookend", XFA_ELEMENT_Bookend, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xd8c31254, (FX_LPCWSTR)L"exObject", XFA_ELEMENT_ExObject, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xda6a8590, (FX_LPCWSTR)L"openAction", XFA_ELEMENT_OpenAction, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xdab4fb7d, (FX_LPCWSTR)L"neverEmbed", XFA_ELEMENT_NeverEmbed, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xdb98475f, (FX_LPCWSTR)L"bindItems", XFA_ELEMENT_BindItems, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xdbfbe02e, (FX_LPCWSTR)L"calculate", XFA_ELEMENT_Calculate, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xdd7676ed, (FX_LPCWSTR)L"print", XFA_ELEMENT_Print, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xdde273d7, (FX_LPCWSTR)L"extras", XFA_ELEMENT_Extras, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xde146b34, (FX_LPCWSTR)L"proto", XFA_ELEMENT_Proto, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xdf059321, (FX_LPCWSTR)L"dSigData", XFA_ELEMENT_DSigData, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xdfccf030, (FX_LPCWSTR)L"creator", XFA_ELEMENT_Creator, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xdff78c6a, (FX_LPCWSTR)L"connect", XFA_ELEMENT_Connect, XFA_XDPPACKET_SourceSet | XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xe11a2cbc, (FX_LPCWSTR)L"permissions", XFA_ELEMENT_Permissions, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xe14c801c, (FX_LPCWSTR)L"connectionSet", XFA_ELEMENT_ConnectionSet, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_ModelNode},
+ {0xe1c83a14, (FX_LPCWSTR)L"submit", XFA_ELEMENT_Submit, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xe29821cd, (FX_LPCWSTR)L"range", XFA_ELEMENT_Range, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xe38d83c7, (FX_LPCWSTR)L"linearized", XFA_ELEMENT_Linearized, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xe3aa2578, (FX_LPCWSTR)L"packet", XFA_ELEMENT_Packet, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_NodeC},
+ {0xe3aa860e, (FX_LPCWSTR)L"rootElement", XFA_ELEMENT_RootElement, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_TextNode},
+ {0xe3e553fa, (FX_LPCWSTR)L"plaintextMetadata", XFA_ELEMENT_PlaintextMetadata, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xe3e6e4f2, (FX_LPCWSTR)L"numberSymbols", XFA_ELEMENT_NumberSymbols, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0xe3f067f6, (FX_LPCWSTR)L"printHighQuality", XFA_ELEMENT_PrintHighQuality, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xe3fd078c, (FX_LPCWSTR)L"driver", XFA_ELEMENT_Driver, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xe48b34f2, (FX_LPCWSTR)L"incrementalLoad", XFA_ELEMENT_IncrementalLoad, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xe550e7c2, (FX_LPCWSTR)L"subjectDN", XFA_ELEMENT_SubjectDN, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_NodeC},
+ {0xe6669a78, (FX_LPCWSTR)L"compressLogicalStructure", XFA_ELEMENT_CompressLogicalStructure, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xe7a7ea02, (FX_LPCWSTR)L"incrementalMerge", XFA_ELEMENT_IncrementalMerge, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xe948530d, (FX_LPCWSTR)L"radial", XFA_ELEMENT_Radial, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xea8d6999, (FX_LPCWSTR)L"variables", XFA_ELEMENT_Variables, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContainerNode},
+ {0xeaa142c0, (FX_LPCWSTR)L"timePatterns", XFA_ELEMENT_TimePatterns, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0xeb943a71, (FX_LPCWSTR)L"effectiveInputPolicy", XFA_ELEMENT_EffectiveInputPolicy, XFA_XDPPACKET_ConnectionSet, XFA_OBJECTTYPE_Node},
+ {0xef04a2bc, (FX_LPCWSTR)L"nameAttr", XFA_ELEMENT_NameAttr, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xf07222ab, (FX_LPCWSTR)L"conformance", XFA_ELEMENT_Conformance, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xf0aaaadc, (FX_LPCWSTR)L"transform", XFA_ELEMENT_Transform, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_Node},
+ {0xf1433e88, (FX_LPCWSTR)L"lockDocument", XFA_ELEMENT_LockDocument, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_ContentNode},
+ {0xf54eb997, (FX_LPCWSTR)L"breakAfter", XFA_ELEMENT_BreakAfter, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xf616da28, (FX_LPCWSTR)L"line", XFA_ELEMENT_Line, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xf616f3dc, (FX_LPCWSTR)L"list", XFA_ELEMENT_List, XFA_XDPPACKET_XDP, XFA_OBJECTTYPE_OrdinaryList},
+ {0xf7055fb1, (FX_LPCWSTR)L"source", XFA_ELEMENT_Source, XFA_XDPPACKET_SourceSet, XFA_OBJECTTYPE_Node},
+ {0xf7eebe1c, (FX_LPCWSTR)L"occur", XFA_ELEMENT_Occur, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+ {0xf8d10d97, (FX_LPCWSTR)L"pickTrayByPDFSize", XFA_ELEMENT_PickTrayByPDFSize, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xf8f19e3a, (FX_LPCWSTR)L"monthNames", XFA_ELEMENT_MonthNames, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_Node},
+ {0xf984149b, (FX_LPCWSTR)L"severity", XFA_ELEMENT_Severity, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xf9bcb037, (FX_LPCWSTR)L"groupParent", XFA_ELEMENT_GroupParent, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_NodeV},
+ {0xfbc42fff, (FX_LPCWSTR)L"documentAssembly", XFA_ELEMENT_DocumentAssembly, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xfc78159f, (FX_LPCWSTR)L"numberSymbol", XFA_ELEMENT_NumberSymbol, XFA_XDPPACKET_LocaleSet, XFA_OBJECTTYPE_ContentNode},
+ {0xfcbd606c, (FX_LPCWSTR)L"tagged", XFA_ELEMENT_Tagged, XFA_XDPPACKET_Config, XFA_OBJECTTYPE_ContentNode},
+ {0xff063802, (FX_LPCWSTR)L"items", XFA_ELEMENT_Items, XFA_XDPPACKET_Template | XFA_XDPPACKET_Form, XFA_OBJECTTYPE_Node},
+};
+extern const FX_INT32 g_iXFAElementCount = sizeof(g_XFAElementData) / sizeof(XFA_ELEMENTINFO);
+extern const XFA_ELEMENTHIERARCHY g_XFAElementPropertyIndex[] = {
+ {0, 8}, {8, 0}, {8, 14}, {22, 0}, {22, 0}, {22, 6}, {28, 0}, {28, 0}, {28, 1}, {29, 3}, {32, 0}, {32, 0}, {32, 0}, {32, 3}, {35, 1}, {36, 0}, {36, 0}, {36, 2}, {38, 0}, {38, 0},
+ {38, 0}, {38, 4}, {42, 0}, {42, 0}, {42, 1}, {43, 0}, {43, 8}, {51, 19}, {70, 0}, {70, 0}, {70, 2}, {72, 1}, {73, 0}, {73, 2}, {75, 4}, {79, 1}, {80, 1}, {81, 0}, {81, 0}, {81, 3},
+ {84, 0}, {84, 4}, {88, 4}, {92, 1}, {93, 0}, {93, 4}, {97, 9}, {106, 14}, {120, 0}, {120, 0}, {120, 5}, {125, 0}, {125, 1}, {126, 0}, {126, 0}, {126, 0}, {126, 0}, {126, 0}, {126, 1}, {127, 0},
+ {127, 0}, {127, 0}, {127, 0}, {127, 0}, {127, 0}, {127, 0}, {127, 6}, {133, 1}, {134, 0}, {134, 1}, {135, 0}, {135, 0}, {135, 1}, {136, 2}, {138, 5}, {143, 2}, {145, 0}, {145, 0}, {145, 0}, {145, 0},
+ {145, 0}, {145, 5}, {150, 0}, {150, 0}, {150, 0}, {150, 0}, {150, 0}, {150, 0}, {150, 0}, {150, 2}, {152, 0}, {152, 0}, {152, 0}, {152, 17}, {169, 0}, {169, 1}, {170, 0}, {170, 0}, {170, 2}, {172, 0},
+ {172, 0}, {172, 1}, {173, 0}, {173, 0}, {173, 2}, {175, 2}, {177, 0}, {177, 0}, {177, 0}, {177, 11}, {188, 0}, {188, 0}, {188, 0}, {188, 0}, {188, 0}, {188, 4}, {192, 3}, {195, 0}, {195, 0}, {195, 0},
+ {195, 0}, {195, 0}, {195, 0}, {195, 9}, {204, 0}, {204, 0}, {204, 17}, {221, 0}, {221, 0}, {221, 0}, {221, 0}, {221, 0}, {221, 0}, {221, 0}, {221, 0}, {221, 0}, {221, 4}, {225, 0}, {225, 0}, {225, 0},
+ {225, 0}, {225, 2}, {227, 3}, {230, 0}, {230, 0}, {230, 2}, {232, 0}, {232, 1}, {233, 2}, {235, 2}, {237, 0}, {237, 0}, {237, 2}, {239, 0}, {239, 1}, {240, 1}, {241, 2}, {243, 0}, {243, 3}, {246, 4},
+ {250, 0}, {250, 1}, {251, 2}, {253, 0}, {253, 0}, {253, 0}, {253, 0}, {253, 0}, {253, 0}, {253, 0}, {253, 0}, {253, 0}, {253, 0}, {253, 2}, {255, 2}, {257, 0}, {257, 6}, {263, 5}, {268, 0}, {268, 0},
+ {268, 0}, {268, 3}, {271, 0}, {271, 0}, {271, 3}, {274, 4}, {278, 0}, {278, 0}, {278, 4}, {282, 0}, {282, 0}, {282, 5}, {287, 0}, {287, 5}, {292, 0}, {292, 0}, {292, 0}, {292, 1}, {293, 0}, {293, 0},
+ {293, 1}, {294, 0}, {294, 2}, {296, 0}, {296, 0}, {296, 0}, {296, 0}, {296, 1}, {297, 0}, {297, 0}, {297, 4}, {301, 0}, {301, 0}, {301, 0}, {301, 0}, {301, 0}, {301, 0}, {301, 1}, {302, 0}, {302, 2},
+ {304, 0}, {304, 0}, {304, 0}, {304, 0}, {304, 1}, {305, 4}, {309, 0}, {309, 3}, {312, 0}, {312, 0}, {312, 1}, {313, 0}, {313, 8}, {321, 0}, {321, 10}, {331, 0}, {331, 10}, {341, 1}, {342, 12}, {354, 3},
+ {357, 1}, {358, 0}, {358, 0}, {358, 0}, {358, 8}, {366, 0}, {366, 0}, {366, 0}, {366, 0}, {366, 0}, {366, 0}, {366, 7}, {373, 2}, {375, 0}, {375, 1}, {376, 0}, {376, 0}, {376, 0}, {376, 0}, {376, 0},
+ {376, 0}, {376, 0}, {376, 0}, {376, 13}, {389, 0}, {389, 1}, {390, 1}, {391, 0}, {391, 0}, {391, 3}, {394, 0}, {394, 0}, {394, 0}, {394, 0}, {394, 0}, {394, 4}, {398, 9}, {407, 0}, {407, 1}, {408, 0},
+ {408, 0}, {408, 0}, {408, 0}, {408, 0}, {408, 1}, {409, 0}, {409, 2}, {411, 0}, {411, 0}, {411, 0}, {411, 0}, {411, 2}, {413, 0}, {413, 1}, {414, 0}, {414, 0}, {414, 0}, {414, 7}, {421, 0}, {421, 1},
+ {422, 1}, {423, 0}, {423, 1}, {424, 1}, {425, 0}, {425, 1}, {426, 0}, {426, 0}, {426, 0}, {426, 0}, {426, 0}, {426, 0},
+};
+extern const XFA_PROPERTY g_XFAElementPropertyData[] = {
+ {XFA_ELEMENT_FontInfo, 1, 0}, {XFA_ELEMENT_Jog, 1, 0}, {XFA_ELEMENT_Xdc, 1, 0}, {XFA_ELEMENT_BatchOutput, 1, 0}, {XFA_ELEMENT_OutputBin, 1, 0}, {XFA_ELEMENT_Compress, 1, 0}, {XFA_ELEMENT_Staple, 1, 0}, {XFA_ELEMENT_MediumInfo, 1, 0}, {XFA_ELEMENT_CheckButton, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_ChoiceList, 1, XFA_PROPERTYFLAG_OneOf},
+ {XFA_ELEMENT_DefaultUi, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Barcode, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Button, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_DateTimeEdit, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Picture, 1, 0}, {XFA_ELEMENT_ImageEdit, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_PasswordEdit, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_NumericEdit, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Signature, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_TextEdit, 1, XFA_PROPERTYFLAG_OneOf},
+ {XFA_ELEMENT_ExObject, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Break, 1, 0}, {XFA_ELEMENT_Overflow, 1, 0}, {XFA_ELEMENT_Desc, 1, 0}, {XFA_ELEMENT_Bookend, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Occur, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_SubsetBelow, 1, 0},
+ {XFA_ELEMENT_Map, 1, 0}, {XFA_ELEMENT_Embed, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_DatePattern, 4, 0}, {XFA_ELEMENT_Edge, 1, 0}, {XFA_ELEMENT_Fill, 1, 0}, {XFA_ELEMENT_To, 1, 0}, {XFA_ELEMENT_Uri, 1, 0},
+ {XFA_ELEMENT_Mode, 1, 0}, {XFA_ELEMENT_Threshold, 1, 0}, {XFA_ELEMENT_Script, 1, 0}, {XFA_ELEMENT_FontInfo, 1, 0}, {XFA_ELEMENT_Jog, 1, 0}, {XFA_ELEMENT_Xdc, 1, 0}, {XFA_ELEMENT_BatchOutput, 1, 0}, {XFA_ELEMENT_PageOffset, 1, 0}, {XFA_ELEMENT_OutputBin, 1, 0}, {XFA_ELEMENT_Staple, 1, 0},
+ {XFA_ELEMENT_MediumInfo, 1, 0}, {XFA_ELEMENT_AdobeExtensionLevel, 1, 0}, {XFA_ELEMENT_FontInfo, 1, 0}, {XFA_ELEMENT_Xdc, 1, 0}, {XFA_ELEMENT_Pdfa, 1, 0}, {XFA_ELEMENT_BatchOutput, 1, 0}, {XFA_ELEMENT_ViewerPreferences, 1, 0}, {XFA_ELEMENT_ScriptModel, 1, 0}, {XFA_ELEMENT_Version, 1, 0}, {XFA_ELEMENT_SubmitFormat, 1, 0},
+ {XFA_ELEMENT_SilentPrint, 1, 0}, {XFA_ELEMENT_Producer, 1, 0}, {XFA_ELEMENT_Compression, 1, 0}, {XFA_ELEMENT_Interactive, 1, 0}, {XFA_ELEMENT_Encryption, 1, 0}, {XFA_ELEMENT_RenderPolicy, 1, 0}, {XFA_ELEMENT_OpenAction, 1, 0}, {XFA_ELEMENT_Creator, 1, 0}, {XFA_ELEMENT_Linearized, 1, 0}, {XFA_ELEMENT_Tagged, 1, 0},
+ {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_Xsl, 1, 0}, {XFA_ELEMENT_Packets, 1, 0}, {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_Debug, 1, 0}, {XFA_ELEMENT_FontInfo, 1, 0}, {XFA_ELEMENT_Xdc, 1, 0}, {XFA_ELEMENT_BatchOutput, 1, 0}, {XFA_ELEMENT_FlipLabel, 1, 0}, {XFA_ELEMENT_TemplateCache, 1, 0},
+ {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_FontInfo, 1, 0}, {XFA_ELEMENT_Xdc, 1, 0}, {XFA_ELEMENT_BatchOutput, 1, 0}, {XFA_ELEMENT_FlipLabel, 1, 0}, {XFA_ELEMENT_EraNames, 1, 0}, {XFA_ELEMENT_DayNames, 2, 0},
+ {XFA_ELEMENT_MeridiemNames, 1, 0}, {XFA_ELEMENT_MonthNames, 2, 0}, {XFA_ELEMENT_Hyphenation, 1, 0}, {XFA_ELEMENT_Amd, 1, 0}, {XFA_ELEMENT_Part, 1, 0}, {XFA_ELEMENT_IncludeXDPContent, 1, 0}, {XFA_ELEMENT_Conformance, 1, 0}, {XFA_ELEMENT_Mdp, 1, 0}, {XFA_ELEMENT_Certificates, 1, 0}, {XFA_ELEMENT_TimeStamp, 1, 0},
+ {XFA_ELEMENT_Handler, 1, 0}, {XFA_ELEMENT_DigestMethods, 1, 0}, {XFA_ELEMENT_Encodings, 1, 0}, {XFA_ELEMENT_Reasons, 1, 0}, {XFA_ELEMENT_AppearanceFilter, 1, 0}, {XFA_ELEMENT_LockDocument, 1, 0}, {XFA_ELEMENT_Xdp, 1, 0}, {XFA_ELEMENT_Cache, 1, 0}, {XFA_ELEMENT_Pagination, 1, 0}, {XFA_ELEMENT_Overprint, 1, 0},
+ {XFA_ELEMENT_BehaviorOverride, 1, 0}, {XFA_ELEMENT_Copies, 1, 0}, {XFA_ELEMENT_Output, 1, 0}, {XFA_ELEMENT_Validate, 1, 0}, {XFA_ELEMENT_Layout, 1, 0}, {XFA_ELEMENT_Script, 1, 0}, {XFA_ELEMENT_Common, 1, 0}, {XFA_ELEMENT_PaginationOverride, 1, 0}, {XFA_ELEMENT_Destination, 1, 0}, {XFA_ELEMENT_IncrementalMerge, 1, 0},
+ {XFA_ELEMENT_Execute, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Script, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_SignData, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Submit, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_CurrencySymbol, 3, 0}, {XFA_ELEMENT_Operation, 1, 0}, {XFA_ELEMENT_WsdlAddress, 1, 0}, {XFA_ELEMENT_SoapAddress, 1, 0},
+ {XFA_ELEMENT_SoapAction, 1, 0}, {XFA_ELEMENT_EffectiveOutputPolicy, 1, 0}, {XFA_ELEMENT_EffectiveInputPolicy, 1, 0}, {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_Era, 2, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Picture, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Edge, 4, 0},
+ {XFA_ELEMENT_Corner, 4, 0}, {XFA_ELEMENT_Fill, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Desc, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_KeyUsage, 1, 0}, {XFA_ELEMENT_SubjectDNs, 1, 0}, {XFA_ELEMENT_Issuers, 1, 0}, {XFA_ELEMENT_Signing, 1, 0}, {XFA_ELEMENT_Oids, 1, 0},
+ {XFA_ELEMENT_Color, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Ui, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Para, 1, 0}, {XFA_ELEMENT_Format, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Assist, 1, 0}, {XFA_ELEMENT_Traversal, 1, 0}, {XFA_ELEMENT_Keep, 1, 0},
+ {XFA_ELEMENT_Validate, 1, 0}, {XFA_ELEMENT_Caption, 1, 0}, {XFA_ELEMENT_Bind, 1, 0}, {XFA_ELEMENT_Desc, 1, 0}, {XFA_ELEMENT_Font, 1, 0}, {XFA_ELEMENT_Value, 1, 0}, {XFA_ELEMENT_Calculate, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Items, 2, 0}, {XFA_ELEMENT_Uri, 1, 0},
+ {XFA_ELEMENT_Desc, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Color, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Color, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Para, 1, 0}, {XFA_ELEMENT_Border, 1, 0},
+ {XFA_ELEMENT_Assist, 1, 0}, {XFA_ELEMENT_Traversal, 1, 0}, {XFA_ELEMENT_Validate, 1, 0}, {XFA_ELEMENT_Caption, 1, 0}, {XFA_ELEMENT_Bind, 1, 0}, {XFA_ELEMENT_Desc, 1, 0}, {XFA_ELEMENT_Calculate, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Border, 1, 0},
+ {XFA_ELEMENT_Comb, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Present, 1, 0}, {XFA_ELEMENT_Acrobat, 1, 0}, {XFA_ELEMENT_Trace, 1, 0}, {XFA_ELEMENT_PrintScaling, 1, 0}, {XFA_ELEMENT_Enforce, 1, 0}, {XFA_ELEMENT_NumberOfCopies, 1, 0}, {XFA_ELEMENT_PageRange, 1, 0}, {XFA_ELEMENT_AddViewerPreferences, 1, 0},
+ {XFA_ELEMENT_ADBE_JSConsole, 1, 0}, {XFA_ELEMENT_DuplexOption, 1, 0}, {XFA_ELEMENT_ADBE_JSDebugger, 1, 0}, {XFA_ELEMENT_PickTrayByPDFSize, 1, 0}, {XFA_ELEMENT_Break, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Para, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Assist, 1, 0}, {XFA_ELEMENT_Traversal, 1, 0},
+ {XFA_ELEMENT_Keep, 1, 0}, {XFA_ELEMENT_Validate, 1, 0}, {XFA_ELEMENT_PageSet, 1, 0}, {XFA_ELEMENT_Overflow, 1, 0}, {XFA_ELEMENT_Bind, 1, 0}, {XFA_ELEMENT_Desc, 1, 0}, {XFA_ELEMENT_Bookend, 1, 0}, {XFA_ELEMENT_Calculate, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Variables, 1, 0},
+ {XFA_ELEMENT_Occur, 1, 0}, {XFA_ELEMENT_Query, 1, 0}, {XFA_ELEMENT_Insert, 1, 0}, {XFA_ELEMENT_Update, 1, 0}, {XFA_ELEMENT_Delete, 1, 0}, {XFA_ELEMENT_MsgId, 1, 0}, {XFA_ELEMENT_Severity, 1, 0}, {XFA_ELEMENT_To, 1, 0}, {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_Type, 1, 0},
+ {XFA_ELEMENT_ToolTip, 1, 0}, {XFA_ELEMENT_Speak, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_AddSilentPrint, 1, 0}, {XFA_ELEMENT_PrinterName, 1, 0}, {XFA_ELEMENT_FontInfo, 1, 0}, {XFA_ELEMENT_Xdc, 1, 0}, {XFA_ELEMENT_Color, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Extras, 1, 0},
+ {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_RecordSet, 1, 0}, {XFA_ELEMENT_Select, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Message, 1, 0}, {XFA_ELEMENT_Picture, 1, 0}, {XFA_ELEMENT_Script, 1, 0}, {XFA_ELEMENT_Extras, 1, 0},
+ {XFA_ELEMENT_NumberPattern, 4, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Occur, 1, 0}, {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_RootElement, 1, 0}, {XFA_ELEMENT_Script, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_Xsl, 1, 0}, {XFA_ELEMENT_StartPage, 1, 0},
+ {XFA_ELEMENT_Relevant, 1, 0}, {XFA_ELEMENT_Base, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_AutoSave, 1, 0}, {XFA_ELEMENT_Validate, 1, 0}, {XFA_ELEMENT_ValidateApprovalSignatures, 1, 0}, {XFA_ELEMENT_Acrobat7, 1, 0}, {XFA_ELEMENT_Common, 1, 0}, {XFA_ELEMENT_Exclude, 1, 0}, {XFA_ELEMENT_CurrentPage, 1, 0},
+ {XFA_ELEMENT_RunScripts, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Comb, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Medium, 1, 0}, {XFA_ELEMENT_Desc, 1, 0},
+ {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Occur, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Filter, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Manifest, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Para, 1, 0}, {XFA_ELEMENT_Font, 1, 0},
+ {XFA_ELEMENT_Value, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Day, 7, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Color, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Occur, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Comb, 1, 0},
+ {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_Filter, 1, 0}, {XFA_ELEMENT_Manifest, 1, 0}, {XFA_ELEMENT_Picture, 1, 0}, {XFA_ELEMENT_Level, 1, 0}, {XFA_ELEMENT_Type, 1, 0}, {XFA_ELEMENT_CompressObjectStream, 1, 0}, {XFA_ELEMENT_CompressLogicalStructure, 1, 0}, {XFA_ELEMENT_Edge, 4, 0},
+ {XFA_ELEMENT_Corner, 4, 0}, {XFA_ELEMENT_Fill, 1, 0}, {XFA_ELEMENT_DynamicRender, 1, 0}, {XFA_ELEMENT_DatePatterns, 1, 0}, {XFA_ELEMENT_CalendarSymbols, 1, 0}, {XFA_ELEMENT_CurrencySymbols, 1, 0}, {XFA_ELEMENT_Typefaces, 1, 0}, {XFA_ELEMENT_DateTimeSymbols, 1, 0}, {XFA_ELEMENT_NumberPatterns, 1, 0}, {XFA_ELEMENT_NumberSymbols, 1, 0},
+ {XFA_ELEMENT_TimePatterns, 1, 0}, {XFA_ELEMENT_Uri, 1, 0}, {XFA_ELEMENT_Xsl, 1, 0}, {XFA_ELEMENT_StartNode, 1, 0}, {XFA_ELEMENT_OutputXSL, 1, 0}, {XFA_ELEMENT_AdjustData, 1, 0}, {XFA_ELEMENT_Attributes, 1, 0}, {XFA_ELEMENT_Window, 1, 0}, {XFA_ELEMENT_Record, 1, 0}, {XFA_ELEMENT_Range, 1, 0},
+ {XFA_ELEMENT_IncrementalLoad, 1, 0}, {XFA_ELEMENT_Text, 1, 0}, {XFA_ELEMENT_Time, 1, 0}, {XFA_ELEMENT_DateTime, 1, 0}, {XFA_ELEMENT_Image, 1, 0}, {XFA_ELEMENT_Decimal, 1, 0}, {XFA_ELEMENT_Boolean, 1, 0}, {XFA_ELEMENT_Integer, 1, 0}, {XFA_ELEMENT_ExData, 1, 0}, {XFA_ELEMENT_Date, 1, 0},
+ {XFA_ELEMENT_Float, 1, 0}, {XFA_ELEMENT_Certificate, 1, 0}, {XFA_ELEMENT_Ui, 1, 0}, {XFA_ELEMENT_Margin, 1, 0}, {XFA_ELEMENT_Para, 1, 0}, {XFA_ELEMENT_Border, 1, 0}, {XFA_ELEMENT_Assist, 1, 0}, {XFA_ELEMENT_Traversal, 1, 0}, {XFA_ELEMENT_Keep, 1, 0}, {XFA_ELEMENT_Caption, 1, 0},
+ {XFA_ELEMENT_Desc, 1, 0}, {XFA_ELEMENT_Font, 1, 0}, {XFA_ELEMENT_Value, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_EncryptionLevel, 1, 0}, {XFA_ELEMENT_Encrypt, 1, 0}, {XFA_ELEMENT_Permissions, 1, 0}, {XFA_ELEMENT_Meridiem, 2, 0}, {XFA_ELEMENT_SuppressBanner, 1, 0}, {XFA_ELEMENT_VersionControl, 1, 0},
+ {XFA_ELEMENT_LocaleSet, 1, 0}, {XFA_ELEMENT_Template, 1, 0}, {XFA_ELEMENT_ValidationMessaging, 1, 0}, {XFA_ELEMENT_Locale, 1, 0}, {XFA_ELEMENT_Data, 1, 0}, {XFA_ELEMENT_Messaging, 1, 0}, {XFA_ELEMENT_Pattern, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Solid, 1, XFA_PROPERTYFLAG_OneOf | XFA_PROPERTYFLAG_DefaultOneOf}, {XFA_ELEMENT_Stipple, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Color, 1, 0},
+ {XFA_ELEMENT_Linear, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Radial, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Fill, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Map, 1, 0}, {XFA_ELEMENT_Arc, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Text, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Time, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_DateTime, 1, XFA_PROPERTYFLAG_OneOf},
+ {XFA_ELEMENT_Image, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Decimal, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Boolean, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Integer, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_ExData, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Rectangle, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Date, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Float, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Line, 1, XFA_PROPERTYFLAG_OneOf}, {XFA_ELEMENT_Extras, 1, 0},
+ {XFA_ELEMENT_Destination, 1, 0}, {XFA_ELEMENT_Message, 1, 0}, {XFA_ELEMENT_Script, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Picture, 1, 0}, {XFA_ELEMENT_ConnectString, 1, 0}, {XFA_ELEMENT_User, 1, 0}, {XFA_ELEMENT_Password, 1, 0}, {XFA_ELEMENT_ModifyAnnots, 1, 0}, {XFA_ELEMENT_ContentCopy, 1, 0},
+ {XFA_ELEMENT_FormFieldFilling, 1, 0}, {XFA_ELEMENT_Change, 1, 0}, {XFA_ELEMENT_AccessibleContent, 1, 0}, {XFA_ELEMENT_Print, 1, 0}, {XFA_ELEMENT_PlaintextMetadata, 1, 0}, {XFA_ELEMENT_PrintHighQuality, 1, 0}, {XFA_ELEMENT_DocumentAssembly, 1, 0}, {XFA_ELEMENT_Encrypt, 1, 0}, {XFA_ELEMENT_NumberSymbol, 5, 0}, {XFA_ELEMENT_FontInfo, 1, 0},
+ {XFA_ELEMENT_Xdc, 1, 0}, {XFA_ELEMENT_Color, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_TimePattern, 4, 0}, {XFA_ELEMENT_Whitespace, 1, 0}, {XFA_ELEMENT_Rename, 1, 0}, {XFA_ELEMENT_IfEmpty, 1, 0}, {XFA_ELEMENT_Presence, 1, 0}, {XFA_ELEMENT_Picture, 1, 0}, {XFA_ELEMENT_NameAttr, 1, 0},
+ {XFA_ELEMENT_GroupParent, 1, 0}, {XFA_ELEMENT_Script, 1, 0}, {XFA_ELEMENT_Edge, 1, 0}, {XFA_ELEMENT_Connect, 1, 0}, {XFA_ELEMENT_Extras, 1, 0}, {XFA_ELEMENT_Month, 12, 0},
+};
+extern const XFA_ELEMENTHIERARCHY g_XFAElementChildrenIndex[] = {
+ {0, 0}, {0, 0}, {0, 0}, {0, 1}, {1, 0}, {1, 4}, {5, 0}, {5, 0}, {5, 0}, {5, 3}, {8, 0}, {8, 0}, {8, 0}, {8, 0}, {8, 0}, {8, 1}, {9, 0}, {9, 0}, {9, 0}, {9, 0},
+ {9, 0}, {9, 0}, {9, 2}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0},
+ {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 0}, {11, 8}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0}, {19, 0},
+ {19, 0}, {19, 0}, {19, 1}, {20, 1}, {21, 1}, {22, 0}, {22, 0}, {22, 0}, {22, 0}, {22, 0}, {22, 0}, {22, 0}, {22, 0}, {22, 0}, {22, 0}, {22, 7}, {29, 0}, {29, 0}, {29, 0}, {29, 0},
+ {29, 0}, {29, 0}, {29, 1}, {30, 1}, {31, 0}, {31, 0}, {31, 0}, {31, 0}, {31, 0}, {31, 0}, {31, 0}, {31, 0}, {31, 0}, {31, 4}, {35, 2}, {37, 0}, {37, 0}, {37, 0}, {37, 0}, {37, 0},
+ {37, 0}, {37, 0}, {37, 0}, {37, 0}, {37, 0}, {37, 0}, {37, 0}, {37, 0}, {37, 0}, {37, 4}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 0}, {41, 2}, {43, 0}, {43, 0}, {43, 0},
+ {43, 0}, {43, 0}, {43, 0}, {43, 0}, {43, 0}, {43, 0}, {43, 13}, {56, 0}, {56, 0}, {56, 1}, {57, 0}, {57, 0}, {57, 0}, {57, 0}, {57, 0}, {57, 0}, {57, 0}, {57, 0}, {57, 0}, {57, 0},
+ {57, 0}, {57, 1}, {58, 0}, {58, 1}, {59, 0}, {59, 0}, {59, 0}, {59, 1}, {60, 0}, {60, 0}, {60, 0}, {60, 0}, {60, 0}, {60, 0}, {60, 0}, {60, 0}, {60, 1}, {61, 0}, {61, 0}, {61, 0},
+ {61, 1}, {62, 0}, {62, 2}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 0}, {64, 1}, {65, 1}, {66, 1}, {67, 0}, {67, 1},
+ {68, 0}, {68, 0}, {68, 0}, {68, 0}, {68, 0}, {68, 0}, {68, 0}, {68, 0}, {68, 6}, {74, 0}, {74, 1}, {75, 0}, {75, 0}, {75, 0}, {75, 0}, {75, 0}, {75, 0}, {75, 0}, {75, 0}, {75, 0},
+ {75, 1}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0},
+ {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 0}, {76, 2}, {78, 0}, {78, 0}, {78, 0}, {78, 1}, {79, 0},
+ {79, 0}, {79, 1}, {80, 0}, {80, 0}, {80, 1}, {81, 0}, {81, 0}, {81, 1}, {82, 0}, {82, 0}, {82, 0}, {82, 0}, {82, 0}, {82, 0}, {82, 0}, {82, 0}, {82, 0}, {82, 0}, {82, 1}, {83, 0},
+ {83, 0}, {83, 0}, {83, 0}, {83, 0}, {83, 0}, {83, 11}, {94, 0}, {94, 0}, {94, 0}, {94, 0}, {94, 0}, {94, 11}, {105, 106}, {211, 0}, {211, 0}, {211, 1}, {212, 0}, {212, 3}, {215, 1}, {216, 0},
+ {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 0}, {216, 12}, {228, 0}, {228, 0}, {228, 0}, {228, 0}, {228, 0}, {228, 0}, {228, 0},
+ {228, 0}, {228, 0}, {228, 2}, {230, 0}, {230, 0}, {230, 0}, {230, 0}, {230, 0}, {230, 0}, {230, 0}, {230, 0}, {230, 10},
+};
+extern const FX_WORD g_XFAElementChildrenData[] = {
+ XFA_ELEMENT_Extras, XFA_ELEMENT_SubformSet, XFA_ELEMENT_BreakBefore, XFA_ELEMENT_Subform, XFA_ELEMENT_BreakAfter, XFA_ELEMENT_AlwaysEmbed, XFA_ELEMENT_DefaultTypeface, XFA_ELEMENT_NeverEmbed, XFA_ELEMENT_Source, XFA_ELEMENT_Equate,
+ XFA_ELEMENT_EquateRange, XFA_ELEMENT_Ps, XFA_ELEMENT_Pcl, XFA_ELEMENT_Pdf, XFA_ELEMENT_Zpl, XFA_ELEMENT_LabelPrinter, XFA_ELEMENT_WebClient, XFA_ELEMENT_SubmitUrl, XFA_ELEMENT_Driver, XFA_ELEMENT_Typeface,
+ XFA_ELEMENT_SubjectDN, XFA_ELEMENT_Certificate, XFA_ELEMENT_SubformSet, XFA_ELEMENT_Area, XFA_ELEMENT_Field, XFA_ELEMENT_ExclGroup, XFA_ELEMENT_Subform, XFA_ELEMENT_Draw, XFA_ELEMENT_ExObject, XFA_ELEMENT_EncryptionMethod,
+ XFA_ELEMENT_Ref, XFA_ELEMENT_Event, XFA_ELEMENT_SetProperty, XFA_ELEMENT_BindItems, XFA_ELEMENT_Connect, XFA_ELEMENT_Pdf, XFA_ELEMENT_Destination, XFA_ELEMENT_Event, XFA_ELEMENT_SetProperty, XFA_ELEMENT_Field,
+ XFA_ELEMENT_Connect, XFA_ELEMENT_Agent, XFA_ELEMENT_PsMap, XFA_ELEMENT_SubformSet, XFA_ELEMENT_BreakBefore, XFA_ELEMENT_Event, XFA_ELEMENT_Area, XFA_ELEMENT_SetProperty, XFA_ELEMENT_Field, XFA_ELEMENT_ExclGroup,
+ XFA_ELEMENT_Subform, XFA_ELEMENT_Draw, XFA_ELEMENT_ExObject, XFA_ELEMENT_Proto, XFA_ELEMENT_Connect, XFA_ELEMENT_BreakAfter, XFA_ELEMENT_Locale, XFA_ELEMENT_Text, XFA_ELEMENT_Font, XFA_ELEMENT_Traverse,
+ XFA_ELEMENT_Map, XFA_ELEMENT_DigestMethod, XFA_ELEMENT_PageSet, XFA_ELEMENT_PageArea, XFA_ELEMENT_Encoding, XFA_ELEMENT_Subform, XFA_ELEMENT_SubmitUrl, XFA_ELEMENT_Certificate, XFA_ELEMENT_Area, XFA_ELEMENT_Field,
+ XFA_ELEMENT_ContentArea, XFA_ELEMENT_ExclGroup, XFA_ELEMENT_Subform, XFA_ELEMENT_Draw, XFA_ELEMENT_Oid, XFA_ELEMENT_Ref, XFA_ELEMENT_ExcludeNS, XFA_ELEMENT_Transform, XFA_ELEMENT_SetProperty, XFA_ELEMENT_Message,
+ XFA_ELEMENT_Log, XFA_ELEMENT_Reason, XFA_ELEMENT_Area, XFA_ELEMENT_Text, XFA_ELEMENT_Time, XFA_ELEMENT_DateTime, XFA_ELEMENT_Image, XFA_ELEMENT_Decimal, XFA_ELEMENT_Boolean, XFA_ELEMENT_Integer,
+ XFA_ELEMENT_ExData, XFA_ELEMENT_Date, XFA_ELEMENT_Float, XFA_ELEMENT_ExObject, XFA_ELEMENT_Text, XFA_ELEMENT_Time, XFA_ELEMENT_DateTime, XFA_ELEMENT_Image, XFA_ELEMENT_Decimal, XFA_ELEMENT_Boolean,
+ XFA_ELEMENT_Integer, XFA_ELEMENT_ExData, XFA_ELEMENT_Date, XFA_ELEMENT_Float, XFA_ELEMENT_Extras, XFA_ELEMENT_Ui, XFA_ELEMENT_SubformSet, XFA_ELEMENT_Break, XFA_ELEMENT_CheckButton, XFA_ELEMENT_Arc,
+ XFA_ELEMENT_Mdp, XFA_ELEMENT_BreakBefore, XFA_ELEMENT_Oid, XFA_ELEMENT_Ref, XFA_ELEMENT_Margin, XFA_ELEMENT_KeyUsage, XFA_ELEMENT_ChoiceList, XFA_ELEMENT_Para, XFA_ELEMENT_Filter, XFA_ELEMENT_Encoding,
+ XFA_ELEMENT_Event, XFA_ELEMENT_DefaultUi, XFA_ELEMENT_Barcode, XFA_ELEMENT_SubjectDNs, XFA_ELEMENT_Issuers, XFA_ELEMENT_Button, XFA_ELEMENT_Format, XFA_ELEMENT_Border, XFA_ELEMENT_Area, XFA_ELEMENT_Hyphenation,
+ XFA_ELEMENT_Text, XFA_ELEMENT_Time, XFA_ELEMENT_Certificates, XFA_ELEMENT_SetProperty, XFA_ELEMENT_DateTime, XFA_ELEMENT_Comb, XFA_ELEMENT_Pattern, XFA_ELEMENT_Field, XFA_ELEMENT_ContentArea, XFA_ELEMENT_Solid,
+ XFA_ELEMENT_Edge, XFA_ELEMENT_Stipple, XFA_ELEMENT_ExclGroup, XFA_ELEMENT_ToolTip, XFA_ELEMENT_Reason, XFA_ELEMENT_Execute, XFA_ELEMENT_DateTimeEdit, XFA_ELEMENT_Image, XFA_ELEMENT_TimeStamp, XFA_ELEMENT_Decimal,
+ XFA_ELEMENT_Subform, XFA_ELEMENT_Handler, XFA_ELEMENT_Boolean, XFA_ELEMENT_Message, XFA_ELEMENT_Assist, XFA_ELEMENT_Picture, XFA_ELEMENT_Traversal, XFA_ELEMENT_Corner, XFA_ELEMENT_Color, XFA_ELEMENT_Keep,
+ XFA_ELEMENT_ImageEdit, XFA_ELEMENT_Validate, XFA_ELEMENT_DigestMethods, XFA_ELEMENT_PageSet, XFA_ELEMENT_Integer, XFA_ELEMENT_Traverse, XFA_ELEMENT_Encodings, XFA_ELEMENT_Signing, XFA_ELEMENT_Script, XFA_ELEMENT_PasswordEdit,
+ XFA_ELEMENT_NumericEdit, XFA_ELEMENT_PageArea, XFA_ELEMENT_Oids, XFA_ELEMENT_Signature, XFA_ELEMENT_Caption, XFA_ELEMENT_ExData, XFA_ELEMENT_Manifest, XFA_ELEMENT_Overflow, XFA_ELEMENT_Linear, XFA_ELEMENT_DigestMethod,
+ XFA_ELEMENT_Medium, XFA_ELEMENT_TextEdit, XFA_ELEMENT_SignData, XFA_ELEMENT_Rectangle, XFA_ELEMENT_Date, XFA_ELEMENT_Desc, XFA_ELEMENT_Encrypt, XFA_ELEMENT_Draw, XFA_ELEMENT_Speak, XFA_ELEMENT_Reasons,
+ XFA_ELEMENT_AppearanceFilter, XFA_ELEMENT_Fill, XFA_ELEMENT_Font, XFA_ELEMENT_Certificate, XFA_ELEMENT_Float, XFA_ELEMENT_Value, XFA_ELEMENT_Bookend, XFA_ELEMENT_ExObject, XFA_ELEMENT_BindItems, XFA_ELEMENT_Calculate,
+ XFA_ELEMENT_Extras, XFA_ELEMENT_Connect, XFA_ELEMENT_Submit, XFA_ELEMENT_SubjectDN, XFA_ELEMENT_Radial, XFA_ELEMENT_Variables, XFA_ELEMENT_LockDocument, XFA_ELEMENT_BreakAfter, XFA_ELEMENT_Line, XFA_ELEMENT_Occur,
+ XFA_ELEMENT_Items, XFA_ELEMENT_Extras, XFA_ELEMENT_WsdlConnection, XFA_ELEMENT_XsdConnection, XFA_ELEMENT_XmlConnection, XFA_ELEMENT_SignData, XFA_ELEMENT_Text, XFA_ELEMENT_Time, XFA_ELEMENT_DateTime, XFA_ELEMENT_Image,
+ XFA_ELEMENT_Decimal, XFA_ELEMENT_Boolean, XFA_ELEMENT_Integer, XFA_ELEMENT_Script, XFA_ELEMENT_ExData, XFA_ELEMENT_Manifest, XFA_ELEMENT_Date, XFA_ELEMENT_Float, XFA_ELEMENT_Command, XFA_ELEMENT_Bind,
+ XFA_ELEMENT_Text, XFA_ELEMENT_Time, XFA_ELEMENT_DateTime, XFA_ELEMENT_Image, XFA_ELEMENT_Decimal, XFA_ELEMENT_Boolean, XFA_ELEMENT_Integer, XFA_ELEMENT_ExData, XFA_ELEMENT_Date, XFA_ELEMENT_Float,
+};
+extern const XFA_ELEMENTHIERARCHY g_XFAElementAttributeIndex[] = {
+ {0, 3}, {3, 2}, {5, 3}, {8, 10}, {18, 2}, {20, 6}, {26, 2}, {28, 1}, {29, 13}, {42, 2}, {44, 1}, {45, 2}, {47, 2}, {49, 7}, {56, 0}, {56, 4}, {60, 2}, {62, 7}, {69, 0}, {69, 0},
+ {69, 2}, {71, 2}, {73, 8}, {81, 5}, {86, 8}, {94, 4}, {98, 3}, {101, 3}, {104, 3}, {107, 6}, {113, 2}, {115, 2}, {117, 2}, {119, 2}, {121, 3}, {124, 2}, {126, 7}, {133, 13}, {146, 2}, {148, 6},
+ {154, 2}, {156, 3}, {159, 1}, {160, 17}, {177, 2}, {179, 2}, {181, 6}, {187, 2}, {189, 2}, {191, 3}, {194, 7}, {201, 2}, {203, 3}, {206, 0}, {206, 21}, {227, 1}, {228, 3}, {231, 2}, {233, 0}, {233, 2},
+ {235, 2}, {237, 6}, {243, 0}, {243, 4}, {247, 4}, {251, 0}, {251, 2}, {253, 2}, {255, 0}, {255, 0}, {255, 2}, {257, 2}, {259, 4}, {263, 3}, {266, 7}, {273, 10}, {283, 9}, {292, 6}, {298, 4}, {302, 2},
+ {304, 2}, {306, 6}, {312, 4}, {316, 3}, {319, 2}, {321, 2}, {323, 4}, {327, 4}, {331, 4}, {335, 4}, {339, 2}, {341, 2}, {343, 2}, {345, 22}, {367, 3}, {370, 2}, {372, 2}, {374, 2}, {376, 9}, {385, 0},
+ {385, 4}, {389, 3}, {392, 0}, {392, 2}, {394, 7}, {401, 4}, {405, 2}, {407, 4}, {411, 0}, {411, 21}, {432, 4}, {436, 3}, {439, 4}, {443, 6}, {449, 2}, {451, 5}, {456, 2}, {458, 8}, {466, 1}, {467, 2},
+ {469, 2}, {471, 5}, {476, 0}, {476, 2}, {478, 2}, {480, 6}, {486, 26}, {512, 4}, {516, 2}, {518, 2}, {520, 4}, {524, 0}, {524, 2}, {526, 2}, {528, 2}, {530, 2}, {532, 5}, {537, 2}, {539, 3}, {542, 2},
+ {544, 4}, {548, 5}, {553, 2}, {555, 0}, {555, 2}, {557, 4}, {561, 5}, {566, 3}, {569, 2}, {571, 3}, {574, 0}, {574, 2}, {576, 9}, {585, 2}, {587, 5}, {592, 6}, {598, 5}, {603, 4}, {607, 4}, {611, 8},
+ {619, 4}, {623, 0}, {623, 7}, {630, 4}, {634, 4}, {638, 5}, {643, 2}, {645, 2}, {647, 4}, {651, 4}, {655, 2}, {657, 2}, {659, 1}, {660, 2}, {662, 5}, {667, 4}, {671, 3}, {674, 2}, {676, 2}, {678, 4},
+ {682, 0}, {682, 9}, {691, 2}, {693, 2}, {695, 5}, {700, 4}, {704, 3}, {707, 2}, {709, 10}, {719, 2}, {721, 4}, {725, 4}, {729, 2}, {731, 6}, {737, 2}, {739, 2}, {741, 9}, {750, 1}, {751, 4}, {755, 3},
+ {758, 5}, {763, 6}, {769, 4}, {773, 1}, {774, 4}, {778, 0}, {778, 3}, {781, 1}, {782, 5}, {787, 10}, {797, 7}, {804, 3}, {807, 2}, {809, 5}, {814, 2}, {816, 0}, {816, 2}, {818, 2}, {820, 2}, {822, 6},
+ {828, 2}, {830, 1}, {831, 2}, {833, 2}, {835, 8}, {843, 2}, {845, 4}, {849, 4}, {853, 4}, {857, 2}, {859, 2}, {861, 2}, {863, 3}, {866, 2}, {868, 2}, {870, 4}, {874, 3}, {877, 5}, {882, 20}, {902, 2},
+ {904, 0}, {904, 2}, {906, 6}, {912, 1}, {913, 2}, {915, 1}, {916, 2}, {918, 4}, {922, 2}, {924, 2}, {926, 4}, {930, 4}, {934, 20}, {954, 1}, {955, 2}, {957, 4}, {961, 4}, {965, 2}, {967, 2}, {969, 4},
+ {973, 2}, {975, 0}, {975, 2}, {977, 5}, {982, 5}, {987, 8}, {995, 2}, {997, 2}, {999, 4}, {1003, 4}, {1007, 2}, {1009, 4}, {1013, 0}, {1013, 1}, {1014, 2}, {1016, 9}, {1025, 2}, {1027, 0}, {1027, 8}, {1035, 2},
+ {1037, 2}, {1039, 0}, {1039, 4}, {1043, 2}, {1045, 0}, {1045, 2}, {1047, 3}, {1050, 2}, {1052, 5}, {1057, 2}, {1059, 2}, {1061, 4}, {1065, 3}, {1068, 0}, {1068, 4}, {1072, 2}, {1074, 2}, {1076, 3}, {1079, 4}, {1083, 8},
+ {1091, 5}, {1096, 0}, {1096, 4}, {1100, 6}, {1106, 2}, {1108, 1}, {1109, 2}, {1111, 2}, {1113, 2}, {1115, 1}, {1116, 2}, {1118, 7},
+};
+extern const FX_BYTE g_XFAElementAttributeData[] = {
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Max, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_EofAction, XFA_ATTRIBUTE_CursorType, XFA_ATTRIBUTE_LockType, XFA_ATTRIBUTE_BofAction, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_CursorLocation, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_BeforeTarget, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_OverflowTarget, XFA_ATTRIBUTE_OverflowLeader, XFA_ATTRIBUTE_OverflowTrailer, XFA_ATTRIBUTE_StartNew, XFA_ATTRIBUTE_BookendTrailer, XFA_ATTRIBUTE_After, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_BookendLeader,
+ XFA_ATTRIBUTE_AfterTarget, XFA_ATTRIBUTE_Before, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_AllowNeutral, XFA_ATTRIBUTE_Mark, XFA_ATTRIBUTE_Shape, XFA_ATTRIBUTE_Size, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_StartAngle, XFA_ATTRIBUTE_SweepAngle, XFA_ATTRIBUTE_Circular, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Bind, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_From,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_SignatureType, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Permissions, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_StartNew, XFA_ATTRIBUTE_Trailer,
+ XFA_ATTRIBUTE_TargetType, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Target, XFA_ATTRIBUTE_Leader, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_TimeStamp, XFA_ATTRIBUTE_Uuid, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_LeftInset, XFA_ATTRIBUTE_BottomInset,
+ XFA_ATTRIBUTE_TopInset, XFA_ATTRIBUTE_RightInset, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_NonRepudiation, XFA_ATTRIBUTE_EncipherOnly, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_DigitalSignature, XFA_ATTRIBUTE_CrlSign,
+ XFA_ATTRIBUTE_KeyAgreement, XFA_ATTRIBUTE_KeyEncipherment, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_DataEncipherment, XFA_ATTRIBUTE_KeyCertSign, XFA_ATTRIBUTE_DecipherOnly, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Open, XFA_ATTRIBUTE_CommitOn, XFA_ATTRIBUTE_TextEntry, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTE_TextIndent, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Widows, XFA_ATTRIBUTE_MarginRight, XFA_ATTRIBUTE_MarginLeft, XFA_ATTRIBUTE_RadixOffset, XFA_ATTRIBUTE_Preserve, XFA_ATTRIBUTE_SpaceBelow,
+ XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTE_TabDefault, XFA_ATTRIBUTE_TabStops, XFA_ATTRIBUTE_Orphans, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_LineHeight, XFA_ATTRIBUTE_SpaceAbove, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Version, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_AddRevocationInfo, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Listen, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Activity, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_DataRowCount, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_DataPrep,
+ XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_TextLocation, XFA_ATTRIBUTE_ModuleWidth, XFA_ATTRIBUTE_PrintCheckDigit, XFA_ATTRIBUTE_ModuleHeight, XFA_ATTRIBUTE_StartChar, XFA_ATTRIBUTE_Truncate, XFA_ATTRIBUTE_WideNarrowRatio, XFA_ATTRIBUTE_ErrorCorrectionLevel, XFA_ATTRIBUTE_UpsMode,
+ XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTE_CharEncoding, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_DataColumnCount, XFA_ATTRIBUTE_RowColumnRatio, XFA_ATTRIBUTE_DataLength, XFA_ATTRIBUTE_EndChar, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Format, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Output, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Input, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_DataDescription, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Highlight, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Break, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Presence,
+ XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTE_X, XFA_ATTRIBUTE_Y, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Level, XFA_ATTRIBUTE_Relevant,
+ XFA_ATTRIBUTE_ColSpan, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_WordCharacterCount, XFA_ATTRIBUTE_Hyphenate, XFA_ATTRIBUTE_ExcludeInitialCap, XFA_ATTRIBUTE_PushCharacterCount, XFA_ATTRIBUTE_RemainCharacterCount,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_ExcludeAllCaps, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Rid, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_MaxChars, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Url, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_CredentialServerPolicy,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_UrlPolicy, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Connection, XFA_ATTRIBUTE_Target, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_X, XFA_ATTRIBUTE_Y, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_NumberOfCells, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_H, XFA_ATTRIBUTE_W, XFA_ATTRIBUTE_X, XFA_ATTRIBUTE_Y, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Access, XFA_ATTRIBUTE_Rotate, XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTE_MaxH, XFA_ATTRIBUTE_MaxW, XFA_ATTRIBUTE_MinH,
+ XFA_ATTRIBUTE_MinW, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_ColSpan, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Locale, XFA_ATTRIBUTE_AnchorType, XFA_ATTRIBUTE_AccessKey, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_H, XFA_ATTRIBUTE_W, XFA_ATTRIBUTE_X, XFA_ATTRIBUTE_Y,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Cap, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_Thickness,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Rate, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_SourceBelow, XFA_ATTRIBUTE_OutputBelow, XFA_ATTRIBUTE_SourceAbove,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_H, XFA_ATTRIBUTE_W, XFA_ATTRIBUTE_X, XFA_ATTRIBUTE_Y, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Access,
+ XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTE_MaxH, XFA_ATTRIBUTE_MaxW, XFA_ATTRIBUTE_MinH, XFA_ATTRIBUTE_MinW, XFA_ATTRIBUTE_Layout, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_ColSpan, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_AnchorType, XFA_ATTRIBUTE_AccessKey, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Rid, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Connection, XFA_ATTRIBUTE_RunAt, XFA_ATTRIBUTE_ExecuteType, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Picker, XFA_ATTRIBUTE_HScrollPolicy, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_ContentType, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Aspect, XFA_ATTRIBUTE_Href, XFA_ATTRIBUTE_Value, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Server, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_FracDigits, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_LeadDigits, XFA_ATTRIBUTE_H, XFA_ATTRIBUTE_W, XFA_ATTRIBUTE_X, XFA_ATTRIBUTE_Y,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_AllowMacro, XFA_ATTRIBUTE_ColumnWidths, XFA_ATTRIBUTE_Access, XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTE_MaxH,
+ XFA_ATTRIBUTE_MaxW, XFA_ATTRIBUTE_MinH, XFA_ATTRIBUTE_MinW, XFA_ATTRIBUTE_Layout, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_MergeMode, XFA_ATTRIBUTE_ColSpan, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Locale, XFA_ATTRIBUTE_AnchorType,
+ XFA_ATTRIBUTE_RestoreState, XFA_ATTRIBUTE_Scope, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Mode,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Role,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Stroke, XFA_ATTRIBUTE_Presence,
+ XFA_ATTRIBUTE_Inverted, XFA_ATTRIBUTE_Thickness, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Join, XFA_ATTRIBUTE_Radius, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_CSpace,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Value, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Next, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Previous, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Intact, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_CommandType, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Data, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_ScriptTest, XFA_ATTRIBUTE_NullTest, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_FormatTest, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Relation, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_DuplexImposition, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_To, XFA_ATTRIBUTE_Force,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_From, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Value,
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_DataDescription, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Operation, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_BaseProfile, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_ContentType, XFA_ATTRIBUTE_RunAt, XFA_ATTRIBUTE_Binding, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_PasswordChar, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_HScrollPolicy,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_HScrollPolicy, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_PagePosition, XFA_ATTRIBUTE_OddOrEven, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_InitialNumber, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Numbered, XFA_ATTRIBUTE_BlankOrNotBlank, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Reserve, XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Placement, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Rid, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_ContentType, XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_MaxLength, XFA_ATTRIBUTE_Href,
+ XFA_ATTRIBUTE_Abbr, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_WritingScript, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Action, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Trailer, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Target, XFA_ATTRIBUTE_Leader, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_To, XFA_ATTRIBUTE_UnicodeRange, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_From, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_TrayOut, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Orientation, XFA_ATTRIBUTE_ImagingBBox, XFA_ATTRIBUTE_Short, XFA_ATTRIBUTE_TrayIn, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Stock, XFA_ATTRIBUTE_Long, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_VScrollPolicy, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_AllowRichText, XFA_ATTRIBUTE_MultiLine, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_HScrollPolicy, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_MaxEntries, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_ContentType, XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTE_Value, XFA_ATTRIBUTE_IsNull, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_DataDescription,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Operation, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Target, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_ContentType,
+ XFA_ATTRIBUTE_TransferEncoding, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Match, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_H, XFA_ATTRIBUTE_W, XFA_ATTRIBUTE_X, XFA_ATTRIBUTE_Y, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_HAlign, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Rotate, XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_VAlign, XFA_ATTRIBUTE_MaxH, XFA_ATTRIBUTE_MaxW, XFA_ATTRIBUTE_MinH, XFA_ATTRIBUTE_MinW, XFA_ATTRIBUTE_Relevant, XFA_ATTRIBUTE_ColSpan, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Locale, XFA_ATTRIBUTE_AnchorType, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Rid, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Priority,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Disable, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Value, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_LineThrough, XFA_ATTRIBUTE_Typeface, XFA_ATTRIBUTE_FontHorizontalScale, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_KerningMode,
+ XFA_ATTRIBUTE_Underline, XFA_ATTRIBUTE_BaselineShift, XFA_ATTRIBUTE_OverlinePeriod, XFA_ATTRIBUTE_LetterSpacing, XFA_ATTRIBUTE_LineThroughPeriod, XFA_ATTRIBUTE_FontVerticalScale, XFA_ATTRIBUTE_PsName, XFA_ATTRIBUTE_Size, XFA_ATTRIBUTE_Posture, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Weight, XFA_ATTRIBUTE_UnderlinePeriod, XFA_ATTRIBUTE_Overline, XFA_ATTRIBUTE_GenericFamily, XFA_ATTRIBUTE_Checksum, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Relevant,
+ XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Override, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Trailer, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Leader, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_CodeType, XFA_ATTRIBUTE_Archive, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_CodeBase, XFA_ATTRIBUTE_ClassId, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Ref,
+ XFA_ATTRIBUTE_Connection, XFA_ATTRIBUTE_LabelRef, XFA_ATTRIBUTE_ValueRef, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Override, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Value, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Use,
+ XFA_ATTRIBUTE_Timeout, XFA_ATTRIBUTE_Connection, XFA_ATTRIBUTE_Usage, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_DelayedOpen, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Format,
+ XFA_ATTRIBUTE_EmbedPDF, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Target, XFA_ATTRIBUTE_TextEncoding, XFA_ATTRIBUTE_XdpContent, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock,
+ XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Delimiter, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id,
+ XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Type, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_StartNew, XFA_ATTRIBUTE_Trailer, XFA_ATTRIBUTE_TargetType, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Target,
+ XFA_ATTRIBUTE_Leader, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Slope, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Hand, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Usehref,
+ XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Max, XFA_ATTRIBUTE_Min, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Initial, XFA_ATTRIBUTE_Usehref, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Abbr, XFA_ATTRIBUTE_Desc,
+ XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Name, XFA_ATTRIBUTE_Desc, XFA_ATTRIBUTE_Lock, XFA_ATTRIBUTE_Id, XFA_ATTRIBUTE_Name,
+ XFA_ATTRIBUTE_Ref, XFA_ATTRIBUTE_Use, XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTE_Save, XFA_ATTRIBUTE_Usehref,
+};
+extern const XFA_PACKETINFO g_XFAPacketData[] = {
+ {0x0, NULL, XFA_XDPPACKET_USER, NULL, XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTMANY},
+ {0x811929d, (FX_LPCWSTR)L"sourceSet", XFA_XDPPACKET_SourceSet, (FX_LPCWSTR)L"http://www.xfa.org/schema/xfa-source-set/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0xb843dba, (FX_LPCWSTR)L"pdf", XFA_XDPPACKET_Pdf, (FX_LPCWSTR)L"http://ns.adobe.com/xdp/pdf/", XFA_XDPPACKET_FLAGS_COMPLETEMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0xc56afbf, (FX_LPCWSTR)L"xdc", XFA_XDPPACKET_Xdc, (FX_LPCWSTR)L"http://www.xfa.org/schema/xdc/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0xc56afcc, (FX_LPCWSTR)L"xdp", XFA_XDPPACKET_XDP, (FX_LPCWSTR)L"http://ns.adobe.com/xdp/", XFA_XDPPACKET_FLAGS_COMPLETEMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0x132a8fbc, (FX_LPCWSTR)L"xmpmeta", XFA_XDPPACKET_Xmpmeta, (FX_LPCWSTR)L"http://ns.adobe.com/xmpmeta/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTMANY},
+ {0x48d004a8, (FX_LPCWSTR)L"xfdf", XFA_XDPPACKET_Xfdf, (FX_LPCWSTR)L"http://ns.adobe.com/xfdf/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0x4e1e39b6, (FX_LPCWSTR)L"config", XFA_XDPPACKET_Config, (FX_LPCWSTR)L"http://www.xfa.org/schema/xci/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0x5473b6dc, (FX_LPCWSTR)L"localeSet", XFA_XDPPACKET_LocaleSet, (FX_LPCWSTR)L"http://www.xfa.org/schema/xfa-locale-set/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0x6038580a, (FX_LPCWSTR)L"stylesheet", XFA_XDPPACKET_Stylesheet, (FX_LPCWSTR)L"http://www.w3.org/1999/XSL/Transform", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTMANY},
+ {0x803550fc, (FX_LPCWSTR)L"template", XFA_XDPPACKET_Template, (FX_LPCWSTR)L"http://www.xfa.org/schema/xfa-template/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0x8b036f32, (FX_LPCWSTR)L"signature", XFA_XDPPACKET_Signature, (FX_LPCWSTR)L"http://www.w3.org/2000/09/xmldsig#", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0x99b95079, (FX_LPCWSTR)L"datasets", XFA_XDPPACKET_Datasets, (FX_LPCWSTR)L"http://www.xfa.org/schema/xfa-data/", XFA_XDPPACKET_FLAGS_PREFIXMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0xcd309ff4, (FX_LPCWSTR)L"form", XFA_XDPPACKET_Form, (FX_LPCWSTR)L"http://www.xfa.org/schema/xfa-form/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+ {0xe14c801c, (FX_LPCWSTR)L"connectionSet", XFA_XDPPACKET_ConnectionSet, (FX_LPCWSTR)L"http://www.xfa.org/schema/xfa-connection-set/", XFA_XDPPACKET_FLAGS_NOMATCH | XFA_XDPPACKET_FLAGS_SUPPORTONE},
+};
+extern const FX_INT32 g_iXFAPacketCount = sizeof(g_XFAPacketData) / sizeof(XFA_PACKETINFO);
+extern const XFA_SCRIPTHIERARCHY g_XFAScriptIndex[] = {
+ {0, 0, 0, 2, 316}, {0, 0, 2, 2, 316}, {0, 0, 4, 2, 316}, {0, 0, 6, 8, 316}, {0, 0, 14, 4, 316}, {0, 0, 18, 5, 317}, {0, 0, 23, 2, 316}, {0, 0, 25, 1, 316}, {0, 0, 26, 12, 316}, {0, 0, 38, 2, 316}, {0, 0, 40, 1, 316}, {0, 0, 41, 3, 316}, {0, 0, 44, 2, 316}, {0, 0, 46, 6, 316}, {0, 0, 52, 0, 316}, {0, 0, 52, 2, 319}, {0, 0, 54, 2, 316}, {0, 0, 56, 6, 316}, {0, 0, 62, 0, 316}, {0, 0, 62, 0, 316},
+ {0, 0, 62, 2, 316}, {0, 0, 64, 2, 316}, {0, 0, 66, 6, 316}, {0, 0, 72, 4, 316}, {0, 0, 76, 7, 316}, {0, 0, 83, 2, 320}, {0, 0, 85, 3, 316}, {0, 0, 88, 3, 316}, {0, 0, 91, 2, 320}, {0, 0, 93, 6, 320}, {0, 0, 99, 4, 316}, {0, 0, 103, 2, 316}, {0, 0, 105, 3, 319}, {0, 0, 108, 4, 316}, {0, 0, 112, 3, 316}, {0, 0, 115, 2, 316}, {0, 0, 117, 6, 316}, {0, 0, 123, 12, 316}, {0, 0, 135, 2, 316}, {0, 0, 137, 5, 316},
+ {0, 0, 142, 2, 316}, {0, 0, 144, 3, 316}, {0, 0, 147, 1, 316}, {0, 0, 148, 14, 316}, {0, 0, 162, 2, 316}, {0, 0, 164, 2, 316}, {0, 0, 166, 3, 316}, {0, 0, 169, 2, 316}, {0, 0, 171, 2, 316}, {0, 0, 173, 2, 316}, {0, 0, 175, 4, 316}, {0, 0, 179, 2, 316}, {0, 0, 181, 2, 316}, {0, 0, 183, 0, 319}, {0, 0, 183, 20, 316}, {0, 0, 203, 1, 316}, {0, 0, 204, 3, 316}, {0, 0, 207, 2, 316}, {0, 0, 209, 0, 316}, {0, 0, 209, 2, 316},
+ {0, 0, 211, 2, 316}, {0, 0, 213, 4, 320}, {0, 0, 217, 0, 316}, {0, 0, 217, 1, 316}, {0, 0, 218, 3, 316}, {0, 4, 221, 0, 312}, {4, 1, 221, 1, 316}, {5, 0, 222, 2, 316}, {5, 1, 224, 3, -1}, {6, 0, 227, 0, 316}, {6, 0, 227, 2, 316}, {6, 0, 229, 2, 316}, {6, 0, 231, 3, 316}, {6, 0, 234, 2, 316}, {6, 0, 236, 6, 316}, {6, 0, 242, 10, 317}, {6, 0, 252, 9, 316}, {6, 0, 261, 5, 318}, {6, 0, 266, 4, 318}, {6, 0, 270, 2, 316},
+ {6, 0, 272, 2, 316}, {6, 0, 274, 5, 316}, {6, 0, 279, 3, 316}, {6, 0, 282, 2, 316}, {6, 0, 284, 2, 316}, {6, 0, 286, 2, 316}, {6, 0, 288, 2, 316}, {6, 0, 290, 4, 316}, {6, 0, 294, 3, 316}, {6, 0, 297, 3, 316}, {6, 0, 300, 2, 316}, {6, 0, 302, 2, 316}, {6, 0, 304, 2, 316}, {6, 13, 306, 36, 317}, {19, 0, 342, 3, 316}, {19, 0, 345, 2, 316}, {19, 0, 347, 2, 316}, {19, 0, 349, 2, 316}, {19, 0, 351, 7, 317}, {19, 2, 358, 16, 312},
+ {21, 0, 374, 2, 320}, {21, 0, 376, 2, 316}, {21, 0, 378, 0, 316}, {21, 0, 378, 2, 316}, {21, 0, 380, 6, 316}, {21, 0, 386, 3, 316}, {21, 0, 389, 2, 316}, {21, 0, 391, 4, 316}, {21, 0, 395, 0, 316}, {21, 5, 395, 30, 316}, {26, 0, 425, 2, 320}, {26, 0, 427, 3, 316}, {26, 0, 430, 2, 320}, {26, 0, 432, 5, 316}, {26, 0, 437, 2, 316}, {26, 0, 439, 3, 316}, {26, 0, 442, 2, 316}, {26, 0, 444, 8, 316}, {26, 0, 452, 1, 316}, {26, 0, 453, 2, 316},
+ {26, 0, 455, 2, 316}, {26, 0, 457, 4, 316}, {26, 0, 461, 0, 316}, {26, 0, 461, 2, 316}, {26, 0, 463, 2, 316}, {26, 0, 465, 6, 318}, {26, 5, 471, 31, 317}, {31, 0, 502, 2, 320}, {31, 0, 504, 2, 316}, {31, 0, 506, 2, 316}, {31, 0, 508, 4, 320}, {31, 16, 512, 14, 312}, {47, 0, 526, 2, 316}, {47, 0, 528, 2, 316}, {47, 0, 530, 2, 316}, {47, 0, 532, 2, 316}, {47, 0, 534, 3, 316}, {47, 0, 537, 2, 316}, {47, 0, 539, 3, 316}, {47, 0, 542, 3, 316},
+ {47, 0, 545, 4, 318}, {47, 0, 549, 4, 316}, {47, 0, 553, 2, 316}, {47, 0, 555, 0, 316}, {47, 0, 555, 2, 316}, {47, 0, 557, 3, 316}, {47, 0, 560, 6, 316}, {47, 0, 566, 2, 316}, {47, 0, 568, 2, 316}, {47, 0, 570, 3, 316}, {47, 19, 573, 1, 312}, {66, 0, 574, 2, 316}, {66, 0, 576, 8, 316}, {66, 0, 584, 2, 316}, {66, 0, 586, 4, 316}, {66, 0, 590, 5, 316}, {66, 0, 595, 3, 316}, {66, 0, 598, 2, 320}, {66, 0, 600, 3, 316}, {66, 0, 603, 7, 316},
+ {66, 0, 610, 3, 316}, {66, 0, 613, 0, 316}, {66, 0, 613, 4, 317}, {66, 0, 617, 4, 318}, {66, 0, 621, 2, 320}, {66, 0, 623, 5, 316}, {66, 0, 628, 2, 316}, {66, 0, 630, 2, 316}, {66, 0, 632, 2, 320}, {66, 0, 634, 2, 320}, {66, 0, 636, 4, 316}, {66, 0, 640, 2, 316}, {66, 0, 642, 1, 316}, {66, 0, 643, 1, 316}, {66, 0, 644, 4, 316}, {66, 0, 648, 3, 316}, {66, 7, 651, 2, 319}, {73, 0, 653, 2, 316}, {73, 0, 655, 2, 316}, {73, 0, 657, 3, 316},
+ {73, 4, 660, 4, 312}, {77, 0, 664, 10, 316}, {77, 0, 674, 2, 316}, {77, 0, 676, 4, 316}, {77, 0, 680, 4, 316}, {77, 0, 684, 3, 316}, {77, 0, 687, 2, 316}, {77, 0, 689, 2, 316}, {77, 0, 691, 8, 317}, {77, 0, 699, 3, 316}, {77, 0, 702, 3, 316}, {77, 0, 705, 2, 316}, {77, 0, 707, 2, 316}, {77, 0, 709, 5, 316}, {77, 0, 714, 4, 316}, {77, 0, 718, 2, 316}, {77, 0, 720, 8, 318}, {77, 0, 728, 1, 316}, {77, 0, 729, 2, 320}, {77, 0, 731, 3, 316},
+ {77, 1, 734, 4, 316}, {78, 0, 738, 5, 316}, {78, 0, 743, 3, 316}, {78, 0, 746, 1, 316}, {78, 0, 747, 2, 320}, {78, 0, 749, 0, 313}, {78, 0, 749, 2, 316}, {78, 5, 751, 3, 316}, {83, 0, 754, 5, 316}, {83, 0, 759, 7, 316}, {83, 0, 766, 6, 316}, {83, 0, 772, 3, 316}, {83, 0, 775, 2, 316}, {83, 0, 777, 5, 316}, {83, 0, 782, 2, 316}, {83, 0, 784, 0, 314}, {83, 0, 784, 2, 316}, {83, 0, 786, 1, 316}, {83, 0, 787, 2, 316}, {83, 0, 789, 5, 316},
+ {83, 0, 794, 2, 316}, {83, 0, 796, 1, 316}, {83, 0, 797, 2, 316}, {83, 0, 799, 2, 316}, {83, 0, 801, 6, 316}, {83, 0, 807, 2, 316}, {83, 0, 809, 2, 320}, {83, 0, 811, 3, 316}, {83, 0, 814, 4, 316}, {83, 0, 818, 2, 316}, {83, 0, 820, 2, 316}, {83, 0, 822, 2, 316}, {83, 0, 824, 2, 316}, {83, 0, 826, 2, 316}, {83, 0, 828, 2, 316}, {83, 0, 830, 4, 318}, {83, 1, 834, 2, 316}, {84, 0, 836, 5, 316}, {84, 0, 841, 20, 317}, {84, 0, 861, 2, 316},
+ {84, 0, 863, 0, 316}, {84, 0, 863, 2, 316}, {84, 0, 865, 4, 320}, {84, 0, 869, 0, 316}, {84, 0, 869, 2, 316}, {84, 0, 871, 1, 316}, {84, 0, 872, 2, 316}, {84, 0, 874, 3, 316}, {84, 0, 877, 2, 316}, {84, 0, 879, 2, 316}, {84, 0, 881, 4, 316}, {84, 0, 885, 3, 316}, {84, 0, 888, 17, 316}, {84, 6, 905, 1, 319}, {90, 0, 906, 2, 316}, {90, 0, 908, 2, 320}, {90, 0, 910, 2, 320}, {90, 0, 912, 2, 316}, {90, 0, 914, 2, 316}, {90, 0, 916, 4, 318},
+ {90, 0, 920, 2, 316}, {90, 5, 922, 0, 312}, {95, 0, 922, 2, 316}, {95, 0, 924, 4, 316}, {95, 0, 928, 4, 316}, {95, 0, 932, 6, 316}, {95, 0, 938, 2, 316}, {95, 0, 940, 4, 316}, {95, 0, 944, 3, 316}, {95, 0, 947, 3, 316}, {95, 0, 950, 2, 316}, {95, 0, 952, 3, 316}, {95, 0, 955, 0, 316}, {95, 0, 955, 0, 316}, {95, 0, 955, 2, 316}, {95, 0, 957, 7, 316}, {95, 0, 964, 2, 316}, {95, 0, 966, 0, 319}, {95, 0, 966, 7, 316}, {95, 0, 973, 2, 316},
+ {95, 0, 975, 2, 316}, {95, 3, 977, 1, 316}, {98, 0, 978, 2, 320}, {98, 0, 980, 4, 316}, {98, 0, 984, 0, 316}, {98, 0, 984, 2, 316}, {98, 0, 986, 2, 316}, {98, 0, 988, 4, 316}, {98, 0, 992, 1, 316}, {98, 0, 993, 2, 316}, {98, 0, 995, 2, 316}, {98, 0, 997, 3, 316}, {98, 0, 1000, 2, 317}, {98, 0, 1002, 0, 316}, {98, 0, 1002, 4, 316}, {98, 0, 1006, 4, 316}, {98, 0, 1010, 2, 316}, {98, 0, 1012, 3, 316}, {98, 0, 1015, 4, 316}, {98, 0, 1019, 7, 316},
+ {98, 0, 1026, 4, 316}, {98, 0, 1030, 1, 313}, {98, 17, 1031, 3, 316}, {115, 0, 1034, 5, 316}, {115, 0, 1039, 2, 316}, {115, 0, 1041, 1, 316}, {115, 0, 1042, 4, 316}, {115, 0, 1046, 2, 316}, {115, 0, 1048, 2, 316}, {115, 0, 1050, 1, 316}, {115, 0, 1051, 2, 316}, {115, 0, 1053, 5, 316}, {115, 0, 1058, 1, -1}, {115, 4, 1059, 1, 312}, {119, 1, 1060, 0, 313}, {120, 2, 1060, 8, 312}, {122, 11, 1068, 6, 315}, {133, 2, 1074, 0, 316}, {135, 0, 1074, 0, 316}, {135, 3, 1074, 2, 316},
+ {138, 0, 1076, 2, 316},
+};
+extern const XFA_METHODINFO g_SomMethodData[] = {
+ {0x3c752495, (FX_LPCWSTR)L"verify", (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Verify}, {0xa68635f1, (FX_LPCWSTR)L"sign", (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Sign}, {0xa7f2c5e6, (FX_LPCWSTR)L"enumerate", (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Enumerate},
+ {0xd8ed1467, (FX_LPCWSTR)L"clear", (XFA_METHOD_CALLBACK)&CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Clear}, {0x4bdcce13, (FX_LPCWSTR)L"execute", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_WsdlConnection_Execute}, {0x1c296ba4, (FX_LPCWSTR)L"restore", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Delta_Restore},
+ {0x7d123a9, (FX_LPCWSTR)L"clearItems", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ClearItems}, {0xfb0b007, (FX_LPCWSTR)L"execEvent", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecEvent}, {0x6716ce97, (FX_LPCWSTR)L"execInitialize", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecInitialize},
+ {0x7bb919c2, (FX_LPCWSTR)L"deleteItem", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_DeleteItem}, {0x9f053d5e, (FX_LPCWSTR)L"getSaveItem", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_GetSaveItem}, {0xbbd32747, (FX_LPCWSTR)L"boundItem", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_BoundItem},
+ {0xc492d950, (FX_LPCWSTR)L"getItemState", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_GetItemState}, {0xc6013cd3, (FX_LPCWSTR)L"execCalculate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecCalculate}, {0xd8930d0e, (FX_LPCWSTR)L"setItems", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_SetItems},
+ {0xe0f15045, (FX_LPCWSTR)L"getDisplayItem", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_GetDisplayItem}, {0xe23acddc, (FX_LPCWSTR)L"setItemState", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_SetItemState}, {0xe2dfb2f8, (FX_LPCWSTR)L"addItem", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_AddItem},
+ {0xef8ce48f, (FX_LPCWSTR)L"execValidate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Field_ExecValidate}, {0x461079ef, (FX_LPCWSTR)L"emit", (XFA_METHOD_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_Emit}, {0xfec90c63, (FX_LPCWSTR)L"reset", (XFA_METHOD_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_Reset},
+ {0xfb0b007, (FX_LPCWSTR)L"execEvent", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecEvent}, {0x3d832221, (FX_LPCWSTR)L"selectedMember", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_SelectedMember}, {0x6716ce97, (FX_LPCWSTR)L"execInitialize", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecInitialize},
+ {0xc6013cd3, (FX_LPCWSTR)L"execCalculate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecCalculate}, {0xef8ce48f, (FX_LPCWSTR)L"execValidate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ExclGroup_ExecValidate}, {0xfb0b007, (FX_LPCWSTR)L"execEvent", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecEvent},
+ {0x6716ce97, (FX_LPCWSTR)L"execInitialize", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecInitialize}, {0xc6013cd3, (FX_LPCWSTR)L"execCalculate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecCalculate}, {0xd9b9b1f1, (FX_LPCWSTR)L"getInvalidObjects", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_GetInvalidObjects},
+ {0xef8ce48f, (FX_LPCWSTR)L"execValidate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Subform_ExecValidate}, {0xa366b7c, (FX_LPCWSTR)L"exportData", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_ExportData}, {0x16cc226c, (FX_LPCWSTR)L"gotoURL", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_GotoURL},
+ {0x1e0722f5, (FX_LPCWSTR)L"pageDown", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_PageDown}, {0x3e66cb2c, (FX_LPCWSTR)L"setFocus", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_SetFocus}, {0x4ac9faae, (FX_LPCWSTR)L"openList", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_OpenList},
+ {0x7b89714f, (FX_LPCWSTR)L"response", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Response}, {0x7fd9fd58, (FX_LPCWSTR)L"documentInBatch", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_DocumentInBatch}, {0xaf1d019d, (FX_LPCWSTR)L"resetData", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_ResetData},
+ {0xb07be13c, (FX_LPCWSTR)L"beep", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Beep}, {0xb1882ca0, (FX_LPCWSTR)L"getFocus", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_GetFocus}, {0xbf4ba9ee, (FX_LPCWSTR)L"messageBox", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_MessageBox},
+ {0xd6d4dbc1, (FX_LPCWSTR)L"documentCountInBatch", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_DocumentCountInBatch}, {0xdd7676ed, (FX_LPCWSTR)L"print", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Print}, {0xe2f863d0, (FX_LPCWSTR)L"currentDateTime", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_CurrentDateTime},
+ {0xf995d0f5, (FX_LPCWSTR)L"importData", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_ImportData}, {0xfeb96b62, (FX_LPCWSTR)L"pageUp", (XFA_METHOD_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_PageUp}, {0x68, (FX_LPCWSTR)L"h", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_H},
+ {0x77, (FX_LPCWSTR)L"w", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_W}, {0x78, (FX_LPCWSTR)L"x", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_X}, {0x79, (FX_LPCWSTR)L"y", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Y},
+ {0x5460206, (FX_LPCWSTR)L"pageCount", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageCount}, {0x5eb5b0f, (FX_LPCWSTR)L"pageSpan", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageSpan}, {0x10f1b1bd, (FX_LPCWSTR)L"page", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Page},
+ {0x1c1e6318, (FX_LPCWSTR)L"pageContent", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageContent}, {0x1c1f4a5c, (FX_LPCWSTR)L"absPageCount", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCount}, {0x1ec47db5, (FX_LPCWSTR)L"absPageCountInBatch", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCountInBatch},
+ {0x2e4ecbdb, (FX_LPCWSTR)L"sheetCountInBatch", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCountInBatch}, {0x2fcff4b5, (FX_LPCWSTR)L"relayout", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Relayout}, {0x3bf1c2a5, (FX_LPCWSTR)L"absPageSpan", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageSpan},
+ {0x5775c2cc, (FX_LPCWSTR)L"absPageInBatch", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageInBatch}, {0x8c5feb32, (FX_LPCWSTR)L"sheetInBatch", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetInBatch}, {0x8f3a8379, (FX_LPCWSTR)L"sheet", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Sheet},
+ {0x96f3c4cb, (FX_LPCWSTR)L"relayoutPageArea", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_RelayoutPageArea}, {0xd2a4a542, (FX_LPCWSTR)L"sheetCount", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCount}, {0xe74f0653, (FX_LPCWSTR)L"absPage", (XFA_METHOD_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPage},
+ {0x44c352ad, (FX_LPCWSTR)L"formNodes", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_FormNodes}, {0x45efb847, (FX_LPCWSTR)L"remerge", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_Remerge}, {0x6716ce97, (FX_LPCWSTR)L"execInitialize", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_ExecInitialize},
+ {0x712c6afa, (FX_LPCWSTR)L"createNode", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_CreateNode}, {0xa8a35e25, (FX_LPCWSTR)L"recalculate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_Recalculate}, {0xc6013cd3, (FX_LPCWSTR)L"execCalculate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_ExecCalculate},
+ {0xef8ce48f, (FX_LPCWSTR)L"execValidate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Template_ExecValidate}, {0x4cc1c0f9, (FX_LPCWSTR)L"moveCurrentRecord", (XFA_METHOD_CALLBACK)&CScript_DataWindow::Script_DataWindow_MoveCurrentRecord}, {0x5779d65f, (FX_LPCWSTR)L"record", (XFA_METHOD_CALLBACK)&CScript_DataWindow::Script_DataWindow_Record},
+ {0x8a476498, (FX_LPCWSTR)L"gotoRecord", (XFA_METHOD_CALLBACK)&CScript_DataWindow::Script_DataWindow_GotoRecord}, {0xaac241c8, (FX_LPCWSTR)L"isRecordGroup", (XFA_METHOD_CALLBACK)&CScript_DataWindow::Script_DataWindow_IsRecordGroup}, {0x1c6f4277, (FX_LPCWSTR)L"evaluate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Manifest_Evaluate},
+ {0x2afec2cc, (FX_LPCWSTR)L"moveInstance", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_MoveInstance}, {0x2bf94a63, (FX_LPCWSTR)L"removeInstance", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_RemoveInstance}, {0x303adaf4, (FX_LPCWSTR)L"setInstances", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_SetInstances},
+ {0x4d76b89e, (FX_LPCWSTR)L"addInstance", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_AddInstance}, {0xc660dc8a, (FX_LPCWSTR)L"insertInstance", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_InstanceManager_InsertInstance}, {0xddfd1ea1, (FX_LPCWSTR)L"metadata", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Desc_Metadata},
+ {0x44c352ad, (FX_LPCWSTR)L"formNodes", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_FormNodes}, {0x45efb847, (FX_LPCWSTR)L"remerge", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_Remerge}, {0x6716ce97, (FX_LPCWSTR)L"execInitialize", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_ExecInitialize},
+ {0xa8a35e25, (FX_LPCWSTR)L"recalculate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_Recalculate}, {0xc6013cd3, (FX_LPCWSTR)L"execCalculate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_ExecCalculate}, {0xef8ce48f, (FX_LPCWSTR)L"execValidate", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Form_ExecValidate},
+ {0x60490a85, (FX_LPCWSTR)L"message", (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::Script_LogPseudoModel_Message}, {0x60ecfcc9, (FX_LPCWSTR)L"traceDeactivate", (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::Script_LogPseudoModel_TraceDeactivate}, {0x86a0f4c0, (FX_LPCWSTR)L"traceActivate", (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::Script_LogPseudoModel_TraceActivate},
+ {0x93eac39a, (FX_LPCWSTR)L"traceEnabled", (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::Script_LogPseudoModel_TraceEnabled}, {0xd1227e6f, (FX_LPCWSTR)L"trace", (XFA_METHOD_CALLBACK)&CScript_LogPseudoModel::Script_LogPseudoModel_Trace}, {0x36c0ee14, (FX_LPCWSTR)L"getAttribute", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Packet_GetAttribute},
+ {0x5468e2a0, (FX_LPCWSTR)L"setAttribute", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Packet_SetAttribute}, {0xadc48de2, (FX_LPCWSTR)L"removeAttribute", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Packet_RemoveAttribute}, {0x3848b3f, (FX_LPCWSTR)L"next", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Next},
+ {0x14e25bc8, (FX_LPCWSTR)L"cancelBatch", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_CancelBatch}, {0x3ce05d68, (FX_LPCWSTR)L"first", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_First}, {0x649e1e65, (FX_LPCWSTR)L"updateBatch", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_UpdateBatch},
+ {0x6a3405dd, (FX_LPCWSTR)L"previous", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Previous}, {0x74818fb3, (FX_LPCWSTR)L"isBOF", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_IsBOF}, {0x74d07a76, (FX_LPCWSTR)L"isEOF", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_IsEOF},
+ {0x7613cb66, (FX_LPCWSTR)L"cancel", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Cancel}, {0x7baca2e3, (FX_LPCWSTR)L"update", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Update}, {0x8b90e1f2, (FX_LPCWSTR)L"open", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Open},
+ {0x9c6471b3, (FX_LPCWSTR)L"delete", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Delete}, {0xa7315093, (FX_LPCWSTR)L"addNew", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_AddNew}, {0xa7ce5f8d, (FX_LPCWSTR)L"requery", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Requery},
+ {0xc7368674, (FX_LPCWSTR)L"resync", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Resync}, {0xd9f47f36, (FX_LPCWSTR)L"close", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Close}, {0xf54481d4, (FX_LPCWSTR)L"last", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_Last},
+ {0xf7965460, (FX_LPCWSTR)L"hasDataChanged", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_Source_HasDataChanged}, {0x6275f6af, (FX_LPCWSTR)L"item", (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Item}, {0x7033bfd5, (FX_LPCWSTR)L"insert", (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Insert},
+ {0x9cab7cae, (FX_LPCWSTR)L"remove", (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Remove}, {0xda12e518, (FX_LPCWSTR)L"append", (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_ListClass_Append}, {0xd892a054, (FX_LPCWSTR)L"namedItem", (XFA_METHOD_CALLBACK)&CXFA_NodeList::Script_TreelistClass_NamedItem},
+ {0xba2dd386, (FX_LPCWSTR)L"resolveNode", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_TreeClass_ResolveNode}, {0xe509e2b9, (FX_LPCWSTR)L"resolveNodes", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_TreeClass_ResolveNodes}, {0x1bca1ebd, (FX_LPCWSTR)L"applyXSL", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_ApplyXSL},
+ {0x36c0ee14, (FX_LPCWSTR)L"getAttribute", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_GetAttribute}, {0x5468e2a0, (FX_LPCWSTR)L"setAttribute", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SetAttribute}, {0x5ee00996, (FX_LPCWSTR)L"setElement", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SetElement},
+ {0x92dada4f, (FX_LPCWSTR)L"saveFilteredXML", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SaveFilteredXML}, {0x9c456500, (FX_LPCWSTR)L"saveXML", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_SaveXML}, {0xabd3200a, (FX_LPCWSTR)L"getElement", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_GetElement},
+ {0xb269c60d, (FX_LPCWSTR)L"isPropertySpecified", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_IsPropertySpecified}, {0xb528be91, (FX_LPCWSTR)L"loadXML", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_LoadXML}, {0xd9f46591, (FX_LPCWSTR)L"clone", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_Clone},
+ {0xe006a76b, (FX_LPCWSTR)L"assignNode", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_NodeClass_AssignNode}, {0x7303fcea, (FX_LPCWSTR)L"getDelta", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ContainerClass_GetDelta}, {0xe7742c9d, (FX_LPCWSTR)L"getDeltas", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ContainerClass_GetDeltas},
+ {0x30ff6aad, (FX_LPCWSTR)L"clearErrorList", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ModelClass_ClearErrorList}, {0x712c6afa, (FX_LPCWSTR)L"createNode", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ModelClass_CreateNode}, {0x83a6411d, (FX_LPCWSTR)L"isCompatibleNS", (XFA_METHOD_CALLBACK)&CXFA_Node::Script_ModelClass_IsCompatibleNS},
+};
+extern const FX_INT32 g_iSomMethodCount = sizeof(g_SomMethodData) / sizeof(XFA_METHODINFO);
+extern const _XFA_SCRIPTATTRIBUTEINFO g_SomAttributeData[] = {
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xb3543a6, (FX_LPCWSTR)L"max", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Max, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x45a6daf8, (FX_LPCWSTR)L"eofAction", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_EofAction, XFA_SCRIPT_Basic},
+ {0x5ec958c0, (FX_LPCWSTR)L"cursorType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CursorType, XFA_SCRIPT_Basic}, {0x79975f2b, (FX_LPCWSTR)L"lockType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LockType, XFA_SCRIPT_Basic}, {0xa5340ff5, (FX_LPCWSTR)L"bofAction", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_BofAction, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc5762157, (FX_LPCWSTR)L"cursorLocation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CursorLocation, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x1ee2d24d, (FX_LPCWSTR)L"instanceIndex", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_InstanceIndex, -1, XFA_SCRIPT_Basic}, {0x8c99377e, (FX_LPCWSTR)L"relation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relation, XFA_SCRIPT_Basic},
+ {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0x3106c3a, (FX_LPCWSTR)L"beforeTarget", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_BeforeTarget, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x13a08bdb, (FX_LPCWSTR)L"overflowTarget", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_OverflowTarget, XFA_SCRIPT_Basic}, {0x169134a1, (FX_LPCWSTR)L"overflowLeader", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_OverflowLeader, XFA_SCRIPT_Basic},
+ {0x20914367, (FX_LPCWSTR)L"overflowTrailer", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_OverflowTrailer, XFA_SCRIPT_Basic}, {0x453eaf38, (FX_LPCWSTR)L"startNew", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_StartNew, XFA_SCRIPT_Basic}, {0x64110ab5, (FX_LPCWSTR)L"bookendTrailer", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_BookendTrailer, XFA_SCRIPT_Basic},
+ {0xb6b44172, (FX_LPCWSTR)L"after", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_After, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc3c1442f, (FX_LPCWSTR)L"bookendLeader", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_BookendLeader, XFA_SCRIPT_Basic},
+ {0xcb150479, (FX_LPCWSTR)L"afterTarget", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AfterTarget, XFA_SCRIPT_Basic}, {0xf4ffce73, (FX_LPCWSTR)L"before", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Before, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue_Read, -1, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x47cfa43a, (FX_LPCWSTR)L"allowNeutral", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AllowNeutral, XFA_SCRIPT_Basic},
+ {0x7c2fd80b, (FX_LPCWSTR)L"mark", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Mark, XFA_SCRIPT_Basic}, {0x8ed182d1, (FX_LPCWSTR)L"shape", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Shape, XFA_SCRIPT_Basic}, {0xa686975b, (FX_LPCWSTR)L"size", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Size, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x5c054755, (FX_LPCWSTR)L"startAngle", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_StartAngle, XFA_SCRIPT_Basic}, {0x74788f8b, (FX_LPCWSTR)L"sweepAngle", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_SweepAngle, XFA_SCRIPT_Basic}, {0x9d833d75, (FX_LPCWSTR)L"circular", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Circular, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd996fa9b, (FX_LPCWSTR)L"hand", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xb0e5485d, (FX_LPCWSTR)L"bind", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Bind, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xcd7f7b54, (FX_LPCWSTR)L"from", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_From, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x8e29d794, (FX_LPCWSTR)L"signatureType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_SignatureType, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xe11a2cbc, (FX_LPCWSTR)L"permissions", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Permissions, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x453eaf38, (FX_LPCWSTR)L"startNew", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_StartNew, XFA_SCRIPT_Basic},
+ {0x9dcc3ab3, (FX_LPCWSTR)L"trailer", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic}, {0xa6118c89, (FX_LPCWSTR)L"targetType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TargetType, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic}, {0xcbcaf66d, (FX_LPCWSTR)L"leader", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x2d574d58, (FX_LPCWSTR)L"this", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Xfa_This, -1, XFA_SCRIPT_Object}, {0x4fdc3454, (FX_LPCWSTR)L"timeStamp", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TimeStamp, XFA_SCRIPT_Basic}, {0xb598a1f7, (FX_LPCWSTR)L"uuid", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Uuid, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xcfea02e, (FX_LPCWSTR)L"leftInset", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LeftInset, XFA_SCRIPT_Basic}, {0x1356caf8, (FX_LPCWSTR)L"bottomInset", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_BottomInset, XFA_SCRIPT_Basic},
+ {0x25764436, (FX_LPCWSTR)L"topInset", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TopInset, XFA_SCRIPT_Basic}, {0x8a692521, (FX_LPCWSTR)L"rightInset", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_RightInset, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x1e459b8f, (FX_LPCWSTR)L"nonRepudiation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_NonRepudiation, XFA_SCRIPT_Basic}, {0x2bb3f470, (FX_LPCWSTR)L"encipherOnly", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_EncipherOnly, XFA_SCRIPT_Basic},
+ {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0x5f760b50, (FX_LPCWSTR)L"digitalSignature", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DigitalSignature, XFA_SCRIPT_Basic}, {0x69aa2292, (FX_LPCWSTR)L"crlSign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CrlSign, XFA_SCRIPT_Basic},
+ {0x98fd4d81, (FX_LPCWSTR)L"keyAgreement", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_KeyAgreement, XFA_SCRIPT_Basic}, {0xa66404cb, (FX_LPCWSTR)L"keyEncipherment", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_KeyEncipherment, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xca5dc27c, (FX_LPCWSTR)L"dataEncipherment", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataEncipherment, XFA_SCRIPT_Basic}, {0xe8f118a8, (FX_LPCWSTR)L"keyCertSign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_KeyCertSign, XFA_SCRIPT_Basic}, {0xfea53ec6, (FX_LPCWSTR)L"decipherOnly", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DecipherOnly, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x8b90e1f2, (FX_LPCWSTR)L"open", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Open, XFA_SCRIPT_Basic}, {0x957fa006, (FX_LPCWSTR)L"commitOn", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CommitOn, XFA_SCRIPT_Basic}, {0xb12128b7, (FX_LPCWSTR)L"textEntry", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TextEntry, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0x2282c73, (FX_LPCWSTR)L"hAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic}, {0x8d4f1c7, (FX_LPCWSTR)L"textIndent", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TextIndent, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2a82d99c, (FX_LPCWSTR)L"marginRight", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MarginRight, XFA_SCRIPT_Basic}, {0x534729c9, (FX_LPCWSTR)L"marginLeft", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MarginLeft, XFA_SCRIPT_Basic},
+ {0x5739d1ff, (FX_LPCWSTR)L"radixOffset", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_RadixOffset, XFA_SCRIPT_Basic}, {0x577682ac, (FX_LPCWSTR)L"preserve", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Preserve, XFA_SCRIPT_Basic}, {0x731e0665, (FX_LPCWSTR)L"spaceBelow", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_SpaceBelow, XFA_SCRIPT_Basic},
+ {0x7a7cc341, (FX_LPCWSTR)L"vAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic}, {0x836d4d7c, (FX_LPCWSTR)L"tabDefault", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TabDefault, XFA_SCRIPT_Basic}, {0x8fa01790, (FX_LPCWSTR)L"tabStops", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TabStops, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd4b01921, (FX_LPCWSTR)L"lineHeight", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LineHeight, XFA_SCRIPT_Basic}, {0xe18b5659, (FX_LPCWSTR)L"spaceAbove", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_SpaceAbove, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xd861f8af, (FX_LPCWSTR)L"addRevocationInfo", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AddRevocationInfo, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbb8df5d, (FX_LPCWSTR)L"ref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6128d8d, (FX_LPCWSTR)L"activity", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Activity, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0x43e349b, (FX_LPCWSTR)L"dataRowCount", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataRowCount, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x28e17e91, (FX_LPCWSTR)L"dataPrep", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataPrep, XFA_SCRIPT_Basic},
+ {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0x3650557e, (FX_LPCWSTR)L"textLocation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TextLocation, XFA_SCRIPT_Basic}, {0x3b582286, (FX_LPCWSTR)L"moduleWidth", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ModuleWidth, XFA_SCRIPT_Basic},
+ {0x52666f1c, (FX_LPCWSTR)L"printCheckDigit", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_PrintCheckDigit, XFA_SCRIPT_Basic}, {0x5404d6df, (FX_LPCWSTR)L"moduleHeight", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ModuleHeight, XFA_SCRIPT_Basic}, {0x5ab23b6c, (FX_LPCWSTR)L"startChar", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_StartChar, XFA_SCRIPT_Basic},
+ {0x7c732a66, (FX_LPCWSTR)L"truncate", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Truncate, XFA_SCRIPT_Basic}, {0x8d181d61, (FX_LPCWSTR)L"wideNarrowRatio", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_WideNarrowRatio, XFA_SCRIPT_Basic}, {0x99800d7a, (FX_LPCWSTR)L"errorCorrectionLevel", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ErrorCorrectionLevel, XFA_SCRIPT_Basic},
+ {0x9a63da3d, (FX_LPCWSTR)L"upsMode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_UpsMode, XFA_SCRIPT_Basic}, {0xaf754613, (FX_LPCWSTR)L"checksum", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Checksum, XFA_SCRIPT_Basic}, {0xb045fbc5, (FX_LPCWSTR)L"charEncoding", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CharEncoding, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc035c6b1, (FX_LPCWSTR)L"dataColumnCount", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataColumnCount, XFA_SCRIPT_Basic}, {0xd3c84d25, (FX_LPCWSTR)L"rowColumnRatio", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_RowColumnRatio, XFA_SCRIPT_Basic},
+ {0xd57c513c, (FX_LPCWSTR)L"dataLength", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataLength, XFA_SCRIPT_Basic}, {0xf575ca75, (FX_LPCWSTR)L"endChar", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_EndChar, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+ {0x28dee6e9, (FX_LPCWSTR)L"format", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Format, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x60d4c8b1, (FX_LPCWSTR)L"output", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Output, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xd6a39990, (FX_LPCWSTR)L"input", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Input, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0x2b5df51e, (FX_LPCWSTR)L"dataDescription", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataDescription, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x6c0d9600, (FX_LPCWSTR)L"currentValue", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Delta_CurrentValue, -1, XFA_SCRIPT_Basic},
+ {0x942643f0, (FX_LPCWSTR)L"savedValue", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Delta_SavedValue, -1, XFA_SCRIPT_Basic}, {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Delta_Target, -1, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd4cc53f8, (FX_LPCWSTR)L"highlight", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Highlight, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0x5518c25, (FX_LPCWSTR)L"break", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Break, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd996fa9b, (FX_LPCWSTR)L"hand", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic}, {0x78, (FX_LPCWSTR)L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+ {0x79, (FX_LPCWSTR)L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x1059ec18, (FX_LPCWSTR)L"level", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_Integer, XFA_ATTRIBUTE_Level, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+ {0xac06e2b0, (FX_LPCWSTR)L"colSpan", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x21aed, (FX_LPCWSTR)L"id", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f105f72, (FX_LPCWSTR)L"wordCharacterCount", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_WordCharacterCount, XFA_SCRIPT_Basic},
+ {0x3d123c26, (FX_LPCWSTR)L"hyphenate", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Hyphenate, XFA_SCRIPT_Basic}, {0x66539c48, (FX_LPCWSTR)L"excludeInitialCap", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ExcludeInitialCap, XFA_SCRIPT_Basic}, {0x6a95c976, (FX_LPCWSTR)L"pushCharacterCount", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_PushCharacterCount, XFA_SCRIPT_Basic},
+ {0x982bd892, (FX_LPCWSTR)L"remainCharacterCount", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_RemainCharacterCount, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xe5c96d6a, (FX_LPCWSTR)L"excludeAllCaps", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ExcludeAllCaps, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x8af2e657, (FX_LPCWSTR)L"maxChars", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxChars, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc080cd3, (FX_LPCWSTR)L"url", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Url, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xa6710262, (FX_LPCWSTR)L"credentialServerPolicy", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CredentialServerPolicy, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc2ba0923, (FX_LPCWSTR)L"urlPolicy", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_UrlPolicy, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0x47d03490, (FX_LPCWSTR)L"connection", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic}, {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x78bff531, (FX_LPCWSTR)L"numberOfCells", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_Integer, XFA_ATTRIBUTE_NumberOfCells, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x68, (FX_LPCWSTR)L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic}, {0x77, (FX_LPCWSTR)L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic}, {0x78, (FX_LPCWSTR)L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+ {0x79, (FX_LPCWSTR)L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic}, {0x2282c73, (FX_LPCWSTR)L"hAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x1abbd7e0, (FX_LPCWSTR)L"dataNode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DataNode, -1, XFA_SCRIPT_Object}, {0x25839852, (FX_LPCWSTR)L"access", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Access, XFA_SCRIPT_Basic}, {0x2ee7678f, (FX_LPCWSTR)L"rotate", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Rotate, XFA_SCRIPT_Basic},
+ {0x3b1ddd06, (FX_LPCWSTR)L"fillColor", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FillColor, -1, XFA_SCRIPT_Basic}, {0x54c399e3, (FX_LPCWSTR)L"formattedValue", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_FormattedValue, -1, XFA_SCRIPT_Basic}, {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+ {0x5a3b375d, (FX_LPCWSTR)L"borderColor", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderColor, -1, XFA_SCRIPT_Basic}, {0x5e936ed6, (FX_LPCWSTR)L"fontColor", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FontColor, -1, XFA_SCRIPT_Basic}, {0x6826c408, (FX_LPCWSTR)L"parentSubform", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_ParentSubform, -1, XFA_SCRIPT_Basic},
+ {0x79b67434, (FX_LPCWSTR)L"mandatoryMessage", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_MandatoryMessage, -1, XFA_SCRIPT_Basic}, {0x7a7cc341, (FX_LPCWSTR)L"vAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic}, {0x7c2ff6ae, (FX_LPCWSTR)L"maxH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic},
+ {0x7c2ff6bd, (FX_LPCWSTR)L"maxW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic}, {0x7d02356c, (FX_LPCWSTR)L"minH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic}, {0x7d02357b, (FX_LPCWSTR)L"minW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic},
+ {0x85fd6faf, (FX_LPCWSTR)L"mandatory", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_Mandatory, -1, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic}, {0x964fb42e, (FX_LPCWSTR)L"formatMessage", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_FormatMessage, -1, XFA_SCRIPT_Basic},
+ {0xa03cf627, (FX_LPCWSTR)L"rawValue", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xa60dd202, (FX_LPCWSTR)L"length", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_Length, -1, XFA_SCRIPT_Basic},
+ {0xac06e2b0, (FX_LPCWSTR)L"colSpan", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbc8fa350, (FX_LPCWSTR)L"locale", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Locale, XFA_SCRIPT_Basic},
+ {0xc2bd40fd, (FX_LPCWSTR)L"anchorType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic}, {0xc4fed09b, (FX_LPCWSTR)L"accessKey", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AccessKey, XFA_SCRIPT_Basic}, {0xcabfa3d0, (FX_LPCWSTR)L"validationMessage", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_ValidationMessage, -1, XFA_SCRIPT_Basic},
+ {0xdcecd663, (FX_LPCWSTR)L"editValue", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_EditValue, -1, XFA_SCRIPT_Basic}, {0xe07e5061, (FX_LPCWSTR)L"selectedIndex", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Field_SelectedIndex, -1, XFA_SCRIPT_Basic}, {0xf65e34be, (FX_LPCWSTR)L"borderWidth", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderWidth, -1, XFA_SCRIPT_Basic},
+ {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x68, (FX_LPCWSTR)L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic}, {0x77, (FX_LPCWSTR)L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic}, {0x78, (FX_LPCWSTR)L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+ {0x79, (FX_LPCWSTR)L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd843798, (FX_LPCWSTR)L"fullText", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_FullText, -1, XFA_SCRIPT_Basic}, {0x1b6d1cf5, (FX_LPCWSTR)L"reenter", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_Reenter, -1, XFA_SCRIPT_Basic},
+ {0x1e6ffa9a, (FX_LPCWSTR)L"prevContentType", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_PrevContentType, -1, XFA_SCRIPT_Basic}, {0x25a3c206, (FX_LPCWSTR)L"soapFaultString", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_SoapFaultString, -1, XFA_SCRIPT_Basic}, {0x2e00c007, (FX_LPCWSTR)L"newContentType", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_NewContentType, -1, XFA_SCRIPT_Basic},
+ {0x4570500f, (FX_LPCWSTR)L"modifier", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_Modifier, -1, XFA_SCRIPT_Basic}, {0x50e2e33b, (FX_LPCWSTR)L"selEnd", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_SelEnd, -1, XFA_SCRIPT_Basic}, {0x57de87c2, (FX_LPCWSTR)L"prevText", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_PrevText, -1, XFA_SCRIPT_Basic},
+ {0x6ea04e0a, (FX_LPCWSTR)L"soapFaultCode", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_SoapFaultCode, -1, XFA_SCRIPT_Basic}, {0x6f6556cf, (FX_LPCWSTR)L"newText", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_NewText, -1, XFA_SCRIPT_Basic}, {0x891f4606, (FX_LPCWSTR)L"change", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_Change, -1, XFA_SCRIPT_Basic},
+ {0x8fa3c19e, (FX_LPCWSTR)L"shift", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_Shift, -1, XFA_SCRIPT_Basic}, {0xa9d9b2e1, (FX_LPCWSTR)L"keyDown", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_KeyDown, -1, XFA_SCRIPT_Basic}, {0xbfc89db2, (FX_LPCWSTR)L"selStart", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_SelStart, -1, XFA_SCRIPT_Basic},
+ {0xc32a5812, (FX_LPCWSTR)L"commitKey", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_CommitKey, -1, XFA_SCRIPT_Basic}, {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CScript_EventPseudoModel::Script_EventPseudoModel_Target, -1, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xa2e3514, (FX_LPCWSTR)L"cap", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Cap, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x5392ea58, (FX_LPCWSTR)L"stroke", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Stroke, XFA_SCRIPT_Basic}, {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+ {0x94446dcc, (FX_LPCWSTR)L"thickness", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Thickness, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x1ec8ab2c, (FX_LPCWSTR)L"rate", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Rate, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x7b29630a, (FX_LPCWSTR)L"sourceBelow", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_SourceBelow, XFA_SCRIPT_Basic}, {0x8fc36c0a, (FX_LPCWSTR)L"outputBelow", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_OutputBelow, XFA_SCRIPT_Basic},
+ {0xe996b2fe, (FX_LPCWSTR)L"sourceAbove", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_SourceAbove, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x68, (FX_LPCWSTR)L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic},
+ {0x77, (FX_LPCWSTR)L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic}, {0x78, (FX_LPCWSTR)L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic}, {0x79, (FX_LPCWSTR)L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic},
+ {0x2282c73, (FX_LPCWSTR)L"hAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xf23332f, (FX_LPCWSTR)L"errorText", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_ErrorText, -1, XFA_SCRIPT_Basic},
+ {0x1abbd7e0, (FX_LPCWSTR)L"dataNode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DataNode, -1, XFA_SCRIPT_Object}, {0x25839852, (FX_LPCWSTR)L"access", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Access, XFA_SCRIPT_Basic}, {0x3b1ddd06, (FX_LPCWSTR)L"fillColor", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FillColor, -1, XFA_SCRIPT_Basic},
+ {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic}, {0x5a3b375d, (FX_LPCWSTR)L"borderColor", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderColor, -1, XFA_SCRIPT_Basic}, {0x79b67434, (FX_LPCWSTR)L"mandatoryMessage", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_MandatoryMessage, -1, XFA_SCRIPT_Basic},
+ {0x7a7cc341, (FX_LPCWSTR)L"vAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic}, {0x7c2ff6ae, (FX_LPCWSTR)L"maxH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic}, {0x7c2ff6bd, (FX_LPCWSTR)L"maxW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic},
+ {0x7d02356c, (FX_LPCWSTR)L"minH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic}, {0x7d02357b, (FX_LPCWSTR)L"minW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic}, {0x7e7e845e, (FX_LPCWSTR)L"layout", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Layout, XFA_SCRIPT_Basic},
+ {0x846599f8, (FX_LPCWSTR)L"transient", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_Transient, -1, XFA_SCRIPT_Basic}, {0x85fd6faf, (FX_LPCWSTR)L"mandatory", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_Mandatory, -1, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+ {0xa03cf627, (FX_LPCWSTR)L"rawValue", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_DefaultAndRawValue, -1, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ExclGroup_DefaultAndRawValue, -1, XFA_SCRIPT_Basic}, {0xac06e2b0, (FX_LPCWSTR)L"colSpan", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc2bd40fd, (FX_LPCWSTR)L"anchorType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic}, {0xc4fed09b, (FX_LPCWSTR)L"accessKey", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AccessKey, XFA_SCRIPT_Basic},
+ {0xcabfa3d0, (FX_LPCWSTR)L"validationMessage", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_ValidationMessage, -1, XFA_SCRIPT_Basic}, {0xf65e34be, (FX_LPCWSTR)L"borderWidth", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderWidth, -1, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xeda9017a, (FX_LPCWSTR)L"scope", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Scope, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x47d03490, (FX_LPCWSTR)L"connection", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic}, {0x6cfa828a, (FX_LPCWSTR)L"runAt", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_RunAt, XFA_SCRIPT_Basic},
+ {0xa1b0d2f5, (FX_LPCWSTR)L"executeType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ExecuteType, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xe6f99487, (FX_LPCWSTR)L"hScrollPolicy", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x42fed1fd, (FX_LPCWSTR)L"contentType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic}, {0x54fa722c, (FX_LPCWSTR)L"transferEncoding", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TransferEncoding, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue_Read, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd171b240, (FX_LPCWSTR)L"aspect", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Aspect, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue_Read, -1, XFA_SCRIPT_Basic}, {0xdb55fec5, (FX_LPCWSTR)L"href", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Href, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+ {0x7f6fd3d7, (FX_LPCWSTR)L"server", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Server, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x4b8bc840, (FX_LPCWSTR)L"fracDigits", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_FracDigits, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xde7f92ba, (FX_LPCWSTR)L"leadDigits", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LeadDigits, XFA_SCRIPT_Basic},
+ {0x68, (FX_LPCWSTR)L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic}, {0x77, (FX_LPCWSTR)L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic}, {0x78, (FX_LPCWSTR)L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic},
+ {0x79, (FX_LPCWSTR)L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic}, {0x2282c73, (FX_LPCWSTR)L"hAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x1414d431, (FX_LPCWSTR)L"allowMacro", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AllowMacro, XFA_SCRIPT_Basic}, {0x1517dfa1, (FX_LPCWSTR)L"columnWidths", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ColumnWidths, XFA_SCRIPT_Basic}, {0x1abbd7e0, (FX_LPCWSTR)L"dataNode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DataNode, -1, XFA_SCRIPT_Object},
+ {0x1ee2d24d, (FX_LPCWSTR)L"instanceIndex", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_InstanceIndex, -1, XFA_SCRIPT_Basic}, {0x25839852, (FX_LPCWSTR)L"access", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Access, XFA_SCRIPT_Basic}, {0x3b1ddd06, (FX_LPCWSTR)L"fillColor", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_FillColor, -1, XFA_SCRIPT_Basic},
+ {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic}, {0x5a3b375d, (FX_LPCWSTR)L"borderColor", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderColor, -1, XFA_SCRIPT_Basic}, {0x7a7cc341, (FX_LPCWSTR)L"vAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic},
+ {0x7c2ff6ae, (FX_LPCWSTR)L"maxH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic}, {0x7c2ff6bd, (FX_LPCWSTR)L"maxW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic}, {0x7d02356c, (FX_LPCWSTR)L"minH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic},
+ {0x7d02357b, (FX_LPCWSTR)L"minW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic}, {0x7e7e845e, (FX_LPCWSTR)L"layout", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Layout, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+ {0x9cc17d75, (FX_LPCWSTR)L"mergeMode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MergeMode, XFA_SCRIPT_Basic}, {0x9f3e9510, (FX_LPCWSTR)L"instanceManager", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Subform_InstanceManager, -1, XFA_SCRIPT_Object}, {0xac06e2b0, (FX_LPCWSTR)L"colSpan", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbc8fa350, (FX_LPCWSTR)L"locale", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Subform_Locale, -1, XFA_SCRIPT_Basic}, {0xc2bd40fd, (FX_LPCWSTR)L"anchorType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic},
+ {0xcabfa3d0, (FX_LPCWSTR)L"validationMessage", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_ValidationMessage, -1, XFA_SCRIPT_Basic}, {0xe4c3a5e5, (FX_LPCWSTR)L"restoreState", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_RestoreState, XFA_SCRIPT_Basic}, {0xeda9017a, (FX_LPCWSTR)L"scope", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Scope, XFA_SCRIPT_Basic},
+ {0xf65e34be, (FX_LPCWSTR)L"borderWidth", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_BorderWidth, -1, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+ {0x5a50e9e6, (FX_LPCWSTR)L"version", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Handler_Version, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0x4107ed, (FX_LPCWSTR)L"foxitAppType", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_FoxitAppType, -1, XFA_SCRIPT_Basic},
+ {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Name, -1, XFA_SCRIPT_Basic}, {0x66c1ae9, (FX_LPCWSTR)L"validationsEnabled", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_ValidationsEnabled, -1, XFA_SCRIPT_Basic}, {0x14d04502, (FX_LPCWSTR)L"title", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Title, -1, XFA_SCRIPT_Basic},
+ {0x193afe8b, (FX_LPCWSTR)L"foxitName", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_FoxitName, -1, XFA_SCRIPT_Basic}, {0x392ae445, (FX_LPCWSTR)L"platform", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Platform, -1, XFA_SCRIPT_Basic}, {0x5a50e9e6, (FX_LPCWSTR)L"version", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Version, -1, XFA_SCRIPT_Basic},
+ {0x66cb1eed, (FX_LPCWSTR)L"variation", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Variation, -1, XFA_SCRIPT_Basic}, {0x7717cbc4, (FX_LPCWSTR)L"language", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_Language, -1, XFA_SCRIPT_Basic}, {0x86698963, (FX_LPCWSTR)L"appType", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_AppType, -1, XFA_SCRIPT_Basic},
+ {0x94ff9e8d, (FX_LPCWSTR)L"calculationsEnabled", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_CalculationsEnabled, -1, XFA_SCRIPT_Basic}, {0xbcd44940, (FX_LPCWSTR)L"currentPage", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_CurrentPage, -1, XFA_SCRIPT_Basic}, {0xd4286870, (FX_LPCWSTR)L"foxitVersion", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_FoxitVersion, -1, XFA_SCRIPT_Basic},
+ {0xd592b920, (FX_LPCWSTR)L"numPages", (XFA_ATTRIBUTE_CALLBACK)&CScript_HostPseudoModel::Script_HostPseudoModel_NumPages, -1, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x24d85167, (FX_LPCWSTR)L"timeout", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Timeout, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x7d9fd7c5, (FX_LPCWSTR)L"mode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Mode, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x7d9fd7c5, (FX_LPCWSTR)L"mode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_SubmitFormat_Mode, -1, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x2038c9b2, (FX_LPCWSTR)L"role", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Role, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xfcef86b5, (FX_LPCWSTR)L"ready", (XFA_ATTRIBUTE_CALLBACK)&CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Ready, -1, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x5392ea58, (FX_LPCWSTR)L"stroke", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Stroke, XFA_SCRIPT_Basic}, {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+ {0x7b95e661, (FX_LPCWSTR)L"inverted", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Inverted, XFA_SCRIPT_Basic}, {0x94446dcc, (FX_LPCWSTR)L"thickness", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Thickness, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xe8dddf50, (FX_LPCWSTR)L"join", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Join, XFA_SCRIPT_Basic}, {0xe948b9a8, (FX_LPCWSTR)L"radius", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Radius, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xabfa6c4f, (FX_LPCWSTR)L"cSpace", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CSpace, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic}, {0x3848b3f, (FX_LPCWSTR)L"next", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Next, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x6a3405dd, (FX_LPCWSTR)L"previous", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Previous, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xf6b59543, (FX_LPCWSTR)L"intact", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Intact, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x268b7ec1, (FX_LPCWSTR)L"commandType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CommandType, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbde9abda, (FX_LPCWSTR)L"data", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Data, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x5b707a35, (FX_LPCWSTR)L"scriptTest", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ScriptTest, XFA_SCRIPT_Basic}, {0x6b6ddcfb, (FX_LPCWSTR)L"nullTest", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_NullTest, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xe64b1129, (FX_LPCWSTR)L"formatTest", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_FormatTest, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x8c99377e, (FX_LPCWSTR)L"relation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relation, XFA_SCRIPT_Basic},
+ {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0x25363, (FX_LPCWSTR)L"to", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_To, XFA_SCRIPT_Basic},
+ {0x66642f8f, (FX_LPCWSTR)L"force", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Force, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xcd7f7b54, (FX_LPCWSTR)L"from", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_From, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic}, {0x2b5df51e, (FX_LPCWSTR)L"dataDescription", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataDescription, XFA_SCRIPT_Basic}, {0xbb8df5d, (FX_LPCWSTR)L"ref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x226ca8f1, (FX_LPCWSTR)L"operation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Operation, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xfb67185, (FX_LPCWSTR)L"recordsBefore", (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::Script_DataWindow_RecordsBefore, -1, XFA_SCRIPT_Basic}, {0x21d5dfcb, (FX_LPCWSTR)L"currentRecordNumber", (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::Script_DataWindow_CurrentRecordNumber, -1, XFA_SCRIPT_Basic}, {0x312af044, (FX_LPCWSTR)L"recordsAfter", (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::Script_DataWindow_RecordsAfter, -1, XFA_SCRIPT_Basic},
+ {0x6aab37cb, (FX_LPCWSTR)L"isDefined", (XFA_ATTRIBUTE_CALLBACK)&CScript_DataWindow::Script_DataWindow_IsDefined, -1, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x42fed1fd, (FX_LPCWSTR)L"contentType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic},
+ {0x6cfa828a, (FX_LPCWSTR)L"runAt", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_RunAt, XFA_SCRIPT_Basic}, {0xa021b738, (FX_LPCWSTR)L"stateless", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Script_Stateless, -1, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xadc4c77b, (FX_LPCWSTR)L"binding", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Binding, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x7a0cc471, (FX_LPCWSTR)L"passwordChar", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_PasswordChar, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xe6f99487, (FX_LPCWSTR)L"hScrollPolicy", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xe6f99487, (FX_LPCWSTR)L"hScrollPolicy", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x14a32d52, (FX_LPCWSTR)L"pagePosition", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_PagePosition, XFA_SCRIPT_Basic},
+ {0x8340ea66, (FX_LPCWSTR)L"oddOrEven", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_OddOrEven, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic}, {0xa85e74f3, (FX_LPCWSTR)L"initialNumber", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_InitialNumber, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe9ba472, (FX_LPCWSTR)L"numbered", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Numbered, XFA_SCRIPT_Basic}, {0xd70798c2, (FX_LPCWSTR)L"blankOrNotBlank", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_BlankOrNotBlank, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x34ae103c, (FX_LPCWSTR)L"reserve", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Reserve, XFA_SCRIPT_Basic},
+ {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xf2009339, (FX_LPCWSTR)L"placement", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Placement, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x42fed1fd, (FX_LPCWSTR)L"contentType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic}, {0x54fa722c, (FX_LPCWSTR)L"transferEncoding", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TransferEncoding, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc4547a08, (FX_LPCWSTR)L"maxLength", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxLength, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xdb55fec5, (FX_LPCWSTR)L"href", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Href, XFA_SCRIPT_Basic}, {0x29418bb7, (FX_LPCWSTR)L"abbr", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Abbr, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf531b059, (FX_LPCWSTR)L"writingScript", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_WritingScript, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x1b8dce3e, (FX_LPCWSTR)L"action", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Action, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x9dcc3ab3, (FX_LPCWSTR)L"trailer", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic}, {0xcbcaf66d, (FX_LPCWSTR)L"leader", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xb3543a6, (FX_LPCWSTR)L"max", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_InstanceManager_Max, -1, XFA_SCRIPT_Basic}, {0xb356ca4, (FX_LPCWSTR)L"min", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_InstanceManager_Min, -1, XFA_SCRIPT_Basic},
+ {0x6f544d49, (FX_LPCWSTR)L"count", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_InstanceManager_Count, -1, XFA_SCRIPT_Basic}, {0x25363, (FX_LPCWSTR)L"to", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_To, XFA_SCRIPT_Basic}, {0xa0933954, (FX_LPCWSTR)L"unicodeRange", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_UnicodeRange, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xcd7f7b54, (FX_LPCWSTR)L"from", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_From, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x4ef3d02c, (FX_LPCWSTR)L"orientation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Orientation, XFA_SCRIPT_Basic}, {0x65e30c67, (FX_LPCWSTR)L"imagingBBox", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ImagingBBox, XFA_SCRIPT_Basic},
+ {0x9041d4b0, (FX_LPCWSTR)L"short", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Short, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xe349d044, (FX_LPCWSTR)L"stock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Stock, XFA_SCRIPT_Basic},
+ {0xf6b4afb0, (FX_LPCWSTR)L"long", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Long, XFA_SCRIPT_Basic}, {0x5ce6195, (FX_LPCWSTR)L"vScrollPolicy", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_VScrollPolicy, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x1ef3a64a, (FX_LPCWSTR)L"allowRichText", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AllowRichText, XFA_SCRIPT_Basic}, {0x5a32e493, (FX_LPCWSTR)L"multiLine", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MultiLine, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xe6f99487, (FX_LPCWSTR)L"hScrollPolicy", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HScrollPolicy, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xd52482e0, (FX_LPCWSTR)L"maxEntries", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxEntries, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x42fed1fd, (FX_LPCWSTR)L"contentType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic}, {0x8855805f, (FX_LPCWSTR)L"contains", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Contains, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xe372ae97, (FX_LPCWSTR)L"isNull", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_IsNull, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x2b5df51e, (FX_LPCWSTR)L"dataDescription", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DataDescription, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbb8df5d, (FX_LPCWSTR)L"ref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x226ca8f1, (FX_LPCWSTR)L"operation", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Operation, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbb8df5d, (FX_LPCWSTR)L"ref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x42fed1fd, (FX_LPCWSTR)L"contentType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ContentType, XFA_SCRIPT_Basic},
+ {0x54fa722c, (FX_LPCWSTR)L"transferEncoding", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TransferEncoding, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xf197844d, (FX_LPCWSTR)L"match", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Match, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xd996fa9b, (FX_LPCWSTR)L"hand", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic}, {0x21aed, (FX_LPCWSTR)L"id", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x28dee6e9, (FX_LPCWSTR)L"format", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Encrypt_Format, -1, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x68, (FX_LPCWSTR)L"h", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_H, XFA_SCRIPT_Basic}, {0x77, (FX_LPCWSTR)L"w", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_W, XFA_SCRIPT_Basic},
+ {0x78, (FX_LPCWSTR)L"x", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_X, XFA_SCRIPT_Basic}, {0x79, (FX_LPCWSTR)L"y", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Y, XFA_SCRIPT_Basic}, {0x2282c73, (FX_LPCWSTR)L"hAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_HAlign, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2ee7678f, (FX_LPCWSTR)L"rotate", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Rotate, XFA_SCRIPT_Basic}, {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+ {0x7a7cc341, (FX_LPCWSTR)L"vAlign", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_VAlign, XFA_SCRIPT_Basic}, {0x7c2ff6ae, (FX_LPCWSTR)L"maxH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxH, XFA_SCRIPT_Basic}, {0x7c2ff6bd, (FX_LPCWSTR)L"maxW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MaxW, XFA_SCRIPT_Basic},
+ {0x7d02356c, (FX_LPCWSTR)L"minH", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinH, XFA_SCRIPT_Basic}, {0x7d02357b, (FX_LPCWSTR)L"minW", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_MinW, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic},
+ {0xa03cf627, (FX_LPCWSTR)L"rawValue", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xac06e2b0, (FX_LPCWSTR)L"colSpan", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ColSpan, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbc8fa350, (FX_LPCWSTR)L"locale", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Locale, XFA_SCRIPT_Basic}, {0xc2bd40fd, (FX_LPCWSTR)L"anchorType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_AnchorType, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x39cdb0a2, (FX_LPCWSTR)L"priority", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Priority, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xeb511b54, (FX_LPCWSTR)L"disable", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Disable, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Value, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x21aed, (FX_LPCWSTR)L"id", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xcb0ac9, (FX_LPCWSTR)L"lineThrough", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LineThrough, XFA_SCRIPT_Basic}, {0x2c1c7f1, (FX_LPCWSTR)L"typeface", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Typeface, XFA_SCRIPT_Basic}, {0x8c74ae9, (FX_LPCWSTR)L"fontHorizontalScale", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_FontHorizontalScale, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2cd79033, (FX_LPCWSTR)L"kerningMode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_KerningMode, XFA_SCRIPT_Basic}, {0x3a0273a6, (FX_LPCWSTR)L"underline", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Underline, XFA_SCRIPT_Basic},
+ {0x4873c601, (FX_LPCWSTR)L"baselineShift", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_BaselineShift, XFA_SCRIPT_Basic}, {0x4b319767, (FX_LPCWSTR)L"overlinePeriod", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_OverlinePeriod, XFA_SCRIPT_Basic}, {0x79543055, (FX_LPCWSTR)L"letterSpacing", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LetterSpacing, XFA_SCRIPT_Basic},
+ {0x8ec6204c, (FX_LPCWSTR)L"lineThroughPeriod", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LineThroughPeriod, XFA_SCRIPT_Basic}, {0x907c7719, (FX_LPCWSTR)L"fontVerticalScale", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_FontVerticalScale, XFA_SCRIPT_Basic}, {0xa686975b, (FX_LPCWSTR)L"size", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Size, XFA_SCRIPT_Basic},
+ {0xb5e49bf2, (FX_LPCWSTR)L"posture", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Posture, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbd6e1d88, (FX_LPCWSTR)L"weight", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Weight, XFA_SCRIPT_Basic},
+ {0xbd96a0e9, (FX_LPCWSTR)L"underlinePeriod", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_UnderlinePeriod, XFA_SCRIPT_Basic}, {0xc0ec9fa4, (FX_LPCWSTR)L"overline", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Overline, XFA_SCRIPT_Basic}, {0xaf754613, (FX_LPCWSTR)L"checksum", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Form_Checksum, -1, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x8e1c2921, (FX_LPCWSTR)L"relevant", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Relevant, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xea7090a0, (FX_LPCWSTR)L"override", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Override, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x9dcc3ab3, (FX_LPCWSTR)L"trailer", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xcbcaf66d, (FX_LPCWSTR)L"leader", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x60a61edd, (FX_LPCWSTR)L"codeType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CodeType, XFA_SCRIPT_Basic}, {0xb373a862, (FX_LPCWSTR)L"archive", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Archive, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xe1a26b56, (FX_LPCWSTR)L"codeBase", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_CodeBase, XFA_SCRIPT_Basic}, {0xeb091003, (FX_LPCWSTR)L"classId", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ClassId, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x47d03490, (FX_LPCWSTR)L"connection", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic},
+ {0xc39a88bd, (FX_LPCWSTR)L"labelRef", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_LabelRef, XFA_SCRIPT_Basic}, {0xd50f903a, (FX_LPCWSTR)L"valueRef", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_ValueRef, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xea7090a0, (FX_LPCWSTR)L"override", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Override, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Extras_Type, -1, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbb8df5d, (FX_LPCWSTR)L"ref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x24d85167, (FX_LPCWSTR)L"timeout", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Timeout, XFA_SCRIPT_Basic},
+ {0x47d03490, (FX_LPCWSTR)L"connection", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Connection, XFA_SCRIPT_Basic}, {0x552d9ad5, (FX_LPCWSTR)L"usage", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usage, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xc860f30a, (FX_LPCWSTR)L"delayedOpen", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_DelayedOpen, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x28dee6e9, (FX_LPCWSTR)L"format", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Format, XFA_SCRIPT_Basic}, {0x824f21b7, (FX_LPCWSTR)L"embedPDF", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_EmbedPDF, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic}, {0xdc75676c, (FX_LPCWSTR)L"textEncoding", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TextEncoding, XFA_SCRIPT_Basic},
+ {0xf889e747, (FX_LPCWSTR)L"xdpContent", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_XdpContent, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x97be91b, (FX_LPCWSTR)L"content", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Packet_Content, -1, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x4156ee3f, (FX_LPCWSTR)L"delimiter", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Delimiter, XFA_SCRIPT_Basic},
+ {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0x21aed, (FX_LPCWSTR)L"id", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbb8df5d, (FX_LPCWSTR)L"ref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0x21aed, (FX_LPCWSTR)L"id", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x2f16a382, (FX_LPCWSTR)L"type", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Type, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic},
+ {0x453eaf38, (FX_LPCWSTR)L"startNew", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_StartNew, XFA_SCRIPT_Basic}, {0x9dcc3ab3, (FX_LPCWSTR)L"trailer", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Trailer, XFA_SCRIPT_Basic}, {0xa6118c89, (FX_LPCWSTR)L"targetType", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_TargetType, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xc8da4da7, (FX_LPCWSTR)L"target", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Target, XFA_SCRIPT_Basic}, {0xcbcaf66d, (FX_LPCWSTR)L"leader", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Leader, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xabef37e3, (FX_LPCWSTR)L"slope", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Slope, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic},
+ {0xd996fa9b, (FX_LPCWSTR)L"hand", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Hand, XFA_SCRIPT_Basic}, {0xa60dd202, (FX_LPCWSTR)L"length", (XFA_ATTRIBUTE_CALLBACK)&CXFA_NodeList::Script_ListClass_Length, -1, XFA_SCRIPT_Basic}, {0x20146, (FX_LPCWSTR)L"db", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Source_Db, -1, XFA_SCRIPT_Basic},
+ {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xb3543a6, (FX_LPCWSTR)L"max", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Occur_Max, -1, XFA_SCRIPT_Basic},
+ {0xb356ca4, (FX_LPCWSTR)L"min", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Occur_Min, -1, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x7d0b5fca, (FX_LPCWSTR)L"initial", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Initial, XFA_SCRIPT_Basic},
+ {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x29418bb7, (FX_LPCWSTR)L"abbr", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Abbr, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic},
+ {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0xbe52dfbf, (FX_LPCWSTR)L"desc", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Desc, XFA_SCRIPT_Basic}, {0xf6b47749, (FX_LPCWSTR)L"lock", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_BOOL, XFA_ATTRIBUTE_Lock, XFA_SCRIPT_Basic},
+ {0xbb8df5d, (FX_LPCWSTR)L"ref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Ref, XFA_SCRIPT_Basic}, {0xc0811ed, (FX_LPCWSTR)L"use", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Use, XFA_SCRIPT_Basic}, {0x570ce835, (FX_LPCWSTR)L"presence", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Presence, XFA_SCRIPT_Basic},
+ {0xa5b410cf, (FX_LPCWSTR)L"save", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Save, XFA_SCRIPT_Basic}, {0xbc254332, (FX_LPCWSTR)L"usehref", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Usehref, XFA_SCRIPT_Basic}, {0xb2c80857, (FX_LPCWSTR)L"className", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Object::Script_ObjectClass_ClassName, -1, XFA_SCRIPT_Basic},
+ {0xa60dd202, (FX_LPCWSTR)L"length", (XFA_ATTRIBUTE_CALLBACK)&CXFA_NodeList::Script_ListClass_Length, -1, XFA_SCRIPT_Basic}, {0x31b19c1, (FX_LPCWSTR)L"name", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Name, XFA_SCRIPT_Basic}, {0x9f9d0f9, (FX_LPCWSTR)L"all", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_All, -1, XFA_SCRIPT_Object},
+ {0x4df15659, (FX_LPCWSTR)L"nodes", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_Nodes, -1, XFA_SCRIPT_Object}, {0x78a8d6cf, (FX_LPCWSTR)L"classAll", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_ClassAll, -1, XFA_SCRIPT_Object}, {0xcad6d8ca, (FX_LPCWSTR)L"parent", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_Parent, -1, XFA_SCRIPT_Object},
+ {0xd5679c78, (FX_LPCWSTR)L"index", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_Index, -1, XFA_SCRIPT_Basic}, {0xdb5b4bce, (FX_LPCWSTR)L"classIndex", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_ClassIndex, -1, XFA_SCRIPT_Basic}, {0xe4989adf, (FX_LPCWSTR)L"somExpression", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_TreeClass_SomExpression, -1, XFA_SCRIPT_Basic},
+ {0x21aed, (FX_LPCWSTR)L"id", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Attribute_String, XFA_ATTRIBUTE_Id, XFA_SCRIPT_Basic}, {0x234a1, (FX_LPCWSTR)L"ns", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_Ns, -1, XFA_SCRIPT_Basic}, {0x50d1a9d1, (FX_LPCWSTR)L"model", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_Model, -1, XFA_SCRIPT_Object},
+ {0xacb4823f, (FX_LPCWSTR)L"isContainer", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_IsContainer, -1, XFA_SCRIPT_Basic}, {0xe372ae97, (FX_LPCWSTR)L"isNull", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_IsNull, -1, XFA_SCRIPT_Basic}, {0xfe612a5b, (FX_LPCWSTR)L"oneOfChild", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_NodeClass_OneOfChild, -1, XFA_SCRIPT_Object},
+ {0x97c1c65, (FX_LPCWSTR)L"context", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ModelClass_Context, -1, XFA_SCRIPT_Object}, {0x58be2870, (FX_LPCWSTR)L"aliasNode", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_ModelClass_AliasNode, -1, XFA_SCRIPT_Object}, {0xa52682bd, (FX_LPCWSTR)L"{default}", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+ {0xd6e27f1d, (FX_LPCWSTR)L"value", (XFA_ATTRIBUTE_CALLBACK)&CXFA_Node::Script_Som_DefaultValue, -1, XFA_SCRIPT_Basic},
+};
+extern const FX_INT32 g_iSomAttributeCount = sizeof(g_SomAttributeData) / sizeof(XFA_ATTRIBUTEINFO);
diff --git a/xfa/src/fxfa/src/parser/xfa_basic_imp.cpp b/xfa/src/fxfa/src/parser/xfa_basic_imp.cpp
new file mode 100644
index 0000000000..2d8f173f0f
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_basic_imp.cpp
@@ -0,0 +1,634 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_basic_imp.h"
+extern const XFA_PACKETINFO g_XFAPacketData[];
+extern const FX_INT32 g_iXFAPacketCount;
+extern const XFA_ATTRIBUTEENUMINFO g_XFAEnumData[];
+extern const FX_INT32 g_iXFAEnumCount;
+extern const XFA_ATTRIBUTEINFO g_XFAAttributeData[];
+extern const FX_INT32 g_iXFAAttributeCount;
+extern const XFA_ELEMENTINFO g_XFAElementData[];
+extern const FX_INT32 g_iXFAElementCount;
+extern const XFA_ELEMENTHIERARCHY g_XFAElementChildrenIndex[];
+extern const FX_WORD g_XFAElementChildrenData[];
+extern const XFA_ELEMENTHIERARCHY g_XFAElementAttributeIndex[];
+extern const FX_BYTE g_XFAElementAttributeData[];
+extern const XFA_NOTSUREATTRIBUTE g_XFANotsureAttributes[];
+extern const FX_INT32 g_iXFANotsureCount;
+extern const XFA_ELEMENTHIERARCHY g_XFAElementPropertyIndex[];
+extern const XFA_PROPERTY g_XFAElementPropertyData[];
+extern const XFA_SCRIPTHIERARCHY g_XFAScriptIndex[];
+extern const XFA_METHODINFO g_SomMethodData[];
+extern const FX_INT32 g_iSomMethodCount;
+extern const XFA_SCRIPTATTRIBUTEINFO g_SomAttributeData[];
+extern const FX_INT32 g_iSomAttributeCount;
+XFA_LPCPACKETINFO XFA_GetPacketByName(FX_WSTR wsName)
+{
+ FX_INT32 iLength = wsName.GetLength();
+ if (iLength == 0) {
+ return NULL;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+ FX_INT32 iStart = 0, iEnd = g_iXFAPacketCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCPACKETINFO pInfo = g_XFAPacketData + iMid;
+ if (uHash == pInfo->uHash) {
+ return pInfo;
+ } else if (uHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+XFA_LPCPACKETINFO XFA_GetPacketByID(FX_DWORD dwPacket)
+{
+ FX_INT32 iStart = 0, iEnd = g_iXFAPacketCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ FX_DWORD dwFind = (g_XFAPacketData + iMid)->eName;
+ if (dwPacket == dwFind) {
+ return g_XFAPacketData + iMid;
+ } else if (dwPacket < dwFind) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByName(FX_WSTR wsName)
+{
+ FX_INT32 iLength = wsName.GetLength();
+ if (iLength == 0) {
+ return NULL;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+ FX_INT32 iStart = 0, iEnd = g_iXFAEnumCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCATTRIBUTEENUMINFO pInfo = g_XFAEnumData + iMid;
+ if (uHash == pInfo->uHash) {
+ return pInfo;
+ } else if (uHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+XFA_LPCATTRIBUTEENUMINFO XFA_GetAttributeEnumByID(XFA_ATTRIBUTEENUM eName)
+{
+ return g_XFAEnumData + eName;
+}
+FX_INT32 XFA_GetAttributeCount()
+{
+ return g_iXFAAttributeCount;
+}
+XFA_LPCATTRIBUTEINFO XFA_GetAttributeByName(FX_WSTR wsName)
+{
+ FX_INT32 iLength = wsName.GetLength();
+ if (iLength == 0) {
+ return NULL;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+ FX_INT32 iStart = 0, iEnd = g_iXFAAttributeCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCATTRIBUTEINFO pInfo = g_XFAAttributeData + iMid;
+ if (uHash == pInfo->uHash) {
+ return pInfo;
+ } else if (uHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+XFA_LPCATTRIBUTEINFO XFA_GetAttributeByID(XFA_ATTRIBUTE eName)
+{
+ return (eName < g_iXFAAttributeCount) ? (g_XFAAttributeData + eName) : NULL;
+}
+FX_BOOL XFA_GetAttributeDefaultValue(FX_LPVOID &pValue, XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, XFA_ATTRIBUTETYPE eType, FX_DWORD dwPacket)
+{
+ XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttribute);
+ if (pInfo == NULL) {
+ return FALSE;
+ }
+ if (dwPacket && (dwPacket & pInfo->dwPackets) == 0) {
+ return FALSE;
+ }
+ if (pInfo->eType == eType) {
+ pValue = pInfo->pDefValue;
+ return TRUE;
+ } else if (pInfo->eType == XFA_ATTRIBUTETYPE_NOTSURE) {
+ XFA_LPCNOTSUREATTRIBUTE pAttr = XFA_GetNotsureAttribute(eElement, eAttribute, eType);
+ if (pAttr) {
+ pValue = pAttr->pValue;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+XFA_ATTRIBUTEENUM XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket)
+{
+ FX_LPVOID pValue;
+ if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, XFA_ATTRIBUTETYPE_Enum, dwPacket)) {
+ return (XFA_ATTRIBUTEENUM)(FX_UINTPTR)pValue;
+ }
+ return XFA_ATTRIBUTEENUM_Unknown;
+}
+CFX_WideStringC XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket)
+{
+ FX_LPVOID pValue;
+ if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, XFA_ATTRIBUTETYPE_Cdata, dwPacket)) {
+ return (FX_LPCWSTR)pValue;
+ }
+ return NULL;
+}
+FX_BOOL XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket)
+{
+ FX_LPVOID pValue;
+ if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, XFA_ATTRIBUTETYPE_Boolean, dwPacket)) {
+ return (FX_BOOL)(FX_UINTPTR)pValue;
+ }
+ return FALSE;
+}
+FX_INT32 XFA_GetAttributeDefaultValue_Integer(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket)
+{
+ FX_LPVOID pValue;
+ if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, XFA_ATTRIBUTETYPE_Integer, dwPacket)) {
+ return (FX_INT32)(FX_UINTPTR)pValue;
+ }
+ return 0;
+}
+CXFA_Measurement XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket)
+{
+ FX_LPVOID pValue;
+ if (XFA_GetAttributeDefaultValue(pValue, eElement, eAttribute, XFA_ATTRIBUTETYPE_Measure, dwPacket)) {
+ return *(CXFA_Measurement*)pValue;
+ }
+ return CXFA_Measurement();
+}
+FX_INT32 XFA_GetElementCount()
+{
+ return g_iXFAElementCount;
+}
+XFA_LPCELEMENTINFO XFA_GetElementByName(FX_WSTR wsName)
+{
+ FX_INT32 iLength = wsName.GetLength();
+ if (iLength == 0) {
+ return NULL;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsName.GetPtr(), iLength);
+ FX_INT32 iStart = 0, iEnd = g_iXFAElementCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCELEMENTINFO pInfo = g_XFAElementData + iMid;
+ if (uHash == pInfo->uHash) {
+ return pInfo;
+ } else if (uHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+XFA_LPCELEMENTINFO XFA_GetElementByID(XFA_ELEMENT eName)
+{
+ return (eName < g_iXFAElementCount) ? (g_XFAElementData + eName) : NULL;
+}
+FX_LPCWORD XFA_GetElementChildren(XFA_ELEMENT eElement, FX_INT32 &iCount)
+{
+ if (eElement >= g_iXFAElementCount) {
+ return NULL;
+ }
+ XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementChildrenIndex + eElement;
+ iCount = pElement->wCount;
+ return g_XFAElementChildrenData + pElement->wStart;
+}
+FX_LPCBYTE XFA_GetElementAttributes(XFA_ELEMENT eElement, FX_INT32 &iCount)
+{
+ if (eElement >= g_iXFAElementCount) {
+ return NULL;
+ }
+ XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementAttributeIndex + eElement;
+ iCount = pElement->wCount;
+ return g_XFAElementAttributeData + pElement->wStart;
+}
+XFA_LPCATTRIBUTEINFO XFA_GetAttributeOfElement(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, FX_DWORD dwPacket)
+{
+ FX_INT32 iCount = 0;
+ FX_LPCBYTE pAttr = XFA_GetElementAttributes(eElement, iCount);
+ if (pAttr == NULL || iCount < 1) {
+ return NULL;
+ }
+ CFX_DSPATemplate<FX_BYTE> search;
+ FX_INT32 index = search.Lookup(eAttribute, pAttr, iCount);
+ if (index < 0) {
+ return NULL;
+ }
+ XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttribute);
+ ASSERT(pInfo != NULL);
+ if (dwPacket == XFA_XDPPACKET_UNKNOWN) {
+ return pInfo;
+ }
+ return (dwPacket & pInfo->dwPackets) ? pInfo : NULL;
+}
+XFA_LPCELEMENTINFO XFA_GetChildOfElement(XFA_ELEMENT eElement, XFA_ELEMENT eChild, FX_DWORD dwPacket)
+{
+ FX_INT32 iCount = 0;
+ FX_LPCWORD pChild = XFA_GetElementChildren(eElement, iCount);
+ if (pChild == NULL || iCount < 1) {
+ return NULL;
+ }
+ CFX_DSPATemplate<FX_WORD> search;
+ FX_INT32 index = search.Lookup(eChild, pChild, iCount);
+ if (index < 0) {
+ return NULL;
+ }
+ XFA_LPCELEMENTINFO pInfo = XFA_GetElementByID(eChild);
+ ASSERT(pInfo != NULL);
+ if (dwPacket == XFA_XDPPACKET_UNKNOWN) {
+ return pInfo;
+ }
+ return (dwPacket & pInfo->dwPackets) ? pInfo : NULL;
+}
+XFA_LPCPROPERTY XFA_GetElementProperties(XFA_ELEMENT eElement, FX_INT32 &iCount)
+{
+ if (eElement >= g_iXFAElementCount) {
+ return NULL;
+ }
+ XFA_LPCELEMENTHIERARCHY pElement = g_XFAElementPropertyIndex + eElement;
+ iCount = pElement->wCount;
+ return g_XFAElementPropertyData + pElement->wStart;
+}
+XFA_LPCPROPERTY XFA_GetPropertyOfElement(XFA_ELEMENT eElement, XFA_ELEMENT eProperty, FX_DWORD dwPacket)
+{
+ FX_INT32 iCount = 0;
+ XFA_LPCPROPERTY pProperty = XFA_GetElementProperties(eElement, iCount);
+ if (pProperty == NULL || iCount < 1) {
+ return NULL;
+ }
+ FX_INT32 iStart = 0, iEnd = iCount - 1, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ XFA_ELEMENT eName = (XFA_ELEMENT)pProperty[iMid].eName;
+ if (eProperty == eName) {
+ break;
+ } else if (eProperty < eName) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ if (iStart > iEnd) {
+ return NULL;
+ }
+ XFA_LPCELEMENTINFO pInfo = XFA_GetElementByID(eProperty);
+ ASSERT(pInfo != NULL);
+ if (dwPacket == XFA_XDPPACKET_UNKNOWN) {
+ return pProperty + iMid;
+ }
+ return (dwPacket & pInfo->dwPackets) ? (pProperty + iMid) : NULL;
+}
+XFA_LPCNOTSUREATTRIBUTE XFA_GetNotsureAttribute(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, XFA_ATTRIBUTETYPE eType)
+{
+ FX_INT32 iStart = 0, iEnd = g_iXFANotsureCount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCNOTSUREATTRIBUTE pAttr = g_XFANotsureAttributes + iMid;
+ if (eElement == pAttr->eElement) {
+ if (pAttr->eAttribute == eAttribute) {
+ if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
+ return pAttr;
+ }
+ return NULL;
+ } else {
+ FX_INT32 iBefore = iMid - 1;
+ if(iBefore >= 0) {
+ pAttr = g_XFANotsureAttributes + iBefore;
+ while(eElement == pAttr->eElement) {
+ if(pAttr->eAttribute == eAttribute) {
+ if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
+ return pAttr;
+ }
+ return NULL;
+ }
+ iBefore --;
+ if(iBefore < 0) {
+ break;
+ }
+ pAttr = g_XFANotsureAttributes + iBefore;
+ }
+ }
+ FX_INT32 iAfter = iMid + 1;
+ if(iAfter <= g_iXFANotsureCount - 1) {
+ pAttr = g_XFANotsureAttributes + iAfter;
+ while(eElement == pAttr->eElement) {
+ if(pAttr->eAttribute == eAttribute) {
+ if (eType == XFA_ATTRIBUTETYPE_NOTSURE || eType == pAttr->eType) {
+ return pAttr;
+ }
+ return NULL;
+ }
+ iAfter ++;
+ if(iAfter > g_iXFANotsureCount - 1) {
+ break;
+ }
+ pAttr = g_XFANotsureAttributes + iAfter;
+ }
+ }
+ return NULL;
+ }
+ } else if (eElement < pAttr->eElement) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+FX_INT32 XFA_GetMethodCount()
+{
+ return g_iSomMethodCount;
+}
+XFA_LPCMETHODINFO XFA_GetMethodByName(XFA_ELEMENT eElement, FX_WSTR wsMethodName)
+{
+ FX_INT32 iLength = wsMethodName.GetLength();
+ if (iLength == 0) {
+ return NULL;
+ }
+ FX_INT32 iElementIndex = eElement;
+ while(iElementIndex != -1) {
+ XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex;
+ FX_INT32 icount = scriptIndex->wMethodCount;
+ if(icount == 0) {
+ iElementIndex = scriptIndex->wParentIndex;
+ continue;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsMethodName.GetPtr(), iLength);
+ FX_INT32 iStart = scriptIndex->wMethodStart, iEnd = iStart + icount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCMETHODINFO pInfo = g_SomMethodData + iMid;
+ if (uHash == pInfo->uHash) {
+ return pInfo;
+ } else if (uHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ iElementIndex = scriptIndex->wParentIndex;
+ }
+ return NULL;
+}
+XFA_LPCSCRIPTATTRIBUTEINFO XFA_GetScriptAttributeByName(XFA_ELEMENT eElement, FX_WSTR wsAttributeName)
+{
+ FX_INT32 iLength = wsAttributeName.GetLength();
+ if (iLength == 0) {
+ return NULL;
+ }
+ FX_INT32 iElementIndex = eElement;
+ while(iElementIndex != -1) {
+ XFA_LPCSCRIPTHIERARCHY scriptIndex = g_XFAScriptIndex + iElementIndex;
+ FX_INT32 icount = scriptIndex->wAttributeCount;
+ if(icount == 0) {
+ iElementIndex = scriptIndex->wParentIndex;
+ continue;
+ }
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsAttributeName.GetPtr(), iLength);
+ FX_INT32 iStart = scriptIndex->wAttributeStart, iEnd = iStart + icount - 1;
+ do {
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ XFA_LPCSCRIPTATTRIBUTEINFO pInfo = g_SomAttributeData + iMid;
+ if (uHash == pInfo->uHash) {
+ return pInfo;
+ } else if (uHash < pInfo->uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ iElementIndex = scriptIndex->wParentIndex;
+ }
+ return NULL;
+}
+void CXFA_Measurement::Set(FX_WSTR wsMeasure)
+{
+ if (wsMeasure.IsEmpty()) {
+ m_fValue = 0;
+ m_eUnit = XFA_UNIT_Unknown;
+ return;
+ }
+ FX_INT32 iUsedLen = 0;
+ FX_INT32 iOffset = (wsMeasure.GetAt(0) == L'=') ? 1 : 0;
+ FX_FLOAT fValue = FX_wcstof(wsMeasure.GetPtr() + iOffset, wsMeasure.GetLength() - iOffset, &iUsedLen);
+ XFA_UNIT eUnit = GetUnit(wsMeasure.Mid(iOffset + iUsedLen));
+ Set(fValue, eUnit);
+}
+FX_BOOL CXFA_Measurement::ToString(CFX_WideString &wsMeasure) const
+{
+ switch (GetUnit()) {
+ case XFA_UNIT_Mm:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8gmm", GetValue());
+ return TRUE;
+ case XFA_UNIT_Pt:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8gpt", GetValue());
+ return TRUE;
+ case XFA_UNIT_In:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8gin", GetValue());
+ return TRUE;
+ case XFA_UNIT_Cm:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8gcm", GetValue());
+ return TRUE;
+ case XFA_UNIT_Mp:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8gmp", GetValue());
+ return TRUE;
+ case XFA_UNIT_Pc:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8gpc", GetValue());
+ return TRUE;
+ case XFA_UNIT_Em:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8gem", GetValue());
+ return TRUE;
+ case XFA_UNIT_Percent:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8g%%", GetValue());
+ return TRUE;
+ default:
+ wsMeasure.Format((FX_LPCWSTR)L"%.8g", GetValue());
+ return FALSE;
+ }
+}
+FX_BOOL CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT &fValue) const
+{
+ fValue = GetValue();
+ XFA_UNIT eFrom = GetUnit();
+ if (eFrom == eUnit) {
+ return TRUE;
+ }
+ switch (eFrom) {
+ case XFA_UNIT_Pt:
+ break;
+ case XFA_UNIT_Mm:
+ fValue *= 72 / 2.54f / 10;
+ break;
+ case XFA_UNIT_In:
+ fValue *= 72;
+ break;
+ case XFA_UNIT_Cm:
+ fValue *= 72 / 2.54f;
+ break;
+ case XFA_UNIT_Mp:
+ fValue *= 0.001f;
+ break;
+ case XFA_UNIT_Pc:
+ fValue *= 12.0f;
+ break;
+ default:
+ fValue = 0;
+ return FALSE;
+ }
+ switch (eUnit) {
+ case XFA_UNIT_Pt:
+ return TRUE;
+ case XFA_UNIT_Mm:
+ fValue /= 72 / 2.54f / 10;
+ return TRUE;
+ case XFA_UNIT_In:
+ fValue /= 72;
+ return TRUE;
+ case XFA_UNIT_Cm:
+ fValue /= 72 / 2.54f;
+ return TRUE;
+ case XFA_UNIT_Mp:
+ fValue /= 0.001f;
+ return TRUE;
+ case XFA_UNIT_Pc:
+ fValue /= 12.0f;
+ return TRUE;
+ default:
+ fValue = 0;
+ return FALSE;
+ }
+ return FALSE;
+}
+XFA_UNIT CXFA_Measurement::GetUnit(FX_WSTR wsUnit)
+{
+ if (wsUnit == FX_WSTRC(L"mm")) {
+ return XFA_UNIT_Mm;
+ } else if (wsUnit == FX_WSTRC(L"pt")) {
+ return XFA_UNIT_Pt;
+ } else if (wsUnit == FX_WSTRC(L"in")) {
+ return XFA_UNIT_In;
+ } else if (wsUnit == FX_WSTRC(L"cm")) {
+ return XFA_UNIT_Cm;
+ } else if (wsUnit == FX_WSTRC(L"pc")) {
+ return XFA_UNIT_Pc;
+ } else if (wsUnit == FX_WSTRC(L"mp")) {
+ return XFA_UNIT_Mp;
+ } else if (wsUnit == FX_WSTRC(L"em")) {
+ return XFA_UNIT_Em;
+ } else if (wsUnit == FX_WSTRC(L"%")) {
+ return XFA_UNIT_Percent;
+ } else {
+ return XFA_UNIT_Unknown;
+ }
+}
+IFX_Stream* XFA_CreateWideTextRead(const CFX_WideString &wsBuffer)
+{
+ return FX_NEW CXFA_WideTextRead(wsBuffer);
+}
+CXFA_WideTextRead::CXFA_WideTextRead(const CFX_WideString &wsBuffer)
+ : m_wsBuffer(wsBuffer)
+ , m_iPosition(0)
+ , m_iRefCount(1)
+{
+}
+void CXFA_WideTextRead::Release()
+{
+ if (--m_iRefCount < 1) {
+ delete this;
+ }
+}
+IFX_Stream* CXFA_WideTextRead::Retain()
+{
+ m_iRefCount++;
+ return this;
+}
+FX_DWORD CXFA_WideTextRead::GetAccessModes() const
+{
+ return FX_STREAMACCESS_Read | FX_STREAMACCESS_Text;
+}
+FX_INT32 CXFA_WideTextRead::GetLength() const
+{
+ return m_wsBuffer.GetLength() * sizeof(FX_WCHAR);
+}
+FX_INT32 CXFA_WideTextRead::Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset)
+{
+ switch (eSeek) {
+ case FX_STREAMSEEK_Begin:
+ m_iPosition = iOffset;
+ break;
+ case FX_STREAMSEEK_Current:
+ m_iPosition += iOffset;
+ break;
+ case FX_STREAMSEEK_End:
+ m_iPosition = m_wsBuffer.GetLength() + iOffset;
+ break;
+ }
+ if (m_iPosition < 0) {
+ m_iPosition = 0;
+ }
+ if (m_iPosition > m_wsBuffer.GetLength()) {
+ m_iPosition = m_wsBuffer.GetLength();
+ }
+ return GetPosition();
+}
+FX_INT32 CXFA_WideTextRead::GetPosition()
+{
+ return m_iPosition * sizeof(FX_WCHAR);
+}
+FX_BOOL CXFA_WideTextRead::IsEOF() const
+{
+ return m_iPosition >= m_wsBuffer.GetLength();
+}
+FX_INT32 CXFA_WideTextRead::ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize )
+{
+ if (iMaxLength > m_wsBuffer.GetLength() - m_iPosition) {
+ iMaxLength = m_wsBuffer.GetLength() - m_iPosition;
+ }
+ FXSYS_wcsncpy(pStr, (FX_LPCWSTR)m_wsBuffer + m_iPosition, iMaxLength);
+ m_iPosition += iMaxLength;
+ bEOS = IsEOF();
+ return iMaxLength;
+}
+FX_WORD CXFA_WideTextRead::GetCodePage() const
+{
+ return (sizeof(FX_WCHAR) == 2) ? FX_CODEPAGE_UTF16LE : FX_CODEPAGE_UTF32LE;
+}
+FX_WORD CXFA_WideTextRead::SetCodePage(FX_WORD wCodePage)
+{
+ return GetCodePage();
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_basic_imp.h b/xfa/src/fxfa/src/parser/xfa_basic_imp.h
new file mode 100644
index 0000000000..7fced07a05
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_basic_imp.h
@@ -0,0 +1,73 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_BASIC_IMP
+#define _XFA_BASIC_IMP
+typedef struct _XFA_NOTSUREATTRIBUTE {
+ XFA_ELEMENT eElement;
+ XFA_ATTRIBUTE eAttribute;
+ XFA_ATTRIBUTETYPE eType;
+ FX_LPVOID pValue;
+} XFA_NOTSUREATTRIBUTE, * XFA_LPNOTSUREATTRIBUTE;
+typedef XFA_NOTSUREATTRIBUTE const * XFA_LPCNOTSUREATTRIBUTE;
+XFA_LPCNOTSUREATTRIBUTE XFA_GetNotsureAttribute(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute, XFA_ATTRIBUTETYPE eType = XFA_ATTRIBUTETYPE_NOTSURE);
+class CXFA_WideTextRead : public IFX_Stream, public CFX_Object
+{
+public:
+ CXFA_WideTextRead(const CFX_WideString &wsBuffer);
+ virtual void Release();
+ virtual IFX_Stream* Retain();
+
+ virtual FX_DWORD GetAccessModes() const;
+ virtual FX_INT32 GetLength() const;
+ virtual FX_INT32 Seek(FX_STREAMSEEK eSeek, FX_INT32 iOffset);
+ virtual FX_INT32 GetPosition();
+ virtual FX_BOOL IsEOF() const;
+
+ virtual FX_INT32 ReadData(FX_LPBYTE pBuffer, FX_INT32 iBufferSize)
+ {
+ return 0;
+ }
+ virtual FX_INT32 ReadString(FX_LPWSTR pStr, FX_INT32 iMaxLength, FX_BOOL &bEOS, FX_INT32 const *pByteSize = NULL);
+ virtual FX_INT32 WriteData(FX_LPCBYTE pBuffer, FX_INT32 iBufferSize)
+ {
+ return 0;
+ }
+ virtual FX_INT32 WriteString(FX_LPCWSTR pStr, FX_INT32 iLength)
+ {
+ return 0;
+ }
+ virtual void Flush() {}
+ virtual FX_BOOL SetLength(FX_INT32 iLength)
+ {
+ return FALSE;
+ }
+
+ virtual FX_INT32 GetBOM(FX_BYTE bom[4]) const
+ {
+ return 0;
+ }
+ virtual FX_WORD GetCodePage() const;
+ virtual FX_WORD SetCodePage(FX_WORD wCodePage);
+
+ virtual void Lock() {}
+ virtual void Unlock() {}
+
+ virtual IFX_Stream* CreateSharedStream(FX_DWORD dwAccess, FX_INT32 iOffset, FX_INT32 iLength)
+ {
+ return NULL;
+ }
+
+ CFX_WideString GetSrcText() const
+ {
+ return m_wsBuffer;
+ }
+protected:
+ CFX_WideString m_wsBuffer;
+ FX_INT32 m_iPosition;
+ FX_INT32 m_iRefCount;
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_debug_parser.cpp b/xfa/src/fxfa/src/parser/xfa_debug_parser.cpp
new file mode 100644
index 0000000000..4f5365e1d8
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_debug_parser.cpp
@@ -0,0 +1,18 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
diff --git a/xfa/src/fxfa/src/parser/xfa_debug_parser.h b/xfa/src/fxfa/src/parser/xfa_debug_parser.h
new file mode 100644
index 0000000000..90dce89d3e
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_debug_parser.h
@@ -0,0 +1,9 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DEBUG_PARSER_H_
+#define _XFA_DEBUG_PARSER_H_
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.cpp b/xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.cpp
new file mode 100644
index 0000000000..a559d5415f
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.cpp
@@ -0,0 +1,116 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#define XFA_HASHCODE_Group 0xf7f75fcd
+class CXFA_TraverseStrategy_DDGroup
+{
+public:
+ static inline CXFA_Node* GetFirstChild(CXFA_Node* pDDGroupNode)
+ {
+ return pDDGroupNode->GetFirstChildByName(XFA_HASHCODE_Group);
+ }
+ static inline CXFA_Node* GetNextSibling(CXFA_Node* pDDGroupNode)
+ {
+ return pDDGroupNode->GetNextSameNameSibling(XFA_HASHCODE_Group);
+ }
+ static inline CXFA_Node* GetParent(CXFA_Node* pDDGroupNode)
+ {
+ return pDDGroupNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+};
+void XFA_DataDescription_UpdateDataRelation(CXFA_Node* pDataNode, CXFA_Node* pDataDescriptionNode)
+{
+ FXSYS_assert(pDataDescriptionNode);
+ for(CXFA_Node* pDataChild = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); pDataChild; pDataChild = pDataChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ FX_DWORD dwNameHash = pDataChild->GetNameHash();
+ XFA_ELEMENT eType = pDataChild->GetClassID();
+ if(!dwNameHash) {
+ continue;
+ }
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> sIterator(pDataDescriptionNode);
+ for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; pDDGroupNode = sIterator.MoveToNext()) {
+ if(pDDGroupNode != pDataDescriptionNode) {
+ if(pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) {
+ continue;
+ }
+ CFX_WideString wsNamespace;
+ if(!pDDGroupNode->TryNamespace(wsNamespace) || wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
+ continue;
+ }
+ }
+ CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(dwNameHash);
+ if(!pDDNode) {
+ continue;
+ }
+ if(pDDNode->GetClassID() != eType) {
+ break;
+ }
+ pDataChild->SetDataDescriptionNode(pDDNode);
+ XFA_DataDescription_UpdateDataRelation(pDataChild, pDDNode);
+ break;
+ }
+ }
+}
+CXFA_Node* XFA_DataDescription_MaybeCreateDataNode(CXFA_Document* pDocument, CXFA_Node* pDataParent, XFA_ELEMENT eNodeType, FX_WSTR wsName)
+{
+ if(!pDataParent) {
+ return NULL;
+ }
+ CXFA_Node *pParentDDNode = pDataParent->GetDataDescriptionNode();
+ if(!pParentDDNode) {
+ CXFA_Node *pDataNode = pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
+ FXSYS_assert(pDataNode);
+ pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+ pDataNode->CreateXMLMappingNode();
+ pDataParent->InsertChild(pDataNode);
+ pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ return pDataNode;
+ } else {
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_DDGroup> sIterator(pParentDDNode);
+ for (CXFA_Node* pDDGroupNode = sIterator.GetCurrent(); pDDGroupNode; pDDGroupNode = sIterator.MoveToNext()) {
+ if(pDDGroupNode != pParentDDNode) {
+ if(pDDGroupNode->GetClassID() != XFA_ELEMENT_DataGroup) {
+ continue;
+ }
+ CFX_WideString wsNamespace;
+ if(!pDDGroupNode->TryNamespace(wsNamespace) || wsNamespace != FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
+ continue;
+ }
+ }
+ CXFA_Node* pDDNode = pDDGroupNode->GetFirstChildByName(wsName);
+ if(!pDDNode) {
+ continue;
+ }
+ if(pDDNode->GetClassID() != eNodeType) {
+ break;
+ }
+ CXFA_Node *pDataNode = pDocument->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
+ FXSYS_assert(pDataNode);
+ pDataNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+ pDataNode->CreateXMLMappingNode();
+ if(eNodeType == XFA_ELEMENT_DataValue && pDDNode->GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData) {
+ pDataNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData);
+ }
+ pDataParent->InsertChild(pDataNode);
+ pDataNode->SetDataDescriptionNode(pDDNode);
+ pDataNode->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ return pDataNode;
+ }
+ return NULL;
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.h b/xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.h
new file mode 100644
index 0000000000..ede14c03aa
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_datadescription_imp.h
@@ -0,0 +1,11 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCUMENT_DATADESCRIPTION_IMP_H_
+#define _XFA_DOCUMENT_DATADESCRIPTION_IMP_H_
+void XFA_DataDescription_UpdateDataRelation(CXFA_Node* pDataNode, CXFA_Node* pDataDescriptionNode);
+CXFA_Node* XFA_DataDescription_MaybeCreateDataNode(CXFA_Document* pDocument, CXFA_Node* pDataParent, XFA_ELEMENT eNodeType, FX_WSTR wsName);
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.cpp b/xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.cpp
new file mode 100644
index 0000000000..4cb97f436b
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.cpp
@@ -0,0 +1,1267 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_basic_imp.h"
+#include "xfa_document_imp.h"
+#include "xfa_document_datadescription_imp.h"
+#include "xfa_document_datamerger_imp.h"
+#include "xfa_document_layout_imp.h"
+static FX_BOOL XFA_GetOccurInfo(CXFA_Node* pOccurNode, FX_INT32& iMin, FX_INT32& iMax, FX_INT32& iInit)
+{
+ if(!pOccurNode) {
+ return FALSE;
+ }
+ CXFA_Occur occur(pOccurNode);
+ return occur.GetOccurInfo(iMin, iMax, iInit);
+}
+struct XFA_DataMerge_RecurseRecord {
+ CXFA_Node *pTemplateChild;
+ CXFA_Node *pDataChild;
+};
+static CXFA_Node* XFA_DataMerge_FormValueNode_CreateChild(CXFA_Node* pValueNode, XFA_ELEMENT iType = XFA_ELEMENT_UNKNOWN)
+{
+ CXFA_Node * pChildNode = pValueNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pChildNode) {
+ if (iType == XFA_ELEMENT_UNKNOWN) {
+ return FALSE;
+ }
+ pChildNode = pValueNode->GetProperty(0, iType);
+ }
+ return pChildNode;
+}
+static void XFA_DataMerge_FormValueNode_MatchNoneCreateChild(CXFA_Node* pFormNode)
+{
+ CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
+ FXSYS_assert(pWidgetData);
+ XFA_ELEMENT eUIType = pWidgetData->GetUIType();
+}
+static FX_BOOL XFA_DataMerge_FormValueNode_SetChildContent(CXFA_Node* pValueNode, const CFX_WideString& wsContent, XFA_ELEMENT iType = XFA_ELEMENT_UNKNOWN)
+{
+ if (!pValueNode) {
+ return FALSE;
+ }
+ FXSYS_assert(pValueNode->GetPacketID() == XFA_XDPPACKET_Form);
+ CXFA_Node* pChildNode = XFA_DataMerge_FormValueNode_CreateChild(pValueNode, iType);
+ if (!pChildNode) {
+ return FALSE;
+ }
+ XFA_OBJECTTYPE objectType = pChildNode->GetObjectType();
+ switch (objectType) {
+ case XFA_OBJECTTYPE_ContentNode: {
+ CXFA_Node *pContentRawDataNode = pChildNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pContentRawDataNode) {
+ XFA_ELEMENT element = XFA_ELEMENT_Sharptext;
+ if (pChildNode->GetClassID() == XFA_ELEMENT_ExData) {
+ CFX_WideString wsContentType;
+ pChildNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+ element = XFA_ELEMENT_SharpxHTML;
+ } else if (wsContentType.Equal(FX_WSTRC(L"text/xml"))) {
+ element = XFA_ELEMENT_Sharpxml;
+ }
+ }
+ pContentRawDataNode = pChildNode->CreateSamePacketNode(element);
+ pChildNode->InsertChild(pContentRawDataNode);
+ }
+ pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
+ }
+ break;
+ case XFA_OBJECTTYPE_NodeC:
+ case XFA_OBJECTTYPE_TextNode:
+ case XFA_OBJECTTYPE_NodeV: {
+ pChildNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
+ }
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ return TRUE;
+}
+static void XFA_DataMerge_CreateDataBinding(CXFA_Node* pFormNode, CXFA_Node* pDataNode, FX_BOOL bDataToForm = TRUE)
+{
+ pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, pDataNode);
+ pDataNode->AddBindItem(pFormNode);
+ XFA_ELEMENT eClass = pFormNode->GetClassID();
+ if (eClass != XFA_ELEMENT_Field && eClass != XFA_ELEMENT_ExclGroup) {
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = pFormNode->GetWidgetData();
+ FXSYS_assert(pWidgetData);
+ FX_BOOL bNotify = FALSE;
+ XFA_ELEMENT eUIType = pWidgetData->GetUIType();
+ CXFA_Value defValue = pFormNode->GetProperty(0, XFA_ELEMENT_Value);
+ if(!bDataToForm) {
+ CFX_WideString wsValue;
+ CFX_WideString wsFormatedValue;
+ switch (eUIType) {
+ case XFA_ELEMENT_ImageEdit: {
+ CXFA_Image image = defValue.GetImage();
+ CFX_WideString wsContentType;
+ CFX_WideString wsHref;
+ if (image) {
+ image.GetContent(wsValue);
+ image.GetContentType(wsContentType);
+ image.GetHref(wsHref);
+ }
+ IFDE_XMLElement *pXMLDataElement = (IFDE_XMLElement *)(pDataNode->GetXMLMappingNode());
+ FXSYS_assert(pXMLDataElement);
+ pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+ pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+ pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+ if (!wsHref.IsEmpty()) {
+ pXMLDataElement->SetString(FX_WSTRC(L"href"), wsHref);
+ }
+ }
+ break;
+ case XFA_ELEMENT_ChoiceList:
+ defValue.GetChildValueContent(wsValue);
+ if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+ CFX_WideStringArray wsSelTextArray;
+ pWidgetData->GetSelectedItemsValue(wsSelTextArray);
+ FX_INT32 iSize = wsSelTextArray.GetSize();
+ if (iSize >= 1) {
+ CXFA_Node *pValue = NULL;
+ IFDE_XMLNode *pValueXMLNode = NULL;
+ for (FX_INT32 i = 0; i < iSize; i++) {
+ pValue = pDataNode->CreateSamePacketNode(XFA_ELEMENT_DataValue);
+ pValue->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"value"));
+ pValueXMLNode = pValue->CreateXMLMappingNode();
+ pDataNode->InsertChild(pValue);
+ pValue->SetCData(XFA_ATTRIBUTE_Value, wsSelTextArray[i]);
+ }
+ } else {
+ IFDE_XMLNode *pXMLNode = pDataNode->GetXMLMappingNode();
+ FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element);
+ ((IFDE_XMLElement *)pXMLNode)->SetString(FX_WSTRC(L"xfa:dataNode"), FX_WSTRC(L"dataGroup"));
+ }
+ } else if (!wsValue.IsEmpty()) {
+ pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+ pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+ }
+ break;
+ case XFA_ELEMENT_CheckButton:
+ defValue.GetChildValueContent(wsValue);
+ if (wsValue.IsEmpty()) {
+ break;
+ }
+ pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+ pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+ break;
+ case XFA_ELEMENT_ExclGroup: {
+ CXFA_Node* pChecked = NULL;
+ XFA_ELEMENT eValueType = XFA_ELEMENT_UNKNOWN;
+ CXFA_Node* pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for ( ; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pChild->GetClassID() != XFA_ELEMENT_Field) {
+ continue;
+ }
+ CXFA_Node* pValue = pChild->GetChild(0, XFA_ELEMENT_Value);
+ if (!pValue) {
+ continue;
+ }
+ CXFA_Value valueChild(pValue);
+ valueChild.GetChildValueContent(wsValue);
+ if (wsValue.IsEmpty()) {
+ continue;
+ }
+ CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
+ if (!pItems) {
+ continue;
+ }
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pText) {
+ continue;
+ }
+ CFX_WideString wsContent;
+ if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
+ pChecked = pChild;
+ eValueType = pText->GetClassID();
+ wsFormatedValue = wsValue;
+ pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+ pFormNode->SetCData(XFA_ATTRIBUTE_Value, wsContent);
+ break;
+ }
+ }
+ if (!pChecked) {
+ break;
+ }
+ pChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for ( ; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pChild == pChecked) {
+ continue;
+ }
+ if (pChild->GetClassID() != XFA_ELEMENT_Field) {
+ continue;
+ }
+ CXFA_Node* pValue = pChild->GetProperty(0, XFA_ELEMENT_Value);
+ CXFA_Node* pItems = pChild->GetChild(0, XFA_ELEMENT_Items);
+ CXFA_Node* pText = pItems ? pItems->GetNodeItem(XFA_NODEITEM_FirstChild) : NULL;
+ if (pText) {
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ CFX_WideString wsContent;
+ if (pText) {
+ pText->TryContent(wsContent);
+ }
+ XFA_DataMerge_FormValueNode_SetChildContent(pValue, wsContent, XFA_ELEMENT_Text);
+ }
+ }
+ break;
+ case XFA_ELEMENT_NumericEdit: {
+ defValue.GetChildValueContent(wsValue);
+ if (wsValue.IsEmpty()) {
+ break;
+ }
+ CFX_WideString wsOutput;
+ pWidgetData->NormalizeNumStr(wsValue, wsOutput);
+ wsValue = wsOutput;
+ pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+ pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+ CXFA_Node* pValue = pFormNode->GetProperty(0, XFA_ELEMENT_Value);
+ XFA_DataMerge_FormValueNode_SetChildContent(pValue, wsValue, XFA_ELEMENT_Float);
+ }
+ break;
+ default:
+ defValue.GetChildValueContent(wsValue);
+ if (wsValue.IsEmpty()) {
+ break;
+ }
+ pWidgetData->GetFormatDataValue(wsValue, wsFormatedValue);
+ pDataNode->SetAttributeValue(wsValue, wsFormatedValue);
+ break;
+ }
+ } else {
+ CFX_WideString wsXMLValue;
+ pDataNode->TryContent(wsXMLValue);
+ CFX_WideString wsNormailizeValue;
+ pWidgetData->GetNormalizeDataValue(wsXMLValue, wsNormailizeValue);
+ pDataNode->SetAttributeValue(wsNormailizeValue, wsXMLValue);
+ switch (eUIType) {
+ case XFA_ELEMENT_ImageEdit: {
+ XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Image);
+ CXFA_Image image = defValue.GetImage();
+ if (image) {
+ IFDE_XMLElement *pXMLDataElement = (IFDE_XMLElement *)(pDataNode->GetXMLMappingNode());
+ FXSYS_assert(pXMLDataElement);
+ CFX_WideString wsContentType;
+ CFX_WideString wsHref;
+ pXMLDataElement->GetString((FX_LPCWSTR)L"xfa:contentType", wsContentType);
+ if (!wsContentType.IsEmpty()) {
+ pDataNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+ image.SetContentType(wsContentType);
+ }
+ pXMLDataElement->GetString((FX_LPCWSTR)L"href", wsHref);
+ if (!wsHref.IsEmpty()) {
+ image.SetHref(wsHref);
+ }
+ }
+ }
+ break;
+ case XFA_ELEMENT_ChoiceList:
+ if (pWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+ CXFA_NodeArray items;
+ pDataNode->GetNodeList(items);
+ FX_INT32 iCounts = items.GetSize();
+ if (iCounts > 0) {
+ wsNormailizeValue.Empty();
+ CFX_WideString wsItem;
+ for (FX_INT32 i = 0; i < iCounts; i++) {
+ items[i]->TryContent(wsItem);
+ wsItem = (iCounts == 1) ? wsItem : wsItem + FX_WSTRC(L"\n");
+ wsNormailizeValue += wsItem;
+ }
+ CXFA_ExData exData = defValue.GetExData();
+ FXSYS_assert(exData != NULL);
+ exData.SetContentType((iCounts == 1) ? FX_WSTRC(L"text/plain") : FX_WSTRC(L"text/xml"));
+ }
+ XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_ExData);
+ } else {
+ XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);
+ }
+ break;
+ case XFA_ELEMENT_CheckButton:
+ XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);
+ break;
+ case XFA_ELEMENT_ExclGroup: {
+ pWidgetData->SetSelectedMemberByValue(wsNormailizeValue, bNotify, FALSE, FALSE);
+ }
+ break;
+ case XFA_ELEMENT_DateTimeEdit:
+ XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_DateTime);
+ break;
+ case XFA_ELEMENT_NumericEdit: {
+ CFX_WideString wsPicture;
+ pWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+ if(wsPicture.IsEmpty()) {
+ CFX_WideString wsOutput;
+ pWidgetData->NormalizeNumStr(wsNormailizeValue, wsOutput);
+ wsNormailizeValue = wsOutput;
+ }
+ XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Float);
+ }
+ break;
+ case XFA_ELEMENT_Barcode:
+ case XFA_ELEMENT_Button:
+ case XFA_ELEMENT_PasswordEdit:
+ case XFA_ELEMENT_Signature:
+ case XFA_ELEMENT_TextEdit:
+ default:
+ XFA_DataMerge_FormValueNode_SetChildContent(defValue.GetNode(), wsNormailizeValue, XFA_ELEMENT_Text);
+ break;
+ }
+ }
+}
+static CXFA_Node* XFA_DataMerge_GetGlobalBinding(CXFA_Document* pDocument, FX_DWORD dwNameHash)
+{
+ CXFA_Node* pNode = NULL;
+ pDocument->m_rgGlobalBinding.Lookup(dwNameHash, pNode);
+ return pNode;
+}
+static void XFA_DataMerge_RegisterGlobalBinding(CXFA_Document* pDocument, FX_DWORD dwNameHash, CXFA_Node* pDataNode)
+{
+ pDocument->m_rgGlobalBinding.SetAt(dwNameHash, pDataNode);
+}
+static void XFA_DataMerge_ClearGlobalBinding(CXFA_Document* pDocument)
+{
+ pDocument->m_rgGlobalBinding.RemoveAll();
+}
+static CXFA_Node* XFA_DataMerge_ScopeMatchGlobalBinding(CXFA_Node* pDataScope, FX_DWORD dwNameHash, XFA_ELEMENT eMatchDataNodeType, FX_BOOL bUpLevel = TRUE)
+{
+ for(CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = NULL;
+ pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
+ pLastDataScope = pCurDataScope, pCurDataScope = pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
+ for(CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash); pDataChild; pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
+ if(pDataChild == pLastDataScope || (eMatchDataNodeType != XFA_ELEMENT_DataModel && pDataChild->GetClassID() != eMatchDataNodeType) || pDataChild->HasBindItem()) {
+ continue;
+ }
+ return pDataChild;
+ }
+ for(CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByClass(XFA_ELEMENT_DataGroup); pDataChild; pDataChild = pDataChild->GetNextSameClassSibling(XFA_ELEMENT_DataGroup)) {
+ CXFA_Node* pDataNode = XFA_DataMerge_ScopeMatchGlobalBinding(pDataChild, dwNameHash, eMatchDataNodeType, FALSE);
+ if(pDataNode) {
+ return pDataNode;
+ }
+ }
+ if(!bUpLevel) {
+ break;
+ }
+ }
+ return NULL;
+}
+static CXFA_Node* XFA_DataMerge_FindGlobalDataNode(CXFA_Document* pDocument, CFX_WideStringC wsName, CXFA_Node* pDataScope, XFA_ELEMENT eMatchNodeType)
+{
+ FX_DWORD dwNameHash = wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+ if (dwNameHash != 0) {
+ CXFA_Node *pBounded = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);
+ if(!pBounded) {
+ pBounded = XFA_DataMerge_ScopeMatchGlobalBinding(pDataScope, dwNameHash, eMatchNodeType);
+ if(pBounded) {
+ XFA_DataMerge_RegisterGlobalBinding(pDocument, dwNameHash, pBounded);
+ }
+ }
+ return pBounded;
+ }
+ return NULL;
+}
+static CXFA_Node* XFA_DataMerge_FindOnceDataNode(CXFA_Document* pDocument, CFX_WideStringC wsName, CXFA_Node* pDataScope, XFA_ELEMENT eMatchNodeType)
+{
+ FX_DWORD dwNameHash = wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+ if (dwNameHash != 0) {
+ for(CXFA_Node *pCurDataScope = pDataScope, *pLastDataScope = NULL;
+ pCurDataScope && pCurDataScope->GetPacketID() == XFA_XDPPACKET_Datasets;
+ pLastDataScope = pCurDataScope, pCurDataScope = pCurDataScope->GetNodeItem(XFA_NODEITEM_Parent)) {
+ for(CXFA_Node* pDataChild = pCurDataScope->GetFirstChildByName(dwNameHash); pDataChild; pDataChild = pDataChild->GetNextSameNameSibling(dwNameHash)) {
+ if(pDataChild == pLastDataScope || (eMatchNodeType != XFA_ELEMENT_DataModel && pDataChild->GetClassID() != eMatchNodeType) || pDataChild->HasBindItem()) {
+ continue;
+ }
+ return pDataChild;
+ }
+ }
+ }
+ return NULL;
+}
+static CXFA_Node* XFA_DataMerge_FindDataRefDataNode(CXFA_Document* pDocument, CFX_WideStringC wsRef, CXFA_Node* pDataScope, XFA_ELEMENT eMatchNodeType, CXFA_Node* pTemplateNode, FX_BOOL bForceBind, FX_BOOL bUpLevel = TRUE)
+{
+ FX_DWORD dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_BindNew;
+ if (bUpLevel || wsRef != FX_WSTRC(L"name")) {
+ dFlags |= (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
+ }
+ XFA_RESOLVENODE_RS rs;
+ pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags, pTemplateNode);
+ if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeAll || rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll || rs.nodes.GetSize() > 1) {
+ return pDocument->GetNotBindNode(rs.nodes);
+ } else if (rs.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
+ CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;
+ CXFA_Node *pNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;
+ if (!bForceBind && (pNode != NULL) && pNode->HasBindItem()) {
+ pNode = NULL;
+ }
+ return pNode;
+ }
+ return NULL;
+}
+CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument, XFA_ELEMENT eClassID, FX_DWORD dwNameHash, CXFA_Node* pFormParent)
+{
+ CXFA_Node* pFormChild = pFormParent->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for(; pFormChild; pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pFormChild->GetClassID() == eClassID && pFormChild->GetNameHash() == dwNameHash && pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+ return pFormChild;
+ }
+ }
+ return NULL;
+}
+static FX_BOOL XFA_NeedGenerateForm(CXFA_Node* pTemplateChild, FX_BOOL bUseInstanceManager = TRUE)
+{
+ XFA_ELEMENT eType = pTemplateChild->GetClassID();
+ if (eType == XFA_ELEMENT_Variables) {
+ return TRUE;
+ }
+ if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ return FALSE;
+ }
+ if (eType == XFA_ELEMENT_Proto || (bUseInstanceManager && eType == XFA_ELEMENT_Occur)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document* pDocument, CXFA_Node* pFormParent, CXFA_Node* pTemplateNode, FX_BOOL bRecursive, CXFA_NodeArray* pSubformArray)
+{
+ CXFA_Node* pExistingNode = NULL;
+ if (pSubformArray == NULL) {
+ pExistingNode = XFA_DataMerge_FindFormDOMInstance(pDocument, pTemplateNode->GetClassID(), pTemplateNode->GetNameHash(), pFormParent);
+ } else if (pSubformArray->GetSize() > 0) {
+ pExistingNode = pSubformArray->GetAt(0);
+ pSubformArray->RemoveAt(0);
+ }
+ if(pExistingNode) {
+ if (pSubformArray) {
+ pFormParent->InsertChild(pExistingNode);
+ } else if (pExistingNode->IsContainerNode()) {
+ pFormParent->RemoveChild(pExistingNode);
+ pFormParent->InsertChild(pExistingNode);
+ }
+ pExistingNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ pExistingNode->SetTemplateNode(pTemplateNode);
+ if(bRecursive && pExistingNode->GetClassID() != XFA_ELEMENT_Items) {
+ for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(XFA_NeedGenerateForm(pTemplateChild)) {
+ XFA_NodeMerge_CloneOrMergeContainer(pDocument, pExistingNode, pTemplateChild, bRecursive);
+ }
+ }
+ }
+ pExistingNode->SetFlag(XFA_NODEFLAG_Initialized);
+ return pExistingNode;
+ }
+ CXFA_Node* pNewNode = pTemplateNode->CloneTemplateToForm(FALSE);
+ pFormParent->InsertChild(pNewNode, NULL);
+ if(bRecursive) {
+ for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(XFA_NeedGenerateForm(pTemplateChild)) {
+ CXFA_Node* pNewChild = pTemplateChild->CloneTemplateToForm(TRUE);
+ pNewNode->InsertChild(pNewChild, NULL);
+ }
+ }
+ }
+ return pNewNode;
+}
+static CXFA_Node* XFA_NodeMerge_CloneOrMergeInstanceManager(CXFA_Document* pDocument, CXFA_Node* pFormParent, CXFA_Node* pTemplateNode, CXFA_NodeArray& subforms)
+{
+ CFX_WideStringC wsSubformName = pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
+ CFX_WideString wsInstMgrNodeName = FX_WSTRC(L"_") + wsSubformName;
+ FX_DWORD dwInstNameHash = FX_HashCode_String_GetW(wsInstMgrNodeName, wsInstMgrNodeName.GetLength());
+ CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(pDocument, XFA_ELEMENT_InstanceManager, dwInstNameHash, pFormParent);
+ if(pExistingNode) {
+ FX_DWORD dwNameHash = pTemplateNode->GetNameHash();
+ for(CXFA_Node* pNode = pExistingNode->GetNodeItem(XFA_NODEITEM_NextSibling); pNode; ) {
+ XFA_ELEMENT eCurType = pNode->GetClassID();
+ if (eCurType == XFA_ELEMENT_InstanceManager) {
+ break;
+ }
+ if ((eCurType != XFA_ELEMENT_Subform) && (eCurType != XFA_ELEMENT_SubformSet)) {
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ continue;
+ }
+ if (dwNameHash != pNode->GetNameHash()) {
+ break;
+ }
+ CXFA_Node* pNextNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pFormParent->RemoveChild(pNode);
+ subforms.Add(pNode);
+ pNode = pNextNode;
+ }
+ pFormParent->RemoveChild(pExistingNode);
+ pFormParent->InsertChild(pExistingNode);
+ pExistingNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ pExistingNode->SetTemplateNode(pTemplateNode);
+ return pExistingNode;
+ }
+ CXFA_Node* pNewNode = pDocument->GetParser()->GetFactory()->CreateNode(XFA_XDPPACKET_Form, XFA_ELEMENT_InstanceManager);
+ FXSYS_assert(pNewNode);
+ wsInstMgrNodeName = FX_WSTRC(L"_") + pTemplateNode->GetCData(XFA_ATTRIBUTE_Name);
+ pNewNode->SetCData(XFA_ATTRIBUTE_Name, wsInstMgrNodeName);
+ pFormParent->InsertChild(pNewNode, NULL);
+ pNewNode->SetTemplateNode(pTemplateNode);
+ return pNewNode;
+}
+static CXFA_Node* XFA_DataMerge_FindMatchingDataNode(CXFA_Document* pDocument, CXFA_Node* pTemplateNode, CXFA_Node* pDataScope, FX_BOOL& bAccessedDataDOM, FX_BOOL bForceBind, CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>* pIterator, FX_BOOL& bSelfMatch, XFA_ATTRIBUTEENUM& eBindMatch, FX_BOOL bUpLevel = TRUE)
+{
+ FX_BOOL bOwnIterator = FALSE;
+ if(!pIterator) {
+ bOwnIterator = TRUE;
+ pIterator = FX_NEW CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode>(pTemplateNode);
+ }
+ CXFA_Node* pResult = NULL;
+ for(CXFA_Node* pCurTemplateNode = pIterator->GetCurrent(); pCurTemplateNode; ) {
+ XFA_ELEMENT eMatchNodeType;
+ switch(pCurTemplateNode->GetClassID()) {
+ case XFA_ELEMENT_Subform:
+ eMatchNodeType = XFA_ELEMENT_DataGroup;
+ break;
+ case XFA_ELEMENT_Field: {
+ eMatchNodeType = XFA_FieldIsMultiListBox(pCurTemplateNode) ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;
+ }
+ break;
+ case XFA_ELEMENT_ExclGroup:
+ eMatchNodeType = XFA_ELEMENT_DataValue;
+ break;
+ default:
+ pCurTemplateNode = pIterator->MoveToNext();
+ continue;
+ }
+ CXFA_Node* pTemplateNodeOccur = pCurTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ FX_INT32 iMin, iMax, iInit;
+ if(pTemplateNodeOccur && XFA_GetOccurInfo(pTemplateNodeOccur, iMin, iMax, iInit) && iMax == 0) {
+ pCurTemplateNode = pIterator->MoveToNext();
+ continue;
+ }
+ CXFA_Node* pTemplateNodeBind = pCurTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind);
+ XFA_ATTRIBUTEENUM eMatch = pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) : XFA_ATTRIBUTEENUM_Once;
+ eBindMatch = eMatch;
+ switch(eMatch) {
+ case XFA_ATTRIBUTEENUM_None:
+ pCurTemplateNode = pIterator->MoveToNext();
+ continue;
+ case XFA_ATTRIBUTEENUM_Global:
+ bAccessedDataDOM = TRUE;
+ if(!bForceBind) {
+ pCurTemplateNode = pIterator->MoveToNext();
+ continue;
+ }
+ if (eMatchNodeType == XFA_ELEMENT_DataValue || (eMatchNodeType == XFA_ELEMENT_DataGroup && XFA_FieldIsMultiListBox(pTemplateNodeBind))) {
+ CXFA_Node* pGlobalBindNode = XFA_DataMerge_FindGlobalDataNode(pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name), pDataScope, eMatchNodeType);
+ if(!pGlobalBindNode) {
+ pCurTemplateNode = pIterator->MoveToNext();
+ continue;
+ }
+ pResult = pGlobalBindNode;
+ break;
+ }
+ case XFA_ATTRIBUTEENUM_Once: {
+ bAccessedDataDOM = TRUE;
+ CXFA_Node* pOnceBindNode = XFA_DataMerge_FindOnceDataNode(pDocument, pCurTemplateNode->GetCData(XFA_ATTRIBUTE_Name), pDataScope, eMatchNodeType);
+ if(!pOnceBindNode) {
+ pCurTemplateNode = pIterator->MoveToNext();
+ continue;
+ }
+ pResult = pOnceBindNode;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_DataRef: {
+ bAccessedDataDOM = TRUE;
+ CXFA_Node* pDataRefBindNode = XFA_DataMerge_FindDataRefDataNode(pDocument, pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref), pDataScope, eMatchNodeType, pTemplateNode, bForceBind, bUpLevel);
+ if(pDataRefBindNode && pDataRefBindNode->GetClassID() == eMatchNodeType) {
+ pResult = pDataRefBindNode;
+ }
+ if(!pResult) {
+ pCurTemplateNode = pIterator->SkipChildrenAndMoveToNext();
+ continue;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if(pCurTemplateNode == pTemplateNode && pResult != NULL) {
+ bSelfMatch = TRUE;
+ }
+ break;
+ }
+ if(bOwnIterator) {
+ delete pIterator;
+ }
+ return pResult;
+}
+static void XFA_DataMerge_SortRecurseRecord(CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord>& rgRecords, CXFA_Node* pDataScope, FX_BOOL bChoiceMode = FALSE)
+{
+ FX_INT32 iCount = rgRecords.GetSize();
+ CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord> rgResultRecord;
+ for (CXFA_Node* pChildNode = pDataScope->GetNodeItem(XFA_NODEITEM_FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ for(FX_INT32 i = 0; i < iCount; i ++) {
+ CXFA_Node* pNode = rgRecords[i].pDataChild;
+ if (pChildNode == pNode) {
+ XFA_DataMerge_RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, pNode};
+ rgResultRecord.Add(sNewRecord);
+ rgRecords.RemoveAt(i);
+ iCount--;
+ break;
+ }
+ }
+ if (bChoiceMode && rgResultRecord.GetSize() > 0) {
+ break;
+ }
+ }
+ if (rgResultRecord.GetSize() > 0) {
+ if (!bChoiceMode) {
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ XFA_DataMerge_RecurseRecord sNewRecord = {rgRecords[i].pTemplateChild, rgRecords[i].pDataChild};
+ rgResultRecord.Add(sNewRecord);
+ }
+ }
+ rgRecords.RemoveAll();
+ rgRecords.Copy(rgResultRecord);
+ }
+}
+static CXFA_Node* XFA_DataMerge_CopyContainer_SubformSet(CXFA_Document* pDocument, CXFA_Node* pTemplateNode, CXFA_Node* pFormParentNode, CXFA_Node* pDataScope, FX_BOOL bOneInstance, FX_BOOL bDataMerge)
+{
+ XFA_ELEMENT eElement = pTemplateNode->GetClassID();
+ CXFA_Node *pOccurNode = NULL;
+ CXFA_Node *pFirstInstance = NULL;
+ FX_BOOL bUseInstanceManager = pFormParentNode->GetClassID() != XFA_ELEMENT_Area;
+ CXFA_Node* pInstMgrNode = NULL;
+ CXFA_NodeArray subformArray;
+ CXFA_NodeArray* pSearchArray = NULL;
+ if (!bOneInstance && (eElement == XFA_ELEMENT_SubformSet || eElement == XFA_ELEMENT_Subform)) {
+ pInstMgrNode = bUseInstanceManager ? XFA_NodeMerge_CloneOrMergeInstanceManager(pDocument, pFormParentNode, pTemplateNode, subformArray) : NULL;
+ if(CXFA_Node* pOccurTemplateNode = pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Occur)) {
+ pOccurNode = pInstMgrNode != NULL ? XFA_NodeMerge_CloneOrMergeContainer(pDocument, pInstMgrNode, pOccurTemplateNode, FALSE) : pOccurTemplateNode;
+ } else if (pInstMgrNode) {
+ pOccurNode = pInstMgrNode->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ if (pOccurNode) {
+ pOccurNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ }
+ }
+ if (pInstMgrNode) {
+ pInstMgrNode->SetFlag(XFA_NODEFLAG_Initialized);
+ pSearchArray = &subformArray;
+ if (pFormParentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ bOneInstance = TRUE;
+ if (subformArray.GetSize() < 1) {
+ pSearchArray = NULL;
+ }
+ } else if ((pTemplateNode->GetNameHash() == 0) && (subformArray.GetSize() < 1)) {
+ pSearchArray = NULL;
+ }
+ }
+ }
+ FX_INT32 iMax = 1, iInit = 1, iMin = 1;
+ if(!bOneInstance) {
+ XFA_GetOccurInfo(pOccurNode, iMin, iMax, iInit);
+ }
+ XFA_ATTRIBUTEENUM eRelation = eElement == XFA_ELEMENT_SubformSet ? pTemplateNode->GetEnum(XFA_ATTRIBUTE_Relation) : XFA_ATTRIBUTEENUM_Ordered;
+ FX_INT32 iCurRepeatIndex = 0;
+ XFA_ATTRIBUTEENUM eParentBindMatch = XFA_ATTRIBUTEENUM_None;
+ if (bDataMerge) {
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sNodeIterator(pTemplateNode);
+ FX_BOOL bAccessedDataDOM = FALSE;
+ if (eElement == XFA_ELEMENT_SubformSet || eElement == XFA_ELEMENT_Area) {
+ sNodeIterator.MoveToNext();
+ } else {
+ CFX_MapPtrTemplate<CXFA_Node*, CXFA_Node*> subformMapArray;
+ CXFA_NodeArray subformArray;
+ for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
+ FX_BOOL bSelfMatch = FALSE;
+ XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
+ CXFA_Node* pDataNode = XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, FALSE, &sNodeIterator, bSelfMatch, eBindMatch);
+ if(!pDataNode || sNodeIterator.GetCurrent() != pTemplateNode) {
+ break;
+ }
+ eParentBindMatch = eBindMatch;
+ CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+ if(!pFirstInstance) {
+ pFirstInstance = pSubformNode;
+ }
+ XFA_DataMerge_CreateDataBinding(pSubformNode, pDataNode);
+ FXSYS_assert(pSubformNode);
+ subformMapArray.SetAt(pSubformNode, pDataNode);
+ subformArray.Add(pSubformNode);
+ }
+ FX_POSITION position = subformMapArray.GetStartPosition();
+ for(FX_INT32 iIndex = 0; iIndex < subformArray.GetSize(); iIndex ++) {
+ CXFA_Node* pSubform = subformArray[iIndex];
+ CXFA_Node* pDataNode = (CXFA_Node*)subformMapArray.GetValueAt(pSubform);
+ for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+ XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubform, pTemplateChild, TRUE);
+ } else if (pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ pDocument->DataMerge_CopyContainer(pTemplateChild, pSubform, pDataNode, FALSE, TRUE, FALSE);
+ }
+ }
+ }
+ subformMapArray.RemoveAll();
+ }
+ for (; iMax < 0 || iCurRepeatIndex < iMax; iCurRepeatIndex++) {
+ FX_BOOL bSelfMatch = FALSE;
+ CXFA_Node* pOldNode = sNodeIterator.GetCurrent();
+ XFA_ATTRIBUTEENUM eBindMatch = XFA_ATTRIBUTEENUM_None;
+ if(!XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, FALSE, &sNodeIterator, bSelfMatch, eBindMatch)) {
+ break;
+ }
+ if(eBindMatch == XFA_ATTRIBUTEENUM_DataRef && eParentBindMatch == XFA_ATTRIBUTEENUM_DataRef) {
+ break;
+ }
+ if (eRelation == XFA_ATTRIBUTEENUM_Choice || eRelation == XFA_ATTRIBUTEENUM_Unordered) {
+ CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+ FXSYS_assert(pSubformSetNode);
+ if(!pFirstInstance) {
+ pFirstInstance = pSubformSetNode;
+ }
+ CFX_ArrayTemplate<XFA_DataMerge_RecurseRecord> rgItemMatchList;
+ CFX_ArrayTemplate<CXFA_Node*> rgItemUnmatchList;
+ for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+ XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, pTemplateChild, TRUE);
+ } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ CXFA_Node *pDataMatch;
+ bSelfMatch = FALSE;
+ eBindMatch = XFA_ATTRIBUTEENUM_None;
+ if(eRelation != XFA_ATTRIBUTEENUM_Ordered && (pDataMatch = XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateChild, pDataScope, bAccessedDataDOM, FALSE, NULL, bSelfMatch, eBindMatch))) {
+ XFA_DataMerge_RecurseRecord sNewRecord = {pTemplateChild, pDataMatch};
+ if(bSelfMatch) {
+ rgItemMatchList.InsertAt(0, sNewRecord);
+ } else {
+ rgItemMatchList.Add(sNewRecord);
+ }
+ } else {
+ rgItemUnmatchList.Add(pTemplateChild);
+ }
+ }
+ }
+ switch(eRelation) {
+ case XFA_ATTRIBUTEENUM_Choice: {
+ FXSYS_assert(rgItemMatchList.GetSize());
+ XFA_DataMerge_SortRecurseRecord(rgItemMatchList, pDataScope, TRUE);
+ pDocument->DataMerge_CopyContainer(rgItemMatchList[0].pTemplateChild, pSubformSetNode, pDataScope);
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Unordered: {
+ if(rgItemMatchList.GetSize()) {
+ XFA_DataMerge_SortRecurseRecord(rgItemMatchList, pDataScope);
+ for(FX_INT32 i = 0, count = rgItemMatchList.GetSize(); i < count; i ++) {
+ pDocument->DataMerge_CopyContainer(rgItemMatchList[i].pTemplateChild, pSubformSetNode, pDataScope);
+ }
+ }
+ for(FX_INT32 i = 0, count = rgItemUnmatchList.GetSize(); i < count; i ++) {
+ pDocument->DataMerge_CopyContainer(rgItemUnmatchList[i], pSubformSetNode, pDataScope);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ } else {
+ CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+ FXSYS_assert(pSubformSetNode);
+ if(!pFirstInstance) {
+ pFirstInstance = pSubformSetNode;
+ }
+ for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+ XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, pTemplateChild, TRUE);
+ } else if (pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataScope);
+ }
+ }
+ }
+ }
+ if(iCurRepeatIndex == 0 && bAccessedDataDOM == FALSE) {
+ FX_INT32 iLimit = iMax;
+ if (pInstMgrNode && pTemplateNode->GetNameHash() == 0) {
+ iLimit = subformArray.GetSize();
+ if (iLimit < iMin) {
+ iLimit = iInit;
+ }
+ }
+ for (; (iLimit < 0 || iCurRepeatIndex < iLimit); iCurRepeatIndex++) {
+ if (pInstMgrNode) {
+ if (pSearchArray && pSearchArray->GetSize() < 1) {
+ if (pTemplateNode->GetNameHash() != 0) {
+ break;
+ }
+ pSearchArray = NULL;
+ }
+ } else if(!XFA_DataMerge_FindFormDOMInstance(pDocument, pTemplateNode->GetClassID(), pTemplateNode->GetNameHash(), pFormParentNode)) {
+ break;
+ }
+ CXFA_Node* pSubformNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+ FXSYS_assert(pSubformNode);
+ if(!pFirstInstance) {
+ pFirstInstance = pSubformNode;
+ }
+ for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+ XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformNode, pTemplateChild, TRUE);
+ } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformNode, pDataScope);
+ }
+ }
+ }
+ }
+ }
+ FX_INT32 iMinimalLimit = iCurRepeatIndex == 0 ? iInit : iMin;
+ for (; iCurRepeatIndex < iMinimalLimit; iCurRepeatIndex++) {
+ CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormParentNode, pTemplateNode, FALSE, pSearchArray);
+ FXSYS_assert(pSubformSetNode);
+ if(!pFirstInstance) {
+ pFirstInstance = pSubformSetNode;
+ }
+ FX_BOOL bFound = FALSE;
+ for (CXFA_Node *pTemplateChild = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (XFA_NeedGenerateForm(pTemplateChild, bUseInstanceManager)) {
+ XFA_NodeMerge_CloneOrMergeContainer(pDocument, pSubformSetNode, pTemplateChild, TRUE);
+ } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ if(bFound && eRelation == XFA_ATTRIBUTEENUM_Choice) {
+ continue;
+ }
+ pDocument->DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataScope, FALSE, bDataMerge);
+ bFound = TRUE;
+ }
+ }
+ }
+ return pFirstInstance;
+}
+static CXFA_Node* XFA_DataMerge_CopyContainer_Field(CXFA_Document* pDocument, CXFA_Node* pTemplateNode, CXFA_Node* pFormNode, CXFA_Node* pDataScope, FX_BOOL bDataMerge, FX_BOOL bUpLevel = TRUE)
+{
+ CXFA_Node* pFieldNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFormNode, pTemplateNode, FALSE);
+ FXSYS_assert(pFieldNode);
+ for (CXFA_Node *pTemplateChildNode = pTemplateNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChildNode; pTemplateChildNode = pTemplateChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(XFA_NeedGenerateForm(pTemplateChildNode)) {
+ XFA_NodeMerge_CloneOrMergeContainer(pDocument, pFieldNode, pTemplateChildNode, TRUE);
+ } else if (pTemplateNode->GetClassID() == XFA_ELEMENT_ExclGroup && pTemplateChildNode->IsContainerNode()) {
+ if (pTemplateChildNode->GetClassID() == XFA_ELEMENT_Field) {
+ XFA_DataMerge_CopyContainer_Field(pDocument, pTemplateChildNode, pFieldNode, NULL, FALSE);
+ }
+ }
+ }
+ if(bDataMerge) {
+ FX_BOOL bAccessedDataDOM = FALSE;
+ FX_BOOL bSelfMatch = FALSE;
+ XFA_ATTRIBUTEENUM eBindMatch;
+ CXFA_Node* pDataNode = XFA_DataMerge_FindMatchingDataNode(pDocument, pTemplateNode, pDataScope, bAccessedDataDOM, TRUE, NULL, bSelfMatch, eBindMatch, bUpLevel);
+ if(pDataNode) {
+ XFA_DataMerge_CreateDataBinding(pFieldNode, pDataNode);
+ }
+ } else {
+ XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFieldNode);
+ }
+ return pFieldNode;
+}
+CXFA_Node* CXFA_Document::DataMerge_CopyContainer(CXFA_Node* pTemplateNode, CXFA_Node* pFormNode, CXFA_Node* pDataScope, FX_BOOL bOneInstance , FX_BOOL bDataMerge , FX_BOOL bUpLevel)
+{
+ switch(pTemplateNode->GetClassID()) {
+ case XFA_ELEMENT_SubformSet:
+ case XFA_ELEMENT_Subform:
+ case XFA_ELEMENT_Area:
+ case XFA_ELEMENT_PageArea:
+ return XFA_DataMerge_CopyContainer_SubformSet(this, pTemplateNode, pFormNode, pDataScope, bOneInstance, bDataMerge);
+ case XFA_ELEMENT_ExclGroup:
+ case XFA_ELEMENT_Field:
+ case XFA_ELEMENT_Draw:
+ case XFA_ELEMENT_ContentArea:
+ return XFA_DataMerge_CopyContainer_Field(this, pTemplateNode, pFormNode, pDataScope, bDataMerge, bUpLevel);
+ case XFA_ELEMENT_PageSet:
+ break;
+ case XFA_ELEMENT_Variables:
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ return NULL;
+}
+#define XFA_DATAMERGE_UPDATEBINDINGRELATIONS_DFS
+#ifdef XFA_DATAMERGE_UPDATEBINDINGRELATIONS_DFS
+static void XFA_DataMerge_UpdateBindingRelations(CXFA_Document* pDocument, CXFA_Node* pFormNode, CXFA_Node* pDataScope, FX_BOOL bDataRef, FX_BOOL bParentDataRef)
+{
+ FX_BOOL bMatchRef = TRUE;
+ XFA_ELEMENT eClassID = pFormNode->GetClassID();
+ CXFA_Node* pDataNode = pFormNode->GetBindData();
+ if(eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup || eClassID == XFA_ELEMENT_Field) {
+ CXFA_Node *pTemplateNode = pFormNode->GetTemplateNode();
+ CXFA_Node *pTemplateNodeBind = pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind) : NULL;
+ XFA_ATTRIBUTEENUM eMatch = pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) : XFA_ATTRIBUTEENUM_Once;
+ switch(eMatch) {
+ case XFA_ATTRIBUTEENUM_None:
+ if (!bDataRef || bParentDataRef) {
+ XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Once:
+ if (!bDataRef || bParentDataRef) {
+ if (!pDataNode) {
+ if (pFormNode->GetNameHash() != 0 && pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) != XFA_ATTRIBUTEENUM_None) {
+ XFA_ELEMENT eDataNodeType = (eClassID == XFA_ELEMENT_Subform || XFA_FieldIsMultiListBox(pFormNode)) ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;
+ pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pDataScope, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));
+ if(pDataNode) {
+ XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);
+ }
+ }
+ if (!pDataNode) {
+ XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+ }
+ } else {
+ CXFA_Node* pDataParent = pDataNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(pDataParent != pDataScope) {
+ FXSYS_assert(pDataParent);
+ pDataParent->RemoveChild(pDataNode);
+ pDataScope->InsertChild(pDataNode);
+ }
+ }
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Global:
+ if (!bDataRef || bParentDataRef) {
+ FX_DWORD dwNameHash = pFormNode->GetNameHash();
+ if (dwNameHash != 0 && !pDataNode) {
+ pDataNode = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);
+ if(!pDataNode) {
+ XFA_ELEMENT eDataNodeType = (eClassID == XFA_ELEMENT_Subform || XFA_FieldIsMultiListBox(pFormNode)) ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;
+ CXFA_Node* pRecordNode = (CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Record);
+ pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pRecordNode, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));
+ if(pDataNode) {
+ XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);
+ XFA_DataMerge_RegisterGlobalBinding(pDocument, pFormNode->GetNameHash(), pDataNode);
+ }
+ } else {
+ XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode);
+ }
+ }
+ if (!pDataNode) {
+ XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+ }
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_DataRef: {
+ bMatchRef = bDataRef;
+ bParentDataRef = TRUE;
+ if (!pDataNode && bDataRef) {
+ CFX_WideStringC wsRef = pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref);
+ FX_DWORD dFlags = XFA_RESOLVENODE_Children
+ | XFA_RESOLVENODE_CreateNode;
+ XFA_RESOLVENODE_RS rs;
+ pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags, pTemplateNode);
+ CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;
+ pDataNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;
+ if(pDataNode) {
+ XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, rs.dwFlags == XFA_RESOVENODE_RSTYPE_ExistNodes ? TRUE : FALSE);
+ } else {
+ XFA_DataMerge_FormValueNode_MatchNoneCreateChild(pFormNode);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if(bMatchRef && (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_SubformSet || eClassID == XFA_ELEMENT_Area || eClassID == XFA_ELEMENT_PageArea || eClassID == XFA_ELEMENT_PageSet)) {
+ for(CXFA_Node* pFormChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); pFormChild; pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pFormChild->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {
+ continue;
+ }
+ if(pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+ continue;
+ }
+ XFA_DataMerge_UpdateBindingRelations(pDocument, pFormChild, pDataNode ? pDataNode : pDataScope, bDataRef, bParentDataRef);
+ }
+ }
+}
+#else
+static void XFA_DataMerge_UpdateBindingRelations(CXFA_Document* pDocument, CXFA_Node* pFormNode, CXFA_Node* pDataScope, CFX_PtrList& rgFormNodeList, CFX_PtrList& rgDataScopeList, FX_BOOL bD _DEBUG
+#ifdef _DEBUG
+ CFX_WideString wsFormSOM; CFX_WideString wsDataScopeSOM;
+ pFormNode->GetSOMExpression(wsFormSOM); pDataScope->GetSOMExpression(wsDataScopeSOM);
+#endif
+ XFA_ELEMENT eClassID = pFormNode->GetClassID();
+ CXFA_Node* pDataNode = pFormNode->GetBindData();
+ if(eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup || eClassID == XFA_ELEMENT_Field)
+{
+CXFA_Node *pTemplateNode = pFormNode->GetTemplateNode();
+ CXFA_Node *pTemplateNodeBind = pTemplateNode ? pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Bind) : NULL;
+ XFA_ATTRIBUTEENUM eMatch = pTemplateNodeBind ? pTemplateNodeBind->GetEnum(XFA_ATTRIBUTE_Match) : XFA_ATTRIBUTEENUM_Once;
+ switch(eMatch) {
+ case XFA_ATTRIBUTEENUM_None:
+ break;
+ case XFA_ATTRIBUTEENUM_Once: {
+ if (!pDataNode) {
+ if (pFormNode->GetNameHash() != 0 && pFormNode->GetEnum(XFA_ATTRIBUTE_Scope) != XFA_ATTRIBUTEENUM_None) {
+ XFA_ELEMENT eDataNodeType = eClassID == XFA_ELEMENT_Subform ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;
+ pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pDataScope, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));
+ if(pDataNode) {
+ XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);
+ }
+ }
+ } else {
+ CXFA_Node* pDataParent = pDataNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(pDataParent != pDataScope) {
+ FXSYS_assert(pDataParent);
+ pDataParent->RemoveChild(pDataNode);
+ pDataScope->InsertChild(pDataNode);
+ }
+ }
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Global: {
+ FX_DWORD dwNameHash = pFormNode->GetNameHash();
+ if (dwNameHash != 0 && !pDataNode) {
+ pDataNode = XFA_DataMerge_GetGlobalBinding(pDocument, dwNameHash);
+ if(!pDataNode) {
+ XFA_ELEMENT eDataNodeType = eClassID == XFA_ELEMENT_Subform ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;
+ CXFA_Node* pRecordNode = (CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Record);
+ pDataNode = XFA_DataDescription_MaybeCreateDataNode(pDocument, pRecordNode, eDataNodeType, pFormNode->GetCData(XFA_ATTRIBUTE_Name));
+ }
+ if(pDataNode) {
+ XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);
+ XFA_DataMerge_RegisterGlobalBinding(pDocument, pFormNode->GetNameHash(), pDataNode);
+ }
+ }
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_DataRef: {
+ if (!pDataNode) {
+ CFX_WideStringC wsRef = pTemplateNodeBind->GetCData(XFA_ATTRIBUTE_Ref);
+ FX_DWORD dFlags = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent
+ | XFA_RESOLVENODE_CreateNode;
+ XFA_RESOLVENODE_RS rs;
+ pDocument->GetScriptContext()->ResolveObjects(pDataScope, wsRef, rs, dFlags, pTemplateNode);
+ CXFA_Object* pObject = (rs.nodes.GetSize() > 0) ? rs.nodes[0] : NULL;
+ pDataNode = (pObject && pObject->IsNode()) ? (CXFA_Node*)pObject : NULL;
+ if(pDataNode) {
+ XFA_DataMerge_CreateDataBinding(pFormNode, pDataNode, FALSE);
+ }
+ }
+ }
+ break;
+ }
+}
+if(eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup || eClassID == XFA_ELEMENT_SubformSet || eClassID == XFA_ELEMENT_Area || eClassID == XFA_ELEMENT_PageArea)
+{
+for(CXFA_Node* pFormChild = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); pFormChild; pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pFormChild->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {
+ continue;
+ }
+ if(pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+ continue;
+ }
+ rgFormNodeList.AddTail(pFormChild);
+ rgDataScopeList.AddTail(pDataNode ? pDataNode : pDataScope);
+ }
+}
+}
+#endif
+CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode)
+{
+ for(CXFA_Node* pRootBoundNode = pParentFormNode; pRootBoundNode && pRootBoundNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode; pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+ CXFA_Node* pDataScope = pRootBoundNode->GetBindData();
+ if(pDataScope) {
+ return pDataScope;
+ }
+ }
+ return (CXFA_Node*)pParentFormNode->GetDocument()->GetXFANode(XFA_HASHCODE_Data);
+}
+void CXFA_Document::DataMerge_UpdateBindingRelations(CXFA_Node* pFormUpdateRoot)
+{
+ CXFA_Node* pDataScope = XFA_DataMerge_FindDataScope(pFormUpdateRoot->GetNodeItem(XFA_NODEITEM_Parent));
+ if (!pDataScope) {
+ return;
+ }
+#ifdef XFA_DATAMERGE_UPDATEBINDINGRELATIONS_DFS
+ XFA_DataMerge_UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, FALSE, FALSE);
+ XFA_DataMerge_UpdateBindingRelations(this, pFormUpdateRoot, pDataScope, TRUE, FALSE);
+#else
+ CFX_PtrList rgFormNodeList, rgDataScopeList;
+ rgFormNodeList.AddTail(pFormUpdateRoot);
+ rgDataScopeList.AddTail(pDataScope);
+ while(rgFormNodeList.GetCount()) {
+ FX_POSITION pos;
+ pos = rgFormNodeList.GetHeadPosition();
+ CXFA_Node *pCurFormNode = (CXFA_Node*)rgFormNodeList.GetAt(pos);
+ rgFormNodeList.RemoveAt(pos);
+ pos = rgDataScopeList.GetHeadPosition();
+ CXFA_Node *pCurDataScope = (CXFA_Node*)rgDataScopeList.GetAt(pos);
+ rgDataScopeList.RemoveAt(pos);
+ XFA_DataMerge_UpdateBindingRelations(this, pCurFormNode, pCurDataScope, rgFormNodeList, rgDataScopeList);
+ }
+#endif
+}
+CXFA_Node * CXFA_Document::GetNotBindNode(CXFA_ObjArray& arrayNodes)
+{
+ for(FX_INT32 i = 0; i < arrayNodes.GetSize(); i++) {
+ CXFA_Object* pObject = arrayNodes[i];
+ if(!pObject->IsNode()) {
+ continue;
+ }
+ if (((CXFA_Node*)pObject)->HasBindItem()) {
+ continue;
+ }
+ return ((CXFA_Node*)pObject);
+ }
+ return NULL;
+}
+void CXFA_Document::DoDataMerge()
+{
+ CXFA_Node* pTemplateRoot = m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Template);
+ CXFA_Node* pDatasetsRoot = (CXFA_Node*)GetXFANode(XFA_HASHCODE_Datasets);
+ if(!pDatasetsRoot) {
+ IFDE_XMLElement* pDatasetsXMLNode = IFDE_XMLElement::Create(FX_WSTRC(L"xfa:datasets"));
+ FXSYS_assert(pDatasetsXMLNode);
+ pDatasetsXMLNode->SetString(FX_WSTRC(L"xmlns:xfa"), FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"));
+ pDatasetsRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataModel);
+ pDatasetsRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"datasets"));
+ m_pRootNode->GetXMLMappingNode()->InsertChildNode(pDatasetsXMLNode);
+ m_pRootNode->InsertChild(pDatasetsRoot);
+ pDatasetsRoot->SetXMLMappingNode(pDatasetsXMLNode);
+ }
+ CXFA_Node *pDataRoot = NULL, *pDDRoot = NULL;
+ CFX_WideString wsDatasetsURI;
+ pDatasetsRoot->TryNamespace(wsDatasetsURI);
+ for(CXFA_Node *pChildNode = pDatasetsRoot->GetNodeItem(XFA_NODEITEM_FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pChildNode->GetClassID() != XFA_ELEMENT_DataGroup) {
+ continue;
+ }
+ CFX_WideString wsNamespaceURI;
+ if(!pDDRoot && pChildNode->GetNameHash() == XFA_HASHCODE_DataDescription) {
+ if(!pChildNode->TryNamespace(wsNamespaceURI)) {
+ continue;
+ }
+ if(wsNamespaceURI == FX_WSTRC(L"http://ns.adobe.com/data-description/")) {
+ pDDRoot = pChildNode;
+ }
+ } else if(!pDataRoot && pChildNode->GetNameHash() == XFA_HASHCODE_Data) {
+ if(!pChildNode->TryNamespace(wsNamespaceURI)) {
+ continue;
+ }
+ if(wsNamespaceURI == wsDatasetsURI) {
+ pDataRoot = pChildNode;
+ }
+ }
+ if(pDataRoot && pDDRoot) {
+ break;
+ }
+ }
+ if(!pDataRoot) {
+ IFDE_XMLElement* pDataRootXMLNode = IFDE_XMLElement::Create(FX_WSTRC(L"xfa:data"));
+ FXSYS_assert(pDataRootXMLNode);
+ pDataRoot = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);
+ pDataRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"data"));
+ pDataRoot->SetXMLMappingNode(pDataRootXMLNode);
+ pDatasetsRoot->InsertChild(pDataRoot);
+ }
+ CXFA_Node* pDataTopLevel = pDataRoot->GetFirstChildByClass(XFA_ELEMENT_DataGroup);
+ FX_DWORD dwNameHash = pDataTopLevel ? pDataTopLevel->GetNameHash() : 0;
+ CXFA_Node* pTemplateChosen = dwNameHash != 0 ? pTemplateRoot->GetFirstChildByName(dwNameHash) : NULL;
+ if(!pTemplateChosen || pTemplateChosen->GetClassID() != XFA_ELEMENT_Subform) {
+ pTemplateChosen = pTemplateRoot->GetFirstChildByClass(XFA_ELEMENT_Subform);
+ }
+ if(!pTemplateChosen) {
+ return;
+ }
+ CXFA_Node* pFormRoot = m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Form);
+ FX_BOOL bEmptyForm = FALSE;
+ if(!pFormRoot) {
+ bEmptyForm = TRUE;
+ pFormRoot = CreateNode(XFA_XDPPACKET_Form, XFA_ELEMENT_Form);
+ FXSYS_assert(pFormRoot);
+ pFormRoot->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"form"));
+ m_pRootNode->InsertChild(pFormRoot, NULL);
+ } else {
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pFormRoot);
+ for(CXFA_Node *pNode = sIterator.MoveToNext(); pNode; pNode = sIterator.MoveToNext()) {
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+ }
+ }
+ CXFA_Node* pSubformSetNode = XFA_NodeMerge_CloneOrMergeContainer(this, pFormRoot, pTemplateChosen, FALSE);
+ FXSYS_assert(pSubformSetNode);
+ if (!pDataTopLevel) {
+ CFX_WideStringC wsFormName = pSubformSetNode->GetCData(XFA_ATTRIBUTE_Name);
+ CFX_WideString wsDataTopLevelName = wsFormName.IsEmpty() ? FX_WSTRC(L"form") : wsFormName;
+ IFDE_XMLElement* pDataTopLevelXMLNode = IFDE_XMLElement::Create(wsDataTopLevelName);
+ FXSYS_assert(pDataTopLevelXMLNode);
+ pDataTopLevel = CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);
+ pDataTopLevel->SetCData(XFA_ATTRIBUTE_Name, wsDataTopLevelName);
+ pDataTopLevel->SetXMLMappingNode(pDataTopLevelXMLNode);
+ CXFA_Node* pBeforeNode = pDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+ pDataRoot->InsertChild(pDataTopLevel, pBeforeNode);
+ }
+ FXSYS_assert(pDataTopLevel);
+ XFA_DataMerge_CreateDataBinding(pSubformSetNode, pDataTopLevel);
+ for (CXFA_Node *pTemplateChild = pTemplateChosen->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (XFA_NeedGenerateForm(pTemplateChild)) {
+ XFA_NodeMerge_CloneOrMergeContainer(this, pSubformSetNode, pTemplateChild, TRUE);
+ } else if(pTemplateChild->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ DataMerge_CopyContainer(pTemplateChild, pSubformSetNode, pDataTopLevel);
+ }
+ }
+ if(pDDRoot) {
+ XFA_DataDescription_UpdateDataRelation(pDataRoot, pDDRoot);
+ }
+ DataMerge_UpdateBindingRelations(pSubformSetNode);
+ CXFA_Node* pPageSetNode = pSubformSetNode->GetFirstChildByClass(XFA_ELEMENT_PageSet);
+ while (pPageSetNode) {
+ m_pPendingPageSet.Add(pPageSetNode);
+ CXFA_Node* pNextPageSetNode = pPageSetNode->GetNextSameClassSibling(XFA_ELEMENT_PageSet);
+ pSubformSetNode->RemoveChild(pPageSetNode);
+ pPageSetNode = pNextPageSetNode;
+ }
+ if(!bEmptyForm) {
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pFormRoot);
+ CXFA_Node *pNode = sIterator.MoveToNext();
+ while(pNode) {
+ if(pNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+ if(pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode || pNode->GetClassID() == XFA_ELEMENT_InstanceManager) {
+ CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
+ pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);
+ pNode = pNext;
+ } else {
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ pNode->SetFlag(XFA_NODEFLAG_Initialized);
+ pNode = sIterator.MoveToNext();
+ }
+ } else {
+ pNode->SetFlag(XFA_NODEFLAG_Initialized);
+ pNode = sIterator.MoveToNext();
+ }
+ }
+ }
+}
+void CXFA_Document::DoDataRemerge(FX_BOOL bDoDataMerge)
+{
+ CXFA_Node* pFormRoot = (CXFA_Node*)this->GetXFANode(XFA_HASHCODE_Form);
+ if(pFormRoot) {
+ while(CXFA_Node* pNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ pFormRoot->RemoveChild(pNode);
+ }
+ pFormRoot->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+ }
+ XFA_DataMerge_ClearGlobalBinding(this);
+ if (bDoDataMerge) {
+ DoDataMerge();
+ }
+ CXFA_LayoutProcessor* pLayoutProcessor = GetLayoutProcessor();
+ pLayoutProcessor->SetForceReLayout(TRUE);
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.h b/xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.h
new file mode 100644
index 0000000000..9b7bc5a408
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_datamerger_imp.h
@@ -0,0 +1,12 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCUMENT_DATAMERGER_IMP_H_
+#define _XFA_DOCUMENT_DATAMERGER_IMP_H_
+CXFA_Node* XFA_NodeMerge_CloneOrMergeContainer(CXFA_Document* pDocument, CXFA_Node* pFormParent, CXFA_Node* pTemplateNode, FX_BOOL bRecursive, CXFA_NodeArray* pSubformArray = NULL);
+CXFA_Node* XFA_DataMerge_FindDataScope(CXFA_Node* pParentFormNode);
+CXFA_Node* XFA_DataMerge_FindFormDOMInstance(CXFA_Document* pDocument, XFA_ELEMENT eClassID, FX_DWORD dwNameHash, CXFA_Node* pFormParent);
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_document_imp.cpp b/xfa/src/fxfa/src/parser/xfa_document_imp.cpp
new file mode 100644
index 0000000000..ad1ff99253
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_imp.cpp
@@ -0,0 +1,418 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_basic_imp.h"
+#include "xfa_document_layout_imp.h"
+#include "xfa_script_datawindow.h"
+#include "xfa_script_eventpseudomodel.h"
+#include "xfa_script_hostpseudomodel.h"
+#include "xfa_script_logpseudomodel.h"
+#include "xfa_script_layoutpseudomodel.h"
+#include "xfa_script_signaturepseudomodel.h"
+CXFA_Document::CXFA_Document(IXFA_DocParser *pParser)
+ : m_pParser(pParser)
+ , m_pLayoutProcessor(NULL)
+ , m_pRootNode(NULL)
+ , m_pScriptContext(NULL)
+ , m_pLocalMgr(NULL)
+ , m_pScriptDataWindow(NULL)
+ , m_pScriptEvent(NULL)
+ , m_pScriptHost(NULL)
+ , m_pScriptLog(NULL)
+ , m_pScriptLayout(NULL)
+ , m_pScriptSignature(NULL)
+ , m_dwDocFlags(0)
+ , m_eCurVersionMode(XFA_VERSION_DEFAULT)
+{
+ ASSERT(m_pParser);
+}
+CXFA_Document::~CXFA_Document()
+{
+ if (m_pRootNode) {
+ delete m_pRootNode;
+ }
+ PurgeNodes();
+}
+void CXFA_Document::ClearLayoutData()
+{
+ if(m_pLayoutProcessor) {
+ delete m_pLayoutProcessor;
+ m_pLayoutProcessor = NULL;
+ }
+ if (m_pScriptContext) {
+ m_pScriptContext->Release();
+ m_pScriptContext = NULL;
+ }
+ if (m_pLocalMgr) {
+ delete m_pLocalMgr;
+ m_pLocalMgr = NULL;
+ }
+ if(m_pScriptDataWindow) {
+ delete m_pScriptDataWindow;
+ m_pScriptDataWindow = NULL;
+ }
+ if(m_pScriptEvent) {
+ delete m_pScriptEvent;
+ m_pScriptEvent = NULL;
+ }
+ if (m_pScriptHost) {
+ delete m_pScriptHost;
+ m_pScriptHost = NULL;
+ }
+ if (m_pScriptLog) {
+ delete m_pScriptLog;
+ m_pScriptLog = NULL;
+ }
+ if(m_pScriptLayout) {
+ delete m_pScriptLayout;
+ m_pScriptLayout = NULL;
+ }
+ if(m_pScriptSignature) {
+ delete m_pScriptSignature;
+ m_pScriptSignature = NULL;
+ }
+}
+void CXFA_Document::SetRoot(CXFA_Node* pNewRoot)
+{
+ if(m_pRootNode) {
+ AddPurgeNode(m_pRootNode);
+ }
+ m_pRootNode = pNewRoot;
+ RemovePurgeNode(pNewRoot);
+}
+IXFA_Notify* CXFA_Document::GetNotify() const
+{
+ return m_pParser->GetNotify();
+}
+CXFA_Object* CXFA_Document::GetXFANode(FX_WSTR wsNodeName)
+{
+ return GetXFANode(FX_HashCode_String_GetW(wsNodeName.GetPtr(), wsNodeName.GetLength()));
+}
+CXFA_Object* CXFA_Document::GetXFANode(FX_DWORD dwNodeNameHash)
+{
+ switch(dwNodeNameHash) {
+ case XFA_HASHCODE_Data: {
+ CXFA_Node* pDatasetsNode = (CXFA_Node*)GetXFANode(XFA_HASHCODE_Datasets);
+ if(!pDatasetsNode) {
+ return NULL;
+ }
+ for (CXFA_Node* pDatasetsChild = pDatasetsNode->GetFirstChildByClass(XFA_ELEMENT_DataGroup); pDatasetsChild; pDatasetsChild = pDatasetsChild->GetNextSameClassSibling(XFA_ELEMENT_DataGroup)) {
+ if(pDatasetsChild->GetNameHash() != XFA_HASHCODE_Data) {
+ continue;
+ }
+ CFX_WideString wsNamespaceURI;
+ if(!pDatasetsChild->TryNamespace(wsNamespaceURI)) {
+ continue;
+ }
+ CFX_WideString wsDatasetsURI;
+ if(!pDatasetsNode->TryNamespace(wsDatasetsURI)) {
+ continue;
+ }
+ if(wsNamespaceURI == wsDatasetsURI) {
+ return pDatasetsChild;
+ }
+ }
+ }
+ return NULL;
+ case XFA_HASHCODE_Record: {
+ CXFA_Node* pData = (CXFA_Node*)GetXFANode(XFA_HASHCODE_Data);
+ return pData ? pData->GetFirstChildByClass(XFA_ELEMENT_DataGroup) : NULL;
+ }
+ case XFA_HASHCODE_DataWindow: {
+ if(m_pScriptDataWindow == NULL) {
+ m_pScriptDataWindow = FX_NEW CScript_DataWindow(this);
+ }
+ return m_pScriptDataWindow;
+ }
+ case XFA_HASHCODE_Event: {
+ if(m_pScriptEvent == NULL) {
+ m_pScriptEvent = FX_NEW CScript_EventPseudoModel(this);
+ }
+ return m_pScriptEvent;
+ }
+ case XFA_HASHCODE_Host: {
+ if(m_pScriptHost == NULL) {
+ m_pScriptHost = FX_NEW CScript_HostPseudoModel(this);
+ }
+ return m_pScriptHost;
+ }
+ case XFA_HASHCODE_Log: {
+ if (m_pScriptLog == NULL) {
+ m_pScriptLog = FX_NEW CScript_LogPseudoModel(this);
+ }
+ return m_pScriptLog;
+ }
+ case XFA_HASHCODE_Signature: {
+ if(m_pScriptSignature == NULL) {
+ m_pScriptSignature = FX_NEW CScript_SignaturePseudoModel(this);
+ }
+ return m_pScriptSignature;
+ }
+ case XFA_HASHCODE_Layout: {
+ if(m_pScriptLayout == NULL) {
+ m_pScriptLayout = FX_NEW CScript_LayoutPseudoModel(this);
+ }
+ return m_pScriptLayout;
+ }
+ default:
+ return m_pRootNode->GetFirstChildByName(dwNodeNameHash);
+ }
+}
+CXFA_Node* CXFA_Document::CreateNode(FX_DWORD dwPacket, XFA_ELEMENT eElement)
+{
+ XFA_LPCPACKETINFO pPacket = XFA_GetPacketByID(dwPacket);
+ return CreateNode(pPacket, eElement);
+}
+CXFA_Node* CXFA_Document::CreateNode(XFA_LPCPACKETINFO pPacket, XFA_ELEMENT eElement)
+{
+ if (pPacket == NULL) {
+ return NULL;
+ }
+ XFA_LPCELEMENTINFO pElement = XFA_GetElementByID(eElement);
+ if (pElement && (pElement->dwPackets & pPacket->eName)) {
+ CXFA_Node* pNode = FX_NEW CXFA_Node(this, pPacket->eName, pElement->eName);
+ if(pNode) {
+ AddPurgeNode(pNode);
+ }
+ return pNode;
+ }
+ return NULL;
+}
+void CXFA_Document::AddPurgeNode(CXFA_Node *pNode)
+{
+ m_rgPurgeNodes.Add(pNode);
+}
+FX_BOOL CXFA_Document::RemovePurgeNode(CXFA_Node *pNode)
+{
+ return m_rgPurgeNodes.RemoveKey(pNode);
+}
+void CXFA_Document::PurgeNodes()
+{
+ FX_POSITION psNode = m_rgPurgeNodes.GetStartPosition();
+ while(psNode) {
+ CXFA_Node* pNode;
+ m_rgPurgeNodes.GetNextAssoc(psNode, pNode);
+ delete pNode;
+ }
+ m_rgPurgeNodes.RemoveAll();
+}
+void CXFA_Document::SetFlag(FX_DWORD dwFlag, FX_BOOL bOn )
+{
+ if (bOn) {
+ m_dwDocFlags |= dwFlag;
+ } else {
+ m_dwDocFlags &= ~dwFlag;
+ }
+}
+FX_BOOL CXFA_Document::IsInteractive()
+{
+ if (m_dwDocFlags & XFA_DOCFLAG_HasInteractive) {
+ return m_dwDocFlags & XFA_DOCFLAG_Interactive;
+ }
+ CXFA_Node* pConfig = (CXFA_Node*)this->GetXFANode(XFA_HASHCODE_Config);
+ if (!pConfig) {
+ return FALSE;
+ }
+ CFX_WideString wsInteractive;
+ CXFA_Node* pPresent = pConfig->GetFirstChildByClass(XFA_ELEMENT_Present);
+ if (!pPresent) {
+ return FALSE;
+ }
+ CXFA_Node* pPDF = pPresent->GetFirstChildByClass(XFA_ELEMENT_Pdf);
+ if (!pPDF) {
+ return FALSE;
+ }
+ CXFA_Node* pInteractive = pPDF->GetChild(0, XFA_ELEMENT_Interactive);
+ if (pInteractive) {
+ m_dwDocFlags |= XFA_DOCFLAG_HasInteractive;
+ if (pInteractive->TryContent(wsInteractive) && wsInteractive == FX_WSTRC(L"1")) {
+ m_dwDocFlags |= XFA_DOCFLAG_Interactive;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+CXFA_LocaleMgr* CXFA_Document::GetLocalMgr()
+{
+ if (!m_pLocalMgr) {
+ CFX_WideString wsLanguage;
+ this->GetParser()->GetNotify()->GetAppProvider()->GetLanguage(wsLanguage);
+ m_pLocalMgr = FX_NEW CXFA_LocaleMgr((CXFA_Node*)this->GetXFANode(XFA_HASHCODE_LocaleSet), wsLanguage);
+ }
+ return m_pLocalMgr;
+}
+IXFA_ScriptContext* CXFA_Document::InitScriptContext(FXJSE_HRUNTIME hRuntime)
+{
+ if (!m_pScriptContext) {
+ m_pScriptContext = XFA_ScriptContext_Create(this);
+ }
+ m_pScriptContext->Initialize(hRuntime);
+ return m_pScriptContext;
+}
+IXFA_ScriptContext* CXFA_Document::GetScriptContext()
+{
+ if (!m_pScriptContext) {
+ m_pScriptContext = XFA_ScriptContext_Create(this);
+ }
+ return m_pScriptContext;
+}
+XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber(CFX_WideString& wsTemplateNS)
+{
+ CFX_WideStringC wsTemplateURIPrefix = XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI;
+ FX_STRSIZE nPrefixLength = wsTemplateURIPrefix.GetLength();
+ if(CFX_WideStringC(wsTemplateNS, wsTemplateNS.GetLength()) != wsTemplateURIPrefix) {
+ return XFA_VERSION_UNKNOWN;
+ }
+ FX_STRSIZE nDotPos = wsTemplateNS.Find('.', nPrefixLength);
+ if(nDotPos == (FX_STRSIZE)-1) {
+ return XFA_VERSION_UNKNOWN;
+ }
+ FX_INT8 iMajor = FXSYS_wtoi(wsTemplateNS.Mid(nPrefixLength, nDotPos - nPrefixLength));
+ FX_INT8 iMinor = FXSYS_wtoi(wsTemplateNS.Mid(nDotPos + 1, wsTemplateNS.GetLength() - nDotPos - 2));
+ XFA_VERSION eVersion = (XFA_VERSION)((FX_INT32)iMajor * 100 + iMinor);
+ if(eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX) {
+ return XFA_VERSION_UNKNOWN;
+ }
+ m_eCurVersionMode = eVersion;
+ return eVersion;
+}
+CXFA_Node* CXFA_Document::GetNodeByID(CXFA_Node* pRoot, FX_WSTR wsID)
+{
+ if(!pRoot || wsID.IsEmpty()) {
+ return NULL;
+ }
+ CXFA_NodeIterator sIterator(pRoot);
+ for(CXFA_Node* pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ CFX_WideStringC wsIDVal;
+ if(pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
+ if(wsIDVal == wsID) {
+ return pNode;
+ }
+ }
+ }
+ return NULL;
+}
+static void XFA_ProtoMerge_MergeNodeRecurse(CXFA_Document *pDocument, CXFA_Node *pDestNodeParent, CXFA_Node *pProtoNode)
+{
+ CXFA_Node* pExistingNode = NULL;
+ for(CXFA_Node* pFormChild = pDestNodeParent->GetNodeItem(XFA_NODEITEM_FirstChild); pFormChild; pFormChild = pFormChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pFormChild->GetClassID() == pProtoNode->GetClassID() && pFormChild->GetNameHash() == pProtoNode->GetNameHash() && pFormChild->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+ pFormChild->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ pExistingNode = pFormChild;
+ break;
+ }
+ }
+ if (pExistingNode) {
+ pExistingNode->SetTemplateNode(pProtoNode);
+ for (CXFA_Node *pTemplateChild = pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_ProtoMerge_MergeNodeRecurse(pDocument, pExistingNode, pTemplateChild);
+ }
+ return;
+ }
+ CXFA_Node* pNewNode = pProtoNode->Clone(TRUE);
+ pNewNode->SetTemplateNode(pProtoNode);
+ pDestNodeParent->InsertChild(pNewNode, NULL);
+}
+static void XFA_ProtoMerge_MergeNode(CXFA_Document *pDocument, CXFA_Node *pDestNode, CXFA_Node *pProtoNode)
+{
+ {
+ CXFA_NodeIterator sIterator(pDestNode);
+ for(CXFA_Node* pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+ }
+ }
+ pDestNode->SetTemplateNode(pProtoNode);
+ for (CXFA_Node *pTemplateChild = pProtoNode->GetNodeItem(XFA_NODEITEM_FirstChild); pTemplateChild; pTemplateChild = pTemplateChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_ProtoMerge_MergeNodeRecurse(pDocument, pDestNode, pTemplateChild);
+ }
+ {
+ CXFA_NodeIterator sIterator(pDestNode);
+ for(CXFA_Node* pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ }
+ }
+}
+void CXFA_Document::DoProtoMerge()
+{
+ CXFA_Node* pTemplateRoot = (CXFA_Node*)GetXFANode(XFA_HASHCODE_Template);
+ if(!pTemplateRoot) {
+ return;
+ }
+ CFX_MapPtrTemplate<FX_DWORD, CXFA_Node*> mIDMap;
+ CXFA_NodeSet sUseNodes;
+ CXFA_NodeIterator sIterator(pTemplateRoot);
+ for(CXFA_Node* pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ CFX_WideStringC wsIDVal;
+ if(pNode->TryCData(XFA_ATTRIBUTE_Id, wsIDVal) && !wsIDVal.IsEmpty()) {
+ mIDMap[FX_HashCode_String_GetW(wsIDVal.GetPtr(), wsIDVal.GetLength())] = pNode;
+ }
+ CFX_WideStringC wsUseVal;
+ if(pNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) {
+ sUseNodes.Add(pNode);
+ } else if (pNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && !wsUseVal.IsEmpty()) {
+ sUseNodes.Add(pNode);
+ }
+ }
+ FX_POSITION pos = sUseNodes.GetStartPosition();
+ while (pos) {
+ CXFA_Node* pUseHrefNode = NULL;
+ sUseNodes.GetNextAssoc(pos, pUseHrefNode);
+ CFX_WideString wsUseVal;
+ CFX_WideStringC wsURI, wsID, wsSOM;
+ if (pUseHrefNode->TryCData(XFA_ATTRIBUTE_Usehref, wsUseVal) && !wsUseVal.IsEmpty()) {
+ FX_STRSIZE uSharpPos = wsUseVal.Find('#');
+ if(uSharpPos < 0) {
+ wsURI = wsUseVal;
+ } else {
+ wsURI = CFX_WideStringC((FX_LPCWSTR)wsUseVal, uSharpPos);
+ FX_STRSIZE uLen = wsUseVal.GetLength();
+ if(uLen >= uSharpPos + 5 && CFX_WideStringC((FX_LPCWSTR)wsUseVal + uSharpPos, 5) == FX_WSTRC(L"#som(") && wsUseVal[uLen - 1] == ')') {
+ wsSOM = CFX_WideStringC((FX_LPCWSTR)wsUseVal + uSharpPos + 5, uLen - 1 - uSharpPos - 5);
+ } else {
+ wsID = CFX_WideStringC((FX_LPCWSTR)wsUseVal + uSharpPos + 1, uLen - uSharpPos - 1);
+ }
+ }
+ } else if(pUseHrefNode->TryCData(XFA_ATTRIBUTE_Use, wsUseVal) && !wsUseVal.IsEmpty()) {
+ if(wsUseVal[0] == '#') {
+ wsID = CFX_WideStringC((FX_LPCWSTR)wsUseVal + 1, wsUseVal.GetLength() - 1);
+ } else {
+ wsSOM = CFX_WideStringC((FX_LPCWSTR)wsUseVal, wsUseVal.GetLength());
+ }
+ }
+ if (!wsURI.IsEmpty() && wsURI != FX_WSTRC(L".")) {
+ continue;
+ }
+ CXFA_Node* pProtoNode = NULL;
+ if(!wsSOM.IsEmpty()) {
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = m_pScriptContext->ResolveObjects(pUseHrefNode, wsSOM, resoveNodeRS, dwFlag);
+ if(iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
+ pProtoNode = (CXFA_Node*)resoveNodeRS.nodes[0];
+ }
+ } else if(!wsID.IsEmpty()) {
+ if(!mIDMap.Lookup(FX_HashCode_String_GetW(wsID.GetPtr(), wsID.GetLength()), pProtoNode)) {
+ continue;
+ }
+ }
+ if(!pProtoNode) {
+ continue;
+ }
+ XFA_ProtoMerge_MergeNode(this, pUseHrefNode, pProtoNode);
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_document_imp.h b/xfa/src/fxfa/src/parser/xfa_document_imp.h
new file mode 100644
index 0000000000..53404c0d9e
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_imp.h
@@ -0,0 +1,9 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCUMENT_IMP_H_
+#define _XFA_DOCUMENT_IMP_H_
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_document_layout_imp.cpp b/xfa/src/fxfa/src/parser/xfa_document_layout_imp.cpp
new file mode 100644
index 0000000000..5ca9bb7a9b
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_layout_imp.cpp
@@ -0,0 +1,201 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_basic_imp.h"
+#include "xfa_document_imp.h"
+#include "xfa_document_layout_imp.h"
+#include "xfa_document_datamerger_imp.h"
+#include "xfa_layout_itemlayout.h"
+#include "xfa_layout_pagemgr_new.h"
+#include "xfa_layout_appadapter.h"
+CXFA_LayoutProcessor* CXFA_Document::GetLayoutProcessor()
+{
+ if(!m_pLayoutProcessor) {
+ m_pLayoutProcessor = FX_NEW CXFA_LayoutProcessor(this);
+ ASSERT(m_pLayoutProcessor);
+ }
+ return m_pLayoutProcessor;
+}
+IXFA_DocLayout* CXFA_Document::GetDocLayout()
+{
+ return GetLayoutProcessor();
+}
+CXFA_LayoutProcessor::CXFA_LayoutProcessor(CXFA_Document* pDocument)
+ : m_pDocument(pDocument)
+ , m_pRootItemLayoutProcessor(NULL)
+ , m_pLayoutPageMgr(NULL)
+ , m_nProgressCounter(0)
+ , m_bNeeLayout(TRUE)
+{
+}
+CXFA_LayoutProcessor::~CXFA_LayoutProcessor()
+{
+ ClearLayoutData();
+}
+CXFA_Document* CXFA_LayoutProcessor::GetDocument() const
+{
+ return m_pDocument;
+}
+FX_INT32 CXFA_LayoutProcessor::StartLayout(FX_BOOL bForceRestart)
+{
+ if (!bForceRestart && !IsNeedLayout()) {
+ return 100;
+ }
+ if(m_pRootItemLayoutProcessor) {
+ delete m_pRootItemLayoutProcessor;
+ m_pRootItemLayoutProcessor = NULL;
+ }
+ m_nProgressCounter = 0;
+ CXFA_Node* pFormPacketNode = (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Form);
+ if (!pFormPacketNode) {
+ return -1;
+ }
+ CXFA_Node* pFormRoot = pFormPacketNode->GetFirstChildByClass(XFA_ELEMENT_Subform);
+ if(!pFormRoot) {
+ return -1;
+ }
+ if (!m_pLayoutPageMgr) {
+ m_pLayoutPageMgr = FX_NEW CXFA_LayoutPageMgr(this);
+ }
+ if (!m_pLayoutPageMgr->InitLayoutPage(pFormRoot)) {
+ return -1;
+ }
+ if (!m_pLayoutPageMgr->PrepareFirstPage(pFormRoot)) {
+ return -1;
+ }
+ m_pRootItemLayoutProcessor = FX_NEW CXFA_ItemLayoutProcessor(pFormRoot, m_pLayoutPageMgr);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ m_pRootItemLayoutProcessor->m_pPageMgrCreateItem = m_pLayoutPageMgr;
+#endif
+ m_nProgressCounter = 1;
+ return 0;
+}
+FX_INT32 CXFA_LayoutProcessor::DoLayout(IFX_Pause* pPause )
+{
+ if (m_nProgressCounter < 1) {
+ return -1;
+ }
+ XFA_ItemLayoutProcessorResult eStatus;
+ CXFA_Node* pFormNode = m_pRootItemLayoutProcessor->GetFormNode();
+ FX_FLOAT fPosX = pFormNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);
+ FX_FLOAT fPosY = pFormNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);
+ do {
+ FX_FLOAT fAvailHeight = m_pLayoutPageMgr->GetAvailHeight();
+ eStatus = m_pRootItemLayoutProcessor->DoLayout(TRUE, fAvailHeight, fAvailHeight);
+ if(eStatus != XFA_ItemLayoutProcessorResult_Done) {
+ m_nProgressCounter++;
+ }
+ CXFA_ContentLayoutItemImpl* pLayoutItem = m_pRootItemLayoutProcessor->ExtractLayoutItem();
+ if(pLayoutItem) {
+ pLayoutItem->m_sPos.Set(fPosX, fPosY);
+ }
+ m_pLayoutPageMgr->SubmitContentItem(pLayoutItem, eStatus);
+ } while (eStatus != XFA_ItemLayoutProcessorResult_Done && (!pPause || !pPause->NeedToPauseNow()));
+ if (eStatus == XFA_ItemLayoutProcessorResult_Done) {
+ m_pLayoutPageMgr->FinishPaginatedPageSets();
+ m_pLayoutPageMgr->SyncLayoutData();
+ m_bNeeLayout = FALSE;
+ m_rgChangedContainers.RemoveAll();
+ }
+ return 100 * (eStatus == XFA_ItemLayoutProcessorResult_Done ? m_nProgressCounter : m_nProgressCounter - 1) / m_nProgressCounter;
+}
+FX_BOOL CXFA_LayoutProcessor::IncrementLayout()
+{
+ if (m_bNeeLayout) {
+ StartLayout(TRUE);
+ return DoLayout(NULL) == 100;
+ }
+ for (FX_INT32 i = 0, c = m_rgChangedContainers.GetSize(); i < c; i++) {
+ CXFA_Node *pNode = m_rgChangedContainers[i];
+ CXFA_Node *pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ if(!pParentNode) {
+ return FALSE;
+ }
+ if(!CXFA_ItemLayoutProcessor::IncrementRelayoutNode(this, pNode, pParentNode)) {
+ return FALSE;
+ }
+ }
+ m_rgChangedContainers.RemoveAll();
+ return TRUE;
+}
+FX_INT32 CXFA_LayoutProcessor::CountPages() const
+{
+ return m_pLayoutPageMgr ? m_pLayoutPageMgr->GetPageCount() : 0;
+}
+IXFA_LayoutPage* CXFA_LayoutProcessor::GetPage(FX_INT32 index) const
+{
+ return m_pLayoutPageMgr ? m_pLayoutPageMgr->GetPage(index) : NULL;
+}
+CXFA_LayoutItem* CXFA_LayoutProcessor::GetLayoutItem(CXFA_Node *pFormItem)
+{
+ return (CXFA_LayoutItem*)pFormItem->GetUserData(XFA_LAYOUTITEMKEY);
+}
+void CXFA_LayoutProcessor::AddChangedContainer(CXFA_Node* pContainer)
+{
+ if (m_rgChangedContainers.Find(pContainer) < 0) {
+ m_rgChangedContainers.Add(pContainer);
+ }
+}
+CXFA_ContainerLayoutItemImpl* CXFA_LayoutProcessor::GetRootLayoutItem() const
+{
+ return m_pLayoutPageMgr ? m_pLayoutPageMgr->GetRootLayoutItem() : NULL;
+}
+void CXFA_LayoutProcessor::ClearLayoutData()
+{
+ if(m_pLayoutPageMgr) {
+ delete m_pLayoutPageMgr;
+ m_pLayoutPageMgr = NULL;
+ }
+ if(m_pRootItemLayoutProcessor) {
+ delete m_pRootItemLayoutProcessor;
+ m_pRootItemLayoutProcessor = NULL;
+ }
+ m_nProgressCounter = 0;
+}
+FX_BOOL CXFA_LayoutProcessor::IsNeedLayout()
+{
+ return m_bNeeLayout || m_rgChangedContainers.GetSize() > 0;
+}
+CXFA_LayoutItemImpl::CXFA_LayoutItemImpl(CXFA_Node *pNode, FX_BOOL bIsContentLayoutItem)
+ : m_pFormNode(pNode)
+ , m_bIsContentLayoutItem(bIsContentLayoutItem)
+ , m_pParent(NULL)
+ , m_pNextSibling(NULL)
+ , m_pFirstChild(NULL)
+{
+}
+CXFA_LayoutItemImpl::~CXFA_LayoutItemImpl()
+{
+}
+CXFA_ContainerLayoutItemImpl::CXFA_ContainerLayoutItemImpl(CXFA_Node *pNode)
+ : CXFA_LayoutItemImpl(pNode, FALSE), m_pOldSubform(NULL)
+{
+}
+CXFA_ContentLayoutItemImpl::CXFA_ContentLayoutItemImpl(CXFA_Node *pNode)
+ : CXFA_LayoutItemImpl(pNode, TRUE)
+ , m_pPrev(NULL)
+ , m_pNext(NULL)
+ , m_dwStatus(0)
+{
+}
+CXFA_ContentLayoutItemImpl::~CXFA_ContentLayoutItemImpl()
+{
+ if (m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY) == this) {
+ m_pFormNode->SetUserData(XFA_LAYOUTITEMKEY, NULL);
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_document_layout_imp.h b/xfa/src/fxfa/src/parser/xfa_document_layout_imp.h
new file mode 100644
index 0000000000..178268caf9
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_layout_imp.h
@@ -0,0 +1,52 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCUMENT_LAYOUT_IMP_H_
+#define _XFA_DOCUMENT_LAYOUT_IMP_H_
+class CXFA_ItemLayoutProcessor;
+class CXFA_LayoutPageMgr;
+class CXFA_LayoutAppAdapter;
+class CXFA_ContainerLayoutItemImpl;
+class CXFA_LayoutProcessor : public IXFA_DocLayout, public CFX_Object
+{
+public:
+ CXFA_LayoutProcessor(CXFA_Document* pDocument);
+ ~CXFA_LayoutProcessor();
+ virtual CXFA_Document* GetDocument() const;
+ virtual FX_INT32 StartLayout(FX_BOOL bForceRestart = FALSE);
+ virtual FX_INT32 DoLayout(IFX_Pause *pPause = NULL);
+ virtual FX_BOOL IncrementLayout();
+ virtual FX_INT32 CountPages() const;
+ virtual IXFA_LayoutPage* GetPage(FX_INT32 index) const;
+ virtual CXFA_LayoutItem* GetLayoutItem(CXFA_Node *pFormItem);
+
+ void AddChangedContainer(CXFA_Node* pContainer);
+ void SetForceReLayout(FX_BOOL bForceRestart)
+ {
+ m_bNeeLayout = bForceRestart;
+ }
+ CXFA_ContainerLayoutItemImpl* GetRootLayoutItem() const;
+ CXFA_ItemLayoutProcessor* GetRootRootItemLayoutProcessor()
+ {
+ return m_pRootItemLayoutProcessor;
+ }
+ CXFA_LayoutPageMgr* GetLayoutPageMgr()
+ {
+ return m_pLayoutPageMgr;
+ }
+protected:
+ void ClearLayoutData();
+
+ FX_BOOL IsNeedLayout();
+
+ CXFA_Document* m_pDocument;
+ CXFA_ItemLayoutProcessor* m_pRootItemLayoutProcessor;
+ CXFA_LayoutPageMgr* m_pLayoutPageMgr;
+ CXFA_NodeArray m_rgChangedContainers;
+ FX_UINT32 m_nProgressCounter;
+ FX_BOOL m_bNeeLayout;
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_document_serialize.cpp b/xfa/src/fxfa/src/parser/xfa_document_serialize.cpp
new file mode 100644
index 0000000000..690a255ce1
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_serialize.cpp
@@ -0,0 +1,543 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_document_serialize.h"
+IXFA_PacketImport* IXFA_PacketImport::Create(CXFA_Document *pDocument)
+{
+ return FX_NEW CXFA_DataImporter(pDocument);
+}
+CXFA_DataImporter::CXFA_DataImporter(CXFA_Document *pDocument)
+ : m_pDocument(pDocument)
+{
+ ASSERT(m_pDocument != NULL);
+}
+FX_BOOL CXFA_DataImporter::ImportData(IFX_FileRead* pDataDocument)
+{
+ IXFA_Parser *pDataDocumentParser = IXFA_Parser::Create(m_pDocument);
+ if(!pDataDocumentParser) {
+ return FALSE;
+ }
+ if(pDataDocumentParser->StartParse(pDataDocument, XFA_XDPPACKET_Datasets) != XFA_PARSESTATUS_Ready) {
+ pDataDocumentParser->Release();
+ return FALSE;
+ }
+ if(pDataDocumentParser->DoParse(NULL) < XFA_PARSESTATUS_Done) {
+ pDataDocumentParser->Release();
+ return FALSE;
+ }
+ CXFA_Node* pImportDataRoot = pDataDocumentParser->GetRootNode();
+ if(!pImportDataRoot) {
+ pDataDocumentParser->Release();
+ return FALSE;
+ }
+ CXFA_Node* pDataModel = (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Datasets);
+ if (!pDataModel) {
+ pDataDocumentParser->Release();
+ return FALSE;
+ }
+ CXFA_Node* pDataNode = (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Data);
+ if (pDataNode) {
+ pDataModel->RemoveChild(pDataNode);
+ }
+ if (pImportDataRoot->GetClassID() == XFA_ELEMENT_DataModel) {
+ while(CXFA_Node* pChildNode = pImportDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ pImportDataRoot->RemoveChild(pChildNode);
+ pDataModel->InsertChild(pChildNode);
+ }
+ } else {
+ IFDE_XMLNode* pXMLNode = pImportDataRoot->GetXMLMappingNode();
+ IFDE_XMLNode* pParentXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+ if (pParentXMLNode) {
+ pParentXMLNode->RemoveChildNode(pXMLNode);
+ }
+ pDataModel->InsertChild(pImportDataRoot);
+ }
+ m_pDocument->DoDataRemerge(FALSE);
+ pDataDocumentParser->Release();
+ return TRUE;
+}
+CFX_WideString XFA_ExportEncodeAttribute(const CFX_WideString& str)
+{
+ CFX_WideTextBuf textBuf;
+ FX_INT32 iLen = str.GetLength();
+ for (FX_INT32 i = 0; i < iLen; i++) {
+ switch (str[i]) {
+ case '&':
+ textBuf << FX_WSTRC(L"&amp;");
+ break;
+ case '<':
+ textBuf << FX_WSTRC(L"&lt;");
+ break;
+ case '>':
+ textBuf << FX_WSTRC(L"&gt;");
+ break;
+ case '\'':
+ textBuf << FX_WSTRC(L"&apos;");
+ break;
+ case '\"':
+ textBuf << FX_WSTRC(L"&quot;");
+ break;
+ default:
+ textBuf.AppendChar(str[i]);
+ }
+ }
+ return textBuf.GetWideString();
+}
+CFX_WideString XFA_ExportEncodeContent(FX_WSTR str)
+{
+ CFX_WideTextBuf textBuf;
+ FX_INT32 iLen = str.GetLength();
+ for (FX_INT32 i = 0; i < iLen; i++) {
+ FX_WCHAR ch = str.GetAt(i);
+ if (!FDE_IsXMLValidChar(ch)) {
+ continue;
+ }
+ if (ch == '&') {
+ textBuf << FX_WSTRC(L"&amp;");
+ } else if (ch == '<') {
+ textBuf << FX_WSTRC(L"&lt;");
+ } else if (ch == '>') {
+ textBuf << FX_WSTRC(L"&gt;");
+ } else if (ch == '\'') {
+ textBuf << FX_WSTRC(L"&apos;");
+ } else if (ch == '\"') {
+ textBuf << FX_WSTRC(L"&quot;");
+ } else if (ch == ' ') {
+ if (i && str.GetAt(i - 1) != ' ') {
+ textBuf.AppendChar(' ');
+ } else {
+ textBuf << FX_WSTRC(L"&#x20;");
+ }
+ } else {
+ textBuf.AppendChar(str.GetAt(i));
+ }
+ }
+ return textBuf.GetWideString();
+}
+static void XFA_SaveAttribute(CXFA_Node* pNode, XFA_ATTRIBUTE eName, FX_WSTR wsName, FX_BOOL bProto, CFX_WideString &wsOutput)
+{
+ CFX_WideString wsValue;
+ if ((!bProto && !pNode->HasAttribute((XFA_ATTRIBUTE)eName, bProto)) || !pNode->GetAttribute((XFA_ATTRIBUTE)eName, wsValue, FALSE)) {
+ return;
+ }
+ wsValue = XFA_ExportEncodeAttribute(wsValue);
+ wsOutput += FX_WSTRC(L" ");
+ wsOutput += wsName;
+ wsOutput += FX_WSTRC(L"=\"");
+ wsOutput += wsValue;
+ wsOutput += FX_WSTRC(L"\"");
+}
+static FX_BOOL XFA_DataExporter_AttributeSaveInDataModel(CXFA_Node* pNode, XFA_ATTRIBUTE eAttribute)
+{
+ FX_BOOL bSaveInDataModel = FALSE;
+ if (pNode->GetClassID() != XFA_ELEMENT_Image) {
+ return bSaveInDataModel;
+ }
+ CXFA_Node* pValueNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pValueNode || pValueNode->GetClassID() != XFA_ELEMENT_Value) {
+ return bSaveInDataModel;
+ }
+ CXFA_Node* pFieldNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pFieldNode && pFieldNode->GetBindData() && eAttribute == XFA_ATTRIBUTE_Href) {
+ bSaveInDataModel = TRUE;
+ }
+ return bSaveInDataModel;
+}
+FX_BOOL XFA_DataExporter_ContentNodeNeedtoExport(CXFA_Node* pContentNode)
+{
+ CFX_WideString wsContent;
+ if (!pContentNode->TryContent(wsContent, FALSE, FALSE)) {
+ return FALSE;
+ }
+ FXSYS_assert(pContentNode->GetObjectType() == XFA_OBJECTTYPE_ContentNode);
+ CXFA_Node* pParentNode = pContentNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pParentNode || pParentNode->GetClassID() != XFA_ELEMENT_Value) {
+ return TRUE;
+ }
+ CXFA_Node* pGrandParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pGrandParentNode || pGrandParentNode->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {
+ return TRUE;
+ }
+ if (pGrandParentNode->GetBindData()) {
+ return FALSE;
+ }
+ CXFA_WidgetData* pWidgetData = pGrandParentNode->GetWidgetData();
+ XFA_ELEMENT eUIType = pWidgetData->GetUIType();
+ if (eUIType == XFA_ELEMENT_PasswordEdit) {
+ return FALSE;
+ }
+ return TRUE;
+}
+static void XFA_DataExporter_RecognizeXFAVersionNumber(CXFA_Node *pTemplateRoot, CFX_WideString& wsVersionNumber)
+{
+ wsVersionNumber.Empty();
+ if(!pTemplateRoot) {
+ return;
+ }
+ CFX_WideString wsTemplateNS;
+ if(!pTemplateRoot->TryNamespace(wsTemplateNS)) {
+ return;
+ }
+ XFA_VERSION eVersion = pTemplateRoot->GetDocument()->RecognizeXFAVersionNumber(wsTemplateNS);
+ if(eVersion == XFA_VERSION_UNKNOWN) {
+ eVersion = XFA_VERSION_DEFAULT;
+ }
+ wsVersionNumber.Format((FX_LPCWSTR)L"%i.%i", eVersion / 100, eVersion % 100);
+}
+static void XFA_DataExporter_RegenerateFormFile_Changed(CXFA_Node* pNode, CFX_WideTextBuf& buf, FX_BOOL bSaveXML = FALSE)
+{
+ CFX_WideString wsAttrs;
+ FX_INT32 iAttrs = 0;
+ FX_LPCBYTE pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs);
+ while (iAttrs--) {
+ XFA_LPCATTRIBUTEINFO pAttr = XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]);
+ if (pAttr->eName == XFA_ATTRIBUTE_Name || (XFA_DataExporter_AttributeSaveInDataModel(pNode, pAttr->eName) && !bSaveXML)) {
+ continue;
+ }
+ CFX_WideString wsAttr;
+ XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, bSaveXML, wsAttr);
+ wsAttrs += wsAttr;
+ }
+ CFX_WideString wsChildren;
+ switch(pNode->GetObjectType()) {
+ case XFA_OBJECTTYPE_ContentNode: {
+ if (!bSaveXML && !XFA_DataExporter_ContentNodeNeedtoExport(pNode)) {
+ break;
+ }
+ CXFA_Node *pRawValueNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while(pRawValueNode && pRawValueNode->GetClassID() != XFA_ELEMENT_SharpxHTML && pRawValueNode->GetClassID() != XFA_ELEMENT_Sharptext && pRawValueNode->GetClassID() != XFA_ELEMENT_Sharpxml) {
+ pRawValueNode = pRawValueNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ if(!pRawValueNode) {
+ break;
+ }
+ CFX_WideString wsContentType;
+ pNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ if (pRawValueNode->GetClassID() == XFA_ELEMENT_SharpxHTML && wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+ IFDE_XMLNode* pExDataXML = pNode->GetXMLMappingNode();
+ if (!pExDataXML) {
+ break;
+ }
+ IFDE_XMLNode* pRichTextXML = pExDataXML->GetNodeItem(IFDE_XMLNode::FirstChild);
+ if (!pRichTextXML) {
+ break;
+ }
+ IFX_MemoryStream* pMemStream = FX_CreateMemoryStream(TRUE);
+ IFX_Stream *pTempStream = IFX_Stream::CreateStream((IFX_FileWrite*)pMemStream, FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
+ pTempStream->SetCodePage(FX_CODEPAGE_UTF8);
+ pRichTextXML->SaveXMLNode(pTempStream);
+ wsChildren += CFX_WideString::FromUTF8((FX_LPCSTR)pMemStream->GetBuffer(), pMemStream->GetSize());
+ pTempStream->Release();
+ pMemStream->Release();
+ } else if (pRawValueNode->GetClassID() == XFA_ELEMENT_Sharpxml && wsContentType.Equal(FX_WSTRC(L"text/xml"))) {
+ CFX_WideString wsRawValue;
+ pRawValueNode->GetAttribute(XFA_ATTRIBUTE_Value, wsRawValue, FALSE);
+ if (wsRawValue.IsEmpty()) {
+ break;
+ }
+ CFX_WideStringArray wsSelTextArray;
+ FX_INT32 iStart = 0;
+ FX_INT32 iEnd = wsRawValue.Find(L'\n', iStart);
+ iEnd = (iEnd == -1) ? wsRawValue.GetLength() : iEnd;
+ while (iEnd >= iStart) {
+ wsSelTextArray.Add(wsRawValue.Mid(iStart, iEnd - iStart));
+ iStart = iEnd + 1;
+ if (iStart >= wsRawValue.GetLength()) {
+ break;
+ }
+ iEnd = wsRawValue.Find(L'\n', iStart);
+ }
+ CXFA_Node *pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ FXSYS_assert(pParentNode);
+ CXFA_Node *pGrandparentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+ FXSYS_assert(pGrandparentNode);
+ CFX_WideString bodyTagName;
+ bodyTagName = pGrandparentNode->GetCData(XFA_ATTRIBUTE_Name);
+ if (bodyTagName.IsEmpty()) {
+ bodyTagName = FX_WSTRC(L"ListBox1");
+ }
+ buf << FX_WSTRC(L"<");
+ buf << bodyTagName;
+ buf << FX_WSTRC(L" xmlns=\"\"\n>");
+ for (FX_INT32 i = 0; i < wsSelTextArray.GetSize(); i++) {
+ buf << FX_WSTRC(L"<value\n>");
+ buf << XFA_ExportEncodeContent(wsSelTextArray[i]);
+ buf << FX_WSTRC(L"</value\n>");
+ }
+ buf << FX_WSTRC(L"</");
+ buf << bodyTagName;
+ buf << FX_WSTRC(L"\n>");
+ wsChildren += buf.GetWideString();
+ buf.Clear();
+ } else {
+ CFX_WideStringC wsValue = pRawValueNode->GetCData(XFA_ATTRIBUTE_Value);
+ wsChildren += XFA_ExportEncodeContent(wsValue);
+ }
+ }
+ break;
+ case XFA_OBJECTTYPE_TextNode:
+ case XFA_OBJECTTYPE_NodeC:
+ case XFA_OBJECTTYPE_NodeV: {
+ CFX_WideStringC wsValue = pNode->GetCData(XFA_ATTRIBUTE_Value);
+ wsChildren += XFA_ExportEncodeContent(wsValue);
+ }
+ break;
+ default:
+ if (pNode->GetClassID() == XFA_ELEMENT_Items) {
+ CXFA_Node* pTemplateNode = pNode->GetTemplateNode();
+ if (!pTemplateNode || pTemplateNode->CountChildren(XFA_ELEMENT_UNKNOWN) != pNode->CountChildren(XFA_ELEMENT_UNKNOWN)) {
+ bSaveXML = TRUE;
+ }
+ }
+ CFX_WideTextBuf newBuf;
+ CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChildNode) {
+ XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf, bSaveXML);
+ wsChildren += newBuf.GetWideString();
+ newBuf.Clear();
+ pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ if (!bSaveXML && !wsChildren.IsEmpty() && pNode->GetClassID() == XFA_ELEMENT_Items) {
+ wsChildren.Empty();
+ bSaveXML = TRUE;
+ CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChildNode) {
+ XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf, bSaveXML);
+ wsChildren += newBuf.GetWideString();
+ newBuf.Clear();
+ pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ }
+ break;
+ }
+ if (!wsChildren.IsEmpty() || !wsAttrs.IsEmpty() || pNode->HasAttribute(XFA_ATTRIBUTE_Name)) {
+ CFX_WideStringC wsElement;
+ pNode->GetClassName(wsElement);
+ CFX_WideString wsName;
+ XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE, wsName);
+ buf << FX_WSTRC(L"<");
+ buf << wsElement;
+ buf << wsName;
+ buf << wsAttrs;
+ if (wsChildren.IsEmpty()) {
+ buf << FX_WSTRC(L"\n/>");
+ } else {
+ buf << FX_WSTRC(L"\n>");
+ buf << wsChildren;
+ buf << FX_WSTRC(L"</");
+ buf << wsElement;
+ buf << FX_WSTRC(L"\n>");
+ }
+ }
+}
+static void XFA_DataExporter_RegenerateFormFile_Container(CXFA_Node* pNode, IFX_Stream* pStream, FX_BOOL bSaveXML = FALSE)
+{
+ XFA_ELEMENT eElement = pNode->GetClassID();
+ if (eElement == XFA_ELEMENT_Field || eElement == XFA_ELEMENT_Draw || !pNode->IsContainerNode()) {
+ CFX_WideTextBuf buf;
+ XFA_DataExporter_RegenerateFormFile_Changed(pNode, buf, bSaveXML);
+ FX_STRSIZE nLen = buf.GetLength();
+ if (nLen > 0) {
+ pStream->WriteString((FX_LPCWSTR)buf.GetBuffer(), nLen);
+ }
+ return;
+ }
+ CFX_WideStringC wsElement;
+ pNode->GetClassName(wsElement);
+ pStream->WriteString((FX_LPCWSTR)L"<", 1);
+ pStream->WriteString(wsElement.GetPtr(), wsElement.GetLength());
+ CFX_WideString wsOutput;
+ XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE, wsOutput);
+ CFX_WideString wsAttrs;
+ FX_INT32 iAttrs = 0;
+ FX_LPCBYTE pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs);
+ while (iAttrs--) {
+ XFA_LPCATTRIBUTEINFO pAttr = XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]);
+ if (pAttr->eName == XFA_ATTRIBUTE_Name) {
+ continue;
+ }
+ CFX_WideString wsAttr;
+ XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, FALSE, wsAttr);
+ wsOutput += wsAttr;
+ }
+ if (!wsOutput.IsEmpty()) {
+ pStream->WriteString((FX_LPCWSTR)wsOutput, wsOutput.GetLength());
+ }
+ CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pChildNode) {
+ pStream->WriteString((FX_LPCWSTR)L"\n>", 2);
+ while (pChildNode) {
+ XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream, bSaveXML);
+ pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ pStream->WriteString((FX_LPCWSTR)L"</", 2);
+ pStream->WriteString(wsElement.GetPtr(), wsElement.GetLength());
+ pStream->WriteString((FX_LPCWSTR)L"\n>", 2);
+ } else {
+ pStream->WriteString((FX_LPCWSTR)L"\n/>", 3);
+ }
+}
+void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, IFX_Stream* pStream, FX_LPCSTR pChecksum , FX_BOOL bSaveXML)
+{
+ if(pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) {
+ static FX_LPCWSTR s_pwsTagName = (FX_LPCWSTR)L"<form";
+ static FX_LPCWSTR s_pwsClose = (FX_LPCWSTR)L"</form\n>";
+ pStream->WriteString(s_pwsTagName, FXSYS_wcslen(s_pwsTagName));
+ if (pChecksum != NULL) {
+ static FX_LPCWSTR s_pwChecksum = (FX_LPCWSTR)L" checksum=\"";
+ CFX_WideString wsChecksum = CFX_WideString::FromUTF8(pChecksum, FXSYS_strlen(pChecksum));
+ pStream->WriteString(s_pwChecksum, FXSYS_wcslen(s_pwChecksum));
+ pStream->WriteString((FX_LPCWSTR)wsChecksum, wsChecksum.GetLength());
+ pStream->WriteString((FX_LPCWSTR)L"\"", 1);
+ }
+ pStream->WriteString((FX_LPCWSTR)L" xmlns=\"", FXSYS_wcslen((FX_LPCWSTR)L" xmlns=\""));
+ FX_LPCWSTR pURI = XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI;
+ pStream->WriteString(pURI, FXSYS_wcslen(pURI));
+ CFX_WideString wsVersionNumber;
+ XFA_DataExporter_RecognizeXFAVersionNumber((CXFA_Node*)pNode->GetDocument()->GetXFANode(XFA_XDPPACKET_Template), wsVersionNumber);
+ if (wsVersionNumber.IsEmpty()) {
+ wsVersionNumber = FX_WSTRC(L"2.8");
+ }
+ wsVersionNumber += FX_WSTRC(L"/\"\n>");
+ pStream->WriteString((FX_LPCWSTR)wsVersionNumber, wsVersionNumber.GetLength());
+ CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChildNode) {
+ XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream);
+ pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ pStream->WriteString(s_pwsClose, FXSYS_wcslen(s_pwsClose));
+ } else {
+ XFA_DataExporter_RegenerateFormFile_Container(pNode, pStream, bSaveXML);
+ }
+}
+IXFA_PacketExport* IXFA_PacketExport::Create(CXFA_Document *pDocument, XFA_DATAFORMAT eFormat )
+{
+ return FX_NEW CXFA_DataExporter(pDocument);
+}
+CXFA_DataExporter::CXFA_DataExporter(CXFA_Document *pDocument)
+ : m_pDocument(pDocument)
+{
+ ASSERT(m_pDocument != NULL);
+}
+FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite *pWrite)
+{
+ return Export(pWrite, m_pDocument->GetRoot());
+}
+FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite *pWrite, CXFA_Node *pNode, FX_DWORD dwFlag , FX_LPCSTR pChecksum )
+{
+ ASSERT(pWrite != NULL);
+ if (pWrite == NULL) {
+ return FALSE;
+ }
+ IFX_Stream *pStream = IFX_Stream::CreateStream(pWrite, FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
+ if (pStream == NULL) {
+ return FALSE;
+ }
+ pStream->SetCodePage(FX_CODEPAGE_UTF8);
+ FX_BOOL bRet = Export(pStream, pNode, dwFlag, pChecksum);
+ pStream->Release();
+ return bRet;
+}
+FX_BOOL CXFA_DataExporter::Export(IFX_Stream *pStream, CXFA_Node *pNode, FX_DWORD dwFlag, FX_LPCSTR pChecksum)
+{
+ IFDE_XMLDoc* pXMLDoc = m_pDocument->GetParser()->GetXMLDoc();
+ if(pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) {
+ switch (pNode->GetPacketID()) {
+ case XFA_XDPPACKET_XDP: {
+ static FX_LPCWSTR s_pwsPreamble = (FX_LPCWSTR)L"<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">";
+ pStream->WriteString(s_pwsPreamble, FXSYS_wcslen(s_pwsPreamble));
+ for(CXFA_Node *pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ Export(pStream, pChild, dwFlag, pChecksum);
+ }
+ static FX_LPCWSTR s_pwsPostamble = (FX_LPCWSTR)L"</xdp:xdp\n>";
+ pStream->WriteString(s_pwsPostamble, FXSYS_wcslen(s_pwsPostamble));
+ }
+ break;
+ case XFA_XDPPACKET_Datasets: {
+ IFDE_XMLElement* pElement = (IFDE_XMLElement*)pNode->GetXMLMappingNode();
+ if(!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+ return FALSE;
+ }
+ CXFA_Node *pDataNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ FXSYS_assert(pDataNode != NULL);
+ XFA_DataExporter_DealWithDataGroupNode(pDataNode);
+ pXMLDoc->SaveXMLNode(pStream, pElement);
+ }
+ break;
+ case XFA_XDPPACKET_Form: {
+ XFA_DataExporter_RegenerateFormFile(pNode, pStream, pChecksum);
+ }
+ break;
+ case XFA_XDPPACKET_Template:
+ default: {
+ IFDE_XMLElement* pElement = (IFDE_XMLElement*)pNode->GetXMLMappingNode();
+ if(!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+ return FALSE;
+ }
+ pXMLDoc->SaveXMLNode(pStream, pElement);
+ }
+ break;
+ }
+ } else {
+ CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ CXFA_Node* pExportNode = pNode;
+ for (CXFA_Node* pChildNode = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pChildNode != pNode) {
+ pExportNode = pDataNode;
+ break;
+ }
+ }
+ IFDE_XMLElement* pElement = (IFDE_XMLElement*)pExportNode->GetXMLMappingNode();
+ if(!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+ return FALSE;
+ }
+ XFA_DataExporter_DealWithDataGroupNode(pExportNode);
+ pElement->SetString(FX_WSTRC(L"xmlns:xfa"), FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"));
+ pXMLDoc->SaveXMLNode(pStream, pElement);
+ pElement->RemoveAttribute(FX_LPCWSTR(L"xmlns:xfa"));
+ }
+ return TRUE;
+}
+static void XFA_DataExporter_GenerateChecksum(CXFA_Document* pDocument, CFX_WideString& wsChecksum)
+{
+}
+void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node *pDataNode)
+{
+ if (!pDataNode || pDataNode->GetClassID() == XFA_ELEMENT_DataValue) {
+ return;
+ }
+ FX_INT32 iChildNum = 0;
+ for (CXFA_Node *pChildNode = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ iChildNum++;
+ XFA_DataExporter_DealWithDataGroupNode(pChildNode);
+ }
+ if (pDataNode->GetClassID() == XFA_ELEMENT_DataGroup) {
+ if (iChildNum > 0) {
+ IFDE_XMLNode *pXMLNode = pDataNode->GetXMLMappingNode();
+ FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element);
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement *)pXMLNode;
+ if (pXMLElement->HasAttribute((FX_LPCWSTR)L"xfa:dataNode")) {
+ pXMLElement->RemoveAttribute((FX_LPCWSTR)L"xfa:dataNode");
+ }
+ } else {
+ IFDE_XMLNode *pXMLNode = pDataNode->GetXMLMappingNode();
+ FXSYS_assert(pXMLNode->GetType() == FDE_XMLNODE_Element);
+ ((IFDE_XMLElement *)pXMLNode)->SetString(FX_WSTRC(L"xfa:dataNode"), FX_WSTRC(L"dataGroup"));
+ }
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_document_serialize.h b/xfa/src/fxfa/src/parser/xfa_document_serialize.h
new file mode 100644
index 0000000000..1caf96a76c
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_document_serialize.h
@@ -0,0 +1,35 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_DOCUMENT_SERIALIZE_H_
+#define _XFA_DOCUMENT_SERIALIZE_H_
+class CXFA_DataImporter : public IXFA_PacketImport, public CFX_Object
+{
+public:
+ CXFA_DataImporter(CXFA_Document *pDocument);
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_BOOL ImportData(IFX_FileRead* pDataDocument);
+protected:
+ CXFA_Document *m_pDocument;
+};
+class CXFA_DataExporter : public IXFA_PacketExport, public CFX_Object
+{
+public:
+ CXFA_DataExporter(CXFA_Document *pDocument);
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_BOOL Export(IFX_FileWrite *pWrite);
+ virtual FX_BOOL Export(IFX_FileWrite *pWrite, CXFA_Node *pNode, FX_DWORD dwFlag = 0, FX_LPCSTR pChecksum = NULL);
+protected:
+ FX_BOOL Export(IFX_Stream *pStream, CXFA_Node *pNode, FX_DWORD dwFlag, FX_LPCSTR pChecksum);
+ CXFA_Document *m_pDocument;
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_layout_appadapter.cpp b/xfa/src/fxfa/src/parser/xfa_layout_appadapter.cpp
new file mode 100644
index 0000000000..fb592b4c97
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_layout_appadapter.cpp
@@ -0,0 +1,180 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_document_layout_imp.h"
+#include "xfa_layout_itemlayout.h"
+#include "xfa_layout_pagemgr_new.h"
+#include "xfa_layout_appadapter.h"
+IXFA_DocLayout* IXFA_LayoutPage::GetLayout() const
+{
+ CXFA_ContainerLayoutItemImpl* pThis = (CXFA_ContainerLayoutItemImpl*)this;
+ return pThis->m_pFormNode->GetDocument()->GetLayoutProcessor();
+}
+FX_INT32 IXFA_LayoutPage::GetPageIndex() const
+{
+ CXFA_ContainerLayoutItemImpl* pThis = (CXFA_ContainerLayoutItemImpl*)this;
+ return pThis->m_pFormNode->GetDocument()->GetLayoutProcessor()->GetLayoutPageMgr()->GetPageIndex((IXFA_LayoutPage*)this);
+}
+void IXFA_LayoutPage::GetPageSize(CFX_SizeF &size)
+{
+ CXFA_ContainerLayoutItemImpl* pThis = (CXFA_ContainerLayoutItemImpl*)this;
+ size.Set(0, 0);
+ CXFA_Node *pMedium = pThis->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Medium);
+ if (pMedium) {
+ size.x = pMedium->GetMeasure(XFA_ATTRIBUTE_Short).ToUnit(XFA_UNIT_Pt);
+ size.y = pMedium->GetMeasure(XFA_ATTRIBUTE_Long).ToUnit(XFA_UNIT_Pt);
+ if (pMedium->GetEnum(XFA_ATTRIBUTE_Orientation) == XFA_ATTRIBUTEENUM_Landscape) {
+ size.Set(size.y, size.x);
+ }
+ }
+}
+CXFA_Node* IXFA_LayoutPage::GetMasterPage() const
+{
+ CXFA_ContainerLayoutItemImpl* pThis = (CXFA_ContainerLayoutItemImpl*)this;
+ return pThis->m_pFormNode;
+}
+IXFA_LayoutPage* CXFA_LayoutItem::GetPage() const
+{
+ CXFA_ContainerLayoutItemImpl* pThis = (CXFA_ContainerLayoutItemImpl*)this;
+ for(CXFA_LayoutItemImpl* pCurNode = pThis; pCurNode; pCurNode = pCurNode->m_pParent) {
+ if(pCurNode->m_pFormNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ return (IXFA_LayoutPage*)pCurNode;
+ }
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_LayoutItem::GetFormNode() const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ return pThis->m_pFormNode;
+}
+void CXFA_LayoutItem::GetRect(CFX_RectF &rtLayout, FX_BOOL bRelative) const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ CFX_PointF sPos = pThis->m_sPos;
+ CFX_SizeF sSize = pThis->m_sSize;
+ if (!bRelative) {
+ for(CXFA_LayoutItemImpl* pLayoutItem = pThis->m_pParent; pLayoutItem; pLayoutItem = pLayoutItem->m_pParent) {
+ if(pLayoutItem->IsContentLayoutItem()) {
+ sPos += ((CXFA_ContentLayoutItemImpl*)pLayoutItem)->m_sPos;
+ if(CXFA_Node* pMarginNode = pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin)) {
+ sPos.Add(pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt), pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt));
+ }
+ } else {
+ if(pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+ sPos.Add(pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt), pLayoutItem->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt));
+ break;
+ } else if(pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ break;
+ }
+ }
+ }
+ }
+ rtLayout.Set(sPos.x, sPos.y, sSize.x, sSize.y);
+}
+CXFA_LayoutItem* CXFA_LayoutItem::GetParent() const
+{
+ CXFA_LayoutItemImpl* pThis = (CXFA_LayoutItemImpl*)this;
+ return (CXFA_LayoutItem*)pThis->m_pParent;
+}
+CXFA_LayoutItem* CXFA_LayoutItem::GetFirst() const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ CXFA_ContentLayoutItemImpl* pCurNode = pThis;
+ while(pCurNode->m_pPrev) {
+ pCurNode = pCurNode->m_pPrev;
+ }
+ return (CXFA_LayoutItem*)pCurNode;
+}
+CXFA_LayoutItem* CXFA_LayoutItem::GetPrev() const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ return (CXFA_LayoutItem*)pThis->m_pPrev;
+}
+CXFA_LayoutItem* CXFA_LayoutItem::GetNext() const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ return (CXFA_LayoutItem*)pThis->m_pNext;
+}
+CXFA_LayoutItem* CXFA_LayoutItem::GetLast() const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ CXFA_ContentLayoutItemImpl* pCurNode = pThis;
+ while(pCurNode->m_pNext) {
+ pCurNode = pCurNode->m_pNext;
+ }
+ return (CXFA_LayoutItem*)pCurNode;
+}
+FX_INT32 CXFA_LayoutItem::GetIndex() const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ FX_INT32 iIndex = 0;
+ CXFA_ContentLayoutItemImpl* pCurNode = pThis;
+ while(pCurNode->m_pPrev) {
+ pCurNode = pCurNode->m_pPrev;
+ iIndex++;
+ }
+ return iIndex;
+}
+FX_INT32 CXFA_LayoutItem::GetCount() const
+{
+ CXFA_ContentLayoutItemImpl* pThis = (CXFA_ContentLayoutItemImpl*)this;
+ FX_INT32 iCount = 1;
+ CXFA_ContentLayoutItemImpl* pCurNode = NULL;
+ pCurNode = pThis;
+ while(pCurNode->m_pPrev) {
+ pCurNode = pCurNode->m_pPrev;
+ iCount++;
+ }
+ pCurNode = pThis;
+ while(pCurNode->m_pNext) {
+ pCurNode = pCurNode->m_pNext;
+ iCount++;
+ }
+ return iCount;
+}
+FX_DWORD XFA_GetRelevant(CXFA_Node* pFormItem, FX_DWORD dwParentRelvant)
+{
+ FX_DWORD dwRelevant = XFA_LAYOUTSTATUS_Viewable | XFA_LAYOUTSTATUS_Printable;
+ CFX_WideStringC wsRelevant;
+ if (pFormItem->TryCData(XFA_ATTRIBUTE_Relevant, wsRelevant)) {
+ if (wsRelevant == FX_WSTRC(L"+print") || wsRelevant == FX_WSTRC(L"print")) {
+ dwRelevant &= ~XFA_LAYOUTSTATUS_Viewable;
+ } else if (wsRelevant == FX_WSTRC(L"-print")) {
+ dwRelevant &= ~XFA_LAYOUTSTATUS_Printable;
+ }
+ }
+ if (!(dwParentRelvant & XFA_LAYOUTSTATUS_Viewable) && (dwRelevant != XFA_LAYOUTSTATUS_Viewable)) {
+ dwRelevant &= ~XFA_LAYOUTSTATUS_Viewable;
+ }
+ if (!(dwParentRelvant & XFA_LAYOUTSTATUS_Printable) && (dwRelevant != XFA_LAYOUTSTATUS_Printable)) {
+ dwRelevant &= ~XFA_LAYOUTSTATUS_Printable;
+ }
+ return dwRelevant;
+}
+void XFA_ReleaseLayoutItem(CXFA_LayoutItemImpl *pLayoutItem)
+{
+ CXFA_LayoutItemImpl *pNext, *pNode = pLayoutItem->m_pFirstChild;
+ while (pNode) {
+ pNext = pNode->m_pNextSibling;
+ pNode->m_pParent = NULL;
+ XFA_ReleaseLayoutItem(pNode);
+ pNode = pNext;
+ }
+ delete pLayoutItem;
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_layout_appadapter.h b/xfa/src/fxfa/src/parser/xfa_layout_appadapter.h
new file mode 100644
index 0000000000..ab50517b9f
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_layout_appadapter.h
@@ -0,0 +1,74 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_LAYOUT_APPADAPTER_H_
+#define _XFA_LAYOUT_APPADAPTER_H_
+class CXFA_TraverseStrategy_PageAreaContainerLayoutItem
+{
+public:
+ static inline CXFA_ContainerLayoutItemImpl* GetFirstChild(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ if(pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageSet) {
+ return (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pFirstChild;
+ }
+ return NULL;
+ }
+ static inline CXFA_ContainerLayoutItemImpl* GetNextSibling(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ return (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pNextSibling;
+ }
+ static inline CXFA_ContainerLayoutItemImpl* GetParent(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ return (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pParent;
+ }
+};
+class CXFA_TraverseStrategy_ContentAreaContainerLayoutItem
+{
+public:
+ static inline CXFA_ContainerLayoutItemImpl* GetFirstChild(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ for(CXFA_LayoutItemImpl* pChildItem = pLayoutItem->m_pFirstChild; pChildItem; pChildItem = pChildItem->m_pNextSibling) {
+ if(pChildItem->IsContentLayoutItem()) {
+ continue;
+ }
+ return (CXFA_ContainerLayoutItemImpl*)pChildItem;
+ }
+ return NULL;
+ }
+ static inline CXFA_ContainerLayoutItemImpl* GetNextSibling(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ for(CXFA_LayoutItemImpl* pChildItem = pLayoutItem->m_pNextSibling; pChildItem; pChildItem = pChildItem->m_pNextSibling) {
+ if(pChildItem->IsContentLayoutItem()) {
+ continue;
+ }
+ return (CXFA_ContainerLayoutItemImpl*)pChildItem;
+ }
+ return NULL;
+ }
+ static inline CXFA_ContainerLayoutItemImpl* GetParent(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ return (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pParent;
+ }
+};
+class CXFA_TraverseStrategy_ContentLayoutItem
+{
+public:
+ static inline CXFA_ContentLayoutItemImpl* GetFirstChild(CXFA_ContentLayoutItemImpl* pLayoutItem)
+ {
+ return (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pFirstChild;
+ }
+ static inline CXFA_ContentLayoutItemImpl* GetNextSibling(CXFA_ContentLayoutItemImpl* pLayoutItem)
+ {
+ return (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pNextSibling;
+ }
+ static inline CXFA_ContentLayoutItemImpl* GetParent(CXFA_ContentLayoutItemImpl* pLayoutItem)
+ {
+ return (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pParent;
+ }
+};
+FX_DWORD XFA_GetRelevant(CXFA_Node* pFormItem, FX_DWORD dwParentRelvant);
+void XFA_ReleaseLayoutItem(CXFA_LayoutItemImpl* pLayoutItem);
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp b/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp
new file mode 100644
index 0000000000..e6a2070088
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.cpp
@@ -0,0 +1,2391 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_document_layout_imp.h"
+#include "xfa_layout_itemlayout.h"
+#include "xfa_layout_pagemgr_new.h"
+#include "xfa_layout_appadapter.h"
+CXFA_ItemLayoutProcessor::CXFA_ItemLayoutProcessor(CXFA_Node *pNode, CXFA_LayoutPageMgr* pPageMgr)
+ : m_pFormNode(pNode)
+ , m_pLayoutItem(NULL)
+ , m_pCurChildNode(XFA_LAYOUT_INVALIDNODE)
+ , m_nCurChildNodeStage(XFA_ItemLayoutProcessorStages_None)
+ , m_pCurChildPreprocessor(NULL)
+ , m_fUsedSize(0)
+ , m_pPageMgr(pPageMgr)
+ , m_bHasAvailHeight(TRUE)
+#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
+ , m_pOldLayoutItem(NULL)
+#else
+ , m_pPageMgrCreateItem(NULL)
+#endif
+ , m_bKeepBreakFinish(FALSE)
+ , m_pKeepHeadNode(NULL)
+ , m_pKeepTailNode(NULL)
+ , m_bIsProcessKeep(FALSE)
+ , m_bBreakPending(TRUE)
+ , m_fLastRowWidth(0)
+ , m_fLastRowY(0)
+ , m_bUseInheriated(FALSE)
+ , m_fWidthLimite(0)
+ , m_ePreProcessRs(XFA_ItemLayoutProcessorResult_Done)
+{
+ FXSYS_assert(m_pFormNode && (m_pFormNode->IsContainerNode() || m_pFormNode->GetClassID() == XFA_ELEMENT_Form));
+#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
+ m_pOldLayoutItem = (CXFA_ContentLayoutItemImpl*)m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
+#endif
+}
+CXFA_ContentLayoutItemImpl* CXFA_ItemLayoutProcessor::CreateContentLayoutItem(CXFA_Node* pFormNode)
+{
+ if(!pFormNode) {
+ return NULL;
+ }
+ CXFA_ContentLayoutItemImpl* pLayoutItem = NULL;
+#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
+ if (m_pOldLayoutItem) {
+ pLayoutItem = m_pOldLayoutItem;
+ m_pOldLayoutItem = m_pOldLayoutItem->m_pNext;
+ return pLayoutItem;
+ }
+ pLayoutItem = (CXFA_ContentLayoutItemImpl*)pFormNode->GetDocument()->GetParser()->GetNotify()->OnCreateLayoutItem(pFormNode);
+#else
+ pLayoutItem = (CXFA_ContentLayoutItemImpl*)m_pPageMgrCreateItem->FindOrCreateLayoutItem(pFormNode);
+#endif
+ CXFA_ContentLayoutItemImpl* pPrevLayoutItem = (CXFA_ContentLayoutItemImpl*)pFormNode->GetUserData(XFA_LAYOUTITEMKEY);
+ if(pPrevLayoutItem) {
+ while(pPrevLayoutItem->m_pNext) {
+ pPrevLayoutItem = pPrevLayoutItem->m_pNext;
+ }
+ pPrevLayoutItem->m_pNext = pLayoutItem;
+ pLayoutItem->m_pPrev = pPrevLayoutItem;
+ } else {
+ pFormNode->SetUserData(XFA_LAYOUTITEMKEY, pLayoutItem);
+ }
+ return pLayoutItem;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::FindLayoutItemSplitPos(CXFA_ContentLayoutItemImpl* pLayoutItem, FX_FLOAT fCurVerticalOffset, FX_FLOAT& fProposedSplitPos, FX_BOOL& bAppChange, FX_BOOL bCalculateMargin )
+{
+ CXFA_Node* pFormNode = pLayoutItem->m_pFormNode;
+ if (fProposedSplitPos > fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION && fProposedSplitPos <= fCurVerticalOffset + pLayoutItem->m_sSize.y - XFA_LAYOUT_FLOAT_PERCISION) {
+ switch(pFormNode->GetIntact()) {
+ case XFA_ATTRIBUTEENUM_None: {
+ FX_BOOL bAnyChanged = FALSE;
+ CXFA_Document* pDocument = pFormNode->GetDocument();
+ IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
+ FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
+ CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ if(pMarginNode && bCalculateMargin) {
+ fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+ fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+ }
+ FX_BOOL bChanged = TRUE;
+ while(bChanged) {
+ bChanged = FALSE;
+ {
+ FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurVerticalOffset;
+ if(pNotify->FindSplitPos(pFormNode, ((CXFA_LayoutItem*)pLayoutItem)->GetIndex(), fRelSplitPos)) {
+ bAnyChanged = TRUE;
+ bChanged = TRUE;
+ fProposedSplitPos = fCurVerticalOffset + fRelSplitPos;
+ bAppChange = TRUE;
+ if(fProposedSplitPos <= fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
+ return TRUE;
+ }
+ }
+ }
+ FX_FLOAT fRelSplitPos = fProposedSplitPos - fCurBottomMargin;
+ for(CXFA_ContentLayoutItemImpl* pChildItem = (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pFirstChild; pChildItem; pChildItem = (CXFA_ContentLayoutItemImpl*)pChildItem->m_pNextSibling) {
+ FX_FLOAT fChildOffset = fCurVerticalOffset + fCurTopMargin + pChildItem->m_sPos.y;
+ FX_BOOL bAppChange = FALSE;
+ if (FindLayoutItemSplitPos(pChildItem, fChildOffset, fRelSplitPos, bAppChange, bCalculateMargin)) {
+ if(fRelSplitPos - fChildOffset < XFA_LAYOUT_FLOAT_PERCISION && bAppChange) {
+ fProposedSplitPos = fRelSplitPos - fCurTopMargin;
+ } else {
+ fProposedSplitPos = fRelSplitPos + fCurBottomMargin;
+ }
+ bAnyChanged = TRUE;
+ bChanged = TRUE;
+ if(fProposedSplitPos <= fCurVerticalOffset + XFA_LAYOUT_FLOAT_PERCISION) {
+ return TRUE;
+ }
+ if(bAnyChanged) {
+ break;
+ }
+ }
+ }
+ }
+ return bAnyChanged;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_ContentArea:
+ case XFA_ATTRIBUTEENUM_PageArea: {
+ fProposedSplitPos = fCurVerticalOffset;
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+static XFA_ATTRIBUTEENUM XFA_ItemLayoutProcessor_GetLayout(CXFA_Node* pFormNode, FX_BOOL& bRootForceTb)
+{
+ bRootForceTb = FALSE;
+ XFA_ATTRIBUTEENUM eLayoutMode;
+ if(pFormNode->TryEnum(XFA_ATTRIBUTE_Layout, eLayoutMode, FALSE)) {
+ return eLayoutMode;
+ }
+ CXFA_Node *pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Form) {
+ bRootForceTb = TRUE;
+ return XFA_ATTRIBUTEENUM_Tb;
+ }
+ return XFA_ATTRIBUTEENUM_Position;
+}
+static FX_BOOL XFA_ExistContainerKeep(CXFA_Node* pCurNode, FX_BOOL bPreFind)
+{
+ if(pCurNode == NULL || !XFA_ItemLayoutProcessor_IsTakingSpace(pCurNode)) {
+ return FALSE;
+ }
+ XFA_NODEITEM eItemType = XFA_NODEITEM_PrevSibling;
+ if(!bPreFind) {
+ eItemType = XFA_NODEITEM_NextSibling;
+ }
+ CXFA_Node* pPreContainer = pCurNode->GetNodeItem(eItemType, XFA_OBJECTTYPE_ContainerNode);
+ if(pPreContainer == NULL) {
+ return FALSE;
+ }
+ CXFA_Node* pKeep = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Keep);
+ if (pKeep) {
+ XFA_ATTRIBUTEENUM ePrevious;
+ XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Previous;
+ if(!bPreFind) {
+ eKeepType = XFA_ATTRIBUTE_Next;
+ }
+ if (pKeep->TryEnum(eKeepType, ePrevious, FALSE)) {
+ if(ePrevious == XFA_ATTRIBUTEENUM_ContentArea || ePrevious == XFA_ATTRIBUTEENUM_PageArea) {
+ return TRUE;
+ }
+ }
+ }
+ pKeep = pPreContainer->GetFirstChildByClass(XFA_ELEMENT_Keep);
+ if (!pKeep) {
+ return FALSE;
+ }
+ XFA_ATTRIBUTEENUM eNext;
+ XFA_ATTRIBUTE eKeepType = XFA_ATTRIBUTE_Next;
+ if(!bPreFind) {
+ eKeepType = XFA_ATTRIBUTE_Previous;
+ }
+ if (!pKeep->TryEnum(eKeepType, eNext, FALSE)) {
+ return FALSE;
+ }
+ if(eNext == XFA_ATTRIBUTEENUM_ContentArea || eNext == XFA_ATTRIBUTEENUM_PageArea) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_FLOAT CXFA_ItemLayoutProcessor::FindSplitPos(FX_FLOAT fProposedSplitPos)
+{
+ ASSERT(m_pLayoutItem);
+ XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ FX_BOOL bCalculateMargin = TRUE;
+ if(eLayout == XFA_ATTRIBUTEENUM_Position) {
+ bCalculateMargin = FALSE;
+ }
+ while(fProposedSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+ FX_BOOL bAppChange = FALSE;
+ if(!FindLayoutItemSplitPos(m_pLayoutItem, 0, fProposedSplitPos, bAppChange, bCalculateMargin)) {
+ break;
+ }
+ }
+ return fProposedSplitPos;
+}
+void CXFA_ItemLayoutProcessor::SplitLayoutItem(CXFA_ContentLayoutItemImpl* pLayoutItem, CXFA_ContentLayoutItemImpl* pSecondParent, FX_FLOAT fSplitPos)
+{
+ FX_FLOAT fCurTopMargin = 0, fCurBottomMargin = 0;
+ XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ FX_BOOL bCalculateMargin = TRUE;
+ if(eLayout == XFA_ATTRIBUTEENUM_Position) {
+ bCalculateMargin = FALSE;
+ }
+ CXFA_Node* pMarginNode = pLayoutItem->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ if(pMarginNode && bCalculateMargin) {
+ fCurTopMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+ fCurBottomMargin = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+ }
+ CXFA_ContentLayoutItemImpl* pSecondLayoutItem = NULL;
+ if (m_pCurChildPreprocessor && m_pCurChildPreprocessor->m_pFormNode == pLayoutItem->m_pFormNode) {
+ pSecondLayoutItem = m_pCurChildPreprocessor->CreateContentLayoutItem(pLayoutItem->m_pFormNode);
+ } else {
+ pSecondLayoutItem = CreateContentLayoutItem(pLayoutItem->m_pFormNode);
+ }
+ pSecondLayoutItem->m_sPos.x = pLayoutItem->m_sPos.x;
+ pSecondLayoutItem->m_sSize.x = pLayoutItem->m_sSize.x;
+ pSecondLayoutItem->m_sPos.y = 0;
+ pSecondLayoutItem->m_sSize.y = pLayoutItem->m_sSize.y - fSplitPos;
+ pLayoutItem->m_sSize.y -= pSecondLayoutItem->m_sSize.y;
+ if(pLayoutItem->m_pFirstChild) {
+ pSecondLayoutItem->m_sSize.y += fCurTopMargin;
+ }
+ if (pSecondParent) {
+ pSecondParent->AddChild(pSecondLayoutItem);
+ if(fCurTopMargin > 0 && pLayoutItem->m_pFirstChild) {
+ pSecondParent->m_sSize.y += fCurTopMargin;
+ CXFA_ContentLayoutItemImpl* pParentItem = (CXFA_ContentLayoutItemImpl*)pSecondParent->m_pParent;
+ while(pParentItem) {
+ pParentItem->m_sSize.y += fCurTopMargin;
+ pParentItem = (CXFA_ContentLayoutItemImpl*)pParentItem->m_pParent;
+ }
+ }
+ } else {
+ pSecondLayoutItem->m_pParent = pLayoutItem->m_pParent;
+ pSecondLayoutItem->m_pNextSibling = pLayoutItem->m_pNextSibling;
+ pLayoutItem->m_pNextSibling = pSecondLayoutItem;
+ }
+ CXFA_ContentLayoutItemImpl *pChildren = (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pFirstChild;
+ pLayoutItem->m_pFirstChild = NULL;
+ FX_FLOAT lHeightForKeep = 0;
+ CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> keepLayoutItems;
+ FX_FLOAT fAddMarginHeight = 0;
+ for(CXFA_ContentLayoutItemImpl *pChildItem = pChildren, *pChildNext = NULL; pChildItem; pChildItem = pChildNext) {
+ pChildNext = (CXFA_ContentLayoutItemImpl*)pChildItem->m_pNextSibling;
+ pChildItem->m_pNextSibling = NULL;
+ if (fSplitPos <= fCurTopMargin + pChildItem->m_sPos.y + fCurBottomMargin + XFA_LAYOUT_FLOAT_PERCISION) {
+ if(!XFA_ExistContainerKeep(pChildItem->m_pFormNode, TRUE)) {
+ pChildItem->m_sPos.y -= fSplitPos - fCurBottomMargin;
+ pChildItem->m_sPos.y += lHeightForKeep;
+ pChildItem->m_sPos.y += fAddMarginHeight;
+ pSecondLayoutItem->AddChild(pChildItem);
+ } else {
+ if(lHeightForKeep < XFA_LAYOUT_FLOAT_PERCISION) {
+ for(FX_INT32 iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex ++) {
+ CXFA_ContentLayoutItemImpl *pPreItem = keepLayoutItems[iIndex];
+ pLayoutItem->RemoveChild(pPreItem);
+ pPreItem->m_sPos.y -= fSplitPos;
+ if(pPreItem->m_sPos.y < 0) {
+ pPreItem->m_sPos.y = 0;
+ }
+ if (pPreItem->m_sPos.y + pPreItem->m_sSize.y > lHeightForKeep) {
+ pPreItem->m_sPos.y = lHeightForKeep;
+ lHeightForKeep += pPreItem->m_sSize.y;
+ pSecondLayoutItem->m_sSize.y += pPreItem->m_sSize.y;
+ if(pSecondParent) {
+ pSecondParent->m_sSize.y += pPreItem->m_sSize.y;
+ }
+ }
+ pSecondLayoutItem->AddChild(pPreItem);
+ }
+ }
+ pChildItem->m_sPos.y -= fSplitPos;
+ pChildItem->m_sPos.y += lHeightForKeep;
+ pChildItem->m_sPos.y += fAddMarginHeight;
+ pSecondLayoutItem->AddChild(pChildItem);
+ }
+ } else if (fSplitPos + XFA_LAYOUT_FLOAT_PERCISION >= fCurTopMargin + fCurBottomMargin + pChildItem->m_sPos.y + pChildItem->m_sSize.y) {
+ pLayoutItem->AddChild(pChildItem);
+ if(XFA_ExistContainerKeep(pChildItem->m_pFormNode, FALSE)) {
+ keepLayoutItems.Add(pChildItem);
+ } else {
+ keepLayoutItems.RemoveAll();
+ }
+ } else {
+ FX_FLOAT fOldHeight = pSecondLayoutItem->m_sSize.y;
+ SplitLayoutItem(pChildItem, pSecondLayoutItem, fSplitPos - fCurTopMargin - fCurBottomMargin - pChildItem->m_sPos.y);
+ fAddMarginHeight = pSecondLayoutItem->m_sSize.y - fOldHeight;
+ pLayoutItem->AddChild(pChildItem);
+ }
+ }
+}
+void CXFA_ItemLayoutProcessor::SplitLayoutItem(FX_FLOAT fSplitPos)
+{
+ ASSERT(m_pLayoutItem);
+ SplitLayoutItem(m_pLayoutItem, NULL, fSplitPos);
+ return;
+}
+void CXFA_LayoutItemImpl::AddChild(CXFA_LayoutItemImpl *pChildItem)
+{
+ if(pChildItem->m_pParent) {
+ pChildItem->m_pParent->RemoveChild(pChildItem);
+ }
+ pChildItem->m_pParent = this;
+ if(m_pFirstChild == NULL) {
+ m_pFirstChild = pChildItem;
+ } else {
+ CXFA_LayoutItemImpl* pExistingChildItem = m_pFirstChild;
+ while(pExistingChildItem->m_pNextSibling) {
+ pExistingChildItem = pExistingChildItem->m_pNextSibling;
+ }
+ pExistingChildItem->m_pNextSibling = pChildItem;
+ }
+}
+void CXFA_LayoutItemImpl::AddHeadChild(CXFA_LayoutItemImpl *pChildItem)
+{
+ if(pChildItem->m_pParent) {
+ pChildItem->m_pParent->RemoveChild(pChildItem);
+ }
+ pChildItem->m_pParent = this;
+ if(m_pFirstChild == NULL) {
+ m_pFirstChild = pChildItem;
+ } else {
+ CXFA_LayoutItemImpl* pExistingChildItem = m_pFirstChild;
+ m_pFirstChild = pChildItem;
+ m_pFirstChild->m_pNextSibling = pExistingChildItem;
+ }
+}
+void CXFA_LayoutItemImpl::InsertChild(CXFA_LayoutItemImpl *pBeforeItem, CXFA_LayoutItemImpl *pChildItem)
+{
+ if(pBeforeItem->m_pParent != this) {
+ return;
+ }
+ if(pChildItem->m_pParent) {
+ pChildItem->m_pParent = NULL;
+ }
+ pChildItem->m_pParent = this;
+ CXFA_LayoutItemImpl* pExistingChildItem = pBeforeItem->m_pNextSibling;
+ pBeforeItem->m_pNextSibling = pChildItem;
+ pChildItem->m_pNextSibling = pExistingChildItem;
+}
+void CXFA_LayoutItemImpl::RemoveChild(CXFA_LayoutItemImpl *pChildItem)
+{
+ if(pChildItem->m_pParent != this) {
+ return;
+ }
+ if(m_pFirstChild == pChildItem) {
+ m_pFirstChild = pChildItem->m_pNextSibling;
+ } else {
+ CXFA_LayoutItemImpl* pExistingChildItem = m_pFirstChild;
+ while(pExistingChildItem && pExistingChildItem->m_pNextSibling != pChildItem) {
+ pExistingChildItem = pExistingChildItem->m_pNextSibling;
+ }
+ if(pExistingChildItem) {
+ pExistingChildItem->m_pNextSibling = pChildItem->m_pNextSibling;
+ }
+ }
+ pChildItem->m_pNextSibling = NULL;
+ pChildItem->m_pParent = NULL;
+}
+CXFA_ContentLayoutItemImpl* CXFA_ItemLayoutProcessor::ExtractLayoutItem()
+{
+ CXFA_ContentLayoutItemImpl* pLayoutItem = m_pLayoutItem;
+ if(pLayoutItem) {
+ m_pLayoutItem = (CXFA_ContentLayoutItemImpl*)pLayoutItem->m_pNextSibling;
+ pLayoutItem->m_pNextSibling = NULL;
+ }
+#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
+ if (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && m_pOldLayoutItem && m_pOldLayoutItem->IsContentLayoutItem()) {
+ if (m_pOldLayoutItem->m_pPrev) {
+ m_pOldLayoutItem->m_pPrev->m_pNext = NULL;
+ }
+ IXFA_Notify* pNotify = m_pOldLayoutItem->m_pFormNode->GetDocument()->GetParser()->GetNotify();
+ IXFA_DocLayout* pDocLayout = m_pOldLayoutItem->m_pFormNode->GetDocument()->GetDocLayout();
+ CXFA_ContentLayoutItemImpl* pOldLayoutItem = m_pOldLayoutItem;
+ while (pOldLayoutItem) {
+ CXFA_ContentLayoutItemImpl* pNextOldLayoutItem = pOldLayoutItem->m_pNext;
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pOldLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ delete pOldLayoutItem;
+ pOldLayoutItem = pNextOldLayoutItem;
+ }
+ m_pOldLayoutItem = NULL;
+ }
+#endif
+ return pLayoutItem;
+}
+static FX_BOOL XFA_ItemLayoutProcessor_FindBreakNode(CXFA_Node* pContainerNode, CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, FX_BOOL bBreakBefore)
+{
+ FX_BOOL bFindRs = FALSE;
+ for(CXFA_Node *pBreakNode = pContainerNode; pBreakNode; pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_ATTRIBUTE eAttributeType = XFA_ATTRIBUTE_Before;
+ if(!bBreakBefore) {
+ eAttributeType = XFA_ATTRIBUTE_After;
+ }
+ switch(pBreakNode->GetClassID()) {
+ case XFA_ELEMENT_BreakBefore: {
+ if(bBreakBefore) {
+ pCurActionNode = pBreakNode;
+ nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
+ bFindRs = TRUE;
+ }
+ }
+ break;
+ case XFA_ELEMENT_BreakAfter: {
+ if(!bBreakBefore) {
+ pCurActionNode = pBreakNode;
+ nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
+ bFindRs = TRUE;
+ }
+ }
+ break;
+ case XFA_ELEMENT_Break:
+ if(pBreakNode->GetEnum(eAttributeType) != XFA_ATTRIBUTEENUM_Auto) {
+ pCurActionNode = pBreakNode;
+ nCurStage = XFA_ItemLayoutProcessorStages_BreakBefore;
+ if(!bBreakBefore) {
+ nCurStage = XFA_ItemLayoutProcessorStages_BreakAfter;
+ }
+ bFindRs = TRUE;
+ break;
+ }
+ default:
+ break;
+ }
+ if(bFindRs) {
+ break;
+ }
+ }
+ return bFindRs;
+}
+#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
+static void XFA_DeleteLayoutGeneratedNode(CXFA_Node* pGenerateNode)
+{
+ IXFA_Notify* pNotify = pGenerateNode->GetDocument()->GetParser()->GetNotify();
+ IXFA_DocLayout* pDocLayout = pGenerateNode->GetDocument()->GetDocLayout();
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pGenerateNode);
+ for(CXFA_Node* pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ CXFA_ContentLayoutItemImpl* pCurLayoutItem = (CXFA_ContentLayoutItemImpl*)pNode->GetUserData(XFA_LAYOUTITEMKEY);
+ CXFA_ContentLayoutItemImpl* pNextLayoutItem = NULL;
+ while (pCurLayoutItem) {
+ pNextLayoutItem = pCurLayoutItem->m_pNext;
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pCurLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ delete pCurLayoutItem;
+ pCurLayoutItem = pNextLayoutItem;
+ }
+ }
+ pGenerateNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pGenerateNode);
+}
+#endif
+void CXFA_ItemLayoutProcessor::XFA_ItemLayoutProcessor_GotoNextContainerNode(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pParentContainer, FX_BOOL bUsePageBreak)
+{
+ CXFA_Node *pEntireContainer = pParentContainer;
+ CXFA_Node* pChildContainer = XFA_LAYOUT_INVALIDNODE;
+ switch (nCurStage) {
+ case XFA_ItemLayoutProcessorStages_BreakBefore:
+ case XFA_ItemLayoutProcessorStages_BreakAfter: {
+ pChildContainer = pCurActionNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ break;
+ case XFA_ItemLayoutProcessorStages_Keep:
+ case XFA_ItemLayoutProcessorStages_Container:
+ pChildContainer = pCurActionNode;
+ break;
+ default:
+ pChildContainer = XFA_LAYOUT_INVALIDNODE;
+ break;
+ }
+ switch(nCurStage) {
+ case XFA_ItemLayoutProcessorStages_Keep: {
+ CXFA_Node *pBreakAfterNode = pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
+ return;
+ }
+ goto CheckNextChildContainer;
+ }
+ case XFA_ItemLayoutProcessorStages_None: {
+ pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+ case XFA_ItemLayoutProcessorStages_BookendLeader:
+ for(CXFA_Node *pBookendNode = pCurActionNode == XFA_LAYOUT_INVALIDNODE ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) :
+ pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pBookendNode; pBookendNode = pBookendNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ switch(pBookendNode->GetClassID()) {
+ case XFA_ELEMENT_Bookend:
+ case XFA_ELEMENT_Break:
+ pCurActionNode = pBookendNode;
+ nCurStage = XFA_ItemLayoutProcessorStages_BookendLeader;
+ return;
+ default:
+ break;
+ }
+ }
+ }
+ {
+ pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+ case XFA_ItemLayoutProcessorStages_BreakBefore:
+ if(pCurActionNode != XFA_LAYOUT_INVALIDNODE) {
+ CXFA_Node *pBreakBeforeNode = pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pBreakBeforeNode, pCurActionNode, nCurStage, TRUE)) {
+ return;
+ }
+ if(m_bIsProcessKeep) {
+ if(ProcessKeepNodesForBreakBefore(pCurActionNode, nCurStage, pChildContainer)) {
+ return;
+ }
+ goto CheckNextChildContainer;
+ }
+ pCurActionNode = pChildContainer;
+ nCurStage = XFA_ItemLayoutProcessorStages_Container;
+ return;
+ }
+ goto CheckNextChildContainer;
+ }
+ case XFA_ItemLayoutProcessorStages_Container: {
+ pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+ case XFA_ItemLayoutProcessorStages_BreakAfter: {
+ if(pCurActionNode == XFA_LAYOUT_INVALIDNODE) {
+ CXFA_Node *pBreakAfterNode = pChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
+ return;
+ }
+ } else {
+ CXFA_Node *pBreakAfterNode = pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ if(XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
+ return;
+ }
+ }
+ goto CheckNextChildContainer;
+ }
+ }
+CheckNextChildContainer: {
+ CXFA_Node *pNextChildContainer = pChildContainer == XFA_LAYOUT_INVALIDNODE ?
+ pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode) :
+ pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);
+ while(pNextChildContainer && pNextChildContainer->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {
+ CXFA_Node* pSaveNode = pNextChildContainer;
+ pNextChildContainer = pNextChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode);
+#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
+ if (pSaveNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+ XFA_DeleteLayoutGeneratedNode(pSaveNode);
+ }
+#endif
+ }
+ if(!pNextChildContainer) {
+ goto NoMoreChildContainer;
+ }
+ FX_BOOL bLastKeep = FALSE;
+ if(ProcessKeepNodesForCheckNext(pCurActionNode, nCurStage, pNextChildContainer, bLastKeep)) {
+ return;
+ }
+ if(!m_bKeepBreakFinish && !bLastKeep && XFA_ItemLayoutProcessor_FindBreakNode(pNextChildContainer->GetNodeItem(XFA_NODEITEM_FirstChild), pCurActionNode, nCurStage, TRUE)) {
+ return;
+ }
+ pCurActionNode = pNextChildContainer;
+ if(m_bIsProcessKeep) {
+ nCurStage = XFA_ItemLayoutProcessorStages_Keep;
+ } else {
+ nCurStage = XFA_ItemLayoutProcessorStages_Container;
+ }
+ return;
+ }
+NoMoreChildContainer: {
+ pCurActionNode = XFA_LAYOUT_INVALIDNODE;
+ case XFA_ItemLayoutProcessorStages_BookendTrailer:
+ for(CXFA_Node *pBookendNode = pCurActionNode == XFA_LAYOUT_INVALIDNODE ? pEntireContainer->GetNodeItem(XFA_NODEITEM_FirstChild) :
+ pCurActionNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pBookendNode; pBookendNode = pBookendNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ switch(pBookendNode->GetClassID()) {
+ case XFA_ELEMENT_Bookend:
+ case XFA_ELEMENT_Break:
+ pCurActionNode = pBookendNode;
+ nCurStage = XFA_ItemLayoutProcessorStages_BookendTrailer;
+ return;
+ default:
+ break;
+ }
+ }
+ }
+ default:
+ pCurActionNode = NULL;
+ nCurStage = XFA_ItemLayoutProcessorStages_Done;
+ }
+}
+FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node*& pNextContainer, FX_BOOL& bLastKeepNode)
+{
+ FX_BOOL bCanSplite = pNextContainer->GetIntact() == XFA_ATTRIBUTEENUM_None;
+ FX_BOOL bNextKeep = FALSE;
+ if(XFA_ExistContainerKeep(pNextContainer, FALSE)) {
+ bNextKeep = TRUE;
+ }
+ if(bNextKeep && !bCanSplite) {
+ if(!m_bIsProcessKeep && !m_bKeepBreakFinish) {
+ m_pKeepHeadNode = pNextContainer;
+ m_bIsProcessKeep = TRUE;
+ }
+ } else {
+ if(m_bIsProcessKeep && m_pKeepHeadNode != NULL) {
+ m_pKeepTailNode = pNextContainer;
+ if(!m_bKeepBreakFinish && XFA_ItemLayoutProcessor_FindBreakNode(pNextContainer->GetNodeItem(XFA_NODEITEM_FirstChild), pCurActionNode, nCurStage, TRUE)) {
+ return TRUE;
+ } else {
+ pNextContainer = m_pKeepHeadNode;
+ m_bKeepBreakFinish = TRUE;
+ m_pKeepHeadNode = NULL;
+ m_pKeepTailNode = NULL;
+ m_bIsProcessKeep = FALSE;
+ }
+ } else {
+ if(m_bKeepBreakFinish) {
+ bLastKeepNode = TRUE;
+ }
+ m_bKeepBreakFinish = FALSE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepNodesForBreakBefore(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pContainerNode)
+{
+ if(m_pKeepTailNode == pContainerNode) {
+ pCurActionNode = m_pKeepHeadNode;
+ m_bKeepBreakFinish = TRUE;
+ m_pKeepHeadNode = NULL;
+ m_pKeepTailNode = NULL;
+ m_bIsProcessKeep = FALSE;
+ nCurStage = XFA_ItemLayoutProcessorStages_Container;
+ return TRUE;
+ }
+ CXFA_Node *pBreakAfterNode = pContainerNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if(XFA_ItemLayoutProcessor_FindBreakNode(pBreakAfterNode, pCurActionNode, nCurStage, FALSE)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode)
+{
+ XFA_ATTRIBUTEENUM ePresence = pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+ return ePresence == XFA_ATTRIBUTEENUM_Visible || ePresence == XFA_ATTRIBUTEENUM_Invisible;
+}
+static inline void XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(CXFA_Node* pFormNode, FX_FLOAT& fContainerWidth, FX_FLOAT& fContainerHeight, FX_BOOL& bContainerWidthAutoSize, FX_BOOL& bContainerHeightAutoSize)
+{
+ fContainerWidth = 0;
+ fContainerHeight = 0;
+ bContainerWidthAutoSize = TRUE;
+ bContainerHeightAutoSize = TRUE;
+ XFA_ELEMENT eClassID = pFormNode->GetClassID();
+ CXFA_Measurement mTmpValue;
+ if(bContainerWidthAutoSize && (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) && pFormNode->TryMeasure(XFA_ATTRIBUTE_W, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+ fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
+ bContainerWidthAutoSize = FALSE;
+ }
+ if(bContainerHeightAutoSize && (eClassID == XFA_ELEMENT_Subform || eClassID == XFA_ELEMENT_ExclGroup) && pFormNode->TryMeasure(XFA_ATTRIBUTE_H, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+ fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
+ bContainerHeightAutoSize = FALSE;
+ }
+ if(bContainerWidthAutoSize && eClassID == XFA_ELEMENT_Subform && pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxW, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+ fContainerWidth = mTmpValue.ToUnit(XFA_UNIT_Pt);
+ bContainerWidthAutoSize = FALSE;
+ }
+ if(bContainerHeightAutoSize && eClassID == XFA_ELEMENT_Subform && pFormNode->TryMeasure(XFA_ATTRIBUTE_MaxH, mTmpValue, FALSE) && mTmpValue.GetValue() > XFA_LAYOUT_FLOAT_PERCISION) {
+ fContainerHeight = mTmpValue.ToUnit(XFA_UNIT_Pt);
+ bContainerHeightAutoSize = FALSE;
+ }
+}
+static inline void XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize
+(CXFA_Node* pFormNode, FX_BOOL bContainerWidthAutoSize, FX_FLOAT fContentCalculatedWidth, FX_FLOAT& fContainerWidth, FX_BOOL bContainerHeightAutoSize, FX_FLOAT fContentCalculatedHeight, FX_FLOAT& fContainerHeight)
+{
+ CXFA_Node* pMarginNode = pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ CXFA_Measurement mTmpValue;
+ if(bContainerWidthAutoSize) {
+ fContainerWidth = fContentCalculatedWidth;
+ if(pMarginNode) {
+ if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_LeftInset, mTmpValue, FALSE)) {
+ fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
+ }
+ if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_RightInset, mTmpValue, FALSE)) {
+ fContainerWidth += mTmpValue.ToUnit(XFA_UNIT_Pt);
+ }
+ }
+ }
+ if(bContainerHeightAutoSize) {
+ fContainerHeight = fContentCalculatedHeight;
+ if(pMarginNode) {
+ if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_TopInset, mTmpValue, FALSE)) {
+ fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
+ }
+ if(pMarginNode->TryMeasure(XFA_ATTRIBUTE_BottomInset, mTmpValue, FALSE)) {
+ fContainerHeight += mTmpValue.ToUnit(XFA_UNIT_Pt);
+ }
+ }
+ }
+}
+void CXFA_ItemLayoutProcessor::CalculatePositionedContainerPos(CXFA_Node* pNode, FX_FLOAT fWidth, FX_FLOAT fHeight, FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY)
+{
+ FX_FLOAT fAnchorX = pNode->GetMeasure(XFA_ATTRIBUTE_X).ToUnit(XFA_UNIT_Pt);
+ FX_FLOAT fAnchorY = pNode->GetMeasure(XFA_ATTRIBUTE_Y).ToUnit(XFA_UNIT_Pt);
+ FX_INT32 nRotate = FXSYS_round(pNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
+ nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360) / 90;
+ XFA_ATTRIBUTEENUM eAnchorType = pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);
+ FX_INT32 nAnchorType = 0;
+ switch(eAnchorType) {
+ case XFA_ATTRIBUTEENUM_TopLeft:
+ nAnchorType = 0;
+ break;
+ case XFA_ATTRIBUTEENUM_TopCenter:
+ nAnchorType = 1;
+ break;
+ case XFA_ATTRIBUTEENUM_TopRight:
+ nAnchorType = 2;
+ break;
+ case XFA_ATTRIBUTEENUM_MiddleLeft:
+ nAnchorType = 3;
+ break;
+ case XFA_ATTRIBUTEENUM_MiddleCenter:
+ nAnchorType = 4;
+ break;
+ case XFA_ATTRIBUTEENUM_MiddleRight:
+ nAnchorType = 5;
+ break;
+ case XFA_ATTRIBUTEENUM_BottomLeft:
+ nAnchorType = 6;
+ break;
+ case XFA_ATTRIBUTEENUM_BottomCenter:
+ nAnchorType = 7;
+ break;
+ case XFA_ATTRIBUTEENUM_BottomRight:
+ nAnchorType = 8;
+ break;
+ default:
+ break;
+ }
+ static const FX_UINT8 nNextPos[4][9] = {{0, 1, 2, 3, 4, 5, 6, 7, 8}, {6, 3, 0, 7, 4, 1, 8, 5, 2}, {8, 7, 6, 5, 4, 3, 2, 1, 0}, {2, 5, 8, 1, 4, 7, 0, 3, 6}};
+ FX_INT32 nAbsoluteAnchorType = nNextPos[nRotate][nAnchorType];
+ fAbsoluteX = fAnchorX;
+ fAbsoluteY = fAnchorY;
+ switch(nAbsoluteAnchorType / 3) {
+ case 1:
+ fAbsoluteY -= fHeight / 2;
+ break;
+ case 2:
+ fAbsoluteY -= fHeight;
+ break;
+ default:
+ break;
+ }
+ switch(nAbsoluteAnchorType % 3) {
+ case 1:
+ fAbsoluteX -= fWidth / 2;
+ break;
+ case 2:
+ fAbsoluteX -= fWidth;
+ break;
+ default:
+ break;
+ }
+}
+static FX_BOOL XFA_ItemLayoutProcessor_FloatAlmostEqual(FX_FLOAT f1, FX_FLOAT f2)
+{
+ return f1 >= f2 - XFA_LAYOUT_FLOAT_PERCISION && f1 <= f2 + XFA_LAYOUT_FLOAT_PERCISION;
+}
+static FX_BOOL XFA_ItemLayoutProcessor_FloatGreaterThan(FX_FLOAT f1, FX_FLOAT f2)
+{
+ return f1 > f2 + XFA_LAYOUT_FLOAT_PERCISION;
+}
+static FX_BOOL XFA_ItemLayoutProcessor_FloatLessThan(FX_FLOAT f1, FX_FLOAT f2)
+{
+ return f1 < f2 - XFA_LAYOUT_FLOAT_PERCISION;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor, CXFA_Node *pNode, CXFA_Node *pParentNode)
+{
+ return FALSE;
+}
+void CXFA_ItemLayoutProcessor::DoLayoutPageArea(CXFA_ContainerLayoutItemImpl* pPageAreaLayoutItem)
+{
+ CXFA_Node *pFormNode = pPageAreaLayoutItem->m_pFormNode;
+ CXFA_Node *pCurChildNode = XFA_LAYOUT_INVALIDNODE;
+ XFA_ItemLayoutProcessorStages nCurChildNodeStage = XFA_ItemLayoutProcessorStages_None;
+ CXFA_LayoutItemImpl* pBeforeItem = NULL;
+ for(XFA_ItemLayoutProcessor_GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode, FALSE);
+ pCurChildNode;
+ XFA_ItemLayoutProcessor_GotoNextContainerNode(pCurChildNode, nCurChildNodeStage, pFormNode, FALSE)) {
+ if (nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
+ continue;
+ }
+ if(pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
+ continue;
+ }
+ CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pCurChildNode, NULL);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
+ if(!pProcessor->HasLayoutItem()) {
+ delete pProcessor;
+ continue;
+ }
+ FX_FLOAT fWidth, fHeight;
+ pProcessor->GetCurrentComponentSize(fWidth, fHeight);
+ FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
+ CalculatePositionedContainerPos(pCurChildNode, fWidth, fHeight, fAbsoluteX, fAbsoluteY);
+ pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
+ CXFA_LayoutItemImpl* pProcessItem = pProcessor->ExtractLayoutItem();
+ if(pBeforeItem == NULL) {
+ pPageAreaLayoutItem->AddHeadChild(pProcessItem);
+ } else {
+ pPageAreaLayoutItem->InsertChild(pBeforeItem, pProcessItem);
+ }
+ pBeforeItem = pProcessItem;
+ delete pProcessor;
+ }
+ pBeforeItem = NULL;
+ CXFA_LayoutItemImpl* pLayoutItem = pPageAreaLayoutItem->m_pFirstChild;
+ while (pLayoutItem) {
+ if (!pLayoutItem->IsContentLayoutItem() || pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_Draw) {
+ pLayoutItem = pLayoutItem->m_pNextSibling;
+ continue;
+ }
+ if (pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_Draw) {
+ CXFA_LayoutItemImpl* pNextLayoutItem = pLayoutItem->m_pNextSibling;
+ pPageAreaLayoutItem->RemoveChild(pLayoutItem);
+ if (pBeforeItem == NULL) {
+ pPageAreaLayoutItem->AddHeadChild(pLayoutItem);
+ } else {
+ pPageAreaLayoutItem->InsertChild(pBeforeItem, pLayoutItem);
+ }
+ pBeforeItem = pLayoutItem;
+ pLayoutItem = pNextLayoutItem;
+ }
+ }
+}
+void CXFA_ItemLayoutProcessor::DoLayoutPositionedContainer(CXFA_LayoutContext* pContext)
+{
+ if(m_pLayoutItem != NULL) {
+ return;
+ }
+ m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+ FX_BOOL bIgnoreXY = (m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) != XFA_ATTRIBUTEENUM_Position);
+ FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+ FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+ XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);
+ FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+ FX_FLOAT fHiddenContentCalculatedWidth = 0, fHiddenContentCalculatedHeight = 0;
+ if(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
+ XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
+ }
+ FX_INT32 iColIndex = 0;
+ for(; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
+ if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
+ continue;
+ }
+ if(m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
+ continue;
+ }
+ CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ if (pContext && pContext->m_prgSpecifiedColumnWidths) {
+ FX_INT32 iColSpan = m_pCurChildNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+ if (iColSpan <= pContext->m_prgSpecifiedColumnWidths->GetSize() - iColIndex) {
+ pContext->m_fCurColumnWidth = 0;
+ pContext->m_bCurColumnWidthAvaiable = TRUE;
+ if(iColSpan == -1) {
+ iColSpan = pContext->m_prgSpecifiedColumnWidths->GetSize();
+ }
+ for (FX_INT32 i = 0; i < iColSpan; i++) {
+ pContext->m_fCurColumnWidth += pContext->m_prgSpecifiedColumnWidths->GetAt(iColIndex + i);
+ }
+ if(pContext->m_fCurColumnWidth == 0) {
+ pContext->m_bCurColumnWidthAvaiable = FALSE;
+ }
+ iColIndex += iColSpan;
+ }
+ }
+ pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, pContext);
+ if(!pProcessor->HasLayoutItem()) {
+ delete pProcessor;
+ continue;
+ }
+ FX_FLOAT fWidth, fHeight;
+ pProcessor->GetCurrentComponentSize(fWidth, fHeight);
+ FX_BOOL bChangeParentSize = FALSE;
+ if (XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
+ bChangeParentSize = TRUE;
+ }
+ FX_FLOAT fAbsoluteX = 0, fAbsoluteY = 0;
+ if(!bIgnoreXY) {
+ CalculatePositionedContainerPos(m_pCurChildNode, fWidth, fHeight, fAbsoluteX, fAbsoluteY);
+ }
+ pProcessor->SetCurrentComponentPos(fAbsoluteX, fAbsoluteY);
+ if(bContainerWidthAutoSize) {
+ FX_FLOAT fChildSuppliedWidth = fAbsoluteX + fWidth;
+ if(bChangeParentSize) {
+ if(fContentCalculatedWidth < fChildSuppliedWidth) {
+ fContentCalculatedWidth = fChildSuppliedWidth;
+ }
+ } else {
+ if(fHiddenContentCalculatedWidth < fChildSuppliedWidth && m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
+ fHiddenContentCalculatedWidth = fChildSuppliedWidth;
+ }
+ }
+ }
+ if(bContainerHeightAutoSize) {
+ FX_FLOAT fChildSuppliedHeight = fAbsoluteY + fHeight;
+ if(bChangeParentSize) {
+ if(fContentCalculatedHeight < fChildSuppliedHeight) {
+ fContentCalculatedHeight = fChildSuppliedHeight;
+ }
+ } else {
+ if(fHiddenContentCalculatedHeight < fChildSuppliedHeight && m_pCurChildNode->GetClassID() != XFA_ELEMENT_Subform) {
+ fHiddenContentCalculatedHeight = fChildSuppliedHeight;
+ }
+ }
+ }
+ m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
+ delete pProcessor;
+ }
+ XFA_VERSION eVersion = m_pFormNode->GetDocument()->GetCurVersionMode();
+ if(fContentCalculatedWidth == 0 && eVersion < XFA_VERSION_207) {
+ fContentCalculatedWidth = fHiddenContentCalculatedWidth;
+ }
+ if(fContentCalculatedHeight == 0 && eVersion < XFA_VERSION_207) {
+ fContentCalculatedHeight = fHiddenContentCalculatedHeight;
+ }
+ XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);
+ SetCurrentComponentSize(fContainerWidth, fContainerHeight);
+}
+static inline void XFA_ItemLayoutProcessor_UpdateWidgetSize(CXFA_ContentLayoutItemImpl* pLayoutItem, FX_FLOAT& fWidth, FX_FLOAT& fHeight)
+{
+ CXFA_Node *pNode = pLayoutItem->m_pFormNode;
+ ASSERT(pNode);
+ XFA_ELEMENT eClassID = pNode->GetClassID();
+ switch(eClassID) {
+ case XFA_ELEMENT_Subform:
+ case XFA_ELEMENT_Area:
+ case XFA_ELEMENT_ExclGroup:
+ case XFA_ELEMENT_SubformSet: {
+ if(fWidth < -XFA_LAYOUT_FLOAT_PERCISION) {
+ fWidth = pLayoutItem->m_sSize.x;
+ }
+ if(fHeight < -XFA_LAYOUT_FLOAT_PERCISION) {
+ fHeight = pLayoutItem->m_sSize.y;
+ }
+ break;
+ }
+ case XFA_ELEMENT_Draw:
+ case XFA_ELEMENT_Field: {
+ pNode->GetDocument()->GetParser()->GetNotify()->StartFieldDrawLayout(pNode, fWidth, fHeight);
+ break;
+ }
+ default:
+ ASSERT(FALSE);
+ }
+}
+static inline void XFA_ItemLayoutProcessor_RelocateTableRowCells(CXFA_ContentLayoutItemImpl* pLayoutRow, const CFX_ArrayTemplate<FX_FLOAT>& rgSpecifiedColumnWidths, XFA_ATTRIBUTEENUM eLayout)
+{
+ FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+ FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+ XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(pLayoutRow->m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);
+ CXFA_Node* pMarginNode = pLayoutRow->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+ if(pMarginNode) {
+ fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+ fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+ fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+ fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+ }
+ FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;
+ FX_FLOAT fContentCurrentHeight = pLayoutRow->m_sSize.y - fTopInset - fBottomInset;
+ FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+ FX_FLOAT fCurrentColX = 0;
+ FX_INT32 nCurrentColIdx = 0;
+ FX_BOOL bMetWholeRowCell = FALSE;
+ for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {
+ FX_INT32 nOriginalColSpan = pLayoutChild->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+ FX_INT32 nColSpan = nOriginalColSpan;
+ FX_FLOAT fColSpanWidth = 0;
+ if(nColSpan == -1 || nCurrentColIdx + nColSpan > rgSpecifiedColumnWidths.GetSize()) {
+ nColSpan = rgSpecifiedColumnWidths.GetSize() - nCurrentColIdx;
+ }
+ for(FX_INT32 i = 0; i < nColSpan; i ++) {
+ fColSpanWidth += rgSpecifiedColumnWidths[nCurrentColIdx + i];
+ }
+ if (nColSpan != nOriginalColSpan) {
+ fColSpanWidth = bMetWholeRowCell ? 0 : FX_MAX(fColSpanWidth, pLayoutChild->m_sSize.y);
+ }
+ if(nOriginalColSpan == -1) {
+ bMetWholeRowCell = TRUE;
+ }
+ pLayoutChild->m_sPos.Set(fCurrentColX, 0);
+ pLayoutChild->m_sSize.x = fColSpanWidth;
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
+ fCurrentColX += fColSpanWidth;
+ nCurrentColIdx += nColSpan;
+ FX_FLOAT fNewHeight = bContainerHeightAutoSize ? -1 : fContentCurrentHeight;
+ XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, fColSpanWidth, fNewHeight);
+ pLayoutChild->m_sSize.y = fNewHeight;
+ if(bContainerHeightAutoSize) {
+ FX_FLOAT fChildSuppliedHeight = pLayoutChild->m_sSize.y;
+ if(fContentCalculatedHeight < fChildSuppliedHeight) {
+ fContentCalculatedHeight = fChildSuppliedHeight;
+ }
+ }
+ }
+ }
+ if(bContainerHeightAutoSize) {
+ for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {
+ XFA_ItemLayoutProcessor_UpdateWidgetSize(pLayoutChild, pLayoutChild->m_sSize.x, fContentCalculatedHeight);
+ FX_FLOAT fOldChildHeight = pLayoutChild->m_sSize.y;
+ pLayoutChild->m_sSize.y = fContentCalculatedHeight;
+ CXFA_Node* pParaNode = pLayoutChild->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Para);
+ if(pParaNode && pLayoutChild->m_pFirstChild) {
+ FX_FLOAT fOffHeight = fContentCalculatedHeight - fOldChildHeight;
+ XFA_ATTRIBUTEENUM eVType = pParaNode->GetEnum(XFA_ATTRIBUTE_VAlign);
+ switch(eVType) {
+ case XFA_ATTRIBUTEENUM_Middle:
+ fOffHeight = fOffHeight / 2;
+ break;
+ case XFA_ATTRIBUTEENUM_Bottom:
+ break;
+ case XFA_ATTRIBUTEENUM_Top:
+ default:
+ fOffHeight = 0;
+ break;
+ }
+ if(fOffHeight > 0) {
+ for(CXFA_ContentLayoutItemImpl* pInnerLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pFirstChild; pInnerLayoutChild; pInnerLayoutChild = (CXFA_ContentLayoutItemImpl*)pInnerLayoutChild->m_pNextSibling) {
+ pInnerLayoutChild->m_sPos.y += fOffHeight;
+ }
+ }
+ }
+ }
+ }
+ if(bContainerWidthAutoSize) {
+ FX_FLOAT fChildSuppliedWidth = fCurrentColX;
+ if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {
+ fChildSuppliedWidth = fContentWidthLimit;
+ }
+ if (fContentCalculatedWidth < fChildSuppliedWidth) {
+ fContentCalculatedWidth = fChildSuppliedWidth;
+ }
+ } else {
+ fContentCalculatedWidth = fContainerWidth - fLeftInset - fRightInset;
+ }
+ if(pLayoutRow->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout) == XFA_ATTRIBUTEENUM_Rl_row) {
+ for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutRow->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {
+ pLayoutChild->m_sPos.x = fContentCalculatedWidth - pLayoutChild->m_sPos.x - pLayoutChild->m_sSize.x;
+ }
+ }
+ XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(pLayoutRow->m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);
+ pLayoutRow->m_sSize.Set(fContainerWidth, fContainerHeight);
+}
+void CXFA_ItemLayoutProcessor::DoLayoutTableContainer(CXFA_Node* pLayoutNode)
+{
+ if(m_pLayoutItem != NULL) {
+ return;
+ }
+ if(pLayoutNode == NULL) {
+ pLayoutNode = m_pFormNode;
+ }
+ ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
+ m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+ FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+ FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+ XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);
+ FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+ CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+ if(pMarginNode) {
+ fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+ fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+ fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+ fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+ }
+ FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;
+ CFX_WideStringC wsColumnWidths;
+ if (pLayoutNode->TryCData(XFA_ATTRIBUTE_ColumnWidths, wsColumnWidths)) {
+ CFX_WideStringArray widths;
+ if (FX_SeparateStringW(wsColumnWidths.GetPtr(), wsColumnWidths.GetLength(), L' ', widths) > 0) {
+ FX_INT32 iCols = widths.GetSize();
+ CFX_WideString wsWidth;
+ for (FX_INT32 i = 0; i < iCols; i++) {
+ wsWidth = widths[i];
+ wsWidth.TrimLeft(L' ');
+ if (!wsWidth.IsEmpty()) {
+ CXFA_Measurement measure(wsWidth);
+ m_rgSpecifiedColumnWidths.Add(measure.ToUnit(XFA_UNIT_Pt));
+ }
+ }
+ }
+ }
+ FX_INT32 iSpecifiedColumnCount = m_rgSpecifiedColumnWidths.GetSize();
+ CXFA_LayoutContext layoutContext;
+ layoutContext.m_prgSpecifiedColumnWidths = &m_rgSpecifiedColumnWidths;
+ CXFA_LayoutContext* pLayoutContext = iSpecifiedColumnCount > 0 ? &layoutContext : NULL;
+ if(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE) {
+ XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE);
+ }
+ for(; m_pCurChildNode; XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, FALSE)) {
+ layoutContext.m_bCurColumnWidthAvaiable = FALSE;
+ layoutContext.m_fCurColumnWidth = 0;
+ if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Container) {
+ continue;
+ }
+ CXFA_ItemLayoutProcessor* pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ pProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, pLayoutContext);
+ if(!pProcessor->HasLayoutItem()) {
+ delete pProcessor;
+ continue;
+ }
+ m_pLayoutItem->AddChild(pProcessor->ExtractLayoutItem());
+ delete pProcessor;
+ }
+ FX_INT32 iRowCount = 0, iColCount = 0;
+ {
+ CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> rgRowItems;
+ CFX_ArrayTemplate<FX_INT32> rgRowItemsSpan;
+ CFX_ArrayTemplate<FX_FLOAT> rgRowItemsWidth;
+ for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {
+ if(pLayoutChild->m_pFormNode->GetClassID() != XFA_ELEMENT_Subform) {
+ continue;
+ }
+ if(!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
+ continue;
+ }
+ XFA_ATTRIBUTEENUM eLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ if(eLayout != XFA_ATTRIBUTEENUM_Row && eLayout != XFA_ATTRIBUTEENUM_Rl_row) {
+ continue;
+ }
+ if (CXFA_ContentLayoutItemImpl* pRowLayoutCell = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pFirstChild) {
+ rgRowItems.Add(pRowLayoutCell);
+ FX_INT32 iColSpan = pRowLayoutCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+ rgRowItemsSpan.Add(iColSpan);
+ rgRowItemsWidth.Add(pRowLayoutCell->m_sSize.x);
+ }
+ }
+ iRowCount = rgRowItems.GetSize();
+ iColCount = 0;
+ FX_BOOL bMoreColumns = TRUE;
+ while(bMoreColumns) {
+ bMoreColumns = FALSE;
+ FX_BOOL bAutoCol = FALSE;
+ for(FX_INT32 i = 0; i < iRowCount; i ++) {
+ while(rgRowItems[i] != NULL && (rgRowItemsSpan[i] <= 0 || !XFA_ItemLayoutProcessor_IsTakingSpace(rgRowItems[i]->m_pFormNode))) {
+ CXFA_ContentLayoutItemImpl* pNewCell = (CXFA_ContentLayoutItemImpl*)rgRowItems[i]->m_pNextSibling;
+ if(rgRowItemsSpan[i] < 0 && XFA_ItemLayoutProcessor_IsTakingSpace(rgRowItems[i]->m_pFormNode)) {
+ pNewCell = NULL;
+ }
+ rgRowItems[i] = pNewCell;
+ rgRowItemsSpan[i] = pNewCell ? pNewCell->m_pFormNode->GetInteger(XFA_ATTRIBUTE_ColSpan) : 0;
+ rgRowItemsWidth[i] = pNewCell ? pNewCell->m_sSize.x : 0;
+ }
+ CXFA_ContentLayoutItemImpl* pCell = rgRowItems[i];
+ if(!pCell) {
+ continue;
+ }
+ bMoreColumns = TRUE;
+ if (rgRowItemsSpan[i] == 1) {
+ if (iColCount >= iSpecifiedColumnCount) {
+ for (FX_INT32 j = 0, c = iColCount + 1 - m_rgSpecifiedColumnWidths.GetSize(); j < c; j ++) {
+ m_rgSpecifiedColumnWidths.Add(0);
+ }
+ }
+ if (m_rgSpecifiedColumnWidths[iColCount] < XFA_LAYOUT_FLOAT_PERCISION) {
+ bAutoCol = TRUE;
+ }
+ if (bAutoCol && m_rgSpecifiedColumnWidths[iColCount] < rgRowItemsWidth[i]) {
+ m_rgSpecifiedColumnWidths[iColCount] = rgRowItemsWidth[i];
+ }
+ }
+ }
+ if(bMoreColumns) {
+ FX_FLOAT fFinalColumnWidth = m_rgSpecifiedColumnWidths[iColCount];
+ for(FX_INT32 i = 0; i < iRowCount; i ++) {
+ if(!rgRowItems[i]) {
+ continue;
+ }
+ rgRowItemsSpan[i]--;
+ rgRowItemsWidth[i] -= fFinalColumnWidth;
+ }
+ iColCount ++;
+ }
+ }
+ }
+ FX_FLOAT fCurrentRowY = 0;
+ for(CXFA_ContentLayoutItemImpl* pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutChild; pLayoutChild = (CXFA_ContentLayoutItemImpl*)pLayoutChild->m_pNextSibling) {
+ if(!XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutChild->m_pFormNode)) {
+ continue;
+ }
+ if(pLayoutChild->m_pFormNode->GetClassID() == XFA_ELEMENT_Subform) {
+ XFA_ATTRIBUTEENUM eSubformLayout = pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ if(eSubformLayout == XFA_ATTRIBUTEENUM_Row || eSubformLayout == XFA_ATTRIBUTEENUM_Rl_row) {
+ XFA_ItemLayoutProcessor_RelocateTableRowCells(pLayoutChild, m_rgSpecifiedColumnWidths, eSubformLayout);
+ }
+ }
+ pLayoutChild->m_sPos.y = fCurrentRowY;
+ if(bContainerWidthAutoSize) {
+ pLayoutChild->m_sPos.x = 0;
+ } else {
+ switch(pLayoutChild->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
+ case XFA_ATTRIBUTEENUM_Left:
+ default:
+ pLayoutChild->m_sPos.x = 0;
+ break;
+ case XFA_ATTRIBUTEENUM_Center:
+ pLayoutChild->m_sPos.x = (fContentWidthLimit - pLayoutChild->m_sSize.x) / 2 ;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ pLayoutChild->m_sPos.x = fContentWidthLimit - pLayoutChild->m_sSize.x;
+ break;
+ }
+ }
+ if(bContainerWidthAutoSize) {
+ FX_FLOAT fChildSuppliedWidth = pLayoutChild->m_sPos.x + pLayoutChild->m_sSize.x;
+ if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {
+ fChildSuppliedWidth = fContentWidthLimit;
+ }
+ if (fContentCalculatedWidth < fChildSuppliedWidth) {
+ fContentCalculatedWidth = fChildSuppliedWidth;
+ }
+ }
+ fCurrentRowY += pLayoutChild->m_sSize.y;
+ }
+ if(bContainerHeightAutoSize) {
+ FX_FLOAT fChildSuppliedHeight = fCurrentRowY;
+ if(fContentCalculatedHeight < fChildSuppliedHeight) {
+ fContentCalculatedHeight = fChildSuppliedHeight;
+ }
+ }
+ XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);
+ SetCurrentComponentSize(fContainerWidth, fContainerHeight);
+}
+static FX_UINT8 XFA_ItemLayoutProcessor_HAlignEnumToInt(XFA_ATTRIBUTEENUM eHAlign)
+{
+ switch(eHAlign) {
+ case XFA_ATTRIBUTEENUM_Center:
+ return 1;
+ case XFA_ATTRIBUTEENUM_Right:
+ return 2;
+ case XFA_ATTRIBUTEENUM_Left:
+ default:
+ return 0;
+ }
+}
+static void XFA_ItemLayoutProcessor_UpdatePendedItemLayout(CXFA_ItemLayoutProcessor* pProcessor, CXFA_ContentLayoutItemImpl* pLayoutItem)
+{
+ XFA_ATTRIBUTEENUM eLayout = pLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ switch(eLayout) {
+ case XFA_ATTRIBUTEENUM_Row:
+ case XFA_ATTRIBUTEENUM_Rl_row:
+ XFA_ItemLayoutProcessor_RelocateTableRowCells(pLayoutItem, pProcessor->m_rgSpecifiedColumnWidths, eLayout);
+ break;
+ default:
+ break;
+ }
+}
+FX_BOOL CXFA_ItemLayoutProcessor::IsAddNewRowForTrailer(CXFA_ContentLayoutItemImpl* pTrailerItem)
+{
+ if(!pTrailerItem) {
+ return FALSE;
+ }
+ FX_FLOAT fWidth = pTrailerItem->m_sSize.x;
+ XFA_ATTRIBUTEENUM eLayout = m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ if(eLayout != XFA_ATTRIBUTEENUM_Tb && m_fWidthLimite > fWidth) {
+ return FALSE;
+ }
+ return TRUE;
+}
+static void XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(CXFA_ItemLayoutProcessor* pProcessor, FX_FLOAT fSplitPos, CXFA_ContentLayoutItemImpl* pTrailerLayoutItem, FX_BOOL bUseInherited = FALSE)
+{
+ if(!pTrailerLayoutItem) {
+ return;
+ }
+ FX_FLOAT fHeight = pTrailerLayoutItem->m_sSize.y;
+ if(bUseInherited) {
+ FX_FLOAT fNewSplitPos = 0;
+ if(fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
+ fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
+ }
+ if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+ pProcessor->SplitLayoutItem(fNewSplitPos);
+ }
+ return;
+ }
+ XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pTrailerLayoutItem);
+ CXFA_Node* pMarginNode = pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+ if(pMarginNode) {
+ fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+ fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+ fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+ fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+ }
+ FX_FLOAT fWidth = pTrailerLayoutItem->m_sSize.x;
+ XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ if(!pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem)) {
+ pTrailerLayoutItem->m_sPos.y = pProcessor->m_fLastRowY;
+ pTrailerLayoutItem->m_sPos.x = pProcessor->m_fLastRowWidth;
+ pProcessor->m_pLayoutItem->m_sSize.x += pTrailerLayoutItem->m_sSize.x;
+ pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
+ return;
+ }
+ FX_FLOAT fNewSplitPos = 0;
+ if(fSplitPos - fHeight > XFA_LAYOUT_FLOAT_PERCISION) {
+ fNewSplitPos = pProcessor->FindSplitPos(fSplitPos - fHeight);
+ }
+ if (fNewSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+ pProcessor->SplitLayoutItem(fNewSplitPos);
+ pTrailerLayoutItem->m_sPos.y = fNewSplitPos - fTopInset - fBottomInset;
+ } else {
+ pTrailerLayoutItem->m_sPos.y = fSplitPos - fTopInset - fBottomInset;
+ }
+ switch(pTrailerLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
+ case XFA_ATTRIBUTEENUM_Left:
+ default:
+ pTrailerLayoutItem->m_sPos.x = fLeftInset;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ pTrailerLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - fRightInset - pTrailerLayoutItem->m_sSize.x;
+ break;
+ case XFA_ATTRIBUTEENUM_Center:
+ pTrailerLayoutItem->m_sPos.x = (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - pTrailerLayoutItem->m_sSize.x) / 2;
+ break;
+ }
+ pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
+ pProcessor->m_pLayoutItem->AddChild(pTrailerLayoutItem);
+};
+static void XFA_ItemLayoutProcessor_AddLeaderAfterSplit(CXFA_ItemLayoutProcessor* pProcessor, CXFA_ContentLayoutItemImpl* pLeaderLayoutItem)
+{
+ XFA_ItemLayoutProcessor_UpdatePendedItemLayout(pProcessor, pLeaderLayoutItem);
+ CXFA_Node* pMarginNode = pProcessor->m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+ if(pMarginNode) {
+ fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+ fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+ fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+ fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+ }
+ FX_FLOAT fHeight = pLeaderLayoutItem->m_sSize.y;
+ for (CXFA_ContentLayoutItemImpl* pChildItem = (CXFA_ContentLayoutItemImpl*)pProcessor->m_pLayoutItem->m_pFirstChild; pChildItem; pChildItem = (CXFA_ContentLayoutItemImpl*)pChildItem->m_pNextSibling) {
+ pChildItem->m_sPos.y += fHeight;
+ }
+ pLeaderLayoutItem->m_sPos.y = 0;
+ switch(pLeaderLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign)) {
+ case XFA_ATTRIBUTEENUM_Left:
+ default:
+ pLeaderLayoutItem->m_sPos.x = fLeftInset;
+ break;
+ case XFA_ATTRIBUTEENUM_Right:
+ pLeaderLayoutItem->m_sPos.x = pProcessor->m_pLayoutItem->m_sSize.x - fRightInset - pLeaderLayoutItem->m_sSize.x;
+ break;
+ case XFA_ATTRIBUTEENUM_Center:
+ pLeaderLayoutItem->m_sPos.x = (pProcessor->m_pLayoutItem->m_sSize.x - fLeftInset - fRightInset - pLeaderLayoutItem->m_sSize.x) / 2;
+ break;
+ }
+ pProcessor->m_pLayoutItem->m_sSize.y += fHeight;
+ pProcessor->m_pLayoutItem->AddChild(pLeaderLayoutItem);
+};
+static void XFA_ItemLayoutProcessor_AddPendingNode(CXFA_ItemLayoutProcessor* pProcessor, CXFA_Node* pPendingNode, FX_BOOL bBreakPending)
+{
+ pProcessor->m_rgPendingNodes.AddTail(pPendingNode);
+ pProcessor->m_bBreakPending = bBreakPending;
+}
+static FX_FLOAT XFA_ItemLayoutProcessor_InsertPendingItems(CXFA_ItemLayoutProcessor* pProcessor, CXFA_Node* pCurChildNode)
+{
+ FX_FLOAT fTotalHeight = 0;
+ if(pProcessor->m_rgPendingNodes.GetCount() < 1) {
+ return fTotalHeight;
+ }
+ if(pProcessor->m_pLayoutItem == NULL) {
+ pProcessor->m_pLayoutItem = pProcessor->CreateContentLayoutItem(pCurChildNode);
+ pProcessor->m_pLayoutItem->m_sSize.Set(0, 0);
+ }
+ while(pProcessor->m_rgPendingNodes.GetCount() > 0) {
+ FX_POSITION pos = pProcessor->m_rgPendingNodes.GetHeadPosition();
+ CXFA_Node* pPendingNode = (CXFA_Node*)pProcessor->m_rgPendingNodes.GetAt(pos);
+ pProcessor->m_rgPendingNodes.RemoveAt(pos);
+ CXFA_ContentLayoutItemImpl* pPendingLayoutItem = NULL;
+ CXFA_ItemLayoutProcessor *pPendingProcessor = FX_NEW CXFA_ItemLayoutProcessor(pPendingNode, NULL);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pPendingProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;
+#endif
+ pPendingProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
+ pPendingLayoutItem = pPendingProcessor->HasLayoutItem() ? pPendingProcessor->ExtractLayoutItem() : NULL;
+ delete pPendingProcessor;
+ if(pPendingLayoutItem) {
+ XFA_ItemLayoutProcessor_AddLeaderAfterSplit(pProcessor, pPendingLayoutItem);
+ if(pProcessor->m_bBreakPending) {
+ fTotalHeight += pPendingLayoutItem->m_sSize.y;
+ }
+ }
+ }
+ return fTotalHeight;
+}
+FX_FLOAT CXFA_ItemLayoutProcessor::InsertKeepLayoutItems()
+{
+ FX_FLOAT fTotalHeight = 0;
+ if(m_arrayKeepItems.GetSize()) {
+ if(m_pLayoutItem == NULL) {
+ m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+ m_pLayoutItem->m_sSize.Set(0, 0);
+ }
+ for(FX_INT32 iIndex = m_arrayKeepItems.GetSize() - 1; iIndex >= 0 ; iIndex --) {
+ XFA_ItemLayoutProcessor_AddLeaderAfterSplit(this, m_arrayKeepItems[iIndex]);
+ fTotalHeight += m_arrayKeepItems[iIndex]->m_sSize.y;
+ }
+ m_arrayKeepItems.RemoveAll();
+ }
+ return fTotalHeight;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::ProcessKeepForSplite(CXFA_ItemLayoutProcessor* pParentProcessor, CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue,
+ CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>& rgCurLineLayoutItem, FX_FLOAT& fContentCurRowAvailWidth,
+ FX_FLOAT& fContentCurRowHeight, FX_FLOAT& fContentCurRowY, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, XFA_ItemLayoutProcessorResult& result)
+{
+ if(pParentProcessor == NULL || pChildProcessor == NULL) {
+ return FALSE;
+ }
+ if(pParentProcessor->m_pCurChildNode->GetIntact() != XFA_ATTRIBUTEENUM_None || !pChildProcessor->m_bHasAvailHeight) {
+ if(XFA_ExistContainerKeep(pParentProcessor->m_pCurChildNode, TRUE)) {
+ FX_FLOAT fChildWidth, fChildHeight;
+ pChildProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+ CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> keepLayoutItems;
+ if(pParentProcessor->JudgePutNextPage(pParentProcessor->m_pLayoutItem, fChildHeight, keepLayoutItems)) {
+ m_arrayKeepItems.RemoveAll();
+ for(FX_INT32 iIndex = 0; iIndex < keepLayoutItems.GetSize(); iIndex++) {
+ CXFA_ContentLayoutItemImpl* pItem = keepLayoutItems.GetAt(iIndex);
+ pParentProcessor->m_pLayoutItem->RemoveChild(pItem);
+ fContentCurRowY -= pItem->m_sSize.y;
+ m_arrayKeepItems.Add(pItem);
+ }
+ bAddedItemInRow = TRUE;
+ bForceEndPage = TRUE;
+ result = XFA_ItemLayoutProcessorResult_PageFullBreak;
+ return TRUE;
+ }
+ rgCurLineLayoutItem.Add(pChildProcessor->ExtractLayoutItem());
+ bAddedItemInRow = TRUE;
+ fContentCurRowAvailWidth -= fChildWidth;
+ if(fContentCurRowHeight < fChildHeight ) {
+ fContentCurRowHeight = fChildHeight;
+ }
+ result = eRetValue;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_ItemLayoutProcessor::JudgePutNextPage(CXFA_ContentLayoutItemImpl* pParentLayoutItem, FX_FLOAT fChildHeight, CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> &pKeepItems)
+{
+ if(pParentLayoutItem == NULL) {
+ return FALSE;
+ }
+ FX_FLOAT fItemsHeight = 0;
+ for(CXFA_ContentLayoutItemImpl* pChildLayoutItem = (CXFA_ContentLayoutItemImpl*)pParentLayoutItem->m_pFirstChild; pChildLayoutItem; pChildLayoutItem = (CXFA_ContentLayoutItemImpl*)pChildLayoutItem->m_pNextSibling) {
+ if(XFA_ExistContainerKeep(pChildLayoutItem->m_pFormNode, FALSE)) {
+ pKeepItems.Add(pChildLayoutItem);
+ fItemsHeight += pChildLayoutItem->m_sSize.y;
+ } else {
+ pKeepItems.RemoveAll();
+ fItemsHeight = 0;
+ }
+ }
+ fItemsHeight += fChildHeight;
+ if(m_pPageMgr->GetNextAvailContentHeight(fItemsHeight)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+void CXFA_ItemLayoutProcessor::ProcessUnUseBinds(CXFA_Node* pFormNode)
+{
+ if(!pFormNode) {
+ return;
+ }
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pFormNode);
+ for(CXFA_Node *pNode = sIterator.MoveToNext(); pNode; pNode = sIterator.MoveToNext()) {
+ if(pNode->IsContainerNode()) {
+ CXFA_Node* pBindNode = pNode->GetBindData();
+ if (pBindNode) {
+ pBindNode->RemoveBindItem(pNode);
+ pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+ }
+ }
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+ }
+}
+void CXFA_ItemLayoutProcessor::ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, CXFA_ContentLayoutItemImpl* pTrailerItem, CXFA_Node* pFormNode)
+{
+ ProcessUnUseBinds(pLeaderNode);
+ ProcessUnUseBinds(pTrailerNode);
+ if(pFormNode == NULL) {
+ return;
+ }
+ if(pFormNode->GetClassID() == XFA_ELEMENT_Overflow || pFormNode->GetClassID() == XFA_ELEMENT_Break) {
+ pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ if(pLeaderNode && pFormNode) {
+ pFormNode->RemoveChild(pLeaderNode);
+ }
+ if(pTrailerNode && pFormNode) {
+ pFormNode->RemoveChild(pTrailerNode);
+ }
+ if(pTrailerItem) {
+ XFA_ReleaseLayoutItem(pTrailerItem);
+ }
+}
+static XFA_ItemLayoutProcessorResult XFA_ItemLayoutProcessor_InsertFlowedItem(CXFA_ItemLayoutProcessor* pThis, CXFA_ItemLayoutProcessor*& pProcessor,
+ FX_BOOL bContainerWidthAutoSize, FX_BOOL bContainerHeightAutoSize, FX_FLOAT fContainerHeight, XFA_ATTRIBUTEENUM eFlowStrategy, FX_UINT8& uCurHAlignState, CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> (&rgCurLineLayoutItems)[3],
+ FX_BOOL bUseBreakControl, FX_FLOAT fAvailHeight, FX_FLOAT fRealHeight, FX_FLOAT& fContentCurRowY, FX_FLOAT& fContentWidthLimit, FX_FLOAT& fContentCurRowAvailWidth,
+ FX_FLOAT& fContentCurRowHeight, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, CXFA_LayoutContext* pLayoutContext = NULL, FX_BOOL bNewRow = FALSE)
+{
+ FX_BOOL bTakeSpace = XFA_ItemLayoutProcessor_IsTakingSpace(pProcessor->m_pFormNode);
+ FX_UINT8 uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(pThis->m_pCurChildNode->GetEnum(XFA_ATTRIBUTE_HAlign));
+ if(bContainerWidthAutoSize) {
+ uHAlign = 0;
+ }
+ if((eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb && uHAlign < uCurHAlignState) || (eFlowStrategy == XFA_ATTRIBUTEENUM_Rl_tb && uHAlign > uCurHAlignState)) {
+ return XFA_ItemLayoutProcessorResult_RowFullBreak;
+ }
+ uCurHAlignState = uHAlign;
+ FX_BOOL bIsOwnSplite = pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None;
+ FX_BOOL bUseRealHeight = bTakeSpace && bContainerHeightAutoSize && bIsOwnSplite
+ && pProcessor->m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetIntact() == XFA_ATTRIBUTEENUM_None;
+ FX_BOOL bIsTransHeight = bTakeSpace;
+ if(bIsTransHeight && !bIsOwnSplite) {
+ FX_BOOL bRootForceTb = FALSE;
+ XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(pProcessor->m_pFormNode, bRootForceTb);
+ if(eLayoutStrategy == XFA_ATTRIBUTEENUM_Lr_tb || eLayoutStrategy == XFA_ATTRIBUTEENUM_Rl_tb) {
+ bIsTransHeight = FALSE;
+ }
+ }
+ FX_BOOL bUseInherited = FALSE;
+ CXFA_LayoutContext layoutContext;
+ if (pThis->m_pPageMgr) {
+ CXFA_Node* pOverflowNode = pThis->m_pPageMgr->QueryOverflow(pThis->m_pFormNode);
+ if(pOverflowNode) {
+ layoutContext.m_pOverflowNode = pOverflowNode;
+ layoutContext.m_pOverflowProcessor = pThis;
+ pLayoutContext = &layoutContext;
+ }
+ }
+ XFA_ItemLayoutProcessorResult eRetValue = XFA_ItemLayoutProcessorResult_Done;
+ if(!bNewRow || pProcessor->m_ePreProcessRs == XFA_ItemLayoutProcessorResult_Done) {
+ eRetValue = pProcessor->DoLayout(bTakeSpace ? bUseBreakControl : FALSE, bUseRealHeight ?
+ fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, bIsTransHeight ? fRealHeight - fContentCurRowY : XFA_LAYOUT_FLOAT_MAX, pLayoutContext);
+ pProcessor->m_ePreProcessRs = eRetValue;
+ } else {
+ eRetValue = pProcessor->m_ePreProcessRs;
+ pProcessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;
+ }
+ if (pProcessor->HasLayoutItem() == FALSE) {
+ return eRetValue;
+ }
+ FX_FLOAT fChildWidth, fChildHeight;
+ pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+ if (bUseRealHeight && fRealHeight < XFA_LAYOUT_FLOAT_PERCISION) {
+ fRealHeight = XFA_LAYOUT_FLOAT_MAX;
+ fAvailHeight = XFA_LAYOUT_FLOAT_MAX;
+ }
+ if (!bTakeSpace || (fChildWidth <= fContentCurRowAvailWidth + XFA_LAYOUT_FLOAT_PERCISION) || (fContentWidthLimit - fContentCurRowAvailWidth <= XFA_LAYOUT_FLOAT_PERCISION)) {
+ CXFA_Node *pOverflowLeaderNode = NULL, *pOverflowTrailerNode = NULL, *pFormNode = NULL;
+ CXFA_ContentLayoutItemImpl* pTrailerLayoutItem = NULL;
+ FX_BOOL bIsAddTrailerHeight = FALSE;
+ if(pThis->m_pPageMgr && pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
+ pFormNode = pThis->m_pPageMgr->QueryOverflow(pProcessor->m_pFormNode);
+ if(pFormNode == NULL && pLayoutContext && pLayoutContext->m_pOverflowProcessor) {
+ pFormNode = pLayoutContext->m_pOverflowNode;
+ bUseInherited = TRUE;
+ }
+ if(pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, FALSE)) {
+ if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowTrailerNode)) {
+ if(pOverflowTrailerNode) {
+ CXFA_ItemLayoutProcessor *pOverflowLeaderProcessor = FX_NEW CXFA_ItemLayoutProcessor(pOverflowTrailerNode, NULL);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pOverflowLeaderProcessor->m_pPageMgrCreateItem = pProcessor->m_pPageMgrCreateItem;
+#endif
+ pOverflowLeaderProcessor->DoLayout(FALSE, XFA_LAYOUT_FLOAT_MAX);
+ pTrailerLayoutItem = pOverflowLeaderProcessor->HasLayoutItem() ? pOverflowLeaderProcessor->ExtractLayoutItem() : NULL;
+ delete pOverflowLeaderProcessor;
+ }
+ if(bUseInherited) {
+ bIsAddTrailerHeight = pThis->IsAddNewRowForTrailer(pTrailerLayoutItem);
+ } else {
+ bIsAddTrailerHeight = pProcessor->IsAddNewRowForTrailer(pTrailerLayoutItem);
+ }
+ if(bIsAddTrailerHeight) {
+ FX_FLOAT fTrailerHeight = pTrailerLayoutItem->m_sSize.y;
+ fChildHeight += fTrailerHeight;
+ bIsAddTrailerHeight = TRUE;
+ }
+ }
+ }
+ }
+ if(!bTakeSpace || fContentCurRowY + fChildHeight <= fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION ||
+ (!bContainerHeightAutoSize && pThis->m_fUsedSize + fAvailHeight + XFA_LAYOUT_FLOAT_PERCISION >= fContainerHeight)) {
+ if(!bTakeSpace || eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+ if(pProcessor->m_bUseInheriated) {
+ if(pTrailerLayoutItem) {
+ XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fChildHeight, pTrailerLayoutItem);
+ }
+ if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+ XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);
+ }
+ pProcessor->m_bUseInheriated = FALSE;
+ } else {
+ if(bIsAddTrailerHeight) {
+ fChildHeight -= pTrailerLayoutItem->m_sSize.y;
+ }
+ pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);
+ }
+ CXFA_ContentLayoutItemImpl* pChildLayoutItem = pProcessor->ExtractLayoutItem();
+ if(XFA_ExistContainerKeep(pProcessor->m_pFormNode, FALSE) && pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
+ pThis->m_arrayKeepItems.Add(pChildLayoutItem);
+ } else {
+ pThis->m_arrayKeepItems.RemoveAll();
+ }
+ rgCurLineLayoutItems[uHAlign].Add(pChildLayoutItem);
+ bAddedItemInRow = TRUE;
+ if(bTakeSpace) {
+ fContentCurRowAvailWidth -= fChildWidth;
+ if(fContentCurRowHeight < fChildHeight ) {
+ fContentCurRowHeight = fChildHeight;
+ }
+ }
+ return XFA_ItemLayoutProcessorResult_Done;
+ } else {
+ if(eRetValue == XFA_ItemLayoutProcessorResult_PageFullBreak) {
+ if(pProcessor->m_bUseInheriated) {
+ if(pTrailerLayoutItem) {
+ XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fChildHeight, pTrailerLayoutItem);
+ }
+ if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+ XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);
+ }
+ pProcessor->m_bUseInheriated = FALSE;
+ } else {
+ if(bIsAddTrailerHeight) {
+ fChildHeight -= pTrailerLayoutItem->m_sSize.y;
+ }
+ pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);
+ }
+ }
+ rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+ bAddedItemInRow = TRUE;
+ fContentCurRowAvailWidth -= fChildWidth;
+ if(fContentCurRowHeight < fChildHeight ) {
+ fContentCurRowHeight = fChildHeight;
+ }
+ return eRetValue;
+ }
+ } else {
+ XFA_ItemLayoutProcessorResult eResult;
+ if(pThis->ProcessKeepForSplite(pThis, pProcessor, eRetValue, rgCurLineLayoutItems[uHAlign],
+ fContentCurRowAvailWidth, fContentCurRowHeight, fContentCurRowY, bAddedItemInRow, bForceEndPage, eResult)) {
+ return eResult;
+ }
+ bForceEndPage = TRUE;
+ FX_FLOAT fSplitPos = pProcessor->FindSplitPos(fAvailHeight - fContentCurRowY);
+ if (fSplitPos > XFA_LAYOUT_FLOAT_PERCISION) {
+ XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ if(eLayout == XFA_ATTRIBUTEENUM_Tb && eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+ pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);
+ rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+ bAddedItemInRow = TRUE;
+ if(bTakeSpace) {
+ fContentCurRowAvailWidth -= fChildWidth;
+ if(fContentCurRowHeight < fChildHeight ) {
+ fContentCurRowHeight = fChildHeight;
+ }
+ }
+ return XFA_ItemLayoutProcessorResult_PageFullBreak;
+ }
+ CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
+ if(pThis->m_pPageMgr && !pProcessor->m_bUseInheriated && eRetValue != XFA_ItemLayoutProcessorResult_PageFullBreak) {
+ pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, pTempTrailerNode, FALSE, TRUE);
+ }
+ if(pTrailerLayoutItem && bIsAddTrailerHeight) {
+ XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem, bUseInherited);
+ } else {
+ pProcessor->SplitLayoutItem(fSplitPos);
+ }
+ if(bUseInherited) {
+ pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);
+ pThis->m_bUseInheriated = TRUE;
+ } else {
+ if(pProcessor->m_pLayoutItem->m_pFirstChild && pProcessor->m_pLayoutItem->m_pFirstChild->m_pNextSibling == NULL
+ && pProcessor->m_pLayoutItem->m_pFirstChild->m_pFormNode->HasFlag(XFA_NODEFLAG_LayoutGeneratedNode)) {
+ pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);
+ } else {
+ if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+ XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);
+ }
+ }
+ }
+ if(pProcessor->m_pLayoutItem->m_pNextSibling) {
+ pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+ rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+ bAddedItemInRow = TRUE;
+ if(bTakeSpace) {
+ fContentCurRowAvailWidth -= fChildWidth;
+ if(fContentCurRowHeight < fChildHeight ) {
+ fContentCurRowHeight = fChildHeight;
+ }
+ }
+ }
+ return XFA_ItemLayoutProcessorResult_PageFullBreak;
+ } else if (fContentCurRowY <= XFA_LAYOUT_FLOAT_PERCISION) {
+ pProcessor->GetCurrentComponentSize(fChildWidth, fChildHeight);
+ if(pProcessor->m_pPageMgr->GetNextAvailContentHeight(fChildHeight)) {
+ CXFA_Node *pTempLeaderNode = NULL, *pTempTrailerNode = NULL;
+ if(pThis->m_pPageMgr) {
+ if(pFormNode == NULL && pLayoutContext != NULL) {
+ pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
+ }
+ pThis->m_pPageMgr->ProcessOverflow(pFormNode, pTempLeaderNode, pTempTrailerNode, FALSE, TRUE);
+ }
+ if(bUseInherited) {
+ pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);
+ pThis->m_bUseInheriated = TRUE;
+ }
+ return XFA_ItemLayoutProcessorResult_PageFullBreak;
+ }
+ rgCurLineLayoutItems[uHAlign].Add(pProcessor->ExtractLayoutItem());
+ bAddedItemInRow = TRUE;
+ if(bTakeSpace) {
+ fContentCurRowAvailWidth -= fChildWidth;
+ if(fContentCurRowHeight < fChildHeight ) {
+ fContentCurRowHeight = fChildHeight;
+ }
+ }
+ if(eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+ bForceEndPage = FALSE;
+ }
+ return eRetValue;
+ } else {
+ XFA_ATTRIBUTEENUM eLayout = pProcessor->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ if(pProcessor->m_pFormNode->GetIntact() == XFA_ATTRIBUTEENUM_None && eLayout == XFA_ATTRIBUTEENUM_Tb) {
+ if(pThis->m_pPageMgr) {
+ pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, TRUE);
+ }
+ if(pTrailerLayoutItem) {
+ XFA_ItemLayoutProcessor_AddTrailerBeforeSplit(pProcessor, fSplitPos, pTrailerLayoutItem);
+ }
+ if(pProcessor->JudgeLeaderOrTrailerForOccur(pOverflowLeaderNode)) {
+ XFA_ItemLayoutProcessor_AddPendingNode(pProcessor, pOverflowLeaderNode, FALSE);
+ }
+ } else {
+ if(eRetValue == XFA_ItemLayoutProcessorResult_Done) {
+ if(pFormNode == NULL && pLayoutContext != NULL) {
+ pFormNode = pLayoutContext->m_pOverflowProcessor->m_pFormNode;
+ }
+ if(pThis->m_pPageMgr) {
+ pThis->m_pPageMgr->ProcessOverflow(pFormNode, pOverflowLeaderNode, pOverflowTrailerNode, FALSE, TRUE);
+ }
+ if(bUseInherited) {
+ pProcessor->ProcessUnUseOverFlow(pOverflowLeaderNode, pOverflowTrailerNode, pTrailerLayoutItem, pFormNode);
+ pThis->m_bUseInheriated = TRUE;
+ }
+ }
+ }
+ return XFA_ItemLayoutProcessorResult_PageFullBreak;
+ }
+ }
+ } else {
+ return XFA_ItemLayoutProcessorResult_RowFullBreak;
+ }
+ return XFA_ItemLayoutProcessorResult_Done;
+}
+XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayoutFlowedContainer(FX_BOOL bUseBreakControl, XFA_ATTRIBUTEENUM eFlowStrategy, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext, FX_BOOL bRootForceTb)
+{
+ m_bHasAvailHeight = TRUE;
+ FX_FLOAT fContainerWidth = 0, fContainerHeight = 0;
+ FX_BOOL bBreakDone = FALSE;
+ FX_BOOL bContainerWidthAutoSize = TRUE, bContainerHeightAutoSize = TRUE;
+ FX_BOOL bForceEndPage = FALSE;
+ FX_BOOL bIsManualBreak = FALSE;
+ if(m_pCurChildPreprocessor) {
+ m_pCurChildPreprocessor->m_ePreProcessRs = XFA_ItemLayoutProcessorResult_Done;
+ }
+ XFA_ItemLayoutProcessor_CalculateContainerSpecfiedSize(m_pFormNode, fContainerWidth, fContainerHeight, bContainerWidthAutoSize, bContainerHeightAutoSize);
+ if (pContext && pContext->m_bCurColumnWidthAvaiable) {
+ bContainerWidthAutoSize = FALSE;
+ fContainerWidth = pContext->m_fCurColumnWidth;
+ }
+ if(!bContainerHeightAutoSize) {
+ fContainerHeight -= m_fUsedSize;
+ }
+ if(!bContainerHeightAutoSize) {
+ CXFA_Node* pParentNode = m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent);
+ FX_BOOL bFocrTb = FALSE;
+ if(pParentNode && XFA_ItemLayoutProcessor_GetLayout(pParentNode, bFocrTb) == XFA_ATTRIBUTEENUM_Row) {
+ CXFA_Node* pChildContainer = m_pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode);
+ if(pChildContainer && pChildContainer->GetNodeItem(XFA_NODEITEM_NextSibling, XFA_OBJECTTYPE_ContainerNode)) {
+ fContainerHeight = 0;
+ bContainerHeightAutoSize = TRUE;
+ }
+ }
+ }
+ CXFA_Node* pMarginNode = m_pFormNode->GetFirstChildByClass(XFA_ELEMENT_Margin);
+ FX_FLOAT fLeftInset = 0, fTopInset = 0, fRightInset = 0, fBottomInset = 0;
+ if(pMarginNode) {
+ fLeftInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_LeftInset).ToUnit(XFA_UNIT_Pt);
+ fTopInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_TopInset).ToUnit(XFA_UNIT_Pt);
+ fRightInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_RightInset).ToUnit(XFA_UNIT_Pt);
+ fBottomInset = pMarginNode->GetMeasure(XFA_ATTRIBUTE_BottomInset).ToUnit(XFA_UNIT_Pt);
+ }
+ FX_FLOAT fContentWidthLimit = bContainerWidthAutoSize ? XFA_LAYOUT_FLOAT_MAX : fContainerWidth - fLeftInset - fRightInset;
+ FX_FLOAT fContentCalculatedWidth = 0, fContentCalculatedHeight = 0;
+ FX_FLOAT fAvailHeight = fHeightLimit - fTopInset - fBottomInset;
+ if(fAvailHeight < 0) {
+ m_bHasAvailHeight = FALSE;
+ }
+ fRealHeight = fRealHeight - fTopInset - fBottomInset;
+ FX_FLOAT fContentCurRowY = 0;
+ CXFA_ContentLayoutItemImpl* pLayoutChild = NULL;
+ if(m_pLayoutItem != NULL) {
+ if (m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done && eFlowStrategy != XFA_ATTRIBUTEENUM_Tb) {
+ pLayoutChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild;
+ for (CXFA_ContentLayoutItemImpl* pLayoutNext = pLayoutChild; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {
+ if (pLayoutNext->m_sPos.y != pLayoutChild->m_sPos.y) {
+ pLayoutChild = pLayoutNext;
+ }
+ }
+ }
+ for(CXFA_ContentLayoutItemImpl* pLayoutTempChild = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild; pLayoutTempChild != pLayoutChild; pLayoutTempChild = (CXFA_ContentLayoutItemImpl*)pLayoutTempChild->m_pNextSibling) {
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutTempChild->m_pFormNode)) {
+ FX_FLOAT fChildContentWidth = pLayoutTempChild->m_sPos.x + pLayoutTempChild->m_sSize.x;
+ FX_FLOAT fChildContentHeight = pLayoutTempChild->m_sPos.y + pLayoutTempChild->m_sSize.y;
+ if(fContentCalculatedWidth < fChildContentWidth) {
+ fContentCalculatedWidth = fChildContentWidth;
+ }
+ if(fContentCalculatedHeight < fChildContentHeight) {
+ fContentCalculatedHeight = fChildContentHeight;
+ }
+ }
+ }
+ if (pLayoutChild) {
+ fContentCurRowY = pLayoutChild->m_sPos.y;
+ } else {
+ fContentCurRowY = fContentCalculatedHeight;
+ }
+ }
+ fContentCurRowY += InsertKeepLayoutItems();
+ if(m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_None) {
+ XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+ }
+ fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
+ if(m_pCurChildPreprocessor && m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Container) {
+ if(XFA_ExistContainerKeep(m_pCurChildPreprocessor->GetFormNode(), FALSE)) {
+ m_pKeepHeadNode = m_pCurChildNode;
+ m_bIsProcessKeep = TRUE;
+ m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Keep;
+ }
+ }
+ while(m_nCurChildNodeStage != XFA_ItemLayoutProcessorStages_Done) {
+ FX_FLOAT fContentCurRowHeight = 0;
+ FX_FLOAT fContentCurRowAvailWidth = fContentWidthLimit;
+ m_fWidthLimite = fContentCurRowAvailWidth;
+ CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> rgCurLineLayoutItems[3];
+ FX_UINT8 uCurHAlignState = (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb ? 0 : 2);
+ if (pLayoutChild) {
+ for (CXFA_ContentLayoutItemImpl* pLayoutNext = pLayoutChild; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {
+ if (pLayoutNext->m_pNextSibling == NULL && m_pCurChildPreprocessor && m_pCurChildPreprocessor->m_pFormNode == pLayoutNext->m_pFormNode) {
+ pLayoutNext->m_pNext = m_pCurChildPreprocessor->m_pLayoutItem;
+ m_pCurChildPreprocessor->m_pLayoutItem = pLayoutNext;
+ break;
+ }
+ FX_UINT8 uHAlign = XFA_ItemLayoutProcessor_HAlignEnumToInt(pLayoutNext->m_pFormNode->GetEnum(XFA_ATTRIBUTE_HAlign));
+ rgCurLineLayoutItems[uHAlign].Add(pLayoutNext);
+ if (eFlowStrategy == XFA_ATTRIBUTEENUM_Lr_tb) {
+ if (uHAlign > uCurHAlignState) {
+ uCurHAlignState = uHAlign;
+ }
+ } else if (uHAlign < uCurHAlignState) {
+ uCurHAlignState = uHAlign;
+ }
+ if (XFA_ItemLayoutProcessor_IsTakingSpace(pLayoutNext->m_pFormNode)) {
+ if (pLayoutNext->m_sSize.y > fContentCurRowHeight) {
+ fContentCurRowHeight = pLayoutNext->m_sSize.y;
+ }
+ fContentCurRowAvailWidth -= pLayoutNext->m_sSize.x;
+ }
+ }
+ if ((CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild == pLayoutChild) {
+ m_pLayoutItem->m_pFirstChild = NULL;
+ } else {
+ CXFA_ContentLayoutItemImpl* pLayoutNext = (CXFA_ContentLayoutItemImpl*)m_pLayoutItem->m_pFirstChild;
+ for (; pLayoutNext; pLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling) {
+ if ((CXFA_ContentLayoutItemImpl*)pLayoutNext->m_pNextSibling == pLayoutChild) {
+ pLayoutNext->m_pNextSibling = NULL;
+ break;
+ }
+ }
+ }
+ CXFA_ContentLayoutItemImpl* pLayoutNextTemp = (CXFA_ContentLayoutItemImpl*)pLayoutChild;
+ while (pLayoutNextTemp) {
+ pLayoutNextTemp->m_pParent = NULL;
+ CXFA_ContentLayoutItemImpl* pSaveLayoutNext = (CXFA_ContentLayoutItemImpl*)pLayoutNextTemp->m_pNextSibling;
+ pLayoutNextTemp->m_pNextSibling = NULL;
+ pLayoutNextTemp = pSaveLayoutNext;
+ }
+ pLayoutChild = NULL;
+ }
+ while(m_pCurChildNode) {
+ CXFA_ItemLayoutProcessor* pProcessor = NULL;
+ FX_BOOL bAddedItemInRow = FALSE;
+ fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(this, m_pFormNode);
+ switch(m_nCurChildNodeStage) {
+ case XFA_ItemLayoutProcessorStages_Keep:
+ case XFA_ItemLayoutProcessorStages_None:
+ break;
+ case XFA_ItemLayoutProcessorStages_BreakBefore: {
+ for(FX_INT32 iIndex = 0; iIndex < m_arrayKeepItems.GetSize(); iIndex++) {
+ CXFA_ContentLayoutItemImpl* pItem = m_arrayKeepItems.GetAt(iIndex);
+ m_pLayoutItem->RemoveChild(pItem);
+ fContentCalculatedHeight -= pItem->m_sSize.y;
+ }
+ CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
+ FX_BOOL bCreatePage = FALSE;
+ if(bUseBreakControl && m_pPageMgr && m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, TRUE, pLeaderNode, pTrailerNode, bCreatePage) && m_pFormNode->GetClassID() != XFA_ELEMENT_Form
+ && bCreatePage) {
+ if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
+ XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
+ }
+ if(JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
+ if(m_pFormNode->GetNodeItem(XFA_NODEITEM_Parent)->GetClassID() == XFA_ELEMENT_Form && m_pLayoutItem == NULL) {
+ XFA_ItemLayoutProcessor_AddPendingNode(this, pTrailerNode, TRUE);
+ } else {
+ CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,
+ rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,
+ fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);
+ delete pProcessor;
+ pProcessor = NULL;
+ }
+ }
+ XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+ bForceEndPage = TRUE;
+ bIsManualBreak = TRUE;
+ goto SuspendAndCreateNewRow;
+ }
+ }
+ break;
+ case XFA_ItemLayoutProcessorStages_BreakAfter: {
+ XFA_ItemLayoutProcessorResult eResult;
+ CXFA_Node *pLeaderNode = NULL, *pTrailerNode = NULL;
+ FX_BOOL bCreatePage = FALSE;
+ if(bUseBreakControl && m_pPageMgr && m_pPageMgr->ProcessBreakBeforeOrAfter(m_pCurChildNode, FALSE, pLeaderNode, pTrailerNode, bCreatePage) && m_pFormNode->GetClassID() != XFA_ELEMENT_Form) {
+ if(JudgeLeaderOrTrailerForOccur(pTrailerNode)) {
+ CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, NULL);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ eResult = XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,
+ rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,
+ fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);
+ delete pProcessor;
+ pProcessor = NULL;
+ }
+ if(!bCreatePage) {
+ if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
+ CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, bContainerWidthAutoSize,
+ fContentCalculatedWidth, fContentCalculatedHeight, fContentCurRowY, fContentCurRowHeight, fContentWidthLimit);
+ rgCurLineLayoutItems->RemoveAll();
+ CXFA_ItemLayoutProcessor *pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pLeaderNode, NULL);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,
+ rgCurLineLayoutItems, FALSE, XFA_LAYOUT_FLOAT_MAX, XFA_LAYOUT_FLOAT_MAX, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,
+ fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext);
+ delete pProcessor;
+ pProcessor = NULL;
+ }
+ } else {
+ if(JudgeLeaderOrTrailerForOccur(pLeaderNode)) {
+ XFA_ItemLayoutProcessor_AddPendingNode(this, pLeaderNode, TRUE);
+ }
+ }
+ XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+ if(bCreatePage) {
+ bForceEndPage = TRUE;
+ bIsManualBreak = TRUE;
+ if(m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done) {
+ bBreakDone = TRUE;
+ }
+ }
+ goto SuspendAndCreateNewRow;
+ }
+ }
+ break;
+ case XFA_ItemLayoutProcessorStages_BookendLeader: {
+ CXFA_Node* pLeaderNode = NULL;
+ if (m_pCurChildPreprocessor) {
+ pProcessor = m_pCurChildPreprocessor;
+ m_pCurChildPreprocessor = NULL;
+ } else if(m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer(m_pCurChildNode, TRUE, pLeaderNode)) {
+ pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pLeaderNode, m_pPageMgr);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ }
+ if(pProcessor) {
+ if(XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,
+ rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,
+ fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext) != XFA_ItemLayoutProcessorResult_Done) {
+ goto SuspendAndCreateNewRow;
+ } else {
+ delete pProcessor;
+ pProcessor = NULL;
+ }
+ }
+ }
+ break;
+ case XFA_ItemLayoutProcessorStages_BookendTrailer: {
+ CXFA_Node* pTrailerNode = NULL;
+ if (m_pCurChildPreprocessor) {
+ pProcessor = m_pCurChildPreprocessor;
+ m_pCurChildPreprocessor = NULL;
+ } else if(m_pPageMgr && m_pPageMgr->ProcessBookendLeaderOrTrailer(m_pCurChildNode, FALSE, pTrailerNode)) {
+ pProcessor = FX_NEW CXFA_ItemLayoutProcessor(pTrailerNode, m_pPageMgr);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ }
+ if(pProcessor) {
+ if(XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,
+ rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,
+ fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext) != XFA_ItemLayoutProcessorResult_Done) {
+ goto SuspendAndCreateNewRow;
+ } else {
+ delete pProcessor;
+ pProcessor = NULL;
+ }
+ }
+ }
+ break;
+ case XFA_ItemLayoutProcessorStages_Container:
+ ASSERT(m_pCurChildNode->IsContainerNode());
+ if(m_pCurChildNode->GetClassID() == XFA_ELEMENT_Variables) {
+ break;
+ }
+ if(fContentCurRowY >= fHeightLimit + XFA_LAYOUT_FLOAT_PERCISION && XFA_ItemLayoutProcessor_IsTakingSpace(m_pCurChildNode)) {
+ bForceEndPage = TRUE;
+ goto SuspendAndCreateNewRow;
+ }
+ if(m_pCurChildNode->IsContainerNode()) {
+ FX_BOOL bNewRow = FALSE;
+ if (m_pCurChildPreprocessor) {
+ pProcessor = m_pCurChildPreprocessor;
+ m_pCurChildPreprocessor = NULL;
+ bNewRow = TRUE;
+ } else {
+ pProcessor = FX_NEW CXFA_ItemLayoutProcessor(m_pCurChildNode, m_pPageMgr);
+#ifndef _XFA_LAYOUTITEM_ProcessCACHE_
+ pProcessor->m_pPageMgrCreateItem = m_pPageMgrCreateItem;
+#endif
+ }
+ XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, m_pCurChildNode);
+ XFA_ItemLayoutProcessorResult rs = XFA_ItemLayoutProcessor_InsertFlowedItem(this, pProcessor, bContainerWidthAutoSize, bContainerHeightAutoSize, fContainerHeight, eFlowStrategy, uCurHAlignState,
+ rgCurLineLayoutItems, bUseBreakControl, fAvailHeight, fRealHeight, fContentCurRowY, fContentWidthLimit, fContentCurRowAvailWidth,
+ fContentCurRowHeight, bAddedItemInRow, bForceEndPage, pContext, bNewRow);
+ switch(rs) {
+ case XFA_ItemLayoutProcessorResult_ManualBreak:
+ bIsManualBreak = TRUE;
+ case XFA_ItemLayoutProcessorResult_PageFullBreak:
+ bForceEndPage = TRUE;
+ case XFA_ItemLayoutProcessorResult_RowFullBreak:
+ goto SuspendAndCreateNewRow;
+ case XFA_ItemLayoutProcessorResult_Done:
+ default:
+ fContentCurRowY += XFA_ItemLayoutProcessor_InsertPendingItems(pProcessor, m_pCurChildNode);
+ delete pProcessor;
+ pProcessor = NULL;
+ }
+ }
+ break;
+ case XFA_ItemLayoutProcessorStages_Done:
+ break;
+ default:
+ break;
+ }
+ XFA_ItemLayoutProcessor_GotoNextContainerNode(m_pCurChildNode, m_nCurChildNodeStage, m_pFormNode, TRUE);
+ if(bAddedItemInRow && eFlowStrategy == XFA_ATTRIBUTEENUM_Tb) {
+ break;
+ } else {
+ continue;
+ }
+SuspendAndCreateNewRow:
+ if (pProcessor) {
+ m_pCurChildPreprocessor = pProcessor;
+ }
+ break;
+ }
+ CalculateRowChildPosition(rgCurLineLayoutItems, eFlowStrategy, bContainerHeightAutoSize, bContainerWidthAutoSize,
+ fContentCalculatedWidth, fContentCalculatedHeight, fContentCurRowY, fContentCurRowHeight, fContentWidthLimit, bRootForceTb);
+ m_fWidthLimite = fContentCurRowAvailWidth;
+ if(bForceEndPage) {
+ break;
+ }
+ }
+ FX_BOOL bRetValue = (m_nCurChildNodeStage == XFA_ItemLayoutProcessorStages_Done && m_rgPendingNodes.GetCount() == 0);
+ if(bBreakDone) {
+ bRetValue = FALSE;
+ }
+ XFA_ItemLayoutProcessor_CalculateContainerComponentSizeFromContentSize(m_pFormNode, bContainerWidthAutoSize, fContentCalculatedWidth, fContainerWidth, bContainerHeightAutoSize, fContentCalculatedHeight, fContainerHeight);
+ if(fContainerHeight >= XFA_LAYOUT_FLOAT_PERCISION || m_pLayoutItem || bRetValue) {
+ if(m_pLayoutItem == NULL) {
+ m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+ }
+ if(fContainerHeight < 0 ) {
+ fContainerHeight = 0;
+ }
+ SetCurrentComponentSize(fContainerWidth, fContainerHeight);
+ if(bForceEndPage) {
+ m_fUsedSize = 0;
+ } else {
+ m_fUsedSize += m_pLayoutItem->m_sSize.y;
+ }
+ }
+ return bRetValue ? XFA_ItemLayoutProcessorResult_Done : (bIsManualBreak ? XFA_ItemLayoutProcessorResult_ManualBreak : XFA_ItemLayoutProcessorResult_PageFullBreak);
+}
+FX_BOOL CXFA_ItemLayoutProcessor::CalculateRowChildPosition(CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>(&rgCurLineLayoutItems)[3], XFA_ATTRIBUTEENUM eFlowStrategy, FX_BOOL bContainerHeightAutoSize,
+ FX_BOOL bContainerWidthAutoSize, FX_FLOAT& fContentCalculatedWidth, FX_FLOAT& fContentCalculatedHeight, FX_FLOAT& fContentCurRowY, FX_FLOAT fContentCurRowHeight, FX_FLOAT fContentWidthLimit, FX_BOOL bRootForceTb)
+{
+ FX_INT32 nGroupLengths[3] = {0, 0, 0};
+ FX_FLOAT fGroupWidths[3] = {0, 0, 0};
+ FX_INT32 nTotalLength = 0;
+ for(FX_INT32 i = 0; i < 3; i ++) {
+ nGroupLengths[i] = rgCurLineLayoutItems[i].GetSize();
+ for(FX_INT32 c = nGroupLengths[i], j = 0; j < c; j++) {
+ nTotalLength++;
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[i][j]->m_pFormNode)) {
+ fGroupWidths[i] += rgCurLineLayoutItems[i][j]->m_sSize.x;
+ }
+ }
+ }
+ if(!nTotalLength) {
+ if(bContainerHeightAutoSize) {
+ FX_FLOAT fNewHeight = fContentCurRowY;
+ if(fContentCalculatedHeight > fNewHeight) {
+ fContentCalculatedHeight = fNewHeight;
+ }
+ }
+ return FALSE;
+ }
+ if(m_pLayoutItem == NULL) {
+ m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+ }
+ if (eFlowStrategy != XFA_ATTRIBUTEENUM_Rl_tb) {
+ FX_FLOAT fCurPos;
+ fCurPos = 0;
+ for(FX_INT32 c = nGroupLengths[0], j = 0; j < c; j++) {
+ if(bRootForceTb) {
+ FX_FLOAT fAbsoluteX, fAbsoluteY;
+ CalculatePositionedContainerPos(rgCurLineLayoutItems[0][j]->m_pFormNode, rgCurLineLayoutItems[0][j]->m_sSize.x, rgCurLineLayoutItems[0][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);
+ rgCurLineLayoutItems[0][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
+ } else {
+ rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[0][j]->m_pFormNode)) {
+ fCurPos += rgCurLineLayoutItems[0][j]->m_sSize.x;
+ }
+ }
+ m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
+ m_fLastRowWidth = fCurPos;
+ }
+ fCurPos = (fContentWidthLimit + fGroupWidths[0] - fGroupWidths[1] - fGroupWidths[2]) / 2;
+ for(FX_INT32 c = nGroupLengths[1], j = 0; j < c; j++) {
+ if(bRootForceTb) {
+ FX_FLOAT fAbsoluteX, fAbsoluteY;
+ CalculatePositionedContainerPos(rgCurLineLayoutItems[1][j]->m_pFormNode, rgCurLineLayoutItems[1][j]->m_sSize.x, rgCurLineLayoutItems[1][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);
+ rgCurLineLayoutItems[1][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
+ } else {
+ rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[1][j]->m_pFormNode)) {
+ fCurPos += rgCurLineLayoutItems[1][j]->m_sSize.x;
+ }
+ }
+ m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
+ m_fLastRowWidth = fCurPos;
+ }
+ fCurPos = fContentWidthLimit - fGroupWidths[2];
+ for(FX_INT32 c = nGroupLengths[2], j = 0; j < c; j++) {
+ if(bRootForceTb) {
+ FX_FLOAT fAbsoluteX, fAbsoluteY;
+ CalculatePositionedContainerPos(rgCurLineLayoutItems[2][j]->m_pFormNode, rgCurLineLayoutItems[2][j]->m_sSize.x, rgCurLineLayoutItems[2][j]->m_sSize.y, fAbsoluteX, fAbsoluteY);
+ rgCurLineLayoutItems[2][j]->m_sPos.Set(fAbsoluteX, fAbsoluteY);
+ } else {
+ rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[2][j]->m_pFormNode)) {
+ fCurPos += rgCurLineLayoutItems[2][j]->m_sSize.x;
+ }
+ }
+ m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
+ m_fLastRowWidth = fCurPos;
+ }
+ } else {
+ FX_FLOAT fCurPos;
+ fCurPos = fGroupWidths[0];
+ for(FX_INT32 c = nGroupLengths[0], j = 0; j < c; j++) {
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[0][j]->m_pFormNode)) {
+ fCurPos -= rgCurLineLayoutItems[0][j]->m_sSize.x;
+ }
+ rgCurLineLayoutItems[0][j]->m_sPos.Set(fCurPos, fContentCurRowY);
+ m_pLayoutItem->AddChild(rgCurLineLayoutItems[0][j]);
+ m_fLastRowWidth = fCurPos;
+ }
+ fCurPos = (fContentWidthLimit + fGroupWidths[0] + fGroupWidths[1] - fGroupWidths[2]) / 2;
+ for(FX_INT32 c = nGroupLengths[1], j = 0; j < c; j++) {
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[1][j]->m_pFormNode)) {
+ fCurPos -= rgCurLineLayoutItems[1][j]->m_sSize.x;
+ }
+ rgCurLineLayoutItems[1][j]->m_sPos.Set(fCurPos, fContentCurRowY);
+ m_pLayoutItem->AddChild(rgCurLineLayoutItems[1][j]);
+ m_fLastRowWidth = fCurPos;
+ }
+ fCurPos = fContentWidthLimit;
+ for(FX_INT32 c = nGroupLengths[2], j = 0; j < c; j++) {
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(rgCurLineLayoutItems[2][j]->m_pFormNode)) {
+ fCurPos -= rgCurLineLayoutItems[2][j]->m_sSize.x;
+ }
+ rgCurLineLayoutItems[2][j]->m_sPos.Set(fCurPos, fContentCurRowY);
+ m_pLayoutItem->AddChild(rgCurLineLayoutItems[2][j]);
+ m_fLastRowWidth = fCurPos;
+ }
+ }
+ m_fLastRowY = fContentCurRowY;
+ fContentCurRowY += fContentCurRowHeight;
+ if(bContainerWidthAutoSize) {
+ FX_FLOAT fChildSuppliedWidth = fGroupWidths[0];
+ if(fContentWidthLimit < XFA_LAYOUT_FLOAT_MAX && fContentWidthLimit > fChildSuppliedWidth) {
+ fChildSuppliedWidth = fContentWidthLimit;
+ }
+ if (fContentCalculatedWidth < fChildSuppliedWidth) {
+ fContentCalculatedWidth = fChildSuppliedWidth;
+ }
+ }
+ if(bContainerHeightAutoSize) {
+ FX_FLOAT fChildSuppliedHeight = fContentCurRowY;
+ if(fContentCalculatedHeight < fChildSuppliedHeight) {
+ fContentCalculatedHeight = fChildSuppliedHeight;
+ }
+ }
+ return TRUE;
+}
+CXFA_Node* CXFA_ItemLayoutProcessor::GetSubformSetParent(CXFA_Node* pSubformSet)
+{
+ if(pSubformSet && pSubformSet->GetClassID() == XFA_ELEMENT_SubformSet) {
+ CXFA_Node* pParent = pSubformSet->GetNodeItem(XFA_NODEITEM_Parent);
+ while(pParent) {
+ if(pParent->GetClassID() != XFA_ELEMENT_SubformSet) {
+ return pParent;
+ }
+ pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ }
+ return pSubformSet;
+}
+void CXFA_ItemLayoutProcessor::DoLayoutField()
+{
+ if(m_pLayoutItem != NULL) {
+ return;
+ }
+ ASSERT(m_pCurChildNode == XFA_LAYOUT_INVALIDNODE);
+ m_pLayoutItem = CreateContentLayoutItem(m_pFormNode);
+ if (!m_pLayoutItem) {
+ return;
+ }
+ CXFA_Document* pDocument = m_pFormNode->GetDocument();
+ IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
+ FX_FLOAT fHeight = -1;
+ FX_FLOAT fWidth = -1;
+ pNotify->StartFieldDrawLayout(m_pFormNode, fWidth, fHeight);
+ FX_INT32 nRotate = FXSYS_round(m_pFormNode->GetMeasure(XFA_ATTRIBUTE_Rotate).GetValue());
+ nRotate = (nRotate < 0 ? (nRotate % 360) + 360 : nRotate % 360);
+ if(nRotate == 90 || nRotate == 270) {
+ FX_FLOAT fTmp = fWidth;
+ fWidth = fHeight;
+ fHeight = fTmp;
+ }
+ SetCurrentComponentSize(fWidth, fHeight);
+}
+XFA_ItemLayoutProcessorResult CXFA_ItemLayoutProcessor::DoLayout(FX_BOOL bUseBreakControl, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext)
+{
+ XFA_ELEMENT eClassID = m_pFormNode->GetClassID();
+ switch(eClassID) {
+ case XFA_ELEMENT_Subform:
+ case XFA_ELEMENT_Area:
+ case XFA_ELEMENT_ExclGroup:
+ case XFA_ELEMENT_SubformSet: {
+ FX_BOOL bRootForceTb = FALSE;
+ CXFA_Node* pLayoutNode = GetSubformSetParent(m_pFormNode);
+ XFA_ATTRIBUTEENUM eLayoutStrategy = XFA_ItemLayoutProcessor_GetLayout(pLayoutNode, bRootForceTb);
+ switch(eLayoutStrategy) {
+ case XFA_ATTRIBUTEENUM_Tb:
+ case XFA_ATTRIBUTEENUM_Lr_tb:
+ case XFA_ATTRIBUTEENUM_Rl_tb:
+ return DoLayoutFlowedContainer(bUseBreakControl, eLayoutStrategy, fHeightLimit, fRealHeight, pContext, bRootForceTb);
+ case XFA_ATTRIBUTEENUM_Position:
+ case XFA_ATTRIBUTEENUM_Row:
+ case XFA_ATTRIBUTEENUM_Rl_row:
+ default:
+ DoLayoutPositionedContainer(pContext);
+ m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
+ return XFA_ItemLayoutProcessorResult_Done;
+ case XFA_ATTRIBUTEENUM_Table:
+ DoLayoutTableContainer(pLayoutNode);
+ m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
+ return XFA_ItemLayoutProcessorResult_Done;
+ }
+ }
+ case XFA_ELEMENT_Draw:
+ case XFA_ELEMENT_Field:
+ DoLayoutField();
+ m_nCurChildNodeStage = XFA_ItemLayoutProcessorStages_Done;
+ return XFA_ItemLayoutProcessorResult_Done;
+ case XFA_ELEMENT_ContentArea:
+ return XFA_ItemLayoutProcessorResult_Done;
+ default:
+ return XFA_ItemLayoutProcessorResult_Done;
+ }
+}
+void CXFA_ItemLayoutProcessor::GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY)
+{
+ ASSERT(m_pLayoutItem);
+ fAbsoluteX = m_pLayoutItem->m_sPos.x;
+ fAbsoluteY = m_pLayoutItem->m_sPos.y;
+}
+void CXFA_ItemLayoutProcessor::GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight)
+{
+ ASSERT(m_pLayoutItem);
+ fWidth = m_pLayoutItem->m_sSize.x;
+ fHeight = m_pLayoutItem->m_sSize.y;
+}
+void CXFA_ItemLayoutProcessor::SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY)
+{
+ ASSERT(m_pLayoutItem);
+ m_pLayoutItem->m_sPos.Set(fAbsoluteX, fAbsoluteY);
+}
+void CXFA_ItemLayoutProcessor::SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight)
+{
+ ASSERT(m_pLayoutItem);
+ m_pLayoutItem->m_sSize.Set(fWidth, fHeight);
+}
+FX_BOOL CXFA_ItemLayoutProcessor::JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode)
+{
+ if(pFormNode == NULL) {
+ return FALSE;
+ }
+ CXFA_Node* pTemplate = pFormNode->GetTemplateNode();
+ if (!pTemplate) {
+ pTemplate = pFormNode;
+ }
+ CXFA_Occur NodeOccur = pTemplate->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ FX_INT32 iMax = NodeOccur.GetMax();
+ if (iMax > -1) {
+ FX_INT32 iCount = (FX_INT32)(FX_UINTPTR)m_PendingNodesCount.GetValueAt(pTemplate);
+ if (iCount >= iMax) {
+ return FALSE;
+ }
+ iCount++;
+ m_PendingNodesCount.SetAt(pTemplate, (FX_LPVOID)(FX_UINTPTR)(iCount));
+ return TRUE;
+ }
+ return TRUE;
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.h b/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.h
new file mode 100644
index 0000000000..7844fb556f
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_layout_itemlayout.h
@@ -0,0 +1,132 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_LAYOUT_ITEMLAYOUT_H_
+#define _XFA_LAYOUT_ITEMLAYOUT_H_
+#define XFA_LAYOUT_INVALIDNODE ((CXFA_Node*)(FX_INTPTR)-1)
+#define XFA_LAYOUT_FLOAT_PERCISION (0.0005f)
+#include "float.h"
+#define XFA_LAYOUT_FLOAT_MAX FLT_MAX
+class CXFA_ItemLayoutProcessor;
+class CXFA_LayoutPageMgr;
+class CXFA_ContainerLayoutItemImpl;
+class CXFA_ContentLayoutItemImpl;
+enum XFA_ItemLayoutProcessorResult {
+ XFA_ItemLayoutProcessorResult_Done,
+ XFA_ItemLayoutProcessorResult_PageFullBreak,
+ XFA_ItemLayoutProcessorResult_RowFullBreak,
+ XFA_ItemLayoutProcessorResult_ManualBreak,
+};
+enum XFA_ItemLayoutProcessorStages {
+ XFA_ItemLayoutProcessorStages_None,
+ XFA_ItemLayoutProcessorStages_BookendLeader,
+ XFA_ItemLayoutProcessorStages_BreakBefore,
+ XFA_ItemLayoutProcessorStages_Keep,
+ XFA_ItemLayoutProcessorStages_Container,
+ XFA_ItemLayoutProcessorStages_BreakAfter,
+ XFA_ItemLayoutProcessorStages_BookendTrailer,
+ XFA_ItemLayoutProcessorStages_Done,
+};
+class CXFA_LayoutContext : public CFX_Object
+{
+public:
+ CXFA_LayoutContext(): m_prgSpecifiedColumnWidths(NULL)
+ , m_fCurColumnWidth(0)
+ , m_bCurColumnWidthAvaiable(FALSE)
+ , m_pOverflowProcessor(NULL)
+ , m_pOverflowNode(NULL)
+ {
+ }
+ ~CXFA_LayoutContext()
+ {
+ m_pOverflowProcessor = NULL;
+ }
+ CFX_ArrayTemplate<FX_FLOAT>* m_prgSpecifiedColumnWidths;
+ FX_FLOAT m_fCurColumnWidth;
+ FX_BOOL m_bCurColumnWidthAvaiable;
+ CXFA_ItemLayoutProcessor* m_pOverflowProcessor;
+ CXFA_Node* m_pOverflowNode;
+};
+class CXFA_ItemLayoutProcessor : public CFX_Object
+{
+public:
+ CXFA_ItemLayoutProcessor(CXFA_Node *pNode, CXFA_LayoutPageMgr* pPageMgr);
+ XFA_ItemLayoutProcessorResult DoLayout(FX_BOOL bUseBreakControl, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight = XFA_LAYOUT_FLOAT_MAX, CXFA_LayoutContext* pContext = NULL);
+ void GetCurrentComponentPos(FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY);
+ void GetCurrentComponentSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight);
+ void SetCurrentComponentPos(FX_FLOAT fAbsoluteX, FX_FLOAT fAbsoluteY);
+ void SetCurrentComponentSize(FX_FLOAT fWidth, FX_FLOAT fHeight);
+ inline CXFA_Node* GetFormNode()
+ {
+ return m_pFormNode;
+ }
+ inline FX_BOOL HasLayoutItem()
+ {
+ return m_pLayoutItem != NULL;
+ }
+ CXFA_ContentLayoutItemImpl* ExtractLayoutItem();
+
+ static FX_BOOL IncrementRelayoutNode(CXFA_LayoutProcessor* pLayoutProcessor, CXFA_Node *pNode, CXFA_Node *pParentNode);
+ static void CalculatePositionedContainerPos(CXFA_Node* pNode, FX_FLOAT fWidth, FX_FLOAT fHeight, FX_FLOAT& fAbsoluteX, FX_FLOAT& fAbsoluteY);
+ static FX_BOOL FindLayoutItemSplitPos(CXFA_ContentLayoutItemImpl* pLayoutItem, FX_FLOAT fCurVerticalOffset, FX_FLOAT& fProposedSplitPos, FX_BOOL& bAppChange, FX_BOOL bCalculateMargin = TRUE);
+ FX_FLOAT FindSplitPos(FX_FLOAT fProposedSplitPos);
+ void SplitLayoutItem(CXFA_ContentLayoutItemImpl* pLayoutItem, CXFA_ContentLayoutItemImpl* pSecondParent, FX_FLOAT fSplitPos);
+ void SplitLayoutItem(FX_FLOAT fSplitPos);
+ FX_BOOL JudgePutNextPage(CXFA_ContentLayoutItemImpl* pParentLayoutItem, FX_FLOAT fChildHeight, CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> &pKeepItems);
+ FX_BOOL ProcessKeepForSplite(CXFA_ItemLayoutProcessor* pParentProcessor, CXFA_ItemLayoutProcessor* pChildProcessor, XFA_ItemLayoutProcessorResult eRetValue,
+ CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>& rgCurLineLayoutItem, FX_FLOAT& fContentCurRowAvailWidth,
+ FX_FLOAT& fContentCurRowHeight, FX_FLOAT& fContentCurRowY, FX_BOOL& bAddedItemInRow, FX_BOOL& bForceEndPage, XFA_ItemLayoutProcessorResult& result);
+ FX_FLOAT InsertKeepLayoutItems();
+ void DoLayoutPageArea(CXFA_ContainerLayoutItemImpl* pPageAreaLayoutItem);
+ FX_BOOL CalculateRowChildPosition(CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*>(&rgCurLineLayoutItems)[3], XFA_ATTRIBUTEENUM eFlowStrategy, FX_BOOL bContainerHeightAutoSize,
+ FX_BOOL bContainerWidthAutoSize, FX_FLOAT& fContentCalculatedWidth, FX_FLOAT& fContentCalculatedHeight, FX_FLOAT& fContentCurRowY,
+ FX_FLOAT fContentCurRowHeight, FX_FLOAT fContentWidthLimit, FX_BOOL bRootForceTb = FALSE);
+ void ProcessUnUseOverFlow(CXFA_Node* pLeaderNode, CXFA_Node* pTrailerNode, CXFA_ContentLayoutItemImpl* pTrailerItem, CXFA_Node* pFormNode);
+ void ProcessUnUseBinds(CXFA_Node* pFormNode);
+ FX_BOOL IsAddNewRowForTrailer(CXFA_ContentLayoutItemImpl* pTrailerItem);
+ FX_BOOL JudgeLeaderOrTrailerForOccur(CXFA_Node* pFormNode);
+ CXFA_ContentLayoutItemImpl* CreateContentLayoutItem(CXFA_Node* pFormNode);
+protected:
+ void DoLayoutPositionedContainer(CXFA_LayoutContext* pContext = NULL);
+ void DoLayoutTableContainer(CXFA_Node* pLayoutNode);
+ XFA_ItemLayoutProcessorResult DoLayoutFlowedContainer(FX_BOOL bUseBreakControl, XFA_ATTRIBUTEENUM eFlowStrategy, FX_FLOAT fHeightLimit, FX_FLOAT fRealHeight, CXFA_LayoutContext* pContext = NULL, FX_BOOL bRootForceTb = FALSE);
+ void DoLayoutField();
+ void XFA_ItemLayoutProcessor_GotoNextContainerNode(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pParentContainer, FX_BOOL bUsePageBreak);
+ FX_BOOL ProcessKeepNodesForCheckNext(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node*& pNextContainer, FX_BOOL& bLastKeepNode);
+ FX_BOOL ProcessKeepNodesForBreakBefore(CXFA_Node*& pCurActionNode, XFA_ItemLayoutProcessorStages& nCurStage, CXFA_Node* pContainerNode);
+ CXFA_Node* GetSubformSetParent(CXFA_Node* pSubformSet);
+
+public:
+ FX_BOOL m_bKeepBreakFinish;
+ FX_BOOL m_bIsProcessKeep;
+ CXFA_Node* m_pKeepHeadNode;
+ CXFA_Node* m_pKeepTailNode;
+ CXFA_Node* m_pFormNode;
+ CXFA_ContentLayoutItemImpl* m_pLayoutItem;
+#ifdef _XFA_LAYOUTITEM_ProcessCACHE_
+ CXFA_ContentLayoutItemImpl* m_pOldLayoutItem;
+#else
+ CXFA_LayoutPageMgr* m_pPageMgrCreateItem;
+#endif
+ CXFA_Node* m_pCurChildNode;
+ CXFA_ItemLayoutProcessor* m_pCurChildPreprocessor;
+ XFA_ItemLayoutProcessorStages m_nCurChildNodeStage;
+ FX_FLOAT m_fUsedSize;
+ CXFA_LayoutPageMgr* m_pPageMgr;
+ CFX_PtrList m_rgPendingNodes;
+ FX_BOOL m_bBreakPending;
+ CFX_ArrayTemplate<FX_FLOAT> m_rgSpecifiedColumnWidths;
+ CFX_ArrayTemplate<CXFA_ContentLayoutItemImpl*> m_arrayKeepItems;
+ CFX_MapPtrToPtr m_PendingNodesCount;
+ FX_FLOAT m_fLastRowWidth;
+ FX_FLOAT m_fLastRowY;
+ FX_FLOAT m_fWidthLimite;
+ FX_BOOL m_bUseInheriated;
+ XFA_ItemLayoutProcessorResult m_ePreProcessRs;
+ FX_BOOL m_bHasAvailHeight;
+};
+FX_BOOL XFA_ItemLayoutProcessor_IsTakingSpace(CXFA_Node* pNode);
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.cpp b/xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.cpp
new file mode 100644
index 0000000000..bc2d8104fd
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.cpp
@@ -0,0 +1,1680 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_document_datamerger_imp.h"
+#include "xfa_document_layout_imp.h"
+#include "xfa_layout_itemlayout.h"
+#include "xfa_layout_pagemgr_new.h"
+#include "xfa_layout_appadapter.h"
+CXFA_LayoutPageMgr::CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor)
+ : m_pLayoutProcessor(pLayoutProcessor)
+ , m_pTemplatePageSetRoot(NULL)
+ , m_pPageSetLayoutItemRoot(NULL)
+ , m_pCurrentContainerRecord(NULL)
+ , m_nCurPageCount(0)
+ , m_pCurPageArea(NULL)
+ , m_ePageSetMode(XFA_ATTRIBUTEENUM_OrderedOccurrence)
+ , m_nAvailPages(0)
+ , m_pPageSetCurRoot(NULL)
+ , m_bCreateOverFlowPage(FALSE)
+{
+}
+CXFA_LayoutPageMgr::~CXFA_LayoutPageMgr()
+{
+ ClearData();
+ CXFA_LayoutItemImpl *pLayoutItem = GetRootLayoutItem();
+ CXFA_LayoutItemImpl *pNextLayout = NULL;
+ for(; pLayoutItem; pLayoutItem = pNextLayout) {
+ pNextLayout = pLayoutItem->m_pNextSibling;
+ XFA_ReleaseLayoutItem(pLayoutItem);
+ }
+}
+FX_BOOL CXFA_LayoutPageMgr::InitLayoutPage(CXFA_Node* pFormNode)
+{
+ PrepareLayout();
+ CXFA_Node* pTemplateNode = pFormNode->GetTemplateNode();
+ if (!pTemplateNode) {
+ return FALSE;
+ }
+ m_pTemplatePageSetRoot = pTemplateNode->GetProperty(0, XFA_ELEMENT_PageSet);
+ ASSERT(m_pTemplatePageSetRoot);
+ if (m_pPageSetLayoutItemRoot) {
+ m_pPageSetLayoutItemRoot->m_pParent = NULL;
+ m_pPageSetLayoutItemRoot->m_pFirstChild = NULL;
+ m_pPageSetLayoutItemRoot->m_pNextSibling = NULL;
+ m_pPageSetLayoutItemRoot->m_pFormNode = m_pTemplatePageSetRoot;
+ } else {
+ m_pPageSetLayoutItemRoot = FX_NEW CXFA_ContainerLayoutItemImpl(m_pTemplatePageSetRoot);
+ }
+ m_pPageSetCurRoot = m_pPageSetLayoutItemRoot;
+ m_pTemplatePageSetRoot->SetUserData(XFA_LAYOUTITEMKEY, (FX_LPVOID)m_pPageSetLayoutItemRoot);
+ XFA_ATTRIBUTEENUM eRelation = m_pTemplatePageSetRoot->GetEnum(XFA_ATTRIBUTE_Relation);
+ if(eRelation != XFA_ATTRIBUTEENUM_Unknown) {
+ m_ePageSetMode = eRelation;
+ }
+ InitPageSetMap();
+ CXFA_Node* pPageArea = NULL;
+ FX_INT32 iCount = 0;
+ for (pPageArea = m_pTemplatePageSetRoot->GetNodeItem(XFA_NODEITEM_FirstChild); pPageArea; pPageArea = pPageArea->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pPageArea->GetClassID() == XFA_ELEMENT_PageArea) {
+ iCount++;
+ if (pPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea)) {
+ return TRUE;
+ }
+ }
+ }
+ if (iCount > 0) {
+ return FALSE;
+ }
+ CXFA_Document* pDocument = pTemplateNode->GetDocument();
+ IXFA_ObjFactory* pObjFactory = pDocument->GetParser()->GetFactory();
+ pPageArea = m_pTemplatePageSetRoot->GetChild(0, XFA_ELEMENT_PageArea);
+ if (!pPageArea) {
+ pPageArea = pObjFactory->CreateNode(m_pTemplatePageSetRoot->GetPacketID(), XFA_ELEMENT_PageArea);
+ if(!pPageArea) {
+ return FALSE;
+ }
+ m_pTemplatePageSetRoot->InsertChild(pPageArea, NULL);
+ pPageArea->SetFlag(XFA_NODEFLAG_Initialized);
+ }
+ CXFA_Node* pContentArea = pPageArea->GetChild(0, XFA_ELEMENT_ContentArea);
+ if (!pContentArea) {
+ pContentArea = pObjFactory->CreateNode(pPageArea->GetPacketID(), XFA_ELEMENT_ContentArea);
+ if(!pContentArea) {
+ return FALSE;
+ }
+ pPageArea->InsertChild(pContentArea, NULL);
+ pContentArea->SetFlag(XFA_NODEFLAG_Initialized);
+ pContentArea->SetMeasure(XFA_ATTRIBUTE_X, CXFA_Measurement(0.25f, XFA_UNIT_In));
+ pContentArea->SetMeasure(XFA_ATTRIBUTE_Y, CXFA_Measurement(0.25f, XFA_UNIT_In));
+ pContentArea->SetMeasure(XFA_ATTRIBUTE_W, CXFA_Measurement(8.0f, XFA_UNIT_In));
+ pContentArea->SetMeasure(XFA_ATTRIBUTE_H, CXFA_Measurement(10.5f, XFA_UNIT_In));
+ }
+ CXFA_Node* pMedium = pPageArea->GetChild(0, XFA_ELEMENT_Medium);
+ if (!pMedium) {
+ pMedium = pObjFactory->CreateNode(pPageArea->GetPacketID(), XFA_ELEMENT_Medium);
+ if(!pContentArea) {
+ return FALSE;
+ }
+ pPageArea->InsertChild(pMedium, NULL);
+ pMedium->SetFlag(XFA_NODEFLAG_Initialized);
+ pMedium->SetMeasure(XFA_ATTRIBUTE_Short, CXFA_Measurement(8.5f, XFA_UNIT_In));
+ pMedium->SetMeasure(XFA_ATTRIBUTE_Long, CXFA_Measurement(11.0f, XFA_UNIT_In));
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_LayoutPageMgr::PrepareFirstPage(CXFA_Node* pRootSubform)
+{
+ FX_BOOL bProBreakBefore = FALSE;
+ CXFA_Node* pBreakBeforeNode = NULL;
+ while (pRootSubform) {
+ for(CXFA_Node* pBreakNode = pRootSubform->GetNodeItem(XFA_NODEITEM_FirstChild); pBreakNode; pBreakNode = pBreakNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_ELEMENT eType = pBreakNode->GetClassID();
+ if (eType == XFA_ELEMENT_BreakBefore || (eType == XFA_ELEMENT_Break && pBreakNode->GetEnum(XFA_ATTRIBUTE_Before) != XFA_ATTRIBUTEENUM_Auto)) {
+ bProBreakBefore = TRUE;
+ pBreakBeforeNode = pBreakNode;
+ break;
+ }
+ }
+ if (bProBreakBefore) {
+ break;
+ }
+ bProBreakBefore = TRUE;
+ pRootSubform = pRootSubform->GetFirstChildByClass(XFA_ELEMENT_Subform);
+ while (pRootSubform && !XFA_ItemLayoutProcessor_IsTakingSpace(pRootSubform)) {
+ pRootSubform = pRootSubform->GetNextSameClassSibling(XFA_ELEMENT_Subform);
+ }
+ }
+ CXFA_Node* pLeader, *pTrailer;
+ if (pBreakBeforeNode && ExecuteBreakBeforeOrAfter(pBreakBeforeNode, TRUE, pLeader, pTrailer)) {
+ m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetHeadPosition();
+ return TRUE;
+ }
+ return AppendNewPage(TRUE);
+}
+FX_BOOL CXFA_LayoutPageMgr::AppendNewPage(FX_BOOL bFirstTemPage)
+{
+ if(m_pCurrentContainerRecord != m_rgProposedContainerRecord.GetTailPosition()) {
+ return TRUE;
+ }
+ CXFA_Node* pPageNode = GetNextAvailPageArea(NULL);
+ if (!pPageNode) {
+ return FALSE;
+ }
+ if (bFirstTemPage && m_pCurrentContainerRecord == NULL) {
+ m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetHeadPosition();
+ }
+ return !bFirstTemPage || m_pCurrentContainerRecord != NULL;
+}
+static void XFA_LayoutItemMgr_ReorderLayoutItemToTail(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+{
+ CXFA_ContainerLayoutItemImpl* pParentLayoutItem = (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pParent;
+ if(!pParentLayoutItem) {
+ return;
+ }
+ CXFA_LayoutItemImpl* pNext = pLayoutItem->m_pNextSibling;
+ pParentLayoutItem->RemoveChild(pLayoutItem);
+ pParentLayoutItem->AddChild(pLayoutItem);
+}
+static void XFA_LayoutItemMgr_RemoveLayoutItem(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+{
+ CXFA_ContainerLayoutItemImpl* pParentLayoutItem = (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pParent;
+ if(!pParentLayoutItem) {
+ return;
+ }
+ CXFA_LayoutItemImpl* pNext = pLayoutItem->m_pNextSibling;
+ pParentLayoutItem->RemoveChild(pLayoutItem);
+}
+void CXFA_LayoutPageMgr::RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord, CXFA_ContainerRecord* pPrevRecord)
+{
+ if(!pNewRecord || !pPrevRecord) {
+ return;
+ }
+ if(pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
+ XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurPageSet);
+ return;
+ }
+ if(pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
+ XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurPageArea);
+ return;
+ }
+ if(pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
+ XFA_LayoutItemMgr_RemoveLayoutItem(pNewRecord->pCurContentArea);
+ return;
+ }
+}
+void CXFA_LayoutPageMgr::ReorderPendingLayoutRecordToTail(CXFA_ContainerRecord* pNewRecord, CXFA_ContainerRecord* pPrevRecord)
+{
+ if(!pNewRecord || !pPrevRecord) {
+ return;
+ }
+ if(pNewRecord->pCurPageSet != pPrevRecord->pCurPageSet) {
+ XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurPageSet);
+ return;
+ }
+ if(pNewRecord->pCurPageArea != pPrevRecord->pCurPageArea) {
+ XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurPageArea);
+ return;
+ }
+ if(pNewRecord->pCurContentArea != pPrevRecord->pCurContentArea) {
+ XFA_LayoutItemMgr_ReorderLayoutItemToTail(pNewRecord->pCurContentArea);
+ return;
+ }
+}
+void CXFA_LayoutPageMgr::SubmitContentItem(CXFA_ContentLayoutItemImpl* pContentLayoutItem, XFA_ItemLayoutProcessorResult eStatus)
+{
+ if(pContentLayoutItem) {
+ GetCurrentContainerRecord()->pCurContentArea->AddChild(pContentLayoutItem);
+ m_bCreateOverFlowPage = FALSE;
+ }
+ if(eStatus != XFA_ItemLayoutProcessorResult_Done) {
+ if(eStatus == XFA_ItemLayoutProcessorResult_PageFullBreak && m_pCurrentContainerRecord == m_rgProposedContainerRecord.GetTailPosition()) {
+ AppendNewPage();
+ }
+ m_pCurrentContainerRecord = m_rgProposedContainerRecord.GetTailPosition();
+ m_pCurPageArea = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
+ }
+}
+FX_FLOAT CXFA_LayoutPageMgr::GetAvailHeight()
+{
+ FX_FLOAT fAvailHeight = GetCurrentContainerRecord()->pCurContentArea->m_pFormNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+ if (fAvailHeight < XFA_LAYOUT_FLOAT_PERCISION) {
+ if (m_pCurrentContainerRecord == m_rgProposedContainerRecord.GetHeadPosition()) {
+ fAvailHeight = 0;
+ } else {
+ fAvailHeight = XFA_LAYOUT_FLOAT_MAX;
+ }
+ }
+ return fAvailHeight;
+}
+static CXFA_Node* XFA_ResolveBreakTarget(CXFA_Node* pPageSetRoot, FX_BOOL bNewExprStyle, CFX_WideStringC& wsTargetExpr)
+{
+ CXFA_Document* pDocument = pPageSetRoot->GetDocument();
+ if(wsTargetExpr.IsEmpty()) {
+ return NULL;
+ }
+ CFX_WideString wsTargetAll = wsTargetExpr;
+ wsTargetAll.TrimLeft();
+ wsTargetAll.TrimRight();
+ FX_INT32 iSpliteIndex = 0;
+ FX_BOOL bTargetAllFind = TRUE;
+ while(iSpliteIndex != -1) {
+ CFX_WideString wsTargetExpr;
+ FX_INT32 iSpliteNextIndex = 0;
+ if(!bTargetAllFind) {
+ iSpliteNextIndex = wsTargetAll.Find(' ', iSpliteIndex);
+ wsTargetExpr = wsTargetAll.Mid(iSpliteIndex, iSpliteNextIndex - iSpliteIndex);
+ } else {
+ wsTargetExpr = wsTargetAll;
+ }
+ if(wsTargetExpr.IsEmpty()) {
+ return NULL;
+ }
+ bTargetAllFind = FALSE;
+ if(wsTargetExpr.GetAt(0) == '#') {
+ CXFA_Node *pNode = pDocument->GetNodeByID((CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Template), wsTargetExpr.Mid(1));
+ if(pNode) {
+ return pNode;
+ }
+ } else if(bNewExprStyle) {
+ CFX_WideString wsProcessedTarget = wsTargetExpr;
+ if(wsTargetExpr.Left(4) == FX_WSTRC(L"som(") && wsTargetExpr.Right(1) == FX_WSTRC(L")")) {
+ wsProcessedTarget = wsTargetExpr.Mid(4, wsTargetExpr.GetLength() - 5);
+ }
+ XFA_RESOLVENODE_RS rs;
+ FX_INT32 iCount = pDocument->GetScriptContext()->ResolveObjects(pPageSetRoot, wsProcessedTarget, rs, XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent);
+ if(iCount > 0 && rs.nodes[0]->IsNode()) {
+ return (CXFA_Node*)rs.nodes[0];
+ }
+ }
+ iSpliteIndex = iSpliteNextIndex;
+ }
+ return NULL;
+}
+
+FX_BOOL XFA_LayoutPageMgr_RunBreakTestScript(CXFA_Node* pTestScript)
+{
+ CFX_WideString wsExpression;
+ pTestScript->TryContent(wsExpression);
+ if(wsExpression.IsEmpty()) {
+ return TRUE;
+ }
+ return pTestScript->GetDocument()->GetParser()->GetNotify()->RunScript(pTestScript, pTestScript->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode));
+}
+CXFA_ContainerRecord* CXFA_LayoutPageMgr::CreateContainerRecord(CXFA_Node* pPageNode, FX_BOOL bCreateNew)
+{
+ CXFA_ContainerRecord* pNewRecord = FX_NEW CXFA_ContainerRecord();
+ if(m_pCurrentContainerRecord) {
+ if(!IsPageSetRootOrderedOccurrence() || pPageNode == NULL) {
+ *pNewRecord = *GetCurrentContainerRecord();
+ m_rgProposedContainerRecord.AddTail(pNewRecord);
+ return pNewRecord;
+ }
+ CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(!bCreateNew) {
+ if(pPageSet == m_pTemplatePageSetRoot) {
+ pNewRecord->pCurPageSet = m_pPageSetCurRoot;
+ } else {
+ CXFA_ContainerLayoutItemImpl* pParentLayoutItem = (CXFA_ContainerLayoutItemImpl*)pPageSet->GetUserData(XFA_LAYOUTITEMKEY);
+ if(pParentLayoutItem == NULL) {
+ pParentLayoutItem = m_pPageSetCurRoot;
+ }
+ pNewRecord->pCurPageSet = pParentLayoutItem;
+ }
+ } else {
+ CXFA_ContainerLayoutItemImpl* pParentPageSetLayout = NULL;
+ if(pPageSet == GetCurrentContainerRecord()->pCurPageSet->m_pFormNode) {
+ pParentPageSetLayout = (CXFA_ContainerLayoutItemImpl*)GetCurrentContainerRecord()->pCurPageSet->m_pParent;
+ } else {
+ pParentPageSetLayout = (CXFA_ContainerLayoutItemImpl*)pPageSet->GetNodeItem(XFA_NODEITEM_Parent)->GetUserData(XFA_LAYOUTITEMKEY);
+ }
+ CXFA_ContainerLayoutItemImpl* pPageSetLayoutItem = FX_NEW CXFA_ContainerLayoutItemImpl(pPageSet);
+ pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (FX_LPVOID)pPageSetLayoutItem);
+ if(pParentPageSetLayout == NULL) {
+ CXFA_ContainerLayoutItemImpl* pPrePageSet = m_pPageSetLayoutItemRoot;
+ while(pPrePageSet->m_pNextSibling) {
+ pPrePageSet = (CXFA_ContainerLayoutItemImpl*)pPrePageSet->m_pNextSibling;
+ }
+ pPrePageSet->m_pNextSibling = pPageSetLayoutItem;
+ m_pPageSetCurRoot = pPageSetLayoutItem;
+ } else {
+ pParentPageSetLayout->AddChild(pPageSetLayoutItem);
+ }
+ pNewRecord->pCurPageSet = pPageSetLayoutItem;
+ }
+ } else {
+ if(pPageNode) {
+ CXFA_Node* pPageSet = pPageNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(pPageSet == m_pTemplatePageSetRoot) {
+ pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
+ } else {
+ CXFA_ContainerLayoutItemImpl* pPageSetLayoutItem = FX_NEW CXFA_ContainerLayoutItemImpl(pPageSet);
+ pPageSet->SetUserData(XFA_LAYOUTITEMKEY, (FX_LPVOID)pPageSetLayoutItem);
+ m_pPageSetLayoutItemRoot->AddChild(pPageSetLayoutItem);
+ pNewRecord->pCurPageSet = pPageSetLayoutItem;
+ }
+ } else {
+ pNewRecord->pCurPageSet = m_pPageSetLayoutItemRoot;
+ }
+ }
+ m_rgProposedContainerRecord.AddTail(pNewRecord);
+ return pNewRecord;
+}
+void CXFA_LayoutPageMgr::AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord, CXFA_Node* pNewPageArea)
+{
+ CXFA_ContainerLayoutItemImpl* pNewPageAreaLayoutItem = NULL;
+ if (m_PageArray.GetSize() > m_nAvailPages) {
+ CXFA_ContainerLayoutItemImpl* pContainerItem = m_PageArray[m_nAvailPages];
+ pContainerItem->m_pFormNode = pNewPageArea;
+ m_nAvailPages++;
+ pNewPageAreaLayoutItem = pContainerItem;
+ } else {
+ IXFA_Notify* pNotify = pNewPageArea->GetDocument()->GetParser()->GetNotify();
+ CXFA_ContainerLayoutItemImpl* pContainerItem = (CXFA_ContainerLayoutItemImpl*)pNotify->OnCreateLayoutItem(pNewPageArea);
+ m_PageArray.Add(pContainerItem);
+ m_nAvailPages++;
+ pNotify->OnPageEvent((IXFA_LayoutPage*)pContainerItem, XFA_PAGEEVENT_PageAdded, (FX_LPVOID)(FX_UINTPTR)m_nAvailPages);
+ pNewPageAreaLayoutItem = pContainerItem;
+ }
+ pNewRecord->pCurPageSet->AddChild(pNewPageAreaLayoutItem);
+ pNewRecord->pCurPageArea = pNewPageAreaLayoutItem;
+ pNewRecord->pCurContentArea = NULL;
+}
+void CXFA_LayoutPageMgr::AddContentAreaLayoutItem(CXFA_ContainerRecord* pNewRecord, CXFA_Node* pContentArea)
+{
+ if(pContentArea == NULL) {
+ pNewRecord->pCurContentArea = NULL;
+ return;
+ }
+ CXFA_ContainerLayoutItemImpl* pNewContentAreaLayoutItem = FX_NEW CXFA_ContainerLayoutItemImpl(pContentArea);
+ ASSERT(pNewRecord->pCurPageArea);
+ pNewRecord->pCurPageArea->AddChild(pNewContentAreaLayoutItem);
+ pNewRecord->pCurContentArea = pNewContentAreaLayoutItem;
+}
+class CXFA_TraverseStrategy_PageSetContainerLayoutItem
+{
+public:
+ static inline CXFA_ContainerLayoutItemImpl* GetFirstChild(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ if(pLayoutItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageSet) {
+ CXFA_ContainerLayoutItemImpl* pChildItem = (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pFirstChild;
+ while(pChildItem && pChildItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageSet) {
+ pChildItem = (CXFA_ContainerLayoutItemImpl*)pChildItem->m_pNextSibling;
+ }
+ return pChildItem;
+ }
+ return NULL;
+ }
+ static inline CXFA_ContainerLayoutItemImpl* GetNextSibling(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ CXFA_ContainerLayoutItemImpl* pChildItem = (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pNextSibling;
+ while(pChildItem && pChildItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageSet) {
+ pChildItem = (CXFA_ContainerLayoutItemImpl*)pChildItem->m_pNextSibling;
+ }
+ return pChildItem;
+ }
+ static inline CXFA_ContainerLayoutItemImpl* GetParent(CXFA_ContainerLayoutItemImpl* pLayoutItem)
+ {
+ return (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pParent;
+ }
+};
+void CXFA_LayoutPageMgr::FinishPaginatedPageSets()
+{
+ CXFA_ContainerLayoutItemImpl* pRootPageSetLayoutItem = m_pPageSetLayoutItemRoot;
+ for (; pRootPageSetLayoutItem; pRootPageSetLayoutItem = (CXFA_ContainerLayoutItemImpl*)pRootPageSetLayoutItem->m_pNextSibling) {
+ CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItemImpl, CXFA_TraverseStrategy_PageSetContainerLayoutItem> sIterator(pRootPageSetLayoutItem);
+ for(CXFA_ContainerLayoutItemImpl *pPageSetLayoutItem = sIterator.GetCurrent(); pPageSetLayoutItem; pPageSetLayoutItem = sIterator.MoveToNext()) {
+ XFA_ATTRIBUTEENUM ePageRelation = pPageSetLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Relation);
+ switch(ePageRelation) {
+ case XFA_ATTRIBUTEENUM_OrderedOccurrence:
+ default: {
+ ProcessLastPageSet();
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_SimplexPaginated:
+ case XFA_ATTRIBUTEENUM_DuplexPaginated: {
+ CXFA_LayoutItemImpl* pLastPageAreaLayoutItem = NULL;
+ FX_INT32 nPageAreaCount = 0;
+ for(CXFA_LayoutItemImpl* pPageAreaLayoutItem = pPageSetLayoutItem->m_pFirstChild; pPageAreaLayoutItem; pPageAreaLayoutItem = pPageAreaLayoutItem->m_pNextSibling) {
+ if(pPageAreaLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) {
+ continue;
+ }
+ nPageAreaCount++;
+ pLastPageAreaLayoutItem = pPageAreaLayoutItem;
+ }
+ if(!pLastPageAreaLayoutItem) {
+ break;
+ }
+ if (!FindPageAreaFromPageSet_SimplexDuplex(pPageSetLayoutItem->m_pFormNode, NULL, NULL, NULL, TRUE, TRUE, nPageAreaCount == 1 ? XFA_ATTRIBUTEENUM_Only : XFA_ATTRIBUTEENUM_Last)
+ && (nPageAreaCount == 1 && !FindPageAreaFromPageSet_SimplexDuplex(pPageSetLayoutItem->m_pFormNode, NULL, NULL, NULL, TRUE, TRUE, XFA_ATTRIBUTEENUM_Last))) {
+ break;
+ }
+ CXFA_Node *pNode = m_pCurPageArea;
+ XFA_ATTRIBUTEENUM eCurChoice = pNode->GetEnum(XFA_ATTRIBUTE_PagePosition);
+ if(eCurChoice == XFA_ATTRIBUTEENUM_Last) {
+ XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any;
+ pNode->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven);
+ XFA_ATTRIBUTEENUM eLastChoice = pLastPageAreaLayoutItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_PagePosition);
+ if (eLastChoice == XFA_ATTRIBUTEENUM_First && (ePageRelation == XFA_ATTRIBUTEENUM_SimplexPaginated || eOddOrEven != XFA_ATTRIBUTEENUM_Odd)) {
+ CXFA_ContainerRecord* pRecord = CreateContainerRecord();
+ AddPageAreaLayoutItem(pRecord, pNode);
+ break;;
+ }
+ }
+ FX_BOOL bUsable = TRUE;
+ CFX_ArrayTemplate<FX_FLOAT> rgUsedHeights;
+ for(CXFA_LayoutItemImpl* pChildLayoutItem = pLastPageAreaLayoutItem->m_pFirstChild; pChildLayoutItem; pChildLayoutItem = pChildLayoutItem->m_pNextSibling) {
+ if(pChildLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+ continue;
+ }
+ FX_FLOAT fUsedHeight = 0;
+ for(CXFA_LayoutItemImpl* pContentChildLayoutItem = pChildLayoutItem->m_pFirstChild; pContentChildLayoutItem; pContentChildLayoutItem = pContentChildLayoutItem->m_pNextSibling) {
+ if(!pContentChildLayoutItem->IsContentLayoutItem()) {
+ continue;
+ }
+ fUsedHeight += ((CXFA_ContentLayoutItemImpl*)pContentChildLayoutItem)->m_sSize.y;
+ }
+ rgUsedHeights.Add(fUsedHeight);
+ }
+ FX_INT32 iCurContentAreaIndex = -1;
+ for(CXFA_Node* pContentAreaNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pContentAreaNode; pContentAreaNode = pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pContentAreaNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+ continue;
+ }
+ iCurContentAreaIndex++;
+ if(rgUsedHeights[iCurContentAreaIndex] > pContentAreaNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt) + XFA_LAYOUT_FLOAT_PERCISION) {
+ bUsable = FALSE;
+ break;
+ }
+ }
+ if(bUsable) {
+ CXFA_LayoutItemImpl* pChildLayoutItem = pLastPageAreaLayoutItem->m_pFirstChild;
+ CXFA_Node* pContentAreaNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ pLastPageAreaLayoutItem->m_pFormNode = pNode;
+ while(pChildLayoutItem && pContentAreaNode) {
+ if(pChildLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+ pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
+ continue;
+ }
+ if(pContentAreaNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+ pContentAreaNode = pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ continue;
+ }
+ pChildLayoutItem->m_pFormNode = pContentAreaNode;
+ pChildLayoutItem = pChildLayoutItem->m_pNextSibling;
+ pContentAreaNode = pContentAreaNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ } else if(pNode->GetEnum(XFA_ATTRIBUTE_PagePosition) == XFA_ATTRIBUTEENUM_Last) {
+ CXFA_ContainerRecord* pRecord = CreateContainerRecord();
+ AddPageAreaLayoutItem(pRecord, pNode);
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+FX_INT32 CXFA_LayoutPageMgr::GetPageCount() const
+{
+ return m_PageArray.GetSize();
+}
+IXFA_LayoutPage* CXFA_LayoutPageMgr::GetPage(FX_INT32 index) const
+{
+ if (m_PageArray.GetSize() > index) {
+ return (IXFA_LayoutPage*)m_PageArray[index];
+ }
+ return NULL;
+}
+FX_INT32 CXFA_LayoutPageMgr::GetPageIndex(IXFA_LayoutPage* pPage) const
+{
+ return m_PageArray.Find((CXFA_ContainerLayoutItemImpl*)pPage);
+}
+FX_BOOL CXFA_LayoutPageMgr::RunBreak(XFA_ELEMENT eBreakType, XFA_ATTRIBUTEENUM eTargetType, CXFA_Node* pTarget, FX_BOOL bStartNew)
+{
+ FX_BOOL bRet = FALSE;
+ switch(eTargetType) {
+ case XFA_ATTRIBUTEENUM_ContentArea:
+ if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_ContentArea) {
+ pTarget = NULL;
+ }
+ if (!pTarget || !m_pCurrentContainerRecord || pTarget != GetCurrentContainerRecord()->pCurContentArea->m_pFormNode || bStartNew) {
+ CXFA_Node* pPageArea = NULL;
+ if(pTarget) {
+ pPageArea = pTarget->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ pPageArea = GetNextAvailPageArea(pPageArea, pTarget);
+ bRet = pPageArea != NULL;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_PageArea:
+ if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) {
+ pTarget = NULL;
+ }
+ if (!pTarget || !m_pCurrentContainerRecord || pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode || bStartNew) {
+ CXFA_Node* pPageArea = GetNextAvailPageArea(pTarget, NULL, TRUE);
+ bRet = pPageArea != NULL;
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_PageOdd:
+ if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) {
+ pTarget = NULL;
+ }
+ if (m_nAvailPages % 2 != 1 || !m_pCurrentContainerRecord || (pTarget && pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode) || bStartNew) {
+ if(m_nAvailPages % 2 == 1) {
+ }
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_PageEven:
+ if (pTarget && pTarget->GetClassID() != XFA_ELEMENT_PageArea) {
+ pTarget = NULL;
+ }
+ if (m_nAvailPages % 2 != 0 || !m_pCurrentContainerRecord || (pTarget && pTarget != GetCurrentContainerRecord()->pCurPageArea->m_pFormNode) || bStartNew) {
+ if(m_nAvailPages % 2 == 0) {
+ }
+ }
+ break;
+ case XFA_ATTRIBUTEENUM_Auto:
+ default:
+ break;;
+ }
+ return bRet;
+}
+FX_BOOL CXFA_LayoutPageMgr::ExecuteBreakBeforeOrAfter(CXFA_Node* pCurNode, FX_BOOL bBefore, CXFA_Node* &pBreakLeaderTemplate, CXFA_Node* &pBreakTrailerTemplate)
+{
+ XFA_ELEMENT eType = pCurNode->GetClassID();
+ switch(eType) {
+ case XFA_ELEMENT_BreakBefore:
+ case XFA_ELEMENT_BreakAfter: {
+ CFX_WideStringC wsBreakLeader, wsBreakTrailer;
+ CXFA_Node* pFormNode = pCurNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ CXFA_Node *pContainer = pFormNode->GetTemplateNode();
+ FX_BOOL bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0;
+ CXFA_Node *pScript = pCurNode->GetFirstChildByClass(XFA_ELEMENT_Script);
+ if(pScript && !XFA_LayoutPageMgr_RunBreakTestScript(pScript)) {
+ return FALSE;
+ }
+ CFX_WideStringC wsTarget = pCurNode->GetCData(XFA_ATTRIBUTE_Target);
+ CXFA_Node* pTarget = XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE, wsTarget);
+ wsBreakTrailer = pCurNode->GetCData(XFA_ATTRIBUTE_Trailer);
+ wsBreakLeader = pCurNode->GetCData(XFA_ATTRIBUTE_Leader);
+ pBreakLeaderTemplate = XFA_ResolveBreakTarget(pContainer, TRUE, wsBreakLeader);
+ pBreakTrailerTemplate = XFA_ResolveBreakTarget(pContainer, TRUE, wsBreakTrailer);
+ if(RunBreak(eType, pCurNode->GetEnum(XFA_ATTRIBUTE_TargetType), pTarget, bStartNew)) {
+ return TRUE;
+ } else {
+ if(m_rgProposedContainerRecord.GetCount() > 0 && m_pCurrentContainerRecord == m_rgProposedContainerRecord.GetHeadPosition()
+ && eType == XFA_ELEMENT_BreakBefore) {
+ CXFA_Node* pParentNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ if(!pParentNode || pFormNode != pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild, XFA_OBJECTTYPE_ContainerNode)) {
+ break;
+ }
+ pParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(!pParentNode || pParentNode->GetClassID() != XFA_ELEMENT_Form) {
+ break;
+ }
+ return TRUE;
+ }
+ }
+ }
+ break;
+ case XFA_ELEMENT_Break: {
+ FX_BOOL bStartNew = pCurNode->GetInteger(XFA_ATTRIBUTE_StartNew) != 0;
+ CFX_WideStringC wsTarget = pCurNode->GetCData(bBefore ? XFA_ATTRIBUTE_BeforeTarget : XFA_ATTRIBUTE_AfterTarget);
+ CXFA_Node* pTarget = XFA_ResolveBreakTarget(m_pTemplatePageSetRoot, TRUE, wsTarget);
+ if(RunBreak(bBefore ? XFA_ELEMENT_BreakBefore : XFA_ELEMENT_BreakAfter, pCurNode->GetEnum(bBefore ? XFA_ATTRIBUTE_Before : XFA_ATTRIBUTE_After), pTarget, bStartNew)) {
+ return TRUE;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+static void XFA_SetLayoutGeneratedNodeFlag(CXFA_Node* pNode)
+{
+ pNode->SetFlag(XFA_NODEFLAG_LayoutGeneratedNode, TRUE, FALSE);
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE, FALSE);
+}
+FX_BOOL CXFA_LayoutPageMgr::ProcessBreakBeforeOrAfter(CXFA_Node* pBreakNode, FX_BOOL bBefore, CXFA_Node* &pBreakLeaderNode, CXFA_Node* &pBreakTrailerNode, FX_BOOL& bCreatePage)
+{
+ CXFA_Node *pLeaderTemplate = NULL, *pTrailerTemplate = NULL;
+ CXFA_Node *pFormNode = pBreakNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ if(XFA_ItemLayoutProcessor_IsTakingSpace(pFormNode)) {
+ bCreatePage = ExecuteBreakBeforeOrAfter(pBreakNode, bBefore, pLeaderTemplate, pTrailerTemplate);
+ CXFA_Document* pDocument = pBreakNode->GetDocument();
+ CXFA_Node* pDataScope = NULL;
+ pFormNode = pFormNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ if(pLeaderTemplate) {
+ if(!pDataScope) {
+ pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+ }
+ pBreakLeaderNode = pDocument->DataMerge_CopyContainer(pLeaderTemplate, pFormNode, pDataScope, TRUE);
+ pDocument->DataMerge_UpdateBindingRelations(pBreakLeaderNode);
+ XFA_SetLayoutGeneratedNodeFlag(pBreakLeaderNode);
+ }
+ if(pTrailerTemplate) {
+ if(!pDataScope) {
+ pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+ }
+ pBreakTrailerNode = pDocument->DataMerge_CopyContainer(pTrailerTemplate, pFormNode, pDataScope, TRUE);
+ pDocument->DataMerge_UpdateBindingRelations(pBreakTrailerNode);
+ XFA_SetLayoutGeneratedNodeFlag(pBreakTrailerNode);
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_LayoutPageMgr::ProcessBookendLeaderOrTrailer(CXFA_Node* pBookendNode, FX_BOOL bLeader, CXFA_Node* &pBookendAppendNode)
+{
+ CXFA_Node* pLeaderTemplate = NULL;
+ CXFA_Node* pFormNode = pBookendNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ if(ResolveBookendLeaderOrTrailer(pBookendNode, bLeader, pLeaderTemplate)) {
+ CXFA_Document *pDocument = pBookendNode->GetDocument();
+ CXFA_Node *pDataScope = NULL;
+ if(pLeaderTemplate) {
+ if(!pDataScope) {
+ pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+ }
+ pBookendAppendNode = pDocument->DataMerge_CopyContainer(pLeaderTemplate, pFormNode, pDataScope, TRUE);
+ pDocument->DataMerge_UpdateBindingRelations(pBookendAppendNode);
+ XFA_SetLayoutGeneratedNodeFlag(pBookendAppendNode);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+CXFA_Node* CXFA_LayoutPageMgr::BreakOverflow(CXFA_Node* pOverflowNode, CXFA_Node*& pLeaderTemplate, CXFA_Node*& pTrailerTemplate, FX_BOOL bCreatePage )
+{
+ CFX_WideStringC wsOverflowLeader, wsOverflowTrailer;
+ CXFA_Node *pContainer = pOverflowNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode)->GetTemplateNode();
+ if(pOverflowNode->GetClassID() == XFA_ELEMENT_Break) {
+ CFX_WideStringC wsOverflowLeader;
+ CFX_WideStringC wsOverflowTarget;
+ CFX_WideStringC wsOverflowTrailer;
+ pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader);
+ pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer);
+ pOverflowNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget);
+ if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() || !wsOverflowTarget.IsEmpty()) {
+ if(!wsOverflowTarget.IsEmpty() && bCreatePage && !m_bCreateOverFlowPage) {
+ CXFA_Node* pTarget = XFA_ResolveBreakTarget(this->m_pTemplatePageSetRoot, TRUE, wsOverflowTarget);
+ if(pTarget) {
+ m_bCreateOverFlowPage = TRUE;
+ switch(pTarget->GetClassID()) {
+ case XFA_ELEMENT_PageArea:
+ RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_PageArea, pTarget, TRUE);
+ break;
+ case XFA_ELEMENT_ContentArea:
+ RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_ContentArea, pTarget, TRUE);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if(!bCreatePage) {
+ pLeaderTemplate = XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowLeader);
+ pTrailerTemplate = XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowTrailer);
+ }
+ return pOverflowNode;
+ }
+ return NULL;
+ } else if(pOverflowNode->GetClassID() == XFA_ELEMENT_Overflow) {
+ CFX_WideStringC wsOverflowTarget;
+ pOverflowNode->TryCData(XFA_ATTRIBUTE_Leader, wsOverflowLeader);
+ pOverflowNode->TryCData(XFA_ATTRIBUTE_Trailer, wsOverflowTrailer);
+ pOverflowNode->TryCData(XFA_ATTRIBUTE_Target, wsOverflowTarget);
+ if(!wsOverflowTarget.IsEmpty() && bCreatePage && !m_bCreateOverFlowPage) {
+ CXFA_Node* pTarget = XFA_ResolveBreakTarget(this->m_pTemplatePageSetRoot, TRUE, wsOverflowTarget);
+ if(pTarget) {
+ m_bCreateOverFlowPage = TRUE;
+ switch(pTarget->GetClassID()) {
+ case XFA_ELEMENT_PageArea:
+ RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_PageArea, pTarget, TRUE);
+ break;
+ case XFA_ELEMENT_ContentArea:
+ RunBreak(XFA_ELEMENT_Overflow, XFA_ATTRIBUTEENUM_ContentArea, pTarget, TRUE);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if(!bCreatePage) {
+ pLeaderTemplate = XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowLeader);
+ pTrailerTemplate = XFA_ResolveBreakTarget(pContainer, TRUE, wsOverflowTrailer);
+ }
+ return pOverflowNode;
+ }
+ return NULL;
+}
+FX_BOOL CXFA_LayoutPageMgr::ProcessOverflow(CXFA_Node* pFormNode, CXFA_Node* &pLeaderNode, CXFA_Node* &pTrailerNode, FX_BOOL bDataMerge, FX_BOOL bCreatePage)
+{
+ if(pFormNode == NULL) {
+ return FALSE;
+ }
+ CXFA_Node *pLeaderTemplate = NULL, *pTrailerTemplate = NULL;
+ FX_BOOL bIsOverflowNode = FALSE;
+ if(pFormNode->GetClassID() == XFA_ELEMENT_Overflow || pFormNode->GetClassID() == XFA_ELEMENT_Break) {
+ bIsOverflowNode = TRUE;
+ }
+ for(CXFA_Node* pCurNode = bIsOverflowNode ? pFormNode : pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
+ if(BreakOverflow(pCurNode, pLeaderTemplate, pTrailerTemplate, bCreatePage)) {
+ if(bIsOverflowNode) {
+ pFormNode = pCurNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ CXFA_Document *pDocument = pCurNode->GetDocument();
+ CXFA_Node *pDataScope = NULL;
+ if(pLeaderTemplate) {
+ if(!pDataScope) {
+ pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+ }
+ pLeaderNode = pDocument->DataMerge_CopyContainer(pLeaderTemplate, pFormNode, pDataScope, TRUE);
+ pDocument->DataMerge_UpdateBindingRelations(pLeaderNode);
+ XFA_SetLayoutGeneratedNodeFlag(pLeaderNode);
+ }
+ if(pTrailerTemplate) {
+ if(!pDataScope) {
+ pDataScope = XFA_DataMerge_FindDataScope(pFormNode);
+ }
+ pTrailerNode = pDocument->DataMerge_CopyContainer(pTrailerTemplate, pFormNode, pDataScope, TRUE);
+ pDocument->DataMerge_UpdateBindingRelations(pTrailerNode);
+ XFA_SetLayoutGeneratedNodeFlag(pTrailerNode);
+ }
+ return TRUE;
+ }
+ if(bIsOverflowNode) {
+ break;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_LayoutPageMgr::ResolveBookendLeaderOrTrailer(CXFA_Node* pBookendNode, FX_BOOL bLeader, CXFA_Node* &pBookendAppendTemplate)
+{
+ CFX_WideStringC wsBookendLeader;
+ CXFA_Node *pContainer = pBookendNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode)->GetTemplateNode();
+ if(pBookendNode->GetClassID() == XFA_ELEMENT_Break) {
+ pBookendNode->TryCData(bLeader ? XFA_ATTRIBUTE_BookendLeader : XFA_ATTRIBUTE_BookendTrailer, wsBookendLeader);
+ if (!wsBookendLeader.IsEmpty()) {
+ pBookendAppendTemplate = XFA_ResolveBreakTarget(pContainer, FALSE, wsBookendLeader);
+ return TRUE;
+ }
+ return FALSE;
+ } else if(pBookendNode->GetClassID() == XFA_ELEMENT_Bookend) {
+ pBookendNode->TryCData(bLeader ? XFA_ATTRIBUTE_Leader : XFA_ATTRIBUTE_Trailer, wsBookendLeader);
+ pBookendAppendTemplate = XFA_ResolveBreakTarget(pContainer, TRUE, wsBookendLeader);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet(CXFA_Node* pPageSet, CXFA_Node* pStartChild, CXFA_Node* pTargetPageArea, CXFA_Node* pTargetContentArea, FX_BOOL bNewPage, FX_BOOL bQuery)
+{
+ if(pPageSet == NULL && pStartChild == NULL) {
+ return FALSE;
+ }
+ FX_INT32 iPageSetCount = 0;
+ if(IsPageSetRootOrderedOccurrence()) {
+ return FindPageAreaFromPageSet_Ordered(pPageSet, pStartChild, pTargetPageArea, pTargetContentArea, bNewPage, bQuery);
+ }
+ XFA_ATTRIBUTEENUM ePreferredPosition = m_pCurrentContainerRecord ? XFA_ATTRIBUTEENUM_Rest : XFA_ATTRIBUTEENUM_First;
+ return FindPageAreaFromPageSet_SimplexDuplex(pPageSet, pStartChild, pTargetPageArea, pTargetContentArea, bNewPage, bQuery, ePreferredPosition);
+}
+FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet, CXFA_Node* pStartChild, CXFA_Node* pTargetPageArea, CXFA_Node* pTargetContentArea, FX_BOOL bNewPage, FX_BOOL bQuery)
+{
+ FX_INT32 iPageSetCount = 0;
+ if(!pStartChild && !bQuery) {
+ m_pPageSetMap.Lookup(pPageSet, iPageSetCount);
+ FX_INT32 iMax = -1;
+ CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ if(pOccurNode) {
+ pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+ }
+ if (iMax >= 0 && iMax <= iPageSetCount) {
+ return FALSE;
+ }
+ }
+ FX_BOOL bRes = FALSE;
+ CXFA_Node *pCurrentNode = pStartChild ? pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling) : pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for(; pCurrentNode; pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ if((pTargetPageArea == pCurrentNode || pTargetPageArea == NULL)) {
+ if (pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea) == NULL) {
+ if(pTargetPageArea == pCurrentNode) {
+ CreateMinPageRecord(pCurrentNode, TRUE);
+ pTargetPageArea = NULL;
+ }
+ continue;
+ }
+ if (!bQuery) {
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(pCurrentNode, pStartChild == NULL);
+ AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+ if(pTargetContentArea == NULL) {
+ pTargetContentArea = pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+ }
+ AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
+ }
+ m_pCurPageArea = pCurrentNode;
+ m_nCurPageCount = 1;
+ bRes = TRUE;
+ break;
+ }
+ if(!bQuery) {
+ CreateMinPageRecord(pCurrentNode, FALSE);
+ }
+ } else if(pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) {
+ if(FindPageAreaFromPageSet_Ordered(pCurrentNode, NULL, pTargetPageArea, pTargetContentArea, bNewPage, bQuery)) {
+ bRes = TRUE;
+ break;
+ }
+ if(!bQuery) {
+ CreateMinPageSetRecord(pCurrentNode, TRUE);
+ }
+ }
+ }
+ if(!pStartChild && bRes && !bQuery) {
+ m_pPageSetMap.SetAt(pPageSet, ++ iPageSetCount);
+ }
+ return bRes;
+}
+FX_BOOL CXFA_LayoutPageMgr::FindPageAreaFromPageSet_SimplexDuplex(CXFA_Node* pPageSet, CXFA_Node* pStartChild, CXFA_Node* pTargetPageArea, CXFA_Node* pTargetContentArea, FX_BOOL bNewPage, FX_BOOL bQuery, XFA_ATTRIBUTEENUM ePreferredPosition)
+{
+ XFA_ATTRIBUTEENUM eAdvisedPagePosition = pTargetPageArea ? pTargetPageArea->GetEnum(XFA_ATTRIBUTE_PagePosition) : (XFA_ATTRIBUTEENUM) - 1;
+ const XFA_ATTRIBUTEENUM eFallbackPosition = XFA_ATTRIBUTEENUM_Any;
+ CXFA_Node *pPreferredPageArea = NULL, *pFallbackPageArea = NULL;
+ CXFA_Node* pCurrentNode = NULL;
+ if (!pStartChild || pStartChild->GetClassID() == XFA_ELEMENT_PageArea) {
+ pCurrentNode = pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild);
+ } else {
+ pCurrentNode = pStartChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ for(; pCurrentNode; pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ if(!MatchPageAreaOddOrEven(pCurrentNode, FALSE)) {
+ continue;
+ }
+ XFA_ATTRIBUTEENUM eCurPagePosition = pCurrentNode->GetEnum(XFA_ATTRIBUTE_PagePosition);
+ if(ePreferredPosition == XFA_ATTRIBUTEENUM_Last) {
+ if (eCurPagePosition != ePreferredPosition) {
+ continue;
+ }
+ if (m_ePageSetMode == XFA_ATTRIBUTEENUM_SimplexPaginated || pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) == XFA_ATTRIBUTEENUM_Any) {
+ pPreferredPageArea = pCurrentNode;
+ break;
+ }
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+ AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+ AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea));
+ pPreferredPageArea = pCurrentNode;
+ return FALSE;
+ } else if(ePreferredPosition == XFA_ATTRIBUTEENUM_Only) {
+ if (eCurPagePosition != ePreferredPosition) {
+ continue;
+ }
+ if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated || pCurrentNode->GetEnum(XFA_ATTRIBUTE_OddOrEven) == XFA_ATTRIBUTEENUM_Any) {
+ pPreferredPageArea = pCurrentNode;
+ break;
+ }
+ return FALSE;
+ }
+ if((pTargetPageArea == pCurrentNode || pTargetPageArea == NULL)) {
+ if (pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea) == NULL) {
+ if(pTargetPageArea == pCurrentNode) {
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+ AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+ pTargetPageArea = NULL;
+ }
+ continue;
+ }
+ if((ePreferredPosition == XFA_ATTRIBUTEENUM_Rest && eCurPagePosition == XFA_ATTRIBUTEENUM_Any) || eCurPagePosition == ePreferredPosition) {
+ pPreferredPageArea = pCurrentNode;
+ break;
+ } else if(eCurPagePosition == eFallbackPosition && !pFallbackPageArea) {
+ pFallbackPageArea = pCurrentNode;
+ }
+ } else if (pTargetPageArea && !MatchPageAreaOddOrEven(pTargetPageArea, FALSE)) {
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+ AddPageAreaLayoutItem(pNewRecord, pCurrentNode);
+ AddContentAreaLayoutItem(pNewRecord, pCurrentNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea));
+ }
+ } else if(pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) {
+ if(FindPageAreaFromPageSet_SimplexDuplex(pCurrentNode, NULL, pTargetPageArea, pTargetContentArea, bNewPage, bQuery, ePreferredPosition)) {
+ break;
+ }
+ }
+ }
+ CXFA_Node* pCurPageArea = NULL;
+ if(pPreferredPageArea) {
+ pCurPageArea = pPreferredPageArea;
+ } else if(pFallbackPageArea) {
+ pCurPageArea = pFallbackPageArea;
+ }
+ if (!pCurPageArea) {
+ return FALSE;
+ }
+ if (!bQuery) {
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+ AddPageAreaLayoutItem(pNewRecord, pCurPageArea);
+ if(pTargetContentArea == NULL) {
+ pTargetContentArea = pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+ }
+ AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
+ }
+ m_pCurPageArea = pCurPageArea;
+ return TRUE;
+}
+FX_BOOL CXFA_LayoutPageMgr::MatchPageAreaOddOrEven(CXFA_Node* pPageArea, FX_BOOL bLastMatch)
+{
+ if (m_ePageSetMode != XFA_ATTRIBUTEENUM_DuplexPaginated) {
+ return TRUE;
+ }
+ XFA_ATTRIBUTEENUM eOddOrEven = XFA_ATTRIBUTEENUM_Any;
+ pPageArea->TryEnum(XFA_ATTRIBUTE_OddOrEven, eOddOrEven);
+ if (eOddOrEven != XFA_ATTRIBUTEENUM_Any) {
+ FX_INT32 iPageCount = GetPageCount();
+ if (bLastMatch) {
+ return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 1 : iPageCount % 2 == 0;
+ }
+ return eOddOrEven == XFA_ATTRIBUTEENUM_Odd ? iPageCount % 2 == 0 : iPageCount % 2 == 1;
+ }
+ return TRUE;
+}
+CXFA_Node* CXFA_LayoutPageMgr::GetNextAvailPageArea(CXFA_Node* pTargetPageArea, CXFA_Node* pTargetContentArea, FX_BOOL bNewPage, FX_BOOL bQuery)
+{
+ if(m_pCurPageArea == NULL) {
+ FindPageAreaFromPageSet(m_pTemplatePageSetRoot, NULL, pTargetPageArea, pTargetContentArea, bNewPage, bQuery);
+ ASSERT(m_pCurPageArea);
+ return m_pCurPageArea;
+ }
+ if(pTargetPageArea == NULL || pTargetPageArea == m_pCurPageArea) {
+ if(!bNewPage && GetNextContentArea(pTargetContentArea)) {
+ return m_pCurPageArea;
+ }
+ if(IsPageSetRootOrderedOccurrence()) {
+ FX_INT32 iMax = -1;
+ CXFA_Node* pOccurNode = m_pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ if(pOccurNode) {
+ pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+ }
+ if((iMax < 0 || m_nCurPageCount < iMax)) {
+ if (!bQuery) {
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord(m_pCurPageArea);
+ AddPageAreaLayoutItem(pNewRecord, m_pCurPageArea);
+ if(pTargetContentArea == NULL) {
+ pTargetContentArea = m_pCurPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+ }
+ AddContentAreaLayoutItem(pNewRecord, pTargetContentArea);
+ }
+ m_nCurPageCount ++;
+ return m_pCurPageArea;
+ }
+ }
+ }
+ if(!bQuery && IsPageSetRootOrderedOccurrence()) {
+ CreateMinPageRecord(m_pCurPageArea, FALSE, TRUE);
+ }
+ if(FindPageAreaFromPageSet(m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent), m_pCurPageArea, pTargetPageArea, pTargetContentArea, bNewPage, bQuery)) {
+ return m_pCurPageArea;
+ }
+ CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
+ while(TRUE) {
+ if (FindPageAreaFromPageSet(pPageSet, NULL, pTargetPageArea, pTargetContentArea, bNewPage, bQuery)) {
+ return m_pCurPageArea;
+ }
+ if(!bQuery && IsPageSetRootOrderedOccurrence()) {
+ CreateMinPageSetRecord(pPageSet);
+ }
+ if(FindPageAreaFromPageSet(NULL, pPageSet, pTargetPageArea, pTargetContentArea, bNewPage, bQuery)) {
+ return m_pCurPageArea;
+ }
+ if(pPageSet == m_pTemplatePageSetRoot) {
+ break;
+ }
+ pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ return NULL;
+}
+static FX_BOOL XFA_LayoutPageMgr_CheckContentAreaNotUsed(CXFA_ContainerLayoutItemImpl* pPageAreaLayoutItem, CXFA_Node* pContentArea, CXFA_ContainerLayoutItemImpl*& pContentAreaLayoutItem)
+{
+ for(CXFA_ContainerLayoutItemImpl* pLayoutItem = (CXFA_ContainerLayoutItemImpl*)pPageAreaLayoutItem->m_pFirstChild; pLayoutItem; pLayoutItem = (CXFA_ContainerLayoutItemImpl*)pLayoutItem->m_pNextSibling) {
+ if(pLayoutItem->m_pFormNode == pContentArea) {
+ if(pLayoutItem->m_pFirstChild == NULL) {
+ pContentAreaLayoutItem = pLayoutItem;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_LayoutPageMgr::GetNextContentArea(CXFA_Node* pContentArea)
+{
+ CXFA_Node* pCurContentNode = GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
+ if(pContentArea == NULL) {
+ pContentArea = pCurContentNode->GetNextSameClassSibling(XFA_ELEMENT_ContentArea);
+ if(pContentArea == NULL) {
+ return FALSE;
+ }
+ } else {
+ if(pContentArea->GetNodeItem(XFA_NODEITEM_Parent) != m_pCurPageArea) {
+ return FALSE;
+ }
+ CXFA_ContainerLayoutItemImpl* pContentAreaLayout = NULL;
+ if(!XFA_LayoutPageMgr_CheckContentAreaNotUsed(GetCurrentContainerRecord()->pCurPageArea, pContentArea, pContentAreaLayout)) {
+ return FALSE;
+ }
+ if(pContentAreaLayout) {
+ if(pContentAreaLayout->m_pFormNode != pCurContentNode) {
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+ pNewRecord->pCurContentArea = pContentAreaLayout;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+ AddContentAreaLayoutItem(pNewRecord, pContentArea);
+ return TRUE;
+}
+void CXFA_LayoutPageMgr::InitPageSetMap()
+{
+ if(!IsPageSetRootOrderedOccurrence()) {
+ return;
+ }
+ CXFA_NodeIterator sIterator(m_pTemplatePageSetRoot);
+ for (CXFA_Node* pPageSetNode = sIterator.GetCurrent(); pPageSetNode; pPageSetNode = sIterator.MoveToNext()) {
+ if(pPageSetNode->GetClassID() == XFA_ELEMENT_PageSet) {
+ XFA_ATTRIBUTEENUM eRelation = pPageSetNode->GetEnum(XFA_ATTRIBUTE_Relation);
+ if(eRelation == XFA_ATTRIBUTEENUM_OrderedOccurrence) {
+ m_pPageSetMap.SetAt(pPageSetNode, 0);
+ }
+ }
+ }
+}
+FX_INT32 CXFA_LayoutPageMgr::CreateMinPageRecord(CXFA_Node* pPageArea, FX_BOOL bTargetPageArea, FX_BOOL bCreateLast)
+{
+ if(pPageArea == NULL) {
+ return 0;
+ }
+ CXFA_Node* pOccurNode = pPageArea->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ FX_INT32 iMin = 0;
+ if((pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE)) || bTargetPageArea) {
+ CXFA_Node* pContentArea = pPageArea->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+ if (iMin < 1 && bTargetPageArea && !pContentArea) {
+ iMin = 1;
+ }
+ FX_INT32 i = 0;
+ if(bCreateLast) {
+ i = m_nCurPageCount;
+ }
+ for(; i < iMin; i++) {
+ CXFA_ContainerRecord* pNewRecord = CreateContainerRecord();
+ AddPageAreaLayoutItem(pNewRecord, pPageArea);
+ AddContentAreaLayoutItem(pNewRecord, pContentArea);
+ }
+ }
+ return iMin;
+}
+void CXFA_LayoutPageMgr::CreateMinPageSetRecord(CXFA_Node* pPageSet, FX_BOOL bCreateAll)
+{
+ if(pPageSet == NULL) {
+ return;
+ }
+ FX_INT32 iCurSetCount = 0;
+ if(!m_pPageSetMap.Lookup(pPageSet, iCurSetCount)) {
+ return;
+ }
+ if(bCreateAll) {
+ iCurSetCount = 0;
+ }
+ CXFA_Node* pOccurNode = pPageSet->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ FX_INT32 iMin = 0;
+ if(pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE)) {
+ if(iCurSetCount < iMin) {
+ for(FX_INT32 i = 0; i < iMin - iCurSetCount; i++) {
+ for(CXFA_Node *pCurrentPageNode = pPageSet->GetNodeItem(XFA_NODEITEM_FirstChild); pCurrentPageNode; pCurrentPageNode = pCurrentPageNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pCurrentPageNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ CreateMinPageRecord(pCurrentPageNode, FALSE);
+ } else if(pCurrentPageNode->GetClassID() == XFA_ELEMENT_PageSet) {
+ CreateMinPageSetRecord(pCurrentPageNode, TRUE);
+ }
+ }
+ }
+ m_pPageSetMap.SetAt(pPageSet, iMin);
+ }
+ }
+}
+void CXFA_LayoutPageMgr::CreateNextMinRecord(CXFA_Node* pRecordNode)
+{
+ if(pRecordNode == NULL) {
+ return;
+ }
+ for(CXFA_Node *pCurrentNode = pRecordNode->GetNodeItem(XFA_NODEITEM_NextSibling); pCurrentNode; pCurrentNode = pCurrentNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pCurrentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ CreateMinPageRecord(pCurrentNode, FALSE);
+ } else if(pCurrentNode->GetClassID() == XFA_ELEMENT_PageSet) {
+ CreateMinPageSetRecord(pCurrentNode, TRUE);
+ }
+ }
+}
+void CXFA_LayoutPageMgr::ProcessLastPageSet()
+{
+ CreateMinPageRecord(m_pCurPageArea, FALSE, TRUE);
+ CreateNextMinRecord(m_pCurPageArea);
+ CXFA_Node* pPageSet = m_pCurPageArea->GetNodeItem(XFA_NODEITEM_Parent);
+ while(TRUE) {
+ CreateMinPageSetRecord(pPageSet);
+ if(pPageSet == m_pTemplatePageSetRoot) {
+ break;
+ }
+ CreateNextMinRecord(pPageSet);
+ pPageSet = pPageSet->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+}
+FX_BOOL CXFA_LayoutPageMgr::GetNextAvailContentHeight(FX_FLOAT fChildHeight)
+{
+ CXFA_Node* pCurContentNode = GetCurrentContainerRecord()->pCurContentArea->m_pFormNode;
+ if(pCurContentNode == NULL) {
+ return FALSE;
+ }
+ pCurContentNode = pCurContentNode->GetNextSameClassSibling(XFA_ELEMENT_ContentArea);
+ if(pCurContentNode) {
+ FX_FLOAT fNextContentHeight = pCurContentNode->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+ return fNextContentHeight > fChildHeight ? TRUE : FALSE;
+ }
+ CXFA_Node* pPageNode = GetCurrentContainerRecord()->pCurPageArea->m_pFormNode;
+ CXFA_Node* pOccurNode = pPageNode->GetFirstChildByClass(XFA_ELEMENT_Occur);
+ FX_INT32 iMax = 0;
+ if(pOccurNode && pOccurNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE)) {
+ if(m_nCurPageCount == iMax) {
+ CXFA_Node* pSrcPage = m_pCurPageArea;
+ FX_INT32 nSrcPageCount = m_nCurPageCount;
+ FX_POSITION psSrcRecord = m_rgProposedContainerRecord.GetTailPosition();
+ CXFA_Node* pNextPage = GetNextAvailPageArea(NULL, NULL, FALSE, TRUE);
+ m_pCurPageArea = pSrcPage;
+ m_nCurPageCount = nSrcPageCount;
+ CXFA_ContainerRecord* pPrevRecord = (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext(psSrcRecord);
+ while (psSrcRecord) {
+ FX_POSITION psSaveRecord = psSrcRecord;
+ CXFA_ContainerRecord* pInsertRecord = (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext(psSrcRecord);
+ RemoveLayoutRecord(pInsertRecord, pPrevRecord);
+ delete pInsertRecord;
+ m_rgProposedContainerRecord.RemoveAt(psSaveRecord);
+ }
+ if(pNextPage) {
+ CXFA_Node* pContentArea = pNextPage->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+ if(pContentArea) {
+ FX_FLOAT fNextContentHeight = pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+ if(fNextContentHeight > fChildHeight) {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+ }
+ }
+ CXFA_Node* pContentArea = pPageNode->GetFirstChildByClass(XFA_ELEMENT_ContentArea);
+ FX_FLOAT fNextContentHeight = pContentArea->GetMeasure(XFA_ATTRIBUTE_H).ToUnit(XFA_UNIT_Pt);
+ if (fNextContentHeight < XFA_LAYOUT_FLOAT_PERCISION) {
+ return TRUE;
+ }
+ if(fNextContentHeight > fChildHeight) {
+ return TRUE;
+ }
+ return FALSE;
+}
+void CXFA_LayoutPageMgr::ClearData()
+{
+ ClearRecordList();
+}
+void CXFA_LayoutPageMgr::ClearRecordList()
+{
+ if (!m_pTemplatePageSetRoot) {
+ return;
+ }
+ if(m_rgProposedContainerRecord.GetCount() > 0) {
+ FX_POSITION sPos;
+ sPos = m_rgProposedContainerRecord.GetHeadPosition();
+ while(sPos) {
+ CXFA_ContainerRecord* pRecord = (CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetNext(sPos);
+ delete pRecord;
+ }
+ m_rgProposedContainerRecord.RemoveAll();
+ }
+ m_pCurrentContainerRecord = NULL;
+ m_pCurPageArea = NULL;
+ m_nCurPageCount = 0;
+ m_bCreateOverFlowPage = FALSE;
+ m_pPageSetMap.RemoveAll();
+}
+CXFA_LayoutItemImpl* CXFA_LayoutPageMgr::FindOrCreateLayoutItem(CXFA_Node* pFormNode)
+{
+#if defined(_XFA_LAYOUTITEM_MAPCACHE_)
+ if (m_NodeToContent.GetCount() > 0) {
+ CXFA_ContentLayoutItemImpl* pLayoutItem = NULL;
+ if (m_NodeToContent.Lookup(pFormNode, (void*&)pLayoutItem)) {
+ if (pLayoutItem->m_pNext) {
+ m_NodeToContent.SetAt(pFormNode, pLayoutItem->m_pNext);
+ pLayoutItem->m_pNext->m_pPrev = NULL;
+ pLayoutItem->m_pNext = NULL;
+ } else {
+ m_NodeToContent.RemoveKey(pFormNode);
+ }
+ pLayoutItem->m_pFormNode = pFormNode;
+ return pLayoutItem;
+ }
+ }
+#endif
+ return (CXFA_LayoutItemImpl*)pFormNode->GetDocument()->GetParser()->GetNotify()->OnCreateLayoutItem(pFormNode);
+}
+#if defined(_XFA_LAYOUTITEM_MAPCACHE_)
+void CXFA_LayoutPageMgr::SaveLayoutItem(CXFA_LayoutItemImpl* pParentLayoutItem)
+{
+ CXFA_LayoutItemImpl *pNextLayoutItem, *pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
+ while (pCurLayoutItem) {
+ pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
+ if (pCurLayoutItem->m_pFirstChild) {
+ SaveLayoutItem(pCurLayoutItem);
+ }
+ if (pCurLayoutItem->IsContentLayoutItem()) {
+ if (m_NodeToContent.GetValueAt(pCurLayoutItem->m_pFormNode) == NULL) {
+ pCurLayoutItem->m_pFormNode->SetUserData(XFA_LAYOUTITEMKEY, NULL);
+ m_NodeToContent.SetAt(pCurLayoutItem->m_pFormNode, pCurLayoutItem);
+ }
+ } else if (pCurLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) {
+ delete pCurLayoutItem;
+ pCurLayoutItem = NULL;
+ }
+ if (pCurLayoutItem) {
+ pCurLayoutItem->m_pParent = NULL;
+ pCurLayoutItem->m_pNextSibling = NULL;
+ pCurLayoutItem->m_pFirstChild = NULL;
+ }
+ pCurLayoutItem = pNextLayoutItem;
+ }
+}
+#elif defined(_XFA_LAYOUTITEM_ProcessCACHE_)
+static void XFA_SyncRemoveLayoutItem(CXFA_LayoutItemImpl* pParentLayoutItem, IXFA_Notify* pNotify, IXFA_DocLayout* pDocLayout)
+{
+ CXFA_LayoutItemImpl *pNextLayoutItem, *pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
+ while (pCurLayoutItem) {
+ pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
+ if (pCurLayoutItem->m_pFirstChild) {
+ XFA_SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
+ }
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pCurLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ delete pCurLayoutItem;
+ pCurLayoutItem = pNextLayoutItem;
+ }
+}
+void CXFA_LayoutPageMgr::SaveLayoutItem(CXFA_LayoutItemImpl* pParentLayoutItem)
+{
+ CXFA_LayoutItemImpl *pNextLayoutItem, *pCurLayoutItem = pParentLayoutItem->m_pFirstChild;
+ while (pCurLayoutItem) {
+ pNextLayoutItem = pCurLayoutItem->m_pNextSibling;
+ if (pCurLayoutItem->IsContentLayoutItem()) {
+ FX_DWORD dwFlag = pCurLayoutItem->m_pFormNode->GetFlag();
+ if (dwFlag & (XFA_NODEFLAG_HasRemoved)) {
+ IXFA_Notify* pNotify = m_pTemplatePageSetRoot->GetDocument()->GetParser()->GetNotify();
+ IXFA_DocLayout* pDocLayout = m_pTemplatePageSetRoot->GetDocument()->GetDocLayout();
+ if (pCurLayoutItem->m_pFirstChild) {
+ XFA_SyncRemoveLayoutItem(pCurLayoutItem, pNotify, pDocLayout);
+ }
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pCurLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ delete pCurLayoutItem;
+ pCurLayoutItem = pNextLayoutItem;
+ continue;
+ }
+ if (dwFlag & XFA_NODEFLAG_LayoutGeneratedNode) {
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pCurLayoutItem->m_pFormNode);
+ for(CXFA_Node *pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode, TRUE, FALSE);
+ }
+ }
+ }
+ if (pCurLayoutItem->m_pFirstChild) {
+ SaveLayoutItem(pCurLayoutItem);
+ }
+ pCurLayoutItem->m_pParent = NULL;
+ pCurLayoutItem->m_pNextSibling = NULL;
+ pCurLayoutItem->m_pFirstChild = NULL;
+ if (!pCurLayoutItem->IsContentLayoutItem() && pCurLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) {
+ delete pCurLayoutItem;
+ }
+ pCurLayoutItem = pNextLayoutItem;
+ }
+}
+#endif
+CXFA_Node* CXFA_LayoutPageMgr::QueryOverflow(CXFA_Node* pFormNode, CXFA_LayoutContext* pLayoutContext)
+{
+ for(CXFA_Node* pCurNode = pFormNode->GetNodeItem(XFA_NODEITEM_FirstChild); pCurNode; pCurNode = pCurNode->GetNodeItem((XFA_NODEITEM_NextSibling))) {
+ if(pCurNode->GetClassID() == XFA_ELEMENT_Break) {
+ CFX_WideStringC wsOverflowLeader;
+ CFX_WideStringC wsOverflowTarget;
+ CFX_WideStringC wsOverflowTrailer;
+ pCurNode->TryCData(XFA_ATTRIBUTE_OverflowLeader, wsOverflowLeader);
+ pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTrailer, wsOverflowTrailer);
+ pCurNode->TryCData(XFA_ATTRIBUTE_OverflowTarget, wsOverflowTarget);
+ if (!wsOverflowLeader.IsEmpty() || !wsOverflowTrailer.IsEmpty() || !wsOverflowTarget.IsEmpty()) {
+ return pCurNode;
+ }
+ return NULL;
+ } else if(pCurNode->GetClassID() == XFA_ELEMENT_Overflow) {
+ return pCurNode;
+ }
+ }
+ return NULL;
+}
+void CXFA_LayoutPageMgr::MergePageSetContents()
+{
+ CXFA_Document *pDocument = m_pTemplatePageSetRoot->GetDocument();
+ IXFA_Notify* pNotify = pDocument->GetParser()->GetNotify();
+ IXFA_DocLayout* pDocLayout = pDocument->GetDocLayout();
+ CXFA_ContainerLayoutItemImpl* pRootLayout = this->GetRootLayoutItem();
+ {
+ for(FX_INT32 iIndex = 0; iIndex < pDocument->m_pPendingPageSet.GetSize(); iIndex ++) {
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pDocument->m_pPendingPageSet.GetAt(iIndex));
+ for(CXFA_Node *pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ if(pNode->IsContainerNode()) {
+ CXFA_Node* pBindNode = pNode->GetBindData();
+ if (pBindNode) {
+ pBindNode->RemoveBindItem(pNode);
+ pNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+ }
+ }
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode);
+ }
+ }
+ }
+ FX_INT32 iIndex = 0;
+ CXFA_Node* pPendingPageSet = NULL;
+ for(; pRootLayout; pRootLayout = (CXFA_ContainerLayoutItemImpl* )pRootLayout->m_pNextSibling) {
+ pPendingPageSet = NULL;
+ CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItemImpl, CXFA_TraverseStrategy_ContentAreaContainerLayoutItem> iterator(pRootLayout);
+ CXFA_ContainerLayoutItemImpl* pRootPageSetContainerItem = iterator.GetCurrent();
+ ASSERT(pRootPageSetContainerItem->m_pFormNode->GetClassID() == XFA_ELEMENT_PageSet);
+ if(iIndex < pDocument->m_pPendingPageSet.GetSize()) {
+ pPendingPageSet = pDocument->m_pPendingPageSet.GetAt(iIndex);
+ iIndex ++;
+ }
+ if(!pPendingPageSet) {
+ if(pRootPageSetContainerItem->m_pFormNode->GetPacketID() == XFA_XDPPACKET_Template) {
+ pPendingPageSet = pRootPageSetContainerItem->m_pFormNode->CloneTemplateToForm(FALSE);
+ } else {
+ pPendingPageSet = pRootPageSetContainerItem->m_pFormNode;
+ }
+ }
+ if (pRootPageSetContainerItem->m_pFormNode->GetUserData(XFA_LAYOUTITEMKEY) == pRootPageSetContainerItem) {
+ pRootPageSetContainerItem->m_pFormNode->SetUserData(XFA_LAYOUTITEMKEY, NULL);
+ }
+ pRootPageSetContainerItem->m_pFormNode = pPendingPageSet;
+ pPendingPageSet->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ for(CXFA_ContainerLayoutItemImpl* pContainerItem = iterator.MoveToNext(); pContainerItem; pContainerItem = iterator.MoveToNext()) {
+ CXFA_Node* pNode = pContainerItem->m_pFormNode;
+ if(pNode->GetPacketID() != XFA_XDPPACKET_Template) {
+ continue;
+ }
+ switch(pNode->GetClassID()) {
+ case XFA_ELEMENT_PageSet: {
+ CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
+ pContainerItem->m_pFormNode = XFA_NodeMerge_CloneOrMergeContainer(pDocument, pParentNode, pContainerItem->m_pFormNode, TRUE);
+ }
+ break;
+ case XFA_ELEMENT_PageArea: {
+ CXFA_ContainerLayoutItemImpl* pFormLayout = pContainerItem;
+ CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
+ FX_BOOL bIsExistForm = TRUE;
+ for(FX_INT32 iLevel = 0; iLevel < 3; iLevel ++) {
+ pFormLayout = (CXFA_ContainerLayoutItemImpl*)pFormLayout->m_pFirstChild;
+ if(iLevel == 2) {
+ while(pFormLayout && !XFA_ItemLayoutProcessor_IsTakingSpace(pFormLayout->m_pFormNode)) {
+ pFormLayout = (CXFA_ContainerLayoutItemImpl*)pFormLayout->m_pNextSibling;
+ }
+ }
+ if(pFormLayout == NULL) {
+ bIsExistForm = FALSE;
+ break;
+ }
+ }
+ if(bIsExistForm) {
+ CXFA_Node* pNewSubform = pFormLayout->m_pFormNode;
+ if( pContainerItem->m_pOldSubform != NULL && pContainerItem->m_pOldSubform != pNewSubform) {
+ CXFA_Node* pExistingNode = XFA_DataMerge_FindFormDOMInstance(pDocument, pContainerItem->m_pFormNode->GetClassID(), pContainerItem->m_pFormNode->GetNameHash(), pParentNode);
+ CXFA_ContainerIterator sIterator(pExistingNode);
+ for(CXFA_Node *pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ if(pNode->GetClassID() != XFA_ELEMENT_ContentArea) {
+ CXFA_LayoutItemImpl* pLayoutItem = (CXFA_LayoutItemImpl*)pNode->GetUserData(XFA_LAYOUTITEMKEY);
+ if(pLayoutItem) {
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ delete pLayoutItem;
+ }
+ }
+ }
+ if(pExistingNode) {
+ pParentNode->RemoveChild(pExistingNode);
+ }
+ }
+ pContainerItem->m_pOldSubform = pNewSubform;
+ }
+ pContainerItem->m_pFormNode = pDocument->DataMerge_CopyContainer(pContainerItem->m_pFormNode, pParentNode, (CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Record), TRUE);
+ }
+ break;
+ case XFA_ELEMENT_ContentArea: {
+ CXFA_Node* pParentNode = pContainerItem->m_pParent->m_pFormNode;
+ for(CXFA_Node* pChildNode = pParentNode->GetNodeItem(XFA_NODEITEM_FirstChild); pChildNode; pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pChildNode->GetTemplateNode() != pContainerItem->m_pFormNode) {
+ continue;
+ }
+ pContainerItem->m_pFormNode = pChildNode;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if(!pPendingPageSet->GetNodeItem(XFA_NODEITEM_Parent)) {
+ CXFA_Node* pFormToplevelSubform = ((CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Form))->GetFirstChildByClass(XFA_ELEMENT_Subform);
+ pFormToplevelSubform->InsertChild(pPendingPageSet);
+ }
+ pDocument->DataMerge_UpdateBindingRelations(pPendingPageSet);
+ pPendingPageSet->SetFlag(XFA_NODEFLAG_Initialized);
+ }
+ pPendingPageSet = GetRootLayoutItem()->m_pFormNode;
+ while(pPendingPageSet) {
+ CXFA_Node* pNextPendingPageSet = pPendingPageSet->GetNextSameClassSibling(XFA_ELEMENT_PageSet);
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFANode> sIterator(pPendingPageSet);
+ CXFA_Node *pNode = sIterator.GetCurrent();
+ while(pNode) {
+ if(pNode->HasFlag(XFA_NODEFLAG_UnusedNode)) {
+ if(pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ XFA_ELEMENT eCurId = pNode->GetClassID();
+ if (eCurId == XFA_ELEMENT_PageArea || eCurId == XFA_ELEMENT_PageSet) {
+ CXFA_ContainerIterator iteChild(pNode);
+ CXFA_Node* pChildNode = iteChild.MoveToNext();
+ for (; pChildNode; pChildNode = iteChild.MoveToNext()) {
+ CXFA_LayoutItemImpl* pLayoutItem = (CXFA_LayoutItemImpl*)pChildNode->GetUserData(XFA_LAYOUTITEMKEY);
+ if(pLayoutItem) {
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ delete pLayoutItem;
+ }
+ }
+ } else if (eCurId != XFA_ELEMENT_ContentArea) {
+ CXFA_LayoutItemImpl* pLayoutItem = (CXFA_LayoutItemImpl*)pNode->GetUserData(XFA_LAYOUTITEMKEY);
+ if(pLayoutItem) {
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ delete pLayoutItem;
+ }
+ }
+ CXFA_Node* pNext = sIterator.SkipChildrenAndMoveToNext();
+ pNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pNode);
+ pNode = pNext;
+ } else {
+ pNode->SetFlag(XFA_NODEFLAG_UnusedNode, FALSE);
+ pNode->SetFlag(XFA_NODEFLAG_Initialized);
+ pNode = sIterator.MoveToNext();
+ }
+ } else {
+ pNode->SetFlag(XFA_NODEFLAG_Initialized);
+ pNode = sIterator.MoveToNext();
+ }
+ }
+ pPendingPageSet = pNextPendingPageSet;
+ }
+}
+void CXFA_LayoutPageMgr::LayoutPageSetContents()
+{
+ CXFA_ContainerLayoutItemImpl* pRootLayoutItem = this->GetRootLayoutItem();
+ for(; pRootLayoutItem; pRootLayoutItem = (CXFA_ContainerLayoutItemImpl*)pRootLayoutItem->m_pNextSibling) {
+ CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItemImpl, CXFA_TraverseStrategy_ContentAreaContainerLayoutItem> iterator(pRootLayoutItem);
+ for(CXFA_ContainerLayoutItemImpl* pContainerItem = iterator.GetCurrent(); pContainerItem; pContainerItem = iterator.MoveToNext()) {
+ CXFA_Node* pNode = pContainerItem->m_pFormNode;
+ switch(pNode->GetClassID()) {
+ case XFA_ELEMENT_PageArea:
+ m_pLayoutProcessor->GetRootRootItemLayoutProcessor()->DoLayoutPageArea(pContainerItem);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+void XFA_SyncContainer(IXFA_Notify* pNotify, IXFA_DocLayout* pDocLayout, CXFA_LayoutItemImpl* pContainerItem, FX_DWORD dwRelevant, FX_BOOL bVisible, FX_INT32 nPageIndex)
+{
+ FX_BOOL bVisibleItem = FALSE;
+ FX_DWORD dwStatus = 0;
+ FX_DWORD dwRelevantContainer = 0;
+ if (bVisible) {
+ XFA_ATTRIBUTEENUM eAttributeValue = pContainerItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence);
+ if(eAttributeValue == XFA_ATTRIBUTEENUM_Visible || eAttributeValue == XFA_ATTRIBUTEENUM_Unknown) {
+ bVisibleItem = TRUE;
+ }
+ dwRelevantContainer = XFA_GetRelevant(pContainerItem->m_pFormNode, dwRelevant);
+ dwStatus = (bVisibleItem ? XFA_LAYOUTSTATUS_Visible : 0) | dwRelevantContainer;
+ }
+ pNotify->OnLayoutEvent(pDocLayout, (CXFA_LayoutItem*)pContainerItem, XFA_LAYOUTEVENT_ItemAdded, (FX_LPVOID)(FX_UINTPTR)nPageIndex, (FX_LPVOID)(FX_UINTPTR)dwStatus);
+ CXFA_LayoutItemImpl *pChild = pContainerItem->m_pFirstChild;
+ while (pChild) {
+ if (!pChild->IsContentLayoutItem()) {
+ pChild = pChild->m_pNextSibling;
+ continue;
+ }
+ XFA_SyncContainer(pNotify, pDocLayout, pChild, dwRelevantContainer, bVisibleItem, nPageIndex);
+ pChild = pChild->m_pNextSibling;
+ }
+}
+void CXFA_LayoutPageMgr::SyncLayoutData()
+{
+ MergePageSetContents();
+ LayoutPageSetContents();
+ IXFA_Notify* pNotify = m_pTemplatePageSetRoot->GetDocument()->GetParser()->GetNotify();
+ FX_INT32 nPageIdx = -1;
+ CXFA_ContainerLayoutItemImpl* pRootLayoutItem = this->GetRootLayoutItem();
+ for(; pRootLayoutItem; pRootLayoutItem = (CXFA_ContainerLayoutItemImpl*)pRootLayoutItem->m_pNextSibling) {
+ CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItemImpl, CXFA_TraverseStrategy_ContentAreaContainerLayoutItem> iteratorParent(pRootLayoutItem);
+ for(CXFA_ContainerLayoutItemImpl* pContainerItem = iteratorParent.GetCurrent(); pContainerItem; pContainerItem = iteratorParent.MoveToNext()) {
+ switch(pContainerItem->m_pFormNode->GetClassID()) {
+ case XFA_ELEMENT_PageArea: {
+ nPageIdx++;
+ FX_DWORD dwRelevant = XFA_LAYOUTSTATUS_Viewable | XFA_LAYOUTSTATUS_Printable;
+ CXFA_NodeIteratorTemplate<CXFA_LayoutItem, CXFA_TraverseStrategy_LayoutItem> iterator((CXFA_LayoutItem*)pContainerItem);
+ for(CXFA_LayoutItem* pChildLayoutItem = iterator.GetCurrent(); pChildLayoutItem;) {
+ if (!((CXFA_LayoutItemImpl*)pChildLayoutItem)->IsContentLayoutItem()) {
+ pChildLayoutItem = iterator.MoveToNext();
+ continue;
+ }
+ CXFA_ContentLayoutItemImpl* pContentItem = (CXFA_ContentLayoutItemImpl*)pChildLayoutItem;
+ FX_BOOL bVisible = (pContentItem->m_pFormNode->GetEnum(XFA_ATTRIBUTE_Presence) == XFA_ATTRIBUTEENUM_Visible);
+ FX_DWORD dwRelevantChild = XFA_GetRelevant(pContentItem->m_pFormNode, dwRelevant);
+ XFA_SyncContainer(pNotify, m_pLayoutProcessor, pContentItem, dwRelevantChild, bVisible, nPageIdx);
+ pChildLayoutItem = iterator.SkipChildrenAndMoveToNext();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ FX_INT32 nPage = m_PageArray.GetSize();
+ for (FX_INT32 i = nPage - 1; i >= m_nAvailPages; i--) {
+ CXFA_ContainerLayoutItemImpl* pPage = m_PageArray[i];
+ m_PageArray.RemoveAt(i);
+ pNotify->OnPageEvent((IXFA_LayoutPage*)pPage, XFA_PAGEEVENT_PageRemoved);
+ delete pPage;
+ }
+ ClearRecordList();
+}
+void XFA_ReleaseLayoutItem_NoPageArea(CXFA_LayoutItemImpl *pLayoutItem)
+{
+ CXFA_LayoutItemImpl *pNext, *pNode = pLayoutItem->m_pFirstChild;
+ while (pNode) {
+ pNext = pNode->m_pNextSibling;
+ pNode->m_pParent = NULL;
+ XFA_ReleaseLayoutItem_NoPageArea(pNode);
+ pNode = pNext;
+ }
+ if (pLayoutItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) {
+ delete pLayoutItem;
+ }
+}
+void CXFA_LayoutPageMgr::PrepareLayout()
+{
+ m_pPageSetCurRoot = NULL;
+ m_ePageSetMode = XFA_ATTRIBUTEENUM_OrderedOccurrence;
+ m_nAvailPages = 0;
+ ClearRecordList();
+ if (!m_pPageSetLayoutItemRoot) {
+ return;
+ }
+ CXFA_ContainerLayoutItemImpl* pRootLayoutItem = m_pPageSetLayoutItemRoot;
+ if(pRootLayoutItem && pRootLayoutItem->m_pFormNode->GetPacketID() == XFA_XDPPACKET_Form) {
+ CXFA_Node* pPageSetFormNode = pRootLayoutItem->m_pFormNode;
+ pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.RemoveAll();
+ if (pPageSetFormNode->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+ XFA_ReleaseLayoutItem(pRootLayoutItem);
+ m_pPageSetLayoutItemRoot = NULL;
+ pRootLayoutItem = NULL;
+ pPageSetFormNode = NULL;
+ m_PageArray.RemoveAll();
+ }
+ while(pPageSetFormNode) {
+ CXFA_Node* pNextPageSet = pPageSetFormNode->GetNextSameClassSibling(XFA_ELEMENT_PageSet);
+ pPageSetFormNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pPageSetFormNode, FALSE);
+ pRootLayoutItem->m_pFormNode->GetDocument()->m_pPendingPageSet.Add(pPageSetFormNode);
+ pPageSetFormNode = pNextPageSet;
+ }
+ }
+#if defined(_XFA_LAYOUTITEM_MAPCACHE_) || defined(_XFA_LAYOUTITEM_ProcessCACHE_)
+ pRootLayoutItem = m_pPageSetLayoutItemRoot;
+ CXFA_ContainerLayoutItemImpl* pNextLayout = NULL;
+ for(; pRootLayoutItem; pRootLayoutItem = pNextLayout) {
+ pNextLayout = (CXFA_ContainerLayoutItemImpl*)pRootLayoutItem->m_pNextSibling;
+ SaveLayoutItem(pRootLayoutItem);
+ delete pRootLayoutItem;
+ }
+ m_pPageSetLayoutItemRoot = NULL;
+#else
+ IXFA_Notify* pNotify = m_pLayoutProcessor->GetDocument()->GetParser()->GetNotify();
+ pRootLayoutItem = m_pPageSetLayoutItemRoot;
+ for(; pRootLayoutItem; pRootLayoutItem = (CXFA_ContainerLayoutItemImpl*)pRootLayoutItem->m_pNextSibling) {
+ CXFA_NodeIteratorTemplate<CXFA_ContainerLayoutItemImpl, CXFA_TraverseStrategy_PageAreaContainerLayoutItem> iterator(pRootLayoutItem);
+ for(CXFA_ContainerLayoutItemImpl* pContainerItem = iterator.GetCurrent(); pContainerItem; pContainerItem = iterator.MoveToNext()) {
+ if(pContainerItem->m_pFormNode->GetClassID() != XFA_ELEMENT_PageArea) {
+ continue;
+ }
+ CXFA_NodeIteratorTemplate<CXFA_LayoutItem, CXFA_TraverseStrategy_LayoutItem> iterator((CXFA_LayoutItem*)pContainerItem);
+ for(CXFA_LayoutItemImpl* pLayoutItem = (CXFA_LayoutItemImpl*)iterator.GetCurrent(); pLayoutItem; pLayoutItem = (CXFA_LayoutItemImpl*)iterator.MoveToNext()) {
+ if (!pLayoutItem->IsContentLayoutItem()) {
+ continue;
+ }
+ pNotify->OnLayoutEvent(m_pLayoutProcessor, (CXFA_LayoutItem*)pLayoutItem, XFA_LAYOUTEVENT_ItemRemoving);
+ }
+ pNotify->OnPageEvent((IXFA_LayoutPage*)pContainerItem, XFA_PAGEEVENT_PageRemoved);
+ }
+ }
+ pRootLayoutItem = m_pPageSetLayoutItemRoot;
+ CXFA_ContainerLayoutItemImpl* pNextLayout = NULL;
+ for(; pRootLayoutItem; pRootLayoutItem = pNextLayout) {
+ pNextLayout = (CXFA_ContainerLayoutItemImpl*)pRootLayoutItem->m_pNextSibling;
+ XFA_ReleaseLayoutItem_NoPageArea(pRootLayoutItem);
+ }
+ m_pPageSetLayoutItemRoot = NULL;
+#endif
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.h b/xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.h
new file mode 100644
index 0000000000..dcaf01c739
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_layout_pagemgr_new.h
@@ -0,0 +1,102 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_LAYOUT_PAGEMGR_H_
+#define _XFA_LAYOUT_PAGEMGR_H_
+class CXFA_ContainerRecord : public CFX_Object
+{
+public:
+ CXFA_ContainerRecord(CXFA_ContainerLayoutItemImpl* pPageSet = NULL, CXFA_ContainerLayoutItemImpl* pPageArea = NULL, CXFA_ContainerLayoutItemImpl* pContentArea = NULL)
+ : pCurPageSet(pPageSet), pCurPageArea(pPageArea), pCurContentArea(pContentArea)
+ {
+ }
+ CXFA_ContainerLayoutItemImpl* pCurPageSet;
+ CXFA_ContainerLayoutItemImpl* pCurPageArea;
+ CXFA_ContainerLayoutItemImpl* pCurContentArea;
+};
+class CXFA_LayoutPageMgr : public CFX_Object
+{
+public:
+ CXFA_LayoutPageMgr(CXFA_LayoutProcessor* pLayoutProcessor);
+ ~CXFA_LayoutPageMgr();
+ FX_BOOL InitLayoutPage(CXFA_Node* pFormNode);
+ FX_BOOL PrepareFirstPage(CXFA_Node* pRootSubform);
+ FX_FLOAT GetAvailHeight();
+ FX_BOOL GetNextAvailContentHeight(FX_FLOAT fChildHeight);
+ void SubmitContentItem(CXFA_ContentLayoutItemImpl* pContentLayoutItem, XFA_ItemLayoutProcessorResult eStatus);
+ void FinishPaginatedPageSets();
+ void SyncLayoutData();
+ FX_INT32 GetPageCount() const;
+ IXFA_LayoutPage* GetPage(FX_INT32 index) const;
+ FX_INT32 GetPageIndex(IXFA_LayoutPage* pPage) const;
+ inline CXFA_ContainerLayoutItemImpl* GetRootLayoutItem() const
+ {
+ return m_pPageSetLayoutItemRoot;
+ }
+ FX_BOOL ProcessBreakBeforeOrAfter(CXFA_Node* pBreakNode, FX_BOOL bBefore, CXFA_Node* &pBreakLeaderNode, CXFA_Node* &pBreakTrailerNode, FX_BOOL& bCreatePage);
+ FX_BOOL ProcessOverflow(CXFA_Node* pFormNode, CXFA_Node* &pLeaderNode, CXFA_Node* &pTrailerNode, FX_BOOL bDataMerge = FALSE, FX_BOOL bCreatePage = TRUE);
+ CXFA_Node* QueryOverflow(CXFA_Node* pFormNode, CXFA_LayoutContext* pLayoutContext = NULL);
+ FX_BOOL ProcessBookendLeaderOrTrailer(CXFA_Node* pBookendNode, FX_BOOL bLeader, CXFA_Node* &pBookendAppendNode);
+ CXFA_LayoutItemImpl* FindOrCreateLayoutItem(CXFA_Node* pFormNode);
+protected:
+ FX_BOOL AppendNewPage(FX_BOOL bFirstTemPage = FALSE);
+ void ReorderPendingLayoutRecordToTail(CXFA_ContainerRecord* pNewRecord, CXFA_ContainerRecord* pPrevRecord);
+ void RemoveLayoutRecord(CXFA_ContainerRecord* pNewRecord, CXFA_ContainerRecord* pPrevRecord);
+ inline CXFA_ContainerRecord* GetCurrentContainerRecord()
+ {
+ CXFA_ContainerRecord* result = ((CXFA_ContainerRecord*)m_rgProposedContainerRecord.GetAt(m_pCurrentContainerRecord));
+ ASSERT(result);
+ return result;
+ }
+ CXFA_ContainerRecord* CreateContainerRecord(CXFA_Node* pPageNode = NULL, FX_BOOL bCreateNew = FALSE);
+ void AddPageAreaLayoutItem(CXFA_ContainerRecord* pNewRecord, CXFA_Node* pNewPageArea);
+ void AddContentAreaLayoutItem(CXFA_ContainerRecord* pNewRecord, CXFA_Node* pContentArea);
+ FX_BOOL RunBreak(XFA_ELEMENT eBreakType, XFA_ATTRIBUTEENUM eTargetType, CXFA_Node* pTarget, FX_BOOL bStartNew);
+ CXFA_Node* BreakOverflow(CXFA_Node* pOverflowNode, CXFA_Node*& pLeaderTemplate, CXFA_Node*& pTrailerTemplate, FX_BOOL bCreatePage = TRUE);
+ FX_BOOL ResolveBookendLeaderOrTrailer(CXFA_Node* pBookendNode, FX_BOOL bLeader, CXFA_Node* &pBookendAppendTemplate);
+ FX_BOOL ExecuteBreakBeforeOrAfter(CXFA_Node* pCurNode, FX_BOOL bBefore, CXFA_Node* &pBreakLeaderTemplate, CXFA_Node* &pBreakTrailerTemplate);
+
+ FX_INT32 CreateMinPageRecord(CXFA_Node* pPageArea, FX_BOOL bTargetPageArea, FX_BOOL bCreateLast = FALSE);
+ void CreateMinPageSetRecord(CXFA_Node* pPageSet, FX_BOOL bCreateAll = FALSE);
+ void CreateNextMinRecord(CXFA_Node* pRecordNode);
+ FX_BOOL FindPageAreaFromPageSet(CXFA_Node* pPageSet, CXFA_Node* pStartChild, CXFA_Node* pTargetPageArea = NULL, CXFA_Node* pTargetContentArea = NULL, FX_BOOL bNewPage = FALSE, FX_BOOL bQuery = FALSE);
+ FX_BOOL FindPageAreaFromPageSet_Ordered(CXFA_Node* pPageSet, CXFA_Node* pStartChild, CXFA_Node* pTargetPageArea = NULL, CXFA_Node* pTargetContentArea = NULL, FX_BOOL bNewPage = FALSE, FX_BOOL bQuery = FALSE);
+ FX_BOOL FindPageAreaFromPageSet_SimplexDuplex(CXFA_Node* pPageSet, CXFA_Node* pStartChild, CXFA_Node* pTargetPageArea = NULL, CXFA_Node* pTargetContentArea = NULL, FX_BOOL bNewPage = FALSE, FX_BOOL bQuery = FALSE, XFA_ATTRIBUTEENUM ePreferredPosition = XFA_ATTRIBUTEENUM_First);
+ FX_BOOL MatchPageAreaOddOrEven(CXFA_Node* pPageArea, FX_BOOL bLastMatch);
+ CXFA_Node* GetNextAvailPageArea(CXFA_Node* pTargetPageArea, CXFA_Node* pTargetContentArea = NULL, FX_BOOL bNewPage = FALSE, FX_BOOL bQuery = FALSE);
+ FX_BOOL GetNextContentArea(CXFA_Node* pTargetContentArea);
+ void InitPageSetMap();
+ void ProcessLastPageSet();
+ inline FX_BOOL IsPageSetRootOrderedOccurrence()
+ {
+ return m_ePageSetMode == XFA_ATTRIBUTEENUM_OrderedOccurrence;
+ }
+ void ClearData();
+ void ClearRecordList();
+ void MergePageSetContents();
+ void LayoutPageSetContents();
+ void PrepareLayout();
+ CXFA_LayoutProcessor* m_pLayoutProcessor;
+ CXFA_Node* m_pTemplatePageSetRoot;
+ CXFA_ContainerLayoutItemImpl* m_pPageSetLayoutItemRoot;
+ CXFA_ContainerLayoutItemImpl* m_pPageSetCurRoot;
+ FX_POSITION m_pCurrentContainerRecord;
+ CFX_PtrList m_rgProposedContainerRecord;
+ CXFA_Node* m_pCurPageArea;
+ FX_INT32 m_nAvailPages;
+ FX_INT32 m_nCurPageCount;
+ XFA_ATTRIBUTEENUM m_ePageSetMode;
+ FX_BOOL m_bCreateOverFlowPage;
+ CFX_MapPtrTemplate<CXFA_Node*, FX_INT32> m_pPageSetMap;
+#ifdef _XFA_LAYOUTITEM_MAPCACHE_
+ void SaveLayoutItem(CXFA_LayoutItemImpl* pParentLayoutItem);
+ CFX_MapPtrToPtr m_NodeToContent;
+#elif defined(_XFA_LAYOUTITEM_ProcessCACHE_)
+ void SaveLayoutItem(CXFA_LayoutItemImpl* pParentLayoutItem);
+#endif
+ CFX_ArrayTemplate<CXFA_ContainerLayoutItemImpl*> m_PageArray;
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_locale.cpp b/xfa/src/fxfa/src/parser/xfa_locale.cpp
new file mode 100644
index 0000000000..d859905aa4
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_locale.cpp
@@ -0,0 +1,373 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_locale.h"
+const static FX_LPCWSTR g_FX_Percent = (FX_LPCWSTR)L"z,zzz,zzz,zzz,zzz,zzz%";
+const static FX_LPCWSTR g_FX_Currency = (FX_LPCWSTR)L"$z,zzz,zzz,zzz,zzz,zz9.99";
+const static FX_LPCWSTR g_FX_Decimal = (FX_LPCWSTR)L"z,zzz,zzz,zzz,zzz,zz9.zzz";
+const static FX_LPCWSTR g_FX_Integer = (FX_LPCWSTR)L"z,zzz,zzz,zzz,zzz,zzz";
+CXFA_XMLLocale::CXFA_XMLLocale(CXML_Element* pLocaleData)
+{
+ m_pLocaleData = pLocaleData;
+}
+CXFA_XMLLocale::~CXFA_XMLLocale()
+{
+ if (m_pLocaleData) {
+ delete m_pLocaleData;
+ }
+}
+void CXFA_XMLLocale::Release()
+{
+ delete this;
+}
+CFX_WideString CXFA_XMLLocale::GetName()
+{
+ return m_pLocaleData ? m_pLocaleData->GetAttrValue(FX_BSTRC("name")) : CFX_WideString();
+}
+void CXFA_XMLLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const
+{
+ CFX_ByteString bsSymbols;
+ CFX_WideString wsName;
+ switch (eType) {
+ case FX_LOCALENUMSYMBOL_Decimal:
+ bsSymbols = FX_BSTRC("numberSymbols");
+ wsName = FX_WSTRC(L"decimal");
+ break;
+ case FX_LOCALENUMSYMBOL_Grouping:
+ bsSymbols = FX_BSTRC("numberSymbols");
+ wsName = FX_WSTRC(L"grouping");
+ break;
+ case FX_LOCALENUMSYMBOL_Percent:
+ bsSymbols = FX_BSTRC("numberSymbols");
+ wsName = FX_WSTRC(L"percent");
+ break;
+ case FX_LOCALENUMSYMBOL_Minus:
+ bsSymbols = (FX_BSTRC("numberSymbols"));
+ wsName = FX_WSTRC(L"minus");
+ break;
+ case FX_LOCALENUMSYMBOL_Zero:
+ bsSymbols = (FX_BSTRC("numberSymbols"));
+ wsName = FX_WSTRC(L"zero");
+ break;
+ case FX_LOCALENUMSYMBOL_CurrencySymbol:
+ bsSymbols = (FX_BSTRC("currencySymbols"));
+ wsName = FX_WSTRC(L"symbol");
+ break;
+ case FX_LOCALENUMSYMBOL_CurrencyName:
+ bsSymbols = (FX_BSTRC("currencySymbols"));
+ wsName = FX_WSTRC(L"isoname");
+ break;
+ default:
+ return;
+ }
+ CXML_Element* pElement = m_pLocaleData->GetElement(FX_BSTRC(""), bsSymbols);
+ if (!pElement) {
+ return;
+ }
+ GetPattern(pElement, CFX_ByteStringC((FX_LPCSTR)bsSymbols, bsSymbols.GetLength() - 1), wsName, wsNumSymbol);
+}
+void CXFA_XMLLocale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const
+{
+ if (!m_pLocaleData) {
+ return;
+ }
+ CFX_ByteString bsSpace;
+ CXML_Element* pNumberSymbols = m_pLocaleData->GetElement(bsSpace, FX_BSTRC("dateTimeSymbols"));
+ if (!pNumberSymbols) {
+ return;
+ }
+ wsDtSymbol = pNumberSymbols->GetContent(0);
+}
+void CXFA_XMLLocale::GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr ) const
+{
+ wsMonthName = GetCalendarSymbol(FX_BSTRC("month"), nMonth, bAbbr);
+}
+void CXFA_XMLLocale::GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr ) const
+{
+ wsDayName = GetCalendarSymbol(FX_BSTRC("day"), nWeek, bAbbr);
+}
+void CXFA_XMLLocale::GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM ) const
+{
+ wsMeridiemName = GetCalendarSymbol(FX_BSTRC("meridiem"), bAM ? 0 : 1, FALSE);
+}
+void CXFA_XMLLocale::GetTimeZone(FX_TIMEZONE& tz) const
+{
+ IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get();
+ pProvider->GetTimeZone(tz);
+}
+void CXFA_XMLLocale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD ) const
+{
+ wsEraName = GetCalendarSymbol(FX_BSTRC("era"), bAD ? 1 : 0, FALSE);
+}
+CFX_WideString CXFA_XMLLocale::GetCalendarSymbol(FX_BSTR symbol, int index, FX_BOOL bAbbr) const
+{
+ CFX_ByteString pstrSymbolNames = symbol + "Names";
+ CFX_WideString wsSymbolName = L"";
+ if (m_pLocaleData) {
+ CXML_Element *pChild = m_pLocaleData->GetElement("", FX_BSTRC("calendarSymbols"));
+ if (pChild) {
+ CXML_Element *pSymbolNames = pChild->GetElement("", pstrSymbolNames);
+ if (pSymbolNames) {
+ if (pSymbolNames->GetAttrInteger(FX_BSTRC("abbr")) != bAbbr) {
+ pSymbolNames = pChild->GetElement("", pstrSymbolNames, 1);
+ }
+ if (pSymbolNames && pSymbolNames->GetAttrInteger(FX_BSTRC("abbr")) == bAbbr) {
+ CXML_Element *pSymbolName = pSymbolNames->GetElement("", symbol, index);
+ if (pSymbolName) {
+ wsSymbolName = pSymbolName->GetContent(0);
+ }
+ }
+ }
+ }
+ }
+ return wsSymbolName;
+}
+void CXFA_XMLLocale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ CXML_Element* pElement = m_pLocaleData->GetElement(FX_BSTRC(""), FX_BSTRC("datePatterns"));
+ if (pElement == NULL) {
+ return;
+ }
+ CFX_WideString wsName;
+ switch (eType) {
+ case FX_LOCALEDATETIMESUBCATEGORY_Short:
+ wsName = L"short";
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Default:
+ case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+ wsName = L"med";
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Full:
+ wsName = L"full";
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Long:
+ wsName = L"long";
+ break;
+ }
+ GetPattern(pElement, FX_BSTRC("datePattern"), wsName, wsPattern);
+}
+void CXFA_XMLLocale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ CXML_Element* pElement = m_pLocaleData->GetElement(FX_BSTRC(""), FX_BSTRC("timePatterns"));
+ if (pElement == NULL) {
+ return;
+ }
+ CFX_WideString wsName;
+ switch (eType) {
+ case FX_LOCALEDATETIMESUBCATEGORY_Short:
+ wsName = L"short";
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Default:
+ case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+ wsName = L"med";
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Full:
+ wsName = L"full";
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Long:
+ wsName = L"long";
+ break;
+ }
+ GetPattern(pElement, FX_BSTRC("timePattern"), wsName, wsPattern);
+}
+void CXFA_XMLLocale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ CXML_Element* pElement = m_pLocaleData->GetElement(FX_BSTRC(""), FX_BSTRC("numberPatterns"));
+ if (pElement == NULL) {
+ return;
+ }
+ switch (eType) {
+ case FX_LOCALENUMPATTERN_Percent:
+ wsPattern = g_FX_Percent;
+ break;
+ case FX_LOCALENUMPATTERN_Currency:
+ wsPattern = g_FX_Currency;
+ break;
+ case FX_LOCALENUMPATTERN_Decimal:
+ wsPattern = g_FX_Decimal;
+ break;
+ case FX_LOCALENUMPATTERN_Integer:
+ wsPattern = g_FX_Integer;
+ break;
+ }
+}
+void CXFA_XMLLocale::GetPattern(CXML_Element* pElement, FX_BSTR bsTag, FX_WSTR wsName, CFX_WideString& wsPattern) const
+{
+ FX_INT32 iCount = pElement->CountElements(FX_BSTRC(""), bsTag);
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXML_Element* pChild = pElement->GetElement(FX_BSTRC(""), bsTag, i);
+ if (pChild->GetAttrValue(FX_BSTRC("name")) == wsName) {
+ wsPattern = pChild->GetContent(0);
+ return;
+ }
+ }
+}
+CXFA_NodeLocale::CXFA_NodeLocale(CXFA_Node *pLocale)
+{
+ m_pLocale = pLocale;
+}
+CXFA_NodeLocale::~CXFA_NodeLocale()
+{
+}
+void CXFA_NodeLocale::Release()
+{
+ delete this;
+}
+CFX_WideString CXFA_NodeLocale::GetName()
+{
+ return m_pLocale ? m_pLocale->GetCData(XFA_ATTRIBUTE_Name) : NULL;
+}
+void CXFA_NodeLocale::GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const
+{
+ switch (eType) {
+ case FX_LOCALENUMSYMBOL_Decimal:
+ wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"decimal"));
+ break;
+ case FX_LOCALENUMSYMBOL_Grouping:
+ wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"grouping"));
+ break;
+ case FX_LOCALENUMSYMBOL_Percent:
+ wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"percent"));
+ break;
+ case FX_LOCALENUMSYMBOL_Minus:
+ wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"minus"));
+ break;
+ case FX_LOCALENUMSYMBOL_Zero:
+ wsNumSymbol = GetSymbol(XFA_ELEMENT_NumberSymbols, FX_WSTRC(L"zero"));
+ break;
+ case FX_LOCALENUMSYMBOL_CurrencySymbol:
+ wsNumSymbol = GetSymbol(XFA_ELEMENT_CurrencySymbols, FX_WSTRC(L"symbol"));
+ break;
+ case FX_LOCALENUMSYMBOL_CurrencyName:
+ wsNumSymbol = GetSymbol(XFA_ELEMENT_CurrencySymbols, FX_WSTRC(L"isoname"));
+ break;
+ }
+}
+void CXFA_NodeLocale::GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const
+{
+ CXFA_Node *pSymbols = m_pLocale ? m_pLocale->GetChild(0, XFA_ELEMENT_DateTimeSymbols) : NULL;
+ wsDtSymbol = pSymbols ? pSymbols->GetContent() : CFX_WideString();
+}
+void CXFA_NodeLocale::GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr ) const
+{
+ wsMonthName = GetCalendarSymbol(XFA_ELEMENT_MonthNames, nMonth, bAbbr);
+}
+void CXFA_NodeLocale::GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr ) const
+{
+ wsDayName = GetCalendarSymbol(XFA_ELEMENT_DayNames, nWeek, bAbbr);
+}
+void CXFA_NodeLocale::GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM ) const
+{
+ wsMeridiemName = GetCalendarSymbol(XFA_ELEMENT_MeridiemNames, bAM ? 0 : 1, FALSE);
+}
+void CXFA_NodeLocale::GetTimeZone(FX_TIMEZONE& tz) const
+{
+ IXFA_TimeZoneProvider* pProvider = IXFA_TimeZoneProvider::Get();
+ pProvider->GetTimeZone(tz);
+}
+void CXFA_NodeLocale::GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD ) const
+{
+ wsEraName = GetCalendarSymbol(XFA_ELEMENT_EraNames, bAD ? 1 : 0, FALSE);
+}
+void CXFA_NodeLocale::GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ switch (eType) {
+ case FX_LOCALEDATETIMESUBCATEGORY_Short:
+ wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"short"));
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+ case FX_LOCALEDATETIMESUBCATEGORY_Default:
+ wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"med"));
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Full:
+ wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"full"));
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Long:
+ wsPattern = GetSymbol(XFA_ELEMENT_DatePatterns, FX_WSTRC(L"long"));
+ break;
+ }
+}
+void CXFA_NodeLocale::GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ switch (eType) {
+ case FX_LOCALEDATETIMESUBCATEGORY_Short:
+ wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"short"));
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Medium:
+ case FX_LOCALEDATETIMESUBCATEGORY_Default:
+ wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"med"));
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Full:
+ wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"full"));
+ break;
+ case FX_LOCALEDATETIMESUBCATEGORY_Long:
+ wsPattern = GetSymbol(XFA_ELEMENT_TimePatterns, FX_WSTRC(L"long"));
+ break;
+ }
+}
+void CXFA_NodeLocale::GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const
+{
+ switch (eType) {
+ case FX_LOCALENUMPATTERN_Percent:
+ wsPattern = g_FX_Percent;
+ break;
+ case FX_LOCALENUMPATTERN_Currency:
+ wsPattern = g_FX_Currency;
+ break;
+ case FX_LOCALENUMPATTERN_Decimal:
+ wsPattern = g_FX_Decimal;
+ break;
+ case FX_LOCALENUMPATTERN_Integer:
+ wsPattern = g_FX_Integer;
+ break;
+ }
+}
+CXFA_Node* CXFA_NodeLocale::GetNodeByName(CXFA_Node *pParent, FX_WSTR wsName) const
+{
+ CXFA_Node *pChild = pParent ? pParent->GetNodeItem(XFA_NODEITEM_FirstChild) : NULL;
+ while (pChild) {
+ CFX_WideString wsChild;
+ if (pChild->GetAttribute(XFA_ATTRIBUTE_Name, wsChild)) {
+ if (wsChild == wsName) {
+ return pChild;
+ }
+ }
+ pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return NULL;
+}
+CFX_WideString CXFA_NodeLocale::GetSymbol(XFA_ELEMENT eElement, FX_WSTR symbol_type) const
+{
+ CXFA_Node *pSymbols = m_pLocale ? m_pLocale->GetChild(0, eElement) : NULL;
+ CXFA_Node *pSymbol = GetNodeByName(pSymbols, symbol_type);
+ return pSymbol ? pSymbol->GetContent() : CFX_WideString();
+}
+CFX_WideString CXFA_NodeLocale::GetCalendarSymbol(XFA_ELEMENT eElement, int index, FX_BOOL bAbbr) const
+{
+ CXFA_Node *pCalendar = m_pLocale ? m_pLocale->GetChild(0, XFA_ELEMENT_CalendarSymbols) : NULL;
+ if (pCalendar) {
+ CXFA_Node *pNode = pCalendar->GetFirstChildByClass(eElement);
+ for (; pNode; pNode = pNode->GetNextSameClassSibling(eElement)) {
+ if (pNode->GetBoolean(XFA_ATTRIBUTE_Abbr) == bAbbr) {
+ CXFA_Node *pSymbol = pNode->GetChild(index, XFA_ELEMENT_UNKNOWN);
+ return pSymbol ? pSymbol->GetContent() : CFX_WideString();
+ }
+ }
+ }
+ return CFX_WideString();
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_locale.h b/xfa/src/fxfa/src/parser/xfa_locale.h
new file mode 100644
index 0000000000..3f0b13a20d
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_locale.h
@@ -0,0 +1,61 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_LOCALE_H
+#define _FXFA_LOCALE_H
+class CXFA_XMLLocale : public IFX_Locale, public CFX_Object
+{
+public:
+ CXFA_XMLLocale(CXML_Element* pLocaleData);
+ virtual void Release();
+ virtual CFX_WideString GetName();
+ virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const;
+
+ virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const;
+ virtual void GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr = TRUE) const;
+ virtual void GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr = TRUE) const;
+ virtual void GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM = TRUE) const;
+ virtual void GetTimeZone(FX_TIMEZONE& tz) const;
+ virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const;
+
+ virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const;
+ virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const;
+ virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const;
+
+protected:
+ ~CXFA_XMLLocale();
+ void GetPattern(CXML_Element* pElement, FX_BSTR bsTag, FX_WSTR wsName, CFX_WideString& wsPattern) const;
+ CFX_WideString GetCalendarSymbol(FX_BSTR symbol, int index, FX_BOOL bAbbr) const;
+private:
+ CXML_Element* m_pLocaleData;
+};
+class CXFA_NodeLocale : public IFX_Locale, public CFX_Object
+{
+public:
+ CXFA_NodeLocale(CXFA_Node* pLocale);
+ virtual void Release();
+ virtual CFX_WideString GetName();
+ virtual void GetNumbericSymbol(FX_LOCALENUMSYMBOL eType, CFX_WideString& wsNumSymbol) const;
+
+ virtual void GetDateTimeSymbols(CFX_WideString& wsDtSymbol) const;
+ virtual void GetMonthName(FX_INT32 nMonth, CFX_WideString& wsMonthName, FX_BOOL bAbbr = TRUE) const;
+ virtual void GetDayName(FX_INT32 nWeek, CFX_WideString& wsDayName, FX_BOOL bAbbr = TRUE) const;
+ virtual void GetMeridiemName(CFX_WideString& wsMeridiemName, FX_BOOL bAM = TRUE) const;
+ virtual void GetTimeZone(FX_TIMEZONE& tz) const;
+ virtual void GetEraName(CFX_WideString& wsEraName, FX_BOOL bAD = TRUE) const;
+
+ virtual void GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const;
+ virtual void GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY eType, CFX_WideString& wsPattern) const;
+ virtual void GetNumPattern(FX_LOCALENUMSUBCATEGORY eType, CFX_WideString& wsPattern) const;
+protected:
+ ~CXFA_NodeLocale();
+ CXFA_Node* GetNodeByName(CXFA_Node *pParent, FX_WSTR wsName) const;
+ CFX_WideString GetSymbol(XFA_ELEMENT eElement, FX_WSTR symbol_type) const;
+ CFX_WideString GetCalendarSymbol(XFA_ELEMENT eElement, int index, FX_BOOL bAbbr) const;
+
+ CXFA_Node* m_pLocale;
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_localemgr.cpp b/xfa/src/fxfa/src/parser/xfa_localemgr.cpp
new file mode 100644
index 0000000000..8c56c95dc9
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_localemgr.cpp
@@ -0,0 +1,934 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_locale.h"
+const FX_BYTE g_enUS_Locale[] = {
+ 0x78, 0x9C, 0x95, 0x56, 0xD1, 0x6E, 0x9B, 0x30, 0x14, 0x7D, 0x9F, 0xB4, 0x7F, 0x40, 0xD6, 0x2A, 0xB5, 0x52, 0x56, 0x6F,
+ 0x8F, 0xA9, 0x88, 0xA5, 0x6C, 0x24, 0x9B, 0x3A, 0xD1, 0x55, 0x22, 0x55, 0xB5, 0xBE, 0x4C, 0x0E, 0xDC, 0x05, 0x34, 0xB0,
+ 0x23, 0x83, 0x37, 0x05, 0xED, 0xE3, 0x67, 0x07, 0xC3, 0xC0, 0xF6, 0x24, 0xC2, 0x4B, 0x7C, 0xCF, 0x3D, 0xE7, 0xE6, 0xDE,
+ 0x63, 0x30, 0x84, 0x25, 0x4F, 0x69, 0x09, 0x01, 0xA3, 0x15, 0xAC, 0x10, 0xB0, 0xEF, 0x4F, 0x09, 0x0A, 0x32, 0xA8, 0xD3,
+ 0x15, 0xDA, 0xB0, 0x43, 0x59, 0xD4, 0xF9, 0xF5, 0xBA, 0x02, 0x51, 0xA4, 0xF4, 0x06, 0x91, 0x50, 0x53, 0x59, 0x46, 0x45,
+ 0x72, 0xAA, 0xF6, 0xBC, 0xAC, 0x8D, 0xEA, 0x20, 0xE0, 0xC0, 0x45, 0x41, 0x99, 0x62, 0x54, 0x9C, 0x35, 0xF9, 0x83, 0x82,
+ 0x6B, 0xB3, 0x26, 0xF7, 0x94, 0x49, 0x2A, 0x4E, 0x21, 0xEE, 0xC2, 0xD7, 0xAF, 0x0C, 0xBE, 0x85, 0xBD, 0xF0, 0x26, 0x62,
+ 0x2A, 0xD2, 0xDC, 0x41, 0xD7, 0x47, 0x51, 0x94, 0x1E, 0xAE, 0xAB, 0xBF, 0x97, 0x0C, 0x3C, 0x60, 0xE9, 0x32, 0xD7, 0xF2,
+ 0x20, 0xEB, 0xC6, 0x81, 0x13, 0x38, 0x36, 0x50, 0xED, 0x41, 0x38, 0x99, 0xAF, 0x69, 0xC3, 0x7D, 0xF8, 0x03, 0xFF, 0xE5,
+ 0x17, 0x44, 0x90, 0xDA, 0x09, 0x3C, 0xB2, 0xA8, 0xE7, 0x9D, 0xA3, 0x80, 0xEE, 0xF7, 0x62, 0x85, 0xDE, 0xA3, 0x91, 0x73,
+ 0x3E, 0xD7, 0x7C, 0x86, 0xF9, 0xEC, 0x9A, 0x6B, 0x96, 0xCF, 0x2B, 0x9F, 0x55, 0x3E, 0x9F, 0x7C, 0x0E, 0xF9, 0xDC, 0xF1,
+ 0x19, 0xF3, 0x7F, 0x4F, 0x32, 0x7A, 0x32, 0xB7, 0x90, 0x5A, 0x91, 0x44, 0xAA, 0x5B, 0x4E, 0x75, 0xAE, 0xD7, 0x5D, 0x92,
+ 0xC4, 0xDC, 0x81, 0x76, 0x12, 0x6A, 0x1B, 0x7B, 0x86, 0x8C, 0xB9, 0xE8, 0x2E, 0x97, 0xC2, 0x01, 0xB7, 0xA2, 0xB0, 0xA1,
+ 0x84, 0x36, 0x52, 0x8C, 0x41, 0x3C, 0xF4, 0x35, 0xEA, 0x71, 0xB4, 0x6B, 0xA6, 0x59, 0xBB, 0x53, 0xBB, 0x4D, 0xBB, 0x45,
+ 0xBB, 0x39, 0xBB, 0x2F, 0xBB, 0x29, 0x7F, 0x3F, 0xFA, 0x21, 0xCD, 0x0A, 0xA8, 0xFA, 0x67, 0xCF, 0x84, 0x64, 0x1D, 0x2B,
+ 0x77, 0xFB, 0x60, 0xC4, 0x23, 0x8F, 0x56, 0x02, 0x4F, 0x2B, 0x28, 0x04, 0x04, 0x35, 0xD5, 0xD4, 0x8A, 0x7C, 0xF8, 0x18,
+ 0x62, 0xFD, 0xDB, 0x25, 0xC8, 0x3A, 0x1A, 0x42, 0x3C, 0x10, 0x75, 0x60, 0x9D, 0x11, 0x5D, 0xE3, 0x0D, 0x3C, 0xD2, 0xA6,
+ 0x01, 0xC1, 0xCE, 0x7B, 0x3A, 0x44, 0xE6, 0x00, 0xF9, 0x21, 0xCB, 0x12, 0x91, 0x8D, 0xBA, 0x16, 0x41, 0xAC, 0xAE, 0x20,
+ 0x5A, 0x04, 0xDF, 0xD4, 0xA5, 0x27, 0x1C, 0xB8, 0x56, 0x21, 0x23, 0x2D, 0x39, 0x3B, 0x20, 0x72, 0xA1, 0xA8, 0x82, 0xEC,
+ 0xAC, 0xB9, 0x40, 0x52, 0xE7, 0x5C, 0x34, 0x4A, 0x84, 0x23, 0xEC, 0xE1, 0xE3, 0xC9, 0x84, 0x0A, 0x68, 0x8A, 0x6A, 0x34,
+ 0xF1, 0x28, 0x9A, 0x4C, 0x9C, 0xDF, 0xC5, 0xF1, 0x5D, 0x92, 0x04, 0xEB, 0xE0, 0x25, 0xC4, 0x23, 0x92, 0x55, 0x61, 0x32,
+ 0xEA, 0x65, 0x9A, 0xF3, 0xA4, 0x83, 0x64, 0x86, 0xC0, 0xCC, 0xA9, 0x25, 0x1E, 0x3E, 0x9E, 0xCC, 0x65, 0x8C, 0xDA, 0x29,
+ 0xAC, 0xDF, 0xEC, 0x4F, 0xA7, 0x38, 0xFB, 0xF9, 0xB9, 0xAA, 0x93, 0x4D, 0xB4, 0xFD, 0xFD, 0x4C, 0xF3, 0x2F, 0xED, 0x4B,
+ 0x67, 0xCE, 0x98, 0xA4, 0x74, 0x4C, 0xEA, 0x53, 0xF1, 0x9F, 0x43, 0x93, 0xD8, 0xB4, 0xA2, 0x30, 0xFD, 0xE2, 0x41, 0xA4,
+ 0x5D, 0xB4, 0xED, 0xF2, 0xB6, 0x6D, 0xDB, 0x10, 0x4F, 0x78, 0x4E, 0x21, 0x23, 0x4C, 0xA5, 0x10, 0xC0, 0xD2, 0x13, 0x22,
+ 0x6F, 0x3A, 0xE9, 0x72, 0xF9, 0xE7, 0x7A, 0x58, 0xDE, 0xCC, 0xAC, 0x72, 0x04, 0x91, 0x02, 0x6B, 0xCC, 0xDF, 0x5F, 0x79,
+ 0x54, 0xD8, 0x9A, 0x62, 0x28, 0xD4, 0x0F, 0x3A, 0x09, 0x4D, 0xD9, 0x0C, 0xD2, 0xA2, 0xA2, 0x6A, 0xF3, 0x6F, 0x7B, 0x7D,
+ 0x97, 0xB6, 0xD5, 0xC3, 0xBB, 0x95, 0xCB, 0x63, 0xA1, 0x37, 0x7E, 0x31, 0x8B, 0x3F, 0x74, 0x7D, 0x35, 0x8B, 0x5E, 0x15,
+ 0x4C, 0xD6, 0x88, 0xBC, 0x9D, 0x45, 0x6E, 0x41, 0x70, 0x44, 0xDE, 0xB9, 0x5C, 0x3C, 0x1D, 0x5B, 0x21, 0xFD, 0x16, 0x0C,
+ 0x4E, 0x4C, 0x81, 0xFE, 0x66, 0x3B, 0x07, 0x6A, 0x9B, 0xD4, 0xA9, 0x31, 0xC9, 0xBB, 0x25, 0x8C, 0xA2, 0xA8, 0xB9, 0x5E,
+ 0x20, 0xF2, 0x94, 0x44, 0xB3, 0x45, 0x63, 0xCB, 0x5D, 0x09, 0xB6, 0x7B, 0xD5, 0x58, 0xF7, 0x55, 0xA4, 0x96, 0x7F, 0x01,
+ 0x75, 0x37, 0x1B, 0x8B,
+};
+const FX_BYTE g_enGB_Locale[] = {
+ 0x78, 0x9C, 0x95, 0x56, 0xD1, 0x6E, 0xD3, 0x30, 0x14, 0x7D, 0x47, 0xE2, 0x1F, 0xA2, 0x88, 0x49, 0x20, 0x6D, 0x33, 0x3C,
+ 0x6E, 0xEA, 0x2C, 0x75, 0xEB, 0xD6, 0x32, 0xC8, 0xA8, 0x48, 0xC5, 0xC4, 0x5E, 0x90, 0x9B, 0x78, 0x8D, 0x59, 0x62, 0x57,
+ 0x4E, 0xCC, 0x94, 0xFC, 0x02, 0x9F, 0xC0, 0x23, 0xCF, 0x08, 0xF1, 0x01, 0xBC, 0xF0, 0x2F, 0x48, 0xFB, 0x0C, 0x6E, 0x1A,
+ 0x27, 0x4B, 0x1C, 0xAF, 0x64, 0x79, 0x89, 0xEF, 0xB9, 0xE7, 0xDC, 0xDE, 0x7B, 0x9C, 0xB8, 0x19, 0xC5, 0x22, 0x20, 0x31,
+ 0x75, 0x38, 0x49, 0xE8, 0x91, 0x4B, 0xF9, 0xA7, 0xE9, 0xB1, 0xEB, 0x84, 0x34, 0x0D, 0x8E, 0xDC, 0xBB, 0xAF, 0xBF, 0xEE,
+ 0x7E, 0xFE, 0x78, 0x0E, 0xB7, 0xBF, 0xDF, 0x7E, 0xBF, 0x70, 0xF1, 0xA8, 0x24, 0xF2, 0x90, 0x48, 0x3F, 0x4F, 0x96, 0x22,
+ 0x4E, 0xB5, 0x66, 0x25, 0xE9, 0x4A, 0x48, 0x46, 0x38, 0x30, 0x12, 0xC1, 0xB3, 0xE8, 0x02, 0xE0, 0x54, 0xAF, 0xF1, 0x39,
+ 0xE1, 0x8A, 0xC8, 0x7C, 0x84, 0xAA, 0xF0, 0xE9, 0x13, 0x8D, 0x9F, 0xD1, 0xA5, 0xB4, 0x26, 0x3C, 0x22, 0x83, 0xA8, 0x87,
+ 0x8E, 0xD7, 0x92, 0xC5, 0x16, 0x6E, 0x5F, 0x7F, 0xAE, 0x38, 0xB5, 0x80, 0x71, 0x9F, 0x39, 0x56, 0x2B, 0x95, 0x66, 0x3D,
+ 0xD8, 0xA7, 0xEB, 0x8C, 0x26, 0x4B, 0x2A, 0x7B, 0x99, 0x77, 0x41, 0x26, 0x6C, 0xF8, 0x85, 0xF8, 0x62, 0x17, 0x4C, 0x68,
+ 0x60, 0x26, 0x50, 0xCB, 0xA2, 0x9A, 0xB7, 0x89, 0x1C, 0xB2, 0x5C, 0xCA, 0x23, 0xF7, 0x95, 0xDB, 0x72, 0xCE, 0xE6, 0x9A,
+ 0xCD, 0x30, 0x9B, 0x5D, 0x43, 0xCD, 0xB2, 0x79, 0x65, 0xB3, 0xCA, 0xE6, 0x93, 0xCD, 0x21, 0x9B, 0x3B, 0x36, 0x63, 0x1E,
+ 0xF6, 0x24, 0x24, 0xB9, 0x7E, 0x84, 0x60, 0x85, 0x7D, 0x05, 0x8F, 0x1C, 0x74, 0x5E, 0xAE, 0xAB, 0x24, 0xF6, 0x44, 0x0F,
+ 0x5A, 0x28, 0x9A, 0x9A, 0xD8, 0x25, 0x0D, 0x79, 0x1F, 0x5D, 0x44, 0x4A, 0xF6, 0xC0, 0x33, 0xC9, 0x4C, 0xC8, 0x27, 0x99,
+ 0x92, 0x6D, 0x10, 0x35, 0x7D, 0xB5, 0x7A, 0x6C, 0xED, 0x9A, 0x6E, 0xD6, 0xEC, 0xD4, 0x6C, 0xD3, 0x6C, 0xD1, 0x6C, 0xCE,
+ 0xEC, 0xCB, 0x6C, 0xCA, 0xDE, 0x4F, 0x42, 0x61, 0x02, 0x46, 0x93, 0xFA, 0xDD, 0xD3, 0x21, 0x1E, 0x7B, 0xE0, 0x6E, 0x1D,
+ 0xB4, 0x78, 0x78, 0x6E, 0x24, 0x50, 0xB7, 0x02, 0x20, 0x54, 0x12, 0x5D, 0x0D, 0x56, 0xF8, 0xF8, 0x64, 0x84, 0xCA, 0x7B,
+ 0x95, 0xC0, 0xE3, 0x49, 0x13, 0xA2, 0x86, 0x58, 0x06, 0xC6, 0x19, 0x51, 0x35, 0x9E, 0xD1, 0x39, 0xC9, 0x32, 0x2A, 0xF9,
+ 0x66, 0x4F, 0x9B, 0x48, 0x1F, 0x20, 0xD7, 0x2A, 0x8E, 0x5D, 0x7C, 0x0A, 0xD7, 0xAE, 0x33, 0x71, 0x3C, 0xB8, 0x9C, 0x8F,
+ 0x70, 0x95, 0x03, 0x36, 0x54, 0xA3, 0x8E, 0x56, 0xC6, 0x82, 0xAF, 0x5C, 0xFC, 0x38, 0x4D, 0x42, 0x43, 0x2D, 0x19, 0xAA,
+ 0x48, 0x23, 0x21, 0x33, 0xD0, 0x4C, 0x90, 0xE7, 0x21, 0xAB, 0x06, 0x75, 0x46, 0x04, 0x20, 0x63, 0x49, 0x6B, 0xE4, 0x56,
+ 0xD4, 0x19, 0x79, 0x36, 0x3B, 0xF4, 0xBC, 0x43, 0xDF, 0x77, 0xAE, 0x46, 0xA8, 0xC5, 0x31, 0x0A, 0x74, 0x66, 0x7D, 0x94,
+ 0x64, 0x33, 0x6A, 0xAD, 0x18, 0xC0, 0xD7, 0x83, 0x6E, 0x14, 0x3D, 0x3A, 0xEA, 0xCC, 0xA4, 0x8D, 0x5A, 0x00, 0x56, 0xEF,
+ 0xF4, 0x34, 0xF7, 0xC2, 0x9B, 0x59, 0x92, 0xFA, 0xA7, 0x93, 0xB3, 0xDB, 0x4B, 0x12, 0xBD, 0x29, 0xAE, 0x2A, 0x63, 0xDA,
+ 0x24, 0xD0, 0x71, 0x55, 0x1E, 0x89, 0xF7, 0xEE, 0x74, 0x62, 0xDD, 0x09, 0x60, 0xF0, 0x38, 0x06, 0x2E, 0x2E, 0x76, 0x8B,
+ 0xE2, 0x60, 0xBF, 0x28, 0x8A, 0x11, 0xEA, 0xF0, 0x7A, 0x85, 0xB4, 0x30, 0x50, 0x52, 0x52, 0x1E, 0xE4, 0x2E, 0x7E, 0x56,
+ 0x49, 0x0F, 0x0E, 0x06, 0x2A, 0xD7, 0x54, 0x06, 0x94, 0x67, 0xFA, 0x27, 0x77, 0x2C, 0x2A, 0x64, 0x74, 0xDE, 0x14, 0xAA,
+ 0x87, 0xEB, 0x84, 0xBA, 0x6C, 0x48, 0x03, 0x96, 0x10, 0xD8, 0xEC, 0xFD, 0x5A, 0x5F, 0xA5, 0x4D, 0x75, 0xF3, 0x67, 0x2A,
+ 0xD4, 0x9A, 0x95, 0x3B, 0xBD, 0x3B, 0x88, 0xDF, 0x74, 0xBD, 0x33, 0x88, 0x9E, 0x30, 0xAE, 0x52, 0x17, 0xEF, 0x0D, 0x22,
+ 0x17, 0x54, 0x0A, 0x17, 0xBF, 0xEC, 0x73, 0x51, 0x77, 0x6C, 0x40, 0x6A, 0xDB, 0x1B, 0x27, 0xBA, 0x40, 0xFD, 0x7C, 0x6D,
+ 0x02, 0x17, 0xFF, 0xF9, 0x0E, 0xE7, 0x44, 0x87, 0xD0, 0xAF, 0xA1, 0x25, 0x2C, 0x15, 0xE5, 0xC2, 0xC5, 0xD3, 0xE3, 0xF9,
+ 0x60, 0x51, 0xDB, 0xF3, 0xBE, 0x04, 0x99, 0xCD, 0x96, 0xEF, 0x42, 0xBE, 0xA6, 0xD7, 0x24, 0x28, 0x0F, 0xBB, 0x7A, 0xA9,
+ 0x6B, 0x79, 0x39, 0x7C, 0xDA, 0x84, 0xCE, 0x1C, 0xAC, 0x40, 0x6D, 0x66, 0x9D, 0x66, 0x9C, 0x09, 0xFE, 0x60, 0xFA, 0x44,
+ 0x28, 0xC9, 0xA8, 0x74, 0xFC, 0x2C, 0xB4, 0xE6, 0xC7, 0x21, 0x7C, 0x50, 0x38, 0x73, 0xF6, 0x1F, 0xC2, 0x0C, 0x3E, 0x96,
+ 0xE8, 0xED, 0x16, 0xC2, 0x58, 0x92, 0x25, 0xBC, 0x2E, 0x0F, 0x13, 0x16, 0x11, 0x61, 0xD6, 0xF4, 0x1B, 0x51, 0xA8, 0x1B,
+ 0xE2, 0x4C, 0x45, 0x16, 0xB1, 0xA0, 0x9C, 0x63, 0xEF, 0xC3, 0x6B, 0xC7, 0xDB, 0x46, 0x85, 0x91, 0x83, 0x48, 0xD4, 0xD4,
+ 0xF7, 0x5B, 0x7E, 0x14, 0x98, 0xAB, 0x72, 0x32, 0xE7, 0xED, 0x16, 0x92, 0x2F, 0x06, 0x90, 0xBC, 0x5C, 0xF1, 0xD5, 0x67,
+ 0xB1, 0xE1, 0xE9, 0xE6, 0xD0, 0xFD, 0x9E, 0x95, 0x51, 0xF5, 0x19, 0x0B, 0xCB, 0x7F, 0x8E, 0x69, 0xAC, 0xD0
+};
+const FX_BYTE g_zhCN_Locale[] = {
+ 0x78, 0x9C, 0xED, 0x56, 0x41, 0x4F, 0xD4, 0x40, 0x14, 0xBE, 0x9B, 0xF8, 0x1F, 0x9A, 0x46, 0x52, 0x4D, 0x58, 0x46, 0x8F,
+ 0x90, 0xD2, 0x64, 0x03, 0x08, 0x06, 0xBB, 0x21, 0x96, 0x68, 0xE0, 0x62, 0xBA, 0xED, 0xB0, 0x2D, 0x6C, 0x3B, 0x64, 0xB6,
+ 0x0D, 0x6E, 0x4F, 0x18, 0x82, 0x82, 0xC2, 0x45, 0x89, 0x9A, 0x80, 0xE1, 0x64, 0x3C, 0x28, 0x9E, 0x8C, 0x01, 0x22, 0xF1,
+ 0xCF, 0xB0, 0xCB, 0x91, 0xBF, 0xE0, 0x9B, 0xED, 0xB4, 0xB4, 0xDD, 0xD9, 0xB5, 0x3F, 0xC0, 0x3D, 0xCD, 0xFB, 0xDE, 0xF7,
+ 0x7D, 0xF3, 0xDE, 0xEB, 0x74, 0xB6, 0x6A, 0x93, 0x58, 0x66, 0x13, 0x4B, 0xBE, 0xE9, 0xE1, 0x49, 0x39, 0x72, 0x9E, 0x4F,
+ 0xD5, 0x64, 0xC9, 0xC6, 0x2D, 0x6B, 0x52, 0xBE, 0x3C, 0x3D, 0xE9, 0x7E, 0x78, 0x7D, 0xF7, 0xEA, 0xC7, 0xE6, 0xE5, 0xC5,
+ 0xFB, 0xEB, 0xDF, 0x7B, 0x10, 0x77, 0x0E, 0x2F, 0xEE, 0xC9, 0x9A, 0xCA, 0x14, 0xBE, 0x6D, 0x52, 0xA3, 0xED, 0xD5, 0x49,
+ 0xB3, 0xC5, 0xC5, 0x0D, 0x8A, 0x1B, 0x84, 0xBA, 0xA6, 0x0F, 0x0C, 0x8F, 0xF8, 0x81, 0x53, 0x03, 0xB8, 0xC5, 0xD7, 0xDA,
+ 0xE5, 0xE9, 0x66, 0xF7, 0x68, 0x47, 0x45, 0x71, 0x74, 0xFB, 0x56, 0x02, 0x9F, 0xEF, 0x09, 0xE1, 0xD3, 0x5D, 0x11, 0xDC,
+ 0x39, 0x3C, 0x14, 0x9B, 0x1C, 0x08, 0xD9, 0xDB, 0x27, 0x62, 0xEF, 0x2D, 0x31, 0xFB, 0x9B, 0x90, 0x7D, 0xF6, 0x59, 0xC8,
+ 0xDE, 0x7F, 0x39, 0x00, 0x1E, 0xD0, 0x28, 0xCB, 0x14, 0x7B, 0x45, 0x99, 0x31, 0x25, 0xC4, 0x5E, 0x24, 0x99, 0xF5, 0x3A,
+ 0x9D, 0x94, 0x1F, 0xC8, 0xFF, 0xA7, 0x57, 0x7A, 0x7A, 0xB6, 0xD9, 0xE6, 0x07, 0x0E, 0x56, 0x5A, 0xF7, 0xD3, 0x71, 0xF7,
+ 0xE8, 0xB8, 0xFB, 0xF1, 0x8B, 0x8A, 0x58, 0x18, 0xE7, 0x39, 0x0A, 0x7B, 0x88, 0xD0, 0xF3, 0x3D, 0x21, 0x77, 0x57, 0x80,
+ 0xC2, 0x24, 0x85, 0x0E, 0x07, 0x22, 0xEE, 0xF6, 0x49, 0x8A, 0xA2, 0xB4, 0xC8, 0x4C, 0xC1, 0x99, 0x87, 0xDD, 0x53, 0x15,
+ 0x6A, 0x2E, 0x56, 0x5B, 0xAC, 0xB3, 0x58, 0x61, 0xB1, 0xB6, 0x62, 0x55, 0x03, 0xEB, 0xF1, 0x30, 0x75, 0x6D, 0x17, 0x7B,
+ 0xC9, 0x6B, 0xCB, 0x43, 0xD8, 0xE0, 0x4D, 0x67, 0x9F, 0x0D, 0x3E, 0x01, 0x32, 0x5C, 0x48, 0xBE, 0xED, 0x4B, 0xA2, 0xBC,
+ 0x13, 0x20, 0x98, 0x9A, 0xDC, 0x15, 0x56, 0x50, 0xC1, 0xF7, 0xCE, 0xF6, 0x56, 0x67, 0x77, 0x5F, 0x45, 0x2C, 0x8C, 0xF3,
+ 0x1C, 0x4D, 0x21, 0x94, 0x6A, 0x58, 0x50, 0xB8, 0x71, 0xE2, 0x5E, 0x02, 0xBC, 0x60, 0x06, 0x01, 0xA6, 0x7E, 0xEF, 0x99,
+ 0xA7, 0x11, 0xBF, 0x8E, 0x56, 0xC2, 0x66, 0x53, 0xD6, 0x96, 0xE0, 0xA7, 0x74, 0xCE, 0x7E, 0x2A, 0xBA, 0x02, 0xA7, 0x47,
+ 0x99, 0x56, 0x60, 0xBC, 0xCA, 0x0C, 0xFC, 0x58, 0xEF, 0xA9, 0xA4, 0xE0, 0xC7, 0x1D, 0x9A, 0xC4, 0x6F, 0x0C, 0x70, 0x28,
+ 0xA1, 0xF6, 0xB0, 0x1D, 0x8B, 0x2B, 0x7A, 0x65, 0xBA, 0x04, 0xBF, 0xE5, 0x10, 0x1A, 0x30, 0x85, 0x90, 0x8F, 0x72, 0xED,
+ 0x02, 0x10, 0xB8, 0x5E, 0xA6, 0xFD, 0x4C, 0x94, 0x6B, 0xBF, 0xEA, 0x38, 0x50, 0xEF, 0x2F, 0x45, 0xD7, 0x95, 0xCE, 0xCE,
+ 0x2B, 0xC5, 0x30, 0x94, 0xAB, 0xAF, 0xEF, 0x14, 0x69, 0x59, 0x45, 0x19, 0x45, 0xC1, 0x2E, 0xD7, 0xBD, 0xD8, 0xA0, 0x84,
+ 0xBC, 0xD7, 0x3E, 0xA8, 0x27, 0x74, 0x7D, 0xC2, 0x30, 0x4A, 0x08, 0x78, 0xFF, 0x55, 0xA6, 0xE8, 0xA3, 0xA3, 0x5C, 0xBB,
+ 0x7C, 0x7E, 0x8B, 0x80, 0x25, 0x07, 0x62, 0xD6, 0xF4, 0x57, 0xD7, 0xE6, 0xBC, 0x96, 0x31, 0x33, 0xFD, 0x70, 0xE3, 0xD9,
+ 0x0B, 0x67, 0x3E, 0x5A, 0x8E, 0x67, 0x96, 0x25, 0x81, 0xCE, 0x0F, 0xBD, 0x3A, 0xA6, 0x37, 0x83, 0xCB, 0xC5, 0xBC, 0x12,
+ 0xC0, 0xE0, 0x00, 0x5B, 0xB2, 0x16, 0x8D, 0x46, 0xD1, 0xF8, 0x58, 0x14, 0x45, 0x2A, 0xCA, 0xF1, 0xFA, 0x8C, 0xB8, 0xD0,
+ 0x0A, 0x29, 0xC5, 0xBE, 0xD5, 0x96, 0xB5, 0x3B, 0xB1, 0x74, 0x7C, 0xBC, 0xA4, 0x72, 0x1D, 0x53, 0x0B, 0xFB, 0x01, 0xDF,
+ 0x72, 0x44, 0xA0, 0x42, 0x85, 0xCA, 0x53, 0xA3, 0xA4, 0xB9, 0x5C, 0xC8, 0x6D, 0x6D, 0x6C, 0xB9, 0x9E, 0x09, 0xE7, 0x60,
+ 0x2C, 0xD1, 0xC7, 0xE9, 0xA2, 0x3A, 0xFD, 0x07, 0x27, 0xE1, 0xBA, 0xCB, 0x1E, 0xFB, 0x68, 0x29, 0x7E, 0x5A, 0xF5, 0x48,
+ 0x29, 0xBA, 0xE7, 0xFA, 0x61, 0x4B, 0xD6, 0x2A, 0xA5, 0xC8, 0x11, 0xA6, 0x44, 0xD6, 0xEE, 0xF7, 0x73, 0x51, 0xBE, 0x6D,
+ 0x40, 0x92, 0xB1, 0xA7, 0x93, 0xC8, 0x03, 0xC9, 0xF9, 0xEA, 0x05, 0xB2, 0x76, 0xFD, 0x07, 0xEE, 0xD7, 0x3C, 0xA3, 0xDF,
+ 0x84, 0x6B, 0xDC, 0x16, 0x61, 0x0B, 0x59, 0x9B, 0xAA, 0x2D, 0x95, 0x16, 0x65, 0x87, 0xDE, 0x2F, 0x41, 0xC5, 0x6A, 0xD9,
+ 0xCB, 0xD0, 0x5E, 0xC7, 0x2B, 0xA6, 0xC5, 0xEE, 0xC7, 0x64, 0xC9, 0xBD, 0xAA, 0x36, 0xA9, 0x63, 0xC9, 0x80, 0x57, 0x51,
+ 0x32, 0x02, 0x5B, 0x7A, 0x2C, 0xA3, 0x2C, 0x9F, 0x93, 0xF4, 0x36, 0x7C, 0x75, 0xD9, 0xD2, 0x02, 0x0C, 0x4C, 0x98, 0x76,
+ 0x7D, 0x97, 0xF8, 0x03, 0xD3, 0x53, 0x24, 0xA4, 0x2E, 0xA6, 0xCC, 0x5F, 0x98, 0x8F, 0x4B, 0x58, 0x70, 0xFF, 0x41, 0x98,
+ 0xC3, 0x75, 0x8A, 0x37, 0x86, 0x10, 0xAA, 0xD4, 0xAC, 0xC3, 0x4B, 0x35, 0x98, 0xB0, 0xE8, 0x98, 0xAE, 0x30, 0x3D, 0x4F,
+ 0xA2, 0x70, 0xCD, 0x94, 0x66, 0x49, 0xE0, 0xB8, 0x16, 0xEB, 0xA3, 0xF2, 0xF4, 0x91, 0xA4, 0x0F, 0xA3, 0x42, 0xCB, 0x96,
+ 0x43, 0x12, 0xEA, 0x93, 0x21, 0x9B, 0x02, 0x73, 0xD8, 0x68, 0x39, 0xA9, 0x1D, 0xFA, 0x8D, 0x55, 0xD2, 0xE3, 0xF1, 0x7D,
+ 0xD1, 0xCD, 0x33, 0x63, 0x51, 0xFC, 0x15, 0x0D, 0xCB, 0xBF, 0xC0, 0xE4, 0x3D, 0x40
+};
+const FX_BYTE g_zhTW_Locale[] = {
+ 0x78, 0x9C, 0xED, 0x57, 0xCD, 0x4F, 0xD4, 0x40, 0x14, 0x3F, 0x63, 0xE2, 0xFF, 0x30, 0x69, 0x20, 0xD5, 0x04, 0xA8, 0x1E,
+ 0x21, 0xA5, 0xC9, 0xC6, 0x45, 0x30, 0x58, 0x42, 0xEC, 0x46, 0x22, 0x17, 0x33, 0xDB, 0x0E, 0xDB, 0xC2, 0xB6, 0x43, 0x66,
+ 0xDB, 0xC0, 0xF6, 0x24, 0x12, 0x14, 0x14, 0x62, 0xA2, 0xC4, 0x8F, 0x80, 0xE1, 0x64, 0x3C, 0x28, 0x89, 0x07, 0x0F, 0x2C,
+ 0x51, 0xFF, 0x1A, 0x76, 0x39, 0xFA, 0x2F, 0x38, 0xD3, 0x2F, 0xFA, 0xB1, 0xB3, 0xD4, 0xC4, 0xA3, 0x7B, 0x9A, 0xF7, 0xDE,
+ 0xEF, 0xF7, 0xE6, 0xBD, 0xDF, 0xBC, 0x7D, 0xD9, 0x95, 0x9B, 0x58, 0x87, 0x4D, 0x04, 0x1C, 0x68, 0xA3, 0x29, 0xC1, 0x37,
+ 0x1F, 0xD7, 0x16, 0x05, 0x60, 0xA0, 0x96, 0x3E, 0x25, 0x9C, 0x9F, 0x9E, 0xF4, 0xDE, 0x3E, 0xBF, 0x71, 0xD1, 0xD9, 0x3C,
+ 0xFF, 0xF9, 0xE6, 0xF7, 0x8F, 0xBD, 0xEE, 0xAB, 0x6F, 0xBD, 0xCE, 0xAF, 0x9B, 0x82, 0x72, 0xFD, 0x1A, 0x00, 0x32, 0x63,
+ 0x39, 0x06, 0x24, 0x5A, 0xDB, 0xAE, 0xE3, 0x66, 0x2B, 0x4A, 0xD0, 0x20, 0xA8, 0x81, 0x89, 0x05, 0x1D, 0x86, 0x1A, 0x02,
+ 0xB2, 0x8D, 0x1D, 0xD7, 0x9C, 0xA7, 0xA1, 0x16, 0xB3, 0x87, 0x42, 0x5B, 0x39, 0x3F, 0x7D, 0xD2, 0x3B, 0xDA, 0x91, 0xA5,
+ 0xD0, 0x4A, 0x07, 0xCE, 0xF6, 0x38, 0x81, 0xD3, 0xDD, 0xFE, 0x81, 0xEE, 0xE1, 0x21, 0x2F, 0xD5, 0x01, 0x87, 0xB1, 0x7D,
+ 0xC2, 0xBB, 0x63, 0x8B, 0xC7, 0xF8, 0xC2, 0x61, 0x74, 0x3E, 0x72, 0x18, 0xFB, 0x9B, 0xDC, 0x00, 0xB7, 0x79, 0x16, 0xCB,
+ 0xF7, 0x0F, 0xA2, 0x73, 0x22, 0x61, 0x5A, 0x52, 0x00, 0xEB, 0x75, 0x32, 0x25, 0xDC, 0x16, 0xFE, 0x6B, 0xFB, 0x8F, 0xB4,
+ 0x35, 0x60, 0x3B, 0x35, 0xAC, 0xD4, 0x52, 0x7A, 0xEF, 0x8F, 0x7B, 0x47, 0xC7, 0xBD, 0x77, 0x9F, 0x64, 0x89, 0x99, 0x39,
+ 0x3F, 0xBD, 0xAF, 0xBF, 0xFF, 0x6C, 0x8F, 0x83, 0xDF, 0xED, 0xEB, 0xA7, 0x4A, 0x73, 0xF2, 0x1C, 0xF4, 0xC7, 0x6F, 0x9F,
+ 0x24, 0x7E, 0x10, 0x9C, 0xFA, 0x34, 0x91, 0x1B, 0x8F, 0x80, 0x5D, 0xE8, 0xA3, 0xD8, 0x41, 0xB1, 0xF6, 0x62, 0xD5, 0xC5,
+ 0x7A, 0x8B, 0x95, 0x0E, 0xAC, 0xD1, 0x46, 0xC4, 0x32, 0x2C, 0x64, 0xA7, 0x57, 0x43, 0xE4, 0xA2, 0xD7, 0xBD, 0xE8, 0xEE,
+ 0xB3, 0x87, 0x8A, 0x1D, 0xF9, 0xF0, 0xCB, 0x42, 0x18, 0x5C, 0x9A, 0xA9, 0x4B, 0x10, 0x81, 0xA9, 0xFC, 0xD4, 0xA2, 0x35,
+ 0x7D, 0xED, 0x6E, 0x6F, 0x75, 0x77, 0xF7, 0x65, 0x89, 0x99, 0x39, 0x7F, 0xE2, 0x04, 0xC1, 0x29, 0xE6, 0xD2, 0x65, 0x27,
+ 0xE5, 0xB6, 0x5D, 0xE8, 0x35, 0xA0, 0x8B, 0x16, 0xA0, 0xEB, 0x22, 0xE2, 0x24, 0xD2, 0x27, 0x9E, 0x68, 0x21, 0x2E, 0x7B,
+ 0xCD, 0xA6, 0xA0, 0x3C, 0xA2, 0x1F, 0xB1, 0xDB, 0xF9, 0x2E, 0xAA, 0x22, 0x9D, 0x41, 0xB1, 0x2A, 0xD2, 0x87, 0x10, 0xA7,
+ 0xE9, 0x87, 0xE9, 0x92, 0x50, 0x78, 0x39, 0x9A, 0xD8, 0x69, 0x70, 0x72, 0x94, 0xE2, 0xDB, 0xC8, 0x08, 0xE9, 0x92, 0x2A,
+ 0x55, 0x4B, 0x31, 0x5A, 0x26, 0x26, 0x2E, 0x9F, 0x03, 0x40, 0xC6, 0x13, 0xC9, 0xE1, 0x5A, 0x76, 0x4E, 0x8E, 0x94, 0x27,
+ 0x23, 0x47, 0xC5, 0x34, 0xC5, 0xDE, 0x87, 0xA7, 0xA2, 0xAA, 0x8A, 0xDD, 0x9D, 0x67, 0xA2, 0xA6, 0x89, 0x17, 0x9F, 0x5F,
+ 0x8B, 0x60, 0x49, 0x96, 0x52, 0x0C, 0x5E, 0x8A, 0x50, 0x8D, 0xFE, 0x29, 0x4A, 0x25, 0x08, 0xE4, 0xA8, 0x00, 0x73, 0x52,
+ 0x55, 0x27, 0x35, 0xAD, 0x14, 0x25, 0xD2, 0x23, 0x24, 0xE5, 0x19, 0x4C, 0x8D, 0x5C, 0xEF, 0xD1, 0x70, 0xD4, 0xA8, 0x37,
+ 0x9E, 0x98, 0x19, 0xE8, 0xAC, 0xAC, 0xCE, 0xDA, 0x2D, 0x6D, 0xBA, 0x7A, 0x77, 0x7D, 0x71, 0xC3, 0x9C, 0xF3, 0x97, 0x42,
+ 0x11, 0xD3, 0xA0, 0x80, 0xE9, 0x78, 0x76, 0x1D, 0x91, 0xAC, 0x92, 0x19, 0x5F, 0x54, 0x14, 0xF5, 0xD1, 0x99, 0xD7, 0x05,
+ 0xC5, 0x1F, 0xF5, 0xFD, 0x89, 0x71, 0xDF, 0xF7, 0x65, 0x29, 0x83, 0xE3, 0x53, 0x75, 0x8F, 0x10, 0xE4, 0xE8, 0x6D, 0x41,
+ 0x19, 0x0E, 0xC9, 0x13, 0x13, 0xA5, 0xB9, 0x6B, 0x88, 0xE8, 0xC8, 0x71, 0xA3, 0x6B, 0x47, 0x8A, 0x3C, 0xA6, 0x47, 0xA1,
+ 0x87, 0xA4, 0xAF, 0xCB, 0x56, 0x87, 0xB2, 0xAE, 0x28, 0xBD, 0x81, 0x74, 0xCB, 0x86, 0x74, 0x48, 0xC6, 0xE3, 0x2C, 0x61,
+ 0x98, 0x4B, 0x68, 0x10, 0xEC, 0xAD, 0x59, 0x6C, 0x26, 0x46, 0x4B, 0x32, 0x92, 0x0E, 0x46, 0x4A, 0x12, 0x6C, 0xCB, 0xF1,
+ 0x5A, 0x82, 0x32, 0x56, 0x12, 0xEE, 0x23, 0x82, 0x05, 0xE5, 0x56, 0x01, 0x7D, 0x29, 0x4C, 0xE6, 0xBD, 0xE3, 0xC7, 0xC8,
+ 0x28, 0x93, 0x75, 0xC6, 0x63, 0x18, 0x18, 0x82, 0x32, 0x5F, 0x1B, 0xA6, 0x2B, 0x29, 0x83, 0x18, 0xC0, 0xB2, 0x5A, 0x98,
+ 0x1D, 0x04, 0xA5, 0xB6, 0x58, 0xFD, 0x0B, 0x5A, 0xFA, 0x21, 0x0A, 0xA4, 0x60, 0x27, 0x16, 0xEA, 0x66, 0x4B, 0xA0, 0xBD,
+ 0x86, 0x96, 0xA1, 0x1E, 0xAF, 0xE0, 0xD8, 0x8C, 0x72, 0x56, 0x0C, 0x5C, 0x47, 0x40, 0xA5, 0xAF, 0x05, 0x34, 0xD7, 0x00,
+ 0xF7, 0x05, 0xA9, 0x2F, 0x4C, 0x6D, 0xD3, 0x9F, 0x90, 0x06, 0x58, 0xA0, 0x32, 0x72, 0x00, 0x96, 0x63, 0x61, 0x67, 0x00,
+ 0xE0, 0x0E, 0xF6, 0x88, 0x85, 0x08, 0xBB, 0x85, 0x83, 0x08, 0x4B, 0x59, 0xB0, 0xAE, 0x84, 0xCC, 0xA2, 0x3A, 0x41, 0xEB,
+ 0x03, 0x21, 0x15, 0x02, 0xEB, 0xF4, 0x8B, 0x38, 0x08, 0x52, 0x33, 0xA1, 0xC5, 0x01, 0xCC, 0x61, 0xDF, 0x5B, 0x85, 0x60,
+ 0x06, 0xBB, 0xA6, 0xA5, 0xB3, 0x9E, 0xC6, 0x1E, 0xDE, 0x03, 0xEA, 0x60, 0x30, 0x15, 0x40, 0x37, 0x71, 0x0C, 0x7E, 0x30,
+ 0xF0, 0x6A, 0x0D, 0x5F, 0x21, 0x77, 0xF4, 0x2A, 0x6D, 0xCF, 0x69, 0xAC, 0xE0, 0x00, 0x19, 0xDE, 0x1E, 0x2C, 0xB6, 0xD4,
+ 0x7B, 0xCA, 0x52, 0xF8, 0x67, 0x41, 0xF9, 0x03, 0x11, 0xC2, 0x4A, 0xC9
+};
+const FX_BYTE g_zhHK_Locale[] = {
+ 0x78, 0x9C, 0xA5, 0x57, 0x4D, 0x4F, 0x13, 0x41, 0x18, 0x3E, 0x63, 0xE2, 0x7F, 0x98, 0x6C, 0x20, 0x0B, 0x09, 0x50, 0x8A,
+ 0x9F, 0x25, 0xCB, 0x26, 0x44, 0x90, 0x9A, 0x5A, 0x43, 0x2C, 0xD1, 0xC8, 0xC5, 0x6C, 0x77, 0x87, 0xEE, 0x42, 0x77, 0x87,
+ 0x4C, 0xB7, 0xC1, 0x6E, 0x3C, 0x88, 0x04, 0xA5, 0x5A, 0x2E, 0x4A, 0x54, 0x02, 0x86, 0x78, 0x50, 0x0F, 0x48, 0xBC, 0x78,
+ 0x68, 0x89, 0xC6, 0x3F, 0x43, 0x8B, 0x9E, 0xFC, 0x0B, 0xCE, 0xEC, 0x17, 0xFB, 0x35, 0x6D, 0x8D, 0x3D, 0xCD, 0xFB, 0xBC,
+ 0xCF, 0xF3, 0xCE, 0xFB, 0x3E, 0x33, 0x3B, 0x01, 0xA1, 0x8C, 0x64, 0xA9, 0x0C, 0x81, 0x21, 0xE9, 0x70, 0x9A, 0xB3, 0xD4,
+ 0x87, 0xD9, 0x1C, 0x07, 0x14, 0x58, 0x91, 0xA7, 0xB9, 0xD3, 0xE6, 0x71, 0xE7, 0xCD, 0xF3, 0xE1, 0xB3, 0xD6, 0xC6, 0xE9,
+ 0x8F, 0xD7, 0x7F, 0xBE, 0x37, 0x7E, 0x7F, 0xDA, 0xEB, 0x34, 0xBF, 0x9E, 0xD5, 0x5B, 0xED, 0xED, 0xA3, 0x5F, 0x1F, 0x1A,
+ 0x9D, 0xDD, 0x9F, 0xED, 0xC6, 0xC9, 0x08, 0x27, 0x5E, 0xBC, 0x00, 0x80, 0x40, 0x8B, 0x18, 0x8A, 0x84, 0x0B, 0x35, 0xBD,
+ 0x88, 0xCA, 0x15, 0xB7, 0x5E, 0x09, 0xC3, 0x12, 0xC2, 0x9A, 0x64, 0x50, 0xD6, 0x00, 0x10, 0x74, 0x64, 0x98, 0xEA, 0x1D,
+ 0x92, 0xAA, 0xD0, 0x78, 0xC0, 0x89, 0xC5, 0xD3, 0xE6, 0x93, 0xCE, 0xC1, 0xB6, 0x90, 0x72, 0xA2, 0x60, 0xE2, 0xA4, 0xC1,
+ 0x48, 0x34, 0xEB, 0xC9, 0x89, 0xF6, 0xFE, 0x3E, 0xAB, 0xD4, 0x2E, 0x43, 0xB1, 0x75, 0xCC, 0xDA, 0x63, 0x93, 0xA5, 0x38,
+ 0x62, 0x28, 0x5A, 0xEF, 0x19, 0x8A, 0x9D, 0x0D, 0x66, 0x82, 0x39, 0x3C, 0xCD, 0x45, 0xE7, 0x07, 0xEE, 0xDA, 0xB7, 0x30,
+ 0x68, 0x29, 0x90, 0x8A, 0x45, 0x3C, 0xCD, 0xA5, 0xB9, 0x60, 0x95, 0x74, 0x72, 0xF1, 0xC9, 0x64, 0xF8, 0x52, 0x32, 0x7C,
+ 0x39, 0x19, 0xBE, 0x92, 0x0C, 0x5F, 0x4D, 0x86, 0xAF, 0x25, 0xC3, 0xD7, 0x93, 0xE1, 0x4C, 0x32, 0x9C, 0x9E, 0x60, 0xE0,
+ 0x8C, 0x39, 0xD3, 0x93, 0x3D, 0x0D, 0x54, 0xA4, 0x5A, 0xE0, 0x46, 0x92, 0x48, 0xEC, 0xBC, 0x3B, 0xEC, 0x1C, 0x1C, 0x76,
+ 0xDE, 0x7E, 0x14, 0x52, 0x34, 0x8C, 0xE0, 0xE4, 0xC0, 0x92, 0xF1, 0x93, 0x06, 0x83, 0x5F, 0x4F, 0xC4, 0xC9, 0x55, 0x65,
+ 0xD4, 0xD9, 0x4D, 0xE6, 0x6F, 0x1D, 0xFB, 0x38, 0xB0, 0x57, 0x09, 0x43, 0x44, 0xEE, 0x80, 0xAD, 0x8E, 0xCD, 0x11, 0x9F,
+ 0x20, 0xDE, 0x7B, 0xBC, 0xEB, 0x78, 0xBF, 0xF1, 0x4E, 0xBB, 0xF6, 0xA8, 0x43, 0xAC, 0x29, 0x1A, 0xD4, 0x83, 0xDF, 0xBF,
+ 0x0B, 0x91, 0xED, 0x5E, 0xB4, 0x77, 0xE8, 0x41, 0x79, 0x40, 0x34, 0xFD, 0x32, 0x96, 0x06, 0xE7, 0x61, 0x60, 0x13, 0x88,
+ 0xA5, 0x40, 0x7D, 0x12, 0x91, 0x9E, 0xBE, 0xB4, 0xB7, 0x36, 0xDB, 0xF5, 0x1D, 0x21, 0x45, 0xC3, 0x08, 0xEE, 0x83, 0xC0,
+ 0x5E, 0x79, 0x5A, 0xF2, 0xA2, 0xA5, 0x22, 0x4F, 0x9A, 0x83, 0x2A, 0x92, 0x09, 0x17, 0x24, 0xD3, 0x84, 0xD8, 0xF0, 0xAD,
+ 0xF7, 0x11, 0xF7, 0xD5, 0x5B, 0xAE, 0x96, 0xCB, 0x9C, 0xF8, 0x80, 0xFC, 0xF8, 0x76, 0xEB, 0x1B, 0x9F, 0xE7, 0xC9, 0x1D,
+ 0xE4, 0x67, 0x79, 0x72, 0x10, 0x3C, 0x98, 0x23, 0x3F, 0x6A, 0x8C, 0xAF, 0x61, 0x15, 0x29, 0x23, 0xA3, 0xC4, 0x28, 0xD2,
+ 0x97, 0x5E, 0x87, 0xCA, 0xFF, 0xC8, 0x2B, 0x2A, 0xC2, 0x26, 0x2D, 0xD0, 0x53, 0x0E, 0x40, 0x08, 0x71, 0x7D, 0x32, 0x35,
+ 0x3D, 0xE2, 0x53, 0x00, 0x09, 0xF9, 0x34, 0xA3, 0xAA, 0x7C, 0x67, 0xEF, 0x29, 0x9F, 0xCF, 0xF3, 0xED, 0xED, 0x67, 0x7C,
+ 0xA1, 0xC0, 0x9F, 0x7D, 0x7E, 0xC5, 0x83, 0x25, 0x21, 0x15, 0x50, 0xB0, 0x4A, 0x38, 0x2E, 0x25, 0x97, 0xE8, 0xAB, 0x80,
+ 0x6D, 0x13, 0xD1, 0x4F, 0xE5, 0xF3, 0x53, 0x85, 0x42, 0x5F, 0x12, 0xD7, 0x9A, 0x19, 0xAA, 0x89, 0x0A, 0xA8, 0x19, 0x91,
+ 0xD1, 0xDD, 0x4B, 0xB3, 0x48, 0x50, 0xEF, 0x26, 0xCD, 0x4B, 0xC6, 0xCA, 0x6A, 0x56, 0xAF, 0x14, 0xE6, 0x66, 0x6F, 0xAE,
+ 0xDF, 0x7F, 0xA4, 0xE6, 0xAC, 0x25, 0xC7, 0xC3, 0x20, 0xC9, 0x56, 0x1A, 0x55, 0xBD, 0x08, 0x71, 0xD8, 0xC8, 0x10, 0xE6,
+ 0xF6, 0x44, 0x30, 0xF2, 0x2D, 0xC8, 0x9C, 0x68, 0x8D, 0x5A, 0x56, 0x66, 0xDC, 0xB2, 0x2C, 0x21, 0x15, 0xE2, 0xB1, 0xA5,
+ 0x72, 0x15, 0x63, 0x68, 0xC8, 0x35, 0x4E, 0x1C, 0x74, 0xC4, 0x99, 0xCC, 0xE3, 0x61, 0x7F, 0x39, 0xD2, 0x77, 0x9D, 0x35,
+ 0x88, 0x65, 0x68, 0x98, 0x6E, 0x0B, 0x43, 0x71, 0x1D, 0xF5, 0x26, 0x36, 0x8F, 0x3F, 0xE3, 0xF9, 0xD8, 0x03, 0x61, 0xC8,
+ 0x2D, 0xAF, 0x40, 0x59, 0xD3, 0x25, 0x72, 0x5F, 0xC6, 0xBD, 0x2A, 0x4E, 0x9A, 0x29, 0x28, 0x61, 0x54, 0x5D, 0xD3, 0xE8,
+ 0xF5, 0x18, 0xED, 0x53, 0xE1, 0x4F, 0x30, 0xD4, 0xA7, 0x40, 0xD7, 0x8C, 0x6A, 0x85, 0x13, 0xC7, 0xFA, 0xA4, 0x5B, 0x10,
+ 0x23, 0x4E, 0x9C, 0x88, 0xB1, 0xCF, 0x8D, 0x09, 0x9D, 0xBD, 0x77, 0x30, 0x21, 0x67, 0xC2, 0xA0, 0x77, 0x23, 0xED, 0x80,
+ 0x13, 0xB3, 0xB9, 0x41, 0xF2, 0x6C, 0x85, 0x18, 0x5D, 0x54, 0x5A, 0x05, 0xD1, 0x05, 0x95, 0xCD, 0xFE, 0x83, 0x2C, 0x78,
+ 0x10, 0x31, 0x91, 0xFD, 0x6E, 0xC6, 0xFA, 0xA6, 0xEF, 0x41, 0x6D, 0x0D, 0x2E, 0x4B, 0xB2, 0xF7, 0x4C, 0x7B, 0xA1, 0x5B,
+ 0x73, 0x46, 0x41, 0x45, 0x08, 0xF2, 0xE4, 0xB4, 0x40, 0xC1, 0x54, 0xC0, 0x6D, 0x2E, 0x95, 0x48, 0xCB, 0xD7, 0xC8, 0xDF,
+ 0x92, 0x0A, 0x58, 0x20, 0x36, 0x32, 0x08, 0x9A, 0xA1, 0x21, 0xA3, 0x0B, 0xE1, 0x06, 0xAA, 0x62, 0x0D, 0x62, 0xBA, 0x0B,
+ 0x83, 0xE1, 0xB4, 0xB2, 0xA0, 0xF5, 0xA4, 0x64, 0x61, 0x11, 0xC3, 0xF5, 0xAE, 0x94, 0x19, 0x2C, 0x15, 0xC9, 0x47, 0xD9,
+ 0x8D, 0xB2, 0xA8, 0x4A, 0x1A, 0x83, 0x90, 0x43, 0x56, 0x75, 0x55, 0x02, 0xF3, 0xC8, 0x54, 0x35, 0x99, 0xCE, 0x34, 0x76,
+ 0xEF, 0x16, 0xC8, 0x77, 0x27, 0x13, 0x03, 0x64, 0x15, 0x79, 0xE4, 0xBB, 0x5D, 0xB7, 0x2E, 0xA0, 0x1E, 0x76, 0xBB, 0xA7,
+ 0x52, 0xAB, 0x1A, 0xA5, 0x15, 0x64, 0x33, 0x9D, 0xDD, 0xED, 0x47, 0x2E, 0x70, 0x9E, 0x42, 0xCA, 0xF9, 0x27, 0x42, 0xFC,
+ 0x0B, 0xD9, 0x0E, 0x4B, 0xED
+};
+const FX_BYTE g_jaJP_Locale[] = {
+ 0x78, 0x9C, 0xED, 0x56, 0xCB, 0x6E, 0xD3, 0x40, 0x14, 0x5D, 0x17, 0x89, 0x7F, 0x18, 0x59, 0x20, 0x83, 0xD4, 0xD6, 0x0D,
+ 0xEF, 0x56, 0xAE, 0xA5, 0x8A, 0x96, 0x86, 0x16, 0xA3, 0x08, 0x57, 0xA0, 0x76, 0x83, 0x26, 0xF6, 0x34, 0x99, 0x36, 0x9E,
+ 0xA9, 0x26, 0xB6, 0x4A, 0xBC, 0xE2, 0x21, 0x20, 0x48, 0x74, 0x01, 0x1B, 0x04, 0x44, 0x62, 0x55, 0x40, 0x02, 0x04, 0x8B,
+ 0x6E, 0xD8, 0xD0, 0xAF, 0x49, 0x5A, 0x56, 0xFC, 0x02, 0x33, 0x7E, 0xC5, 0x8E, 0xED, 0xE0, 0xEE, 0xF1, 0x22, 0x99, 0x7B,
+ 0x7C, 0xCE, 0xF5, 0xBD, 0xE7, 0x8E, 0x47, 0x56, 0x5B, 0xD4, 0x84, 0x2D, 0x04, 0x08, 0xB4, 0xD1, 0xBC, 0xB4, 0x05, 0xEF,
+ 0xAF, 0xD4, 0x24, 0x60, 0xA1, 0xB6, 0x39, 0x2F, 0x0D, 0xDE, 0xEC, 0x1F, 0x7F, 0xFF, 0x76, 0x8E, 0xFF, 0x0D, 0x7A, 0x5F,
+ 0xCF, 0x4B, 0xDA, 0xE9, 0x53, 0x00, 0xA8, 0x82, 0x4C, 0x2C, 0xC8, 0x8C, 0x8E, 0x5D, 0xA7, 0xAD, 0x76, 0xA8, 0x6B, 0x30,
+ 0xD4, 0xA0, 0x0C, 0x43, 0x22, 0x58, 0x13, 0x40, 0xB5, 0x29, 0x71, 0x9A, 0xB7, 0xF9, 0xAD, 0xB6, 0x88, 0x27, 0x82, 0x58,
+ 0xAB, 0x0C, 0x7A, 0x5D, 0x55, 0x09, 0xD6, 0x09, 0xF8, 0x42, 0x3E, 0x7C, 0x31, 0x1F, 0xBE, 0x94, 0x0F, 0x5F, 0xCE, 0x87,
+ 0xAF, 0xE4, 0xC3, 0x57, 0xF3, 0xE1, 0x6B, 0xF9, 0xF0, 0x6C, 0x3E, 0x5C, 0x99, 0x29, 0xC0, 0x0B, 0xFA, 0xAC, 0x8C, 0x34,
+ 0x0A, 0xC2, 0x75, 0xEC, 0x53, 0xD2, 0x37, 0x00, 0xEB, 0x75, 0x36, 0x2F, 0x55, 0xA4, 0xFF, 0x06, 0x9E, 0xC4, 0x40, 0x0B,
+ 0x76, 0x12, 0xDB, 0x8E, 0x47, 0x9A, 0xD8, 0xBE, 0xEF, 0x7B, 0xFC, 0x57, 0x55, 0x44, 0x38, 0xC4, 0x7B, 0xDD, 0x5C, 0xFC,
+ 0xE8, 0xD1, 0x97, 0x7C, 0xFE, 0x8F, 0x83, 0x82, 0x3C, 0x9F, 0x73, 0xF1, 0xDF, 0xCF, 0x5F, 0xE5, 0xE2, 0xFD, 0xDE, 0x87,
+ 0x11, 0x1C, 0xF8, 0xAB, 0x9C, 0x26, 0x46, 0xF6, 0x40, 0xD8, 0x4D, 0xB6, 0x8F, 0x6C, 0x07, 0xD9, 0xDA, 0xB3, 0x55, 0x67,
+ 0xEB, 0xCD, 0x56, 0x5A, 0x5C, 0xA3, 0x8D, 0x18, 0xB6, 0x30, 0xB2, 0x93, 0x2F, 0x79, 0x08, 0x69, 0xFD, 0xBD, 0x6E, 0xFF,
+ 0xC5, 0x1E, 0x1F, 0x4E, 0x04, 0x64, 0x6F, 0xFF, 0x7A, 0x99, 0xBE, 0x0D, 0x86, 0x61, 0xE2, 0x21, 0x88, 0xC1, 0x44, 0x7E,
+ 0x1E, 0x69, 0x47, 0x07, 0x0F, 0xFB, 0x4F, 0x9F, 0xF8, 0xD9, 0x45, 0x18, 0xE3, 0xC7, 0xFB, 0x87, 0x83, 0x77, 0x1F, 0x63,
+ 0x10, 0xF8, 0xAB, 0x48, 0xCB, 0x8F, 0x2D, 0x65, 0xE4, 0xDC, 0x0A, 0x50, 0x0B, 0x3A, 0xA8, 0x06, 0x1D, 0x07, 0x31, 0x12,
+ 0x5B, 0x1F, 0x23, 0xE1, 0xD1, 0xB6, 0xE9, 0xB6, 0x5A, 0x92, 0xB6, 0xCE, 0x2F, 0xB9, 0xFF, 0xF3, 0x40, 0xD6, 0x65, 0x6E,
+ 0xB8, 0xBC, 0x28, 0xF3, 0x41, 0xC8, 0x4B, 0xFC, 0x12, 0xBE, 0xC4, 0x92, 0xA2, 0x1C, 0x2D, 0x4A, 0x1A, 0x05, 0x39, 0x4A,
+ 0xE9, 0x6D, 0x64, 0x05, 0x72, 0x45, 0xD7, 0x95, 0xC5, 0xC5, 0x52, 0x9A, 0x76, 0x93, 0x32, 0x47, 0xA8, 0xF2, 0x35, 0x00,
+ 0xA4, 0x90, 0xD0, 0x10, 0x07, 0xDB, 0x23, 0x86, 0x24, 0x90, 0x94, 0x21, 0x55, 0x79, 0xF0, 0xF6, 0xB1, 0xAC, 0xEB, 0x72,
+ 0xBF, 0xFB, 0x4C, 0x36, 0x0C, 0xF9, 0xE8, 0xD3, 0x6B, 0x79, 0x43, 0x55, 0x12, 0xF4, 0x22, 0x7D, 0x60, 0x46, 0x75, 0x4E,
+ 0xD7, 0xE7, 0x0C, 0x63, 0xAE, 0x9C, 0xC6, 0x37, 0x20, 0x94, 0x94, 0x12, 0x84, 0xDD, 0x0B, 0xC9, 0x28, 0x5F, 0x74, 0x3E,
+ 0xD2, 0x67, 0xB8, 0x15, 0xD6, 0x38, 0x1A, 0xED, 0x8F, 0x65, 0x48, 0xB6, 0xB6, 0xAB, 0x76, 0xDB, 0x58, 0x5A, 0xBC, 0xB1,
+ 0x7B, 0xEF, 0x41, 0x73, 0xD5, 0xDB, 0x08, 0x0C, 0x4B, 0x92, 0x7C, 0x25, 0x71, 0xED, 0x3A, 0x62, 0x69, 0xD7, 0x52, 0x58,
+ 0x58, 0x12, 0xC7, 0xF8, 0x0E, 0x37, 0x25, 0xCD, 0x9B, 0xF4, 0xBC, 0xD9, 0x69, 0xCF, 0xF3, 0x54, 0x25, 0xC5, 0x2B, 0x96,
+ 0x9A, 0x2E, 0x63, 0x88, 0x98, 0x1D, 0x49, 0x3B, 0xE3, 0x8B, 0x4B, 0x0B, 0x77, 0x10, 0x33, 0x11, 0x71, 0xC2, 0x67, 0x9E,
+ 0xCD, 0xEA, 0x84, 0x19, 0x99, 0x06, 0xE2, 0xA6, 0x86, 0x7D, 0x4E, 0xA4, 0xA1, 0x30, 0xBD, 0x85, 0x4C, 0x6C, 0x43, 0xBE,
+ 0x1B, 0xA6, 0xA3, 0x2C, 0xC1, 0xED, 0x42, 0x41, 0x83, 0x51, 0x77, 0x07, 0x8B, 0xF9, 0x4F, 0x96, 0x54, 0xC4, 0x1D, 0x9C,
+ 0x2D, 0x29, 0xB0, 0x31, 0x71, 0xDB, 0x92, 0x36, 0x55, 0x92, 0xEE, 0x21, 0x46, 0x25, 0x6D, 0x26, 0xC3, 0x1E, 0x1A, 0x93,
+ 0x1A, 0x76, 0x34, 0x89, 0x94, 0x33, 0x69, 0x30, 0xDA, 0x81, 0x7E, 0x20, 0x69, 0x7F, 0x0E, 0xF9, 0x89, 0x9D, 0x66, 0x8C,
+ 0x51, 0xE1, 0x36, 0x15, 0x0B, 0x49, 0x5B, 0xA9, 0xAD, 0x9F, 0x40, 0x96, 0x1C, 0x44, 0x46, 0xE4, 0x1F, 0x7F, 0x99, 0xBA,
+ 0xC5, 0xDB, 0xDE, 0xD9, 0x41, 0x9B, 0xD0, 0x8C, 0x4E, 0xDB, 0x28, 0x0C, 0x73, 0xAE, 0x52, 0xCF, 0xDD, 0x86, 0x60, 0x99,
+ 0x3A, 0x4D, 0x6C, 0x82, 0x1A, 0xA3, 0x53, 0x77, 0x6F, 0x02, 0x5D, 0x52, 0xC6, 0x91, 0x75, 0x4C, 0xCC, 0x26, 0x8D, 0xC8,
+ 0x77, 0x0A, 0xC8, 0x7A, 0x87, 0x7F, 0x2A, 0x5A, 0x82, 0x55, 0x44, 0xC0, 0x04, 0x53, 0x32, 0x86, 0x70, 0x9D, 0xBA, 0x0C,
+ 0x23, 0x06, 0x0C, 0xC7, 0x2A, 0x60, 0x2C, 0x58, 0xB4, 0x8E, 0x40, 0x0D, 0xFF, 0x93, 0x52, 0x45, 0x75, 0x86, 0x76, 0xC7,
+ 0x52, 0x16, 0x18, 0xAC, 0xF3, 0x17, 0x77, 0x1C, 0x65, 0xAD, 0x09, 0xF1, 0x58, 0x02, 0x6F, 0xA9, 0x21, 0x6A, 0x01, 0xB7,
+ 0xC6, 0xD2, 0x0C, 0x5A, 0x8A, 0xA6, 0x77, 0x5C, 0xD2, 0xD8, 0xA2, 0x3E, 0x33, 0x18, 0x89, 0x7F, 0xAA, 0x25, 0xE6, 0xA9,
+ 0x2A, 0xC1, 0x87, 0xBD, 0xF6, 0x17, 0x6C, 0x42, 0x08, 0x21
+};
+const FX_BYTE g_koKR_Locale[] = {
+ 0x78, 0x9C, 0xED, 0x56, 0x4D, 0x6B, 0xD4, 0x40, 0x18, 0x3E, 0x57, 0xF0, 0x3F, 0x0C, 0xC1, 0x12, 0x85, 0x76, 0xB7, 0xEB,
+ 0x77, 0x4B, 0x1A, 0x28, 0x6E, 0x6D, 0x65, 0x8D, 0x94, 0xA6, 0x58, 0xEC, 0x45, 0x66, 0x93, 0xE9, 0x26, 0xED, 0x26, 0x53,
+ 0x26, 0x09, 0x75, 0x73, 0xAE, 0x52, 0xF0, 0xE2, 0xA1, 0x87, 0xEA, 0x6E, 0xB1, 0x07, 0x11, 0x2A, 0x88, 0x22, 0x22, 0x1E,
+ 0x14, 0x7F, 0x8D, 0x62, 0x6D, 0x8A, 0x7F, 0xC1, 0xC9, 0xE7, 0xE6, 0x63, 0xB2, 0x4D, 0xEF, 0xEE, 0x61, 0x99, 0xF7, 0x99,
+ 0xE7, 0x79, 0xF3, 0xBE, 0xCF, 0x4C, 0x5E, 0x22, 0x74, 0xB1, 0x02, 0xBB, 0x08, 0x98, 0xD0, 0x40, 0xB3, 0xDC, 0x26, 0x7E,
+ 0xDC, 0x5A, 0xE6, 0x80, 0x8A, 0x2C, 0x65, 0x96, 0xFB, 0x35, 0x38, 0x38, 0xFE, 0x34, 0xF8, 0xFD, 0xE1, 0xFD, 0xE5, 0xE3,
+ 0xD7, 0x47, 0x3F, 0xFB, 0xDF, 0xAF, 0x70, 0xE2, 0xC5, 0x0B, 0x00, 0x08, 0x3E, 0xDF, 0x54, 0x21, 0x91, 0x7B, 0x46, 0x1B,
+ 0x77, 0xAD, 0x48, 0xDA, 0x21, 0xA8, 0x83, 0x89, 0x0E, 0x4D, 0x9F, 0x35, 0x06, 0x04, 0x03, 0x9B, 0xB6, 0xF6, 0x80, 0x6E,
+ 0x59, 0x7E, 0x3C, 0x16, 0xC6, 0x62, 0xC3, 0xEB, 0xEF, 0x09, 0xF5, 0x70, 0x9D, 0x82, 0xAF, 0xB2, 0xE1, 0x6B, 0x6C, 0xF8,
+ 0x3A, 0x1B, 0xBE, 0xC1, 0x86, 0x6F, 0xB2, 0xE1, 0x5B, 0x6C, 0xF8, 0x36, 0x1B, 0x9E, 0x66, 0xC3, 0x8D, 0xA9, 0x12, 0xBC,
+ 0xA4, 0xCF, 0x46, 0xAE, 0x51, 0x10, 0xAD, 0x13, 0x9F, 0xD2, 0xBE, 0x01, 0xD8, 0x6E, 0x93, 0x59, 0xAE, 0xC1, 0xFD, 0x37,
+ 0xF0, 0x3C, 0x06, 0xAA, 0xB0, 0x97, 0xBA, 0x76, 0x34, 0x12, 0xBD, 0x83, 0x6F, 0xDE, 0xAB, 0x3D, 0xFA, 0x2F, 0xD4, 0xFD,
+ 0x70, 0x88, 0xF7, 0xF7, 0x98, 0xF8, 0xE9, 0x4B, 0x36, 0xEE, 0xED, 0xEE, 0x33, 0xF1, 0x93, 0x77, 0x47, 0x4C, 0xFC, 0xCF,
+ 0xD7, 0x5D, 0x76, 0xFE, 0x67, 0x87, 0x39, 0x1C, 0x04, 0x2B, 0x46, 0x13, 0xB9, 0x3B, 0x10, 0x75, 0x53, 0xEC, 0xA3, 0xD8,
+ 0x41, 0xB1, 0xF6, 0x62, 0xD5, 0xC5, 0x7A, 0x8B, 0x95, 0x96, 0xD7, 0x68, 0x20, 0xA2, 0xAB, 0x3A, 0x32, 0xD2, 0x2F, 0x79,
+ 0x04, 0x89, 0xDE, 0xFE, 0x1B, 0xEF, 0x70, 0x87, 0x1E, 0x4E, 0x0C, 0x14, 0xB6, 0x4F, 0xFB, 0xB9, 0x6D, 0x30, 0x0C, 0x53,
+ 0x0F, 0x41, 0x04, 0xA6, 0xF2, 0xD3, 0x88, 0x56, 0xF9, 0xD1, 0xEB, 0xBF, 0x08, 0xB2, 0xFB, 0x61, 0x82, 0x7B, 0x3B, 0x03,
+ 0xBA, 0x95, 0x80, 0x20, 0x58, 0xC5, 0x5A, 0x3A, 0xB6, 0xEA, 0xB9, 0xB9, 0x15, 0xA2, 0x2A, 0xB4, 0xD1, 0x12, 0xB4, 0x6D,
+ 0x44, 0xCC, 0xC4, 0xFA, 0x04, 0x89, 0x46, 0xDB, 0xBA, 0xD3, 0xED, 0x72, 0xE2, 0x23, 0xFA, 0xE3, 0x4F, 0x9E, 0xEE, 0xF0,
+ 0x40, 0xE2, 0xA9, 0xE3, 0x3C, 0x68, 0xF2, 0xF4, 0x28, 0x78, 0x30, 0x4F, 0x7F, 0xBE, 0x35, 0x89, 0xAA, 0x2C, 0x4D, 0x17,
+ 0x9B, 0x9D, 0xD2, 0x34, 0x95, 0x32, 0x18, 0x48, 0x0D, 0x13, 0xD4, 0x80, 0x24, 0xD5, 0x40, 0xB3, 0x59, 0x49, 0x65, 0x69,
+ 0x98, 0xD8, 0xBE, 0xAE, 0x4C, 0x05, 0x40, 0x06, 0x89, 0x9C, 0xB1, 0x75, 0x23, 0xE7, 0x4C, 0x0A, 0xC9, 0x38, 0x33, 0x07,
+ 0x34, 0x8D, 0xF7, 0x9E, 0x0F, 0x68, 0x4B, 0x12, 0x7F, 0xF2, 0x85, 0xB6, 0x26, 0xCB, 0xBC, 0xF7, 0x79, 0x97, 0x07, 0x6B,
+ 0x42, 0x3D, 0x25, 0x2A, 0xCB, 0x12, 0x1A, 0x53, 0x9A, 0xA5, 0x52, 0x8E, 0xC0, 0x1A, 0x9A, 0x62, 0x46, 0x92, 0x66, 0x64,
+ 0xB9, 0x92, 0x24, 0xF2, 0x25, 0x14, 0xE5, 0x15, 0xBE, 0x27, 0x39, 0x07, 0xA2, 0xDB, 0xB2, 0x42, 0xD1, 0xF8, 0x0A, 0x2D,
+ 0x40, 0x73, 0x63, 0x73, 0xD1, 0xB0, 0xE4, 0xF9, 0xE6, 0xDD, 0xED, 0xD5, 0x27, 0x5A, 0xCB, 0x5D, 0x0B, 0xAD, 0x4C, 0x93,
+ 0x02, 0xA5, 0xE9, 0x18, 0x6D, 0x44, 0xB2, 0x7E, 0x66, 0xB0, 0xA8, 0x28, 0x8A, 0xD1, 0x97, 0x40, 0xE1, 0x44, 0x77, 0xC2,
+ 0x75, 0xA7, 0x6B, 0xAE, 0xEB, 0x0A, 0xF5, 0x0C, 0xAF, 0x5C, 0xAA, 0x38, 0x84, 0x20, 0x53, 0xE9, 0x71, 0xE2, 0xA5, 0x40,
+ 0x5C, 0x59, 0xB8, 0x85, 0x88, 0x82, 0x4C, 0x3B, 0x7A, 0xE6, 0x78, 0x51, 0xE7, 0x9B, 0x51, 0x68, 0x20, 0x69, 0x6A, 0xD8,
+ 0xE7, 0x58, 0x16, 0x8A, 0xD2, 0xAB, 0x48, 0xD1, 0x0D, 0x48, 0xEF, 0x49, 0x2D, 0xCE, 0x12, 0x6E, 0x97, 0x0A, 0x3A, 0x04,
+ 0x3B, 0x5B, 0xBA, 0x7F, 0x27, 0x26, 0x2A, 0x2A, 0x92, 0x0E, 0xC6, 0x2B, 0x0A, 0x0C, 0xDD, 0x74, 0x2C, 0x4E, 0x9C, 0xAC,
+ 0x48, 0x77, 0x11, 0xC1, 0x9C, 0x38, 0x55, 0x60, 0x0F, 0x8D, 0xC9, 0x1C, 0x76, 0x7C, 0x12, 0x19, 0x67, 0xB2, 0x60, 0x7C,
+ 0x07, 0x83, 0x80, 0x13, 0xFF, 0xFE, 0x78, 0x4B, 0x07, 0x54, 0x86, 0x31, 0x42, 0xA5, 0x5B, 0xD8, 0x5F, 0x70, 0x62, 0x6B,
+ 0x79, 0xF5, 0x1C, 0xB2, 0xF4, 0x41, 0x14, 0x44, 0xC1, 0x84, 0x2C, 0xD4, 0xED, 0xCF, 0x81, 0xDE, 0x16, 0x5A, 0x87, 0x4A,
+ 0x3C, 0x90, 0xE3, 0x30, 0xCA, 0x39, 0xA7, 0xE2, 0x36, 0x02, 0x52, 0xCF, 0x31, 0x3B, 0x1B, 0x18, 0xC8, 0xB6, 0x0A, 0x24,
+ 0xAE, 0xCE, 0x64, 0x4A, 0x3D, 0xFA, 0x75, 0xA8, 0x82, 0x25, 0xEA, 0x64, 0x09, 0x41, 0x37, 0x75, 0x6C, 0x8E, 0x20, 0xDC,
+ 0xC1, 0x0E, 0xD1, 0x11, 0xF1, 0x9F, 0x52, 0xC2, 0x08, 0xAB, 0x59, 0xD2, 0xCF, 0xA4, 0x2C, 0xA2, 0x36, 0x41, 0xDB, 0x23,
+ 0x29, 0x73, 0x04, 0xB6, 0xE9, 0x8B, 0x38, 0x8A, 0xB2, 0xA2, 0x41, 0xBD, 0x84, 0xD0, 0xC2, 0xAE, 0xB3, 0x09, 0xC1, 0x02,
+ 0xB6, 0x35, 0x5D, 0xF1, 0x7B, 0x9A, 0x7C, 0x78, 0xAF, 0xD4, 0x9A, 0x88, 0x4C, 0x0D, 0x50, 0x34, 0x1C, 0x93, 0x97, 0x47,
+ 0x3E, 0x9A, 0x72, 0x3B, 0x81, 0xDD, 0xF7, 0x47, 0xD2, 0x64, 0x9C, 0xA1, 0x05, 0x53, 0x2D, 0x75, 0x9E, 0x42, 0x3D, 0xFC,
+ 0xFC, 0x17, 0xFF, 0x01, 0xDC, 0xF1, 0x18, 0xD3
+};
+const FX_BYTE g_esES_Locale[] = {
+ 0x78, 0x9C, 0x9D, 0x56, 0xCF, 0x6B, 0xD4, 0x40, 0x14, 0xBE, 0x0B, 0xFE, 0x0F, 0x21, 0x58, 0x56, 0xA1, 0xDD, 0xD1, 0x63,
+ 0xCB, 0x36, 0x50, 0xDA, 0xDA, 0x95, 0x1A, 0x59, 0x9A, 0xAA, 0xD8, 0x8B, 0x4C, 0x92, 0xE9, 0xEE, 0xB4, 0xC9, 0xCC, 0x32,
+ 0x49, 0x2C, 0x9B, 0xA3, 0xE0, 0x41, 0x10, 0x0B, 0xDE, 0x8A, 0x27, 0x0F, 0x1E, 0x04, 0x8B, 0x77, 0x51, 0x3C, 0xF4, 0x3F,
+ 0x11, 0x6A, 0xEB, 0xC9, 0x7F, 0xC1, 0x37, 0x9B, 0x49, 0x36, 0x3F, 0x66, 0xD7, 0x60, 0x4E, 0xF3, 0xBE, 0xF7, 0x7D, 0x2F,
+ 0xEF, 0x7D, 0x93, 0x4C, 0xD2, 0x0B, 0xB8, 0x87, 0x03, 0x62, 0x30, 0x1C, 0x92, 0x75, 0x93, 0x44, 0xCF, 0xB7, 0x1D, 0xD3,
+ 0xF0, 0x49, 0xE4, 0xAD, 0x9B, 0xD7, 0x1F, 0x7F, 0x5C, 0x9D, 0x9E, 0x5F, 0xBD, 0x3E, 0xBB, 0xFE, 0x72, 0x7E, 0xBB, 0x08,
+ 0xFE, 0x7C, 0x7B, 0x73, 0xF9, 0xFE, 0xFB, 0xEF, 0xB3, 0x57, 0xBF, 0xDE, 0xBE, 0xBB, 0xFC, 0x7A, 0x7A, 0xC7, 0xB4, 0x7A,
+ 0xB2, 0x00, 0xF3, 0xB1, 0x70, 0x26, 0xA1, 0xCB, 0x83, 0x48, 0xD5, 0x1A, 0x0A, 0x32, 0xE4, 0x82, 0x62, 0x06, 0x8C, 0x90,
+ 0xB3, 0x78, 0xF4, 0x08, 0xE0, 0x48, 0xAD, 0x2D, 0xC2, 0x88, 0xE0, 0x3D, 0x94, 0x05, 0x37, 0x6F, 0x28, 0xF4, 0x90, 0xB8,
+ 0x42, 0x87, 0x87, 0x58, 0xA4, 0x4D, 0x14, 0xBB, 0x82, 0x06, 0x1A, 0xEE, 0xA4, 0x49, 0x3D, 0x4A, 0x18, 0xD5, 0xA1, 0x81,
+ 0x06, 0xC5, 0x43, 0x1E, 0xC5, 0x4D, 0x38, 0x22, 0xE3, 0x98, 0x92, 0x10, 0x1A, 0x6C, 0xA4, 0xB8, 0x17, 0x27, 0x3A, 0x9C,
+ 0xF1, 0x17, 0x73, 0x14, 0x3E, 0xF5, 0x1A, 0x19, 0x54, 0x72, 0x29, 0x27, 0x4E, 0x23, 0x03, 0xBB, 0xAE, 0x58, 0x37, 0xEF,
+ 0x99, 0x25, 0xF3, 0x74, 0xD6, 0xE9, 0x6C, 0xD3, 0x99, 0xA6, 0xB3, 0x4C, 0xE7, 0x98, 0xCE, 0x2F, 0x9D, 0x5B, 0x3A, 0xAB,
+ 0x74, 0x1E, 0xE9, 0xFC, 0xD1, 0x39, 0x33, 0xDF, 0x13, 0x1F, 0x4F, 0xD4, 0x53, 0x04, 0x2B, 0xCB, 0xE7, 0x21, 0x65, 0xF2,
+ 0xF6, 0x32, 0xC8, 0xB2, 0x56, 0x90, 0x30, 0x12, 0x55, 0x10, 0x30, 0x21, 0xAE, 0x43, 0xF4, 0xE2, 0x93, 0xF0, 0x78, 0x50,
+ 0x83, 0x8F, 0x12, 0xF2, 0xA2, 0x06, 0xC1, 0xFE, 0x89, 0x7A, 0xC1, 0xE8, 0xE2, 0x83, 0x8B, 0xFD, 0xD9, 0x6D, 0x51, 0xD1,
+ 0x55, 0xA9, 0xC3, 0xD2, 0x9E, 0xA9, 0x56, 0xEB, 0x6D, 0xD6, 0x9B, 0x6C, 0x74, 0x58, 0xEF, 0xAD, 0xDE, 0x58, 0xA3, 0x29,
+ 0x7D, 0x47, 0x21, 0x11, 0xD4, 0x87, 0x87, 0x2D, 0x7F, 0xFD, 0x54, 0x68, 0x6D, 0xD8, 0xE0, 0x6E, 0x1E, 0x94, 0x78, 0xD6,
+ 0xA0, 0x96, 0x40, 0xD5, 0x0A, 0x80, 0x10, 0x81, 0x55, 0x35, 0x58, 0x59, 0xB8, 0xBB, 0xD9, 0xED, 0x21, 0xB9, 0xCA, 0x52,
+ 0x96, 0x5F, 0x06, 0x50, 0x41, 0x96, 0x41, 0xED, 0xA8, 0xC8, 0xBA, 0x8F, 0xC9, 0x00, 0xC7, 0x31, 0x18, 0x3D, 0xDD, 0xD7,
+ 0x22, 0x52, 0xE7, 0xC8, 0x61, 0x12, 0x04, 0xA6, 0xB5, 0x0D, 0x97, 0xB1, 0xD5, 0x81, 0xA3, 0xC9, 0xE8, 0xD8, 0x70, 0x65,
+ 0xAB, 0x67, 0x70, 0xC9, 0x69, 0x0B, 0x4D, 0xAD, 0xA0, 0x2A, 0x11, 0x70, 0x36, 0x34, 0xAD, 0xFF, 0x55, 0x87, 0xC4, 0x07,
+ 0xF1, 0x16, 0xB2, 0x6D, 0xD4, 0x52, 0x11, 0x8D, 0xB8, 0x88, 0x67, 0x9A, 0x86, 0x02, 0x55, 0x66, 0x06, 0x20, 0xA6, 0x61,
+ 0xC9, 0x83, 0x52, 0x54, 0xF1, 0xA0, 0xDF, 0xEF, 0xF4, 0xA1, 0xFD, 0x0E, 0x5C, 0x0E, 0x9C, 0xD2, 0x07, 0x3D, 0x54, 0x62,
+ 0xD6, 0xCA, 0x54, 0x26, 0xEF, 0xF7, 0xD7, 0x6C, 0x7B, 0xCD, 0x71, 0x5A, 0x49, 0xA6, 0xE3, 0x2A, 0x41, 0x0B, 0xBA, 0x9A,
+ 0x55, 0x0A, 0x1A, 0x6C, 0x54, 0x99, 0x4B, 0x59, 0xB5, 0x0F, 0x58, 0xBE, 0xFD, 0x3B, 0x89, 0x1D, 0x1F, 0x8F, 0xC2, 0xC8,
+ 0xD9, 0xDE, 0xBA, 0x7F, 0xF2, 0x14, 0x8F, 0x76, 0xD3, 0x83, 0xCC, 0x9C, 0x32, 0x09, 0x74, 0x2C, 0x09, 0x5D, 0x22, 0x66,
+ 0x0E, 0x55, 0x62, 0xD5, 0x08, 0x60, 0xF0, 0x9C, 0x7A, 0xA6, 0x95, 0x2E, 0xA7, 0xE9, 0x6A, 0x37, 0x4D, 0xD3, 0x1E, 0xAA,
+ 0xF0, 0x1A, 0x85, 0x94, 0xD0, 0x4B, 0x84, 0x20, 0xCC, 0x9B, 0xE4, 0xCA, 0xD5, 0x55, 0xE3, 0x56, 0x4B, 0xE9, 0x98, 0x08,
+ 0x8F, 0xB0, 0x58, 0x29, 0x97, 0x34, 0x2A, 0x54, 0x6B, 0xBD, 0x28, 0x94, 0x4F, 0x57, 0x09, 0x55, 0x59, 0x9F, 0x78, 0x34,
+ 0xC4, 0xB0, 0xE3, 0xCB, 0xB9, 0x3E, 0x4B, 0xD7, 0xD5, 0xC5, 0x97, 0x96, 0x27, 0x63, 0x2A, 0x37, 0xBA, 0xDB, 0x8A, 0x5F,
+ 0x74, 0xBD, 0xD4, 0x8A, 0x0E, 0x87, 0x6C, 0x12, 0x99, 0xD6, 0x4A, 0x2B, 0x72, 0x0A, 0x9F, 0x6F, 0xD3, 0xBA, 0xDB, 0xE4,
+ 0xA2, 0xEA, 0xD8, 0x80, 0xE4, 0xBE, 0x17, 0x4E, 0x54, 0x81, 0xFC, 0xF9, 0x9A, 0x06, 0xA6, 0xF5, 0xF3, 0xE5, 0x67, 0x38,
+ 0x3E, 0x2A, 0x8C, 0x66, 0x11, 0xA5, 0xA1, 0x11, 0x97, 0x0B, 0x38, 0x35, 0x1E, 0xEF, 0xB5, 0x16, 0x95, 0x4D, 0x6F, 0x4A,
+ 0x50, 0xBD, 0x5B, 0xF9, 0x32, 0x4C, 0xC6, 0xE4, 0x10, 0x7B, 0xF2, 0x1C, 0xCC, 0x97, 0xAA, 0x96, 0x3D, 0x81, 0x1F, 0x1F,
+ 0xDF, 0x18, 0x80, 0x17, 0xA8, 0xCC, 0xCC, 0xD3, 0x14, 0xFE, 0x46, 0xD8, 0xDC, 0xF4, 0x26, 0x4F, 0x04, 0x7C, 0x77, 0x0C,
+ 0x27, 0xF6, 0xB5, 0xF9, 0x0D, 0x9F, 0xBB, 0xC4, 0x18, 0xD0, 0x7F, 0x10, 0xFA, 0xF2, 0x67, 0xEA, 0x64, 0x01, 0x61, 0x43,
+ 0x60, 0x17, 0x5E, 0x98, 0xF9, 0x84, 0xFD, 0x11, 0xA6, 0xDA, 0xF4, 0x2E, 0x4F, 0x93, 0x63, 0x6C, 0xEC, 0xF0, 0x78, 0x44,
+ 0x3D, 0x39, 0xC7, 0xCA, 0x93, 0x07, 0x86, 0xBD, 0x88, 0x0A, 0x23, 0x7B, 0x23, 0x9E, 0x53, 0xF7, 0x16, 0xDC, 0x14, 0x98,
+ 0x43, 0x39, 0x99, 0xF1, 0x70, 0x01, 0xC9, 0xE1, 0x2D, 0x48, 0xF6, 0x24, 0x61, 0xC3, 0x23, 0x3E, 0xE5, 0xA9, 0xE6, 0xD0,
+ 0x6C, 0xCF, 0x64, 0x94, 0xFD, 0xFC, 0xC2, 0xF2, 0x2F, 0x7C, 0xDC, 0xCC, 0x2F,
+};
+const FX_BYTE g_esLA_Locale[] = {
+ 0x78, 0x9C, 0x9D, 0x56, 0xCD, 0x4E, 0xDC, 0x30, 0x10, 0x3E, 0x53, 0xA9, 0xEF, 0x60, 0x45, 0x45, 0x80, 0x04, 0x9B, 0xF6,
+ 0xB8, 0x28, 0x44, 0x5A, 0x01, 0xA5, 0x15, 0x0D, 0x5A, 0x75, 0x51, 0x4B, 0xB9, 0x54, 0x4E, 0x62, 0x36, 0x86, 0xC4, 0x5E,
+ 0x39, 0x09, 0x68, 0xA3, 0xBE, 0x40, 0x4F, 0x3D, 0xF4, 0xD4, 0x63, 0x2B, 0x21, 0xB5, 0x07, 0xD4, 0x47, 0xE8, 0x81, 0x67,
+ 0x41, 0xF0, 0x18, 0x9D, 0xFC, 0x6E, 0x12, 0x3B, 0xE9, 0xD2, 0x9C, 0x3C, 0xDF, 0x7C, 0x9F, 0x77, 0xE6, 0xB3, 0x33, 0x1B,
+ 0xC3, 0xE7, 0x0E, 0xF6, 0x09, 0x62, 0x38, 0x20, 0x3B, 0x1A, 0x09, 0x3F, 0x5A, 0x27, 0x1A, 0x72, 0x49, 0xE8, 0xEC, 0x68,
+ 0x0F, 0xD7, 0x7F, 0xEE, 0xBF, 0xDC, 0xDC, 0x7F, 0xFE, 0xF6, 0xF0, 0xFB, 0x66, 0xFD, 0xEE, 0xC7, 0x4F, 0x88, 0xEF, 0xBE,
+ 0x5E, 0x6F, 0x68, 0xE6, 0xD3, 0x27, 0x08, 0x19, 0xA9, 0x8A, 0xB9, 0x58, 0x4C, 0xE6, 0x81, 0xCD, 0xFD, 0xB0, 0xD8, 0x60,
+ 0x2A, 0xC8, 0x94, 0x0B, 0x8A, 0x59, 0xCA, 0x5A, 0x41, 0x46, 0xC0, 0x59, 0xE4, 0x1D, 0x41, 0x2A, 0x4C, 0xE3, 0x95, 0x3C,
+ 0x36, 0x09, 0x23, 0x82, 0x1B, 0x7A, 0x1E, 0xD4, 0xF0, 0x33, 0x62, 0x0B, 0x75, 0x26, 0xC0, 0x22, 0x51, 0xE1, 0xD8, 0x16,
+ 0xD4, 0x57, 0xF2, 0xE7, 0x2A, 0xFA, 0x79, 0xCC, 0xA8, 0x1A, 0xF7, 0x95, 0x38, 0x9E, 0xF2, 0x30, 0x52, 0x25, 0x42, 0x32,
+ 0x8B, 0x28, 0x09, 0xA0, 0x5C, 0x45, 0x92, 0x3B, 0x51, 0xAC, 0xCE, 0x30, 0x7E, 0xD9, 0xA9, 0x72, 0xA9, 0x23, 0xE5, 0x50,
+ 0xB1, 0xAE, 0x1C, 0xAC, 0x3B, 0x8A, 0xB0, 0x6D, 0x8B, 0x1D, 0xED, 0x85, 0xD6, 0xB2, 0x56, 0x6D, 0xAC, 0xDA, 0x54, 0xB5,
+ 0xA5, 0x6A, 0x43, 0xD5, 0x7E, 0xAA, 0xDD, 0x54, 0x7B, 0xA9, 0x36, 0x52, 0xED, 0xA0, 0xDA, 0x3D, 0xB5, 0x6F, 0xFD, 0x8E,
+ 0xB9, 0x78, 0x5E, 0xBB, 0x81, 0x10, 0x99, 0x2E, 0x0F, 0x28, 0x4B, 0xCB, 0x49, 0x83, 0x0A, 0xF5, 0x63, 0x46, 0xC2, 0x16,
+ 0x06, 0x16, 0x45, 0x32, 0x48, 0x6F, 0x7F, 0x09, 0x87, 0xFB, 0x52, 0xE2, 0x3C, 0x26, 0x97, 0x12, 0x08, 0x27, 0x2E, 0xE4,
+ 0x8D, 0xC3, 0xDB, 0xEF, 0x36, 0x76, 0x17, 0x25, 0xA0, 0x6C, 0xA5, 0xA8, 0xBA, 0x75, 0xCA, 0x45, 0xF9, 0x72, 0xE9, 0x72,
+ 0xE1, 0x8A, 0xAA, 0xE5, 0x7A, 0xE5, 0x62, 0x15, 0x85, 0x76, 0x57, 0x19, 0x10, 0x41, 0x5D, 0xB8, 0xB6, 0xF5, 0x57, 0xBC,
+ 0x80, 0xCC, 0x91, 0x05, 0x67, 0x51, 0x06, 0xCD, 0xD4, 0xB8, 0x95, 0x42, 0x8B, 0xB0, 0xB6, 0x39, 0x11, 0xB8, 0xB6, 0x2F,
+ 0x44, 0x26, 0x1E, 0xEC, 0x0E, 0x0C, 0x3D, 0x5D, 0x55, 0x90, 0x5B, 0x87, 0x50, 0xB6, 0x2A, 0x45, 0x30, 0xA5, 0xF4, 0xD6,
+ 0x98, 0xCA, 0x51, 0x17, 0x47, 0x64, 0x8C, 0xA3, 0x08, 0x0E, 0xA6, 0x72, 0xBB, 0x42, 0x8A, 0x49, 0x76, 0x16, 0xFB, 0xBE,
+ 0x66, 0xEE, 0xC3, 0x83, 0xF6, 0xD6, 0x60, 0x22, 0xA2, 0x35, 0x0B, 0x9E, 0x7C, 0xF5, 0x01, 0x9E, 0xD4, 0x89, 0x4A, 0xD3,
+ 0xB5, 0x89, 0xCF, 0xD9, 0x54, 0x33, 0xFF, 0x5F, 0x1F, 0x10, 0x17, 0xE4, 0x7B, 0xBA, 0x65, 0xE9, 0x4B, 0x6B, 0x42, 0x8F,
+ 0x8B, 0x68, 0xA1, 0x6A, 0x6B, 0x10, 0x6A, 0x20, 0x85, 0x23, 0x11, 0x0D, 0x5A, 0x8E, 0xD4, 0x90, 0x86, 0x23, 0x9E, 0xB7,
+ 0x6D, 0x59, 0xDB, 0x93, 0x09, 0x1A, 0xA1, 0x53, 0x43, 0xAF, 0xB1, 0xBA, 0x64, 0xB9, 0x07, 0x8F, 0x96, 0x65, 0xAD, 0x2F,
+ 0x54, 0x4B, 0x69, 0x8A, 0xD6, 0x33, 0x95, 0x2C, 0x49, 0x3B, 0x6F, 0xF5, 0x59, 0xDC, 0x85, 0x63, 0x40, 0xCB, 0x0B, 0x72,
+ 0x10, 0x5B, 0xD1, 0x85, 0x17, 0x84, 0x93, 0xFD, 0xBD, 0x97, 0x57, 0xEF, 0xB1, 0x77, 0x98, 0x9C, 0xE6, 0x86, 0xD5, 0x49,
+ 0x99, 0x92, 0xC5, 0x81, 0x4D, 0x44, 0xD3, 0xB5, 0x06, 0x56, 0x54, 0x05, 0x18, 0xDC, 0x6D, 0x47, 0x33, 0x93, 0xCD, 0x24,
+ 0x19, 0x0E, 0x92, 0x24, 0x31, 0xF4, 0x06, 0xAF, 0x5B, 0xEA, 0xC4, 0x42, 0x10, 0xE6, 0xCC, 0x35, 0xF3, 0x59, 0x2E, 0x1E,
+ 0x0E, 0x3F, 0xAD, 0x57, 0xCB, 0x8D, 0xA5, 0xF7, 0x99, 0x11, 0xE1, 0x10, 0x16, 0x15, 0x25, 0xAC, 0xCA, 0xBA, 0xD4, 0x1B,
+ 0xA9, 0x9F, 0xAA, 0xC7, 0x45, 0xDB, 0x2B, 0x4D, 0xA8, 0xD8, 0xDE, 0x25, 0x0E, 0x0D, 0x30, 0x5C, 0x8E, 0x41, 0xB9, 0x4B,
+ 0x9E, 0xEE, 0x14, 0x4C, 0x05, 0x8F, 0x67, 0x34, 0xBD, 0x17, 0x9B, 0x4B, 0x2A, 0xAA, 0x0E, 0x56, 0x97, 0x14, 0xC0, 0x84,
+ 0x8F, 0x43, 0xCD, 0xDC, 0x5A, 0x92, 0x9E, 0xC0, 0x77, 0x87, 0x66, 0x3E, 0x97, 0xD8, 0x0B, 0x63, 0x1A, 0x67, 0x5F, 0x1E,
+ 0x4C, 0xC3, 0x99, 0x26, 0x58, 0xDE, 0xC9, 0x2C, 0x80, 0x03, 0x84, 0x59, 0xD4, 0xC8, 0xF7, 0x68, 0x68, 0xC8, 0xD3, 0x85,
+ 0x66, 0x5A, 0x27, 0x47, 0x8F, 0x90, 0xD5, 0x8F, 0x41, 0x12, 0x65, 0xC3, 0x50, 0xAA, 0x3A, 0x7D, 0xF5, 0xE7, 0x33, 0x72,
+ 0x86, 0x9D, 0x72, 0xE8, 0x96, 0x61, 0xB1, 0xA7, 0x35, 0x87, 0xAF, 0x39, 0x17, 0x8D, 0xC1, 0x1D, 0x5D, 0x4D, 0xA0, 0xF0,
+ 0x49, 0xC5, 0x7A, 0x08, 0xBB, 0x3C, 0x16, 0xF0, 0x17, 0x88, 0x26, 0x91, 0xDB, 0xC1, 0x18, 0xB9, 0xDC, 0x26, 0x68, 0x4C,
+ 0xFF, 0x49, 0x79, 0x95, 0x7E, 0x1F, 0x5E, 0xF5, 0x52, 0x46, 0x02, 0xDB, 0xF0, 0xAE, 0xF5, 0x51, 0x8E, 0x3D, 0x4C, 0x3B,
+ 0x08, 0x87, 0x3C, 0x89, 0x2F, 0x30, 0x3A, 0xE0, 0x91, 0x47, 0x9D, 0xB4, 0xA7, 0xAD, 0x77, 0xAF, 0x91, 0xD5, 0x4F, 0x06,
+ 0x03, 0x1C, 0x8F, 0x97, 0xE4, 0xB7, 0xBD, 0x3F, 0x0D, 0xDC, 0x69, 0xDA, 0x25, 0x7A, 0xD3, 0x4B, 0x9B, 0xF0, 0xA5, 0x68,
+ 0xD6, 0x3C, 0x66, 0xD3, 0x73, 0x9E, 0x31, 0xF3, 0x22, 0xB3, 0x11, 0x57, 0x3B, 0x4F, 0x43, 0xCF, 0x3F, 0xEF, 0xCD, 0xBF,
+ 0xC4, 0xB5, 0xD4, 0x04
+};
+const FX_BYTE g_deDE_Loacale[] = {
+ 0x78, 0x9C, 0x95, 0x56, 0x4D, 0x6F, 0xD4, 0x30, 0x10, 0xBD, 0x23, 0xF1, 0x1F, 0xAC, 0x88, 0xAA, 0x20, 0xB5, 0x1B, 0x38,
+ 0xB6, 0xDA, 0x46, 0x5A, 0x75, 0xFB, 0x41, 0x4B, 0xCA, 0xAA, 0x69, 0x41, 0xF4, 0x82, 0xBC, 0x89, 0xBB, 0x71, 0x9B, 0xD8,
+ 0x2B, 0xC7, 0x69, 0xB5, 0x39, 0xF2, 0x37, 0xB8, 0x72, 0x04, 0x71, 0xE4, 0x04, 0x17, 0xFE, 0x09, 0x52, 0x25, 0x7E, 0x06,
+ 0x93, 0x8D, 0x93, 0x26, 0xB6, 0xBB, 0x0D, 0xB9, 0xAC, 0xE7, 0xCD, 0x7B, 0xB3, 0x33, 0xCF, 0x89, 0x93, 0x61, 0xC2, 0x43,
+ 0x9C, 0x10, 0xC4, 0x70, 0x4A, 0x76, 0x9C, 0x88, 0x7C, 0x1C, 0xEF, 0x39, 0x28, 0x22, 0x59, 0xB8, 0xE3, 0xDC, 0xFD, 0xFA,
+ 0xF1, 0xF7, 0xFB, 0xB7, 0xE7, 0xF0, 0x73, 0xF7, 0xF9, 0xE7, 0x0B, 0xC7, 0x1B, 0x96, 0x44, 0x16, 0x61, 0x11, 0x2C, 0xD2,
+ 0x29, 0x4F, 0x32, 0xA5, 0x99, 0x09, 0x32, 0xE3, 0x82, 0x62, 0x06, 0x8C, 0x94, 0x33, 0x19, 0x9F, 0x00, 0x9C, 0xA9, 0xB5,
+ 0x77, 0x84, 0x59, 0x8E, 0xC5, 0xD0, 0xAD, 0xA2, 0xA7, 0x4F, 0x14, 0xBC, 0x4F, 0xA6, 0xC2, 0x86, 0xFB, 0xBF, 0xBF, 0x88,
+ 0xC2, 0x40, 0x47, 0x73, 0x41, 0x13, 0x93, 0x8B, 0xA9, 0x81, 0x1D, 0xE5, 0xCC, 0x06, 0x26, 0x26, 0x38, 0xCA, 0x67, 0x79,
+ 0x26, 0x0D, 0x38, 0x20, 0x73, 0x49, 0xD2, 0x29, 0x31, 0x5B, 0x7B, 0x7B, 0x2D, 0xB9, 0x0D, 0x3F, 0xE1, 0x37, 0x76, 0xC1,
+ 0x98, 0x14, 0x7A, 0xC2, 0x6D, 0x19, 0x54, 0xF3, 0x96, 0x11, 0xC2, 0xD3, 0xA9, 0xD8, 0x71, 0x5E, 0x39, 0x2D, 0xDF, 0x6C,
+ 0xA6, 0x99, 0x26, 0xD8, 0xED, 0xEA, 0x6B, 0x96, 0xCD, 0x2B, 0x9B, 0x55, 0x36, 0x9F, 0x6C, 0x0E, 0xD9, 0xDC, 0xB1, 0x19,
+ 0xF3, 0xB0, 0x27, 0x11, 0x5E, 0xA8, 0x1B, 0x08, 0x56, 0x5E, 0xC0, 0x19, 0x93, 0x18, 0xFE, 0xBE, 0x0C, 0xAA, 0xAC, 0xE7,
+ 0x73, 0x03, 0x1A, 0x53, 0xC2, 0x32, 0x83, 0x47, 0xA5, 0xBC, 0xE5, 0x61, 0xDC, 0x65, 0x42, 0x41, 0x22, 0x0C, 0xEE, 0xBE,
+ 0x20, 0x54, 0xC7, 0x02, 0x9C, 0x76, 0x78, 0x6E, 0xD3, 0x5A, 0xAB, 0xCD, 0xD6, 0xC6, 0x55, 0xFD, 0x6A, 0xAD, 0x6A, 0x6D,
+ 0x6A, 0x0D, 0x6A, 0xAD, 0x69, 0x2D, 0x69, 0xDD, 0xD8, 0x1B, 0x49, 0x89, 0xA0, 0x11, 0x25, 0x69, 0xFD, 0xD4, 0xA9, 0xD0,
+ 0x1B, 0xF9, 0xE0, 0x6C, 0x1D, 0xB4, 0x78, 0xDE, 0x44, 0x4B, 0xB8, 0xDD, 0x0A, 0x80, 0x10, 0x81, 0x55, 0x35, 0x58, 0x79,
+ 0x37, 0x03, 0xB4, 0x1B, 0x8B, 0xC1, 0xD0, 0x2D, 0x83, 0x2A, 0xEB, 0x31, 0x0D, 0x73, 0x1B, 0x49, 0x19, 0x68, 0xE7, 0x44,
+ 0x35, 0x81, 0x24, 0x13, 0x2C, 0x25, 0x11, 0x6C, 0xB9, 0xB3, 0x4D, 0xA4, 0x0E, 0x91, 0xCB, 0x3C, 0x49, 0x1C, 0x6F, 0x0F,
+ 0xAE, 0x0D, 0x34, 0x1E, 0x20, 0x1F, 0x2E, 0xF4, 0x01, 0xAE, 0x72, 0xD6, 0x86, 0xAB, 0x15, 0x52, 0xD2, 0x84, 0xB3, 0x99,
+ 0xE3, 0xFD, 0xA7, 0x28, 0x25, 0x11, 0x68, 0xC6, 0x03, 0xDF, 0x1F, 0xF4, 0x54, 0x64, 0x31, 0x17, 0xF2, 0x5E, 0x63, 0x28,
+ 0xDC, 0xCE, 0x88, 0x00, 0x48, 0x9A, 0xB6, 0x46, 0x6E, 0x45, 0x9D, 0x91, 0x0F, 0xB7, 0x7D, 0x7F, 0x1D, 0x9D, 0xC7, 0x02,
+ 0xAD, 0x5F, 0x0C, 0xDD, 0x16, 0x4B, 0x2B, 0xD1, 0x19, 0xF6, 0xB0, 0x54, 0x6D, 0x07, 0x01, 0xEA, 0x23, 0x59, 0x8E, 0x5A,
+ 0x2B, 0x7A, 0xF0, 0xD5, 0xA0, 0x4B, 0x85, 0x41, 0x77, 0x3B, 0x53, 0x29, 0xA3, 0xCE, 0x00, 0xAB, 0xF7, 0xFA, 0xE0, 0xCA,
+ 0x97, 0xD7, 0x87, 0x69, 0x16, 0xEC, 0x8D, 0xF7, 0x6F, 0xDF, 0xE3, 0xF8, 0xB8, 0xB8, 0xA8, 0xAC, 0x69, 0x93, 0x40, 0xC7,
+ 0xF2, 0xF2, 0x68, 0xBC, 0xF7, 0xA7, 0x13, 0xAB, 0x4E, 0x00, 0x83, 0x5B, 0x33, 0x74, 0xBC, 0x62, 0xA3, 0x28, 0xB6, 0x06,
+ 0x45, 0x01, 0xC7, 0x46, 0x87, 0x67, 0x14, 0x52, 0xC2, 0x30, 0x17, 0x82, 0xB0, 0x70, 0x51, 0x2B, 0xB7, 0xB6, 0xD0, 0xB3,
+ 0x9E, 0xD2, 0x39, 0x11, 0x21, 0x61, 0x52, 0x29, 0xD7, 0x2C, 0x2A, 0x57, 0x6B, 0xBD, 0x29, 0x54, 0x4F, 0xD7, 0x09, 0x9B,
+ 0x17, 0x6B, 0x48, 0x53, 0x0C, 0xFB, 0xBD, 0x51, 0xEB, 0xAB, 0xB4, 0xAE, 0x6E, 0xDE, 0xA9, 0x3C, 0x9F, 0xD3, 0x72, 0xAB,
+ 0x07, 0xBD, 0xF8, 0x4D, 0xD7, 0x6B, 0xBD, 0xE8, 0x29, 0x65, 0x79, 0xE6, 0x78, 0x9B, 0xBD, 0xC8, 0x05, 0x11, 0xDC, 0xF1,
+ 0x5E, 0x9A, 0x5C, 0xB7, 0x3B, 0x36, 0x20, 0xB5, 0xEF, 0x8D, 0x13, 0x5D, 0xA0, 0xBE, 0xC1, 0x96, 0x81, 0xE3, 0xFD, 0xF9,
+ 0xF4, 0x15, 0xCE, 0x8A, 0x0E, 0xC3, 0x2C, 0xA2, 0x34, 0x34, 0xE3, 0xE5, 0x02, 0x8E, 0x88, 0xF3, 0xD3, 0xDE, 0xA2, 0xB6,
+ 0xE9, 0xA6, 0xC4, 0xD5, 0xBB, 0x2D, 0x9F, 0x86, 0xC5, 0x9C, 0x5C, 0xE2, 0xB0, 0x3C, 0xFA, 0xEA, 0xA5, 0xAA, 0xE5, 0x2F,
+ 0xE0, 0x13, 0x27, 0x42, 0x13, 0xF0, 0xC2, 0x6D, 0x33, 0xEB, 0x34, 0x65, 0x94, 0xB3, 0x07, 0xD3, 0xBB, 0x3C, 0x17, 0x94,
+ 0x08, 0x14, 0xC8, 0xC8, 0x9A, 0x1F, 0x45, 0xF0, 0x69, 0x81, 0x26, 0xF4, 0x11, 0xC2, 0x21, 0x7C, 0x35, 0x91, 0xDB, 0x15,
+ 0x84, 0x91, 0xC0, 0x53, 0x78, 0x60, 0x1E, 0x26, 0x9C, 0xC5, 0x98, 0x5A, 0xD3, 0xC7, 0xBC, 0xC8, 0xAF, 0x31, 0x3A, 0xE0,
+ 0x32, 0xA6, 0x61, 0x39, 0xC7, 0xE6, 0xBB, 0xD7, 0xC8, 0x5F, 0x45, 0x85, 0x91, 0xC3, 0x98, 0xD7, 0xD4, 0xD3, 0x15, 0x7F,
+ 0x0A, 0xCC, 0x59, 0x39, 0x19, 0x7A, 0xB3, 0x82, 0x04, 0x6F, 0xFA, 0xC7, 0x49, 0xFE, 0x22, 0x67, 0xB3, 0x2B, 0xBE, 0xE4,
+ 0xA9, 0xE6, 0xDC, 0xFB, 0x3D, 0x2B, 0xA3, 0xEA, 0x73, 0x16, 0x96, 0xFF, 0x00, 0x29, 0x27, 0xAF, 0x17,
+};
+const FX_BYTE g_frFR_Locale[] = {
+ 0x78, 0x9C, 0x95, 0x56, 0x4D, 0x6F, 0xD3, 0x40, 0x10, 0xBD, 0x23, 0xF1, 0x1F, 0x56, 0x16, 0x55, 0x41, 0x6A, 0xBD, 0x70,
+ 0x4C, 0x95, 0x5A, 0xAA, 0xFA, 0x15, 0x28, 0x46, 0x51, 0x53, 0x40, 0xF4, 0x82, 0x36, 0xF6, 0x36, 0xDE, 0xD4, 0xDE, 0x8D,
+ 0xD6, 0x76, 0x4A, 0x7C, 0xE4, 0x3F, 0x70, 0xE2, 0xC2, 0xB5, 0x12, 0x88, 0x03, 0x47, 0xC4, 0x85, 0xFE, 0x13, 0x24, 0x10,
+ 0x3F, 0x83, 0x71, 0xBC, 0x76, 0xED, 0x5D, 0x27, 0xB8, 0xBE, 0x64, 0xE7, 0xCD, 0x7B, 0xE3, 0x99, 0xB7, 0xF6, 0xC6, 0xFD,
+ 0x50, 0x78, 0x24, 0xA4, 0x88, 0x93, 0x88, 0xEE, 0x5A, 0x17, 0xF2, 0xED, 0xD1, 0xA9, 0x85, 0x7C, 0x1A, 0x7B, 0xBB, 0xD6,
+ 0x9F, 0x6F, 0x1F, 0xFE, 0x7E, 0xFD, 0xF2, 0x10, 0x7E, 0x7E, 0x7F, 0xFC, 0xF1, 0xC8, 0x72, 0xFA, 0x39, 0x91, 0xFB, 0x44,
+ 0x8E, 0x16, 0xD1, 0x58, 0x84, 0xB1, 0xD2, 0x4C, 0x24, 0x9D, 0x08, 0xC9, 0x08, 0x07, 0x46, 0x24, 0x78, 0x12, 0xBC, 0x00,
+ 0x38, 0x56, 0x6B, 0x67, 0x4A, 0xF8, 0x9C, 0x51, 0xD9, 0xC7, 0x45, 0x78, 0xFF, 0x9E, 0xC2, 0x2F, 0x6E, 0xAE, 0xE7, 0xB2,
+ 0x2D, 0x11, 0x11, 0x19, 0x1B, 0x20, 0x01, 0x6E, 0xD8, 0x42, 0x65, 0x06, 0x36, 0x4D, 0x19, 0x6F, 0x03, 0xC3, 0x90, 0x26,
+ 0x66, 0x59, 0x71, 0xF3, 0xDD, 0x44, 0x63, 0x3A, 0x4B, 0x68, 0x34, 0x96, 0xD4, 0xC8, 0x08, 0x2F, 0x11, 0x6D, 0x38, 0x17,
+ 0xF3, 0x76, 0x81, 0x7F, 0x73, 0xED, 0xE9, 0x19, 0x5C, 0x33, 0xA9, 0x24, 0x2E, 0x23, 0x44, 0xC6, 0x63, 0xB9, 0x6B, 0x3D,
+ 0xB1, 0xEA, 0xDE, 0xD9, 0xED, 0xCE, 0x99, 0xF0, 0x2A, 0xDF, 0xDA, 0x98, 0x77, 0xB0, 0xCD, 0x94, 0xAF, 0x36, 0xCD, 0xE4,
+ 0x82, 0x61, 0x26, 0x08, 0x6E, 0x99, 0x60, 0xEE, 0x94, 0xBD, 0xDA, 0x25, 0x9F, 0x2C, 0xD4, 0x63, 0x05, 0x2B, 0xC7, 0x67,
+ 0x11, 0xE1, 0x5E, 0x00, 0xAE, 0xE6, 0x51, 0x91, 0x76, 0xC2, 0x94, 0xFB, 0xAC, 0x81, 0x80, 0x25, 0x3A, 0x42, 0xA5, 0x27,
+ 0xA9, 0x06, 0x4E, 0x69, 0xAA, 0x21, 0x73, 0x78, 0xCC, 0x0D, 0x5A, 0x0C, 0xF7, 0xAF, 0x41, 0xB8, 0x6A, 0xA9, 0xD6, 0x5E,
+ 0x6D, 0x0B, 0x55, 0x9F, 0xB6, 0xDE, 0xA3, 0xAD, 0xB7, 0x68, 0xEB, 0x1D, 0xDA, 0x7A, 0x77, 0xB6, 0xDE, 0x9C, 0xAD, 0x37,
+ 0x66, 0xB7, 0xB7, 0x05, 0xC5, 0x98, 0xCF, 0x68, 0x54, 0xBE, 0x91, 0x2A, 0x74, 0xF6, 0x5C, 0xF0, 0xB7, 0x0C, 0x6A, 0x3C,
+ 0x67, 0xA8, 0x25, 0x70, 0xB3, 0x02, 0x20, 0x54, 0x12, 0x55, 0x0D, 0x56, 0xF0, 0x7C, 0xD9, 0xE8, 0x99, 0xBD, 0xBD, 0x0F,
+ 0xF7, 0xCF, 0xC3, 0x22, 0xEF, 0x90, 0x99, 0x8E, 0xE2, 0x4A, 0x96, 0x07, 0xDA, 0x39, 0x52, 0xCC, 0x91, 0xD0, 0x21, 0x49,
+ 0x12, 0x2A, 0xF9, 0x72, 0x8F, 0xAB, 0xA8, 0x3C, 0x98, 0xD2, 0x30, 0xB4, 0x9C, 0x43, 0xB8, 0xD0, 0x01, 0x72, 0xE1, 0x42,
+ 0x6F, 0xE0, 0xCA, 0xA7, 0xAD, 0x98, 0x5A, 0x19, 0x25, 0x0C, 0x05, 0x9F, 0x58, 0xCE, 0xDD, 0x34, 0xB0, 0xCF, 0x4A, 0x82,
+ 0x3A, 0xF1, 0xE3, 0x40, 0xC8, 0x04, 0x14, 0x07, 0xD8, 0x75, 0x71, 0x8B, 0x02, 0x37, 0xA6, 0x03, 0x20, 0x61, 0x51, 0x6D,
+ 0xDA, 0x5A, 0xD4, 0x98, 0x76, 0x30, 0xD8, 0x44, 0x01, 0xDA, 0x84, 0x2E, 0xCE, 0xFB, 0xB8, 0x46, 0xD2, 0x2A, 0x34, 0x06,
+ 0x1D, 0x0C, 0x76, 0x5C, 0x77, 0x67, 0x34, 0xEA, 0x24, 0x59, 0xCE, 0x59, 0x2A, 0x3A, 0xF0, 0xD5, 0x9C, 0x4B, 0x85, 0x41,
+ 0xC7, 0x8D, 0xA1, 0x94, 0x4F, 0x67, 0x80, 0x95, 0xBB, 0x7C, 0x4C, 0xDC, 0xE9, 0xE5, 0x20, 0x8A, 0x47, 0x87, 0x07, 0x47,
+ 0x57, 0xAF, 0xDF, 0x05, 0x27, 0xD9, 0x79, 0xE1, 0x4C, 0x9D, 0x04, 0x3A, 0x9E, 0x46, 0x63, 0x2A, 0x6F, 0xED, 0x69, 0xC4,
+ 0xAA, 0x13, 0xC0, 0xE0, 0xC1, 0xF4, 0x2C, 0x27, 0xDB, 0xCA, 0xB2, 0x9E, 0x9D, 0x65, 0x59, 0x1F, 0x37, 0x78, 0x46, 0x21,
+ 0x25, 0xF4, 0x52, 0x29, 0x29, 0xF7, 0x16, 0xA5, 0xB2, 0xD7, 0x43, 0x0F, 0x3A, 0x4A, 0x67, 0x70, 0x76, 0x50, 0x9E, 0x28,
+ 0xE5, 0x46, 0x8B, 0x0A, 0x6B, 0xAD, 0x57, 0x85, 0xCA, 0xE9, 0x1A, 0xA1, 0x2A, 0xEB, 0x53, 0x0F, 0x4E, 0x33, 0xD8, 0xEE,
+ 0xAD, 0x52, 0x5F, 0xA4, 0x75, 0x75, 0xF5, 0x6F, 0x2B, 0xD2, 0x19, 0xCB, 0xB7, 0xFA, 0xE7, 0xA7, 0x4E, 0x82, 0xAA, 0xED,
+ 0x8D, 0x4E, 0xF4, 0x88, 0xF1, 0x34, 0xB6, 0x9C, 0xED, 0x4E, 0xE4, 0x8C, 0x4A, 0x61, 0x39, 0x8F, 0x4D, 0x2E, 0x6E, 0xCE,
+ 0x0D, 0x48, 0x69, 0x7C, 0x65, 0x45, 0x13, 0x28, 0x9F, 0xB0, 0x65, 0x60, 0x39, 0xBF, 0xDE, 0x7F, 0x86, 0x63, 0xA2, 0xC1,
+ 0x30, 0x8B, 0x28, 0x0D, 0x8B, 0x45, 0xBE, 0x80, 0xD3, 0xE1, 0xE5, 0x69, 0x67, 0x51, 0xDD, 0x75, 0x53, 0x82, 0xF5, 0x6E,
+ 0xF3, 0xD7, 0x61, 0x31, 0xA3, 0x17, 0xC4, 0xCB, 0x4F, 0xBE, 0x72, 0xA9, 0x6A, 0xB9, 0x0B, 0xF8, 0xFA, 0xF1, 0xD1, 0x10,
+ 0xBC, 0xC0, 0x75, 0x66, 0x99, 0x66, 0x9C, 0x09, 0xBE, 0x32, 0xBD, 0x2F, 0xD2, 0xFC, 0x3B, 0x08, 0x8D, 0x12, 0xBF, 0x35,
+ 0xBF, 0xE7, 0x8B, 0x31, 0x45, 0x43, 0xF6, 0x1F, 0xC2, 0x80, 0xC2, 0x57, 0xC6, 0xD5, 0x1A, 0xC2, 0x9E, 0x24, 0x63, 0x78,
+ 0x63, 0x56, 0x13, 0xCE, 0x02, 0xC2, 0x5A, 0xD3, 0x27, 0x22, 0x4B, 0x2F, 0x09, 0x3A, 0x16, 0x49, 0xC0, 0xBC, 0x7C, 0x8E,
+ 0xED, 0x57, 0x4F, 0x91, 0xBB, 0x8E, 0x0A, 0x23, 0x7B, 0x81, 0x28, 0xA9, 0xA7, 0x6B, 0x6E, 0x0A, 0xCC, 0x49, 0x3E, 0x19,
+ 0x7A, 0xBE, 0x86, 0x34, 0x12, 0x1D, 0x48, 0xEE, 0x22, 0xE5, 0x93, 0xA9, 0x58, 0xF2, 0x54, 0x73, 0xF8, 0x76, 0xCF, 0xF2,
+ 0xA8, 0xF8, 0xD2, 0x85, 0xE5, 0x3F, 0x5D, 0x49, 0xBE, 0x1B
+};
+const FX_BYTE g_itIT_Locale[] = {
+ 0x78, 0x9C, 0x95, 0x56, 0xD1, 0x6A, 0xD4, 0x40, 0x14, 0x7D, 0x17, 0xFC, 0x87, 0x21, 0x58, 0x50, 0x68, 0x3B, 0xFA, 0xD8,
+ 0x92, 0x06, 0x4A, 0x5B, 0xBB, 0xA5, 0x46, 0x96, 0xEE, 0xAA, 0xD8, 0x17, 0x99, 0x64, 0xA6, 0xD9, 0xB1, 0xC9, 0xCC, 0x32,
+ 0x49, 0x5A, 0x92, 0x47, 0xF1, 0xC1, 0x37, 0x7F, 0x42, 0x10, 0x41, 0xF1, 0x23, 0xFC, 0x13, 0xA1, 0xE2, 0x67, 0x78, 0xB3,
+ 0x99, 0xA4, 0xC9, 0x64, 0xBA, 0xA6, 0x79, 0xD9, 0xB9, 0xE7, 0x9E, 0x73, 0x73, 0xEF, 0x99, 0x64, 0x36, 0x6E, 0x2C, 0x43,
+ 0x12, 0x33, 0x24, 0x48, 0xC2, 0xF6, 0x1C, 0x9E, 0xBD, 0x3B, 0x99, 0x3B, 0x88, 0xB2, 0x34, 0xDC, 0x73, 0xFE, 0x7C, 0xFC,
+ 0x7C, 0xF3, 0xE5, 0xEB, 0xCD, 0xA7, 0x6F, 0x7F, 0x7F, 0xFE, 0x78, 0xDC, 0x06, 0x4F, 0x1C, 0xCF, 0xAD, 0x14, 0x82, 0x12,
+ 0x35, 0x2B, 0x92, 0x40, 0xC6, 0xA9, 0x16, 0x47, 0x8A, 0x45, 0x52, 0x71, 0x22, 0x80, 0x91, 0x48, 0x91, 0x2D, 0x5E, 0x02,
+ 0x9C, 0xEA, 0xB5, 0x17, 0x31, 0x21, 0x08, 0x97, 0x2E, 0xAE, 0xC3, 0x87, 0x0F, 0x34, 0x7E, 0xC1, 0x82, 0x40, 0xD9, 0x12,
+ 0x09, 0x51, 0xE5, 0x10, 0x25, 0x4B, 0xC5, 0x63, 0x66, 0x21, 0x47, 0x91, 0xA5, 0x46, 0xC4, 0xF3, 0x48, 0x0C, 0xE1, 0x38,
+ 0x8F, 0x62, 0x0B, 0x9B, 0x44, 0x32, 0xCD, 0x86, 0x70, 0xCA, 0xB2, 0x8C, 0x25, 0x81, 0x1A, 0xDE, 0x55, 0x66, 0x99, 0xB4,
+ 0xE1, 0x42, 0x5E, 0xD9, 0x05, 0x94, 0x87, 0x66, 0x02, 0x77, 0xAC, 0x6A, 0x78, 0xAB, 0x08, 0x11, 0x30, 0x66, 0xCF, 0x79,
+ 0xE6, 0x74, 0x1C, 0xB4, 0xB9, 0x67, 0x33, 0xCE, 0x66, 0x9B, 0xCD, 0x33, 0x9B, 0x61, 0x36, 0xB7, 0x6C, 0x56, 0xD9, 0x7C,
+ 0xB2, 0x39, 0x64, 0x73, 0xC7, 0x66, 0xCC, 0xDD, 0x9E, 0x50, 0x52, 0xE8, 0x47, 0x09, 0x56, 0x1E, 0x95, 0x09, 0x13, 0x3C,
+ 0x24, 0x2E, 0xAE, 0xA2, 0x3A, 0x0D, 0x3D, 0x0A, 0x46, 0x7F, 0x7D, 0xEF, 0x61, 0xE0, 0x43, 0x36, 0x04, 0x99, 0x0A, 0x65,
+ 0x3C, 0x80, 0xE1, 0xE1, 0xB9, 0x1A, 0x80, 0x57, 0x4C, 0x30, 0x65, 0x82, 0x29, 0x09, 0x48, 0xF5, 0x90, 0x68, 0x08, 0xB7,
+ 0xCD, 0x75, 0x1A, 0xED, 0x6C, 0x9D, 0xEE, 0xD8, 0x6C, 0xD6, 0x6C, 0xD4, 0xEC, 0xD1, 0x6C, 0xCE, 0xEC, 0xCB, 0x6C, 0xC9,
+ 0xDE, 0x0F, 0x14, 0xE2, 0x94, 0xB3, 0xA4, 0x79, 0x11, 0x75, 0xE8, 0xED, 0xFB, 0x60, 0x71, 0x13, 0x74, 0x78, 0xDE, 0xD4,
+ 0x48, 0xE0, 0x7E, 0x05, 0x40, 0x98, 0x22, 0xBA, 0x1A, 0xAC, 0x3C, 0x72, 0xE0, 0xE2, 0xEA, 0xB7, 0x4E, 0x78, 0xF4, 0x36,
+ 0xC4, 0x2D, 0xB1, 0x0A, 0x8C, 0x03, 0xA3, 0x6E, 0x3C, 0x63, 0x53, 0x02, 0x6F, 0x96, 0x12, 0xAB, 0x8D, 0x6D, 0x23, 0x7D,
+ 0x9A, 0x5C, 0xE4, 0x71, 0xEC, 0x78, 0x47, 0x70, 0xA1, 0x43, 0xE4, 0xC3, 0x85, 0xDE, 0xC2, 0x55, 0xCD, 0xD7, 0x32, 0x8D,
+ 0x32, 0x5A, 0x18, 0x4B, 0x11, 0x39, 0xDE, 0xE1, 0xFD, 0x44, 0x09, 0xA3, 0x95, 0x06, 0x83, 0x04, 0x8F, 0x12, 0xA4, 0x0B,
+ 0xA9, 0x32, 0x2D, 0xB1, 0x29, 0x70, 0x6F, 0x3E, 0x00, 0x32, 0x9E, 0x74, 0xE6, 0xED, 0x44, 0xBD, 0x79, 0x27, 0x93, 0x5D,
+ 0xDF, 0xDF, 0x9D, 0xCD, 0xD0, 0xB9, 0x8B, 0x3B, 0x1C, 0xA3, 0x40, 0x6F, 0xD2, 0xFB, 0x28, 0x56, 0x63, 0x36, 0xF7, 0x18,
+ 0xC1, 0xD7, 0x53, 0xAE, 0x14, 0x03, 0x3A, 0xEE, 0x8D, 0xA4, 0x5D, 0x9A, 0x03, 0xD6, 0xEC, 0xF2, 0x71, 0xE1, 0xD3, 0xCB,
+ 0x49, 0x92, 0xCE, 0x8E, 0x0E, 0x9F, 0x5F, 0xBF, 0x21, 0x8B, 0xD3, 0xF2, 0xBC, 0xF6, 0xA5, 0x4B, 0x02, 0x9D, 0xC8, 0x93,
+ 0x80, 0xA9, 0x5B, 0x73, 0x7A, 0xB1, 0xEE, 0x04, 0x30, 0x78, 0x14, 0x43, 0xC7, 0x2B, 0x37, 0xCB, 0x72, 0x67, 0xBB, 0x2C,
+ 0x4B, 0x17, 0xF7, 0x78, 0x83, 0x42, 0x5A, 0x18, 0xE6, 0x4A, 0x31, 0x11, 0x16, 0x8E, 0xF7, 0x08, 0xD5, 0xDA, 0x9D, 0x9D,
+ 0x91, 0xD2, 0x25, 0x9C, 0x15, 0x4C, 0x64, 0xFA, 0x9E, 0x1B, 0x16, 0x15, 0x36, 0x5A, 0x6F, 0x0B, 0x35, 0xD3, 0xF5, 0x42,
+ 0x5D, 0x96, 0xB2, 0x90, 0x27, 0x04, 0x36, 0x7B, 0xB3, 0xD1, 0xD7, 0x69, 0x53, 0xDD, 0xFE, 0xAD, 0xCA, 0x7C, 0xC9, 0xAB,
+ 0x9D, 0xDE, 0x1E, 0xC5, 0x6F, 0xBB, 0xDE, 0x18, 0x45, 0x4F, 0xB8, 0xC8, 0x53, 0xC7, 0xDB, 0x1A, 0x45, 0x2E, 0x99, 0x92,
+ 0x8E, 0xF7, 0x74, 0xC8, 0xC5, 0xFD, 0xB1, 0x01, 0x69, 0x7C, 0x6F, 0x9D, 0xE8, 0x03, 0xCD, 0x03, 0xB6, 0x0A, 0x1C, 0xEF,
+ 0xF7, 0x07, 0x38, 0x65, 0xFB, 0x8C, 0x61, 0x91, 0xE6, 0x23, 0x25, 0x95, 0xD5, 0x02, 0x0E, 0x87, 0x57, 0x67, 0xA3, 0x45,
+ 0x5D, 0xD3, 0x87, 0x12, 0x6C, 0x76, 0x5B, 0xBD, 0x0D, 0xC5, 0x92, 0x5D, 0x90, 0xB0, 0x3A, 0xEA, 0x9A, 0xA5, 0xAE, 0xE5,
+ 0x17, 0xF0, 0x95, 0x43, 0xD1, 0x14, 0xBC, 0xC0, 0x5D, 0x66, 0x93, 0xE6, 0x82, 0x4B, 0x71, 0x67, 0xFA, 0x40, 0xE6, 0x8A,
+ 0x33, 0x85, 0x66, 0x19, 0xB5, 0xE6, 0xF7, 0xA9, 0x0C, 0x18, 0x9A, 0xF2, 0xFF, 0x10, 0x26, 0x0C, 0xBE, 0x23, 0xAE, 0xD7,
+ 0x10, 0xF6, 0x15, 0x09, 0xE0, 0x85, 0xB9, 0x9B, 0x30, 0x5F, 0x10, 0x6E, 0x4D, 0x9F, 0xCA, 0x32, 0xBF, 0x24, 0xE8, 0x58,
+ 0x66, 0x0B, 0x1E, 0x56, 0x73, 0x6C, 0xBD, 0x3E, 0x41, 0xFE, 0x3A, 0x2A, 0x8C, 0x1C, 0x2E, 0x64, 0x43, 0x3D, 0x5B, 0x73,
+ 0x53, 0x60, 0x46, 0xD5, 0x64, 0xE8, 0xC5, 0x1A, 0xD2, 0x4C, 0x8E, 0x20, 0xF9, 0x45, 0x2E, 0xA2, 0xF7, 0x72, 0xC5, 0xD3,
+ 0xCD, 0xE1, 0xDB, 0x3D, 0xAB, 0xA2, 0xFA, 0xD3, 0x16, 0x96, 0xFF, 0x00, 0x20, 0x8B, 0xBE, 0xF7
+};
+const FX_BYTE g_ptBR_Locale[] = {
+ 0x78, 0x9C, 0x9D, 0x56, 0x3D, 0x6F, 0xD4, 0x40, 0x10, 0xAD, 0x83, 0xC4, 0x7F, 0x58, 0x59, 0x89, 0x0E, 0xA4, 0x24, 0x86,
+ 0x92, 0xC8, 0x67, 0xE9, 0x92, 0x0B, 0x39, 0x94, 0x18, 0x9D, 0xCE, 0x11, 0x88, 0x34, 0x68, 0x6D, 0xEF, 0xD9, 0x9B, 0xD8,
+ 0xBB, 0xC7, 0xDA, 0x4E, 0xB0, 0x6B, 0x1A, 0x3A, 0x28, 0x29, 0x53, 0x20, 0x2A, 0x44, 0x83, 0x44, 0x49, 0x91, 0xDF, 0x82,
+ 0xB8, 0x9F, 0xC1, 0xFA, 0xF3, 0xFC, 0xB1, 0x36, 0x06, 0x37, 0xDE, 0x99, 0x79, 0x6F, 0x3D, 0xF3, 0x76, 0x76, 0x64, 0xC5,
+ 0xA5, 0x26, 0x74, 0x11, 0x20, 0xD0, 0x43, 0x63, 0x69, 0x15, 0xBC, 0x3E, 0x5C, 0x48, 0xC0, 0x42, 0xBE, 0x39, 0x96, 0xD6,
+ 0x1F, 0x6F, 0xD7, 0x1F, 0xDE, 0xFD, 0x7E, 0xFF, 0x69, 0xFD, 0xED, 0xEB, 0x83, 0x5F, 0x3F, 0xBE, 0xAF, 0x3F, 0xFF, 0x7C,
+ 0x28, 0xA9, 0xF7, 0xEF, 0x01, 0xA0, 0x24, 0x14, 0x62, 0x41, 0xA6, 0x47, 0x9E, 0x41, 0x5D, 0x3F, 0x67, 0xDB, 0x0C, 0xD9,
+ 0x94, 0x61, 0x48, 0x12, 0xD4, 0x16, 0x50, 0x3C, 0x4A, 0x02, 0xE7, 0x39, 0x0F, 0xF9, 0x89, 0xBD, 0x95, 0xD9, 0xEA, 0x25,
+ 0x24, 0x08, 0x33, 0xAA, 0xC8, 0x99, 0x59, 0x89, 0x2C, 0xD1, 0x35, 0x62, 0x1D, 0x31, 0x0F, 0xB2, 0xBB, 0x2F, 0xA2, 0x00,
+ 0x34, 0x18, 0x76, 0x85, 0x04, 0x2C, 0x82, 0x5F, 0x86, 0xC4, 0x11, 0xFB, 0x5D, 0xA1, 0x1F, 0xDA, 0xD4, 0x0F, 0x44, 0x01,
+ 0x1F, 0x05, 0xC8, 0x33, 0x84, 0xB9, 0xD2, 0x30, 0x08, 0xC5, 0x11, 0x42, 0xAF, 0xBB, 0x48, 0x16, 0x8A, 0x9B, 0x21, 0x90,
+ 0xAF, 0x4B, 0x09, 0xAB, 0x92, 0x02, 0x68, 0x18, 0x6C, 0x2C, 0x3D, 0x96, 0x1A, 0xDA, 0x8A, 0x75, 0x15, 0x2B, 0x2A, 0x96,
+ 0x53, 0x2C, 0xA6, 0x58, 0x4B, 0xB1, 0x92, 0x62, 0x1D, 0xC5, 0x22, 0x8A, 0xF5, 0x13, 0x6B, 0x27, 0x96, 0xAD, 0x5F, 0x31,
+ 0x0B, 0x46, 0x95, 0x16, 0xE4, 0x96, 0x6A, 0x51, 0x0F, 0x93, 0x24, 0x9D, 0xC4, 0x28, 0xBD, 0x3E, 0xB2, 0x43, 0xDE, 0xD2,
+ 0x7B, 0x4B, 0xDE, 0x80, 0xB0, 0x11, 0x0B, 0x10, 0x6F, 0x3E, 0x71, 0xE8, 0x4D, 0x08, 0x59, 0xD0, 0x15, 0xC2, 0xA4, 0x23,
+ 0xE4, 0xA3, 0xB7, 0x5D, 0x91, 0xBB, 0x5B, 0x03, 0x5A, 0x9B, 0xE4, 0x40, 0xBA, 0x12, 0xD4, 0xD3, 0x38, 0xFF, 0xBC, 0xB0,
+ 0x76, 0x51, 0xED, 0x52, 0xDA, 0x15, 0xB4, 0x13, 0x6F, 0xE7, 0x2B, 0xC8, 0xB3, 0x3B, 0x49, 0x0F, 0x31, 0x6C, 0x61, 0xE4,
+ 0x55, 0x2F, 0x7F, 0xEE, 0x52, 0x27, 0x1A, 0x3F, 0xA4, 0xC2, 0xA8, 0x87, 0xE6, 0x8D, 0x10, 0xD8, 0x98, 0x95, 0xCD, 0x11,
+ 0x83, 0x95, 0x7D, 0xB9, 0xA5, 0x1E, 0x1E, 0x29, 0x72, 0xF2, 0x2E, 0x1D, 0x93, 0x69, 0xE9, 0x00, 0xE9, 0xAA, 0x20, 0xF0,
+ 0xD9, 0x25, 0x37, 0x86, 0x57, 0xE6, 0xB5, 0x60, 0x80, 0xE6, 0x30, 0xE0, 0xF2, 0x90, 0x52, 0xE8, 0xD2, 0x93, 0xCF, 0xB7,
+ 0x65, 0xE8, 0xBA, 0x92, 0x7A, 0xCC, 0x9F, 0x5D, 0x30, 0x1D, 0xF1, 0x29, 0x09, 0x46, 0x1A, 0x7F, 0xB2, 0xD5, 0x2B, 0xFE,
+ 0x24, 0x32, 0x94, 0xA4, 0xAE, 0x5D, 0x5C, 0x4A, 0x6C, 0x49, 0xFD, 0x7F, 0xBE, 0x87, 0x2C, 0x4E, 0x9F, 0xCA, 0x9A, 0x26,
+ 0x0F, 0xE6, 0xF8, 0x0E, 0x65, 0xC1, 0x86, 0xD5, 0xE4, 0x00, 0x50, 0xF3, 0xE4, 0x92, 0x04, 0xD8, 0x6B, 0x48, 0x52, 0xF1,
+ 0xD4, 0x24, 0x99, 0xCD, 0x46, 0x0E, 0x2F, 0x65, 0xC4, 0xEF, 0xD5, 0x48, 0xD7, 0x47, 0xFE, 0x08, 0x5C, 0x28, 0x72, 0x05,
+ 0xDC, 0xC5, 0xCE, 0xA4, 0x48, 0xC9, 0x19, 0x77, 0x38, 0x35, 0x55, 0x61, 0x36, 0x3B, 0xD0, 0xB4, 0x03, 0x5D, 0x1F, 0xC4,
+ 0xC8, 0x35, 0x48, 0x39, 0x4D, 0x42, 0x22, 0x40, 0xA3, 0xDC, 0xBC, 0x27, 0xCE, 0xB9, 0xB7, 0x68, 0x94, 0x93, 0x48, 0xB3,
+ 0xAE, 0x66, 0x9E, 0xAF, 0x1F, 0x4F, 0x9F, 0xDE, 0xBC, 0x84, 0xCE, 0x69, 0x7C, 0x91, 0xE9, 0x56, 0x05, 0xA5, 0x4C, 0x12,
+ 0x7A, 0x06, 0x62, 0x75, 0xF1, 0x6A, 0xBE, 0x3C, 0x27, 0xEE, 0xE3, 0xFD, 0x6D, 0x4A, 0x6A, 0xBC, 0x1B, 0xC7, 0x4F, 0xF6,
+ 0xE3, 0x98, 0x0F, 0xB3, 0x1A, 0xAE, 0x9B, 0x6A, 0x86, 0x8C, 0x21, 0x62, 0x46, 0x92, 0xBA, 0x0D, 0x0A, 0xF6, 0x60, 0xF2,
+ 0x0A, 0x31, 0x13, 0x91, 0x20, 0xFF, 0xEE, 0x4E, 0x9B, 0x97, 0x08, 0xD2, 0x2A, 0xA2, 0x2C, 0x6C, 0x53, 0xEB, 0x56, 0xDD,
+ 0x95, 0x6F, 0x6F, 0x21, 0x13, 0x7B, 0x90, 0x37, 0xC6, 0x6E, 0xB1, 0x4B, 0x16, 0xEE, 0x24, 0xD8, 0x8C, 0x86, 0x2B, 0x9C,
+ 0x34, 0xC3, 0xFE, 0x40, 0x46, 0x59, 0xC1, 0xCE, 0x40, 0x02, 0xEF, 0xAF, 0xD0, 0x97, 0xD4, 0xBD, 0x81, 0xF0, 0x18, 0x31,
+ 0x2A, 0xA9, 0x8F, 0x5A, 0xE8, 0x8D, 0x30, 0xB5, 0x03, 0x2F, 0x4E, 0xA3, 0xA6, 0x4C, 0xDD, 0x59, 0xB4, 0x61, 0x6A, 0x48,
+ 0xEA, 0x62, 0x9B, 0x4F, 0xA2, 0x1A, 0xA0, 0x87, 0x84, 0x7D, 0x9A, 0x2C, 0x24, 0xF5, 0x70, 0x71, 0xF6, 0x0F, 0xB4, 0xEA,
+ 0x39, 0xB4, 0x48, 0xE9, 0x28, 0x6C, 0xA5, 0x9D, 0xDC, 0xFB, 0x68, 0x85, 0x96, 0xD0, 0x2C, 0xC6, 0x6D, 0x61, 0xE6, 0x7B,
+ 0x6A, 0x11, 0xFF, 0xC3, 0xB3, 0xC0, 0x9C, 0xCB, 0x23, 0x8B, 0x01, 0x98, 0x60, 0x4A, 0x7A, 0x00, 0x47, 0x34, 0x64, 0x18,
+ 0x31, 0xA0, 0x07, 0x56, 0x07, 0x62, 0x62, 0x51, 0x03, 0x81, 0x39, 0xFE, 0x2B, 0x64, 0x86, 0x0C, 0x86, 0x6E, 0x7A, 0x21,
+ 0x13, 0x06, 0x0D, 0x7E, 0xC3, 0xFA, 0x20, 0xE7, 0x0E, 0xC4, 0x1D, 0x80, 0x53, 0x1A, 0x87, 0x57, 0x10, 0x9C, 0xD0, 0xC0,
+ 0xC1, 0x66, 0x52, 0xD3, 0xDE, 0x8B, 0x67, 0x40, 0xEB, 0x07, 0x73, 0x01, 0x4C, 0x87, 0x16, 0xE0, 0x45, 0xEF, 0xA7, 0x39,
+ 0xD6, 0x4E, 0xAA, 0x04, 0x67, 0xBD, 0x30, 0x9D, 0x0E, 0x82, 0x69, 0x51, 0x48, 0xEC, 0x4B, 0x9A, 0x22, 0xB3, 0x24, 0xD3,
+ 0xC1, 0x56, 0x39, 0x4F, 0x45, 0xCE, 0xFE, 0xF7, 0xD5, 0x3F, 0x30, 0xBB, 0xD9, 0x9B
+};
+const FX_BYTE g_nlNL_Locale[] = {
+ 0x78, 0x9C, 0x95, 0x56, 0x4D, 0x4F, 0xDC, 0x30, 0x10, 0x3D, 0x53, 0xA9, 0xFF, 0xC1, 0x8A, 0x8A, 0x68, 0x25, 0x96, 0x2D,
+ 0x47, 0x50, 0x88, 0xB4, 0x05, 0x0A, 0x15, 0x04, 0xAD, 0x58, 0xDA, 0xAA, 0x5C, 0x2A, 0x6F, 0x62, 0x76, 0xBD, 0x24, 0xF6,
+ 0xCA, 0x89, 0x41, 0xC9, 0xB1, 0x52, 0x8F, 0xFD, 0x27, 0xAD, 0xDA, 0x5B, 0xFF, 0x4F, 0xA5, 0x4A, 0xFC, 0x8C, 0x8E, 0xF3,
+ 0x45, 0x12, 0x3B, 0x69, 0xC8, 0x05, 0xCF, 0x9B, 0xF7, 0xBC, 0x33, 0xCF, 0xCE, 0x10, 0x3B, 0xE0, 0x1E, 0x0E, 0x08, 0x62,
+ 0x38, 0x24, 0x07, 0x16, 0x0B, 0x3E, 0x5F, 0x9C, 0x5B, 0xC8, 0x27, 0x91, 0x77, 0x60, 0x3D, 0x7C, 0xFB, 0xFD, 0xF7, 0xEB,
+ 0xAF, 0x87, 0x9F, 0x3F, 0x5E, 0xE6, 0xAB, 0x57, 0x96, 0xF3, 0xFC, 0x19, 0x42, 0xB6, 0xE2, 0x33, 0x1F, 0x8B, 0x59, 0x12,
+ 0xCE, 0x79, 0x10, 0x15, 0xD2, 0x85, 0x20, 0x0B, 0x2E, 0x28, 0x66, 0x8A, 0xB5, 0x81, 0xEC, 0x90, 0xB3, 0x78, 0x79, 0x01,
+ 0xA9, 0x48, 0xC5, 0x1B, 0x79, 0xEC, 0xAC, 0x30, 0x93, 0x58, 0x50, 0x7B, 0x9C, 0x87, 0xB5, 0xCC, 0x0D, 0x99, 0x8B, 0x8E,
+ 0x54, 0x88, 0xB1, 0x88, 0x0D, 0x38, 0x5E, 0x0B, 0x1A, 0x98, 0xF8, 0xC4, 0xB4, 0xCB, 0x4A, 0x32, 0x33, 0x1C, 0x98, 0x60,
+ 0x2C, 0x17, 0x32, 0x8A, 0x65, 0x64, 0x48, 0x45, 0x64, 0x1D, 0x93, 0x70, 0x4E, 0x84, 0x21, 0xC7, 0x6F, 0x63, 0x6E, 0xCE,
+ 0x30, 0x7E, 0xD7, 0x25, 0xF2, 0x89, 0xD7, 0x4E, 0xA1, 0x62, 0x5D, 0x19, 0x58, 0x37, 0x14, 0xE1, 0xF9, 0x5C, 0x1C, 0x58,
+ 0xBB, 0x56, 0xCB, 0x59, 0xB3, 0xAB, 0x26, 0x83, 0xBA, 0xEC, 0x7C, 0x8A, 0x99, 0x66, 0x2F, 0xCD, 0x56, 0x9A, 0x5D, 0x34,
+ 0xFB, 0x67, 0xF6, 0xCE, 0x6C, 0x5B, 0xBF, 0x63, 0x3E, 0x4E, 0x6A, 0x17, 0x10, 0x22, 0x27, 0xE5, 0x70, 0x71, 0xA1, 0x1A,
+ 0xB5, 0xAE, 0x40, 0xB8, 0x5E, 0x06, 0xD4, 0xA7, 0x2C, 0xD2, 0xD1, 0x7B, 0x4E, 0x4C, 0xB0, 0x0F, 0xFB, 0x12, 0xA1, 0xE3,
+ 0x77, 0x82, 0xAE, 0x74, 0x34, 0xC5, 0x71, 0x93, 0x8C, 0xB2, 0x95, 0xA1, 0xF2, 0xD6, 0x49, 0xE7, 0x2D, 0x68, 0xE5, 0x6B,
+ 0x95, 0x6B, 0x45, 0x6B, 0xE5, 0x6A, 0x75, 0x6A, 0x25, 0x76, 0x17, 0x17, 0x12, 0x41, 0x7D, 0x4A, 0xC2, 0xFA, 0xCB, 0x5D,
+ 0x40, 0xCE, 0xC4, 0x85, 0x63, 0x28, 0x83, 0x66, 0x6A, 0xDA, 0x4A, 0xA1, 0xC7, 0xB0, 0xB6, 0x39, 0x11, 0xB8, 0xB6, 0x2F,
+ 0x44, 0xCE, 0x9B, 0x43, 0x7B, 0xAC, 0xFE, 0x56, 0xC0, 0xE4, 0xA8, 0x02, 0x50, 0xB6, 0x2A, 0x05, 0x30, 0x9B, 0xC6, 0xAD,
+ 0xE1, 0x94, 0xA3, 0x3E, 0x18, 0x3E, 0xC5, 0x31, 0xB8, 0xCE, 0x2A, 0x83, 0x2B, 0xA4, 0x98, 0x5F, 0x37, 0x32, 0x08, 0x2C,
+ 0xE7, 0x18, 0x1E, 0x74, 0x84, 0x5C, 0x78, 0xD0, 0x27, 0x78, 0x54, 0xEF, 0x15, 0xB3, 0x4B, 0x1A, 0x70, 0xB6, 0xB0, 0x9C,
+ 0xA7, 0xAA, 0x42, 0xE2, 0x83, 0x68, 0x04, 0x9A, 0xD1, 0x60, 0x4D, 0xB4, 0xE4, 0x22, 0xCE, 0x54, 0x23, 0x5D, 0x81, 0x50,
+ 0x03, 0x29, 0x7A, 0x8F, 0x69, 0xD8, 0xEA, 0xBD, 0x86, 0x34, 0x7A, 0x3F, 0xDD, 0x77, 0xDD, 0xFD, 0xD9, 0x6C, 0x0B, 0x49,
+ 0x29, 0xB6, 0xD0, 0xB5, 0x3D, 0xAE, 0x11, 0xBB, 0x94, 0x79, 0xEB, 0x85, 0x72, 0xA0, 0x26, 0x6B, 0xBC, 0x90, 0x0C, 0x12,
+ 0x14, 0x5D, 0x2B, 0x49, 0x9B, 0xAF, 0x7A, 0x6E, 0x75, 0x58, 0x9C, 0xF7, 0x15, 0xA0, 0xE5, 0x25, 0x38, 0x49, 0x5C, 0xFF,
+ 0xF6, 0x34, 0x8C, 0x66, 0xC7, 0x47, 0x6F, 0xEF, 0x3F, 0xE2, 0xE5, 0x59, 0x7A, 0x9D, 0x5B, 0x55, 0x27, 0x65, 0x4A, 0x26,
+ 0xD5, 0x20, 0x6E, 0xFA, 0xD5, 0xC0, 0xCA, 0x7F, 0x94, 0x52, 0xDD, 0x5D, 0xCF, 0x72, 0xD2, 0xED, 0x34, 0xDD, 0xDB, 0x49,
+ 0xD3, 0xD4, 0x1E, 0x37, 0x78, 0xDD, 0x52, 0x4F, 0x0A, 0x41, 0x98, 0x97, 0x58, 0xCE, 0x0B, 0x94, 0xAB, 0xF7, 0xF6, 0xA2,
+ 0xC1, 0xEA, 0x35, 0x11, 0x1E, 0x61, 0x71, 0xF1, 0xC3, 0x9B, 0xBA, 0x4E, 0x39, 0xA2, 0x75, 0x51, 0x75, 0xF6, 0xD8, 0xEC,
+ 0x46, 0x13, 0x2A, 0xB6, 0x87, 0x99, 0x4A, 0x43, 0x0C, 0x97, 0x61, 0xBB, 0xDC, 0x25, 0x4F, 0x77, 0x0A, 0x16, 0x82, 0xCB,
+ 0x35, 0x55, 0x97, 0x60, 0x67, 0xA0, 0xA2, 0xEA, 0x60, 0x73, 0xA0, 0x20, 0xA4, 0x4C, 0x46, 0x96, 0x33, 0x1A, 0x48, 0x4F,
+ 0x89, 0xE0, 0x96, 0xF3, 0x5A, 0x63, 0x3F, 0x1A, 0xD3, 0x38, 0xF1, 0xF2, 0x38, 0x1A, 0xCE, 0x34, 0xC1, 0xF2, 0x1A, 0x66,
+ 0x81, 0xE5, 0xFC, 0xF9, 0xF2, 0x1D, 0xE6, 0x4C, 0x83, 0xD1, 0xA3, 0xA2, 0x11, 0x57, 0x0B, 0x18, 0x2D, 0xEF, 0x2F, 0x9F,
+ 0x20, 0xAB, 0x1F, 0x84, 0x26, 0xCA, 0x06, 0x9D, 0x56, 0xB7, 0x7A, 0xD9, 0x93, 0x35, 0xB9, 0xC1, 0x5E, 0x39, 0x4C, 0xCB,
+ 0xB0, 0xD8, 0xD3, 0x4D, 0xE0, 0xFB, 0xCC, 0x47, 0x53, 0xF0, 0x67, 0x6C, 0x26, 0x50, 0x46, 0x39, 0xEB, 0x21, 0x1C, 0x72,
+ 0x29, 0x28, 0x11, 0x68, 0x16, 0xFB, 0x1D, 0x8C, 0x89, 0x0F, 0xDF, 0x3F, 0x68, 0x4A, 0xFF, 0x4B, 0x39, 0x85, 0xEF, 0x3D,
+ 0x72, 0xDF, 0x4B, 0x99, 0x08, 0x3C, 0x87, 0x77, 0xAC, 0x8F, 0x72, 0xB5, 0xC4, 0xB4, 0x83, 0x70, 0xC6, 0x53, 0x79, 0x8B,
+ 0xD1, 0x09, 0x8F, 0x97, 0xD4, 0x53, 0x3D, 0x8D, 0x3E, 0xBC, 0x43, 0x6E, 0x3F, 0x19, 0x0C, 0xF0, 0x96, 0xBC, 0x24, 0x5F,
+ 0xF6, 0xFE, 0x34, 0x70, 0x17, 0xAA, 0x4B, 0x74, 0xDE, 0x4B, 0x9B, 0xF1, 0x41, 0x34, 0x37, 0x91, 0x6C, 0xB1, 0xE2, 0x19,
+ 0x33, 0x2F, 0x32, 0x1B, 0x6D, 0xB5, 0xF3, 0xB4, 0xC7, 0xF9, 0xA7, 0xBA, 0xF3, 0x0F, 0xD5, 0xFA, 0xC0, 0xFA
+};
+const FX_BYTE g_ruRU_Locale[] = {
+ 0x78, 0x9C, 0xAD, 0x57, 0x4D, 0x4F, 0x13, 0x41, 0x18, 0x3E, 0x63, 0xE2, 0x7F, 0x98, 0x6C, 0x24, 0x68, 0x02, 0xAD, 0x1E,
+ 0x25, 0x65, 0x13, 0x22, 0x0A, 0x06, 0xD7, 0x90, 0x16, 0x34, 0x72, 0x31, 0xDB, 0xDD, 0xA1, 0x5D, 0xE8, 0xEE, 0x90, 0xE9,
+ 0x6E, 0xB0, 0x7B, 0x2A, 0x85, 0xE8, 0x05, 0x25, 0xE1, 0xA0, 0x47, 0xF4, 0xE4, 0xC9, 0x50, 0xBE, 0x12, 0x82, 0xB6, 0x24,
+ 0xFE, 0x82, 0xD9, 0xFF, 0x60, 0xD4, 0x9F, 0xE1, 0x3B, 0xFB, 0xD1, 0xEE, 0xB7, 0xC5, 0xD8, 0x1E, 0x3A, 0xF3, 0x3E, 0xCF,
+ 0xF3, 0xCE, 0xFB, 0xB5, 0xD3, 0xB6, 0xD4, 0x20, 0x8A, 0xDC, 0xC0, 0xC8, 0x90, 0x75, 0x3C, 0x23, 0x50, 0xEB, 0x65, 0x79,
+ 0x45, 0x40, 0x2A, 0x6E, 0x2A, 0x33, 0xC2, 0x8F, 0xAB, 0xDD, 0xDF, 0x47, 0x5F, 0x6E, 0xC3, 0xC7, 0xAF, 0xDE, 0x87, 0x9F,
+ 0xEF, 0x8F, 0xEE, 0x08, 0xE2, 0xCD, 0x1B, 0x08, 0x95, 0x38, 0xDF, 0x50, 0x65, 0x5A, 0x69, 0xE9, 0x55, 0xD2, 0x68, 0xFA,
+ 0xD2, 0x1A, 0xC5, 0x35, 0x42, 0x35, 0xD9, 0xE0, 0xAC, 0x31, 0x54, 0xD2, 0x89, 0x61, 0xD6, 0x9F, 0x02, 0xD4, 0xE4, 0xFB,
+ 0x31, 0x6F, 0x2F, 0x3A, 0xFB, 0xAC, 0xC7, 0x4E, 0x58, 0xD7, 0x69, 0x3B, 0xFB, 0xA5, 0xA2, 0x67, 0x0B, 0xC3, 0xBB, 0xEC,
+ 0x9C, 0x9D, 0x38, 0x6D, 0xD6, 0x65, 0x5F, 0x53, 0x09, 0xEC, 0x9B, 0xAB, 0xED, 0xB0, 0x6E, 0x1A, 0xD8, 0x65, 0x57, 0xA0,
+ 0x3D, 0xCF, 0xD3, 0xA6, 0x02, 0x17, 0xCE, 0x3B, 0xD6, 0xCB, 0x86, 0x32, 0xDC, 0x75, 0x21, 0x91, 0x53, 0x67, 0xC7, 0xD9,
+ 0xCE, 0x08, 0xC7, 0xD9, 0x86, 0x50, 0x7A, 0x4E, 0x07, 0x72, 0x3E, 0xCE, 0xC8, 0x97, 0xF5, 0xD9, 0x65, 0x3E, 0xA1, 0xC7,
+ 0xFA, 0x79, 0xF0, 0x19, 0x1C, 0x71, 0x09, 0x91, 0xC4, 0x09, 0xC8, 0x5F, 0x0F, 0x1A, 0x10, 0x6E, 0x08, 0x92, 0xAB, 0x55,
+ 0x3A, 0x23, 0xDC, 0x13, 0x92, 0x9D, 0x29, 0xE4, 0x34, 0x25, 0x0D, 0x1B, 0xA1, 0x1F, 0x99, 0xB2, 0xFF, 0xDD, 0x8A, 0xD4,
+ 0xD8, 0xFD, 0x1E, 0xA4, 0x06, 0xE1, 0x16, 0x3F, 0x15, 0xF1, 0xAB, 0x9E, 0x8A, 0xB9, 0x25, 0x2F, 0xE4, 0xD7, 0x5A, 0x95,
+ 0x5B, 0xA1, 0xD1, 0x87, 0x9D, 0x08, 0x01, 0xF6, 0x21, 0x98, 0x4B, 0x3E, 0x9F, 0x7E, 0x50, 0x7B, 0xEC, 0xBC, 0x54, 0xE4,
+ 0xD8, 0x90, 0x74, 0x05, 0x31, 0xF5, 0x00, 0x3C, 0x73, 0x87, 0x78, 0x0F, 0xD6, 0x17, 0xEC, 0x32, 0x4E, 0x3A, 0x81, 0x72,
+ 0xF7, 0xC1, 0x4F, 0x1A, 0x08, 0xC3, 0xD8, 0x76, 0xF5, 0xDD, 0x38, 0xF0, 0x06, 0xCE, 0xED, 0x40, 0x14, 0xE7, 0x40, 0x38,
+ 0x4D, 0x9C, 0xEB, 0xEC, 0x03, 0x08, 0x0E, 0x9D, 0xD7, 0x49, 0xE5, 0xB6, 0xB3, 0xC3, 0x8E, 0xE1, 0xDD, 0xF7, 0xDA, 0xEC,
+ 0x83, 0xC8, 0x5D, 0xA5, 0xE4, 0x1C, 0x9B, 0x2E, 0xD7, 0xFF, 0x81, 0xB3, 0x1D, 0x3F, 0xF2, 0x90, 0xF5, 0xE2, 0xA6, 0x03,
+ 0xA7, 0x13, 0x37, 0x7D, 0x72, 0xDA, 0x71, 0xD3, 0xE7, 0x24, 0xEB, 0x30, 0x45, 0xC8, 0x8E, 0xB3, 0x43, 0xD5, 0x31, 0xD5,
+ 0x54, 0x0D, 0xEB, 0xE1, 0xEB, 0xC9, 0x37, 0x89, 0xB3, 0x12, 0xB4, 0x33, 0xD8, 0x44, 0xA1, 0xA5, 0x18, 0x84, 0x86, 0xDB,
+ 0x90, 0x73, 0x4C, 0xE5, 0x90, 0x5F, 0xD8, 0xF1, 0x91, 0xE9, 0x23, 0xD6, 0x2B, 0x38, 0x6F, 0x61, 0x6C, 0xB8, 0x61, 0x88,
+ 0x44, 0x8D, 0xC8, 0x5D, 0x05, 0x6A, 0xB8, 0x6A, 0x8B, 0xB1, 0xBB, 0xD6, 0xB3, 0xAA, 0xB2, 0x89, 0x97, 0x64, 0xD3, 0xC4,
+ 0xD4, 0x18, 0xD4, 0x7E, 0x60, 0xF1, 0xAF, 0xE3, 0x35, 0xAB, 0xD1, 0x10, 0xC4, 0x39, 0x24, 0xC1, 0x0B, 0xBD, 0x80, 0x17,
+ 0x9A, 0x80, 0x27, 0x64, 0x82, 0x57, 0x62, 0x40, 0xCD, 0xD2, 0x36, 0x88, 0x51, 0xFB, 0x57, 0xAD, 0x8E, 0x55, 0x90, 0xCE,
+ 0x15, 0x24, 0xA9, 0xC0, 0x95, 0x23, 0x69, 0x9A, 0x75, 0x42, 0xCD, 0xA1, 0x2A, 0xAE, 0x41, 0x28, 0x62, 0xF1, 0x8B, 0x60,
+ 0x6A, 0x7A, 0xAC, 0x08, 0x21, 0x4B, 0xA4, 0x08, 0x0B, 0xD3, 0x92, 0x34, 0x5D, 0xA9, 0xA0, 0xD5, 0x52, 0x31, 0x44, 0xC9,
+ 0xD2, 0x78, 0xC9, 0x5F, 0x4F, 0xE3, 0x26, 0xED, 0x4B, 0x46, 0x12, 0xF8, 0x19, 0x73, 0x49, 0x9C, 0xCF, 0xB3, 0x8D, 0xE5,
+ 0xE6, 0xB7, 0x7C, 0x19, 0xAC, 0xC1, 0x1C, 0xCC, 0xCB, 0xC6, 0xFA, 0xC6, 0x82, 0xDE, 0xAC, 0x3C, 0x9C, 0x7B, 0xB4, 0xF5,
+ 0xFC, 0x55, 0x7D, 0xD1, 0x5E, 0xF5, 0x8A, 0x14, 0x26, 0xB9, 0x4A, 0xC3, 0xD2, 0xAB, 0x98, 0x46, 0x2B, 0x15, 0xB1, 0xF9,
+ 0x21, 0x81, 0x0D, 0x66, 0x59, 0x11, 0x44, 0x7B, 0xD2, 0xB6, 0xEF, 0x17, 0x6C, 0xDB, 0x2E, 0x15, 0x23, 0xBC, 0x6C, 0xA9,
+ 0x62, 0x51, 0x8A, 0x0D, 0xA5, 0x35, 0xD4, 0xDE, 0x1A, 0x59, 0xBB, 0x89, 0xA9, 0x82, 0x0D, 0xD3, 0x97, 0x8E, 0x27, 0x75,
+ 0xBC, 0x1E, 0x89, 0x1C, 0x06, 0x79, 0x0D, 0x53, 0x1D, 0x8B, 0x9A, 0x7C, 0xF7, 0x2A, 0x56, 0x34, 0x5D, 0x86, 0x21, 0x98,
+ 0x0C, 0xBC, 0x78, 0x70, 0xA6, 0xA0, 0x46, 0x89, 0xB5, 0xA9, 0xF1, 0x11, 0xF8, 0xFE, 0x71, 0x44, 0xC9, 0x20, 0x85, 0xF1,
+ 0x11, 0x05, 0xBA, 0x66, 0x58, 0x4D, 0x41, 0x9C, 0x1A, 0x91, 0x6E, 0x63, 0x4A, 0x04, 0xF1, 0x6E, 0x82, 0x3D, 0xAC, 0x4C,
+ 0xA4, 0xE1, 0x41, 0x37, 0x22, 0xA5, 0x89, 0x1A, 0x83, 0x29, 0x74, 0x37, 0x82, 0xE8, 0x7E, 0x47, 0x47, 0x19, 0x39, 0x2A,
+ 0xAD, 0x49, 0xF8, 0x42, 0x10, 0xCB, 0x2B, 0xE5, 0x6B, 0xC8, 0xC2, 0x9D, 0x48, 0x88, 0xDC, 0xAB, 0x2E, 0x11, 0x37, 0x7F,
+ 0xCA, 0x5B, 0x9B, 0x78, 0x4D, 0x56, 0x82, 0xBB, 0x35, 0xD8, 0xFA, 0x3E, 0xA5, 0x16, 0xFC, 0xE0, 0x54, 0xD1, 0x12, 0xD4,
+ 0xA7, 0x98, 0x4E, 0xD0, 0x0C, 0x8D, 0x18, 0x39, 0x84, 0x07, 0xC4, 0xA2, 0x1A, 0xA6, 0xA8, 0x62, 0xAA, 0x19, 0x8C, 0x59,
+ 0x95, 0x54, 0x31, 0x5A, 0xD2, 0xFE, 0x4A, 0x59, 0xC0, 0x55, 0x8A, 0xB7, 0x72, 0x29, 0xB3, 0x54, 0xAE, 0xC2, 0x23, 0x96,
+ 0x47, 0x59, 0xAE, 0xCB, 0x5A, 0x06, 0x61, 0x91, 0xD8, 0xD6, 0x86, 0x8C, 0xE6, 0x89, 0x59, 0xD7, 0x14, 0x9E, 0xD3, 0xD4,
+ 0xB3, 0xC7, 0x48, 0xCA, 0x27, 0x43, 0x01, 0x94, 0x3A, 0x09, 0xC8, 0xE5, 0xDC, 0xA3, 0x81, 0x5B, 0xE3, 0x59, 0xA2, 0x27,
+ 0xB9, 0xB4, 0x0A, 0x19, 0x89, 0x26, 0xB5, 0x2C, 0xA3, 0xB6, 0x4E, 0x5C, 0xA6, 0x17, 0xA4, 0x7B, 0xB3, 0x85, 0xFA, 0x59,
+ 0x2A, 0x7A, 0xFF, 0x3D, 0xC4, 0x3F, 0xDE, 0xCB, 0x8B, 0xC4
+};
+static IFX_Locale* XFA_GetLocaleFromBuffer(FX_LPCBYTE pBuf, int nBufLen)
+{
+ if (pBuf == NULL || nBufLen <= 0) {
+ return NULL;
+ }
+ CFX_GEModule* pGeModule = CFX_GEModule::Get();
+ if (!pGeModule) {
+ return NULL;
+ }
+ CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
+ if (!pCodecMgr) {
+ return NULL;
+ }
+ CXML_Element* pLocale = NULL;
+ FX_LPBYTE pOut = NULL;
+ FX_DWORD dwSize;
+ pCodecMgr->GetFlateModule()->FlateOrLZWDecode(FALSE,
+ pBuf, nBufLen, TRUE, 0, 0, 0, 0, 0, pOut, dwSize);
+ if (pOut) {
+ pLocale = CXML_Element::Parse(pOut, dwSize);
+ FX_Free(pOut);
+ }
+ if (pLocale) {
+ return FX_NEW CXFA_XMLLocale(pLocale);
+ }
+ return NULL;
+}
+static FX_WORD XFA_GetLanguage(CFX_WideString wsLanguage)
+{
+ FX_WORD dwLangueID = XFA_LANGID_en_US;
+ if (wsLanguage.GetLength() < 2) {
+ return dwLangueID;
+ }
+ wsLanguage.MakeLower();
+ FX_DWORD dwIDFirst = wsLanguage.GetAt(0) << 8 | wsLanguage.GetAt(1);
+ FX_DWORD dwIDSecond = wsLanguage.GetLength() >= 5 ? wsLanguage.GetAt(3) << 8 | wsLanguage.GetAt(4) : 0;
+ switch (dwIDFirst) {
+ case FXBSTR_ID(0, 0, 'z', 'h'): {
+ if (dwIDSecond == FXBSTR_ID(0, 0, 'c', 'n')) {
+ dwLangueID = XFA_LANGID_zh_CN;
+ } else if (dwIDSecond == FXBSTR_ID(0, 0, 't', 'w')) {
+ dwLangueID = XFA_LANGID_zh_TW;
+ } else if (dwIDSecond == FXBSTR_ID(0, 0, 'h', 'k')) {
+ dwLangueID = XFA_LANGID_zh_HK;
+ }
+ }
+ break;
+ case FXBSTR_ID(0, 0, 'j', 'a'):
+ dwLangueID = XFA_LANGID_ja_JP;
+ break;
+ case FXBSTR_ID(0, 0, 'k', 'o'):
+ dwLangueID = XFA_LANGID_ko_KR;
+ break;
+ case FXBSTR_ID(0, 0, 'e', 'n'): {
+ if (dwIDSecond == FXBSTR_ID(0, 0, 'g', 'b')) {
+ dwLangueID = XFA_LANGID_en_GB;
+ } else {
+ dwLangueID = XFA_LANGID_en_US;
+ }
+ }
+ break;
+ case FXBSTR_ID(0, 0, 'd', 'e'):
+ dwLangueID = XFA_LANGID_de_DE;
+ break;
+ case FXBSTR_ID(0, 0, 'f', 'r'):
+ dwLangueID = XFA_LANGID_fr_FR;
+ break;
+ case FXBSTR_ID(0, 0, 'e', 's'): {
+ if (dwIDSecond == FXBSTR_ID(0, 0, 'e', 's')) {
+ dwLangueID = XFA_LANGID_es_ES;
+ } else {
+ dwLangueID = XFA_LANGID_es_LA;
+ }
+ }
+ break;
+ case FXBSTR_ID(0, 0, 'i', 't'):
+ dwLangueID = XFA_LANGID_it_IT;
+ break;
+ case FXBSTR_ID(0, 0, 'p', 't'):
+ dwLangueID = XFA_LANGID_pt_BR;
+ break;
+ case FXBSTR_ID(0, 0, 'n', 'l'):
+ dwLangueID = XFA_LANGID_nl_NL;
+ break;
+ case FXBSTR_ID(0, 0, 'r', 'u'):
+ dwLangueID = XFA_LANGID_ru_RU;
+ break;
+ }
+ return dwLangueID;
+}
+CXFA_LocaleMgr::CXFA_LocaleMgr(CXFA_Node* pLocaleSet, CFX_WideString wsDeflcid)
+ : m_dwLocaleFlags(0x00)
+{
+ m_dwDeflcid = XFA_GetLanguage(wsDeflcid);
+ CXFA_Node* pNodeLocale = NULL;
+ if (pLocaleSet && (pNodeLocale = pLocaleSet->GetNodeItem(XFA_NODEITEM_FirstChild))) {
+ while (pNodeLocale) {
+ m_LocaleArray.Add(FX_NEW CXFA_NodeLocale(pNodeLocale));
+ pNodeLocale = pNodeLocale->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ }
+ m_pDefLocale = GetLocaleByName(wsDeflcid);
+}
+CXFA_LocaleMgr::~CXFA_LocaleMgr()
+{
+ FX_INT32 iCount = m_LocaleArray.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ ((IFX_Locale*)m_LocaleArray[i])->Release();
+ }
+ FX_INT32 iXmls = m_XMLLocaleArray.GetSize();
+ for (FX_INT32 j = 0; j < iXmls; j++) {
+ ((IFX_Locale*)m_XMLLocaleArray[j])->Release();
+ }
+}
+void CXFA_LocaleMgr::Release()
+{
+ delete this;
+}
+FX_WORD CXFA_LocaleMgr::GetDefLocaleID()
+{
+ return m_dwDeflcid;
+}
+IFX_Locale* CXFA_LocaleMgr::GetDefLocale()
+{
+ if (m_pDefLocale) {
+ return m_pDefLocale;
+ } else if (m_LocaleArray.GetSize()) {
+ return (IFX_Locale*)m_LocaleArray[0];
+ } else if (m_XMLLocaleArray.GetSize()) {
+ return (IFX_Locale*)m_XMLLocaleArray[0];
+ }
+ m_pDefLocale = GetLocale(m_dwDeflcid);
+ if (m_pDefLocale != NULL) {
+ m_XMLLocaleArray.Add(m_pDefLocale);
+ }
+ return m_pDefLocale;
+}
+IFX_Locale* CXFA_LocaleMgr::GetLocale(FX_WORD lcid)
+{
+ IFX_Locale* pLocal = NULL;
+ switch (lcid) {
+ case XFA_LANGID_zh_CN:
+ pLocal = XFA_GetLocaleFromBuffer(g_zhCN_Locale, sizeof(g_zhCN_Locale));
+ break;
+ case XFA_LANGID_zh_TW:
+ pLocal = XFA_GetLocaleFromBuffer(g_zhTW_Locale, sizeof(g_zhTW_Locale));
+ break;
+ case XFA_LANGID_zh_HK:
+ pLocal = XFA_GetLocaleFromBuffer(g_zhHK_Locale, sizeof(g_zhHK_Locale));
+ break;
+ case XFA_LANGID_ja_JP:
+ pLocal = XFA_GetLocaleFromBuffer(g_jaJP_Locale, sizeof(g_jaJP_Locale));
+ break;
+ case XFA_LANGID_ko_KR:
+ pLocal = XFA_GetLocaleFromBuffer(g_koKR_Locale, sizeof(g_koKR_Locale));
+ break;
+ case XFA_LANGID_en_GB:
+ pLocal = XFA_GetLocaleFromBuffer(g_enGB_Locale, sizeof(g_enGB_Locale));
+ break;
+ case XFA_LANGID_es_LA:
+ pLocal = XFA_GetLocaleFromBuffer(g_esLA_Locale, sizeof(g_esLA_Locale));
+ break;
+ case XFA_LANGID_es_ES:
+ pLocal = XFA_GetLocaleFromBuffer(g_esES_Locale, sizeof(g_esES_Locale));
+ break;
+ case XFA_LANGID_de_DE:
+ pLocal = XFA_GetLocaleFromBuffer(g_deDE_Loacale, sizeof(g_deDE_Loacale));
+ break;
+ case XFA_LANGID_fr_FR:
+ pLocal = XFA_GetLocaleFromBuffer(g_frFR_Locale, sizeof(g_frFR_Locale));
+ break;
+ case XFA_LANGID_it_IT:
+ pLocal = XFA_GetLocaleFromBuffer(g_itIT_Locale, sizeof(g_itIT_Locale));
+ break;
+ case XFA_LANGID_pt_BR:
+ pLocal = XFA_GetLocaleFromBuffer(g_ptBR_Locale, sizeof(g_ptBR_Locale));
+ break;
+ case XFA_LANGID_nl_NL:
+ pLocal = XFA_GetLocaleFromBuffer(g_nlNL_Locale, sizeof(g_nlNL_Locale));
+ break;
+ case XFA_LANGID_ru_RU:
+ pLocal = XFA_GetLocaleFromBuffer(g_ruRU_Locale, sizeof(g_ruRU_Locale));
+ break;
+ case XFA_LANGID_en_US:
+ default:
+ pLocal = XFA_GetLocaleFromBuffer(g_enUS_Locale, sizeof(g_enUS_Locale));
+ break;
+ }
+ return pLocal;
+}
+IFX_Locale* CXFA_LocaleMgr::GetLocaleByName(FX_WSTR wsLocaleName)
+{
+ FX_INT32 iCount = m_LocaleArray.GetSize();
+ FX_INT32 i = 0;
+ for (i = 0; i < iCount; i++) {
+ IFX_Locale* pLocale = ((IFX_Locale*)m_LocaleArray[i]);
+ if (pLocale->GetName() == wsLocaleName) {
+ return pLocale;
+ }
+ }
+ FX_INT32 iLen = wsLocaleName.GetLength();
+ if (iLen < 2) {
+ return NULL;
+ }
+ iCount = m_XMLLocaleArray.GetSize();
+ for (i = 0; i < iCount; i++) {
+ IFX_Locale* pLocale = ((IFX_Locale*)m_XMLLocaleArray[i]);
+ if (pLocale->GetName() == wsLocaleName) {
+ return pLocale;
+ }
+ }
+ FX_WORD dwLangueID = XFA_GetLanguage(wsLocaleName);
+ IFX_Locale* pLocale = GetLocale(dwLangueID);
+ if (pLocale != NULL) {
+ m_XMLLocaleArray.Add(pLocale);
+ }
+ return pLocale;
+}
+void CXFA_LocaleMgr::SetDefLocale(IFX_Locale* pLocale)
+{
+ m_pDefLocale = pLocale;
+}
+CFX_WideStringC CXFA_LocaleMgr::GetConfigLocaleName(CXFA_Node* pConfig)
+{
+ if (!(m_dwLocaleFlags & 0x01)) {
+ m_wsConfigLocale.Empty();
+ if (pConfig) {
+ CXFA_Node* pChildfConfig = pConfig->GetFirstChildByClass(XFA_ELEMENT_Acrobat);
+ if (!pChildfConfig) {
+ pChildfConfig = pConfig->GetFirstChildByClass(XFA_ELEMENT_Present);
+ }
+ CXFA_Node* pCommon = pChildfConfig ? pChildfConfig->GetFirstChildByClass(XFA_ELEMENT_Common) : NULL;
+ CXFA_Node* pLocale = pCommon ? pCommon->GetFirstChildByClass(XFA_ELEMENT_Locale) : NULL;
+ if (pLocale) {
+ pLocale->TryCData(XFA_ATTRIBUTE_Value, m_wsConfigLocale, FALSE);
+ }
+ }
+ m_dwLocaleFlags |= 0x01;
+ }
+ return m_wsConfigLocale;
+}
+static CXFA_TimeZoneProvider *g_pProvider = NULL;
+IXFA_TimeZoneProvider* IXFA_TimeZoneProvider::Create()
+{
+ FXSYS_assert(!g_pProvider);
+ g_pProvider = FX_NEW CXFA_TimeZoneProvider();
+ return g_pProvider;
+}
+IXFA_TimeZoneProvider* IXFA_TimeZoneProvider::Get()
+{
+ if (!g_pProvider) {
+ g_pProvider = FX_NEW CXFA_TimeZoneProvider();
+ }
+ return g_pProvider;
+}
+void IXFA_TimeZoneProvider::Destroy()
+{
+ delete g_pProvider;
+ g_pProvider = NULL;
+}
+#include <time.h>
+CXFA_TimeZoneProvider::CXFA_TimeZoneProvider()
+{
+#if _FXM_PLATFORM_==_FXM_PLATFORM_WINDOWS_
+ _tzset();
+ m_tz.tzHour = (FX_INT8)(_timezone / 3600 * -1);
+ m_tz.tzMinute = (FX_INT8)((FXSYS_abs(_timezone) % 3600) / 60);
+#else
+ tzset();
+ m_tz.tzHour = (FX_INT8)(timezone / 3600 * -1);
+ m_tz.tzMinute = (FX_INT8)((FXSYS_abs((int)timezone) % 3600) / 60);
+#endif
+}
+CXFA_TimeZoneProvider::~CXFA_TimeZoneProvider()
+{
+}
+void CXFA_TimeZoneProvider::SetTimeZone(FX_TIMEZONE& tz)
+{
+ m_tz = tz;
+}
+void CXFA_TimeZoneProvider::GetTimeZone(FX_TIMEZONE& tz)
+{
+ tz = m_tz;
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_localevalue.cpp b/xfa/src/fxfa/src/parser/xfa_localevalue.cpp
new file mode 100644
index 0000000000..469589bad8
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_localevalue.cpp
@@ -0,0 +1,976 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+static const FX_DOUBLE fraction_scales[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,
+ 0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001, 0.000000000001,
+ 0.0000000000001, 0.00000000000001, 0.000000000000001, 0.0000000000000001
+ };
+static FX_BOOL IsAlpha(FX_WCHAR c)
+{
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
+}
+CXFA_LocaleValue::CXFA_LocaleValue()
+{
+ m_dwType = XFA_VT_NULL;
+ m_bValid = TRUE;
+ m_pLocaleMgr = NULL;
+}
+CXFA_LocaleValue::CXFA_LocaleValue(const CXFA_LocaleValue& value)
+{
+ m_dwType = XFA_VT_NULL;
+ m_bValid = TRUE;
+ m_pLocaleMgr = NULL;
+ *this = value;
+}
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType, CXFA_LocaleMgr* pLocaleMgr)
+{
+ m_dwType = dwType;
+ m_bValid = (m_dwType != XFA_VT_NULL);
+ m_pLocaleMgr = pLocaleMgr;
+}
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType, const CFX_WideString& wsValue, CXFA_LocaleMgr* pLocaleMgr)
+{
+ m_wsValue = wsValue;
+ m_dwType = dwType;
+ m_pLocaleMgr = pLocaleMgr;
+ m_bValid = ValidateCanonicalValue(wsValue, dwType);
+}
+CXFA_LocaleValue::CXFA_LocaleValue(FX_DWORD dwType, const CFX_WideString& wsValue, const CFX_WideString& wsFormat, IFX_Locale* pLocale, CXFA_LocaleMgr* pLocaleMgr)
+{
+ m_pLocaleMgr = pLocaleMgr;
+ m_bValid = TRUE;
+ m_dwType = dwType;
+ m_bValid = ParsePatternValue(wsValue, wsFormat, pLocale);
+}
+CXFA_LocaleValue& CXFA_LocaleValue::operator = (const CXFA_LocaleValue& value)
+{
+ m_wsValue = value.m_wsValue;
+ m_dwType = value.m_dwType;
+ m_bValid = value.m_bValid;
+ m_pLocaleMgr = value.m_pLocaleMgr;
+ return *this;
+}
+CXFA_LocaleValue::~CXFA_LocaleValue()
+{
+}
+static FX_LOCALECATEGORY XFA_ValugeCategory(FX_LOCALECATEGORY eCategory, FX_DWORD dwValueType)
+{
+ if (eCategory == FX_LOCALECATEGORY_Unknown) {
+ switch (dwValueType) {
+ case XFA_VT_BOOLEAN:
+ case XFA_VT_INTEGER:
+ case XFA_VT_DECIMAL:
+ case XFA_VT_FLOAT:
+ return FX_LOCALECATEGORY_Num;
+ case XFA_VT_TEXT:
+ return FX_LOCALECATEGORY_Text;
+ case XFA_VT_DATE:
+ return FX_LOCALECATEGORY_Date;
+ case XFA_VT_TIME:
+ return FX_LOCALECATEGORY_Time;
+ case XFA_VT_DATETIME:
+ return FX_LOCALECATEGORY_DateTime;
+ }
+ }
+ return eCategory;
+}
+FX_BOOL CXFA_LocaleValue::ValidateValue(const CFX_WideString& wsValue, const CFX_WideString& wsPattern, IFX_Locale* pLocale, CFX_WideString* pMatchFormat )
+{
+ CFX_WideString wsOutput;
+ IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
+ if (pLocale) {
+ m_pLocaleMgr->SetDefLocale(pLocale);
+ }
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+ CFX_WideStringArray wsPatterns;
+ pFormat->SplitFormatString(wsPattern, wsPatterns);
+ FX_BOOL bRet = FALSE;
+ FX_INT32 iCount = wsPatterns.GetSize();
+ FX_INT32 i = 0;
+ for (; i < iCount && !bRet; i++) {
+ CFX_WideString wsFormat = wsPatterns[i];
+ FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
+ eCategory = XFA_ValugeCategory(eCategory, m_dwType);
+ switch (eCategory) {
+ case FX_LOCALECATEGORY_Null:
+ bRet = pFormat->ParseNull(wsValue, wsFormat);
+ if (!bRet) {
+ bRet = wsValue.IsEmpty();
+ }
+ break;
+ case FX_LOCALECATEGORY_Zero:
+ bRet = pFormat->ParseZero(wsValue, wsFormat);
+ if (!bRet) {
+ bRet = wsValue == FX_WSTRC(L"0");
+ }
+ break;
+ case FX_LOCALECATEGORY_Num: {
+ CFX_WideString fNum;
+ bRet = pFormat->ParseNum(wsValue, wsFormat, fNum);
+ if (!bRet) {
+ bRet = pFormat->FormatNum(wsValue, wsFormat, wsOutput);
+ }
+ break;
+ }
+ case FX_LOCALECATEGORY_Text:
+ bRet = pFormat->ParseText(wsValue, wsFormat, wsOutput);
+ wsOutput.Empty();
+ if (!bRet) {
+ bRet = pFormat->FormatText(wsValue, wsFormat, wsOutput);
+ }
+ break;
+ case FX_LOCALECATEGORY_Date: {
+ CFX_Unitime dt;
+ bRet = ValidateCanonicalDate(wsValue, dt);
+ if (!bRet) {
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date, dt);
+ if (!bRet) {
+ bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, FX_DATETIMETYPE_Date);
+ }
+ }
+ break;
+ }
+ case FX_LOCALECATEGORY_Time: {
+ CFX_Unitime dt;
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt);
+ if (!bRet) {
+ bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, FX_DATETIMETYPE_Time);
+ }
+ break;
+ }
+ case FX_LOCALECATEGORY_DateTime: {
+ CFX_Unitime dt;
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_DateTime, dt);
+ if (!bRet) {
+ bRet = pFormat->FormatDateTime(wsValue, wsFormat, wsOutput, FX_DATETIMETYPE_DateTime);
+ }
+ break;
+ }
+ default:
+ bRet = FALSE;
+ break;
+ }
+ }
+ if (bRet && pMatchFormat) {
+ *pMatchFormat = wsPatterns[i - 1];
+ }
+ pFormat->Release();
+ if (pLocale) {
+ m_pLocaleMgr->SetDefLocale(locale);
+ }
+ return bRet;
+}
+CFX_WideString CXFA_LocaleValue::GetValue() const
+{
+ return m_wsValue;
+}
+FX_DWORD CXFA_LocaleValue::GetType() const
+{
+ return m_dwType;
+}
+void CXFA_LocaleValue::SetValue(const CFX_WideString& wsValue, FX_DWORD dwType)
+{
+ m_wsValue = wsValue;
+ m_dwType = dwType;
+}
+CFX_WideString CXFA_LocaleValue::GetText() const
+{
+ if (m_bValid && m_dwType == XFA_VT_TEXT) {
+ return m_wsValue;
+ }
+ return CFX_WideString();
+}
+FX_FLOAT CXFA_LocaleValue::GetNum() const
+{
+ if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER ||
+ m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) {
+ FX_INT64 nIntegral = 0;
+ FX_DWORD dwFractional = 0;
+ FX_INT32 nExponent = 0;
+ int cc = 0;
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+ FX_LPCWSTR str = (FX_LPCWSTR)m_wsValue;
+ int len = m_wsValue.GetLength();
+ while (XFA_IsSpace(str[cc]) && cc < len) {
+ cc++;
+ }
+ if (cc >= len) {
+ return 0;
+ }
+ if (str[0] == '+') {
+ cc++;
+ } else if (str[0] == '-') {
+ bNegative = TRUE;
+ cc++;
+ }
+ int nIntegralLen = 0;
+ while (cc < len) {
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) {
+ break;
+ }
+ nIntegral = nIntegral * 10 + str[cc] - '0';
+ cc ++;
+ nIntegralLen++;
+ }
+ nIntegral = bNegative ? -nIntegral : nIntegral;
+ int scale = 0;
+ double fraction = 0.0;
+ if (cc < len && str[cc] == '.') {
+ cc ++;
+ while (cc < len) {
+ fraction += fraction_scales[scale] * (str[cc] - '0');
+ scale ++;
+ cc ++;
+ if (scale == sizeof fraction_scales / sizeof(double)
+ || !XFA_IsDigit(str[cc])) {
+ break;
+ }
+ }
+ dwFractional = (FX_DWORD)(fraction * 4294967296.0);
+ }
+ if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+ cc ++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
+ break;
+ }
+ nExponent = nExponent * 10 + str[cc] - '0';
+ cc ++;
+ }
+ nExponent = bExpSign ? -nExponent : nExponent;
+ }
+ FX_FLOAT fValue = (FX_FLOAT)(dwFractional / 4294967296.0);
+ fValue = nIntegral + (nIntegral >= 0 ? fValue : -fValue);
+ if (nExponent != 0) {
+ fValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
+ }
+ return fValue;
+ }
+ return 0;
+}
+FX_DOUBLE CXFA_LocaleValue::GetDoubleNum() const
+{
+ if (m_bValid && (m_dwType == XFA_VT_BOOLEAN || m_dwType == XFA_VT_INTEGER ||
+ m_dwType == XFA_VT_DECIMAL || m_dwType == XFA_VT_FLOAT)) {
+ FX_INT64 nIntegral = 0;
+ FX_DWORD dwFractional = 0;
+ FX_INT32 nExponent = 0;
+ FX_INT32 cc = 0;
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+ FX_LPCWSTR str = (FX_LPCWSTR)m_wsValue;
+ int len = m_wsValue.GetLength();
+ while (XFA_IsSpace(str[cc]) && cc < len) {
+ cc++;
+ }
+ if (cc >= len) {
+ return 0;
+ }
+ if (str[0] == '+') {
+ cc++;
+ } else if (str[0] == '-') {
+ bNegative = TRUE;
+ cc++;
+ }
+ FX_INT32 nIntegralLen = 0;
+ while (cc < len) {
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc]) || nIntegralLen > 17) {
+ break;
+ }
+ nIntegral = nIntegral * 10 + str[cc] - '0';
+ cc ++;
+ nIntegralLen++;
+ }
+ nIntegral = bNegative ? -nIntegral : nIntegral;
+ FX_INT32 scale = 0;
+ FX_DOUBLE fraction = 0.0;
+ if (cc < len && str[cc] == '.') {
+ cc ++;
+ while (cc < len) {
+ fraction += fraction_scales[scale] * (str[cc] - '0');
+ scale ++;
+ cc ++;
+ if (scale == sizeof fraction_scales / sizeof(FX_DOUBLE)
+ || !XFA_IsDigit(str[cc])) {
+ break;
+ }
+ }
+ dwFractional = (FX_DWORD)(fraction * 4294967296.0);
+ }
+ if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+ cc ++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
+ break;
+ }
+ nExponent = nExponent * 10 + str[cc] - '0';
+ cc ++;
+ }
+ nExponent = bExpSign ? -nExponent : nExponent;
+ }
+ FX_DOUBLE dValue = (dwFractional / 4294967296.0);
+ dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
+ if (nExponent != 0) {
+ dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
+ }
+ return dValue;
+ }
+ return 0;
+}
+CFX_Unitime CXFA_LocaleValue::GetDate() const
+{
+ if (m_bValid && m_dwType == XFA_VT_DATE) {
+ CFX_Unitime dt;
+ FX_DateFromCanonical(m_wsValue, dt);
+ return dt;
+ }
+ return CFX_Unitime();
+}
+CFX_Unitime CXFA_LocaleValue::GetTime() const
+{
+ if (m_bValid && m_dwType == XFA_VT_TIME) {
+ CFX_Unitime dt(0);
+ FXSYS_assert(m_pLocaleMgr);
+ FX_TimeFromCanonical(m_wsValue, dt, m_pLocaleMgr->GetDefLocale());
+ return dt;
+ }
+ return CFX_Unitime();
+}
+CFX_Unitime CXFA_LocaleValue::GetDateTime() const
+{
+ if (m_bValid && m_dwType == XFA_VT_DATETIME) {
+ FX_INT32 index = m_wsValue.Find('T');
+ CFX_Unitime dt;
+ FX_DateFromCanonical(m_wsValue.Left(index), dt);
+ FXSYS_assert(m_pLocaleMgr);
+ FX_TimeFromCanonical(m_wsValue.Right(m_wsValue.GetLength() - index - 1), dt, m_pLocaleMgr->GetDefLocale());
+ return dt;
+ }
+ return CFX_Unitime();
+}
+FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText)
+{
+ m_dwType = XFA_VT_TEXT;
+ m_wsValue = wsText;
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetText(const CFX_WideString& wsText, const CFX_WideString& wsFormat, IFX_Locale* pLocale)
+{
+ m_dwType = XFA_VT_TEXT;
+ return m_bValid = ParsePatternValue(wsText, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetNum(FX_FLOAT fNum)
+{
+ m_dwType = XFA_VT_FLOAT;
+ m_wsValue.Format((FX_LPCWSTR)L"%.8g", (FX_DOUBLE)fNum);
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetNum(const CFX_WideString& wsNum, const CFX_WideString& wsFormat,
+ IFX_Locale* pLocale)
+{
+ m_dwType = XFA_VT_FLOAT;
+ return m_bValid = ParsePatternValue(wsNum, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetDate(const CFX_Unitime& d)
+{
+ m_dwType = XFA_VT_DATE;
+ m_wsValue.Format((FX_LPCWSTR)L"%04d-%02d-%02d", d.GetYear(), d.GetMonth(), d.GetDay());
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetDate(const CFX_WideString& wsDate, const CFX_WideString& wsFormat, IFX_Locale* pLocale)
+{
+ m_dwType = XFA_VT_DATE;
+ return m_bValid = ParsePatternValue(wsDate, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetTime(const CFX_Unitime& t)
+{
+ m_dwType = XFA_VT_TIME;
+ m_wsValue.Format((FX_LPCWSTR)L"%02d:%02d:%02d", t.GetHour(), t.GetMinute(), t.GetSecond());
+ if (t.GetMillisecond() > 0) {
+ CFX_WideString wsTemp;
+ wsTemp.Format((FX_LPCWSTR)L"%:03d", t.GetMillisecond());
+ m_wsValue += wsTemp;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetTime(const CFX_WideString& wsTime, const CFX_WideString& wsFormat, IFX_Locale* pLocale)
+{
+ m_dwType = XFA_VT_TIME;
+ return m_bValid = ParsePatternValue(wsTime, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_Unitime& dt)
+{
+ m_dwType = XFA_VT_DATETIME;
+ m_wsValue.Format((FX_LPCWSTR)L"%04d-%02d-%02dT%02d:%02d:%02d", dt.GetYear(), dt.GetMonth(), dt.GetDay(),
+ dt.GetHour(), dt.GetMinute(), dt.GetSecond());
+ if (dt.GetMillisecond() > 0) {
+ CFX_WideString wsTemp;
+ wsTemp.Format((FX_LPCWSTR)L"%:03d", dt.GetMillisecond());
+ m_wsValue += wsTemp;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::SetDateTime(const CFX_WideString& wsDateTime,
+ const CFX_WideString& wsFormat, IFX_Locale* pLocale)
+{
+ m_dwType = XFA_VT_DATETIME;
+ return m_bValid = ParsePatternValue(wsDateTime, wsFormat, pLocale);
+}
+FX_BOOL CXFA_LocaleValue::FormatPatterns(CFX_WideString& wsResult, const CFX_WideString& wsFormat, IFX_Locale* pLocale,
+ XFA_VALUEPICTURE eValueType) const
+{
+ wsResult.Empty();
+ FX_BOOL bRet = FALSE;
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+ CFX_WideStringArray wsPatterns;
+ pFormat->SplitFormatString(wsFormat, wsPatterns);
+ FX_INT32 iCount = wsPatterns.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ bRet = FormatSinglePattern(wsResult, wsPatterns[i], pLocale, eValueType);
+ if (bRet) {
+ break;
+ }
+ }
+ pFormat->Release();
+ return bRet;
+}
+FX_BOOL CXFA_LocaleValue::FormatSinglePattern(CFX_WideString& wsResult, const CFX_WideString& wsFormat, IFX_Locale* pLocale,
+ XFA_VALUEPICTURE eValueType) const
+{
+ IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
+ if (pLocale) {
+ m_pLocaleMgr->SetDefLocale(pLocale);
+ }
+ wsResult.Empty();
+ FX_BOOL bRet = FALSE;
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+ FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
+ eCategory = XFA_ValugeCategory(eCategory, m_dwType);
+ switch (eCategory) {
+ case FX_LOCALECATEGORY_Null:
+ if (m_wsValue.IsEmpty()) {
+ bRet = pFormat->FormatNull(wsFormat, wsResult);
+ }
+ break;
+ case FX_LOCALECATEGORY_Zero:
+ if (m_wsValue == FX_WSTRC(L"0")) {
+ bRet = pFormat->FormatZero(wsFormat, wsResult);
+ }
+ break;
+ case FX_LOCALECATEGORY_Num:
+ bRet = pFormat->FormatNum(m_wsValue, wsFormat, wsResult);
+ break;
+ case FX_LOCALECATEGORY_Text:
+ bRet = pFormat->FormatText(m_wsValue, wsFormat, wsResult);
+ break;
+ case FX_LOCALECATEGORY_Date:
+ bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, FX_DATETIMETYPE_Date);
+ break;
+ case FX_LOCALECATEGORY_Time:
+ bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, FX_DATETIMETYPE_Time);
+ break;
+ case FX_LOCALECATEGORY_DateTime:
+ bRet = pFormat->FormatDateTime(m_wsValue, wsFormat, wsResult, FX_DATETIMETYPE_DateTime);
+ break;
+ default:
+ wsResult = m_wsValue;
+ bRet = TRUE;
+ }
+ pFormat->Release();
+ if (!bRet && (eCategory != FX_LOCALECATEGORY_Num || eValueType != XFA_VALUEPICTURE_Display)) {
+ wsResult = m_wsValue;
+ }
+ if (pLocale) {
+ m_pLocaleMgr->SetDefLocale(locale);
+ }
+ return bRet;
+}
+static FX_BOOL XFA_ValueSplitDateTime(const CFX_WideString& wsDateTime, CFX_WideString& wsDate, CFX_WideString& wsTime)
+{
+ wsDate = L"";
+ wsTime = L"";
+ if (wsDateTime.IsEmpty()) {
+ return FALSE;
+ }
+ int nSplitIndex = -1;
+ nSplitIndex = wsDateTime.Find('T');
+ if (nSplitIndex < 0) {
+ nSplitIndex = wsDateTime.Find(' ');
+ }
+ if (nSplitIndex < 0) {
+ return FALSE;
+ }
+ wsDate = wsDateTime.Left(nSplitIndex);
+ wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalValue(const CFX_WideString& wsValue, FX_DWORD dwVType)
+{
+ if (wsValue.IsEmpty()) {
+ return TRUE;
+ }
+ CFX_Unitime dt;
+ switch (dwVType) {
+ case XFA_VT_DATE: {
+ if (ValidateCanonicalDate(wsValue, dt)) {
+ return TRUE;
+ }
+ CFX_WideString wsDate, wsTime;
+ if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && ValidateCanonicalDate(wsDate, dt)) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ case XFA_VT_TIME: {
+ if (ValidateCanonicalTime(wsValue)) {
+ return TRUE;
+ }
+ CFX_WideString wsDate, wsTime;
+ if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && ValidateCanonicalTime(wsTime)) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ case XFA_VT_DATETIME: {
+ CFX_WideString wsDate, wsTime;
+ if (XFA_ValueSplitDateTime(wsValue, wsDate, wsTime) && ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime)) {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalDate(const CFX_WideString& wsDate, CFX_Unitime& unDate)
+{
+ const FX_WORD LastDay[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ const FX_WORD wCountY = 4, wCountM = 2, wCountD = 2;
+ int nLen = wsDate.GetLength();
+ if (nLen < wCountY || nLen > wCountY + wCountM + wCountD + 2) {
+ return FALSE;
+ }
+ FX_BOOL bSymbol = (wsDate.Find(0x2D) == -1) ? FALSE : TRUE;
+ FX_WORD wYear = 0, wMonth = 0, wDay = 0;
+ FX_LPCWSTR pDate = (FX_LPCWSTR)wsDate;
+ int nIndex = 0, nStart = 0;
+ while (pDate[nIndex] != '\0' && nIndex < wCountY) {
+ if (!XFA_IsDigit(pDate[nIndex])) {
+ return FALSE;
+ }
+ wYear = (pDate[nIndex] - '0') + wYear * 10;
+ nIndex++;
+ }
+ if (bSymbol) {
+ if (pDate[nIndex] != 0x2D) {
+ return FALSE;
+ }
+ nIndex++;
+ }
+ nStart = nIndex;
+ while (pDate[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) {
+ if (!XFA_IsDigit(pDate[nIndex])) {
+ return FALSE;
+ }
+ wMonth = (pDate[nIndex] - '0') + wMonth * 10;
+ nIndex++;
+ }
+ if (bSymbol) {
+ if (pDate[nIndex] != 0x2D) {
+ return FALSE;
+ }
+ nIndex++;
+ }
+ nStart = nIndex;
+ while (pDate[nIndex] != '\0' && nIndex - nStart < wCountD && nIndex < nLen) {
+ if (!XFA_IsDigit(pDate[nIndex])) {
+ return FALSE;
+ }
+ wDay = (pDate[nIndex] - '0') + wDay * 10;
+ nIndex++;
+ }
+ if (nIndex != nLen) {
+ return FALSE;
+ }
+ if (wYear < 1900 || wYear > 2029) {
+ return FALSE;
+ }
+ if (wMonth < 1 || wMonth > 12) {
+ if (wMonth == 0 && nLen == wCountY) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ if (wDay < 1) {
+ if (wDay == 0 && (nLen == wCountY + wCountM)) {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ if (wMonth == 2) {
+ if (wYear % 400 == 0 || (wYear % 100 != 0 && wYear % 4 == 0)) {
+ if (wDay > 29) {
+ return FALSE;
+ }
+ } else {
+ if (wDay > 28) {
+ return FALSE;
+ }
+ }
+ } else if (wDay > LastDay[wMonth - 1]) {
+ return FALSE;
+ }
+ CFX_Unitime ut;
+ ut.Set(wYear, wMonth, wDay);
+ unDate = unDate + ut;
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalTime(const CFX_WideString& wsTime)
+{
+ int nLen = wsTime.GetLength();
+ if (nLen < 2) {
+ return FALSE;
+ }
+ const FX_WORD wCountH = 2, wCountM = 2, wCountS = 2, wCountF = 3;
+ FX_BOOL bSymbol = (wsTime.Find(':') == -1) ? FALSE : TRUE;
+ FX_WORD wHour = 0, wMinute = 0, wSecond = 0, wFraction = 0;
+ FX_LPCWSTR pTime = (FX_LPCWSTR)wsTime;
+ int nIndex = 0, nStart = 0;
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountH) {
+ if (!XFA_IsDigit(pTime[nIndex])) {
+ return FALSE;
+ }
+ wHour = (pTime[nIndex] - '0') + wHour * 10;
+ nIndex++;
+ }
+ if (bSymbol) {
+ if (nIndex < nLen && pTime[nIndex] != ':') {
+ return FALSE;
+ }
+ nIndex++;
+ }
+ nStart = nIndex;
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) {
+ if (!XFA_IsDigit(pTime[nIndex])) {
+ return FALSE;
+ }
+ wMinute = (pTime[nIndex] - '0') + wMinute * 10;
+ nIndex++;
+ }
+ if (bSymbol) {
+ if (nIndex < nLen && pTime[nIndex] != ':') {
+ return FALSE;
+ }
+ nIndex++;
+ }
+ nStart = nIndex;
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountS && nIndex < nLen) {
+ if (!XFA_IsDigit(pTime[nIndex])) {
+ return FALSE;
+ }
+ wSecond = (pTime[nIndex] - '0') + wSecond * 10;
+ nIndex++;
+ }
+ if (wsTime.Find('.') > 0) {
+ if (pTime[nIndex] != '.') {
+ return FALSE;
+ }
+ nIndex++;
+ nStart = nIndex;
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountF && nIndex < nLen) {
+ if (!XFA_IsDigit(pTime[nIndex])) {
+ return FALSE;
+ }
+ wFraction = (pTime[nIndex] - '0') + wFraction * 10;
+ nIndex++;
+ }
+ }
+ if (nIndex < nLen) {
+ if (pTime[nIndex] == 'Z') {
+ nIndex++;
+ } else if (pTime[nIndex] == '-' || pTime[nIndex] == '+') {
+ FX_SHORT nOffsetH = 0, nOffsetM = 0;
+ nIndex++;
+ nStart = nIndex;
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountH && nIndex < nLen) {
+ if (!XFA_IsDigit(pTime[nIndex])) {
+ return FALSE;
+ }
+ nOffsetH = (pTime[nIndex] - '0') + nOffsetH * 10;
+ nIndex++;
+ }
+ if (bSymbol) {
+ if (nIndex < nLen && pTime[nIndex] != ':') {
+ return FALSE;
+ }
+ nIndex++;
+ }
+ nStart = nIndex;
+ while (pTime[nIndex] != '\0' && nIndex - nStart < wCountM && nIndex < nLen) {
+ if (!XFA_IsDigit(pTime[nIndex])) {
+ return FALSE;
+ }
+ nOffsetM = (pTime[nIndex] - '0') + nOffsetM * 10;
+ nIndex++;
+ }
+ if (nOffsetH > 12) {
+ return FALSE;
+ }
+ if (nOffsetM >= 60) {
+ return FALSE;
+ }
+ }
+ }
+ if (nIndex != nLen) {
+ return FALSE;
+ }
+ if (wHour >= 24) {
+ return FALSE;
+ }
+ if (wMinute >= 60) {
+ return FALSE;
+ }
+ if (wSecond >= 60) {
+ return FALSE;
+ }
+ if (wFraction > 999) {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_LocaleValue::ValidateCanonicalDateTime(const CFX_WideString& wsDateTime)
+{
+ CFX_WideString wsDate, wsTime;
+ if (wsDateTime.IsEmpty()) {
+ return FALSE;
+ }
+ int nSplitIndex = -1;
+ nSplitIndex = wsDateTime.Find('T');
+ if (nSplitIndex < 0) {
+ nSplitIndex = wsDateTime.Find(' ');
+ }
+ if (nSplitIndex < 0) {
+ return FALSE;
+ }
+ wsDate = wsDateTime.Left(nSplitIndex);
+ wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
+ CFX_Unitime dt;
+ return ValidateCanonicalDate(wsDate, dt) && ValidateCanonicalTime(wsTime);
+}
+FX_BOOL CXFA_LocaleValue::ParsePatternValue(const CFX_WideString& wsValue, const CFX_WideString& wsPattern, IFX_Locale* pLocale)
+{
+ IFX_Locale* locale = m_pLocaleMgr->GetDefLocale();
+ if (pLocale) {
+ m_pLocaleMgr->SetDefLocale(pLocale);
+ }
+ IFX_FormatString* pFormat = IFX_FormatString::Create(m_pLocaleMgr, FALSE);
+ CFX_WideStringArray wsPatterns;
+ pFormat->SplitFormatString(wsPattern, wsPatterns);
+ FX_BOOL bRet = FALSE;
+ FX_INT32 iCount = wsPatterns.GetSize();
+ for (FX_INT32 i = 0; i < iCount && !bRet; i++) {
+ CFX_WideString wsFormat = wsPatterns[i];
+ FX_LOCALECATEGORY eCategory = pFormat->GetCategory(wsFormat);
+ eCategory = XFA_ValugeCategory(eCategory, m_dwType);
+ switch (eCategory) {
+ case FX_LOCALECATEGORY_Null:
+ bRet = pFormat->ParseNull(wsValue, wsFormat);
+ if (bRet) {
+ m_wsValue.Empty();
+ }
+ break;
+ case FX_LOCALECATEGORY_Zero:
+ bRet = pFormat->ParseZero(wsValue, wsFormat);
+ if (bRet) {
+ m_wsValue = FX_WSTRC(L"0");
+ }
+ break;
+ case FX_LOCALECATEGORY_Num: {
+ CFX_WideString fNum;
+ bRet = pFormat->ParseNum(wsValue, wsFormat, fNum);
+ if (bRet) {
+ m_wsValue = fNum;
+ }
+ break;
+ }
+ case FX_LOCALECATEGORY_Text:
+ bRet = pFormat->ParseText(wsValue, wsFormat, m_wsValue);
+ break;
+ case FX_LOCALECATEGORY_Date: {
+ CFX_Unitime dt;
+ bRet = ValidateCanonicalDate(wsValue, dt);
+ if (!bRet) {
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Date, dt);
+ }
+ if (bRet) {
+ SetDate(dt);
+ }
+ break;
+ }
+ case FX_LOCALECATEGORY_Time: {
+ CFX_Unitime dt;
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_Time, dt);
+ if (bRet) {
+ SetTime(dt);
+ }
+ break;
+ }
+ case FX_LOCALECATEGORY_DateTime: {
+ CFX_Unitime dt;
+ bRet = pFormat->ParseDateTime(wsValue, wsFormat, FX_DATETIMETYPE_DateTime, dt);
+ if (bRet) {
+ SetDateTime(dt);
+ }
+ break;
+ }
+ default:
+ m_wsValue = wsValue;
+ bRet = TRUE;
+ break;
+ }
+ }
+ if (!bRet) {
+ m_wsValue = wsValue;
+ }
+ pFormat->Release();
+ if (pLocale) {
+ m_pLocaleMgr->SetDefLocale(locale);
+ }
+ return bRet;
+}
+void CXFA_LocaleValue::GetNumbericFormat(CFX_WideString &wsFormat, FX_INT32 nIntLen, FX_INT32 nDecLen, FX_BOOL bSign )
+{
+ FXSYS_assert(wsFormat.IsEmpty());
+ FXSYS_assert(nIntLen >= -1 && nDecLen >= -1);
+ FX_INT32 nTotalLen \
+ = (nIntLen >= 0 ? nIntLen : 2) \
+ + (bSign ? 1 : 0) \
+ + (nDecLen >= 0 ? nDecLen : 2) \
+ + (nDecLen == 0 ? 0 : 1);
+ FX_LPWSTR lpBuf = wsFormat.GetBuffer(nTotalLen);
+ FX_INT32 nPos = 0;
+ if (bSign) {
+ lpBuf[nPos++] = L's';
+ }
+ if (nIntLen == -1) {
+ lpBuf[nPos++] = L'z';
+ lpBuf[nPos++] = L'*';
+ } else {
+ while (nIntLen) {
+ lpBuf[nPos++] = L'z';
+ nIntLen --;
+ }
+ }
+ if (nDecLen != 0) {
+ lpBuf[nPos++] = L'.';
+ }
+ if (nDecLen == -1) {
+ lpBuf[nPos++] = L'z';
+ lpBuf[nPos++] = L'*';
+ } else {
+ while (nDecLen) {
+ lpBuf[nPos++] = L'z';
+ nDecLen --;
+ }
+ }
+ wsFormat.ReleaseBuffer(nTotalLen);
+}
+FX_BOOL CXFA_LocaleValue::ValidateNumericTemp(CFX_WideString& wsNumeric, CFX_WideString& wsFormat, IFX_Locale* pLocale , FX_INT32* pos )
+{
+ if (wsFormat.IsEmpty() || wsNumeric.IsEmpty()) {
+ return TRUE;
+ }
+ FX_LPCWSTR pNum = FX_LPCWSTR(wsNumeric);
+ FX_LPCWSTR pFmt = FX_LPCWSTR(wsFormat);
+ FX_INT32 n = 0, nf = 0;
+ FX_WCHAR c = pNum[n];
+ FX_WCHAR cf = pFmt[nf];
+ if (cf == L's') {
+ if (c == L'-' || c == L'+') {
+ ++n;
+ }
+ ++nf;
+ }
+ FX_BOOL bLimit = TRUE;
+ FX_INT32 nCount = wsNumeric.GetLength();
+ FX_INT32 nCountFmt = wsFormat.GetLength();
+ while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) && XFA_IsDigit(c = pNum[n])) {
+ if (bLimit == TRUE) {
+ if ((cf = pFmt[nf]) == L'*') {
+ bLimit = FALSE;
+ } else if (cf == L'z') {
+ nf ++;
+ } else {
+ return FALSE;
+ }
+ }
+ n ++;
+ }
+ if (n == nCount) {
+ return TRUE;
+ }
+ if (nf == nCountFmt) {
+ return FALSE;
+ }
+ while (nf < nCountFmt && (cf = pFmt[nf]) != L'.') {
+ FXSYS_assert(cf == L'z' || cf == L'*');
+ ++nf;
+ }
+ CFX_WideString wsDecimalSymbol;
+ if (pLocale) {
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDecimalSymbol);
+ } else {
+ wsDecimalSymbol = CFX_WideString(L'.');
+ }
+ if (pFmt[nf] != L'.') {
+ return FALSE;
+ }
+ if (wsDecimalSymbol != CFX_WideStringC(c) && c != L'.') {
+ return FALSE;
+ }
+ ++ nf;
+ ++ n;
+ bLimit = TRUE;
+ while (n < nCount && (bLimit ? nf < nCountFmt : TRUE) && XFA_IsDigit(c = pNum[n])) {
+ if (bLimit == TRUE) {
+ if ((cf = pFmt[nf]) == L'*') {
+ bLimit = FALSE;
+ } else if (cf == L'z') {
+ nf ++;
+ } else {
+ return FALSE;
+ }
+ }
+ n ++;
+ }
+ return n == nCount;
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_object_imp.cpp b/xfa/src/fxfa/src/parser/xfa_object_imp.cpp
new file mode 100644
index 0000000000..54f29a5c94
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_object_imp.cpp
@@ -0,0 +1,5125 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_basic_imp.h"
+#include "xfa_document_layout_imp.h"
+CXFA_Object::CXFA_Object(CXFA_Document* pDocument, FX_DWORD uFlags)
+ : m_pDocument(pDocument)
+ , m_uFlags(uFlags)
+{
+}
+void CXFA_Object::GetClassName(CFX_WideStringC &wsName) const
+{
+ XFA_LPCELEMENTINFO pElement = XFA_GetElementByID(GetClassID());
+ ASSERT(pElement != NULL);
+ wsName = pElement->pName;
+}
+FX_UINT32 CXFA_Object::GetClassHashCode() const
+{
+ XFA_LPCELEMENTINFO pElement = XFA_GetElementByID(GetClassID());
+ ASSERT(pElement != NULL);
+ return pElement->uHash;
+}
+XFA_ELEMENT CXFA_Object::GetClassID() const
+{
+ if (IsNode()) {
+ return ((const CXFA_Node*)this)->GetClassID();
+ } else if(IsOrdinaryObject()) {
+ return ((const CXFA_OrdinaryObject*)this)->GetClassID();
+ } else if(IsNodeList()) {
+ return ((const CXFA_NodeList*)this)->GetClassID();
+ } else if(IsOrdinaryList()) {
+ return XFA_ELEMENT_List;
+ }
+ ASSERT(FALSE);
+ return (XFA_ELEMENT)0;
+}
+void CXFA_Object::Script_ObjectClass_ClassName(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ CFX_WideStringC className;
+ GetClassName(className);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(className.GetPtr(), className.GetLength()));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+void CXFA_Object::ThrowScriptErrorMessage(FX_INT32 iStringID, ...)
+{
+ IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
+ FXSYS_assert(pAppProvider);
+ CFX_WideString wsFormat;
+ pAppProvider->LoadString(iStringID, wsFormat);
+ CFX_WideString wsMessage;
+ va_list arg_ptr;
+ va_start(arg_ptr, iStringID);
+ wsMessage.FormatV((FX_LPCWSTR)wsFormat, arg_ptr);
+ va_end(arg_ptr);
+ FXJSE_ThrowMessage(FX_BSTRC(""), FX_UTF8Encode(wsMessage, wsMessage.GetLength()));
+}
+static void XFA_DeleteWideString(FX_LPVOID pData)
+{
+ if (pData) {
+ delete (CFX_WideString*)pData;
+ }
+}
+static void XFA_CopyWideString(FX_LPVOID& pData)
+{
+ if (pData) {
+ CFX_WideString* pNewData = FX_NEW CFX_WideString(*(CFX_WideString*)pData);
+ pData = pNewData;
+ }
+}
+static XFA_MAPDATABLOCKCALLBACKINFO deleteWideStringCallBack = {XFA_DeleteWideString, XFA_CopyWideString};
+static XFA_OBJECTTYPE XFA_GetElementObjectType(XFA_ELEMENT eElement)
+{
+ XFA_LPCELEMENTINFO pElement = XFA_GetElementByID(eElement);
+ ASSERT(pElement != NULL);
+ return (XFA_OBJECTTYPE)pElement->eObjectType;
+}
+CXFA_Node::CXFA_Node(CXFA_Document *pDoc, FX_WORD ePacket, XFA_ELEMENT eElement)
+ : CXFA_Object(pDoc, XFA_GetElementObjectType(eElement))
+ , m_pParent(NULL)
+ , m_pNext(NULL)
+ , m_pChild(NULL)
+ , m_pLastChild(NULL)
+ , m_pXMLNode(NULL)
+ , m_ePacket(ePacket)
+ , m_eNodeClass(eElement)
+ , m_dwNameHash(0)
+ , m_pAuxNode(NULL)
+ , m_pMapModuleData(NULL)
+{
+ ASSERT(m_pDocument != NULL);
+}
+CXFA_Node::~CXFA_Node()
+{
+ FXSYS_assert(m_pParent == NULL);
+ RemoveMapModuleKey();
+ CXFA_Node *pNext, *pNode = m_pChild;
+ while (pNode) {
+ pNext = pNode->m_pNext;
+ pNode->m_pParent = NULL;
+ delete pNode;
+ pNode = pNext;
+ }
+ if (m_pXMLNode && HasFlag(XFA_NODEFLAG_OwnXMLNode)) {
+ m_pXMLNode->Release();
+ }
+}
+CXFA_Node* CXFA_Node::Clone(FX_BOOL bRecursive)
+{
+ IXFA_ObjFactory *pFactory = m_pDocument->GetParser()->GetFactory();
+ CXFA_Node *pClone = pFactory->CreateNode(m_ePacket, m_eNodeClass);
+ if(!pClone) {
+ return NULL;
+ }
+ MergeAllData(pClone);
+ pClone->UpdateNameHash();
+ if (IsNeedSavingXMLNode()) {
+ IFDE_XMLNode* pCloneXML = NULL;
+ if (IsAttributeInXML()) {
+ CFX_WideString wsName;
+ this->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+ IFDE_XMLElement* pCloneXMLElement = IFDE_XMLElement::Create(wsName);
+ CFX_WideStringC wsValue = this->GetCData(XFA_ATTRIBUTE_Value);
+ if (!wsValue.IsEmpty()) {
+ pCloneXMLElement->SetTextData(wsValue);
+ }
+ pCloneXML = pCloneXMLElement;
+ pCloneXMLElement = NULL;
+ pClone->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
+ } else {
+ pCloneXML = m_pXMLNode->Clone(FALSE);
+ }
+ pClone->SetXMLMappingNode(pCloneXML);
+ pClone->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+ }
+ if (bRecursive) {
+ for(CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ pClone->InsertChild(pChild->Clone(bRecursive));
+ }
+ }
+ pClone->SetFlag(XFA_NODEFLAG_Initialized);
+ pClone->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+ return pClone;
+}
+CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem) const
+{
+ switch (eItem) {
+ case XFA_NODEITEM_NextSibling:
+ return m_pNext;
+ case XFA_NODEITEM_FirstChild:
+ return m_pChild;
+ case XFA_NODEITEM_Parent:
+ return m_pParent;
+ case XFA_NODEITEM_PrevSibling:
+ if (m_pParent) {
+ CXFA_Node *pSibling = m_pParent->m_pChild;
+ CXFA_Node *pPrev = NULL;
+ while (pSibling && pSibling != this) {
+ pPrev = pSibling;
+ pSibling = pSibling->m_pNext;
+ }
+ return pPrev;
+ }
+ return NULL;
+ default:
+ break;
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_Node::GetNodeItem(XFA_NODEITEM eItem, XFA_OBJECTTYPE eType) const
+{
+ CXFA_Node *pNode = NULL;
+ switch (eItem) {
+ case XFA_NODEITEM_NextSibling:
+ pNode = m_pNext;
+ if (eType != XFA_OBJECTTYPEMASK)
+ while (pNode && pNode->GetObjectType() != eType) {
+ pNode = pNode->m_pNext;
+ }
+ break;
+ case XFA_NODEITEM_FirstChild:
+ pNode = m_pChild;
+ if (eType != XFA_OBJECTTYPEMASK)
+ while (pNode && pNode->GetObjectType() != eType) {
+ pNode = pNode->m_pNext;
+ }
+ break;
+ case XFA_NODEITEM_Parent:
+ pNode = m_pParent;
+ if (eType != XFA_OBJECTTYPEMASK)
+ while (pNode && pNode->GetObjectType() != eType) {
+ pNode = pNode->m_pParent;
+ }
+ break;
+ case XFA_NODEITEM_PrevSibling:
+ if (m_pParent) {
+ CXFA_Node *pSibling = m_pParent->m_pChild;
+ while (pSibling && pSibling != this) {
+ if (eType == XFA_OBJECTTYPEMASK || eType == pSibling->GetObjectType()) {
+ pNode = pSibling;
+ }
+ pSibling = pSibling->m_pNext;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return pNode;
+}
+FX_INT32 CXFA_Node::GetNodeList(CXFA_NodeArray &nodes, FX_DWORD dwTypeFilter , XFA_ELEMENT eElementFilter , FX_INT32 iLevel )
+{
+ if (--iLevel < 0) {
+ return nodes.GetSize();
+ }
+ if (eElementFilter != XFA_ELEMENT_UNKNOWN) {
+ CXFA_Node *pChild = m_pChild;
+ while (pChild) {
+ if (pChild->GetClassID() == eElementFilter) {
+ nodes.Add(pChild);
+ if (iLevel > 0) {
+ GetNodeList(nodes, dwTypeFilter, eElementFilter, iLevel);
+ }
+ }
+ pChild = pChild->m_pNext;
+ }
+ } else if (dwTypeFilter == (XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties)) {
+ CXFA_Node *pChild = m_pChild;
+ while (pChild) {
+ nodes.Add(pChild);
+ if (iLevel > 0) {
+ GetNodeList(nodes, dwTypeFilter, eElementFilter, iLevel);
+ }
+ pChild = pChild->m_pNext;
+ }
+ } else if (dwTypeFilter != 0) {
+ FX_BOOL bFilterChildren = (dwTypeFilter & XFA_NODEFILTER_Children) != 0;
+ FX_BOOL bFilterProperties = (dwTypeFilter & XFA_NODEFILTER_Properties) != 0;
+ FX_BOOL bFilterOneOfProperties = (dwTypeFilter & XFA_NODEFILTER_OneOfProperty) != 0;
+ CXFA_Node *pChild = m_pChild;
+ while (pChild) {
+ XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(GetClassID(), pChild->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+ if (pPropert) {
+ if (bFilterProperties) {
+ nodes.Add(pChild);
+ } else if (bFilterOneOfProperties && (pPropert->uFlags & XFA_PROPERTYFLAG_OneOf)) {
+ nodes.Add(pChild);
+ } else if(bFilterChildren && (pChild->GetClassID() == XFA_ELEMENT_Variables || pChild->GetClassID() == XFA_ELEMENT_PageSet)) {
+ nodes.Add(pChild);
+ }
+ } else {
+ if (bFilterChildren) {
+ nodes.Add(pChild);
+ }
+ }
+ pChild = pChild->m_pNext;
+ }
+ if (bFilterOneOfProperties && nodes.GetSize() < 1) {
+ FX_INT32 iProperties = 0;
+ XFA_LPCPROPERTY pProperty = XFA_GetElementProperties(GetClassID(), iProperties);
+ if (pProperty == NULL || iProperties < 1) {
+ return 0;
+ }
+ for (FX_INT32 i = 0; i < iProperties; i++) {
+ if (pProperty[i].uFlags & XFA_PROPERTYFLAG_DefaultOneOf) {
+ IXFA_ObjFactory *pFactory = m_pDocument->GetParser()->GetFactory();
+ XFA_LPCPACKETINFO pPacket = XFA_GetPacketByID(GetPacketID());
+ CXFA_Node* pNewNode = pFactory->CreateNode(pPacket, (XFA_ELEMENT)pProperty[i].eName);
+ if(!pNewNode) {
+ break;
+ }
+ InsertChild(pNewNode, NULL);
+ pNewNode->SetFlag(XFA_NODEFLAG_Initialized);
+ nodes.Add(pNewNode);
+ break;
+ }
+ }
+ }
+ }
+ return nodes.GetSize();
+}
+CXFA_Node* CXFA_Node::CreateSamePacketNode(XFA_ELEMENT eElement, FX_DWORD dwFlags)
+{
+ IXFA_ObjFactory *pFactory = m_pDocument->GetParser()->GetFactory();
+ CXFA_Node* pNode = pFactory->CreateNode(m_ePacket, eElement);
+ pNode->SetFlag(dwFlags);
+ return pNode;
+}
+CXFA_Node* CXFA_Node::CloneTemplateToForm(FX_BOOL bRecursive)
+{
+ FXSYS_assert(m_ePacket == XFA_XDPPACKET_Template);
+ IXFA_ObjFactory *pFactory = m_pDocument->GetParser()->GetFactory();
+ CXFA_Node *pClone = pFactory->CreateNode(XFA_XDPPACKET_Form, m_eNodeClass);
+ if(!pClone) {
+ return NULL;
+ }
+ pClone->SetTemplateNode(this);
+ pClone->UpdateNameHash();
+ pClone->SetXMLMappingNode(GetXMLMappingNode());
+ if (bRecursive) {
+ for(CXFA_Node* pChild = GetNodeItem(XFA_NODEITEM_FirstChild); pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ pClone->InsertChild(pChild->CloneTemplateToForm(bRecursive));
+ }
+ }
+ pClone->SetFlag(XFA_NODEFLAG_Initialized);
+ return pClone;
+}
+CXFA_Node* CXFA_Node::GetTemplateNode()
+{
+ return m_pAuxNode;
+}
+void CXFA_Node::SetTemplateNode(CXFA_Node* pTemplateNode)
+{
+ m_pAuxNode = pTemplateNode;
+}
+CXFA_Node* CXFA_Node::GetBindData()
+{
+ ASSERT(GetPacketID() == XFA_XDPPACKET_Form);
+ return (CXFA_Node*)GetObject(XFA_ATTRIBUTE_BindingNode);
+}
+FX_INT32 CXFA_Node::GetBindItems(CXFA_NodeArray& formItems)
+{
+ if (m_uFlags & XFA_NODEFLAG_BindFormItems) {
+ CXFA_NodeArray* pItems = NULL;
+ TryObject(XFA_ATTRIBUTE_BindingNode, (FX_LPVOID&)pItems);
+ formItems.Copy(*pItems);
+ return formItems.GetSize();
+ }
+ CXFA_Node* pFormNode = (CXFA_Node*)GetObject(XFA_ATTRIBUTE_BindingNode);
+ if (pFormNode) {
+ formItems.Add(pFormNode);
+ }
+ return formItems.GetSize();
+}
+static void XFA_DataNodeDeleteBindItem(FX_LPVOID pData)
+{
+ if (pData) {
+ delete ((CXFA_NodeArray*)pData);
+ }
+}
+static XFA_MAPDATABLOCKCALLBACKINFO deleteBindItemCallBack = {XFA_DataNodeDeleteBindItem, NULL};
+FX_INT32 CXFA_Node::AddBindItem(CXFA_Node* pFormNode)
+{
+ ASSERT(pFormNode);
+ if (m_uFlags & XFA_NODEFLAG_BindFormItems) {
+ CXFA_NodeArray* pItems = NULL;
+ TryObject(XFA_ATTRIBUTE_BindingNode, (FX_LPVOID&)pItems);
+ ASSERT(pItems);
+ if (pItems->Find(pFormNode) < 0) {
+ pItems->Add(pFormNode);
+ }
+ return pItems->GetSize();
+ }
+ CXFA_Node* pOldFormItem = (CXFA_Node*)GetObject(XFA_ATTRIBUTE_BindingNode);
+ if (!pOldFormItem) {
+ SetObject(XFA_ATTRIBUTE_BindingNode, pFormNode);
+ return 1;
+ } else if (pOldFormItem == pFormNode) {
+ return 1;
+ }
+ CXFA_NodeArray* pItems = FX_NEW CXFA_NodeArray;
+ SetObject(XFA_ATTRIBUTE_BindingNode, pItems, &deleteBindItemCallBack);
+ pItems->Add(pOldFormItem);
+ pItems->Add(pFormNode);
+ m_uFlags |= XFA_NODEFLAG_BindFormItems;
+ return 2;
+}
+FX_INT32 CXFA_Node::RemoveBindItem(CXFA_Node* pFormNode)
+{
+ if (m_uFlags & XFA_NODEFLAG_BindFormItems) {
+ CXFA_NodeArray* pItems = NULL;
+ TryObject(XFA_ATTRIBUTE_BindingNode, (FX_LPVOID&)pItems);
+ ASSERT(pItems);
+ FX_INT32 iIndex = pItems->Find(pFormNode);
+ FX_INT32 iCount = pItems->GetSize();
+ if (iIndex >= 0) {
+ if (iIndex != iCount - 1) {
+ pItems->SetAt(iIndex, pItems->GetAt(iCount - 1));
+ }
+ pItems->RemoveAt(iCount - 1);
+ if (iCount == 2) {
+ CXFA_Node* pLastFormNode = pItems->GetAt(0);
+ SetObject(XFA_ATTRIBUTE_BindingNode, pLastFormNode);
+ m_uFlags &= ~XFA_NODEFLAG_BindFormItems;
+ }
+ iCount--;
+ }
+ return iCount;
+ }
+ CXFA_Node* pOldFormItem = (CXFA_Node*)GetObject(XFA_ATTRIBUTE_BindingNode);
+ if(pOldFormItem == pFormNode) {
+ SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+ pOldFormItem = NULL;
+ }
+ return pOldFormItem == NULL ? 0 : 1;
+}
+FX_BOOL CXFA_Node::HasBindItem()
+{
+ return (GetPacketID() == XFA_XDPPACKET_Datasets) && GetObject(XFA_ATTRIBUTE_BindingNode) != NULL;
+}
+CXFA_WidgetData* CXFA_Node::GetWidgetData()
+{
+ return (CXFA_WidgetData*)GetObject(XFA_ATTRIBUTE_WidgetData);
+}
+CXFA_WidgetData* CXFA_Node::GetContainerWidgetData()
+{
+ if (GetPacketID() != XFA_XDPPACKET_Form) {
+ return NULL;
+ }
+ XFA_ELEMENT classID = GetClassID();
+ if (classID == XFA_ELEMENT_ExclGroup) {
+ return NULL;
+ }
+ CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_ExclGroup) {
+ return NULL;
+ }
+ if (classID == XFA_ELEMENT_Field) {
+ CXFA_WidgetData* pFieldWidgetData = this->GetWidgetData();
+ if (pFieldWidgetData && pFieldWidgetData->GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+ return NULL;
+ } else {
+ CFX_WideString wsPicture;
+ if (pFieldWidgetData) {
+ pFieldWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+ }
+ if (!wsPicture.IsEmpty()) {
+ return pFieldWidgetData;
+ }
+ CXFA_Node* pDataNode = this->GetBindData();
+ if (!pDataNode) {
+ return NULL;
+ }
+ pFieldWidgetData = NULL;
+ CXFA_NodeArray formNodes;
+ pDataNode->GetBindItems(formNodes);
+ for (FX_INT32 i = 0; i < formNodes.GetSize(); i++) {
+ CXFA_Node* pFormNode = formNodes.GetAt(i);
+ if (!pFormNode || pFormNode->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+ continue;
+ }
+ pFieldWidgetData = pFormNode->GetWidgetData();
+ if (pFieldWidgetData) {
+ pFieldWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+ }
+ if (!wsPicture.IsEmpty()) {
+ break;
+ }
+ pFieldWidgetData = NULL;
+ }
+ return pFieldWidgetData;
+ }
+ }
+ CXFA_Node* pGrandNode = pParentNode ? pParentNode->GetNodeItem(XFA_NODEITEM_Parent) : NULL;
+ CXFA_Node* pValueNode = (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_Value) ? pParentNode : NULL;
+ if (!pValueNode) {
+ pValueNode = (pGrandNode && pGrandNode->GetClassID() == XFA_ELEMENT_Value) ? pGrandNode : NULL;
+ }
+ CXFA_Node* pParentOfValueNode = pValueNode ? pValueNode->GetNodeItem(XFA_NODEITEM_Parent) : NULL;
+ return pParentOfValueNode ? pParentOfValueNode->GetContainerWidgetData() : NULL;
+}
+FX_BOOL CXFA_Node::GetLocaleName(CFX_WideString& wsLocaleName)
+{
+ CXFA_Node* pForm = (CXFA_Node*)GetDocument()->GetXFANode(XFA_HASHCODE_Form);
+ CXFA_Node* pTopSubform = pForm->GetFirstChildByClass(XFA_ELEMENT_Subform);
+ FXSYS_assert(pTopSubform);
+ CXFA_Node* pLocaleNode = this;
+ FX_BOOL bLocale = FALSE;
+ do {
+ bLocale = pLocaleNode->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, FALSE);
+ if (!bLocale) {
+ pLocaleNode = pLocaleNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ } while (pLocaleNode && pLocaleNode != pTopSubform && !bLocale);
+ if (bLocale) {
+ return bLocale;
+ }
+ CXFA_Node* pConfig = (CXFA_Node*)GetDocument()->GetXFANode(XFA_HASHCODE_Config);
+ wsLocaleName = GetDocument()->GetLocalMgr()->GetConfigLocaleName(pConfig);
+ if (!wsLocaleName.IsEmpty()) {
+ bLocale = TRUE;
+ }
+ if (bLocale) {
+ return bLocale;
+ }
+ if (pTopSubform) {
+ bLocale = pTopSubform->TryCData(XFA_ATTRIBUTE_Locale, wsLocaleName, FALSE);
+ }
+ if (bLocale) {
+ return bLocale;
+ }
+ IFX_Locale* pLocale = GetDocument()->GetLocalMgr()->GetDefLocale();
+ if (pLocale) {
+ wsLocaleName = pLocale->GetName();
+ bLocale = TRUE;
+ }
+ return bLocale;
+}
+XFA_ATTRIBUTEENUM CXFA_Node::GetIntact()
+{
+ XFA_ELEMENT eElement = GetClassID();
+ CXFA_Node* pKeep = GetFirstChildByClass(XFA_ELEMENT_Keep);
+ XFA_ATTRIBUTEENUM eLayoutType = GetEnum(XFA_ATTRIBUTE_Layout);
+ if (pKeep) {
+ XFA_ATTRIBUTEENUM eIntact;
+ if (pKeep->TryEnum(XFA_ATTRIBUTE_Intact, eIntact, FALSE)) {
+ if(eIntact == XFA_ATTRIBUTEENUM_None && eLayoutType == XFA_ATTRIBUTEENUM_Row && m_pDocument->GetCurVersionMode() < XFA_VERSION_208) {
+ CXFA_Node* pPreviewRow = GetNodeItem(XFA_NODEITEM_PrevSibling, XFA_OBJECTTYPE_ContainerNode);
+ if(pPreviewRow && pPreviewRow->GetEnum(XFA_ATTRIBUTE_Layout) == XFA_ATTRIBUTEENUM_Row) {
+ XFA_ATTRIBUTEENUM eValue;
+ if(pKeep->TryEnum(XFA_ATTRIBUTE_Previous, eValue, FALSE)) {
+ if(eValue == XFA_ATTRIBUTEENUM_ContentArea || eValue == XFA_ATTRIBUTEENUM_PageArea) {
+ return XFA_ATTRIBUTEENUM_ContentArea;
+ }
+ }
+ CXFA_Node* pKeep = pPreviewRow->GetFirstChildByClass(XFA_ELEMENT_Keep);
+ if (pKeep) {
+ if (pKeep->TryEnum(XFA_ATTRIBUTE_Next, eValue, FALSE)) {
+ if(eValue == XFA_ATTRIBUTEENUM_ContentArea || eValue == XFA_ATTRIBUTEENUM_PageArea) {
+ return XFA_ATTRIBUTEENUM_ContentArea;
+ }
+ }
+ }
+ }
+ }
+ return eIntact;
+ }
+ }
+ switch (eElement) {
+ case XFA_ELEMENT_Subform:
+ switch (eLayoutType) {
+ case XFA_ATTRIBUTEENUM_Position:
+ case XFA_ATTRIBUTEENUM_Row:
+ return XFA_ATTRIBUTEENUM_ContentArea;
+ case XFA_ATTRIBUTEENUM_Tb:
+ case XFA_ATTRIBUTEENUM_Table:
+ case XFA_ATTRIBUTEENUM_Lr_tb:
+ case XFA_ATTRIBUTEENUM_Rl_tb:
+ return XFA_ATTRIBUTEENUM_None;
+ default:
+ break;
+ }
+ break;
+ case XFA_ELEMENT_Field: {
+ CXFA_Node* pParentNode = this->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pParentNode || pParentNode->GetClassID() == XFA_ELEMENT_PageArea) {
+ return XFA_ATTRIBUTEENUM_ContentArea;
+ }
+ if (pParentNode->GetIntact() == XFA_ATTRIBUTEENUM_None) {
+ XFA_ATTRIBUTEENUM eParLayout = pParentNode->GetEnum(XFA_ATTRIBUTE_Layout);
+ if (eParLayout == XFA_ATTRIBUTEENUM_Position || eParLayout == XFA_ATTRIBUTEENUM_Row || eParLayout == XFA_ATTRIBUTEENUM_Table) {
+ return XFA_ATTRIBUTEENUM_None;
+ }
+ XFA_VERSION version = m_pDocument->GetCurVersionMode();
+ if (eParLayout == XFA_ATTRIBUTEENUM_Tb && version < XFA_VERSION_208) {
+ CXFA_Measurement measureH;
+ if (this->TryMeasure(XFA_ATTRIBUTE_H, measureH, FALSE)) {
+ return XFA_ATTRIBUTEENUM_ContentArea;
+ }
+ }
+ return XFA_ATTRIBUTEENUM_None;
+ }
+ return XFA_ATTRIBUTEENUM_ContentArea;
+ }
+ case XFA_ELEMENT_Draw:
+ return XFA_ATTRIBUTEENUM_ContentArea;
+ default:
+ break;
+ }
+ return XFA_ATTRIBUTEENUM_None;
+}
+CXFA_Node* CXFA_Node::GetDataDescriptionNode()
+{
+ if(m_ePacket == XFA_XDPPACKET_Datasets) {
+ return m_pAuxNode;
+ }
+ return NULL;
+}
+void CXFA_Node::SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode)
+{
+ FXSYS_assert(m_ePacket == XFA_XDPPACKET_Datasets);
+ m_pAuxNode = pDataDescriptionNode;
+}
+void CXFA_Node::Script_TreeClass_ResolveNode(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"resolveNode"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ CXFA_Node* refNode = this;
+ if(refNode->GetClassID() == XFA_ELEMENT_Xfa) {
+ refNode = (CXFA_Node*)pScriptContext->GetThisObject();
+ }
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = pScriptContext->ResolveObjects(refNode, wsExpression, resoveNodeRS, dwFlag);
+ if (iRet < 1) {
+ return FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ }
+ FXJSE_HVALUE hValue = NULL;
+ if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+ CXFA_Object* pNode = resoveNodeRS.nodes[0];
+ hValue = pScriptContext->GetJSValueFromMap(pNode);
+ FXJSE_Value_Set(pArguments->GetReturnValue(), hValue);
+ } else {
+ XFA_LPCSCRIPTATTRIBUTEINFO lpAttributeInfo = resoveNodeRS.pScriptAttribute;
+ if (lpAttributeInfo && lpAttributeInfo->eValueType == XFA_SCRIPT_Object) {
+ hValue = FXJSE_Value_Create(pScriptContext->GetRuntime());
+ (resoveNodeRS.nodes[0]->*(lpAttributeInfo->lpfnCallback))(hValue, FALSE, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+ FXJSE_Value_Set(pArguments->GetReturnValue(), hValue);
+ FXJSE_Value_Release(hValue);
+ } else {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ }
+ }
+}
+void CXFA_Node::Script_TreeClass_ResolveNodes(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"resolveNodes"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (!hValue) {
+ return;
+ }
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ CXFA_Node* refNode = this;
+ if(refNode->GetClassID() == XFA_ELEMENT_Xfa) {
+ refNode = (CXFA_Node*)m_pDocument->GetScriptContext()->GetThisObject();
+ }
+ Script_Som_ResolveNodeList(hValue, wsExpression, dwFlag, refNode);
+}
+void CXFA_Node::Script_Som_ResolveNodeList(FXJSE_HVALUE hValue, CFX_WideString wsExpression, FX_DWORD dwFlag, CXFA_Node* refNode)
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ if(refNode == NULL) {
+ refNode = this;
+ }
+ FX_INT32 iRet = pScriptContext->ResolveObjects(refNode, wsExpression, resoveNodeRS, dwFlag);
+ CXFA_ArrayNodeList* pNodeList = FX_NEW CXFA_ArrayNodeList(m_pDocument);
+ if (resoveNodeRS.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+ for (FX_INT32 i = 0; i < resoveNodeRS.nodes.GetSize(); i++) {
+ if (resoveNodeRS.nodes[i]->IsNode()) {
+ pNodeList->Append((CXFA_Node*)resoveNodeRS.nodes[i]);
+ }
+ }
+ } else {
+ CXFA_HVALUEArray hValueArray(pScriptContext->GetRuntime());
+ if (resoveNodeRS.GetAttributeResult(hValueArray) > 0) {
+ CXFA_ObjArray objectArray;
+ hValueArray.GetAttributeObject(objectArray);
+ for (FX_INT32 i = 0; i < objectArray.GetSize(); i++) {
+ if (objectArray[i]->IsNode()) {
+ pNodeList->Append((CXFA_Node*)objectArray[i]);
+ }
+ }
+ }
+ }
+ FXJSE_Value_SetObject(hValue, (CXFA_Object*)pNodeList, pScriptContext->GetJseNormalClass());
+}
+void CXFA_Node::Script_TreeClass_All(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
+ CFX_WideString wsName;
+ GetAttribute(XFA_ATTRIBUTE_Name, wsName);
+ CFX_WideString wsExpression = wsName + FX_WSTRC(L"[*]");
+ Script_Som_ResolveNodeList(hValue, wsExpression, dwFlag);
+ }
+}
+void CXFA_Node::Script_TreeClass_Nodes(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ if (bSetting) {
+ IXFA_AppProvider* pAppProvider = m_pDocument->GetNotify()->GetAppProvider();
+ FXSYS_assert(pAppProvider);
+ CFX_WideString wsMessage;
+ pAppProvider->LoadString(XFA_IDS_Unable_TO_SET, wsMessage);
+ FXJSE_ThrowMessage(FX_BSTRC(""), FX_UTF8Encode(wsMessage, wsMessage.GetLength()));
+ } else {
+ CXFA_AttachNodeList* pNodeList = FX_NEW CXFA_AttachNodeList(m_pDocument, this);
+ FXJSE_Value_SetObject(hValue, (CXFA_Object*)pNodeList, pScriptContext->GetJseNormalClass());
+ }
+}
+void CXFA_Node::Script_TreeClass_ClassAll(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_ALL;
+ CFX_WideStringC wsName;
+ this->GetClassName(wsName);
+ CFX_WideString wsExpression = FX_WSTRC(L"#") + wsName + FX_WSTRC(L"[*]");
+ Script_Som_ResolveNodeList(hValue, wsExpression, dwFlag);
+ }
+}
+void CXFA_Node::Script_TreeClass_Parent(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ CXFA_Node* pParent = this->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParent) {
+ FXJSE_Value_Set(hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(pParent));
+ } else {
+ FXJSE_Value_SetNull(hValue);
+ }
+ }
+}
+void CXFA_Node::Script_TreeClass_Index(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ FXJSE_Value_SetInteger(hValue, GetNodeSameNameIndex());
+ }
+}
+void CXFA_Node::Script_TreeClass_ClassIndex(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ FXJSE_Value_SetInteger(hValue, GetNodeSameClassIndex());
+ }
+}
+void CXFA_Node::Script_TreeClass_SomExpression(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ CFX_WideString wsSOMExpression;
+ GetSOMExpression(wsSOMExpression);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsSOMExpression));
+ }
+}
+void CXFA_Node::Script_NodeClass_ApplyXSL(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"applyXSL"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+}
+void CXFA_Node::Script_NodeClass_AssignNode(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 3) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"assignNode"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ CFX_WideString wsValue;
+ FX_INT32 iAction = 0;
+ if (iLength >= 1) {
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ }
+ if (iLength >= 2) {
+ CFX_ByteString bsValue = pArguments->GetUTF8String(1);
+ wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ }
+ if (iLength >= 3) {
+ iAction = pArguments->GetInt32(2);
+ }
+}
+void CXFA_Node::Script_NodeClass_Clone(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"clone"));
+ return;
+ }
+ FX_BOOL bClone = TRUE;
+ bClone = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+ CXFA_Node* pCloneNode = this->Clone(bClone);
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pCloneNode));
+}
+void CXFA_Node::Script_NodeClass_GetAttribute(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"getAttribute"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ CFX_WideString wsValue;
+ this->GetAttribute(wsExpression, wsValue);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+ }
+}
+void CXFA_Node::Script_NodeClass_GetElement(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 2) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"getElement"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ FX_INT32 iValue = 0;
+ if (iLength >= 1) {
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ }
+ if (iLength >= 2) {
+ iValue = pArguments->GetInt32(1);
+ }
+ XFA_LPCELEMENTINFO pElementInfo = XFA_GetElementByName(wsExpression);
+ CXFA_Node* pNode = this->GetProperty(iValue, pElementInfo->eName);
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
+}
+void CXFA_Node::Script_NodeClass_IsPropertySpecified(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 3) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"isPropertySpecified"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ FX_BOOL bParent = TRUE;
+ FX_INT32 iIndex = 0;
+ if (iLength >= 1) {
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ }
+ if (iLength >= 2) {
+ bParent = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+ }
+ if (iLength >= 3) {
+ iIndex = pArguments->GetInt32(2);
+ }
+ FX_BOOL bHas = FALSE;
+ XFA_LPCATTRIBUTEINFO pAttributeInfo = XFA_GetAttributeByName(wsExpression);
+ CFX_WideString wsValue;
+ if(pAttributeInfo) {
+ bHas = this->HasAttribute(pAttributeInfo->eName);
+ }
+ if (!bHas) {
+ XFA_LPCELEMENTINFO pElementInfo = XFA_GetElementByName(wsExpression);
+ bHas = (this->GetProperty(iIndex, pElementInfo->eName) != NULL);
+ }
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetBoolean(hValue, bHas);
+ }
+}
+void CXFA_Node::Script_NodeClass_LoadXML(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 3) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"loadXML"));
+ return;
+ }
+ CFX_WideString wsExpression;
+ FX_BOOL bIgnoreRoot = TRUE;
+ FX_BOOL bOverwrite = 0;
+ if (iLength >= 1) {
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ if (wsExpression.IsEmpty()) {
+ return;
+ }
+ }
+ if (iLength >= 2) {
+ bIgnoreRoot = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+ }
+ if (iLength >= 3) {
+ bOverwrite = pArguments->GetInt32(2) == 0 ? FALSE : TRUE;
+ }
+ IXFA_Parser* pParser = IXFA_Parser::Create(m_pDocument);
+ if (!pParser) {
+ return;
+ }
+ IFDE_XMLNode* pXMLNode = NULL;
+ FX_INT32 iParserStatus = pParser->ParseXMLData(wsExpression, pXMLNode, NULL);
+ if (iParserStatus != XFA_PARSESTATUS_Done || !pXMLNode) {
+ pParser->Release();
+ pParser = NULL;
+ return;
+ }
+ if (bIgnoreRoot && (pXMLNode->GetType() != FDE_XMLNODE_Element || XFA_RecognizeRichText((IFDE_XMLElement*)pXMLNode))) {
+ bIgnoreRoot = FALSE;
+ }
+ CXFA_Node* pFakeRoot = this->Clone(FALSE);
+ CFX_WideStringC wsContentType = this->GetCData(XFA_ATTRIBUTE_ContentType);
+ if (!wsContentType.IsEmpty()) {
+ pFakeRoot->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+ }
+ IFDE_XMLNode* pFakeXMLRoot = pFakeRoot->GetXMLMappingNode();
+ if (!pFakeXMLRoot) {
+ IFDE_XMLNode* pThisXMLRoot = this->GetXMLMappingNode();
+ pFakeXMLRoot = pThisXMLRoot ? pThisXMLRoot->Clone(FALSE) : NULL;
+ }
+ if (!pFakeXMLRoot) {
+ CFX_WideStringC wsClassName;
+ this->GetClassName(wsClassName);
+ pFakeXMLRoot = IFDE_XMLElement::Create(wsClassName);
+ }
+ if (bIgnoreRoot) {
+ IFDE_XMLNode *pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+ while (pXMLChild) {
+ IFDE_XMLNode * pXMLSibling = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling);
+ pXMLNode->RemoveChildNode(pXMLChild);
+ pFakeXMLRoot->InsertChildNode(pXMLChild);
+ pXMLChild = pXMLSibling;
+ }
+ } else {
+ IFDE_XMLNode *pXMLParent = pXMLNode->GetNodeItem(IFDE_XMLNode::Parent);
+ if (pXMLParent) {
+ pXMLParent->RemoveChildNode(pXMLNode);
+ }
+ pFakeXMLRoot->InsertChildNode(pXMLNode);
+ }
+ pParser->ConstructXFANode(pFakeRoot, pFakeXMLRoot);
+ pFakeRoot = pParser->GetRootNode();
+ if (pFakeRoot) {
+ if (bOverwrite) {
+ CXFA_Node *pChild = this->GetNodeItem(XFA_NODEITEM_FirstChild);
+ CXFA_Node* pNewChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+ FX_INT32 index = 0;
+ while (pNewChild) {
+ CXFA_Node* pItem = pNewChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pFakeRoot->RemoveChild(pNewChild);
+ this->InsertChild(index++, pNewChild);
+ pNewChild->SetFlag(XFA_NODEFLAG_Initialized);
+ pNewChild = pItem;
+ }
+ while (pChild) {
+ CXFA_Node *pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ this->RemoveChild(pChild);
+ pFakeRoot->InsertChild(pChild);
+ pChild = pItem;
+ }
+ if (GetPacketID() == XFA_XDPPACKET_Form && GetClassID() == XFA_ELEMENT_ExData) {
+ IFDE_XMLNode* pTempXMLNode = this->GetXMLMappingNode();
+ this->SetXMLMappingNode(pFakeXMLRoot);
+ this->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+ if (pTempXMLNode && pTempXMLNode->GetNodeItem(IFDE_XMLNode::Parent) == NULL) {
+ pFakeXMLRoot = pTempXMLNode;
+ } else {
+ pFakeXMLRoot = NULL;
+ }
+ }
+ MoveBufferMapData(pFakeRoot, this, XFA_CalcData, TRUE);
+ } else {
+ CXFA_Node* pChild = pFakeRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChild) {
+ CXFA_Node *pItem = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pFakeRoot->RemoveChild(pChild);
+ this->InsertChild(pChild);
+ pChild->SetFlag(XFA_NODEFLAG_Initialized);
+ pChild = pItem;
+ }
+ }
+ if (pFakeXMLRoot) {
+ pFakeRoot->SetXMLMappingNode(pFakeXMLRoot);
+ pFakeRoot->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+ }
+ pFakeRoot->SetFlag(XFA_NODEFLAG_HasRemoved, TRUE, FALSE);
+ } else {
+ if (pFakeXMLRoot) {
+ pFakeXMLRoot->Release();
+ pFakeXMLRoot = NULL;
+ }
+ }
+ pParser->Release();
+ pParser = NULL;
+}
+void CXFA_Node::Script_NodeClass_SaveFilteredXML(CFXJSE_Arguments* pArguments)
+{
+}
+void CXFA_Node::Script_NodeClass_SaveXML(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 0 || iLength > 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"saveXML"));
+ return;
+ }
+ FX_BOOL bPrettyMode = FALSE;
+ if (iLength == 1) {
+ CFX_ByteString bsPretty = pArguments->GetUTF8String(0);
+ if (bsPretty.Equal(FX_BSTRC("pretty"))) {
+ bPrettyMode = TRUE;
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ return;
+ }
+ }
+ CFX_ByteStringC bsXMLHeader = FX_BSTRC("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ if (GetPacketID() == XFA_XDPPACKET_Form) {
+ IFX_MemoryStream* pMemoryStream = FX_CreateMemoryStream(TRUE);
+ if (!pMemoryStream) {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), bsXMLHeader);
+ return;
+ }
+ IFX_Stream *pStream = IFX_Stream::CreateStream((IFX_FileWrite*)pMemoryStream, FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
+ if (!pStream) {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), bsXMLHeader);
+ pMemoryStream->Release();
+ pMemoryStream = NULL;
+ return;
+ }
+ pStream->SetCodePage(FX_CODEPAGE_UTF8);
+ pStream->WriteData(bsXMLHeader, bsXMLHeader.GetLength());
+ XFA_DataExporter_RegenerateFormFile(this, pStream, NULL, TRUE);
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), CFX_ByteStringC(pMemoryStream->GetBuffer(), pMemoryStream->GetSize()));
+ pStream->Release();
+ pStream = NULL;
+ if (pMemoryStream) {
+ pMemoryStream->Release();
+ pMemoryStream = NULL;
+ }
+ return;
+ } else if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+ IFDE_XMLNode* pElement = this->GetXMLMappingNode();
+ if(!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), bsXMLHeader);
+ return;
+ }
+ XFA_DataExporter_DealWithDataGroupNode(this);
+ IFX_MemoryStream* pMemoryStream = FX_CreateMemoryStream(TRUE);
+ if (!pMemoryStream) {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), bsXMLHeader);
+ return;
+ }
+ if (pMemoryStream) {
+ IFX_Stream *pStream = IFX_Stream::CreateStream((IFX_FileWrite*)pMemoryStream, FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
+ if (pStream) {
+ pStream->SetCodePage(FX_CODEPAGE_UTF8);
+ pStream->WriteData(bsXMLHeader, bsXMLHeader.GetLength());
+ pElement->SaveXMLNode(pStream);
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), CFX_ByteStringC(pMemoryStream->GetBuffer(), pMemoryStream->GetSize()));
+ pStream->Release();
+ pStream = NULL;
+ }
+ if (pMemoryStream) {
+ pMemoryStream->Release();
+ pMemoryStream = NULL;
+ }
+ return;
+ }
+ } else {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), FX_BSTRC(""));
+ }
+}
+void CXFA_Node::Script_NodeClass_SetAttribute(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 2) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"setAttribute"));
+ return;
+ }
+ CFX_WideString wsAttribute;
+ CFX_WideString wsAttributeValue;
+ CFX_ByteString bsAttributeValue = pArguments->GetUTF8String(0);
+ CFX_ByteString bsAttribute = pArguments->GetUTF8String(1);
+ wsAttributeValue = CFX_WideString::FromUTF8(bsAttributeValue, bsAttributeValue.GetLength());
+ wsAttribute = CFX_WideString::FromUTF8(bsAttribute, bsAttribute.GetLength());
+ this->SetAttribute(wsAttribute, wsAttributeValue, TRUE);
+}
+void CXFA_Node::Script_NodeClass_SetElement(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1 && iLength != 2) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"setElement"));
+ return;
+ }
+ CXFA_Node* pNode = NULL;
+ CFX_WideString wsName;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ if (iLength >= 2) {
+ CFX_ByteString bsName = pArguments->GetUTF8String(1);
+ wsName = CFX_WideString::FromUTF8(bsName, bsName.GetLength());
+ }
+}
+void CXFA_Node::Script_NodeClass_Ns(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ CFX_WideString wsNameSpace;
+ this->TryNamespace(wsNameSpace);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsNameSpace));
+ }
+}
+void CXFA_Node::Script_NodeClass_Model(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ FXJSE_Value_Set(hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(this->GetModelNode()));
+ }
+}
+void CXFA_Node::Script_NodeClass_IsContainer(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ FXJSE_Value_SetBoolean(hValue, this->IsContainerNode());
+ }
+}
+void CXFA_Node::Script_NodeClass_IsNull(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ if (this->GetClassID() == XFA_ELEMENT_Subform) {
+ FXJSE_Value_SetBoolean(hValue, FALSE);
+ return;
+ }
+ CFX_WideString strValue;
+ FXJSE_Value_SetBoolean(hValue, !TryContent(strValue) || strValue.IsEmpty());
+ }
+}
+void CXFA_Node::Script_NodeClass_OneOfChild(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ CXFA_NodeArray properts;
+ FX_INT32 iSize = this->GetNodeList(properts, XFA_NODEFILTER_OneOfProperty);
+ if (iSize > 0) {
+ FXJSE_Value_Set(hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(properts[0]));
+ }
+ }
+}
+void CXFA_Node::Script_ContainerClass_GetDelta(CFXJSE_Arguments* pArguments)
+{
+}
+void CXFA_Node::Script_ContainerClass_GetDeltas(CFXJSE_Arguments* pArguments)
+{
+ CXFA_ArrayNodeList* pFormNodes = FX_NEW CXFA_ArrayNodeList(m_pDocument);
+ FXJSE_Value_SetObject(pArguments->GetReturnValue(), (CXFA_Object*)pFormNodes, m_pDocument->GetScriptContext()->GetJseNormalClass());
+}
+void CXFA_Node::Script_ModelClass_ClearErrorList(CFXJSE_Arguments* pArguments)
+{
+}
+void CXFA_Node::Script_ModelClass_CreateNode(CFXJSE_Arguments* pArguments)
+{
+ Script_Template_CreateNode(pArguments);
+}
+void CXFA_Node::Script_ModelClass_IsCompatibleNS(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"isCompatibleNS"));
+ return;
+ }
+ CFX_WideString wsNameSpace;
+ if (iLength >= 1) {
+ CFX_ByteString bsNameSpace = pArguments->GetUTF8String(0);
+ wsNameSpace = CFX_WideString::FromUTF8(bsNameSpace, bsNameSpace.GetLength());
+ }
+ CFX_WideString wsNodeNameSpace;
+ this->TryNamespace(wsNodeNameSpace);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetBoolean(hValue, wsNodeNameSpace.Equal(wsNameSpace));
+ }
+}
+void CXFA_Node::Script_ModelClass_Context(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_ModelClass_AliasNode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_Attribute_Integer(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ SetInteger(eAttribute, FXJSE_Value_ToInteger(hValue), TRUE);
+ } else {
+ FXJSE_Value_SetInteger(hValue, GetInteger(eAttribute));
+ }
+}
+void CXFA_Node::Script_Attribute_IntegerRead(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ FXJSE_Value_SetInteger(hValue, GetInteger(eAttribute));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+void CXFA_Node::Script_Attribute_BOOL(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ SetBoolean(eAttribute, FXJSE_Value_ToBoolean(hValue), TRUE);
+ } else {
+ FXJSE_Value_SetUTF8String(hValue, GetBoolean(eAttribute) ? FX_BSTRC("1") : FX_BSTRC("0"));
+ }
+}
+void CXFA_Node::Script_Attribute_BOOLRead(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ FXJSE_Value_SetUTF8String(hValue, GetBoolean(eAttribute) ? FX_BSTRC("1") : FX_BSTRC("0"));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+void CXFA_Node::Script_Attribute_SendAttributeChangeMessage(FX_LPVOID eAttribute, FX_LPVOID eValue, FX_BOOL bScriptModify)
+{
+ CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+ if (!pLayoutPro) {
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ FX_DWORD dwPacket = this->GetPacketID();
+ if (dwPacket & XFA_XDPPACKET_Form) {
+ FX_BOOL bNeedFindContainer = FALSE;
+ XFA_ELEMENT eType = this->GetClassID();
+ switch (eType) {
+ case XFA_ELEMENT_Caption:
+ bNeedFindContainer = TRUE;
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, this, this->GetNodeItem(XFA_NODEITEM_Parent));
+ break;
+ case XFA_ELEMENT_Font:
+ case XFA_ELEMENT_Para: {
+ bNeedFindContainer = TRUE;
+ CXFA_Node* pParentNode = this->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParentNode->GetClassID() == XFA_ELEMENT_Caption) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pParentNode, pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
+ } else {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, this, pParentNode);
+ }
+ }
+ break;
+ case XFA_ELEMENT_Margin: {
+ bNeedFindContainer = TRUE;
+ CXFA_Node* pParentNode = this->GetNodeItem(XFA_NODEITEM_Parent);
+ XFA_ELEMENT eParentType = pParentNode->GetClassID();
+ if (pParentNode->IsContainerNode()) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, this, pParentNode);
+ } else if (eParentType == XFA_ELEMENT_Caption) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pParentNode, pParentNode->GetNodeItem(XFA_NODEITEM_Parent));
+ } else {
+ CXFA_Node* pNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pNode && pNode->GetClassID() == XFA_ELEMENT_Ui) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pNode, pNode->GetNodeItem(XFA_NODEITEM_Parent));
+ }
+ }
+ }
+ break;
+ case XFA_ELEMENT_Comb: {
+ CXFA_Node* pEditNode = this->GetNodeItem(XFA_NODEITEM_Parent);
+ XFA_ELEMENT eUIType = pEditNode->GetClassID();
+ if (pEditNode && (eUIType == XFA_ELEMENT_DateTimeEdit || eUIType == XFA_ELEMENT_NumericEdit || eUIType == XFA_ELEMENT_TextEdit)) {
+ CXFA_Node* pUINode = pEditNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pUINode) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pUINode, pUINode->GetNodeItem(XFA_NODEITEM_Parent));
+ }
+ }
+ }
+ break;
+ case XFA_ELEMENT_Button:
+ case XFA_ELEMENT_Barcode:
+ case XFA_ELEMENT_ChoiceList:
+ case XFA_ELEMENT_DateTimeEdit:
+ case XFA_ELEMENT_NumericEdit:
+ case XFA_ELEMENT_PasswordEdit:
+ case XFA_ELEMENT_TextEdit: {
+ CXFA_Node* pUINode = this->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pUINode) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pUINode, pUINode->GetNodeItem(XFA_NODEITEM_Parent));
+ }
+ }
+ break;
+ case XFA_ELEMENT_CheckButton: {
+ bNeedFindContainer = TRUE;
+ CXFA_Node* pUINode = this->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pUINode) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pUINode, pUINode->GetNodeItem(XFA_NODEITEM_Parent));
+ }
+ }
+ break;
+ case XFA_ELEMENT_Keep:
+ case XFA_ELEMENT_Bookend:
+ case XFA_ELEMENT_Break:
+ case XFA_ELEMENT_BreakAfter:
+ case XFA_ELEMENT_BreakBefore:
+ case XFA_ELEMENT_Overflow:
+ bNeedFindContainer = TRUE;
+ break;
+ case XFA_ELEMENT_Area:
+ case XFA_ELEMENT_Draw:
+ case XFA_ELEMENT_ExclGroup:
+ case XFA_ELEMENT_Field:
+ case XFA_ELEMENT_Subform:
+ case XFA_ELEMENT_SubformSet:
+ pLayoutPro->AddChangedContainer(this);
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, this, this);
+ break;
+ case XFA_ELEMENT_Sharptext:
+ case XFA_ELEMENT_Sharpxml:
+ case XFA_ELEMENT_SharpxHTML: {
+ CXFA_Node* pTextNode = this->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pTextNode) {
+ return;
+ }
+ CXFA_Node* pValueNode = pTextNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pValueNode) {
+ return;
+ }
+ XFA_ELEMENT eType = pValueNode->GetClassID();
+ if (eType == XFA_ELEMENT_Value) {
+ bNeedFindContainer = TRUE;
+ CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pNode && pNode->IsContainerNode()) {
+ if (bScriptModify) {
+ pValueNode = pNode;
+ }
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pValueNode, pNode);
+ } else {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pNode, pNode->GetNodeItem(XFA_NODEITEM_Parent));
+ }
+ } else {
+ if (eType == XFA_ELEMENT_Items) {
+ CXFA_Node* pNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pNode && pNode->IsContainerNode()) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, pValueNode, pNode);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (bNeedFindContainer) {
+ CXFA_Node* pParent = this;
+ while (pParent) {
+ if (pParent->IsContainerNode()) {
+ break;
+ }
+ pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ if (pParent) {
+ pLayoutPro->AddChangedContainer(pParent);
+ }
+ }
+ } else {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanged, eAttribute, eValue, this, this);
+ }
+}
+void CXFA_Node::Script_Attribute_String(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ CFX_ByteString szValue;
+ FXJSE_Value_ToUTF8String(hValue, szValue);
+ CFX_WideString wsValue = CFX_WideString::FromUTF8(szValue, szValue.GetLength());
+ SetAttribute(eAttribute, wsValue, TRUE);
+ if(eAttribute == XFA_ATTRIBUTE_Use && this->GetClassID() == XFA_ELEMENT_Desc) {
+ CFX_WideString wsUseVal = wsValue, wsID, wsSOM;
+ CXFA_Node* pTemplateNode = (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Template);
+ CXFA_Node* pProtoRoot = pTemplateNode->GetFirstChildByClass(XFA_ELEMENT_Subform)->GetFirstChildByClass(XFA_ELEMENT_Proto);
+ if(!wsUseVal.IsEmpty()) {
+ if(wsUseVal[0] == '#') {
+ wsID = CFX_WideString((FX_LPCWSTR)wsUseVal + 1, wsUseVal.GetLength() - 1);
+ } else {
+ wsSOM = CFX_WideString((FX_LPCWSTR)wsUseVal, wsUseVal.GetLength());
+ }
+ }
+ CXFA_Node* pProtoNode = NULL;
+ if(!wsSOM.IsEmpty()) {
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Attributes | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = m_pDocument->GetScriptContext()->ResolveObjects(pProtoRoot, wsSOM, resoveNodeRS, dwFlag);
+ if(iRet > 0 && resoveNodeRS.nodes[0]->IsNode()) {
+ pProtoNode = (CXFA_Node*)resoveNodeRS.nodes[0];
+ }
+ } else if(!wsID.IsEmpty()) {
+ pProtoNode = m_pDocument->GetNodeByID(pProtoRoot, wsID);
+ }
+ if(pProtoNode) {
+ CXFA_Node* pHeadChild = GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pHeadChild) {
+ CXFA_Node* pSibling = pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ RemoveChild(pHeadChild);
+ pHeadChild = pSibling;
+ }
+ CXFA_Node* pProtoForm = pProtoNode->CloneTemplateToForm(TRUE);
+ pHeadChild = pProtoForm->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pHeadChild) {
+ CXFA_Node* pSibling = pHeadChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pProtoForm->RemoveChild(pHeadChild);
+ InsertChild(pHeadChild);
+ pHeadChild = pSibling;
+ }
+ m_pDocument->RemovePurgeNode(pProtoForm);
+ delete pProtoForm;
+ }
+ }
+ } else {
+ CFX_WideString wsValue;
+ GetAttribute(eAttribute, wsValue);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue, wsValue.GetLength()));
+ }
+}
+void CXFA_Node::Script_Attribute_StringRead(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ CFX_WideString wsValue;
+ GetAttribute(eAttribute, wsValue);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue, wsValue.GetLength()));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+void CXFA_Node::Script_WsdlConnection_Execute(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if ((argc == 0) || (argc == 1)) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execute"));
+ }
+}
+void CXFA_Node::Script_Delta_Restore(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"restore"));
+ }
+}
+void CXFA_Node::Script_Delta_CurrentValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_Delta_SavedValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_Delta_Target(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_Som_Message(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_SOM_MESSAGETYPE iMessageType)
+{
+ CXFA_WidgetData *pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ FX_BOOL bNew = FALSE;
+ CXFA_Validate validate = pWidgetData->GetValidate();
+ if (!validate) {
+ validate = pWidgetData->GetValidate(TRUE);
+ bNew = TRUE;
+ }
+ if (bSetting) {
+ CFX_ByteString bsMessage;
+ FXJSE_Value_ToUTF8String(hValue, bsMessage);
+ switch (iMessageType) {
+ case XFA_SOM_ValidationMessage:
+ validate.SetScriptMessageText(CFX_WideString::FromUTF8(bsMessage, bsMessage.GetLength()));
+ break;
+ case XFA_SOM_FormatMessage:
+ validate.SetFormatMessageText(CFX_WideString::FromUTF8(bsMessage, bsMessage.GetLength()));
+ break;
+ case XFA_SOM_MandatoryMessage:
+ validate.SetNullMessageText(CFX_WideString::FromUTF8(bsMessage, bsMessage.GetLength()));
+ break;
+ default:
+ break;
+ }
+ if (!bNew) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->AddCalcValidate(this);
+ }
+ } else {
+ CFX_WideString wsMessage;
+ switch (iMessageType) {
+ case XFA_SOM_ValidationMessage:
+ validate.GetScriptMessageText(wsMessage);
+ break;
+ case XFA_SOM_FormatMessage:
+ validate.GetFormatMessageText(wsMessage);
+ break;
+ case XFA_SOM_MandatoryMessage:
+ validate.GetNullMessageText(wsMessage);
+ break;
+ default:
+ break;
+ }
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsMessage));
+ }
+}
+void CXFA_Node::Script_Som_ValidationMessage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_Som_Message(hValue, bSetting, XFA_SOM_ValidationMessage);
+}
+void CXFA_Node::Script_Field_Length(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ CXFA_WidgetData *pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetInteger(hValue, 0);
+ return;
+ }
+ FXJSE_Value_SetInteger(hValue, pWidgetData->CountChoiceListItems(TRUE));
+ }
+}
+void CXFA_Node::Script_Som_DefaultValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ XFA_ELEMENT classID = GetClassID();
+ if(classID == XFA_ELEMENT_Field) {
+ Script_Field_DefaultValue(hValue, bSetting, eAttribute);
+ return;
+ } else if(classID == XFA_ELEMENT_Draw) {
+ Script_Draw_DefaultValue(hValue, bSetting, eAttribute);
+ return;
+ } else if (classID == XFA_ELEMENT_Boolean) {
+ Script_Boolean_Value(hValue, bSetting, eAttribute);
+ return;
+ }
+ if (bSetting) {
+ CFX_ByteString newValue;
+ if (!(FXJSE_Value_IsNull(hValue) || FXJSE_Value_IsUndefined(hValue))) {
+ FXJSE_Value_ToUTF8String(hValue, newValue);
+ }
+ CFX_WideString wsNewValue = CFX_WideString::FromUTF8(newValue, newValue.GetLength());
+ CFX_WideString wsFormatValue(wsNewValue);
+ CXFA_WidgetData* pContainerWidgetData = NULL;
+ if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+ CXFA_NodeArray formNodes;
+ this->GetBindItems(formNodes);
+ CFX_WideString wsPicture;
+ for (FX_INT32 i = 0; i < formNodes.GetSize(); i++) {
+ CXFA_Node* pFormNode = formNodes.GetAt(i);
+ if (!pFormNode || pFormNode->HasFlag(XFA_NODEFLAG_HasRemoved)) {
+ continue;
+ }
+ pContainerWidgetData = pFormNode->GetContainerWidgetData();
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+ }
+ if (!wsPicture.IsEmpty()) {
+ break;
+ }
+ pContainerWidgetData = NULL;
+ }
+ } else if (GetPacketID() == XFA_XDPPACKET_Form) {
+ pContainerWidgetData = GetContainerWidgetData();
+ }
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
+ }
+ SetScriptContent(wsNewValue, wsFormatValue, TRUE, TRUE);
+ } else {
+ CFX_WideString content = GetScriptContent(TRUE);
+ if(content.IsEmpty() && classID != XFA_ELEMENT_Text && classID != XFA_ELEMENT_SubmitUrl) {
+ FXJSE_Value_SetNull(hValue);
+ } else if (classID == XFA_ELEMENT_Integer) {
+ FXJSE_Value_SetInteger(hValue, FXSYS_wtoi(content)) ;
+ } else if (classID == XFA_ELEMENT_Float || classID == XFA_ELEMENT_Decimal) {
+ CFX_Decimal decimal(content);
+ FXJSE_Value_SetFloat(hValue, (FX_FLOAT)(double)decimal);
+ } else {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(content, content.GetLength()));
+ }
+ }
+}
+void CXFA_Node::Script_Som_DefaultValue_Read(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ }
+ CFX_WideString content = GetScriptContent(TRUE);
+ if (content.IsEmpty()) {
+ FXJSE_Value_SetNull(hValue);
+ } else {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(content, content.GetLength()));
+ }
+}
+void CXFA_Node::Script_Boolean_Value(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ CFX_ByteString newValue;
+ if (!(FXJSE_Value_IsNull(hValue) || FXJSE_Value_IsUndefined(hValue))) {
+ FXJSE_Value_ToUTF8String(hValue, newValue);
+ }
+ FX_INT32 iValue = FXSYS_atoi(newValue);
+ CFX_WideString wsNewValue = (iValue == 0) ? FX_WSTRC(L"0") : FX_WSTRC(L"1");
+ CFX_WideString wsFormatValue(wsNewValue);
+ CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsNewValue, wsFormatValue);
+ }
+ SetScriptContent(wsNewValue, wsFormatValue, TRUE, TRUE);
+ } else {
+ CFX_WideString wsValue = GetScriptContent(TRUE);
+ FXJSE_Value_SetBoolean(hValue, wsValue.Equal(FX_WSTRC(L"1")) ? TRUE : FALSE);
+ }
+}
+struct XFA_ExecEventParaInfo {
+public:
+ FX_UINT32 m_uHash;
+ FX_LPCWSTR m_lpcEventName;
+ XFA_EVENTTYPE m_eventType;
+ FX_UINT32 m_validFlags;
+};
+static const XFA_ExecEventParaInfo gs_eventParaInfos[] = {
+ {0x02a6c55a, (FX_LPCWSTR)L"postSubmit", XFA_EVENT_PostSubmit, 0},
+ {0x0ab466bb, (FX_LPCWSTR)L"preSubmit", XFA_EVENT_PreSubmit, 0},
+ {0x109d7ce7, (FX_LPCWSTR)L"mouseEnter", XFA_EVENT_MouseEnter, 5},
+ {0x17fad373, (FX_LPCWSTR)L"postPrint", XFA_EVENT_PostPrint, 0},
+ {0x1bfc72d9, (FX_LPCWSTR)L"preOpen", XFA_EVENT_PreOpen, 7},
+ {0x2196a452, (FX_LPCWSTR)L"initialize", XFA_EVENT_Initialize, 1},
+ {0x27410f03, (FX_LPCWSTR)L"mouseExit", XFA_EVENT_MouseExit, 5},
+ {0x33c43dec, (FX_LPCWSTR)L"docClose", XFA_EVENT_DocClose, 0},
+ {0x361fa1b6, (FX_LPCWSTR)L"preSave", XFA_EVENT_PreSave, 0},
+ {0x36f1c6d8, (FX_LPCWSTR)L"preSign", XFA_EVENT_PreSign, 6},
+ {0x4731d6ba, (FX_LPCWSTR)L"exit", XFA_EVENT_Exit, 2},
+ {0x56bf456b, (FX_LPCWSTR)L"docReady", XFA_EVENT_DocReady, 0},
+ {0x7233018a, (FX_LPCWSTR)L"validate", XFA_EVENT_Validate, 1},
+ {0x8808385e, (FX_LPCWSTR)L"indexChange", XFA_EVENT_IndexChange, 3},
+ {0x891f4606, (FX_LPCWSTR)L"change", XFA_EVENT_Change, 4},
+ {0x9528a7b4, (FX_LPCWSTR)L"prePrint", XFA_EVENT_PrePrint, 0},
+ {0x9f693b21, (FX_LPCWSTR)L"mouseDown", XFA_EVENT_MouseDown, 5},
+ {0xcdce56b3, (FX_LPCWSTR)L"full", XFA_EVENT_Full, 4},
+ {0xd576d08e, (FX_LPCWSTR)L"mouseUp", XFA_EVENT_MouseUp, 5},
+ {0xd95657a6, (FX_LPCWSTR)L"click", XFA_EVENT_Click, 4},
+ {0xdbfbe02e, (FX_LPCWSTR)L"calculate", XFA_EVENT_Calculate, 1},
+ {0xe25fa7b8, (FX_LPCWSTR)L"postOpen", XFA_EVENT_PostOpen, 7},
+ {0xe28dce7e, (FX_LPCWSTR)L"enter", XFA_EVENT_Enter, 2},
+ {0xfc82d695, (FX_LPCWSTR)L"postSave", XFA_EVENT_PostSave, 0},
+ {0xfd54fbb7, (FX_LPCWSTR)L"postSign", XFA_EVENT_PostSign, 6},
+};
+const XFA_ExecEventParaInfo* GetEventParaInfoByName(FX_WSTR wsEventName)
+{
+ FX_INT32 iLength = wsEventName.GetLength();
+ FX_UINT32 uHash = FX_HashCode_String_GetW(wsEventName.GetPtr(), iLength);
+ const XFA_ExecEventParaInfo* eventParaInfo = NULL;
+ FX_INT32 iStart = 0, iEnd = (sizeof(gs_eventParaInfos) / sizeof(gs_eventParaInfos[0])) - 1;
+ FX_INT32 iMid = (iStart + iEnd) / 2;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ eventParaInfo = &gs_eventParaInfos[iMid];
+ if (uHash == eventParaInfo->m_uHash) {
+ return eventParaInfo;
+ } else if (uHash < eventParaInfo->m_uHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
+void XFA_STRING_TO_RGB(CFX_WideString &strRGB, FX_INT32 &r, FX_INT32 &g, FX_INT32 &b)
+{
+ r = 0;
+ g = 0;
+ b = 0;
+ FX_WCHAR zero = '0';
+ FX_INT32 iIndex = 0;
+ FX_INT32 iLen = strRGB.GetLength();
+ for (FX_INT32 i = 0; i < iLen; ++i) {
+ FX_WCHAR ch = strRGB.GetAt(i);
+ if (ch == L',') {
+ ++iIndex;
+ }
+ if (iIndex > 2) {
+ break;
+ }
+ FX_INT32 iValue = ch - zero;
+ if (iValue >= 0 && iValue <= 9) {
+ switch (iIndex) {
+ case 0:
+ r = r * 10 + iValue;
+ break;
+ case 1:
+ g = g * 10 + iValue;
+ break;
+ default:
+ b = b * 10 + iValue;
+ break;
+ }
+ }
+ }
+}
+void CXFA_Node::Script_Som_BorderColor(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CXFA_Border border = pWidgetData->GetBorder(TRUE);
+ FX_INT32 iSize = border.CountEdges();
+ CFX_WideString strColor;
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ strColor = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ FX_INT32 r = 0, g = 0, b = 0;
+ XFA_STRING_TO_RGB(strColor, r, g, b);
+ FX_ARGB rgb = ArgbEncode(100, r, g, b);
+ for (FX_INT32 i = 0; i < iSize; ++i) {
+ CXFA_Edge edge = border.GetEdge(i);
+ edge.SetColor(rgb);
+ }
+ } else {
+ CXFA_Edge edge = border.GetEdge(0);
+ FX_ARGB color = edge.GetColor();
+ FX_INT32 a, r, g, b;
+ ArgbDecode(color, a, r, g, b);
+ strColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(strColor));
+ }
+}
+void CXFA_Node::Script_Som_BorderWidth(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CXFA_Border border = pWidgetData->GetBorder(TRUE);
+ FX_INT32 iSize = border.CountEdges();
+ CFX_WideString wsThickness;
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ wsThickness = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ for (FX_INT32 i = 0; i < iSize; ++i) {
+ CXFA_Edge edge = border.GetEdge(i);
+ CXFA_Measurement thickness(wsThickness);
+ edge.SetMSThickness(thickness);
+ }
+ } else {
+ CXFA_Edge edge = border.GetEdge(0);
+ CXFA_Measurement thickness = edge.GetMSThickness();
+ thickness.ToString(wsThickness);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsThickness));
+ }
+}
+void CXFA_Node::Script_Som_FillColor(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CXFA_Border border = pWidgetData->GetBorder(TRUE);
+ CXFA_Fill borderfill = border.GetFill(TRUE);
+ CXFA_Node *pNode = (CXFA_Node*)borderfill;
+ if (!pNode) {
+ return;
+ }
+ CFX_WideString wsColor;
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ wsColor = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ FX_INT32 r, g, b;
+ XFA_STRING_TO_RGB(wsColor, r, g, b);
+ FX_ARGB color = ArgbEncode(0xff, r, g, b);
+ borderfill.SetColor(color);
+ } else {
+ FX_ARGB color = borderfill.GetColor();
+ FX_INT32 a, r, g, b;
+ ArgbDecode(color, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsColor));
+ }
+}
+void CXFA_Node::Script_Som_DataNode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ CXFA_Node *pDataNode = GetBindData();
+ if (pDataNode) {
+ FXJSE_Value_Set(hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(pDataNode));
+ } else {
+ FXJSE_Value_SetNull(hValue);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+void CXFA_Node::Script_Draw_DefaultValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ if (FXJSE_Value_IsUTF8String(hValue)) {
+ CXFA_WidgetData *pWidgetData = GetWidgetData();
+ FXSYS_assert(pWidgetData);
+ XFA_ELEMENT uiType = pWidgetData->GetUIType();
+ if (uiType == XFA_ELEMENT_Text) {
+ CFX_ByteString newValue;
+ FXJSE_Value_ToUTF8String(hValue, newValue);
+ CFX_WideString wsNewValue = CFX_WideString::FromUTF8(newValue, newValue.GetLength());
+ CFX_WideString wsFormatValue(wsNewValue);
+ SetScriptContent(wsNewValue, wsFormatValue, TRUE, TRUE);
+ } else if(uiType != XFA_ELEMENT_Image) {
+ }
+ }
+ } else {
+ CFX_WideString content = GetScriptContent(TRUE);
+ if(content.IsEmpty()) {
+ FXJSE_Value_SetNull(hValue);
+ } else {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(content, content.GetLength()));
+ }
+ }
+}
+void CXFA_Node::Script_Field_DefaultValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ if (bSetting) {
+ if (FXJSE_Value_IsNull(hValue)) {
+ pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
+ pWidgetData->m_bIsNull = TRUE;
+ } else {
+ pWidgetData->m_bPreNull = pWidgetData->m_bIsNull;
+ pWidgetData->m_bIsNull = FALSE;
+ }
+ CFX_ByteString newValue;
+ if (!(FXJSE_Value_IsNull(hValue) || FXJSE_Value_IsUndefined(hValue))) {
+ FXJSE_Value_ToUTF8String(hValue, newValue);
+ }
+ CFX_WideString wsNewText = CFX_WideString::FromUTF8(newValue, newValue.GetLength());
+ CXFA_Node *pUIChild = pWidgetData->GetUIChild();
+ if (pUIChild->GetClassID() == XFA_ELEMENT_NumericEdit) {
+ FX_INT32 iLeadDigits = 0;
+ FX_INT32 iFracDigits = 0;
+ pWidgetData->GetLeadDigits(iLeadDigits);
+ pWidgetData->GetFracDigits(iFracDigits);
+ wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
+ }
+ CXFA_WidgetData* pContainerWidgetData = GetContainerWidgetData();
+ CFX_WideString wsFormatText(wsNewText);
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsNewText, wsFormatText);
+ }
+ SetScriptContent(wsNewText, wsFormatText, TRUE, TRUE);
+ } else {
+ CFX_WideString content = GetScriptContent(TRUE);
+ if(content.IsEmpty()) {
+ FXJSE_Value_SetNull(hValue);
+ } else {
+ CXFA_Node *pUIChild = pWidgetData->GetUIChild();
+ XFA_ELEMENT eUI = pUIChild->GetClassID();
+ CXFA_Value defVal = pWidgetData->GetFormValue();
+ CXFA_Node* pNode = defVal.GetNode()->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pNode && pNode->GetClassID() == XFA_ELEMENT_Decimal) {
+ if(eUI == XFA_ELEMENT_NumericEdit && (pNode->GetInteger(XFA_ATTRIBUTE_FracDigits) == -1)) {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(content, content.GetLength()));
+ } else {
+ CFX_Decimal decimal(content);
+ FXJSE_Value_SetFloat(hValue, (FX_FLOAT)(double)decimal);
+ }
+ } else if (pNode && pNode->GetClassID() == XFA_ELEMENT_Integer) {
+ FXJSE_Value_SetInteger(hValue, FXSYS_wtoi(content)) ;
+ } else if (pNode && pNode->GetClassID() == XFA_ELEMENT_Boolean) {
+ FXJSE_Value_SetBoolean(hValue, FXSYS_wtoi(content) == 0 ? FALSE : TRUE);
+ } else if (pNode && pNode->GetClassID() == XFA_ELEMENT_Float) {
+ CFX_Decimal decimal(content);
+ FXJSE_Value_SetFloat(hValue, (FX_FLOAT)(double)decimal);
+ } else {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(content, content.GetLength()));
+ }
+ }
+ }
+}
+void CXFA_Node::Script_Field_EditValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CFX_WideString wsValue;
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ pWidgetData->SetValue(wsValue, XFA_VALUEPICTURE_Edit);
+ } else {
+ pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Edit);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+ }
+}
+void CXFA_Node::Script_Som_FontColor(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CXFA_Font font = pWidgetData->GetFont(TRUE);
+ CXFA_Node *pNode = (CXFA_Node*)font;
+ if (!pNode) {
+ return;
+ }
+ CFX_WideString wsColor;
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ wsColor = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ FX_INT32 r, g, b;
+ XFA_STRING_TO_RGB(wsColor, r, g, b);
+ FX_ARGB color = ArgbEncode(0xff, r, g, b);
+ font.SetColor(color);
+ } else {
+ FX_ARGB color = font.GetColor();
+ FX_INT32 a, r, g, b;
+ ArgbDecode(color, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsColor));
+ }
+}
+void CXFA_Node::Script_Field_FormatMessage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_Som_Message(hValue, bSetting, XFA_SOM_FormatMessage);
+}
+void CXFA_Node::Script_Field_FormattedValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CFX_WideString wsValue;
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ pWidgetData->SetValue(wsValue, XFA_VALUEPICTURE_Display);
+ } else {
+ pWidgetData->GetValue(wsValue, XFA_VALUEPICTURE_Display);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+ }
+}
+void CXFA_Node::Script_Som_Mandatory(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CXFA_Validate validate = pWidgetData->GetValidate(TRUE);
+ CFX_WideString wsValue;
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ validate.SetNullTest(wsValue);
+ } else {
+ FX_INT32 iValue = validate.GetNullTest();
+ XFA_LPCATTRIBUTEENUMINFO pInfo = XFA_GetAttributeEnumByID((XFA_ATTRIBUTEENUM)iValue);
+ if (pInfo) {
+ wsValue = pInfo->pName;
+ }
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+ }
+}
+void CXFA_Node::Script_Som_MandatoryMessage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_Som_Message(hValue, bSetting, XFA_SOM_MandatoryMessage);
+}
+void CXFA_Node::Script_Field_ParentSubform(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ } else {
+ FXJSE_Value_SetNull(hValue);
+ }
+}
+void CXFA_Node::Script_Field_SelectedIndex(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ if (bSetting) {
+ FX_INT32 iIndex = FXJSE_Value_ToInteger(hValue);
+ if (iIndex == -1) {
+ pWidgetData->ClearAllSelections();
+ return;
+ }
+ pWidgetData->SetItemState(iIndex, TRUE, TRUE, TRUE);
+ } else {
+ FXJSE_Value_SetInteger(hValue, pWidgetData->GetSelectedItem());
+ }
+}
+void CXFA_Node::Script_Field_ClearItems(CFXJSE_Arguments* pArguments)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ pWidgetData->DeleteItem(-1, TRUE);
+}
+void CXFA_Node::Script_Field_ExecEvent(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ CFX_ByteString eventString = pArguments->GetUTF8String(0);
+ FX_INT32 iRet = execSingleEventByName(CFX_WideString::FromUTF8(eventString, eventString.GetLength()), XFA_ELEMENT_Field);
+ if (eventString == FX_BSTRC("validate")) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execEvent"));
+ }
+}
+void CXFA_Node::Script_Field_ExecInitialize(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize, FALSE, FALSE);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execInitialize"));
+ }
+}
+void CXFA_Node::Script_Field_DeleteItem(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"deleteItem"));
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ FX_BOOL bValue = pWidgetData->DeleteItem(iIndex, TRUE, TRUE);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetBoolean(hValue, bValue);
+ }
+}
+void CXFA_Node::Script_Field_GetSaveItem(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"getSaveItem"));
+ return;
+ }
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ if (iIndex < 0) {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ return;
+ }
+ CFX_WideString wsValue;
+ FX_BOOL bHasItem = pWidgetData->GetChoiceListItem(wsValue, iIndex, TRUE);
+ if (bHasItem) {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), FX_UTF8Encode(wsValue, wsValue.GetLength()));
+ } else {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ }
+}
+void CXFA_Node::Script_Field_BoundItem(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"boundItem"));
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CFX_ByteString bsValue = pArguments->GetUTF8String(0);
+ CFX_WideString wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ CFX_WideString wsBoundValue;
+ pWidgetData->GetItemValue(wsValue, wsBoundValue);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsBoundValue));
+ }
+}
+void CXFA_Node::Script_Field_GetItemState(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"getItemState"));
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ FX_BOOL bValue = pWidgetData->GetItemState(iIndex);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetBoolean(hValue, bValue);
+ }
+}
+void CXFA_Node::Script_Field_ExecCalculate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate, FALSE, FALSE);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execCalculate"));
+ }
+}
+void CXFA_Node::Script_Field_SetItems(CFXJSE_Arguments* pArguments)
+{
+}
+void CXFA_Node::Script_Field_GetDisplayItem(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"getDisplayItem"));
+ return;
+ }
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ if (iIndex < 0) {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ return;
+ }
+ CFX_WideString wsValue;
+ FX_BOOL bHasItem = pWidgetData->GetChoiceListItem(wsValue, iIndex, FALSE);
+ if (bHasItem) {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), FX_UTF8Encode(wsValue, wsValue.GetLength()));
+ } else {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ }
+}
+void CXFA_Node::Script_Field_SetItemState(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 2) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"setItemState"));
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ FX_BOOL bAdd = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+ if (bAdd) {
+ pWidgetData->SetItemState(iIndex, TRUE, TRUE, TRUE);
+ } else {
+ if (pWidgetData->GetItemState(iIndex)) {
+ pWidgetData->SetItemState(iIndex, FALSE, TRUE, TRUE);
+ }
+ }
+}
+void CXFA_Node::Script_Field_AddItem(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 2) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"addItem"));
+ return;
+ }
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ return;
+ }
+ CFX_WideString wsLabel;
+ CFX_WideString wsValue;
+ if (iLength >= 1) {
+ CFX_ByteString bsLable = pArguments->GetUTF8String(0);
+ wsLabel = CFX_WideString::FromUTF8(bsLable, bsLable.GetLength());
+ }
+ if (iLength >= 2) {
+ CFX_ByteString bsValue = pArguments->GetUTF8String(1);
+ wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ }
+ pWidgetData->InsertItem(wsLabel, wsValue, -1, TRUE);
+}
+void CXFA_Node::Script_Field_ExecValidate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FX_INT32 iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate, FALSE, FALSE);
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execValidate"));
+ }
+}
+void CXFA_Node::Script_ExclGroup_ErrorText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+void CXFA_Node::Script_ExclGroup_DefaultAndRawValue(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if(!pWidgetData) {
+ return;
+ }
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ pWidgetData->SetSelectedMemberByValue(CFX_WideString::FromUTF8(bsValue, bsValue.GetLength()), TRUE, TRUE);
+ } else {
+ CFX_WideString wsValue = GetScriptContent(TRUE);
+ XFA_VERSION curVersion = GetDocument()->GetCurVersionMode();
+ if (wsValue.IsEmpty() && curVersion >= XFA_VERSION_300) {
+ FXJSE_Value_SetNull(hValue);
+ } else {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+ }
+ }
+}
+void CXFA_Node::Script_ExclGroup_Transient(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_ExclGroup_ExecEvent(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ CFX_ByteString eventString = pArguments->GetUTF8String(0);
+ execSingleEventByName(CFX_WideString::FromUTF8(eventString, eventString.GetLength()), XFA_ELEMENT_ExclGroup);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execEvent"));
+ }
+}
+void CXFA_Node::Script_ExclGroup_SelectedMember(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if ((argc == 0) || (argc == 1)) {
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ } else {
+ CXFA_Node * pReturnNode = NULL;
+ if (argc == 0) {
+ pReturnNode = pWidgetData->GetSelectedMember();
+ } else {
+ CFX_ByteString szName;
+ szName = pArguments->GetUTF8String(0);
+ pReturnNode = pWidgetData->SetSelectedMember(CFX_WideString::FromUTF8(szName, szName.GetLength()));
+ }
+ if (pReturnNode) {
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pReturnNode));
+ } else {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ }
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"selectedMember"));
+ }
+}
+void CXFA_Node::Script_ExclGroup_ExecInitialize(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execInitialize"));
+ }
+}
+void CXFA_Node::Script_ExclGroup_ExecCalculate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execCalculate"));
+ }
+}
+void CXFA_Node::Script_ExclGroup_ExecValidate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FX_INT32 iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execValidate"));
+ }
+}
+static CXFA_Node* XFA_ScriptInstanceManager_GetItem(CXFA_Node *pInstMgrNode, FX_INT32 iIndex)
+{
+ ASSERT(pInstMgrNode);
+ FX_INT32 iCount = 0;
+ FX_DWORD dwNameHash = 0;
+ for(CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_ELEMENT eCurType = pNode->GetClassID();
+ if (eCurType == XFA_ELEMENT_InstanceManager) {
+ break;
+ }
+ if ((eCurType != XFA_ELEMENT_Subform) && (eCurType != XFA_ELEMENT_SubformSet)) {
+ continue;
+ }
+ if (iCount == 0) {
+ CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+ CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
+ if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' || wsInstName.Mid(1) != wsName) {
+ return NULL;
+ }
+ dwNameHash = pNode->GetNameHash();
+ }
+ if (dwNameHash != pNode->GetNameHash()) {
+ break;
+ }
+ iCount ++;
+ if (iCount > iIndex) {
+ return pNode;
+ }
+ }
+ return NULL;
+}
+void CXFA_Node::Script_Som_InstanceIndex(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ FX_INT32 iTo = FXJSE_Value_ToInteger(hValue);
+ FX_INT32 iFrom = Subform_and_SubformSet_InstanceIndex();
+ CXFA_Node *pManagerNode = NULL;
+ for (CXFA_Node *pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode != NULL; pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+ if (pNode->GetClassID() == XFA_ELEMENT_InstanceManager) {
+ pManagerNode = pNode;
+ break;
+ }
+ }
+ if (pManagerNode) {
+ pManagerNode->InstanceManager_MoveInstance(iTo, iFrom);
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CXFA_Node* pToInstance = XFA_ScriptInstanceManager_GetItem(pManagerNode, iTo);
+ if (pToInstance && pToInstance->GetClassID() == XFA_ELEMENT_Subform) {
+ pNotify->RunSubformIndexChange(pToInstance);
+ }
+ CXFA_Node* pFromInstance = XFA_ScriptInstanceManager_GetItem(pManagerNode, iFrom);
+ if (pFromInstance && pFromInstance->GetClassID() == XFA_ELEMENT_Subform) {
+ pNotify->RunSubformIndexChange(pFromInstance);
+ }
+ }
+ } else {
+ FXJSE_Value_SetInteger(hValue, Subform_and_SubformSet_InstanceIndex());
+ }
+}
+void CXFA_Node::Script_Subform_InstanceManager(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ CFX_WideStringC wsName = this->GetCData(XFA_ATTRIBUTE_Name);
+ CXFA_Node* pInstanceMgr = NULL;
+ for (CXFA_Node *pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode != NULL; pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+ if (pNode->GetClassID() == XFA_ELEMENT_InstanceManager) {
+ CFX_WideStringC wsInstMgrName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+ if (wsInstMgrName.GetLength() >= 1 && wsInstMgrName.GetAt(0) == '_' && wsInstMgrName.Mid(1) == wsName) {
+ pInstanceMgr = pNode;
+ }
+ break;
+ }
+ }
+ if (pInstanceMgr) {
+ FXJSE_Value_Set(hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(pInstanceMgr));
+ } else {
+ FXJSE_Value_SetNull(hValue);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+void CXFA_Node::Script_Subform_Locale(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ CFX_ByteString bsLocaleName;
+ FXJSE_Value_ToUTF8String(hValue, bsLocaleName);
+ this->SetCData(XFA_ATTRIBUTE_Locale, CFX_WideString::FromUTF8(bsLocaleName, bsLocaleName.GetLength()), TRUE, TRUE);
+ } else {
+ CFX_WideString wsLocaleName;
+ GetLocaleName(wsLocaleName);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsLocaleName, wsLocaleName.GetLength()));
+ }
+}
+void CXFA_Node::Script_Subform_ExecEvent(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ CFX_ByteString eventString = pArguments->GetUTF8String(0);
+ execSingleEventByName(CFX_WideString::FromUTF8(eventString, eventString.GetLength()), XFA_ELEMENT_Subform);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execEvent"));
+ }
+}
+void CXFA_Node::Script_Subform_ExecInitialize(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execInitialize"));
+ }
+}
+void CXFA_Node::Script_Subform_ExecCalculate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execCalculate"));
+ }
+}
+void CXFA_Node::Script_Subform_ExecValidate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FX_INT32 iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execValidate"));
+ }
+}
+void CXFA_Node::Script_Subform_GetInvalidObjects(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"getInvalidObjects"));
+ }
+}
+FX_INT32 CXFA_Node::Subform_and_SubformSet_InstanceIndex()
+{
+ FX_INT32 index = 0;
+ for (CXFA_Node *pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode != NULL; pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+ if ((pNode->GetClassID() == XFA_ELEMENT_Subform) || (pNode->GetClassID() == XFA_ELEMENT_SubformSet)) {
+ index++;
+ } else {
+ break;
+ }
+ }
+ return index;
+}
+void CXFA_Node::Script_Template_FormNodes(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"formNodes"));
+ }
+}
+void CXFA_Node::Script_Template_Remerge(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ m_pDocument->DoDataRemerge(TRUE);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"remerge"));
+ }
+}
+void CXFA_Node::Script_Template_ExecInitialize(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execInitialize"));
+ }
+}
+void CXFA_Node::Script_Template_CreateNode(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if ((argc > 0) && (argc < 4)) {
+ CFX_WideString strTagName;
+ CFX_WideString strName;
+ CFX_WideString strNameSpace;
+ CFX_ByteString bsTagName = pArguments->GetUTF8String(0);
+ strTagName = CFX_WideString::FromUTF8(bsTagName, bsTagName.GetLength());
+ if (argc > 1) {
+ CFX_ByteString bsName = pArguments->GetUTF8String(1);
+ strName = CFX_WideString::FromUTF8(bsName, bsName.GetLength());
+ if (argc == 3) {
+ CFX_ByteString bsNameSpace = pArguments->GetUTF8String(2);
+ strNameSpace = CFX_WideString::FromUTF8(bsNameSpace, bsNameSpace.GetLength());
+ }
+ }
+ XFA_LPCELEMENTINFO pElement = XFA_GetElementByName(strTagName);
+ CXFA_Node *pNewNode = CreateSamePacketNode(pElement->eName);
+ if (!pNewNode) {
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ } else {
+ if (!strName.IsEmpty()) {
+ if ( XFA_GetAttributeOfElement(pElement->eName, XFA_ATTRIBUTE_Name, XFA_XDPPACKET_UNKNOWN)) {
+ pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, strName, TRUE);
+ if (pNewNode->GetPacketID() == XFA_XDPPACKET_Datasets) {
+ pNewNode->CreateXMLMappingNode();
+ }
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_NOT_HAVE_PROPERTY, (FX_LPCWSTR)strTagName, (FX_LPCWSTR)(L"name"));
+ }
+ } else {
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewNode));
+ }
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"createNode"));
+ }
+}
+void CXFA_Node::Script_Template_Recalculate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ FX_BOOL bScriptFlags = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"recalculate"));
+ }
+}
+void CXFA_Node::Script_Template_ExecCalculate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execCalculate"));
+ }
+}
+void CXFA_Node::Script_Template_ExecValidate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execValidate"));
+ }
+}
+void CXFA_Node::Script_Manifest_Evaluate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ CXFA_WidgetData* pWidgetData = GetWidgetData();
+ if (!pWidgetData) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), TRUE);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"evaluate"));
+ }
+}
+void CXFA_Node::Script_InstanceManager_Max(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ } else {
+ CXFA_Occur nodeOccur = GetOccurNode();
+ FXJSE_Value_SetInteger(hValue, nodeOccur.GetMax());
+ }
+}
+void CXFA_Node::Script_InstanceManager_Min(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ } else {
+ CXFA_Occur nodeOccur = GetOccurNode();
+ FXJSE_Value_SetInteger(hValue, nodeOccur.GetMin());
+ }
+}
+static FX_INT32 XFA_ScriptInstanceManager_GetCount(CXFA_Node *pInstMgrNode)
+{
+ ASSERT(pInstMgrNode);
+ FX_INT32 iCount = 0;
+ FX_DWORD dwNameHash = 0;
+ for(CXFA_Node* pNode = pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_ELEMENT eCurType = pNode->GetClassID();
+ if (eCurType == XFA_ELEMENT_InstanceManager) {
+ break;
+ }
+ if ((eCurType != XFA_ELEMENT_Subform) && (eCurType != XFA_ELEMENT_SubformSet)) {
+ continue;
+ }
+ if (iCount == 0) {
+ CFX_WideStringC wsName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+ CFX_WideStringC wsInstName = pInstMgrNode->GetCData(XFA_ATTRIBUTE_Name);
+ if (wsInstName.GetLength() < 1 || wsInstName.GetAt(0) != '_' || wsInstName.Mid(1) != wsName) {
+ return iCount;
+ }
+ dwNameHash = pNode->GetNameHash();
+ }
+ if (dwNameHash != pNode->GetNameHash()) {
+ break;
+ }
+ iCount ++;
+ }
+ return iCount;
+}
+static void XFA_ScriptInstanceManager_ReorderDataNodes_SortNodeArrayByDocumentIdx(const CXFA_NodeSet& rgNodeSet, CXFA_NodeArray& rgNodeArray, CFX_ArrayTemplate<FX_INT32>& rgIdxArray)
+{
+ FX_INT32 iCount = rgNodeSet.GetCount();
+ rgNodeArray.SetSize(iCount);
+ rgIdxArray.SetSize(iCount);
+ if(iCount == 0) {
+ return;
+ }
+ FX_INT32 iIndex = -1, iTotalIndex = -1;
+ CXFA_Node* pNode = NULL;
+ FX_POSITION pos = rgNodeSet.GetStartPosition();
+ rgNodeSet.GetNextAssoc(pos, pNode);
+ for(pNode = pNode->GetNodeItem(XFA_NODEITEM_Parent)->GetNodeItem(XFA_NODEITEM_FirstChild);
+ pNode && iIndex < iCount;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ iTotalIndex++;
+ if(rgNodeSet.Lookup(pNode)) {
+ iIndex ++;
+ rgNodeArray[iIndex] = pNode;
+ rgIdxArray[iIndex] = iTotalIndex;
+ }
+ }
+}
+struct CXFA_DualNodeArray : CFX_Object {
+ CXFA_NodeSet firstNodeList;
+ CXFA_NodeSet secondNodeList;
+};
+static void XFA_ScriptInstanceManager_ReorderDataNodes(CXFA_NodeSet& sSet1, CXFA_NodeSet& sSet2, FX_BOOL bInsertBefore)
+{
+ CFX_MapPtrTemplate<CXFA_Node*, CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>*> rgNodeListMap;
+ FX_POSITION pos;
+ pos = sSet1.GetStartPosition();
+ while(pos) {
+ CXFA_Node* pNode = NULL;
+ sSet1.GetNextAssoc(pos, pNode);
+ CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ FX_DWORD dwNameHash = pNode->GetNameHash();
+ if(!pParentNode || !dwNameHash) {
+ continue;
+ }
+ CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>* pNodeListChildMap = rgNodeListMap[pParentNode];
+ if(!pNodeListChildMap) {
+ rgNodeListMap[pParentNode] = pNodeListChildMap = FX_NEW CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>;
+ }
+ CXFA_DualNodeArray* pDualNodeArray = (*pNodeListChildMap)[dwNameHash];
+ if(!pDualNodeArray) {
+ (*pNodeListChildMap)[dwNameHash] = pDualNodeArray = FX_NEW CXFA_DualNodeArray;
+ }
+ pDualNodeArray->firstNodeList.Add(pNode);
+ }
+ pos = sSet2.GetStartPosition();
+ while(pos) {
+ CXFA_Node* pNode = NULL;
+ sSet2.GetNextAssoc(pos, pNode);
+ CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ FX_DWORD dwNameHash = pNode->GetNameHash();
+ if(!pParentNode || !dwNameHash) {
+ continue;
+ }
+ CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>* pNodeListChildMap = rgNodeListMap[pParentNode];
+ if(!pNodeListChildMap) {
+ rgNodeListMap[pParentNode] = pNodeListChildMap = FX_NEW CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>;
+ }
+ CXFA_DualNodeArray* pDualNodeArray = (*pNodeListChildMap)[dwNameHash];
+ if(!pDualNodeArray) {
+ (*pNodeListChildMap)[dwNameHash] = pDualNodeArray = FX_NEW CXFA_DualNodeArray;
+ }
+ if(pDualNodeArray->firstNodeList.Lookup(pNode)) {
+ pDualNodeArray->firstNodeList.RemoveKey(pNode);
+ } else {
+ pDualNodeArray->secondNodeList.Add(pNode);
+ }
+ }
+ pos = rgNodeListMap.GetStartPosition();
+ while (pos) {
+ CXFA_Node* pParentNode = NULL;
+ CFX_MapPtrTemplate<FX_DWORD, CXFA_DualNodeArray*>* pNodeListChildMap = NULL;
+ rgNodeListMap.GetNextAssoc(pos, pParentNode, pNodeListChildMap);
+ if(!pNodeListChildMap) {
+ continue;
+ }
+ FX_POSITION childpos = pNodeListChildMap->GetStartPosition();
+ while(childpos) {
+ FX_DWORD dwNameHash = 0;
+ CXFA_DualNodeArray* pDualNodeArray = NULL;
+ pNodeListChildMap->GetNextAssoc(childpos, dwNameHash, pDualNodeArray);
+ if(!pDualNodeArray) {
+ continue;
+ }
+ if(pDualNodeArray->firstNodeList.GetCount() != 0 && pDualNodeArray->secondNodeList.GetCount() != 0) {
+ CXFA_NodeArray rgNodeArray1, rgNodeArray2;
+ CFX_ArrayTemplate<FX_INT32> rgIdxArray1, rgIdxArray2;
+ XFA_ScriptInstanceManager_ReorderDataNodes_SortNodeArrayByDocumentIdx(pDualNodeArray->firstNodeList, rgNodeArray1, rgIdxArray1);
+ XFA_ScriptInstanceManager_ReorderDataNodes_SortNodeArrayByDocumentIdx(pDualNodeArray->secondNodeList, rgNodeArray2, rgIdxArray2);
+ FX_INT32 iLimit;
+ CXFA_Node *pParentNode = NULL, *pBeforeNode = NULL;
+ if(bInsertBefore) {
+ iLimit = rgIdxArray2[0];
+ pBeforeNode = rgNodeArray2[0];
+ pParentNode = pBeforeNode->GetNodeItem(XFA_NODEITEM_Parent);
+ } else {
+ iLimit = rgIdxArray2[rgIdxArray2.GetSize() - 1];
+ CXFA_Node *pLastNode = rgNodeArray2[rgIdxArray2.GetSize() - 1];
+ pParentNode = pLastNode->GetNodeItem(XFA_NODEITEM_Parent);
+ pBeforeNode = pLastNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ for(FX_INT32 iIdx = 0, iCount = rgIdxArray1.GetSize(); iIdx < iCount; iIdx++) {
+ CXFA_Node* pCurNode = rgNodeArray1[iIdx];
+ pParentNode->RemoveChild(pCurNode);
+ pParentNode->InsertChild(pCurNode, pBeforeNode);
+ }
+ }
+ delete pDualNodeArray;
+ }
+ pNodeListChildMap->RemoveAll();
+ }
+ rgNodeListMap.RemoveAll();
+}
+static void XFA_ScriptInstanceManager_InsertItem(CXFA_Node *pInstMgrNode, CXFA_Node *pNewInstance, FX_INT32 iPos, FX_INT32 iCount = -1, FX_BOOL bMoveDataBindingNodes = TRUE)
+{
+ if(iCount < 0) {
+ iCount = XFA_ScriptInstanceManager_GetCount(pInstMgrNode);
+ }
+ if(iPos < 0) {
+ iPos = iCount;
+ }
+ if(iPos == iCount) {
+ CXFA_Node* pNextSibling = iCount > 0 ? XFA_ScriptInstanceManager_GetItem(pInstMgrNode, iCount - 1)->GetNodeItem(XFA_NODEITEM_NextSibling)
+ : pInstMgrNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)->InsertChild(pNewInstance, pNextSibling);
+ if(bMoveDataBindingNodes) {
+ CXFA_NodeSet sNew, sAfter;
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorNew(pNewInstance);
+ for(CXFA_Node *pNode = sIteratorNew.GetCurrent(); pNode; pNode = sIteratorNew.MoveToNext()) {
+ CXFA_Node *pDataNode = pNode->GetBindData();
+ if(!pDataNode) {
+ continue;
+ }
+ sNew.Add(pDataNode);
+ }
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorAfter(pNextSibling);
+ for(CXFA_Node *pNode = sIteratorAfter.GetCurrent(); pNode; pNode = sIteratorAfter.MoveToNext()) {
+ CXFA_Node *pDataNode = pNode->GetBindData();
+ if(!pDataNode) {
+ continue;
+ }
+ sAfter.Add(pDataNode);
+ }
+ XFA_ScriptInstanceManager_ReorderDataNodes(sNew, sAfter, FALSE);
+ }
+ } else {
+ CXFA_Node * pBeforeInstance = XFA_ScriptInstanceManager_GetItem(pInstMgrNode, iPos);
+ pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)->InsertChild(pNewInstance, pBeforeInstance);
+ if(bMoveDataBindingNodes) {
+ CXFA_NodeSet sNew, sBefore;
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorNew(pNewInstance);
+ for(CXFA_Node *pNode = sIteratorNew.GetCurrent(); pNode; pNode = sIteratorNew.MoveToNext()) {
+ CXFA_Node *pDataNode = pNode->GetBindData();
+ if(!pDataNode) {
+ continue;
+ }
+ sNew.Add(pDataNode);
+ }
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIteratorBefore(pBeforeInstance);
+ for(CXFA_Node *pNode = sIteratorBefore.GetCurrent(); pNode; pNode = sIteratorBefore.MoveToNext()) {
+ CXFA_Node *pDataNode = pNode->GetBindData();
+ if(!pDataNode) {
+ continue;
+ }
+ sBefore.Add(pDataNode);
+ }
+ XFA_ScriptInstanceManager_ReorderDataNodes(sNew, sBefore, TRUE);
+ }
+ }
+}
+static void XFA_ScriptInstanceManager_RemoveItem(CXFA_Node *pInstMgrNode, CXFA_Node *pRemoveInstance, FX_BOOL bRemoveDataBinding = TRUE)
+{
+ pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent)->RemoveChild(pRemoveInstance);
+ if(!bRemoveDataBinding) {
+ return;
+ }
+ CXFA_NodeIteratorTemplate<CXFA_Node, CXFA_TraverseStrategy_XFAContainerNode> sIterator(pRemoveInstance);
+ for(CXFA_Node* pFormNode = sIterator.GetCurrent(); pFormNode; pFormNode = sIterator.MoveToNext()) {
+ CXFA_Node* pDataNode = pFormNode->GetBindData();
+ if(!pDataNode) {
+ continue;
+ }
+ if(pDataNode->RemoveBindItem(pFormNode) == 0) {
+ if(CXFA_Node* pDataParent = pDataNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+ pDataParent->RemoveChild(pDataNode);
+ }
+ }
+ pFormNode->SetObject(XFA_ATTRIBUTE_BindingNode, NULL);
+ }
+}
+static CXFA_Node* XFA_ScriptInstanceManager_CreateInstance(CXFA_Node *pInstMgrNode, FX_BOOL bDataMerge)
+{
+ CXFA_Document* pDocument = pInstMgrNode->GetDocument();
+ CXFA_Node* pTemplateNode = pInstMgrNode->GetTemplateNode();
+ CXFA_Node* pFormParent = pInstMgrNode->GetNodeItem(XFA_NODEITEM_Parent);
+ CXFA_Node* pDataScope = NULL;
+ for(CXFA_Node* pRootBoundNode = pFormParent; pRootBoundNode && pRootBoundNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode; pRootBoundNode = pRootBoundNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+ pDataScope = pRootBoundNode->GetBindData();
+ if(pDataScope) {
+ break;
+ }
+ }
+ if(!pDataScope) {
+ pDataScope = (CXFA_Node*)pDocument->GetXFANode(XFA_HASHCODE_Record);
+ ASSERT(pDataScope);
+ }
+ CXFA_Node *pInstance = pDocument->DataMerge_CopyContainer(pTemplateNode, pFormParent, pDataScope, TRUE, bDataMerge);
+ if(pInstance) {
+ pDocument->DataMerge_UpdateBindingRelations(pInstance);
+ pFormParent->RemoveChild(pInstance);
+ }
+ return pInstance;
+}
+void CXFA_Node::Script_InstanceManager_Count(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ FX_INT32 iDesired = FXJSE_Value_ToInteger(hValue);
+ InstanceManager_SetInstances(iDesired);
+ } else {
+ FXJSE_Value_SetInteger(hValue, XFA_ScriptInstanceManager_GetCount(this));
+ }
+}
+void CXFA_Node::Script_InstanceManager_MoveInstance(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc != 2) {
+ FXJSE_Value_SetUndefined(pArguments->GetReturnValue());
+ return;
+ }
+ FX_INT32 iFrom = pArguments->GetInt32(0);
+ FX_INT32 iTo = pArguments->GetInt32(1);
+ InstanceManager_MoveInstance(iTo, iFrom);
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CXFA_Node* pToInstance = XFA_ScriptInstanceManager_GetItem(this, iTo);
+ if (pToInstance && pToInstance->GetClassID() == XFA_ELEMENT_Subform) {
+ pNotify->RunSubformIndexChange(pToInstance);
+ }
+ CXFA_Node* pFromInstance = XFA_ScriptInstanceManager_GetItem(this, iFrom);
+ if (pFromInstance && pFromInstance->GetClassID() == XFA_ELEMENT_Subform) {
+ pNotify->RunSubformIndexChange(pFromInstance);
+ }
+}
+void CXFA_Node::Script_InstanceManager_RemoveInstance(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc != 1) {
+ FXJSE_Value_SetUndefined(pArguments->GetReturnValue());
+ return;
+ }
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ FX_INT32 iCount = XFA_ScriptInstanceManager_GetCount(this);
+ if (iIndex < 0 || iIndex >= iCount) {
+ ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+ return;
+ }
+ CXFA_Occur nodeOccur = GetOccurNode();
+ FX_INT32 iMin = nodeOccur.GetMin();
+ if (iCount - 1 < iMin) {
+ ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, (FX_LPCWSTR)(L"min"));
+ return;
+ }
+ CXFA_Node *pRemoveInstance = XFA_ScriptInstanceManager_GetItem(this, iIndex);
+ XFA_ScriptInstanceManager_RemoveItem(this, pRemoveInstance);
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (pNotify) {
+ for (FX_INT32 i = iIndex; i < iCount - 1; i++) {
+ CXFA_Node *pSubformInstance = XFA_ScriptInstanceManager_GetItem(this, i);
+ if (pSubformInstance && pSubformInstance->GetClassID() == XFA_ELEMENT_Subform) {
+ pNotify->RunSubformIndexChange(pSubformInstance);
+ }
+ }
+ }
+ CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+ if (!pLayoutPro) {
+ return;
+ }
+ pLayoutPro->AddChangedContainer((CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Form));
+}
+void CXFA_Node::Script_InstanceManager_SetInstances(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc != 1) {
+ FXJSE_Value_SetUndefined(pArguments->GetReturnValue());
+ return;
+ }
+ FX_INT32 iDesired = pArguments->GetInt32(0);
+ InstanceManager_SetInstances(iDesired);
+}
+void CXFA_Node::Script_InstanceManager_AddInstance(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if ((argc != 0) && (argc != 1)) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"addInstance"));
+ return;
+ }
+ FX_BOOL fFlags = TRUE;
+ if (argc == 1) {
+ fFlags = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+ }
+ FX_INT32 iCount = XFA_ScriptInstanceManager_GetCount(this);
+ CXFA_Occur nodeOccur = GetOccurNode();
+ FX_INT32 iMax = nodeOccur.GetMax();
+ if (iMax >= 0 && iCount >= iMax) {
+ ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, (FX_LPCWSTR)(L"max"));
+ return;
+ }
+ CXFA_Node* pNewInstance = XFA_ScriptInstanceManager_CreateInstance(this, fFlags);
+ XFA_ScriptInstanceManager_InsertItem(this, pNewInstance, iCount, iCount, FALSE);
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->RunNodeInitialize(pNewInstance);
+ CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+ if (!pLayoutPro) {
+ return;
+ }
+ pLayoutPro->AddChangedContainer((CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Form));
+}
+void CXFA_Node::Script_InstanceManager_InsertInstance(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if ((argc != 1) && (argc != 2)) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"insertInstance"));
+ return;
+ }
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ FX_BOOL bBind = FALSE;
+ if (argc == 2) {
+ bBind = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+ }
+ CXFA_Occur nodeOccur = GetOccurNode();
+ FX_INT32 iCount = XFA_ScriptInstanceManager_GetCount(this);
+ if (iIndex < 0 || iIndex > iCount) {
+ ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+ return;
+ }
+ FX_INT32 iMax = nodeOccur.GetMax();
+ if (iMax >= 0 && iCount >= iMax) {
+ ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, (FX_LPCWSTR)(L"max"));
+ return;
+ }
+ CXFA_Node* pNewInstance = XFA_ScriptInstanceManager_CreateInstance(this, bBind);
+ XFA_ScriptInstanceManager_InsertItem(this, pNewInstance, iIndex, iCount, TRUE);
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pNewInstance));
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->RunNodeInitialize(pNewInstance);
+ CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+ if (!pLayoutPro) {
+ return;
+ }
+ pLayoutPro->AddChangedContainer((CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Form));
+}
+FX_INT32 CXFA_Node::InstanceManager_SetInstances(FX_INT32 iDesired)
+{
+ CXFA_Occur nodeOccur = GetOccurNode();
+ FX_INT32 iMax = nodeOccur.GetMax();
+ FX_INT32 iMin = nodeOccur.GetMin();
+ if (iDesired < iMin) {
+ ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, (FX_LPCWSTR)(L"min"));
+ return 1;
+ }
+ if ((iMax >= 0) && (iDesired > iMax)) {
+ ThrowScriptErrorMessage(XFA_IDS_VIOLATE_BOUNDARY, (FX_LPCWSTR)(L"max"));
+ return 2;
+ }
+ FX_INT32 iCount = XFA_ScriptInstanceManager_GetCount(this);
+ if (iDesired == iCount) {
+ return 0;
+ }
+ if(iDesired < iCount) {
+ CFX_WideStringC wsInstManagerName = this->GetCData(XFA_ATTRIBUTE_Name);
+ CFX_WideString wsInstanceName = wsInstManagerName.IsEmpty() ? wsInstManagerName : wsInstManagerName.Mid(1);
+ FX_DWORD dInstanceNameHash = wsInstanceName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsInstanceName, wsInstanceName.GetLength());
+ CXFA_Node* pPrevSibling = (iDesired == 0) ? this : XFA_ScriptInstanceManager_GetItem(this, iDesired - 1);
+ while(iCount > iDesired) {
+ CXFA_Node* pRemoveInstance = pPrevSibling->GetNodeItem(XFA_NODEITEM_NextSibling);
+ if (pRemoveInstance->GetClassID() != XFA_ELEMENT_Subform && pRemoveInstance->GetClassID() != XFA_ELEMENT_SubformSet) {
+ continue;
+ }
+ if (pRemoveInstance->GetClassID() == XFA_ELEMENT_InstanceManager) {
+ FXSYS_assert(FALSE);
+ break;
+ }
+ if (pRemoveInstance->GetNameHash() == dInstanceNameHash) {
+ XFA_ScriptInstanceManager_RemoveItem(this, pRemoveInstance);
+ iCount--;
+ }
+ }
+ } else if (iDesired > iCount) {
+ CXFA_Node* pTemplateNode = GetTemplateNode();
+ CXFA_Node* pFormNode = GetNodeItem(XFA_NODEITEM_NextSibling);
+ while (iCount < iDesired) {
+ CXFA_Node* pNewInstance = XFA_ScriptInstanceManager_CreateInstance(this, TRUE);
+ XFA_ScriptInstanceManager_InsertItem(this, pNewInstance, iCount, iCount, FALSE);
+ iCount ++;
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return 0;
+ }
+ pNotify->RunNodeInitialize(pNewInstance);
+ }
+ }
+ CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+ if (!pLayoutPro) {
+ return 0;
+ }
+ pLayoutPro->AddChangedContainer((CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Form));
+ return 0;
+}
+FX_INT32 CXFA_Node::InstanceManager_MoveInstance(FX_INT32 iTo, FX_INT32 iFrom)
+{
+ FX_INT32 iCount = XFA_ScriptInstanceManager_GetCount(this);
+ if (iFrom > iCount || iTo > iCount - 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+ return 1;
+ }
+ if (iFrom < 0 || iTo < 0 || iFrom == iTo) {
+ return 0;
+ }
+ CXFA_Node * pMoveInstance = XFA_ScriptInstanceManager_GetItem(this, iFrom);
+ XFA_ScriptInstanceManager_RemoveItem(this, pMoveInstance, FALSE);
+ XFA_ScriptInstanceManager_InsertItem(this, pMoveInstance, iTo, iCount - 1, TRUE);
+ CXFA_LayoutProcessor* pLayoutPro = m_pDocument->GetLayoutProcessor();
+ if (!pLayoutPro) {
+ return 0;
+ }
+ pLayoutPro->AddChangedContainer((CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Form));
+ return 0;
+}
+void CXFA_Node::Script_Occur_Max(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_Occur occur(this);
+ if (bSetting) {
+ FX_INT32 iMax = FXJSE_Value_ToInteger(hValue);
+ occur.SetMax(iMax);
+ } else {
+ FXJSE_Value_SetInteger(hValue, occur.GetMax());
+ }
+}
+void CXFA_Node::Script_Occur_Min(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ CXFA_Occur occur(this);
+ if (bSetting) {
+ FX_INT32 iMin = FXJSE_Value_ToInteger(hValue);
+ occur.SetMin(iMin);
+ } else {
+ FXJSE_Value_SetInteger(hValue, occur.GetMin());
+ }
+}
+void CXFA_Node::Script_Desc_Metadata(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if ((argc == 0) || (argc == 1)) {
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), FX_BSTRC(""));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"metadata"));
+ }
+}
+void CXFA_Node::Script_Form_FormNodes(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ CXFA_Node * pDataNode = (CXFA_Node *)pArguments->GetObject(0);
+ if (pDataNode) {
+ CXFA_NodeArray formItems;
+ FX_INT32 iSize = pDataNode->GetBindItems(formItems);
+ CXFA_ArrayNodeList *pFormNodes = FX_NEW CXFA_ArrayNodeList(m_pDocument);
+ pFormNodes->SetArrayNodeList(formItems);
+ FXJSE_Value_SetObject(pArguments->GetReturnValue(), (CXFA_Object*)pFormNodes, m_pDocument->GetScriptContext()->GetJseNormalClass());
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"formNodes"));
+ }
+}
+void CXFA_Node::Script_Form_Remerge(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ m_pDocument->DoDataRemerge(TRUE);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"remerge"));
+ }
+}
+void CXFA_Node::Script_Form_ExecInitialize(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Initialize);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execInitialize"));
+ }
+}
+void CXFA_Node::Script_Form_Recalculate(CFXJSE_Arguments* pArguments)
+{
+ CXFA_EventParam* pEventParam = m_pDocument->GetScriptContext()->GetEventParam();
+ if (pEventParam->m_eType == XFA_EVENT_Calculate || pEventParam->m_eType == XFA_EVENT_InitCalculate) {
+ return;
+ }
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ FX_BOOL bScriptFlags = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bScriptFlags) {
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Ready, TRUE);
+ } else {
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"recalculate"));
+ }
+}
+void CXFA_Node::Script_Form_ExecCalculate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Calculate);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execCalculate"));
+ }
+}
+void CXFA_Node::Script_Form_ExecValidate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), FALSE);
+ } else {
+ FX_INT32 iRet = pNotify->ExecEventByDeepFirst(this, XFA_EVENT_Validate);
+ FXJSE_Value_SetBoolean(pArguments->GetReturnValue(), ((iRet == XFA_EVENTERROR_Error) ? FALSE : TRUE));
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"execValidate"));
+ }
+}
+void CXFA_Node::Script_Form_Checksum(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ CFX_ByteString bsChecksum;
+ FXJSE_Value_ToUTF8String(hValue, bsChecksum);
+ SetAttribute(XFA_ATTRIBUTE_Checksum, CFX_WideString::FromUTF8(bsChecksum, bsChecksum.GetLength()));
+ } else {
+ CFX_WideString wsChecksum;
+ GetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum, FALSE);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsChecksum, wsChecksum.GetLength()));
+ }
+}
+void CXFA_Node::Script_Packet_GetAttribute(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ CFX_ByteString bsAttributeName = pArguments->GetUTF8String(0);
+ CFX_WideString wsAttributeValue;
+ IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+ if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ ((IFDE_XMLElement *)pXMLNode)->GetString(CFX_WideString::FromUTF8(bsAttributeName, bsAttributeName.GetLength()), wsAttributeValue);
+ }
+ FXJSE_Value_SetUTF8String(pArguments->GetReturnValue(), FX_UTF8Encode(wsAttributeValue, wsAttributeValue.GetLength()));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"getAttribute"));
+ }
+}
+void CXFA_Node::Script_Packet_SetAttribute(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 2) {
+ CFX_ByteString bsValue = pArguments->GetUTF8String(0);
+ CFX_ByteString bsName = pArguments->GetUTF8String(1);
+ IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+ if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ ((IFDE_XMLElement *)pXMLNode)->SetString(CFX_WideString::FromUTF8(bsName, bsName.GetLength()), CFX_WideString::FromUTF8(bsValue, bsValue.GetLength()));
+ }
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"setAttribute"));
+ }
+}
+void CXFA_Node::Script_Packet_RemoveAttribute(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 1) {
+ CFX_ByteString bsName = pArguments->GetUTF8String(0);
+ CFX_WideString wsName = CFX_WideString::FromUTF8(bsName, bsName.GetLength());
+ IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+ if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement *)pXMLNode;
+ if (pXMLElement->HasAttribute(wsName)) {
+ pXMLElement->RemoveAttribute(wsName);
+ }
+ }
+ FXJSE_Value_SetNull(pArguments->GetReturnValue());
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"removeAttribute"));
+ }
+}
+void CXFA_Node::Script_Packet_Content(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ CFX_ByteString bsNewContent;
+ FXJSE_Value_ToUTF8String(hValue, bsNewContent);
+ IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+ if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement *)pXMLNode;
+ pXMLElement->SetTextData(CFX_WideString::FromUTF8(bsNewContent, bsNewContent.GetLength()));
+ }
+ } else {
+ CFX_WideString wsTextData;
+ IFDE_XMLNode* pXMLNode = GetXMLMappingNode();
+ if (pXMLNode && pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement *)pXMLNode;
+ pXMLElement->GetTextData(wsTextData);
+ }
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsTextData, wsTextData.GetLength()));
+ }
+}
+void CXFA_Node::Script_Source_Next(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"next"));
+ }
+}
+void CXFA_Node::Script_Source_CancelBatch(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"cancelBatch"));
+ }
+}
+void CXFA_Node::Script_Source_First(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"first"));
+ }
+}
+void CXFA_Node::Script_Source_UpdateBatch(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"updateBatch"));
+ }
+}
+void CXFA_Node::Script_Source_Previous(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"previous"));
+ }
+}
+void CXFA_Node::Script_Source_IsBOF(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"isBOF"));
+ }
+}
+void CXFA_Node::Script_Source_IsEOF(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"isEOF"));
+ }
+}
+void CXFA_Node::Script_Source_Cancel(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"cancel"));
+ }
+}
+void CXFA_Node::Script_Source_Update(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"update"));
+ }
+}
+void CXFA_Node::Script_Source_Open(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"open"));
+ }
+}
+void CXFA_Node::Script_Source_Delete(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"delete"));
+ }
+}
+void CXFA_Node::Script_Source_AddNew(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"addNew"));
+ }
+}
+void CXFA_Node::Script_Source_Requery(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"requery"));
+ }
+}
+void CXFA_Node::Script_Source_Resync(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"resync"));
+ }
+}
+void CXFA_Node::Script_Source_Close(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"close"));
+ }
+}
+void CXFA_Node::Script_Source_Last(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"last"));
+ }
+}
+void CXFA_Node::Script_Source_HasDataChanged(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if (argc == 0) {
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"hasDataChanged"));
+ }
+}
+void CXFA_Node::Script_Source_Db(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_Xfa_This(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!bSetting) {
+ CXFA_Object* pThis = m_pDocument->GetScriptContext()->GetThisObject();
+ FXSYS_assert(pThis);
+ FXJSE_Value_Set(hValue, m_pDocument->GetScriptContext()->GetJSValueFromMap(pThis));
+ }
+}
+void CXFA_Node::Script_Handler_Version(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_SubmitFormat_Mode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_Extras_Type(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CXFA_Node::Script_Script_Stateless(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ }
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(FX_WSTRC(L"0")));
+}
+void CXFA_Node::Script_Encrypt_Format(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+enum XFA_KEYTYPE {
+ XFA_KEYTYPE_Custom,
+ XFA_KEYTYPE_Element,
+};
+FX_LPVOID XFA_GetMapKey_Custom(FX_WSTR wsKey)
+{
+ FX_DWORD dwKey = FX_HashCode_String_GetW(wsKey.GetPtr(), wsKey.GetLength());
+ return (FX_LPVOID)(FX_UINTPTR)((dwKey << 1) | XFA_KEYTYPE_Custom);
+}
+FX_LPVOID XFA_GetMapKey_Element(XFA_ELEMENT eElement, XFA_ATTRIBUTE eAttribute)
+{
+ return (FX_LPVOID)(FX_UINTPTR)((eElement << 16) | (eAttribute << 8) | XFA_KEYTYPE_Element);
+}
+static inline FX_BOOL XFA_NodeData_PrepareKey(XFA_ELEMENT eElem, XFA_ATTRIBUTE eAttr, FX_LPVOID &pKey)
+{
+ pKey = XFA_GetMapKey_Element(eElem, eAttr);
+ return TRUE;
+}
+FX_BOOL CXFA_Node::HasAttribute(XFA_ATTRIBUTE eAttr, FX_BOOL bCanInherit )
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ return HasMapModuleKey(pKey, bCanInherit);
+}
+FX_BOOL CXFA_Node::SetAttribute(XFA_ATTRIBUTE eAttr, FX_WSTR wsValue, FX_BOOL bNotify )
+{
+ XFA_LPCATTRIBUTEINFO pAttr = XFA_GetAttributeByID(eAttr);
+ if (pAttr == NULL) {
+ return FALSE;
+ }
+ XFA_ATTRIBUTETYPE eType = pAttr->eType;
+ if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
+ XFA_LPCNOTSUREATTRIBUTE pNotsure = XFA_GetNotsureAttribute(GetClassID(), pAttr->eName);
+ eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
+ }
+ switch (eType) {
+ case XFA_ATTRIBUTETYPE_Enum: {
+ XFA_LPCATTRIBUTEENUMINFO pEnum = XFA_GetAttributeEnumByName(wsValue);
+ return SetEnum(pAttr->eName, pEnum ? pEnum->eName : (XFA_ATTRIBUTEENUM)(FX_INTPTR)(pAttr->pDefValue), bNotify);
+ }
+ break;
+ case XFA_ATTRIBUTETYPE_Cdata:
+ return SetCData(pAttr->eName, wsValue, bNotify);
+ case XFA_ATTRIBUTETYPE_Boolean:
+ return SetBoolean(pAttr->eName, wsValue != FX_WSTRC(L"0"), bNotify);
+ case XFA_ATTRIBUTETYPE_Integer:
+ return SetInteger(pAttr->eName, FXSYS_round(FX_wcstof(wsValue.GetPtr(), wsValue.GetLength())), bNotify);
+ case XFA_ATTRIBUTETYPE_Measure:
+ return SetMeasure(pAttr->eName, CXFA_Measurement(wsValue), bNotify);
+ default:
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_Node::GetAttribute(XFA_ATTRIBUTE eAttr, CFX_WideString &wsValue, FX_BOOL bUseDefault )
+{
+ XFA_LPCATTRIBUTEINFO pAttr = XFA_GetAttributeByID(eAttr);
+ if (pAttr == NULL) {
+ return FALSE;
+ }
+ XFA_ATTRIBUTETYPE eType = pAttr->eType;
+ if (eType == XFA_ATTRIBUTETYPE_NOTSURE) {
+ XFA_LPCNOTSUREATTRIBUTE pNotsure = XFA_GetNotsureAttribute(GetClassID(), pAttr->eName);
+ eType = pNotsure ? pNotsure->eType : XFA_ATTRIBUTETYPE_Cdata;
+ }
+ switch (eType) {
+ case XFA_ATTRIBUTETYPE_Enum: {
+ XFA_ATTRIBUTEENUM eValue;
+ if (!TryEnum(pAttr->eName, eValue, bUseDefault)) {
+ return FALSE;
+ }
+ wsValue = XFA_GetAttributeEnumByID(eValue)->pName;
+ return TRUE;
+ }
+ break;
+ case XFA_ATTRIBUTETYPE_Cdata: {
+ CFX_WideStringC wsValueC;
+ if (!TryCData(pAttr->eName, wsValueC, bUseDefault)) {
+ return FALSE;
+ }
+ wsValue = wsValueC;
+ return TRUE;
+ }
+ break;
+ case XFA_ATTRIBUTETYPE_Boolean: {
+ FX_BOOL bValue;
+ if (!TryBoolean(pAttr->eName, bValue, bUseDefault)) {
+ return FALSE;
+ }
+ wsValue = bValue ? FX_WSTRC(L"1") : FX_WSTRC(L"0");
+ return TRUE;
+ }
+ break;
+ case XFA_ATTRIBUTETYPE_Integer: {
+ FX_INT32 iValue;
+ if (!TryInteger(pAttr->eName, iValue, bUseDefault)) {
+ return FALSE;
+ }
+ wsValue.Format((FX_LPCWSTR)L"%d", iValue);
+ return TRUE;
+ }
+ break;
+ case XFA_ATTRIBUTETYPE_Measure: {
+ CXFA_Measurement mValue;
+ if (!TryMeasure(pAttr->eName, mValue, bUseDefault)) {
+ return FALSE;
+ }
+ mValue.ToString(wsValue);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_Node::SetAttribute(FX_WSTR wsAttr, FX_WSTR wsValue, FX_BOOL bNotify)
+{
+ XFA_LPCATTRIBUTEINFO pAttributeInfo = XFA_GetAttributeByName(wsValue);
+ if (pAttributeInfo) {
+ return SetAttribute(pAttributeInfo->eName, wsValue, bNotify);
+ }
+ FX_LPVOID pKey = XFA_GetMapKey_Custom(wsAttr);
+ SetMapModuleString(pKey, wsValue);
+ return TRUE;
+}
+FX_BOOL CXFA_Node::GetAttribute(FX_WSTR wsAttr, CFX_WideString &wsValue, FX_BOOL bUseDefault)
+{
+ XFA_LPCATTRIBUTEINFO pAttributeInfo = XFA_GetAttributeByName(wsAttr);
+ if (pAttributeInfo) {
+ return GetAttribute(pAttributeInfo->eName, wsValue, bUseDefault);
+ }
+ FX_LPVOID pKey = XFA_GetMapKey_Custom(wsAttr);
+ CFX_WideStringC wsValueC;
+ if (GetMapModuleString(pKey, wsValueC)) {
+ wsValue = wsValueC;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_Node::RemoveAttribute(FX_WSTR wsAttr)
+{
+ FX_LPVOID pKey = XFA_GetMapKey_Custom(wsAttr);
+ RemoveMapModuleKey(pKey);
+ return TRUE;
+}
+FX_BOOL CXFA_Node::TryBoolean(XFA_ATTRIBUTE eAttr, FX_BOOL &bValue, FX_BOOL bUseDefault )
+{
+ FX_LPVOID pValue = NULL;
+ if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Boolean, bUseDefault, pValue)) {
+ return FALSE;
+ }
+ bValue = (FX_BOOL)(FX_UINTPTR)pValue;
+ return TRUE;
+}
+FX_BOOL CXFA_Node::TryInteger(XFA_ATTRIBUTE eAttr, FX_INT32 &iValue, FX_BOOL bUseDefault)
+{
+ FX_LPVOID pValue = NULL;
+ if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Integer, bUseDefault, pValue)) {
+ return FALSE;
+ }
+ iValue = (FX_INT32)(FX_UINTPTR)pValue;
+ return TRUE;
+}
+FX_BOOL CXFA_Node::TryEnum(XFA_ATTRIBUTE eAttr, XFA_ATTRIBUTEENUM &eValue, FX_BOOL bUseDefault)
+{
+ FX_LPVOID pValue = NULL;
+ if (!GetValue(eAttr, XFA_ATTRIBUTETYPE_Enum, bUseDefault, pValue)) {
+ return FALSE;
+ }
+ eValue = (XFA_ATTRIBUTEENUM)(FX_UINTPTR)pValue;
+ return TRUE;
+}
+FX_BOOL CXFA_Node::SetMeasure(XFA_ATTRIBUTE eAttr, CXFA_Measurement mValue, FX_BOOL bNotify )
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ OnChanging(eAttr, &mValue, bNotify);
+ SetMapModuleBuffer(pKey, &mValue, sizeof(CXFA_Measurement));
+ OnChanged(eAttr, &mValue, bNotify);
+ return TRUE;
+}
+FX_BOOL CXFA_Node::TryMeasure(XFA_ATTRIBUTE eAttr, CXFA_Measurement &mValue, FX_BOOL bUseDefault)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ FX_LPVOID pValue;
+ FX_INT32 iBytes;
+ if(GetMapModuleBuffer(pKey, pValue, iBytes) && iBytes == sizeof(mValue)) {
+ FX_memcpy(&mValue, pValue, sizeof(mValue));
+ return TRUE;
+ }
+ if(bUseDefault && XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr, XFA_ATTRIBUTETYPE_Measure, m_ePacket)) {
+ FX_memcpy(&mValue, pValue, sizeof(mValue));
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_Node::SetCData(XFA_ATTRIBUTE eAttr, const CFX_WideString& wsValue, FX_BOOL bNotify, FX_BOOL bScriptModify)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ OnChanging(eAttr, (FX_LPVOID)(FX_LPCWSTR)wsValue, bNotify);
+ if (eAttr == XFA_ATTRIBUTE_Value) {
+ CFX_WideString *pClone = FX_NEW CFX_WideString(wsValue);
+ if (pClone == NULL) {
+ return FALSE;
+ }
+ SetUserData(pKey, pClone, &deleteWideStringCallBack);
+ } else {
+ SetMapModuleString(pKey, wsValue);
+ if(eAttr == XFA_ATTRIBUTE_Name) {
+ UpdateNameHash();
+ if (XFA_LPCJSBUILTININFO pBuiltin = XFA_GetJSBuiltinByHash(m_dwNameHash)) {
+ m_pDocument->GetScriptContext()->AddJSBuiltinObject(pBuiltin);
+ }
+ }
+ }
+ OnChanged(eAttr, (FX_LPVOID)(FX_LPCWSTR)wsValue, bNotify, bScriptModify);
+ if (IsNeedSavingXMLNode() && eAttr != XFA_ATTRIBUTE_QualifiedName && eAttr != XFA_ATTRIBUTE_BindingNode) {
+ if (eAttr == XFA_ATTRIBUTE_Name && (m_eNodeClass == XFA_ELEMENT_DataValue || m_eNodeClass == XFA_ELEMENT_DataGroup)) {
+ return TRUE;
+ }
+ if (eAttr == XFA_ATTRIBUTE_Value) {
+ FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
+ switch (eXMLType) {
+ case FDE_XMLNODE_Element:
+ if (IsAttributeInXML()) {
+ ((IFDE_XMLElement*)m_pXMLNode)->SetString(GetCData(XFA_ATTRIBUTE_QualifiedName), wsValue);
+ } else {
+ FX_BOOL bDeleteChildren = TRUE;
+ if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+ for (CXFA_Node* pChildDataNode = this->GetNodeItem(XFA_NODEITEM_FirstChild); pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ CXFA_NodeArray formNodes;
+ if (pChildDataNode->GetBindItems(formNodes) > 0) {
+ bDeleteChildren = FALSE;
+ break;
+ }
+ }
+ }
+ if (bDeleteChildren) {
+ ((IFDE_XMLElement*)m_pXMLNode)->DeleteChildren();
+ }
+ ((IFDE_XMLElement*)m_pXMLNode)->SetTextData(wsValue);
+ }
+ break;
+ case FDE_XMLNODE_Text:
+ ((IFDE_XMLText*)m_pXMLNode)->SetText(wsValue);
+ break;
+ default:
+ FXSYS_assert(0);
+ }
+ return TRUE;
+ }
+ XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttr);
+ if (pInfo) {
+ FXSYS_assert(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
+ CFX_WideString wsAttrName = pInfo->pName;
+ if(pInfo->eName == XFA_ATTRIBUTE_ContentType) {
+ wsAttrName = FX_WSTRC(L"xfa:") + wsAttrName;
+ }
+ ((IFDE_XMLElement*)m_pXMLNode)->SetString(wsAttrName, wsValue);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_Node::SetAttributeValue(const CFX_WideString& wsValue, const CFX_WideString& wsXMLValue, FX_BOOL bNotify, FX_BOOL bScriptModify)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), XFA_ATTRIBUTE_Value, pKey)) {
+ return FALSE;
+ }
+ OnChanging(XFA_ATTRIBUTE_Value, (FX_LPVOID)(FX_LPCWSTR)wsValue, bNotify);
+ CFX_WideString *pClone = FX_NEW CFX_WideString(wsValue);
+ if (pClone == NULL) {
+ return FALSE;
+ }
+ SetUserData(pKey, pClone, &deleteWideStringCallBack);
+ OnChanged(XFA_ATTRIBUTE_Value, (FX_LPVOID)(FX_LPCWSTR)wsValue, bNotify, bScriptModify);
+ if (IsNeedSavingXMLNode()) {
+ FDE_XMLNODETYPE eXMLType = m_pXMLNode->GetType();
+ switch (eXMLType) {
+ case FDE_XMLNODE_Element:
+ if (IsAttributeInXML()) {
+ ((IFDE_XMLElement*)m_pXMLNode)->SetString(GetCData(XFA_ATTRIBUTE_QualifiedName), wsXMLValue);
+ } else {
+ FX_BOOL bDeleteChildren = TRUE;
+ if (GetPacketID() == XFA_XDPPACKET_Datasets) {
+ for (CXFA_Node* pChildDataNode = this->GetNodeItem(XFA_NODEITEM_FirstChild); pChildDataNode; pChildDataNode = pChildDataNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ CXFA_NodeArray formNodes;
+ if (pChildDataNode->GetBindItems(formNodes) > 0) {
+ bDeleteChildren = FALSE;
+ break;
+ }
+ }
+ }
+ if (bDeleteChildren) {
+ ((IFDE_XMLElement*)m_pXMLNode)->DeleteChildren();
+ }
+ ((IFDE_XMLElement*)m_pXMLNode)->SetTextData(wsXMLValue);
+ }
+ break;
+ case FDE_XMLNODE_Text:
+ ((IFDE_XMLText*)m_pXMLNode)->SetText(wsXMLValue);
+ break;
+ default:
+ FXSYS_assert(0);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr, CFX_WideString &wsValue, FX_BOOL bUseDefault, FX_BOOL bProto)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ if (eAttr == XFA_ATTRIBUTE_Value) {
+ CFX_WideString *pStr = (CFX_WideString*)GetUserData(pKey, bProto);
+ if (pStr) {
+ wsValue = *pStr;
+ return TRUE;
+ }
+ } else {
+ CFX_WideStringC wsValueC;
+ if (GetMapModuleString(pKey, wsValueC)) {
+ wsValue = wsValueC;
+ return TRUE;
+ }
+ }
+ if (!bUseDefault) {
+ return FALSE;
+ }
+ FX_LPVOID pValue = NULL;
+ if (XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr, XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
+ wsValue = (FX_LPCWSTR)pValue;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_Node::TryCData(XFA_ATTRIBUTE eAttr, CFX_WideStringC &wsValue, FX_BOOL bUseDefault, FX_BOOL bProto)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ if (eAttr == XFA_ATTRIBUTE_Value) {
+ CFX_WideString *pStr = (CFX_WideString*)GetUserData(pKey, bProto);
+ if (pStr) {
+ wsValue = *pStr;
+ return TRUE;
+ }
+ } else {
+ if (GetMapModuleString(pKey, wsValue)) {
+ return TRUE;
+ }
+ }
+ if (!bUseDefault) {
+ return FALSE;
+ }
+ FX_LPVOID pValue = NULL;
+ if (XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr, XFA_ATTRIBUTETYPE_Cdata, m_ePacket)) {
+ wsValue = (CFX_WideStringC)(FX_LPCWSTR)pValue;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_Node::SetObject(XFA_ATTRIBUTE eAttr, FX_LPVOID pData, XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo )
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ return SetUserData(pKey, pData, pCallbackInfo);
+}
+FX_BOOL CXFA_Node::TryObject(XFA_ATTRIBUTE eAttr, FX_LPVOID &pData)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ pData = GetUserData(pKey);
+ return pData != NULL;
+}
+FX_BOOL CXFA_Node::SetValue(XFA_ATTRIBUTE eAttr, XFA_ATTRIBUTETYPE eType, FX_LPVOID pValue, FX_BOOL bNotify)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ OnChanging(eAttr, pValue, bNotify);
+ SetMapModuleValue(pKey, pValue);
+ OnChanged(eAttr, pValue, bNotify);
+ if (IsNeedSavingXMLNode()) {
+ FXSYS_assert(m_pXMLNode->GetType() == FDE_XMLNODE_Element);
+ XFA_LPCATTRIBUTEINFO pInfo = XFA_GetAttributeByID(eAttr);
+ if (pInfo) {
+ switch (eType) {
+ case XFA_ATTRIBUTETYPE_Enum:
+ ((IFDE_XMLElement*)m_pXMLNode)->SetString(pInfo->pName, XFA_GetAttributeEnumByID((XFA_ATTRIBUTEENUM)(FX_UINTPTR)pValue)->pName);
+ break;
+ case XFA_ATTRIBUTETYPE_Boolean:
+ ((IFDE_XMLElement*)m_pXMLNode)->SetString(pInfo->pName, pValue ? FX_WSTRC(L"1") : FX_WSTRC(L"0"));
+ break;
+ case XFA_ATTRIBUTETYPE_Integer:
+ ((IFDE_XMLElement*)m_pXMLNode)->SetInteger(pInfo->pName, (FX_INT32)(FX_UINTPTR)pValue);
+ break;
+ default:
+ FXSYS_assert(0);
+ }
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_Node::GetValue(XFA_ATTRIBUTE eAttr, XFA_ATTRIBUTETYPE eType, FX_BOOL bUseDefault, FX_LPVOID &pValue)
+{
+ FX_LPVOID pKey = NULL;
+ if (!XFA_NodeData_PrepareKey(GetClassID(), eAttr, pKey)) {
+ return FALSE;
+ }
+ if(GetMapModuleValue(pKey, pValue)) {
+ return TRUE;
+ }
+ if (!bUseDefault) {
+ return FALSE;
+ }
+ return XFA_GetAttributeDefaultValue(pValue, GetClassID(), eAttr, eType, m_ePacket);
+}
+static void XFA_DefaultFreeData(FX_LPVOID pData)
+{
+}
+static XFA_MAPDATABLOCKCALLBACKINFO gs_XFADefaultFreeData = {XFA_DefaultFreeData, NULL};
+FX_BOOL CXFA_Node::SetUserData(FX_LPVOID pKey, FX_LPVOID pData, XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo )
+{
+ SetMapModuleBuffer(pKey, &pData, sizeof(FX_LPVOID), pCallbackInfo ? pCallbackInfo : &gs_XFADefaultFreeData);
+ return TRUE;
+}
+FX_BOOL CXFA_Node::TryUserData(FX_LPVOID pKey, FX_LPVOID &pData, FX_BOOL bProtoAlso)
+{
+ FX_INT32 iBytes = 0;
+ if (!GetMapModuleBuffer(pKey, pData, iBytes, bProtoAlso)) {
+ return FALSE;
+ }
+ return iBytes == sizeof(FX_LPVOID) && FXSYS_memcpy(&pData, pData, iBytes);
+}
+FX_BOOL CXFA_Node::SetScriptContent(const CFX_WideString& wsContent, const CFX_WideString& wsXMLValue, FX_BOOL bNotify, FX_BOOL bScriptModify, FX_BOOL bSyncData)
+{
+ CXFA_Node* pNode = NULL;
+ CXFA_Node* pBindNode = NULL;
+ switch (GetObjectType()) {
+ case XFA_OBJECTTYPE_ContainerNode: {
+ if (XFA_FieldIsMultiListBox(this)) {
+ CXFA_Node* pValue = GetProperty(0, XFA_ELEMENT_Value);
+ CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+ FXSYS_assert(pChildValue);
+ pChildValue->SetCData(XFA_ATTRIBUTE_ContentType, FX_WSTRC(L"text/xml"));
+ pChildValue->SetScriptContent(wsContent, wsContent, bNotify, bScriptModify, FALSE);
+ CXFA_Node *pBind = GetBindData();
+ if (bSyncData && pBind) {
+ CFX_WideStringArray wsSaveTextArray;
+ FX_INT32 iSize = 0;
+ if (!wsContent.IsEmpty()) {
+ FX_INT32 iStart = 0;
+ FX_INT32 iLength = wsContent.GetLength();
+ FX_INT32 iEnd = wsContent.Find(L'\n', iStart);
+ iEnd = (iEnd == -1) ? iLength : iEnd;
+ while (iEnd >= iStart) {
+ wsSaveTextArray.Add(wsContent.Mid(iStart, iEnd - iStart));
+ iStart = iEnd + 1;
+ if (iStart >= iLength) {
+ break;
+ }
+ iEnd = wsContent.Find(L'\n', iStart);
+ if (iEnd < 0) {
+ wsSaveTextArray.Add(wsContent.Mid(iStart, iLength - iStart));
+ }
+ }
+ iSize = wsSaveTextArray.GetSize();
+ }
+ if(iSize == 0) {
+ while (CXFA_Node* pChildNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ pBind->RemoveChild(pChildNode);
+ }
+ } else {
+ CXFA_NodeArray valueNodes;
+ FX_INT32 iDatas = pBind->GetNodeList(valueNodes, XFA_NODEFILTER_Children, XFA_ELEMENT_DataValue);
+ if (iDatas < iSize) {
+ FX_INT32 iAddNodes = iSize - iDatas;
+ CXFA_Node *pValueNodes = NULL;
+ while (iAddNodes-- > 0) {
+ pValueNodes = pBind->CreateSamePacketNode(XFA_ELEMENT_DataValue);
+ pValueNodes->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"value"));
+ pValueNodes->CreateXMLMappingNode();
+ pBind->InsertChild(pValueNodes);
+ }
+ pValueNodes = NULL;
+ } else if (iDatas > iSize) {
+ FX_INT32 iDelNodes = iDatas - iSize;
+ while (iDelNodes-- > 0) {
+ pBind->RemoveChild(pBind->GetNodeItem(XFA_NODEITEM_FirstChild));
+ }
+ }
+ FX_INT32 i = 0;
+ for (CXFA_Node *pValueNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild); pValueNode; pValueNode = pValueNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ pValueNode->SetAttributeValue(wsSaveTextArray[i], wsSaveTextArray[i], FALSE);
+ i++;
+ }
+ }
+ CXFA_NodeArray nodeArray;
+ pBind->GetBindItems(nodeArray);
+ for (FX_INT32 i = 0; i < nodeArray.GetSize(); i++) {
+ CXFA_Node* pNode = nodeArray[i];
+ if (pNode == this) {
+ continue;
+ }
+ pNode->SetScriptContent(wsContent, wsContent, bNotify, bScriptModify, FALSE);
+ }
+ }
+ break;
+ } else if (GetClassID() == XFA_ELEMENT_ExclGroup) {
+ pNode = this;
+ } else {
+ CXFA_Node* pValue = GetProperty(0, XFA_ELEMENT_Value);
+ CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+ FXSYS_assert(pChildValue);
+ pChildValue->SetScriptContent(wsContent, wsContent, bNotify, bScriptModify, FALSE);
+ }
+ pBindNode = GetBindData();
+ if (pBindNode && bSyncData) {
+ pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify, bScriptModify, FALSE);
+ CXFA_NodeArray nodeArray;
+ pBindNode->GetBindItems(nodeArray);
+ for (FX_INT32 i = 0; i < nodeArray.GetSize(); i++) {
+ CXFA_Node* pNode = nodeArray[i];
+ if (pNode == this) {
+ continue;
+ }
+ pNode->SetScriptContent(wsContent, wsContent, bNotify, TRUE, FALSE);
+ }
+ }
+ pBindNode = NULL;
+ break;
+ }
+ case XFA_OBJECTTYPE_ContentNode: {
+ CFX_WideString wsContentType;
+ if (GetClassID() == XFA_ELEMENT_ExData) {
+ GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+ wsContentType = FX_WSTRC(L"");
+ SetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType);
+ }
+ }
+ CXFA_Node *pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pContentRawDataNode) {
+ pContentRawDataNode = CreateSamePacketNode((wsContentType.Equal(FX_WSTRC(L"text/xml"))) ? XFA_ELEMENT_Sharpxml : XFA_ELEMENT_Sharptext);
+ InsertChild(pContentRawDataNode);
+ }
+ return pContentRawDataNode->SetScriptContent(wsContent, wsXMLValue, bNotify, bScriptModify, bSyncData);
+ }
+ break;
+ case XFA_OBJECTTYPE_NodeC:
+ case XFA_OBJECTTYPE_TextNode:
+ pNode = this;
+ break;
+ case XFA_OBJECTTYPE_NodeV:
+ pNode = this;
+ if (bSyncData && GetPacketID() == XFA_XDPPACKET_Form) {
+ CXFA_Node* pParent = GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParent) {
+ pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ if (pParent && pParent->GetClassID() == XFA_ELEMENT_Value) {
+ pParent = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParent && pParent->IsContainerNode()) {
+ pBindNode = pParent->GetBindData();
+ if (pBindNode) {
+ pBindNode->SetScriptContent(wsContent, wsXMLValue, bNotify, bScriptModify, FALSE);
+ }
+ }
+ }
+ }
+ break;
+ default:
+ if (GetClassID() == XFA_ELEMENT_DataValue) {
+ pNode = this;
+ pBindNode = this;
+ }
+ break;
+ }
+ if (pNode) {
+ SetAttributeValue(wsContent, wsXMLValue, bNotify, bScriptModify);
+ if (pBindNode && bSyncData) {
+ CXFA_NodeArray nodeArray;
+ pBindNode->GetBindItems(nodeArray);
+ for (FX_INT32 i = 0; i < nodeArray.GetSize(); i++) {
+ CXFA_Node* pNode = nodeArray[i];
+ pNode->SetScriptContent(wsContent, wsContent, bNotify, bScriptModify, FALSE);
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_Node::SetContent(const CFX_WideString& wsContent, const CFX_WideString& wsXMLValue, FX_BOOL bNotify, FX_BOOL bScriptModify, FX_BOOL bSyncData)
+{
+ return SetScriptContent(wsContent, wsXMLValue, bNotify, bScriptModify, bSyncData);
+}
+CFX_WideString CXFA_Node::GetScriptContent(FX_BOOL bScriptModify)
+{
+ CFX_WideString wsContent;
+ return TryContent(wsContent, bScriptModify) ? wsContent : CFX_WideString();
+}
+CFX_WideString CXFA_Node::GetContent()
+{
+ return GetScriptContent();
+}
+FX_BOOL CXFA_Node::TryContent(CFX_WideString& wsContent, FX_BOOL bScriptModify, FX_BOOL bProto)
+{
+ CXFA_Node* pNode = NULL;
+ switch (GetObjectType()) {
+ case XFA_OBJECTTYPE_ContainerNode:
+ if (GetClassID() == XFA_ELEMENT_ExclGroup) {
+ pNode = this;
+ } else {
+ CXFA_Node* pValue = GetChild(0, XFA_ELEMENT_Value);
+ if (!pValue) {
+ return FALSE;
+ }
+ CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pChildValue && XFA_FieldIsMultiListBox(this)) {
+ pChildValue->SetAttribute(XFA_ATTRIBUTE_ContentType, FX_WSTRC(L"text/xml"));
+ }
+ return pChildValue ? pChildValue->TryContent(wsContent, bScriptModify, bProto) : FALSE;
+ }
+ break;
+ case XFA_OBJECTTYPE_ContentNode: {
+ CXFA_Node *pContentRawDataNode = GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pContentRawDataNode) {
+ XFA_ELEMENT element = XFA_ELEMENT_Sharptext;
+ if (GetClassID() == XFA_ELEMENT_ExData) {
+ CFX_WideString wsContentType;
+ GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ if (wsContentType.Equal(FX_WSTRC(L"text/html"))) {
+ element = XFA_ELEMENT_SharpxHTML;
+ } else if (wsContentType.Equal(FX_WSTRC(L"text/xml"))) {
+ element = XFA_ELEMENT_Sharpxml;
+ }
+ }
+ pContentRawDataNode = CreateSamePacketNode(element);
+ InsertChild(pContentRawDataNode);
+ }
+ return pContentRawDataNode->TryContent(wsContent, bScriptModify, bProto);
+ }
+ case XFA_OBJECTTYPE_NodeC:
+ case XFA_OBJECTTYPE_NodeV:
+ case XFA_OBJECTTYPE_TextNode:
+ pNode = this;
+ default:
+ if (GetClassID() == XFA_ELEMENT_DataValue) {
+ pNode = this;
+ }
+ break;
+ }
+ if (pNode) {
+ if (bScriptModify) {
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (pScriptContext) {
+ m_pDocument->GetScriptContext()->AddNodesOfRunScript(this);
+ }
+ }
+ return TryCData(XFA_ATTRIBUTE_Value, wsContent, FALSE, bProto);
+ }
+ return FALSE;
+}
+CXFA_Node* CXFA_Node::GetModelNode()
+{
+ switch(GetPacketID()) {
+ case XFA_XDPPACKET_XDP:
+ return m_pDocument->GetRoot();
+ case XFA_XDPPACKET_Config:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Config);
+ case XFA_XDPPACKET_Template:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Template);
+ case XFA_XDPPACKET_Form:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Form);
+ case XFA_XDPPACKET_Datasets:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Datasets);
+ case XFA_XDPPACKET_LocaleSet:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_LocaleSet);
+ case XFA_XDPPACKET_ConnectionSet:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_ConnectionSet);
+ case XFA_XDPPACKET_SourceSet:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_SourceSet);
+ case XFA_XDPPACKET_Xdc:
+ return (CXFA_Node*)m_pDocument->GetXFANode(XFA_HASHCODE_Xdc);
+ default:
+ return this;
+ }
+}
+FX_BOOL CXFA_Node::TryNamespace(CFX_WideString& wsNamespace)
+{
+ wsNamespace.Empty();
+ if(this->GetObjectType() == XFA_OBJECTTYPE_ModelNode || this->GetClassID() == XFA_ELEMENT_Packet) {
+ IFDE_XMLNode* pXMLNode = this->GetXMLMappingNode();
+ if(!pXMLNode || pXMLNode->GetType() != FDE_XMLNODE_Element) {
+ return FALSE;
+ }
+ ((IFDE_XMLElement*)pXMLNode)->GetNamespaceURI(wsNamespace);
+ return TRUE;
+ } else if(this->GetPacketID() == XFA_XDPPACKET_Datasets) {
+ IFDE_XMLNode* pXMLNode = this->GetXMLMappingNode();
+ if(!pXMLNode) {
+ return FALSE;
+ }
+ if(pXMLNode->GetType() != FDE_XMLNODE_Element) {
+ return TRUE;
+ }
+ if(this->GetClassID() == XFA_ELEMENT_DataValue && this->GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData) {
+ return XFA_FDEExtension_ResolveNamespaceQualifier((IFDE_XMLElement*)pXMLNode, this->GetCData(XFA_ATTRIBUTE_QualifiedName), wsNamespace);
+ }
+ ((IFDE_XMLElement*)pXMLNode)->GetNamespaceURI(wsNamespace);
+ return TRUE;
+ } else {
+ CXFA_Node *pModelNode = GetModelNode();
+ return pModelNode->TryNamespace(wsNamespace);
+ }
+}
+CXFA_Node* CXFA_Node::GetProperty(FX_INT32 index, XFA_ELEMENT eProperty, FX_BOOL bCreateProperty )
+{
+ XFA_ELEMENT eElement = GetClassID();
+ FX_DWORD dwPacket = GetPacketID();
+ XFA_LPCPROPERTY pProperty = XFA_GetPropertyOfElement(eElement, eProperty, dwPacket);
+ if (pProperty == NULL || index >= pProperty->uOccur) {
+ return NULL;
+ }
+ CXFA_Node *pNode = m_pChild;
+ FX_INT32 iCount = 0;
+ for(; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetClassID() == eProperty) {
+ iCount ++;
+ if (iCount > index) {
+ return pNode;
+ }
+ }
+ }
+ if (!bCreateProperty) {
+ return NULL;
+ }
+ if (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf) {
+ pNode = m_pChild;
+ for(; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_LPCPROPERTY pExistProterty = XFA_GetPropertyOfElement(eElement, pNode->GetClassID(), dwPacket);
+ if (pExistProterty && (pExistProterty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
+ return NULL;
+ }
+ }
+ }
+ IXFA_ObjFactory *pFactory = m_pDocument->GetParser()->GetFactory();
+ XFA_LPCPACKETINFO pPacket = XFA_GetPacketByID(dwPacket);
+ CXFA_Node *pNewNode;
+ for (; iCount <= index ; iCount ++) {
+ pNewNode = pFactory->CreateNode(pPacket, eProperty);
+ if(!pNewNode) {
+ return NULL;
+ }
+ this->InsertChild(pNewNode, NULL);
+ pNewNode->SetFlag(XFA_NODEFLAG_Initialized);
+ }
+ return pNewNode;
+}
+FX_INT32 CXFA_Node::CountChildren(XFA_ELEMENT eElement, FX_BOOL bOnlyChild)
+{
+ CXFA_Node *pNode = m_pChild;
+ FX_INT32 iCount = 0;
+ for(; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetClassID() == eElement || eElement == XFA_ELEMENT_UNKNOWN) {
+ if(bOnlyChild) {
+ XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(GetClassID(), pNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+ if(pPropert) {
+ continue;
+ }
+ }
+ iCount ++;
+ }
+ }
+ return iCount;
+}
+CXFA_Node* CXFA_Node::GetChild(FX_INT32 index, XFA_ELEMENT eElement, FX_BOOL bOnlyChild)
+{
+ FXSYS_assert(index > -1);
+ CXFA_Node *pNode = m_pChild;
+ FX_INT32 iCount = 0;
+ for(; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetClassID() == eElement || eElement == XFA_ELEMENT_UNKNOWN) {
+ if(bOnlyChild) {
+ XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(GetClassID(), pNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+ if(pPropert) {
+ continue;
+ }
+ }
+ iCount ++;
+ if (iCount > index) {
+ return pNode;
+ }
+ }
+ }
+ return NULL;
+}
+FX_INT32 CXFA_Node::InsertChild(FX_INT32 index, CXFA_Node *pNode)
+{
+ ASSERT(pNode != NULL && pNode->m_pNext == NULL);
+ pNode->m_pParent = this;
+ FX_BOOL bWasPurgeNode = m_pDocument->RemovePurgeNode(pNode);
+ FXSYS_assert(bWasPurgeNode == TRUE);
+ if (m_pChild == NULL || index == 0) {
+ if (index > 0) {
+ return -1;
+ }
+ pNode->m_pNext = m_pChild;
+ m_pChild = pNode;
+ index = 0;
+ } else if (index < 0) {
+ m_pLastChild->m_pNext = pNode;
+ } else {
+ CXFA_Node *pPrev = m_pChild;
+ FX_INT32 iCount = 0;
+ while (++iCount != index && pPrev->m_pNext) {
+ pPrev = pPrev->m_pNext;
+ }
+ if (index > 0 && index != iCount) {
+ return -1;
+ }
+ pNode->m_pNext = pPrev->m_pNext;
+ pPrev->m_pNext = pNode;
+ index = iCount;
+ }
+ if (pNode->m_pNext == NULL) {
+ m_pLastChild = pNode;
+ }
+ ASSERT(m_pLastChild != NULL && m_pLastChild->m_pNext == NULL);
+ pNode->SetFlag(XFA_NODEFLAG_HasRemoved, FALSE);
+ IXFA_Notify *pNotify = m_pDocument->GetParser()->GetNotify();
+ if (pNotify) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ChildAdded, pNode);
+ }
+ if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
+ FXSYS_assert(pNode->m_pXMLNode->GetNodeItem(IFDE_XMLNode::Parent) == NULL);
+ m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, index);
+ pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, FALSE, FALSE);
+ }
+ return index;
+}
+FX_BOOL CXFA_Node::InsertChild(CXFA_Node *pNode, CXFA_Node *pBeforeNode)
+{
+ if (!pNode || pNode->m_pParent != NULL || (pBeforeNode && pBeforeNode->m_pParent != this)) {
+ FXSYS_assert(FALSE);
+ return FALSE;
+ }
+ FX_BOOL bWasPurgeNode = m_pDocument->RemovePurgeNode(pNode);
+ FXSYS_assert(bWasPurgeNode == TRUE);
+ FX_INT32 nIndex = -1;
+ pNode->m_pParent = this;
+ if (m_pChild == NULL || pBeforeNode == m_pChild) {
+ pNode->m_pNext = m_pChild;
+ m_pChild = pNode;
+ nIndex = 0;
+ } else if (!pBeforeNode) {
+ pNode->m_pNext = m_pLastChild->m_pNext;
+ m_pLastChild->m_pNext = pNode;
+ } else {
+ nIndex = 1;
+ CXFA_Node *pPrev = m_pChild;
+ while (pPrev->m_pNext != pBeforeNode) {
+ pPrev = pPrev->m_pNext;
+ nIndex++;
+ }
+ pNode->m_pNext = pPrev->m_pNext;
+ pPrev->m_pNext = pNode;
+ }
+ if (pNode->m_pNext == NULL) {
+ m_pLastChild = pNode;
+ }
+ ASSERT(m_pLastChild != NULL && m_pLastChild->m_pNext == NULL);
+ pNode->SetFlag(XFA_NODEFLAG_HasRemoved, FALSE);
+ IXFA_Notify *pNotify = m_pDocument->GetParser()->GetNotify();
+ if (pNotify) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ChildAdded, pNode);
+ }
+ if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
+ FXSYS_assert(pNode->m_pXMLNode->GetNodeItem(IFDE_XMLNode::Parent) == NULL);
+ m_pXMLNode->InsertChildNode(pNode->m_pXMLNode, nIndex);
+ pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, FALSE, FALSE);
+ }
+ return TRUE;
+}
+CXFA_Node* CXFA_Node::Deprecated_GetPrevSibling()
+{
+ if(!m_pParent) {
+ return NULL;
+ }
+ for (CXFA_Node *pSibling = m_pParent->m_pChild; pSibling; pSibling = pSibling->m_pNext) {
+ if(pSibling->m_pNext == this) {
+ return pSibling;
+ }
+ }
+ return NULL;
+}
+FX_BOOL CXFA_Node::RemoveChild(CXFA_Node *pNode, FX_BOOL bNotify)
+{
+ if (pNode == NULL || pNode->m_pParent != this) {
+ FXSYS_assert(FALSE);
+ return FALSE;
+ }
+ if (m_pChild == pNode) {
+ m_pChild = pNode->m_pNext;
+ if (m_pLastChild == pNode) {
+ m_pLastChild = pNode->m_pNext;
+ }
+ pNode->m_pNext = NULL;
+ pNode->m_pParent = NULL;
+ } else {
+ CXFA_Node *pPrev = pNode->Deprecated_GetPrevSibling();
+ pPrev->m_pNext = pNode->m_pNext;
+ if (m_pLastChild == pNode) {
+ m_pLastChild = pNode->m_pNext ? pNode->m_pNext : pPrev;
+ }
+ pNode->m_pNext = NULL;
+ pNode->m_pParent = NULL;
+ }
+ ASSERT(m_pLastChild == NULL || m_pLastChild->m_pNext == NULL);
+ OnRemoved(this, pNode, bNotify);
+ pNode->SetFlag(XFA_NODEFLAG_HasRemoved);
+ m_pDocument->AddPurgeNode(pNode);
+ if (IsNeedSavingXMLNode() && pNode->m_pXMLNode) {
+ if (pNode->IsAttributeInXML()) {
+ FXSYS_assert(pNode->m_pXMLNode == m_pXMLNode && m_pXMLNode->GetType() == FDE_XMLNODE_Element);
+ if (pNode->m_pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)(pNode->m_pXMLNode);
+ CFX_WideStringC wsAttributeName = pNode->GetCData(XFA_ATTRIBUTE_QualifiedName);
+ pXMLElement->RemoveAttribute(wsAttributeName.GetPtr());
+ }
+ CFX_WideString wsName;
+ pNode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+ IFDE_XMLElement* pNewXMLElement = IFDE_XMLElement::Create(wsName);
+ CFX_WideStringC wsValue = this->GetCData(XFA_ATTRIBUTE_Value);
+ if (!wsValue.IsEmpty()) {
+ pNewXMLElement->SetTextData(wsValue);
+ }
+ pNode->m_pXMLNode = pNewXMLElement;
+ pNode->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_Unknown);
+ } else {
+ m_pXMLNode->RemoveChildNode(pNode->m_pXMLNode);
+ }
+ pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+ }
+ return TRUE;
+}
+CXFA_Node* CXFA_Node::GetFirstChildByName(FX_WSTR wsName) const
+{
+ return GetFirstChildByName(wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength()));
+}
+CXFA_Node* CXFA_Node::GetFirstChildByName(FX_DWORD dwNameHash) const
+{
+ for(CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pNode->GetNameHash() == dwNameHash) {
+ return pNode;
+ }
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_Node::GetFirstChildByClass(XFA_ELEMENT eElement) const
+{
+ for(CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_FirstChild); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pNode->GetClassID() == eElement) {
+ return pNode;
+ }
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_Node::GetNextSameNameSibling(FX_DWORD dwNameHash) const
+{
+ for(CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pNode->GetNameHash() == dwNameHash) {
+ return pNode;
+ }
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_Node::GetNextSameNameSibling(FX_WSTR wsNodeName) const
+{
+ return GetNextSameNameSibling(wsNodeName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsNodeName.GetPtr(), wsNodeName.GetLength()));
+}
+CXFA_Node* CXFA_Node::GetNextSameClassSibling(XFA_ELEMENT eElement) const
+{
+ for(CXFA_Node* pNode = GetNodeItem(XFA_NODEITEM_NextSibling); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if(pNode->GetClassID() == eElement) {
+ return pNode;
+ }
+ }
+ return NULL;
+}
+FX_INT32 CXFA_Node::GetNodeSameNameIndex() const
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return -1;
+ }
+ return pScriptContext->GetIndexByName((CXFA_Node*)this);
+}
+FX_INT32 CXFA_Node::GetNodeSameClassIndex() const
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return -1;
+ }
+ return pScriptContext->GetIndexByClassName((CXFA_Node*)this);
+}
+void CXFA_Node::GetSOMExpression(CFX_WideString& wsSOMExpression)
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ pScriptContext->GetSomExpression(this, wsSOMExpression);
+}
+CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform()
+{
+ CXFA_Node* pInstanceMgr = NULL;
+ if (m_ePacket == XFA_XDPPACKET_Form) {
+ CXFA_Node* pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pParentNode || pParentNode->GetClassID() == XFA_ELEMENT_Area) {
+ return pInstanceMgr;
+ }
+ for (CXFA_Node *pNode = GetNodeItem(XFA_NODEITEM_PrevSibling); pNode != NULL; pNode = pNode->GetNodeItem(XFA_NODEITEM_PrevSibling)) {
+ XFA_ELEMENT eType = pNode->GetClassID();
+ if ((eType == XFA_ELEMENT_Subform || eType == XFA_ELEMENT_SubformSet) && pNode->m_dwNameHash != m_dwNameHash) {
+ break;
+ }
+ if (eType == XFA_ELEMENT_InstanceManager) {
+ CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
+ CFX_WideStringC wsInstName = pNode->GetCData(XFA_ATTRIBUTE_Name);
+ if (wsInstName.GetLength() > 0 && wsInstName.GetAt(0) == '_' && wsInstName.Mid(1) == wsName) {
+ pInstanceMgr = pNode;
+ }
+ break;
+ }
+ }
+ }
+ return pInstanceMgr;
+}
+CXFA_Node* CXFA_Node::GetOccurNode()
+{
+ return GetFirstChildByClass(XFA_ELEMENT_Occur);
+}
+FX_BOOL CXFA_Node::HasFlag(FX_DWORD dwFlag) const
+{
+ if (m_uFlags & dwFlag) {
+ return TRUE;
+ }
+ switch (dwFlag) {
+ case XFA_NODEFLAG_HasRemoved:
+ return m_pParent && m_pParent->HasFlag(dwFlag);
+ default:
+ break;
+ }
+ return FALSE;
+}
+void CXFA_Node::SetFlag(FX_DWORD dwFlag, FX_BOOL bOn , FX_BOOL bNotify )
+{
+ if (bOn) {
+ switch (dwFlag) {
+ case XFA_NODEFLAG_Initialized:
+ if (bNotify && !HasFlag(XFA_NODEFLAG_Initialized)) {
+ IXFA_Notify *pNotify = m_pDocument->GetParser()->GetNotify();
+ if (pNotify) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_Ready);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ m_uFlags |= dwFlag;
+ } else {
+ m_uFlags &= ~dwFlag;
+ }
+}
+FX_BOOL CXFA_Node::IsAttributeInXML()
+{
+ return GetEnum(XFA_ATTRIBUTE_Contains) == XFA_ATTRIBUTEENUM_MetaData;
+}
+void CXFA_Node::OnRemoved(CXFA_Node *pParent, CXFA_Node *pRemoved, FX_BOOL bNotify)
+{
+ if (bNotify && (pParent != NULL)) {
+ IXFA_Notify *pNotify = m_pDocument->GetParser()->GetNotify();
+ if (pNotify) {
+ pNotify->OnNodeEvent(pParent, XFA_NODEEVENT_ChildRemoved, pRemoved);
+ }
+ }
+}
+void CXFA_Node::OnChanging(XFA_ATTRIBUTE eAttr, FX_LPVOID pNewValue, FX_BOOL bNotify)
+{
+ if (bNotify && HasFlag(XFA_NODEFLAG_Initialized)) {
+ IXFA_Notify *pNotify = m_pDocument->GetParser()->GetNotify();
+ if (pNotify) {
+ pNotify->OnNodeEvent(this, XFA_NODEEVENT_ValueChanging, (FX_LPVOID)(FX_UINTPTR)eAttr, pNewValue);
+ }
+ }
+}
+void CXFA_Node::OnChanged(XFA_ATTRIBUTE eAttr, FX_LPVOID pNewValue, FX_BOOL bNotify, FX_BOOL bScriptModify)
+{
+ if (bNotify && HasFlag(XFA_NODEFLAG_Initialized)) {
+ Script_Attribute_SendAttributeChangeMessage((FX_LPVOID)(FX_UINTPTR)eAttr, pNewValue, bScriptModify);
+ }
+}
+FX_INT32 CXFA_Node::execSingleEventByName(FX_WSTR wsEventName, XFA_ELEMENT eElementType)
+{
+ FX_INT32 iRet = XFA_EVENTERROR_NotExist;
+ const XFA_ExecEventParaInfo* eventParaInfo = GetEventParaInfoByName(wsEventName);
+ if (eventParaInfo) {
+ FX_UINT32 validFlags = eventParaInfo->m_validFlags;
+ IXFA_Notify * pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return iRet;
+ }
+ if (validFlags == 1) {
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType);
+ } else if (validFlags == 2) {
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType, FALSE, FALSE);
+ } else if (validFlags == 3) {
+ if (eElementType == XFA_ELEMENT_Subform) {
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType, FALSE, FALSE);
+ }
+ } else if (validFlags == 4) {
+ if (eElementType == XFA_ELEMENT_ExclGroup || eElementType == XFA_ELEMENT_Field) {
+ CXFA_Node *pParentNode = GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParentNode && pParentNode->GetClassID() == XFA_ELEMENT_ExclGroup) {
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType, FALSE, FALSE);
+ }
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType, FALSE, FALSE);
+ }
+ } else if (validFlags == 5) {
+ if (eElementType == XFA_ELEMENT_Field) {
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType, FALSE, FALSE);
+ }
+ } else if (validFlags == 6) {
+ CXFA_WidgetData * pWidgetData = GetWidgetData();
+ if (pWidgetData) {
+ CXFA_Node * pUINode = pWidgetData->GetUIChild();
+ if (pUINode->m_eNodeClass == XFA_ELEMENT_Signature) {
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType, FALSE, FALSE);
+ }
+ }
+ } else if (validFlags == 7) {
+ CXFA_WidgetData * pWidgetData = GetWidgetData();
+ if (pWidgetData) {
+ CXFA_Node * pUINode = pWidgetData->GetUIChild();
+ if ((pUINode->m_eNodeClass == XFA_ELEMENT_ChoiceList) && (!pWidgetData->IsListBox())) {
+ iRet = pNotify->ExecEventByDeepFirst(this, eventParaInfo->m_eventType, FALSE, FALSE);
+ }
+ }
+ }
+ }
+ return iRet;
+}
+void CXFA_Node::UpdateNameHash()
+{
+ XFA_LPCNOTSUREATTRIBUTE pNotsure = XFA_GetNotsureAttribute(GetClassID(), XFA_ATTRIBUTE_Name);
+ if(!pNotsure || pNotsure->eType == XFA_ATTRIBUTETYPE_Cdata) {
+ CFX_WideStringC wsName = GetCData(XFA_ATTRIBUTE_Name);
+ m_dwNameHash = wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+ } else if (pNotsure->eType == XFA_ATTRIBUTETYPE_Enum) {
+ CFX_WideStringC wsName = XFA_GetAttributeEnumByID(GetEnum(XFA_ATTRIBUTE_Name))->pName;
+ m_dwNameHash = wsName.IsEmpty() ? 0 : FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+ }
+}
+IFDE_XMLNode* CXFA_Node::CreateXMLMappingNode()
+{
+ if (!m_pXMLNode) {
+ CFX_WideStringC wsTag = GetCData(XFA_ATTRIBUTE_Name);
+ m_pXMLNode = IFDE_XMLElement::Create(wsTag);
+ SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+ }
+ return m_pXMLNode;
+}
+FX_BOOL CXFA_Node::IsNeedSavingXMLNode()
+{
+ return m_pXMLNode && (GetPacketID() == XFA_XDPPACKET_Datasets || GetClassID() == XFA_ELEMENT_Xfa );
+}
+XFA_LPMAPMODULEDATA CXFA_Node::GetMapModuleData(FX_BOOL bCreateNew)
+{
+ if (!m_pMapModuleData && bCreateNew) {
+ m_pMapModuleData = FX_NEW XFA_MAPMODULEDATA;
+ }
+ return m_pMapModuleData;
+}
+void CXFA_Node::SetMapModuleValue(FX_LPVOID pKey, FX_LPVOID pValue)
+{
+ XFA_LPMAPMODULEDATA pMoudle = this->GetMapModuleData(TRUE);
+ if (!pMoudle) {
+ return;
+ }
+ pMoudle->m_ValueMap.SetAt(pKey, pValue);
+}
+FX_BOOL CXFA_Node::GetMapModuleValue(FX_LPVOID pKey, FX_LPVOID &pValue)
+{
+ CXFA_Node* pNode = this;
+ while (pNode) {
+ XFA_LPMAPMODULEDATA pMoudle = pNode->GetMapModuleData(FALSE);
+ if (pMoudle && pMoudle->m_ValueMap.Lookup(pKey, pValue)) {
+ return TRUE;
+ }
+ pNode = pNode->GetPacketID() != XFA_XDPPACKET_Datasets ? pNode->GetTemplateNode() : NULL;
+ }
+ return FALSE;
+}
+void CXFA_Node::SetMapModuleString(FX_LPVOID pKey, FX_WSTR wsValue)
+{
+ SetMapModuleBuffer(pKey, (FX_LPVOID)wsValue.GetPtr(), wsValue.GetLength() * sizeof(FX_WCHAR));
+}
+FX_BOOL CXFA_Node::GetMapModuleString(FX_LPVOID pKey, CFX_WideStringC &wsValue)
+{
+ FX_LPVOID pValue;
+ FX_INT32 iBytes;
+ if (!GetMapModuleBuffer(pKey, pValue, iBytes)) {
+ return FALSE;
+ }
+ wsValue = CFX_WideStringC((FX_LPCWSTR)pValue, iBytes / sizeof(FX_WCHAR));
+ return TRUE;
+}
+void CXFA_Node::SetMapModuleBuffer(FX_LPVOID pKey, FX_LPVOID pValue, FX_INT32 iBytes, XFA_MAPDATABLOCKCALLBACKINFO* pCallbackInfo )
+{
+ XFA_LPMAPMODULEDATA pMoudle = this->GetMapModuleData(TRUE);
+ if (!pMoudle) {
+ return;
+ }
+ XFA_LPMAPDATABLOCK &pBuffer = pMoudle->m_BufferMap[pKey];
+ if (pBuffer == NULL) {
+ pBuffer = (XFA_LPMAPDATABLOCK)FX_Alloc(FX_BYTE, sizeof(XFA_MAPDATABLOCK) + iBytes);
+ } else if (pBuffer->iBytes != iBytes) {
+ if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+ pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+ }
+ pBuffer = (XFA_LPMAPDATABLOCK)FX_Realloc(FX_BYTE, pBuffer, sizeof(XFA_MAPDATABLOCK) + iBytes);
+ } else if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+ pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+ }
+ if (pBuffer == NULL) {
+ return;
+ }
+ pBuffer->pCallbackInfo = pCallbackInfo;
+ pBuffer->iBytes = iBytes;
+ FXSYS_memcpy(pBuffer->GetData(), pValue, iBytes);
+}
+FX_BOOL CXFA_Node::GetMapModuleBuffer(FX_LPVOID pKey, FX_LPVOID &pValue, FX_INT32 &iBytes, FX_BOOL bProtoAlso)
+{
+ XFA_LPMAPDATABLOCK pBuffer = NULL;
+ CXFA_Node* pNode = this;
+ while (pNode) {
+ XFA_LPMAPMODULEDATA pMoudle = pNode->GetMapModuleData(FALSE);
+ if (pMoudle && pMoudle->m_BufferMap.Lookup(pKey, pBuffer)) {
+ break;
+ }
+ pNode = (bProtoAlso && pNode->GetPacketID() != XFA_XDPPACKET_Datasets) ? pNode->GetTemplateNode() : NULL;
+ }
+ if (pBuffer == NULL) {
+ return FALSE;
+ }
+ pValue = pBuffer->GetData();
+ iBytes = pBuffer->iBytes;
+ return TRUE;
+}
+FX_BOOL CXFA_Node::HasMapModuleKey(FX_LPVOID pKey, FX_BOOL bProtoAlso)
+{
+ CXFA_Node* pNode = this;
+ while (pNode) {
+ FX_LPVOID pVal;
+ XFA_LPMAPMODULEDATA pMoudle = pNode->GetMapModuleData(FALSE);
+ if (pMoudle && (pMoudle->m_ValueMap.Lookup(pKey, pVal) || pMoudle->m_BufferMap.Lookup(pKey, (XFA_LPMAPDATABLOCK&)pVal))) {
+ return TRUE;
+ }
+ pNode = (bProtoAlso && pNode->GetPacketID() != XFA_XDPPACKET_Datasets) ? pNode->GetTemplateNode() : NULL;
+ }
+ return FALSE;
+}
+void CXFA_Node::RemoveMapModuleKey(FX_LPVOID pKey )
+{
+ XFA_LPMAPMODULEDATA pMoudle = this->GetMapModuleData(FALSE);
+ if (!pMoudle) {
+ return;
+ }
+ if (pKey) {
+ XFA_LPMAPDATABLOCK pBuffer = NULL;
+ pMoudle->m_BufferMap.Lookup(pKey, pBuffer);
+ if (pBuffer) {
+ if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+ pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+ }
+ FX_Free(pBuffer);
+ }
+ pMoudle->m_BufferMap.RemoveKey(pKey);
+ pMoudle->m_ValueMap.RemoveKey(pKey);
+ } else {
+ XFA_LPMAPDATABLOCK pBuffer;
+ FX_POSITION posBuffer = pMoudle->m_BufferMap.GetStartPosition();
+ while (posBuffer) {
+ pMoudle->m_BufferMap.GetNextAssoc(posBuffer, pKey, pBuffer);
+ if (pBuffer) {
+ if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+ pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+ }
+ FX_Free(pBuffer);
+ }
+ }
+ pMoudle->m_BufferMap.RemoveAll();
+ pMoudle->m_ValueMap.RemoveAll();
+ if (pMoudle) {
+ delete pMoudle;
+ pMoudle = NULL;
+ }
+ }
+}
+void CXFA_Node::MergeAllData(FX_LPVOID pDstModule, FX_BOOL bUseSrcAttr )
+{
+ XFA_LPMAPMODULEDATA pDstModuleData = ((CXFA_Node*)pDstModule)->GetMapModuleData(TRUE);
+ if (!pDstModuleData) {
+ return;
+ }
+ XFA_LPMAPMODULEDATA pSrcModuleData = this->GetMapModuleData(FALSE);
+ if (!pSrcModuleData) {
+ return;
+ }
+ FX_POSITION psValue = pSrcModuleData->m_ValueMap.GetStartPosition();
+ while (psValue) {
+ FX_LPVOID pKey;
+ FX_LPVOID pValue;
+ pSrcModuleData->m_ValueMap.GetNextAssoc(psValue, pKey, pValue);
+ if (bUseSrcAttr || !pDstModuleData->m_ValueMap.GetValueAt(pKey)) {
+ pDstModuleData->m_ValueMap.SetAt(pKey, pValue);
+ }
+ }
+ FX_POSITION psBuffer = pSrcModuleData->m_BufferMap.GetStartPosition();
+ while (psBuffer) {
+ FX_LPVOID pKey;
+ XFA_LPMAPDATABLOCK pSrcBuffer;
+ pSrcModuleData->m_BufferMap.GetNextAssoc(psBuffer, pKey, pSrcBuffer);
+ XFA_LPMAPDATABLOCK &pBuffer = pDstModuleData->m_BufferMap[pKey];
+ if (pBuffer && !bUseSrcAttr) {
+ continue;
+ }
+ if (pSrcBuffer->pCallbackInfo && pSrcBuffer->pCallbackInfo->pFree && !pSrcBuffer->pCallbackInfo->pCopy) {
+ if (pBuffer) {
+ pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+ pDstModuleData->m_BufferMap.RemoveKey(pKey);
+ }
+ continue;
+ }
+ if (pBuffer == NULL) {
+ pBuffer = (XFA_LPMAPDATABLOCK)FX_Alloc(FX_BYTE, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
+ } else if (pBuffer->iBytes != pSrcBuffer->iBytes) {
+ if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+ pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+ }
+ pBuffer = (XFA_LPMAPDATABLOCK)FX_Realloc(FX_BYTE, pBuffer, sizeof(XFA_MAPDATABLOCK) + pSrcBuffer->iBytes);
+ } else if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pFree) {
+ pBuffer->pCallbackInfo->pFree(*(void**)pBuffer->GetData());
+ }
+ if (pBuffer == NULL) {
+ continue;
+ }
+ pBuffer->pCallbackInfo = pSrcBuffer->pCallbackInfo;
+ pBuffer->iBytes = pSrcBuffer->iBytes;
+ FXSYS_memcpy(pBuffer->GetData(), pSrcBuffer->GetData(), pSrcBuffer->iBytes);
+ if (pBuffer->pCallbackInfo && pBuffer->pCallbackInfo->pCopy) {
+ pBuffer->pCallbackInfo->pCopy(*(void**)pBuffer->GetData());
+ }
+ }
+}
+void CXFA_Node::MoveBufferMapData(CXFA_Node* pDstModule, FX_LPVOID pKey)
+{
+ if (!pDstModule) {
+ return;
+ }
+ FX_BOOL bNeedMove = TRUE;
+ if (!pKey) {
+ bNeedMove = FALSE;
+ }
+ if (pDstModule->GetClassID() != this->GetClassID()) {
+ bNeedMove = FALSE;
+ }
+ XFA_LPMAPMODULEDATA pSrcModuleData = NULL;
+ XFA_LPMAPMODULEDATA pDstModuleData = NULL;
+ if (bNeedMove) {
+ pSrcModuleData = this->GetMapModuleData(FALSE);
+ if (!pSrcModuleData) {
+ bNeedMove = FALSE;
+ }
+ pDstModuleData = pDstModule->GetMapModuleData(TRUE);
+ if (!pDstModuleData) {
+ bNeedMove = FALSE;
+ }
+ }
+ if (bNeedMove) {
+ FX_LPVOID pBufferBlockData = pSrcModuleData->m_BufferMap.GetValueAt(pKey);
+ if (pBufferBlockData) {
+ pSrcModuleData->m_BufferMap.RemoveKey(pKey);
+ pDstModuleData->m_BufferMap.RemoveKey(pKey);
+ pDstModuleData->m_BufferMap.SetAt(pKey, (XFA_LPMAPDATABLOCK)pBufferBlockData);
+ }
+ }
+ if (pDstModule->GetObjectType() == XFA_OBJECTTYPE_NodeV) {
+ CFX_WideString wsValue = pDstModule->GetScriptContent(FALSE);
+ CFX_WideString wsFormatValue(wsValue);
+ CXFA_WidgetData* pWidgetData = pDstModule->GetContainerWidgetData();
+ if (pWidgetData) {
+ pWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
+ }
+ pDstModule->SetScriptContent(wsValue, wsFormatValue, TRUE, TRUE);
+ }
+}
+void CXFA_Node::MoveBufferMapData(CXFA_Node* pSrcModule, CXFA_Node* pDstModule, FX_LPVOID pKey, FX_BOOL bRecursive )
+{
+ if (!pSrcModule || !pDstModule || !pKey) {
+ return;
+ }
+ if (bRecursive) {
+ CXFA_Node* pSrcChild = pSrcModule->GetNodeItem(XFA_NODEITEM_FirstChild);
+ CXFA_Node* pDstChild = pDstModule->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for ( ; pSrcChild && pDstChild; pSrcChild = pSrcChild->GetNodeItem(XFA_NODEITEM_NextSibling), pDstChild = pDstChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ MoveBufferMapData(pSrcChild, pDstChild, pKey, TRUE);
+ }
+ }
+ pSrcModule->MoveBufferMapData(pDstModule, pKey);
+}
+CXFA_NodeList::CXFA_NodeList(CXFA_Document* pDocument)
+ : CXFA_Object(pDocument, XFA_OBJECTTYPE_NodeList)
+{
+ m_pDocument->GetScriptContext()->CacheList(this);
+}
+CXFA_Node* CXFA_NodeList::NamedItem(FX_WSTR wsName)
+{
+ FX_INT32 iCount = GetLength();
+ FX_DWORD dwHashCode = FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXFA_Node* ret = Item(i);
+ if (dwHashCode == ret->GetNameHash()) {
+ return ret;
+ }
+ }
+ return NULL;
+}
+void CXFA_NodeList::Script_ListClass_Append(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if(argc == 1) {
+ CXFA_Node *pNode = (CXFA_Node *)pArguments->GetObject(0);
+ if(pNode) {
+ Append(pNode);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"append"));
+ }
+}
+void CXFA_NodeList::Script_ListClass_Insert(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if(argc == 2) {
+ CXFA_Node *pNewNode = (CXFA_Node *)pArguments->GetObject(0);
+ CXFA_Node *pBeforeNode = (CXFA_Node *)pArguments->GetObject(1);
+ if(pNewNode) {
+ Insert(pNewNode, pBeforeNode);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"insert"));
+ }
+}
+void CXFA_NodeList::Script_ListClass_Remove(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if(argc == 1) {
+ CXFA_Node *pNode = (CXFA_Node *)pArguments->GetObject(0);
+ if(pNode) {
+ Remove(pNode);
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"remove"));
+ }
+}
+void CXFA_NodeList::Script_ListClass_Item(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if(argc == 1) {
+ FX_INT32 iIndex = pArguments->GetInt32(0);
+ if((iIndex >= 0) && (iIndex + 1 <= GetLength())) {
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(Item(iIndex)));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INDEX_OUT_OF_BOUNDS);
+ }
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"item"));
+ }
+}
+void CXFA_NodeList::Script_TreelistClass_NamedItem(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 argc = pArguments->GetLength();
+ if(argc == 1) {
+ CFX_ByteString szName = pArguments->GetUTF8String(0);
+ CXFA_Node* pNode = NamedItem(CFX_WideString::FromUTF8(szName, szName.GetLength()));
+ if (!pNode) {
+ return;
+ }
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"namedItem"));
+ }
+}
+void CXFA_NodeList::Script_ListClass_Length(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if(!bSetting) {
+ FXJSE_Value_SetInteger(hValue, GetLength());
+ } else {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ }
+}
+CXFA_ArrayNodeList::CXFA_ArrayNodeList(CXFA_Document* pDocument)
+ : CXFA_NodeList(pDocument)
+{
+}
+void CXFA_ArrayNodeList::SetArrayNodeList(const CXFA_NodeArray &srcArray)
+{
+ if (srcArray.GetSize() > 0) {
+ m_array.Copy(srcArray);
+ }
+}
+FX_INT32 CXFA_ArrayNodeList::GetLength()
+{
+ return m_array.GetSize();
+}
+FX_BOOL CXFA_ArrayNodeList::Append(CXFA_Node* pNode)
+{
+ m_array.Add(pNode);
+ return TRUE;
+}
+FX_BOOL CXFA_ArrayNodeList::Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode)
+{
+ if (pBeforeNode == NULL) {
+ m_array.Add(pNewNode);
+ } else {
+ FX_INT32 iSize = m_array.GetSize();
+ for (FX_INT32 i = 0; i < iSize; ++i) {
+ if (m_array[i] == pBeforeNode) {
+ m_array.InsertAt(i, pNewNode);
+ break;
+ }
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_ArrayNodeList::Remove(CXFA_Node* pNode)
+{
+ FX_INT32 iSize = m_array.GetSize();
+ for (FX_INT32 i = 0; i < iSize; ++i) {
+ if (m_array[i] == pNode) {
+ m_array.RemoveAt(i);
+ break;
+ }
+ }
+ return TRUE;
+}
+CXFA_Node* CXFA_ArrayNodeList::Item(FX_INT32 iIndex)
+{
+ FX_INT32 iSize = m_array.GetSize();
+ if (iIndex >= 0 && iIndex < iSize) {
+ return m_array[iIndex];
+ }
+ return NULL;
+}
+CXFA_AttachNodeList::CXFA_AttachNodeList(CXFA_Document* pDocument, CXFA_Node* pAttachNode)
+ : CXFA_NodeList(pDocument)
+{
+ m_pAttachNode = pAttachNode;
+}
+FX_INT32 CXFA_AttachNodeList::GetLength()
+{
+ return m_pAttachNode->CountChildren(XFA_ELEMENT_UNKNOWN, m_pAttachNode->GetClassID() == XFA_ELEMENT_Subform ? TRUE : FALSE);
+}
+FX_BOOL CXFA_AttachNodeList::Append(CXFA_Node* pNode)
+{
+ CXFA_Node* pParent = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParent) {
+ pParent->RemoveChild(pNode);
+ }
+ return m_pAttachNode->InsertChild(pNode);
+}
+FX_BOOL CXFA_AttachNodeList::Insert(CXFA_Node* pNewNode, CXFA_Node* pBeforeNode)
+{
+ CXFA_Node* pParent = pNewNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (pParent) {
+ pParent->RemoveChild(pNewNode);
+ }
+ return m_pAttachNode->InsertChild(pNewNode, pBeforeNode);
+}
+FX_BOOL CXFA_AttachNodeList::Remove(CXFA_Node* pNode)
+{
+ return m_pAttachNode->RemoveChild(pNode);
+}
+CXFA_Node* CXFA_AttachNodeList::Item(FX_INT32 iIndex)
+{
+ return m_pAttachNode->GetChild(iIndex, XFA_ELEMENT_UNKNOWN, m_pAttachNode->GetClassID() == XFA_ELEMENT_Subform ? TRUE : FALSE);
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp b/xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp
new file mode 100644
index 0000000000..a390d62592
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_objectacc_imp.cpp
@@ -0,0 +1,4161 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+static FX_ARGB XFA_WStringToColor(FX_WSTR wsValue)
+{
+ FX_BYTE r = 0, g = 0, b = 0;
+ if (wsValue.GetLength() == 0) {
+ return 0xff000000;
+ }
+ int cc = 0;
+ FX_LPCWSTR str = wsValue.GetPtr();
+ int len = wsValue.GetLength();
+ while (XFA_IsSpace(str[cc]) && cc < len) {
+ cc++;
+ }
+ if (cc >= len) {
+ return 0xff000000;
+ }
+ while (cc < len) {
+ if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
+ break;
+ }
+ r = r * 10 + str[cc] - '0';
+ cc ++;
+ }
+ if (cc < len && str[cc] == ',') {
+ cc ++;
+ while (XFA_IsSpace(str[cc]) && cc < len) {
+ cc++;
+ }
+ while (cc < len) {
+ if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
+ break;
+ }
+ g = g * 10 + str[cc] - '0';
+ cc ++;
+ }
+ if (cc < len && str[cc] == ',') {
+ cc ++;
+ while (XFA_IsSpace(str[cc]) && cc < len) {
+ cc++;
+ }
+ while (cc < len) {
+ if (str[cc] == ',' || !XFA_IsDigit(str[cc])) {
+ break;
+ }
+ b = b * 10 + str[cc] - '0';
+ cc ++;
+ }
+ }
+ }
+ return (0xff << 24) | (r << 16) | (g << 8) | b;
+}
+XFA_ELEMENT CXFA_Data::GetClassID() const
+{
+ return m_pNode ? m_pNode->GetClassID() : XFA_ELEMENT_UNKNOWN;
+}
+FX_BOOL CXFA_Data::TryMeasure(XFA_ATTRIBUTE eAttr, FX_FLOAT &fValue, FX_BOOL bUseDefault ) const
+{
+ CXFA_Measurement ms;
+ if (m_pNode->TryMeasure(eAttr, ms, bUseDefault)) {
+ fValue = ms.ToUnit(XFA_UNIT_Pt);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_Data::SetMeasure(XFA_ATTRIBUTE eAttr, FX_FLOAT fValue)
+{
+ CXFA_Measurement ms(fValue, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(eAttr, ms);
+}
+CXFA_Fill::CXFA_Fill(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+CXFA_Fill::~CXFA_Fill()
+{
+}
+FX_INT32 CXFA_Fill::GetPresence()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+}
+void CXFA_Fill::SetColor(FX_ARGB color)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
+ CFX_WideString wsColor;
+ int a, r, g, b;
+ ArgbDecode(color, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+}
+FX_ARGB CXFA_Fill::GetColor(FX_BOOL bText)
+{
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Color)) {
+ CFX_WideStringC wsColor;
+ if (pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE)) {
+ return XFA_WStringToColor(wsColor);
+ }
+ }
+ if (bText) {
+ return 0xFF000000;
+ }
+ return 0xFFFFFFFF;
+}
+FX_INT32 CXFA_Fill::GetFillType()
+{
+ CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChild) {
+ FX_INT32 eType = pChild->GetClassID();
+ if (eType != XFA_ELEMENT_Color && eType != XFA_ELEMENT_Extras) {
+ return eType;
+ }
+ pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return XFA_ELEMENT_Solid;
+}
+FX_INT32 CXFA_Fill::GetPattern(FX_ARGB& foreColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Pattern);
+ if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+ CFX_WideStringC wsColor;
+ pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+ foreColor = XFA_WStringToColor(wsColor);
+ } else {
+ foreColor = 0xFF000000;
+ }
+ return pNode->GetEnum(XFA_ATTRIBUTE_Type);
+}
+FX_INT32 CXFA_Fill::GetStipple(FX_ARGB& stippleColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Stipple);
+ FX_INT32 eAttr = 50;
+ pNode->TryInteger(XFA_ATTRIBUTE_Rate, eAttr);
+ if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+ CFX_WideStringC wsColor;
+ pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+ stippleColor = XFA_WStringToColor(wsColor);
+ } else {
+ stippleColor = 0xFF000000;
+ }
+ return eAttr;
+}
+FX_INT32 CXFA_Fill::GetLinear(FX_ARGB& endColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Linear);
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToRight;
+ pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
+ if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+ CFX_WideStringC wsColor;
+ pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+ endColor = XFA_WStringToColor(wsColor);
+ } else {
+ endColor = 0xFF000000;
+ }
+ return eAttr;
+}
+FX_INT32 CXFA_Fill::GetRadial(FX_ARGB& endColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Radial);
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_ToEdge;
+ pNode->TryEnum(XFA_ATTRIBUTE_Type, eAttr);
+ if (CXFA_Node* pColor = pNode->GetChild(0, XFA_ELEMENT_Color)) {
+ CFX_WideStringC wsColor;
+ pColor->TryCData(XFA_ATTRIBUTE_Value, wsColor, FALSE);
+ endColor = XFA_WStringToColor(wsColor);
+ } else {
+ endColor = 0xFF000000;
+ }
+ return eAttr;
+}
+FX_BOOL CXFA_Fill::SetPresence(FX_INT32 iPresence)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Presence, (XFA_ATTRIBUTEENUM)iPresence);
+}
+FX_BOOL CXFA_Fill::SetFillType(FX_INT32 iType)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_Fill::SetPattern(FX_INT32 iPattern, FX_ARGB foreColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Pattern);
+ CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+ CFX_WideString wsColor;
+ int a, r, g, b;
+ ArgbDecode(foreColor, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+ return pNode->SetEnum(XFA_ATTRIBUTE_Type, (XFA_ATTRIBUTEENUM)iPattern);
+}
+FX_BOOL CXFA_Fill::SetStipple(FX_INT32 iStipple, FX_ARGB stippleColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Stipple);
+ CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+ CFX_WideString wsColor;
+ int a, r, g, b;
+ ArgbDecode(stippleColor, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+ return pNode->SetEnum(XFA_ATTRIBUTE_Rate, (XFA_ATTRIBUTEENUM)iStipple);
+}
+FX_BOOL CXFA_Fill::SetLinear(FX_INT32 iLinear, FX_ARGB endColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Linear);
+ CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+ CFX_WideString wsColor;
+ int a, r, g, b;
+ ArgbDecode(endColor, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+ return pNode->SetEnum(XFA_ATTRIBUTE_Type, (XFA_ATTRIBUTEENUM)iLinear);
+}
+FX_BOOL CXFA_Fill::SetRadial(FX_INT32 iRadial, FX_ARGB endColor)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Radial);
+ CXFA_Node* pColor = pNode->GetProperty(0, XFA_ELEMENT_Color);
+ CFX_WideString wsColor;
+ int a, r, g, b;
+ ArgbDecode(endColor, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ pColor->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+ return pNode->SetEnum(XFA_ATTRIBUTE_Type, (XFA_ATTRIBUTEENUM)iRadial);
+}
+CXFA_Margin::CXFA_Margin(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_BOOL CXFA_Margin::GetLeftInset(FX_FLOAT &fInset, FX_FLOAT fDefInset ) const
+{
+ fInset = fDefInset;
+ return TryMeasure(XFA_ATTRIBUTE_LeftInset, fInset);
+}
+FX_BOOL CXFA_Margin::GetTopInset(FX_FLOAT &fInset, FX_FLOAT fDefInset ) const
+{
+ fInset = fDefInset;
+ return TryMeasure(XFA_ATTRIBUTE_TopInset, fInset);
+}
+FX_BOOL CXFA_Margin::GetRightInset(FX_FLOAT &fInset, FX_FLOAT fDefInset ) const
+{
+ fInset = fDefInset;
+ return TryMeasure(XFA_ATTRIBUTE_RightInset, fInset);
+}
+FX_BOOL CXFA_Margin::GetBottomInset(FX_FLOAT &fInset, FX_FLOAT fDefInset ) const
+{
+ fInset = fDefInset;
+ return TryMeasure(XFA_ATTRIBUTE_BottomInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetLeftInset(FX_FLOAT fInset)
+{
+ return SetMeasure(XFA_ATTRIBUTE_LeftInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetTopInset(FX_FLOAT fInset)
+{
+ return SetMeasure(XFA_ATTRIBUTE_TopInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetRightInset(FX_FLOAT fInset)
+{
+ return SetMeasure(XFA_ATTRIBUTE_RightInset, fInset);
+}
+FX_BOOL CXFA_Margin::SetBottomInset(FX_FLOAT fInset)
+{
+ return SetMeasure(XFA_ATTRIBUTE_BottomInset, fInset);
+}
+CXFA_Font::CXFA_Font(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_FLOAT CXFA_Font::GetBaselineShift()
+{
+ return m_pNode->GetMeasure(XFA_ATTRIBUTE_BaselineShift).ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Font::GetHorizontalScale()
+{
+ CFX_WideString wsValue;
+ m_pNode->TryCData(XFA_ATTRIBUTE_FontHorizontalScale, wsValue);
+ FX_INT32 iScale = FXSYS_wtoi((FX_LPCWSTR)wsValue);
+ return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
+}
+FX_FLOAT CXFA_Font::GetVerticalScale()
+{
+ CFX_WideString wsValue;
+ m_pNode->TryCData(XFA_ATTRIBUTE_FontVerticalScale, wsValue);
+ FX_INT32 iScale = FXSYS_wtoi((FX_LPCWSTR)wsValue);
+ return iScale > 0 ? (FX_FLOAT)iScale : 100.0f;
+}
+FX_FLOAT CXFA_Font::GetLetterSpacing()
+{
+ CFX_WideStringC wsValue;
+ if (!m_pNode->TryCData(XFA_ATTRIBUTE_LetterSpacing, wsValue)) {
+ return 0;
+ }
+ CXFA_Measurement ms(wsValue);
+ if (ms.GetUnit() == XFA_UNIT_Em) {
+ return ms.GetValue() * GetFontSize();
+ }
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_INT32 CXFA_Font::GetLineThrough()
+{
+ FX_INT32 iValue = 0;
+ m_pNode->TryInteger(XFA_ATTRIBUTE_LineThrough, iValue);
+ return iValue;
+}
+FX_INT32 CXFA_Font::GetLineThroughPeriod()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_LineThroughPeriod, eAttr);
+ return eAttr;
+}
+FX_INT32 CXFA_Font::GetOverline()
+{
+ FX_INT32 iValue = 0;
+ m_pNode->TryInteger(XFA_ATTRIBUTE_Overline, iValue);
+ return iValue;
+}
+FX_INT32 CXFA_Font::GetOverlinePeriod()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_OverlinePeriod, eAttr);
+ return eAttr;
+}
+FX_INT32 CXFA_Font::GetUnderline()
+{
+ FX_INT32 iValue = 0;
+ m_pNode->TryInteger(XFA_ATTRIBUTE_Underline, iValue);
+ return iValue;
+}
+FX_INT32 CXFA_Font::GetUnderlinePeriod()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_All;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_UnderlinePeriod, eAttr);
+ return eAttr;
+}
+FX_FLOAT CXFA_Font::GetFontSize()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_Size, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+void CXFA_Font::GetTypeface(CFX_WideStringC &wsTypeFace)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Typeface, wsTypeFace);
+}
+FX_BOOL CXFA_Font::IsBold()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Weight, eAttr);
+ return eAttr == XFA_ATTRIBUTEENUM_Bold;
+}
+FX_BOOL CXFA_Font::IsItalic()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Normal;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Posture, eAttr);
+ return eAttr == XFA_ATTRIBUTEENUM_Italic;
+}
+FX_BOOL CXFA_Font::IsUseKerning()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_KerningMode, eAttr);
+ return eAttr == XFA_ATTRIBUTEENUM_Pair;
+}
+void CXFA_Font::SetColor(FX_ARGB color)
+{
+ CXFA_Fill fill = m_pNode->GetProperty(0, XFA_ELEMENT_Fill);
+ fill.SetColor(color);
+}
+FX_ARGB CXFA_Font::GetColor()
+{
+ if (CXFA_Fill fill = m_pNode->GetChild(0, XFA_ELEMENT_Fill)) {
+ return fill.GetColor(TRUE);
+ }
+ return 0xFF000000;
+}
+FX_BOOL CXFA_Font::SetBaselineShift(FX_FLOAT fBaselineShift)
+{
+ CXFA_Measurement ms(fBaselineShift, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_BaselineShift, ms);
+}
+FX_BOOL CXFA_Font::SetHorizontalScale(FX_FLOAT fHorizontalScale)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%d", (FX_INT32)fHorizontalScale);
+ return m_pNode->SetCData(XFA_ATTRIBUTE_FontHorizontalScale, wsValue);
+}
+FX_BOOL CXFA_Font::SetVerticalScale(FX_FLOAT fVerticalScale)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%d", (FX_INT32)fVerticalScale);
+ return m_pNode->SetCData(XFA_ATTRIBUTE_FontVerticalScale, wsValue);
+}
+FX_BOOL CXFA_Font::SetLetterSpacing(FX_FLOAT fLetterSpacing, XFA_UNIT eUnit)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_Font::SetLineThrough(FX_INT32 iLineThrough)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_LineThrough, iLineThrough);
+}
+FX_BOOL CXFA_Font::SetLineThroughPeriod(FX_INT32 iLineThroughPeriod)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_LineThroughPeriod, (XFA_ATTRIBUTEENUM)iLineThroughPeriod);
+}
+FX_BOOL CXFA_Font::SetOverline(FX_INT32 iOverline)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_Overline, iOverline);
+}
+FX_BOOL CXFA_Font::SetOverlinePeriod(FX_INT32 iOverlinePeriod)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_OverlinePeriod, (XFA_ATTRIBUTEENUM)iOverlinePeriod);
+}
+FX_BOOL CXFA_Font::SetUnderline(FX_INT32 iUnderline)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_Underline, iUnderline);
+}
+FX_BOOL CXFA_Font::SetUnderlinePeriod(FX_INT32 iUnderlinePeriod)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_UnderlinePeriod, (XFA_ATTRIBUTEENUM)iUnderlinePeriod);
+}
+CXFA_Caption::CXFA_Caption(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_INT32 CXFA_Caption::GetPresence()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Visible;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Presence, eAttr);
+ return eAttr;
+}
+FX_INT32 CXFA_Caption::GetPlacementType()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Placement, eAttr);
+ return eAttr;
+}
+FX_FLOAT CXFA_Caption::GetReserve()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_Reserve, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+CXFA_Margin CXFA_Caption::GetMargin()
+{
+ return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin) : NULL);
+}
+CXFA_Font CXFA_Caption::GetFont()
+{
+ return CXFA_Font(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Font) : NULL);
+}
+CXFA_Value CXFA_Caption::GetValue()
+{
+ return CXFA_Value(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Value) : NULL);
+}
+CXFA_Para CXFA_Caption::GetPara()
+{
+ return CXFA_Para(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Para) : NULL);
+}
+FX_BOOL CXFA_Caption::SetPresence(FX_INT32 iPresence)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Presence, (XFA_ATTRIBUTEENUM)iPresence);
+}
+FX_BOOL CXFA_Caption::SetPlacementType(FX_INT32 iType)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Placement, (XFA_ATTRIBUTEENUM)iType);
+}
+FX_BOOL CXFA_Caption::SetReserve(FX_FLOAT fReserve)
+{
+ CXFA_Measurement ms(fReserve, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_Reserve, ms);
+}
+CXFA_Para::CXFA_Para(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_INT32 CXFA_Para::GetHorizontalAlign()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Left;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_HAlign, eAttr);
+ return eAttr;
+}
+FX_INT32 CXFA_Para::GetVerticalAlign()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_Top;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_VAlign, eAttr);
+ return eAttr;
+}
+FX_FLOAT CXFA_Para::GetLineHeight()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_LineHeight, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetMarginLeft()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginLeft, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetMarginRight()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_MarginRight, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_INT32 CXFA_Para::GetOrphans()
+{
+ FX_INT32 iValue = 0;
+ m_pNode->TryInteger(XFA_ATTRIBUTE_Orphans, iValue);
+ return iValue;
+}
+FX_FLOAT CXFA_Para::GetRadixOffset()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_RadixOffset, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetSpaceAbove()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceAbove, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetSpaceBelow()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_SpaceBelow, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_FLOAT CXFA_Para::GetTextIndent()
+{
+ CXFA_Measurement ms;
+ m_pNode->TryMeasure(XFA_ATTRIBUTE_TextIndent, ms);
+ return ms.ToUnit(XFA_UNIT_Pt);
+}
+FX_INT32 CXFA_Para::GetWidows()
+{
+ FX_INT32 iValue = 0;
+ m_pNode->TryInteger(XFA_ATTRIBUTE_Widows, iValue);
+ return iValue;
+}
+FX_BOOL CXFA_Para::SetHorizontalAlign(FX_INT32 iHorizontalAlign)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_HAlign, (XFA_ATTRIBUTEENUM)iHorizontalAlign);
+}
+FX_BOOL CXFA_Para::SetVerticalAlign(FX_INT32 iVerticalAlign)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_VAlign, (XFA_ATTRIBUTEENUM)iVerticalAlign);
+}
+FX_BOOL CXFA_Para::SetLineHeight(FX_FLOAT fLineHeight)
+{
+ CXFA_Measurement ms;
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_LineHeight, ms);
+}
+FX_BOOL CXFA_Para::SetMarginLeft(FX_FLOAT fMarginLeft)
+{
+ CXFA_Measurement ms(fMarginLeft, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_MarginLeft, ms);
+}
+FX_BOOL CXFA_Para::SetMarginRight(FX_FLOAT fMarginRight)
+{
+ CXFA_Measurement ms(fMarginRight, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_MarginRight, ms);
+}
+FX_BOOL CXFA_Para::SetOrphans(FX_INT32 iOrphans)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_Orphans, iOrphans);
+}
+FX_BOOL CXFA_Para::SetRadixOffset(FX_FLOAT fRadixOffset)
+{
+ CXFA_Measurement ms(fRadixOffset, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_RadixOffset, ms);
+}
+FX_BOOL CXFA_Para::SetSpaceAbove(FX_FLOAT fSpaceAbove)
+{
+ CXFA_Measurement ms(fSpaceAbove, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_SpaceAbove, ms);
+}
+FX_BOOL CXFA_Para::SetSpaceBelow(FX_FLOAT fSpaceBelow)
+{
+ CXFA_Measurement ms(fSpaceBelow, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_SpaceBelow, ms);
+}
+FX_BOOL CXFA_Para::SetTextIndent(FX_FLOAT fTextIndent)
+{
+ CXFA_Measurement ms(fTextIndent, XFA_UNIT_Pt);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_TextIndent, ms);
+}
+FX_BOOL CXFA_Para::SetWidows(FX_INT32 iWidows)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_Widows, iWidows);
+}
+CXFA_Keep::CXFA_Keep(CXFA_Node *pNode, CXFA_Node *pParent)
+ : CXFA_Data(pNode)
+ , m_pParent(pParent)
+{
+}
+FX_INT32 CXFA_Keep::GetIntact()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+ switch (m_pParent->GetClassID()) {
+ case XFA_ELEMENT_Subform: {
+ XFA_ATTRIBUTEENUM eAttrSubForm;
+ m_pParent->TryEnum(XFA_ATTRIBUTE_Layout, eAttrSubForm);
+ if (eAttrSubForm == XFA_ATTRIBUTEENUM_Position || eAttrSubForm == XFA_ATTRIBUTEENUM_Row) {
+ eAttr = XFA_ATTRIBUTEENUM_ContentArea;
+ }
+ }
+ break;
+ case XFA_ELEMENT_Draw:
+ eAttr = XFA_ATTRIBUTEENUM_ContentArea;
+ break;
+ default:
+ break;
+ }
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Intact, eAttr, FALSE);
+ return eAttr;
+}
+FX_INT32 CXFA_Keep::GetNext()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Next, eAttr);
+ return eAttr;
+}
+FX_INT32 CXFA_Keep::GetPrevious()
+{
+ XFA_ATTRIBUTEENUM eAttr = XFA_ATTRIBUTEENUM_None;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Previous, eAttr);
+ return eAttr;
+}
+FX_BOOL CXFA_Keep::SetIntact(FX_INT32 iIntact)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Intact, (XFA_ATTRIBUTEENUM)iIntact);
+}
+FX_BOOL CXFA_Keep::SetNext(FX_INT32 iNext)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Next, (XFA_ATTRIBUTEENUM)iNext);
+}
+FX_BOOL CXFA_Keep::SetPrevious(FX_INT32 iPrevious)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Previous, (XFA_ATTRIBUTEENUM)iPrevious);
+}
+CXFA_Event::CXFA_Event(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_INT32 CXFA_Event::GetActivity()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Activity);
+}
+FX_INT32 CXFA_Event::GetEventType()
+{
+ CXFA_Node* pChild = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChild) {
+ FX_INT32 eType = pChild->GetClassID();
+ if (eType != XFA_ELEMENT_Extras) {
+ return eType;
+ }
+ pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return XFA_ELEMENT_UNKNOWN;
+}
+void CXFA_Event::GetRef(CFX_WideStringC &wsRef)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+FX_INT32 CXFA_Event::GetExecuteRunAt()
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+ return pNode->GetEnum(XFA_ATTRIBUTE_RunAt);
+}
+FX_INT32 CXFA_Event::GetExecuteType()
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+ return pNode->GetEnum(XFA_ATTRIBUTE_ExecuteType);
+}
+void CXFA_Event::GetExecuteConnection(CFX_WideString &wsConnection)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+ CFX_WideStringC cData;
+ pNode->TryCData(XFA_ATTRIBUTE_Connection, cData);
+ wsConnection = cData;
+}
+CXFA_Script CXFA_Event::GetScript()
+{
+ return m_pNode->GetChild(0, XFA_ELEMENT_Script);
+}
+CXFA_Submit CXFA_Event::GetSubmit()
+{
+ return m_pNode->GetChild(0, XFA_ELEMENT_Submit);
+}
+FX_INT32 CXFA_Event::GetSignDataOperation()
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData);
+ return pNode->GetEnum(XFA_ATTRIBUTE_Operation);
+}
+void CXFA_Event::GetSignDataTarget(CFX_WideString &wsTarget)
+{
+ if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData)) {
+ CFX_WideStringC wsCData;
+ pNode->TryCData(XFA_ATTRIBUTE_Target, wsCData);
+ wsTarget = wsCData;
+ }
+}
+FX_BOOL CXFA_Event::SetActivity(FX_INT32 iActivity)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Activity, (XFA_ATTRIBUTEENUM)iActivity);
+}
+FX_BOOL CXFA_Event::SetEventType(FX_INT32 iEventType)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_Event::SetExecuteRunAt(FX_INT32 iExecuteRunAt)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+ return pNode->SetEnum(XFA_ATTRIBUTE_RunAt, (XFA_ATTRIBUTEENUM)iExecuteRunAt);
+}
+FX_BOOL CXFA_Event::SetExecuteType(FX_INT32 iExecuteType)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+ return pNode->SetEnum(XFA_ATTRIBUTE_ExecuteType, (XFA_ATTRIBUTEENUM)iExecuteType);
+}
+FX_BOOL CXFA_Event::SetExecuteConnection(const CFX_WideString& wsConnection)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Execute);
+ return pNode->SetCData(XFA_ATTRIBUTE_Connection, wsConnection);
+}
+FX_BOOL CXFA_Event::SetSignDataOperation(FX_INT32 iOperation)
+{
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData);
+ return pNode->SetEnum(XFA_ATTRIBUTE_Operation, (XFA_ATTRIBUTEENUM)iOperation);
+}
+FX_BOOL CXFA_Event::SetSignDataTarget(const CFX_WideString& wsTarget)
+{
+ if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_SignData)) {
+ return pNode->SetCData(XFA_ATTRIBUTE_Target, wsTarget);
+ }
+ return FALSE;
+}
+CXFA_Script::CXFA_Script(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+void CXFA_Script::GetBinding(CFX_WideString &wsBinding)
+{
+ CFX_WideStringC cData;
+ m_pNode->TryCData(XFA_ATTRIBUTE_Binding, cData);
+ wsBinding = cData;
+}
+XFA_SCRIPTTYPE CXFA_Script::GetContentType()
+{
+ CFX_WideStringC cData;
+ if (m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, cData, FALSE)) {
+ if (cData == FX_WSTRC(L"application/x-javascript")) {
+ return XFA_SCRIPTTYPE_Javascript;
+ } else if (cData == FX_WSTRC(L"application/x-formcalc")) {
+ return XFA_SCRIPTTYPE_Formcalc;
+ } else {
+ return XFA_SCRIPTTYPE_Unkown;
+ }
+ }
+ return XFA_SCRIPTTYPE_Formcalc;
+}
+FX_INT32 CXFA_Script::GetRunAt()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_RunAt);
+}
+void CXFA_Script::GetExpression(CFX_WideString &wsExpression)
+{
+ m_pNode->TryContent(wsExpression);
+}
+FX_BOOL CXFA_Script::SetBinding(const CFX_WideString& wsBinding)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Binding, wsBinding);
+}
+FX_BOOL CXFA_Script::SetContentType(XFA_SCRIPTTYPE eType)
+{
+ CFX_WideString wsType;
+ switch (eType) {
+ case XFA_SCRIPTTYPE_Javascript:
+ wsType = L"application/x-javascript";
+ break;
+ case XFA_SCRIPTTYPE_Formcalc:
+ wsType = L"application/x-formcalc";
+ break;
+ default:
+ break;
+ }
+ return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsType);
+}
+FX_BOOL CXFA_Script::SetRunAt(FX_INT32 iRunAt)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_RunAt, (XFA_ATTRIBUTEENUM)iRunAt);
+}
+FX_BOOL CXFA_Script::SetExpression(const CFX_WideString& wsExpression)
+{
+ return m_pNode->SetContent(wsExpression, wsExpression);
+}
+CXFA_Submit::CXFA_Submit(CXFA_Node* pNode)
+ : CXFA_Data (pNode)
+{
+}
+FX_BOOL CXFA_Submit::IsSubmitEmbedPDF()
+{
+ return m_pNode->GetBoolean(XFA_ATTRIBUTE_EmbedPDF);
+}
+FX_INT32 CXFA_Submit::GetSubmitFormat()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Format);
+}
+void CXFA_Submit::GetSubmitTarget(CFX_WideStringC &wsTarget)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Target, wsTarget);
+}
+XFA_TEXTENCODING CXFA_Submit::GetSubmitTextEncoding()
+{
+ CFX_WideStringC wsCData;
+ if (!m_pNode->TryCData(XFA_ATTRIBUTE_TextEncoding, wsCData)) {
+ return XFA_TEXTENCODING_None;
+ }
+ CFX_WideString wsValue(wsCData);
+ if (wsValue == L"Big-Five") {
+ return XFA_TEXTENCODING_Big5;
+ } else if (wsValue == L"fontSpecific") {
+ return XFA_TEXTENCODING_FontSpecific;
+ } else if (wsValue == L"GBK") {
+ return XFA_TEXTENCODING_GBK;
+ } else if (wsValue == L"GB-18030") {
+ return XFA_TEXTENCODING_GB18030;
+ } else if (wsValue == L"GB-2312") {
+ return XFA_TEXTENCODING_GB2312;
+ } else if (wsValue == L"ISO-8859-NN") {
+ return XFA_TEXTENCODING_ISO8859NN;
+ } else if (wsValue == L"KSC-5601") {
+ return XFA_TEXTENCODING_KSC5601;
+ } else if (wsValue == L"Shift-JIS") {
+ return XFA_TEXTENCODING_ShiftJIS;
+ } else if (wsValue == L"UCS-2") {
+ return XFA_TEXTENCODING_UCS2;
+ } else if (wsValue == L"UTF-16") {
+ return XFA_TEXTENCODING_UTF16;
+ } else if (wsValue == L"UTF-8") {
+ return XFA_TEXTENCODING_UTF8;
+ }
+ return XFA_TEXTENCODING_None;
+}
+void CXFA_Submit::GetSubmitXDPContent(CFX_WideStringC &wsContent)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_XdpContent, wsContent);
+}
+FX_BOOL CXFA_Submit::SetSubmitFormat(FX_INT32 iSubmitFormat)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Format, (XFA_ATTRIBUTEENUM)iSubmitFormat);
+}
+FX_BOOL CXFA_Submit::SetSubmitTarget(const CFX_WideString& wsTarget)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Target, wsTarget);
+}
+FX_BOOL CXFA_Submit::SetSubmitTextEncoding(XFA_TEXTENCODING eTextEncoding)
+{
+ CFX_WideString wsValue;
+ switch (eTextEncoding) {
+ case XFA_TEXTENCODING_Big5:
+ wsValue = L"Big-Five";
+ break;
+ case XFA_TEXTENCODING_FontSpecific:
+ wsValue = L"fontSpecific";
+ break;
+ case XFA_TEXTENCODING_GBK:
+ wsValue = L"GBK";
+ break;
+ case XFA_TEXTENCODING_GB18030:
+ wsValue = L"GB-18030";
+ break;
+ case XFA_TEXTENCODING_GB2312:
+ wsValue = L"GB-2312";
+ break;
+ case XFA_TEXTENCODING_ISO8859NN:
+ wsValue = L"ISO-8859-NN";
+ break;
+ case XFA_TEXTENCODING_KSC5601:
+ wsValue = L"KSC-5601";
+ break;
+ case XFA_TEXTENCODING_ShiftJIS:
+ wsValue = L"Shift-JIS";
+ break;
+ case XFA_TEXTENCODING_UCS2:
+ wsValue = L"UCS-2";
+ break;
+ case XFA_TEXTENCODING_UTF16:
+ wsValue = L"UTF-16";
+ break;
+ case XFA_TEXTENCODING_UTF8:
+ wsValue = L"UTF-8";
+ break;
+ default:
+ break;
+ }
+ return m_pNode->SetCData(XFA_ATTRIBUTE_TextEncoding, wsValue);
+}
+FX_BOOL CXFA_Submit::SetSubmitXDPContent(const CFX_WideString& wsContent)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_XdpContent, wsContent);
+}
+XFA_ELEMENT CXFA_Value::GetChildValueClassID()
+{
+ if (!m_pNode) {
+ return XFA_ELEMENT_UNKNOWN;
+ }
+ if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ return pNode->GetClassID();
+ }
+ return XFA_ELEMENT_UNKNOWN;
+}
+FX_BOOL CXFA_Value::GetChildValueContent(CFX_WideString &wsContent)
+{
+ if (!m_pNode) {
+ return FALSE;
+ }
+ if (CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ return pNode->TryContent(wsContent);
+ }
+ return FALSE;
+}
+CXFA_Arc CXFA_Value::GetArc()
+{
+ return m_pNode ? CXFA_Arc(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : NULL;
+}
+CXFA_Line CXFA_Value::GetLine()
+{
+ return m_pNode ? CXFA_Line(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : NULL;
+}
+CXFA_Rectangle CXFA_Value::GetRectangle()
+{
+ return m_pNode ? CXFA_Rectangle(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : NULL;
+}
+CXFA_Text CXFA_Value::GetText()
+{
+ return m_pNode ? CXFA_Text(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : NULL;
+}
+CXFA_ExData CXFA_Value::GetExData()
+{
+ return m_pNode ? CXFA_ExData(m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : NULL;
+}
+CXFA_Image CXFA_Value::GetImage()
+{
+ return CXFA_Image(m_pNode ? (m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) : NULL, TRUE);
+}
+FX_BOOL CXFA_Value::SetChildValueContent(const CFX_WideString& wsContent, FX_BOOL bNotify , XFA_ELEMENT iType )
+{
+ if (!m_pNode) {
+ return FALSE;
+ }
+ CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pNode) {
+ if (iType == XFA_ELEMENT_UNKNOWN) {
+ return FALSE;
+ }
+ pNode = m_pNode->GetProperty(0, iType);
+ }
+ CFX_WideString wsFormatContent(wsContent);
+ CXFA_WidgetData* pContainerWidgetData = pNode->GetContainerWidgetData();
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsContent, wsFormatContent);
+ }
+ return pNode->SetContent(wsContent, wsFormatContent, bNotify);
+}
+FX_INT32 CXFA_Line::GetHand()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
+}
+FX_BOOL CXFA_Line::GetSlop()
+{
+ XFA_ATTRIBUTEENUM eSlop = m_pNode->GetEnum(XFA_ATTRIBUTE_Slope);
+ return (eSlop == XFA_ATTRIBUTEENUM_Slash) ? TRUE : FALSE;
+}
+CXFA_Edge CXFA_Line::GetEdge()
+{
+ return CXFA_Edge(m_pNode->GetChild(0, XFA_ELEMENT_Edge));
+}
+FX_BOOL CXFA_Line::SetHand(FX_INT32 iHand)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Hand, (XFA_ATTRIBUTEENUM)iHand);
+}
+FX_BOOL CXFA_Line::SetSlop(FX_INT32 iSlop)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Slope, (XFA_ATTRIBUTEENUM)iSlop);
+}
+CXFA_Text::CXFA_Text(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+void CXFA_Text::GetName(CFX_WideStringC &wsName)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+}
+FX_INT32 CXFA_Text::GetMaxChars()
+{
+ return m_pNode->GetInteger(XFA_ATTRIBUTE_MaxChars);
+}
+void CXFA_Text::GetRid(CFX_WideStringC &wsRid)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+void CXFA_Text::GetContent(CFX_WideString &wsText)
+{
+ m_pNode->TryContent(wsText);
+}
+void CXFA_Text::SetContent(CFX_WideString wsText, FX_BOOL bNotify )
+{
+ CFX_WideString wsFormatValue(wsText);
+ CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsText, wsFormatValue);
+ }
+ m_pNode->SetContent(wsText, wsFormatValue, bNotify);
+}
+FX_BOOL CXFA_Text::SetName(const CFX_WideString& wsName)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+}
+FX_BOOL CXFA_Text::SetMaxChars(FX_INT32 iMaxChars)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_MaxChars, iMaxChars);
+}
+FX_BOOL CXFA_Text::SetRid(const CFX_WideString& wsRid)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+CXFA_ExData::CXFA_ExData(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+void CXFA_ExData::GetContentType(CFX_WideStringC &wsContentType)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+void CXFA_ExData::GetHref(CFX_WideStringC &wsHref)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Href, wsHref);
+}
+FX_INT32 CXFA_ExData::GetMaxLength()
+{
+ return m_pNode->GetInteger(XFA_ATTRIBUTE_MaxLength);
+}
+void CXFA_ExData::GetRid(CFX_WideStringC &wsRid)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+FX_INT32 CXFA_ExData::GetTransferEncoding()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_TransferEncoding);
+}
+void CXFA_ExData::GetContent(CFX_WideString &wsText)
+{
+ m_pNode->TryContent(wsText);
+}
+FX_BOOL CXFA_ExData::SetContentType(const CFX_WideString& wsContentType)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+FX_BOOL CXFA_ExData::SetHref(const CFX_WideString& wsHref)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Href, wsHref);
+}
+FX_BOOL CXFA_ExData::SetMaxLength(FX_INT32 iMaxLength)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_MaxLength, iMaxLength);
+}
+FX_BOOL CXFA_ExData::SetRid(const CFX_WideString& wsRid)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Rid, wsRid);
+}
+FX_BOOL CXFA_ExData::SetTransferEncoding(FX_INT32 iTransferEncoding)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_TransferEncoding, (XFA_ATTRIBUTEENUM)iTransferEncoding);
+}
+FX_BOOL CXFA_ExData::SetContent(const CFX_WideString& wsText, FX_BOOL bNotify , FX_BOOL bScriptModify, FX_BOOL bSyncData )
+{
+ CFX_WideString wsFormatValue(wsText);
+ CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsText, wsFormatValue);
+ }
+ return m_pNode->SetContent(wsText, wsFormatValue, bNotify, bScriptModify, bSyncData);
+}
+CXFA_Image::CXFA_Image(CXFA_Node* pNode, FX_BOOL bDefValue)
+ : CXFA_Data(pNode)
+ , m_bDefValue(bDefValue)
+{
+}
+FX_INT32 CXFA_Image::GetAspect()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Aspect);
+}
+FX_BOOL CXFA_Image::GetContentType(CFX_WideString &wsContentType)
+{
+ return m_pNode->TryCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+FX_BOOL CXFA_Image::GetHref(CFX_WideString &wsHref)
+{
+ if (m_bDefValue) {
+ return m_pNode->TryCData(XFA_ATTRIBUTE_Href, wsHref);
+ }
+ return m_pNode->GetAttribute(FX_WSTRC(L"href"), wsHref);
+}
+FX_INT32 CXFA_Image::GetTransferEncoding()
+{
+ if (m_bDefValue) {
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_TransferEncoding);
+ }
+ return XFA_ATTRIBUTEENUM_Base64;
+}
+FX_BOOL CXFA_Image::GetContent(CFX_WideString &wsText)
+{
+ return m_pNode->TryContent(wsText);
+}
+FX_BOOL CXFA_Image::SetAspect(FX_INT32 iAspect)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Aspect, (XFA_ATTRIBUTEENUM)iAspect);
+}
+FX_BOOL CXFA_Image::SetContentType(const CFX_WideString& wsContentType)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_ContentType, wsContentType);
+}
+FX_BOOL CXFA_Image::SetHref(const CFX_WideString& wsHref)
+{
+ if (m_bDefValue) {
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Href, wsHref);
+ }
+ return m_pNode->SetAttribute(XFA_ATTRIBUTE_Href, wsHref);
+}
+FX_BOOL CXFA_Image::SetTransferEncoding(FX_INT32 iTransferEncoding)
+{
+ if (m_bDefValue) {
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_TransferEncoding, (XFA_ATTRIBUTEENUM)iTransferEncoding);
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_Image::SetContent(const CFX_WideString& wsText)
+{
+ CFX_WideString wsFormatValue(wsText);
+ CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsText, wsFormatValue);
+ }
+ return m_pNode->SetContent(wsText, wsFormatValue);
+}
+CXFA_Calculate::CXFA_Calculate(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_INT32 CXFA_Calculate::GetOverride()
+{
+ XFA_ATTRIBUTEENUM eAtt = XFA_ATTRIBUTEENUM_Error;
+ m_pNode->TryEnum(XFA_ATTRIBUTE_Override, eAtt, FALSE);
+ return eAtt;
+}
+CXFA_Script CXFA_Calculate::GetScript()
+{
+ return m_pNode->GetChild(0, XFA_ELEMENT_Script);
+}
+void CXFA_Calculate::GetMessageText(CFX_WideString &wsMessage)
+{
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Message)) {
+ CXFA_Text text(pNode->GetChild(0, XFA_ELEMENT_Text));
+ if (text) {
+ text.GetContent(wsMessage);
+ }
+ }
+}
+FX_BOOL CXFA_Calculate::SetOverride(FX_INT32 iOverride)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Override, (XFA_ATTRIBUTEENUM)iOverride);
+}
+FX_BOOL CXFA_Calculate::SetMessageText(const CFX_WideString& wsMessage)
+{
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Message)) {
+ CXFA_Node* pChildNode = pNode->GetProperty(0, XFA_ELEMENT_Text);
+ return pChildNode->SetContent(wsMessage, wsMessage);
+ }
+ return FALSE;
+}
+CXFA_Validate::CXFA_Validate(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_INT32 CXFA_Validate::GetFormatTest()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_FormatTest);
+}
+FX_BOOL CXFA_Validate::SetTestValue(FX_INT32 iType, CFX_WideString &wsValue, XFA_ATTRIBUTEENUM eName)
+{
+ XFA_LPCATTRIBUTEENUMINFO pInfo = XFA_GetAttributeEnumByName(wsValue);
+ if (pInfo) {
+ eName = pInfo->eName;
+ }
+ m_pNode->SetEnum((XFA_ATTRIBUTE)iType, eName, FALSE);
+ return TRUE;
+}
+FX_BOOL CXFA_Validate::SetFormatTest(CFX_WideString wsValue)
+{
+ return SetTestValue(XFA_ATTRIBUTE_FormatTest, wsValue, XFA_ATTRIBUTEENUM_Warning);
+}
+FX_BOOL CXFA_Validate::SetNullTest(CFX_WideString wsValue)
+{
+ return SetTestValue(XFA_ATTRIBUTE_NullTest, wsValue, XFA_ATTRIBUTEENUM_Disabled);
+}
+FX_INT32 CXFA_Validate::GetNullTest()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_NullTest);
+}
+FX_INT32 CXFA_Validate::GetScriptTest()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_ScriptTest);
+}
+void CXFA_Validate::GetMessageText(CFX_WideString &wsMessage, FX_WSTR wsMessageType)
+{
+ if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, FALSE)) {
+ CXFA_Node *pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItemNode; pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
+ continue;
+ }
+ CFX_WideStringC wsName;
+ pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+ if (wsName.IsEmpty() || wsName == wsMessageType) {
+ pItemNode->TryContent(wsMessage);
+ return;
+ }
+ }
+ }
+}
+void CXFA_Validate::SetFormatMessageText(CFX_WideString wsMessage)
+{
+ SetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
+}
+void CXFA_Validate::GetFormatMessageText(CFX_WideString &wsMessage)
+{
+ GetMessageText(wsMessage, FX_WSTRC(L"formatTest"));
+}
+void CXFA_Validate::SetNullMessageText(CFX_WideString wsMessage)
+{
+ SetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
+}
+void CXFA_Validate::GetNullMessageText(CFX_WideString &wsMessage)
+{
+ GetMessageText(wsMessage, FX_WSTRC(L"nullTest"));
+}
+void CXFA_Validate::SetMessageText(CFX_WideString &wsMessage, FX_WSTR wsMessageType)
+{
+ if (CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Message, TRUE)) {
+ CXFA_Node *pItemNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItemNode; pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItemNode->GetClassID() != XFA_ELEMENT_Text) {
+ continue;
+ }
+ CFX_WideStringC wsName;
+ pItemNode->TryCData(XFA_ATTRIBUTE_Name, wsName);
+ if (wsName.IsEmpty() || wsName == wsMessageType) {
+ pItemNode->SetContent(wsMessage, wsMessage, FALSE);
+ return;
+ }
+ }
+ CXFA_Node* pTextNode = pNode->CreateSamePacketNode(XFA_ELEMENT_Text);
+ pNode->InsertChild(pTextNode);
+ pTextNode->SetCData(XFA_ATTRIBUTE_Name, wsMessageType, FALSE);
+ pTextNode->SetContent(wsMessage, wsMessage, FALSE);
+ }
+}
+void CXFA_Validate::GetScriptMessageText(CFX_WideString &wsMessage)
+{
+ GetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
+}
+void CXFA_Validate::SetScriptMessageText(CFX_WideString wsMessage)
+{
+ SetMessageText(wsMessage, FX_WSTRC(L"scriptTest"));
+}
+void CXFA_Validate::GetPicture(CFX_WideString &wsPicture)
+{
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
+ pNode->TryContent(wsPicture);
+ }
+}
+CXFA_Script CXFA_Validate::GetScript()
+{
+ return m_pNode->GetChild(0, XFA_ELEMENT_Script);
+}
+CXFA_Variables::CXFA_Variables(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_INT32 CXFA_Variables::CountScripts()
+{
+ return m_pNode->CountChildren(XFA_ELEMENT_Script);
+}
+CXFA_Script CXFA_Variables::GetScript(FX_INT32 nIndex)
+{
+ return m_pNode->GetChild(nIndex, XFA_ELEMENT_Script);
+}
+CXFA_Bind::CXFA_Bind(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_INT32 CXFA_Bind::GetMatch()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Match);
+}
+void CXFA_Bind::GetRef(CFX_WideStringC &wsRef)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+void CXFA_Bind::GetPicture(CFX_WideString &wsPicture)
+{
+ if (CXFA_Node* pPicture = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
+ pPicture->TryContent(wsPicture);
+ }
+}
+FX_BOOL CXFA_Bind::SetMatch(FX_INT32 iMatch)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Match, (XFA_ATTRIBUTEENUM)iMatch);
+}
+FX_BOOL CXFA_Bind::SetRef(const CFX_WideString& wsRef)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+FX_BOOL CXFA_Bind::SetPicture(const CFX_WideString& wsPicture)
+{
+ if (CXFA_Node* pPicture = m_pNode->GetChild(0, XFA_ELEMENT_Picture)) {
+ return pPicture->SetContent(wsPicture, wsPicture);
+ }
+ return FALSE;
+}
+CXFA_Assist::CXFA_Assist(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+CXFA_ToolTip CXFA_Assist::GetToolTip()
+{
+ return m_pNode->GetChild(0, XFA_ELEMENT_ToolTip);
+}
+CXFA_ToolTip::CXFA_ToolTip(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+FX_BOOL CXFA_ToolTip::GetTip(CFX_WideString &wsTip)
+{
+ return m_pNode->TryContent(wsTip);
+}
+FX_BOOL CXFA_ToolTip::SetTip(const CFX_WideString& wsTip)
+{
+ return m_pNode->SetContent(wsTip, wsTip);
+}
+CXFA_BindItems::CXFA_BindItems(CXFA_Node* pNode)
+ : CXFA_Data(pNode)
+{
+}
+void CXFA_BindItems::GetConnection(CFX_WideStringC &wsConnection)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Connection, wsConnection);
+}
+void CXFA_BindItems::GetLabelRef(CFX_WideStringC &wsLabelRef)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_LabelRef, wsLabelRef);
+}
+void CXFA_BindItems::GetValueRef(CFX_WideStringC &wsValueRef)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_ValueRef, wsValueRef);
+}
+void CXFA_BindItems::GetRef(CFX_WideStringC &wsRef)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+FX_BOOL CXFA_BindItems::SetConnection(const CFX_WideString& wsConnection)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Connection, wsConnection);
+}
+FX_BOOL CXFA_BindItems::SetLabelRef(const CFX_WideString& wsLabelRef)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_LabelRef, wsLabelRef);
+}
+FX_BOOL CXFA_BindItems::SetValueRef(const CFX_WideString& wsValueRef)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_ValueRef, wsValueRef);
+}
+FX_BOOL CXFA_BindItems::SetRef(const CFX_WideString& wsRef)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Ref, wsRef);
+}
+FX_INT32 CXFA_Box::GetBreak() const
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Close;
+ }
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Break);
+}
+FX_INT32 CXFA_Box::GetHand() const
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Even;
+ }
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
+}
+FX_INT32 CXFA_Box::GetPresence() const
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Hidden;
+ }
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+}
+FX_INT32 CXFA_Box::CountCorners() const
+{
+ if (!m_pNode) {
+ return 0;
+ }
+ return m_pNode->CountChildren(XFA_ELEMENT_Corner);
+}
+CXFA_Corner CXFA_Box::GetCorner(FX_INT32 nIndex) const
+{
+ if (!m_pNode) {
+ return NULL;
+ }
+ return CXFA_Corner(m_pNode->GetProperty(nIndex, XFA_ELEMENT_Corner, nIndex == 0));
+}
+FX_INT32 CXFA_Box::CountEdges() const
+{
+ if (!m_pNode) {
+ return 0;
+ }
+ return m_pNode->CountChildren(XFA_ELEMENT_Edge);
+}
+CXFA_Edge CXFA_Box::GetEdge(FX_INT32 nIndex) const
+{
+ if (!m_pNode) {
+ return NULL;
+ }
+ return CXFA_Edge(m_pNode->GetProperty(nIndex, XFA_ELEMENT_Edge, nIndex == 0));
+}
+static void XFA_BOX_GetStrokes(CXFA_Node *pNode, CXFA_StrokeArray &strokes, FX_BOOL bNULL)
+{
+ strokes.RemoveAll();
+ if (!pNode) {
+ return;
+ }
+ strokes.SetSize(8);
+ FX_INT32 i, j;
+ for (i = 0, j = 0; i < 4; i ++) {
+ CXFA_Corner corner = CXFA_Corner(pNode->GetProperty(i, XFA_ELEMENT_Corner, i == 0));
+ if (corner.IsExistInXML() || i == 0) {
+ strokes.SetAt(j, corner);
+ } else if (bNULL) {
+ strokes.SetAt(j, NULL);
+ } else if (i == 1) {
+ strokes.SetAt(j, strokes[0]);
+ } else if (i == 2) {
+ strokes.SetAt(j, strokes[0]);
+ } else {
+ strokes.SetAt(j, strokes[2]);
+ }
+ j ++;
+ CXFA_Edge edge = CXFA_Edge(pNode->GetProperty(i, XFA_ELEMENT_Edge, i == 0));
+ if (edge.IsExistInXML() || i == 0) {
+ strokes.SetAt(j, edge);
+ } else if (bNULL) {
+ strokes.SetAt(j, NULL);
+ } else if (i == 1) {
+ strokes.SetAt(j, strokes[1]);
+ } else if (i == 2) {
+ strokes.SetAt(j, strokes[1]);
+ } else {
+ strokes.SetAt(j, strokes[3]);
+ }
+ j ++;
+ }
+}
+void CXFA_Box::GetStrokes(CXFA_StrokeArray &strokes) const
+{
+ XFA_BOX_GetStrokes(m_pNode, strokes, FALSE);
+}
+FX_BOOL CXFA_Box::IsCircular() const
+{
+ if (!m_pNode) {
+ return FALSE;
+ }
+ return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
+}
+FX_BOOL CXFA_Box::GetStartAngle(FX_FLOAT &fStartAngle) const
+{
+ fStartAngle = 0;
+ if (!m_pNode) {
+ return FALSE;
+ }
+ CXFA_Measurement ms;
+ FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, FALSE);
+ if (bRet) {
+ fStartAngle = ms.GetValue();
+ }
+ return bRet;
+}
+FX_BOOL CXFA_Box::GetSweepAngle(FX_FLOAT &fSweepAngle) const
+{
+ fSweepAngle = 360;
+ if (!m_pNode) {
+ return FALSE;
+ }
+ CXFA_Measurement ms;
+ FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, FALSE);
+ if (bRet) {
+ fSweepAngle = ms.GetValue();
+ }
+ return bRet;
+}
+CXFA_Fill CXFA_Box::GetFill(FX_BOOL bModified) const
+{
+ if (!m_pNode) {
+ return NULL;
+ }
+ CXFA_Node *pFillNode = m_pNode->GetProperty(0, XFA_ELEMENT_Fill, bModified);
+ return CXFA_Fill(pFillNode);
+}
+CXFA_Margin CXFA_Box::GetMargin() const
+{
+ if (!m_pNode) {
+ return NULL;
+ }
+ return CXFA_Margin(m_pNode->GetChild(0, XFA_ELEMENT_Margin));
+}
+static FX_BOOL XFA_BOX_SameStyles(const CXFA_StrokeArray &strokes)
+{
+ FX_INT32 iCount = strokes.GetSize();
+ if (iCount < 1) {
+ return TRUE;
+ }
+ CXFA_Stroke stroke1 = strokes[0];
+ for (FX_INT32 i = 1; i < iCount; i ++) {
+ CXFA_Stroke stroke2 = strokes[i];
+ if (!stroke2.IsExistInXML()) {
+ continue;
+ }
+ if (!stroke1.IsExistInXML()) {
+ stroke1 = stroke2;
+ } else if (!stroke1.SameStyles(stroke2)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_Box::SameStyles() const
+{
+ if (IsArc()) {
+ return TRUE;
+ }
+ CXFA_StrokeArray strokes;
+ XFA_BOX_GetStrokes(m_pNode, strokes, TRUE);
+ return XFA_BOX_SameStyles(strokes);
+}
+static FX_INT32 XFA_BOX_3DStyle(const CXFA_StrokeArray &strokes, CXFA_Stroke &stroke)
+{
+ FX_INT32 iCount = strokes.GetSize();
+ if (iCount < 1) {
+ return 0;
+ }
+ stroke = strokes[0];
+ for (FX_INT32 i = 1; i < iCount; i ++) {
+ CXFA_Stroke find = strokes[i];
+ if (!find.IsExistInXML()) {
+ continue;
+ }
+ if (!stroke.IsExistInXML()) {
+ stroke = find;
+ } else if (stroke.GetStrokeType() != find.GetStrokeType()) {
+ stroke = find;
+ break;
+ }
+ }
+ FX_INT32 iType = stroke.GetStrokeType();
+ if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
+ iType == XFA_ATTRIBUTEENUM_Etched || iType == XFA_ATTRIBUTEENUM_Embossed) {
+ return iType;
+ }
+ return 0;
+}
+FX_INT32 CXFA_Box::Get3DStyle(FX_BOOL &bVisible, FX_FLOAT &fThickness) const
+{
+ if (IsArc()) {
+ return 0;
+ }
+ CXFA_StrokeArray strokes;
+ XFA_BOX_GetStrokes(m_pNode, strokes, TRUE);
+ CXFA_Stroke stroke(NULL);
+ FX_INT32 iType = XFA_BOX_3DStyle(strokes, stroke);
+ if (iType) {
+ bVisible = stroke.IsVisible();
+ fThickness = stroke.GetThickness();
+ }
+ return iType;
+}
+FX_INT32 CXFA_Stroke::GetPresence() const
+{
+ return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Presence) : XFA_ATTRIBUTEENUM_Invisible;
+}
+FX_INT32 CXFA_Stroke::GetCapType() const
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Square;
+ }
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Cap);
+}
+FX_INT32 CXFA_Stroke::GetStrokeType() const
+{
+ return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Stroke) : XFA_ATTRIBUTEENUM_Solid;
+}
+FX_FLOAT CXFA_Stroke::GetThickness() const
+{
+ return GetMSThickness().ToUnit(XFA_UNIT_Pt);
+}
+CXFA_Measurement CXFA_Stroke::GetMSThickness() const
+{
+ return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Thickness) : XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT_Edge, XFA_ATTRIBUTE_Thickness, XFA_XDPPACKET_Form);
+}
+void CXFA_Stroke::SetThickness(FX_FLOAT fThickness)
+{
+ if (!m_pNode) {
+ return;
+ }
+ CXFA_Measurement thickness(fThickness, XFA_UNIT_Pt);
+ m_pNode->SetMeasure(XFA_ATTRIBUTE_Thickness, thickness);
+}
+void CXFA_Stroke::SetMSThickness(CXFA_Measurement msThinkness)
+{
+ if (!m_pNode) {
+ return;
+ }
+ m_pNode->SetMeasure(XFA_ATTRIBUTE_Thickness, msThinkness);
+}
+FX_ARGB CXFA_Stroke::GetColor() const
+{
+ if (!m_pNode) {
+ return 0xFF000000;
+ }
+ CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Color);
+ if (!pNode) {
+ return 0xFF000000;
+ }
+ CFX_WideStringC wsColor;
+ pNode->TryCData(XFA_ATTRIBUTE_Value, wsColor);
+ return XFA_WStringToColor(wsColor);
+}
+void CXFA_Stroke::SetColor(FX_ARGB argb)
+{
+ if (!m_pNode) {
+ return;
+ }
+ CXFA_Node* pNode = m_pNode->GetProperty(0, XFA_ELEMENT_Color);
+ CFX_WideString wsColor;
+ int a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ wsColor.Format((FX_LPCWSTR)L"%d,%d,%d", r, g, b);
+ pNode->SetCData(XFA_ATTRIBUTE_Value, wsColor);
+}
+FX_INT32 CXFA_Stroke::GetJoinType() const
+{
+ return m_pNode ? m_pNode->GetEnum(XFA_ATTRIBUTE_Join) : XFA_ATTRIBUTEENUM_Square;
+}
+FX_BOOL CXFA_Stroke::IsInverted() const
+{
+ return m_pNode ? m_pNode->GetBoolean(XFA_ATTRIBUTE_Inverted) : FALSE;
+}
+FX_FLOAT CXFA_Stroke::GetRadius() const
+{
+ return m_pNode ? m_pNode->GetMeasure(XFA_ATTRIBUTE_Radius).ToUnit(XFA_UNIT_Pt) : 0;
+}
+FX_BOOL CXFA_Stroke::SameStyles(CXFA_Stroke stroke, FX_DWORD dwFlags) const
+{
+ if (m_pNode == (CXFA_Node*)stroke) {
+ return TRUE;
+ }
+ if (FXSYS_fabs(GetThickness() - stroke.GetThickness()) >= 0.01f) {
+ return FALSE;
+ }
+ if ((dwFlags & XFA_STROKE_SAMESTYLE_NoPresence) == 0 && IsVisible() != stroke.IsVisible()) {
+ return FALSE;
+ }
+ if (GetStrokeType() != stroke.GetStrokeType()) {
+ return FALSE;
+ }
+ if (GetColor() != stroke.GetColor()) {
+ return FALSE;
+ }
+ if ((dwFlags & XFA_STROKE_SAMESTYLE_Corner) != 0 && FXSYS_fabs(GetRadius() - stroke.GetRadius()) >= 0.01f) {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_FLOAT XFA_GetEdgeThickness(const CXFA_StrokeArray &strokes, FX_BOOL b3DStyle, FX_INT32 nIndex)
+{
+ FX_FLOAT fThickness = 0;
+ {
+ if (strokes[nIndex * 2 + 1].GetPresence() == XFA_ATTRIBUTEENUM_Visible) {
+ if (nIndex == 0) {
+ fThickness += 2.5f;
+ }
+ fThickness += strokes[nIndex * 2 + 1].GetThickness() * (b3DStyle ? 4 : 2);
+ }
+ }
+ return fThickness;
+}
+CXFA_WidgetData::CXFA_WidgetData(CXFA_Node *pNode)
+ : CXFA_Data(pNode)
+ , m_bIsNull(TRUE)
+ , m_bPreNull(TRUE)
+ , m_pUiChildNode(NULL)
+ , m_eUIType(XFA_ELEMENT_UNKNOWN)
+{
+}
+CXFA_Node* CXFA_WidgetData::GetUIChild()
+{
+ if (m_eUIType == XFA_ELEMENT_UNKNOWN) {
+ m_pUiChildNode = XFA_CreateUIChild(m_pNode, m_eUIType);
+ }
+ return m_pUiChildNode;
+}
+XFA_ELEMENT CXFA_WidgetData::GetUIType()
+{
+ GetUIChild();
+ return m_eUIType;
+}
+CFX_WideString CXFA_WidgetData::GetRawValue()
+{
+ return m_pNode->GetContent();
+}
+FX_INT32 CXFA_WidgetData::GetAccess(FX_BOOL bTemplate)
+{
+ if (bTemplate) {
+ CXFA_Node* pNode = m_pNode->GetTemplateNode();
+ if (pNode) {
+ return pNode->GetEnum(XFA_ATTRIBUTE_Access);
+ }
+ return XFA_ATTRIBUTEENUM_Open;
+ }
+ CXFA_Node* pNode = m_pNode;
+ while (pNode) {
+ FX_INT32 iAcc = pNode->GetEnum(XFA_ATTRIBUTE_Access);
+ if (iAcc != XFA_ATTRIBUTEENUM_Open) {
+ return iAcc;
+ }
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_Parent, XFA_OBJECTTYPE_ContainerNode);
+ }
+ return XFA_ATTRIBUTEENUM_Open;
+}
+FX_BOOL CXFA_WidgetData::GetAccessKey(CFX_WideStringC &wsAccessKey)
+{
+ return m_pNode->TryCData(XFA_ATTRIBUTE_AccessKey, wsAccessKey);
+}
+FX_INT32 CXFA_WidgetData::GetAnchorType()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_AnchorType);
+}
+FX_INT32 CXFA_WidgetData::GetColSpan()
+{
+ return m_pNode->GetInteger(XFA_ATTRIBUTE_ColSpan);
+}
+FX_INT32 CXFA_WidgetData::GetPresence()
+{
+ return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+ CXFA_Node* pNode = m_pNode;
+ while (pNode && pNode->GetObjectType() == XFA_OBJECTTYPE_ContainerNode) {
+ FX_INT32 iAcc = pNode->GetEnum(XFA_ATTRIBUTE_Presence);
+ if ( iAcc != XFA_ATTRIBUTEENUM_Visible) {
+ return iAcc;
+ }
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ return XFA_ATTRIBUTEENUM_Visible;
+}
+FX_INT32 CXFA_WidgetData::GetRotate()
+{
+ CXFA_Measurement ms;
+ if (!m_pNode->TryMeasure(XFA_ATTRIBUTE_Rotate, ms, FALSE)) {
+ return 0;
+ }
+ FX_INT32 iRotate = FXSYS_round(ms.GetValue());
+ iRotate = (iRotate < 0 ? (iRotate % 360) + 360 : iRotate % 360);
+ return iRotate / 90 * 90;
+}
+CXFA_Border CXFA_WidgetData::GetBorder(FX_BOOL bModified)
+{
+ return CXFA_Border(m_pNode->GetProperty(0, XFA_ELEMENT_Border, bModified));
+}
+CXFA_Caption CXFA_WidgetData::GetCaption(FX_BOOL bModified )
+{
+ return CXFA_Caption(m_pNode->GetProperty(0, XFA_ELEMENT_Caption, bModified));
+}
+CXFA_Font CXFA_WidgetData::GetFont(FX_BOOL bModified )
+{
+ return CXFA_Font(m_pNode->GetProperty(0, XFA_ELEMENT_Font, bModified));
+}
+CXFA_Margin CXFA_WidgetData::GetMargin(FX_BOOL bModified )
+{
+ return CXFA_Margin(m_pNode->GetProperty(0, XFA_ELEMENT_Margin, bModified));
+}
+CXFA_Para CXFA_WidgetData::GetPara(FX_BOOL bModified )
+{
+ return CXFA_Para(m_pNode->GetProperty(0, XFA_ELEMENT_Para, bModified));
+}
+CXFA_Keep CXFA_WidgetData::GetKeep(FX_BOOL bModified )
+{
+ return CXFA_Keep(m_pNode->GetProperty(0, XFA_ELEMENT_Keep, bModified), m_pNode);
+}
+void CXFA_WidgetData::GetEventList(CXFA_NodeArray &events)
+{
+ m_pNode->GetNodeList(events, 0, XFA_ELEMENT_Event);
+}
+FX_INT32 CXFA_WidgetData::GetEventByActivity(FX_INT32 iActivity, CXFA_NodeArray &events, FX_BOOL bIsFormReady)
+{
+ CXFA_NodeArray allEvents;
+ GetEventList(allEvents);
+ FX_INT32 iCount = allEvents.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CXFA_Event event(allEvents[i]);
+ if (event.GetActivity() == iActivity) {
+ if (iActivity == XFA_ATTRIBUTEENUM_Ready) {
+ CFX_WideStringC wsRef;
+ event.GetRef(wsRef);
+ if (bIsFormReady) {
+ if (wsRef == CFX_WideStringC(L"$form")) {
+ events.Add(allEvents[i]);
+ }
+ } else {
+ if (wsRef == CFX_WideStringC(L"$layout")) {
+ events.Add(allEvents[i]);
+ }
+ }
+ } else {
+ events.Add(allEvents[i]);
+ }
+ }
+ }
+ return events.GetSize();
+}
+CXFA_Value CXFA_WidgetData::GetDefaultValue(FX_BOOL bModified )
+{
+ CXFA_Node* pTemNode = m_pNode->GetTemplateNode();
+ return pTemNode ? pTemNode->GetProperty(0, XFA_ELEMENT_Value, bModified) : NULL;
+}
+CXFA_Value CXFA_WidgetData::GetFormValue(FX_BOOL bModified )
+{
+ return m_pNode->GetProperty(0, XFA_ELEMENT_Value, bModified);
+}
+CXFA_Calculate CXFA_WidgetData::GetCalculate(FX_BOOL bModified )
+{
+ return m_pNode->GetProperty(0, XFA_ELEMENT_Calculate, bModified);
+}
+CXFA_Validate CXFA_WidgetData::GetValidate(FX_BOOL bModified)
+{
+ return m_pNode->GetProperty(0, XFA_ELEMENT_Validate, bModified);
+}
+CXFA_Variables CXFA_WidgetData::GetVariables(FX_BOOL bModified )
+{
+ return m_pNode->GetProperty(0, XFA_ELEMENT_Variables, bModified);
+}
+CXFA_Bind CXFA_WidgetData::GetBind(FX_BOOL bModified )
+{
+ return m_pNode->GetProperty(0, XFA_ELEMENT_Bind, bModified);
+}
+CXFA_Assist CXFA_WidgetData::GetAssist(FX_BOOL bModified )
+{
+ return m_pNode->GetProperty(0, XFA_ELEMENT_Assist, bModified);
+}
+void CXFA_WidgetData::GetRelevant(CFX_WideStringC &wsRelevant)
+{
+ m_pNode->TryCData(XFA_ATTRIBUTE_Relevant, wsRelevant);
+}
+FX_BOOL CXFA_WidgetData::GetWidth(FX_FLOAT &fWidth)
+{
+ return TryMeasure(XFA_ATTRIBUTE_W, fWidth);
+}
+FX_BOOL CXFA_WidgetData::GetHeight(FX_FLOAT &fHeight)
+{
+ return TryMeasure(XFA_ATTRIBUTE_H, fHeight);
+}
+FX_BOOL CXFA_WidgetData::GetMinWidth(FX_FLOAT &fMinWidth)
+{
+ return TryMeasure(XFA_ATTRIBUTE_MinW, fMinWidth);
+}
+FX_BOOL CXFA_WidgetData::GetMinHeight(FX_FLOAT &fMinHeight)
+{
+ return TryMeasure(XFA_ATTRIBUTE_MinH, fMinHeight);
+}
+FX_BOOL CXFA_WidgetData::GetMaxWidth(FX_FLOAT &fMaxWidth)
+{
+ return TryMeasure(XFA_ATTRIBUTE_MaxW, fMaxWidth);
+}
+FX_BOOL CXFA_WidgetData::GetMaxHeight(FX_FLOAT &fMaxHeight)
+{
+ return TryMeasure(XFA_ATTRIBUTE_MaxH, fMaxHeight);
+}
+CXFA_BindItems CXFA_WidgetData::GetBindItems()
+{
+ return m_pNode->GetChild(0, XFA_ELEMENT_BindItems);
+}
+FX_BOOL CXFA_WidgetData::SetAccess(FX_INT32 iAccess, FX_BOOL bNotify)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Access, (XFA_ATTRIBUTEENUM)iAccess, bNotify);
+}
+FX_BOOL CXFA_WidgetData::SetAccessKey(const CFX_WideString& wsAccessKey)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_AccessKey, wsAccessKey);
+}
+FX_BOOL CXFA_WidgetData::SetAnchorType(FX_INT32 iType)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_AnchorType, (XFA_ATTRIBUTEENUM)iType);
+}
+FX_BOOL CXFA_WidgetData::SetColSpan(FX_INT32 iColSpan)
+{
+ return m_pNode->SetInteger(XFA_ATTRIBUTE_ColSpan, (XFA_ATTRIBUTEENUM)iColSpan);
+}
+FX_BOOL CXFA_WidgetData::SetPresence(FX_INT32 iPresence)
+{
+ return m_pNode->SetEnum(XFA_ATTRIBUTE_Presence, (XFA_ATTRIBUTEENUM)iPresence);
+}
+FX_BOOL CXFA_WidgetData::SetRotate(FX_INT32 iRotate)
+{
+ while (iRotate < 0) {
+ iRotate += 360;
+ }
+ while (iRotate >= 360) {
+ iRotate -= 360;
+ }
+ CXFA_Measurement ms((FX_FLOAT)iRotate, XFA_UNIT_Angle);
+ return m_pNode->SetMeasure(XFA_ATTRIBUTE_Rotate, ms);
+}
+FX_BOOL CXFA_WidgetData::SetRelevant(const CFX_WideString& wsRelevant)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Relevant, wsRelevant);
+}
+FX_BOOL CXFA_WidgetData::SetStatus(FX_DWORD dwStatus)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::SetWidth(FX_FLOAT fWidth)
+{
+ return SetMeasure(XFA_ATTRIBUTE_W, fWidth);
+}
+FX_BOOL CXFA_WidgetData::SetHeight(FX_FLOAT fHeight)
+{
+ return SetMeasure(XFA_ATTRIBUTE_H, fHeight);
+}
+FX_BOOL CXFA_WidgetData::SetMinWidth(FX_FLOAT fMinWidth)
+{
+ return SetMeasure(XFA_ATTRIBUTE_MinW, fMinWidth);
+}
+FX_BOOL CXFA_WidgetData::SetMinHeight(FX_FLOAT fMinHeight)
+{
+ return SetMeasure(XFA_ATTRIBUTE_MinH, fMinHeight);
+}
+FX_BOOL CXFA_WidgetData::SetMaxWidth(FX_FLOAT fMaxWidth)
+{
+ return SetMeasure(XFA_ATTRIBUTE_MaxW, fMaxWidth);
+}
+FX_BOOL CXFA_WidgetData::SetMaxHeight(FX_FLOAT fMaxHeight)
+{
+ return SetMeasure(XFA_ATTRIBUTE_MaxH, fMaxHeight);
+}
+FX_BOOL CXFA_WidgetData::SetPos(FX_FLOAT x, FX_FLOAT y)
+{
+ return SetMeasure(XFA_ATTRIBUTE_X, x) && SetMeasure(XFA_ATTRIBUTE_Y, y);
+}
+FX_BOOL CXFA_WidgetData::SetName(const CFX_WideString& wsName)
+{
+ return m_pNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+}
+FX_BOOL CXFA_WidgetData::SetButtonHighlight(FX_INT32 iButtonHighlight)
+{
+ CXFA_Node* pUiChildNode = GetUIChild();
+ return pUiChildNode->SetEnum(XFA_ATTRIBUTE_Highlight, (XFA_ATTRIBUTEENUM)iButtonHighlight);
+}
+FX_BOOL CXFA_WidgetData::SetButtonRollover(const CFX_WideString &wsRollover, FX_BOOL bRichText)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::SetButtonDown(const CFX_WideString& wsDown, FX_BOOL bRichText)
+{
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::SetCheckButtonShape(FX_INT32 iCheckButtonShape)
+{
+ CXFA_Node* pUiChildNode = GetUIChild();
+ return pUiChildNode->SetEnum(XFA_ATTRIBUTE_Shape, (XFA_ATTRIBUTEENUM)iCheckButtonShape);
+}
+FX_BOOL CXFA_WidgetData::SetCheckButtonMark(FX_INT32 iCheckButtonMark)
+{
+ CXFA_Node* pUiChildNode = GetUIChild();
+ return pUiChildNode->SetEnum(XFA_ATTRIBUTE_Mark, (XFA_ATTRIBUTEENUM)iCheckButtonMark);
+}
+FX_BOOL CXFA_WidgetData::SetCheckButtonSize(FX_FLOAT fCheckButtonMark)
+{
+ CXFA_Node* pUiChildNode = GetUIChild();
+ if (pUiChildNode) {
+ CXFA_Measurement ms(fCheckButtonMark, XFA_UNIT_Pt);
+ return pUiChildNode->SetMeasure(XFA_ATTRIBUTE_Size, ms);
+ }
+ return FALSE;
+}
+CXFA_Border CXFA_WidgetData::GetUIBorder(FX_BOOL bModified )
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Border, bModified) : NULL;
+}
+CXFA_Margin CXFA_WidgetData::GetUIMargin(FX_BOOL bModified )
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild ? pUIChild->GetProperty(0, XFA_ELEMENT_Margin, bModified) : NULL;
+}
+void CXFA_WidgetData::GetUIMargin(CFX_RectF &rtUIMargin)
+{
+ rtUIMargin.Reset();
+ CXFA_Margin mgUI = GetUIMargin();
+ if (!mgUI) {
+ return;
+ }
+ CXFA_Border border = GetUIBorder();
+ if (border && border.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
+ return;
+ }
+ FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
+ FX_BOOL bLeft = mgUI.GetLeftInset(fLeftInset);
+ FX_BOOL bTop = mgUI.GetTopInset(fTopInset);
+ FX_BOOL bRight = mgUI.GetRightInset(fRightInset);
+ FX_BOOL bBottom = mgUI.GetBottomInset(fBottomInset);
+ if (border) {
+ FX_BOOL bVisible = FALSE;
+ FX_FLOAT fThickness = 0;
+ border.Get3DStyle(bVisible, fThickness);
+ if (!bLeft || !bTop || !bRight || !bBottom) {
+ CXFA_StrokeArray strokes;
+ border.GetStrokes(strokes);
+ if (!bTop) {
+ fTopInset = XFA_GetEdgeThickness(strokes, bVisible, 0);
+ }
+ if (!bRight) {
+ fRightInset = XFA_GetEdgeThickness(strokes, bVisible, 1);
+ }
+ if (!bBottom) {
+ fBottomInset = XFA_GetEdgeThickness(strokes, bVisible, 2);
+ }
+ if (!bLeft) {
+ fLeftInset = XFA_GetEdgeThickness(strokes, bVisible, 3);
+ }
+ }
+ }
+ rtUIMargin.Set(fLeftInset, fTopInset, fRightInset, fBottomInset);
+}
+FX_INT32 CXFA_WidgetData::GetButtonHighlight()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetEnum(XFA_ATTRIBUTE_Highlight);
+ }
+ return XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT_Button, XFA_ATTRIBUTE_Highlight, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::GetButtonRollover(CFX_WideString &wsRollover, FX_BOOL &bRichText)
+{
+ if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pText) {
+ CFX_WideStringC wsName;
+ pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
+ if (wsName == FX_WSTRC(L"rollover")) {
+ pText->TryContent(wsRollover);
+ bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
+ return !wsRollover.IsEmpty();
+ }
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetButtonDown(CFX_WideString &wsDown, FX_BOOL &bRichText)
+{
+ if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while(pText) {
+ CFX_WideStringC wsName;
+ pText->TryCData(XFA_ATTRIBUTE_Name, wsName);
+ if (wsName == FX_WSTRC(L"down")) {
+ pText->TryContent(wsDown);
+ bRichText = pText->GetClassID() == XFA_ELEMENT_ExData;
+ return !wsDown.IsEmpty();
+ }
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ }
+ return FALSE;
+}
+FX_INT32 CXFA_WidgetData::GetCheckButtonShape()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetEnum(XFA_ATTRIBUTE_Shape);
+ }
+ return XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Shape, XFA_XDPPACKET_Form);
+}
+FX_INT32 CXFA_WidgetData::GetCheckButtonMark()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetEnum(XFA_ATTRIBUTE_Mark);
+ }
+ return XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Mark, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::IsRadioButton()
+{
+ if (CXFA_Node* pParent = m_pNode->GetNodeItem(XFA_NODEITEM_Parent)) {
+ return pParent->GetClassID() == XFA_ELEMENT_ExclGroup;
+ }
+ return FALSE;
+}
+FX_FLOAT CXFA_WidgetData::GetCheckButtonSize()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetMeasure(XFA_ATTRIBUTE_Size).ToUnit(XFA_UNIT_Pt);
+ }
+ return XFA_GetAttributeDefaultValue_Measure(XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_Size, XFA_XDPPACKET_Form).ToUnit(XFA_UNIT_Pt);
+}
+FX_BOOL CXFA_WidgetData::IsAllowNeutral()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetBoolean(XFA_ATTRIBUTE_AllowNeutral);
+ }
+ return XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT_CheckButton, XFA_ATTRIBUTE_AllowNeutral, XFA_XDPPACKET_Form);
+}
+XFA_CHECKSTATE CXFA_WidgetData::GetCheckState()
+{
+ CFX_WideString wsValue = GetRawValue();
+ if (wsValue.IsEmpty()) {
+ return XFA_CHECKSTATE_Off;
+ }
+ if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ FX_INT32 i = 0;
+ while(pText) {
+ CFX_WideString wsContent;
+ if (pText->TryContent(wsContent) && (wsContent == wsValue)) {
+ return (XFA_CHECKSTATE)i;
+ }
+ i++;
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ }
+ return XFA_CHECKSTATE_Off;
+}
+void CXFA_WidgetData::SetCheckState(XFA_CHECKSTATE eCheckState, FX_BOOL bNotify)
+{
+ if (CXFA_WidgetData exclGroup = GetExclGroupNode()) {
+ CFX_WideString wsValue;
+ if (eCheckState != XFA_CHECKSTATE_Off) {
+ if (CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items)) {
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pText) {
+ pText->TryContent(wsValue);
+ }
+ }
+ }
+ CXFA_Node* pChild = ((CXFA_Node*)exclGroup)->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pChild->GetClassID() != XFA_ELEMENT_Field) {
+ continue;
+ }
+ CXFA_Node* pItem = pChild->GetChild(0, XFA_ELEMENT_Items);
+ if (!pItem) {
+ continue;
+ }
+ CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pItemchild) {
+ continue;
+ }
+ CFX_WideString text = pItemchild->GetContent();
+ CFX_WideString wsChildValue = text;
+ if (wsValue != text) {
+ pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ if (pItemchild) {
+ wsChildValue = pItemchild->GetContent();
+ } else {
+ wsChildValue.Empty();
+ }
+ }
+ CXFA_WidgetData ch(pChild);
+ ch.SyncValue(wsChildValue, bNotify);
+ }
+ exclGroup.SyncValue(wsValue, bNotify);
+ } else {
+ CXFA_Node* pItems = m_pNode->GetChild(0, XFA_ELEMENT_Items);
+ if (!pItems) {
+ return;
+ }
+ FX_INT32 i = -1;
+ CXFA_Node* pText = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ CFX_WideString wsContent;
+ while (pText) {
+ i++;
+ if (i == eCheckState) {
+ pText->TryContent(wsContent);
+ break;
+ }
+ pText = pText->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ SyncValue(wsContent, bNotify);
+ }
+}
+CXFA_Node* CXFA_WidgetData::GetExclGroupNode()
+{
+ CXFA_Node* pExcl = (CXFA_Node*)m_pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if (!pExcl || pExcl->GetClassID() != XFA_ELEMENT_ExclGroup) {
+ return NULL;
+ }
+ return pExcl;
+}
+CXFA_Node* CXFA_WidgetData::GetSelectedMember()
+{
+ CXFA_Node *pSelectedMember = NULL;
+ CFX_WideString wsState = GetRawValue();
+ if (wsState.IsEmpty()) {
+ return pSelectedMember;
+ }
+ for (CXFA_Node *pNode = (CXFA_Node*)m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode != NULL; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ CXFA_WidgetData widgetData(pNode);
+ if (widgetData.GetCheckState() == XFA_CHECKSTATE_On) {
+ pSelectedMember = pNode;
+ break;
+ }
+ }
+ return pSelectedMember;
+}
+CXFA_Node* CXFA_WidgetData::SetSelectedMember(FX_WSTR wsName, FX_BOOL bNotify)
+{
+ CXFA_Node *pSelectedMember = NULL;
+ FX_DWORD nameHash = FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength());
+ for (CXFA_Node *pNode = (CXFA_Node*)m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode != NULL; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetNameHash() == nameHash) {
+ CXFA_WidgetData widgetData(pNode);
+ widgetData.SetCheckState(XFA_CHECKSTATE_On, bNotify);
+ pSelectedMember = pNode;
+ break;
+ }
+ }
+ return pSelectedMember;
+}
+void CXFA_WidgetData::SetSelectedMemberByValue(FX_WSTR wsValue, FX_BOOL bNotify, FX_BOOL bScriptModify, FX_BOOL bSyncData)
+{
+ CFX_WideString wsExclGroup;
+ for (CXFA_Node *pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild); pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetClassID() != XFA_ELEMENT_Field) {
+ continue;
+ }
+ CXFA_Node* pItem = pNode->GetChild(0, XFA_ELEMENT_Items);
+ if (!pItem) {
+ continue;
+ }
+ CXFA_Node* pItemchild = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pItemchild) {
+ continue;
+ }
+ CFX_WideString wsChildValue = pItemchild->GetContent();
+ if (wsValue != wsChildValue) {
+ pItemchild = pItemchild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ if (pItemchild) {
+ wsChildValue = pItemchild->GetContent();
+ } else {
+ wsChildValue.Empty();
+ }
+ } else {
+ wsExclGroup = wsValue;
+ }
+ pNode->SetContent(wsChildValue, wsChildValue, bNotify, bScriptModify, FALSE);
+ }
+ if (m_pNode) {
+ m_pNode->SetContent(wsExclGroup, wsExclGroup, bNotify, bScriptModify, bSyncData);
+ }
+}
+CXFA_Node* CXFA_WidgetData::GetExclGroupFirstMember()
+{
+ CXFA_Node* pExcl = GetNode();
+ if (!pExcl) {
+ return NULL;
+ }
+ CXFA_Node* pNode = pExcl->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pNode) {
+ if (pNode->GetClassID() == XFA_ELEMENT_Field) {
+ return pNode;
+ }
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_WidgetData::GetExclGroupNextMember(CXFA_Node* pNode)
+{
+ if (!pNode) {
+ return NULL;
+ }
+ CXFA_Node* pNodeField = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ while (pNodeField) {
+ if (pNodeField->GetClassID() == XFA_ELEMENT_Field) {
+ return pNodeField;
+ }
+ pNodeField = pNodeField->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ return NULL;
+}
+FX_INT32 CXFA_WidgetData::GetChoiceListCommitOn()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetEnum(XFA_ATTRIBUTE_CommitOn);
+ }
+ return XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_CommitOn, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::IsChoiceListAllowTextEntry()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetBoolean(XFA_ATTRIBUTE_TextEntry);
+ }
+ return XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_TextEntry, XFA_XDPPACKET_Form);
+}
+FX_INT32 CXFA_WidgetData::GetChoiceListOpen()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetEnum(XFA_ATTRIBUTE_Open);
+ }
+ return XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT_ChoiceList, XFA_ATTRIBUTE_Open, XFA_XDPPACKET_Form);
+}
+FX_BOOL CXFA_WidgetData::IsListBox()
+{
+ FX_INT32 iOpenMode = GetChoiceListOpen();
+ return (iOpenMode == XFA_ATTRIBUTEENUM_Always || iOpenMode == XFA_ATTRIBUTEENUM_MultiSelect);
+}
+FX_INT32 CXFA_WidgetData::CountChoiceListItems(FX_BOOL bSaveValue)
+{
+ CXFA_NodeArray pItems;
+ CXFA_Node* pItem = NULL;
+ FX_INT32 iCount = 0;
+ CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetClassID() != XFA_ELEMENT_Items) {
+ continue;
+ }
+ iCount++;
+ pItems.Add(pNode);
+ if (iCount == 2) {
+ break;
+ }
+ }
+ if(iCount == 0) {
+ return 0;
+ }
+ pItem = pItems[0];
+ if (iCount > 1) {
+ FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
+ FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
+ pItem = pItems[1];
+ }
+ }
+ pItems.RemoveAll();
+ return pItem->CountChildren(XFA_ELEMENT_UNKNOWN);
+}
+FX_BOOL CXFA_WidgetData::GetChoiceListItem(CFX_WideString &wsText, FX_INT32 nIndex, FX_BOOL bSaveValue )
+{
+ wsText.Empty();
+ CXFA_NodeArray pItemsArray;
+ CXFA_Node* pItems = NULL;
+ FX_INT32 iCount = 0;
+ CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetClassID() != XFA_ELEMENT_Items) {
+ continue;
+ }
+ iCount++;
+ pItemsArray.Add(pNode);
+ if (iCount == 2) {
+ break;
+ }
+ }
+ if (iCount == 0) {
+ return FALSE;
+ }
+ pItems = pItemsArray[0];
+ if (iCount > 1) {
+ FX_BOOL bItemOneHasSave = pItemsArray[0]->GetBoolean(XFA_ATTRIBUTE_Save);
+ FX_BOOL bItemTwoHasSave = pItemsArray[1]->GetBoolean(XFA_ATTRIBUTE_Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
+ pItems = pItemsArray[1];
+ }
+ }
+ if (pItems) {
+ CXFA_Node *pItem = pItems->GetChild(nIndex, XFA_ELEMENT_UNKNOWN);
+ if(pItem != NULL) {
+ pItem->TryContent(wsText);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CXFA_WidgetData::GetChoiceListItems(CFX_WideStringArray &wsTextArray, FX_BOOL bSaveValue )
+{
+ CXFA_NodeArray pItems;
+ CXFA_Node* pItem = NULL;
+ FX_INT32 iCount = 0;
+ CXFA_Node* pNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pNode->GetClassID() != XFA_ELEMENT_Items) {
+ continue;
+ }
+ iCount++;
+ pItems.Add(pNode);
+ if (iCount == 2) {
+ break;
+ }
+ }
+ if(iCount == 0) {
+ return;
+ }
+ pItem = pItems[0];
+ if (iCount > 1) {
+ FX_BOOL bItemOneHasSave = pItems[0]->GetBoolean(XFA_ATTRIBUTE_Save);
+ FX_BOOL bItemTwoHasSave = pItems[1]->GetBoolean(XFA_ATTRIBUTE_Save);
+ if (bItemOneHasSave != bItemTwoHasSave && bSaveValue == bItemTwoHasSave) {
+ pItem = pItems[1];
+ }
+ }
+ pItems.RemoveAll();
+ pNode = pItem->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pNode; pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ pNode->TryContent(wsTextArray.Add());
+ }
+}
+FX_INT32 CXFA_WidgetData::CountSelectedItems()
+{
+ CFX_WideStringArray wsValueArray;
+ GetSelectedItemsValue(wsValueArray);
+ if (IsListBox() || !IsChoiceListAllowTextEntry()) {
+ return wsValueArray.GetSize();
+ }
+ FX_INT32 iSelected = 0;
+ CFX_WideStringArray wsSaveTextArray;
+ GetChoiceListItems(wsSaveTextArray, TRUE);
+ FX_INT32 iValues = wsValueArray.GetSize();
+ for (FX_INT32 i = 0; i < iValues; i++) {
+ FX_INT32 iSaves = wsSaveTextArray.GetSize();
+ for (FX_INT32 j = 0; j < iSaves; j++) {
+ if (wsValueArray[i] == wsSaveTextArray[j]) {
+ iSelected++;
+ break;
+ }
+ }
+ }
+ return iSelected;
+}
+FX_INT32 CXFA_WidgetData::GetSelectedItem(FX_INT32 nIndex )
+{
+ CFX_WideStringArray wsValueArray;
+ GetSelectedItemsValue(wsValueArray);
+ FX_INT32 iSelected = 0;
+ CFX_WideStringArray wsSaveTextArray;
+ GetChoiceListItems(wsSaveTextArray, TRUE);
+ FX_INT32 iSaves = wsSaveTextArray.GetSize();
+ for (FX_INT32 j = 0; j < iSaves; j++) {
+ if (wsValueArray[nIndex] == wsSaveTextArray[j]) {
+ return j;
+ }
+ }
+ return -1;
+}
+void CXFA_WidgetData::GetSelectedItems(CFX_Int32Array &iSelArray)
+{
+ CFX_WideStringArray wsValueArray;
+ GetSelectedItemsValue(wsValueArray);
+ FX_INT32 iValues = wsValueArray.GetSize();
+ if (iValues < 1) {
+ return;
+ }
+ CFX_WideStringArray wsSaveTextArray;
+ GetChoiceListItems(wsSaveTextArray, TRUE);
+ FX_INT32 iSaves = wsSaveTextArray.GetSize();
+ for (FX_INT32 i = 0; i < iValues; i++) {
+ for (FX_INT32 j = 0; j < iSaves; j++) {
+ if (wsValueArray[i] == wsSaveTextArray[j]) {
+ iSelArray.Add(j);
+ break;
+ }
+ }
+ }
+}
+void CXFA_WidgetData::GetSelectedItemsValue(CFX_WideStringArray &wsSelTextArray)
+{
+ CFX_WideString wsValue = GetRawValue();
+ if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+ if (!wsValue.IsEmpty()) {
+ FX_INT32 iStart = 0;
+ FX_INT32 iLength = wsValue.GetLength();
+ FX_INT32 iEnd = wsValue.Find(L'\n', iStart);
+ iEnd = (iEnd == -1) ? iLength : iEnd;
+ while (iEnd >= iStart) {
+ wsSelTextArray.Add(wsValue.Mid(iStart, iEnd - iStart));
+ iStart = iEnd + 1;
+ if (iStart >= iLength) {
+ break;
+ }
+ iEnd = wsValue.Find(L'\n', iStart);
+ if (iEnd < 0) {
+ wsSelTextArray.Add(wsValue.Mid(iStart, iLength - iStart));
+ }
+ }
+ }
+ } else {
+ wsSelTextArray.Add(wsValue);
+ }
+}
+FX_BOOL CXFA_WidgetData::GetItemState(FX_INT32 nIndex)
+{
+ if (nIndex < 0) {
+ return FALSE;
+ }
+ CFX_WideStringArray wsSaveTextArray;
+ GetChoiceListItems(wsSaveTextArray, TRUE);
+ if (wsSaveTextArray.GetSize() <= nIndex) {
+ return FALSE;
+ }
+ CFX_WideStringArray wsValueArray;
+ GetSelectedItemsValue(wsValueArray);
+ FX_INT32 iValues = wsValueArray.GetSize();
+ for (FX_INT32 j = 0; j < iValues; j++) {
+ if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CXFA_WidgetData::SetItemState(FX_INT32 nIndex, FX_BOOL bSelected, FX_BOOL bNotify, FX_BOOL bScriptModify, FX_BOOL bSyncData)
+{
+ if (nIndex < 0) {
+ return;
+ }
+ CFX_WideStringArray wsSaveTextArray;
+ GetChoiceListItems(wsSaveTextArray, TRUE);
+ if (wsSaveTextArray.GetSize() <= nIndex) {
+ return;
+ }
+ FX_INT32 iSel = -1;
+ CFX_WideStringArray wsValueArray;
+ GetSelectedItemsValue(wsValueArray);
+ FX_INT32 iValues = wsValueArray.GetSize();
+ for (FX_INT32 j = 0; j < iValues; j++) {
+ if (wsValueArray[j] == wsSaveTextArray[nIndex]) {
+ iSel = j;
+ break;
+ }
+ }
+ if (GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+ if (bSelected) {
+ if (iSel < 0) {
+ CFX_WideString wsValue = GetRawValue();
+ if (!wsValue.IsEmpty()) {
+ wsValue += L"\n";
+ }
+ wsValue += wsSaveTextArray[nIndex];
+ m_pNode->SetContent(wsValue, wsValue, bNotify, bScriptModify, bSyncData);
+ }
+ } else if (iSel >= 0) {
+ CFX_Int32Array iSelArray;
+ GetSelectedItems(iSelArray);
+ for (FX_INT32 i = 0; i < iSelArray.GetSize(); i++) {
+ if (iSelArray[i] == nIndex) {
+ iSelArray.RemoveAt(i);
+ break;
+ }
+ }
+ SetSelectdItems(iSelArray, bNotify, bScriptModify, bSyncData);
+ }
+ } else {
+ if (bSelected) {
+ if (iSel < 0) {
+ CFX_WideString wsSaveText = wsSaveTextArray[nIndex];
+ CFX_WideString wsFormatText(wsSaveText);
+ GetFormatDataValue(wsSaveText, wsFormatText);
+ m_pNode->SetContent(wsSaveText, wsFormatText, bNotify, bScriptModify, bSyncData);
+ }
+ } else if (iSel >= 0) {
+ m_pNode->SetContent(CFX_WideString(), CFX_WideString(), bNotify, bScriptModify, bSyncData);
+ }
+ }
+}
+void CXFA_WidgetData::SetSelectdItems(CFX_Int32Array &iSelArray, FX_BOOL bNotify, FX_BOOL bScriptModify, FX_BOOL bSyncData)
+{
+ CFX_WideString wsValue;
+ FX_INT32 iSize = iSelArray.GetSize();
+ if (iSize >= 1) {
+ CFX_WideStringArray wsSaveTextArray;
+ GetChoiceListItems(wsSaveTextArray, TRUE);
+ CFX_WideString wsItemValue;
+ for (FX_INT32 i = 0; i < iSize; i++) {
+ wsItemValue = (iSize == 1) ? wsSaveTextArray[iSelArray[i]] : wsSaveTextArray[iSelArray[i]] + FX_WSTRC(L"\n");
+ wsValue += wsItemValue;
+ }
+ }
+ CFX_WideString wsFormat(wsValue);
+ if (GetChoiceListOpen() != XFA_ATTRIBUTEENUM_MultiSelect) {
+ GetFormatDataValue(wsValue, wsFormat);
+ }
+ m_pNode->SetContent(wsValue, wsFormat, bNotify, bScriptModify, bSyncData);
+}
+void CXFA_WidgetData::ClearAllSelections()
+{
+ CXFA_Node* pBind = m_pNode->GetBindData();
+ if (pBind && GetChoiceListOpen() == XFA_ATTRIBUTEENUM_MultiSelect) {
+ while (CXFA_Node* pChildNode = pBind->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ pBind->RemoveChild(pChildNode);
+ }
+ } else {
+ SyncValue(CFX_WideString(), FALSE);
+ }
+}
+void CXFA_WidgetData::InsertItem(const CFX_WideString &wsLabel, const CFX_WideString &wsValue, FX_INT32 nIndex , FX_BOOL bNotify )
+{
+ CFX_WideString wsNewValue(wsValue);
+ if (wsNewValue.IsEmpty()) {
+ wsNewValue = wsLabel;
+ }
+ CXFA_NodeArray listitems;
+ FX_INT32 iCount = 0;
+ CXFA_Node *pItemNode = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItemNode; pItemNode = pItemNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItemNode->GetClassID() != XFA_ELEMENT_Items) {
+ continue;
+ }
+ listitems.Add(pItemNode);
+ iCount ++;
+ }
+ if (iCount < 1) {
+ CXFA_Node* pItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
+ m_pNode->InsertChild(-1, pItems);
+ InsertListTextItem(pItems, wsLabel, nIndex);
+ CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
+ m_pNode->InsertChild(-1, pSaveItems);
+ pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
+ InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+ } else if (iCount > 1) {
+ for (FX_INT32 i = 0; i < 2; i++) {
+ CXFA_Node* pNode = listitems[i];
+ FX_BOOL bHasSave = pNode->GetBoolean(XFA_ATTRIBUTE_Save);
+ if (bHasSave) {
+ InsertListTextItem(pNode, wsNewValue, nIndex);
+ } else {
+ InsertListTextItem(pNode, wsLabel, nIndex);
+ }
+ }
+ } else {
+ CXFA_Node* pNode = listitems[0];
+ pNode->SetBoolean(XFA_ATTRIBUTE_Save, FALSE);
+ pNode->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Visible);
+ CXFA_Node* pSaveItems = m_pNode->CreateSamePacketNode(XFA_ELEMENT_Items);
+ m_pNode->InsertChild(-1, pSaveItems);
+ pSaveItems->SetBoolean(XFA_ATTRIBUTE_Save, TRUE);
+ pSaveItems->SetEnum(XFA_ATTRIBUTE_Presence, XFA_ATTRIBUTEENUM_Hidden);
+ listitems.RemoveAll();
+ CXFA_Node *pListNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ FX_INT32 i = 0;
+ while(pListNode) {
+ CFX_WideString wsOldValue;
+ pListNode->TryContent(wsOldValue);
+ InsertListTextItem(pSaveItems, wsOldValue, i);
+ i++;
+ pListNode = pListNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ InsertListTextItem(pNode, wsLabel, nIndex);
+ InsertListTextItem(pSaveItems, wsNewValue, nIndex);
+ }
+ if(!bNotify) {
+ return;
+ }
+ m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(this, XFA_WIDGETEVENT_ListItemAdded, (FX_LPVOID)(FX_LPCWSTR)wsLabel, (FX_LPVOID)(FX_LPCWSTR)wsValue, (FX_LPVOID)(FX_UINTPTR)nIndex);
+}
+void CXFA_WidgetData::GetItemLabel(FX_WSTR wsValue, CFX_WideString &wsLabel)
+{
+ FX_INT32 iCount = 0;
+ CXFA_NodeArray listitems;
+ CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItems->GetClassID() != XFA_ELEMENT_Items) {
+ continue;
+ }
+ iCount++;
+ listitems.Add(pItems);
+ }
+ if (iCount <= 1) {
+ wsLabel = wsValue;
+ } else {
+ CXFA_Node* pLabelItems = listitems[0];
+ FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
+ CXFA_Node* pSaveItems = NULL;
+ if (bSave) {
+ pSaveItems = pLabelItems;
+ pLabelItems = listitems[1];
+ } else {
+ pSaveItems = listitems[1];
+ }
+ iCount = 0;
+ FX_INT32 iSearch = -1;
+ CFX_WideString wsContent;
+ CXFA_Node* pChildItem = pSaveItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pChildItem; pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ pChildItem->TryContent(wsContent);
+ if (wsContent == wsValue) {
+ iSearch = iCount;
+ break;
+ }
+ iCount ++;
+ }
+ if (iSearch < 0) {
+ return;
+ }
+ if (CXFA_Node* pText = pLabelItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
+ pText->TryContent(wsLabel);
+ }
+ }
+}
+void CXFA_WidgetData::GetItemValue(FX_WSTR wsLabel, CFX_WideString &wsValue)
+{
+ FX_INT32 iCount = 0;
+ CXFA_NodeArray listitems;
+ CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItems->GetClassID() != XFA_ELEMENT_Items) {
+ continue;
+ }
+ iCount++;
+ listitems.Add(pItems);
+ }
+ if (iCount <= 1) {
+ wsValue = wsLabel;
+ } else {
+ CXFA_Node* pLabelItems = listitems[0];
+ FX_BOOL bSave = pLabelItems->GetBoolean(XFA_ATTRIBUTE_Save);
+ CXFA_Node* pSaveItems = NULL;
+ if (bSave) {
+ pSaveItems = pLabelItems;
+ pLabelItems = listitems[1];
+ } else {
+ pSaveItems = listitems[1];
+ }
+ iCount = 0;
+ FX_INT32 iSearch = -1;
+ CFX_WideString wsContent;
+ CXFA_Node* pChildItem = pLabelItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pChildItem; pChildItem = pChildItem->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ pChildItem->TryContent(wsContent);
+ if (wsContent == wsLabel) {
+ iSearch = iCount;
+ break;
+ }
+ iCount ++;
+ }
+ if (iSearch < 0) {
+ return;
+ }
+ if (CXFA_Node* pText = pSaveItems->GetChild(iSearch, XFA_ELEMENT_UNKNOWN)) {
+ pText->TryContent(wsValue);
+ }
+ }
+}
+FX_BOOL CXFA_WidgetData::DeleteItem(FX_INT32 nIndex, FX_BOOL bNotify, FX_BOOL bScriptModify, FX_BOOL bSyncData)
+{
+ FX_BOOL bSetValue = FALSE;
+ CXFA_Node* pItems = m_pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for (; pItems; pItems = pItems->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ if (pItems->GetClassID() != XFA_ELEMENT_Items) {
+ continue;
+ }
+ if (nIndex < 0) {
+ while (CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ pItems->RemoveChild(pNode);
+ }
+ } else {
+ if (!bSetValue && pItems->GetBoolean(XFA_ATTRIBUTE_Save)) {
+ SetItemState(nIndex, FALSE, TRUE, bScriptModify, bSyncData);
+ bSetValue = TRUE;
+ }
+ FX_INT32 i = 0;
+ CXFA_Node* pNode = pItems->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pNode) {
+ if (i == nIndex) {
+ pItems->RemoveChild(pNode);
+ break;
+ }
+ i++;
+ pNode = pNode->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ }
+ }
+ if(!bNotify) {
+ return TRUE;
+ }
+ m_pNode->GetDocument()->GetNotify()->OnWidgetDataEvent(this, XFA_WIDGETEVENT_ListItemRemoved, (FX_LPVOID)(FX_UINTPTR)nIndex);
+ return TRUE;
+}
+FX_INT32 CXFA_WidgetData::GetHorizontalScrollPolicy()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetEnum(XFA_ATTRIBUTE_HScrollPolicy);
+ }
+ return XFA_ATTRIBUTEENUM_Auto;
+}
+FX_INT32 CXFA_WidgetData::GetNumberOfCells()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (!pUIChild) {
+ return -1;
+ }
+ if (CXFA_Node* pNode = pUIChild->GetChild(0, XFA_ELEMENT_Comb)) {
+ return pNode->GetInteger(XFA_ATTRIBUTE_NumberOfCells);
+ }
+ return -1;
+}
+FX_BOOL CXFA_WidgetData::IsDateTimeEditUsePicker()
+{
+ return TRUE;
+}
+CFX_WideString CXFA_WidgetData::GetBarcodeType()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ return pUIChild ? pUIChild->GetCData(XFA_ATTRIBUTE_Type) : NULL;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_CharEncoding(FX_INT32& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CFX_WideString wsCharEncoding;
+ if(pUIChild->TryCData(XFA_ATTRIBUTE_CharEncoding, wsCharEncoding)) {
+ if (wsCharEncoding.CompareNoCase((FX_LPCWSTR)(L"UTF-16"))) {
+ val = CHAR_ENCODING_UNICODE;
+ return TRUE;
+ } else if (wsCharEncoding.CompareNoCase((FX_LPCWSTR)(L"UTF-8"))) {
+ val = CHAR_ENCODING_UTF8;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Checksum(FX_INT32& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ XFA_ATTRIBUTEENUM eChecksum;
+ if (pUIChild->TryEnum(XFA_ATTRIBUTE_Checksum, eChecksum)) {
+ switch (eChecksum) {
+ case XFA_ATTRIBUTEENUM_None:
+ val = 0;
+ return TRUE;
+ case XFA_ATTRIBUTEENUM_Auto:
+ val = 1;
+ return TRUE;
+ case XFA_ATTRIBUTEENUM_1mod10:
+ break;
+ case XFA_ATTRIBUTEENUM_1mod10_1mod11:
+ break;
+ case XFA_ATTRIBUTEENUM_2mod10:
+ break;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_DataLength(FX_INT32& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CFX_WideString wsDataLength;
+ if(pUIChild->TryCData(XFA_ATTRIBUTE_DataLength, wsDataLength)) {
+ val = FXSYS_wtoi(wsDataLength);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_StartChar(FX_CHAR& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CFX_WideStringC wsStartEndChar;
+ if(pUIChild->TryCData(XFA_ATTRIBUTE_StartChar, wsStartEndChar)) {
+ if(wsStartEndChar.GetLength()) {
+ val = (FX_CHAR)wsStartEndChar.GetAt(0);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_EndChar(FX_CHAR& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CFX_WideStringC wsStartEndChar;
+ if(pUIChild->TryCData(XFA_ATTRIBUTE_EndChar, wsStartEndChar)) {
+ if(wsStartEndChar.GetLength()) {
+ val = (FX_CHAR)wsStartEndChar.GetAt(0);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ECLevel(FX_INT32& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CFX_WideString wsECLevel;
+ if(pUIChild->TryCData(XFA_ATTRIBUTE_ErrorCorrectionLevel, wsECLevel)) {
+ val = FXSYS_wtoi(wsECLevel);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleWidth(FX_INT32& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CXFA_Measurement mModuleWidthHeight;
+ if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleWidth, mModuleWidthHeight)) {
+ val = (FX_INT32)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_ModuleHeight(FX_INT32& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CXFA_Measurement mModuleWidthHeight;
+ if (pUIChild->TryMeasure(XFA_ATTRIBUTE_ModuleHeight, mModuleWidthHeight)) {
+ val = (FX_INT32)mModuleWidthHeight.ToUnit(XFA_UNIT_Pt);
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_PrintChecksum(FX_BOOL& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ FX_BOOL bPrintCheckDigit;
+ if(pUIChild->TryBoolean(XFA_ATTRIBUTE_PrintCheckDigit, bPrintCheckDigit)) {
+ val = bPrintCheckDigit;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_TextLocation(FX_INT32& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ XFA_ATTRIBUTEENUM eTextLocation;
+ if (pUIChild->TryEnum(XFA_ATTRIBUTE_TextLocation, eTextLocation)) {
+ switch(eTextLocation) {
+ case XFA_ATTRIBUTEENUM_None:
+ val = BC_TEXT_LOC_NONE;
+ return TRUE;
+ case XFA_ATTRIBUTEENUM_Above:
+ val = BC_TEXT_LOC_ABOVE;
+ return TRUE;
+ case XFA_ATTRIBUTEENUM_Below:
+ val = BC_TEXT_LOC_BELOW;
+ return TRUE;
+ case XFA_ATTRIBUTEENUM_AboveEmbedded:
+ val = BC_TEXT_LOC_ABOVEEMBED;
+ return TRUE;
+ case XFA_ATTRIBUTEENUM_BelowEmbedded:
+ val = BC_TEXT_LOC_BELOWEMBED;
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_Truncate(FX_BOOL& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ FX_BOOL bTruncate;
+ if(pUIChild->TryBoolean(XFA_ATTRIBUTE_Truncate, bTruncate)) {
+ val = bTruncate;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetBarcodeAttribute_WideNarrowRatio(FX_FLOAT& val)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ CFX_WideString wsWideNarrowRatio;
+ if (pUIChild->TryCData(XFA_ATTRIBUTE_WideNarrowRatio, wsWideNarrowRatio)) {
+ FX_STRSIZE ptPos = wsWideNarrowRatio.Find(':');
+ FX_FLOAT fRatio = 0;
+ if(ptPos >= 0) {
+ fRatio = (FX_FLOAT)FXSYS_wtoi(wsWideNarrowRatio);
+ } else {
+ FX_INT32 fA, fB;
+ fA = FXSYS_wtoi(wsWideNarrowRatio.Left(ptPos));
+ fB = FXSYS_wtoi(wsWideNarrowRatio.Mid(ptPos + 1));
+ if(fB) {
+ fRatio = (FX_FLOAT)fA / fB;
+ }
+ }
+ val = fRatio;
+ return TRUE;
+ }
+ return FALSE;
+}
+void CXFA_WidgetData::GetPasswordChar(CFX_WideString &wsPassWord)
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ pUIChild->TryCData(XFA_ATTRIBUTE_PasswordChar, wsPassWord);
+ } else {
+ wsPassWord = XFA_GetAttributeDefaultValue_Cdata(XFA_ELEMENT_PasswordEdit, XFA_ATTRIBUTE_PasswordChar, XFA_XDPPACKET_Form);
+ }
+}
+FX_BOOL CXFA_WidgetData::IsAllowRichText()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ FX_BOOL bValue = FALSE;
+ if (pUIChild && pUIChild->TryBoolean(XFA_ATTRIBUTE_AllowRichText, bValue, FALSE)) {
+ return bValue;
+ }
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+ if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ return pChild->GetClassID() == XFA_ELEMENT_ExData;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::IsMultiLine()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetBoolean(XFA_ATTRIBUTE_MultiLine);
+ }
+ return XFA_GetAttributeDefaultValue_Boolean(XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_MultiLine, XFA_XDPPACKET_Form);
+}
+FX_INT32 CXFA_WidgetData::GetVerticalScrollPolicy()
+{
+ CXFA_Node* pUIChild = GetUIChild();
+ if (pUIChild) {
+ return pUIChild->GetEnum(XFA_ATTRIBUTE_VScrollPolicy);
+ }
+ return XFA_GetAttributeDefaultValue_Enum(XFA_ELEMENT_TextEdit, XFA_ATTRIBUTE_VScrollPolicy, XFA_XDPPACKET_Form);
+}
+FX_INT32 CXFA_WidgetData::GetMaxChars(XFA_ELEMENT& eType)
+{
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+ if (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild)) {
+ switch(pChild->GetClassID()) {
+ case XFA_ELEMENT_Text:
+ eType = XFA_ELEMENT_Text;
+ return pChild->GetInteger(XFA_ATTRIBUTE_MaxChars);
+ case XFA_ELEMENT_ExData: {
+ eType = XFA_ELEMENT_ExData;
+ FX_INT32 iMax = pChild->GetInteger(XFA_ATTRIBUTE_MaxLength);
+ return iMax < 0 ? 0 : iMax;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return 0;
+}
+FX_BOOL CXFA_WidgetData::GetFracDigits(FX_INT32 &iFracDigits)
+{
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+ if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
+ return pChild->TryInteger(XFA_ATTRIBUTE_FracDigits, iFracDigits);
+ }
+ }
+ iFracDigits = -1;
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetLeadDigits(FX_INT32 &iLeadDigits)
+{
+ if (CXFA_Node* pNode = m_pNode->GetChild(0, XFA_ELEMENT_Value)) {
+ if (CXFA_Node* pChild = pNode->GetChild(0, XFA_ELEMENT_Decimal)) {
+ return pChild->TryInteger(XFA_ATTRIBUTE_LeadDigits, iLeadDigits);
+ }
+ }
+ iLeadDigits = -1;
+ return FALSE;
+}
+static CFX_WideString XFA_NumericNormalize(const CFX_WideString &wsValue, IFX_Locale* pLocale)
+{
+ CFX_WideString wsDecimalSymbol;
+ if (pLocale) {
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsDecimalSymbol);
+ }
+ if (wsDecimalSymbol.IsEmpty()) {
+ wsDecimalSymbol = '.';
+ }
+ CFX_WideString wsNewValue(wsValue);
+ wsNewValue.TrimLeft(L" ");
+ wsNewValue.TrimLeft(L"0");
+ wsNewValue.TrimRight(L" ");
+ FX_INT32 iCount = wsNewValue.GetLength();
+ if (iCount == 0) {
+ return FX_WSTRC(L"0");
+ }
+ FX_INT32 iIndex = 0;
+ CFX_WideString wsRet;
+ FX_LPWSTR pRetBuffer = wsRet.GetBuffer(iCount);
+ FX_INT32 iDestCount = 0;
+ FX_INT32 i = 0;
+ if (wsNewValue[i] == L'-') {
+ pRetBuffer[iIndex++] = '-';
+ } else if (wsNewValue[i] == L'+') {
+ i++;
+ }
+ FX_BOOL bHasPoint = FALSE;
+ FX_INT32 nCharStart = -1;
+ for ( ; i < iCount; i ++) {
+ FX_WCHAR wc = wsNewValue[i];
+ if (XFA_IsDigit(wc)) {
+ if (nCharStart != -1) {
+ CFX_WideStringC wsChar((FX_LPCWSTR)wsNewValue + nCharStart, i - nCharStart);
+ if (wsChar == '.' || wsChar == wsDecimalSymbol) {
+ bHasPoint = TRUE;
+ nCharStart = -1;
+ } else {
+ pRetBuffer[0] = '0';
+ iCount = 1;
+ break;
+ }
+ }
+ pRetBuffer[iIndex++] = wc;
+ continue;
+ }
+ if (bHasPoint) {
+ pRetBuffer[0] = '0';
+ iCount = 1;
+ break;
+ }
+ if (nCharStart == -1) {
+ nCharStart = i;
+ pRetBuffer[iIndex++] = wc;
+ }
+ }
+ wsRet.ReleaseBuffer(iCount);
+ return wsRet;
+}
+CFX_WideString XFA_NumericLimit(const CFX_WideString &wsValue, FX_INT32 iLead, FX_INT32 iTread)
+{
+ if ((iLead == - 1) && (iTread == -1)) {
+ return wsValue;
+ }
+ CFX_WideString wsRet;
+ FX_INT32 iLead_ = 0, iTread_ = -1;
+ FX_INT32 iCount = wsValue.GetLength();
+ if (iCount == 0) {
+ return wsValue;
+ }
+ FX_INT32 i = 0;
+ if (wsValue[i] == L'-') {
+ wsRet += L'-';
+ i++;
+ }
+ for (; i < iCount; i ++) {
+ FX_WCHAR wc = wsValue[i];
+ if (XFA_IsDigit(wc)) {
+ if (iLead >= 0) {
+ iLead_ ++;
+ if (iLead_ > iLead) {
+ return L"0";
+ }
+ } else if (iTread_ >= 0) {
+ iTread_ ++;
+ if (iTread_ > iTread) {
+ if (iTread != -1) {
+ CFX_Decimal wsDeci = CFX_Decimal(wsValue);
+ wsDeci.SetScale(iTread);
+ wsRet = wsDeci;
+ }
+ return wsRet;
+ }
+ }
+ } else if (wc == L'.') {
+ iTread_ = 0;
+ iLead = -1;
+ }
+ wsRet += wc;
+ }
+ return wsRet;
+}
+FX_BOOL CXFA_WidgetData::SetValue(const CFX_WideString& wsValue, XFA_VALUEPICTURE eValueType)
+{
+ if (wsValue.IsEmpty()) {
+ SyncValue(wsValue, TRUE);
+ return TRUE;
+ }
+ CFX_WideString wsNewText(wsValue);
+ CFX_WideString wsPicture;
+ GetPictureContent(wsPicture, eValueType);
+ FX_BOOL bNormalizeNum = TRUE;
+ CXFA_Node* pNode = GetUIChild();
+ if (!pNode) {
+ return TRUE;
+ }
+ XFA_ELEMENT uiType = pNode->GetClassID();
+ if (!wsPicture.IsEmpty()) {
+ CXFA_LocaleMgr* pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+ IFX_Locale* pLocale = GetLocal();
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ if (!widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
+ return FALSE;
+ }
+ widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNewText, wsPicture, pLocale, pLocalMgr);
+ wsNewText = widgetValue.GetValue();
+ if (uiType == XFA_ELEMENT_NumericEdit) {
+ FX_INT32 iLeadDigits = 0;
+ FX_INT32 iFracDigits = 0;
+ GetLeadDigits(iLeadDigits);
+ GetFracDigits(iFracDigits);
+ wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
+ bNormalizeNum = FALSE;
+ }
+ }
+ if (uiType == XFA_ELEMENT_NumericEdit && bNormalizeNum) {
+ if (wsNewText != FX_WSTRC(L"0")) {
+ FX_INT32 iLeadDigits = 0;
+ FX_INT32 iFracDigits = 0;
+ GetLeadDigits(iLeadDigits);
+ GetFracDigits(iFracDigits);
+ wsNewText = XFA_NumericLimit(wsNewText, iLeadDigits, iFracDigits);
+ }
+ }
+ SyncValue(wsNewText, TRUE);
+ return TRUE;
+}
+FX_BOOL CXFA_WidgetData::GetPictureContent(CFX_WideString &wsPicture, XFA_VALUEPICTURE ePicture)
+{
+ if (ePicture == XFA_VALUEPICTURE_Raw) {
+ return FALSE;
+ }
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ switch(ePicture) {
+ case XFA_VALUEPICTURE_Display: {
+ if (CXFA_Node* pFormat = m_pNode->GetChild(0, XFA_ELEMENT_Format)) {
+ if (CXFA_Node* pPicture = pFormat->GetChild(0, XFA_ELEMENT_Picture)) {
+ if (pPicture->TryContent(wsPicture)) {
+ return TRUE;
+ }
+ }
+ }
+ CFX_WideString wsDataPicture, wsTimePicture;
+ IFX_Locale* pLocale = GetLocal();
+ if (!pLocale) {
+ return FALSE;
+ }
+ FX_DWORD dwType = widgetValue.GetType();
+ switch (dwType) {
+ case XFA_VT_DATE:
+ pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium, wsPicture);
+ break;
+ case XFA_VT_TIME:
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium, wsPicture);
+ break;
+ case XFA_VT_DATETIME:
+ pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium, wsDataPicture);
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Medium, wsTimePicture);
+ wsPicture = wsDataPicture + FX_WSTRC(L"T") + wsTimePicture;
+ break;
+ case XFA_VT_DECIMAL:
+ case XFA_VT_FLOAT:
+ break;
+ default:
+ break;
+ }
+ }
+ return TRUE;
+ case XFA_VALUEPICTURE_Edit: {
+ CXFA_Node* pUI = m_pNode->GetChild(0, XFA_ELEMENT_Ui);
+ if (pUI) {
+ if (CXFA_Node* pPicture = pUI->GetChild(0, XFA_ELEMENT_Picture)) {
+ if (pPicture->TryContent(wsPicture)) {
+ return TRUE;
+ }
+ }
+ }
+ {
+ CFX_WideString wsDataPicture, wsTimePicture;
+ IFX_Locale* pLocale = GetLocal();
+ if (!pLocale) {
+ return FALSE;
+ }
+ FX_DWORD dwType = widgetValue.GetType();
+ switch (dwType) {
+ case XFA_VT_DATE:
+ pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short, wsPicture);
+ break;
+ case XFA_VT_TIME:
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short, wsPicture);
+ break;
+ case XFA_VT_DATETIME:
+ pLocale->GetDatePattern(FX_LOCALEDATETIMESUBCATEGORY_Short, wsDataPicture);
+ pLocale->GetTimePattern(FX_LOCALEDATETIMESUBCATEGORY_Short, wsTimePicture);
+ wsPicture = wsDataPicture + L"T" + wsTimePicture;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return TRUE;
+ case XFA_VALUEPICTURE_DataBind: {
+ if (CXFA_Bind bind = GetBind()) {
+ bind.GetPicture(wsPicture);
+ return TRUE;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+IFX_Locale* CXFA_WidgetData::GetLocal()
+{
+ IFX_Locale* pLocale = NULL;
+ if (!m_pNode) {
+ return pLocale;
+ }
+ FX_BOOL bLocale = FALSE;
+ CFX_WideString wsLocaleName;
+ bLocale = m_pNode->GetLocaleName(wsLocaleName);
+ if (bLocale) {
+ if (wsLocaleName.Equal(FX_WSTRC(L"ambient"))) {
+ pLocale = m_pNode->GetDocument()->GetLocalMgr()->GetDefLocale();
+ } else {
+ pLocale = m_pNode->GetDocument()->GetLocalMgr()->GetLocaleByName(wsLocaleName);
+ }
+ }
+ return pLocale;
+}
+static FX_BOOL XFA_SplitDateTime(const CFX_WideString& wsDateTime, CFX_WideString& wsDate, CFX_WideString& wsTime)
+{
+ wsDate = L"";
+ wsTime = L"";
+ if (wsDateTime.IsEmpty()) {
+ return FALSE;
+ }
+ int nSplitIndex = -1;
+ nSplitIndex = wsDateTime.Find('T');
+ if (nSplitIndex < 0) {
+ nSplitIndex = wsDateTime.Find(' ');
+ }
+ if (nSplitIndex < 0) {
+ return FALSE;
+ }
+ wsDate = wsDateTime.Left(nSplitIndex);
+ if (!wsDate.IsEmpty()) {
+ FX_INT32 iCount = wsDate.GetLength();
+ FX_INT32 i = 0;
+ for (i = 0; i < iCount; i++) {
+ if (wsDate[i] >= '0' && wsDate[i] <= '9') {
+ break;
+ }
+ }
+ if (i == iCount) {
+ return FALSE;
+ }
+ }
+ wsTime = wsDateTime.Right(wsDateTime.GetLength() - nSplitIndex - 1);
+ if (!wsTime.IsEmpty()) {
+ FX_INT32 iCount = wsTime.GetLength();
+ FX_INT32 i = 0;
+ for (i = 0; i < iCount; i++) {
+ if (wsTime[i] >= '0' && wsTime[i] <= '9') {
+ break;
+ }
+ }
+ if (i == iCount) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+#ifndef XFA_PARSE_HAS_LINEIDENTIFIER
+FX_BOOL CXFA_FieldNode_IsRichTextEdit(CXFA_Node *pFieldNode, IFDE_XMLNode *&pXMLNode)
+{
+ FX_BOOL bRichTextEdit = FALSE;
+ pXMLNode = NULL;
+ if (pFieldNode->GetClassID() == XFA_ELEMENT_Field) {
+ CXFA_Node* pValue = pFieldNode->GetChild(0, XFA_ELEMENT_Value);
+ if (!pValue) {
+ return bRichTextEdit;
+ }
+ CXFA_Node* pChildValue = pValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pChildValue) {
+ return bRichTextEdit;
+ }
+ if (pChildValue->GetClassID() == XFA_ELEMENT_ExData) {
+ CFX_WideString wsContentType;
+ pChildValue->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
+ bRichTextEdit = wsContentType.Equal(FX_WSTRC(L"text/html"));
+ if(bRichTextEdit) {
+ FX_BOOL bXMLInData = FALSE;
+ CXFA_Node *pDataNode = pFieldNode->GetBindData();
+ if (pDataNode) {
+ IFDE_XMLNode *pBindXML = pDataNode->GetXMLMappingNode();
+ FXSYS_assert(pBindXML);
+ IFDE_XMLNode *pValueXML = pBindXML->GetNodeItem(IFDE_XMLNode::FirstChild);
+ if (pValueXML && pValueXML->GetType() == FDE_XMLNODE_Element) {
+ pXMLNode = pValueXML;
+ bXMLInData = TRUE;
+ }
+ }
+ if (!bXMLInData) {
+ pXMLNode = pChildValue->GetXMLMappingNode();
+ }
+ }
+ }
+ }
+ return bRichTextEdit;
+}
+#endif
+FX_BOOL CXFA_WidgetData::GetValue(CFX_WideString &wsValue, XFA_VALUEPICTURE eValueType)
+{
+#ifdef XFA_PARSE_HAS_LINEIDENTIFIER
+ wsValue = m_pNode->GetContent();
+#else
+ IFDE_XMLNode *pXMLNode = NULL;
+ FX_BOOL bRichTextEdit = CXFA_FieldNode_IsRichTextEdit(m_pNode, pXMLNode);
+ if (bRichTextEdit) {
+ XFA_GetPlainTextFromRichText(pXMLNode, wsValue);
+ } else {
+ wsValue = m_pNode->GetContent();
+ }
+#endif
+ if (eValueType == XFA_VALUEPICTURE_Display) {
+ GetItemLabel(wsValue, wsValue);
+ }
+ CFX_WideString wsPicture;
+ GetPictureContent(wsPicture, eValueType);
+ CXFA_Node* pNode = GetUIChild();
+ if (!pNode) {
+ return TRUE;
+ }
+ XFA_ELEMENT uiType = GetUIChild()->GetClassID();
+ switch(uiType) {
+ case XFA_ELEMENT_ChoiceList: {
+ if (eValueType == XFA_VALUEPICTURE_Display) {
+ FX_INT32 iSelItemIndex = GetSelectedItem(0);
+ if (iSelItemIndex >= 0) {
+ GetChoiceListItem(wsValue, iSelItemIndex);
+ wsPicture.Empty();
+ }
+ }
+ }
+ break;
+ case XFA_ELEMENT_NumericEdit:
+ if(eValueType != XFA_VALUEPICTURE_Raw && wsPicture.IsEmpty()) {
+ IFX_Locale* pLocale = GetLocal();
+ if (eValueType == XFA_VALUEPICTURE_Display && pLocale) {
+ CFX_WideString wsOutput;
+ NormalizeNumStr(wsValue, wsOutput);
+ FormatNumStr(wsOutput, pLocale, wsOutput);
+ wsValue = wsOutput;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if(wsPicture.IsEmpty()) {
+ return TRUE;
+ }
+ if (IFX_Locale* pLocale = GetLocal()) {
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ CXFA_LocaleMgr *pLocalMgr = m_pNode->GetDocument()->GetLocalMgr();
+ switch (widgetValue.GetType()) {
+ case XFA_VT_DATE: {
+ CFX_WideString wsDate, wsTime;
+ if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+ if (date.FormatPatterns(wsValue, wsPicture, pLocale, eValueType)) {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case XFA_VT_TIME: {
+ CFX_WideString wsDate, wsTime;
+ if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+ if (time.FormatPatterns(wsValue, wsPicture, pLocale, eValueType)) {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ widgetValue.FormatPatterns(wsValue, wsPicture, pLocale, eValueType);
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_WidgetData::GetNormalizeDataValue(FX_WSTR wsValue, CFX_WideString &wsNormalizeValue)
+{
+ wsNormalizeValue = wsValue;
+ if (wsValue.IsEmpty()) {
+ return TRUE;
+ }
+ CFX_WideString wsPicture;
+ GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+ if (wsPicture.IsEmpty()) {
+ return TRUE;
+ }
+ FXSYS_assert(GetNode());
+ CXFA_LocaleMgr* pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+ IFX_Locale* pLocale = GetLocal();
+ CXFA_LocaleValue widgetValue = XFA_GetLocaleValue(this);
+ if (widgetValue.ValidateValue(wsValue, wsPicture, pLocale, &wsPicture)) {
+ widgetValue = CXFA_LocaleValue(widgetValue.GetType(), wsNormalizeValue, wsPicture, pLocale, pLocalMgr);
+ wsNormalizeValue = widgetValue.GetValue();
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_WidgetData::GetFormatDataValue(FX_WSTR wsValue, CFX_WideString &wsFormatedValue)
+{
+ wsFormatedValue = wsValue;
+ if (wsValue.IsEmpty()) {
+ return TRUE;
+ }
+ CFX_WideString wsPicture;
+ GetPictureContent(wsPicture, XFA_VALUEPICTURE_DataBind);
+ if (wsPicture.IsEmpty()) {
+ return TRUE;
+ }
+ if (IFX_Locale* pLocale = GetLocal()) {
+ FXSYS_assert(GetNode());
+ CXFA_Node* pNodeValue = GetNode()->GetChild(0, XFA_ELEMENT_Value);
+ if (!pNodeValue) {
+ return FALSE;
+ }
+ CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pValueChild) {
+ return FALSE;
+ }
+ FX_INT32 iVTType = XFA_VT_NULL;
+ XFA_ELEMENT eType = pValueChild->GetClassID();
+ switch (eType) {
+ case XFA_ELEMENT_Decimal:
+ iVTType = XFA_VT_DECIMAL;
+ break;
+ case XFA_ELEMENT_Float:
+ iVTType = XFA_VT_FLOAT;
+ break;
+ case XFA_ELEMENT_Date:
+ iVTType = XFA_VT_DATE;
+ break;
+ case XFA_ELEMENT_Time:
+ iVTType = XFA_VT_TIME;
+ break;
+ case XFA_ELEMENT_DateTime:
+ iVTType = XFA_VT_DATETIME;
+ break;
+ case XFA_ELEMENT_Boolean:
+ iVTType = XFA_VT_BOOLEAN;
+ break;
+ case XFA_ELEMENT_Integer:
+ iVTType = XFA_VT_INTEGER;
+ break;
+ case XFA_ELEMENT_Text:
+ iVTType = XFA_VT_TEXT;
+ break;
+ default:
+ iVTType = XFA_VT_NULL;
+ break;
+ }
+ CXFA_LocaleMgr *pLocalMgr = GetNode()->GetDocument()->GetLocalMgr();
+ CXFA_LocaleValue widgetValue(iVTType, wsValue, pLocalMgr);
+ switch (widgetValue.GetType()) {
+ case XFA_VT_DATE: {
+ CFX_WideString wsDate, wsTime;
+ if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue date(XFA_VT_DATE, wsDate, pLocalMgr);
+ if (date.FormatPatterns(wsFormatedValue, wsPicture, pLocale, XFA_VALUEPICTURE_DataBind)) {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ case XFA_VT_TIME: {
+ CFX_WideString wsDate, wsTime;
+ if (XFA_SplitDateTime(wsValue, wsDate, wsTime)) {
+ CXFA_LocaleValue time(XFA_VT_TIME, wsTime, pLocalMgr);
+ if (time.FormatPatterns(wsFormatedValue, wsPicture, pLocale, XFA_VALUEPICTURE_DataBind)) {
+ return TRUE;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ widgetValue.FormatPatterns(wsFormatedValue, wsPicture, pLocale, XFA_VALUEPICTURE_DataBind);
+ }
+ return FALSE;
+}
+void CXFA_WidgetData::NormalizeNumStr(const CFX_WideString& wsValue, CFX_WideString& wsOutput)
+{
+ if (wsValue.IsEmpty()) {
+ return;
+ }
+ wsOutput = wsValue;
+ wsOutput.TrimLeft('0');
+ FX_INT32 dot_index = wsOutput.Find('.');
+ FX_INT32 iFracDigits = 0;
+ if (!wsOutput.IsEmpty() && dot_index >= 0 && (!GetFracDigits(iFracDigits) || iFracDigits != -1)) {
+ wsOutput.TrimRight((FX_LPCWSTR)L"0");
+ wsOutput.TrimRight((FX_LPCWSTR)L".");
+ }
+ if (wsOutput.IsEmpty() || wsOutput[0] == '.') {
+ wsOutput.Insert(0, '0');
+ }
+}
+void CXFA_WidgetData::FormatNumStr(const CFX_WideString& wsValue, IFX_Locale* pLocale, CFX_WideString& wsOutput)
+{
+ if (wsValue.IsEmpty()) {
+ return;
+ }
+ CFX_WideString wsSrcNum = wsValue;
+ CFX_WideString wsGroupSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Grouping, wsGroupSymbol);
+ FX_BOOL bNeg = FALSE;
+ if (wsSrcNum[0] == '-') {
+ bNeg = TRUE;
+ wsSrcNum.Delete(0, 1);
+ }
+ FX_INT32 len = wsSrcNum.GetLength();
+ FX_INT32 dot_index = wsSrcNum.Find('.');
+ if (dot_index == -1) {
+ dot_index = len;
+ }
+ FX_INT32 cc = dot_index - 1;
+ if (cc >= 0) {
+ int nPos = dot_index % 3;
+ wsOutput.Empty();
+ for (FX_INT32 i = 0; i < dot_index; i++) {
+ if (i % 3 == nPos && i != 0) {
+ wsOutput += wsGroupSymbol;
+ }
+ wsOutput += wsSrcNum[i];
+ }
+ if (dot_index < len) {
+ CFX_WideString wsSymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Decimal, wsSymbol);
+ wsOutput += wsSymbol;
+ wsOutput += wsSrcNum.Right(len - dot_index - 1);
+ }
+ if (bNeg) {
+ CFX_WideString wsMinusymbol;
+ pLocale->GetNumbericSymbol(FX_LOCALENUMSYMBOL_Minus, wsMinusymbol);
+ wsOutput = wsMinusymbol + wsOutput;
+ }
+ }
+}
+void CXFA_WidgetData::SyncValue(const CFX_WideString& wsValue, FX_BOOL bNotify)
+{
+ if (!m_pNode) {
+ return;
+ }
+ CFX_WideString wsFormatValue(wsValue);
+ CXFA_WidgetData* pContainerWidgetData = m_pNode->GetContainerWidgetData();
+ if (pContainerWidgetData) {
+ pContainerWidgetData->GetFormatDataValue(wsValue, wsFormatValue);
+ }
+ m_pNode->SetContent(wsValue, wsFormatValue, bNotify);
+}
+void CXFA_WidgetData::InsertListTextItem(CXFA_Node* pItems, FX_WSTR wsText, FX_INT32 nIndex )
+{
+ CXFA_Node* pText = pItems->CreateSamePacketNode(XFA_ELEMENT_Text);
+ pItems->InsertChild(nIndex, pText);
+ pText->SetContent(wsText, wsText, FALSE, FALSE, FALSE);
+}
+CXFA_Filter CXFA_WidgetData::GetFilter(FX_BOOL bModified)
+{
+ if (!m_pUiChildNode) {
+ return CXFA_Filter(NULL);
+ }
+ return m_pUiChildNode->GetProperty(0, XFA_ELEMENT_Filter, bModified);
+}
+CXFA_Manifest CXFA_WidgetData::GetManifest(FX_BOOL bModified)
+{
+ if (!m_pUiChildNode) {
+ return CXFA_Manifest(NULL);
+ }
+ return m_pUiChildNode->GetProperty(0, XFA_ELEMENT_Manifest, bModified);
+}
+CXFA_Occur::CXFA_Occur(CXFA_Node *pNode) : CXFA_Data(pNode)
+{ }
+FX_INT32 CXFA_Occur::GetMax()
+{
+ FX_INT32 iMax = 1;
+ if (m_pNode) {
+ if(!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, TRUE)) {
+ iMax = GetMin();
+ }
+ }
+ return iMax;
+}
+FX_INT32 CXFA_Occur::GetMin()
+{
+ FX_INT32 iMin = 1;
+ if (m_pNode) {
+ if(!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, TRUE) || iMin < 0) {
+ iMin = 1;
+ }
+ }
+ return iMin;
+}
+FX_INT32 CXFA_Occur::GetInitial()
+{
+ FX_INT32 iInit = 1;
+ if (m_pNode) {
+ FX_INT32 iMin = GetMin();
+ if(!m_pNode->TryInteger(XFA_ATTRIBUTE_Initial, iInit, TRUE) || iInit < iMin) {
+ iInit = iMin;
+ }
+ }
+ return iInit;
+}
+FX_BOOL CXFA_Occur::GetOccurInfo(FX_INT32& iMin, FX_INT32& iMax, FX_INT32& iInit)
+{
+ if(!m_pNode) {
+ return FALSE;
+ }
+ if(!m_pNode->TryInteger(XFA_ATTRIBUTE_Min, iMin, FALSE) || iMin < 0) {
+ iMin = 1;
+ }
+ if(!m_pNode->TryInteger(XFA_ATTRIBUTE_Max, iMax, FALSE)) {
+ if(iMin == 0) {
+ iMax = 1;
+ } else {
+ iMax = iMin;
+ }
+ }
+ if(!m_pNode->TryInteger(XFA_ATTRIBUTE_Initial, iInit, FALSE) || iInit < iMin) {
+ iInit = iMin;
+ }
+ return TRUE;
+}
+void CXFA_Occur::SetMax(FX_INT32 iMax)
+{
+ iMax = (iMax != -1 && iMax < 1) ? 1 : iMax;
+ m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+ FX_INT32 iMin = GetMin();
+ if (iMax != -1 && iMax < iMin) {
+ iMin = iMax;
+ m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
+ }
+}
+void CXFA_Occur::SetMin(FX_INT32 iMin)
+{
+ iMin = (iMin < 0) ? 1 : iMin;
+ m_pNode->SetInteger(XFA_ATTRIBUTE_Min, iMin, FALSE);
+ FX_INT32 iMax = GetMax();
+ if (iMax > 0 && iMax < iMin) {
+ iMax = iMin;
+ m_pNode->SetInteger(XFA_ATTRIBUTE_Max, iMax, FALSE);
+ }
+}
+XFA_ATTRIBUTEENUM XFA_GetEnumTypeAttribute(CXFA_Node* pNode, XFA_ATTRIBUTE attributeValue = XFA_ATTRIBUTE_Type, XFA_ATTRIBUTEENUM eDefaultValue = XFA_ATTRIBUTEENUM_Optional)
+{
+ XFA_ATTRIBUTEENUM eType = eDefaultValue;
+ if (pNode) {
+ if (!pNode->TryEnum(attributeValue, eType, TRUE)) {
+ eType = eDefaultValue;
+ }
+ }
+ return eType;
+}
+CFX_WideString CXFA_Filter::GetFilterString(XFA_ATTRIBUTE eAttribute)
+{
+ CFX_WideString wsStringValue;
+ if (m_pNode) {
+ m_pNode->GetAttribute(eAttribute, wsStringValue, FALSE);
+ }
+ return wsStringValue;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetAppearanceFilterType()
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Optional;
+ }
+ CXFA_Node* pAppearanceFilterNode = m_pNode->GetProperty(0, XFA_ELEMENT_AppearanceFilter);
+ return XFA_GetEnumTypeAttribute(pAppearanceFilterNode);
+}
+CFX_WideString CXFA_Filter::GetAppearanceFilterContent()
+{
+ CFX_WideString wsContent;
+ if (m_pNode) {
+ CXFA_Node* pAppearanceFilterNode = m_pNode->GetProperty(0, XFA_ELEMENT_AppearanceFilter);
+ pAppearanceFilterNode->TryContent(wsContent);
+ }
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetCertificatesCredentialServerPolicy()
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Optional;
+ }
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+ return XFA_GetEnumTypeAttribute(pCertsNode, XFA_ATTRIBUTE_CredentialServerPolicy);
+}
+CFX_WideString CXFA_Filter::GetCertificatesURL()
+{
+ CFX_WideString wsURL;
+ if (m_pNode) {
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+ pCertsNode->GetAttribute(XFA_ATTRIBUTE_Url, wsURL, FALSE);
+ }
+ return wsURL;
+}
+CFX_WideString CXFA_Filter::GetCertificatesURLPolicy()
+{
+ CFX_WideString wsURLPolicy;
+ if (m_pNode) {
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+ pCertsNode->GetAttribute(XFA_ATTRIBUTE_UrlPolicy, wsURLPolicy, FALSE);
+ }
+ return wsURLPolicy;
+}
+CXFA_WrapCertificate CXFA_Filter::GetCertificatesEncryption(FX_BOOL bModified)
+{
+ if (!m_pNode) {
+ return CXFA_WrapCertificate(NULL);
+ }
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates, bModified);
+ return CXFA_WrapCertificate(pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Encryption, bModified) : NULL);
+}
+CXFA_WrapCertificate CXFA_Filter::GetCertificatesIssuers(FX_BOOL bModified )
+{
+ if (!m_pNode) {
+ return CXFA_WrapCertificate(NULL);
+ }
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates, bModified);
+ return CXFA_WrapCertificate(pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Issuers, bModified) : NULL);
+}
+CFX_WideString CXFA_Filter::GetCertificatesKeyUsageString(XFA_ATTRIBUTE eAttribute)
+{
+ if (!m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+ CXFA_Node* pKeyUsageNode = pCertsNode->GetProperty(0, XFA_ELEMENT_KeyUsage);
+ CFX_WideString wsAttributeValue;
+ pKeyUsageNode->GetAttribute(eAttribute, wsAttributeValue, FALSE);
+ return wsAttributeValue;
+}
+CXFA_Oids CXFA_Filter::GetCertificatesOids()
+{
+ if (!m_pNode) {
+ return CXFA_Oids(NULL);
+ }
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates);
+ return CXFA_Oids(pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Oids) : NULL);
+}
+CXFA_WrapCertificate CXFA_Filter::GetCertificatesSigning(FX_BOOL bModified )
+{
+ if (!m_pNode) {
+ return CXFA_WrapCertificate(NULL);
+ }
+ CXFA_Node* pCertsNode = m_pNode->GetProperty(0, XFA_ELEMENT_Certificates, bModified);
+ return CXFA_WrapCertificate(pCertsNode ? pCertsNode->GetProperty(0, XFA_ELEMENT_Signing, bModified) : NULL);
+}
+CXFA_DigestMethods CXFA_Filter::GetDigestMethods(FX_BOOL bModified )
+{
+ return CXFA_DigestMethods(m_pNode ? m_pNode->GetProperty(0, XFA_ELEMENT_DigestMethods, bModified) : NULL);
+}
+CXFA_Encodings CXFA_Filter::GetEncodings(FX_BOOL bModified )
+{
+ return CXFA_Encodings(m_pNode ? m_pNode->GetProperty(0, XFA_ELEMENT_Encodings, bModified) : NULL);
+}
+CXFA_EncryptionMethods CXFA_Filter::GetEncryptionMethods(FX_BOOL bModified )
+{
+ return CXFA_EncryptionMethods(m_pNode ? m_pNode->GetProperty(0, XFA_ELEMENT_EncryptionMethods, bModified) : NULL);
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetHandlerType()
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Optional;
+ }
+ CXFA_Node* pHandlerNode = m_pNode->GetProperty(0, XFA_ELEMENT_Handler);
+ return XFA_GetEnumTypeAttribute(pHandlerNode);
+}
+CFX_WideString CXFA_Filter::GetHandlerContent()
+{
+ CFX_WideString wsContent;
+ if (m_pNode) {
+ CXFA_Node* pHandlerNode = m_pNode->GetProperty(0, XFA_ELEMENT_Handler);
+ pHandlerNode->TryContent(wsContent);
+ }
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetlockDocumentType()
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Optional;
+ }
+ CXFA_Node* pLockDocNode = m_pNode->GetProperty(0, XFA_ELEMENT_LockDocument);
+ return XFA_GetEnumTypeAttribute(pLockDocNode);
+}
+CFX_WideString CXFA_Filter::GetlockDocumentContent()
+{
+ CFX_WideString wsContent = FX_WSTRC(L"auto");
+ if (m_pNode) {
+ CXFA_Node* pLockDocNode = m_pNode->GetProperty(0, XFA_ELEMENT_LockDocument);
+ pLockDocNode->TryContent(wsContent);
+ }
+ return wsContent;
+}
+FX_INT32 CXFA_Filter::GetMDPPermissions()
+{
+ FX_INT32 iPermissions = 2;
+ if (m_pNode) {
+ CXFA_Node* pMDPNode = m_pNode->GetProperty(0, XFA_ELEMENT_Mdp);
+ if (!pMDPNode->TryInteger(XFA_ATTRIBUTE_Permissions, iPermissions, TRUE)) {
+ iPermissions = 2;
+ }
+ }
+ return iPermissions;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetMDPSignatureType()
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Filter;
+ }
+ CXFA_Node* pMDPNode = m_pNode->GetProperty(0, XFA_ELEMENT_Mdp);
+ return XFA_GetEnumTypeAttribute(pMDPNode, XFA_ATTRIBUTE_SignatureType, XFA_ATTRIBUTEENUM_Filter);
+}
+CXFA_Reasons CXFA_Filter::GetReasons(FX_BOOL bModified )
+{
+ return CXFA_Reasons(m_pNode ? m_pNode->GetProperty(0, XFA_ELEMENT_Reasons) : NULL);
+}
+CFX_WideString CXFA_Filter::GetTimeStampServer()
+{
+ CFX_WideString wsServerURI;
+ if (m_pNode) {
+ CXFA_Node* pTimeStampNode = m_pNode->GetProperty(0, XFA_ELEMENT_TimeStamp);
+ pTimeStampNode->GetAttribute(XFA_ATTRIBUTE_Server, wsServerURI, FALSE);
+ }
+ return wsServerURI;
+}
+XFA_ATTRIBUTEENUM CXFA_Filter::GetTimeStampType()
+{
+ if (!m_pNode) {
+ return XFA_ATTRIBUTEENUM_Optional;
+ }
+ CXFA_Node* pTimeStampNode = m_pNode->GetProperty(0, XFA_ELEMENT_TimeStamp);
+ return XFA_GetEnumTypeAttribute(pTimeStampNode);
+}
+CFX_WideString CXFA_Certificate::GetCertificateName()
+{
+ CFX_WideString wsName;
+ if (m_pNode) {
+ m_pNode->GetAttribute(XFA_ATTRIBUTE_Name, wsName, FALSE);
+ }
+ return wsName;
+}
+CFX_WideString CXFA_Certificate::GetCertificateContent()
+{
+ CFX_WideString wsContent;
+ if (m_pNode) {
+ m_pNode->TryContent(wsContent);
+ }
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_WrapCertificate::GetType()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode);
+}
+FX_INT32 CXFA_WrapCertificate::CountCertificates()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Certificate) : 0;
+}
+CXFA_Certificate CXFA_WrapCertificate::GetCertificate(FX_INT32 nIndex)
+{
+ return CXFA_Certificate((nIndex > -1 && m_pNode) ? m_pNode->GetChild(nIndex, XFA_ELEMENT_Certificate) : NULL);
+}
+XFA_ATTRIBUTEENUM CXFA_Oids::GetOidsType()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode);
+}
+FX_INT32 CXFA_Oids::CountOids()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Oid) : 0;
+}
+CFX_WideString CXFA_Oids::GetOidContent(FX_INT32 nIndex)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pOidNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Oid);
+ if (!pOidNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsContent;
+ pOidNode->TryContent(wsContent);
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_SubjectDNs::GetSubjectDNsType()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode);
+}
+FX_INT32 CXFA_SubjectDNs::CountSubjectDNs()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_SubjectDN) : 0;
+}
+CFX_WideString CXFA_SubjectDNs::GetSubjectDNString(FX_INT32 nIndex, XFA_ATTRIBUTE eAttribute)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pSubjectDNNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_SubjectDN);
+ if (!pSubjectDNNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsAttributeValue;
+ pSubjectDNNode->GetAttribute(eAttribute, wsAttributeValue, FALSE);
+ return wsAttributeValue;
+}
+CFX_WideString CXFA_SubjectDNs::GetSubjectDNContent(FX_INT32 nIndex)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pSubjectDNNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_SubjectDN);
+ if (!pSubjectDNNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsContent;
+ pSubjectDNNode->TryContent(wsContent);
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_DigestMethods::GetDigestMethodsType()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode);
+}
+FX_INT32 CXFA_DigestMethods::CountDigestMethods()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_DigestMethod) : 0;
+}
+CFX_WideString CXFA_DigestMethods::GetDigestMethodContent(FX_INT32 nIndex)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pDigestMethodNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_DigestMethod);
+ if (!pDigestMethodNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsContent;
+ pDigestMethodNode->TryContent(wsContent);
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Encodings::GetEncodingsType()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode);
+}
+FX_INT32 CXFA_Encodings::CountEncodings()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Encoding) : 0;
+}
+CFX_WideString CXFA_Encodings::GetEncodingContent(FX_INT32 nIndex)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pEncodingNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Encoding);
+ if (!pEncodingNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsContent;
+ pEncodingNode->TryContent(wsContent);
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_EncryptionMethods::GetEncryptionMethodsType()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode);
+}
+FX_INT32 CXFA_EncryptionMethods::CountEncryptionMethods()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_EncryptionMethod) : 0;
+}
+CFX_WideString CXFA_EncryptionMethods::GetEncryptionMethodContent(FX_INT32 nIndex)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pEncryMethodNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_EncryptionMethod);
+ if (!pEncryMethodNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsContent;
+ pEncryMethodNode->TryContent(wsContent);
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Reasons::GetReasonsType()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode);
+}
+FX_INT32 CXFA_Reasons::CountReasons()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Reason) : 0;
+}
+CFX_WideString CXFA_Reasons::GetReasonContent(FX_INT32 nIndex)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pReasonNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Reason);
+ if (!pReasonNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsContent;
+ pReasonNode->TryContent(wsContent);
+ return wsContent;
+}
+XFA_ATTRIBUTEENUM CXFA_Manifest::GetAction()
+{
+ return XFA_GetEnumTypeAttribute(m_pNode, XFA_ATTRIBUTE_Action, XFA_ATTRIBUTEENUM_Include);
+}
+FX_INT32 CXFA_Manifest::CountReives()
+{
+ return m_pNode ? m_pNode->CountChildren(XFA_ELEMENT_Ref) : 0;
+}
+CFX_WideString CXFA_Manifest::GetRefContent(FX_INT32 nIndex)
+{
+ if (nIndex <= -1 || !m_pNode) {
+ return FX_WSTRC(L"");
+ }
+ CXFA_Node* pRefNode = m_pNode->GetChild(nIndex, XFA_ELEMENT_Ref);
+ if (!pRefNode) {
+ return FX_WSTRC(L"");
+ }
+ CFX_WideString wsContent;
+ pRefNode->TryContent(wsContent);
+ return wsContent;
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_parser_imp.cpp b/xfa/src/fxfa/src/parser/xfa_parser_imp.cpp
new file mode 100644
index 0000000000..14c3e669a1
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_parser_imp.cpp
@@ -0,0 +1,1421 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_basic_imp.h"
+#include "xfa_parser_imp.h"
+IXFA_Parser* IXFA_Parser::Create(IXFA_ObjFactory *pFactory, FX_BOOL bDocumentParser)
+{
+ return FX_NEW CXFA_SimpleParser(pFactory, bDocumentParser);
+}
+CXFA_SimpleParser::CXFA_SimpleParser(IXFA_ObjFactory *pFactory, FX_BOOL bDocumentParser )
+ : m_pXMLParser(NULL)
+ , m_pXMLDoc(NULL)
+ , m_pStream(NULL)
+ , m_pFactory(pFactory)
+ , m_ePacketID(XFA_XDPPACKET_UNKNOWN)
+ , m_pRootNode(NULL)
+ , m_bDocumentParser(bDocumentParser)
+{
+}
+CXFA_SimpleParser::~CXFA_SimpleParser()
+{
+ CloseParser();
+}
+void CXFA_SimpleParser::SetFactory(IXFA_ObjFactory* pFactory)
+{
+ m_pFactory = pFactory;
+}
+static IFDE_XMLNode* XFA_FDEExtension_GetDocumentNode(IFDE_XMLDoc *pXMLDoc, FX_BOOL bVerifyWellFormness = FALSE)
+{
+ if(!pXMLDoc) {
+ return NULL;
+ }
+ IFDE_XMLNode* pXMLFakeRoot = pXMLDoc->GetRoot();
+ for(IFDE_XMLNode* pXMLNode = pXMLFakeRoot->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLNode; pXMLNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if(pXMLNode->GetType() == FDE_XMLNODE_Element) {
+ if(bVerifyWellFormness) {
+ for(IFDE_XMLNode* pNextNode = pXMLNode->GetNodeItem(IFDE_XMLNode::NextSibling); pNextNode; pNextNode = pNextNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if(pNextNode->GetType() == FDE_XMLNODE_Element) {
+ return FALSE;
+ }
+ }
+ }
+ return pXMLNode;
+ }
+ }
+ return NULL;
+}
+FX_INT32 CXFA_SimpleParser::StartParse(IFX_FileRead *pStream, XFA_XDPPACKET ePacketID)
+{
+ CloseParser();
+ m_pFileRead = pStream;
+ m_pStream = IFX_Stream::CreateStream(pStream, FX_STREAMACCESS_Read | FX_STREAMACCESS_Text);
+ if (m_pStream == NULL) {
+ return XFA_PARSESTATUS_StreamErr;
+ }
+ FX_WORD wCodePage = m_pStream->GetCodePage();
+ if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && wCodePage != FX_CODEPAGE_UTF8) {
+ m_pStream->SetCodePage(FX_CODEPAGE_UTF8);
+ }
+ m_pXMLDoc = IFDE_XMLDoc::Create();
+ if (m_pXMLDoc == NULL) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+ m_pXMLParser = FX_NEW CXFA_XMLParser(m_pXMLDoc->GetRoot(), m_pStream);
+ if (m_pXMLParser == NULL) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+ if (!m_pXMLDoc->LoadXML(m_pXMLParser)) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+ m_ePacketID = ePacketID;
+ return XFA_PARSESTATUS_Ready;
+}
+FX_INT32 CXFA_SimpleParser::DoParse(IFX_Pause *pPause)
+{
+ if (m_pXMLDoc == NULL || m_ePacketID == XFA_XDPPACKET_UNKNOWN) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+ FX_INT32 iRet = m_pXMLDoc->DoLoad(pPause);
+ if (iRet < 0) {
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ if (iRet < 100) {
+ return iRet / 2;
+ }
+ m_pRootNode = ParseAsXDPPacket(XFA_FDEExtension_GetDocumentNode(m_pXMLDoc), m_ePacketID);
+ m_pXMLDoc->CloseXML();
+ if (m_pStream) {
+ m_pStream->Release();
+ m_pStream = NULL;
+ }
+ if(!m_pRootNode) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+ return XFA_PARSESTATUS_Done;
+}
+FX_INT32 CXFA_SimpleParser::ParseXMLData(const CFX_WideString &wsXML, IFDE_XMLNode* &pXMLNode, IFX_Pause *pPause)
+{
+ CloseParser();
+ pXMLNode = NULL;
+ IFX_Stream* pStream = XFA_CreateWideTextRead(wsXML);
+ if (!pStream) {
+ return XFA_PARSESTATUS_StreamErr;
+ }
+ m_pStream = pStream;
+ m_pXMLDoc = IFDE_XMLDoc::Create();
+ if (m_pXMLDoc == NULL) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+ CXFA_XMLParser *pParser = FX_NEW CXFA_XMLParser(m_pXMLDoc->GetRoot(), m_pStream);
+ if (pParser == NULL) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+#ifdef _XFA_VERIFY_Checksum_
+ pParser->m_dwCheckStatus = 0x03;
+#endif
+ if (!m_pXMLDoc->LoadXML(pParser)) {
+ return XFA_PARSESTATUS_StatusErr;
+ }
+ FX_INT32 iRet = m_pXMLDoc->DoLoad(pPause);
+ if (iRet < 0 || iRet >= 100) {
+ m_pXMLDoc->CloseXML();
+ }
+ if (iRet < 0) {
+ return XFA_PARSESTATUS_SyntaxErr;
+ }
+ if (iRet < 100) {
+ return iRet / 2;
+ }
+ if (m_pStream) {
+ m_pStream->Release();
+ m_pStream = NULL;
+ }
+ pXMLNode = XFA_FDEExtension_GetDocumentNode(m_pXMLDoc);
+ return XFA_PARSESTATUS_Done;
+}
+void CXFA_SimpleParser::ConstructXFANode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode)
+{
+ XFA_XDPPACKET ePacketID = (XFA_XDPPACKET)pXFANode->GetPacketID();
+ if (ePacketID == XFA_XDPPACKET_Datasets) {
+ if (pXFANode->GetClassID() == XFA_ELEMENT_DataValue) {
+ for (IFDE_XMLNode *pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
+ if(eNodeType == FDE_XMLNODE_Instruction) {
+ continue;
+ }
+ if (eNodeType == FDE_XMLNODE_Element) {
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataValue);
+ if (pXFAChild == NULL) {
+ return;
+ }
+ CFX_WideString wsNodeStr;
+ ((IFDE_XMLElement*)pXMLChild)->GetLocalTagName(wsNodeStr);
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeStr);
+ CFX_WideString wsChildValue;
+#ifdef XFA_PARSE_HAS_LINEIDENTIFIER
+ XFA_GetPlainTextFromRichText((IFDE_XMLElement*)pXMLChild, wsChildValue);
+#else
+ XFA_ConvertRichTextToPlainText((IFDE_XMLElement*)pXMLChild, wsChildValue);
+#endif
+ if (!wsChildValue.IsEmpty()) {
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsChildValue);
+ }
+ pXFANode->InsertChild(pXFAChild);
+ pXFAChild->SetXMLMappingNode(pXMLChild);
+ pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ break;
+ }
+ }
+ m_pRootNode = pXFANode;
+ } else {
+ m_pRootNode = DataLoader(pXFANode, pXMLNode, TRUE);
+ }
+ } else {
+ if (pXFANode->GetObjectType() == XFA_OBJECTTYPE_ContentNode) {
+ ParseContentNode(pXFANode, pXMLNode, ePacketID);
+ m_pRootNode = pXFANode;
+ } else {
+ m_pRootNode = NormalLoader(pXFANode, pXMLNode, ePacketID);
+ }
+ }
+}
+FX_BOOL XFA_FDEExtension_ResolveNamespaceQualifier(IFDE_XMLElement* pNode, FX_WSTR wsQualifier, CFX_WideString& wsNamespaceURI)
+{
+ if(!pNode) {
+ return FALSE;
+ }
+ IFDE_XMLNode* pFakeRoot = pNode->GetNodeItem(IFDE_XMLNode::Root);
+ CFX_WideString wsNSAttribute;
+ FX_BOOL bRet = FALSE;
+ if(wsQualifier.IsEmpty()) {
+ wsNSAttribute = FX_WSTRC(L"xmlns");
+ bRet = TRUE;
+ } else {
+ wsNSAttribute = FX_WSTRC(L"xmlns:") + wsQualifier;
+ }
+ for(; pNode != pFakeRoot; pNode = (IFDE_XMLElement*)pNode->GetNodeItem(IFDE_XMLNode::Parent)) {
+ if(pNode->GetType() != FDE_XMLNODE_Element) {
+ continue;
+ }
+ if(pNode->HasAttribute(wsNSAttribute)) {
+ pNode->GetString(wsNSAttribute, wsNamespaceURI);
+ return TRUE;
+ }
+ }
+ wsNamespaceURI.Empty();
+ return bRet;
+}
+static inline void XFA_FDEExtension_GetElementTagNamespaceURI(IFDE_XMLElement* pElement, CFX_WideString& wsNamespaceURI)
+{
+ CFX_WideString wsNodeStr;
+ pElement->GetNamespacePrefix(wsNodeStr);
+ if(!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNodeStr, wsNamespaceURI)) {
+ wsNamespaceURI.Empty();
+ }
+}
+static FX_BOOL XFA_FDEExtension_MatchNodeName(IFDE_XMLNode* pNode, FX_WSTR wsLocalTagName, FX_WSTR wsNamespaceURIPrefix, FX_DWORD eMatchFlags = XFA_XDPPACKET_FLAGS_NOMATCH)
+{
+ if(!pNode || pNode->GetType() != FDE_XMLNODE_Element) {
+ return FALSE;
+ }
+ IFDE_XMLElement* pElement = reinterpret_cast<IFDE_XMLElement*>(pNode);
+ CFX_WideString wsNodeStr;
+ pElement->GetLocalTagName(wsNodeStr);
+ if(wsNodeStr != wsLocalTagName) {
+ return FALSE;
+ }
+ XFA_FDEExtension_GetElementTagNamespaceURI(pElement, wsNodeStr);
+ if (eMatchFlags & XFA_XDPPACKET_FLAGS_NOMATCH) {
+ return TRUE;
+ }
+ if(eMatchFlags & XFA_XDPPACKET_FLAGS_PREFIXMATCH) {
+ return wsNodeStr.Left(wsNamespaceURIPrefix.GetLength()) == wsNamespaceURIPrefix;
+ }
+ return wsNodeStr == wsNamespaceURIPrefix;
+}
+static FX_BOOL XFA_FDEExtension_GetAttributeLocalName(FX_WSTR wsAttributeName, CFX_WideString& wsLocalAttrName)
+{
+ CFX_WideString wsAttrName(wsAttributeName);
+ FX_STRSIZE iFind = wsAttrName.Find(L':', 0);
+ if (iFind < 0) {
+ wsLocalAttrName = wsAttrName;
+ return FALSE;
+ } else {
+ wsLocalAttrName = wsAttrName.Right(wsAttrName.GetLength() - iFind - 1);
+ return TRUE;
+ }
+}
+static FX_BOOL XFA_FDEExtension_ResolveAttribute(IFDE_XMLElement *pElement, FX_WSTR wsAttributeName, CFX_WideString& wsLocalAttrName, CFX_WideString& wsNamespaceURI)
+{
+ CFX_WideString wsAttrName(wsAttributeName);
+ CFX_WideString wsNSPrefix;
+ if(XFA_FDEExtension_GetAttributeLocalName(wsAttributeName, wsLocalAttrName)) {
+ wsNSPrefix = wsAttrName.Left(wsAttributeName.GetLength() - wsLocalAttrName.GetLength() - 1);
+ }
+ if(wsLocalAttrName == FX_WSTRC(L"xmlns") || wsNSPrefix == FX_WSTRC(L"xmlns") || wsNSPrefix == FX_WSTRC(L"xml")) {
+ return FALSE;
+ }
+ if(!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNSPrefix, wsNamespaceURI)) {
+ wsNamespaceURI.Empty();
+ return FALSE;
+ }
+ return TRUE;
+}
+static FX_BOOL XFA_FDEExtension_FindAttributeWithNS(IFDE_XMLElement *pElement, FX_WSTR wsLocalAttributeName, FX_WSTR wsNamespaceURIPrefix, CFX_WideString& wsValue, FX_BOOL bMatchNSAsPrefix = FALSE)
+{
+ if(!pElement) {
+ return FALSE;
+ }
+ CFX_WideString wsAttrName;
+ CFX_WideString wsAttrValue;
+ CFX_WideString wsAttrNS;
+ for(FX_INT32 iAttrCount = pElement->CountAttributes(), i = 0; i < iAttrCount; i ++) {
+ pElement->GetAttribute(i, wsAttrName, wsAttrValue);
+ FX_STRSIZE iFind = wsAttrName.Find(L':', 0);
+ CFX_WideString wsNSPrefix;
+ if (iFind < 0) {
+ if(wsLocalAttributeName != wsAttrName) {
+ continue;
+ }
+ } else {
+ if(wsLocalAttributeName != wsAttrName.Right(wsAttrName.GetLength() - iFind - 1)) {
+ continue;
+ }
+ wsNSPrefix = wsAttrName.Left(iFind);
+ }
+ if(!XFA_FDEExtension_ResolveNamespaceQualifier(pElement, wsNSPrefix, wsAttrNS)) {
+ continue;
+ }
+ if(bMatchNSAsPrefix) {
+ if(wsAttrNS.Left(wsNamespaceURIPrefix.GetLength()) != wsNamespaceURIPrefix) {
+ continue;
+ }
+ } else {
+ if(wsAttrNS != wsNamespaceURIPrefix) {
+ continue;
+ }
+ }
+ wsValue = wsAttrValue;
+ return TRUE;
+ }
+ return FALSE;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ switch(ePacketID) {
+ case XFA_XDPPACKET_UNKNOWN:
+ return NULL;
+ case XFA_XDPPACKET_XDP:
+ return ParseAsXDPPacket_XDP(pXMLDocumentNode, ePacketID);
+ case XFA_XDPPACKET_Config:
+ return ParseAsXDPPacket_Config(pXMLDocumentNode, ePacketID);
+ case XFA_XDPPACKET_Template:
+ case XFA_XDPPACKET_Form:
+ return ParseAsXDPPacket_TemplateForm(pXMLDocumentNode, ePacketID);
+ case XFA_XDPPACKET_Datasets:
+ return ParseAsXDPPacket_Data(pXMLDocumentNode, ePacketID);
+ case XFA_XDPPACKET_Xdc:
+ return ParseAsXDPPacket_Xdc(pXMLDocumentNode, ePacketID);
+ case XFA_XDPPACKET_LocaleSet:
+ case XFA_XDPPACKET_ConnectionSet:
+ case XFA_XDPPACKET_SourceSet:
+ return ParseAsXDPPacket_LocaleConnectionSourceSet(pXMLDocumentNode, ePacketID);
+ default:
+ return ParseAsXDPPacket_User(pXMLDocumentNode, ePacketID);
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_XDP(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ if(!XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_XDP)->pName, XFA_GetPacketByIndex(XFA_PACKET_XDP)->pURI, XFA_GetPacketByIndex(XFA_PACKET_XDP)->eFlags)) {
+ return NULL;
+ }
+ CXFA_Node* pXFARootNode = m_pFactory->CreateNode(XFA_XDPPACKET_XDP, XFA_ELEMENT_Xfa);
+ if(!pXFARootNode) {
+ return NULL;
+ }
+ m_pRootNode = pXFARootNode;
+ pXFARootNode->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L"xfa"));
+ {
+ IFDE_XMLElement* pElement = (IFDE_XMLElement*)pXMLDocumentNode;
+ FX_INT32 iAttributeCount = pElement->CountAttributes();
+ for(FX_INT32 i = 0; i < iAttributeCount; i++) {
+ CFX_WideString wsAttriName, wsAttriValue;
+ pElement->GetAttribute(i, wsAttriName, wsAttriValue);
+ if(wsAttriName == FX_WSTRC(L"uuid")) {
+ pXFARootNode->SetCData(XFA_ATTRIBUTE_Uuid, wsAttriValue);
+ } else if(wsAttriName == FX_WSTRC(L"timeStamp")) {
+ pXFARootNode->SetCData(XFA_ATTRIBUTE_TimeStamp, wsAttriValue);
+ }
+ }
+ }
+ IFDE_XMLNode* pXMLConfigDOMRoot = NULL;
+ CXFA_Node* pXFAConfigDOMRoot = NULL;
+ {
+ for (IFDE_XMLNode* pChildItem = pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::FirstChild); pChildItem; pChildItem = pChildItem->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ XFA_LPCPACKETINFO pPacketInfo = XFA_GetPacketByIndex(XFA_PACKET_Config);
+ if(!XFA_FDEExtension_MatchNodeName(pChildItem, pPacketInfo->pName, pPacketInfo->pURI, pPacketInfo->eFlags)) {
+ continue;
+ }
+ if (CXFA_Node * pChildNode = pXFARootNode->GetFirstChildByName(pPacketInfo->uHash)) {
+ return NULL;
+ }
+ pXMLConfigDOMRoot = pChildItem;
+ pXFAConfigDOMRoot = ParseAsXDPPacket_Config(pXMLConfigDOMRoot, XFA_XDPPACKET_Config);
+ pXFARootNode->InsertChild(pXFAConfigDOMRoot, NULL);
+ }
+ }
+ IFDE_XMLNode* pXMLDatasetsDOMRoot = NULL;
+ IFDE_XMLNode* pXMLFormDOMRoot = NULL;
+ {
+ for (IFDE_XMLNode* pChildItem = pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::FirstChild); pChildItem; pChildItem = pChildItem->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if(!pChildItem || pChildItem->GetType() != FDE_XMLNODE_Element) {
+ continue;
+ }
+ if(pChildItem == pXMLConfigDOMRoot) {
+ continue;
+ }
+ IFDE_XMLElement* pElement = reinterpret_cast<IFDE_XMLElement*>(pChildItem);
+ CFX_WideString wsPacketName;
+ pElement->GetLocalTagName(wsPacketName);
+ XFA_LPCPACKETINFO pPacketInfo = XFA_GetPacketByName(wsPacketName);
+ if (pPacketInfo && pPacketInfo->pURI) {
+ if(!XFA_FDEExtension_MatchNodeName(pElement, pPacketInfo->pName, pPacketInfo->pURI, pPacketInfo->eFlags)) {
+ pPacketInfo = NULL;
+ }
+ }
+ XFA_XDPPACKET ePacket = pPacketInfo ? pPacketInfo->eName : XFA_XDPPACKET_USER;
+ if(ePacket == XFA_XDPPACKET_XDP) {
+ continue;
+ }
+ if(ePacket == XFA_XDPPACKET_Datasets) {
+ if (pXMLDatasetsDOMRoot) {
+ pXMLDatasetsDOMRoot = NULL;
+ return NULL;
+ }
+ pXMLDatasetsDOMRoot = pElement;
+ } else if(ePacket == XFA_XDPPACKET_Form) {
+ if (pXMLFormDOMRoot) {
+ pXMLFormDOMRoot = NULL;
+ return NULL;
+ }
+ pXMLFormDOMRoot = pElement;
+ } else {
+ CXFA_Node* pPacketNode = ParseAsXDPPacket(pElement, ePacket);
+ if(pPacketNode) {
+ if (pPacketInfo && (pPacketInfo->eFlags & XFA_XDPPACKET_FLAGS_SUPPORTONE) && pXFARootNode->GetFirstChildByName(pPacketInfo->uHash)) {
+ return NULL;
+ }
+ pXFARootNode->InsertChild(pPacketNode);
+ }
+ }
+ }
+ }
+ if(pXMLDatasetsDOMRoot) {
+ CXFA_Node* pPacketNode = ParseAsXDPPacket(pXMLDatasetsDOMRoot, XFA_XDPPACKET_Datasets);
+ if (pPacketNode) {
+ pXFARootNode->InsertChild(pPacketNode);
+ }
+ }
+ if(pXMLFormDOMRoot) {
+ CXFA_Node* pPacketNode = ParseAsXDPPacket(pXMLFormDOMRoot, XFA_XDPPACKET_Form);
+ if (pPacketNode) {
+ pXFARootNode->InsertChild(pPacketNode);
+ }
+ }
+ pXFARootNode->SetXMLMappingNode(pXMLDocumentNode);
+ return pXFARootNode;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Config(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ if(!XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Config)->pName, XFA_GetPacketByIndex(XFA_PACKET_Config)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Config)->eFlags)) {
+ return NULL;
+ }
+ CXFA_Node* pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Config, XFA_ELEMENT_Config);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_Config)->pName);
+ if(!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+ return NULL;
+ }
+ pNode->SetXMLMappingNode(pXMLDocumentNode);
+ return pNode;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_TemplateForm(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ CXFA_Node* pNode = NULL;
+ if (ePacketID == XFA_XDPPACKET_Template) {
+ if(XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Template)->pName, XFA_GetPacketByIndex(XFA_PACKET_Template)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Template)->eFlags)) {
+ pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Template, XFA_ELEMENT_Template);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_Template)->pName);
+ if(m_bDocumentParser) {
+ CFX_WideString wsNamespaceURI;
+ IFDE_XMLElement* pXMLDocumentElement = (IFDE_XMLElement*)pXMLDocumentNode;
+ pXMLDocumentElement->GetNamespaceURI(wsNamespaceURI);
+ if (wsNamespaceURI.IsEmpty()) {
+ pXMLDocumentElement->GetString((FX_LPCWSTR)(L"xmlns:xfa"), wsNamespaceURI);
+ }
+ pNode->GetDocument()->RecognizeXFAVersionNumber(wsNamespaceURI);
+ }
+ if(!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+ return NULL;
+ }
+ }
+ } else if (ePacketID == XFA_XDPPACKET_Form) {
+ if(XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Form)->pName, XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Form)->eFlags)) {
+ IFDE_XMLElement* pXMLDocumentElement = (IFDE_XMLElement*)pXMLDocumentNode;
+ CFX_WideString wsChecksum;
+ pXMLDocumentElement->GetString((FX_LPCWSTR)L"checksum", wsChecksum);
+#ifdef _XFA_VERIFY_Checksum_
+ if (wsChecksum.GetLength() != 28 || m_pXMLParser->m_dwCheckStatus != 0x03) {
+ return NULL;
+ }
+ IXFA_ChecksumContext *pChecksum = XFA_Checksum_Create();
+ pChecksum->StartChecksum();
+ pChecksum->UpdateChecksum(m_pFileRead, m_pXMLParser->m_nStart[0], m_pXMLParser->m_nSize[0]);
+ pChecksum->UpdateChecksum(m_pFileRead, m_pXMLParser->m_nStart[1], m_pXMLParser->m_nSize[1]);
+ pChecksum->FinishChecksum();
+ CFX_ByteString bsCheck;
+ pChecksum->GetChecksum(bsCheck);
+ pChecksum->Release();
+ if (bsCheck != wsChecksum.UTF8Encode()) {
+ return NULL;
+ }
+#endif
+ pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Form, XFA_ELEMENT_Form);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_Form)->pName);
+ pNode->SetAttribute(XFA_ATTRIBUTE_Checksum, wsChecksum);
+ CXFA_Node* pTemplateRoot = m_pRootNode->GetFirstChildByClass(XFA_ELEMENT_Template);
+ CXFA_Node* pTemplateChosen = pTemplateRoot ? pTemplateRoot->GetFirstChildByClass(XFA_ELEMENT_Subform) : NULL;
+ FX_BOOL bUseAttribute = TRUE;
+ if (pTemplateChosen && pTemplateChosen->GetEnum(XFA_ATTRIBUTE_RestoreState) != XFA_ATTRIBUTEENUM_Auto) {
+ bUseAttribute = FALSE;
+ }
+ if(!NormalLoader(pNode, pXMLDocumentNode, ePacketID, bUseAttribute)) {
+ return NULL;
+ }
+ }
+ }
+ if (pNode) {
+ pNode->SetXMLMappingNode(pXMLDocumentNode);
+ }
+ return pNode;
+}
+static IFDE_XMLNode* XFA_GetDataSetsFromXDP(IFDE_XMLNode* pXMLDocumentNode)
+{
+ if (XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
+ return pXMLDocumentNode;
+ }
+ if (!XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_XDP)->pName, XFA_GetPacketByIndex(XFA_PACKET_XDP)->pURI, XFA_GetPacketByIndex(XFA_PACKET_XDP)->eFlags)) {
+ return NULL;
+ }
+ for(IFDE_XMLNode* pDatasetsNode = pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::FirstChild); pDatasetsNode; pDatasetsNode = pDatasetsNode->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if(!XFA_FDEExtension_MatchNodeName(pDatasetsNode, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
+ continue;
+ }
+ return pDatasetsNode;
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Data(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ IFDE_XMLNode* pDatasetsXMLNode = XFA_GetDataSetsFromXDP(pXMLDocumentNode);
+ if(pDatasetsXMLNode) {
+ CXFA_Node* pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataModel);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pName);
+ if(!DataLoader(pNode, pDatasetsXMLNode, FALSE)) {
+ return NULL;
+ }
+ pNode->SetXMLMappingNode(pDatasetsXMLNode);
+ return pNode;
+ }
+ IFDE_XMLNode* pDataXMLNode = NULL;
+ if (XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, FX_WSTRC(L"data"), XFA_GetPacketByIndex(XFA_PACKET_Datasets)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Datasets)->eFlags)) {
+ ((IFDE_XMLElement*)pXMLDocumentNode)->RemoveAttribute((FX_LPCWSTR)(L"xmlns:xfa"));
+ pDataXMLNode = pXMLDocumentNode;
+ } else {
+ IFDE_XMLElement* pDataElement = IFDE_XMLElement::Create(FX_WSTRC(L"xfa:data"));
+ IFDE_XMLNode* pParentXMLNode = pXMLDocumentNode->GetNodeItem(IFDE_XMLNode::Parent);
+ if (pParentXMLNode) {
+ pParentXMLNode->RemoveChildNode(pXMLDocumentNode);
+ }
+ FXSYS_assert(pXMLDocumentNode->GetType() == FDE_XMLNODE_Element);
+ if (pXMLDocumentNode->GetType() == FDE_XMLNODE_Element) {
+ ((IFDE_XMLElement*)pXMLDocumentNode)->RemoveAttribute((FX_LPCWSTR)(L"xmlns:xfa"));
+ }
+ pDataElement->InsertChildNode(pXMLDocumentNode);
+ pDataXMLNode = pDataElement;
+ }
+ if(pDataXMLNode) {
+ CXFA_Node* pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataGroup);
+ if(!pNode) {
+ if (pDataXMLNode != pXMLDocumentNode) {
+ pDataXMLNode->Release();
+ }
+ return NULL;
+ }
+ CFX_WideString wsLocalName;
+ ((IFDE_XMLElement*)pDataXMLNode)->GetLocalTagName(wsLocalName);
+ pNode->SetCData(XFA_ATTRIBUTE_Name, wsLocalName);
+ if(!DataLoader(pNode, pDataXMLNode, TRUE)) {
+ return NULL;
+ }
+ pNode->SetXMLMappingNode(pDataXMLNode);
+ if (pDataXMLNode != pXMLDocumentNode) {
+ pNode->SetFlag(XFA_NODEFLAG_OwnXMLNode, TRUE, FALSE);
+ }
+ return pNode;
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_LocaleConnectionSourceSet(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ CXFA_Node* pNode = NULL;
+ if (ePacketID == XFA_XDPPACKET_LocaleSet) {
+ if(XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pName, XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pURI, XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->eFlags)) {
+ pNode = m_pFactory->CreateNode(XFA_XDPPACKET_LocaleSet, XFA_ELEMENT_LocaleSet);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_LocaleSet)->pName);
+ if(!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+ return NULL;
+ }
+ }
+ } else if(ePacketID == XFA_XDPPACKET_ConnectionSet) {
+ if(XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pName, XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pURI, XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->eFlags)) {
+ pNode = m_pFactory->CreateNode(XFA_XDPPACKET_ConnectionSet, XFA_ELEMENT_ConnectionSet);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_ConnectionSet)->pName);
+ if(!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+ return NULL;
+ }
+ }
+ } else if(ePacketID == XFA_XDPPACKET_SourceSet) {
+ if(XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pName, XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pURI, XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->eFlags)) {
+ pNode = m_pFactory->CreateNode(XFA_XDPPACKET_SourceSet, XFA_ELEMENT_SourceSet);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_SourceSet)->pName);
+ if(!NormalLoader(pNode, pXMLDocumentNode, ePacketID)) {
+ return NULL;
+ }
+ }
+ }
+ if (pNode) {
+ pNode->SetXMLMappingNode(pXMLDocumentNode);
+ }
+ return pNode;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_Xdc(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ if(XFA_FDEExtension_MatchNodeName(pXMLDocumentNode, XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pName, XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pURI, XFA_GetPacketByIndex(XFA_PACKET_Xdc)->eFlags)) {
+ CXFA_Node* pNode = m_pFactory->CreateNode(XFA_XDPPACKET_Xdc, XFA_ELEMENT_Xdc);
+ if(!pNode) {
+ return NULL;
+ }
+ pNode->SetCData(XFA_ATTRIBUTE_Name, XFA_GetPacketByIndex(XFA_PACKET_Xdc)->pName);
+ pNode->SetXMLMappingNode(pXMLDocumentNode);
+ return pNode;
+ }
+ return NULL;
+}
+CXFA_Node* CXFA_SimpleParser::ParseAsXDPPacket_User(IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID)
+{
+ CXFA_Node* pNode = m_pFactory->CreateNode(XFA_XDPPACKET_XDP, XFA_ELEMENT_Packet);
+ if(!pNode) {
+ return NULL;
+ }
+ CFX_WideString wsName;
+ ((IFDE_XMLElement*)pXMLDocumentNode)->GetLocalTagName(wsName);
+ pNode->SetCData(XFA_ATTRIBUTE_Name, wsName);
+ if(!UserPacketLoader(pNode, pXMLDocumentNode)) {
+ return NULL;
+ }
+ pNode->SetXMLMappingNode(pXMLDocumentNode);
+ return pNode;
+}
+CXFA_Node* CXFA_SimpleParser::UserPacketLoader(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLDoc)
+{
+ return pXFANode;
+}
+static FX_BOOL XFA_FDEExtension_IsStringAllWhitespace(CFX_WideString wsText)
+{
+ wsText.TrimRight(L"\x20\x9\xD\xA");
+ return wsText.IsEmpty();
+}
+CXFA_Node* CXFA_SimpleParser::DataLoader(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLDoc, FX_BOOL bDoTransform )
+{
+ ParseDataGroup(pXFANode, pXMLDoc, XFA_XDPPACKET_Datasets);
+ return pXFANode;
+}
+CXFA_Node* CXFA_SimpleParser::NormalLoader(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLDoc, XFA_XDPPACKET ePacketID, FX_BOOL bUseAttribute)
+{
+ FX_BOOL bOneOfPropertyFound = FALSE;
+ for (IFDE_XMLNode *pXMLChild = pXMLDoc->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ switch (pXMLChild->GetType()) {
+ case FDE_XMLNODE_Element: {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement*)pXMLChild;
+ CFX_WideString wsTagName;
+ pXMLElement->GetLocalTagName(wsTagName);
+ XFA_LPCELEMENTINFO pElemInfo = XFA_GetElementByName(wsTagName);
+ if(!pElemInfo) {
+ continue;
+ }
+ XFA_LPCPROPERTY pPropertyInfo = XFA_GetPropertyOfElement(pXFANode->GetClassID(), pElemInfo->eName, ePacketID);
+ if (pPropertyInfo && ((pPropertyInfo->uFlags & (XFA_PROPERTYFLAG_OneOf | XFA_PROPERTYFLAG_DefaultOneOf)) != 0)) {
+ if (bOneOfPropertyFound) {
+ break;
+ }
+ bOneOfPropertyFound = TRUE;
+ }
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(ePacketID, pElemInfo->eName);
+ if (pXFAChild == NULL) {
+ return NULL;
+ }
+ if (ePacketID == XFA_XDPPACKET_Config) {
+ pXFAChild->SetAttribute(XFA_ATTRIBUTE_Name, wsTagName);
+ }
+ FX_BOOL IsNeedValue = TRUE;
+ for(FX_INT32 i = 0, count = pXMLElement->CountAttributes(); i < count; i++) {
+ CFX_WideString wsAttrQualifiedName;
+ CFX_WideString wsAttrName;
+ CFX_WideString wsAttrValue;
+ pXMLElement->GetAttribute(i, wsAttrQualifiedName, wsAttrValue);
+ XFA_FDEExtension_GetAttributeLocalName(wsAttrQualifiedName, wsAttrName);
+ if(wsAttrName == FX_WSTRC(L"nil") && wsAttrValue == FX_WSTRC(L"true")) {
+ IsNeedValue = FALSE;
+ }
+ XFA_LPCATTRIBUTEINFO lpAttrInfo = XFA_GetAttributeByName(wsAttrName);
+ if(!lpAttrInfo) {
+ continue;
+ }
+ if (!bUseAttribute && lpAttrInfo->eName != XFA_ATTRIBUTE_Name && lpAttrInfo->eName != XFA_ATTRIBUTE_Save) {
+ continue;
+ }
+ pXFAChild->SetAttribute(lpAttrInfo->eName, wsAttrValue);
+ }
+ pXFANode->InsertChild(pXFAChild);
+ if (pElemInfo->eName == XFA_ELEMENT_Validate || pElemInfo->eName == XFA_ELEMENT_Locale) {
+ if (ePacketID == XFA_XDPPACKET_Config) {
+ ParseContentNode(pXFAChild, pXMLElement, ePacketID);
+ } else {
+ NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);
+ }
+ break;
+ }
+ switch(pXFAChild->GetObjectType()) {
+ case XFA_OBJECTTYPE_ContentNode:
+ case XFA_OBJECTTYPE_TextNode:
+ case XFA_OBJECTTYPE_NodeC:
+ case XFA_OBJECTTYPE_NodeV:
+ if(IsNeedValue) {
+ ParseContentNode(pXFAChild, pXMLElement, ePacketID);
+ }
+ break;
+ default:
+ NormalLoader(pXFAChild, pXMLElement, ePacketID, bUseAttribute);
+ break;
+ }
+ }
+ break;
+ case FDE_XMLNODE_Instruction:
+ ParseInstruction(pXFANode, (IFDE_XMLInstruction*)pXMLChild, ePacketID);
+ break;
+ default:
+ break;
+ }
+ }
+ return pXFANode;
+}
+FX_BOOL XFA_RecognizeRichText(IFDE_XMLElement* pRichTextXMLNode)
+{
+ if (pRichTextXMLNode) {
+ CFX_WideString wsNamespaceURI;
+ XFA_FDEExtension_GetElementTagNamespaceURI(pRichTextXMLNode, wsNamespaceURI);
+ if (wsNamespaceURI == FX_WSTRC(L"http://www.w3.org/1999/xhtml")) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+class RichTextNodeVisitor
+{
+public:
+ static inline IFDE_XMLNode* GetFirstChild(IFDE_XMLNode* pNode)
+ {
+ return pNode->GetNodeItem(IFDE_XMLNode::FirstChild);
+ }
+ static inline IFDE_XMLNode* GetNextSibling(IFDE_XMLNode* pNode)
+ {
+ return pNode->GetNodeItem(IFDE_XMLNode::NextSibling);
+ }
+ static inline IFDE_XMLNode* GetParent(IFDE_XMLNode* pNode)
+ {
+ return pNode->GetNodeItem(IFDE_XMLNode::Parent);
+ }
+};
+#ifndef XFA_PARSE_HAS_LINEIDENTIFIER
+void XFA_ConvertRichTextToPlainText(IFDE_XMLElement* pRichTextXMLNode, CFX_WideString& wsOutput)
+{
+ CXFA_NodeIteratorTemplate<IFDE_XMLNode, RichTextNodeVisitor> sIterator(pRichTextXMLNode);
+ CFX_WideTextBuf wsPlainTextBuf;
+ for(IFDE_XMLNode* pNode = sIterator.GetCurrent(); pNode; pNode = sIterator.MoveToNext()) {
+ switch(pNode->GetType()) {
+ case FDE_XMLNODE_Text: {
+ CFX_WideString wsText;
+ ((IFDE_XMLText*)pNode)->GetText(wsText);
+ wsPlainTextBuf << wsText;
+ }
+ break;
+ case FDE_XMLNODE_CharData: {
+ CFX_WideString wsText;
+ ((IFDE_XMLCharData*)pNode)->GetCharData(wsText);
+ wsPlainTextBuf << wsText;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ wsOutput = wsPlainTextBuf.GetWideString();
+}
+#endif
+void XFA_ConvertXMLToPlainText(IFDE_XMLElement* pRootXMLNode, CFX_WideString& wsOutput)
+{
+ for (IFDE_XMLNode *pXMLChild = pRootXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+#ifdef _DEBUG
+ FDE_XMLNODETYPE nodeType = pXMLChild->GetType();
+#endif
+ switch(pXMLChild->GetType()) {
+ case FDE_XMLNODE_Element: {
+ CFX_WideString wsTextData;
+ ((IFDE_XMLElement*)pXMLChild)->GetTextData(wsTextData);
+ wsTextData += FX_WSTRC(L"\n");
+ wsOutput += wsTextData;
+ }
+ break;
+ case FDE_XMLNODE_Text: {
+ CFX_WideString wsText;
+ ((IFDE_XMLText*)pXMLChild)->GetText(wsText);
+ if (XFA_FDEExtension_IsStringAllWhitespace(wsText)) {
+ continue;
+ } else {
+ wsOutput = wsText;
+ }
+ }
+ break;
+ case FDE_XMLNODE_CharData: {
+ CFX_WideString wsCharData;
+ ((IFDE_XMLCharData*)pXMLChild)->GetCharData(wsCharData);
+ if (XFA_FDEExtension_IsStringAllWhitespace(wsCharData)) {
+ continue;
+ } else {
+ wsOutput = wsCharData;
+ }
+ }
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+}
+void CXFA_SimpleParser::ParseContentNode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode, XFA_XDPPACKET ePacketID)
+{
+ XFA_ELEMENT element = XFA_ELEMENT_Sharptext;
+ if (pXFANode->GetClassID() == XFA_ELEMENT_ExData) {
+ CFX_WideStringC wsContentType = pXFANode->GetCData(XFA_ATTRIBUTE_ContentType);
+ if (wsContentType == FX_WSTRC(L"text/html")) {
+ element = XFA_ELEMENT_SharpxHTML;
+ } else if (wsContentType == FX_WSTRC(L"text/xml")) {
+ element = XFA_ELEMENT_Sharpxml;
+ }
+ }
+ if (element == XFA_ELEMENT_SharpxHTML) {
+ pXFANode->SetXMLMappingNode(pXMLNode);
+ }
+ CFX_WideString wsValue;
+ for (IFDE_XMLNode *pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
+ if(eNodeType == FDE_XMLNODE_Instruction) {
+ continue;
+ }
+ if(element == XFA_ELEMENT_SharpxHTML) {
+ if(eNodeType != FDE_XMLNODE_Element) {
+ break;
+ }
+ if (XFA_RecognizeRichText((IFDE_XMLElement*)pXMLChild)) {
+#ifdef XFA_PARSE_HAS_LINEIDENTIFIER
+ XFA_GetPlainTextFromRichText((IFDE_XMLElement*)pXMLChild, wsValue);
+#else
+ XFA_ConvertRichTextToPlainText((IFDE_XMLElement*)pXMLChild, wsValue);
+#endif
+ }
+ } else if (element == XFA_ELEMENT_Sharpxml) {
+ if(eNodeType != FDE_XMLNODE_Element) {
+ break;
+ }
+ XFA_ConvertXMLToPlainText((IFDE_XMLElement*)pXMLChild, wsValue);
+ } else {
+ if(eNodeType == FDE_XMLNODE_Element) {
+ break;
+ }
+ if(eNodeType == FDE_XMLNODE_Text) {
+ ((IFDE_XMLText*)pXMLChild)->GetText(wsValue);
+ } else if(eNodeType == FDE_XMLNODE_CharData) {
+ ((IFDE_XMLCharData*)pXMLChild)->GetCharData(wsValue);
+ }
+ }
+ break;
+ }
+ if(!wsValue.IsEmpty()) {
+ if (pXFANode->GetObjectType() == XFA_OBJECTTYPE_ContentNode) {
+ CXFA_Node *pContentRawDataNode = m_pFactory->CreateNode(ePacketID, element);
+ FXSYS_assert(pContentRawDataNode);
+ pContentRawDataNode->SetCData(XFA_ATTRIBUTE_Value, wsValue);
+ pXFANode->InsertChild(pContentRawDataNode);
+ } else {
+ pXFANode->SetCData(XFA_ATTRIBUTE_Value, wsValue);
+ }
+ }
+}
+void CXFA_SimpleParser::ParseDataGroup(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode, XFA_XDPPACKET ePacketID)
+{
+ for (IFDE_XMLNode *pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ switch (pXMLChild->GetType()) {
+ case FDE_XMLNODE_Element: {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement*)pXMLChild;
+ {
+ CFX_WideString wsNamespaceURI;
+ XFA_FDEExtension_GetElementTagNamespaceURI(pXMLElement, wsNamespaceURI);
+ if(wsNamespaceURI == FX_WSTRC(L"http://www.xfa.com/schema/xfa-package/") ||
+ wsNamespaceURI == FX_WSTRC(L"http://www.xfa.org/schema/xfa-package/") ||
+ wsNamespaceURI == FX_WSTRC(L"http://www.w3.org/2001/XMLSchema-instance")) {
+ continue;
+ }
+ if(0) {
+ continue;
+ }
+ }
+ XFA_ELEMENT eNodeType = XFA_ELEMENT_DataModel;
+ if (eNodeType == XFA_ELEMENT_DataModel) {
+ CFX_WideString wsDataNodeAttr;
+ if(XFA_FDEExtension_FindAttributeWithNS(pXMLElement, FX_WSTRC(L"dataNode"), FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"), wsDataNodeAttr)) {
+ if (wsDataNodeAttr == FX_WSTRC(L"dataGroup")) {
+ eNodeType = XFA_ELEMENT_DataGroup;
+ } else if (wsDataNodeAttr == FX_WSTRC(L"dataValue")) {
+ eNodeType = XFA_ELEMENT_DataValue;
+ }
+ }
+ }
+ CFX_WideString wsContentType;
+ if (eNodeType == XFA_ELEMENT_DataModel) {
+ if(XFA_FDEExtension_FindAttributeWithNS(pXMLElement, FX_WSTRC(L"contentType"), FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/"), wsContentType)) {
+ if (!wsContentType.IsEmpty()) {
+ eNodeType = XFA_ELEMENT_DataValue;
+ }
+ }
+ }
+ if (eNodeType == XFA_ELEMENT_DataModel) {
+ for (IFDE_XMLNode *pXMLDataChild = pXMLElement->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLDataChild; pXMLDataChild = pXMLDataChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ if(pXMLDataChild->GetType() == FDE_XMLNODE_Element) {
+ if (!XFA_RecognizeRichText((IFDE_XMLElement*)pXMLDataChild)) {
+ eNodeType = XFA_ELEMENT_DataGroup;
+ break;
+ }
+ }
+ }
+ }
+ if (eNodeType == XFA_ELEMENT_DataModel) {
+ eNodeType = XFA_ELEMENT_DataValue;
+ }
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, eNodeType);
+ if (pXFAChild == NULL) {
+ return;
+ }
+ CFX_WideString wsNodeName;
+ pXMLElement->GetLocalTagName(wsNodeName);
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeName);
+ FX_BOOL bNeedValue = TRUE;
+ if (1) {
+ for(FX_INT32 i = 0, count = pXMLElement->CountAttributes(); i < count; i++) {
+ CFX_WideString wsAttrQualifiedName;
+ CFX_WideString wsAttrValue;
+ CFX_WideString wsAttrName;
+ CFX_WideString wsAttrNamespaceURI;
+ pXMLElement->GetAttribute(i, wsAttrQualifiedName, wsAttrValue);
+ if(!XFA_FDEExtension_ResolveAttribute(pXMLElement, wsAttrQualifiedName, wsAttrName, wsAttrNamespaceURI)) {
+ continue;
+ }
+ if(wsAttrName == FX_WSTRC(L"nil") && wsAttrValue == FX_WSTRC(L"true")) {
+ bNeedValue = FALSE;
+ continue;
+ }
+ if(wsAttrNamespaceURI == FX_WSTRC(L"http://www.xfa.com/schema/xfa-package/") ||
+ wsAttrNamespaceURI == FX_WSTRC(L"http://www.xfa.org/schema/xfa-package/") ||
+ wsAttrNamespaceURI == FX_WSTRC(L"http://www.w3.org/2001/XMLSchema-instance") ||
+ wsAttrNamespaceURI == FX_WSTRC(L"http://www.xfa.org/schema/xfa-data/1.0/")) {
+ continue;
+ }
+ if(0) {
+ continue;
+ }
+ CXFA_Node *pXFAMetaData = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataValue);
+ if (pXFAMetaData == NULL) {
+ return;
+ }
+ pXFAMetaData->SetCData(XFA_ATTRIBUTE_Name, wsAttrName);
+ pXFAMetaData->SetCData(XFA_ATTRIBUTE_QualifiedName, wsAttrQualifiedName);
+ pXFAMetaData->SetCData(XFA_ATTRIBUTE_Value, wsAttrValue);
+ pXFAMetaData->SetEnum(XFA_ATTRIBUTE_Contains, XFA_ATTRIBUTEENUM_MetaData);
+ pXFAChild->InsertChild(pXFAMetaData);
+ pXFAMetaData->SetXMLMappingNode(pXMLElement);
+ pXFAMetaData->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ }
+ if(!bNeedValue) {
+ CFX_WideString wsNilName = FX_WSTRC(L"xsi:nil");
+ pXMLElement->RemoveAttribute(wsNilName);
+ }
+ }
+ pXFANode->InsertChild(pXFAChild);
+ if (eNodeType == XFA_ELEMENT_DataGroup) {
+ ParseDataGroup(pXFAChild, pXMLElement, ePacketID);
+ } else {
+ if(bNeedValue) {
+ ParseDataValue(pXFAChild, pXMLChild, XFA_XDPPACKET_Datasets);
+ }
+ }
+ pXFAChild->SetXMLMappingNode(pXMLElement);
+ pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ }
+ continue;
+ case FDE_XMLNODE_CharData: {
+ IFDE_XMLCharData *pXMLCharData = (IFDE_XMLCharData*)pXMLChild;
+ CFX_WideString wsCharData;
+ pXMLCharData->GetCharData(wsCharData);
+ if (XFA_FDEExtension_IsStringAllWhitespace(wsCharData)) {
+ continue;
+ }
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataValue);
+ if (pXFAChild == NULL) {
+ return;
+ }
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCharData);
+ pXFANode->InsertChild(pXFAChild);
+ pXFAChild->SetXMLMappingNode(pXMLCharData);
+ pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ }
+ continue;
+ case FDE_XMLNODE_Text: {
+ IFDE_XMLText *pXMLText = (IFDE_XMLText*)pXMLChild;
+ CFX_WideString wsText;
+ pXMLText->GetText(wsText);
+ if (XFA_FDEExtension_IsStringAllWhitespace(wsText)) {
+ continue;
+ }
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(XFA_XDPPACKET_Datasets, XFA_ELEMENT_DataValue);
+ if (pXFAChild == NULL) {
+ return;
+ }
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsText);
+ pXFANode->InsertChild(pXFAChild);
+ pXFAChild->SetXMLMappingNode(pXMLText);
+ pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ }
+ continue;
+ case FDE_XMLNODE_Instruction:
+ continue;
+ default:
+ continue;
+ }
+ }
+}
+void CXFA_SimpleParser::ParseDataValue(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode, XFA_XDPPACKET ePacketID)
+{
+ CFX_WideTextBuf wsValueTextBuf;
+ CFX_WideTextBuf wsCurValueTextBuf;
+ FX_BOOL bMarkAsCompound = FALSE;
+ IFDE_XMLNode *pXMLCurValueNode = NULL;
+ for (IFDE_XMLNode *pXMLChild = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pXMLChild; pXMLChild = pXMLChild->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ FDE_XMLNODETYPE eNodeType = pXMLChild->GetType();
+ if(eNodeType == FDE_XMLNODE_Instruction) {
+ continue;
+ }
+ CFX_WideString wsText;
+ FX_BOOL bBreak = FALSE;
+ if(eNodeType == FDE_XMLNODE_Text) {
+ ((IFDE_XMLText*)pXMLChild)->GetText(wsText);
+ if(!pXMLCurValueNode) {
+ pXMLCurValueNode = pXMLChild;
+ }
+ wsCurValueTextBuf << wsText;
+ } else if(eNodeType == FDE_XMLNODE_CharData) {
+ ((IFDE_XMLCharData*)pXMLChild)->GetCharData(wsText);
+ if(!pXMLCurValueNode) {
+ pXMLCurValueNode = pXMLChild;
+ }
+ wsCurValueTextBuf << wsText;
+ } else if(XFA_RecognizeRichText((IFDE_XMLElement*)pXMLChild)) {
+#ifdef XFA_PARSE_HAS_LINEIDENTIFIER
+ XFA_GetPlainTextFromRichText((IFDE_XMLElement*)pXMLChild, wsText);
+#else
+ XFA_ConvertRichTextToPlainText((IFDE_XMLElement*)pXMLChild, wsText);
+#endif
+ if(!pXMLCurValueNode) {
+ pXMLCurValueNode = pXMLChild;
+ }
+ wsCurValueTextBuf << wsText;
+ } else {
+ bMarkAsCompound = TRUE;
+ if(pXMLCurValueNode) {
+ CFX_WideStringC wsCurValue = wsCurValueTextBuf.GetWideString();
+ if(!wsCurValue.IsEmpty()) {
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(ePacketID, XFA_ELEMENT_DataValue);
+ if (pXFAChild == NULL) {
+ return;
+ }
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L""));
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCurValue);
+ pXFANode->InsertChild(pXFAChild);
+ pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
+ pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ wsValueTextBuf << wsCurValue;
+ wsCurValueTextBuf.Clear();
+ }
+ pXMLCurValueNode = NULL;
+ }
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(ePacketID, XFA_ELEMENT_DataValue);
+ if (pXFAChild == NULL) {
+ return;
+ }
+ CFX_WideString wsNodeStr;
+ ((IFDE_XMLElement*)pXMLChild)->GetLocalTagName(wsNodeStr);
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Name, wsNodeStr);
+ ParseDataValue(pXFAChild, pXMLChild, ePacketID);
+ pXFANode->InsertChild(pXFAChild);
+ pXFAChild->SetXMLMappingNode(pXMLChild);
+ pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ CFX_WideStringC wsCurValue = pXFAChild->GetCData(XFA_ATTRIBUTE_Value);
+ wsValueTextBuf << wsCurValue;
+ }
+ }
+ if(pXMLCurValueNode) {
+ CFX_WideStringC wsCurValue = wsCurValueTextBuf.GetWideString();
+ if(!wsCurValue.IsEmpty()) {
+ if(bMarkAsCompound) {
+ CXFA_Node *pXFAChild = m_pFactory->CreateNode(ePacketID, XFA_ELEMENT_DataValue);
+ if (pXFAChild == NULL) {
+ return;
+ }
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Name, FX_WSTRC(L""));
+ pXFAChild->SetCData(XFA_ATTRIBUTE_Value, wsCurValue);
+ pXFANode->InsertChild(pXFAChild);
+ pXFAChild->SetXMLMappingNode(pXMLCurValueNode);
+ pXFAChild->SetFlag(XFA_NODEFLAG_Initialized, TRUE, FALSE);
+ }
+ wsValueTextBuf << wsCurValue;
+ wsCurValueTextBuf.Clear();
+ }
+ pXMLCurValueNode = NULL;
+ }
+ CFX_WideStringC wsNodeValue = wsValueTextBuf.GetWideString();
+ pXFANode->SetCData(XFA_ATTRIBUTE_Value, wsNodeValue);
+}
+void CXFA_SimpleParser::ParseInstruction(CXFA_Node *pXFANode, IFDE_XMLInstruction *pXMLInstruction, XFA_XDPPACKET ePacketID)
+{
+ if(!m_bDocumentParser) {
+ return;
+ }
+ CFX_WideString wsTargetName;
+ pXMLInstruction->GetTargetName(wsTargetName);
+ FX_INT32 iDataCount = pXMLInstruction->CountData();
+ if (wsTargetName == FX_WSTRC(L"originalXFAVersion")) {
+ CFX_WideString wsData;
+ if(pXMLInstruction->GetData(0, wsData) && (pXFANode->GetDocument()->RecognizeXFAVersionNumber(wsData) != XFA_VERSION_UNKNOWN)) {
+ wsData.Empty();
+ if (pXMLInstruction->GetData(1, wsData) && wsData == FX_WSTRC(L"v2.7-scripting:1")) {
+ pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_Scripting, TRUE);
+ }
+ }
+ } else if (wsTargetName == FX_WSTRC(L"acrobat")) {
+ CFX_WideString wsData;
+ if (pXMLInstruction->GetData(0, wsData) && wsData == FX_WSTRC(L"JavaScript")) {
+ if (pXMLInstruction->GetData(1, wsData) && wsData == FX_WSTRC(L"strictScoping")) {
+ pXFANode->GetDocument()->SetFlag(XFA_DOCFLAG_StrictScoping, TRUE);
+ }
+ }
+ }
+}
+void CXFA_SimpleParser::CloseParser()
+{
+ if (m_pXMLDoc) {
+ m_pXMLDoc->Release();
+ m_pXMLDoc = NULL;
+ }
+ if (m_pStream) {
+ m_pStream->Release();
+ m_pStream = NULL;
+ }
+}
+IXFA_DocParser* IXFA_DocParser::Create(IXFA_Notify *pNotify)
+{
+ return FX_NEW CXFA_DocumentParser(pNotify);
+}
+CXFA_DocumentParser::CXFA_DocumentParser(IXFA_Notify *pNotify)
+ : m_pNotify(pNotify)
+ , m_nodeParser(NULL, TRUE)
+ , m_pDocument(NULL)
+{
+}
+CXFA_DocumentParser::~CXFA_DocumentParser()
+{
+ CloseParser();
+}
+FX_INT32 CXFA_DocumentParser::StartParse(IFX_FileRead *pStream, XFA_XDPPACKET ePacketID )
+{
+ CloseParser();
+ FX_INT32 nRetStatus = m_nodeParser.StartParse(pStream, ePacketID);
+ if(nRetStatus == XFA_PARSESTATUS_Ready) {
+ m_pDocument = FX_NEW CXFA_Document(this);
+ m_nodeParser.SetFactory(m_pDocument);
+ }
+ return nRetStatus;
+}
+FX_INT32 CXFA_DocumentParser::DoParse(IFX_Pause *pPause )
+{
+ FX_INT32 nRetStatus = m_nodeParser.DoParse(pPause);
+ if (nRetStatus >= XFA_PARSESTATUS_Done) {
+ FXSYS_assert(m_pDocument);
+ m_pDocument->SetRoot(m_nodeParser.GetRootNode());
+ }
+ return nRetStatus;
+}
+FX_INT32 CXFA_DocumentParser::ParseXMLData(const CFX_WideString &wsXML, IFDE_XMLNode* &pXMLNode, IFX_Pause *pPause)
+{
+ CloseParser();
+ FX_INT32 nRetStatus = m_nodeParser.ParseXMLData(wsXML, pXMLNode, NULL);
+ if(nRetStatus == XFA_PARSESTATUS_Done && pXMLNode) {
+ m_pDocument = FX_NEW CXFA_Document(this);
+ m_nodeParser.SetFactory(m_pDocument);
+ }
+ return nRetStatus;
+}
+void CXFA_DocumentParser::ConstructXFANode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode)
+{
+ if (!pXFANode || !pXMLNode) {
+ return;
+ }
+ m_nodeParser.ConstructXFANode(pXFANode, pXMLNode);
+ CXFA_Node* pRootNode = m_nodeParser.GetRootNode();
+ if (m_pDocument && pRootNode) {
+ m_pDocument->SetRoot(pRootNode);
+ }
+}
+void CXFA_DocumentParser::CloseParser()
+{
+ if (m_pDocument) {
+ delete m_pDocument;
+ m_pDocument = NULL;
+ }
+ m_nodeParser.CloseParser();
+}
+CXFA_XMLParser::CXFA_XMLParser(IFDE_XMLNode *pRoot, IFX_Stream *pStream)
+ : m_pRoot(pRoot)
+ , m_pStream(pStream)
+ , m_pParser(NULL)
+ , m_dwStatus(FDE_XMLSYNTAXSTATUS_None)
+ , m_pParent(pRoot)
+ , m_pChild(NULL)
+ , m_NodeStack(16)
+ , m_ws1()
+ , m_ws2()
+#ifdef _XFA_VERIFY_Checksum_
+ , m_nElementStart(0)
+ , m_dwCheckStatus(0)
+ , m_dwCurrentCheckStatus(0)
+#endif
+{
+ ASSERT(m_pParent && m_pStream);
+ m_NodeStack.Push(m_pParent);
+ m_pParser = IFDE_XMLSyntaxParser::Create();
+ m_pParser->Init(m_pStream, 32 * 1024, 1024 * 1024);
+}
+CXFA_XMLParser::~CXFA_XMLParser()
+{
+ if (m_pParser) {
+ m_pParser->Release();
+ }
+ m_NodeStack.RemoveAll();
+ m_ws1.Empty();
+ m_ws2.Empty();
+}
+FX_INT32 CXFA_XMLParser::DoParser(IFX_Pause *pPause)
+{
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) {
+ return -1;
+ }
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ return 100;
+ }
+ FX_INT32 iCount = 0;
+ while (TRUE) {
+ m_dwStatus = m_pParser->DoSyntaxParse();
+ switch (m_dwStatus) {
+ case FDE_XMLSYNTAXSTATUS_InstructionOpen:
+ break;
+ case FDE_XMLSYNTAXSTATUS_InstructionClose:
+ if (m_pChild) {
+ if (m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ }
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementOpen:
+#ifdef _XFA_VERIFY_Checksum_
+ if (m_dwCheckStatus != 0x03 && m_NodeStack.GetSize() == 2) {
+ m_nElementStart = m_pParser->GetCurrentPos() - 1;
+ }
+#endif
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementBreak:
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementClose:
+ if (m_pChild->GetType() != FDE_XMLNODE_Element) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParser->GetTagName(m_ws1);
+ ((IFDE_XMLElement*)m_pChild)->GetTagName(m_ws2);
+ if (m_ws1.GetLength() > 0 && !m_ws1.Equal(m_ws2)) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_NodeStack.Pop();
+ if (m_NodeStack.GetSize() < 1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+#ifdef _XFA_VERIFY_Checksum_
+ else if (m_dwCurrentCheckStatus != 0 && m_NodeStack.GetSize() == 2) {
+ m_nSize[m_dwCurrentCheckStatus - 1] = m_pParser->GetCurrentBinaryPos() - m_nStart[m_dwCurrentCheckStatus - 1];
+ m_dwCurrentCheckStatus = 0;
+ }
+#endif
+ m_pParent = (IFDE_XMLNode*)*m_NodeStack.GetTopElement();
+ m_pChild = m_pParent;
+ iCount++;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetName:
+ m_pParser->GetTargetName(m_ws1);
+ if (m_ws1 == FX_WSTRC(L"originalXFAVersion") || m_ws1 == FX_WSTRC(L"acrobat")) {
+ m_pChild = IFDE_XMLInstruction::Create(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ } else {
+ m_pChild = NULL;
+ }
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_TagName:
+ m_pParser->GetTagName(m_ws1);
+ m_pChild = IFDE_XMLElement::Create(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_NodeStack.Push(m_pChild);
+ m_pParent = m_pChild;
+#ifdef _XFA_VERIFY_Checksum_
+ if (m_dwCheckStatus != 0x03 && m_NodeStack.GetSize() == 3) {
+ CFX_WideString wsTag;
+ ((IFDE_XMLElement*)m_pChild)->GetLocalTagName(wsTag);
+ if (wsTag == FX_WSTRC(L"template")) {
+ m_dwCheckStatus |= 0x01;
+ m_dwCurrentCheckStatus = 0x01;
+ m_nStart[0] = m_pParser->GetCurrentBinaryPos() - (m_pParser->GetCurrentPos() - m_nElementStart);
+ } else if (wsTag == FX_WSTRC(L"datasets")) {
+ m_dwCheckStatus |= 0x02;
+ m_dwCurrentCheckStatus = 0x02;
+ m_nStart[1] = m_pParser->GetCurrentBinaryPos() - (m_pParser->GetCurrentPos() - m_nElementStart);
+ }
+ }
+#endif
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriName:
+ m_pParser->GetAttributeName(m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriValue:
+ if (m_pChild) {
+ m_pParser->GetAttributeName(m_ws2);
+ if (m_pChild->GetType() == FDE_XMLNODE_Element) {
+ ((IFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2);
+ }
+ }
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_Text:
+ m_pParser->GetTextData(m_ws1);
+ m_pChild = IFDE_XMLText::Create(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_CData:
+ m_pParser->GetTextData(m_ws1);
+ m_pChild = IFDE_XMLCharData::Create(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetData:
+ if (m_pChild) {
+ if (m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ if (!m_ws1.IsEmpty()) {
+ ((IFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+ }
+ m_pParser->GetTargetData(m_ws1);
+ ((IFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+ }
+ m_ws1.Empty();
+ break;
+ default:
+ break;
+ }
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ break;
+ }
+ if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) {
+ break;
+ }
+ }
+ return (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_NodeStack.GetSize() != 1) ? -1 : m_pParser->GetStatus();
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_parser_imp.h b/xfa/src/fxfa/src/parser/xfa_parser_imp.h
new file mode 100644
index 0000000000..41b1462b94
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_parser_imp.h
@@ -0,0 +1,137 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_PARSER_IMP
+#define _XFA_PARSER_IMP
+#define _XFA_VERIFY_Checksum_
+class CXFA_XMLParser;
+class CXFA_SimpleParser : public IXFA_Parser, public CFX_Object
+{
+public:
+ CXFA_SimpleParser(IXFA_ObjFactory *pFactory, FX_BOOL bDocumentParser = FALSE);
+ ~CXFA_SimpleParser();
+ virtual void Release()
+ {
+ delete this;
+ }
+
+ virtual FX_INT32 StartParse(IFX_FileRead *pStream, XFA_XDPPACKET ePacketID = XFA_XDPPACKET_XDP);
+ virtual FX_INT32 DoParse(IFX_Pause *pPause = NULL);
+ virtual FX_INT32 ParseXMLData(const CFX_WideString &wsXML, IFDE_XMLNode* &pXMLNode, IFX_Pause *pPause = NULL);
+ virtual void ConstructXFANode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode);
+ virtual IXFA_ObjFactory* GetFactory() const
+ {
+ return m_pFactory;
+ }
+ virtual CXFA_Node* GetRootNode() const
+ {
+ return m_pRootNode;
+ }
+ virtual IFDE_XMLDoc* GetXMLDoc() const
+ {
+ return m_pXMLDoc;
+ }
+ virtual void CloseParser();
+protected:
+ CXFA_Node* ParseAsXDPPacket (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* ParseAsXDPPacket_XDP (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* ParseAsXDPPacket_Config (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* ParseAsXDPPacket_TemplateForm (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* ParseAsXDPPacket_Data (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* ParseAsXDPPacket_LocaleConnectionSourceSet (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* ParseAsXDPPacket_Xdc (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* ParseAsXDPPacket_User (IFDE_XMLNode* pXMLDocumentNode, XFA_XDPPACKET ePacketID);
+ CXFA_Node* NormalLoader (CXFA_Node* pXFANode, IFDE_XMLNode* pXMLDoc, XFA_XDPPACKET ePacketID, FX_BOOL bUseAttribute = TRUE);
+ CXFA_Node* DataLoader (CXFA_Node* pXFANode, IFDE_XMLNode* pXMLDoc, FX_BOOL bDoTransform);
+ CXFA_Node* UserPacketLoader (CXFA_Node* pXFANode, IFDE_XMLNode* pXMLDoc);
+ void ParseContentNode (CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode, XFA_XDPPACKET ePacketID);
+ void ParseDataValue (CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode, XFA_XDPPACKET ePacketID);
+ void ParseDataGroup (CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode, XFA_XDPPACKET ePacketID);
+ void ParseInstruction (CXFA_Node *pXFANode, IFDE_XMLInstruction *pXMLInstruction, XFA_XDPPACKET ePacketID);
+protected:
+ void SetFactory (IXFA_ObjFactory* pFactory);
+ CXFA_XMLParser* m_pXMLParser;
+ IFDE_XMLDoc* m_pXMLDoc;
+ IFX_Stream* m_pStream;
+ IFX_FileRead* m_pFileRead;
+ IXFA_ObjFactory* m_pFactory;
+ CXFA_Node* m_pRootNode;
+ XFA_XDPPACKET m_ePacketID;
+ FX_BOOL m_bDocumentParser;
+ friend class CXFA_DocumentParser;
+};
+class CXFA_DocumentParser : public IXFA_DocParser, public CFX_Object
+{
+public:
+ CXFA_DocumentParser(IXFA_Notify *pNotify);
+ ~CXFA_DocumentParser();
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_INT32 StartParse(IFX_FileRead *pStream, XFA_XDPPACKET ePacketID = XFA_XDPPACKET_XDP);
+ virtual FX_INT32 DoParse(IFX_Pause *pPause = NULL);
+ virtual FX_INT32 ParseXMLData(const CFX_WideString &wsXML, IFDE_XMLNode* &pXMLNode, IFX_Pause *pPause = NULL);
+ virtual void ConstructXFANode(CXFA_Node* pXFANode, IFDE_XMLNode* pXMLNode);
+ virtual IXFA_ObjFactory* GetFactory() const
+ {
+ return m_nodeParser.GetFactory();
+ }
+ virtual CXFA_Node* GetRootNode() const
+ {
+ return m_nodeParser.GetRootNode();
+ }
+ virtual IFDE_XMLDoc* GetXMLDoc() const
+ {
+ return m_nodeParser.GetXMLDoc();
+ }
+ virtual IXFA_Notify* GetNotify() const
+ {
+ return m_pNotify;
+ }
+ virtual CXFA_Document* GetDocument() const
+ {
+ return m_pDocument;
+ }
+ virtual void CloseParser();
+protected:
+ CXFA_SimpleParser m_nodeParser;
+ IXFA_Notify* m_pNotify;
+ CXFA_Document* m_pDocument;
+};
+typedef CFX_StackTemplate<IFDE_XMLNode*> CXFA_XMLNodeStack;
+class CXFA_XMLParser : public IFDE_XMLParser, public CFX_Object
+{
+public:
+ CXFA_XMLParser(IFDE_XMLNode *pRoot, IFX_Stream *pStream);
+ ~CXFA_XMLParser();
+
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_INT32 DoParser(IFX_Pause *pPause);
+protected:
+ IFDE_XMLNode *m_pRoot;
+ IFX_Stream *m_pStream;
+ IFDE_XMLSyntaxParser *m_pParser;
+
+ IFDE_XMLNode *m_pParent;
+ IFDE_XMLNode *m_pChild;
+ CXFA_XMLNodeStack m_NodeStack;
+ CFX_WideString m_ws1;
+ CFX_WideString m_ws2;
+ FX_DWORD m_dwStatus;
+#ifdef _XFA_VERIFY_Checksum_
+public:
+ FX_FILESIZE m_nStart[2];
+ size_t m_nSize[2];
+ FX_FILESIZE m_nElementStart;
+ FX_WORD m_dwCheckStatus;
+ FX_WORD m_dwCurrentCheckStatus;
+#endif
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_datawindow.cpp b/xfa/src/fxfa/src/parser/xfa_script_datawindow.cpp
new file mode 100644
index 0000000000..dc393d7c9b
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_datawindow.cpp
@@ -0,0 +1,51 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_datawindow.h"
+CScript_DataWindow::CScript_DataWindow(CXFA_Document* pDocument)
+ : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_DataWindow)
+{
+ m_uScriptHash = XFA_HASHCODE_DataWindow;
+}
+CScript_DataWindow::~CScript_DataWindow()
+{
+}
+void CScript_DataWindow::Script_DataWindow_MoveCurrentRecord(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_DataWindow::Script_DataWindow_Record(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_DataWindow::Script_DataWindow_GotoRecord(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_DataWindow::Script_DataWindow_IsRecordGroup(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_DataWindow::Script_DataWindow_RecordsBefore(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CScript_DataWindow::Script_DataWindow_CurrentRecordNumber(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CScript_DataWindow::Script_DataWindow_RecordsAfter(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
+void CScript_DataWindow::Script_DataWindow_IsDefined(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_datawindow.h b/xfa/src/fxfa/src/parser/xfa_script_datawindow.h
new file mode 100644
index 0000000000..48fd416826
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_datawindow.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _SCRIPT_DATAWINDOW_H_
+#define _SCRIPT_DATAWINDOW_H_
+class CScript_DataWindow : public CXFA_OrdinaryObject
+{
+public:
+ CScript_DataWindow(CXFA_Document* pDocument);
+ virtual ~CScript_DataWindow();
+ void Script_DataWindow_MoveCurrentRecord(CFXJSE_Arguments* pArguments);
+ void Script_DataWindow_Record(CFXJSE_Arguments* pArguments);
+ void Script_DataWindow_GotoRecord(CFXJSE_Arguments* pArguments);
+ void Script_DataWindow_IsRecordGroup(CFXJSE_Arguments* pArguments);
+ void Script_DataWindow_RecordsBefore(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_DataWindow_CurrentRecordNumber(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_DataWindow_RecordsAfter(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_DataWindow_IsDefined(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.cpp b/xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.cpp
new file mode 100644
index 0000000000..fb83349961
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.cpp
@@ -0,0 +1,218 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_eventpseudomodel.h"
+CScript_EventPseudoModel::CScript_EventPseudoModel(CXFA_Document* pDocument)
+ : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_EventPseudoModel)
+{
+ m_uScriptHash = XFA_HASHCODE_Event;
+}
+CScript_EventPseudoModel::~CScript_EventPseudoModel()
+{
+}
+void Script_EventPseudoModel_StringProperty(FXJSE_HVALUE hValue, CFX_WideString& wsValue, FX_BOOL bSetting)
+{
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ wsValue = CFX_WideString::FromUTF8(bsValue, bsValue.GetLength());
+ } else {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+ }
+}
+void Script_EventPseudoModel_InterProperty(FXJSE_HVALUE hValue, FX_INT32& iValue, FX_BOOL bSetting)
+{
+ if (bSetting) {
+ iValue = FXJSE_Value_ToInteger(hValue);
+ } else {
+ FXJSE_Value_SetInteger(hValue, iValue);
+ }
+}
+void Script_EventPseudoModel_BooleanProperty(FXJSE_HVALUE hValue, FX_BOOL& bValue, FX_BOOL bSetting)
+{
+ if (bSetting) {
+ bValue = FXJSE_Value_ToBoolean(hValue);
+ } else {
+ FXJSE_Value_SetBoolean(hValue, bValue);
+ }
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Property(FXJSE_HVALUE hValue, FX_DWORD dwFlag, FX_BOOL bSetting)
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
+ if (!pEventParam) {
+ return;
+ }
+ switch (dwFlag) {
+ case XFA_EVENT_CANCELACTION:
+ Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bCancelAction, bSetting);
+ break;
+ case XFA_EVENT_CHANGE:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsChange, bSetting);
+ break;
+ case XFA_EVENT_COMMITKEY:
+ Script_EventPseudoModel_InterProperty(hValue, pEventParam->m_iCommitKey, bSetting);
+ break;
+ case XFA_EVENT_FULLTEXT:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsFullText, bSetting);
+ break;
+ case XFA_EVENT_KEYDOWN:
+ Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bKeyDown, bSetting);
+ break;
+ case XFA_EVENT_MODIFIER:
+ Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bModifier, bSetting);
+ break;
+ case XFA_EVENT_NEWCONTENTTYPE:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsNewContentType, bSetting);
+ break;
+ case XFA_EVENT_NEWTEXT:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsNewText, bSetting);
+ break;
+ case XFA_EVENT_PREVCONTENTTYPE:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsPrevContentType, bSetting);
+ break;
+ case XFA_EVENT_PREVTEXT:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsPrevText, bSetting);
+ break;
+ case XFA_EVENT_REENTER:
+ Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bReenter, bSetting);
+ break;
+ case XFA_EVENT_SELEND:
+ Script_EventPseudoModel_InterProperty(hValue, pEventParam->m_iSelEnd, bSetting);
+ break;
+ case XFA_EVENT_SELSTART:
+ Script_EventPseudoModel_InterProperty(hValue, pEventParam->m_iSelStart, bSetting);
+ break;
+ case XFA_EVENT_SHIFT:
+ Script_EventPseudoModel_BooleanProperty(hValue, pEventParam->m_bShift, bSetting);
+ break;
+ case XFA_EVENT_SOAPFAULTCODE:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsSoapFaultCode, bSetting);
+ break;
+ case XFA_EVENT_SOAPFAULTSTRING:
+ Script_EventPseudoModel_StringProperty(hValue, pEventParam->m_wsSoapFaultString, bSetting);
+ break;
+ case XFA_EVENT_TARGET:
+ break;
+ default:
+ break;
+ }
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_CancelAction(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_CANCELACTION, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Change(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_CHANGE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_CommitKey(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_COMMITKEY, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_FullText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_FULLTEXT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_KeyDown(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_KEYDOWN, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Modifier(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_MODIFIER, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_NewContentType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_NEWCONTENTTYPE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_NewText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_NEWTEXT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_PrevContentType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_PREVCONTENTTYPE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_PrevText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_PREVTEXT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Reenter(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_REENTER, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SelEnd(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_SELEND, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SelStart(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_SELSTART, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Shift(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_SHIFT, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SoapFaultCode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_SOAPFAULTCODE, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_SoapFaultString(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_SOAPFAULTSTRING, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Target(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ Script_EventPseudoModel_Property(hValue, XFA_EVENT_TARGET, bSetting);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Emit(CFXJSE_Arguments* pArguments)
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
+ if (!pEventParam) {
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ IXFA_WidgetHandler* pWidgetHandler = pNotify->GetWidgetHandler();
+ if (!pWidgetHandler) {
+ return;
+ }
+ pWidgetHandler->ProcessEvent(pEventParam->m_pTarget, pEventParam);
+}
+void CScript_EventPseudoModel::Script_EventPseudoModel_Reset(CFXJSE_Arguments* pArguments)
+{
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ CXFA_EventParam* pEventParam = pScriptContext->GetEventParam();
+ if (!pEventParam) {
+ return;
+ }
+ pEventParam->Reset();
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.h b/xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.h
new file mode 100644
index 0000000000..83c59e0917
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_eventpseudomodel.h
@@ -0,0 +1,56 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _SCRIPT_EVENTPSEUDOMODEL_H_
+#define _SCRIPT_EVENTPSEUDOMODEL_H_
+#define XFA_EVENT_CHANGE 0
+#define XFA_EVENT_COMMITKEY 1
+#define XFA_EVENT_FULLTEXT 2
+#define XFA_EVENT_KEYDOWN 3
+#define XFA_EVENT_MODIFIER 4
+#define XFA_EVENT_NEWCONTENTTYPE 5
+#define XFA_EVENT_NEWTEXT 6
+#define XFA_EVENT_PREVCONTENTTYPE 7
+#define XFA_EVENT_PREVTEXT 8
+#define XFA_EVENT_REENTER 9
+#define XFA_EVENT_SELEND 10
+#define XFA_EVENT_SELSTART 11
+#define XFA_EVENT_SHIFT 12
+#define XFA_EVENT_SOAPFAULTCODE 13
+#define XFA_EVENT_SOAPFAULTSTRING 14
+#define XFA_EVENT_TARGET 15
+#define XFA_EVENT_CANCELACTION 16
+class CScript_EventPseudoModel : public CXFA_OrdinaryObject
+{
+public:
+ CScript_EventPseudoModel(CXFA_Document* pDocument);
+ virtual ~CScript_EventPseudoModel();
+
+ void Script_EventPseudoModel_CancelAction(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_Change(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_CommitKey(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_FullText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_KeyDown(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_Modifier(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_NewContentType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_NewText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_PrevContentType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_PrevText(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_Reenter(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_SelEnd(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_SelStart(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_Shift(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_SoapFaultCode(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_SoapFaultString(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_EventPseudoModel_Target(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+
+
+ void Script_EventPseudoModel_Emit(CFXJSE_Arguments* pArguments);
+ void Script_EventPseudoModel_Reset(CFXJSE_Arguments* pArguments);
+protected:
+ void Script_EventPseudoModel_Property(FXJSE_HVALUE hValue, FX_DWORD dwFlag, FX_BOOL bSetting);
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.cpp b/xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.cpp
new file mode 100644
index 0000000000..6fd7baad8a
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.cpp
@@ -0,0 +1,754 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_hostpseudomodel.h"
+CScript_HostPseudoModel::CScript_HostPseudoModel(CXFA_Document* pDocument)
+ : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_HostPseudoModel)
+{
+ m_uScriptHash = XFA_HASHCODE_Host;
+}
+CScript_HostPseudoModel::~CScript_HostPseudoModel()
+{
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_LoadString(FXJSE_HVALUE hValue, IXFA_Notify* pNotify, FX_DWORD dwFlag)
+{
+ CFX_WideString wsValue;
+ pNotify->GetAppProvider()->LoadString(dwFlag, wsValue);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsValue));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_AppType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ }
+ CFX_WideString wsAppType;
+ pNotify->GetAppProvider()->GetAppType(wsAppType);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAppType));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_FoxitAppType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ }
+ CFX_WideString wsAppType;
+ pNotify->GetAppProvider()->GetFoxitAppType(wsAppType);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAppType));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_CalculationsEnabled(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ if (bSetting) {
+ pNotify->GetDocProvider()->SetCalculationsEnabled(hDoc, FXJSE_Value_ToBoolean(hValue));
+ return;
+ }
+ FX_BOOL bEnabled = pNotify->GetDocProvider()->IsCalculationsEnabled(hDoc);
+ FXJSE_Value_SetBoolean(hValue, bEnabled);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_CurrentPage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ if (bSetting) {
+ pNotify->GetDocProvider()->SetCurrentPage(hDoc, FXJSE_Value_ToInteger(hValue));
+ return;
+ }
+ FX_INT32 iCurrentPage = pNotify->GetDocProvider()->GetCurrentPage(hDoc);
+ FXJSE_Value_SetInteger(hValue, iCurrentPage);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Language(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_LANGUAGE);
+ return;
+ }
+ CFX_WideString wsLanguage;
+ pNotify->GetAppProvider()->GetLanguage(wsLanguage);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsLanguage));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_NumPages(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_NUMPAGES);
+ return;
+ }
+ FX_INT32 iNumPages = pNotify->GetDocProvider()->CountPages(hDoc);
+ FXJSE_Value_SetInteger(hValue, iNumPages);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Platform(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_PLATFORM);
+ return;
+ }
+ CFX_WideString wsPlatform;
+ pNotify->GetAppProvider()->GetPlatform(wsPlatform);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsPlatform));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Title(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ if (bSetting) {
+ CFX_ByteString bsValue;
+ FXJSE_Value_ToUTF8String(hValue, bsValue);
+ pNotify->GetDocProvider()->SetTitle(hDoc, CFX_WideString::FromUTF8(bsValue, bsValue.GetLength()));
+ return;
+ }
+ CFX_WideString wsTitle;
+ pNotify->GetDocProvider()->GetTitle(hDoc, wsTitle);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsTitle));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ValidationsEnabled(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ if (bSetting) {
+ pNotify->GetDocProvider()->SetValidationsEnabled(hDoc, FXJSE_Value_ToBoolean(hValue));
+ return;
+ }
+ FX_BOOL bEnabled = pNotify->GetDocProvider()->IsValidationsEnabled(hDoc);
+ FXJSE_Value_SetBoolean(hValue, bEnabled);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Variation(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_VARIATION);
+ return;
+ }
+ CFX_WideString wsVariation;
+ pNotify->GetAppProvider()->GetVariation(wsVariation);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsVariation));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Version(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_VERSION);
+ return;
+ }
+ CFX_WideString wsVersion;
+ pNotify->GetAppProvider()->GetVersion(wsVersion);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsVersion));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_FoxitVersion(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_VERSION);
+ return;
+ }
+ CFX_WideString wsVersion;
+ pNotify->GetAppProvider()->GetFoxitVersion(wsVersion);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsVersion));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Name(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ }
+ CFX_WideString wsAppName;
+ pNotify->GetAppProvider()->GetAppName(wsAppName);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAppName));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_FoxitName(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_INVAlID_PROP_SET);
+ return;
+ }
+ CFX_WideString wsFoxitAppName;
+ pNotify->GetAppProvider()->GetFoxitAppName(wsFoxitAppName);
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsFoxitAppName));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_GotoURL(CFXJSE_Arguments* pArguments)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"gotoURL"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ CFX_WideString wsURL;
+ if (iLength >= 1) {
+ CFX_ByteString bsURL = pArguments->GetUTF8String(0);
+ wsURL = CFX_WideString::FromUTF8(bsURL, bsURL.GetLength());
+ }
+ pNotify->GetDocProvider()->GotoURL(hDoc, wsURL);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_OpenList(CFXJSE_Arguments* pArguments)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"openList"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CXFA_Node* pNode = NULL;
+ if (iLength >= 1) {
+ FXJSE_HVALUE hValue = pArguments->GetValue(0);
+ if (FXJSE_Value_IsObject(hValue)) {
+ pNode = (CXFA_Node*)FXJSE_Value_ToObject(hValue, NULL);
+ } else if (FXJSE_Value_IsUTF8String(hValue)) {
+ CFX_ByteString bsString;
+ FXJSE_Value_ToUTF8String(hValue, bsString);
+ CFX_WideString wsExpression = CFX_WideString::FromUTF8(bsString, bsString.GetLength());
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ FXJSE_Value_Release(hValue);
+ return;
+ }
+ CXFA_Object* pObject = pScriptContext->GetThisObject();
+ if (!pObject) {
+ FXJSE_Value_Release(hValue);
+ return;
+ }
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = pScriptContext->ResolveObjects(pObject, wsExpression, resoveNodeRS, dwFlag);
+ if (iRet < 1 || !resoveNodeRS.nodes[0]->IsNode()) {
+ FXJSE_Value_Release(hValue);
+ return;
+ }
+ pNode = (CXFA_Node*)resoveNodeRS.nodes[0];
+ }
+ FXJSE_Value_Release(hValue);
+ }
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ XFA_HWIDGET hWidget = pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
+ if (!hWidget) {
+ return;
+ }
+ pNotify->GetDocProvider()->SetFocusWidget(pNotify->GetHDOC(), hWidget);
+ pNotify->OpenDropDownList(hWidget);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Response(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 4) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"response"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CFX_WideString wsQuestion;
+ CFX_WideString wsTitle;
+ CFX_WideString wsDefaultAnswer;
+ FX_BOOL bMark = FALSE;
+ if (iLength >= 1) {
+ CFX_ByteString bsQuestion = pArguments->GetUTF8String(0);
+ wsQuestion = CFX_WideString::FromUTF8(bsQuestion, bsQuestion.GetLength());
+ }
+ if (iLength >= 2) {
+ CFX_ByteString bsTitle = pArguments->GetUTF8String(1);
+ wsTitle = CFX_WideString::FromUTF8(bsTitle, bsTitle.GetLength());
+ }
+ if (iLength >= 3) {
+ CFX_ByteString bsDefaultAnswer = pArguments->GetUTF8String(2);
+ wsDefaultAnswer = CFX_WideString::FromUTF8(bsDefaultAnswer, bsDefaultAnswer.GetLength());
+ }
+ if (iLength >= 4) {
+ bMark = pArguments->GetInt32(3) == 0 ? FALSE : TRUE;
+ }
+ CFX_WideString wsAnswer;
+ pNotify->GetAppProvider()->Response(wsAnswer, wsQuestion, wsTitle, wsDefaultAnswer, bMark);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsAnswer));
+ }
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_DocumentInBatch(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ FX_INT32 iCur = pNotify->GetAppProvider()->GetCurDocumentInBatch();
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iCur);
+ }
+}
+static FX_INT32 XFA_FilterName(FX_WSTR wsExpression, FX_INT32 nStart, CFX_WideString &wsFilter)
+{
+ FXSYS_assert(nStart > -1);
+ FX_INT32 iLength = wsExpression.GetLength();
+ if (nStart >= iLength) {
+ return iLength;
+ }
+ FX_LPWSTR pBuf = wsFilter.GetBuffer(iLength - nStart);
+ FX_INT32 nCount = 0;
+ FX_LPCWSTR pSrc = wsExpression.GetPtr();
+ FX_WCHAR wCur;
+ while (nStart < iLength) {
+ wCur = pSrc[nStart ++];
+ if (wCur == ',') {
+ break;
+ }
+ pBuf[nCount ++] = wCur;
+ }
+ wsFilter.ReleaseBuffer(nCount);
+ wsFilter.TrimLeft();
+ wsFilter.TrimRight();
+ return nStart;
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ResetData(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 0 || iLength > 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"resetData"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CFX_WideString wsExpression;
+ if (iLength >= 1) {
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(0);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ }
+ if (wsExpression.IsEmpty()) {
+ pNotify->ResetData();
+ return;
+ }
+ FX_INT32 iStart = 0;
+ CFX_WideString wsName;
+ CXFA_Node* pNode = NULL;
+ FX_INT32 iExpLength = wsExpression.GetLength();
+ while (iStart < iExpLength) {
+ iStart = XFA_FilterName(wsExpression, iStart, wsName);
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ return;
+ }
+ CXFA_Object* pObject = pScriptContext->GetThisObject();
+ if (!pObject) {
+ return;
+ }
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = pScriptContext->ResolveObjects(pObject, wsName, resoveNodeRS, dwFlag);
+ if (iRet < 1 || !resoveNodeRS.nodes[0]->IsNode()) {
+ continue;
+ }
+ pNode = (CXFA_Node*)resoveNodeRS.nodes[0];
+ pNotify->ResetData(pNode->GetWidgetData());
+ }
+ if (!pNode) {
+ pNotify->ResetData();
+ }
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Beep(CFXJSE_Arguments* pArguments)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 0 || iLength > 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"beep"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ FX_DWORD dwType = 4;
+ if (iLength >= 1) {
+ dwType = pArguments->GetInt32(0);
+ }
+ pNotify->GetAppProvider()->Beep(dwType);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_SetFocus(CFXJSE_Arguments* pArguments)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"setFocus"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ CXFA_Node* pNode = NULL;
+ if (iLength >= 1) {
+ FXJSE_HVALUE hValue = pArguments->GetValue(0);
+ if (FXJSE_Value_IsObject(hValue)) {
+ pNode = (CXFA_Node*)FXJSE_Value_ToObject(hValue, NULL);
+ } else if (FXJSE_Value_IsUTF8String(hValue)) {
+ CFX_ByteString bsString;
+ FXJSE_Value_ToUTF8String(hValue, bsString);
+ CFX_WideString wsExpression = CFX_WideString::FromUTF8(bsString, bsString.GetLength());
+ IXFA_ScriptContext* pScriptContext = m_pDocument->GetScriptContext();
+ if (!pScriptContext) {
+ FXJSE_Value_Release(hValue);
+ return;
+ }
+ CXFA_Object* pObject = pScriptContext->GetThisObject();
+ if (!pObject) {
+ FXJSE_Value_Release(hValue);
+ return;
+ }
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ XFA_RESOLVENODE_RS resoveNodeRS;
+ FX_INT32 iRet = pScriptContext->ResolveObjects(pObject, wsExpression, resoveNodeRS, dwFlag);
+ if (iRet < 1 || !resoveNodeRS.nodes[0]->IsNode()) {
+ FXJSE_Value_Release(hValue);
+ return;
+ }
+ pNode = (CXFA_Node*)resoveNodeRS.nodes[0];
+ }
+ FXJSE_Value_Release(hValue);
+ }
+ pNotify->SetFocusWidgetNode(pNode);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_GetFocus(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CXFA_Node* pNode = pNotify->GetFocusWidgetNode();
+ if (!pNode) {
+ return;
+ }
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pNode));
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_MessageBox(CFXJSE_Arguments* pArguments)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 4) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"messageBox"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CFX_WideString wsMessage;
+ CFX_WideString bsTitle;
+ FX_DWORD dwMessageType = XFA_MBICON_Error;
+ FX_DWORD dwButtonType = XFA_MB_OK;
+ if (iLength >= 1) {
+ if(!Script_HostPseudoModel_ValidateArgsForMsg(pArguments, 0, wsMessage)) {
+ return;
+ }
+ }
+ if (iLength >= 2) {
+ if(!Script_HostPseudoModel_ValidateArgsForMsg(pArguments, 1, bsTitle)) {
+ return;
+ }
+ }
+ if (iLength >= 3) {
+ dwMessageType = pArguments->GetInt32(2);
+ if (dwMessageType > XFA_MBICON_Status) {
+ dwMessageType = XFA_MBICON_Error;
+ }
+ }
+ if (iLength >= 4) {
+ dwButtonType = pArguments->GetInt32(3);
+ if (dwButtonType > XFA_MB_YesNoCancel) {
+ dwButtonType = XFA_MB_OK;
+ }
+ }
+ FX_INT32 iValue = pNotify->GetAppProvider()->MsgBox(wsMessage, bsTitle, dwMessageType, dwButtonType);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iValue);
+ }
+}
+FX_BOOL CScript_HostPseudoModel::Script_HostPseudoModel_ValidateArgsForMsg(CFXJSE_Arguments* pArguments, FX_INT32 iArgIndex, CFX_WideString& wsValue)
+{
+ if(pArguments == NULL || iArgIndex < 0) {
+ return FALSE;
+ }
+ FX_BOOL bIsJsType = FALSE;
+ if(m_pDocument->GetScriptContext()->GetType() == XFA_SCRIPTLANGTYPE_Javascript) {
+ bIsJsType = TRUE;
+ }
+ FXJSE_HVALUE hValueArg = pArguments->GetValue(iArgIndex);
+ if(!FXJSE_Value_IsUTF8String(hValueArg) && bIsJsType) {
+ ThrowScriptErrorMessage(XFA_IDS_ARGUMENT_MISMATCH);
+ FXJSE_Value_Release(hValueArg);
+ return FALSE;
+ }
+ if(FXJSE_Value_IsNull(hValueArg)) {
+ wsValue = FX_WSTRC(L"");
+ } else {
+ CFX_ByteString byMessage;
+ FXJSE_Value_ToUTF8String(hValueArg, byMessage);
+ wsValue = CFX_WideString::FromUTF8(byMessage, byMessage.GetLength());
+ }
+ FXJSE_Value_Release(hValueArg);
+ return TRUE;
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_DocumentCountInBatch(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ FX_INT32 iValue = pNotify->GetAppProvider()->GetDocumentCountInBatch();
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iValue);
+ }
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_Print(CFXJSE_Arguments* pArguments)
+{
+ if (!m_pDocument->GetScriptContext()->IsRunAtClient()) {
+ return;
+ }
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 8) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"print"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ FX_DWORD dwOptions = 0;
+ FX_BOOL bShowDialog = TRUE;
+ if (iLength >= 1) {
+ bShowDialog = pArguments->GetInt32(0) == 0 ? FALSE : TRUE;
+ }
+ if(bShowDialog) {
+ dwOptions |= XFA_PRINTOPT_ShowDialog;
+ }
+ FX_INT32 nStartPage = 0;
+ if (iLength >= 2) {
+ nStartPage = pArguments->GetInt32(1);
+ }
+ FX_INT32 nEndPage = 0;
+ if (iLength >= 3) {
+ nEndPage = pArguments->GetInt32(2);
+ }
+ FX_BOOL bCanCancel = TRUE;
+ if (iLength >= 4) {
+ bCanCancel = pArguments->GetInt32(3) == 0 ? FALSE : TRUE;
+ }
+ if(bCanCancel) {
+ dwOptions |= XFA_PRINTOPT_CanCancel;
+ }
+ FX_BOOL bShrinkPage = TRUE;
+ if (iLength >= 5) {
+ bShrinkPage = pArguments->GetInt32(4) == 0 ? FALSE : TRUE;
+ }
+ if(bShrinkPage) {
+ dwOptions |= XFA_PRINTOPT_ShrinkPage;
+ }
+ FX_BOOL bAsImage = TRUE;
+ if (iLength >= 6) {
+ bAsImage = pArguments->GetInt32(5) == 0 ? FALSE : TRUE;
+ }
+ if(bAsImage) {
+ dwOptions |= XFA_PRINTOPT_AsImage;
+ }
+ FX_BOOL bReverseOrder = TRUE;
+ if (iLength >= 7) {
+ bAsImage = pArguments->GetInt32(5) == 0 ? FALSE : TRUE;
+ }
+ bReverseOrder = pArguments->GetInt32(6) == 0 ? FALSE : TRUE;
+ if(bReverseOrder) {
+ dwOptions |= XFA_PRINTOPT_ReverseOrder;
+ }
+ FX_BOOL bPrintAnnot = TRUE;
+ if (iLength >= 8) {
+ bPrintAnnot = pArguments->GetInt32(7) == 0 ? FALSE : TRUE;
+ }
+ if(bPrintAnnot) {
+ dwOptions |= XFA_PRINTOPT_PrintAnnot;
+ }
+ pNotify->GetDocProvider()->Print(hDoc, nStartPage, nEndPage, dwOptions);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ImportData(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 0 || iLength > 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"importData"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CFX_WideString wsFilePath;
+ if (iLength > 0) {
+ CFX_ByteString bsFilePath = pArguments->GetUTF8String(0);
+ wsFilePath = CFX_WideString::FromUTF8(bsFilePath, bsFilePath.GetLength());
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ pNotify->GetDocProvider()->ImportData(hDoc, wsFilePath);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_ExportData(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 0 || iLength > 2) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"exportData"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ CFX_WideString wsFilePath;
+ FX_BOOL bXDP = TRUE;
+ if (iLength >= 1) {
+ CFX_ByteString bsFilePath = pArguments->GetUTF8String(0);
+ wsFilePath = CFX_WideString::FromUTF8(bsFilePath, bsFilePath.GetLength());
+ }
+ if (iLength >= 2) {
+ bXDP = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+ }
+ pNotify->GetDocProvider()->ExportData(hDoc, wsFilePath, bXDP);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_PageUp(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ FX_INT32 nCurPage = pNotify->GetDocProvider()->GetCurrentPage(hDoc);
+ FX_INT32 nNewPage = 0;
+ if (nCurPage <= 1) {
+ return;
+ }
+ nNewPage = nCurPage - 1;
+ pNotify->GetDocProvider()->SetCurrentPage(hDoc, nNewPage);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_PageDown(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ FX_INT32 nCurPage = pNotify->GetDocProvider()->GetCurrentPage(hDoc);
+ FX_INT32 nPageCount = pNotify->GetDocProvider()->CountPages(hDoc);
+ if (!nPageCount || nCurPage == nPageCount) {
+ return;
+ }
+ FX_INT32 nNewPage = 0;
+ if (nCurPage >= nPageCount) {
+ nNewPage = nPageCount - 1;
+ } else {
+ nNewPage = nCurPage + 1;
+ }
+ pNotify->GetDocProvider()->SetCurrentPage(hDoc, nNewPage);
+}
+void CScript_HostPseudoModel::Script_HostPseudoModel_CurrentDateTime(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ CFX_WideString wsDataTime = pNotify->GetCurrentDateTime();
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetUTF8String(hValue, FX_UTF8Encode(wsDataTime));
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.h b/xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.h
new file mode 100644
index 0000000000..118680e792
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_hostpseudomodel.h
@@ -0,0 +1,50 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _SCRIPT_HOSTPSEUDOMODEL_H_
+#define _SCRIPT_HOSTPSEUDOMODEL_H_
+class CScript_HostPseudoModel : public CXFA_OrdinaryObject
+{
+public:
+ CScript_HostPseudoModel(CXFA_Document* pDocument);
+ virtual ~CScript_HostPseudoModel();
+
+ void Script_HostPseudoModel_AppType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_FoxitAppType(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_CalculationsEnabled(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_CurrentPage(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_Language(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_NumPages(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_Platform(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_Title(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_ValidationsEnabled(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_Variation(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_Version(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_FoxitVersion(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_Name(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+ void Script_HostPseudoModel_FoxitName(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+
+ void Script_HostPseudoModel_GotoURL(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_OpenList(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_Response(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_DocumentInBatch(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_ResetData(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_Beep(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_SetFocus(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_GetFocus(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_MessageBox(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_DocumentCountInBatch(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_Print(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_ImportData(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_ExportData(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_PageUp(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_PageDown(CFXJSE_Arguments* pArguments);
+ void Script_HostPseudoModel_CurrentDateTime(CFXJSE_Arguments* pArguments);
+protected:
+ void Script_HostPseudoModel_LoadString(FXJSE_HVALUE hValue, IXFA_Notify* pNotify, FX_DWORD dwFlag);
+ FX_BOOL Script_HostPseudoModel_ValidateArgsForMsg(CFXJSE_Arguments* pArguments, FX_INT32 iArgIndex, CFX_WideString& wsValue);
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_imp.cpp b/xfa/src/fxfa/src/parser/xfa_script_imp.cpp
new file mode 100644
index 0000000000..bdf59ca082
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_imp.cpp
@@ -0,0 +1,750 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_imp.h"
+#include "xfa_script_resolveprocessor.h"
+#include "xfa_script_nodehelper.h"
+CXFA_ScriptContext::CXFA_ScriptContext(CXFA_Document* pDocument)
+ : m_pDocument(pDocument), m_hJsRuntime(NULL), m_hJsContext(NULL), m_hJsClass(NULL)
+ , m_pEventParam(NULL), m_pResolveProcessor(NULL), m_eScriptType(XFA_SCRIPTLANGTYPE_Unkown)
+ , m_hFM2JSContext(NULL), m_pThisObject(NULL), m_pScriptNodeArray(NULL)
+ , m_dwBuiltInInFlags(0)
+ , m_eRunAtType(XFA_ATTRIBUTEENUM_Client)
+{
+ FX_memset(&m_JsGlobalClass, 0, sizeof(FXJSE_CLASS));
+ FX_memset(&m_JsNormalClass, 0, sizeof(FXJSE_CLASS));
+}
+CXFA_ScriptContext::~CXFA_ScriptContext()
+{
+ FX_POSITION ps = m_mapXFAToHValue.GetStartPosition();
+ while (ps) {
+ CXFA_Object* pXFAObj;
+ FXJSE_HVALUE pValue;
+ m_mapXFAToHValue.GetNextAssoc(ps, pXFAObj, pValue);
+ FXJSE_Value_Release(pValue);
+ }
+ m_mapXFAToHValue.RemoveAll();
+ ReleaseVariablesMap();
+ if(m_hFM2JSContext) {
+ XFA_FM2JS_ContextRelease(m_hFM2JSContext);
+ m_hFM2JSContext = NULL;
+ }
+ if(m_hJsContext) {
+ FXJSE_Context_Release(m_hJsContext);
+ m_hJsContext = NULL;
+ }
+ if(m_pResolveProcessor) {
+ delete m_pResolveProcessor;
+ m_pResolveProcessor = NULL;
+ }
+ m_upObjectArray.RemoveAll();
+ for (FX_INT32 i = 0; i < m_CacheListArray.GetSize(); i++) {
+ delete ((CXFA_NodeList*)m_CacheListArray[i]);
+ }
+ m_CacheListArray.RemoveAll();
+ if (m_dwBuiltInInFlags & XFA_JSBUILTIN_HasCount) {
+ FX_POSITION ps = m_JSBuiltInObjects.GetStartPosition();
+ while (ps) {
+ CFX_ByteString bsKey;
+ void* pValue = NULL;
+ m_JSBuiltInObjects.GetNextAssoc(ps, bsKey, pValue);
+ if (pValue) {
+ FXJSE_Value_Release((FXJSE_HVALUE)pValue);
+ }
+ }
+ m_JSBuiltInObjects.RemoveAll();
+ }
+}
+void CXFA_ScriptContext::Initialize(FXJSE_HRUNTIME hRuntime)
+{
+ m_hJsRuntime = hRuntime;
+ DefineJsContext();
+ DefineJsClass();
+ m_pResolveProcessor = FX_NEW CXFA_ResolveProcessor;
+}
+void CXFA_ScriptContext::Release()
+{
+ delete this;
+}
+FX_BOOL CXFA_ScriptContext::RunScript(XFA_SCRIPTLANGTYPE eScriptType, FX_WSTR wsScript, FXJSE_HVALUE hRetValue, CXFA_Object* pThisObject )
+{
+ CFX_ByteString btScript;
+ XFA_SCRIPTLANGTYPE eSaveType = m_eScriptType;
+ m_eScriptType = eScriptType;
+ if(eScriptType == XFA_SCRIPTLANGTYPE_Formcalc) {
+ if(!m_hFM2JSContext) {
+ m_hFM2JSContext = XFA_FM2JS_ContextCreate();
+ XFA_FM2JS_ContextInitialize(m_hFM2JSContext, m_hJsRuntime, m_hJsContext, m_pDocument);
+ }
+ CFX_WideTextBuf wsJavaScript;
+ CFX_WideString wsErrorInfo;
+ FX_INT32 iFlags = XFA_FM2JS_Translate(wsScript, wsJavaScript, wsErrorInfo);
+ if(iFlags) {
+ FXJSE_Value_SetUndefined(hRetValue);
+ return FALSE;
+ }
+ btScript = FX_UTF8Encode(wsJavaScript.GetBuffer(), wsJavaScript.GetLength());
+ } else {
+ if ((m_dwBuiltInInFlags & XFA_JSBUILTIN_Initialized) == 0) {
+ m_dwBuiltInInFlags = XFA_JSBUILTIN_Initialized;
+ FX_POSITION ps = m_JSBuiltInObjects.GetStartPosition();
+ if (ps) {
+ FXJSE_HVALUE hObject = FXJSE_Context_GetGlobalObject(m_hJsContext);
+ while (ps) {
+ CFX_ByteString bsKey;
+ void* pValue;
+ m_JSBuiltInObjects.GetNextAssoc(ps, bsKey, pValue);
+ FXJSE_HVALUE hProp = FXJSE_Value_Create(m_hJsRuntime);
+ if (FXJSE_Value_GetObjectProp(hObject, bsKey, hProp)) {
+ m_JSBuiltInObjects.SetAt(bsKey, hProp);
+ FXJSE_Value_DeleteObjectProp(hObject, bsKey);
+ m_dwBuiltInInFlags |= XFA_JSBUILTIN_HasCount;
+ } else {
+ m_JSBuiltInObjects.RemoveKey(bsKey);
+ FXJSE_Value_Release(hProp);
+ }
+ }
+ FXJSE_Value_Release(hObject);
+ }
+ }
+ btScript = FX_UTF8Encode(wsScript.GetPtr(), wsScript.GetLength());
+ }
+ CXFA_Object *pOriginalObject = m_pThisObject;
+ m_pThisObject = pThisObject;
+ FXJSE_HVALUE pValue = pThisObject ? GetJSValueFromMap(pThisObject) : NULL;
+ FX_BOOL bRet = FXJSE_ExecuteScript(m_hJsContext, btScript, hRetValue, pValue);
+ m_pThisObject = pOriginalObject;
+ m_eScriptType = eSaveType;
+ return bRet;
+}
+void CXFA_ScriptContext::GlobalPropertySetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ CXFA_Object* lpOrginalNode = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+ CXFA_Document* pDoc = lpOrginalNode->GetDocument();
+ CXFA_ScriptContext* lpScriptContext = (CXFA_ScriptContext*)pDoc->GetScriptContext();
+ CXFA_Object* lpCurNode = lpScriptContext->GetVariablesThis(lpOrginalNode);
+ CFX_WideString wsPropName = CFX_WideString::FromUTF8((FX_LPCSTR)szPropName.GetPtr(), szPropName.GetLength());
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Attributes;
+ CXFA_Node* pRefNode = (CXFA_Node*)lpScriptContext->GetThisObject();
+ if(lpOrginalNode->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+ pRefNode = (CXFA_Node*)lpCurNode;
+ }
+ if(lpScriptContext->QueryNodeByFlag(pRefNode, wsPropName, hValue, dwFlag, TRUE)) {
+ return;
+ }
+ if(lpOrginalNode->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+ if (FXJSE_Value_IsUndefined(hValue)) {
+ FXJSE_Value_SetObjectOwnProp(hObject, szPropName, hValue);
+ return;
+ }
+ }
+ IXFA_Notify* pNotify = pDoc->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->GetDocProvider()->SetGlobalProperty(pNotify->GetHDOC(), szPropName, hValue);
+}
+FX_BOOL CXFA_ScriptContext::QueryNodeByFlag(CXFA_Node* refNode, FX_WSTR propname, FXJSE_HVALUE hValue, FX_DWORD dwFlag, FX_BOOL bSetting)
+{
+ XFA_RESOLVENODE_RS resolveRs;
+ FX_INT32 iRet = ResolveObjects(refNode, propname, resolveRs, dwFlag);
+ FX_BOOL bResult = FALSE;
+ if (iRet > 0) {
+ bResult = TRUE;
+ if(resolveRs.dwFlags == XFA_RESOVENODE_RSTYPE_Nodes) {
+ FXJSE_HVALUE pValue = GetJSValueFromMap(resolveRs.nodes[0]);
+ FXJSE_Value_Set(hValue, pValue);
+ } else if(resolveRs.dwFlags == XFA_RESOVENODE_RSTYPE_Attribute) {
+ XFA_LPCSCRIPTATTRIBUTEINFO lpAttributeInfo = resolveRs.pScriptAttribute;
+ if(lpAttributeInfo) {
+ (resolveRs.nodes[0]->*(lpAttributeInfo->lpfnCallback))(hValue, bSetting, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+ }
+ }
+ }
+ return bResult;
+}
+void CXFA_ScriptContext::GlobalPropertyGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ CXFA_Object* pOrginalObject = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+ CXFA_Document* pDoc = pOrginalObject->GetDocument();
+ CXFA_ScriptContext* lpScriptContext = (CXFA_ScriptContext*)pDoc->GetScriptContext();
+ CXFA_Object* lpCurNode = lpScriptContext->GetVariablesThis(pOrginalObject);
+ CFX_WideString wsPropName = CFX_WideString::FromUTF8((FX_LPCSTR)szPropName.GetPtr(), szPropName.GetLength());
+ if (lpScriptContext->GetType() == XFA_SCRIPTLANGTYPE_Formcalc) {
+ if(szPropName == FX_BSTRC(FOXIT_XFA_FM2JS_FORMCALC_RUNTIME)) {
+ XFA_FM2JS_GlobalPropertyGetter(lpScriptContext->m_hFM2JSContext, hValue);
+ return;
+ }
+ FX_UINT32 uHashCode = FX_HashCode_String_GetW(wsPropName, wsPropName.GetLength());
+ if(uHashCode != XFA_HASHCODE_Layout) {
+ CXFA_Object * pObject = lpScriptContext->GetDocument()->GetXFANode(uHashCode);
+ if (pObject) {
+ FXJSE_Value_Set(hValue, lpScriptContext->GetJSValueFromMap(pObject));
+ return;
+ }
+ }
+ }
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Attributes;
+ CXFA_Node* pRefNode = (CXFA_Node*)lpScriptContext->GetThisObject();
+ if(pOrginalObject->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+ pRefNode = (CXFA_Node*)lpCurNode;
+ }
+ if(lpScriptContext->QueryNodeByFlag(pRefNode, wsPropName, hValue, dwFlag, FALSE)) {
+ return;
+ }
+ dwFlag = XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ if(lpScriptContext->QueryNodeByFlag(pRefNode, wsPropName, hValue, dwFlag, FALSE)) {
+ return;
+ }
+ CXFA_Object* pScriptObject = lpScriptContext->GetVariablesThis(pOrginalObject, TRUE);
+ if (pScriptObject && lpScriptContext->QueryVariableHValue((CXFA_Node *)pScriptObject, szPropName, hValue, TRUE)) {
+ return;
+ }
+ if (lpScriptContext->QueryBuiltinHValue(szPropName, hValue)) {
+ return;
+ }
+ IXFA_Notify* pNotify = pDoc->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ pNotify->GetDocProvider()->GetGlobalProperty(pNotify->GetHDOC(), szPropName, hValue);
+}
+void CXFA_ScriptContext::NormalPropertyGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ CXFA_Object* pOrginalObject = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+ if(pOrginalObject == NULL) {
+ FXJSE_Value_SetUndefined(hValue);
+ return;
+ }
+ CFX_WideString wsPropName = CFX_WideString::FromUTF8((FX_LPCSTR)szPropName.GetPtr(), szPropName.GetLength());
+ CXFA_ScriptContext* lpScriptContext = (CXFA_ScriptContext*)pOrginalObject->GetDocument()->GetScriptContext();
+ CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOrginalObject);
+ if(wsPropName == FX_WSTRC(L"xfa")) {
+ FXJSE_HVALUE pValue = lpScriptContext->GetJSValueFromMap(lpScriptContext->GetDocument()->GetRoot());
+ FXJSE_Value_Set(hValue, pValue);
+ return;
+ }
+ FX_DWORD dwFlag = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties | XFA_RESOLVENODE_Attributes;
+ FX_BOOL bRet = lpScriptContext->QueryNodeByFlag((CXFA_Node *)pObject, wsPropName, hValue, dwFlag, FALSE);
+ if(bRet) {
+ return;
+ }
+ if (pObject == lpScriptContext->GetThisObject() || (lpScriptContext->GetType() == XFA_SCRIPTLANGTYPE_Javascript && !lpScriptContext->IsStrictScopeInJavaScript())) {
+ dwFlag = XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings;
+ bRet = lpScriptContext->QueryNodeByFlag((CXFA_Node *)pObject, wsPropName, hValue, dwFlag, FALSE);
+ }
+ if(bRet) {
+ return;
+ }
+ CXFA_Object* pScriptObject = lpScriptContext->GetVariablesThis(pOrginalObject, TRUE);
+ if (pScriptObject) {
+ bRet = lpScriptContext->QueryVariableHValue((CXFA_Node *)pScriptObject, szPropName, hValue, TRUE);
+ }
+ if (!bRet) {
+ FXJSE_Value_SetUndefined(hValue);
+ }
+}
+void CXFA_ScriptContext::NormalPropertySetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ CXFA_Object* pOrginalObject = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+ if(pOrginalObject == NULL) {
+ return;
+ }
+ CXFA_ScriptContext* lpScriptContext = (CXFA_ScriptContext*)pOrginalObject->GetDocument()->GetScriptContext();
+ CXFA_Object* pObject = lpScriptContext->GetVariablesThis(pOrginalObject);
+ CFX_WideString wsPropName = CFX_WideString::FromUTF8((FX_LPCSTR)szPropName.GetPtr(), szPropName.GetLength());
+ XFA_LPCSCRIPTATTRIBUTEINFO lpAttributeInfo = XFA_GetScriptAttributeByName(pObject->GetClassID(), wsPropName);
+ if(lpAttributeInfo) {
+ (pObject->*(lpAttributeInfo->lpfnCallback))(hValue, TRUE, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+ } else {
+ if(pObject->IsNode()) {
+ if(wsPropName.GetAt(0) == '#') {
+ wsPropName = wsPropName.Right(wsPropName.GetLength() - 1);
+ }
+ CXFA_Node* pNode = (CXFA_Node*)pObject;
+ CXFA_Node *pPropOrChild = NULL;
+ XFA_LPCELEMENTINFO lpElementInfo = XFA_GetElementByName(wsPropName);
+ if (lpElementInfo) {
+ pPropOrChild = pNode->GetProperty(0, lpElementInfo->eName);
+ } else {
+ pPropOrChild = pNode->GetFirstChildByName(wsPropName);
+ }
+ if (pPropOrChild) {
+ CFX_WideString wsDefaultName = FX_WSTRC(L"{default}");
+ XFA_LPCSCRIPTATTRIBUTEINFO lpAttributeInfo = XFA_GetScriptAttributeByName(pPropOrChild->GetClassID(), wsDefaultName);
+ if(lpAttributeInfo) {
+ (pPropOrChild->*(lpAttributeInfo->lpfnCallback))(hValue, TRUE, (XFA_ATTRIBUTE)lpAttributeInfo->eAttribute);
+ return;
+ }
+ }
+ }
+ CXFA_Object* pScriptObject = lpScriptContext->GetVariablesThis(pOrginalObject, TRUE);
+ if (pScriptObject) {
+ lpScriptContext->QueryVariableHValue((CXFA_Node *)pScriptObject, szPropName, hValue, FALSE);
+ }
+ }
+}
+FX_INT32 CXFA_ScriptContext::NormalPropTypeGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FX_BOOL bQueryIn)
+{
+ CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+ if(pObject == NULL) {
+ return FXJSE_ClassPropType_None;
+ }
+ CXFA_ScriptContext* lpScriptContext = (CXFA_ScriptContext*)pObject->GetDocument()->GetScriptContext();
+ pObject = lpScriptContext->GetVariablesThis(pObject);
+ XFA_ELEMENT objElement = pObject->GetClassID();
+ CFX_WideString wsPropName = CFX_WideString::FromUTF8((FX_LPCSTR)szPropName.GetPtr(), szPropName.GetLength());
+ if(XFA_GetMethodByName(objElement, wsPropName)) {
+ return FXJSE_ClassPropType_Method;
+ }
+ if (bQueryIn && !XFA_GetScriptAttributeByName(objElement, wsPropName)) {
+ return FXJSE_ClassPropType_None;
+ }
+ return FXJSE_ClassPropType_Property;
+}
+FX_INT32 CXFA_ScriptContext::GlobalPropTypeGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FX_BOOL bQueryIn)
+{
+ CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+ if(pObject == NULL) {
+ return FXJSE_ClassPropType_None;
+ }
+ CXFA_ScriptContext* lpScriptContext = (CXFA_ScriptContext*)pObject->GetDocument()->GetScriptContext();
+ pObject = lpScriptContext->GetVariablesThis(pObject);
+ XFA_ELEMENT objElement = pObject->GetClassID();
+ CFX_WideString wsPropName = CFX_WideString::FromUTF8((FX_LPCSTR)szPropName.GetPtr(), szPropName.GetLength());
+ if(XFA_GetMethodByName(objElement, wsPropName)) {
+ return FXJSE_ClassPropType_Method;
+ }
+ return FXJSE_ClassPropType_Property;
+}
+void CXFA_ScriptContext::NormalMethodCall(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args)
+{
+ CXFA_Object* pObject = (CXFA_Object*)FXJSE_Value_ToObject(hThis, NULL);
+ if(pObject == NULL) {
+ return;
+ }
+ CXFA_ScriptContext* lpScriptContext = (CXFA_ScriptContext*)pObject->GetDocument()->GetScriptContext();
+ pObject = lpScriptContext->GetVariablesThis(pObject);
+ CFX_WideString wsFunName = CFX_WideString::FromUTF8((FX_LPCSTR)szFuncName.GetPtr(), szFuncName.GetLength());
+ XFA_LPCMETHODINFO lpMethodInfo = XFA_GetMethodByName(pObject->GetClassID(), wsFunName);
+ if(NULL == lpMethodInfo) {
+ return;
+ }
+ (pObject->*(lpMethodInfo->lpfnCallback))(&args);
+}
+FX_BOOL CXFA_ScriptContext::IsStrictScopeInJavaScript()
+{
+ return m_pDocument->HasFlag(XFA_DOCFLAG_StrictScoping);
+}
+XFA_SCRIPTLANGTYPE CXFA_ScriptContext::GetType()
+{
+ return m_eScriptType;
+}
+void CXFA_ScriptContext::DefineJsContext()
+{
+ m_JsGlobalClass.constructor = NULL;
+ m_JsGlobalClass.name = "Root";
+ m_JsGlobalClass.propNum = 0;
+ m_JsGlobalClass.properties = NULL;
+ m_JsGlobalClass.methNum = 0;
+ m_JsGlobalClass.methods = NULL;
+ m_JsGlobalClass.dynPropGetter = CXFA_ScriptContext::GlobalPropertyGetter;
+ m_JsGlobalClass.dynPropSetter = CXFA_ScriptContext::GlobalPropertySetter;
+ m_JsGlobalClass.dynPropTypeGetter = CXFA_ScriptContext::GlobalPropTypeGetter;
+ m_JsGlobalClass.dynPropDeleter = NULL;
+ m_JsGlobalClass.dynMethodCall = CXFA_ScriptContext::NormalMethodCall;
+ m_hJsContext = FXJSE_Context_Create(m_hJsRuntime, &m_JsGlobalClass, m_pDocument->GetRoot());
+ FXJSE_Context_EnableCompatibleMode(m_hJsContext, FXJSE_COMPATIBLEMODEFLAG_CONSTRUCTOREXTRAMETHODS);
+}
+FXJSE_HCONTEXT CXFA_ScriptContext::CreateVariablesContext(CXFA_Node* pScriptNode, CXFA_Node* pSubform)
+{
+ if(pScriptNode == NULL || pSubform == NULL) {
+ return NULL;
+ }
+ if(m_mapVariableToHValue.GetCount() == 0) {
+ m_JsGlobalVariablesClass.constructor = NULL;
+ m_JsGlobalVariablesClass.name = "XFAScriptObject";
+ m_JsGlobalVariablesClass.propNum = 0;
+ m_JsGlobalVariablesClass.properties = NULL;
+ m_JsGlobalVariablesClass.methNum = 0;
+ m_JsGlobalVariablesClass.methods = NULL;
+ m_JsGlobalVariablesClass.dynPropGetter = CXFA_ScriptContext::GlobalPropertyGetter;
+ m_JsGlobalVariablesClass.dynPropSetter = CXFA_ScriptContext::GlobalPropertySetter;
+ m_JsGlobalVariablesClass.dynPropTypeGetter = CXFA_ScriptContext::NormalPropTypeGetter;
+ m_JsGlobalVariablesClass.dynPropDeleter = NULL;
+ m_JsGlobalVariablesClass.dynMethodCall = CXFA_ScriptContext::NormalMethodCall;
+ }
+ CXFA_ThisProxy* lpVariableNode = FX_NEW CXFA_ThisProxy(pSubform, pScriptNode);
+ FXJSE_HCONTEXT hVariablesContext = FXJSE_Context_Create(m_hJsRuntime, &m_JsGlobalVariablesClass, (CXFA_Object*)lpVariableNode);
+ FXJSE_Context_EnableCompatibleMode(hVariablesContext, FXJSE_COMPATIBLEMODEFLAG_CONSTRUCTOREXTRAMETHODS);
+ m_mapVariableToHValue.SetAt(pScriptNode, hVariablesContext);
+ return hVariablesContext;
+}
+CXFA_Object* CXFA_ScriptContext::GetVariablesThis(CXFA_Object* pObject, FX_BOOL bScriptNode)
+{
+ if(pObject->GetObjectType() == XFA_OBJECTTYPE_VariablesThis) {
+ return bScriptNode ? ((CXFA_ThisProxy*)pObject)->GetScriptNode() : ((CXFA_ThisProxy*)pObject)->GetThisNode();
+ }
+ return pObject;
+}
+FX_BOOL CXFA_ScriptContext::RunVariablesScript(CXFA_Node* pScriptNode)
+{
+ if(pScriptNode == NULL) {
+ return FALSE;
+ }
+ if(pScriptNode->GetClassID() == XFA_ELEMENT_Script) {
+ CXFA_Node* pParent = pScriptNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(!pParent || pParent->GetClassID() != XFA_ELEMENT_Variables) {
+ return FALSE;
+ }
+ if(m_mapVariableToHValue.GetValueAt(pScriptNode)) {
+ return TRUE;
+ }
+ CXFA_Node *pTextNode = pScriptNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pTextNode) {
+ return FALSE;
+ }
+ CFX_WideStringC wsScript;
+ if(!pTextNode->TryCData(XFA_ATTRIBUTE_Value, wsScript)) {
+ return FALSE;
+ }
+ CFX_ByteString btScript = FX_UTF8Encode(wsScript.GetPtr(), wsScript.GetLength());
+ FXJSE_HVALUE hRetValue = FXJSE_Value_Create(m_hJsRuntime);
+ CXFA_Node* pThisObject = pParent->GetNodeItem(XFA_NODEITEM_Parent);
+ FXJSE_HCONTEXT hVariablesContext = CreateVariablesContext(pScriptNode, pThisObject);
+ CXFA_Object *pOriginalObject = m_pThisObject;
+ m_pThisObject = pThisObject;
+ FX_BOOL bRet = FXJSE_ExecuteScript(hVariablesContext, btScript, hRetValue);
+ m_pThisObject = pOriginalObject;
+ FXJSE_Value_Release(hRetValue);
+ return bRet;
+ }
+ return TRUE;
+}
+FX_BOOL CXFA_ScriptContext::QueryVariableHValue(CXFA_Node* pScriptNode, FX_BSTR szPropName, FXJSE_HVALUE hValue, FX_BOOL bGetter)
+{
+ if(pScriptNode->GetClassID() != XFA_ELEMENT_Script) {
+ return FALSE;
+ }
+ CXFA_Node* variablesNode = pScriptNode->GetNodeItem(XFA_NODEITEM_Parent);
+ if(!variablesNode || variablesNode->GetClassID() != XFA_ELEMENT_Variables) {
+ return FALSE;
+ }
+ FX_BOOL bRes = FALSE;
+ FX_LPVOID lpVariables = m_mapVariableToHValue.GetValueAt(pScriptNode);
+ if(lpVariables) {
+ FXJSE_HCONTEXT hVariableContext = (FXJSE_HCONTEXT)lpVariables;
+ FXJSE_HVALUE hObject = FXJSE_Context_GetGlobalObject(hVariableContext);
+ FXJSE_HVALUE hVariableValue = FXJSE_Value_Create(m_hJsRuntime);
+ if (!bGetter) {
+ FXJSE_Value_SetObjectOwnProp(hObject, szPropName, hValue);
+ bRes = TRUE;
+ } else if(FXJSE_Value_ObjectHasOwnProp(hObject, szPropName, FALSE)) {
+ FXJSE_Value_GetObjectProp(hObject, szPropName, hVariableValue);
+ if(FXJSE_Value_IsFunction(hVariableValue)) {
+ FXJSE_Value_SetFunctionBind(hValue, hVariableValue, hObject);
+ } else if (bGetter) {
+ FXJSE_Value_Set(hValue, hVariableValue);
+ } else {
+ FXJSE_Value_Set(hVariableValue, hValue);
+ }
+ bRes = TRUE;
+ }
+ FXJSE_Value_Release(hVariableValue);
+ FXJSE_Value_Release(hObject);
+ }
+ return bRes;
+}
+FX_BOOL CXFA_ScriptContext::QueryBuiltinHValue(FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ void* pBuiltin = NULL;
+ if ((m_dwBuiltInInFlags & XFA_JSBUILTIN_HasCount) && m_JSBuiltInObjects.Lookup(szPropName, pBuiltin)) {
+ FXJSE_Value_Set(hValue, (FXJSE_HVALUE)pBuiltin);
+ return TRUE;
+ }
+ return FALSE;
+}
+void CXFA_ScriptContext::ReleaseVariablesMap()
+{
+ FX_POSITION ps = m_mapVariableToHValue.GetStartPosition();
+ while (ps) {
+ CXFA_Object* pScriptNode;
+ FXJSE_HCONTEXT hVariableContext;
+ m_mapVariableToHValue.GetNextAssoc(ps, pScriptNode, hVariableContext);
+ FXJSE_HVALUE hObject = FXJSE_Context_GetGlobalObject(hVariableContext);
+ CXFA_Object* lpCurNode = (CXFA_Object*)FXJSE_Value_ToObject(hObject, NULL);
+ if(lpCurNode) {
+ delete (CXFA_ThisProxy*)lpCurNode;
+ lpCurNode = NULL;
+ }
+ FXJSE_Value_Release(hObject);
+ FXJSE_Context_Release(hVariableContext);
+ hVariableContext = NULL;
+ }
+ m_mapVariableToHValue.RemoveAll();
+}
+void CXFA_ScriptContext::DefineJsClass()
+{
+ m_JsNormalClass.constructor = NULL;
+ m_JsNormalClass.name = "XFAObject";
+ m_JsNormalClass.propNum = 0;
+ m_JsNormalClass.properties = NULL;
+ m_JsNormalClass.methNum = 0;
+ m_JsNormalClass.methods = NULL;
+ m_JsNormalClass.dynPropGetter = CXFA_ScriptContext::NormalPropertyGetter;
+ m_JsNormalClass.dynPropSetter = CXFA_ScriptContext::NormalPropertySetter;
+ m_JsNormalClass.dynPropTypeGetter = CXFA_ScriptContext::NormalPropTypeGetter;
+ m_JsNormalClass.dynPropDeleter = NULL;
+ m_JsNormalClass.dynMethodCall = CXFA_ScriptContext::NormalMethodCall;
+ m_hJsClass = FXJSE_DefineClass(m_hJsContext, &m_JsNormalClass);
+}
+FXJSE_HCLASS CXFA_ScriptContext::GetJseNormalClass()
+{
+ return m_hJsClass;
+}
+void CXFA_ScriptContext::AddJSBuiltinObject(XFA_LPCJSBUILTININFO pBuitinObject)
+{
+ if (m_dwBuiltInInFlags & XFA_JSBUILTIN_Initialized) {
+ return;
+ }
+ m_JSBuiltInObjects.SetAt(pBuitinObject->pName, (void*)pBuitinObject);
+}
+FX_INT32 CXFA_ScriptContext::ResolveObjects(CXFA_Object* refNode, FX_WSTR wsExpression, XFA_RESOLVENODE_RS& resolveNodeRS, FX_DWORD dwStyles, CXFA_Node* bindNode)
+{
+ if (wsExpression.IsEmpty()) {
+ return 0;
+ }
+ if (m_eScriptType != XFA_SCRIPTLANGTYPE_Formcalc || (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) {
+ m_upObjectArray.RemoveAll();
+ }
+ if(refNode && (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings)) && refNode->IsNode()) {
+ m_upObjectArray.Add((CXFA_Node*)refNode);
+ }
+ FX_BOOL bNextCreate = FALSE;
+ if(dwStyles & XFA_RESOLVENODE_CreateNode) {
+ m_pResolveProcessor->GetNodeHelper()->XFA_SetCreateNodeType(bindNode);
+ }
+ m_pResolveProcessor->GetNodeHelper()->m_pCreateParent = NULL;
+ m_pResolveProcessor->GetNodeHelper()->m_iCurAllStart = -1;
+ CXFA_ResolveNodesData rndFind;
+ FX_INT32 nStart = 0;
+ FX_INT32 nLevel = 0;
+ FX_INT32 nRet = -1;
+ rndFind.m_pSC = this;
+ CXFA_ObjArray findNodes;
+ if (refNode != NULL) {
+ findNodes.Add(refNode);
+ } else {
+ findNodes.Add(m_pDocument->GetRoot());
+ }
+ FX_INT32 nNodes = 0;
+ while (TRUE) {
+ nNodes = findNodes.GetSize();
+ FX_INT32 i = 0;
+ rndFind.m_dwStyles = dwStyles;
+ m_pResolveProcessor->m_iCurStart = nStart;
+ nStart = m_pResolveProcessor->XFA_ResolveNodes_GetFilter(wsExpression, nStart, rndFind);
+ if (nStart < 1) {
+ if((dwStyles & XFA_RESOLVENODE_CreateNode) && !bNextCreate) {
+ CXFA_Node* pDataNode = NULL;
+ nStart = m_pResolveProcessor->GetNodeHelper()->m_iCurAllStart;
+ if(nStart != -1) {
+ pDataNode = m_pDocument->GetNotBindNode(findNodes);
+ if(pDataNode) {
+ findNodes.RemoveAll();
+ findNodes.Add(pDataNode);
+ break;
+ }
+ } else {
+ pDataNode = (CXFA_Node*)findNodes[0];
+ findNodes.RemoveAll();
+ findNodes.Add(pDataNode);
+ break;
+ }
+ dwStyles |= XFA_RESOLVENODE_Bind;
+ findNodes.RemoveAll();
+ findNodes.Add(m_pResolveProcessor->GetNodeHelper()->m_pAllStartParent);
+ continue;
+ } else {
+ break;
+ }
+ }
+ if(bNextCreate) {
+ FX_BOOL bCreate = m_pResolveProcessor->GetNodeHelper()->XFA_ResolveNodes_CreateNode(rndFind.m_wsName, rndFind.m_wsCondition, nStart == wsExpression.GetLength() ? TRUE : FALSE, this);
+ if(bCreate) {
+ continue;
+ } else {
+ break;
+ }
+ }
+ CXFA_ObjArray retNodes;
+ while (i < nNodes) {
+ FX_BOOL bDataBind = FALSE;
+ if(((dwStyles & XFA_RESOLVENODE_Bind) || (dwStyles & XFA_RESOLVENODE_CreateNode)) && nNodes > 1) {
+ CXFA_ResolveNodesData rndBind;
+ m_pResolveProcessor->XFA_ResolveNodes_GetFilter(wsExpression, nStart, rndBind);
+ m_pResolveProcessor->XFA_ResolveNode_SetIndexDataBind(rndBind.m_wsCondition, i, nNodes);
+ bDataBind = TRUE;
+ }
+ rndFind.m_CurNode = findNodes[i ++];
+ rndFind.m_nLevel = nLevel;
+ rndFind.m_dwFlag = XFA_RESOVENODE_RSTYPE_Nodes;
+ nRet = m_pResolveProcessor->XFA_ResolveNodes(rndFind);
+ if (nRet < 1) {
+ continue;
+ }
+ if (rndFind.m_dwFlag == XFA_RESOVENODE_RSTYPE_Attribute && rndFind.m_pScriptAttribute && nStart < wsExpression.GetLength()) {
+ FXJSE_HVALUE hValue = FXJSE_Value_Create(m_hJsRuntime);
+ (rndFind.m_Nodes[0]->*(rndFind.m_pScriptAttribute->lpfnCallback))(hValue, FALSE, (XFA_ATTRIBUTE)rndFind.m_pScriptAttribute->eAttribute);
+ rndFind.m_Nodes.SetAt(0, (CXFA_Object*)FXJSE_Value_ToObject(hValue, NULL));
+ FXJSE_Value_Release(hValue);
+ }
+ FX_INT32 iSize = m_upObjectArray.GetSize();
+ if (iSize) {
+ m_upObjectArray.RemoveAt(iSize - 1);
+ }
+ retNodes.Append(rndFind.m_Nodes);
+ rndFind.m_Nodes.RemoveAll();
+ if(bDataBind){
+ break;
+ }
+ }
+ findNodes.RemoveAll();
+ nNodes = retNodes.GetSize();
+ if (nNodes < 1) {
+ if(dwStyles & XFA_RESOLVENODE_CreateNode) {
+ bNextCreate = TRUE;
+ if(m_pResolveProcessor->GetNodeHelper()->m_pCreateParent == NULL) {
+ m_pResolveProcessor->GetNodeHelper()->m_pCreateParent = (CXFA_Node*)rndFind.m_CurNode;
+ m_pResolveProcessor->GetNodeHelper()->m_iCreateCount = 1;
+ }
+ FX_BOOL bCreate = m_pResolveProcessor->GetNodeHelper()->XFA_ResolveNodes_CreateNode(rndFind.m_wsName, rndFind.m_wsCondition, nStart == wsExpression.GetLength() ? TRUE : FALSE, this);
+ if(bCreate) {
+ continue;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ findNodes.Copy(retNodes);
+ rndFind.m_Nodes.RemoveAll();
+ if (nLevel == 0) {
+ dwStyles &= ~(XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings);
+ }
+ nLevel ++;
+ }
+ if(!bNextCreate) {
+ resolveNodeRS.dwFlags = rndFind.m_dwFlag;
+ if (nNodes > 0) {
+ resolveNodeRS.nodes.Append(findNodes);
+ }
+ if(rndFind.m_dwFlag == XFA_RESOVENODE_RSTYPE_Attribute) {
+ resolveNodeRS.pScriptAttribute = rndFind.m_pScriptAttribute;
+ return 1;
+ }
+ }
+ if(dwStyles & (XFA_RESOLVENODE_CreateNode | XFA_RESOLVENODE_Bind | XFA_RESOLVENODE_BindNew)) {
+ m_pResolveProcessor->XFA_ResolveNode_SetResultCreateNode(resolveNodeRS, rndFind.m_wsCondition);
+ if (!bNextCreate && (dwStyles & XFA_RESOLVENODE_CreateNode)) {
+ resolveNodeRS.dwFlags = XFA_RESOVENODE_RSTYPE_ExistNodes;
+ }
+ return resolveNodeRS.nodes.GetSize();
+ }
+ return nNodes;
+}
+FXJSE_HVALUE CXFA_ScriptContext::GetJSValueFromMap(CXFA_Object* pObject)
+{
+ if (!pObject) {
+ return NULL;
+ }
+ if(pObject->IsNode()) {
+ RunVariablesScript((CXFA_Node*)pObject);
+ }
+ FX_LPVOID pValue = m_mapXFAToHValue.GetValueAt(pObject);
+ if(pValue == NULL) {
+ FXJSE_HVALUE jsHvalue = FXJSE_Value_Create(m_hJsRuntime);
+ FXJSE_Value_SetObject(jsHvalue, pObject, m_hJsClass);
+ m_mapXFAToHValue.SetAt(pObject, jsHvalue);
+ pValue = jsHvalue;
+ }
+ return (FXJSE_HVALUE)pValue;
+}
+FX_INT32 CXFA_ScriptContext::GetIndexByName(CXFA_Node* refNode)
+{
+ CXFA_NodeHelper* lpNodeHelper = m_pResolveProcessor->GetNodeHelper();
+ return lpNodeHelper->XFA_GetIndex(refNode, XFA_LOGIC_Transparent, lpNodeHelper->XFA_NodeIsProperty(refNode), FALSE);
+}
+FX_INT32 CXFA_ScriptContext::GetIndexByClassName(CXFA_Node* refNode)
+{
+ CXFA_NodeHelper* lpNodeHelper = m_pResolveProcessor->GetNodeHelper();
+ return lpNodeHelper->XFA_GetIndex(refNode, XFA_LOGIC_Transparent, lpNodeHelper->XFA_NodeIsProperty(refNode), TRUE);
+}
+void CXFA_ScriptContext::GetSomExpression(CXFA_Node* refNode, CFX_WideString &wsExpression)
+{
+ CXFA_NodeHelper* lpNodeHelper = m_pResolveProcessor->GetNodeHelper();
+ lpNodeHelper->XFA_GetNameExpression(refNode, wsExpression, TRUE, XFA_LOGIC_Transparent);
+}
+void CXFA_ScriptContext::SetNodesOfRunScript(CXFA_NodeArray *pArray)
+{
+ m_pScriptNodeArray = pArray;
+}
+void CXFA_ScriptContext::AddNodesOfRunScript(const CXFA_NodeArray& nodes)
+{
+ if (!m_pScriptNodeArray) {
+ return;
+ }
+ if (nodes.GetSize() > 0) {
+ m_pScriptNodeArray->Copy(nodes);
+ }
+}
+void CXFA_ScriptContext::AddNodesOfRunScript(CXFA_Node* pNode)
+{
+ if (!m_pScriptNodeArray) {
+ return;
+ }
+ if (m_pScriptNodeArray->Find(pNode) == -1) {
+ m_pScriptNodeArray->Add(pNode);
+ }
+}
+IXFA_ScriptContext* XFA_ScriptContext_Create(CXFA_Document* pDocument)
+{
+ return FX_NEW CXFA_ScriptContext(pDocument);
+}
+static const XFA_JSBUILTININFO gs_JSBUILTINData[] = {
+ {0x8108b9a9, (FX_LPCSTR)"Number"},
+ {0xe07e3fbe, (FX_LPCSTR)"Date"},
+};
+const FX_INT32 g_iJSBuiltinCount = sizeof(XFA_JSBUILTININFO) / sizeof(XFA_JSBUILTININFO);
+XFA_LPCJSBUILTININFO XFA_GetJSBuiltinByHash(FX_UINT32 uHashCode)
+{
+ FX_INT32 iStart = 0, iEnd = g_iJSBuiltinCount - 1, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ XFA_LPCJSBUILTININFO pInfo = gs_JSBUILTINData + iMid;
+ if (uHashCode == pInfo->uUnicodeHash) {
+ return pInfo;
+ } else if (uHashCode < pInfo->uUnicodeHash) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_imp.h b/xfa/src/fxfa/src/parser/xfa_script_imp.h
new file mode 100644
index 0000000000..d8aec1a2f6
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_imp.h
@@ -0,0 +1,113 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FXFA_SCRIPT_IMP_H
+#define _FXFA_SCRIPT_IMP_H
+#define XFA_RESOLVENODE_TagName 0x0002
+#define XFA_JSBUILTIN_Initialized 0x0001
+#define XFA_JSBUILTIN_HasCount 0x0002
+class CXFA_ResolveProcessor;
+class CXFA_ScriptContext : public IXFA_ScriptContext, public CFX_Object
+{
+public:
+ CXFA_ScriptContext(CXFA_Document* pDocument);
+ ~CXFA_ScriptContext();
+ virtual void Release();
+ virtual void Initialize(FXJSE_HRUNTIME hRuntime);
+ virtual void SetEventParam(CXFA_EventParam* pEventParam)
+ {
+ m_pEventParam = pEventParam;
+ }
+ virtual CXFA_EventParam* GetEventParam()
+ {
+ return m_pEventParam;
+ }
+ virtual FX_BOOL RunScript(XFA_SCRIPTLANGTYPE eScriptType, FX_WSTR wsScript, FXJSE_HVALUE hRetValue, CXFA_Object* pThisObject = NULL);
+
+ virtual FX_INT32 ResolveObjects(CXFA_Object* refNode, FX_WSTR wsExpression, XFA_RESOLVENODE_RS& resolveNodeRS, FX_DWORD dwStyles = XFA_RESOLVENODE_Children, CXFA_Node* bindNode = NULL);
+ virtual FXJSE_HVALUE GetJSValueFromMap(CXFA_Object* pObject);
+ virtual void CacheList(CXFA_NodeList* pList)
+ {
+ m_CacheListArray.Add(pList);
+ }
+ virtual CXFA_Object* GetThisObject() const
+ {
+ return m_pThisObject;
+ }
+ virtual FXJSE_HRUNTIME GetRuntime() const
+ {
+ return m_hJsRuntime;
+ }
+
+ virtual FX_INT32 GetIndexByName(CXFA_Node* refNode);
+ virtual FX_INT32 GetIndexByClassName(CXFA_Node* refNode);
+ virtual void GetSomExpression(CXFA_Node* refNode, CFX_WideString &wsExpression);
+
+ virtual void SetNodesOfRunScript(CXFA_NodeArray *pArray);
+ virtual void AddNodesOfRunScript(const CXFA_NodeArray& nodes);
+ virtual void AddNodesOfRunScript(CXFA_Node* pNode);
+ virtual FXJSE_HCLASS GetJseNormalClass();
+
+ virtual void AddJSBuiltinObject(XFA_LPCJSBUILTININFO pBuitinObject);
+ virtual void SetRunAtType(XFA_ATTRIBUTEENUM eRunAt)
+ {
+ m_eRunAtType = eRunAt;
+ }
+ virtual FX_BOOL IsRunAtClient()
+ {
+ return m_eRunAtType != XFA_ATTRIBUTEENUM_Server;
+ }
+ FX_BOOL QueryNodeByFlag(CXFA_Node* refNode, FX_WSTR propname, FXJSE_HVALUE hValue, FX_DWORD dwFlag, FX_BOOL bSetting);
+ FX_BOOL QueryVariableHValue(CXFA_Node* pScriptNode, FX_BSTR szPropName, FXJSE_HVALUE hValue, FX_BOOL bGetter);
+ FX_BOOL QueryBuiltinHValue(FX_BSTR szPropName, FXJSE_HVALUE hValue);
+ static void GlobalPropertyGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue);
+ static void GlobalPropertySetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue);
+ static void NormalPropertyGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue);
+ static void NormalPropertySetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue);
+ static void NormalMethodCall(FXJSE_HOBJECT hThis, FX_BSTR szFuncName, CFXJSE_Arguments &args);
+ static FX_INT32 NormalPropTypeGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FX_BOOL bQueryIn);
+ static FX_INT32 GlobalPropTypeGetter(FXJSE_HOBJECT hObject, FX_BSTR szPropName, FX_BOOL bQueryIn);
+ FX_BOOL RunVariablesScript(CXFA_Node* pScriptNode);
+ CXFA_Object* GetVariablesThis(CXFA_Object* pObject, FX_BOOL bScriptNode = FALSE);
+ void ReleaseVariablesMap();
+ FX_BOOL IsStrictScopeInJavaScript();
+ XFA_SCRIPTLANGTYPE GetType();
+ CXFA_NodeArray& GetUpObjectArray()
+ {
+ return m_upObjectArray;
+ }
+ CXFA_Document* GetDocument() const
+ {
+ return m_pDocument;
+ }
+protected:
+ void DefineJsContext();
+ FXJSE_HCONTEXT CreateVariablesContext(CXFA_Node* pScriptNode, CXFA_Node* pSubform);
+
+ void DefineJsClass();
+ CXFA_Document* m_pDocument;
+ FXJSE_HCONTEXT m_hJsContext;
+ FXJSE_HRUNTIME m_hJsRuntime;
+ FXJSE_HCLASS m_hJsClass;
+ XFA_SCRIPTLANGTYPE m_eScriptType;
+ FXJSE_CLASS m_JsGlobalClass;
+ FXJSE_CLASS m_JsNormalClass;
+ CFX_MapPtrTemplate<CXFA_Object*, FXJSE_HVALUE> m_mapXFAToHValue;
+
+ FXJSE_CLASS m_JsGlobalVariablesClass;
+ CFX_MapPtrTemplate<CXFA_Object*, FXJSE_HCONTEXT> m_mapVariableToHValue;
+ CXFA_EventParam* m_pEventParam;
+ CXFA_NodeArray m_upObjectArray;
+ CFX_PtrArray m_CacheListArray;
+ CXFA_NodeArray* m_pScriptNodeArray;
+ CXFA_ResolveProcessor* m_pResolveProcessor;
+ XFA_HFM2JSCONTEXT m_hFM2JSContext;
+ CXFA_Object* m_pThisObject;
+ CFX_CMapByteStringToPtr m_JSBuiltInObjects;
+ FX_DWORD m_dwBuiltInInFlags;
+ XFA_ATTRIBUTEENUM m_eRunAtType;
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.cpp b/xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.cpp
new file mode 100644
index 0000000000..12da5bc7ea
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.cpp
@@ -0,0 +1,524 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_layoutpseudomodel.h"
+#include "xfa_document_layout_imp.h"
+#include "xfa_layout_appadapter.h"
+CScript_LayoutPseudoModel::CScript_LayoutPseudoModel(CXFA_Document* pDocument)
+ : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_LayoutPseudoModel)
+{
+ m_uScriptHash = XFA_HASHCODE_Layout;
+}
+CScript_LayoutPseudoModel::~CScript_LayoutPseudoModel()
+{
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Ready(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ if (bSetting) {
+ ThrowScriptErrorMessage(XFA_IDS_UNABLE_SET_READY);
+ return;
+ }
+ FX_INT32 iStatus = pNotify->GetLayoutStatus();
+ FXJSE_Value_SetBoolean(hValue, iStatus >= 2);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_HWXY(CFXJSE_Arguments* pArguments, XFA_LAYOUTMODEL_HWXY layoutModel)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if ( iLength < 1 || iLength > 3) {
+ FX_LPCWSTR methodName = NULL;
+ switch (layoutModel) {
+ case XFA_LAYOUTMODEL_H:
+ methodName = (FX_LPCWSTR)(L"h");
+ break;
+ case XFA_LAYOUTMODEL_W:
+ methodName = (FX_LPCWSTR)(L"w");
+ break;
+ case XFA_LAYOUTMODEL_X:
+ methodName = (FX_LPCWSTR)(L"x");
+ break;
+ case XFA_LAYOUTMODEL_Y:
+ methodName = (FX_LPCWSTR)(L"y");
+ break;
+ }
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, methodName);
+ return;
+ }
+ CXFA_Node* pNode = NULL;
+ CFX_WideString wsUnit = FX_WSTRC(L"pt");
+ FX_INT32 iIndex = 0;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ if (iLength >= 2) {
+ CFX_ByteString bsUnit = pArguments->GetUTF8String(1);
+ if (!bsUnit.IsEmpty()) {
+ wsUnit = CFX_WideString::FromUTF8(bsUnit, bsUnit.GetLength());
+ }
+ }
+ if (iLength >= 3) {
+ iIndex = pArguments->GetInt32(2);
+ }
+ if (!pNode) {
+ return;
+ }
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ CFX_RectF rtRect;
+ CXFA_Measurement measure;
+ CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
+ if (!pLayoutItem) {
+ return;
+ }
+ while (iIndex > 0 && pLayoutItem) {
+ pLayoutItem = pLayoutItem->GetNext();
+ iIndex --;
+ }
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (!pLayoutItem) {
+ FXJSE_Value_SetFloat(hValue, 0);
+ return;
+ }
+ pLayoutItem->GetRect(rtRect, TRUE);
+ switch (layoutModel) {
+ case XFA_LAYOUTMODEL_H:
+ measure.Set(rtRect.height, XFA_UNIT_Pt);
+ break;
+ case XFA_LAYOUTMODEL_W:
+ measure.Set(rtRect.width, XFA_UNIT_Pt);
+ break;
+ case XFA_LAYOUTMODEL_X:
+ measure.Set(rtRect.left, XFA_UNIT_Pt);
+ break;
+ case XFA_LAYOUTMODEL_Y:
+ measure.Set(rtRect.top, XFA_UNIT_Pt);
+ break;
+ }
+ XFA_UNIT unit = measure.GetUnit(wsUnit);
+ FX_FLOAT fValue = measure.ToUnit(unit);
+ fValue = FXSYS_round(fValue * 1000) / 1000.0f;
+ if (hValue) {
+ FXJSE_Value_SetFloat(hValue, fValue);
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_H(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_H);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_W(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_W);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_X(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_X);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Y(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_HWXY(pArguments, XFA_LAYOUTMODEL_Y);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_NumberedPageCount(CFXJSE_Arguments* pArguments, FX_BOOL bNumbered)
+{
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ FX_INT32 iPageCount = 0;
+ FX_INT32 iPageNum = pDocLayout->CountPages();
+ if (bNumbered) {
+ for (FX_INT32 i = 0; i < iPageNum; i++) {
+ IXFA_LayoutPage* pLayoutPage = pDocLayout->GetPage(i);
+ if (!pLayoutPage) {
+ continue;
+ }
+ CXFA_Node* pMasterPage = pLayoutPage->GetMasterPage();
+ if (pMasterPage->GetInteger(XFA_ATTRIBUTE_Numbered)) {
+ iPageCount++;
+ }
+ }
+ } else {
+ iPageCount = iPageNum;
+ }
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iPageCount);
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageCount(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_NumberedPageCount(pArguments, TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageSpan(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"pageSpan"));
+ return;
+ }
+ CXFA_Node* pNode = NULL;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ if (!pNode) {
+ return;
+ }
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
+ if (!pLayoutItem) {
+ FXJSE_Value_SetInteger(hValue, -1);
+ return;
+ }
+ FX_INT32 iLast = pLayoutItem->GetLast()->GetPage()->GetPageIndex();
+ FX_INT32 iFirst = pLayoutItem->GetFirst()->GetPage()->GetPageIndex();
+ FX_INT32 iPageSpan = iLast - iFirst + 1;
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iPageSpan);
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Page(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_PageImp(pArguments, FALSE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_GetObjArray(IXFA_DocLayout* pDocLayout, FX_INT32 iPageNo, const CFX_WideString &wsType, FX_BOOL bOnPageArea, CXFA_NodeArray &retArray)
+{
+ CXFA_ContainerLayoutItemImpl* pLayoutPage = (CXFA_ContainerLayoutItemImpl*)pDocLayout->GetPage(iPageNo);
+ if (!pLayoutPage) {
+ return;
+ }
+ if (wsType == FX_WSTRC(L"pageArea")) {
+ if (CXFA_Node* pMasterPage = pLayoutPage->m_pFormNode) {
+ retArray.Add(pMasterPage);
+ }
+ return;
+ }
+ if (wsType == FX_WSTRC(L"contentArea")) {
+ for(CXFA_LayoutItemImpl* pItem = pLayoutPage->m_pFirstChild; pItem; pItem = pItem->m_pNextSibling) {
+ if(pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+ retArray.Add(pItem->m_pFormNode);
+ }
+ }
+ return;
+ }
+ CFX_MapPtrToPtr formItems;
+ formItems.InitHashTable(256, TRUE);
+ if (wsType.IsEmpty()) {
+ if (CXFA_Node* pMasterPage = pLayoutPage->m_pFormNode) {
+ retArray.Add(pMasterPage);
+ }
+ for(CXFA_LayoutItemImpl* pItem = pLayoutPage->m_pFirstChild; pItem; pItem = pItem->m_pNextSibling) {
+ if(pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+ retArray.Add(pItem->m_pFormNode);
+ if(!bOnPageArea) {
+ CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItemImpl, CXFA_TraverseStrategy_ContentLayoutItem> iterator((CXFA_ContentLayoutItemImpl*)pItem->m_pFirstChild);
+ for(CXFA_ContentLayoutItemImpl* pItemChild = iterator.GetCurrent(); pItemChild; pItemChild = iterator.MoveToNext()) {
+ if(!pItemChild->IsContentLayoutItem()) {
+ continue;
+ }
+ XFA_ELEMENT eElementType = pItemChild->m_pFormNode->GetClassID();
+ if (eElementType != XFA_ELEMENT_Field && eElementType != XFA_ELEMENT_Draw
+ && eElementType != XFA_ELEMENT_Subform && eElementType != XFA_ELEMENT_Area) {
+ continue;
+ }
+ if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+ continue;
+ }
+ formItems.SetAt(pItemChild->m_pFormNode, this);
+ retArray.Add(pItemChild->m_pFormNode);
+ }
+ }
+ } else {
+ if(bOnPageArea) {
+ CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItemImpl, CXFA_TraverseStrategy_ContentLayoutItem> iterator((CXFA_ContentLayoutItemImpl*)pItem);
+ for(CXFA_ContentLayoutItemImpl* pItemChild = iterator.GetCurrent(); pItemChild; pItemChild = iterator.MoveToNext()) {
+ if(!pItemChild->IsContentLayoutItem()) {
+ continue;
+ }
+ XFA_ELEMENT eElementType = pItemChild->m_pFormNode->GetClassID();
+ if (eElementType != XFA_ELEMENT_Field && eElementType != XFA_ELEMENT_Draw
+ && eElementType != XFA_ELEMENT_Subform && eElementType != XFA_ELEMENT_Area) {
+ continue;
+ }
+ if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+ continue;
+ }
+ formItems.SetAt(pItemChild->m_pFormNode, this);
+ retArray.Add(pItemChild->m_pFormNode);
+ }
+ }
+ }
+ }
+ return;
+ }
+ XFA_ELEMENT eType = XFA_ELEMENT_UNKNOWN;
+ if (wsType == FX_WSTRC(L"field")) {
+ eType = XFA_ELEMENT_Field;
+ } else if (wsType == FX_WSTRC(L"draw")) {
+ eType = XFA_ELEMENT_Draw;
+ } else if (wsType == FX_WSTRC(L"subform")) {
+ eType = XFA_ELEMENT_Subform;
+ } else if (wsType == FX_WSTRC(L"area")) {
+ eType = XFA_ELEMENT_Area;
+ }
+ if (eType != XFA_ELEMENT_UNKNOWN) {
+ for(CXFA_LayoutItemImpl* pItem = pLayoutPage->m_pFirstChild; pItem; pItem = pItem->m_pNextSibling) {
+ if(pItem->m_pFormNode->GetClassID() == XFA_ELEMENT_ContentArea) {
+ if(!bOnPageArea) {
+ CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItemImpl, CXFA_TraverseStrategy_ContentLayoutItem> iterator((CXFA_ContentLayoutItemImpl*)pItem->m_pFirstChild);
+ for(CXFA_ContentLayoutItemImpl* pItemChild = iterator.GetCurrent(); pItemChild; pItemChild = iterator.MoveToNext()) {
+ if(!pItemChild->IsContentLayoutItem()) {
+ continue;
+ }
+ if (pItemChild->m_pFormNode->GetClassID() != eType) {
+ continue;
+ }
+ if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+ continue;
+ }
+ formItems.SetAt(pItemChild->m_pFormNode, this);
+ retArray.Add(pItemChild->m_pFormNode);
+ }
+ }
+ } else {
+ if(bOnPageArea) {
+ CXFA_NodeIteratorTemplate<CXFA_ContentLayoutItemImpl, CXFA_TraverseStrategy_ContentLayoutItem> iterator((CXFA_ContentLayoutItemImpl*)pItem);
+ for(CXFA_ContentLayoutItemImpl* pItemChild = iterator.GetCurrent(); pItemChild; pItemChild = iterator.MoveToNext()) {
+ if(!pItemChild->IsContentLayoutItem()) {
+ continue;
+ }
+ if (pItemChild->m_pFormNode->GetClassID() != eType) {
+ continue;
+ }
+ if (formItems.GetValueAt(pItemChild->m_pFormNode)) {
+ continue;
+ }
+ formItems.SetAt(pItemChild->m_pFormNode, this);
+ retArray.Add(pItemChild->m_pFormNode);
+ }
+ }
+ }
+ }
+ return;
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageContent(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 3) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"pageContent"));
+ return;
+ }
+ FX_INT32 iIndex = 0;
+ CFX_WideString wsType;
+ FX_BOOL bOnPageArea = FALSE;
+ if (iLength >= 1) {
+ iIndex = pArguments->GetInt32(0);
+ }
+ if (iLength >= 2) {
+ CFX_ByteString bsType = pArguments->GetUTF8String(1);
+ wsType = CFX_WideString::FromUTF8(bsType, bsType.GetLength());
+ }
+ if (iLength >= 3) {
+ bOnPageArea = pArguments->GetInt32(2) == 0 ? FALSE : TRUE;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ CXFA_NodeArray retArray;
+ Script_LayoutPseudoModel_GetObjArray(pDocLayout, iIndex, wsType, bOnPageArea, retArray);
+ CXFA_ArrayNodeList* pArrayNodeList = FX_NEW CXFA_ArrayNodeList(m_pDocument);
+ pArrayNodeList->SetArrayNodeList(retArray);
+ FXJSE_Value_SetObject(pArguments->GetReturnValue(), (CXFA_Object*)pArrayNodeList, m_pDocument->GetScriptContext()->GetJseNormalClass());
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCount(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_NumberedPageCount(pArguments, FALSE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageCountInBatch(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ FX_INT32 iPageCount = pNotify->GetDocProvider()->AbsPageCountInBatch(hDoc);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iPageCount);
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCountInBatch(CFXJSE_Arguments* pArguments)
+{
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ FX_INT32 iPageCount = pNotify->GetDocProvider()->SheetCountInBatch(hDoc);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iPageCount);
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Relayout(CFXJSE_Arguments* pArguments)
+{
+ CXFA_Node* pRootNode = m_pDocument->GetRoot();
+ CXFA_Node* pFormRoot = pRootNode->GetFirstChildByClass(XFA_ELEMENT_Form);
+ FXSYS_assert(pFormRoot);
+ CXFA_Node* pContentRootNode = pFormRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
+ CXFA_LayoutProcessor* pLayoutProcessor = m_pDocument->GetLayoutProcessor();
+ if (pContentRootNode) {
+ pLayoutProcessor->AddChangedContainer(pContentRootNode);
+ }
+ pLayoutProcessor->SetForceReLayout(TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageSpan(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_PageSpan(pArguments);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPageInBatch(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"absPageInBatch"));
+ return;
+ }
+ CXFA_Node* pNode = NULL;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ if (!pNode) {
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ XFA_HWIDGET hWidget = pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
+ if (!hWidget) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ FX_INT32 iPageCount = pNotify->GetDocProvider()->AbsPageInBatch(hDoc, hWidget);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iPageCount);
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetInBatch(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"sheetInBatch"));
+ return;
+ }
+ CXFA_Node* pNode = NULL;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ if (!pNode) {
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ XFA_HWIDGET hWidget = pNotify->GetHWidget(pDocLayout->GetLayoutItem(pNode));
+ if (!hWidget) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ FX_INT32 iPageCount = pNotify->GetDocProvider()->SheetInBatch(hDoc, hWidget);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, iPageCount);
+ }
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_Sheet(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_PageImp(pArguments, TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_RelayoutPageArea(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_SheetCount(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_NumberedPageCount(pArguments, FALSE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_AbsPage(CFXJSE_Arguments* pArguments)
+{
+ Script_LayoutPseudoModel_PageImp(pArguments, TRUE);
+}
+void CScript_LayoutPseudoModel::Script_LayoutPseudoModel_PageImp(CFXJSE_Arguments* pArguments, FX_BOOL bAbsPage)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 1) {
+ FX_LPCWSTR methodName;
+ if (bAbsPage) {
+ methodName = (FX_LPCWSTR)(L"absPage");
+ } else {
+ methodName = (FX_LPCWSTR)(L"page");
+ }
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, methodName);
+ return;
+ }
+ CXFA_Node* pNode = NULL;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ FX_INT32 iPage = 0;
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (!pNode && hValue) {
+ FXJSE_Value_SetInteger(hValue, iPage);
+ }
+ IXFA_DocLayout* pDocLayout = m_pDocument->GetDocLayout();
+ if (!pDocLayout) {
+ return;
+ }
+ CXFA_LayoutItem* pLayoutItem = pDocLayout->GetLayoutItem(pNode);
+ if (!pLayoutItem) {
+ FXJSE_Value_SetInteger(hValue, -1);
+ return;
+ }
+ iPage = pLayoutItem->GetFirst()->GetPage()->GetPageIndex();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, bAbsPage ? iPage : iPage + 1);
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.h b/xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.h
new file mode 100644
index 0000000000..c94742aa3f
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_layoutpseudomodel.h
@@ -0,0 +1,48 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _SCRIPT_LAYOUTPSEUDOMODEL_H_
+#define _SCRIPT_LAYOUTPSEUDOMODEL_H_
+enum XFA_LAYOUTMODEL_HWXY {
+ XFA_LAYOUTMODEL_H,
+ XFA_LAYOUTMODEL_W,
+ XFA_LAYOUTMODEL_X,
+ XFA_LAYOUTMODEL_Y
+};
+class CScript_LayoutPseudoModel : public CXFA_OrdinaryObject
+{
+public:
+ CScript_LayoutPseudoModel(CXFA_Document* pDocument);
+ ~CScript_LayoutPseudoModel();
+
+ void Script_LayoutPseudoModel_Ready(FXJSE_HVALUE hValue, FX_BOOL bSetting, XFA_ATTRIBUTE eAttribute);
+
+ void Script_LayoutPseudoModel_HWXY(CFXJSE_Arguments* pArguments, XFA_LAYOUTMODEL_HWXY layoutModel);
+ void Script_LayoutPseudoModel_H(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_W(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_X(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_Y(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_NumberedPageCount(CFXJSE_Arguments* pArguments, FX_BOOL bNumbered);
+ void Script_LayoutPseudoModel_PageCount(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_PageSpan(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_Page(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_PageContent(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_AbsPageCount(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_AbsPageCountInBatch(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_SheetCountInBatch(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_Relayout(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_AbsPageSpan(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_AbsPageInBatch(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_SheetInBatch(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_Sheet(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_RelayoutPageArea(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_SheetCount(CFXJSE_Arguments* pArguments);
+ void Script_LayoutPseudoModel_AbsPage(CFXJSE_Arguments* pArguments);
+protected:
+ void Script_LayoutPseudoModel_GetObjArray(IXFA_DocLayout* pDocLayout, FX_INT32 iPageNo, const CFX_WideString &wsType, FX_BOOL bOnPageArea, CXFA_NodeArray &retArray);
+ void Script_LayoutPseudoModel_PageImp(CFXJSE_Arguments* pArguments, FX_BOOL bAbsPage);
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.cpp b/xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.cpp
new file mode 100644
index 0000000000..9a4406faf6
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.cpp
@@ -0,0 +1,42 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_logpseudomodel.h"
+CScript_LogPseudoModel::CScript_LogPseudoModel(CXFA_Document* pDocument)
+ : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_LogPseudoModel)
+{
+ m_uScriptHash = XFA_HASHCODE_Log;
+}
+CScript_LogPseudoModel::~CScript_LogPseudoModel()
+{
+}
+void CScript_LogPseudoModel::Script_LogPseudoModel_Message(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_LogPseudoModel::Script_LogPseudoModel_TraceEnabled(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_LogPseudoModel::Script_LogPseudoModel_TraceActivate(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_LogPseudoModel::Script_LogPseudoModel_TraceDeactivate(CFXJSE_Arguments* pArguments)
+{
+}
+void CScript_LogPseudoModel::Script_LogPseudoModel_Trace(CFXJSE_Arguments* pArguments)
+{
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.h b/xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.h
new file mode 100644
index 0000000000..5616f10f5b
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_logpseudomodel.h
@@ -0,0 +1,21 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _SCRIPT_LOGPSEUDOMODEL_H_
+#define _SCRIPT_LOGPSEUDOMODEL_H_
+class CScript_LogPseudoModel : public CXFA_OrdinaryObject
+{
+public:
+ CScript_LogPseudoModel(CXFA_Document* pDocument);
+ virtual ~CScript_LogPseudoModel();
+
+ void Script_LogPseudoModel_Message(CFXJSE_Arguments* pArguments);
+ void Script_LogPseudoModel_TraceEnabled(CFXJSE_Arguments* pArguments);
+ void Script_LogPseudoModel_TraceActivate(CFXJSE_Arguments* pArguments);
+ void Script_LogPseudoModel_TraceDeactivate(CFXJSE_Arguments* pArguments);
+ void Script_LogPseudoModel_Trace(CFXJSE_Arguments* pArguments);
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_nodehelper.cpp b/xfa/src/fxfa/src/parser/xfa_script_nodehelper.cpp
new file mode 100644
index 0000000000..e8cadc900a
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_nodehelper.cpp
@@ -0,0 +1,393 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_nodehelper.h"
+#include "xfa_script_imp.h"
+CXFA_NodeHelper::CXFA_NodeHelper(void)
+ : m_eLastCreateType(XFA_ELEMENT_DataValue), m_pCreateParent(NULL)
+ , m_iCreateCount(0), m_iCreateFlag(XFA_RESOLVENODE_RSTYPE_CreateNodeOne)
+ , m_iCurAllStart(-1), m_pAllStartParent(NULL)
+{
+}
+CXFA_NodeHelper::~CXFA_NodeHelper(void)
+{
+}
+CXFA_Node* CXFA_NodeHelper::XFA_ResolveNodes_GetOneChild(CXFA_Node* parent, FX_LPCWSTR pwsName, FX_BOOL bIsClassName)
+{
+ if(parent == NULL) {
+ return NULL;
+ }
+ CXFA_NodeArray siblings;
+ FX_UINT32 uNameHash = FX_HashCode_String_GetW(pwsName, FXSYS_wcslen(pwsName));
+ XFA_NodeAcc_TraverseAnySiblings(parent, uNameHash, &siblings, bIsClassName);
+ if (siblings.GetSize() == 0) {
+ return NULL;
+ }
+ return siblings[0];
+}
+FX_INT32 CXFA_NodeHelper::XFA_CountSiblings(CXFA_Node* pNode, XFA_LOGIC_TYPE eLogicType, CXFA_NodeArray *pSiblings, FX_BOOL bIsClassName)
+{
+ CXFA_Node* parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_NoTransparent);
+ if(parent == NULL) {
+ return 0;
+ }
+ XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(parent->GetClassID(), pNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+ if(!pPropert && eLogicType == XFA_LOGIC_Transparent) {
+ parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_Transparent);
+ if (parent == NULL) {
+ return 0;
+ }
+ }
+ if(bIsClassName) {
+ return XFA_NodeAcc_TraverseSiblings(parent, pNode->GetClassHashCode(), pSiblings, eLogicType, bIsClassName);
+ } else {
+ return XFA_NodeAcc_TraverseSiblings(parent, pNode->GetNameHash(), pSiblings, eLogicType, bIsClassName);
+ }
+}
+FX_INT32 CXFA_NodeHelper::XFA_NodeAcc_TraverseAnySiblings(CXFA_Node* parent, FX_DWORD dNameHash, CXFA_NodeArray* pSiblings, FX_BOOL bIsClassName )
+{
+ if(parent == NULL || pSiblings == NULL) {
+ return 0;
+ }
+ FX_INT32 nCount = 0;
+ FX_INT32 i = 0;
+ CXFA_NodeArray properties;
+ parent->GetNodeList(properties, XFA_NODEFILTER_Properties);
+ FX_INT32 nProperties = properties.GetSize();
+ for (i = 0; i < nProperties; ++i) {
+ CXFA_Node* child = properties[i];
+ if(bIsClassName) {
+ if (child->GetClassHashCode() == dNameHash) {
+ pSiblings->Add(child);
+ nCount ++;
+ }
+ } else {
+ if (child->GetNameHash() == dNameHash) {
+ pSiblings->Add(child);
+ nCount ++;
+ }
+ }
+ if(nCount > 0) {
+ return nCount;
+ }
+ nCount += XFA_NodeAcc_TraverseAnySiblings(child, dNameHash, pSiblings, bIsClassName);
+ }
+ CXFA_NodeArray children;
+ parent->GetNodeList(children, XFA_NODEFILTER_Children);
+ FX_INT32 nChildren = children.GetSize();
+ for (i = 0; i < nChildren; i ++) {
+ CXFA_Node* child = children[i];
+ if(bIsClassName) {
+ if (child->GetClassHashCode() == dNameHash) {
+ if (pSiblings) {
+ pSiblings->Add(child);
+ }
+ nCount ++;
+ }
+ } else {
+ if (child->GetNameHash() == dNameHash) {
+ if (pSiblings) {
+ pSiblings->Add(child);
+ }
+ nCount ++;
+ }
+ }
+ if(nCount > 0) {
+ return nCount;
+ }
+ nCount += XFA_NodeAcc_TraverseAnySiblings(child, dNameHash, pSiblings, bIsClassName);
+ }
+ return nCount;
+}
+FX_INT32 CXFA_NodeHelper::XFA_NodeAcc_TraverseSiblings(CXFA_Node* parent, FX_DWORD dNameHash, CXFA_NodeArray* pSiblings, XFA_LOGIC_TYPE eLogicType, FX_BOOL bIsClassName, FX_BOOL bIsFindProperty)
+{
+ if (parent == NULL || pSiblings == NULL) {
+ return 0;
+ }
+ FX_INT32 nCount = 0;
+ FX_INT32 i = 0;
+ if(bIsFindProperty) {
+ CXFA_NodeArray properties;
+ parent->GetNodeList(properties, XFA_NODEFILTER_Properties);
+ FX_INT32 nProperties = properties.GetSize();
+ for (i = 0; i < nProperties; ++i) {
+ CXFA_Node* child = properties[i];
+ if(bIsClassName) {
+ if (child->GetClassHashCode() == dNameHash) {
+ pSiblings->Add(child);
+ nCount ++;
+ }
+ } else {
+ if (child->GetNameHash() == dNameHash) {
+ if(child->GetClassID() != XFA_ELEMENT_PageSet && child->GetClassID() != XFA_ELEMENT_Extras
+ && child->GetClassID() != XFA_ELEMENT_Items) {
+ pSiblings->Add(child);
+ nCount ++;
+ }
+ }
+ }
+ if (child->IsUnnamed() && child->GetClassID() == XFA_ELEMENT_PageSet) {
+ nCount += XFA_NodeAcc_TraverseSiblings(child, dNameHash, pSiblings, eLogicType, bIsClassName, FALSE);
+ }
+ }
+ if(nCount > 0) {
+ return nCount;
+ }
+ }
+ CXFA_NodeArray children;
+ parent->GetNodeList(children, XFA_NODEFILTER_Children);
+ FX_INT32 nChildren = children.GetSize();
+ for (i = 0; i < nChildren; i ++) {
+ CXFA_Node* child = children[i];
+ if(child->GetClassID() == XFA_ELEMENT_Variables) {
+ continue;
+ }
+ if(bIsClassName) {
+ if (child->GetClassHashCode() == dNameHash) {
+ if (pSiblings) {
+ pSiblings->Add(child);
+ }
+ nCount ++;
+ }
+ } else {
+ if (child->GetNameHash() == dNameHash) {
+ if (pSiblings) {
+ pSiblings->Add(child);
+ }
+ nCount ++;
+ }
+ }
+ if (eLogicType == XFA_LOGIC_NoTransparent) {
+ continue;
+ }
+ if (XFA_NodeIsTransparent(child) && child->GetClassID() != XFA_ELEMENT_PageSet) {
+ nCount += XFA_NodeAcc_TraverseSiblings(child, dNameHash, pSiblings, eLogicType, bIsClassName, FALSE);
+ }
+ }
+ return nCount;
+}
+CXFA_Node* CXFA_NodeHelper::XFA_ResolveNodes_GetParent(CXFA_Node* pNode, XFA_LOGIC_TYPE eLogicType)
+{
+ if (!pNode) {
+ return NULL;
+ }
+ if (eLogicType == XFA_LOGIC_NoTransparent) {
+ return pNode->GetNodeItem(XFA_NODEITEM_Parent);
+ }
+ CXFA_Node* parent;
+ CXFA_Node* node = pNode;
+ while (TRUE) {
+ parent = XFA_ResolveNodes_GetParent(node);
+ if (parent == NULL) {
+ break;
+ }
+ XFA_ELEMENT parentElement = parent->GetClassID();
+ if ((!parent->IsUnnamed() && parentElement != XFA_ELEMENT_SubformSet) || parentElement == XFA_ELEMENT_Variables) {
+ break;
+ }
+ node = parent;
+ }
+ return parent;
+}
+FX_INT32 CXFA_NodeHelper::XFA_GetIndex(CXFA_Node* pNode, XFA_LOGIC_TYPE eLogicType, FX_BOOL bIsProperty , FX_BOOL bIsClassIndex )
+{
+ CXFA_Node* parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_NoTransparent);
+ if(parent == NULL) {
+ return 0;
+ }
+ if(!bIsProperty && eLogicType == XFA_LOGIC_Transparent) {
+ parent = XFA_ResolveNodes_GetParent(pNode, XFA_LOGIC_Transparent);
+ if (parent == NULL) {
+ return 0;
+ }
+ }
+ FX_DWORD dwHashName = pNode->GetNameHash();
+ if(bIsClassIndex) {
+ dwHashName = pNode->GetClassHashCode();
+ }
+ CXFA_NodeArray siblings;
+ FX_INT32 iSize = XFA_NodeAcc_TraverseSiblings(parent, dwHashName, &siblings, eLogicType, bIsClassIndex);
+ for (FX_INT32 i = 0; i < iSize; ++i) {
+ CXFA_Node* child = siblings[i];
+ if (child == pNode) {
+ return i;
+ }
+ }
+ return 0;
+}
+void CXFA_NodeHelper::XFA_GetNameExpression(CXFA_Node* refNode, CFX_WideString &wsName, FX_BOOL bIsAllPath, XFA_LOGIC_TYPE eLogicType)
+{
+ wsName.Empty();
+ if (bIsAllPath) {
+ XFA_GetNameExpression(refNode, wsName, FALSE, eLogicType);
+ CFX_WideString wsParent;
+ CXFA_Node* parent = XFA_ResolveNodes_GetParent(refNode, XFA_LOGIC_NoTransparent);
+ while (parent != NULL) {
+ XFA_GetNameExpression(parent, wsParent, FALSE, eLogicType);
+ wsParent += L".";
+ wsParent += wsName;
+ wsName = wsParent;
+ parent = XFA_ResolveNodes_GetParent(parent, XFA_LOGIC_NoTransparent);
+ }
+ return;
+ } else {
+ CFX_WideStringC wsTagName;
+ CFX_WideString ws;
+ FX_BOOL bIsProperty = XFA_NodeIsProperty(refNode);
+ if (refNode->IsUnnamed() || (bIsProperty && refNode->GetClassID() != XFA_ELEMENT_PageSet)) {
+ refNode->GetClassName(wsTagName);
+ ws = wsTagName;
+ wsName.Format((FX_LPCWSTR)L"#%s[%d]", (FX_LPCWSTR)ws, XFA_GetIndex(refNode, eLogicType, bIsProperty, TRUE));
+ return;
+ }
+ ws = refNode->GetCData(XFA_ATTRIBUTE_Name);
+ ws.Replace((FX_LPCWSTR)L".", (FX_LPCWSTR)L"\\.");
+ wsName.Format((FX_LPCWSTR)L"%s[%d]", (FX_LPCWSTR)ws, XFA_GetIndex(refNode, eLogicType, bIsProperty, FALSE));
+ }
+}
+FX_BOOL CXFA_NodeHelper::XFA_NodeIsTransparent(CXFA_Node* refNode)
+{
+ if(refNode == NULL) {
+ return FALSE;
+ }
+ XFA_ELEMENT eRefNode = refNode->GetClassID();
+ if((refNode->IsUnnamed() && refNode->IsContainerNode()) || eRefNode == XFA_ELEMENT_SubformSet
+ || eRefNode == XFA_ELEMENT_Area || eRefNode == XFA_ELEMENT_Proto) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_NodeHelper::XFA_CreateNode_ForCondition(CFX_WideString & wsCondition)
+{
+ FX_INT32 iLen = wsCondition.GetLength();
+ CFX_WideString wsIndex = FX_WSTRC(L"0");;
+ FX_BOOL bAll = FALSE;
+ if(iLen == 0) {
+ m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeOne;
+ return FALSE;
+ }
+ if(wsCondition.GetAt(0) == '[') {
+ FX_INT32 i = 1;
+ for (; i < iLen; ++i) {
+ FX_WCHAR ch = wsCondition[i];
+ if (ch == ' ') {
+ continue;
+ }
+ if (ch == '+' || ch == '-') {
+ break;
+ } else if (ch == '*') {
+ bAll = TRUE;
+ break;
+ } else {
+ break;
+ }
+ }
+ if(bAll) {
+ wsIndex = FX_WSTRC(L"1");
+ m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeAll;
+ } else {
+ m_iCreateFlag = XFA_RESOLVENODE_RSTYPE_CreateNodeOne;
+ wsIndex = wsCondition.Mid(i, iLen - 1 - i);
+ }
+ FX_INT32 iIndex = wsIndex.GetInteger();
+ m_iCreateCount = iIndex;
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CXFA_NodeHelper::XFA_ResolveNodes_CreateNode(CFX_WideString wsName, CFX_WideString wsCondition, FX_BOOL bLastNode, CXFA_ScriptContext* pScriptContext)
+{
+ if(m_pCreateParent == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bIsClassName = FALSE;
+ FX_BOOL bResult = FALSE;
+ if(wsName.GetAt(0) == '!') {
+ wsName = wsName.Right(wsName.GetLength() - 1);
+ m_pCreateParent = (CXFA_Node*)pScriptContext->GetDocument()->GetXFANode(XFA_HASHCODE_Datasets);
+ }
+ if(wsName.GetAt(0) == '#') {
+ bIsClassName = TRUE;
+ wsName = wsName.Right(wsName.GetLength() - 1);
+ }
+ if(m_iCreateCount == 0) {
+ XFA_CreateNode_ForCondition(wsCondition);
+ }
+ if(bIsClassName) {
+ XFA_LPCELEMENTINFO lpElement = XFA_GetElementByName(wsName);
+ if(lpElement == NULL) {
+ return FALSE;
+ }
+ for(FX_INT32 iIndex = 0; iIndex < m_iCreateCount; iIndex ++) {
+ CXFA_Node* pNewNode = m_pCreateParent->CreateSamePacketNode(lpElement->eName);
+ if(pNewNode) {
+ m_pCreateParent->InsertChild(pNewNode);
+ if(iIndex == m_iCreateCount - 1) {
+ m_pCreateParent = pNewNode;
+ }
+ bResult = TRUE;
+ }
+ }
+ } else {
+ XFA_ELEMENT eClassType = XFA_ELEMENT_DataGroup;
+ if(bLastNode) {
+ eClassType = m_eLastCreateType;
+ }
+ for(FX_INT32 iIndex = 0; iIndex < m_iCreateCount; iIndex ++) {
+ CXFA_Node* pNewNode = m_pCreateParent->CreateSamePacketNode(eClassType);
+ if(pNewNode) {
+ pNewNode->SetAttribute(XFA_ATTRIBUTE_Name, wsName);
+ pNewNode->CreateXMLMappingNode();
+ m_pCreateParent->InsertChild(pNewNode);
+ if(iIndex == m_iCreateCount - 1) {
+ m_pCreateParent = pNewNode;
+ }
+ bResult = TRUE;
+ }
+ }
+ }
+ if(!bResult) {
+ m_pCreateParent = NULL;
+ }
+ return bResult;
+}
+void CXFA_NodeHelper::XFA_SetCreateNodeType(CXFA_Node* refNode)
+{
+ if(refNode == NULL) {
+ return;
+ }
+ if(refNode->GetClassID() == XFA_ELEMENT_Subform) {
+ m_eLastCreateType = XFA_ELEMENT_DataGroup;
+ } else if(refNode->GetClassID() == XFA_ELEMENT_Field) {
+ m_eLastCreateType = XFA_FieldIsMultiListBox(refNode) ? XFA_ELEMENT_DataGroup : XFA_ELEMENT_DataValue;
+ } else if(refNode->GetClassID() == XFA_ELEMENT_ExclGroup) {
+ m_eLastCreateType = XFA_ELEMENT_DataValue;
+ }
+}
+FX_BOOL CXFA_NodeHelper::XFA_NodeIsProperty(CXFA_Node* refNode)
+{
+ FX_BOOL bRes = FALSE;
+ CXFA_Node* parent = XFA_ResolveNodes_GetParent(refNode, XFA_LOGIC_NoTransparent);
+ if(parent != NULL && refNode != NULL) {
+ XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(parent->GetClassID(), refNode->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+ if(pPropert) {
+ bRes = TRUE;
+ }
+ }
+ return bRes;
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_nodehelper.h b/xfa/src/fxfa/src/parser/xfa_script_nodehelper.h
new file mode 100644
index 0000000000..5b3be76803
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_nodehelper.h
@@ -0,0 +1,41 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_NODEHELPER_H_
+#define _XFA_NODEHELPER_H_
+class CXFA_ScriptContext;
+enum XFA_LOGIC_TYPE {
+ XFA_LOGIC_NoTransparent,
+ XFA_LOGIC_Transparent,
+};
+class CXFA_NodeHelper : public CFX_Object
+{
+public:
+ CXFA_NodeHelper(void);
+ ~CXFA_NodeHelper(void);
+ CXFA_Node* XFA_ResolveNodes_GetOneChild(CXFA_Node* parent, FX_LPCWSTR pwsName, FX_BOOL bIsClassName = FALSE);
+ CXFA_Node* XFA_ResolveNodes_GetParent(CXFA_Node* pNode, XFA_LOGIC_TYPE eLogicType = XFA_LOGIC_NoTransparent);
+
+ FX_INT32 XFA_NodeAcc_TraverseSiblings(CXFA_Node* parent, FX_DWORD dNameHash, CXFA_NodeArray* pSiblings, XFA_LOGIC_TYPE eLogicType, FX_BOOL bIsClassName = FALSE, FX_BOOL bIsFindProperty = TRUE);
+ FX_INT32 XFA_NodeAcc_TraverseAnySiblings(CXFA_Node* parent, FX_DWORD dNameHash, CXFA_NodeArray* pSiblings, FX_BOOL bIsClassName = FALSE);
+ FX_INT32 XFA_CountSiblings(CXFA_Node* pNode, XFA_LOGIC_TYPE eLogicType, CXFA_NodeArray *pSiblings, FX_BOOL bIsClassName = FALSE);
+ FX_INT32 XFA_GetIndex(CXFA_Node* pNode, XFA_LOGIC_TYPE eLogicType = XFA_LOGIC_NoTransparent, FX_BOOL bIsProperty = FALSE, FX_BOOL bIsClassIndex = FALSE);
+ void XFA_GetNameExpression(CXFA_Node* refNode, CFX_WideString &wsName, FX_BOOL bIsAllPath, XFA_LOGIC_TYPE eLogicType = XFA_LOGIC_NoTransparent);
+ FX_BOOL XFA_NodeIsTransparent(CXFA_Node* refNode);
+ FX_BOOL XFA_ResolveNodes_CreateNode(CFX_WideString wsName, CFX_WideString wsCondition, FX_BOOL bLastNode, CXFA_ScriptContext* pScriptContext);
+ FX_BOOL XFA_CreateNode_ForCondition(CFX_WideString & wsCondition);
+ void XFA_SetCreateNodeType(CXFA_Node* refNode);
+ FX_BOOL XFA_NodeIsProperty(CXFA_Node* refNode);
+public:
+ XFA_ELEMENT m_eLastCreateType;
+ CXFA_Node* m_pCreateParent;
+ FX_INT32 m_iCreateCount;
+ XFA_RESOVENODE_RSTYPE m_iCreateFlag;
+ FX_INT32 m_iCurAllStart;
+ CXFA_Node* m_pAllStartParent;
+
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.cpp b/xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.cpp
new file mode 100644
index 0000000000..c133f6b6f1
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.cpp
@@ -0,0 +1,784 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_resolveprocessor.h"
+#include "xfa_script_nodehelper.h"
+#include "xfa_script_imp.h"
+CXFA_ResolveProcessor::CXFA_ResolveProcessor(void)
+ : m_pNodeHelper(NULL), m_iCurStart(0)
+{
+ m_pNodeHelper = FX_NEW CXFA_NodeHelper;
+}
+CXFA_ResolveProcessor::~CXFA_ResolveProcessor(void)
+{
+ if(m_pNodeHelper) {
+ delete m_pNodeHelper;
+ m_pNodeHelper = NULL;
+ }
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes(CXFA_ResolveNodesData &rnd)
+{
+ if (rnd.m_CurNode == NULL) {
+ return -1;
+ }
+ if(!rnd.m_CurNode->IsNode()) {
+ if(rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) {
+ return XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd, rnd.m_wsName);
+ }
+ return 0;
+ }
+ if (rnd.m_dwStyles & XFA_RESOLVENODE_AnyChild) {
+ return XFA_ResolveNodes_AnyChild(rnd);
+ }
+ FX_WCHAR wch = rnd.m_wsName.GetAt(0);
+ switch (wch) {
+ case '$':
+ return XFA_ResolveNodes_Dollar(rnd);
+ case '!':
+ return XFA_ResolveNodes_Excalmatory(rnd);
+ case '#':
+ return XFA_ResolveNodes_NumberSign(rnd);
+ case '*':
+ return XFA_ResolveNodes_Asterisk(rnd);
+ case '.':
+ return XFA_ResolveNodes_AnyChild(rnd);
+ default:
+ break;
+ }
+ if (rnd.m_uHashName == XFA_HASHCODE_This && rnd.m_nLevel == 0) {
+ rnd.m_Nodes.Add(rnd.m_pSC->GetThisObject());
+ return 1;
+ } else if(rnd.m_CurNode->GetClassID() == XFA_ELEMENT_Xfa) {
+ CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFANode(rnd.m_uHashName);
+ if(pObjNode) {
+ rnd.m_Nodes.Add(pObjNode);
+ } else if (rnd.m_uHashName == XFA_HASHCODE_Xfa) {
+ rnd.m_Nodes.Add(rnd.m_CurNode);
+ } else if ((rnd.m_dwStyles & XFA_RESOLVENODE_Attributes) && XFA_ResolveNodes_ForAttributeRs(rnd.m_CurNode, rnd, rnd.m_wsName)) {
+ return 1;
+ }
+ if (rnd.m_Nodes.GetSize() > 0) {
+ XFA_ResolveNode_FilterCondition(rnd, rnd.m_wsCondition);
+ }
+ return rnd.m_Nodes.GetSize();
+ }
+ FX_INT32 nRet = XFA_ResolveNodes_Normal(rnd);
+ if (nRet < 1 && rnd.m_uHashName == XFA_HASHCODE_Xfa) {
+ rnd.m_Nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
+ }
+ return rnd.m_Nodes.GetSize();
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_AnyChild(CXFA_ResolveNodesData &rnd)
+{
+ CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
+ CFX_WideString wsCondition = rnd.m_wsCondition;
+ CXFA_Node* findNode = NULL;
+ CXFA_NodeArray siblings;
+ FX_BOOL bClassName = FALSE;
+ if(wsName.GetAt(0) == '#') {
+ bClassName = TRUE;
+ wsName = wsName.Right(wsName.GetLength() - 1);
+ }
+ findNode = m_pNodeHelper->XFA_ResolveNodes_GetOneChild((CXFA_Node*)rnd.m_CurNode, wsName, bClassName);
+ if (findNode == NULL) {
+ return 0;
+ }
+ if (wsCondition.IsEmpty()) {
+ rnd.m_Nodes.Add(findNode);
+ return rnd.m_Nodes.GetSize();
+ }
+ m_pNodeHelper->XFA_CountSiblings(findNode, XFA_LOGIC_Transparent, (CXFA_NodeArray*)&rnd.m_Nodes, bClassName);
+ XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+ return rnd.m_Nodes.GetSize();
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_Dollar(CXFA_ResolveNodesData &rnd)
+{
+ CXFA_ObjArray &nodes = rnd.m_Nodes;
+ CFX_WideString wsName = rnd.m_wsName;
+ CFX_WideString wsCondition = rnd.m_wsCondition;
+ FX_INT32 iNameLen = wsName.GetLength();
+ if (iNameLen == 1) {
+ nodes.Add(rnd.m_CurNode);
+ return 1;
+ }
+ if (rnd.m_nLevel > 0) {
+ return -1;
+ }
+ FX_DWORD dwNameHash = FX_HashCode_String_GetW((FX_LPCWSTR)wsName + 1, iNameLen - 1);
+ if (dwNameHash == XFA_HASHCODE_Xfa) {
+ nodes.Add(rnd.m_pSC->GetDocument()->GetRoot());
+ } else {
+ CXFA_Object* pObjNode = rnd.m_pSC->GetDocument()->GetXFANode(dwNameHash);
+ if(pObjNode) {
+ rnd.m_Nodes.Add(pObjNode);
+ }
+ }
+ if (rnd.m_Nodes.GetSize() > 0) {
+ XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+ }
+ return rnd.m_Nodes.GetSize();
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_Excalmatory(CXFA_ResolveNodesData &rnd)
+{
+ if (rnd.m_nLevel > 0) {
+ return 0;
+ }
+ CXFA_Node* datasets = (CXFA_Node*)rnd.m_pSC->GetDocument()->GetXFANode(XFA_HASHCODE_Datasets);
+ if (datasets == NULL) {
+ return 0;
+ }
+ CXFA_ResolveNodesData rndFind;
+ rndFind.m_pSC = rnd.m_pSC;
+ rndFind.m_CurNode = datasets;
+ rndFind.m_wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
+ rndFind.m_uHashName = FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
+ rndFind.m_nLevel = rnd.m_nLevel + 1;
+ rndFind.m_dwStyles = XFA_RESOLVENODE_Children;
+ rndFind.m_wsCondition = rnd.m_wsCondition;
+ XFA_ResolveNodes(rndFind);
+ if (rndFind.m_Nodes.GetSize() > 0) {
+ rnd.m_Nodes.Append(rndFind.m_Nodes);
+ rndFind.m_Nodes.RemoveAll();
+ }
+ return rnd.m_Nodes.GetSize();
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_NumberSign(CXFA_ResolveNodesData &rnd)
+{
+ FX_DWORD dwStyles = rnd.m_dwStyles;
+ CFX_WideString wsName = rnd.m_wsName.Right(rnd.m_wsName.GetLength() - 1);
+ CFX_WideString wsCondition = rnd.m_wsCondition;
+ CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
+ if(XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
+ return 1;
+ }
+ CXFA_ResolveNodesData rndFind;
+ rndFind.m_pSC = rnd.m_pSC;
+ rndFind.m_nLevel = rnd.m_nLevel + 1;
+ rndFind.m_dwStyles = rnd.m_dwStyles;
+ rndFind.m_dwStyles |= XFA_RESOLVENODE_TagName;
+ rndFind.m_dwStyles &= ~XFA_RESOLVENODE_Attributes;
+ rndFind.m_wsName = wsName;
+ rndFind.m_uHashName = FX_HashCode_String_GetW(rndFind.m_wsName, rndFind.m_wsName.GetLength());
+ rndFind.m_wsCondition = wsCondition;
+ rndFind.m_CurNode = curNode;
+ XFA_ResolveNodes_Normal(rndFind);
+ if (rndFind.m_Nodes.GetSize() > 0) {
+ if(wsCondition.GetLength() == 0 && rndFind.m_Nodes.Find(curNode) >= 0) {
+ rnd.m_Nodes.Add(curNode);
+ } else {
+ rnd.m_Nodes.Append(rndFind.m_Nodes);
+ rndFind.m_Nodes.RemoveAll();
+ }
+ }
+ return rnd.m_Nodes.GetSize();
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_ForAttributeRs(CXFA_Object* curNode, CXFA_ResolveNodesData &rnd, FX_WSTR strAttr)
+{
+ XFA_LPCSCRIPTATTRIBUTEINFO lpScriptAttribute = XFA_GetScriptAttributeByName(curNode->GetClassID(), strAttr);
+ if(lpScriptAttribute) {
+ rnd.m_pScriptAttribute = lpScriptAttribute;
+ rnd.m_Nodes.Add(curNode);
+ rnd.m_dwFlag = XFA_RESOVENODE_RSTYPE_Attribute;
+ return 1;
+ }
+ return 0;
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_Normal(CXFA_ResolveNodesData &rnd)
+{
+ if (rnd.m_nLevel > 32) {
+ return 0;
+ }
+ if(!rnd.m_CurNode->IsNode()) {
+ return 0;
+ }
+ CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
+ CXFA_ObjArray &nodes = rnd.m_Nodes;
+ FX_INT32 nNum = nodes.GetSize();
+ FX_DWORD dwStyles = rnd.m_dwStyles;
+ CFX_WideString &wsName = rnd.m_wsName;
+ FX_UINT32 uNameHash = rnd.m_uHashName;
+ CFX_WideString &wsCondition = rnd.m_wsCondition;
+ CXFA_ResolveNodesData rndFind;
+ rndFind.m_wsName = rnd.m_wsName;
+ rndFind.m_wsCondition = rnd.m_wsCondition;
+ rndFind.m_pSC = rnd.m_pSC;
+ rndFind.m_nLevel = rnd.m_nLevel + 1;
+ rndFind.m_uHashName = uNameHash;
+ CXFA_NodeArray children;
+ CXFA_NodeArray properties;
+ CXFA_Node* pVariablesNode = NULL;
+ CXFA_Node* pPageSetNode = NULL;
+ CXFA_Node *pChild = curNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ while (pChild) {
+ if(pChild->GetClassID() == XFA_ELEMENT_Variables) {
+ pVariablesNode = pChild;
+ pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ continue;
+ } else if(pChild->GetClassID() == XFA_ELEMENT_PageSet) {
+ pPageSetNode = pChild;
+ pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ continue;
+ } else {
+ XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(curNode->GetClassID(), pChild->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+ if(pPropert) {
+ properties.Add(pChild);
+ } else {
+ children.Add(pChild);
+ }
+ }
+ pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ if((dwStyles & XFA_RESOLVENODE_Properties) && pVariablesNode) {
+ FX_UINT32 uPropHash = pVariablesNode->GetClassHashCode();
+ if (uPropHash == uNameHash) {
+ nodes.Add(pVariablesNode);
+ } else {
+ rndFind.m_CurNode = pVariablesNode;
+ XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
+ CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
+ rndFind.m_wsCondition.Empty();
+ XFA_ResolveNodes_Normal(rndFind);
+ rndFind.m_wsCondition = wsSaveCondition;
+ if (rndFind.m_Nodes.GetSize() > 0) {
+ nodes.Append(rndFind.m_Nodes);
+ rndFind.m_Nodes.RemoveAll();
+ }
+ }
+ if (nodes.GetSize() > nNum) {
+ XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+ if (nodes.GetSize() > 0) {
+ return 1;
+ }
+ return 0;
+ }
+ }
+ if (dwStyles & XFA_RESOLVENODE_Children) {
+ FX_BOOL bSetFlag = FALSE;
+ if(pPageSetNode && (dwStyles & XFA_RESOLVENODE_Properties)) {
+ children.Add(pPageSetNode);
+ }
+ for(FX_INT32 i = 0; i < children.GetSize(); i++) {
+ CXFA_Node* child = children[i];
+ if (dwStyles & XFA_RESOLVENODE_TagName) {
+ if (child->GetClassHashCode() == uNameHash) {
+ nodes.Add(child);
+ }
+ } else if (child->GetNameHash() == uNameHash) {
+ nodes.Add(child);
+ }
+ if (m_pNodeHelper->XFA_NodeIsTransparent(child) && child->GetClassID() != XFA_ELEMENT_PageSet) {
+ if(!bSetFlag) {
+ XFA_ResolveNodes_SetStylesForChild(dwStyles, rndFind);
+ bSetFlag = TRUE;
+ }
+ rndFind.m_CurNode = child;
+ CFX_WideString wsSaveCondition = rndFind.m_wsCondition;
+ rndFind.m_wsCondition.Empty();
+ XFA_ResolveNodes_Normal(rndFind);
+ rndFind.m_wsCondition = wsSaveCondition;
+ if (rndFind.m_Nodes.GetSize() > 0) {
+ nodes.Append(rndFind.m_Nodes);
+ rndFind.m_Nodes.RemoveAll();
+ }
+ }
+ }
+ if (nodes.GetSize() > nNum) {
+ if(!(dwStyles & XFA_RESOLVENODE_ALL)) {
+ CXFA_NodeArray upArrayNodes;
+ if(m_pNodeHelper->XFA_NodeIsTransparent((CXFA_Node*)curNode)) {
+ m_pNodeHelper->XFA_CountSiblings((CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes, dwStyles & XFA_RESOLVENODE_TagName ? TRUE : FALSE);
+ }
+ if(upArrayNodes.GetSize() > nodes.GetSize()) {
+ upArrayNodes[0] = (CXFA_Node*)nodes[0];
+ nodes.RemoveAll();
+ nodes.Append((CXFA_ObjArray &)upArrayNodes);
+ upArrayNodes.RemoveAll();
+ }
+ }
+ XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+ if (nodes.GetSize() > 0) {
+ return 1;
+ }
+ return 0;
+ }
+ }
+ if (dwStyles & XFA_RESOLVENODE_Attributes) {
+ if(XFA_ResolveNodes_ForAttributeRs(curNode, rnd, wsName)) {
+ return 1;
+ }
+ }
+ if (dwStyles & XFA_RESOLVENODE_Properties) {
+ FX_BOOL bSetFlag = FALSE;
+ for(FX_INT32 i = 0; i < properties.GetSize(); i++) {
+ CXFA_Node* childProperty = properties[i];
+ if(childProperty->IsUnnamed()) {
+ FX_UINT32 uPropHash = childProperty->GetClassHashCode();
+ XFA_ELEMENT eName = childProperty->GetClassID();
+ if (uPropHash == uNameHash) {
+ nodes.Add(childProperty);
+ }
+ } else if(childProperty->GetNameHash() == uNameHash && childProperty->GetClassID() != XFA_ELEMENT_Extras
+ && childProperty->GetClassID() != XFA_ELEMENT_Items) {
+ nodes.Add(childProperty);
+ }
+ }
+ if (nodes.GetSize() > nNum) {
+ XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+ if (nodes.GetSize() > 0) {
+ return 1;
+ }
+ return 0;
+ }
+ CXFA_Node* pProp = NULL;
+ if(XFA_ELEMENT_Subform == curNode->GetClassID() && XFA_HASHCODE_Occur == uNameHash) {
+ CXFA_Node* pInstanceManager = ((CXFA_Node*)curNode)->GetInstanceMgrOfSubform();
+ if(pInstanceManager) {
+ pProp = pInstanceManager->GetProperty(0, XFA_ELEMENT_Occur, TRUE);
+ }
+ } else {
+ XFA_LPCELEMENTINFO pElement = XFA_GetElementByName(wsName);
+ if (pElement) {
+ pProp = ((CXFA_Node*)curNode)->GetProperty(0, pElement->eName, pElement->eName != XFA_ELEMENT_PageSet);
+ }
+ }
+ if (pProp) {
+ nodes.Add(pProp);
+ return nodes.GetSize();
+ }
+ }
+ CXFA_Node* parentNode = m_pNodeHelper->XFA_ResolveNodes_GetParent((CXFA_Node *)curNode, XFA_LOGIC_NoTransparent);
+ FX_UINT32 uCurClassHash = curNode->GetClassHashCode();
+ if (parentNode == NULL) {
+ if(uCurClassHash == uNameHash) {
+ nodes.Add((CXFA_Node*)curNode);
+ XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+ if(nodes.GetSize() > 0) {
+ return 1;
+ }
+ }
+ return 0;
+ }
+ if (dwStyles & XFA_RESOLVENODE_Siblings) {
+ CXFA_Node* child = parentNode->GetNodeItem(XFA_NODEITEM_FirstChild);
+ FX_DWORD dwSubStyles = XFA_RESOLVENODE_Children | XFA_RESOLVENODE_Properties;
+ if (dwStyles & XFA_RESOLVENODE_TagName) {
+ dwSubStyles |= XFA_RESOLVENODE_TagName;
+ }
+ if (dwStyles & XFA_RESOLVENODE_ALL) {
+ dwSubStyles |= XFA_RESOLVENODE_ALL;
+ }
+ rndFind.m_dwStyles = dwSubStyles;
+ while (child) {
+ if (child == curNode) {
+ if (dwStyles & XFA_RESOLVENODE_TagName) {
+ if (uCurClassHash == uNameHash) {
+ nodes.Add(curNode);
+ }
+ } else {
+ if (child->GetNameHash() == uNameHash) {
+ nodes.Add(curNode);
+ if(rnd.m_nLevel == 0 && wsCondition.GetLength() == 0) {
+ nodes.RemoveAll();
+ nodes.Add(curNode);
+ return 1;
+ }
+ }
+ }
+ child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
+ continue;
+ }
+ if (dwStyles & XFA_RESOLVENODE_TagName) {
+ if (child->GetClassHashCode() == uNameHash) {
+ nodes.Add(child);
+ }
+ } else if (child->GetNameHash() == uNameHash) {
+ nodes.Add(child);
+ }
+ XFA_LPCPROPERTY pPropert = XFA_GetPropertyOfElement(parentNode->GetClassID(), child->GetClassID(), XFA_XDPPACKET_UNKNOWN);
+ FX_BOOL bInnerSearch = FALSE;
+ if(pPropert) {
+ if((child->GetClassID() == XFA_ELEMENT_Variables || child->GetClassID() == XFA_ELEMENT_PageSet)) {
+ bInnerSearch = TRUE;
+ }
+ } else {
+ if(m_pNodeHelper->XFA_NodeIsTransparent(child)) {
+ bInnerSearch = TRUE;
+ }
+ }
+ if (bInnerSearch) {
+ rndFind.m_CurNode = child;
+ CFX_WideString wsOriginCondition = rndFind.m_wsCondition;
+ rndFind.m_wsCondition.Empty();
+ FX_DWORD dwOriginStyle = rndFind.m_dwStyles;
+ rndFind.m_dwStyles = dwOriginStyle | XFA_RESOLVENODE_ALL;
+ XFA_ResolveNodes_Normal(rndFind);
+ rndFind.m_dwStyles = dwOriginStyle;
+ rndFind.m_wsCondition = wsOriginCondition;
+ if (rndFind.m_Nodes.GetSize() > 0) {
+ nodes.Append(rndFind.m_Nodes);
+ rndFind.m_Nodes.RemoveAll();
+ }
+ }
+ child = child->GetNodeItem(XFA_NODEITEM_NextSibling);
+ }
+ if (nodes.GetSize() > nNum) {
+ if(m_pNodeHelper->XFA_NodeIsTransparent(parentNode)) {
+ CXFA_NodeArray upArrayNodes;
+ m_pNodeHelper->XFA_CountSiblings((CXFA_Node*)nodes[0], XFA_LOGIC_Transparent, &upArrayNodes, dwStyles & XFA_RESOLVENODE_TagName ? TRUE : FALSE);
+ if(upArrayNodes.GetSize() > nodes.GetSize()) {
+ upArrayNodes[0] = (CXFA_Node*)nodes[0];
+ nodes.RemoveAll();
+ nodes.Append((CXFA_ObjArray &)upArrayNodes);
+ upArrayNodes.RemoveAll();
+ }
+ }
+ XFA_ResolveNode_FilterCondition(rnd, wsCondition);
+ if (nodes.GetSize() > 0) {
+ return 1;
+ }
+ return 0;
+ }
+ }
+ if (dwStyles & XFA_RESOLVENODE_Parent) {
+ FX_DWORD dwSubStyles = XFA_RESOLVENODE_Siblings | XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Properties;
+ if (dwStyles & XFA_RESOLVENODE_TagName) {
+ dwSubStyles |= XFA_RESOLVENODE_TagName;
+ }
+ if (dwStyles & XFA_RESOLVENODE_ALL) {
+ dwSubStyles |= XFA_RESOLVENODE_ALL;
+ }
+ rndFind.m_dwStyles = dwSubStyles;
+ rndFind.m_CurNode = parentNode;
+ CXFA_NodeArray& array = rnd.m_pSC->GetUpObjectArray();
+ array.Add(parentNode);
+ XFA_ResolveNodes_Normal(rndFind);
+ if (rndFind.m_Nodes.GetSize() > 0) {
+ nodes.Append(rndFind.m_Nodes);
+ rndFind.m_Nodes.RemoveAll();
+ }
+ if (nodes.GetSize() > nNum) {
+ return 1;
+ }
+ }
+ return 0;
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_Asterisk(CXFA_ResolveNodesData &rnd)
+{
+ CXFA_Node* curNode = (CXFA_Node*)rnd.m_CurNode;
+ CXFA_ObjArray &nodes = rnd.m_Nodes;
+ CXFA_NodeArray array;
+ curNode->GetNodeList(array, XFA_NODEFILTER_Children | XFA_NODEFILTER_Properties);
+ nodes.Append((CXFA_ObjArray &)array);
+ return nodes.GetSize();
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_PopStack(CFX_Int32Array &stack)
+{
+ FX_INT32 nType = -1;
+ FX_INT32 iSize = stack.GetSize() - 1;
+ if (iSize > -1) {
+ nType = stack[iSize];
+ stack.RemoveAt(iSize, 1);
+ }
+ return nType;
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNodes_GetFilter(FX_WSTR wsExpression, FX_INT32 nStart, CXFA_ResolveNodesData &rnd)
+{
+ FXSYS_assert(nStart > -1);
+ FX_INT32 iLength = wsExpression.GetLength();
+ if (nStart >= iLength) {
+ return 0;
+ }
+ CFX_WideString& wsName = rnd.m_wsName;
+ CFX_WideString& wsCondition = rnd.m_wsCondition;
+ FX_LPWSTR pNameBuf = wsName.GetBuffer(iLength - nStart);
+ FX_LPWSTR pConditionBuf = wsCondition.GetBuffer(iLength - nStart);
+ FX_INT32 nCount = 0;
+ FX_INT32 nNameCount = 0;
+ FX_INT32 nConditionCount = 0;
+ CFX_Int32Array stack;
+ FX_INT32 nType = -1;
+ FX_LPCWSTR pSrc = wsExpression.GetPtr();
+ FX_WCHAR wPrev = 0, wCur;
+ FX_BOOL bIsCondition = FALSE;
+ while (nStart < iLength) {
+ wCur = pSrc[nStart ++];
+ if (wCur == '.') {
+ if (wPrev == '\\') {
+ pNameBuf[nNameCount - 1] = wPrev = '.';
+ continue;
+ }
+ if(nNameCount == 0) {
+ pNameBuf[nNameCount ++] = wCur;
+ continue;
+ }
+ FX_WCHAR wLookahead = nStart < iLength ? pSrc [nStart] : 0;
+ if(wLookahead != '[' && wLookahead != '(') {
+ if (nType < 0) {
+ break;
+ }
+ }
+ }
+ if (wCur == '[' || wCur == '(') {
+ bIsCondition = TRUE;
+ } else if (wCur == '.' && nStart < iLength && (pSrc[nStart] == '[' || pSrc[nStart] == '(')) {
+ bIsCondition = TRUE;
+ }
+ if(bIsCondition) {
+ pConditionBuf[nConditionCount ++] = wCur;
+ } else {
+ pNameBuf[nNameCount ++] = wCur;
+ }
+ FX_BOOL bRecursive = TRUE;
+ switch (nType) {
+ case 0:
+ if (wCur == ']') {
+ nType = XFA_ResolveNodes_PopStack(stack);
+ bRecursive = FALSE;
+ }
+ break;
+ case 1:
+ if (wCur == ')') {
+ nType = XFA_ResolveNodes_PopStack(stack);
+ bRecursive = FALSE;
+ }
+ break;
+ case 2:
+ if (wCur == '"') {
+ nType = XFA_ResolveNodes_PopStack(stack);
+ bRecursive = FALSE;
+ }
+ break;
+ }
+ if (bRecursive) {
+ switch (wCur) {
+ case '[':
+ stack.Add(nType);
+ nType = 0;
+ break;
+ case '(':
+ stack.Add(nType);
+ nType = 1;
+ break;
+ case '"':
+ stack.Add(nType);
+ nType = 2;
+ break;
+ }
+ }
+ wPrev = wCur;
+ }
+ if (stack.GetSize() > 0) {
+ return -1;
+ }
+ wsName.ReleaseBuffer(nNameCount);
+ wsName.TrimLeft();
+ wsName.TrimRight();
+ wsCondition.ReleaseBuffer(nConditionCount);
+ wsCondition.TrimLeft();
+ wsCondition.TrimRight();
+ rnd.m_uHashName = FX_HashCode_String_GetW(wsName, wsName.GetLength());
+ return nStart;
+}
+void CXFA_ResolveProcessor::XFA_ResolveNode_ConditionArray(FX_INT32 iCurIndex, CFX_WideString wsCondition, FX_INT32 iFoundCount, CXFA_ResolveNodesData &rnd)
+{
+ CXFA_NodeArray &findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
+ FX_INT32 iLen = wsCondition.GetLength();
+ FX_BOOL bRelative = FALSE;
+ FX_BOOL bAll = FALSE;
+ FX_INT32 i = 1;
+ for (; i < iLen; ++i) {
+ FX_WCHAR ch = wsCondition[i];
+ if (ch == ' ') {
+ continue;
+ }
+ if (ch == '+' || ch == '-') {
+ bRelative = TRUE;
+ break;
+ } else if (ch == '*') {
+ bAll = TRUE;
+ break;
+ } else {
+ break;
+ }
+ }
+ if (bAll) {
+ if(rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+ if(rnd.m_dwStyles & XFA_RESOLVENODE_Bind) {
+ m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
+ m_pNodeHelper->m_iCreateCount = 1;
+ findNodes.RemoveAll();
+ m_pNodeHelper->m_iCurAllStart = -1;
+ m_pNodeHelper->m_pAllStartParent = NULL;
+ } else {
+ if(m_pNodeHelper->m_iCurAllStart == -1) {
+ m_pNodeHelper->m_iCurAllStart = m_iCurStart;
+ m_pNodeHelper->m_pAllStartParent = (CXFA_Node*)rnd.m_CurNode;
+ }
+ }
+ } else if(rnd.m_dwStyles & XFA_RESOLVENODE_BindNew) {
+ if(m_pNodeHelper->m_iCurAllStart == -1) {
+ m_pNodeHelper->m_iCurAllStart = m_iCurStart;
+ }
+ }
+ return;
+ }
+ if (iFoundCount == 1 && !iLen) {
+ return;
+ }
+ CFX_WideString wsIndex;
+ wsIndex = wsCondition.Mid(i, iLen - 1 - i);
+ FX_INT32 iIndex = wsIndex.GetInteger();
+ if (bRelative) {
+ iIndex += iCurIndex;
+ }
+ if (iFoundCount <= iIndex || iIndex < 0) {
+ if(rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+ m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
+ m_pNodeHelper->m_iCreateCount = iIndex - iFoundCount + 1;
+ }
+ findNodes.RemoveAll();
+ } else {
+ CXFA_Node* ret = findNodes[iIndex];
+ findNodes.RemoveAll();
+ findNodes.Add(ret);
+ }
+}
+void CXFA_ResolveProcessor::XFA_ResolveNode_DoPredicateFilter(FX_INT32 iCurIndex, CFX_WideString wsCondition, FX_INT32 iFoundCount, CXFA_ResolveNodesData &rnd)
+{
+ CXFA_NodeArray &findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
+ FXSYS_assert(iFoundCount == findNodes.GetSize());
+ CFX_WideString wsExpression;
+ IXFA_ScriptContext* pContext = NULL;
+ XFA_SCRIPTLANGTYPE eLangType = XFA_SCRIPTLANGTYPE_Unkown;
+ if (wsCondition.Left(2) == FX_WSTRC(L".[") && wsCondition.Right(1) == FX_WSTRC(L"]")) {
+ eLangType = XFA_SCRIPTLANGTYPE_Formcalc;
+ } else if (wsCondition.Left(2) == FX_WSTRC(L".(") && wsCondition.Right(1) == FX_WSTRC(L")")) {
+ eLangType = XFA_SCRIPTLANGTYPE_Javascript;
+ } else {
+ return;
+ }
+ pContext = rnd.m_pSC;
+ wsExpression = wsCondition.Mid(2, wsCondition.GetLength() - 3);
+ for(FX_INT32 i = iFoundCount - 1; i >= 0; i--) {
+ CXFA_Object* node = findNodes[i];
+ FX_BOOL bRet = FALSE;
+ FXJSE_HVALUE pRetValue = FXJSE_Value_Create(rnd.m_pSC->GetRuntime());
+ bRet = pContext->RunScript(eLangType, wsExpression, pRetValue, node);
+ if(!bRet || !FXJSE_Value_ToBoolean(pRetValue)) {
+ findNodes.RemoveAt(i);
+ }
+ FXJSE_Value_Release(pRetValue);
+ }
+ return;
+}
+void CXFA_ResolveProcessor::XFA_ResolveNode_FilterCondition(CXFA_ResolveNodesData &rnd, CFX_WideString wsCondition)
+{
+ CXFA_NodeArray &findNodes = (CXFA_NodeArray&)rnd.m_Nodes;
+ FX_INT32 iCurrIndex = 0;
+ const CXFA_NodeArray &array = rnd.m_pSC->GetUpObjectArray();
+ FX_INT32 iSize = array.GetSize();
+ if (iSize) {
+ CXFA_Node* curNode = array[iSize - 1];
+ FX_BOOL bIsProperty = m_pNodeHelper->XFA_NodeIsProperty(curNode);
+ if(curNode->IsUnnamed() || (bIsProperty && curNode->GetClassID() != XFA_ELEMENT_PageSet)) {
+ iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent, bIsProperty, TRUE);
+ } else {
+ iCurrIndex = m_pNodeHelper->XFA_GetIndex(curNode, XFA_LOGIC_Transparent, bIsProperty, FALSE);
+ }
+ }
+ FX_INT32 iFoundCount = findNodes.GetSize();
+ wsCondition.TrimLeft();
+ wsCondition.TrimRight();
+ FX_INT32 iLen = wsCondition.GetLength();
+ if (!iLen) {
+ if (rnd.m_dwStyles & XFA_RESOLVENODE_ALL) {
+ return;
+ }
+ if (iFoundCount == 1) {
+ return;
+ }
+ if (iFoundCount <= iCurrIndex) {
+ if(rnd.m_dwStyles & XFA_RESOLVENODE_CreateNode) {
+ m_pNodeHelper->m_pCreateParent = (CXFA_Node*)rnd.m_CurNode;
+ m_pNodeHelper->m_iCreateCount = iCurrIndex - iFoundCount + 1;
+ }
+ findNodes.RemoveAll();
+ return;
+ } else {
+ CXFA_Node* ret = findNodes[iCurrIndex];
+ findNodes.RemoveAll();
+ findNodes.Add(ret);
+ return;
+ }
+ }
+ FX_WCHAR wTypeChar = wsCondition[0];
+ switch (wTypeChar) {
+ case '[':
+ XFA_ResolveNode_ConditionArray(iCurrIndex, wsCondition, iFoundCount, rnd);
+ return;
+ case '(':
+ return;
+ case '"':
+ return;
+ case '.':
+ if(iLen > 1 && (wsCondition[1] == '[' || wsCondition[1] == '(')) {
+ XFA_ResolveNode_DoPredicateFilter(iCurrIndex, wsCondition, iFoundCount, rnd);
+ }
+ default:
+ return;
+ }
+}
+void CXFA_ResolveProcessor::XFA_ResolveNodes_SetStylesForChild(FX_DWORD dwParentStyles, CXFA_ResolveNodesData &rnd)
+{
+ FX_DWORD dwSubStyles = XFA_RESOLVENODE_Children;
+ if (dwParentStyles & XFA_RESOLVENODE_TagName) {
+ dwSubStyles |= XFA_RESOLVENODE_TagName;
+ }
+ dwSubStyles &= ~XFA_RESOLVENODE_Parent;
+ dwSubStyles &= ~XFA_RESOLVENODE_Siblings;
+ dwSubStyles &= ~XFA_RESOLVENODE_Properties;
+ dwSubStyles |= XFA_RESOLVENODE_ALL;
+ rnd.m_dwStyles = dwSubStyles;
+}
+FX_INT32 CXFA_ResolveProcessor::XFA_ResolveNode_SetResultCreateNode(XFA_RESOLVENODE_RS& resolveNodeRS, CFX_WideString &wsLastCondition)
+{
+ if(m_pNodeHelper->m_pCreateParent) {
+ resolveNodeRS.nodes.Add(m_pNodeHelper->m_pCreateParent);
+ } else {
+ m_pNodeHelper->XFA_CreateNode_ForCondition(wsLastCondition);
+ }
+ resolveNodeRS.dwFlags = m_pNodeHelper->m_iCreateFlag;
+ if(resolveNodeRS.dwFlags == XFA_RESOLVENODE_RSTYPE_CreateNodeOne) {
+ if(m_pNodeHelper->m_iCurAllStart != -1) {
+ resolveNodeRS.dwFlags = XFA_RESOLVENODE_RSTYPE_CreateNodeMidAll;
+ }
+ }
+ return resolveNodeRS.nodes.GetSize();
+}
+void CXFA_ResolveProcessor::XFA_ResolveNode_SetIndexDataBind(CFX_WideString &wsNextCondition, FX_INT32 &iIndex, FX_INT32 iCount)
+{
+ if(m_pNodeHelper->XFA_CreateNode_ForCondition(wsNextCondition)) {
+ if(m_pNodeHelper->m_eLastCreateType == XFA_ELEMENT_DataGroup) {
+ iIndex = 0;
+ } else {
+ iIndex = iCount - 1;
+ }
+ } else {
+ iIndex = iCount - 1;
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.h b/xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.h
new file mode 100644
index 0000000000..08fe52ddca
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_resolveprocessor.h
@@ -0,0 +1,72 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _XFA_RESOLVEPROCESSOR_H_
+#define _XFA_RESOLVEPROCESSOR_H_
+class CXFA_NodeHelper;
+class CXFA_ScriptContext;
+class CXFA_ResolveNodesData : public CFX_Object
+{
+public:
+ CXFA_ResolveNodesData(CXFA_ScriptContext *pSC = NULL)
+ : m_pSC(pSC)
+ , m_CurNode(NULL)
+ , m_wsName()
+ , m_uHashName(0)
+ , m_wsCondition()
+ , m_nLevel(0)
+ , m_Nodes()
+ , m_dwStyles(XFA_RESOLVENODE_Children)
+ , m_pScriptAttribute(NULL)
+ , m_dwFlag(XFA_RESOVENODE_RSTYPE_Nodes)
+ {
+ }
+ ~CXFA_ResolveNodesData()
+ {
+ m_Nodes.RemoveAll();
+ }
+ CXFA_ScriptContext* m_pSC;
+ CXFA_Object* m_CurNode;
+ CFX_WideString m_wsName;
+ FX_UINT32 m_uHashName;
+ CFX_WideString m_wsCondition;
+ FX_INT32 m_nLevel;
+ CXFA_ObjArray m_Nodes;
+ FX_DWORD m_dwStyles;
+ XFA_LPCSCRIPTATTRIBUTEINFO m_pScriptAttribute;
+ XFA_RESOVENODE_RSTYPE m_dwFlag;
+};
+class CXFA_ResolveProcessor : public CFX_Object
+{
+public:
+ CXFA_ResolveProcessor(void);
+ ~CXFA_ResolveProcessor(void);
+ FX_INT32 XFA_ResolveNodes(CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_AnyChild(CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_Dollar(CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_Excalmatory(CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_NumberSign(CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_Asterisk(CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_Normal(CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_ForAttributeRs(CXFA_Object* curNode, CXFA_ResolveNodesData &rnd, FX_WSTR strAttr);
+ void XFA_ResolveNode_ConditionArray(FX_INT32 iCurIndex, CFX_WideString wsCondition, FX_INT32 iFoundCount, CXFA_ResolveNodesData &rnd);
+ void XFA_ResolveNode_DoPredicateFilter(FX_INT32 iCurIndex, CFX_WideString wsCondition, FX_INT32 iFoundCount, CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNodes_GetFilter(FX_WSTR wsExpression, FX_INT32 nStart, CXFA_ResolveNodesData &rnd);
+ void XFA_ResolveNode_FilterCondition(CXFA_ResolveNodesData &rnd, CFX_WideString wsCondition);
+ FX_INT32 XFA_ResolveNodes_PopStack(CFX_Int32Array &stack);
+ void XFA_ResolveNodes_SetStylesForChild(FX_DWORD dwParentStyles, CXFA_ResolveNodesData &rnd);
+ FX_INT32 XFA_ResolveNode_SetResultCreateNode(XFA_RESOLVENODE_RS& resolveNodeRS, CFX_WideString &wsLastCondition);
+ void XFA_ResolveNode_SetIndexDataBind(CFX_WideString &wsNextCondition, FX_INT32 &iIndex, FX_INT32 iCount);
+ CXFA_NodeHelper* GetNodeHelper()
+ {
+ return m_pNodeHelper;
+ }
+private:
+ CXFA_NodeHelper* m_pNodeHelper;
+public:
+ FX_INT32 m_iCurStart;
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.cpp b/xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.cpp
new file mode 100644
index 0000000000..69b9de1a64
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.cpp
@@ -0,0 +1,122 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+#include "xfa_script_signaturepseudomodel.h"
+CScript_SignaturePseudoModel::CScript_SignaturePseudoModel(CXFA_Document* pDocument)
+ : CXFA_OrdinaryObject(pDocument, XFA_ELEMENT_SignaturePseudoModel)
+{
+ m_uScriptHash = XFA_HASHCODE_Signature;
+}
+CScript_SignaturePseudoModel::~CScript_SignaturePseudoModel()
+{
+}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Verify(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 4) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"verify"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ CXFA_Node* pNode = NULL;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ FX_INT32 bVerify = pNotify->GetDocProvider()->Verify(hDoc, pNode);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetInteger(hValue, bVerify);
+ }
+}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Sign(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 3 || iLength > 7) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"sign"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ CXFA_NodeList* pNodeList = NULL;
+ CFX_WideString wsExpression;
+ CFX_WideString wsXMLIdent;
+ if (iLength >= 1) {
+ pNodeList = (CXFA_NodeList*)pArguments->GetObject(0);
+ }
+ if (iLength >= 2) {
+ CFX_ByteString bsExpression = pArguments->GetUTF8String(1);
+ wsExpression = CFX_WideString::FromUTF8(bsExpression, bsExpression.GetLength());
+ }
+ if (iLength >= 3) {
+ CFX_ByteString bsXMLIdent = pArguments->GetUTF8String(2);
+ wsXMLIdent = CFX_WideString::FromUTF8(bsXMLIdent, bsXMLIdent.GetLength());
+ }
+ FX_BOOL bSign = pNotify->GetDocProvider()->Sign(hDoc, pNodeList, wsExpression, wsXMLIdent);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetBoolean(hValue, bSign);
+ }
+}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Enumerate(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength != 0) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"enumerate"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ CXFA_NodeList *pList = pNotify->GetDocProvider()->Enumerate(hDoc);
+ FXJSE_Value_Set(pArguments->GetReturnValue(), m_pDocument->GetScriptContext()->GetJSValueFromMap(pList));
+}
+void CScript_SignaturePseudoModel::Script_SignaturePseudoModel_Clear(CFXJSE_Arguments* pArguments)
+{
+ FX_INT32 iLength = pArguments->GetLength();
+ if (iLength < 1 || iLength > 2) {
+ ThrowScriptErrorMessage(XFA_IDS_INCORRECT_NUMBER_OF_METHOD, (FX_LPCWSTR)(L"clear"));
+ return;
+ }
+ IXFA_Notify* pNotify = m_pDocument->GetParser()->GetNotify();
+ if (!pNotify) {
+ return;
+ }
+ XFA_HDOC hDoc = pNotify->GetHDOC();
+ CXFA_Node* pNode = NULL;
+ FX_BOOL bClear = TRUE;
+ if (iLength >= 1) {
+ pNode = (CXFA_Node*)pArguments->GetObject(0);
+ }
+ if (iLength >= 2) {
+ bClear = pArguments->GetInt32(1) == 0 ? FALSE : TRUE;
+ }
+ FX_BOOL bFlag = pNotify->GetDocProvider()->Clear(hDoc, pNode, bClear);
+ FXJSE_HVALUE hValue = pArguments->GetReturnValue();
+ if (hValue) {
+ FXJSE_Value_SetBoolean(hValue, bFlag);
+ }
+}
diff --git a/xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.h b/xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.h
new file mode 100644
index 0000000000..d389820ce7
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_script_signaturepseudomodel.h
@@ -0,0 +1,19 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _SCRIPT_SIGNATUREPSEUDOMODEL_H_
+#define _SCRIPT_SIGNATUREPSEUDOMODEL_H_
+class CScript_SignaturePseudoModel : public CXFA_OrdinaryObject
+{
+public:
+ CScript_SignaturePseudoModel(CXFA_Document* pDocument);
+ ~CScript_SignaturePseudoModel();
+ void Script_SignaturePseudoModel_Verify(CFXJSE_Arguments* pArguments);
+ void Script_SignaturePseudoModel_Sign(CFXJSE_Arguments* pArguments);
+ void Script_SignaturePseudoModel_Enumerate(CFXJSE_Arguments* pArguments);
+ void Script_SignaturePseudoModel_Clear(CFXJSE_Arguments* pArguments);
+};
+#endif
diff --git a/xfa/src/fxfa/src/parser/xfa_utils_imp.cpp b/xfa/src/fxfa/src/parser/xfa_utils_imp.cpp
new file mode 100644
index 0000000000..9c7ca9c274
--- /dev/null
+++ b/xfa/src/fxfa/src/parser/xfa_utils_imp.cpp
@@ -0,0 +1,382 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "../common/xfa_utils.h"
+#include "../common/xfa_object.h"
+#include "../common/xfa_document.h"
+#include "../common/xfa_parser.h"
+#include "../common/xfa_script.h"
+#include "../common/xfa_docdata.h"
+#include "../common/xfa_doclayout.h"
+#include "../common/xfa_debug.h"
+#include "../common/xfa_localemgr.h"
+#include "../common/xfa_fm2jsapi.h"
+#include "xfa_debug_parser.h"
+CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType)
+{
+ XFA_ELEMENT eType = pNode->GetClassID();
+ eWidgetType = eType;
+ if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_Draw) {
+ return NULL;
+ }
+ eWidgetType = XFA_ELEMENT_UNKNOWN;
+ XFA_ELEMENT eUIType = XFA_ELEMENT_UNKNOWN;
+ CXFA_Value defValue = pNode->GetProperty(0, XFA_ELEMENT_Value, TRUE);
+ XFA_ELEMENT eValueType = (XFA_ELEMENT)defValue.GetChildValueClassID();
+ switch (eValueType) {
+ case XFA_ELEMENT_Boolean:
+ eUIType = XFA_ELEMENT_CheckButton;
+ break;
+ case XFA_ELEMENT_Integer:
+ case XFA_ELEMENT_Decimal:
+ case XFA_ELEMENT_Float:
+ eUIType = XFA_ELEMENT_NumericEdit;
+ break;
+ case XFA_ELEMENT_ExData:
+ case XFA_ELEMENT_Text:
+ eUIType = XFA_ELEMENT_TextEdit;
+ eWidgetType = XFA_ELEMENT_Text;
+ break;
+ case XFA_ELEMENT_Date:
+ case XFA_ELEMENT_Time:
+ case XFA_ELEMENT_DateTime:
+ eUIType = XFA_ELEMENT_DateTimeEdit;
+ break;
+ case XFA_ELEMENT_Image:
+ eUIType = XFA_ELEMENT_ImageEdit;
+ eWidgetType = XFA_ELEMENT_Image;
+ break;;
+ case XFA_ELEMENT_Arc:
+ case XFA_ELEMENT_Line:
+ case XFA_ELEMENT_Rectangle:
+ eUIType = XFA_ELEMENT_DefaultUi;
+ eWidgetType = eValueType;
+ break;
+ default:
+ break;
+ }
+ CXFA_Node* pUIChild = NULL;
+ CXFA_Node* pUI = pNode->GetProperty(0, XFA_ELEMENT_Ui, TRUE);
+ CXFA_Node *pChild = pUI->GetNodeItem(XFA_NODEITEM_FirstChild);
+ for ( ; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
+ XFA_ELEMENT eChild = pChild->GetClassID();
+ if (eChild == XFA_ELEMENT_Extras || eChild == XFA_ELEMENT_Picture) {
+ continue;
+ }
+ XFA_LPCPROPERTY pProterty = XFA_GetPropertyOfElement(XFA_ELEMENT_Ui, eChild, XFA_XDPPACKET_Form);
+ if (pProterty && (pProterty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
+ pUIChild = pChild;
+ break;
+ }
+ }
+ if(eType == XFA_ELEMENT_Draw) {
+ XFA_ELEMENT eDraw = pUIChild ? pUIChild->GetClassID() : XFA_ELEMENT_UNKNOWN;
+ switch (eDraw) {
+ case XFA_ELEMENT_TextEdit:
+ eWidgetType = XFA_ELEMENT_Text;
+ break;
+ case XFA_ELEMENT_ImageEdit:
+ eWidgetType = XFA_ELEMENT_Image;
+ break;
+ default:
+ eWidgetType = eWidgetType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_Text : eWidgetType;
+ break;
+ }
+ } else {
+ if (pUIChild && pUIChild->GetClassID() == XFA_ELEMENT_DefaultUi) {
+ eWidgetType = XFA_ELEMENT_TextEdit;
+ } else {
+ eWidgetType = pUIChild ? pUIChild->GetClassID() : (eUIType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_TextEdit : eUIType);
+ }
+ }
+ if (!pUIChild) {
+ if (eUIType == XFA_ELEMENT_UNKNOWN) {
+ eUIType = XFA_ELEMENT_TextEdit;
+ ((CXFA_Node*)defValue)->GetProperty(0, XFA_ELEMENT_Text, TRUE);
+ }
+ pUIChild = pUI->GetProperty(0, eUIType, TRUE);
+ } else if (eUIType == XFA_ELEMENT_UNKNOWN) {
+ switch (pUIChild->GetClassID()) {
+ case XFA_ELEMENT_CheckButton: {
+ eValueType = XFA_ELEMENT_Text;
+ if (CXFA_Node* pItems = pNode->GetChild(0, XFA_ELEMENT_Items)) {
+ if (CXFA_Node* pItem = pItems->GetChild(0, XFA_ELEMENT_UNKNOWN)) {
+ eValueType = pItem->GetClassID();
+ }
+ }
+ }
+ break;
+ case XFA_ELEMENT_DateTimeEdit:
+ eValueType = XFA_ELEMENT_DateTime;
+ break;
+ case XFA_ELEMENT_ImageEdit:
+ eValueType = XFA_ELEMENT_Image;
+ break;
+ case XFA_ELEMENT_NumericEdit:
+ eValueType = XFA_ELEMENT_Float;
+ break;
+ case XFA_ELEMENT_ChoiceList: {
+ eValueType = (pUIChild->GetEnum(XFA_ATTRIBUTE_Open) == XFA_ATTRIBUTEENUM_MultiSelect) ? XFA_ELEMENT_ExData : XFA_ELEMENT_Text;
+ }
+ break;
+ case XFA_ELEMENT_Barcode:
+ case XFA_ELEMENT_Button:
+ case XFA_ELEMENT_PasswordEdit:
+ case XFA_ELEMENT_Signature:
+ case XFA_ELEMENT_TextEdit:
+ default:
+ eValueType = XFA_ELEMENT_Text;
+ break;
+ }
+ ((CXFA_Node*)defValue)->GetProperty(0, eValueType, TRUE);
+ }
+ return pUIChild;
+}
+CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData)
+{
+ CXFA_Node* pNodeValue = pWidgetData->GetNode()->GetChild(0, XFA_ELEMENT_Value);
+ if (!pNodeValue) {
+ return CXFA_LocaleValue();
+ }
+ CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (!pValueChild) {
+ return CXFA_LocaleValue();
+ }
+ FX_INT32 iVTType = XFA_VT_NULL;
+ XFA_ELEMENT eType = pValueChild->GetClassID();
+ switch (eType) {
+ case XFA_ELEMENT_Decimal:
+ iVTType = XFA_VT_DECIMAL;
+ break;
+ case XFA_ELEMENT_Float:
+ iVTType = XFA_VT_FLOAT;
+ break;
+ case XFA_ELEMENT_Date:
+ iVTType = XFA_VT_DATE;
+ break;
+ case XFA_ELEMENT_Time:
+ iVTType = XFA_VT_TIME;
+ break;
+ case XFA_ELEMENT_DateTime:
+ iVTType = XFA_VT_DATETIME;
+ break;
+ case XFA_ELEMENT_Boolean:
+ iVTType = XFA_VT_BOOLEAN;
+ break;
+ case XFA_ELEMENT_Integer:
+ iVTType = XFA_VT_INTEGER;
+ break;
+ case XFA_ELEMENT_Text:
+ iVTType = XFA_VT_TEXT;
+ break;
+ default:
+ iVTType = XFA_VT_NULL;
+ break;
+ }
+ return CXFA_LocaleValue(iVTType, pWidgetData->GetRawValue(), pWidgetData->GetNode()->GetDocument()->GetLocalMgr());
+}
+void XFA_GetPlainTextFromRichText(IFDE_XMLNode *pXMLNode, CFX_WideString &wsPlainText)
+{
+ if (pXMLNode == NULL) {
+ return;
+ }
+ switch(pXMLNode->GetType()) {
+ case FDE_XMLNODE_Element: {
+ IFDE_XMLElement *pXMLElement = (IFDE_XMLElement*)pXMLNode;
+ CFX_WideString wsTag;
+ pXMLElement->GetLocalTagName(wsTag);
+ FX_UINT32 uTag = FX_HashCode_String_GetW(wsTag, wsTag.GetLength(), TRUE);
+ if (uTag == 0x0001f714) {
+ wsPlainText += L"\n";
+ } else if (uTag == 0x00000070) {
+ if (!wsPlainText.IsEmpty()) {
+ wsPlainText += L"\n";
+ }
+ } else if (uTag == 0xa48ac63) {
+ if (!wsPlainText.IsEmpty() && wsPlainText[wsPlainText.GetLength() - 1] != '\n') {
+ wsPlainText += L"\n";
+ }
+ }
+ }
+ break;
+ case FDE_XMLNODE_Text: {
+ CFX_WideString wsContent;
+ ((IFDE_XMLText*)pXMLNode)->GetText(wsContent);
+ wsPlainText += wsContent;
+ }
+ break;
+ case FDE_XMLNODE_CharData: {
+ CFX_WideString wsCharData;
+ ((IFDE_XMLCharData*)pXMLNode)->GetCharData(wsCharData);
+ wsPlainText += wsCharData;
+ }
+ break;
+ default:
+ break;
+ }
+ for (IFDE_XMLNode *pChildXML = pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); pChildXML; pChildXML = pChildXML->GetNodeItem(IFDE_XMLNode::NextSibling)) {
+ XFA_GetPlainTextFromRichText(pChildXML, wsPlainText);
+ }
+}
+FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode)
+{
+ FX_BOOL bRet = FALSE;
+ if (!pFieldNode) {
+ return bRet;
+ }
+ CXFA_Node *pUIChild = pFieldNode->GetChild(0, XFA_ELEMENT_Ui);
+ if (pUIChild) {
+ CXFA_Node *pFirstChild = pUIChild->GetNodeItem(XFA_NODEITEM_FirstChild);
+ if (pFirstChild && pFirstChild->GetClassID() == XFA_ELEMENT_ChoiceList) {
+ bRet = pFirstChild->GetEnum(XFA_ATTRIBUTE_Open) == XFA_ATTRIBUTEENUM_MultiSelect;
+ }
+ }
+ return bRet;
+}
+FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer )
+{
+ switch (eElement) {
+ case XFA_ELEMENT_Draw:
+ case XFA_ELEMENT_Field:
+ case XFA_ELEMENT_InstanceManager:
+ return !bLayoutContainer;
+ case XFA_ELEMENT_Area:
+ case XFA_ELEMENT_Subform:
+ case XFA_ELEMENT_ExclGroup:
+ case XFA_ELEMENT_SubformSet:
+ return TRUE;
+ case XFA_ELEMENT_PageArea:
+ case XFA_ELEMENT_Form:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence)
+{
+ switch (ePresence) {
+ case XFA_ATTRIBUTEENUM_Visible:
+ case XFA_ATTRIBUTEENUM_Invisible:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout)
+{
+ switch (eLayout) {
+ case XFA_ATTRIBUTEENUM_Tb:
+ case XFA_ATTRIBUTEENUM_Lr_tb:
+ case XFA_ATTRIBUTEENUM_Rl_tb:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout)
+{
+ switch (eLayout) {
+ case XFA_ATTRIBUTEENUM_Lr_tb:
+ case XFA_ATTRIBUTEENUM_Rl_tb:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+static const FX_DOUBLE fraction_scales[] = {0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001,
+ 0.0000001, 0.00000001, 0.000000001, 0.0000000001, 0.00000000001, 0.000000000001,
+ 0.0000000000001, 0.00000000000001, 0.000000000000001, 0.0000000000000001
+ };
+FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString &wsStringVal)
+{
+ CFX_WideString wsValue = wsStringVal;
+ wsValue.TrimLeft();
+ wsValue.TrimRight();
+ FX_BOOL bValid = TRUE;
+ FX_INT64 nIntegral = 0;
+ FX_DWORD dwFractional = 0;
+ FX_INT32 nExponent = 0;
+ FX_INT32 cc = 0;
+ FX_BOOL bNegative = FALSE, bExpSign = FALSE;
+ FX_LPCWSTR str = (FX_LPCWSTR)wsValue;
+ FX_INT32 len = wsValue.GetLength();
+ if (str[0] == '+') {
+ cc++;
+ } else if (str[0] == '-') {
+ bNegative = TRUE;
+ cc++;
+ }
+ FX_INT32 nIntegralLen = 0;
+ while (cc < len) {
+ if (str[cc] == '.' || str[cc] == 'E' || str[cc] == 'e' || nIntegralLen > 17) {
+ break;
+ }
+ if (!XFA_IsDigit(str[cc])) {
+ return 0;
+ }
+ nIntegral = nIntegral * 10 + str[cc] - '0';
+ cc ++;
+ nIntegralLen++;
+ }
+ nIntegral = bNegative ? -nIntegral : nIntegral;
+ FX_INT32 scale = 0;
+ FX_DOUBLE fraction = 0.0;
+ if (cc < len && str[cc] == '.') {
+ cc ++;
+ while (cc < len) {
+ fraction += fraction_scales[scale] * (str[cc] - '0');
+ scale ++;
+ cc ++;
+ if (cc == len) {
+ break;
+ }
+ if (scale == sizeof (fraction_scales) / sizeof(FX_DOUBLE)
+ || str[cc] == 'E'
+ || str[cc] == 'e') {
+ break;
+ }
+ if (!XFA_IsDigit(str[cc])) {
+ return 0;
+ }
+ }
+ dwFractional = (FX_DWORD)(fraction * 4294967296.0);
+ }
+ if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
+ cc ++;
+ if (cc < len) {
+ if (str[cc] == '+') {
+ cc++;
+ } else if (str[cc] == '-') {
+ bExpSign = TRUE;
+ cc++;
+ }
+ }
+ while (cc < len) {
+ if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
+ return 0;
+ }
+ nExponent = nExponent * 10 + str[cc] - '0';
+ cc ++;
+ }
+ nExponent = bExpSign ? -nExponent : nExponent;
+ }
+ FX_DOUBLE dValue = (dwFractional / 4294967296.0);
+ dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
+ if (nExponent != 0) {
+ dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
+ }
+ return dValue;
+}
+FX_DOUBLE XFA_ByteStringToDouble(FX_BSTR szStringVal)
+{
+ CFX_WideString wsValue = CFX_WideString::FromUTF8(szStringVal.GetCStr(), szStringVal.GetLength());
+ return XFA_WideStringToDouble(wsValue);
+}
diff --git a/xfa/src/fxgraphics/src/fx_graphics.cpp b/xfa/src/fxgraphics/src/fx_graphics.cpp
new file mode 100644
index 0000000000..340d46dfa9
--- /dev/null
+++ b/xfa/src/fxgraphics/src/fx_graphics.cpp
@@ -0,0 +1,1670 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "pre.h"
+#include "fx_path_generator.h"
+class CAGG_Graphics : public CFX_Object
+{
+public:
+ CAGG_Graphics();
+ FX_ERR Create(CFX_Graphics * owner,
+ FX_INT32 width,
+ FX_INT32 height,
+ FXDIB_Format format);
+ virtual ~CAGG_Graphics();
+private:
+ CFX_Graphics * _owner;
+};
+CFX_Graphics::CFX_Graphics()
+{
+ _type = FX_CONTEXT_None;
+ _info._graphState.SetDashCount(0);
+ _info._isAntialiasing = TRUE;
+ _info._strokeAlignment = FX_STROKEALIGNMENT_Center;
+ _info._CTM.Reset();
+ _info._isActOnDash = FALSE;
+ _info._strokeColor = NULL;
+ _info._fillColor = NULL;
+ _info._font = NULL;
+ _info._fontSize = 40.0;
+ _info._fontHScale = 1.0;
+ _info._fontSpacing = 0.0;
+ _renderDevice = NULL;
+ _aggGraphics = NULL;
+}
+FX_ERR CFX_Graphics::Create(CFX_RenderDevice * renderDevice,
+ FX_BOOL isAntialiasing )
+{
+ _FX_RETURN_VALUE_IF_FAIL(renderDevice, FX_ERR_Parameter_Invalid);
+ if (_type != FX_CONTEXT_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_CONTEXT_Device;
+ _info._isAntialiasing = isAntialiasing;
+ _renderDevice = renderDevice;
+ if (_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP) {
+ return FX_ERR_Succeeded;
+ }
+ return FX_ERR_Indefinite;
+}
+FX_ERR CFX_Graphics::Create(FX_INT32 width,
+ FX_INT32 height,
+ FXDIB_Format format,
+ FX_BOOL isNative ,
+ FX_BOOL isAntialiasing )
+{
+ if (_type != FX_CONTEXT_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_CONTEXT_Device;
+ _info._isAntialiasing = isAntialiasing;
+ {
+ _aggGraphics = FX_NEW CAGG_Graphics;
+ return _aggGraphics->Create(this, width, height, format);
+ }
+}
+CFX_Graphics::~CFX_Graphics()
+{
+ if (_aggGraphics) {
+ delete _aggGraphics;
+ _aggGraphics = NULL;
+ }
+ _renderDevice = NULL;
+ _info._graphState.SetDashCount(0);
+ _type = FX_CONTEXT_None;
+}
+FX_ERR CFX_Graphics::GetDeviceCap(const FX_INT32 capID, FX_DeviceCap & capVal)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ capVal = _renderDevice->GetDeviceCaps(capID);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::IsPrinterDevice(FX_BOOL & isPrinter)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_INT32 deviceClass = _renderDevice->GetDeviceClass();
+ if (deviceClass == FXDC_PRINTER) {
+ isPrinter = TRUE;
+ } else {
+ isPrinter = FALSE;
+ }
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._isAntialiasing = isAntialiasing;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SaveGraphState()
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _renderDevice->SaveState();
+ TInfo * info = FX_NEW TInfo;
+ info->_graphState.Copy(_info._graphState);
+ info->_isAntialiasing = _info._isAntialiasing;
+ info->_strokeAlignment = _info._strokeAlignment;
+ info->_CTM = _info._CTM;
+ info->_isActOnDash = _info._isActOnDash;
+ info->_strokeColor = _info._strokeColor;
+ info->_fillColor = _info._fillColor;
+ info->_font = _info._font;
+ info->_fontSize = _info._fontSize;
+ info->_fontHScale = _info._fontHScale;
+ info->_fontSpacing = _info._fontSpacing;
+ _infoStack.Add(info);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::RestoreGraphState()
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _renderDevice->RestoreState();
+ FX_INT32 size = _infoStack.GetSize();
+ if (size <= 0) {
+ return FX_ERR_Intermediate_Value_Invalid;
+ }
+ FX_INT32 topIndex = size - 1;
+ TInfo * info = (TInfo *) _infoStack.GetAt(topIndex);
+ _FX_RETURN_VALUE_IF_FAIL(info, FX_ERR_Intermediate_Value_Invalid);
+ _info._graphState.Copy(info->_graphState);
+ _info._isAntialiasing = info->_isAntialiasing;
+ _info._strokeAlignment = info->_strokeAlignment;
+ _info._CTM = info->_CTM;
+ _info._isActOnDash = info->_isActOnDash;
+ _info._strokeColor = info->_strokeColor;
+ _info._fillColor = info->_fillColor;
+ _info._font = info->_font;
+ _info._fontSize = info->_fontSize;
+ _info._fontHScale = info->_fontHScale;
+ _info._fontSpacing = info->_fontSpacing;
+ delete info;
+ info = NULL;
+ _infoStack.RemoveAt(topIndex);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap & lineCap)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ lineCap = _info._graphState.m_LineCap;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_LineCap = lineCap;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetDashCount(FX_INT32 & dashCount)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ dashCount = _info._graphState.m_DashCount;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetLineDash(FX_FLOAT & dashPhase, FX_FLOAT * dashArray)
+{
+ _FX_RETURN_VALUE_IF_FAIL(dashArray, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ dashPhase = _info._graphState.m_DashPhase;
+ FXSYS_memcpy(dashArray,
+ _info._graphState.m_DashArray,
+ _info._graphState.m_DashCount * sizeof (FX_FLOAT));
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetLineDash(FX_FLOAT dashPhase,
+ FX_FLOAT * dashArray,
+ FX_INT32 dashCount)
+{
+ if (dashCount > 0 && !dashArray) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ dashCount = dashCount < 0 ? 0 : dashCount;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_FLOAT scale = 1.0;
+ if (_info._isActOnDash) {
+ scale = _info._graphState.m_LineWidth;
+ }
+ _info._graphState.m_DashPhase = dashPhase;
+ _info._graphState.SetDashCount(dashCount);
+ for (FX_INT32 i = 0; i < dashCount; i++) {
+ _info._graphState.m_DashArray[i] = dashArray[i] * scale;
+ }
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetLineDash(FX_DashStyle dashStyle)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceSetLineDash(dashStyle);
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetLineJoin(CFX_GraphStateData::LineJoin & lineJoin)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ lineJoin = _info._graphState.m_LineJoin;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_LineJoin = lineJoin;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetMiterLimit(FX_FLOAT & miterLimit)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ miterLimit = _info._graphState.m_MiterLimit;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_MiterLimit = miterLimit;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetLineWidth(FX_FLOAT & lineWidth)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ lineWidth = _info._graphState.m_LineWidth;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash )
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._graphState.m_LineWidth = lineWidth;
+ _info._isActOnDash = isActOnDash;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetStrokeAlignment(FX_StrokeAlignment & strokeAlignment)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ strokeAlignment = _info._strokeAlignment;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._strokeAlignment = strokeAlignment;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetStrokeColor(CFX_Color * color)
+{
+ _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._strokeColor = color;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetFillColor(CFX_Color * color)
+{
+ _FX_RETURN_VALUE_IF_FAIL(color, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fillColor = color;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::StrokePath(CFX_Path * path, CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceStrokePath(path, matrix);
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::FillPath(CFX_Path * path,
+ FX_FillMode fillMode ,
+ CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceFillPath(path, fillMode, matrix);
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::ClipPath(CFX_Path * path,
+ FX_FillMode fillMode ,
+ CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(path, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_BOOL result = _renderDevice->SetClip_PathFill(path->GetPathData(),
+ (CFX_AffineMatrix *) matrix,
+ fillMode);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::DrawImage(CFX_DIBSource * source,
+ const CFX_PointF & point,
+ CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceDrawImage(source, point, matrix);
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::StretchImage(CFX_DIBSource * source,
+ const CFX_RectF & rect,
+ CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(source, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceStretchImage(source, rect, matrix);
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::ConcatMatrix(CFX_Matrix * matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(matrix, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._CTM.Concat(*matrix);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+CFX_Matrix * CFX_Graphics::GetMatrix()
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, NULL);
+ return &_info._CTM;
+ }
+ default: {
+ return NULL;
+ }
+ }
+}
+FX_ERR CFX_Graphics::GetClipRect(CFX_RectF & rect)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_RECT r = _renderDevice->GetClipBox();
+ rect.left = (FX_FLOAT) r.left;
+ rect.top = (FX_FLOAT) r.top;
+ rect.width = (FX_FLOAT) r.Width();
+ rect.height = (FX_FLOAT) r.Height();
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetClipRect(const CFX_RectF & rect)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_RECT r(FXSYS_round(rect.left),
+ FXSYS_round(rect.top),
+ FXSYS_round(rect.right()),
+ FXSYS_round(rect.bottom()));
+ FX_BOOL result = _renderDevice->SetClip_Rect(&r);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::ClearClip()
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_BOOL result = FX_ERR_Succeeded;
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetFont(CFX_Font * font)
+{
+ _FX_RETURN_VALUE_IF_FAIL(font, FX_ERR_Parameter_Invalid);
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._font = font;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetFontSize(const FX_FLOAT size)
+{
+ FX_FLOAT fontSize = size <= 0 ? 1.0f : size;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fontSize = fontSize;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetFontHScale(const FX_FLOAT scale)
+{
+ FX_FLOAT fontHScale = scale <= 0 ? 1.0f : scale;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fontHScale = fontHScale;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing)
+{
+ FX_FLOAT fontSpacing = spacing < 0 ? 0 : spacing;
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ _info._fontSpacing = fontSpacing;
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::SetTextDrawingMode(const FX_INT32 mode)
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::ShowText(const CFX_PointF & point,
+ const CFX_WideString & text,
+ CFX_Matrix * matrix )
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ return RenderDeviceShowText(point, text, matrix);
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::CalcTextRect(CFX_RectF & rect,
+ const CFX_WideString & text,
+ FX_BOOL isMultiline ,
+ CFX_Matrix * matrix )
+{
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ FX_INT32 length = text.GetLength();
+ FX_DWORD * charCodes = FX_Alloc(FX_DWORD, length);
+ FXTEXT_CHARPOS * charPos = FX_Alloc(FXTEXT_CHARPOS,
+ length * sizeof (FXTEXT_CHARPOS));
+ CalcTextInfo(text, charCodes, charPos, rect);
+ FX_Free(charPos);
+ FX_Free(charCodes);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::Transfer(CFX_Graphics * graphics, CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ {
+ _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
+ FX_ERR_Parameter_Invalid);
+ CFX_DIBitmap * bitmap = graphics->_renderDevice->GetBitmap();
+ FX_BOOL result = _renderDevice->SetDIBits(bitmap, 0, 0);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ }
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::Transfer(CFX_Graphics * graphics,
+ FX_FLOAT srcLeft,
+ FX_FLOAT srcTop,
+ const CFX_RectF & dstRect,
+ CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(graphics, FX_ERR_Parameter_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_type) {
+ case FX_CONTEXT_Device: {
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ {
+ _FX_RETURN_VALUE_IF_FAIL(graphics->_renderDevice,
+ FX_ERR_Parameter_Invalid);
+ CFX_DIBitmap * bitmap = graphics->_renderDevice->GetBitmap();
+ FX_BOOL result = FX_ERR_Indefinite;
+ CFX_DIBitmap bmp;
+ result = bmp.Create((FX_INT32) dstRect.width,
+ (FX_INT32) dstRect.height,
+ bitmap->GetFormat());
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Intermediate_Value_Invalid);
+ result = graphics->_renderDevice->GetDIBits(&bmp,
+ (FX_INT32) srcLeft,
+ (FX_INT32) srcTop);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ result = _renderDevice->SetDIBits(&bmp,
+ (FX_INT32) dstRect.left,
+ (FX_INT32) dstRect.top);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Method_Not_Supported);
+ return FX_ERR_Succeeded;
+ }
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+CFX_RenderDevice * CFX_Graphics::GetRenderDevice()
+{
+ return _renderDevice;
+}
+FX_ERR CFX_Graphics::InverseRect(const CFX_RectF & rect)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
+ _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Property_Invalid);
+ CFX_RectF temp(rect);
+ _info._CTM.TransformRect(temp);
+ CFX_RectF r;
+ r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth());
+ r.Intersect(temp);
+ if (r.IsEmpty()) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ FX_ARGB* pBuf = (FX_ARGB*)(bitmap->GetBuffer() + FX_INT32(r.top) * bitmap->GetPitch());
+ FX_INT32 bottom = (FX_INT32)r.bottom();
+ FX_INT32 right = (FX_INT32)r.right();
+ for (FX_INT32 i = (FX_INT32)r.top; i < bottom; i ++) {
+ FX_ARGB* pLine = pBuf + (FX_INT32)r.left;
+ for (FX_INT32 j = (FX_INT32)r.left; j < right; j ++) {
+ FX_ARGB c = *pLine;
+ *pLine ++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF));
+ }
+ pBuf = (FX_ARGB*)((FX_LPBYTE)pBuf + bitmap->GetPitch());
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::XorDIBitmap(const CFX_DIBitmap * srcBitmap, const CFX_RectF & rect)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ CFX_DIBitmap * dst = _renderDevice->GetBitmap();
+ _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
+ CFX_RectF temp(rect);
+ _info._CTM.TransformRect(temp);
+ CFX_RectF r;
+ r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
+ r.Intersect(temp);
+ if (r.IsEmpty()) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + FX_INT32(r.top) * srcBitmap->GetPitch());
+ FX_ARGB* pDstBuf = (FX_ARGB*)(dst->GetBuffer() + FX_INT32(r.top) * dst->GetPitch());
+ FX_INT32 bottom = (FX_INT32)r.bottom();
+ FX_INT32 right = (FX_INT32)r.right();
+ for (FX_INT32 i = (FX_INT32)r.top; i < bottom; i ++) {
+ FX_ARGB* pSrcLine = pSrcBuf + (FX_INT32)r.left;
+ FX_ARGB* pDstLine = pDstBuf + (FX_INT32)r.left;
+ for (FX_INT32 j = (FX_INT32)r.left; j < right; j ++) {
+ FX_ARGB c = *pDstLine;
+ *pDstLine ++ = ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF));
+ pSrcLine ++;
+ }
+ pSrcBuf = (FX_ARGB*)((FX_LPBYTE)pSrcBuf + srcBitmap->GetPitch());
+ pDstBuf = (FX_ARGB*)((FX_LPBYTE)pDstBuf + dst->GetPitch());
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap * srcBitmap, const CFX_RectF & rect)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_renderDevice, FX_ERR_Property_Invalid);
+ CFX_DIBitmap * dst = _renderDevice->GetBitmap();
+ _FX_RETURN_VALUE_IF_FAIL(dst, FX_ERR_Property_Invalid);
+ CFX_RectF temp(rect);
+ _info._CTM.TransformRect(temp);
+ CFX_RectF r;
+ r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth());
+ r.Intersect(temp);
+ if (r.IsEmpty()) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + FX_INT32(r.top) * srcBitmap->GetPitch());
+ FX_ARGB* pDstBuf = (FX_ARGB*)(dst->GetBuffer() + FX_INT32(r.top) * dst->GetPitch());
+ FX_INT32 bottom = (FX_INT32)r.bottom();
+ FX_INT32 right = (FX_INT32)r.right();
+ for (FX_INT32 i = (FX_INT32)r.top; i < bottom; i ++) {
+ FX_ARGB* pSrcLine = pSrcBuf + (FX_INT32)r.left;
+ FX_ARGB* pDstLine = pDstBuf + (FX_INT32)r.left;
+ for (FX_INT32 j = (FX_INT32)r.left; j < right; j ++) {
+ FX_ARGB c = *pDstLine;
+ *pDstLine ++ = ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)));
+ pSrcLine ++;
+ }
+ pSrcBuf = (FX_ARGB*)((FX_LPBYTE)pSrcBuf + srcBitmap->GetPitch());
+ pDstBuf = (FX_ARGB*)((FX_LPBYTE)pDstBuf + dst->GetPitch());
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle)
+{
+ switch (dashStyle) {
+ case FX_DASHSTYLE_Solid: {
+ _info._graphState.SetDashCount(0);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_Dash: {
+ FX_FLOAT dashArray[] = {3, 1};
+ SetLineDash(0, dashArray, 2);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_Dot: {
+ FX_FLOAT dashArray[] = {1, 1};
+ SetLineDash(0, dashArray, 2);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_DashDot: {
+ FX_FLOAT dashArray[] = {3, 1, 1, 1};
+ SetLineDash(0, dashArray, 4);
+ return FX_ERR_Succeeded;
+ }
+ case FX_DASHSTYLE_DashDotDot: {
+ FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
+ SetLineDash(0, dashArray, 6);
+ return FX_ERR_Succeeded;
+ }
+ default: {
+ return FX_ERR_Parameter_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::RenderDeviceStrokePath(CFX_Path * path, CFX_Matrix * matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_info._strokeColor, FX_ERR_Property_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_info._strokeColor->_type) {
+ case FX_COLOR_Solid: {
+ FX_BOOL result = _renderDevice->DrawPath(path->GetPathData(),
+ (CFX_AffineMatrix *) &m,
+ &_info._graphState,
+ 0x0,
+ _info._strokeColor->_argb,
+ 0);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ return FX_ERR_Succeeded;
+ }
+ case FX_COLOR_Pattern: {
+ return StrokePathWithPattern(path, &m);
+ }
+ case FX_COLOR_Shading: {
+ return StrokePathWithShading(path, &m);
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::RenderDeviceFillPath(CFX_Path * path,
+ FX_FillMode fillMode,
+ CFX_Matrix * matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_info._fillColor, FX_ERR_Property_Invalid);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ switch (_info._fillColor->_type) {
+ case FX_COLOR_Solid: {
+ FX_BOOL result = _renderDevice->DrawPath(path->GetPathData(),
+ (CFX_AffineMatrix *) &m,
+ &_info._graphState,
+ _info._fillColor->_argb,
+ 0x0,
+ fillMode);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ return FX_ERR_Succeeded;
+ }
+ case FX_COLOR_Pattern: {
+ {
+ return FillPathWithPattern(path, fillMode, &m);
+ }
+ }
+ case FX_COLOR_Shading: {
+ {
+ return FillPathWithShading(path, fillMode, &m);
+ }
+ }
+ default: {
+ return FX_ERR_Property_Invalid;
+ }
+ }
+}
+FX_ERR CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource * source,
+ const CFX_PointF & point,
+ CFX_Matrix * matrix)
+{
+ CFX_Matrix m1;
+ m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
+ if (matrix) {
+ m1.Concat(*matrix);
+ }
+ CFX_Matrix m2;
+ m2.Set((FX_FLOAT) source->GetWidth(),
+ 0.0,
+ 0.0,
+ (FX_FLOAT) source->GetHeight(),
+ point.x,
+ point.y);
+ m2.Concat(m1);
+ FX_INT32 left, top;
+ CFX_DIBitmap * bmp1 = source->FlipImage(FALSE, TRUE);
+ CFX_DIBitmap * bmp2 = bmp1->TransformTo((CFX_AffineMatrix *) &m2, left, top);
+ CFX_RectF r;
+ GetClipRect(r);
+ FX_ERR result = FX_ERR_Indefinite;
+ {
+ CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
+ CFX_DIBitmap bmp;
+ bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb);
+ _renderDevice->GetDIBits(&bmp, 0, 0);
+ bmp.TransferBitmap(FXSYS_round(r.left),
+ FXSYS_round(r.top),
+ FXSYS_round(r.Width()),
+ FXSYS_round(r.Height()),
+ bmp2,
+ FXSYS_round(r.left - left),
+ FXSYS_round(r.top - top));
+ _renderDevice->SetDIBits(&bmp, 0, 0);
+ result = FX_ERR_Succeeded;
+ }
+ if (bmp2) {
+ delete bmp2;
+ bmp2 = NULL;
+ }
+ if (bmp1) {
+ delete bmp1;
+ bmp1 = NULL;
+ }
+ return result;
+}
+FX_ERR CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource * source,
+ const CFX_RectF & rect,
+ CFX_Matrix * matrix)
+{
+ CFX_Matrix m1;
+ m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
+ if (matrix) {
+ m1.Concat(*matrix);
+ }
+ CFX_DIBitmap * bmp1 = source->StretchTo((FX_INT32) rect.Width(),
+ (FX_INT32) rect.Height());
+ CFX_Matrix m2;
+ m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top);
+ m2.Concat(m1);
+ FX_INT32 left, top;
+ CFX_DIBitmap * bmp2 = bmp1->FlipImage(FALSE, TRUE);
+ CFX_DIBitmap * bmp3 = bmp2->TransformTo((CFX_AffineMatrix *) &m2, left, top);
+ CFX_RectF r;
+ GetClipRect(r);
+ FX_ERR result = FX_ERR_Indefinite;
+ {
+ CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
+ bitmap->CompositeBitmap(FXSYS_round(r.left),
+ FXSYS_round(r.top),
+ FXSYS_round(r.Width()),
+ FXSYS_round(r.Height()),
+ bmp3,
+ FXSYS_round(r.left - left),
+ FXSYS_round(r.top - top));
+ result = FX_ERR_Succeeded;
+ }
+ if (bmp3) {
+ delete bmp3;
+ bmp3 = NULL;
+ }
+ if (bmp2) {
+ delete bmp2;
+ bmp2 = NULL;
+ }
+ if (bmp1) {
+ delete bmp1;
+ bmp1 = NULL;
+ }
+ return result;
+}
+FX_ERR CFX_Graphics::RenderDeviceShowText(const CFX_PointF & point,
+ const CFX_WideString & text,
+ CFX_Matrix * matrix)
+{
+ FX_INT32 length = text.GetLength();
+ FX_DWORD * charCodes = FX_Alloc(FX_DWORD, length);
+ FXTEXT_CHARPOS * charPos = FX_Alloc(FXTEXT_CHARPOS,
+ length * sizeof (FXTEXT_CHARPOS));
+ CFX_RectF rect;
+ rect.Set(point.x, point.y, 0, 0);
+ CalcTextInfo(text, charCodes, charPos, rect);
+ CFX_Matrix m;
+ m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, _info._CTM.f);
+ m.Translate(0, _info._fontSize * _info._fontHScale);
+ if (matrix) {
+ m.Concat(*matrix);
+ }
+ FX_BOOL result = _renderDevice->DrawNormalText(length,
+ charPos,
+ _info._font,
+ CFX_GEModule::Get()->GetFontCache(),
+ -_info._fontSize * _info._fontHScale,
+ (CFX_AffineMatrix *) &m,
+ _info._fillColor->_argb,
+ FXTEXT_CLEARTYPE);
+ _FX_RETURN_VALUE_IF_FAIL(result, FX_ERR_Indefinite);
+ FX_Free(charPos);
+ FX_Free(charCodes);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::StrokePathWithPattern(CFX_Path * path, CFX_Matrix * matrix)
+{
+ return FX_ERR_Method_Not_Supported;
+}
+FX_ERR CFX_Graphics::StrokePathWithShading(CFX_Path * path, CFX_Matrix * matrix)
+{
+ return FX_ERR_Method_Not_Supported;
+}
+FX_ERR CFX_Graphics::FillPathWithPattern(CFX_Path * path,
+ FX_FillMode fillMode,
+ CFX_Matrix * matrix)
+{
+ CFX_Pattern * pattern = _info._fillColor->_pattern;
+ CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
+ FX_INT32 width = bitmap->GetWidth();
+ FX_INT32 height = bitmap->GetHeight();
+ CFX_DIBitmap bmp;
+ bmp.Create(width, height, FXDIB_Argb);
+ _renderDevice->GetDIBits(&bmp, 0, 0);
+ switch (pattern->_type) {
+ case FX_PATTERN_Bitmap: {
+ FX_INT32 xStep = FXSYS_round(pattern->_x1Step);
+ FX_INT32 yStep = FXSYS_round(pattern->_y1Step);
+ FX_INT32 xCount = width / xStep + 1;
+ FX_INT32 yCount = height / yStep + 1;
+ for (FX_INT32 i = 0; i <= yCount; i++) {
+ for (FX_INT32 j = 0; j <= xCount; j++) {
+ bmp.TransferBitmap(j * xStep,
+ i * yStep,
+ xStep,
+ yStep,
+ pattern->_bitmap,
+ 0,
+ 0);
+ }
+ }
+ break;
+ }
+ case FX_PATTERN_Hatch: {
+ FX_HatchStyle hatchStyle = _info._fillColor->_pattern->_hatchStyle;
+ if (hatchStyle < FX_HATCHSTYLE_Horizontal || hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
+ return FX_ERR_Intermediate_Value_Invalid;
+ }
+ const FX_HATCHDATA & data = hatchBitmapData[hatchStyle];
+ CFX_DIBitmap mask;
+ mask.Create(data.width, data.height, FXDIB_1bppMask);
+ FXSYS_memcpy(mask.GetBuffer(), data.maskBits, mask.GetPitch() * data.height);
+ CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox();
+ if (matrix) {
+ rectf.Transform((const CFX_AffineMatrix *) matrix);
+ }
+ FX_RECT rect(FXSYS_round(rectf.left),
+ FXSYS_round(rectf.top),
+ FXSYS_round(rectf.right),
+ FXSYS_round(rectf.bottom));
+ CFX_FxgeDevice device;
+ device.Attach(&bmp);
+ device.FillRect(&rect, _info._fillColor->_pattern->_backArgb);
+ for (FX_INT32 j = rect.bottom; j < rect.top; j += mask.GetHeight()) {
+ for (FX_INT32 i = rect.left; i < rect.right; i += mask.GetWidth()) {
+ device.SetBitMask(&mask, i, j, _info._fillColor->_pattern->_foreArgb);
+ }
+ }
+ break;
+ }
+ }
+ _renderDevice->SaveState();
+ _renderDevice->SetClip_PathFill(path->GetPathData(),
+ (CFX_AffineMatrix *) matrix,
+ fillMode);
+ SetDIBitsWithMatrix(&bmp, &pattern->_matrix);
+ _renderDevice->RestoreState();
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::FillPathWithShading(CFX_Path * path,
+ FX_FillMode fillMode,
+ CFX_Matrix * matrix)
+{
+ CFX_DIBitmap * bitmap = _renderDevice->GetBitmap();
+ FX_INT32 width = bitmap->GetWidth();
+ FX_INT32 height = bitmap->GetHeight();
+ FX_FLOAT start_x = _info._fillColor->_shading->_beginPoint.x;
+ FX_FLOAT start_y = _info._fillColor->_shading->_beginPoint.y;
+ FX_FLOAT end_x = _info._fillColor->_shading->_endPoint.x;
+ FX_FLOAT end_y = _info._fillColor->_shading->_endPoint.y;
+ CFX_DIBitmap bmp;
+ bmp.Create(width, height, FXDIB_Argb);
+ _renderDevice->GetDIBits(&bmp, 0, 0);
+ FX_INT32 pitch = bmp.GetPitch();
+ FX_BOOL result = FALSE;
+ switch (_info._fillColor->_shading->_type) {
+ case FX_SHADING_Axial: {
+ FX_FLOAT x_span = end_x - start_x;
+ FX_FLOAT y_span = end_y - start_y;
+ FX_FLOAT axis_len_square = FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span);
+ for (FX_INT32 row = 0; row < height; row++) {
+ FX_DWORD * dib_buf = (FX_DWORD *) (bmp.GetBuffer() + row * pitch);
+ for (FX_INT32 column = 0; column < width; column++) {
+ FX_FLOAT x = (FX_FLOAT)(column);
+ FX_FLOAT y = (FX_FLOAT)(row);
+ FX_FLOAT scale = FXSYS_Div(FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span),
+ axis_len_square);
+ if (scale < 0) {
+ if (!_info._fillColor->_shading->_isExtendedBegin) {
+ continue;
+ }
+ scale = 0;
+ } else if (scale > 1.0f) {
+ if (!_info._fillColor->_shading->_isExtendedEnd) {
+ continue;
+ }
+ scale = 1.0f;
+ }
+ FX_INT32 index = (FX_INT32)(scale * (FX_SHADING_Steps - 1));
+ dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
+ }
+ }
+ result = TRUE;
+ break;
+ }
+ case FX_SHADING_Radial: {
+ FX_FLOAT start_r = _info._fillColor->_shading->_beginRadius;
+ FX_FLOAT end_r = _info._fillColor->_shading->_endRadius;
+ FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) + FXSYS_Mul(start_y - end_y, start_y - end_y) - FXSYS_Mul(start_r - end_r, start_r - end_r);
+ for (FX_INT32 row = 0; row < height; row++) {
+ FX_DWORD * dib_buf = (FX_DWORD *) (bmp.GetBuffer() + row * pitch);
+ for (FX_INT32 column = 0; column < width; column++) {
+ FX_FLOAT x = (FX_FLOAT)(column);
+ FX_FLOAT y = (FX_FLOAT)(row);
+ FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) + FXSYS_Mul(y - start_y, end_y - start_y) +
+ FXSYS_Mul(start_r, end_r - start_r));
+ FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) + FXSYS_Mul(y - start_y, y - start_y) -
+ FXSYS_Mul(start_r, start_r);
+ FX_FLOAT s;
+ if (a == 0) {
+ s = (FXSYS_Div(-c, b));
+ } else {
+ FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c);
+ if (b2_4ac < 0) {
+ continue;
+ }
+ FX_FLOAT root = (FXSYS_sqrt(b2_4ac));
+ FX_FLOAT s1, s2;
+ if (a > 0) {
+ s1 = FXSYS_Div(-b - root, 2 * a);
+ s2 = FXSYS_Div(-b + root, 2 * a);
+ } else {
+ s2 = FXSYS_Div(-b - root, 2 * a);
+ s1 = FXSYS_Div(-b + root, 2 * a);
+ }
+ if (s2 <= 1.0f || _info._fillColor->_shading->_isExtendedEnd) {
+ s = (s2);
+ } else {
+ s = (s1);
+ }
+ if ((start_r) + s * (end_r - start_r) < 0) {
+ continue;
+ }
+ }
+ if (s < 0) {
+ if (!_info._fillColor->_shading->_isExtendedBegin) {
+ continue;
+ }
+ s = 0;
+ }
+ if (s > 1.0f) {
+ if (!_info._fillColor->_shading->_isExtendedEnd) {
+ continue;
+ }
+ s = 1.0f;
+ }
+ int index = (FX_INT32)(s * (FX_SHADING_Steps - 1));
+ dib_buf[column] = _info._fillColor->_shading->_argbArray[index];
+ }
+ }
+ result = TRUE;
+ break;
+ }
+ default: {
+ result = FALSE;
+ }
+ }
+ if (result) {
+ _renderDevice->SaveState();
+ _renderDevice->SetClip_PathFill(path->GetPathData(),
+ (CFX_AffineMatrix *) matrix,
+ fillMode);
+ SetDIBitsWithMatrix(&bmp, matrix);
+ _renderDevice->RestoreState();
+ }
+ return result;
+}
+FX_ERR CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource * source, CFX_Matrix * matrix)
+{
+ if (matrix->IsIdentity()) {
+ _renderDevice->SetDIBits(source, 0, 0);
+ } else {
+ CFX_Matrix m;
+ m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0, 0);
+ m.Concat(*matrix);
+ FX_INT32 left, top;
+ CFX_DIBitmap * bmp1 = source->FlipImage(FALSE, TRUE);
+ CFX_DIBitmap * bmp2 = bmp1->TransformTo((CFX_AffineMatrix *) &m, left, top);
+ _renderDevice->SetDIBits(bmp2, left, top);
+ if (bmp2) {
+ delete bmp2;
+ bmp2 = NULL;
+ }
+ if (bmp1) {
+ delete bmp1;
+ bmp1 = NULL;
+ }
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Graphics::CalcTextInfo(const CFX_WideString & text, FX_DWORD * charCodes, FXTEXT_CHARPOS * charPos, CFX_RectF & rect)
+{
+ IFX_FontEncoding * encoding = FXGE_CreateUnicodeEncoding(_info._font);
+ FX_INT32 length = text.GetLength();
+ FX_FLOAT penX = (FX_FLOAT) rect.left;
+ FX_FLOAT penY = (FX_FLOAT) rect.top;
+ FX_FLOAT left = (FX_FLOAT)(0);
+ FX_FLOAT top = (FX_FLOAT)(0);
+ charCodes[0] = text.GetAt(0);
+ charPos[0].m_OriginX = penX + left;
+ charPos[0].m_OriginY = penY + top;
+ charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]);
+ charPos[0].m_FontCharWidth = FXSYS_round(_info._font->GetGlyphWidth(charPos[0].m_GlyphIndex) * _info._fontHScale);
+ charPos[0].m_bGlyphAdjust = TRUE;
+ charPos[0].m_AdjustMatrix[0] = -1;
+ charPos[0].m_AdjustMatrix[1] = 0;
+ charPos[0].m_AdjustMatrix[2] = 0;
+ charPos[0].m_AdjustMatrix[3] = 1;
+ penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * _info._fontSize / 1000 + _info._fontSpacing;
+ for (FX_INT32 i = 1; i < length; i++) {
+ charCodes[i] = text.GetAt(i);
+ charPos[i].m_OriginX = penX + left;
+ charPos[i].m_OriginY = penY + top;
+ charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]);
+ charPos[i].m_FontCharWidth = FXSYS_round(_info._font->GetGlyphWidth(charPos[i].m_GlyphIndex) * _info._fontHScale);
+ charPos[i].m_bGlyphAdjust = TRUE;
+ charPos[i].m_AdjustMatrix[0] = -1;
+ charPos[i].m_AdjustMatrix[1] = 0;
+ charPos[i].m_AdjustMatrix[2] = 0;
+ charPos[i].m_AdjustMatrix[3] = 1;
+ penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * _info._fontSize / 1000 + _info._fontSpacing;
+ }
+ rect.width = (FX_FLOAT) penX - rect.left;
+ rect.height = rect.top + _info._fontSize * _info._fontHScale - rect.top;
+ delete encoding;
+ encoding = NULL;
+ return FX_ERR_Succeeded;
+}
+CAGG_Graphics::CAGG_Graphics()
+{
+ _owner = NULL;
+}
+FX_ERR CAGG_Graphics::Create(CFX_Graphics * owner,
+ FX_INT32 width,
+ FX_INT32 height,
+ FXDIB_Format format)
+{
+ if (owner->_renderDevice) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ if (_owner) {
+ return FX_ERR_Property_Invalid;
+ }
+ CFX_FxgeDevice * device = FX_NEW CFX_FxgeDevice;
+ device->Create(width, height, format);
+ _owner = owner;
+ _owner->_renderDevice = device;
+ _owner->_renderDevice->GetBitmap()->Clear(0xFFFFFFFF);
+ return FX_ERR_Succeeded;
+}
+CAGG_Graphics::~CAGG_Graphics()
+{
+ if (_owner->_renderDevice) {
+ delete (CFX_FxgeDevice *) _owner->_renderDevice;
+ }
+ _owner = NULL;
+}
+CFX_Path::CFX_Path()
+{
+ _generator = NULL;
+}
+FX_ERR CFX_Path::Create()
+{
+ if (_generator) {
+ return FX_ERR_Property_Invalid;
+ }
+ _generator = FX_NEW CFX_PathGenerator;
+ _generator->Create();
+ return FX_ERR_Succeeded;
+}
+CFX_Path::~CFX_Path()
+{
+ if (_generator) {
+ delete _generator;
+ _generator = NULL;
+ }
+}
+FX_ERR CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->MoveTo(x, y);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->LineTo(x, y);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::BezierTo(FX_FLOAT ctrlX1,
+ FX_FLOAT ctrlY1,
+ FX_FLOAT ctrlX2,
+ FX_FLOAT ctrlY2,
+ FX_FLOAT toX,
+ FX_FLOAT toY)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::ArcTo(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->ArcTo(left + width / 2,
+ top + height / 2,
+ width / 2,
+ height / 2,
+ startAngle,
+ sweepAngle);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::Close()
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->Close();
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddLine(FX_FLOAT x1,
+ FX_FLOAT y1,
+ FX_FLOAT x2,
+ FX_FLOAT y2)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddLine(x1, y1, x2, y2);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddBezier(FX_FLOAT startX,
+ FX_FLOAT startY,
+ FX_FLOAT ctrlX1,
+ FX_FLOAT ctrlY1,
+ FX_FLOAT ctrlX2,
+ FX_FLOAT ctrlY2,
+ FX_FLOAT endX,
+ FX_FLOAT endY)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddRectangle(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddRectangle(left, top, left + width, top + height);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddEllipse(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddEllipse(left + width / 2, top + height / 2, width / 2, height / 2);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddEllipse(const CFX_RectF & rect)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddEllipse(rect.left + rect.Width() / 2,
+ rect.top + rect.Height() / 2,
+ rect.Width() / 2,
+ rect.Height() / 2);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddArc(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddArc(left + width / 2,
+ top + height / 2,
+ width / 2,
+ height / 2,
+ startAngle,
+ sweepAngle);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddPie(FX_FLOAT left,
+ FX_FLOAT top,
+ FX_FLOAT width,
+ FX_FLOAT height,
+ FX_FLOAT startAngle,
+ FX_FLOAT sweepAngle)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddPie(left + width / 2,
+ top + height / 2,
+ width / 2,
+ height / 2,
+ startAngle,
+ sweepAngle);
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::AddSubpath(CFX_Path * path)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->AddPathData(path->GetPathData());
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Path::Clear()
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ _generator->GetPathData()->SetPointCount(0);
+ return FX_ERR_Succeeded;
+}
+FX_BOOL CFX_Path::IsEmpty()
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, FX_ERR_Property_Invalid);
+ if (_generator->GetPathData()->GetPointCount() == 0) {
+ return TRUE;
+ }
+ return FALSE;
+}
+CFX_PathData * CFX_Path::GetPathData()
+{
+ _FX_RETURN_VALUE_IF_FAIL(_generator, NULL);
+ return _generator->GetPathData();
+}
+CFX_Color::CFX_Color()
+{
+ _type = FX_COLOR_None;
+}
+CFX_Color::CFX_Color(const FX_ARGB argb)
+{
+ _type = FX_COLOR_None;
+ Set(argb);
+}
+CFX_Color::CFX_Color(CFX_Pattern * pattern, const FX_ARGB argb )
+{
+ _type = FX_COLOR_None;
+ Set(pattern, argb);
+}
+CFX_Color::CFX_Color(CFX_Shading * shading)
+{
+ _type = FX_COLOR_None;
+ Set(shading);
+}
+CFX_Color::~CFX_Color()
+{
+ _type = FX_COLOR_None;
+}
+FX_ERR CFX_Color::Set(const FX_ARGB argb)
+{
+ _type = FX_COLOR_Solid;
+ _argb = argb;
+ _pattern = NULL;
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Color::Set(CFX_Pattern * pattern, const FX_ARGB argb )
+{
+ _FX_RETURN_VALUE_IF_FAIL(pattern, FX_ERR_Parameter_Invalid);
+ _type = FX_COLOR_Pattern;
+ _argb = argb;
+ _pattern = pattern;
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Color::Set(CFX_Shading * shading)
+{
+ _FX_RETURN_VALUE_IF_FAIL(shading, FX_ERR_Parameter_Invalid);
+ _type = FX_COLOR_Shading;
+ _shading = shading;
+ return FX_ERR_Succeeded;
+}
+CFX_Pattern::CFX_Pattern()
+{
+ _type = FX_PATTERN_None;
+ _matrix.Reset();
+}
+FX_ERR CFX_Pattern::Create(CFX_DIBitmap * bitmap,
+ const FX_FLOAT xStep,
+ const FX_FLOAT yStep,
+ CFX_Matrix * matrix )
+{
+ _FX_RETURN_VALUE_IF_FAIL(bitmap, FX_ERR_Parameter_Invalid);
+ if (_type != FX_PATTERN_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_PATTERN_Bitmap;
+ _bitmap = bitmap;
+ _x1Step = xStep;
+ _y1Step = yStep;
+ if (matrix) {
+ _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
+ }
+ return FX_ERR_Succeeded;
+}
+FX_ERR CFX_Pattern::Create(FX_HatchStyle hatchStyle,
+ const FX_ARGB foreArgb,
+ const FX_ARGB backArgb,
+ CFX_Matrix * matrix )
+{
+ if (hatchStyle < FX_HATCHSTYLE_Horizontal
+ || hatchStyle > FX_HATCHSTYLE_SolidDiamond) {
+ return FX_ERR_Parameter_Invalid;
+ }
+ if (_type != FX_PATTERN_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_PATTERN_Hatch;
+ _hatchStyle = hatchStyle;
+ _foreArgb = foreArgb;
+ _backArgb = backArgb;
+ if (matrix) {
+ _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, matrix->f);
+ }
+ return FX_ERR_Succeeded;
+}
+CFX_Pattern::~CFX_Pattern()
+{
+ _type = FX_PATTERN_None;
+}
+CFX_Shading::CFX_Shading()
+{
+ _type = FX_SHADING_None;
+}
+FX_ERR CFX_Shading::CreateAxial(const CFX_PointF & beginPoint,
+ const CFX_PointF & endPoint,
+ FX_BOOL isExtendedBegin,
+ FX_BOOL isExtendedEnd,
+ const FX_ARGB beginArgb,
+ const FX_ARGB endArgb)
+{
+ if (_type != FX_SHADING_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_SHADING_Axial;
+ _beginPoint = beginPoint;
+ _endPoint = endPoint;
+ _isExtendedBegin = isExtendedBegin;
+ _isExtendedEnd = isExtendedEnd;
+ _beginArgb = beginArgb;
+ _endArgb = endArgb;
+ return InitArgbArray();
+}
+FX_ERR CFX_Shading::CreateRadial(const CFX_PointF & beginPoint,
+ const CFX_PointF & endPoint,
+ const FX_FLOAT beginRadius,
+ const FX_FLOAT endRadius,
+ FX_BOOL isExtendedBegin,
+ FX_BOOL isExtendedEnd,
+ const FX_ARGB beginArgb,
+ const FX_ARGB endArgb)
+{
+ if (_type != FX_SHADING_None) {
+ return FX_ERR_Property_Invalid;
+ }
+ _type = FX_SHADING_Radial;
+ _beginPoint = beginPoint;
+ _endPoint = endPoint;
+ _beginRadius = beginRadius;
+ _endRadius = endRadius;
+ _isExtendedBegin = isExtendedBegin;
+ _isExtendedEnd = isExtendedEnd;
+ _beginArgb = beginArgb;
+ _endArgb = endArgb;
+ return InitArgbArray();
+}
+CFX_Shading::~CFX_Shading()
+{
+ _type = FX_SHADING_None;
+}
+FX_ERR CFX_Shading::InitArgbArray()
+{
+ FX_INT32 a1, r1, g1, b1;
+ ArgbDecode(_beginArgb, a1, r1, g1, b1);
+ FX_INT32 a2, r2, g2, b2;
+ ArgbDecode(_endArgb, a2, r2, g2, b2);
+ FX_FLOAT f = (FX_FLOAT) (FX_SHADING_Steps - 1);
+ FX_FLOAT aScale = (FX_FLOAT) (1.0 * (a2 - a1) / f);
+ FX_FLOAT rScale = (FX_FLOAT) (1.0 * (r2 - r1) / f);
+ FX_FLOAT gScale = (FX_FLOAT) (1.0 * (g2 - g1) / f);
+ FX_FLOAT bScale = (FX_FLOAT) (1.0 * (b2 - b1) / f);
+ FX_INT32 a3, r3, g3, b3;
+ for (FX_INT32 i = 0; i < FX_SHADING_Steps; i++) {
+ a3 = (FX_INT32) (i * aScale);
+ r3 = (FX_INT32) (i * rScale);
+ g3 = (FX_INT32) (i * gScale);
+ b3 = (FX_INT32) (i * bScale);
+ _argbArray[i] = FXARGB_TODIB(FXARGB_MAKE((a1 + a3),
+ (r1 + r3),
+ (g1 + g3),
+ (b1 + b3)));
+ }
+ return FX_ERR_Succeeded;
+}
+class CFX_Pause : public IFX_Pause
+{
+public:
+ virtual FX_BOOL NeedToPauseNow()
+ {
+ return TRUE;
+ }
+};
diff --git a/xfa/src/fxgraphics/src/fx_metafile_interpreter.cpp b/xfa/src/fxgraphics/src/fx_metafile_interpreter.cpp
new file mode 100644
index 0000000000..388fbc5ad5
--- /dev/null
+++ b/xfa/src/fxgraphics/src/fx_metafile_interpreter.cpp
@@ -0,0 +1,281 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "pre.h"
+#include "../include/fx_graphics.h"
+#include "fx_metafile_interpreter.h"
+CFX_MetafileInterpreter::CFX_MetafileInterpreter()
+{
+ _element = NULL;
+}
+CFX_MetafileInterpreter::~CFX_MetafileInterpreter()
+{
+ _element = NULL;
+}
+FX_BOOL CFX_MetafileInterpreter::SetCurrentElement(CXML_Element * element)
+{
+ _FX_RETURN_VALUE_IF_FAIL(element, FALSE);
+ _element = element;
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetLineCap(FX_INT32 & lineCap)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * lineCapElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(lineCapElement, FALSE);
+ lineCap = lineCapElement->GetAttrInteger("CFX_GraphStateData::LineCap");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetLineDash(FX_FLOAT & dashPhase,
+ FX_INT32 & dashArray,
+ FX_INT32 & dashCount)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * dashPhaseElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(dashPhaseElement, FALSE);
+ dashPhase = dashPhaseElement->GetAttrFloat("FX_FLOAT");
+ CXML_Element * dashArrayElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(dashArrayElement, FALSE);
+ dashArray = dashArrayElement->GetAttrInteger("FX_FLOAT *");
+ CXML_Element * dashCountElement = _element->GetElement(2);
+ _FX_RETURN_VALUE_IF_FAIL(dashCountElement, FALSE);
+ dashCount = dashCountElement->GetAttrInteger("FX_INT32");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetLineDash(FX_INT32 & dashStyle)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * dashStyleElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(dashStyleElement, FALSE);
+ dashStyle = dashStyleElement->GetAttrInteger("FX_DashStyle");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetLineJoin(FX_INT32 & lineJoin)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * lineJoinElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(lineJoinElement, FALSE);
+ lineJoin = lineJoinElement->GetAttrInteger("CFX_GraphStateData::LineJoin");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetMiterLimit(FX_FLOAT & miterLimit)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * miterLimitElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(miterLimitElement, FALSE);
+ miterLimit = miterLimitElement->GetAttrFloat("FX_FLOAT");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetLineWidth(FX_FLOAT & lineWidth,
+ FX_INT32 & isActOnDash)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * lineWidthElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(lineWidthElement, FALSE);
+ lineWidth = lineWidthElement->GetAttrFloat("FX_FLOAT");
+ CXML_Element * isActOnDashElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(isActOnDashElement, FALSE);
+ isActOnDash = isActOnDashElement->GetAttrInteger("FX_BOOL");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetStrokeColor(FX_INT32 & color)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * colorElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(colorElement, FALSE);
+ color = colorElement->GetAttrInteger("CFX_Color *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetFillColor(FX_INT32 & color)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * colorElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(colorElement, FALSE);
+ color = colorElement->GetAttrInteger("CFX_Color *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_StrokePath(FX_INT32 & path, FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * pathElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(pathElement, FALSE);
+ path = pathElement->GetAttrInteger("CFX_Path *");
+ CXML_Element * matrixElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_FillPath(FX_INT32 & path,
+ FX_INT32 & fillMode,
+ FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * pathElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(pathElement, FALSE);
+ path = pathElement->GetAttrInteger("CFX_Path *");
+ CXML_Element * fillModeElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(fillModeElement, FALSE);
+ fillMode = fillModeElement->GetAttrInteger("FX_FillMode");
+ CXML_Element * matrixElement = _element->GetElement(2);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_ClipPath(FX_INT32 & path,
+ FX_INT32 & fillMode,
+ FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * pathElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(pathElement, FALSE);
+ path = pathElement->GetAttrInteger("CFX_Path *");
+ CXML_Element * fillModeElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(fillModeElement, FALSE);
+ fillMode = fillModeElement->GetAttrInteger("FX_FillMode");
+ CXML_Element * matrixElement = _element->GetElement(2);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_DrawImage(FX_INT32 & source,
+ FX_INT32 & point,
+ FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * sourceElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(sourceElement, FALSE);
+ source = sourceElement->GetAttrInteger("CFX_DIBSource *");
+ CXML_Element * pointElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(pointElement, FALSE);
+ point = pointElement->GetAttrInteger("CFX_PointF *");
+ CXML_Element * matrixElement = _element->GetElement(2);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_StretchImage(FX_INT32 & source,
+ FX_INT32 & rect,
+ FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * sourceElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(sourceElement, FALSE);
+ source = sourceElement->GetAttrInteger("CFX_DIBSource *");
+ CXML_Element * rectElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(rectElement, FALSE);
+ rect = rectElement->GetAttrInteger("CFX_RectF *");
+ CXML_Element * matrixElement = _element->GetElement(2);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_ConcatMatrix(FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * matrixElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetClipRect(FX_INT32 & rect)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * rectElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(rectElement, FALSE);
+ rect = rectElement->GetAttrInteger("CFX_RectF *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetFont(FX_INT32 & font)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * fontElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(fontElement, FALSE);
+ font = fontElement->GetAttrInteger("CFX_Font *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetFontSize(FX_FLOAT & size)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * sizeElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(sizeElement, FALSE);
+ size = sizeElement->GetAttrFloat("FX_FLOAT");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetFontHScale(FX_FLOAT & scale)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * scaleElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(scaleElement, FALSE);
+ scale = scaleElement->GetAttrFloat("FX_FLOAT");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetCharSpacing(FX_FLOAT & spacing)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * spacingElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(spacingElement, FALSE);
+ spacing = spacingElement->GetAttrFloat("FX_FLOAT");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetTextDrawingMode(FX_INT32 & mode)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * modeElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(modeElement, FALSE);
+ mode = modeElement->GetAttrInteger("FX_INT32");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_SetText(FX_INT32 & point,
+ FX_INT32 & text,
+ FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * pointElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(pointElement, FALSE);
+ point = pointElement->GetAttrInteger("CFX_PointF *");
+ CXML_Element * textElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(textElement, FALSE);
+ text = textElement->GetAttrInteger("CFX_WideString *");
+ CXML_Element * matrixElement = _element->GetElement(2);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_Transfer(FX_INT32 & graphics, FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * graphicsElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(graphicsElement, FALSE);
+ graphics = graphicsElement->GetAttrInteger("CFX_Graphics *");
+ CXML_Element * matrixElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
+FX_BOOL CFX_MetafileInterpreter::ParamOf_Transfer(FX_INT32 & graphics,
+ FX_FLOAT & srcLeft,
+ FX_FLOAT & srcTop,
+ FX_INT32 & dstRect,
+ FX_INT32 & matrix)
+{
+ _FX_RETURN_VALUE_IF_FAIL(_element, FALSE);
+ CXML_Element * graphicsElement = _element->GetElement(0);
+ _FX_RETURN_VALUE_IF_FAIL(graphicsElement, FALSE);
+ graphics = graphicsElement->GetAttrInteger("CFX_Graphics *");
+ CXML_Element * srcLeftElement = _element->GetElement(2);
+ _FX_RETURN_VALUE_IF_FAIL(srcLeftElement, FALSE);
+ srcLeft = srcLeftElement->GetAttrFloat("FX_FLOAT");
+ CXML_Element * srcTopElement = _element->GetElement(3);
+ _FX_RETURN_VALUE_IF_FAIL(srcTopElement, FALSE);
+ srcTop = srcTopElement->GetAttrFloat("FX_FLOAT");
+ CXML_Element * dstRectElement = _element->GetElement(1);
+ _FX_RETURN_VALUE_IF_FAIL(dstRectElement, FALSE);
+ dstRect = dstRectElement->GetAttrInteger("CFX_RectF *");
+ CXML_Element * matrixElement = _element->GetElement(4);
+ _FX_RETURN_VALUE_IF_FAIL(matrixElement, FALSE);
+ matrix = matrixElement->GetAttrInteger("CFX_Matrix *");
+ return TRUE;
+}
diff --git a/xfa/src/fxgraphics/src/fx_metafile_interpreter.h b/xfa/src/fxgraphics/src/fx_metafile_interpreter.h
new file mode 100644
index 0000000000..6d827b6f30
--- /dev/null
+++ b/xfa/src/fxgraphics/src/fx_metafile_interpreter.h
@@ -0,0 +1,54 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef __H_FX_METAFILE_INTERPRETER__
+#define __H_FX_METAFILE_INTERPRETER__
+class CFX_MetafileInterpreter : public CFX_Object
+{
+public:
+ CFX_MetafileInterpreter();
+ virtual ~CFX_MetafileInterpreter();
+
+ FX_BOOL SetCurrentElement(CXML_Element * element);
+
+ FX_BOOL ParamOf_SetLineCap(FX_INT32 & lineCap);
+ FX_BOOL ParamOf_SetLineDash(FX_FLOAT & dashPhase,
+ FX_INT32 & dashArray,
+ FX_INT32 & dashCount);
+ FX_BOOL ParamOf_SetLineDash(FX_INT32 & dashStyle);
+ FX_BOOL ParamOf_SetLineJoin(FX_INT32 & lineJoin);
+ FX_BOOL ParamOf_SetMiterLimit(FX_FLOAT & miterLimit);
+ FX_BOOL ParamOf_SetLineWidth(FX_FLOAT & lineWidth, FX_INT32 & isActOnDash);
+
+ FX_BOOL ParamOf_SetStrokeColor(FX_INT32 & color);
+ FX_BOOL ParamOf_SetFillColor(FX_INT32 & color);
+
+ FX_BOOL ParamOf_StrokePath(FX_INT32 & path, FX_INT32 & matrix);
+ FX_BOOL ParamOf_FillPath(FX_INT32 & path, FX_INT32 & fillMode, FX_INT32 & matrix);
+ FX_BOOL ParamOf_ClipPath(FX_INT32 & path, FX_INT32 & fillMode, FX_INT32 & matrix);
+
+ FX_BOOL ParamOf_DrawImage(FX_INT32 & source, FX_INT32 & point, FX_INT32 & matrix);
+ FX_BOOL ParamOf_StretchImage(FX_INT32 & source, FX_INT32 & rect, FX_INT32 & matrix);
+
+ FX_BOOL ParamOf_ConcatMatrix(FX_INT32 & matrix);
+ FX_BOOL ParamOf_SetClipRect(FX_INT32 & rect);
+ FX_BOOL ParamOf_SetFont(FX_INT32 & font);
+ FX_BOOL ParamOf_SetFontSize(FX_FLOAT & size);
+ FX_BOOL ParamOf_SetFontHScale(FX_FLOAT & scale);
+ FX_BOOL ParamOf_SetCharSpacing(FX_FLOAT & spacing);
+ FX_BOOL ParamOf_SetTextDrawingMode(FX_INT32 & mode);
+ FX_BOOL ParamOf_SetText(FX_INT32 & point, FX_INT32 & text, FX_INT32 & matrix);
+ FX_BOOL ParamOf_Transfer(FX_INT32 & graphics, FX_INT32 & matrix);
+ FX_BOOL ParamOf_Transfer(FX_INT32 & graphics,
+ FX_FLOAT & srcLeft,
+ FX_FLOAT & srcTop,
+ FX_INT32 & dstRect,
+ FX_INT32 & matrix);
+
+private:
+ CXML_Element * _element;
+};
+#endif
diff --git a/xfa/src/fxgraphics/src/fx_path_generator.cpp b/xfa/src/fxgraphics/src/fx_path_generator.cpp
new file mode 100644
index 0000000000..da9d3df063
--- /dev/null
+++ b/xfa/src/fxgraphics/src/fx_path_generator.cpp
@@ -0,0 +1,222 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "pre.h"
+#include "fx_path_generator.h"
+CFX_PathGenerator::CFX_PathGenerator()
+{
+ m_pPathData = NULL;
+}
+void CFX_PathGenerator::Create()
+{
+ m_pPathData = FX_NEW CFX_PathData;
+}
+CFX_PathGenerator::~CFX_PathGenerator()
+{
+ if ( m_pPathData) {
+ delete m_pPathData;
+ m_pPathData = NULL;
+ }
+}
+void CFX_PathGenerator::AddPathData(CFX_PathData *pPathData)
+{
+ if (pPathData && pPathData->GetPointCount() > 0) {
+ int nCount = pPathData->GetPointCount();
+ FX_PATHPOINT *pPoints = pPathData->GetPoints();
+ AddPathData(pPoints, nCount);
+ }
+}
+void CFX_PathGenerator::AddPathData(FX_PATHPOINT *pPoints, int nCount)
+{
+ if (pPoints && nCount > 0) {
+ int nOldCount = m_pPathData->GetPointCount();
+ m_pPathData->AddPointCount(nCount);
+ FX_PATHPOINT *pDstPoints = m_pPathData->GetPoints();
+ FXSYS_memcpy(pDstPoints + nOldCount, pPoints, sizeof(FX_PATHPOINT) * nCount);
+ }
+}
+void CFX_PathGenerator::MoveTo(FX_FLOAT x, FX_FLOAT y)
+{
+ m_pPathData->AddPointCount(1);
+ m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, FXPT_MOVETO);
+}
+void CFX_PathGenerator::LineTo(FX_FLOAT x, FX_FLOAT y)
+{
+ m_pPathData->AddPointCount(1);
+ m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, FXPT_LINETO);
+}
+void CFX_PathGenerator::BezierTo(FX_FLOAT ctrl_x1, FX_FLOAT ctrl_y1,
+ FX_FLOAT ctrl_x2, FX_FLOAT ctrl_y2, FX_FLOAT to_x, FX_FLOAT to_y)
+{
+ int old_count = m_pPathData->GetPointCount();
+ m_pPathData->AddPointCount(3);
+ m_pPathData->SetPoint(old_count, ctrl_x1, ctrl_y1, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 1, ctrl_x2, ctrl_y2, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 2, to_x, to_y, FXPT_BEZIERTO);
+}
+void CFX_PathGenerator::Close()
+{
+ if (m_pPathData->GetPointCount() > 0) {
+ int index = m_pPathData->GetPointCount() - 1;
+ FX_PATHPOINT *pPoints = m_pPathData->GetPoints();
+ pPoints[index].m_Flag |= FXPT_CLOSEFIGURE;
+ }
+}
+void CFX_PathGenerator::AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
+{
+ int old_count = m_pPathData->GetPointCount();
+ m_pPathData->AddPointCount(2);
+ m_pPathData->SetPoint(old_count, x1, y1, FXPT_MOVETO);
+ m_pPathData->SetPoint(old_count + 1, x2, y2, FXPT_LINETO);
+}
+void CFX_PathGenerator::AddBezier(FX_FLOAT start_x, FX_FLOAT start_y,
+ FX_FLOAT ctrl_x1, FX_FLOAT ctrl_y1, FX_FLOAT ctrl_x2, FX_FLOAT ctrl_y2,
+ FX_FLOAT end_x, FX_FLOAT end_y)
+{
+ int old_count = m_pPathData->GetPointCount();
+ m_pPathData->AddPointCount(4);
+ m_pPathData->SetPoint(old_count, start_x, start_y, FXPT_MOVETO);
+ m_pPathData->SetPoint(old_count + 1, ctrl_x1, ctrl_y1, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 2, ctrl_x2, ctrl_y2, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 3, end_x, end_y, FXPT_BEZIERTO);
+}
+void CFX_PathGenerator::AddRectangle(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
+{
+ m_pPathData->AppendRect(x1, y1, x2, y2);
+}
+void CFX_PathGenerator::AddEllipse(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height)
+{
+#if 0
+ FX_FIXFLOAT16 k;
+ k = fix16_to_8(fixsqrt_32_to_16(fixmul_8_8_to_32(width, width) + fixmul_8_8_to_32(height, height)) / 2);
+ int old_count = m_pPathData->GetPointCount();
+ m_pPathData->AddPointCount(7);
+ m_pPathData->SetPoint(old_count, x, y - height / 2, FXPT_MOVETO);
+ m_pPathData->SetPoint(old_count + 1, x + k, y - height / 2, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 2, x + k, y + height / 2, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 3, x, y + height / 2, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 4, x - k, y + height / 2, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 5, x - k, y - height / 2, FXPT_BEZIERTO);
+ m_pPathData->SetPoint(old_count + 6, x, y - height / 2, FXPT_BEZIERTO);
+#else
+ AddArc(x, y, width, height, 0, FX_PI * 2);
+#endif
+}
+void CFX_PathGenerator::ArcTo(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height,
+ FX_FLOAT start_angle, FX_FLOAT sweep_angle)
+{
+ FX_FLOAT x0 = FXSYS_cos(sweep_angle / 2);
+ FX_FLOAT y0 = FXSYS_sin(sweep_angle / 2);
+ FX_FLOAT tx = FXSYS_Div((1.0f - x0) * 4, 3 * 1.0f);
+ FX_FLOAT ty = y0 - FXSYS_Div(FXSYS_Mul(tx, x0), y0);
+ FX_FLOAT px[3], py[3];
+ px[0] = x0 + tx;
+ py[0] = -ty;
+ px[1] = x0 + tx;
+ py[1] = ty;
+ FX_FLOAT sn = FXSYS_sin(start_angle + sweep_angle / 2);
+ FX_FLOAT cs = FXSYS_cos(start_angle + sweep_angle / 2);
+ int old_count = m_pPathData->GetPointCount();
+ m_pPathData->AddPointCount(3);
+ FX_FLOAT bezier_x, bezier_y;
+ bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[0], cs) - FXSYS_Mul(py[0], sn));
+ bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[0], sn) + FXSYS_Mul(py[0], cs));
+ m_pPathData->SetPoint(old_count, bezier_x, bezier_y, FXPT_BEZIERTO);
+ bezier_x = x + FXSYS_Mul(width, FXSYS_Mul(px[1], cs) - FXSYS_Mul(py[1], sn));
+ bezier_y = y + FXSYS_Mul(height, FXSYS_Mul(px[1], sn) + FXSYS_Mul(py[1], cs));
+ m_pPathData->SetPoint(old_count + 1, bezier_x, bezier_y, FXPT_BEZIERTO);
+ bezier_x = x + FXSYS_Mul(width, FXSYS_cos(start_angle + sweep_angle)),
+ bezier_y = y + FXSYS_Mul(height, FXSYS_sin(start_angle + sweep_angle));
+ m_pPathData->SetPoint(old_count + 2, bezier_x, bezier_y, FXPT_BEZIERTO);
+}
+void CFX_PathGenerator::AddArc(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height,
+ FX_FLOAT start_angle, FX_FLOAT sweep_angle)
+{
+#if 0
+ FX_FIXFLOAT32 sweep = sweep_angle;
+ while (sweep > FIXFLOAT32_PI * 2) {
+ sweep -= FIXFLOAT32_PI * 2;
+ }
+ if (sweep == 0) {
+ return;
+ }
+ m_pPathData->AddPointCount(1);
+ m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1,
+ x + fixmul_8_32_to_8(width, fixcos(start_angle)),
+ y + fixmul_8_32_to_8(height, fixsin(start_angle)), FXPT_MOVETO);
+ FX_FIXFLOAT32 angle1 = 0, angle2;
+ FX_BOOL bDone = FALSE;
+ do {
+ angle2 = angle1 + FIXFLOAT32_PI / 2;
+ if (angle2 >= sweep) {
+ angle2 = sweep;
+ bDone = TRUE;
+ }
+ ArcTo(x, y, width, height, start_angle + angle1, angle2 - angle1);
+ angle1 = angle2;
+ } while (!bDone);
+#else
+ if (sweep_angle == 0) {
+ return;
+ }
+ static const FX_FLOAT bezier_arc_angle_epsilon = (FX_FLOAT)(0.01f);
+ while (start_angle > FX_PI * 2) {
+ start_angle -= FX_PI * 2;
+ }
+ while (start_angle < 0) {
+ start_angle += FX_PI * 2;
+ }
+ if(sweep_angle >= FX_PI * 2) {
+ sweep_angle = FX_PI * 2;
+ }
+ if(sweep_angle <= -FX_PI * 2) {
+ sweep_angle = -FX_PI * 2;
+ }
+ m_pPathData->AddPointCount(1);
+ m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1,
+ x + FXSYS_Mul(width, FXSYS_cos(start_angle)),
+ y + FXSYS_Mul(height, FXSYS_sin(start_angle)), FXPT_MOVETO);
+ FX_FLOAT total_sweep = 0, local_sweep = 0, prev_sweep = 0;
+ FX_BOOL done = FALSE;
+ do {
+ if (sweep_angle < 0) {
+ prev_sweep = total_sweep;
+ local_sweep = -FX_PI / 2;
+ total_sweep -= FX_PI / 2;
+ if (total_sweep <= sweep_angle + bezier_arc_angle_epsilon) {
+ local_sweep = sweep_angle - prev_sweep;
+ done = TRUE;
+ }
+ } else {
+ prev_sweep = total_sweep;
+ local_sweep = FX_PI / 2;
+ total_sweep += FX_PI / 2;
+ if (total_sweep >= sweep_angle - bezier_arc_angle_epsilon) {
+ local_sweep = sweep_angle - prev_sweep;
+ done = TRUE;
+ }
+ }
+ ArcTo(x, y, width, height, start_angle, local_sweep);
+ start_angle += local_sweep;
+ } while (!done);
+#endif
+}
+void CFX_PathGenerator::AddPie(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height,
+ FX_FLOAT start_angle, FX_FLOAT sweep_angle)
+{
+ if (sweep_angle == 0) {
+ int old_count = m_pPathData->GetPointCount();
+ m_pPathData->AddPointCount(2);
+ m_pPathData->SetPoint(old_count, x, y, FXPT_MOVETO);
+ m_pPathData->SetPoint(old_count + 1,
+ x + FXSYS_Mul(width, FXSYS_cos(start_angle)),
+ y + FXSYS_Mul(height, FXSYS_sin(start_angle)), FXPT_LINETO);
+ return;
+ }
+ AddArc(x, y, width, height, start_angle, sweep_angle);
+ m_pPathData->AddPointCount(1);
+ m_pPathData->SetPoint(m_pPathData->GetPointCount() - 1, x, y, FXPT_LINETO | FXPT_CLOSEFIGURE);
+}
diff --git a/xfa/src/fxgraphics/src/fx_path_generator.h b/xfa/src/fxgraphics/src/fx_path_generator.h
new file mode 100644
index 0000000000..c1447f6c3a
--- /dev/null
+++ b/xfa/src/fxgraphics/src/fx_path_generator.h
@@ -0,0 +1,42 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef __H_FX_PATH_GENERATOR__
+#define __H_FX_PATH_GENERATOR__
+class CFX_PathGenerator : public CFX_Object
+{
+public:
+ CFX_PathGenerator();
+ void Create();
+ ~CFX_PathGenerator();
+ CFX_PathData *GetPathData() const
+ {
+ return m_pPathData;
+ }
+ void AddPathData(CFX_PathData *path_data);
+ void AddPathData(FX_PATHPOINT *points, int count);
+ void MoveTo(FX_FLOAT x, FX_FLOAT y);
+ void LineTo(FX_FLOAT x, FX_FLOAT y);
+ void BezierTo(FX_FLOAT ctrl_x1, FX_FLOAT ctrl_y1,
+ FX_FLOAT ctrl_x2, FX_FLOAT ctrl_y2, FX_FLOAT to_x, FX_FLOAT to_y);
+ void Close();
+ void ArcTo(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height,
+ FX_FLOAT start_angle, FX_FLOAT sweep_angle);
+
+ void AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
+ void AddBezier(FX_FLOAT start_x, FX_FLOAT start_y,
+ FX_FLOAT ctrl_x1, FX_FLOAT ctrl_y1, FX_FLOAT ctrl_x2, FX_FLOAT ctrl_y2,
+ FX_FLOAT end_x, FX_FLOAT end_y);
+ void AddRectangle(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
+ void AddEllipse(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height);
+ void AddArc(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height,
+ FX_FLOAT start_angle, FX_FLOAT sweep_angle);
+ void AddPie(FX_FLOAT x, FX_FLOAT y, FX_FLOAT width, FX_FLOAT height,
+ FX_FLOAT start_angle, FX_FLOAT sweep_angle);
+protected:
+ CFX_PathData *m_pPathData;
+};
+#endif
diff --git a/xfa/src/fxgraphics/src/pre.h b/xfa/src/fxgraphics/src/pre.h
new file mode 100644
index 0000000000..dc82b35a74
--- /dev/null
+++ b/xfa/src/fxgraphics/src/pre.h
@@ -0,0 +1,115 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../foxitlib.h"
+#ifndef FXSYS_Mul
+#define FXSYS_Mul(a, b) ((a) * (b))
+#define FXSYS_Div(a, b) ((a) / (b))
+#define FXSYS_MulDiv(a, b, c) ((a) * (b) / (c))
+#define FXSYS_sqrt2(a, b) (FX_FLOAT)FXSYS_sqrt((a)*(a) + (b)*(b))
+#endif
+enum {
+ FX_CONTEXT_None = 0,
+ FX_CONTEXT_Device,
+};
+enum {
+ FX_COLOR_None = 0,
+ FX_COLOR_Solid,
+ FX_COLOR_Pattern,
+ FX_COLOR_Shading
+};
+enum {
+ FX_PATTERN_None = 0,
+ FX_PATTERN_Bitmap,
+ FX_PATTERN_Hatch
+};
+enum {
+ FX_SHADING_None = 0,
+ FX_SHADING_Axial,
+ FX_SHADING_Radial
+};
+#define FX_HATCHSTYLE_Total 53
+struct FX_HATCHDATA {
+ FX_INT32 width;
+ FX_INT32 height;
+ FX_BYTE maskBits[64];
+};
+typedef FX_HATCHDATA const * FX_LPCHATCHDATA;
+static const FX_HATCHDATA hatchBitmapData[FX_HATCHSTYLE_Total] = {
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,}},
+ {16, 16, {0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,}},
+ {16, 16, {0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00,}},
+ {16, 16, {0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,}},
+ {16, 16, {0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00, 0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00,}},
+ {16, 16, {0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00,}},
+ {16, 16, {0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00,}},
+ {16, 16, {0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+};
+#if defined (__WIN32__) || defined (_WIN32)
+#define FX_START_TIMER SYSTEMTIME start, stop; \
+ ::GetLocalTime(&start);
+#define FX_STOP_TIMER ::GetLocalTime(&stop); \
+ WORD wSecond = stop.wSecond - start.wSecond; \
+ WORD wMilliseconds = stop.wMilliseconds - start.wMilliseconds; \
+ char buf[256]; \
+ sprintf(buf, "duration is %d millisecond\n", wSecond * 1000 + wMilliseconds); \
+ ::OutputDebugString(buf);
+#elif defined (__linux) || defined (linux)
+#define FX_START_TIMER
+#define FX_STOP_TIMER
+#elif defined (__APPLE__) || defined (__MACOSX__)
+#define FX_START_TIMER NSTimeInterval start, stop; \
+ start = [NSDate timeIntervalSinceReferenceDate];
+#define FX_STOP_TIMER stop = [NSDate timeIntervalSinceReferenceDate]; \
+ NSTimeInterval duration = stop - start; \
+ printf("duration is %f millisecond\n", duration * 1000);
+#else
+#endif
diff --git a/xfa/src/fxjse/src/class.cpp b/xfa/src/fxjse/src/class.cpp
new file mode 100644
index 0000000000..326e8d47c2
--- /dev/null
+++ b/xfa/src/fxjse/src/class.cpp
@@ -0,0 +1,268 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../foxitlib.h"
+#include "fxv8.h"
+#include "context.h"
+#include "class.h"
+#include "value.h"
+#include "scope_inline.h"
+#include "util_inline.h"
+static void FXJSE_V8ConstructorCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value>& info);
+static void FXJSE_V8FunctionCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value>& info);
+static void FXJSE_V8GetterCallback_Wrapper(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info);
+static void FXJSE_V8SetterCallback_Wrapper(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info);
+void FXJSE_DefineFunctions(FXJSE_HCONTEXT hContext, const FXJSE_FUNCTION* lpFunctions, int nNum)
+{
+ CFXJSE_Context* lpContext = reinterpret_cast<CFXJSE_Context*>(hContext);
+ ASSERT(lpContext);
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(lpContext);
+ v8::Isolate *pIsolate = lpContext->GetRuntime();
+ v8::Handle<v8::Object> hGlobalObject = FXJSE_GetGlobalObjectFromContext(scope.GetLocalContext());
+ for(FX_INT32 i = 0; i < nNum; i++) {
+ hGlobalObject->ForceSet(v8::String::NewFromUtf8(pIsolate, lpFunctions[i].name),
+ v8::Function::New(pIsolate, FXJSE_V8FunctionCallback_Wrapper, v8::External::New(pIsolate, const_cast<FXJSE_FUNCTION*>(lpFunctions + i))),
+ static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+ }
+}
+FXJSE_HCLASS FXJSE_DefineClass(FXJSE_HCONTEXT hContext, const FXJSE_CLASS* lpClass)
+{
+ CFXJSE_Context* lpContext = reinterpret_cast<CFXJSE_Context*>(hContext);
+ ASSERT(lpContext);
+ return reinterpret_cast<FXJSE_HCLASS>(CFXJSE_Class::Create(lpContext, lpClass, FALSE));
+}
+FXJSE_HCLASS FXJSE_GetClass(FXJSE_HCONTEXT hContext, FX_BSTR szName)
+{
+ return reinterpret_cast<FXJSE_HCLASS>(CFXJSE_Class::GetClassFromContext(reinterpret_cast<CFXJSE_Context*>(hContext), szName));
+}
+static void FXJSE_V8FunctionCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ const FXJSE_FUNCTION* lpFunctionInfo = static_cast<FXJSE_FUNCTION*>(info.Data().As<v8::External>()->Value());
+ if (!lpFunctionInfo) {
+ return;
+ }
+ CFX_ByteStringC szFunctionName(lpFunctionInfo->name);
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_ArgumentsImpl impl = {&info, lpRetValue};
+ lpFunctionInfo->callbackProc(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFunctionName, reinterpret_cast<CFXJSE_Arguments&>(impl));
+ if(!lpRetValue->DirectGetValue().IsEmpty()) {
+ info.GetReturnValue().Set(lpRetValue->DirectGetValue());
+ }
+ delete lpRetValue;
+ lpRetValue = NULL;
+ delete lpThisValue;
+ lpThisValue = NULL;
+}
+static void FXJSE_V8ClassGlobalConstructorCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ const FXJSE_CLASS* lpClassDefinition = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ if (!lpClassDefinition) {
+ return;
+ }
+ CFX_ByteStringC szFunctionName(lpClassDefinition->name);
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_ArgumentsImpl impl = {&info, lpRetValue};
+ lpClassDefinition->constructor(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFunctionName, reinterpret_cast<CFXJSE_Arguments&>(impl));
+ if(!lpRetValue->DirectGetValue().IsEmpty()) {
+ info.GetReturnValue().Set(lpRetValue->DirectGetValue());
+ }
+ delete lpRetValue;
+ lpRetValue = NULL;
+ delete lpThisValue;
+ lpThisValue = NULL;
+}
+static void FXJSE_V8GetterCallback_Wrapper(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
+{
+ const FXJSE_PROPERTY* lpPropertyInfo = static_cast<FXJSE_PROPERTY*>(info.Data().As<v8::External>()->Value());
+ if (!lpPropertyInfo) {
+ return;
+ }
+ CFX_ByteStringC szPropertyName(lpPropertyInfo->name);
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ lpPropertyInfo->getProc(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szPropertyName, reinterpret_cast<FXJSE_HVALUE>(lpPropValue));
+ info.GetReturnValue().Set(lpPropValue->DirectGetValue());
+ delete lpThisValue;
+ lpThisValue = NULL;
+ delete lpPropValue;
+ lpPropValue = NULL;
+}
+static void FXJSE_V8SetterCallback_Wrapper(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
+{
+ const FXJSE_PROPERTY* lpPropertyInfo = static_cast<FXJSE_PROPERTY*>(info.Data().As<v8::External>()->Value());
+ if (!lpPropertyInfo) {
+ return;
+ }
+ CFX_ByteStringC szPropertyName(lpPropertyInfo->name);
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ lpPropValue->ForceSetValue(value);
+ lpPropertyInfo->setProc(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szPropertyName, reinterpret_cast<FXJSE_HVALUE>(lpPropValue));
+ delete lpThisValue;
+ lpThisValue = NULL;
+ delete lpPropValue;
+ lpPropValue = NULL;
+}
+static void FXJSE_V8ConstructorCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ const FXJSE_CLASS* lpClassDefinition = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ if (!lpClassDefinition) {
+ return;
+ }
+ FXSYS_assert(info.This()->InternalFieldCount());
+ info.This()->SetAlignedPointerInInternalField(0, NULL);
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ if(lpClassDefinition->dynMethodCall || lpClassDefinition->dynPropGetter || lpClassDefinition->dynPropSetter || lpClassDefinition->dynPropTypeGetter) {
+ CFXJSE_Class::SetUpDynPropHandler(NULL, lpThisValue, lpClassDefinition);
+ }
+ delete lpThisValue;
+ lpThisValue = NULL;
+}
+FXJSE_HRUNTIME CFXJSE_Arguments::GetRuntime() const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ return reinterpret_cast<FXJSE_HRUNTIME>(lpArguments->m_pRetValue->GetIsolate());
+}
+FX_INT32 CFXJSE_Arguments::GetLength() const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ return lpArguments->m_pInfo->Length();
+}
+FXJSE_HVALUE CFXJSE_Arguments::GetValue(FX_INT32 index) const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ CFXJSE_Value* lpArgValue = CFXJSE_Value::Create(v8::Isolate::GetCurrent());
+ ASSERT(lpArgValue);
+ lpArgValue->ForceSetValue((*lpArguments->m_pInfo)[index]);
+ return reinterpret_cast<FXJSE_HVALUE>(lpArgValue);
+}
+FX_BOOL CFXJSE_Arguments::GetBoolean(FX_INT32 index) const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ return (*lpArguments->m_pInfo)[index]->BooleanValue() ? TRUE : FALSE;
+}
+FX_INT32 CFXJSE_Arguments::GetInt32(FX_INT32 index) const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ return static_cast<FX_INT32>((*lpArguments->m_pInfo)[index]->NumberValue());
+}
+FX_FLOAT CFXJSE_Arguments::GetFloat(FX_INT32 index) const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ return static_cast<FX_FLOAT>((*lpArguments->m_pInfo)[index]->NumberValue());
+}
+CFX_ByteString CFXJSE_Arguments::GetUTF8String(FX_INT32 index) const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ v8::Handle<v8::String> hString = (*lpArguments->m_pInfo)[index]->ToString();
+ v8::String::Utf8Value szStringVal(hString);
+ return CFX_ByteString(*szStringVal);
+}
+FX_LPVOID CFXJSE_Arguments::GetObject(FX_INT32 index, FXJSE_HCLASS hClass ) const
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ v8::Handle<v8::Value> hValue = (*lpArguments->m_pInfo)[index];
+ ASSERT(!hValue.IsEmpty());
+ if(!hValue->IsObject()) {
+ return NULL;
+ }
+ CFXJSE_Class* lpClass = reinterpret_cast<CFXJSE_Class*>(hClass);
+ return FXJSE_RetrieveObjectBinding(hValue.As<v8::Object>(), lpClass);
+}
+FXJSE_HVALUE CFXJSE_Arguments::GetReturnValue()
+{
+ const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast<const CFXJSE_ArgumentsImpl* const>(this);
+ return reinterpret_cast<FXJSE_HVALUE>(lpArguments->m_pRetValue);
+}
+static void FXJSE_Context_GlobalObjToString(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ const FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ if (!lpClass) {
+ return;
+ }
+ if(info.This() == info.Holder() && lpClass->name) {
+ CFX_ByteString szStringVal;
+ szStringVal.Format("[object %s]", lpClass->name);
+ info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), (FX_LPCSTR)szStringVal, v8::String::kNormalString, szStringVal.GetLength()));
+ } else {
+ info.GetReturnValue().Set(info.This()->ObjectProtoToString());
+ }
+}
+CFXJSE_Class* CFXJSE_Class::Create(CFXJSE_Context* lpContext, const FXJSE_CLASS* lpClassDefinition, FX_BOOL bIsJSGlobal )
+{
+ if(!lpContext || !lpClassDefinition) {
+ return NULL;
+ }
+ CFXJSE_Class* pClass = GetClassFromContext(lpContext, lpClassDefinition->name);
+ if(pClass) {
+ return pClass;
+ }
+ v8::Isolate* pIsolate = lpContext->m_pIsolate;
+ pClass = FX_NEW CFXJSE_Class(lpContext);
+ ASSERT(pClass);
+ pClass->m_szClassName = lpClassDefinition->name;
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::FunctionTemplate> hFunctionTemplate = v8::FunctionTemplate::New(pIsolate, bIsJSGlobal ? 0 : FXJSE_V8ConstructorCallback_Wrapper, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition)));
+ hFunctionTemplate->SetClassName(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name));
+ hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(1);
+ v8::Local<v8::ObjectTemplate> hObjectTemplate = hFunctionTemplate->InstanceTemplate();
+ if (lpClassDefinition->dynPropDeleter || lpClassDefinition->dynPropTypeGetter) {
+ SetUpNamedPropHandler(pIsolate, hObjectTemplate, lpClassDefinition);
+ }
+ if(lpClassDefinition->propNum) {
+ for(FX_INT32 i = 0; i < lpClassDefinition->propNum; i++) {
+ hObjectTemplate->SetNativeDataProperty(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->properties[i].name),
+ lpClassDefinition->properties[i].getProc ? FXJSE_V8GetterCallback_Wrapper : NULL,
+ lpClassDefinition->properties[i].setProc ? FXJSE_V8SetterCallback_Wrapper : NULL,
+ v8::External::New(pIsolate, const_cast<FXJSE_PROPERTY*>(lpClassDefinition->properties + i)),
+ static_cast<v8::PropertyAttribute>(v8::DontDelete));
+ }
+ }
+ if(lpClassDefinition->methNum) {
+ for(FX_INT32 i = 0; i < lpClassDefinition->methNum; i++) {
+ hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name),
+ v8::FunctionTemplate::New(pIsolate, FXJSE_V8FunctionCallback_Wrapper,
+ v8::External::New(pIsolate, const_cast<FXJSE_FUNCTION*>(lpClassDefinition->methods + i))),
+ static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+ }
+ }
+ if(lpClassDefinition->constructor) {
+ if(bIsJSGlobal) {
+ hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name),
+ v8::FunctionTemplate::New(pIsolate, FXJSE_V8ClassGlobalConstructorCallback_Wrapper,
+ v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))),
+ static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+ } else {
+ v8::Local<v8::Context> hLocalContext = v8::Local<v8::Context>::New(pIsolate, lpContext->m_hContext);
+ FXJSE_GetGlobalObjectFromContext(hLocalContext)->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name),
+ v8::Function::New(pIsolate, FXJSE_V8ClassGlobalConstructorCallback_Wrapper,
+ v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ }
+ }
+ if(bIsJSGlobal) {
+ hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, "toString"), v8::FunctionTemplate::New(pIsolate, FXJSE_Context_GlobalObjToString, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ }
+ pClass->m_hTemplate.Reset(lpContext->m_pIsolate, hFunctionTemplate);
+ lpContext->m_rgClasses.Add(pClass);
+ return pClass;
+}
+CFXJSE_Class* CFXJSE_Class::GetClassFromContext(CFXJSE_Context* pContext, FX_BSTR szName)
+{
+ for(int count = pContext->m_rgClasses.GetSize(), i = 0; i < count; i++) {
+ CFXJSE_Class* pClass = pContext->m_rgClasses[i];
+ if(pClass->m_szClassName == szName) {
+ return pClass;
+ }
+ }
+ return NULL;
+}
diff --git a/xfa/src/fxjse/src/class.h b/xfa/src/fxjse/src/class.h
new file mode 100644
index 0000000000..6a0f89fc72
--- /dev/null
+++ b/xfa/src/fxjse/src/class.h
@@ -0,0 +1,40 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJSE_CLASS_H_
+#define FXJSE_CLASS_H_
+class CFXJSE_Context;
+class CFXJSE_Value;
+class CFXJSE_Class : public CFX_Object
+{
+protected:
+ CFXJSE_Class(CFXJSE_Context* lpContext) : m_pContext(lpContext) {}
+public:
+ inline CFXJSE_Context* GetContext()
+ {
+ return m_pContext;
+ }
+ inline v8::Persistent<v8::FunctionTemplate>& GetTemplate()
+ {
+ return m_hTemplate;
+ }
+public:
+ static CFXJSE_Class* Create(CFXJSE_Context* pContext, const FXJSE_CLASS* lpClassDefintion, FX_BOOL bIsJSGlobal = FALSE);
+ static CFXJSE_Class* GetClassFromContext(CFXJSE_Context* pContext, FX_BSTR szName);
+ static void SetUpDynPropHandler(CFXJSE_Context* pContext, CFXJSE_Value* pValue, const FXJSE_CLASS* lpClassDefinition);
+ static void SetUpNamedPropHandler(v8::Isolate* pIsolate, v8::Local<v8::ObjectTemplate>& hObjectTemplate, const FXJSE_CLASS* lpClassDefinition);
+protected:
+ CFX_ByteString m_szClassName;
+ CFXJSE_Context* m_pContext;
+ v8::Persistent<v8::FunctionTemplate> m_hTemplate;
+ friend class CFXJSE_Context;
+ friend class CFXJSE_Value;
+};
+struct CFXJSE_ArgumentsImpl {
+ const v8::FunctionCallbackInfo<v8::Value>* m_pInfo;
+ CFXJSE_Value* m_pRetValue;
+};
+#endif
diff --git a/xfa/src/fxjse/src/context.cpp b/xfa/src/fxjse/src/context.cpp
new file mode 100644
index 0000000000..f2d979ee55
--- /dev/null
+++ b/xfa/src/fxjse/src/context.cpp
@@ -0,0 +1,224 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../foxitlib.h"
+#include "fxv8.h"
+#include "context.h"
+#include "class.h"
+#include "value.h"
+#include "scope_inline.h"
+#include "util_inline.h"
+FXJSE_HCONTEXT FXJSE_Context_Create(FXJSE_HRUNTIME hRuntime, const FXJSE_CLASS* lpGlobalClass , FX_LPVOID lpGlobalObject )
+{
+ CFXJSE_Context* pContext = CFXJSE_Context::Create(reinterpret_cast<v8::Isolate*>(hRuntime), lpGlobalClass, lpGlobalObject);
+ return reinterpret_cast<FXJSE_HCONTEXT>(pContext);
+}
+void FXJSE_Context_Release(FXJSE_HCONTEXT hContext)
+{
+ CFXJSE_Context* pContext = reinterpret_cast<CFXJSE_Context*>(hContext);
+ if(pContext) {
+ delete pContext;
+ }
+}
+FXJSE_HVALUE FXJSE_Context_GetGlobalObject(FXJSE_HCONTEXT hContext)
+{
+ CFXJSE_Context* pContext = reinterpret_cast<CFXJSE_Context*>(hContext);
+ if(!pContext) {
+ return NULL;
+ }
+ CFXJSE_Value* lpValue = CFXJSE_Value::Create(pContext->GetRuntime());
+ ASSERT(lpValue);
+ pContext->GetGlobalObject(lpValue);
+ return reinterpret_cast<FXJSE_HVALUE>(lpValue);
+}
+FXJSE_HRUNTIME FXJSE_Context_GetRuntime(FXJSE_HCONTEXT hContext)
+{
+ CFXJSE_Context* pContext = reinterpret_cast<CFXJSE_Context*>(hContext);
+ return pContext ? reinterpret_cast<FXJSE_HRUNTIME>(pContext->GetRuntime()) : NULL;
+}
+static FX_LPCSTR szCompatibleModeScripts[] = {
+ "(function (global, list) { 'use strict'; var objname; for (objname in list) { var globalobj = global[objname];\n\
+ if (globalobj) { list[objname].forEach( function (name) { if (!globalobj[name]) { Object.defineProperty(globalobj, name, {writable: true, enumerable: false, value: \n\
+ (function (obj) {\n\
+ if (arguments.length === 0) {\n\
+ throw new TypeError('missing argument 0 when calling function ' + objname + '.' + name);\n\
+ }\n\
+ return globalobj.prototype[name].apply(obj, Array.prototype.slice.call(arguments, 1));\n\
+})});}});}}}(this, {String: ['substr', 'toUpperCase']}));",
+};
+void FXJSE_Context_EnableCompatibleMode(FXJSE_HCONTEXT hContext, FX_DWORD dwCompatibleFlags)
+{
+ for (FX_UINT32 i = 0; i < (FX_UINT32)FXJSE_COMPATIBLEMODEFLAGCOUNT; i++) {
+ if (dwCompatibleFlags & (1 << i)) {
+ FXJSE_ExecuteScript(hContext, szCompatibleModeScripts[i], NULL, NULL);
+ }
+ }
+}
+FX_BOOL FXJSE_ExecuteScript(FXJSE_HCONTEXT hContext, FX_LPCSTR szScript, FXJSE_HVALUE hRetValue, FXJSE_HVALUE hNewThisObject )
+{
+ CFXJSE_Context* pContext = reinterpret_cast<CFXJSE_Context*>(hContext);
+ ASSERT(pContext);
+ return pContext->ExecuteScript(szScript, reinterpret_cast<CFXJSE_Value*>(hRetValue), reinterpret_cast<CFXJSE_Value*>(hNewThisObject));
+}
+v8::Handle<v8::Object> FXJSE_CreateReturnValue(v8::Isolate* pIsolate, v8::TryCatch& trycatch)
+{
+ v8::Handle<v8::Object> hReturnValue = v8::Object::New(pIsolate);
+ if (trycatch.HasCaught()) {
+ v8::Handle<v8::Value> hException = trycatch.Exception();
+ v8::Handle<v8::Message> hMessage = trycatch.Message();
+ if (hException->IsObject()) {
+ v8::Local<v8::Value> hValue;
+ hValue = hException.As<v8::Object>()->Get(v8::String::NewFromUtf8(pIsolate, "name"));
+ if(hValue->IsString() || hValue->IsStringObject()) {
+ hReturnValue->Set(0, hValue);
+ } else {
+ hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error"));
+ }
+ hValue = hException.As<v8::Object>()->Get(v8::String::NewFromUtf8(pIsolate, "message"));
+ if(hValue->IsString() || hValue->IsStringObject()) {
+ hReturnValue->Set(1, hValue);
+ } else {
+ hReturnValue->Set(1, hMessage->Get());
+ }
+ } else {
+ hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error"));
+ hReturnValue->Set(1, hMessage->Get());
+ }
+ hReturnValue->Set(2, hException);
+ hReturnValue->Set(3, v8::Integer::New(pIsolate, hMessage->GetLineNumber()));
+ hReturnValue->Set(4, hMessage->GetSourceLine());
+ hReturnValue->Set(5, v8::Integer::New(pIsolate, hMessage->GetStartColumn()));
+ hReturnValue->Set(6, v8::Integer::New(pIsolate, hMessage->GetEndColumn()));
+ }
+ return hReturnValue;
+}
+FX_BOOL FXJSE_ReturnValue_GetMessage(FXJSE_HVALUE hRetValue, CFX_ByteString& utf8Name, CFX_ByteString& utf8Message)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hRetValue);
+ if(!lpValue) {
+ return FALSE;
+ }
+ v8::Isolate* pIsolate = lpValue->GetIsolate();
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, lpValue->DirectGetValue());
+ if(!hValue->IsObject()) {
+ return FALSE;
+ }
+ v8::String::Utf8Value hStringVal0(hValue.As<v8::Object>()->Get(0)->ToString());
+ utf8Name = *hStringVal0;
+ v8::String::Utf8Value hStringVal1(hValue.As<v8::Object>()->Get(1)->ToString());
+ utf8Message = *hStringVal1;
+ return TRUE;
+}
+FX_BOOL FXJSE_ReturnValue_GetLineInfo(FXJSE_HVALUE hRetValue, FX_INT32& nLine, FX_INT32& nCol)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hRetValue);
+ if(!lpValue) {
+ return FALSE;
+ }
+ v8::Isolate* pIsolate = lpValue->GetIsolate();
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, lpValue->DirectGetValue());
+ if(!hValue->IsObject()) {
+ return FALSE;
+ }
+ nLine = hValue.As<v8::Object>()->Get(3)->ToInt32()->Value();
+ nCol = hValue.As<v8::Object>()->Get(5)->ToInt32()->Value();
+ return TRUE;
+}
+CFXJSE_Context* CFXJSE_Context::Create(v8::Isolate* pIsolate, const FXJSE_CLASS* lpGlobalClass , FX_LPVOID lpGlobalObject )
+{
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ CFXJSE_Context* pContext = FX_NEW CFXJSE_Context(pIsolate);
+ CFXJSE_Class* lpGlobalClassObj = NULL;
+ v8::Local<v8::ObjectTemplate> hObjectTemplate;
+ if(lpGlobalClass) {
+ lpGlobalClassObj = CFXJSE_Class::Create(pContext, lpGlobalClass, TRUE);
+ ASSERT(lpGlobalClassObj);
+ v8::Local<v8::FunctionTemplate> hFunctionTemplate = v8::Local<v8::FunctionTemplate>::New(pIsolate, lpGlobalClassObj->m_hTemplate);
+ hObjectTemplate = hFunctionTemplate->InstanceTemplate();
+ } else {
+ hObjectTemplate = v8::ObjectTemplate::New();
+ hObjectTemplate->SetInternalFieldCount(1);
+ }
+ v8::Local<v8::Context> hNewContext = v8::Context::New(pIsolate, NULL, hObjectTemplate);
+ v8::Local<v8::Context> hRootContext = v8::Local<v8::Context>::New(pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
+ hNewContext->SetSecurityToken(hRootContext->GetSecurityToken());
+ v8::Local<v8::Object> hGlobalObject = FXJSE_GetGlobalObjectFromContext(hNewContext);
+ FXJSE_UpdateObjectBinding(hGlobalObject, lpGlobalObject);
+ pContext->m_hContext.Reset(pIsolate, hNewContext);
+ if (lpGlobalClass) {
+ if(lpGlobalClass->dynMethodCall || lpGlobalClass->dynPropGetter || lpGlobalClass->dynPropSetter || lpGlobalClass->dynPropTypeGetter) {
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(pIsolate);
+ lpThisValue->ForceSetValue(hGlobalObject);
+ CFXJSE_Class::SetUpDynPropHandler(pContext, lpThisValue, lpGlobalClass);
+ delete lpThisValue;
+ lpThisValue = NULL;
+ }
+ }
+ return pContext;
+}
+CFXJSE_Context::~CFXJSE_Context()
+{
+ for(FX_INT32 i = 0, count = m_rgClasses.GetSize(); i < count; i++) {
+ CFXJSE_Class* pClass = m_rgClasses[i];
+ if(pClass) {
+ delete pClass;
+ }
+ }
+ m_rgClasses.RemoveAll();
+}
+void CFXJSE_Context::GetGlobalObject(CFXJSE_Value* pValue)
+{
+ ASSERT(pValue);
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
+ v8::Local<v8::Context> hContext = v8::Local<v8::Context>::New(m_pIsolate, m_hContext);
+ v8::Local<v8::Object> hGlobalObject = hContext->Global();
+ pValue->ForceSetValue(hGlobalObject);
+}
+FX_BOOL CFXJSE_Context::ExecuteScript(FX_LPCSTR szScript, CFXJSE_Value* lpRetValue, CFXJSE_Value* lpNewThisObject )
+{
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
+ v8::TryCatch trycatch;
+ v8::Local<v8::String> hScriptString = v8::String::NewFromUtf8(m_pIsolate, szScript);
+ if(lpNewThisObject == NULL) {
+ v8::Local<v8::Script> hScript = v8::Script::Compile(hScriptString);
+ if(!trycatch.HasCaught()) {
+ v8::Local<v8::Value> hValue = hScript->Run();
+ if(!trycatch.HasCaught()) {
+ if(lpRetValue) {
+ lpRetValue->m_hValue.Reset(m_pIsolate, hValue);
+ }
+ return TRUE;
+ }
+ }
+ if(lpRetValue) {
+ lpRetValue->m_hValue.Reset(m_pIsolate, FXJSE_CreateReturnValue(m_pIsolate, trycatch));
+ }
+ return FALSE;
+ } else {
+ v8::Local<v8::Value> hNewThis = v8::Local<v8::Value>::New(m_pIsolate, lpNewThisObject->m_hValue);
+ ASSERT(!hNewThis.IsEmpty());
+ v8::Local<v8::Script> hWrapper = v8::Script::Compile(v8::String::NewFromUtf8(m_pIsolate, "(function () { return eval(arguments[0]); })"));
+ v8::Local<v8::Value> hWrapperValue = hWrapper->Run();
+ ASSERT(hWrapperValue->IsFunction());
+ v8::Local<v8::Function> hWrapperFn = hWrapperValue.As<v8::Function>();
+ if(!trycatch.HasCaught()) {
+ v8::Handle<v8::Value> rgArgs[] = {hScriptString};
+ v8::Local<v8::Value> hValue = hWrapperFn->Call(hNewThis.As<v8::Object>(), 1, rgArgs);
+ if(!trycatch.HasCaught()) {
+ if(lpRetValue) {
+ lpRetValue->m_hValue.Reset(m_pIsolate, hValue);
+ }
+ return TRUE;
+ }
+ }
+ if(lpRetValue) {
+ lpRetValue->m_hValue.Reset(m_pIsolate, FXJSE_CreateReturnValue(m_pIsolate, trycatch));
+ }
+ return FALSE;
+ }
+}
diff --git a/xfa/src/fxjse/src/context.h b/xfa/src/fxjse/src/context.h
new file mode 100644
index 0000000000..6579cd973a
--- /dev/null
+++ b/xfa/src/fxjse/src/context.h
@@ -0,0 +1,37 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJSE_CONTEXT_H_
+#define FXJSE_CONTEXT_H_
+class CFXJSE_Class;
+class CFXJSE_Value;
+class CFXJSE_Context : public CFX_Object
+{
+protected:
+ CFXJSE_Context(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
+public:
+ static CFXJSE_Context* Create(v8::Isolate* pIsolate, const FXJSE_CLASS* lpGlobalClass = NULL, FX_LPVOID lpGlobalObject = NULL);
+ ~CFXJSE_Context();
+ V8_INLINE v8::Isolate* GetRuntime(void)
+ {
+ return m_pIsolate;
+ }
+ void GetGlobalObject(CFXJSE_Value* pValue);
+ FX_BOOL ExecuteScript(FX_LPCSTR szScript, CFXJSE_Value* lpRetValue, CFXJSE_Value* lpNewThisObject = NULL);
+protected:
+ CFXJSE_Context();
+ CFXJSE_Context(const CFXJSE_Context&);
+ CFXJSE_Context& operator = (const CFXJSE_Context&);
+protected:
+ v8::Persistent<v8::Context> m_hContext;
+ v8::Isolate* m_pIsolate;
+ CFX_ArrayTemplate<CFXJSE_Class*> m_rgClasses;
+ friend class CFXJSE_Class;
+ friend class CFXJSE_ScopeUtil_IsolateHandleContext;
+ friend class CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext;
+};
+v8::Handle<v8::Object> FXJSE_CreateReturnValue(v8::Isolate* pIsolate, v8::TryCatch& trycatch);
+#endif
diff --git a/xfa/src/fxjse/src/dynprop.cpp b/xfa/src/fxjse/src/dynprop.cpp
new file mode 100644
index 0000000000..fd03dcf6fd
--- /dev/null
+++ b/xfa/src/fxjse/src/dynprop.cpp
@@ -0,0 +1,284 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../foxitlib.h"
+#include "fxv8.h"
+#include "class.h"
+#include "value.h"
+static void FXJSE_DynPropGetterAdapter_MethodCallback (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
+ FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(hCallBackInfo->GetAlignedPointerFromInternalField(0));
+ v8::Local<v8::String> hPropName = hCallBackInfo->GetInternalField(1).As<v8::String>();
+ ASSERT(lpClass && !hPropName.IsEmpty());
+ v8::String::Utf8Value szPropName(hPropName);
+ CFX_ByteStringC szFxPropName = *szPropName;
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_ArgumentsImpl impl = {&info, lpRetValue};
+ lpClass->dynMethodCall(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName, reinterpret_cast<CFXJSE_Arguments&>(impl));
+ if(!lpRetValue->DirectGetValue().IsEmpty()) {
+ info.GetReturnValue().Set(lpRetValue->DirectGetValue());
+ }
+ delete lpRetValue;
+ lpRetValue = NULL;
+ delete lpThisValue;
+ lpThisValue = NULL;
+}
+static void FXJSE_DynPropGetterAdapter (const FXJSE_CLASS* lpClass, FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ ASSERT(lpClass);
+ FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? FXJSE_ClassPropType_Property : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
+ if(nPropType == FXJSE_ClassPropType_Property) {
+ if(lpClass->dynPropGetter) {
+ lpClass->dynPropGetter(hObject, szPropName, hValue);
+ }
+ } else if(nPropType == FXJSE_ClassPropType_Method) {
+ if(lpClass->dynMethodCall && hValue) {
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ v8::Isolate* pIsolate = lpValue->GetIsolate();
+ v8::HandleScope hscope(pIsolate);
+ v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate = v8::ObjectTemplate::New();
+ hCallBackInfoTemplate->SetInternalFieldCount(2);
+ v8::Local<v8::Object> hCallBackInfo = hCallBackInfoTemplate->NewInstance();
+ hCallBackInfo->SetAlignedPointerInInternalField(0, const_cast<FXJSE_CLASS*>(lpClass));
+ hCallBackInfo->SetInternalField(1, v8::String::NewFromUtf8(pIsolate, reinterpret_cast<const char*>(szPropName.GetPtr()), v8::String::kNormalString, szPropName.GetLength()));
+ lpValue->ForceSetValue(v8::Function::New(lpValue->GetIsolate(), FXJSE_DynPropGetterAdapter_MethodCallback, hCallBackInfo));
+ }
+ }
+}
+static void FXJSE_DynPropSetterAdapter (const FXJSE_CLASS* lpClass, FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue)
+{
+ ASSERT(lpClass);
+ FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? FXJSE_ClassPropType_Property : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
+ if(nPropType != FXJSE_ClassPropType_Method) {
+ if(lpClass->dynPropSetter) {
+ lpClass->dynPropSetter(hObject, szPropName, hValue);
+ }
+ }
+}
+static FX_BOOL FXJSE_DynPropQueryAdapter (const FXJSE_CLASS* lpClass, FXJSE_HOBJECT hObject, FX_BSTR szPropName)
+{
+ ASSERT(lpClass);
+ FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? FXJSE_ClassPropType_Property : lpClass->dynPropTypeGetter(hObject, szPropName, TRUE);
+ return nPropType != FXJSE_ClassPropType_None;
+}
+static FX_BOOL FXJSE_DynPropDeleterAdapter (const FXJSE_CLASS* lpClass, FXJSE_HOBJECT hObject, FX_BSTR szPropName)
+{
+ ASSERT(lpClass);
+ FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? FXJSE_ClassPropType_Property : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
+ if(nPropType != FXJSE_ClassPropType_Method) {
+ if(lpClass->dynPropDeleter) {
+ return lpClass->dynPropDeleter(hObject, szPropName);
+ } else {
+ return nPropType == FXJSE_ClassPropType_Property ? FALSE : TRUE;
+ }
+ }
+ return FALSE;
+}
+static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
+ FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(hCallBackInfo->GetAlignedPointerFromInternalField(0));
+ v8::Local<v8::String> hPropName = hCallBackInfo->GetInternalField(1).As<v8::String>();
+ ASSERT(lpClass && !hPropName.IsEmpty());
+ v8::String::Utf8Value szPropName(hPropName);
+ CFX_ByteStringC szFxPropName = *szPropName;
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ FXJSE_DynPropGetterAdapter(lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName, reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
+ info.GetReturnValue().Set(lpNewValue->DirectGetValue());
+ delete lpThisValue;
+ lpThisValue = NULL;
+ delete lpNewValue;
+ lpNewValue = NULL;
+}
+static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter(const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
+ FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(hCallBackInfo->GetAlignedPointerFromInternalField(0));
+ v8::Local<v8::String> hPropName = hCallBackInfo->GetInternalField(1).As<v8::String>();
+ ASSERT(lpClass && !hPropName.IsEmpty());
+ v8::String::Utf8Value szPropName(hPropName);
+ CFX_ByteStringC szFxPropName = *szPropName;
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ lpNewValue->ForceSetValue(info[0]);
+ FXJSE_DynPropSetterAdapter(lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName, reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
+ delete lpThisValue;
+ lpThisValue = NULL;
+ delete lpNewValue;
+ lpNewValue = NULL;
+}
+static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ const FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ if (!lpClass) {
+ return;
+ }
+ v8::Isolate* pIsolate = info.GetIsolate();
+ v8::HandleScope scope(pIsolate);
+ v8::Local<v8::String> hPropName = info[0]->ToString();
+ v8::String::Utf8Value szPropName(hPropName);
+ CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
+ v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate = v8::ObjectTemplate::New();
+ hCallBackInfoTemplate->SetInternalFieldCount(2);
+ v8::Local<v8::Object> hCallBackInfo = hCallBackInfoTemplate->NewInstance();
+ hCallBackInfo->SetAlignedPointerInInternalField(0, const_cast<FXJSE_CLASS*>(lpClass));
+ hCallBackInfo->SetInternalField(1, hPropName);
+ v8::Local<v8::Object> hPropDescriptor = v8::Object::New(pIsolate);
+ hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "get"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter, hCallBackInfo));
+ hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "set"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter, hCallBackInfo));
+ hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "enumerable"), v8::Boolean::New(pIsolate, false));
+ hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "configurable"), v8::Boolean::New(pIsolate, true));
+ info.GetReturnValue().Set(hPropDescriptor);
+}
+static void FXJSE_V8ProxyCallback_getPropertyDescriptor (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Isolate* pIsolate = info.GetIsolate();
+ v8::Local<v8::Object> hChainObj = info.This()->GetPrototype().As<v8::Object>();
+ v8::Local<v8::Script> fnSource = v8::Script::Compile(v8::String::NewFromUtf8(pIsolate,
+ "(function (o, name) { var fn, x, d; fn = Object.getOwnPropertyDescriptor; x = o; while(x && !(d = fn(x, name))){x = x.__proto__;} return d; })"));
+ v8::Local<v8::Function> fn = fnSource->Run().As<v8::Function>();
+ v8::Handle<v8::Value> rgArgs[] = {hChainObj, info[0]};
+ v8::Local<v8::Value> hChainDescriptor = fn->Call(info.This(), 2, rgArgs);
+ if(!hChainDescriptor.IsEmpty() && hChainDescriptor->IsObject()) {
+ info.GetReturnValue().Set(hChainDescriptor);
+ } else {
+ FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(info);
+ }
+}
+static void FXJSE_V8ProxyCallback_getOwnPropertyNames (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Isolate* pIsolate = info.GetIsolate();
+ v8::HandleScope scope(pIsolate);
+ info.GetReturnValue().Set(v8::Array::New(pIsolate));
+}
+static void FXJSE_V8ProxyCallback_getPropertyNames (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ v8::Local<v8::Object> hChainObj = info.This()->GetPrototype().As<v8::Object>();
+ v8::Local<v8::Value> hChainPropertyNames = hChainObj->GetPropertyNames();
+ info.GetReturnValue().Set(hChainPropertyNames);
+}
+static void FXJSE_V8ProxyCallback_defineProperty (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ const FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ if (!lpClass) {
+ return;
+ }
+ v8::Isolate* pIsolate = info.GetIsolate();
+ v8::HandleScope scope(pIsolate);
+ v8::Local<v8::String> hPropName = info[0]->ToString();
+ v8::Local<v8::Object> hPropDescriptor = info[1]->ToObject();
+ v8::String::Utf8Value szPropName(hPropName);
+ if(!hPropDescriptor->Has(v8::String::NewFromUtf8(pIsolate, "value"))) {
+ return;
+ }
+ v8::Local<v8::Value> hPropValue = hPropDescriptor->Get(v8::String::NewFromUtf8(pIsolate, "value"));
+ CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ lpPropValue->ForceSetValue(hPropValue);
+ FXJSE_DynPropSetterAdapter(lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName, reinterpret_cast<FXJSE_HVALUE>(lpPropValue));
+ delete lpThisValue;
+ lpThisValue = NULL;
+ delete lpPropValue;
+ lpPropValue = NULL;
+}
+static void FXJSE_V8ProxyCallback_delete (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ info.GetReturnValue().Set(true);
+ const FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ if (!lpClass) {
+ return;
+ }
+ v8::Isolate* pIsolate = info.GetIsolate();
+ v8::HandleScope scope(pIsolate);
+ v8::Local<v8::String> hPropName = info[0]->ToString();
+ v8::String::Utf8Value szPropName(hPropName);
+ CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(info.This());
+ info.GetReturnValue().Set(FXJSE_DynPropDeleterAdapter(lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName) ? true : false);
+ delete lpThisValue;
+ lpThisValue = NULL;
+}
+static void FXJSE_V8ProxyCallback_fix (const v8::FunctionCallbackInfo<v8::Value>& info)
+{
+ info.GetReturnValue().SetUndefined();
+}
+static void FXJSE_V8_NamedPropertyQueryCallback(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Integer>& info)
+{
+ v8::Local<v8::Object> thisObject = info.This();
+ if (thisObject->HasRealNamedProperty(property)) {
+ return;
+ }
+ const FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ v8::Isolate* pIsolate = info.GetIsolate();
+ v8::HandleScope scope(pIsolate);
+ v8::String::Utf8Value szPropName(property);
+ CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(thisObject);
+ if(FXJSE_DynPropQueryAdapter(lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName)) {
+ info.GetReturnValue().Set(v8::DontDelete);
+ } else {
+ const FX_INT32 iV8Absent = 64;
+ info.GetReturnValue().Set(iV8Absent);
+ }
+ delete lpThisValue;
+ lpThisValue = NULL;
+}
+static void FXJSE_V8_NamedPropertyDeleterCallback(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Boolean>& info)
+{
+ v8::Local<v8::Object> thisObject = info.This();
+ if (thisObject->HasRealNamedProperty(property)) {
+ return;
+ }
+ const FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
+ v8::Isolate* pIsolate = info.GetIsolate();
+ v8::HandleScope scope(pIsolate);
+ v8::String::Utf8Value szPropName(property);
+ CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
+ CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
+ lpThisValue->ForceSetValue(thisObject);
+ info.GetReturnValue().Set(FXJSE_DynPropDeleterAdapter(lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName) ? true : false);
+ delete lpThisValue;
+ lpThisValue = NULL;
+}
+void CFXJSE_Class::SetUpDynPropHandler(CFXJSE_Context* pContext, CFXJSE_Value* pValue, const FXJSE_CLASS* lpClassDefinition)
+{
+ v8::Isolate* pIsolate = pValue->GetIsolate();
+ CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext scope(pIsolate, pContext);
+ v8::Local<v8::Context> hContext = v8::Local<v8::Context>::New(pIsolate, pContext ? pContext->m_hContext : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
+ v8::Local<v8::Object> hObject = v8::Local<v8::Object>::New(pIsolate, pValue->m_hValue.As<v8::Object>());
+ v8::Local<v8::Object> hHarmonyProxyObj = hContext->Global()->Get(v8::String::NewFromUtf8(pIsolate, "Proxy")).As<v8::Object>();
+ v8::Local<v8::Function> hHarmonyProxyCreateFn = hHarmonyProxyObj->Get(v8::String::NewFromUtf8(pIsolate, "create")).As<v8::Function>();
+ v8::Local<v8::Value> hOldPrototype = hObject->GetPrototype();
+ v8::Local<v8::Object> hTrapper = v8::Object::New(pIsolate);
+ hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getOwnPropertyDescriptor"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getPropertyDescriptor"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyDescriptor, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getOwnPropertyNames"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyNames, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getPropertyNames"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyNames, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "delete"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_delete, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "defineProperty"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_defineProperty, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "fix"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_fix, v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition))));
+ v8::Handle<v8::Value> rgArgs[] = {hTrapper, hOldPrototype};
+ v8::Local<v8::Value> hNewPrototype = hHarmonyProxyCreateFn->Call(hHarmonyProxyObj, 2, rgArgs);
+ hObject->SetPrototype(hNewPrototype);
+}
+void CFXJSE_Class::SetUpNamedPropHandler(v8::Isolate* pIsolate, v8::Local<v8::ObjectTemplate>& hObjectTemplate, const FXJSE_CLASS* lpClassDefinition)
+{
+ hObjectTemplate->SetNamedPropertyHandler(0, 0,
+ lpClassDefinition->dynPropTypeGetter ? FXJSE_V8_NamedPropertyQueryCallback : 0,
+ lpClassDefinition->dynPropDeleter ? FXJSE_V8_NamedPropertyDeleterCallback : 0,
+ 0,
+ v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition)));
+}
diff --git a/xfa/src/fxjse/src/fxv8.h b/xfa/src/fxjse/src/fxv8.h
new file mode 100644
index 0000000000..4cc7b3f406
--- /dev/null
+++ b/xfa/src/fxjse/src/fxv8.h
@@ -0,0 +1,11 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FX_V8_H_
+#define _FX_V8_H_
+#include <v8.h>
+#include <libplatform/libplatform.h>
+#endif
diff --git a/xfa/src/fxjse/src/runtime.cpp b/xfa/src/fxjse/src/runtime.cpp
new file mode 100644
index 0000000000..e406f6a233
--- /dev/null
+++ b/xfa/src/fxjse/src/runtime.cpp
@@ -0,0 +1,118 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../foxitlib.h"
+#include "fxv8.h"
+#include "runtime.h"
+#include "scope_inline.h"
+static void FXJSE_KillV8()
+{
+ v8::V8::Dispose();
+}
+void FXJSE_Initialize()
+{
+ static FX_BOOL bV8Initialized = FALSE;
+ if (bV8Initialized) {
+ return;
+ }
+ bV8Initialized = TRUE;
+ atexit(FXJSE_KillV8);
+ FX_LPCSTR szCmdFlags =
+ "--harmony_proxies "
+ "--block_concurrent_recompilation "
+ ;
+ v8::V8::SetFlagsFromString(szCmdFlags, FXSYS_strlen(szCmdFlags));
+ v8::V8::InitializeICU();
+ v8::Platform* platform = v8::platform::CreateDefaultPlatform();
+ v8::V8::InitializePlatform(platform);
+ v8::V8::Initialize();
+ if(!CFXJSE_RuntimeData::g_RuntimeList) {
+ CFXJSE_RuntimeData::g_RuntimeList = FX_NEW CFXJSE_RuntimeList;
+ }
+}
+static void FXJSE_Runtime_DisposeCallback(v8::Isolate* pIsolate)
+{
+ {
+ v8::Locker locker(pIsolate);
+ CFXJSE_RuntimeData *pRuntimeData = reinterpret_cast<CFXJSE_RuntimeData*>(pIsolate->GetData(0));
+ if(pRuntimeData) {
+ pIsolate->SetData(0, NULL);
+ delete pRuntimeData;
+ }
+ }
+ pIsolate->Dispose();
+}
+void FXJSE_Finalize()
+{
+ if(CFXJSE_RuntimeData::g_RuntimeList) {
+ CFXJSE_RuntimeData::g_RuntimeList->RemoveAllRuntimes(FXJSE_Runtime_DisposeCallback);
+ delete CFXJSE_RuntimeData::g_RuntimeList;
+ CFXJSE_RuntimeData::g_RuntimeList = NULL;
+ }
+}
+FXJSE_HRUNTIME FXJSE_Runtime_Create()
+{
+ v8::Isolate* pIsolate = v8::Isolate::New();
+ ASSERT(pIsolate && CFXJSE_RuntimeData::g_RuntimeList);
+ CFXJSE_RuntimeData::g_RuntimeList->AppendRuntime(pIsolate);
+ return reinterpret_cast<FXJSE_HRUNTIME>(pIsolate);
+}
+void FXJSE_Runtime_Release(FXJSE_HRUNTIME hRuntime)
+{
+ v8::Isolate* pIsolate = reinterpret_cast<v8::Isolate*>(hRuntime);
+ if(pIsolate) {
+ ASSERT(CFXJSE_RuntimeData::g_RuntimeList);
+ CFXJSE_RuntimeData::g_RuntimeList->RemoveRuntime(pIsolate, FXJSE_Runtime_DisposeCallback);
+ }
+}
+CFXJSE_RuntimeData* CFXJSE_RuntimeData::Create(v8::Isolate* pIsolate)
+{
+ CFXJSE_RuntimeData* pRuntimeData = FX_NEW CFXJSE_RuntimeData(pIsolate);
+ ASSERT(pRuntimeData);
+ CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate);
+ v8::Local<v8::FunctionTemplate> hFuncTemplate = v8::FunctionTemplate::New(pIsolate);
+ v8::Local<v8::Context> hContext = v8::Context::New(pIsolate, 0, hFuncTemplate->InstanceTemplate());
+ hContext->SetSecurityToken(v8::External::New(pIsolate, pIsolate));
+ pRuntimeData->m_hRootContextGlobalTemplate.Reset(pIsolate, hFuncTemplate);
+ pRuntimeData->m_hRootContext.Reset(pIsolate, hContext);
+ return pRuntimeData;
+}
+CFXJSE_RuntimeData* CFXJSE_RuntimeData::Get(v8::Isolate* pIsolate)
+{
+ ASSERT(pIsolate);
+ CFXJSE_RuntimeData* pRuntimeData = static_cast<CFXJSE_RuntimeData*>(pIsolate->GetData(0));
+ if(!pRuntimeData) {
+ pRuntimeData = CFXJSE_RuntimeData::Create(pIsolate);
+ ASSERT(pRuntimeData);
+ pIsolate->SetData(0, pRuntimeData);
+ }
+ return pRuntimeData;
+}
+CFXJSE_RuntimeList * CFXJSE_RuntimeData::g_RuntimeList = NULL;
+void CFXJSE_RuntimeList::AppendRuntime(v8::Isolate* pIsolate)
+{
+ m_RuntimeList.Add(pIsolate);
+}
+void CFXJSE_RuntimeList::RemoveRuntime(v8::Isolate* pIsolate, CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback)
+{
+ FX_INT32 iIdx = m_RuntimeList.Find(pIsolate, 0);
+ if(iIdx >= 0) {
+ m_RuntimeList.RemoveAt(iIdx, 1);
+ }
+ if(lpfnDisposeCallback) {
+ lpfnDisposeCallback(pIsolate);
+ }
+}
+void CFXJSE_RuntimeList::RemoveAllRuntimes(CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback)
+{
+ FX_INT32 iSize = m_RuntimeList.GetSize();
+ if(lpfnDisposeCallback) {
+ for(FX_INT32 iIdx = 0; iIdx < iSize; iIdx++) {
+ lpfnDisposeCallback(m_RuntimeList[iIdx]);
+ }
+ }
+ m_RuntimeList.RemoveAll();
+}
diff --git a/xfa/src/fxjse/src/runtime.h b/xfa/src/fxjse/src/runtime.h
new file mode 100644
index 0000000000..78e891bfe4
--- /dev/null
+++ b/xfa/src/fxjse/src/runtime.h
@@ -0,0 +1,39 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJSE_RUNTIME_H_
+#define FXJSE_RUNTIME_H_
+class CFXJSE_RuntimeList;
+class CFXJSE_RuntimeData : public CFX_Object
+{
+protected:
+ CFXJSE_RuntimeData(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {};
+public:
+ static CFXJSE_RuntimeData* Create(v8::Isolate* pIsolate);
+ static CFXJSE_RuntimeData* Get(v8::Isolate* pIsolate);
+public:
+ v8::Isolate* m_pIsolate;
+ v8::Persistent<v8::FunctionTemplate> m_hRootContextGlobalTemplate;
+ v8::Persistent<v8::Context> m_hRootContext;
+public:
+ static CFXJSE_RuntimeList* g_RuntimeList;
+protected:
+ CFXJSE_RuntimeData();
+ CFXJSE_RuntimeData(const CFXJSE_RuntimeData&);
+ CFXJSE_RuntimeData& operator = (const CFXJSE_RuntimeData&);
+};
+class CFXJSE_RuntimeList : public CFX_Object
+{
+public:
+ typedef void (*RuntimeDisposeCallback)(v8::Isolate*);
+public:
+ void AppendRuntime(v8::Isolate* pIsolate);
+ void RemoveRuntime(v8::Isolate* pIsolate, RuntimeDisposeCallback lpfnDisposeCallback);
+ void RemoveAllRuntimes(RuntimeDisposeCallback lpfnDisposeCallback);
+protected:
+ CFX_ArrayTemplate<v8::Isolate*> m_RuntimeList;
+};
+#endif
diff --git a/xfa/src/fxjse/src/scope_inline.h b/xfa/src/fxjse/src/scope_inline.h
new file mode 100644
index 0000000000..8a590f3fb8
--- /dev/null
+++ b/xfa/src/fxjse/src/scope_inline.h
@@ -0,0 +1,86 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJSE_SCOPE_INLINE_H_
+#define FXJSE_SCOPE_INLINE_H_
+#include "runtime.h"
+#include "context.h"
+class CFXJSE_ScopeUtil_IsolateHandle
+{
+protected:
+ v8::Isolate* m_isolate;
+ v8::Locker m_locker;
+ v8::Isolate::Scope m_iscope;
+ v8::HandleScope m_hscope;
+public:
+ explicit CFXJSE_ScopeUtil_IsolateHandle(v8::Isolate* pIsolate) : m_isolate(pIsolate), m_locker(pIsolate), m_iscope(pIsolate), m_hscope(pIsolate) {}
+ v8::Isolate* GetIsolate()
+ {
+ return m_isolate;
+ }
+private:
+ CFXJSE_ScopeUtil_IsolateHandle(const CFXJSE_ScopeUtil_IsolateHandle&);
+ void operator=(const CFXJSE_ScopeUtil_IsolateHandle&);
+ void* operator new(size_t size);
+ void operator delete(void*, size_t);
+};
+class CFXJSE_ScopeUtil_IsolateHandleRootContext
+{
+ CFXJSE_ScopeUtil_IsolateHandle m_parent;
+ v8::Context::Scope m_cscope;
+public:
+ explicit CFXJSE_ScopeUtil_IsolateHandleRootContext(v8::Isolate* pIsolate) : m_parent(pIsolate), m_cscope(v8::Local<v8::Context>::New(pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext)) {}
+private:
+ CFXJSE_ScopeUtil_IsolateHandleRootContext(const CFXJSE_ScopeUtil_IsolateHandleRootContext&);
+ void operator=(const CFXJSE_ScopeUtil_IsolateHandleRootContext&);
+ void* operator new(size_t size);
+ void operator delete(void*, size_t);
+};
+class CFXJSE_ScopeUtil_IsolateHandleContext
+{
+ CFXJSE_Context* m_context;
+ CFXJSE_ScopeUtil_IsolateHandle m_parent;
+ v8::Context::Scope m_cscope;
+public:
+ explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext) : m_context(pContext), m_parent(pContext->m_pIsolate), m_cscope(v8::Local<v8::Context>::New(pContext->m_pIsolate, pContext->m_hContext)) {}
+ v8::Isolate* GetIsolate()
+ {
+ return m_context->m_pIsolate;
+ }
+ v8::Local<v8::Context> GetLocalContext()
+ {
+ return v8::Local<v8::Context>::New(m_context->m_pIsolate, m_context->m_hContext);
+ }
+private:
+ CFXJSE_ScopeUtil_IsolateHandleContext(const CFXJSE_ScopeUtil_IsolateHandleContext&);
+ void operator=(const CFXJSE_ScopeUtil_IsolateHandleContext&);
+ void* operator new(size_t size);
+ void operator delete(void*, size_t);
+};
+class CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext
+{
+ CFXJSE_Context* m_context;
+ CFXJSE_ScopeUtil_IsolateHandle m_parent;
+ v8::Context::Scope m_cscope;
+public:
+ explicit CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext(v8::Isolate* pIsolate, CFXJSE_Context* pContext)
+ : m_context(pContext), m_parent(pIsolate), m_cscope(v8::Local<v8::Context>::New(pIsolate, pContext ? pContext->m_hContext : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext)) {}
+ v8::Isolate* GetIsolate()
+ {
+ return m_parent.GetIsolate();
+ }
+ v8::Local<v8::Context> GetLocalContext()
+ {
+ v8::Isolate* pIsolate = m_parent.GetIsolate();
+ return v8::Local<v8::Context>::New(pIsolate, m_context ? m_context->m_hContext : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
+ }
+private:
+ CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext(const CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext&);
+ void operator=(const CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext&);
+ void* operator new(size_t size);
+ void operator delete(void*, size_t);
+};
+#endif
diff --git a/xfa/src/fxjse/src/util_inline.h b/xfa/src/fxjse/src/util_inline.h
new file mode 100644
index 0000000000..dddcab3053
--- /dev/null
+++ b/xfa/src/fxjse/src/util_inline.h
@@ -0,0 +1,44 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJSE_UTIL_INLINE_H_
+#define FXJSE_UTIL_INLINE_H_
+static V8_INLINE v8::Local<v8::Object> FXJSE_GetGlobalObjectFromContext(const v8::Local<v8::Context>& hContext)
+{
+ return hContext->Global()->GetPrototype().As<v8::Object>();
+}
+static V8_INLINE void FXJSE_UpdateObjectBinding(v8::Local<v8::Object>& hObject, FX_LPVOID lpNewBinding)
+{
+ ASSERT(!hObject.IsEmpty());
+ ASSERT(hObject->InternalFieldCount() > 0);
+ hObject->SetAlignedPointerInInternalField(0, lpNewBinding);
+}
+static V8_INLINE FX_LPVOID FXJSE_RetrieveObjectBinding(const v8::Local<v8::Object>& hJSObject, CFXJSE_Class* lpClass = NULL)
+{
+ ASSERT(!hJSObject.IsEmpty());
+ if(!hJSObject->IsObject()) {
+ return NULL;
+ }
+ v8::Local<v8::Object> hObject = hJSObject;
+ if(hObject->InternalFieldCount() == 0) {
+ v8::Handle<v8::Value> hProtoObject = hObject->GetPrototype();
+ if(hProtoObject.IsEmpty() || !hProtoObject->IsObject()) {
+ return NULL;
+ }
+ hObject = hProtoObject.As<v8::Object>();
+ if(hObject->InternalFieldCount() == 0) {
+ return NULL;
+ }
+ }
+ if(lpClass) {
+ v8::Local<v8::FunctionTemplate> hClass = v8::Local<v8::FunctionTemplate>::New(lpClass->GetContext()->GetRuntime(), lpClass->GetTemplate());
+ if(!hClass->HasInstance(hObject)) {
+ return NULL;
+ }
+ }
+ return hObject->GetAlignedPointerFromInternalField(0);
+}
+#endif
diff --git a/xfa/src/fxjse/src/value.cpp b/xfa/src/fxjse/src/value.cpp
new file mode 100644
index 0000000000..cd2fff1595
--- /dev/null
+++ b/xfa/src/fxjse/src/value.cpp
@@ -0,0 +1,524 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../foxitlib.h"
+#include "fxv8.h"
+#include "value.h"
+#include "class.h"
+#include <math.h>
+#include "util_inline.h"
+#if !defined(__PLACEMENT_NEW_INLINE) && !defined(_MFC_VER) && !defined(_NEW)
+#define __PLACEMENT_NEW_INLINE
+inline void* operator new(size_t size, void* pos)
+{
+ return pos;
+}
+inline void operator delete(void* ptr, void* pos)
+{
+}
+#endif
+FX_BOOL FXJSE_Value_IsUndefined (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsUndefined();
+}
+FX_BOOL FXJSE_Value_IsNull (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsNull();
+}
+FX_BOOL FXJSE_Value_IsBoolean (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsBoolean();
+}
+FX_BOOL FXJSE_Value_IsUTF8String(FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsString();
+}
+FX_BOOL FXJSE_Value_IsNumber (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsNumber();
+}
+FX_BOOL FXJSE_Value_IsInteger (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsInteger();
+}
+FX_BOOL FXJSE_Value_IsObject (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsObject();
+}
+FX_BOOL FXJSE_Value_IsArray (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsArray();
+}
+FX_BOOL FXJSE_Value_IsFunction(FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsFunction();
+}
+FX_BOOL FXJSE_Value_IsDate(FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue && lpValue->IsDate();
+}
+FX_BOOL FXJSE_Value_ToBoolean (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->ToBoolean();
+}
+FX_FLOAT FXJSE_Value_ToFloat (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->ToFloat();
+}
+FXJSE_DOUBLE FXJSE_Value_ToDouble (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->ToDouble();
+}
+void FXJSE_Value_ToUTF8String (FXJSE_HVALUE hValue, CFX_ByteString& szStrOutput)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->ToString(szStrOutput);
+}
+FX_INT32 FXJSE_Value_ToInteger (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->ToInteger();
+}
+FX_LPVOID FXJSE_Value_ToObject (FXJSE_HVALUE hValue, FXJSE_HCLASS hClass)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Class* lpClass = reinterpret_cast<CFXJSE_Class*>(hClass);
+ ASSERT(lpValue);
+ return lpValue->ToObject(lpClass);
+}
+void FXJSE_Value_SetUndefined (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->SetUndefined();
+}
+void FXJSE_Value_SetNull (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->SetNull();
+}
+void FXJSE_Value_SetBoolean (FXJSE_HVALUE hValue, FX_BOOL bBoolean)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->SetBoolean(bBoolean);
+}
+void FXJSE_Value_SetUTF8String (FXJSE_HVALUE hValue, FX_BSTR szString)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->SetString(szString);
+}
+void FXJSE_Value_SetInteger (FXJSE_HVALUE hValue, FX_INT32 nInteger)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->SetInteger(nInteger);
+}
+void FXJSE_Value_SetFloat (FXJSE_HVALUE hValue, FX_FLOAT fFloat)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->SetFloat(fFloat);
+}
+void FXJSE_Value_SetDouble (FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->SetDouble(dDouble);
+}
+void FXJSE_Value_SetObject (FXJSE_HVALUE hValue, FX_LPVOID lpObject, FXJSE_HCLASS hClass)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Class* lpClass = reinterpret_cast<CFXJSE_Class*>(hClass);
+ if(lpClass == NULL) {
+ ASSERT(lpObject == NULL);
+ lpValue->SetJSObject();
+ } else if(lpClass != NULL) {
+ lpValue->SetHostObject(lpObject, lpClass);
+ }
+}
+void FXJSE_Value_SetArray (FXJSE_HVALUE hValue, FX_UINT32 uValueCount, FXJSE_HVALUE* rgValues)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue->SetArray(uValueCount, reinterpret_cast<CFXJSE_Value**>(rgValues));
+}
+void FXJSE_Value_SetDate (FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ return lpValue->SetDate(dDouble);
+}
+void FXJSE_Value_Set (FXJSE_HVALUE hValue, FXJSE_HVALUE hOriginalValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Value* lpOriginalValue = reinterpret_cast<CFXJSE_Value*>(hOriginalValue);
+ ASSERT(lpValue && lpOriginalValue);
+ return lpValue->Assign(lpOriginalValue);
+}
+FX_BOOL FXJSE_Value_GetObjectProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FXJSE_HVALUE hPropValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
+ ASSERT(lpValue && lpPropValue);
+ return lpValue->GetObjectProperty(szPropName, lpPropValue);
+}
+FX_BOOL FXJSE_Value_SetObjectProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FXJSE_HVALUE hPropValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
+ ASSERT(lpValue && lpPropValue);
+ return lpValue->SetObjectProperty(szPropName, lpPropValue);
+}
+FX_BOOL FXJSE_Value_GetObjectPropByIdx (FXJSE_HVALUE hValue, FX_UINT32 uPropIdx, FXJSE_HVALUE hPropValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
+ ASSERT(lpValue && lpPropValue);
+ return lpValue->GetObjectProperty(uPropIdx, lpPropValue);
+}
+FX_BOOL FXJSE_Value_SetObjectPropByIdx (FXJSE_HVALUE hValue, FX_UINT32 uPropIdx, FXJSE_HVALUE hPropValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
+ ASSERT(lpValue && lpPropValue);
+ return lpValue->SetObjectProperty(uPropIdx, lpPropValue);
+}
+FX_BOOL FXJSE_Value_DeleteObjectProp (FXJSE_HVALUE hValue, FX_BSTR szPropName)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->DeleteObjectProperty(szPropName);
+}
+FX_BOOL FXJSE_Value_ObjectHasOwnProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FX_BOOL bUseTypeGetter)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return lpValue->HasObjectOwnProperty(szPropName, bUseTypeGetter);
+}
+FX_BOOL FXJSE_Value_SetObjectOwnProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FXJSE_HVALUE hPropValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
+ ASSERT(lpValue && lpPropValue);
+ return lpValue->SetObjectOwnProperty(szPropName, lpPropValue);
+}
+FX_BOOL FXJSE_Value_SetFunctionBind (FXJSE_HVALUE hValue, FXJSE_HVALUE hOldFunction, FXJSE_HVALUE hNewThis)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ CFXJSE_Value* lpOldFunction = reinterpret_cast<CFXJSE_Value*>(hOldFunction);
+ CFXJSE_Value* lpNewThis = reinterpret_cast<CFXJSE_Value*>(hNewThis);
+ ASSERT(lpValue && lpOldFunction && lpNewThis);
+ return lpValue->SetFunctionBind(lpOldFunction, lpNewThis);
+}
+FX_BOOL FXJSE_Value_CallFunction(FXJSE_HVALUE hFunction, FXJSE_HVALUE hThis, FXJSE_HVALUE hRetValue, FX_UINT32 nArgCount, FXJSE_HVALUE* lpArgs)
+{
+ CFXJSE_Value* lpFunction = reinterpret_cast<CFXJSE_Value*>(hFunction);
+ CFXJSE_Value* lpThis = reinterpret_cast<CFXJSE_Value*>(hThis);
+ CFXJSE_Value* lpRetValue = reinterpret_cast<CFXJSE_Value*>(hRetValue);
+ ASSERT(lpFunction);
+ return lpFunction->Call(lpThis, lpRetValue, nArgCount, lpArgs);
+}
+FXJSE_HVALUE FXJSE_Value_Create (FXJSE_HRUNTIME hRuntime)
+{
+ CFXJSE_Value* lpValue = CFXJSE_Value::Create(reinterpret_cast<v8::Isolate*>(hRuntime));
+ ASSERT(lpValue);
+ return reinterpret_cast<FXJSE_HVALUE>(lpValue);
+}
+void FXJSE_Value_Release (FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ if(lpValue) {
+ delete lpValue;
+ }
+}
+FXJSE_HRUNTIME FXJSE_Value_GetRuntime(FXJSE_HVALUE hValue)
+{
+ CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
+ ASSERT(lpValue);
+ return reinterpret_cast<FXJSE_HRUNTIME>(lpValue->GetIsolate());
+}
+void FXJSE_ThrowMessage(FX_BSTR utf8Name, FX_BSTR utf8Message)
+{
+ v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
+ ASSERT(pIsolate);
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
+ v8::Handle<v8::String> hMessage = v8::String::NewFromUtf8(pIsolate, utf8Message.GetCStr(), v8::String::kNormalString, utf8Message.GetLength());
+ v8::Handle<v8::Value> hError;
+ if(utf8Name == "RangeError") {
+ hError = v8::Exception::RangeError(hMessage);
+ } else if(utf8Name == "ReferenceError") {
+ hError = v8::Exception::ReferenceError(hMessage);
+ } else if(utf8Name == "SyntaxError") {
+ hError = v8::Exception::SyntaxError(hMessage);
+ } else if(utf8Name == "TypeError") {
+ hError = v8::Exception::TypeError(hMessage);
+ } else {
+ hError = v8::Exception::Error(hMessage);
+ if(utf8Name != "Error" && !utf8Name.IsEmpty()) {
+ hError.As<v8::Object>()->Set(v8::String::NewFromUtf8(pIsolate, "name"), v8::String::NewFromUtf8(pIsolate, utf8Name.GetCStr(), v8::String::kNormalString, utf8Name.GetLength()));
+ }
+ }
+ pIsolate->ThrowException(hError);
+}
+CFXJSE_Value* CFXJSE_Value::Create(v8::Isolate* pIsolate)
+{
+ return FX_NEW CFXJSE_Value(pIsolate);
+}
+FX_LPVOID CFXJSE_Value::ToObject(CFXJSE_Class* lpClass) const
+{
+ ASSERT(!m_hValue.IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ ASSERT(!hValue.IsEmpty());
+ if(!hValue->IsObject()) {
+ return NULL;
+ }
+ return FXJSE_RetrieveObjectBinding(hValue.As<v8::Object>(), lpClass);
+}
+V8_INLINE static double FXJSE_ftod(FX_FLOAT fNumber)
+{
+ if(sizeof(FX_FLOAT) != 4) {
+ ASSERT(FALSE);
+ return fNumber;
+ }
+ FX_UINT32 nFloatBits = (FX_UINT32&)fNumber;
+ FX_UINT8 nExponent = (FX_UINT8)(nFloatBits >> 16 >> 7 );
+ if(nExponent == 0 || nExponent == 255) {
+ return fNumber;
+ }
+ FX_INT8 nErrExp = nExponent - 127 - 23;
+ if(nErrExp >= 0) {
+ return fNumber;
+ }
+ double dwError = pow(2.0, nErrExp), dwErrorHalf = dwError / 2;
+ double dNumber = fNumber, dNumberAbs = fabs(fNumber);
+ double dNumberAbsMin = dNumberAbs - dwErrorHalf, dNumberAbsMax = dNumberAbs + dwErrorHalf;
+ FX_INT32 iErrPos = 0;
+ if(floor(dNumberAbsMin) == floor(dNumberAbsMax)) {
+ dNumberAbsMin = fmod(dNumberAbsMin, 1.0);
+ dNumberAbsMax = fmod(dNumberAbsMax, 1.0);
+ FX_INT32 iErrPosMin = 1, iErrPosMax = 38;
+ do {
+ FX_INT32 iMid = (iErrPosMin + iErrPosMax) / 2;
+ double dPow = pow(10.0, iMid);
+ if(floor(dNumberAbsMin * dPow) == floor(dNumberAbsMax * dPow)) {
+ iErrPosMin = iMid + 1;
+ } else {
+ iErrPosMax = iMid;
+ }
+ } while (iErrPosMin < iErrPosMax);
+ iErrPos = iErrPosMax;
+ }
+ double dPow = pow(10.0, iErrPos);
+ return fNumber < 0 ? ceil(dNumber * dPow - 0.5) / dPow : floor(dNumber * dPow + 0.5) / dPow;
+}
+void CFXJSE_Value::SetFloat(FX_FLOAT fFloat)
+{
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Number::New(m_pIsolate, FXJSE_ftod(fFloat));
+ m_hValue.Reset(m_pIsolate, hValue);
+}
+void CFXJSE_Value::SetHostObject(FX_LPVOID lpObject, CFXJSE_Class* lpClass)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ ASSERT(lpClass);
+ v8::Local<v8::FunctionTemplate> hClass = v8::Local<v8::FunctionTemplate>::New(m_pIsolate, lpClass->m_hTemplate);
+ v8::Local<v8::Object> hObject = hClass->InstanceTemplate()->NewInstance();
+ FXJSE_UpdateObjectBinding(hObject, lpObject);
+ m_hValue.Reset(m_pIsolate, hObject);
+}
+void CFXJSE_Value::SetArray(FX_UINT32 uValueCount, CFXJSE_Value** rgValues)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Array> hArrayObject = v8::Array::New(m_pIsolate, uValueCount);
+ if (rgValues) {
+ for(FX_UINT32 i = 0; i < uValueCount; i++) {
+ if(rgValues[i]) {
+ hArrayObject->Set(i, v8::Local<v8::Value>::New(m_pIsolate, rgValues[i]->DirectGetValue()));
+ }
+ }
+ }
+ m_hValue.Reset(m_pIsolate, hArrayObject);
+}
+void CFXJSE_Value::SetDate(FXJSE_DOUBLE dDouble)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hDate = v8::Date::New(m_pIsolate, dDouble);
+ m_hValue.Reset(m_pIsolate, hDate);
+}
+FX_BOOL CFXJSE_Value::SetObjectProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ if(!hObject->IsObject()) {
+ return FALSE;
+ }
+ v8::Local<v8::Value> hPropValue = v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
+ return (FX_BOOL)hObject.As<v8::Object>()->Set(v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, szPropName.GetLength()), hPropValue);
+}
+FX_BOOL CFXJSE_Value::GetObjectProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ if(!hObject->IsObject()) {
+ return FALSE;
+ }
+ v8::Local<v8::Value> hPropValue = hObject.As<v8::Object>()->Get(v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, szPropName.GetLength()));
+ lpPropValue->ForceSetValue(hPropValue);
+ return TRUE;
+}
+FX_BOOL CFXJSE_Value::SetObjectProperty(FX_UINT32 uPropIdx, CFXJSE_Value* lpPropValue)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ if(!hObject->IsObject()) {
+ return FALSE;
+ }
+ v8::Local<v8::Value> hPropValue = v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
+ return (FX_BOOL)hObject.As<v8::Object>()->Set(uPropIdx, hPropValue);
+}
+FX_BOOL CFXJSE_Value::GetObjectProperty(FX_UINT32 uPropIdx, CFXJSE_Value* lpPropValue)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ if(!hObject->IsObject()) {
+ return FALSE;
+ }
+ v8::Local<v8::Value> hPropValue = hObject.As<v8::Object>()->Get(uPropIdx);
+ lpPropValue->ForceSetValue(hPropValue);
+ return TRUE;
+}
+FX_BOOL CFXJSE_Value::DeleteObjectProperty(FX_BSTR szPropName)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ if(!hObject->IsObject()) {
+ return FALSE;
+ }
+ hObject.As<v8::Object>()->Delete(v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, szPropName.GetLength()));
+ return TRUE;
+}
+FX_BOOL CFXJSE_Value::HasObjectOwnProperty(FX_BSTR szPropName, FX_BOOL bUseTypeGetter)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ if(!hObject->IsObject()) {
+ return FALSE;
+ }
+ v8::Local<v8::String> hKey = v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, szPropName.GetLength());
+ return hObject.As<v8::Object>()->HasRealNamedProperty(hKey) || (bUseTypeGetter && hObject.As<v8::Object>()->HasOwnProperty(hKey));
+}
+FX_BOOL CFXJSE_Value::SetObjectOwnProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ if(!hObject->IsObject()) {
+ return FALSE;
+ }
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->m_hValue);
+ return hObject.As<v8::Object>()->ForceSet(v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, szPropName.GetLength()), hValue);
+}
+FX_BOOL CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Handle<v8::Value> rgArgs[2];
+ v8::Local<v8::Value> hOldFunction = v8::Local<v8::Value>::New(m_pIsolate, lpOldFunction->DirectGetValue());
+ if(hOldFunction.IsEmpty() || !hOldFunction->IsFunction()) {
+ return FALSE;
+ }
+ rgArgs[0] = hOldFunction;
+ v8::Local<v8::Value> hNewThis = v8::Local<v8::Value>::New(m_pIsolate, lpNewThis->DirectGetValue());
+ if(hNewThis.IsEmpty()) {
+ return FALSE;
+ }
+ rgArgs[1] = hNewThis;
+ v8::Local<v8::String> hBinderFuncSource = v8::String::NewFromUtf8(m_pIsolate, "(function (oldfunction, newthis) { return oldfunction.bind(newthis); })");
+ v8::Local<v8::Function> hBinderFunc = v8::Script::Compile(hBinderFuncSource)->Run().As<v8::Function>();
+ v8::Local<v8::Value> hBoundFunction = hBinderFunc->Call(m_pIsolate->GetCurrentContext()->Global(), 2, rgArgs);
+ if(hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction()) {
+ return FALSE;
+ }
+ m_hValue.Reset(m_pIsolate, hBoundFunction);
+ return TRUE;
+}
+#define FXJSE_INVALID_PTR ((FX_LPVOID)(FX_INTPTR)-1)
+FX_BOOL CFXJSE_Value::Call(CFXJSE_Value* lpReceiver, CFXJSE_Value* lpRetValue, FX_UINT32 nArgCount, FXJSE_HVALUE* lpArgs)
+{
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hFunctionValue = v8::Local<v8::Value>::New(m_pIsolate, DirectGetValue());
+ v8::Local<v8::Object> hFunctionObject = !hFunctionValue.IsEmpty() && hFunctionValue->IsObject() ? hFunctionValue.As<v8::Object>() : v8::Local<v8::Object>();
+ v8::TryCatch trycatch;
+ if (hFunctionObject.IsEmpty() || !hFunctionObject->IsCallable()) {
+ if(lpRetValue) {
+ lpRetValue->ForceSetValue(FXJSE_CreateReturnValue(m_pIsolate, trycatch));
+ }
+ return FALSE;
+ }
+ v8::Local<v8::Value> hReturnValue;
+ v8::Handle<v8::Value>* lpLocalArgs = NULL;
+ if(nArgCount) {
+ lpLocalArgs = FX_Alloc(v8::Handle<v8::Value>, nArgCount);
+ if (!lpLocalArgs) {
+ return FALSE;
+ }
+ for (FX_UINT32 i = 0; i < nArgCount; i++) {
+ new (lpLocalArgs + i) v8::Handle<v8::Value>;
+ CFXJSE_Value* lpArg = (CFXJSE_Value*)lpArgs[i];
+ if(lpArg) {
+ lpLocalArgs[i] = v8::Local<v8::Value>::New(m_pIsolate, lpArg->DirectGetValue());
+ }
+ if (lpLocalArgs[i].IsEmpty()) {
+ lpLocalArgs[i] = v8::Undefined(m_pIsolate);
+ }
+ }
+ }
+ FX_BOOL bRetValue = TRUE;
+ if(lpReceiver == FXJSE_INVALID_PTR) {
+ hReturnValue = hFunctionObject->CallAsConstructor(nArgCount, lpLocalArgs);
+ } else {
+ v8::Local<v8::Value> hReceiver;
+ if(lpReceiver) {
+ hReceiver = v8::Local<v8::Value>::New(m_pIsolate, lpReceiver->DirectGetValue());
+ }
+ if(hReceiver.IsEmpty() || !hReceiver->IsObject()) {
+ hReceiver = v8::Object::New(m_pIsolate);
+ }
+ hReturnValue = hFunctionObject->CallAsFunction(hReceiver, nArgCount, lpLocalArgs);
+ }
+ if(trycatch.HasCaught()) {
+ hReturnValue = FXJSE_CreateReturnValue(m_pIsolate, trycatch);
+ bRetValue = FALSE;
+ }
+ if(lpRetValue) {
+ lpRetValue->ForceSetValue(hReturnValue);
+ }
+ if(lpLocalArgs) {
+ for (FX_UINT32 i = 0; i < nArgCount; i++) {
+ lpLocalArgs[i].~Handle();
+ }
+ FX_Free(lpLocalArgs);
+ }
+ return bRetValue;
+}
diff --git a/xfa/src/fxjse/src/value.h b/xfa/src/fxjse/src/value.h
new file mode 100644
index 0000000000..aca23bf310
--- /dev/null
+++ b/xfa/src/fxjse/src/value.h
@@ -0,0 +1,236 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef FXJSE_VALUE_H_
+#define FXJSE_VALUE_H_
+#include "scope_inline.h"
+class CFXJSE_Value : public CFX_Object
+{
+public:
+ CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
+protected:
+ CFXJSE_Value();
+ CFXJSE_Value(const CFXJSE_Value&);
+ CFXJSE_Value& operator = (const CFXJSE_Value&);
+public:
+ V8_INLINE FX_BOOL IsUndefined() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsUndefined();
+ }
+ V8_INLINE FX_BOOL IsNull() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsNull();
+ }
+ V8_INLINE FX_BOOL IsBoolean() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsBoolean();
+ }
+ V8_INLINE FX_BOOL IsString() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsString();
+ }
+ V8_INLINE FX_BOOL IsNumber() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsNumber();
+ }
+ V8_INLINE FX_BOOL IsInteger() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsInt32();
+ }
+ V8_INLINE FX_BOOL IsObject() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsObject();
+ }
+ V8_INLINE FX_BOOL IsArray() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsArray();
+ }
+ V8_INLINE FX_BOOL IsFunction() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsFunction();
+ }
+ V8_INLINE FX_BOOL IsDate() const
+ {
+ if (m_hValue.IsEmpty()) {
+ return FALSE;
+ }
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return hValue->IsDate();
+ }
+public:
+ V8_INLINE FX_BOOL ToBoolean() const
+ {
+ ASSERT(!m_hValue.IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return static_cast<FX_BOOL>(hValue->BooleanValue());
+ }
+ V8_INLINE FX_FLOAT ToFloat() const
+ {
+ ASSERT(!m_hValue.IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return static_cast<FX_FLOAT>(hValue->NumberValue());
+ }
+ V8_INLINE FXJSE_DOUBLE ToDouble() const
+ {
+ ASSERT(!m_hValue.IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return static_cast<FXJSE_DOUBLE>(hValue->NumberValue());
+ }
+ V8_INLINE FX_INT32 ToInteger() const
+ {
+ ASSERT(!m_hValue.IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ return static_cast<FX_INT32>(hValue->NumberValue());
+ }
+ V8_INLINE void ToString(CFX_ByteString& szStrOutput) const
+ {
+ ASSERT(!m_hValue.IsEmpty());
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
+ v8::Local<v8::String> hString = hValue->ToString();
+ v8::String::Utf8Value hStringVal(hString);
+ szStrOutput = *hStringVal;
+ }
+ FX_LPVOID ToObject(CFXJSE_Class* lpClass) const;
+public:
+ V8_INLINE void SetUndefined()
+ {
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Undefined(m_pIsolate);
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ V8_INLINE void SetNull()
+ {
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Null(m_pIsolate);
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ V8_INLINE void SetBoolean(FX_BOOL bBoolean)
+ {
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Boolean::New(m_pIsolate, bBoolean != FALSE);
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ V8_INLINE void SetInteger(FX_INT32 nInteger)
+ {
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Integer::New(m_pIsolate, nInteger);
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ V8_INLINE void SetDouble(FXJSE_DOUBLE dDouble)
+ {
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Number::New(m_pIsolate, dDouble);
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ V8_INLINE void SetString(FX_BSTR szString)
+ {
+ CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::String::NewFromUtf8(m_pIsolate,
+ reinterpret_cast<const char*>(szString.GetPtr()),
+ v8::String::kNormalString, szString.GetLength());
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ V8_INLINE void SetFloat(FX_FLOAT fFloat);
+ V8_INLINE void SetJSObject()
+ {
+ CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
+ v8::Local<v8::Value> hValue = v8::Object::New(m_pIsolate);
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ void SetHostObject(FX_LPVOID lpObject, CFXJSE_Class* lpClass);
+ void SetArray(FX_UINT32 uValueCount, CFXJSE_Value** rgValues);
+ void SetDate(FXJSE_DOUBLE dDouble);
+public:
+ FX_BOOL GetObjectProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue);
+ FX_BOOL SetObjectProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue);
+ FX_BOOL GetObjectProperty(FX_UINT32 uPropIdx, CFXJSE_Value* lpPropValue);
+ FX_BOOL SetObjectProperty(FX_UINT32 uPropIdx, CFXJSE_Value* lpPropValue);
+ FX_BOOL DeleteObjectProperty(FX_BSTR szPropName);
+ FX_BOOL HasObjectOwnProperty(FX_BSTR szPropName, FX_BOOL bUseTypeGetter);
+ FX_BOOL SetObjectOwnProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue);
+ FX_BOOL SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis);
+ FX_BOOL Call(CFXJSE_Value* lpReceiver, CFXJSE_Value* lpRetValue, FX_UINT32 nArgCount, FXJSE_HVALUE* lpArgs);
+public:
+ V8_INLINE v8::Isolate* GetIsolate() const
+ {
+ return m_pIsolate;
+ }
+ V8_INLINE const v8::Persistent<v8::Value>& DirectGetValue() const
+ {
+ return m_hValue;
+ }
+ V8_INLINE void ForceSetValue(v8::Local<v8::Value> hValue)
+ {
+ m_hValue.Reset(m_pIsolate, hValue);
+ }
+ V8_INLINE void Assign(const CFXJSE_Value* lpValue)
+ {
+ if(lpValue) {
+ m_hValue.Reset(m_pIsolate, lpValue->m_hValue);
+ } else {
+ m_hValue.Reset();
+ }
+ }
+public:
+ static CFXJSE_Value* Create(v8::Isolate* pIsolate);
+protected:
+ v8::Isolate* m_pIsolate;
+ v8::Persistent<v8::Value> m_hValue;
+ friend class CFXJSE_Context;
+ friend class CFXJSE_Class;
+};
+#endif
diff --git a/xfa_test/FormFiller_Test/BookMarkView.cpp b/xfa_test/FormFiller_Test/BookMarkView.cpp
new file mode 100644
index 0000000000..283c9a47cc
--- /dev/null
+++ b/xfa_test/FormFiller_Test/BookMarkView.cpp
@@ -0,0 +1,197 @@
+// BookMarkView.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+#include "ChildFrm.h"
+#include "BookMarkView.h"
+#include "ReaderVCDoc.h"
+#include "ReaderVCView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CBookMarkView
+
+IMPLEMENT_DYNCREATE(CBookMarkView, CTreeView)
+
+CBookMarkView::CBookMarkView()
+{
+ m_pFram = NULL;
+ m_pDoc = NULL;
+}
+
+CBookMarkView::~CBookMarkView()
+{
+}
+
+
+BEGIN_MESSAGE_MAP(CBookMarkView, CTreeView)
+ //{{AFX_MSG_MAP(CBookMarkView)
+ ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CBookMarkView drawing
+
+void CBookMarkView::OnDraw(CDC* pDC)
+{
+ CReaderVCDoc* pDoc = GetDocument();
+ // TODO: add draw code here
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CBookMarkView diagnostics
+
+#ifdef _DEBUG
+void CBookMarkView::AssertValid() const
+{
+ CTreeView::AssertValid();
+}
+
+void CBookMarkView::Dump(CDumpContext& dc) const
+{
+ CTreeView::Dump(dc);
+}
+
+CReaderVCDoc* CBookMarkView::GetDocument() // non-debug version is inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CReaderVCDoc)));
+ return (CReaderVCDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CBookMarkView message handlers
+
+void CBookMarkView::OnInitialUpdate()
+{
+ CTreeView::OnInitialUpdate();
+ CReaderVCDoc* pDoc = GetDocument();
+ if (! m_pFram || !m_pFram->m_pView)
+ return;
+ m_pDoc = m_pFram->m_pView->GetPDFDoc();
+ if(m_pDoc == NULL) return;
+ int num = m_pFram->m_pView->GetTotalPages();
+ CString strName = pDoc->GetTitle();
+ FPDF_BOOKMARK bookmark1 = NULL;
+
+ //////////////////////////////////////////////////////////////////////////
+ //insert items
+
+// CTreeCtrl &treeCtrl = this->GetTreeCtrl();
+// m_hItemRoot = treeCtrl.InsertItem(strName,0,0,TVI_ROOT,TVI_FIRST);
+// treeCtrl.SetItemData(m_hItemRoot,0);
+// bookmark1 = FPDFBookmark_GetFirstChild(m_pDoc, NULL);
+// if (bookmark1 == NULL)//insert the page index to tree
+// {
+// for (int i=0; i<num; i++)
+// {
+// CString str;
+// str.Format(_T("Page%d"), i+1);
+// HTREEITEM hItem = treeCtrl.InsertItem(str);
+// treeCtrl.SetItemData(hItem, i);
+// }
+// }else{
+// while(bookmark1 != NULL) {
+// this->InsertChildItem(bookmark1, m_hItemRoot, treeCtrl);
+// bookmark1 = FPDFBookmark_GetNextSibling(m_pDoc,bookmark1);
+// }
+// }
+// treeCtrl.Expand(m_hItemRoot,TVE_EXPAND);
+//
+// LONG nStyle = ::GetWindowLong(this->m_hWnd, GWL_STYLE);
+// nStyle |= TVS_LINESATROOT;
+// nStyle |= TVS_HASLINES;
+// nStyle |= TVS_HASBUTTONS;
+// ::SetWindowLong(this->m_hWnd, GWL_STYLE, nStyle);
+
+}
+
+void CBookMarkView::InsertChildItem(FPDF_BOOKMARK bookmark, HTREEITEM hItem, CTreeCtrl &treectrl)
+{
+
+// CString strTitle;
+// DWORD dwItemData = 0;
+// WCHAR buffer[1024];
+// CString str;
+// int strlenth = 0;
+// unsigned long pdf_actType = 0;
+// //FPDF_BOOKMARK
+// FPDF_DEST dest = NULL;
+// FPDF_ACTION action = NULL;
+//
+// memset(buffer,0,1024*sizeof(WCHAR));
+// strlenth = FPDFBookmark_GetTitle(bookmark, buffer, 0);
+// int nlen = WideCharToMultiByte(CP_ACP,0,buffer,-1,NULL,NULL,NULL,NULL);
+// char *buffer1 = new char[nlen];
+// memset(buffer1,0,nlen);
+// WideCharToMultiByte(CP_ACP,0,buffer,strlenth,buffer1,nlen,NULL,NULL);
+// buffer1[nlen -1] = '\0';
+// /* int strl = strlen(buffer1);
+// strTitle = buffer;//
+// strTitle = strTitle.Left(strl-1);*/
+// hItem = treectrl.InsertItem(buffer1, 0, 0, hItem, TVI_LAST);
+// action = FPDFBookmark_GetAction(bookmark);
+// if (action != NULL)
+// {
+// pdf_actType = FPDFAction_GetType(action);
+// if (pdf_actType == 1)
+// {
+// dest = FPDFAction_GetDest(m_pDoc, action);
+// dwItemData = FPDFDest_GetPageIndex(m_pDoc, dest);
+// int nZoomMode = FPDFDest_GetZoomMode(dest);
+// if(nZoomMode == 1)
+// {
+// double nStartX = FPDFDest_GetZoomParam(dest, 0);
+// double nStartY = FPDFDest_GetZoomParam(dest, 1);
+// CPoint pos((int)nStartX, (int)nStartY);
+// m_PosMap.SetAt(hItem, pos);
+// }
+// treectrl.SetItemData(hItem, dwItemData);
+//
+// }else{
+// dwItemData = 0;
+// treectrl.SetItemData(hItem, dwItemData);
+// }
+//
+// }else{
+// dest = FPDFBookmark_GetDest(m_pDoc, bookmark);
+// dwItemData = FPDFDest_GetPageIndex(m_pDoc, dest);
+// treectrl.SetItemData(hItem, dwItemData);
+// }
+//
+// bookmark = FPDFBookmark_GetFirstChild(m_pDoc, bookmark);
+// while(bookmark != NULL)
+// {
+// this->InsertChildItem(bookmark, hItem, treectrl);
+// bookmark = FPDFBookmark_GetNextSibling(m_pDoc, bookmark);
+// }
+// delete buffer1;
+}
+
+void CBookMarkView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
+ // TODO: Add your control notification handler code here
+ HTREEITEM hItem;
+ DWORD dwPageIdex= 0;
+ if(m_pDoc == NULL) return;
+ hItem = GetTreeCtrl().GetSelectedItem();
+ dwPageIdex = GetTreeCtrl().GetItemData(hItem);
+ CPoint p;
+ if(0 == m_PosMap.Lookup(hItem, p))
+ {
+ p.x = 0;
+ p.y = 0;
+ }
+ m_pFram->m_pView->LoadPDFPage(m_pDoc, dwPageIdex, p);
+ m_pFram->m_pView->Invalidate();
+ *pResult = 0;
+}
+
diff --git a/xfa_test/FormFiller_Test/BookMarkView.h b/xfa_test/FormFiller_Test/BookMarkView.h
new file mode 100644
index 0000000000..d10964c0ec
--- /dev/null
+++ b/xfa_test/FormFiller_Test/BookMarkView.h
@@ -0,0 +1,67 @@
+#if !defined(AFX_BOOKMARKVIEW_H__B1EB2803_BE21_4768_A54B_2DE1E0FC968A__INCLUDED_)
+#define AFX_BOOKMARKVIEW_H__B1EB2803_BE21_4768_A54B_2DE1E0FC968A__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// BookMarkView.h : header file
+//
+
+class CChildFrame;
+class CReaderVCDoc;
+/////////////////////////////////////////////////////////////////////////////
+// CBookMarkView view
+
+class CBookMarkView : public CTreeView
+{
+protected:
+ CBookMarkView(); // protected constructor used by dynamic creation
+ DECLARE_DYNCREATE(CBookMarkView)
+
+// Attributes
+public:
+ CChildFrame *m_pFram;
+ FPDF_DOCUMENT m_pDoc;
+ HTREEITEM m_hItemRoot;
+ CReaderVCDoc* GetDocument();
+// Operations
+public:
+ void InsertChildItem(FPDF_BOOKMARK bookmark, HTREEITEM hItem, CTreeCtrl &treectrl);
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CBookMarkView)
+ public:
+ virtual void OnInitialUpdate();
+ protected:
+ virtual void OnDraw(CDC* pDC); // overridden to draw this view
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ virtual ~CBookMarkView();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+ // Generated message map functions
+protected:
+ //{{AFX_MSG(CBookMarkView)
+ afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+private:
+ CMap<HTREEITEM, HTREEITEM&, CPoint, CPoint&> m_PosMap;
+};
+
+#ifndef _DEBUG // debug version in PDFReaderVCView.cpp
+inline CReaderVCDoc* CBookMarkView::GetDocument()
+{ return (CReaderVCDoc*)m_pDocument; }
+#endif
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_BOOKMARKVIEW_H__B1EB2803_BE21_4768_A54B_2DE1E0FC968A__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/ChildFrm.cpp b/xfa_test/FormFiller_Test/ChildFrm.cpp
new file mode 100644
index 0000000000..8d32a72ac7
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ChildFrm.cpp
@@ -0,0 +1,112 @@
+// ChildFrm.cpp : implementation of the CChildFrame class
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+
+#include "ChildFrm.h"
+#include "FX_SplitterWnd.h"
+#include "BookmarkView.h"
+#include "ReaderVCView.h"
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame
+
+IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)
+
+BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
+ //{{AFX_MSG_MAP(CChildFrame)
+ ON_WM_SIZE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame construction/destruction
+
+CChildFrame::CChildFrame()
+{
+ // TODO: add member initialization code here
+ //m_nPosH = m_nPosV = 0;
+// m_pBkView = NULL;
+ m_pView = NULL;
+// m_bBookmark = FALSE;
+}
+
+CChildFrame::~CChildFrame()
+{
+/* if (m_pBkView != NULL)
+ {
+ delete m_pBkView;
+ m_pBkView = NULL;
+ }
+ if (m_pView != NULL)
+ {
+ delete m_pView;
+ m_pView = NULL;
+ }*/
+}
+
+BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+
+ if( !CMDIChildWnd::PreCreateWindow(cs) )
+ return FALSE;
+ cs.style |= WS_MAXIMIZE | WS_VISIBLE;
+ return TRUE;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame diagnostics
+
+#ifdef _DEBUG
+void CChildFrame::AssertValid() const
+{
+ CMDIChildWnd::AssertValid();
+}
+
+void CChildFrame::Dump(CDumpContext& dc) const
+{
+ CMDIChildWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CChildFrame message handlers
+
+
+
+
+
+void CChildFrame::OnSize(UINT nType, int cx, int cy)
+{
+ CMDIChildWnd::OnSize(nType, cx, cy);
+
+
+}
+
+BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
+{
+ if ( !m_wndSplitter.CreateStatic( this, 1, 2 ) ||
+ !m_wndSplitter.CreateView( 0,0,RUNTIME_CLASS(CBookMarkView),CSize(180,0),pContext )||
+ !m_wndSplitter.CreateView( 0,1,pContext->m_pNewViewClass,CSize(0,0),pContext ))
+ {
+ return FALSE;
+ }
+ m_pBkView = (CBookMarkView *)(m_wndSplitter.GetPane(0,0));
+ m_pBkView->m_pFram = this;
+ m_pView = (CReaderVCView*)(m_wndSplitter.GetPane(0,1));
+ m_pView->m_pFram = this;
+ this->SetActiveView( (CView*)m_wndSplitter.GetPane(0,1) );
+
+ return TRUE;
+
+ //return CMDIChildWnd::OnCreateClient(lpcs, pContext);
+}
diff --git a/xfa_test/FormFiller_Test/ChildFrm.h b/xfa_test/FormFiller_Test/ChildFrm.h
new file mode 100644
index 0000000000..dcfc7bd8bc
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ChildFrm.h
@@ -0,0 +1,64 @@
+// ChildFrm.h : interface of the CChildFrame class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_CHILDFRM_H__452F838E_A3F7_4BBF_B4BB_4765F4D394E7__INCLUDED_)
+#define AFX_CHILDFRM_H__452F838E_A3F7_4BBF_B4BB_4765F4D394E7__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+//class CFX_SplitterWnd;
+#include "FX_SplitterWnd.h"
+class CReaderVCView;
+class CBookMarkView;
+//class CFX_SplitterWnd;
+class CChildFrame : public CMDIChildWnd
+{
+ DECLARE_DYNCREATE(CChildFrame)
+public:
+ CChildFrame();
+
+// Attributes
+public:
+ CFX_SplitterWnd m_wndSplitter;
+ CReaderVCView* m_pView;
+ CBookMarkView* m_pBkView;
+// BOOL m_bBookmark;
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CChildFrame)
+ public:
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ protected:
+ virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CChildFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CChildFrame)
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+private:
+ //int m_nPosH, m_nPosV;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CHILDFRM_H__452F838E_A3F7_4BBF_B4BB_4765F4D394E7__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/ConvertDlg.cpp b/xfa_test/FormFiller_Test/ConvertDlg.cpp
new file mode 100644
index 0000000000..ec31948144
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ConvertDlg.cpp
@@ -0,0 +1,65 @@
+// ConvertDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+#include "ConvertDlg.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CConvertDlg dialog
+
+
+CConvertDlg::CConvertDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CConvertDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CConvertDlg)
+ m_nFlag = -1;
+ //}}AFX_DATA_INIT
+}
+
+
+void CConvertDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CConvertDlg)
+ DDX_Radio(pDX, IDC_RADIO_Stream, m_nFlag);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CConvertDlg, CDialog)
+ //{{AFX_MSG_MAP(CConvertDlg)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CConvertDlg message handlers
+
+BOOL CConvertDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // TODO: Add extra initialization here
+ m_pView = (CReaderVCView *)(((CChildFrame *)((CMainFrame *)AfxGetMainWnd())->GetActiveFrame())->GetActiveView());
+ ASSERT(m_pView);
+ ((CButton *)GetDlgItem(IDC_RADIO_Appearance))->SetCheck(1);
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CConvertDlg::OnOK()
+{
+ // TODO: Add extra validation here
+ UpdateData(TRUE);
+ CDialog::OnOK();
+}
diff --git a/xfa_test/FormFiller_Test/ConvertDlg.h b/xfa_test/FormFiller_Test/ConvertDlg.h
new file mode 100644
index 0000000000..8ef993208a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ConvertDlg.h
@@ -0,0 +1,47 @@
+#if !defined(AFX_CONVERTDLG_H__9BB8EADD_CCDD_4C68_A8A0_C1656653A947__INCLUDED_)
+#define AFX_CONVERTDLG_H__9BB8EADD_CCDD_4C68_A8A0_C1656653A947__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// ConvertDlg.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CConvertDlg dialog
+class CReaderVCView;
+class CConvertDlg : public CDialog
+{
+// Construction
+public:
+ CConvertDlg(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CConvertDlg)
+ enum { IDD = IDD_DLG_CONVERT };
+ int m_nFlag;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CConvertDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ CReaderVCView *m_pView;
+ // Generated message map functions
+ //{{AFX_MSG(CConvertDlg)
+ virtual BOOL OnInitDialog();
+ virtual void OnOK();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_CONVERTDLG_H__9BB8EADD_CCDD_4C68_A8A0_C1656653A947__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/ExportPage.cpp b/xfa_test/FormFiller_Test/ExportPage.cpp
new file mode 100644
index 0000000000..76287a7d0b
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ExportPage.cpp
@@ -0,0 +1,189 @@
+// ExportPage.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+#include "ExportPage.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CExportPage dialog
+
+
+CExportPage::CExportPage(CWnd* pParent /*=NULL*/)
+ : CDialog(CExportPage::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CExportPage)
+ m_nHeight = 0;
+ m_nPageHeight = 0;
+ m_nRotate = 0;
+ m_nWidth = 0;
+ m_nPageWidth = 0;
+ //}}AFX_DATA_INIT
+ m_bitmap = NULL;
+}
+
+
+void CExportPage::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CExportPage)
+ DDX_Text(pDX, IDC_EDIT_HEIGHT, m_nHeight);
+ DDX_Text(pDX, IDC_EDIT_PAGE_HEIGHT, m_nPageHeight);
+ DDX_Text(pDX, IDC_EDIT_ROTATE, m_nRotate);
+ DDX_Text(pDX, IDC_EDIT_WIDTH, m_nWidth);
+ DDX_Text(pDX, IDC_EDIT_PAGE_WIDTH, m_nPageWidth);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CExportPage, CDialog)
+ //{{AFX_MSG_MAP(CExportPage)
+ ON_BN_CLICKED(IDC_Rander_Page, OnRanderPage)
+ ON_BN_CLICKED(IDC_Save, OnSave)
+ ON_WM_PAINT()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CExportPage message handlers
+
+void CExportPage::OnRanderPage()
+{
+ if (m_pView)
+ {
+ UpdateData(TRUE);
+ m_page=m_pView->GetPage();
+ if (!m_page) return;
+ if (m_nRotate==1 || m_nRotate==3)
+ {
+ int temp;
+ temp=m_nHeight;
+ m_nHeight=m_nWidth;
+ m_nWidth=temp;
+ }
+ m_bitmap=FPDFBitmap_Create(m_nWidth,m_nHeight,FPDFBitmap_BGRx);
+ FPDFBitmap_FillRect(m_bitmap,0,0,m_nWidth,m_nHeight,0xff,0xff,0xff,0xff);
+ FPDF_RenderPageBitmap(m_bitmap,m_page,0,0,200,200,m_nRotate,FPDF_ANNOT);
+ Invalidate();
+ if (m_nRotate==1 || m_nRotate==3)
+ {
+ int temp;
+ temp=m_nHeight;
+ m_nHeight=m_nWidth;
+ m_nWidth=temp;
+ }
+ //FPDFBitmap_Destroy(bitmap);
+ UpdateData(FALSE);
+ }
+
+}
+
+void CExportPage::InitDialogInfo(CReaderVCView *pView)
+{
+ m_pView=pView;
+ if (pView) m_page=pView->GetPage();
+ SetDlgInfo();
+}
+
+void CExportPage::SetDlgInfo()
+{
+ if (!m_page) return;
+ double height,width;
+ width=FPDF_GetPageWidth(m_page);
+ height=FPDF_GetPageHeight(m_page);
+
+ UpdateData(TRUE);
+ m_nPageHeight = (int)height;
+ m_nPageWidth = (int)width;
+ m_nWidth=(int)width/3;
+ m_nHeight=(int)height/3;
+ UpdateData(FALSE);
+}
+
+void CExportPage::OnSave()
+{
+ CFileDialog SavDlg(FALSE,"","",OFN_FILEMUSTEXIST |OFN_HIDEREADONLY,"bmp(*.bmp)|*.bmp||All Files(*.*)|*.*");
+ if (SavDlg.DoModal()==IDOK)
+ {
+ CString strFileName = SavDlg.GetPathName();
+ BITMAPFILEHEADER bitmapFileHeader;
+ BITMAPINFOHEADER bitmapInfoHeader;
+ BITMAP strBitmap;
+ int wBitCount = 32;
+ winbmp.GetBitmap(&strBitmap);
+ DWORD dwBmBitsSize = ((strBitmap.bmWidth * wBitCount+31)/32) * 4 * strBitmap.bmHeight;
+
+ bitmapFileHeader.bfType = 0x4D42;
+ bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize;
+ bitmapFileHeader.bfReserved1 = bitmapFileHeader.bfReserved2 = 0;
+ bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
+
+ bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bitmapInfoHeader.biWidth = strBitmap.bmWidth;
+ bitmapInfoHeader.biHeight = strBitmap.bmHeight;
+ bitmapInfoHeader.biPlanes = 1;
+ bitmapInfoHeader.biBitCount = wBitCount;
+ bitmapInfoHeader.biClrImportant = BI_RGB;
+ bitmapInfoHeader.biSizeImage = 0; //strBitmap.bmWidth * strBitmap.bmHeight;
+ bitmapInfoHeader.biXPelsPerMeter = 0;
+ bitmapInfoHeader.biYPelsPerMeter = 0;
+ bitmapInfoHeader.biClrUsed = 0;
+ bitmapInfoHeader.biCompression = 0;
+
+ char* context = new char[dwBmBitsSize];
+ CWindowDC dc(NULL);
+ GetDIBits(dc.GetSafeHdc(), (HBITMAP)winbmp.m_hObject, 0, bitmapInfoHeader.biHeight, (LPVOID)context,(BITMAPINFO*)&bitmapInfoHeader, DIB_RGB_COLORS);
+
+ CFile file;
+ file.Open(strFileName, CFile::modeCreate|CFile::modeWrite);
+ file.Write(&bitmapFileHeader, sizeof(BITMAPFILEHEADER));
+ file.Write(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER));
+ file.Write(context, dwBmBitsSize);
+
+ file.Close();
+ delete context;
+ }
+}
+
+void CExportPage::OnPaint()
+{
+ CPaintDC dc(this); // device context for painting
+
+ // TODO: Add your message handler code here
+ if(m_bitmap)
+ {
+ // CDC* pDc=GetDC();
+ int bufsize=FPDFBitmap_GetStride(m_bitmap)*m_nHeight;
+ void* bmpbuf=FPDFBitmap_GetBuffer(m_bitmap);
+ CDC MemDC;
+ CDC *pDc = GetDlgItem(IDC_STATIC_BITMAP)->GetDC(); //ID: picture
+ CRect rect;
+ ((CWnd *)GetDlgItem(IDC_STATIC_BITMAP))->GetWindowRect(rect);
+
+ MemDC.CreateCompatibleDC(pDc);
+ if((HBITMAP)winbmp != NULL)
+ winbmp.DeleteObject();
+ if(HBITMAP(winbmp) == NULL)
+ {
+ winbmp.CreateCompatibleBitmap(pDc,m_nWidth,m_nHeight);
+ winbmp.SetBitmapBits(bufsize,bmpbuf);
+ }
+
+ MemDC.SelectObject(&winbmp);
+
+ pDc->BitBlt(0 , 0 , rect.Width(), rect.Height(), &MemDC,0,0,SRCCOPY);
+ //pDc->StretchBlt(0,0,rect.right-rect.left,rect.bottom-rect.top,&MemDC,0,0,m_nWidth,m_nHeight,SRCCOPY);
+ MemDC.DeleteDC();
+ }
+ // Do not call CDialog::OnPaint() for painting messages
+}
diff --git a/xfa_test/FormFiller_Test/ExportPage.h b/xfa_test/FormFiller_Test/ExportPage.h
new file mode 100644
index 0000000000..1742991c76
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ExportPage.h
@@ -0,0 +1,59 @@
+#if !defined(AFX_EXPORTPAGE_H__D9B06547_96CA_4749_88CB_2506D8AF61D6__INCLUDED_)
+#define AFX_EXPORTPAGE_H__D9B06547_96CA_4749_88CB_2506D8AF61D6__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// ExportPage.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CExportPage dialog
+class CReaderVCView;
+
+class CExportPage : public CDialog
+{
+// Construction
+public:
+ CBitmap winbmp;
+ FPDF_BITMAP m_bitmap;
+ FPDF_PAGE m_page;
+ CReaderVCView *m_pView;
+ void SetDlgInfo();
+ void InitDialogInfo(CReaderVCView *pView);
+ CExportPage(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CExportPage)
+ enum { IDD = IDD_EXPORT_PAGE };
+ int m_nHeight;
+ int m_nPageHeight;
+ int m_nRotate;
+ int m_nWidth;
+ int m_nPageWidth;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CExportPage)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CExportPage)
+ afx_msg void OnRanderPage();
+ afx_msg void OnSave();
+ afx_msg void OnPaint();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_EXPORTPAGE_H__D9B06547_96CA_4749_88CB_2506D8AF61D6__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/FX_SplitterWnd.cpp b/xfa_test/FormFiller_Test/FX_SplitterWnd.cpp
new file mode 100644
index 0000000000..4024bb5c91
--- /dev/null
+++ b/xfa_test/FormFiller_Test/FX_SplitterWnd.cpp
@@ -0,0 +1,373 @@
+// FX_SplitterWnd.cpp: implementation of the CFX_SplitterWnd class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "stdafx.h"
+//#include "teststatusbar.h"
+#include "FX_SplitterWnd.h"
+
+#include <afxpriv.h>
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CFX_SplitterWnd::CFX_SplitterWnd()
+{
+ m_cxSplitter = m_cySplitter = 4 + 1 + 1;
+ m_cxBorderShare = m_cyBorderShare = 0;
+ m_cxSplitterGap = m_cySplitterGap = 4 + 1 + 1;
+ m_cxBorder = m_cyBorder = 1;
+ m_nHidedCol = -1;
+ m_bBarLocked = FALSE;
+}
+
+CFX_SplitterWnd::~CFX_SplitterWnd()
+{
+
+}
+
+BEGIN_MESSAGE_MAP(CFX_SplitterWnd, CSplitterWnd)
+ //{{AFX_MSG_MAP(CFX_SplitterWnd)
+ ON_WM_LBUTTONDOWN()
+ ON_WM_MOUSEMOVE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+void CFX_SplitterWnd::OnDrawSplitter(CDC *pDC,ESplitType nType,const CRect &rectArg)
+{
+ if((nType != splitBorder) || (pDC == NULL))
+ {
+ CSplitterWnd::OnDrawSplitter(pDC, nType, rectArg);
+ return;
+ }
+
+ pDC->Draw3dRect(rectArg, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
+}
+void CFX_SplitterWnd::RecalcLayout()
+{
+ ASSERT_VALID(this);
+ ASSERT(m_nRows > 0 && m_nCols > 0); // must have at least one pane
+
+ CRect rectClient;
+ GetClientRect(rectClient);
+ rectClient.InflateRect(-m_cxBorder, -m_cyBorder);
+
+ CRect rectInside;
+ GetInsideRect(rectInside);
+
+ // layout columns (restrict to possible sizes)
+ LayoutRowCol(m_pColInfo, m_nCols, rectInside.Width(), m_cxSplitterGap);
+ LayoutRowCol(m_pRowInfo, m_nRows, rectInside.Height(), m_cySplitterGap);
+
+ // adjust the panes (and optionally scroll bars)
+
+ // give the hint for the maximum number of HWNDs
+ AFX_SIZEPARENTPARAMS layout;
+ layout.hDWP = ::BeginDeferWindowPos((m_nCols + 1) * (m_nRows + 1) + 1);
+
+ // size of scrollbars
+ int cx = rectClient.right - rectInside.right;
+ int cy = rectClient.bottom - rectInside.bottom;
+
+ // reposition size box
+ if (m_bHasHScroll && m_bHasVScroll)
+ {
+ CWnd* pScrollBar = GetDlgItem(AFX_IDW_SIZE_BOX);
+ ASSERT(pScrollBar != NULL);
+
+ // fix style if necessary
+ BOOL bSizingParent = (GetSizingParent() != NULL);
+ // modifyStyle returns TRUE if style changes
+ if (pScrollBar->ModifyStyle(SBS_SIZEGRIP|SBS_SIZEBOX,
+ bSizingParent ? SBS_SIZEGRIP : SBS_SIZEBOX))
+ pScrollBar->Invalidate();
+ pScrollBar->EnableWindow(bSizingParent);
+
+ // reposition the size box
+ DeferClientPos(&layout, pScrollBar,
+ rectInside.right,
+ rectInside.bottom, cx, cy, TRUE);
+ }
+
+ // reposition scroll bars
+ if (m_bHasHScroll)
+ {
+ int cxSplitterBox = m_cxSplitter;// split box bigger
+ int x = rectClient.left;
+ int y = rectInside.bottom;
+ for (int col = 0; col < m_nCols; col++)
+ {
+ CWnd* pScrollBar = GetDlgItem(AFX_IDW_HSCROLL_FIRST + col);
+ ASSERT(pScrollBar != NULL);
+ int cx = m_pColInfo[col].nCurSize;
+ if (col == 0 && m_nCols < m_nMaxCols)
+ x += cxSplitterBox, cx -= cxSplitterBox;
+ DeferClientPos(&layout, pScrollBar, x, y, cx, cy, TRUE);
+ x += cx + m_cxSplitterGap;
+ }
+ }
+
+ if (m_bHasVScroll)
+ {
+ int cySplitterBox = m_cySplitter;// split box bigger
+ int x = rectInside.right;
+ int y = rectClient.top;
+ for (int row = 0; row < m_nRows; row++)
+ {
+ CWnd* pScrollBar = GetDlgItem(AFX_IDW_VSCROLL_FIRST + row);
+ ASSERT(pScrollBar != NULL);
+ int cy = m_pRowInfo[row].nCurSize;
+ if (row == 0 && m_nRows < m_nMaxRows)
+ y += cySplitterBox, cy -= cySplitterBox;
+ DeferClientPos(&layout, pScrollBar, x, y, cx, cy, TRUE);
+ y += cy + m_cySplitterGap;
+ }
+ }
+
+ //BLOCK: Reposition all the panes
+ {
+ int x = rectClient.left;
+ for (int col = 0; col < m_nCols; col++)
+ {
+ int cx = m_pColInfo[col].nCurSize;
+ int y = rectClient.top;
+ for (int row = 0; row < m_nRows; row++)
+ {
+ int cy = m_pRowInfo[row].nCurSize;
+ CWnd* pWnd = GetPane(row, col);
+ DeferClientPos(&layout, pWnd, x, y, cx, cy, FALSE);
+ y += cy + m_cySplitterGap;
+ }
+ x += cx + m_cxSplitterGap;
+ }
+ }
+
+ // move and resize all the windows at once!
+ if (layout.hDWP == NULL || !::EndDeferWindowPos(layout.hDWP))
+ TRACE0("Warning: DeferWindowPos failed - low system resources.\n");
+
+ // invalidate all the splitter bars (with NULL pDC)
+ DrawAllSplitBars(NULL, rectInside.right, rectInside.bottom);
+}
+
+void CFX_SplitterWnd::DeferClientPos(AFX_SIZEPARENTPARAMS *lpLayout,CWnd *pWnd,int x,int y,int cx,int cy,BOOL bScrollBar)
+{
+ ASSERT(pWnd != NULL);
+ ASSERT(pWnd->m_hWnd != NULL);
+
+ if (bScrollBar)
+ {
+ // if there is enough room, draw scroll bar without border
+ // if there is not enough room, set the WS_BORDER bit so that
+ // we will at least get a proper border drawn
+ BOOL bNeedBorder = (cx <= 1 || cy <= 1);
+ pWnd->ModifyStyle(bNeedBorder ? 0 : 1, bNeedBorder ? 1 : 0);
+ }
+ CRect rect(x, y, x+cx, y+cy);
+
+ // adjust for 3d border (splitter windows have implied border)
+ if ((pWnd->GetExStyle() & WS_EX_CLIENTEDGE) || pWnd->IsKindOf(RUNTIME_CLASS(CSplitterWnd)))
+ {
+ rect.InflateRect(1, 1); // for proper draw CFlatSplitterWnd in view
+// rect.InflateRect(afxData.cxBorder2, afxData.cyBorder2);
+ }
+
+ // first check if the new rectangle is the same as the current
+ CRect rectOld;
+ pWnd->GetWindowRect(rectOld);
+ pWnd->GetParent()->ScreenToClient(&rectOld);
+ if (rect != rectOld)
+ AfxRepositionWindow(lpLayout, pWnd->m_hWnd, rect);
+}
+
+void CFX_SplitterWnd::LayoutRowCol(CSplitterWnd::CRowColInfo *pInfoArray,int nMax,int nSize,int nSizeSplitter)
+{
+ ASSERT(pInfoArray != NULL);
+ ASSERT(nMax > 0);
+ ASSERT(nSizeSplitter > 0);
+
+ CSplitterWnd::CRowColInfo* pInfo;
+ int i;
+
+ if (nSize < 0)
+ nSize = 0; // if really too small, layout as zero size
+
+ // start with ideal sizes
+ for (i = 0, pInfo = pInfoArray; i < nMax-1; i++, pInfo++)
+ {
+ if (pInfo->nIdealSize < pInfo->nMinSize)
+ pInfo->nIdealSize = 0; // too small to see
+ pInfo->nCurSize = pInfo->nIdealSize;
+ }
+ pInfo->nCurSize = INT_MAX; // last row/column takes the rest
+
+ for (i = 0, pInfo = pInfoArray; i < nMax; i++, pInfo++)
+ {
+ ASSERT(nSize >= 0);
+ if (nSize == 0)
+ {
+ // no more room (set pane to be invisible)
+ pInfo->nCurSize = 0;
+ continue; // don't worry about splitters
+ }
+ else if (nSize < pInfo->nMinSize && i != 0)
+ {
+ // additional panes below the recommended minimum size
+ // aren't shown and the size goes to the previous pane
+ pInfo->nCurSize = 0;
+
+ // previous pane already has room for splitter + border
+ // add remaining size and remove the extra border
+ (pInfo-1)->nCurSize += nSize + 2;
+ nSize = 0;
+ }
+ else
+ {
+ // otherwise we can add the second pane
+ ASSERT(nSize > 0);
+ if (pInfo->nCurSize == 0)
+ {
+ // too small to see
+ if (i != 0)
+ pInfo->nCurSize = 0;
+ }
+ else if (nSize < pInfo->nCurSize)
+ {
+ // this row/col won't fit completely - make as small as possible
+ pInfo->nCurSize = nSize;
+ nSize = 0;
+ }
+ else
+ {
+ // can fit everything
+ nSize -= pInfo->nCurSize;
+ }
+ }
+
+ // see if we should add a splitter
+ ASSERT(nSize >= 0);
+ if (i != nMax - 1)
+ {
+ // should have a splitter
+ if (nSize > nSizeSplitter)
+ {
+ nSize -= nSizeSplitter; // leave room for splitter + border
+ ASSERT(nSize > 0);
+ }
+ else
+ {
+ // not enough room - add left over less splitter size
+ pInfo->nCurSize += nSize;
+ if (pInfo->nCurSize > (nSizeSplitter - 2))
+ pInfo->nCurSize -= (nSizeSplitter - 2);
+ nSize = 0;
+ }
+ }
+ }
+ ASSERT(nSize == 0); // all space should be allocated
+}
+
+void CFX_SplitterWnd::HideColumn(int nCol)
+{
+ if ( m_nHidedCol != -1 )
+ return;
+
+ ASSERT_VALID(this);
+ ASSERT(m_nCols > 1);
+ ASSERT(nCol < m_nCols);
+ ASSERT(m_nHidedCol == -1);
+ m_nHidedCol = nCol;
+
+ // if the column has an active window -- change it
+ int rowActive, colActive;
+ if (GetActivePane(&rowActive, &colActive) != NULL &&
+ colActive == nCol)
+ {
+ if (++colActive >= m_nCols)
+ colActive = 0;
+ SetActivePane(rowActive, colActive);
+ }
+
+ // hide all column panes
+ for (int row = 0; row < m_nRows; row++)
+ {
+ CWnd* pPaneHide = GetPane(row, nCol);
+ ASSERT(pPaneHide != NULL);
+ pPaneHide->ShowWindow(SW_HIDE);
+ pPaneHide->SetDlgCtrlID(
+ AFX_IDW_PANE_FIRST + row * 16 + m_nCols);
+
+ for (int col = nCol + 1; col < m_nCols; col++)
+ {
+ CWnd* pPane = GetPane(row, col);
+ ASSERT(pPane != NULL);
+ pPane->SetDlgCtrlID(IdFromRowCol(row, col - 1));
+ }
+ }
+ m_nCols--;
+ m_pColInfo[m_nCols].nCurSize = m_pColInfo[nCol].nCurSize;
+ RecalcLayout();
+}
+
+void CFX_SplitterWnd::ShowColumn()
+{
+ if ( m_nHidedCol == -1 )
+ return;
+
+ ASSERT_VALID(this);
+ ASSERT(m_nCols < m_nMaxCols);
+ ASSERT(m_nHidedCol != -1);
+
+ int colNew = m_nHidedCol;
+ m_nHidedCol = -1;
+ int cxNew = m_pColInfo[m_nCols].nCurSize;
+ m_nCols++; // add a column
+ ASSERT(m_nCols == m_nMaxCols);
+
+ // fill the hided column
+ int col;
+ for (int row = 0; row < m_nRows; row++)
+ {
+ CWnd* pPaneShow = GetDlgItem(
+ AFX_IDW_PANE_FIRST + row * 16 + m_nCols);
+ ASSERT(pPaneShow != NULL);
+ pPaneShow->ShowWindow(SW_SHOWNA);
+
+ for (col = m_nCols - 2; col >= colNew; col--)
+ {
+ CWnd* pPane = GetPane(row, col);
+ ASSERT(pPane != NULL);
+ pPane->SetDlgCtrlID(IdFromRowCol(row, col + 1));
+ }
+
+ pPaneShow->SetDlgCtrlID(IdFromRowCol(row, colNew));
+ }
+
+ // new panes have been created -- recalculate layout
+ for (col = colNew + 1; col < m_nCols; col++)
+ m_pColInfo[col].nIdealSize = m_pColInfo[col - 1].nCurSize;
+ m_pColInfo[colNew].nIdealSize = cxNew;
+
+ RecalcLayout();
+}
+
+void CFX_SplitterWnd::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ if (!m_bBarLocked)
+ CSplitterWnd::OnLButtonDown(nFlags, point);
+}
+
+void CFX_SplitterWnd::OnMouseMove(UINT nFlags, CPoint point)
+{
+ if (!m_bBarLocked)
+ CSplitterWnd::OnMouseMove(nFlags, point);
+ else
+ CWnd::OnMouseMove(nFlags, point);
+}
diff --git a/xfa_test/FormFiller_Test/FX_SplitterWnd.h b/xfa_test/FormFiller_Test/FX_SplitterWnd.h
new file mode 100644
index 0000000000..94893c9719
--- /dev/null
+++ b/xfa_test/FormFiller_Test/FX_SplitterWnd.h
@@ -0,0 +1,44 @@
+// FX_SplitterWnd.h: interface for the CFX_SplitterWnd class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_FX_SPLITTERWND_H__4BF45CD9_0C9D_4223_9D0E_9ECA148F49FB__INCLUDED_)
+#define AFX_FX_SPLITTERWND_H__4BF45CD9_0C9D_4223_9D0E_9ECA148F49FB__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+class CFX_SplitterWnd : public CSplitterWnd
+{
+public:
+ CFX_SplitterWnd();
+ virtual ~CFX_SplitterWnd();
+
+public:
+ virtual void OnDrawSplitter(CDC *pDC,ESplitType nType,const CRect &rectArg);
+ virtual void RecalcLayout();
+ static void DeferClientPos(AFX_SIZEPARENTPARAMS *lpLayout,CWnd *pWnd,int x,int y,int cx,int cy,BOOL bScrollBar);
+ static void LayoutRowCol(CSplitterWnd::CRowColInfo *pInfoArray,int nMax,int nSize,int nSizeSplitter);
+ void LockBar(BOOL bState=TRUE){m_bBarLocked=bState;}
+ void HideColumn(int nCol);
+ void ShowColumn();
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CFX_SplitterWnd)
+ //}}AFX_VIRTUAL
+
+ // Generated message map functions
+protected:
+ //{{AFX_MSG(CFX_SplitterWnd)
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+protected:
+ BOOL m_bBarLocked;
+ int m_nHidedCol;
+
+};
+
+#endif // !defined(AFX_FX_SPLITTERWND_H__4BF45CD9_0C9D_4223_9D0E_9ECA148F49FB__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/FindDlg.cpp b/xfa_test/FormFiller_Test/FindDlg.cpp
new file mode 100644
index 0000000000..88548d991f
--- /dev/null
+++ b/xfa_test/FormFiller_Test/FindDlg.cpp
@@ -0,0 +1,73 @@
+// FindDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+#include "FindDlg.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CFindDlg dialog
+
+
+CFindDlg::CFindDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CFindDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CFindDlg)
+ m_bMatchCase = FALSE;
+ m_bWholeWord = FALSE;
+ m_strFindWhat = _T("");
+ m_nDirection = -1;
+ //}}AFX_DATA_INIT
+}
+
+
+void CFindDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CFindDlg)
+ DDX_Check(pDX, IDC_CHECK_MATCHCASE, m_bMatchCase);
+ DDX_Check(pDX, IDC_CHECK_MATCHWHOLE, m_bWholeWord);
+ DDX_Text(pDX, IDC_EDIT1, m_strFindWhat);
+ DDX_Radio(pDX, IDC_RADIO_Down, m_nDirection);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CFindDlg, CDialog)
+ //{{AFX_MSG_MAP(CFindDlg)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CFindDlg message handlers
+
+void CFindDlg::OnOK()
+{
+ // TODO: Add extra validation here
+ UpdateData(TRUE);
+ m_pView->FindText(m_strFindWhat, m_bMatchCase, m_bWholeWord, m_nDirection);
+ //CDialog::OnOK();
+}
+
+BOOL CFindDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // TODO: Add extra initialization here
+ m_pView = (CReaderVCView *)(((CChildFrame *)((CMainFrame *)AfxGetMainWnd())->GetActiveFrame())->GetActiveView());
+ ASSERT(m_pView);
+ ((CButton *)GetDlgItem(IDC_RADIO_Down))->SetCheck(1);
+ ((CButton *)GetDlgItem(IDC_CHECK_MATCHWHOLE))->SetCheck(1);
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
diff --git a/xfa_test/FormFiller_Test/FindDlg.h b/xfa_test/FormFiller_Test/FindDlg.h
new file mode 100644
index 0000000000..18ef88dc96
--- /dev/null
+++ b/xfa_test/FormFiller_Test/FindDlg.h
@@ -0,0 +1,50 @@
+#if !defined(AFX_FINDDLG_H__355AF96B_B487_4503_8658_7F37B397D38A__INCLUDED_)
+#define AFX_FINDDLG_H__355AF96B_B487_4503_8658_7F37B397D38A__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// FindDlg.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CFindDlg dialog
+class CReaderVCView;
+class CFindDlg : public CDialog
+{
+// Construction
+public:
+ CFindDlg(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CFindDlg)
+ enum { IDD = IDD_DLG_FIND };
+ BOOL m_bMatchCase;
+ BOOL m_bWholeWord;
+ CString m_strFindWhat;
+ int m_nDirection;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CFindDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ CReaderVCView *m_pView;
+ // Generated message map functions
+ //{{AFX_MSG(CFindDlg)
+ virtual void OnOK();
+ virtual BOOL OnInitDialog();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_FINDDLG_H__355AF96B_B487_4503_8658_7F37B397D38A__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/GotoPageDlg.cpp b/xfa_test/FormFiller_Test/GotoPageDlg.cpp
new file mode 100644
index 0000000000..5c189c8c52
--- /dev/null
+++ b/xfa_test/FormFiller_Test/GotoPageDlg.cpp
@@ -0,0 +1,65 @@
+// GotoPageDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+#include "GotoPageDlg.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CGotoPageDlg dialog
+
+
+CGotoPageDlg::CGotoPageDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CGotoPageDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CGotoPageDlg)
+ m_nPageIndex = 0;
+ //}}AFX_DATA_INIT
+}
+
+
+void CGotoPageDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CGotoPageDlg)
+ DDX_Text(pDX, IDC_EDIT1, m_nPageIndex);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CGotoPageDlg, CDialog)
+ //{{AFX_MSG_MAP(CGotoPageDlg)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CGotoPageDlg message handlers
+
+void CGotoPageDlg::OnOK()
+{
+ // TODO: Add extra validation here
+ if (NULL == m_pView) return;
+ UpdateData(TRUE);
+ m_pView->GotoPage(m_nPageIndex);
+ CDialog::OnOK();
+}
+
+BOOL CGotoPageDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // TODO: Add extra initialization here
+ m_pView = (CReaderVCView *)(((CChildFrame *)((CMainFrame *)AfxGetMainWnd())->GetActiveFrame())->GetActiveView());
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
diff --git a/xfa_test/FormFiller_Test/GotoPageDlg.h b/xfa_test/FormFiller_Test/GotoPageDlg.h
new file mode 100644
index 0000000000..40f6bea1c2
--- /dev/null
+++ b/xfa_test/FormFiller_Test/GotoPageDlg.h
@@ -0,0 +1,48 @@
+#if !defined(AFX_GOTOPAGEDLG_H__674C0708_4B25_4465_A73F_310610F9B991__INCLUDED_)
+#define AFX_GOTOPAGEDLG_H__674C0708_4B25_4465_A73F_310610F9B991__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// GotoPageDlg.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CGotoPageDlg dialog
+class CReaderVCView;
+class CGotoPageDlg : public CDialog
+{
+// Construction
+public:
+ CGotoPageDlg(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CGotoPageDlg)
+ enum { IDD = IDD_DLG_GOTOPAGE };
+ int m_nPageIndex;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CGotoPageDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+private:
+ CReaderVCView *m_pView;
+// Implementation
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CGotoPageDlg)
+ virtual void OnOK();
+ virtual BOOL OnInitDialog();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GOTOPAGEDLG_H__674C0708_4B25_4465_A73F_310610F9B991__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/JS_ResponseDlg.cpp b/xfa_test/FormFiller_Test/JS_ResponseDlg.cpp
new file mode 100644
index 0000000000..043efc24c4
--- /dev/null
+++ b/xfa_test/FormFiller_Test/JS_ResponseDlg.cpp
@@ -0,0 +1,152 @@
+// JS_ResponseDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "readervc.h"
+#include "JS_ResponseDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CJS_ResponseDlg dialog
+
+
+CJS_ResponseDlg::CJS_ResponseDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CJS_ResponseDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CJS_ResponseDlg)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+ m_swTitle =(FPDF_WIDESTRING) L"";
+ m_swQuestion =(FPDF_WIDESTRING) L"";
+ m_swLabel =(FPDF_WIDESTRING) L"";
+ m_swDefault =(FPDF_WIDESTRING) L"";
+ m_swResponse =L"";
+ m_bIsVisible = false;
+ m_pResponseEdit = NULL;
+}
+
+
+void CJS_ResponseDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CJS_ResponseDlg)
+ // NOTE: the ClassWizard will add DDX and DDV calls here
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CJS_ResponseDlg, CDialog)
+ //{{AFX_MSG_MAP(CJS_ResponseDlg)
+ // NOTE: the ClassWizard will add message map macros here
+ ON_BN_CLICKED(ID_JS_OK, OnResOk)
+ ON_BN_CLICKED(ID_JS_CANCEL, OnResCancel)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CJS_ResponseDlg message handlers
+BOOL CJS_ResponseDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ ::SetWindowTextW(this->GetSafeHwnd(), (LPCWSTR)m_swTitle);
+
+ CStatic* pQuestion = (CStatic*)GetDlgItem(IDC_JS_QUESTION);
+ ::SetWindowTextW(pQuestion->GetSafeHwnd(), (LPCWSTR)m_swQuestion);
+
+ CStatic* pLabel = (CStatic*)GetDlgItem(IDC_JS_ANSWER);
+
+ CRect DialogRect;
+ CRect LabelRect;
+ RECT rect;
+ GetWindowRect(&DialogRect);
+ pLabel->GetWindowRect(&LabelRect);
+
+ if(m_swLabel == (FPDF_WIDESTRING)L"")
+ {
+ rect.left = DialogRect.left + 20;
+ pLabel->ShowWindow(SW_HIDE);
+ }
+ else
+ {
+ rect.left = LabelRect.right + 1;
+ ::SetWindowTextW(pLabel->GetSafeHwnd(), (LPCWSTR)m_swLabel);
+ }
+
+ rect.top = LabelRect.top - 3;
+ rect.right = DialogRect.right - 20;
+ rect.bottom = LabelRect.bottom + 2;
+ ScreenToClient(&rect);
+ m_pResponseEdit = new CEdit();
+
+ if(m_bIsVisible)
+ m_pResponseEdit->Create(ES_AUTOVSCROLL | ES_NOHIDESEL | ES_PASSWORD | WS_BORDER, rect, this, IDC_JS_EDIT);
+ else
+ m_pResponseEdit->Create(ES_AUTOVSCROLL | ES_NOHIDESEL | WS_BORDER, rect, this, IDC_JS_EDIT);
+
+ ::SetWindowTextW(m_pResponseEdit->GetSafeHwnd(), (LPCWSTR)m_swDefault);
+ m_pResponseEdit->ShowWindow(SW_SHOW);
+
+ return TRUE;
+}
+
+void CJS_ResponseDlg::OnResOk()
+{
+ m_swResponse = (wchar_t*)malloc(sizeof(wchar_t) * 250);
+ ::GetWindowTextW(m_pResponseEdit->GetSafeHwnd(), m_swResponse, 250);
+
+ if(m_pResponseEdit)
+ {
+ m_pResponseEdit->DestroyWindow();
+ delete m_pResponseEdit;
+ m_pResponseEdit = NULL;
+ }
+ CDialog::OnOK();
+}
+
+void CJS_ResponseDlg::OnResCancel()
+{
+ if(m_pResponseEdit)
+ {
+ m_pResponseEdit->DestroyWindow();
+ delete m_pResponseEdit;
+ m_pResponseEdit = NULL;
+ }
+
+ CDialog::OnCancel();
+}
+
+void CJS_ResponseDlg::SetTitle(FPDF_WIDESTRING swTitle)
+{
+ m_swTitle = swTitle;
+}
+
+void CJS_ResponseDlg::SetQuestion(FPDF_WIDESTRING swQuestion)
+{
+ m_swQuestion = swQuestion;
+}
+
+void CJS_ResponseDlg::SetLabel(FPDF_WIDESTRING swLabel)
+{
+ m_swLabel = swLabel;
+}
+
+void CJS_ResponseDlg::SetDefault(FPDF_WIDESTRING swDefault)
+{
+ m_swDefault = swDefault;
+}
+
+FPDF_WIDESTRING CJS_ResponseDlg::GetResponse()
+{
+ return (FPDF_WIDESTRING)m_swResponse;
+}
+
+void CJS_ResponseDlg::SetIsVisible(FPDF_BOOL bPassword)
+{
+ m_bIsVisible = bPassword;
+}
diff --git a/xfa_test/FormFiller_Test/JS_ResponseDlg.h b/xfa_test/FormFiller_Test/JS_ResponseDlg.h
new file mode 100644
index 0000000000..c3410c49bc
--- /dev/null
+++ b/xfa_test/FormFiller_Test/JS_ResponseDlg.h
@@ -0,0 +1,64 @@
+#if !defined(AFX_JS_RESPONSEDLG_H__AE1575EB_3F0A_46E7_B278_089C74F2B34C__INCLUDED_)
+#define AFX_JS_RESPONSEDLG_H__AE1575EB_3F0A_46E7_B278_089C74F2B34C__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// JS_ResponseDlg.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CJS_ResponseDlg dialog
+
+class CJS_ResponseDlg : public CDialog
+{
+// Construction
+public:
+ CJS_ResponseDlg(CWnd* pParent = NULL); // standard constructor
+ ~CJS_ResponseDlg(){ if(m_swResponse) free(m_swResponse); }
+
+// Dialog Data
+ //{{AFX_DATA(CJS_ResponseDlg)
+ enum { IDD = IDD_DLG_RESPONSE };
+ // NOTE: the ClassWizard will add data members here
+ //}}AFX_DATA
+public:
+ void SetTitle(FPDF_WIDESTRING swTitle);
+ void SetQuestion(FPDF_WIDESTRING swQuestion);
+ void SetDefault(FPDF_WIDESTRING swDefault);
+ void SetLabel(FPDF_WIDESTRING swLabel);
+ void SetIsVisible(FPDF_BOOL bPassword);
+ FPDF_WIDESTRING GetResponse();
+
+private:
+ FPDF_WIDESTRING m_swTitle;
+ FPDF_WIDESTRING m_swQuestion;
+ FPDF_WIDESTRING m_swDefault;
+ FPDF_WIDESTRING m_swLabel;
+ wchar_t* m_swResponse;
+ FPDF_BOOL m_bIsVisible;
+ CEdit* m_pResponseEdit;
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CJS_ResponseDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+ // Generated message map functions
+ //{{AFX_MSG(CJS_ResponseDlg)
+ // NOTE: the ClassWizard will add member functions here
+ virtual BOOL OnInitDialog();
+ afx_msg void OnResOk();
+ afx_msg void OnResCancel();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_JS_RESPONSEDLG_H__AE1575EB_3F0A_46E7_B278_089C74F2B34C__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/MainFrm.cpp b/xfa_test/FormFiller_Test/MainFrm.cpp
new file mode 100644
index 0000000000..b6e59439b6
--- /dev/null
+++ b/xfa_test/FormFiller_Test/MainFrm.cpp
@@ -0,0 +1,238 @@
+// MainFrm.cpp : implementation of the CMainFrame class
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+
+#include "MainFrm.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame
+
+IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)
+
+BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
+ //{{AFX_MSG_MAP(CMainFrame)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ ON_WM_CREATE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+static UINT indicators[] =
+{
+ ID_SEPARATOR, // status line indicator
+ ID_INDICATOR_CAPS,
+ ID_INDICATOR_NUM,
+ ID_INDICATOR_SCRL,
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame construction/destruction
+
+CMainFrame::CMainFrame()
+{
+ // TODO: add member initialization code here
+
+}
+
+CMainFrame::~CMainFrame()
+{
+}
+
+int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
+{
+ if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
+ return -1;
+
+ if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
+ | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
+ !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
+ {
+ TRACE0("Failed to create toolbar\n");
+ return -1; // fail to create
+ }
+
+ if (!m_wndStatusBar.Create(this) ||
+ !m_wndStatusBar.SetIndicators(indicators,
+ sizeof(indicators)/sizeof(UINT)))
+ {
+ TRACE0("Failed to create status bar\n");
+ return -1; // fail to create
+ }
+
+ // TODO: Delete these three lines if you don't want the toolbar to
+ // be dockable
+
+ m_wndToolBar.ModifyStyle(0,TBSTYLE_FLAT | CBRS_TOOLTIPS | TBSTYLE_TRANSPARENT | TBBS_CHECKBOX);
+ m_wndToolBar.GetToolBarCtrl().SetButtonWidth(40,40);
+
+ CImageList ImgList,ImgList1;
+ CBitmap bm;
+ ImgList.Create(22,22,ILC_COLOR8|ILC_MASK, 16, 16);
+ ImgList.SetBkColor(::GetSysColor(15));
+ bm.LoadBitmap(IDB_BITMAP23);//OPEN
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP35);//Print
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP17);//first page
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP24);//prev page
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP22);//next page
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP21);//last page
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP16);//count clockwise
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP15);//clockwise
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP14);//zoom in
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP26);//zoom out
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP13);//actual size
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP18);//fit page
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP19);//fit width
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP36);//search
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP7);//Bookmark
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP25);//snap shot
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP2);//select text
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP20);//hand tool
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP12);//about
+ ImgList.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ m_wndToolBar.GetToolBarCtrl().SetImageList(&ImgList);
+ //m_wndToolBar.GetToolBarCtrl().SetHotImageList(&ImgList);
+ ImgList.Detach();
+
+ ImgList1.Create(22,22,ILC_COLOR8|ILC_MASK, 16, 16);
+ ImgList1.SetBkColor(::GetSysColor(15));
+ bm.LoadBitmap(IDB_BITMAP23);//open
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP30);//printer
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP8);//first page
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP29);//prev page
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP28);//next page
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP27);//last page
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP1);//count clockwise
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP6);//clockwise
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP33);//zoom in
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP34);//zoom out
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP4);//actual size
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP9);//fit page
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP10);//fit width
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP31);//search
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP5);//bookmark
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP32);//snap
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP3);//select text
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP11);//hand tool
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ bm.LoadBitmap(IDB_BITMAP12);//about
+ ImgList1.Add(&bm,RGB(0,255,0));
+ bm.Detach();
+ m_wndToolBar.GetToolBarCtrl().SetDisabledImageList(&ImgList1);
+ ImgList1.Detach();
+
+ m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
+ EnableDocking(CBRS_ALIGN_ANY);
+ DockControlBar(&m_wndToolBar);
+
+ return 0;
+}
+
+BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
+{
+ if( !CMDIFrameWnd::PreCreateWindow(cs) )
+ return FALSE;
+ // TODO: Modify the Window class or styles here by modifying
+ // the CREATESTRUCT cs
+
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame diagnostics
+
+#ifdef _DEBUG
+void CMainFrame::AssertValid() const
+{
+ CMDIFrameWnd::AssertValid();
+}
+
+void CMainFrame::Dump(CDumpContext& dc) const
+{
+ CMDIFrameWnd::Dump(dc);
+}
+
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CMainFrame message handlers
+
diff --git a/xfa_test/FormFiller_Test/MainFrm.h b/xfa_test/FormFiller_Test/MainFrm.h
new file mode 100644
index 0000000000..1b9f128fba
--- /dev/null
+++ b/xfa_test/FormFiller_Test/MainFrm.h
@@ -0,0 +1,56 @@
+// MainFrm.h : interface of the CMainFrame class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_MAINFRM_H__B05284F9_FD96_49A9_B8B2_F77706A9A02B__INCLUDED_)
+#define AFX_MAINFRM_H__B05284F9_FD96_49A9_B8B2_F77706A9A02B__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+class CMainFrame : public CMDIFrameWnd
+{
+ DECLARE_DYNAMIC(CMainFrame)
+public:
+ CMainFrame();
+
+// Attributes
+public:
+ CStatusBar m_wndStatusBar;
+ CToolBar m_wndToolBar;
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CMainFrame)
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ virtual ~CMainFrame();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected: // control bar embedded members
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CMainFrame)
+ afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MAINFRM_H__B05284F9_FD96_49A9_B8B2_F77706A9A02B__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/ReaderVC.cpp b/xfa_test/FormFiller_Test/ReaderVC.cpp
new file mode 100644
index 0000000000..2d58c25062
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVC.cpp
@@ -0,0 +1,195 @@
+// ReaderVC.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCDoc.h"
+#include "ReaderVCView.h"
+#include "BookmarkView.h"
+
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCApp
+
+BEGIN_MESSAGE_MAP(CReaderVCApp, CWinApp)
+ //{{AFX_MSG_MAP(CReaderVCApp)
+ ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG_MAP
+ // Standard file based document commands
+ ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
+ ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
+ // Standard print setup command
+ ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCApp construction
+
+
+CReaderVCApp::CReaderVCApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+
+
+
+ m_pActiveView = NULL;
+
+
+
+// FPDF_InitFormFillEnviroument(this);
+}
+
+CReaderVCApp::~CReaderVCApp()
+{
+
+
+
+}
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CReaderVCApp object
+
+CReaderVCApp theApp;
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCApp initialization
+extern void SetSampleFontInfo();
+BOOL CReaderVCApp::InitInstance()
+{
+ AfxEnableControlContainer();
+ FPDF_InitLibrary(this->m_hInstance);
+// FPDF_UnlockDLL("SDKRDYX0408","5E5885A8AD61A855485D9F6C85BE82EF7C1F63AC");
+
+ SetSampleFontInfo();
+ // Standard initialization
+ // If you are not using these features and wish to reduce the size
+ // of your final executable, you should remove from the following
+ // the specific initialization routines you do not need.
+
+#ifdef _AFXDLL
+ Enable3dControls(); // Call this when using MFC in a shared DLL
+#else
+ Enable3dControlsStatic(); // Call this when linking to MFC statically
+#endif
+
+ // Change the registry key under which our settings are stored.
+ // TODO: You should modify this string to be something appropriate
+ // such as the name of your company or organization.
+ SetRegistryKey(_T("Local AppWizard-Generated Applications"));
+
+ LoadStdProfileSettings(); // Load standard INI file options (including MRU)
+
+ // Register the application's document templates. Document templates
+ // serve as the connection between documents, frame windows and views.
+
+ CMultiDocTemplate* pDocTemplate;
+ pDocTemplate = new CMultiDocTemplate(
+ IDR_READERTYPE,
+ RUNTIME_CLASS(CReaderVCDoc),
+ RUNTIME_CLASS(CChildFrame), // custom MDI child frame
+ RUNTIME_CLASS(CReaderVCView));
+ AddDocTemplate(pDocTemplate);
+
+ CMultiDocTemplate* pDocTemplate1;
+ pDocTemplate1 = new CMultiDocTemplate(
+ IDR_READERTYPE,
+ RUNTIME_CLASS(CReaderVCDoc),
+ RUNTIME_CLASS(CChildFrame), // custom MDI child frame
+ RUNTIME_CLASS(CBookMarkView));
+ AddDocTemplate(pDocTemplate1);
+ // create main MDI Frame window
+ CMainFrame* pMainFrame = new CMainFrame;
+ if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
+ return FALSE;
+ m_pMainWnd = pMainFrame;
+ // Parse command line for standard shell commands, DDE, file open
+ CCommandLineInfo cmdInfo;
+ cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
+ ParseCommandLine(cmdInfo);
+
+ // Dispatch commands specified on the command line
+ if (!ProcessShellCommand(cmdInfo))
+ return FALSE;
+
+ // The main window has been initialized, so show and update it.
+ pMainFrame->ShowWindow(SW_SHOWMAXIMIZED);
+ pMainFrame->UpdateWindow();
+ return TRUE;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CAboutDlg dialog used for App About
+
+class CAboutDlg : public CDialog
+{
+public:
+ CAboutDlg();
+
+// Dialog Data
+ //{{AFX_DATA(CAboutDlg)
+ enum { IDD = IDD_ABOUTBOX };
+ //}}AFX_DATA
+
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CAboutDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ //{{AFX_MSG(CAboutDlg)
+ afx_msg void OnMetalfile();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
+{
+ //{{AFX_DATA_INIT(CAboutDlg)
+ //}}AFX_DATA_INIT
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CAboutDlg)
+ //}}AFX_DATA_MAP
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
+ //{{AFX_MSG_MAP(CAboutDlg)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+// App command to run the dialog
+void CReaderVCApp::OnAppAbout()
+{
+ CAboutDlg aboutDlg;
+ aboutDlg.DoModal();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCApp message handlers
+
+
+int CReaderVCApp::ExitInstance()
+{
+ // TODO: Add your specialized code here and/or call the base class
+ FPDF_DestroyLibrary();
+
+ return CWinApp::ExitInstance();
+}
diff --git a/xfa_test/FormFiller_Test/ReaderVC.dsp b/xfa_test/FormFiller_Test/ReaderVC.dsp
new file mode 100644
index 0000000000..8d95e07d81
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVC.dsp
@@ -0,0 +1,460 @@
+# Microsoft Developer Studio Project File - Name="ReaderVC" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Application" 0x0101
+
+CFG=ReaderVC - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "ReaderVC.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "ReaderVC.mak" CFG="ReaderVC - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "ReaderVC - Win32 Release" (based on "Win32 (x86) Application")
+!MESSAGE "ReaderVC - Win32 Debug" (based on "Win32 (x86) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "ReaderVC - Win32 Release"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "FPDFSDK_EXPORTS" /FR /Yu"stdafx.h" /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x804 /d "NDEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x804 /d "NDEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
+# ADD LINK32 /nologo /subsystem:windows /machine:I386 /out:"../../lib/rel_w32_vc6/ReaderVC.exe"
+
+!ELSEIF "$(CFG)" == "ReaderVC - Win32 Debug"
+
+# PROP BASE Use_MFC 6
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 6
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "FPDFSDK_EXPORTS" /FR /Yu"stdafx.h" /FD /GZ /c
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x804 /d "_DEBUG" /d "_AFXDLL"
+# ADD RSC /l 0x804 /d "_DEBUG" /d "_AFXDLL"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 Msimg32.lib /nologo /subsystem:windows /map /debug /machine:I386 /out:"../../lib/dbg_w32_vc6/ReaderVC.exe" /pdbtype:sept
+
+!ENDIF
+
+# Begin Target
+
+# Name "ReaderVC - Win32 Release"
+# Name "ReaderVC - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\BookMarkView.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChildFrm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConvertDlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExportPage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FindDlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FX_SplitterWnd.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\GotoPageDlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\JS_ResponseDlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\MainFrm.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReaderVC.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReaderVC.rc
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReaderVCDoc.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReaderVCView.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.cpp
+# ADD CPP /Yc"stdafx.h"
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestJsDlg.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZoomDlg.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\BookMarkView.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ChildFrm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ConvertDlg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ExportPage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FindDlg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\FX_SplitterWnd.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\GotoPageDlg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\JS_ResponseDlg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\MainFrm.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReaderVC.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReaderVCDoc.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ReaderVCView.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\Resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\StdAfx.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\TestJsDlg.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\ZoomDlg.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\res\BigHandCursor.cur
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap1.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap12.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap19.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap20.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap21.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap22.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap23.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bitmap26.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bookmark.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\bound.cur
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\formOptions.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\point.cur
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Rd_SelText_Icon.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Rd_SelText_Icon_Dis.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\ReaderVC.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\ReaderVC.rc2
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\ReaderVCDoc.ico
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\SmallHandCursor.cur
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_actual_size.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_bookmark1.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_clockwise.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_counterclockwise.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_first.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_fit_page.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_fit_width.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hand1.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_about2.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_actual_size.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_bookmark1.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_clockwise.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_counterclockwise.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_first.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_fit_page.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_fit_width.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_hand1.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_last.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_next.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_open1.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_prev.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_print.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_search.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_snap_shot.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_zoomin.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_hot_zoomout.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_last.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_next.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_prev.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_print.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_search.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_snap_shot.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_zoomin.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\tool_zoomout.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\Toolbar.bmp
+# End Source File
+# Begin Source File
+
+SOURCE=.\res\unknowncolor_gray.bmp
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\ReadMe.txt
+# End Source File
+# End Target
+# End Project
diff --git a/xfa_test/FormFiller_Test/ReaderVC.h b/xfa_test/FormFiller_Test/ReaderVC.h
new file mode 100644
index 0000000000..11bcc4354f
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVC.h
@@ -0,0 +1,54 @@
+// ReaderVC.h : main header file for the READERVC application
+//
+
+#if !defined(AFX_READERVC_H__7873A15F_A60F_4C05_9DC6_C3914C224EAA__INCLUDED_)
+#define AFX_READERVC_H__7873A15F_A60F_4C05_9DC6_C3914C224EAA__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#ifndef __AFXWIN_H__
+ #error include 'stdafx.h' before including this file for PCH
+#endif
+
+class CReaderVCView;
+
+#include "resource.h" // main symbols
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCApp:
+// See ReaderVC.cpp for the implementation of this class
+//
+
+class CReaderVCApp : public CWinApp
+{
+public:
+ CReaderVCApp();
+ ~CReaderVCApp();
+ CReaderVCView * m_pActiveView;
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CReaderVCApp)
+ public:
+ virtual BOOL InitInstance();
+ virtual int ExitInstance();
+ //}}AFX_VIRTUAL
+
+// Implementation
+ //{{AFX_MSG(CReaderVCApp)
+ afx_msg void OnAppAbout();
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_READERVC_H__7873A15F_A60F_4C05_9DC6_C3914C224EAA__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/ReaderVC.rc b/xfa_test/FormFiller_Test/ReaderVC.rc
new file mode 100644
index 0000000000..bf647aefb6
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVC.rc
@@ -0,0 +1,741 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Chinese (P.R.C.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+#ifdef _WIN32
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+#pragma code_page(936)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
+ "#define _AFX_NO_OLE_RESOURCES\r\n"
+ "#define _AFX_NO_TRACKER_RESOURCES\r\n"
+ "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
+ "\r\n"
+ "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
+ "#ifdef _WIN32\r\n"
+ "LANGUAGE 4, 2\r\n"
+ "#pragma code_page(936)\r\n"
+ "#endif //_WIN32\r\n"
+ "#include ""res\\ReaderVC.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
+ "#include ""l.chs\\afxres.rc"" // Standard components\r\n"
+ "#include ""l.chs\\afxprint.rc"" // printing/print preview resources\r\n"
+ "#endif\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDR_MAINFRAME ICON DISCARDABLE "res\\ReaderVC.ico"
+IDR_READERTYPE ICON DISCARDABLE "res\\ReaderVCDoc.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDR_MAINFRAME BITMAP MOVEABLE PURE "res\\Toolbar.bmp"
+IDB_BITMAP1 BITMAP DISCARDABLE "res\\tool_counterclockwise.bmp"
+IDB_BITMAP2 BITMAP DISCARDABLE "res\\Rd_SelText_Icon.bmp"
+IDB_BITMAP3 BITMAP DISCARDABLE "res\\Rd_SelText_Icon_Dis.bmp"
+IDB_BITMAP4 BITMAP DISCARDABLE "res\\tool_actual_size.bmp"
+IDB_BITMAP5 BITMAP DISCARDABLE "res\\tool_bookmark1.bmp"
+IDB_BITMAP6 BITMAP DISCARDABLE "res\\tool_clockwise.bmp"
+IDB_BITMAP7 BITMAP DISCARDABLE "res\\tool_hot_bookmark1.bmp"
+IDB_BITMAP8 BITMAP DISCARDABLE "res\\tool_first.bmp"
+IDB_BITMAP9 BITMAP DISCARDABLE "res\\tool_fit_page.bmp"
+IDB_BITMAP10 BITMAP DISCARDABLE "res\\tool_fit_width.bmp"
+IDB_BITMAP11 BITMAP DISCARDABLE "res\\tool_hand1.bmp"
+IDB_BITMAP12 BITMAP DISCARDABLE "res\\tool_hot_about2.bmp"
+IDB_BITMAP13 BITMAP DISCARDABLE "res\\tool_hot_actual_size.bmp"
+IDB_BITMAP14 BITMAP DISCARDABLE "res\\tool_hot_zoomin.bmp"
+IDB_BITMAP15 BITMAP DISCARDABLE "res\\tool_hot_clockwise.bmp"
+IDB_BITMAP16 BITMAP DISCARDABLE "res\\tool_hot_counterclockwise.bmp"
+IDB_BITMAP17 BITMAP DISCARDABLE "res\\tool_hot_first.bmp"
+IDB_BITMAP18 BITMAP DISCARDABLE "res\\tool_hot_fit_page.bmp"
+IDB_BITMAP19 BITMAP DISCARDABLE "res\\tool_hot_fit_width.bmp"
+IDB_BITMAP20 BITMAP DISCARDABLE "res\\tool_hot_hand1.bmp"
+IDB_BITMAP21 BITMAP DISCARDABLE "res\\tool_hot_last.bmp"
+IDB_BITMAP22 BITMAP DISCARDABLE "res\\tool_hot_next.bmp"
+IDB_BITMAP23 BITMAP DISCARDABLE "res\\tool_hot_open1.bmp"
+IDB_BITMAP24 BITMAP DISCARDABLE "res\\tool_hot_prev.bmp"
+IDB_BITMAP26 BITMAP DISCARDABLE "res\\tool_hot_zoomout.bmp"
+IDB_BITMAP27 BITMAP DISCARDABLE "res\\tool_last.bmp"
+IDB_BITMAP28 BITMAP DISCARDABLE "res\\tool_next.bmp"
+IDB_BITMAP29 BITMAP DISCARDABLE "res\\tool_prev.bmp"
+IDB_BITMAP30 BITMAP DISCARDABLE "res\\tool_print.bmp"
+IDB_BITMAP31 BITMAP DISCARDABLE "res\\tool_search.bmp"
+IDB_BITMAP32 BITMAP DISCARDABLE "res\\tool_snap_shot.bmp"
+IDB_BITMAP33 BITMAP DISCARDABLE "res\\tool_zoomin.bmp"
+IDB_BITMAP34 BITMAP DISCARDABLE "res\\tool_zoomout.bmp"
+IDB_BITMAP25 BITMAP DISCARDABLE "res\\tool_hot_snap_shot.bmp"
+IDB_BITMAP35 BITMAP DISCARDABLE "res\\tool_hot_print.bmp"
+IDB_BITMAP36 BITMAP DISCARDABLE "res\\tool_hot_search.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Toolbar
+//
+
+IDR_MAINFRAME TOOLBAR DISCARDABLE 24, 24
+BEGIN
+ BUTTON ID_FILE_OPEN
+ SEPARATOR
+ BUTTON ID_FILE_PRINT
+ SEPARATOR
+ BUTTON ID_DOC_FIRSTPAGE
+ BUTTON ID_DOC_PREPAGE
+ BUTTON ID_DOC_NEXTPAGE
+ BUTTON ID_DOC_LASTPAGE
+ SEPARATOR
+ BUTTON ID_VIEW_COUNTERCLOCKWISE
+ BUTTON ID_VIEW_CLOCKWISE
+ SEPARATOR
+ BUTTON ID_VIEW_ZOOMIN
+ BUTTON ID_VIEW_ZOOMOUT
+ SEPARATOR
+ BUTTON ID_VIEW_ACTUALSIZE
+ BUTTON ID_VIEW_FITPAGE
+ BUTTON ID_VIEW_FITWIDTH
+ SEPARATOR
+ BUTTON ID_EDIT_FIND
+ SEPARATOR
+ BUTTON ID_VIEW_BOOKMARK
+ SEPARATOR
+ BUTTON ID_TOOL_SNAPSHOT
+ BUTTON ID_TOOL_SELECT
+ BUTTON ID_TOOL_HAND
+ BUTTON ID_APP_ABOUT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Accelerator
+//
+
+IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
+BEGIN
+ "+", ID_VIEW_ZOOMIN, VIRTKEY, CONTROL, NOINVERT
+ "-", ID_VIEW_ZOOMOUT, VIRTKEY, CONTROL, NOINVERT
+ "1", ID_VIEW_ACTUALSIZE, VIRTKEY, CONTROL, NOINVERT
+ "2", ID_VIEW_FITPAGE, VIRTKEY, CONTROL, NOINVERT
+ "3", ID_VIEW_FITWIDTH, VIRTKEY, CONTROL, NOINVERT
+ "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ "F", ID_EDIT_FIND, VIRTKEY, CONTROL, NOINVERT
+ "M", ID_VIEW_ZOOMTO, VIRTKEY, CONTROL, NOINVERT
+ "N", ID_FILE_NEW, VIRTKEY, CONTROL, NOINVERT
+ "N", ID_DOC_GOTOPAGE, VIRTKEY, SHIFT, CONTROL,
+ NOINVERT
+ "O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
+ "P", ID_FILE_PRINT, VIRTKEY, CONTROL, NOINVERT
+ "S", ID_FILE_SAVE, VIRTKEY, CONTROL, NOINVERT
+ "V", ID_EDIT_PASTE, VIRTKEY, CONTROL, NOINVERT
+ VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT, NOINVERT
+ VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT, NOINVERT
+ VK_F6, ID_NEXT_PANE, VIRTKEY, NOINVERT
+ VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT, NOINVERT
+ VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT
+ VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT, NOINVERT
+ "X", ID_EDIT_CUT, VIRTKEY, CONTROL, NOINVERT
+ "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL, NOINVERT
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About ReaderVC"
+FONT 9, "ËÎÌå"
+BEGIN
+ ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
+ LTEXT "Foxit SDK Demo 1.0 version",IDC_STATIC,40,10,126,8,
+ SS_NOPREFIX
+ LTEXT "All rights Reserved",IDC_STATIC,40,25,119,8
+ DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
+END
+
+IDD_DLG_GOTOPAGE DIALOG DISCARDABLE 0, 0, 133, 29
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Goto Page"
+FONT 10, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,91,7,35,14
+ LTEXT "Goto",IDC_STATIC,8,9,16,9
+ EDITTEXT IDC_EDIT1,25,7,64,14,ES_AUTOHSCROLL
+END
+
+IDD_DLG_ZOOMTO DIALOG DISCARDABLE 0, 0, 141, 45
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Zoom To"
+FONT 10, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,38,24,29,14
+ LTEXT "Zoom to",IDC_STATIC,7,9,30,8
+ DEFPUSHBUTTON "Cancel",IDCANCEL,75,24,29,14
+ COMBOBOX IDC_COMBO1,37,7,78,132,CBS_DROPDOWN | WS_VSCROLL |
+ WS_TABSTOP
+END
+
+IDD_DLG_FIND DIALOG DISCARDABLE 0, 0, 222, 70
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Find Text"
+FONT 10, "MS Sans Serif"
+BEGIN
+ DEFPUSHBUTTON "&Find Next",IDOK,174,7,41,13
+ PUSHBUTTON "&Cancel",IDCANCEL,175,24,40,13
+ LTEXT "&Find What",IDC_STATIC,7,10,38,10
+ EDITTEXT IDC_EDIT1,46,7,124,16,ES_AUTOHSCROLL
+ CONTROL "Match &Case",IDC_CHECK_MATCHCASE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,30,90,11
+ CONTROL "Match &Whole word only",IDC_CHECK_MATCHWHOLE,"Button",
+ BS_AUTOCHECKBOX | WS_TABSTOP,7,48,97,10
+ GROUPBOX "Direction",IDC_STATIC,104,28,68,32
+ CONTROL "Down",IDC_RADIO_Down,"Button",BS_AUTORADIOBUTTON |
+ WS_GROUP,109,42,29,10
+ CONTROL "Up",IDC_RADIO_UP,"Button",BS_AUTORADIOBUTTON,146,42,19,
+ 10
+END
+
+IDD_DLG_CONVERT DIALOG DISCARDABLE 0, 0, 128, 74
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Convert mode"
+FONT 10, "System"
+BEGIN
+ DEFPUSHBUTTON "OK",IDOK,17,55,42,12
+ PUSHBUTTON "Cancel",IDCANCEL,69,55,42,12
+ GROUPBOX "Flags for ConvertText",IDC_STATIC,16,7,95,46
+ CONTROL "Stream order",IDC_RADIO_Stream,"Button",
+ BS_AUTORADIOBUTTON | WS_GROUP,30,20,69,8
+ CONTROL "Appearance order",IDC_RADIO_Appearance,"Button",
+ BS_AUTORADIOBUTTON,30,31,69,8
+END
+
+IDD_EXPORT_PAGE DIALOG DISCARDABLE 0, 0, 230, 229
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Export Page"
+FONT 10, "System"
+BEGIN
+ LTEXT "Width",IDC_STATIC,22,16,20,8
+ LTEXT "Height",IDC_STATIC,21,37,22,8
+ LTEXT "Rotate",IDC_STATIC,21,61,22,8
+ LTEXT "Bitmap Width",IDC_STATIC,102,14,45,8
+ LTEXT "Bitmap Height",IDC_STATIC,99,35,47,8
+ PUSHBUTTON "Rander Page ",IDC_Rander_Page,102,58,50,14
+ PUSHBUTTON "Save As...",IDC_Save,158,58,50,14
+ EDITTEXT IDC_EDIT_PAGE_WIDTH,45,14,40,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_PAGE_HEIGHT,45,35,40,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_ROTATE,45,59,40,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_WIDTH,149,13,40,14,ES_AUTOHSCROLL
+ EDITTEXT IDC_EDIT_HEIGHT,148,33,40,14,ES_AUTOHSCROLL
+ CONTROL "",IDC_STATIC_BITMAP,"Static",SS_BLACKFRAME,18,87,196,
+ 127
+END
+
+IDD_DLG_RESPONSE DIALOG DISCARDABLE 0, 0, 241, 66
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 8, "System"
+BEGIN
+ DEFPUSHBUTTON "OK",ID_JS_OK,116,45,50,14
+ PUSHBUTTON "Cancel",ID_JS_CANCEL,184,45,50,14
+ LTEXT "",IDC_JS_QUESTION,7,7,227,12
+ LTEXT "",IDC_JS_ANSWER,7,26,27,12
+END
+
+IDD_TEST_JS DIALOG DISCARDABLE 0, 0, 187, 96
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Dialog"
+FONT 10, "System"
+BEGIN
+ EDITTEXT IDC_EDIT1,7,18,173,33,ES_MULTILINE | ES_AUTOHSCROLL
+ PUSHBUTTON "Run JS",IDC_BUTTON1,130,68,50,14
+END
+
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080404b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "\0"
+ VALUE "FileDescription", "ReaderVC Microsoft »ù´¡ÀàÓ¦ÓóÌÐò\0"
+ VALUE "FileVersion", "1, 0, 0, 1\0"
+ VALUE "InternalName", "ReaderVC\0"
+ VALUE "LegalCopyright", "°æȨËùÓÐ (C) 2007\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "ReaderVC.EXE\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "ReaderVC Ó¦ÓóÌÐò\0"
+ VALUE "ProductVersion", "1, 0, 0, 1\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x804, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_ABOUTBOX, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 228
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 48
+ END
+
+ IDD_DLG_GOTOPAGE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 126
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 22
+ END
+
+ IDD_DLG_ZOOMTO, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 134
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 38
+ END
+
+ IDD_DLG_FIND, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 215
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 63
+ END
+
+ IDD_DLG_CONVERT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 121
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 67
+ END
+
+ IDD_EXPORT_PAGE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 223
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 222
+ END
+
+ IDD_DLG_RESPONSE, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 234
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 59
+ END
+
+ IDD_TEST_JS, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 180
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 89
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Cursor
+//
+
+IDC_CURSOR1 CURSOR DISCARDABLE "res\\SmallHandCursor.cur"
+IDC_CURSOR2 CURSOR DISCARDABLE "res\\BigHandCursor.cur"
+IDC_CURSOR3 CURSOR DISCARDABLE "res\\bound.cur"
+IDC_CURSOR4 CURSOR DISCARDABLE "res\\point.cur"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE PRELOAD DISCARDABLE
+BEGIN
+ IDR_MAINFRAME "ReaderVC"
+ IDR_READERTYPE "\nReader\nReader\n\n\nReaderVC.Document\nReader Document"
+END
+
+STRINGTABLE PRELOAD DISCARDABLE
+BEGIN
+ AFX_IDS_APP_TITLE "ReaderVC"
+ AFX_IDS_IDLEMESSAGE "¾ÍÐ÷"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_INDICATOR_EXT "À©Õ¹Ãû"
+ ID_INDICATOR_CAPS "´óд"
+ ID_INDICATOR_NUM "Êý×Ö"
+ ID_INDICATOR_SCRL "¹ö¶¯"
+ ID_INDICATOR_OVR "¸Äд"
+ ID_INDICATOR_REC "¼Ç¼"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_FILE_NEW "½¨Á¢ÐÂÎĵµ\nн¨"
+ ID_FILE_OPEN "´ò¿ªÒ»¸öÏÖÓÐÎĵµ\n´ò¿ª"
+ ID_FILE_CLOSE "¹Ø±Õ»î¶¯Îĵµ\n¹Ø±Õ"
+ ID_FILE_SAVE "±£´æ»î¶¯Îĵµ\n±£´æ"
+ ID_FILE_SAVE_AS "½«»î¶¯ÎĵµÒÔÒ»¸öÐÂÎļþÃû±£´æ\nÁí´æΪ"
+ ID_FILE_PAGE_SETUP "¸Ä±ä´òÓ¡Ñ¡Ïî\nÒ³ÃæÉèÖÃ"
+ ID_FILE_PRINT_SETUP "¸Ä±ä´òÓ¡»ú¼°´òÓ¡Ñ¡Ïî\n´òÓ¡ÉèÖÃ"
+ ID_FILE_PRINT "´òÓ¡»î¶¯Îĵµ\n´òÓ¡"
+ ID_FILE_PRINT_PREVIEW "ÏÔʾÕûÒ³\n´òÓ¡Ô¤ÀÀ"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_APP_ABOUT "ÏÔʾ³ÌÐòÐÅÏ¢£¬°æ±¾ºÅºÍ°æȨ\n¹ØÓÚ"
+ ID_APP_EXIT "Í˳öÓ¦ÓóÌÐò£»Ìáʾ±£´æÎĵµ\nÍ˳ö"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_FILE_MRU_FILE1 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE2 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE3 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE4 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE5 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE6 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE7 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE8 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE9 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE10 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE11 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE12 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE13 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE14 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE15 "´ò¿ª¸ÃÎĵµ"
+ ID_FILE_MRU_FILE16 "´ò¿ª¸ÃÎĵµ"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_NEXT_PANE "Çл»µ½ÏÂÒ»¸ö´°¸ñ\nÏÂÒ»´°¸ñ"
+ ID_PREV_PANE "Çл»»ØÇ°Ò»¸ö´°¸ñ\nÇ°Ò»´°¸ñ"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_WINDOW_NEW "Ϊ»î¶¯Îĵµ´ò¿ªÁíÒ»¸ö´°¿Ú\nн¨´°¿Ú"
+ ID_WINDOW_ARRANGE "½«Í¼±êÅÅÁÐÔÚ´°¿Úµ×²¿\nÅÅÁÐͼ±ê"
+ ID_WINDOW_CASCADE "ÅÅÁд°¿Ú³ÉÏ໥Öصþ\n²ãµþ´°¿Ú"
+ ID_WINDOW_TILE_HORZ "ÅÅÁд°¿Ú³É»¥²»Öصþ\nƽÆÌ´°¿Ú"
+ ID_WINDOW_TILE_VERT "ÅÅÁд°¿Ú³É»¥²»Öصþ\nƽÆÌ´°¿Ú"
+ ID_WINDOW_SPLIT "½«»î¶¯µÄ´°¿Ú·Ö¸ô³É´°¸ñ\n·Ö¸ô"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_EDIT_CLEAR "ɾ³ý±»Ñ¡¶ÔÏó\nɾ³ý"
+ ID_EDIT_CLEAR_ALL "È«²¿É¾³ý\nÈ«²¿É¾³ý"
+ ID_EDIT_COPY "¸´ÖƱ»Ñ¡¶ÔÏó²¢½«ÆäÖÃÓÚ¼ôÌù°åÉÏ\n¸´ÖÆ"
+ ID_EDIT_CUT "¼ôÇб»Ñ¡¶ÔÏó²¢½«ÆäÖÃÓÚ¼ôÌù°åÉÏ\n¼ôÇÐ"
+ ID_EDIT_FIND "²éÕÒÖ¸¶¨µÄÕýÎÄ\n²éÕÒ"
+ ID_EDIT_PASTE "²åÈë¼ôÌù°åÄÚÈÝ\nÕ³Ìù"
+ ID_EDIT_REPEAT "Öظ´ÉÏÒ»²½²Ù×÷\nÖظ´"
+ ID_EDIT_REPLACE "Óò»Í¬µÄÕýÎÄÌæ»»Ö¸¶¨µÄÕýÎÄ\nÌæ»»"
+ ID_EDIT_SELECT_ALL "Ñ¡ÔñÕû¸öÎĵµ\nÑ¡ÔñÈ«²¿"
+ ID_EDIT_UNDO "³·Ïû×îºóÒ»²½²Ù×÷\n³·Ïû"
+ ID_EDIT_REDO "ÖØÐÂÖ´ÐÐÏÈÇ°Òѳ·ÏûµÄ²Ù×÷\nÖØÐÂÖ´ÐÐ"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ ID_VIEW_TOOLBAR "Show or hide the ToolBar\nShow or hide the ToolBar"
+ ID_VIEW_STATUS_BAR "Show or hide\nShow or hide"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_SCSIZE "¸Ä±ä´°¿Ú´óС"
+ AFX_IDS_SCMOVE "¸Ä±ä´°¿ÚλÖÃ"
+ AFX_IDS_SCMINIMIZE "½«´°¿ÚËõС³Éͼ±ê"
+ AFX_IDS_SCMAXIMIZE "°Ñ´°¿Ú·Å´óµ½×î´ó³ß´ç"
+ AFX_IDS_SCNEXTWINDOW "Çл»µ½ÏÂÒ»¸öÎĵµ´°¿Ú"
+ AFX_IDS_SCPREVWINDOW "Çл»µ½ÏÈÇ°µÄÎĵµ´°¿Ú"
+ AFX_IDS_SCCLOSE "¹Ø±Õ»î¶¯µÄ´°¿Ú²¢Ìáʾ±£´æËùÓÐÎĵµ"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_SCRESTORE "°Ñ´°¿Ú»Ö¸´µ½Õý³£´óС"
+ AFX_IDS_SCTASKLIST "¼¤»îÈÎÎñ±í"
+ AFX_IDS_MDICHILD "¼¤»î¸Ã´°¿Ú"
+END
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ AFX_IDS_PREVIEW_CLOSE "¹Ø±Õ´òÓ¡Ô¤ÀÀģʽ\nÈ¡ÏûÔ¤ÔÄ"
+END
+
+#endif // Chinese (P.R.C.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Menu
+//
+
+IDR_READERTYPE MENU PRELOAD DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM "&Close", ID_FILE_CLOSE
+ MENUITEM "&Save As...", ID_FILE_SAVE
+ MENUITEM SEPARATOR
+ MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT
+ MENUITEM "P&rinter Setup...", ID_FILE_PRINT_SETUP
+ MENUITEM SEPARATOR
+ MENUITEM "Recently File", ID_FILE_MRU_FILE1, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit...\tCtrl+Q", ID_APP_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM "&Copy Select Text", ID_EDIT_COPY
+ MENUITEM "&Find Text...\tCtrl+F", ID_EDIT_FIND
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "Zoom &In\t\tNum+", ID_VIEW_ZOOMIN
+ MENUITEM "Zoom &Out\t\tNum-", ID_VIEW_ZOOMOUT
+ MENUITEM "Zoom &To...\tCtrl+M", ID_VIEW_ZOOMTO
+ MENUITEM SEPARATOR
+ MENUITEM "&Actual Size\tCtrl+1", ID_VIEW_ACTUALSIZE
+ MENUITEM "Fit &Page\tCtrl+2", ID_VIEW_FITPAGE
+ MENUITEM "Fit &Width\tCtrl+3", ID_VIEW_FITWIDTH
+ MENUITEM SEPARATOR
+ POPUP "&Rotate View"
+ BEGIN
+ MENUITEM "&Clockwise\tShift+Ctrl+Plus", ID_VIEW_CLOCKWISE, HELP
+ MENUITEM "Counterclock&wise\tShift+Ctrl+Minus",
+ ID_VIEW_COUNTERCLOCKWISE
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "&ToolBar", ID_VIEW_TOOLBAR
+ MENUITEM "&StatusBar", ID_VIEW_STATUS_BAR
+ END
+ POPUP "&Document"
+ BEGIN
+ MENUITEM "&First Page \t\tHome", ID_DOC_FIRSTPAGE
+ MENUITEM "P&revious Page\tLeft Arrow", ID_DOC_PREPAGE
+ MENUITEM "&Next Page\tRight Arrow", ID_DOC_NEXTPAGE
+ MENUITEM "&Last Page\tEnd", ID_DOC_LASTPAGE
+ MENUITEM SEPARATOR
+ MENUITEM "&Goto Page...\tShift+Ctrl+N", ID_DOC_GOTOPAGE
+ MENUITEM "", TEST_PRINT_METALFILE
+ END
+ POPUP "&Tool"
+ BEGIN
+ MENUITEM "&Hand Tool", ID_TOOL_HAND
+ MENUITEM "Se&lect Text", ID_TOOL_SELECT
+ MENUITEM "&Snapshot", ID_TOOL_SNAPSHOT
+ MENUITEM "Pdf2txt", ID_TOOL_PDF2TXT
+ MENUITEM "Extract links", ID_TOOL_EXTRACTLINKS
+ MENUITEM "Test JavaScript", IDM_Test_JS
+ END
+ POPUP "&Bitmap"
+ BEGIN
+ MENUITEM "&Export PDF to bitmap", ID_EXPORT_PDF_TO_BITMAP
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "About ReaderVC(&A)...", ID_APP_ABOUT
+ END
+END
+
+IDR_MAINFRAME MENU PRELOAD DISCARDABLE
+BEGIN
+ POPUP "&File"
+ BEGIN
+ MENUITEM "&Open...\tCtrl+O", ID_FILE_OPEN
+ MENUITEM "&Close", ID_FILE_CLOSE
+ MENUITEM "&Save As...", ID_FILE_SAVE
+ MENUITEM SEPARATOR
+ MENUITEM "&Print...\tCtrl+P", ID_FILE_PRINT
+ MENUITEM "P&rinter Setup...", ID_FILE_PRINT_SETUP
+ MENUITEM SEPARATOR
+ MENUITEM "Recently File", ID_FILE_MRU_FILE1, GRAYED
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit...\tCtrl+Q", ID_APP_EXIT
+ END
+ POPUP "&Edit"
+ BEGIN
+ MENUITEM SEPARATOR
+ MENUITEM "&Copy Select Text", ID_EDIT_COPY
+ MENUITEM "&Find Text...\tCtrl+F", ID_EDIT_FIND
+ END
+ POPUP "&View"
+ BEGIN
+ MENUITEM "Zoom &In\t\tNum+", ID_VIEW_ZOOMIN
+ MENUITEM "Zoom &Out\t\tNum-", ID_VIEW_ZOOMOUT
+ MENUITEM "Zoom &To...\tCtrl+M", ID_VIEW_ZOOMTO
+ MENUITEM SEPARATOR
+ MENUITEM "&Actual Size\tCtrl+1", ID_VIEW_ACTUALSIZE
+ MENUITEM "Fit &Page\tCtrl+2", ID_VIEW_FITPAGE
+ MENUITEM "Fit &Width\tCtrl+3", ID_VIEW_FITWIDTH
+ MENUITEM SEPARATOR
+ POPUP "&Rotate View"
+ BEGIN
+ MENUITEM "&Clockwise\tShift+Ctrl+Plus", ID_VIEW_CLOCKWISE, HELP
+ MENUITEM "Counterclock&wise\tShift+Ctrl+Minus",
+ ID_VIEW_COUNTERCLOCKWISE
+ END
+ MENUITEM SEPARATOR
+ MENUITEM "&ToolBar", ID_VIEW_TOOLBAR
+ MENUITEM "&StatusBar", ID_VIEW_STATUS_BAR
+ END
+ POPUP "&Document"
+ BEGIN
+ MENUITEM "&First Page \t\tHome", ID_DOC_FIRSTPAGE
+ MENUITEM "P&revious Page\tLeft Arrow", ID_DOC_PREPAGE
+ MENUITEM "&Next Page\tRight Arrow", ID_DOC_NEXTPAGE
+ MENUITEM "&Last Page\tEnd", ID_DOC_LASTPAGE
+ MENUITEM SEPARATOR
+ MENUITEM "&Goto Page...\tShift+Ctrl+N", ID_DOC_GOTOPAGE
+ MENUITEM "Print MetalFile", TEST_PRINT_METALFILE
+ END
+ POPUP "&Tool"
+ BEGIN
+ MENUITEM "&Hand Tool", ID_TOOL_HAND
+ MENUITEM "Se&lect Text", ID_TOOL_SELECT
+ MENUITEM "&Snapshot", ID_TOOL_SNAPSHOT
+ MENUITEM "Pdf2txt", ID_TOOL_PDF2TXT
+ MENUITEM "Extract links", ID_TOOL_EXTRACTLINKS
+ END
+ POPUP "&Bitmap"
+ BEGIN
+ MENUITEM "&Export PDF to bitmap", ID_EXPORT_PDF_TO_BITMAP
+ END
+ POPUP "&Help"
+ BEGIN
+ MENUITEM "About ReaderVC(&A)...", ID_APP_ABOUT
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#define _AFX_NO_SPLITTER_RESOURCES
+#define _AFX_NO_OLE_RESOURCES
+#define _AFX_NO_TRACKER_RESOURCES
+#define _AFX_NO_PROPERTY_RESOURCES
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
+#ifdef _WIN32
+LANGUAGE 4, 2
+#pragma code_page(936)
+#endif //_WIN32
+#include "res\ReaderVC.rc2" // non-Microsoft Visual C++ edited resources
+#include "l.chs\afxres.rc" // Standard components
+#include "l.chs\afxprint.rc" // printing/print preview resources
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/xfa_test/FormFiller_Test/ReaderVCDoc.cpp b/xfa_test/FormFiller_Test/ReaderVCDoc.cpp
new file mode 100644
index 0000000000..e06515d67e
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVCDoc.cpp
@@ -0,0 +1,113 @@
+// ReaderVCDoc.cpp : implementation of the CReaderVCDoc class
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCDoc.h"
+#include "ReaderVCView.h"
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCDoc
+
+IMPLEMENT_DYNCREATE(CReaderVCDoc, CDocument)
+
+BEGIN_MESSAGE_MAP(CReaderVCDoc, CDocument)
+ //{{AFX_MSG_MAP(CReaderVCDoc)
+ // NOTE - the ClassWizard will add and remove mapping macros here.
+ // DO NOT EDIT what you see in these blocks of generated code!
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCDoc construction/destruction
+
+CReaderVCDoc::CReaderVCDoc()
+{
+ // TODO: add one-time construction code here
+
+}
+
+CReaderVCDoc::~CReaderVCDoc()
+{
+}
+
+BOOL CReaderVCDoc::OnNewDocument()
+{
+ if (!CDocument::OnNewDocument())
+ return FALSE;
+
+ // TODO: add reinitialization code here
+ // (SDI documents will reuse this document)
+
+ return TRUE;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCDoc serialization
+
+void CReaderVCDoc::Serialize(CArchive& ar)
+{
+ if (ar.IsStoring())
+ {
+ // TODO: add storing code here
+ }
+ else
+ {
+ // TODO: add loading code here
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCDoc diagnostics
+
+#ifdef _DEBUG
+void CReaderVCDoc::AssertValid() const
+{
+ CDocument::AssertValid();
+}
+
+void CReaderVCDoc::Dump(CDumpContext& dc) const
+{
+ CDocument::Dump(dc);
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCDoc commands
+
+BOOL CReaderVCDoc::OnOpenDocument(LPCTSTR lpszPathName)
+{
+ if (!CDocument::OnOpenDocument(lpszPathName))
+ return FALSE;
+
+ // TODO: Add your specialized creation code here
+ void* pDoc = FPDF_LoadDocument(lpszPathName, NULL);
+
+ m_strPDFName=lpszPathName;
+ if(NULL == pDoc) return FALSE;
+ POSITION pos = GetFirstViewPosition();
+ int nCount = FPDF_GetPageCount(pDoc);
+ while (pos != NULL)
+ {
+ CView* pView = GetNextView(pos);
+ if(pView->IsKindOf(RUNTIME_CLASS(CReaderVCView)))
+ {
+ CMainFrame* pMFrm = (CMainFrame*)AfxGetMainWnd();
+ CChildFrame* pChildFrm =(CChildFrame*) pMFrm->GetActiveFrame();
+ pChildFrm->SetActiveView(pView, TRUE);
+// FPDFApp_SetDocument(((CReaderVCView*)pView)->GetFPDFApp(), (FPDF_DOCUMENT)pDoc);
+ ((CReaderVCView*)pView)->SetPDFDocument(pDoc, nCount);
+ }
+ }
+ return TRUE;
+}
diff --git a/xfa_test/FormFiller_Test/ReaderVCDoc.h b/xfa_test/FormFiller_Test/ReaderVCDoc.h
new file mode 100644
index 0000000000..5bfc7e17f8
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVCDoc.h
@@ -0,0 +1,59 @@
+ // ReaderVCDoc.h : interface of the CReaderVCDoc class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_READERVCDOC_H__6E0B9799_0661_4DB3_9E40_FB2D17F0D5EB__INCLUDED_)
+#define AFX_READERVCDOC_H__6E0B9799_0661_4DB3_9E40_FB2D17F0D5EB__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+
+class CReaderVCDoc : public CDocument
+{
+protected: // create from serialization only
+ CReaderVCDoc();
+ DECLARE_DYNCREATE(CReaderVCDoc)
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CReaderVCDoc)
+ public:
+ virtual BOOL OnNewDocument();
+ virtual void Serialize(CArchive& ar);
+ virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ CString m_strPDFName;
+ virtual ~CReaderVCDoc();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CReaderVCDoc)
+ // NOTE - the ClassWizard will add and remove member functions here.
+ // DO NOT EDIT what you see in these blocks of generated code !
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_READERVCDOC_H__6E0B9799_0661_4DB3_9E40_FB2D17F0D5EB__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/ReaderVCView.cpp b/xfa_test/FormFiller_Test/ReaderVCView.cpp
new file mode 100644
index 0000000000..ef0b58bfbb
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVCView.cpp
@@ -0,0 +1,3750 @@
+// ReaderVCView.cpp : implementation of the CReaderVCView class
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCDoc.h"
+#include "ReaderVCView.h"
+
+#include "GotoPageDlg.h"
+#include "ZoomDlg.h"
+#include "FindDlg.h"
+#include "ConvertDlg.h"
+#include "JS_ResponseDlg.h"
+#include "TestJsDlg.h"
+//#include "../../include/pp_event.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCView
+
+IMPLEMENT_DYNCREATE(CReaderVCView, CView)
+
+BEGIN_MESSAGE_MAP(CReaderVCView, CView)
+ //{{AFX_MSG_MAP(CReaderVCView)
+ ON_COMMAND(ID_DOC_FIRSTPAGE, OnDocFirstpage)
+ ON_COMMAND(ID_DOC_GOTOPAGE, OnDocGotopage)
+ ON_COMMAND(ID_DOC_LASTPAGE, OnDocLastpage)
+ ON_COMMAND(ID_DOC_NEXTPAGE, OnDocNextpage)
+ ON_COMMAND(ID_DOC_PREPAGE, OnDocPrepage)
+ ON_COMMAND(ID_VIEW_CLOCKWISE, OnClockwise)
+ ON_COMMAND(ID_VIEW_COUNTERCLOCKWISE, OnCounterclockwise)
+ ON_COMMAND(ID_VIEW_ACTUALSIZE, OnViewActualSize)
+ ON_COMMAND(ID_VIEW_FITPAGE, OnViewFitPage)
+ ON_COMMAND(ID_VIEW_FITWIDTH, OnViewFitWidth)
+ ON_COMMAND(ID_VIEW_ZOOMIN, OnViewZoomIn)
+ ON_COMMAND(ID_VIEW_ZOOMOUT, OnViewZoomOut)
+ ON_COMMAND(ID_VIEW_ZOOMTO, OnViewZoomTo)
+ ON_COMMAND(ID_EDIT_FIND, OnEditFind)
+ ON_COMMAND(ID_FILE_PRINT, OnFilePrint)
+ ON_WM_LBUTTONDOWN()
+ ON_WM_LBUTTONUP()
+ ON_WM_MOUSEMOVE()
+ ON_WM_KEYDOWN()
+ ON_COMMAND(ID_TOOL_SNAPSHOT, OnToolSnapshot)
+ ON_COMMAND(ID_TOOL_SELECT, OnToolSelect)
+ ON_COMMAND(ID_TOOL_HAND, OnToolHand)
+ ON_COMMAND(ID_TOOL_PDF2TXT, OnToolPdf2txt)
+ ON_WM_SIZE()
+ ON_WM_HSCROLL()
+ ON_WM_VSCROLL()
+ ON_COMMAND(ID_TOOL_EXTRACTLINKS, OnToolExtractlinks)
+ ON_WM_DESTROY()
+ ON_UPDATE_COMMAND_UI(ID_DOC_FIRSTPAGE, OnUpdateDocFirstpage)
+ ON_UPDATE_COMMAND_UI(ID_DOC_LASTPAGE, OnUpdateDocLastpage)
+ ON_UPDATE_COMMAND_UI(ID_DOC_NEXTPAGE, OnUpdateDocNextpage)
+ ON_UPDATE_COMMAND_UI(ID_DOC_PREPAGE, OnUpdateDocPrepage)
+ ON_UPDATE_COMMAND_UI(ID_TOOL_HAND, OnUpdateToolHand)
+ ON_UPDATE_COMMAND_UI(ID_TOOL_SNAPSHOT, OnUpdateToolSnapshot)
+ ON_UPDATE_COMMAND_UI(ID_TOOL_SELECT, OnUpdateToolSelect)
+ ON_COMMAND(ID_VIEW_BOOKMARK, OnViewBookmark)
+ ON_WM_MOUSEWHEEL()
+ ON_WM_CONTEXTMENU()
+ ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
+ ON_COMMAND(ID_RENDERBITMAP, OnRenderbitmap)
+ ON_COMMAND(ID_EXPORT_PDF_TO_BITMAP, OnExportPdfToBitmap)
+ ON_WM_CHAR()
+ ON_WM_KEYUP()
+ ON_COMMAND(ID_FILE_SAVE, OnFileSave)
+ ON_COMMAND(IDM_Test_JS, OnTestJS)
+ ON_COMMAND(TEST_PRINT_METALFILE, OnPrintMetalfile)
+ //}}AFX_MSG_MAP
+ // Standard printing commands
+ ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
+ ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCView construction/destruction
+void Sample_PageToDevice(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page,double page_x,double page_y, int* device_x, int* device_y)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->PageToDeviceImpl(page, page_x, page_y, device_x, device_y);
+ }
+ //((CReaderVCView*)pThis)->PageToDeviceImpl(page, page_x, page_y, device_x, device_y);
+}
+
+void Sample_Invalidate(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page, double left, double top, double right, double bottom)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->InvalidateImpl(page,left, top, right, bottom);
+ }
+ //((CReaderVCView*)pThis)->InvalidateImpl(page,left, top, right, bottom);
+}
+
+void Sample_OutputSelectedRect(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page, double left, double top, double right, double bottom)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->OutputSelectedRectImpl(page,left, top, right, bottom);
+ }
+}
+
+void Sample_DeviceToPage(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page,int device_x, int device_y, double* page_x, double* page_y)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->DeviceToPageImpl(page, device_x, device_y, page_x, page_y);
+ }
+ //((CReaderVCView*)pThis)->DeviceToPageImpl(page, device_x, device_y, page_x, page_y);
+}
+/* /* Remove by Amy Lin 20100913, Since we don't this the FFI_SetCaret any more.
+void Sample_SetCaret(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page,double page_x, double page_y, int nWidth, int nHeight)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->SetCaretImpl(page, page_x, page_y, nWidth, nHeight);
+ }
+ //((CReaderVCView*)pThis)->SetCaretImpl(page, page_x, page_y, nWidth, nHeight);
+}
+*/
+void Sample_Release(struct _FPDF_FORMFILLINFO* pThis)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->ReleaseImpl();
+ }
+ //((CReaderVCView*)pThis)->ReleaseImpl();
+}
+
+
+int Sample_SetTimer(struct _FPDF_FORMFILLINFO* pThis, int uElapse, TimerCallback lpTimerFunc)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->SetTimerImpl(uElapse, lpTimerFunc);
+ }else{
+ return -1;
+ }
+ //return ((CReaderVCView*)pThis)->SetTimerImpl(uElapse, lpTimerFunc);
+}
+
+void Sample_KillTimer(struct _FPDF_FORMFILLINFO* pThis,int nID)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->KillTimerImpl(nID);
+ }
+ //((CReaderVCView*)pThis)->KillTimerImpl(nID);
+}
+
+void Sample_SetCursor(struct _FPDF_FORMFILLINFO* pThis,int nCursorType)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->SetCurorImpl(nCursorType);
+ }
+ //((CReaderVCView*)pThis)->SetCurorImpl(nCursorType);
+}
+
+void Sample_OnChange(struct _FPDF_FORMFILLINFO* pThis)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->OnChangeImpl();
+ }
+}
+FPDF_BOOL Sample_IsSHIFTKeyDown(struct _FPDF_FORMFILLINFO* pThis)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->IsSHIFTKeyDownImpl();
+ }
+ return FALSE;
+}
+FPDF_BOOL Sample_IsCTRLKeyDown(struct _FPDF_FORMFILLINFO* pThis)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->IsCTRLKeyDownImpl();
+ }
+ return FALSE;
+}
+FPDF_BOOL Sample_IsALTKeyDown(struct _FPDF_FORMFILLINFO* pThis)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->IsALTKeyDownImpl();
+ }
+ return FALSE;
+}
+FPDF_BOOL Sample_IsINSERTKeyDown(struct _FPDF_FORMFILLINFO* pThis)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->IsINSERTKeyDownImpl();
+ }
+ return FALSE;
+}
+
+FPDF_PAGE Sample_GetPage(struct _FPDF_FORMFILLINFO* pThis,FPDF_DOCUMENT document, int nPageIndex)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->GetPageImpl(document,nPageIndex);
+ }
+ return NULL;
+}
+
+FPDF_PAGE Sample_GetCurrentPage(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->GetCurrentPageImpl(document);
+ }
+ return NULL;
+}
+
+int Sample_GetRotation(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->GetRotationImpl(page);
+ }
+ return NULL;
+}
+FPDF_SYSTEMTIME Sample_GetLocalTime(struct _FPDF_FORMFILLINFO* pThis)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ return pView->GetLocalTimeImpl();
+ }
+ return FPDF_SYSTEMTIME();
+}
+
+void SampleRelease(struct _FPDF_SYSFONTINFO* pThis)
+{
+ ((CSampleFontInfo*)pThis)->ReleaseImpl();
+}
+
+void SampleEnumFonts(struct _FPDF_SYSFONTINFO* pThis, void* pMapper)
+{
+ ((CSampleFontInfo*)pThis)->EnumFontsImpl(pMapper);
+}
+
+void* SampleMapFont(struct _FPDF_SYSFONTINFO* pThis, int weight, int bItalic, int charset, int pitch_family,
+ const char* face, int* bExact)
+{
+ return ((CSampleFontInfo*)pThis)->MapFontImpl(weight, bItalic, charset, pitch_family, face, bExact);
+}
+
+unsigned long SampleGetFontData(struct _FPDF_SYSFONTINFO* pThis, void* hFont,
+ unsigned int table, unsigned char* buffer, unsigned long buf_size)
+{
+ return ((CSampleFontInfo*)pThis)->GetFontDataImpl(hFont, table, buffer, buf_size);
+}
+
+unsigned long SampleGetFaceName(struct _FPDF_SYSFONTINFO* pThis, void* hFont, char* buffer, unsigned long buf_size)
+{
+ return ((CSampleFontInfo*)pThis)->GetFaceNameImpl(hFont, buffer, buf_size);
+}
+
+int SampleGetFontCharset(struct _FPDF_SYSFONTINFO* pThis, void* hFont)
+{
+ return ((CSampleFontInfo*)pThis)->GetFontCharsetImpl(hFont);
+}
+
+void SampleDeleteFont(struct _FPDF_SYSFONTINFO* pThis, void* hFont)
+{
+ ((CSampleFontInfo*)pThis)->DeleteFontImpl(hFont);
+}
+
+void SetSampleFontInfo()
+{
+ CSampleFontInfo* pFontInfo = new CSampleFontInfo;
+ pFontInfo->version = 1;
+ pFontInfo->DeleteFont = SampleDeleteFont;
+ pFontInfo->EnumFonts = SampleEnumFonts;
+ pFontInfo->GetFaceName = SampleGetFaceName;
+ pFontInfo->GetFont = NULL;
+ pFontInfo->GetFontCharset = SampleGetFontCharset;
+ pFontInfo->GetFontData = SampleGetFontData;
+ pFontInfo->MapFont = SampleMapFont;
+ pFontInfo->Release = SampleRelease;
+ FPDF_SetSystemFontInfo(pFontInfo);
+}
+
+void Sample_ExecuteNamedAction(struct _FPDF_FORMFILLINFO* pThis, FPDF_BYTESTRING namedAction)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if ( pView )
+ {
+ pView->ExecuteNamedActionImpl(namedAction);
+ }
+
+}
+void CReaderVCView::ExecuteNamedActionImpl(FPDF_BYTESTRING namedaction)
+{
+ if(strcmp("Print", (LPCSTR)namedaction) == 0)
+ OnFilePrint();
+}
+void CReaderVCView::OutputSelectedRectImpl(FPDF_PAGE page, double left, double top, double right, double bottom)
+{
+
+ if(page == m_pPage)
+ {
+
+ int device_left, device_top, device_right, device_bottom;
+
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, left, top, &device_left, &device_top);
+
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, right, bottom, &device_right, &device_bottom);
+
+ CRect rc(device_left,device_top, device_right, device_bottom);
+
+
+
+ m_SelectArray.Add(rc);
+
+
+ }
+}
+
+void Sample_Release(FPDF_LPVOID clientData)
+{
+ if (!clientData) return;
+
+ fclose(((FPDF_FILE*)clientData)->file);
+ delete ((FPDF_FILE*)clientData);
+}
+
+FPDF_DWORD Sample_GetSize(FPDF_LPVOID clientData)
+{
+ if (!clientData) return 0;
+
+ long curPos = ftell(((FPDF_FILE*)clientData)->file);
+ fseek(((FPDF_FILE*)clientData)->file, 0, SEEK_END);
+ long size = ftell(((FPDF_FILE*)clientData)->file);
+ fseek(((FPDF_FILE*)clientData)->file, curPos, SEEK_SET);
+
+ return (FPDF_DWORD)size;
+}
+
+FPDF_RESULT Sample_ReadBlock(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPVOID buffer, FPDF_DWORD size)
+{
+ if (!clientData) return -1;
+
+ fseek(((FPDF_FILE*)clientData)->file, (long)offset, SEEK_SET);
+ size_t readSize = fread(buffer, 1, size, ((FPDF_FILE*)clientData)->file);
+ return readSize == size ? 0 : -1;
+}
+
+FPDF_RESULT Sample_WriteBlock(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPCVOID buffer, FPDF_DWORD size)
+{
+ if (!clientData) return -1;
+
+ fseek(((FPDF_FILE*)clientData)->file, (long)offset, SEEK_SET);
+ //Write data
+ size_t writeSize = fwrite(buffer, 1, size, ((FPDF_FILE*)clientData)->file);
+ return writeSize == size ? 0 : -1;
+}
+
+FPDF_RESULT Sample_Flush(FPDF_LPVOID clientData)
+{
+ if (!clientData) return -1;
+
+ //Flush file
+ fflush(((FPDF_FILE*)clientData)->file);
+
+ return 0;
+}
+
+FPDF_RESULT Sample_Truncate(FPDF_LPVOID clientData, FPDF_DWORD size)
+{
+ return 0;
+}
+
+void Sample_DisplayCaret(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_BOOL bVisible, double left, double top, double right, double bottom)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if (!pView) return;
+
+ HWND hWnd = pView->m_hWnd;
+
+ if (bVisible)
+ {
+ CPoint ltPt;
+ pView->PageToDevice(left, top, ltPt);
+ CPoint rbPt;
+ pView->PageToDevice(right, bottom, rbPt);
+ CRect rcCaret(ltPt, rbPt);
+
+ ::DestroyCaret();
+ ::CreateCaret(hWnd, (HBITMAP)0, rcCaret.Width(), rcCaret.Height());
+ ::SetCaretPos (rcCaret.left, rcCaret.top);
+ ::ShowCaret(hWnd);
+ }
+ else
+ {
+ ::DestroyCaret();
+ ::HideCaret(hWnd);
+ }
+}
+
+int Sample_GetCurrentPageIndex(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document)
+{
+ CReaderVCView* pView =(CReaderVCView*)pThis;
+ if (!pView) return -1;
+
+ return pView->GetCurrentPageIndex();
+}
+
+void Sample_SetCurrentPage(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, int iCurPage)
+{
+ CReaderVCView* pView = (CReaderVCView*)pThis;
+ if (!pView) return;
+
+ FPDF_DOCUMENT curDoc = pView->GetPDFDoc();
+ if (curDoc != document)
+ return;
+
+ int nPageCount = FPDF_GetPageCount(curDoc);
+ if (nPageCount > iCurPage)
+ {
+ int nCurPageInx = pView->GetCurrentPageIndex();
+ if (nCurPageInx != iCurPage)
+ {
+ pView->GotoPage(nCurPageInx);
+ }
+ }
+}
+
+void Sample_GotoURL(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, FPDF_WIDESTRING wsURL)
+{
+ CReaderVCView* pView = (CReaderVCView*)pThis;
+ if (!pView) return;
+
+ wchar_t* pURL = (wchar_t*)wsURL;
+ MessageBoxW(NULL, pURL, NULL, MB_OK);
+}
+
+FPDF_WIDESTRING Sample_GetURL(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document)
+{
+ CReaderVCView* pView = (CReaderVCView*)pThis;
+ if (!pView) return NULL;
+
+ if (pView->GetPDFDoc() != document)
+ return NULL;
+
+ //not support in this demo
+
+ return NULL;
+}
+
+void Sample_AddDoRecord(struct _FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, FPDF_WIDGET hWidget)
+{
+ //not support
+}
+
+void Sample_PageEvent(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_DWORD eventFlag)
+{
+ //
+}
+
+void Sample_GetPageViewRect(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, double* left, double* top, double* right, double* bottom)
+{
+ CReaderVCView* pView = (CReaderVCView*)pThis;
+ if (!pView) return;
+
+ if (pView->GetPage() != page)
+ return;
+
+ CRect clientRect;
+ pView->GetClientRect(&clientRect);
+
+ *left = (double)clientRect.left;
+ *right = (double)clientRect.right;
+ *top = (double)clientRect.top;
+ *bottom = (double)clientRect.bottom;
+}
+
+#define WM_XFAMENU_COPY 10000
+
+FPDF_BOOL Sample_PopupMenu(struct _FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_WIDGET hWidget, int menuFlag, float x, float y)
+{
+ CReaderVCView* pView = (CReaderVCView*)pThis;
+ if (!pView)
+ return FALSE;
+
+ CMenu menu;
+ menu.CreatePopupMenu();
+
+ int nMenuIndex = 0;
+
+ if (menuFlag & FXFA_MEMU_COPY)
+ menu.InsertMenu(nMenuIndex++, MF_BYPOSITION, WM_XFAMENU_COPY, "Copy");
+ //...
+
+ CPoint pt;
+ pView->PageToDevice(x, y, pt);
+
+ UINT nID = menu.TrackPopupMenu(TPM_RIGHTBUTTON, pt.x, pt.y, pView);
+ switch(nID)
+ {
+ case WM_XFAMENU_COPY:
+ {
+ FPDF_DWORD length = 0;
+ FPDF_Widget_Copy(pView->GetPDFDoc(), hWidget, NULL, &length);
+ if (length > 0)
+ {
+ unsigned short* buffer = (unsigned short*)malloc((length+1)*sizeof(unsigned short));
+ memset(buffer, 0, (length+1)*sizeof(unsigned short));
+ FPDF_Widget_Copy(pView->GetPDFDoc(), hWidget, buffer, &length);
+ free(buffer);
+ }
+ }
+ break;
+ }
+
+ menu.DestroyMenu();
+
+ return TRUE;
+}
+
+FPDF_FILEHANDLER* Sample_OpenFile(struct _FPDF_FORMFILLINFO* pThis, int fileFlag, FPDF_WIDESTRING wsURL)
+{
+ char* pszURL;
+ CString strURL;
+ if (wsURL == NULL) {
+ if (fileFlag == FXFA_FILE_XDP)
+ strURL = "C://temp.xdp";
+ else if(fileFlag == FXFA_FILE_XML)
+ strURL = "C://temp.xml";
+ }
+ else {
+ int iSize;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsURL, -1, NULL, 0, NULL, NULL);
+ pszURL = (char*)malloc((iSize+1));
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsURL, -1, pszURL, iSize, NULL, NULL);
+ CString str(pszURL);
+ strURL = str;
+ }
+
+
+ FILE* file = fopen(strURL, "r");
+ FPDF_FILE* pFileHander = new FPDF_FILE;
+ pFileHander->file = file;
+ pFileHander->fileHandler.clientData = pFileHander;
+ pFileHander->fileHandler.Flush = Sample_Flush;
+ pFileHander->fileHandler.GetSize = Sample_GetSize;
+ pFileHander->fileHandler.ReadBlock = Sample_ReadBlock;
+ pFileHander->fileHandler.Release = Sample_Release;
+ pFileHander->fileHandler.Truncate = Sample_Truncate;
+ pFileHander->fileHandler.WriteBlock = Sample_WriteBlock;
+
+ free(pszURL);
+ return &pFileHander->fileHandler;
+}
+
+FPDF_BOOL Sample_GetFilePath(struct _FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* pFileHandler, FPDF_BSTR* path)
+{
+ CReaderVCView* pView = (CReaderVCView*)pThis;
+ if (!pView)
+ return NULL;
+
+ CString filePath = pView->GetFilePath();
+ FPDF_BStr_Set(path, filePath.GetBuffer(filePath.GetLength()), filePath.GetLength());
+
+ return TRUE;
+}
+
+void Sample_EmailTo(struct _FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* fileHandler, FPDF_WIDESTRING emailTo)
+{
+ MessageBoxW(NULL, (wchar_t*)emailTo, L"Sample_email", MB_OK);
+}
+
+void Sample_UploadTo(struct _FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* fileHandler, FPDF_WIDESTRING uploadTo)
+{
+ int iSize;
+ char* pszURL;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)uploadTo, -1, NULL, 0, NULL, NULL);
+ pszURL = (char*)malloc((iSize+1));
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)uploadTo, -1, pszURL, iSize, NULL, NULL);
+ CString strPath(pszURL);
+
+ CString strUploadPath = "C://test";
+ int pos = strPath.ReverseFind('.');
+ if (pos != -1){
+ CString suffix = strPath.Right(strPath.GetLength()-pos);
+ strUploadPath += suffix;
+ }
+
+ FILE* file = fopen(strUploadPath, "r");
+ if (file) {
+ int size = fileHandler->GetSize(fileHandler->clientData);
+ BYTE* buffer = (BYTE*)malloc(size);
+ fileHandler->ReadBlock(fileHandler->clientData, 0, buffer, size);
+ fwrite(buffer, size, 1, file);
+ fflush(file);
+ fclose(file);
+ free(buffer);
+ }
+
+ free(pszURL);
+}
+
+int Sample_GetAppName(struct _FPDF_FORMFILLINFO* pThis, void* appName, int length)
+{
+ if(appName == NULL || length <= 0)
+ {
+ CString name = AfxGetAppName();
+ return name.GetLength();
+ }
+ else
+ {
+ CString name = AfxGetAppName();
+ int len = name.GetLength();
+ if(length > len)
+ length = len;
+ memcpy(appName, name.GetBuffer(name.GetLength()), length);
+ return length;
+ }
+}
+
+int Sample_GetPlatform(struct _FPDF_FORMFILLINFO* pThis, void* platform, int length)
+{
+ if(platform == NULL || length <= 0)
+ {
+ return 3;
+ }
+ else
+ {
+ if(length > 3)
+ length = 3;
+ memcpy(platform, "win", length);
+ return length;
+ }
+}
+
+int Sample_GetDocumentCount(struct _FPDF_FORMFILLINFO* pThis)
+{
+ return 1;
+}
+
+int Sample_GetCurDocumentIndex(struct _FPDF_FORMFILLINFO* pThis)
+{
+ return 0;
+}
+
+FPDF_LPFILEHANDLER Sample_DownloadFromURL(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING URL)
+{
+ int iSize;
+ char* pszURL;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)URL, -1, NULL, 0, NULL, NULL);
+ pszURL = (char*)malloc((iSize+1));
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)URL, -1, pszURL, iSize, NULL, NULL);
+ CString strURL(pszURL);
+
+ CString bsLocal = strURL;
+ CReaderVCView::CreateLocalPath(bsLocal);
+
+ if (strURL.Left(7) == "http://")
+ {
+ CInternetSession sess;
+ CHttpFile *pFile = (CHttpFile*)sess.OpenURL(strURL);
+ int iLength = pFile->GetLength();
+ if (pFile == NULL || iLength < 1) return NULL;
+
+ FILE *pImageFile = fopen(bsLocal, "wb");
+
+ BYTE* pContent = new BYTE[iLength];
+ memset(pContent, 0, iLength);
+ int iRead = pFile->Read(pContent, iLength);
+
+ fwrite(pContent, 1, iLength, pImageFile);
+ free(pContent);
+ fflush(pImageFile);
+ fclose(pImageFile);
+
+ pFile->Close();
+ delete pFile;
+ sess.Close();
+ }
+ else if (strURL.Left(6) == "ftp://")
+ {
+ CInternetSession sess;
+ CFtpConnection* pConnect = sess.GetFtpConnection(bsLocal, "NULL", "NULL");
+ CInternetFile* pFile = pConnect->OpenFile(bsLocal);
+
+ int iLength = pFile->GetLength();
+ if (pFile == NULL || iLength < 1) return NULL;
+ FILE *pImageFile = fopen(bsLocal, "wb");
+
+ BYTE* pContent = new BYTE[iLength];
+ memset(pContent, 0, iLength);
+ int iRead = pFile->Read(pContent, iLength);
+
+ fwrite(pContent, 1, iLength, pImageFile);
+ free(pContent);
+ fflush(pImageFile);
+ fclose(pImageFile);
+
+ pFile->Close();
+ delete pFile;
+ sess.Close();
+ }
+
+ free(pszURL);
+
+ FPDF_FILE* fileWrap = new FPDF_FILE;
+ FILE* file = fopen(bsLocal, "r");
+ fileWrap->file = file;
+ fileWrap->fileHandler.clientData = fileWrap;
+ fileWrap->fileHandler.ReadBlock = Sample_ReadBlock;
+ fileWrap->fileHandler.GetSize = Sample_GetSize;
+ fileWrap->fileHandler.Flush = Sample_Flush;
+ fileWrap->fileHandler.Release = Sample_Release;
+ fileWrap->fileHandler.Truncate = Sample_Truncate;
+ fileWrap->fileHandler.WriteBlock = Sample_WriteBlock;
+
+ return &fileWrap->fileHandler;
+}
+
+FPDF_BOOL Sample_PostRequestURL(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsContentType, FPDF_WIDESTRING wsEncode, FPDF_WIDESTRING wsHeader, FPDF_BSTR* respone)
+{
+ int iSize;
+ char* pszURL;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsURL, -1, NULL, 0, NULL, NULL);
+ pszURL = (char*)malloc((iSize+1));
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsURL, -1, pszURL, iSize, NULL, NULL);
+ CString csURL(pszURL);
+
+ char* pszData;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsData, -1, NULL, 0, NULL, NULL);
+ pszData = (char*)malloc(iSize+1);
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsData, -1, pszData, iSize, NULL, NULL);
+ CString csData(pszData);
+
+ char* pszContentType;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsContentType, -1, NULL, 0, NULL, NULL);
+ pszContentType = (char*)malloc(iSize+1);
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsContentType, -1, pszContentType, iSize, NULL, NULL);
+ CString csContentType(pszContentType);
+
+ char* pszHeader;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsHeader, -1, NULL, 0, NULL, NULL);
+ pszHeader = (char*)malloc(iSize+1);
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsHeader, -1, pszHeader, iSize, NULL, NULL);
+ CString csHeader(pszHeader);
+
+ CString csApp = AfxGetAppName();
+ csApp += L"/1.0";
+ BOOL bRet = FALSE;
+ DWORD dwServiceType = 0, dwFlags = ICU_NO_META;
+ CString csServer, sObject, csUserName, csPassword;
+ INTERNET_PORT nPort = 0;
+
+ bRet = AfxParseURLEx(csURL, dwServiceType, csServer, sObject, nPort, csUserName, csPassword, dwFlags);
+ if (!bRet)
+ return bRet;
+
+ if (dwServiceType != AFX_INET_SERVICE_HTTP && dwServiceType != AFX_INET_SERVICE_HTTPS)
+ return bRet;
+
+ CString csObject = sObject;
+ CString csResponse;
+ bRet = CReaderVCView::HttpDataPost(csData, csApp, csObject, csServer, csUserName, csPassword, nPort,
+ dwServiceType == AFX_INET_SERVICE_HTTPS, csContentType, csHeader, csResponse);
+
+ FPDF_BStr_Init(respone);
+ FPDF_BStr_Set(respone, (FPDF_LPCSTR)csResponse.GetBuffer(csResponse.GetLength()), csResponse.GetLength());
+
+ free(pszURL);
+ free(pszData);
+ free(pszContentType);
+ free(pszHeader);
+
+ return true;
+}
+
+FPDF_BOOL Sample_PutRequestURL(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsEncode)
+{
+ int iSize;
+ char* pszURL;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsURL, -1, NULL, 0, NULL, NULL);
+ pszURL = (char*)malloc((iSize+1));
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsURL, -1, pszURL, iSize, NULL, NULL);
+ CString csURL(pszURL);
+
+ char* pszData;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsData, -1, NULL, 0, NULL, NULL);
+ pszData = (char*)malloc((iSize+1));
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsData, -1, pszData, iSize, NULL, NULL);
+ CString csData(pszData);
+
+ CString csApp = AfxGetAppName();
+ csApp += L"/1.0";
+ BOOL bRet = FALSE;
+ DWORD dwServiceType = 0, dwFlags = ICU_NO_META;
+ CString csServer, sObject, csUserName, csPassword;
+ INTERNET_PORT nPort = 0;
+
+ bRet = AfxParseURLEx(csURL, dwServiceType, csServer, sObject, nPort, csUserName, csPassword, dwFlags);
+ if (!bRet)
+ return bRet;
+
+ if (dwServiceType != AFX_INET_SERVICE_HTTP && dwServiceType != AFX_INET_SERVICE_HTTPS)
+ return bRet;
+
+ CString csObject = sObject;
+
+ bRet = CReaderVCView::HttpDataPut(csData, csApp, csObject, csServer, csUserName, csPassword, nPort, dwServiceType == AFX_INET_SERVICE_HTTPS);
+
+ free(pszData);
+ free(pszURL);
+ return TRUE;
+}
+
+FPDF_BOOL Sample_ShowFileDialog(struct _FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsTitle, FPDF_WIDESTRING wsFilter, FPDF_BOOL isOpen, FPDF_STRINGHANDLE pathArr)
+{
+ int iSize;
+ char* pszFilter;
+ iSize = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsFilter, -1, NULL, 0, NULL, NULL);
+ pszFilter = (char*)malloc((iSize+1));
+ WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wsFilter, -1, pszFilter, iSize, NULL, NULL);
+
+ CFileDialog fileOpen(isOpen, NULL,NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST, pszFilter);
+ // fileOpen.m_ofn.Flags|=OFN_ENABLEHOOK|OFN_ALLOWMULTISELECT;
+ if(fileOpen.DoModal()==IDCANCEL)
+ {
+ return FALSE;
+ }
+
+ POSITION pos;
+ pos=fileOpen.GetStartPosition();
+ CString csFile;
+ while(pos!=NULL)
+ {
+ csFile=fileOpen.GetNextPathName(pos);
+ FPDF_StringHandleAddString(pathArr, csFile.GetBuffer(csFile.GetLength()), csFile.GetLength());
+ }
+
+ free(pszFilter);
+ return TRUE;
+}
+
+FPDF_SYSTEMTIME CReaderVCView::GetLocalTimeImpl()
+{
+ FPDF_SYSTEMTIME sys;
+ time_t curTime;
+ time(&curTime);
+ tm* pTm = localtime(&curTime);
+ if(pTm)
+ {
+ sys.wDay = pTm->tm_mday;
+ sys.wDayOfWeek= pTm->tm_wday;
+ sys.wHour = pTm->tm_hour;
+ sys.wMilliseconds = 0;
+ sys.wMinute = pTm->tm_min;
+ sys.wMonth = pTm->tm_mon;
+ sys.wSecond = pTm->tm_sec;
+ sys.wYear = pTm->tm_year + 1900;
+ }
+
+ return sys;
+}
+
+int CReaderVCView::GetRotationImpl(FPDF_PAGE page)
+{
+ return m_nRotateFlag;
+}
+
+FPDF_PAGE CReaderVCView::GetPageImpl(FPDF_DOCUMENT document,int nPageIndex)
+{
+ FPDF_PAGE page = NULL;
+ m_pageMap.Lookup(nPageIndex, page);
+ if(page)
+ return page;
+ page = FPDF_LoadPage(document, nPageIndex);
+ FORM_OnAfterLoadPage(page, m_pApp);
+ m_pageMap.SetAt(nPageIndex, page);
+ return page;
+}
+
+FPDF_PAGE CReaderVCView::GetCurrentPageImpl(FPDF_DOCUMENT document)
+{
+ return m_pPage;
+}
+
+bool CReaderVCView::IsALTKeyDownImpl()
+{
+ return GetKeyState(VK_MENU) < 0;
+}
+bool CReaderVCView::IsINSERTKeyDownImpl()
+{
+ return GetKeyState(VK_INSERT) & 0x01;
+}
+bool CReaderVCView::IsSHIFTKeyDownImpl()
+{
+ return !((GetKeyState(VK_SHIFT)&0x8000) == 0);
+}
+bool CReaderVCView::IsCTRLKeyDownImpl()
+{
+ return GetKeyState(VK_CONTROL) < 0;
+}
+
+void CReaderVCView::OnChangeImpl()
+{
+
+}
+
+CString CReaderVCView::GetFilePath()
+{
+ CReaderVCDoc* pDoc = GetDocument();
+ if(pDoc)
+ {
+ return pDoc->m_strPDFName;
+ }
+ return "";
+}
+
+BOOL CReaderVCView::SubmitFormImpl(void* pBuffer, int nLength, CString strURL)
+{
+ CString tempFDFFile = "D://1.fdf";
+
+ if (pBuffer == NULL || nLength <= 0)
+ {
+ return FALSE;
+ }
+
+ CFile file;
+ if (file.Open(tempFDFFile, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary))
+ {
+ file.Write(pBuffer, nLength);
+ file.Close();
+ }
+
+ return TRUE;
+}
+
+int Sample_appResponse(struct _IPDF_JsPlatform* pThis, FPDF_WIDESTRING Question, FPDF_WIDESTRING Title,
+ FPDF_WIDESTRING Default, FPDF_WIDESTRING cLabel, FPDF_BOOL bPassword, void* response, int length)
+{
+ CReaderVCView* pView = (CReaderVCView*)pThis->m_pFormfillinfo;
+ FPDF_WIDESTRING wsResponse;
+
+ if (pView->m_pwsResponse && response != NULL)
+ {
+ wsResponse = (FPDF_WIDESTRING)pView->m_pwsResponse;
+ length = wcslen((const wchar_t*)wsResponse);
+ memcpy(response, wsResponse, length*sizeof(wchar_t));
+ pView->m_pwsResponse = NULL;
+ }
+ else
+ {
+ CJS_ResponseDlg dlg;
+ dlg.SetTitle(Title);
+ dlg.SetDefault(Default);
+ dlg.SetLabel(cLabel);
+ dlg.SetQuestion(Question);
+ dlg.SetIsVisible(bPassword);
+ int iRet = dlg.DoModal();
+
+ if (iRet == 1)
+ {
+ wsResponse = dlg.GetResponse();
+ length = wcslen((const wchar_t*)wsResponse);
+ pView->m_pwsResponse = new wchar_t[length+1];
+ memset(pView->m_pwsResponse, 0, length*sizeof(wchar_t));
+ memcpy(pView->m_pwsResponse, wsResponse, length*sizeof(wchar_t));
+ pView->m_pwsResponse[length] = L'\0';
+ }
+ }
+
+ return length*sizeof(wchar_t);
+}
+
+int Sample_appalert(struct _IPDF_JsPlatform* pThis, FPDF_WIDESTRING Msg, FPDF_WIDESTRING Title, int Type, int Icon)
+{
+ int nRet = 0;
+ if(pThis && pThis->m_pFormfillinfo)
+ {
+ CReaderVCView* pView = (CReaderVCView*)pThis->m_pFormfillinfo;
+ int msgType = MB_OK;
+ switch(Type)
+ {
+
+ case 1:
+ msgType = MB_OKCANCEL;
+ break;
+ case 2:
+ msgType = MB_YESNO;
+ break;
+ case 3:
+ msgType = MB_YESNOCANCEL;
+ break;
+ case 0:
+ default:
+ break;
+ }
+ nRet = MessageBoxW(pView->m_hWnd, (const wchar_t*)Msg, (const wchar_t*)Title, msgType);
+ switch(nRet)
+ {
+ case IDOK:
+ return 1;
+ case IDCANCEL:
+ return 2;
+ case IDNO:
+ return 3;
+ case IDYES:
+ return 4;
+ }
+ return nRet;
+ }
+ return nRet;
+}
+
+void Sample_appbeep(struct _IPDF_JsPlatform* pThis, int nType)
+{
+ MessageBeep(nType);
+ //AfxMessageBox("aaaa");
+}
+
+
+CString userSelFilePath;
+int Sample_fieldBrowse(struct _IPDF_JsPlatform* pThis,void* filePath, int length)
+{
+ if(userSelFilePath.IsEmpty())
+ {
+ CFileDialog fd(FALSE, "fdf");
+ if(fd.DoModal() == IDOK)
+ {
+ userSelFilePath = fd.GetPathName();
+
+ if(filePath == NULL || length == 0)
+ return userSelFilePath.GetLength() + 1;
+ else
+ return 0;
+ }
+ else
+ return 0;
+ }
+ else
+ {
+ int nLen = userSelFilePath.GetLength()+1;
+ if(length > nLen)
+ length = nLen;
+ memcpy(filePath, userSelFilePath.GetBuffer(length), length);
+ userSelFilePath.ReleaseBuffer();
+ userSelFilePath = "";
+ return length;
+ }
+}
+int Sample_docGetFilePath(struct _IPDF_JsPlatform* pThis, void* filePath, int length)
+{
+ if(pThis && pThis->m_pFormfillinfo)
+ {
+ CReaderVCView* pView = (CReaderVCView*)pThis->m_pFormfillinfo;
+ CString csFilePath = pView->GetFilePath();
+
+ int nbufflen = csFilePath.GetLength() + 1;
+ if(filePath == NULL || length == 0)
+ return nbufflen;
+
+ if(length > nbufflen)
+ length = nbufflen;
+ memcpy(filePath, csFilePath.GetBuffer(length), length);
+ csFilePath.ReleaseBuffer();
+
+ return length;
+
+ }
+ return 0;
+}
+
+void Sample_docSubmitForm(struct _IPDF_JsPlatform* pThis,void* formData, int length, FPDF_WIDESTRING URL)
+{
+ if(pThis && pThis->m_pFormfillinfo)
+ {
+ CReaderVCView *pView = (CReaderVCView*)pThis->m_pFormfillinfo;
+ if (pView)
+ {
+ pView->SubmitFormImpl(formData, length, "");
+ }
+ }
+}
+
+void Sample_gotoPage(struct _IPDF_JsPlatform* pThis, int nPageNum)
+{
+ if(pThis && pThis->m_pFormfillinfo)
+ {
+ CReaderVCView *pView = (CReaderVCView*)pThis->m_pFormfillinfo;
+ if (pView)
+ {
+ pView->GotoPage(nPageNum);
+ }
+ }
+}
+
+CReaderVCView::CReaderVCView()
+{
+ // TODO: add construction code here
+ m_pFram = NULL;
+ m_pExportPageDlg = NULL;
+ m_pDoc = NULL;
+ m_pPage = NULL;
+ m_nTotalPage = 0;
+ m_nRotateFlag = 0;
+ m_dbScaleFactor = 1.0f;
+ m_nPageIndex = -1;
+ m_dbPageWidth = 0.0f;
+ m_dbPageHeight = 0.0f;
+ m_nStartX = 0;
+ m_nStartY = 0;
+ m_nActualSizeX = 0;
+ m_nActualSizeY = 0;
+
+ //for search text
+ m_pTextPage = NULL;
+ m_FindInfo.m_strFind = _T("");
+ m_FindInfo.m_nFlag = -1;
+ m_FindInfo.m_nDirection = -1;
+ m_FindInfo.m_nStartPageIndex = -1;
+ m_FindInfo.m_nStartCharIndex = -1;
+ m_FindInfo.m_bFirst = TRUE;
+ m_FindInfo.m_pCurFindBuf = NULL;
+ m_pSCHHandle = NULL;
+
+ m_rtFind = NULL;
+ m_nRectNum = 0;
+
+ //for select text
+ m_bSelect = FALSE;
+ m_bHand = TRUE;
+ m_bSnap = FALSE;
+ m_bHasChar = FALSE;
+
+ m_ptLBDown.x = m_ptLBDown.y = 0;
+ m_ptLBUp.x = m_ptLBUp.y = 0;
+ m_ptOld.x = m_ptOld.y = 0;
+
+ m_nStartIndex = m_nEndIndex = m_nOldIndex = -1;
+ m_rtArray.RemoveAll();
+ m_rtOld.left = m_rtOld.right = m_rtOld.bottom = m_rtOld.top = 0;
+
+ m_nPosH = m_nPosV = -1;
+
+ // for links
+ m_pLink = NULL;
+ m_bBookmark = FALSE;
+
+ m_bmp = NULL;
+ m_pwsResponse = NULL;
+
+ this->FFI_Invalidate = Sample_Invalidate;
+ this->Release= Sample_Release;
+ this->FFI_SetTimer = Sample_SetTimer;
+ this->FFI_KillTimer = Sample_KillTimer;
+ this->FFI_GetLocalTime = Sample_GetLocalTime;
+ this->FFI_SetCursor = Sample_SetCursor;
+ this->FFI_OnChange = Sample_OnChange;
+ this->FFI_GetPage = Sample_GetPage;
+ this->FFI_GetCurrentPage = Sample_GetCurrentPage;
+ this->FFI_GetRotation = Sample_GetRotation;
+ this->FFI_OutputSelectedRect = Sample_OutputSelectedRect;
+ this->FFI_ExecuteNamedAction = Sample_ExecuteNamedAction;
+ this->FFI_OutputSelectedRect = NULL;
+ this->FFI_SetTextFieldFocus = NULL;
+ this->FFI_DoGoToAction = NULL;
+ this->FFI_DoURIAction = NULL;
+ this->FFI_DisplayCaret = Sample_DisplayCaret;
+ this->FFI_GetCurrentPageIndex = Sample_GetCurrentPageIndex;
+ this->FFI_SetCurrentPage = Sample_SetCurrentPage;
+ this->FFI_GotoURL = Sample_GotoURL;
+ this->FFI_GetPageViewRect = Sample_GetPageViewRect;
+ this->FFI_PopupMenu = Sample_PopupMenu;
+ this->FFI_OpenFile = Sample_OpenFile;
+ this->FFI_GetFilePath = Sample_GetFilePath;
+ this->FFI_EmailTo = Sample_EmailTo;
+ this->FFI_UploadTo = Sample_UploadTo;
+ this->FFI_GetPlatform = Sample_GetPlatform;
+ this->FFI_GetDocumentCount = Sample_GetDocumentCount;
+ this->FFI_GetCurDocumentIndex = Sample_GetCurDocumentIndex;
+ this->FFI_DownloadFromURL = Sample_DownloadFromURL;
+ this->FFI_PostRequestURL = Sample_PostRequestURL;
+ this->FFI_PutRequestURL = Sample_PutRequestURL;
+ this->FFI_ShowFileDialog = Sample_ShowFileDialog;
+ this->version = 1;
+
+ this->m_pJsPlatform = NULL;
+ this->m_pJsPlatform = new IPDF_JSPLATFORM;
+ memset(m_pJsPlatform, 0, sizeof(IPDF_JSPLATFORM));
+ this->m_pJsPlatform->app_alert = Sample_appalert;
+ this->m_pJsPlatform->app_response = Sample_appResponse;
+ this->m_pJsPlatform->app_beep = Sample_appbeep;
+ this->m_pJsPlatform->Field_browse =Sample_fieldBrowse;
+ this->m_pJsPlatform->Doc_getFilePath = Sample_docGetFilePath;
+ this->m_pJsPlatform->Doc_submitForm = Sample_docSubmitForm;
+ this->m_pJsPlatform->Doc_gotoPage = Sample_gotoPage;
+ this->m_pJsPlatform->m_pFormfillinfo = this;
+
+ m_pApp = NULL;
+}
+
+
+CReaderVCView::~CReaderVCView()
+{
+
+// FPDF_DestroyApp(m_App);
+
+ if(m_pTextPage != NULL)
+ {
+ FPDFText_ClosePage(m_pTextPage);
+ m_pTextPage = NULL;
+ }
+ if (m_pLink != NULL)
+ {
+ FPDFLink_CloseWebLinks(m_pLink);
+ m_pLink = NULL;
+ }
+
+ POSITION pos = m_pageMap.GetStartPosition();
+ while(pos)
+ {
+ int nIndex = 0;
+ FPDF_PAGE page = NULL;
+ m_pageMap.GetNextAssoc(pos, nIndex, page);
+
+ if (page)
+ {
+ FORM_OnBeforeClosePage(page, m_pApp);
+ FPDF_ClosePage(page);
+ }
+ }
+ m_pPage = NULL;
+
+ if (m_pDoc != NULL)
+ {
+ //Should strictly follow the reverse order of initialization .
+ FORM_DoDocumentAAction(m_pApp, FPDFDOC_AACTION_WC);
+ if(m_pApp)
+ FPDFDOC_ExitFormFillEnviroument(m_pApp);
+ FPDF_CloseDocument(m_pDoc);
+ m_pDoc = NULL;
+ }
+ if (m_FindInfo.m_pCurFindBuf != NULL)
+ {
+ delete []m_FindInfo.m_pCurFindBuf;
+ m_FindInfo.m_pCurFindBuf = NULL;
+ }
+ if (m_rtFind != NULL)
+ {
+ delete m_rtFind;
+ m_rtFind = NULL;
+ }
+ if(m_bmp != NULL)
+ {
+ FPDFBitmap_Destroy(m_bmp);
+ }
+
+ if (m_pwsResponse)
+ {
+ delete m_pwsResponse;
+ m_pwsResponse = NULL;
+ }
+
+ if(this->m_pJsPlatform)
+ delete m_pJsPlatform;
+
+ m_mapTimerFuns.RemoveAll();
+// m_formFiledInfo.Release();
+// }
+// m_rtArray.RemoveAll();
+}
+
+BOOL CReaderVCView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ // TODO: Modify the Window class or styles here by modifying
+ // the CREATESTRUCT cs
+ cs.style |= WS_MAXIMIZE | WS_VISIBLE | WS_VSCROLL |WS_HSCROLL;
+ return CView::PreCreateWindow(cs);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCView drawing
+
+void CReaderVCView::OnDraw(CDC* pDC)
+{
+ CReaderVCDoc* pDoc = GetDocument();
+ ASSERT_VALID(pDoc);
+ // TODO: add draw code for native data here
+ DrawPage(m_nRotateFlag, pDC);
+ DrawAllRect(pDC);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCView printing
+
+BOOL CReaderVCView::OnPreparePrinting(CPrintInfo* pInfo)
+{
+ // default preparation
+ return DoPreparePrinting(pInfo);
+}
+
+void CReaderVCView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+ // TODO: add extra initialization before printing
+}
+
+void CReaderVCView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
+{
+ // TODO: add cleanup after printing
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCView diagnostics
+
+#ifdef _DEBUG
+void CReaderVCView::AssertValid() const
+{
+ CView::AssertValid();
+}
+
+void CReaderVCView::Dump(CDumpContext& dc) const
+{
+ CView::Dump(dc);
+}
+
+CReaderVCDoc* CReaderVCView::GetDocument() // non-debug version is inline
+{
+ ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CReaderVCDoc)));
+ return (CReaderVCDoc*)m_pDocument;
+}
+#endif //_DEBUG
+
+/////////////////////////////////////////////////////////////////////////////
+// CReaderVCView message handlers
+
+BOOL CReaderVCView::LoadPDFPage(FPDF_DOCUMENT doc, int nIndex, CPoint pos)
+{
+ if(NULL == doc) return FALSE;
+ if(nIndex < 0) nIndex = 0;
+ if(nIndex > m_nTotalPage) nIndex = m_nTotalPage;
+
+ FORM_DoPageAAction(m_pPage, m_pApp, FPDFPAGE_AACTION_CLOSE);
+
+ m_pPage = NULL;
+ m_pageMap.Lookup(nIndex, m_pPage);
+ if(!m_pPage)
+ {
+ m_pPage = FPDF_LoadPage(doc, nIndex);
+ FORM_OnAfterLoadPage(m_pPage, m_pApp);
+ m_pageMap.SetAt(nIndex, m_pPage);
+ }
+ if(NULL == m_pPage) return FALSE;
+
+ FORM_DoPageAAction(m_pPage, m_pApp, FPDFPAGE_AACTION_OPEN);
+
+ m_nPageIndex = nIndex;
+ SetPageMetrics(m_pPage);
+
+ if (m_pTextPage != NULL)
+ {
+ FPDFText_ClosePage(m_pTextPage);
+ m_pTextPage = NULL;
+ }
+ m_pTextPage = FPDFText_LoadPage(m_pPage);
+
+
+ CChildFrame *pParent = (CChildFrame *)this->GetParentFrame();
+ if (pParent != NULL)
+ {
+ pParent->SetActiveView(this);
+ SyncScroll();
+ }
+
+ if(pos.x !=0 && pos.y != 0)
+ {
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(m_nActualSizeX * m_dbScaleFactor),
+ (int)(m_nActualSizeY * m_dbScaleFactor), m_nRotateFlag, pos.x, pos.y, &m_nStartX, &m_nStartY);
+ m_nStartX = -m_nStartX + 20;
+ m_nStartY = -m_nStartY + 20;
+
+ int nSizeX = 0;
+ int nSizeY = 0;
+ if (1 == m_nRotateFlag || 3 == m_nRotateFlag)
+ {
+ nSizeX = m_nActualSizeY;
+ nSizeY = m_nActualSizeX;
+ }
+ else
+ {
+ nSizeX = m_nActualSizeX;
+ nSizeY = m_nActualSizeY;
+ }
+ SCROLLINFO scrinfo;
+ GetScrollInfo(SB_VERT, &scrinfo);
+ scrinfo.nMin = 0;
+ scrinfo.nMax =(int) (nSizeY * m_dbScaleFactor + abs(m_nStartY));
+ SetScrollInfo(SB_VERT, &scrinfo);
+ SetScrollPos(SB_VERT, abs(m_nStartY), TRUE);
+
+ GetScrollInfo(SB_HORZ, &scrinfo);
+ scrinfo.nMin = 0;
+ scrinfo.nMax = (int)(nSizeX * m_dbScaleFactor + abs(m_nStartX));
+ SetScrollInfo(SB_HORZ, &scrinfo);
+ SetScrollPos(SB_HORZ, abs(m_nStartX), TRUE);
+ }
+ this->Invalidate(TRUE);
+// FPDFApp_SetPage(m_App, m_pPage);
+ return TRUE;
+
+}
+
+
+void CReaderVCView::InvalidateImpl(FPDF_PAGE page, double left, double top, double right, double bottom)
+{
+ int device_left, device_top, device_right, device_bottom;
+
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, left, top, &device_left, &device_top);
+
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, right, bottom, &device_right, &device_bottom);
+
+ CRect rc(device_left,device_top, device_right, device_bottom);
+// TRACE("left = %d\r\n", device_left);
+// TRACE("top = %d\r\n", device_top);
+// TRACE("right = %d\r\n", device_right);
+// TRACE("bottom = %d\r\n", device_bottom);
+ if(device_right-device_left>5)
+ TRACE("left=%d,top=%d,right=%d,bottom=%d\r\n",device_left,device_top,device_right,device_bottom);
+ ::InvalidateRect(m_hWnd, rc, FALSE);
+}
+
+void CReaderVCView::SetCaretImpl(FPDF_PAGE page,double page_x, double page_y, int nWidth, int nHeight)
+{
+
+}
+
+void CReaderVCView::ReleaseImpl()
+{
+
+}
+CMap<int, int,TimerCallback, TimerCallback> CReaderVCView::m_mapTimerFuns;
+int CReaderVCView::SetTimerImpl(int uElapse, TimerCallback lpTimerFunc)
+{
+ int nTimeID = ::SetTimer(NULL, 0, uElapse, TimerProc);
+ m_mapTimerFuns.SetAt(nTimeID, lpTimerFunc);
+ return nTimeID;
+}
+
+void CReaderVCView::KillTimerImpl(int nID)
+{
+ ::KillTimer(NULL, nID);
+ m_mapTimerFuns.RemoveKey(nID);
+}
+
+void CReaderVCView::SetCurorImpl(int nCursorType)
+{
+ HCURSOR hcur = LoadCursor(NULL, IDC_UPARROW);
+ switch(nCursorType)
+ {
+ case FXCT_ARROW:
+ case FXCT_NESW:
+ case FXCT_NWSE:
+ case FXCT_VBEAM:
+ case FXCT_HBEAM:
+ case FXCT_HAND:
+ // ::SetCursor(hcur);
+ break;
+ }
+}
+
+void CReaderVCView::PageToDeviceImpl(FPDF_PAGE page,double page_x,double page_y, int* device_x, int* device_y)
+{
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, page_x, page_y,device_x, device_y);
+}
+
+void CReaderVCView::DeviceToPageImpl(FPDF_PAGE page,int device_x, int device_y, double* page_x, double* page_y)
+{
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+ FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, device_x, device_y, page_x, page_y);
+
+}
+
+void CReaderVCView::SetPageMetrics(FPDF_PAGE pPage)
+{
+ m_nStartX = 10;
+ m_nStartY = 10;
+ if(NULL==pPage) return;
+ //get pdf page width an height;
+ m_dbPageWidth = FPDF_GetPageWidth(pPage);
+ m_dbPageHeight = FPDF_GetPageHeight(pPage);
+
+ CDC *pDC = GetDC();
+ int ix, iy;
+ ix = pDC->GetDeviceCaps(LOGPIXELSX);
+ iy = pDC->GetDeviceCaps(LOGPIXELSY);
+ m_nActualSizeX = (int)(m_dbPageWidth / 72 * ix + 0.5f);//convert pdf coordinates to device
+ m_nActualSizeY = (int)(m_dbPageHeight / 72 * iy + 0.5f);//convert pdf coordinates to device
+ ReleaseDC(pDC);
+
+}
+
+void CReaderVCView::SetScalFactor(double dbScal)
+{
+ if(dbScal > 64 ) m_dbScaleFactor = 64;
+ if( dbScal < 0) m_dbScaleFactor = 0.08f;
+ m_dbScaleFactor = dbScal;
+}
+void CReaderVCView::DrawPage(int nRotate, CDC *pDC)
+{
+ int nSizeX = m_nActualSizeX;
+ int nSizeY = m_nActualSizeY;
+
+ if (1 == nRotate || 3 == nRotate)
+ {
+ int temp = nSizeX;
+ nSizeX = nSizeY;
+ nSizeY = temp;
+ }
+
+ int nShowSizeX = (int)(nSizeX * m_dbScaleFactor + m_nStartX);
+ int nShowSizeY = (int)(nSizeY * m_dbScaleFactor + m_nStartY);
+
+
+ CRect rc;
+ pDC->GetClipBox(&rc);
+ FPDF_BITMAP bmptemp = FPDFBitmap_Create(rc.Width(), rc.Height(), 0);
+ int nClientWidth = FPDFBitmap_GetWidth(bmptemp);
+ int nClientHeight = FPDFBitmap_GetHeight(bmptemp);
+
+
+ FPDFBitmap_FillRect(bmptemp, 0, 0, nClientWidth, nClientHeight, 255,255,255, 0);
+ FPDF_RenderPageBitmap(bmptemp, m_pPage, m_nStartX-rc.left, m_nStartY-rc.top, (int)(nSizeX * m_dbScaleFactor), (int)(nSizeY * m_dbScaleFactor), nRotate,
+ FPDF_LCD_TEXT | FPDF_NO_NATIVETEXT);
+ FPDF_FFLDraw(m_pApp, bmptemp, m_pPage, m_nStartX-rc.left, m_nStartY-rc.top, (int)(nSizeX * m_dbScaleFactor), (int)(nSizeY * m_dbScaleFactor), nRotate,
+ FPDF_ANNOT | FPDF_LCD_TEXT | FPDF_NO_NATIVETEXT);
+
+ // m_pPage2 = FPDF_LoadPage(m_pDoc, 2);
+ // FPDF_RenderPageBitmap(m_bmp, m_pPage2, m_nStartX+500, m_nStartY, (int)(nSizeX * m_dbScaleFactor), (int)(nSizeY * m_dbScaleFactor), nRotate,
+ // FPDF_LCD_TEXT | FPDF_NO_NATIVETEXT);
+ // FPDF_FFLDraw(m_pApp, m_bmp, m_pPage2, m_nStartX+500, m_nStartY, (int)(nSizeX * m_dbScaleFactor), (int)(nSizeY * m_dbScaleFactor), nRotate,
+ // FPDF_ANNOT | FPDF_LCD_TEXT | FPDF_NO_NATIVETEXT);
+
+ int t = FPDFBitmap_GetStride(bmptemp);
+ int bufsize=FPDFBitmap_GetStride(bmptemp)*nClientHeight;
+ void* bmpbuf=FPDFBitmap_GetBuffer(bmptemp);
+ CDC MemDC;
+
+ CBitmap winbmp;
+ MemDC.CreateCompatibleDC(pDC);
+ if((HBITMAP)winbmp != NULL)
+ winbmp.DeleteObject();
+ if(HBITMAP(winbmp) == NULL)
+ {
+ winbmp.CreateCompatibleBitmap(pDC,nClientWidth,nClientHeight);
+ winbmp.SetBitmapBits(bufsize,bmpbuf);
+ }
+
+ MemDC.SelectObject(&winbmp);
+
+ pDC->BitBlt(rc.left , rc.top , nClientWidth, nClientHeight, &MemDC,0,0,SRCCOPY);
+ MemDC.DeleteDC();
+
+ FPDFBitmap_Destroy(bmptemp);
+
+
+ int size = m_SelectArray.GetSize();
+ for(int i=0; i<size; i++)
+ {
+
+
+ CRect rc = m_SelectArray.GetAt(i);
+
+ CDC memdc;
+ CBitmap bmp,*pOldBitmap;
+ memdc.CreateCompatibleDC(pDC);
+
+ bmp.CreateCompatibleBitmap(pDC,rc.Width(),rc.Height());
+
+ pOldBitmap = memdc.SelectObject(&bmp);
+
+ memdc.FillSolidRect(0,0,rc.Width(),rc.Height(),RGB(0,100,160));
+
+ BLENDFUNCTION bf;
+
+ bf.BlendOp = AC_SRC_OVER;
+
+ bf.BlendFlags = 0;
+
+ bf.SourceConstantAlpha = 0x4f;
+
+ bf.AlphaFormat = 0;
+
+
+
+ BOOL ret=AlphaBlend(pDC->GetSafeHdc(),rc.left,rc.top,rc.Width(),rc.Height(),memdc.GetSafeHdc(),0,0,rc.Width(),rc.Height(),bf);
+
+ memdc.SelectObject(pOldBitmap);
+ memdc.DeleteDC();
+ bmp.DeleteObject();
+
+ }
+ m_SelectArray.RemoveAll();
+
+
+
+
+}
+
+void CReaderVCView::GetNewPageSize(int &nsizeX, int &nsizeY)
+{
+ int nSizeX = m_nActualSizeX;
+ int nSizeY = m_nActualSizeY;
+ if (1 == m_nRotateFlag || 3 == m_nRotateFlag)
+ {
+ int temp = nSizeX;
+ nSizeX = nSizeY;
+ nSizeY = temp;
+ }
+ nsizeX = (int)(nSizeX*m_dbScaleFactor);
+ nsizeY = (int)(nSizeY*m_dbScaleFactor);
+}
+
+void CReaderVCView::OnDocFirstpage()
+{
+
+ if(m_nPageIndex == 0) return;
+ this->m_nPageIndex = 0;
+ this->LoadPDFPage(m_pDoc, 0);
+ DeleteAllRect();
+}
+
+void CReaderVCView::OnDocGotopage()
+{
+ CGotoPageDlg dlg;
+ dlg.DoModal();
+}
+
+void CReaderVCView::OnDocLastpage()
+{
+// FPDF_DOCUMENT doc = FPDF_LoadDocument("d:\\a1.pdf", "");
+// FPDF_PAGE page = FPDF_LoadPage(doc, 0);
+// FPDF_IMAGEOBJECT imgObject = FPDFPageObj_NewImgeObj(doc);
+// long ret = FPDFImageObj_LoadFromFileEx(&page, 1 ,
+// imgObject, "E:\\temp\\temp\\k.gif",TRUE
+// );
+// FPDFImageObj_SetMatrix(imgObject, 240, 0, 0, 160, 1*50, 0 );
+// FPDFPage_InsertObject(page, imgObject);
+// FPDFPage_GenerateContent(page);
+// FPDF_SaveAsFile(doc, "D:\\out.pdf", 0, NULL, 0, NULL, 0);
+// FPDF_ClosePage(page);
+// FPDF_CloseDocument(doc);
+// return;
+
+
+ if(m_nPageIndex == m_nTotalPage -1) return;
+ this->m_nPageIndex = m_nTotalPage -1;
+ LoadPDFPage(m_pDoc, m_nPageIndex);
+ DeleteAllRect();
+}
+
+void CReaderVCView::OnDocNextpage()
+{
+ m_nPageIndex ++ ;
+ m_nPageIndex %= m_nTotalPage;
+ LoadPDFPage(m_pDoc, m_nPageIndex);
+ DeleteAllRect();
+}
+
+void CReaderVCView::OnDocPrepage()
+{
+ m_nPageIndex --;
+ if(m_nPageIndex < 0) m_nPageIndex = m_nTotalPage-1;
+ LoadPDFPage(m_pDoc, m_nPageIndex);
+ DeleteAllRect();
+}
+
+void CReaderVCView::OnClockwise()
+{
+ m_nRotateFlag ++;
+ m_nRotateFlag %= 4;
+ LoadPDFPage(m_pDoc, m_nPageIndex);
+}
+
+void CReaderVCView::OnCounterclockwise()
+{
+ m_nRotateFlag --;
+ if (m_nRotateFlag < 0) m_nRotateFlag = 3;
+ LoadPDFPage(m_pDoc, m_nPageIndex);
+}
+
+BOOL CReaderVCView::SetPDFDocument(FPDF_DOCUMENT pDoc, int nPageNum)
+{
+ if(pDoc == NULL) return FALSE;
+
+ m_pApp = FPDFDOC_InitFormFillEnviroument(pDoc,this);
+ FPDF_LoadXFA(pDoc);
+
+ FORM_DoDocumentJSAction(m_pApp);
+ FORM_DoDocumentOpenAction(m_pApp);
+// FORM_OnAfterLoadDocument(m_pApp);
+ FPDF_SetFormFieldHighlightColor(m_pApp, 0, RGB(0,255, 0));
+ FPDF_SetFormFieldHighlightAlpha(m_pApp, 128);
+
+
+ m_pDoc = pDoc;
+ m_nTotalPage = nPageNum;
+ if(!LoadPDFPage(m_pDoc, 0)) return FALSE;
+
+ return TRUE;
+}
+
+void CReaderVCView::GotoPage(int index)
+{
+ if(index < 0 || index >= m_nTotalPage){MessageBoxA("Invalidate index");}
+ if(index == m_nPageIndex) return;
+ if(!LoadPDFPage(m_pDoc, index)) return;
+ DeleteAllRect();
+}
+
+void CReaderVCView::OnViewActualSize()
+{
+ m_nStartX = m_nStartY = 10;
+ ScalPage(1.0f);
+}
+
+void CReaderVCView::OnViewFitPage()
+{
+ m_nStartX = m_nStartY = 10;
+ CRect rect;
+ GetClientRect(rect);
+ double dbHeight = rect.Height();
+ double dbScal = dbHeight / m_nActualSizeY;
+ ScalPage(dbScal);
+}
+
+void CReaderVCView::OnViewFitWidth()
+{
+ m_nStartX = m_nStartY = 10;
+ CRect rect;
+ GetClientRect(rect);
+ double dbWidth= rect.Width();
+ double dbScal = dbWidth / m_nActualSizeX;
+ ScalPage(dbScal);
+}
+
+void CReaderVCView::OnViewZoomIn()
+{
+ double dbScal = m_dbScaleFactor;
+ dbScal += 0.25f;
+ if(dbScal > 6400.0f) return;
+ ScalPage(dbScal);
+
+}
+
+void CReaderVCView::OnViewZoomOut()
+{
+ double dbScal = m_dbScaleFactor;
+ dbScal -= 0.25f;
+ if(dbScal < 0.25f) return;
+ ScalPage(dbScal);
+}
+
+void CReaderVCView::OnViewZoomTo()
+{
+ CZoomDlg dlg;
+ dlg.DoModal();
+}
+
+void CReaderVCView::ScalPage(double dbScal)
+{
+ SetScalFactor(dbScal);
+ CChildFrame *pParent = (CChildFrame *)this->GetParentFrame();
+ if (pParent != NULL)
+ {
+ pParent->SetActiveView(this);
+ SyncScroll();
+ }
+ Invalidate(TRUE);
+}
+
+void CReaderVCView::OnEditFind()
+{
+ if(m_pTextPage == NULL)
+ {
+ AfxMessageBox("Sorry, the fpdftext.dll may has expired. For keeping on using the dll, please contact sales@foxitsoftware.com.");
+ return;
+ }
+ CFindDlg dlg;
+ dlg.DoModal();
+}
+
+void CReaderVCView::FindText(CString strFind, BOOL bCase, BOOL bWholeword, int Direction)
+{
+ CString str;
+ str = m_FindInfo.m_strFind;
+ int nFlag = 0;
+ if(bCase) { nFlag |= FPDF_MATCHCASE; }
+ if(bWholeword) { nFlag |= FPDF_MATCHWHOLEWORD; }
+
+ if(NULL == m_pTextPage) return;
+
+ if (strFind.Compare(str) != 0 || nFlag != m_FindInfo.m_nFlag)//new search
+ {
+ if (NULL == m_pTextPage) return;
+ if (NULL != m_pSCHHandle)
+ {
+ FPDFText_FindClose(m_pSCHHandle);
+ m_pSCHHandle = NULL;
+ }
+
+ int len = MultiByteToWideChar(CP_ACP, 0, strFind.GetBuffer(0), -1, NULL, NULL);
+ wchar_t *pBuf = new wchar_t[len];
+ memset(pBuf, 0, len*sizeof(wchar_t));
+ MultiByteToWideChar(CP_ACP, 0, strFind.GetBuffer(0), strFind.GetLength(), pBuf, len);
+ pBuf[len-1] = L'\0';
+ m_pSCHHandle = FPDFText_FindStart(m_pTextPage, (FPDF_WIDESTRING)pBuf, nFlag, 0);
+ if(NULL == m_pSCHHandle) return;
+
+ if (m_FindInfo.m_pCurFindBuf != NULL)
+ {
+ delete []m_FindInfo.m_pCurFindBuf;
+ m_FindInfo.m_pCurFindBuf = NULL;
+ }
+ m_FindInfo.m_pCurFindBuf = new wchar_t[len];
+ memset(m_FindInfo.m_pCurFindBuf, 0, len*sizeof(wchar_t));
+ memcpy(m_FindInfo.m_pCurFindBuf, pBuf, len*sizeof(wchar_t));
+
+ delete []pBuf;
+
+
+ //save the find info
+ m_FindInfo.m_strFind = strFind;
+ m_FindInfo.m_nFlag = nFlag;
+ m_FindInfo.m_nDirection = Direction;
+ m_FindInfo.m_nStartPageIndex = m_nPageIndex;
+ m_FindInfo.m_bFirst = TRUE;
+
+
+ }
+ FindNext(Direction);
+}
+
+void CReaderVCView::FindNext(int nDirection)
+{
+ if(NULL == m_pSCHHandle) return;
+ BOOL bResult = FALSE;
+
+ if (nDirection != m_FindInfo.m_nDirection)
+ {
+ m_FindInfo.m_nDirection = nDirection;
+ m_FindInfo.m_bFirst = TRUE;
+ }
+
+ if (0 == nDirection)// find down
+ {
+ bResult = FPDFText_FindNext(m_pSCHHandle);
+ }
+ if (1 == nDirection)
+ {
+ bResult = FPDFText_FindPrev(m_pSCHHandle);
+ }
+
+ while(!bResult){
+
+ if (m_rtFind != NULL)
+ {
+ delete [] m_rtFind;
+ m_rtFind = NULL;
+ }
+
+ if (0 == nDirection)
+ {
+ m_nPageIndex ++;
+ m_nPageIndex %= m_nTotalPage;
+ if(!LoadPDFPage(m_pDoc, m_nPageIndex)) return;
+ if (NULL == m_pTextPage) return;
+ if (NULL != m_pSCHHandle)
+ {
+ FPDFText_FindClose(m_pSCHHandle);
+ m_pSCHHandle = NULL;
+ }
+ m_pSCHHandle = FPDFText_FindStart(m_pTextPage, (FPDF_WIDESTRING)m_FindInfo.m_pCurFindBuf, m_FindInfo.m_nFlag, 0);
+ if(NULL == m_pSCHHandle) break;
+ bResult = FPDFText_FindNext(m_pSCHHandle);
+ if(!bResult && m_nPageIndex == m_FindInfo.m_nStartPageIndex) break;
+ }
+ else
+ {
+ m_nPageIndex --;
+ if (m_nPageIndex < 0) {m_nPageIndex = m_nTotalPage - 1;}
+ if(!LoadPDFPage(m_pDoc, m_nPageIndex)) return;
+ if (NULL == m_pTextPage) return;
+ if (NULL != m_pSCHHandle)
+ {
+ FPDFText_FindClose(m_pSCHHandle);
+ m_pSCHHandle = NULL;
+ }
+ m_pSCHHandle = FPDFText_FindStart(m_pTextPage, (FPDF_WIDESTRING)m_FindInfo.m_pCurFindBuf, m_FindInfo.m_nFlag, 0);
+ if(NULL == m_pSCHHandle) break;
+ bResult = FPDFText_FindPrev(m_pSCHHandle);
+ if(!bResult && m_nPageIndex == m_FindInfo.m_nStartPageIndex) break;
+ }
+ }//end while
+
+ if(!bResult)//find over
+ {
+ FPDFText_FindClose(m_pSCHHandle);
+ m_pSCHHandle = NULL;
+
+ if (m_rtFind != NULL)
+ {
+ delete [] m_rtFind;
+ m_rtFind = NULL;
+ }
+
+ m_FindInfo.m_bFirst = TRUE;
+ m_FindInfo.m_nDirection = -1;
+ m_FindInfo.m_nFlag = -1;
+ m_FindInfo.m_nStartCharIndex = -1;
+ m_FindInfo.m_nStartPageIndex = -1;
+ m_FindInfo.m_pCurFindBuf = NULL;
+ m_FindInfo.m_strFind = _T("");
+
+ MessageBox("Find complete!", "Find Infomation", MB_OK | MB_ICONINFORMATION);
+ return;
+ }
+
+
+
+ int index = FPDFText_GetSchResultIndex(m_pSCHHandle);
+ if (m_nPageIndex == m_FindInfo.m_nStartPageIndex && index == m_FindInfo.m_nStartCharIndex && !m_FindInfo.m_bFirst )
+ {
+ if (NULL != m_pSCHHandle)
+ {
+ FPDFText_FindClose(m_pSCHHandle);
+ m_pSCHHandle = NULL;
+ }
+ MessageBox("Find complete!", "Find Infomation", MB_OK | MB_ICONINFORMATION);
+ return;
+ }else{
+ CDC *pDC = GetDC();
+ DrawAllRect(pDC);//update
+
+ int nCount = FPDFText_GetSchCount(m_pSCHHandle);
+ int nRects = FPDFText_CountRects(m_pTextPage, index, nCount);
+ if (m_rtFind != NULL)
+ {
+ delete [] m_rtFind;
+ m_rtFind = NULL;
+ }
+ m_rtFind = new PDFRect[nRects];
+ m_nRectNum = nRects;
+ for (int i=0; i<nRects; i++)
+ {
+ double left, top, right, bottom;
+ FPDFText_GetRect(m_pTextPage, i, &left, &top, &right, &bottom);
+ m_rtFind[i].m_dbLeft = left;
+ m_rtFind[i].m_dbTop = top;
+ m_rtFind[i].m_dbRight = right;
+ m_rtFind[i].m_dbBottom = bottom;
+ }
+ DrawAllRect(pDC);//draw new rect
+ ReleaseDC(pDC);
+ }
+
+ if (m_FindInfo.m_bFirst)
+ {//find first string, store info;
+ m_FindInfo.m_bFirst = FALSE;
+ m_FindInfo.m_nStartCharIndex = index;
+ m_FindInfo.m_nStartPageIndex = m_nPageIndex;
+ }
+
+}
+
+void CReaderVCView::DrawReverse(CDC *pDC, CRect rect)
+{
+ CRect rt = rect;
+ rect.left = __min(rt.left, rt.right);
+ rect.right = __max(rt.left, rt.right);
+ rect.top = __min(rt.top, rt.bottom);
+ rect.bottom = __max(rt.top, rt.bottom);
+
+ ASSERT(pDC);
+ int bmp_width=abs(rect.Width());
+ int bmp_height=abs(rect.Height());
+ HBITMAP hbmp = CreateCompatibleBitmap(pDC->m_hDC, bmp_width, bmp_height);
+ CDC MemDC;
+ MemDC.CreateCompatibleDC(pDC);
+ HBITMAP holdbmp = (HBITMAP)MemDC.SelectObject(hbmp);
+ // copy screen DC to memory DC
+ BitBlt(MemDC, 0, 0, bmp_width, bmp_height, pDC->m_hDC, rect.left,rect.top, SRCCOPY);
+ MemDC.SelectObject(holdbmp);
+
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof bmi);
+ bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
+ bmi.bmiHeader.biBitCount = 24;
+ bmi.bmiHeader.biClrImportant = 0;
+ bmi.bmiHeader.biClrUsed = 0;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biHeight = bmp_height;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biSizeImage = 0;
+ bmi.bmiHeader.biWidth = bmp_width;
+ bmi.bmiHeader.biXPelsPerMeter = 0;
+ bmi.bmiHeader.biYPelsPerMeter = 0;
+
+ // get bitmap stream
+ int ret = GetDIBits(MemDC, hbmp, 0,bmp_height, NULL, &bmi, DIB_RGB_COLORS);
+
+ int size = bmi.bmiHeader.biSizeImage;
+
+ BYTE* pBits = new BYTE[size];
+ memset(pBits, 0, size);
+ ret = GetDIBits(MemDC, hbmp, 0,bmp_height, pBits, &bmi, DIB_RGB_COLORS);
+ ret = GetLastError();
+ DeleteObject(hbmp);
+ MemDC.DeleteDC();
+ for (int row = 0; row < bmp_height; row ++) {
+ int pitch = (bmp_width * 3 + 3) / 4 * 4;
+ int rowpos = row * pitch;
+ for(int col = 0; col < bmp_width; col ++){
+ int i = rowpos + col * 3;
+ pBits[i] = 255-pBits[i] ;
+ pBits[i + 1] = 255-pBits[i + 1];
+ pBits[i + 2] = 255-pBits[i + 2];
+ }
+ }
+ ret = SetDIBitsToDevice(pDC->m_hDC,rect.left,rect.top,bmp_width, bmp_height,0, 0, 0, bmp_height, pBits, &bmi, DIB_RGB_COLORS);
+ delete []pBits;
+
+}
+
+void CReaderVCView::DrawAllRect(CDC *pDC)
+{
+ int i;
+ int left, top, right, bottom;
+
+ int nSizeX = 0;
+ int nSizeY = 0;
+// int temp = 0;
+ if (1 == m_nRotateFlag || 3 == m_nRotateFlag)
+ {
+ nSizeX = m_nActualSizeY;
+ nSizeY = m_nActualSizeX;
+ }
+ else
+ {
+ nSizeX = m_nActualSizeX;
+ nSizeY = m_nActualSizeY;
+ }
+ ASSERT(pDC);
+ if (m_rtFind != NULL)
+ {
+ for (i=0; i<m_nRectNum; i++)
+ {
+
+ PDFRect rect = m_rtFind[i];
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nSizeX * m_dbScaleFactor),
+ (int)(nSizeY * m_dbScaleFactor), m_nRotateFlag, rect.m_dbLeft, rect.m_dbTop, &left, &top);
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nSizeX * m_dbScaleFactor),
+ (int)(nSizeY * m_dbScaleFactor), m_nRotateFlag, rect.m_dbRight, rect.m_dbBottom, &right, &bottom);
+ CRect rt(left, top, right, bottom);
+ DrawReverse(pDC, rt);
+
+ }
+ }
+
+ if (m_rtArray.GetSize() != 0)
+ {
+ for (i=0; i<m_rtArray.GetSize(); i++)
+ {
+ PDFRect rect = m_rtArray.GetAt(i);
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nSizeX * m_dbScaleFactor),
+ (int)(nSizeY * m_dbScaleFactor), m_nRotateFlag, rect.m_dbLeft, rect.m_dbTop, &left, &top);
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nSizeX * m_dbScaleFactor),
+ (int)(nSizeY * m_dbScaleFactor), m_nRotateFlag, rect.m_dbRight, rect.m_dbBottom, &right, &bottom);
+ CRect rt(left, top, right, bottom);
+ DrawReverse(pDC, rt);
+ }
+ }
+}
+
+void CReaderVCView::DeleteAllRect()
+{
+ CDC *pDC = GetDC();
+ DrawAllRect(pDC);
+ ReleaseDC(pDC);
+
+ if (m_rtFind != NULL)
+ {
+ delete []m_rtFind;
+ m_rtFind = NULL;
+ }
+
+ if (m_rtArray.GetSize() != 0)
+ {
+ m_rtArray.RemoveAll();
+ }
+}
+
+void CReaderVCView::OnFilePrint()
+{
+ CString strDoc = GetDocument()->GetTitle();
+ CPrintDialog dlg(FALSE, PD_PAGENUMS | PD_USEDEVMODECOPIES);
+ dlg.m_pd.nMinPage = dlg.m_pd.nFromPage =1;
+ dlg.m_pd.nMaxPage = dlg.m_pd.nToPage = m_nTotalPage;
+ if (dlg.DoModal() == IDOK)
+ {
+ int from_page, to_page;
+ if (dlg.PrintAll())
+ {
+ from_page = dlg.m_pd.nMinPage;
+ to_page = dlg.m_pd.nMaxPage;
+ }
+ else if (dlg.PrintRange())
+ {
+ from_page = dlg.GetFromPage();
+ to_page = dlg.GetToPage();
+ }
+ else if (dlg.PrintSelection())
+ {
+ from_page = to_page = m_nPageIndex + 1;
+ }
+
+ HDC printDC;
+ DOCINFO docInfo;
+
+ printDC = dlg.CreatePrinterDC();
+ if(NULL == printDC) return;
+ docInfo.cbSize = sizeof(DOCINFO);
+ docInfo.fwType = 0;
+ docInfo.lpszDatatype = NULL;
+ docInfo.lpszOutput = NULL;
+ docInfo.lpszDocName = strDoc;
+
+ if(StartDoc(printDC, &docInfo) <= 0) return;
+ //FPDF_DOCUMENT pDoc = NULL;
+ FPDF_PAGE pPage = NULL;
+ CString str;
+ for (int i=from_page-1; i<to_page; i++)
+ {
+ if(pPage != NULL)
+ {
+ FPDF_ClosePage(pPage);
+ pPage = NULL;
+ }
+ pPage = FPDF_LoadPage(m_pDoc, i);
+ double npagewidth = FPDF_GetPageWidth(m_pPage);
+ double npageheight = FPDF_GetPageHeight(m_pPage);
+
+ int logpixelsx,logpixelsy;
+ //calculate the page size
+ logpixelsx = GetDeviceCaps(printDC,LOGPIXELSX);
+ logpixelsy = GetDeviceCaps(printDC,LOGPIXELSY);
+ int nsizeX = (int)(npagewidth / 72 *logpixelsx + 0.5f);
+ int nsizeY = (int)(npageheight / 72 *logpixelsy + 0.5f);
+
+ if(StartPage(printDC) <= 0)
+ {
+ str.Format("one error occured when start the page %d", i);
+ MessageBox(str);
+ return;
+ }
+
+ //render to print device
+ FPDF_RenderPage(printDC, pPage, m_nStartX, m_nStartY, nsizeX, nsizeY, m_nRotateFlag, 0);
+
+ if(EndPage(printDC) <= 0)
+ {
+ str.Format("one error occured when close the page %d", i);
+ MessageBox(str);
+ return;
+ }
+
+ }//end for
+ EndDoc(printDC);
+ if(!DeleteDC(printDC))// delete printDC
+ MessageBox("can not delete the printer");
+ }
+}
+
+void CReaderVCView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+ // TODO: Add your message handler code here and/or call default
+
+ double page_x = 0;
+ double page_y = 0;
+ DeviceToPage(point, page_x, page_y);
+
+ if(m_pApp)
+ {
+ FPDF_BOOL b= FORM_OnLButtonDown(m_pApp, m_pPage,ComposeFlag(),page_x, page_y);
+ if(b)
+ return;
+ }
+ DeleteAllRect();
+ LoadMyCursor(1);
+ m_ptLBDown = point;
+
+
+ if (m_bSelect)
+ {
+ m_bHasChar = GetCharIndexByPoint(point, m_nStartIndex);
+ CreateCaret(point);
+ }
+ if (m_bHand)
+ {
+ m_nPosH = GetScrollPos(SB_HORZ);//SetScrollPos(SB_VERT, point.y, TRUE);
+ m_nPosV = GetScrollPos(SB_VERT);
+ }
+ CView::OnLButtonDown(nFlags, point);
+}
+
+void CReaderVCView::OnLButtonUp(UINT nFlags, CPoint point)
+{
+
+ // TODO: Add your message handler code here and/or call default
+ double page_x = 0;
+ double page_y = 0;
+ DeviceToPage(point, page_x, page_y);
+
+ if(m_pApp)
+ {
+ if(FORM_OnLButtonUp(m_pApp, m_pPage,ComposeFlag(), page_x, page_y))
+ return;
+ }
+ LoadMyCursor();
+ m_ptLBUp = point;
+ if (m_bSelect || m_bSnap)
+ {
+ CDC *pDC = GetDC();
+ CPen *pOldPen;
+ CPen pen;
+ CBrush *pOldBr;
+ CRect rect;
+ pen.CreatePen(PS_DASH, 2, RGB(255,0,0));
+ pOldPen = pDC->SelectObject(&pen);
+ pOldBr = (CBrush*) (pDC->SelectStockObject(NULL_BRUSH));
+ int nOldRop = pDC->SetROP2(R2_XORPEN);
+ pDC->Rectangle(m_rtOld);
+ pDC->SetROP2(nOldRop);
+ m_rtOld.left = m_rtOld.top = m_rtOld.right = m_rtOld.bottom = 0;
+ ReleaseDC(pDC);
+ }
+
+ if (m_bSnap)
+ {
+ BOOL open = OpenClipboard();
+ if (open)
+ {
+ ::EmptyClipboard();
+ int bmpWidth = abs(point.x - m_ptLBDown.x);
+ int bmpHeight = abs(point.y - m_ptLBDown.y);
+ if (bmpHeight == 0 || bmpWidth == 0)return;
+ CRect bmpRect(m_ptLBDown, point);
+ CClientDC dc(this);
+ CBitmap *pBitmap = new CBitmap();
+ pBitmap->CreateCompatibleBitmap(&dc,bmpWidth,bmpHeight);
+ CDC memDC;
+ memDC.CreateCompatibleDC(&dc);
+ memDC.SelectObject(pBitmap);
+ CBrush whiteBrush(RGB(255,255,255));
+ //memDC.FillRect(bmpRect,&whiteBrush);
+ memDC.BitBlt(0, 0, bmpRect.Width(), bmpRect.Height(),&dc, bmpRect.left, bmpRect.top,SRCCOPY);
+ HBITMAP hBitmap = (HBITMAP) *pBitmap;
+ :: SetClipboardData(CF_BITMAP, hBitmap);
+ ::CloseClipboard();
+ MessageBox("The selected area has been copied to clipboard!");
+ delete pBitmap;
+ }
+ }
+
+ FPDF_LINK hlink=NULL;
+ double pdfx,pdfy;
+
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+
+ FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor),m_nRotateFlag,point.x,point.y,&pdfx,&pdfy);
+ hlink=FPDFLink_GetLinkAtPoint(m_pPage,pdfx,pdfy);
+ if (hlink)
+ {
+ FPDF_ACTION haction=NULL;
+ FPDF_DEST hLinkDest=NULL;
+ haction=FPDFLink_GetAction(hlink);
+ hLinkDest=FPDFLink_GetDest(m_pDoc,hlink);
+ if (haction)
+ {
+ int nActionType=FPDFAction_GetType(haction);
+ switch(nActionType)
+ {
+ case PDFACTION_UNSUPPORTED: // Unsupported action type
+ break;
+ case PDFACTION_GOTO: // Go to a destination within current document
+ {
+ FPDF_LINK hActLinkDest = FPDFAction_GetDest(m_pDoc,haction);
+ if (hActLinkDest)
+ {
+ int nPageIndex=FPDFDest_GetPageIndex(m_pDoc,hActLinkDest);
+ GotoPage(nPageIndex);
+ }
+ }
+ break;
+ case PDFACTION_REMOTEGOTO: // Go to a destination within another document
+
+ // FPDFAction_GetFilePath(...);
+ // .....
+ break;
+ case PDFACTION_URI: // Universal Resource Identifier, including web pages and
+ // other Internet based resources
+ // int nsize= FPDFAction_GetURIPath(m_pDoc,haction);
+ // ...
+ break;
+ case PDFACTION_LAUNCH: // Launch an application or open a file
+ // FPDFAction_GetFilePath(...)
+ break;
+ default :
+ break;
+ }
+ }
+ else if (hLinkDest)
+ {
+ int nPageIndex=FPDFDest_GetPageIndex(m_pDoc,hLinkDest);
+ GotoPage(nPageIndex);
+ }
+ }
+ CView::OnLButtonUp(nFlags, point);
+}
+
+void CReaderVCView::OnMouseMove(UINT nFlags, CPoint point)
+{
+ // TODO: Add your message handler code here and/or call default
+ double page_x = 0;
+ double page_y = 0;
+ DeviceToPage(point, page_x, page_y);
+
+ if(m_pApp)
+ {
+ if(FORM_OnMouseMove(m_pApp, m_pPage,ComposeFlag(), page_x, page_y))
+ return;
+ }
+ if (nFlags == MK_LBUTTON)
+ {
+ LoadMyCursor(1);
+ }else{LoadMyCursor();}
+
+ CDC *pDC = GetDC();
+
+ if (m_bSelect && nFlags == MK_LBUTTON)
+ {
+ if (m_bHasChar)
+ {
+ if (m_ptOld.x == 0 && m_ptOld.y == 0){m_ptOld = m_ptLBDown;}
+
+ int nIndex = 0;
+ if (!GetCharIndexByPoint(point, nIndex)) return;
+ if(nIndex == m_nEndIndex) return;
+
+ DrawAllRect(pDC);//update all rect
+
+ m_nEndIndex = nIndex;
+ GetRects(m_nStartIndex, m_nEndIndex); //get the rect and store into m_rtArray
+ DrawAllRect(pDC);//draw new rect
+ }
+ else
+ {
+ CPen *pOldPen;
+ CPen pen;
+ CBrush *pOldBr;
+ CRect rect;
+ pen.CreatePen(PS_DASH, 2, RGB(255,0,0));
+ pOldPen = pDC->SelectObject(&pen);
+ pOldBr = (CBrush*) (pDC->SelectStockObject(NULL_BRUSH));
+ int nOldRop = pDC->SetROP2(R2_XORPEN);
+ int nModle = pDC->Rectangle(m_rtOld);
+
+
+ DrawAllRect(pDC);//update all rect
+ rect = SelectSegment(m_ptLBDown, point);
+ DrawAllRect(pDC);
+
+ pDC->Rectangle(rect);
+ pDC->SelectObject(pOldBr);
+ pDC->SelectObject(pOldPen);
+ pDC->SetROP2(nModle);
+ m_rtOld = rect;
+ }
+ }
+
+ if (m_bHand && nFlags == MK_LBUTTON)
+ {
+ int curPos, prevPos;
+ //CChildFrame *pFrame = (CChildFrame *) GetParentFrame();
+
+ int dy = m_ptLBDown.y - point.y;
+ prevPos = m_nPosV;
+ curPos = prevPos + dy;
+ prevPos = SetScrollPos(SB_VERT, curPos, TRUE);
+ curPos = GetScrollPos(SB_VERT);
+ int distance;
+ distance = prevPos - curPos;
+ m_nStartY += distance;
+ ScrollWindow(0, distance);
+
+ dy = m_ptLBDown.x - point.x;
+ prevPos = m_nPosH;
+ curPos = prevPos + dy;
+ prevPos = SetScrollPos(SB_HORZ, curPos, TRUE);
+ curPos = GetScrollPos(SB_HORZ);
+ distance = prevPos - curPos;
+ m_nStartX += distance;
+ ScrollWindow(distance, 0);
+
+ }
+ if (m_bSnap && nFlags == MK_LBUTTON)
+ {
+ CPen *pOldPen;
+ CPen pen;
+ CBrush *pOldBr;
+ CRect rect(m_ptLBDown, point);
+ pen.CreatePen(PS_DASH, 2, RGB(255,0,0));
+ pOldPen = pDC->SelectObject(&pen);
+ pOldBr = (CBrush*) (pDC->SelectStockObject(NULL_BRUSH));
+ int nOldRop = pDC->SetROP2(R2_XORPEN);
+ int nModle = pDC->Rectangle(m_rtOld);
+
+ pDC->Rectangle(rect);
+ pDC->SelectObject(pOldBr);
+ pDC->SelectObject(pOldPen);
+ pDC->SetROP2(nModle);
+ m_rtOld = rect;
+
+ }
+
+ FPDF_LINK hlink=NULL;
+ double pdfx,pdfy;
+
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+
+ FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor),m_nRotateFlag,point.x,point.y,&pdfx,&pdfy);
+ hlink=FPDFLink_GetLinkAtPoint(m_pPage,pdfx,pdfy);
+ if (hlink)
+ {
+ HCURSOR hCur = AfxGetApp()->LoadCursor(IDC_CURSOR4);
+ ::SetCursor(hCur);
+ }
+ ReleaseDC(pDC);
+//
+ CView::OnMouseMove(nFlags, point);
+}
+
+void CReaderVCView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ // TODO: Add your message handler code here and/or call default
+// double page_x = 0;
+// double page_y = 0;
+// DeviceToPage(point, page_x, page_y);
+
+ if(m_pApp)
+ {
+ if(FORM_OnKeyDown(m_pApp, m_pPage, nChar, ComposeFlag()))
+ return;
+ }
+ switch(nChar)
+ {
+ case 35:
+ OnDocLastpage();
+ break;
+ case 36:
+ OnDocFirstpage();
+ break;
+ case 37:
+ this->OnDocPrepage();
+ break;
+ case 39:
+ this->OnDocNextpage();
+ break;
+ case 38:
+
+ break;
+ case 40:
+
+ break;
+ default:
+ break;
+ }
+ CView::OnKeyDown(nChar, nRepCnt, nFlags);
+}
+
+void CReaderVCView::OnToolSnapshot()
+{
+ m_bSnap = TRUE;
+ m_bHand = FALSE;
+ m_bSelect = FALSE;
+ this->HideCaret();
+}
+
+void CReaderVCView::OnToolSelect()
+{
+ if(m_pTextPage == NULL)
+ {
+ AfxMessageBox("Sorry, the fpdftext.dll may has expired. For keeping on using the dll, please contact sales@foxitsoftware.com.");
+ return;
+ }
+ m_bSnap = FALSE;
+ m_bHand = FALSE;
+ m_bSelect = TRUE;
+}
+
+void CReaderVCView::OnToolHand()
+{
+ m_bSnap = FALSE;
+ m_bHand = TRUE;
+ m_bSelect = FALSE;
+ this->HideCaret();
+}
+
+void CReaderVCView::LoadMyCursor(int nflag)
+{
+ HCURSOR hCur;
+ if (nflag == 1)
+ {
+ if (m_bSelect)
+ {
+ hCur = AfxGetApp()->LoadCursor(IDC_CURSOR3);
+ }
+ else if (m_bSnap)
+ {
+ hCur = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
+ }
+ else
+ {
+ hCur = AfxGetApp()->LoadCursor(IDC_CURSOR1);
+ }
+ }
+ else if (m_bHand)
+ {
+ hCur = AfxGetApp()->LoadCursor(IDC_CURSOR2);
+ }
+ else if (m_bSelect)
+ {
+ hCur = AfxGetApp()->LoadCursor(IDC_CURSOR3);
+ }
+ else if (m_bSnap)
+ {
+ hCur = AfxGetApp()->LoadStandardCursor(IDC_CROSS);
+ }else
+ {
+ hCur = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
+ }
+ ::SetCursor(hCur);
+}
+
+BOOL CReaderVCView::DeviceToPage(CPoint pt, double& page_x, double& page_y)
+{
+// if(NULL == m_pTextPage) return FALSE;
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+// switch ( m_nRotateFlag % 4 )
+// {
+// case 0:
+// case 2:
+// {
+// FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, pt.x, pt.y, &page_x, &page_y);
+// break;
+// }
+// case 1:
+// case 3:
+// {
+// FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, m_nActualSizeY * m_dbScaleFactor,
+// m_nActualSizeX * m_dbScaleFactor, m_nRotateFlag, pt.x, pt.y, &page_x, &page_y);
+// break;
+// }
+// }
+
+ FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, pt.x, pt.y, &page_x, &page_y);
+ return TRUE;
+}
+
+BOOL CReaderVCView::PageToDevice(double page_x, double page_y, CPoint& pt)
+{
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+
+ FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, page_x, page_y, (int*)&pt.x, (int*)&pt.y);
+ return TRUE;
+}
+
+BOOL CReaderVCView::GetCharIndexByPoint(CPoint pt, int &nIndex)
+{
+ double page_x = 0.0f;
+ double page_y = 0.0f;
+
+ if(NULL == m_pTextPage) return FALSE;
+ int nActualRangeX = 0;
+ int nActualRangeY = 0;
+ if ( m_nRotateFlag % 2 == 0 )
+ {
+ nActualRangeX = m_nActualSizeX;
+ nActualRangeY = m_nActualSizeY;
+ }else{
+ nActualRangeX = m_nActualSizeY;
+ nActualRangeY = m_nActualSizeX;
+ }
+ FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+ (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, pt.x, pt.y, &page_x, &page_y);
+// FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, pt.x, pt.y, &page_x, &page_y);
+
+ nIndex = FPDFText_GetCharIndexAtPos(m_pTextPage, page_x, page_y, 10, 10);
+ if (-3 == nIndex || -1 == nIndex) return FALSE;
+ return TRUE;
+}
+
+void CReaderVCView::CreateCaret(CPoint pt)
+{
+ double a, b, c, d;
+ int nIndex = 0;
+ int nAcent = 0, nDecent = 0;
+ double orgx = 0.0f, orgy = 0.0f;
+ double fontsize = 0.0f;
+ int left = 0, right = 0;
+ int top = 0, bottom = 0;
+ //double left_char, right_char, top_char, bottom_char;//char bounding box
+ FPDF_FONT pfont = NULL;
+
+ if(!GetCharIndexByPoint(pt, nIndex)) return;
+ fontsize = FPDFText_GetFontSize(m_pTextPage, nIndex);
+// FPDFText_GetOrigin(m_pTextPage, nIndex, &orgx, &orgy);
+// pfont = FPDFText_GetFont(m_pTextPage, nIndex);
+// if(NULL == pfont) return;
+// nAcent = FPDFFont_GetAscent(pfont);
+// nDecent = FPDFFont_GetDescent(pfont);
+// FPDFText_GetMatrix(m_pTextPage, nIndex, &a, &b, &c, &d);
+// nAcent =(int)((nAcent * fontsize / 1000.0f) * d + orgy + 0.5f);
+// nDecent = (int)((nDecent * fontsize / 1000.0f) * d + orgy + 0.5f);
+//
+// int nActualRangeX = 0;
+// int nActualRangeY = 0;
+// if ( m_nRotateFlag % 2 == 0 )
+// {
+// nActualRangeX = m_nActualSizeX;
+// nActualRangeY = m_nActualSizeY;
+// }else{
+// nActualRangeX = m_nActualSizeY;
+// nActualRangeY = m_nActualSizeX;
+// }
+// FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+// (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, orgx, nAcent, &left, &top);
+//
+// FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+// (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, orgx, nDecent, &right, &bottom);
+//
+// // FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// // m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, orgx, nAcent, &left, &top);
+// //
+// // FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// // m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, orgx, nDecent, &right, &bottom);
+//
+// this->CreateSolidCaret(2, abs(top - bottom));
+//
+// /* FPDFText_GetCharBox(m_pTextPage, nIndex, &left_char, &right_char, &bottom_char, &top_char);
+//
+// FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, left_char, top_char, &left, &top);
+// FPDF_PageToDevice(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, right_char, bottom_char, &right, &bottom);*/
+// this->SetCaretPos(CPoint(left, top-2));
+// this->ShowCaret();
+
+
+}
+
+void CReaderVCView::GetRects(int nStart, int nEnd)
+{
+ int temp, nCount;
+ nCount = nEnd - nStart;
+ if (nCount < 0)
+ {
+ temp = nEnd;
+ nEnd = nStart;
+ nStart = temp;
+
+ nCount = abs(nCount);
+ }
+ nCount ++;
+
+ int num = FPDFText_CountRects(m_pTextPage, nStart, nCount);
+ if(num == 0) return;
+
+ if (m_rtArray.GetSize() > 0)
+ {
+ m_rtArray.RemoveAll();
+ }
+ PDFRect rect;
+ for (int i=0; i<num; i++)
+ {
+ FPDFText_GetRect(m_pTextPage, i, &rect.m_dbLeft, &rect.m_dbTop, &rect.m_dbRight, &rect.m_dbBottom);
+ m_rtArray.Add(rect);
+ }
+ return;
+}
+
+CRect CReaderVCView::SelectSegment(CPoint pt_lt, CPoint pt_rb)
+{
+ CRect rect(pt_lt, pt_rb);
+// double left, top, right, bottom;
+// int start_index = 0, nCount = 0;
+// int nRect = 0;
+//
+// int nActualRangeX = 0;
+// int nActualRangeY = 0;
+// if ( m_nRotateFlag % 2 == 0 )
+// {
+// nActualRangeX = m_nActualSizeX;
+// nActualRangeY = m_nActualSizeY;
+// }else{
+// nActualRangeX = m_nActualSizeY;
+// nActualRangeY = m_nActualSizeX;
+// }
+// FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+// (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, rect.left, rect.top, &left, &top);
+// FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, (int)(nActualRangeX * m_dbScaleFactor),
+// (int)(nActualRangeY * m_dbScaleFactor), m_nRotateFlag, rect.right, rect.bottom, &right, &bottom);
+//
+// // FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// // m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, rect.left, rect.top, &left, &top);
+// // FPDF_DeviceToPage(m_pPage, m_nStartX, m_nStartY, m_nActualSizeX * m_dbScaleFactor,
+// // m_nActualSizeY * m_dbScaleFactor, m_nRotateFlag, rect.right, rect.bottom, &right, &bottom);
+//
+// int num = FPDFText_CountBoundedSegments(m_pTextPage, left, top, right, bottom);
+//
+// if (m_rtArray.GetSize() > 0)
+// {
+// m_rtArray.RemoveAll();
+// }
+//
+// CDC *pDC = GetDC();
+// for (int i=0; i<num; i++)
+// {
+// FPDFText_GetBoundedSegment(m_pTextPage, i, &start_index, &nCount);
+// nRect = FPDFText_CountRects(m_pTextPage, start_index, nCount);
+//
+// PDFRect rect_select;
+// for (int j=0; j<num; j++)
+// {
+// FPDFText_GetRect(m_pTextPage, j, &rect_select.m_dbLeft, &rect_select.m_dbTop, &rect_select.m_dbRight, &rect_select.m_dbBottom);
+// m_rtArray.Add(rect_select);
+// }
+// }
+// ReleaseDC(pDC);
+ return rect;
+}
+
+void CReaderVCView::OnToolPdf2txt()
+{
+ // TODO: Add your command handler code here
+ if(m_pTextPage == NULL)
+ {
+ AfxMessageBox("Sorry, the fpdftext.dll may has expired. For keeping on using the dll, please contact sales@foxitsoftware.com.");
+ return;
+ }
+ CConvertDlg condlg;
+ if(condlg.DoModal() == IDOK)
+ {
+ int nFlag=condlg.m_nFlag;
+ CReaderVCDoc *pDoc = this->GetDocument();
+ CString pdfname=pDoc->m_strPDFName;
+ CString strname=pdfname,stem;
+ if (strname.Find(".pdf") != -1 || strname.Find(".PDF") != -1)
+ {
+ int startatr=strname.ReverseFind('\\');
+ stem=strname.Mid(startatr+1,strname.GetLength()-startatr-5);
+ }
+ CString defaultname=stem+".txt";
+
+ char szFilter[] = "Text File(*.txt)|*.txt";
+ CFileDialog dlg(FALSE, ".txt", defaultname, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, szFilter, NULL);
+
+ if (dlg.DoModal() == IDOK)
+ {
+// CString txtname=dlg.GetPathName();
+// BOOL bFlag=FPDFText_PDFToText(pdfname,txtname,nFlag,NULL);
+// if(! bFlag)
+// MessageBox("Convert Failure!");
+ }
+ }
+}
+
+void CReaderVCView::SyncScroll()
+{
+ CRect rect;
+ GetClientRect(rect);
+
+ int nSizeX = 0;
+ int nSizeY = 0;
+ //int temp = 0;
+
+ if (1 == m_nRotateFlag || 3 == m_nRotateFlag)
+ {
+ nSizeX = m_nActualSizeY;
+ nSizeY = m_nActualSizeX;
+ }
+ else
+ {
+ nSizeX = m_nActualSizeX;
+ nSizeY = m_nActualSizeY;
+ }
+
+ SCROLLINFO scrinfo;
+ scrinfo.cbSize = sizeof(SCROLLINFO);
+ GetScrollInfo(SB_HORZ, &scrinfo);
+ scrinfo.nMin =0;
+ scrinfo.nMax = (int)(nSizeX * m_dbScaleFactor);
+ scrinfo.nPage = (unsigned int)(__min(nSizeX * m_dbScaleFactor, rect.Width()));
+ if (nSizeX * m_dbScaleFactor < rect.Width()){scrinfo.fMask |= SIF_DISABLENOSCROLL;}
+ SetScrollInfo(SB_HORZ, &scrinfo);
+ SetScrollPos(SB_HORZ, 0);
+ //m_nPosH = nPosH;
+
+ GetScrollInfo(SB_VERT, &scrinfo);
+ scrinfo.nMin = 0;
+ scrinfo.nMax = (int)(nSizeY * m_dbScaleFactor);
+ scrinfo.nPage =(unsigned int)( __min(nSizeY * m_dbScaleFactor, rect.Height()));
+ if (nSizeY * m_dbScaleFactor < rect.Height()){scrinfo.fMask |= SIF_DISABLENOSCROLL;}
+ SetScrollInfo(SB_VERT, &scrinfo);
+ SetScrollPos(SB_VERT, 0);
+
+}
+
+void CReaderVCView::OnSize(UINT nType, int cx, int cy)
+{
+ CView::OnSize(nType, cx, cy);
+ SyncScroll();
+ if(m_bmp)
+ {
+ FPDFBitmap_Destroy(m_bmp);
+ m_bmp = NULL;
+ }
+
+ m_bmp = FPDFBitmap_Create(cx, cy, 0);
+
+ // TODO: Add your message handler code here
+}
+
+void CReaderVCView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ // TODO: Add your message handler code here and/or call default
+ int prevPos = GetScrollPos(SB_HORZ);
+ int curPos = prevPos;
+ int nMin, nMax, nPage;
+ GetScrollRange(SB_HORZ, &nMin, &nMax);
+ SCROLLINFO si;
+ GetScrollInfo(SB_HORZ, &si);
+ nPage = si.nPage;
+
+ switch(nSBCode)
+ {
+ case SB_TOP:
+ curPos = nMin;
+ break;
+ case SB_BOTTOM:
+ curPos = nMax;
+ break;
+ case SB_LINEUP:
+ curPos --;
+ break;
+ case SB_LINEDOWN:
+ curPos ++;
+ break;
+ case SB_ENDSCROLL:
+ return;
+ case SB_PAGEDOWN:
+ curPos += nPage;
+ break;
+ case SB_PAGEUP:
+ curPos -= nPage;
+ break;
+ case SB_THUMBPOSITION:
+ curPos = si.nTrackPos;
+ break;
+ case SB_THUMBTRACK:
+ curPos = si.nTrackPos;
+ break;
+ }
+
+ if (curPos < nMin) { curPos = nMin;}
+ if(curPos > nMax){ curPos = nMax;}
+ SetScrollPos(SB_HORZ, curPos);
+
+ int distance;
+ distance = prevPos - curPos;
+ m_nStartX += distance;
+ ScrollWindow(distance, 0);
+ CRect rect;
+ GetClientRect(rect);
+ CRect rtnew(rect.left, rect.top, rect.left+distance, rect.bottom);
+ InvalidateRect(&rtnew);
+
+ CView::OnHScroll(nSBCode, nPos, pScrollBar);
+}
+
+void CReaderVCView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+ // TODO: Add your message handler code here and/or call default
+ int prevPos = GetScrollPos(SB_VERT);
+ int curPos = prevPos;
+ int nMin, nMax, nPage;
+ GetScrollRange(SB_VERT, &nMin, &nMax);
+ SCROLLINFO si;
+ GetScrollInfo(SB_VERT, &si);
+ nPage = si.nPage;
+
+ switch(nSBCode)
+ {
+ case SB_TOP:
+ curPos = nMin;
+ break;
+ case SB_BOTTOM:
+ curPos = nMax;
+ break;
+ case SB_LINEUP:
+ curPos --;
+ break;
+ case SB_LINEDOWN:
+ curPos ++;
+ break;
+ case SB_ENDSCROLL:
+ return;
+ case SB_PAGEDOWN:
+ curPos += nPage;
+ break;
+ case SB_PAGEUP:
+ curPos -= nPage;
+ break;
+ case SB_THUMBPOSITION:
+ curPos = si.nTrackPos;
+ break;
+ case SB_THUMBTRACK:
+ curPos = si.nTrackPos;
+ break;
+ }
+
+ if (curPos < nMin) { curPos = nMin;}
+ if(curPos > nMax){ curPos = nMax;}
+ SetScrollPos(SB_VERT, curPos);
+
+ int distance;
+ distance = prevPos - curPos;
+ m_nStartY += distance;
+ ScrollWindow(0, distance);
+
+ CRect rect;
+ GetClientRect(rect);
+ CRect rtnew(rect.left, rect.bottom + distance, rect.right, rect.bottom);
+ CRect rtnew2(rect.left, rect.top, rect.right, rect.top + distance);
+ InvalidateRect(&rtnew);
+ InvalidateRect(&rtnew2);
+
+ CView::OnVScroll(nSBCode, nPos, pScrollBar);
+}
+
+void CReaderVCView::OnToolExtractlinks()
+{
+ if(m_pTextPage == NULL)
+ {
+ AfxMessageBox("Sorry, the fpdftext.dll may has expired. For keeping on using the dll, please contact sales@foxitsoftware.com.");
+ return;
+ }
+ CString strLink = _T("");
+ wchar_t *pBuf = NULL;
+ if(m_pLink != NULL)
+ {
+ FPDFLink_CloseWebLinks(m_pLink);
+ m_pLink = NULL;
+ }
+ m_pLink = FPDFLink_LoadWebLinks(m_pTextPage);
+ if(m_pLink == NULL) return;
+
+ int nCount = FPDFLink_CountWebLinks(m_pLink);
+ if (nCount == 0) return;
+ if (m_rtArray.GetSize()!=0)
+ {
+ m_rtArray.RemoveAll();
+ }
+ for (int i=0; i<nCount; i++)
+ {
+ int nlen = FPDFLink_GetURL(m_pLink, i, NULL, 0)+1;
+ pBuf = new wchar_t[nlen];
+ memset(pBuf, 0, nlen*sizeof(wchar_t));
+ FPDFLink_GetURL(m_pLink, i, (unsigned short*)pBuf, nlen);
+ pBuf[nlen-1] = L'\0';
+ int n = WideCharToMultiByte(CP_ACP, 0, pBuf, -1, NULL, NULL, NULL, NULL);
+ char *p = new char[n];
+ memset(p, 0, n);
+ WideCharToMultiByte(CP_ACP, 0, pBuf, nlen, p, n, NULL, NULL);
+ p[n-1] = '\0';
+ strLink += p;
+ strLink += "\r\n";
+ delete []pBuf;
+ delete []p;
+ int nRects = FPDFLink_CountRects(m_pLink, i);
+ for (int j=0; j<nRects; j++)
+ {
+ PDFRect rect;
+ FPDFLink_GetRect(m_pLink, i, j,
+ &rect.m_dbLeft, &rect.m_dbTop, &rect.m_dbRight, &rect.m_dbBottom);
+ m_rtArray.Add(rect);
+ }
+ }
+ CDC *pDC = GetDC();
+ DrawAllRect(pDC);
+ ReleaseDC(pDC);
+
+ MessageBox(strLink, "Web Links in this page");
+
+}
+
+void CReaderVCView::OnInitialUpdate()
+{
+ CView::OnInitialUpdate();
+
+ // TODO: Add your specialized code here and/or call the base class
+}
+
+void CReaderVCView::OnDestroy()
+{
+ CView::OnDestroy();
+ // TODO: Add your message handler code here
+}
+
+void CReaderVCView::OnUpdateDocFirstpage(CCmdUI* pCmdUI)
+{
+ if (0 == m_nPageIndex)
+ {
+ pCmdUI->Enable(FALSE);
+ }
+ else
+ {
+ pCmdUI->Enable(TRUE);
+ }
+
+}
+
+void CReaderVCView::OnUpdateDocLastpage(CCmdUI* pCmdUI)
+{
+ if (m_nPageIndex == m_nTotalPage - 1)
+ {
+ pCmdUI->Enable(FALSE);
+ }
+ else
+ {
+ pCmdUI->Enable(TRUE);
+ }
+
+}
+
+void CReaderVCView::OnUpdateDocNextpage(CCmdUI* pCmdUI)
+{
+ if (m_nPageIndex == m_nTotalPage - 1)
+ {
+ pCmdUI->Enable(FALSE);
+ }
+ else
+ {
+ pCmdUI->Enable(TRUE);
+ }
+
+}
+
+void CReaderVCView::OnUpdateDocPrepage(CCmdUI* pCmdUI)
+{
+ if (0 == m_nPageIndex)
+ {
+ pCmdUI->Enable(FALSE);
+ }
+ else
+ {
+ pCmdUI->Enable(TRUE);
+ }
+
+}
+
+void CReaderVCView::OnUpdateToolHand(CCmdUI* pCmdUI)
+{
+ // TODO: Add your command update UI handler code here
+ if (m_bHand)
+ {
+ pCmdUI->SetCheck(1);
+ }
+ else
+ {
+ pCmdUI->SetCheck(0);
+ }
+
+
+}
+
+void CReaderVCView::OnUpdateToolSnapshot(CCmdUI* pCmdUI)
+{
+ if (m_bSnap)
+ {
+ pCmdUI->SetCheck(1);
+ }
+ else
+ {
+ pCmdUI->SetCheck(0);
+ }
+
+}
+
+void CReaderVCView::OnUpdateToolSelect(CCmdUI* pCmdUI)
+{
+ if (m_bSelect)
+ {
+ pCmdUI->SetCheck(1);
+ }
+ else
+ {
+ pCmdUI->SetCheck(0);
+ }
+
+}
+
+void CReaderVCView::OnViewBookmark()
+{
+ // TODO: Add your command handler code here
+ CChildFrame* pParent = (CChildFrame*)GetParentFrame();
+ if(pParent == NULL) return;
+ if (m_bBookmark) {
+ pParent->m_wndSplitter.ShowColumn();
+
+ }else{
+ pParent->m_wndSplitter.HideColumn(0);
+ }
+ m_bBookmark = !m_bBookmark;
+}
+
+
+
+BOOL CReaderVCView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
+{
+ ScreenToClient(&pt);
+ // TODO: Add your message handler code here and/or call default
+ double page_x = 0;
+ double page_y = 0;
+ DeviceToPage(pt, page_x, page_y);
+
+ if(m_pApp)
+ {
+// FPDF_BOOL b= FORM_OnMouseWheel(m_pApp, m_pPage,ComposeFlag(),0,zDelta,page_x, page_y);
+// if(b)
+// return TRUE;
+ }
+
+ int curPosY = 0;
+ int prevPosY = 0;
+ int distanceY = 25;
+ if(zDelta > 0)
+ {
+ curPosY = GetScrollPos(SB_VERT);
+ prevPosY = SetScrollPos(SB_VERT, curPosY - distanceY, TRUE);
+ curPosY = GetScrollPos(SB_VERT);
+ distanceY = prevPosY - curPosY;
+ m_nStartY = m_nStartY + distanceY;
+ ScrollWindow(0, distanceY);
+ }
+ else
+ {
+ curPosY = GetScrollPos(SB_VERT);
+ prevPosY = SetScrollPos(SB_VERT, curPosY + distanceY, TRUE);
+ curPosY = GetScrollPos(SB_VERT);
+ distanceY = curPosY - prevPosY;
+ m_nStartY = m_nStartY - distanceY;
+ ScrollWindow(0, -distanceY);
+ }
+ return CView::OnMouseWheel(nFlags, zDelta, pt);
+}
+
+void CReaderVCView::OnContextMenu(CWnd* pWnd, CPoint point)
+{
+
+}
+
+void CReaderVCView::OnEditCopy()
+{
+
+ if(m_pTextPage == NULL)
+ {
+ AfxMessageBox("Sorry, the fpdftext.dll may has expired. For keeping on using the dll, please contact sales@foxitsoftware.com.");
+ return;
+ }
+ long left = 0;
+ long top = 0;
+ long right = 0;
+ long bottom = 0;
+ LPWSTR pBuff = NULL;
+ int buflen = 0;
+ CString csCopyText;
+
+ if(m_rtArray.GetSize() != 0)
+ {
+ for (int i=0; i<m_rtArray.GetSize(); i++)
+ {
+ PDFRect rect = m_rtArray.GetAt(i);
+ buflen = FPDFText_GetBoundedText(m_pTextPage, rect.m_dbLeft, rect.m_dbTop, rect.m_dbRight,
+ rect.m_dbBottom, (unsigned short*)pBuff, 0) + 1;
+ if(buflen == 0)
+ return;
+ pBuff = new wchar_t[2*buflen];
+ memset(pBuff, 0, 2*buflen);
+
+ FPDFText_GetBoundedText(m_pTextPage, rect.m_dbLeft, rect.m_dbTop, rect.m_dbRight,
+ rect.m_dbBottom, (unsigned short*)pBuff, buflen);
+
+ int n = WideCharToMultiByte(CP_ACP, 0, pBuff, -1, NULL, NULL, NULL, NULL);
+ char *p = new char[n];
+ memset(p, 0, n);
+ WideCharToMultiByte(CP_ACP, 0, pBuff, buflen, p, n, NULL, NULL);
+ csCopyText = csCopyText + CString(p);
+ delete[] p;
+ }
+
+ ::OpenClipboard(NULL);
+ ::EmptyClipboard();
+ HANDLE hClip=GlobalAlloc(GMEM_MOVEABLE,csCopyText.GetLength()+1);
+ char* pBuf=(char*)GlobalLock(hClip);
+ strcpy(pBuf,csCopyText);
+ GlobalUnlock(hClip);
+ HANDLE hSuccess = SetClipboardData(CF_TEXT, hClip);
+ if(NULL != hSuccess)
+ AfxMessageBox("copy success!");
+ ::CloseClipboard();
+
+
+ }
+
+}
+
+void CReaderVCView::OnRenderbitmap()
+{
+
+}
+
+void CReaderVCView::OnExportPdfToBitmap()
+{
+ if (!m_pExportPageDlg)
+ {
+ m_pExportPageDlg=new CExportPage;
+ m_pExportPageDlg->Create(IDD_EXPORT_PAGE,this);
+ m_pExportPageDlg->InitDialogInfo(this);
+ m_pExportPageDlg->ShowWindow(SW_SHOW);
+ }
+ else
+ m_pExportPageDlg->ShowWindow(SW_SHOW);
+}
+
+BOOL CReaderVCView::PreTranslateMessage(MSG* pMsg)
+{
+ // TODO: Add your specialized code here and/or call the base class
+// PP_Event event;
+// if(pMsg->message == WM_LBUTTONDOWN)
+// {
+// event.type = PP_Event_Type_MouseDown;
+//
+// int xPos = (int)(WORD)(pMsg->lParam);
+// int yPos = (int)(WORD)((pMsg->lParam >> 16) & 0xFFFF);
+//
+// event.u.mouse.x = xPos;
+// event.u.mouse.y = yPos;
+// FPDF_FormFillEventMsg(m_pPage, event);
+// }
+// if(pMsg->message == WM_LBUTTONUP)
+// {
+// event.type = PP_Event_Type_MouseUp;
+//
+// int xPos = (int)(WORD)(pMsg->lParam);
+// int yPos = (int)(WORD)((pMsg->lParam >> 16) & 0xFFFF);
+//
+// event.u.mouse.x = xPos;
+// event.u.mouse.y = yPos;
+// FPDF_FormFillEventMsg(m_pPage, event);
+// }
+ return CView::PreTranslateMessage(pMsg);
+}
+
+void CReaderVCView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ // TODO: Add your message handler code here and/or call default
+ if(m_pApp)
+ {
+ if(FORM_OnChar(m_pApp, m_pPage, nChar, ComposeFlag()))
+ return ;
+ }
+ CView::OnChar(nChar, nRepCnt, nFlags);
+}
+
+void CReaderVCView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
+{
+ // TODO: Add your specialized code here and/or call the base class
+ ((CReaderVCApp*)AfxGetApp())->m_pActiveView = (CReaderVCView*)pActivateView;
+ CView::OnActivateView(bActivate, pActivateView, pDeactiveView);
+}
+
+void CReaderVCView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
+{
+ // TODO: Add your message handler code here and/or call default
+ if(m_pApp)
+ FORM_OnKeyUp(m_pApp, m_pPage, nChar, ComposeFlag());
+ CView::OnKeyUp(nChar, nRepCnt, nFlags);
+}
+
+
+int G_WriteBlock( FPDF_FILEWRITE* pThis, const void* pData, unsigned long size);
+class CSDK_FileWrite:public FPDF_FILEWRITE
+{
+public:
+ CSDK_FileWrite()
+ {
+ m_fp = NULL;
+ version = 0;
+ WriteBlock = G_WriteBlock;
+ }
+public:
+ FILE* m_fp;
+};
+int G_WriteBlock( FPDF_FILEWRITE* pThis, const void* pData, unsigned long size)
+{
+ CSDK_FileWrite* pFW = (CSDK_FileWrite*)pThis;
+ return fwrite(pData, sizeof(char), size, pFW->m_fp);
+}
+void CReaderVCView::OnFileSave()
+{
+ // TODO: Add your command handler code here
+ if(m_pDoc != NULL)
+ {
+ CFileDialog dlg(FALSE,"",NULL,NULL,"PDF(*.PDF)|*.PDF||All Files(*.*)|*.*");
+ if (dlg.DoModal() == IDOK)
+ {
+ CString strPDFName = dlg.GetPathName();
+
+ CSDK_FileWrite fw;
+ fw.m_fp = fopen(dlg.GetPathName(), "wb");
+
+ FPDF_SaveAsCopy(m_pDoc, &fw, 0);
+ fclose(fw.m_fp);
+// FPDF_SaveAsFile(m_pDoc, strPDFName.GetBuffer(strPDFName.GetLength()), 0, NULL, 0, NULL, 0);
+ }
+ }
+}
+
+
+
+void CReaderVCView::OnTestJS()
+{
+ // TODO: Add your command handler code here
+ //FPDF_WIDESTRING js = L"run=app.setInterval(\"app.alert(\\\"ok\\\")\");app.setTimeOut(\"app.clearInterval(run)\", 6000);";
+// FPDF_WIDESTRING js = L"app.alert(AFNumber_Keystroke(\'aaaaaaaaa\'))";
+// FPDF_WIDESTRING js = L"app.mailMsg(1)";
+ //FPDF_WIDESTRING js = L"app.setTimeOut(\"app.clearInterval(1)\", 6000);";
+ //FPDF_WIDESTRING js = L"t.1";
+// RunJS(m_pApp, js);
+ CTestJsDlg dlg;
+ dlg.init(m_pApp);
+ dlg.DoModal();
+}
+
+//This function is to simulate the pp event.
+#define PP_EVENT_MODIFIER_SHIFTKEY 1<<0
+#define PP_EVENT_MODIFIER_CONTROLKEY 1<<1
+#define PP_EVENT_MODIFIER_ALTKEY 1<<2
+unsigned int CReaderVCView::ComposeFlag()
+{
+ unsigned int nFlag = 0;
+ if(IsALTpressed())
+ nFlag = nFlag|PP_EVENT_MODIFIER_ALTKEY;
+ if(IsCTRLpressed())
+ nFlag = nFlag|PP_EVENT_MODIFIER_CONTROLKEY;
+ if(IsSHIFTpressed())
+ nFlag = nFlag|PP_EVENT_MODIFIER_SHIFTKEY;
+ return nFlag;
+}
+
+void CReaderVCView::OnPrintMetalfile()
+{
+ FPDF_PAGE page = FPDF_LoadPage(m_pDoc, 0);
+ if (!page) {
+ return;
+ }
+
+ HDC printer_dc = CreateDC("WINSPOOL", "Microsoft XPS Document Writer", NULL,
+ NULL);
+ if (!printer_dc) {
+ printf("Could not create printer DC\n");
+ return;
+ }
+ DOCINFO di = {0};
+ di.cbSize = sizeof(DOCINFO);
+ di.lpszDocName = "Foxit print test";
+ int job_id = StartDoc(printer_dc, &di);
+
+ StartPage(printer_dc);
+
+ SetGraphicsMode(printer_dc, GM_ADVANCED);
+ XFORM xform = {0, 0, 0, 0, 0, 0};
+ xform.eM11 = xform.eM22 = 2;
+ ModifyWorldTransform(printer_dc, &xform, MWT_LEFTMULTIPLY);
+
+ int dc_width = GetDeviceCaps(printer_dc, PHYSICALWIDTH);
+ int dc_height = GetDeviceCaps(printer_dc, PHYSICALHEIGHT);
+ HDC metafile_dc = CreateEnhMetaFile(printer_dc, NULL, NULL, NULL);
+ XFORM xform1 = {0, 0, 0, 0, 0, 0};
+ xform1.eM11 = xform1.eM22 = 0.5;
+ ModifyWorldTransform(metafile_dc, &xform1, MWT_LEFTMULTIPLY);
+ FPDF_RenderPage(metafile_dc, page, 0, 0, dc_width, dc_height, 0, 0);
+
+ HENHMETAFILE emf = CloseEnhMetaFile(metafile_dc);
+
+ ENHMETAHEADER header = {0};
+ GetEnhMetaFileHeader(emf, sizeof(header), &header);
+
+ PlayEnhMetaFile(printer_dc, emf, (RECT *)&header.rclBounds);
+
+ EndPage(printer_dc);
+ EndDoc(printer_dc);
+
+ DeleteEnhMetaFile(emf);
+ DeleteDC(printer_dc);
+
+}
+
+void CReaderVCView::CreateLocalPath(CString &csPath)
+{
+ csPath = "c://test.pdf";
+}
+
+BOOL CReaderVCView::HttpDataPost(CString csData, CString csAppName, CString csObject, CString csServer, CString csUserName, CString csPassword, INTERNET_PORT nPort , BOOL IsHTTPS, CString csContentType, CString csAddHeader, CString &csResponse)
+{
+ DWORD retCode = 0;
+ BOOL bRet = FALSE;
+ TRY
+ {
+ CInternetSession sess(csAppName);
+ CHttpConnection* pConnect = sess.GetHttpConnection(csServer, nPort, csUserName, csPassword);
+ if (pConnect == NULL)
+ return FALSE;
+
+ DWORD dwRequestFlags = INTERNET_FLAG_EXISTING_CONNECT;
+ if ( IsHTTPS == TRUE)
+ dwRequestFlags |= INTERNET_FLAG_SECURE;
+ CHttpFile* pHttpFile = pConnect->OpenRequest(CHttpConnection::HTTP_VERB_POST, csObject, NULL, 1, NULL, NULL, dwRequestFlags);
+ if (pHttpFile != NULL)
+ {
+ CString strData = csData;
+ DWORD dwLength = strData.GetLength();
+
+ CString strHeaders;
+ strHeaders.Format("Content-Type: %s\r\nContent-Length: %d\r\n", csContentType, dwLength);
+ strHeaders += csAddHeader;
+ pHttpFile->AddRequestHeaders(strHeaders);
+ DWORD dwTotalLength = dwLength + strHeaders.GetLength();
+
+resend:
+ bRet = pHttpFile->SendRequestEx(dwTotalLength);
+ pHttpFile->Write(csData, dwLength);
+
+ pHttpFile->QueryInfoStatusCode( retCode );
+ if (HTTP_STATUS_OK == retCode) //succ
+ {
+ char buf[4096] = {0};
+ UINT bytesRead = 0;
+ while( ( bytesRead = pHttpFile->Read( buf, 4095 ) ) > 0 )
+ {
+ buf[bytesRead] = '\0';
+ size_t aLen = strlen( buf ) + 1;
+ int wLen = MultiByteToWideChar( 936, 0, buf, aLen, NULL, 0 );
+
+ LPOLESTR lpw = new WCHAR [wLen];
+ MultiByteToWideChar( 936, 0, buf, aLen, lpw, wLen );
+ csResponse += lpw;
+ delete [] lpw;
+
+ memset( buf, 0, 4096 );
+ }
+ }
+ bRet = pHttpFile->EndRequest();
+ if (bRet)
+ {
+ // Handle any authentication dialogs.
+ if (NeedAuth(pHttpFile))
+ {
+ DWORD dwErr;
+ dwErr = pHttpFile->ErrorDlg(GetDesktopWindow(),
+ bRet ? ERROR_SUCCESS : GetLastError(),
+ FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
+ FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
+ FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
+ NULL);
+ if (dwErr == ERROR_INTERNET_FORCE_RETRY)
+ {
+ goto resend;
+ }
+ else if(dwErr == 0)
+ {
+ bRet = FALSE;
+ }
+ }
+ }
+ pHttpFile->Close();
+ delete pHttpFile;
+ }
+ pConnect->Close();
+ delete pConnect;
+ sess.Close();
+ }
+ CATCH_ALL(e)
+ {
+ return FALSE;
+ }
+ END_CATCH_ALL
+ return bRet;
+}
+
+BOOL CReaderVCView::HttpDataPut(CString csData, CString csAppName, CString csObject, CString csServer, CString csUserName, CString csPassword, INTERNET_PORT nPort, BOOL IsHTTPS)
+{
+ DWORD retCode = 0;
+ BOOL bRet = FALSE;
+ TRY
+ {
+ CInternetSession sess(csAppName);
+ CHttpConnection* pConnect = sess.GetHttpConnection(csServer, nPort, csUserName, csPassword);
+ if (pConnect == NULL)
+ return FALSE;
+
+ DWORD dwRequestFlags=INTERNET_FLAG_EXISTING_CONNECT;
+ if ( IsHTTPS== TRUE)
+ dwRequestFlags |= INTERNET_FLAG_SECURE;
+ CHttpFile* pHttpFile = pConnect->OpenRequest(CHttpConnection::HTTP_VERB_PUT, csObject,NULL,1,NULL,NULL,dwRequestFlags);
+ if (pHttpFile != NULL)
+ {
+resend:
+ CString strData = csData;
+ DWORD dwTotalLength = strData.GetLength();
+
+ bRet = pHttpFile->SendRequestEx(dwTotalLength);
+ pHttpFile->Write(csData, dwTotalLength);
+ bRet = pHttpFile->EndRequest();
+ if (bRet)
+ {
+ // Handle any authentication dialogs.
+ if (NeedAuth(pHttpFile))
+ {
+ DWORD dwErr;
+ dwErr = pHttpFile->ErrorDlg(GetDesktopWindow(),
+ bRet ? ERROR_SUCCESS : GetLastError(),
+ FLAGS_ERROR_UI_FILTER_FOR_ERRORS |
+ FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS |
+ FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,
+ NULL
+ );
+ if (dwErr == ERROR_INTERNET_FORCE_RETRY)
+ {
+ goto resend;
+ }
+ else if(dwErr == 0)
+ {
+ bRet = FALSE;
+ }
+ }
+ }
+ pHttpFile->QueryInfoStatusCode( retCode );
+ if (retCode != HTTP_STATUS_OK)
+ {
+ bRet = FALSE;
+ }
+ else
+ bRet = TRUE;
+
+ pHttpFile->Close();
+ delete pHttpFile;
+ }
+ pConnect->Close();
+ delete pConnect;
+ sess.Close();
+ }
+ CATCH_ALL(e)
+ {
+ return FALSE;
+ }
+ END_CATCH_ALL
+ return bRet;
+}
+
+BOOL CReaderVCView::NeedAuth(CHttpFile *pHttpFile)
+{
+ // Get status code.
+ DWORD dwStatus;
+ DWORD cbStatus = sizeof(dwStatus);
+ pHttpFile->QueryInfo
+ (
+ HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE,
+ &dwStatus,
+ &cbStatus,
+ NULL
+ );
+ // fprintf (stderr, "Status: %d\n", dwStatus);
+ // Look for 401 or 407.
+ DWORD dwFlags;
+ switch (dwStatus)
+ {
+ case HTTP_STATUS_DENIED:
+ dwFlags = HTTP_QUERY_WWW_AUTHENTICATE;
+ break;
+ case HTTP_STATUS_PROXY_AUTH_REQ:
+ dwFlags = HTTP_QUERY_PROXY_AUTHENTICATE;
+ break;
+ default:
+ return FALSE;
+ }
+ // Enumerate the authentication types.
+ BOOL fRet;
+ char szScheme[64];
+ DWORD dwIndex = 0;
+ do
+ {
+ DWORD cbScheme = sizeof(szScheme);
+ fRet = pHttpFile->QueryInfo
+ (dwFlags, szScheme, &cbScheme, &dwIndex);
+
+ //if (fRet)
+ //fprintf (stderr, "Found auth scheme: %s\n", szScheme);
+ }
+ while (fRet);
+ return TRUE;
+} \ No newline at end of file
diff --git a/xfa_test/FormFiller_Test/ReaderVCView.h b/xfa_test/FormFiller_Test/ReaderVCView.h
new file mode 100644
index 0000000000..9e4e71b313
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ReaderVCView.h
@@ -0,0 +1,375 @@
+// ReaderVCView.h : interface of the CReaderVCView class
+//
+/////////////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_READERVCVIEW_H__9AFC449C_26D0_4906_ABAE_1298871862E2__INCLUDED_)
+#define AFX_READERVCVIEW_H__9AFC449C_26D0_4906_ABAE_1298871862E2__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "ExportPage.h"
+#include "afxtempl.h"
+#include <wininet.h>
+#include <afxinet.h>
+#include <afxctl.h>
+
+typedef struct
+{
+ CString m_strFind;
+ int m_nFlag;
+ int m_nDirection;
+ BOOL m_bFirst;
+ wchar_t *m_pCurFindBuf; //unicode code
+ int m_nStartPageIndex; // the page index for starting find
+ int m_nStartCharIndex; //start index
+}FindInfo;
+
+typedef struct
+{
+ double m_dbLeft;
+ double m_dbTop;
+ double m_dbRight;
+ double m_dbBottom;
+}PDFRect;
+
+#define IsALTpressed() (GetKeyState(VK_MENU) < 0)
+#define IsCTRLpressed() (GetKeyState(VK_CONTROL) < 0)
+#define IsSHIFTpressed() (GetKeyState(VK_SHIFT)&0x8000)
+#define IsINSERTpressed() (GetKeyState(VK_INSERT) & 0x01)
+// void Sample_PageToDevice(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page,double page_x,double page_y, int* device_x, int* device_y);
+//
+// void Sample_Invalidate(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page, double left, double top, double right, double bottom);
+//
+// void Sample_DeviceToPage(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page,int device_x, int device_y, double* page_x, double* page_y);
+//
+// void Sample_SetCaret(struct _FPDF_FORMFILLINFO* pThis,FPDF_PAGE page,double page_x, double page_y, int nWidth, int nHeight);
+//
+// void Sample_Release(struct _FPDF_FORMFILLINFO* pThis);
+//
+//
+// int Sample_SetTimer(struct _FPDF_FORMFILLINFO* pThis, int uElapse, TimerCallback lpTimerFunc);
+//
+// void Sample_KillTimer(struct _FPDF_FORMFILLINFO* pThis,int nID);
+//
+// void Sample_SetCursor(struct _FPDF_FORMFILLINFO* pThis,int nCursorType);
+//
+// void Sample_OnChange(struct _FPDF_FORMFILLINFO* pThis);
+//
+// FPDF_BOOL Sample_IsSHIFTKeyDown(struct _FPDF_FORMFILLINFO* pThis);
+//
+// FPDF_BOOL Sample_IsCTRLKeyDown(struct _FPDF_FORMFILLINFO* pThis);
+//
+// FPDF_BOOL Sample_IsALTKeyDown(struct _FPDF_FORMFILLINFO* pThis) ;
+//
+// FPDF_BOOL Sample_IsINSERTKeyDown(struct _FPDF_FORMFILLINFO* pThis) ;
+class CReaderVCDoc;
+
+typedef unsigned long FX_DWORD;
+static int CALLBACK FontEnumProc(const LOGFONTA *plf, const TEXTMETRICA *lpntme, FX_DWORD FontType, LPARAM lParam)
+{
+ FPDF_AddInstalledFont((void*)lParam, plf->lfFaceName, plf->lfCharSet);
+ return 1;
+}
+#define FXDWORD_FROM_MSBFIRST2(i) (((unsigned char)(i) << 24) | ((unsigned char)((i) >> 8) << 16) | ((unsigned char)((i) >> 16) << 8) | (unsigned char)((i) >> 24))
+class CSampleFontInfo : public FPDF_SYSFONTINFO
+{
+public:
+ CSampleFontInfo()
+ {
+ m_hDC = CreateDCA("DISPLAY", NULL, NULL, NULL);
+ }
+
+ HDC m_hDC;
+
+ void ReleaseImpl()
+ {
+ DeleteDC(m_hDC);
+ delete this;
+ }
+
+ void EnumFontsImpl(void* pMapper)
+ {
+ LOGFONTA lf;
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfFaceName[0] = 0;
+ lf.lfPitchAndFamily = 0;
+ ::EnumFontFamiliesExA(m_hDC, &lf, FontEnumProc, (LPARAM)pMapper, 0);
+ }
+
+ void* MapFontImpl(int weight, int bItalic, int charset, int pitch_family, const char* face, int* bExact)
+ {
+ return ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0,
+ charset, OUT_TT_ONLY_PRECIS, 0, 0, pitch_family, face);
+ }
+
+ unsigned long GetFontDataImpl(void* hFont, unsigned int table, unsigned char* buffer, unsigned long buf_size)
+ {
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ buf_size = ::GetFontData(m_hDC, FXDWORD_FROM_MSBFIRST2(table), 0, buffer, buf_size);
+ ::SelectObject(m_hDC, hOldFont);
+ if (buf_size == GDI_ERROR) return 0;
+ return buf_size;
+ }
+
+ unsigned long GetFaceNameImpl(void* hFont, char* buffer, unsigned long buf_size)
+ {
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ unsigned long ret = ::GetTextFaceA(m_hDC, buf_size, buffer);
+ ::SelectObject(m_hDC, hOldFont);
+ if (buf_size == GDI_ERROR) return 0;
+ return ret;
+ }
+
+ int GetFontCharsetImpl(void* hFont)
+ {
+ TEXTMETRIC tm;
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ ::GetTextMetrics(m_hDC, &tm);
+ ::SelectObject(m_hDC, hOldFont);
+ return tm.tmCharSet;
+ }
+
+ void DeleteFontImpl(void* hFont)
+ {
+ ::DeleteObject(hFont);
+ }
+};
+
+typedef struct _FPDF_FILE
+{
+ FPDF_FILEHANDLER fileHandler;
+ FILE* file;
+}FPDF_FILE;
+
+class CReaderVCView : public CView, public FPDF_FORMFILLINFO
+{
+protected: // create from serialization only
+ CReaderVCView();
+ DECLARE_DYNCREATE(CReaderVCView)
+
+// Attributes
+public:
+ CReaderVCDoc* GetDocument();
+ CChildFrame *m_pFram;
+// Operations
+public:
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CReaderVCView)
+ public:
+ virtual void OnDraw(CDC* pDC); // overridden to draw this view
+ virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
+ virtual void OnInitialUpdate();
+ virtual BOOL PreTranslateMessage(MSG* pMsg);
+ protected:
+ virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
+ virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
+ virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
+ //}}AFX_VIRTUAL
+
+// Implementation
+public:
+ CExportPage* m_pExportPageDlg;
+ FPDF_PAGE GetPage(){ return m_pPage;}
+ void SyncScroll();
+ CRect SelectSegment(CPoint pt_lt, CPoint pt_rb);
+ void GetRects(int nStart, int nEnd);
+ void CreateCaret(CPoint pt);
+ BOOL GetCharIndexByPoint(CPoint pt, int &nIndex);
+ void LoadMyCursor(int nflag = 0);
+ void DeleteAllRect();
+ void DrawAllRect(CDC *pDC);
+ void DrawReverse(CDC *pDC, CRect rect);
+ void FindNext(int nDirection);
+ void FindText(CString strFind, BOOL bCase, BOOL bWholeword, int Direction);
+ void ScalPage(double dbScal);
+ void GotoPage(int index);
+ BOOL SetPDFDocument(FPDF_DOCUMENT pDoc, int nPageNum);
+ void DrawPage(int nRotate, CDC *pDC);
+ void SetPageMetrics(FPDF_PAGE pPage);
+
+ void SetScalFactor(double dbScal);
+ void GetNewPageSize(int &nsizeX, int &nsizeY);
+ BOOL LoadPDFPage(FPDF_DOCUMENT doc, int nIndex, CPoint pos = CPoint(0,0));
+
+ FPDF_DOCUMENT GetPDFDoc(){ return m_pDoc;}
+ int GetTotalPages(){ return m_nTotalPage;}
+ BOOL DeviceToPage(CPoint pt, double& page_x, double& page_y);
+ BOOL PageToDevice(double page_x, double page_y, CPoint& pt);
+ int GetCurrentPageIndex() { return m_nPageIndex; }
+ static BOOL HttpDataPut(CString csData, CString csAppName, CString csObject, CString csServer,
+ CString csUserName, CString csPassword, INTERNET_PORT nPort, BOOL IsHTTPS);
+ static BOOL NeedAuth(CHttpFile *pHttpFile);
+ static BOOL HttpDataPost(CString csData, CString csAppName, CString csObject, CString csServer, CString csUserName,
+ CString csPassword, INTERNET_PORT nPort , BOOL IsHTTPS, CString csContentType, CString csAddHeader, CString &csResponse);
+ static void CreateLocalPath(CString &csPath);
+
+ virtual ~CReaderVCView();
+#ifdef _DEBUG
+ virtual void AssertValid() const;
+ virtual void Dump(CDumpContext& dc) const;
+#endif
+
+protected:
+public:
+ void PageToDeviceImpl(FPDF_PAGE page,double page_x,double page_y, int* device_x, int* device_y);
+ void DeviceToPageImpl(FPDF_PAGE page,int device_x, int device_y, double* page_x, double* page_y);
+ void InvalidateImpl(FPDF_PAGE page, double left, double top, double right, double bottom);
+ void OutputSelectedRectImpl(FPDF_PAGE page, double left, double top, double right, double bottom);
+ void SetCaretImpl(FPDF_PAGE page,double page_x, double page_y, int nWidth, int nHeight);
+ void ReleaseImpl();
+ int SetTimerImpl(int uElapse, TimerCallback lpTimerFunc);
+ void KillTimerImpl(int nID);
+ FPDF_SYSTEMTIME GetLocalTimeImpl();
+ void SetCurorImpl(int nCursorType);
+ void ExecuteNamedActionImpl(FPDF_BYTESTRING namedaction);
+ void OnChangeImpl();
+ bool IsSHIFTKeyDownImpl();
+ bool IsCTRLKeyDownImpl();
+ bool IsALTKeyDownImpl();
+ bool IsINSERTKeyDownImpl();
+ BOOL SubmitFormImpl(void* pBuffer, int nLength, CString strURL);
+ FPDF_PAGE GetPageImpl(FPDF_DOCUMENT document,int nPageIndex);
+ int GetRotationImpl(FPDF_PAGE page);
+ CString GetFilePath();
+ FPDF_PAGE GetCurrentPageImpl(FPDF_DOCUMENT document);
+// friend FPDF_DOCUMENT _FPDF_GetCurDocument(struct _FPDF_FORMFILLINFO* pThis);
+// friend FPDF_PAGE _FPDF_GetCurPage(struct _FPDF_FORMFILLINFO* pThis);
+private:
+// FPDF_APP m_App;
+// FPDF_FORMFILLINFO m_formFiledInfo;
+private:
+// FPDF_APP GetFPDFApp() {return m_App;}
+ unsigned int ComposeFlag();
+private:
+ CMap<int, int, FPDF_PAGE, FPDF_PAGE> m_pageMap;
+ FPDF_FORMHANDLE m_pApp;
+ FPDF_BITMAP m_bmp;
+ //for render pdf
+ FPDF_DOCUMENT m_pDoc;
+ FPDF_PAGE m_pPage;
+ int m_nTotalPage;
+ int m_nRotateFlag;
+ double m_dbScaleFactor;
+ int m_nPageIndex;
+ double m_dbPageWidth;
+ double m_dbPageHeight;
+ int m_nStartX;
+ int m_nStartY;
+ int m_nActualSizeX;
+ int m_nActualSizeY;
+
+ //for search text
+ FPDF_TEXTPAGE m_pTextPage;
+ FindInfo m_FindInfo;
+ FPDF_SCHHANDLE m_pSCHHandle;
+ PDFRect * m_rtFind;
+ int m_nRectNum;
+
+ //for select text
+ BOOL m_bSelect;
+ BOOL m_bHand;
+ BOOL m_bSnap;
+ BOOL m_bHasChar; //whether can get a char when left button be clicked
+ CPoint m_ptLBDown;
+ CPoint m_ptLBUp;
+ CPoint m_ptOld;
+
+ int m_nStartIndex; //char index
+ int m_nOldIndex;
+ int m_nEndIndex;
+ CArray <PDFRect, PDFRect> m_rtArray;
+ CRect m_rtOld;
+
+ //
+ int m_nPosH;
+ int m_nPosV;
+
+ // for links
+ FPDF_PAGELINK m_pLink;
+
+ BOOL m_bBookmark;
+
+public:
+ wchar_t* m_pwsResponse;
+
+private:
+
+ CArray<CRect, CRect&> m_SelectArray;
+ static CMap<int, int,TimerCallback, TimerCallback> m_mapTimerFuns;
+public:
+ static void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime )
+ {
+ TimerCallback callback = NULL;
+ m_mapTimerFuns.Lookup(idEvent, callback);
+ if(callback)
+ (*callback)(idEvent);
+ }
+// Generated message map functions
+protected:
+ //{{AFX_MSG(CReaderVCView)
+ afx_msg void OnDocFirstpage();
+ afx_msg void OnDocGotopage();
+ afx_msg void OnDocLastpage();
+ afx_msg void OnDocNextpage();
+ afx_msg void OnDocPrepage();
+ afx_msg void OnClockwise();
+ afx_msg void OnCounterclockwise();
+ afx_msg void OnViewActualSize();
+ afx_msg void OnViewFitPage();
+ afx_msg void OnViewFitWidth();
+ afx_msg void OnViewZoomIn();
+ afx_msg void OnViewZoomOut();
+ afx_msg void OnViewZoomTo();
+ afx_msg void OnEditFind();
+ afx_msg void OnFilePrint();
+ afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+ afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+ afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+ afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnToolSnapshot();
+ afx_msg void OnToolSelect();
+ afx_msg void OnToolHand();
+ afx_msg void OnToolPdf2txt();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+ afx_msg void OnToolExtractlinks();
+ afx_msg void OnDestroy();
+ afx_msg void OnUpdateDocFirstpage(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateDocLastpage(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateDocNextpage(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateDocPrepage(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateToolHand(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateToolSnapshot(CCmdUI* pCmdUI);
+ afx_msg void OnUpdateToolSelect(CCmdUI* pCmdUI);
+ afx_msg void OnViewBookmark();
+ afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+ afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
+ afx_msg void OnEditCopy();
+ afx_msg void OnRenderbitmap();
+ afx_msg void OnExportPdfToBitmap();
+ afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
+ afx_msg void OnFileSave();
+ afx_msg void OnTestJS();
+ afx_msg void OnPrintMetalfile();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+#ifndef _DEBUG // debug version in ReaderVCView.cpp
+inline CReaderVCDoc* CReaderVCView::GetDocument()
+ { return (CReaderVCDoc*)m_pDocument; }
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_READERVCVIEW_H__9AFC449C_26D0_4906_ABAE_1298871862E2__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/StdAfx.cpp b/xfa_test/FormFiller_Test/StdAfx.cpp
new file mode 100644
index 0000000000..c358cc0c6d
--- /dev/null
+++ b/xfa_test/FormFiller_Test/StdAfx.cpp
@@ -0,0 +1,8 @@
+// stdafx.cpp : source file that includes just the standard includes
+// ReaderVC.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
+
diff --git a/xfa_test/FormFiller_Test/StdAfx.h b/xfa_test/FormFiller_Test/StdAfx.h
new file mode 100644
index 0000000000..7df16092d5
--- /dev/null
+++ b/xfa_test/FormFiller_Test/StdAfx.h
@@ -0,0 +1,99 @@
+// stdafx.h : include file for standard system include files,
+// or project specific include files that are used frequently, but
+// are changed infrequently
+//
+
+#if !defined(AFX_STDAFX_H__2BC4C1DE_4165_4967_AC3E_AE2EA2A4D2FD__INCLUDED_)
+#define AFX_STDAFX_H__2BC4C1DE_4165_4967_AC3E_AE2EA2A4D2FD__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC Automation classes
+#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
+#include <afxinet.h>
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h> // MFC support for Windows Common Controls
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+
+#include "../../include/fpdfview.h"
+#include "../../include/fpdfdoc.h"
+#include "../../include/fpdftext.h"
+#include "../../include/fpdfformfill.h"
+#include "../../include/fpdf_sysfontinfo.h"
+#include "../../include/fpdfsave.h"
+#include <afxcview.h>
+#include "afxtempl.h"
+
+#include "../../include/fpdfedit.h"
+
+#ifdef _DEBUG
+ #pragma comment(lib, "../../lib/dbg_w32_vc10/formfiller[dbg,w32,vc10].lib")
+ #pragma comment(lib, "../../lib/dbg_w32_vc10/fpdfsdk[dbg,w32,vc10].lib")
+ #pragma comment(lib, "../../lib/dbg_w32_vc10/fxedit[dbg,w32,vc10].lib")
+ #pragma comment(lib, "../../lib/dbg_w32_vc10/javascript[dbg,w32,vc10].lib")
+ #pragma comment(lib, "../../lib/dbg_w32_vc10/jsapi[dbg,w32,vc10].lib")
+ #pragma comment(lib, "../../lib/dbg_w32_vc10/pdfwindow[dbg,w32,vc10].lib")
+// #pragma comment(lib, "../../lib/dbg_w32_vc10/foxitopenpdf.lib")
+
+// #pragma comment(lib, "../../../../../../v8/build/Debug/lib/icui18n.lib")
+// #pragma comment(lib, "../../../../../../v8/build/Debug/lib/icuuc.lib")
+// #pragma comment(lib, "../../../../../../v8/build/Debug/lib/v8_base.ia32.lib")
+// #pragma comment(lib, "../../../../../../v8/build/Debug/lib/v8_nosnapshot.ia32.lib")
+// #pragma comment(lib, "../../../../../../v8/build/Debug/lib/v8_snapshot.lib")
+ #pragma comment(lib, "../../../v8/build/Debug/lib/icui18n.lib")
+ #pragma comment(lib, "../../../v8/build/Debug/lib/icuuc.lib")
+ #pragma comment(lib, "../../../v8/build/Debug/lib/v8_base.ia32.lib")
+ #pragma comment(lib, "../../../v8/build/Debug/lib/v8_nosnapshot.ia32.lib")
+ #pragma comment(lib, "../../../v8/build/Debug/lib/v8_snapshot.lib")
+
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fxcrt[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fxge[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fpdfdoc[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fpdfapi[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fxcodec[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fpdftext[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fdrm[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fxmath[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fxbarcode[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxcore/lib/dbg/x86_vc10/fxhal[dbg_x86_vc10].lib")
+
+ #pragma comment(lib, "../../../fxlib/fxjse/lib/dbg/x86_vc10/fxjse_bare[dbg_x86_vc10].lib")
+
+ #pragma comment(lib, "../../../fxlib/fwl/lib/dbg/x86_vc10/fwlbasewidget[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fwl/lib/dbg/x86_vc10/fwlcore[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fwl/lib/dbg/x86_vc10/fwltheme[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fwl/lib/dbg/x86_vc10/fwllightwidget[dbg_x86_vc10].lib")
+
+ #pragma comment(lib, "../../../fxlib/fxgraphics/lib/dbg/x86_vc10/fxgraphics[dbg_x86_vc10].lib")
+
+ #pragma comment(lib, "../../../fxlib/fgas/lib/dbg/x86_vc10/fgas[dbg_x86_vc10].lib")
+
+ #pragma comment(lib, "../../../fxlib/fee/lib/dbg/x86_vc10/fees[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fee/lib/dbg/x86_vc10/fx_wordbreaks[dbg_x86_vc10].lib")
+
+ #pragma comment(lib, "../../../fxlib/fdp/lib/dbg/x86_vc10/fde[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fdp/lib/dbg/x86_vc10/fdetto[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fdp/lib/dbg/x86_vc10/fdexml[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fdp/lib/dbg/x86_vc10/fdecss[dbg_x86_vc10].lib")
+
+ #pragma comment(lib, "../../../fxlib/fxfa/lib/dbg/x86_vc10/fxfa_app[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxfa/lib/dbg/x86_vc10/fxfa_fm2js[dbg_x86_vc10].lib")
+ #pragma comment(lib, "../../../fxlib/fxfa/lib/dbg/x86_vc10/fxfa_parser[dbg_x86_vc10].lib")
+
+#else
+ #pragma comment(lib, "../../lib/rel_w32_vc6/fpdfsdk.lib")
+#endif
+//#pragma comment(lib, "../../lib/fpdfsdk.dll")
+
+//#include "fpdfsdk_ext_wh.h"
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_STDAFX_H__2BC4C1DE_4165_4967_AC3E_AE2EA2A4D2FD__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/TestJsDlg.cpp b/xfa_test/FormFiller_Test/TestJsDlg.cpp
new file mode 100644
index 0000000000..30fb3a2efb
--- /dev/null
+++ b/xfa_test/FormFiller_Test/TestJsDlg.cpp
@@ -0,0 +1,58 @@
+// TestJsDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "readervc.h"
+#include "TestJsDlg.h"
+#include "../../include/fpdfformfill.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CTestJsDlg dialog
+
+
+CTestJsDlg::CTestJsDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CTestJsDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CTestJsDlg)
+ m_js = _T("");
+ //}}AFX_DATA_INIT
+}
+
+
+void CTestJsDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CTestJsDlg)
+ DDX_Text(pDX, IDC_EDIT1, m_js);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CTestJsDlg, CDialog)
+ //{{AFX_MSG_MAP(CTestJsDlg)
+ ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CTestJsDlg message handlers
+
+void CTestJsDlg::OnButton1()
+{
+ // TODO: Add your control notification handler code here
+ UpdateData(TRUE);
+ LPCTSTR lpStr = m_js.GetBuffer(m_js.GetLength());
+ int nLen = MultiByteToWideChar(CP_ACP, 0, lpStr, m_js.GetLength(), NULL, 0);
+ wchar_t* pbuf = new wchar_t[nLen+1];
+ MultiByteToWideChar(CP_ACP, 0, lpStr, m_js.GetLength(), pbuf, nLen);
+ pbuf[nLen] = 0;
+ m_js.ReleaseBuffer();
+// RunJS(m_handle,pbuf);
+ delete[] pbuf;
+}
diff --git a/xfa_test/FormFiller_Test/TestJsDlg.h b/xfa_test/FormFiller_Test/TestJsDlg.h
new file mode 100644
index 0000000000..b642937abe
--- /dev/null
+++ b/xfa_test/FormFiller_Test/TestJsDlg.h
@@ -0,0 +1,46 @@
+#if !defined(AFX_TESTJSDLG_H__084897F0_A03A_4D55_BDA2_98D40FB98A4F__INCLUDED_)
+#define AFX_TESTJSDLG_H__084897F0_A03A_4D55_BDA2_98D40FB98A4F__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// TestJsDlg.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CTestJsDlg dialog
+
+class CTestJsDlg : public CDialog
+{
+// Construction
+public:
+ CTestJsDlg(CWnd* pParent = NULL); // standard constructor
+ void init(void* handle) {m_handle = handle;}
+// Dialog Data
+ //{{AFX_DATA(CTestJsDlg)
+ enum { IDD = IDD_TEST_JS };
+ CString m_js;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CTestJsDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ void * m_handle;
+ // Generated message map functions
+ //{{AFX_MSG(CTestJsDlg)
+ afx_msg void OnButton1();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_TESTJSDLG_H__084897F0_A03A_4D55_BDA2_98D40FB98A4F__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/ZoomDlg.cpp b/xfa_test/FormFiller_Test/ZoomDlg.cpp
new file mode 100644
index 0000000000..65a19fe6f9
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ZoomDlg.cpp
@@ -0,0 +1,104 @@
+// ZoomDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "ReaderVC.h"
+#include "ZoomDlg.h"
+
+#include "MainFrm.h"
+#include "ChildFrm.h"
+#include "ReaderVCView.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CZoomDlg dialog
+
+
+CZoomDlg::CZoomDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CZoomDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CZoomDlg)
+ // NOTE: the ClassWizard will add member initialization here
+ //}}AFX_DATA_INIT
+}
+
+
+void CZoomDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CZoomDlg)
+ // NOTE: the ClassWizard will add DDX and DDV calls here
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CZoomDlg, CDialog)
+ //{{AFX_MSG_MAP(CZoomDlg)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+/////////////////////////////////////////////////////////////////////////////
+// CZoomDlg message handlers
+
+void CZoomDlg::OnCancel()
+{
+ // TODO: Add extra cleanup here
+
+ CDialog::OnCancel();
+}
+
+void CZoomDlg::OnOK()
+{
+ // TODO: Add extra validation here
+ CComboBox *pCmb = (CComboBox *)GetDlgItem(IDC_COMBO1);
+ int i = pCmb->GetCurSel();
+ int nScal = pCmb->GetItemData(i);
+ double dbScal = nScal / 100.0f;
+ m_pView->ScalPage(dbScal);
+ CDialog::OnOK();
+}
+
+BOOL CZoomDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ // TODO: Add extra initialization here
+ m_pView = (CReaderVCView *)(((CChildFrame *)((CMainFrame *)AfxGetMainWnd())->GetActiveFrame())->GetActiveView());
+ CComboBox *pCmb = (CComboBox *)GetDlgItem(IDC_COMBO1);
+ pCmb->AddString("-----25%-----");
+ pCmb->SetItemData(0, 25);
+ pCmb->AddString("-----50%-----");
+ pCmb->SetItemData(1, 50);
+ pCmb->AddString("-----75%-----");
+ pCmb->SetItemData(3, 75);
+ pCmb->AddString("-----100%----");
+ pCmb->SetItemData(3, 100);
+ pCmb->AddString("-----125%----");
+ pCmb->SetItemData(4, 125);
+ pCmb->AddString("-----200%----");
+ pCmb->SetItemData(5, 200);
+ pCmb->AddString("-----300%----");
+ pCmb->SetItemData(6, 300);
+ pCmb->AddString("-----400%----");
+ pCmb->SetItemData(7, 400);
+ pCmb->AddString("-----600%----");
+ pCmb->SetItemData(8, 600);
+ pCmb->AddString("-----800%----");
+ pCmb->SetItemData(9, 800);
+ pCmb->AddString("-----1200%----");
+ pCmb->SetItemData(10, 1200);
+ pCmb->AddString("-----1600%---");
+ pCmb->SetItemData(11, 160);
+ pCmb->AddString("-----3200%---");
+ pCmb->SetItemData(12, 3200);
+ pCmb->AddString("-----6400%----");
+ pCmb->SetItemData(13, 6400);
+ this->SetDlgItemTextA(IDC_COMBO1, "Select Zoom Factor");
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
diff --git a/xfa_test/FormFiller_Test/ZoomDlg.h b/xfa_test/FormFiller_Test/ZoomDlg.h
new file mode 100644
index 0000000000..15521c605e
--- /dev/null
+++ b/xfa_test/FormFiller_Test/ZoomDlg.h
@@ -0,0 +1,48 @@
+#if !defined(AFX_ZOOMDLG_H__B244E9E1_5278_4244_9D19_7307E1B76C15__INCLUDED_)
+#define AFX_ZOOMDLG_H__B244E9E1_5278_4244_9D19_7307E1B76C15__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// ZoomDlg.h : header file
+//
+
+/////////////////////////////////////////////////////////////////////////////
+// CZoomDlg dialog
+class CReaderVCView;
+class CZoomDlg : public CDialog
+{
+// Construction
+public:
+ CZoomDlg(CWnd* pParent = NULL); // standard constructor
+
+// Dialog Data
+ //{{AFX_DATA(CZoomDlg)
+ enum { IDD = IDD_DLG_ZOOMTO };
+ // NOTE: the ClassWizard will add data members here
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CZoomDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+ CReaderVCView *m_pView;
+ // Generated message map functions
+ //{{AFX_MSG(CZoomDlg)
+ virtual void OnCancel();
+ virtual void OnOK();
+ virtual BOOL OnInitDialog();
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_ZOOMDLG_H__B244E9E1_5278_4244_9D19_7307E1B76C15__INCLUDED_)
diff --git a/xfa_test/FormFiller_Test/res/BigHandCursor.cur b/xfa_test/FormFiller_Test/res/BigHandCursor.cur
new file mode 100644
index 0000000000..c03bff08bd
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/BigHandCursor.cur
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/Rd_SelText_Icon.bmp b/xfa_test/FormFiller_Test/res/Rd_SelText_Icon.bmp
new file mode 100644
index 0000000000..0a2b2f4858
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/Rd_SelText_Icon.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/Rd_SelText_Icon_Dis.bmp b/xfa_test/FormFiller_Test/res/Rd_SelText_Icon_Dis.bmp
new file mode 100644
index 0000000000..6e0e6742c3
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/Rd_SelText_Icon_Dis.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/ReaderVC.ico b/xfa_test/FormFiller_Test/res/ReaderVC.ico
new file mode 100644
index 0000000000..7eef0bcbe6
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/ReaderVC.ico
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/ReaderVC.rc2 b/xfa_test/FormFiller_Test/res/ReaderVC.rc2
new file mode 100644
index 0000000000..c81833479a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/ReaderVC.rc2
@@ -0,0 +1,13 @@
+//
+// READERVC.RC2 - resources Microsoft Visual C++ does not edit directly
+//
+
+#ifdef APSTUDIO_INVOKED
+ #error this file is not editable by Microsoft Visual C++
+#endif //APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Add manually edited resources here...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/xfa_test/FormFiller_Test/res/ReaderVCDoc.ico b/xfa_test/FormFiller_Test/res/ReaderVCDoc.ico
new file mode 100644
index 0000000000..2a1f1ae6ef
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/ReaderVCDoc.ico
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/SmallHandCursor.cur b/xfa_test/FormFiller_Test/res/SmallHandCursor.cur
new file mode 100644
index 0000000000..7bdff73ab3
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/SmallHandCursor.cur
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/Toolbar.bmp b/xfa_test/FormFiller_Test/res/Toolbar.bmp
new file mode 100644
index 0000000000..9598028a77
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/Toolbar.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/bookmark.bmp b/xfa_test/FormFiller_Test/res/bookmark.bmp
new file mode 100644
index 0000000000..c4a109cc7c
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/bookmark.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/bound.cur b/xfa_test/FormFiller_Test/res/bound.cur
new file mode 100644
index 0000000000..acb7f7a4bf
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/bound.cur
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/point.cur b/xfa_test/FormFiller_Test/res/point.cur
new file mode 100644
index 0000000000..deed42a4ed
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/point.cur
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_actual_size.bmp b/xfa_test/FormFiller_Test/res/tool_actual_size.bmp
new file mode 100644
index 0000000000..ae66eec0b5
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_actual_size.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_bookmark1.bmp b/xfa_test/FormFiller_Test/res/tool_bookmark1.bmp
new file mode 100644
index 0000000000..f8097551a9
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_bookmark1.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_clockwise.bmp b/xfa_test/FormFiller_Test/res/tool_clockwise.bmp
new file mode 100644
index 0000000000..2dc70bf8ca
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_clockwise.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_counterclockwise.bmp b/xfa_test/FormFiller_Test/res/tool_counterclockwise.bmp
new file mode 100644
index 0000000000..3b35661051
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_counterclockwise.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_first.bmp b/xfa_test/FormFiller_Test/res/tool_first.bmp
new file mode 100644
index 0000000000..30601ae878
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_first.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_fit_page.bmp b/xfa_test/FormFiller_Test/res/tool_fit_page.bmp
new file mode 100644
index 0000000000..04eaeb9240
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_fit_page.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_fit_width.bmp b/xfa_test/FormFiller_Test/res/tool_fit_width.bmp
new file mode 100644
index 0000000000..bd21478aba
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_fit_width.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hand1.bmp b/xfa_test/FormFiller_Test/res/tool_hand1.bmp
new file mode 100644
index 0000000000..9b15294df1
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hand1.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_about2.bmp b/xfa_test/FormFiller_Test/res/tool_hot_about2.bmp
new file mode 100644
index 0000000000..af274d42fa
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_about2.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_actual_size.bmp b/xfa_test/FormFiller_Test/res/tool_hot_actual_size.bmp
new file mode 100644
index 0000000000..6465e2158f
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_actual_size.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_bookmark1.bmp b/xfa_test/FormFiller_Test/res/tool_hot_bookmark1.bmp
new file mode 100644
index 0000000000..f73dd35999
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_bookmark1.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_clockwise.bmp b/xfa_test/FormFiller_Test/res/tool_hot_clockwise.bmp
new file mode 100644
index 0000000000..d48f3aab48
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_clockwise.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_counterclockwise.bmp b/xfa_test/FormFiller_Test/res/tool_hot_counterclockwise.bmp
new file mode 100644
index 0000000000..3539366bce
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_counterclockwise.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_first.bmp b/xfa_test/FormFiller_Test/res/tool_hot_first.bmp
new file mode 100644
index 0000000000..266018a79a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_first.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_first.xpm b/xfa_test/FormFiller_Test/res/tool_hot_first.xpm
new file mode 100644
index 0000000000..f89ac29059
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_first.xpm
@@ -0,0 +1,109 @@
+/* XPM */
+static char *tool_hot_first[] = {
+/* columns rows colors chars-per-pixel */
+"24 24 79 1",
+" c #3c659e",
+". c #3e689e",
+"X c #3b65a0",
+"o c #3e69a3",
+"O c #42679d",
+"+ c #466b9e",
+"@ c #4c6c9c",
+"# c #466ea3",
+"$ c #486da2",
+"% c #4473aa",
+"& c #4c74a6",
+"* c #4874ab",
+"= c #4b7aaf",
+"- c #4f7cb1",
+"; c #5072a3",
+": c #5678a7",
+"> c #527caf",
+", c #5c7da8",
+"< c green",
+"1 c #5d80ab",
+"2 c #5785b4",
+"3 c #5d88b6",
+"4 c #6487b0",
+"5 c #648db6",
+"6 c #678fba",
+"7 c #6c8eb5",
+"8 c #6593be",
+"9 c #6e90b5",
+"0 c #6e96bc",
+"q c #738aab",
+"w c #7b8da9",
+"e c #738cb0",
+"r c #7294b7",
+"t c #729abd",
+"y c #7a93b6",
+"u c #7e98ba",
+"i c #6694c0",
+"p c #759cc1",
+"a c #7c9fc3",
+"s c #74a1c6",
+"d c #76a4ca",
+"f c #7aa1c3",
+"g c #7ba7c9",
+"h c #7fa9cb",
+"j c #7faed0",
+"k c #8694ac",
+"l c #879db6",
+"z c #8a9db6",
+"x c #939daf",
+"c c #959fb1",
+"v c #8aa1b9",
+"b c #9ca4b3",
+"n c #a6acb6",
+"m c #b2b5ba",
+"M c #b8babd",
+"N c #87afcd",
+"B c #89b2cf",
+"V c #84b4d3",
+"C c #88b6d5",
+"Z c #91abc7",
+"A c #97b1cd",
+"S c #90bdda",
+"D c #a8b6cb",
+"F c #92c2dd",
+"G c #9cc8e0",
+"H c #a0c0d7",
+"J c #a6cfe6",
+"K c #a6d3e8",
+"L c #aad5ea",
+"P c #b0cfe2",
+"I c #b9dbeb",
+"U c #cac8c4",
+"Y c #c3dfed",
+"T c #c5e1ef",
+"R c #cbe2ef",
+"E c #d5e4ef",
+"W c #d2e7f2",
+"Q c #e8f6fa",
+"! c #feffff",
+/* pixels */
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<zlvz<<<<<<<<<<D<<<<<",
+"<<<<7NKp<<<<<<<<<k,<<<<<",
+"<<<<rCLa<<<<<<<<wNN<<<<<",
+"<<<<9hGt<<<<<<MqBKf<<<<<",
+"<<<<7gF0<<<<<nePJS0<<<<<",
+"<<<<7sV5<<<<xuWICV5<<<<<",
+"<<<<40d><<UkZQYVjd1<<<<<",
+"<<<<138><<kA!RVVd8><<<<<",
+"<<<<:>3&<<nyETVd83&<<<<<",
+"<<<<;*-$<<<mqHSi2>#<<<<<",
+"<<<<&#*+<<<<<q68-*#<<<<<",
+"<<<<@o%+<<<<<Uw&=%#<<<<<",
+"<<<<+X%+<<<<<<<k#%#<<<<<",
+"<<<<OX%.<<<<<<<<c+ <<<<<",
+"<<<<@ +@<<<<<<<<<b@<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<",
+"<<<<<<<<<<<<<<<<<<<<<<<<"
+};
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_fit_page.bmp b/xfa_test/FormFiller_Test/res/tool_hot_fit_page.bmp
new file mode 100644
index 0000000000..062cfcd90a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_fit_page.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_fit_width.bmp b/xfa_test/FormFiller_Test/res/tool_hot_fit_width.bmp
new file mode 100644
index 0000000000..07028eed44
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_fit_width.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_hand1.bmp b/xfa_test/FormFiller_Test/res/tool_hot_hand1.bmp
new file mode 100644
index 0000000000..d9d4a13a6a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_hand1.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_last.bmp b/xfa_test/FormFiller_Test/res/tool_hot_last.bmp
new file mode 100644
index 0000000000..9e63f72541
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_last.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_next.bmp b/xfa_test/FormFiller_Test/res/tool_hot_next.bmp
new file mode 100644
index 0000000000..494058444e
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_next.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_open1.bmp b/xfa_test/FormFiller_Test/res/tool_hot_open1.bmp
new file mode 100644
index 0000000000..353fade330
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_open1.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_prev.bmp b/xfa_test/FormFiller_Test/res/tool_hot_prev.bmp
new file mode 100644
index 0000000000..e83f29e338
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_prev.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_print.bmp b/xfa_test/FormFiller_Test/res/tool_hot_print.bmp
new file mode 100644
index 0000000000..e25ef8075a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_print.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_search.bmp b/xfa_test/FormFiller_Test/res/tool_hot_search.bmp
new file mode 100644
index 0000000000..a86b8d46da
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_search.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_snap_shot.bmp b/xfa_test/FormFiller_Test/res/tool_hot_snap_shot.bmp
new file mode 100644
index 0000000000..1552272429
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_snap_shot.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_zoomin.bmp b/xfa_test/FormFiller_Test/res/tool_hot_zoomin.bmp
new file mode 100644
index 0000000000..48cb3c958d
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_zoomin.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_hot_zoomout.bmp b/xfa_test/FormFiller_Test/res/tool_hot_zoomout.bmp
new file mode 100644
index 0000000000..02c37e468a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_hot_zoomout.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_last.bmp b/xfa_test/FormFiller_Test/res/tool_last.bmp
new file mode 100644
index 0000000000..4ac5be89fc
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_last.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_next.bmp b/xfa_test/FormFiller_Test/res/tool_next.bmp
new file mode 100644
index 0000000000..b77cc70dde
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_next.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_prev.bmp b/xfa_test/FormFiller_Test/res/tool_prev.bmp
new file mode 100644
index 0000000000..c2b2e377ec
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_prev.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_print.bmp b/xfa_test/FormFiller_Test/res/tool_print.bmp
new file mode 100644
index 0000000000..257f650adb
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_print.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_search.bmp b/xfa_test/FormFiller_Test/res/tool_search.bmp
new file mode 100644
index 0000000000..aad8b91f03
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_search.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_snap_shot.bmp b/xfa_test/FormFiller_Test/res/tool_snap_shot.bmp
new file mode 100644
index 0000000000..419efe4547
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_snap_shot.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_zoomin.bmp b/xfa_test/FormFiller_Test/res/tool_zoomin.bmp
new file mode 100644
index 0000000000..ddcf4c2ed8
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_zoomin.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/res/tool_zoomout.bmp b/xfa_test/FormFiller_Test/res/tool_zoomout.bmp
new file mode 100644
index 0000000000..6fbd1de184
--- /dev/null
+++ b/xfa_test/FormFiller_Test/res/tool_zoomout.bmp
Binary files differ
diff --git a/xfa_test/FormFiller_Test/resource.h b/xfa_test/FormFiller_Test/resource.h
new file mode 100644
index 0000000000..fab1e6b28a
--- /dev/null
+++ b/xfa_test/FormFiller_Test/resource.h
@@ -0,0 +1,113 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by ReaderVC.rc
+//
+#define IDD_ABOUTBOX 100
+#define IDR_MAINFRAME 128
+#define IDR_READERTYPE 129
+#define IDD_DLG_GOTOPAGE 130
+#define IDD_DLG_ZOOMTO 131
+#define IDD_DLG_FIND 132
+#define IDC_CURSOR1 133
+#define IDC_CURSOR2 134
+#define IDC_CURSOR3 135
+#define IDC_CURSOR4 136
+#define IDB_BITMAP1 215
+#define IDB_BITMAP2 216
+#define IDB_BITMAP3 217
+#define IDB_BITMAP4 218
+#define IDB_BITMAP5 219
+#define IDB_BITMAP6 220
+#define IDB_BITMAP7 221
+#define IDB_BITMAP8 222
+#define IDB_BITMAP9 223
+#define IDB_BITMAP10 224
+#define IDB_BITMAP11 225
+#define IDB_BITMAP12 226
+#define IDB_BITMAP13 227
+#define IDB_BITMAP14 228
+#define IDB_BITMAP15 229
+#define IDB_BITMAP16 230
+#define IDB_BITMAP17 231
+#define IDB_BITMAP18 232
+#define IDB_BITMAP19 233
+#define IDB_BITMAP20 234
+#define IDB_BITMAP21 235
+#define IDB_BITMAP22 236
+#define IDB_BITMAP23 237
+#define IDB_BITMAP24 238
+#define IDB_BITMAP26 240
+#define IDB_BITMAP27 241
+#define IDB_BITMAP28 242
+#define IDB_BITMAP29 243
+#define IDB_BITMAP30 244
+#define IDB_BITMAP31 245
+#define IDB_BITMAP32 246
+#define IDB_BITMAP33 247
+#define IDB_BITMAP34 248
+#define IDB_BITMAP25 249
+#define IDB_BITMAP35 250
+#define IDB_BITMAP36 251
+#define IDD_DLG_CONVERT 252
+#define IDD_EXPORT_PAGE 253
+#define IDD_DLG_RESPONSE 255
+#define IDD_TEST_JS 256
+#define IDC_EDIT1 1000
+#define IDC_COMBO1 1002
+#define IDC_CHECK_MATCHCASE 1003
+#define IDC_CHECK_MATCHWHOLE 1004
+#define IDC_RADIO_Down 1005
+#define IDC_RADIO_UP 1006
+#define IDC_RADIO_Stream 1007
+#define IDC_RADIO_Appearance 1008
+#define IDC_Rander_Page 1009
+#define IDC_Save 1010
+#define IDC_EDIT_PAGE_HEIGHT 1011
+#define IDC_EDIT_ROTATE 1012
+#define IDC_EDIT_WIDTH 1013
+#define IDC_EDIT_HEIGHT 1014
+#define IDC_EDIT_PAGE_WIDTH 1015
+#define IDC_STATIC_BITMAP 1016
+#define ID_JS_OK 1017
+#define ID_JS_CANCEL 1018
+#define IDC_JS_QUESTION 1019
+#define IDC_JS_ANSWER 1020
+#define IDC_BUTTON1 1021
+#define ID_VIEW_ZOOMIN 32772
+#define ID_VIEW_ZOOMOUT 32773
+#define ID_VIEW_ZOOMTO 32774
+#define ID_VIEW_ACTUALSIZE 32775
+#define ID_VIEW_FITPAGE 32776
+#define ID_VIEW_FITWIDTH 32777
+#define ID_DOC_FIRSTPAGE 32778
+#define ID_DOC_PREPAGE 32779
+#define ID_DOC_NEXTPAGE 32780
+#define ID_DOC_LASTPAGE 32781
+#define ID_DOC_GOTOPAGE 32782
+#define ID_VIEW_CLOCKWISE 32784
+#define ID_VIEW_COUNTERCLOCKWISE 32785
+#define ID_TOOL_HAND 32788
+#define ID_TOOL_SELECT 32789
+#define ID_TOOL_SNAPSHOT 32790
+#define ID_TOOL_PDF2TXT 32791
+#define ID_TOOL_EXTRACTLINKS 32792
+#define ID_DOC_EDITGOTO 32793
+#define ID_VIEW_BOOKMARK 32794
+#define ID_TOOL_PAGETOTEXT 32795
+#define ID_RENDERBITMAP 32799
+#define ID_EXPORT_PDF_TO_BITMAP 32800
+#define IDM_Test_JS 32801
+#define IDC_JS_EDIT 32802
+#define TEST_PRINT_METALFILE 32803
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 257
+#define _APS_NEXT_COMMAND_VALUE 32803
+#define _APS_NEXT_CONTROL_VALUE 1022
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/xfa_test/pdf/BUILD.gn b/xfa_test/pdf/BUILD.gn
new file mode 100644
index 0000000000..5e1f165b1c
--- /dev/null
+++ b/xfa_test/pdf/BUILD.gn
@@ -0,0 +1,99 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+pdf_engine = 0 # 0 PDFium
+
+# TODO(GYP) need support for loadable modules
+shared_library("pdf") {
+ sources = [
+ "button.h",
+ "button.cc",
+ "chunk_stream.h",
+ "chunk_stream.cc",
+ "control.h",
+ "control.cc",
+ "document_loader.h",
+ "document_loader.cc",
+ "draw_utils.cc",
+ "draw_utils.h",
+ "fading_control.cc",
+ "fading_control.h",
+ "fading_controls.cc",
+ "fading_controls.h",
+ "instance.cc",
+ "instance.h",
+ "number_image_generator.cc",
+ "number_image_generator.h",
+ "out_of_process_instance.cc",
+ "out_of_process_instance.h",
+ "page_indicator.cc",
+ "page_indicator.h",
+ "paint_aggregator.cc",
+ "paint_aggregator.h",
+ "paint_manager.cc",
+ "paint_manager.h",
+ "pdf.cc",
+ "pdf.h",
+ "pdf.rc",
+ "progress_control.cc",
+ "progress_control.h",
+ "pdf_engine.h",
+ "preview_mode_client.cc",
+ "preview_mode_client.h",
+ "resource.h",
+ "resource_consts.h",
+ "thumbnail_control.cc",
+ "thumbnail_control.h",
+ "../chrome/browser/chrome_page_zoom_constants.cc",
+ "../content/common/page_zoom.cc",
+ ]
+
+ if (pdf_engine == 0) {
+ sources += [
+ "pdfium/pdfium_assert_matching_enums.cc",
+ "pdfium/pdfium_engine.cc",
+ "pdfium/pdfium_engine.h",
+ "pdfium/pdfium_mem_buffer_file_read.cc",
+ "pdfium/pdfium_mem_buffer_file_read.h",
+ "pdfium/pdfium_mem_buffer_file_write.cc",
+ "pdfium/pdfium_mem_buffer_file_write.h",
+ "pdfium/pdfium_page.cc",
+ "pdfium/pdfium_page.h",
+ "pdfium/pdfium_range.cc",
+ "pdfium/pdfium_range.h",
+ ]
+ }
+
+ if (is_win) {
+ defines = [ "COMPILE_CONTENT_STATICALLY" ]
+ cflags = [ "/wd4267" ] # TODO(jschuh) size_t to int truncations.
+ }
+
+ if (is_mac) {
+ # TODO(GYP)
+ #'mac_bundle': 1,
+ #'product_name': 'PDF',
+ #'product_extension': 'plugin',
+ ## Strip the shipping binary of symbols so "Foxit" doesn't appear in
+ ## the binary. Symbols are stored in a separate .dSYM.
+ #'variables': {
+ # 'mac_real_dsym': 1,
+ #},
+ #'sources+': [
+ # 'Info.plist'
+ #]
+ #'xcode_settings': {
+ # 'INFOPLIST_FILE': 'Info.plist',
+ #},
+ }
+
+ deps = [
+ "//base",
+ "//net",
+ "//ppapi:ppapi_cpp",
+ "//third_party/pdfium",
+ ]
+}
+
+# TODO(GYP) pdf_linux_symbols target.
diff --git a/xfa_test/pdf/DEPS b/xfa_test/pdf/DEPS
new file mode 100644
index 0000000000..73f2f8f44d
--- /dev/null
+++ b/xfa_test/pdf/DEPS
@@ -0,0 +1,9 @@
+include_rules = [
+ "!chrome/browser/chrome_page_zoom_constants.h",
+ "!chrome/common/content_restriction.h",
+ "!content/public/common/page_zoom.h",
+ "+net",
+ "+ppapi",
+ "+third_party/pdfium/fpdfsdk/include",
+ "+ui/events/keycodes/keyboard_codes.h",
+]
diff --git a/xfa_test/pdf/Info.plist b/xfa_test/pdf/Info.plist
new file mode 100644
index 0000000000..9f3dfdf834
--- /dev/null
+++ b/xfa_test/pdf/Info.plist
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.chromium.pdf_plugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>BRPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>WebPluginDescription</key>
+ <string>Chrome PDF Viewer</string>
+ <key>WebPluginMIMETypes</key>
+ <dict>
+ <key>application/pdf</key>
+ <dict>
+ <key>WebPluginExtensions</key>
+ <array>
+ <string>pdf</string>
+ </array>
+ <key>WebPluginTypeDescription</key>
+ <string>Acrobat Portable Document Format</string>
+ </dict>
+ </dict>
+ <key>WebPluginName</key>
+ <string>Chrome PDF Viewer</string>
+</dict>
+</plist>
diff --git a/xfa_test/pdf/OWNERS b/xfa_test/pdf/OWNERS
new file mode 100644
index 0000000000..4b408bc7c9
--- /dev/null
+++ b/xfa_test/pdf/OWNERS
@@ -0,0 +1,4 @@
+gene@chromium.org
+jam@chromium.org
+raymes@chromium.org
+thestig@chromium.org \ No newline at end of file
diff --git a/xfa_test/pdf/button.cc b/xfa_test/pdf/button.cc
new file mode 100644
index 0000000000..3a30164c14
--- /dev/null
+++ b/xfa_test/pdf/button.cc
@@ -0,0 +1,179 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/button.h"
+
+#include "base/logging.h"
+#include "pdf/draw_utils.h"
+#include "ppapi/cpp/input_event.h"
+
+namespace chrome_pdf {
+
+Button::Button()
+ : style_(BUTTON_CLICKABLE), state_(BUTTON_NORMAL), is_pressed_(false) {
+}
+
+Button::~Button() {
+}
+
+bool Button::CreateButton(uint32 id,
+ const pp::Point& origin,
+ bool visible,
+ Control::Owner* owner,
+ ButtonStyle style,
+ const pp::ImageData& face_normal,
+ const pp::ImageData& face_highlighted,
+ const pp::ImageData& face_pressed) {
+ DCHECK(face_normal.size().GetArea());
+ DCHECK(face_normal.size() == face_highlighted.size());
+ DCHECK(face_normal.size() == face_pressed.size());
+
+ pp::Rect rc(origin, face_normal.size());
+ if (!Control::Create(id, rc, visible, owner))
+ return false;
+
+ style_ = style;
+
+ normal_ = face_normal;
+ highlighted_ = face_highlighted;
+ pressed_ = face_pressed;
+
+ return true;
+}
+
+
+void Button::Paint(pp::ImageData* image_data, const pp::Rect& rc) {
+ if (!visible())
+ return;
+
+ pp::Rect draw_rc = rc.Intersect(rect());
+ if (draw_rc.IsEmpty())
+ return;
+
+ pp::Point origin = draw_rc.point();
+ draw_rc.Offset(-rect().x(), -rect().y());
+
+ AlphaBlend(GetCurrentImage(), draw_rc, image_data, origin, transparency());
+}
+
+bool Button::HandleEvent(const pp::InputEvent& event) {
+ if (!visible())
+ return false;
+
+ // Button handles mouse events only.
+ pp::MouseInputEvent mouse_event(event);
+ if (mouse_event.is_null())
+ return false;
+
+ pp::Point pt = mouse_event.GetPosition();
+ if (!rect().Contains(pt) ||
+ event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE) {
+ ChangeState(BUTTON_NORMAL, false);
+ owner()->SetEventCapture(id(), false);
+ return false;
+ }
+
+ owner()->SetCursor(id(), PP_CURSORTYPE_POINTER);
+ owner()->SetEventCapture(id(), true);
+
+ bool handled = true;
+ switch (event.GetType()) {
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ if (state_ == BUTTON_NORMAL)
+ ChangeState(BUTTON_HIGHLIGHTED, false);
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT) {
+ ChangeState(BUTTON_PRESSED, false);
+ is_pressed_ = true;
+ }
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ if (mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT &&
+ is_pressed_) {
+ OnButtonClicked();
+ is_pressed_ = false;
+ } else {
+ // Since button has not been pressed, return false to allow other
+ // controls (scrollbar) to process mouse button up.
+ return false;
+ }
+ break;
+ default:
+ handled = false;
+ break;
+ }
+
+ return handled;
+}
+
+void Button::OnEventCaptureReleased() {
+ ChangeState(BUTTON_NORMAL, false);
+}
+
+void Button::Show(bool visible, bool invalidate) {
+ // If button become invisible, remove pressed flag.
+ if (!visible)
+ is_pressed_ = false;
+ Control::Show(visible, invalidate);
+}
+
+void Button::AdjustTransparency(uint8 transparency, bool invalidate) {
+ // If button become invisible, remove pressed flag.
+ if (transparency == kTransparentAlpha)
+ is_pressed_ = false;
+ Control::AdjustTransparency(transparency, invalidate);
+}
+
+void Button::SetPressedState(bool pressed) {
+ if (style_ == BUTTON_STATE) {
+ if (IsPressed() != pressed)
+ ChangeState(pressed ? BUTTON_PRESSED_STICKY : BUTTON_NORMAL, true);
+ }
+}
+
+const pp::ImageData& Button::GetCurrentImage() {
+ switch (state_) {
+ case BUTTON_NORMAL: return normal_;
+ case BUTTON_HIGHLIGHTED: return highlighted_;
+ case BUTTON_PRESSED:
+ case BUTTON_PRESSED_STICKY: return pressed_;
+ }
+ NOTREACHED();
+ return normal_;
+}
+
+void Button::ChangeState(ButtonState new_state, bool force) {
+ if (style_ == BUTTON_STATE && !force) {
+ // If button is a state button and pressed state is sticky,
+ // user have to click on this button again to unpress it.
+ if ((state_ == BUTTON_PRESSED_STICKY && new_state != BUTTON_PRESSED_STICKY)
+ ||
+ (state_ != BUTTON_PRESSED_STICKY && new_state == BUTTON_PRESSED_STICKY))
+ return;
+ }
+
+ if (state_ != new_state) {
+ state_ = new_state;
+ owner()->Invalidate(id(), rect());
+ }
+}
+
+void Button::OnButtonClicked() {
+ switch (style_) {
+ case BUTTON_CLICKABLE:
+ ChangeState(BUTTON_HIGHLIGHTED, true);
+ owner()->OnEvent(id(), EVENT_ID_BUTTON_CLICKED, NULL);
+ break;
+ case BUTTON_STATE:
+ SetPressedState(!IsPressed());
+ owner()->OnEvent(id(), EVENT_ID_BUTTON_STATE_CHANGED, NULL);
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
+} // namespace chrome_pdf
+
diff --git a/xfa_test/pdf/button.h b/xfa_test/pdf/button.h
new file mode 100644
index 0000000000..fa2517d62b
--- /dev/null
+++ b/xfa_test/pdf/button.h
@@ -0,0 +1,71 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_BUTTON_H_
+#define PDF_BUTTON_H_
+
+#include "pdf/control.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/rect.h"
+
+namespace chrome_pdf {
+
+class Button : public Control {
+ public:
+ enum ButtonEventIds {
+ EVENT_ID_BUTTON_CLICKED,
+ EVENT_ID_BUTTON_STATE_CHANGED,
+ };
+
+ enum ButtonStyle {
+ BUTTON_CLICKABLE,
+ BUTTON_STATE
+ };
+
+ enum ButtonState {
+ BUTTON_NORMAL,
+ BUTTON_HIGHLIGHTED,
+ BUTTON_PRESSED,
+ BUTTON_PRESSED_STICKY,
+ };
+
+ Button();
+ virtual ~Button();
+ virtual bool CreateButton(uint32 id,
+ const pp::Point& origin,
+ bool visible,
+ Control::Owner* delegate,
+ ButtonStyle style,
+ const pp::ImageData& face_normal,
+ const pp::ImageData& face_highlighted,
+ const pp::ImageData& face_pressed);
+
+ virtual void Paint(pp::ImageData* image_data, const pp::Rect& rc);
+ virtual bool HandleEvent(const pp::InputEvent& event);
+ virtual void OnEventCaptureReleased();
+ virtual void Show(bool visible, bool invalidate);
+ virtual void AdjustTransparency(uint8 transparency, bool invalidate);
+
+ ButtonState state() const { return state_; }
+ bool IsPressed() const { return state() == BUTTON_PRESSED_STICKY; }
+ void SetPressedState(bool pressed);
+
+ private:
+ void OnButtonClicked();
+
+ const pp::ImageData& GetCurrentImage();
+ void ChangeState(ButtonState new_state, bool force);
+
+ ButtonStyle style_;
+ ButtonState state_;
+ bool is_pressed_;
+
+ pp::ImageData normal_;
+ pp::ImageData highlighted_;
+ pp::ImageData pressed_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_BUTTON_H_
diff --git a/xfa_test/pdf/chunk_stream.cc b/xfa_test/pdf/chunk_stream.cc
new file mode 100644
index 0000000000..7ac8f974a5
--- /dev/null
+++ b/xfa_test/pdf/chunk_stream.cc
@@ -0,0 +1,172 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/chunk_stream.h"
+
+#define __STDC_LIMIT_MACROS
+#ifdef _WIN32
+#include <limits.h>
+#else
+#include <stdint.h>
+#endif
+
+#include <algorithm>
+
+#include "base/basictypes.h"
+
+namespace chrome_pdf {
+
+ChunkStream::ChunkStream() {
+}
+
+ChunkStream::~ChunkStream() {
+}
+
+void ChunkStream::Clear() {
+ chunks_.clear();
+ data_.clear();
+}
+
+void ChunkStream::Preallocate(size_t stream_size) {
+ data_.reserve(stream_size);
+}
+
+size_t ChunkStream::GetSize() {
+ return data_.size();
+}
+
+bool ChunkStream::WriteData(size_t offset, void* buffer, size_t size) {
+ if (SIZE_MAX - size < offset)
+ return false;
+
+ if (data_.size() < offset + size)
+ data_.resize(offset + size);
+
+ memcpy(&data_[offset], buffer, size);
+
+ if (chunks_.empty()) {
+ chunks_[offset] = size;
+ return true;
+ }
+
+ std::map<size_t, size_t>::iterator start = chunks_.upper_bound(offset);
+ if (start != chunks_.begin())
+ --start; // start now points to the key equal or lower than offset.
+ if (start->first + start->second < offset)
+ ++start; // start element is entirely before current chunk, skip it.
+
+ std::map<size_t, size_t>::iterator end = chunks_.upper_bound(offset + size);
+ if (start == end) { // No chunks to merge.
+ chunks_[offset] = size;
+ return true;
+ }
+
+ --end;
+
+ size_t new_offset = std::min<size_t>(start->first, offset);
+ size_t new_size =
+ std::max<size_t>(end->first + end->second, offset + size) - new_offset;
+
+ chunks_.erase(start, ++end);
+
+ chunks_[new_offset] = new_size;
+
+ return true;
+}
+
+bool ChunkStream::ReadData(size_t offset, size_t size, void* buffer) const {
+ if (!IsRangeAvailable(offset, size))
+ return false;
+
+ memcpy(buffer, &data_[offset], size);
+ return true;
+}
+
+bool ChunkStream::GetMissedRanges(
+ size_t offset, size_t size,
+ std::vector<std::pair<size_t, size_t> >* ranges) const {
+ if (IsRangeAvailable(offset, size))
+ return false;
+
+ ranges->clear();
+ if (chunks_.empty()) {
+ ranges->push_back(std::pair<size_t, size_t>(offset, size));
+ return true;
+ }
+
+ std::map<size_t, size_t>::const_iterator start = chunks_.upper_bound(offset);
+ if (start != chunks_.begin())
+ --start; // start now points to the key equal or lower than offset.
+ if (start->first + start->second < offset)
+ ++start; // start element is entirely before current chunk, skip it.
+
+ std::map<size_t, size_t>::const_iterator end =
+ chunks_.upper_bound(offset + size);
+ if (start == end) { // No data in the current range available.
+ ranges->push_back(std::pair<size_t, size_t>(offset, size));
+ return true;
+ }
+
+ size_t cur_offset = offset;
+ std::map<size_t, size_t>::const_iterator it;
+ for (it = start; it != end; ++it) {
+ if (cur_offset < it->first) {
+ size_t new_size = it->first - cur_offset;
+ ranges->push_back(std::pair<size_t, size_t>(cur_offset, new_size));
+ cur_offset = it->first + it->second;
+ } else if (cur_offset < it->first + it->second) {
+ cur_offset = it->first + it->second;
+ }
+ }
+
+ // Add last chunk.
+ if (cur_offset < offset + size)
+ ranges->push_back(std::pair<size_t, size_t>(cur_offset,
+ offset + size - cur_offset));
+
+ return true;
+}
+
+bool ChunkStream::IsRangeAvailable(size_t offset, size_t size) const {
+ if (chunks_.empty())
+ return false;
+
+ if (SIZE_MAX - size < offset)
+ return false;
+
+ std::map<size_t, size_t>::const_iterator it = chunks_.upper_bound(offset);
+ if (it == chunks_.begin())
+ return false; // No chunks includes offset byte.
+
+ --it; // Now it starts equal or before offset.
+ return (it->first + it->second) >= (offset + size);
+}
+
+size_t ChunkStream::GetFirstMissingByte() const {
+ if (chunks_.empty())
+ return 0;
+ std::map<size_t, size_t>::const_iterator begin = chunks_.begin();
+ return begin->first > 0 ? 0 : begin->second;
+}
+
+size_t ChunkStream::GetLastByteBefore(size_t offset) const {
+ if (chunks_.empty())
+ return 0;
+ std::map<size_t, size_t>::const_iterator it = chunks_.upper_bound(offset);
+ if (it == chunks_.begin())
+ return 0;
+ --it;
+ return it->first + it->second;
+}
+
+size_t ChunkStream::GetFirstByteAfter(size_t offset) const {
+ if (chunks_.empty())
+ return 0;
+ std::map<size_t, size_t>::const_iterator it = chunks_.upper_bound(offset);
+ if (it == chunks_.end())
+ return data_.size();
+ return it->first;
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/chunk_stream.h b/xfa_test/pdf/chunk_stream.h
new file mode 100644
index 0000000000..fac1ec644d
--- /dev/null
+++ b/xfa_test/pdf/chunk_stream.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_CHUNK_STREAM_H_
+#define PDF_CHUNK_STREAM_H_
+
+#include <stddef.h>
+
+#include <map>
+#include <vector>
+
+namespace chrome_pdf {
+
+// This class collects a chunks of data into one data stream. Client can check
+// if data in certain range is available, and get missing chunks of data.
+class ChunkStream {
+ public:
+ ChunkStream();
+ ~ChunkStream();
+
+ void Clear();
+
+ void Preallocate(size_t stream_size);
+ size_t GetSize();
+
+ bool WriteData(size_t offset, void* buffer, size_t size);
+ bool ReadData(size_t offset, size_t size, void* buffer) const;
+
+ // Returns vector of pairs where first is an offset, second is a size.
+ bool GetMissedRanges(size_t offset, size_t size,
+ std::vector<std::pair<size_t, size_t> >* ranges) const;
+ bool IsRangeAvailable(size_t offset, size_t size) const;
+ size_t GetFirstMissingByte() const;
+
+ size_t GetLastByteBefore(size_t offset) const;
+ size_t GetFirstByteAfter(size_t offset) const;
+
+ private:
+ std::vector<unsigned char> data_;
+
+ // Pair, first - begining of the chunk, second - size of the chunk.
+ std::map<size_t, size_t> chunks_;
+};
+
+}; // namespace chrome_pdf
+
+#endif
diff --git a/xfa_test/pdf/control.cc b/xfa_test/pdf/control.cc
new file mode 100644
index 0000000000..ed911b6b95
--- /dev/null
+++ b/xfa_test/pdf/control.cc
@@ -0,0 +1,117 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/control.h"
+
+#include "base/logging.h"
+#include "pdf/draw_utils.h"
+
+namespace chrome_pdf {
+
+Control::Control()
+ : id_(kInvalidControlId),
+ visible_(false),
+ owner_(NULL),
+ transparency_(kOpaqueAlpha) {
+}
+
+Control::~Control() {
+}
+
+bool Control::Create(uint32 id, const pp::Rect& rc,
+ bool visible, Owner* owner) {
+ DCHECK(owner);
+ if (owner_ || id == kInvalidControlId)
+ return false; // Already created or id is invalid.
+ id_ = id;
+ rc_ = rc;
+ visible_ = visible;
+ owner_ = owner;
+ return true;
+}
+
+bool Control::HandleEvent(const pp::InputEvent& event) {
+ return false;
+}
+
+void Control::PaintMultipleRects(pp::ImageData* image_data,
+ const std::list<pp::Rect>& rects) {
+ DCHECK(rects.size() > 0);
+ if (rects.size() == 1) {
+ Paint(image_data, rects.front());
+ return;
+ }
+
+ // Some rects in the input list may overlap. To prevent double
+ // painting (causes problems with semi-transparent controls) we'll
+ // paint control into buffer image data only once and copy requested
+ // rectangles.
+ pp::ImageData buffer(owner()->GetInstance(), image_data->format(),
+ rect().size(), false);
+ if (buffer.is_null())
+ return;
+
+ pp::Rect draw_rc = pp::Rect(image_data->size()).Intersect(rect());
+ pp::Rect ctrl_rc = pp::Rect(draw_rc.point() - rect().point(), draw_rc.size());
+ CopyImage(*image_data, draw_rc, &buffer, ctrl_rc, false);
+
+ // Temporary move control to origin (0,0) and draw it into temp buffer.
+ // Move to the original position afterward. Since this is going on temp
+ // buffer, we don't need to invalidate here.
+ pp::Rect temp = rect();
+ MoveTo(pp::Point(0, 0), false);
+ Paint(&buffer, ctrl_rc);
+ MoveTo(temp.point(), false);
+
+ std::list<pp::Rect>::const_iterator iter;
+ for (iter = rects.begin(); iter != rects.end(); ++iter) {
+ pp::Rect draw_rc = rect().Intersect(*iter);
+ if (!draw_rc.IsEmpty()) {
+ // Copy requested rect from the buffer image.
+ pp::Rect src_rc = draw_rc;
+ src_rc.Offset(-rect().x(), -rect().y());
+ CopyImage(buffer, src_rc, image_data, draw_rc, false);
+ }
+ }
+}
+
+void Control::Show(bool visible, bool invalidate) {
+ if (visible_ != visible) {
+ visible_ = visible;
+ if (invalidate)
+ owner_->Invalidate(id_, rc_);
+ }
+}
+
+void Control::AdjustTransparency(uint8 transparency, bool invalidate) {
+ if (transparency_ != transparency) {
+ transparency_ = transparency;
+ if (invalidate && visible_)
+ owner_->Invalidate(id_, rc_);
+ }
+}
+
+void Control::MoveBy(const pp::Point& offset, bool invalidate) {
+ pp::Rect old_rc = rc_;
+ rc_.Offset(offset);
+ if (invalidate && visible_) {
+ owner()->Invalidate(id(), old_rc);
+ owner()->Invalidate(id(), rect());
+ }
+}
+
+void Control::SetRect(const pp::Rect& rc, bool invalidate) {
+ pp::Rect old_rc = rc_;
+ rc_ = rc;
+ if (invalidate && visible_) {
+ owner()->Invalidate(id(), old_rc);
+ owner()->Invalidate(id(), rect());
+ }
+}
+
+void Control::MoveTo(const pp::Point& origin, bool invalidate) {
+ MoveBy(origin - rc_.point(), invalidate);
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/control.h b/xfa_test/pdf/control.h
new file mode 100644
index 0000000000..babb37a2c0
--- /dev/null
+++ b/xfa_test/pdf/control.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_CONTROL_H_
+#define PDF_CONTROL_H_
+
+#include <list>
+
+#include "base/basictypes.h"
+#include "ppapi/c/dev/pp_cursor_type_dev.h"
+#include "ppapi/cpp/rect.h"
+
+namespace pp {
+class ImageData;
+class InputEvent;
+class Instance;
+}
+
+namespace chrome_pdf {
+
+const uint32 kInvalidControlId = 0;
+
+class Control {
+ public:
+ class Owner {
+ public:
+ virtual ~Owner() {}
+ virtual void OnEvent(uint32 control_id, uint32 event_id, void* data) = 0;
+ virtual void Invalidate(uint32 control_id, const pp::Rect& rc) = 0;
+ virtual uint32 ScheduleTimer(uint32 control_id, uint32 timeout_ms) = 0;
+ virtual void SetEventCapture(uint32 control_id, bool set_capture) = 0;
+ virtual void SetCursor(uint32 control_id,
+ PP_CursorType_Dev cursor_type) = 0;
+ virtual pp::Instance* GetInstance() = 0;
+ };
+
+ Control();
+ virtual ~Control();
+ virtual bool Create(uint32 id, const pp::Rect& rc,
+ bool visible, Owner* owner);
+
+ virtual void Paint(pp::ImageData* image_data, const pp::Rect& rc) {}
+ virtual bool HandleEvent(const pp::InputEvent& event);
+ virtual void OnTimerFired(uint32 timer_id) {}
+ virtual void EventCaptureReleased() {}
+
+ // Paint control into multiple destination rects.
+ virtual void PaintMultipleRects(pp::ImageData* image_data,
+ const std::list<pp::Rect>& rects);
+
+ virtual void Show(bool visible, bool invalidate);
+ virtual void AdjustTransparency(uint8 transparency, bool invalidate);
+ virtual void MoveBy(const pp::Point& offset, bool invalidate);
+ virtual void SetRect(const pp::Rect& rc, bool invalidate);
+
+ void MoveTo(const pp::Point& origin, bool invalidate);
+
+ uint32 id() const { return id_; }
+ const pp::Rect& rect() const { return rc_; }
+ bool visible() const { return visible_; }
+ Owner* owner() { return owner_; }
+ uint8 transparency() const { return transparency_; }
+
+ private:
+ uint32 id_;
+ pp::Rect rc_;
+ bool visible_;
+ Owner* owner_;
+ uint8 transparency_;
+};
+
+typedef Control::Owner ControlOwner;
+
+} // namespace chrome_pdf
+
+#endif // PDF_CONTROL_H_
diff --git a/xfa_test/pdf/document_loader.cc b/xfa_test/pdf/document_loader.cc
new file mode 100644
index 0000000000..b2628a6271
--- /dev/null
+++ b/xfa_test/pdf/document_loader.cc
@@ -0,0 +1,513 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/document_loader.h"
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "net/http/http_util.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/url_loader.h"
+#include "ppapi/cpp/url_request_info.h"
+#include "ppapi/cpp/url_response_info.h"
+
+namespace chrome_pdf {
+
+// Document below size will be downloaded in one chunk.
+const uint32 kMinFileSize = 64*1024;
+
+DocumentLoader::DocumentLoader(Client* client)
+ : client_(client), partial_document_(false), request_pending_(false),
+ current_pos_(0), current_chunk_size_(0), current_chunk_read_(0),
+ document_size_(0), header_request_(true), is_multipart_(false) {
+ loader_factory_.Initialize(this);
+}
+
+DocumentLoader::~DocumentLoader() {
+}
+
+bool DocumentLoader::Init(const pp::URLLoader& loader,
+ const std::string& url,
+ const std::string& headers) {
+ DCHECK(url_.empty());
+ url_ = url;
+ loader_ = loader;
+
+ std::string response_headers;
+ if (!headers.empty()) {
+ response_headers = headers;
+ } else {
+ pp::URLResponseInfo response = loader_.GetResponseInfo();
+ pp::Var headers_var = response.GetHeaders();
+
+ if (headers_var.is_string()) {
+ response_headers = headers_var.AsString();
+ }
+ }
+
+ bool accept_ranges_bytes = false;
+ bool content_encoded = false;
+ uint32 content_length = 0;
+ std::string type;
+ std::string disposition;
+ if (!response_headers.empty()) {
+ net::HttpUtil::HeadersIterator it(response_headers.begin(),
+ response_headers.end(), "\n");
+ while (it.GetNext()) {
+ if (LowerCaseEqualsASCII(it.name(), "content-length")) {
+ content_length = atoi(it.values().c_str());
+ } else if (LowerCaseEqualsASCII(it.name(), "accept-ranges")) {
+ accept_ranges_bytes = LowerCaseEqualsASCII(it.values(), "bytes");
+ } else if (LowerCaseEqualsASCII(it.name(), "content-encoding")) {
+ content_encoded = true;
+ } else if (LowerCaseEqualsASCII(it.name(), "content-type")) {
+ type = it.values();
+ size_t semi_colon_pos = type.find(';');
+ if (semi_colon_pos != std::string::npos) {
+ type = type.substr(0, semi_colon_pos);
+ }
+ TrimWhitespace(type, base::TRIM_ALL, &type);
+ } else if (LowerCaseEqualsASCII(it.name(), "content-disposition")) {
+ disposition = it.values();
+ }
+ }
+ }
+ if (!type.empty() &&
+ !EndsWith(type, "/pdf", false) &&
+ !EndsWith(type, ".pdf", false) &&
+ !EndsWith(type, "/x-pdf", false) &&
+ !EndsWith(type, "/*", false) &&
+ !EndsWith(type, "/acrobat", false) &&
+ !EndsWith(type, "/unknown", false)) {
+ return false;
+ }
+ if (StartsWithASCII(disposition, "attachment", false)) {
+ return false;
+ }
+
+ if (content_length > 0)
+ chunk_stream_.Preallocate(content_length);
+
+ document_size_ = content_length;
+ requests_count_ = 0;
+
+ // Enable partial loading only if file size is above the threshold.
+ // It will allow avoiding latency for multiple requests.
+ if (content_length > kMinFileSize &&
+ accept_ranges_bytes &&
+ !content_encoded) {
+ LoadPartialDocument();
+ } else {
+ LoadFullDocument();
+ }
+ return true;
+}
+
+void DocumentLoader::LoadPartialDocument() {
+ partial_document_ = true;
+ // Force the main request to be cancelled, since if we're a full-frame plugin
+ // there could be other references to the loader.
+ loader_.Close();
+ loader_ = pp::URLLoader();
+ // Download file header.
+ header_request_ = true;
+ RequestData(0, std::min(GetRequestSize(), document_size_));
+}
+
+void DocumentLoader::LoadFullDocument() {
+ partial_document_ = false;
+ chunk_buffer_.clear();
+ ReadMore();
+}
+
+bool DocumentLoader::IsDocumentComplete() const {
+ if (document_size_ == 0) // Document size unknown.
+ return false;
+ return IsDataAvailable(0, document_size_);
+}
+
+uint32 DocumentLoader::GetAvailableData() const {
+ if (document_size_ == 0) { // If document size is unknown.
+ return current_pos_;
+ }
+
+ std::vector<std::pair<size_t, size_t> > ranges;
+ chunk_stream_.GetMissedRanges(0, document_size_, &ranges);
+ uint32 available = document_size_;
+ std::vector<std::pair<size_t, size_t> >::iterator it;
+ for (it = ranges.begin(); it != ranges.end(); ++it) {
+ available -= it->second;
+ }
+ return available;
+}
+
+void DocumentLoader::ClearPendingRequests() {
+ // The first item in the queue is pending (need to keep it in the queue).
+ if (pending_requests_.size() > 1) {
+ // Remove all elements except the first one.
+ pending_requests_.erase(++pending_requests_.begin(),
+ pending_requests_.end());
+ }
+}
+
+bool DocumentLoader::GetBlock(uint32 position, uint32 size, void* buf) const {
+ return chunk_stream_.ReadData(position, size, buf);
+}
+
+bool DocumentLoader::IsDataAvailable(uint32 position, uint32 size) const {
+ return chunk_stream_.IsRangeAvailable(position, size);
+}
+
+void DocumentLoader::RequestData(uint32 position, uint32 size) {
+ DCHECK(partial_document_);
+
+ // We have some artefact request from
+ // PDFiumEngine::OnDocumentComplete() -> FPDFAvail_IsPageAvail after
+ // document is complete.
+ // We need this fix in PDFIum. Adding this as a work around.
+ // Bug: http://code.google.com/p/chromium/issues/detail?id=79996
+ // Test url:
+ // http://www.icann.org/en/correspondence/holtzman-to-jeffrey-02mar11-en.pdf
+ if (IsDocumentComplete())
+ return;
+
+ pending_requests_.push_back(std::pair<size_t, size_t>(position, size));
+ DownloadPendingRequests();
+}
+
+void DocumentLoader::DownloadPendingRequests() {
+ if (request_pending_ || pending_requests_.empty())
+ return;
+
+ // Remove already completed requests.
+ // By design DownloadPendingRequests() should have at least 1 request in the
+ // queue. ReadComplete() will remove the last pending comment from the queue.
+ while (pending_requests_.size() > 1) {
+ if (IsDataAvailable(pending_requests_.front().first,
+ pending_requests_.front().second)) {
+ pending_requests_.pop_front();
+ } else {
+ break;
+ }
+ }
+
+ uint32 pos = pending_requests_.front().first;
+ uint32 size = pending_requests_.front().second;
+ if (IsDataAvailable(pos, size)) {
+ ReadComplete();
+ return;
+ }
+
+ // If current request has been partially downloaded already, split it into
+ // a few smaller requests.
+ std::vector<std::pair<size_t, size_t> > ranges;
+ chunk_stream_.GetMissedRanges(pos, size, &ranges);
+ if (ranges.size() > 0) {
+ pending_requests_.pop_front();
+ pending_requests_.insert(pending_requests_.begin(),
+ ranges.begin(), ranges.end());
+ pos = pending_requests_.front().first;
+ size = pending_requests_.front().second;
+ }
+
+ uint32 cur_request_size = GetRequestSize();
+ // If size is less than default request, try to expand download range for
+ // more optimal download.
+ if (size < cur_request_size && partial_document_) {
+ // First, try to expand block towards the end of the file.
+ uint32 new_pos = pos;
+ uint32 new_size = cur_request_size;
+ if (pos + new_size > document_size_)
+ new_size = document_size_ - pos;
+
+ std::vector<std::pair<size_t, size_t> > ranges;
+ if (chunk_stream_.GetMissedRanges(new_pos, new_size, &ranges)) {
+ new_pos = ranges[0].first;
+ new_size = ranges[0].second;
+ }
+
+ // Second, try to expand block towards the beginning of the file.
+ if (new_size < cur_request_size) {
+ uint32 block_end = new_pos + new_size;
+ if (block_end > cur_request_size) {
+ new_pos = block_end - cur_request_size;
+ } else {
+ new_pos = 0;
+ }
+ new_size = block_end - new_pos;
+
+ if (chunk_stream_.GetMissedRanges(new_pos, new_size, &ranges)) {
+ new_pos = ranges.back().first;
+ new_size = ranges.back().second;
+ }
+ }
+ pos = new_pos;
+ size = new_size;
+ }
+
+ size_t last_byte_before = chunk_stream_.GetLastByteBefore(pos);
+ size_t first_byte_after = chunk_stream_.GetFirstByteAfter(pos + size - 1);
+ if (pos - last_byte_before < cur_request_size) {
+ size = pos + size - last_byte_before;
+ pos = last_byte_before;
+ }
+
+ if ((pos + size < first_byte_after) &&
+ (pos + size + cur_request_size >= first_byte_after))
+ size = first_byte_after - pos;
+
+ request_pending_ = true;
+
+ // Start downloading first pending request.
+ loader_.Close();
+ loader_ = client_->CreateURLLoader();
+ pp::CompletionCallback callback =
+ loader_factory_.NewCallback(&DocumentLoader::DidOpen);
+ pp::URLRequestInfo request = GetRequest(pos, size);
+ requests_count_++;
+ int rv = loader_.Open(request, callback);
+ if (rv != PP_OK_COMPLETIONPENDING)
+ callback.Run(rv);
+}
+
+pp::URLRequestInfo DocumentLoader::GetRequest(uint32 position,
+ uint32 size) const {
+ pp::URLRequestInfo request(client_->GetPluginInstance());
+ request.SetURL(url_.c_str());
+ request.SetMethod("GET");
+ request.SetFollowRedirects(true);
+
+ const size_t kBufSize = 100;
+ char buf[kBufSize];
+ // According to rfc2616, byte range specifies position of the first and last
+ // bytes in the requested range inclusively. Therefore we should subtract 1
+ // from the position + size, to get index of the last byte that needs to be
+ // downloaded.
+ base::snprintf(buf, kBufSize, "Range: bytes=%d-%d", position,
+ position + size - 1);
+ pp::Var header(buf);
+ request.SetHeaders(header);
+
+ return request;
+}
+
+void DocumentLoader::DidOpen(int32_t result) {
+ if (result != PP_OK) {
+ NOTREACHED();
+ return;
+ }
+
+ int32_t http_code = loader_.GetResponseInfo().GetStatusCode();
+ if (http_code >= 400 && http_code < 500) {
+ // Error accessing resource. 4xx error indicate subsequent requests
+ // will fail too.
+ // E.g. resource has been removed from the server while loading it.
+ // https://code.google.com/p/chromium/issues/detail?id=414827
+ return;
+ }
+
+ is_multipart_ = false;
+ current_chunk_size_ = 0;
+ current_chunk_read_ = 0;
+
+ pp::Var headers_var = loader_.GetResponseInfo().GetHeaders();
+ std::string headers;
+ if (headers_var.is_string())
+ headers = headers_var.AsString();
+
+ std::string boundary = GetMultiPartBoundary(headers);
+ if (boundary.size()) {
+ // Leave position untouched for now, when we read the data we'll get it.
+ is_multipart_ = true;
+ multipart_boundary_ = boundary;
+ } else {
+ // Need to make sure that the server returned a byte-range, since it's
+ // possible for a server to just ignore our bye-range request and just
+ // return the entire document even if it supports byte-range requests.
+ // i.e. sniff response to
+ // http://www.act.org/compass/sample/pdf/geometry.pdf
+ current_pos_ = 0;
+ uint32 start_pos, end_pos;
+ if (GetByteRange(headers, &start_pos, &end_pos)) {
+ current_pos_ = start_pos;
+ if (end_pos && end_pos > start_pos)
+ current_chunk_size_ = end_pos - start_pos + 1;
+ }
+ }
+
+ ReadMore();
+}
+
+bool DocumentLoader::GetByteRange(const std::string& headers, uint32* start,
+ uint32* end) {
+ net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n");
+ while (it.GetNext()) {
+ if (LowerCaseEqualsASCII(it.name(), "content-range")) {
+ std::string range = it.values().c_str();
+ if (StartsWithASCII(range, "bytes", false)) {
+ range = range.substr(strlen("bytes"));
+ std::string::size_type pos = range.find('-');
+ std::string range_end;
+ if (pos != std::string::npos)
+ range_end = range.substr(pos + 1);
+ TrimWhitespaceASCII(range, base::TRIM_LEADING, &range);
+ TrimWhitespaceASCII(range_end, base::TRIM_LEADING, &range_end);
+ *start = atoi(range.c_str());
+ *end = atoi(range_end.c_str());
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+std::string DocumentLoader::GetMultiPartBoundary(const std::string& headers) {
+ net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\n");
+ while (it.GetNext()) {
+ if (LowerCaseEqualsASCII(it.name(), "content-type")) {
+ std::string type = base::StringToLowerASCII(it.values());
+ if (StartsWithASCII(type, "multipart/", true)) {
+ const char* boundary = strstr(type.c_str(), "boundary=");
+ if (!boundary) {
+ NOTREACHED();
+ break;
+ }
+
+ return std::string(boundary + 9);
+ }
+ }
+ }
+ return std::string();
+}
+
+void DocumentLoader::ReadMore() {
+ pp::CompletionCallback callback =
+ loader_factory_.NewCallback(&DocumentLoader::DidRead);
+ int rv = loader_.ReadResponseBody(buffer_, sizeof(buffer_), callback);
+ if (rv != PP_OK_COMPLETIONPENDING)
+ callback.Run(rv);
+}
+
+void DocumentLoader::DidRead(int32_t result) {
+ if (result > 0) {
+ char* start = buffer_;
+ size_t length = result;
+ if (is_multipart_ && result > 2) {
+ for (int i = 2; i < result; ++i) {
+ if ((buffer_[i - 1] == '\n' && buffer_[i - 2] == '\n') ||
+ (i >= 4 &&
+ buffer_[i - 1] == '\n' && buffer_[i - 2] == '\r' &&
+ buffer_[i - 3] == '\n' && buffer_[i - 4] == '\r')) {
+ uint32 start_pos, end_pos;
+ if (GetByteRange(std::string(buffer_, i), &start_pos, &end_pos)) {
+ current_pos_ = start_pos;
+ start += i;
+ length -= i;
+ if (end_pos && end_pos > start_pos)
+ current_chunk_size_ = end_pos - start_pos + 1;
+ }
+ break;
+ }
+ }
+
+ // Reset this flag so we don't look inside the buffer in future calls of
+ // DidRead for this response. Note that this code DOES NOT handle multi-
+ // part responses with more than one part (we don't issue them at the
+ // moment, so they shouldn't arrive).
+ is_multipart_ = false;
+ }
+
+ if (current_chunk_size_ &&
+ current_chunk_read_ + length > current_chunk_size_)
+ length = current_chunk_size_ - current_chunk_read_;
+
+ if (length) {
+ if (document_size_ > 0) {
+ chunk_stream_.WriteData(current_pos_, start, length);
+ } else {
+ // If we did not get content-length in the response, we can't
+ // preallocate buffer for the entire document. Resizing array causing
+ // memory fragmentation issues on the large files and OOM exceptions.
+ // To fix this, we collect all chunks of the file to the list and
+ // concatenate them together after request is complete.
+ chunk_buffer_.push_back(std::vector<unsigned char>());
+ chunk_buffer_.back().resize(length);
+ memcpy(&(chunk_buffer_.back()[0]), start, length);
+ }
+ current_pos_ += length;
+ current_chunk_read_ += length;
+ client_->OnNewDataAvailable();
+ }
+ ReadMore();
+ } else if (result == PP_OK) {
+ ReadComplete();
+ } else {
+ NOTREACHED();
+ }
+}
+
+void DocumentLoader::ReadComplete() {
+ if (!partial_document_) {
+ if (document_size_ == 0) {
+ // For the document with no 'content-length" specified we've collected all
+ // the chunks already. Let's allocate final document buffer and copy them
+ // over.
+ chunk_stream_.Preallocate(current_pos_);
+ uint32 pos = 0;
+ std::list<std::vector<unsigned char> >::iterator it;
+ for (it = chunk_buffer_.begin(); it != chunk_buffer_.end(); ++it) {
+ chunk_stream_.WriteData(pos, &((*it)[0]), it->size());
+ pos += it->size();
+ }
+ chunk_buffer_.clear();
+ }
+ document_size_ = current_pos_;
+ client_->OnDocumentComplete();
+ return;
+ }
+
+ request_pending_ = false;
+ pending_requests_.pop_front();
+
+ // If there are more pending request - continue downloading.
+ if (!pending_requests_.empty()) {
+ DownloadPendingRequests();
+ return;
+ }
+
+ if (IsDocumentComplete()) {
+ client_->OnDocumentComplete();
+ return;
+ }
+
+ if (header_request_)
+ client_->OnPartialDocumentLoaded();
+ else
+ client_->OnPendingRequestComplete();
+ header_request_ = false;
+
+ // The OnPendingRequestComplete could have added more requests.
+ if (!pending_requests_.empty()) {
+ DownloadPendingRequests();
+ } else {
+ // Document is not complete and we have no outstanding requests.
+ // Let's keep downloading PDF file in small chunks.
+ uint32 pos = chunk_stream_.GetFirstMissingByte();
+ std::vector<std::pair<size_t, size_t> > ranges;
+ chunk_stream_.GetMissedRanges(pos, GetRequestSize(), &ranges);
+ DCHECK(ranges.size() > 0);
+ RequestData(ranges[0].first, ranges[0].second);
+ }
+}
+
+uint32 DocumentLoader::GetRequestSize() const {
+ // Document loading strategy:
+ // For first 10 requests, we use 32k chunk sizes, for the next 10 requests we
+ // double the size (64k), and so on, until we cap max request size at 2M for
+ // 71 or more requests.
+ uint32 limited_count = std::min(std::max(requests_count_, 10u), 70u);
+ return 32*1024 * (1 << ((limited_count - 1) / 10u));
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/document_loader.h b/xfa_test/pdf/document_loader.h
new file mode 100644
index 0000000000..c09dba2ddd
--- /dev/null
+++ b/xfa_test/pdf/document_loader.h
@@ -0,0 +1,124 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_DOCUMENT_LOADER_H_
+#define PDF_DOCUMENT_LOADER_H_
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "pdf/chunk_stream.h"
+#include "ppapi/cpp/url_loader.h"
+#include "ppapi/utility/completion_callback_factory.h"
+
+#define kDefaultRequestSize 32768u
+
+namespace chrome_pdf {
+
+class DocumentLoader {
+ public:
+ class Client {
+ public:
+ // Gets the pp::Instance object.
+ virtual pp::Instance* GetPluginInstance() = 0;
+ // Creates new URLLoader based on client settings.
+ virtual pp::URLLoader CreateURLLoader() = 0;
+ // Notification called when partial information about document is available.
+ // Only called for urls that returns full content size and supports byte
+ // range requests.
+ virtual void OnPartialDocumentLoaded() = 0;
+ // Notification called when all outstanding pending requests are complete.
+ virtual void OnPendingRequestComplete() = 0;
+ // Notification called when new data is available.
+ virtual void OnNewDataAvailable() = 0;
+ // Notification called when document is fully loaded.
+ virtual void OnDocumentComplete() = 0;
+ };
+
+ explicit DocumentLoader(Client* client);
+ virtual ~DocumentLoader();
+
+ bool Init(const pp::URLLoader& loader,
+ const std::string& url,
+ const std::string& headers);
+
+ // Data access interface. Return true is sucessful.
+ bool GetBlock(uint32 position, uint32 size, void* buf) const;
+
+ // Data availability interface. Return true data avaialble.
+ bool IsDataAvailable(uint32 position, uint32 size) const;
+
+ // Data availability interface. Return true data avaialble.
+ void RequestData(uint32 position, uint32 size);
+
+ bool IsDocumentComplete() const;
+ uint32 document_size() const { return document_size_; }
+
+ // Return number of bytes available.
+ uint32 GetAvailableData() const;
+
+ // Clear pending requests from the queue.
+ void ClearPendingRequests();
+
+ bool is_partial_document() { return partial_document_; }
+
+ private:
+ // Called by the completion callback of the document's URLLoader.
+ void DidOpen(int32_t result);
+ // Call to read data from the document's URLLoader.
+ void ReadMore();
+ // Called by the completion callback of the document's URLLoader.
+ void DidRead(int32_t result);
+
+ // If the headers have a byte-range response, writes the start and end
+ // positions and returns true if at least the start position was parsed.
+ // The end position will be set to 0 if it was not found or parsed from the
+ // response.
+ // Returns false if not even a start position could be parsed.
+ static bool GetByteRange(const std::string& headers, uint32* start,
+ uint32* end);
+
+ // If the headers have a multi-part response, returns the boundary name.
+ // Otherwise returns an empty string.
+ static std::string GetMultiPartBoundary(const std::string& headers);
+
+ // Called when we detect that partial document load is possible.
+ void LoadPartialDocument();
+ // Called when we have to load full document.
+ void LoadFullDocument();
+ // Download pending requests.
+ void DownloadPendingRequests();
+ // Called when we complete server request and read all data from it.
+ void ReadComplete();
+ // Creates request to download size byte of data data starting from position.
+ pp::URLRequestInfo GetRequest(uint32 position, uint32 size) const;
+ // Returns current request size in bytes.
+ uint32 GetRequestSize() const;
+
+ Client* client_;
+ std::string url_;
+ pp::URLLoader loader_;
+ pp::CompletionCallbackFactory<DocumentLoader> loader_factory_;
+ ChunkStream chunk_stream_;
+ bool partial_document_;
+ bool request_pending_;
+ typedef std::list<std::pair<size_t, size_t> > PendingRequests;
+ PendingRequests pending_requests_;
+ char buffer_[kDefaultRequestSize];
+ uint32 current_pos_;
+ uint32 current_chunk_size_;
+ uint32 current_chunk_read_;
+ uint32 document_size_;
+ bool header_request_;
+ bool is_multipart_;
+ std::string multipart_boundary_;
+ uint32 requests_count_;
+ std::list<std::vector<unsigned char> > chunk_buffer_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_DOCUMENT_LOADER_H_
diff --git a/xfa_test/pdf/draw_utils.cc b/xfa_test/pdf/draw_utils.cc
new file mode 100644
index 0000000000..d38be52aef
--- /dev/null
+++ b/xfa_test/pdf/draw_utils.cc
@@ -0,0 +1,343 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/draw_utils.h"
+
+#include <algorithm>
+#include <math.h>
+#include <vector>
+
+#include "base/logging.h"
+#include "base/numerics/safe_math.h"
+
+namespace chrome_pdf {
+
+inline uint8 GetBlue(const uint32& pixel) {
+ return static_cast<uint8>(pixel & 0xFF);
+}
+
+inline uint8 GetGreen(const uint32& pixel) {
+ return static_cast<uint8>((pixel >> 8) & 0xFF);
+}
+
+inline uint8 GetRed(const uint32& pixel) {
+ return static_cast<uint8>((pixel >> 16) & 0xFF);
+}
+
+inline uint8 GetAlpha(const uint32& pixel) {
+ return static_cast<uint8>((pixel >> 24) & 0xFF);
+}
+
+inline uint32_t MakePixel(uint8 red, uint8 green, uint8 blue, uint8 alpha) {
+ return (static_cast<uint32_t>(alpha) << 24) |
+ (static_cast<uint32_t>(red) << 16) |
+ (static_cast<uint32_t>(green) << 8) |
+ static_cast<uint32_t>(blue);
+}
+
+inline uint8 GradientChannel(uint8 start, uint8 end, double ratio) {
+ double new_channel = start - (static_cast<double>(start) - end) * ratio;
+ if (new_channel < 0)
+ return 0;
+ if (new_channel > 255)
+ return 255;
+ return static_cast<uint8>(new_channel + 0.5);
+}
+
+inline uint8 ProcessColor(uint8 src_color, uint8 dest_color, uint8 alpha) {
+ uint32 processed = static_cast<uint32>(src_color) * alpha +
+ static_cast<uint32>(dest_color) * (0xFF - alpha);
+ return static_cast<uint8>((processed / 0xFF) & 0xFF);
+}
+
+inline bool ImageDataContainsRect(const pp::ImageData& image_data,
+ const pp::Rect& rect) {
+ return rect.width() >= 0 && rect.height() >= 0 &&
+ pp::Rect(image_data.size()).Contains(rect);
+}
+
+void AlphaBlend(const pp::ImageData& src, const pp::Rect& src_rc,
+ pp::ImageData* dest, const pp::Point& dest_origin,
+ uint8 alpha_adjustment) {
+ if (src_rc.IsEmpty() || !ImageDataContainsRect(src, src_rc))
+ return;
+
+ pp::Rect dest_rc(dest_origin, src_rc.size());
+ if (dest_rc.IsEmpty() || !ImageDataContainsRect(*dest, dest_rc))
+ return;
+
+ const uint32_t* src_origin_pixel = src.GetAddr32(src_rc.point());
+ uint32_t* dest_origin_pixel = dest->GetAddr32(dest_origin);
+
+ int height = src_rc.height();
+ int width = src_rc.width();
+ for (int y = 0; y < height; y++) {
+ const uint32_t* src_pixel = src_origin_pixel;
+ uint32_t* dest_pixel = dest_origin_pixel;
+ for (int x = 0; x < width; x++) {
+ uint8 alpha = static_cast<uint8>(static_cast<uint32_t>(alpha_adjustment) *
+ GetAlpha(*src_pixel) / 0xFF);
+ uint8 red = ProcessColor(GetRed(*src_pixel), GetRed(*dest_pixel), alpha);
+ uint8 green = ProcessColor(GetGreen(*src_pixel),
+ GetGreen(*dest_pixel), alpha);
+ uint8 blue = ProcessColor(GetBlue(*src_pixel),
+ GetBlue(*dest_pixel), alpha);
+ *dest_pixel = MakePixel(red, green, blue, GetAlpha(*dest_pixel));
+
+ src_pixel++;
+ dest_pixel++;
+ }
+ src_origin_pixel = reinterpret_cast<const uint32_t*>(
+ reinterpret_cast<const char*>(src_origin_pixel) + src.stride());
+ dest_origin_pixel = reinterpret_cast<uint32_t*>(
+ reinterpret_cast<char*>(dest_origin_pixel) + dest->stride());
+ }
+}
+
+void GradientFill(pp::ImageData* image, const pp::Rect& rc,
+ uint32 start_color, uint32 end_color, bool horizontal) {
+ std::vector<uint32> colors;
+ colors.resize(horizontal ? rc.width() : rc.height());
+ for (size_t i = 0; i < colors.size(); ++i) {
+ double ratio = static_cast<double>(i) / colors.size();
+ colors[i] = MakePixel(
+ GradientChannel(GetRed(start_color), GetRed(end_color), ratio),
+ GradientChannel(GetGreen(start_color), GetGreen(end_color), ratio),
+ GradientChannel(GetBlue(start_color), GetBlue(end_color), ratio),
+ GradientChannel(GetAlpha(start_color), GetAlpha(end_color), ratio));
+ }
+
+ if (horizontal) {
+ const void* data = &(colors[0]);
+ size_t size = colors.size() * 4;
+ uint32_t* origin_pixel = image->GetAddr32(rc.point());
+ for (int y = 0; y < rc.height(); y++) {
+ memcpy(origin_pixel, data, size);
+ origin_pixel = reinterpret_cast<uint32_t*>(
+ reinterpret_cast<char*>(origin_pixel) + image->stride());
+ }
+ } else {
+ uint32_t* origin_pixel = image->GetAddr32(rc.point());
+ for (int y = 0; y < rc.height(); y++) {
+ uint32_t* pixel = origin_pixel;
+ for (int x = 0; x < rc.width(); x++) {
+ *pixel = colors[y];
+ pixel++;
+ }
+ origin_pixel = reinterpret_cast<uint32_t*>(
+ reinterpret_cast<char*>(origin_pixel) + image->stride());
+ }
+ }
+}
+
+void GradientFill(pp::Instance* instance,
+ pp::ImageData* image,
+ const pp::Rect& dirty_rc,
+ const pp::Rect& gradient_rc,
+ uint32 start_color,
+ uint32 end_color,
+ bool horizontal,
+ uint8 transparency) {
+ pp::Rect draw_rc = gradient_rc.Intersect(dirty_rc);
+ if (draw_rc.IsEmpty())
+ return;
+
+ pp::ImageData gradient(instance, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ gradient_rc.size(), false);
+
+ GradientFill(&gradient, pp::Rect(pp::Point(), gradient_rc.size()),
+ start_color, end_color, horizontal);
+
+ pp::Rect copy_rc(draw_rc);
+ copy_rc.Offset(-gradient_rc.x(), -gradient_rc.y());
+ AlphaBlend(gradient, copy_rc, image, draw_rc.point(), transparency);
+}
+
+void CopyImage(const pp::ImageData& src, const pp::Rect& src_rc,
+ pp::ImageData* dest, const pp::Rect& dest_rc,
+ bool stretch) {
+ if (src_rc.IsEmpty() || !ImageDataContainsRect(src, src_rc))
+ return;
+
+ pp::Rect stretched_rc(dest_rc.point(),
+ stretch ? dest_rc.size() : src_rc.size());
+ if (stretched_rc.IsEmpty() || !ImageDataContainsRect(*dest, stretched_rc))
+ return;
+
+ const uint32_t* src_origin_pixel = src.GetAddr32(src_rc.point());
+ uint32_t* dest_origin_pixel = dest->GetAddr32(dest_rc.point());
+ if (stretch) {
+ double x_ratio = static_cast<double>(src_rc.width()) / dest_rc.width();
+ double y_ratio = static_cast<double>(src_rc.height()) / dest_rc.height();
+ int32_t height = dest_rc.height();
+ int32_t width = dest_rc.width();
+ for (int32_t y = 0; y < height; ++y) {
+ uint32_t* dest_pixel = dest_origin_pixel;
+ for (int32_t x = 0; x < width; ++x) {
+ uint32 src_x = static_cast<uint32>(x * x_ratio);
+ uint32 src_y = static_cast<uint32>(y * y_ratio);
+ const uint32_t* src_pixel = src.GetAddr32(
+ pp::Point(src_rc.x() + src_x, src_rc.y() + src_y));
+ *dest_pixel = *src_pixel;
+ dest_pixel++;
+ }
+ dest_origin_pixel = reinterpret_cast<uint32_t*>(
+ reinterpret_cast<char*>(dest_origin_pixel) + dest->stride());
+ }
+ } else {
+ int32_t height = src_rc.height();
+ base::CheckedNumeric<int32_t> width_bytes = src_rc.width();
+ width_bytes *= 4;
+ for (int32_t y = 0; y < height; ++y) {
+ memcpy(dest_origin_pixel, src_origin_pixel, width_bytes.ValueOrDie());
+ src_origin_pixel = reinterpret_cast<const uint32_t*>(
+ reinterpret_cast<const char*>(src_origin_pixel) + src.stride());
+ dest_origin_pixel = reinterpret_cast<uint32_t*>(
+ reinterpret_cast<char*>(dest_origin_pixel) + dest->stride());
+ }
+ }
+}
+
+void FillRect(pp::ImageData* image, const pp::Rect& rc, uint32 color) {
+ int height = rc.height();
+ if (height == 0)
+ return;
+
+ // Fill in first row.
+ uint32_t* top_line = image->GetAddr32(rc.point());
+ int width = rc.width();
+ for (int x = 0; x < width; x++)
+ top_line[x] = color;
+
+ // Fill in the rest of the rectangle.
+ int byte_width = width * 4;
+ uint32_t* cur_line = reinterpret_cast<uint32_t*>(
+ reinterpret_cast<char*>(top_line) + image->stride());
+ for (int y = 1; y < height; y++) {
+ memcpy(cur_line, top_line, byte_width);
+ cur_line = reinterpret_cast<uint32_t*>(
+ reinterpret_cast<char*>(cur_line) + image->stride());
+ }
+}
+
+ShadowMatrix::ShadowMatrix(uint32 depth, double factor, uint32 background)
+ : depth_(depth), factor_(factor), background_(background) {
+ DCHECK(depth_ > 0);
+ matrix_.resize(depth_ * depth_);
+
+ // pv - is a rounding power factor for smoothing corners.
+ // pv = 2.0 will make corners completely round.
+ const double pv = 4.0;
+ // pow_pv - cache to avoid recalculating pow(x, pv) every time.
+ std::vector<double> pow_pv(depth_, 0.0);
+
+ double r = static_cast<double>(depth_);
+ double coef = 256.0 / pow(r, factor);
+
+ for (uint32 y = 0; y < depth_; y++) {
+ // Since matrix is symmetrical, we can reduce the number of calculations
+ // by mirroring results.
+ for (uint32 x = 0; x <= y; x++) {
+ // Fill cache if needed.
+ if (pow_pv[x] == 0.0)
+ pow_pv[x] = pow(x, pv);
+ if (pow_pv[y] == 0.0)
+ pow_pv[y] = pow(y, pv);
+
+ // v - is a value for the smoothing function.
+ // If x == 0 simplify calculations.
+ double v = (x == 0) ? y : pow(pow_pv[x] + pow_pv[y], 1 / pv);
+
+ // Smoothing function.
+ // If factor == 1, smoothing will be linear from 0 to the end,
+ // if 0 < factor < 1, smoothing will drop faster near 0.
+ // if factor > 1, smoothing will drop faster near the end (depth).
+ double f = 256.0 - coef * pow(v, factor);
+
+ uint8 alpha = 0;
+ if (f > kOpaqueAlpha)
+ alpha = kOpaqueAlpha;
+ else if (f < kTransparentAlpha)
+ alpha = kTransparentAlpha;
+ else
+ alpha = static_cast<uint8>(f);
+
+ uint8 red = ProcessColor(0, GetRed(background), alpha);
+ uint8 green = ProcessColor(0, GetGreen(background), alpha);
+ uint8 blue = ProcessColor(0, GetBlue(background), alpha);
+ uint32 pixel = MakePixel(red, green, blue, GetAlpha(background));
+
+ // Mirror matrix.
+ matrix_[y * depth_ + x] = pixel;
+ matrix_[x * depth_ + y] = pixel;
+ }
+ }
+}
+
+ShadowMatrix::~ShadowMatrix() {
+}
+
+void PaintShadow(pp::ImageData* image,
+ const pp::Rect& clip_rc,
+ const pp::Rect& shadow_rc,
+ const ShadowMatrix& matrix) {
+ pp::Rect draw_rc = shadow_rc.Intersect(clip_rc);
+ if (draw_rc.IsEmpty())
+ return;
+
+ int32 depth = static_cast<int32>(matrix.depth());
+ for (int32_t y = draw_rc.y(); y < draw_rc.bottom(); y++) {
+ for (int32_t x = draw_rc.x(); x < draw_rc.right(); x++) {
+ int32_t matrix_x = std::max(depth + shadow_rc.x() - x - 1,
+ depth - shadow_rc.right() + x);
+ int32_t matrix_y = std::max(depth + shadow_rc.y() - y - 1,
+ depth - shadow_rc.bottom() + y);
+ uint32_t* pixel = image->GetAddr32(pp::Point(x, y));
+
+ if (matrix_x < 0)
+ matrix_x = 0;
+ else if (matrix_x >= static_cast<int32>(depth))
+ matrix_x = depth - 1;
+
+ if (matrix_y < 0)
+ matrix_y = 0;
+ else if (matrix_y >= static_cast<int32>(depth))
+ matrix_y = depth - 1;
+
+ *pixel = matrix.GetValue(matrix_x, matrix_y);
+ }
+ }
+}
+
+void DrawShadow(pp::ImageData* image,
+ const pp::Rect& shadow_rc,
+ const pp::Rect& object_rc,
+ const pp::Rect& clip_rc,
+ const ShadowMatrix& matrix) {
+ if (shadow_rc == object_rc)
+ return; // Nothing to paint.
+
+ // Fill top part.
+ pp::Rect rc(shadow_rc.point(),
+ pp::Size(shadow_rc.width(), object_rc.y() - shadow_rc.y()));
+ PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);
+
+ // Fill bottom part.
+ rc = pp::Rect(shadow_rc.x(), object_rc.bottom(),
+ shadow_rc.width(), shadow_rc.bottom() - object_rc.bottom());
+ PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);
+
+ // Fill left part.
+ rc = pp::Rect(shadow_rc.x(), object_rc.y(),
+ object_rc.x() - shadow_rc.x(), object_rc.height());
+ PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);
+
+ // Fill right part.
+ rc = pp::Rect(object_rc.right(), object_rc.y(),
+ shadow_rc.right() - object_rc.right(), object_rc.height());
+ PaintShadow(image, rc.Intersect(clip_rc), shadow_rc, matrix);
+}
+
+} // namespace chrome_pdf
+
diff --git a/xfa_test/pdf/draw_utils.h b/xfa_test/pdf/draw_utils.h
new file mode 100644
index 0000000000..eedf24f27d
--- /dev/null
+++ b/xfa_test/pdf/draw_utils.h
@@ -0,0 +1,94 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_DRAW_UTILS_H_
+#define PDF_DRAW_UTILS_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/rect.h"
+
+namespace chrome_pdf {
+
+const uint8 kOpaqueAlpha = 0xFF;
+const uint8 kTransparentAlpha = 0x00;
+
+void AlphaBlend(const pp::ImageData& src, const pp::Rect& src_rc,
+ pp::ImageData* dest, const pp::Point& dest_origin,
+ uint8 alpha_adjustment);
+
+// Fill rectangle with gradient horizontally or vertically. Start is a color of
+// top-left point of the rectangle, end color is a color of
+// top-right (horizontal==true) or bottom-left (horizontal==false) point.
+void GradientFill(pp::ImageData* image,
+ const pp::Rect& rc,
+ uint32 start_color,
+ uint32 end_color,
+ bool horizontal);
+
+// Fill dirty rectangle with gradient, where gradient color set for corners of
+// gradient rectangle. Parts of the dirty rect outside of gradient rect will
+// be unchanged.
+void GradientFill(pp::Instance* instance,
+ pp::ImageData* image,
+ const pp::Rect& dirty_rc,
+ const pp::Rect& gradient_rc,
+ uint32 start_color,
+ uint32 end_color,
+ bool horizontal,
+ uint8 transparency);
+
+// Copy one image into another. If stretch is true, the result occupy the entire
+// dest_rc. If stretch is false, dest_rc.point will be used as an origin of the
+// result image. Copy will ignore all pixels with transparent alpha from the
+// source image.
+void CopyImage(const pp::ImageData& src, const pp::Rect& src_rc,
+ pp::ImageData* dest, const pp::Rect& dest_rc,
+ bool stretch);
+
+// Fill in rectangle with specified color.
+void FillRect(pp::ImageData* image, const pp::Rect& rc, uint32 color);
+
+// Shadow Matrix contains matrix for shadow rendering. To reduce amount of
+// calculations user may choose to cache matrix and reuse it if nothing changed.
+class ShadowMatrix {
+ public:
+ // Matrix parameters.
+ // depth - how big matrix should be. Shadow will go smoothly across the
+ // entire matrix from black to background color.
+ // If factor == 1, smoothing will be linear from 0 to the end (depth),
+ // if 0 < factor < 1, smoothing will drop faster near 0.
+ // if factor > 1, smoothing will drop faster near the end (depth).
+ ShadowMatrix(uint32 depth, double factor, uint32 background);
+
+ ~ShadowMatrix();
+
+ uint32 GetValue(int32 x, int32 y) const { return matrix_[y * depth_ + x]; }
+
+ uint32 depth() const { return depth_; }
+ double factor() const { return factor_; }
+ uint32 background() const { return background_; }
+
+ private:
+ uint32 depth_;
+ double factor_;
+ uint32 background_;
+ std::vector<uint32> matrix_;
+};
+
+// Draw shadow on the image using provided ShadowMatrix.
+// shadow_rc - rectangle occupied by shadow
+// object_rc - rectangle that drops the shadow
+// clip_rc - clipping region
+void DrawShadow(pp::ImageData* image,
+ const pp::Rect& shadow_rc,
+ const pp::Rect& object_rc,
+ const pp::Rect& clip_rc,
+ const ShadowMatrix& matrix);
+
+} // namespace chrome_pdf
+
+#endif // PDF_DRAW_UTILS_H_
diff --git a/xfa_test/pdf/fading_control.cc b/xfa_test/pdf/fading_control.cc
new file mode 100644
index 0000000000..7e4d8ef63e
--- /dev/null
+++ b/xfa_test/pdf/fading_control.cc
@@ -0,0 +1,75 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/fading_control.h"
+
+#include <math.h>
+
+#include "base/logging.h"
+#include "pdf/draw_utils.h"
+#include "pdf/resource_consts.h"
+
+namespace chrome_pdf {
+
+FadingControl::FadingControl()
+ : alpha_shift_(0), timer_id_(0) {
+}
+
+FadingControl::~FadingControl() {
+}
+
+void FadingControl::OnTimerFired(uint32 timer_id) {
+ if (timer_id == timer_id_) {
+ int32 new_alpha = transparency() + alpha_shift_;
+ if (new_alpha <= kTransparentAlpha) {
+ Show(false, true);
+ OnFadeOutComplete();
+ return;
+ }
+ if (new_alpha >= kOpaqueAlpha) {
+ AdjustTransparency(kOpaqueAlpha, true);
+ OnFadeInComplete();
+ return;
+ }
+
+ AdjustTransparency(static_cast<uint8>(new_alpha), true);
+ timer_id_ = owner()->ScheduleTimer(id(), kFadingTimeoutMs);
+ }
+}
+
+// Fade In/Out control depending on visible flag over the time of time_ms.
+void FadingControl::Fade(bool show, uint32 time_ms) {
+ DCHECK(time_ms != 0);
+ // Check if we already in the same state.
+ if (!visible() && !show)
+ return;
+ if (!visible() && show) {
+ Show(show, false);
+ AdjustTransparency(kTransparentAlpha, false);
+ OnFadeOutComplete();
+ }
+ if (transparency() == kOpaqueAlpha && show) {
+ OnFadeInComplete();
+ return;
+ }
+
+ int delta = show ? kOpaqueAlpha - transparency() : transparency();
+ double shift =
+ static_cast<double>(delta) * kFadingTimeoutMs / time_ms;
+ if (shift > delta)
+ alpha_shift_ = delta;
+ else
+ alpha_shift_ = static_cast<int>(ceil(shift));
+
+ if (alpha_shift_ == 0)
+ alpha_shift_ = 1;
+
+ // If disabling, make alpha shift negative.
+ if (!show)
+ alpha_shift_ = -alpha_shift_;
+
+ timer_id_ = owner()->ScheduleTimer(id(), kFadingTimeoutMs);
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/fading_control.h b/xfa_test/pdf/fading_control.h
new file mode 100644
index 0000000000..03ac134698
--- /dev/null
+++ b/xfa_test/pdf/fading_control.h
@@ -0,0 +1,32 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_FADING_CONTROL_H_
+#define PDF_FADING_CONTROL_H_
+
+#include "pdf/control.h"
+
+namespace chrome_pdf {
+
+class FadingControl : public Control {
+ public:
+ FadingControl();
+ virtual ~FadingControl();
+
+ virtual void OnTimerFired(uint32 timer_id);
+
+ // Fade In/Out control depending on visible flag over the time of time_ms.
+ virtual void Fade(bool visible, uint32 time_ms);
+
+ virtual void OnFadeInComplete() {}
+ virtual void OnFadeOutComplete() {}
+
+ private:
+ int alpha_shift_;
+ uint32 timer_id_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_FADING_CONTROL_H_
diff --git a/xfa_test/pdf/fading_controls.cc b/xfa_test/pdf/fading_controls.cc
new file mode 100644
index 0000000000..8a9fd89510
--- /dev/null
+++ b/xfa_test/pdf/fading_controls.cc
@@ -0,0 +1,316 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/fading_controls.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "pdf/draw_utils.h"
+#include "pdf/resource_consts.h"
+#include "ppapi/cpp/input_event.h"
+
+namespace chrome_pdf {
+
+const uint32 kFadingAlphaShift = 64;
+const uint32 kSplashFadingAlphaShift = 16;
+
+FadingControls::FadingControls()
+ : state_(NONE), current_transparency_(kOpaqueAlpha), fading_timer_id_(0),
+ current_capture_control_(kInvalidControlId),
+ fading_timeout_(kFadingTimeoutMs), alpha_shift_(kFadingAlphaShift),
+ splash_(false), splash_timeout_(0) {
+}
+
+FadingControls::~FadingControls() {
+ STLDeleteElements(&controls_);
+}
+
+bool FadingControls::CreateFadingControls(
+ uint32 id, const pp::Rect& rc, bool visible,
+ Control::Owner* owner, uint8 transparency) {
+ current_transparency_ = transparency;
+ return Control::Create(id, rc, visible, owner);
+}
+
+void FadingControls::Paint(pp::ImageData* image_data, const pp::Rect& rc) {
+ // When this control is set to invisible the individual controls are not.
+ // So we need to check for visible() here.
+ if (!visible())
+ return;
+
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ (*iter)->Paint(image_data, rc);
+ }
+}
+
+bool FadingControls::HandleEvent(const pp::InputEvent& event) {
+ if (!visible())
+ return false;
+
+ pp::MouseInputEvent mouse_event(event);
+ if (mouse_event.is_null())
+ return NotifyControls(event);
+
+ pp::Point pt = mouse_event.GetPosition();
+
+ bool is_mouse_click =
+ mouse_event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN ||
+ mouse_event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP;
+
+ if (rect().Contains(pt)) {
+ CancelSplashMode();
+ FadeIn();
+
+ // Eat mouse click if are invisible or just fading in.
+ // That prevents accidental clicks on the controls for touch devices.
+ bool eat_mouse_click =
+ (state_ == FADING_IN || current_transparency_ == kTransparentAlpha);
+ if (eat_mouse_click && is_mouse_click &&
+ mouse_event.GetButton() == PP_INPUTEVENT_MOUSEBUTTON_LEFT)
+ return true; // Eat this event here.
+ }
+
+ if ((!rect().Contains(pt)) ||
+ event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE) {
+ if (!splash_)
+ FadeOut();
+ pp::MouseInputEvent event_leave(pp::MouseInputEvent(
+ owner()->GetInstance(),
+ PP_INPUTEVENT_TYPE_MOUSELEAVE,
+ event.GetTimeStamp(),
+ event.GetModifiers(),
+ mouse_event.GetButton(),
+ mouse_event.GetPosition(),
+ mouse_event.GetClickCount(),
+ mouse_event.GetMovement()));
+ return NotifyControls(event_leave);
+ }
+
+ return NotifyControls(event);
+}
+
+void FadingControls::OnTimerFired(uint32 timer_id) {
+ if (timer_id == fading_timer_id_) {
+ int32 current_alpha = static_cast<int32>(current_transparency_);
+ if (state_ == FADING_IN)
+ current_alpha += alpha_shift_;
+ else if (state_ == FADING_OUT)
+ current_alpha -= alpha_shift_;
+
+ if (current_alpha >= kOpaqueAlpha) {
+ state_ = NONE;
+ current_alpha = kOpaqueAlpha;
+ } else if (current_alpha <= kTransparentAlpha) {
+ state_ = NONE;
+ current_alpha = kTransparentAlpha;
+ }
+ current_transparency_ = static_cast<uint8>(current_alpha);
+
+ // Invalidate controls with new alpha transparency.
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ // We are going to invalidate the whole FadingControls area, to
+ // allow simultaneous drawing.
+ (*iter)->AdjustTransparency(current_transparency_, false);
+ }
+ owner()->Invalidate(id(), GetControlsRect());
+
+ if (state_ != NONE) // Fading still in progress.
+ fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_);
+ else
+ OnFadingComplete();
+ } else {
+ // Dispatch timer to controls.
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ (*iter)->OnTimerFired(timer_id);
+ }
+ }
+}
+
+void FadingControls::EventCaptureReleased() {
+ if (current_capture_control_ != kInvalidControlId) {
+ // Remove previous catpure.
+ Control* ctrl = GetControl(current_capture_control_);
+ if (ctrl)
+ ctrl->EventCaptureReleased();
+ }
+}
+
+void FadingControls::MoveBy(const pp::Point& offset, bool invalidate) {
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ // We invalidate entire FadingControl later if needed.
+ (*iter)->MoveBy(offset, false);
+ }
+ Control::MoveBy(offset, invalidate);
+}
+
+void FadingControls::OnEvent(uint32 control_id, uint32 event_id, void* data) {
+ owner()->OnEvent(control_id, event_id, data);
+}
+
+void FadingControls::Invalidate(uint32 control_id, const pp::Rect& rc) {
+ owner()->Invalidate(control_id, rc);
+}
+
+uint32 FadingControls::ScheduleTimer(uint32 control_id, uint32 timeout_ms) {
+ // TODO(gene): implement timer routine properly.
+ NOTIMPLEMENTED();
+ //owner()->ScheduleTimer(control_id);
+ return 0;
+}
+
+void FadingControls::SetEventCapture(uint32 control_id, bool set_capture) {
+ if (control_id == current_capture_control_) {
+ if (!set_capture) // Remove event capture.
+ current_capture_control_ = kInvalidControlId;
+ } else {
+ EventCaptureReleased();
+ current_capture_control_ = control_id;
+ }
+}
+
+void FadingControls::SetCursor(uint32 control_id,
+ PP_CursorType_Dev cursor_type) {
+ owner()->SetCursor(control_id, cursor_type);
+}
+
+pp::Instance* FadingControls::GetInstance() {
+ return owner()->GetInstance();
+}
+
+bool FadingControls::AddControl(Control* control) {
+ DCHECK(control);
+ if (control->owner() != this)
+ return false;
+ if (!rect().Contains(control->rect()))
+ return false;
+
+ control->AdjustTransparency(current_transparency_, false);
+ controls_.push_back(control);
+ return true;
+}
+
+void FadingControls::RemoveControl(uint32 control_id) {
+ if (current_capture_control_ == control_id) {
+ current_capture_control_ = kInvalidControlId;
+ }
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ if ((*iter)->id() == control_id) {
+ delete (*iter);
+ controls_.erase(iter);
+ break;
+ }
+ }
+}
+
+Control* FadingControls::GetControl(uint32 id) {
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ if ((*iter)->id() == id)
+ return *iter;
+ }
+ return NULL;
+}
+
+pp::Rect FadingControls::GetControlsRect() {
+ pp::Rect rc;
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ rc = rc.Union((*iter)->rect());
+ }
+ return rc;
+}
+
+bool FadingControls::ExpandLeft(int offset) {
+ pp::Rect rc = rect();
+ rc.set_width(rc.width() + offset);
+ rc.set_x(rc.x() - offset);
+ if (!rc.Contains(GetControlsRect()))
+ return false;
+ // No need to invalidate since we are expanding triggering area only.
+ SetRect(rc, false);
+ return true;
+}
+
+void FadingControls::Splash(uint32 time_ms) {
+ splash_ = true;
+ splash_timeout_ = time_ms;
+ alpha_shift_ = kSplashFadingAlphaShift;
+ FadeIn();
+}
+
+bool FadingControls::NotifyControls(const pp::InputEvent& event) {
+ // First pass event to a control that current capture is set to.
+ Control* ctrl = GetControl(current_capture_control_);
+ if (ctrl) {
+ if (ctrl->HandleEvent(event))
+ return true;
+ }
+
+ std::list<Control*>::iterator iter;
+ for (iter = controls_.begin(); iter != controls_.end(); ++iter) {
+ // Now pass event to all control except control with capture,
+ // since we already passed to it above.
+ if ((*iter) != ctrl && (*iter)->HandleEvent(event))
+ return true;
+ }
+ return false;
+}
+
+void FadingControls::FadeIn() {
+ bool already_visible =
+ (state_ == NONE && current_transparency_ == kOpaqueAlpha);
+ if (state_ != FADING_IN && !already_visible) {
+ state_ = FADING_IN;
+ fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_);
+ }
+ if (already_visible)
+ OnFadingComplete();
+}
+
+void FadingControls::FadeOut() {
+ bool already_invisible =
+ (state_ == NONE && current_transparency_ == kTransparentAlpha);
+ if (state_ != FADING_OUT && !already_invisible) {
+ state_ = FADING_OUT;
+ fading_timer_id_ = owner()->ScheduleTimer(id(), fading_timeout_);
+ }
+ if (already_invisible)
+ OnFadingComplete();
+}
+
+void FadingControls::OnFadingComplete() {
+ DCHECK(current_transparency_ == kOpaqueAlpha ||
+ current_transparency_ == kTransparentAlpha);
+ // In the splash mode following states are possible:
+ // Fade-in complete: splash_==true, splash_timeout_ != 0
+ // We need to schedule timer for splash_timeout_.
+ // Splash timeout complete: splash_==true, splash_timeout_ == 0
+ // We need to fade out still using splash settings.
+ // Fade-out complete: current_transparency_ == kTransparentAlpha
+ // We need to cancel splash mode and go back to normal settings.
+ if (splash_) {
+ if (current_transparency_ == kOpaqueAlpha) {
+ if (splash_timeout_) {
+ fading_timer_id_ = owner()->ScheduleTimer(id(), splash_timeout_);
+ splash_timeout_ = 0;
+ } else {
+ FadeOut();
+ }
+ } else {
+ CancelSplashMode();
+ }
+ }
+}
+
+void FadingControls::CancelSplashMode() {
+ splash_ = false;
+ alpha_shift_ = kFadingAlphaShift;
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/fading_controls.h b/xfa_test/pdf/fading_controls.h
new file mode 100644
index 0000000000..532464b473
--- /dev/null
+++ b/xfa_test/pdf/fading_controls.h
@@ -0,0 +1,84 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_FADING_CONTROLS_H_
+#define PDF_FADING_CONTROLS_H_
+
+#include <list>
+
+#include "pdf/control.h"
+
+namespace chrome_pdf {
+
+class FadingControls : public Control,
+ public ControlOwner {
+ public:
+ enum FadingState {
+ NONE,
+ FADING_IN,
+ FADING_OUT
+ };
+
+ FadingControls();
+ virtual ~FadingControls();
+ virtual bool CreateFadingControls(
+ uint32 id, const pp::Rect& rc, bool visible,
+ Control::Owner* delegate, uint8 transparency);
+
+ // Control interface.
+ virtual void Paint(pp::ImageData* image_data, const pp::Rect& rc);
+ virtual bool HandleEvent(const pp::InputEvent& event);
+ virtual void OnTimerFired(uint32 timer_id);
+ virtual void EventCaptureReleased();
+ virtual void MoveBy(const pp::Point& offset, bool invalidate);
+
+ // ControlOwner interface.
+ virtual void OnEvent(uint32 control_id, uint32 event_id, void* data);
+ virtual void Invalidate(uint32 control_id, const pp::Rect& rc);
+ virtual uint32 ScheduleTimer(uint32 control_id, uint32 timeout_ms);
+ virtual void SetEventCapture(uint32 control_id, bool set_capture);
+ virtual void SetCursor(uint32 control_id, PP_CursorType_Dev cursor_type);
+ virtual pp::Instance* GetInstance();
+
+ // FadingControls interface
+ // This function takes ownership of the control, and will destoy it
+ // when control is destroyed.
+ // Input control MUST be located inside FadingControls boundaries, and has
+ // this instance of FadingControls as a delegate.
+ virtual bool AddControl(Control* control);
+ virtual void RemoveControl(uint32 control_id);
+ virtual Control* GetControl(uint32 id);
+ virtual pp::Rect GetControlsRect();
+
+ // Expand/Shrink area which triggers inner control appearance to the left.
+ virtual bool ExpandLeft(int offset);
+
+ // Fade-in, then show controls for time_ms, and then fade-out. Any mouse
+ // event in this control area will interrupt splash mode.
+ virtual void Splash(uint32 time_ms);
+
+ uint8 current_transparency() const { return current_transparency_; }
+
+ private:
+ bool NotifyControls(const pp::InputEvent& event);
+ void FadeIn();
+ void FadeOut();
+ void OnFadingComplete();
+ void CancelSplashMode();
+
+ std::list<Control*> controls_;
+ FadingState state_;
+ uint8 current_transparency_;
+ uint32 fading_timer_id_;
+ uint32 current_capture_control_;
+ uint32 fading_timeout_;
+ uint32 alpha_shift_;
+ bool splash_;
+ uint32 splash_timeout_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_FADING_CONTROLS_H_
+
diff --git a/xfa_test/pdf/instance.cc b/xfa_test/pdf/instance.cc
new file mode 100644
index 0000000000..4bd2f787df
--- /dev/null
+++ b/xfa_test/pdf/instance.cc
@@ -0,0 +1,2778 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/instance.h"
+
+#include <algorithm> // for min()
+#define _USE_MATH_DEFINES // for M_PI
+#include <cmath> // for log() and pow()
+#include <math.h>
+#include <list>
+
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "chrome/browser/chrome_page_zoom_constants.h"
+#include "chrome/common/content_restriction.h"
+#include "content/public/common/page_zoom.h"
+#include "net/base/escape.h"
+#include "pdf/draw_utils.h"
+#include "pdf/number_image_generator.h"
+#include "pdf/pdf.h"
+#include "pdf/resource_consts.h"
+#include "ppapi/c/dev/ppb_cursor_control_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/c/private/ppp_pdf.h"
+#include "ppapi/c/trusted/ppb_url_loader_trusted.h"
+#include "ppapi/cpp/core.h"
+#include "ppapi/cpp/dev/font_dev.h"
+#include "ppapi/cpp/dev/memory_dev.h"
+#include "ppapi/cpp/dev/text_input_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/private/pdf.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/url_request_info.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+#if defined(OS_MACOSX)
+#include "base/mac/mac_util.h"
+#endif
+
+namespace chrome_pdf {
+
+struct ToolbarButtonInfo {
+ uint32 id;
+ Button::ButtonStyle style;
+ PP_ResourceImage normal;
+ PP_ResourceImage highlighted;
+ PP_ResourceImage pressed;
+};
+
+namespace {
+
+// Uncomment following #define to enable thumbnails.
+// #define ENABLE_THUMBNAILS
+
+const uint32 kToolbarSplashTimeoutMs = 6000;
+const uint32 kMessageTextColor = 0xFF575757;
+const uint32 kMessageTextSize = 22;
+const uint32 kProgressFadeTimeoutMs = 250;
+const uint32 kProgressDelayTimeoutMs = 1000;
+const uint32 kAutoScrollTimeoutMs = 50;
+const double kAutoScrollFactor = 0.2;
+
+// Javascript methods.
+const char kJSAccessibility[] = "accessibility";
+const char kJSDocumentLoadComplete[] = "documentLoadComplete";
+const char kJSGetHeight[] = "getHeight";
+const char kJSGetHorizontalScrollbarThickness[] =
+ "getHorizontalScrollbarThickness";
+const char kJSGetPageLocationNormalized[] = "getPageLocationNormalized";
+const char kJSGetSelectedText[] = "getSelectedText";
+const char kJSGetVerticalScrollbarThickness[] = "getVerticalScrollbarThickness";
+const char kJSGetWidth[] = "getWidth";
+const char kJSGetZoomLevel[] = "getZoomLevel";
+const char kJSGoToPage[] = "goToPage";
+const char kJSGrayscale[] = "grayscale";
+const char kJSLoadPreviewPage[] = "loadPreviewPage";
+const char kJSOnLoad[] = "onload";
+const char kJSOnPluginSizeChanged[] = "onPluginSizeChanged";
+const char kJSOnScroll[] = "onScroll";
+const char kJSPageXOffset[] = "pageXOffset";
+const char kJSPageYOffset[] = "pageYOffset";
+const char kJSPrintPreviewPageCount[] = "printPreviewPageCount";
+const char kJSReload[] = "reload";
+const char kJSRemovePrintButton[] = "removePrintButton";
+const char kJSResetPrintPreviewUrl[] = "resetPrintPreviewUrl";
+const char kJSSendKeyEvent[] = "sendKeyEvent";
+const char kJSSetPageNumbers[] = "setPageNumbers";
+const char kJSSetPageXOffset[] = "setPageXOffset";
+const char kJSSetPageYOffset[] = "setPageYOffset";
+const char kJSSetZoomLevel[] = "setZoomLevel";
+const char kJSZoomFitToHeight[] = "fitToHeight";
+const char kJSZoomFitToWidth[] = "fitToWidth";
+const char kJSZoomIn[] = "zoomIn";
+const char kJSZoomOut[] = "zoomOut";
+
+// URL reference parameters.
+// For more possible parameters, see RFC 3778 and the "PDF Open Parameters"
+// document from Adobe.
+const char kDelimiters[] = "#&";
+const char kNamedDest[] = "nameddest";
+const char kPage[] = "page";
+
+const char kChromePrint[] = "chrome://print/";
+
+// Dictionary Value key names for the document accessibility info
+const char kAccessibleNumberOfPages[] = "numberOfPages";
+const char kAccessibleLoaded[] = "loaded";
+const char kAccessibleCopyable[] = "copyable";
+
+const ToolbarButtonInfo kPDFToolbarButtons[] = {
+ { kFitToPageButtonId, Button::BUTTON_STATE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED },
+ { kFitToWidthButtonId, Button::BUTTON_STATE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED },
+ { kZoomOutButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED },
+ { kZoomInButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED },
+ { kSaveButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_SAVE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_PRESSED },
+ { kPrintButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_PRINT,
+ PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_PRESSED },
+};
+
+const ToolbarButtonInfo kPDFNoPrintToolbarButtons[] = {
+ { kFitToPageButtonId, Button::BUTTON_STATE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED },
+ { kFitToWidthButtonId, Button::BUTTON_STATE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED },
+ { kZoomOutButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED },
+ { kZoomInButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_PRESSED },
+ { kSaveButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_SAVE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_SAVE_PRESSED },
+ { kPrintButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_DISABLED,
+ PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_DISABLED,
+ PP_RESOURCEIMAGE_PDF_BUTTON_PRINT_DISABLED }
+};
+
+const ToolbarButtonInfo kPrintPreviewToolbarButtons[] = {
+ { kFitToPageButtonId, Button::BUTTON_STATE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTP_PRESSED },
+ { kFitToWidthButtonId, Button::BUTTON_STATE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_FTW_PRESSED },
+ { kZoomOutButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMOUT_PRESSED },
+ { kZoomInButtonId, Button::BUTTON_CLICKABLE,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_HOVER,
+ PP_RESOURCEIMAGE_PDF_BUTTON_ZOOMIN_END_PRESSED },
+};
+
+static const char kPPPPdfInterface[] = PPP_PDF_INTERFACE_1;
+
+PP_Var GetLinkAtPosition(PP_Instance instance, PP_Point point) {
+ pp::Var var;
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPdfInterface);
+ if (object)
+ var = static_cast<Instance*>(object)->GetLinkAtPosition(pp::Point(point));
+ return var.Detach();
+}
+
+void Transform(PP_Instance instance, PP_PrivatePageTransformType type) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPdfInterface);
+ if (object) {
+ Instance* obj_instance = static_cast<Instance*>(object);
+ switch (type) {
+ case PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW:
+ obj_instance->RotateClockwise();
+ break;
+ case PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW:
+ obj_instance->RotateCounterclockwise();
+ break;
+ }
+ }
+}
+
+const PPP_Pdf ppp_private = {
+ &GetLinkAtPosition,
+ &Transform
+};
+
+int ExtractPrintPreviewPageIndex(const std::string& src_url) {
+ // Sample |src_url| format: chrome://print/id/page_index/print.pdf
+ std::vector<std::string> url_substr;
+ base::SplitString(src_url.substr(strlen(kChromePrint)), '/', &url_substr);
+ if (url_substr.size() != 3)
+ return -1;
+
+ if (url_substr[2] != "print.pdf")
+ return -1;
+
+ int page_index = 0;
+ if (!base::StringToInt(url_substr[1], &page_index))
+ return -1;
+ return page_index;
+}
+
+bool IsPrintPreviewUrl(const std::string& url) {
+ return url.substr(0, strlen(kChromePrint)) == kChromePrint;
+}
+
+void ScalePoint(float scale, pp::Point* point) {
+ point->set_x(static_cast<int>(point->x() * scale));
+ point->set_y(static_cast<int>(point->y() * scale));
+}
+
+void ScaleRect(float scale, pp::Rect* rect) {
+ int left = static_cast<int>(floorf(rect->x() * scale));
+ int top = static_cast<int>(floorf(rect->y() * scale));
+ int right = static_cast<int>(ceilf((rect->x() + rect->width()) * scale));
+ int bottom = static_cast<int>(ceilf((rect->y() + rect->height()) * scale));
+ rect->SetRect(left, top, right - left, bottom - top);
+}
+
+template<class T>
+T ClipToRange(T value, T lower_boundary, T upper_boundary) {
+ DCHECK(lower_boundary <= upper_boundary);
+ return std::max<T>(lower_boundary, std::min<T>(value, upper_boundary));
+}
+
+} // namespace
+
+Instance::Instance(PP_Instance instance)
+ : pp::InstancePrivate(instance),
+ pp::Find_Private(this),
+ pp::Printing_Dev(this),
+ pp::Selection_Dev(this),
+ pp::WidgetClient_Dev(this),
+ pp::Zoom_Dev(this),
+ cursor_(PP_CURSORTYPE_POINTER),
+ timer_pending_(false),
+ current_timer_id_(0),
+ zoom_(1.0),
+ device_scale_(1.0),
+ printing_enabled_(true),
+ hidpi_enabled_(false),
+ full_(IsFullFrame()),
+ zoom_mode_(full_ ? ZOOM_AUTO : ZOOM_SCALE),
+ did_call_start_loading_(false),
+ is_autoscroll_(false),
+ scrollbar_thickness_(-1),
+ scrollbar_reserved_thickness_(-1),
+ current_tb_info_(NULL),
+ current_tb_info_size_(0),
+ paint_manager_(this, this, true),
+ delayed_progress_timer_id_(0),
+ first_paint_(true),
+ painted_first_page_(false),
+ show_page_indicator_(false),
+ document_load_state_(LOAD_STATE_LOADING),
+ preview_document_load_state_(LOAD_STATE_COMPLETE),
+ told_browser_about_unsupported_feature_(false),
+ print_preview_page_count_(0) {
+ loader_factory_.Initialize(this);
+ timer_factory_.Initialize(this);
+ form_factory_.Initialize(this);
+ callback_factory_.Initialize(this);
+ engine_.reset(PDFEngine::Create(this));
+ pp::Module::Get()->AddPluginInterface(kPPPPdfInterface, &ppp_private);
+ AddPerInstanceObject(kPPPPdfInterface, this);
+
+ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
+ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_WHEEL);
+ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
+ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_TOUCH);
+}
+
+Instance::~Instance() {
+ if (timer_pending_) {
+ timer_factory_.CancelAll();
+ timer_pending_ = false;
+ }
+ // The engine may try to access this instance during its destruction.
+ // Make sure this happens early while the instance is still intact.
+ engine_.reset();
+ RemovePerInstanceObject(kPPPPdfInterface, this);
+}
+
+bool Instance::Init(uint32_t argc, const char* argn[], const char* argv[]) {
+ // For now, we hide HiDPI support behind a flag.
+ if (pp::PDF::IsFeatureEnabled(this, PP_PDFFEATURE_HIDPI))
+ hidpi_enabled_ = true;
+
+ printing_enabled_ = pp::PDF::IsFeatureEnabled(this, PP_PDFFEATURE_PRINTING);
+ if (printing_enabled_) {
+ CreateToolbar(kPDFToolbarButtons, arraysize(kPDFToolbarButtons));
+ } else {
+ CreateToolbar(kPDFNoPrintToolbarButtons,
+ arraysize(kPDFNoPrintToolbarButtons));
+ }
+
+ CreateProgressBar();
+
+ // Load autoscroll anchor image.
+ autoscroll_anchor_ =
+ CreateResourceImage(PP_RESOURCEIMAGE_PDF_PAN_SCROLL_ICON);
+
+#ifdef ENABLE_THUMBNAILS
+ CreateThumbnails();
+#endif
+ const char* url = NULL;
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (strcmp(argn[i], "src") == 0) {
+ url = argv[i];
+ break;
+ }
+ }
+
+ if (!url)
+ return false;
+
+ CreatePageIndicator(IsPrintPreviewUrl(url));
+
+ if (!full_) {
+ // For PDFs embedded in a frame, we don't get the data automatically like we
+ // do for full-frame loads. Start loading the data manually.
+ LoadUrl(url);
+ } else {
+ DCHECK(!did_call_start_loading_);
+ pp::PDF::DidStartLoading(this);
+ did_call_start_loading_ = true;
+ }
+
+ ZoomLimitsChanged(kMinZoom, kMaxZoom);
+
+ text_input_.reset(new pp::TextInput_Dev(this));
+
+ url_ = url;
+ return engine_->New(url);
+}
+
+bool Instance::HandleDocumentLoad(const pp::URLLoader& loader) {
+ delayed_progress_timer_id_ = ScheduleTimer(kProgressBarId,
+ kProgressDelayTimeoutMs);
+ return engine_->HandleDocumentLoad(loader);
+}
+
+bool Instance::HandleInputEvent(const pp::InputEvent& event) {
+ // To simplify things, convert the event into device coordinates if it is
+ // a mouse event.
+ pp::InputEvent event_device_res(event);
+ {
+ pp::MouseInputEvent mouse_event(event);
+ if (!mouse_event.is_null()) {
+ pp::Point point = mouse_event.GetPosition();
+ pp::Point movement = mouse_event.GetMovement();
+ ScalePoint(device_scale_, &point);
+ ScalePoint(device_scale_, &movement);
+ mouse_event = pp::MouseInputEvent(
+ this,
+ event.GetType(),
+ event.GetTimeStamp(),
+ event.GetModifiers(),
+ mouse_event.GetButton(),
+ point,
+ mouse_event.GetClickCount(),
+ movement);
+ event_device_res = mouse_event;
+ }
+ }
+
+ // Check if we need to go to autoscroll mode.
+ if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE &&
+ (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN)) {
+ pp::MouseInputEvent mouse_event(event_device_res);
+ pp::Point pos = mouse_event.GetPosition();
+ EnableAutoscroll(pos);
+ UpdateCursor(CalculateAutoscroll(pos));
+ return true;
+ } else {
+ // Quit autoscrolling on any other event.
+ DisableAutoscroll();
+ }
+
+#ifdef ENABLE_THUMBNAILS
+ if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSELEAVE)
+ thumbnails_.SlideOut();
+
+ if (thumbnails_.HandleEvent(event_device_res))
+ return true;
+#endif
+
+ if (toolbar_->HandleEvent(event_device_res))
+ return true;
+
+#ifdef ENABLE_THUMBNAILS
+ if (v_scrollbar_.get() && event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE) {
+ pp::MouseInputEvent mouse_event(event);
+ pp::Point pt = mouse_event.GetPosition();
+ pp::Rect v_scrollbar_rc;
+ v_scrollbar_->GetLocation(&v_scrollbar_rc);
+ // There is a bug (https://bugs.webkit.org/show_bug.cgi?id=45208)
+ // in the webkit that makes event.u.mouse.button
+ // equal to PP_INPUTEVENT_MOUSEBUTTON_LEFT, even when no button is pressed.
+ // To work around this issue we use modifier for now, and will switch
+ // to button once the bug is fixed and webkit got merged back to our tree.
+ if (v_scrollbar_rc.Contains(pt) &&
+ (event.GetModifiers() & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN)) {
+ thumbnails_.SlideIn();
+ }
+
+ // When scrollbar is in the scrolling mode we should display thumbnails
+ // even the mouse is outside the thumbnail and scrollbar areas.
+ // If mouse is outside plugin area, we are still getting mouse move events
+ // while scrolling. See bug description for details:
+ // http://code.google.com/p/chromium/issues/detail?id=56444
+ if (!v_scrollbar_rc.Contains(pt) && thumbnails_.visible() &&
+ !(event.GetModifiers() & PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN) &&
+ !thumbnails_.rect().Contains(pt)) {
+ thumbnails_.SlideOut();
+ }
+ }
+#endif
+
+ // Need to pass the event to the engine first, since if we're over an edit
+ // control we want it to get keyboard events (like space) instead of the
+ // scrollbar.
+ // TODO: will have to offset the mouse coordinates once we support bidi and
+ // there could be scrollbars on the left.
+ pp::InputEvent offset_event(event_device_res);
+ bool try_engine_first = true;
+ switch (offset_event.GetType()) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
+ pp::MouseInputEvent mouse_event(event_device_res);
+ pp::MouseInputEvent mouse_event_dip(event);
+ pp::Point point = mouse_event.GetPosition();
+ point.set_x(point.x() - available_area_.x());
+ offset_event = pp::MouseInputEvent(
+ this,
+ event.GetType(),
+ event.GetTimeStamp(),
+ event.GetModifiers(),
+ mouse_event.GetButton(),
+ point,
+ mouse_event.GetClickCount(),
+ mouse_event.GetMovement());
+ if (!engine_->IsSelecting()) {
+ if (!IsOverlayScrollbar() &&
+ !available_area_.Contains(mouse_event.GetPosition())) {
+ try_engine_first = false;
+ } else if (IsOverlayScrollbar()) {
+ pp::Rect temp;
+ if ((v_scrollbar_.get() && v_scrollbar_->GetLocation(&temp) &&
+ temp.Contains(mouse_event_dip.GetPosition())) ||
+ (h_scrollbar_.get() && h_scrollbar_->GetLocation(&temp) &&
+ temp.Contains(mouse_event_dip.GetPosition()))) {
+ try_engine_first = false;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ if (try_engine_first && engine_->HandleEvent(offset_event))
+ return true;
+
+ // Left/Right arrows should scroll to the beginning of the Prev/Next page if
+ // there is no horizontal scroll bar.
+ // If fit-to-height, PgDown/PgUp should scroll to the beginning of the
+ // Prev/Next page. Spacebar / shift+spacebar should do the same.
+ if (v_scrollbar_.get() && event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN) {
+ pp::KeyboardInputEvent keyboard_event(event);
+ bool no_h_scrollbar = !h_scrollbar_.get();
+ uint32_t key_code = keyboard_event.GetKeyCode();
+ bool page_down = no_h_scrollbar && key_code == ui::VKEY_RIGHT;
+ bool page_up = no_h_scrollbar && key_code == ui::VKEY_LEFT;
+ if (zoom_mode_ == ZOOM_FIT_TO_PAGE) {
+ bool has_shift =
+ keyboard_event.GetModifiers() & PP_INPUTEVENT_MODIFIER_SHIFTKEY;
+ bool key_is_space = key_code == ui::VKEY_SPACE;
+ page_down |= key_is_space || key_code == ui::VKEY_NEXT;
+ page_up |= (key_is_space && has_shift) || (key_code == ui::VKEY_PRIOR);
+ }
+ if (page_down) {
+ int page = engine_->GetFirstVisiblePage();
+ if (page == -1)
+ return true;
+ // Engine calculates visible page including delimiter to the page size.
+ // We need to check here if the page itself is completely out of view and
+ // scroll to the next one in that case.
+ if (engine_->GetPageRect(page).bottom() * zoom_ <=
+ v_scrollbar_->GetValue())
+ page++;
+ ScrollToPage(page + 1);
+ UpdateCursor(PP_CURSORTYPE_POINTER);
+ return true;
+ } else if (page_up) {
+ int page = engine_->GetFirstVisiblePage();
+ if (page == -1)
+ return true;
+ if (engine_->GetPageRect(page).y() * zoom_ >= v_scrollbar_->GetValue())
+ page--;
+ ScrollToPage(page);
+ UpdateCursor(PP_CURSORTYPE_POINTER);
+ return true;
+ }
+ }
+
+ if (v_scrollbar_.get() && v_scrollbar_->HandleEvent(event)) {
+ UpdateCursor(PP_CURSORTYPE_POINTER);
+ return true;
+ }
+
+ if (h_scrollbar_.get() && h_scrollbar_->HandleEvent(event)) {
+ UpdateCursor(PP_CURSORTYPE_POINTER);
+ return true;
+ }
+
+ if (timer_pending_ &&
+ (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEUP ||
+ event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE)) {
+ timer_factory_.CancelAll();
+ timer_pending_ = false;
+ } else if (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEMOVE &&
+ engine_->IsSelecting()) {
+ bool set_timer = false;
+ pp::MouseInputEvent mouse_event(event);
+ if (v_scrollbar_.get() &&
+ (mouse_event.GetPosition().y() <= 0 ||
+ mouse_event.GetPosition().y() >= (plugin_dip_size_.height() - 1))) {
+ v_scrollbar_->ScrollBy(
+ PP_SCROLLBY_LINE, mouse_event.GetPosition().y() >= 0 ? 1: -1);
+ set_timer = true;
+ }
+ if (h_scrollbar_.get() &&
+ (mouse_event.GetPosition().x() <= 0 ||
+ mouse_event.GetPosition().x() >= (plugin_dip_size_.width() - 1))) {
+ h_scrollbar_->ScrollBy(PP_SCROLLBY_LINE,
+ mouse_event.GetPosition().x() >= 0 ? 1: -1);
+ set_timer = true;
+ }
+
+ if (set_timer) {
+ last_mouse_event_ = pp::MouseInputEvent(event);
+
+ pp::CompletionCallback callback =
+ timer_factory_.NewCallback(&Instance::OnTimerFired);
+ pp::Module::Get()->core()->CallOnMainThread(kDragTimerMs, callback);
+ timer_pending_ = true;
+ }
+ }
+
+ if (event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN) {
+ pp::KeyboardInputEvent keyboard_event(event);
+ const uint32 modifier = event.GetModifiers();
+ if (modifier & kDefaultKeyModifier) {
+ switch (keyboard_event.GetKeyCode()) {
+ case 'A':
+ engine_->SelectAll();
+ return true;
+ }
+ } else if (modifier & PP_INPUTEVENT_MODIFIER_CONTROLKEY) {
+ switch (keyboard_event.GetKeyCode()) {
+ case ui::VKEY_OEM_4:
+ // Left bracket.
+ engine_->RotateCounterclockwise();
+ return true;
+ case ui::VKEY_OEM_6:
+ // Right bracket.
+ engine_->RotateClockwise();
+ return true;
+ }
+ }
+ }
+
+ // Return true for unhandled clicks so the plugin takes focus.
+ return (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN);
+}
+
+void Instance::DidChangeView(const pp::View& view) {
+ pp::Rect view_rect(view.GetRect());
+ float device_scale = 1.0f;
+ float old_device_scale = device_scale_;
+ if (hidpi_enabled_)
+ device_scale = view.GetDeviceScale();
+ pp::Size view_device_size(view_rect.width() * device_scale,
+ view_rect.height() * device_scale);
+ if (view_device_size == plugin_size_ && device_scale == device_scale_)
+ return; // We don't care about the position, only the size.
+
+ image_data_ = pp::ImageData();
+ device_scale_ = device_scale;
+ plugin_dip_size_ = view_rect.size();
+ plugin_size_ = view_device_size;
+
+ paint_manager_.SetSize(view_device_size, device_scale_);
+
+ image_data_ = pp::ImageData(this,
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ plugin_size_,
+ false);
+ if (image_data_.is_null()) {
+ DCHECK(plugin_size_.IsEmpty());
+ return;
+ }
+
+ // View dimensions changed, disable autoscroll (if it was enabled).
+ DisableAutoscroll();
+
+ OnGeometryChanged(zoom_, old_device_scale);
+}
+
+pp::Var Instance::GetInstanceObject() {
+ if (instance_object_.is_undefined()) {
+ PDFScriptableObject* object = new PDFScriptableObject(this);
+ // The pp::Var takes ownership of object here.
+ instance_object_ = pp::VarPrivate(this, object);
+ }
+
+ return instance_object_;
+}
+
+pp::Var Instance::GetLinkAtPosition(const pp::Point& point) {
+ pp::Point offset_point(point);
+ ScalePoint(device_scale_, &offset_point);
+ offset_point.set_x(offset_point.x() - available_area_.x());
+ return engine_->GetLinkAtPosition(offset_point);
+}
+
+pp::Var Instance::GetSelectedText(bool html) {
+ if (html || !engine_->HasPermission(PDFEngine::PERMISSION_COPY))
+ return pp::Var();
+ return engine_->GetSelectedText();
+}
+
+void Instance::InvalidateWidget(pp::Widget_Dev widget,
+ const pp::Rect& dirty_rect) {
+ if (v_scrollbar_.get() && *v_scrollbar_ == widget) {
+ if (!image_data_.is_null())
+ v_scrollbar_->Paint(dirty_rect.pp_rect(), &image_data_);
+ } else if (h_scrollbar_.get() && *h_scrollbar_ == widget) {
+ if (!image_data_.is_null())
+ h_scrollbar_->Paint(dirty_rect.pp_rect(), &image_data_);
+ } else {
+ // Possible to hit this condition since sometimes the scrollbar codes posts
+ // a task to do something later, and we could have deleted our reference in
+ // the meantime.
+ return;
+ }
+
+ pp::Rect dirty_rect_scaled = dirty_rect;
+ ScaleRect(device_scale_, &dirty_rect_scaled);
+ paint_manager_.InvalidateRect(dirty_rect_scaled);
+}
+
+void Instance::ScrollbarValueChanged(pp::Scrollbar_Dev scrollbar,
+ uint32_t value) {
+ value = GetScaled(value);
+ if (v_scrollbar_.get() && *v_scrollbar_ == scrollbar) {
+ engine_->ScrolledToYPosition(value);
+ pp::Rect rc;
+ v_scrollbar_->GetLocation(&rc);
+ int32 doc_height = GetDocumentPixelHeight();
+ doc_height -= GetScaled(rc.height());
+#ifdef ENABLE_THUMBNAILS
+ if (thumbnails_.visible()) {
+ thumbnails_.SetPosition(value, doc_height, true);
+ }
+#endif
+ pp::Point origin(
+ plugin_size_.width() - page_indicator_.rect().width() -
+ GetScaled(GetScrollbarReservedThickness()),
+ page_indicator_.GetYPosition(value, doc_height, plugin_size_.height()));
+ page_indicator_.MoveTo(origin, page_indicator_.visible());
+ } else if (h_scrollbar_.get() && *h_scrollbar_ == scrollbar) {
+ engine_->ScrolledToXPosition(value);
+ }
+}
+
+void Instance::ScrollbarOverlayChanged(pp::Scrollbar_Dev scrollbar,
+ bool overlay) {
+ scrollbar_reserved_thickness_ = overlay ? 0 : scrollbar_thickness_;
+ OnGeometryChanged(zoom_, device_scale_);
+}
+
+uint32_t Instance::QuerySupportedPrintOutputFormats() {
+ return engine_->QuerySupportedPrintOutputFormats();
+}
+
+int32_t Instance::PrintBegin(const PP_PrintSettings_Dev& print_settings) {
+ // For us num_pages is always equal to the number of pages in the PDF
+ // document irrespective of the printable area.
+ int32_t ret = engine_->GetNumberOfPages();
+ if (!ret)
+ return 0;
+
+ uint32_t supported_formats = engine_->QuerySupportedPrintOutputFormats();
+ if ((print_settings.format & supported_formats) == 0)
+ return 0;
+
+ print_settings_.is_printing = true;
+ print_settings_.pepper_print_settings = print_settings;
+ engine_->PrintBegin();
+ return ret;
+}
+
+pp::Resource Instance::PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) {
+ if (!print_settings_.is_printing)
+ return pp::Resource();
+
+ print_settings_.print_pages_called_ = true;
+ return engine_->PrintPages(page_ranges, page_range_count,
+ print_settings_.pepper_print_settings);
+}
+
+void Instance::PrintEnd() {
+ if (print_settings_.print_pages_called_)
+ UserMetricsRecordAction("PDF.PrintPage");
+ print_settings_.Clear();
+ engine_->PrintEnd();
+}
+
+bool Instance::IsPrintScalingDisabled() {
+ return !engine_->GetPrintScaling();
+}
+
+bool Instance::StartFind(const std::string& text, bool case_sensitive) {
+ engine_->StartFind(text.c_str(), case_sensitive);
+ return true;
+}
+
+void Instance::SelectFindResult(bool forward) {
+ engine_->SelectFindResult(forward);
+}
+
+void Instance::StopFind() {
+ engine_->StopFind();
+}
+
+void Instance::Zoom(double scale, bool text_only) {
+ UserMetricsRecordAction("PDF.ZoomFromBrowser");
+
+ // If the zoom level doesn't change it means that this zoom change might have
+ // been initiated by the plugin. In that case, we don't want to change the
+ // zoom mode to ZOOM_SCALE as it may have been intentionally set to
+ // ZOOM_FIT_TO_PAGE or some other value when the zoom was last changed.
+ if (scale == zoom_)
+ return;
+
+ SetZoom(ZOOM_SCALE, scale);
+}
+
+void Instance::ZoomChanged(double factor) {
+ if (full_)
+ Zoom_Dev::ZoomChanged(factor);
+}
+
+void Instance::OnPaint(const std::vector<pp::Rect>& paint_rects,
+ std::vector<PaintManager::ReadyRect>* ready,
+ std::vector<pp::Rect>* pending) {
+ if (image_data_.is_null()) {
+ DCHECK(plugin_size_.IsEmpty());
+ return;
+ }
+ if (first_paint_) {
+ first_paint_ = false;
+ pp::Rect rect = pp::Rect(pp::Point(), plugin_size_);
+ FillRect(rect, kBackgroundColor);
+ ready->push_back(PaintManager::ReadyRect(rect, image_data_, true));
+ *pending = paint_rects;
+ return;
+ }
+
+ engine_->PrePaint();
+
+ for (size_t i = 0; i < paint_rects.size(); i++) {
+ // Intersect with plugin area since there could be pending invalidates from
+ // when the plugin area was larger.
+ pp::Rect rect =
+ paint_rects[i].Intersect(pp::Rect(pp::Point(), plugin_size_));
+ if (rect.IsEmpty())
+ continue;
+
+ pp::Rect pdf_rect = available_area_.Intersect(rect);
+ if (!pdf_rect.IsEmpty()) {
+ pdf_rect.Offset(available_area_.x() * -1, 0);
+
+ std::vector<pp::Rect> pdf_ready;
+ std::vector<pp::Rect> pdf_pending;
+ engine_->Paint(pdf_rect, &image_data_, &pdf_ready, &pdf_pending);
+ for (size_t j = 0; j < pdf_ready.size(); ++j) {
+ pdf_ready[j].Offset(available_area_.point());
+ ready->push_back(
+ PaintManager::ReadyRect(pdf_ready[j], image_data_, false));
+ }
+ for (size_t j = 0; j < pdf_pending.size(); ++j) {
+ pdf_pending[j].Offset(available_area_.point());
+ pending->push_back(pdf_pending[j]);
+ }
+ }
+
+ for (size_t j = 0; j < background_parts_.size(); ++j) {
+ pp::Rect intersection = background_parts_[j].location.Intersect(rect);
+ if (!intersection.IsEmpty()) {
+ FillRect(intersection, background_parts_[j].color);
+ ready->push_back(
+ PaintManager::ReadyRect(intersection, image_data_, false));
+ }
+ }
+
+ if (document_load_state_ == LOAD_STATE_FAILED) {
+ pp::Point top_center;
+ top_center.set_x(plugin_size_.width() / 2);
+ top_center.set_y(plugin_size_.height() / 2);
+ DrawText(top_center, PP_RESOURCESTRING_PDFLOAD_FAILED);
+ }
+
+#ifdef ENABLE_THUMBNAILS
+ thumbnails_.Paint(&image_data_, rect);
+#endif
+ }
+
+ engine_->PostPaint();
+
+ // Must paint scrollbars after the background parts, in case we have an
+ // overlay scrollbar that's over the background. We also do this in a separate
+ // loop because the scrollbar painting logic uses the signal of whether there
+ // are pending paints or not to figure out if it should draw right away or
+ // not.
+ for (size_t i = 0; i < paint_rects.size(); i++) {
+ PaintIfWidgetIntersects(h_scrollbar_.get(), paint_rects[i], ready, pending);
+ PaintIfWidgetIntersects(v_scrollbar_.get(), paint_rects[i], ready, pending);
+ }
+
+ if (progress_bar_.visible())
+ PaintOverlayControl(&progress_bar_, &image_data_, ready);
+
+ if (page_indicator_.visible())
+ PaintOverlayControl(&page_indicator_, &image_data_, ready);
+
+ if (toolbar_->current_transparency() != kTransparentAlpha)
+ PaintOverlayControl(toolbar_.get(), &image_data_, ready);
+
+ // Paint autoscroll anchor if needed.
+ if (is_autoscroll_) {
+ size_t limit = ready->size();
+ for (size_t i = 0; i < limit; i++) {
+ pp::Rect anchor_rect = autoscroll_rect_.Intersect((*ready)[i].rect);
+ if (!anchor_rect.IsEmpty()) {
+ pp::Rect draw_rc = pp::Rect(
+ pp::Point(anchor_rect.x() - autoscroll_rect_.x(),
+ anchor_rect.y() - autoscroll_rect_.y()),
+ anchor_rect.size());
+ // Paint autoscroll anchor.
+ AlphaBlend(autoscroll_anchor_, draw_rc,
+ &image_data_, anchor_rect.point(), kOpaqueAlpha);
+ }
+ }
+ }
+}
+
+void Instance::PaintOverlayControl(
+ Control* ctrl,
+ pp::ImageData* image_data,
+ std::vector<PaintManager::ReadyRect>* ready) {
+ // Make sure that we only paint overlay controls over an area that's ready,
+ // i.e. not pending. Otherwise we'll mark the control rect as ready and
+ // it'll overwrite the pdf region.
+ std::list<pp::Rect> ctrl_rects;
+ for (size_t i = 0; i < ready->size(); i++) {
+ pp::Rect rc = ctrl->rect().Intersect((*ready)[i].rect);
+ if (!rc.IsEmpty())
+ ctrl_rects.push_back(rc);
+ }
+
+ if (!ctrl_rects.empty()) {
+ ctrl->PaintMultipleRects(image_data, ctrl_rects);
+
+ std::list<pp::Rect>::iterator iter;
+ for (iter = ctrl_rects.begin(); iter != ctrl_rects.end(); ++iter) {
+ ready->push_back(PaintManager::ReadyRect(*iter, *image_data, false));
+ }
+ }
+}
+
+void Instance::DidOpen(int32_t result) {
+ if (result == PP_OK) {
+ engine_->HandleDocumentLoad(embed_loader_);
+ } else if (result != PP_ERROR_ABORTED) { // Can happen in tests.
+ NOTREACHED();
+ }
+}
+
+void Instance::DidOpenPreview(int32_t result) {
+ if (result == PP_OK) {
+ preview_engine_.reset(PDFEngine::Create(new PreviewModeClient(this)));
+ preview_engine_->HandleDocumentLoad(embed_preview_loader_);
+ } else {
+ NOTREACHED();
+ }
+}
+
+void Instance::PaintIfWidgetIntersects(
+ pp::Widget_Dev* widget,
+ const pp::Rect& rect,
+ std::vector<PaintManager::ReadyRect>* ready,
+ std::vector<pp::Rect>* pending) {
+ if (!widget)
+ return;
+
+ pp::Rect location;
+ if (!widget->GetLocation(&location))
+ return;
+
+ ScaleRect(device_scale_, &location);
+ location = location.Intersect(rect);
+ if (location.IsEmpty())
+ return;
+
+ if (IsOverlayScrollbar()) {
+ // If we're using overlay scrollbars, and there are pending paints under the
+ // scrollbar, don't update the scrollbar instantly. While it would be nice,
+ // we would need to double buffer the plugin area in order to make this
+ // work. This is because we'd need to always have a copy of what the pdf
+ // under the scrollbar looks like, and additionally we couldn't paint the
+ // pdf under the scrollbar if it's ready until we got the preceding flush.
+ // So in practice, it would make painting slower and introduce extra buffer
+ // copies for the general case.
+ for (size_t i = 0; i < pending->size(); ++i) {
+ if ((*pending)[i].Intersects(location))
+ return;
+ }
+
+ // Even if none of the pending paints are under the scrollbar, we never want
+ // to paint it if it's over the pdf if there are other pending paints.
+ // Otherwise different parts of the pdf plugin would display at different
+ // scroll offsets.
+ if (!pending->empty() && available_area_.Intersects(rect)) {
+ pending->push_back(location);
+ return;
+ }
+ }
+
+ pp::Rect location_dip = location;
+ ScaleRect(1.0f / device_scale_, &location_dip);
+
+ DCHECK(!image_data_.is_null());
+ widget->Paint(location_dip, &image_data_);
+
+ ready->push_back(PaintManager::ReadyRect(location, image_data_, true));
+}
+
+void Instance::OnTimerFired(int32_t) {
+ HandleInputEvent(last_mouse_event_);
+}
+
+void Instance::OnClientTimerFired(int32_t id) {
+ engine_->OnCallback(id);
+}
+
+void Instance::OnControlTimerFired(int32_t,
+ const uint32& control_id,
+ const uint32& timer_id) {
+ if (control_id == toolbar_->id()) {
+ toolbar_->OnTimerFired(timer_id);
+ } else if (control_id == progress_bar_.id()) {
+ if (timer_id == delayed_progress_timer_id_) {
+ if (document_load_state_ == LOAD_STATE_LOADING &&
+ !progress_bar_.visible()) {
+ progress_bar_.Fade(true, kProgressFadeTimeoutMs);
+ }
+ delayed_progress_timer_id_ = 0;
+ } else {
+ progress_bar_.OnTimerFired(timer_id);
+ }
+ } else if (control_id == kAutoScrollId) {
+ if (is_autoscroll_) {
+ if (autoscroll_x_ != 0 && h_scrollbar_.get()) {
+ h_scrollbar_->ScrollBy(PP_SCROLLBY_PIXEL, autoscroll_x_);
+ }
+ if (autoscroll_y_ != 0 && v_scrollbar_.get()) {
+ v_scrollbar_->ScrollBy(PP_SCROLLBY_PIXEL, autoscroll_y_);
+ }
+
+ // Reschedule timer.
+ ScheduleTimer(kAutoScrollId, kAutoScrollTimeoutMs);
+ }
+ } else if (control_id == kPageIndicatorId) {
+ page_indicator_.OnTimerFired(timer_id);
+ }
+#ifdef ENABLE_THUMBNAILS
+ else if (control_id == thumbnails_.id()) {
+ thumbnails_.OnTimerFired(timer_id);
+ }
+#endif
+}
+
+void Instance::CalculateBackgroundParts() {
+ background_parts_.clear();
+ int v_scrollbar_thickness =
+ GetScaled(v_scrollbar_.get() ? GetScrollbarReservedThickness() : 0);
+ int h_scrollbar_thickness =
+ GetScaled(h_scrollbar_.get() ? GetScrollbarReservedThickness() : 0);
+ int width_without_scrollbar = std::max(
+ plugin_size_.width() - v_scrollbar_thickness, 0);
+ int height_without_scrollbar = std::max(
+ plugin_size_.height() - h_scrollbar_thickness, 0);
+ int left_width = available_area_.x();
+ int right_start = available_area_.right();
+ int right_width = abs(width_without_scrollbar - available_area_.right());
+ int bottom = std::min(available_area_.bottom(), height_without_scrollbar);
+
+ // Add the left, right, and bottom rectangles. Note: we assume only
+ // horizontal centering.
+ BackgroundPart part = {
+ pp::Rect(0, 0, left_width, bottom),
+ kBackgroundColor
+ };
+ if (!part.location.IsEmpty())
+ background_parts_.push_back(part);
+ part.location = pp::Rect(right_start, 0, right_width, bottom);
+ if (!part.location.IsEmpty())
+ background_parts_.push_back(part);
+ part.location = pp::Rect(
+ 0, bottom, width_without_scrollbar, height_without_scrollbar - bottom);
+ if (!part.location.IsEmpty())
+ background_parts_.push_back(part);
+
+ if (h_scrollbar_thickness
+#if defined(OS_MACOSX)
+ ||
+#else
+ &&
+#endif
+ v_scrollbar_thickness) {
+ part.color = 0xFFFFFFFF;
+ part.location = pp::Rect(plugin_size_.width() - v_scrollbar_thickness,
+ plugin_size_.height() - h_scrollbar_thickness,
+ h_scrollbar_thickness,
+ v_scrollbar_thickness);
+ background_parts_.push_back(part);
+ }
+}
+
+int Instance::GetDocumentPixelWidth() const {
+ return static_cast<int>(ceil(document_size_.width() * zoom_ * device_scale_));
+}
+
+int Instance::GetDocumentPixelHeight() const {
+ return static_cast<int>(ceil(document_size_.height() *
+ zoom_ *
+ device_scale_));
+}
+
+void Instance::FillRect(const pp::Rect& rect, uint32 color) {
+ DCHECK(!image_data_.is_null() || rect.IsEmpty());
+ uint32* buffer_start = static_cast<uint32*>(image_data_.data());
+ int stride = image_data_.stride();
+ uint32* ptr = buffer_start + rect.y() * stride / 4 + rect.x();
+ int height = rect.height();
+ int width = rect.width();
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x)
+ *(ptr + x) = color;
+ ptr += stride / 4;
+ }
+}
+
+void Instance::DocumentSizeUpdated(const pp::Size& size) {
+ document_size_ = size;
+
+ OnGeometryChanged(zoom_, device_scale_);
+}
+
+void Instance::Invalidate(const pp::Rect& rect) {
+ pp::Rect offset_rect(rect);
+ offset_rect.Offset(available_area_.point());
+ paint_manager_.InvalidateRect(offset_rect);
+}
+
+void Instance::Scroll(const pp::Point& point) {
+ pp::Rect scroll_area = available_area_;
+ if (IsOverlayScrollbar()) {
+ pp::Rect rc;
+ if (h_scrollbar_.get()) {
+ h_scrollbar_->GetLocation(&rc);
+ ScaleRect(device_scale_, &rc);
+ if (scroll_area.bottom() > rc.y()) {
+ scroll_area.set_height(rc.y() - scroll_area.y());
+ paint_manager_.InvalidateRect(rc);
+ }
+ }
+ if (v_scrollbar_.get()) {
+ v_scrollbar_->GetLocation(&rc);
+ ScaleRect(device_scale_, &rc);
+ if (scroll_area.right() > rc.x()) {
+ scroll_area.set_width(rc.x() - scroll_area.x());
+ paint_manager_.InvalidateRect(rc);
+ }
+ }
+ }
+ paint_manager_.ScrollRect(scroll_area, point);
+
+ if (toolbar_->current_transparency() != kTransparentAlpha)
+ paint_manager_.InvalidateRect(toolbar_->GetControlsRect());
+
+ if (progress_bar_.visible())
+ paint_manager_.InvalidateRect(progress_bar_.rect());
+
+ if (is_autoscroll_)
+ paint_manager_.InvalidateRect(autoscroll_rect_);
+
+ if (show_page_indicator_) {
+ page_indicator_.set_current_page(GetPageNumberToDisplay());
+ page_indicator_.Splash();
+ }
+
+ if (page_indicator_.visible())
+ paint_manager_.InvalidateRect(page_indicator_.rect());
+
+ // Run the scroll callback asynchronously. This function can be invoked by a
+ // layout change which should not re-enter into JS synchronously.
+ pp::CompletionCallback callback =
+ callback_factory_.NewCallback(&Instance::RunCallback,
+ on_scroll_callback_);
+ pp::Module::Get()->core()->CallOnMainThread(0, callback);
+}
+
+void Instance::ScrollToX(int position) {
+ if (!h_scrollbar_.get()) {
+ NOTREACHED();
+ return;
+ }
+ int position_dip = static_cast<int>(position / device_scale_);
+ h_scrollbar_->SetValue(position_dip);
+}
+
+void Instance::ScrollToY(int position) {
+ if (!v_scrollbar_.get()) {
+ NOTREACHED();
+ return;
+ }
+ int position_dip = static_cast<int>(position / device_scale_);
+ v_scrollbar_->SetValue(ClipToRange(position_dip, 0, valid_v_range_));
+}
+
+void Instance::ScrollToPage(int page) {
+ if (!v_scrollbar_.get())
+ return;
+
+ if (engine_->GetNumberOfPages() == 0)
+ return;
+
+ int index = ClipToRange(page, 0, engine_->GetNumberOfPages() - 1);
+ pp::Rect rect = engine_->GetPageRect(index);
+ // If we are trying to scroll pass the last page,
+ // scroll to the end of the last page.
+ int position = index < page ? rect.bottom() : rect.y();
+ ScrollToY(position * zoom_ * device_scale_);
+}
+
+void Instance::NavigateTo(const std::string& url, bool open_in_new_tab) {
+ std::string url_copy(url);
+
+ // Empty |url_copy| is ok, and will effectively be a reload.
+ // Skip the code below so an empty URL does not turn into "http://", which
+ // will cause GURL to fail a DCHECK.
+ if (!url_copy.empty()) {
+ // If |url_copy| starts with '#', then it's for the same URL with a
+ // different URL fragment.
+ if (url_copy[0] == '#') {
+ url_copy = url_ + url_copy;
+ // Changing the href does not actually do anything when navigating in the
+ // same tab, so do the actual page scroll here. Then fall through so the
+ // href gets updated.
+ if (!open_in_new_tab) {
+ int page_number = GetInitialPage(url_copy);
+ if (page_number >= 0)
+ ScrollToPage(page_number);
+ }
+ }
+ // If there's no scheme, add http.
+ if (url_copy.find("://") == std::string::npos &&
+ url_copy.find("mailto:") == std::string::npos) {
+ url_copy = "http://" + url_copy;
+ }
+ // Make sure |url_copy| starts with a valid scheme.
+ if (url_copy.find("http://") != 0 &&
+ url_copy.find("https://") != 0 &&
+ url_copy.find("ftp://") != 0 &&
+ url_copy.find("file://") != 0 &&
+ url_copy.find("mailto:") != 0) {
+ return;
+ }
+ // Make sure |url_copy| is not only a scheme.
+ if (url_copy == "http://" ||
+ url_copy == "https://" ||
+ url_copy == "ftp://" ||
+ url_copy == "file://" ||
+ url_copy == "mailto:") {
+ return;
+ }
+ }
+ if (open_in_new_tab) {
+ GetWindowObject().Call("open", url_copy);
+ } else {
+ GetWindowObject().GetProperty("top").GetProperty("location").
+ SetProperty("href", url_copy);
+ }
+}
+
+void Instance::UpdateCursor(PP_CursorType_Dev cursor) {
+ if (cursor == cursor_)
+ return;
+ cursor_ = cursor;
+
+ const PPB_CursorControl_Dev* cursor_interface =
+ reinterpret_cast<const PPB_CursorControl_Dev*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_CURSOR_CONTROL_DEV_INTERFACE));
+ if (!cursor_interface) {
+ NOTREACHED();
+ return;
+ }
+
+ cursor_interface->SetCursor(
+ pp_instance(), cursor_, pp::ImageData().pp_resource(), NULL);
+}
+
+void Instance::UpdateTickMarks(const std::vector<pp::Rect>& tickmarks) {
+ if (!v_scrollbar_.get())
+ return;
+
+ float inverse_scale = 1.0f / device_scale_;
+ std::vector<pp::Rect> scaled_tickmarks = tickmarks;
+ for (size_t i = 0; i < scaled_tickmarks.size(); i++) {
+ ScaleRect(inverse_scale, &scaled_tickmarks[i]);
+ }
+
+ v_scrollbar_->SetTickMarks(
+ scaled_tickmarks.empty() ? NULL : &scaled_tickmarks[0], tickmarks.size());
+}
+
+void Instance::NotifyNumberOfFindResultsChanged(int total, bool final_result) {
+ NumberOfFindResultsChanged(total, final_result);
+}
+
+void Instance::NotifySelectedFindResultChanged(int current_find_index) {
+ SelectedFindResultChanged(current_find_index);
+}
+
+void Instance::OnEvent(uint32 control_id, uint32 event_id, void* data) {
+ if (event_id == Button::EVENT_ID_BUTTON_CLICKED ||
+ event_id == Button::EVENT_ID_BUTTON_STATE_CHANGED) {
+ switch (control_id) {
+ case kFitToPageButtonId:
+ UserMetricsRecordAction("PDF.FitToPageButton");
+ SetZoom(ZOOM_FIT_TO_PAGE, 0);
+ ZoomChanged(zoom_);
+ break;
+ case kFitToWidthButtonId:
+ UserMetricsRecordAction("PDF.FitToWidthButton");
+ SetZoom(ZOOM_FIT_TO_WIDTH, 0);
+ ZoomChanged(zoom_);
+ break;
+ case kZoomOutButtonId:
+ case kZoomInButtonId:
+ UserMetricsRecordAction(control_id == kZoomOutButtonId ?
+ "PDF.ZoomOutButton" : "PDF.ZoomInButton");
+ SetZoom(ZOOM_SCALE, CalculateZoom(control_id));
+ ZoomChanged(zoom_);
+ break;
+ case kSaveButtonId:
+ UserMetricsRecordAction("PDF.SaveButton");
+ SaveAs();
+ break;
+ case kPrintButtonId:
+ UserMetricsRecordAction("PDF.PrintButton");
+ Print();
+ break;
+ }
+ }
+ if (control_id == kThumbnailsId &&
+ event_id == ThumbnailControl::EVENT_ID_THUMBNAIL_SELECTED) {
+ int page = *static_cast<int*>(data);
+ pp::Rect page_rc(engine_->GetPageRect(page));
+ ScrollToY(static_cast<int>(page_rc.y() * zoom_ * device_scale_));
+ }
+}
+
+void Instance::Invalidate(uint32 control_id, const pp::Rect& rc) {
+ paint_manager_.InvalidateRect(rc);
+}
+
+uint32 Instance::ScheduleTimer(uint32 control_id, uint32 timeout_ms) {
+ current_timer_id_++;
+ pp::CompletionCallback callback =
+ timer_factory_.NewCallback(&Instance::OnControlTimerFired,
+ control_id,
+ current_timer_id_);
+ pp::Module::Get()->core()->CallOnMainThread(timeout_ms, callback);
+ return current_timer_id_;
+}
+
+void Instance::SetEventCapture(uint32 control_id, bool set_capture) {
+ // TODO(gene): set event capture here.
+}
+
+void Instance::SetCursor(uint32 control_id, PP_CursorType_Dev cursor_type) {
+ UpdateCursor(cursor_type);
+}
+
+pp::Instance* Instance::GetInstance() {
+ return this;
+}
+
+void Instance::GetDocumentPassword(
+ pp::CompletionCallbackWithOutput<pp::Var> callback) {
+ std::string message(GetLocalizedString(PP_RESOURCESTRING_PDFGETPASSWORD));
+ pp::Var result = pp::PDF::ModalPromptForPassword(this, message);
+ *callback.output() = result.pp_var();
+ callback.Run(PP_OK);
+}
+
+void Instance::Alert(const std::string& message) {
+ GetWindowObject().Call("alert", message);
+}
+
+bool Instance::Confirm(const std::string& message) {
+ pp::Var result = GetWindowObject().Call("confirm", message);
+ return result.is_bool() ? result.AsBool() : false;
+}
+
+std::string Instance::Prompt(const std::string& question,
+ const std::string& default_answer) {
+ pp::Var result = GetWindowObject().Call("prompt", question, default_answer);
+ return result.is_string() ? result.AsString() : std::string();
+}
+
+std::string Instance::GetURL() {
+ return url_;
+}
+
+void Instance::Email(const std::string& to,
+ const std::string& cc,
+ const std::string& bcc,
+ const std::string& subject,
+ const std::string& body) {
+ std::string javascript =
+ "var href = 'mailto:" + net::EscapeUrlEncodedData(to, false) +
+ "?cc=" + net::EscapeUrlEncodedData(cc, false) +
+ "&bcc=" + net::EscapeUrlEncodedData(bcc, false) +
+ "&subject=" + net::EscapeUrlEncodedData(subject, false) +
+ "&body=" + net::EscapeUrlEncodedData(body, false) +
+ "';var temp = window.open(href, '_blank', " +
+ "'width=1,height=1');if(temp) temp.close();";
+ ExecuteScript(javascript);
+}
+
+void Instance::Print() {
+ if (!printing_enabled_ ||
+ (!engine_->HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY) &&
+ !engine_->HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY))) {
+ return;
+ }
+
+ pp::CompletionCallback callback =
+ callback_factory_.NewCallback(&Instance::OnPrint);
+ pp::Module::Get()->core()->CallOnMainThread(0, callback);
+}
+
+void Instance::OnPrint(int32_t) {
+ pp::PDF::Print(this);
+}
+
+void Instance::SaveAs() {
+ pp::PDF::SaveAs(this);
+}
+
+void Instance::SubmitForm(const std::string& url,
+ const void* data,
+ int length) {
+ pp::URLRequestInfo request(this);
+ request.SetURL(url);
+ request.SetMethod("POST");
+ request.AppendDataToBody(reinterpret_cast<const char*>(data), length);
+
+ pp::CompletionCallback callback =
+ form_factory_.NewCallback(&Instance::FormDidOpen);
+ form_loader_ = CreateURLLoaderInternal();
+ int rv = form_loader_.Open(request, callback);
+ if (rv != PP_OK_COMPLETIONPENDING)
+ callback.Run(rv);
+}
+
+void Instance::FormDidOpen(int32_t result) {
+ // TODO: inform the user of success/failure.
+ if (result != PP_OK) {
+ NOTREACHED();
+ }
+}
+
+std::string Instance::ShowFileSelectionDialog() {
+ // Seems like very low priority to implement, since the pdf has no way to get
+ // the file data anyways. Javascript doesn't let you do this synchronously.
+ NOTREACHED();
+ return std::string();
+}
+
+pp::URLLoader Instance::CreateURLLoader() {
+ if (full_) {
+ if (!did_call_start_loading_) {
+ did_call_start_loading_ = true;
+ pp::PDF::DidStartLoading(this);
+ }
+
+ // Disable save and print until the document is fully loaded, since they
+ // would generate an incomplete document. Need to do this each time we
+ // call DidStartLoading since that resets the content restrictions.
+ pp::PDF::SetContentRestriction(this, CONTENT_RESTRICTION_SAVE |
+ CONTENT_RESTRICTION_PRINT);
+ }
+
+ return CreateURLLoaderInternal();
+}
+
+void Instance::ScheduleCallback(int id, int delay_in_ms) {
+ pp::CompletionCallback callback =
+ timer_factory_.NewCallback(&Instance::OnClientTimerFired);
+ pp::Module::Get()->core()->CallOnMainThread(delay_in_ms, callback, id);
+}
+
+void Instance::SearchString(const base::char16* string,
+ const base::char16* term,
+ bool case_sensitive,
+ std::vector<SearchStringResult>* results) {
+ if (!pp::PDF::IsAvailable()) {
+ NOTREACHED();
+ return;
+ }
+
+ PP_PrivateFindResult* pp_results;
+ int count = 0;
+ pp::PDF::SearchString(
+ this,
+ reinterpret_cast<const unsigned short*>(string),
+ reinterpret_cast<const unsigned short*>(term),
+ case_sensitive,
+ &pp_results,
+ &count);
+
+ results->resize(count);
+ for (int i = 0; i < count; ++i) {
+ (*results)[i].start_index = pp_results[i].start_index;
+ (*results)[i].length = pp_results[i].length;
+ }
+
+ pp::Memory_Dev memory;
+ memory.MemFree(pp_results);
+}
+
+void Instance::DocumentPaintOccurred() {
+ if (painted_first_page_)
+ return;
+
+ painted_first_page_ = true;
+ UpdateToolbarPosition(false);
+ toolbar_->Splash(kToolbarSplashTimeoutMs);
+
+ if (engine_->GetNumberOfPages() > 1)
+ show_page_indicator_ = true;
+ else
+ show_page_indicator_ = false;
+
+ if (v_scrollbar_.get() && show_page_indicator_) {
+ page_indicator_.set_current_page(GetPageNumberToDisplay());
+ page_indicator_.Splash(kToolbarSplashTimeoutMs,
+ kPageIndicatorInitialFadeTimeoutMs);
+ }
+}
+
+void Instance::DocumentLoadComplete(int page_count) {
+ // Clear focus state for OSK.
+ FormTextFieldFocusChange(false);
+
+ // Update progress control.
+ if (progress_bar_.visible())
+ progress_bar_.Fade(false, kProgressFadeTimeoutMs);
+
+ DCHECK(document_load_state_ == LOAD_STATE_LOADING);
+ document_load_state_ = LOAD_STATE_COMPLETE;
+ UserMetricsRecordAction("PDF.LoadSuccess");
+
+ if (did_call_start_loading_) {
+ pp::PDF::DidStopLoading(this);
+ did_call_start_loading_ = false;
+ }
+
+ if (on_load_callback_.is_string())
+ ExecuteScript(on_load_callback_);
+ // Note: If we are in print preview mode on_load_callback_ might call
+ // ScrollTo{X|Y}() and we don't want to scroll again and override it.
+ // #page=N is not supported in Print Preview.
+ if (!IsPrintPreview()) {
+ int initial_page = GetInitialPage(url_);
+ if (initial_page >= 0)
+ ScrollToPage(initial_page);
+ }
+
+ if (!full_)
+ return;
+ if (!pp::PDF::IsAvailable())
+ return;
+
+ int content_restrictions =
+ CONTENT_RESTRICTION_CUT | CONTENT_RESTRICTION_PASTE;
+ if (!engine_->HasPermission(PDFEngine::PERMISSION_COPY))
+ content_restrictions |= CONTENT_RESTRICTION_COPY;
+
+ if (!engine_->HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY) &&
+ !engine_->HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY)) {
+ printing_enabled_ = false;
+ if (current_tb_info_ == kPDFToolbarButtons) {
+ // Remove Print button.
+ CreateToolbar(kPDFNoPrintToolbarButtons,
+ arraysize(kPDFNoPrintToolbarButtons));
+ UpdateToolbarPosition(false);
+ Invalidate(pp::Rect(plugin_size_));
+ }
+ }
+
+ pp::PDF::SetContentRestriction(this, content_restrictions);
+
+ pp::PDF::HistogramPDFPageCount(this, page_count);
+}
+
+void Instance::RotateClockwise() {
+ engine_->RotateClockwise();
+}
+
+void Instance::RotateCounterclockwise() {
+ engine_->RotateCounterclockwise();
+}
+
+void Instance::PreviewDocumentLoadComplete() {
+ if (preview_document_load_state_ != LOAD_STATE_LOADING ||
+ preview_pages_info_.empty()) {
+ return;
+ }
+
+ preview_document_load_state_ = LOAD_STATE_COMPLETE;
+
+ int dest_page_index = preview_pages_info_.front().second;
+ int src_page_index =
+ ExtractPrintPreviewPageIndex(preview_pages_info_.front().first);
+ if (src_page_index > 0 && dest_page_index > -1 && preview_engine_.get())
+ engine_->AppendPage(preview_engine_.get(), dest_page_index);
+
+ preview_pages_info_.pop();
+ // |print_preview_page_count_| is not updated yet. Do not load any
+ // other preview pages till we get this information.
+ if (print_preview_page_count_ == 0)
+ return;
+
+ if (preview_pages_info_.size())
+ LoadAvailablePreviewPage();
+}
+
+void Instance::DocumentLoadFailed() {
+ DCHECK(document_load_state_ == LOAD_STATE_LOADING);
+ UserMetricsRecordAction("PDF.LoadFailure");
+
+ // Hide progress control.
+ progress_bar_.Fade(false, kProgressFadeTimeoutMs);
+
+ if (did_call_start_loading_) {
+ pp::PDF::DidStopLoading(this);
+ did_call_start_loading_ = false;
+ }
+
+ document_load_state_ = LOAD_STATE_FAILED;
+ paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
+}
+
+void Instance::PreviewDocumentLoadFailed() {
+ UserMetricsRecordAction("PDF.PreviewDocumentLoadFailure");
+ if (preview_document_load_state_ != LOAD_STATE_LOADING ||
+ preview_pages_info_.empty()) {
+ return;
+ }
+
+ preview_document_load_state_ = LOAD_STATE_FAILED;
+ preview_pages_info_.pop();
+
+ if (preview_pages_info_.size())
+ LoadAvailablePreviewPage();
+}
+
+pp::Instance* Instance::GetPluginInstance() {
+ return GetInstance();
+}
+
+void Instance::DocumentHasUnsupportedFeature(const std::string& feature) {
+ std::string metric("PDF_Unsupported_");
+ metric += feature;
+ if (!unsupported_features_reported_.count(metric)) {
+ unsupported_features_reported_.insert(metric);
+ UserMetricsRecordAction(metric);
+ }
+
+ // Since we use an info bar, only do this for full frame plugins..
+ if (!full_)
+ return;
+
+ if (told_browser_about_unsupported_feature_)
+ return;
+ told_browser_about_unsupported_feature_ = true;
+
+ pp::PDF::HasUnsupportedFeature(this);
+}
+
+void Instance::DocumentLoadProgress(uint32 available, uint32 doc_size) {
+ double progress = 0.0;
+ if (doc_size == 0) {
+ // Document size is unknown. Use heuristics.
+ // We'll make progress logarithmic from 0 to 100M.
+ static const double kFactor = log(100000000.0) / 100.0;
+ if (available > 0) {
+ progress = log(static_cast<double>(available)) / kFactor;
+ if (progress > 100.0)
+ progress = 100.0;
+ }
+ } else {
+ progress = 100.0 * static_cast<double>(available) / doc_size;
+ }
+ progress_bar_.SetProgress(progress);
+}
+
+void Instance::FormTextFieldFocusChange(bool in_focus) {
+ if (!text_input_.get())
+ return;
+ if (in_focus)
+ text_input_->SetTextInputType(PP_TEXTINPUT_TYPE_DEV_TEXT);
+ else
+ text_input_->SetTextInputType(PP_TEXTINPUT_TYPE_DEV_NONE);
+}
+
+// Called by PDFScriptableObject.
+bool Instance::HasScriptableMethod(const pp::Var& method, pp::Var* exception) {
+ std::string method_str = method.AsString();
+ return (method_str == kJSAccessibility ||
+ method_str == kJSDocumentLoadComplete ||
+ method_str == kJSGetHeight ||
+ method_str == kJSGetHorizontalScrollbarThickness ||
+ method_str == kJSGetPageLocationNormalized ||
+ method_str == kJSGetSelectedText ||
+ method_str == kJSGetVerticalScrollbarThickness ||
+ method_str == kJSGetWidth ||
+ method_str == kJSGetZoomLevel ||
+ method_str == kJSGoToPage ||
+ method_str == kJSGrayscale ||
+ method_str == kJSLoadPreviewPage ||
+ method_str == kJSOnLoad ||
+ method_str == kJSOnPluginSizeChanged ||
+ method_str == kJSOnScroll ||
+ method_str == kJSPageXOffset ||
+ method_str == kJSPageYOffset ||
+ method_str == kJSPrintPreviewPageCount ||
+ method_str == kJSReload ||
+ method_str == kJSRemovePrintButton ||
+ method_str == kJSResetPrintPreviewUrl ||
+ method_str == kJSSendKeyEvent ||
+ method_str == kJSSetPageNumbers ||
+ method_str == kJSSetPageXOffset ||
+ method_str == kJSSetPageYOffset ||
+ method_str == kJSSetZoomLevel ||
+ method_str == kJSZoomFitToHeight ||
+ method_str == kJSZoomFitToWidth ||
+ method_str == kJSZoomIn ||
+ method_str == kJSZoomOut);
+}
+
+pp::Var Instance::CallScriptableMethod(const pp::Var& method,
+ const std::vector<pp::Var>& args,
+ pp::Var* exception) {
+ std::string method_str = method.AsString();
+ if (method_str == kJSGrayscale) {
+ if (args.size() == 1 && args[0].is_bool()) {
+ engine_->SetGrayscale(args[0].AsBool());
+ // Redraw
+ paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
+#ifdef ENABLE_THUMBNAILS
+ if (thumbnails_.visible())
+ thumbnails_.Show(true, true);
+#endif
+ return pp::Var(true);
+ }
+ return pp::Var(false);
+ }
+ if (method_str == kJSOnLoad) {
+ if (args.size() == 1 && args[0].is_string()) {
+ on_load_callback_ = args[0];
+ return pp::Var(true);
+ }
+ return pp::Var(false);
+ }
+ if (method_str == kJSOnScroll) {
+ if (args.size() == 1 && args[0].is_string()) {
+ on_scroll_callback_ = args[0];
+ return pp::Var(true);
+ }
+ return pp::Var(false);
+ }
+ if (method_str == kJSOnPluginSizeChanged) {
+ if (args.size() == 1 && args[0].is_string()) {
+ on_plugin_size_changed_callback_ = args[0];
+ return pp::Var(true);
+ }
+ return pp::Var(false);
+ }
+ if (method_str == kJSReload) {
+ document_load_state_ = LOAD_STATE_LOADING;
+ if (!full_)
+ LoadUrl(url_);
+ preview_engine_.reset();
+ print_preview_page_count_ = 0;
+ engine_.reset(PDFEngine::Create(this));
+ engine_->New(url_.c_str());
+#ifdef ENABLE_THUMBNAILS
+ thumbnails_.ResetEngine(engine_.get());
+#endif
+ return pp::Var();
+ }
+ if (method_str == kJSResetPrintPreviewUrl) {
+ if (args.size() == 1 && args[0].is_string()) {
+ url_ = args[0].AsString();
+ preview_pages_info_ = std::queue<PreviewPageInfo>();
+ preview_document_load_state_ = LOAD_STATE_COMPLETE;
+ }
+ return pp::Var();
+ }
+ if (method_str == kJSZoomFitToHeight) {
+ SetZoom(ZOOM_FIT_TO_PAGE, 0);
+ return pp::Var();
+ }
+ if (method_str == kJSZoomFitToWidth) {
+ SetZoom(ZOOM_FIT_TO_WIDTH, 0);
+ return pp::Var();
+ }
+ if (method_str == kJSZoomIn) {
+ SetZoom(ZOOM_SCALE, CalculateZoom(kZoomInButtonId));
+ return pp::Var();
+ }
+ if (method_str == kJSZoomOut) {
+ SetZoom(ZOOM_SCALE, CalculateZoom(kZoomOutButtonId));
+ return pp::Var();
+ }
+ if (method_str == kJSSetZoomLevel) {
+ if (args.size() == 1 && args[0].is_number())
+ SetZoom(ZOOM_SCALE, args[0].AsDouble());
+ return pp::Var();
+ }
+ if (method_str == kJSGetZoomLevel) {
+ return pp::Var(zoom_);
+ }
+ if (method_str == kJSGetHeight) {
+ return pp::Var(plugin_size_.height());
+ }
+ if (method_str == kJSGetWidth) {
+ return pp::Var(plugin_size_.width());
+ }
+ if (method_str == kJSGetHorizontalScrollbarThickness) {
+ return pp::Var(
+ h_scrollbar_.get() ? GetScrollbarReservedThickness() : 0);
+ }
+ if (method_str == kJSGetVerticalScrollbarThickness) {
+ return pp::Var(
+ v_scrollbar_.get() ? GetScrollbarReservedThickness() : 0);
+ }
+ if (method_str == kJSGetSelectedText) {
+ return GetSelectedText(false);
+ }
+ if (method_str == kJSDocumentLoadComplete) {
+ return pp::Var((document_load_state_ != LOAD_STATE_LOADING));
+ }
+ if (method_str == kJSPageYOffset) {
+ return pp::Var(static_cast<int32_t>(
+ v_scrollbar_.get() ? v_scrollbar_->GetValue() : 0));
+ }
+ if (method_str == kJSSetPageYOffset) {
+ if (args.size() == 1 && args[0].is_number() && v_scrollbar_.get())
+ ScrollToY(GetScaled(args[0].AsInt()));
+ return pp::Var();
+ }
+ if (method_str == kJSPageXOffset) {
+ return pp::Var(static_cast<int32_t>(
+ h_scrollbar_.get() ? h_scrollbar_->GetValue() : 0));
+ }
+ if (method_str == kJSSetPageXOffset) {
+ if (args.size() == 1 && args[0].is_number() && h_scrollbar_.get())
+ ScrollToX(GetScaled(args[0].AsInt()));
+ return pp::Var();
+ }
+ if (method_str == kJSRemovePrintButton) {
+ CreateToolbar(kPrintPreviewToolbarButtons,
+ arraysize(kPrintPreviewToolbarButtons));
+ UpdateToolbarPosition(false);
+ Invalidate(pp::Rect(plugin_size_));
+ return pp::Var();
+ }
+ if (method_str == kJSGoToPage) {
+ if (args.size() == 1 && args[0].is_string()) {
+ ScrollToPage(atoi(args[0].AsString().c_str()));
+ }
+ return pp::Var();
+ }
+ if (method_str == kJSAccessibility) {
+ if (args.size() == 0) {
+ base::DictionaryValue node;
+ node.SetInteger(kAccessibleNumberOfPages, engine_->GetNumberOfPages());
+ node.SetBoolean(kAccessibleLoaded,
+ document_load_state_ != LOAD_STATE_LOADING);
+ bool has_permissions =
+ engine_->HasPermission(PDFEngine::PERMISSION_COPY) ||
+ engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE);
+ node.SetBoolean(kAccessibleCopyable, has_permissions);
+ std::string json;
+ base::JSONWriter::Write(&node, &json);
+ return pp::Var(json);
+ } else if (args[0].is_number()) {
+ return pp::Var(engine_->GetPageAsJSON(args[0].AsInt()));
+ }
+ }
+ if (method_str == kJSPrintPreviewPageCount) {
+ if (args.size() == 1 && args[0].is_number())
+ SetPrintPreviewMode(args[0].AsInt());
+ return pp::Var();
+ }
+ if (method_str == kJSLoadPreviewPage) {
+ if (args.size() == 2 && args[0].is_string() && args[1].is_number())
+ ProcessPreviewPageInfo(args[0].AsString(), args[1].AsInt());
+ return pp::Var();
+ }
+ if (method_str == kJSGetPageLocationNormalized) {
+ const size_t kMaxLength = 30;
+ char location_info[kMaxLength];
+ int page_idx = engine_->GetMostVisiblePage();
+ if (page_idx < 0)
+ return pp::Var(std::string());
+ pp::Rect rect = engine_->GetPageContentsRect(page_idx);
+ int v_scrollbar_reserved_thickness =
+ v_scrollbar_.get() ? GetScaled(GetScrollbarReservedThickness()) : 0;
+
+ rect.set_x(rect.x() + ((plugin_size_.width() -
+ v_scrollbar_reserved_thickness - available_area_.width()) / 2));
+ base::snprintf(location_info,
+ kMaxLength,
+ "%0.4f;%0.4f;%0.4f;%0.4f;",
+ rect.x() / static_cast<float>(plugin_size_.width()),
+ rect.y() / static_cast<float>(plugin_size_.height()),
+ rect.width() / static_cast<float>(plugin_size_.width()),
+ rect.height()/ static_cast<float>(plugin_size_.height()));
+ return pp::Var(std::string(location_info));
+ }
+ if (method_str == kJSSetPageNumbers) {
+ if (args.size() != 1 || !args[0].is_string())
+ return pp::Var();
+ const int num_pages_signed = engine_->GetNumberOfPages();
+ if (num_pages_signed <= 0)
+ return pp::Var();
+ scoped_ptr<base::ListValue> page_ranges(static_cast<base::ListValue*>(
+ base::JSONReader::Read(args[0].AsString(), false)));
+ const size_t num_pages = static_cast<size_t>(num_pages_signed);
+ if (!page_ranges.get() || page_ranges->GetSize() != num_pages)
+ return pp::Var();
+
+ std::vector<int> print_preview_page_numbers;
+ for (size_t index = 0; index < num_pages; ++index) {
+ int page_number = 0; // |page_number| is 1-based.
+ if (!page_ranges->GetInteger(index, &page_number) || page_number < 1)
+ return pp::Var();
+ print_preview_page_numbers.push_back(page_number);
+ }
+ print_preview_page_numbers_ = print_preview_page_numbers;
+ page_indicator_.set_current_page(GetPageNumberToDisplay());
+ return pp::Var();
+ }
+ // This is here to work around https://bugs.webkit.org/show_bug.cgi?id=16735.
+ // In JS, creating a synthetic keyboard event and dispatching it always
+ // result in a keycode of 0.
+ if (method_str == kJSSendKeyEvent) {
+ if (args.size() == 1 && args[0].is_number()) {
+ pp::KeyboardInputEvent event(
+ this, // instance
+ PP_INPUTEVENT_TYPE_KEYDOWN, // HandleInputEvent only care about this.
+ 0, // timestamp, not used for kbd events.
+ 0, // no modifiers.
+ args[0].AsInt(), // keycode.
+ pp::Var()); // no char text needed.
+ HandleInputEvent(event);
+ }
+ }
+ return pp::Var();
+}
+
+void Instance::OnGeometryChanged(double old_zoom, float old_device_scale) {
+ bool force_no_horizontal_scrollbar = false;
+ int scrollbar_thickness = GetScrollbarThickness();
+
+ if (old_device_scale != device_scale_) {
+ // Change in device scale forces us to recreate resources
+ ConfigureNumberImageGenerator();
+
+ CreateToolbar(current_tb_info_, current_tb_info_size_);
+ // Load autoscroll anchor image.
+ autoscroll_anchor_ =
+ CreateResourceImage(PP_RESOURCEIMAGE_PDF_PAN_SCROLL_ICON);
+
+ ConfigurePageIndicator();
+ ConfigureProgressBar();
+
+ pp::Point scroll_position = engine_->GetScrollPosition();
+ ScalePoint(device_scale_ / old_device_scale, &scroll_position);
+ engine_->SetScrollPosition(scroll_position);
+ }
+
+ UpdateZoomScale();
+ if (zoom_ != old_zoom || device_scale_ != old_device_scale)
+ engine_->ZoomUpdated(zoom_ * device_scale_);
+ if (zoom_ != old_zoom)
+ ZoomChanged(zoom_);
+
+ available_area_ = pp::Rect(plugin_size_);
+ if (GetDocumentPixelHeight() > plugin_size_.height()) {
+ CreateVerticalScrollbar();
+ } else {
+ DestroyVerticalScrollbar();
+ }
+
+ int v_scrollbar_reserved_thickness =
+ v_scrollbar_.get() ? GetScaled(GetScrollbarReservedThickness()) : 0;
+
+ if (!force_no_horizontal_scrollbar &&
+ GetDocumentPixelWidth() >
+ (plugin_size_.width() - v_scrollbar_reserved_thickness)) {
+ CreateHorizontalScrollbar();
+
+ // Adding the horizontal scrollbar now might cause us to need vertical
+ // scrollbars.
+ if (GetDocumentPixelHeight() >
+ plugin_size_.height() - GetScaled(GetScrollbarReservedThickness())) {
+ CreateVerticalScrollbar();
+ }
+
+ } else {
+ DestroyHorizontalScrollbar();
+ }
+
+#ifdef ENABLE_THUMBNAILS
+ int thumbnails_pos = 0, thumbnails_total = 0;
+#endif
+ if (v_scrollbar_.get()) {
+ v_scrollbar_->SetScale(device_scale_);
+ available_area_.set_width(
+ std::max(0, plugin_size_.width() - v_scrollbar_reserved_thickness));
+
+#ifdef ENABLE_THUMBNAILS
+ int height = plugin_size_.height();
+#endif
+ int height_dip = plugin_dip_size_.height();
+
+#if defined(OS_MACOSX)
+ // Before Lion, Mac always had the resize at the bottom. After that, it
+ // never did.
+ if ((base::mac::IsOSSnowLeopard() && full_) ||
+ (base::mac::IsOSLionOrLater() && h_scrollbar_.get())) {
+#else
+ if (h_scrollbar_.get()) {
+#endif // defined(OS_MACOSX)
+#ifdef ENABLE_THUMBNAILS
+ height -= GetScaled(GetScrollbarThickness());
+#endif
+ height_dip -= GetScrollbarThickness();
+ }
+#ifdef ENABLE_THUMBNAILS
+ int32 doc_height = GetDocumentPixelHeight();
+#endif
+ int32 doc_height_dip =
+ static_cast<int32>(GetDocumentPixelHeight() / device_scale_);
+#if defined(OS_MACOSX)
+ // On the Mac we always allow room for the resize button (whose width is
+ // the same as that of the scrollbar) in full mode. However, if there is no
+ // no horizontal scrollbar, the end of the scrollbar will scroll past the
+ // end of the document. This is because the scrollbar assumes that its own
+ // height (in the case of a vscroll bar) is the same as the height of the
+ // viewport. Since the viewport is actually larger, we compensate by
+ // adjusting the document height. Similar logic applies below for the
+ // horizontal scrollbar.
+ // For example, if the document size is 1000, and the viewport size is 200,
+ // then the scrollbar position at the end will be 800. In this case the
+ // viewport is actally 215 (assuming 15 as the scrollbar width) but the
+ // scrollbar thinks it is 200. We want the scrollbar position at the end to
+ // be 785. Making the document size 985 achieves this.
+ if (full_ && !h_scrollbar_.get()) {
+#ifdef ENABLE_THUMBNAILS
+ doc_height -= GetScaled(GetScrollbarThickness());
+#endif
+ doc_height_dip -= GetScrollbarThickness();
+ }
+#endif // defined(OS_MACOSX)
+
+ int32 position;
+ position = v_scrollbar_->GetValue();
+ position = static_cast<int>(position * zoom_ / old_zoom);
+ valid_v_range_ = doc_height_dip - height_dip;
+ if (position > valid_v_range_)
+ position = valid_v_range_;
+
+ v_scrollbar_->SetValue(position);
+
+ PP_Rect loc;
+ loc.point.x = static_cast<int>(available_area_.right() / device_scale_);
+ if (IsOverlayScrollbar())
+ loc.point.x -= scrollbar_thickness;
+ loc.point.y = 0;
+ loc.size.width = scrollbar_thickness;
+ loc.size.height = height_dip;
+ v_scrollbar_->SetLocation(loc);
+ v_scrollbar_->SetDocumentSize(doc_height_dip);
+
+#ifdef ENABLE_THUMBNAILS
+ thumbnails_pos = position;
+ thumbnails_total = doc_height - height;
+#endif
+ }
+
+ if (h_scrollbar_.get()) {
+ h_scrollbar_->SetScale(device_scale_);
+ available_area_.set_height(
+ std::max(0, plugin_size_.height() -
+ GetScaled(GetScrollbarReservedThickness())));
+
+ int width_dip = plugin_dip_size_.width();
+
+ // See note above.
+#if defined(OS_MACOSX)
+ if ((base::mac::IsOSSnowLeopard() && full_) ||
+ (base::mac::IsOSLionOrLater() && v_scrollbar_.get())) {
+#else
+ if (v_scrollbar_.get()) {
+#endif
+ width_dip -= GetScrollbarThickness();
+ }
+ int32 doc_width_dip =
+ static_cast<int32>(GetDocumentPixelWidth() / device_scale_);
+#if defined(OS_MACOSX)
+ // See comment in the above if (v_scrollbar_.get()) block.
+ if (full_ && !v_scrollbar_.get())
+ doc_width_dip -= GetScrollbarThickness();
+#endif // defined(OS_MACOSX)
+
+ int32 position;
+ position = h_scrollbar_->GetValue();
+ position = static_cast<int>(position * zoom_ / old_zoom);
+ position = std::min(position, doc_width_dip - width_dip);
+
+ h_scrollbar_->SetValue(position);
+
+ PP_Rect loc;
+ loc.point.x = 0;
+ loc.point.y = static_cast<int>(available_area_.bottom() / device_scale_);
+ if (IsOverlayScrollbar())
+ loc.point.y -= scrollbar_thickness;
+ loc.size.width = width_dip;
+ loc.size.height = scrollbar_thickness;
+ h_scrollbar_->SetLocation(loc);
+ h_scrollbar_->SetDocumentSize(doc_width_dip);
+ }
+
+ int doc_width = GetDocumentPixelWidth();
+ if (doc_width < available_area_.width()) {
+ available_area_.Offset((available_area_.width() - doc_width) / 2, 0);
+ available_area_.set_width(doc_width);
+ }
+ int doc_height = GetDocumentPixelHeight();
+ if (doc_height < available_area_.height()) {
+ available_area_.set_height(doc_height);
+ }
+
+ // We'll invalidate the entire plugin anyways.
+ UpdateToolbarPosition(false);
+ UpdateProgressBarPosition(false);
+ UpdatePageIndicatorPosition(false);
+
+#ifdef ENABLE_THUMBNAILS
+ // Update thumbnail control position.
+ thumbnails_.SetPosition(thumbnails_pos, thumbnails_total, false);
+ pp::Rect thumbnails_rc(plugin_size_.width() - GetScaled(kThumbnailsWidth), 0,
+ GetScaled(kThumbnailsWidth), plugin_size_.height());
+ if (v_scrollbar_.get())
+ thumbnails_rc.Offset(-v_scrollbar_reserved_thickness, 0);
+ if (h_scrollbar_.get())
+ thumbnails_rc.Inset(0, 0, 0, v_scrollbar_reserved_thickness);
+ thumbnails_.SetRect(thumbnails_rc, false);
+#endif
+
+ CalculateBackgroundParts();
+ engine_->PageOffsetUpdated(available_area_.point());
+ engine_->PluginSizeUpdated(available_area_.size());
+
+ if (!document_size_.GetArea())
+ return;
+ paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
+
+ // Run the plugin size change callback asynchronously. This function can be
+ // invoked by a layout change which should not re-enter into JS synchronously.
+ pp::CompletionCallback callback =
+ callback_factory_.NewCallback(&Instance::RunCallback,
+ on_plugin_size_changed_callback_);
+ pp::Module::Get()->core()->CallOnMainThread(0, callback);
+}
+
+void Instance::RunCallback(int32_t, pp::Var callback) {
+ if (callback.is_string())
+ ExecuteScript(callback);
+}
+
+void Instance::CreateHorizontalScrollbar() {
+ if (h_scrollbar_.get())
+ return;
+
+ h_scrollbar_.reset(new pp::Scrollbar_Dev(this, false));
+}
+
+void Instance::CreateVerticalScrollbar() {
+ if (v_scrollbar_.get())
+ return;
+
+ v_scrollbar_.reset(new pp::Scrollbar_Dev(this, true));
+}
+
+void Instance::DestroyHorizontalScrollbar() {
+ if (!h_scrollbar_.get())
+ return;
+ if (h_scrollbar_->GetValue())
+ engine_->ScrolledToXPosition(0);
+ h_scrollbar_.reset();
+}
+
+void Instance::DestroyVerticalScrollbar() {
+ if (!v_scrollbar_.get())
+ return;
+ if (v_scrollbar_->GetValue())
+ engine_->ScrolledToYPosition(0);
+ v_scrollbar_.reset();
+ page_indicator_.Show(false, true);
+}
+
+int Instance::GetScrollbarThickness() {
+ if (scrollbar_thickness_ == -1) {
+ pp::Scrollbar_Dev temp_scrollbar(this, false);
+ scrollbar_thickness_ = temp_scrollbar.GetThickness();
+ scrollbar_reserved_thickness_ =
+ temp_scrollbar.IsOverlay() ? 0 : scrollbar_thickness_;
+ }
+
+ return scrollbar_thickness_;
+}
+
+int Instance::GetScrollbarReservedThickness() {
+ GetScrollbarThickness();
+ return scrollbar_reserved_thickness_;
+}
+
+bool Instance::IsOverlayScrollbar() {
+ return GetScrollbarReservedThickness() == 0;
+}
+
+void Instance::CreateToolbar(const ToolbarButtonInfo* tb_info, size_t size) {
+ toolbar_.reset(new FadingControls());
+
+ DCHECK(tb_info);
+ DCHECK(size >= 0);
+
+ // Remember the current toolbar information in case we need to recreate the
+ // images later.
+ current_tb_info_ = tb_info;
+ current_tb_info_size_ = size;
+
+ int max_height = 0;
+ pp::Point origin(kToolbarFadingOffsetLeft, kToolbarFadingOffsetTop);
+ ScalePoint(device_scale_, &origin);
+
+ std::list<Button*> buttons;
+ for (size_t i = 0; i < size; i++) {
+ Button* btn = new Button;
+ pp::ImageData normal_face =
+ CreateResourceImage(tb_info[i].normal);
+ btn->CreateButton(tb_info[i].id,
+ origin,
+ true,
+ toolbar_.get(),
+ tb_info[i].style,
+ normal_face,
+ CreateResourceImage(tb_info[i].highlighted),
+ CreateResourceImage(tb_info[i].pressed));
+ buttons.push_back(btn);
+
+ origin += pp::Point(normal_face.size().width(), 0);
+ max_height = std::max(max_height, normal_face.size().height());
+ }
+
+ pp::Rect rc_toolbar(0, 0,
+ origin.x() + GetToolbarRightOffset(),
+ origin.y() + max_height + GetToolbarBottomOffset());
+ toolbar_->CreateFadingControls(
+ kToolbarId, rc_toolbar, false, this, kTransparentAlpha);
+
+ std::list<Button*>::iterator iter;
+ for (iter = buttons.begin(); iter != buttons.end(); ++iter) {
+ toolbar_->AddControl(*iter);
+ }
+}
+
+int Instance::GetToolbarRightOffset() {
+ int scrollbar_thickness = GetScrollbarThickness();
+ return GetScaled(kToolbarFadingOffsetRight) + 2 * scrollbar_thickness;
+}
+
+int Instance::GetToolbarBottomOffset() {
+ int scrollbar_thickness = GetScrollbarThickness();
+ return GetScaled(kToolbarFadingOffsetBottom) + scrollbar_thickness;
+}
+
+std::vector<pp::ImageData> Instance::GetThumbnailResources() {
+ std::vector<pp::ImageData> num_images(10);
+ num_images[0] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_0);
+ num_images[1] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_1);
+ num_images[2] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_2);
+ num_images[3] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_3);
+ num_images[4] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_4);
+ num_images[5] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_5);
+ num_images[6] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_6);
+ num_images[7] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_7);
+ num_images[8] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_8);
+ num_images[9] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_9);
+ return num_images;
+}
+
+std::vector<pp::ImageData> Instance::GetProgressBarResources(
+ pp::ImageData* background) {
+ std::vector<pp::ImageData> result(9);
+ result[0] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_0);
+ result[1] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_1);
+ result[2] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_2);
+ result[3] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_3);
+ result[4] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_4);
+ result[5] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_5);
+ result[6] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_6);
+ result[7] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_7);
+ result[8] = CreateResourceImage(PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_8);
+ *background = CreateResourceImage(
+ PP_RESOURCEIMAGE_PDF_PROGRESS_BAR_BACKGROUND);
+ return result;
+}
+
+void Instance::CreatePageIndicator(bool always_visible) {
+ page_indicator_.CreatePageIndicator(kPageIndicatorId, false, this,
+ number_image_generator(), always_visible);
+ ConfigurePageIndicator();
+}
+
+void Instance::ConfigurePageIndicator() {
+ pp::ImageData background =
+ CreateResourceImage(PP_RESOURCEIMAGE_PDF_PAGE_INDICATOR_BACKGROUND);
+ page_indicator_.Configure(pp::Point(), background);
+}
+
+void Instance::CreateProgressBar() {
+ pp::ImageData background;
+ std::vector<pp::ImageData> images = GetProgressBarResources(&background);
+ std::string text = GetLocalizedString(PP_RESOURCESTRING_PDFPROGRESSLOADING);
+ progress_bar_.CreateProgressControl(kProgressBarId, false, this, 0.0,
+ device_scale_, images, background, text);
+}
+
+void Instance::ConfigureProgressBar() {
+ pp::ImageData background;
+ std::vector<pp::ImageData> images = GetProgressBarResources(&background);
+ progress_bar_.Reconfigure(background, images, device_scale_);
+}
+
+void Instance::CreateThumbnails() {
+ thumbnails_.CreateThumbnailControl(
+ kThumbnailsId, pp::Rect(), false, this, engine_.get(),
+ number_image_generator());
+}
+
+void Instance::LoadUrl(const std::string& url) {
+ LoadUrlInternal(url, &embed_loader_, &Instance::DidOpen);
+}
+
+void Instance::LoadPreviewUrl(const std::string& url) {
+ LoadUrlInternal(url, &embed_preview_loader_, &Instance::DidOpenPreview);
+}
+
+void Instance::LoadUrlInternal(const std::string& url, pp::URLLoader* loader,
+ void (Instance::* method)(int32_t)) {
+ pp::URLRequestInfo request(this);
+ request.SetURL(url);
+ request.SetMethod("GET");
+
+ *loader = CreateURLLoaderInternal();
+ pp::CompletionCallback callback = loader_factory_.NewCallback(method);
+ int rv = loader->Open(request, callback);
+ if (rv != PP_OK_COMPLETIONPENDING)
+ callback.Run(rv);
+}
+
+pp::URLLoader Instance::CreateURLLoaderInternal() {
+ pp::URLLoader loader(this);
+
+ const PPB_URLLoaderTrusted* trusted_interface =
+ reinterpret_cast<const PPB_URLLoaderTrusted*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_URLLOADERTRUSTED_INTERFACE));
+ if (trusted_interface)
+ trusted_interface->GrantUniversalAccess(loader.pp_resource());
+ return loader;
+}
+
+int Instance::GetInitialPage(const std::string& url) {
+ size_t found_idx = url.find('#');
+ if (found_idx == std::string::npos)
+ return -1;
+
+ const std::string& ref = url.substr(found_idx + 1);
+ std::vector<std::string> fragments;
+ Tokenize(ref, kDelimiters, &fragments);
+
+ // Page number to return, zero-based.
+ int page = -1;
+
+ // Handle the case of http://foo.com/bar#NAMEDDEST. This is not explicitly
+ // mentioned except by example in the Adobe "PDF Open Parameters" document.
+ if ((fragments.size() == 1) && (fragments[0].find('=') == std::string::npos))
+ return engine_->GetNamedDestinationPage(fragments[0]);
+
+ for (size_t i = 0; i < fragments.size(); ++i) {
+ std::vector<std::string> key_value;
+ base::SplitString(fragments[i], '=', &key_value);
+ if (key_value.size() != 2)
+ continue;
+ const std::string& key = key_value[0];
+ const std::string& value = key_value[1];
+
+ if (base::strcasecmp(kPage, key.c_str()) == 0) {
+ // |page_value| is 1-based.
+ int page_value = -1;
+ if (base::StringToInt(value, &page_value) && page_value > 0)
+ page = page_value - 1;
+ continue;
+ }
+ if (base::strcasecmp(kNamedDest, key.c_str()) == 0) {
+ // |page_value| is 0-based.
+ int page_value = engine_->GetNamedDestinationPage(value);
+ if (page_value >= 0)
+ page = page_value;
+ continue;
+ }
+ }
+ return page;
+}
+
+void Instance::UpdateToolbarPosition(bool invalidate) {
+ pp::Rect ctrl_rc = toolbar_->GetControlsRect();
+ int min_toolbar_width = ctrl_rc.width() + GetToolbarRightOffset() +
+ GetScaled(kToolbarFadingOffsetLeft);
+ int min_toolbar_height = ctrl_rc.width() + GetToolbarBottomOffset() +
+ GetScaled(kToolbarFadingOffsetBottom);
+
+ // Update toolbar position
+ if (plugin_size_.width() < min_toolbar_width ||
+ plugin_size_.height() < min_toolbar_height) {
+ // Disable toolbar if it does not fit on the screen.
+ toolbar_->Show(false, invalidate);
+ } else {
+ pp::Point offset(
+ plugin_size_.width() - GetToolbarRightOffset() - ctrl_rc.right(),
+ plugin_size_.height() - GetToolbarBottomOffset() - ctrl_rc.bottom());
+ toolbar_->MoveBy(offset, invalidate);
+
+ int toolbar_width = std::max(plugin_size_.width() / 2, min_toolbar_width);
+ toolbar_->ExpandLeft(toolbar_width - toolbar_->rect().width());
+ toolbar_->Show(painted_first_page_, invalidate);
+ }
+}
+
+void Instance::UpdateProgressBarPosition(bool invalidate) {
+ // TODO(gene): verify we don't overlap with toolbar.
+ int scrollbar_thickness = GetScrollbarThickness();
+ pp::Point progress_origin(
+ scrollbar_thickness + GetScaled(kProgressOffsetLeft),
+ plugin_size_.height() - progress_bar_.rect().height() -
+ scrollbar_thickness - GetScaled(kProgressOffsetBottom));
+ progress_bar_.MoveTo(progress_origin, invalidate);
+}
+
+void Instance::UpdatePageIndicatorPosition(bool invalidate) {
+ int32 doc_height = static_cast<int>(document_size_.height() * zoom_);
+ pp::Point origin(
+ plugin_size_.width() - page_indicator_.rect().width() -
+ GetScaled(GetScrollbarReservedThickness()),
+ page_indicator_.GetYPosition(engine_->GetVerticalScrollbarYPosition(),
+ doc_height, plugin_size_.height()));
+ page_indicator_.MoveTo(origin, invalidate);
+}
+
+void Instance::SetZoom(ZoomMode zoom_mode, double scale) {
+ double old_zoom = zoom_;
+
+ zoom_mode_ = zoom_mode;
+ if (zoom_mode_ == ZOOM_SCALE)
+ zoom_ = scale;
+ UpdateZoomScale();
+
+ engine_->ZoomUpdated(zoom_ * device_scale_);
+ OnGeometryChanged(old_zoom, device_scale_);
+
+ // If fit-to-height, snap to the beginning of the most visible page.
+ if (zoom_mode_ == ZOOM_FIT_TO_PAGE) {
+ ScrollToPage(engine_->GetMostVisiblePage());
+ }
+
+ // Update sticky buttons to the current zoom style.
+ Button* ftp_btn = static_cast<Button*>(
+ toolbar_->GetControl(kFitToPageButtonId));
+ Button* ftw_btn = static_cast<Button*>(
+ toolbar_->GetControl(kFitToWidthButtonId));
+ switch (zoom_mode_) {
+ case ZOOM_FIT_TO_PAGE:
+ ftp_btn->SetPressedState(true);
+ ftw_btn->SetPressedState(false);
+ break;
+ case ZOOM_FIT_TO_WIDTH:
+ ftw_btn->SetPressedState(true);
+ ftp_btn->SetPressedState(false);
+ break;
+ default:
+ ftw_btn->SetPressedState(false);
+ ftp_btn->SetPressedState(false);
+ }
+}
+
+void Instance::UpdateZoomScale() {
+ switch (zoom_mode_) {
+ case ZOOM_SCALE:
+ break; // Keep current scale.
+ case ZOOM_FIT_TO_PAGE: {
+ int page_num = engine_->GetFirstVisiblePage();
+ if (page_num == -1)
+ break;
+ pp::Rect rc = engine_->GetPageRect(page_num);
+ if (!rc.height())
+ break;
+ // Calculate fit to width zoom level.
+ double ftw_zoom = static_cast<double>(plugin_dip_size_.width() -
+ GetScrollbarReservedThickness()) / document_size_.width();
+ // Calculate fit to height zoom level. If document will not fit
+ // horizontally, adjust zoom level to allow space for horizontal
+ // scrollbar.
+ double fth_zoom =
+ static_cast<double>(plugin_dip_size_.height()) / rc.height();
+ if (fth_zoom * document_size_.width() >
+ plugin_dip_size_.width() - GetScrollbarReservedThickness())
+ fth_zoom = static_cast<double>(plugin_dip_size_.height()
+ - GetScrollbarReservedThickness()) / rc.height();
+ zoom_ = std::min(ftw_zoom, fth_zoom);
+ } break;
+ case ZOOM_FIT_TO_WIDTH:
+ case ZOOM_AUTO:
+ if (!document_size_.width())
+ break;
+ zoom_ = static_cast<double>(plugin_dip_size_.width() -
+ GetScrollbarReservedThickness()) / document_size_.width();
+ if (zoom_mode_ == ZOOM_AUTO && zoom_ > 1.0)
+ zoom_ = 1.0;
+ break;
+ }
+ zoom_ = ClipToRange(zoom_, kMinZoom, kMaxZoom);
+}
+
+double Instance::CalculateZoom(uint32 control_id) const {
+ if (control_id == kZoomInButtonId) {
+ for (size_t i = 0; i < chrome_page_zoom::kPresetZoomFactorsSize; ++i) {
+ double current_zoom = chrome_page_zoom::kPresetZoomFactors[i];
+ if (current_zoom - content::kEpsilon > zoom_)
+ return current_zoom;
+ }
+ } else {
+ for (size_t i = chrome_page_zoom::kPresetZoomFactorsSize; i > 0; --i) {
+ double current_zoom = chrome_page_zoom::kPresetZoomFactors[i - 1];
+ if (current_zoom + content::kEpsilon < zoom_)
+ return current_zoom;
+ }
+ }
+ return zoom_;
+}
+
+pp::ImageData Instance::CreateResourceImage(PP_ResourceImage image_id) {
+ pp::ImageData resource_data;
+ if (hidpi_enabled_) {
+ resource_data =
+ pp::PDF::GetResourceImageForScale(this, image_id, device_scale_);
+ }
+
+ return resource_data.data() ? resource_data
+ : pp::PDF::GetResourceImage(this, image_id);
+}
+
+std::string Instance::GetLocalizedString(PP_ResourceString id) {
+ pp::Var rv(pp::PDF::GetLocalizedString(this, id));
+ if (!rv.is_string())
+ return std::string();
+
+ return rv.AsString();
+}
+
+void Instance::DrawText(const pp::Point& top_center, PP_ResourceString id) {
+ std::string str(GetLocalizedString(id));
+
+ pp::FontDescription_Dev description;
+ description.set_family(PP_FONTFAMILY_SANSSERIF);
+ description.set_size(kMessageTextSize * device_scale_);
+ pp::Font_Dev font(this, description);
+ int length = font.MeasureSimpleText(str);
+ pp::Point point(top_center);
+ point.set_x(point.x() - length / 2);
+ DCHECK(!image_data_.is_null());
+ font.DrawSimpleText(&image_data_, str, point, kMessageTextColor);
+}
+
+void Instance::SetPrintPreviewMode(int page_count) {
+ if (!IsPrintPreview() || page_count <= 0) {
+ print_preview_page_count_ = 0;
+ return;
+ }
+
+ print_preview_page_count_ = page_count;
+ ScrollToPage(0);
+ engine_->AppendBlankPages(print_preview_page_count_);
+ if (preview_pages_info_.size() > 0)
+ LoadAvailablePreviewPage();
+}
+
+bool Instance::IsPrintPreview() {
+ return IsPrintPreviewUrl(url_);
+}
+
+int Instance::GetPageNumberToDisplay() {
+ int page = engine_->GetMostVisiblePage();
+ if (IsPrintPreview() && !print_preview_page_numbers_.empty()) {
+ page = ClipToRange<int>(page, 0, print_preview_page_numbers_.size() - 1);
+ return print_preview_page_numbers_[page];
+ }
+ return page + 1;
+}
+
+void Instance::ProcessPreviewPageInfo(const std::string& url,
+ int dst_page_index) {
+ if (!IsPrintPreview() || print_preview_page_count_ < 0)
+ return;
+
+ int src_page_index = ExtractPrintPreviewPageIndex(url);
+ if (src_page_index < 1)
+ return;
+
+ preview_pages_info_.push(std::make_pair(url, dst_page_index));
+ LoadAvailablePreviewPage();
+}
+
+void Instance::LoadAvailablePreviewPage() {
+ if (preview_pages_info_.size() <= 0)
+ return;
+
+ std::string url = preview_pages_info_.front().first;
+ int dst_page_index = preview_pages_info_.front().second;
+ int src_page_index = ExtractPrintPreviewPageIndex(url);
+ if (src_page_index < 1 ||
+ dst_page_index >= print_preview_page_count_ ||
+ preview_document_load_state_ == LOAD_STATE_LOADING) {
+ return;
+ }
+
+ preview_document_load_state_ = LOAD_STATE_LOADING;
+ LoadPreviewUrl(url);
+}
+
+void Instance::EnableAutoscroll(const pp::Point& origin) {
+ if (is_autoscroll_)
+ return;
+
+ pp::Size client_size = plugin_size_;
+ if (v_scrollbar_.get())
+ client_size.Enlarge(-GetScrollbarThickness(), 0);
+ if (h_scrollbar_.get())
+ client_size.Enlarge(0, -GetScrollbarThickness());
+
+ // Do not allow autoscroll if client area is too small.
+ if (autoscroll_anchor_.size().width() > client_size.width() ||
+ autoscroll_anchor_.size().height() > client_size.height())
+ return;
+
+ autoscroll_rect_ = pp::Rect(
+ pp::Point(origin.x() - autoscroll_anchor_.size().width() / 2,
+ origin.y() - autoscroll_anchor_.size().height() / 2),
+ autoscroll_anchor_.size());
+
+ // Make sure autoscroll anchor is in the client area.
+ if (autoscroll_rect_.right() > client_size.width()) {
+ autoscroll_rect_.set_x(
+ client_size.width() - autoscroll_anchor_.size().width());
+ }
+ if (autoscroll_rect_.bottom() > client_size.height()) {
+ autoscroll_rect_.set_y(
+ client_size.height() - autoscroll_anchor_.size().height());
+ }
+
+ if (autoscroll_rect_.x() < 0)
+ autoscroll_rect_.set_x(0);
+ if (autoscroll_rect_.y() < 0)
+ autoscroll_rect_.set_y(0);
+
+ is_autoscroll_ = true;
+ Invalidate(kAutoScrollId, autoscroll_rect_);
+
+ ScheduleTimer(kAutoScrollId, kAutoScrollTimeoutMs);
+}
+
+void Instance::DisableAutoscroll() {
+ if (is_autoscroll_) {
+ is_autoscroll_ = false;
+ Invalidate(kAutoScrollId, autoscroll_rect_);
+ }
+}
+
+PP_CursorType_Dev Instance::CalculateAutoscroll(const pp::Point& mouse_pos) {
+ // Scroll only if mouse pointer is outside of the anchor area.
+ if (autoscroll_rect_.Contains(mouse_pos)) {
+ autoscroll_x_ = 0;
+ autoscroll_y_ = 0;
+ return PP_CURSORTYPE_MIDDLEPANNING;
+ }
+
+ // Relative position to the center of anchor area.
+ pp::Point rel_pos = mouse_pos - autoscroll_rect_.CenterPoint();
+
+ // Calculate angle from the X axis. Angle is in range from -pi to pi.
+ double angle = atan2(static_cast<double>(rel_pos.y()),
+ static_cast<double>(rel_pos.x()));
+
+ autoscroll_x_ = rel_pos.x() * kAutoScrollFactor;
+ autoscroll_y_ = rel_pos.y() * kAutoScrollFactor;
+
+ // Angle is from -pi to pi. Screen Y is increasing toward bottom,
+ // so negative angle represent north direction.
+ if (angle < - (M_PI * 7.0 / 8.0)) {
+ // going west
+ return PP_CURSORTYPE_WESTPANNING;
+ } else if (angle < - (M_PI * 5.0 / 8.0)) {
+ // going north-west
+ return PP_CURSORTYPE_NORTHWESTPANNING;
+ } else if (angle < - (M_PI * 3.0 / 8.0)) {
+ // going north.
+ return PP_CURSORTYPE_NORTHPANNING;
+ } else if (angle < - (M_PI * 1.0 / 8.0)) {
+ // going north-east
+ return PP_CURSORTYPE_NORTHEASTPANNING;
+ } else if (angle < M_PI * 1.0 / 8.0) {
+ // going east.
+ return PP_CURSORTYPE_EASTPANNING;
+ } else if (angle < M_PI * 3.0 / 8.0) {
+ // going south-east
+ return PP_CURSORTYPE_SOUTHEASTPANNING;
+ } else if (angle < M_PI * 5.0 / 8.0) {
+ // going south.
+ return PP_CURSORTYPE_SOUTHPANNING;
+ } else if (angle < M_PI * 7.0 / 8.0) {
+ // going south-west
+ return PP_CURSORTYPE_SOUTHWESTPANNING;
+ }
+
+ // went around the circle, going west again
+ return PP_CURSORTYPE_WESTPANNING;
+}
+
+void Instance::ConfigureNumberImageGenerator() {
+ std::vector<pp::ImageData> num_images = GetThumbnailResources();
+ pp::ImageData number_background = CreateResourceImage(
+ PP_RESOURCEIMAGE_PDF_BUTTON_THUMBNAIL_NUM_BACKGROUND);
+ number_image_generator_->Configure(number_background,
+ num_images,
+ device_scale_);
+}
+
+NumberImageGenerator* Instance::number_image_generator() {
+ if (!number_image_generator_.get()) {
+ number_image_generator_.reset(new NumberImageGenerator(this));
+ ConfigureNumberImageGenerator();
+ }
+ return number_image_generator_.get();
+}
+
+int Instance::GetScaled(int x) const {
+ return static_cast<int>(x * device_scale_);
+}
+
+void Instance::UserMetricsRecordAction(const std::string& action) {
+ pp::PDF::UserMetricsRecordAction(this, pp::Var(action));
+}
+
+PDFScriptableObject::PDFScriptableObject(Instance* instance)
+ : instance_(instance) {
+}
+
+PDFScriptableObject::~PDFScriptableObject() {
+}
+
+bool PDFScriptableObject::HasMethod(const pp::Var& name, pp::Var* exception) {
+ return instance_->HasScriptableMethod(name, exception);
+}
+
+pp::Var PDFScriptableObject::Call(const pp::Var& method,
+ const std::vector<pp::Var>& args,
+ pp::Var* exception) {
+ return instance_->CallScriptableMethod(method, args, exception);
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/instance.h b/xfa_test/pdf/instance.h
new file mode 100644
index 0000000000..d39ba407c9
--- /dev/null
+++ b/xfa_test/pdf/instance.h
@@ -0,0 +1,531 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_INSTANCE_H_
+#define PDF_INSTANCE_H_
+
+#include <queue>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "pdf/button.h"
+#include "pdf/fading_controls.h"
+#include "pdf/page_indicator.h"
+#include "pdf/paint_manager.h"
+#include "pdf/pdf_engine.h"
+#include "pdf/preview_mode_client.h"
+#include "pdf/progress_control.h"
+#include "pdf/thumbnail_control.h"
+
+#include "ppapi/c/private/ppb_pdf.h"
+#include "ppapi/cpp/dev/printing_dev.h"
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+#include "ppapi/cpp/dev/scrollbar_dev.h"
+#include "ppapi/cpp/dev/selection_dev.h"
+#include "ppapi/cpp/dev/widget_client_dev.h"
+#include "ppapi/cpp/dev/zoom_dev.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/input_event.h"
+#include "ppapi/cpp/private/find_private.h"
+#include "ppapi/cpp/private/instance_private.h"
+#include "ppapi/cpp/private/var_private.h"
+#include "ppapi/cpp/url_loader.h"
+#include "ppapi/utility/completion_callback_factory.h"
+
+namespace pp {
+class TextInput_Dev;
+}
+
+namespace chrome_pdf {
+
+struct ToolbarButtonInfo;
+
+class Instance : public pp::InstancePrivate,
+ public pp::Find_Private,
+ public pp::Printing_Dev,
+ public pp::Selection_Dev,
+ public pp::WidgetClient_Dev,
+ public pp::Zoom_Dev,
+ public PaintManager::Client,
+ public PDFEngine::Client,
+ public PreviewModeClient::Client,
+ public ControlOwner {
+ public:
+ explicit Instance(PP_Instance instance);
+ virtual ~Instance();
+
+ // pp::Instance implementation.
+ virtual bool Init(uint32_t argc,
+ const char* argn[],
+ const char* argv[]) override;
+ virtual bool HandleDocumentLoad(const pp::URLLoader& loader) override;
+ virtual bool HandleInputEvent(const pp::InputEvent& event) override;
+ virtual void DidChangeView(const pp::View& view) override;
+ virtual pp::Var GetInstanceObject() override;
+
+ // pp::Find_Private implementation.
+ virtual bool StartFind(const std::string& text, bool case_sensitive) override;
+ virtual void SelectFindResult(bool forward) override;
+ virtual void StopFind() override;
+
+ // pp::PaintManager::Client implementation.
+ virtual void OnPaint(const std::vector<pp::Rect>& paint_rects,
+ std::vector<PaintManager::ReadyRect>* ready,
+ std::vector<pp::Rect>* pending) override;
+
+ // pp::Printing_Dev implementation.
+ virtual uint32_t QuerySupportedPrintOutputFormats() override;
+ virtual int32_t PrintBegin(
+ const PP_PrintSettings_Dev& print_settings) override;
+ virtual pp::Resource PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) override;
+ virtual void PrintEnd() override;
+ virtual bool IsPrintScalingDisabled() override;
+
+ // pp::Private implementation.
+ virtual pp::Var GetLinkAtPosition(const pp::Point& point);
+
+ // PPP_Selection_Dev implementation.
+ virtual pp::Var GetSelectedText(bool html) override;
+
+ // WidgetClient_Dev implementation.
+ virtual void InvalidateWidget(pp::Widget_Dev widget,
+ const pp::Rect& dirty_rect) override;
+ virtual void ScrollbarValueChanged(pp::Scrollbar_Dev scrollbar,
+ uint32_t value) override;
+ virtual void ScrollbarOverlayChanged(pp::Scrollbar_Dev scrollbar,
+ bool overlay) override;
+
+ // pp::Zoom_Dev implementation.
+ virtual void Zoom(double scale, bool text_only) override;
+ void ZoomChanged(double factor); // Override.
+
+ void FlushCallback(int32_t result);
+ void DidOpen(int32_t result);
+ void DidOpenPreview(int32_t result);
+ // If the given widget intersects the rectangle, paints it and adds the
+ // rect to ready.
+ void PaintIfWidgetIntersects(pp::Widget_Dev* widget,
+ const pp::Rect& rect,
+ std::vector<PaintManager::ReadyRect>* ready,
+ std::vector<pp::Rect>* pending);
+
+ // Called when the timer is fired.
+ void OnTimerFired(int32_t);
+ void OnClientTimerFired(int32_t id);
+
+ // Called when the control timer is fired.
+ void OnControlTimerFired(int32_t,
+ const uint32& control_id,
+ const uint32& timer_id);
+
+ // Called to print without re-entrancy issues.
+ void OnPrint(int32_t);
+
+ // PDFEngine::Client implementation.
+ virtual void DocumentSizeUpdated(const pp::Size& size);
+ virtual void Invalidate(const pp::Rect& rect);
+ virtual void Scroll(const pp::Point& point);
+ virtual void ScrollToX(int position);
+ virtual void ScrollToY(int position);
+ virtual void ScrollToPage(int page);
+ virtual void NavigateTo(const std::string& url, bool open_in_new_tab);
+ virtual void UpdateCursor(PP_CursorType_Dev cursor);
+ virtual void UpdateTickMarks(const std::vector<pp::Rect>& tickmarks);
+ virtual void NotifyNumberOfFindResultsChanged(int total, bool final_result);
+ virtual void NotifySelectedFindResultChanged(int current_find_index);
+ virtual void GetDocumentPassword(
+ pp::CompletionCallbackWithOutput<pp::Var> callback);
+ virtual void Alert(const std::string& message);
+ virtual bool Confirm(const std::string& message);
+ virtual std::string Prompt(const std::string& question,
+ const std::string& default_answer);
+ virtual std::string GetURL();
+ virtual void Email(const std::string& to,
+ const std::string& cc,
+ const std::string& bcc,
+ const std::string& subject,
+ const std::string& body);
+ virtual void Print();
+ virtual void SubmitForm(const std::string& url,
+ const void* data,
+ int length);
+ virtual std::string ShowFileSelectionDialog();
+ virtual pp::URLLoader CreateURLLoader();
+ virtual void ScheduleCallback(int id, int delay_in_ms);
+ virtual void SearchString(const base::char16* string,
+ const base::char16* term,
+ bool case_sensitive,
+ std::vector<SearchStringResult>* results);
+ virtual void DocumentPaintOccurred();
+ virtual void DocumentLoadComplete(int page_count);
+ virtual void DocumentLoadFailed();
+ virtual pp::Instance* GetPluginInstance();
+ virtual void DocumentHasUnsupportedFeature(const std::string& feature);
+ virtual void DocumentLoadProgress(uint32 available, uint32 doc_size);
+ virtual void FormTextFieldFocusChange(bool in_focus);
+ virtual bool IsPrintPreview();
+
+ // ControlOwner implementation.
+ virtual void OnEvent(uint32 control_id, uint32 event_id, void* data);
+ virtual void Invalidate(uint32 control_id, const pp::Rect& rc);
+ virtual uint32 ScheduleTimer(uint32 control_id, uint32 timeout_ms);
+ virtual void SetEventCapture(uint32 control_id, bool set_capture);
+ virtual void SetCursor(uint32 control_id, PP_CursorType_Dev cursor_type);
+ virtual pp::Instance* GetInstance();
+
+ bool dont_paint() const { return dont_paint_; }
+ void set_dont_paint(bool dont_paint) { dont_paint_ = dont_paint; }
+
+ // Called by PDFScriptableObject.
+ bool HasScriptableMethod(const pp::Var& method, pp::Var* exception);
+ pp::Var CallScriptableMethod(const pp::Var& method,
+ const std::vector<pp::Var>& args,
+ pp::Var* exception);
+
+ // PreviewModeClient::Client implementation.
+ virtual void PreviewDocumentLoadComplete() override;
+ virtual void PreviewDocumentLoadFailed() override;
+
+ // Helper functions for implementing PPP_PDF.
+ void RotateClockwise();
+ void RotateCounterclockwise();
+
+ private:
+ // Called whenever the plugin geometry changes to update the location of the
+ // scrollbars, background parts, and notifies the pdf engine.
+ void OnGeometryChanged(double old_zoom, float old_device_scale);
+
+ // Runs the given JS callback given in |callback|.
+ void RunCallback(int32_t, pp::Var callback);
+
+ void CreateHorizontalScrollbar();
+ void CreateVerticalScrollbar();
+ void DestroyHorizontalScrollbar();
+ void DestroyVerticalScrollbar();
+
+ // Returns the thickness of a scrollbar. This returns the thickness when it's
+ // shown, so for overlay scrollbars it'll still be non-zero.
+ int GetScrollbarThickness();
+
+ // Returns the space we need to reserve for the scrollbar in the plugin area.
+ // If overlay scrollbars are used, this will be 0.
+ int GetScrollbarReservedThickness();
+
+ // Returns true if overlay scrollbars are in use.
+ bool IsOverlayScrollbar();
+
+ // Figures out the location of any background rectangles (i.e. those that
+ // aren't painted by the PDF engine).
+ void CalculateBackgroundParts();
+
+ // Computes document width/height in device pixels, based on current zoom and
+ // device scale
+ int GetDocumentPixelWidth() const;
+ int GetDocumentPixelHeight() const;
+
+ // Draws a rectangle with the specified dimensions and color in our buffer.
+ void FillRect(const pp::Rect& rect, uint32 color);
+
+ std::vector<pp::ImageData> GetThumbnailResources();
+ std::vector<pp::ImageData> GetProgressBarResources(pp::ImageData* background);
+
+ void CreateToolbar(const ToolbarButtonInfo* tb_info, size_t size);
+ int GetToolbarRightOffset();
+ int GetToolbarBottomOffset();
+ void CreateProgressBar();
+ void ConfigureProgressBar();
+ void CreateThumbnails();
+ void CreatePageIndicator(bool always_visible);
+ void ConfigurePageIndicator();
+
+ void PaintOverlayControl(Control* ctrl,
+ pp::ImageData* image_data,
+ std::vector<PaintManager::ReadyRect>* ready);
+
+ void LoadUrl(const std::string& url);
+ void LoadPreviewUrl(const std::string& url);
+ void LoadUrlInternal(const std::string& url, pp::URLLoader* loader,
+ void (Instance::* method)(int32_t));
+
+ // Creates a URL loader and allows it to access all urls, i.e. not just the
+ // frame's origin.
+ pp::URLLoader CreateURLLoaderInternal();
+
+ // Figure out the initial page to display based on #page=N and #nameddest=foo
+ // in the |url_|.
+ // Returns -1 if there is no valid fragment. The returned value is 0-based,
+ // whereas page=N is 1-based.
+ int GetInitialPage(const std::string& url);
+
+ void UpdateToolbarPosition(bool invalidate);
+ void UpdateProgressBarPosition(bool invalidate);
+ void UpdatePageIndicatorPosition(bool invalidate);
+
+ void FormDidOpen(int32_t result);
+
+ std::string GetLocalizedString(PP_ResourceString id);
+
+ void UserMetricsRecordAction(const std::string& action);
+
+ void SaveAs();
+
+ enum ZoomMode {
+ ZOOM_SCALE, // Standard zooming mode, resize will not affect it.
+ ZOOM_FIT_TO_WIDTH, // Maintain fit to width on resize.
+ ZOOM_FIT_TO_PAGE, // Maintain fit to page on resize.
+ ZOOM_AUTO // Maintain the default auto fitting mode on resize.
+ };
+
+ enum DocumentLoadState {
+ LOAD_STATE_LOADING,
+ LOAD_STATE_COMPLETE,
+ LOAD_STATE_FAILED,
+ };
+
+ // Set new zoom mode and scale. Scale will be ignored if mode != ZOOM_SCALE.
+ void SetZoom(ZoomMode zoom_mode, double scale);
+
+ // Updates internal zoom scale based on the plugin/document geometry and
+ // current mode.
+ void UpdateZoomScale();
+
+ // Simulates how Chrome "snaps" zooming up/down to the next nearest zoom level
+ // when the previous zoom level wasn't an integer. We do this so that
+ // pressing the zoom buttons has the same effect as the menu buttons, even if
+ // we start from a non-standard zoom level because of fit-width or fit-height.
+ double CalculateZoom(uint32 control_id) const;
+
+ pp::ImageData CreateResourceImage(PP_ResourceImage image_id);
+
+ void DrawText(const pp::Point& top_center, PP_ResourceString id);
+
+ // Set print preview mode, where the current PDF document is reduced to
+ // only one page, and then extended to |page_count| pages with
+ // |page_count| - 1 blank pages.
+ void SetPrintPreviewMode(int page_count);
+
+ // Returns the page number to be displayed in the page indicator. If the
+ // plugin is running within print preview, the displayed number might be
+ // different from the index of the displayed page.
+ int GetPageNumberToDisplay();
+
+ // Process the preview page data information. |src_url| specifies the preview
+ // page data location. The |src_url| is in the format:
+ // chrome://print/id/page_number/print.pdf
+ // |dst_page_index| specifies the blank page index that needs to be replaced
+ // with the new page data.
+ void ProcessPreviewPageInfo(const std::string& src_url, int dst_page_index);
+ // Load the next available preview page into the blank page.
+ void LoadAvailablePreviewPage();
+
+ // Enables autoscroll using origin as a neutral (center) point.
+ void EnableAutoscroll(const pp::Point& origin);
+ // Disables autoscroll and returns to normal functionality.
+ void DisableAutoscroll();
+ // Calculate autoscroll info and return proper mouse pointer and scroll
+ // andjustments.
+ PP_CursorType_Dev CalculateAutoscroll(const pp::Point& mouse_pos);
+
+ void ConfigureNumberImageGenerator();
+
+ NumberImageGenerator* number_image_generator();
+
+ int GetScaled(int x) const;
+
+ pp::ImageData image_data_;
+ // Used when the plugin is embedded in a page and we have to create the loader
+ // ourself.
+ pp::CompletionCallbackFactory<Instance> loader_factory_;
+ pp::URLLoader embed_loader_;
+ pp::URLLoader embed_preview_loader_;
+
+ scoped_ptr<pp::Scrollbar_Dev> h_scrollbar_;
+ scoped_ptr<pp::Scrollbar_Dev> v_scrollbar_;
+ int32 valid_v_range_;
+
+ PP_CursorType_Dev cursor_; // The current cursor.
+
+ // Used when selecting and dragging beyond the visible portion, in which case
+ // we want to scroll the document.
+ bool timer_pending_;
+ pp::MouseInputEvent last_mouse_event_;
+ pp::CompletionCallbackFactory<Instance> timer_factory_;
+ uint32 current_timer_id_;
+
+ // Size, in pixels, of plugin rectangle.
+ pp::Size plugin_size_;
+ // Size, in DIPs, of plugin rectangle.
+ pp::Size plugin_dip_size_;
+ // Remaining area, in pixels, to render the pdf in after accounting for
+ // scrollbars/toolbars and horizontal centering.
+ pp::Rect available_area_;
+ // Size of entire document in pixels (i.e. if each page is 800 pixels high and
+ // there are 10 pages, the height will be 8000).
+ pp::Size document_size_;
+
+ double zoom_; // Current zoom factor.
+
+ float device_scale_; // Current device scale factor.
+ bool printing_enabled_;
+ bool hidpi_enabled_;
+ // True if the plugin is full-page.
+ bool full_;
+ // Zooming mode (none, fit to width, fit to height)
+ ZoomMode zoom_mode_;
+
+ // If true, this means we told the RenderView that we're starting a network
+ // request so that it can start the throbber. We will tell it again once the
+ // document finishes loading.
+ bool did_call_start_loading_;
+
+ // Hold off on painting invalidated requests while this flag is true.
+ bool dont_paint_;
+
+ // Indicates if plugin is in autoscroll mode.
+ bool is_autoscroll_;
+ // Rect for autoscroll anchor.
+ pp::Rect autoscroll_rect_;
+ // Image of the autoscroll anchor and its background.
+ pp::ImageData autoscroll_anchor_;
+ // Autoscrolling deltas in pixels.
+ int autoscroll_x_;
+ int autoscroll_y_;
+
+ // Thickness of a scrollbar.
+ int scrollbar_thickness_;
+
+ // Reserved thickness of a scrollbar. This is how much space the scrollbar
+ // takes from the available area. 0 for overlay.
+ int scrollbar_reserved_thickness_;
+
+ // Used to remember which toolbar is in use
+ const ToolbarButtonInfo* current_tb_info_;
+ size_t current_tb_info_size_;
+
+ PaintManager paint_manager_;
+
+ struct BackgroundPart {
+ pp::Rect location;
+ uint32 color;
+ };
+ std::vector<BackgroundPart> background_parts_;
+
+ struct PrintSettings {
+ PrintSettings() {
+ Clear();
+ }
+ void Clear() {
+ is_printing = false;
+ print_pages_called_ = false;
+ memset(&pepper_print_settings, 0, sizeof(pepper_print_settings));
+ }
+ // This is set to true when PrintBegin is called and false when PrintEnd is
+ // called.
+ bool is_printing;
+ // To know whether this was an actual print operation, so we don't double
+ // count UMA logging.
+ bool print_pages_called_;
+ PP_PrintSettings_Dev pepper_print_settings;
+ };
+
+ PrintSettings print_settings_;
+
+ scoped_ptr<PDFEngine> engine_;
+
+ // This engine is used to render the individual preview page data. This is
+ // used only in print preview mode. This will use |PreviewModeClient|
+ // interface which has very limited access to the pp::Instance.
+ scoped_ptr<PDFEngine> preview_engine_;
+
+ std::string url_;
+
+ scoped_ptr<FadingControls> toolbar_;
+ ThumbnailControl thumbnails_;
+ ProgressControl progress_bar_;
+ uint32 delayed_progress_timer_id_;
+ PageIndicator page_indicator_;
+
+ // Used for creating images from numbers.
+ scoped_ptr<NumberImageGenerator> number_image_generator_;
+
+ // Used for submitting forms.
+ pp::CompletionCallbackFactory<Instance> form_factory_;
+ pp::URLLoader form_loader_;
+
+ // Used for generating callbacks.
+ // TODO(raymes): We don't really need other callback factories we can just
+ // fold them into this one.
+ pp::CompletionCallbackFactory<Instance> callback_factory_;
+
+ // True if we haven't painted the plugin viewport yet.
+ bool first_paint_;
+
+ // True when we've painted at least one page from the document.
+ bool painted_first_page_;
+
+ // True if we should display page indicator, false otherwise
+ bool show_page_indicator_;
+
+ // Callback when the document load completes.
+ pp::Var on_load_callback_;
+ pp::Var on_scroll_callback_;
+ pp::Var on_plugin_size_changed_callback_;
+
+ DocumentLoadState document_load_state_;
+ DocumentLoadState preview_document_load_state_;
+
+ // JavaScript interface to control this instance.
+ // This wraps a PDFScriptableObject in a pp::Var.
+ pp::VarPrivate instance_object_;
+
+ // Used so that we only tell the browser once about an unsupported feature, to
+ // avoid the infobar going up more than once.
+ bool told_browser_about_unsupported_feature_;
+
+ // Keeps track of which unsupported features we reported, so we avoid spamming
+ // the stats if a feature shows up many times per document.
+ std::set<std::string> unsupported_features_reported_;
+
+ // Number of pages in print preview mode, 0 if not in print preview mode.
+ int print_preview_page_count_;
+ std::vector<int> print_preview_page_numbers_;
+
+ // Used to manage loaded print preview page information. A |PreviewPageInfo|
+ // consists of data source url string and the page index in the destination
+ // document.
+ typedef std::pair<std::string, int> PreviewPageInfo;
+ std::queue<PreviewPageInfo> preview_pages_info_;
+
+ // Used to signal the browser about focus changes to trigger the OSK.
+ // TODO(abodenha@chromium.org) Implement full IME support in the plugin.
+ // http://crbug.com/132565
+ scoped_ptr<pp::TextInput_Dev> text_input_;
+};
+
+// This implements the JavaScript class entrypoint for the plugin instance.
+// This class is just a thin wrapper. It delegates relevant methods to Instance.
+class PDFScriptableObject : public pp::deprecated::ScriptableObject {
+ public:
+ explicit PDFScriptableObject(Instance* instance);
+ virtual ~PDFScriptableObject();
+
+ // pp::deprecated::ScriptableObject implementation.
+ virtual bool HasMethod(const pp::Var& method, pp::Var* exception);
+ virtual pp::Var Call(const pp::Var& method,
+ const std::vector<pp::Var>& args,
+ pp::Var* exception);
+
+ private:
+ Instance* instance_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_INSTANCE_H_
diff --git a/xfa_test/pdf/number_image_generator.cc b/xfa_test/pdf/number_image_generator.cc
new file mode 100644
index 0000000000..289691513c
--- /dev/null
+++ b/xfa_test/pdf/number_image_generator.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/number_image_generator.h"
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "pdf/draw_utils.h"
+#include "pdf/instance.h"
+
+namespace chrome_pdf {
+
+const int kPageNumberSeparator = 0;
+const int kPageNumberOriginX = 8;
+const int kPageNumberOriginY = 4;
+
+NumberImageGenerator::NumberImageGenerator(Instance* instance)
+ : instance_(instance),
+ device_scale_(1.0f) {
+}
+
+NumberImageGenerator::~NumberImageGenerator() {
+}
+
+void NumberImageGenerator::Configure(const pp::ImageData& number_background,
+ const std::vector<pp::ImageData>& number_images, float device_scale) {
+ number_background_ = number_background;
+ number_images_ = number_images;
+ device_scale_ = device_scale;
+}
+
+void NumberImageGenerator::GenerateImage(
+ int page_number, pp::ImageData* image) {
+ char buffer[12];
+ base::snprintf(buffer, sizeof(buffer), "%u", page_number);
+ int extra_width = 0;
+ DCHECK(number_images_.size() >= 10);
+ DCHECK(!number_background_.is_null());
+ for (size_t i = 1; i < strlen(buffer); ++i) {
+ int index = buffer[i] - '0';
+ extra_width += number_images_[index].size().width();
+ extra_width += static_cast<int>(kPageNumberSeparator * device_scale_);
+ }
+
+ *image = pp::ImageData(
+ instance_,
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ pp::Size(number_background_.size().width() + extra_width,
+ number_background_.size().height()),
+ false);
+
+ int stretch_point = number_background_.size().width() / 2;
+
+ pp::Rect src_rc(0, 0, stretch_point, number_background_.size().height());
+ pp::Rect dest_rc(src_rc);
+ CopyImage(number_background_, src_rc, image, dest_rc, false);
+ src_rc.Offset(number_background_.size().width() - stretch_point, 0);
+ dest_rc.Offset(image->size().width() - stretch_point, 0);
+ CopyImage(number_background_, src_rc, image, dest_rc, false);
+ src_rc = pp::Rect(stretch_point, 0, 1, number_background_.size().height());
+ dest_rc = src_rc;
+ dest_rc.set_width(extra_width + 1);
+ CopyImage(number_background_, src_rc, image, dest_rc, true);
+
+ pp::Point origin(static_cast<int>(kPageNumberOriginX * device_scale_),
+ static_cast<int>(kPageNumberOriginY * device_scale_));
+ for (size_t i = 0; i < strlen(buffer); ++i) {
+ int index = buffer[i] - '0';
+ CopyImage(
+ number_images_[index],
+ pp::Rect(pp::Point(), number_images_[index].size()),
+ image, pp::Rect(origin, number_images_[index].size()), false);
+ origin += pp::Point(
+ number_images_[index].size().width() +
+ static_cast<int>(kPageNumberSeparator * device_scale_), 0);
+ }
+}
+
+} // namespace chrome_pdf
+
diff --git a/xfa_test/pdf/number_image_generator.h b/xfa_test/pdf/number_image_generator.h
new file mode 100644
index 0000000000..51ffd3ec3d
--- /dev/null
+++ b/xfa_test/pdf/number_image_generator.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_NUMBER_IMAGE_GENERATOR_H
+#define PDF_NUMBER_IMAGE_GENERATOR_H
+
+#include <vector>
+
+#include "ppapi/cpp/image_data.h"
+
+namespace chrome_pdf {
+
+class Instance;
+
+class NumberImageGenerator {
+ public:
+ explicit NumberImageGenerator(Instance* instance);
+ virtual ~NumberImageGenerator();
+
+ void Configure(const pp::ImageData& number_background,
+ const std::vector<pp::ImageData>& number_images,
+ float device_scale);
+
+ void GenerateImage(int page_number, pp::ImageData* image);
+
+ private:
+ Instance* instance_;
+ pp::ImageData number_background_;
+ std::vector<pp::ImageData> number_images_;
+ float device_scale_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_NUMBER_IMAGE_GENERATOR_H
+
diff --git a/xfa_test/pdf/out_of_process_instance.cc b/xfa_test/pdf/out_of_process_instance.cc
new file mode 100644
index 0000000000..d627dc2d79
--- /dev/null
+++ b/xfa_test/pdf/out_of_process_instance.cc
@@ -0,0 +1,1369 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/out_of_process_instance.h"
+
+#include <algorithm> // for min/max()
+#define _USE_MATH_DEFINES // for M_PI
+#include <cmath> // for log() and pow()
+#include <math.h>
+#include <list>
+
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
+#include "base/values.h"
+#include "chrome/common/content_restriction.h"
+#include "net/base/escape.h"
+#include "pdf/pdf.h"
+#include "ppapi/c/dev/ppb_cursor_control_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_rect.h"
+#include "ppapi/c/private/ppb_instance_private.h"
+#include "ppapi/c/private/ppp_pdf.h"
+#include "ppapi/c/trusted/ppb_url_loader_trusted.h"
+#include "ppapi/cpp/core.h"
+#include "ppapi/cpp/dev/memory_dev.h"
+#include "ppapi/cpp/dev/text_input_dev.h"
+#include "ppapi/cpp/dev/url_util_dev.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/private/pdf.h"
+#include "ppapi/cpp/private/var_private.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/resource.h"
+#include "ppapi/cpp/url_request_info.h"
+#include "ppapi/cpp/var_array.h"
+#include "ppapi/cpp/var_dictionary.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+#if defined(OS_MACOSX)
+#include "base/mac/mac_util.h"
+#endif
+
+namespace chrome_pdf {
+
+const char kChromePrint[] = "chrome://print/";
+const char kChromeExtension[] =
+ "chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai";
+
+// Dictionary Value key names for the document accessibility info
+const char kAccessibleNumberOfPages[] = "numberOfPages";
+const char kAccessibleLoaded[] = "loaded";
+const char kAccessibleCopyable[] = "copyable";
+
+// Constants used in handling postMessage() messages.
+const char kType[] = "type";
+// Viewport message arguments. (Page -> Plugin).
+const char kJSViewportType[] = "viewport";
+const char kJSXOffset[] = "xOffset";
+const char kJSYOffset[] = "yOffset";
+const char kJSZoom[] = "zoom";
+// Stop scrolling message (Page -> Plugin)
+const char kJSStopScrollingType[] = "stopScrolling";
+// Document dimension arguments (Plugin -> Page).
+const char kJSDocumentDimensionsType[] = "documentDimensions";
+const char kJSDocumentWidth[] = "width";
+const char kJSDocumentHeight[] = "height";
+const char kJSPageDimensions[] = "pageDimensions";
+const char kJSPageX[] = "x";
+const char kJSPageY[] = "y";
+const char kJSPageWidth[] = "width";
+const char kJSPageHeight[] = "height";
+// Document load progress arguments (Plugin -> Page)
+const char kJSLoadProgressType[] = "loadProgress";
+const char kJSProgressPercentage[] = "progress";
+// Get password arguments (Plugin -> Page)
+const char kJSGetPasswordType[] = "getPassword";
+// Get password complete arguments (Page -> Plugin)
+const char kJSGetPasswordCompleteType[] = "getPasswordComplete";
+const char kJSPassword[] = "password";
+// Print (Page -> Plugin)
+const char kJSPrintType[] = "print";
+// Go to page (Plugin -> Page)
+const char kJSGoToPageType[] = "goToPage";
+const char kJSPageNumber[] = "page";
+// Reset print preview mode (Page -> Plugin)
+const char kJSResetPrintPreviewModeType[] = "resetPrintPreviewMode";
+const char kJSPrintPreviewUrl[] = "url";
+const char kJSPrintPreviewGrayscale[] = "grayscale";
+const char kJSPrintPreviewPageCount[] = "pageCount";
+// Load preview page (Page -> Plugin)
+const char kJSLoadPreviewPageType[] = "loadPreviewPage";
+const char kJSPreviewPageUrl[] = "url";
+const char kJSPreviewPageIndex[] = "index";
+// Set scroll position (Plugin -> Page)
+const char kJSSetScrollPositionType[] = "setScrollPosition";
+const char kJSPositionX[] = "x";
+const char kJSPositionY[] = "y";
+// Set translated strings (Plugin -> Page)
+const char kJSSetTranslatedStringsType[] = "setTranslatedStrings";
+const char kJSGetPasswordString[] = "getPasswordString";
+const char kJSLoadingString[] = "loadingString";
+const char kJSLoadFailedString[] = "loadFailedString";
+// Request accessibility JSON data (Page -> Plugin)
+const char kJSGetAccessibilityJSONType[] = "getAccessibilityJSON";
+const char kJSAccessibilityPageNumber[] = "page";
+// Reply with accessibility JSON data (Plugin -> Page)
+const char kJSGetAccessibilityJSONReplyType[] = "getAccessibilityJSONReply";
+const char kJSAccessibilityJSON[] = "json";
+// Cancel the stream URL request (Plugin -> Page)
+const char kJSCancelStreamUrlType[] = "cancelStreamUrl";
+// Navigate to the given URL (Plugin -> Page)
+const char kJSNavigateType[] = "navigate";
+const char kJSNavigateUrl[] = "url";
+const char kJSNavigateNewTab[] = "newTab";
+// Open the email editor with the given parameters (Plugin -> Page)
+const char kJSEmailType[] = "email";
+const char kJSEmailTo[] = "to";
+const char kJSEmailCc[] = "cc";
+const char kJSEmailBcc[] = "bcc";
+const char kJSEmailSubject[] = "subject";
+const char kJSEmailBody[] = "body";
+// Rotation (Page -> Plugin)
+const char kJSRotateClockwiseType[] = "rotateClockwise";
+const char kJSRotateCounterclockwiseType[] = "rotateCounterclockwise";
+// Select all text in the document (Page -> Plugin)
+const char kJSSelectAllType[] = "selectAll";
+
+const int kFindResultCooldownMs = 100;
+
+const double kMinZoom = 0.01;
+
+namespace {
+
+static const char kPPPPdfInterface[] = PPP_PDF_INTERFACE_1;
+
+PP_Var GetLinkAtPosition(PP_Instance instance, PP_Point point) {
+ pp::Var var;
+ void* object = pp::Instance::GetPerInstanceObject(instance, kPPPPdfInterface);
+ if (object) {
+ var = static_cast<OutOfProcessInstance*>(object)->GetLinkAtPosition(
+ pp::Point(point));
+ }
+ return var.Detach();
+}
+
+void Transform(PP_Instance instance, PP_PrivatePageTransformType type) {
+ void* object =
+ pp::Instance::GetPerInstanceObject(instance, kPPPPdfInterface);
+ if (object) {
+ OutOfProcessInstance* obj_instance =
+ static_cast<OutOfProcessInstance*>(object);
+ switch (type) {
+ case PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CW:
+ obj_instance->RotateClockwise();
+ break;
+ case PP_PRIVATEPAGETRANSFORMTYPE_ROTATE_90_CCW:
+ obj_instance->RotateCounterclockwise();
+ break;
+ }
+ }
+}
+
+const PPP_Pdf ppp_private = {
+ &GetLinkAtPosition,
+ &Transform
+};
+
+int ExtractPrintPreviewPageIndex(const std::string& src_url) {
+ // Sample |src_url| format: chrome://print/id/page_index/print.pdf
+ std::vector<std::string> url_substr;
+ base::SplitString(src_url.substr(strlen(kChromePrint)), '/', &url_substr);
+ if (url_substr.size() != 3)
+ return -1;
+
+ if (url_substr[2] != "print.pdf")
+ return -1;
+
+ int page_index = 0;
+ if (!base::StringToInt(url_substr[1], &page_index))
+ return -1;
+ return page_index;
+}
+
+bool IsPrintPreviewUrl(const std::string& url) {
+ return url.substr(0, strlen(kChromePrint)) == kChromePrint;
+}
+
+void ScalePoint(float scale, pp::Point* point) {
+ point->set_x(static_cast<int>(point->x() * scale));
+ point->set_y(static_cast<int>(point->y() * scale));
+}
+
+void ScaleRect(float scale, pp::Rect* rect) {
+ int left = static_cast<int>(floorf(rect->x() * scale));
+ int top = static_cast<int>(floorf(rect->y() * scale));
+ int right = static_cast<int>(ceilf((rect->x() + rect->width()) * scale));
+ int bottom = static_cast<int>(ceilf((rect->y() + rect->height()) * scale));
+ rect->SetRect(left, top, right - left, bottom - top);
+}
+
+// TODO(raymes): Remove this dependency on VarPrivate/InstancePrivate. It's
+// needed right now to do a synchronous call to JavaScript, but we could easily
+// replace this with a custom PPB_PDF function.
+pp::Var ModalDialog(const pp::Instance* instance,
+ const std::string& type,
+ const std::string& message,
+ const std::string& default_answer) {
+ const PPB_Instance_Private* interface =
+ reinterpret_cast<const PPB_Instance_Private*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_INSTANCE_PRIVATE_INTERFACE));
+ pp::VarPrivate window(pp::PASS_REF,
+ interface->GetWindowObject(instance->pp_instance()));
+ if (default_answer.empty())
+ return window.Call(type, message);
+ else
+ return window.Call(type, message, default_answer);
+}
+
+} // namespace
+
+OutOfProcessInstance::OutOfProcessInstance(PP_Instance instance)
+ : pp::Instance(instance),
+ pp::Find_Private(this),
+ pp::Printing_Dev(this),
+ pp::Selection_Dev(this),
+ cursor_(PP_CURSORTYPE_POINTER),
+ zoom_(1.0),
+ device_scale_(1.0),
+ printing_enabled_(true),
+ full_(false),
+ paint_manager_(this, this, true),
+ first_paint_(true),
+ document_load_state_(LOAD_STATE_LOADING),
+ preview_document_load_state_(LOAD_STATE_COMPLETE),
+ uma_(this),
+ told_browser_about_unsupported_feature_(false),
+ print_preview_page_count_(0),
+ last_progress_sent_(0),
+ recently_sent_find_update_(false),
+ received_viewport_message_(false),
+ did_call_start_loading_(false),
+ stop_scrolling_(false) {
+ loader_factory_.Initialize(this);
+ timer_factory_.Initialize(this);
+ form_factory_.Initialize(this);
+ print_callback_factory_.Initialize(this);
+ engine_.reset(PDFEngine::Create(this));
+ pp::Module::Get()->AddPluginInterface(kPPPPdfInterface, &ppp_private);
+ AddPerInstanceObject(kPPPPdfInterface, this);
+
+ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
+ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_KEYBOARD);
+ RequestFilteringInputEvents(PP_INPUTEVENT_CLASS_TOUCH);
+}
+
+OutOfProcessInstance::~OutOfProcessInstance() {
+ RemovePerInstanceObject(kPPPPdfInterface, this);
+}
+
+bool OutOfProcessInstance::Init(uint32_t argc,
+ const char* argn[],
+ const char* argv[]) {
+ // Check if the PDF is being loaded in the PDF chrome extension. We only allow
+ // the plugin to be put into "full frame" mode when it is being loaded in the
+ // extension because this enables some features that we don't want pages
+ // abusing outside of the extension.
+ pp::Var document_url_var = pp::URLUtil_Dev::Get()->GetDocumentURL(this);
+ std::string document_url = document_url_var.is_string() ?
+ document_url_var.AsString() : std::string();
+ std::string extension_url = std::string(kChromeExtension);
+ bool in_extension =
+ !document_url.compare(0, extension_url.size(), extension_url);
+
+ if (in_extension) {
+ // Check if the plugin is full frame. This is passed in from JS.
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (strcmp(argn[i], "full-frame") == 0) {
+ full_ = true;
+ break;
+ }
+ }
+ }
+
+ // Only allow the plugin to handle find requests if it is full frame.
+ if (full_)
+ SetPluginToHandleFindRequests();
+
+ // Send translated strings to the extension where they will be displayed.
+ // TODO(raymes): It would be better to get these in the extension directly
+ // through an API but no such API currently exists.
+ pp::VarDictionary translated_strings;
+ translated_strings.Set(kType, kJSSetTranslatedStringsType);
+ translated_strings.Set(kJSGetPasswordString,
+ GetLocalizedString(PP_RESOURCESTRING_PDFGETPASSWORD));
+ translated_strings.Set(kJSLoadingString,
+ GetLocalizedString(PP_RESOURCESTRING_PDFLOADING));
+ translated_strings.Set(kJSLoadFailedString,
+ GetLocalizedString(PP_RESOURCESTRING_PDFLOAD_FAILED));
+ PostMessage(translated_strings);
+
+ text_input_.reset(new pp::TextInput_Dev(this));
+
+ const char* stream_url = NULL;
+ const char* original_url = NULL;
+ const char* headers = NULL;
+ for (uint32_t i = 0; i < argc; ++i) {
+ if (strcmp(argn[i], "src") == 0)
+ original_url = argv[i];
+ else if (strcmp(argn[i], "stream-url") == 0)
+ stream_url = argv[i];
+ else if (strcmp(argn[i], "headers") == 0)
+ headers = argv[i];
+ }
+
+ // TODO(raymes): This is a hack to ensure that if no headers are passed in
+ // then we get the right MIME type. When the in process plugin is removed we
+ // can fix the document loader properly and remove this hack.
+ if (!headers || strcmp(headers, "") == 0)
+ headers = "content-type: application/pdf";
+
+ if (!original_url)
+ return false;
+
+ if (!stream_url)
+ stream_url = original_url;
+
+ // If we're in print preview mode we don't need to load the document yet.
+ // A |kJSResetPrintPreviewModeType| message will be sent to the plugin letting
+ // it know the url to load. By not loading here we avoid loading the same
+ // document twice.
+ if (IsPrintPreviewUrl(original_url))
+ return true;
+
+ LoadUrl(stream_url);
+ url_ = original_url;
+ return engine_->New(original_url, headers);
+}
+
+void OutOfProcessInstance::HandleMessage(const pp::Var& message) {
+ pp::VarDictionary dict(message);
+ if (!dict.Get(kType).is_string()) {
+ NOTREACHED();
+ return;
+ }
+
+ std::string type = dict.Get(kType).AsString();
+
+ if (type == kJSViewportType &&
+ dict.Get(pp::Var(kJSXOffset)).is_int() &&
+ dict.Get(pp::Var(kJSYOffset)).is_int() &&
+ dict.Get(pp::Var(kJSZoom)).is_number()) {
+ received_viewport_message_ = true;
+ stop_scrolling_ = false;
+ double zoom = dict.Get(pp::Var(kJSZoom)).AsDouble();
+ pp::Point scroll_offset(dict.Get(pp::Var(kJSXOffset)).AsInt(),
+ dict.Get(pp::Var(kJSYOffset)).AsInt());
+
+ // Bound the input parameters.
+ zoom = std::max(kMinZoom, zoom);
+ SetZoom(zoom);
+ scroll_offset = BoundScrollOffsetToDocument(scroll_offset);
+ engine_->ScrolledToXPosition(scroll_offset.x() * device_scale_);
+ engine_->ScrolledToYPosition(scroll_offset.y() * device_scale_);
+ } else if (type == kJSGetPasswordCompleteType &&
+ dict.Get(pp::Var(kJSPassword)).is_string()) {
+ if (password_callback_) {
+ pp::CompletionCallbackWithOutput<pp::Var> callback = *password_callback_;
+ password_callback_.reset();
+ *callback.output() = dict.Get(pp::Var(kJSPassword)).pp_var();
+ callback.Run(PP_OK);
+ } else {
+ NOTREACHED();
+ }
+ } else if (type == kJSPrintType) {
+ Print();
+ } else if (type == kJSRotateClockwiseType) {
+ RotateClockwise();
+ } else if (type == kJSRotateCounterclockwiseType) {
+ RotateCounterclockwise();
+ } else if (type == kJSSelectAllType) {
+ engine_->SelectAll();
+ } else if (type == kJSResetPrintPreviewModeType &&
+ dict.Get(pp::Var(kJSPrintPreviewUrl)).is_string() &&
+ dict.Get(pp::Var(kJSPrintPreviewGrayscale)).is_bool() &&
+ dict.Get(pp::Var(kJSPrintPreviewPageCount)).is_int()) {
+ url_ = dict.Get(pp::Var(kJSPrintPreviewUrl)).AsString();
+ preview_pages_info_ = std::queue<PreviewPageInfo>();
+ preview_document_load_state_ = LOAD_STATE_COMPLETE;
+ document_load_state_ = LOAD_STATE_LOADING;
+ LoadUrl(url_);
+ preview_engine_.reset();
+ engine_.reset(PDFEngine::Create(this));
+ engine_->SetGrayscale(dict.Get(pp::Var(kJSPrintPreviewGrayscale)).AsBool());
+ engine_->New(url_.c_str());
+
+ print_preview_page_count_ =
+ std::max(dict.Get(pp::Var(kJSPrintPreviewPageCount)).AsInt(), 0);
+
+ paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
+ } else if (type == kJSLoadPreviewPageType &&
+ dict.Get(pp::Var(kJSPreviewPageUrl)).is_string() &&
+ dict.Get(pp::Var(kJSPreviewPageIndex)).is_int()) {
+ ProcessPreviewPageInfo(dict.Get(pp::Var(kJSPreviewPageUrl)).AsString(),
+ dict.Get(pp::Var(kJSPreviewPageIndex)).AsInt());
+ } else if (type == kJSGetAccessibilityJSONType) {
+ pp::VarDictionary reply;
+ reply.Set(pp::Var(kType), pp::Var(kJSGetAccessibilityJSONReplyType));
+ if (dict.Get(pp::Var(kJSAccessibilityPageNumber)).is_int()) {
+ int page = dict.Get(pp::Var(kJSAccessibilityPageNumber)).AsInt();
+ reply.Set(pp::Var(kJSAccessibilityJSON),
+ pp::Var(engine_->GetPageAsJSON(page)));
+ } else {
+ base::DictionaryValue node;
+ node.SetInteger(kAccessibleNumberOfPages, engine_->GetNumberOfPages());
+ node.SetBoolean(kAccessibleLoaded,
+ document_load_state_ != LOAD_STATE_LOADING);
+ bool has_permissions =
+ engine_->HasPermission(PDFEngine::PERMISSION_COPY) ||
+ engine_->HasPermission(PDFEngine::PERMISSION_COPY_ACCESSIBLE);
+ node.SetBoolean(kAccessibleCopyable, has_permissions);
+ std::string json;
+ base::JSONWriter::Write(&node, &json);
+ reply.Set(pp::Var(kJSAccessibilityJSON), pp::Var(json));
+ }
+ PostMessage(reply);
+ } else if (type == kJSStopScrollingType) {
+ stop_scrolling_ = true;
+ } else {
+ NOTREACHED();
+ }
+}
+
+bool OutOfProcessInstance::HandleInputEvent(
+ const pp::InputEvent& event) {
+ // To simplify things, convert the event into device coordinates if it is
+ // a mouse event.
+ pp::InputEvent event_device_res(event);
+ {
+ pp::MouseInputEvent mouse_event(event);
+ if (!mouse_event.is_null()) {
+ pp::Point point = mouse_event.GetPosition();
+ pp::Point movement = mouse_event.GetMovement();
+ ScalePoint(device_scale_, &point);
+ ScalePoint(device_scale_, &movement);
+ mouse_event = pp::MouseInputEvent(
+ this,
+ event.GetType(),
+ event.GetTimeStamp(),
+ event.GetModifiers(),
+ mouse_event.GetButton(),
+ point,
+ mouse_event.GetClickCount(),
+ movement);
+ event_device_res = mouse_event;
+ }
+ }
+
+ pp::InputEvent offset_event(event_device_res);
+ switch (offset_event.GetType()) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ case PP_INPUTEVENT_TYPE_MOUSEENTER:
+ case PP_INPUTEVENT_TYPE_MOUSELEAVE: {
+ pp::MouseInputEvent mouse_event(event_device_res);
+ pp::MouseInputEvent mouse_event_dip(event);
+ pp::Point point = mouse_event.GetPosition();
+ point.set_x(point.x() - available_area_.x());
+ offset_event = pp::MouseInputEvent(
+ this,
+ event.GetType(),
+ event.GetTimeStamp(),
+ event.GetModifiers(),
+ mouse_event.GetButton(),
+ point,
+ mouse_event.GetClickCount(),
+ mouse_event.GetMovement());
+ break;
+ }
+ default:
+ break;
+ }
+ if (engine_->HandleEvent(offset_event))
+ return true;
+
+ // TODO(raymes): Implement this scroll behavior in JS:
+ // When click+dragging, scroll the document correctly.
+
+ // Return true for unhandled clicks so the plugin takes focus.
+ return (event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN);
+}
+
+void OutOfProcessInstance::DidChangeView(const pp::View& view) {
+ pp::Rect view_rect(view.GetRect());
+ float old_device_scale = device_scale_;
+ float device_scale = view.GetDeviceScale();
+ pp::Size view_device_size(view_rect.width() * device_scale,
+ view_rect.height() * device_scale);
+
+ if (view_device_size != plugin_size_ || device_scale != device_scale_) {
+ device_scale_ = device_scale;
+ plugin_dip_size_ = view_rect.size();
+ plugin_size_ = view_device_size;
+
+ paint_manager_.SetSize(view_device_size, device_scale_);
+
+ pp::Size new_image_data_size = PaintManager::GetNewContextSize(
+ image_data_.size(),
+ plugin_size_);
+ if (new_image_data_size != image_data_.size()) {
+ image_data_ = pp::ImageData(this,
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ new_image_data_size,
+ false);
+ first_paint_ = true;
+ }
+
+ if (image_data_.is_null()) {
+ DCHECK(plugin_size_.IsEmpty());
+ return;
+ }
+
+ OnGeometryChanged(zoom_, old_device_scale);
+ }
+
+ if (!stop_scrolling_) {
+ pp::Point scroll_offset(
+ BoundScrollOffsetToDocument(view.GetScrollOffset()));
+ engine_->ScrolledToXPosition(scroll_offset.x() * device_scale_);
+ engine_->ScrolledToYPosition(scroll_offset.y() * device_scale_);
+ }
+}
+
+pp::Var OutOfProcessInstance::GetLinkAtPosition(
+ const pp::Point& point) {
+ pp::Point offset_point(point);
+ ScalePoint(device_scale_, &offset_point);
+ offset_point.set_x(offset_point.x() - available_area_.x());
+ return engine_->GetLinkAtPosition(offset_point);
+}
+
+pp::Var OutOfProcessInstance::GetSelectedText(bool html) {
+ if (html || !engine_->HasPermission(PDFEngine::PERMISSION_COPY))
+ return pp::Var();
+ return engine_->GetSelectedText();
+}
+
+uint32_t OutOfProcessInstance::QuerySupportedPrintOutputFormats() {
+ return engine_->QuerySupportedPrintOutputFormats();
+}
+
+int32_t OutOfProcessInstance::PrintBegin(
+ const PP_PrintSettings_Dev& print_settings) {
+ // For us num_pages is always equal to the number of pages in the PDF
+ // document irrespective of the printable area.
+ int32_t ret = engine_->GetNumberOfPages();
+ if (!ret)
+ return 0;
+
+ uint32_t supported_formats = engine_->QuerySupportedPrintOutputFormats();
+ if ((print_settings.format & supported_formats) == 0)
+ return 0;
+
+ print_settings_.is_printing = true;
+ print_settings_.pepper_print_settings = print_settings;
+ engine_->PrintBegin();
+ return ret;
+}
+
+pp::Resource OutOfProcessInstance::PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) {
+ if (!print_settings_.is_printing)
+ return pp::Resource();
+
+ print_settings_.print_pages_called_ = true;
+ return engine_->PrintPages(page_ranges, page_range_count,
+ print_settings_.pepper_print_settings);
+}
+
+void OutOfProcessInstance::PrintEnd() {
+ if (print_settings_.print_pages_called_)
+ UserMetricsRecordAction("PDF.PrintPage");
+ print_settings_.Clear();
+ engine_->PrintEnd();
+}
+
+bool OutOfProcessInstance::IsPrintScalingDisabled() {
+ return !engine_->GetPrintScaling();
+}
+
+bool OutOfProcessInstance::StartFind(const std::string& text,
+ bool case_sensitive) {
+ engine_->StartFind(text.c_str(), case_sensitive);
+ return true;
+}
+
+void OutOfProcessInstance::SelectFindResult(bool forward) {
+ engine_->SelectFindResult(forward);
+}
+
+void OutOfProcessInstance::StopFind() {
+ engine_->StopFind();
+ tickmarks_.clear();
+ SetTickmarks(tickmarks_);
+}
+
+void OutOfProcessInstance::OnPaint(
+ const std::vector<pp::Rect>& paint_rects,
+ std::vector<PaintManager::ReadyRect>* ready,
+ std::vector<pp::Rect>* pending) {
+ if (image_data_.is_null()) {
+ DCHECK(plugin_size_.IsEmpty());
+ return;
+ }
+ if (first_paint_) {
+ first_paint_ = false;
+ pp::Rect rect = pp::Rect(pp::Point(), image_data_.size());
+ FillRect(rect, kBackgroundColor);
+ ready->push_back(PaintManager::ReadyRect(rect, image_data_, true));
+ }
+
+ if (!received_viewport_message_)
+ return;
+
+ engine_->PrePaint();
+
+ for (size_t i = 0; i < paint_rects.size(); i++) {
+ // Intersect with plugin area since there could be pending invalidates from
+ // when the plugin area was larger.
+ pp::Rect rect =
+ paint_rects[i].Intersect(pp::Rect(pp::Point(), plugin_size_));
+ if (rect.IsEmpty())
+ continue;
+
+ pp::Rect pdf_rect = available_area_.Intersect(rect);
+ if (!pdf_rect.IsEmpty()) {
+ pdf_rect.Offset(available_area_.x() * -1, 0);
+
+ std::vector<pp::Rect> pdf_ready;
+ std::vector<pp::Rect> pdf_pending;
+ engine_->Paint(pdf_rect, &image_data_, &pdf_ready, &pdf_pending);
+ for (size_t j = 0; j < pdf_ready.size(); ++j) {
+ pdf_ready[j].Offset(available_area_.point());
+ ready->push_back(
+ PaintManager::ReadyRect(pdf_ready[j], image_data_, false));
+ }
+ for (size_t j = 0; j < pdf_pending.size(); ++j) {
+ pdf_pending[j].Offset(available_area_.point());
+ pending->push_back(pdf_pending[j]);
+ }
+ }
+
+ for (size_t j = 0; j < background_parts_.size(); ++j) {
+ pp::Rect intersection = background_parts_[j].location.Intersect(rect);
+ if (!intersection.IsEmpty()) {
+ FillRect(intersection, background_parts_[j].color);
+ ready->push_back(
+ PaintManager::ReadyRect(intersection, image_data_, false));
+ }
+ }
+ }
+
+ engine_->PostPaint();
+}
+
+void OutOfProcessInstance::DidOpen(int32_t result) {
+ if (result == PP_OK) {
+ if (!engine_->HandleDocumentLoad(embed_loader_)) {
+ document_load_state_ = LOAD_STATE_LOADING;
+ DocumentLoadFailed();
+ }
+ } else if (result != PP_ERROR_ABORTED) { // Can happen in tests.
+ NOTREACHED();
+ DocumentLoadFailed();
+ }
+
+ // If it's a progressive load, cancel the stream URL request so that requests
+ // can be made on the original URL.
+ // TODO(raymes): Make this clearer once the in-process plugin is deleted.
+ if (engine_->IsProgressiveLoad()) {
+ pp::VarDictionary message;
+ message.Set(kType, kJSCancelStreamUrlType);
+ PostMessage(message);
+ }
+}
+
+void OutOfProcessInstance::DidOpenPreview(int32_t result) {
+ if (result == PP_OK) {
+ preview_engine_.reset(PDFEngine::Create(new PreviewModeClient(this)));
+ preview_engine_->HandleDocumentLoad(embed_preview_loader_);
+ } else {
+ NOTREACHED();
+ }
+}
+
+void OutOfProcessInstance::OnClientTimerFired(int32_t id) {
+ engine_->OnCallback(id);
+}
+
+void OutOfProcessInstance::CalculateBackgroundParts() {
+ background_parts_.clear();
+ int left_width = available_area_.x();
+ int right_start = available_area_.right();
+ int right_width = abs(plugin_size_.width() - available_area_.right());
+ int bottom = std::min(available_area_.bottom(), plugin_size_.height());
+
+ // Add the left, right, and bottom rectangles. Note: we assume only
+ // horizontal centering.
+ BackgroundPart part = {
+ pp::Rect(0, 0, left_width, bottom),
+ kBackgroundColor
+ };
+ if (!part.location.IsEmpty())
+ background_parts_.push_back(part);
+ part.location = pp::Rect(right_start, 0, right_width, bottom);
+ if (!part.location.IsEmpty())
+ background_parts_.push_back(part);
+ part.location = pp::Rect(
+ 0, bottom, plugin_size_.width(), plugin_size_.height() - bottom);
+ if (!part.location.IsEmpty())
+ background_parts_.push_back(part);
+}
+
+int OutOfProcessInstance::GetDocumentPixelWidth() const {
+ return static_cast<int>(ceil(document_size_.width() * zoom_ * device_scale_));
+}
+
+int OutOfProcessInstance::GetDocumentPixelHeight() const {
+ return static_cast<int>(
+ ceil(document_size_.height() * zoom_ * device_scale_));
+}
+
+void OutOfProcessInstance::FillRect(const pp::Rect& rect, uint32 color) {
+ DCHECK(!image_data_.is_null() || rect.IsEmpty());
+ uint32* buffer_start = static_cast<uint32*>(image_data_.data());
+ int stride = image_data_.stride();
+ uint32* ptr = buffer_start + rect.y() * stride / 4 + rect.x();
+ int height = rect.height();
+ int width = rect.width();
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x)
+ *(ptr + x) = color;
+ ptr += stride /4;
+ }
+}
+
+void OutOfProcessInstance::DocumentSizeUpdated(const pp::Size& size) {
+ document_size_ = size;
+
+ pp::VarDictionary dimensions;
+ dimensions.Set(kType, kJSDocumentDimensionsType);
+ dimensions.Set(kJSDocumentWidth, pp::Var(document_size_.width()));
+ dimensions.Set(kJSDocumentHeight, pp::Var(document_size_.height()));
+ pp::VarArray page_dimensions_array;
+ int num_pages = engine_->GetNumberOfPages();
+ for (int i = 0; i < num_pages; ++i) {
+ pp::Rect page_rect = engine_->GetPageRect(i);
+ pp::VarDictionary page_dimensions;
+ page_dimensions.Set(kJSPageX, pp::Var(page_rect.x()));
+ page_dimensions.Set(kJSPageY, pp::Var(page_rect.y()));
+ page_dimensions.Set(kJSPageWidth, pp::Var(page_rect.width()));
+ page_dimensions.Set(kJSPageHeight, pp::Var(page_rect.height()));
+ page_dimensions_array.Set(i, page_dimensions);
+ }
+ dimensions.Set(kJSPageDimensions, page_dimensions_array);
+ PostMessage(dimensions);
+
+ OnGeometryChanged(zoom_, device_scale_);
+}
+
+void OutOfProcessInstance::Invalidate(const pp::Rect& rect) {
+ pp::Rect offset_rect(rect);
+ offset_rect.Offset(available_area_.point());
+ paint_manager_.InvalidateRect(offset_rect);
+}
+
+void OutOfProcessInstance::Scroll(const pp::Point& point) {
+ if (!image_data_.is_null())
+ paint_manager_.ScrollRect(available_area_, point);
+}
+
+void OutOfProcessInstance::ScrollToX(int x) {
+ pp::VarDictionary position;
+ position.Set(kType, kJSSetScrollPositionType);
+ position.Set(kJSPositionX, pp::Var(x / device_scale_));
+ PostMessage(position);
+}
+
+void OutOfProcessInstance::ScrollToY(int y) {
+ pp::VarDictionary position;
+ position.Set(kType, kJSSetScrollPositionType);
+ position.Set(kJSPositionY, pp::Var(y / device_scale_));
+ PostMessage(position);
+}
+
+void OutOfProcessInstance::ScrollToPage(int page) {
+ if (engine_->GetNumberOfPages() == 0)
+ return;
+
+ pp::VarDictionary message;
+ message.Set(kType, kJSGoToPageType);
+ message.Set(kJSPageNumber, pp::Var(page));
+ PostMessage(message);
+}
+
+void OutOfProcessInstance::NavigateTo(const std::string& url,
+ bool open_in_new_tab) {
+ std::string url_copy(url);
+
+ // Empty |url_copy| is ok, and will effectively be a reload.
+ // Skip the code below so an empty URL does not turn into "http://", which
+ // will cause GURL to fail a DCHECK.
+ if (!url_copy.empty()) {
+ // If |url_copy| starts with '#', then it's for the same URL with a
+ // different URL fragment.
+ if (url_copy[0] == '#') {
+ url_copy = url_ + url_copy;
+ }
+ // If there's no scheme, add http.
+ if (url_copy.find("://") == std::string::npos &&
+ url_copy.find("mailto:") == std::string::npos) {
+ url_copy = std::string("http://") + url_copy;
+ }
+ // Make sure |url_copy| starts with a valid scheme.
+ if (url_copy.find("http://") != 0 &&
+ url_copy.find("https://") != 0 &&
+ url_copy.find("ftp://") != 0 &&
+ url_copy.find("file://") != 0 &&
+ url_copy.find("mailto:") != 0) {
+ return;
+ }
+ // Make sure |url_copy| is not only a scheme.
+ if (url_copy == "http://" ||
+ url_copy == "https://" ||
+ url_copy == "ftp://" ||
+ url_copy == "file://" ||
+ url_copy == "mailto:") {
+ return;
+ }
+ }
+ pp::VarDictionary message;
+ message.Set(kType, kJSNavigateType);
+ message.Set(kJSNavigateUrl, url_copy);
+ message.Set(kJSNavigateNewTab, open_in_new_tab);
+ PostMessage(message);
+}
+
+void OutOfProcessInstance::UpdateCursor(PP_CursorType_Dev cursor) {
+ if (cursor == cursor_)
+ return;
+ cursor_ = cursor;
+
+ const PPB_CursorControl_Dev* cursor_interface =
+ reinterpret_cast<const PPB_CursorControl_Dev*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_CURSOR_CONTROL_DEV_INTERFACE));
+ if (!cursor_interface) {
+ NOTREACHED();
+ return;
+ }
+
+ cursor_interface->SetCursor(
+ pp_instance(), cursor_, pp::ImageData().pp_resource(), NULL);
+}
+
+void OutOfProcessInstance::UpdateTickMarks(
+ const std::vector<pp::Rect>& tickmarks) {
+ float inverse_scale = 1.0f / device_scale_;
+ std::vector<pp::Rect> scaled_tickmarks = tickmarks;
+ for (size_t i = 0; i < scaled_tickmarks.size(); i++)
+ ScaleRect(inverse_scale, &scaled_tickmarks[i]);
+ tickmarks_ = scaled_tickmarks;
+}
+
+void OutOfProcessInstance::NotifyNumberOfFindResultsChanged(int total,
+ bool final_result) {
+ // We don't want to spam the renderer with too many updates to the number of
+ // find results. Don't send an update if we sent one too recently. If it's the
+ // final update, we always send it though.
+ if (final_result) {
+ NumberOfFindResultsChanged(total, final_result);
+ SetTickmarks(tickmarks_);
+ return;
+ }
+
+ if (recently_sent_find_update_)
+ return;
+
+ NumberOfFindResultsChanged(total, final_result);
+ SetTickmarks(tickmarks_);
+ recently_sent_find_update_ = true;
+ pp::CompletionCallback callback =
+ timer_factory_.NewCallback(
+ &OutOfProcessInstance::ResetRecentlySentFindUpdate);
+ pp::Module::Get()->core()->CallOnMainThread(kFindResultCooldownMs,
+ callback, 0);
+}
+
+void OutOfProcessInstance::NotifySelectedFindResultChanged(
+ int current_find_index) {
+ SelectedFindResultChanged(current_find_index);
+}
+
+void OutOfProcessInstance::GetDocumentPassword(
+ pp::CompletionCallbackWithOutput<pp::Var> callback) {
+ if (password_callback_) {
+ NOTREACHED();
+ return;
+ }
+
+ password_callback_.reset(
+ new pp::CompletionCallbackWithOutput<pp::Var>(callback));
+ pp::VarDictionary message;
+ message.Set(pp::Var(kType), pp::Var(kJSGetPasswordType));
+ PostMessage(message);
+}
+
+void OutOfProcessInstance::Alert(const std::string& message) {
+ ModalDialog(this, "alert", message, std::string());
+}
+
+bool OutOfProcessInstance::Confirm(const std::string& message) {
+ pp::Var result = ModalDialog(this, "confirm", message, std::string());
+ return result.is_bool() ? result.AsBool() : false;
+}
+
+std::string OutOfProcessInstance::Prompt(const std::string& question,
+ const std::string& default_answer) {
+ pp::Var result = ModalDialog(this, "prompt", question, default_answer);
+ return result.is_string() ? result.AsString() : std::string();
+}
+
+std::string OutOfProcessInstance::GetURL() {
+ return url_;
+}
+
+void OutOfProcessInstance::Email(const std::string& to,
+ const std::string& cc,
+ const std::string& bcc,
+ const std::string& subject,
+ const std::string& body) {
+ pp::VarDictionary message;
+ message.Set(pp::Var(kType), pp::Var(kJSEmailType));
+ message.Set(pp::Var(kJSEmailTo),
+ pp::Var(net::EscapeUrlEncodedData(to, false)));
+ message.Set(pp::Var(kJSEmailCc),
+ pp::Var(net::EscapeUrlEncodedData(cc, false)));
+ message.Set(pp::Var(kJSEmailBcc),
+ pp::Var(net::EscapeUrlEncodedData(bcc, false)));
+ message.Set(pp::Var(kJSEmailSubject),
+ pp::Var(net::EscapeUrlEncodedData(subject, false)));
+ message.Set(pp::Var(kJSEmailBody),
+ pp::Var(net::EscapeUrlEncodedData(body, false)));
+ PostMessage(message);
+}
+
+void OutOfProcessInstance::Print() {
+ if (!printing_enabled_ ||
+ (!engine_->HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY) &&
+ !engine_->HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY))) {
+ return;
+ }
+
+ pp::CompletionCallback callback =
+ print_callback_factory_.NewCallback(&OutOfProcessInstance::OnPrint);
+ pp::Module::Get()->core()->CallOnMainThread(0, callback);
+}
+
+void OutOfProcessInstance::OnPrint(int32_t) {
+ pp::PDF::Print(this);
+}
+
+void OutOfProcessInstance::SubmitForm(const std::string& url,
+ const void* data,
+ int length) {
+ pp::URLRequestInfo request(this);
+ request.SetURL(url);
+ request.SetMethod("POST");
+ request.AppendDataToBody(reinterpret_cast<const char*>(data), length);
+
+ pp::CompletionCallback callback =
+ form_factory_.NewCallback(&OutOfProcessInstance::FormDidOpen);
+ form_loader_ = CreateURLLoaderInternal();
+ int rv = form_loader_.Open(request, callback);
+ if (rv != PP_OK_COMPLETIONPENDING)
+ callback.Run(rv);
+}
+
+void OutOfProcessInstance::FormDidOpen(int32_t result) {
+ // TODO: inform the user of success/failure.
+ if (result != PP_OK) {
+ NOTREACHED();
+ }
+}
+
+std::string OutOfProcessInstance::ShowFileSelectionDialog() {
+ // Seems like very low priority to implement, since the pdf has no way to get
+ // the file data anyways. Javascript doesn't let you do this synchronously.
+ NOTREACHED();
+ return std::string();
+}
+
+pp::URLLoader OutOfProcessInstance::CreateURLLoader() {
+ if (full_) {
+ if (!did_call_start_loading_) {
+ did_call_start_loading_ = true;
+ pp::PDF::DidStartLoading(this);
+ }
+
+ // Disable save and print until the document is fully loaded, since they
+ // would generate an incomplete document. Need to do this each time we
+ // call DidStartLoading since that resets the content restrictions.
+ pp::PDF::SetContentRestriction(this, CONTENT_RESTRICTION_SAVE |
+ CONTENT_RESTRICTION_PRINT);
+ }
+
+ return CreateURLLoaderInternal();
+}
+
+void OutOfProcessInstance::ScheduleCallback(int id, int delay_in_ms) {
+ pp::CompletionCallback callback =
+ timer_factory_.NewCallback(&OutOfProcessInstance::OnClientTimerFired);
+ pp::Module::Get()->core()->CallOnMainThread(delay_in_ms, callback, id);
+}
+
+void OutOfProcessInstance::SearchString(const base::char16* string,
+ const base::char16* term,
+ bool case_sensitive,
+ std::vector<SearchStringResult>* results) {
+ PP_PrivateFindResult* pp_results;
+ int count = 0;
+ pp::PDF::SearchString(
+ this,
+ reinterpret_cast<const unsigned short*>(string),
+ reinterpret_cast<const unsigned short*>(term),
+ case_sensitive,
+ &pp_results,
+ &count);
+
+ results->resize(count);
+ for (int i = 0; i < count; ++i) {
+ (*results)[i].start_index = pp_results[i].start_index;
+ (*results)[i].length = pp_results[i].length;
+ }
+
+ pp::Memory_Dev memory;
+ memory.MemFree(pp_results);
+}
+
+void OutOfProcessInstance::DocumentPaintOccurred() {
+}
+
+void OutOfProcessInstance::DocumentLoadComplete(int page_count) {
+ // Clear focus state for OSK.
+ FormTextFieldFocusChange(false);
+
+ DCHECK(document_load_state_ == LOAD_STATE_LOADING);
+ document_load_state_ = LOAD_STATE_COMPLETE;
+ UserMetricsRecordAction("PDF.LoadSuccess");
+
+ // Note: If we are in print preview mode the scroll location is retained
+ // across document loads so we don't want to scroll again and override it.
+ if (IsPrintPreview()) {
+ AppendBlankPrintPreviewPages();
+ OnGeometryChanged(0, 0);
+ }
+
+ pp::VarDictionary message;
+ message.Set(pp::Var(kType), pp::Var(kJSLoadProgressType));
+ message.Set(pp::Var(kJSProgressPercentage), pp::Var(100)) ;
+ PostMessage(message);
+
+ if (!full_)
+ return;
+
+ if (did_call_start_loading_) {
+ pp::PDF::DidStopLoading(this);
+ did_call_start_loading_ = false;
+ }
+
+ int content_restrictions =
+ CONTENT_RESTRICTION_CUT | CONTENT_RESTRICTION_PASTE;
+ if (!engine_->HasPermission(PDFEngine::PERMISSION_COPY))
+ content_restrictions |= CONTENT_RESTRICTION_COPY;
+
+ if (!engine_->HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY) &&
+ !engine_->HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY)) {
+ printing_enabled_ = false;
+ }
+
+ pp::PDF::SetContentRestriction(this, content_restrictions);
+
+ uma_.HistogramCustomCounts("PDF.PageCount", page_count,
+ 1, 1000000, 50);
+}
+
+void OutOfProcessInstance::RotateClockwise() {
+ engine_->RotateClockwise();
+}
+
+void OutOfProcessInstance::RotateCounterclockwise() {
+ engine_->RotateCounterclockwise();
+}
+
+void OutOfProcessInstance::PreviewDocumentLoadComplete() {
+ if (preview_document_load_state_ != LOAD_STATE_LOADING ||
+ preview_pages_info_.empty()) {
+ return;
+ }
+
+ preview_document_load_state_ = LOAD_STATE_COMPLETE;
+
+ int dest_page_index = preview_pages_info_.front().second;
+ int src_page_index =
+ ExtractPrintPreviewPageIndex(preview_pages_info_.front().first);
+ if (src_page_index > 0 && dest_page_index > -1 && preview_engine_.get())
+ engine_->AppendPage(preview_engine_.get(), dest_page_index);
+
+ preview_pages_info_.pop();
+ // |print_preview_page_count_| is not updated yet. Do not load any
+ // other preview pages till we get this information.
+ if (print_preview_page_count_ == 0)
+ return;
+
+ if (preview_pages_info_.size())
+ LoadAvailablePreviewPage();
+}
+
+void OutOfProcessInstance::DocumentLoadFailed() {
+ DCHECK(document_load_state_ == LOAD_STATE_LOADING);
+ UserMetricsRecordAction("PDF.LoadFailure");
+
+ if (did_call_start_loading_) {
+ pp::PDF::DidStopLoading(this);
+ did_call_start_loading_ = false;
+ }
+
+ document_load_state_ = LOAD_STATE_FAILED;
+ paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
+
+ // Send a progress value of -1 to indicate a failure.
+ pp::VarDictionary message;
+ message.Set(pp::Var(kType), pp::Var(kJSLoadProgressType));
+ message.Set(pp::Var(kJSProgressPercentage), pp::Var(-1)) ;
+ PostMessage(message);
+}
+
+void OutOfProcessInstance::PreviewDocumentLoadFailed() {
+ UserMetricsRecordAction("PDF.PreviewDocumentLoadFailure");
+ if (preview_document_load_state_ != LOAD_STATE_LOADING ||
+ preview_pages_info_.empty()) {
+ return;
+ }
+
+ preview_document_load_state_ = LOAD_STATE_FAILED;
+ preview_pages_info_.pop();
+
+ if (preview_pages_info_.size())
+ LoadAvailablePreviewPage();
+}
+
+pp::Instance* OutOfProcessInstance::GetPluginInstance() {
+ return this;
+}
+
+void OutOfProcessInstance::DocumentHasUnsupportedFeature(
+ const std::string& feature) {
+ std::string metric("PDF_Unsupported_");
+ metric += feature;
+ if (!unsupported_features_reported_.count(metric)) {
+ unsupported_features_reported_.insert(metric);
+ UserMetricsRecordAction(metric);
+ }
+
+ // Since we use an info bar, only do this for full frame plugins..
+ if (!full_)
+ return;
+
+ if (told_browser_about_unsupported_feature_)
+ return;
+ told_browser_about_unsupported_feature_ = true;
+
+ pp::PDF::HasUnsupportedFeature(this);
+}
+
+void OutOfProcessInstance::DocumentLoadProgress(uint32 available,
+ uint32 doc_size) {
+ double progress = 0.0;
+ if (doc_size == 0) {
+ // Document size is unknown. Use heuristics.
+ // We'll make progress logarithmic from 0 to 100M.
+ static const double kFactor = log(100000000.0) / 100.0;
+ if (available > 0) {
+ progress = log(static_cast<double>(available)) / kFactor;
+ if (progress > 100.0)
+ progress = 100.0;
+ }
+ } else {
+ progress = 100.0 * static_cast<double>(available) / doc_size;
+ }
+
+ // We send 100% load progress in DocumentLoadComplete.
+ if (progress >= 100)
+ return;
+
+ // Avoid sending too many progress messages over PostMessage.
+ if (progress > last_progress_sent_ + 1) {
+ last_progress_sent_ = progress;
+ pp::VarDictionary message;
+ message.Set(pp::Var(kType), pp::Var(kJSLoadProgressType));
+ message.Set(pp::Var(kJSProgressPercentage), pp::Var(progress)) ;
+ PostMessage(message);
+ }
+}
+
+void OutOfProcessInstance::FormTextFieldFocusChange(bool in_focus) {
+ if (!text_input_.get())
+ return;
+ if (in_focus)
+ text_input_->SetTextInputType(PP_TEXTINPUT_TYPE_DEV_TEXT);
+ else
+ text_input_->SetTextInputType(PP_TEXTINPUT_TYPE_DEV_NONE);
+}
+
+void OutOfProcessInstance::ResetRecentlySentFindUpdate(int32_t /* unused */) {
+ recently_sent_find_update_ = false;
+}
+
+void OutOfProcessInstance::OnGeometryChanged(double old_zoom,
+ float old_device_scale) {
+ if (zoom_ != old_zoom || device_scale_ != old_device_scale)
+ engine_->ZoomUpdated(zoom_ * device_scale_);
+
+ available_area_ = pp::Rect(plugin_size_);
+ int doc_width = GetDocumentPixelWidth();
+ if (doc_width < available_area_.width()) {
+ available_area_.Offset((available_area_.width() - doc_width) / 2, 0);
+ available_area_.set_width(doc_width);
+ }
+ int doc_height = GetDocumentPixelHeight();
+ if (doc_height < available_area_.height()) {
+ available_area_.set_height(doc_height);
+ }
+
+ CalculateBackgroundParts();
+ engine_->PageOffsetUpdated(available_area_.point());
+ engine_->PluginSizeUpdated(available_area_.size());
+
+ if (!document_size_.GetArea())
+ return;
+ paint_manager_.InvalidateRect(pp::Rect(pp::Point(), plugin_size_));
+}
+
+void OutOfProcessInstance::LoadUrl(const std::string& url) {
+ LoadUrlInternal(url, &embed_loader_, &OutOfProcessInstance::DidOpen);
+}
+
+void OutOfProcessInstance::LoadPreviewUrl(const std::string& url) {
+ LoadUrlInternal(url, &embed_preview_loader_,
+ &OutOfProcessInstance::DidOpenPreview);
+}
+
+void OutOfProcessInstance::LoadUrlInternal(
+ const std::string& url,
+ pp::URLLoader* loader,
+ void (OutOfProcessInstance::* method)(int32_t)) {
+ pp::URLRequestInfo request(this);
+ request.SetURL(url);
+ request.SetMethod("GET");
+
+ *loader = CreateURLLoaderInternal();
+ pp::CompletionCallback callback = loader_factory_.NewCallback(method);
+ int rv = loader->Open(request, callback);
+ if (rv != PP_OK_COMPLETIONPENDING)
+ callback.Run(rv);
+}
+
+pp::URLLoader OutOfProcessInstance::CreateURLLoaderInternal() {
+ pp::URLLoader loader(this);
+
+ const PPB_URLLoaderTrusted* trusted_interface =
+ reinterpret_cast<const PPB_URLLoaderTrusted*>(
+ pp::Module::Get()->GetBrowserInterface(
+ PPB_URLLOADERTRUSTED_INTERFACE));
+ if (trusted_interface)
+ trusted_interface->GrantUniversalAccess(loader.pp_resource());
+ return loader;
+}
+
+void OutOfProcessInstance::SetZoom(double scale) {
+ double old_zoom = zoom_;
+ zoom_ = scale;
+ OnGeometryChanged(old_zoom, device_scale_);
+}
+
+std::string OutOfProcessInstance::GetLocalizedString(PP_ResourceString id) {
+ pp::Var rv(pp::PDF::GetLocalizedString(this, id));
+ if (!rv.is_string())
+ return std::string();
+
+ return rv.AsString();
+}
+
+void OutOfProcessInstance::AppendBlankPrintPreviewPages() {
+ if (print_preview_page_count_ == 0)
+ return;
+ engine_->AppendBlankPages(print_preview_page_count_);
+ if (preview_pages_info_.size() > 0)
+ LoadAvailablePreviewPage();
+}
+
+bool OutOfProcessInstance::IsPrintPreview() {
+ return IsPrintPreviewUrl(url_);
+}
+
+void OutOfProcessInstance::ProcessPreviewPageInfo(const std::string& url,
+ int dst_page_index) {
+ if (!IsPrintPreview())
+ return;
+
+ int src_page_index = ExtractPrintPreviewPageIndex(url);
+ if (src_page_index < 1)
+ return;
+
+ preview_pages_info_.push(std::make_pair(url, dst_page_index));
+ LoadAvailablePreviewPage();
+}
+
+void OutOfProcessInstance::LoadAvailablePreviewPage() {
+ if (preview_pages_info_.size() <= 0 ||
+ document_load_state_ != LOAD_STATE_COMPLETE) {
+ return;
+ }
+
+ std::string url = preview_pages_info_.front().first;
+ int dst_page_index = preview_pages_info_.front().second;
+ int src_page_index = ExtractPrintPreviewPageIndex(url);
+ if (src_page_index < 1 ||
+ dst_page_index >= print_preview_page_count_ ||
+ preview_document_load_state_ == LOAD_STATE_LOADING) {
+ return;
+ }
+
+ preview_document_load_state_ = LOAD_STATE_LOADING;
+ LoadPreviewUrl(url);
+}
+
+void OutOfProcessInstance::UserMetricsRecordAction(
+ const std::string& action) {
+ // TODO(raymes): Move this function to PPB_UMA_Private.
+ pp::PDF::UserMetricsRecordAction(this, pp::Var(action));
+}
+
+pp::Point OutOfProcessInstance::BoundScrollOffsetToDocument(
+ const pp::Point& scroll_offset) {
+ int max_x = document_size_.width() * zoom_ - plugin_dip_size_.width();
+ int x = std::max(std::min(scroll_offset.x(), max_x), 0);
+ int max_y = document_size_.height() * zoom_ - plugin_dip_size_.height();
+ int y = std::max(std::min(scroll_offset.y(), max_y), 0);
+ return pp::Point(x, y);
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/out_of_process_instance.h b/xfa_test/pdf/out_of_process_instance.h
new file mode 100644
index 0000000000..355f050dc3
--- /dev/null
+++ b/xfa_test/pdf/out_of_process_instance.h
@@ -0,0 +1,345 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_OUT_OF_PROCESS_INSTANCE_H_
+#define PDF_OUT_OF_PROCESS_INSTANCE_H_
+
+#include <queue>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "pdf/paint_manager.h"
+#include "pdf/pdf_engine.h"
+#include "pdf/preview_mode_client.h"
+
+#include "ppapi/c/private/ppb_pdf.h"
+#include "ppapi/cpp/dev/printing_dev.h"
+#include "ppapi/cpp/dev/scriptable_object_deprecated.h"
+#include "ppapi/cpp/dev/selection_dev.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/input_event.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/private/find_private.h"
+#include "ppapi/cpp/private/uma_private.h"
+#include "ppapi/cpp/url_loader.h"
+#include "ppapi/utility/completion_callback_factory.h"
+
+namespace pp {
+class TextInput_Dev;
+}
+
+namespace chrome_pdf {
+
+class OutOfProcessInstance : public pp::Instance,
+ public pp::Find_Private,
+ public pp::Printing_Dev,
+ public pp::Selection_Dev,
+ public PaintManager::Client,
+ public PDFEngine::Client,
+ public PreviewModeClient::Client {
+ public:
+ explicit OutOfProcessInstance(PP_Instance instance);
+ virtual ~OutOfProcessInstance();
+
+ // pp::Instance implementation.
+ virtual bool Init(uint32_t argc,
+ const char* argn[],
+ const char* argv[]) override;
+ virtual void HandleMessage(const pp::Var& message) override;
+ virtual bool HandleInputEvent(const pp::InputEvent& event) override;
+ virtual void DidChangeView(const pp::View& view) override;
+
+ // pp::Find_Private implementation.
+ virtual bool StartFind(const std::string& text, bool case_sensitive) override;
+ virtual void SelectFindResult(bool forward) override;
+ virtual void StopFind() override;
+
+ // pp::PaintManager::Client implementation.
+ virtual void OnPaint(const std::vector<pp::Rect>& paint_rects,
+ std::vector<PaintManager::ReadyRect>* ready,
+ std::vector<pp::Rect>* pending) override;
+
+ // pp::Printing_Dev implementation.
+ virtual uint32_t QuerySupportedPrintOutputFormats() override;
+ virtual int32_t PrintBegin(
+ const PP_PrintSettings_Dev& print_settings) override;
+ virtual pp::Resource PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) override;
+ virtual void PrintEnd() override;
+ virtual bool IsPrintScalingDisabled() override;
+
+ // pp::Private implementation.
+ virtual pp::Var GetLinkAtPosition(const pp::Point& point);
+
+ // PPP_Selection_Dev implementation.
+ virtual pp::Var GetSelectedText(bool html) override;
+
+ void FlushCallback(int32_t result);
+ void DidOpen(int32_t result);
+ void DidOpenPreview(int32_t result);
+
+ // Called when the timer is fired.
+ void OnClientTimerFired(int32_t id);
+
+ // Called to print without re-entrancy issues.
+ void OnPrint(int32_t);
+
+ // PDFEngine::Client implementation.
+ virtual void DocumentSizeUpdated(const pp::Size& size);
+ virtual void Invalidate(const pp::Rect& rect);
+ virtual void Scroll(const pp::Point& point);
+ virtual void ScrollToX(int position);
+ virtual void ScrollToY(int position);
+ virtual void ScrollToPage(int page);
+ virtual void NavigateTo(const std::string& url, bool open_in_new_tab);
+ virtual void UpdateCursor(PP_CursorType_Dev cursor);
+ virtual void UpdateTickMarks(const std::vector<pp::Rect>& tickmarks);
+ virtual void NotifyNumberOfFindResultsChanged(int total, bool final_result);
+ virtual void NotifySelectedFindResultChanged(int current_find_index);
+ virtual void GetDocumentPassword(
+ pp::CompletionCallbackWithOutput<pp::Var> callback);
+ virtual void Alert(const std::string& message);
+ virtual bool Confirm(const std::string& message);
+ virtual std::string Prompt(const std::string& question,
+ const std::string& default_answer);
+ virtual std::string GetURL();
+ virtual void Email(const std::string& to,
+ const std::string& cc,
+ const std::string& bcc,
+ const std::string& subject,
+ const std::string& body);
+ virtual void Print();
+ virtual void SubmitForm(const std::string& url,
+ const void* data,
+ int length);
+ virtual std::string ShowFileSelectionDialog();
+ virtual pp::URLLoader CreateURLLoader();
+ virtual void ScheduleCallback(int id, int delay_in_ms);
+ virtual void SearchString(const base::char16* string,
+ const base::char16* term,
+ bool case_sensitive,
+ std::vector<SearchStringResult>* results);
+ virtual void DocumentPaintOccurred();
+ virtual void DocumentLoadComplete(int page_count);
+ virtual void DocumentLoadFailed();
+ virtual pp::Instance* GetPluginInstance();
+ virtual void DocumentHasUnsupportedFeature(const std::string& feature);
+ virtual void DocumentLoadProgress(uint32 available, uint32 doc_size);
+ virtual void FormTextFieldFocusChange(bool in_focus);
+ virtual bool IsPrintPreview();
+
+ // PreviewModeClient::Client implementation.
+ virtual void PreviewDocumentLoadComplete() override;
+ virtual void PreviewDocumentLoadFailed() override;
+
+ // Helper functions for implementing PPP_PDF.
+ void RotateClockwise();
+ void RotateCounterclockwise();
+
+ private:
+ void ResetRecentlySentFindUpdate(int32_t);
+
+ // Called whenever the plugin geometry changes to update the location of the
+ // background parts, and notifies the pdf engine.
+ void OnGeometryChanged(double old_zoom, float old_device_scale);
+
+ // Figures out the location of any background rectangles (i.e. those that
+ // aren't painted by the PDF engine).
+ void CalculateBackgroundParts();
+
+ // Computes document width/height in device pixels, based on current zoom and
+ // device scale
+ int GetDocumentPixelWidth() const;
+ int GetDocumentPixelHeight() const;
+
+ // Draws a rectangle with the specified dimensions and color in our buffer.
+ void FillRect(const pp::Rect& rect, uint32 color);
+
+ void LoadUrl(const std::string& url);
+ void LoadPreviewUrl(const std::string& url);
+ void LoadUrlInternal(const std::string& url, pp::URLLoader* loader,
+ void (OutOfProcessInstance::* method)(int32_t));
+
+ // Creates a URL loader and allows it to access all urls, i.e. not just the
+ // frame's origin.
+ pp::URLLoader CreateURLLoaderInternal();
+
+ // Figure out the initial page to display based on #page=N and #nameddest=foo
+ // in the |url_|.
+ // Returns -1 if there is no valid fragment. The returned value is 0-based,
+ // whereas page=N is 1-based.
+ int GetInitialPage(const std::string& url);
+
+ void FormDidOpen(int32_t result);
+
+ std::string GetLocalizedString(PP_ResourceString id);
+
+ void UserMetricsRecordAction(const std::string& action);
+
+ enum DocumentLoadState {
+ LOAD_STATE_LOADING,
+ LOAD_STATE_COMPLETE,
+ LOAD_STATE_FAILED,
+ };
+
+ // Set new zoom scale.
+ void SetZoom(double scale);
+
+ // Reduces the document to 1 page and appends |print_preview_page_count_|
+ // blank pages to the document for print preview.
+ void AppendBlankPrintPreviewPages();
+
+ // Process the preview page data information. |src_url| specifies the preview
+ // page data location. The |src_url| is in the format:
+ // chrome://print/id/page_number/print.pdf
+ // |dst_page_index| specifies the blank page index that needs to be replaced
+ // with the new page data.
+ void ProcessPreviewPageInfo(const std::string& src_url, int dst_page_index);
+ // Load the next available preview page into the blank page.
+ void LoadAvailablePreviewPage();
+
+ // Bound the given scroll offset to the document.
+ pp::Point BoundScrollOffsetToDocument(const pp::Point& scroll_offset);
+
+ pp::ImageData image_data_;
+ // Used when the plugin is embedded in a page and we have to create the loader
+ // ourself.
+ pp::CompletionCallbackFactory<OutOfProcessInstance> loader_factory_;
+ pp::URLLoader embed_loader_;
+ pp::URLLoader embed_preview_loader_;
+
+ PP_CursorType_Dev cursor_; // The current cursor.
+
+ pp::CompletionCallbackFactory<OutOfProcessInstance> timer_factory_;
+
+ // Size, in pixels, of plugin rectangle.
+ pp::Size plugin_size_;
+ // Size, in DIPs, of plugin rectangle.
+ pp::Size plugin_dip_size_;
+ // Remaining area, in pixels, to render the pdf in after accounting for
+ // horizontal centering.
+ pp::Rect available_area_;
+ // Size of entire document in pixels (i.e. if each page is 800 pixels high and
+ // there are 10 pages, the height will be 8000).
+ pp::Size document_size_;
+
+ double zoom_; // Current zoom factor.
+
+ float device_scale_; // Current device scale factor.
+ bool printing_enabled_;
+ // True if the plugin is full-page.
+ bool full_;
+
+ PaintManager paint_manager_;
+
+ struct BackgroundPart {
+ pp::Rect location;
+ uint32 color;
+ };
+ std::vector<BackgroundPart> background_parts_;
+
+ struct PrintSettings {
+ PrintSettings() {
+ Clear();
+ }
+ void Clear() {
+ is_printing = false;
+ print_pages_called_ = false;
+ memset(&pepper_print_settings, 0, sizeof(pepper_print_settings));
+ }
+ // This is set to true when PrintBegin is called and false when PrintEnd is
+ // called.
+ bool is_printing;
+ // To know whether this was an actual print operation, so we don't double
+ // count UMA logging.
+ bool print_pages_called_;
+ PP_PrintSettings_Dev pepper_print_settings;
+ };
+
+ PrintSettings print_settings_;
+
+ scoped_ptr<PDFEngine> engine_;
+
+ // This engine is used to render the individual preview page data. This is
+ // used only in print preview mode. This will use |PreviewModeClient|
+ // interface which has very limited access to the pp::Instance.
+ scoped_ptr<PDFEngine> preview_engine_;
+
+ std::string url_;
+
+ // Used for submitting forms.
+ pp::CompletionCallbackFactory<OutOfProcessInstance> form_factory_;
+ pp::URLLoader form_loader_;
+
+ // Used for printing without re-entrancy issues.
+ pp::CompletionCallbackFactory<OutOfProcessInstance> print_callback_factory_;
+
+ // True if we haven't painted the plugin viewport yet.
+ bool first_paint_;
+
+ DocumentLoadState document_load_state_;
+ DocumentLoadState preview_document_load_state_;
+
+ // A UMA resource for histogram reporting.
+ pp::UMAPrivate uma_;
+
+ // Used so that we only tell the browser once about an unsupported feature, to
+ // avoid the infobar going up more than once.
+ bool told_browser_about_unsupported_feature_;
+
+ // Keeps track of which unsupported features we reported, so we avoid spamming
+ // the stats if a feature shows up many times per document.
+ std::set<std::string> unsupported_features_reported_;
+
+ // Number of pages in print preview mode, 0 if not in print preview mode.
+ int print_preview_page_count_;
+ std::vector<int> print_preview_page_numbers_;
+
+ // Used to manage loaded print preview page information. A |PreviewPageInfo|
+ // consists of data source url string and the page index in the destination
+ // document.
+ typedef std::pair<std::string, int> PreviewPageInfo;
+ std::queue<PreviewPageInfo> preview_pages_info_;
+
+ // Used to signal the browser about focus changes to trigger the OSK.
+ // TODO(abodenha@chromium.org) Implement full IME support in the plugin.
+ // http://crbug.com/132565
+ scoped_ptr<pp::TextInput_Dev> text_input_;
+
+ // The last document load progress value sent to the web page.
+ double last_progress_sent_;
+
+ // Whether an update to the number of find results found was sent less than
+ // |kFindResultCooldownMs| milliseconds ago.
+ bool recently_sent_find_update_;
+
+ // The tickmarks.
+ std::vector<pp::Rect> tickmarks_;
+
+ // Whether the plugin has received a viewport changed message. Nothing should
+ // be painted until this is received.
+ bool received_viewport_message_;
+
+ // If true, this means we told the RenderView that we're starting a network
+ // request so that it can start the throbber. We will tell it again once the
+ // document finishes loading.
+ bool did_call_start_loading_;
+
+ // If this is true, then don't scroll the plugin in response to DidChangeView
+ // messages. This will be true when the extension page is in the process of
+ // zooming the plugin so that flickering doesn't occur while zooming.
+ bool stop_scrolling_;
+
+ // The callback for receiving the password from the page.
+ scoped_ptr<pp::CompletionCallbackWithOutput<pp::Var> > password_callback_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_OUT_OF_PROCESS_INSTANCE_H_
diff --git a/xfa_test/pdf/page_indicator.cc b/xfa_test/pdf/page_indicator.cc
new file mode 100644
index 0000000000..c4af1e07b7
--- /dev/null
+++ b/xfa_test/pdf/page_indicator.cc
@@ -0,0 +1,127 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/page_indicator.h"
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "pdf/draw_utils.h"
+#include "pdf/number_image_generator.h"
+#include "pdf/resource_consts.h"
+
+namespace chrome_pdf {
+
+
+PageIndicator::PageIndicator()
+ : current_page_(0),
+ fade_out_timer_id_(0),
+ splash_timeout_(kPageIndicatorSplashTimeoutMs),
+ fade_timeout_(kPageIndicatorScrollFadeTimeoutMs),
+ always_visible_(false) {
+}
+
+PageIndicator::~PageIndicator() {
+}
+
+bool PageIndicator::CreatePageIndicator(
+ uint32 id,
+ bool visible,
+ Control::Owner* delegate,
+ NumberImageGenerator* number_image_generator,
+ bool always_visible) {
+ number_image_generator_ = number_image_generator;
+ always_visible_ = always_visible;
+
+ pp::Rect rc;
+ bool res = Control::Create(id, rc, visible, delegate);
+ return res;
+}
+
+void PageIndicator::Configure(const pp::Point& origin,
+ const pp::ImageData& background) {
+ background_ = background;
+ pp::Rect rc(origin, background_.size());
+ Control::SetRect(rc, false);
+}
+
+void PageIndicator::set_current_page(int current_page) {
+ if (current_page_ < 0)
+ return;
+
+ current_page_ = current_page;
+}
+
+void PageIndicator::Paint(pp::ImageData* image_data, const pp::Rect& rc) {
+ if (!visible())
+ return;
+
+ pp::Rect draw_rc = rc.Intersect(rect());
+ if (draw_rc.IsEmpty())
+ return;
+
+ // Copying the background image to a temporary buffer.
+ pp::ImageData buffer(owner()->GetInstance(), background_.format(),
+ background_.size(), false);
+ CopyImage(background_, pp::Rect(background_.size()),
+ &buffer, pp::Rect(background_.size()), false);
+
+ // Creating the page number image.
+ pp::ImageData page_number_image;
+ number_image_generator_->GenerateImage(current_page_, &page_number_image);
+
+ pp::Point origin2(
+ (buffer.size().width() - page_number_image.size().width()) / 2.5,
+ (buffer.size().height() - page_number_image.size().height()) / 2);
+
+ // Drawing page number image on the buffer.
+ if (origin2.x() > 0 && origin2.y() > 0) {
+ CopyImage(page_number_image,
+ pp::Rect(pp::Point(), page_number_image.size()),
+ &buffer,
+ pp::Rect(origin2, page_number_image.size()),
+ false);
+ }
+
+ // Drawing the buffer.
+ pp::Point origin = draw_rc.point();
+ draw_rc.Offset(-rect().x(), -rect().y());
+ AlphaBlend(buffer, draw_rc, image_data, origin, transparency());
+}
+
+void PageIndicator::OnTimerFired(uint32 timer_id) {
+ FadingControl::OnTimerFired(timer_id);
+ if (timer_id == fade_out_timer_id_) {
+ Fade(false, fade_timeout_);
+ }
+}
+
+void PageIndicator::ResetFadeOutTimer() {
+ fade_out_timer_id_ =
+ owner()->ScheduleTimer(id(), splash_timeout_);
+}
+
+void PageIndicator::OnFadeInComplete() {
+ if (!always_visible_)
+ ResetFadeOutTimer();
+}
+
+void PageIndicator::Splash() {
+ Splash(kPageIndicatorSplashTimeoutMs, kPageIndicatorScrollFadeTimeoutMs);
+}
+
+void PageIndicator::Splash(uint32 splash_timeout, uint32 fade_timeout) {
+ splash_timeout_ = splash_timeout;
+ fade_timeout_ = fade_timeout;
+ if (!always_visible_)
+ fade_out_timer_id_ = 0;
+ Fade(true, fade_timeout_);
+}
+
+int PageIndicator::GetYPosition(
+ int vertical_scrollbar_y, int document_height, int plugin_height) {
+ double percent = static_cast<double>(vertical_scrollbar_y) / document_height;
+ return (plugin_height - rect().height()) * percent;
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/page_indicator.h b/xfa_test/pdf/page_indicator.h
new file mode 100644
index 0000000000..0d06ee1a0b
--- /dev/null
+++ b/xfa_test/pdf/page_indicator.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PAGE_INDICATOR_H_
+#define PDF_PAGE_INDICATOR_H_
+
+#include <string>
+#include <vector>
+
+#include "pdf/control.h"
+#include "pdf/fading_control.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/point.h"
+#include "ppapi/cpp/rect.h"
+
+namespace chrome_pdf {
+
+class NumberImageGenerator;
+
+const uint32 kPageIndicatorScrollFadeTimeoutMs = 240;
+const uint32 kPageIndicatorInitialFadeTimeoutMs = 960;
+const uint32 kPageIndicatorSplashTimeoutMs = 2000;
+
+class PageIndicator : public FadingControl {
+ public:
+ PageIndicator();
+ virtual ~PageIndicator();
+ virtual bool CreatePageIndicator(
+ uint32 id,
+ bool visible,
+ Control::Owner* delegate,
+ NumberImageGenerator* number_image_generator,
+ bool always_visible);
+
+ void Configure(const pp::Point& origin, const pp::ImageData& background);
+
+ int current_page() const { return current_page_; }
+ void set_current_page(int current_page);
+
+ virtual void Splash();
+ void Splash(uint32 splash_timeout, uint32 page_timeout);
+
+ // Returns the y position where the page indicator should be drawn given the
+ // position of the scrollbar and the total document height and the plugin
+ // height.
+ int GetYPosition(
+ int vertical_scrollbar_y, int document_height, int plugin_height);
+
+ // Control interface.
+ virtual void Paint(pp::ImageData* image_data, const pp::Rect& rc);
+ virtual void OnTimerFired(uint32 timer_id);
+
+ // FadingControl interface.
+ virtual void OnFadeInComplete();
+
+ private:
+ void ResetFadeOutTimer();
+
+ int current_page_;
+ pp::ImageData background_;
+ NumberImageGenerator* number_image_generator_;
+ uint32 fade_out_timer_id_;
+ uint32 splash_timeout_;
+ uint32 fade_timeout_;
+
+ bool always_visible_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PAGE_INDICATOR_H_
diff --git a/xfa_test/pdf/paint_aggregator.cc b/xfa_test/pdf/paint_aggregator.cc
new file mode 100644
index 0000000000..549cab6d09
--- /dev/null
+++ b/xfa_test/pdf/paint_aggregator.cc
@@ -0,0 +1,263 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/paint_aggregator.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+
+// ----------------------------------------------------------------------------
+// ALGORITHM NOTES
+//
+// We attempt to maintain a scroll rect in the presence of invalidations that
+// are contained within the scroll rect. If an invalidation crosses a scroll
+// rect, then we just treat the scroll rect as an invalidation rect.
+//
+// For invalidations performed prior to scrolling and contained within the
+// scroll rect, we offset the invalidation rects to account for the fact that
+// the consumer will perform scrolling before painting.
+//
+// We only support scrolling along one axis at a time. A diagonal scroll will
+// therefore be treated as an invalidation.
+// ----------------------------------------------------------------------------
+
+PaintAggregator::PaintUpdate::PaintUpdate() {
+}
+
+PaintAggregator::PaintUpdate::~PaintUpdate() {
+}
+
+PaintAggregator::InternalPaintUpdate::InternalPaintUpdate() :
+ synthesized_scroll_damage_rect_(false) {
+}
+
+PaintAggregator::InternalPaintUpdate::~InternalPaintUpdate() {
+}
+
+pp::Rect PaintAggregator::InternalPaintUpdate::GetScrollDamage() const {
+ // Should only be scrolling in one direction at a time.
+ DCHECK(!(scroll_delta.x() && scroll_delta.y()));
+
+ pp::Rect damaged_rect;
+
+ // Compute the region we will expose by scrolling, and paint that into a
+ // shared memory section.
+ if (scroll_delta.x()) {
+ int32_t dx = scroll_delta.x();
+ damaged_rect.set_y(scroll_rect.y());
+ damaged_rect.set_height(scroll_rect.height());
+ if (dx > 0) {
+ damaged_rect.set_x(scroll_rect.x());
+ damaged_rect.set_width(dx);
+ } else {
+ damaged_rect.set_x(scroll_rect.right() + dx);
+ damaged_rect.set_width(-dx);
+ }
+ } else {
+ int32_t dy = scroll_delta.y();
+ damaged_rect.set_x(scroll_rect.x());
+ damaged_rect.set_width(scroll_rect.width());
+ if (dy > 0) {
+ damaged_rect.set_y(scroll_rect.y());
+ damaged_rect.set_height(dy);
+ } else {
+ damaged_rect.set_y(scroll_rect.bottom() + dy);
+ damaged_rect.set_height(-dy);
+ }
+ }
+
+ // In case the scroll offset exceeds the width/height of the scroll rect
+ return scroll_rect.Intersect(damaged_rect);
+}
+
+PaintAggregator::PaintAggregator() {
+}
+
+bool PaintAggregator::HasPendingUpdate() const {
+ return !update_.scroll_rect.IsEmpty() || !update_.paint_rects.empty();
+}
+
+void PaintAggregator::ClearPendingUpdate() {
+ update_ = InternalPaintUpdate();
+}
+
+PaintAggregator::PaintUpdate PaintAggregator::GetPendingUpdate() {
+ // Convert the internal paint update to the external one, which includes a
+ // bit more precomputed info for the caller.
+ PaintUpdate ret;
+ ret.scroll_delta = update_.scroll_delta;
+ ret.scroll_rect = update_.scroll_rect;
+ ret.has_scroll = ret.scroll_delta.x() != 0 || ret.scroll_delta.y() != 0;
+
+ // Include the scroll damage (if any) in the paint rects.
+ // Code invalidates damaged rect here, it pick it up from the list of paint
+ // rects in the next block.
+ if (ret.has_scroll && !update_.synthesized_scroll_damage_rect_) {
+ update_.synthesized_scroll_damage_rect_ = true;
+ pp::Rect scroll_damage = update_.GetScrollDamage();
+ InvalidateRectInternal(scroll_damage, false);
+ }
+
+ ret.paint_rects.reserve(update_.paint_rects.size() + 1);
+ for (size_t i = 0; i < update_.paint_rects.size(); i++)
+ ret.paint_rects.push_back(update_.paint_rects[i]);
+
+ return ret;
+}
+
+void PaintAggregator::SetIntermediateResults(
+ const std::vector<ReadyRect>& ready,
+ const std::vector<pp::Rect>& pending) {
+ update_.ready_rects.insert(
+ update_.ready_rects.end(), ready.begin(), ready.end());
+ update_.paint_rects = pending;
+}
+
+std::vector<PaintAggregator::ReadyRect> PaintAggregator::GetReadyRects() const {
+ return update_.ready_rects;
+}
+
+void PaintAggregator::InvalidateRect(const pp::Rect& rect) {
+ InvalidateRectInternal(rect, true);
+}
+
+void PaintAggregator::ScrollRect(const pp::Rect& clip_rect,
+ const pp::Point& amount) {
+ // We only support scrolling along one axis at a time.
+ if (amount.x() != 0 && amount.y() != 0) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // We can only scroll one rect at a time.
+ if (!update_.scroll_rect.IsEmpty() && update_.scroll_rect != clip_rect) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // Again, we only support scrolling along one axis at a time. Make sure this
+ // update doesn't scroll on a different axis than any existing one.
+ if ((amount.x() && update_.scroll_delta.y()) ||
+ (amount.y() && update_.scroll_delta.x())) {
+ InvalidateRect(clip_rect);
+ return;
+ }
+
+ // The scroll rect is new or isn't changing (though the scroll amount may
+ // be changing).
+ update_.scroll_rect = clip_rect;
+ update_.scroll_delta += amount;
+
+ // We might have just wiped out a pre-existing scroll.
+ if (update_.scroll_delta == pp::Point()) {
+ update_.scroll_rect = pp::Rect();
+ return;
+ }
+
+ // Adjust any paint rects that intersect the scroll. For the portion of the
+ // paint that is inside the scroll area, move it by the scroll amount and
+ // replace the existing paint with it. For the portion (if any) that is
+ // outside the scroll, just invalidate it.
+ std::vector<pp::Rect> leftover_rects;
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ if (!update_.scroll_rect.Intersects(update_.paint_rects[i]))
+ continue;
+
+ pp::Rect intersection =
+ update_.paint_rects[i].Intersect(update_.scroll_rect);
+ pp::Rect rect = update_.paint_rects[i];
+ while (!rect.IsEmpty()) {
+ pp::Rect leftover = rect.Subtract(intersection);
+ if (leftover.IsEmpty())
+ break;
+ // Don't want to call InvalidateRectInternal now since it'll modify
+ // update_.paint_rects, so keep track of this and do it below.
+ leftover_rects.push_back(leftover);
+ rect = rect.Subtract(leftover);
+ }
+
+ update_.paint_rects[i] = ScrollPaintRect(intersection, amount);
+
+ // The rect may have been scrolled out of view.
+ if (update_.paint_rects[i].IsEmpty()) {
+ update_.paint_rects.erase(update_.paint_rects.begin() + i);
+ i--;
+ }
+ }
+
+ for (size_t i = 0; i < leftover_rects.size(); ++i)
+ InvalidateRectInternal(leftover_rects[i], false);
+
+ for (size_t i = 0; i < update_.ready_rects.size(); ++i) {
+ if (update_.scroll_rect.Contains(update_.ready_rects[i].rect)) {
+ update_.ready_rects[i].rect =
+ ScrollPaintRect(update_.ready_rects[i].rect, amount);
+ }
+ }
+
+ if (update_.synthesized_scroll_damage_rect_) {
+ pp::Rect damage = update_.GetScrollDamage();
+ InvalidateRect(damage);
+ }
+}
+
+pp::Rect PaintAggregator::ScrollPaintRect(const pp::Rect& paint_rect,
+ const pp::Point& amount) const {
+ pp::Rect result = paint_rect;
+ result.Offset(amount);
+ result = update_.scroll_rect.Intersect(result);
+ return result;
+}
+
+void PaintAggregator::InvalidateScrollRect() {
+ pp::Rect scroll_rect = update_.scroll_rect;
+ update_.scroll_rect = pp::Rect();
+ update_.scroll_delta = pp::Point();
+ InvalidateRect(scroll_rect);
+}
+
+void PaintAggregator::InvalidateRectInternal(const pp::Rect& rect_old,
+ bool check_scroll) {
+ pp::Rect rect = rect_old;
+ // Check if any rects that are ready to be painted overlap.
+ for (size_t i = 0; i < update_.ready_rects.size(); ++i) {
+ const pp::Rect& existing_rect = update_.ready_rects[i].rect;
+ if (rect.Intersects(existing_rect)) {
+ // Re-invalidate in case the union intersects other paint rects.
+ rect = existing_rect.Union(rect);
+ update_.ready_rects.erase(update_.ready_rects.begin() + i);
+ break;
+ }
+ }
+
+ bool add_paint = true;
+
+ // Combine overlapping paints using smallest bounding box.
+ for (size_t i = 0; i < update_.paint_rects.size(); ++i) {
+ const pp::Rect& existing_rect = update_.paint_rects[i];
+ if (existing_rect.Contains(rect)) // Optimize out redundancy.
+ add_paint = false;
+ if (rect.Intersects(existing_rect) || rect.SharesEdgeWith(existing_rect)) {
+ // Re-invalidate in case the union intersects other paint rects.
+ pp::Rect combined_rect = existing_rect.Union(rect);
+ update_.paint_rects.erase(update_.paint_rects.begin() + i);
+ InvalidateRectInternal(combined_rect, check_scroll);
+ add_paint = false;
+ }
+ }
+
+ if (add_paint) {
+ // Add a non-overlapping paint.
+ update_.paint_rects.push_back(rect);
+ }
+
+ // If the new paint overlaps with a scroll, then also invalidate the rect in
+ // its new position.
+ if (check_scroll &&
+ !update_.scroll_rect.IsEmpty() &&
+ update_.scroll_rect.Intersects(rect)) {
+ InvalidateRectInternal(ScrollPaintRect(rect, update_.scroll_delta), false);
+ }
+}
diff --git a/xfa_test/pdf/paint_aggregator.h b/xfa_test/pdf/paint_aggregator.h
new file mode 100644
index 0000000000..96f61e0878
--- /dev/null
+++ b/xfa_test/pdf/paint_aggregator.h
@@ -0,0 +1,130 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PAINT_AGGREGATOR_H_
+#define PDF_PAINT_AGGREGATOR_H_
+
+#include <vector>
+
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/rect.h"
+
+// This class is responsible for aggregating multiple invalidation and scroll
+// commands to produce a scroll and repaint sequence. You can use this manually
+// to track your updates, but most applications will use the PaintManager to
+// additionally handle the necessary callbacks on top of the PaintAggregator
+// functionality.
+//
+// See http://code.google.com/p/ppapi/wiki/2DPaintingModel
+class PaintAggregator {
+ public:
+ // Stores information about a rectangle that has finished painting. The
+ // PaintManager will paint it only when everything else on the screen is also
+ // ready.
+ struct ReadyRect {
+ pp::Point offset;
+ pp::Rect rect;
+ pp::ImageData image_data;
+ };
+
+ struct PaintUpdate {
+ PaintUpdate();
+ ~PaintUpdate();
+
+ // True if there is a scroll applied. This indicates that the scroll delta
+ // and scroll_rect are nonzero (just as a convenience).
+ bool has_scroll;
+
+ // The amount to scroll by. Either the X or Y may be nonzero to indicate a
+ // scroll in that direction, but there will never be a scroll in both
+ // directions at the same time (this will be converted to a paint of the
+ // region instead).
+ //
+ // If there is no scroll, this will be (0, 0).
+ pp::Point scroll_delta;
+
+ // The rectangle that should be scrolled by the scroll_delta. If there is no
+ // scroll, this will be (0, 0, 0, 0). We only track one scroll command at
+ // once. If there are multiple ones, they will be converted to invalidates.
+ pp::Rect scroll_rect;
+
+ // A list of all the individual dirty rectangles. This is an aggregated list
+ // of all invalidate calls. Different rectangles may be unified to produce a
+ // minimal list with no overlap that is more efficient to paint. This list
+ // also contains the region exposed by any scroll command.
+ std::vector<pp::Rect> paint_rects;
+ };
+
+ PaintAggregator();
+
+ // There is a PendingUpdate if InvalidateRect or ScrollRect were called and
+ // ClearPendingUpdate was not called.
+ bool HasPendingUpdate() const;
+ void ClearPendingUpdate();
+
+ PaintUpdate GetPendingUpdate();
+
+ // Sets the result of a call to the plugin to paint. This includes rects that
+ // are finished painting (ready), and ones that are still in-progress
+ // (pending).
+ void SetIntermediateResults(const std::vector<ReadyRect>& ready,
+ const std::vector<pp::Rect>& pending);
+
+ // Returns the rectangles that are ready to be painted.
+ std::vector<ReadyRect> GetReadyRects() const;
+
+ // The given rect should be repainted.
+ void InvalidateRect(const pp::Rect& rect);
+
+ // The given rect should be scrolled by the given amounts.
+ void ScrollRect(const pp::Rect& clip_rect, const pp::Point& amount);
+
+ private:
+ // This structure is an internal version of PaintUpdate. It's different in
+ // two respects:
+ //
+ // - The scroll damange (area exposed by the scroll operation, if any) is
+ // maintained separately from the dirty rects generated by calling
+ // InvalidateRect. We need to know this distinction for some operations.
+ //
+ // - The paint bounds union is computed on the fly so we don't have to keep
+ // a rectangle up-to-date as we do different operations.
+ class InternalPaintUpdate {
+ public:
+ InternalPaintUpdate();
+ ~InternalPaintUpdate();
+
+ // Computes the rect damaged by scrolling within |scroll_rect| by
+ // |scroll_delta|. This rect must be repainted. It is not included in
+ // paint_rects.
+ pp::Rect GetScrollDamage() const;
+
+ pp::Point scroll_delta;
+ pp::Rect scroll_rect;
+
+ // Does not include the scroll damage rect unless
+ // synthesized_scroll_damage_rect_ is set.
+ std::vector<pp::Rect> paint_rects;
+
+ // Rectangles that are finished painting.
+ std::vector<ReadyRect> ready_rects;
+
+ // Whether we have added the scroll damage rect to paint_rects yet or not.
+ bool synthesized_scroll_damage_rect_;
+ };
+
+ pp::Rect ScrollPaintRect(const pp::Rect& paint_rect,
+ const pp::Point& amount) const;
+ void InvalidateScrollRect();
+
+ // Internal method used by InvalidateRect. If |check_scroll| is true, then the
+ // method checks if there's a pending scroll and if so also invalidates |rect|
+ // in the new scroll position.
+ void InvalidateRectInternal(const pp::Rect& rect, bool check_scroll);
+
+ InternalPaintUpdate update_;
+};
+
+#endif // PDF_PAINT_AGGREGATOR_H_
diff --git a/xfa_test/pdf/paint_manager.cc b/xfa_test/pdf/paint_manager.cc
new file mode 100644
index 0000000000..f452b37186
--- /dev/null
+++ b/xfa_test/pdf/paint_manager.cc
@@ -0,0 +1,302 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/paint_manager.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+
+PaintManager::PaintManager(pp::Instance* instance,
+ Client* client,
+ bool is_always_opaque)
+ : instance_(instance),
+ client_(client),
+ is_always_opaque_(is_always_opaque),
+ callback_factory_(NULL),
+ manual_callback_pending_(false),
+ flush_pending_(false),
+ has_pending_resize_(false),
+ graphics_need_to_be_bound_(false),
+ pending_device_scale_(1.0),
+ device_scale_(1.0),
+ in_paint_(false),
+ first_paint_(true),
+ view_size_changed_waiting_for_paint_(false) {
+ // Set the callback object outside of the initializer list to avoid a
+ // compiler warning about using "this" in an initializer list.
+ callback_factory_.Initialize(this);
+
+ // You can not use a NULL client pointer.
+ DCHECK(client);
+}
+
+PaintManager::~PaintManager() {
+}
+
+// static
+pp::Size PaintManager::GetNewContextSize(const pp::Size& current_context_size,
+ const pp::Size& plugin_size) {
+ // The amount of additional space in pixels to allocate to the right/bottom of
+ // the context.
+ const int kBufferSize = 50;
+
+ // Default to returning the same size.
+ pp::Size result = current_context_size;
+
+ // The minimum size of the plugin before resizing the context to ensure we
+ // aren't wasting too much memory. We deduct twice the kBufferSize from the
+ // current context size which gives a threshhold that is kBufferSize below
+ // the plugin size when the context size was last computed.
+ pp::Size min_size(
+ std::max(current_context_size.width() - 2 * kBufferSize, 0),
+ std::max(current_context_size.height() - 2 * kBufferSize, 0));
+
+ // If the plugin size is bigger than the current context size, we need to
+ // resize the context. If the plugin size is smaller than the current
+ // context size by a given threshhold then resize the context so that we
+ // aren't wasting too much memory.
+ if (plugin_size.width() > current_context_size.width() ||
+ plugin_size.height() > current_context_size.height() ||
+ plugin_size.width() < min_size.width() ||
+ plugin_size.height() < min_size.height()) {
+ // Create a larger context than needed so that if we only resize by a
+ // small margin, we don't need a new context.
+ result = pp::Size(plugin_size.width() + kBufferSize,
+ plugin_size.height() + kBufferSize);
+ }
+
+ return result;
+}
+
+void PaintManager::Initialize(pp::Instance* instance,
+ Client* client,
+ bool is_always_opaque) {
+ DCHECK(!instance_ && !client_); // Can't initialize twice.
+ instance_ = instance;
+ client_ = client;
+ is_always_opaque_ = is_always_opaque;
+}
+
+void PaintManager::SetSize(const pp::Size& new_size, float device_scale) {
+ if (GetEffectiveSize() == new_size &&
+ GetEffectiveDeviceScale() == device_scale)
+ return;
+
+ has_pending_resize_ = true;
+ pending_size_ = new_size;
+ pending_device_scale_ = device_scale;
+
+ view_size_changed_waiting_for_paint_ = true;
+
+ Invalidate();
+}
+
+void PaintManager::Invalidate() {
+ // You must call SetSize before using.
+ DCHECK(!graphics_.is_null() || has_pending_resize_);
+
+ EnsureCallbackPending();
+ aggregator_.InvalidateRect(pp::Rect(GetEffectiveSize()));
+}
+
+void PaintManager::InvalidateRect(const pp::Rect& rect) {
+ DCHECK(!in_paint_);
+
+ // You must call SetSize before using.
+ DCHECK(!graphics_.is_null() || has_pending_resize_);
+
+ // Clip the rect to the device area.
+ pp::Rect clipped_rect = rect.Intersect(pp::Rect(GetEffectiveSize()));
+ if (clipped_rect.IsEmpty())
+ return; // Nothing to do.
+
+ EnsureCallbackPending();
+ aggregator_.InvalidateRect(clipped_rect);
+}
+
+void PaintManager::ScrollRect(const pp::Rect& clip_rect,
+ const pp::Point& amount) {
+ DCHECK(!in_paint_);
+
+ // You must call SetSize before using.
+ DCHECK(!graphics_.is_null() || has_pending_resize_);
+
+ EnsureCallbackPending();
+
+ aggregator_.ScrollRect(clip_rect, amount);
+}
+
+pp::Size PaintManager::GetEffectiveSize() const {
+ return has_pending_resize_ ? pending_size_ : plugin_size_;
+}
+
+float PaintManager::GetEffectiveDeviceScale() const {
+ return has_pending_resize_ ? pending_device_scale_ : device_scale_;
+}
+
+void PaintManager::EnsureCallbackPending() {
+ // The best way for us to do the next update is to get a notification that
+ // a previous one has completed. So if we're already waiting for one, we
+ // don't have to do anything differently now.
+ if (flush_pending_)
+ return;
+
+ // If no flush is pending, we need to do a manual call to get back to the
+ // main thread. We may have one already pending, or we may need to schedule.
+ if (manual_callback_pending_)
+ return;
+
+ pp::Module::Get()->core()->CallOnMainThread(
+ 0,
+ callback_factory_.NewCallback(&PaintManager::OnManualCallbackComplete),
+ 0);
+ manual_callback_pending_ = true;
+}
+
+void PaintManager::DoPaint() {
+ in_paint_ = true;
+
+ std::vector<ReadyRect> ready;
+ std::vector<pp::Rect> pending;
+
+ DCHECK(aggregator_.HasPendingUpdate());
+
+ // Apply any pending resize. Setting the graphics to this class must happen
+ // before asking the plugin to paint in case it requests invalides or resizes.
+ // However, the bind must not happen until afterward since we don't want to
+ // have an unpainted device bound. The needs_binding flag tells us whether to
+ // do this later.
+ if (has_pending_resize_) {
+ plugin_size_ = pending_size_;
+ // Only create a new graphics context if the current context isn't big
+ // enough or if it is far too big. This avoids creating a new context if
+ // we only resize by a small amount.
+ pp::Size new_size = GetNewContextSize(graphics_.size(), pending_size_);
+ if (graphics_.size() != new_size) {
+ graphics_ = pp::Graphics2D(instance_, new_size, is_always_opaque_);
+ graphics_need_to_be_bound_ = true;
+
+ // Since we're binding a new one, all of the callbacks have been canceled.
+ manual_callback_pending_ = false;
+ flush_pending_ = false;
+ callback_factory_.CancelAll();
+ }
+
+ if (pending_device_scale_ != 1.0)
+ graphics_.SetScale(1.0 / pending_device_scale_);
+ device_scale_ = pending_device_scale_;
+
+ // This must be cleared before calling into the plugin since it may do
+ // additional invalidation or sizing operations.
+ has_pending_resize_ = false;
+ pending_size_ = pp::Size();
+ }
+
+ PaintAggregator::PaintUpdate update = aggregator_.GetPendingUpdate();
+ client_->OnPaint(update.paint_rects, &ready, &pending);
+
+ if (ready.empty() && pending.empty()) {
+ in_paint_ = false;
+ return; // Nothing was painted, don't schedule a flush.
+ }
+
+ std::vector<PaintAggregator::ReadyRect> ready_now;
+ if (pending.empty()) {
+ std::vector<PaintAggregator::ReadyRect> temp_ready;
+ for (size_t i = 0; i < ready.size(); ++i)
+ temp_ready.push_back(ready[i]);
+ aggregator_.SetIntermediateResults(temp_ready, pending);
+ ready_now = aggregator_.GetReadyRects();
+ aggregator_.ClearPendingUpdate();
+
+ // Apply any scroll first.
+ if (update.has_scroll)
+ graphics_.Scroll(update.scroll_rect, update.scroll_delta);
+
+ view_size_changed_waiting_for_paint_ = false;
+ } else {
+ std::vector<PaintAggregator::ReadyRect> ready_later;
+ for (size_t i = 0; i < ready.size(); ++i) {
+ // Don't flush any part (i.e. scrollbars) if we're resizing the browser,
+ // as that'll lead to flashes. Until we flush, the browser will use the
+ // previous image, but if we flush, it'll revert to using the blank image.
+ // We make an exception for the first paint since we want to show the
+ // default background color instead of the pepper default of black.
+ if (ready[i].flush_now &&
+ (!view_size_changed_waiting_for_paint_ || first_paint_)) {
+ ready_now.push_back(ready[i]);
+ } else {
+ ready_later.push_back(ready[i]);
+ }
+ }
+ // Take the rectangles, except the ones that need to be flushed right away,
+ // and save them so that everything is flushed at once.
+ aggregator_.SetIntermediateResults(ready_later, pending);
+
+ if (ready_now.empty()) {
+ in_paint_ = false;
+ EnsureCallbackPending();
+ return;
+ }
+ }
+
+ for (size_t i = 0; i < ready_now.size(); ++i) {
+ graphics_.PaintImageData(
+ ready_now[i].image_data, ready_now[i].offset, ready_now[i].rect);
+ }
+
+ int32_t result = graphics_.Flush(
+ callback_factory_.NewCallback(&PaintManager::OnFlushComplete));
+
+ // If you trigger this assertion, then your plugin has called Flush()
+ // manually. When using the PaintManager, you should not call Flush, it will
+ // handle that for you because it needs to know when it can do the next paint
+ // by implementing the flush callback.
+ //
+ // Another possible cause of this assertion is re-using devices. If you
+ // use one device, swap it with another, then swap it back, we won't know
+ // that we've already scheduled a Flush on the first device. It's best to not
+ // re-use devices in this way.
+ DCHECK(result != PP_ERROR_INPROGRESS);
+
+ if (result == PP_OK_COMPLETIONPENDING) {
+ flush_pending_ = true;
+ } else {
+ DCHECK(result == PP_OK); // Catch all other errors in debug mode.
+ }
+
+ in_paint_ = false;
+ first_paint_ = false;
+
+ if (graphics_need_to_be_bound_) {
+ instance_->BindGraphics(graphics_);
+ graphics_need_to_be_bound_ = false;
+ }
+}
+
+void PaintManager::OnFlushComplete(int32_t) {
+ DCHECK(flush_pending_);
+ flush_pending_ = false;
+
+ // If more paints were enqueued while we were waiting for the flush to
+ // complete, execute them now.
+ if (aggregator_.HasPendingUpdate())
+ DoPaint();
+}
+
+void PaintManager::OnManualCallbackComplete(int32_t) {
+ DCHECK(manual_callback_pending_);
+ manual_callback_pending_ = false;
+
+ // Just because we have a manual callback doesn't mean there are actually any
+ // invalid regions. Even though we only schedule this callback when something
+ // is pending, a Flush callback could have come in before this callback was
+ // executed and that could have cleared the queue.
+ if (aggregator_.HasPendingUpdate())
+ DoPaint();
+}
diff --git a/xfa_test/pdf/paint_manager.h b/xfa_test/pdf/paint_manager.h
new file mode 100644
index 0000000000..7755eb6829
--- /dev/null
+++ b/xfa_test/pdf/paint_manager.h
@@ -0,0 +1,205 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PAINT_MANAGER_H_
+#define PDF_PAINT_MANAGER_H_
+
+#include <vector>
+
+#include "pdf/paint_aggregator.h"
+#include "ppapi/cpp/graphics_2d.h"
+#include "ppapi/utility/completion_callback_factory.h"
+
+namespace pp {
+class Graphics2D;
+class Instance;
+class Point;
+class Rect;
+};
+
+// Custom PaintManager for the PDF plugin. This is branched from the Pepper
+// version. The difference is that this supports progressive rendering of dirty
+// rects, where multiple calls to the rendering engine are needed. It also
+// supports having higher-priority rects flushing right away, i.e. the
+// scrollbars.
+//
+// The client's OnPaint
+class PaintManager {
+ public:
+ // Like PaintAggregator's version, but allows the plugin to tell us whether
+ // it should be flushed to the screen immediately or when the rest of the
+ // plugin viewport is ready.
+ struct ReadyRect {
+ pp::Point offset;
+ pp::Rect rect;
+ pp::ImageData image_data;
+ bool flush_now;
+
+ ReadyRect(const pp::Rect& r, const pp::ImageData& i, bool f)
+ : rect(r), image_data(i), flush_now(f) {}
+
+ operator PaintAggregator::ReadyRect() const {
+ PaintAggregator::ReadyRect rv;
+ rv.offset = offset;
+ rv.rect = rect;
+ rv.image_data = image_data;
+ return rv;
+ }
+ };
+ class Client {
+ public:
+ // Paints the given invalid area of the plugin to the given graphics
+ // device. Returns true if anything was painted.
+ //
+ // You are given the list of rects to paint in |paint_rects|. You can
+ // combine painting into less rectangles if it's more efficient. When a
+ // rect is painted, information about that paint should be inserted into
+ // |ready|. Otherwise if a paint needs more work, add the rect to
+ // |pending|. If |pending| is not empty, your OnPaint function will get
+ // called again. Once OnPaint is called and it returns no pending rects,
+ // all the previously ready rects will be flushed on screen. The exception
+ // is for ready rects that have |flush_now| set to true. These will be
+ // flushed right away.
+ //
+ // Do not call Flush() on the graphics device, this will be done
+ // automatically if you return true from this function since the
+ // PaintManager needs to handle the callback.
+ //
+ // Calling Invalidate/Scroll is not allowed while inside an OnPaint
+ virtual void OnPaint(const std::vector<pp::Rect>& paint_rects,
+ std::vector<ReadyRect>* ready,
+ std::vector<pp::Rect>* pending) = 0;
+ protected:
+ // You shouldn't be doing deleting through this interface.
+ virtual ~Client() {}
+ };
+
+ // The instance is the plugin instance using this paint manager to do its
+ // painting. Painting will automatically go to this instance and you don't
+ // have to manually bind any device context (this is all handled by the
+ // paint manager).
+ //
+ // The Client is a non-owning pointer and must remain valid (normally the
+ // object implementing the Client interface will own the paint manager).
+ //
+ // The is_always_opaque flag will be passed to the device contexts that this
+ // class creates. Set this to true if your plugin always draws an opaque
+ // image to the device. This is used as a hint to the browser that it does
+ // not need to do alpha blending, which speeds up painting. If you generate
+ // non-opqaue pixels or aren't sure, set this to false for more general
+ // blending.
+ //
+ // If you set is_always_opaque, your alpha channel should always be set to
+ // 0xFF or there may be painting artifacts. Being opaque will allow the
+ // browser to do a memcpy rather than a blend to paint the plugin, and this
+ // means your alpha values will get set on the page backing store. If these
+ // values are incorrect, it could mess up future blending. If you aren't
+ // sure, it is always correct to specify that it it not opaque.
+ //
+ // You will need to call SetSize before this class will do anything. Normally
+ // you do this from the ViewChanged method of your plugin instance.
+ PaintManager(pp::Instance* instance, Client* client, bool is_always_opaque);
+
+ ~PaintManager();
+
+ // Returns the size of the graphics context to allocate for a given plugin
+ // size. We may allocated a slightly larger buffer than required so that we
+ // don't have to resize the context when scrollbars appear/dissapear due to
+ // zooming (which can result in flickering).
+ static pp::Size GetNewContextSize(const pp::Size& current_context_size,
+ const pp::Size& plugin_size);
+
+ // You must call this function before using if you use the 0-arg constructor.
+ // See the constructor for what these arguments mean.
+ void Initialize(pp::Instance* instance, Client* client,
+ bool is_always_opaque);
+
+ // Sets the size of the plugin. If the size is the same as the previous call,
+ // this will be a NOP. If the size has changed, a new device will be
+ // allocated to the given size and a paint to that device will be scheduled.
+ //
+ // This is intended to be called from ViewChanged with the size of the
+ // plugin. Since it tracks the old size and only allocates when the size
+ // changes, you can always call this function without worrying about whether
+ // the size changed or ViewChanged is called for another reason (like the
+ // position changed).
+ void SetSize(const pp::Size& new_size, float new_device_scale);
+
+ // Invalidate the entire plugin.
+ void Invalidate();
+
+ // Invalidate the given rect.
+ void InvalidateRect(const pp::Rect& rect);
+
+ // The given rect should be scrolled by the given amounts.
+ void ScrollRect(const pp::Rect& clip_rect, const pp::Point& amount);
+
+ // Returns the size of the graphics context for the next paint operation.
+ // This is the pending size if a resize is pending (the plugin has called
+ // SetSize but we haven't actually painted it yet), or the current size of
+ // no resize is pending.
+ pp::Size GetEffectiveSize() const;
+ float GetEffectiveDeviceScale() const;
+
+ private:
+ // Disallow copy and assign (these are unimplemented).
+ PaintManager(const PaintManager&);
+ PaintManager& operator=(const PaintManager&);
+
+ // Makes sure there is a callback that will trigger a paint at a later time.
+ // This will be either a Flush callback telling us we're allowed to generate
+ // more data, or, if there's no flush callback pending, a manual call back
+ // to the message loop via ExecuteOnMainThread.
+ void EnsureCallbackPending();
+
+ // Does the client paint and executes a Flush if necessary.
+ void DoPaint();
+
+ // Callback for asynchronous completion of Flush.
+ void OnFlushComplete(int32_t);
+
+ // Callback for manual scheduling of paints when there is no flush callback
+ // pending.
+ void OnManualCallbackComplete(int32_t);
+
+ pp::Instance* instance_;
+
+ // Non-owning pointer. See the constructor.
+ Client* client_;
+
+ bool is_always_opaque_;
+
+ pp::CompletionCallbackFactory<PaintManager> callback_factory_;
+
+ // This graphics device will be is_null() if no graphics has been manually
+ // set yet.
+ pp::Graphics2D graphics_;
+
+ PaintAggregator aggregator_;
+
+ // See comment for EnsureCallbackPending for more on how these work.
+ bool manual_callback_pending_;
+ bool flush_pending_;
+
+ // When we get a resize, we don't bind right away (see SetSize). The
+ // has_pending_resize_ tells us that we need to do a resize for the next
+ // paint operation. When true, the new size is in pending_size_.
+ bool has_pending_resize_;
+ bool graphics_need_to_be_bound_;
+ pp::Size pending_size_;
+ pp::Size plugin_size_;
+ float pending_device_scale_;
+ float device_scale_;
+
+ // True iff we're in the middle of a paint.
+ bool in_paint_;
+
+ // True if we haven't painted the plugin viewport yet.
+ bool first_paint_;
+
+ // True when the view size just changed and we're waiting for a paint.
+ bool view_size_changed_waiting_for_paint_;
+};
+
+#endif // PDF_PAINT_MANAGER_H_
diff --git a/xfa_test/pdf/pdf.cc b/xfa_test/pdf/pdf.cc
new file mode 100644
index 0000000000..6a4507f4fc
--- /dev/null
+++ b/xfa_test/pdf/pdf.cc
@@ -0,0 +1,275 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/pdf.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "pdf/instance.h"
+#include "pdf/out_of_process_instance.h"
+#include "ppapi/c/ppp.h"
+#include "ppapi/cpp/private/pdf.h"
+
+bool g_sdk_initialized_via_pepper = false;
+
+// The Mac release builds discard CreateModule and the entire PDFModule
+// definition because they are not referenced here. This causes the Pepper
+// exports (PPP_GetInterface etc) to not be exported. So we force the linker
+// to include this code by using __attribute__((used)).
+#if __GNUC__ >= 4
+#define PDF_USED __attribute__((used))
+#else
+#define PDF_USED
+#endif
+
+#if defined(OS_WIN)
+HMODULE g_hmodule;
+
+void HandleInvalidParameter(const wchar_t* expression,
+ const wchar_t* function,
+ const wchar_t* file,
+ unsigned int line,
+ uintptr_t reserved) {
+ // Do the same as Chrome's CHECK(false) which is undefined.
+ ::base::debug::BreakDebugger();
+ return;
+}
+
+void HandlePureVirtualCall() {
+ // Do the same as Chrome's CHECK(false) which is undefined.
+ ::base::debug::BreakDebugger();
+ return;
+}
+
+
+BOOL APIENTRY DllMain(HMODULE module, DWORD reason_for_call, LPVOID reserved) {
+ g_hmodule = module;
+ if (reason_for_call == DLL_PROCESS_ATTACH) {
+ // On windows following handlers work only inside module. So breakpad in
+ // chrome.dll does not catch that. To avoid linking related code or
+ // duplication breakpad_win.cc::InitCrashReporter() just catch errors here
+ // and crash in a way interceptable by breakpad of parent module.
+ _set_invalid_parameter_handler(HandleInvalidParameter);
+ _set_purecall_handler(HandlePureVirtualCall);
+ }
+ return TRUE;
+}
+
+#endif
+
+namespace pp {
+
+PDF_USED Module* CreateModule() {
+ return new chrome_pdf::PDFModule();
+}
+
+} // namespace pp
+
+namespace chrome_pdf {
+
+PDFModule::PDFModule() {
+}
+
+PDFModule::~PDFModule() {
+ if (g_sdk_initialized_via_pepper) {
+ chrome_pdf::ShutdownSDK();
+ g_sdk_initialized_via_pepper = false;
+ }
+}
+
+bool PDFModule::Init() {
+ return true;
+}
+
+pp::Instance* PDFModule::CreateInstance(PP_Instance instance) {
+ if (!g_sdk_initialized_via_pepper) {
+ void* data = NULL;
+#if defined(OS_WIN)
+ data = g_hmodule;
+#endif
+ if (!chrome_pdf::InitializeSDK(data))
+ return NULL;
+ g_sdk_initialized_via_pepper = true;
+ }
+
+ if (pp::PDF::IsOutOfProcess(pp::InstanceHandle(instance)))
+ return new OutOfProcessInstance(instance);
+ return new Instance(instance);
+}
+
+} // namespace chrome_pdf
+
+extern "C" {
+
+// TODO(sanjeevr): It might make sense to provide more stateful wrappers over
+// the internal PDF SDK (such as LoadDocument, LoadPage etc). Determine if we
+// need to provide this.
+// Wrapper exports over the PDF engine that can be used by an external module
+// such as Chrome (since Chrome cannot directly pull in PDFium sources).
+#if defined(OS_WIN)
+// |pdf_buffer| is the buffer that contains the entire PDF document to be
+// rendered.
+// |buffer_size| is the size of |pdf_buffer| in bytes.
+// |page_number| is the 0-based index of the page to be rendered.
+// |dc| is the device context to render into.
+// |dpi_x| and |dpi_y| are the x and y resolutions respectively. If either
+// value is -1, the dpi from the DC will be used.
+// |bounds_origin_x|, |bounds_origin_y|, |bounds_width| and |bounds_height|
+// specify a bounds rectangle within the DC in which to render the PDF
+// page.
+// |fit_to_bounds| specifies whether the output should be shrunk to fit the
+// supplied bounds if the page size is larger than the bounds in any
+// dimension. If this is false, parts of the PDF page that lie outside
+// the bounds will be clipped.
+// |stretch_to_bounds| specifies whether the output should be stretched to fit
+// the supplied bounds if the page size is smaller than the bounds in any
+// dimension.
+// If both |fit_to_bounds| and |stretch_to_bounds| are true, then
+// |fit_to_bounds| is honored first.
+// |keep_aspect_ratio| If any scaling is to be done is true, this flag
+// specifies whether the original aspect ratio of the page should be
+// preserved while scaling.
+// |center_in_bounds| specifies whether the final image (after any scaling is
+// done) should be centered within the given bounds.
+// |autorotate| specifies whether the final image should be rotated to match
+// the output bound.
+// Returns false if the document or the page number are not valid.
+PP_EXPORT bool RenderPDFPageToDC(const void* pdf_buffer,
+ int buffer_size,
+ int page_number,
+ HDC dc,
+ int dpi_x,
+ int dpi_y,
+ int bounds_origin_x,
+ int bounds_origin_y,
+ int bounds_width,
+ int bounds_height,
+ bool fit_to_bounds,
+ bool stretch_to_bounds,
+ bool keep_aspect_ratio,
+ bool center_in_bounds,
+ bool autorotate) {
+ if (!g_sdk_initialized_via_pepper) {
+ if (!chrome_pdf::InitializeSDK(g_hmodule)) {
+ return false;
+ }
+ }
+ scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports(
+ chrome_pdf::PDFEngineExports::Create());
+ chrome_pdf::PDFEngineExports::RenderingSettings settings(
+ dpi_x, dpi_y, pp::Rect(bounds_origin_x, bounds_origin_y, bounds_width,
+ bounds_height),
+ fit_to_bounds, stretch_to_bounds, keep_aspect_ratio, center_in_bounds,
+ autorotate);
+ bool ret = engine_exports->RenderPDFPageToDC(pdf_buffer, buffer_size,
+ page_number, settings, dc);
+ if (!g_sdk_initialized_via_pepper) {
+ chrome_pdf::ShutdownSDK();
+ }
+ return ret;
+}
+
+#endif // OS_WIN
+
+// |page_count| and |max_page_width| are optional and can be NULL.
+// Returns false if the document is not valid.
+PDF_USED PP_EXPORT
+bool GetPDFDocInfo(const void* pdf_buffer,
+ int buffer_size, int* page_count,
+ double* max_page_width) {
+ if (!g_sdk_initialized_via_pepper) {
+ void* data = NULL;
+#if defined(OS_WIN)
+ data = g_hmodule;
+#endif
+ if (!chrome_pdf::InitializeSDK(data))
+ return false;
+ }
+ scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports(
+ chrome_pdf::PDFEngineExports::Create());
+ bool ret = engine_exports->GetPDFDocInfo(
+ pdf_buffer, buffer_size, page_count, max_page_width);
+ if (!g_sdk_initialized_via_pepper) {
+ chrome_pdf::ShutdownSDK();
+ }
+ return ret;
+}
+
+// Gets the dimensions of a specific page in a document.
+// |pdf_buffer| is the buffer that contains the entire PDF document to be
+// rendered.
+// |pdf_buffer_size| is the size of |pdf_buffer| in bytes.
+// |page_number| is the page number that the function will get the dimensions
+// of.
+// |width| is the output for the width of the page in points.
+// |height| is the output for the height of the page in points.
+// Returns false if the document or the page number are not valid.
+PDF_USED PP_EXPORT
+bool GetPDFPageSizeByIndex(const void* pdf_buffer,
+ int pdf_buffer_size, int page_number,
+ double* width, double* height) {
+ if (!g_sdk_initialized_via_pepper) {
+ void* data = NULL;
+#if defined(OS_WIN)
+ data = g_hmodule;
+#endif
+ if (!chrome_pdf::InitializeSDK(data))
+ return false;
+ }
+ scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports(
+ chrome_pdf::PDFEngineExports::Create());
+ bool ret = engine_exports->GetPDFPageSizeByIndex(
+ pdf_buffer, pdf_buffer_size, page_number, width, height);
+ if (!g_sdk_initialized_via_pepper)
+ chrome_pdf::ShutdownSDK();
+ return ret;
+}
+
+// Renders PDF page into 4-byte per pixel BGRA color bitmap.
+// |pdf_buffer| is the buffer that contains the entire PDF document to be
+// rendered.
+// |pdf_buffer_size| is the size of |pdf_buffer| in bytes.
+// |page_number| is the 0-based index of the page to be rendered.
+// |bitmap_buffer| is the output buffer for bitmap.
+// |bitmap_width| is the width of the output bitmap.
+// |bitmap_height| is the height of the output bitmap.
+// |dpi| is the resolutions.
+// |autorotate| specifies whether the final image should be rotated to match
+// the output bound.
+// Returns false if the document or the page number are not valid.
+PDF_USED PP_EXPORT
+bool RenderPDFPageToBitmap(const void* pdf_buffer,
+ int pdf_buffer_size,
+ int page_number,
+ void* bitmap_buffer,
+ int bitmap_width,
+ int bitmap_height,
+ int dpi,
+ bool autorotate) {
+ if (!g_sdk_initialized_via_pepper) {
+ void* data = NULL;
+#if defined(OS_WIN)
+ data = g_hmodule;
+#endif
+ if (!chrome_pdf::InitializeSDK(data))
+ return false;
+ }
+ scoped_ptr<chrome_pdf::PDFEngineExports> engine_exports(
+ chrome_pdf::PDFEngineExports::Create());
+ chrome_pdf::PDFEngineExports::RenderingSettings settings(
+ dpi, dpi, pp::Rect(bitmap_width, bitmap_height), true, false, true, true,
+ autorotate);
+ bool ret = engine_exports->RenderPDFPageToBitmap(
+ pdf_buffer, pdf_buffer_size, page_number, settings, bitmap_buffer);
+ if (!g_sdk_initialized_via_pepper) {
+ chrome_pdf::ShutdownSDK();
+ }
+ return ret;
+}
+
+} // extern "C"
diff --git a/xfa_test/pdf/pdf.def b/xfa_test/pdf/pdf.def
new file mode 100644
index 0000000000..b36918bb27
--- /dev/null
+++ b/xfa_test/pdf/pdf.def
@@ -0,0 +1,7 @@
+LIBRARY pdf
+
+EXPORTS
+ NP_GetEntryPoints @1
+ NP_Initialize @2
+ NP_Shutdown @3
+
diff --git a/xfa_test/pdf/pdf.gyp b/xfa_test/pdf/pdf.gyp
new file mode 100644
index 0000000000..f1e8e3e658
--- /dev/null
+++ b/xfa_test/pdf/pdf.gyp
@@ -0,0 +1,200 @@
+{
+ 'variables': {
+ 'chromium_code': 1,
+ 'pdf_engine%': 0, # 0 PDFium
+ },
+ 'target_defaults': {
+ 'cflags': [
+ '-fPIC',
+ ],
+ },
+ 'targets': [
+ {
+ 'target_name': 'pdf',
+ 'type': 'loadable_module',
+ 'msvs_guid': '647863C0-C7A3-469A-B1ED-AD7283C34BED',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../net/net.gyp:net',
+ '../ppapi/ppapi.gyp:ppapi_cpp',
+ '../third_party/pdfium/pdfium.gyp:pdfium',
+ ],
+ 'xcode_settings': {
+ 'INFOPLIST_FILE': 'Info.plist',
+ },
+ 'mac_framework_dirs': [
+ '$(SDKROOT)/System/Library/Frameworks/ApplicationServices.framework/Frameworks',
+ ],
+ 'ldflags': [ '-L<(PRODUCT_DIR)',],
+ 'sources': [
+ 'button.h',
+ 'button.cc',
+ 'chunk_stream.h',
+ 'chunk_stream.cc',
+ 'control.h',
+ 'control.cc',
+ 'document_loader.h',
+ 'document_loader.cc',
+ 'draw_utils.cc',
+ 'draw_utils.h',
+ 'fading_control.cc',
+ 'fading_control.h',
+ 'fading_controls.cc',
+ 'fading_controls.h',
+ 'instance.cc',
+ 'instance.h',
+ 'number_image_generator.cc',
+ 'number_image_generator.h',
+ 'out_of_process_instance.cc',
+ 'out_of_process_instance.h',
+ 'page_indicator.cc',
+ 'page_indicator.h',
+ 'paint_aggregator.cc',
+ 'paint_aggregator.h',
+ 'paint_manager.cc',
+ 'paint_manager.h',
+ 'pdf.cc',
+ 'pdf.h',
+ 'pdf.rc',
+ 'progress_control.cc',
+ 'progress_control.h',
+ 'pdf_engine.h',
+ 'preview_mode_client.cc',
+ 'preview_mode_client.h',
+ 'resource.h',
+ 'resource_consts.h',
+ 'thumbnail_control.cc',
+ 'thumbnail_control.h',
+ '../chrome/browser/chrome_page_zoom_constants.cc',
+ '../content/common/page_zoom.cc',
+ ],
+ 'conditions': [
+ ['pdf_engine==0', {
+ 'sources': [
+ 'pdfium/pdfium_assert_matching_enums.cc',
+ 'pdfium/pdfium_engine.cc',
+ 'pdfium/pdfium_engine.h',
+ 'pdfium/pdfium_mem_buffer_file_read.cc',
+ 'pdfium/pdfium_mem_buffer_file_read.h',
+ 'pdfium/pdfium_mem_buffer_file_write.cc',
+ 'pdfium/pdfium_mem_buffer_file_write.h',
+ 'pdfium/pdfium_page.cc',
+ 'pdfium/pdfium_page.h',
+ 'pdfium/pdfium_range.cc',
+ 'pdfium/pdfium_range.h',
+ ],
+ }],
+ ['OS!="win"', {
+ 'sources!': [
+ 'pdf.rc',
+ ],
+ }],
+ ['OS=="mac"', {
+ 'mac_bundle': 1,
+ 'product_name': 'PDF',
+ 'product_extension': 'plugin',
+ # Strip the shipping binary of symbols so "Foxit" doesn't appear in
+ # the binary. Symbols are stored in a separate .dSYM.
+ 'variables': {
+ 'mac_real_dsym': 1,
+ },
+ 'sources+': [
+ 'Info.plist'
+ ],
+ }],
+ ['OS=="win"', {
+ 'defines': [
+ 'COMPILE_CONTENT_STATICALLY',
+ ],
+ # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
+ 'msvs_disabled_warnings': [ 4267, ],
+ }],
+ ['OS=="linux"', {
+ 'configurations': {
+ 'Release_Base': {
+ #'cflags': [ '-fno-weak',], # get rid of symbols that strip doesn't remove.
+ # Don't do this for now since official builder will take care of it. That
+ # way symbols can still be uploaded to the crash server.
+ #'ldflags': [ '-s',], # strip local symbols from binary.
+ },
+ },
+ }],
+ ],
+ },
+ ],
+ 'conditions': [
+ # CrOS has a separate step to do this.
+ ['OS=="linux" and chromeos==0',
+ { 'targets': [
+ {
+ 'target_name': 'pdf_linux_symbols',
+ 'type': 'none',
+ 'conditions': [
+ ['linux_dump_symbols==1', {
+ 'actions': [
+ {
+ 'action_name': 'dump_symbols',
+ 'inputs': [
+ '<(DEPTH)/build/linux/dump_app_syms',
+ '<(PRODUCT_DIR)/dump_syms',
+ '<(PRODUCT_DIR)/libpdf.so',
+ ],
+ 'outputs': [
+ '<(PRODUCT_DIR)/libpdf.so.breakpad.<(target_arch)',
+ ],
+ 'action': ['<(DEPTH)/build/linux/dump_app_syms',
+ '<(PRODUCT_DIR)/dump_syms',
+ '<(linux_strip_binary)',
+ '<(PRODUCT_DIR)/libpdf.so',
+ '<@(_outputs)'],
+ 'message': 'Dumping breakpad symbols to <(_outputs)',
+ 'process_outputs_as_sources': 1,
+ },
+ ],
+ 'dependencies': [
+ 'pdf',
+ '../breakpad/breakpad.gyp:dump_syms',
+ ],
+ }],
+ ],
+ },
+ ],
+ },], # OS=="linux" and chromeos==0
+ ['OS=="win" and fastbuild==0 and target_arch=="ia32" and syzyasan==1', {
+ 'variables': {
+ 'dest_dir': '<(PRODUCT_DIR)/syzygy',
+ },
+ 'targets': [
+ {
+ 'target_name': 'pdf_syzyasan',
+ 'type': 'none',
+ 'sources' : [],
+ 'dependencies': [
+ 'pdf',
+ ],
+ # Instrument PDFium with SyzyAsan.
+ 'actions': [
+ {
+ 'action_name': 'Instrument PDFium with SyzyAsan',
+ 'inputs': [
+ '<(PRODUCT_DIR)/pdf.dll',
+ ],
+ 'outputs': [
+ '<(dest_dir)/pdf.dll',
+ '<(dest_dir)/pdf.dll.pdb',
+ ],
+ 'action': [
+ 'python',
+ '<(DEPTH)/chrome/tools/build/win/syzygy_instrument.py',
+ '--mode', 'asan',
+ '--input_executable', '<(PRODUCT_DIR)/pdf.dll',
+ '--input_symbol', '<(PRODUCT_DIR)/pdf.dll.pdb',
+ '--destination_dir', '<(dest_dir)',
+ ],
+ },
+ ],
+ },
+ ],
+ }], # OS=="win" and fastbuild==0 and target_arch=="ia32" and syzyasan==1
+ ],
+}
diff --git a/xfa_test/pdf/pdf.h b/xfa_test/pdf/pdf.h
new file mode 100644
index 0000000000..d797bbbaf5
--- /dev/null
+++ b/xfa_test/pdf/pdf.h
@@ -0,0 +1,24 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PDF_H_
+#define PDF_PDF_H_
+
+#include "ppapi/cpp/module.h"
+
+namespace chrome_pdf {
+
+class PDFModule : public pp::Module {
+ public:
+ PDFModule();
+ virtual ~PDFModule();
+
+ // pp::Module implementation.
+ virtual bool Init();
+ virtual pp::Instance* CreateInstance(PP_Instance instance);
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDF_H_
diff --git a/xfa_test/pdf/pdf.rc b/xfa_test/pdf/pdf.rc
new file mode 100644
index 0000000000..cbc98e1e4b
--- /dev/null
+++ b/xfa_test/pdf/pdf.rc
@@ -0,0 +1,104 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904e4"
+ BEGIN
+ VALUE "FileDescription", "Chrome PDF Viewer"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "pdf"
+ VALUE "LegalCopyright", "Copyright (C) 2010"
+ VALUE "MIMEType", "application/pdf"
+ VALUE "FileExtents", "pdf"
+ VALUE "FileOpenName", "Acrobat Portable Document Format"
+ VALUE "OriginalFilename", "pdf.dll"
+ VALUE "ProductName", "Chrome PDF Viewer"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1252
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/xfa_test/pdf/pdf_engine.h b/xfa_test/pdf/pdf_engine.h
new file mode 100644
index 0000000000..cc25a299d8
--- /dev/null
+++ b/xfa_test/pdf/pdf_engine.h
@@ -0,0 +1,321 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PDF_ENGINE_H_
+#define PDF_PDF_ENGINE_H_
+
+#include "build/build_config.h"
+
+#if defined(OS_WIN)
+#include <windows.h>
+#endif
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+
+#include "ppapi/c/dev/pp_cursor_type_dev.h"
+#include "ppapi/c/dev/ppp_printing_dev.h"
+#include "ppapi/c/ppb_input_event.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/rect.h"
+#include "ppapi/cpp/size.h"
+#include "ppapi/cpp/url_loader.h"
+
+namespace pp {
+class InputEvent;
+}
+
+const uint32 kBackgroundColor = 0xFFCCCCCC;
+
+namespace chrome_pdf {
+
+class Stream;
+
+#if defined(OS_MACOSX)
+const uint32 kDefaultKeyModifier = PP_INPUTEVENT_MODIFIER_METAKEY;
+#else // !OS_MACOSX
+const uint32 kDefaultKeyModifier = PP_INPUTEVENT_MODIFIER_CONTROLKEY;
+#endif // OS_MACOSX
+
+// Do one time initialization of the SDK. data is platform specific, on Windows
+// it's the instance of the DLL and it's unused on other platforms.
+bool InitializeSDK(void* data);
+// Tells the SDK that we're shutting down.
+void ShutdownSDK();
+
+// This class encapsulates a PDF rendering engine.
+class PDFEngine {
+ public:
+
+ enum DocumentPermission {
+ PERMISSION_COPY,
+ PERMISSION_COPY_ACCESSIBLE,
+ PERMISSION_PRINT_LOW_QUALITY,
+ PERMISSION_PRINT_HIGH_QUALITY,
+ };
+
+ // The interface that's provided to the rendering engine.
+ class Client {
+ public:
+ // Informs the client about the document's size in pixels.
+ virtual void DocumentSizeUpdated(const pp::Size& size) = 0;
+
+ // Informs the client that the given rect needs to be repainted.
+ virtual void Invalidate(const pp::Rect& rect) = 0;
+
+ // Informs the client to scroll the plugin area by the given offset.
+ virtual void Scroll(const pp::Point& point) = 0;
+
+ // Scroll the horizontal/vertical scrollbars to a given position.
+ virtual void ScrollToX(int position) = 0;
+ virtual void ScrollToY(int position) = 0;
+
+ // Scroll to the specified page.
+ virtual void ScrollToPage(int page) = 0;
+
+ // Navigate to the given url.
+ virtual void NavigateTo(const std::string& url, bool open_in_new_tab) = 0;
+
+ // Updates the cursor.
+ virtual void UpdateCursor(PP_CursorType_Dev cursor) = 0;
+
+ // Updates the tick marks in the vertical scrollbar.
+ virtual void UpdateTickMarks(const std::vector<pp::Rect>& tickmarks) = 0;
+
+ // Updates the number of find results for the current search term. If
+ // there are no matches 0 should be passed in. Only when the plugin has
+ // finished searching should it pass in the final count with final_result
+ // set to true.
+ virtual void NotifyNumberOfFindResultsChanged(int total,
+ bool final_result) = 0;
+
+ // Updates the index of the currently selected search item.
+ virtual void NotifySelectedFindResultChanged(int current_find_index) = 0;
+
+ // Prompts the user for a password to open this document. The callback is
+ // called when the password is retrieved.
+ virtual void GetDocumentPassword(
+ pp::CompletionCallbackWithOutput<pp::Var> callback) = 0;
+
+ // Puts up an alert with the given message.
+ virtual void Alert(const std::string& message) = 0;
+
+ // Puts up a confirm with the given message, and returns true if the user
+ // presses OK, or false if they press cancel.
+ virtual bool Confirm(const std::string& message) = 0;
+
+ // Puts up a prompt with the given message and default answer and returns
+ // the answer.
+ virtual std::string Prompt(const std::string& question,
+ const std::string& default_answer) = 0;
+
+ // Returns the url of the pdf.
+ virtual std::string GetURL() = 0;
+
+ // Send an email.
+ virtual void Email(const std::string& to,
+ const std::string& cc,
+ const std::string& bcc,
+ const std::string& subject,
+ const std::string& body) = 0;
+ // Put up the print dialog.
+ virtual void Print() = 0;
+
+ // Submit the data using HTTP POST.
+ virtual void SubmitForm(const std::string& url,
+ const void* data,
+ int length) = 0;
+
+ // Pops up a file selection dialog and returns the result.
+ virtual std::string ShowFileSelectionDialog() = 0;
+
+ // Creates and returns new URL loader for partial document requests.
+ virtual pp::URLLoader CreateURLLoader() = 0;
+
+ // Calls the client's OnCallback() function in delay_in_ms with the given
+ // id.
+ virtual void ScheduleCallback(int id, int delay_in_ms) = 0;
+
+ // Searches the given string for "term" and returns the results. Unicode-
+ // aware.
+ struct SearchStringResult {
+ int start_index;
+ int length;
+ };
+ virtual void SearchString(const base::char16* string,
+ const base::char16* term,
+ bool case_sensitive,
+ std::vector<SearchStringResult>* results) = 0;
+
+ // Notifies the client that the engine has painted a page from the document.
+ virtual void DocumentPaintOccurred() = 0;
+
+ // Notifies the client that the document has finished loading.
+ virtual void DocumentLoadComplete(int page_count) = 0;
+
+ // Notifies the client that the document has failed to load.
+ virtual void DocumentLoadFailed() = 0;
+
+ virtual pp::Instance* GetPluginInstance() = 0;
+
+ // Notifies that an unsupported feature in the PDF was encountered.
+ virtual void DocumentHasUnsupportedFeature(const std::string& feature) = 0;
+
+ // Notifies the client about document load progress.
+ virtual void DocumentLoadProgress(uint32 available, uint32 doc_size) = 0;
+
+ // Notifies the client about focus changes for form text fields.
+ virtual void FormTextFieldFocusChange(bool in_focus) = 0;
+
+ // Returns true if the plugin has been opened within print preview.
+ virtual bool IsPrintPreview() = 0;
+ };
+
+ // Factory method to create an instance of the PDF Engine.
+ static PDFEngine* Create(Client* client);
+
+ virtual ~PDFEngine() {}
+ // Most of these functions are similar to the Pepper functions of the same
+ // name, so not repeating the description here unless it's different.
+ virtual bool New(const char* url) = 0;
+ virtual bool New(const char* url,
+ const char* headers) = 0;
+ virtual void PageOffsetUpdated(const pp::Point& page_offset) = 0;
+ virtual void PluginSizeUpdated(const pp::Size& size) = 0;
+ virtual void ScrolledToXPosition(int position) = 0;
+ virtual void ScrolledToYPosition(int position) = 0;
+ // Paint is called a series of times. Before these n calls are made, PrePaint
+ // is called once. After Paint is called n times, PostPaint is called once.
+ virtual void PrePaint() = 0;
+ virtual void Paint(const pp::Rect& rect,
+ pp::ImageData* image_data,
+ std::vector<pp::Rect>* ready,
+ std::vector<pp::Rect>* pending) = 0;
+ virtual void PostPaint() = 0;
+ virtual bool HandleDocumentLoad(const pp::URLLoader& loader) = 0;
+ virtual bool HandleEvent(const pp::InputEvent& event) = 0;
+ virtual uint32_t QuerySupportedPrintOutputFormats() = 0;
+ virtual void PrintBegin() = 0;
+ virtual pp::Resource PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count,
+ const PP_PrintSettings_Dev& print_settings) = 0;
+ virtual void PrintEnd() = 0;
+ virtual void StartFind(const char* text, bool case_sensitive) = 0;
+ virtual bool SelectFindResult(bool forward) = 0;
+ virtual void StopFind() = 0;
+ virtual void ZoomUpdated(double new_zoom_level) = 0;
+ virtual void RotateClockwise() = 0;
+ virtual void RotateCounterclockwise() = 0;
+ virtual std::string GetSelectedText() = 0;
+ virtual std::string GetLinkAtPosition(const pp::Point& point) = 0;
+ virtual bool IsSelecting() = 0;
+ // Checks the permissions associated with this document.
+ virtual bool HasPermission(DocumentPermission permission) const = 0;
+ virtual void SelectAll() = 0;
+ // Gets the number of pages in the document.
+ virtual int GetNumberOfPages() = 0;
+ // Gets the 0-based page number of |destination|, or -1 if it does not exist.
+ virtual int GetNamedDestinationPage(const std::string& destination) = 0;
+ // Gets the index of the first visible page, or -1 if none are visible.
+ virtual int GetFirstVisiblePage() = 0;
+ // Gets the index of the most visible page, or -1 if none are visible.
+ virtual int GetMostVisiblePage() = 0;
+ // Gets the rectangle of the page including shadow.
+ virtual pp::Rect GetPageRect(int index) = 0;
+ // Gets the rectangle of the page excluding any additional areas.
+ virtual pp::Rect GetPageContentsRect(int index) = 0;
+ // Gets the offset of the vertical scrollbar from the top in document
+ // coordinates.
+ virtual int GetVerticalScrollbarYPosition() = 0;
+ // Paints page thumbnail to the ImageData.
+ virtual void PaintThumbnail(pp::ImageData* image_data, int index) = 0;
+ // Set color / grayscale rendering modes.
+ virtual void SetGrayscale(bool grayscale) = 0;
+ // Callback for timer that's set with ScheduleCallback().
+ virtual void OnCallback(int id) = 0;
+ // Gets the JSON representation of the PDF file
+ virtual std::string GetPageAsJSON(int index) = 0;
+ // Gets the PDF document's print scaling preference. True if the document can
+ // be scaled to fit.
+ virtual bool GetPrintScaling() = 0;
+
+ // Append blank pages to make a 1-page document to a |num_pages| document.
+ // Always retain the first page data.
+ virtual void AppendBlankPages(int num_pages) = 0;
+ // Append the first page of the document loaded with the |engine| to this
+ // document at page |index|.
+ virtual void AppendPage(PDFEngine* engine, int index) = 0;
+
+ // Allow client to query and reset scroll positions in document coordinates.
+ // Note that this is meant for cases where the device scale factor changes,
+ // and not for general scrolling - the engine will not repaint due to this.
+ virtual pp::Point GetScrollPosition() = 0;
+ virtual void SetScrollPosition(const pp::Point& position) = 0;
+
+ virtual bool IsProgressiveLoad() = 0;
+};
+
+// Interface for exports that wrap the PDF engine.
+class PDFEngineExports {
+ public:
+ struct RenderingSettings {
+ RenderingSettings(int dpi_x,
+ int dpi_y,
+ const pp::Rect& bounds,
+ bool fit_to_bounds,
+ bool stretch_to_bounds,
+ bool keep_aspect_ratio,
+ bool center_in_bounds,
+ bool autorotate)
+ : dpi_x(dpi_x), dpi_y(dpi_y), bounds(bounds),
+ fit_to_bounds(fit_to_bounds), stretch_to_bounds(stretch_to_bounds),
+ keep_aspect_ratio(keep_aspect_ratio),
+ center_in_bounds(center_in_bounds), autorotate(autorotate) {
+ }
+ int dpi_x;
+ int dpi_y;
+ pp::Rect bounds;
+ bool fit_to_bounds;
+ bool stretch_to_bounds;
+ bool keep_aspect_ratio;
+ bool center_in_bounds;
+ bool autorotate;
+ };
+
+ PDFEngineExports() {}
+ virtual ~PDFEngineExports() {}
+ static PDFEngineExports* Create();
+#if defined(OS_WIN)
+ // See the definition of RenderPDFPageToDC in pdf.cc for details.
+ virtual bool RenderPDFPageToDC(const void* pdf_buffer,
+ int buffer_size,
+ int page_number,
+ const RenderingSettings& settings,
+ HDC dc) = 0;
+#endif // OS_WIN
+ // See the definition of RenderPDFPageToBitmap in pdf.cc for details.
+ virtual bool RenderPDFPageToBitmap(const void* pdf_buffer,
+ int pdf_buffer_size,
+ int page_number,
+ const RenderingSettings& settings,
+ void* bitmap_buffer) = 0;
+
+ virtual bool GetPDFDocInfo(const void* pdf_buffer,
+ int buffer_size,
+ int* page_count,
+ double* max_page_width) = 0;
+
+ // See the definition of GetPDFPageSizeByIndex in pdf.cc for details.
+ virtual bool GetPDFPageSizeByIndex(const void* pdf_buffer,
+ int pdf_buffer_size, int page_number,
+ double* width, double* height) = 0;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDF_ENGINE_H_
diff --git a/xfa_test/pdf/pdfium/pdfium_assert_matching_enums.cc b/xfa_test/pdf/pdfium/pdfium_assert_matching_enums.cc
new file mode 100644
index 0000000000..ef140cf7c9
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_assert_matching_enums.cc
@@ -0,0 +1,207 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "ppapi/c/pp_input_event.h"
+#include "ppapi/c/private/ppb_pdf.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_fwlevent.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_sysfontinfo.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+#define COMPILE_ASSERT_MATCH(np_name, pdfium_name) \
+ COMPILE_ASSERT(int(np_name) == int(pdfium_name), mismatching_enums)
+
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_SHIFTKEY, FWL_EVENTFLAG_ShiftKey);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_CONTROLKEY,
+ FWL_EVENTFLAG_ControlKey);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_ALTKEY, FWL_EVENTFLAG_AltKey);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_METAKEY, FWL_EVENTFLAG_MetaKey);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_ISKEYPAD, FWL_EVENTFLAG_KeyPad);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT,
+ FWL_EVENTFLAG_AutoRepeat);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_LEFTBUTTONDOWN,
+ FWL_EVENTFLAG_LeftButtonDown);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_MIDDLEBUTTONDOWN,
+ FWL_EVENTFLAG_MiddleButtonDown);
+COMPILE_ASSERT_MATCH(PP_INPUTEVENT_MODIFIER_RIGHTBUTTONDOWN,
+ FWL_EVENTFLAG_RightButtonDown);
+
+COMPILE_ASSERT_MATCH(ui::VKEY_BACK, FWL_VKEY_Back);
+COMPILE_ASSERT_MATCH(ui::VKEY_TAB, FWL_VKEY_Tab);
+COMPILE_ASSERT_MATCH(ui::VKEY_CLEAR, FWL_VKEY_Clear);
+COMPILE_ASSERT_MATCH(ui::VKEY_RETURN, FWL_VKEY_Return);
+COMPILE_ASSERT_MATCH(ui::VKEY_SHIFT, FWL_VKEY_Shift);
+COMPILE_ASSERT_MATCH(ui::VKEY_CONTROL, FWL_VKEY_Control);
+COMPILE_ASSERT_MATCH(ui::VKEY_MENU, FWL_VKEY_Menu);
+COMPILE_ASSERT_MATCH(ui::VKEY_PAUSE, FWL_VKEY_Pause);
+COMPILE_ASSERT_MATCH(ui::VKEY_CAPITAL, FWL_VKEY_Capital);
+COMPILE_ASSERT_MATCH(ui::VKEY_KANA, FWL_VKEY_Kana);
+COMPILE_ASSERT_MATCH(ui::VKEY_HANGUL, FWL_VKEY_Hangul);
+COMPILE_ASSERT_MATCH(ui::VKEY_JUNJA, FWL_VKEY_Junja);
+COMPILE_ASSERT_MATCH(ui::VKEY_FINAL, FWL_VKEY_Final);
+COMPILE_ASSERT_MATCH(ui::VKEY_HANJA, FWL_VKEY_Hanja);
+COMPILE_ASSERT_MATCH(ui::VKEY_KANJI, FWL_VKEY_Kanji);
+COMPILE_ASSERT_MATCH(ui::VKEY_ESCAPE, FWL_VKEY_Escape);
+COMPILE_ASSERT_MATCH(ui::VKEY_CONVERT, FWL_VKEY_Convert);
+COMPILE_ASSERT_MATCH(ui::VKEY_NONCONVERT, FWL_VKEY_NonConvert);
+COMPILE_ASSERT_MATCH(ui::VKEY_ACCEPT, FWL_VKEY_Accept);
+COMPILE_ASSERT_MATCH(ui::VKEY_MODECHANGE, FWL_VKEY_ModeChange);
+COMPILE_ASSERT_MATCH(ui::VKEY_SPACE, FWL_VKEY_Space);
+COMPILE_ASSERT_MATCH(ui::VKEY_PRIOR, FWL_VKEY_Prior);
+COMPILE_ASSERT_MATCH(ui::VKEY_NEXT, FWL_VKEY_Next);
+COMPILE_ASSERT_MATCH(ui::VKEY_END, FWL_VKEY_End);
+COMPILE_ASSERT_MATCH(ui::VKEY_HOME, FWL_VKEY_Home);
+COMPILE_ASSERT_MATCH(ui::VKEY_LEFT, FWL_VKEY_Left);
+COMPILE_ASSERT_MATCH(ui::VKEY_UP, FWL_VKEY_Up);
+COMPILE_ASSERT_MATCH(ui::VKEY_RIGHT, FWL_VKEY_Right);
+COMPILE_ASSERT_MATCH(ui::VKEY_DOWN, FWL_VKEY_Down);
+COMPILE_ASSERT_MATCH(ui::VKEY_SELECT, FWL_VKEY_Select);
+COMPILE_ASSERT_MATCH(ui::VKEY_PRINT, FWL_VKEY_Print);
+COMPILE_ASSERT_MATCH(ui::VKEY_EXECUTE, FWL_VKEY_Execute);
+COMPILE_ASSERT_MATCH(ui::VKEY_SNAPSHOT, FWL_VKEY_Snapshot);
+COMPILE_ASSERT_MATCH(ui::VKEY_INSERT, FWL_VKEY_Insert);
+COMPILE_ASSERT_MATCH(ui::VKEY_DELETE, FWL_VKEY_Delete);
+COMPILE_ASSERT_MATCH(ui::VKEY_HELP, FWL_VKEY_Help);
+COMPILE_ASSERT_MATCH(ui::VKEY_0, FWL_VKEY_0);
+COMPILE_ASSERT_MATCH(ui::VKEY_1, FWL_VKEY_1);
+COMPILE_ASSERT_MATCH(ui::VKEY_2, FWL_VKEY_2);
+COMPILE_ASSERT_MATCH(ui::VKEY_3, FWL_VKEY_3);
+COMPILE_ASSERT_MATCH(ui::VKEY_4, FWL_VKEY_4);
+COMPILE_ASSERT_MATCH(ui::VKEY_5, FWL_VKEY_5);
+COMPILE_ASSERT_MATCH(ui::VKEY_6, FWL_VKEY_6);
+COMPILE_ASSERT_MATCH(ui::VKEY_7, FWL_VKEY_7);
+COMPILE_ASSERT_MATCH(ui::VKEY_8, FWL_VKEY_8);
+COMPILE_ASSERT_MATCH(ui::VKEY_9, FWL_VKEY_9);
+COMPILE_ASSERT_MATCH(ui::VKEY_A, FWL_VKEY_A);
+COMPILE_ASSERT_MATCH(ui::VKEY_B, FWL_VKEY_B);
+COMPILE_ASSERT_MATCH(ui::VKEY_C, FWL_VKEY_C);
+COMPILE_ASSERT_MATCH(ui::VKEY_D, FWL_VKEY_D);
+COMPILE_ASSERT_MATCH(ui::VKEY_E, FWL_VKEY_E);
+COMPILE_ASSERT_MATCH(ui::VKEY_F, FWL_VKEY_F);
+COMPILE_ASSERT_MATCH(ui::VKEY_G, FWL_VKEY_G);
+COMPILE_ASSERT_MATCH(ui::VKEY_H, FWL_VKEY_H);
+COMPILE_ASSERT_MATCH(ui::VKEY_I, FWL_VKEY_I);
+COMPILE_ASSERT_MATCH(ui::VKEY_J, FWL_VKEY_J);
+COMPILE_ASSERT_MATCH(ui::VKEY_K, FWL_VKEY_K);
+COMPILE_ASSERT_MATCH(ui::VKEY_L, FWL_VKEY_L);
+COMPILE_ASSERT_MATCH(ui::VKEY_M, FWL_VKEY_M);
+COMPILE_ASSERT_MATCH(ui::VKEY_N, FWL_VKEY_N);
+COMPILE_ASSERT_MATCH(ui::VKEY_O, FWL_VKEY_O);
+COMPILE_ASSERT_MATCH(ui::VKEY_P, FWL_VKEY_P);
+COMPILE_ASSERT_MATCH(ui::VKEY_Q, FWL_VKEY_Q);
+COMPILE_ASSERT_MATCH(ui::VKEY_R, FWL_VKEY_R);
+COMPILE_ASSERT_MATCH(ui::VKEY_S, FWL_VKEY_S);
+COMPILE_ASSERT_MATCH(ui::VKEY_T, FWL_VKEY_T);
+COMPILE_ASSERT_MATCH(ui::VKEY_U, FWL_VKEY_U);
+COMPILE_ASSERT_MATCH(ui::VKEY_V, FWL_VKEY_V);
+COMPILE_ASSERT_MATCH(ui::VKEY_W, FWL_VKEY_W);
+COMPILE_ASSERT_MATCH(ui::VKEY_X, FWL_VKEY_X);
+COMPILE_ASSERT_MATCH(ui::VKEY_Y, FWL_VKEY_Y);
+COMPILE_ASSERT_MATCH(ui::VKEY_Z, FWL_VKEY_Z);
+COMPILE_ASSERT_MATCH(ui::VKEY_LWIN, FWL_VKEY_LWin);
+COMPILE_ASSERT_MATCH(ui::VKEY_COMMAND, FWL_VKEY_Command);
+COMPILE_ASSERT_MATCH(ui::VKEY_RWIN, FWL_VKEY_RWin);
+COMPILE_ASSERT_MATCH(ui::VKEY_APPS, FWL_VKEY_Apps);
+COMPILE_ASSERT_MATCH(ui::VKEY_SLEEP, FWL_VKEY_Sleep);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD0, FWL_VKEY_NumPad0);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD1, FWL_VKEY_NumPad1);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD2, FWL_VKEY_NumPad2);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD3, FWL_VKEY_NumPad3);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD4, FWL_VKEY_NumPad4);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD5, FWL_VKEY_NumPad5);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD6, FWL_VKEY_NumPad6);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD7, FWL_VKEY_NumPad7);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD8, FWL_VKEY_NumPad8);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMPAD9, FWL_VKEY_NumPad9);
+COMPILE_ASSERT_MATCH(ui::VKEY_MULTIPLY, FWL_VKEY_Multiply);
+COMPILE_ASSERT_MATCH(ui::VKEY_ADD, FWL_VKEY_Add);
+COMPILE_ASSERT_MATCH(ui::VKEY_SEPARATOR, FWL_VKEY_Separator);
+COMPILE_ASSERT_MATCH(ui::VKEY_SUBTRACT, FWL_VKEY_Subtract);
+COMPILE_ASSERT_MATCH(ui::VKEY_DECIMAL, FWL_VKEY_Decimal);
+COMPILE_ASSERT_MATCH(ui::VKEY_DIVIDE, FWL_VKEY_Divide);
+COMPILE_ASSERT_MATCH(ui::VKEY_F1, FWL_VKEY_F1);
+COMPILE_ASSERT_MATCH(ui::VKEY_F2, FWL_VKEY_F2);
+COMPILE_ASSERT_MATCH(ui::VKEY_F3, FWL_VKEY_F3);
+COMPILE_ASSERT_MATCH(ui::VKEY_F4, FWL_VKEY_F4);
+COMPILE_ASSERT_MATCH(ui::VKEY_F5, FWL_VKEY_F5);
+COMPILE_ASSERT_MATCH(ui::VKEY_F6, FWL_VKEY_F6);
+COMPILE_ASSERT_MATCH(ui::VKEY_F7, FWL_VKEY_F7);
+COMPILE_ASSERT_MATCH(ui::VKEY_F8, FWL_VKEY_F8);
+COMPILE_ASSERT_MATCH(ui::VKEY_F9, FWL_VKEY_F9);
+COMPILE_ASSERT_MATCH(ui::VKEY_F10, FWL_VKEY_F10);
+COMPILE_ASSERT_MATCH(ui::VKEY_F11, FWL_VKEY_F11);
+COMPILE_ASSERT_MATCH(ui::VKEY_F12, FWL_VKEY_F12);
+COMPILE_ASSERT_MATCH(ui::VKEY_F13, FWL_VKEY_F13);
+COMPILE_ASSERT_MATCH(ui::VKEY_F14, FWL_VKEY_F14);
+COMPILE_ASSERT_MATCH(ui::VKEY_F15, FWL_VKEY_F15);
+COMPILE_ASSERT_MATCH(ui::VKEY_F16, FWL_VKEY_F16);
+COMPILE_ASSERT_MATCH(ui::VKEY_F17, FWL_VKEY_F17);
+COMPILE_ASSERT_MATCH(ui::VKEY_F18, FWL_VKEY_F18);
+COMPILE_ASSERT_MATCH(ui::VKEY_F19, FWL_VKEY_F19);
+COMPILE_ASSERT_MATCH(ui::VKEY_F20, FWL_VKEY_F20);
+COMPILE_ASSERT_MATCH(ui::VKEY_F21, FWL_VKEY_F21);
+COMPILE_ASSERT_MATCH(ui::VKEY_F22, FWL_VKEY_F22);
+COMPILE_ASSERT_MATCH(ui::VKEY_F23, FWL_VKEY_F23);
+COMPILE_ASSERT_MATCH(ui::VKEY_F24, FWL_VKEY_F24);
+COMPILE_ASSERT_MATCH(ui::VKEY_NUMLOCK, FWL_VKEY_NunLock);
+COMPILE_ASSERT_MATCH(ui::VKEY_SCROLL, FWL_VKEY_Scroll);
+COMPILE_ASSERT_MATCH(ui::VKEY_LSHIFT, FWL_VKEY_LShift);
+COMPILE_ASSERT_MATCH(ui::VKEY_RSHIFT, FWL_VKEY_RShift);
+COMPILE_ASSERT_MATCH(ui::VKEY_LCONTROL, FWL_VKEY_LControl);
+COMPILE_ASSERT_MATCH(ui::VKEY_RCONTROL, FWL_VKEY_RControl);
+COMPILE_ASSERT_MATCH(ui::VKEY_LMENU, FWL_VKEY_LMenu);
+COMPILE_ASSERT_MATCH(ui::VKEY_RMENU, FWL_VKEY_RMenu);
+COMPILE_ASSERT_MATCH(ui::VKEY_BROWSER_BACK, FWL_VKEY_BROWSER_Back);
+COMPILE_ASSERT_MATCH(ui::VKEY_BROWSER_FORWARD, FWL_VKEY_BROWSER_Forward);
+COMPILE_ASSERT_MATCH(ui::VKEY_BROWSER_REFRESH, FWL_VKEY_BROWSER_Refresh);
+COMPILE_ASSERT_MATCH(ui::VKEY_BROWSER_STOP, FWL_VKEY_BROWSER_Stop);
+COMPILE_ASSERT_MATCH(ui::VKEY_BROWSER_SEARCH, FWL_VKEY_BROWSER_Search);
+COMPILE_ASSERT_MATCH(ui::VKEY_BROWSER_FAVORITES, FWL_VKEY_BROWSER_Favorites);
+COMPILE_ASSERT_MATCH(ui::VKEY_BROWSER_HOME, FWL_VKEY_BROWSER_Home);
+COMPILE_ASSERT_MATCH(ui::VKEY_VOLUME_MUTE, FWL_VKEY_VOLUME_Mute);
+COMPILE_ASSERT_MATCH(ui::VKEY_VOLUME_DOWN, FWL_VKEY_VOLUME_Down);
+COMPILE_ASSERT_MATCH(ui::VKEY_VOLUME_UP, FWL_VKEY_VOLUME_Up);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_NEXT_TRACK, FWL_VKEY_MEDIA_NEXT_Track);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_PREV_TRACK, FWL_VKEY_MEDIA_PREV_Track);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_STOP, FWL_VKEY_MEDIA_Stop);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_PLAY_PAUSE, FWL_VKEY_MEDIA_PLAY_Pause);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_LAUNCH_MAIL, FWL_VKEY_MEDIA_LAUNCH_Mail);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_LAUNCH_MEDIA_SELECT,
+ FWL_VKEY_MEDIA_LAUNCH_MEDIA_Select);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_LAUNCH_APP1, FWL_VKEY_MEDIA_LAUNCH_APP1);
+COMPILE_ASSERT_MATCH(ui::VKEY_MEDIA_LAUNCH_APP2, FWL_VKEY_MEDIA_LAUNCH_APP2);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_1, FWL_VKEY_OEM_1);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_PLUS, FWL_VKEY_OEM_Plus);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_COMMA, FWL_VKEY_OEM_Comma);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_MINUS, FWL_VKEY_OEM_Minus);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_PERIOD, FWL_VKEY_OEM_Period);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_2, FWL_VKEY_OEM_2);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_3, FWL_VKEY_OEM_3);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_4, FWL_VKEY_OEM_4);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_5, FWL_VKEY_OEM_5);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_6, FWL_VKEY_OEM_6);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_7, FWL_VKEY_OEM_7);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_8, FWL_VKEY_OEM_8);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_102, FWL_VKEY_OEM_102);
+COMPILE_ASSERT_MATCH(ui::VKEY_PROCESSKEY, FWL_VKEY_ProcessKey);
+COMPILE_ASSERT_MATCH(ui::VKEY_PACKET, FWL_VKEY_Packet);
+COMPILE_ASSERT_MATCH(ui::VKEY_ATTN, FWL_VKEY_Attn);
+COMPILE_ASSERT_MATCH(ui::VKEY_CRSEL, FWL_VKEY_Crsel);
+COMPILE_ASSERT_MATCH(ui::VKEY_EXSEL, FWL_VKEY_Exsel);
+COMPILE_ASSERT_MATCH(ui::VKEY_EREOF, FWL_VKEY_Ereof);
+COMPILE_ASSERT_MATCH(ui::VKEY_PLAY, FWL_VKEY_Play);
+COMPILE_ASSERT_MATCH(ui::VKEY_ZOOM, FWL_VKEY_Zoom);
+COMPILE_ASSERT_MATCH(ui::VKEY_NONAME, FWL_VKEY_NoName);
+COMPILE_ASSERT_MATCH(ui::VKEY_PA1, FWL_VKEY_PA1);
+COMPILE_ASSERT_MATCH(ui::VKEY_OEM_CLEAR, FWL_VKEY_OEM_Clear);
+COMPILE_ASSERT_MATCH(ui::VKEY_UNKNOWN, FWL_VKEY_Unknown);
+
+COMPILE_ASSERT_MATCH(PP_PRIVATEFONTCHARSET_ANSI, FXFONT_ANSI_CHARSET);
+COMPILE_ASSERT_MATCH(PP_PRIVATEFONTCHARSET_DEFAULT, FXFONT_DEFAULT_CHARSET);
+COMPILE_ASSERT_MATCH(PP_PRIVATEFONTCHARSET_SYMBOL, FXFONT_SYMBOL_CHARSET);
+COMPILE_ASSERT_MATCH(PP_PRIVATEFONTCHARSET_SHIFTJIS, FXFONT_SHIFTJIS_CHARSET);
+COMPILE_ASSERT_MATCH(PP_PRIVATEFONTCHARSET_HANGUL, FXFONT_HANGEUL_CHARSET);
+COMPILE_ASSERT_MATCH(PP_PRIVATEFONTCHARSET_GB2312, FXFONT_GB2312_CHARSET);
+COMPILE_ASSERT_MATCH(PP_PRIVATEFONTCHARSET_CHINESEBIG5,
+ FXFONT_CHINESEBIG5_CHARSET);
diff --git a/xfa_test/pdf/pdfium/pdfium_engine.cc b/xfa_test/pdf/pdfium/pdfium_engine.cc
new file mode 100644
index 0000000000..44e7052bf3
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_engine.cc
@@ -0,0 +1,3884 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/pdfium/pdfium_engine.h"
+
+#include <math.h>
+
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "pdf/draw_utils.h"
+#include "pdf/pdfium/pdfium_mem_buffer_file_read.h"
+#include "pdf/pdfium/pdfium_mem_buffer_file_write.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/c/pp_input_event.h"
+#include "ppapi/c/ppb_core.h"
+#include "ppapi/c/private/ppb_pdf.h"
+#include "ppapi/cpp/dev/memory_dev.h"
+#include "ppapi/cpp/input_event.h"
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/private/pdf.h"
+#include "ppapi/cpp/trusted/browser_font_trusted.h"
+#include "ppapi/cpp/url_response_info.h"
+#include "ppapi/cpp/var.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_ext.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_flatten.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_searchex.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_sysfontinfo.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_transformpage.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfedit.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfoom.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfppo.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfsave.h"
+#include "third_party/pdfium/fpdfsdk/include/pdfwindow/PDFWindow.h"
+#include "third_party/pdfium/fpdfsdk/include/pdfwindow/PWL_FontMap.h"
+#include "ui/events/keycodes/keyboard_codes.h"
+
+namespace chrome_pdf {
+
+namespace {
+
+#define kPageShadowTop 3
+#define kPageShadowBottom 7
+#define kPageShadowLeft 5
+#define kPageShadowRight 5
+
+#define kPageSeparatorThickness 4
+#define kHighlightColorR 153
+#define kHighlightColorG 193
+#define kHighlightColorB 218
+
+const uint32 kPendingPageColor = 0xFFEEEEEE;
+
+#define kFormHighlightColor 0xFFE4DD
+#define kFormHighlightAlpha 100
+
+#define kMaxPasswordTries 3
+
+// See Table 3.20 in
+// http://www.adobe.com/devnet/acrobat/pdfs/pdf_reference_1-7.pdf
+#define kPDFPermissionPrintLowQualityMask 1 << 2
+#define kPDFPermissionPrintHighQualityMask 1 << 11
+#define kPDFPermissionCopyMask 1 << 4
+#define kPDFPermissionCopyAccessibleMask 1 << 9
+
+#define kLoadingTextVerticalOffset 50
+
+// The maximum amount of time we'll spend doing a paint before we give back
+// control of the thread.
+#define kMaxProgressivePaintTimeMs 50
+
+// The maximum amount of time we'll spend doing the first paint. This is less
+// than the above to keep things smooth if the user is scrolling quickly. We
+// try painting a little because with accelerated compositing, we get flushes
+// only every 16 ms. If we were to wait until the next flush to paint the rest
+// of the pdf, we would never get to draw the pdf and would only draw the
+// scrollbars. This value is picked to give enough time for gpu related code to
+// do its thing and still fit within the timelimit for 60Hz. For the
+// non-composited case, this doesn't make things worse since we're still
+// painting the scrollbars > 60 Hz.
+#define kMaxInitialProgressivePaintTimeMs 10
+
+// Copied from printing/units.cc because we don't want to depend on printing
+// since it brings in libpng which causes duplicate symbols with PDFium.
+const int kPointsPerInch = 72;
+const int kPixelsPerInch = 96;
+
+struct ClipBox {
+ float left;
+ float right;
+ float top;
+ float bottom;
+};
+
+int ConvertUnit(int value, int old_unit, int new_unit) {
+ // With integer arithmetic, to divide a value with correct rounding, you need
+ // to add half of the divisor value to the dividend value. You need to do the
+ // reverse with negative number.
+ if (value >= 0) {
+ return ((value * new_unit) + (old_unit / 2)) / old_unit;
+ } else {
+ return ((value * new_unit) - (old_unit / 2)) / old_unit;
+ }
+}
+
+std::vector<uint32_t> GetPageNumbersFromPrintPageNumberRange(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count) {
+ std::vector<uint32_t> page_numbers;
+ for (uint32_t index = 0; index < page_range_count; ++index) {
+ for (uint32_t page_number = page_ranges[index].first_page_number;
+ page_number <= page_ranges[index].last_page_number; ++page_number) {
+ page_numbers.push_back(page_number);
+ }
+ }
+ return page_numbers;
+}
+
+#if defined(OS_LINUX)
+
+PP_Instance g_last_instance_id;
+
+struct PDFFontSubstitution {
+ const char* pdf_name;
+ const char* face;
+ bool bold;
+ bool italic;
+};
+
+PP_BrowserFont_Trusted_Weight WeightToBrowserFontTrustedWeight(int weight) {
+ COMPILE_ASSERT(PP_BROWSERFONT_TRUSTED_WEIGHT_100 == 0,
+ PP_BrowserFont_Trusted_Weight_Min);
+ COMPILE_ASSERT(PP_BROWSERFONT_TRUSTED_WEIGHT_900 == 8,
+ PP_BrowserFont_Trusted_Weight_Max);
+ const int kMinimumWeight = 100;
+ const int kMaximumWeight = 900;
+ int normalized_weight =
+ std::min(std::max(weight, kMinimumWeight), kMaximumWeight);
+ normalized_weight = (normalized_weight / 100) - 1;
+ return static_cast<PP_BrowserFont_Trusted_Weight>(normalized_weight);
+}
+
+// This list is for CPWL_FontMap::GetDefaultFontByCharset().
+// We pretend to have these font natively and let the browser (or underlying
+// fontconfig) to pick the proper font on the system.
+void EnumFonts(struct _FPDF_SYSFONTINFO* sysfontinfo, void* mapper) {
+ FPDF_AddInstalledFont(mapper, "Arial", FXFONT_DEFAULT_CHARSET);
+
+ int i = 0;
+ while (CPWL_FontMap::defaultTTFMap[i].charset != -1) {
+ FPDF_AddInstalledFont(mapper,
+ CPWL_FontMap::defaultTTFMap[i].fontname,
+ CPWL_FontMap::defaultTTFMap[i].charset);
+ ++i;
+ }
+}
+
+const PDFFontSubstitution PDFFontSubstitutions[] = {
+ {"Courier", "Courier New", false, false},
+ {"Courier-Bold", "Courier New", true, false},
+ {"Courier-BoldOblique", "Courier New", true, true},
+ {"Courier-Oblique", "Courier New", false, true},
+ {"Helvetica", "Arial", false, false},
+ {"Helvetica-Bold", "Arial", true, false},
+ {"Helvetica-BoldOblique", "Arial", true, true},
+ {"Helvetica-Oblique", "Arial", false, true},
+ {"Times-Roman", "Times New Roman", false, false},
+ {"Times-Bold", "Times New Roman", true, false},
+ {"Times-BoldItalic", "Times New Roman", true, true},
+ {"Times-Italic", "Times New Roman", false, true},
+
+ // MS P?(Mincho|Gothic) are the most notable fonts in Japanese PDF files
+ // without embedding the glyphs. Sometimes the font names are encoded
+ // in Japanese Windows's locale (CP932/Shift_JIS) without space.
+ // Most Linux systems don't have the exact font, but for outsourcing
+ // fontconfig to find substitutable font in the system, we pass ASCII
+ // font names to it.
+ {"MS-PGothic", "MS PGothic", false, false},
+ {"MS-Gothic", "MS Gothic", false, false},
+ {"MS-PMincho", "MS PMincho", false, false},
+ {"MS-Mincho", "MS Mincho", false, false},
+ // MS PGothic in Shift_JIS encoding.
+ {"\x82\x6C\x82\x72\x82\x6F\x83\x53\x83\x56\x83\x62\x83\x4E",
+ "MS PGothic", false, false},
+ // MS Gothic in Shift_JIS encoding.
+ {"\x82\x6C\x82\x72\x83\x53\x83\x56\x83\x62\x83\x4E",
+ "MS Gothic", false, false},
+ // MS PMincho in Shift_JIS encoding.
+ {"\x82\x6C\x82\x72\x82\x6F\x96\xBE\x92\xA9",
+ "MS PMincho", false, false},
+ // MS Mincho in Shift_JIS encoding.
+ {"\x82\x6C\x82\x72\x96\xBE\x92\xA9",
+ "MS Mincho", false, false},
+};
+
+void* MapFont(struct _FPDF_SYSFONTINFO*, int weight, int italic,
+ int charset, int pitch_family, const char* face, int* exact) {
+ // Do not attempt to map fonts if pepper is not initialized (for privet local
+ // printing).
+ // TODO(noamsml): Real font substitution (http://crbug.com/391978)
+ if (!pp::Module::Get())
+ return NULL;
+
+ pp::BrowserFontDescription description;
+
+ // Pretend the system does not have the Symbol font to force a fallback to
+ // the built in Symbol font in CFX_FontMapper::FindSubstFont().
+ if (strcmp(face, "Symbol") == 0)
+ return NULL;
+
+ if (pitch_family & FXFONT_FF_FIXEDPITCH) {
+ description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_MONOSPACE);
+ } else if (pitch_family & FXFONT_FF_ROMAN) {
+ description.set_family(PP_BROWSERFONT_TRUSTED_FAMILY_SERIF);
+ }
+
+ // Map from the standard PDF fonts to TrueType font names.
+ size_t i;
+ for (i = 0; i < arraysize(PDFFontSubstitutions); ++i) {
+ if (strcmp(face, PDFFontSubstitutions[i].pdf_name) == 0) {
+ description.set_face(PDFFontSubstitutions[i].face);
+ if (PDFFontSubstitutions[i].bold)
+ description.set_weight(PP_BROWSERFONT_TRUSTED_WEIGHT_BOLD);
+ if (PDFFontSubstitutions[i].italic)
+ description.set_italic(true);
+ break;
+ }
+ }
+
+ if (i == arraysize(PDFFontSubstitutions)) {
+ // TODO(kochi): Pass the face in UTF-8. If face is not encoded in UTF-8,
+ // convert to UTF-8 before passing.
+ description.set_face(face);
+
+ description.set_weight(WeightToBrowserFontTrustedWeight(weight));
+ description.set_italic(italic > 0);
+ }
+
+ if (!pp::PDF::IsAvailable()) {
+ NOTREACHED();
+ return NULL;
+ }
+
+ PP_Resource font_resource = pp::PDF::GetFontFileWithFallback(
+ pp::InstanceHandle(g_last_instance_id),
+ &description.pp_font_description(),
+ static_cast<PP_PrivateFontCharset>(charset));
+ long res_id = font_resource;
+ return reinterpret_cast<void*>(res_id);
+}
+
+unsigned long GetFontData(struct _FPDF_SYSFONTINFO*, void* font_id,
+ unsigned int table, unsigned char* buffer,
+ unsigned long buf_size) {
+ if (!pp::PDF::IsAvailable()) {
+ NOTREACHED();
+ return 0;
+ }
+
+ uint32_t size = buf_size;
+ long res_id = reinterpret_cast<long>(font_id);
+ if (!pp::PDF::GetFontTableForPrivateFontFile(res_id, table, buffer, &size))
+ return 0;
+ return size;
+}
+
+void DeleteFont(struct _FPDF_SYSFONTINFO*, void* font_id) {
+ long res_id = reinterpret_cast<long>(font_id);
+ pp::Module::Get()->core()->ReleaseResource(res_id);
+}
+
+FPDF_SYSFONTINFO g_font_info = {
+ 1,
+ 0,
+ EnumFonts,
+ MapFont,
+ 0,
+ GetFontData,
+ 0,
+ 0,
+ DeleteFont
+};
+#endif // defined(OS_LINUX)
+
+void OOM_Handler(_OOM_INFO*) {
+ // Kill the process. This is important for security, since the code doesn't
+ // NULL-check many memory allocations. If a malloc fails, returns NULL, and
+ // the buffer is then used, it provides a handy mapping of memory starting at
+ // address 0 for an attacker to utilize.
+ abort();
+}
+
+OOM_INFO g_oom_info = {
+ 1,
+ OOM_Handler
+};
+
+PDFiumEngine* g_engine_for_unsupported;
+
+void Unsupported_Handler(UNSUPPORT_INFO*, int type) {
+ if (!g_engine_for_unsupported) {
+ NOTREACHED();
+ return;
+ }
+
+ g_engine_for_unsupported->UnsupportedFeature(type);
+}
+
+UNSUPPORT_INFO g_unsuppored_info = {
+ 1,
+ Unsupported_Handler
+};
+
+// Set the destination page size and content area in points based on source
+// page rotation and orientation.
+//
+// |rotated| True if source page is rotated 90 degree or 270 degree.
+// |is_src_page_landscape| is true if the source page orientation is landscape.
+// |page_size| has the actual destination page size in points.
+// |content_rect| has the actual destination page printable area values in
+// points.
+void SetPageSizeAndContentRect(bool rotated,
+ bool is_src_page_landscape,
+ pp::Size* page_size,
+ pp::Rect* content_rect) {
+ bool is_dst_page_landscape = page_size->width() > page_size->height();
+ bool page_orientation_mismatched = is_src_page_landscape !=
+ is_dst_page_landscape;
+ bool rotate_dst_page = rotated ^ page_orientation_mismatched;
+ if (rotate_dst_page) {
+ page_size->SetSize(page_size->height(), page_size->width());
+ content_rect->SetRect(content_rect->y(), content_rect->x(),
+ content_rect->height(), content_rect->width());
+ }
+}
+
+// Calculate the scale factor between |content_rect| and a page of size
+// |src_width| x |src_height|.
+//
+// |scale_to_fit| is true, if we need to calculate the scale factor.
+// |content_rect| specifies the printable area of the destination page, with
+// origin at left-bottom. Values are in points.
+// |src_width| specifies the source page width in points.
+// |src_height| specifies the source page height in points.
+// |rotated| True if source page is rotated 90 degree or 270 degree.
+double CalculateScaleFactor(bool scale_to_fit,
+ const pp::Rect& content_rect,
+ double src_width, double src_height, bool rotated) {
+ if (!scale_to_fit || src_width == 0 || src_height == 0)
+ return 1.0;
+
+ double actual_source_page_width = rotated ? src_height : src_width;
+ double actual_source_page_height = rotated ? src_width : src_height;
+ double ratio_x = static_cast<double>(content_rect.width()) /
+ actual_source_page_width;
+ double ratio_y = static_cast<double>(content_rect.height()) /
+ actual_source_page_height;
+ return std::min(ratio_x, ratio_y);
+}
+
+// Compute source clip box boundaries based on the crop box / media box of
+// source page and scale factor.
+//
+// |page| Handle to the source page. Returned by FPDF_LoadPage function.
+// |scale_factor| specifies the scale factor that should be applied to source
+// clip box boundaries.
+// |rotated| True if source page is rotated 90 degree or 270 degree.
+// |clip_box| out param to hold the computed source clip box values.
+void CalculateClipBoxBoundary(FPDF_PAGE page, double scale_factor, bool rotated,
+ ClipBox* clip_box) {
+ if (!FPDFPage_GetCropBox(page, &clip_box->left, &clip_box->bottom,
+ &clip_box->right, &clip_box->top)) {
+ if (!FPDFPage_GetMediaBox(page, &clip_box->left, &clip_box->bottom,
+ &clip_box->right, &clip_box->top)) {
+ // Make the default size to be letter size (8.5" X 11"). We are just
+ // following the PDFium way of handling these corner cases. PDFium always
+ // consider US-Letter as the default page size.
+ float paper_width = 612;
+ float paper_height = 792;
+ clip_box->left = 0;
+ clip_box->bottom = 0;
+ clip_box->right = rotated ? paper_height : paper_width;
+ clip_box->top = rotated ? paper_width : paper_height;
+ }
+ }
+ clip_box->left *= scale_factor;
+ clip_box->right *= scale_factor;
+ clip_box->bottom *= scale_factor;
+ clip_box->top *= scale_factor;
+}
+
+// Calculate the clip box translation offset for a page that does need to be
+// scaled. All parameters are in points.
+//
+// |content_rect| specifies the printable area of the destination page, with
+// origin at left-bottom.
+// |source_clip_box| specifies the source clip box positions, relative to
+// origin at left-bottom.
+// |offset_x| and |offset_y| will contain the final translation offsets for the
+// source clip box, relative to origin at left-bottom.
+void CalculateScaledClipBoxOffset(const pp::Rect& content_rect,
+ const ClipBox& source_clip_box,
+ double* offset_x, double* offset_y) {
+ const float clip_box_width = source_clip_box.right - source_clip_box.left;
+ const float clip_box_height = source_clip_box.top - source_clip_box.bottom;
+
+ // Center the intended clip region to real clip region.
+ *offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() -
+ source_clip_box.left;
+ *offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() -
+ source_clip_box.bottom;
+}
+
+// Calculate the clip box offset for a page that does not need to be scaled.
+// All parameters are in points.
+//
+// |content_rect| specifies the printable area of the destination page, with
+// origin at left-bottom.
+// |rotation| specifies the source page rotation values which are N / 90
+// degrees.
+// |page_width| specifies the screen destination page width.
+// |page_height| specifies the screen destination page height.
+// |source_clip_box| specifies the source clip box positions, relative to origin
+// at left-bottom.
+// |offset_x| and |offset_y| will contain the final translation offsets for the
+// source clip box, relative to origin at left-bottom.
+void CalculateNonScaledClipBoxOffset(const pp::Rect& content_rect, int rotation,
+ int page_width, int page_height,
+ const ClipBox& source_clip_box,
+ double* offset_x, double* offset_y) {
+ // Align the intended clip region to left-top corner of real clip region.
+ switch (rotation) {
+ case 0:
+ *offset_x = -1 * source_clip_box.left;
+ *offset_y = page_height - source_clip_box.top;
+ break;
+ case 1:
+ *offset_x = 0;
+ *offset_y = -1 * source_clip_box.bottom;
+ break;
+ case 2:
+ *offset_x = page_width - source_clip_box.right;
+ *offset_y = 0;
+ break;
+ case 3:
+ *offset_x = page_height - source_clip_box.right;
+ *offset_y = page_width - source_clip_box.top;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+}
+
+// This formats a string with special 0xfffe end-of-line hyphens the same way
+// as Adobe Reader. When a hyphen is encountered, the next non-CR/LF whitespace
+// becomes CR+LF and the hyphen is erased. If there is no whitespace between
+// two hyphens, the latter hyphen is erased and ignored.
+void FormatStringWithHyphens(base::string16* text) {
+ // First pass marks all the hyphen positions.
+ struct HyphenPosition {
+ HyphenPosition() : position(0), next_whitespace_position(0) {}
+ size_t position;
+ size_t next_whitespace_position; // 0 for none
+ };
+ std::vector<HyphenPosition> hyphen_positions;
+ HyphenPosition current_hyphen_position;
+ bool current_hyphen_position_is_valid = false;
+ const base::char16 kPdfiumHyphenEOL = 0xfffe;
+
+ for (size_t i = 0; i < text->size(); ++i) {
+ const base::char16& current_char = (*text)[i];
+ if (current_char == kPdfiumHyphenEOL) {
+ if (current_hyphen_position_is_valid)
+ hyphen_positions.push_back(current_hyphen_position);
+ current_hyphen_position = HyphenPosition();
+ current_hyphen_position.position = i;
+ current_hyphen_position_is_valid = true;
+ } else if (IsWhitespace(current_char)) {
+ if (current_hyphen_position_is_valid) {
+ if (current_char != L'\r' && current_char != L'\n')
+ current_hyphen_position.next_whitespace_position = i;
+ hyphen_positions.push_back(current_hyphen_position);
+ current_hyphen_position_is_valid = false;
+ }
+ }
+ }
+ if (current_hyphen_position_is_valid)
+ hyphen_positions.push_back(current_hyphen_position);
+
+ // With all the hyphen positions, do the search and replace.
+ while (!hyphen_positions.empty()) {
+ static const base::char16 kCr[] = {L'\r', L'\0'};
+ const HyphenPosition& position = hyphen_positions.back();
+ if (position.next_whitespace_position != 0) {
+ (*text)[position.next_whitespace_position] = L'\n';
+ text->insert(position.next_whitespace_position, kCr);
+ }
+ text->erase(position.position, 1);
+ hyphen_positions.pop_back();
+ }
+
+ // Adobe Reader also get rid of trailing spaces right before a CRLF.
+ static const base::char16 kSpaceCrCn[] = {L' ', L'\r', L'\n', L'\0'};
+ static const base::char16 kCrCn[] = {L'\r', L'\n', L'\0'};
+ ReplaceSubstringsAfterOffset(text, 0, kSpaceCrCn, kCrCn);
+}
+
+// Replace CR/LF with just LF on POSIX.
+void FormatStringForOS(base::string16* text) {
+#if defined(OS_POSIX)
+ static const base::char16 kCr[] = {L'\r', L'\0'};
+ static const base::char16 kBlank[] = {L'\0'};
+ base::ReplaceChars(*text, kCr, kBlank, text);
+#elif defined(OS_WIN)
+ // Do nothing
+#else
+ NOTIMPLEMENTED();
+#endif
+}
+
+} // namespace
+
+bool InitializeSDK(void* data) {
+ FPDF_InitLibrary(data);
+
+#if defined(OS_LINUX)
+ // Font loading doesn't work in the renderer sandbox in Linux.
+ FPDF_SetSystemFontInfo(&g_font_info);
+#endif
+
+ FSDK_SetOOMHandler(&g_oom_info);
+ FSDK_SetUnSpObjProcessHandler(&g_unsuppored_info);
+
+ return true;
+}
+
+void ShutdownSDK() {
+ FPDF_DestroyLibrary();
+}
+
+PDFEngine* PDFEngine::Create(PDFEngine::Client* client) {
+ return new PDFiumEngine(client);
+}
+
+PDFiumEngine::PDFiumEngine(PDFEngine::Client* client)
+ : client_(client),
+ current_zoom_(1.0),
+ current_rotation_(0),
+ doc_loader_(this),
+ password_tries_remaining_(0),
+ doc_(NULL),
+ form_(NULL),
+ defer_page_unload_(false),
+ selecting_(false),
+ mouse_down_state_(PDFiumPage::NONSELECTABLE_AREA,
+ PDFiumPage::LinkTarget()),
+ next_page_to_search_(-1),
+ last_page_to_search_(-1),
+ last_character_index_to_search_(-1),
+ current_find_index_(-1),
+ resume_find_index_(-1),
+ permissions_(0),
+ fpdf_availability_(NULL),
+ next_timer_id_(0),
+ last_page_mouse_down_(-1),
+ first_visible_page_(-1),
+ most_visible_page_(-1),
+ called_do_document_action_(false),
+ render_grayscale_(false),
+ progressive_paint_timeout_(0),
+ getting_password_(false) {
+ find_factory_.Initialize(this);
+ password_factory_.Initialize(this);
+
+ file_access_.m_FileLen = 0;
+ file_access_.m_GetBlock = &GetBlock;
+ file_access_.m_Param = &doc_loader_;
+
+ file_availability_.version = 1;
+ file_availability_.IsDataAvail = &IsDataAvail;
+ file_availability_.loader = &doc_loader_;
+
+ download_hints_.version = 1;
+ download_hints_.AddSegment = &AddSegment;
+ download_hints_.loader = &doc_loader_;
+
+ // Initialize FPDF_FORMFILLINFO member variables. Deriving from this struct
+ // allows the static callbacks to be able to cast the FPDF_FORMFILLINFO in
+ // callbacks to ourself instead of maintaining a map of them to
+ // PDFiumEngine.
+ FPDF_FORMFILLINFO::version = 1;
+ FPDF_FORMFILLINFO::m_pJsPlatform = this;
+ FPDF_FORMFILLINFO::Release = NULL;
+ FPDF_FORMFILLINFO::FFI_Invalidate = Form_Invalidate;
+ FPDF_FORMFILLINFO::FFI_OutputSelectedRect = Form_OutputSelectedRect;
+ FPDF_FORMFILLINFO::FFI_SetCursor = Form_SetCursor;
+ FPDF_FORMFILLINFO::FFI_SetTimer = Form_SetTimer;
+ FPDF_FORMFILLINFO::FFI_KillTimer = Form_KillTimer;
+ FPDF_FORMFILLINFO::FFI_GetLocalTime = Form_GetLocalTime;
+ FPDF_FORMFILLINFO::FFI_OnChange = Form_OnChange;
+ FPDF_FORMFILLINFO::FFI_GetPage = Form_GetPage;
+ FPDF_FORMFILLINFO::FFI_GetCurrentPage = Form_GetCurrentPage;
+ FPDF_FORMFILLINFO::FFI_GetRotation = Form_GetRotation;
+ FPDF_FORMFILLINFO::FFI_ExecuteNamedAction = Form_ExecuteNamedAction;
+ FPDF_FORMFILLINFO::FFI_SetTextFieldFocus = Form_SetTextFieldFocus;
+ FPDF_FORMFILLINFO::FFI_DoURIAction = Form_DoURIAction;
+ FPDF_FORMFILLINFO::FFI_DoGoToAction = Form_DoGoToAction;
+#ifdef _TEST_XFA
+ FPDF_FORMFILLINFO::FFI_EmailTo = Form_EmailTo;
+ FPDF_FORMFILLINFO::FFI_DisplayCaret = Form_DisplayCaret;
+ //FPDF_FORMFILLINFO::FFI_GetCurDocumentIndex = Form_GetCurDocumentIndex;
+ //FPDF_FORMFILLINFO::FFI_GetDocumentCount = Form_GetDocumentCount;
+ FPDF_FORMFILLINFO::FFI_SetCurrentPage = Form_SetCurrentPage;
+ FPDF_FORMFILLINFO::FFI_GetCurrentPageIndex = Form_GetCurrentPageIndex;
+ FPDF_FORMFILLINFO::FFI_GetPageViewRect = Form_GetPageViewRect;
+ FPDF_FORMFILLINFO::FFI_GetPlatform = Form_GetPlatform;
+ FPDF_FORMFILLINFO::FFI_PopupMenu = Form_PopupMenu;
+ FPDF_FORMFILLINFO::FFI_PostRequestURL = Form_PostRequestURL;
+ FPDF_FORMFILLINFO::FFI_PutRequestURL = Form_PutRequestURL;
+// FPDF_FORMFILLINFO::FFI_ShowFileDialog = Form_ShowFileDialog;
+ FPDF_FORMFILLINFO::FFI_UploadTo = Form_UploadTo;
+ FPDF_FORMFILLINFO::FFI_DownloadFromURL = Form_DownloadFromURL;
+ // FPDF_FORMFILLINFO::FFI_GetFilePath = MyForm_GetFilePath;
+ FPDF_FORMFILLINFO::FFI_OpenFile = Form_OpenFile;
+ FPDF_FORMFILLINFO::FFI_GotoURL = Form_GotoURL;
+ FPDF_FORMFILLINFO::FFI_GetLanguage = Form_GetLanguage;
+#endif // _TEST_XFA
+ IPDF_JSPLATFORM::version = 1;
+ IPDF_JSPLATFORM::app_alert = Form_Alert;
+ IPDF_JSPLATFORM::app_beep = Form_Beep;
+ IPDF_JSPLATFORM::app_response = Form_Response;
+ IPDF_JSPLATFORM::Doc_getFilePath = Form_GetFilePath;
+ IPDF_JSPLATFORM::Doc_mail = Form_Mail;
+ IPDF_JSPLATFORM::Doc_print = Form_Print;
+ IPDF_JSPLATFORM::Doc_submitForm = Form_SubmitForm;
+ IPDF_JSPLATFORM::Doc_gotoPage = Form_GotoPage;
+ IPDF_JSPLATFORM::Field_browse = Form_Browse;
+
+ IFSDK_PAUSE::version = 1;
+ IFSDK_PAUSE::user = NULL;
+ IFSDK_PAUSE::NeedToPauseNow = Pause_NeedToPauseNow;
+}
+
+PDFiumEngine::~PDFiumEngine() {
+ for (size_t i = 0; i < pages_.size(); ++i)
+ pages_[i]->Unload();
+
+ if (doc_) {
+ if (form_) {
+ FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_WC);
+ }
+ FPDF_CloseDocument(doc_);
+ if (form_) {
+ FPDFDOC_ExitFormFillEnviroument(form_);
+ }
+ }
+
+ if (fpdf_availability_)
+ FPDFAvail_Destroy(fpdf_availability_);
+
+ STLDeleteElements(&pages_);
+}
+
+#ifdef _TEST_XFA
+
+typedef struct _FPDF_FILE {
+ FPDF_FILEHANDLER fileHandler;
+ FILE* file;
+}FPDF_FILE;
+
+
+void Sample_Release(FPDF_LPVOID clientData) {
+ if (!clientData) return;
+
+ fclose(((FPDF_FILE*)clientData)->file);
+ delete ((FPDF_FILE*)clientData);
+}
+
+FPDF_DWORD Sample_GetSize(FPDF_LPVOID clientData) {
+ if (!clientData) return 0;
+
+ long curPos = ftell(((FPDF_FILE*)clientData)->file);
+ fseek(((FPDF_FILE*)clientData)->file, 0, SEEK_END);
+ long size = ftell(((FPDF_FILE*)clientData)->file);
+ fseek(((FPDF_FILE*)clientData)->file, curPos, SEEK_SET);
+
+ return (FPDF_DWORD)size;
+}
+
+FPDF_RESULT Sample_ReadBlock(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPVOID buffer, FPDF_DWORD size) {
+ if (!clientData) return -1;
+
+ fseek(((FPDF_FILE*)clientData)->file, (long)offset, SEEK_SET);
+ size_t readSize = fread(buffer, 1, size, ((FPDF_FILE*)clientData)->file);
+ return readSize == size ? 0 : -1;
+}
+
+FPDF_RESULT Sample_WriteBlock(FPDF_LPVOID clientData, FPDF_DWORD offset, FPDF_LPCVOID buffer, FPDF_DWORD size) {
+ if (!clientData) return -1;
+
+ fseek(((FPDF_FILE*)clientData)->file, (long)offset, SEEK_SET);
+ //Write data
+ size_t writeSize = fwrite(buffer, 1, size, ((FPDF_FILE*)clientData)->file);
+ return writeSize == size ? 0 : -1;
+}
+
+FPDF_RESULT Sample_Flush(FPDF_LPVOID clientData) {
+ if (!clientData) return -1;
+
+ //Flush file
+ fflush(((FPDF_FILE*)clientData)->file);
+
+ return 0;
+}
+
+FPDF_RESULT Sample_Truncate(FPDF_LPVOID clientData, FPDF_DWORD size) {
+ return 0;
+}
+
+
+void PDFiumEngine::Form_EmailTo(FPDF_FORMFILLINFO* pThis,
+ FPDF_FILEHANDLER* fileHandler,
+ FPDF_WIDESTRING to,
+ FPDF_WIDESTRING subject,
+ FPDF_WIDESTRING cc,
+ FPDF_WIDESTRING bcc,
+ FPDF_WIDESTRING message) {
+ std::string to_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(to));
+ std::string subject_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(subject));
+ std::string cc_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(cc));
+ std::string bcc_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(bcc));
+ std::string message_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(message));
+
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+ engine->client_->Email(to_str, cc_str, bcc_str, subject_str, message_str);
+}
+
+void PDFiumEngine::Form_DisplayCaret(FPDF_FORMFILLINFO* pThis,
+ FPDF_PAGE page, FPDF_BOOL bVisible,
+ double left, double top, double right, double bottom) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+ engine->client_->UpdateCursor(PP_CURSORTYPE_IBEAM);
+ std::vector<pp::Rect> tickmarks;
+ pp::Rect rect(left, top, right, bottom);
+ tickmarks.push_back(rect);
+ engine->client_->UpdateTickMarks(tickmarks);
+}
+
+//int PDFiumEngine::Form_GetCurDocumentIndex(FPDF_FORMFILLINFO* pThis) {
+// PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+// engine->client_->RunJSCmd("alert(\"GetCurDocumentIndex\")");
+// return 0;
+//}
+//
+//int PDFiumEngine::Form_GetDocumentCount(FPDF_FORMFILLINFO* pThis) {
+// PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+// engine->client_->RunJSCmd("alert(\"GetCurDocumentCount\")");
+// return 0;
+//}
+
+void PDFiumEngine::Form_SetCurrentPage(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, int iCurPage) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+ pp::Rect pageViewRect = engine->GetPageContentsRect(iCurPage);
+ engine->ScrolledToYPosition(pageViewRect.height());
+ pp::Point pos(1, pageViewRect.height());
+ engine->SetScrollPosition(pos);
+}
+
+int PDFiumEngine::Form_GetCurrentPageIndex(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document) {
+ //int pageCount = FPDF_GetPageCount(document);
+ int pageIndex = -1;
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+ pageIndex = engine->GetMostVisiblePage();
+ return pageIndex;
+}
+
+void PDFiumEngine::Form_GetPageViewRect(FPDF_FORMFILLINFO* pThis,
+ FPDF_PAGE page,
+ double* left, double* top, double* right, double* bottom) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+ int page_index = engine->GetMostVisiblePage();
+ pp::Rect pageViewRect = engine->GetPageContentsRect(page_index);
+
+ *left = pageViewRect.x();
+ *right = pageViewRect.width() + pageViewRect.x();
+ *top = pageViewRect.y();
+ *bottom = pageViewRect.height();
+
+ std::string javascript = "alert(\"PageViewRect:"
+ + base::DoubleToString(*left) + ","
+ + base::DoubleToString(*right) + ","
+ + base::DoubleToString(*top) + ","
+ + base::DoubleToString(*bottom) + ","
+ + "\")";
+
+}
+
+int PDFiumEngine::Form_GetPlatform(FPDF_FORMFILLINFO* pThis,
+ void* platform,
+ int length) {
+ int platform_flag = -1;
+#if defined(WIN32)
+ platform_flag = 0;
+#elif defined(__linux__)
+ platform_flag = 1;
+#else
+ platform_flag = 2;
+#endif
+ std::string javascript = "alert(\"Platform:"
+ + base::DoubleToString(platform_flag)
+ + "\")";
+ //platform = new char[3];
+ //char tem[10] = "WIN";
+ //strncpy((char*)platform, tem, 3);
+
+ return 3;
+}
+
+FPDF_BOOL PDFiumEngine::Form_PopupMenu(FPDF_FORMFILLINFO* pThis,
+ FPDF_PAGE page,
+ FPDF_WIDGET hWidget,
+ int menuFlag, float x, float y) {
+ return false;
+}
+
+FPDF_BOOL PDFiumEngine::Form_PostRequestURL(FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL,
+ FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsContentType,
+ FPDF_WIDESTRING wsEncode, FPDF_WIDESTRING wsHeader, FPDF_BSTR* respone) {
+ std::string url_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsURL));
+ std::string data_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsData));
+ std::string content_type_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsContentType));
+ std::string encode_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsEncode));
+ std::string header_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsHeader));
+
+ std::string javascript = "alert(\"Post:"
+ + url_str + "," + data_str + "," + content_type_str + ","
+ + encode_str + "," + header_str
+ + "\")";
+ return true;
+}
+
+FPDF_BOOL PDFiumEngine::Form_PutRequestURL(FPDF_FORMFILLINFO* pThis,
+ FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsEncode) {
+ std::string url_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsURL));
+ std::string data_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsData));
+ std::string encode_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsEncode));
+
+ std::string javascript = "alert(\"Put:"
+ + url_str + "," + data_str + "," + encode_str
+ + "\")";
+
+ return true;
+}
+
+//FPDF_BOOL PDFiumEngine::Form_ShowFileDialog(FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsTitle, FPDF_WIDESTRING wsFilter, FPDF_BOOL isOpen, FPDF_STRINGHANDLE pathArr) {
+// int tem = 1;
+// tem++;
+// return false;
+//}
+
+void PDFiumEngine::Form_UploadTo(FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* fileHandler, int fileFlag, FPDF_WIDESTRING uploadTo) {
+ std::string to_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(uploadTo));
+
+}
+
+FPDF_LPFILEHANDLER PDFiumEngine::Form_DownloadFromURL(FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING URL) {
+ std::string url_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(URL));
+
+
+ // Get URL data...
+ FILE* file = fopen(FXQA_TESTFILE("downloadtest.tem"), "w");
+ FPDF_FILE* pFileHander = new FPDF_FILE;
+ pFileHander->file = file;
+ pFileHander->fileHandler.clientData = pFileHander;
+ pFileHander->fileHandler.Flush = Sample_Flush;
+ pFileHander->fileHandler.GetSize = Sample_GetSize;
+ pFileHander->fileHandler.ReadBlock = Sample_ReadBlock;
+ pFileHander->fileHandler.Release = Sample_Release;
+ pFileHander->fileHandler.Truncate = Sample_Truncate;
+ pFileHander->fileHandler.WriteBlock = Sample_WriteBlock;
+
+ return &pFileHander->fileHandler;
+}
+
+//FPDF_BOOL PDFiumEngine::MyForm_GetFilePath(FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* pFileHandler, void* filePath, int length) {
+// //std::string filePath = engine->client_->FileOpen(fileFlag);
+// if (filePath == NULL) {
+// std::string javascript = "alert(\"GetFilePath:NULL\")";
+// PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+// engine->client_->RunJSCmd(javascript);
+// return false;
+// }
+// std::string filePath_str = (char*)filePath;
+//
+// std::string javascript = "alert(\"GetFilePath:" + filePath_str + "\")";
+// PDFiumEngine* engine = static_cast<PDFiumEngine*>(pThis);
+// engine->client_->RunJSCmd(javascript);
+//
+// FILE* file = fopen(FXQA_TESTFILE("tem.xdp"), "w");
+// FPDF_FILE* pFileHander = new FPDF_FILE;
+// pFileHander->file = file;
+// pFileHander->fileHandler.clientData = pFileHander;
+// pFileHander->fileHandler.Flush = Sample_Flush;
+// pFileHander->fileHandler.GetSize = Sample_GetSize;
+// pFileHander->fileHandler.ReadBlock = Sample_ReadBlock;
+// pFileHander->fileHandler.Release = Sample_Release;
+// pFileHander->fileHandler.Truncate = Sample_Truncate;
+// pFileHander->fileHandler.WriteBlock = Sample_WriteBlock;
+//
+// pFileHandler = &pFileHander->fileHandler;
+//
+// return true;
+//}
+
+FPDF_FILEHANDLER* PDFiumEngine::Form_OpenFile(FPDF_FORMFILLINFO* pThis, int fileFlag, FPDF_WIDESTRING wsURL, const char* mode) {
+ std::string url_str = "NULL";
+ if (wsURL == NULL) {
+ url_str = "NULL";
+ }
+ else {
+ url_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsURL));
+ }
+ if (strncmp(mode, "wb", 2) == 0) {
+
+ FILE* file = fopen(FXQA_TESTFILE("tem.txt"), mode);
+ FPDF_FILE* pFileHander = new FPDF_FILE;
+ pFileHander->file = file;
+ pFileHander->fileHandler.clientData = pFileHander;
+ pFileHander->fileHandler.Flush = Sample_Flush;
+ pFileHander->fileHandler.GetSize = Sample_GetSize;
+ pFileHander->fileHandler.ReadBlock = Sample_ReadBlock;
+ pFileHander->fileHandler.Release = Sample_Release;
+ pFileHander->fileHandler.Truncate = Sample_Truncate;
+ pFileHander->fileHandler.WriteBlock = Sample_WriteBlock;
+ return &pFileHander->fileHandler;
+ }
+ else {
+ url_str = base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsURL));
+ }
+ return NULL;
+}
+
+
+void PDFiumEngine::Form_GotoURL(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, FPDF_WIDESTRING wsURL) {
+ std::string url_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(wsURL));
+ int pageCount = FPDF_GetPageCount(document);
+}
+
+int PDFiumEngine::Form_GetLanguage(FPDF_FORMFILLINFO* pThis, void* language, int length) {
+ return 0;
+}
+
+#endif // _TEST_XFA
+
+int PDFiumEngine::GetBlock(void* param, unsigned long position,
+ unsigned char* buffer, unsigned long size) {
+ DocumentLoader* loader = static_cast<DocumentLoader*>(param);
+ return loader->GetBlock(position, size, buffer);
+}
+
+bool PDFiumEngine::IsDataAvail(FX_FILEAVAIL* param,
+ size_t offset, size_t size) {
+ PDFiumEngine::FileAvail* file_avail =
+ static_cast<PDFiumEngine::FileAvail*>(param);
+ return file_avail->loader->IsDataAvailable(offset, size);
+}
+
+void PDFiumEngine::AddSegment(FX_DOWNLOADHINTS* param,
+ size_t offset, size_t size) {
+ PDFiumEngine::DownloadHints* download_hints =
+ static_cast<PDFiumEngine::DownloadHints*>(param);
+ return download_hints->loader->RequestData(offset, size);
+}
+
+bool PDFiumEngine::New(const char* url) {
+ url_ = url;
+ headers_ = std::string();
+ return true;
+}
+
+bool PDFiumEngine::New(const char* url,
+ const char* headers) {
+ url_ = url;
+ if (!headers)
+ headers_ = std::string();
+ else
+ headers_ = headers;
+ return true;
+}
+
+void PDFiumEngine::PageOffsetUpdated(const pp::Point& page_offset) {
+ page_offset_ = page_offset;
+}
+
+void PDFiumEngine::PluginSizeUpdated(const pp::Size& size) {
+ CancelPaints();
+
+ plugin_size_ = size;
+ CalculateVisiblePages();
+}
+
+void PDFiumEngine::ScrolledToXPosition(int position) {
+ CancelPaints();
+
+ int old_x = position_.x();
+ position_.set_x(position);
+ CalculateVisiblePages();
+ client_->Scroll(pp::Point(old_x - position, 0));
+}
+
+void PDFiumEngine::ScrolledToYPosition(int position) {
+ CancelPaints();
+
+ int old_y = position_.y();
+ position_.set_y(position);
+ CalculateVisiblePages();
+ client_->Scroll(pp::Point(0, old_y - position));
+}
+
+void PDFiumEngine::PrePaint() {
+ for (size_t i = 0; i < progressive_paints_.size(); ++i)
+ progressive_paints_[i].painted_ = false;
+}
+
+void PDFiumEngine::Paint(const pp::Rect& rect,
+ pp::ImageData* image_data,
+ std::vector<pp::Rect>* ready,
+ std::vector<pp::Rect>* pending) {
+ pp::Rect leftover = rect;
+ for (size_t i = 0; i < visible_pages_.size(); ++i) {
+ int index = visible_pages_[i];
+ pp::Rect page_rect = pages_[index]->rect();
+ // Convert the current page's rectangle to screen rectangle. We do this
+ // instead of the reverse (converting the dirty rectangle from screen to
+ // page coordinates) because then we'd have to convert back to screen
+ // coordinates, and the rounding errors sometime leave pixels dirty or even
+ // move the text up or down a pixel when zoomed.
+ pp::Rect page_rect_in_screen = GetPageScreenRect(index);
+ pp::Rect dirty_in_screen = page_rect_in_screen.Intersect(leftover);
+ if (dirty_in_screen.IsEmpty())
+ continue;
+
+ leftover = leftover.Subtract(dirty_in_screen);
+
+ if (pages_[index]->available()) {
+ int progressive = GetProgressiveIndex(index);
+ if (progressive != -1 &&
+ progressive_paints_[progressive].rect != dirty_in_screen) {
+ // The PDFium code can only handle one progressive paint at a time, so
+ // queue this up. Previously we used to merge the rects when this
+ // happened, but it made scrolling up on complex PDFs very slow since
+ // there would be a damaged rect at the top (from scroll) and at the
+ // bottom (from toolbar).
+ pending->push_back(dirty_in_screen);
+ continue;
+ }
+
+ if (progressive == -1) {
+ progressive = StartPaint(index, dirty_in_screen);
+ progressive_paint_timeout_ = kMaxInitialProgressivePaintTimeMs;
+ } else {
+ progressive_paint_timeout_ = kMaxProgressivePaintTimeMs;
+ }
+
+ progressive_paints_[progressive].painted_ = true;
+ if (ContinuePaint(progressive, image_data)) {
+ FinishPaint(progressive, image_data);
+ ready->push_back(dirty_in_screen);
+ } else {
+ pending->push_back(dirty_in_screen);
+ }
+ } else {
+ PaintUnavailablePage(index, dirty_in_screen, image_data);
+ ready->push_back(dirty_in_screen);
+ }
+ }
+}
+
+void PDFiumEngine::PostPaint() {
+ for (size_t i = 0; i < progressive_paints_.size(); ++i) {
+ if (progressive_paints_[i].painted_)
+ continue;
+
+ // This rectangle must have been merged with another one, that's why we
+ // weren't asked to paint it. Remove it or otherwise we'll never finish
+ // painting.
+ FPDF_RenderPage_Close(
+ pages_[progressive_paints_[i].page_index]->GetPage());
+ FPDFBitmap_Destroy(progressive_paints_[i].bitmap);
+ progressive_paints_.erase(progressive_paints_.begin() + i);
+ --i;
+ }
+}
+
+bool PDFiumEngine::HandleDocumentLoad(const pp::URLLoader& loader) {
+ password_tries_remaining_ = kMaxPasswordTries;
+ return doc_loader_.Init(loader, url_, headers_);
+}
+
+pp::Instance* PDFiumEngine::GetPluginInstance() {
+ return client_->GetPluginInstance();
+}
+
+pp::URLLoader PDFiumEngine::CreateURLLoader() {
+ return client_->CreateURLLoader();
+}
+
+void PDFiumEngine::AppendPage(PDFEngine* engine, int index) {
+ // Unload and delete the blank page before appending.
+ pages_[index]->Unload();
+ pages_[index]->set_calculated_links(false);
+ pp::Size curr_page_size = GetPageSize(index);
+ FPDFPage_Delete(doc_, index);
+ FPDF_ImportPages(doc_,
+ static_cast<PDFiumEngine*>(engine)->doc(),
+ "1",
+ index);
+ pp::Size new_page_size = GetPageSize(index);
+ if (curr_page_size != new_page_size)
+ LoadPageInfo(true);
+ client_->Invalidate(GetPageScreenRect(index));
+}
+
+pp::Point PDFiumEngine::GetScrollPosition() {
+ return position_;
+}
+
+void PDFiumEngine::SetScrollPosition(const pp::Point& position) {
+ position_ = position;
+}
+
+bool PDFiumEngine::IsProgressiveLoad() {
+ return doc_loader_.is_partial_document();
+}
+
+void PDFiumEngine::OnPartialDocumentLoaded() {
+ file_access_.m_FileLen = doc_loader_.document_size();
+ fpdf_availability_ = FPDFAvail_Create(&file_availability_, &file_access_);
+ DCHECK(fpdf_availability_);
+
+ // Currently engine does not deal efficiently with some non-linearized files.
+ // See http://code.google.com/p/chromium/issues/detail?id=59400
+ // To improve user experience we download entire file for non-linearized PDF.
+ if (!FPDFAvail_IsLinearized(fpdf_availability_)) {
+ doc_loader_.RequestData(0, doc_loader_.document_size());
+ return;
+ }
+
+ LoadDocument();
+}
+
+void PDFiumEngine::OnPendingRequestComplete() {
+ if (!doc_ || !form_) {
+ LoadDocument();
+ return;
+ }
+
+ // LoadDocument() will result in |pending_pages_| being reset so there's no
+ // need to run the code below in that case.
+ bool update_pages = false;
+ std::vector<int> still_pending;
+ for (size_t i = 0; i < pending_pages_.size(); ++i) {
+ if (CheckPageAvailable(pending_pages_[i], &still_pending)) {
+ update_pages = true;
+ if (IsPageVisible(pending_pages_[i]))
+ client_->Invalidate(GetPageScreenRect(pending_pages_[i]));
+ }
+ }
+ pending_pages_.swap(still_pending);
+ if (update_pages)
+ LoadPageInfo(true);
+}
+
+void PDFiumEngine::OnNewDataAvailable() {
+ client_->DocumentLoadProgress(doc_loader_.GetAvailableData(),
+ doc_loader_.document_size());
+}
+
+void PDFiumEngine::OnDocumentComplete() {
+ if (!doc_ || !form_) {
+ file_access_.m_FileLen = doc_loader_.document_size();
+ LoadDocument();
+ return;
+ }
+
+ bool need_update = false;
+ for (size_t i = 0; i < pages_.size(); ++i) {
+ if (pages_[i]->available())
+ continue;
+
+ pages_[i]->set_available(true);
+ // We still need to call IsPageAvail() even if the whole document is
+ // already downloaded.
+ FPDFAvail_IsPageAvail(fpdf_availability_, i, &download_hints_);
+ need_update = true;
+ if (IsPageVisible(i))
+ client_->Invalidate(GetPageScreenRect(i));
+ }
+ if (need_update)
+ LoadPageInfo(true);
+
+ FinishLoadingDocument();
+}
+
+void PDFiumEngine::FinishLoadingDocument() {
+ DCHECK(doc_loader_.IsDocumentComplete() && doc_);
+ if (called_do_document_action_)
+ return;
+ called_do_document_action_ = true;
+
+ // These can only be called now, as the JS might end up needing a page.
+ FORM_DoDocumentJSAction(form_);
+ FORM_DoDocumentOpenAction(form_);
+ if (most_visible_page_ != -1) {
+ FPDF_PAGE new_page = pages_[most_visible_page_]->GetPage();
+ FORM_DoPageAAction(new_page, form_, FPDFPAGE_AACTION_OPEN);
+ }
+
+ if (doc_) // This can only happen if loading |doc_| fails.
+ client_->DocumentLoadComplete(pages_.size());
+}
+
+void PDFiumEngine::UnsupportedFeature(int type) {
+ std::string feature;
+ switch (type) {
+ case FPDF_UNSP_DOC_XFAFORM:
+ //feature = "XFA";
+ break;
+ case FPDF_UNSP_DOC_PORTABLECOLLECTION:
+ feature = "Portfolios_Packages";
+ break;
+ case FPDF_UNSP_DOC_ATTACHMENT:
+ case FPDF_UNSP_ANNOT_ATTACHMENT:
+ feature = "Attachment";
+ break;
+ case FPDF_UNSP_DOC_SECURITY:
+ feature = "Rights_Management";
+ break;
+ case FPDF_UNSP_DOC_SHAREDREVIEW:
+ feature = "Shared_Review";
+ break;
+ case FPDF_UNSP_DOC_SHAREDFORM_ACROBAT:
+ case FPDF_UNSP_DOC_SHAREDFORM_FILESYSTEM:
+ case FPDF_UNSP_DOC_SHAREDFORM_EMAIL:
+ feature = "Shared_Form";
+ break;
+ case FPDF_UNSP_ANNOT_3DANNOT:
+ feature = "3D";
+ break;
+ case FPDF_UNSP_ANNOT_MOVIE:
+ feature = "Movie";
+ break;
+ case FPDF_UNSP_ANNOT_SOUND:
+ feature = "Sound";
+ break;
+ case FPDF_UNSP_ANNOT_SCREEN_MEDIA:
+ case FPDF_UNSP_ANNOT_SCREEN_RICHMEDIA:
+ feature = "Screen";
+ break;
+ case FPDF_UNSP_ANNOT_SIG:
+ feature = "Digital_Signature";
+ break;
+ }
+ client_->DocumentHasUnsupportedFeature(feature);
+}
+
+void PDFiumEngine::ContinueFind(int32_t result) {
+ StartFind(current_find_text_.c_str(), !!result);
+}
+
+bool PDFiumEngine::HandleEvent(const pp::InputEvent& event) {
+ DCHECK(!defer_page_unload_);
+ defer_page_unload_ = true;
+ bool rv = false;
+ switch (event.GetType()) {
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ rv = OnMouseDown(pp::MouseInputEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEUP:
+ rv = OnMouseUp(pp::MouseInputEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ rv = OnMouseMove(pp::MouseInputEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_KEYDOWN:
+ rv = OnKeyDown(pp::KeyboardInputEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_KEYUP:
+ rv = OnKeyUp(pp::KeyboardInputEvent(event));
+ break;
+ case PP_INPUTEVENT_TYPE_CHAR:
+ rv = OnChar(pp::KeyboardInputEvent(event));
+ break;
+ default:
+ break;
+ }
+
+ DCHECK(defer_page_unload_);
+ defer_page_unload_ = false;
+ for (size_t i = 0; i < deferred_page_unloads_.size(); ++i)
+ pages_[deferred_page_unloads_[i]]->Unload();
+ deferred_page_unloads_.clear();
+ return rv;
+}
+
+uint32_t PDFiumEngine::QuerySupportedPrintOutputFormats() {
+ if (!HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY))
+ return 0;
+ return PP_PRINTOUTPUTFORMAT_PDF;
+}
+
+void PDFiumEngine::PrintBegin() {
+ FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_WP);
+}
+
+pp::Resource PDFiumEngine::PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
+ const PP_PrintSettings_Dev& print_settings) {
+ if (HasPermission(PDFEngine::PERMISSION_PRINT_HIGH_QUALITY))
+ return PrintPagesAsPDF(page_ranges, page_range_count, print_settings);
+ else if (HasPermission(PDFEngine::PERMISSION_PRINT_LOW_QUALITY))
+ return PrintPagesAsRasterPDF(page_ranges, page_range_count, print_settings);
+ return pp::Resource();
+}
+
+FPDF_DOCUMENT PDFiumEngine::CreateSinglePageRasterPdf(
+ double source_page_width,
+ double source_page_height,
+ const PP_PrintSettings_Dev& print_settings,
+ PDFiumPage* page_to_print) {
+ FPDF_DOCUMENT temp_doc = FPDF_CreateNewDocument();
+ if (!temp_doc)
+ return temp_doc;
+
+ const pp::Size& bitmap_size(page_to_print->rect().size());
+
+ FPDF_PAGE temp_page =
+ FPDFPage_New(temp_doc, 0, source_page_width, source_page_height);
+
+ pp::ImageData image = pp::ImageData(client_->GetPluginInstance(),
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ bitmap_size,
+ false);
+
+ FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(bitmap_size.width(),
+ bitmap_size.height(),
+ FPDFBitmap_BGRx,
+ image.data(),
+ image.stride());
+
+ // Clear the bitmap
+ FPDFBitmap_FillRect(
+ bitmap, 0, 0, bitmap_size.width(), bitmap_size.height(), 0xFFFFFFFF);
+
+ pp::Rect page_rect = page_to_print->rect();
+ FPDF_RenderPageBitmap(bitmap,
+ page_to_print->GetPrintPage(),
+ page_rect.x(),
+ page_rect.y(),
+ page_rect.width(),
+ page_rect.height(),
+ print_settings.orientation,
+ FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+
+ double ratio_x = (static_cast<double>(bitmap_size.width()) * kPointsPerInch) /
+ print_settings.dpi;
+ double ratio_y =
+ (static_cast<double>(bitmap_size.height()) * kPointsPerInch) /
+ print_settings.dpi;
+
+ // Add the bitmap to an image object and add the image object to the output
+ // page.
+ FPDF_PAGEOBJECT temp_img = FPDFPageObj_NewImgeObj(temp_doc);
+ FPDFImageObj_SetBitmap(&temp_page, 1, temp_img, bitmap);
+ FPDFImageObj_SetMatrix(temp_img, ratio_x, 0, 0, ratio_y, 0, 0);
+ FPDFPage_InsertObject(temp_page, temp_img);
+ FPDFPage_GenerateContent(temp_page);
+ FPDF_ClosePage(temp_page);
+
+ page_to_print->ClosePrintPage();
+ FPDFBitmap_Destroy(bitmap);
+
+ return temp_doc;
+}
+
+pp::Buffer_Dev PDFiumEngine::PrintPagesAsRasterPDF(
+ const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
+ const PP_PrintSettings_Dev& print_settings) {
+ if (!page_range_count)
+ return pp::Buffer_Dev();
+
+ // If document is not downloaded yet, disable printing.
+ if (doc_ && !doc_loader_.IsDocumentComplete())
+ return pp::Buffer_Dev();
+
+ FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+ if (!output_doc)
+ return pp::Buffer_Dev();
+
+ SaveSelectedFormForPrint();
+
+ std::vector<PDFiumPage> pages_to_print;
+ // width and height of source PDF pages.
+ std::vector<std::pair<double, double> > source_page_sizes;
+ // Collect pages to print and sizes of source pages.
+ std::vector<uint32_t> page_numbers =
+ GetPageNumbersFromPrintPageNumberRange(page_ranges, page_range_count);
+ for (size_t i = 0; i < page_numbers.size(); ++i) {
+ uint32_t page_number = page_numbers[i];
+ FPDF_PAGE pdf_page = FPDF_LoadPage(doc_, page_number);
+ double source_page_width = FPDF_GetPageWidth(pdf_page);
+ double source_page_height = FPDF_GetPageHeight(pdf_page);
+ source_page_sizes.push_back(std::make_pair(source_page_width,
+ source_page_height));
+
+ int width_in_pixels = ConvertUnit(source_page_width,
+ static_cast<int>(kPointsPerInch),
+ print_settings.dpi);
+ int height_in_pixels = ConvertUnit(source_page_height,
+ static_cast<int>(kPointsPerInch),
+ print_settings.dpi);
+
+ pp::Rect rect(width_in_pixels, height_in_pixels);
+ pages_to_print.push_back(PDFiumPage(this, page_number, rect, true));
+ FPDF_ClosePage(pdf_page);
+ }
+
+#if defined(OS_LINUX)
+ g_last_instance_id = client_->GetPluginInstance()->pp_instance();
+#endif
+
+ size_t i = 0;
+ for (; i < pages_to_print.size(); ++i) {
+ double source_page_width = source_page_sizes[i].first;
+ double source_page_height = source_page_sizes[i].second;
+
+ // Use temp_doc to compress image by saving PDF to buffer.
+ FPDF_DOCUMENT temp_doc = CreateSinglePageRasterPdf(source_page_width,
+ source_page_height,
+ print_settings,
+ &pages_to_print[i]);
+
+ if (!temp_doc)
+ break;
+
+ pp::Buffer_Dev buffer = GetFlattenedPrintData(temp_doc);
+ FPDF_CloseDocument(temp_doc);
+
+ PDFiumMemBufferFileRead file_read(buffer.data(), buffer.size());
+ temp_doc = FPDF_LoadCustomDocument(&file_read, NULL);
+
+ FPDF_BOOL imported = FPDF_ImportPages(output_doc, temp_doc, "1", i);
+ FPDF_CloseDocument(temp_doc);
+ if (!imported)
+ break;
+ }
+
+ pp::Buffer_Dev buffer;
+ if (i == pages_to_print.size()) {
+ FPDF_CopyViewerPreferences(output_doc, doc_);
+ FitContentsToPrintableAreaIfRequired(output_doc, print_settings);
+ // Now flatten all the output pages.
+ buffer = GetFlattenedPrintData(output_doc);
+ }
+ FPDF_CloseDocument(output_doc);
+ return buffer;
+}
+
+pp::Buffer_Dev PDFiumEngine::GetFlattenedPrintData(const FPDF_DOCUMENT& doc) {
+ int page_count = FPDF_GetPageCount(doc);
+ bool flatten_succeeded = true;
+ for (int i = 0; i < page_count; ++i) {
+ FPDF_PAGE page = FPDF_LoadPage(doc, i);
+ DCHECK(page);
+ if (page) {
+ int flatten_ret = FPDFPage_Flatten(page, FLAT_PRINT);
+ FPDF_ClosePage(page);
+ if (flatten_ret == FLATTEN_FAIL) {
+ flatten_succeeded = false;
+ break;
+ }
+ } else {
+ flatten_succeeded = false;
+ break;
+ }
+ }
+ if (!flatten_succeeded) {
+ FPDF_CloseDocument(doc);
+ return pp::Buffer_Dev();
+ }
+
+ pp::Buffer_Dev buffer;
+ PDFiumMemBufferFileWrite output_file_write;
+ if (FPDF_SaveAsCopy(doc, &output_file_write, 0)) {
+ buffer = pp::Buffer_Dev(
+ client_->GetPluginInstance(), output_file_write.size());
+ if (!buffer.is_null()) {
+ memcpy(buffer.data(), output_file_write.buffer().c_str(),
+ output_file_write.size());
+ }
+ }
+ return buffer;
+}
+
+pp::Buffer_Dev PDFiumEngine::PrintPagesAsPDF(
+ const PP_PrintPageNumberRange_Dev* page_ranges, uint32_t page_range_count,
+ const PP_PrintSettings_Dev& print_settings) {
+ if (!page_range_count)
+ return pp::Buffer_Dev();
+
+ DCHECK(doc_);
+ FPDF_DOCUMENT output_doc = FPDF_CreateNewDocument();
+ if (!output_doc)
+ return pp::Buffer_Dev();
+
+ SaveSelectedFormForPrint();
+
+ std::string page_number_str;
+ for (uint32_t index = 0; index < page_range_count; ++index) {
+ if (!page_number_str.empty())
+ page_number_str.append(",");
+ page_number_str.append(
+ base::IntToString(page_ranges[index].first_page_number + 1));
+ if (page_ranges[index].first_page_number !=
+ page_ranges[index].last_page_number) {
+ page_number_str.append("-");
+ page_number_str.append(
+ base::IntToString(page_ranges[index].last_page_number + 1));
+ }
+ }
+
+ std::vector<uint32_t> page_numbers =
+ GetPageNumbersFromPrintPageNumberRange(page_ranges, page_range_count);
+ for (size_t i = 0; i < page_numbers.size(); ++i) {
+ uint32_t page_number = page_numbers[i];
+ pages_[page_number]->GetPage();
+ if (!IsPageVisible(page_numbers[i]))
+ pages_[page_number]->Unload();
+ }
+
+ FPDF_CopyViewerPreferences(output_doc, doc_);
+ if (!FPDF_ImportPages(output_doc, doc_, page_number_str.c_str(), 0)) {
+ FPDF_CloseDocument(output_doc);
+ return pp::Buffer_Dev();
+ }
+
+ FitContentsToPrintableAreaIfRequired(output_doc, print_settings);
+
+ // Now flatten all the output pages.
+ pp::Buffer_Dev buffer = GetFlattenedPrintData(output_doc);
+ FPDF_CloseDocument(output_doc);
+ return buffer;
+}
+
+void PDFiumEngine::FitContentsToPrintableAreaIfRequired(
+ const FPDF_DOCUMENT& doc, const PP_PrintSettings_Dev& print_settings) {
+ // Check to see if we need to fit pdf contents to printer paper size.
+ if (print_settings.print_scaling_option !=
+ PP_PRINTSCALINGOPTION_SOURCE_SIZE) {
+ int num_pages = FPDF_GetPageCount(doc);
+ // In-place transformation is more efficient than creating a new
+ // transformed document from the source document. Therefore, transform
+ // every page to fit the contents in the selected printer paper.
+ for (int i = 0; i < num_pages; ++i) {
+ FPDF_PAGE page = FPDF_LoadPage(doc, i);
+ TransformPDFPageForPrinting(page, print_settings);
+ FPDF_ClosePage(page);
+ }
+ }
+}
+
+void PDFiumEngine::SaveSelectedFormForPrint() {
+ FORM_ForceToKillFocus(form_);
+ client_->FormTextFieldFocusChange(false);
+}
+
+void PDFiumEngine::PrintEnd() {
+ FORM_DoDocumentAAction(form_, FPDFDOC_AACTION_DP);
+}
+
+PDFiumPage::Area PDFiumEngine::GetCharIndex(
+ const pp::MouseInputEvent& event, int* page_index,
+ int* char_index, PDFiumPage::LinkTarget* target) {
+ // First figure out which page this is in.
+ pp::Point mouse_point = event.GetPosition();
+ pp::Point point(
+ static_cast<int>((mouse_point.x() + position_.x()) / current_zoom_),
+ static_cast<int>((mouse_point.y() + position_.y()) / current_zoom_));
+ return GetCharIndex(point, page_index, char_index, target);
+}
+
+PDFiumPage::Area PDFiumEngine::GetCharIndex(
+ const pp::Point& point,
+ int* page_index,
+ int* char_index,
+ PDFiumPage::LinkTarget* target) {
+ int page = -1;
+ for (size_t i = 0; i < visible_pages_.size(); ++i) {
+ if (pages_[visible_pages_[i]]->rect().Contains(point)) {
+ page = visible_pages_[i];
+ break;
+ }
+ }
+ if (page == -1)
+ return PDFiumPage::NONSELECTABLE_AREA;
+
+ // If the page hasn't finished rendering, calling into the page sometimes
+ // leads to hangs.
+ for (size_t i = 0; i < progressive_paints_.size(); ++i) {
+ if (progressive_paints_[i].page_index == page)
+ return PDFiumPage::NONSELECTABLE_AREA;
+ }
+
+ *page_index = page;
+ return pages_[page]->GetCharIndex(point, current_rotation_, char_index,
+ target);
+}
+
+bool PDFiumEngine::OnMouseDown(const pp::MouseInputEvent& event) {
+ if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT)
+ return false;
+
+ SelectionChangeInvalidator selection_invalidator(this);
+ selection_.clear();
+
+ int page_index = -1;
+ int char_index = -1;
+ PDFiumPage::LinkTarget target;
+ PDFiumPage::Area area = GetCharIndex(event, &page_index,
+ &char_index, &target);
+ mouse_down_state_.Set(area, target);
+
+ // Decide whether to open link or not based on user action in mouse up and
+ // mouse move events.
+ if (area == PDFiumPage::WEBLINK_AREA)
+ return true;
+
+ if (area == PDFiumPage::DOCLINK_AREA) {
+ client_->ScrollToPage(target.page);
+ client_->FormTextFieldFocusChange(false);
+ return true;
+ }
+
+ if (page_index != -1) {
+ last_page_mouse_down_ = page_index;
+ double page_x, page_y;
+ pp::Point point = event.GetPosition();
+ DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
+
+ FORM_OnLButtonDown(form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
+ int control = FPDPage_HasFormFieldAtPoint(
+ form_, pages_[page_index]->GetPage(), page_x, page_y);
+ if (control > FPDF_FORMFIELD_UNKNOWN) { // returns -1 sometimes...
+#ifdef _TEST_XFA
+ client_->FormTextFieldFocusChange(control == FPDF_FORMFIELD_TEXTFIELD ||
+ control == FPDF_FORMFIELD_COMBOBOX ||
+ control == FPDF_FORMFIELD_XFA);
+#else
+ client_->FormTextFieldFocusChange(control == FPDF_FORMFIELD_TEXTFIELD ||
+ control == FPDF_FORMFIELD_COMBOBOX);
+#endif
+ return true; // Return now before we get into the selection code.
+ }
+ }
+
+ client_->FormTextFieldFocusChange(false);
+
+ if (area != PDFiumPage::TEXT_AREA)
+ return true; // Return true so WebKit doesn't do its own highlighting.
+
+ if (event.GetClickCount() == 1) {
+ OnSingleClick(page_index, char_index);
+ } else if (event.GetClickCount() == 2 ||
+ event.GetClickCount() == 3) {
+ OnMultipleClick(event.GetClickCount(), page_index, char_index);
+ }
+
+ return true;
+}
+
+void PDFiumEngine::OnSingleClick(int page_index, int char_index) {
+ selecting_ = true;
+ selection_.push_back(PDFiumRange(pages_[page_index], char_index, 0));
+}
+
+void PDFiumEngine::OnMultipleClick(int click_count,
+ int page_index,
+ int char_index) {
+ // It would be more efficient if the SDK could support finding a space, but
+ // now it doesn't.
+ int start_index = char_index;
+ do {
+ base::char16 cur = pages_[page_index]->GetCharAtIndex(start_index);
+ // For double click, we want to select one word so we look for whitespace
+ // boundaries. For triple click, we want the whole line.
+ if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t')))
+ break;
+ } while (--start_index >= 0);
+ if (start_index)
+ start_index++;
+
+ int end_index = char_index;
+ int total = pages_[page_index]->GetCharCount();
+ while (end_index++ <= total) {
+ base::char16 cur = pages_[page_index]->GetCharAtIndex(end_index);
+ if (cur == '\n' || (click_count == 2 && (cur == ' ' || cur == '\t')))
+ break;
+ }
+
+ selection_.push_back(PDFiumRange(
+ pages_[page_index], start_index, end_index - start_index));
+}
+
+bool PDFiumEngine::OnMouseUp(const pp::MouseInputEvent& event) {
+ if (event.GetButton() != PP_INPUTEVENT_MOUSEBUTTON_LEFT)
+ return false;
+
+ int page_index = -1;
+ int char_index = -1;
+ PDFiumPage::LinkTarget target;
+ PDFiumPage::Area area =
+ GetCharIndex(event, &page_index, &char_index, &target);
+
+ // Open link on mouse up for same link for which mouse down happened earlier.
+ if (mouse_down_state_.Matches(area, target)) {
+ if (area == PDFiumPage::WEBLINK_AREA) {
+ bool open_in_new_tab = !!(event.GetModifiers() & kDefaultKeyModifier);
+ client_->NavigateTo(target.url, open_in_new_tab);
+ client_->FormTextFieldFocusChange(false);
+ return true;
+ }
+ }
+
+ if (page_index != -1) {
+ double page_x, page_y;
+ pp::Point point = event.GetPosition();
+ DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
+ FORM_OnLButtonUp(
+ form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
+ }
+
+ if (!selecting_)
+ return false;
+
+ selecting_ = false;
+ return true;
+}
+
+bool PDFiumEngine::OnMouseMove(const pp::MouseInputEvent& event) {
+ int page_index = -1;
+ int char_index = -1;
+ PDFiumPage::LinkTarget target;
+ PDFiumPage::Area area =
+ GetCharIndex(event, &page_index, &char_index, &target);
+
+ // Clear |mouse_down_state_| if mouse moves away from where the mouse down
+ // happened.
+ if (!mouse_down_state_.Matches(area, target))
+ mouse_down_state_.Reset();
+
+ if (!selecting_) {
+ PP_CursorType_Dev cursor;
+ switch (area) {
+ case PDFiumPage::TEXT_AREA:
+ cursor = PP_CURSORTYPE_IBEAM;
+ break;
+ case PDFiumPage::WEBLINK_AREA:
+ case PDFiumPage::DOCLINK_AREA:
+ cursor = PP_CURSORTYPE_HAND;
+ break;
+ case PDFiumPage::NONSELECTABLE_AREA:
+ default:
+ cursor = PP_CURSORTYPE_POINTER;
+ break;
+ }
+
+ if (page_index != -1) {
+ double page_x, page_y;
+ pp::Point point = event.GetPosition();
+ DeviceToPage(page_index, point.x(), point.y(), &page_x, &page_y);
+
+ FORM_OnMouseMove(form_, pages_[page_index]->GetPage(), 0, page_x, page_y);
+ int control = FPDPage_HasFormFieldAtPoint(
+ form_, pages_[page_index]->GetPage(), page_x, page_y);
+ switch (control) {
+ case FPDF_FORMFIELD_PUSHBUTTON:
+ case FPDF_FORMFIELD_CHECKBOX:
+ case FPDF_FORMFIELD_RADIOBUTTON:
+ case FPDF_FORMFIELD_COMBOBOX:
+ case FPDF_FORMFIELD_LISTBOX:
+ cursor = PP_CURSORTYPE_HAND;
+ break;
+ case FPDF_FORMFIELD_TEXTFIELD:
+ cursor = PP_CURSORTYPE_IBEAM;
+ break;
+ default:
+ break;
+ }
+ }
+
+ client_->UpdateCursor(cursor);
+ pp::Point point = event.GetPosition();
+ std::string url = GetLinkAtPosition(event.GetPosition());
+ if (url != link_under_cursor_) {
+ link_under_cursor_ = url;
+ pp::PDF::SetLinkUnderCursor(GetPluginInstance(), url.c_str());
+ }
+ // No need to swallow the event, since this might interfere with the
+ // scrollbars if the user is dragging them.
+ return false;
+ }
+
+ // We're selecting but right now we're not over text, so don't change the
+ // current selection.
+ if (area != PDFiumPage::TEXT_AREA && area != PDFiumPage::WEBLINK_AREA &&
+ area != PDFiumPage::DOCLINK_AREA) {
+ return false;
+ }
+
+ SelectionChangeInvalidator selection_invalidator(this);
+
+ // Check if the user has descreased their selection area and we need to remove
+ // pages from selection_.
+ for (size_t i = 0; i < selection_.size(); ++i) {
+ if (selection_[i].page_index() == page_index) {
+ // There should be no other pages after this.
+ selection_.erase(selection_.begin() + i + 1, selection_.end());
+ break;
+ }
+ }
+
+ if (selection_.size() == 0)
+ return false;
+
+ int last = selection_.size() - 1;
+ if (selection_[last].page_index() == page_index) {
+ // Selecting within a page.
+ int count;
+ if (char_index >= selection_[last].char_index()) {
+ // Selecting forward.
+ count = char_index - selection_[last].char_index() + 1;
+ } else {
+ count = char_index - selection_[last].char_index() - 1;
+ }
+ selection_[last].SetCharCount(count);
+ } else if (selection_[last].page_index() < page_index) {
+ // Selecting into the next page.
+
+ // First make sure that there are no gaps in selection, i.e. if mousedown on
+ // page one but we only get mousemove over page three, we want page two.
+ for (int i = selection_[last].page_index() + 1; i < page_index; ++i) {
+ selection_.push_back(PDFiumRange(pages_[i], 0,
+ pages_[i]->GetCharCount()));
+ }
+
+ int count = pages_[selection_[last].page_index()]->GetCharCount();
+ selection_[last].SetCharCount(count - selection_[last].char_index());
+ selection_.push_back(PDFiumRange(pages_[page_index], 0, char_index));
+ } else {
+ // Selecting into the previous page.
+ selection_[last].SetCharCount(-selection_[last].char_index());
+
+ // First make sure that there are no gaps in selection, i.e. if mousedown on
+ // page three but we only get mousemove over page one, we want page two.
+ for (int i = selection_[last].page_index() - 1; i > page_index; --i) {
+ selection_.push_back(PDFiumRange(pages_[i], 0,
+ pages_[i]->GetCharCount()));
+ }
+
+ int count = pages_[page_index]->GetCharCount();
+ selection_.push_back(
+ PDFiumRange(pages_[page_index], count, count - char_index));
+ }
+
+ return true;
+}
+
+bool PDFiumEngine::OnKeyDown(const pp::KeyboardInputEvent& event) {
+ if (last_page_mouse_down_ == -1)
+ return false;
+
+ bool rv = !!FORM_OnKeyDown(
+ form_, pages_[last_page_mouse_down_]->GetPage(),
+ event.GetKeyCode(), event.GetModifiers());
+
+ if (event.GetKeyCode() == ui::VKEY_BACK ||
+ event.GetKeyCode() == ui::VKEY_ESCAPE) {
+ // Chrome doesn't send char events for backspace or escape keys, see
+ // PlatformKeyboardEventBuilder::isCharacterKey() and
+ // http://chrome-corpsvn.mtv.corp.google.com/viewvc?view=rev&root=chrome&revision=31805
+ // for more information. So just fake one since PDFium uses it.
+ std::string str;
+ str.push_back(event.GetKeyCode());
+ pp::KeyboardInputEvent synthesized(pp::KeyboardInputEvent(
+ client_->GetPluginInstance(),
+ PP_INPUTEVENT_TYPE_CHAR,
+ event.GetTimeStamp(),
+ event.GetModifiers(),
+ event.GetKeyCode(),
+ str));
+ OnChar(synthesized);
+ }
+
+ return rv;
+}
+
+bool PDFiumEngine::OnKeyUp(const pp::KeyboardInputEvent& event) {
+ if (last_page_mouse_down_ == -1)
+ return false;
+
+ return !!FORM_OnKeyUp(
+ form_, pages_[last_page_mouse_down_]->GetPage(),
+ event.GetKeyCode(), event.GetModifiers());
+}
+
+bool PDFiumEngine::OnChar(const pp::KeyboardInputEvent& event) {
+ if (last_page_mouse_down_ == -1)
+ return false;
+
+ base::string16 str = base::UTF8ToUTF16(event.GetCharacterText().AsString());
+ return !!FORM_OnChar(
+ form_, pages_[last_page_mouse_down_]->GetPage(),
+ str[0],
+ event.GetModifiers());
+}
+
+void PDFiumEngine::StartFind(const char* text, bool case_sensitive) {
+ // We can get a call to StartFind before we have any page information (i.e.
+ // before the first call to LoadDocument has happened). Handle this case.
+ if (pages_.empty())
+ return;
+
+ bool first_search = false;
+ int character_to_start_searching_from = 0;
+ if (current_find_text_ != text) { // First time we search for this text.
+ first_search = true;
+ std::vector<PDFiumRange> old_selection = selection_;
+ StopFind();
+ current_find_text_ = text;
+
+ if (old_selection.empty()) {
+ // Start searching from the beginning of the document.
+ next_page_to_search_ = 0;
+ last_page_to_search_ = pages_.size() - 1;
+ last_character_index_to_search_ = -1;
+ } else {
+ // There's a current selection, so start from it.
+ next_page_to_search_ = old_selection[0].page_index();
+ last_character_index_to_search_ = old_selection[0].char_index();
+ character_to_start_searching_from = old_selection[0].char_index();
+ last_page_to_search_ = next_page_to_search_;
+ }
+ }
+
+ int current_page = next_page_to_search_;
+
+ if (pages_[current_page]->available()) {
+ base::string16 str = base::UTF8ToUTF16(text);
+ // Don't use PDFium to search for now, since it doesn't support unicode text.
+ // Leave the code for now to avoid bit-rot, in case it's fixed later.
+ if (0) {
+ SearchUsingPDFium(
+ str, case_sensitive, first_search, character_to_start_searching_from,
+ current_page);
+ } else {
+ SearchUsingICU(
+ str, case_sensitive, first_search, character_to_start_searching_from,
+ current_page);
+ }
+
+ if (!IsPageVisible(current_page))
+ pages_[current_page]->Unload();
+ }
+
+ if (next_page_to_search_ != last_page_to_search_ ||
+ (first_search && last_character_index_to_search_ != -1)) {
+ ++next_page_to_search_;
+ }
+
+ if (next_page_to_search_ == static_cast<int>(pages_.size()))
+ next_page_to_search_ = 0;
+ // If there's only one page in the document and we start searching midway,
+ // then we'll want to search the page one more time.
+ bool end_of_search =
+ next_page_to_search_ == last_page_to_search_ &&
+ // Only one page but didn't start midway.
+ ((pages_.size() == 1 && last_character_index_to_search_ == -1) ||
+ // Started midway, but only 1 page and we already looped around.
+ (pages_.size() == 1 && !first_search) ||
+ // Started midway, and we've just looped around.
+ (pages_.size() > 1 && current_page == next_page_to_search_));
+
+ if (end_of_search) {
+ // Send the final notification.
+ client_->NotifyNumberOfFindResultsChanged(find_results_.size(), true);
+
+ // When searching is complete, resume finding at a particular index.
+ if (resume_find_index_ != -1) {
+ current_find_index_ = resume_find_index_;
+ resume_find_index_ = -1;
+ }
+ } else {
+ pp::CompletionCallback callback =
+ find_factory_.NewCallback(&PDFiumEngine::ContinueFind);
+ pp::Module::Get()->core()->CallOnMainThread(
+ 0, callback, case_sensitive ? 1 : 0);
+ }
+}
+
+void PDFiumEngine::SearchUsingPDFium(const base::string16& term,
+ bool case_sensitive,
+ bool first_search,
+ int character_to_start_searching_from,
+ int current_page) {
+ // Find all the matches in the current page.
+ unsigned long flags = case_sensitive ? FPDF_MATCHCASE : 0;
+ FPDF_SCHHANDLE find = FPDFText_FindStart(
+ pages_[current_page]->GetTextPage(),
+ reinterpret_cast<const unsigned short*>(term.c_str()),
+ flags, character_to_start_searching_from);
+
+ // Note: since we search one page at a time, we don't find matches across
+ // page boundaries. We could do this manually ourself, but it seems low
+ // priority since Reader itself doesn't do it.
+ while (FPDFText_FindNext(find)) {
+ PDFiumRange result(pages_[current_page],
+ FPDFText_GetSchResultIndex(find),
+ FPDFText_GetSchCount(find));
+
+ if (!first_search &&
+ last_character_index_to_search_ != -1 &&
+ result.page_index() == last_page_to_search_ &&
+ result.char_index() >= last_character_index_to_search_) {
+ break;
+ }
+
+ AddFindResult(result);
+ }
+
+ FPDFText_FindClose(find);
+}
+
+void PDFiumEngine::SearchUsingICU(const base::string16& term,
+ bool case_sensitive,
+ bool first_search,
+ int character_to_start_searching_from,
+ int current_page) {
+ base::string16 page_text;
+ int text_length = pages_[current_page]->GetCharCount();
+ if (character_to_start_searching_from) {
+ text_length -= character_to_start_searching_from;
+ } else if (!first_search &&
+ last_character_index_to_search_ != -1 &&
+ current_page == last_page_to_search_) {
+ text_length = last_character_index_to_search_;
+ }
+ if (text_length <= 0)
+ return;
+ unsigned short* data =
+ reinterpret_cast<unsigned short*>(WriteInto(&page_text, text_length + 1));
+ FPDFText_GetText(pages_[current_page]->GetTextPage(),
+ character_to_start_searching_from,
+ text_length,
+ data);
+ std::vector<PDFEngine::Client::SearchStringResult> results;
+ client_->SearchString(
+ page_text.c_str(), term.c_str(), case_sensitive, &results);
+ for (size_t i = 0; i < results.size(); ++i) {
+ // Need to map the indexes from the page text, which may have generated
+ // characters like space etc, to character indices from the page.
+ int temp_start = results[i].start_index + character_to_start_searching_from;
+ int start = FPDFText_GetCharIndexFromTextIndex(
+ pages_[current_page]->GetTextPage(), temp_start);
+ int end = FPDFText_GetCharIndexFromTextIndex(
+ pages_[current_page]->GetTextPage(),
+ temp_start + results[i].length);
+ AddFindResult(PDFiumRange(pages_[current_page], start, end - start));
+ }
+}
+
+void PDFiumEngine::AddFindResult(const PDFiumRange& result) {
+ // Figure out where to insert the new location, since we could have
+ // started searching midway and now we wrapped.
+ size_t i;
+ int page_index = result.page_index();
+ int char_index = result.char_index();
+ for (i = 0; i < find_results_.size(); ++i) {
+ if (find_results_[i].page_index() > page_index ||
+ (find_results_[i].page_index() == page_index &&
+ find_results_[i].char_index() > char_index)) {
+ break;
+ }
+ }
+ find_results_.insert(find_results_.begin() + i, result);
+ UpdateTickMarks();
+
+ if (current_find_index_ == -1 && resume_find_index_ == -1) {
+ // Select the first match.
+ SelectFindResult(true);
+ } else if (static_cast<int>(i) <= current_find_index_) {
+ // Update the current match index
+ current_find_index_++;
+ client_->NotifySelectedFindResultChanged(current_find_index_);
+ }
+ client_->NotifyNumberOfFindResultsChanged(find_results_.size(), false);
+}
+
+bool PDFiumEngine::SelectFindResult(bool forward) {
+ if (find_results_.empty()) {
+ NOTREACHED();
+ return false;
+ }
+
+ SelectionChangeInvalidator selection_invalidator(this);
+
+ // Move back/forward through the search locations we previously found.
+ if (forward) {
+ if (++current_find_index_ == static_cast<int>(find_results_.size()))
+ current_find_index_ = 0;
+ } else {
+ if (--current_find_index_ < 0) {
+ current_find_index_ = find_results_.size() - 1;
+ }
+ }
+
+ // Update the selection before telling the client to scroll, since it could
+ // paint then.
+ selection_.clear();
+ selection_.push_back(find_results_[current_find_index_]);
+
+ // If the result is not in view, scroll to it.
+ size_t i;
+ pp::Rect bounding_rect;
+ pp::Rect visible_rect = GetVisibleRect();
+ // Use zoom of 1.0 since visible_rect is without zoom.
+ std::vector<pp::Rect> rects = find_results_[current_find_index_].
+ GetScreenRects(pp::Point(), 1.0, current_rotation_);
+ for (i = 0; i < rects.size(); ++i)
+ bounding_rect = bounding_rect.Union(rects[i]);
+ if (!visible_rect.Contains(bounding_rect)) {
+ pp::Point center = bounding_rect.CenterPoint();
+ // Make the page centered.
+ int new_y = static_cast<int>(center.y() * current_zoom_) -
+ static_cast<int>(visible_rect.height() * current_zoom_ / 2);
+ if (new_y < 0)
+ new_y = 0;
+ client_->ScrollToY(new_y);
+
+ // Only move horizontally if it's not visible.
+ if (center.x() < visible_rect.x() || center.x() > visible_rect.right()) {
+ int new_x = static_cast<int>(center.x() * current_zoom_) -
+ static_cast<int>(visible_rect.width() * current_zoom_ / 2);
+ if (new_x < 0)
+ new_x = 0;
+ client_->ScrollToX(new_x);
+ }
+ }
+
+ client_->NotifySelectedFindResultChanged(current_find_index_);
+
+ return true;
+}
+
+void PDFiumEngine::StopFind() {
+ SelectionChangeInvalidator selection_invalidator(this);
+
+ selection_.clear();
+ selecting_ = false;
+ find_results_.clear();
+ next_page_to_search_ = -1;
+ last_page_to_search_ = -1;
+ last_character_index_to_search_ = -1;
+ current_find_index_ = -1;
+ current_find_text_.clear();
+ UpdateTickMarks();
+ find_factory_.CancelAll();
+}
+
+void PDFiumEngine::UpdateTickMarks() {
+ std::vector<pp::Rect> tickmarks;
+ for (size_t i = 0; i < find_results_.size(); ++i) {
+ pp::Rect rect;
+ // Always use an origin of 0,0 since scroll positions don't affect tickmark.
+ std::vector<pp::Rect> rects = find_results_[i].GetScreenRects(
+ pp::Point(0, 0), current_zoom_, current_rotation_);
+ for (size_t j = 0; j < rects.size(); ++j)
+ rect = rect.Union(rects[j]);
+ tickmarks.push_back(rect);
+ }
+
+ client_->UpdateTickMarks(tickmarks);
+}
+
+void PDFiumEngine::ZoomUpdated(double new_zoom_level) {
+ CancelPaints();
+
+ current_zoom_ = new_zoom_level;
+
+ CalculateVisiblePages();
+ UpdateTickMarks();
+}
+
+void PDFiumEngine::RotateClockwise() {
+ current_rotation_ = (current_rotation_ + 1) % 4;
+
+ // Store the current find index so that we can resume finding at that
+ // particular index after we have recomputed the find results.
+ std::string current_find_text = current_find_text_;
+ resume_find_index_ = current_find_index_;
+
+ InvalidateAllPages();
+
+ if (!current_find_text.empty())
+ StartFind(current_find_text.c_str(), false);
+}
+
+void PDFiumEngine::RotateCounterclockwise() {
+ current_rotation_ = (current_rotation_ - 1) % 4;
+
+ // Store the current find index so that we can resume finding at that
+ // particular index after we have recomputed the find results.
+ std::string current_find_text = current_find_text_;
+ resume_find_index_ = current_find_index_;
+
+ InvalidateAllPages();
+
+ if (!current_find_text.empty())
+ StartFind(current_find_text.c_str(), false);
+}
+
+void PDFiumEngine::InvalidateAllPages() {
+ CancelPaints();
+ StopFind();
+ LoadPageInfo(true);
+ client_->Invalidate(pp::Rect(plugin_size_));
+}
+
+std::string PDFiumEngine::GetSelectedText() {
+ base::string16 result;
+ for (size_t i = 0; i < selection_.size(); ++i) {
+ if (i > 0 &&
+ selection_[i - 1].page_index() > selection_[i].page_index()) {
+ result = selection_[i].GetText() + result;
+ } else {
+ result.append(selection_[i].GetText());
+ }
+ }
+
+ FormatStringWithHyphens(&result);
+ FormatStringForOS(&result);
+ return base::UTF16ToUTF8(result);
+}
+
+std::string PDFiumEngine::GetLinkAtPosition(const pp::Point& point) {
+ int temp;
+ PDFiumPage::LinkTarget target;
+ pp::Point point_in_page(
+ static_cast<int>((point.x() + position_.x()) / current_zoom_),
+ static_cast<int>((point.y() + position_.y()) / current_zoom_));
+ PDFiumPage::Area area = GetCharIndex(point_in_page, &temp, &temp, &target);
+ if (area == PDFiumPage::WEBLINK_AREA)
+ return target.url;
+ return std::string();
+}
+
+bool PDFiumEngine::IsSelecting() {
+ return selecting_;
+}
+
+bool PDFiumEngine::HasPermission(DocumentPermission permission) const {
+ switch (permission) {
+ case PERMISSION_COPY:
+ return (permissions_ & kPDFPermissionCopyMask) != 0;
+ case PERMISSION_COPY_ACCESSIBLE:
+ return (permissions_ & kPDFPermissionCopyAccessibleMask) != 0;
+ case PERMISSION_PRINT_LOW_QUALITY:
+ return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0;
+ case PERMISSION_PRINT_HIGH_QUALITY:
+ return (permissions_ & kPDFPermissionPrintLowQualityMask) != 0 &&
+ (permissions_ & kPDFPermissionPrintHighQualityMask) != 0;
+ default:
+ return true;
+ };
+}
+
+void PDFiumEngine::SelectAll() {
+ SelectionChangeInvalidator selection_invalidator(this);
+
+ selection_.clear();
+ for (size_t i = 0; i < pages_.size(); ++i)
+ if (pages_[i]->available()) {
+ selection_.push_back(PDFiumRange(pages_[i], 0,
+ pages_[i]->GetCharCount()));
+ }
+}
+
+int PDFiumEngine::GetNumberOfPages() {
+ return pages_.size();
+}
+
+int PDFiumEngine::GetNamedDestinationPage(const std::string& destination) {
+ // Look for the destination.
+ FPDF_DEST dest = FPDF_GetNamedDestByName(doc_, destination.c_str());
+ if (!dest) {
+ // Look for a bookmark with the same name.
+ base::string16 destination_wide = base::UTF8ToUTF16(destination);
+ FPDF_WIDESTRING destination_pdf_wide =
+ reinterpret_cast<FPDF_WIDESTRING>(destination_wide.c_str());
+ FPDF_BOOKMARK bookmark = FPDFBookmark_Find(doc_, destination_pdf_wide);
+ if (!bookmark)
+ return -1;
+ dest = FPDFBookmark_GetDest(doc_, bookmark);
+ }
+ return dest ? FPDFDest_GetPageIndex(doc_, dest) : -1;
+}
+
+int PDFiumEngine::GetFirstVisiblePage() {
+ CalculateVisiblePages();
+ return first_visible_page_;
+}
+
+int PDFiumEngine::GetMostVisiblePage() {
+ CalculateVisiblePages();
+ return most_visible_page_;
+}
+
+pp::Rect PDFiumEngine::GetPageRect(int index) {
+ pp::Rect rc(pages_[index]->rect());
+ rc.Inset(-kPageShadowLeft, -kPageShadowTop,
+ -kPageShadowRight, -kPageShadowBottom);
+ return rc;
+}
+
+pp::Rect PDFiumEngine::GetPageContentsRect(int index) {
+ return GetScreenRect(pages_[index]->rect());
+}
+
+void PDFiumEngine::PaintThumbnail(pp::ImageData* image_data, int index) {
+ FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(
+ image_data->size().width(), image_data->size().height(),
+ FPDFBitmap_BGRx, image_data->data(), image_data->stride());
+
+ if (pages_[index]->available()) {
+ FPDFBitmap_FillRect(bitmap, 0, 0, image_data->size().width(),
+ image_data->size().height(), 0xFFFFFFFF);
+
+ FPDF_RenderPageBitmap(
+ bitmap, pages_[index]->GetPage(), 0, 0, image_data->size().width(),
+ image_data->size().height(), 0, GetRenderingFlags());
+ } else {
+ FPDFBitmap_FillRect(bitmap, 0, 0, image_data->size().width(),
+ image_data->size().height(), kPendingPageColor);
+ }
+
+ FPDFBitmap_Destroy(bitmap);
+}
+
+void PDFiumEngine::SetGrayscale(bool grayscale) {
+ render_grayscale_ = grayscale;
+}
+
+void PDFiumEngine::OnCallback(int id) {
+ if (!timers_.count(id))
+ return;
+
+ timers_[id].second(id);
+ if (timers_.count(id)) // The callback might delete the timer.
+ client_->ScheduleCallback(id, timers_[id].first);
+}
+
+std::string PDFiumEngine::GetPageAsJSON(int index) {
+ if (!(HasPermission(PERMISSION_COPY) ||
+ HasPermission(PERMISSION_COPY_ACCESSIBLE))) {
+ return "{}";
+ }
+
+ if (index < 0 || static_cast<size_t>(index) > pages_.size() - 1)
+ return "{}";
+
+ scoped_ptr<base::Value> node(
+ pages_[index]->GetAccessibleContentAsValue(current_rotation_));
+ std::string page_json;
+ base::JSONWriter::Write(node.get(), &page_json);
+ return page_json;
+}
+
+bool PDFiumEngine::GetPrintScaling() {
+ return !!FPDF_VIEWERREF_GetPrintScaling(doc_);
+}
+
+void PDFiumEngine::AppendBlankPages(int num_pages) {
+ DCHECK(num_pages != 0);
+
+ if (!doc_)
+ return;
+
+ selection_.clear();
+ pending_pages_.clear();
+
+ // Delete all pages except the first one.
+ while (pages_.size() > 1) {
+ delete pages_.back();
+ pages_.pop_back();
+ FPDFPage_Delete(doc_, pages_.size());
+ }
+
+ // Calculate document size and all page sizes.
+ std::vector<pp::Rect> page_rects;
+ pp::Size page_size = GetPageSize(0);
+ page_size.Enlarge(kPageShadowLeft + kPageShadowRight,
+ kPageShadowTop + kPageShadowBottom);
+ pp::Size old_document_size = document_size_;
+ document_size_ = pp::Size(page_size.width(), 0);
+ for (int i = 0; i < num_pages; ++i) {
+ if (i != 0) {
+ // Add space for horizontal separator.
+ document_size_.Enlarge(0, kPageSeparatorThickness);
+ }
+
+ pp::Rect rect(pp::Point(0, document_size_.height()), page_size);
+ page_rects.push_back(rect);
+
+ document_size_.Enlarge(0, page_size.height());
+ }
+
+ // Create blank pages.
+ for (int i = 1; i < num_pages; ++i) {
+ pp::Rect page_rect(page_rects[i]);
+ page_rect.Inset(kPageShadowLeft, kPageShadowTop,
+ kPageShadowRight, kPageShadowBottom);
+ double width_in_points =
+ page_rect.width() * kPointsPerInch / kPixelsPerInch;
+ double height_in_points =
+ page_rect.height() * kPointsPerInch / kPixelsPerInch;
+ FPDFPage_New(doc_, i, width_in_points, height_in_points);
+ pages_.push_back(new PDFiumPage(this, i, page_rect, true));
+ }
+
+ CalculateVisiblePages();
+ if (document_size_ != old_document_size)
+ client_->DocumentSizeUpdated(document_size_);
+}
+
+void PDFiumEngine::LoadDocument() {
+ // Check if the document is ready for loading. If it isn't just bail for now,
+ // we will call LoadDocument() again later.
+ if (!doc_ && !doc_loader_.IsDocumentComplete() &&
+ !FPDFAvail_IsDocAvail(fpdf_availability_, &download_hints_)) {
+ return;
+ }
+
+ // If we're in the middle of getting a password, just return. We will retry
+ // loading the document after we get the password anyway.
+ if (getting_password_)
+ return;
+
+ ScopedUnsupportedFeature scoped_unsupported_feature(this);
+ bool needs_password = false;
+ if (TryLoadingDoc(false, std::string(), &needs_password)) {
+ ContinueLoadingDocument(false, std::string());
+ return;
+ }
+ if (needs_password)
+ GetPasswordAndLoad();
+ else
+ client_->DocumentLoadFailed();
+}
+
+bool PDFiumEngine::TryLoadingDoc(bool with_password,
+ const std::string& password,
+ bool* needs_password) {
+ *needs_password = false;
+ if (doc_)
+ return true;
+
+ const char* password_cstr = NULL;
+ if (with_password) {
+ password_cstr = password.c_str();
+ password_tries_remaining_--;
+ }
+ if (doc_loader_.IsDocumentComplete())
+ doc_ = FPDF_LoadCustomDocument(&file_access_, password_cstr);
+ else
+ doc_ = FPDFAvail_GetDocument(fpdf_availability_, password_cstr);
+
+ if (!doc_ && FPDF_GetLastError() == FPDF_ERR_PASSWORD)
+ *needs_password = true;
+
+ return doc_ != NULL;
+}
+
+void PDFiumEngine::GetPasswordAndLoad() {
+ getting_password_ = true;
+ DCHECK(!doc_ && FPDF_GetLastError() == FPDF_ERR_PASSWORD);
+ client_->GetDocumentPassword(password_factory_.NewCallbackWithOutput(
+ &PDFiumEngine::OnGetPasswordComplete));
+}
+
+void PDFiumEngine::OnGetPasswordComplete(int32_t result,
+ const pp::Var& password) {
+ getting_password_ = false;
+
+ bool password_given = false;
+ std::string password_text;
+ if (result == PP_OK && password.is_string()) {
+ password_text = password.AsString();
+ if (!password_text.empty())
+ password_given = true;
+ }
+ ContinueLoadingDocument(password_given, password_text);
+}
+
+void PDFiumEngine::ContinueLoadingDocument(
+ bool has_password,
+ const std::string& password) {
+ ScopedUnsupportedFeature scoped_unsupported_feature(this);
+
+ bool needs_password = false;
+ bool loaded = TryLoadingDoc(has_password, password, &needs_password);
+ bool password_incorrect = !loaded && has_password && needs_password;
+ if (password_incorrect && password_tries_remaining_ > 0) {
+ GetPasswordAndLoad();
+ return;
+ }
+
+ if (!doc_) {
+ client_->DocumentLoadFailed();
+ return;
+ }
+
+ if (FPDFDoc_GetPageMode(doc_) == PAGEMODE_USEOUTLINES)
+ client_->DocumentHasUnsupportedFeature("Bookmarks");
+
+ permissions_ = FPDF_GetDocPermissions(doc_);
+
+ if (!form_) {
+ // Only returns 0 when data isn't available. If form data is downloaded, or
+ // if this isn't a form, returns positive values.
+ if (!doc_loader_.IsDocumentComplete() &&
+ !FPDFAvail_IsFormAvail(fpdf_availability_, &download_hints_)) {
+ return;
+ }
+
+ form_ = FPDFDOC_InitFormFillEnviroument(
+ doc_, static_cast<FPDF_FORMFILLINFO*>(this));
+#ifdef _TEST_XFA
+ FPDF_LoadXFA(doc_);
+#endif
+
+ FPDF_SetFormFieldHighlightColor(form_, 0, kFormHighlightColor);
+ FPDF_SetFormFieldHighlightAlpha(form_, kFormHighlightAlpha);
+ }
+
+ if (!doc_loader_.IsDocumentComplete()) {
+ // Check if the first page is available. In a linearized PDF, that is not
+ // always page 0. Doing this gives us the default page size, since when the
+ // document is available, the first page is available as well.
+ CheckPageAvailable(FPDFAvail_GetFirstPageNum(doc_), &pending_pages_);
+ }
+
+ LoadPageInfo(false);
+
+ if (doc_loader_.IsDocumentComplete())
+ FinishLoadingDocument();
+}
+
+void PDFiumEngine::LoadPageInfo(bool reload) {
+ pending_pages_.clear();
+ pp::Size old_document_size = document_size_;
+ document_size_ = pp::Size();
+ std::vector<pp::Rect> page_rects;
+ int page_count = FPDF_GetPageCount(doc_);
+ bool doc_complete = doc_loader_.IsDocumentComplete();
+ for (int i = 0; i < page_count; ++i) {
+ if (i != 0) {
+ // Add space for horizontal separator.
+ document_size_.Enlarge(0, kPageSeparatorThickness);
+ }
+
+ // Get page availability. If reload==false, and document is not loaded yet
+ // (we are using async loading) - mark all pages as unavailable.
+ // If reload==true (we have document constructed already), get page
+ // availability flag from already existing PDFiumPage class.
+ bool page_available = reload ? pages_[i]->available() : doc_complete;
+
+ pp::Size size = page_available ? GetPageSize(i) : default_page_size_;
+ size.Enlarge(kPageShadowLeft + kPageShadowRight,
+ kPageShadowTop + kPageShadowBottom);
+ pp::Rect rect(pp::Point(0, document_size_.height()), size);
+ page_rects.push_back(rect);
+
+ if (size.width() > document_size_.width())
+ document_size_.set_width(size.width());
+
+ document_size_.Enlarge(0, size.height());
+ }
+
+ for (int i = 0; i < page_count; ++i) {
+ // Center pages relative to the entire document.
+ page_rects[i].set_x((document_size_.width() - page_rects[i].width()) / 2);
+ pp::Rect page_rect(page_rects[i]);
+ page_rect.Inset(kPageShadowLeft, kPageShadowTop,
+ kPageShadowRight, kPageShadowBottom);
+ if (reload) {
+ pages_[i]->set_rect(page_rect);
+ } else {
+ pages_.push_back(new PDFiumPage(this, i, page_rect, doc_complete));
+ }
+ }
+
+ CalculateVisiblePages();
+ if (document_size_ != old_document_size)
+ client_->DocumentSizeUpdated(document_size_);
+}
+
+void PDFiumEngine::CalculateVisiblePages() {
+ // Clear pending requests queue, since it may contain requests to the pages
+ // that are already invisible (after scrolling for example).
+ pending_pages_.clear();
+ doc_loader_.ClearPendingRequests();
+
+ visible_pages_.clear();
+ pp::Rect visible_rect(plugin_size_);
+ for (size_t i = 0; i < pages_.size(); ++i) {
+ // Check an entire PageScreenRect, since we might need to repaint side
+ // borders and shadows even if the page itself is not visible.
+ // For example, when user use pdf with different page sizes and zoomed in
+ // outside page area.
+ if (visible_rect.Intersects(GetPageScreenRect(i))) {
+ visible_pages_.push_back(i);
+ CheckPageAvailable(i, &pending_pages_);
+ } else {
+ // Need to unload pages when we're not using them, since some PDFs use a
+ // lot of memory. See http://crbug.com/48791
+ if (defer_page_unload_) {
+ deferred_page_unloads_.push_back(i);
+ } else {
+ pages_[i]->Unload();
+ }
+
+ // If the last mouse down was on a page that's no longer visible, reset
+ // that variable so that we don't send keyboard events to it (the focus
+ // will be lost when the page is first closed anyways).
+ if (static_cast<int>(i) == last_page_mouse_down_)
+ last_page_mouse_down_ = -1;
+ }
+ }
+
+ // Any pending highlighting of form fields will be invalid since these are in
+ // screen coordinates.
+ form_highlights_.clear();
+
+ if (visible_pages_.size() == 0)
+ first_visible_page_ = -1;
+ else
+ first_visible_page_ = visible_pages_.front();
+
+ int most_visible_page = first_visible_page_;
+ // Check if the next page is more visible than the first one.
+ if (most_visible_page != -1 &&
+ pages_.size() > 0 &&
+ most_visible_page < static_cast<int>(pages_.size()) - 1) {
+ pp::Rect rc_first =
+ visible_rect.Intersect(GetPageScreenRect(most_visible_page));
+ pp::Rect rc_next =
+ visible_rect.Intersect(GetPageScreenRect(most_visible_page + 1));
+ if (rc_next.height() > rc_first.height())
+ most_visible_page++;
+ }
+
+ SetCurrentPage(most_visible_page);
+}
+
+bool PDFiumEngine::IsPageVisible(int index) const {
+ for (size_t i = 0; i < visible_pages_.size(); ++i) {
+ if (visible_pages_[i] == index)
+ return true;
+ }
+
+ return false;
+}
+
+bool PDFiumEngine::CheckPageAvailable(int index, std::vector<int>* pending) {
+ if (!doc_ || !form_)
+ return false;
+
+ if (static_cast<int>(pages_.size()) > index && pages_[index]->available())
+ return true;
+
+ if (!FPDFAvail_IsPageAvail(fpdf_availability_, index, &download_hints_)) {
+ size_t j;
+ for (j = 0; j < pending->size(); ++j) {
+ if ((*pending)[j] == index)
+ break;
+ }
+
+ if (j == pending->size())
+ pending->push_back(index);
+ return false;
+ }
+
+ if (static_cast<int>(pages_.size()) > index)
+ pages_[index]->set_available(true);
+ if (!default_page_size_.GetArea())
+ default_page_size_ = GetPageSize(index);
+ return true;
+}
+
+pp::Size PDFiumEngine::GetPageSize(int index) {
+ pp::Size size;
+ double width_in_points = 0;
+ double height_in_points = 0;
+ int rv = FPDF_GetPageSizeByIndex(
+ doc_, index, &width_in_points, &height_in_points);
+
+ if (rv) {
+ int width_in_pixels = static_cast<int>(
+ width_in_points * kPixelsPerInch / kPointsPerInch);
+ int height_in_pixels = static_cast<int>(
+ height_in_points * kPixelsPerInch / kPointsPerInch);
+ if (current_rotation_ % 2 == 1)
+ std::swap(width_in_pixels, height_in_pixels);
+ size = pp::Size(width_in_pixels, height_in_pixels);
+ }
+ return size;
+}
+
+int PDFiumEngine::StartPaint(int page_index, const pp::Rect& dirty) {
+ // For the first time we hit paint, do nothing and just record the paint for
+ // the next callback. This keeps the UI responsive in case the user is doing
+ // a lot of scrolling.
+ ProgressivePaint progressive;
+ progressive.rect = dirty;
+ progressive.page_index = page_index;
+ progressive.bitmap = NULL;
+ progressive.painted_ = false;
+ progressive_paints_.push_back(progressive);
+ return progressive_paints_.size() - 1;
+}
+
+bool PDFiumEngine::ContinuePaint(int progressive_index,
+ pp::ImageData* image_data) {
+#if defined(OS_LINUX)
+ g_last_instance_id = client_->GetPluginInstance()->pp_instance();
+#endif
+
+ int rv;
+ int page_index = progressive_paints_[progressive_index].page_index;
+ last_progressive_start_time_ = base::Time::Now();
+ if (progressive_paints_[progressive_index].bitmap) {
+ rv = FPDF_RenderPage_Continue(
+ pages_[page_index]->GetPage(), static_cast<IFSDK_PAUSE*>(this));
+ } else {
+ pp::Rect dirty = progressive_paints_[progressive_index].rect;
+ progressive_paints_[progressive_index].bitmap = CreateBitmap(dirty,
+ image_data);
+ int start_x, start_y, size_x, size_y;
+ GetPDFiumRect(
+ page_index, dirty, &start_x, &start_y, &size_x, &size_y);
+ FPDFBitmap_FillRect(progressive_paints_[progressive_index].bitmap, start_x,
+ start_y, size_x, size_y, 0xFFFFFFFF);
+ rv = FPDF_RenderPageBitmap_Start(
+ progressive_paints_[progressive_index].bitmap,
+ pages_[page_index]->GetPage(), start_x, start_y, size_x, size_y,
+ current_rotation_,
+ GetRenderingFlags(), static_cast<IFSDK_PAUSE*>(this));
+ }
+ return rv != FPDF_RENDER_TOBECOUNTINUED;
+}
+
+void PDFiumEngine::FinishPaint(int progressive_index,
+ pp::ImageData* image_data) {
+ int page_index = progressive_paints_[progressive_index].page_index;
+ pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
+ FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
+ int start_x, start_y, size_x, size_y;
+ GetPDFiumRect(
+ page_index, dirty_in_screen, &start_x, &start_y, &size_x, &size_y);
+
+ // Draw the forms.
+ FPDF_FFLDraw(
+ form_, bitmap, pages_[page_index]->GetPage(), start_x, start_y, size_x,
+ size_y, current_rotation_, GetRenderingFlags());
+
+ FillPageSides(progressive_index);
+
+ // Paint the page shadows.
+ PaintPageShadow(progressive_index, image_data);
+
+ DrawSelections(progressive_index, image_data);
+
+ FPDF_RenderPage_Close(pages_[page_index]->GetPage());
+ FPDFBitmap_Destroy(bitmap);
+ progressive_paints_.erase(progressive_paints_.begin() + progressive_index);
+
+ client_->DocumentPaintOccurred();
+}
+
+void PDFiumEngine::CancelPaints() {
+ for (size_t i = 0; i < progressive_paints_.size(); ++i) {
+ FPDF_RenderPage_Close(pages_[progressive_paints_[i].page_index]->GetPage());
+ FPDFBitmap_Destroy(progressive_paints_[i].bitmap);
+ }
+ progressive_paints_.clear();
+}
+
+void PDFiumEngine::FillPageSides(int progressive_index) {
+ int page_index = progressive_paints_[progressive_index].page_index;
+ pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
+ FPDF_BITMAP bitmap = progressive_paints_[progressive_index].bitmap;
+
+ pp::Rect page_rect = pages_[page_index]->rect();
+ if (page_rect.x() > 0) {
+ pp::Rect left(0,
+ page_rect.y() - kPageShadowTop,
+ page_rect.x() - kPageShadowLeft,
+ page_rect.height() + kPageShadowTop +
+ kPageShadowBottom + kPageSeparatorThickness);
+ left = GetScreenRect(left).Intersect(dirty_in_screen);
+
+ FPDFBitmap_FillRect(bitmap, left.x() - dirty_in_screen.x(),
+ left.y() - dirty_in_screen.y(), left.width(),
+ left.height(), kBackgroundColor);
+ }
+
+ if (page_rect.right() < document_size_.width()) {
+ pp::Rect right(page_rect.right() + kPageShadowRight,
+ page_rect.y() - kPageShadowTop,
+ document_size_.width() - page_rect.right() -
+ kPageShadowRight,
+ page_rect.height() + kPageShadowTop +
+ kPageShadowBottom + kPageSeparatorThickness);
+ right = GetScreenRect(right).Intersect(dirty_in_screen);
+
+ FPDFBitmap_FillRect(bitmap, right.x() - dirty_in_screen.x(),
+ right.y() - dirty_in_screen.y(), right.width(),
+ right.height(), kBackgroundColor);
+ }
+
+ // Paint separator.
+ pp::Rect bottom(page_rect.x() - kPageShadowLeft,
+ page_rect.bottom() + kPageShadowBottom,
+ page_rect.width() + kPageShadowLeft + kPageShadowRight,
+ kPageSeparatorThickness);
+ bottom = GetScreenRect(bottom).Intersect(dirty_in_screen);
+
+ FPDFBitmap_FillRect(bitmap, bottom.x() - dirty_in_screen.x(),
+ bottom.y() - dirty_in_screen.y(), bottom.width(),
+ bottom.height(), kBackgroundColor);
+}
+
+void PDFiumEngine::PaintPageShadow(int progressive_index,
+ pp::ImageData* image_data) {
+ int page_index = progressive_paints_[progressive_index].page_index;
+ pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
+ pp::Rect page_rect = pages_[page_index]->rect();
+ pp::Rect shadow_rect(page_rect);
+ shadow_rect.Inset(-kPageShadowLeft, -kPageShadowTop,
+ -kPageShadowRight, -kPageShadowBottom);
+
+ // Due to the rounding errors of the GetScreenRect it is possible to get
+ // different size shadows on the left and right sides even they are defined
+ // the same. To fix this issue let's calculate shadow rect and then shrink
+ // it by the size of the shadows.
+ shadow_rect = GetScreenRect(shadow_rect);
+ page_rect = shadow_rect;
+
+ page_rect.Inset(static_cast<int>(ceil(kPageShadowLeft * current_zoom_)),
+ static_cast<int>(ceil(kPageShadowTop * current_zoom_)),
+ static_cast<int>(ceil(kPageShadowRight * current_zoom_)),
+ static_cast<int>(ceil(kPageShadowBottom * current_zoom_)));
+
+ DrawPageShadow(page_rect, shadow_rect, dirty_in_screen, image_data);
+}
+
+void PDFiumEngine::DrawSelections(int progressive_index,
+ pp::ImageData* image_data) {
+ int page_index = progressive_paints_[progressive_index].page_index;
+ pp::Rect dirty_in_screen = progressive_paints_[progressive_index].rect;
+
+ void* region = NULL;
+ int stride;
+ GetRegion(dirty_in_screen.point(), image_data, &region, &stride);
+
+ std::vector<pp::Rect> highlighted_rects;
+ pp::Rect visible_rect = GetVisibleRect();
+ for (size_t k = 0; k < selection_.size(); ++k) {
+ if (selection_[k].page_index() != page_index)
+ continue;
+ std::vector<pp::Rect> rects = selection_[k].GetScreenRects(
+ visible_rect.point(), current_zoom_, current_rotation_);
+ for (size_t j = 0; j < rects.size(); ++j) {
+ pp::Rect visible_selection = rects[j].Intersect(dirty_in_screen);
+ if (visible_selection.IsEmpty())
+ continue;
+
+ visible_selection.Offset(
+ -dirty_in_screen.point().x(), -dirty_in_screen.point().y());
+ Highlight(region, stride, visible_selection, &highlighted_rects);
+ }
+ }
+
+ for (size_t k = 0; k < form_highlights_.size(); ++k) {
+ pp::Rect visible_selection = form_highlights_[k].Intersect(dirty_in_screen);
+ if (visible_selection.IsEmpty())
+ continue;
+
+ visible_selection.Offset(
+ -dirty_in_screen.point().x(), -dirty_in_screen.point().y());
+ Highlight(region, stride, visible_selection, &highlighted_rects);
+ }
+ form_highlights_.clear();
+}
+
+void PDFiumEngine::PaintUnavailablePage(int page_index,
+ const pp::Rect& dirty,
+ pp::ImageData* image_data) {
+ int start_x, start_y, size_x, size_y;
+ GetPDFiumRect(page_index, dirty, &start_x, &start_y, &size_x, &size_y);
+ FPDF_BITMAP bitmap = CreateBitmap(dirty, image_data);
+ FPDFBitmap_FillRect(bitmap, start_x, start_y, size_x, size_y,
+ kPendingPageColor);
+
+ pp::Rect loading_text_in_screen(
+ pages_[page_index]->rect().width() / 2,
+ pages_[page_index]->rect().y() + kLoadingTextVerticalOffset, 0, 0);
+ loading_text_in_screen = GetScreenRect(loading_text_in_screen);
+ FPDFBitmap_Destroy(bitmap);
+}
+
+int PDFiumEngine::GetProgressiveIndex(int page_index) const {
+ for (size_t i = 0; i < progressive_paints_.size(); ++i) {
+ if (progressive_paints_[i].page_index == page_index)
+ return i;
+ }
+ return -1;
+}
+
+FPDF_BITMAP PDFiumEngine::CreateBitmap(const pp::Rect& rect,
+ pp::ImageData* image_data) const {
+ void* region;
+ int stride;
+ GetRegion(rect.point(), image_data, &region, &stride);
+ if (!region)
+ return NULL;
+ return FPDFBitmap_CreateEx(
+ rect.width(), rect.height(), FPDFBitmap_BGRx, region, stride);
+}
+
+void PDFiumEngine::GetPDFiumRect(
+ int page_index, const pp::Rect& rect, int* start_x, int* start_y,
+ int* size_x, int* size_y) const {
+ pp::Rect page_rect = GetScreenRect(pages_[page_index]->rect());
+ page_rect.Offset(-rect.x(), -rect.y());
+
+ *start_x = page_rect.x();
+ *start_y = page_rect.y();
+ *size_x = page_rect.width();
+ *size_y = page_rect.height();
+}
+
+int PDFiumEngine::GetRenderingFlags() const {
+ int flags = FPDF_LCD_TEXT | FPDF_NO_CATCH;
+ if (render_grayscale_)
+ flags |= FPDF_GRAYSCALE;
+ if (client_->IsPrintPreview())
+ flags |= FPDF_PRINTING;
+ return flags;
+}
+
+pp::Rect PDFiumEngine::GetVisibleRect() const {
+ pp::Rect rv;
+ rv.set_x(static_cast<int>(position_.x() / current_zoom_));
+ rv.set_y(static_cast<int>(position_.y() / current_zoom_));
+ rv.set_width(static_cast<int>(ceil(plugin_size_.width() / current_zoom_)));
+ rv.set_height(static_cast<int>(ceil(plugin_size_.height() / current_zoom_)));
+ return rv;
+}
+
+pp::Rect PDFiumEngine::GetPageScreenRect(int page_index) const {
+ // Since we use this rect for creating the PDFium bitmap, also include other
+ // areas around the page that we might need to update such as the page
+ // separator and the sides if the page is narrower than the document.
+ return GetScreenRect(pp::Rect(
+ 0,
+ pages_[page_index]->rect().y() - kPageShadowTop,
+ document_size_.width(),
+ pages_[page_index]->rect().height() + kPageShadowTop +
+ kPageShadowBottom + kPageSeparatorThickness));
+}
+
+pp::Rect PDFiumEngine::GetScreenRect(const pp::Rect& rect) const {
+ pp::Rect rv;
+ int right =
+ static_cast<int>(ceil(rect.right() * current_zoom_ - position_.x()));
+ int bottom =
+ static_cast<int>(ceil(rect.bottom() * current_zoom_ - position_.y()));
+
+ rv.set_x(static_cast<int>(rect.x() * current_zoom_ - position_.x()));
+ rv.set_y(static_cast<int>(rect.y() * current_zoom_ - position_.y()));
+ rv.set_width(right - rv.x());
+ rv.set_height(bottom - rv.y());
+ return rv;
+}
+
+void PDFiumEngine::Highlight(void* buffer,
+ int stride,
+ const pp::Rect& rect,
+ std::vector<pp::Rect>* highlighted_rects) {
+ if (!buffer)
+ return;
+
+ pp::Rect new_rect = rect;
+ for (size_t i = 0; i < highlighted_rects->size(); ++i)
+ new_rect = new_rect.Subtract((*highlighted_rects)[i]);
+
+ highlighted_rects->push_back(new_rect);
+ int l = new_rect.x();
+ int t = new_rect.y();
+ int w = new_rect.width();
+ int h = new_rect.height();
+
+ for (int y = t; y < t + h; ++y) {
+ for (int x = l; x < l + w; ++x) {
+ uint8* pixel = static_cast<uint8*>(buffer) + y * stride + x * 4;
+ // This is our highlight color.
+ pixel[0] = static_cast<uint8>(
+ pixel[0] * (kHighlightColorB / 255.0));
+ pixel[1] = static_cast<uint8>(
+ pixel[1] * (kHighlightColorG / 255.0));
+ pixel[2] = static_cast<uint8>(
+ pixel[2] * (kHighlightColorR / 255.0));
+ }
+ }
+}
+
+PDFiumEngine::SelectionChangeInvalidator::SelectionChangeInvalidator(
+ PDFiumEngine* engine) : engine_(engine) {
+ previous_origin_ = engine_->GetVisibleRect().point();
+ GetVisibleSelectionsScreenRects(&old_selections_);
+}
+
+PDFiumEngine::SelectionChangeInvalidator::~SelectionChangeInvalidator() {
+ // Offset the old selections if the document scrolled since we recorded them.
+ pp::Point offset = previous_origin_ - engine_->GetVisibleRect().point();
+ for (size_t i = 0; i < old_selections_.size(); ++i)
+ old_selections_[i].Offset(offset);
+
+ std::vector<pp::Rect> new_selections;
+ GetVisibleSelectionsScreenRects(&new_selections);
+ for (size_t i = 0; i < new_selections.size(); ++i) {
+ for (size_t j = 0; j < old_selections_.size(); ++j) {
+ if (!old_selections_[j].IsEmpty() &&
+ new_selections[i] == old_selections_[j]) {
+ // Rectangle was selected before and after, so no need to invalidate it.
+ // Mark the rectangles by setting them to empty.
+ new_selections[i] = old_selections_[j] = pp::Rect();
+ break;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < old_selections_.size(); ++i) {
+ if (!old_selections_[i].IsEmpty())
+ engine_->client_->Invalidate(old_selections_[i]);
+ }
+ for (size_t i = 0; i < new_selections.size(); ++i) {
+ if (!new_selections[i].IsEmpty())
+ engine_->client_->Invalidate(new_selections[i]);
+ }
+ engine_->OnSelectionChanged();
+}
+
+void
+PDFiumEngine::SelectionChangeInvalidator::GetVisibleSelectionsScreenRects(
+ std::vector<pp::Rect>* rects) {
+ pp::Rect visible_rect = engine_->GetVisibleRect();
+ for (size_t i = 0; i < engine_->selection_.size(); ++i) {
+ int page_index = engine_->selection_[i].page_index();
+ if (!engine_->IsPageVisible(page_index))
+ continue; // This selection is on a page that's not currently visible.
+
+ std::vector<pp::Rect> selection_rects =
+ engine_->selection_[i].GetScreenRects(
+ visible_rect.point(),
+ engine_->current_zoom_,
+ engine_->current_rotation_);
+ rects->insert(rects->end(), selection_rects.begin(), selection_rects.end());
+ }
+}
+
+PDFiumEngine::MouseDownState::MouseDownState(
+ const PDFiumPage::Area& area,
+ const PDFiumPage::LinkTarget& target)
+ : area_(area), target_(target) {
+}
+
+PDFiumEngine::MouseDownState::~MouseDownState() {
+}
+
+void PDFiumEngine::MouseDownState::Set(const PDFiumPage::Area& area,
+ const PDFiumPage::LinkTarget& target) {
+ area_ = area;
+ target_ = target;
+}
+
+void PDFiumEngine::MouseDownState::Reset() {
+ area_ = PDFiumPage::NONSELECTABLE_AREA;
+ target_ = PDFiumPage::LinkTarget();
+}
+
+bool PDFiumEngine::MouseDownState::Matches(
+ const PDFiumPage::Area& area,
+ const PDFiumPage::LinkTarget& target) const {
+ if (area_ == area) {
+ if (area == PDFiumPage::WEBLINK_AREA)
+ return target_.url == target.url;
+ if (area == PDFiumPage::DOCLINK_AREA)
+ return target_.page == target.page;
+ return true;
+ }
+ return false;
+}
+
+void PDFiumEngine::DeviceToPage(int page_index,
+ float device_x,
+ float device_y,
+ double* page_x,
+ double* page_y) {
+ *page_x = *page_y = 0;
+ int temp_x = static_cast<int>((device_x + position_.x())/ current_zoom_ -
+ pages_[page_index]->rect().x());
+ int temp_y = static_cast<int>((device_y + position_.y())/ current_zoom_ -
+ pages_[page_index]->rect().y());
+ FPDF_DeviceToPage(
+ pages_[page_index]->GetPage(), 0, 0,
+ pages_[page_index]->rect().width(), pages_[page_index]->rect().height(),
+ current_rotation_, temp_x, temp_y, page_x, page_y);
+}
+
+int PDFiumEngine::GetVisiblePageIndex(FPDF_PAGE page) {
+ for (size_t i = 0; i < visible_pages_.size(); ++i) {
+ if (pages_[visible_pages_[i]]->GetPage() == page)
+ return visible_pages_[i];
+ }
+ return -1;
+}
+
+void PDFiumEngine::SetCurrentPage(int index) {
+ if (index == most_visible_page_ || !form_)
+ return;
+ if (most_visible_page_ != -1 && called_do_document_action_) {
+ FPDF_PAGE old_page = pages_[most_visible_page_]->GetPage();
+ FORM_DoPageAAction(old_page, form_, FPDFPAGE_AACTION_CLOSE);
+ }
+ most_visible_page_ = index;
+#if defined(OS_LINUX)
+ g_last_instance_id = client_->GetPluginInstance()->pp_instance();
+#endif
+ if (most_visible_page_ != -1 && called_do_document_action_) {
+ FPDF_PAGE new_page = pages_[most_visible_page_]->GetPage();
+ FORM_DoPageAAction(new_page, form_, FPDFPAGE_AACTION_OPEN);
+ }
+}
+
+void PDFiumEngine::TransformPDFPageForPrinting(
+ FPDF_PAGE page,
+ const PP_PrintSettings_Dev& print_settings) {
+ // Get the source page width and height in points.
+ const double src_page_width = FPDF_GetPageWidth(page);
+ const double src_page_height = FPDF_GetPageHeight(page);
+
+ const int src_page_rotation = FPDFPage_GetRotation(page);
+ const bool fit_to_page = print_settings.print_scaling_option ==
+ PP_PRINTSCALINGOPTION_FIT_TO_PRINTABLE_AREA;
+
+ pp::Size page_size(print_settings.paper_size);
+ pp::Rect content_rect(print_settings.printable_area);
+ const bool rotated = (src_page_rotation % 2 == 1);
+ SetPageSizeAndContentRect(rotated,
+ src_page_width > src_page_height,
+ &page_size,
+ &content_rect);
+
+ // Compute the screen page width and height in points.
+ const int actual_page_width =
+ rotated ? page_size.height() : page_size.width();
+ const int actual_page_height =
+ rotated ? page_size.width() : page_size.height();
+
+ const double scale_factor = CalculateScaleFactor(fit_to_page, content_rect,
+ src_page_width,
+ src_page_height, rotated);
+
+ // Calculate positions for the clip box.
+ ClipBox source_clip_box;
+ CalculateClipBoxBoundary(page, scale_factor, rotated, &source_clip_box);
+
+ // Calculate the translation offset values.
+ double offset_x = 0;
+ double offset_y = 0;
+ if (fit_to_page) {
+ CalculateScaledClipBoxOffset(content_rect, source_clip_box, &offset_x,
+ &offset_y);
+ } else {
+ CalculateNonScaledClipBoxOffset(content_rect, src_page_rotation,
+ actual_page_width, actual_page_height,
+ source_clip_box, &offset_x, &offset_y);
+ }
+
+ // Reset the media box and crop box. When the page has crop box and media box,
+ // the plugin will display the crop box contents and not the entire media box.
+ // If the pages have different crop box values, the plugin will display a
+ // document of multiple page sizes. To give better user experience, we
+ // decided to have same crop box and media box values. Hence, the user will
+ // see a list of uniform pages.
+ FPDFPage_SetMediaBox(page, 0, 0, page_size.width(), page_size.height());
+ FPDFPage_SetCropBox(page, 0, 0, page_size.width(), page_size.height());
+
+ // Transformation is not required, return. Do this check only after updating
+ // the media box and crop box. For more detailed information, please refer to
+ // the comment block right before FPDF_SetMediaBox and FPDF_GetMediaBox calls.
+ if (scale_factor == 1.0 && offset_x == 0 && offset_y == 0)
+ return;
+
+
+ // All the positions have been calculated, now manipulate the PDF.
+ FS_MATRIX matrix = {static_cast<float>(scale_factor),
+ 0,
+ 0,
+ static_cast<float>(scale_factor),
+ static_cast<float>(offset_x),
+ static_cast<float>(offset_y)};
+ FS_RECTF cliprect = {static_cast<float>(source_clip_box.left+offset_x),
+ static_cast<float>(source_clip_box.top+offset_y),
+ static_cast<float>(source_clip_box.right+offset_x),
+ static_cast<float>(source_clip_box.bottom+offset_y)};
+ FPDFPage_TransFormWithClip(page, &matrix, &cliprect);
+ FPDFPage_TransformAnnots(page, scale_factor, 0, 0, scale_factor,
+ offset_x, offset_y);
+}
+
+void PDFiumEngine::DrawPageShadow(const pp::Rect& page_rc,
+ const pp::Rect& shadow_rc,
+ const pp::Rect& clip_rc,
+ pp::ImageData* image_data) {
+ pp::Rect page_rect(page_rc);
+ page_rect.Offset(page_offset_);
+
+ pp::Rect shadow_rect(shadow_rc);
+ shadow_rect.Offset(page_offset_);
+
+ pp::Rect clip_rect(clip_rc);
+ clip_rect.Offset(page_offset_);
+
+ // Page drop shadow parameters.
+ const double factor = 0.5;
+ uint32 depth = std::max(
+ std::max(page_rect.x() - shadow_rect.x(),
+ page_rect.y() - shadow_rect.y()),
+ std::max(shadow_rect.right() - page_rect.right(),
+ shadow_rect.bottom() - page_rect.bottom()));
+ depth = static_cast<uint32>(depth * 1.5) + 1;
+
+ // We need to check depth only to verify our copy of shadow matrix is correct.
+ if (!page_shadow_.get() || page_shadow_->depth() != depth)
+ page_shadow_.reset(new ShadowMatrix(depth, factor, kBackgroundColor));
+
+ DCHECK(!image_data->is_null());
+ DrawShadow(image_data, shadow_rect, page_rect, clip_rect, *page_shadow_);
+}
+
+void PDFiumEngine::GetRegion(const pp::Point& location,
+ pp::ImageData* image_data,
+ void** region,
+ int* stride) const {
+ if (image_data->is_null()) {
+ DCHECK(plugin_size_.IsEmpty());
+ *stride = 0;
+ *region = NULL;
+ return;
+ }
+ char* buffer = static_cast<char*>(image_data->data());
+ *stride = image_data->stride();
+
+ pp::Point offset_location = location + page_offset_;
+ // TODO: update this when we support BIDI and scrollbars can be on the left.
+ if (!buffer ||
+ !pp::Rect(page_offset_, plugin_size_).Contains(offset_location)) {
+ *region = NULL;
+ return;
+ }
+
+ buffer += location.y() * (*stride);
+ buffer += (location.x() + page_offset_.x()) * 4;
+ *region = buffer;
+}
+
+void PDFiumEngine::OnSelectionChanged() {
+ if (HasPermission(PDFEngine::PERMISSION_COPY))
+ pp::PDF::SetSelectedText(GetPluginInstance(), GetSelectedText().c_str());
+}
+
+void PDFiumEngine::Form_Invalidate(FPDF_FORMFILLINFO* param,
+ FPDF_PAGE page,
+ double left,
+ double top,
+ double right,
+ double bottom) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ int page_index = engine->GetVisiblePageIndex(page);
+ if (page_index == -1) {
+ // This can sometime happen when the page is closed because it went off
+ // screen, and PDFium invalidates the control as it's being deleted.
+ return;
+ }
+
+ pp::Rect rect = engine->pages_[page_index]->PageToScreen(
+ engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
+ bottom, engine->current_rotation_);
+ engine->client_->Invalidate(rect);
+}
+
+void PDFiumEngine::Form_OutputSelectedRect(FPDF_FORMFILLINFO* param,
+ FPDF_PAGE page,
+ double left,
+ double top,
+ double right,
+ double bottom) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ int page_index = engine->GetVisiblePageIndex(page);
+ if (page_index == -1) {
+ NOTREACHED();
+ return;
+ }
+ pp::Rect rect = engine->pages_[page_index]->PageToScreen(
+ engine->GetVisibleRect().point(), engine->current_zoom_, left, top, right,
+ bottom, engine->current_rotation_);
+ engine->form_highlights_.push_back(rect);
+}
+
+void PDFiumEngine::Form_SetCursor(FPDF_FORMFILLINFO* param, int cursor_type) {
+ // We don't need this since it's not enough to change the cursor in all
+ // scenarios. Instead, we check which form field we're under in OnMouseMove.
+}
+
+int PDFiumEngine::Form_SetTimer(FPDF_FORMFILLINFO* param,
+ int elapse,
+ TimerCallback timer_func) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->timers_[++engine->next_timer_id_] =
+ std::pair<int, TimerCallback>(elapse, timer_func);
+ engine->client_->ScheduleCallback(engine->next_timer_id_, elapse);
+ return engine->next_timer_id_;
+}
+
+void PDFiumEngine::Form_KillTimer(FPDF_FORMFILLINFO* param, int timer_id) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->timers_.erase(timer_id);
+}
+
+FPDF_SYSTEMTIME PDFiumEngine::Form_GetLocalTime(FPDF_FORMFILLINFO* param) {
+ base::Time time = base::Time::Now();
+ base::Time::Exploded exploded;
+ time.LocalExplode(&exploded);
+
+ FPDF_SYSTEMTIME rv;
+ rv.wYear = exploded.year;
+ rv.wMonth = exploded.month;
+ rv.wDayOfWeek = exploded.day_of_week;
+ rv.wDay = exploded.day_of_month;
+ rv.wHour = exploded.hour;
+ rv.wMinute = exploded.minute;
+ rv.wSecond = exploded.second;
+ rv.wMilliseconds = exploded.millisecond;
+ return rv;
+}
+
+void PDFiumEngine::Form_OnChange(FPDF_FORMFILLINFO* param) {
+ // Don't care about.
+}
+
+FPDF_PAGE PDFiumEngine::Form_GetPage(FPDF_FORMFILLINFO* param,
+ FPDF_DOCUMENT document,
+ int page_index) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ if (page_index < 0 || page_index >= static_cast<int>(engine->pages_.size()))
+ return NULL;
+ return engine->pages_[page_index]->GetPage();
+}
+
+FPDF_PAGE PDFiumEngine::Form_GetCurrentPage(FPDF_FORMFILLINFO* param,
+ FPDF_DOCUMENT document) {
+ // TODO(jam): find out what this is used for.
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ int index = engine->last_page_mouse_down_;
+ if (index == -1) {
+ index = engine->GetMostVisiblePage();
+ if (index == -1) {
+ NOTREACHED();
+ return NULL;
+ }
+ }
+
+ return engine->pages_[index]->GetPage();
+}
+
+int PDFiumEngine::Form_GetRotation(FPDF_FORMFILLINFO* param, FPDF_PAGE page) {
+ return 0;
+}
+
+void PDFiumEngine::Form_ExecuteNamedAction(FPDF_FORMFILLINFO* param,
+ FPDF_BYTESTRING named_action) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ std::string action(named_action);
+ if (action == "Print") {
+ engine->client_->Print();
+ return;
+ }
+
+ int index = engine->last_page_mouse_down_;
+ /* Don't try to calculate the most visible page if we don't have a left click
+ before this event (this code originally copied Form_GetCurrentPage which of
+ course needs to do that and which doesn't have recursion). This can end up
+ causing infinite recursion. See http://crbug.com/240413 for more
+ information. Either way, it's not necessary for the spec'd list of named
+ actions.
+ if (index == -1)
+ index = engine->GetMostVisiblePage();
+ */
+ if (index == -1)
+ return;
+
+ // This is the only list of named actions per the spec (see 12.6.4.11). Adobe
+ // Reader supports more, like FitWidth, but since they're not part of the spec
+ // and we haven't got bugs about them, no need to now.
+ if (action == "NextPage") {
+ engine->client_->ScrollToPage(index + 1);
+ } else if (action == "PrevPage") {
+ engine->client_->ScrollToPage(index - 1);
+ } else if (action == "FirstPage") {
+ engine->client_->ScrollToPage(0);
+ } else if (action == "LastPage") {
+ engine->client_->ScrollToPage(engine->pages_.size() - 1);
+ }
+}
+
+void PDFiumEngine::Form_SetTextFieldFocus(FPDF_FORMFILLINFO* param,
+ FPDF_WIDESTRING value,
+ FPDF_DWORD valueLen,
+ FPDF_BOOL is_focus) {
+ // Do nothing for now.
+ // TODO(gene): use this signal to trigger OSK.
+}
+
+void PDFiumEngine::Form_DoURIAction(FPDF_FORMFILLINFO* param,
+ FPDF_BYTESTRING uri) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->client_->NavigateTo(std::string(uri), false);
+}
+
+void PDFiumEngine::Form_DoGoToAction(FPDF_FORMFILLINFO* param,
+ int page_index,
+ int zoom_mode,
+ float* position_array,
+ int size_of_array) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->client_->ScrollToPage(page_index);
+}
+
+int PDFiumEngine::Form_Alert(IPDF_JSPLATFORM* param,
+ FPDF_WIDESTRING message,
+ FPDF_WIDESTRING title,
+ int type,
+ int icon) {
+ // See fpdfformfill.h for these values.
+ enum AlertType {
+ ALERT_TYPE_OK = 0,
+ ALERT_TYPE_OK_CANCEL,
+ ALERT_TYPE_YES_ON,
+ ALERT_TYPE_YES_NO_CANCEL
+ };
+
+ enum AlertResult {
+ ALERT_RESULT_OK = 1,
+ ALERT_RESULT_CANCEL,
+ ALERT_RESULT_NO,
+ ALERT_RESULT_YES
+ };
+
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ std::string message_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(message));
+ if (type == ALERT_TYPE_OK) {
+ engine->client_->Alert(message_str);
+ return ALERT_RESULT_OK;
+ }
+
+ bool rv = engine->client_->Confirm(message_str);
+ if (type == ALERT_TYPE_OK_CANCEL)
+ return rv ? ALERT_RESULT_OK : ALERT_RESULT_CANCEL;
+ return rv ? ALERT_RESULT_YES : ALERT_RESULT_NO;
+}
+
+void PDFiumEngine::Form_Beep(IPDF_JSPLATFORM* param, int type) {
+ // Beeps are annoying, and not possible using javascript, so ignore for now.
+}
+
+int PDFiumEngine::Form_Response(IPDF_JSPLATFORM* param,
+ FPDF_WIDESTRING question,
+ FPDF_WIDESTRING title,
+ FPDF_WIDESTRING default_response,
+ FPDF_WIDESTRING label,
+ FPDF_BOOL password,
+ void* response,
+ int length) {
+ std::string question_str = base::UTF16ToUTF8(
+ reinterpret_cast<const base::char16*>(question));
+ std::string default_str = base::UTF16ToUTF8(
+ reinterpret_cast<const base::char16*>(default_response));
+
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ std::string rv = engine->client_->Prompt(question_str, default_str);
+ base::string16 rv_16 = base::UTF8ToUTF16(rv);
+ int rv_bytes = rv_16.size() * sizeof(base::char16);
+ if (response) {
+ int bytes_to_copy = rv_bytes < length ? rv_bytes : length;
+ memcpy(response, rv_16.c_str(), bytes_to_copy);
+ }
+ return rv_bytes;
+}
+
+int PDFiumEngine::Form_GetFilePath(IPDF_JSPLATFORM* param,
+ void* file_path,
+ int length) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ std::string rv = engine->client_->GetURL();
+ if (file_path && rv.size() <= static_cast<size_t>(length))
+ memcpy(file_path, rv.c_str(), rv.size());
+ return rv.size();
+}
+
+void PDFiumEngine::Form_Mail(IPDF_JSPLATFORM* param,
+ void* mail_data,
+ int length,
+ FPDF_BOOL ui,
+ FPDF_WIDESTRING to,
+ FPDF_WIDESTRING subject,
+ FPDF_WIDESTRING cc,
+ FPDF_WIDESTRING bcc,
+ FPDF_WIDESTRING message) {
+ DCHECK(length == 0); // Don't handle attachments; no way with mailto.
+ std::string to_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(to));
+ std::string cc_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(cc));
+ std::string bcc_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(bcc));
+ std::string subject_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(subject));
+ std::string message_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(message));
+
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->client_->Email(to_str, cc_str, bcc_str, subject_str, message_str);
+}
+
+void PDFiumEngine::Form_Print(IPDF_JSPLATFORM* param,
+ FPDF_BOOL ui,
+ int start,
+ int end,
+ FPDF_BOOL silent,
+ FPDF_BOOL shrink_to_fit,
+ FPDF_BOOL print_as_image,
+ FPDF_BOOL reverse,
+ FPDF_BOOL annotations) {
+ // No way to pass the extra information to the print dialog using JavaScript.
+ // Just opening it is fine for now.
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->client_->Print();
+}
+
+void PDFiumEngine::Form_SubmitForm(IPDF_JSPLATFORM* param,
+ void* form_data,
+ int length,
+ FPDF_WIDESTRING url) {
+ std::string url_str =
+ base::UTF16ToUTF8(reinterpret_cast<const base::char16*>(url));
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->client_->SubmitForm(url_str, form_data, length);
+}
+
+void PDFiumEngine::Form_GotoPage(IPDF_JSPLATFORM* param,
+ int page_number) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ engine->client_->ScrollToPage(page_number);
+}
+
+int PDFiumEngine::Form_Browse(IPDF_JSPLATFORM* param,
+ void* file_path,
+ int length) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ std::string path = engine->client_->ShowFileSelectionDialog();
+ if (path.size() + 1 <= static_cast<size_t>(length))
+ memcpy(file_path, &path[0], path.size() + 1);
+ return path.size() + 1;
+}
+
+FPDF_BOOL PDFiumEngine::Pause_NeedToPauseNow(IFSDK_PAUSE* param) {
+ PDFiumEngine* engine = static_cast<PDFiumEngine*>(param);
+ return (base::Time::Now() - engine->last_progressive_start_time_).
+ InMilliseconds() > engine->progressive_paint_timeout_;
+}
+
+ScopedUnsupportedFeature::ScopedUnsupportedFeature(PDFiumEngine* engine)
+ : engine_(engine), old_engine_(g_engine_for_unsupported) {
+ g_engine_for_unsupported = engine_;
+}
+
+ScopedUnsupportedFeature::~ScopedUnsupportedFeature() {
+ g_engine_for_unsupported = old_engine_;
+}
+
+PDFEngineExports* PDFEngineExports::Create() {
+ return new PDFiumEngineExports;
+}
+
+namespace {
+
+int CalculatePosition(FPDF_PAGE page,
+ const PDFiumEngineExports::RenderingSettings& settings,
+ pp::Rect* dest) {
+ int page_width = static_cast<int>(
+ FPDF_GetPageWidth(page) * settings.dpi_x / kPointsPerInch);
+ int page_height = static_cast<int>(
+ FPDF_GetPageHeight(page) * settings.dpi_y / kPointsPerInch);
+
+ // Start by assuming that we will draw exactly to the bounds rect
+ // specified.
+ *dest = settings.bounds;
+
+ int rotate = 0; // normal orientation.
+
+ // Auto-rotate landscape pages to print correctly.
+ if (settings.autorotate &&
+ (dest->width() > dest->height()) != (page_width > page_height)) {
+ rotate = 3; // 90 degrees counter-clockwise.
+ std::swap(page_width, page_height);
+ }
+
+ // See if we need to scale the output
+ bool scale_to_bounds = false;
+ if (settings.fit_to_bounds &&
+ ((page_width > dest->width()) || (page_height > dest->height()))) {
+ scale_to_bounds = true;
+ } else if (settings.stretch_to_bounds &&
+ ((page_width < dest->width()) || (page_height < dest->height()))) {
+ scale_to_bounds = true;
+ }
+
+ if (scale_to_bounds) {
+ // If we need to maintain aspect ratio, calculate the actual width and
+ // height.
+ if (settings.keep_aspect_ratio) {
+ double scale_factor_x = page_width;
+ scale_factor_x /= dest->width();
+ double scale_factor_y = page_height;
+ scale_factor_y /= dest->height();
+ if (scale_factor_x > scale_factor_y) {
+ dest->set_height(page_height / scale_factor_x);
+ } else {
+ dest->set_width(page_width / scale_factor_y);
+ }
+ }
+ } else {
+ // We are not scaling to bounds. Draw in the actual page size. If the
+ // actual page size is larger than the bounds, the output will be
+ // clipped.
+ dest->set_width(page_width);
+ dest->set_height(page_height);
+ }
+
+ if (settings.center_in_bounds) {
+ pp::Point offset((settings.bounds.width() - dest->width()) / 2,
+ (settings.bounds.height() - dest->height()) / 2);
+ dest->Offset(offset);
+ }
+ return rotate;
+}
+
+} // namespace
+
+#if defined(OS_WIN)
+bool PDFiumEngineExports::RenderPDFPageToDC(const void* pdf_buffer,
+ int buffer_size,
+ int page_number,
+ const RenderingSettings& settings,
+ HDC dc) {
+ FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, buffer_size, NULL);
+ if (!doc)
+ return false;
+ FPDF_PAGE page = FPDF_LoadPage(doc, page_number);
+ if (!page) {
+ FPDF_CloseDocument(doc);
+ return false;
+ }
+ RenderingSettings new_settings = settings;
+ // calculate the page size
+ if (new_settings.dpi_x == -1)
+ new_settings.dpi_x = GetDeviceCaps(dc, LOGPIXELSX);
+ if (new_settings.dpi_y == -1)
+ new_settings.dpi_y = GetDeviceCaps(dc, LOGPIXELSY);
+
+ pp::Rect dest;
+ int rotate = CalculatePosition(page, new_settings, &dest);
+
+ int save_state = SaveDC(dc);
+ // The caller wanted all drawing to happen within the bounds specified.
+ // Based on scale calculations, our destination rect might be larger
+ // than the bounds. Set the clip rect to the bounds.
+ IntersectClipRect(dc, settings.bounds.x(), settings.bounds.y(),
+ settings.bounds.x() + settings.bounds.width(),
+ settings.bounds.y() + settings.bounds.height());
+
+ // A temporary hack. PDFs generated by Cairo (used by Chrome OS to generate
+ // a PDF output from a webpage) result in very large metafiles and the
+ // rendering using FPDF_RenderPage is incorrect. In this case, render as a
+ // bitmap. Note that this code does not kick in for PDFs printed from Chrome
+ // because in that case we create a temp PDF first before printing and this
+ // temp PDF does not have a creator string that starts with "cairo".
+ base::string16 creator;
+ size_t buffer_bytes = FPDF_GetMetaText(doc, "Creator", NULL, 0);
+ if (buffer_bytes > 1) {
+ FPDF_GetMetaText(
+ doc, "Creator", WriteInto(&creator, buffer_bytes + 1), buffer_bytes);
+ }
+ bool use_bitmap = false;
+ if (StartsWith(creator, L"cairo", false))
+ use_bitmap = true;
+
+ // Another temporary hack. Some PDFs seems to render very slowly if
+ // FPDF_RenderPage is directly used on a printer DC. I suspect it is
+ // because of the code to talk Postscript directly to the printer if
+ // the printer supports this. Need to discuss this with PDFium. For now,
+ // render to a bitmap and then blit the bitmap to the DC if we have been
+ // supplied a printer DC.
+ int device_type = GetDeviceCaps(dc, TECHNOLOGY);
+ if (use_bitmap ||
+ (device_type == DT_RASPRINTER) || (device_type == DT_PLOTTER)) {
+ FPDF_BITMAP bitmap = FPDFBitmap_Create(dest.width(), dest.height(),
+ FPDFBitmap_BGRx);
+ // Clear the bitmap
+ FPDFBitmap_FillRect(bitmap, 0, 0, dest.width(), dest.height(), 0xFFFFFFFF);
+ FPDF_RenderPageBitmap(
+ bitmap, page, 0, 0, dest.width(), dest.height(), rotate,
+ FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+ int stride = FPDFBitmap_GetStride(bitmap);
+ BITMAPINFO bmi;
+ memset(&bmi, 0, sizeof(bmi));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = dest.width();
+ bmi.bmiHeader.biHeight = -dest.height(); // top-down image
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biSizeImage = stride * dest.height();
+ StretchDIBits(dc, dest.x(), dest.y(), dest.width(), dest.height(),
+ 0, 0, dest.width(), dest.height(),
+ FPDFBitmap_GetBuffer(bitmap), &bmi, DIB_RGB_COLORS, SRCCOPY);
+ FPDFBitmap_Destroy(bitmap);
+ } else {
+ FPDF_RenderPage(dc, page, dest.x(), dest.y(), dest.width(), dest.height(),
+ rotate, FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+ }
+ RestoreDC(dc, save_state);
+ FPDF_ClosePage(page);
+ FPDF_CloseDocument(doc);
+ return true;
+}
+#endif // OS_WIN
+
+bool PDFiumEngineExports::RenderPDFPageToBitmap(
+ const void* pdf_buffer,
+ int pdf_buffer_size,
+ int page_number,
+ const RenderingSettings& settings,
+ void* bitmap_buffer) {
+ FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL);
+ if (!doc)
+ return false;
+ FPDF_PAGE page = FPDF_LoadPage(doc, page_number);
+ if (!page) {
+ FPDF_CloseDocument(doc);
+ return false;
+ }
+
+ pp::Rect dest;
+ int rotate = CalculatePosition(page, settings, &dest);
+
+ FPDF_BITMAP bitmap =
+ FPDFBitmap_CreateEx(settings.bounds.width(), settings.bounds.height(),
+ FPDFBitmap_BGRA, bitmap_buffer,
+ settings.bounds.width() * 4);
+ // Clear the bitmap
+ FPDFBitmap_FillRect(bitmap, 0, 0, settings.bounds.width(),
+ settings.bounds.height(), 0xFFFFFFFF);
+ // Shift top-left corner of bounds to (0, 0) if it's not there.
+ dest.set_point(dest.point() - settings.bounds.point());
+ FPDF_RenderPageBitmap(
+ bitmap, page, dest.x(), dest.y(), dest.width(), dest.height(), rotate,
+ FPDF_ANNOT | FPDF_PRINTING | FPDF_NO_CATCH);
+ FPDFBitmap_Destroy(bitmap);
+ FPDF_ClosePage(page);
+ FPDF_CloseDocument(doc);
+ return true;
+}
+
+bool PDFiumEngineExports::GetPDFDocInfo(const void* pdf_buffer,
+ int buffer_size,
+ int* page_count,
+ double* max_page_width) {
+ FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, buffer_size, NULL);
+ if (!doc)
+ return false;
+ int page_count_local = FPDF_GetPageCount(doc);
+ if (page_count) {
+ *page_count = page_count_local;
+ }
+ if (max_page_width) {
+ *max_page_width = 0;
+ for (int page_number = 0; page_number < page_count_local; page_number++) {
+ double page_width = 0;
+ double page_height = 0;
+ FPDF_GetPageSizeByIndex(doc, page_number, &page_width, &page_height);
+ if (page_width > *max_page_width) {
+ *max_page_width = page_width;
+ }
+ }
+ }
+ FPDF_CloseDocument(doc);
+ return true;
+}
+
+bool PDFiumEngineExports::GetPDFPageSizeByIndex(
+ const void* pdf_buffer,
+ int pdf_buffer_size,
+ int page_number,
+ double* width,
+ double* height) {
+ FPDF_DOCUMENT doc = FPDF_LoadMemDocument(pdf_buffer, pdf_buffer_size, NULL);
+ if (!doc)
+ return false;
+ bool success = FPDF_GetPageSizeByIndex(doc, page_number, width, height) != 0;
+ FPDF_CloseDocument(doc);
+ return success;
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/pdfium/pdfium_engine.h b/xfa_test/pdf/pdfium/pdfium_engine.h
new file mode 100644
index 0000000000..242c33df27
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_engine.h
@@ -0,0 +1,687 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PDFIUM_PDFIUM_ENGINE_H_
+#define PDF_PDFIUM_PDFIUM_ENGINE_H_
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/time/time.h"
+#include "pdf/document_loader.h"
+#include "pdf/pdf_engine.h"
+#include "pdf/pdfium/pdfium_page.h"
+#include "pdf/pdfium/pdfium_range.h"
+#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/buffer_dev.h"
+#include "ppapi/cpp/image_data.h"
+#include "ppapi/cpp/point.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_dataavail.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdf_progressive.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfformfill.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfview.h"
+
+#define _TEST_XFA
+#ifdef _TEST_XFA
+# if defined(WIN32)
+# define FXQA_TESTFILE(filename) "E:/"#filename
+# else
+# define FXQA_TESTFILE(filename) "/home/"#filename
+# endif
+#endif
+
+namespace pp {
+class KeyboardInputEvent;
+class MouseInputEvent;
+}
+
+namespace chrome_pdf {
+
+class ShadowMatrix;
+
+class PDFiumEngine : public PDFEngine,
+ public DocumentLoader::Client,
+ public FPDF_FORMFILLINFO,
+ public IPDF_JSPLATFORM,
+ public IFSDK_PAUSE {
+ public:
+ explicit PDFiumEngine(PDFEngine::Client* client);
+ virtual ~PDFiumEngine();
+
+ // PDFEngine implementation.
+ virtual bool New(const char* url);
+ virtual bool New(const char* url,
+ const char* headers);
+ virtual void PageOffsetUpdated(const pp::Point& page_offset);
+ virtual void PluginSizeUpdated(const pp::Size& size);
+ virtual void ScrolledToXPosition(int position);
+ virtual void ScrolledToYPosition(int position);
+ virtual void PrePaint();
+ virtual void Paint(const pp::Rect& rect,
+ pp::ImageData* image_data,
+ std::vector<pp::Rect>* ready,
+ std::vector<pp::Rect>* pending);
+ virtual void PostPaint();
+ virtual bool HandleDocumentLoad(const pp::URLLoader& loader);
+ virtual bool HandleEvent(const pp::InputEvent& event);
+ virtual uint32_t QuerySupportedPrintOutputFormats();
+ virtual void PrintBegin();
+ virtual pp::Resource PrintPages(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count,
+ const PP_PrintSettings_Dev& print_settings);
+ virtual void PrintEnd();
+ virtual void StartFind(const char* text, bool case_sensitive);
+ virtual bool SelectFindResult(bool forward);
+ virtual void StopFind();
+ virtual void ZoomUpdated(double new_zoom_level);
+ virtual void RotateClockwise();
+ virtual void RotateCounterclockwise();
+ virtual std::string GetSelectedText();
+ virtual std::string GetLinkAtPosition(const pp::Point& point);
+ virtual bool IsSelecting();
+ virtual bool HasPermission(DocumentPermission permission) const;
+ virtual void SelectAll();
+ virtual int GetNumberOfPages();
+ virtual int GetNamedDestinationPage(const std::string& destination);
+ virtual int GetFirstVisiblePage();
+ virtual int GetMostVisiblePage();
+ virtual pp::Rect GetPageRect(int index);
+ virtual pp::Rect GetPageContentsRect(int index);
+ virtual int GetVerticalScrollbarYPosition() { return position_.y(); }
+ virtual void PaintThumbnail(pp::ImageData* image_data, int index);
+ virtual void SetGrayscale(bool grayscale);
+ virtual void OnCallback(int id);
+ virtual std::string GetPageAsJSON(int index);
+ virtual bool GetPrintScaling();
+ virtual void AppendBlankPages(int num_pages);
+ virtual void AppendPage(PDFEngine* engine, int index);
+ virtual pp::Point GetScrollPosition();
+ virtual void SetScrollPosition(const pp::Point& position);
+ virtual bool IsProgressiveLoad();
+
+ // DocumentLoader::Client implementation.
+ virtual pp::Instance* GetPluginInstance();
+ virtual pp::URLLoader CreateURLLoader();
+ virtual void OnPartialDocumentLoaded();
+ virtual void OnPendingRequestComplete();
+ virtual void OnNewDataAvailable();
+ virtual void OnDocumentComplete();
+
+ void UnsupportedFeature(int type);
+
+ std::string current_find_text() const { return current_find_text_; }
+
+ FPDF_DOCUMENT doc() { return doc_; }
+ FPDF_FORMHANDLE form() { return form_; }
+
+ private:
+ // This helper class is used to detect the difference in selection between
+ // construction and destruction. At destruction, it invalidates all the
+ // parts that are newly selected, along with all the parts that used to be
+ // selected but are not anymore.
+ class SelectionChangeInvalidator {
+ public:
+ explicit SelectionChangeInvalidator(PDFiumEngine* engine);
+ ~SelectionChangeInvalidator();
+ private:
+ // Sets the given container to the all the currently visible selection
+ // rectangles, in screen coordinates.
+ void GetVisibleSelectionsScreenRects(std::vector<pp::Rect>* rects);
+
+ PDFiumEngine* engine_;
+ // Screen rectangles that were selected on construction.
+ std::vector<pp::Rect> old_selections_;
+ // The origin at the time this object was constructed.
+ pp::Point previous_origin_;
+ };
+
+ // Used to store mouse down state to handle it in other mouse event handlers.
+ class MouseDownState {
+ public:
+ MouseDownState(const PDFiumPage::Area& area,
+ const PDFiumPage::LinkTarget& target);
+ ~MouseDownState();
+
+ void Set(const PDFiumPage::Area& area,
+ const PDFiumPage::LinkTarget& target);
+ void Reset();
+ bool Matches(const PDFiumPage::Area& area,
+ const PDFiumPage::LinkTarget& target) const;
+
+ private:
+ PDFiumPage::Area area_;
+ PDFiumPage::LinkTarget target_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseDownState);
+ };
+
+ friend class SelectionChangeInvalidator;
+
+ struct FileAvail : public FX_FILEAVAIL {
+ DocumentLoader* loader;
+ };
+
+ struct DownloadHints : public FX_DOWNLOADHINTS {
+ DocumentLoader* loader;
+ };
+
+ // PDFium interface to get block of data.
+ static int GetBlock(void* param, unsigned long position,
+ unsigned char* buffer, unsigned long size);
+
+ // PDFium interface to check is block of data is available.
+ static bool IsDataAvail(FX_FILEAVAIL* param,
+ size_t offset, size_t size);
+
+ // PDFium interface to request download of the block of data.
+ static void AddSegment(FX_DOWNLOADHINTS* param,
+ size_t offset, size_t size);
+
+ // We finished getting the pdf file, so load it. This will complete
+ // asynchronously (due to password fetching) and may be run multiple times.
+ void LoadDocument();
+
+ // Try loading the document. Returns true if the document is successfully
+ // loaded or is already loaded otherwise it will return false. If
+ // |with_password| is set to true, the document will be loaded with
+ // |password|. If the document could not be loaded and needs a password,
+ // |needs_password| will be set to true.
+ bool TryLoadingDoc(bool with_password,
+ const std::string& password,
+ bool* needs_password);
+
+ // Ask the user for the document password and then continue loading the
+ // document.
+ void GetPasswordAndLoad();
+
+ // Called when the password has been retrieved.
+ void OnGetPasswordComplete(int32_t result,
+ const pp::Var& password);
+
+ // Continues loading the document when the password has been retrieved, or if
+ // there is no password.
+ void ContinueLoadingDocument(bool has_password,
+ const std::string& password);
+
+ // Finish loading the document and notify the client that the document has
+ // been loaded. This should only be run after |doc_| has been loaded and the
+ // document is fully downloaded. If this has been run once, it will result in
+ // a no-op.
+ void FinishLoadingDocument();
+
+ // Loads information about the pages in the document and calculate the
+ // document size.
+ void LoadPageInfo(bool reload);
+
+ // Calculate which pages should be displayed right now.
+ void CalculateVisiblePages();
+
+ // Returns true iff the given page index is visible. CalculateVisiblePages
+ // must have been called first.
+ bool IsPageVisible(int index) const;
+
+ // Checks if a page is now available, and if so marks it as such and returns
+ // true. Otherwise, it will return false and will add the index to the given
+ // array if it's not already there.
+ bool CheckPageAvailable(int index, std::vector<int>* pending);
+
+ // Helper function to get a given page's size in pixels. This is not part of
+ // PDFiumPage because we might not have that structure when we need this.
+ pp::Size GetPageSize(int index);
+
+ void UpdateTickMarks();
+
+ // Called to continue searching so we don't block the main thread.
+ void ContinueFind(int32_t result);
+
+ // Inserts a find result into find_results_, which is sorted.
+ void AddFindResult(const PDFiumRange& result);
+
+ // Search a page using PDFium's methods. Doesn't work with unicode. This
+ // function is just kept arount in case PDFium code is fixed.
+ void SearchUsingPDFium(const base::string16& term,
+ bool case_sensitive,
+ bool first_search,
+ int character_to_start_searching_from,
+ int current_page);
+
+ // Search a page ourself using ICU.
+ void SearchUsingICU(const base::string16& term,
+ bool case_sensitive,
+ bool first_search,
+ int character_to_start_searching_from,
+ int current_page);
+
+ // Input event handlers.
+ bool OnMouseDown(const pp::MouseInputEvent& event);
+ bool OnMouseUp(const pp::MouseInputEvent& event);
+ bool OnMouseMove(const pp::MouseInputEvent& event);
+ bool OnKeyDown(const pp::KeyboardInputEvent& event);
+ bool OnKeyUp(const pp::KeyboardInputEvent& event);
+ bool OnChar(const pp::KeyboardInputEvent& event);
+
+ FPDF_DOCUMENT CreateSinglePageRasterPdf(
+ double source_page_width,
+ double source_page_height,
+ const PP_PrintSettings_Dev& print_settings,
+ PDFiumPage* page_to_print);
+
+ pp::Buffer_Dev PrintPagesAsRasterPDF(
+ const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count,
+ const PP_PrintSettings_Dev& print_settings);
+
+ pp::Buffer_Dev PrintPagesAsPDF(const PP_PrintPageNumberRange_Dev* page_ranges,
+ uint32_t page_range_count,
+ const PP_PrintSettings_Dev& print_settings);
+
+ pp::Buffer_Dev GetFlattenedPrintData(const FPDF_DOCUMENT& doc);
+ void FitContentsToPrintableAreaIfRequired(
+ const FPDF_DOCUMENT& doc,
+ const PP_PrintSettings_Dev& print_settings);
+ void SaveSelectedFormForPrint();
+
+ // Given a mouse event, returns which page and character location it's closest
+ // to.
+ PDFiumPage::Area GetCharIndex(const pp::MouseInputEvent& event,
+ int* page_index,
+ int* char_index,
+ PDFiumPage::LinkTarget* target);
+ PDFiumPage::Area GetCharIndex(const pp::Point& point,
+ int* page_index,
+ int* char_index,
+ PDFiumPage::LinkTarget* target);
+
+ void OnSingleClick(int page_index, int char_index);
+ void OnMultipleClick(int click_count, int page_index, int char_index);
+
+ // Starts a progressive paint operation given a rectangle in screen
+ // coordinates. Returns the index in progressive_rects_.
+ int StartPaint(int page_index, const pp::Rect& dirty);
+
+ // Continues a paint operation that was started earlier. Returns true if the
+ // paint is done, or false if it needs to be continued.
+ bool ContinuePaint(int progressive_index, pp::ImageData* image_data);
+
+ // Called once PDFium is finished rendering a page so that we draw our
+ // borders, highlighting etc.
+ void FinishPaint(int progressive_index, pp::ImageData* image_data);
+
+ // Stops any paints that are in progress.
+ void CancelPaints();
+
+ // Invalidates all pages. Use this when some global parameter, such as page
+ // orientation, has changed.
+ void InvalidateAllPages();
+
+ // If the page is narrower than the document size, paint the extra space
+ // with the page background.
+ void FillPageSides(int progressive_index);
+
+ void PaintPageShadow(int progressive_index, pp::ImageData* image_data);
+
+ // Highlight visible find results and selections.
+ void DrawSelections(int progressive_index, pp::ImageData* image_data);
+
+ // Paints an page that hasn't finished downloading.
+ void PaintUnavailablePage(int page_index,
+ const pp::Rect& dirty,
+ pp::ImageData* image_data);
+
+ // Given a page index, returns the corresponding index in progressive_rects_,
+ // or -1 if it doesn't exist.
+ int GetProgressiveIndex(int page_index) const;
+
+ // Creates a FPDF_BITMAP from a rectangle in screen coordinates.
+ FPDF_BITMAP CreateBitmap(const pp::Rect& rect,
+ pp::ImageData* image_data) const;
+
+ // Given a rectangle in screen coordinates, returns the coordinates in the
+ // units that PDFium rendering functions expect.
+ void GetPDFiumRect(int page_index, const pp::Rect& rect, int* start_x,
+ int* start_y, int* size_x, int* size_y) const;
+
+ // Returns the rendering flags to pass to PDFium.
+ int GetRenderingFlags() const;
+
+ // Returns the currently visible rectangle in document coordinates.
+ pp::Rect GetVisibleRect() const;
+
+ // Returns a page's rect in screen coordinates, as well as its surrounding
+ // border areas and bottom separator.
+ pp::Rect GetPageScreenRect(int page_index) const;
+
+ // Given a rectangle in document coordinates, returns the rectange into screen
+ // coordinates (i.e. 0,0 is top left corner of plugin area). If it's not
+ // visible, an empty rectangle is returned.
+ pp::Rect GetScreenRect(const pp::Rect& rect) const;
+
+ // Highlights the given rectangle.
+ void Highlight(void* buffer,
+ int stride,
+ const pp::Rect& rect,
+ std::vector<pp::Rect>* highlighted_rects);
+
+ // Helper function to convert a device to page coordinates. If the page is
+ // not yet loaded, page_x and page_y will be set to 0.
+ void DeviceToPage(int page_index,
+ float device_x,
+ float device_y,
+ double* page_x,
+ double* page_y);
+
+ // Helper function to get the index of a given FPDF_PAGE. Returns -1 if not
+ // found.
+ int GetVisiblePageIndex(FPDF_PAGE page);
+
+ // Helper function to change the current page, running page open/close
+ // triggers as necessary.
+ void SetCurrentPage(int index);
+
+ // Transform |page| contents to fit in the selected printer paper size.
+ void TransformPDFPageForPrinting(FPDF_PAGE page,
+ const PP_PrintSettings_Dev& print_settings);
+
+ void DrawPageShadow(const pp::Rect& page_rect,
+ const pp::Rect& shadow_rect,
+ const pp::Rect& clip_rect,
+ pp::ImageData* image_data);
+
+ void GetRegion(const pp::Point& location,
+ pp::ImageData* image_data,
+ void** region,
+ int* stride) const;
+
+ // Called when the selection changes.
+ void OnSelectionChanged();
+
+ // FPDF_FORMFILLINFO callbacks.
+ static void Form_Invalidate(FPDF_FORMFILLINFO* param,
+ FPDF_PAGE page,
+ double left,
+ double top,
+ double right,
+ double bottom);
+ static void Form_OutputSelectedRect(FPDF_FORMFILLINFO* param,
+ FPDF_PAGE page,
+ double left,
+ double top,
+ double right,
+ double bottom);
+ static void Form_SetCursor(FPDF_FORMFILLINFO* param, int cursor_type);
+ static int Form_SetTimer(FPDF_FORMFILLINFO* param,
+ int elapse,
+ TimerCallback timer_func);
+ static void Form_KillTimer(FPDF_FORMFILLINFO* param, int timer_id);
+ static FPDF_SYSTEMTIME Form_GetLocalTime(FPDF_FORMFILLINFO* param);
+ static void Form_OnChange(FPDF_FORMFILLINFO* param);
+ static FPDF_PAGE Form_GetPage(FPDF_FORMFILLINFO* param,
+ FPDF_DOCUMENT document,
+ int page_index);
+ static FPDF_PAGE Form_GetCurrentPage(FPDF_FORMFILLINFO* param,
+ FPDF_DOCUMENT document);
+ static int Form_GetRotation(FPDF_FORMFILLINFO* param, FPDF_PAGE page);
+ static void Form_ExecuteNamedAction(FPDF_FORMFILLINFO* param,
+ FPDF_BYTESTRING named_action);
+ static void Form_SetTextFieldFocus(FPDF_FORMFILLINFO* param,
+ FPDF_WIDESTRING value,
+ FPDF_DWORD valueLen,
+ FPDF_BOOL is_focus);
+ static void Form_DoURIAction(FPDF_FORMFILLINFO* param, FPDF_BYTESTRING uri);
+ static void Form_DoGoToAction(FPDF_FORMFILLINFO* param,
+ int page_index,
+ int zoom_mode,
+ float* position_array,
+ int size_of_array);
+
+ // IPDF_JSPLATFORM callbacks.
+ static int Form_Alert(IPDF_JSPLATFORM* param,
+ FPDF_WIDESTRING message,
+ FPDF_WIDESTRING title,
+ int type,
+ int icon);
+ static void Form_Beep(IPDF_JSPLATFORM* param, int type);
+ static int Form_Response(IPDF_JSPLATFORM* param,
+ FPDF_WIDESTRING question,
+ FPDF_WIDESTRING title,
+ FPDF_WIDESTRING default_response,
+ FPDF_WIDESTRING label,
+ FPDF_BOOL password,
+ void* response,
+ int length);
+ static int Form_GetFilePath(IPDF_JSPLATFORM* param,
+ void* file_path,
+ int length);
+ static void Form_Mail(IPDF_JSPLATFORM* param,
+ void* mail_data,
+ int length,
+ FPDF_BOOL ui,
+ FPDF_WIDESTRING to,
+ FPDF_WIDESTRING subject,
+ FPDF_WIDESTRING cc,
+ FPDF_WIDESTRING bcc,
+ FPDF_WIDESTRING message);
+ static void Form_Print(IPDF_JSPLATFORM* param,
+ FPDF_BOOL ui,
+ int start,
+ int end,
+ FPDF_BOOL silent,
+ FPDF_BOOL shrink_to_fit,
+ FPDF_BOOL print_as_image,
+ FPDF_BOOL reverse,
+ FPDF_BOOL annotations);
+ static void Form_SubmitForm(IPDF_JSPLATFORM* param,
+ void* form_data,
+ int length,
+ FPDF_WIDESTRING url);
+ static void Form_GotoPage(IPDF_JSPLATFORM* param, int page_number);
+ static int Form_Browse(IPDF_JSPLATFORM* param, void* file_path, int length);
+#ifdef _TEST_XFA
+ static void Form_EmailTo(FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* fileHandler,
+ FPDF_WIDESTRING to, FPDF_WIDESTRING subject, FPDF_WIDESTRING cc, FPDF_WIDESTRING bcc, FPDF_WIDESTRING message);
+ static void Form_DisplayCaret(FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_BOOL bVisible, double left, double top, double right, double bottom);
+ //static int Form_GetCurDocumentIndex(FPDF_FORMFILLINFO* pThis);
+ //static int Form_GetDocumentCount(FPDF_FORMFILLINFO* pThis);
+ static void Form_SetCurrentPage(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, int iCurPage);
+ static int Form_GetCurrentPageIndex(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document);
+ static void Form_GetPageViewRect(FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, double* left, double* top, double* right, double* bottom);
+ static int Form_GetPlatform(FPDF_FORMFILLINFO* pThis, void* platform, int length);
+ static FPDF_BOOL Form_PopupMenu(FPDF_FORMFILLINFO* pThis, FPDF_PAGE page, FPDF_WIDGET hWidget, int menuFlag, float x, float y);
+ static FPDF_BOOL Form_PostRequestURL(FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsContentType, FPDF_WIDESTRING wsEncode, FPDF_WIDESTRING wsHeader, FPDF_BSTR* respone);
+ static FPDF_BOOL Form_PutRequestURL(FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsURL, FPDF_WIDESTRING wsData, FPDF_WIDESTRING wsEncode);
+ //static FPDF_BOOL Form_ShowFileDialog(FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING wsTitle, FPDF_WIDESTRING wsFilter, FPDF_BOOL isOpen, FPDF_STRINGHANDLE pathArr);
+ static void Form_UploadTo(FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* fileHandler, int fileFlag, FPDF_WIDESTRING uploadTo);
+ static FPDF_LPFILEHANDLER Form_DownloadFromURL(FPDF_FORMFILLINFO* pThis, FPDF_WIDESTRING URL);
+ //static FPDF_BOOL MyForm_GetFilePath(FPDF_FORMFILLINFO* pThis, FPDF_FILEHANDLER* pFileHandler, void* filePath, int length);
+ static FPDF_FILEHANDLER* Form_OpenFile(FPDF_FORMFILLINFO* pThis, int fileFlag, FPDF_WIDESTRING wsURL, const char* mode);
+ static void Form_GotoURL(FPDF_FORMFILLINFO* pThis, FPDF_DOCUMENT document, FPDF_WIDESTRING wsURL);
+ static int Form_GetLanguage(FPDF_FORMFILLINFO* pThis, void* language, int length);
+#endif // _TEST_XFA
+ // IFSDK_PAUSE callbacks
+ static FPDF_BOOL Pause_NeedToPauseNow(IFSDK_PAUSE* param);
+
+ PDFEngine::Client* client_;
+ pp::Size document_size_; // Size of document in pixels.
+
+ // The scroll position in screen coordinates.
+ pp::Point position_;
+ // The offset of the page into the viewport.
+ pp::Point page_offset_;
+ // The plugin size in screen coordinates.
+ pp::Size plugin_size_;
+ double current_zoom_;
+ unsigned int current_rotation_;
+
+ DocumentLoader doc_loader_; // Main document's loader.
+ std::string url_;
+ std::string headers_;
+ pp::CompletionCallbackFactory<PDFiumEngine> find_factory_;
+
+ pp::CompletionCallbackFactory<PDFiumEngine> password_factory_;
+ int32_t password_tries_remaining_;
+
+ // The current text used for searching.
+ std::string current_find_text_;
+
+ // The PDFium wrapper object for the document.
+ FPDF_DOCUMENT doc_;
+
+ // The PDFium wrapper for form data. Used even if there are no form controls
+ // on the page.
+ FPDF_FORMHANDLE form_;
+
+ // The page(s) of the document. Store a vector of pointers so that when the
+ // vector is resized we don't close the pages that are used in pending
+ // paints.
+ std::vector<PDFiumPage*> pages_;
+
+ // The indexes of the pages currently visible.
+ std::vector<int> visible_pages_;
+
+ // The indexes of the pages pending download.
+ std::vector<int> pending_pages_;
+
+ // During handling of input events we don't want to unload any pages in
+ // callbacks to us from PDFium, since the current page can change while PDFium
+ // code still has a pointer to it.
+ bool defer_page_unload_;
+ std::vector<int> deferred_page_unloads_;
+
+ // Used for selection. There could be more than one range if selection spans
+ // more than one page.
+ std::vector<PDFiumRange> selection_;
+ // True if we're in the middle of selection.
+ bool selecting_;
+
+ MouseDownState mouse_down_state_;
+
+ // Used for searching.
+ typedef std::vector<PDFiumRange> FindResults;
+ FindResults find_results_;
+ // Which page to search next.
+ int next_page_to_search_;
+ // Where to stop searching.
+ int last_page_to_search_;
+ int last_character_index_to_search_; // -1 if search until end of page.
+ // Which result the user has currently selected.
+ int current_find_index_;
+ // Where to resume searching.
+ int resume_find_index_;
+
+ // Permissions bitfield.
+ unsigned long permissions_;
+
+ // Interface structure to provide access to document stream.
+ FPDF_FILEACCESS file_access_;
+ // Interface structure to check data availability in the document stream.
+ FileAvail file_availability_;
+ // Interface structure to request data chunks from the document stream.
+ DownloadHints download_hints_;
+ // Pointer to the document availability interface.
+ FPDF_AVAIL fpdf_availability_;
+
+ pp::Size default_page_size_;
+
+ // Used to manage timers that form fill API needs. The pair holds the timer
+ // period, in ms, and the callback function.
+ std::map<int, std::pair<int, TimerCallback> > timers_;
+ int next_timer_id_;
+
+ // Holds the page index of the last page that the mouse clicked on.
+ int last_page_mouse_down_;
+
+ // Holds the page index of the first visible page; refreshed by calling
+ // CalculateVisiblePages()
+ int first_visible_page_;
+
+ // Holds the page index of the most visible page; refreshed by calling
+ // CalculateVisiblePages()
+ int most_visible_page_;
+
+ // Set to true after FORM_DoDocumentJSAction/FORM_DoDocumentOpenAction have
+ // been called. Only after that can we call FORM_DoPageAAction.
+ bool called_do_document_action_;
+
+ // Records parts of form fields that need to be highlighted at next paint, in
+ // screen coordinates.
+ std::vector<pp::Rect> form_highlights_;
+
+ // Whether to render in grayscale or in color.
+ bool render_grayscale_;
+
+ // The link currently under the cursor.
+ std::string link_under_cursor_;
+
+ // Pending progressive paints.
+ struct ProgressivePaint {
+ pp::Rect rect; // In screen coordinates.
+ FPDF_BITMAP bitmap;
+ int page_index;
+ // Temporary used to figure out if in a series of Paint() calls whether this
+ // pending paint was updated or not.
+ int painted_;
+ };
+ std::vector<ProgressivePaint> progressive_paints_;
+
+ // Keeps track of when we started the last progressive paint, so that in our
+ // callback we can determine if we need to pause.
+ base::Time last_progressive_start_time_;
+
+ // The timeout to use for the current progressive paint.
+ int progressive_paint_timeout_;
+
+ // Shadow matrix for generating the page shadow bitmap.
+ scoped_ptr<ShadowMatrix> page_shadow_;
+
+ // Set to true if the user is being prompted for their password. Will be set
+ // to false after the user finishes getting their password.
+ bool getting_password_;
+};
+
+// Create a local variable of this when calling PDFium functions which can call
+// our global callback when an unsupported feature is reached.
+class ScopedUnsupportedFeature {
+ public:
+ explicit ScopedUnsupportedFeature(PDFiumEngine* engine);
+ ~ScopedUnsupportedFeature();
+ private:
+ PDFiumEngine* engine_;
+ PDFiumEngine* old_engine_;
+};
+
+class PDFiumEngineExports : public PDFEngineExports {
+ public:
+ PDFiumEngineExports() {}
+#if defined(OS_WIN)
+ // See the definition of RenderPDFPageToDC in pdf.cc for details.
+ virtual bool RenderPDFPageToDC(const void* pdf_buffer,
+ int buffer_size,
+ int page_number,
+ const RenderingSettings& settings,
+ HDC dc);
+#endif // OS_WIN
+ virtual bool RenderPDFPageToBitmap(const void* pdf_buffer,
+ int pdf_buffer_size,
+ int page_number,
+ const RenderingSettings& settings,
+ void* bitmap_buffer);
+
+ virtual bool GetPDFDocInfo(const void* pdf_buffer,
+ int buffer_size,
+ int* page_count,
+ double* max_page_width);
+
+ // See the definition of GetPDFPageSizeByIndex in pdf.cc for details.
+ virtual bool GetPDFPageSizeByIndex(const void* pdf_buffer,
+ int pdf_buffer_size, int page_number,
+ double* width, double* height);
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDFIUM_PDFIUM_ENGINE_H_
diff --git a/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.cc b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.cc
new file mode 100644
index 0000000000..b2371b42ff
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/pdfium/pdfium_mem_buffer_file_read.h"
+
+#include <string.h>
+
+namespace chrome_pdf {
+
+PDFiumMemBufferFileRead::PDFiumMemBufferFileRead(const void* data,
+ size_t size) {
+ m_FileLen = size;
+ m_Param = this;
+ m_GetBlock = &GetBlock;
+ data_ = reinterpret_cast<const unsigned char*>(data);
+}
+
+PDFiumMemBufferFileRead::~PDFiumMemBufferFileRead() {
+}
+
+int PDFiumMemBufferFileRead::GetBlock(void* param,
+ unsigned long position,
+ unsigned char* buf,
+ unsigned long size) {
+ const PDFiumMemBufferFileRead* data =
+ reinterpret_cast<const PDFiumMemBufferFileRead*>(param);
+ if (!data || position + size > data->m_FileLen)
+ return 0;
+ memcpy(buf, data->data_ + position, size);
+ return 1;
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.h b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.h
new file mode 100644
index 0000000000..88ec410a6c
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_read.h
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PDFIUM_PDFIUM_MEM_BUFFER_FILE_READ_H_
+#define PDF_PDFIUM_PDFIUM_MEM_BUFFER_FILE_READ_H_
+
+#include <stdlib.h>
+
+#include "third_party/pdfium/fpdfsdk/include/fpdfview.h"
+
+namespace chrome_pdf {
+
+// Implementation of FPDF_FILEACCESS from a memory buffer.
+class PDFiumMemBufferFileRead : public FPDF_FILEACCESS {
+ public:
+ PDFiumMemBufferFileRead(const void* data, size_t size);
+ ~PDFiumMemBufferFileRead();
+
+ private:
+ static int GetBlock(void* param,
+ unsigned long position,
+ unsigned char* buf,
+ unsigned long size);
+ const unsigned char* data_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDFIUM_PDFIUM_MEM_BUFFER_FILE_READ_H_
diff --git a/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.cc b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.cc
new file mode 100644
index 0000000000..45e564b67b
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.cc
@@ -0,0 +1,33 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/pdfium/pdfium_mem_buffer_file_write.h"
+
+namespace chrome_pdf {
+
+PDFiumMemBufferFileWrite::PDFiumMemBufferFileWrite() {
+ version = 1;
+ WriteBlock = &WriteBlockImpl;
+}
+
+PDFiumMemBufferFileWrite::~PDFiumMemBufferFileWrite() {
+}
+
+int PDFiumMemBufferFileWrite::WriteBlockImpl(FPDF_FILEWRITE* this_file_write,
+ const void* data,
+ unsigned long size) {
+ PDFiumMemBufferFileWrite* mem_buffer_file_write =
+ static_cast<PDFiumMemBufferFileWrite*>(this_file_write);
+ return mem_buffer_file_write->DoWriteBlock(data, size);
+}
+
+int PDFiumMemBufferFileWrite::DoWriteBlock(const void* data,
+ unsigned long size) {
+ buffer_.append(static_cast<const unsigned char*>(data), size);
+ return 1;
+}
+
+
+} // namespace chrome_pdf
+
diff --git a/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.h b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.h
new file mode 100644
index 0000000000..1795c83e89
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_mem_buffer_file_write.h
@@ -0,0 +1,34 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PDFIUM_PDFIUM_MEM_BUFFER_FILE_WRITE_
+#define PDF_PDFIUM_PDFIUM_MEM_BUFFER_FILE_WRITE_
+
+#include <string>
+
+#include "third_party/pdfium/fpdfsdk/include/fpdfsave.h"
+
+namespace chrome_pdf {
+
+// Implementation of FPDF_FILEWRITE into a memory buffer.
+class PDFiumMemBufferFileWrite : public FPDF_FILEWRITE {
+ public:
+ PDFiumMemBufferFileWrite();
+ ~PDFiumMemBufferFileWrite();
+
+ const std::basic_string<unsigned char>& buffer() { return buffer_; }
+ size_t size() { return buffer_.size(); }
+
+ private:
+ int DoWriteBlock(const void* data, unsigned long size);
+ static int WriteBlockImpl(FPDF_FILEWRITE* this_file_write, const void* data,
+ unsigned long size);
+
+ std::basic_string<unsigned char> buffer_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDFIUM_PDFIUM_MEM_BUFFER_FILE_WRITE_
+
diff --git a/xfa_test/pdf/pdfium/pdfium_page.cc b/xfa_test/pdf/pdfium/pdfium_page.cc
new file mode 100644
index 0000000000..d8a5dce5a2
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_page.cc
@@ -0,0 +1,477 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/pdfium/pdfium_page.h"
+
+#include <math.h>
+
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/values.h"
+#include "pdf/pdfium/pdfium_engine.h"
+
+// Used when doing hit detection.
+#define kTolerance 20.0
+
+// Dictionary Value key names for returning the accessible page content as JSON.
+const char kPageWidth[] = "width";
+const char kPageHeight[] = "height";
+const char kPageTextBox[] = "textBox";
+const char kTextBoxLeft[] = "left";
+const char kTextBoxTop[] = "top";
+const char kTextBoxWidth[] = "width";
+const char kTextBoxHeight[] = "height";
+const char kTextBoxFontSize[] = "fontSize";
+const char kTextBoxNodes[] = "textNodes";
+const char kTextNodeType[] = "type";
+const char kTextNodeText[] = "text";
+const char kTextNodeURL[] = "url";
+const char kTextNodeTypeText[] = "text";
+const char kTextNodeTypeURL[] = "url";
+const char kDocLinkURLPrefix[] = "#page";
+
+namespace chrome_pdf {
+
+PDFiumPage::PDFiumPage(PDFiumEngine* engine,
+ int i,
+ const pp::Rect& r,
+ bool available)
+ : engine_(engine),
+ page_(NULL),
+ text_page_(NULL),
+ index_(i),
+ rect_(r),
+ calculated_links_(false),
+ available_(available) {
+}
+
+PDFiumPage::~PDFiumPage() {
+}
+
+void PDFiumPage::Unload() {
+ if (text_page_) {
+ FPDFText_ClosePage(text_page_);
+ text_page_ = NULL;
+ }
+
+ if (page_) {
+ if (engine_->form()) {
+ FORM_OnBeforeClosePage(page_, engine_->form());
+ }
+ FPDF_ClosePage(page_);
+ page_ = NULL;
+ }
+}
+
+FPDF_PAGE PDFiumPage::GetPage() {
+ ScopedUnsupportedFeature scoped_unsupported_feature(engine_);
+ if (!available_)
+ return NULL;
+ if (!page_) {
+ page_ = FPDF_LoadPage(engine_->doc(), index_);
+ if (page_ && engine_->form()) {
+ FORM_OnAfterLoadPage(page_, engine_->form());
+ }
+ }
+ return page_;
+}
+
+FPDF_PAGE PDFiumPage::GetPrintPage() {
+ ScopedUnsupportedFeature scoped_unsupported_feature(engine_);
+ if (!available_)
+ return NULL;
+ if (!page_)
+ page_ = FPDF_LoadPage(engine_->doc(), index_);
+ return page_;
+}
+
+void PDFiumPage::ClosePrintPage() {
+ if (page_) {
+ FPDF_ClosePage(page_);
+ page_ = NULL;
+ }
+}
+
+FPDF_TEXTPAGE PDFiumPage::GetTextPage() {
+ if (!available_)
+ return NULL;
+ if (!text_page_)
+ text_page_ = FPDFText_LoadPage(GetPage());
+ return text_page_;
+}
+
+base::Value* PDFiumPage::GetAccessibleContentAsValue(int rotation) {
+ base::DictionaryValue* node = new base::DictionaryValue();
+
+ if (!available_)
+ return node;
+
+ double width = FPDF_GetPageWidth(GetPage());
+ double height = FPDF_GetPageHeight(GetPage());
+
+ base::ListValue* text = new base::ListValue();
+ int box_count = FPDFText_CountRects(GetTextPage(), 0, GetCharCount());
+ for (int i = 0; i < box_count; i++) {
+ double left, top, right, bottom;
+ FPDFText_GetRect(GetTextPage(), i, &left, &top, &right, &bottom);
+ text->Append(
+ GetTextBoxAsValue(height, left, top, right, bottom, rotation));
+ }
+
+ node->SetDouble(kPageWidth, width);
+ node->SetDouble(kPageHeight, height);
+ node->Set(kPageTextBox, text); // Takes ownership of |text|
+
+ return node;
+}
+
+base::Value* PDFiumPage::GetTextBoxAsValue(double page_height,
+ double left, double top,
+ double right, double bottom,
+ int rotation) {
+ base::string16 text_utf16;
+ int char_count =
+ FPDFText_GetBoundedText(GetTextPage(), left, top, right, bottom, NULL, 0);
+ if (char_count > 0) {
+ unsigned short* data = reinterpret_cast<unsigned short*>(
+ WriteInto(&text_utf16, char_count + 1));
+ FPDFText_GetBoundedText(GetTextPage(),
+ left, top, right, bottom,
+ data, char_count);
+ }
+ std::string text_utf8 = base::UTF16ToUTF8(text_utf16);
+
+ FPDF_LINK link = FPDFLink_GetLinkAtPoint(GetPage(), left, top);
+ Area area;
+ std::vector<LinkTarget> targets;
+ if (link) {
+ targets.push_back(LinkTarget());
+ area = GetLinkTarget(link, &targets[0]);
+ } else {
+ pp::Rect rect(
+ PageToScreen(pp::Point(), 1.0, left, top, right, bottom, rotation));
+ GetLinks(rect, &targets);
+ area = targets.size() == 0 ? TEXT_AREA : WEBLINK_AREA;
+ }
+
+ int char_index = FPDFText_GetCharIndexAtPos(GetTextPage(), left, top,
+ kTolerance, kTolerance);
+ double font_size = FPDFText_GetFontSize(GetTextPage(), char_index);
+
+ base::DictionaryValue* node = new base::DictionaryValue();
+ node->SetDouble(kTextBoxLeft, left);
+ node->SetDouble(kTextBoxTop, page_height - top);
+ node->SetDouble(kTextBoxWidth, right - left);
+ node->SetDouble(kTextBoxHeight, top - bottom);
+ node->SetDouble(kTextBoxFontSize, font_size);
+
+ base::ListValue* text_nodes = new base::ListValue();
+
+ if (area == DOCLINK_AREA) {
+ std::string url = kDocLinkURLPrefix + base::IntToString(targets[0].page);
+ text_nodes->Append(CreateURLNode(text_utf8, url));
+ } else if (area == WEBLINK_AREA && link) {
+ text_nodes->Append(CreateURLNode(text_utf8, targets[0].url));
+ } else if (area == WEBLINK_AREA && !link) {
+ size_t start = 0;
+ for (size_t i = 0; i < targets.size(); ++i) {
+ // Remove the extra NULL character at end.
+ // Otherwise, find() will not return any matches.
+ if (targets[i].url.size() > 0 &&
+ targets[i].url[targets[i].url.size() - 1] == '\0') {
+ targets[i].url.resize(targets[i].url.size() - 1);
+ }
+ // There should only ever be one NULL character
+ DCHECK(targets[i].url[targets[i].url.size() - 1] != '\0');
+
+ // PDFium may change the case of generated links.
+ std::string lowerCaseURL = base::StringToLowerASCII(targets[i].url);
+ std::string lowerCaseText = base::StringToLowerASCII(text_utf8);
+ size_t pos = lowerCaseText.find(lowerCaseURL, start);
+ size_t length = targets[i].url.size();
+ if (pos == std::string::npos) {
+ // Check if the link is a "mailto:" URL
+ if (lowerCaseURL.compare(0, 7, "mailto:") == 0) {
+ pos = lowerCaseText.find(lowerCaseURL.substr(7), start);
+ length -= 7;
+ }
+
+ if (pos == std::string::npos) {
+ // No match has been found. This should never happen.
+ continue;
+ }
+ }
+
+ std::string before_text = text_utf8.substr(start, pos - start);
+ if (before_text.size() > 0)
+ text_nodes->Append(CreateTextNode(before_text));
+ std::string link_text = text_utf8.substr(pos, length);
+ text_nodes->Append(CreateURLNode(link_text, targets[i].url));
+
+ start = pos + length;
+ }
+ std::string before_text = text_utf8.substr(start);
+ if (before_text.size() > 0)
+ text_nodes->Append(CreateTextNode(before_text));
+ } else {
+ text_nodes->Append(CreateTextNode(text_utf8));
+ }
+
+ node->Set(kTextBoxNodes, text_nodes); // Takes ownership of |text_nodes|.
+ return node;
+}
+
+base::Value* PDFiumPage::CreateTextNode(std::string text) {
+ base::DictionaryValue* node = new base::DictionaryValue();
+ node->SetString(kTextNodeType, kTextNodeTypeText);
+ node->SetString(kTextNodeText, text);
+ return node;
+}
+
+base::Value* PDFiumPage::CreateURLNode(std::string text, std::string url) {
+ base::DictionaryValue* node = new base::DictionaryValue();
+ node->SetString(kTextNodeType, kTextNodeTypeURL);
+ node->SetString(kTextNodeText, text);
+ node->SetString(kTextNodeURL, url);
+ return node;
+}
+
+PDFiumPage::Area PDFiumPage::GetCharIndex(const pp::Point& point,
+ int rotation,
+ int* char_index,
+ LinkTarget* target) {
+ if (!available_)
+ return NONSELECTABLE_AREA;
+ pp::Point point2 = point - rect_.point();
+ double new_x, new_y;
+ FPDF_DeviceToPage(GetPage(), 0, 0, rect_.width(), rect_.height(),
+ rotation, point2.x(), point2.y(), &new_x, &new_y);
+
+ int rv = FPDFText_GetCharIndexAtPos(
+ GetTextPage(), new_x, new_y, kTolerance, kTolerance);
+ *char_index = rv;
+
+ FPDF_LINK link = FPDFLink_GetLinkAtPoint(GetPage(), new_x, new_y);
+ if (link) {
+ // We don't handle all possible link types of the PDF. For example,
+ // launch actions, cross-document links, etc.
+ // In that case, GetLinkTarget() will return NONSELECTABLE_AREA
+ // and we should proceed with area detection.
+ PDFiumPage::Area area = GetLinkTarget(link, target);
+ if (area != PDFiumPage::NONSELECTABLE_AREA)
+ return area;
+ }
+
+ if (rv < 0)
+ return NONSELECTABLE_AREA;
+
+ return GetLink(*char_index, target) != -1 ? WEBLINK_AREA : TEXT_AREA;
+}
+
+base::char16 PDFiumPage::GetCharAtIndex(int index) {
+ if (!available_)
+ return L'\0';
+ return static_cast<base::char16>(FPDFText_GetUnicode(GetTextPage(), index));
+}
+
+int PDFiumPage::GetCharCount() {
+ if (!available_)
+ return 0;
+ return FPDFText_CountChars(GetTextPage());
+}
+
+PDFiumPage::Area PDFiumPage::GetLinkTarget(
+ FPDF_LINK link, PDFiumPage::LinkTarget* target) {
+ FPDF_DEST dest = FPDFLink_GetDest(engine_->doc(), link);
+ if (dest != NULL)
+ return GetDestinationTarget(dest, target);
+
+ FPDF_ACTION action = FPDFLink_GetAction(link);
+ if (action) {
+ switch (FPDFAction_GetType(action)) {
+ case PDFACTION_GOTO: {
+ FPDF_DEST dest = FPDFAction_GetDest(engine_->doc(), action);
+ if (dest)
+ return GetDestinationTarget(dest, target);
+ // TODO(gene): We don't fully support all types of the in-document
+ // links. Need to implement that. There is a bug to track that:
+ // http://code.google.com/p/chromium/issues/detail?id=55776
+ } break;
+ case PDFACTION_URI: {
+ if (target) {
+ size_t buffer_size =
+ FPDFAction_GetURIPath(engine_->doc(), action, NULL, 0);
+ if (buffer_size > 1) {
+ void* data = WriteInto(&target->url, buffer_size + 1);
+ FPDFAction_GetURIPath(engine_->doc(), action, data, buffer_size);
+ }
+ }
+ return WEBLINK_AREA;
+ } break;
+ // TODO(gene): We don't support PDFACTION_REMOTEGOTO and PDFACTION_LAUNCH
+ // at the moment.
+ }
+ }
+
+ return NONSELECTABLE_AREA;
+}
+
+PDFiumPage::Area PDFiumPage::GetDestinationTarget(
+ FPDF_DEST destination, PDFiumPage::LinkTarget* target) {
+ int page_index = FPDFDest_GetPageIndex(engine_->doc(), destination);
+ if (target) {
+ target->page = page_index;
+ }
+ return DOCLINK_AREA;
+}
+
+int PDFiumPage::GetLink(int char_index, PDFiumPage::LinkTarget* target) {
+ if (!available_)
+ return -1;
+
+ CalculateLinks();
+
+ // Get the bounding box of the rect again, since it might have moved because
+ // of the tolerance above.
+ double left, right, bottom, top;
+ FPDFText_GetCharBox(GetTextPage(), char_index, &left, &right, &bottom, &top);
+
+ pp::Point origin(
+ PageToScreen(pp::Point(), 1.0, left, top, right, bottom, 0).point());
+ for (size_t i = 0; i < links_.size(); ++i) {
+ for (size_t j = 0; j < links_[i].rects.size(); ++j) {
+ if (links_[i].rects[j].Contains(origin)) {
+ if (target)
+ target->url = links_[i].url;
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+std::vector<int> PDFiumPage::GetLinks(pp::Rect text_area,
+ std::vector<LinkTarget>* targets) {
+ if (!available_)
+ return std::vector<int>();
+
+ CalculateLinks();
+
+ std::vector<int> links;
+
+ for (size_t i = 0; i < links_.size(); ++i) {
+ for (size_t j = 0; j < links_[i].rects.size(); ++j) {
+ if (links_[i].rects[j].Intersects(text_area)) {
+ if (targets) {
+ LinkTarget target;
+ target.url = links_[i].url;
+ targets->push_back(target);
+ }
+ links.push_back(i);
+ }
+ }
+ }
+ return links;
+}
+
+void PDFiumPage::CalculateLinks() {
+ if (calculated_links_)
+ return;
+
+ calculated_links_ = true;
+ FPDF_PAGELINK links = FPDFLink_LoadWebLinks(GetTextPage());
+ int count = FPDFLink_CountWebLinks(links);
+ for (int i = 0; i < count; ++i) {
+ base::string16 url;
+ int url_length = FPDFLink_GetURL(links, i, NULL, 0);
+ if (url_length > 1) { // WriteInto needs at least 2 characters.
+ unsigned short* data =
+ reinterpret_cast<unsigned short*>(WriteInto(&url, url_length + 1));
+ FPDFLink_GetURL(links, i, data, url_length);
+ }
+ Link link;
+ link.url = base::UTF16ToUTF8(url);
+
+ // If the link cannot be converted to a pp::Var, then it is not possible to
+ // pass it to JS. In this case, ignore the link like other PDF viewers.
+ // See http://crbug.com/312882 for an example.
+ pp::Var link_var(link.url);
+ if (!link_var.is_string())
+ continue;
+
+ // Make sure all the characters in the URL are valid per RFC 1738.
+ // http://crbug.com/340326 has a sample bad PDF.
+ // GURL does not work correctly, e.g. it just strips \t \r \n.
+ bool is_invalid_url = false;
+ for (size_t j = 0; j < link.url.length(); ++j) {
+ // Control characters are not allowed.
+ // 0x7F is also a control character.
+ // 0x80 and above are not in US-ASCII.
+ if (link.url[j] < ' ' || link.url[j] >= '\x7F') {
+ is_invalid_url = true;
+ break;
+ }
+ }
+ if (is_invalid_url)
+ continue;
+
+ int rect_count = FPDFLink_CountRects(links, i);
+ for (int j = 0; j < rect_count; ++j) {
+ double left, top, right, bottom;
+ FPDFLink_GetRect(links, i, j, &left, &top, &right, &bottom);
+ link.rects.push_back(
+ PageToScreen(pp::Point(), 1.0, left, top, right, bottom, 0));
+ }
+ links_.push_back(link);
+ }
+ FPDFLink_CloseWebLinks(links);
+}
+
+pp::Rect PDFiumPage::PageToScreen(const pp::Point& offset,
+ double zoom,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int rotation) {
+ if (!available_)
+ return pp::Rect();
+
+ int new_left, new_top, new_right, new_bottom;
+ FPDF_PageToDevice(
+ page_,
+ static_cast<int>((rect_.x() - offset.x()) * zoom),
+ static_cast<int>((rect_.y() - offset.y()) * zoom),
+ static_cast<int>(ceil(rect_.width() * zoom)),
+ static_cast<int>(ceil(rect_.height() * zoom)),
+ rotation, left, top, &new_left, &new_top);
+ FPDF_PageToDevice(
+ page_,
+ static_cast<int>((rect_.x() - offset.x()) * zoom),
+ static_cast<int>((rect_.y() - offset.y()) * zoom),
+ static_cast<int>(ceil(rect_.width() * zoom)),
+ static_cast<int>(ceil(rect_.height() * zoom)),
+ rotation, right, bottom, &new_right, &new_bottom);
+
+ // If the PDF is rotated, the horizontal/vertical coordinates could be
+ // flipped. See
+ // http://www.netl.doe.gov/publications/proceedings/03/ubc/presentations/Goeckner-pres.pdf
+ if (new_right < new_left)
+ std::swap(new_right, new_left);
+ if (new_bottom < new_top)
+ std::swap(new_bottom, new_top);
+
+ return pp::Rect(
+ new_left, new_top, new_right - new_left + 1, new_bottom - new_top + 1);
+}
+
+PDFiumPage::Link::Link() {
+}
+
+PDFiumPage::Link::~Link() {
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/pdfium/pdfium_page.h b/xfa_test/pdf/pdfium/pdfium_page.h
new file mode 100644
index 0000000000..22ea142988
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_page.h
@@ -0,0 +1,136 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PDFIUM_PDFIUM_PAGE_H_
+#define PDF_PDFIUM_PDFIUM_PAGE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "ppapi/cpp/rect.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfdoc.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdfformfill.h"
+#include "third_party/pdfium/fpdfsdk/include/fpdftext.h"
+
+namespace base {
+class Value;
+}
+
+namespace chrome_pdf {
+
+class PDFiumEngine;
+
+// Wrapper around a page from the document.
+class PDFiumPage {
+ public:
+ PDFiumPage(PDFiumEngine* engine,
+ int i,
+ const pp::Rect& r,
+ bool available);
+ ~PDFiumPage();
+ // Unloads the PDFium data for this page from memory.
+ void Unload();
+ // Gets the FPDF_PAGE for this page, loading and parsing it if necessary.
+ FPDF_PAGE GetPage();
+ //Get the FPDF_PAGE for printing.
+ FPDF_PAGE GetPrintPage();
+ //Close the printing page.
+ void ClosePrintPage();
+
+ // Returns FPDF_TEXTPAGE for the page, loading and parsing it if necessary.
+ FPDF_TEXTPAGE GetTextPage();
+
+ // Returns a DictionaryValue version of the page.
+ base::Value* GetAccessibleContentAsValue(int rotation);
+
+ enum Area {
+ NONSELECTABLE_AREA,
+ TEXT_AREA,
+ WEBLINK_AREA, // Area is a hyperlink.
+ DOCLINK_AREA, // Area is a link to a different part of the same document.
+ };
+
+ struct LinkTarget {
+ // We are using std::string here which have a copy contructor.
+ // That prevents us from using union here.
+ std::string url; // Valid for WEBLINK_AREA only.
+ int page; // Valid for DOCLINK_AREA only.
+ };
+
+ // Given a point in the document that's in this page, returns its character
+ // index if it's near a character, and also the type of text.
+ // Target is optional. It will be filled in for WEBLINK_AREA or
+ // DOCLINK_AREA only.
+ Area GetCharIndex(const pp::Point& point, int rotation, int* char_index,
+ LinkTarget* target);
+
+ // Gets the character at the given index.
+ base::char16 GetCharAtIndex(int index);
+
+ // Gets the number of characters in the page.
+ int GetCharCount();
+
+ // Converts from page coordinates to screen coordinates.
+ pp::Rect PageToScreen(const pp::Point& offset,
+ double zoom,
+ double left,
+ double top,
+ double right,
+ double bottom,
+ int rotation);
+
+ int index() const { return index_; }
+ pp::Rect rect() const { return rect_; }
+ void set_rect(const pp::Rect& r) { rect_ = r; }
+ bool available() const { return available_; }
+ void set_available(bool available) { available_ = available; }
+ void set_calculated_links(bool calculated_links) {
+ calculated_links_ = calculated_links;
+ }
+
+ private:
+ // Returns a link index if the given character index is over a link, or -1
+ // otherwise.
+ int GetLink(int char_index, LinkTarget* target);
+ // Returns the link indices if the given rect intersects a link rect, or an
+ // empty vector otherwise.
+ std::vector<int> GetLinks(pp::Rect text_area,
+ std::vector<LinkTarget>* targets);
+ // Calculate the locations of any links on the page.
+ void CalculateLinks();
+ // Returns link type and target associated with a link. Returns
+ // NONSELECTABLE_AREA if link detection failed.
+ Area GetLinkTarget(FPDF_LINK link, LinkTarget* target);
+ // Returns target associated with a destination.
+ Area GetDestinationTarget(FPDF_DEST destination, LinkTarget* target);
+ // Returns the text in the supplied box as a Value Node
+ base::Value* GetTextBoxAsValue(double page_height, double left, double top,
+ double right, double bottom, int rotation);
+ // Helper functions for JSON generation
+ base::Value* CreateTextNode(std::string text);
+ base::Value* CreateURLNode(std::string text, std::string url);
+
+ struct Link {
+ Link();
+ ~Link();
+
+ std::string url;
+ // Bounding rectangles of characters.
+ std::vector<pp::Rect> rects;
+ };
+
+ PDFiumEngine* engine_;
+ FPDF_PAGE page_;
+ FPDF_TEXTPAGE text_page_;
+ int index_;
+ pp::Rect rect_;
+ bool calculated_links_;
+ std::vector<Link> links_;
+ bool available_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDFIUM_PDFIUM_PAGE_H_
diff --git a/xfa_test/pdf/pdfium/pdfium_range.cc b/xfa_test/pdf/pdfium/pdfium_range.cc
new file mode 100644
index 0000000000..c77d5906dd
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_range.cc
@@ -0,0 +1,79 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/pdfium/pdfium_range.h"
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+
+namespace chrome_pdf {
+
+PDFiumRange::PDFiumRange(PDFiumPage* page, int char_index, int char_count)
+ : page_(page),
+ char_index_(char_index),
+ char_count_(char_count),
+ cached_screen_rects_zoom_(0) {
+}
+
+PDFiumRange::~PDFiumRange() {
+}
+
+void PDFiumRange::SetCharCount(int char_count) {
+ char_count_ = char_count;
+
+ cached_screen_rects_offset_ = pp::Point();
+ cached_screen_rects_zoom_ = 0;
+}
+
+std::vector<pp::Rect> PDFiumRange::GetScreenRects(const pp::Point& offset,
+ double zoom,
+ int rotation) {
+ if (offset == cached_screen_rects_offset_ &&
+ zoom == cached_screen_rects_zoom_) {
+ return cached_screen_rects_;
+ }
+
+ cached_screen_rects_.clear();
+ cached_screen_rects_offset_ = offset;
+ cached_screen_rects_zoom_ = zoom;
+
+ int char_index = char_index_;
+ int char_count = char_count_;
+ if (char_count < 0) {
+ char_count *= -1;
+ char_index -= char_count - 1;
+ }
+
+ int count = FPDFText_CountRects(page_->GetTextPage(), char_index, char_count);
+ for (int i = 0; i < count; ++i) {
+ double left, top, right, bottom;
+ FPDFText_GetRect(page_->GetTextPage(), i, &left, &top, &right, &bottom);
+ cached_screen_rects_.push_back(
+ page_->PageToScreen(offset, zoom, left, top, right, bottom, rotation));
+ }
+
+ return cached_screen_rects_;
+}
+
+base::string16 PDFiumRange::GetText() {
+ int index = char_index_;
+ int count = char_count_;
+ if (!count)
+ return base::string16();
+ if (count < 0) {
+ count *= -1;
+ index -= count - 1;
+ }
+
+ base::string16 rv;
+ unsigned short* data =
+ reinterpret_cast<unsigned short*>(WriteInto(&rv, count + 1));
+ if (data) {
+ int written = FPDFText_GetText(page_->GetTextPage(), index, count, data);
+ rv.reserve(written);
+ }
+ return rv;
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/pdfium/pdfium_range.h b/xfa_test/pdf/pdfium/pdfium_range.h
new file mode 100644
index 0000000000..ed8daf65bb
--- /dev/null
+++ b/xfa_test/pdf/pdfium/pdfium_range.h
@@ -0,0 +1,54 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PDFIUM_PDFIUM_RANGE_H_
+#define PDF_PDFIUM_PDFIUM_RANGE_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string16.h"
+#include "pdf/pdfium/pdfium_page.h"
+#include "ppapi/cpp/rect.h"
+
+namespace chrome_pdf {
+
+// Describes location of a string of characters.
+class PDFiumRange {
+ public:
+ PDFiumRange(PDFiumPage* page, int char_index, int char_count);
+ ~PDFiumRange();
+
+ // Update how many characters are in the selection. Could be negative if
+ // backwards.
+ void SetCharCount(int char_count);
+
+ int page_index() const { return page_->index(); }
+ int char_index() const { return char_index_; }
+ int char_count() const { return char_count_; }
+
+ // Gets bounding rectangles of range in screen coordinates.
+ std::vector<pp::Rect> GetScreenRects(const pp::Point& offset,
+ double zoom,
+ int rotation);
+
+ // Gets the string of characters in this range.
+ base::string16 GetText();
+
+ private:
+ PDFiumPage* page_;
+ // Index of first character.
+ int char_index_;
+ // How many characters are part of this range (negative if backwards).
+ int char_count_;
+
+ // Cache of ScreenRect, and the associated variables used when caching it.
+ std::vector<pp::Rect> cached_screen_rects_;
+ pp::Point cached_screen_rects_offset_;
+ double cached_screen_rects_zoom_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PDFIUM_PDFIUM_RANGE_H_
diff --git a/xfa_test/pdf/preview_mode_client.cc b/xfa_test/pdf/preview_mode_client.cc
new file mode 100644
index 0000000000..8b9919b46e
--- /dev/null
+++ b/xfa_test/pdf/preview_mode_client.cc
@@ -0,0 +1,162 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/preview_mode_client.h"
+
+#include "base/logging.h"
+#include "pdf/instance.h"
+
+namespace chrome_pdf {
+
+PreviewModeClient::PreviewModeClient(Client* client)
+ : client_(client) {
+}
+
+void PreviewModeClient::DocumentSizeUpdated(const pp::Size& size) {
+}
+
+void PreviewModeClient::Invalidate(const pp::Rect& rect) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::Scroll(const pp::Point& point) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::ScrollToX(int position) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::ScrollToY(int position) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::ScrollToPage(int page) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::NavigateTo(const std::string& url,
+ bool open_in_new_tab) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::UpdateCursor(PP_CursorType_Dev cursor) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::UpdateTickMarks(
+ const std::vector<pp::Rect>& tickmarks) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::NotifyNumberOfFindResultsChanged(int total,
+ bool final_result) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::NotifySelectedFindResultChanged(
+ int current_find_index) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::GetDocumentPassword(
+ pp::CompletionCallbackWithOutput<pp::Var> callback) {
+ callback.Run(PP_ERROR_FAILED);
+}
+
+void PreviewModeClient::Alert(const std::string& message) {
+ NOTREACHED();
+}
+
+bool PreviewModeClient::Confirm(const std::string& message) {
+ NOTREACHED();
+ return false;
+}
+
+std::string PreviewModeClient::Prompt(const std::string& question,
+ const std::string& default_answer) {
+ NOTREACHED();
+ return std::string();
+}
+
+std::string PreviewModeClient::GetURL() {
+ NOTREACHED();
+ return std::string();
+}
+
+void PreviewModeClient::Email(const std::string& to,
+ const std::string& cc,
+ const std::string& bcc,
+ const std::string& subject,
+ const std::string& body) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::Print() {
+ NOTREACHED();
+}
+
+void PreviewModeClient::SubmitForm(const std::string& url,
+ const void* data,
+ int length) {
+ NOTREACHED();
+}
+
+std::string PreviewModeClient::ShowFileSelectionDialog() {
+ NOTREACHED();
+ return std::string();
+}
+
+pp::URLLoader PreviewModeClient::CreateURLLoader() {
+ NOTREACHED();
+ return pp::URLLoader();
+}
+
+void PreviewModeClient::ScheduleCallback(int id, int delay_in_ms) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::SearchString(const base::char16* string,
+ const base::char16* term,
+ bool case_sensitive,
+ std::vector<SearchStringResult>* results) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::DocumentPaintOccurred() {
+ NOTREACHED();
+}
+
+void PreviewModeClient::DocumentLoadComplete(int page_count) {
+ client_->PreviewDocumentLoadComplete();
+}
+
+void PreviewModeClient::DocumentLoadFailed() {
+ client_->PreviewDocumentLoadFailed();
+}
+
+pp::Instance* PreviewModeClient::GetPluginInstance() {
+ NOTREACHED();
+ return NULL;
+}
+
+void PreviewModeClient::DocumentHasUnsupportedFeature(
+ const std::string& feature) {
+ NOTREACHED();
+}
+
+void PreviewModeClient::DocumentLoadProgress(uint32 available,
+ uint32 doc_size) {
+}
+
+void PreviewModeClient::FormTextFieldFocusChange(bool in_focus) {
+ NOTREACHED();
+}
+
+bool PreviewModeClient::IsPrintPreview() {
+ NOTREACHED();
+ return false;
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/preview_mode_client.h b/xfa_test/pdf/preview_mode_client.h
new file mode 100644
index 0000000000..0e766f949f
--- /dev/null
+++ b/xfa_test/pdf/preview_mode_client.h
@@ -0,0 +1,77 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PREVIEW_MODE_CLIENT_H_
+#define PDF_PREVIEW_MODE_CLIENT_H_
+
+#include <string>
+#include <vector>
+
+#include "pdf/pdf_engine.h"
+
+namespace chrome_pdf {
+
+// The interface that's provided to the print preview rendering engine.
+class PreviewModeClient : public PDFEngine::Client {
+ public:
+ class Client {
+ public:
+ virtual void PreviewDocumentLoadFailed() = 0;
+ virtual void PreviewDocumentLoadComplete() = 0;
+ };
+ explicit PreviewModeClient(Client* client);
+ virtual ~PreviewModeClient() {}
+
+ // PDFEngine::Client implementation.
+ virtual void DocumentSizeUpdated(const pp::Size& size);
+ virtual void Invalidate(const pp::Rect& rect);
+ virtual void Scroll(const pp::Point& point);
+ virtual void ScrollToX(int position);
+ virtual void ScrollToY(int position);
+ virtual void ScrollToPage(int page);
+ virtual void NavigateTo(const std::string& url, bool open_in_new_tab);
+ virtual void UpdateCursor(PP_CursorType_Dev cursor);
+ virtual void UpdateTickMarks(const std::vector<pp::Rect>& tickmarks);
+ virtual void NotifyNumberOfFindResultsChanged(int total,
+ bool final_result);
+ virtual void NotifySelectedFindResultChanged(int current_find_index);
+ virtual void GetDocumentPassword(
+ pp::CompletionCallbackWithOutput<pp::Var> callback);
+ virtual void Alert(const std::string& message);
+ virtual bool Confirm(const std::string& message);
+ virtual std::string Prompt(const std::string& question,
+ const std::string& default_answer);
+ virtual std::string GetURL();
+ virtual void Email(const std::string& to,
+ const std::string& cc,
+ const std::string& bcc,
+ const std::string& subject,
+ const std::string& body);
+ virtual void Print();
+ virtual void SubmitForm(const std::string& url,
+ const void* data,
+ int length);
+ virtual std::string ShowFileSelectionDialog();
+ virtual pp::URLLoader CreateURLLoader();
+ virtual void ScheduleCallback(int id, int delay_in_ms);
+ virtual void SearchString(const base::char16* string,
+ const base::char16* term,
+ bool case_sensitive,
+ std::vector<SearchStringResult>* results);
+ virtual void DocumentPaintOccurred();
+ virtual void DocumentLoadComplete(int page_count);
+ virtual void DocumentLoadFailed();
+ virtual pp::Instance* GetPluginInstance();
+ virtual void DocumentHasUnsupportedFeature(const std::string& feature);
+ virtual void DocumentLoadProgress(uint32 available, uint32 doc_size);
+ virtual void FormTextFieldFocusChange(bool in_focus);
+ virtual bool IsPrintPreview();
+
+ private:
+ Client* client_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PREVIEW_MODE_CLIENT_H_
diff --git a/xfa_test/pdf/progress_control.cc b/xfa_test/pdf/progress_control.cc
new file mode 100644
index 0000000000..2c2bca4e42
--- /dev/null
+++ b/xfa_test/pdf/progress_control.cc
@@ -0,0 +1,283 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/progress_control.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "pdf/draw_utils.h"
+#include "pdf/resource_consts.h"
+#include "ppapi/cpp/dev/font_dev.h"
+
+namespace chrome_pdf {
+
+const double ProgressControl::kCompleted = 100.0;
+
+// There is a bug outputting text with alpha 0xFF (opaque) to an intermediate
+// image. It outputs alpha channgel of the text pixels to 0xFF (transparent).
+// And it breaks next alpha blending.
+// For now, let's use alpha 0xFE to work around this bug.
+// TODO(gene): investigate this bug.
+const uint32 kProgressTextColor = 0xFEDDE6FC;
+const uint32 kProgressTextSize = 16;
+const uint32 kImageTextSpacing = 8;
+const uint32 kTopPadding = 8;
+const uint32 kBottomPadding = 12;
+const uint32 kLeftPadding = 10;
+const uint32 kRightPadding = 10;
+
+int ScaleInt(int val, float scale) {
+ return static_cast<int>(val * scale);
+}
+
+ProgressControl::ProgressControl()
+ : progress_(0.0),
+ device_scale_(1.0) {
+}
+
+ProgressControl::~ProgressControl() {
+}
+
+bool ProgressControl::CreateProgressControl(
+ uint32 id,
+ bool visible,
+ Control::Owner* delegate,
+ double progress,
+ float device_scale,
+ const std::vector<pp::ImageData>& images,
+ const pp::ImageData& background,
+ const std::string& text) {
+ progress_ = progress;
+ text_ = text;
+ bool res = Control::Create(id, pp::Rect(), visible, delegate);
+ if (res)
+ Reconfigure(background, images, device_scale);
+ return res;
+}
+
+void ProgressControl::Reconfigure(const pp::ImageData& background,
+ const std::vector<pp::ImageData>& images,
+ float device_scale) {
+ DCHECK(images.size() != 0);
+ images_ = images;
+ background_ = background;
+ device_scale_ = device_scale;
+ pp::Size ctrl_size;
+ CalculateLayout(owner()->GetInstance(), images_, background_, text_,
+ device_scale_, &ctrl_size, &image_rc_, &text_rc_);
+ pp::Rect rc(pp::Point(), ctrl_size);
+ Control::SetRect(rc, false);
+ PrepareBackground();
+}
+
+// static
+void ProgressControl::CalculateLayout(pp::Instance* instance,
+ const std::vector<pp::ImageData>& images,
+ const pp::ImageData& background,
+ const std::string& text,
+ float device_scale,
+ pp::Size* ctrl_size,
+ pp::Rect* image_rc,
+ pp::Rect* text_rc) {
+ DCHECK(images.size() != 0);
+ int image_width = 0;
+ int image_height = 0;
+ for (size_t i = 0; i < images.size(); i++) {
+ image_width = std::max(image_width, images[i].size().width());
+ image_height = std::max(image_height, images[i].size().height());
+ }
+
+ pp::FontDescription_Dev description;
+ description.set_family(PP_FONTFAMILY_SANSSERIF);
+ description.set_size(ScaleInt(kProgressTextSize, device_scale));
+ description.set_weight(PP_FONTWEIGHT_BOLD);
+ pp::Font_Dev font(instance, description);
+ int text_length = font.MeasureSimpleText(text);
+
+ pp::FontDescription_Dev desc;
+ PP_FontMetrics_Dev metrics;
+ font.Describe(&desc, &metrics);
+ int text_height = metrics.height;
+
+ *ctrl_size = pp::Size(
+ image_width + text_length +
+ ScaleInt(kImageTextSpacing + kLeftPadding + kRightPadding, device_scale),
+ std::max(image_height, text_height) +
+ ScaleInt(kTopPadding + kBottomPadding, device_scale));
+
+ int offset_x = 0;
+ int offset_y = 0;
+ if (ctrl_size->width() < background.size().width()) {
+ offset_x += (background.size().width() - ctrl_size->width()) / 2;
+ ctrl_size->set_width(background.size().width());
+ }
+ if (ctrl_size->height() < background.size().height()) {
+ offset_y += (background.size().height() - ctrl_size->height()) / 2;
+ ctrl_size->set_height(background.size().height());
+ }
+
+ *image_rc = pp::Rect(ScaleInt(kLeftPadding, device_scale) + offset_x,
+ ScaleInt(kTopPadding, device_scale) + offset_y,
+ image_width,
+ image_height);
+
+ *text_rc = pp::Rect(
+ ctrl_size->width() - text_length -
+ ScaleInt(kRightPadding, device_scale) - offset_x,
+ (ctrl_size->height() - text_height) / 2,
+ text_length,
+ text_height);
+}
+
+size_t ProgressControl::GetImageIngex() const {
+ return static_cast<size_t>((progress_ / 100.0) * images_.size());
+}
+
+void ProgressControl::Paint(pp::ImageData* image_data, const pp::Rect& rc) {
+ if (!visible())
+ return;
+
+ pp::Rect draw_rc = rect().Intersect(rc);
+ if (draw_rc.IsEmpty())
+ return;
+
+ pp::ImageData buffer(owner()->GetInstance(), ctrl_background_.format(),
+ ctrl_background_.size(), false);
+ CopyImage(ctrl_background_, pp::Rect(ctrl_background_.size()),
+ &buffer, pp::Rect(ctrl_background_.size()), false);
+
+ size_t index = GetImageIngex();
+ if (index >= images_.size())
+ index = images_.size() - 1;
+
+ AlphaBlend(images_[index],
+ pp::Rect(images_[index].size()),
+ &buffer,
+ image_rc_.point(),
+ kOpaqueAlpha);
+
+ pp::Rect image_draw_rc(draw_rc);
+ image_draw_rc.Offset(-rect().x(), -rect().y());
+ AlphaBlend(buffer,
+ image_draw_rc,
+ image_data,
+ draw_rc.point(),
+ transparency());
+}
+
+void ProgressControl::SetProgress(double progress) {
+ size_t old_index = GetImageIngex();
+ progress_ = progress;
+ size_t new_index = GetImageIngex();
+ if (progress_ >= kCompleted) {
+ progress_ = kCompleted;
+ owner()->OnEvent(id(), EVENT_ID_PROGRESS_COMPLETED, NULL);
+ }
+ if (visible() && old_index != new_index)
+ owner()->Invalidate(id(), rect());
+}
+
+void ProgressControl::PrepareBackground() {
+ AdjustBackground();
+
+ pp::FontDescription_Dev description;
+ description.set_family(PP_FONTFAMILY_SANSSERIF);
+ description.set_size(ScaleInt(kProgressTextSize, device_scale_));
+ description.set_weight(PP_FONTWEIGHT_BOLD);
+ pp::Font_Dev font(owner()->GetInstance(), description);
+
+ pp::FontDescription_Dev desc;
+ PP_FontMetrics_Dev metrics;
+ font.Describe(&desc, &metrics);
+
+ pp::Point text_origin = pp::Point(text_rc_.x(),
+ (text_rc_.y() + text_rc_.bottom() + metrics.x_height) / 2);
+ font.DrawTextAt(&ctrl_background_, pp::TextRun_Dev(text_), text_origin,
+ kProgressTextColor, pp::Rect(ctrl_background_.size()), false);
+}
+
+void ProgressControl::AdjustBackground() {
+ ctrl_background_ = pp::ImageData(owner()->GetInstance(),
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ rect().size(),
+ false);
+
+ if (rect().size() == background_.size()) {
+ CopyImage(background_, pp::Rect(background_.size()),
+ &ctrl_background_, pp::Rect(ctrl_background_.size()), false);
+ return;
+ }
+
+ // We need to stretch background to new dimentions. To do so, we split
+ // background into 9 different parts. We copy corner rects (1,3,7,9) as is,
+ // stretch rectangles between corners (2,4,6,8) in 1 dimention, and
+ // stretch center rect (5) in 2 dimentions.
+ // |---|---|---|
+ // | 1 | 2 | 3 |
+ // |---|---|---|
+ // | 4 | 5 | 6 |
+ // |---|---|---|
+ // | 7 | 8 | 9 |
+ // |---|---|---|
+ int slice_x = background_.size().width() / 3;
+ int slice_y = background_.size().height() / 3;
+
+ // Copy rect 1
+ pp::Rect src_rc(0, 0, slice_x, slice_y);
+ pp::Rect dest_rc(0, 0, slice_x, slice_y);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, false);
+
+ // Copy rect 3
+ src_rc.set_x(background_.size().width() - slice_x);
+ dest_rc.set_x(ctrl_background_.size().width() - slice_x);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, false);
+
+ // Copy rect 9
+ src_rc.set_y(background_.size().height() - slice_y);
+ dest_rc.set_y(ctrl_background_.size().height() - slice_y);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, false);
+
+ // Copy rect 7
+ src_rc.set_x(0);
+ dest_rc.set_x(0);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, false);
+
+ // Stretch rect 2
+ src_rc = pp::Rect(
+ slice_x, 0, background_.size().width() - 2 * slice_x, slice_y);
+ dest_rc = pp::Rect(
+ slice_x, 0, ctrl_background_.size().width() - 2 * slice_x, slice_y);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, true);
+
+ // Copy rect 8
+ src_rc.set_y(background_.size().height() - slice_y);
+ dest_rc.set_y(ctrl_background_.size().height() - slice_y);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, true);
+
+ // Stretch rect 4
+ src_rc = pp::Rect(
+ 0, slice_y, slice_x, background_.size().height() - 2 * slice_y);
+ dest_rc = pp::Rect(
+ 0, slice_y, slice_x, ctrl_background_.size().height() - 2 * slice_y);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, true);
+
+ // Copy rect 6
+ src_rc.set_x(background_.size().width() - slice_x);
+ dest_rc.set_x(ctrl_background_.size().width() - slice_x);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, true);
+
+ // Stretch rect 5
+ src_rc = pp::Rect(slice_x,
+ slice_y,
+ background_.size().width() - 2 * slice_x,
+ background_.size().height() - 2 * slice_y);
+ dest_rc = pp::Rect(slice_x,
+ slice_y,
+ ctrl_background_.size().width() - 2 * slice_x,
+ ctrl_background_.size().height() - 2 * slice_y);
+ CopyImage(background_, src_rc, &ctrl_background_, dest_rc, true);
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/progress_control.h b/xfa_test/pdf/progress_control.h
new file mode 100644
index 0000000000..96d5da1ce9
--- /dev/null
+++ b/xfa_test/pdf/progress_control.h
@@ -0,0 +1,72 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_PROGRESS_CONTROL_H_
+#define PDF_PROGRESS_CONTROL_H_
+
+#include <string>
+#include <vector>
+
+#include "pdf/control.h"
+#include "pdf/fading_control.h"
+#include "ppapi/cpp/image_data.h"
+
+namespace chrome_pdf {
+
+class ProgressControl : public FadingControl {
+ public:
+ static const double kCompleted;
+
+ enum ProgressEventIds {
+ EVENT_ID_PROGRESS_COMPLETED,
+ };
+
+ ProgressControl();
+ virtual ~ProgressControl();
+ virtual bool CreateProgressControl(uint32 id,
+ bool visible,
+ Control::Owner* delegate,
+ double progress,
+ float device_scale,
+ const std::vector<pp::ImageData>& images,
+ const pp::ImageData& background,
+ const std::string& text);
+ void Reconfigure(const pp::ImageData& background,
+ const std::vector<pp::ImageData>& images,
+ float device_scale);
+
+ static void CalculateLayout(pp::Instance* instance,
+ const std::vector<pp::ImageData>& images,
+ const pp::ImageData& background,
+ const std::string& text,
+ float device_scale,
+ pp::Size* ctrl_size,
+ pp::Rect* image_rc,
+ pp::Rect* text_rc);
+
+ // Control interface.
+ virtual void Paint(pp::ImageData* image_data, const pp::Rect& rc);
+
+ // ProgressControl interface
+ // Set progress indicator in percents from 0% to 100%.
+ virtual void SetProgress(double progress);
+
+ private:
+ void PrepareBackground();
+ void AdjustBackground();
+ size_t GetImageIngex() const;
+
+ double progress_;
+ float device_scale_;
+ std::vector<pp::ImageData> images_;
+ pp::ImageData background_;
+ pp::ImageData ctrl_background_;
+ std::string text_;
+ pp::Rect image_rc_;
+ pp::Rect text_rc_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_PROGRESS_CONTROL_H_
diff --git a/xfa_test/pdf/resource.h b/xfa_test/pdf/resource.h
new file mode 100644
index 0000000000..9fdbea758b
--- /dev/null
+++ b/xfa_test/pdf/resource.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by pdf.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/xfa_test/pdf/resource_consts.h b/xfa_test/pdf/resource_consts.h
new file mode 100644
index 0000000000..f12efd61be
--- /dev/null
+++ b/xfa_test/pdf/resource_consts.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_RESOURCE_RESOURCE_CONSTS_H_
+#define PDF_RESOURCE_RESOURCE_CONSTS_H_
+
+#include "base/basictypes.h"
+
+namespace chrome_pdf {
+
+const int kDragTimerMs = 50;
+const double kMinZoom = 0.1;
+const double kMaxZoom = 10.0;
+const double kZoomStep = 1.2;
+
+const uint32 kFadingTimeoutMs = 50;
+
+const uint32 kToolbarId = 10;
+const uint32 kThumbnailsId = 11;
+const uint32 kProgressBarId = 12;
+const uint32 kPageIndicatorId = 13;
+const uint32 kFitToPageButtonId = 100;
+const uint32 kFitToWidthButtonId = 101;
+const uint32 kZoomOutButtonId = 102;
+const uint32 kZoomInButtonId = 103;
+const uint32 kSaveButtonId = 104;
+const uint32 kPrintButtonId = 105;
+
+const uint32 kAutoScrollId = 200;
+
+// fading_rect.left = button_rect.left - kToolbarFadingOffsetLeft
+const int32 kToolbarFadingOffsetLeft = 40;
+// fading_rect.top = button_rect.top - kToolbarFadingOffsetTop
+const int32 kToolbarFadingOffsetTop = 40;
+// fading_rect.right = button_rect.right + kToolbarFadingOffsetRight
+const int32 kToolbarFadingOffsetRight = 10;
+// fading_rect.bottom = button_rect.bottom + kToolbarFadingOffsetBottom
+const int32 kToolbarFadingOffsetBottom = 8;
+
+const int32 kProgressOffsetLeft = 8;
+const int32 kProgressOffsetBottom = 8;
+
+// Width of the thumbnails control.
+const int32 kThumbnailsWidth = 196;
+
+} // namespace chrome_pdf
+
+#endif // PDF_RESOURCE_RESOURCE_CONSTS_H_
diff --git a/xfa_test/pdf/thumbnail_control.cc b/xfa_test/pdf/thumbnail_control.cc
new file mode 100644
index 0000000000..9a779b2912
--- /dev/null
+++ b/xfa_test/pdf/thumbnail_control.cc
@@ -0,0 +1,301 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "pdf/thumbnail_control.h"
+
+#include <algorithm>
+
+#include "base/logging.h"
+#include "base/strings/string_util.h"
+#include "pdf/draw_utils.h"
+#include "pdf/number_image_generator.h"
+
+namespace chrome_pdf {
+
+const int kLeftBorderSize = 52;
+const int kBorderSize = 12;
+const int kHighlightBorderSize = 2;
+
+const uint32 kLeftColor = 0x003F537B;
+const uint32 kRightColor = 0x990D1626;
+
+const uint32 kTopHighlightColor = 0xFF426DC9;
+const uint32 kBottomHighlightColor = 0xFF6391DE;
+const uint32 kThumbnailBackgroundColor = 0xFF000000;
+
+const uint32 kSlidingTimeoutMs = 50;
+const int32 kSlidingShift = 50;
+
+const double kNonSelectedThumbnailAlpha = 0.91;
+
+ThumbnailControl::ThumbnailControl()
+ : engine_(NULL), sliding_width_(0), sliding_shift_(kSlidingShift),
+ sliding_timeout_(kSlidingTimeoutMs), sliding_timer_id_(0) {
+}
+
+ThumbnailControl::~ThumbnailControl() {
+ ClearCache();
+}
+
+bool ThumbnailControl::CreateThumbnailControl(
+ uint32 id, const pp::Rect& rc,
+ bool visible, Owner* owner, PDFEngine* engine,
+ NumberImageGenerator* number_image_generator) {
+ engine_ = engine;
+ number_image_generator_ = number_image_generator;
+ sliding_width_ = rc.width();
+
+ return Control::Create(id, rc, visible, owner);
+}
+
+void ThumbnailControl::SetPosition(int position, int total, bool invalidate) {
+ visible_rect_ = pp::Rect();
+ visible_pages_.clear();
+
+ if (rect().width() < kLeftBorderSize + kBorderSize) {
+ return; // control is too narrow to show thumbnails.
+ }
+
+ int num_pages = engine_->GetNumberOfPages();
+
+ int max_doc_width = 0, total_doc_height = 0;
+ std::vector<pp::Rect> page_sizes(num_pages);
+ for (int i = 0; i < num_pages; ++i) {
+ page_sizes[i] = engine_->GetPageRect(i);
+ max_doc_width = std::max(max_doc_width, page_sizes[i].width());
+ total_doc_height += page_sizes[i].height();
+ }
+
+ if (!max_doc_width)
+ return;
+
+ int max_thumbnail_width = rect().width() - kLeftBorderSize - kBorderSize;
+ double thumbnail_ratio =
+ max_thumbnail_width / static_cast<double>(max_doc_width);
+
+ int total_thumbnail_height = 0;
+ for (int i = 0; i < num_pages; ++i) {
+ total_thumbnail_height += kBorderSize;
+ int thumbnail_width =
+ static_cast<int>(page_sizes[i].width() * thumbnail_ratio);
+ int thumbnail_height =
+ static_cast<int>(page_sizes[i].height() * thumbnail_ratio);
+ int x = (max_thumbnail_width - thumbnail_width) / 2;
+ page_sizes[i] =
+ pp::Rect(x, total_thumbnail_height, thumbnail_width, thumbnail_height);
+ total_thumbnail_height += thumbnail_height;
+ }
+ total_thumbnail_height += kBorderSize;
+
+ int visible_y = 0;
+ if (total > 0) {
+ double range = total_thumbnail_height - rect().height();
+ if (range < 0)
+ range = 0;
+ visible_y = static_cast<int>(range * position / total);
+ }
+ visible_rect_ = pp::Rect(0, visible_y, max_thumbnail_width, rect().height());
+
+ for (int i = 0; i < num_pages; ++i) {
+ if (page_sizes[i].Intersects(visible_rect_)) {
+ PageInfo page_info;
+ page_info.index = i;
+ page_info.rect = page_sizes[i];
+ page_info.rect.Offset(kLeftBorderSize, -visible_rect_.y());
+ visible_pages_.push_back(page_info);
+ }
+ }
+
+ if (invalidate)
+ owner()->Invalidate(id(), rect());
+}
+
+void ThumbnailControl::Show(bool visible, bool invalidate) {
+ if (!visible || invalidate)
+ ClearCache();
+ sliding_width_ = rect().width();
+ Control::Show(visible, invalidate);
+}
+
+void ThumbnailControl::SlideIn() {
+ if (visible())
+ return;
+
+ Show(true, false);
+ sliding_width_ = 0;
+ sliding_shift_ = kSlidingShift;
+
+ sliding_timer_id_ = owner()->ScheduleTimer(id(), sliding_timeout_);
+ owner()->Invalidate(id(), rect());
+}
+
+void ThumbnailControl::SlideOut() {
+ if (!visible())
+ return;
+ sliding_shift_ = -kSlidingShift;
+ sliding_timer_id_ = owner()->ScheduleTimer(id(), sliding_timeout_);
+}
+
+void ThumbnailControl::Paint(pp::ImageData* image_data, const pp::Rect& rc) {
+ if (!visible())
+ return;
+
+ pp::Rect control_rc(rect());
+ control_rc.Offset(control_rc.width() - sliding_width_, 0);
+ control_rc.set_width(sliding_width_);
+
+ pp::Rect draw_rc = rc.Intersect(control_rc);
+ if (draw_rc.IsEmpty())
+ return;
+
+ pp::Rect gradient_rc(control_rc.x(), draw_rc.y(),
+ control_rc.width(), draw_rc.height());
+ GradientFill(owner()->GetInstance(),
+ image_data,
+ draw_rc,
+ gradient_rc,
+ kLeftColor,
+ kRightColor,
+ true,
+ transparency());
+
+ int selected_page = engine_->GetMostVisiblePage();
+ for (size_t i = 0; i < visible_pages_.size(); ++i) {
+ pp::Rect page_rc = visible_pages_[i].rect;
+ page_rc.Offset(control_rc.point());
+
+ if (visible_pages_[i].index == selected_page) {
+ pp::Rect highlight_rc = page_rc;
+ highlight_rc.Inset(-kHighlightBorderSize, -kHighlightBorderSize);
+ GradientFill(owner()->GetInstance(),
+ image_data,
+ draw_rc,
+ highlight_rc,
+ kTopHighlightColor,
+ kBottomHighlightColor,
+ false,
+ transparency());
+ }
+
+ pp::Rect draw_page_rc = page_rc.Intersect(draw_rc);
+ if (draw_page_rc.IsEmpty())
+ continue;
+
+ // First search page image in the cache.
+ pp::ImageData* thumbnail = NULL;
+ std::map<int, pp::ImageData*>::iterator it =
+ image_cache_.find(visible_pages_[i].index);
+ if (it != image_cache_.end()) {
+ if (it->second->size() == page_rc.size())
+ thumbnail = image_cache_[visible_pages_[i].index];
+ else
+ image_cache_.erase(it);
+ }
+
+ // If page is not found in the cache, create new one.
+ if (thumbnail == NULL) {
+ thumbnail = new pp::ImageData(owner()->GetInstance(),
+ PP_IMAGEDATAFORMAT_BGRA_PREMUL,
+ page_rc.size(),
+ false);
+ engine_->PaintThumbnail(thumbnail, visible_pages_[i].index);
+
+ pp::ImageData page_number;
+ number_image_generator_->GenerateImage(
+ visible_pages_[i].index + 1, &page_number);
+ pp::Point origin(
+ (thumbnail->size().width() - page_number.size().width()) / 2,
+ (thumbnail->size().height() - page_number.size().height()) / 2);
+
+ if (origin.x() > 0 && origin.y() > 0) {
+ AlphaBlend(page_number, pp::Rect(pp::Point(), page_number.size()),
+ thumbnail, origin, kOpaqueAlpha);
+ }
+
+ image_cache_[visible_pages_[i].index] = thumbnail;
+ }
+
+ uint8 alpha = transparency();
+ if (visible_pages_[i].index != selected_page)
+ alpha = static_cast<uint8>(alpha * kNonSelectedThumbnailAlpha);
+ FillRect(image_data, draw_page_rc, kThumbnailBackgroundColor);
+ draw_page_rc.Offset(-page_rc.x(), -page_rc.y());
+ AlphaBlend(*thumbnail, draw_page_rc, image_data,
+ draw_page_rc.point() + page_rc.point(), alpha);
+ }
+}
+
+bool ThumbnailControl::HandleEvent(const pp::InputEvent& event) {
+ if (!visible())
+ return false;
+
+ pp::MouseInputEvent mouse_event(event);
+ if (mouse_event.is_null())
+ return false;
+ pp::Point pt = mouse_event.GetPosition();
+ if (!rect().Contains(pt))
+ return false;
+
+ int over_page = -1;
+ for (size_t i = 0; i < visible_pages_.size(); ++i) {
+ pp::Rect page_rc = visible_pages_[i].rect;
+ page_rc.Offset(rect().point());
+ if (page_rc.Contains(pt)) {
+ over_page = i;
+ break;
+ }
+ }
+
+ bool handled = false;
+ switch (event.GetType()) {
+ case PP_INPUTEVENT_TYPE_MOUSEMOVE:
+ owner()->SetCursor(id(),
+ over_page == -1 ? PP_CURSORTYPE_POINTER : PP_CURSORTYPE_HAND);
+ break;
+ case PP_INPUTEVENT_TYPE_MOUSEDOWN:
+ if (over_page != -1) {
+ owner()->Invalidate(id(), rect());
+ owner()->OnEvent(id(), EVENT_ID_THUMBNAIL_SELECTED,
+ &visible_pages_[over_page].index);
+ }
+ handled = true;
+ break;
+ default:
+ break;
+ }
+
+ return handled;
+}
+
+void ThumbnailControl::OnTimerFired(uint32 timer_id) {
+ if (timer_id == sliding_timer_id_) {
+ sliding_width_ += sliding_shift_;
+ if (sliding_width_ <= 0) {
+ // We completely slided out. Make control invisible now.
+ Show(false, false);
+ } else if (sliding_width_ >= rect().width()) {
+ // We completely slided in. Make sliding width to full control width.
+ sliding_width_ = rect().width();
+ } else {
+ // We have not completed sliding yet. Keep sliding.
+ sliding_timer_id_ = owner()->ScheduleTimer(id(), sliding_timeout_);
+ }
+ owner()->Invalidate(id(), rect());
+ }
+}
+
+void ThumbnailControl::ResetEngine(PDFEngine* engine) {
+ engine_ = engine;
+ ClearCache();
+}
+
+void ThumbnailControl::ClearCache() {
+ std::map<int, pp::ImageData*>::iterator it;
+ for (it = image_cache_.begin(); it != image_cache_.end(); ++it) {
+ delete it->second;
+ }
+ image_cache_.clear();
+}
+
+} // namespace chrome_pdf
diff --git a/xfa_test/pdf/thumbnail_control.h b/xfa_test/pdf/thumbnail_control.h
new file mode 100644
index 0000000000..d10a32896d
--- /dev/null
+++ b/xfa_test/pdf/thumbnail_control.h
@@ -0,0 +1,67 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PDF_THUMBNAIL_CONTROL_H_
+#define PDF_THUMBNAIL_CONTROL_H_
+
+#include <map>
+#include <vector>
+
+#include "pdf/control.h"
+#include "pdf/pdf_engine.h"
+#include "ppapi/cpp/input_event.h"
+
+namespace chrome_pdf {
+
+class NumberImageGenerator;
+
+class ThumbnailControl : public Control {
+ public:
+ enum ThumbnailEventIds {
+ EVENT_ID_THUMBNAIL_SELECTED = 100,
+ };
+
+ explicit ThumbnailControl();
+ virtual ~ThumbnailControl();
+
+ // Sets current position of the thumnail control.
+ void SetPosition(int position, int total, bool invalidate);
+ void SlideIn();
+ void SlideOut();
+
+ virtual bool CreateThumbnailControl(
+ uint32 id, const pp::Rect& rc,
+ bool visible, Owner* owner, PDFEngine* engine,
+ NumberImageGenerator* number_image_generator);
+
+ // Control interface.
+ virtual void Show(bool visible, bool invalidate);
+ virtual void Paint(pp::ImageData* image_data, const pp::Rect& rc);
+ virtual bool HandleEvent(const pp::InputEvent& event);
+ virtual void OnTimerFired(uint32 timer_id);
+
+ virtual void ResetEngine(PDFEngine* engine);
+
+ private:
+ void ClearCache();
+
+ struct PageInfo {
+ int index;
+ pp::Rect rect;
+ };
+
+ PDFEngine* engine_;
+ pp::Rect visible_rect_;
+ std::vector<PageInfo> visible_pages_;
+ std::map<int, pp::ImageData*> image_cache_;
+ int sliding_width_;
+ int sliding_shift_;
+ int sliding_timeout_;
+ uint32 sliding_timer_id_;
+ NumberImageGenerator* number_image_generator_;
+};
+
+} // namespace chrome_pdf
+
+#endif // PDF_THUMBNAIL_CONTROL_H_
diff --git a/xfa_test/process/process.cc b/xfa_test/process/process.cc
new file mode 100644
index 0000000000..c8f96db240
--- /dev/null
+++ b/xfa_test/process/process.cc
@@ -0,0 +1,712 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <v8.h>
+
+#include <string>
+#include <map>
+
+#ifdef COMPRESS_STARTUP_DATA_BZ2
+#error Using compressed startup data is not supported for this sample
+#endif
+
+using namespace std;
+using namespace v8;
+
+// These interfaces represent an existing request processing interface.
+// The idea is to imagine a real application that uses these interfaces
+// and then add scripting capabilities that allow you to interact with
+// the objects through JavaScript.
+
+/**
+ * A simplified http request.
+ */
+class HttpRequest {
+ public:
+ virtual ~HttpRequest() { }
+ virtual const string& Path() = 0;
+ virtual const string& Referrer() = 0;
+ virtual const string& Host() = 0;
+ virtual const string& UserAgent() = 0;
+};
+
+
+/**
+ * The abstract superclass of http request processors.
+ */
+class HttpRequestProcessor {
+ public:
+ virtual ~HttpRequestProcessor() { }
+
+ // Initialize this processor. The map contains options that control
+ // how requests should be processed.
+ virtual bool Initialize(map<string, string>* options,
+ map<string, string>* output) = 0;
+
+ // Process a single request.
+ virtual bool Process(HttpRequest* req) = 0;
+
+ static void Log(const char* event);
+};
+
+
+/**
+ * An http request processor that is scriptable using JavaScript.
+ */
+class JsHttpRequestProcessor : public HttpRequestProcessor {
+ public:
+ // Creates a new processor that processes requests by invoking the
+ // Process function of the JavaScript script given as an argument.
+ JsHttpRequestProcessor(Isolate* isolate, Handle<String> script)
+ : isolate_(isolate), script_(script) { }
+ virtual ~JsHttpRequestProcessor();
+
+ virtual bool Initialize(map<string, string>* opts,
+ map<string, string>* output);
+ virtual bool Process(HttpRequest* req);
+
+ private:
+ // Execute the script associated with this processor and extract the
+ // Process function. Returns true if this succeeded, otherwise false.
+ bool ExecuteScript(Handle<String> script);
+
+ // Wrap the options and output map in a JavaScript objects and
+ // install it in the global namespace as 'options' and 'output'.
+ bool InstallMaps(map<string, string>* opts, map<string, string>* output);
+
+ // Constructs the template that describes the JavaScript wrapper
+ // type for requests.
+ static Handle<ObjectTemplate> MakeRequestTemplate(Isolate* isolate);
+ static Handle<ObjectTemplate> MakeMapTemplate(Isolate* isolate);
+
+ // Callbacks that access the individual fields of request objects.
+ static void GetPath(Local<String> name,
+ const PropertyCallbackInfo<Value>& info);
+ static void GetReferrer(Local<String> name,
+ const PropertyCallbackInfo<Value>& info);
+ static void GetHost(Local<String> name,
+ const PropertyCallbackInfo<Value>& info);
+ static void GetUserAgent(Local<String> name,
+ const PropertyCallbackInfo<Value>& info);
+
+ // Callbacks that access maps
+ static void MapGet(Local<String> name,
+ const PropertyCallbackInfo<Value>& info);
+ static void MapSet(Local<String> name,
+ Local<Value> value,
+ const PropertyCallbackInfo<Value>& info);
+
+ // Utility methods for wrapping C++ objects as JavaScript objects,
+ // and going back again.
+ Handle<Object> WrapMap(map<string, string>* obj);
+ static map<string, string>* UnwrapMap(Handle<Object> obj);
+ Handle<Object> WrapRequest(HttpRequest* obj);
+ static HttpRequest* UnwrapRequest(Handle<Object> obj);
+
+ Isolate* GetIsolate() { return isolate_; }
+
+ Isolate* isolate_;
+ Handle<String> script_;
+ Persistent<Context> context_;
+ Persistent<Function> process_;
+ static Persistent<ObjectTemplate> request_template_;
+ static Persistent<ObjectTemplate> map_template_;
+};
+
+
+// -------------------------
+// --- P r o c e s s o r ---
+// -------------------------
+
+
+static void LogCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ if (args.Length() < 1) return;
+ HandleScope scope(args.GetIsolate());
+ Handle<Value> arg = args[0];
+ String::Utf8Value value(arg);
+ HttpRequestProcessor::Log(*value);
+}
+
+static void MethodCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+ if (args.Length() < 1) return;
+ HandleScope scope(args.GetIsolate());
+ Handle<Value> arg = args[0];
+ String::Utf8Value value(arg);
+ HttpRequestProcessor::Log(*value);
+}
+
+static void MyJSObjectCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+
+ HandleScope scope(args.GetIsolate());
+ if(args.IsConstructCall())
+ {
+ //args.GetReturnValue().Set(String::NewFromUtf8(
+ // args.GetIsolate(), "HelloWorld", String::kNormalString,
+ // static_cast<int>(10)));
+ args.This();
+ }
+}
+
+void Getter(
+ Local<String> property,
+ const PropertyCallbackInfo<Value>& info)
+{
+// info.GetReturnValue().Set(String::NewFromUtf8(
+// info.GetIsolate(), "HelloWorld", String::kNormalString,
+// static_cast<int>(10)));
+}
+
+
+// Execute the script and fetch the Process method.
+bool JsHttpRequestProcessor::Initialize(map<string, string>* opts,
+ map<string, string>* output) {
+ // Create a handle scope to hold the temporary references.
+ HandleScope handle_scope(GetIsolate());
+
+ // Create a template for the global object where we set the
+ // built-in global functions.
+ Handle<ObjectTemplate> global = ObjectTemplate::New(GetIsolate());
+ global->Set(String::NewFromUtf8(GetIsolate(), "log"),
+ FunctionTemplate::New(GetIsolate(), LogCallback));
+
+
+// Local<FunctionTemplate> funJSObj = FunctionTemplate::New(GetIsolate(), MyJSObjectCallback);
+// funJSObj->InstanceTemplate()->SetAccessor(String::NewFromUtf8(GetIsolate(), "activeDocs"), Getter, 0, Handle<Value>(), ALL_CAN_READ|PROHIBITS_OVERWRITING);
+// funJSObj->InstanceTemplate()->Set(String::NewFromUtf8(GetIsolate(), "method1"),FunctionTemplate::New(GetIsolate(), MethodCallback));
+//
+// global->Set(String::NewFromUtf8(GetIsolate(), "app"), funJSObj);
+
+ // Each processor gets its own context so different processors don't
+ // affect each other. Context::New returns a persistent handle which
+ // is what we need for the reference to remain after we return from
+ // this method. That persistent handle has to be disposed in the
+ // destructor.
+ v8::Handle<v8::Context> context = Context::New(GetIsolate(), NULL, global);
+ context_.Reset(GetIsolate(), context);
+
+ // Enter the new context so all the following operations take place
+ // within it.
+ Context::Scope context_scope(context);
+
+ Local<ObjectTemplate> ObjTemp = ObjectTemplate::New(GetIsolate());
+ ObjTemp->SetAccessor(String::NewFromUtf8(GetIsolate(), "activeDocs"), Getter, 0, Handle<Value>(), PROHIBITS_OVERWRITING);
+ Local<Object> ins = ObjTemp->NewInstance();
+ context->Global()->Set(String::NewFromUtf8(GetIsolate(), "app"), ins);
+
+
+ // Make the options mapping available within the context
+ if (!InstallMaps(opts, output))
+ return false;
+
+ // Compile and run the script
+ if (!ExecuteScript(script_))
+ return false;
+
+ // The script compiled and ran correctly. Now we fetch out the
+ // Process function from the global object.
+ Handle<String> process_name = String::NewFromUtf8(GetIsolate(), "Process");
+ Handle<Value> process_val = context->Global()->Get(process_name);
+
+ // If there is no Process function, or if it is not a function,
+ // bail out
+ if (!process_val->IsFunction()) return false;
+
+ // It is a function; cast it to a Function
+ Handle<Function> process_fun = Handle<Function>::Cast(process_val);
+
+ // Store the function in a Persistent handle, since we also want
+ // that to remain after this call returns
+ process_.Reset(GetIsolate(), process_fun);
+
+ // All done; all went well
+ return true;
+}
+
+
+bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
+ HandleScope handle_scope(GetIsolate());
+
+ // We're just about to compile the script; set up an error handler to
+ // catch any exceptions the script might throw.
+ TryCatch try_catch;
+
+ // Compile the script and check for errors.
+ Handle<Script> compiled_script = Script::Compile(script);
+ if (compiled_script.IsEmpty()) {
+ String::Utf8Value error(try_catch.Exception());
+ Log(*error);
+ // The script failed to compile; bail out.
+ return false;
+ }
+
+ // Run the script!
+ Handle<Value> result = compiled_script->Run();
+ if (result.IsEmpty()) {
+ // The TryCatch above is still in effect and will have caught the error.
+ String::Utf8Value error(try_catch.Exception());
+ Log(*error);
+ // Running the script failed; bail out.
+ return false;
+ }
+ return true;
+}
+
+
+bool JsHttpRequestProcessor::InstallMaps(map<string, string>* opts,
+ map<string, string>* output) {
+ HandleScope handle_scope(GetIsolate());
+
+ // Wrap the map object in a JavaScript wrapper
+ Handle<Object> opts_obj = WrapMap(opts);
+
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(GetIsolate(), context_);
+
+ // Set the options object as a property on the global object.
+ context->Global()->Set(String::NewFromUtf8(GetIsolate(), "options"),
+ opts_obj);
+
+ Handle<Object> output_obj = WrapMap(output);
+ context->Global()->Set(String::NewFromUtf8(GetIsolate(), "output"),
+ output_obj);
+
+ return true;
+}
+
+
+bool JsHttpRequestProcessor::Process(HttpRequest* request) {
+ // Create a handle scope to keep the temporary object references.
+ HandleScope handle_scope(GetIsolate());
+
+ v8::Local<v8::Context> context =
+ v8::Local<v8::Context>::New(GetIsolate(), context_);
+
+ // Enter this processor's context so all the remaining operations
+ // take place there
+ Context::Scope context_scope(context);
+
+ // Wrap the C++ request object in a JavaScript wrapper
+ Handle<Object> request_obj = WrapRequest(request);
+
+ // Set up an exception handler before calling the Process function
+ TryCatch try_catch;
+
+ // Invoke the process function, giving the global object as 'this'
+ // and one argument, the request.
+ const int argc = 1;
+ Handle<Value> argv[argc] = { request_obj };
+ v8::Local<v8::Function> process =
+ v8::Local<v8::Function>::New(GetIsolate(), process_);
+ Handle<Value> result = process->Call(context->Global(), argc, argv);
+ if (result.IsEmpty()) {
+ String::Utf8Value error(try_catch.Exception());
+ Log(*error);
+ return false;
+ } else {
+ return true;
+ }
+}
+
+
+JsHttpRequestProcessor::~JsHttpRequestProcessor() {
+ // Dispose the persistent handles. When noone else has any
+ // references to the objects stored in the handles they will be
+ // automatically reclaimed.
+ context_.Reset();
+ process_.Reset();
+}
+
+
+Persistent<ObjectTemplate> JsHttpRequestProcessor::request_template_;
+Persistent<ObjectTemplate> JsHttpRequestProcessor::map_template_;
+
+
+// -----------------------------------
+// --- A c c e s s i n g M a p s ---
+// -----------------------------------
+
+// Utility function that wraps a C++ http request object in a
+// JavaScript object.
+Handle<Object> JsHttpRequestProcessor::WrapMap(map<string, string>* obj) {
+ // Handle scope for temporary handles.
+ EscapableHandleScope handle_scope(GetIsolate());
+
+ // Fetch the template for creating JavaScript map wrappers.
+ // It only has to be created once, which we do on demand.
+ if (map_template_.IsEmpty()) {
+ Handle<ObjectTemplate> raw_template = MakeMapTemplate(GetIsolate());
+ map_template_.Reset(GetIsolate(), raw_template);
+ }
+ Handle<ObjectTemplate> templ =
+ Local<ObjectTemplate>::New(GetIsolate(), map_template_);
+
+ // Create an empty map wrapper.
+ Local<Object> result = templ->NewInstance();
+
+ // Wrap the raw C++ pointer in an External so it can be referenced
+ // from within JavaScript.
+ Handle<External> map_ptr = External::New(GetIsolate(), obj);
+
+ // Store the map pointer in the JavaScript wrapper.
+ result->SetInternalField(0, map_ptr);
+
+ // Return the result through the current handle scope. Since each
+ // of these handles will go away when the handle scope is deleted
+ // we need to call Close to let one, the result, escape into the
+ // outer handle scope.
+ return handle_scope.Escape(result);
+}
+
+
+// Utility function that extracts the C++ map pointer from a wrapper
+// object.
+map<string, string>* JsHttpRequestProcessor::UnwrapMap(Handle<Object> obj) {
+ Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
+ void* ptr = field->Value();
+ return static_cast<map<string, string>*>(ptr);
+}
+
+
+// Convert a JavaScript string to a std::string. To not bother too
+// much with string encodings we just use ascii.
+string ObjectToString(Local<Value> value) {
+ String::Utf8Value utf8_value(value);
+ return string(*utf8_value);
+}
+
+
+void JsHttpRequestProcessor::MapGet(Local<String> name,
+ const PropertyCallbackInfo<Value>& info) {
+ // Fetch the map wrapped by this object.
+ map<string, string>* obj = UnwrapMap(info.Holder());
+
+ // Convert the JavaScript string to a std::string.
+ string key = ObjectToString(name);
+
+ // Look up the value if it exists using the standard STL ideom.
+ map<string, string>::iterator iter = obj->find(key);
+
+ // If the key is not present return an empty handle as signal
+ if (iter == obj->end()) return;
+
+ // Otherwise fetch the value and wrap it in a JavaScript string
+ const string& value = (*iter).second;
+ info.GetReturnValue().Set(String::NewFromUtf8(
+ info.GetIsolate(), value.c_str(), String::kNormalString,
+ static_cast<int>(value.length())));
+}
+
+
+void JsHttpRequestProcessor::MapSet(Local<String> name,
+ Local<Value> value_obj,
+ const PropertyCallbackInfo<Value>& info) {
+ // Fetch the map wrapped by this object.
+ map<string, string>* obj = UnwrapMap(info.Holder());
+
+ // Convert the key and value to std::strings.
+ string key = ObjectToString(name);
+ string value = ObjectToString(value_obj);
+
+ // Update the map.
+ (*obj)[key] = value;
+
+ // Return the value; any non-empty handle will work.
+ info.GetReturnValue().Set(value_obj);
+}
+
+
+Handle<ObjectTemplate> JsHttpRequestProcessor::MakeMapTemplate(
+ Isolate* isolate) {
+ EscapableHandleScope handle_scope(isolate);
+
+ Local<ObjectTemplate> result = ObjectTemplate::New(isolate);
+ result->SetInternalFieldCount(1);
+ result->SetNamedPropertyHandler(MapGet, MapSet);
+
+ // Again, return the result through the current handle scope.
+ return handle_scope.Escape(result);
+}
+
+
+// -------------------------------------------
+// --- A c c e s s i n g R e q u e s t s ---
+// -------------------------------------------
+
+/**
+ * Utility function that wraps a C++ http request object in a
+ * JavaScript object.
+ */
+Handle<Object> JsHttpRequestProcessor::WrapRequest(HttpRequest* request) {
+ // Handle scope for temporary handles.
+ EscapableHandleScope handle_scope(GetIsolate());
+
+ // Fetch the template for creating JavaScript http request wrappers.
+ // It only has to be created once, which we do on demand.
+ if (request_template_.IsEmpty()) {
+ Handle<ObjectTemplate> raw_template = MakeRequestTemplate(GetIsolate());
+ request_template_.Reset(GetIsolate(), raw_template);
+ }
+ Handle<ObjectTemplate> templ =
+ Local<ObjectTemplate>::New(GetIsolate(), request_template_);
+
+ // Create an empty http request wrapper.
+ Local<Object> result = templ->NewInstance();
+
+ // Wrap the raw C++ pointer in an External so it can be referenced
+ // from within JavaScript.
+ Handle<External> request_ptr = External::New(GetIsolate(), request);
+
+ // Store the request pointer in the JavaScript wrapper.
+ result->SetInternalField(0, request_ptr);
+
+ // Return the result through the current handle scope. Since each
+ // of these handles will go away when the handle scope is deleted
+ // we need to call Close to let one, the result, escape into the
+ // outer handle scope.
+ return handle_scope.Escape(result);
+}
+
+
+/**
+ * Utility function that extracts the C++ http request object from a
+ * wrapper object.
+ */
+HttpRequest* JsHttpRequestProcessor::UnwrapRequest(Handle<Object> obj) {
+ Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0));
+ void* ptr = field->Value();
+ return static_cast<HttpRequest*>(ptr);
+}
+
+
+void JsHttpRequestProcessor::GetPath(Local<String> name,
+ const PropertyCallbackInfo<Value>& info) {
+ // Extract the C++ request object from the JavaScript wrapper.
+ HttpRequest* request = UnwrapRequest(info.Holder());
+
+ // Fetch the path.
+ const string& path = request->Path();
+
+ // Wrap the result in a JavaScript string and return it.
+ info.GetReturnValue().Set(String::NewFromUtf8(
+ info.GetIsolate(), path.c_str(), String::kNormalString,
+ static_cast<int>(path.length())));
+}
+
+
+void JsHttpRequestProcessor::GetReferrer(
+ Local<String> name,
+ const PropertyCallbackInfo<Value>& info) {
+ HttpRequest* request = UnwrapRequest(info.Holder());
+ const string& path = request->Referrer();
+ info.GetReturnValue().Set(String::NewFromUtf8(
+ info.GetIsolate(), path.c_str(), String::kNormalString,
+ static_cast<int>(path.length())));
+}
+
+
+void JsHttpRequestProcessor::GetHost(Local<String> name,
+ const PropertyCallbackInfo<Value>& info) {
+ HttpRequest* request = UnwrapRequest(info.Holder());
+ const string& path = request->Host();
+ info.GetReturnValue().Set(String::NewFromUtf8(
+ info.GetIsolate(), path.c_str(), String::kNormalString,
+ static_cast<int>(path.length())));
+}
+
+
+void JsHttpRequestProcessor::GetUserAgent(
+ Local<String> name,
+ const PropertyCallbackInfo<Value>& info) {
+ HttpRequest* request = UnwrapRequest(info.Holder());
+ const string& path = request->UserAgent();
+ info.GetReturnValue().Set(String::NewFromUtf8(
+ info.GetIsolate(), path.c_str(), String::kNormalString,
+ static_cast<int>(path.length())));
+}
+
+
+Handle<ObjectTemplate> JsHttpRequestProcessor::MakeRequestTemplate(
+ Isolate* isolate) {
+ EscapableHandleScope handle_scope(isolate);
+
+ Local<ObjectTemplate> result = ObjectTemplate::New(isolate);
+ result->SetInternalFieldCount(1);
+
+ // Add accessors for each of the fields of the request.
+ result->SetAccessor(
+ String::NewFromUtf8(isolate, "path", String::kInternalizedString),
+ GetPath);
+ result->SetAccessor(
+ String::NewFromUtf8(isolate, "referrer", String::kInternalizedString),
+ GetReferrer);
+ result->SetAccessor(
+ String::NewFromUtf8(isolate, "host", String::kInternalizedString),
+ GetHost);
+ result->SetAccessor(
+ String::NewFromUtf8(isolate, "userAgent", String::kInternalizedString),
+ GetUserAgent);
+
+ // Again, return the result through the current handle scope.
+ return handle_scope.Escape(result);
+}
+
+
+// --- Test ---
+
+
+void HttpRequestProcessor::Log(const char* event) {
+ printf("Logged: %s\n", event);
+}
+
+
+/**
+ * A simplified http request.
+ */
+class StringHttpRequest : public HttpRequest {
+ public:
+ StringHttpRequest(const string& path,
+ const string& referrer,
+ const string& host,
+ const string& user_agent);
+ virtual const string& Path() { return path_; }
+ virtual const string& Referrer() { return referrer_; }
+ virtual const string& Host() { return host_; }
+ virtual const string& UserAgent() { return user_agent_; }
+ private:
+ string path_;
+ string referrer_;
+ string host_;
+ string user_agent_;
+};
+
+
+StringHttpRequest::StringHttpRequest(const string& path,
+ const string& referrer,
+ const string& host,
+ const string& user_agent)
+ : path_(path),
+ referrer_(referrer),
+ host_(host),
+ user_agent_(user_agent) { }
+
+
+void ParseOptions(int argc,
+ char* argv[],
+ map<string, string>& options,
+ string* file) {
+ for (int i = 1; i < argc; i++) {
+ string arg = argv[i];
+ size_t index = arg.find('=', 0);
+ if (index == string::npos) {
+ *file = arg;
+ } else {
+ string key = arg.substr(0, index);
+ string value = arg.substr(index+1);
+ options[key] = value;
+ }
+ }
+}
+
+
+// Reads a file into a v8 string.
+Handle<String> ReadFile(Isolate* isolate, const string& name) {
+ FILE* file = fopen(name.c_str(), "rb");
+ if (file == NULL) return Handle<String>();
+
+ fseek(file, 0, SEEK_END);
+ int size = ftell(file);
+ rewind(file);
+
+ char* chars = new char[size + 1];
+ chars[size] = '\0';
+ for (int i = 0; i < size;) {
+ int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
+ i += read;
+ }
+ fclose(file);
+ Handle<String> result =
+ String::NewFromUtf8(isolate, chars, String::kNormalString, size);
+ delete[] chars;
+ return result;
+}
+
+
+const int kSampleSize = 6;
+StringHttpRequest kSampleRequests[kSampleSize] = {
+ StringHttpRequest("/process.cc", "localhost", "google.com", "firefox"),
+ StringHttpRequest("/", "localhost", "google.net", "firefox"),
+ StringHttpRequest("/", "localhost", "google.org", "safari"),
+ StringHttpRequest("/", "localhost", "yahoo.com", "ie"),
+ StringHttpRequest("/", "localhost", "yahoo.com", "safari"),
+ StringHttpRequest("/", "localhost", "yahoo.com", "firefox")
+};
+
+
+bool ProcessEntries(HttpRequestProcessor* processor, int count,
+ StringHttpRequest* reqs) {
+ for (int i = 0; i < count; i++) {
+ if (!processor->Process(&reqs[i]))
+ return false;
+ }
+ return true;
+}
+
+
+void PrintMap(map<string, string>* m) {
+ for (map<string, string>::iterator i = m->begin(); i != m->end(); i++) {
+ pair<string, string> entry = *i;
+ printf("%s: %s\n", entry.first.c_str(), entry.second.c_str());
+ }
+}
+
+
+int main(int argc, char* argv[]) {
+ v8::V8::InitializeICU();
+ map<string, string> options;
+ string file;
+ ParseOptions(argc, argv, options, &file);
+ if (file.empty()) {
+ fprintf(stderr, "No script was specified.\n");
+ return 1;
+ }
+ Isolate* isolate = Isolate::GetCurrent();
+ HandleScope scope(isolate);
+ Handle<String> source = ReadFile(isolate, file);
+ if (source.IsEmpty()) {
+ fprintf(stderr, "Error reading '%s'.\n", file.c_str());
+ return 1;
+ }
+ JsHttpRequestProcessor processor(isolate, source);
+ map<string, string> output;
+ if (!processor.Initialize(&options, &output)) {
+ fprintf(stderr, "Error initializing processor.\n");
+ return 1;
+ }
+ if (!ProcessEntries(&processor, kSampleSize, kSampleRequests))
+ return 1;
+ PrintMap(&output);
+}
diff --git a/xfa_test/process/script.txt b/xfa_test/process/script.txt
new file mode 100644
index 0000000000..aceb48c505
--- /dev/null
+++ b/xfa_test/process/script.txt
@@ -0,0 +1,21 @@
+function Process(request)
+{
+
+//var c = new MyJSObject();
+
+//this.log(c.property1);
+
+var c = app.activeDocs;
+
+
+if(options["param1"] != "x")
+{
+ this.output["hello"] = 1;
+ log(request.host);
+}
+else
+{
+ this.output["hello"] = 2;
+ log(request.host);
+}
+} \ No newline at end of file